Commit 842dfc11ea9a21f9825167c8a4f2834b205b0a79

Authored by Manuel Lauss
Committed by Ralf Baechle
1 parent 491a48aa52

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>

Showing 14 changed files with 118 additions and 17 deletions Side-by-side Diff

... ... @@ -93,6 +93,15 @@
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 #
arch/mips/include/asm/asmmacro-32.h
... ... @@ -13,6 +13,8 @@
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)
19 21  
... ... @@ -47,9 +49,12 @@
47 49 swc1 $f30, THREAD_FPR30_LS64(\thread)
48 50 swc1 $f31, THREAD_FPR31_LS64(\thread)
49 51 sw \tmp, THREAD_FCR31(\thread)
  52 + .set pop
50 53 .endm
51 54  
52 55 .macro fpu_restore_single thread tmp=t0
  56 + .set push
  57 + SET_HARDFLOAT
53 58 lw \tmp, THREAD_FCR31(\thread)
54 59 lwc1 $f0, THREAD_FPR0_LS64(\thread)
55 60 lwc1 $f1, THREAD_FPR1_LS64(\thread)
... ... @@ -84,6 +89,7 @@
84 89 lwc1 $f30, THREAD_FPR30_LS64(\thread)
85 90 lwc1 $f31, THREAD_FPR31_LS64(\thread)
86 91 ctc1 \tmp, fcr31
  92 + .set pop
87 93 .endm
88 94  
89 95 .macro cpu_save_nonscratch thread
arch/mips/include/asm/asmmacro.h
... ... @@ -57,6 +57,8 @@
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)
63 65  
... ... @@ -75,11 +77,13 @@
75 77 sdc1 $f28, THREAD_FPR28_LS64(\thread)
76 78 sdc1 $f30, THREAD_FPR30_LS64(\thread)
77 79 sw \tmp, THREAD_FCR31(\thread)
  80 + .set pop
78 81 .endm
79 82  
80 83 .macro fpu_save_16odd thread
81 84 .set push
82 85 .set mips64r2
  86 + SET_HARDFLOAT
83 87 sdc1 $f1, THREAD_FPR1_LS64(\thread)
84 88 sdc1 $f3, THREAD_FPR3_LS64(\thread)
85 89 sdc1 $f5, THREAD_FPR5_LS64(\thread)
... ... @@ -110,6 +114,8 @@
110 114 .endm
111 115  
112 116 .macro fpu_restore_16even thread tmp=t0
  117 + .set push
  118 + SET_HARDFLOAT
113 119 lw \tmp, THREAD_FCR31(\thread)
114 120 ldc1 $f0, THREAD_FPR0_LS64(\thread)
115 121 ldc1 $f2, THREAD_FPR2_LS64(\thread)
... ... @@ -133,6 +139,7 @@
133 139 .macro fpu_restore_16odd thread
134 140 .set push
135 141 .set mips64r2
  142 + SET_HARDFLOAT
136 143 ldc1 $f1, THREAD_FPR1_LS64(\thread)
137 144 ldc1 $f3, THREAD_FPR3_LS64(\thread)
138 145 ldc1 $f5, THREAD_FPR5_LS64(\thread)
... ... @@ -277,6 +284,7 @@
277 284 .macro cfcmsa rd, cs
278 285 .set push
279 286 .set noat
  287 + SET_HARDFLOAT
280 288 .insn
281 289 .word CFC_MSA_INSN | (\cs << 11)
282 290 move \rd, $1
... ... @@ -286,6 +294,7 @@
286 294 .macro ctcmsa cd, rs
287 295 .set push
288 296 .set noat
  297 + SET_HARDFLOAT
289 298 move $1, \rs
290 299 .word CTC_MSA_INSN | (\cd << 6)
291 300 .set pop
... ... @@ -294,6 +303,7 @@
294 303 .macro ld_d wd, off, base
295 304 .set push
296 305 .set noat
  306 + SET_HARDFLOAT
297 307 add $1, \base, \off
298 308 .word LDD_MSA_INSN | (\wd << 6)
299 309 .set pop
... ... @@ -302,6 +312,7 @@
302 312 .macro st_d wd, off, base
303 313 .set push
304 314 .set noat
  315 + SET_HARDFLOAT
305 316 add $1, \base, \off
306 317 .word STD_MSA_INSN | (\wd << 6)
307 318 .set pop
... ... @@ -310,6 +321,7 @@
310 321 .macro copy_u_w rd, ws, n
311 322 .set push
312 323 .set noat
  324 + SET_HARDFLOAT
313 325 .insn
314 326 .word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
315 327 /* move triggers an assembler bug... */
... ... @@ -320,6 +332,7 @@
320 332 .macro copy_u_d rd, ws, n
321 333 .set push
322 334 .set noat
  335 + SET_HARDFLOAT
