123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- From d339550fcb6a2048b829634612da96b186d97dfe Mon Sep 17 00:00:00 2001
- From: Manuel Lauss <manuel.lauss@gmail.com>
- Date: Fri, 7 Nov 2014 14:13:54 +0100
- Subject: [PATCH] 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.
- Signed-off-by: Manuel Lauss <manuel.lauss@gmail.com>
- Cc: Linux-MIPS <linux-mips@linux-mips.org>
- Cc: Matthew Fortune <Matthew.Fortune@imgtec.com>
- Cc: Markos Chandras <Markos.Chandras@imgtec.com>
- Cc: Maciej W. Rozycki <macro@linux-mips.org>
- Patchwork: https://patchwork.linux-mips.org/patch/8355/
- Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
- ---
- arch/mips/Makefile | 9 +++++++++
- arch/mips/include/asm/asmmacro-32.h | 6 ++++++
- arch/mips/include/asm/asmmacro.h | 7 +++++++
- arch/mips/include/asm/fpregdef.h | 14 ++++++++++++++
- arch/mips/include/asm/mipsregs.h | 11 ++++++++++-
- arch/mips/kernel/branch.c | 2 +-
- arch/mips/kernel/genex.S | 1 +
- arch/mips/kernel/r2300_fpu.S | 6 ++++++
- arch/mips/kernel/r2300_switch.S | 5 +++++
- arch/mips/kernel/r4k_fpu.S | 27 +++++++++++++++++++++++++--
- arch/mips/kernel/r4k_switch.S | 11 ++++++++++-
- arch/mips/kernel/r6000_fpu.S | 5 +++++
- arch/mips/math-emu/cp1emu.c | 2 +-
- 13 files changed, 100 insertions(+), 6 deletions(-)
- diff --git a/arch/mips/Makefile b/arch/mips/Makefile
- index 9b8556d..20f6379 100644
- --- a/arch/mips/Makefile
- +++ b/arch/mips/Makefile
- @@ -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
-
- #
- diff --git a/arch/mips/include/asm/asmmacro-32.h b/arch/mips/include/asm/asmmacro-32.h
- index 70e1f17..8038647 100644
- --- a/arch/mips/include/asm/asmmacro-32.h
- +++ b/arch/mips/include/asm/asmmacro-32.h
- @@ -13,6 +13,8 @@
- #include <asm/mipsregs.h>
-
- .macro fpu_save_single thread tmp=t0
- + .set push
- + SET_HARDFLOAT
- cfc1 \tmp, fcr31
- swc1 $f0, THREAD_FPR0(\thread)
- swc1 $f1, THREAD_FPR1(\thread)
- @@ -47,9 +49,12 @@
- swc1 $f30, THREAD_FPR30(\thread)
- swc1 $f31, THREAD_FPR31(\thread)
- sw \tmp, THREAD_FCR31(\thread)
- + .set pop
- .endm
-
- .macro fpu_restore_single thread tmp=t0
- + .set push
- + SET_HARDFLOAT
- lw \tmp, THREAD_FCR31(\thread)
- lwc1 $f0, THREAD_FPR0(\thread)
- lwc1 $f1, THREAD_FPR1(\thread)
- @@ -84,6 +89,7 @@
- lwc1 $f30, THREAD_FPR30(\thread)
- lwc1 $f31, THREAD_FPR31(\thread)
- ctc1 \tmp, fcr31
- + .set pop
- .endm
-
- .macro cpu_save_nonscratch thread
- diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h
- index 4225e99..d6d5b19 100644
- --- a/arch/mips/include/asm/asmmacro.h
- +++ b/arch/mips/include/asm/asmmacro.h
- @@ -74,6 +74,8 @@
- #endif /* CONFIG_MIPS_MT_SMTC */
-
- .macro fpu_save_16even thread tmp=t0
- + .set push
- + SET_HARDFLOAT
- cfc1 \tmp, fcr31
- sdc1 $f0, THREAD_FPR0(\thread)
- sdc1 $f2, THREAD_FPR2(\thread)
- @@ -92,11 +94,13 @@
- sdc1 $f28, THREAD_FPR28(\thread)
- sdc1 $f30, THREAD_FPR30(\thread)
- sw \tmp, THREAD_FCR31(\thread)
- + .set pop
- .endm
-
- .macro fpu_save_16odd thread
- .set push
- .set mips64r2
- + SET_HARDFLOAT
- sdc1 $f1, THREAD_FPR1(\thread)
- sdc1 $f3, THREAD_FPR3(\thread)
- sdc1 $f5, THREAD_FPR5(\thread)
- @@ -127,6 +131,8 @@
- .endm
-
- .macro fpu_restore_16even thread tmp=t0
- + .set push
- + SET_HARDFLOAT
- lw \tmp, THREAD_FCR31(\thread)
- ldc1 $f0, THREAD_FPR0(\thread)
- ldc1 $f2, THREAD_FPR2(\thread)
- @@ -150,6 +156,7 @@
- .macro fpu_restore_16odd thread
- .set push
- .set mips64r2
- + SET_HARDFLOAT
- ldc1 $f1, THREAD_FPR1(\thread)
- ldc1 $f3, THREAD_FPR3(\thread)
- ldc1 $f5, THREAD_FPR5(\thread)
- diff --git a/arch/mips/include/asm/fpregdef.h b/arch/mips/include/asm/fpregdef.h
- index 429481f..f184ba0 100644
- --- a/arch/mips/include/asm/fpregdef.h
- +++ b/arch/mips/include/asm/fpregdef.h
- @@ -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
-
- /*
- diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
- index bbc3dd4..d68ad1e 100644
- --- a/arch/mips/include/asm/mipsregs.h
- +++ b/arch/mips/include/asm/mipsregs.h
- @@ -1251,7 +1251,7 @@ do { \
- /*
- * Macros to access the floating point coprocessor control registers
- */
- -#define read_32bit_cp1_register(source) \
- +#define _read_32bit_cp1_register(source, gas_hardfloat) \
- ({ \
- int __res; \
- \
- @@ -1261,12 +1261,21 @@ do { \
- " # gas fails to assemble cfc1 for some archs, \n" \
- " # like Octeon. \n" \
- " .set mips1 \n" \
- + " "STR(gas_hardfloat)" \n" \
- " cfc1 %0,"STR(source)" \n" \
- " .set pop \n" \
- : "=r" (__res)); \
- __res; \
- })
-
- +#ifdef GAS_HAS_SET_HARDFLOAT
- +#define read_32bit_cp1_register(source) \
- + _read_32bit_cp1_register(source, .set hardfloat)
- +#else
- +#define read_32bit_cp1_register(source) \
- + _read_32bit_cp1_register(source, )
- +#endif
- +
- #ifdef HAVE_AS_DSP
- #define rddsp(mask) \
- ({ \
- diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
- index 4d78bf4..aa5dbd3 100644
- --- a/arch/mips/kernel/branch.c
- +++ b/arch/mips/kernel/branch.c
- @@ -366,7 +366,7 @@ int __compute_return_epc_for_insn(struct pt_regs *regs,
- case cop1_op:
- preempt_disable();
- if (is_fpu_owner())
- - asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
- + fcr31 = read_32bit_cp1_register(CP1_STATUS);
- else
- fcr31 = current->thread.fpu.fcr31;
- preempt_enable();
- diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
- index d84f6a5..00b507f 100644
- --- a/arch/mips/kernel/genex.S
- +++ b/arch/mips/kernel/genex.S
- @@ -408,6 +408,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
- diff --git a/arch/mips/kernel/r2300_fpu.S b/arch/mips/kernel/r2300_fpu.S
- index f31063d..5ce3b74 100644
- --- a/arch/mips/kernel/r2300_fpu.S
- +++ b/arch/mips/kernel/r2300_fpu.S
- @@ -28,6 +28,8 @@
- .set mips1
- /* Save floating point context */
- LEAF(_save_fp_context)
- + .set push
- + SET_HARDFLOAT
- li v0, 0 # assume success
- cfc1 t1,fcr31
- EX(swc1 $f0,(SC_FPREGS+0)(a0))
- @@ -65,6 +67,7 @@ LEAF(_save_fp_context)
- EX(sw t1,(SC_FPC_CSR)(a0))
- cfc1 t0,$0 # implementation/version
- jr ra
- + .set pop
- .set nomacro
- EX(sw t0,(SC_FPC_EIR)(a0))
- .set macro
- @@ -80,6 +83,8 @@ LEAF(_save_fp_context)
- * stack frame which might have been changed by the user.
- */
- LEAF(_restore_fp_context)
- + .set push
- + SET_HARDFLOAT
- li v0, 0 # assume success
- EX(lw t0,(SC_FPC_CSR)(a0))
- EX(lwc1 $f0,(SC_FPREGS+0)(a0))
- @@ -116,6 +121,7 @@ LEAF(_restore_fp_context)
- EX(lwc1 $f31,(SC_FPREGS+248)(a0))
- jr ra
- ctc1 t0,fcr31
- + .set pop
- END(_restore_fp_context)
- .set reorder
-
- diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S
- index 20b7b04..435ea65 100644
- --- a/arch/mips/kernel/r2300_switch.S
- +++ b/arch/mips/kernel/r2300_switch.S
- @@ -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
- diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
- index 73b0ddf..06f8b2a 100644
- --- a/arch/mips/kernel/r4k_fpu.S
- +++ b/arch/mips/kernel/r4k_fpu.S
- @@ -19,8 +19,12 @@
- #include <asm/asm-offsets.h>
- #include <asm/regdef.h>
-
- +/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
- +#undef fp
- +
- .macro EX insn, reg, src
- .set push
- + SET_HARDFLOAT
- .set nomacro
- .ex\@: \insn \reg, \src
- .set pop
- @@ -33,12 +37,17 @@
- .set mips3
-
- LEAF(_save_fp_context)
- + .set push
- + SET_HARDFLOAT
- cfc1 t1, fcr31
- + .set pop
-
- #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
- .set push
- + SET_HARDFLOAT
- #ifdef CONFIG_CPU_MIPS32_R2
- - .set mips64r2
- + .set mips32r2
- + .set fp=64
- mfc0 t0, CP0_STATUS
- sll t0, t0, 5
- bgez t0, 1f # skip storing odd if FR=0
- @@ -64,6 +73,8 @@ LEAF(_save_fp_context)
- 1: .set pop
- #endif
-
- + .set push
- + SET_HARDFLOAT
- /* Store the 16 even double precision registers */
- EX sdc1 $f0, SC_FPREGS+0(a0)
- EX sdc1 $f2, SC_FPREGS+16(a0)
- @@ -84,11 +95,14 @@ LEAF(_save_fp_context)
- EX sw t1, SC_FPC_CSR(a0)
- jr ra
- li v0, 0 # success
- + .set pop
- END(_save_fp_context)
-
- #ifdef CONFIG_MIPS32_COMPAT
- /* Save 32-bit process floating point context */
- LEAF(_save_fp_context32)
- + .set push
- + SET_HARDFLOAT
- cfc1 t1, fcr31
-
- mfc0 t0, CP0_STATUS
- @@ -134,6 +148,7 @@ LEAF(_save_fp_context32)
- EX sw t1, SC32_FPC_CSR(a0)
- cfc1 t0, $0 # implementation/version
- EX sw t0, SC32_FPC_EIR(a0)
- + .set pop
-
- jr ra
- li v0, 0 # success
- @@ -150,8 +165,10 @@ LEAF(_restore_fp_context)
-
- #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
- .set push
- + SET_HARDFLOAT
- #ifdef CONFIG_CPU_MIPS32_R2
- - .set mips64r2
- + .set mips32r2
- + .set fp=64
- mfc0 t0, CP0_STATUS
- sll t0, t0, 5
- bgez t0, 1f # skip loading odd if FR=0
- @@ -175,6 +192,8 @@ LEAF(_restore_fp_context)
- EX ldc1 $f31, SC_FPREGS+248(a0)
- 1: .set pop
- #endif
- + .set push
- + SET_HARDFLOAT
- EX ldc1 $f0, SC_FPREGS+0(a0)
- EX ldc1 $f2, SC_FPREGS+16(a0)
- EX ldc1 $f4, SC_FPREGS+32(a0)
- @@ -192,6 +211,7 @@ LEAF(_restore_fp_context)
- EX ldc1 $f28, SC_FPREGS+224(a0)
- EX ldc1 $f30, SC_FPREGS+240(a0)
- ctc1 t1, fcr31
- + .set pop
- jr ra
- li v0, 0 # success
- END(_restore_fp_context)
- @@ -199,6 +219,8 @@ LEAF(_restore_fp_context)
- #ifdef CONFIG_MIPS32_COMPAT
- LEAF(_restore_fp_context32)
- /* Restore an o32 sigcontext. */
- + .set push
- + SET_HARDFLOAT
- EX lw t1, SC32_FPC_CSR(a0)
-
- mfc0 t0, CP0_STATUS
- @@ -242,6 +264,7 @@ LEAF(_restore_fp_context32)
- ctc1 t1, fcr31
- jr ra
- li v0, 0 # success
- + .set pop
- END(_restore_fp_context32)
- #endif
-
- diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S
- index cc78dd9..83b4f05 100644
- --- a/arch/mips/kernel/r4k_switch.S
- +++ b/arch/mips/kernel/r4k_switch.S
- @@ -22,6 +22,9 @@
-
- #include <asm/asmmacro.h>
-
- +/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */
- +#undef fp
- +
- /*
- * Offset to the current process status flags, the first 32 bytes of the
- * stack are not used.
- @@ -151,6 +154,9 @@ LEAF(_restore_fp)
-
- #define FPU_DEFAULT 0x00000000
-
- + .set push
- + SET_HARDFLOAT
- +
- LEAF(_init_fpu)
- #ifdef CONFIG_MIPS_MT_SMTC
- /* Rather than manipulate per-VPE Status, set per-TC bit in TCStatus */
- @@ -231,7 +237,8 @@ LEAF(_init_fpu)
-
- #ifdef CONFIG_CPU_MIPS32_R2
- .set push
- - .set mips64r2
- + .set mips32r2
- + .set fp=64
- sll t0, t0, 5 # is Status.FR set?
- bgez t0, 1f # no: skip setting upper 32b
-
- @@ -290,3 +297,5 @@ LEAF(_init_fpu)
- #endif
- jr ra
- END(_init_fpu)
- +
- + .set pop /* SET_HARDFLOAT */
- diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S
- index da0fbe4..4707738 100644
- --- a/arch/mips/kernel/r6000_fpu.S
- +++ b/arch/mips/kernel/r6000_fpu.S
- @@ -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 */
- diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
- index 0b4e2e3..c0a0914 100644
- --- a/arch/mips/math-emu/cp1emu.c
- +++ b/arch/mips/math-emu/cp1emu.c
- @@ -817,7 +817,7 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
- if (insn.i_format.rs == bc_op) {
- preempt_disable();
- if (is_fpu_owner())
- - asm volatile("cfc1\t%0,$31" : "=r" (fcr31));
- + fcr31 = read_32bit_cp1_register(CP1_STATUS);
- else
- fcr31 = current->thread.fpu.fcr31;
- preempt_enable();
- --
- 2.4.5
|