MIPS: fix build with binutils 2.24.51+
RFC PATCH v3 1/1 MIPS: fix build with binutils 2.24.51+
Starting with version 2.24.51.20140728 MIPS binutils complain loudly about mixing soft-float and hard-float object files, leading to this build failure since GCC is invoked with "-msoft-float" on MIPS:
{standard input}: Warning: .gnu_attribute 4,3 requires `softfloat'
LD arch/mips/alchemy/common/built-in.o
mipsel-softfloat-linux-gnu-ld: Warning: arch/mips/alchemy/common/built-in.o
uses -msoft-float (set by arch/mips/alchemy/common/prom.o), arch/mips/alchemy/common/sleeper.o uses -mhard-float
To fix this, we detect if GAS is new enough to support "-msoft-float" command option, and if it does, we can let GCC pass it to GAS; but then we also need to sprinkle the files which make use of floating point registers with the necessary ".set hardfloat" directives.
---
I've only tested a mips32r1 build, but at least binutils-2.23 and a snapshot from today (with the MIPS fp changes) compile a bootable kernel.
Tests on 64bit and with MSA and other extensions also appreciated!
v3: incorporate Maciej's suggestions:
- detect if gas can handle -msoft-float and ".set hardfloat"
- apply .set hardfloat only where really necessary
v2: cover more files
This was introduced in binutils commit 351cdf24d223290b15fa991e5052ec9e9bd1e284 ("[MIPS] Implement O32 FPXX, FP64 and FP64A ABI extensions").
arch/mips/Makefile | 9 +++++++++ arch/mips/include/asm/asmmacro-32.h | 5 +++++ arch/mips/include/asm/asmmacro.h | 18 ++++++++++++++++++ arch/mips/include/asm/fpregdef.h | 14 ++++++++++++++ arch/mips/include/asm/mipsregs.h | 19 +++++++++++++++++++ arch/mips/kernel/genex.S | 1 + arch/mips/kernel/r2300_switch.S | 5 +++++ arch/mips/kernel/r4k_fpu.S | 7 +++++++ arch/mips/kernel/r4k_switch.S | 9 +++++++++ arch/mips/kernel/r6000_fpu.S | 5 +++++ 10 files changed, 92 insertions(+)
arch/mips/Makefile +9 -0
@@ -93,6 +93,15 @@ LDFLAGS_vmlinux += -G 0 -static -n -nostdlib KBUILD_AFLAGS_MODULE += -mlong-calls KBUILD_CFLAGS_MODULE += -mlong-calls +# +# pass -msoft-float to GAS if it supports it. However on newer binutils +# (specifically newer than 2.24.51.20140728) we then also need to explicitly +# set ".set hardfloat" in all files which manipulate floating point registers. +# +ifneq ($(call as-option,-Wa$(comma)-msoft-float,),) + cflags-y += -DGAS_HAS_SET_HARDFLOAT -Wa,-msoft-float +endif + cflags-y += -ffreestanding #
arch/mips/include/asm/asmmacro-32.h +5 -0
@@ -12,6 +12,9 @@#include <asm/fpregdef.h> #include <asm/mipsregs.h> + .set push + SET_HARDFLOAT + .macro fpu_save_single thread tmp=t0 cfc1 \tmp, fcr31 swc1 $f0, THREAD_FPR0_LS64(\thread)
@@ -86,6 +89,8 @@ ctc1 \tmp, fcr31 .endm + .set pop + .macro cpu_save_nonscratch thread LONG_S s0, THREAD_REG16(\thread) LONG_S s1, THREAD_REG17(\thread)
arch/mips/include/asm/asmmacro.h +18 -0
@@ -57,6 +57,8 @@#endif /* CONFIG_CPU_MIPSR2 */ .macro fpu_save_16even thread tmp=t0 + .set push +SET_HARDFLOAT cfc1 \tmp, fcr31 sdc1 $f0, THREAD_FPR0_LS64(\thread) sdc1 $f2, THREAD_FPR2_LS64(\thread)
@@ -75,11 +77,13 @@ sdc1 $f28, THREAD_FPR28_LS64(\thread) sdc1 $f30, THREAD_FPR30_LS64(\thread) sw \tmp, THREAD_FCR31(\thread) + .set pop .endm .macro fpu_save_16odd thread .set push .set mips64r2 + SET_HARDFLOAT sdc1 $f1, THREAD_FPR1_LS64(\thread) sdc1 $f3, THREAD_FPR3_LS64(\thread) sdc1 $f5, THREAD_FPR5_LS64(\thread)
@@ -110,6 +114,8 @@ .endm .macro fpu_restore_16even thread tmp=t0 + .set push +SET_HARDFLOAT lw \tmp, THREAD_FCR31(\thread) ldc1 $f0, THREAD_FPR0_LS64(\thread) ldc1 $f2, THREAD_FPR2_LS64(\thread)
@@ -133,6 +139,7 @@ .macro fpu_restore_16odd thread .set push .set mips64r2 +SET_HARDFLOAT ldc1 $f1, THREAD_FPR1_LS64(\thread) ldc1 $f3, THREAD_FPR3_LS64(\thread) ldc1 $f5, THREAD_FPR5_LS64(\thread)
@@ -277,6 +284,7 @@ .macro cfcmsa rd, cs .set push .set noat + SET_HARDFLOAT .insn .word CFC_MSA_INSN | (\cs << 11) move \rd, $1
@@ -286,6 +294,7 @@ .macro ctcmsa cd, rs .set push .set noat + SET_HARDFLOAT move $1, \rs .word CTC_MSA_INSN | (\cd << 6) .set pop
@@ -294,6 +303,7 @@ .macro ld_d wd, off, base .set push .set noat + SET_HARDFLOAT add $1, \base, \off .word LDD_MSA_INSN | (\wd << 6) .set pop
@@ -302,6 +312,7 @@ .macro st_d wd, off, base .set push .set noat + SET_HARDFLOAT add $1, \base, \off .word STD_MSA_INSN | (\wd << 6) .set pop
@@ -310,6 +321,7 @@ .macro copy_u_w rd, ws, n .set push .set noat + SET_HARDFLOAT .insn .word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)/* move triggers an assembler bug... */
@@ -320,6 +332,7 @@ .macro copy_u_d rd, ws, n .set push .set noat + SET_HARDFLOAT .insn .word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)/* move triggers an assembler bug... */
@@ -330,6 +343,7 @@ .macro insert_w wd, n, rs .set push .set noat +SET_HARDFLOAT /* move triggers an assembler bug... */ or $1, \rs, zero .word INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6)
@@ -339,6 +353,7 @@ .macro insert_d wd, n, rs .set push .set noat +SET_HARDFLOAT /* move triggers an assembler bug... */ or $1, \rs, zero .word INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6)
@@ -381,6 +396,7 @@ st_d 31, THREAD_FPR31, \thread .set push .set noat + SET_HARDFLOAT cfcmsa $1, MSA_CSR sw $1, THREAD_MSA_CSR(\thread) .set pop
@@ -389,6 +405,7 @@ .macro msa_restore_all thread .set push .set noat +SET_HARDFLOAT lw $1, THREAD_MSA_CSR(\thread) ctcmsa MSA_CSR, $1 .set pop
@@ -441,6 +458,7 @@ .macro msa_init_all_upper .set push .set noat + SET_HARDFLOAT not $1, zero msa_init_upper 0 .set pop
arch/mips/include/asm/fpregdef.h +14 -0
@@ -14,6 +14,20 @@#include <asm/sgidefs.h> +/* +* starting with binutils 2.24.51.20140729, MIPS binutils warn about mixing +* hardfloat and softfloat object files. The kernel build uses soft-float by +* default, so we also need to pass -msoft-float along to GAS if it supports it. +* But this in turn causes assembler errors in files which access hardfloat +* registers. We detect if GAS supports "-msoft-float" in the Makefile and +* explicitly put ".set hardfloat" where floating point registers are touched. +*/ +#ifdef GAS_HAS_SET_HARDFLOAT +#define SET_HARDFLOAT .set hardfloat +#else +#define SET_HARDFLOAT +#endif +#if _MIPS_SIM == _MIPS_SIM_ABI32/*
arch/mips/include/asm/mipsregs.h +19 -0
@@ -1324,6 +1324,7 @@ do { \/* * Macros to access the floating point coprocessor control registers */ +#ifdef GAS_HAS_SET_HARDFLOAT #define read_32bit_cp1_register (source) \ ({ \ int __res; \
@@ -1334,11 +1335,29 @@ do { \" # gas fails to assemble cfc1 for some archs, \n" \" # like Octeon. \n" \" .set mips1 \n" \ +" .set hardfloat \n" \ " cfc1 %0,"STR(source)" \n" \ " .set pop \n" \ : "=r" (__res)); \ __res; \ }) +#else +#define read_32bit_cp1_register (source) \ +({ \ + int __res; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set reorder \n" \ + " # gas fails to assemble cfc1 for some archs, \n" \ + " # like Octeon. \n" \ + " .set mips1 \n" \ + " cfc1 %0,"STR(source)" \n" \ + " .set pop \n" \ + : "=r" (__res)); \ + __res; \ +}) +#endif #ifdef HAVE_AS_DSP #define rddsp (mask) \
arch/mips/kernel/genex.S +1 -0
@@ -358,6 +358,7 @@ NESTED(nmi_handler, PT_SIZE, sp) .set push /* gas fails to assemble cfc1 for some archs (octeon).*/ \ .set mips1 + SET_HARDFLOAT cfc1 a1, fcr31 li a2, ~(0x3f << 12) and a2, a1
arch/mips/kernel/r2300_switch.S +5 -0
@@ -120,6 +120,9 @@ LEAF(_restore_fp) #define FPU_DEFAULT 0x00000000 + .set push + SET_HARDFLOAT + LEAF(_init_fpu) mfc0 t0, CP0_STATUS li t1, ST0_CU1
@@ -165,3 +168,5 @@ LEAF(_init_fpu) mtc1 t0, $f31 jr ra END(_init_fpu) + + .set pop
arch/mips/kernel/r4k_fpu.S +7 -0
@@ -21,6 +21,7 @@ .macro EX insn, reg, src .set push + SET_HARDFLOAT .set nomacro .ex\@: \insn \reg, \src .set pop
@@ -33,7 +34,10 @@ .set arch=r4000 LEAF(_save_fp_context) + .set push + SET_HARDFLOAT cfc1 t1, fcr31 + .set pop #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) .set push
@@ -191,7 +195,10 @@ LEAF(_restore_fp_context) EX ldc1 $f26, SC_FPREGS+208(a0) EX ldc1 $f28, SC_FPREGS+224(a0) EX ldc1 $f30, SC_FPREGS+240(a0) + .set push + SET_HARDFLOAT ctc1 t1, fcr31 + .set pop jr ra li v0, 0 # success END(_restore_fp_context)
arch/mips/kernel/r4k_switch.S +9 -0
@@ -65,8 +65,12 @@ bgtz a3, 1f /* Save 128b MSA vector context + scalar FP control & status. */ + .set push + SET_HARDFLOAT cfc1 t1, fcr31 msa_save_all a0 + .set pop /* SET_HARDFLOAT */ + sw t1, THREAD_FCR31(a0) b 2f
@@ -161,6 +165,9 @@ LEAF(_init_msa_upper) #define FPU_DEFAULT 0x00000000 + .set push + SET_HARDFLOAT + LEAF(_init_fpu) mfc0 t0, CP0_STATUS li t1, ST0_CU1
@@ -291,3 +298,5 @@ LEAF(_init_fpu) #endif jr ra END(_init_fpu) + + .set pop /* SET_HARDFLOAT */
arch/mips/kernel/r6000_fpu.S +5 -0
@@ -18,6 +18,9 @@ .set noreorder .set mips2 + .set push + SET_HARDFLOAT + /* Save floating point context */ LEAF(_save_fp_context) mfc0 t0,CP0_STATUS
@@ -85,3 +88,5 @@ 1: jr ra nop END(_restore_fp_context) + + .set pop /* SET_HARDFLOAT */
--
2.1.2
Quoted 32 lines · Manuel Lauss
Starting with version 2.24.51.20140728 MIPS binutils complain loudly about mixing soft-float and hard-float object files, leading to this build failure since GCC is invoked with "-msoft-float" on MIPS:
{standard input}: Warning: .gnu_attribute 4,3 requires `softfloat'
LDarch/mips/alchemy/common/built-in.o
mipsel-softfloat-linux-gnu-ld: Warning:arch/mips/alchemy/common/built-in.o
uses -msoft-float (set byarch/mips/alchemy/common/prom.o),arch/mips/alchemy/common/sleeper.ouses -mhard-floatTo fix this, we detect if GAS is new enough to support "-msoft-float" command option, and if it does, we can let GCC pass it to GAS; but then we also need to sprinkle the files which make use of floating point registers with the necessary ".set hardfloat" directives.
Signed-off-by Manuel Lauss <[email protected]>---
I've only tested a mips32r1 build, but at least binutils-2.23 and a snapshot from today (with the MIPS fp changes) compile a bootable kernel.Tests on 64bit and with MSA and other extensions also appreciated!
v3: incorporate Maciej's suggestions:
- detect if gas can handle -msoft-float and ".set hardfloat"
- apply .set hardfloat only where really necessaryv2: cover more files
This was introduced in binutils commit
351cdf24d223290b15fa991e5052ec9e9bd1e284("[MIPS] Implement O32 FPXX, FP64 and FP64A ABI extensions").
Quoted 12 lines
arch/mips/Makefile | 9 +++++++++ arch/mips/include/asm/asmmacro-32.h | 5 +++++ arch/mips/include/asm/asmmacro.h | 18 ++++++++++++++++++ arch/mips/include/asm/fpregdef.h | 14 ++++++++++++++ arch/mips/include/asm/mipsregs.h | 19 +++++++++++++++++++ arch/mips/kernel/genex.S | 1 + arch/mips/kernel/r2300_switch.S | 5 +++++ arch/mips/kernel/r4k_fpu.S | 7 +++++++ arch/mips/kernel/r4k_switch.S | 9 +++++++++ arch/mips/kernel/r6000_fpu.S | 5 +++++ 10 files changed, 92 insertions(+)
Hi,
I applied this patch but it still does not build for me on a malta_defconfig:
arch/mips/kernel/r4k_fpu.S: Assembler messages:arch/mips/kernel/r4k_fpu.S:52: Error: float register should be even, was 1 arch/mips/kernel/r4k_fpu.S:53: Error: float register should be even, was 3 arch/mips/kernel/r4k_fpu.S:54: Error: float register should be even, was 5 arch/mips/kernel/r4k_fpu.S:55: Error: float register should be even, was 7
...
The error is different this time so we probably need a follow-up patch
Signature · 1 line
markos
Quoted 50 lines · Markos Chandras
Quoted 32 lines · Manuel Lauss
Starting with version 2.24.51.20140728 MIPS binutils complain loudly about mixing soft-float and hard-float object files, leading to this build failure since GCC is invoked with "-msoft-float" on MIPS:
{standard input}: Warning: .gnu_attribute 4,3 requires `softfloat'
LDarch/mips/alchemy/common/built-in.o
mipsel-softfloat-linux-gnu-ld: Warning:arch/mips/alchemy/common/built-in.o
uses -msoft-float (set byarch/mips/alchemy/common/prom.o),arch/mips/alchemy/common/sleeper.ouses -mhard-floatTo fix this, we detect if GAS is new enough to support "-msoft-float" command option, and if it does, we can let GCC pass it to GAS; but then we also need to sprinkle the files which make use of floating point registers with the necessary ".set hardfloat" directives.
Signed-off-by Manuel Lauss <[email protected]>---
I've only tested a mips32r1 build, but at least binutils-2.23 and a snapshot from today (with the MIPS fp changes) compile a bootable kernel.Tests on 64bit and with MSA and other extensions also appreciated!
v3: incorporate Maciej's suggestions:
- detect if gas can handle -msoft-float and ".set hardfloat"
- apply .set hardfloat only where really necessaryv2: cover more files
This was introduced in binutils commit
351cdf24d223290b15fa991e5052ec9e9bd1e284("[MIPS] Implement O32 FPXX, FP64 and FP64A ABI extensions").Quoted 12 lines
arch/mips/Makefile | 9 +++++++++ arch/mips/include/asm/asmmacro-32.h | 5 +++++ arch/mips/include/asm/asmmacro.h | 18 ++++++++++++++++++ arch/mips/include/asm/fpregdef.h | 14 ++++++++++++++ arch/mips/include/asm/mipsregs.h | 19 +++++++++++++++++++ arch/mips/kernel/genex.S | 1 + arch/mips/kernel/r2300_switch.S | 5 +++++ arch/mips/kernel/r4k_fpu.S | 7 +++++++ arch/mips/kernel/r4k_switch.S | 9 +++++++++ arch/mips/kernel/r6000_fpu.S | 5 +++++ 10 files changed, 92 insertions(+)Hi,
I applied this patch but it still does not build for me on a
malta_defconfig:
Quoted 9 lines
arch/mips/kernel/r4k_fpu.S: Assembler messages:arch/mips/kernel/r4k_fpu.S:52: Error: float register should be even, was 1arch/mips/kernel/r4k_fpu.S:53: Error: float register should be even, was 3arch/mips/kernel/r4k_fpu.S:54: Error: float register should be even, was 5arch/mips/kernel/r4k_fpu.S:55: Error: float register should be even, was 7
...The error is different this time so we probably need a follow-up patch
I also get a problem with an older version of binutils (the one from the latest Sourcery CodeBench toolchain[1])
{standard input}: Assembler messages:
{standard input}:406: Error: opcode not supported on this processor:
mips1 (mips1) `cfc1 $9,$31'scripts/Makefile.build:257: recipe for target 'arch/mips/kernel/branch.o' failed
make[2]: *** [arch/mips/kernel/branch.o] Error 1
[1] https://sourcery.mentor.com/GNUToolchain/release2791
Signature · 1 line
markos
(top posting so Matthew can see the entire patch)
+CC Matthew Fortune who has some comments on the patch.
Quoted 409 lines · Manuel Lauss
Starting with version 2.24.51.20140728 MIPS binutils complain loudly about mixing soft-float and hard-float object files, leading to this build failure since GCC is invoked with "-msoft-float" on MIPS:
{standard input}: Warning: .gnu_attribute 4,3 requires `softfloat'
LDarch/mips/alchemy/common/built-in.o
mipsel-softfloat-linux-gnu-ld: Warning:arch/mips/alchemy/common/built-in.o
uses -msoft-float (set byarch/mips/alchemy/common/prom.o),arch/mips/alchemy/common/sleeper.ouses -mhard-floatTo fix this, we detect if GAS is new enough to support "-msoft-float" command option, and if it does, we can let GCC pass it to GAS; but then we also need to sprinkle the files which make use of floating point registers with the necessary ".set hardfloat" directives.
Signed-off-by Manuel Lauss <[email protected]>---
I've only tested a mips32r1 build, but at least binutils-2.23 and a snapshot from today (with the MIPS fp changes) compile a bootable kernel.Tests on 64bit and with MSA and other extensions also appreciated!
v3: incorporate Maciej's suggestions:
- detect if gas can handle -msoft-float and ".set hardfloat"
- apply .set hardfloat only where really necessaryv2: cover more files
This was introduced in binutils commit
351cdf24d223290b15fa991e5052ec9e9bd1e284("[MIPS] Implement O32 FPXX, FP64 and FP64A ABI extensions").arch/mips/Makefile | 9 +++++++++ arch/mips/include/asm/asmmacro-32.h | 5 +++++ arch/mips/include/asm/asmmacro.h | 18 ++++++++++++++++++ arch/mips/include/asm/fpregdef.h | 14 ++++++++++++++ arch/mips/include/asm/mipsregs.h | 19 +++++++++++++++++++ arch/mips/kernel/genex.S | 1 + arch/mips/kernel/r2300_switch.S | 5 +++++ arch/mips/kernel/r4k_fpu.S | 7 +++++++ arch/mips/kernel/r4k_switch.S | 9 +++++++++ arch/mips/kernel/r6000_fpu.S | 5 +++++ 10 files changed, 92 insertions(+)arch/mips/Makefile +9
-0@@ -93,6 +93,15 @@ LDFLAGS_vmlinux += -G 0 -static -n -nostdlib KBUILD_AFLAGS_MODULE += -mlong-calls KBUILD_CFLAGS_MODULE += -mlong-calls +# +# pass -msoft-float to GAS if it supports it. However on newer binutils +# (specifically newer than 2.24.51.20140728) we then also need to explicitly +# set ".set hardfloat" in all files which manipulate floating point registers. +# +ifneq ($(call as-option,-Wa$(comma)-msoft-float,),) + cflags-y += -DGAS_HAS_SET_HARDFLOAT -Wa,-msoft-float +endif + cflags-y += -ffreestanding #arch/mips/include/asm/asmmacro-32.h +5
-0@@ -12,6 +12,9 @@#include <asm/fpregdef.h> #include <asm/mipsregs.h> + .set push + SET_HARDFLOAT + .macro fpu_save_single thread tmp=t0 cfc1 \tmp, fcr31 swc1 $f0, THREAD_FPR0_LS64(\thread)@@ -86,6 +89,8 @@ ctc1 \tmp, fcr31 .endm + .set pop + .macro cpu_save_nonscratch thread LONG_S s0, THREAD_REG16(\thread) LONG_S s1, THREAD_REG17(\thread)arch/mips/include/asm/asmmacro.h +18
-0@@ -57,6 +57,8 @@#endif /* CONFIG_CPU_MIPSR2 */ .macro fpu_save_16even thread tmp=t0 + .set push +SET_HARDFLOAT cfc1 \tmp, fcr31 sdc1 $f0, THREAD_FPR0_LS64(\thread) sdc1 $f2, THREAD_FPR2_LS64(\thread)@@ -75,11 +77,13 @@ sdc1 $f28, THREAD_FPR28_LS64(\thread) sdc1 $f30, THREAD_FPR30_LS64(\thread) sw \tmp, THREAD_FCR31(\thread) + .set pop .endm .macro fpu_save_16odd thread .set push .set mips64r2 + SET_HARDFLOAT sdc1 $f1, THREAD_FPR1_LS64(\thread) sdc1 $f3, THREAD_FPR3_LS64(\thread) sdc1 $f5, THREAD_FPR5_LS64(\thread)@@ -110,6 +114,8 @@ .endm .macro fpu_restore_16even thread tmp=t0 + .set push +SET_HARDFLOAT lw \tmp, THREAD_FCR31(\thread) ldc1 $f0, THREAD_FPR0_LS64(\thread) ldc1 $f2, THREAD_FPR2_LS64(\thread)@@ -133,6 +139,7 @@ .macro fpu_restore_16odd thread .set push .set mips64r2 +SET_HARDFLOAT ldc1 $f1, THREAD_FPR1_LS64(\thread) ldc1 $f3, THREAD_FPR3_LS64(\thread) ldc1 $f5, THREAD_FPR5_LS64(\thread)@@ -277,6 +284,7 @@ .macro cfcmsa rd, cs .set push .set noat + SET_HARDFLOAT .insn .word CFC_MSA_INSN | (\cs << 11) move \rd, $1@@ -286,6 +294,7 @@ .macro ctcmsa cd, rs .set push .set noat + SET_HARDFLOAT move $1, \rs .word CTC_MSA_INSN | (\cd << 6) .set pop@@ -294,6 +303,7 @@ .macro ld_d wd, off, base .set push .set noat + SET_HARDFLOAT add $1, \base, \off .word LDD_MSA_INSN | (\wd << 6) .set pop@@ -302,6 +312,7 @@ .macro st_d wd, off, base .set push .set noat + SET_HARDFLOAT add $1, \base, \off .word STD_MSA_INSN | (\wd << 6) .set pop@@ -310,6 +321,7 @@ .macro copy_u_w rd, ws, n .set push .set noat + SET_HARDFLOAT .insn .word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)/* move triggers an assembler bug... */ @@ -320,6 +332,7 @@ .macro copy_u_d rd, ws, n .set push .set noat + SET_HARDFLOAT .insn .word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)/* move triggers an assembler bug... */ @@ -330,6 +343,7 @@ .macro insert_w wd, n, rs .set push .set noat +SET_HARDFLOAT /* move triggers an assembler bug... */ or $1, \rs, zero .word INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6)@@ -339,6 +353,7 @@ .macro insert_d wd, n, rs .set push .set noat +SET_HARDFLOAT /* move triggers an assembler bug... */ or $1, \rs, zero .word INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6)@@ -381,6 +396,7 @@ st_d 31, THREAD_FPR31, \thread .set push .set noat + SET_HARDFLOAT cfcmsa $1, MSA_CSR sw $1, THREAD_MSA_CSR(\thread) .set pop@@ -389,6 +405,7 @@ .macro msa_restore_all thread .set push .set noat +SET_HARDFLOAT lw $1, THREAD_MSA_CSR(\thread) ctcmsa MSA_CSR, $1 .set pop@@ -441,6 +458,7 @@ .macro msa_init_all_upper .set push .set noat + SET_HARDFLOAT not $1, zero msa_init_upper 0 .set poparch/mips/include/asm/fpregdef.h +14
-0@@ -14,6 +14,20 @@#include <asm/sgidefs.h> +/* +* starting with binutils 2.24.51.20140729, MIPS binutils warn about mixing +* hardfloat and softfloat object files. The kernel build uses soft-float by +* default, so we also need to pass -msoft-float along to GAS if it supports it. +* But this in turn causes assembler errors in files which access hardfloat +* registers. We detect if GAS supports "-msoft-float" in the Makefile and +* explicitly put ".set hardfloat" where floating point registers are touched. +*/ +#ifdef GAS_HAS_SET_HARDFLOAT +#define SET_HARDFLOAT .set hardfloat +#else +#define SET_HARDFLOAT +#endif +#if _MIPS_SIM == _MIPS_SIM_ABI32/* arch/mips/include/asm/mipsregs.h +19
-0@@ -1324,6 +1324,7 @@ do { \/* * Macros to access the floating point coprocessor control registers */ +#ifdef GAS_HAS_SET_HARDFLOAT #define read_32bit_cp1_register (source) \ ({ \ int __res; \@@ -1334,11 +1335,29 @@ do { \" # gas fails to assemble cfc1 for some archs, \n" \" # like Octeon. \n" \" .set mips1 \n" \ +" .set hardfloat \n" \ " cfc1 %0,"STR(source)" \n" \ " .set pop \n" \ : "=r" (__res)); \ __res; \ }) +#else +#define read_32bit_cp1_register (source) \ +({ \ + int __res; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set reorder \n" \ + " # gas fails to assemble cfc1 for some archs, \n" \ + " # like Octeon. \n" \ + " .set mips1 \n" \ + " cfc1 %0,"STR(source)" \n" \ + " .set pop \n" \ + : "=r" (__res)); \ + __res; \ +}) +#endif #ifdef HAVE_AS_DSP #define rddsp (mask) \arch/mips/kernel/genex.S +1
-0@@ -358,6 +358,7 @@ NESTED(nmi_handler, PT_SIZE, sp) .set push /* gas fails to assemble cfc1 for some archs (octeon).*/ \ .set mips1 + SET_HARDFLOAT cfc1 a1, fcr31 li a2, ~(0x3f << 12) and a2, a1arch/mips/kernel/r2300_switch.S +5
-0@@ -120,6 +120,9 @@ LEAF(_restore_fp) #define FPU_DEFAULT 0x00000000 + .set push + SET_HARDFLOAT + LEAF(_init_fpu) mfc0 t0, CP0_STATUS li t1, ST0_CU1@@ -165,3 +168,5 @@ LEAF(_init_fpu) mtc1 t0, $f31 jr ra END(_init_fpu) + + .set poparch/mips/kernel/r4k_fpu.S +7
-0@@ -21,6 +21,7 @@ .macro EX insn, reg, src .set push + SET_HARDFLOAT .set nomacro .ex\@: \insn \reg, \src .set pop@@ -33,7 +34,10 @@ .set arch=r4000 LEAF(_save_fp_context) + .set push + SET_HARDFLOAT cfc1 t1, fcr31 + .set pop #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) .set push@@ -191,7 +195,10 @@ LEAF(_restore_fp_context) EX ldc1 $f26, SC_FPREGS+208(a0) EX ldc1 $f28, SC_FPREGS+224(a0) EX ldc1 $f30, SC_FPREGS+240(a0) + .set push + SET_HARDFLOAT ctc1 t1, fcr31 + .set pop jr ra li v0, 0 # success END(_restore_fp_context)arch/mips/kernel/r4k_switch.S +9
-0@@ -65,8 +65,12 @@ bgtz a3, 1f /* Save 128b MSA vector context + scalar FP control & status. */ + .set push + SET_HARDFLOAT cfc1 t1, fcr31 msa_save_all a0 + .set pop /* SET_HARDFLOAT */ + sw t1, THREAD_FCR31(a0) b 2f@@ -161,6 +165,9 @@ LEAF(_init_msa_upper) #define FPU_DEFAULT 0x00000000 + .set push + SET_HARDFLOAT + LEAF(_init_fpu) mfc0 t0, CP0_STATUS li t1, ST0_CU1@@ -291,3 +298,5 @@ LEAF(_init_fpu) #endif jr ra END(_init_fpu) + + .set pop /* SET_HARDFLOAT */arch/mips/kernel/r6000_fpu.S +5
-1@@ -18,6 +18,9 @@ .set noreorder .set mips2 + .set push + SET_HARDFLOAT + /* Save floating point context */ LEAF(_save_fp_context) mfc0 t0,CP0_STATUS@@ -85,3 +88,5 @@ 1: jr ra nop END(_restore_fp_context) + + .set pop /* SET_HARDFLOAT */ --2.1.2
Signature · 1 line
markos
Quoted 24 lines · Markos Chandras
(top posting so Matthew can see the entire patch)
+CC Matthew Fortune who has some comments on the patch.
Review
Quoted 1 line · Manuel Lauss
(quoted diff) +0
-0
b/arch/mips/include/asm/asmmacro-32.hQuoted 17 lines
index e38c281..a97ce53 100644
arch/mips/include/asm/asmmacro-32.h +3
-0@@ -12,6 +12,9 @@#include <asm/fpregdef.h> #include <asm/mipsregs.h> + .set push + SET_HARDFLOAT + .macro fpu_save_single thread tmp=t0 cfc1 \tmp, fcr31 swc1 $f0, THREAD_FPR0_LS64(\thread)@@ -86,6 +89,8 @@ ctc1 \tmp, fcr31 .endm
Quoted 2 lines
arch/mips/include/asm/asmmacro-32.h line 93
Quoted 2 lines
arch/mips/include/asm/asmmacro-32.h +2
-0+ .set pop +
Any reason for putting the push/pop outside of the macro here but inside the macros elsewhere?
Quoted 34 lines
Review
Quoted 1 line
(quoted diff) +0
-0
b/arch/mips/include/asm/mipsregs.harch/mips/include/asm/mipsregs.h do {
Quoted 4 lines
index cf3b580..889c012 100644
arch/mips/include/asm/mipsregs.h +0
-0@@ -1324,6 +1324,7 @@ do {\arch/mips/include/asm/mipsregs.h do {
Quoted 8 lines
arch/mips/include/asm/mipsregs.h +1
-0/* * Macros to access the floating point coprocessor control registers */ +#ifdef GAS_HAS_SET_HARDFLOAT #define read_32bit_cp1_register (source) \ ({ \ int __res; \@@ -1334,11 +1335,29 @@ do {\Quoted 18 lines
arch/mips/include/asm/mipsregs.h +10
-0" # gas fails to assemble cfc1 for some archs, \n" \" # like Octeon. \n" \" .set mips1 \n" \ +" .set hardfloat \n" \ " cfc1 %0,"STR(source)" \n" \ " .set pop \n" \ : "=r" (__res)); \ __res; \ }) +#else +#define read_32bit_cp1_register (source) \ +({ \ + int __res; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set reorder \n" \ + " # gas fails to assemble cfc1 for some archs, \n" \
Quoted 8 lines
arch/mips/include/asm/mipsregs.h do { \ · line 1360
Quoted 8 lines
arch/mips/include/asm/mipsregs.h +8
-0+" # like Octeon. \n" \ +" .set mips1 \n" \ + " cfc1 %0,"STR(source)" \n" \ + " .set pop \n" \ + : "=r" (__res)); \ + __res; \ +}) +#endif
This looks fairly ugly. I believe you can just add the hardfloat using:
Quoted 8 lines
arch/mips/include/asm/mipsregs.h do { \ · line 1342
Quoted 8 lines
arch/mips/include/asm/mipsregs.h +1
-0" # gas fails to assemble cfc1 for some archs, \n" \" # like Octeon. \n" \" .set mips1 \n" \ + " "STR(SET_HARDFLOAT)" \n" \ " cfc1 %0,"STR(source)" \n" \ " .set pop \n" \ : "=r" (__res)); \__res; \
The ctc1/cfc1 instructions are quite unusual as they were (before my binutils patch) floating point instructions but are general purpose after the patch. While that may indicate that you don't need .set hardfloat to use ctc1/cfc1 that is not true when you consider using a new compiler and/or the -Wa,-msoft-float CFLAGS patch with an old assembler. It would therefore be wise to test the kernel patch with an assembler which pre-dates my FPXX patch to make sure that all instances of ctc1/cfc1 have been caught.
That is the reason why Markos saw issues with using one of the mentor toolchains with your patch in place.
Markos' secondary issue relating to odd-numbered single-precision registers is probably something to address on the GCC side but I haven't quite figured out what the root cause is. I'm trying to avoid the kernel having to add both .set hardfloat and .set oddspreg as I think it is legitimate for the kernel to expect that when enabling hardfloat in a softfloat module then the standard hardfloat ABI should apply to that region and all registers should be available.
Hope that is helpful,
Matthew
Quoted 25 lines · Matthew Fortune
Quoted 24 lines · Markos Chandras
(top posting so Matthew can see the entire patch)
+CC Matthew Fortune who has some comments on the patch.
Review
Quoted 1 line · Manuel Lauss
(quoted diff) +0
-0
b/arch/mips/include/asm/asmmacro-32.hQuoted 17 lines
index e38c281..a97ce53 100644
arch/mips/include/asm/asmmacro-32.h +3
-0@@ -12,6 +12,9 @@#include <asm/fpregdef.h> #include <asm/mipsregs.h> + .set push + SET_HARDFLOAT + .macro fpu_save_single thread tmp=t0 cfc1 \tmp, fcr31 swc1 $f0, THREAD_FPR0_LS64(\thread)@@ -86,6 +89,8 @@ ctc1 \tmp, fcr31 .endm
Quoted 5 lines
Quoted 2 lines
arch/mips/include/asm/asmmacro-32.h line 93
Quoted 2 lines
arch/mips/include/asm/asmmacro-32.h +2
-0+ .set pop +Any reason for putting the push/pop outside of the macro here but inside the macros elsewhere?
I think I figured I just enclose all float-using macros with this in one go. I'll fix it.
Quoted 36 lines
Quoted 36 lines
Review
Quoted 1 line
(quoted diff) +0
-0
b/arch/mips/include/asm/mipsregs.harch/mips/include/asm/mipsregs.h do {
Quoted 4 lines
index cf3b580..889c012 100644
arch/mips/include/asm/mipsregs.h +0
-0@@ -1324,6 +1324,7 @@ do {\arch/mips/include/asm/mipsregs.h do {
Quoted 8 lines
arch/mips/include/asm/mipsregs.h +1
-0/* * Macros to access the floating point coprocessor control registers */ +#ifdef GAS_HAS_SET_HARDFLOAT #define read_32bit_cp1_register (source) \ ({ \ int __res; \@@ -1334,11 +1335,29 @@ do {\Quoted 20 lines
arch/mips/include/asm/mipsregs.h +12
-0" # gas fails to assemble cfc1 for some archs, \n" \" # like Octeon. \n" \" .set mips1 \n" \ +" .set hardfloat \n" \ " cfc1 %0,"STR(source)" \n" \ " .set pop \n" \ : "=r" (__res)); \ __res; \ }) +#else +#define read_32bit_cp1_register (source) \ +({ \ + int __res; \ + \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set reorder \n" \ + " # gas fails to assemble cfc1 for some archs, \n" \ + " # like Octeon. \n" \ + " .set mips1 \n" \
Quoted 17 lines
Quoted 6 lines
arch/mips/include/asm/mipsregs.h do { \ · line 1360
Quoted 6 lines
arch/mips/include/asm/mipsregs.h +6
-0+ " cfc1 %0,"STR(source)" \n" \ + " .set pop \n" \ + : "=r" (__res)); \ + __res; \ +}) +#endif This looks fairly ugly. I believe you can just add the hardfloat using:
Quoted 8 lines
Quoted 8 lines
arch/mips/include/asm/mipsregs.h +1
-0" # gas fails to assemble cfc1 for some archs, \n" \" # like Octeon. \n" \" .set mips1 \n" \ + " "STR(SET_HARDFLOAT)" \n" \ " cfc1 %0,"STR(source)" \n" \ " .set pop \n" \ : "=r" (__res)); \__res; \
I didn't know that, thanks!
Quoted 7 lines
The ctc1/cfc1 instructions are quite unusual as they were (before my binutils patch) floating point instructions but are general purpose after the patch. While that may indicate that you don't need .set hardfloat to use ctc1/cfc1 that is not true when you consider using a new compiler and/or the -Wa,-msoft-float CFLAGS patch with an old assembler. It would therefore be wise to test the kernel patch with an assembler which pre-dates my FPXX patch to make sure that all instances of ctc1/cfc1 have been caught.
Actually, I did test the patch with 2.24 first, but just with my mips32r1 alchemy target. I'll try to fix everything, retest and resend.
Thank you,
Manuel