ffi 1.0.11 → 1.0.12.pre

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ffi might be problematic. Click here for more details.

Files changed (159) hide show
  1. data/Rakefile +1 -1
  2. data/ext/ffi_c/AbstractMemory.c +9 -0
  3. data/ext/ffi_c/AbstractMemory.h +4 -0
  4. data/ext/ffi_c/Buffer.c +8 -0
  5. data/ext/ffi_c/Call.c +8 -0
  6. data/ext/ffi_c/ClosurePool.c +12 -0
  7. data/ext/ffi_c/DynamicLibrary.c +7 -1
  8. data/ext/ffi_c/Function.c +11 -1
  9. data/ext/ffi_c/Function.h +6 -0
  10. data/ext/ffi_c/FunctionInfo.c +8 -0
  11. data/ext/ffi_c/LastError.c +8 -0
  12. data/ext/ffi_c/MemoryPointer.c +8 -0
  13. data/ext/ffi_c/MemoryPointer.h +6 -0
  14. data/ext/ffi_c/MethodHandle.c +8 -0
  15. data/ext/ffi_c/Platform.c +8 -0
  16. data/ext/ffi_c/Pointer.c +8 -0
  17. data/ext/ffi_c/Pointer.h +6 -0
  18. data/ext/ffi_c/Struct.c +6 -0
  19. data/ext/ffi_c/StructByReference.c +8 -0
  20. data/ext/ffi_c/StructByValue.c +8 -0
  21. data/ext/ffi_c/StructLayout.c +6 -0
  22. data/ext/ffi_c/Thread.c +7 -0
  23. data/ext/ffi_c/Thread.h +6 -0
  24. data/ext/ffi_c/Type.c +3 -0
  25. data/ext/ffi_c/Types.h +4 -0
  26. data/ext/ffi_c/Variadic.c +8 -0
  27. data/ext/ffi_c/endian.h +3 -0
  28. data/ext/ffi_c/extconf.rb +6 -1
  29. data/ext/ffi_c/libffi.vc.mk +26 -0
  30. data/ext/ffi_c/libffi.vc64.mk +26 -0
  31. data/ext/ffi_c/libffi/ChangeLog +541 -0
  32. data/ext/ffi_c/libffi/ChangeLog.libffi +13 -87
  33. data/ext/ffi_c/libffi/LICENSE +3 -3
  34. data/ext/ffi_c/libffi/Makefile.am +41 -32
  35. data/ext/ffi_c/libffi/Makefile.in +95 -66
  36. data/ext/ffi_c/libffi/Makefile.vc +141 -0
  37. data/ext/ffi_c/libffi/Makefile.vc64 +141 -0
  38. data/ext/ffi_c/libffi/README +40 -4
  39. data/ext/ffi_c/libffi/aclocal.m4 +729 -7854
  40. data/ext/ffi_c/libffi/build-ios.sh +67 -0
  41. data/ext/ffi_c/libffi/compile +11 -10
  42. data/ext/ffi_c/libffi/config.guess +4 -1
  43. data/ext/ffi_c/libffi/config.sub +6 -3
  44. data/ext/ffi_c/libffi/configure +6264 -6354
  45. data/ext/ffi_c/libffi/configure.ac +155 -63
  46. data/ext/ffi_c/libffi/depcomp +81 -35
  47. data/ext/ffi_c/libffi/doc/libffi.info +78 -18
  48. data/ext/ffi_c/libffi/doc/libffi.texi +64 -5
  49. data/ext/ffi_c/libffi/doc/stamp-vti +4 -4
  50. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  51. data/ext/ffi_c/libffi/fficonfig.h.in +18 -0
  52. data/ext/ffi_c/libffi/fficonfig.hw +57 -0
  53. data/ext/ffi_c/libffi/include/Makefile.in +21 -3
  54. data/ext/ffi_c/libffi/include/ffi.h.in +42 -14
  55. data/ext/ffi_c/libffi/include/ffi.h.vc +427 -0
  56. data/ext/ffi_c/libffi/include/ffi.h.vc64 +427 -0
  57. data/ext/ffi_c/libffi/include/ffi_common.h +9 -5
  58. data/ext/ffi_c/libffi/install-sh +364 -167
  59. data/ext/ffi_c/libffi/ltmain.sh +2599 -1369
  60. data/ext/ffi_c/libffi/m4/ax_cc_maxopt.m4 +176 -0
  61. data/ext/ffi_c/libffi/m4/ax_cflags_warn_all.m4 +195 -0
  62. data/ext/ffi_c/libffi/m4/ax_check_compiler_flags.m4 +76 -0
  63. data/ext/ffi_c/libffi/m4/ax_compiler_vendor.m4 +63 -0
  64. data/ext/ffi_c/libffi/m4/ax_configure_args.m4 +70 -0
  65. data/ext/ffi_c/libffi/m4/ax_enable_builddir.m4 +300 -0
  66. data/ext/ffi_c/libffi/m4/ax_gcc_archflag.m4 +215 -0
  67. data/ext/ffi_c/libffi/m4/ax_gcc_x86_cpuid.m4 +79 -0
  68. data/ext/ffi_c/libffi/m4/libtool.m4 +1239 -768
  69. data/ext/ffi_c/libffi/m4/ltoptions.m4 +7 -6
  70. data/ext/ffi_c/libffi/m4/ltversion.m4 +6 -6
  71. data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +9 -3
  72. data/ext/ffi_c/libffi/man/Makefile.in +21 -3
  73. data/ext/ffi_c/libffi/mdate-sh +0 -0
  74. data/ext/ffi_c/libffi/missing +60 -44
  75. data/ext/ffi_c/libffi/msvcc.sh +197 -0
  76. data/ext/ffi_c/libffi/src/alpha/osf.S +39 -18
  77. data/ext/ffi_c/libffi/src/arm/ffi.c +443 -24
  78. data/ext/ffi_c/libffi/src/arm/ffitarget.h +17 -1
  79. data/ext/ffi_c/libffi/src/arm/gentramp.sh +118 -0
  80. data/ext/ffi_c/libffi/src/arm/sysv.S +206 -15
  81. data/ext/ffi_c/libffi/src/arm/trampoline.S +4450 -0
  82. data/ext/ffi_c/libffi/src/avr32/ffi.c +4 -2
  83. data/ext/ffi_c/libffi/src/avr32/ffitarget.h +2 -2
  84. data/ext/ffi_c/libffi/src/closures.c +17 -35
  85. data/ext/ffi_c/libffi/src/cris/ffi.c +1 -1
  86. data/ext/ffi_c/libffi/src/cris/ffitarget.h +2 -2
  87. data/ext/ffi_c/libffi/src/dlmalloc.c +66 -4
  88. data/ext/ffi_c/libffi/src/frv/ffitarget.h +2 -6
  89. data/ext/ffi_c/libffi/src/ia64/ffi.c +7 -5
  90. data/ext/ffi_c/libffi/src/ia64/ffitarget.h +2 -2
  91. data/ext/ffi_c/libffi/src/java_raw_api.c +1 -1
  92. data/ext/ffi_c/libffi/src/m32r/ffitarget.h +2 -2
  93. data/ext/ffi_c/libffi/src/m68k/ffi.c +10 -0
  94. data/ext/ffi_c/libffi/src/m68k/ffitarget.h +2 -2
  95. data/ext/ffi_c/libffi/src/m68k/sysv.S +36 -0
  96. data/ext/ffi_c/libffi/src/mips/ffi.c +12 -5
  97. data/ext/ffi_c/libffi/src/mips/ffitarget.h +18 -11
  98. data/ext/ffi_c/libffi/src/mips/n32.S +4 -4
  99. data/ext/ffi_c/libffi/src/moxie/eabi.S +128 -0
  100. data/ext/ffi_c/libffi/src/moxie/ffi.c +276 -0
  101. data/ext/ffi_c/libffi/src/pa/ffi.c +7 -4
  102. data/ext/ffi_c/libffi/src/pa/ffitarget.h +6 -5
  103. data/ext/ffi_c/libffi/src/powerpc/aix.S +5 -1
  104. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +2 -0
  105. data/ext/ffi_c/libffi/src/powerpc/asm.h +1 -1
  106. data/ext/ffi_c/libffi/src/powerpc/darwin.S +215 -77
  107. data/ext/ffi_c/libffi/src/powerpc/darwin_closure.S +358 -100
  108. data/ext/ffi_c/libffi/src/powerpc/ffi.c +11 -5
  109. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +603 -172
  110. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +17 -4
  111. data/ext/ffi_c/libffi/src/prep_cif.c +16 -13
  112. data/ext/ffi_c/libffi/src/s390/ffitarget.h +4 -2
  113. data/ext/ffi_c/libffi/src/sh/ffitarget.h +2 -2
  114. data/ext/ffi_c/libffi/src/sh64/ffitarget.h +2 -2
  115. data/ext/ffi_c/libffi/src/sparc/ffi.c +55 -11
  116. data/ext/ffi_c/libffi/src/sparc/ffitarget.h +5 -3
  117. data/ext/ffi_c/libffi/src/x86/ffi.c +54 -92
  118. data/ext/ffi_c/libffi/src/x86/ffi64.c +17 -8
  119. data/ext/ffi_c/libffi/src/x86/ffitarget.h +15 -14
  120. data/ext/ffi_c/libffi/src/x86/sysv.S +40 -26
  121. data/ext/ffi_c/libffi/src/x86/unix64.S +4 -0
  122. data/ext/ffi_c/libffi/src/x86/win32.S +379 -191
  123. data/ext/ffi_c/libffi/src/x86/win64.S +15 -7
  124. data/ext/ffi_c/libffi/testsuite/Makefile.am +1 -1
  125. data/ext/ffi_c/libffi/testsuite/Makefile.in +22 -4
  126. data/ext/ffi_c/libffi/testsuite/lib/libffi.exp +350 -0
  127. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +1 -5
  128. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +1 -1
  129. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +1 -1
  130. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +1 -0
  131. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +1 -0
  132. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c +3 -0
  133. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c +2 -2
  134. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c +3 -0
  135. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c +1 -1
  136. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c +1 -1
  137. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +1 -0
  138. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_abi.c +2 -3
  139. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +2 -1
  140. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +36 -0
  141. data/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c +17 -17
  142. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +1 -0
  143. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c +1 -0
  144. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +1 -1
  145. data/ext/ffi_c/libffi/testsuite/libffi.special/special.exp +1 -3
  146. data/ext/ffi_c/win32/stdint.h +199 -0
  147. data/gen/Rakefile +18 -2
  148. data/lib/ffi/platform/arm-linux/types.conf +102 -0
  149. data/lib/ffi/platform/i486-gnu/types.conf +107 -0
  150. data/lib/ffi/platform/ia64-linux/types.conf +102 -0
  151. data/lib/ffi/platform/mips-linux/types.conf +102 -0
  152. data/lib/ffi/platform/mipsel-linux/types.conf +102 -0
  153. data/lib/ffi/platform/powerpc-linux/types.conf +100 -0
  154. data/lib/ffi/platform/s390-linux/types.conf +102 -0
  155. data/lib/ffi/platform/s390x-linux/types.conf +102 -0
  156. data/lib/ffi/platform/sparc-linux/types.conf +102 -0
  157. data/lib/ffi/tools/types_generator.rb +8 -1
  158. data/lib/ffi_c.bundle +0 -0
  159. metadata +72 -42
@@ -1,7 +1,8 @@
1
1
  /* -----------------------------------------------------------------------
2
- ffi.c - Copyright (c) 1998 Geoffrey Keating
3
- Copyright (C) 2007, 2008 Free Software Foundation, Inc
4
- Copyright (C) 2008 Red Hat, Inc
2
+ ffi.c - Copyright (C) 2011 Anthony Green
3
+ Copyright (C) 2008 Red Hat, Inc
4
+ Copyright (C) 2007, 2008 Free Software Foundation, Inc
5
+ Copyright (c) 1998 Geoffrey Keating
5
6
 
6
7
  PowerPC Foreign Function Interface
7
8
 
@@ -949,14 +950,19 @@ ffi_prep_closure_loc (ffi_closure *closure,
949
950
  #ifdef POWERPC64
950
951
  void **tramp = (void **) &closure->tramp[0];
951
952
 
952
- FFI_ASSERT (cif->abi == FFI_LINUX64);
953
+ if (cif->abi != FFI_LINUX64)
954
+ return FFI_BAD_ABI;
953
955
  /* Copy function address and TOC from ffi_closure_LINUX64. */
954
956
  memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
955
957
  tramp[2] = codeloc;
956
958
  #else
957
959
  unsigned int *tramp;
958
960
 
959
- FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV);
961
+ if (! (cif->abi == FFI_GCC_SYSV
962
+ || cif->abi == FFI_SYSV
963
+ || cif->abi == FFI_LINUX
964
+ || cif->abi == FFI_LINUX_SOFT_FLOAT))
965
+ return FFI_BAD_ABI;
960
966
 
961
967
  tramp = (unsigned int *) &closure->tramp[0];
962
968
  tramp[0] = 0x7c0802a6; /* mflr r0 */
@@ -3,7 +3,7 @@
3
3
 
4
4
  Copyright (C) 1998 Geoffrey Keating
5
5
  Copyright (C) 2001 John Hornkvist
6
- Copyright (C) 2002, 2006, 2007, 2009 Free Software Foundation, Inc.
6
+ Copyright (C) 2002, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
7
7
 
8
8
  FFI support for Darwin and AIX.
9
9
 
@@ -35,11 +35,17 @@
35
35
  extern void ffi_closure_ASM (void);
36
36
 
37
37
  enum {
38
- /* The assembly depends on these exact flags. */
39
- FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */
40
- FLAG_RETURNS_FP = 1 << (31-29),
41
- FLAG_RETURNS_64BITS = 1 << (31-28),
42
- FLAG_RETURNS_128BITS = 1 << (31-31),
38
+ /* The assembly depends on these exact flags.
39
+ For Darwin64 (when FLAG_RETURNS_STRUCT is set):
40
+ FLAG_RETURNS_FP indicates that the structure embeds FP data.
41
+ FLAG_RETURNS_128BITS signals a special struct size that is not
42
+ expanded for float content. */
43
+ FLAG_RETURNS_128BITS = 1 << (31-31), /* These go in cr7 */
44
+ FLAG_RETURNS_NOTHING = 1 << (31-30),
45
+ FLAG_RETURNS_FP = 1 << (31-29),
46
+ FLAG_RETURNS_64BITS = 1 << (31-28),
47
+
48
+ FLAG_RETURNS_STRUCT = 1 << (31-27), /* This goes in cr6 */
43
49
 
44
50
  FLAG_ARG_NEEDS_COPY = 1 << (31- 7),
45
51
  FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */
@@ -50,43 +56,61 @@ enum {
50
56
  /* About the DARWIN ABI. */
51
57
  enum {
52
58
  NUM_GPR_ARG_REGISTERS = 8,
53
- NUM_FPR_ARG_REGISTERS = 13
59
+ NUM_FPR_ARG_REGISTERS = 13,
60
+ LINKAGE_AREA_GPRS = 6
54
61
  };
55
- enum { ASM_NEEDS_REGISTERS = 4 };
62
+
63
+ enum { ASM_NEEDS_REGISTERS = 4 }; /* r28-r31 */
56
64
 
57
65
  /* ffi_prep_args is called by the assembly routine once stack space
58
66
  has been allocated for the function's arguments.
67
+
68
+ m32/m64
59
69
 
60
70
  The stack layout we want looks like this:
61
71
 
62
72
  | Return address from ffi_call_DARWIN | higher addresses
63
73
  |--------------------------------------------|
64
- | Previous backchain pointer 4 | stack pointer here
74
+ | Previous backchain pointer 4/8 | stack pointer here
65
75
  |--------------------------------------------|<+ <<< on entry to
66
- | Saved r28-r31 4*4 | | ffi_call_DARWIN
76
+ | ASM_NEEDS_REGISTERS=r28-r31 4*(4/8) | | ffi_call_DARWIN
67
77
  |--------------------------------------------| |
68
- | Parameters (at least 8*4=32) | |
78
+ | When we have any FP activity... the | |
79
+ | FPRs occupy NUM_FPR_ARG_REGISTERS slots | |
80
+ | here fp13 .. fp1 from high to low addr. | |
81
+ ~ ~ ~
82
+ | Parameters (at least 8*4/8=32/64) | | NUM_GPR_ARG_REGISTERS
69
83
  |--------------------------------------------| |
70
- | Space for GPR2 4 | |
84
+ | TOC=R2 (AIX) Reserved (Darwin) 4/8 | |
71
85
  |--------------------------------------------| | stack |
72
- | Reserved 2*4 | | grows |
86
+ | Reserved 2*4/8 | | grows |
73
87
  |--------------------------------------------| | down V
74
- | Space for callee's LR 4 | |
88
+ | Space for callee's LR 4/8 | |
75
89
  |--------------------------------------------| | lower addresses
76
- | Saved CR 4 | |
90
+ | Saved CR [low word for m64] 4/8 | |
77
91
  |--------------------------------------------| | stack pointer here
78
- | Current backchain pointer 4 |-/ during
92
+ | Current backchain pointer 4/8 |-/ during
79
93
  |--------------------------------------------| <<< ffi_call_DARWIN
80
94
 
81
95
  */
82
96
 
97
+ #if defined(POWERPC_DARWIN64)
98
+ static void
99
+ darwin64_pass_struct_by_value
100
+ (ffi_type *, char *, unsigned, unsigned *, double **, unsigned long **);
101
+ #endif
102
+
103
+ /* This depends on GPR_SIZE = sizeof (unsigned long) */
104
+
83
105
  void
84
106
  ffi_prep_args (extended_cif *ecif, unsigned long *const stack)
85
107
  {
86
108
  const unsigned bytes = ecif->cif->bytes;
87
109
  const unsigned flags = ecif->cif->flags;
88
110
  const unsigned nargs = ecif->cif->nargs;
111
+ #if !defined(POWERPC_DARWIN64)
89
112
  const ffi_abi abi = ecif->cif->abi;
113
+ #endif
90
114
 
91
115
  /* 'stacktop' points at the previous backchain pointer. */
92
116
  unsigned long *const stacktop = stack + (bytes / sizeof(unsigned long));
@@ -94,18 +118,19 @@ ffi_prep_args (extended_cif *ecif, unsigned long *const stack)
94
118
  /* 'fpr_base' points at the space for fpr1, and grows upwards as
95
119
  we use FPR registers. */
96
120
  double *fpr_base = (double *) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;
97
- int fparg_count = 0;
98
-
121
+ int gp_count = 0, fparg_count = 0;
99
122
 
100
123
  /* 'next_arg' grows up as we put parameters in it. */
101
- unsigned long *next_arg = stack + 6; /* 6 reserved positions. */
124
+ unsigned long *next_arg = stack + LINKAGE_AREA_GPRS; /* 6 reserved positions. */
102
125
 
103
126
  int i;
104
127
  double double_tmp;
105
128
  void **p_argv = ecif->avalue;
106
129
  unsigned long gprvalue;
107
130
  ffi_type** ptr = ecif->cif->arg_types;
131
+ #if !defined(POWERPC_DARWIN64)
108
132
  char *dest_cpy;
133
+ #endif
109
134
  unsigned size_al = 0;
110
135
 
111
136
  /* Check that everything starts aligned properly. */
@@ -130,25 +155,30 @@ ffi_prep_args (extended_cif *ecif, unsigned long *const stack)
130
155
  the size of the floating-point parameter are skipped. */
131
156
  case FFI_TYPE_FLOAT:
132
157
  double_tmp = *(float *) *p_argv;
133
- if (fparg_count >= NUM_FPR_ARG_REGISTERS)
134
- *(double *)next_arg = double_tmp;
135
- else
158
+ if (fparg_count < NUM_FPR_ARG_REGISTERS)
136
159
  *fpr_base++ = double_tmp;
160
+ #if defined(POWERPC_DARWIN)
161
+ *(float *)next_arg = *(float *) *p_argv;
162
+ #else
163
+ *(double *)next_arg = double_tmp;
164
+ #endif
137
165
  next_arg++;
166
+ gp_count++;
138
167
  fparg_count++;
139
168
  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
140
169
  break;
141
170
 
142
171
  case FFI_TYPE_DOUBLE:
143
172
  double_tmp = *(double *) *p_argv;
144
- if (fparg_count >= NUM_FPR_ARG_REGISTERS)
145
- *(double *)next_arg = double_tmp;
146
- else
173
+ if (fparg_count < NUM_FPR_ARG_REGISTERS)
147
174
  *fpr_base++ = double_tmp;
175
+ *(double *)next_arg = double_tmp;
148
176
  #ifdef POWERPC64
149
177
  next_arg++;
178
+ gp_count++;
150
179
  #else
151
180
  next_arg += 2;
181
+ gp_count += 2;
152
182
  #endif
153
183
  fparg_count++;
154
184
  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
@@ -157,30 +187,41 @@ ffi_prep_args (extended_cif *ecif, unsigned long *const stack)
157
187
  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
158
188
 
159
189
  case FFI_TYPE_LONGDOUBLE:
160
- #ifdef POWERPC64
190
+ # if defined(POWERPC64) && !defined(POWERPC_DARWIN64)
191
+ /* ??? This will exceed the regs count when the value starts at fp13
192
+ and it will not put the extra bit on the stack. */
161
193
  if (fparg_count < NUM_FPR_ARG_REGISTERS)
162
194
  *(long double *) fpr_base++ = *(long double *) *p_argv;
163
195
  else
164
196
  *(long double *) next_arg = *(long double *) *p_argv;
165
197
  next_arg += 2;
166
198
  fparg_count += 2;
167
- #else
199
+ # else
168
200
  double_tmp = ((double *) *p_argv)[0];
169
201
  if (fparg_count < NUM_FPR_ARG_REGISTERS)
170
202
  *fpr_base++ = double_tmp;
171
- else
172
- *(double *) next_arg = double_tmp;
203
+ *(double *) next_arg = double_tmp;
204
+ # if defined(POWERPC_DARWIN64)
205
+ next_arg++;
206
+ gp_count++;
207
+ # else
173
208
  next_arg += 2;
209
+ gp_count += 2;
210
+ # endif
174
211
  fparg_count++;
175
-
176
212
  double_tmp = ((double *) *p_argv)[1];
177
213
  if (fparg_count < NUM_FPR_ARG_REGISTERS)
178
214
  *fpr_base++ = double_tmp;
179
- else
180
- *(double *) next_arg = double_tmp;
215
+ *(double *) next_arg = double_tmp;
216
+ # if defined(POWERPC_DARWIN64)
217
+ next_arg++;
218
+ gp_count++;
219
+ # else
181
220
  next_arg += 2;
221
+ gp_count += 2;
222
+ # endif
182
223
  fparg_count++;
183
- #endif
224
+ # endif
184
225
  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
185
226
  break;
186
227
  #endif
@@ -192,6 +233,7 @@ ffi_prep_args (extended_cif *ecif, unsigned long *const stack)
192
233
  #else
193
234
  *(long long *) next_arg = *(long long *) *p_argv;
194
235
  next_arg += 2;
236
+ gp_count += 2;
195
237
  #endif
196
238
  break;
197
239
  case FFI_TYPE_POINTER:
@@ -211,32 +253,35 @@ ffi_prep_args (extended_cif *ecif, unsigned long *const stack)
211
253
  goto putgpr;
212
254
 
213
255
  case FFI_TYPE_STRUCT:
214
- #ifdef POWERPC64
215
- dest_cpy = (char *) next_arg;
216
256
  size_al = (*ptr)->size;
217
- if ((*ptr)->elements[0]->type == 3)
257
+ #if defined(POWERPC_DARWIN64)
258
+ next_arg = (unsigned long *)ALIGN((char *)next_arg, (*ptr)->alignment);
259
+ darwin64_pass_struct_by_value (*ptr, (char *) *p_argv,
260
+ (unsigned) size_al,
261
+ (unsigned int *) &fparg_count,
262
+ &fpr_base, &next_arg);
263
+ #else
264
+ dest_cpy = (char *) next_arg;
265
+
266
+ /* If the first member of the struct is a double, then include enough
267
+ padding in the struct size to align it to double-word. */
268
+ if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
218
269
  size_al = ALIGN((*ptr)->size, 8);
219
- if (size_al < 3 && abi == FFI_DARWIN)
220
- dest_cpy += 4 - size_al;
221
270
 
271
+ # if defined(POWERPC64)
272
+ FFI_ASSERT (abi != FFI_DARWIN);
222
273
  memcpy ((char *) dest_cpy, (char *) *p_argv, size_al);
223
274
  next_arg += (size_al + 7) / 8;
224
- #else
225
- dest_cpy = (char *) next_arg;
226
-
275
+ # else
227
276
  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
228
277
  SI 4 bytes) are aligned as if they were those modes.
229
278
  Structures with 3 byte in size are padded upwards. */
230
- size_al = (*ptr)->size;
231
- /* If the first member of the struct is a double, then align
232
- the struct to double-word. */
233
- if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
234
- size_al = ALIGN((*ptr)->size, 8);
235
279
  if (size_al < 3 && abi == FFI_DARWIN)
236
280
  dest_cpy += 4 - size_al;
237
281
 
238
282
  memcpy((char *) dest_cpy, (char *) *p_argv, size_al);
239
283
  next_arg += (size_al + 3) / 4;
284
+ # endif
240
285
  #endif
241
286
  break;
242
287
 
@@ -249,6 +294,7 @@ ffi_prep_args (extended_cif *ecif, unsigned long *const stack)
249
294
  gprvalue = *(unsigned int *) *p_argv;
250
295
  putgpr:
251
296
  *next_arg++ = gprvalue;
297
+ gp_count++;
252
298
  break;
253
299
  default:
254
300
  break;
@@ -262,8 +308,269 @@ ffi_prep_args (extended_cif *ecif, unsigned long *const stack)
262
308
  //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
263
309
  }
264
310
 
311
+ #if defined(POWERPC_DARWIN64)
312
+
313
+ /* See if we can put some of the struct into fprs.
314
+ This should not be called for structures of size 16 bytes, since these are not
315
+ broken out this way. */
316
+ static void
317
+ darwin64_scan_struct_for_floats (ffi_type *s, unsigned *nfpr)
318
+ {
319
+ int i;
320
+
321
+ FFI_ASSERT (s->type == FFI_TYPE_STRUCT)
322
+
323
+ for (i = 0; s->elements[i] != NULL; i++)
324
+ {
325
+ ffi_type *p = s->elements[i];
326
+ switch (p->type)
327
+ {
328
+ case FFI_TYPE_STRUCT:
329
+ darwin64_scan_struct_for_floats (p, nfpr);
330
+ break;
331
+ case FFI_TYPE_LONGDOUBLE:
332
+ (*nfpr) += 2;
333
+ break;
334
+ case FFI_TYPE_DOUBLE:
335
+ case FFI_TYPE_FLOAT:
336
+ (*nfpr) += 1;
337
+ break;
338
+ default:
339
+ break;
340
+ }
341
+ }
342
+ }
343
+
344
+ static int
345
+ darwin64_struct_size_exceeds_gprs_p (ffi_type *s, char *src, unsigned *nfpr)
346
+ {
347
+ unsigned struct_offset=0, i;
348
+
349
+ for (i = 0; s->elements[i] != NULL; i++)
350
+ {
351
+ char *item_base;
352
+ ffi_type *p = s->elements[i];
353
+ /* Find the start of this item (0 for the first one). */
354
+ if (i > 0)
355
+ struct_offset = ALIGN(struct_offset, p->alignment);
356
+
357
+ item_base = src + struct_offset;
358
+
359
+ switch (p->type)
360
+ {
361
+ case FFI_TYPE_STRUCT:
362
+ if (darwin64_struct_size_exceeds_gprs_p (p, item_base, nfpr))
363
+ return 1;
364
+ break;
365
+ case FFI_TYPE_LONGDOUBLE:
366
+ if (*nfpr >= NUM_FPR_ARG_REGISTERS)
367
+ return 1;
368
+ (*nfpr) += 1;
369
+ item_base += 8;
370
+ /* FALL THROUGH */
371
+ case FFI_TYPE_DOUBLE:
372
+ if (*nfpr >= NUM_FPR_ARG_REGISTERS)
373
+ return 1;
374
+ (*nfpr) += 1;
375
+ break;
376
+ case FFI_TYPE_FLOAT:
377
+ if (*nfpr >= NUM_FPR_ARG_REGISTERS)
378
+ return 1;
379
+ (*nfpr) += 1;
380
+ break;
381
+ default:
382
+ /* If we try and place any item, that is non-float, once we've
383
+ exceeded the 8 GPR mark, then we can't fit the struct. */
384
+ if ((unsigned long)item_base >= 8*8)
385
+ return 1;
386
+ break;
387
+ }
388
+ /* now count the size of what we just used. */
389
+ struct_offset += p->size;
390
+ }
391
+ return 0;
392
+ }
393
+
394
+ /* Can this struct be returned by value? */
395
+ int
396
+ darwin64_struct_ret_by_value_p (ffi_type *s)
397
+ {
398
+ unsigned nfp = 0;
399
+
400
+ FFI_ASSERT (s && s->type == FFI_TYPE_STRUCT);
401
+
402
+ /* The largest structure we can return is 8long + 13 doubles. */
403
+ if (s->size > 168)
404
+ return 0;
405
+
406
+ /* We can't pass more than 13 floats. */
407
+ darwin64_scan_struct_for_floats (s, &nfp);
408
+ if (nfp > 13)
409
+ return 0;
410
+
411
+ /* If there are not too many floats, and the struct is
412
+ small enough to accommodate in the GPRs, then it must be OK. */
413
+ if (s->size <= 64)
414
+ return 1;
415
+
416
+ /* Well, we have to look harder. */
417
+ nfp = 0;
418
+ if (darwin64_struct_size_exceeds_gprs_p (s, NULL, &nfp))
419
+ return 0;
420
+
421
+ return 1;
422
+ }
423
+
424
+ void
425
+ darwin64_pass_struct_floats (ffi_type *s, char *src,
426
+ unsigned *nfpr, double **fprs)
427
+ {
428
+ int i;
429
+ double *fpr_base = *fprs;
430
+ unsigned struct_offset = 0;
431
+
432
+ /* We don't assume anything about the alignment of the source. */
433
+ for (i = 0; s->elements[i] != NULL; i++)
434
+ {
435
+ char *item_base;
436
+ ffi_type *p = s->elements[i];
437
+ /* Find the start of this item (0 for the first one). */
438
+ if (i > 0)
439
+ struct_offset = ALIGN(struct_offset, p->alignment);
440
+ item_base = src + struct_offset;
441
+
442
+ switch (p->type)
443
+ {
444
+ case FFI_TYPE_STRUCT:
445
+ darwin64_pass_struct_floats (p, item_base, nfpr,
446
+ &fpr_base);
447
+ break;
448
+ case FFI_TYPE_LONGDOUBLE:
449
+ if (*nfpr < NUM_FPR_ARG_REGISTERS)
450
+ *fpr_base++ = *(double *)item_base;
451
+ (*nfpr) += 1;
452
+ item_base += 8;
453
+ /* FALL THROUGH */
454
+ case FFI_TYPE_DOUBLE:
455
+ if (*nfpr < NUM_FPR_ARG_REGISTERS)
456
+ *fpr_base++ = *(double *)item_base;
457
+ (*nfpr) += 1;
458
+ break;
459
+ case FFI_TYPE_FLOAT:
460
+ if (*nfpr < NUM_FPR_ARG_REGISTERS)
461
+ *fpr_base++ = (double) *(float *)item_base;
462
+ (*nfpr) += 1;
463
+ break;
464
+ default:
465
+ break;
466
+ }
467
+ /* now count the size of what we just used. */
468
+ struct_offset += p->size;
469
+ }
470
+ /* Update the scores. */
471
+ *fprs = fpr_base;
472
+ }
473
+
474
+ /* Darwin64 special rules.
475
+ Break out a struct into params and float registers. */
476
+ static void
477
+ darwin64_pass_struct_by_value (ffi_type *s, char *src, unsigned size,
478
+ unsigned *nfpr, double **fprs, unsigned long **arg)
479
+ {
480
+ unsigned long *next_arg = *arg;
481
+ char *dest_cpy = (char *)next_arg;
482
+
483
+ FFI_ASSERT (s->type == FFI_TYPE_STRUCT)
484
+
485
+ if (!size)
486
+ return;
487
+
488
+ /* First... special cases. */
489
+ if (size < 3
490
+ || (size == 4
491
+ && s->elements[0]
492
+ && s->elements[0]->type != FFI_TYPE_FLOAT))
493
+ {
494
+ /* Must be at least one GPR, padding is unspecified in value,
495
+ let's make it zero. */
496
+ *next_arg = 0UL;
497
+ dest_cpy += 8 - size;
498
+ memcpy ((char *) dest_cpy, src, size);
499
+ next_arg++;
500
+ }
501
+ else if (size == 16)
502
+ {
503
+ memcpy ((char *) dest_cpy, src, size);
504
+ next_arg += 2;
505
+ }
506
+ else
507
+ {
508
+ /* now the general case, we consider embedded floats. */
509
+ memcpy ((char *) dest_cpy, src, size);
510
+ darwin64_pass_struct_floats (s, src, nfpr, fprs);
511
+ next_arg += (size+7)/8;
512
+ }
513
+
514
+ *arg = next_arg;
515
+ }
516
+
517
+ double *
518
+ darwin64_struct_floats_to_mem (ffi_type *s, char *dest, double *fprs, unsigned *nf)
519
+ {
520
+ int i;
521
+ unsigned struct_offset = 0;
522
+
523
+ /* We don't assume anything about the alignment of the source. */
524
+ for (i = 0; s->elements[i] != NULL; i++)
525
+ {
526
+ char *item_base;
527
+ ffi_type *p = s->elements[i];
528
+ /* Find the start of this item (0 for the first one). */
529
+ if (i > 0)
530
+ struct_offset = ALIGN(struct_offset, p->alignment);
531
+ item_base = dest + struct_offset;
532
+
533
+ switch (p->type)
534
+ {
535
+ case FFI_TYPE_STRUCT:
536
+ fprs = darwin64_struct_floats_to_mem (p, item_base, fprs, nf);
537
+ break;
538
+ case FFI_TYPE_LONGDOUBLE:
539
+ if (*nf < NUM_FPR_ARG_REGISTERS)
540
+ {
541
+ *(double *)item_base = *fprs++ ;
542
+ (*nf) += 1;
543
+ }
544
+ item_base += 8;
545
+ /* FALL THROUGH */
546
+ case FFI_TYPE_DOUBLE:
547
+ if (*nf < NUM_FPR_ARG_REGISTERS)
548
+ {
549
+ *(double *)item_base = *fprs++ ;
550
+ (*nf) += 1;
551
+ }
552
+ break;
553
+ case FFI_TYPE_FLOAT:
554
+ if (*nf < NUM_FPR_ARG_REGISTERS)
555
+ {
556
+ *(float *)item_base = (float) *fprs++ ;
557
+ (*nf) += 1;
558
+ }
559
+ break;
560
+ default:
561
+ break;
562
+ }
563
+ /* now count the size of what we just used. */
564
+ struct_offset += p->size;
565
+ }
566
+ return fprs;
567
+ }
568
+
569
+ #endif
570
+
265
571
  /* Adjust the size of S to be correct for Darwin.
266
- On Darwin, the first field of a structure has natural alignment. */
572
+ On Darwin m32, the first field of a structure has natural alignment.
573
+ On Darwin m64, all fields have natural alignment. */
267
574
 
268
575
  static void
269
576
  darwin_adjust_aggregate_sizes (ffi_type *s)
@@ -280,22 +587,29 @@ darwin_adjust_aggregate_sizes (ffi_type *s)
280
587
  int align;
281
588
 
282
589
  p = s->elements[i];
283
- darwin_adjust_aggregate_sizes (p);
284
- if (i == 0
285
- && (p->type == FFI_TYPE_UINT64
286
- || p->type == FFI_TYPE_SINT64
287
- || p->type == FFI_TYPE_DOUBLE
288
- || p->alignment == 8))
289
- align = 8;
590
+ if (p->type == FFI_TYPE_STRUCT)
591
+ darwin_adjust_aggregate_sizes (p);
592
+ #if defined(POWERPC_DARWIN64)
593
+ /* Natural alignment for all items. */
594
+ align = p->alignment;
595
+ #else
596
+ /* Natrual alignment for the first item... */
597
+ if (i == 0)
598
+ align = p->alignment;
290
599
  else if (p->alignment == 16 || p->alignment < 4)
600
+ /* .. subsequent items with vector or align < 4 have natural align. */
291
601
  align = p->alignment;
292
602
  else
603
+ /* .. or align is 4. */
293
604
  align = 4;
605
+ #endif
606
+ /* Pad, if necessary, before adding the current item. */
294
607
  s->size = ALIGN(s->size, align) + p->size;
295
608
  }
296
609
 
297
610
  s->size = ALIGN(s->size, s->alignment);
298
611
 
612
+ /* This should not be necessary on m64, but harmless. */
299
613
  if (s->elements[0]->type == FFI_TYPE_UINT64
300
614
  || s->elements[0]->type == FFI_TYPE_SINT64
301
615
  || s->elements[0]->type == FFI_TYPE_DOUBLE
@@ -344,10 +658,10 @@ ffi_status
344
658
  ffi_prep_cif_machdep (ffi_cif *cif)
345
659
  {
346
660
  /* All this is for the DARWIN ABI. */
347
- int i;
661
+ unsigned i;
348
662
  ffi_type **ptr;
349
663
  unsigned bytes;
350
- int fparg_count = 0, intarg_count = 0;
664
+ unsigned fparg_count = 0, intarg_count = 0;
351
665
  unsigned flags = 0;
352
666
  unsigned size_al = 0;
353
667
 
@@ -372,16 +686,25 @@ ffi_prep_cif_machdep (ffi_cif *cif)
372
686
  /* Space for the frame pointer, callee's LR, CR, etc, and for
373
687
  the asm's temp regs. */
374
688
 
375
- bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
689
+ bytes = (LINKAGE_AREA_GPRS + ASM_NEEDS_REGISTERS) * sizeof(unsigned long);
376
690
 
377
- /* Return value handling. The rules are as follows:
691
+ /* Return value handling.
692
+ The rules m32 are as follows:
378
693
  - 32-bit (or less) integer values are returned in gpr3;
379
- - Structures of size <= 4 bytes also returned in gpr3;
380
- - 64-bit integer values and structures between 5 and 8 bytes are returned
381
- in gpr3 and gpr4;
694
+ - structures of size <= 4 bytes also returned in gpr3;
695
+ - 64-bit integer values [??? and structures between 5 and 8 bytes] are
696
+ returned in gpr3 and gpr4;
382
697
  - Single/double FP values are returned in fpr1;
383
698
  - Long double FP (if not equivalent to double) values are returned in
384
699
  fpr1 and fpr2;
700
+ m64:
701
+ - 64-bit or smaller integral values are returned in GPR3
702
+ - Single/double FP values are returned in fpr1;
703
+ - Long double FP values are returned in fpr1 and fpr2;
704
+ m64 Structures:
705
+ - If the structure could be accommodated in registers were it to be the
706
+ first argument to a routine, then it is returned in those registers.
707
+ m32/m64 structures otherwise:
385
708
  - Larger structures values are allocated space and a pointer is passed
386
709
  as the first argument. */
387
710
  switch (cif->rtype->type)
@@ -410,9 +733,42 @@ ffi_prep_cif_machdep (ffi_cif *cif)
410
733
  break;
411
734
 
412
735
  case FFI_TYPE_STRUCT:
736
+ #if defined(POWERPC_DARWIN64)
737
+ {
738
+ /* Can we fit the struct into regs? */
739
+ if (darwin64_struct_ret_by_value_p (cif->rtype))
740
+ {
741
+ unsigned nfpr = 0;
742
+ flags |= FLAG_RETURNS_STRUCT;
743
+ if (cif->rtype->size != 16)
744
+ darwin64_scan_struct_for_floats (cif->rtype, &nfpr) ;
745
+ else
746
+ flags |= FLAG_RETURNS_128BITS;
747
+ /* Will be 0 for 16byte struct. */
748
+ if (nfpr)
749
+ flags |= FLAG_RETURNS_FP;
750
+ }
751
+ else /* By ref. */
752
+ {
753
+ flags |= FLAG_RETVAL_REFERENCE;
754
+ flags |= FLAG_RETURNS_NOTHING;
755
+ intarg_count++;
756
+ }
757
+ }
758
+ #elif defined(DARWIN_PPC)
759
+ if (cif->rtype->size <= 4)
760
+ flags |= FLAG_RETURNS_STRUCT;
761
+ else /* else by reference. */
762
+ {
763
+ flags |= FLAG_RETVAL_REFERENCE;
764
+ flags |= FLAG_RETURNS_NOTHING;
765
+ intarg_count++;
766
+ }
767
+ #else /* assume we pass by ref. */
413
768
  flags |= FLAG_RETVAL_REFERENCE;
414
769
  flags |= FLAG_RETURNS_NOTHING;
415
770
  intarg_count++;
771
+ #endif
416
772
  break;
417
773
  case FFI_TYPE_VOID:
418
774
  flags |= FLAG_RETURNS_NOTHING;
@@ -425,57 +781,83 @@ ffi_prep_cif_machdep (ffi_cif *cif)
425
781
 
426
782
  /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
427
783
  first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
428
- goes on the stack. Structures are passed as a pointer to a copy of
429
- the structure. Stuff on the stack needs to keep proper alignment. */
784
+ goes on the stack.
785
+ ??? Structures are passed as a pointer to a copy of the structure.
786
+ Stuff on the stack needs to keep proper alignment.
787
+ For m64 the count is effectively of half-GPRs. */
430
788
  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
431
789
  {
790
+ unsigned align_words;
432
791
  switch ((*ptr)->type)
433
792
  {
434
793
  case FFI_TYPE_FLOAT:
435
794
  case FFI_TYPE_DOUBLE:
436
795
  fparg_count++;
796
+ #if !defined(POWERPC_DARWIN64)
437
797
  /* If this FP arg is going on the stack, it must be
438
798
  8-byte-aligned. */
439
799
  if (fparg_count > NUM_FPR_ARG_REGISTERS
440
- && intarg_count%2 != 0)
800
+ && (intarg_count & 0x01) != 0)
441
801
  intarg_count++;
802
+ #endif
442
803
  break;
443
804
 
444
805
  #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
445
-
446
806
  case FFI_TYPE_LONGDOUBLE:
447
807
  fparg_count += 2;
448
808
  /* If this FP arg is going on the stack, it must be
449
- 8-byte-aligned. */
450
- if (fparg_count > NUM_FPR_ARG_REGISTERS
451
- && intarg_count%2 != 0)
452
- intarg_count++;
453
- intarg_count +=2;
809
+ 16-byte-aligned. */
810
+ if (fparg_count >= NUM_FPR_ARG_REGISTERS)
811
+ #if defined (POWERPC64)
812
+ intarg_count = ALIGN(intarg_count, 2);
813
+ #else
814
+ intarg_count = ALIGN(intarg_count, 4);
815
+ #endif
454
816
  break;
455
817
  #endif
456
818
 
457
819
  case FFI_TYPE_UINT64:
458
820
  case FFI_TYPE_SINT64:
821
+ #if defined(POWERPC64)
822
+ intarg_count++;
823
+ #else
459
824
  /* 'long long' arguments are passed as two words, but
460
825
  either both words must fit in registers or both go
461
826
  on the stack. If they go on the stack, they must
462
827
  be 8-byte-aligned. */
463
828
  if (intarg_count == NUM_GPR_ARG_REGISTERS-1
464
- || (intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0))
829
+ || (intarg_count >= NUM_GPR_ARG_REGISTERS
830
+ && (intarg_count & 0x01) != 0))
465
831
  intarg_count++;
466
832
  intarg_count += 2;
833
+ #endif
467
834
  break;
468
835
 
469
836
  case FFI_TYPE_STRUCT:
470
837
  size_al = (*ptr)->size;
838
+ #if defined(POWERPC_DARWIN64)
839
+ align_words = (*ptr)->alignment >> 3;
840
+ if (align_words)
841
+ intarg_count = ALIGN(intarg_count, align_words);
842
+ /* Base size of the struct. */
843
+ intarg_count += (size_al + 7) / 8;
844
+ /* If 16 bytes then don't worry about floats. */
845
+ if (size_al != 16)
846
+ /* Scan through for floats to be placed in regs. */
847
+ darwin64_scan_struct_for_floats (*ptr, &fparg_count) ;
848
+ #else
849
+ align_words = (*ptr)->alignment >> 2;
850
+ if (align_words)
851
+ intarg_count = ALIGN(intarg_count, align_words);
471
852
  /* If the first member of the struct is a double, then align
472
- the struct to double-word. */
853
+ the struct to double-word.
473
854
  if ((*ptr)->elements[0]->type == FFI_TYPE_DOUBLE)
474
- size_al = ALIGN((*ptr)->size, 8);
475
- #ifdef POWERPC64
855
+ size_al = ALIGN((*ptr)->size, 8); */
856
+ # ifdef POWERPC64
476
857
  intarg_count += (size_al + 7) / 8;
477
- #else
858
+ # else
478
859
  intarg_count += (size_al + 3) / 4;
860
+ # endif
479
861
  #endif
480
862
  break;
481
863
 
@@ -490,9 +872,18 @@ ffi_prep_cif_machdep (ffi_cif *cif)
490
872
  if (fparg_count != 0)
491
873
  flags |= FLAG_FP_ARGUMENTS;
492
874
 
875
+ #if defined(POWERPC_DARWIN64)
876
+ /* Space to image the FPR registers, if needed - which includes when they might be
877
+ used in a struct return. */
878
+ if (fparg_count != 0
879
+ || ((flags & FLAG_RETURNS_STRUCT)
880
+ && (flags & FLAG_RETURNS_FP)))
881
+ bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
882
+ #else
493
883
  /* Space for the FPR registers, if needed. */
494
884
  if (fparg_count != 0)
495
885
  bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
886
+ #endif
496
887
 
497
888
  /* Stack space. */
498
889
  #ifdef POWERPC64
@@ -506,7 +897,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
506
897
  bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
507
898
 
508
899
  /* The stack space allocated needs to be a multiple of 16 bytes. */
509
- bytes = (bytes + 15) & ~0xF;
900
+ bytes = ALIGN(bytes, 16) ;
510
901
 
511
902
  cif->flags = flags;
512
903
  cif->bytes = bytes;
@@ -516,8 +907,9 @@ ffi_prep_cif_machdep (ffi_cif *cif)
516
907
 
517
908
  extern void ffi_call_AIX(extended_cif *, long, unsigned, unsigned *,
518
909
  void (*fn)(void), void (*fn2)(void));
910
+
519
911
  extern void ffi_call_DARWIN(extended_cif *, long, unsigned, unsigned *,
520
- void (*fn)(void), void (*fn2)(void));
912
+ void (*fn)(void), void (*fn2)(void), ffi_type*);
521
913
 
522
914
  void
523
915
  ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
@@ -542,11 +934,11 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
542
934
  {
543
935
  case FFI_AIX:
544
936
  ffi_call_AIX(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
545
- ffi_prep_args);
937
+ FFI_FN(ffi_prep_args));
546
938
  break;
547
939
  case FFI_DARWIN:
548
940
  ffi_call_DARWIN(&ecif, -(long)cif->bytes, cif->flags, ecif.rvalue, fn,
549
- ffi_prep_args);
941
+ FFI_FN(ffi_prep_args), cif->rtype);
550
942
  break;
551
943
  default:
552
944
  FFI_ASSERT(0);
@@ -566,58 +958,48 @@ typedef struct aix_fd_struct {
566
958
  } aix_fd;
567
959
 
568
960
  /* here I'd like to add the stack frame layout we use in darwin_closure.S
569
- and aix_clsoure.S
570
-
571
- SP previous -> +---------------------------------------+ <--- child frame
572
- | back chain to caller 4 |
573
- +---------------------------------------+ 4
574
- | saved CR 4 |
575
- +---------------------------------------+ 8
576
- | saved LR 4 |
577
- +---------------------------------------+ 12
578
- | reserved for compilers 4 |
579
- +---------------------------------------+ 16
580
- | reserved for binders 4 |
581
- +---------------------------------------+ 20
582
- | saved TOC pointer 4 |
583
- +---------------------------------------+ 24
584
- | always reserved 8*4=32 (previous GPRs)|
585
- | according to the linkage convention |
586
- | from AIX |
587
- +---------------------------------------+ 56
588
- | our FPR area 13*8=104 |
589
- | f1 |
590
- | . |
591
- | f13 |
592
- +---------------------------------------+ 160
593
- | result area 8 |
594
- +---------------------------------------+ 168
595
- | alignement to the next multiple of 16 |
596
- SP current --> +---------------------------------------+ 176 <- parent frame
597
- | back chain to caller 4 |
598
- +---------------------------------------+ 180
599
- | saved CR 4 |
600
- +---------------------------------------+ 184
601
- | saved LR 4 |
602
- +---------------------------------------+ 188
603
- | reserved for compilers 4 |
604
- +---------------------------------------+ 192
605
- | reserved for binders 4 |
606
- +---------------------------------------+ 196
607
- | saved TOC pointer 4 |
608
- +---------------------------------------+ 200
609
- | always reserved 8*4=32 we store our |
610
- | GPRs here |
611
- | r3 |
612
- | . |
613
- | r10 |
614
- +---------------------------------------+ 232
615
- | overflow part |
616
- +---------------------------------------+ xxx
617
- | ???? |
618
- +---------------------------------------+ xxx
961
+ and aix_closure.S
962
+
963
+ m32/m64
964
+
965
+ The stack layout looks like this:
966
+
967
+ | Additional params... | | Higher address
968
+ ~ ~ ~
969
+ | Parameters (at least 8*4/8=32/64) | | NUM_GPR_ARG_REGISTERS
970
+ |--------------------------------------------| |
971
+ | TOC=R2 (AIX) Reserved (Darwin) 4/8 | |
972
+ |--------------------------------------------| |
973
+ | Reserved 2*4/8 | |
974
+ |--------------------------------------------| |
975
+ | Space for callee's LR 4/8 | |
976
+ |--------------------------------------------| |
977
+ | Saved CR [low word for m64] 4/8 | |
978
+ |--------------------------------------------| |
979
+ | Current backchain pointer 4/8 |-/ Parent's frame.
980
+ |--------------------------------------------| <+ <<< on entry to ffi_closure_ASM
981
+ | Result Bytes 16 | |
982
+ |--------------------------------------------| |
983
+ ~ padding to 16-byte alignment ~ ~
984
+ |--------------------------------------------| |
985
+ | NUM_FPR_ARG_REGISTERS slots | |
986
+ | here fp13 .. fp1 13*8 | |
987
+ |--------------------------------------------| |
988
+ | R3..R10 8*4/8=32/64 | | NUM_GPR_ARG_REGISTERS
989
+ |--------------------------------------------| |
990
+ | TOC=R2 (AIX) Reserved (Darwin) 4/8 | |
991
+ |--------------------------------------------| | stack |
992
+ | Reserved [compiler,binder] 2*4/8 | | grows |
993
+ |--------------------------------------------| | down V
994
+ | Space for callee's LR 4/8 | |
995
+ |--------------------------------------------| | lower addresses
996
+ | Saved CR [low word for m64] 4/8 | |
997
+ |--------------------------------------------| | stack pointer here
998
+ | Current backchain pointer 4/8 |-/ during
999
+ |--------------------------------------------| <<< ffi_closure_ASM.
619
1000
 
620
1001
  */
1002
+
621
1003
  ffi_status
622
1004
  ffi_prep_closure_loc (ffi_closure* closure,
623
1005
  ffi_cif* cif,
@@ -631,30 +1013,44 @@ ffi_prep_closure_loc (ffi_closure* closure,
631
1013
 
632
1014
  switch (cif->abi)
633
1015
  {
634
- case FFI_DARWIN:
635
-
636
- FFI_ASSERT (cif->abi == FFI_DARWIN);
637
-
638
- tramp = (unsigned int *) &closure->tramp[0];
639
- tramp[0] = 0x7c0802a6; /* mflr r0 */
640
- tramp[1] = 0x429f000d; /* bcl- 20,4*cr7+so,0x10 */
641
- tramp[4] = 0x7d6802a6; /* mflr r11 */
642
- tramp[5] = 0x818b0000; /* lwz r12,0(r11) function address */
643
- tramp[6] = 0x7c0803a6; /* mtlr r0 */
644
- tramp[7] = 0x7d8903a6; /* mtctr r12 */
645
- tramp[8] = 0x816b0004; /* lwz r11,4(r11) static chain */
646
- tramp[9] = 0x4e800420; /* bctr */
647
- tramp[2] = (unsigned long) ffi_closure_ASM; /* function */
648
- tramp[3] = (unsigned long) codeloc; /* context */
649
-
650
- closure->cif = cif;
651
- closure->fun = fun;
652
- closure->user_data = user_data;
1016
+ case FFI_DARWIN:
1017
+
1018
+ FFI_ASSERT (cif->abi == FFI_DARWIN);
1019
+
1020
+ tramp = (unsigned int *) &closure->tramp[0];
1021
+ #if defined(POWERPC_DARWIN64)
1022
+ tramp[0] = 0x7c0802a6; /* mflr r0 */
1023
+ tramp[1] = 0x429f0015; /* bcl- 20,4*cr7+so, +0x18 (L1) */
1024
+ /* We put the addresses here. */
1025
+ tramp[6] = 0x7d6802a6; /*L1: mflr r11 */
1026
+ tramp[7] = 0xe98b0000; /* ld r12,0(r11) function address */
1027
+ tramp[8] = 0x7c0803a6; /* mtlr r0 */
1028
+ tramp[9] = 0x7d8903a6; /* mtctr r12 */
1029
+ tramp[10] = 0xe96b0008; /* lwz r11,8(r11) static chain */
1030
+ tramp[11] = 0x4e800420; /* bctr */
1031
+
1032
+ *((unsigned long *)&tramp[2]) = (unsigned long) ffi_closure_ASM; /* function */
1033
+ *((unsigned long *)&tramp[4]) = (unsigned long) codeloc; /* context */
1034
+ #else
1035
+ tramp[0] = 0x7c0802a6; /* mflr r0 */
1036
+ tramp[1] = 0x429f000d; /* bcl- 20,4*cr7+so,0x10 */
1037
+ tramp[4] = 0x7d6802a6; /* mflr r11 */
1038
+ tramp[5] = 0x818b0000; /* lwz r12,0(r11) function address */
1039
+ tramp[6] = 0x7c0803a6; /* mtlr r0 */
1040
+ tramp[7] = 0x7d8903a6; /* mtctr r12 */
1041
+ tramp[8] = 0x816b0004; /* lwz r11,4(r11) static chain */
1042
+ tramp[9] = 0x4e800420; /* bctr */
1043
+ tramp[2] = (unsigned long) ffi_closure_ASM; /* function */
1044
+ tramp[3] = (unsigned long) codeloc; /* context */
1045
+ #endif
1046
+ closure->cif = cif;
1047
+ closure->fun = fun;
1048
+ closure->user_data = user_data;
653
1049
 
654
- /* Flush the icache. Only necessary on Darwin. */
655
- flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
1050
+ /* Flush the icache. Only necessary on Darwin. */
1051
+ flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
656
1052
 
657
- break;
1053
+ break;
658
1054
 
659
1055
  case FFI_AIX:
660
1056
 
@@ -708,7 +1104,7 @@ typedef union
708
1104
  double d;
709
1105
  } ffi_dblfl;
710
1106
 
711
- int
1107
+ ffi_type *
712
1108
  ffi_closure_helper_DARWIN (ffi_closure *, void *,
713
1109
  unsigned long *, ffi_dblfl *);
714
1110
 
@@ -719,7 +1115,7 @@ ffi_closure_helper_DARWIN (ffi_closure *, void *,
719
1115
  up space for a return value, ffi_closure_ASM invokes the
720
1116
  following helper function to do most of the work. */
721
1117
 
722
- int
1118
+ ffi_type *
723
1119
  ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
724
1120
  unsigned long *pgr, ffi_dblfl *pfr)
725
1121
  {
@@ -741,16 +1137,32 @@ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
741
1137
  ffi_cif * cif;
742
1138
  ffi_dblfl * end_pfr = pfr + NUM_FPR_ARG_REGISTERS;
743
1139
  unsigned size_al;
1140
+ #if defined(POWERPC_DARWIN64)
1141
+ unsigned fpsused = 0;
1142
+ #endif
744
1143
 
745
1144
  cif = closure->cif;
746
1145
  avalue = alloca (cif->nargs * sizeof(void *));
747
1146
 
748
- /* Copy the caller's structure return value address so that the closure
749
- returns the data directly to the caller. */
750
1147
  if (cif->rtype->type == FFI_TYPE_STRUCT)
751
1148
  {
1149
+ #if defined(POWERPC_DARWIN64)
1150
+ if (!darwin64_struct_ret_by_value_p (cif->rtype))
1151
+ {
1152
+ /* Won't fit into the regs - return by ref. */
1153
+ rvalue = (void *) *pgr;
1154
+ pgr++;
1155
+ }
1156
+ #elif defined(DARWIN_PPC)
1157
+ if (cif->rtype->size > 4)
1158
+ {
1159
+ rvalue = (void *) *pgr;
1160
+ pgr++;
1161
+ }
1162
+ #else /* assume we return by ref. */
752
1163
  rvalue = (void *) *pgr;
753
1164
  pgr++;
1165
+ #endif
754
1166
  }
755
1167
 
756
1168
  i = 0;
@@ -764,7 +1176,7 @@ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
764
1176
  {
765
1177
  case FFI_TYPE_SINT8:
766
1178
  case FFI_TYPE_UINT8:
767
- #ifdef POWERPC64
1179
+ #if defined(POWERPC64)
768
1180
  avalue[i] = (char *) pgr + 7;
769
1181
  #else
770
1182
  avalue[i] = (char *) pgr + 3;
@@ -774,7 +1186,7 @@ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
774
1186
 
775
1187
  case FFI_TYPE_SINT16:
776
1188
  case FFI_TYPE_UINT16:
777
- #ifdef POWERPC64
1189
+ #if defined(POWERPC64)
778
1190
  avalue[i] = (char *) pgr + 6;
779
1191
  #else
780
1192
  avalue[i] = (char *) pgr + 2;
@@ -784,7 +1196,7 @@ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
784
1196
 
785
1197
  case FFI_TYPE_SINT32:
786
1198
  case FFI_TYPE_UINT32:
787
- #ifdef POWERPC64
1199
+ #if defined(POWERPC64)
788
1200
  avalue[i] = (char *) pgr + 4;
789
1201
  #else
790
1202
  case FFI_TYPE_POINTER:
@@ -794,34 +1206,53 @@ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
794
1206
  break;
795
1207
 
796
1208
  case FFI_TYPE_STRUCT:
797
- #ifdef POWERPC64
798
1209
  size_al = arg_types[i]->size;
799
- if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
800
- size_al = ALIGN (arg_types[i]->size, 8);
801
- if (size_al < 3 && cif->abi == FFI_DARWIN)
802
- avalue[i] = (void *) pgr + 8 - size_al;
803
- else
804
- avalue[i] = (void *) pgr;
1210
+ #if defined(POWERPC_DARWIN64)
1211
+ pgr = (unsigned long *)ALIGN((char *)pgr, arg_types[i]->alignment);
1212
+ if (size_al < 3 || size_al == 4)
1213
+ {
1214
+ avalue[i] = ((char *)pgr)+8-size_al;
1215
+ if (arg_types[i]->elements[0]->type == FFI_TYPE_FLOAT
1216
+ && fpsused < NUM_FPR_ARG_REGISTERS)
1217
+ {
1218
+ *(float *)pgr = (float) *(double *)pfr;
1219
+ pfr++;
1220
+ fpsused++;
1221
+ }
1222
+ }
1223
+ else
1224
+ {
1225
+ if (size_al != 16)
1226
+ pfr = (ffi_dblfl *)
1227
+ darwin64_struct_floats_to_mem (arg_types[i], (char *)pgr,
1228
+ (double *)pfr, &fpsused);
1229
+ avalue[i] = pgr;
1230
+ }
805
1231
  pgr += (size_al + 7) / 8;
806
1232
  #else
807
- /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
808
- SI 4 bytes) are aligned as if they were those modes. */
809
- size_al = arg_types[i]->size;
810
1233
  /* If the first member of the struct is a double, then align
811
1234
  the struct to double-word. */
812
1235
  if (arg_types[i]->elements[0]->type == FFI_TYPE_DOUBLE)
813
1236
  size_al = ALIGN(arg_types[i]->size, 8);
1237
+ # if defined(POWERPC64)
1238
+ FFI_ASSERT (cif->abi != FFI_DARWIN)
1239
+ avalue[i] = pgr;
1240
+ pgr += (size_al + 7) / 8;
1241
+ # else
1242
+ /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
1243
+ SI 4 bytes) are aligned as if they were those modes. */
814
1244
  if (size_al < 3 && cif->abi == FFI_DARWIN)
815
- avalue[i] = (void*) pgr + 4 - size_al;
1245
+ avalue[i] = (char*) pgr + 4 - size_al;
816
1246
  else
817
- avalue[i] = (void*) pgr;
1247
+ avalue[i] = pgr;
818
1248
  pgr += (size_al + 3) / 4;
1249
+ # endif
819
1250
  #endif
820
1251
  break;
821
1252
 
822
1253
  case FFI_TYPE_SINT64:
823
1254
  case FFI_TYPE_UINT64:
824
- #ifdef POWERPC64
1255
+ #if defined(POWERPC64)
825
1256
  case FFI_TYPE_POINTER:
826
1257
  avalue[i] = pgr;
827
1258
  pgr++;
@@ -924,5 +1355,5 @@ ffi_closure_helper_DARWIN (ffi_closure *closure, void *rvalue,
924
1355
  (closure->fun) (cif, rvalue, avalue, closure->user_data);
925
1356
 
926
1357
  /* Tell ffi_closure_ASM to perform return type promotions. */
927
- return cif->rtype->type;
1358
+ return cif->rtype;
928
1359
  }