For MCS-51, it should be possible to choose more optimal opcodes if the source code is detected to be bit addressing a SFR with an address of the form 0b1XXX'X000.
An example illustrating this:
__sfr __at(0xE0) ACC;
__sfr __at(0x82) DPL;
void main(void) {
if (ACC & 0x01) ACC = 0;
if (DPL & 0x01) DPL = 0;
}
Which generates the following assembly:
_main:
mov a,_ACC
jnb acc.0,00102$
mov _ACC,#0x00
00102$:
mov a,_DPL
jnb acc.0,00105$
mov _DPL,#0x00
00105$:
ret
Where one can see the redundancy of the first instruction, The compiler could be able to tell apart these two cases by just checking whether the address of ACC has its first bit set and its three lowest bits cleared, not being the case for DPL
A more appropiate selection would reduce code related to context saving of interupt subroutines as:
__sfr __at(0x80) P0;
void main(void) { }
void isr(void) __interrupt(0) {if (P0 & 0x4) P0 = 1;}
Which generates:
_isr:
push acc
push ar7
push psw
mov psw,#0x00
mov a,_P0
jnb acc.2,00103$
mov _P0,#0x01
00103$:
pop psw
pop ar7
pop acc
reti
Where it is clear that the use of the stack was not needed at all if "jnb 0x80 + 2, 00103$" had been used instead.
This was one of the things which I tried to address in issue 466,
https://sourceforge.net/p/sdcc/patches/466/attachment/0009-add-isSpecialRegister-peephole-condition-function-al.patch
My patched-up SDCC produces the following:
Since ACC and DPL/DPH/DPTR are standard registers that are used by the compiler for usual code generation it realizes that the results are not used and omits all of the code (except for a the last dangling
mov a,_DPL)This might be a little unexpected if some code relies on those SFRs being treated effectively like volatile variables.
However, for other "unknown" SFRs it will preserve the operations.
For the 2nd case, I'm getting the following (using svn r 16432)
This seems to be the main issue of this request. The compiler doesn't know that an SFR is also bit-addressable. If the address of the SFR is known at compile time, it could certainly deduce that.
This might be actually implemented as a peephole optimization. In addition to my proposed
isSpecialRegisterpeephole support function it would also require another one to check if a a special register is also bit addressable, by e.g. checking for this: