GCC fubaring register
GCC fubaring register
- Subject: GCC fubaring register
- From: Ryan Govostes <email@hidden>
- Date: Mon, 12 Jun 2006 16:32:12 -0400
I'm working with the following function, trimmed down to demonstrate
my problem
static void exampleFunc (long *a) {
unsigned long toc;
asm("mr %0, r2\n\t" : "=r" (toc) : : "r2" );
// ...
asm("mr r2, %0\n\t" : : "r" (toc) : );
secondFunc(a);
}
Essentially, I need to preserve the contents of the TOC (r2) - if it
has changed by the time it calls secondFunc(), a horrible crash will
ensue. What I've tried to do is to store the contents of the register
before doing anything else, and then reset the value immediately
before calling secondFunc(). For added protection, the first inline
ASM line tells GCC that r2 has been "clobbered," which I understand
to mean that it shouldn't be used again throughout the function for
any purpose.
Looking at the assembly produced by GCC in compiling the above,
however, shows that all of this is being disregarded. At 0x000020d0
we're saving r2 to our toc variable, and at 0x000020d8 we're loading
it back, but at 0x000020dc GCC has slipped some instructions to
overwrite the value of r2, between my inline ASM and the call to
secondFunc().
0x000020ac mflr r0
0x000020b0 stmw r30,-8(r1)
0x000020b4 stw r0,8(r1)
0x000020b8 stwu r1,-96(r1)
0x000020bc mr r30,r1
0x000020c0 bcl- 20,4*cr7+so,0x20c4 24>
0x000020c4 mflr r31
0x000020c8 stw r3,120(r30)
0x000020cc mr r0,r2 // First inline ASM ... move r2 into r0
0x000020d0 stw r0,56(r30) // store it in memory (unsigned long toc)
// Rest of function would go here
0x000020d4 lwz r0,56(r30) // Second inline ASM... load toc into r0
0x000020d8 mr r2,r0 // move r0 into r2 -- now we've got the
same value we started with
0x000020dc addis r2,r31,0 // But wait, now it's overwriting r2
with something else!
0x000020e0 addi r2,r2,12100
0x000020e4 lwz r0,0(r2)
0x000020e8 lwz r3,120(r30)
0x000020ec mr r12,r0
0x000020f0 mtctr r12
0x000020f4 bctrl // Call to secondFunc()
0x000020f8 lwz r1,0(r1)
0x000020fc lwz r0,8(r1)
0x00002100 mtlr r0
0x00002104 lmw r30,-8(r1)
0x00002108 blr
Is there any other way I can tell gcc that I *really* don't want it
to use r2 for anything else? I also considered an intermediary
function, written entirely in assembly that would restore the TOC and
then call the function, but I don't see that as being very graceful.
Any thoughts?
Thanks,
Ryan Govostes
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden