From 6f0201c803a9a1f0f9b6fd226a42fb8daa223928 Mon Sep 17 00:00:00 2001 From: foxsen <2503799872@qq.com> Date: Tue, 4 Aug 2015 18:25:34 +0800 Subject: [PATCH] various fixes for go closure support. Now all n64 tests passed. --- src/mips/ffi.c | 7 +++++-- src/mips/ffitarget.h | 2 +- src/mips/n32.S | 19 +++++++++++-------- src/mips/o32.S | 2 +- 4 files changed, 18 insertions(+), 12 deletions(-) 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 -- 2.7.4