inline asm: How to push PIC reg before seven input operands get loaded?

Andrew Haley aph@redhat.com
Sat Mar 24 22:15:00 GMT 2007


lynx.abraxas@freenet.de writes:
 > On 24/03/07 18:16:51, Andrew Haley wrote:
 > >  > If I do eg:
 > >  > 
 > >  > Pixel16 *tileData[4]; uint16 *pDestPixel; Pixel16 *dataPtr, *transDataPtr;
 > >  > sint32 startX, endX;
 > >  > __asm__ __volatile__ (
 > >  > "push %%ebx     \n\t"  // save reg for PIC!
 > >  > //code here using %1 but now reg can be rused:
 > >  > 
 > >  > "movl %5, %1            \n\t" //no reg left for %5 when gcc should handel it
 > >  >                               //but now gcc says: 
 > >  >                               //error: memory input 5 is not directly addressable
 > >  > "movl (%1,%%ebx,4), %1 \n\t"  //instead of "movl (%5,%%ebx,4), %1 \n\t" 
 > >  >                               //because m for %5 didn't work here
 > >  > 
 > >  > //more code using also ebx and ebp
 > >  > "pop %%ebx     \n\t" // restore reg for PIC!
 > >  > :
 > >  > : "D" (pDestPixel), "d" (endX), "c" (startX), "a" (transDataPtr), "S" (dataPtr), "m" (tileData)
 > > 
 > >  > : "cc" //don't tell gcc about what was done to ebx because of PIC!!!
 > >  > );
 > >  > 
 > >  > gcc complains about: error: memory input 5 is not directly addressable
 > > 
 > >  > Why is that? How else should I load the tileData pointer from
 > >  > memory into a register?
 > > 
 > > I wouldn't be using the "m" constraint for this.  Pass in the pointer
 > > as an operand using constraint "r" or "g".  Something like "g"(&tileData);
 > > 
 > > Can you post some small sample code?  Make it the shortest possible
 > > programs that shows your problem.  Make sure all the types it needs
 > > are defined.
 > 
 > This  is  a problem. My task is to tranlate this inline asm written for MSC to
 > gcc. It's from a big game (Call to Power II, CTP2). I've attached a file  with
 > the  function  that  contains  the  code.  But  it  won't compile withou a lot
 > modifications outside the source tree.

And you can't figure out how to provide the typedefs it needs...

 > At L131 my translation starts. It has the constrains I got it to compile  with
 > but  segfaults  then.  I  noticed that using any other var than tileData works
 > with "m". Could it be a problem for  gcc  to  use  the  double  pointer  here:
 > Pixel16 **tileData ?

 > >   >  >   >  Also I wonder which -f option that comes with -O2 makes gcc stop
 > reporting:
 > >  > >  > error: can't find a register in class 'LEGACY_REGS' while  reloading
 > 'asm'
 > >  > >
 > >  > > I guess this is a joke.
 > >  >
 > >  > No, it isn't. I wouldn't have asked else wise...
 > >
 > > Reload has run out of registers.  It's telling you that it needs
 > > another one.  A -f option is not going to give reload another
 > > register.
 > 
 > The  point  is,  if  I  just add -O2 to the g++ cammand, this error disappears
 > without having changed anything in the code or the number of register the part
 > uses.

Sure, because gcc is optimizing, and thus it uses fewer registers.

 > It  seems  that  an  option  in -O2 or above lets g++ be able to cope with the
 > registers I have left it (ebx and ebp, esp). I found this solution quite often
 > on the net.

 > >  > Is it the combination of all -f options in -O2? I coudn't find a
 > >  > single obviouse one in the manpage.  Is it a rule then to include
 > >  > -O2 or higher if inline asm is used???
 > >
 > > No, there's no such rule.  You've run out of registers.
 > >
 > > gcc needs one or two spare registers to work with.  The x86 has eight,
 > > some of which are used for special purposes.  You are using five in
 > > your asm.  This is a very tight situation.
 > 
 > Compiling all this with -fomit-frame-pointer:
 > 
 > Can gcc not push all registers, and give me all seven without esp?
 > 
 > I also tryed to use "R" instead of "m" for tileData. It compiled
 > without errors even when I had specified -fPIC.

Excellent.  That one is solved, then.

 > -fPIC seems to use ebx so I pushed and poped that in my asm
 > code. But when looking at the disassembly I had to see gcc used ebx
 > for tileData and not ebp.

OK.

 >  But if I specified "b" it complains about: error: PIC register
 > %ebx clobbered in asm
 > 
 > Is this a bug in gcc??? Is there a constraint just for ebp so I
 > don't have to use "R" and hope it gets into ebp?

Why do you care that it is in ebp?  Why do you not allow gcc to choose
the register?  You seem to want to use explicit registers in your asm,
but I can't see any reason why you want to do that.  gcc usually works
better when you let gcc choose the registers.

Andrew.



More information about the Gcc-help mailing list