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