| From 655e82c92d5c3875aee04322f1993d6b0774a7bf Mon Sep 17 00:00:00 2001 |
| From: Yousong Zhou <yszhou4tech@gmail.com> |
| Date: Mon, 15 Aug 2016 15:00:13 +0800 |
| Subject: [PATCH] mips: fix MIPS softfloat build issue |
| |
| The patch for o32.S is taken from OpenWrt packages repo 3a7a4bf "libffi: |
| fix MIPS softfloat build issue with current binutils" |
| |
| Signed-off-by: Felix Fietkau <nbd@openwrt.org> |
| Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com> |
| --- |
| Upstream-Status: Backport [https://github.com/libffi/libffi/commit/2ded2a4f494165c93293afc14ab0be1243cf8c49] |
| src/mips/n32.S | 17 +++++++++++++++++ |
| src/mips/o32.S | 17 +++++++++++++++++ |
| 2 files changed, 34 insertions(+) |
| |
| diff --git a/src/mips/n32.S b/src/mips/n32.S |
| index c6985d3..8f25994 100644 |
| --- a/src/mips/n32.S |
| +++ b/src/mips/n32.S |
| @@ -107,6 +107,16 @@ loadregs: |
| |
| REG_L t6, 3*FFI_SIZEOF_ARG($fp) # load the flags word into t6. |
| |
| +#ifdef __mips_soft_float |
| + REG_L a0, 0*FFI_SIZEOF_ARG(t9) |
| + REG_L a1, 1*FFI_SIZEOF_ARG(t9) |
| + REG_L a2, 2*FFI_SIZEOF_ARG(t9) |
| + REG_L a3, 3*FFI_SIZEOF_ARG(t9) |
| + REG_L a4, 4*FFI_SIZEOF_ARG(t9) |
| + REG_L a5, 5*FFI_SIZEOF_ARG(t9) |
| + REG_L a6, 6*FFI_SIZEOF_ARG(t9) |
| + REG_L a7, 7*FFI_SIZEOF_ARG(t9) |
| +#else |
| and t4, t6, ((1<<FFI_FLAG_BITS)-1) |
| REG_L a0, 0*FFI_SIZEOF_ARG(t9) |
| beqz t4, arg1_next |
| @@ -193,6 +203,7 @@ arg7_next: |
| arg8_doublep: |
| l.d $f19, 7*FFI_SIZEOF_ARG(t9) |
| arg8_next: |
| +#endif |
| |
| callit: |
| # Load the function pointer |
| @@ -214,6 +225,7 @@ retint: |
| b epilogue |
| |
| retfloat: |
| +#ifndef __mips_soft_float |
| bne t6, FFI_TYPE_FLOAT, retdouble |
| jal t9 |
| REG_L t4, 4*FFI_SIZEOF_ARG($fp) |
| @@ -272,6 +284,7 @@ retstruct_f_d: |
| s.s $f0, 0(t4) |
| s.d $f2, 8(t4) |
| b epilogue |
| +#endif |
| |
| retstruct_d_soft: |
| bne t6, FFI_TYPE_STRUCT_D_SOFT, retstruct_f_soft |
| @@ -429,6 +442,7 @@ ffi_closure_N32: |
| REG_S a6, A6_OFF2($sp) |
| REG_S a7, A7_OFF2($sp) |
| |
| +#ifndef __mips_soft_float |
| # Store all possible float/double registers. |
| s.d $f12, F12_OFF2($sp) |
| s.d $f13, F13_OFF2($sp) |
| @@ -438,6 +452,7 @@ ffi_closure_N32: |
| s.d $f17, F17_OFF2($sp) |
| s.d $f18, F18_OFF2($sp) |
| s.d $f19, F19_OFF2($sp) |
| +#endif |
| |
| # Call ffi_closure_mips_inner_N32 to do the real work. |
| LA t9, ffi_closure_mips_inner_N32 |
| @@ -458,6 +473,7 @@ cls_retint: |
| b cls_epilogue |
| |
| cls_retfloat: |
| +#ifndef __mips_soft_float |
| bne v0, FFI_TYPE_FLOAT, cls_retdouble |
| l.s $f0, V0_OFF2($sp) |
| b cls_epilogue |
| @@ -500,6 +516,7 @@ cls_retstruct_f_d: |
| l.s $f0, V0_OFF2($sp) |
| l.d $f2, V1_OFF2($sp) |
| b cls_epilogue |
| +#endif |
| |
| cls_retstruct_small2: |
| REG_L v0, V0_OFF2($sp) |
| diff --git a/src/mips/o32.S b/src/mips/o32.S |
| index eb27981..429dd0a 100644 |
| --- a/src/mips/o32.S |
| +++ b/src/mips/o32.S |
| @@ -82,13 +82,16 @@ sixteen: |
| |
| ADDU $sp, 4 * FFI_SIZEOF_ARG # adjust $sp to new args |
| |
| +#ifndef __mips_soft_float |
| bnez t0, pass_d # make it quick for int |
| +#endif |
| REG_L a0, 0*FFI_SIZEOF_ARG($sp) # just go ahead and load the |
| REG_L a1, 1*FFI_SIZEOF_ARG($sp) # four regs. |
| REG_L a2, 2*FFI_SIZEOF_ARG($sp) |
| REG_L a3, 3*FFI_SIZEOF_ARG($sp) |
| b call_it |
| |
| +#ifndef __mips_soft_float |
| pass_d: |
| bne t0, FFI_ARGS_D, pass_f |
| l.d $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args |
| @@ -130,6 +133,7 @@ pass_f_d: |
| # bne t0, FFI_ARGS_F_D, call_it |
| l.s $f12, 0*FFI_SIZEOF_ARG($sp) # load $fp regs from args |
| l.d $f14, 2*FFI_SIZEOF_ARG($sp) # passing double and float |
| +#endif |
| |
| call_it: |
| # Load the function pointer |
| @@ -158,14 +162,23 @@ retfloat: |
| bne t2, FFI_TYPE_FLOAT, retdouble |
| jalr t9 |
| REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) |
| +#ifndef __mips_soft_float |
| s.s $f0, 0(t0) |
| +#else |
| + REG_S v0, 0(t0) |
| +#endif |
| b epilogue |
| |
| retdouble: |
| bne t2, FFI_TYPE_DOUBLE, noretval |
| jalr t9 |
| REG_L t0, SIZEOF_FRAME + 4*FFI_SIZEOF_ARG($fp) |
| +#ifndef __mips_soft_float |
| s.d $f0, 0(t0) |
| +#else |
| + REG_S v1, 4(t0) |
| + REG_S v0, 0(t0) |
| +#endif |
| b epilogue |
| |
| noretval: |
| @@ -261,9 +274,11 @@ $LCFI7: |
| li $13, 1 # FFI_O32 |
| bne $16, $13, 1f # Skip fp save if FFI_O32_SOFT_FLOAT |
| |
| +#ifndef __mips_soft_float |
| # Store all possible float/double registers. |
| s.d $f12, FA_0_0_OFF2($fp) |
| s.d $f14, FA_1_0_OFF2($fp) |
| +#endif |
| 1: |
| # Call ffi_closure_mips_inner_O32 to do the work. |
| la t9, ffi_closure_mips_inner_O32 |
| @@ -281,6 +296,7 @@ $LCFI7: |
| li $13, 1 # FFI_O32 |
| bne $16, $13, 1f # Skip fp restore if FFI_O32_SOFT_FLOAT |
| |
| +#ifndef __mips_soft_float |
| li $9, FFI_TYPE_FLOAT |
| l.s $f0, V0_OFF2($fp) |
| beq $8, $9, closure_done |
| @@ -288,6 +304,7 @@ $LCFI7: |
| li $9, FFI_TYPE_DOUBLE |
| l.d $f0, V0_OFF2($fp) |
| beq $8, $9, closure_done |
| +#endif |
| 1: |
| REG_L $3, V1_OFF2($fp) |
| REG_L $2, V0_OFF2($fp) |
| -- |
| 2.9.3 |
| |