I worked out an optimization that turns GOTOs
(2 words in program memory) into BRAs (using
only 1 word) by modifying the pCode.
(This cannot be done using the normal peephole
optimizer because of problems mentioned below).
The optimization actually has two aims:
(1) program memory is being reduced
(2) execution of "BTFSx; GOTO" pairs will be
sped up (saving one cycle if skipping,
as the GOTO leaves a NOP to execute).
Additionally the procedure turns
"BTFSx STATUS,i; GOTO" pairs into equivalent
"Bcc" instructions (with BTFSx being either BTFSS
or BTFSC and Bcc being one of BC, BZ, BOV, BN
or their negated variant).
This again speeds things up and reduces
program memory usage even further.
My code checks whether the destination labels
of the GOTO instructions are within +-1023 bytes
from the statement (the largest offset permitted
by BRA) or even within +-127 bytes (the largest
offset permitted by Bcc instructions) by summing
up the (estimated) sizes of all instructions in
between the GOTO and its destination; inline
assembly instructions (PS_ASMDIR) are assumed
to be 4 bytes (to be on the safe side).
Furthermore the procedure takes care NOT to destroy
jumptables (by conservatively estimating whether
the GOTo in question can be part of a jumptable or
Last but not least I make sure that no label(s)
attached to modified instructions get lost or
moved to wrong places (especially important
in cases like:
which would otherwise be turned into
turning the unconditional GOTO into a
Taking all this into consideration should result
in valid code in all cases.
To be on the safe side, I added a compiler switch
"--optimize-goto" to enable the feature and a
(conditional) call to the optimization
(pic16_optimizeJumps) to pic16glue().
I also modified the bankswitch-insertion procedure
from inserting GOTOs to using BRAs instead.
A patch to include this into the current CVS sources
has been uploaded (apply in src/pic16/ with -p0).
I am looking forward to getting comments/questions
about the patch,