[Mono-dev] Question on PPC and porting..

Steven Munroe munroesj at linux.vnet.ibm.com
Mon Apr 27 11:57:36 EDT 2009

On Sun, 2009-04-26 at 10:58 -0400, Randall Stewart wrote:
> Hi all:
> I am new to the list and am currently working on getting mono
> to work with AIX (5.3 initially and then later 6.1) ;-)
> I have been examining the ppc register storing routines and I find
> in apple (ppc) the following from a simple call:
> 0x1edc <foo>:	mflr    r0
> 0x1ee0 <foo+4>:	stmw    r30,-8(r1)
> 0x1ee4 <foo+8>:	stw     r0,8(r1)
> 0x1ee8 <foo+12>:	stwu    r1,-96(r1)
> 0x1eec <foo+16>:	mr      r30,r1
> 0x1ef0 <foo+20>:	stw     r3,120(r30)
> 0x1ef4 <foo+24>:	stw     r4,124(r30)
> 0x1ef8 <foo+28>:	stw     r5,128(r30)
> 0x1efc <foo+32>:	stw     r6,132(r30)

Saving "foo" parameters into the parm save area of the previous frame
which is correct per the ABI.

> 0x1f00 <foo+36>:	lwz     r3,120(r30)
> 0x1f04 <foo+40>:	lwz     r4,124(r30)
> 0x1f08 <foo+44>:	lwz     r5,128(r30)
> 0x1f0c <foo+48>:	lwz     r6,132(r30)
> 0x1f10 <foo+52>:	bl      0x1e14 <fee>

"fee" would use the parm save area of this frame if it was needed.
remember in the ABI this frame only has to reserve space for largest
case for the functions it calls but does not have to initialize it. The
parameter list it calle save.

> 0x1f14 <foo+56>:	mr      r0,r3
> 0x1f18 <foo+60>:	stw     r0,56(r30)
> 0x1f1c <foo+64>:	lwz     r0,56(r30)
> 0x1f20 <foo+68>:	mr      r3,r0
> 0x1f24 <foo+72>:	lwz     r1,0(r1)
> 0x1f28 <foo+76>:	lwz     r0,8(r1)
> 0x1f2c <foo+80>:	mtlr    r0
> 0x1f30 <foo+84>:	lmw     r30,-8(r1)
> 0x1f34 <foo+88>:	blr
> Now I am trying to make sure my call chain offsets and such
> are correct... the sp+8 is correct i.e. in arch/tramp.c
> matches the apple type.
> I also note that they are using r30 as the index to
> the stack.. where as r31 is used in xlc (and gcc too in aix).
> Now what makes me puzzled is the offset to stack_param's
> For apple its defined as 24. Now this sort of matches what
> is happening here.. its storing the registers at +24 to the
> OLD stack... not the new one. i.e. 96+24 = 120.
There are Darwin and Linux ABIs already implemented which are slightly
different from each other and from AIX. Please guard any changes you
make for AIX only. The frame pointer can be 30 or 31 as long as the Call
Frame info its correct.

+24 is the parm save area of the previous frame which is correct. Read
the ABI!

> This is also what happens in the xlc assembly as well. It appears
> that each function locally allocates storage for its callers (not  
> itself)
> to use. When a function needs to use registers it stores
> the old value in the function's callers stack NOT any locally
> allocated stack.

Parms are handled differently from nonvolatile (r14-r31). Nonvolatile's
are saved in the calle's frame (in this case r30-31), parameters are
(optionally) saved in the callers frame.

Note: negative stack accesses are not allowed in the Linux powerpc32
ABI. Technically mono is in violation here. AIX does allow this, not
sure about Darwin.

> Where as it appears the emit_save_parameters() routine is just
> taking that offset for the emission of parameters... i.e. it
> stores the registers in its allocated stack. This seems to me
> that if a regular library function was being called that library
> function would then overwrite those saved values.
> Now either I am mis-reading the code, or maybe the assembly (I am a
> bit rusty on ppc assembly). If someone could point out what I
> am mis-reading I would appreciate it.

This parm save is correct per the ABI.

Steven Munroe
IBM Linux technology Center
Toolchain Architect.

More information about the Mono-devel-list mailing list