ffi 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. data/LICENSE +1 -27
  2. data/Rakefile +9 -12
  3. data/ext/ffi_c/AbstractMemory.c +11 -8
  4. data/ext/ffi_c/AbstractMemory.h +23 -21
  5. data/ext/ffi_c/AutoPointer.c +0 -1
  6. data/ext/ffi_c/Buffer.c +24 -8
  7. data/ext/ffi_c/Call.c +28 -0
  8. data/ext/ffi_c/Call.h +8 -4
  9. data/ext/ffi_c/ClosurePool.c +7 -5
  10. data/ext/ffi_c/DynamicLibrary.c +0 -1
  11. data/ext/ffi_c/Function.c +19 -2
  12. data/ext/ffi_c/MemoryPointer.c +3 -3
  13. data/ext/ffi_c/MethodHandle.c +1 -1
  14. data/ext/ffi_c/Pointer.c +23 -9
  15. data/ext/ffi_c/Struct.c +142 -69
  16. data/ext/ffi_c/Struct.h +16 -7
  17. data/ext/ffi_c/StructLayout.c +92 -55
  18. data/ext/ffi_c/Type.c +5 -22
  19. data/ext/ffi_c/Type.h +1 -1
  20. data/ext/ffi_c/Types.c +8 -2
  21. data/ext/ffi_c/Types.h +2 -0
  22. data/ext/ffi_c/Variadic.c +7 -19
  23. data/ext/ffi_c/endian.h +1 -1
  24. data/ext/ffi_c/extconf.rb +20 -11
  25. data/ext/ffi_c/libffi/ChangeLog +900 -84
  26. data/ext/ffi_c/libffi/ChangeLog.libffi +311 -0
  27. data/ext/ffi_c/libffi/LICENSE +1 -1
  28. data/ext/ffi_c/libffi/Makefile.am +14 -4
  29. data/ext/ffi_c/libffi/Makefile.in +362 -211
  30. data/ext/ffi_c/libffi/README +70 -92
  31. data/ext/ffi_c/libffi/aclocal.m4 +6068 -4586
  32. data/ext/ffi_c/libffi/config.guess +125 -143
  33. data/ext/ffi_c/libffi/config.sub +103 -27
  34. data/ext/ffi_c/libffi/configure +11364 -18497
  35. data/ext/ffi_c/libffi/configure.ac +43 -4
  36. data/ext/ffi_c/libffi/doc/libffi.info +15 -15
  37. data/ext/ffi_c/libffi/doc/libffi.texi +1 -1
  38. data/ext/ffi_c/libffi/doc/stamp-vti +4 -4
  39. data/ext/ffi_c/libffi/doc/version.texi +4 -4
  40. data/ext/ffi_c/libffi/fficonfig.h.in +24 -3
  41. data/ext/ffi_c/libffi/include/Makefile.am +1 -1
  42. data/ext/ffi_c/libffi/include/Makefile.in +97 -50
  43. data/ext/ffi_c/libffi/include/ffi.h.in +8 -2
  44. data/ext/ffi_c/libffi/include/ffi_common.h +24 -0
  45. data/ext/ffi_c/libffi/libtool-version +1 -1
  46. data/ext/ffi_c/libffi/ltmain.sh +7346 -5870
  47. data/ext/ffi_c/libffi/m4/libtool.m4 +7360 -0
  48. data/ext/ffi_c/libffi/m4/ltoptions.m4 +368 -0
  49. data/ext/ffi_c/libffi/m4/ltsugar.m4 +123 -0
  50. data/ext/ffi_c/libffi/m4/ltversion.m4 +23 -0
  51. data/ext/ffi_c/libffi/m4/lt~obsolete.m4 +92 -0
  52. data/ext/ffi_c/libffi/man/Makefile.in +115 -62
  53. data/ext/ffi_c/libffi/man/ffi_call.3 +3 -3
  54. data/ext/ffi_c/libffi/missing +15 -8
  55. data/ext/ffi_c/libffi/src/arm/sysv.S +15 -8
  56. data/ext/ffi_c/libffi/src/avr32/ffi.c +421 -0
  57. data/ext/ffi_c/libffi/src/avr32/ffitarget.h +50 -0
  58. data/ext/ffi_c/libffi/src/avr32/sysv.S +208 -0
  59. data/ext/ffi_c/libffi/src/closures.c +47 -10
  60. data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
  61. data/ext/ffi_c/libffi/src/java_raw_api.c +0 -3
  62. data/ext/ffi_c/libffi/src/mips/ffi.c +135 -32
  63. data/ext/ffi_c/libffi/src/mips/ffitarget.h +37 -4
  64. data/ext/ffi_c/libffi/src/mips/n32.S +67 -10
  65. data/ext/ffi_c/libffi/src/mips/o32.S +8 -8
  66. data/ext/ffi_c/libffi/src/pa/ffi.c +7 -0
  67. data/ext/ffi_c/libffi/src/powerpc/aix.S +163 -64
  68. data/ext/ffi_c/libffi/src/powerpc/aix_closure.S +308 -112
  69. data/ext/ffi_c/libffi/src/powerpc/ffi.c +20 -7
  70. data/ext/ffi_c/libffi/src/powerpc/ffi_darwin.c +208 -80
  71. data/ext/ffi_c/libffi/src/powerpc/ffitarget.h +11 -3
  72. data/ext/ffi_c/libffi/src/powerpc/sysv.S +12 -23
  73. data/ext/ffi_c/libffi/src/s390/sysv.S +1 -1
  74. data/ext/ffi_c/libffi/src/sh/sysv.S +9 -9
  75. data/ext/ffi_c/libffi/src/sh64/ffi.c +37 -22
  76. data/ext/ffi_c/libffi/src/sh64/sysv.S +23 -14
  77. data/ext/ffi_c/libffi/src/sparc/ffi.c +21 -6
  78. data/ext/ffi_c/libffi/src/sparc/v8.S +55 -14
  79. data/ext/ffi_c/libffi/src/x86/darwin.S +10 -9
  80. data/ext/ffi_c/libffi/src/x86/ffi.c +293 -86
  81. data/ext/ffi_c/libffi/src/x86/ffi64.c +73 -19
  82. data/ext/ffi_c/libffi/src/x86/ffitarget.h +30 -0
  83. data/ext/ffi_c/libffi/src/x86/sysv.S +21 -4
  84. data/ext/ffi_c/libffi/src/x86/unix64.S +8 -4
  85. data/ext/ffi_c/libffi/src/x86/win32.S +633 -147
  86. data/ext/ffi_c/libffi/src/x86/win64.S +460 -0
  87. data/ext/ffi_c/libffi/testsuite/Makefile.am +63 -54
  88. data/ext/ffi_c/libffi/testsuite/Makefile.in +112 -77
  89. data/ext/ffi_c/libffi/testsuite/lib/libffi-dg.exp +12 -1
  90. data/ext/ffi_c/libffi/testsuite/libffi.call/call.exp +4 -4
  91. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn0.c +7 -15
  92. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn1.c +7 -15
  93. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn2.c +7 -15
  94. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn3.c +7 -15
  95. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn4.c +7 -15
  96. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn5.c +7 -14
  97. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_fn6.c +7 -15
  98. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_loc_fn0.c +95 -0
  99. data/ext/ffi_c/libffi/testsuite/libffi.call/closure_stdcall.c +6 -14
  100. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_12byte.c +4 -12
  101. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_16byte.c +4 -12
  102. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_18byte.c +4 -12
  103. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_19byte.c +4 -12
  104. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_1_1byte.c +4 -12
  105. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte.c +4 -12
  106. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_20byte1.c +4 -12
  107. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_24byte.c +4 -12
  108. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_2byte.c +4 -12
  109. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3_1byte.c +4 -12
  110. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte1.c +4 -12
  111. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_3byte2.c +4 -12
  112. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4_1byte.c +4 -12
  113. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_4byte.c +4 -12
  114. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5_1_byte.c +4 -12
  115. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_5byte.c +4 -12
  116. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_64byte.c +4 -12
  117. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6_1_byte.c +4 -12
  118. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_6byte.c +4 -12
  119. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7_1_byte.c +4 -12
  120. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_7byte.c +4 -12
  121. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_8byte.c +4 -12
  122. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte1.c +4 -12
  123. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_9byte2.c +4 -12
  124. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_double.c +4 -12
  125. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_float.c +4 -12
  126. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble.c +4 -12
  127. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split.c +134 -0
  128. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_longdouble_split2.c +117 -0
  129. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_pointer.c +11 -17
  130. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint16.c +4 -12
  131. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint32.c +4 -12
  132. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_sint64.c +7 -15
  133. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint16.c +4 -12
  134. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint32.c +4 -12
  135. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_align_uint64.c +7 -15
  136. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_dbls_struct.c +66 -0
  137. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double.c +4 -12
  138. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_double_va.c +57 -0
  139. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_float.c +4 -13
  140. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble.c +105 -0
  141. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_longdouble_va.c +57 -0
  142. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_schar.c +4 -12
  143. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshort.c +4 -12
  144. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_sshortchar.c +4 -12
  145. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_uchar.c +4 -12
  146. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushort.c +4 -12
  147. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_multi_ushortchar.c +4 -12
  148. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer.c +74 -0
  149. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_pointer_stack.c +140 -0
  150. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_schar.c +4 -12
  151. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sint.c +4 -12
  152. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_sshort.c +4 -12
  153. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uchar.c +4 -12
  154. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_uint.c +4 -12
  155. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ulonglong.c +8 -16
  156. data/ext/ffi_c/libffi/testsuite/libffi.call/cls_ushort.c +4 -12
  157. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_abi.c +37 -0
  158. data/ext/ffi_c/libffi/testsuite/libffi.call/err_bad_typedef.c +25 -0
  159. data/ext/ffi_c/libffi/testsuite/libffi.call/ffitest.h +31 -0
  160. data/ext/ffi_c/libffi/testsuite/libffi.call/float2.c +2 -1
  161. data/ext/ffi_c/libffi/testsuite/libffi.call/huge_struct.c +342 -0
  162. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct.c +4 -12
  163. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct1.c +4 -12
  164. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct10.c +4 -12
  165. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct2.c +4 -12
  166. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct3.c +4 -12
  167. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct4.c +4 -12
  168. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct5.c +4 -12
  169. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct6.c +4 -12
  170. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct7.c +4 -12
  171. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct8.c +4 -12
  172. data/ext/ffi_c/libffi/testsuite/libffi.call/nested_struct9.c +4 -12
  173. data/ext/ffi_c/libffi/testsuite/libffi.call/problem1.c +4 -12
  174. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ldl.c +1 -1
  175. data/ext/ffi_c/libffi/testsuite/libffi.call/return_ll1.c +1 -1
  176. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large.c +145 -0
  177. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_large2.c +148 -0
  178. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium.c +124 -0
  179. data/ext/ffi_c/libffi/testsuite/libffi.call/stret_medium2.c +124 -0
  180. data/ext/ffi_c/libffi/testsuite/libffi.call/testclosure.c +70 -0
  181. data/ext/ffi_c/libffi/testsuite/libffi.special/ffitestcxx.h +10 -0
  182. data/ext/ffi_c/libffi/testsuite/libffi.special/special.exp +4 -5
  183. data/ext/ffi_c/libffi/testsuite/libffi.special/unwindtest.cc +17 -16
  184. data/ext/ffi_c/libffi/texinfo.tex +155 -427
  185. data/ext/ffi_c/libffi.bsd.mk +1 -1
  186. data/lib/ffi/autopointer.rb +79 -20
  187. data/lib/ffi/buffer.rb +4 -0
  188. data/lib/ffi/callback.rb +4 -10
  189. data/lib/ffi/enum.rb +28 -0
  190. data/lib/ffi/ffi.rb +0 -1
  191. data/lib/ffi/io.rb +28 -0
  192. data/lib/ffi/library.rb +237 -182
  193. data/lib/ffi/memorypointer.rb +28 -62
  194. data/lib/ffi/platform.rb +27 -0
  195. data/lib/ffi/pointer.rb +28 -0
  196. data/lib/ffi/struct.rb +55 -1
  197. data/lib/ffi/types.rb +29 -0
  198. data/lib/ffi/variadic.rb +29 -0
  199. data/spec/ffi/library_spec.rb +31 -5
  200. data/spec/ffi/managed_struct_spec.rb +1 -1
  201. data/spec/ffi/pointer_spec.rb +1 -1
  202. data/spec/ffi/rbx/attach_function_spec.rb +2 -1
  203. data/spec/ffi/rbx/memory_pointer_spec.rb +2 -1
  204. data/spec/ffi/spec_helper.rb +5 -1
  205. data/spec/ffi/struct_spec.rb +77 -0
  206. metadata +28 -18
  207. data/ext/ffi_c/libffi/TODO +0 -1
  208. data/ext/ffi_c/libffi/ltcf-c.sh +0 -861
  209. data/ext/ffi_c/libffi/ltcf-cxx.sh +0 -1069
  210. data/ext/ffi_c/libffi/ltcf-gcj.sh +0 -700
  211. data/ext/ffi_c/libffi/ltconfig +0 -2862
  212. data/ext/ffi_c/libffi/mkinstalldirs +0 -158
@@ -1,6 +1,6 @@
1
1
  /* -----------------------------------------------------------------------
2
- closures.c - Copyright (c) 2007 Red Hat, Inc.
3
- Copyright (C) 2007 Free Software Foundation, Inc
2
+ closures.c - Copyright (c) 2007, 2009 Red Hat, Inc.
3
+ Copyright (C) 2007, 2009 Free Software Foundation, Inc
4
4
 
5
5
  Code to allocate and deallocate memory for closures.
6
6
 
@@ -44,7 +44,7 @@
44
44
  # define FFI_MMAP_EXEC_WRIT 1
45
45
  # define HAVE_MNTENT 1
46
46
  # endif
47
- # ifdef X86_WIN32
47
+ # if defined(X86_WIN32) || defined(X86_WIN64)
48
48
  /* Windows systems may have Data Execution Protection (DEP) enabled,
49
49
  which requires the use of VirtualMalloc/VirtualFree to alloc/free
50
50
  executable memory. */
@@ -67,7 +67,11 @@
67
67
 
68
68
  #define USE_LOCKS 1
69
69
  #define USE_DL_PREFIX 1
70
+ #ifdef __GNUC__
71
+ #ifndef USE_BUILTIN_FFS
70
72
  #define USE_BUILTIN_FFS 1
73
+ #endif
74
+ #endif
71
75
 
72
76
  /* We need to use mmap, not sbrk. */
73
77
  #define HAVE_MORECORE 0
@@ -97,10 +101,12 @@
97
101
  #include <sys/stat.h>
98
102
  #include <fcntl.h>
99
103
  #include <errno.h>
104
+ #ifndef _MSC_VER
100
105
  #include <unistd.h>
106
+ #endif
101
107
  #include <string.h>
102
108
  #include <stdio.h>
103
- #ifndef X86_WIN32
109
+ #if !defined(X86_WIN32) && !defined(X86_WIN64)
104
110
  #ifdef HAVE_MNTENT
105
111
  #include <mntent.h>
106
112
  #endif /* HAVE_MNTENT */
@@ -159,8 +165,16 @@ selinux_enabled_check (void)
159
165
 
160
166
  #define is_selinux_enabled() 0
161
167
 
162
- #endif
163
- #endif /* X86_WIN32 */
168
+ #endif /* !FFI_MMAP_EXEC_SELINUX */
169
+
170
+ #elif defined (__CYGWIN__)
171
+
172
+ #include <sys/mman.h>
173
+
174
+ /* Cygwin is Linux-like, but not quite that Linux-like. */
175
+ #define is_selinux_enabled() 0
176
+
177
+ #endif /* !defined(X86_WIN32) && !defined(X86_WIN64) */
164
178
 
165
179
  /* Declare all functions defined in dlmalloc.c as static. */
166
180
  static void *dlmalloc(size_t);
@@ -179,11 +193,11 @@ static int dlmalloc_trim(size_t) MAYBE_UNUSED;
179
193
  static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
180
194
  static void dlmalloc_stats(void) MAYBE_UNUSED;
181
195
 
182
- #ifndef X86_WIN32
196
+ #if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__)
183
197
  /* Use these for mmap and munmap within dlmalloc.c. */
184
198
  static void *dlmmap(void *, size_t, int, int, int, off_t);
185
199
  static int dlmunmap(void *, size_t);
186
- #endif /* X86_WIN32 */
200
+ #endif /* !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__) */
187
201
 
188
202
  #define mmap dlmmap
189
203
  #define munmap dlmunmap
@@ -193,7 +207,9 @@ static int dlmunmap(void *, size_t);
193
207
  #undef mmap
194
208
  #undef munmap
195
209
 
196
- #ifndef X86_WIN32
210
+ #if !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__)
211
+
212
+ #if FFI_MMAP_EXEC_SELINUX
197
213
 
198
214
  /* A mutex used to synchronize access to *exec* variables in this file. */
199
215
  static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -464,6 +480,27 @@ dlmmap (void *start, size_t length, int prot,
464
480
  return dlmmap_locked (start, length, prot, flags, offset);
465
481
  }
466
482
 
483
+ #else
484
+
485
+ static void *
486
+ dlmmap (void *start, size_t length, int prot,
487
+ int flags, int fd, off_t offset)
488
+ {
489
+
490
+ assert (start == NULL && length % malloc_getpagesize == 0
491
+ && prot == (PROT_READ | PROT_WRITE)
492
+ && flags == (MAP_PRIVATE | MAP_ANONYMOUS)
493
+ && fd == -1 && offset == 0);
494
+
495
+ #if FFI_CLOSURE_TEST
496
+ printf ("mapping in %zi\n", length);
497
+ #endif
498
+
499
+ return mmap (start, length, prot | PROT_EXEC, flags, fd, offset);
500
+ }
501
+
502
+ #endif
503
+
467
504
  /* Release memory at the given address, as well as the corresponding
468
505
  executable page if it's separate. */
469
506
  static int
@@ -508,7 +545,7 @@ segment_holding_code (mstate m, char* addr)
508
545
  }
509
546
  #endif
510
547
 
511
- #endif /* X86_WIN32 */
548
+ #endif /* !(defined(X86_WIN32) || defined(X86_WIN64)) || defined (__CYGWIN__) */
512
549
 
513
550
  /* Allocate a chunk of memory with the given size. Returns a pointer
514
551
  to the writable address, and sets *CODE to the executable
@@ -1,6 +1,6 @@
1
1
  /* -----------------------------------------------------------------------
2
2
  ffi.c - Copyright (C) 2004 Anthony Green
3
- Copyright (C) 2007 Free Software Foundation, Inc.
3
+ Copyright (C) 2007 Free Software Foundation, Inc.
4
4
  Copyright (C) 2008 Red Hat, Inc.
5
5
 
6
6
  FR-V Foreign Function Interface
@@ -276,9 +276,6 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
276
276
  case FFI_TYPE_SINT16:
277
277
  case FFI_TYPE_SINT32:
278
278
  case FFI_TYPE_INT:
279
- #if FFI_SIZEOF_JAVA_RAW == 4
280
- case FFI_TYPE_POINTER:
281
- #endif
282
279
  *(SINT64 *)rvalue >>= 32;
283
280
  break;
284
281
 
@@ -99,7 +99,7 @@ static void ffi_prep_args(char *stack,
99
99
 
100
100
  p_argv = ecif->avalue;
101
101
 
102
- for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
102
+ for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; i++, p_arg++)
103
103
  {
104
104
  size_t z;
105
105
  unsigned int a;
@@ -123,9 +123,25 @@ static void ffi_prep_args(char *stack,
123
123
 
124
124
  /* The size of a pointer depends on the ABI */
125
125
  if (type == FFI_TYPE_POINTER)
126
- type =
127
- (ecif->cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
126
+ type = (ecif->cif->abi == FFI_N64
127
+ || ecif->cif->abi == FFI_N64_SOFT_FLOAT)
128
+ ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
128
129
 
130
+ if (i < 8 && (ecif->cif->abi == FFI_N32_SOFT_FLOAT
131
+ || ecif->cif->abi == FFI_N64_SOFT_FLOAT))
132
+ {
133
+ switch (type)
134
+ {
135
+ case FFI_TYPE_FLOAT:
136
+ type = FFI_TYPE_UINT32;
137
+ break;
138
+ case FFI_TYPE_DOUBLE:
139
+ type = FFI_TYPE_UINT64;
140
+ break;
141
+ default:
142
+ break;
143
+ }
144
+ }
129
145
  switch (type)
130
146
  {
131
147
  case FFI_TYPE_SINT8:
@@ -205,13 +221,17 @@ static void ffi_prep_args(char *stack,
205
221
  definitions and generates the appropriate flags. */
206
222
 
207
223
  static unsigned
208
- calc_n32_struct_flags(ffi_type *arg, unsigned *loc, unsigned *arg_reg)
224
+ calc_n32_struct_flags(int soft_float, ffi_type *arg,
225
+ unsigned *loc, unsigned *arg_reg)
209
226
  {
210
227
  unsigned flags = 0;
211
228
  unsigned index = 0;
212
229
 
213
230
  ffi_type *e;
214
231
 
232
+ if (soft_float)
233
+ return 0;
234
+
215
235
  while ((e = arg->elements[index]))
216
236
  {
217
237
  /* Align this object. */
@@ -236,7 +256,7 @@ calc_n32_struct_flags(ffi_type *arg, unsigned *loc, unsigned *arg_reg)
236
256
  }
237
257
 
238
258
  static unsigned
239
- calc_n32_return_struct_flags(ffi_type *arg)
259
+ calc_n32_return_struct_flags(int soft_float, ffi_type *arg)
240
260
  {
241
261
  unsigned flags = 0;
242
262
  unsigned small = FFI_TYPE_SMALLSTRUCT;
@@ -256,6 +276,7 @@ calc_n32_return_struct_flags(ffi_type *arg)
256
276
  small = FFI_TYPE_SMALLSTRUCT2;
257
277
 
258
278
  e = arg->elements[0];
279
+
259
280
  if (e->type == FFI_TYPE_DOUBLE)
260
281
  flags = FFI_TYPE_DOUBLE;
261
282
  else if (e->type == FFI_TYPE_FLOAT)
@@ -276,6 +297,8 @@ calc_n32_return_struct_flags(ffi_type *arg)
276
297
  floats! This must be passed the old way. */
277
298
  return small;
278
299
  }
300
+ if (soft_float)
301
+ flags += FFI_TYPE_STRUCT_SOFT;
279
302
  }
280
303
  else
281
304
  if (!flags)
@@ -382,16 +405,19 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
382
405
  #ifdef FFI_MIPS_N32
383
406
  /* Set the flags necessary for N32 processing */
384
407
  {
408
+ int type;
385
409
  unsigned arg_reg = 0;
386
410
  unsigned loc = 0;
387
411
  unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
388
412
  unsigned index = 0;
389
413
 
390
414
  unsigned struct_flags = 0;
415
+ int soft_float = (cif->abi == FFI_N32_SOFT_FLOAT
416
+ || cif->abi == FFI_N64_SOFT_FLOAT);
391
417
 
392
418
  if (cif->rtype->type == FFI_TYPE_STRUCT)
393
419
  {
394
- struct_flags = calc_n32_return_struct_flags(cif->rtype);
420
+ struct_flags = calc_n32_return_struct_flags(soft_float, cif->rtype);
395
421
 
396
422
  if (struct_flags == 0)
397
423
  {
@@ -411,7 +437,22 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
411
437
 
412
438
  while (count-- > 0 && arg_reg < 8)
413
439
  {
414
- switch ((cif->arg_types)[index]->type)
440
+ type = (cif->arg_types)[index]->type;
441
+ if (soft_float)
442
+ {
443
+ switch (type)
444
+ {
445
+ case FFI_TYPE_FLOAT:
446
+ type = FFI_TYPE_UINT32;
447
+ break;
448
+ case FFI_TYPE_DOUBLE:
449
+ type = FFI_TYPE_UINT64;
450
+ break;
451
+ default:
452
+ break;
453
+ }
454
+ }
455
+ switch (type)
415
456
  {
416
457
  case FFI_TYPE_FLOAT:
417
458
  case FFI_TYPE_DOUBLE:
@@ -423,17 +464,25 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
423
464
  /* Align it. */
424
465
  arg_reg = ALIGN(arg_reg, 2);
425
466
  /* Treat it as two adjacent doubles. */
426
- cif->flags +=
427
- (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
428
- arg_reg++;
429
- cif->flags +=
430
- (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
431
- arg_reg++;
467
+ if (soft_float)
468
+ {
469
+ arg_reg += 2;
470
+ }
471
+ else
472
+ {
473
+ cif->flags +=
474
+ (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
475
+ arg_reg++;
476
+ cif->flags +=
477
+ (FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
478
+ arg_reg++;
479
+ }
432
480
  break;
433
481
 
434
482
  case FFI_TYPE_STRUCT:
435
483
  loc = arg_reg * FFI_SIZEOF_ARG;
436
- cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
484
+ cif->flags += calc_n32_struct_flags(soft_float,
485
+ (cif->arg_types)[index],
437
486
  &loc, &arg_reg);
438
487
  break;
439
488
 
@@ -469,17 +518,43 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
469
518
  case FFI_TYPE_VOID:
470
519
  /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
471
520
  break;
472
-
521
+
522
+ case FFI_TYPE_POINTER:
523
+ if (cif->abi == FFI_N32_SOFT_FLOAT || cif->abi == FFI_N32)
524
+ cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
525
+ else
526
+ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
527
+ break;
528
+
473
529
  case FFI_TYPE_FLOAT:
530
+ if (soft_float)
531
+ {
532
+ cif->flags += FFI_TYPE_SINT32 << (FFI_FLAG_BITS * 8);
533
+ break;
534
+ }
535
+ /* else fall through */
474
536
  case FFI_TYPE_DOUBLE:
475
- cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
537
+ if (soft_float)
538
+ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
539
+ else
540
+ cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
476
541
  break;
542
+
477
543
  case FFI_TYPE_LONGDOUBLE:
478
544
  /* Long double is returned as if it were a struct containing
479
545
  two doubles. */
480
- cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
481
- cif->flags += (FFI_TYPE_DOUBLE + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))
482
- << (4 + (FFI_FLAG_BITS * 8));
546
+ if (soft_float)
547
+ {
548
+ cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
549
+ cif->flags += FFI_TYPE_SMALLSTRUCT2 << (4 + (FFI_FLAG_BITS * 8));
550
+ }
551
+ else
552
+ {
553
+ cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
554
+ cif->flags += (FFI_TYPE_DOUBLE
555
+ + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))
556
+ << (4 + (FFI_FLAG_BITS * 8));
557
+ }
483
558
  break;
484
559
  default:
485
560
  cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
@@ -499,7 +574,7 @@ extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
499
574
  /* Low level routine for calling N32 functions */
500
575
  extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
501
576
  extended_cif *, unsigned,
502
- unsigned, unsigned *, void (*)(void));
577
+ unsigned, void *, void (*)(void));
503
578
 
504
579
  void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
505
580
  {
@@ -529,10 +604,13 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
529
604
 
530
605
  #ifdef FFI_MIPS_N32
531
606
  case FFI_N32:
607
+ case FFI_N32_SOFT_FLOAT:
532
608
  case FFI_N64:
609
+ case FFI_N64_SOFT_FLOAT:
533
610
  {
534
611
  int copy_rvalue = 0;
535
- void *rvalue_copy = ecif.rvalue;
612
+ int copy_offset = 0;
613
+ char *rvalue_copy = ecif.rvalue;
536
614
  if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
537
615
  {
538
616
  /* For structures smaller than 16 bytes we clobber memory
@@ -541,10 +619,20 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
541
619
  rvalue_copy = alloca(16);
542
620
  copy_rvalue = 1;
543
621
  }
622
+ else if (cif->rtype->type == FFI_TYPE_FLOAT
623
+ && (cif->abi == FFI_N64_SOFT_FLOAT
624
+ || cif->abi == FFI_N32_SOFT_FLOAT))
625
+ {
626
+ rvalue_copy = alloca (8);
627
+ copy_rvalue = 1;
628
+ #if defined(__MIPSEB__) || defined(_MIPSEB)
629
+ copy_offset = 4;
630
+ #endif
631
+ }
544
632
  ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
545
633
  cif->flags, rvalue_copy, fn);
546
634
  if (copy_rvalue)
547
- memcpy(ecif.rvalue, rvalue_copy, cif->rtype->size);
635
+ memcpy(ecif.rvalue, rvalue_copy + copy_offset, cif->rtype->size);
548
636
  }
549
637
  break;
550
638
  #endif
@@ -684,9 +772,10 @@ ffi_closure_mips_inner_O32 (ffi_closure *closure,
684
772
  {
685
773
  if (i < 2 && !seen_int &&
686
774
  (arg_types[i]->type == FFI_TYPE_FLOAT ||
687
- arg_types[i]->type == FFI_TYPE_DOUBLE))
775
+ arg_types[i]->type == FFI_TYPE_DOUBLE ||
776
+ arg_types[i]->type == FFI_TYPE_LONGDOUBLE))
688
777
  {
689
- #ifdef __MIPSEB__
778
+ #if defined(__MIPSEB__) || defined(_MIPSEB)
690
779
  if (arg_types[i]->type == FFI_TYPE_FLOAT)
691
780
  avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
692
781
  else
@@ -755,7 +844,7 @@ ffi_closure_mips_inner_O32 (ffi_closure *closure,
755
844
  static void
756
845
  copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
757
846
  int argn, unsigned arg_offset, ffi_arg *ar,
758
- ffi_arg *fpr)
847
+ ffi_arg *fpr, int soft_float)
759
848
  {
760
849
  ffi_type **elt_typep = type->elements;
761
850
  while(*elt_typep)
@@ -777,7 +866,7 @@ copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
777
866
 
778
867
  tp = target + offset;
779
868
 
780
- if (elt_type->type == FFI_TYPE_DOUBLE)
869
+ if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float)
781
870
  *(double *)tp = *(double *)fpp;
782
871
  else
783
872
  memcpy(tp, argp + arg_offset, elt_type->size);
@@ -815,8 +904,12 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
815
904
  ffi_arg *avalue;
816
905
  ffi_type **arg_types;
817
906
  int i, avn, argn;
907
+ int soft_float;
908
+ ffi_arg *argp;
818
909
 
819
910
  cif = closure->cif;
911
+ soft_float = cif->abi == FFI_N64_SOFT_FLOAT
912
+ || cif->abi == FFI_N32_SOFT_FLOAT;
820
913
  avalue = alloca (cif->nargs * sizeof (ffi_arg));
821
914
  avaluep = alloca (cif->nargs * sizeof (ffi_arg));
822
915
 
@@ -839,10 +932,16 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
839
932
  while (i < avn)
840
933
  {
841
934
  if (arg_types[i]->type == FFI_TYPE_FLOAT
842
- || arg_types[i]->type == FFI_TYPE_DOUBLE)
935
+ || arg_types[i]->type == FFI_TYPE_DOUBLE
936
+ || arg_types[i]->type == FFI_TYPE_LONGDOUBLE)
843
937
  {
844
- ffi_arg *argp = argn >= 8 ? ar + argn : fpr + argn;
845
- #ifdef __MIPSEB__
938
+ argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn;
939
+ if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((unsigned)argp & (arg_types[i]->alignment-1)))
940
+ {
941
+ argp=(ffi_arg*)ALIGN(argp,arg_types[i]->alignment);
942
+ argn++;
943
+ }
944
+ #if defined(__MIPSEB__) || defined(_MIPSEB)
846
945
  if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
847
946
  avaluep[i] = ((char *) argp) + sizeof (float);
848
947
  else
@@ -856,11 +955,15 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
856
955
  if (arg_types[i]->alignment > sizeof(ffi_arg))
857
956
  argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
858
957
 
859
- ffi_arg *argp = ar + argn;
958
+ argp = ar + argn;
860
959
 
861
960
  /* The size of a pointer depends on the ABI */
862
961
  if (type == FFI_TYPE_POINTER)
863
- type = (cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
962
+ type = (cif->abi == FFI_N64 || cif->abi == FFI_N64_SOFT_FLOAT)
963
+ ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
964
+
965
+ if (soft_float && type == FFI_TYPE_FLOAT)
966
+ type = FFI_TYPE_UINT32;
864
967
 
865
968
  switch (type)
866
969
  {
@@ -901,7 +1004,7 @@ ffi_closure_mips_inner_N32 (ffi_closure *closure,
901
1004
  it was passed in registers. */
902
1005
  avaluep[i] = alloca(arg_types[i]->size);
903
1006
  copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
904
- argn, 0, ar, fpr);
1007
+ argn, 0, ar, fpr, soft_float);
905
1008
 
906
1009
  break;
907
1010
  }
@@ -28,7 +28,10 @@
28
28
  #define LIBFFI_TARGET_H
29
29
 
30
30
  #ifdef linux
31
- #include <asm/sgidefs.h>
31
+ # include <asm/sgidefs.h>
32
+ #else
33
+ # include <sgidefs.h>
34
+ #endif
32
35
  # ifndef _ABIN32
33
36
  # define _ABIN32 _MIPS_SIM_NABI32
34
37
  # endif
@@ -38,7 +41,6 @@
38
41
  # ifndef _ABIO32
39
42
  # define _ABIO32 _MIPS_SIM_ABI32
40
43
  # endif
41
- #endif
42
44
 
43
45
  #if !defined(_MIPS_SIM)
44
46
  -- something is very wrong --
@@ -95,6 +97,15 @@
95
97
  #define FFI_TYPE_STRUCT_DF 189
96
98
  #define FFI_TYPE_STRUCT_SMALL 93
97
99
  #define FFI_TYPE_STRUCT_SMALL2 109
100
+
101
+ /* and for n32 soft float, add 16 * 2^4 */
102
+ #define FFI_TYPE_STRUCT_D_SOFT 317
103
+ #define FFI_TYPE_STRUCT_F_SOFT 301
104
+ #define FFI_TYPE_STRUCT_DD_SOFT 509
105
+ #define FFI_TYPE_STRUCT_FF_SOFT 429
106
+ #define FFI_TYPE_STRUCT_FD_SOFT 493
107
+ #define FFI_TYPE_STRUCT_DF_SOFT 445
108
+ #define FFI_TYPE_STRUCT_SOFT 16
98
109
  #endif
99
110
 
100
111
  #ifdef LIBFFI_ASM
@@ -145,7 +156,8 @@
145
156
  # endif /* _MIPS_SIM==_ABI64 */
146
157
  #endif /* !FFI_MIPS_O32 */
147
158
  #else /* !LIBFFI_ASM */
148
- #ifdef FFI_MIPS_O32
159
+ # ifdef __GNUC__
160
+ # ifdef FFI_MIPS_O32
149
161
  /* O32 stack frames have 32bit integer args */
150
162
  typedef unsigned int ffi_arg __attribute__((__mode__(__SI__)));
151
163
  typedef signed int ffi_sarg __attribute__((__mode__(__SI__)));
@@ -153,7 +165,18 @@ typedef signed int ffi_sarg __attribute__((__mode__(__SI__)));
153
165
  /* N32 and N64 frames have 64bit integer args */
154
166
  typedef unsigned int ffi_arg __attribute__((__mode__(__DI__)));
155
167
  typedef signed int ffi_sarg __attribute__((__mode__(__DI__)));
156
- #endif
168
+ # endif
169
+ # else
170
+ # ifdef FFI_MIPS_O32
171
+ /* O32 stack frames have 32bit integer args */
172
+ typedef __uint32_t ffi_arg;
173
+ typedef __int32_t ffi_sarg;
174
+ # else
175
+ /* N32 and N64 frames have 64bit integer args */
176
+ typedef __uint64_t ffi_arg;
177
+ typedef __int64_t ffi_sarg;
178
+ # endif
179
+ # endif /* __GNUC__ */
157
180
 
158
181
  typedef enum ffi_abi {
159
182
  FFI_FIRST_ABI = 0,
@@ -161,6 +184,8 @@ typedef enum ffi_abi {
161
184
  FFI_N32,
162
185
  FFI_N64,
163
186
  FFI_O32_SOFT_FLOAT,
187
+ FFI_N32_SOFT_FLOAT,
188
+ FFI_N64_SOFT_FLOAT,
164
189
 
165
190
  #ifdef FFI_MIPS_O32
166
191
  #ifdef __mips_soft_float
@@ -170,9 +195,17 @@ typedef enum ffi_abi {
170
195
  #endif
171
196
  #else
172
197
  # if _MIPS_SIM==_ABI64
198
+ # ifdef __mips_soft_float
199
+ FFI_DEFAULT_ABI = FFI_N64_SOFT_FLOAT,
200
+ # else
173
201
  FFI_DEFAULT_ABI = FFI_N64,
202
+ # endif
174
203
  # else
204
+ # ifdef __mips_soft_float
205
+ FFI_DEFAULT_ABI = FFI_N32_SOFT_FLOAT,
206
+ # else
175
207
  FFI_DEFAULT_ABI = FFI_N32,
208
+ # endif
176
209
  # endif
177
210
  #endif
178
211
 
@@ -14,14 +14,14 @@
14
14
  The above copyright notice and this permission notice shall be included
15
15
  in all copies or substantial portions of the Software.
16
16
 
17
- THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
21
- ANY CLAIM, DAMAGES OR
22
- OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
- OTHER DEALINGS IN THE SOFTWARE.
17
+ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ DEALINGS IN THE SOFTWARE.
25
25
  ----------------------------------------------------------------------- */
26
26
 
27
27
  #define LIBFFI_ASM
@@ -40,7 +40,9 @@
40
40
 
41
41
  #define SIZEOF_FRAME ( 8 * FFI_SIZEOF_ARG )
42
42
 
43
+ #ifdef linux
43
44
  .abicalls
45
+ #endif
44
46
  .text
45
47
  .align 2
46
48
  .globl ffi_call_N32
@@ -217,8 +219,10 @@ callit:
217
219
 
218
220
  # Shift the return type flag over
219
221
  SRL t6, 8*FFI_FLAG_BITS
220
-
222
+
223
+ beq t6, FFI_TYPE_SINT32, retint
221
224
  bne t6, FFI_TYPE_INT, retfloat
225
+ retint:
222
226
  jal t9
223
227
  REG_L t4, 4*FFI_SIZEOF_ARG($fp)
224
228
  REG_S v0, 0(t4)
@@ -277,12 +281,58 @@ retstruct_d_f:
277
281
  b epilogue
278
282
 
279
283
  retstruct_f_d:
280
- bne t6, FFI_TYPE_STRUCT_FD, retstruct_small
284
+ bne t6, FFI_TYPE_STRUCT_FD, retstruct_d_soft
281
285
  jal t9
282
286
  REG_L t4, 4*FFI_SIZEOF_ARG($fp)
283
287
  s.s $f0, 0(t4)
284
288
  s.d $f2, 8(t4)
285
289
  b epilogue
290
+
291
+ retstruct_d_soft:
292
+ bne t6, FFI_TYPE_STRUCT_D_SOFT, retstruct_f_soft
293
+ jal t9
294
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
295
+ sd v0, 0(t4)
296
+ b epilogue
297
+
298
+ retstruct_f_soft:
299
+ bne t6, FFI_TYPE_STRUCT_F_SOFT, retstruct_d_d_soft
300
+ jal t9
301
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
302
+ sw v0, 0(t4)
303
+ b epilogue
304
+
305
+ retstruct_d_d_soft:
306
+ bne t6, FFI_TYPE_STRUCT_DD_SOFT, retstruct_f_f_soft
307
+ jal t9
308
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
309
+ sd v0, 0(t4)
310
+ sd v1, 8(t4)
311
+ b epilogue
312
+
313
+ retstruct_f_f_soft:
314
+ bne t6, FFI_TYPE_STRUCT_FF_SOFT, retstruct_d_f_soft
315
+ jal t9
316
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
317
+ sw v0, 0(t4)
318
+ sw v1, 4(t4)
319
+ b epilogue
320
+
321
+ retstruct_d_f_soft:
322
+ bne t6, FFI_TYPE_STRUCT_DF_SOFT, retstruct_f_d_soft
323
+ jal t9
324
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
325
+ sd v0, 0(t4)
326
+ sw v1, 8(t4)
327
+ b epilogue
328
+
329
+ retstruct_f_d_soft:
330
+ bne t6, FFI_TYPE_STRUCT_FD_SOFT, retstruct_small
331
+ jal t9
332
+ REG_L t4, 4*FFI_SIZEOF_ARG($fp)
333
+ sw v0, 0(t4)
334
+ sd v1, 8(t4)
335
+ b epilogue
286
336
 
287
337
  retstruct_small:
288
338
  bne t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2
@@ -413,6 +463,11 @@ ffi_closure_N32:
413
463
  jalr t9
414
464
 
415
465
  # Return flags are in v0
466
+ bne v0, FFI_TYPE_SINT32, cls_retint
467
+ lw v0, V0_OFF2($sp)
468
+ b cls_epilogue
469
+
470
+ cls_retint:
416
471
  bne v0, FFI_TYPE_INT, cls_retfloat
417
472
  REG_L v0, V0_OFF2($sp)
418
473
  b cls_epilogue
@@ -474,6 +529,7 @@ cls_epilogue:
474
529
  .LFE2:
475
530
  .end ffi_closure_N32
476
531
 
532
+ #ifdef linux
477
533
  .section .eh_frame,"aw",@progbits
478
534
  .Lframe1:
479
535
  .4byte .LECIE1-.LSCIE1 # length
@@ -530,5 +586,6 @@ cls_epilogue:
530
586
  .uleb128 (SIZEOF_FRAME2 - RA_OFF2)/4
531
587
  .align EH_FRAME_ALIGN
532
588
  .LEFDE3:
589
+ #endif /* linux */
533
590
 
534
591
  #endif