mozilla-libffi-ppc64le.patch
author Wolfgang Rosenauer <wr@rosenauer.org>
Fri, 07 Feb 2014 22:10:42 +0100
changeset 703 c4aab80e472f
parent 692 8add0ba12be5
permissions -rw-r--r--
Firefox 28.0beta1
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
692
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
     1
# HG changeset patch
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
     2
# Parent a38c083288a664a9b1fdeaa16563b47661ef6c16
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
     3
# User Ulrich Weigand <uweigand@de.ibm.com>
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
     4
PPC64 LE support for libffi
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
     5
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
     6
diff --git a/js/src/ctypes/libffi/src/powerpc/aix.S b/js/src/ctypes/libffi/src/powerpc/aix.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
     7
--- a/js/src/ctypes/libffi/src/powerpc/aix.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
     8
+++ b/js/src/ctypes/libffi/src/powerpc/aix.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
     9
@@ -1,10 +1,10 @@
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    10
 /* -----------------------------------------------------------------------
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    11
-   aix.S - Copyright (c) 2002,2009 Free Software Foundation, Inc.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    12
+   aix.S - Copyright (c) 2002, 2009 Free Software Foundation, Inc.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    13
    based on darwin.S by John Hornkvist
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    14
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    15
    PowerPC Assembly glue.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    16
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    17
    Permission is hereby granted, free of charge, to any person obtaining
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    18
    a copy of this software and associated documentation files (the
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    19
    ``Software''), to deal in the Software without restriction, including
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    20
    without limitation the rights to use, copy, modify, merge, publish,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    21
@@ -74,16 +74,18 @@
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    22
 	.set f15,15
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    23
 	.set f16,16
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    24
 	.set f17,17
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    25
 	.set f18,18
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    26
 	.set f19,19
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    27
 	.set f20,20
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    28
 	.set f21,21
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    29
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    30
+	.extern .ffi_prep_args
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    31
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    32
 #define LIBFFI_ASM
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    33
 #include <fficonfig.h>
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    34
 #include <ffi.h>
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    35
 #define JUMPTARGET(name) name
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    36
 #define L(x) x
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    37
 	.file "aix.S"
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    38
 	.toc
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    39
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    40
@@ -120,16 +122,17 @@ ffi_call_AIX:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    41
 	mr	r31, r5	/* flags, */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    42
 	mr	r30, r6	/* rvalue, */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    43
 	mr	r29, r7	/* function address.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    44
 	std	r2, 40(r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    45
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    46
 	/* Call ffi_prep_args.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    47
 	mr	r4, r1
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    48
 	bl	.ffi_prep_args
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    49
+	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    50
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    51
 	/* Now do the call.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    52
 	ld	r0, 0(r29)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    53
 	ld	r2, 8(r29)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    54
 	ld	r11, 16(r29)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    55
 	/* Set up cr1 with bits 4-7 of the flags.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    56
 	mtcrf	0x40, r31
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    57
 	mtctr	r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    58
@@ -221,16 +224,17 @@ L(float_return_value):
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    59
 	mr	r31, r5	/* flags, */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    60
 	mr	r30, r6	/* rvalue, */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    61
 	mr	r29, r7	/* function address, */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    62
 	stw	r2, 20(r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    63
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    64
 	/* Call ffi_prep_args.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    65
 	mr	r4, r1
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    66
 	bl	.ffi_prep_args
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    67
+	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    68
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    69
 	/* Now do the call.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    70
 	lwz	r0, 0(r29)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    71
 	lwz	r2, 4(r29)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    72
 	lwz	r11, 8(r29)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    73
 	/* Set up cr1 with bits 4-7 of the flags.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    74
 	mtcrf	0x40, r31
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    75
 	mtctr	r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    76
diff --git a/js/src/ctypes/libffi/src/powerpc/ffi.c b/js/src/ctypes/libffi/src/powerpc/ffi.c
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    77
--- a/js/src/ctypes/libffi/src/powerpc/ffi.c
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    78
+++ b/js/src/ctypes/libffi/src/powerpc/ffi.c
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    79
@@ -1,12 +1,14 @@
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    80
 /* -----------------------------------------------------------------------
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    81
-   ffi.c - Copyright (c) 1998 Geoffrey Keating
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    82
-   Copyright (C) 2007, 2008 Free Software Foundation, Inc
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    83
-   Copyright (C) 2008 Red Hat, Inc
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    84
+   ffi.c - Copyright (C) 2011 Anthony Green
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    85
+           Copyright (C) 2011 Kyle Moffett
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    86
+           Copyright (C) 2008 Red Hat, Inc
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    87
+           Copyright (C) 2007, 2008 Free Software Foundation, Inc
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    88
+	   Copyright (c) 1998 Geoffrey Keating
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    89
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    90
    PowerPC Foreign Function Interface
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    91
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    92
    Permission is hereby granted, free of charge, to any person obtaining
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    93
    a copy of this software and associated documentation files (the
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    94
    ``Software''), to deal in the Software without restriction, including
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    95
    without limitation the rights to use, copy, modify, merge, publish,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    96
    distribute, sublicense, and/or sell copies of the Software, and to
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    97
@@ -34,42 +36,39 @@
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    98
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
    99
 extern void ffi_closure_SYSV (void);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   100
 extern void FFI_HIDDEN ffi_closure_LINUX64 (void);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   101
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   102
 enum {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   103
   /* The assembly depends on these exact flags.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   104
   FLAG_RETURNS_SMST	= 1 << (31-31), /* Used for FFI_SYSV small structs.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   105
   FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   106
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   107
   FLAG_RETURNS_FP       = 1 << (31-29),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   108
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   109
   FLAG_RETURNS_64BITS   = 1 << (31-28),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   110
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   111
   FLAG_RETURNS_128BITS  = 1 << (31-27), /* cr6  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   112
-  FLAG_SYSV_SMST_R4     = 1 << (31-26), /* use r4 for FFI_SYSV 8 byte
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   113
-					   structs.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   114
-  FLAG_SYSV_SMST_R3     = 1 << (31-25), /* use r3 for FFI_SYSV 4 byte
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   115
-					   structs.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   116
-  /* Bits (31-24) through (31-19) store shift value for SMST */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   117
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   118
   FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   119
+  FLAG_ARG_NEEDS_PSAVE  = FLAG_ARG_NEEDS_COPY, /* Used by ELFv2 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   120
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   121
   FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   122
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   123
   FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   124
   FLAG_RETVAL_REFERENCE = 1 << (31- 4)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   125
 };
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   126
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   127
 /* About the SYSV ABI.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   128
-unsigned int NUM_GPR_ARG_REGISTERS = 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   129
+#define ASM_NEEDS_REGISTERS 4
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   130
+#define NUM_GPR_ARG_REGISTERS 8
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   131
 #ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   132
-unsigned int NUM_FPR_ARG_REGISTERS = 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   133
-#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   134
-unsigned int NUM_FPR_ARG_REGISTERS = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   135
+# define NUM_FPR_ARG_REGISTERS 8
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   136
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   137
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   138
-enum { ASM_NEEDS_REGISTERS = 4 };
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   139
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   140
 /* ffi_prep_args_SYSV is called by the assembly routine once stack space
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   141
    has been allocated for the function's arguments.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   142
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   143
    The stack layout we want looks like this:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   144
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   145
    |   Return address from ffi_call_SYSV 4bytes	|	higher addresses
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   146
    |--------------------------------------------|
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   147
    |   Previous backchain pointer	4	|       stack pointer here
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   148
@@ -108,100 +107,119 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   149
   /* 'stacktop' points at the previous backchain pointer.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   150
   valp stacktop;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   151
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   152
   /* 'gpr_base' points at the space for gpr3, and grows upwards as
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   153
      we use GPR registers.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   154
   valp gpr_base;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   155
   int intarg_count;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   156
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   157
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   158
   /* 'fpr_base' points at the space for fpr1, and grows upwards as
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   159
      we use FPR registers.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   160
   valp fpr_base;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   161
   int fparg_count;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   162
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   163
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   164
   /* 'copy_space' grows down as we put structures in it.  It should
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   165
      stay 16-byte aligned.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   166
   valp copy_space;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   167
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   168
   /* 'next_arg' grows up as we put parameters in it.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   169
   valp next_arg;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   170
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   171
-  int i, ii MAYBE_UNUSED;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   172
+  int i;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   173
   ffi_type **ptr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   174
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   175
   double double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   176
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   177
   union {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   178
     void **v;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   179
     char **c;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   180
     signed char **sc;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   181
     unsigned char **uc;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   182
     signed short **ss;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   183
     unsigned short **us;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   184
     unsigned int **ui;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   185
     long long **ll;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   186
     float **f;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   187
     double **d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   188
   } p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   189
   size_t struct_copy_size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   190
   unsigned gprvalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   191
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   192
-  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   193
-    NUM_FPR_ARG_REGISTERS = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   194
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   195
   stacktop.c = (char *) stack + bytes;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   196
   gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   197
   intarg_count = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   198
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   199
   fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   200
   fparg_count = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   201
   copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   202
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   203
+  copy_space.c = gpr_base.c;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   204
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   205
   next_arg.u = stack + 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   206
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   207
   /* Check that everything starts aligned properly.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   208
-  FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   209
-  FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   210
-  FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   211
+  FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   212
+  FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   213
+  FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   214
   FFI_ASSERT ((bytes & 0xF) == 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   215
   FFI_ASSERT (copy_space.c >= next_arg.c);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   216
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   217
   /* Deal with return values that are actually pass-by-reference.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   218
   if (flags & FLAG_RETVAL_REFERENCE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   219
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   220
       *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   221
       intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   222
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   223
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   224
   /* Now for the arguments.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   225
   p_argv.v = ecif->avalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   226
   for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   227
        i > 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   228
        i--, ptr++, p_argv.v++)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   229
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   230
-      switch ((*ptr)->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   231
-	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   232
+      unsigned short typenum = (*ptr)->type;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   233
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   234
+      /* We may need to handle some values depending on ABI */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   235
+      if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   236
+		if (typenum == FFI_TYPE_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   237
+			typenum = FFI_TYPE_UINT32;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   238
+		if (typenum == FFI_TYPE_DOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   239
+			typenum = FFI_TYPE_UINT64;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   240
+		if (typenum == FFI_TYPE_LONGDOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   241
+			typenum = FFI_TYPE_UINT128;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   242
+      } else if (ecif->cif->abi != FFI_LINUX) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   243
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   244
+		if (typenum == FFI_TYPE_LONGDOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   245
+			typenum = FFI_TYPE_STRUCT;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   246
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   247
+      }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   248
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   249
+      /* Now test the translated value */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   250
+      switch (typenum) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   251
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   252
 	case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   253
 	  /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   254
-	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   255
-	    goto soft_float_prep;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   256
 	  double_tmp = **p_argv.f;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   257
 	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   258
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   259
 	      *next_arg.f = (float) double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   260
 	      next_arg.u += 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   261
 	      intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   262
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   263
 	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   264
 	    *fpr_base.d++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   265
 	  fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   266
 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   267
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   268
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   269
 	case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   270
 	  /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   271
-	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   272
-	    goto soft_double_prep;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   273
 	  double_tmp = **p_argv.d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   274
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   275
 	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   276
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   277
 	      if (intarg_count >= NUM_GPR_ARG_REGISTERS
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   278
 		  && intarg_count % 2 != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   279
 		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   280
 		  intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   281
@@ -213,53 +231,16 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   282
 	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   283
 	    *fpr_base.d++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   284
 	  fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   285
 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   286
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   287
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   288
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   289
 	case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   290
-	  if ((ecif->cif->abi != FFI_LINUX)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   291
-		&& (ecif->cif->abi != FFI_LINUX_SOFT_FLOAT))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   292
-	    goto do_struct;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   293
-	  /* The soft float ABI for long doubles works like this,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   294
-	     a long double is passed in four consecutive gprs if available.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   295
-	     A maximum of 2 long doubles can be passed in gprs.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   296
-	     If we do not have 4 gprs left, the long double is passed on the
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   297
-	     stack, 4-byte aligned.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   298
-	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   299
-	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   300
-	      unsigned int int_tmp = (*p_argv.ui)[0];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   301
-	      if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   302
-		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   303
-		  if (intarg_count < NUM_GPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   304
-		    intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   305
-		  *next_arg.u = int_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   306
-		  next_arg.u++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   307
-		  for (ii = 1; ii < 4; ii++)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   308
-		    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   309
-		      int_tmp = (*p_argv.ui)[ii];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   310
-		      *next_arg.u = int_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   311
-		      next_arg.u++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   312
-		    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   313
-		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   314
-	      else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   315
-		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   316
-		  *gpr_base.u++ = int_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   317
-		  for (ii = 1; ii < 4; ii++)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   318
-		    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   319
-		      int_tmp = (*p_argv.ui)[ii];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   320
-		      *gpr_base.u++ = int_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   321
-		    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   322
-		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   323
-	      intarg_count +=4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   324
-	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   325
-	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   326
-	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   327
 	      double_tmp = (*p_argv.d)[0];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   328
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   329
 	      if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   330
 		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   331
 		  if (intarg_count >= NUM_GPR_ARG_REGISTERS
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   332
 		      && intarg_count % 2 != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   333
 		    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   334
 		      intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   335
@@ -275,23 +256,50 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   336
 		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   337
 		  *fpr_base.d++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   338
 		  double_tmp = (*p_argv.d)[1];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   339
 		  *fpr_base.d++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   340
 		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   341
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   342
 	      fparg_count += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   343
 	      FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   344
-	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   345
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   346
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   347
+#endif /* have FPRs */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   348
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   349
+	/*
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   350
+	 * The soft float ABI for long doubles works like this, a long double
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   351
+	 * is passed in four consecutive GPRs if available.  A maximum of 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   352
+	 * long doubles can be passed in gprs.  If we do not have 4 GPRs
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   353
+	 * left, the long double is passed on the stack, 4-byte aligned.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   354
+	 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   355
+	case FFI_TYPE_UINT128: {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   356
+		unsigned int int_tmp = (*p_argv.ui)[0];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   357
+		unsigned int ii;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   358
+		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   359
+			if (intarg_count < NUM_GPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   360
+				intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   361
+			*(next_arg.u++) = int_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   362
+			for (ii = 1; ii < 4; ii++) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   363
+				int_tmp = (*p_argv.ui)[ii];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   364
+				*(next_arg.u++) = int_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   365
+			}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   366
+		} else {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   367
+			*(gpr_base.u++) = int_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   368
+			for (ii = 1; ii < 4; ii++) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   369
+				int_tmp = (*p_argv.ui)[ii];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   370
+				*(gpr_base.u++) = int_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   371
+			}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   372
+		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   373
+		intarg_count += 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   374
+		break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   375
+	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   376
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   377
 	case FFI_TYPE_UINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   378
 	case FFI_TYPE_SINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   379
-	soft_double_prep:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   380
 	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   381
 	    intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   382
 	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   383
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   384
 	      if (intarg_count % 2 != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   385
 		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   386
 		  intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   387
 		  next_arg.u++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   388
@@ -314,19 +322,16 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   389
 		  gpr_base.u++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   390
 		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   391
 	      *gpr_base.ll++ = **p_argv.ll;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   392
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   393
 	  intarg_count += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   394
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   395
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   396
 	case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   397
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   398
-	do_struct:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   399
-#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   400
 	  struct_copy_size = ((*ptr)->size + 15) & ~0xF;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   401
 	  copy_space.c -= struct_copy_size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   402
 	  memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   403
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   404
 	  gprvalue = (unsigned long) copy_space.c;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   405
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   406
 	  FFI_ASSERT (copy_space.c > next_arg.c);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   407
 	  FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   408
@@ -344,45 +349,91 @@ ffi_prep_args_SYSV (extended_cif *ecif, 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   409
 	case FFI_TYPE_SINT16:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   410
 	  gprvalue = **p_argv.ss;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   411
 	  goto putgpr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   412
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   413
 	case FFI_TYPE_INT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   414
 	case FFI_TYPE_UINT32:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   415
 	case FFI_TYPE_SINT32:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   416
 	case FFI_TYPE_POINTER:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   417
-	soft_float_prep:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   418
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   419
 	  gprvalue = **p_argv.ui;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   420
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   421
 	putgpr:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   422
 	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   423
 	    *next_arg.u++ = gprvalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   424
 	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   425
 	    *gpr_base.u++ = gprvalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   426
 	  intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   427
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   428
 	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   429
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   430
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   431
   /* Check that we didn't overrun the stack...  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   432
   FFI_ASSERT (copy_space.c >= next_arg.c);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   433
   FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   434
+  /* The assert below is testing that the number of integer arguments agrees
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   435
+     with the number found in ffi_prep_cif_machdep().  However, intarg_count
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   436
+     is incremented whenever we place an FP arg on the stack, so account for
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   437
+     that before our assert test.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   438
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   439
+  if (fparg_count > NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   440
+    intarg_count -= fparg_count - NUM_FPR_ARG_REGISTERS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   441
   FFI_ASSERT (fpr_base.u
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   442
 	      <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   443
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   444
   FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   445
 }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   446
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   447
 /* About the LINUX64 ABI.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   448
 enum {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   449
   NUM_GPR_ARG_REGISTERS64 = 8,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   450
   NUM_FPR_ARG_REGISTERS64 = 13
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   451
 };
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   452
 enum { ASM_NEEDS_REGISTERS64 = 4 };
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   453
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   454
+#if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   455
+static unsigned int
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   456
+discover_homogeneous_aggregate (const ffi_type *t, unsigned int *elnum)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   457
+{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   458
+  switch (t->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   459
+    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   460
+    case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   461
+    case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   462
+      *elnum = 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   463
+      return (int) t->type;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   464
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   465
+    case FFI_TYPE_STRUCT:;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   466
+      {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   467
+	unsigned int base_elt = 0, total_elnum = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   468
+	ffi_type **el = t->elements;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   469
+	while (*el)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   470
+	  {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   471
+	    unsigned int el_elt, el_elnum = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   472
+	    el_elt = discover_homogeneous_aggregate (*el, &el_elnum);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   473
+	    if (el_elt == 0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   474
+		|| (base_elt && base_elt != el_elt))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   475
+	      return 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   476
+	    base_elt = el_elt;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   477
+	    total_elnum += el_elnum;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   478
+	    if (total_elnum > 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   479
+	      return 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   480
+	    el++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   481
+	  }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   482
+	*elnum = total_elnum;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   483
+	return base_elt;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   484
+      }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   485
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   486
+    default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   487
+      return 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   488
+    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   489
+}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   490
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   491
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   492
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   493
 /* ffi_prep_args64 is called by the assembly routine once stack space
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   494
    has been allocated for the function's arguments.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   495
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   496
    The stack layout we want looks like this:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   497
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   498
    |   Ret addr from ffi_call_LINUX64	8bytes	|	higher addresses
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   499
    |--------------------------------------------|
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   500
    |   CR save area			8bytes	|
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   501
@@ -418,141 +469,216 @@ ffi_prep_args64 (extended_cif *ecif, uns
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   502
   const unsigned long bytes = ecif->cif->bytes;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   503
   const unsigned long flags = ecif->cif->flags;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   504
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   505
   typedef union {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   506
     char *c;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   507
     unsigned long *ul;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   508
     float *f;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   509
     double *d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   510
+    size_t p;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   511
   } valp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   512
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   513
   /* 'stacktop' points at the previous backchain pointer.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   514
   valp stacktop;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   515
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   516
   /* 'next_arg' points at the space for gpr3, and grows upwards as
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   517
      we use GPR registers, then continues at rest.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   518
   valp gpr_base;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   519
   valp gpr_end;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   520
   valp rest;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   521
   valp next_arg;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   522
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   523
   /* 'fpr_base' points at the space for fpr3, and grows upwards as
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   524
      we use FPR registers.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   525
   valp fpr_base;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   526
-  int fparg_count;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   527
+  unsigned int fparg_count;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   528
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   529
-  int i, words;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   530
+  unsigned int i, words, nargs, nfixedargs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   531
   ffi_type **ptr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   532
   double double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   533
   union {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   534
     void **v;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   535
     char **c;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   536
     signed char **sc;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   537
     unsigned char **uc;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   538
     signed short **ss;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   539
     unsigned short **us;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   540
     signed int **si;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   541
     unsigned int **ui;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   542
     unsigned long **ul;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   543
     float **f;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   544
     double **d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   545
   } p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   546
   unsigned long gprvalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   547
+#ifdef __STRUCT_PARM_ALIGN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   548
+  unsigned long align;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   549
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   550
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   551
   stacktop.c = (char *) stack + bytes;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   552
   gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   553
   gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   554
+#if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   555
+  rest.ul = stack + 4 + NUM_GPR_ARG_REGISTERS64;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   556
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   557
   rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   558
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   559
   fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   560
   fparg_count = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   561
   next_arg.ul = gpr_base.ul;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   562
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   563
   /* Check that everything starts aligned properly.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   564
   FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   565
   FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   566
   FFI_ASSERT ((bytes & 0xF) == 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   567
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   568
   /* Deal with return values that are actually pass-by-reference.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   569
   if (flags & FLAG_RETVAL_REFERENCE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   570
     *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   571
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   572
   /* Now for the arguments.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   573
   p_argv.v = ecif->avalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   574
-  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   575
-       i > 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   576
-       i--, ptr++, p_argv.v++)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   577
+  nargs = ecif->cif->nargs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   578
+  nfixedargs = ecif->cif->nfixedargs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   579
+  for (ptr = ecif->cif->arg_types, i = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   580
+       i < nargs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   581
+       i++, ptr++, p_argv.v++)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   582
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   583
+      unsigned int elt, elnum;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   584
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   585
       switch ((*ptr)->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   586
 	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   587
 	case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   588
 	  double_tmp = **p_argv.f;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   589
-	  *next_arg.f = (float) double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   590
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   591
+	    *fpr_base.d++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   592
+	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   593
+	    *next_arg.f = (float) double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   594
 	  if (++next_arg.ul == gpr_end.ul)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   595
 	    next_arg.ul = rest.ul;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   596
-	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   597
-	    *fpr_base.d++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   598
 	  fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   599
 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   600
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   601
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   602
 	case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   603
 	  double_tmp = **p_argv.d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   604
-	  *next_arg.d = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   605
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   606
+	    *fpr_base.d++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   607
+	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   608
+	    *next_arg.d = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   609
 	  if (++next_arg.ul == gpr_end.ul)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   610
 	    next_arg.ul = rest.ul;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   611
-	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   612
-	    *fpr_base.d++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   613
 	  fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   614
 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   615
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   616
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   617
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   618
 	case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   619
 	  double_tmp = (*p_argv.d)[0];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   620
-	  *next_arg.d = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   621
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   622
+	    *fpr_base.d++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   623
+	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   624
+	    *next_arg.d = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   625
 	  if (++next_arg.ul == gpr_end.ul)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   626
 	    next_arg.ul = rest.ul;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   627
-	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   628
-	    *fpr_base.d++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   629
 	  fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   630
 	  double_tmp = (*p_argv.d)[1];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   631
-	  *next_arg.d = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   632
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   633
+	    *fpr_base.d++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   634
+	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   635
+	    *next_arg.d = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   636
 	  if (++next_arg.ul == gpr_end.ul)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   637
 	    next_arg.ul = rest.ul;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   638
-	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   639
-	    *fpr_base.d++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   640
 	  fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   641
 	  FFI_ASSERT (__LDBL_MANT_DIG__ == 106);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   642
 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   643
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   644
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   645
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   646
 	case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   647
-	  words = ((*ptr)->size + 7) / 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   648
-	  if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   649
+#ifdef __STRUCT_PARM_ALIGN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   650
+	  align = (*ptr)->alignment;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   651
+	  if (align > __STRUCT_PARM_ALIGN__)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   652
+	    align = __STRUCT_PARM_ALIGN__;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   653
+	  if (align > 1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   654
+	    next_arg.p = ALIGN (next_arg.p, align);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   655
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   656
+	  elt = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   657
+#if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   658
+	  elt = discover_homogeneous_aggregate (*ptr, &elnum);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   659
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   660
+	  if (elt)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   661
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   662
-	      size_t first = gpr_end.c - next_arg.c;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   663
-	      memcpy (next_arg.c, *p_argv.c, first);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   664
-	      memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   665
-	      next_arg.c = rest.c + words * 8 - first;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   666
+	      union {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   667
+		void *v;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   668
+		float *f;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   669
+		double *d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   670
+	      } arg;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   671
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   672
+	      arg.v = *p_argv.v;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   673
+	      if (elt == FFI_TYPE_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   674
+		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   675
+		  do
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   676
+		    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   677
+		      double_tmp = *arg.f++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   678
+		      if (fparg_count < NUM_FPR_ARG_REGISTERS64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   679
+			  && i < nfixedargs)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   680
+			*fpr_base.d++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   681
+		      else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   682
+			*next_arg.f = (float) double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   683
+		      if (++next_arg.f == gpr_end.f)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   684
+			next_arg.f = rest.f;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   685
+		      fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   686
+		    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   687
+		  while (--elnum != 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   688
+		  if ((next_arg.p & 3) != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   689
+		    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   690
+		      if (++next_arg.f == gpr_end.f)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   691
+			next_arg.f = rest.f;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   692
+		    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   693
+		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   694
+	      else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   695
+		do
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   696
+		  {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   697
+		    double_tmp = *arg.d++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   698
+		    if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   699
+		      *fpr_base.d++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   700
+		    else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   701
+		      *next_arg.d = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   702
+		    if (++next_arg.d == gpr_end.d)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   703
+		      next_arg.d = rest.d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   704
+		    fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   705
+		  }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   706
+		while (--elnum != 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   707
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   708
 	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   709
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   710
-	      char *where = next_arg.c;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   711
+	      words = ((*ptr)->size + 7) / 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   712
+	      if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   713
+		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   714
+		  size_t first = gpr_end.c - next_arg.c;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   715
+		  memcpy (next_arg.c, *p_argv.c, first);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   716
+		  memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   717
+		  next_arg.c = rest.c + words * 8 - first;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   718
+		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   719
+	      else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   720
+		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   721
+		  char *where = next_arg.c;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   722
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   723
-	      /* Structures with size less than eight bytes are passed
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   724
-		 left-padded.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   725
-	      if ((*ptr)->size < 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   726
-		where += 8 - (*ptr)->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   727
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   728
-	      memcpy (where, *p_argv.c, (*ptr)->size);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   729
-	      next_arg.ul += words;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   730
-	      if (next_arg.ul == gpr_end.ul)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   731
-		next_arg.ul = rest.ul;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   732
+#ifndef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   733
+		  /* Structures with size less than eight bytes are passed
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   734
+		     left-padded.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   735
+		  if ((*ptr)->size < 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   736
+		    where += 8 - (*ptr)->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   737
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   738
+		  memcpy (where, *p_argv.c, (*ptr)->size);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   739
+		  next_arg.ul += words;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   740
+		  if (next_arg.ul == gpr_end.ul)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   741
+		    next_arg.ul = rest.ul;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   742
+		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   743
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   744
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   745
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   746
 	case FFI_TYPE_UINT8:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   747
 	  gprvalue = **p_argv.uc;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   748
 	  goto putgpr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   749
 	case FFI_TYPE_SINT8:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   750
 	  gprvalue = **p_argv.sc;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   751
@@ -586,53 +712,55 @@ ffi_prep_args64 (extended_cif *ecif, uns
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   752
   FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   753
 	      || (next_arg.ul >= gpr_base.ul
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   754
 		  && next_arg.ul <= gpr_base.ul + 4));
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   755
 }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   756
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   757
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   758
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   759
 /* Perform machine dependent cif processing */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   760
-ffi_status
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   761
-ffi_prep_cif_machdep (ffi_cif *cif)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   762
+static ffi_status
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   763
+ffi_prep_cif_machdep_core (ffi_cif *cif)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   764
 {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   765
   /* All this is for the SYSV and LINUX64 ABI.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   766
-  int i;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   767
   ffi_type **ptr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   768
   unsigned bytes;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   769
-  int fparg_count = 0, intarg_count = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   770
-  unsigned flags = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   771
+  unsigned i, fparg_count = 0, intarg_count = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   772
+  unsigned flags = cif->flags;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   773
   unsigned struct_copy_size = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   774
   unsigned type = cif->rtype->type;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   775
   unsigned size = cif->rtype->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   776
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   777
-  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   778
-    NUM_FPR_ARG_REGISTERS = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   779
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   780
+  /* The machine-independent calculation of cif->bytes doesn't work
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   781
+     for us.  Redo the calculation.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   782
   if (cif->abi != FFI_LINUX64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   783
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   784
-      /* All the machine-independent calculation of cif->bytes will be wrong.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   785
-	 Redo the calculation for SYSV.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   786
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   787
       /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   788
       bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   789
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   790
       /* Space for the GPR registers.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   791
       bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   792
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   793
   else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   794
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   795
       /* 64-bit ABI.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   796
+#if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   797
+      /* Space for backchain, CR, LR, TOC and the asm's temp regs.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   798
+      bytes = (4 + ASM_NEEDS_REGISTERS64) * sizeof (long);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   799
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   800
+      /* Space for the general registers.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   801
+      bytes += NUM_GPR_ARG_REGISTERS64 * sizeof (long);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   802
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   803
       /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   804
 	 regs.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   805
       bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   806
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   807
       /* Space for the mandatory parm save area and general registers.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   808
       bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   809
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   810
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   811
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   812
   /* Return value handling.  The rules for SYSV are as follows:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   813
      - 32-bit (or less) integer values are returned in gpr3;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   814
      - Structures of size <= 4 bytes also returned in gpr3;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   815
      - 64-bit integer values and structures between 5 and 8 bytes are returned
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   816
      in gpr3 and gpr4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   817
      - Single/double FP values are returned in fpr1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   818
@@ -641,71 +769,93 @@ ffi_prep_cif_machdep (ffi_cif *cif)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   819
      - long doubles (if not equivalent to double) are returned in
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   820
      fpr1,fpr2 for Linux and as for large structs for SysV.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   821
      For LINUX64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   822
      - integer values in gpr3;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   823
      - Structures/Unions by reference;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   824
      - Single/double FP values in fpr1, long double in fpr1,fpr2.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   825
      - soft-float float/doubles are treated as UINT32/UINT64 respectivley.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   826
      - soft-float long doubles are returned in gpr3-gpr6.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   827
+  /* First translate for softfloat/nonlinux */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   828
+  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   829
+    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   830
+      if (type == FFI_TYPE_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   831
+	type = FFI_TYPE_UINT32;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   832
+      if (type == FFI_TYPE_DOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   833
+	type = FFI_TYPE_UINT64;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   834
+      if (type == FFI_TYPE_LONGDOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   835
+	type = FFI_TYPE_UINT128;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   836
+    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   837
+  else if (cif->abi != FFI_LINUX
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   838
+	   && cif->abi != FFI_LINUX64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   839
+    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   840
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   841
+      if (type == FFI_TYPE_LONGDOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   842
+	type = FFI_TYPE_STRUCT;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   843
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   844
+    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   845
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   846
   switch (type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   847
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   848
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   849
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   850
     case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   851
-      if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   852
-	&& cif->abi != FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   853
-	goto byref;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   854
       flags |= FLAG_RETURNS_128BITS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   855
       /* Fall through.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   856
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   857
     case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   858
       flags |= FLAG_RETURNS_64BITS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   859
       /* Fall through.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   860
     case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   861
-      /* With FFI_LINUX_SOFT_FLOAT no fp registers are used.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   862
-      if (cif->abi != FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   863
-	flags |= FLAG_RETURNS_FP;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   864
+      flags |= FLAG_RETURNS_FP;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   865
       break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   866
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   867
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   868
+    case FFI_TYPE_UINT128:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   869
+      flags |= FLAG_RETURNS_128BITS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   870
+      /* Fall through.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   871
     case FFI_TYPE_UINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   872
     case FFI_TYPE_SINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   873
       flags |= FLAG_RETURNS_64BITS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   874
       break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   875
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   876
     case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   877
-      if (cif->abi == FFI_SYSV)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   878
+      /*
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   879
+       * The final SYSV ABI says that structures smaller or equal 8 bytes
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   880
+       * are returned in r3/r4.  The FFI_GCC_SYSV ABI instead returns them
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   881
+       * in memory.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   882
+       *
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   883
+       * NOTE: The assembly code can safely assume that it just needs to
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   884
+       *       store both r3 and r4 into a 8-byte word-aligned buffer, as
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   885
+       *       we allocate a temporary buffer in ffi_call() if this flag is
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   886
+       *       set.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   887
+       */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   888
+      if (cif->abi == FFI_SYSV && size <= 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   889
 	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   890
-	  /* The final SYSV ABI says that structures smaller or equal 8 bytes
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   891
-	     are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   892
-	     in memory.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   893
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   894
-	  /* Treat structs with size <= 8 bytes.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   895
-	  if (size <= 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   896
+	  flags |= FLAG_RETURNS_SMST;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   897
+	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   898
+	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   899
+#if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   900
+      if (cif->abi == FFI_LINUX64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   901
+	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   902
+	  unsigned int elt, elnum;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   903
+	  elt = discover_homogeneous_aggregate (cif->rtype, &elnum);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   904
+	  if (elt)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   905
+	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   906
+	      if (elt == FFI_TYPE_DOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   907
+		flags |= FLAG_RETURNS_64BITS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   908
+	      flags |= FLAG_RETURNS_FP | FLAG_RETURNS_SMST;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   909
+	      break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   910
+	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   911
+	  if (size <= 16)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   912
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   913
 	      flags |= FLAG_RETURNS_SMST;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   914
-	      /* These structs are returned in r3. We pack the type and the
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   915
-		 precalculated shift value (needed in the sysv.S) into flags.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   916
-		 The same applies for the structs returned in r3/r4.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   917
-	      if (size <= 4)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   918
-		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   919
-		  flags |= FLAG_SYSV_SMST_R3;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   920
-		  flags |= 8 * (4 - size) << 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   921
-		  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   922
-		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   923
-	      /* These structs are returned in r3 and r4. See above.   */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   924
-	      if  (size <= 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   925
-		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   926
-		  flags |= FLAG_SYSV_SMST_R3 | FLAG_SYSV_SMST_R4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   927
-		  flags |= 8 * (8 - size) << 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   928
-		  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   929
-		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   930
+	      break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   931
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   932
 	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   933
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   934
-    byref:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   935
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   936
       intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   937
       flags |= FLAG_RETVAL_REFERENCE;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   938
       /* Fall through.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   939
     case FFI_TYPE_VOID:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   940
       flags |= FLAG_RETURNS_NOTHING;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   941
       break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   942
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   943
@@ -717,218 +867,334 @@ ffi_prep_cif_machdep (ffi_cif *cif)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   944
   if (cif->abi != FFI_LINUX64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   945
     /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   946
        first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   947
        goes on the stack.  Structures and long doubles (if not equivalent
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   948
        to double) are passed as a pointer to a copy of the structure.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   949
        Stuff on the stack needs to keep proper alignment.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   950
     for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   951
       {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   952
-	switch ((*ptr)->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   953
-	  {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   954
+	unsigned short typenum = (*ptr)->type;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   955
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   956
+	/* We may need to handle some values depending on ABI */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   957
+	if (cif->abi == FFI_LINUX_SOFT_FLOAT) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   958
+		if (typenum == FFI_TYPE_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   959
+			typenum = FFI_TYPE_UINT32;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   960
+		if (typenum == FFI_TYPE_DOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   961
+			typenum = FFI_TYPE_UINT64;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   962
+		if (typenum == FFI_TYPE_LONGDOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   963
+			typenum = FFI_TYPE_UINT128;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   964
+	} else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   965
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   966
+		if (typenum == FFI_TYPE_LONGDOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   967
+			typenum = FFI_TYPE_STRUCT;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   968
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   969
+	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   970
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   971
+	switch (typenum) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   972
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   973
 	  case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   974
-	    /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   975
-	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   976
-	      goto soft_float_cif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   977
 	    fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   978
 	    /* floating singles are not 8-aligned on stack */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   979
 	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   980
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   981
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   982
 	  case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   983
-	    if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   984
-	      goto do_struct;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   985
-	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   986
-	      {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   987
-		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   988
-		  || intarg_count < NUM_GPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   989
-		  /* A long double in FFI_LINUX_SOFT_FLOAT can use only
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   990
-		     a set of four consecutive gprs. If we have not enough,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   991
-		     we have to adjust the intarg_count value.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   992
-		  intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   993
-		intarg_count += 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   994
-		break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   995
-	      }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   996
-	    else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   997
-	      fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   998
+	    fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
   999
 	    /* Fall thru */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1000
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1001
 	  case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1002
-	    /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1003
-	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1004
-	      goto soft_double_cif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1005
 	    fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1006
 	    /* If this FP arg is going on the stack, it must be
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1007
 	       8-byte-aligned.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1008
 	    if (fparg_count > NUM_FPR_ARG_REGISTERS
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1009
 		&& intarg_count >= NUM_GPR_ARG_REGISTERS
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1010
 		&& intarg_count % 2 != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1011
 	      intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1012
 	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1013
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1014
+	  case FFI_TYPE_UINT128:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1015
+		/*
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1016
+		 * A long double in FFI_LINUX_SOFT_FLOAT can use only a set
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1017
+		 * of four consecutive gprs. If we do not have enough, we
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1018
+		 * have to adjust the intarg_count value.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1019
+		 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1020
+		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1021
+				&& intarg_count < NUM_GPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1022
+			intarg_count = NUM_GPR_ARG_REGISTERS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1023
+		intarg_count += 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1024
+		break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1025
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1026
 	  case FFI_TYPE_UINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1027
 	  case FFI_TYPE_SINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1028
-	  soft_double_cif:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1029
 	    /* 'long long' arguments are passed as two words, but
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1030
 	       either both words must fit in registers or both go
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1031
 	       on the stack.  If they go on the stack, they must
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1032
 	       be 8-byte-aligned.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1033
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1034
 	       Also, only certain register pairs can be used for
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1035
 	       passing long long int -- specifically (r3,r4), (r5,r6),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1036
 	       (r7,r8), (r9,r10).
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1037
 	    */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1038
 	    if (intarg_count == NUM_GPR_ARG_REGISTERS-1
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1039
 		|| intarg_count % 2 != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1040
 	      intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1041
 	    intarg_count += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1042
 	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1043
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1044
 	  case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1045
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1046
-	  do_struct:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1047
-#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1048
 	    /* We must allocate space for a copy of these to enforce
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1049
 	       pass-by-value.  Pad the space up to a multiple of 16
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1050
 	       bytes (the maximum alignment required for anything under
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1051
 	       the SYSV ABI).  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1052
 	    struct_copy_size += ((*ptr)->size + 15) & ~0xF;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1053
 	    /* Fall through (allocate space for the pointer).  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1054
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1055
-	  default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1056
-	  soft_float_cif:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1057
+	  case FFI_TYPE_POINTER:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1058
+	  case FFI_TYPE_INT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1059
+	  case FFI_TYPE_UINT32:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1060
+	  case FFI_TYPE_SINT32:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1061
+	  case FFI_TYPE_UINT16:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1062
+	  case FFI_TYPE_SINT16:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1063
+	  case FFI_TYPE_UINT8:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1064
+	  case FFI_TYPE_SINT8:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1065
 	    /* Everything else is passed as a 4-byte word in a GPR, either
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1066
 	       the object itself or a pointer to it.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1067
 	    intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1068
 	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1069
+	  default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1070
+		FFI_ASSERT (0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1071
 	  }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1072
       }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1073
   else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1074
     for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1075
       {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1076
+	unsigned int elt, elnum;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1077
+#ifdef __STRUCT_PARM_ALIGN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1078
+	unsigned int align;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1079
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1080
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1081
 	switch ((*ptr)->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1082
 	  {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1083
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1084
 	  case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1085
-	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1086
-	      intarg_count += 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1087
-	    else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1088
-	      {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1089
-		fparg_count += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1090
-		intarg_count += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1091
-	      }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1092
+	    fparg_count += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1093
+	    intarg_count += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1094
+	    if (fparg_count > NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1095
+	      flags |= FLAG_ARG_NEEDS_PSAVE;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1096
 	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1097
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1098
 	  case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1099
 	  case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1100
 	    fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1101
 	    intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1102
+	    if (fparg_count > NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1103
+	      flags |= FLAG_ARG_NEEDS_PSAVE;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1104
 	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1105
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1106
 	  case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1107
+#ifdef __STRUCT_PARM_ALIGN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1108
+	    align = (*ptr)->alignment;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1109
+	    if (align > __STRUCT_PARM_ALIGN__)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1110
+	      align = __STRUCT_PARM_ALIGN__;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1111
+	    align = align / 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1112
+	    if (align > 1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1113
+	      intarg_count = ALIGN (intarg_count, align);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1114
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1115
 	    intarg_count += ((*ptr)->size + 7) / 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1116
+	    elt = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1117
+#if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1118
+	    elt = discover_homogeneous_aggregate (*ptr, &elnum);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1119
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1120
+	    if (elt)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1121
+	      {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1122
+		fparg_count += elnum;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1123
+		if (fparg_count > NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1124
+		  flags |= FLAG_ARG_NEEDS_PSAVE;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1125
+	      }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1126
+	    else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1127
+	      {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1128
+		if (intarg_count > NUM_GPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1129
+		  flags |= FLAG_ARG_NEEDS_PSAVE;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1130
+	      }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1131
 	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1132
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1133
-	  default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1134
+	  case FFI_TYPE_POINTER:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1135
+	  case FFI_TYPE_UINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1136
+	  case FFI_TYPE_SINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1137
+	  case FFI_TYPE_INT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1138
+	  case FFI_TYPE_UINT32:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1139
+	  case FFI_TYPE_SINT32:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1140
+	  case FFI_TYPE_UINT16:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1141
+	  case FFI_TYPE_SINT16:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1142
+	  case FFI_TYPE_UINT8:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1143
+	  case FFI_TYPE_SINT8:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1144
 	    /* Everything else is passed as a 8-byte word in a GPR, either
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1145
 	       the object itself or a pointer to it.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1146
 	    intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1147
+	    if (intarg_count > NUM_GPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1148
+	      flags |= FLAG_ARG_NEEDS_PSAVE;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1149
 	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1150
+	  default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1151
+	    FFI_ASSERT (0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1152
 	  }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1153
       }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1154
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1155
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1156
   if (fparg_count != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1157
     flags |= FLAG_FP_ARGUMENTS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1158
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1159
   if (intarg_count > 4)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1160
     flags |= FLAG_4_GPR_ARGUMENTS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1161
   if (struct_copy_size != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1162
     flags |= FLAG_ARG_NEEDS_COPY;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1163
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1164
   if (cif->abi != FFI_LINUX64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1165
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1166
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1167
       /* Space for the FPR registers, if needed.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1168
       if (fparg_count != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1169
 	bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1170
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1171
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1172
       /* Stack space.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1173
       if (intarg_count > NUM_GPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1174
 	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1175
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1176
       if (fparg_count > NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1177
 	bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1178
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1179
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1180
   else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1181
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1182
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1183
       /* Space for the FPR registers, if needed.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1184
       if (fparg_count != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1185
 	bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1186
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1187
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1188
       /* Stack space.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1189
+#if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1190
+      if ((flags & FLAG_ARG_NEEDS_PSAVE) != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1191
+	bytes += intarg_count * sizeof (long);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1192
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1193
       if (intarg_count > NUM_GPR_ARG_REGISTERS64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1194
 	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1195
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1196
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1197
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1198
   /* The stack space allocated needs to be a multiple of 16 bytes.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1199
   bytes = (bytes + 15) & ~0xF;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1200
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1201
   /* Add in the space for the copied structures.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1202
   bytes += struct_copy_size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1203
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1204
   cif->flags = flags;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1205
   cif->bytes = bytes;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1206
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1207
   return FFI_OK;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1208
 }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1209
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1210
+ffi_status
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1211
+ffi_prep_cif_machdep (ffi_cif *cif)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1212
+{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1213
+  cif->nfixedargs = cif->nargs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1214
+  return ffi_prep_cif_machdep_core (cif);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1215
+}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1216
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1217
+ffi_status
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1218
+ffi_prep_cif_machdep_var (ffi_cif *cif,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1219
+			  unsigned int nfixedargs,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1220
+			  unsigned int ntotalargs MAYBE_UNUSED)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1221
+{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1222
+  cif->nfixedargs = nfixedargs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1223
+#if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1224
+  if (cif->abi == FFI_LINUX64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1225
+    cif->flags |= FLAG_ARG_NEEDS_PSAVE;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1226
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1227
+  return ffi_prep_cif_machdep_core (cif);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1228
+}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1229
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1230
 extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1231
 			  void (*fn)(void));
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1232
 extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1233
 					unsigned long, unsigned long *,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1234
 					void (*fn)(void));
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1235
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1236
 void
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1237
 ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1238
 {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1239
+  /*
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1240
+   * The final SYSV ABI says that structures smaller or equal 8 bytes
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1241
+   * are returned in r3/r4.  The FFI_GCC_SYSV ABI instead returns them
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1242
+   * in memory.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1243
+   *
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1244
+   * We bounce-buffer SYSV small struct return values so that sysv.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1245
+   * can write r3 and r4 to memory without worrying about struct size.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1246
+   *
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1247
+   * For ELFv2 ABI, use a bounce buffer for homogeneous structs too,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1248
+   * for similar reasons.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1249
+   */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1250
+  unsigned long smst_buffer[8];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1251
   extended_cif ecif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1252
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1253
   ecif.cif = cif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1254
   ecif.avalue = avalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1255
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1256
-  /* If the return value is a struct and we don't have a return	*/
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1257
-  /* value address then we need to make one		        */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1258
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1259
-  if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1260
-    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1261
-      ecif.rvalue = alloca(cif->rtype->size);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1262
-    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1263
-  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1264
-    ecif.rvalue = rvalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1265
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1266
+  ecif.rvalue = rvalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1267
+  if ((cif->flags & FLAG_RETURNS_SMST) != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1268
+    ecif.rvalue = smst_buffer;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1269
+  /* Ensure that we have a valid struct return value.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1270
+     FIXME: Isn't this just papering over a user problem?  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1271
+  else if (!rvalue && cif->rtype->type == FFI_TYPE_STRUCT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1272
+    ecif.rvalue = alloca (cif->rtype->size);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1273
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1274
   switch (cif->abi)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1275
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1276
 #ifndef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1277
+# ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1278
     case FFI_SYSV:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1279
     case FFI_GCC_SYSV:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1280
     case FFI_LINUX:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1281
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1282
     case FFI_LINUX_SOFT_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1283
       ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1284
       break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1285
 #else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1286
     case FFI_LINUX64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1287
       ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1288
       break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1289
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1290
     default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1291
       FFI_ASSERT (0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1292
       break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1293
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1294
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1295
+  /* Check for a bounce-buffered return value */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1296
+  if (rvalue && ecif.rvalue == smst_buffer)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1297
+    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1298
+      unsigned int rsize = cif->rtype->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1299
+#ifndef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1300
+      /* The SYSV ABI returns a structure of up to 4 bytes in size
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1301
+	 left-padded in r3.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1302
+      if (cif->abi == FFI_SYSV && rsize <= 4)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1303
+	memcpy (rvalue, (char *) smst_buffer + 4 - rsize, rsize);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1304
+      /* The SYSV ABI returns a structure of up to 8 bytes in size
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1305
+	 left-padded in r3/r4, and the ELFv2 ABI similarly returns a
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1306
+	 structure of up to 8 bytes in size left-padded in r3.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1307
+      else if (rsize <= 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1308
+	memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1309
+      else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1310
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1311
+	memcpy (rvalue, smst_buffer, rsize);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1312
+    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1313
 }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1314
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1315
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1316
-#ifndef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1317
+#if !defined POWERPC64 || _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1318
 #define MIN_CACHE_LINE_SIZE 8
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1319
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1320
 static void
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1321
 flush_icache (char *wraddr, char *xaddr, int size)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1322
 {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1323
   int i;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1324
   for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1325
     __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;"
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1326
@@ -942,26 +1208,48 @@ flush_icache (char *wraddr, char *xaddr,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1327
 ffi_status
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1328
 ffi_prep_closure_loc (ffi_closure *closure,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1329
 		      ffi_cif *cif,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1330
 		      void (*fun) (ffi_cif *, void *, void **, void *),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1331
 		      void *user_data,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1332
 		      void *codeloc)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1333
 {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1334
 #ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1335
+# if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1336
+  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1337
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1338
+  if (cif->abi != FFI_LINUX64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1339
+    return FFI_BAD_ABI;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1340
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1341
+  tramp[0] = 0xe96c0018;	/* 0:	ld	11,2f-0b(12)	*/
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1342
+  tramp[1] = 0xe98c0010;	/*	ld	12,1f-0b(12)	*/
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1343
+  tramp[2] = 0x7d8903a6;	/*	mtctr	12		*/
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1344
+  tramp[3] = 0x4e800420;	/*	bctr			*/
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1345
+				/* 1:	.quad	function_addr	*/
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1346
+				/* 2:	.quad	context		*/
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1347
+  *(void **) &tramp[4] = (void *) ffi_closure_LINUX64;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1348
+  *(void **) &tramp[6] = codeloc;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1349
+  flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1350
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1351
   void **tramp = (void **) &closure->tramp[0];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1352
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1353
-  FFI_ASSERT (cif->abi == FFI_LINUX64);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1354
+  if (cif->abi != FFI_LINUX64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1355
+    return FFI_BAD_ABI;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1356
   /* Copy function address and TOC from ffi_closure_LINUX64.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1357
   memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1358
   tramp[2] = codeloc;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1359
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1360
 #else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1361
   unsigned int *tramp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1362
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1363
-  FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1364
+  if (! (cif->abi == FFI_GCC_SYSV 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1365
+	 || cif->abi == FFI_SYSV
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1366
+	 || cif->abi == FFI_LINUX
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1367
+	 || cif->abi == FFI_LINUX_SOFT_FLOAT))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1368
+    return FFI_BAD_ABI;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1369
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1370
   tramp = (unsigned int *) &closure->tramp[0];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1371
   tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1372
   tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1373
   tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1374
   tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1375
   tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1376
   tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1377
@@ -1006,110 +1294,215 @@ ffi_closure_helper_SYSV (ffi_closure *cl
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1378
   /* rvalue is the pointer to space for return value in closure assembly */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1379
   /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1380
   /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1381
   /* pst is the pointer to outgoing parameter stack in original caller */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1382
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1383
   void **          avalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1384
   ffi_type **      arg_types;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1385
   long             i, avn;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1386
-  long             nf;   /* number of floating registers already used */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1387
-  long             ng;   /* number of general registers already used */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1388
-  ffi_cif *        cif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1389
-  double           temp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1390
-  unsigned         size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1391
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1392
+  long             nf = 0;   /* number of floating registers already used */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1393
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1394
+  long             ng = 0;   /* number of general registers already used */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1395
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1396
-  cif = closure->cif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1397
+  ffi_cif *cif = closure->cif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1398
+  unsigned       size     = cif->rtype->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1399
+  unsigned short rtypenum = cif->rtype->type;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1400
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1401
   avalue = alloca (cif->nargs * sizeof (void *));
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1402
-  size = cif->rtype->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1403
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1404
-  nf = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1405
-  ng = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1406
+  /* First translate for softfloat/nonlinux */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1407
+  if (cif->abi == FFI_LINUX_SOFT_FLOAT) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1408
+	if (rtypenum == FFI_TYPE_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1409
+		rtypenum = FFI_TYPE_UINT32;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1410
+	if (rtypenum == FFI_TYPE_DOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1411
+		rtypenum = FFI_TYPE_UINT64;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1412
+	if (rtypenum == FFI_TYPE_LONGDOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1413
+		rtypenum = FFI_TYPE_UINT128;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1414
+  } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1415
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1416
+	if (rtypenum == FFI_TYPE_LONGDOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1417
+		rtypenum = FFI_TYPE_STRUCT;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1418
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1419
+  }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1420
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1421
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1422
   /* Copy the caller's structure return value address so that the closure
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1423
      returns the data directly to the caller.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1424
      For FFI_SYSV the result is passed in r3/r4 if the struct size is less
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1425
      or equal 8 bytes.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1426
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1427
-  if ((cif->rtype->type == FFI_TYPE_STRUCT
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1428
-       && !((cif->abi == FFI_SYSV) && (size <= 8)))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1429
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1430
-      || (cif->rtype->type == FFI_TYPE_LONGDOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1431
-	  && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1432
-#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1433
-      )
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1434
-    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1435
+  if (rtypenum == FFI_TYPE_STRUCT && ((cif->abi != FFI_SYSV) || (size > 8))) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1436
       rvalue = (void *) *pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1437
       ng++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1438
       pgr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1439
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1440
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1441
   i = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1442
   avn = cif->nargs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1443
   arg_types = cif->arg_types;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1444
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1445
   /* Grab the addresses of the arguments from the stack frame.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1446
-  while (i < avn)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1447
-    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1448
-      switch (arg_types[i]->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1449
-	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1450
+  while (i < avn) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1451
+      unsigned short typenum = arg_types[i]->type;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1452
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1453
+      /* We may need to handle some values depending on ABI */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1454
+      if (cif->abi == FFI_LINUX_SOFT_FLOAT) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1455
+		if (typenum == FFI_TYPE_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1456
+			typenum = FFI_TYPE_UINT32;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1457
+		if (typenum == FFI_TYPE_DOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1458
+			typenum = FFI_TYPE_UINT64;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1459
+		if (typenum == FFI_TYPE_LONGDOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1460
+			typenum = FFI_TYPE_UINT128;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1461
+      } else if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1462
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1463
+		if (typenum == FFI_TYPE_LONGDOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1464
+			typenum = FFI_TYPE_STRUCT;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1465
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1466
+      }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1467
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1468
+      switch (typenum) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1469
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1470
+	case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1471
+	  /* unfortunately float values are stored as doubles
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1472
+	   * in the ffi_closure_SYSV code (since we don't check
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1473
+	   * the type in that routine).
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1474
+	   */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1475
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1476
+	  /* there are 8 64bit floating point registers */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1477
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1478
+	  if (nf < 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1479
+	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1480
+	      double temp = pfr->d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1481
+	      pfr->f = (float) temp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1482
+	      avalue[i] = pfr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1483
+	      nf++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1484
+	      pfr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1485
+	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1486
+	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1487
+	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1488
+	      /* FIXME? here we are really changing the values
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1489
+	       * stored in the original calling routines outgoing
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1490
+	       * parameter stack.  This is probably a really
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1491
+	       * naughty thing to do but...
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1492
+	       */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1493
+	      avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1494
+	      pst += 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1495
+	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1496
+	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1497
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1498
+	case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1499
+	  /* On the outgoing stack all values are aligned to 8 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1500
+	  /* there are 8 64bit floating point registers */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1501
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1502
+	  if (nf < 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1503
+	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1504
+	      avalue[i] = pfr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1505
+	      nf++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1506
+	      pfr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1507
+	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1508
+	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1509
+	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1510
+	      if (((long) pst) & 4)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1511
+		pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1512
+	      avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1513
+	      pst += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1514
+	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1515
+	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1516
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1517
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1518
+	case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1519
+	  if (nf < 7)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1520
+	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1521
+	      avalue[i] = pfr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1522
+	      pfr += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1523
+	      nf += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1524
+	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1525
+	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1526
+	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1527
+	      if (((long) pst) & 4)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1528
+		pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1529
+	      avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1530
+	      pst += 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1531
+	      nf = 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1532
+	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1533
+	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1534
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1535
+#endif /* have FPRS */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1536
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1537
+	case FFI_TYPE_UINT128:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1538
+		/*
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1539
+		 * Test if for the whole long double, 4 gprs are available.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1540
+		 * otherwise the stuff ends up on the stack.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1541
+		 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1542
+		if (ng < 5) {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1543
+			avalue[i] = pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1544
+			pgr += 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1545
+			ng += 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1546
+		} else {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1547
+			avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1548
+			pst += 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1549
+			ng = 8+4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1550
+		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1551
+		break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1552
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1553
 	case FFI_TYPE_SINT8:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1554
 	case FFI_TYPE_UINT8:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1555
+#ifndef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1556
 	  /* there are 8 gpr registers used to pass values */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1557
 	  if (ng < 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1558
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1559
 	      avalue[i] = (char *) pgr + 3;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1560
 	      ng++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1561
 	      pgr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1562
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1563
 	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1564
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1565
 	      avalue[i] = (char *) pst + 3;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1566
 	      pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1567
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1568
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1569
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1570
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1571
 	case FFI_TYPE_SINT16:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1572
 	case FFI_TYPE_UINT16:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1573
+#ifndef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1574
 	  /* there are 8 gpr registers used to pass values */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1575
 	  if (ng < 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1576
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1577
 	      avalue[i] = (char *) pgr + 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1578
 	      ng++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1579
 	      pgr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1580
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1581
 	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1582
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1583
 	      avalue[i] = (char *) pst + 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1584
 	      pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1585
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1586
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1587
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1588
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1589
 	case FFI_TYPE_SINT32:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1590
 	case FFI_TYPE_UINT32:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1591
 	case FFI_TYPE_POINTER:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1592
-	soft_float_closure:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1593
 	  /* there are 8 gpr registers used to pass values */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1594
 	  if (ng < 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1595
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1596
 	      avalue[i] = pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1597
 	      ng++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1598
 	      pgr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1599
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1600
 	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1601
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1602
 	      avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1603
 	      pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1604
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1605
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1606
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1607
 	case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1608
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1609
-	do_struct:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1610
-#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1611
 	  /* Structs are passed by reference. The address will appear in a
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1612
 	     gpr if it is one of the first 8 arguments.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1613
 	  if (ng < 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1614
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1615
 	      avalue[i] = (void *) *pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1616
 	      ng++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1617
 	      pgr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1618
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1619
@@ -1117,17 +1510,16 @@ ffi_closure_helper_SYSV (ffi_closure *cl
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1620
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1621
 	      avalue[i] = (void *) *pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1622
 	      pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1623
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1624
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1625
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1626
 	case FFI_TYPE_SINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1627
 	case FFI_TYPE_UINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1628
-	soft_double_closure:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1629
 	  /* passing long long ints are complex, they must
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1630
 	   * be passed in suitable register pairs such as
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1631
 	   * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1632
 	   * and if the entire pair aren't available then the outgoing
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1633
 	   * parameter stack is used for both but an alignment of 8
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1634
 	   * must will be kept.  So we must either look in pgr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1635
 	   * or pst to find the correct address for this type
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1636
 	   * of parameter.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1637
@@ -1149,277 +1541,239 @@ ffi_closure_helper_SYSV (ffi_closure *cl
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1638
 	      if (((long) pst) & 4)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1639
 		pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1640
 	      avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1641
 	      pst += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1642
 	      ng = 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1643
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1644
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1645
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1646
-	case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1647
-	  /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1648
-	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1649
-	    goto soft_float_closure;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1650
-	  /* unfortunately float values are stored as doubles
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1651
-	   * in the ffi_closure_SYSV code (since we don't check
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1652
-	   * the type in that routine).
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1653
-	   */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1654
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1655
-	  /* there are 8 64bit floating point registers */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1656
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1657
-	  if (nf < 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1658
-	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1659
-	      temp = pfr->d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1660
-	      pfr->f = (float) temp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1661
-	      avalue[i] = pfr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1662
-	      nf++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1663
-	      pfr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1664
-	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1665
-	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1666
-	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1667
-	      /* FIXME? here we are really changing the values
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1668
-	       * stored in the original calling routines outgoing
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1669
-	       * parameter stack.  This is probably a really
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1670
-	       * naughty thing to do but...
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1671
-	       */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1672
-	      avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1673
-	      pst += 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1674
-	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1675
-	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1676
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1677
-	case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1678
-	  /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1679
-	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1680
-	    goto soft_double_closure;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1681
-	  /* On the outgoing stack all values are aligned to 8 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1682
-	  /* there are 8 64bit floating point registers */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1683
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1684
-	  if (nf < 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1685
-	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1686
-	      avalue[i] = pfr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1687
-	      nf++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1688
-	      pfr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1689
-	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1690
-	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1691
-	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1692
-	      if (((long) pst) & 4)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1693
-		pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1694
-	      avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1695
-	      pst += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1696
-	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1697
-	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1698
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1699
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1700
-	case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1701
-	  if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1702
-	    goto do_struct;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1703
-	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1704
-	    { /* Test if for the whole long double, 4 gprs are available.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1705
-		 otherwise the stuff ends up on the stack.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1706
-	      if (ng < 5)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1707
-		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1708
-		  avalue[i] = pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1709
-		  pgr += 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1710
-		  ng += 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1711
-		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1712
-	      else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1713
-		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1714
-		  avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1715
-		  pst += 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1716
-		  ng = 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1717
-		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1718
-	      break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1719
-	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1720
-	  if (nf < 7)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1721
-	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1722
-	      avalue[i] = pfr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1723
-	      pfr += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1724
-	      nf += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1725
-	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1726
-	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1727
-	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1728
-	      if (((long) pst) & 4)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1729
-		pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1730
-	      avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1731
-	      pst += 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1732
-	      nf = 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1733
-	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1734
-	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1735
-#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1736
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1737
 	default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1738
-	  FFI_ASSERT (0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1739
+		FFI_ASSERT (0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1740
 	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1741
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1742
       i++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1743
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1744
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1745
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1746
   (closure->fun) (cif, rvalue, avalue, closure->user_data);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1747
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1748
   /* Tell ffi_closure_SYSV how to perform return type promotions.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1749
      Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1750
      we have to tell ffi_closure_SYSV how to treat them. We combine the base
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1751
      type FFI_SYSV_TYPE_SMALL_STRUCT - 1  with the size of the struct.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1752
      So a one byte struct gets the return type 16. Return type 1 to 15 are
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1753
      already used and we never have a struct with size zero. That is the reason
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1754
      for the subtraction of 1. See the comment in ffitarget.h about ordering.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1755
   */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1756
-  if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1757
-      && size <= 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1758
+  if (cif->abi == FFI_SYSV && rtypenum == FFI_TYPE_STRUCT && size <= 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1759
     return (FFI_SYSV_TYPE_SMALL_STRUCT - 1) + size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1760
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1761
-  else if (cif->rtype->type == FFI_TYPE_LONGDOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1762
-	   && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1763
-    return FFI_TYPE_STRUCT;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1764
-#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1765
-  /* With FFI_LINUX_SOFT_FLOAT floats and doubles are handled like UINT32
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1766
-     respectivley UINT64.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1767
-  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1768
-    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1769
-      switch (cif->rtype->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1770
-	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1771
-	case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1772
-	  return FFI_TYPE_UINT32;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1773
-	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1774
-	case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1775
-	  return FFI_TYPE_UINT64;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1776
-	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1777
-#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1778
-	case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1779
-	  return FFI_TYPE_UINT128;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1780
-	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1781
-#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1782
-	default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1783
-	  return cif->rtype->type;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1784
-	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1785
-    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1786
-  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1787
-    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1788
-      return cif->rtype->type;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1789
-    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1790
+  return rtypenum;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1791
 }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1792
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1793
 int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1794
 					   unsigned long *, ffi_dblfl *);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1795
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1796
 int FFI_HIDDEN
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1797
 ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1798
 			    unsigned long *pst, ffi_dblfl *pfr)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1799
 {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1800
   /* rvalue is the pointer to space for return value in closure assembly */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1801
   /* pst is the pointer to parameter save area
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1802
      (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1803
   /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1804
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1805
   void **avalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1806
   ffi_type **arg_types;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1807
-  long i, avn;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1808
+  unsigned long i, avn, nfixedargs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1809
   ffi_cif *cif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1810
   ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1811
+#ifdef __STRUCT_PARM_ALIGN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1812
+  unsigned long align;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1813
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1814
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1815
   cif = closure->cif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1816
   avalue = alloca (cif->nargs * sizeof (void *));
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1817
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1818
-  /* Copy the caller's structure return value address so that the closure
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1819
-     returns the data directly to the caller.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1820
-  if (cif->rtype->type == FFI_TYPE_STRUCT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1821
+  /* Copy the caller's structure return value address so that the
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1822
+     closure returns the data directly to the caller.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1823
+  if (cif->rtype->type == FFI_TYPE_STRUCT
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1824
+      && (cif->flags & FLAG_RETURNS_SMST) == 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1825
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1826
       rvalue = (void *) *pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1827
       pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1828
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1829
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1830
   i = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1831
   avn = cif->nargs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1832
+  nfixedargs = cif->nfixedargs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1833
   arg_types = cif->arg_types;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1834
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1835
   /* Grab the addresses of the arguments from the stack frame.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1836
   while (i < avn)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1837
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1838
+      unsigned int elt, elnum;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1839
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1840
       switch (arg_types[i]->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1841
 	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1842
 	case FFI_TYPE_SINT8:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1843
 	case FFI_TYPE_UINT8:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1844
+#ifndef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1845
 	  avalue[i] = (char *) pst + 7;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1846
 	  pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1847
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1848
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1849
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1850
 	case FFI_TYPE_SINT16:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1851
 	case FFI_TYPE_UINT16:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1852
+#ifndef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1853
 	  avalue[i] = (char *) pst + 6;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1854
 	  pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1855
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1856
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1857
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1858
 	case FFI_TYPE_SINT32:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1859
 	case FFI_TYPE_UINT32:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1860
+#ifndef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1861
 	  avalue[i] = (char *) pst + 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1862
 	  pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1863
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1864
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1865
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1866
 	case FFI_TYPE_SINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1867
 	case FFI_TYPE_UINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1868
 	case FFI_TYPE_POINTER:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1869
 	  avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1870
 	  pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1871
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1872
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1873
 	case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1874
-	  /* Structures with size less than eight bytes are passed
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1875
-	     left-padded.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1876
-	  if (arg_types[i]->size < 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1877
-	    avalue[i] = (char *) pst + 8 - arg_types[i]->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1878
+#ifdef __STRUCT_PARM_ALIGN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1879
+	  align = arg_types[i]->alignment;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1880
+	  if (align > __STRUCT_PARM_ALIGN__)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1881
+	    align = __STRUCT_PARM_ALIGN__;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1882
+	  if (align > 1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1883
+	    pst = (unsigned long *) ALIGN ((size_t) pst, align);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1884
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1885
+	  elt = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1886
+#if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1887
+	  elt = discover_homogeneous_aggregate (arg_types[i], &elnum);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1888
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1889
+	  if (elt)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1890
+	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1891
+	      union {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1892
+		void *v;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1893
+		unsigned long *ul;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1894
+		float *f;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1895
+		double *d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1896
+		size_t p;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1897
+	      } to, from;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1898
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1899
+	      /* Repackage the aggregate from its parts.  The
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1900
+		 aggregate size is not greater than the space taken by
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1901
+		 the registers so store back to the register/parameter
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1902
+		 save arrays.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1903
+	      if (pfr + elnum <= end_pfr)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1904
+		to.v = pfr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1905
+	      else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1906
+		to.v = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1907
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1908
+	      avalue[i] = to.v;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1909
+	      from.ul = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1910
+	      if (elt == FFI_TYPE_FLOAT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1911
+		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1912
+		  do
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1913
+		    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1914
+		      if (pfr < end_pfr && i < nfixedargs)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1915
+			{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1916
+			  *to.f = (float) pfr->d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1917
+			  pfr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1918
+			}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1919
+		      else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1920
+			*to.f = *from.f;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1921
+		      to.f++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1922
+		      from.f++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1923
+		    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1924
+		  while (--elnum != 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1925
+		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1926
+	      else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1927
+		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1928
+		  do
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1929
+		    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1930
+		      if (pfr < end_pfr && i < nfixedargs)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1931
+			{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1932
+			  *to.d = pfr->d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1933
+			  pfr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1934
+			}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1935
+		      else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1936
+			*to.d = *from.d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1937
+		      to.d++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1938
+		      from.d++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1939
+		    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1940
+		  while (--elnum != 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1941
+		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1942
+	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1943
 	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1944
-	    avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1945
+	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1946
+#ifndef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1947
+	      /* Structures with size less than eight bytes are passed
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1948
+		 left-padded.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1949
+	      if (arg_types[i]->size < 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1950
+		avalue[i] = (char *) pst + 8 - arg_types[i]->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1951
+	      else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1952
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1953
+		avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1954
+	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1955
 	  pst += (arg_types[i]->size + 7) / 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1956
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1957
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1958
 	case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1959
 	  /* unfortunately float values are stored as doubles
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1960
 	   * in the ffi_closure_LINUX64 code (since we don't check
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1961
 	   * the type in that routine).
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1962
 	   */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1963
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1964
 	  /* there are 13 64bit floating point registers */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1965
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1966
-	  if (pfr < end_pfr)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1967
+	  if (pfr < end_pfr && i < nfixedargs)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1968
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1969
 	      double temp = pfr->d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1970
 	      pfr->f = (float) temp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1971
 	      avalue[i] = pfr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1972
 	      pfr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1973
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1974
 	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1975
 	    avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1976
 	  pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1977
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1978
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1979
 	case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1980
 	  /* On the outgoing stack all values are aligned to 8 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1981
 	  /* there are 13 64bit floating point registers */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1982
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1983
-	  if (pfr < end_pfr)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1984
+	  if (pfr < end_pfr && i < nfixedargs)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1985
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1986
 	      avalue[i] = pfr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1987
 	      pfr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1988
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1989
 	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1990
 	    avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1991
 	  pst++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1992
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1993
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1994
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1995
 	case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1996
-	  if (pfr + 1 < end_pfr)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1997
+	  if (pfr + 1 < end_pfr && i + 1 < nfixedargs)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1998
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  1999
 	      avalue[i] = pfr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2000
 	      pfr += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2001
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2002
 	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2003
 	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2004
-	      if (pfr < end_pfr)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2005
+	      if (pfr < end_pfr && i < nfixedargs)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2006
 		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2007
 		  /* Passed partly in f13 and partly on the stack.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2008
 		     Move it all to the stack.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2009
 		  *pst = *(unsigned long *) pfr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2010
 		  pfr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2011
 		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2012
 	      avalue[i] = pst;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2013
 	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2014
@@ -1433,10 +1787,19 @@ ffi_closure_helper_LINUX64 (ffi_closure 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2015
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2016
       i++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2017
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2018
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2019
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2020
   (closure->fun) (cif, rvalue, avalue, closure->user_data);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2021
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2022
   /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2023
+  if ((cif->flags & FLAG_RETURNS_SMST) != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2024
+    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2025
+      if ((cif->flags & FLAG_RETURNS_FP) == 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2026
+	return FFI_V2_TYPE_SMALL_STRUCT + cif->rtype->size - 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2027
+      else if ((cif->flags & FLAG_RETURNS_64BITS) != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2028
+	return FFI_V2_TYPE_DOUBLE_HOMOG;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2029
+      else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2030
+	return FFI_V2_TYPE_FLOAT_HOMOG;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2031
+    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2032
   return cif->rtype->type;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2033
 }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2034
diff --git a/js/src/ctypes/libffi/src/powerpc/ffi_darwin.c b/js/src/ctypes/libffi/src/powerpc/ffi_darwin.c
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2035
--- a/js/src/ctypes/libffi/src/powerpc/ffi_darwin.c
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2036
+++ b/js/src/ctypes/libffi/src/powerpc/ffi_darwin.c
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2037
@@ -1,14 +1,14 @@
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2038
 /* -----------------------------------------------------------------------
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2039
    ffi_darwin.c
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2040
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2041
    Copyright (C) 1998 Geoffrey Keating
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2042
    Copyright (C) 2001 John Hornkvist
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2043
-   Copyright (C) 2002, 2006, 2007, 2009 Free Software Foundation, Inc.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2044
+   Copyright (C) 2002, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2045
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2046
    FFI support for Darwin and AIX.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2047
    
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2048
    Permission is hereby granted, free of charge, to any person obtaining
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2049
    a copy of this software and associated documentation files (the
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2050
    ``Software''), to deal in the Software without restriction, including
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2051
    without limitation the rights to use, copy, modify, merge, publish,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2052
    distribute, sublicense, and/or sell copies of the Software, and to
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2053
@@ -30,87 +30,112 @@
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2054
 #include <ffi.h>
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2055
 #include <ffi_common.h>
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2056
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2057
 #include <stdlib.h>
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2058
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2059
 extern void ffi_closure_ASM (void);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2060
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2061
 enum {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2062
-  /* The assembly depends on these exact flags.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2063
-  FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2064
-  FLAG_RETURNS_FP       = 1 << (31-29),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2065
-  FLAG_RETURNS_64BITS   = 1 << (31-28),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2066
-  FLAG_RETURNS_128BITS  = 1 << (31-31),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2067
+  /* The assembly depends on these exact flags.  
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2068
+     For Darwin64 (when FLAG_RETURNS_STRUCT is set):
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2069
+       FLAG_RETURNS_FP indicates that the structure embeds FP data.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2070
+       FLAG_RETURNS_128BITS signals a special struct size that is not
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2071
+       expanded for float content.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2072
+  FLAG_RETURNS_128BITS	= 1 << (31-31), /* These go in cr7  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2073
+  FLAG_RETURNS_NOTHING	= 1 << (31-30),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2074
+  FLAG_RETURNS_FP	= 1 << (31-29),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2075
+  FLAG_RETURNS_64BITS	= 1 << (31-28),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2076
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2077
+  FLAG_RETURNS_STRUCT	= 1 << (31-27), /* This goes in cr6  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2078
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2079
   FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2080
   FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2081
   FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2082
   FLAG_RETVAL_REFERENCE = 1 << (31- 4)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2083
 };
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2084
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2085
 /* About the DARWIN ABI.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2086
 enum {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2087
   NUM_GPR_ARG_REGISTERS = 8,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2088
-  NUM_FPR_ARG_REGISTERS = 13
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2089
+  NUM_FPR_ARG_REGISTERS = 13,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2090
+  LINKAGE_AREA_GPRS = 6
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2091
 };
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2092
-enum { ASM_NEEDS_REGISTERS = 4 };
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2093
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2094
+enum { ASM_NEEDS_REGISTERS = 4 }; /* r28-r31 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2095
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2096
 /* ffi_prep_args is called by the assembly routine once stack space
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2097
    has been allocated for the function's arguments.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2098
+   
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2099
+   m32/m64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2100
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2101
    The stack layout we want looks like this:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2102
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2103
    |   Return address from ffi_call_DARWIN      |	higher addresses
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2104
    |--------------------------------------------|
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2105
-   |   Previous backchain pointer	4	|	stack pointer here
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2106
+   |   Previous backchain pointer	4/8	|	stack pointer here
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2107
    |--------------------------------------------|<+ <<<	on entry to
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2108
-   |   Saved r28-r31			4*4	| |	ffi_call_DARWIN
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2109
+   |   ASM_NEEDS_REGISTERS=r28-r31   4*(4/8)	| |	ffi_call_DARWIN
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2110
    |--------------------------------------------| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2111
-   |   Parameters             (at least 8*4=32) | |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2112
+   |   When we have any FP activity... the	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2113
+   |   FPRs occupy NUM_FPR_ARG_REGISTERS slots	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2114
+   |   here fp13 .. fp1 from high to low addr.	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2115
+   ~						~ ~
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2116
+   |   Parameters      (at least 8*4/8=32/64)	| | NUM_GPR_ARG_REGISTERS
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2117
    |--------------------------------------------| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2118
-   |   Space for GPR2                   4       | |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2119
+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2120
    |--------------------------------------------| |	stack	|
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2121
-   |   Reserved                       2*4       | |	grows	|
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2122
+   |   Reserved                       2*4/8	| |	grows	|
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2123
    |--------------------------------------------| |	down	V
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2124
-   |   Space for callee's LR		4	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2125
+   |   Space for callee's LR		4/8	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2126
    |--------------------------------------------| |	lower addresses
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2127
-   |   Saved CR                         4       | |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2128
+   |   Saved CR [low word for m64]      4/8	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2129
    |--------------------------------------------| |     stack pointer here
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2130
-   |   Current backchain pointer	4	|-/	during
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2131
+   |   Current backchain pointer	4/8	|-/	during
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2132
    |--------------------------------------------|   <<<	ffi_call_DARWIN
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2133
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2134
    */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2135
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2136
+#if defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2137
+static void
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2138
+darwin64_pass_struct_by_value 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2139
+  (ffi_type *, char *, unsigned, unsigned *, double **, unsigned long **);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2140
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2141
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2142
+/* This depends on GPR_SIZE = sizeof (unsigned long) */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2143
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2144
 void
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2145
 ffi_prep_args (extended_cif *ecif, unsigned long *const stack)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2146
 {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2147
   const unsigned bytes = ecif->cif->bytes;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2148
   const unsigned flags = ecif->cif->flags;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2149
   const unsigned nargs = ecif->cif->nargs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2150
+#if !defined(POWERPC_DARWIN64) 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2151
   const ffi_abi abi = ecif->cif->abi;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2152
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2153
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2154
   /* 'stacktop' points at the previous backchain pointer.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2155
   unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long));
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2156
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2157
   /* 'fpr_base' points at the space for fpr1, and grows upwards as
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2158
      we use FPR registers.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2159
   double *fpr_base = (double *) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2160
-  int fparg_count = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2161
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2162
+  int gp_count = 0, fparg_count = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2163
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2164
   /* 'next_arg' grows up as we put parameters in it.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2165
-  unsigned long *next_arg = stack + 6; /* 6 reserved positions.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2166
+  unsigned long *next_arg = stack + LINKAGE_AREA_GPRS; /* 6 reserved positions.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2167
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2168
   int i;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2169
   double double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2170
   void **p_argv = ecif->avalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2171
   unsigned long gprvalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2172
   ffi_type** ptr = ecif->cif->arg_types;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2173
+#if !defined(POWERPC_DARWIN64) 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2174
   char *dest_cpy;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2175
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2176
   unsigned size_al = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2177
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2178
   /* Check that everything starts aligned properly.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2179
   FFI_ASSERT(((unsigned) (char *) stack & 0xF) == 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2180
   FFI_ASSERT(((unsigned) (char *) stacktop & 0xF) == 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2181
   FFI_ASSERT((bytes & 0xF) == 0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2182
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2183
   /* Deal with return values that are actually pass-by-reference.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2184
@@ -125,78 +150,95 @@ ffi_prep_args (extended_cif *ecif, unsig
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2185
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2186
       switch ((*ptr)->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2187
 	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2188
 	/* If a floating-point parameter appears before all of the general-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2189
 	   purpose registers are filled, the corresponding GPRs that match
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2190
 	   the size of the floating-point parameter are skipped.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2191
 	case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2192
 	  double_tmp = *(float *) *p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2193
-	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2194
-	    *(double *)next_arg = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2195
-	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2196
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2197
 	    *fpr_base++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2198
+#if defined(POWERPC_DARWIN)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2199
+	  *(float *)next_arg = *(float *) *p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2200
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2201
+	  *(double *)next_arg = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2202
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2203
 	  next_arg++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2204
+	  gp_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2205
 	  fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2206
 	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2207
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2208
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2209
 	case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2210
 	  double_tmp = *(double *) *p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2211
-	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2212
-	    *(double *)next_arg = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2213
-	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2214
+	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2215
 	    *fpr_base++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2216
+	  *(double *)next_arg = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2217
 #ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2218
 	  next_arg++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2219
+	  gp_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2220
 #else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2221
 	  next_arg += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2222
+	  gp_count += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2223
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2224
 	  fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2225
 	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2226
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2227
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2228
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2229
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2230
 	case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2231
-#ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2232
+#  if defined(POWERPC64) && !defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2233
+	  /* ??? This will exceed the regs count when the value starts at fp13
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2234
+	     and it will not put the extra bit on the stack.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2235
 	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2236
 	    *(long double *) fpr_base++ = *(long double *) *p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2237
 	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2238
 	    *(long double *) next_arg = *(long double *) *p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2239
 	  next_arg += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2240
 	  fparg_count += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2241
-#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2242
+#  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2243
 	  double_tmp = ((double *) *p_argv)[0];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2244
 	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2245
 	    *fpr_base++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2246
-	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2247
-	    *(double *) next_arg = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2248
+	  *(double *) next_arg = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2249
+#    if defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2250
+	  next_arg++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2251
+	  gp_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2252
+#    else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2253
 	  next_arg += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2254
+	  gp_count += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2255
+#    endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2256
 	  fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2257
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2258
 	  double_tmp = ((double *) *p_argv)[1];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2259
 	  if (fparg_count < NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2260
 	    *fpr_base++ = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2261
-	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2262
-	    *(double *) next_arg = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2263
+	  *(double *) next_arg = double_tmp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2264
+#    if defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2265
+	  next_arg++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2266
+	  gp_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2267
+#    else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2268
 	  next_arg += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2269
+	  gp_count += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2270
+#    endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2271
 	  fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2272
-#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2273
+#  endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2274
 	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2275
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2276
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2277
 	case FFI_TYPE_UINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2278
 	case FFI_TYPE_SINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2279
 #ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2280
 	  gprvalue = *(long long *) *p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2281
 	  goto putgpr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2282
 #else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2283
 	  *(long long *) next_arg = *(long long *) *p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2284
 	  next_arg += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2285
+	  gp_count += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2286
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2287
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2288
 	case FFI_TYPE_POINTER:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2289
 	  gprvalue = *(unsigned long *) *p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2290
 	  goto putgpr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2291
 	case FFI_TYPE_UINT8:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2292
 	  gprvalue = *(unsigned char *) *p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2293
 	  goto putgpr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2294
@@ -206,101 +248,373 @@ ffi_prep_args (extended_cif *ecif, unsig
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2295
 	case FFI_TYPE_UINT16:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2296
 	  gprvalue = *(unsigned short *) *p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2297
 	  goto putgpr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2298
 	case FFI_TYPE_SINT16:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2299
 	  gprvalue = *(signed short *) *p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2300
 	  goto putgpr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2301
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2302
 	case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2303
-#ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2304
-	  dest_cpy = (char *) next_arg;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2305
 	  size_al = (*ptr)->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2306
-	  if ((*ptr)->elements[0]->type == 3)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2307
-	    size_al = ALIGN((*ptr)->size, 8);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2308
-	  if (size_al < 3 && abi == FFI_DARWIN)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2309
-	    dest_cpy += 4 - size_al;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2310
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2311
-	  memcpy ((char *) dest_cpy, (char *) *p_argv, size_al);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2312
-	  next_arg += (size_al + 7) / 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2313
+#if defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2314
+	  next_arg = (unsigned long *)ALIGN((char *)next_arg, (*ptr)->alignment);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2315
+	  darwin64_pass_struct_by_value (*ptr, (char *) *p_argv, 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2316
+					 (unsigned) size_al,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2317
+					 (unsigned int *) &fparg_count,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2318
+					 &fpr_base, &next_arg);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2319
 #else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2320
 	  dest_cpy = (char *) next_arg;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2321
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2322
+	  /* If the first member of the struct is a double, then include enough
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2323
+	     padding in the struct size to align it to double-word.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2324
+	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2325
+	    size_al = ALIGN((*ptr)->size, 8);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2326
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2327
+#  if defined(POWERPC64) 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2328
+	  FFI_ASSERT (abi != FFI_DARWIN);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2329
+	  memcpy ((char *) dest_cpy, (char *) *p_argv, size_al);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2330
+	  next_arg += (size_al + 7) / 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2331
+#  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2332
 	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2333
 	     SI 4 bytes) are aligned as if they were those modes.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2334
 	     Structures with 3 byte in size are padded upwards.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2335
-	  size_al = (*ptr)->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2336
-	  /* If the first member of the struct is a double, then align
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2337
-	     the struct to double-word.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2338
-	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2339
-	    size_al = ALIGN((*ptr)->size, 8);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2340
 	  if (size_al < 3 && abi == FFI_DARWIN)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2341
 	    dest_cpy += 4 - size_al;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2342
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2343
 	  memcpy((char *) dest_cpy, (char *) *p_argv, size_al);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2344
 	  next_arg += (size_al + 3) / 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2345
+#  endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2346
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2347
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2348
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2349
 	case FFI_TYPE_INT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2350
 	case FFI_TYPE_SINT32:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2351
 	  gprvalue = *(signed int *) *p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2352
 	  goto putgpr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2353
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2354
 	case FFI_TYPE_UINT32:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2355
 	  gprvalue = *(unsigned int *) *p_argv;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2356
 	putgpr:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2357
 	  *next_arg++ = gprvalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2358
+	  gp_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2359
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2360
 	default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2361
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2362
 	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2363
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2364
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2365
   /* Check that we didn't overrun the stack...  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2366
   //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2367
   //FFI_ASSERT((unsigned *)fpr_base
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2368
   //	     <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2369
   //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2370
 }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2371
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2372
+#if defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2373
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2374
+/* See if we can put some of the struct into fprs.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2375
+   This should not be called for structures of size 16 bytes, since these are not
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2376
+   broken out this way.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2377
+static void
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2378
+darwin64_scan_struct_for_floats (ffi_type *s, unsigned *nfpr)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2379
+{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2380
+  int i;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2381
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2382
+  FFI_ASSERT (s->type == FFI_TYPE_STRUCT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2383
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2384
+  for (i = 0; s->elements[i] != NULL; i++)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2385
+    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2386
+      ffi_type *p = s->elements[i];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2387
+      switch (p->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2388
+	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2389
+	  case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2390
+	    darwin64_scan_struct_for_floats (p, nfpr);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2391
+	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2392
+	  case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2393
+	    (*nfpr) += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2394
+	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2395
+	  case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2396
+	  case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2397
+	    (*nfpr) += 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2398
+	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2399
+	  default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2400
+	    break;    
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2401
+	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2402
+    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2403
+}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2404
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2405
+static int
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2406
+darwin64_struct_size_exceeds_gprs_p (ffi_type *s, char *src, unsigned *nfpr)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2407
+{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2408
+  unsigned struct_offset=0, i;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2409
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2410
+  for (i = 0; s->elements[i] != NULL; i++)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2411
+    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2412
+      char *item_base;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2413
+      ffi_type *p = s->elements[i];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2414
+      /* Find the start of this item (0 for the first one).  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2415
+      if (i > 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2416
+        struct_offset = ALIGN(struct_offset, p->alignment);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2417
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2418
+      item_base = src + struct_offset;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2419
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2420
+      switch (p->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2421
+	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2422
+	  case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2423
+	    if (darwin64_struct_size_exceeds_gprs_p (p, item_base, nfpr))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2424
+	      return 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2425
+	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2426
+	  case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2427
+	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2428
+	      return 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2429
+	    (*nfpr) += 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2430
+	    item_base += 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2431
+	  /* FALL THROUGH */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2432
+	  case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2433
+	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2434
+	      return 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2435
+	    (*nfpr) += 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2436
+	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2437
+	  case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2438
+	    if (*nfpr >= NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2439
+	      return 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2440
+	    (*nfpr) += 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2441
+	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2442
+	  default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2443
+	    /* If we try and place any item, that is non-float, once we've
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2444
+	       exceeded the 8 GPR mark, then we can't fit the struct.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2445
+	    if ((unsigned long)item_base >= 8*8) 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2446
+	      return 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2447
+	    break;    
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2448
+	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2449
+      /* now count the size of what we just used.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2450
+      struct_offset += p->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2451
+    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2452
+  return 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2453
+}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2454
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2455
+/* Can this struct be returned by value?  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2456
+int 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2457
+darwin64_struct_ret_by_value_p (ffi_type *s)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2458
+{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2459
+  unsigned nfp = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2460
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2461
+  FFI_ASSERT (s && s->type == FFI_TYPE_STRUCT);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2462
+  
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2463
+  /* The largest structure we can return is 8long + 13 doubles.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2464
+  if (s->size > 168)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2465
+    return 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2466
+  
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2467
+  /* We can't pass more than 13 floats.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2468
+  darwin64_scan_struct_for_floats (s, &nfp);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2469
+  if (nfp > 13)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2470
+    return 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2471
+  
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2472
+  /* If there are not too many floats, and the struct is
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2473
+     small enough to accommodate in the GPRs, then it must be OK.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2474
+  if (s->size <= 64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2475
+    return 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2476
+  
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2477
+  /* Well, we have to look harder.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2478
+  nfp = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2479
+  if (darwin64_struct_size_exceeds_gprs_p (s, NULL, &nfp))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2480
+    return 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2481
+  
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2482
+  return 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2483
+}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2484
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2485
+void
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2486
+darwin64_pass_struct_floats (ffi_type *s, char *src, 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2487
+			     unsigned *nfpr, double **fprs)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2488
+{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2489
+  int i;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2490
+  double *fpr_base = *fprs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2491
+  unsigned struct_offset = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2492
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2493
+  /* We don't assume anything about the alignment of the source.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2494
+  for (i = 0; s->elements[i] != NULL; i++)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2495
+    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2496
+      char *item_base;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2497
+      ffi_type *p = s->elements[i];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2498
+      /* Find the start of this item (0 for the first one).  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2499
+      if (i > 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2500
+        struct_offset = ALIGN(struct_offset, p->alignment);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2501
+      item_base = src + struct_offset;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2502
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2503
+      switch (p->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2504
+	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2505
+	  case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2506
+	    darwin64_pass_struct_floats (p, item_base, nfpr,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2507
+					   &fpr_base);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2508
+	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2509
+	  case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2510
+	    if (*nfpr < NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2511
+	      *fpr_base++ = *(double *)item_base;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2512
+	    (*nfpr) += 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2513
+	    item_base += 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2514
+	  /* FALL THROUGH */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2515
+	  case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2516
+	    if (*nfpr < NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2517
+	      *fpr_base++ = *(double *)item_base;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2518
+	    (*nfpr) += 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2519
+	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2520
+	  case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2521
+	    if (*nfpr < NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2522
+	      *fpr_base++ = (double) *(float *)item_base;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2523
+	    (*nfpr) += 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2524
+	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2525
+	  default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2526
+	    break;    
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2527
+	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2528
+      /* now count the size of what we just used.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2529
+      struct_offset += p->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2530
+    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2531
+  /* Update the scores.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2532
+  *fprs = fpr_base;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2533
+}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2534
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2535
+/* Darwin64 special rules.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2536
+   Break out a struct into params and float registers.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2537
+static void
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2538
+darwin64_pass_struct_by_value (ffi_type *s, char *src, unsigned size,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2539
+			       unsigned *nfpr, double **fprs, unsigned long **arg)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2540
+{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2541
+  unsigned long *next_arg = *arg;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2542
+  char *dest_cpy = (char *)next_arg;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2543
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2544
+  FFI_ASSERT (s->type == FFI_TYPE_STRUCT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2545
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2546
+  if (!size)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2547
+    return;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2548
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2549
+  /* First... special cases.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2550
+  if (size < 3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2551
+      || (size == 4 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2552
+	  && s->elements[0] 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2553
+	  && s->elements[0]->type != FFI_TYPE_FLOAT))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2554
+    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2555
+      /* Must be at least one GPR, padding is unspecified in value, 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2556
+	 let's make it zero.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2557
+      *next_arg = 0UL; 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2558
+      dest_cpy += 8 - size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2559
+      memcpy ((char *) dest_cpy, src, size);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2560
+      next_arg++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2561
+    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2562
+  else if (size == 16)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2563
+    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2564
+      memcpy ((char *) dest_cpy, src, size);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2565
+      next_arg += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2566
+    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2567
+  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2568
+    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2569
+      /* now the general case, we consider embedded floats.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2570
+      memcpy ((char *) dest_cpy, src, size);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2571
+      darwin64_pass_struct_floats (s, src, nfpr, fprs);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2572
+      next_arg += (size+7)/8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2573
+    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2574
+    
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2575
+  *arg = next_arg;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2576
+}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2577
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2578
+double *
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2579
+darwin64_struct_floats_to_mem (ffi_type *s, char *dest, double *fprs, unsigned *nf)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2580
+{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2581
+  int i;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2582
+  unsigned struct_offset = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2583
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2584
+  /* We don't assume anything about the alignment of the source.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2585
+  for (i = 0; s->elements[i] != NULL; i++)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2586
+    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2587
+      char *item_base;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2588
+      ffi_type *p = s->elements[i];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2589
+      /* Find the start of this item (0 for the first one).  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2590
+      if (i > 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2591
+        struct_offset = ALIGN(struct_offset, p->alignment);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2592
+      item_base = dest + struct_offset;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2593
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2594
+      switch (p->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2595
+	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2596
+	  case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2597
+	    fprs = darwin64_struct_floats_to_mem (p, item_base, fprs, nf);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2598
+	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2599
+	  case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2600
+	    if (*nf < NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2601
+	      {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2602
+		*(double *)item_base = *fprs++ ;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2603
+		(*nf) += 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2604
+	      }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2605
+	    item_base += 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2606
+	  /* FALL THROUGH */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2607
+	  case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2608
+	    if (*nf < NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2609
+	      {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2610
+		*(double *)item_base = *fprs++ ;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2611
+		(*nf) += 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2612
+	      }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2613
+	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2614
+	  case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2615
+	    if (*nf < NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2616
+	      {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2617
+		*(float *)item_base = (float) *fprs++ ;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2618
+		(*nf) += 1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2619
+	      }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2620
+	    break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2621
+	  default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2622
+	    break;    
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2623
+	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2624
+      /* now count the size of what we just used.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2625
+      struct_offset += p->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2626
+    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2627
+  return fprs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2628
+}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2629
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2630
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2631
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2632
 /* Adjust the size of S to be correct for Darwin.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2633
-   On Darwin, the first field of a structure has natural alignment.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2634
+   On Darwin m32, the first field of a structure has natural alignment.  
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2635
+   On Darwin m64, all fields have natural alignment.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2636
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2637
 static void
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2638
 darwin_adjust_aggregate_sizes (ffi_type *s)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2639
 {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2640
   int i;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2641
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2642
   if (s->type != FFI_TYPE_STRUCT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2643
     return;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2644
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2645
   s->size = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2646
   for (i = 0; s->elements[i] != NULL; i++)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2647
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2648
       ffi_type *p;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2649
       int align;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2650
       
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2651
       p = s->elements[i];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2652
-      darwin_adjust_aggregate_sizes (p);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2653
-      if (i == 0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2654
-	  && (p->type == FFI_TYPE_UINT64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2655
-	      || p->type == FFI_TYPE_SINT64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2656
-	      || p->type == FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2657
-	      || p->alignment == 8))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2658
-	align = 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2659
+      if (p->type == FFI_TYPE_STRUCT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2660
+	darwin_adjust_aggregate_sizes (p);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2661
+#if defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2662
+      /* Natural alignment for all items.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2663
+      align = p->alignment;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2664
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2665
+      /* Natrual alignment for the first item... */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2666
+      if (i == 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2667
+	align = p->alignment;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2668
       else if (p->alignment == 16 || p->alignment < 4)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2669
+	/* .. subsequent items with vector or align < 4 have natural align.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2670
 	align = p->alignment;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2671
       else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2672
+	/* .. or align is 4.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2673
 	align = 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2674
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2675
+      /* Pad, if necessary, before adding the current item.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2676
       s->size = ALIGN(s->size, align) + p->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2677
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2678
   
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2679
   s->size = ALIGN(s->size, s->alignment);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2680
   
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2681
+  /* This should not be necessary on m64, but harmless.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2682
   if (s->elements[0]->type == FFI_TYPE_UINT64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2683
       || s->elements[0]->type == FFI_TYPE_SINT64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2684
       || s->elements[0]->type == FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2685
       || s->elements[0]->alignment == 8)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2686
     s->alignment = s->alignment > 8 ? s->alignment : 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2687
   /* Do not add additional tail padding.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2688
 }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2689
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2690
@@ -342,17 +656,17 @@ aix_adjust_aggregate_sizes (ffi_type *s)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2691
 /* Perform machine dependent cif processing.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2692
 ffi_status
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2693
 ffi_prep_cif_machdep (ffi_cif *cif)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2694
 {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2695
   /* All this is for the DARWIN ABI.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2696
   unsigned i;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2697
   ffi_type **ptr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2698
   unsigned bytes;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2699
-  int fparg_count = 0, intarg_count = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2700
+  unsigned fparg_count = 0, intarg_count = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2701
   unsigned flags = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2702
   unsigned size_al = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2703
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2704
   /* All the machine-independent calculation of cif->bytes will be wrong.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2705
      All the calculation of structure sizes will also be wrong.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2706
      Redo the calculation for DARWIN.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2707
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2708
   if (cif->abi == FFI_DARWIN)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2709
@@ -367,26 +681,35 @@ ffi_prep_cif_machdep (ffi_cif *cif)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2710
       aix_adjust_aggregate_sizes (cif->rtype);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2711
       for (i = 0; i < cif->nargs; i++)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2712
 	aix_adjust_aggregate_sizes (cif->arg_types[i]);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2713
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2714
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2715
   /* Space for the frame pointer, callee's LR, CR, etc, and for
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2716
      the asm's temp regs.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2717
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2718
-  bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2719
+  bytes = (LINKAGE_AREA_GPRS + ASM_NEEDS_REGISTERS) * sizeof(unsigned long);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2720
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2721
-  /* Return value handling.  The rules are as follows:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2722
+  /* Return value handling.  
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2723
+    The rules m32 are as follows:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2724
      - 32-bit (or less) integer values are returned in gpr3;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2725
-     - Structures of size <= 4 bytes also returned in gpr3;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2726
-     - 64-bit integer values and structures between 5 and 8 bytes are returned
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2727
-       in gpr3 and gpr4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2728
+     - structures of size <= 4 bytes also returned in gpr3;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2729
+     - 64-bit integer values [??? and structures between 5 and 8 bytes] are
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2730
+       returned in gpr3 and gpr4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2731
      - Single/double FP values are returned in fpr1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2732
      - Long double FP (if not equivalent to double) values are returned in
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2733
        fpr1 and fpr2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2734
+     m64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2735
+     - 64-bit or smaller integral values are returned in GPR3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2736
+     - Single/double FP values are returned in fpr1;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2737
+     - Long double FP values are returned in fpr1 and fpr2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2738
+     m64 Structures:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2739
+     - If the structure could be accommodated in registers were it to be the
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2740
+       first argument to a routine, then it is returned in those registers.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2741
+     m32/m64 structures otherwise:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2742
      - Larger structures values are allocated space and a pointer is passed
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2743
        as the first argument.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2744
   switch (cif->rtype->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2745
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2746
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2747
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2748
     case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2749
       flags |= FLAG_RETURNS_128BITS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2750
@@ -405,124 +728,193 @@ ffi_prep_cif_machdep (ffi_cif *cif)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2751
     case FFI_TYPE_SINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2752
 #ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2753
     case FFI_TYPE_POINTER:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2754
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2755
       flags |= FLAG_RETURNS_64BITS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2756
       break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2757
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2758
     case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2759
+#if defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2760
+      {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2761
+	/* Can we fit the struct into regs?  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2762
+	if (darwin64_struct_ret_by_value_p (cif->rtype))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2763
+	  {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2764
+	    unsigned nfpr = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2765
+	    flags |= FLAG_RETURNS_STRUCT;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2766
+	    if (cif->rtype->size != 16)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2767
+	      darwin64_scan_struct_for_floats (cif->rtype, &nfpr) ;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2768
+	    else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2769
+	      flags |= FLAG_RETURNS_128BITS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2770
+	    /* Will be 0 for 16byte struct.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2771
+	    if (nfpr)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2772
+	      flags |= FLAG_RETURNS_FP;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2773
+	  }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2774
+	else /* By ref. */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2775
+	  {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2776
+	    flags |= FLAG_RETVAL_REFERENCE;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2777
+	    flags |= FLAG_RETURNS_NOTHING;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2778
+	    intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2779
+	  }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2780
+      }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2781
+#elif defined(DARWIN_PPC)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2782
+      if (cif->rtype->size <= 4)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2783
+	flags |= FLAG_RETURNS_STRUCT;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2784
+      else /* else by reference.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2785
+	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2786
+	  flags |= FLAG_RETVAL_REFERENCE;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2787
+	  flags |= FLAG_RETURNS_NOTHING;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2788
+	  intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2789
+	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2790
+#else /* assume we pass by ref.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2791
       flags |= FLAG_RETVAL_REFERENCE;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2792
       flags |= FLAG_RETURNS_NOTHING;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2793
       intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2794
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2795
       break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2796
     case FFI_TYPE_VOID:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2797
       flags |= FLAG_RETURNS_NOTHING;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2798
       break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2799
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2800
     default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2801
       /* Returns 32-bit integer, or similar.  Nothing to do here.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2802
       break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2803
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2804
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2805
   /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2806
      first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2807
-     goes on the stack.  Structures are passed as a pointer to a copy of
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2808
-     the structure. Stuff on the stack needs to keep proper alignment.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2809
+     goes on the stack.  
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2810
+     ??? Structures are passed as a pointer to a copy of the structure. 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2811
+     Stuff on the stack needs to keep proper alignment.  
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2812
+     For m64 the count is effectively of half-GPRs.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2813
   for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2814
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2815
+      unsigned align_words;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2816
       switch ((*ptr)->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2817
 	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2818
 	case FFI_TYPE_FLOAT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2819
 	case FFI_TYPE_DOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2820
 	  fparg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2821
+#if !defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2822
 	  /* If this FP arg is going on the stack, it must be
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2823
 	     8-byte-aligned.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2824
 	  if (fparg_count > NUM_FPR_ARG_REGISTERS
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2825
-	      && intarg_count%2 != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2826
+	      && (intarg_count & 0x01) != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2827
 	    intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2828
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2829
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2830
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2831
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2832
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2833
 	case FFI_TYPE_LONGDOUBLE:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2834
 	  fparg_count += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2835
 	  /* If this FP arg is going on the stack, it must be
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2836
-	     8-byte-aligned.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2837
-	  if (fparg_count > NUM_FPR_ARG_REGISTERS
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2838
-	      && intarg_count%2 != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2839
-	    intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2840
-	  intarg_count +=2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2841
+	     16-byte-aligned.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2842
+	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2843
+#if defined (POWERPC64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2844
+	    intarg_count = ALIGN(intarg_count, 2);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2845
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2846
+	    intarg_count = ALIGN(intarg_count, 4);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2847
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2848
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2849
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2850
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2851
 	case FFI_TYPE_UINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2852
 	case FFI_TYPE_SINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2853
+#if defined(POWERPC64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2854
+	  intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2855
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2856
 	  /* 'long long' arguments are passed as two words, but
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2857
 	     either both words must fit in registers or both go
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2858
 	     on the stack.  If they go on the stack, they must
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2859
 	     be 8-byte-aligned.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2860
 	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2861
-	      || (intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2862
+	      || (intarg_count >= NUM_GPR_ARG_REGISTERS 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2863
+	          && (intarg_count & 0x01) != 0))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2864
 	    intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2865
 	  intarg_count += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2866
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2867
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2868
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2869
 	case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2870
 	  size_al = (*ptr)->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2871
+#if defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2872
+	  align_words = (*ptr)->alignment >> 3;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2873
+	  if (align_words)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2874
+	    intarg_count = ALIGN(intarg_count, align_words);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2875
+	  /* Base size of the struct.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2876
+	  intarg_count += (size_al + 7) / 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2877
+	  /* If 16 bytes then don't worry about floats.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2878
+	  if (size_al != 16)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2879
+	    /* Scan through for floats to be placed in regs.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2880
+	    darwin64_scan_struct_for_floats (*ptr, &fparg_count) ;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2881
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2882
+	  align_words = (*ptr)->alignment >> 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2883
+	  if (align_words)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2884
+	    intarg_count = ALIGN(intarg_count, align_words);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2885
 	  /* If the first member of the struct is a double, then align
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2886
-	     the struct to double-word.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2887
+	     the struct to double-word. 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2888
 	  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2889
-	    size_al = ALIGN((*ptr)->size, 8);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2890
-#ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2891
+	    size_al = ALIGN((*ptr)->size, 8); */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2892
+#  ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2893
 	  intarg_count += (size_al + 7) / 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2894
-#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2895
+#  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2896
 	  intarg_count += (size_al + 3) / 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2897
+#  endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2898
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2899
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2900
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2901
 	default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2902
 	  /* Everything else is passed as a 4-byte word in a GPR, either
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2903
 	     the object itself or a pointer to it.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2904
 	  intarg_count++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2905
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2906
 	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2907
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2908
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2909
   if (fparg_count != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2910
     flags |= FLAG_FP_ARGUMENTS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2911
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2912
+#if defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2913
+  /* Space to image the FPR registers, if needed - which includes when they might be
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2914
+     used in a struct return.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2915
+  if (fparg_count != 0 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2916
+      || ((flags & FLAG_RETURNS_STRUCT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2917
+	   && (flags & FLAG_RETURNS_FP)))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2918
+    bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2919
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2920
   /* Space for the FPR registers, if needed.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2921
   if (fparg_count != 0)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2922
     bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2923
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2924
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2925
   /* Stack space.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2926
 #ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2927
   if ((intarg_count + fparg_count) > NUM_GPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2928
     bytes += (intarg_count + fparg_count) * sizeof(long);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2929
 #else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2930
   if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2931
     bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2932
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2933
   else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2934
     bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2935
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2936
   /* The stack space allocated needs to be a multiple of 16 bytes.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2937
-  bytes = (bytes + 15) & ~0xF;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2938
+  bytes = ALIGN(bytes, 16) ;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2939
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2940
   cif->flags = flags;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2941
   cif->bytes = bytes;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2942
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2943
   return FFI_OK;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2944
 }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2945
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2946
 extern void ffi_call_AIX(extended_cif *, long, unsigned, unsigned *,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2947
 			 void (*fn)(void), void (*fn2)(void));
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2948
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2949
 extern void ffi_call_DARWIN(extended_cif *, long, unsigned, unsigned *,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2950
-			    void (*fn)(void), void (*fn2)(void));
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2951
+			    void (*fn)(void), void (*fn2)(void), ffi_type*);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2952
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2953
 void
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2954
 ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2955
 {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2956
   extended_cif ecif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2957
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2958
   ecif.cif = cif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2959
   ecif.avalue = avalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2960
@@ -541,17 +933,17 @@ ffi_call (ffi_cif *cif, void (*fn)(void)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2961
   switch (cif->abi)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2962
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2963
     case FFI_AIX:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2964
       ffi_call_AIX(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2965
 		   FFI_FN(ffi_prep_args));
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2966
       break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2967
     case FFI_DARWIN:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2968
       ffi_call_DARWIN(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2969
-		      FFI_FN(ffi_prep_args));
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2970
+		      FFI_FN(ffi_prep_args), cif->rtype);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2971
       break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2972
     default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2973
       FFI_ASSERT(0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2974
       break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2975
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2976
 }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2977
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2978
 static void flush_icache(char *);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2979
@@ -561,123 +953,127 @@ static void flush_range(char *, int);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2980
    points to one of these.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2981
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2982
 typedef struct aix_fd_struct {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2983
   void *code_pointer;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2984
   void *toc;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2985
 } aix_fd;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2986
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2987
 /* here I'd like to add the stack frame layout we use in darwin_closure.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2988
-   and aix_clsoure.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2989
+   and aix_closure.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2990
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2991
-   SP previous -> +---------------------------------------+ <--- child frame
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2992
-		  | back chain to caller 4                |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2993
-		  +---------------------------------------+ 4
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2994
-		  | saved CR 4                            |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2995
-		  +---------------------------------------+ 8
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2996
-		  | saved LR 4                            |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2997
-		  +---------------------------------------+ 12
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2998
-		  | reserved for compilers 4              |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  2999
-		  +---------------------------------------+ 16
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3000
-		  | reserved for binders 4                |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3001
-		  +---------------------------------------+ 20
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3002
-		  | saved TOC pointer 4                   |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3003
-		  +---------------------------------------+ 24
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3004
-		  | always reserved 8*4=32 (previous GPRs)|
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3005
-		  | according to the linkage convention   |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3006
-		  | from AIX                              |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3007
-		  +---------------------------------------+ 56
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3008
-		  | our FPR area 13*8=104                 |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3009
-		  | f1                                    |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3010
-		  | .                                     |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3011
-		  | f13                                   |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3012
-		  +---------------------------------------+ 160
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3013
-		  | result area 8                         |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3014
-		  +---------------------------------------+ 168
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3015
-		  | alignement to the next multiple of 16 |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3016
-SP current -->    +---------------------------------------+ 176 <- parent frame
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3017
-		  | back chain to caller 4                |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3018
-		  +---------------------------------------+ 180
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3019
-		  | saved CR 4                            |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3020
-		  +---------------------------------------+ 184
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3021
-		  | saved LR 4                            |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3022
-		  +---------------------------------------+ 188
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3023
-		  | reserved for compilers 4              |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3024
-		  +---------------------------------------+ 192
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3025
-		  | reserved for binders 4                |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3026
-		  +---------------------------------------+ 196
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3027
-		  | saved TOC pointer 4                   |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3028
-		  +---------------------------------------+ 200
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3029
-		  | always reserved 8*4=32  we store our  |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3030
-		  | GPRs here                             |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3031
-		  | r3                                    |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3032
-		  | .                                     |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3033
-		  | r10                                   |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3034
-		  +---------------------------------------+ 232
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3035
-		  | overflow part                         |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3036
-		  +---------------------------------------+ xxx
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3037
-		  | ????                                  |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3038
-		  +---------------------------------------+ xxx
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3039
+   m32/m64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3040
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3041
+   The stack layout looks like this:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3042
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3043
+   |   Additional params...			| |     Higher address
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3044
+   ~						~ ~
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3045
+   |   Parameters      (at least 8*4/8=32/64)	| | NUM_GPR_ARG_REGISTERS
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3046
+   |--------------------------------------------| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3047
+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3048
+   |--------------------------------------------| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3049
+   |   Reserved                       2*4/8	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3050
+   |--------------------------------------------| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3051
+   |   Space for callee's LR		4/8	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3052
+   |--------------------------------------------| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3053
+   |   Saved CR [low word for m64]      4/8	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3054
+   |--------------------------------------------| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3055
+   |   Current backchain pointer	4/8	|-/ Parent's frame.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3056
+   |--------------------------------------------| <+ <<< on entry to ffi_closure_ASM
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3057
+   |   Result Bytes			16	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3058
+   |--------------------------------------------| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3059
+   ~   padding to 16-byte alignment		~ ~
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3060
+   |--------------------------------------------| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3061
+   |   NUM_FPR_ARG_REGISTERS slots		| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3062
+   |   here fp13 .. fp1		       13*8	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3063
+   |--------------------------------------------| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3064
+   |   R3..R10			  8*4/8=32/64	| | NUM_GPR_ARG_REGISTERS
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3065
+   |--------------------------------------------| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3066
+   |   TOC=R2 (AIX) Reserved (Darwin)   4/8	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3067
+   |--------------------------------------------| |	stack	|
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3068
+   |   Reserved [compiler,binder]     2*4/8	| |	grows	|
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3069
+   |--------------------------------------------| |	down	V
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3070
+   |   Space for callee's LR		4/8	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3071
+   |--------------------------------------------| |	lower addresses
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3072
+   |   Saved CR [low word for m64]      4/8	| |
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3073
+   |--------------------------------------------| |     stack pointer here
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3074
+   |   Current backchain pointer	4/8	|-/	during
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3075
+   |--------------------------------------------|   <<<	ffi_closure_ASM.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3076
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3077
 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3078
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3079
 ffi_status
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3080
 ffi_prep_closure_loc (ffi_closure* closure,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3081
 		      ffi_cif* cif,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3082
 		      void (*fun)(ffi_cif*, void*, void**, void*),
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3083
 		      void *user_data,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3084
 		      void *codeloc)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3085
 {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3086
   unsigned int *tramp;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3087
   struct ffi_aix_trampoline_struct *tramp_aix;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3088
   aix_fd *fd;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3089
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3090
   switch (cif->abi)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3091
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3092
-    case FFI_DARWIN:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3093
+      case FFI_DARWIN:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3094
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3095
-      FFI_ASSERT (cif->abi == FFI_DARWIN);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3096
+	FFI_ASSERT (cif->abi == FFI_DARWIN);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3097
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3098
-      tramp = (unsigned int *) &closure->tramp[0];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3099
-      tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3100
-      tramp[1] = 0x429f000d;  /*   bcl-    20,4*cr7+so,0x10  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3101
-      tramp[4] = 0x7d6802a6;  /*   mflr    r11  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3102
-      tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11) function address  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3103
-      tramp[6] = 0x7c0803a6;  /*   mtlr    r0   */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3104
-      tramp[7] = 0x7d8903a6;  /*   mtctr   r12  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3105
-      tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11) static chain  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3106
-      tramp[9] = 0x4e800420;  /*   bctr  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3107
-      tramp[2] = (unsigned long) ffi_closure_ASM; /* function  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3108
-      tramp[3] = (unsigned long) codeloc; /* context  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3109
+	tramp = (unsigned int *) &closure->tramp[0];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3110
+#if defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3111
+	tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3112
+	tramp[1] = 0x429f0015;  /*   bcl-    20,4*cr7+so,  +0x18 (L1)  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3113
+	/* We put the addresses here.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3114
+	tramp[6] = 0x7d6802a6;  /*L1:   mflr    r11  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3115
+	tramp[7] = 0xe98b0000;  /*   ld     r12,0(r11) function address  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3116
+	tramp[8] = 0x7c0803a6;  /*   mtlr    r0   */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3117
+	tramp[9] = 0x7d8903a6;  /*   mtctr   r12  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3118
+	tramp[10] = 0xe96b0008;  /*   lwz     r11,8(r11) static chain  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3119
+	tramp[11] = 0x4e800420;  /*   bctr  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3120
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3121
-      closure->cif = cif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3122
-      closure->fun = fun;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3123
-      closure->user_data = user_data;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3124
+	*((unsigned long *)&tramp[2]) = (unsigned long) ffi_closure_ASM; /* function  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3125
+	*((unsigned long *)&tramp[4]) = (unsigned long) codeloc; /* context  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3126
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3127
+	tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3128
+	tramp[1] = 0x429f000d;  /*   bcl-    20,4*cr7+so,0x10  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3129
+	tramp[4] = 0x7d6802a6;  /*   mflr    r11  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3130
+	tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11) function address  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3131
+	tramp[6] = 0x7c0803a6;  /*   mtlr    r0   */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3132
+	tramp[7] = 0x7d8903a6;  /*   mtctr   r12  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3133
+	tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11) static chain  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3134
+	tramp[9] = 0x4e800420;  /*   bctr  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3135
+	tramp[2] = (unsigned long) ffi_closure_ASM; /* function  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3136
+	tramp[3] = (unsigned long) codeloc; /* context  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3137
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3138
+	closure->cif = cif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3139
+	closure->fun = fun;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3140
+	closure->user_data = user_data;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3141
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3142
-      /* Flush the icache. Only necessary on Darwin.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3143
-      flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3144
+	/* Flush the icache. Only necessary on Darwin.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3145
+	flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3146
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3147
-      break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3148
+	break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3149
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3150
     case FFI_AIX:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3151
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3152
       tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3153
       fd = (aix_fd *)(void *)ffi_closure_ASM;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3154
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3155
       FFI_ASSERT (cif->abi == FFI_AIX);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3156
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3157
       tramp_aix->code_pointer = fd->code_pointer;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3158
       tramp_aix->toc = fd->toc;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3159
       tramp_aix->static_chain = codeloc;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3160
       closure->cif = cif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3161
       closure->fun = fun;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3162
       closure->user_data = user_data;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3163
+      break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3164
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3165
     default:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3166
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3167
-      FFI_ASSERT(0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3168
+      return FFI_BAD_ABI;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3169
       break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3170
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3171
   return FFI_OK;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3172
 }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3173
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3174
 static void
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3175
 flush_icache(char *addr)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3176
 {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3177
@@ -703,28 +1099,28 @@ flush_range(char * addr1, int size)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3178
 }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3179
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3180
 typedef union
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3181
 {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3182
   float f;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3183
   double d;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3184
 } ffi_dblfl;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3185
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3186
-int
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3187
+ffi_type *
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3188
 ffi_closure_helper_DARWIN (ffi_closure *, void *,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3189
 			   unsigned long *, ffi_dblfl *);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3190
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3191
 /* Basically the trampoline invokes ffi_closure_ASM, and on
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3192
    entry, r11 holds the address of the closure.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3193
    After storing the registers that could possibly contain
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3194
    parameters to be passed into the stack frame and setting
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3195
    up space for a return value, ffi_closure_ASM invokes the
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3196
    following helper function to do most of the work.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3197
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3198
-int
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3199
+ffi_type *
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3200
 ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3201
 			   unsigned long *pgr, ffi_dblfl *pfr)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3202
 {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3203
   /* rvalue is the pointer to space for return value in closure assembly
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3204
      pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3205
      pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3206
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3207
   typedef double ldbits[2];
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3208
@@ -736,97 +1132,132 @@ ffi_closure_helper_DARWIN (ffi_closure *
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3209
   };
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3210
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3211
   void **          avalue;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3212
   ffi_type **      arg_types;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3213
   long             i, avn;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3214
   ffi_cif *        cif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3215
   ffi_dblfl *      end_pfr = pfr + NUM_FPR_ARG_REGISTERS;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3216
   unsigned         size_al;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3217
+#if defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3218
+  unsigned 	   fpsused = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3219
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3220
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3221
   cif = closure->cif;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3222
   avalue = alloca (cif->nargs * sizeof(void *));
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3223
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3224
-  /* Copy the caller's structure return value address so that the closure
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3225
-     returns the data directly to the caller.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3226
   if (cif->rtype->type == FFI_TYPE_STRUCT)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3227
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3228
+#if defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3229
+      if (!darwin64_struct_ret_by_value_p (cif->rtype))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3230
+	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3231
+    	  /* Won't fit into the regs - return by ref.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3232
+	  rvalue = (void *) *pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3233
+	  pgr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3234
+	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3235
+#elif defined(DARWIN_PPC)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3236
+      if (cif->rtype->size > 4)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3237
+	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3238
+	  rvalue = (void *) *pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3239
+	  pgr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3240
+	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3241
+#else /* assume we return by ref.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3242
       rvalue = (void *) *pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3243
       pgr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3244
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3245
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3246
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3247
   i = 0;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3248
   avn = cif->nargs;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3249
   arg_types = cif->arg_types;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3250
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3251
   /* Grab the addresses of the arguments from the stack frame.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3252
   while (i < avn)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3253
     {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3254
       switch (arg_types[i]->type)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3255
 	{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3256
 	case FFI_TYPE_SINT8:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3257
 	case FFI_TYPE_UINT8:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3258
-#ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3259
+#if  defined(POWERPC64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3260
 	  avalue[i] = (char *) pgr + 7;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3261
 #else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3262
 	  avalue[i] = (char *) pgr + 3;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3263
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3264
 	  pgr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3265
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3266
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3267
 	case FFI_TYPE_SINT16:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3268
 	case FFI_TYPE_UINT16:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3269
-#ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3270
+#if  defined(POWERPC64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3271
 	  avalue[i] = (char *) pgr + 6;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3272
 #else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3273
 	  avalue[i] = (char *) pgr + 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3274
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3275
 	  pgr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3276
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3277
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3278
 	case FFI_TYPE_SINT32:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3279
 	case FFI_TYPE_UINT32:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3280
-#ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3281
+#if  defined(POWERPC64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3282
 	  avalue[i] = (char *) pgr + 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3283
 #else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3284
 	case FFI_TYPE_POINTER:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3285
 	  avalue[i] = pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3286
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3287
 	  pgr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3288
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3289
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3290
 	case FFI_TYPE_STRUCT:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3291
-#ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3292
 	  size_al = arg_types[i]->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3293
-	  if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3294
-	    size_al = ALIGN (arg_types[i]->size, 8);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3295
-	  if (size_al < 3 && cif->abi == FFI_DARWIN)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3296
-	    avalue[i] = (char *) pgr + 8 - size_al;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3297
-	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3298
-	    avalue[i] = pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3299
+#if defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3300
+	  pgr = (unsigned long *)ALIGN((char *)pgr, arg_types[i]->alignment);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3301
+	  if (size_al < 3 || size_al == 4)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3302
+	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3303
+	      avalue[i] = ((char *)pgr)+8-size_al;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3304
+	      if (arg_types[i]->elements[0]->type == FFI_TYPE_FLOAT
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3305
+		  && fpsused < NUM_FPR_ARG_REGISTERS)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3306
+		{
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3307
+		  *(float *)pgr = (float) *(double *)pfr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3308
+		  pfr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3309
+		  fpsused++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3310
+		}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3311
+	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3312
+	  else 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3313
+	    {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3314
+	      if (size_al != 16)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3315
+		pfr = (ffi_dblfl *) 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3316
+		    darwin64_struct_floats_to_mem (arg_types[i], (char *)pgr,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3317
+						   (double *)pfr, &fpsused);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3318
+	      avalue[i] = pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3319
+	    }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3320
 	  pgr += (size_al + 7) / 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3321
 #else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3322
-	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3323
-	     SI 4 bytes) are aligned as if they were those modes.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3324
-	  size_al = arg_types[i]->size;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3325
 	  /* If the first member of the struct is a double, then align
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3326
 	     the struct to double-word.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3327
 	  if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3328
 	    size_al = ALIGN(arg_types[i]->size, 8);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3329
+#  if defined(POWERPC64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3330
+	  FFI_ASSERT (cif->abi != FFI_DARWIN);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3331
+	  avalue[i] = pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3332
+	  pgr += (size_al + 7) / 8;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3333
+#  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3334
+	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3335
+	     SI 4 bytes) are aligned as if they were those modes.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3336
 	  if (size_al < 3 && cif->abi == FFI_DARWIN)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3337
 	    avalue[i] = (char*) pgr + 4 - size_al;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3338
 	  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3339
 	    avalue[i] = pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3340
 	  pgr += (size_al + 3) / 4;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3341
+#  endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3342
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3343
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3344
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3345
 	case FFI_TYPE_SINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3346
 	case FFI_TYPE_UINT64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3347
-#ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3348
+#if  defined(POWERPC64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3349
 	case FFI_TYPE_POINTER:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3350
 	  avalue[i] = pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3351
 	  pgr++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3352
 	  break;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3353
 #else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3354
 	  /* Long long ints are passed in two gpr's.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3355
 	  avalue[i] = pgr;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3356
 	  pgr += 2;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3357
@@ -919,10 +1350,10 @@ ffi_closure_helper_DARWIN (ffi_closure *
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3358
 	  FFI_ASSERT(0);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3359
 	}
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3360
       i++;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3361
     }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3362
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3363
   (closure->fun) (cif, rvalue, avalue, closure->user_data);
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3364
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3365
   /* Tell ffi_closure_ASM to perform return type promotions.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3366
-  return cif->rtype->type;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3367
+  return cif->rtype;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3368
 }
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3369
diff --git a/js/src/ctypes/libffi/src/powerpc/ffitarget.h b/js/src/ctypes/libffi/src/powerpc/ffitarget.h
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3370
--- a/js/src/ctypes/libffi/src/powerpc/ffitarget.h
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3371
+++ b/js/src/ctypes/libffi/src/powerpc/ffitarget.h
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3372
@@ -1,11 +1,13 @@
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3373
 /* -----------------------------------------------------------------*-C-*-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3374
-   ffitarget.h - Copyright (c) 1996-2003  Red Hat, Inc.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3375
-   Copyright (C) 2007, 2008 Free Software Foundation, Inc
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3376
+   ffitarget.h - Copyright (c) 2012  Anthony Green
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3377
+                 Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3378
+                 Copyright (c) 1996-2003  Red Hat, Inc.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3379
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3380
    Target configuration macros for PowerPC.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3381
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3382
    Permission is hereby granted, free of charge, to any person obtaining
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3383
    a copy of this software and associated documentation files (the
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3384
    ``Software''), to deal in the Software without restriction, including
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3385
    without limitation the rights to use, copy, modify, merge, publish,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3386
    distribute, sublicense, and/or sell copies of the Software, and to
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3387
    permit persons to whom the Software is furnished to do so, subject to
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3388
@@ -23,26 +25,33 @@
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3389
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3390
    DEALINGS IN THE SOFTWARE.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3391
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3392
    ----------------------------------------------------------------------- */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3393
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3394
 #ifndef LIBFFI_TARGET_H
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3395
 #define LIBFFI_TARGET_H
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3396
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3397
+#ifndef LIBFFI_H
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3398
+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3399
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3400
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3401
 /* ---- System specific configurations ----------------------------------- */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3402
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3403
 #if defined (POWERPC) && defined (__powerpc64__)	/* linux64 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3404
 #ifndef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3405
 #define POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3406
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3407
-#elif defined (POWERPC_DARWIN) && defined (__ppc64__)	/* Darwin */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3408
+#elif defined (POWERPC_DARWIN) && defined (__ppc64__)	/* Darwin64 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3409
 #ifndef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3410
 #define POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3411
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3412
+#ifndef POWERPC_DARWIN64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3413
+#define POWERPC_DARWIN64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3414
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3415
 #elif defined (POWERPC_AIX) && defined (__64BIT__)	/* AIX64 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3416
 #ifndef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3417
 #define POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3418
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3419
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3420
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3421
 #ifndef LIBFFI_ASM
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3422
 typedef unsigned long          ffi_arg;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3423
@@ -52,28 +61,24 @@ typedef enum ffi_abi {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3424
   FFI_FIRST_ABI = 0,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3425
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3426
 #ifdef POWERPC
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3427
   FFI_SYSV,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3428
   FFI_GCC_SYSV,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3429
   FFI_LINUX64,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3430
   FFI_LINUX,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3431
   FFI_LINUX_SOFT_FLOAT,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3432
-# ifdef POWERPC64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3433
+# if defined(POWERPC64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3434
   FFI_DEFAULT_ABI = FFI_LINUX64,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3435
+# elif defined(__NO_FPRS__)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3436
+  FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3437
+# elif (__LDBL_MANT_DIG__ == 106)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3438
+  FFI_DEFAULT_ABI = FFI_LINUX,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3439
 # else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3440
-#  if (!defined(__NO_FPRS__) && (__LDBL_MANT_DIG__ == 106))
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3441
-  FFI_DEFAULT_ABI = FFI_LINUX,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3442
-#  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3443
-#   ifdef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3444
-  FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3445
-#   else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3446
   FFI_DEFAULT_ABI = FFI_GCC_SYSV,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3447
-#   endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3448
-#  endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3449
 # endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3450
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3451
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3452
 #ifdef POWERPC_AIX
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3453
   FFI_AIX,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3454
   FFI_DARWIN,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3455
   FFI_DEFAULT_ABI = FFI_AIX,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3456
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3457
@@ -96,32 +101,49 @@ typedef enum ffi_abi {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3458
   FFI_LAST_ABI
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3459
 } ffi_abi;
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3460
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3461
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3462
 /* ---- Definitions for closures ----------------------------------------- */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3463
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3464
 #define FFI_CLOSURES 1
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3465
 #define FFI_NATIVE_RAW_API 0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3466
+#if defined (POWERPC) || defined (POWERPC_FREEBSD)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3467
+# define FFI_TARGET_SPECIFIC_VARIADIC 1
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3468
+# define FFI_EXTRA_CIF_FIELDS unsigned nfixedargs
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3469
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3470
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3471
 /* For additional types like the below, take care about the order in
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3472
    ppc_closures.S. They must follow after the FFI_TYPE_LAST.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3473
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3474
 /* Needed for soft-float long-double-128 support.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3475
 #define FFI_TYPE_UINT128 (FFI_TYPE_LAST + 1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3476
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3477
 /* Needed for FFI_SYSV small structure returns.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3478
    We use two flag bits, (FLAG_SYSV_SMST_R3, FLAG_SYSV_SMST_R4) which are
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3479
    defined in ffi.c, to determine the exact return type and its size.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3480
 #define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3481
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3482
-#if defined(POWERPC64) || defined(POWERPC_AIX)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3483
-#define FFI_TRAMPOLINE_SIZE 24
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3484
-#else /* POWERPC || POWERPC_AIX */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3485
-#define FFI_TRAMPOLINE_SIZE 40
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3486
+/* Used by ELFv2 for homogenous structure returns.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3487
+#define FFI_V2_TYPE_FLOAT_HOMOG		(FFI_TYPE_LAST + 1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3488
+#define FFI_V2_TYPE_DOUBLE_HOMOG	(FFI_TYPE_LAST + 2)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3489
+#define FFI_V2_TYPE_SMALL_STRUCT	(FFI_TYPE_LAST + 3)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3490
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3491
+#if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3492
+# define FFI_TRAMPOLINE_SIZE 32
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3493
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3494
+# if defined(POWERPC64) || defined(POWERPC_AIX)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3495
+#  if defined(POWERPC_DARWIN64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3496
+#    define FFI_TRAMPOLINE_SIZE 48
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3497
+#  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3498
+#    define FFI_TRAMPOLINE_SIZE 24
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3499
+#  endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3500
+# else /* POWERPC || POWERPC_AIX */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3501
+#  define FFI_TRAMPOLINE_SIZE 40
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3502
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3503
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3504
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3505
 #ifndef LIBFFI_ASM
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3506
 #if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3507
 struct ffi_aix_trampoline_struct {
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3508
     void * code_pointer;	/* Pointer to ffi_closure_ASM */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3509
     void * toc;			/* TOC */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3510
     void * static_chain;	/* Pointer to closure */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3511
diff --git a/js/src/ctypes/libffi/src/powerpc/linux64.S b/js/src/ctypes/libffi/src/powerpc/linux64.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3512
--- a/js/src/ctypes/libffi/src/powerpc/linux64.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3513
+++ b/js/src/ctypes/libffi/src/powerpc/linux64.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3514
@@ -25,56 +25,86 @@
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3515
    DEALINGS IN THE SOFTWARE.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3516
    ----------------------------------------------------------------------- */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3517
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3518
 #define LIBFFI_ASM
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3519
 #include <fficonfig.h>
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3520
 #include <ffi.h>
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3521
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3522
 #ifdef __powerpc64__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3523
-	.hidden	ffi_call_LINUX64, .ffi_call_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3524
-	.globl	ffi_call_LINUX64, .ffi_call_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3525
+	.hidden	ffi_call_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3526
+	.globl	ffi_call_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3527
+# if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3528
+	.text
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3529
+ffi_call_LINUX64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3530
+	addis	%r2, %r12, .TOC.-ffi_call_LINUX64@ha
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3531
+	addi	%r2, %r2, .TOC.-ffi_call_LINUX64@l
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3532
+	.localentry ffi_call_LINUX64, . - ffi_call_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3533
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3534
 	.section	".opd","aw"
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3535
 	.align	3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3536
 ffi_call_LINUX64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3537
+#  ifdef _CALL_LINUX
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3538
+	.quad	.L.ffi_call_LINUX64,.TOC.@tocbase,0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3539
+	.type	ffi_call_LINUX64,@function
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3540
+	.text
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3541
+.L.ffi_call_LINUX64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3542
+#  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3543
+	.hidden	.ffi_call_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3544
+	.globl	.ffi_call_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3545
 	.quad	.ffi_call_LINUX64,.TOC.@tocbase,0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3546
 	.size	ffi_call_LINUX64,24
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3547
 	.type	.ffi_call_LINUX64,@function
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3548
 	.text
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3549
 .ffi_call_LINUX64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3550
+#  endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3551
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3552
 .LFB1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3553
 	mflr	%r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3554
 	std	%r28, -32(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3555
 	std	%r29, -24(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3556
 	std	%r30, -16(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3557
 	std	%r31, -8(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3558
 	std	%r0, 16(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3559
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3560
 	mr	%r28, %r1	/* our AP.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3561
 .LCFI0:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3562
 	stdux	%r1, %r1, %r4
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3563
 	mr	%r31, %r5	/* flags, */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3564
 	mr	%r30, %r6	/* rvalue, */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3565
 	mr	%r29, %r7	/* function address.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3566
+/* Save toc pointer, not for the ffi_prep_args64 call, but for the later
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3567
+   bctrl function call.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3568
+# if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3569
+	std	%r2, 24(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3570
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3571
 	std	%r2, 40(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3572
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3573
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3574
 	/* Call ffi_prep_args64.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3575
 	mr	%r4, %r1
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3576
+# if defined _CALL_LINUX || _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3577
+	bl	ffi_prep_args64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3578
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3579
 	bl	.ffi_prep_args64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3580
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3581
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3582
-	ld	%r0, 0(%r29)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3583
+# if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3584
+	mr	%r12, %r29
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3585
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3586
+	ld	%r12, 0(%r29)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3587
 	ld	%r2, 8(%r29)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3588
 	ld	%r11, 16(%r29)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3589
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3590
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3591
 	/* Now do the call.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3592
 	/* Set up cr1 with bits 4-7 of the flags.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3593
 	mtcrf	0x40, %r31
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3594
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3595
 	/* Get the address to call into CTR.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3596
-	mtctr	%r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3597
+	mtctr	%r12
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3598
 	/* Load all those argument registers.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3599
 	ld	%r3, -32-(8*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3600
 	ld	%r4, -32-(7*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3601
 	ld	%r5, -32-(6*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3602
 	ld	%r6, -32-(5*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3603
 	bf-	5, 1f
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3604
 	ld	%r7, -32-(4*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3605
 	ld	%r8, -32-(3*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3606
@@ -99,50 +129,93 @@ 1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3607
 	lfd	%f13, -32-(9*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3608
 2:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3609
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3610
 	/* Make the call.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3611
 	bctrl
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3612
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3613
 	/* This must follow the call immediately, the unwinder
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3614
 	   uses this to find out if r2 has been saved or not.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3615
+# if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3616
+	ld	%r2, 24(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3617
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3618
 	ld	%r2, 40(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3619
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3620
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3621
 	/* Now, deal with the return value.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3622
 	mtcrf	0x01, %r31
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3623
-	bt-	30, .Ldone_return_value
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3624
-	bt-	29, .Lfp_return_value
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3625
+	bt	31, .Lstruct_return_value
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3626
+	bt	30, .Ldone_return_value
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3627
+	bt	29, .Lfp_return_value
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3628
 	std	%r3, 0(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3629
 	/* Fall through...  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3630
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3631
 .Ldone_return_value:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3632
 	/* Restore the registers we used and return.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3633
 	mr	%r1, %r28
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3634
 	ld	%r0, 16(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3635
-	ld	%r28, -32(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3636
+	ld	%r28, -32(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3637
 	mtlr	%r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3638
 	ld	%r29, -24(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3639
 	ld	%r30, -16(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3640
 	ld	%r31, -8(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3641
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3642
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3643
 .Lfp_return_value:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3644
 	bf	28, .Lfloat_return_value
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3645
 	stfd	%f1, 0(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3646
 	mtcrf	0x02, %r31 /* cr6  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3647
 	bf	27, .Ldone_return_value
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3648
 	stfd	%f2, 8(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3649
 	b	.Ldone_return_value
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3650
 .Lfloat_return_value:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3651
 	stfs	%f1, 0(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3652
 	b	.Ldone_return_value
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3653
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3654
+.Lstruct_return_value:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3655
+	bf	29, .Lsmall_struct
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3656
+	bf	28, .Lfloat_homog_return_value
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3657
+	stfd	%f1, 0(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3658
+	stfd	%f2, 8(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3659
+	stfd	%f3, 16(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3660
+	stfd	%f4, 24(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3661
+	stfd	%f5, 32(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3662
+	stfd	%f6, 40(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3663
+	stfd	%f7, 48(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3664
+	stfd	%f8, 56(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3665
+	b	.Ldone_return_value
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3666
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3667
+.Lfloat_homog_return_value:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3668
+	stfs	%f1, 0(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3669
+	stfs	%f2, 4(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3670
+	stfs	%f3, 8(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3671
+	stfs	%f4, 12(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3672
+	stfs	%f5, 16(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3673
+	stfs	%f6, 20(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3674
+	stfs	%f7, 24(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3675
+	stfs	%f8, 28(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3676
+	b	.Ldone_return_value
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3677
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3678
+.Lsmall_struct:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3679
+	std	%r3, 0(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3680
+	std	%r4, 8(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3681
+	b	.Ldone_return_value
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3682
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3683
 .LFE1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3684
 	.long	0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3685
 	.byte	0,12,0,1,128,4,0,0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3686
+# if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3687
+	.size	ffi_call_LINUX64,.-ffi_call_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3688
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3689
+#  ifdef _CALL_LINUX
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3690
+	.size	ffi_call_LINUX64,.-.L.ffi_call_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3691
+#  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3692
 	.size	.ffi_call_LINUX64,.-.ffi_call_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3693
+#  endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3694
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3695
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3696
 	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3697
 .Lframe1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3698
 	.4byte	.LECIE1-.LSCIE1	 # Length of Common Information Entry
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3699
 .LSCIE1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3700
 	.4byte	0x0	 # CIE Identifier Tag
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3701
 	.byte	0x1	 # CIE Version
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3702
 	.ascii "zR\0"	 # CIE Augmentation
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3703
@@ -175,13 +248,13 @@ 2:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3704
 	.byte	0x9e	 # DW_CFA_offset, column 0x1e
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3705
 	.uleb128 0x2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3706
 	.byte	0x9d	 # DW_CFA_offset, column 0x1d
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3707
 	.uleb128 0x3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3708
 	.byte	0x9c	 # DW_CFA_offset, column 0x1c
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3709
 	.uleb128 0x4
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3710
 	.align 3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3711
 .LEFDE1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3712
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3713
+# if (defined __ELF__ && defined __linux__) || _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3714
+	.section	.note.GNU-stack,"",@progbits
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3715
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3716
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3717
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3718
-#if defined __ELF__ && defined __linux__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3719
-	.section	.note.GNU-stack,"",@progbits
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3720
-#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3721
diff --git a/js/src/ctypes/libffi/src/powerpc/linux64_closure.S b/js/src/ctypes/libffi/src/powerpc/linux64_closure.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3722
--- a/js/src/ctypes/libffi/src/powerpc/linux64_closure.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3723
+++ b/js/src/ctypes/libffi/src/powerpc/linux64_closure.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3724
@@ -27,179 +27,332 @@
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3725
 #define LIBFFI_ASM
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3726
 #include <fficonfig.h>
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3727
 #include <ffi.h>
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3728
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3729
 	.file	"linux64_closure.S"
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3730
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3731
 #ifdef __powerpc64__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3732
 	FFI_HIDDEN (ffi_closure_LINUX64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3733
-	FFI_HIDDEN (.ffi_closure_LINUX64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3734
-	.globl  ffi_closure_LINUX64, .ffi_closure_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3735
+	.globl  ffi_closure_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3736
+# if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3737
+	.text
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3738
+ffi_closure_LINUX64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3739
+	addis	%r2, %r12, .TOC.-ffi_closure_LINUX64@ha
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3740
+	addi	%r2, %r2, .TOC.-ffi_closure_LINUX64@l
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3741
+	.localentry ffi_closure_LINUX64, . - ffi_closure_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3742
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3743
 	.section        ".opd","aw"
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3744
 	.align  3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3745
 ffi_closure_LINUX64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3746
+#  ifdef _CALL_LINUX
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3747
+	.quad   .L.ffi_closure_LINUX64,.TOC.@tocbase,0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3748
+	.type   ffi_closure_LINUX64,@function
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3749
+	.text
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3750
+.L.ffi_closure_LINUX64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3751
+#  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3752
+	FFI_HIDDEN (.ffi_closure_LINUX64)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3753
+	.globl  .ffi_closure_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3754
 	.quad   .ffi_closure_LINUX64,.TOC.@tocbase,0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3755
 	.size   ffi_closure_LINUX64,24
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3756
 	.type   .ffi_closure_LINUX64,@function
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3757
 	.text
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3758
 .ffi_closure_LINUX64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3759
+#  endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3760
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3761
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3762
+# if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3763
+#  32 byte special reg save area + 64 byte parm save area and retval
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3764
+#  + 13*8 fpr save area + round to 16
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3765
+#  define STACKFRAME 208
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3766
+#  define PARMSAVE 32
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3767
+#  No parameter save area is needed for the call to ffi_closure_helper_LINUX64,
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3768
+#  so return value can start there.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3769
+#  define RETVAL PARMSAVE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3770
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3771
+#  48 bytes special reg save area + 64 bytes parm save area
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3772
+#  + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3773
+#  define STACKFRAME 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3774
+#  define PARMSAVE 48
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3775
+#  define RETVAL PARMSAVE+64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3776
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3777
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3778
 .LFB1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3779
-	# save general regs into parm save area
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3780
-	std	%r3, 48(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3781
-	std	%r4, 56(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3782
-	std	%r5, 64(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3783
-	std	%r6, 72(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3784
+# if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3785
+	ld	%r12, FFI_TRAMPOLINE_SIZE(%r11)		# closure->cif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3786
 	mflr	%r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3787
+	lwz	%r12, 28(%r12)				# cif->flags
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3788
+	mtcrf	0x40, %r12
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3789
+	addi	%r12, %r1, PARMSAVE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3790
+	bt	7, .Lparmsave
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3791
+	# Our caller has not allocated a parameter save area.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3792
+	# We need to allocate one here and use it to pass gprs to
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3793
+	# ffi_closure_helper_LINUX64.  The return value area will do.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3794
+	addi	%r12, %r1, -STACKFRAME+RETVAL
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3795
+.Lparmsave:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3796
+	std	%r0, 16(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3797
+	# Save general regs into parm save area
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3798
+	std	%r3, 0(%r12)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3799
+	std	%r4, 8(%r12)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3800
+	std	%r5, 16(%r12)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3801
+	std	%r6, 24(%r12)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3802
+	std	%r7, 32(%r12)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3803
+	std	%r8, 40(%r12)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3804
+	std	%r9, 48(%r12)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3805
+	std	%r10, 56(%r12)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3806
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3807
-	std	%r7, 80(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3808
-	std	%r8, 88(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3809
-	std	%r9, 96(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3810
-	std	%r10, 104(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3811
+	# load up the pointer to the parm save area
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3812
+	mr	%r5, %r12
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3813
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3814
+	mflr	%r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3815
+	# Save general regs into parm save area
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3816
+	# This is the parameter save area set up by our caller.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3817
+	std	%r3, PARMSAVE+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3818
+	std	%r4, PARMSAVE+8(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3819
+	std	%r5, PARMSAVE+16(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3820
+	std	%r6, PARMSAVE+24(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3821
+	std	%r7, PARMSAVE+32(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3822
+	std	%r8, PARMSAVE+40(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3823
+	std	%r9, PARMSAVE+48(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3824
+	std	%r10, PARMSAVE+56(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3825
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3826
 	std	%r0, 16(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3827
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3828
-	# mandatory 48 bytes special reg save area + 64 bytes parm save area
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3829
-	# + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3830
-	stdu	%r1, -240(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3831
+	# load up the pointer to the parm save area
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3832
+	addi	%r5, %r1, PARMSAVE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3833
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3834
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3835
+	# next save fpr 1 to fpr 13
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3836
+	stfd	%f1, -104+(0*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3837
+	stfd	%f2, -104+(1*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3838
+	stfd	%f3, -104+(2*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3839
+	stfd	%f4, -104+(3*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3840
+	stfd	%f5, -104+(4*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3841
+	stfd	%f6, -104+(5*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3842
+	stfd	%f7, -104+(6*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3843
+	stfd	%f8, -104+(7*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3844
+	stfd	%f9, -104+(8*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3845
+	stfd	%f10, -104+(9*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3846
+	stfd	%f11, -104+(10*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3847
+	stfd	%f12, -104+(11*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3848
+	stfd	%f13, -104+(12*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3849
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3850
+	# load up the pointer to the saved fpr registers */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3851
+	addi	%r6, %r1, -104
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3852
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3853
+	# load up the pointer to the result storage
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3854
+	addi	%r4, %r1, -STACKFRAME+RETVAL
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3855
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3856
+	stdu	%r1, -STACKFRAME(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3857
 .LCFI0:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3858
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3859
-	# next save fpr 1 to fpr 13
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3860
-	stfd  %f1, 128+(0*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3861
-	stfd  %f2, 128+(1*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3862
-	stfd  %f3, 128+(2*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3863
-	stfd  %f4, 128+(3*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3864
-	stfd  %f5, 128+(4*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3865
-	stfd  %f6, 128+(5*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3866
-	stfd  %f7, 128+(6*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3867
-	stfd  %f8, 128+(7*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3868
-	stfd  %f9, 128+(8*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3869
-	stfd  %f10, 128+(9*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3870
-	stfd  %f11, 128+(10*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3871
-	stfd  %f12, 128+(11*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3872
-	stfd  %f13, 128+(12*8)(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3873
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3874
-	# set up registers for the routine that actually does the work
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3875
 	# get the context pointer from the trampoline
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3876
-	mr %r3, %r11
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3877
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3878
-	# now load up the pointer to the result storage
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3879
-	addi %r4, %r1, 112
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3880
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3881
-	# now load up the pointer to the parameter save area
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3882
-	# in the previous frame
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3883
-	addi %r5, %r1, 240 + 48
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3884
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3885
-	# now load up the pointer to the saved fpr registers */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3886
-	addi %r6, %r1, 128
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3887
+	mr	%r3, %r11
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3888
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3889
 	# make the call
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3890
+# if defined _CALL_LINUX || _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3891
+	bl ffi_closure_helper_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3892
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3893
 	bl .ffi_closure_helper_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3894
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3895
 .Lret:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3896
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3897
 	# now r3 contains the return type
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3898
 	# so use it to look up in a table
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3899
 	# so we know how to deal with each type
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3900
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3901
 	# look up the proper starting point in table
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3902
 	# by using return type as offset
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3903
+	ld %r0, STACKFRAME+16(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3904
+	cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3905
+	bge .Lsmall
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3906
 	mflr %r4		# move address of .Lret to r4
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3907
 	sldi %r3, %r3, 4	# now multiply return type by 16
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3908
 	addi %r4, %r4, .Lret_type0 - .Lret
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3909
-	ld %r0, 240+16(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3910
 	add %r3, %r3, %r4	# add contents of table to table address
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3911
 	mtctr %r3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3912
 	bctr			# jump to it
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3913
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3914
 # Each of the ret_typeX code fragments has to be exactly 16 bytes long
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3915
 # (4 instructions). For cache effectiveness we align to a 16 byte boundary
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3916
 # first.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3917
 	.align 4
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3918
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3919
 .Lret_type0:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3920
 # case FFI_TYPE_VOID
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3921
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3922
-	addi %r1, %r1, 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3923
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3924
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3925
 	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3926
 # case FFI_TYPE_INT
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3927
-	lwa %r3, 112+4(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3928
+# ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3929
+	lwa %r3, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3930
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3931
+	lwa %r3, RETVAL+4(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3932
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3933
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3934
-	addi %r1, %r1, 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3935
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3936
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3937
 # case FFI_TYPE_FLOAT
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3938
-	lfs %f1, 112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3939
+	lfs %f1, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3940
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3941
-	addi %r1, %r1, 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3942
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3943
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3944
 # case FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3945
-	lfd %f1, 112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3946
+	lfd %f1, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3947
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3948
-	addi %r1, %r1, 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3949
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3950
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3951
 # case FFI_TYPE_LONGDOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3952
-	lfd %f1, 112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3953
+	lfd %f1, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3954
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3955
-	lfd %f2, 112+8(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3956
+	lfd %f2, RETVAL+8(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3957
 	b .Lfinish
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3958
 # case FFI_TYPE_UINT8
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3959
-	lbz %r3, 112+7(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3960
+# ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3961
+	lbz %r3, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3962
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3963
+	lbz %r3, RETVAL+7(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3964
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3965
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3966
-	addi %r1, %r1, 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3967
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3968
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3969
 # case FFI_TYPE_SINT8
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3970
-	lbz %r3, 112+7(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3971
+# ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3972
+	lbz %r3, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3973
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3974
+	lbz %r3, RETVAL+7(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3975
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3976
 	extsb %r3,%r3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3977
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3978
 	b .Lfinish
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3979
 # case FFI_TYPE_UINT16
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3980
-	lhz %r3, 112+6(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3981
+# ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3982
+	lhz %r3, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3983
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3984
+	lhz %r3, RETVAL+6(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3985
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3986
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3987
 .Lfinish:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3988
-	addi %r1, %r1, 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3989
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3990
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3991
 # case FFI_TYPE_SINT16
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3992
-	lha %r3, 112+6(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3993
+# ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3994
+	lha %r3, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3995
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3996
+	lha %r3, RETVAL+6(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3997
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3998
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  3999
-	addi %r1, %r1, 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4000
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4001
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4002
 # case FFI_TYPE_UINT32
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4003
-	lwz %r3, 112+4(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4004
+# ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4005
+	lwz %r3, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4006
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4007
+	lwz %r3, RETVAL+4(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4008
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4009
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4010
-	addi %r1, %r1, 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4011
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4012
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4013
 # case FFI_TYPE_SINT32
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4014
-	lwa %r3, 112+4(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4015
+# ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4016
+	lwa %r3, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4017
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4018
+	lwa %r3, RETVAL+4(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4019
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4020
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4021
-	addi %r1, %r1, 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4022
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4023
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4024
 # case FFI_TYPE_UINT64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4025
-	ld %r3, 112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4026
+	ld %r3, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4027
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4028
-	addi %r1, %r1, 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4029
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4030
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4031
 # case FFI_TYPE_SINT64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4032
-	ld %r3, 112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4033
+	ld %r3, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4034
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4035
-	addi %r1, %r1, 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4036
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4037
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4038
 # case FFI_TYPE_STRUCT
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4039
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4040
-	addi %r1, %r1, 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4041
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4042
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4043
 	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4044
 # case FFI_TYPE_POINTER
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4045
-	ld %r3, 112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4046
+	ld %r3, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4047
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4048
-	addi %r1, %r1, 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4049
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4050
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4051
-# esac
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4052
+# case FFI_V2_TYPE_FLOAT_HOMOG
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4053
+	lfs %f1, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4054
+	lfs %f2, RETVAL+4(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4055
+	lfs %f3, RETVAL+8(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4056
+	b .Lmorefloat
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4057
+# case FFI_V2_TYPE_DOUBLE_HOMOG
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4058
+	lfd %f1, RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4059
+	lfd %f2, RETVAL+8(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4060
+	lfd %f3, RETVAL+16(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4061
+	lfd %f4, RETVAL+24(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4062
+	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4063
+	lfd %f5, RETVAL+32(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4064
+	lfd %f6, RETVAL+40(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4065
+	lfd %f7, RETVAL+48(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4066
+	lfd %f8, RETVAL+56(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4067
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4068
+	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4069
+.Lmorefloat:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4070
+	lfs %f4, RETVAL+12(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4071
+	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4072
+	lfs %f5, RETVAL+16(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4073
+	lfs %f6, RETVAL+20(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4074
+	lfs %f7, RETVAL+24(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4075
+	lfs %f8, RETVAL+28(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4076
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4077
+	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4078
+.Lsmall:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4079
+# ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4080
+	ld %r3,RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4081
+	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4082
+	ld %r4,RETVAL+8(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4083
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4084
+	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4085
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4086
+	# A struct smaller than a dword is returned in the low bits of r3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4087
+	# ie. right justified.  Larger structs are passed left justified
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4088
+	# in r3 and r4.  The return value area on the stack will have
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4089
+	# the structs as they are usually stored in memory.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4090
+	cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT + 7 # size 8 bytes?
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4091
+	neg %r5, %r3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4092
+	ld %r3,RETVAL+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4093
+	blt .Lsmalldown
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4094
+	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4095
+	ld %r4,RETVAL+8(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4096
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4097
+	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4098
+.Lsmalldown:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4099
+	addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4100
+	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4101
+	sldi %r5, %r5, 3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4102
+	addi %r1, %r1, STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4103
+	srd %r3, %r3, %r5
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4104
+	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4105
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4106
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4107
 .LFE1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4108
 	.long	0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4109
 	.byte	0,12,0,1,128,0,0,0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4110
+# if _CALL_ELF == 2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4111
+	.size	ffi_closure_LINUX64,.-ffi_closure_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4112
+# else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4113
+#  ifdef _CALL_LINUX
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4114
+	.size	ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4115
+#  else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4116
 	.size	.ffi_closure_LINUX64,.-.ffi_closure_LINUX64
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4117
+#  endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4118
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4119
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4120
 	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4121
 .Lframe1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4122
 	.4byte	.LECIE1-.LSCIE1	 # Length of Common Information Entry
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4123
 .LSCIE1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4124
 	.4byte	0x0	 # CIE Identifier Tag
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4125
 	.byte	0x1	 # CIE Version
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4126
 	.ascii "zR\0"	 # CIE Augmentation
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4127
@@ -218,19 +371,19 @@ ffi_closure_LINUX64:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4128
 .LASFDE1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4129
 	.4byte	.LASFDE1-.Lframe1	 # FDE CIE offset
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4130
 	.8byte	.LFB1-.	 # FDE initial location
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4131
 	.8byte	.LFE1-.LFB1	 # FDE address range
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4132
 	.uleb128 0x0	 # Augmentation size
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4133
 	.byte	0x2	 # DW_CFA_advance_loc1
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4134
 	.byte	.LCFI0-.LFB1
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4135
 	.byte	0xe	 # DW_CFA_def_cfa_offset
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4136
-	.uleb128 240
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4137
+	.uleb128 STACKFRAME
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4138
 	.byte	0x11	 # DW_CFA_offset_extended_sf
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4139
 	.uleb128 0x41
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4140
 	.sleb128 -2
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4141
 	.align 3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4142
 .LEFDE1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4143
+
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4144
+# if defined __ELF__ && defined __linux__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4145
+	.section	.note.GNU-stack,"",@progbits
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4146
+# endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4147
 #endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4148
-
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4149
-#if defined __ELF__ && defined __linux__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4150
-	.section	.note.GNU-stack,"",@progbits
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4151
-#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4152
diff --git a/js/src/ctypes/libffi/src/powerpc/ppc_closure.S b/js/src/ctypes/libffi/src/powerpc/ppc_closure.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4153
--- a/js/src/ctypes/libffi/src/powerpc/ppc_closure.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4154
+++ b/js/src/ctypes/libffi/src/powerpc/ppc_closure.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4155
@@ -117,53 +117,88 @@ ENTRY(ffi_closure_SYSV)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4156
 # case FFI_TYPE_INT
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4157
 	lwz %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4158
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4159
 .Lfinish:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4160
 	addi %r1,%r1,144
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4161
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4162
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4163
 # case FFI_TYPE_FLOAT
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4164
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4165
 	lfs %f1,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4166
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4167
 	addi %r1,%r1,144
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4168
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4169
+	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4170
+	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4171
+	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4172
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4173
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4174
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4175
 # case FFI_TYPE_DOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4176
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4177
 	lfd %f1,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4178
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4179
 	addi %r1,%r1,144
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4180
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4181
+	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4182
+	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4183
+	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4184
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4185
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4186
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4187
 # case FFI_TYPE_LONGDOUBLE
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4188
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4189
 	lfd %f1,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4190
 	lfd %f2,112+8(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4191
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4192
 	b .Lfinish
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4193
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4194
+	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4195
+	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4196
+	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4197
+	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4198
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4199
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4200
 # case FFI_TYPE_UINT8
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4201
+#ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4202
+	lbz %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4203
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4204
 	lbz %r3,112+3(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4205
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4206
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4207
 	addi %r1,%r1,144
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4208
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4209
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4210
 # case FFI_TYPE_SINT8
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4211
+#ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4212
+	lbz %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4213
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4214
 	lbz %r3,112+3(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4215
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4216
 	extsb %r3,%r3
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4217
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4218
 	b .Lfinish
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4219
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4220
 # case FFI_TYPE_UINT16
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4221
+#ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4222
+	lhz %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4223
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4224
 	lhz %r3,112+2(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4225
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4226
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4227
 	addi %r1,%r1,144
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4228
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4229
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4230
 # case FFI_TYPE_SINT16
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4231
+#ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4232
+	lha %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4233
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4234
 	lha %r3,112+2(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4235
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4236
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4237
 	addi %r1,%r1,144
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4238
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4239
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4240
 # case FFI_TYPE_UINT32
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4241
 	lwz %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4242
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4243
 	addi %r1,%r1,144
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4244
@@ -198,76 +233,99 @@ ENTRY(ffi_closure_SYSV)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4245
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4246
 	addi %r1,%r1,144
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4247
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4248
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4249
 # case FFI_TYPE_UINT128
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4250
 	lwz %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4251
 	lwz %r4,112+4(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4252
 	lwz %r5,112+8(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4253
-	bl .Luint128
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4254
+	b .Luint128
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4255
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4256
 # The return types below are only used when the ABI type is FFI_SYSV.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4257
 # case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4258
 	lbz %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4259
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4260
 	addi %r1,%r1,144
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4261
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4262
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4263
 # case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4264
 	lhz %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4265
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4266
 	addi %r1,%r1,144
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4267
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4268
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4269
 # case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4270
 	lwz %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4271
+#ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4272
+	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4273
+	addi %r1,%r1,144
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4274
+	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4275
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4276
 	srwi %r3,%r3,8
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4277
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4278
 	b .Lfinish
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4279
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4280
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4281
 # case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4282
 	lwz %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4283
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4284
 	addi %r1,%r1,144
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4285
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4286
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4287
 # case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4288
 	lwz %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4289
 	lwz %r4,112+4(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4290
+#ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4291
+	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4292
+	b .Lfinish
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4293
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4294
 	li %r5,24
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4295
 	b .Lstruct567
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4296
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4297
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4298
 # case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4299
 	lwz %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4300
 	lwz %r4,112+4(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4301
+#ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4302
+	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4303
+	b .Lfinish
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4304
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4305
 	li %r5,16
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4306
 	b .Lstruct567
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4307
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4308
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4309
 # case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4310
 	lwz %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4311
 	lwz %r4,112+4(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4312
+#ifdef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4313
+	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4314
+	b .Lfinish
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4315
+#else
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4316
 	li %r5,8
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4317
 	b .Lstruct567
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4318
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4319
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4320
 # case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4321
 	lwz %r3,112+0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4322
 	lwz %r4,112+4(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4323
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4324
 	b .Lfinish
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4325
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4326
+#ifndef __LITTLE_ENDIAN__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4327
 .Lstruct567:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4328
 	subfic %r6,%r5,32
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4329
 	srw %r4,%r4,%r5
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4330
 	slw %r6,%r3,%r6
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4331
 	srw %r3,%r3,%r5
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4332
 	or %r4,%r6,%r4
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4333
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4334
 	addi %r1,%r1,144
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4335
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4336
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4337
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4338
 .Luint128:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4339
 	lwz %r6,112+12(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4340
 	mtlr %r0
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4341
 	addi %r1,%r1,144
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4342
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4343
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4344
 END(ffi_closure_SYSV)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4345
diff --git a/js/src/ctypes/libffi/src/powerpc/sysv.S b/js/src/ctypes/libffi/src/powerpc/sysv.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4346
--- a/js/src/ctypes/libffi/src/powerpc/sysv.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4347
+++ b/js/src/ctypes/libffi/src/powerpc/sysv.S
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4348
@@ -78,37 +78,41 @@ ENTRY(ffi_call_SYSV)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4349
 	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4350
 	lwz	%r7,-16-(4*4)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4351
 	lwz	%r8,-16-(3*4)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4352
 	lwz	%r9,-16-(2*4)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4353
 	lwz	%r10,-16-(1*4)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4354
 	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4355
 1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4356
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4357
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4358
 	/* Load all the FP registers.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4359
 	bf-	6,2f
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4360
 	lfd	%f1,-16-(8*4)-(8*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4361
 	lfd	%f2,-16-(8*4)-(7*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4362
 	lfd	%f3,-16-(8*4)-(6*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4363
 	lfd	%f4,-16-(8*4)-(5*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4364
 	nop
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4365
 	lfd	%f5,-16-(8*4)-(4*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4366
 	lfd	%f6,-16-(8*4)-(3*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4367
 	lfd	%f7,-16-(8*4)-(2*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4368
 	lfd	%f8,-16-(8*4)-(1*8)(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4369
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4370
 2:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4371
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4372
 	/* Make the call.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4373
 	bctrl
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4374
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4375
 	/* Now, deal with the return value.  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4376
 	mtcrf	0x01,%r31 /* cr7  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4377
 	bt-	31,L(small_struct_return_value)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4378
 	bt-	30,L(done_return_value)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4379
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4380
 	bt-	29,L(fp_return_value)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4381
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4382
 	stw	%r3,0(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4383
 	bf+	28,L(done_return_value)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4384
 	stw	%r4,4(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4385
 	mtcrf	0x02,%r31 /* cr6  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4386
 	bf	27,L(done_return_value)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4387
 	stw     %r5,8(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4388
 	stw	%r6,12(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4389
 	/* Fall through...  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4390
@@ -119,41 +123,38 @@ L(done_return_value):
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4391
 	lwz	%r31, -4(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4392
 	mtlr	%r9
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4393
 	lwz	%r30, -8(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4394
 	lwz	%r29,-12(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4395
 	lwz	%r28,-16(%r28)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4396
 	lwz	%r1,0(%r1)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4397
 	blr
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4398
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4399
+#ifndef __NO_FPRS__
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4400
 L(fp_return_value):
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4401
 	bf	28,L(float_return_value)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4402
 	stfd	%f1,0(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4403
 	mtcrf   0x02,%r31 /* cr6  */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4404
 	bf	27,L(done_return_value)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4405
 	stfd	%f2,8(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4406
 	b	L(done_return_value)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4407
 L(float_return_value):
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4408
 	stfs	%f1,0(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4409
 	b	L(done_return_value)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4410
+#endif
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4411
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4412
 L(small_struct_return_value):
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4413
-	extrwi	%r6,%r31,2,19         /* number of bytes padding = shift/8 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4414
-	mtcrf	0x02,%r31	      /* copy flags to cr[24:27] (cr6) */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4415
-	extrwi	%r5,%r31,5,19         /* r5 <- number of bits of padding */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4416
-	subfic  %r6,%r6,4             /* r6 <- number of useful bytes in r3 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4417
-	bf-	25,L(done_return_value) /* struct in r3 ? if not, done. */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4418
-/* smst_one_register: */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4419
-	slw	%r3,%r3,%r5           /* Left-justify value in r3 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4420
-	mtxer	%r6                   /* move byte count to XER ... */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4421
-	stswx	%r3,0,%r30            /* ... and store that many bytes */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4422
-	bf+	26,L(done_return_value)  /* struct in r3:r4 ? */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4423
-	add	%r6,%r6,%r30          /* adjust pointer */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4424
-	stswi	%r4,%r6,4             /* store last four bytes */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4425
-	b	L(done_return_value)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4426
+	/*
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4427
+	 * The C code always allocates a properly-aligned 8-byte bounce
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4428
+	 * buffer to make this assembly code very simple.  Just write out
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4429
+	 * r3 and r4 to the buffer to allow the C code to handle the rest.
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4430
+	 */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4431
+	stw %r3, 0(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4432
+	stw %r4, 4(%r30)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4433
+	b L(done_return_value)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4434
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4435
 .LFE1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4436
 END(ffi_call_SYSV)
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4437
 
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4438
       .section	".eh_frame",EH_FRAME_FLAGS,@progbits
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4439
 .Lframe1:
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4440
       .4byte    .LECIE1-.LSCIE1  /*  Length of Common Information Entry */
8add0ba12be5 PPC64LE support
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff changeset
  4441
 .LSCIE1: