Chano wrote:Well, it works with -O3 if I put the bios call inside a .s file... it seems like a GCC bug, right?
Possibly, I'm not really sure.
I've never entirely got inline assembly to work consistently so I tend to avoid it for anything more complex than getting access to conditions codes or arm registers. There's a good write up at
http://www.ethernut.de/en/documents/arm-inline-asm.html which can be immensely helpful sometimes.
I got your code to work at -O1 by telling the compiler that result & remainder are inputs as well as outputs. Once the function gets inlined things start going strange though.
Code: Select all
//---------------------------------------------------------------------------------
// BIOS divison function
//---------------------------------------------------------------------------------
void biosDivision(s32 numerator, s32 denominator, s32* result, s32* remainder) {
//---------------------------------------------------------------------------------
asm volatile (
"mov r0, %[numerator] \n\t"
"mov r1, %[denominator] \n\t"
#if defined ( __thumb__ )
"swi 6 \n\t" // Put 6 here for Thumb C Compiler mode.
#else
"swi 6<<16 \n\t" // Put 0x60000 there for ARM C Compiler mode.
#endif
"mov r2, %[result]\n\t"
"str r0, [r2]\n\t"
"mov r2, %[remainder]\n\t"
"str r1, [r2] \n\t"
: [result] "+l" (result), [remainder] "+l" (remainder)
: [numerator] "l" (numerator), [denominator] "l" (denominator)
: "r0","r1","r2","r3"
);
}
I was mainly just playing around to see what happens. "l" is a low register (r0-7), the "+" modifier says this operand is read as well as written