323 336 .insn
324 337 .word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
325 338 /* move triggers an assembler bug... */
... ... @@ -330,6 +343,7 @@
330 343 .macro insert_w wd, n, rs
331 344 .set push
332 345 .set noat
  346 + SET_HARDFLOAT
333 347 /* move triggers an assembler bug... */
334 348 or $1, \rs, zero
335 349 .word INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6)
... ... @@ -339,6 +353,7 @@
339 353 .macro insert_d wd, n, rs
340 354 .set push
341 355 .set noat
  356 + SET_HARDFLOAT
342 357 /* move triggers an assembler bug... */
343 358 or $1, \rs, zero
344 359 .word INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6)
... ... @@ -381,6 +396,7 @@
381 396 st_d 31, THREAD_FPR31, \thread
382 397 .set push
383 398 .set noat
  399 + SET_HARDFLOAT
384 400 cfcmsa $1, MSA_CSR
385 401 sw $1, THREAD_MSA_CSR(\thread)
386 402 .set pop
... ... @@ -389,6 +405,7 @@
389 405 .macro msa_restore_all thread
390 406 .set push
391 407 .set noat
  408 + SET_HARDFLOAT
392 409 lw $1, THREAD_MSA_CSR(\thread)
393 410 ctcmsa MSA_CSR, $1
394 411 .set pop
... ... @@ -441,6 +458,7 @@
441 458 .macro msa_init_all_upper
442 459 .set push
443 460 .set noat
  461 + SET_HARDFLOAT
444 462 not $1, zero
445 463 msa_init_upper 0
446 464 .set pop
arch/mips/include/asm/fpregdef.h
... ... @@ -14,6 +14,20 @@
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 /*
arch/mips/include/asm/fpu.h
... ... @@ -145,8 +145,8 @@
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);
arch/mips/include/asm/mipsregs.h
... ... @@ -1324,7 +1324,7 @@
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 \
1331 1331  
... ... @@ -1334,11 +1334,20 @@
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) \
arch/mips/kernel/branch.c
... ... @@ -144,7 +144,7 @@
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,11 +562,7 @@
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();
arch/mips/kernel/genex.S
... ... @@ -358,6 +358,7 @@
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
arch/mips/kernel/r2300_fpu.S
... ... @@ -28,6 +28,8 @@
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))
... ... @@ -65,6 +67,7 @@
65 67 EX(sw t1,(SC_FPC_CSR)(a0))
66 68 cfc1 t0,$0 # implementation/version
67 69 jr ra
  70 + .set pop
68 71 .set nomacro
69 72 EX(sw t0,(SC_FPC_EIR)(a0))
70 73 .set macro
... ... @@ -80,6 +83,8 @@
80 83 * stack frame which might have been changed by the user.
81 84 */
82 85 LEAF(_restore_fp_context)
  86 + .set push
  87 + SET_HARDFLOAT
83 88 li v0, 0 # assume success
84 89 EX(lw t0,(SC_FPC_CSR)(a0))
85 90 EX(lwc1 $f0,(SC_FPREGS+0)(a0))
... ... @@ -116,6 +121,7 @@
116 121 EX(lwc1 $f31,(SC_FPREGS+248)(a0))
117 122 jr ra
118 123 ctc1 t0,fcr31
  124 + .set pop
119 125 END(_restore_fp_context)
120 126 .set reorder
121 127  
arch/mips/kernel/r2300_switch.S
... ... @@ -120,6 +120,9 @@
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
... ... @@ -165,4 +168,6 @@
165 168 mtc1 t0, $f31
166 169 jr ra
167 170 END(_init_fpu)
  171 +
  172 + .set pop
arch/mips/kernel/r4k_fpu.S
... ... @@ -19,8 +19,12 @@
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
27 31  
28 32  
29 33  
... ... @@ -33,12 +37,17 @@
33 37 .set arch=r4000
34 38  
35 39 LEAF(_save_fp_context)
  40 + .set push
  41 + SET_HARDFLOAT
36 42 cfc1 t1, fcr31
  43 + .set pop
37 44  
38 45 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
39 46 .set push
  47 + SET_HARDFLOAT
40 48 #ifdef CONFIG_CPU_MIPS32_R2
41   - .set mips64r2
  49 + .set mips32r2
  50 + .set fp=64
42 51 mfc0 t0, CP0_STATUS
43 52 sll t0, t0, 5
44 53 bgez t0, 1f # skip storing odd if FR=0
... ... @@ -64,6 +73,8 @@
64 73 1: .set pop
65 74 #endif
66 75  
  76 + .set push
  77 + SET_HARDFLOAT
67 78 /* Store the 16 even double precision registers */
68 79 EX sdc1 $f0, SC_FPREGS+0(a0)
69 80 EX sdc1 $f2, SC_FPREGS+16(a0)
70 81  
... ... @@ -84,11 +95,14 @@
84 95 EX sw t1, SC_FPC_CSR(a0)
85 96 jr ra
86 97 li v0, 0 # success
  98 + .set pop
