This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Calling convention that gets frame pointer register clobbered


 --- Andrew Haley wrote?:
> This is really getting to be off-topic for the gcc developer's list.
> 
> Etienne Lorrain writes:
>  >     short ret, tmp;
>  >     asm (
>  > " pushl %es           \n"
>  > " int $0x15           \n"
>  > " movw %es:3(%bp),%ax \n"
>  > " movzbl %ah,%0        \n"
>  > " popl %es            \n"
>  >         : "=g" (ret), "=a" (tmp)
>  >         :
>  >         : "ebp"
>  >         };
>  >     return ret;
>  >     }
>  >   Does not work if "=g" (ret) is a stack reference because the
>  >  stack pointer is modified by push/pop %es - it does work for
>  >  anything else.
> 
> Why not use "=r" (ret)  ?

  It is basically what I do to get a working executable, but when
 looking at the assembler generated on ia32, you can often see the
 price of forcing something in register by the number of instruction
 added (save/restore/reload around your asm()). On ia32 you also have
 the problem of the size of the access, a "=g" would fit
 byte/half word/word but you have to do "=q" for byte registers -
 there is just four of them, just two which shall not be invariant
 through function calls: %ax and %dx...
 This function is inlined so it depends where and how many
 time it is called - I cannot give you a real use case where it
 had matter that much.
  What I can remember is how long it takes to find the bug - previous
 GCC not optimising that much had a free register at that point.

  I can still say that asm("") efficiency does matter sometimes,
 for instance on my graphic library (see gujin on sourceforge),
 I have to use asm("") to access the "gs:" segment to print a pixel,
 to finally print letters and the whole screen at high definition.

 Then you can see in the assembler the price of not using the
 standard access method for variable/pointer but a mere
 " movl %1,%gs:%2 " : : "g" (data) : "g" (address)
 It seem transparent enough but, for instance, will not be optimised
 to movs or stos when some optimisation would have been done on
 usual variable. Or a movzbl or movzwl would have been detected
 by the optimiser. Or the processor flags are destroyed by asm()
 and a test has to be re-done.

 No, no - I am not claiming that you should be able to do:
unsigned short *pixel16bpp attribute ((segment("gs")));
 because I cannot pay anybody to do the patch.
 That would also be usefull for (search "FS base and GS base" in):
http://www.sandpile.org/aa64/msr.htm
 if someone would like to find a "real" application.
 And it would have to be generic across processor:
union {
  unsigned all;
  struct {
    unsigne bitfields:3;
    ...;
    } bits;
  } powerpc_spr_35 attribute ((packed, segment("spr")));
 to use "mfspr"/"mtspr" instead of load/store to access
 the value.
 Shall not do on ia32 neither:
struct uart_t uart attribute ((segment("ioport")));

 I hope I gonna have a nice turkey for Xmas,
 Etienne.


_________________________________________________________________
Do You Yahoo!? -- Une adresse @yahoo.fr gratuite et en français !
Yahoo! Mail : http://fr.mail.yahoo.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]