aboutsummaryrefslogtreecommitdiff
path: root/libffi/src
diff options
context:
space:
mode:
authorDavid Edelsohn <edelsohn@gnu.org>2002-01-17 16:04:21 +0000
committerDavid Edelsohn <dje@gcc.gnu.org>2002-01-17 11:04:21 -0500
commit2f4006f8c77a20332c70e43d34bc0308405620c2 (patch)
tree31a08ca08821cff1bd464db9f21ab0be03ae388a /libffi/src
parent2bcb0aa08196a5a16accb58cdd8d18cecd7ae0f6 (diff)
downloadgcc-2f4006f8c77a20332c70e43d34bc0308405620c2.zip
gcc-2f4006f8c77a20332c70e43d34bc0308405620c2.tar.gz
gcc-2f4006f8c77a20332c70e43d34bc0308405620c2.tar.bz2
Makefile.am (EXTRA_DIST): Add Darwin and AIX files.
* Makefile.am (EXTRA_DIST): Add Darwin and AIX files. (TARGET_SRC_POWERPC_AIX): New. (POWERPC_AIX): New stanza. * Makefile.in: Regenerate. * configure.in: Add AIX case. * configure: Regenerate. * include/ffi.h.in (ffi_abi): Add FFI_AIX. * src/powerpc/ffi_darwin.c (ffi_status): Use "long" to scale frame size. Fix "long double" support. (ffi_call): Add FFI_AIX case. * src/powerpc/aix.S: New. From-SVN: r48956
Diffstat (limited to 'libffi/src')
-rw-r--r--libffi/src/powerpc/aix.S209
-rw-r--r--libffi/src/powerpc/ffi_darwin.c42
2 files changed, 237 insertions, 14 deletions
diff --git a/libffi/src/powerpc/aix.S b/libffi/src/powerpc/aix.S
new file mode 100644
index 0000000..a0a6598
--- /dev/null
+++ b/libffi/src/powerpc/aix.S
@@ -0,0 +1,209 @@
+/* -----------------------------------------------------------------------
+ aix.S - Copyright (c) 2002 Free Software Foundation, Inc.
+ based on darwin.S by John Hornkvist
+
+ PowerPC Assembly glue.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ ``Software''), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ ----------------------------------------------------------------------- */
+
+ .set r0,0
+ .set r1,1
+ .set r2,2
+ .set r3,3
+ .set r4,4
+ .set r5,5
+ .set r6,6
+ .set r7,7
+ .set r8,8
+ .set r9,9
+ .set r10,10
+ .set r11,11
+ .set r12,12
+ .set r13,13
+ .set r14,14
+ .set r15,15
+ .set r16,16
+ .set r17,17
+ .set r18,18
+ .set r19,19
+ .set r20,20
+ .set r21,21
+ .set r22,22
+ .set r23,23
+ .set r24,24
+ .set r25,25
+ .set r26,26
+ .set r27,27
+ .set r28,28
+ .set r29,29
+ .set r30,30
+ .set r31,31
+ .set f0,0
+ .set f1,1
+ .set f2,2
+ .set f3,3
+ .set f4,4
+ .set f5,5
+ .set f6,6
+ .set f7,7
+ .set f8,8
+ .set f9,9
+ .set f10,10
+ .set f11,11
+ .set f12,12
+ .set f13,13
+ .set f14,14
+ .set f15,15
+ .set f16,16
+ .set f17,17
+ .set f18,18
+ .set f19,19
+ .set f20,20
+ .set f21,21
+
+#define LIBFFI_ASM
+#include <ffi.h>
+#define JUMPTARGET(name) name
+#define L(x) x
+ .file "aix.S"
+ .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:
+ 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. */
+ stwux r1,r1,r4
+
+ /* Save registers we use. */
+ mflr r9
+
+ stw r28,-16(r8)
+ stw r29,-12(r8)
+ stw r30, -8(r8)
+ stw r31, -4(r8)
+
+ stw r9, 8(r8)
+ stw r2, 20(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
+
+ lwz r2,4(r12)
+ lwz r12,0(r12)
+ mtctr r12 // r12 holds address of _ffi_prep_args
+ bctrl
+ lwz r2,20(r1)
+
+ /* Now do the call. */
+ lwz r12,0(r29)
+ /* Set up cr1 with bits 4-7 of the flags. */
+ mtcrf 0x40,r31
+ stw r2,20(r1)
+ mtctr r12
+ 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)
+ 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)
+
+L1:
+ /* Load all the FP registers. */
+ bf 6,L2 // 2f + 0x18
+ lfd f1,-16-(13*8)(r28)
+ lfd f2,-16-(12*8)(r28)
+ lfd f3,-16-(11*8)(r28)
+ lfd f4,-16-(10*8)(r28)
+ nop
+ lfd f5,-16-(9*8)(r28)
+ lfd f6,-16-(8*8)(r28)
+ 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)
+ nop
+ lfd f13,-16-(1*8)(r28)
+
+L2:
+ /* Make the call. */
+ bctrl
+ lwz r2,20(r1)
+
+ /* Now, deal with the return value. */
+ mtcrf 0x01,r31
+
+ bt 30,L(done_return_value)
+ bt 29,L(fp_return_value)
+ stw r3,0(r30)
+ bf 28,L(done_return_value)
+ stw r4,4(r30)
+
+ /* Fall through... */
+
+L(done_return_value):
+ /* Restore the registers we used and return. */
+ lwz r9, 8(r28)
+ lwz r31, -4(r28)
+ mtlr r9
+ lwz r30, -8(r28)
+ lwz r29,-12(r28)
+ lwz r28,-16(r28)
+ lwz 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)
+//END(ffi_call_AIX)
+
diff --git a/libffi/src/powerpc/ffi_darwin.c b/libffi/src/powerpc/ffi_darwin.c
index 684144b..d4a986d 100644
--- a/libffi/src/powerpc/ffi_darwin.c
+++ b/libffi/src/powerpc/ffi_darwin.c
@@ -4,8 +4,9 @@
PowerPC Foreign Function Interface
Darwin ABI support (c) 2001 John Hornkvist
+ AIX ABI support (c) 2002 Free Software Foundation, Inc.
- $Id: ffi.c,v 1.1.1.1 1998/11/29 16:48:16 green Exp $
+ $Id: ffi_darwin.c,v 1.1 2002/01/16 05:32:15 bryce Exp $
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
@@ -202,7 +203,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
/* Space for the frame pointer, callee's LR, CR, etc, and for
the asm's temp regs. */
- bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(int);
+ bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
/* Return value handling. The rules are as follows:
- 32-bit (or less) integer values are returned in gpr3;
@@ -210,10 +211,16 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
- 64-bit integer values and structures between 5 and 8 bytes are returned
in gpr3 and gpr4;
- Single/double FP values are returned in fpr1;
- - Larger structures and long double (if not equivalent to double) values
- are allocated space and a pointer is passed as the first argument. */
+ - Long double FP (if not equivalent to double) values are returned in
+ fpr1 and fpr2;
+ - Larger structures values are allocated space and a pointer is passed
+ as the first argument. */
switch (cif->rtype->type)
{
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+#endif
+ /* Fall through. */
case FFI_TYPE_DOUBLE:
flags |= FLAG_RETURNS_64BITS;
/* Fall through. */
@@ -227,10 +234,6 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
break;
case FFI_TYPE_STRUCT:
- /* Fall through. */
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
- case FFI_TYPE_LONGDOUBLE:
-#endif
flags |= FLAG_RETVAL_REFERENCE;
flags |= FLAG_RETURNS_NOTHING;
intarg_count++;
@@ -301,9 +304,9 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
/* Stack space. */
if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
- bytes += (intarg_count + 2 * fparg_count) * sizeof(int);
+ bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
else
- bytes += NUM_GPR_ARG_REGISTERS * sizeof(int);
+ bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
/* The stack space allocated needs to be a multiple of 16 bytes. */
bytes = (bytes + 15) & ~0xF;
@@ -316,11 +319,16 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
/*@-declundef@*/
/*@-exportheader@*/
+extern void ffi_call_AIX(/*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)(),
+ void (*fn2)());
extern void ffi_call_DARWIN(/*@out@*/ extended_cif *,
- unsigned, unsigned,
- /*@out@*/ unsigned *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
void (*fn)(),
- void (*fn2)());
+ void (*fn2)());
/*@=declundef@*/
/*@=exportheader@*/
@@ -349,10 +357,16 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
switch (cif->abi)
{
+ case FFI_AIX:
+ /*@-usedef@*/
+ ffi_call_AIX(&ecif, -cif->bytes,
+ cif->flags, ecif.rvalue, fn, ffi_prep_args);
+ /*@=usedef@*/
+ break;
case FFI_DARWIN:
/*@-usedef@*/
ffi_call_DARWIN(&ecif, -cif->bytes,
- cif->flags, ecif.rvalue, fn, ffi_prep_args);
+ cif->flags, ecif.rvalue, fn, ffi_prep_args);
/*@=usedef@*/
break;
default: