sdcc -v
3.6.5 #9879 (MINGW64)
Example code:
unsigned char *p; unsigned char *a; signed char b; void main(void) { p = a + b; }
sdcc -S -mz80 test.c
Generated asm:
_main:: ;zzz.c:8: p = a + b; ld hl,#_b push de ld de,#_p ld iy,#_a ld a,0 (iy) add a, (hl) ld (de),a ld a,1 (iy) adc a, #0x00 inc de ld (de),a pop de ret
HL is pointing to "signed char b". It gets added to the running sum in 8-bit add "add a,(hl)" and carry is carried through into the 16-bit result in "adc a,#0x00". This is an unsigned addition where the signed char has not been sign extended into 16-bits.
If this asm code is really generated for this piece of C, there is a much bigger problem. The assembly overwrites p[1].
And when both operands and the result are char there is no need for promotion to int.
Maarten, I think you've misread
as
Philipp
I read:
To me that reads as overwriting p[1]. Please tell me where I am wrong.
Wait, I see it. It's adding to the pointer, not the pointee.
The asm code writes the two bytes that make up the 16-bit pointer p. It does not write to the location that p points to.
Philipp
The promotion to int is also missing in the generated code for stm8, so I guess all ports are affected.
Philipp
The bug is there already in the AST dump:
compiled using sdcc -mstm8 test.c --fverbose-asm --dump-ast --dump-i-code gives:
Philipp
But there is no promotion bug! The result is the same no matter whether promotion is applied or not in f(). And f2() looks OK to me.
The only bug I see is if p[1] is really overwritten for the original C code. But I suspect this to be user error by pasting asm that was generated for a different C source.
There is (see attachment). Looks like line 4008 in SDCCast.c is to blame. If I remove that one, the generated code works (but I get warnings about a pointer being cast to int).
Philipp
Fixed in revision [r9880].
Philipp
Last edit: Maarten Brock 2017-04-28