While reviewing the new code for identifying which descriptor is being requested by the USB host, I noticed that instead of using the Switch/Case macros I had instead manually implemented the same mechanism of using XOR and conditional branches. "Why not be consistent?" I thought to myself, and set about converting it into the Switch/Case pattern.
While using the macros cleans up the code appearance, and gets rid of some labels... it also increases the code size by a few bytes. Reviewing the reason why, I found that the 'default' case at the end of the block imposes 2 extra branch instructions. And in this specific scenario, the code inside the default block in this example is a branch to the setup_error code. This means the default block is literally 3 branches, when ideally it could be 1.
I looked at the other switch blocks in the code, and found 2 other cases of a default block that contain a single branch. Crafting a specialized case macro that includes this branch, instead of requiring a separate default block, will shave 4 bytes off of each case. It's a little ham-fisted for general use, but for the purposes of the 1KB challenge, seems like a win.
So, instead of this:
CASE SOME_VALUE DO_SOME_STUFF DEFAULT bra somewhere_else ENDSW
I'll wind up with this:
CASEELSE SOME_VALUE, somewhere_else DO_SOME_STUFF ENDSW
And in the process, clean up the descriptor lookup code as well as save 4 bytes per altered statement.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.