• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
GCC fubaring register
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • Follow-Ups:
    • Re: GCC fubaring register
      • From: Andrew Pinski <email@hidden>
    • Re: GCC fubaring register
      • From: Andrew Pinski <email@hidden>
  • Prev by Date: dyld binding problem
  • Next by Date: Re: GCC fubaring register
  • Previous by thread: dyld binding problem
  • Next by thread: Re: GCC fubaring register
  • Index(es):
    • Date
    • Thread