This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Calling convention that gets frame pointer register clobbered
- From: Etienne Lorrain <etienne_lorrain at yahoo dot fr>
- To: gcc at gcc dot gnu dot org
- Cc: Andrew Haley <aph at redhat dot com>
- Date: Fri, 19 Dec 2003 16:14:59 +0100 (CET)
- Subject: 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