At 10 Jul 2006 09:27:19 -0700, Ian Lance Taylor wrote: > > Simon Kagstrom <simon.kagstrom@xxxxxx> writes: > > > Unfortunately there was no difference with -Wa,-O0. It does however > > look like the use of Linux-style syscalls break the > > -fno-delayed-branch behavior. I have code like > > > > #define _syscall1(type,name,atype,a) \ > > type name(atype a) \ > > { \ > > register unsigned long __a0 asm("$4") = (unsigned long) a; \ > > register unsigned long __v0 asm("$2"); \ > > \ > > __asm__ volatile ( \ > > ".set\tnoreorder\n\t" \ > > "li\t$2, %2\t\t\t# " #name "\n\t" \ > > "syscall\n\t" \ > > ".set\treorder" \ > > : "=&r" (__v0) \ > > : "r" (__a0), "i" (__NR_##name) \ > > ); \ > > \ > > return (type) __v0; \ > > } > > #define __NR_exit 0 > > static inline _syscall1(void,exit , int, code ); > > > > and with the call of exit(...), the delay slots are filled with > > instructions. If I just define a plain function and call that, > > -fno-delayed-branch seems to behave correctly. > > I see. This is not a bug in the compiler. The ".set reorder" > directive tells the assembler that it should reorder instructions into > branch delay slots when possible. The compiler just copies the ".set > reorder" directly from the asm statement. Both the compiler and the > assembler are acting as expected. Ah, that explains it. I knew what .set reorder / noreorder does, but it didn't occur to me that this was how GCC implemented the -fno-delayed-branch option, but it all makes sense now. > You should rewrite your asm statement to not use .set reorder. Do this instead: > .set push > .set noreorder > ... > .set pop Thanks for the help, it works now! // Simon