87 99 END(_save_fp_context)
88 100  
89 101 #ifdef CONFIG_MIPS32_COMPAT
90 102 /* Save 32-bit process floating point context */
91 103 LEAF(_save_fp_context32)
  104 + .set push
  105 + SET_HARDFLOAT
92 106 cfc1 t1, fcr31
93 107  
94 108 mfc0 t0, CP0_STATUS
... ... @@ -134,6 +148,7 @@
134 148 EX sw t1, SC32_FPC_CSR(a0)
135 149 cfc1 t0, $0 # implementation/version
136 150 EX sw t0, SC32_FPC_EIR(a0)
  151 + .set pop
137 152  
138 153 jr ra
139 154 li v0, 0 # success
140 155  
... ... @@ -150,8 +165,10 @@
150 165  
151 166 #if defined(CONFIG_64BIT) || defined(CONFIG_CPU_MIPS32_R2)
152 167 .set push
  168 + SET_HARDFLOAT
153 169 #ifdef CONFIG_CPU_MIPS32_R2
154   - .set mips64r2
  170 + .set mips32r2
  171 + .set fp=64
155 172 mfc0 t0, CP0_STATUS
156 173 sll t0, t0, 5
157 174 bgez t0, 1f # skip loading odd if FR=0
... ... @@ -175,6 +192,8 @@
175 192 EX ldc1 $f31, SC_FPREGS+248(a0)
176 193 1: .set pop
177 194 #endif
  195 + .set push
  196 + SET_HARDFLOAT
178 197 EX ldc1 $f0, SC_FPREGS+0(a0)
179 198 EX ldc1 $f2, SC_FPREGS+16(a0)
180 199 EX ldc1 $f4, SC_FPREGS+32(a0)
... ... @@ -192,6 +211,7 @@
192 211 EX ldc1 $f28, SC_FPREGS+224(a0)
193 212 EX ldc1 $f30, SC_FPREGS+240(a0)
194 213 ctc1 t1, fcr31
  214 + .set pop
195 215 jr ra
196 216 li v0, 0 # success
197 217 END(_restore_fp_context)
... ... @@ -199,6 +219,8 @@
199 219 #ifdef CONFIG_MIPS32_COMPAT
200 220 LEAF(_restore_fp_context32)
201 221 /* Restore an o32 sigcontext. */
  222 + .set push
  223 + SET_HARDFLOAT
202 224 EX lw t1, SC32_FPC_CSR(a0)
203 225  
204 226 mfc0 t0, CP0_STATUS
... ... @@ -242,6 +264,7 @@
242 264 ctc1 t1, fcr31
243 265 jr ra
244 266 li v0, 0 # success
  267 + .set pop
245 268 END(_restore_fp_context32)
246 269 #endif
247 270  
arch/mips/kernel/r4k_switch.S
... ... @@ -22,6 +22,9 @@
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.
28 31  
... ... @@ -65,8 +68,12 @@
65 68 bgtz a3, 1f
66 69  
67 70 /* Save 128b MSA vector context + scalar FP control & status. */
  71 + .set push
  72 + SET_HARDFLOAT
68 73 cfc1 t1, fcr31
69 74 msa_save_all a0
  75 + .set pop /* SET_HARDFLOAT */
  76 +
70 77 sw t1, THREAD_FCR31(a0)
71 78 b 2f
72 79  
... ... @@ -161,6 +168,9 @@
161 168  
162 169 #define FPU_DEFAULT 0x00000000
163 170  
  171 + .set push
  172 + SET_HARDFLOAT
  173 +
164 174 LEAF(_init_fpu)
165 175 mfc0 t0, CP0_STATUS
166 176 li t1, ST0_CU1
... ... @@ -232,7 +242,8 @@
232 242  
233 243 #ifdef CONFIG_CPU_MIPS32_R2
234 244 .set push
235   - .set mips64r2
  245 + .set mips32r2
  246 + .set fp=64
236 247 sll t0, t0, 5 # is Status.FR set?
237 248 bgez t0, 1f # no: skip setting upper 32b
238 249  
... ... @@ -291,4 +302,6 @@
291 302 #endif
292 303 jr ra
293 304 END(_init_fpu)
  305 +
  306 + .set pop /* SET_HARDFLOAT */
arch/mips/kernel/r6000_fpu.S
... ... @@ -18,6 +18,9 @@
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
... ... @@ -85,4 +88,6 @@
85 88 1: jr ra
86 89 nop
87 90 END(_restore_fp_context)
  91 +
  92 + .set pop /* SET_HARDFLOAT */
arch/mips/math-emu/cp1emu.c
... ... @@ -584,11 +584,7 @@
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();