When is a branch not a branch?

C6808 | |

I recently got an interesting code sequence out of the compiler. The variables are all signed and 16 bits in size.

3922 B6 23      LDA   $23              result = (s_low + s_high) / 2;
3924 BB 2D      ADD   $2D
3926 B7 4A      STA   $4A
3928 B6 22      LDA   $22
392A B9 2C      ADC   $2C
392C B7 49      STA   $49
392E 0F 49 00   BRCLR 7,$49,$3931
3931 B6 49      LDA   $49
3933 46         RORA  
3934 B7 49      STA   $49
3936 B6 4A      LDA   $4A
3938 46         RORA  
3939 B7 4A      STA   $4A

The branch looks to be unnecessary--both results arrive at the same location. A waste of three bytes, you might think.

It's not. The Branch on Bit Clear instruction has a side effect: it copies the state of the tested bit into the Carry bit.

That puts it in position to rotate back into the top bit of the variable when the Rotate Right takes place. This preserves the sign information of the MSB.

Sometimes we get support calls about seemingly unnecessary instructions. We're happy when we're able to explain strange code away as compiler cleverness like this.