Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Manuel Lauss and committed by
Ralf Baechle
842dfc11 491a48aa

+118 -17
+9
arch/mips/Makefile
··· 93 93 KBUILD_AFLAGS_MODULE += -mlong-calls 94 94 KBUILD_CFLAGS_MODULE += -mlong-calls 95 95 96 + # 97 + # pass -msoft-float to GAS if it supports it. However on newer binutils 98 + # (specifically newer than 2.24.51.20140728) we then also need to explicitly 99 + # set ".set hardfloat" in all files which manipulate floating point registers. 100 + # 101 + ifneq ($(call as-option,-Wa$(comma)-msoft-float,),) 102 + cflags-y += -DGAS_HAS_SET_HARDFLOAT -Wa,-msoft-float 103 + endif 104 + 96 105 cflags-y += -ffreestanding 97 106 98 107 #
+6
arch/mips/include/asm/asmmacro-32.h
··· 13 13 #include <asm/mipsregs.h> 14 14 15 15 .macro fpu_save_single thread tmp=t0 16 + .set push 17 + SET_HARDFLOAT 16 18 cfc1 \tmp, fcr31 17 19 swc1 $f0, THREAD_FPR0_LS64(\thread) 18 20 swc1 $f1, THREAD_FPR1_LS64(\thread) ··· 49 47 swc1 $f30, THREAD_FPR30_LS64(\thread) 50 48 swc1 $f31, THREAD_FPR31_LS64(\thread) 51 49 sw \tmp, THREAD_FCR31(\thread) 50 + .set pop 52 51 .endm 53 52 54 53 .macro fpu_restore_single thread tmp=t0 54 + .set push 55 + SET_HARDFLOAT 55 56 lw \tmp, THREAD_FCR31(\thread) 56 57 lwc1 $f0, THREAD_FPR0_LS64(\thread) 57 58 lwc1 $f1, THREAD_FPR1_LS64(\thread) ··· 89 84 lwc1 $f30, THREAD_FPR30_LS64(\thread) 90 85 lwc1 $f31, THREAD_FPR31_LS64(\thread) 91 86 ctc1 \tmp, fcr31 87 + .set pop 92 88 .endm 93 89 94 90 .macro cpu_save_nonscratch thread
+18
arch/mips/include/asm/asmmacro.h
··· 57 57 #endif /* CONFIG_CPU_MIPSR2 */ 58 58 59 59 .macro fpu_save_16even thread tmp=t0 60 + .set push 61 + SET_HARDFLOAT 60 62 cfc1 \tmp, fcr31 61 63 sdc1 $f0, THREAD_FPR0_LS64(\thread) 62 64 sdc1 $f2, THREAD_FPR2_LS64(\thread) ··· 77 75 sdc1 $f28, THREAD_FPR28_LS64(\thread) 78 76 sdc1 $f30, THREAD_FPR30_LS64(\thread) 79 77 sw \tmp, THREAD_FCR31(\thread) 78 + .set pop 80 79 .endm 81 80 82 81 .macro fpu_save_16odd thread 83 82 .set push 84 83 .set mips64r2 84 + SET_HARDFLOAT 85 85 sdc1 $f1, THREAD_FPR1_LS64(\thread) 86 86 sdc1 $f3, THREAD_FPR3_LS64(\thread) 87 87 sdc1 $f5, THREAD_FPR5_LS64(\thread) ··· 114 110 .endm 115 111 116 112 .macro fpu_restore_16even thread tmp=t0 113 + .set push 114 + SET_HARDFLOAT 117 115 lw \tmp, THREAD_FCR31(\thread) 118 116 ldc1 $f0, THREAD_FPR0_LS64(\thread) 119 117 ldc1 $f2, THREAD_FPR2_LS64(\thread) ··· 139 133 .macro fpu_restore_16odd thread 140 134 .set push 141 135 .set mips64r2 136 + SET_HARDFLOAT 142 137 ldc1 $f1, THREAD_FPR1_LS64(\thread) 143 138 ldc1 $f3, THREAD_FPR3_LS64(\thread) 144 139 ldc1 $f5, THREAD_FPR5_LS64(\thread) ··· 284 277 .macro cfcmsa rd, cs 285 278 .set push 286 279 .set noat 280 + SET_HARDFLOAT 287 281 .insn 288 282 .word CFC_MSA_INSN | (\cs << 11) 289 283 move \rd, $1 ··· 294 286 .macro ctcmsa cd, rs 295 287 .set push 296 288 .set noat 289 + SET_HARDFLOAT 297 290 move $1, \rs 298 291 .word CTC_MSA_INSN | (\cd << 6) 299 292 .set pop ··· 303 294 .macro ld_d wd, off, base 304 295 .set push 305 296 .set noat 297 + SET_HARDFLOAT 306 298 add $1, \base, \off 307 299 .word LDD_MSA_INSN | (\wd << 6) 308 300 .set pop ··· 312 302 .macro st_d wd, off, base 313 303 .set push 314 304 .set noat 305 + SET_HARDFLOAT 315 306 add $1, \base, \off 316 307 .word STD_MSA_INSN | (\wd << 6) 317 308 .set pop ··· 321 310 .macro copy_u_w rd, ws, n 322 311 .set push 323 312 .set noat 313 + SET_HARDFLOAT 324 314 .insn 325 315 .word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11) 326 316 /* move triggers an assembler bug... */ ··· 332 320 .macro copy_u_d rd, ws, n 333 321 .set push 334 322 .set noat 323 + SET_HARDFLOAT 335 324 .insn 336 325 .word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11) 337 326 /* move triggers an assembler bug... */ ··· 343 330 .macro insert_w wd, n, rs 344 331 .set push 345 332 .set noat 333 + SET_HARDFLOAT 346 334 /* move triggers an assembler bug... */ 347 335 or $1, \rs, zero 348 336 .word INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6) ··· 353 339 .macro insert_d wd, n, rs 354 340 .set push 355 341 .set noat 342 + SET_HARDFLOAT 356 343 /* move triggers an assembler bug... */ 357 344 or $1, \rs, zero 358 345 .word INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6) ··· 396 381 st_d 31, THREAD_FPR31, \thread 397 382 .set push 398 383 .set noat 384 + SET_HARDFLOAT 399 385 cfcmsa $1, MSA_CSR 400 386 sw $1, THREAD_MSA_CSR(\thread) 401 387 .set pop ··· 405 389 .macro msa_restore_all thread 406 390 .set push 407 391 .set noat 392 + SET_HARDFLOAT 408 393 lw $1, THREAD_MSA_CSR(\thread) 409 394 ctcmsa MSA_CSR, $1 410 395 .set pop ··· 458 441 .macro msa_init_all_upper 459 442 .set push 460 443 .set noat 444 + SET_HARDFLOAT 461 445 not $1, zero 462 446 msa_init_upper 0 463 447 .set pop
+14
arch/mips/include/asm/fpregdef.h
··· 14 14 15 15 #include <asm/sgidefs.h> 16 16 17 + /* 18 + * starting with binutils 2.24.51.20140729, MIPS binutils warn about mixing 19 + * hardfloat and softfloat object files. The kernel build uses soft-float by 20 + * default, so we also need to pass -msoft-float along to GAS if it supports it. 21 + * But this in turn causes assembler errors in files which access hardfloat 22 + * registers. We detect if GAS supports "-msoft-float" in the Makefile and 23 + * explicitly put ".set hardfloat" where floating point registers are touched. 24 + */ 25 + #ifdef GAS_HAS_SET_HARDFLOAT 26 + #define SET_HARDFLOAT .set hardfloat 27 + #else 28 + #define SET_HARDFLOAT 29 + #endif 30 + 17 31 #if _MIPS_SIM == _MIPS_SIM_ABI32 18 32 19 33 /*
+2 -2
arch/mips/include/asm/fpu.h
··· 145 145 if (is_msa_enabled()) { 146 146 if (save) { 147 147 save_msa(current); 148 - asm volatile("cfc1 %0, $31" 149 - : "=r"(current->thread.fpu.fcr31)); 148 + current->thread.fpu.fcr31 = 149 + read_32bit_cp1_register(CP1_STATUS); 150 150 } 151 151 disable_msa(); 152 152 clear_thread_flag(TIF_USEDMSA);
+10 -1
arch/mips/include/asm/mipsregs.h
··· 1324 1324 /* 1325 1325 * Macros to access the floating point coprocessor control registers 1326 1326 */ 1327 - #define read_32bit_cp1_register(source) \ 1327 + #define _read_32bit_cp1_register(source, gas_hardfloat) \ 1328 1328 ({ \ 1329 1329 int __res; \ 1330 1330 \ ··· 1334 1334 " # gas fails to assemble cfc1 for some archs, \n" \ 1335 1335 " # like Octeon. \n" \ 1336 1336 " .set mips1 \n" \ 1337 + " "STR(gas_hardfloat)" \n" \ 1337 1338 " cfc1 %0,"STR(source)" \n" \ 1338 1339 " .set pop \n" \ 1339 1340 : "=r" (__res)); \ 1340 1341 __res; \ 1341 1342 }) 1343 + 1344 + #ifdef GAS_HAS_SET_HARDFLOAT 1345 + #define read_32bit_cp1_register(source) \ 1346 + _read_32bit_cp1_register(source, .set hardfloat) 1347 + #else 1348 + #define read_32bit_cp1_register(source) \ 1349 + _read_32bit_cp1_register(source, ) 1350 + #endif 1342 1351 1343 1352 #ifdef HAVE_AS_DSP 1344 1353 #define rddsp(mask) \
+2 -6
arch/mips/kernel/branch.c
··· 144 144 case mm_bc1t_op: 145 145 preempt_disable(); 146 146 if (is_fpu_owner()) 147 - asm volatile("cfc1\t%0,$31" : "=r" (fcr31)); 147 + fcr31 = read_32bit_cp1_register(CP1_STATUS); 148 148 else 149 149 fcr31 = current->thread.fpu.fcr31; 150 150 preempt_enable(); ··· 562 562 case cop1_op: 563 563 preempt_disable(); 564 564 if (is_fpu_owner()) 565 - asm volatile( 566 - ".set push\n" 567 - "\t.set mips1\n" 568 - "\tcfc1\t%0,$31\n" 569 - "\t.set pop" : "=r" (fcr31)); 565 + fcr31 = read_32bit_cp1_register(CP1_STATUS); 570 566 else 571 567 fcr31 = current->thread.fpu.fcr31; 572 568 preempt_enable();
+1
arch/mips/kernel/genex.S
··· 358 358 .set push 359 359 /* gas fails to assemble cfc1 for some archs (octeon).*/ \ 360 360 .set mips1 361 + SET_HARDFLOAT 361 362 cfc1 a1, fcr31 362 363 li a2, ~(0x3f << 12) 363 364 and a2, a1
+6
arch/mips/kernel/r2300_fpu.S
··· 28 28 .set mips1 29 29 /* Save floating point context */ 30 30 LEAF(_save_fp_context) 31 + .set push 32 + SET_HARDFLOAT 31 33 li v0, 0 # assume success 32 34 cfc1 t1,fcr31 33 35 EX(swc1 $f0,(SC_FPREGS+0)(a0)) ··· 67 65 EX(sw t1,(SC_FPC_CSR)(a0)) 68 66 cfc1 t0,$0 # implementation/version 69 67 jr ra 68 + .set pop 70 69 .set nomacro 71 70 EX(sw t0,(SC_FPC_EIR)(a0)) 72 71 .set macro ··· 83 80 * stack frame which might have been changed by the user. 84 81 */ 85 82 LEAF(_restore_fp_context) 83 + .set push 84 + SET_HARDFLOAT 86 85 li v0, 0 # assume success 87 86 EX(lw t0,(SC_FPC_CSR)(a0)) 88 87 EX(lwc1 $f0,(SC_FPREGS+0)(a0)) ··· 121 116 EX(lwc1 $f31,(SC_FPREGS+248)(a0)) 122 117 jr ra 123 118 ctc1 t0,fcr31 119 + .set pop 124 120 END(_restore_fp_context) 125 121 .set reorder 126 122
+5
arch/mips/kernel/r2300_switch.S
··· 120 120 121 121 #define FPU_DEFAULT 0x00000000 122 122 123 + .set push 124 + SET_HARDFLOAT 125 + 123 126 LEAF(_init_fpu) 124 127 mfc0 t0, CP0_STATUS 125 128 li t1, ST0_CU1 ··· 168 165 mtc1 t0, $f31 169 166 jr ra 170 167 END(_init_fpu) 168 + 169 + .set pop
+25 -2
arch/mips/kernel/r4k_fpu.S
··· 19 19 #include <asm/asm-offsets.h> 20 20 #include <asm/regdef.h> 21 21 22 + /* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */ 23 + #undef fp 24 + 22 25 .macro EX insn, reg, src 23 26 .set push 27 + SET_HARDFLOAT 24 28 .set nomacro 25 29 .ex\@: \insn \reg, \src 26 30 .set pop ··· 37 33 .set arch=r4000 38 34 39 35 LEAF(_save_fp_context) 36 + .set push 37 + SET_HARDFLOAT 40 38 cfc1 t1, fcr31 39 + .set pop 41 40 42 41 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) 43 42 .set push 43 + SET_HARDFLOAT 44 44 #ifdef CONFIG_CPU_MIPS32_R2 45 - .set mips64r2 45 + .set mips32r2 46 + .set fp=64 46 47 mfc0 t0, CP0_STATUS 47 48 sll t0, t0, 5 48 49 bgez t0, 1f # skip storing odd if FR=0 ··· 73 64 1: .set pop 74 65 #endif 75 66 67 + .set push 68 + SET_HARDFLOAT 76 69 /* Store the 16 even double precision registers */ 77 70 EX sdc1 $f0, SC_FPREGS+0(a0) 78 71 EX sdc1 $f2, SC_FPREGS+16(a0) ··· 95 84 EX sw t1, SC_FPC_CSR(a0) 96 85 jr ra 97 86 li v0, 0 # success 87 + .set pop 98 88 END(_save_fp_context) 99 89 100 90 #ifdef CONFIG_MIPS32_COMPAT 101 91 /* Save 32-bit process floating point context */ 102 92 LEAF(_save_fp_context32) 93 + .set push 94 + SET_HARDFLOAT 103 95 cfc1 t1, fcr31 104 96 105 97 mfc0 t0, CP0_STATUS ··· 148 134 EX sw t1, SC32_FPC_CSR(a0) 149 135 cfc1 t0, $0 # implementation/version 150 136 EX sw t0, SC32_FPC_EIR(a0) 137 + .set pop 151 138 152 139 jr ra 153 140 li v0, 0 # success ··· 165 150 166 151 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2) 167 152 .set push 153 + SET_HARDFLOAT 168 154 #ifdef CONFIG_CPU_MIPS32_R2 169 - .set mips64r2 155 + .set mips32r2 156 + .set fp=64 170 157 mfc0 t0, CP0_STATUS 171 158 sll t0, t0, 5 172 159 bgez t0, 1f # skip loading odd if FR=0 ··· 192 175 EX ldc1 $f31, SC_FPREGS+248(a0) 193 176 1: .set pop 194 177 #endif 178 + .set push 179 + SET_HARDFLOAT 195 180 EX ldc1 $f0, SC_FPREGS+0(a0) 196 181 EX ldc1 $f2, SC_FPREGS+16(a0) 197 182 EX ldc1 $f4, SC_FPREGS+32(a0) ··· 211 192 EX ldc1 $f28, SC_FPREGS+224(a0) 212 193 EX ldc1 $f30, SC_FPREGS+240(a0) 213 194 ctc1 t1, fcr31 195 + .set pop 214 196 jr ra 215 197 li v0, 0 # success 216 198 END(_restore_fp_context) ··· 219 199 #ifdef CONFIG_MIPS32_COMPAT 220 200 LEAF(_restore_fp_context32) 221 201 /* Restore an o32 sigcontext. */ 202 + .set push 203 + SET_HARDFLOAT 222 204 EX lw t1, SC32_FPC_CSR(a0) 223 205 224 206 mfc0 t0, CP0_STATUS ··· 264 242 ctc1 t1, fcr31 265 243 jr ra 266 244 li v0, 0 # success 245 + .set pop 267 246 END(_restore_fp_context32) 268 247 #endif 269 248
+14 -1
arch/mips/kernel/r4k_switch.S
··· 22 22 23 23 #include <asm/asmmacro.h> 24 24 25 + /* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */ 26 + #undef fp 27 + 25 28 /* 26 29 * Offset to the current process status flags, the first 32 bytes of the 27 30 * stack are not used. ··· 68 65 bgtz a3, 1f 69 66 70 67 /* Save 128b MSA vector context + scalar FP control & status. */ 68 + .set push 69 + SET_HARDFLOAT 71 70 cfc1 t1, fcr31 72 71 msa_save_all a0 72 + .set pop /* SET_HARDFLOAT */ 73 + 73 74 sw t1, THREAD_FCR31(a0) 74 75 b 2f 75 76 ··· 168 161 169 162 #define FPU_DEFAULT 0x00000000 170 163 164 + .set push 165 + SET_HARDFLOAT 166 + 171 167 LEAF(_init_fpu) 172 168 mfc0 t0, CP0_STATUS 173 169 li t1, ST0_CU1 ··· 242 232 243 233 #ifdef CONFIG_CPU_MIPS32_R2 244 234 .set push 245 - .set mips64r2 235 + .set mips32r2 236 + .set fp=64 246 237 sll t0, t0, 5 # is Status.FR set? 247 238 bgez t0, 1f # no: skip setting upper 32b 248 239 ··· 302 291 #endif 303 292 jr ra 304 293 END(_init_fpu) 294 + 295 + .set pop /* SET_HARDFLOAT */
+5
arch/mips/kernel/r6000_fpu.S
··· 18 18 19 19 .set noreorder 20 20 .set mips2 21 + .set push 22 + SET_HARDFLOAT 23 + 21 24 /* Save floating point context */ 22 25 LEAF(_save_fp_context) 23 26 mfc0 t0,CP0_STATUS ··· 88 85 1: jr ra 89 86 nop 90 87 END(_restore_fp_context) 88 + 89 + .set pop /* SET_HARDFLOAT */
+1 -5
arch/mips/math-emu/cp1emu.c
··· 584 584 if (insn.i_format.rs == bc_op) { 585 585 preempt_disable(); 586 586 if (is_fpu_owner()) 587 - asm volatile( 588 - ".set push\n" 589 - "\t.set mips1\n" 590 - "\tcfc1\t%0,$31\n" 591 - "\t.set pop" : "=r" (fcr31)); 587 + fcr31 = read_32bit_cp1_register(CP1_STATUS); 592 588 else 593 589 fcr31 = current->thread.fpu.fcr31; 594 590 preempt_enable();