*** src/powerpc/aix.S.ORIG Fri Aug 28 15:04:18 2009 --- src/powerpc/aix.S Fri Aug 28 15:05:06 2009 *************** *** 88,101 **** .toc .csect .text[PR] .align 2 - .globl ffi_prep_args .csect .text[PR] .align 2 .globl ffi_call_AIX .globl .ffi_call_AIX .csect ffi_call_AIX[DS] ffi_call_AIX: .long .ffi_call_AIX, TOC[tc0], 0 .csect .text[PR] .ffi_call_AIX: --- 88,233 ---- .toc .csect .text[PR] .align 2 .csect .text[PR] .align 2 + #ifdef __64BIT__ + /* void ffi_call_AIX(extended_cif *ecif, unsigned long bytes, + * unsigned int flags, unsigned int *rvalue, + * void (*fn)(), + * void (*prep_args)(extended_cif*, unsigned *const)); + * r3=ecif, r4=bytes, r5=flags, r6=rvalue, r7=fn, r8=prep_args + */ + .globl ffi_call_AIX .globl .ffi_call_AIX .csect ffi_call_AIX[DS] ffi_call_AIX: + .llong .ffi_call_AIX, TOC[tc0], 0 + .csect .text[PR] + .ffi_call_AIX: + // We only need r12 until the call, so it doesn't have to be saved... + + mr r12,r8 /* r8 is prep_args() */ + + /* Save the old stack pointer as AP. */ + + mr r8,r1 + + /* Allocate the stack space we need. */ + + stdux r1,r1,r4 /* r4 is -cif->bytes */ + + /* Save registers we use. */ + + mflr r9 /* r9 becomes return address */ + + std r28,-32(r8) + std r29,-24(r8) + std r30,-16(r8) + std r31, -8(r8) + + std r9, 16(r8) /* save return address */ + std r2, 40(r1) /* save TOC pointer */ + + /* Save arguments over call... */ + mr r31,r5 /* flags, */ + mr r30,r6 /* rvalue, */ + mr r29,r7 /* fn() */ + mr r28,r8 /* our AP. */ + + /* Call ffi_prep_args. */ + /* r3 is already &ecif */ + mr r4,r1 /* r4 becomes stack pointer */ + li r9,0 + + ld r2,8(r12) /* TOC of prep_args() */ + ld r12,0(r12) /* trampoline */ + mtctr r12 /* r12 holds address of prep_args() */ + bctrl + ld r2,40(r1) /* restore TOC */ + + /* Now do the call. */ + + ld r12,0(r29) /* r29 is fn(), r12 its trampoline */ + /* Set up cr1 with bits 4-7 of the flags. */ + mtcrf 0x40,r31 /* r31 is cif->flags */ + std r2,40(r1) /* save current TOC */ + mtctr r12 /* load ctr with fn() pointer */ + ld r2,8(r29) /* r2 is TOC of fn() */ + /* Load all those argument registers. */ + // We have set up a nice stack frame, just load it into registers. + ld r3, 40+(1*8)(r1) + ld r4, 40+(2*8)(r1) + ld r5, 40+(3*8)(r1) + ld r6, 40+(4*8)(r1) + nop + ld r7, 40+(5*8)(r1) + ld r8, 40+(6*8)(r1) + ld r9, 40+(7*8)(r1) + ld r10,40+(8*8)(r1) + + L1: + /* Load all the FP registers. */ + bf 6,L2 // 2f + 0x18 + lfd f1,-32-(13*8)(r28) + lfd f2,-32-(12*8)(r28) + lfd f3,-32-(11*8)(r28) + lfd f4,-32-(10*8)(r28) + nop + lfd f5,-32-(9*8)(r28) + lfd f6,-32-(8*8)(r28) + lfd f7,-32-(7*8)(r28) + lfd f8,-32-(6*8)(r28) + nop + lfd f9,-32-(5*8)(r28) + lfd f10,-32-(4*8)(r28) + lfd f11,-32-(3*8)(r28) + lfd f12,-32-(2*8)(r28) + nop + lfd f13,-32-(1*8)(r28) + + L2: + /* Make the call. */ + bctrl + ld r2,40(r1) /* restore TOC */ + + /* Now, deal with the return value. */ + mtcrf 0x01,r31 + + bt 30,L(done_return_value) + bt 29,L(fp_return_value) + std r3,0(r30) + bf 28,L(done_return_value) + std r4,8(r30) + + /* Fall through... */ + + L(done_return_value): + /* Restore the registers we used and return. */ + ld r9, 16(r28) + ld r31, -8(r28) + mtlr r9 + ld r30, -16(r28) + ld r29,-24(r28) + ld r28,-32(r28) + ld r1,0(r1) + blr + + L(fp_return_value): + bf 28,L(float_return_value) + stfd f1,0(r30) + b L(done_return_value) + L(float_return_value): + stfs f1,0(r30) + b L(done_return_value) + .long 0 + .byte 0,0,0,1,128,4,0,0 + #else /* ! __64BIT__ */ + .globl ffi_call_AIX + .globl .ffi_call_AIX + .csect ffi_call_AIX[DS] + ffi_call_AIX: .long .ffi_call_AIX, TOC[tc0], 0 .csect .text[PR] .ffi_call_AIX: *************** *** 208,213 **** --- 340,346 ---- b L(done_return_value) .long 0 .byte 0,0,0,1,128,4,0,0 + #endif /* ! __64BIT__ */ //END(ffi_call_AIX) .csect .text[PR] *************** *** 216,222 **** --- 349,359 ---- .globl .ffi_call_DARWIN .csect ffi_call_DARWIN[DS] ffi_call_DARWIN: + #ifdef __64BIT__ + .llong .ffi_call_DARWIN, TOC[tc0], 0 + #else .long .ffi_call_DARWIN, TOC[tc0], 0 + #endif .csect .text[PR] .ffi_call_DARWIN: blr *** src/powerpc/aix_closure.S.ORIG Fri Aug 28 15:04:25 2009 --- src/powerpc/aix_closure.S Fri Aug 28 15:05:06 2009 *************** *** 91,101 **** --- 91,269 ---- .csect .text[PR] .align 2 + #ifdef __64BIT__ .globl ffi_closure_ASM .globl .ffi_closure_ASM .csect ffi_closure_ASM[DS] + ffi_closure_ASM: + .llong .ffi_closure_ASM, TOC[tc0], 0 + .csect .text[PR] + .ffi_closure_ASM: + + mflr r0 /* extract return address */ + std r0, 16(r1) /* save the return address */ + + /* 48 Bytes (Linkage Area) */ + /* 64 Bytes (output params 8*8) */ + /* 104 Bytes (13*8 from FPR) */ + /* 32 Bytes (result) */ + /* 248 Bytes */ + + stdu r1,-248(r1) /* skip over caller save area */ + + /* we want to build up an area for the parameters passed + * in registers (both floating point and integer) */ + + /* 256 bytes (callee stack frame aligned to 32 + * 48 bytes (caller linkage area) + * 304 (start of caller parameter aligned to 8 + */ + + + /* we store gpr 3 to gpr 10 in the parents outgoing area */ + + std r3, (304+0*8)(r1) + std r4, (304+1*8)(r1) + std r5, (304+2*8)(r1) + std r6, (304+3*8)(r1) + std r7, (304+4*8)(r1) + std r8, (304+5*8)(r1) + std r9, (304+6*8)(r1) + std r10, (304+7*8)(r1) + + /* next save fpr 1 to fpr 13 */ + + stfd f1, (112+0*8)(r1) + stfd f2, (112+1*8)(r1) + stfd f3, (112+2*8)(r1) + stfd f4, (112+3*8)(r1) + stfd f5, (112+4*8)(r1) + stfd f6, (112+5*8)(r1) + stfd f7, (112+6*8)(r1) + stfd f8, (112+7*8)(r1) + stfd f9, (112+8*8)(r1) + stfd f10, (112+9*8)(r1) + stfd f11, (112+10*8)(r1) + stfd f12, (112+11*8)(r1) + stfd f13, (112+12*8)(r1) + + /* set up registers for the routine that actually does the work + * get the context pointer from the trampoline + */ + mr r3,r11 + + /* now load up the pointer to the result storage + * current stack frame size - ((8 * 4) + saved registers) + */ + addi r4,r1,216 + + /* now load up the pointer to the saved gpr registers */ + addi r5,r1,304 + + /* now load up the pointer to the saved fpr registers */ + addi r6,r1,112 + + /* make the call + * int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue, + * unsigned long * pgr, ffi_dblfl * pfr) + */ + + bl .ffi_closure_helper_DARWIN + nop + + /* now r3 contains the return type */ + /* so use it to look up in a table */ + /* so we know how to deal with each type */ + + /* look up the proper starting point in table */ + /* by using return type as offset */ + addi r5,r1,216 /* get pointer to results area */ + ld r4,LC..60(r2) /* get address of jump table */ + sldi r3,r3,2 /* now multiply return type by 4 */ + lwzx r3,r4,r3 /* get the contents of that table value */ + add r3,r3,r4 /* add contents of table to table address */ + mtctr r3 + bctr /* jump to it */ + + L..60: + .long L..44-L..60 /* FFI_TYPE_VOID */ + .long L..50-L..60 /* FFI_TYPE_INT */ + .long L..47-L..60 /* FFI_TYPE_FLOAT */ + .long L..46-L..60 /* FFI_TYPE_DOUBLE */ + .long L..62-L..60 /* FFI_TYPE_LONGDOUBLE */ + .long L..56-L..60 /* FFI_TYPE_UINT8 */ + .long L..55-L..60 /* FFI_TYPE_SINT8 */ + .long L..58-L..60 /* FFI_TYPE_UINT16 */ + .long L..57-L..60 /* FFI_TYPE_SINT16 */ + .long L..50-L..60 /* FFI_TYPE_UINT32 */ + .long L..50-L..60 /* FFI_TYPE_SINT32 */ + .long L..48-L..60 /* FFI_TYPE_UINT64 */ + .long L..48-L..60 /* FFI_TYPE_SINT64 */ + .long L..44-L..60 /* FFI_TYPE_STRUCT */ + .long L..48-L..60 /* FFI_TYPE_POINTER */ + + + /* case double */ + L..46: + lfd f1,0(r5) + b L..44 + + /* case long double */ + L..62: + lfd f1,0(r5) + lfd f2,8(r5) + b L..44 + + /* case float */ + L..47: + lfs f1,0(r5) + b L..44 + + /* case long long */ + L..48: + ld r3,0(r5) + b L..44 + + /* case int / int32 / uint32*/ + L..50: + lwz r3,4(r5) + b L..44 + + /* case signed int8 */ + L..55: + lbz r3,7(r5) + extsb r3,r3 + b L..44 + + /* case unsigned int8 */ + L..56: + lbz r3,7(r5) + b L..44 + + /* case signed int16 */ + L..57: + lha r3,6(r5) + b L..44 + + /* case unsigned int16 */ + L..58: + lhz r3,6(r5) + b L..44 + + /* case void / done */ + L..44: + addi r1,r1,248 /* restore stack pointer */ + ld r0,16(r1) /* get return address */ + mtlr r0 /* reset link register */ + blr + #else /* ! __64BIT__ */ + .globl ffi_closure_ASM + .globl .ffi_closure_ASM + .csect ffi_closure_ASM[DS] + + ffi_closure_ASM: .long .ffi_closure_ASM, TOC[tc0], 0 .csect .text[PR] .ffi_closure_ASM: *************** *** 106,113 **** /* 24 Bytes (Linkage Area) */ /* 32 Bytes (params) */ /* 104 Bytes (13*8 from FPR) */ ! /* 8 Bytes (result) */ ! /* 168 Bytes */ stwu r1,-176(r1) /* skip over caller save area keep stack aligned to 16 */ --- 274,281 ---- /* 24 Bytes (Linkage Area) */ /* 32 Bytes (params) */ /* 104 Bytes (13*8 from FPR) */ ! /* 16 Bytes (result) */ ! /* 176 Bytes */ stwu r1,-176(r1) /* skip over caller save area keep stack aligned to 16 */ *************** *** 243,247 **** --- 411,416 ---- lwz r0,8(r1) /* get return address */ mtlr r0 /* reset link register */ blr + #endif /* __64BIT__ */ /* END(ffi_closure_ASM) */ *** src/powerpc/ffitarget.h.ORIG Fri Aug 28 15:04:31 2009 --- src/powerpc/ffitarget.h Fri Aug 28 15:05:06 2009 *************** *** 30,36 **** /* ---- System specific configurations ----------------------------------- */ ! #if defined (POWERPC) && defined (__powerpc64__) #define POWERPC64 #endif --- 30,40 ---- /* ---- System specific configurations ----------------------------------- */ ! #if defined (POWERPC) && defined (__powerpc64__) /* linux64 */ ! #define POWERPC64 ! #elif defined(POWERPC_DARWIN) && defined (__ppc64__) /* Darwin */ ! #define POWERPC64 ! #elif defined(POWERPC_AIX) && defined (__64BIT__) /* AIX */ #define POWERPC64 #endif There are no differences between the files.