<div dir="ltr">(I think you meant to send this to linux-yocto@...)</div><div class="gmail_extra"><br><div class="gmail_quote">On 15 July 2015 at 21:15, Yang Shi <span dir="ltr"><<a href="mailto:yang.shi@windriver.com" target="_blank">yang.shi@windriver.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Manuel Lauss <<a href="mailto:manuel.lauss@gmail.com">manuel.lauss@gmail.com</a>><br>
<br>
commit 842dfc11ea9a21f9825167c8a4f2834b205b0a79 upstream<br>
<br>
Starting with version 2.24.51.20140728 MIPS binutils complain loudly<br>
about mixing soft-float and hard-float object files, leading to this<br>
build failure since GCC is invoked with "-msoft-float" on MIPS:<br>
<br>
{standard input}: Warning: .gnu_attribute 4,3 requires `softfloat'<br>
LD arch/mips/alchemy/common/built-in.o<br>
mipsel-softfloat-linux-gnu-ld: Warning: arch/mips/alchemy/common/built-in.o<br>
uses -msoft-float (set by arch/mips/alchemy/common/prom.o),<br>
arch/mips/alchemy/common/sleeper.o uses -mhard-float<br>
<br>
To fix this, we detect if GAS is new enough to support "-msoft-float" command<br>
option, and if it does, we can let GCC pass it to GAS; but then we also need<br>
to sprinkle the files which make use of floating point registers with the<br>
necessary ".set hardfloat" directives.<br>
<br>
Signed-off-by: Manuel Lauss <<a href="mailto:manuel.lauss@gmail.com">manuel.lauss@gmail.com</a>><br>
Cc: Linux-MIPS <<a href="mailto:linux-mips@linux-mips.org">linux-mips@linux-mips.org</a>><br>
Cc: Matthew Fortune <<a href="mailto:Matthew.Fortune@imgtec.com">Matthew.Fortune@imgtec.com</a>><br>
Cc: Markos Chandras <<a href="mailto:Markos.Chandras@imgtec.com">Markos.Chandras@imgtec.com</a>><br>
Cc: Maciej W. Rozycki <<a href="mailto:macro@linux-mips.org">macro@linux-mips.org</a>><br>
Patchwork: <a href="https://patchwork.linux-mips.org/patch/8355/" rel="noreferrer" target="_blank">https://patchwork.linux-mips.org/patch/8355/</a><br>
Signed-off-by: Ralf Baechle <<a href="mailto:ralf@linux-mips.org">ralf@linux-mips.org</a>><br>
[yshi: Backported to Yocto 3.14 kernel]<br>
Signed-off-by: Yang Shi <<a href="mailto:yang.shi@windriver.com">yang.shi@windriver.com</a>><br>
---<br>
arch/mips/Makefile | 9 +++++++++<br>
arch/mips/include/asm/asmmacro-32.h | 6 ++++++<br>
arch/mips/include/asm/asmmacro.h | 7 +++++++<br>
arch/mips/include/asm/fpregdef.h | 14 ++++++++++++++<br>
arch/mips/include/asm/mipsregs.h | 11 ++++++++++-<br>
arch/mips/kernel/branch.c | 6 +-----<br>
arch/mips/kernel/genex.S | 1 +<br>
arch/mips/kernel/r2300_fpu.S | 6 ++++++<br>
arch/mips/kernel/r2300_switch.S | 5 +++++<br>
arch/mips/kernel/r4k_fpu.S | 27 +++++++++++++++++++++++++--<br>
arch/mips/kernel/r4k_switch.S | 11 ++++++++++-<br>
arch/mips/kernel/r6000_fpu.S | 5 +++++<br>
arch/mips/math-emu/cp1emu.c | 6 +-----<br>
13 files changed, 100 insertions(+), 14 deletions(-)<br>
<br>
diff --git a/arch/mips/Makefile b/arch/mips/Makefile<br>
index 69bd6f7..c1a7f83 100644<br>
--- a/arch/mips/Makefile<br>
+++ b/arch/mips/Makefile<br>
@@ -96,6 +96,15 @@ KBUILD_AFLAGS_MODULE += -mlong-calls<br>
KBUILD_CFLAGS_MODULE += -mlong-calls<br>
endif<br>
<br>
+#<br>
+# pass -msoft-float to GAS if it supports it. However on newer binutils<br>
+# (specifically newer than 2.24.51.20140728) we then also need to explicitly<br>
+# set ".set hardfloat" in all files which manipulate floating point registers.<br>
+#<br>
+ifneq ($(call as-option,-Wa$(comma)-msoft-float,),)<br>
+ cflags-y += -DGAS_HAS_SET_HARDFLOAT -Wa,-msoft-float<br>
+endif<br>
+<br>
cflags-y += -ffreestanding<br>
<br>
#<br>
diff --git a/arch/mips/include/asm/asmmacro-32.h b/arch/mips/include/asm/asmmacro-32.h<br>
index 70e1f17..8038647 100644<br>
--- a/arch/mips/include/asm/asmmacro-32.h<br>
+++ b/arch/mips/include/asm/asmmacro-32.h<br>
@@ -13,6 +13,8 @@<br>
#include <asm/mipsregs.h><br>
<br>
.macro fpu_save_single thread tmp=t0<br>
+ .set push<br>
+ SET_HARDFLOAT<br>
cfc1 \tmp, fcr31<br>
swc1 $f0, THREAD_FPR0(\thread)<br>
swc1 $f1, THREAD_FPR1(\thread)<br>
@@ -47,9 +49,12 @@<br>
swc1 $f30, THREAD_FPR30(\thread)<br>
swc1 $f31, THREAD_FPR31(\thread)<br>
sw \tmp, THREAD_FCR31(\thread)<br>
+ .set pop<br>
.endm<br>
<br>
.macro fpu_restore_single thread tmp=t0<br>
+ .set push<br>
+ SET_HARDFLOAT<br>
lw \tmp, THREAD_FCR31(\thread)<br>
lwc1 $f0, THREAD_FPR0(\thread)<br>
lwc1 $f1, THREAD_FPR1(\thread)<br>
@@ -84,6 +89,7 @@<br>
lwc1 $f30, THREAD_FPR30(\thread)<br>
lwc1 $f31, THREAD_FPR31(\thread)<br>
ctc1 \tmp, fcr31<br>
+ .set pop<br>
.endm<br>
<br>
.macro cpu_save_nonscratch thread<br>
diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h<br>
index 4225e99..d6d5b19 100644<br>
--- a/arch/mips/include/asm/asmmacro.h<br>
+++ b/arch/mips/include/asm/asmmacro.h<br>
@@ -74,6 +74,8 @@<br>
#endif /* CONFIG_MIPS_MT_SMTC */<br>
<br>
.macro fpu_save_16even thread tmp=t0<br>
+ .set push<br>
+ SET_HARDFLOAT<br>
cfc1 \tmp, fcr31<br>
sdc1 $f0, THREAD_FPR0(\thread)<br>
sdc1 $f2, THREAD_FPR2(\thread)<br>
@@ -92,11 +94,13 @@<br>
sdc1 $f28, THREAD_FPR28(\thread)<br>
sdc1 $f30, THREAD_FPR30(\thread)<br>
sw \tmp, THREAD_FCR31(\thread)<br>
+ .set pop<br>
.endm<br>
<br>
.macro fpu_save_16odd thread<br>
.set push<br>
.set mips64r2<br>
+ SET_HARDFLOAT<br>
sdc1 $f1, THREAD_FPR1(\thread)<br>
sdc1 $f3, THREAD_FPR3(\thread)<br>
sdc1 $f5, THREAD_FPR5(\thread)<br>
@@ -127,6 +131,8 @@<br>
.endm<br>
<br>
.macro fpu_restore_16even thread tmp=t0<br>
+ .set push<br>
+ SET_HARDFLOAT<br>
lw \tmp, THREAD_FCR31(\thread)<br>
ldc1 $f0, THREAD_FPR0(\thread)<br>
ldc1 $f2, THREAD_FPR2(\thread)<br>
@@ -150,6 +156,7 @@<br>
.macro fpu_restore_16odd thread<br>
.set push<br>
.set mips64r2<br>
+ SET_HARDFLOAT<br>
ldc1 $f1, THREAD_FPR1(\thread)<br>
ldc1 $f3, THREAD_FPR3(\thread)<br>
ldc1 $f5, THREAD_FPR5(\thread)<br>
diff --git a/arch/mips/include/asm/fpregdef.h b/arch/mips/include/asm/fpregdef.h<br>
index 429481f..f184ba0 100644<br>
--- a/arch/mips/include/asm/fpregdef.h<br>
+++ b/arch/mips/include/asm/fpregdef.h<br>
@@ -14,6 +14,20 @@<br>
<br>
#include <asm/sgidefs.h><br>
<br>
+/*<br>
+ * starting with binutils 2.24.51.20140729, MIPS binutils warn about mixing<br>
+ * hardfloat and softfloat object files. The kernel build uses soft-float by<br>
+ * default, so we also need to pass -msoft-float along to GAS if it supports it.<br>
+ * But this in turn causes assembler errors in files which access hardfloat<br>
+ * registers. We detect if GAS supports "-msoft-float" in the Makefile and<br>
+ * explicitly put ".set hardfloat" where floating point registers are touched.<br>
+ */<br>
+#ifdef GAS_HAS_SET_HARDFLOAT<br>
+#define SET_HARDFLOAT .set hardfloat<br>
+#else<br>
+#define SET_HARDFLOAT<br>
+#endif<br>
+<br>
#if _MIPS_SIM == _MIPS_SIM_ABI32<br>
<br>
/*<br>
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h<br>
index d6a8ced..67a209f 100644<br>
--- a/arch/mips/include/asm/mipsregs.h<br>
+++ b/arch/mips/include/asm/mipsregs.h<br>
@@ -1518,7 +1518,7 @@ do { \<br>
/*<br>
* Macros to access the floating point coprocessor control registers<br>
*/<br>
-#define read_32bit_cp1_register(source) \<br>
+#define _read_32bit_cp1_register(source, gas_hardfloat) \<br>
({ \<br>
int __res; \<br>
\<br>
@@ -1528,12 +1528,21 @@ do { \<br>
" # gas fails to assemble cfc1 for some archs, \n" \<br>
" # like Octeon. \n" \<br>
" .set mips1 \n" \<br>
+ " "STR(gas_hardfloat)" \n" \<br>
" cfc1 %0,"STR(source)" \n" \<br>
" .set pop \n" \<br>
: "=r" (__res)); \<br>
__res; \<br>
})<br>
<br>
+#ifdef GAS_HAS_SET_HARDFLOAT<br>
+#define read_32bit_cp1_register(source) \<br>
+ _read_32bit_cp1_register(source, .set hardfloat)<br>
+#else<br>
+#define read_32bit_cp1_register(source) \<br>
+ _read_32bit_cp1_register(source, )<br>
+#endif<br>
+<br>
#ifdef HAVE_AS_DSP<br>
#define rddsp(mask) \<br>
({ \<br>
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c<br>
index ecba7eb..d14383d 100644<br>
--- a/arch/mips/kernel/branch.c<br>
+++ b/arch/mips/kernel/branch.c<br>
@@ -438,11 +438,7 @@ static unsigned int __get_fcr31(void)<br>
<br>
preempt_disable();<br>
if (is_fpu_owner())<br>
- asm volatile(<br>
- ".set push\n"<br>
- "\t.set mips1\n"<br>
- "\tcfc1\t%0,$31\n"<br>
- "\t.set pop" : "=r" (fcr31));<br>
+ fcr31 = read_32bit_cp1_register(CP1_STATUS);<br>
else<br>
fcr31 = current->thread.fpu.fcr31;<br>
preempt_enable();<br>
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S<br>
index eb59fed..7b7611a 100644<br>
--- a/arch/mips/kernel/genex.S<br>
+++ b/arch/mips/kernel/genex.S<br>
@@ -432,6 +432,7 @@ NESTED(nmi_handler, PT_SIZE, sp)<br>
.set push<br>
/* gas fails to assemble cfc1 for some archs (octeon).*/ \<br>
.set mips1<br>
+ SET_HARDFLOAT<br>
cfc1 a1, fcr31<br>
li a2, ~(0x3f << 12)<br>
and a2, a1<br>
diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S<br>
index f31063d..5ce3b74 100644<br>
--- a/arch/mips/kernel/r2300_fpu.S<br>
+++ b/arch/mips/kernel/r2300_fpu.S<br>
@@ -28,6 +28,8 @@<br>
.set mips1<br>
/* Save floating point context */<br>
LEAF(_save_fp_context)<br>
+ .set push<br>
+ SET_HARDFLOAT<br>
li v0, 0 # assume success<br>
cfc1 t1,fcr31<br>
EX(swc1 $f0,(SC_FPREGS+0)(a0))<br>
@@ -65,6 +67,7 @@ LEAF(_save_fp_context)<br>
EX(sw t1,(SC_FPC_CSR)(a0))<br>
cfc1 t0,$0 # implementation/version<br>
jr ra<br>
+ .set pop<br>
.set nomacro<br>
EX(sw t0,(SC_FPC_EIR)(a0))<br>
.set macro<br>
@@ -80,6 +83,8 @@ LEAF(_save_fp_context)<br>
* stack frame which might have been changed by the user.<br>
*/<br>
LEAF(_restore_fp_context)<br>
+ .set push<br>
+ SET_HARDFLOAT<br>
li v0, 0 # assume success<br>
EX(lw t0,(SC_FPC_CSR)(a0))<br>
EX(lwc1 $f0,(SC_FPREGS+0)(a0))<br>
@@ -116,6 +121,7 @@ LEAF(_restore_fp_context)<br>
EX(lwc1 $f31,(SC_FPREGS+248)(a0))<br>
jr ra<br>
ctc1 t0,fcr31<br>
+ .set pop<br>
END(_restore_fp_context)<br>
.set reorder<br>
<br>
diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S<br>
index 20b7b04..435ea65 100644<br>
--- a/arch/mips/kernel/r2300_switch.S<br>
+++ b/arch/mips/kernel/r2300_switch.S<br>
@@ -120,6 +120,9 @@ LEAF(_restore_fp)<br>
<br>
#define FPU_DEFAULT 0x00000000<br>
<br>
+ .set push<br>
+ SET_HARDFLOAT<br>
+<br>
LEAF(_init_fpu)<br>
mfc0 t0, CP0_STATUS<br>
li t1, ST0_CU1<br>
@@ -165,3 +168,5 @@ LEAF(_init_fpu)<br>
mtc1 t0, $f31<br>
jr ra<br>
END(_init_fpu)<br>
+<br>
+ .set pop<br>
diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S<br>
index 73b0ddf..06f8b2a 100644<br>
--- a/arch/mips/kernel/r4k_fpu.S<br>
+++ b/arch/mips/kernel/r4k_fpu.S<br>
@@ -19,8 +19,12 @@<br>
#include <asm/asm-offsets.h><br>
#include <asm/regdef.h><br>
<br>
+/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */<br>
+#undef fp<br>
+<br>
.macro EX insn, reg, src<br>
.set push<br>
+ SET_HARDFLOAT<br>
.set nomacro<br>
.ex\@: \insn \reg, \src<br>
.set pop<br>
@@ -33,12 +37,17 @@<br>
.set mips3<br>
<br>
LEAF(_save_fp_context)<br>
+ .set push<br>
+ SET_HARDFLOAT<br>
cfc1 t1, fcr31<br>
+ .set pop<br>
<br>
#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)<br>
.set push<br>
+ SET_HARDFLOAT<br>
#ifdef CONFIG_CPU_MIPS32_R2<br>
- .set mips64r2<br>
+ .set mips32r2<br>
+ .set fp=64<br>
mfc0 t0, CP0_STATUS<br>
sll t0, t0, 5<br>
bgez t0, 1f # skip storing odd if FR=0<br>
@@ -64,6 +73,8 @@ LEAF(_save_fp_context)<br>
1: .set pop<br>
#endif<br>
<br>
+ .set push<br>
+ SET_HARDFLOAT<br>
/* Store the 16 even double precision registers */<br>
EX sdc1 $f0, SC_FPREGS+0(a0)<br>
EX sdc1 $f2, SC_FPREGS+16(a0)<br>
@@ -84,11 +95,14 @@ LEAF(_save_fp_context)<br>
EX sw t1, SC_FPC_CSR(a0)<br>
jr ra<br>
li v0, 0 # success<br>
+ .set pop<br>
END(_save_fp_context)<br>
<br>
#ifdef CONFIG_MIPS32_COMPAT<br>
/* Save 32-bit process floating point context */<br>
LEAF(_save_fp_context32)<br>
+ .set push<br>
+ SET_HARDFLOAT<br>
cfc1 t1, fcr31<br>
<br>
mfc0 t0, CP0_STATUS<br>
@@ -134,6 +148,7 @@ LEAF(_save_fp_context32)<br>
EX sw t1, SC32_FPC_CSR(a0)<br>
cfc1 t0, $0 # implementation/version<br>
EX sw t0, SC32_FPC_EIR(a0)<br>
+ .set pop<br>
<br>
jr ra<br>
li v0, 0 # success<br>
@@ -150,8 +165,10 @@ LEAF(_restore_fp_context)<br>
<br>
#if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)<br>
.set push<br>
+ SET_HARDFLOAT<br>
#ifdef CONFIG_CPU_MIPS32_R2<br>
- .set mips64r2<br>
+ .set mips32r2<br>
+ .set fp=64<br>
mfc0 t0, CP0_STATUS<br>
sll t0, t0, 5<br>
bgez t0, 1f # skip loading odd if FR=0<br>
@@ -175,6 +192,8 @@ LEAF(_restore_fp_context)<br>
EX ldc1 $f31, SC_FPREGS+248(a0)<br>
1: .set pop<br>
#endif<br>
+ .set push<br>
+ SET_HARDFLOAT<br>
EX ldc1 $f0, SC_FPREGS+0(a0)<br>
EX ldc1 $f2, SC_FPREGS+16(a0)<br>
EX ldc1 $f4, SC_FPREGS+32(a0)<br>
@@ -192,6 +211,7 @@ LEAF(_restore_fp_context)<br>
EX ldc1 $f28, SC_FPREGS+224(a0)<br>
EX ldc1 $f30, SC_FPREGS+240(a0)<br>
ctc1 t1, fcr31<br>
+ .set pop<br>
jr ra<br>
li v0, 0 # success<br>
END(_restore_fp_context)<br>
@@ -199,6 +219,8 @@ LEAF(_restore_fp_context)<br>
#ifdef CONFIG_MIPS32_COMPAT<br>
LEAF(_restore_fp_context32)<br>
/* Restore an o32 sigcontext. */<br>
+ .set push<br>
+ SET_HARDFLOAT<br>
EX lw t1, SC32_FPC_CSR(a0)<br>
<br>
mfc0 t0, CP0_STATUS<br>
@@ -242,6 +264,7 @@ LEAF(_restore_fp_context32)<br>
ctc1 t1, fcr31<br>
jr ra<br>
li v0, 0 # success<br>
+ .set pop<br>
END(_restore_fp_context32)<br>
#endif<br>
<br>
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S<br>
index 8a4f9a5..715fb13 100644<br>
--- a/arch/mips/kernel/r4k_switch.S<br>
+++ b/arch/mips/kernel/r4k_switch.S<br>
@@ -22,6 +22,9 @@<br>
<br>
#include <asm/asmmacro.h><br>
<br>
+/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */<br>
+#undef fp<br>
+<br>
/*<br>
* Offset to the current process status flags, the first 32 bytes of the<br>
* stack are not used.<br>
@@ -154,6 +157,9 @@ LEAF(_restore_fp)<br>
<br>
#define FPU_DEFAULT 0x00000000<br>
<br>
+ .set push<br>
+ SET_HARDFLOAT<br>
+<br>
LEAF(_init_fpu)<br>
#ifdef CONFIG_MIPS_MT_SMTC<br>
/* Rather than manipulate per-VPE Status, set per-TC bit in TCStatus */<br>
@@ -234,7 +240,8 @@ LEAF(_init_fpu)<br>
<br>
#ifdef CONFIG_CPU_MIPS32_R2<br>
.set push<br>
- .set mips64r2<br>
+ .set mips32r2<br>
+ .set fp=64<br>
sll t0, t0, 5 # is Status.FR set?<br>
bgez t0, 1f # no: skip setting upper 32b<br>
<br>
@@ -293,3 +300,5 @@ LEAF(_init_fpu)<br>
#endif<br>
jr ra<br>
END(_init_fpu)<br>
+<br>
+ .set pop /* SET_HARDFLOAT */<br>
diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S<br>
index da0fbe4..4707738 100644<br>
--- a/arch/mips/kernel/r6000_fpu.S<br>
+++ b/arch/mips/kernel/r6000_fpu.S<br>
@@ -18,6 +18,9 @@<br>
<br>
.set noreorder<br>
.set mips2<br>
+ .set push<br>
+ SET_HARDFLOAT<br>
+<br>
/* Save floating point context */<br>
LEAF(_save_fp_context)<br>
mfc0 t0,CP0_STATUS<br>
@@ -85,3 +88,5 @@<br>
1: jr ra<br>
nop<br>
END(_restore_fp_context)<br>
+<br>
+ .set pop /* SET_HARDFLOAT */<br>
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c<br>
index edb110c..4e9e3c1 100644<br>
--- a/arch/mips/math-emu/cp1emu.c<br>
+++ b/arch/mips/math-emu/cp1emu.c<br>
@@ -821,11 +821,7 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,<br>
if (<a href="http://insn.i_format.rs" rel="noreferrer" target="_blank">insn.i_format.rs</a> == bc_op) {<br>
preempt_disable();<br>
if (is_fpu_owner())<br>
- asm volatile(<br>
- ".set push\n"<br>
- "\t.set mips1\n"<br>
- "\tcfc1\t%0,$31\n"<br>
- "\t.set pop" : "=r" (fcr31));<br>
+ fcr31 = read_32bit_cp1_register(CP1_STATUS);<br>
else<br>
fcr31 = current->thread.fpu.fcr31;<br>
preempt_enable();<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.0.2<br>
<br>
--<br>
_______________________________________________<br>
Openembedded-core mailing list<br>
<a href="mailto:Openembedded-core@lists.openembedded.org">Openembedded-core@lists.openembedded.org</a><br>
<a href="http://lists.openembedded.org/mailman/listinfo/openembedded-core" rel="noreferrer" target="_blank">http://lists.openembedded.org/mailman/listinfo/openembedded-core</a><br>
</font></span></blockquote></div><br></div>