#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: johnmci@smalltalkconsulting.com * 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 #import .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