I have encountered a situation where SDCC is generating bad STM8 code.
For some reason, in a certain scenario it is not rewinding the stack
pointer after returning from a function call. That is, before the
function call, it pushes arguments to the stack as normal, but
afterwards it is NOT following up with a "addw sp, #N" instruction.
The following example program demonstrates the issue. There may be a
simpler test case, but this is what I was able to narrow down to a
minimal example from the actual code where I discovered the problem.
// Compile with: sdcc -S -mstm8 main.c
#include <stddef.h>
typedef struct {
unsigned long m;
unsigned long n;
} some_t;
static const struct {
unsigned long a;
unsigned long b;
unsigned long c;
unsigned long d;
} blah[] = {
{ 2483400797, 742211619, 3, 256765940 },
};
void foo(unsigned long x, unsigned long y, some_t *z) {
(void)x;
(void)y;
(void)z;
}
unsigned long bar(unsigned long x, unsigned long y) {
(void)x;
(void)y;
return 0UL;
}
void main(void) {
unsigned long t;
some_t r;
for(size_t i = 0; i < (sizeof(blah) / sizeof(blah[0])); i++) {
t = bar(blah[i].a, blah[i].b);
}
for(size_t i = 0; i < (sizeof(blah) / sizeof(blah[0])); i++) {
foo(blah[i].a, blah[i].b, &r);
}
while(1);
}
When one inspects the generated assembly code, you can see that where it
calls bar(), it generates the following:
pushw y
ldw x, (0x0f, sp)
pushw x
ldw x, (0x0f, sp)
pushw x
ldw x, (0x17, sp)
pushw x
ldw x, (0x17, sp)
pushw x
call _bar
addw sp, #8 ; <-- SP rewind
popw y
But when it later calls foo(), it generates the following:
pushw x
ldw x, (0x0d, sp)
pushw x
ldw x, (0x0d, sp)
pushw x
pushw y
ldw x, (0x15, sp)
pushw x
call _foo
ldw x, (0x11, sp) ; <-- no SP rewind!
As you can see, it does not follow the "call" instruction with anything
to rewind the stack pointer and clean up the arguments it previously
pushed! Therefore, execution here goes haywire, because unexpected
values are encountered for stack-held variables (in my original code,
'i' became bogus and the for loop exited early).
This bug is worrying me, as I have been attempting to mitigate by
rearranging my code in all sorts of ways, yet I cannot convince SDCC to
emit the proper stack clean-up code for the affected function call.
Anyone have any advice?
Regards,
Basil Hussain
P.S. SDCC version:
SDCC :
mcs51/z80/z180/r2k/r2ka/r3ka/sm83/tlcs90/ez80_z80/z80n/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502
4.2.0 #13081 (MINGW64)
_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user