diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 6f7978f..446a039 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -57,6 +57,15 @@ ifdef CONFIG_FUNCTION_GRAPH_TRACER endif cflags-y += $(call cc-option, -mno-check-zero-division) +GCC_VERSION = 60000 # $(shell ../../cross/mips/bcm7335/bin/mipsel-unknown-linux-gcc --version | grep ^mipsel-unknown-linux-gcc | sed 's/^.* //g' | sed -e 's/\.\([0-9][0-9]\)/\1/g' -e 's/\.\([0-9]\)/0\1/g' -e 's/^[0-9]\{3,4\}$$/&00/') +GCC_GTEQ_493 = $(shell expr $(GCC_VERSION) \>= 40903) +ifeq ($(GCC_GTEQ_493),1) + # oskwon fixed. + ifneq ($(call as-option,-Wa$(comma)-msoft-float,),) + cflags-y += -DGAS_HAS_SET_HARDFLOAT -Wa,-msoft-float + endif +endif + ifdef CONFIG_32BIT ld-emul = $(32bit-emul) vmlinux-32 = vmlinux diff --git a/arch/mips/brcmstb/vector.S b/arch/mips/brcmstb/vector.S index 6eab27b..12c36e2 100644 --- a/arch/mips/brcmstb/vector.S +++ b/arch/mips/brcmstb/vector.S @@ -27,10 +27,19 @@ #include .macro CLR_FPR a b c d +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif mtc1 $0, $\a mtc1 $0, $\b mtc1 $0, $\c mtc1 $0, $\d +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop +#endif .endm .macro BARRIER diff --git a/arch/mips/include/asm/asmmacro-32.h b/arch/mips/include/asm/asmmacro-32.h index 2413afe..7ac5413 100644 --- a/arch/mips/include/asm/asmmacro-32.h +++ b/arch/mips/include/asm/asmmacro-32.h @@ -13,6 +13,11 @@ #include .macro fpu_save_double thread status tmp1=t0 +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif cfc1 \tmp1, fcr31 sdc1 $f0, THREAD_FPR0(\thread) sdc1 $f2, THREAD_FPR2(\thread) @@ -31,9 +36,18 @@ sdc1 $f28, THREAD_FPR28(\thread) sdc1 $f30, THREAD_FPR30(\thread) sw \tmp1, THREAD_FCR31(\thread) +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop +#endif .endm .macro fpu_save_single thread tmp=t0 +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif cfc1 \tmp, fcr31 swc1 $f0, THREAD_FPR0(\thread) swc1 $f1, THREAD_FPR1(\thread) @@ -68,9 +82,18 @@ swc1 $f30, THREAD_FPR30(\thread) swc1 $f31, THREAD_FPR31(\thread) sw \tmp, THREAD_FCR31(\thread) +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop +#endif .endm .macro fpu_restore_double thread status tmp=t0 +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif lw \tmp, THREAD_FCR31(\thread) ldc1 $f0, THREAD_FPR0(\thread) ldc1 $f2, THREAD_FPR2(\thread) @@ -89,9 +112,18 @@ ldc1 $f28, THREAD_FPR28(\thread) ldc1 $f30, THREAD_FPR30(\thread) ctc1 \tmp, fcr31 +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop +#endif .endm .macro fpu_restore_single thread tmp=t0 +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif lw \tmp, THREAD_FCR31(\thread) lwc1 $f0, THREAD_FPR0(\thread) lwc1 $f1, THREAD_FPR1(\thread) @@ -126,9 +158,18 @@ lwc1 $f30, THREAD_FPR30(\thread) lwc1 $f31, THREAD_FPR31(\thread) ctc1 \tmp, fcr31 +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop +#endif .endm .macro cpu_save_nonscratch thread +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif LONG_S s0, THREAD_REG16(\thread) LONG_S s1, THREAD_REG17(\thread) LONG_S s2, THREAD_REG18(\thread) @@ -142,6 +183,11 @@ .endm .macro cpu_restore_nonscratch thread +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif LONG_L s0, THREAD_REG16(\thread) LONG_L s1, THREAD_REG17(\thread) LONG_L s2, THREAD_REG18(\thread) diff --git a/arch/mips/include/asm/fpregdef.h b/arch/mips/include/asm/fpregdef.h index 429481f..6396e21 100644 --- a/arch/mips/include/asm/fpregdef.h +++ b/arch/mips/include/asm/fpregdef.h @@ -14,6 +14,25 @@ #include +#define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +/*oskwon fixed.*/ +/* + * 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 0da44d4..f338747 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -1144,7 +1144,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; \ \ @@ -1154,11 +1154,19 @@ 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 83ffe95..920168b 100644 --- a/arch/mips/kernel/branch.c +++ b/arch/mips/kernel/branch.c @@ -188,7 +188,12 @@ int __compute_return_epc_for_insn(struct pt_regs *regs, case cop1_op: preempt_disable(); if (is_fpu_owner()) +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + fcr31 = read_32bit_cp1_register(CP1_STATUS); /*oskwon*/ +#else asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); +#endif else fcr31 = current->thread.fpu.fcr31; preempt_enable(); diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index bcd9a7c..bc09cf5 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S @@ -387,6 +387,10 @@ NESTED(nmi_handler, PT_SIZE, sp) .set push /* gas fails to assemble cfc1 for some archs (octeon).*/ \ .set mips1 +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + SET_HARDFLOAT +#endif 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..d2520ca 100644 --- a/arch/mips/kernel/r2300_fpu.S +++ b/arch/mips/kernel/r2300_fpu.S @@ -28,6 +28,11 @@ .set mips1 /* Save floating point context */ LEAF(_save_fp_context) +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif li v0, 0 # assume success cfc1 t1,fcr31 EX(swc1 $f0,(SC_FPREGS+0)(a0)) @@ -65,6 +70,10 @@ LEAF(_save_fp_context) EX(sw t1,(SC_FPC_CSR)(a0)) cfc1 t0,$0 # implementation/version jr ra +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop +#endif .set nomacro EX(sw t0,(SC_FPC_EIR)(a0)) .set macro @@ -80,6 +89,11 @@ LEAF(_save_fp_context) * stack frame which might have been changed by the user. */ LEAF(_restore_fp_context) +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif li v0, 0 # assume success EX(lw t0,(SC_FPC_CSR)(a0)) EX(lwc1 $f0,(SC_FPREGS+0)(a0)) @@ -116,6 +130,10 @@ LEAF(_restore_fp_context) EX(lwc1 $f31,(SC_FPREGS+248)(a0)) jr ra ctc1 t0,fcr31 +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop +#endif END(_restore_fp_context) .set reorder diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 5266c6e..4bd0684 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S @@ -113,6 +113,12 @@ LEAF(_restore_fp) #define FPU_DEFAULT 0x00000000 +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif + LEAF(_init_fpu) mfc0 t0, CP0_STATUS li t1, ST0_CU1 @@ -158,3 +164,9 @@ LEAF(_init_fpu) mtc1 t0, $f31 jr ra END(_init_fpu) + +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop +#endif + diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S index 55ffe14..485e915 100644 --- a/arch/mips/kernel/r4k_fpu.S +++ b/arch/mips/kernel/r4k_fpu.S @@ -19,8 +19,18 @@ #include #include +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 +/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */ +#undef fp +#endif + .macro EX insn, reg, src .set push +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + SET_HARDFLOAT +#endif .set nomacro .ex\@: \insn \reg, \src .set pop @@ -33,7 +43,16 @@ .set mips3 LEAF(_save_fp_context) +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif cfc1 t1, fcr31 +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop +#endif #ifdef CONFIG_64BIT /* Store the 16 odd double precision registers */ @@ -54,8 +73,12 @@ LEAF(_save_fp_context) EX sdc1 $f29, SC_FPREGS+232(a0) EX sdc1 $f31, SC_FPREGS+248(a0) #endif - /* Store the 16 even double precision registers */ +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif EX sdc1 $f0, SC_FPREGS+0(a0) EX sdc1 $f2, SC_FPREGS+16(a0) EX sdc1 $f4, SC_FPREGS+32(a0) @@ -75,11 +98,20 @@ LEAF(_save_fp_context) EX sw t1, SC_FPC_CSR(a0) jr ra li v0, 0 # success +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop +#endif END(_save_fp_context) #ifdef CONFIG_MIPS32_COMPAT /* Save 32-bit process floating point context */ LEAF(_save_fp_context32) +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif cfc1 t1, fcr31 EX sdc1 $f0, SC32_FPREGS+0(a0) @@ -101,6 +133,10 @@ LEAF(_save_fp_context32) EX sw t1, SC32_FPC_CSR(a0) cfc1 t0, $0 # implementation/version EX sw t0, SC32_FPC_EIR(a0) +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop +#endif jr ra li v0, 0 # success @@ -132,6 +168,12 @@ LEAF(_restore_fp_context) EX ldc1 $f29, SC_FPREGS+232(a0) EX ldc1 $f31, SC_FPREGS+248(a0) #endif + +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif EX ldc1 $f0, SC_FPREGS+0(a0) EX ldc1 $f2, SC_FPREGS+16(a0) EX ldc1 $f4, SC_FPREGS+32(a0) @@ -149,6 +191,10 @@ LEAF(_restore_fp_context) EX ldc1 $f28, SC_FPREGS+224(a0) EX ldc1 $f30, SC_FPREGS+240(a0) ctc1 t0, fcr31 +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop +#endif jr ra li v0, 0 # success END(_restore_fp_context) @@ -156,6 +202,11 @@ LEAF(_restore_fp_context) #ifdef CONFIG_MIPS32_COMPAT LEAF(_restore_fp_context32) /* Restore an o32 sigcontext. */ +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif EX lw t0, SC32_FPC_CSR(a0) EX ldc1 $f0, SC32_FPREGS+0(a0) EX ldc1 $f2, SC32_FPREGS+16(a0) @@ -176,6 +227,10 @@ LEAF(_restore_fp_context32) ctc1 t0, fcr31 jr ra li v0, 0 # success +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop +#endif END(_restore_fp_context32) #endif diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 5e51219..1c5bc5c 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -22,6 +22,12 @@ #include +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 +/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */ +#undef fp +#endif + /* * Offset to the current process status flags, the first 32 bytes of the * stack are not used. @@ -145,6 +151,12 @@ LEAF(_restore_fp) #define FPU_DEFAULT 0x00000000 +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif + LEAF(_init_fpu) #ifdef CONFIG_MIPS_MT_SMTC /* Rather than manipulate per-VPE Status, set per-TC bit in TCStatus */ @@ -243,3 +255,9 @@ LEAF(_init_fpu) #endif jr ra END(_init_fpu) + +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop /* SET_HARDFLOAT */ +#endif + diff --git a/arch/mips/kernel/r6000_fpu.S b/arch/mips/kernel/r6000_fpu.S index da0fbe4..4299891 100644 --- a/arch/mips/kernel/r6000_fpu.S +++ b/arch/mips/kernel/r6000_fpu.S @@ -18,6 +18,11 @@ .set noreorder .set mips2 +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set push + SET_HARDFLOAT +#endif /* Save floating point context */ LEAF(_save_fp_context) mfc0 t0,CP0_STATUS @@ -48,6 +53,10 @@ 1: jr ra nop END(_save_fp_context) +/* Test for GCC >= 4.9.3 */ +#if GCC_VERSION >= 40903 + .set pop /* SET_HARDFLOAT */ +#endif /* Restore FPU state: * - fp gp registers