Commit 5751cf6f by David Edelsohn Committed by David Edelsohn

re PR libffi/35484 (libffi doesn't support AIX 64bit)

2009-11-30  David Edelsohn  <edelsohn@gnu.org>

        PR target/35484
        * src/powerpc/ffitarget.h (POWERPC64): Define for PPC64 Linux and
        AIX64.
        * src/powerpc/aix.S: Implement AIX64 version.
        * src/powerpc/aix_closure.S: Implement AIX64 version.
        (ffi_closure_ASM): Use extsb, lha and displament addresses.
        * src/powerpc/ffi_darwin.c (ffi_prep_args): Implement AIX64
        support.
        (ffi_prep_cif_machdep): Same.
        (ffi_call): Same.
        (ffi_closure_helper_DARWIN): Same.

From-SVN: r154855
parent 17f35e23
2009-11-30 David Edelsohn <edelsohn@gnu.org>
PR target/35484
* src/powerpc/ffitarget.h (POWERPC64): Define for PPC64 Linux and
AIX64.
* src/powerpc/aix.S: Implement AIX64 version.
* src/powerpc/aix_closure.S: Implement AIX64 version.
(ffi_closure_ASM): Use extsb, lha and displament addresses.
* src/powerpc/ffi_darwin.c (ffi_prep_args): Implement AIX64
support.
(ffi_prep_cif_machdep): Same.
(ffi_call): Same.
(ffi_closure_helper_DARWIN): Same.
2009-11-02 Andreas Tobler <a.tobler@schweiz.org>
PR libffi/41908
......
/* -----------------------------------------------------------------------
aix.S - Copyright (c) 2002 Free Software Foundation, Inc.
aix.S - Copyright (c) 2002,2009 Free Software Foundation, Inc.
based on darwin.S by John Hornkvist
PowerPC Assembly glue.
......@@ -86,9 +86,13 @@
#define L(x) x
.file "aix.S"
.toc
.csect .text[PR]
.align 2
.globl ffi_prep_args
/* 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
*/
.csect .text[PR]
.align 2
......@@ -96,10 +100,124 @@
.globl .ffi_call_AIX
.csect ffi_call_AIX[DS]
ffi_call_AIX:
#ifdef __64BIT__
.llong .ffi_call_AIX, TOC[tc0], 0
.csect .text[PR]
.ffi_call_AIX:
mr r12,r8 // We only need r12 until the call, so it doesn't have to be saved...
/* Save the old stack pointer as AP. */
mr r8,r1
/* Allocate the stack space we need. */
stdux r1,r1,r4
/* Save registers we use. */
mflr r9
std r28,-32(r8)
std r29,-24(r8)
std r30,-16(r8)
std r31, -8(r8)
std r9, 16(r8)
std r2, 40(r1)
/* Save arguments over call... */
mr r31,r5 /* flags, */
mr r30,r6 /* rvalue, */
mr r29,r7 /* function address, */
mr r28,r8 /* our AP. */
/* Call ffi_prep_args. */
mr r4,r1
li r9,0
ld r2,8(r12)
ld r12,0(r12)
mtctr r12 // r12 holds address of _ffi_prep_args
bctrl
ld r2,40(r1)
/* Now do the call. */
ld r12,0(r29)
/* Set up cr1 with bits 4-7 of the flags. */
mtcrf 0x40,r31
std r2,40(r1)
mtctr r12
ld r2,8(r29)
/* 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)
/* 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,4(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)
#else /* ! __64BIT__ */
.long .ffi_call_AIX, TOC[tc0], 0
.csect .text[PR]
.ffi_call_AIX:
mr r12,r8 // We only need r12 until the call, so it doesn't have to be saved...
mr r12,r8 // We only need r12 until the call, so it doesn't have to be saved...
/* Save the old stack pointer as AP. */
mr r8,r1
......@@ -142,15 +260,15 @@ ffi_call_AIX:
lwz r2,4(r29)
/* Load all those argument registers. */
// We have set up a nice stack frame, just load it into registers.
lwz r3, 20+(1*4)(r1)
lwz r4, 20+(2*4)(r1)
lwz r5, 20+(3*4)(r1)
lwz r6, 20+(4*4)(r1)
lwz r3, 20+(1*4)(r1)
lwz r4, 20+(2*4)(r1)
lwz r5, 20+(3*4)(r1)
lwz r6, 20+(4*4)(r1)
nop
lwz r7, 20+(5*4)(r1)
lwz r8, 20+(6*4)(r1)
lwz r9, 20+(7*4)(r1)
lwz r10,20+(8*4)(r1)
lwz r7, 20+(5*4)(r1)
lwz r8, 20+(6*4)(r1)
lwz r9, 20+(7*4)(r1)
lwz r10,20+(8*4)(r1)
L1:
/* Load all the FP registers. */
......@@ -165,17 +283,17 @@ L1:
lfd f7,-16-(7*8)(r28)
lfd f8,-16-(6*8)(r28)
nop
lfd f9,-16-(5*8)(r28)
lfd f10,-16-(4*8)(r28)
lfd f11,-16-(3*8)(r28)
lfd f12,-16-(2*8)(r28)
lfd f9,-16-(5*8)(r28)
lfd f10,-16-(4*8)(r28)
lfd f11,-16-(3*8)(r28)
lfd f12,-16-(2*8)(r28)
nop
lfd f13,-16-(1*8)(r28)
lfd f13,-16-(1*8)(r28)
L2:
/* Make the call. */
bctrl
lwz r2,20(r1)
lwz r2,20(r1)
/* Now, deal with the return value. */
mtcrf 0x01,r31
......@@ -190,8 +308,8 @@ L2:
L(done_return_value):
/* Restore the registers we used and return. */
lwz r9, 8(r28)
lwz r31, -4(r28)
lwz r9,8(r28)
lwz r31,-4(r28)
mtlr r9
lwz r30, -8(r28)
lwz r29,-12(r28)
......@@ -206,6 +324,7 @@ L(fp_return_value):
L(float_return_value):
stfs f1,0(r30)
b L(done_return_value)
#endif
.long 0
.byte 0,0,0,1,128,4,0,0
//END(ffi_call_AIX)
......@@ -216,7 +335,11 @@ L(float_return_value):
.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
......
/* -----------------------------------------------------------------------
aix_closure.S - Copyright (c) 2002 2003 Free Software Foundation, Inc.
aix_closure.S - Copyright (c) 2002, 2003, 2009 Free Software Foundation, Inc.
based on darwin_closure.S
PowerPC Assembly glue.
......@@ -94,8 +94,162 @@ LC..60:
.globl ffi_closure_ASM
.globl .ffi_closure_ASM
.csect ffi_closure_ASM[DS]
ffi_closure_ASM:
#ifdef __64BIT__
.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 (params) */
/* 104 Bytes (13*8 from FPR) */
/* 32 Bytes (result) */
/* 248 Bytes */
stdu r1,-248(r1) /* skip over caller save area
keep stack aligned to 16 */
/* we want to build up an area for the parameters passed */
/* in registers (both floating point and integer) */
/* we store gpr 3 to gpr 10 (aligned to 4)
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 (aligned to 8) */
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 */
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 */
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(2) /* 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..51-L..60 /* FFI_TYPE_INT */
.long L..47-L..60 /* FFI_TYPE_FLOAT */
.long L..46-L..60 /* FFI_TYPE_DOUBLE */
.long L..45-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..51-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 long double */
L..45:
lfd f1,0(r5)
lfd f2,8(r5)
b L..44
/* case double */
L..46:
lfd f1,0(r5)
b L..44
/* case float */
L..47:
lfs f1,0(r5)
b L..44
/* case long long / pointer */
L..48:
ld r3,0(r5)
b L..44
/* case uint32 */
L..50:
lwz r3,4(r5)
b L..44
/* case int / sint32 */
L..51:
lwa 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)
/* 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__ */
.long .ffi_closure_ASM, TOC[tc0], 0
.csect .text[PR]
.ffi_closure_ASM:
......@@ -106,8 +260,8 @@ ffi_closure_ASM:
/* 24 Bytes (Linkage Area) */
/* 32 Bytes (params) */
/* 104 Bytes (13*8 from FPR) */
/* 8 Bytes (result) */
/* 168 Bytes */
/* 16 Bytes (result) */
/* 176 Bytes */
stwu r1,-176(r1) /* skip over caller save area
keep stack aligned to 16 */
......@@ -177,7 +331,7 @@ L..60:
.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..46-L..60 /* FFI_TYPE_LONGDOUBLE */
.long L..45-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 */
......@@ -190,6 +344,12 @@ L..60:
.long L..50-L..60 /* FFI_TYPE_POINTER */
/* case long double */
L..45:
lfd f1,0(r5)
lfd f2,8(r5)
b L..44
/* case double */
L..46:
lfd f1,0(r5)
......@@ -211,31 +371,25 @@ L..50:
lwz r3,0(r5)
b L..44
/* case signed int8 */
/* case signed int8 */
L..55:
addi r5,r5,3
lbz r3,0(r5)
slwi r3,r3,24
srawi r3,r3,24
lbz r3,3(r5)
extsb r3,r3
b L..44
/* case unsigned int8 */
/* case unsigned int8 */
L..56:
addi r5,r5,3
lbz r3,0(r5)
lbz r3,3(r5)
b L..44
/* case signed int16 */
L..57:
addi r5,r5,2
lhz r3,0(r5)
extsh r3,r3
lha r3,2(r5)
b L..44
/* case unsigned int16 */
L..58:
addi r5,r5,2
lhz r3,0(r5)
lhz r3,2(r5)
/* case void / done */
L..44:
......@@ -243,5 +397,5 @@ L..44:
lwz r0,8(r1) /* get return address */
mtlr r0 /* reset link register */
blr
#endif
/* END(ffi_closure_ASM) */
......@@ -30,7 +30,11 @@
/* ---- System specific configurations ----------------------------------- */
#if defined (POWERPC) && defined (__powerpc64__)
#if defined (POWERPC) && defined (__powerpc64__) /* linux64 */
#define POWERPC64
#elif defined (POWERPC_DARWIN) && defined (__ppc64__) /* Darwin */
#define POWERPC64
#elif defined (POWERPC_AIX) && defined (__64BIT__) /* AIX64 */
#define POWERPC64
#endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment