]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Makefile.am (EXTRA_DIST): Add Darwin and AIX closure files.
authorAndreas Tobler <toa@pop.agri.ch>
Thu, 7 Mar 2002 18:24:42 +0000 (19:24 +0100)
committerDavid Edelsohn <dje@gcc.gnu.org>
Thu, 7 Mar 2002 18:24:42 +0000 (13:24 -0500)
2002-03-07  Andreas Tobler  <toa@pop.agri.ch>
    David Edelsohn  <edelsohn@gnu.org>

* Makefile.am (EXTRA_DIST): Add Darwin and AIX closure files.
(TARGET_SRC_POWERPC_AIX): Add aix_closure.S.
(TARGET_SRC_POWERPC_DARWIN): Add darwin_closure.S.
* Makefile.in: Regenerate.
* include/ffi.h.in: Add AIX and Darwin closure definitions.
* src/powerpc/ffi_darwin.c (ffi_prep_closure): New function.
(flush_icache, flush_range): New functions.
(ffi_closure_helper_DARWIN): New function.
* src/powerpc/aix_closure.S: New file.
* src/powerpc/darwin_closure.S: New file.

Co-Authored-By: David Edelsohn <edelsohn@gnu.org>
From-SVN: r50408

libffi/ChangeLog
libffi/Makefile.am
libffi/Makefile.in
libffi/include/ffi.h.in
libffi/src/powerpc/aix_closure.S [new file with mode: 0644]
libffi/src/powerpc/darwin_closure.S [new file with mode: 0644]
libffi/src/powerpc/ffi_darwin.c

index ad33876a7dc069efc26a52d3ebd9cd5f0a825ce8..382e73bfcde3516b3ef03f1bd2a22533bd279e4a 100644 (file)
@@ -1,3 +1,17 @@
+2002-03-07  Andreas Tobler  <toa@pop.agri.ch>
+           David Edelsohn  <edelsohn@gnu.org>
+
+       * Makefile.am (EXTRA_DIST): Add Darwin and AIX closure files.
+       (TARGET_SRC_POWERPC_AIX): Add aix_closure.S.
+       (TARGET_SRC_POWERPC_DARWIN): Add darwin_closure.S.
+       * Makefile.in: Regenerate.
+       * include/ffi.h.in: Add AIX and Darwin closure definitions.
+       * src/powerpc/ffi_darwin.c (ffi_prep_closure): New function.
+       (flush_icache, flush_range): New functions.
+       (ffi_closure_helper_DARWIN): New function.
+       * src/powerpc/aix_closure.S: New file.
+       * src/powerpc/darwin_closure.S: New file.
+       
 2002-02-24  Jeff Sturm  <jsturm@one-point.com>
 
        * include/ffi.h.in: Add typedef for ffi_arg.
index 04cc125e5959f9f1a6afaacb95a61f84ef2e3ce9..eece0813bc991f4c0c08dd5d785334435d4ddddb 100644 (file)
@@ -14,6 +14,7 @@ EXTRA_DIST = LICENSE ChangeLog.v1 src/mips/ffi.c src/mips/n32.S \
                src/powerpc/ppc_closure.S src/powerpc/asm.h \
                src/powerpc/ffi_darwin.c \
                src/powerpc/darwin.S src/powerpc/aix.S \
+               src/powerpc/darwin_closure.S src/powerpc/aix_closures.S \
                src/arm/ffi.c src/arm/sysv.S
 
 VPATH = @srcdir@:@srcdir@/src:@srcdir@/src/@TARGETDIR@
@@ -99,8 +100,8 @@ TARGET_SRC_ALPHA = src/alpha/ffi.c src/alpha/osf.S
 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_POWERPC_AIX = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closures.S
+TARGET_SRC_POWERPC_DARWIN = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
 TARGET_SRC_ARM =  src/arm/sysv.S src/arm/ffi.c
 
 ##libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c $(TARGET_SRC_@TARGET@)
index 17d8d43944b6b1dcd614142f808709dcd4310336..f0f0348fd7cdb8d7e147ffbf27669e9ebf164aa6 100644 (file)
@@ -95,6 +95,7 @@ EXTRA_DIST = LICENSE ChangeLog.v1 src/mips/ffi.c src/mips/n32.S \
                src/powerpc/ppc_closure.S src/powerpc/asm.h \
                src/powerpc/ffi_darwin.c \
                src/powerpc/darwin.S src/powerpc/aix.S \
+               src/powerpc/darwin_closure.S src/powerpc/aix_closure.S \
                src/arm/ffi.c src/arm/sysv.S
 
 
@@ -170,8 +171,8 @@ TARGET_SRC_ALPHA = src/alpha/ffi.c src/alpha/osf.S
 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_POWERPC_AIX = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
+TARGET_SRC_POWERPC_DARWIN = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
 TARGET_SRC_ARM = src/arm/sysv.S src/arm/ffi.c
 
 libffi_la_common_SOURCES = src/debug.c src/prep_cif.c src/types.c \
@@ -252,11 +253,11 @@ libfficonvenience_la_LIBADD =
 @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_AIX_TRUE@src/powerpc/aix.lo src/powerpc/aix_closure.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 \
-@POWERPC_DARWIN_TRUE@src/powerpc/darwin.lo
+@POWERPC_DARWIN_TRUE@src/powerpc/darwin.lo src/powerpc/darwin_closure.lo
 @MIPS_SGI_TRUE@libfficonvenience_la_OBJECTS =  src/debug.lo \
 @MIPS_SGI_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
 @MIPS_SGI_TRUE@src/java_raw_api.lo src/mips/ffi.lo src/mips/o32.lo \
@@ -292,10 +293,12 @@ libffi_la_LIBADD =
 @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_AIX_TRUE@src/powerpc/ffi_darwin.lo src/powerpc/aix.lo \
+@POWERPC_AIX_TRUE@src/powerpc/aix_closure.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
+@POWERPC_DARWIN_TRUE@src/powerpc/ffi_darwin.lo src/powerpc/darwin.lo \
+@POWERPC_DARWIN_TRUE@src/powerpc/darwin_closure.lo
 @MIPS_SGI_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
 @MIPS_SGI_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
 @MIPS_SGI_TRUE@src/mips/ffi.lo src/mips/o32.lo src/mips/n32.lo
