I noticed that sm83’s calling convention would make --callee-saves-bc basically impossible. (2B return in BC)
But my tests showed that --callee-saves-bc is generally ignored on sm83 and z80.
hello.c:
#include <assert.h>
unsigned char func (unsigned int a) {
return (a>>8)&0xF0 | (a&0x0F);
}
int main (void) {
unsigned int b = 0;
for (unsigned char i = 8; i > 0; --i) {
b += func(0x1231);
}
assert(b == 0x88);return b;
}
./4.2.0/sdcc -S -msm83 hello.c and ./4.2.0/sdcc -S -msm83 --callee-saves-bc hello.c produce:
_func::
ld a, d
and a, #0xf0
ld c, a
ld a, e
and a, #0x0f
or a, c
ret
...
push bc
ld de, #0x1231
call _func
pop bc
...
./4.2.0/sdcc -S -msm83 --sdcccall 0 hello.c and ./4.2.0/sdcc -S -msm83 --sdcccall 0 --callee-saves-bc hello.c produce:
_func::
ldhl sp, #3
ld a, (hl-)
and a, #0xf0
ld c, a
ld a, (hl)
and a, #0x0f
or a, c
ld e, a
ret
...
push bc
push de
ld hl, #0x1231
push hl
call _func
pop hl
ld l, e
pop de
pop bc
...
./4.1.0/sdcc -S -mgbz80 hello.c and ./4.1.0/sdcc -S -mgbz80 --callee-saves-bc hello.c produce:
_func::
ldhl sp, #3
ld a, (hl)
and a, #0xf0
ld c, a
dec hl
ld a, (hl)
and a, #0x0f
or a, c
ld e, a
ret
...
push bc
push de
ld hl, #0x1231
push hl
call _func
add sp, #2
ld a, e
pop de
pop bc
...
It looks similar on z80.
Diff:
Diff: