various fixes for go closure support. Now all n64 tests passed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
diff --git a/src/mips/ffi.c b/src/mips/ffi.c
index 076f1f8..3ed9b48 100644
--- a/src/mips/ffi.c
+++ b/src/mips/ffi.c
@@ -673,8 +673,10 @@ ffi_call_go (ffi_cif *cif, void (*fn)(void), void *rvalue,
#if FFI_CLOSURES
#if defined(FFI_MIPS_O32)
extern void ffi_closure_O32(void);
+extern void ffi_go_closure_O32(void);
#else
extern void ffi_closure_N32(void);
+extern void ffi_go_closure_N32(void);
#endif /* FFI_MIPS_O32 */
ffi_status
@@ -779,7 +781,7 @@ ffi_prep_closure_loc (ffi_closure *closure,
int
ffi_closure_mips_inner_O32 (ffi_cif *cif,
void (*fun)(ffi_cif*, void*, void**, void*),
- void *user_data;
+ void *user_data,
void *rvalue, ffi_arg *ar,
double *fpr)
{
@@ -1064,11 +1066,12 @@ ffi_closure_mips_inner_N32 (ffi_cif *cif,
#if defined(FFI_MIPS_O32)
extern void ffi_closure_O32(void);
+extern void ffi_go_closure_O32(void);
#else
extern void ffi_closure_N32(void);
+extern void ffi_go_closure_N32(void);
#endif /* FFI_MIPS_O32 */
-void
ffi_status
ffi_prep_go_closure (ffi_go_closure* closure, ffi_cif* cif,
void (*fun)(ffi_cif*,void*,void**,void*))
diff --git a/src/mips/ffitarget.h b/src/mips/ffitarget.h
index a201c92..cc89a84 100644
--- a/src/mips/ffitarget.h
+++ b/src/mips/ffitarget.h
@@ -238,7 +238,7 @@ typedef enum ffi_abi {
# define FFI_CLOSURES 1
#define FFI_GO_CLOSURES 1
#if _MIPS_SIM==_ABI64
-#define FFI_TRAMPOLINE_SIZE 52
+#define FFI_TRAMPOLINE_SIZE 56
#else
#define FFI_TRAMPOLINE_SIZE 20
#endif
diff --git a/src/mips/n32.S b/src/mips/n32.S
index 67c82be..750555e 100644
--- a/src/mips/n32.S
+++ b/src/mips/n32.S
@@ -39,7 +39,10 @@
#define fn a5
#define closure a6
-#define SIZEOF_FRAME ( 8 * FFI_SIZEOF_ARG )
+/* Note: to keep stack 16 byte aligned we need even number slots
+ used 9 slots here
+*/
+#define SIZEOF_FRAME ( 10 * FFI_SIZEOF_ARG )
#ifdef __GNUC__
.abicalls
@@ -419,7 +422,7 @@ ffi_go_closure_N32:
.fmask 0x00000000,0
SUBU $sp, SIZEOF_FRAME2
- .cpsetup t9, GP_OFF2, ffi_closure_N32
+ .cpsetup t9, GP_OFF2, ffi_go_closure_N32
REG_S ra, RA_OFF2($sp) # Save return address
REG_S a0, A0_OFF2($sp)
@@ -431,9 +434,9 @@ ffi_go_closure_N32:
# Call ffi_closure_mips_inner_N32 to do the real work.
LA t9, ffi_closure_mips_inner_N32
- REG_L a0, FFI_SIZE_OF_ARG($15) # cif
- REG_L a1, 2*FFI_SIZE_OF_ARG($15) # fun
- mov a2, t7 # userdata=closure
+ REG_L a0, 8($15) # cif
+ REG_L a1, 16($15) # fun
+ move a2, t7 # userdata=closure
ADDU a3, $sp, V0_OFF2 # rvalue
ADDU a4, $sp, A0_OFF2 # ar
ADDU a5, $sp, F12_OFF2 # fpr
@@ -464,9 +467,9 @@ ffi_closure_N32:
# Call ffi_closure_mips_inner_N32 to do the real work.
LA t9, ffi_closure_mips_inner_N32
- REG_L a0, FFI_TRAMPOLINE_SIZE($12) # cif
- REG_L a1, FFI_TRAMPOLINE_SIZE + FFI_SIZE_OF_ARG($12) # fun
- REG_L a2, FFI_TRAMPOLINE_SIZE + 2*FFI_SIZE_OF_ARG($12) # user_data
+ REG_L a0, 56($12) # cif
+ REG_L a1, 64($12) # fun
+ REG_L a2, 72($12) # user_data
ADDU a3, $sp, V0_OFF2
ADDU a4, $sp, A0_OFF2
ADDU a5, $sp, F12_OFF2
diff --git a/src/mips/o32.S b/src/mips/o32.S
index 942a2c8..be2381f 100644
--- a/src/mips/o32.S
+++ b/src/mips/o32.S
@@ -272,7 +272,7 @@ ffi_go_closure_O32:
# prepare arguments for ffi_closure_mips_inner_O32
REG_L a0, 4($15) # cif
REG_L a1, 8($15) # fun
- mov a2, $15 # user_data = go closure
+ move a2, $15 # user_data = go closure
addu a3, $fp, V0_OFF2 # rvalue
addu t9, $fp, A0_OFF2 # ar