index 90ed269230580814ddd2092ed6fe165b8f715edd..8097917fe105ce802c681b82ced462249650a767 100644 (file)
@@ -412,6 +412,18 @@ struct ffi_ia64_trampoline_struct {
 #define FFI_TRAMPOLINE_SIZE 40
 #define FFI_NATIVE_RAW_API 0
 
+#elif defined(POWERPC_DARWIN)
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 40
+#define FFI_NATIVE_RAW_API 0
+
+#elif defined(POWERPC_AIX)
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 24 /* see struct below */ 
+#define FFI_NATIVE_RAW_API 0
+
 #else 
 
 #define FFI_CLOSURES 0
@@ -419,6 +431,16 @@ struct ffi_ia64_trampoline_struct {
 
 #endif
 
+#if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
+
+struct ffi_aix_trampoline_struct {
+    void * code_pointer;       /* Pointer to ffi_closure_ASM */
+    void * toc;                        /* TOC */
+    void * static_chain;       /* Pointer to closure */
+};
+
+#endif
+
 
 
 #if FFI_CLOSURES
diff --git a/libffi/src/powerpc/aix_closure.S b/libffi/src/powerpc/aix_closure.S
new file mode 100644 (file)
index 0000000..7fa96f1
--- /dev/null
@@ -0,0 +1,251 @@
+/* -----------------------------------------------------------------------
+   aix_closures.S - Copyright (c) 2002 Free Software Foundation, Inc.
+   based on darwin_closures.S 
+  
+   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
+#define JUMPTARGET(name) name
+#define L(x) x
+       .file "aix_closure.S"
+       .toc
+LC..60:
+       .tc L..60[TC],L..60
+       .csect .text[PR]
+       .align 2
+
+.csect .text[PR]
+       .align 2
+       .globl ffi_closure_ASM
+       .globl .ffi_closure_ASM
+.csect ffi_closure_ASM[DS]
+
+ffi_closure_ASM:
+       .long .ffi_closure_ASM, TOC[tc0], 0
+       .csect .text[PR]
+.ffi_closure_ASM:
+
+       mflr r0                 /* extract return address */
+       stw r0, 8(r1)           /* save the return address */
+       
+       /* 24 Bytes (Linkage Area) */
+       /* 32 Bytes (params) */
+       /* 104 Bytes (13*8 from FPR) */ 
+       /* 4 Bytes (result)
+       /* 164 Bytes */
+       
+       stwu r1,-164(r1)        /* skip over caller save area */
+
+/* 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            */
+       stw   r3, 188(r1)
+       stw   r4, 192(r1)
+       stw   r5, 196(r1) 
+       stw   r6, 200(r1)
+       stw   r7, 204(r1)
+       stw   r8, 208(r1) 
+       stw   r9, 212(r1)
+       stw   r10, 216(r1)
+
+       /* next save fpr 1 to fpr 13 (aligned to 8) */
+       stfd  f1, 56(r1)
+       stfd  f2, 64(r1)
+       stfd  f3, 72(r1)
+       stfd  f4, 80(r1)
+       stfd  f5, 88(r1)
+       stfd  f6, 96(r1)
+       stfd  f7, 104(r1)
+       stfd  f8, 112(r1)
+       stfd  f9, 120(r1) 
+       stfd  f10, 128(r1) 
+       stfd  f11, 136(r1) 
+       stfd  f12, 144(r1) 
+       stfd  f13, 152(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,160
+       
+       /* now load up the pointer to the saved gpr registers */
+       addi r5,r1,188
+
+       /* now load up the pointer to the saved fpr registers */
+       addi r6,r1,56
+
+       /* now load up the pointer to the outgoing parameter  */
+       /* stack in the previous frame */
+       addi r7,r1,220
+       
+       /* 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,160          /* get pointer to results area */
+       lwz r4,LC..60(2)        /* get address of jump table */
+       slwi 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..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..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..50-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..50-L..60    /* FFI_TYPE_POINTER */
+
+
+/* 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 */
+L..48:
+       lwz r3,0(r5)
+       lwz r4,4(r5)
+       b L..44
+       
+/* case default / int32 / pointer */
+L..50:
+       lwz r3,0(r5)
+       b L..44
+       
+/* case signed int8     */
+L..55:
+       addi r5,r5,3
+       lbz r3,0(r5)
+       slwi r3,r3,24
+       srawi r3,r3,24
+       b L..44
+
+/* case unsigned int8   */
+L..56:
+       addi r5,r5,3
+       lbz r3,0(r5)
+       b L..44
+
+/* case signed int16 */
+L..57:
+       addi r5,r5,2
+       lhz r3,0(r5)
+       extsh r3,r3
+       b L..44
+
+/* case unsigned int16 */
+L..58: 
+       addi r5,r5,2
+       lhz r3,0(r5)
+
+/* case void / done     */
+L..44:
+       
+       addi r1,r1,164          /* restore stack pointer */
+       lwz r0,8(r1)            /* get return address */
+       mtlr r0                 /* reset link register */
+       blr
+       
+/* END(ffi_closure_ASM) */
diff --git a/libffi/src/powerpc/darwin_closure.S b/libffi/src/powerpc/darwin_closure.S
new file mode 100644 (file)
index 0000000..9e54d22
--- /dev/null
@@ -0,0 +1,189 @@
+/* -----------------------------------------------------------------------
+   darwin_closures.S - Copyright (c) 2002 Free Software Foundation, Inc.
+   based on ppc_closures.S
+   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.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#define JUMPTARGET(name) name
+#define L(x) x
+.text
+.globl _ffi_closure_helper_DARWIN
+
+.text
+       .align 2
+.globl _ffi_closure_ASM
+
+.text
+       .align 2
+_ffi_closure_ASM:
+       
+       mflr r0                 /* extract return address */
+       stw r0, 8(r1)           /* save the return address */
+       
+       /* 24 Bytes (Linkage Area) */
+       /* 32 Bytes (outgoing parameter area, always reserved) */
+       /* 104 Bytes (13*8 from FPR) */ 
+       /* 4 Bytes (result)
+       /* 164 Bytes */
+       
+       stwu r1,-164(r1)        /* skip over caller save area */
+       
+/* 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            */
+       stw   r3, 188(r1)
+       stw   r4, 192(r1)
+       stw   r5, 196(r1) 
+       stw   r6, 200(r1)
+       stw   r7, 204(r1)
+       stw   r8, 208(r1) 
+       stw   r9, 212(r1)
+       stw   r10, 216(r1)
+
+       /* we save fpr 1 to fpr 13 (aligned to 8) */
+       stfd  f1, 56(r1)
+       stfd  f2, 64(r1)
+       stfd  f3, 72(r1)
+       stfd  f4, 80(r1)
+       stfd  f5, 88(r1)
+       stfd  f6, 96(r1)
+       stfd  f7, 104(r1)
+       stfd  f8, 112(r1)
+       stfd  f9, 120(r1) 
+       stfd  f10, 128(r1) 
+       stfd  f11, 136(r1) 
+       stfd  f12, 144(r1) 
+       stfd  f13, 152(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,160
+       
+       /* now load up the pointer to the saved gpr registers */
+       addi r5,r1,188
+
+       /* now load up the pointer to the saved fpr registers */
+       addi r6,r1,56
+
+       /* now load up the pointer to the outgoing parameter  */
+       /* stack in the previous frame */
+       addi r7,r1,220
+       
+       /* make the call */
+       bl L(_ffi_closure_helper_DARWIN)
+
+       /* 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,160          /* get pointer to results area */
+       addis r4,0,ha16(.L60)   /* get address of jump table */
+       addi r4,r4,lo16(.L60)
+       slwi 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 */
+
+.L60:
+       .long .L44-.L60    /* FFI_TYPE_VOID */
+       .long .L50-.L60    /* FFI_TYPE_INT */
+       .long .L47-.L60    /* FFI_TYPE_FLOAT */
+       .long .L46-.L60    /* FFI_TYPE_DOUBLE */
+       .long .L46-.L60    /* FFI_TYPE_LONGDOUBLE */
+       .long .L56-.L60    /* FFI_TYPE_UINT8 */
+       .long .L55-.L60    /* FFI_TYPE_SINT8 */
+       .long .L58-.L60    /* FFI_TYPE_UINT16 */
+       .long .L57-.L60    /* FFI_TYPE_SINT16 */
+       .long .L50-.L60    /* FFI_TYPE_UINT32 */
+       .long .L50-.L60    /* FFI_TYPE_SINT32 */
+       .long .L48-.L60    /* FFI_TYPE_UINT64 */
+       .long .L48-.L60    /* FFI_TYPE_SINT64 */
+       .long .L44-.L60    /* FFI_TYPE_STRUCT */
+       .long .L50-.L60    /* FFI_TYPE_POINTER */
+
+
+/* case double */
+.L46:   
+       lfd f1,0(r5)
+       b .L44
+
+/* case float */
+.L47:
+       lfs f1,0(r5)
+       b .L44
+       
+/* case long long */
+.L48:
+       lwz r3,0(r5)
+       lwz r4,4(r5)
+       b .L44
+       
+/* case default / int32 / pointer */
+.L50:
+       lwz r3,0(r5)
+       b .L44
+       
+/* case signed int8     */
+.L55:
+       addi r5,r5,3
+       lbz r3,0(r5)
+       extsb r3,r3
+       b .L44
+
+/* case unsigned int8   */
+.L56:
+       addi r5,r5,3
+       lbz r3,0(r5)
+       b .L44
+
+/* case signed int16 */
+.L57:
+       addi r5,r5,2
+       lhz r3,0(r5)
+       extsh r3,r3
+       b .L44
+
+/* case unsigned int16 */
+.L58:  
+       addi r5,r5,2
+       lhz r3,0(r5)
+
+/* case void / done     */
+.L44:
+       
+       addi r1,r1,164          /* restore stack pointer */
+       lwz r0,8(r1)            /* get return address */
+       mtlr r0                 /* reset link register */
+       blr
+       
+/* END(ffi_closure_ASM) */
+
index 3cf504cf150ff7903660a9dbcce49e78adc2513e..d80f6bfc6f09a30a7bbbf50de68da7d2275a5588 100644 (file)
@@ -6,7 +6,7 @@
    Darwin ABI support (c) 2001 John Hornkvist
    AIX ABI support (c) 2002 Free Software Foundation, Inc.
 
-   $Id: ffi_darwin.c,v 1.2 2002/01/17 16:04:21 dje Exp $
+   $Id: ffi_darwin.c,v 1.3 2002/02/21 19:14:28 dje Exp $
 
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
@@ -31,6 +31,8 @@
 #include <ffi_common.h>
 
 #include <stdlib.h>
+   
+extern void ffi_closure_ASM(void);
 
 enum {
   /* The assembly depends on these exact flags.  */
@@ -382,3 +384,328 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
       break;
     }
 }
+
+static void flush_icache(char *);
+static void flush_range(char *, int);
+   
+/* The layout of a function descriptor.  A C function pointer really    */
+/* points to one of these.                                              */
+
+typedef struct aix_fd_struct {
+    void *code_pointer;
+    void *toc;
+} aix_fd;
+
+/* here I'd like to add the stack frame layout we use in darwin_closure.S
+ * and aix_clsoure.S
+ *
+/* SP previous -> +---------------------------------------+ <--- child frame
+                  | back chain to caller 4                | 
+                  +---------------------------------------+ 4
+                  | saved CR 4                            | 
+                  +---------------------------------------+ 8 
+                  | saved LR 4                            | 
+                  +---------------------------------------+ 12
+                  | reserved for compilers 4              | 
+                  +---------------------------------------+ 16
+                  | reserved for binders 4                | 
+                  +---------------------------------------+ 20
+                  | saved TOC pointer 4                   | 
+                  +---------------------------------------+ 24
+                  | always reserved 8*4=32  (revious GPRs)| 
+                  | according to the linkage convention   |
+                  | from AIX                             |
+                  +---------------------------------------+ 56
+                  | our FPR area 13*8=104                |
+                  | f1                                   |
+                  | .                                    |
+                  | f13                                  | 
+                  +---------------------------------------+ 160
+                  | result area 4                         | 
+SP current -->    +---------------------------------------+ 164 <- parent frame
+                  | back chain to caller 4                | 
+                  +---------------------------------------+ 168
+                  | saved CR 4                            | 
+                  +---------------------------------------+ 172
+                  | saved LR 4                            | 
+                  +---------------------------------------+ 176
+                  | reserved for compilers 4              | 
+                  +---------------------------------------+ 180
+                  | reserved for binders 4                | 
+                  +---------------------------------------+ 184
+                  | saved TOC pointer 4                   | 
+                  +---------------------------------------+ 188
+                  | always reserved 8*4=32  we store our  |
+                  | GPRs here                            |
+                  | r3                                   |
+                  | .                                    |
+                  | r10                                  |
+                  +---------------------------------------+ 220
+                  | PST area, overflow part              | 
+                  +---------------------------------------+ xxx
+                  | ????                                 | 
+                  +---------------------------------------+ xxx
+
+*/
+ffi_status
+ffi_prep_closure (ffi_closure* closure,    
+                  ffi_cif* cif,
+                  void (*fun)(ffi_cif*, void*, void**, void*),
+                  void *user_data)
+{
+  unsigned int *tramp;
+  struct ffi_aix_trampoline_struct *tramp_aix;
+  switch (cif->abi)
+    {  
+    case FFI_DARWIN:
+
+      FFI_ASSERT (cif->abi == FFI_DARWIN);
+
+      tramp = (unsigned int *) &closure->tramp[0];
+      tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
+      tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
+      tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
+      tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11)  /* function address */
+      tramp[6] = 0x7c0803a6;  /*   mtlr    r0  */
+      tramp[7] = 0x7d8903a6;  /*   mtctr   r12 */
+      tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11)  /* static chain */
+      tramp[9] = 0x4e800420;  /*   bctr */
+      *(void **) &tramp[2] = (void *)ffi_closure_ASM; /* function */
+      *(void **) &tramp[3] = (void *)closure;          /* context */
+
+      closure->cif = cif;
+      closure->fun = fun;
+      closure->user_data = user_data;
+
+      /* Flush the icache. Only necessary on Darwin  */
+      flush_range(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
+     
+      break;
+
+    case FFI_AIX:
+
+      tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);
+      aix_fd *fd = (aix_fd *)(void *)ffi_closure_ASM;
+
+      FFI_ASSERT (cif->abi == FFI_AIX);
+
+      tramp_aix->code_pointer = fd->code_pointer;
+      tramp_aix->toc = fd->toc;
+      tramp_aix->static_chain = closure;
+      closure->cif = cif;
+      closure->fun = fun;
+      closure->user_data = user_data;
+
+    default:
+
+      FFI_ASSERT(0);
+      break;
+    }
+  return FFI_OK;
+}
+
+static void
+flush_icache(char *addr)
+{
+#ifndef _AIX
+  __asm__ volatile (
+                "dcbf 0,%0;"
+                "sync;"
+                "icbi 0,%0;"
+                "sync;"
+                "isync;"
+                : : "r"(addr) : "memory");
+#endif
+}
+
+static void
+flush_range(char * addr1, int size)
+{
+#define MIN_LINE_SIZE 32
+  int i;
+  for (i = 0; i < size; i += MIN_LINE_SIZE)
+    flush_icache(addr1+i);
+  flush_icache(addr1+size-1);
+}
+
+int ffi_closure_helper_DARWIN (ffi_closure*, void*, unsigned long*,
+                                     unsigned long*, unsigned long*);
+
+/* Basically the trampoline invokes ffi_closure_ASM, and on
+ * entry, r11 holds the address of the closure.
+ * After storing the registers that could possibly contain
+ * parameters to be passed into the stack frame and setting
+ * up space for a return value, ffi_closure_ASM invokes the
+ * following helper function to do most of the work
+ */
+
+int
+ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
+            unsigned long * pgr, unsigned long * pfr,
+            unsigned long * pst)
+{
+  /* rvalue is the pointer to space for return value in closure assembly */
+  /* pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM */
+  /* pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM */
+  /* pst is the pointer to outgoing parameter stack in original caller */
+
+  void **          avalue;
+  ffi_type **      arg_types;
+  long             i, avn;
+  long             nf;   /* number of floating registers already used */
+  long             ng;   /* number of general registers already used */
+  ffi_cif *        cif;
+  double           temp;
+
+  cif = closure->cif;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  nf = 0;
+  ng = 0;
+
+  /* Copy the caller's structure return value address so that the closure
+     returns the data directly to the caller.  */
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      rvalue = (void *)pgr;
+      ng++;      
+      pgr++;
+    }
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  while (i < avn)
+    {
+      switch (arg_types[i]->type)
+        {
+        case FFI_TYPE_SINT8:
+        case FFI_TYPE_UINT8:
+        /* there are 8 gpr registers used to pass values */
+          if (ng < 8) {
+             avalue[i] = (((char *)pgr)+3);
+             ng++;
+             pgr++;
+          } else {
+             avalue[i] = (((char *)pst)+3);
+             pst++;
+          }
+          break;
+
+        case FFI_TYPE_SINT16:
+        case FFI_TYPE_UINT16:
+        /* there are 8 gpr registers used to pass values */
+          if (ng < 8) {
+             avalue[i] = (((char *)pgr)+2);
+             ng++;
+             pgr++;
+          } else {
+             avalue[i] = (((char *)pst)+2);
+             pst++;
+          }
+          break;
+
+        case FFI_TYPE_SINT32:
+        case FFI_TYPE_UINT32:
+        case FFI_TYPE_POINTER:
+        case FFI_TYPE_STRUCT:
+        /* there are 8 gpr registers used to pass values */
+          if (ng < 8) {  
+             avalue[i] = pgr;
+             ng++;
+             pgr++;
+          } else {
+             avalue[i] = pst;
+             pst++;
+          }
+          break;
+
+        case FFI_TYPE_SINT64:
+        case FFI_TYPE_UINT64:
+          /* long long ints are passed in two gpr's if available or in 
+           * the pst, one place is a bit odd, when a long long passes
+          * the boundary between gpr and pst area we have to increment
+          * the pst by one.
+           */
+           if (ng < 7) {
+              avalue[i] = pgr;
+              ng+=2;
+              pgr+=2;
+           } else if (ng == 7) {
+              avalue[i] = pgr;
+              ng++;
+              pgr++;
+              pst++;
+           } else {
+              avalue[i] = pst;
+              pst+=2;
+           }
+           break;
+
+        case FFI_TYPE_FLOAT:
+          /* a float value consumes a GPR
+           *
+           * there are 13 64bit floating point registers 
+          */
+          
+         if ((ng > 7) && (nf < 13)) {
+            pst++;
+         }
+          if (nf < 13) {
+            temp = *(double*)pfr;
+             *(float*)pfr = (float)temp;
+             avalue[i] = pfr;
+             nf++;
+             pfr+=2;
+             ng++;
+            pgr++;
+                
+          } else {
+             avalue[i] = pst;
+             nf++;
+             pst++;
+          }
+          break;
+
+        case FFI_TYPE_DOUBLE:
+         /* a double value consumes two GPRs
+           *  
+           * there are 13 64bit floating point registers 
+          */
+
+         if ((ng == 7) && (nf < 13)) {
+             pst++;    /* if only one gpr is left the double steals it */
+         } else if ((ng > 7) && (nf < 13)) {
+            pst+=2;    /* a double consumes two GPRs in Darwin/AIX */
+         }
+          if (nf < 13) {
+             avalue[i] = pfr;
+             nf++;
+             pfr+=2;
+            ng+=2;
+            pgr+=2;
+
+          } else {
+             avalue[i] = pst;
+             nf++;
+             pst+=2;
+          }
+          break;
+
+        default:
+          FFI_ASSERT(0);
+       
+        }
+
+      i++;
+    }
+
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_ASM to perform return type promotions.  */
+  return cif->rtype->type;
+
+}