This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: -fno-delayed-branch and the bne-instruction on MIPS
At 10 Jul 2006 09:27:19 -0700,
Ian Lance Taylor wrote:
>
> Simon Kagstrom <simon.kagstrom@bth.se> 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