Given the following C expression (or equivalent if-else statement)
uint8_t x = (var & 0x80) ? 0x87 : 0
avr-gcc generates code like this
sbrs r21,7 ; 1,2 rjmp .L10 ; 2,0 ldi r24,lo8(-121) ; 0,1 rjmp .L12 ; 0,2 .L10: ldi r24,lo8(0) ; 1,0 .L12:
The comment at the end of each line were added by me to indicate the number of cycles required in the false and true cases. Results are 4 cycles for false and 5 cycles for true. With a total of 5 words of code.
I have two questions about that:
1) Why lo8(-121) instead of just lo8(135)?
2) Why not generate the code below instead?
ldi r24,lo8(-121) ; 1,1 sbrs r21,7 ; 1,2 ldi r24,lo8(0) ; 1,0
Results are 3 cycles for false and 3 cycles for true, and a total of 3 words of code. Admittedly a small difference, but with no down-side that I see. Particularly given that the equivalent C code is fairly common in avr code.
I'm guessing this may be a side effect of the fact that GCC targets multiple platforms?