aboutsummaryrefslogtreecommitdiff
path: root/libffi/src/powerpc/aix.S
diff options
context:
space:
mode:
authorDavid Edelsohn <edelsohn@gnu.org>2009-11-30 23:34:33 +0000
committerDavid Edelsohn <dje@gcc.gnu.org>2009-11-30 18:34:33 -0500
commit5751cf6fef34bcadf288b8d02e287d0bb1520b99 (patch)
treeabc3b22bd91bc9b3d8d8907ee5124199c36b3a6f /libffi/src/powerpc/aix.S
parent17f35e23325426fb3f95070cd3218c0b4f87c5a0 (diff)
downloadgcc-5751cf6fef34bcadf288b8d02e287d0bb1520b99.zip
gcc-5751cf6fef34bcadf288b8d02e287d0bb1520b99.tar.gz
gcc-5751cf6fef34bcadf288b8d02e287d0bb1520b99.tar.bz2
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
Diffstat (limited to 'libffi/src/powerpc/aix.S')
-rw-r--r--libffi/src/powerpc/aix.S165
1 files changed, 144 insertions, 21 deletions
diff --git a/libffi/src/powerpc/aix.S b/libffi/src/powerpc/aix.S
index 45502f7..7b73999 100644
--- a/libffi/src/powerpc/aix.S
+++ b/libffi/src/powerpc/aix.S
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------
- 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