Manpcnin wrote:... this code fails and crashes under "-gen gcc -O 1" (and -O 2 / -O 3)
I found a bug that is related to float to integer conversions in the gcc backend. For float/integer conversions fbc will generate an inline C function something like the following:
Code: Select all
static inline int32 fb_F2I( float value )
{
volatile int32 result;
__asm__(
"fld %1;"
"fistp %0;"
:"=m" (result)
:"m" (value)
);
return result;
}
The only way I could get a CRASH was to mix intel and att asm syntax. If you compile the BAS to C (intel syntax) and then use the resulting C file with gcc expecting att syntax, it will compile because the 'fistp' instruction is valid but wrong, should be 'fistpl'. That's not a bug, just something to be aware of if compiling the generated C directly and there was in fact a crash - maybe due to accessing memory outside of the array bounds. Something could check for by compiling with -exx in fbc.
I was able to reproduce FAILUREs readily, where all results of the example program are zero on 32-bit -gen gcc -O 1/2/3. Here's where the bug is: the generated __asm__(*) block doesn't give any indication that x87 stack gets clobbered. And because the gcc optimizer uses st(7) for doing some fxch's on either side of fb_F2I() usage it doesn't know that st(7) gets clobbered. This could also explain extra NAN's in the resulting calculations.
Rounding specifics aside if there are any, this is easy to patch, basically adding a ' :"st" ' line at the end of the __asm__ block to indicate that x87 stack gets clobbered and gcc will optimize differently.