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> 2009-11-02 Andreas Tobler <a.tobler@schweiz.org>
PR libffi/41908 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 based on darwin.S by John Hornkvist
PowerPC Assembly glue. PowerPC Assembly glue.
...@@ -86,9 +86,13 @@ ...@@ -86,9 +86,13 @@
#define L(x) x #define L(x) x
.file "aix.S" .file "aix.S"
.toc .toc
.csect .text[PR]
.align 2 /* void ffi_call_AIX(extended_cif *ecif, unsigned long bytes,
.globl ffi_prep_args * 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] .csect .text[PR]
.align 2 .align 2
...@@ -96,6 +100,120 @@ ...@@ -96,6 +100,120 @@
.globl .ffi_call_AIX .globl .ffi_call_AIX
.csect ffi_call_AIX[DS] .csect ffi_call_AIX[DS]
ffi_call_AIX: 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 .long .ffi_call_AIX, TOC[tc0], 0
.csect .text[PR] .csect .text[PR]
.ffi_call_AIX: .ffi_call_AIX:
...@@ -190,8 +308,8 @@ L2: ...@@ -190,8 +308,8 @@ L2:
L(done_return_value): L(done_return_value):
/* Restore the registers we used and return. */ /* Restore the registers we used and return. */
lwz r9, 8(r28) lwz r9,8(r28)
lwz r31, -4(r28) lwz r31,-4(r28)
mtlr r9 mtlr r9
lwz r30, -8(r28) lwz r30, -8(r28)
lwz r29,-12(r28) lwz r29,-12(r28)
...@@ -206,6 +324,7 @@ L(fp_return_value): ...@@ -206,6 +324,7 @@ L(fp_return_value):
L(float_return_value): L(float_return_value):
stfs f1,0(r30) stfs f1,0(r30)
b L(done_return_value) b L(done_return_value)
#endif
.long 0 .long 0
.byte 0,0,0,1,128,4,0,0 .byte 0,0,0,1,128,4,0,0
//END(ffi_call_AIX) //END(ffi_call_AIX)
...@@ -216,7 +335,11 @@ L(float_return_value): ...@@ -216,7 +335,11 @@ L(float_return_value):
.globl .ffi_call_DARWIN .globl .ffi_call_DARWIN
.csect ffi_call_DARWIN[DS] .csect ffi_call_DARWIN[DS]
ffi_call_DARWIN: ffi_call_DARWIN:
#ifdef __64BIT__
.llong .ffi_call_DARWIN, TOC[tc0], 0
#else
.long .ffi_call_DARWIN, TOC[tc0], 0 .long .ffi_call_DARWIN, TOC[tc0], 0
#endif
.csect .text[PR] .csect .text[PR]
.ffi_call_DARWIN: .ffi_call_DARWIN:
blr 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 based on darwin_closure.S
PowerPC Assembly glue. PowerPC Assembly glue.
...@@ -94,8 +94,162 @@ LC..60: ...@@ -94,8 +94,162 @@ LC..60:
.globl ffi_closure_ASM .globl ffi_closure_ASM
.globl .ffi_closure_ASM .globl .ffi_closure_ASM
.csect ffi_closure_ASM[DS] .csect ffi_closure_ASM[DS]
ffi_closure_ASM: 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 .long .ffi_closure_ASM, TOC[tc0], 0
.csect .text[PR] .csect .text[PR]
.ffi_closure_ASM: .ffi_closure_ASM:
...@@ -106,8 +260,8 @@ ffi_closure_ASM: ...@@ -106,8 +260,8 @@ ffi_closure_ASM:
/* 24 Bytes (Linkage Area) */ /* 24 Bytes (Linkage Area) */
/* 32 Bytes (params) */ /* 32 Bytes (params) */
/* 104 Bytes (13*8 from FPR) */ /* 104 Bytes (13*8 from FPR) */
/* 8 Bytes (result) */ /* 16 Bytes (result) */
/* 168 Bytes */ /* 176 Bytes */
stwu r1,-176(r1) /* skip over caller save area stwu r1,-176(r1) /* skip over caller save area
keep stack aligned to 16 */ keep stack aligned to 16 */
...@@ -177,7 +331,7 @@ L..60: ...@@ -177,7 +331,7 @@ L..60:
.long L..50-L..60 /* FFI_TYPE_INT */ .long L..50-L..60 /* FFI_TYPE_INT */
.long L..47-L..60 /* FFI_TYPE_FLOAT */ .long L..47-L..60 /* FFI_TYPE_FLOAT */
.long L..46-L..60 /* FFI_TYPE_DOUBLE */ .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..56-L..60 /* FFI_TYPE_UINT8 */
.long L..55-L..60 /* FFI_TYPE_SINT8 */ .long L..55-L..60 /* FFI_TYPE_SINT8 */
.long L..58-L..60 /* FFI_TYPE_UINT16 */ .long L..58-L..60 /* FFI_TYPE_UINT16 */
...@@ -190,6 +344,12 @@ L..60: ...@@ -190,6 +344,12 @@ L..60:
.long L..50-L..60 /* FFI_TYPE_POINTER */ .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 */ /* case double */
L..46: L..46:
lfd f1,0(r5) lfd f1,0(r5)
...@@ -213,29 +373,23 @@ L..50: ...@@ -213,29 +373,23 @@ L..50:
/* case signed int8 */ /* case signed int8 */
L..55: L..55:
addi r5,r5,3 lbz r3,3(r5)
lbz r3,0(r5) extsb r3,r3
slwi r3,r3,24
srawi r3,r3,24
b L..44 b L..44
/* case unsigned int8 */ /* case unsigned int8 */
L..56: L..56:
addi r5,r5,3 lbz r3,3(r5)
lbz r3,0(r5)
b L..44 b L..44
/* case signed int16 */ /* case signed int16 */
L..57: L..57:
addi r5,r5,2 lha r3,2(r5)
lhz r3,0(r5)
extsh r3,r3
b L..44 b L..44
/* case unsigned int16 */ /* case unsigned int16 */
L..58: L..58:
addi r5,r5,2 lhz r3,2(r5)
lhz r3,0(r5)
/* case void / done */ /* case void / done */
L..44: L..44:
...@@ -243,5 +397,5 @@ L..44: ...@@ -243,5 +397,5 @@ L..44:
lwz r0,8(r1) /* get return address */ lwz r0,8(r1) /* get return address */
mtlr r0 /* reset link register */ mtlr r0 /* reset link register */
blr blr
#endif
/* END(ffi_closure_ASM) */ /* END(ffi_closure_ASM) */
...@@ -30,7 +30,11 @@ ...@@ -30,7 +30,11 @@
/* ---- System specific configurations ----------------------------------- */ /* ---- 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 #define POWERPC64
#endif #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