#ifndef __PIC__ # define REG "ebx" #else # define REG "ebp" #endif
#ifndef NBEFORE void some_function_before(){ } #endif void test_function (){ long var = 42; asm volatile( "inc %0\n#DEBUG %%0=%0, clobber: %%"REG", ..." :"+rm"(var) : :"%"REG"","%ecx","%esi","%edi","%edx","%eax"); } ======================== This little piece of code did several strange things for different flags: 1. #DEBUG %0=%ebp, clobber: %ebp, ... e.g. -fPIC -fomit-frame-pointer -O2, not -DNBEFORE This is the core of my bug report. The compiler should never ever use a register from the clobber list to store an operand. It doesn't do this for ebx, and it doen't do this if there function containing the asm is the first in the translation unit. But for ebp and with another function before, this strange bug occurs. Another function making a difference looks a bit like bug 28635 2. can't find a register in class 'GENERAL_REGS' while reloading 'asm' e.g. -O1, not -fomit-frame-pointer This seems to be a problem of -O1. Probably the compiler decides to use the r alternative and has problems falling back to m when this does not work. Perhaps the rationale is that gcc only looks at how to get the variables into the asm code with the least number of operations, and it's the programmer's task to make sure all mentioned operand constraints are possible on the target architecture. But this would be strange. If it were -O0 instead of -O1 I'd say it's bug 11203 3. #DEBUG %0=-12(%ebp), clobber: %ebp, ... e.g. -fPIC -O0, not -fomit-frame-pointer Seems like clobber lists get completely ignored for -O0. Perhaps this makes sense, as the compiler doen't have to care about registers being clobbered if all variables are stored in memory. Still this is strange behaviour. This is bug 11807 -- Summary: ebp from clobber list used as operand Product: gcc Version: 4.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: inline-asm AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: Martin dot vGagern at gmx dot net GCC build triplet: i686-pc-linux-gnu-gcc GCC host triplet: i686-pc-linux-gnu-gcc GCC target triplet: i686-pc-linux-gnu-gcc http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28686