Hi!
Compiling the code below SDCC 10612 (MINGW32)
typedef union
{
int32_t i;
float f;
} intflt;
void sum(int8_t tp, intflt *if1, intflt *if2)
{
if(tp)
(*if1).f *= (*if2).f;
else
(*if1).i *= (*if2).i;
}
gives the next assembly:
.area CODE
; .\Source\main.c: 11: void sum(int8_t tp, intflt *if1, intflt *if2)
; -----------------------------------------
; function sum
; -----------------------------------------
_sum:
sub sp, #10
; .\Source\main.c: 15: (*if1).f *= (*if2).f;
ldw y, (0x0e, sp)
ldw (0x09, sp), y
ldw y, (0x10, sp)
ldw x, (0x09, sp)
ld a, (0x3, x)
ld (0x08, sp), a
ld a, (0x2, x)
ld (0x07, sp), a
ldw x, (x)
ldw (0x05, sp), x
ldw x, y
ldw y, (0x2, y)
ldw x, (x)
pushw y
pushw x
ldw x, (0x0b, sp)
pushw x
ldw x, (0x0b, sp)
pushw x
; .\Source\main.c: 13: if(tp)
call ___fsmul
addw sp, #8
ldw (0x01, sp), y
tnz (0x0d, sp)
jreq 00102$
; .\Source\main.c: 15: (*if1).f *= (*if2).f;
ldw y, (0x09, sp)
ldw (0x2, y), x
ldw x, (0x01, sp)
ldw (y), x
jra 00104$
00102$:
; .\Source\main.c: 19: (*if1).i *= (*if2).i;
ldw y, (0x09, sp)
ldw (0x2, y), x
ldw x, (0x01, sp)
ldw (y), x
00104$:
; .\Source\main.c: 21: }
addw sp, #10
ret
Unfortunately I don't see 32bit integer multiplication there :(
This code is ok:
void sum(int8_t tp, intflt *if1, intflt *if2)
{
if(tp == 1)
(*if1).f *= (*if2).f;
else
if(tp == 0)
(*if1).i *= (*if2).i;
}
PS
Also I'm very upset with very inefficient indirection operation processing: it takes 10 bytes of stack memory. And the second variant of sum function uses 20 bytes of stack...
Looks as if lospre doesn't see the difference between float and long multiplication here. The bug is not stm8-specific.
Workaround: Use --nolospre.
Increasing priority, since bad code is generated silently.
Philipp
Fixed in [r10615].
Philipp