#if __BIG_ENDIAN__
/****************************************************************************
* PROJECT: mac os-x FFI assembler, from the os-9 version
* FILE: sqMacFFI.s
* CONTENT:
*
* AUTHOR: Andreas Raab (ar), John McIntosh.
* ADDRESS:
* EMAIL: [email protected]
* RCSID: $Id: sqMacFFI.s 1369 2006-03-22 04:48:20Z johnmci $
*
* NOTES: See change log below.
* 1/24/2002 JMM hacked from the original code for os-x, added save for CCR and
* tweaked _4_gpregs compare
*
* 11/14/2002 JMM clean & fix quad word alignment issue
* 2/24/2006 JMM unable to compile and work on GCC 3.3, perhaps linkage area is 32, not 24?
*****************************************************************************/
#import <architecture/ppc/asm_help.h>
#import <architecture/ppc/pseudo_inst.h>
.text
.globl _ffiCallAddressOf
_ffiCallAddressOf:
mflr r0 /* Save link register */
stw r0, 8(sp)
mfcr r0 /* save CCR */
stw r0, 4(sp)
/* get stack index and preserve it for copying stuff later */
EXTERN_TO_REG(r4, _ffiStackIndex) // lwz r4, ffiStackIndex(r2)
/* compute frame size */
rlwinm r5, r4, 2, 0, 29 /* ffiStackIndex words to bytes (e.g., "slwi r5, r4, 2") */
addi r5, r5, 32+15 /* linkage area */ //* JMM 02/25/06 was 24, Ian has 32 */
rlwinm r5,r5,0,0,27 /* JMM round up to quad word*/
neg r5, r5 /* stack goes down */
stwux sp, sp, r5 /* adjust stack frame */
/* load the stack frame area */
/* note: r4 == ffiStackIndex */
addi r5, sp, 24 /* dst = r1 + linkage area, was 24 */
EXTERN_TO_REG(r6, _ffiStackLocation) //lwz r6, ffiStack(r2) /* src = ffiStack */
li r7, 0 /* i = 0 */
b nextItem
copyItem:
rlwinm r8, r7, 2, 0, 29 /* r8 = i << 2 (e.g., "slwi r8, r7, 2") */
lwzx r0, r6, r8 /* r0 = ffiStack[r8] */
addi r7, r7, 1 /* i = i + 1 */
stwx r0, r5, r8 /* dst[r8] = r0 */
nextItem:
cmpw r7, r4 /* i < ffiStackIndex ? */
blt copyItem
/* Keep addr somewhere so we can load all regs beforehand */
stw r3, 20(sp)
/* load all the floating point registers */
EXTERN_TO_REG(r3, _fpRegCount) //lwz r3, fpRegCount
EXTERN_TO_REG(r12, _FPRegsLocation) // lwz r12, FPRegs(r2)
cmpwi r3, 0 /* skip all fpregs if no FP values used */
beq _0_fpregs /* was lt should be eq */
cmpwi r3, 8
blt _7_fpregs /* skip last N fpregs if unused */
_all_fpregs:
lfd f8, 56(r12)
lfd f9, 64(r12)
lfd f10, 72(r12)
lfd f11, 80(r12)
lfd f12, 88(r12)
lfd f13, 96(r12)
_7_fpregs:
lfd f1, 0(r12)
lfd f2, 8(r12)
lfd f3, 16(r12)
lfd f4, 24(r12)
lfd f5, 32(r12)
lfd f6, 40(r12)
lfd f7, 48(r12)
_0_fpregs:
/* load all the general purpose registers */
EXTERN_TO_REG(r3, _gpRegCount) //lwz r3, gpRegCount
EXTERN_TO_REG(r12, _GPRegsLocation) // lwz r12, GPRegs(r2)
cmpwi r3, 5 /* 5 was 4 in original code but that seems to be a bug? */
blt _4_gpregs /* skip last four gpregs if unused */
_all_gpregs:
lwz r7, 16(r12)
lwz r8, 20(r12)
lwz r9, 24(r12)
lwz r10, 28(r12)
_4_gpregs:
lwz r3, 0(r12)
lwz r4, 4(r12)
lwz r5, 8(r12)
lwz r6, 12(r12)
_0_gpregs:
/* go calling out */
//Note: OS-X mach-o does not use TVectors rather the addr is the entry point
lwz r12, 20(sp) /* fetch addr */
mtctr r12 /* move entry point into count register */
bctrl /* jump through count register and link */
lwz sp, 0(sp) /* restore frame */
/* store the result of the call */
/* more intelligent logic would have a check for type versus assuming all */
EXTERN_TO_REG(r12, _longReturnValueLocation) //lwz r12, longReturnValue(r2)
stw r3, 0(r12)
stw r4, 4(r12)
EXTERN_TO_REG(r12, _floatReturnValueLocation) //lwz r12, longReturnValue(r2)
stfd f1, 0(r12) //stfd f1, floatReturnValue(r2)
/* and get out of here */
lwz r0, 4(sp) /*restore CCR */
mtcrf 0xff,r0
lwz r0, 8(sp) /* restore ltr */
mtlr r0
blr
#endif
|