Code:
144: var1 = var1 >> 2;
04524 0101 MOVLB 0x1
04526 90D8 BCF 0xfd8, 0, ACCESS ; set Carry flag to '0'
04528 33E7 RRCF 0xe7, F, BANKED ; C -> var1.hi -> C
0452A 33E6 RRCF 0xe6, F, BANKED ; C -> var1.lo -> C
0452C 90D8 BCF 0xfd8, 0, ACCESS ; set C flag to '0'
0452E 33E7 RRCF 0xe7, F, BANKED ; shift again
04530 33E6 RRCF 0xe6, F, BANKED
Its more accurate to say the compiler doesn't support signed shifts. The PIC is capable of doing signed shifts if asked to. All shifts are treated as unsigned by the compiler and have the carry in flag set to zero during the rotations. The PIC is capable of shifting in a '1' for negative values but the compile chooses not to -- 'cause all shifting operations are unsigned. Other compilers, such as HI-TECH's PIC C compiler chose to preserve the sign bit. This is a compiler specific implementation selection allowed by the ANSI C spec.
If you want to do signed shifts, you have to roll your own and change the instructions to:
Code:
BTFSC 0xe7, 7, BANKED
BRA NEGVALUE_SHIFT
POSVALUE_SHIFT:
BCF 0xfd8, 0, ACCESS ; Set CARRY (C) flag to '0'
RRCF 0xe7, F, BANKED ; C -> var1.hi -> C
RRCF 0xe6, F, BANKED ; C -> var1.lo -> C
BCF 0xfd8, 0, ACCESS ; clear C flag for next shift op
RRCF 0xe7, F, BANKED
RRCF 0xe6, F, BANKED
BRA DONE_SHIFT
NEGVALUE_SHIFT:
BSF 0xfd8, 0, ACCESS ; Set CARRY (C) flag to '1'
RRCF 0xe7, F, BANKED ; C -> var1.hi -> C
RRCF 0xe6, F, BANKED ; C -> var1.lo -> C
BSF 0xfd8, 0, ACCESS ; set C flag for next shift op
RRCF 0xe7, F, BANKED
RRCF 0xe6, F, BANKED
BRA DONE_SHIFT
DONE_SHIFT:
alternatively, in C a little more convoluted... plus there are other methods.
Code:
if (var1 > 0)
var1 = (var1 >> 2);
else
var1 = (varl >> 2) | 0xC000;