This is the mail archive of the
libffi-discuss@sources.redhat.com
mailing list for the libffi project.
Re: libffi Darwin support
- From: David Edelsohn <dje at watson dot ibm dot com>
- To: libffi-discuss at sources dot redhat dot com
- Cc: ?ISO-8859-1?Q?John_H=F6rnkvist?= <john at toastedmarshmallow dot com>, Bryce McKinlay <bryce at waitaki dot otago dot ac dot nz>
- Date: Wed, 16 Jan 2002 22:09:02 -0500
- Subject: Re: libffi Darwin support
- References: <59B9E470-E3B8-11D5-BCF3-0030654E84BA@toastedmarshmallow.com><200201161903.OAA24226@makai.watson.ibm.com>
Revised patch.
David
* 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.
* src/powerpc/ffi_darwin.c (ffi_call): Add FFI_AIX case.
* src/powerpc/aix.S: New.
Index: Makefile.am
===================================================================
RCS file: /cvs/gcc/egcs/libffi/Makefile.am,v
retrieving revision 1.14
diff -c -p -r1.14 Makefile.am
*** Makefile.am 2001/10/09 05:32:15 1.14
--- Makefile.am 2002/01/17 03:02:08
*************** EXTRA_DIST = LICENSE ChangeLog.v1 src/mi
*** 11,17 ****
src/alpha/ffi.c src/alpha/osf.S \
src/m68k/ffi.c src/m68k/sysv.S \
src/powerpc/ffi.c src/powerpc/sysv.S \
! src/powerpc/ppc_closure.S src/powerpc/asm.h \
src/arm/ffi.c src/arm/sysv.S
VPATH = @srcdir@:@srcdir@/src:@srcdir@/src/@TARGETDIR@
--- 11,19 ----
src/alpha/ffi.c src/alpha/osf.S \
src/m68k/ffi.c src/m68k/sysv.S \
src/powerpc/ffi.c src/powerpc/sysv.S \
! src/powerpc/ppc_closure.S src/powerpc/asm.h \
! src/powerpc/ffi_darwin.c \
! src/powerpc/darwin.S src/powerpc/aix.S \
src/arm/ffi.c src/arm/sysv.S
VPATH = @srcdir@:@srcdir@/src:@srcdir@/src/@TARGETDIR@
*************** TARGET_SRC_ALPHA = src/alpha/ffi.c src/a
*** 97,102 ****
--- 99,105 ----
TARGET_SRC_IA64 = src/ia64/ffi.c src/ia64/unix.S
TARGET_SRC_M68K = src/m68k/ffi.c src/m68k/sysv.S
TARGET_SRC_POWERPC = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
+ TARGET_SRC_POWERPC_AIX = src/powerpc/ffi_darwin.c src/powerpc/aix.S
TARGET_SRC_POWERPC_DARWIN = src/powerpc/ffi_darwin.c src/powerpc/darwin.S
TARGET_SRC_ARM = src/arm/sysv.S src/arm/ffi.c
*************** endif
*** 139,144 ****
--- 142,151 ----
if POWERPC
libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC)
libfficonvenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC)
+ endif
+ if POWERPC_AIX
+ libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_AIX)
+ libfficonvenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_AIX)
endif
if POWERPC_DARWIN
libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_DARWIN)
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/libffi/Makefile.in,v
retrieving revision 1.19
diff -c -p -r1.19 Makefile.in
*** Makefile.in 2001/10/09 05:32:15 1.19
--- Makefile.in 2002/01/17 03:02:08
*************** EXTRA_DIST = LICENSE ChangeLog.v1 src/mi
*** 92,98 ****
src/alpha/ffi.c src/alpha/osf.S \
src/m68k/ffi.c src/m68k/sysv.S \
src/powerpc/ffi.c src/powerpc/sysv.S \
! src/powerpc/ppc_closure.S src/powerpc/asm.h \
src/arm/ffi.c src/arm/sysv.S
--- 92,100 ----
src/alpha/ffi.c src/alpha/osf.S \
src/m68k/ffi.c src/m68k/sysv.S \
src/powerpc/ffi.c src/powerpc/sysv.S \
! src/powerpc/ppc_closure.S src/powerpc/asm.h \
! src/powerpc/ffi_darwin.c \
! src/powerpc/darwin.S src/powerpc/aix.S \
src/arm/ffi.c src/arm/sysv.S
*************** TARGET_SRC_ALPHA = src/alpha/ffi.c src/a
*** 168,173 ****
--- 170,176 ----
TARGET_SRC_IA64 = src/ia64/ffi.c src/ia64/unix.S
TARGET_SRC_M68K = src/m68k/ffi.c src/m68k/sysv.S
TARGET_SRC_POWERPC = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
+ TARGET_SRC_POWERPC_AIX = src/powerpc/ffi_darwin.c src/powerpc/aix.S
TARGET_SRC_POWERPC_DARWIN = src/powerpc/ffi_darwin.c src/powerpc/darwin.S
TARGET_SRC_ARM = src/arm/sysv.S src/arm/ffi.c
*************** libffi_la_common_SOURCES = src/debug.c s
*** 183,188 ****
--- 186,192 ----
@IA64_TRUE@libffi_la_SOURCES = @IA64_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_IA64)
@M68K_TRUE@libffi_la_SOURCES = @M68K_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_M68K)
@POWERPC_TRUE@libffi_la_SOURCES = @POWERPC_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC)
+ @POWERPC_AIX_TRUE@libffi_la_SOURCES = @POWERPC_AIX_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_AIX)
@POWERPC_DARWIN_TRUE@libffi_la_SOURCES = @POWERPC_DARWIN_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_DARWIN)
@ARM_TRUE@libffi_la_SOURCES = @ARM_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_ARM)
@MIPS_GCC_TRUE@libfficonvenience_la_SOURCES = @MIPS_GCC_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_GCC)
*************** libffi_la_common_SOURCES = src/debug.c s
*** 194,199 ****
--- 198,204 ----
@IA64_TRUE@libfficonvenience_la_SOURCES = @IA64_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_IA64)
@M68K_TRUE@libfficonvenience_la_SOURCES = @M68K_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_M68K)
@POWERPC_TRUE@libfficonvenience_la_SOURCES = @POWERPC_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC)
+ @POWERPC_AIX_TRUE@libfficonvenience_la_SOURCES = @POWERPC_AIX_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_AIX)
@POWERPC_DARWIN_TRUE@libfficonvenience_la_SOURCES = @POWERPC_DARWIN_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_DARWIN)
@ARM_TRUE@libfficonvenience_la_SOURCES = @ARM_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_ARM)
*************** libfficonvenience_la_LIBADD =
*** 244,249 ****
--- 249,258 ----
@IA64_TRUE@libfficonvenience_la_OBJECTS = src/debug.lo src/prep_cif.lo \
@IA64_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
@IA64_TRUE@src/ia64/ffi.lo src/ia64/unix.lo
+ @POWERPC_AIX_TRUE@libfficonvenience_la_OBJECTS = src/debug.lo \
+ @POWERPC_AIX_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
+ @POWERPC_AIX_TRUE@src/java_raw_api.lo src/powerpc/ffi_darwin.lo \
+ @POWERPC_AIX_TRUE@src/powerpc/aix.lo
@POWERPC_DARWIN_TRUE@libfficonvenience_la_OBJECTS = src/debug.lo \
@POWERPC_DARWIN_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
@POWERPC_DARWIN_TRUE@src/java_raw_api.lo src/powerpc/ffi_darwin.lo \
*************** libffi_la_LIBADD =
*** 281,286 ****
--- 290,298 ----
@IA64_TRUE@libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo \
@IA64_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
@IA64_TRUE@src/ia64/ffi.lo src/ia64/unix.lo
+ @POWERPC_AIX_TRUE@libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo \
+ @POWERPC_AIX_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
+ @POWERPC_AIX_TRUE@src/powerpc/ffi_darwin.lo src/powerpc/aix.lo
@POWERPC_DARWIN_TRUE@libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo \
@POWERPC_DARWIN_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
@POWERPC_DARWIN_TRUE@src/powerpc/ffi_darwin.lo src/powerpc/darwin.lo
Index: configure.in
===================================================================
RCS file: /cvs/gcc/egcs/libffi/configure.in,v
retrieving revision 1.17
diff -c -p -r1.17 configure.in
*** configure.in 2001/10/09 05:32:16 1.17
--- configure.in 2002/01/17 03:02:09
*************** m68k-*-linux*) TARGET=M68K; TARGETDIR=m6
*** 57,62 ****
--- 57,64 ----
powerpc-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;;
powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;;
powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;;
+ powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
+ rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
esac
*************** AM_CONDITIONAL(ALPHA, test x$TARGET = xA
*** 73,78 ****
--- 75,81 ----
AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
+ AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
Index: include/ffi.h.in
===================================================================
RCS file: /cvs/gcc/egcs/libffi/include/ffi.h.in,v
retrieving revision 1.11
diff -c -p -r1.11 ffi.h.in
*** ffi.h.in 2001/10/09 05:32:16 1.11
--- ffi.h.in 2002/01/17 03:02:09
*************** typedef enum ffi_abi {
*** 233,239 ****
--- 233,246 ----
FFI_DEFAULT_ABI = FFI_GCC_SYSV,
#endif
+ #ifdef POWERPC_AIX
+ FFI_AIX,
+ FFI_DARWIN,
+ FFI_DEFAULT_ABI = FFI_AIX,
+ #endif
+
#ifdef POWERPC_DARWIN
+ FFI_AIX,
FFI_DARWIN,
FFI_DEFAULT_ABI = FFI_DARWIN,
#endif
Index: src/powerpc/ffi_darwin.c
===================================================================
RCS file: /cvs/gcc/egcs/libffi/src/powerpc/ffi_darwin.c,v
retrieving revision 1.1
diff -c -p -r1.1 ffi_darwin.c
*** ffi_darwin.c 2001/10/09 05:32:15 1.1
--- ffi_darwin.c 2002/01/17 03:02:09
***************
*** 4,11 ****
PowerPC Foreign Function Interface
Darwin ABI support (c) 2001 John Hornkvist
! $Id: ffi_darwin.c,v 1.1 2001/10/09 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
--- 4,12 ----
PowerPC Foreign Function Interface
Darwin ABI support (c) 2001 John Hornkvist
+ AIX ABI support (c) 2002 David Edelsohn
! $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
*************** ffi_status ffi_prep_cif_machdep(ffi_cif
*** 202,208 ****
/* Space for the frame pointer, callee's LR, CR, etc, and for
the asm's temp regs. */
! bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(int);
/* Return value handling. The rules are as follows:
- 32-bit (or less) integer values are returned in gpr3;
--- 203,209 ----
/* Space for the frame pointer, callee's LR, CR, etc, and for
the asm's temp regs. */
! 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;
*************** ffi_status ffi_prep_cif_machdep(ffi_cif
*** 210,219 ****
- 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. */
switch (cif->rtype->type)
{
case FFI_TYPE_DOUBLE:
flags |= FLAG_RETURNS_64BITS;
/* Fall through. */
--- 211,226 ----
- 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;
! - 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. */
*************** ffi_status ffi_prep_cif_machdep(ffi_cif
*** 227,236 ****
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++;
--- 234,239 ----
*************** ffi_status ffi_prep_cif_machdep(ffi_cif
*** 301,309 ****
/* Stack space. */
if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
! bytes += (intarg_count + 2 * fparg_count) * sizeof(int);
else
! bytes += NUM_GPR_ARG_REGISTERS * sizeof(int);
/* The stack space allocated needs to be a multiple of 16 bytes. */
bytes = (bytes + 15) & ~0xF;
--- 304,312 ----
/* Stack space. */
if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
! bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
else
! bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
/* The stack space allocated needs to be a multiple of 16 bytes. */
bytes = (bytes + 15) & ~0xF;
*************** ffi_status ffi_prep_cif_machdep(ffi_cif
*** 316,326 ****
/*@-declundef@*/
/*@-exportheader@*/
extern void ffi_call_DARWIN(/*@out@*/ extended_cif *,
! unsigned, unsigned,
! /*@out@*/ unsigned *,
void (*fn)(),
! void (*fn2)());
/*@=declundef@*/
/*@=exportheader@*/
--- 319,334 ----
/*@-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 *,
void (*fn)(),
! void (*fn2)());
/*@=declundef@*/
/*@=exportheader@*/
*************** void ffi_call(/*@dependent@*/ ffi_cif *c
*** 349,358 ****
switch (cif->abi)
{
case FFI_DARWIN:
/*@-usedef@*/
ffi_call_DARWIN(&ecif, -cif->bytes,
! cif->flags, ecif.rvalue, fn, ffi_prep_args);
/*@=usedef@*/
break;
default:
--- 357,372 ----
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);
/*@=usedef@*/
break;
default:
*** /dev/null Wed Jan 16 22:02:25 2002
--- src/powerpc/aix.S Wed Jan 16 16:24:44 2002
***************
*** 0 ****
--- 1,209 ----
+ /* -----------------------------------------------------------------------
+ aix.S - Copyright (c) 2002 David Edelsohn
+ 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)
+