mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 15:11:31 +00:00
Merge branch '4.1-fp' of git://git.linux-mips.org/pub/scm/ralf/upstream-sfr into kvm_mips_queue
MIPS FP/MSA fixes from the MIPS tree. Includes a fix to ensure that the FPU is properly disabled by lose_fpu() when MSA is in use, and Paul Burton's "FP/MSA fixes" patchset which is required for FP/MSA support in KVM: > This series fixes a bunch of bugs, both build & runtime, with FP & MSA > support. Most of them only affect systems with the new FP modes & MSA > support enabled but patch 6 in particular is more general, fixing > problems for mips64 systems.
This commit is contained in:
commit
8e6c949103
@ -16,38 +16,38 @@
|
||||
.set push
|
||||
SET_HARDFLOAT
|
||||
cfc1 \tmp, fcr31
|
||||
swc1 $f0, THREAD_FPR0_LS64(\thread)
|
||||
swc1 $f1, THREAD_FPR1_LS64(\thread)
|
||||
swc1 $f2, THREAD_FPR2_LS64(\thread)
|
||||
swc1 $f3, THREAD_FPR3_LS64(\thread)
|
||||
swc1 $f4, THREAD_FPR4_LS64(\thread)
|
||||
swc1 $f5, THREAD_FPR5_LS64(\thread)
|
||||
swc1 $f6, THREAD_FPR6_LS64(\thread)
|
||||
swc1 $f7, THREAD_FPR7_LS64(\thread)
|
||||
swc1 $f8, THREAD_FPR8_LS64(\thread)
|
||||
swc1 $f9, THREAD_FPR9_LS64(\thread)
|
||||
swc1 $f10, THREAD_FPR10_LS64(\thread)
|
||||
swc1 $f11, THREAD_FPR11_LS64(\thread)
|
||||
swc1 $f12, THREAD_FPR12_LS64(\thread)
|
||||
swc1 $f13, THREAD_FPR13_LS64(\thread)
|
||||
swc1 $f14, THREAD_FPR14_LS64(\thread)
|
||||
swc1 $f15, THREAD_FPR15_LS64(\thread)
|
||||
swc1 $f16, THREAD_FPR16_LS64(\thread)
|
||||
swc1 $f17, THREAD_FPR17_LS64(\thread)
|
||||
swc1 $f18, THREAD_FPR18_LS64(\thread)
|
||||
swc1 $f19, THREAD_FPR19_LS64(\thread)
|
||||
swc1 $f20, THREAD_FPR20_LS64(\thread)
|
||||
swc1 $f21, THREAD_FPR21_LS64(\thread)
|
||||
swc1 $f22, THREAD_FPR22_LS64(\thread)
|
||||
swc1 $f23, THREAD_FPR23_LS64(\thread)
|
||||
swc1 $f24, THREAD_FPR24_LS64(\thread)
|
||||
swc1 $f25, THREAD_FPR25_LS64(\thread)
|
||||
swc1 $f26, THREAD_FPR26_LS64(\thread)
|
||||
swc1 $f27, THREAD_FPR27_LS64(\thread)
|
||||
swc1 $f28, THREAD_FPR28_LS64(\thread)
|
||||
swc1 $f29, THREAD_FPR29_LS64(\thread)
|
||||
swc1 $f30, THREAD_FPR30_LS64(\thread)
|
||||
swc1 $f31, THREAD_FPR31_LS64(\thread)
|
||||
swc1 $f0, THREAD_FPR0(\thread)
|
||||
swc1 $f1, THREAD_FPR1(\thread)
|
||||
swc1 $f2, THREAD_FPR2(\thread)
|
||||
swc1 $f3, THREAD_FPR3(\thread)
|
||||
swc1 $f4, THREAD_FPR4(\thread)
|
||||
swc1 $f5, THREAD_FPR5(\thread)
|
||||
swc1 $f6, THREAD_FPR6(\thread)
|
||||
swc1 $f7, THREAD_FPR7(\thread)
|
||||
swc1 $f8, THREAD_FPR8(\thread)
|
||||
swc1 $f9, THREAD_FPR9(\thread)
|
||||
swc1 $f10, THREAD_FPR10(\thread)
|
||||
swc1 $f11, THREAD_FPR11(\thread)
|
||||
swc1 $f12, THREAD_FPR12(\thread)
|
||||
swc1 $f13, THREAD_FPR13(\thread)
|
||||
swc1 $f14, THREAD_FPR14(\thread)
|
||||
swc1 $f15, THREAD_FPR15(\thread)
|
||||
swc1 $f16, THREAD_FPR16(\thread)
|
||||
swc1 $f17, THREAD_FPR17(\thread)
|
||||
swc1 $f18, THREAD_FPR18(\thread)
|
||||
swc1 $f19, THREAD_FPR19(\thread)
|
||||
swc1 $f20, THREAD_FPR20(\thread)
|
||||
swc1 $f21, THREAD_FPR21(\thread)
|
||||
swc1 $f22, THREAD_FPR22(\thread)
|
||||
swc1 $f23, THREAD_FPR23(\thread)
|
||||
swc1 $f24, THREAD_FPR24(\thread)
|
||||
swc1 $f25, THREAD_FPR25(\thread)
|
||||
swc1 $f26, THREAD_FPR26(\thread)
|
||||
swc1 $f27, THREAD_FPR27(\thread)
|
||||
swc1 $f28, THREAD_FPR28(\thread)
|
||||
swc1 $f29, THREAD_FPR29(\thread)
|
||||
swc1 $f30, THREAD_FPR30(\thread)
|
||||
swc1 $f31, THREAD_FPR31(\thread)
|
||||
sw \tmp, THREAD_FCR31(\thread)
|
||||
.set pop
|
||||
.endm
|
||||
@ -56,38 +56,38 @@
|
||||
.set push
|
||||
SET_HARDFLOAT
|
||||
lw \tmp, THREAD_FCR31(\thread)
|
||||
lwc1 $f0, THREAD_FPR0_LS64(\thread)
|
||||
lwc1 $f1, THREAD_FPR1_LS64(\thread)
|
||||
lwc1 $f2, THREAD_FPR2_LS64(\thread)
|
||||
lwc1 $f3, THREAD_FPR3_LS64(\thread)
|
||||
lwc1 $f4, THREAD_FPR4_LS64(\thread)
|
||||
lwc1 $f5, THREAD_FPR5_LS64(\thread)
|
||||
lwc1 $f6, THREAD_FPR6_LS64(\thread)
|
||||
lwc1 $f7, THREAD_FPR7_LS64(\thread)
|
||||
lwc1 $f8, THREAD_FPR8_LS64(\thread)
|
||||
lwc1 $f9, THREAD_FPR9_LS64(\thread)
|
||||
lwc1 $f10, THREAD_FPR10_LS64(\thread)
|
||||
lwc1 $f11, THREAD_FPR11_LS64(\thread)
|
||||
lwc1 $f12, THREAD_FPR12_LS64(\thread)
|
||||
lwc1 $f13, THREAD_FPR13_LS64(\thread)
|
||||
lwc1 $f14, THREAD_FPR14_LS64(\thread)
|
||||
lwc1 $f15, THREAD_FPR15_LS64(\thread)
|
||||
lwc1 $f16, THREAD_FPR16_LS64(\thread)
|
||||
lwc1 $f17, THREAD_FPR17_LS64(\thread)
|
||||
lwc1 $f18, THREAD_FPR18_LS64(\thread)
|
||||
lwc1 $f19, THREAD_FPR19_LS64(\thread)
|
||||
lwc1 $f20, THREAD_FPR20_LS64(\thread)
|
||||
lwc1 $f21, THREAD_FPR21_LS64(\thread)
|
||||
lwc1 $f22, THREAD_FPR22_LS64(\thread)
|
||||
lwc1 $f23, THREAD_FPR23_LS64(\thread)
|
||||
lwc1 $f24, THREAD_FPR24_LS64(\thread)
|
||||
lwc1 $f25, THREAD_FPR25_LS64(\thread)
|
||||
lwc1 $f26, THREAD_FPR26_LS64(\thread)
|
||||
lwc1 $f27, THREAD_FPR27_LS64(\thread)
|
||||
lwc1 $f28, THREAD_FPR28_LS64(\thread)
|
||||
lwc1 $f29, THREAD_FPR29_LS64(\thread)
|
||||
lwc1 $f30, THREAD_FPR30_LS64(\thread)
|
||||
lwc1 $f31, THREAD_FPR31_LS64(\thread)
|
||||
lwc1 $f0, THREAD_FPR0(\thread)
|
||||
lwc1 $f1, THREAD_FPR1(\thread)
|
||||
lwc1 $f2, THREAD_FPR2(\thread)
|
||||
lwc1 $f3, THREAD_FPR3(\thread)
|
||||
lwc1 $f4, THREAD_FPR4(\thread)
|
||||
lwc1 $f5, THREAD_FPR5(\thread)
|
||||
lwc1 $f6, THREAD_FPR6(\thread)
|
||||
lwc1 $f7, THREAD_FPR7(\thread)
|
||||
lwc1 $f8, THREAD_FPR8(\thread)
|
||||
lwc1 $f9, THREAD_FPR9(\thread)
|
||||
lwc1 $f10, THREAD_FPR10(\thread)
|
||||
lwc1 $f11, THREAD_FPR11(\thread)
|
||||
lwc1 $f12, THREAD_FPR12(\thread)
|
||||
lwc1 $f13, THREAD_FPR13(\thread)
|
||||
lwc1 $f14, THREAD_FPR14(\thread)
|
||||
lwc1 $f15, THREAD_FPR15(\thread)
|
||||
lwc1 $f16, THREAD_FPR16(\thread)
|
||||
lwc1 $f17, THREAD_FPR17(\thread)
|
||||
lwc1 $f18, THREAD_FPR18(\thread)
|
||||
lwc1 $f19, THREAD_FPR19(\thread)
|
||||
lwc1 $f20, THREAD_FPR20(\thread)
|
||||
lwc1 $f21, THREAD_FPR21(\thread)
|
||||
lwc1 $f22, THREAD_FPR22(\thread)
|
||||
lwc1 $f23, THREAD_FPR23(\thread)
|
||||
lwc1 $f24, THREAD_FPR24(\thread)
|
||||
lwc1 $f25, THREAD_FPR25(\thread)
|
||||
lwc1 $f26, THREAD_FPR26(\thread)
|
||||
lwc1 $f27, THREAD_FPR27(\thread)
|
||||
lwc1 $f28, THREAD_FPR28(\thread)
|
||||
lwc1 $f29, THREAD_FPR29(\thread)
|
||||
lwc1 $f30, THREAD_FPR30(\thread)
|
||||
lwc1 $f31, THREAD_FPR31(\thread)
|
||||
ctc1 \tmp, fcr31
|
||||
.set pop
|
||||
.endm
|
||||
|
@ -60,22 +60,22 @@
|
||||
.set push
|
||||
SET_HARDFLOAT
|
||||
cfc1 \tmp, fcr31
|
||||
sdc1 $f0, THREAD_FPR0_LS64(\thread)
|
||||
sdc1 $f2, THREAD_FPR2_LS64(\thread)
|
||||
sdc1 $f4, THREAD_FPR4_LS64(\thread)
|
||||
sdc1 $f6, THREAD_FPR6_LS64(\thread)
|
||||
sdc1 $f8, THREAD_FPR8_LS64(\thread)
|
||||
sdc1 $f10, THREAD_FPR10_LS64(\thread)
|
||||
sdc1 $f12, THREAD_FPR12_LS64(\thread)
|
||||
sdc1 $f14, THREAD_FPR14_LS64(\thread)
|
||||
sdc1 $f16, THREAD_FPR16_LS64(\thread)
|
||||
sdc1 $f18, THREAD_FPR18_LS64(\thread)
|
||||
sdc1 $f20, THREAD_FPR20_LS64(\thread)
|
||||
sdc1 $f22, THREAD_FPR22_LS64(\thread)
|
||||
sdc1 $f24, THREAD_FPR24_LS64(\thread)
|
||||
sdc1 $f26, THREAD_FPR26_LS64(\thread)
|
||||
sdc1 $f28, THREAD_FPR28_LS64(\thread)
|
||||
sdc1 $f30, THREAD_FPR30_LS64(\thread)
|
||||
sdc1 $f0, THREAD_FPR0(\thread)
|
||||
sdc1 $f2, THREAD_FPR2(\thread)
|
||||
sdc1 $f4, THREAD_FPR4(\thread)
|
||||
sdc1 $f6, THREAD_FPR6(\thread)
|
||||
sdc1 $f8, THREAD_FPR8(\thread)
|
||||
sdc1 $f10, THREAD_FPR10(\thread)
|
||||
sdc1 $f12, THREAD_FPR12(\thread)
|
||||
sdc1 $f14, THREAD_FPR14(\thread)
|
||||
sdc1 $f16, THREAD_FPR16(\thread)
|
||||
sdc1 $f18, THREAD_FPR18(\thread)
|
||||
sdc1 $f20, THREAD_FPR20(\thread)
|
||||
sdc1 $f22, THREAD_FPR22(\thread)
|
||||
sdc1 $f24, THREAD_FPR24(\thread)
|
||||
sdc1 $f26, THREAD_FPR26(\thread)
|
||||
sdc1 $f28, THREAD_FPR28(\thread)
|
||||
sdc1 $f30, THREAD_FPR30(\thread)
|
||||
sw \tmp, THREAD_FCR31(\thread)
|
||||
.set pop
|
||||
.endm
|
||||
@ -84,22 +84,22 @@
|
||||
.set push
|
||||
.set mips64r2
|
||||
SET_HARDFLOAT
|
||||
sdc1 $f1, THREAD_FPR1_LS64(\thread)
|
||||
sdc1 $f3, THREAD_FPR3_LS64(\thread)
|
||||
sdc1 $f5, THREAD_FPR5_LS64(\thread)
|
||||
sdc1 $f7, THREAD_FPR7_LS64(\thread)
|
||||
sdc1 $f9, THREAD_FPR9_LS64(\thread)
|
||||
sdc1 $f11, THREAD_FPR11_LS64(\thread)
|
||||
sdc1 $f13, THREAD_FPR13_LS64(\thread)
|
||||
sdc1 $f15, THREAD_FPR15_LS64(\thread)
|
||||
sdc1 $f17, THREAD_FPR17_LS64(\thread)
|
||||
sdc1 $f19, THREAD_FPR19_LS64(\thread)
|
||||
sdc1 $f21, THREAD_FPR21_LS64(\thread)
|
||||
sdc1 $f23, THREAD_FPR23_LS64(\thread)
|
||||
sdc1 $f25, THREAD_FPR25_LS64(\thread)
|
||||
sdc1 $f27, THREAD_FPR27_LS64(\thread)
|
||||
sdc1 $f29, THREAD_FPR29_LS64(\thread)
|
||||
sdc1 $f31, THREAD_FPR31_LS64(\thread)
|
||||
sdc1 $f1, THREAD_FPR1(\thread)
|
||||
sdc1 $f3, THREAD_FPR3(\thread)
|
||||
sdc1 $f5, THREAD_FPR5(\thread)
|
||||
sdc1 $f7, THREAD_FPR7(\thread)
|
||||
sdc1 $f9, THREAD_FPR9(\thread)
|
||||
sdc1 $f11, THREAD_FPR11(\thread)
|
||||
sdc1 $f13, THREAD_FPR13(\thread)
|
||||
sdc1 $f15, THREAD_FPR15(\thread)
|
||||
sdc1 $f17, THREAD_FPR17(\thread)
|
||||
sdc1 $f19, THREAD_FPR19(\thread)
|
||||
sdc1 $f21, THREAD_FPR21(\thread)
|
||||
sdc1 $f23, THREAD_FPR23(\thread)
|
||||
sdc1 $f25, THREAD_FPR25(\thread)
|
||||
sdc1 $f27, THREAD_FPR27(\thread)
|
||||
sdc1 $f29, THREAD_FPR29(\thread)
|
||||
sdc1 $f31, THREAD_FPR31(\thread)
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
@ -118,22 +118,22 @@
|
||||
.set push
|
||||
SET_HARDFLOAT
|
||||
lw \tmp, THREAD_FCR31(\thread)
|
||||
ldc1 $f0, THREAD_FPR0_LS64(\thread)
|
||||
ldc1 $f2, THREAD_FPR2_LS64(\thread)
|
||||
ldc1 $f4, THREAD_FPR4_LS64(\thread)
|
||||
ldc1 $f6, THREAD_FPR6_LS64(\thread)
|
||||
ldc1 $f8, THREAD_FPR8_LS64(\thread)
|
||||
ldc1 $f10, THREAD_FPR10_LS64(\thread)
|
||||
ldc1 $f12, THREAD_FPR12_LS64(\thread)
|
||||
ldc1 $f14, THREAD_FPR14_LS64(\thread)
|
||||
ldc1 $f16, THREAD_FPR16_LS64(\thread)
|
||||
ldc1 $f18, THREAD_FPR18_LS64(\thread)
|
||||
ldc1 $f20, THREAD_FPR20_LS64(\thread)
|
||||
ldc1 $f22, THREAD_FPR22_LS64(\thread)
|
||||
ldc1 $f24, THREAD_FPR24_LS64(\thread)
|
||||
ldc1 $f26, THREAD_FPR26_LS64(\thread)
|
||||
ldc1 $f28, THREAD_FPR28_LS64(\thread)
|
||||
ldc1 $f30, THREAD_FPR30_LS64(\thread)
|
||||
ldc1 $f0, THREAD_FPR0(\thread)
|
||||
ldc1 $f2, THREAD_FPR2(\thread)
|
||||
ldc1 $f4, THREAD_FPR4(\thread)
|
||||
ldc1 $f6, THREAD_FPR6(\thread)
|
||||
ldc1 $f8, THREAD_FPR8(\thread)
|
||||
ldc1 $f10, THREAD_FPR10(\thread)
|
||||
ldc1 $f12, THREAD_FPR12(\thread)
|
||||
ldc1 $f14, THREAD_FPR14(\thread)
|
||||
ldc1 $f16, THREAD_FPR16(\thread)
|
||||
ldc1 $f18, THREAD_FPR18(\thread)
|
||||
ldc1 $f20, THREAD_FPR20(\thread)
|
||||
ldc1 $f22, THREAD_FPR22(\thread)
|
||||
ldc1 $f24, THREAD_FPR24(\thread)
|
||||
ldc1 $f26, THREAD_FPR26(\thread)
|
||||
ldc1 $f28, THREAD_FPR28(\thread)
|
||||
ldc1 $f30, THREAD_FPR30(\thread)
|
||||
ctc1 \tmp, fcr31
|
||||
.endm
|
||||
|
||||
@ -141,22 +141,22 @@
|
||||
.set push
|
||||
.set mips64r2
|
||||
SET_HARDFLOAT
|
||||
ldc1 $f1, THREAD_FPR1_LS64(\thread)
|
||||
ldc1 $f3, THREAD_FPR3_LS64(\thread)
|
||||
ldc1 $f5, THREAD_FPR5_LS64(\thread)
|
||||
ldc1 $f7, THREAD_FPR7_LS64(\thread)
|
||||
ldc1 $f9, THREAD_FPR9_LS64(\thread)
|
||||
ldc1 $f11, THREAD_FPR11_LS64(\thread)
|
||||
ldc1 $f13, THREAD_FPR13_LS64(\thread)
|
||||
ldc1 $f15, THREAD_FPR15_LS64(\thread)
|
||||
ldc1 $f17, THREAD_FPR17_LS64(\thread)
|
||||
ldc1 $f19, THREAD_FPR19_LS64(\thread)
|
||||
ldc1 $f21, THREAD_FPR21_LS64(\thread)
|
||||
ldc1 $f23, THREAD_FPR23_LS64(\thread)
|
||||
ldc1 $f25, THREAD_FPR25_LS64(\thread)
|
||||
ldc1 $f27, THREAD_FPR27_LS64(\thread)
|
||||
ldc1 $f29, THREAD_FPR29_LS64(\thread)
|
||||
ldc1 $f31, THREAD_FPR31_LS64(\thread)
|
||||
ldc1 $f1, THREAD_FPR1(\thread)
|
||||
ldc1 $f3, THREAD_FPR3(\thread)
|
||||
ldc1 $f5, THREAD_FPR5(\thread)
|
||||
ldc1 $f7, THREAD_FPR7(\thread)
|
||||
ldc1 $f9, THREAD_FPR9(\thread)
|
||||
ldc1 $f11, THREAD_FPR11(\thread)
|
||||
ldc1 $f13, THREAD_FPR13(\thread)
|
||||
ldc1 $f15, THREAD_FPR15(\thread)
|
||||
ldc1 $f17, THREAD_FPR17(\thread)
|
||||
ldc1 $f19, THREAD_FPR19(\thread)
|
||||
ldc1 $f21, THREAD_FPR21(\thread)
|
||||
ldc1 $f23, THREAD_FPR23(\thread)
|
||||
ldc1 $f25, THREAD_FPR25(\thread)
|
||||
ldc1 $f27, THREAD_FPR27(\thread)
|
||||
ldc1 $f29, THREAD_FPR29(\thread)
|
||||
ldc1 $f31, THREAD_FPR31(\thread)
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
@ -211,6 +211,22 @@
|
||||
.endm
|
||||
|
||||
#ifdef TOOLCHAIN_SUPPORTS_MSA
|
||||
.macro _cfcmsa rd, cs
|
||||
.set push
|
||||
.set mips32r2
|
||||
.set msa
|
||||
cfcmsa \rd, $\cs
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.macro _ctcmsa cd, rs
|
||||
.set push
|
||||
.set mips32r2
|
||||
.set msa
|
||||
ctcmsa $\cd, \rs
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.macro ld_d wd, off, base
|
||||
.set push
|
||||
.set mips32r2
|
||||
@ -227,35 +243,35 @@
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.macro copy_u_w rd, ws, n
|
||||
.macro copy_u_w ws, n
|
||||
.set push
|
||||
.set mips32r2
|
||||
.set msa
|
||||
copy_u.w \rd, $w\ws[\n]
|
||||
copy_u.w $1, $w\ws[\n]
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.macro copy_u_d rd, ws, n
|
||||
.macro copy_u_d ws, n
|
||||
.set push
|
||||
.set mips64r2
|
||||
.set msa
|
||||
copy_u.d \rd, $w\ws[\n]
|
||||
copy_u.d $1, $w\ws[\n]
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.macro insert_w wd, n, rs
|
||||
.macro insert_w wd, n
|
||||
.set push
|
||||
.set mips32r2
|
||||
.set msa
|
||||
insert.w $w\wd[\n], \rs
|
||||
insert.w $w\wd[\n], $1
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.macro insert_d wd, n, rs
|
||||
.macro insert_d wd, n
|
||||
.set push
|
||||
.set mips64r2
|
||||
.set msa
|
||||
insert.d $w\wd[\n], \rs
|
||||
insert.d $w\wd[\n], $1
|
||||
.set pop
|
||||
.endm
|
||||
#else
|
||||
@ -283,7 +299,7 @@
|
||||
/*
|
||||
* Temporary until all toolchains in use include MSA support.
|
||||
*/
|
||||
.macro cfcmsa rd, cs
|
||||
.macro _cfcmsa rd, cs
|
||||
.set push
|
||||
.set noat
|
||||
SET_HARDFLOAT
|
||||
@ -293,7 +309,7 @@
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.macro ctcmsa cd, rs
|
||||
.macro _ctcmsa cd, rs
|
||||
.set push
|
||||
.set noat
|
||||
SET_HARDFLOAT
|
||||
@ -320,44 +336,36 @@
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.macro copy_u_w rd, ws, n
|
||||
.macro copy_u_w ws, n
|
||||
.set push
|
||||
.set noat
|
||||
SET_HARDFLOAT
|
||||
.insn
|
||||
.word COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
|
||||
/* move triggers an assembler bug... */
|
||||
or \rd, $1, zero
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.macro copy_u_d rd, ws, n
|
||||
.macro copy_u_d ws, n
|
||||
.set push
|
||||
.set noat
|
||||
SET_HARDFLOAT
|
||||
.insn
|
||||
.word COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
|
||||
/* move triggers an assembler bug... */
|
||||
or \rd, $1, zero
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.macro insert_w wd, n, rs
|
||||
.macro insert_w wd, n
|
||||
.set push
|
||||
.set noat
|
||||
SET_HARDFLOAT
|
||||
/* move triggers an assembler bug... */
|
||||
or $1, \rs, zero
|
||||
.word INSERT_W_MSA_INSN | (\n << 16) | (\wd << 6)
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
.macro insert_d wd, n, rs
|
||||
.macro insert_d wd, n
|
||||
.set push
|
||||
.set noat
|
||||
SET_HARDFLOAT
|
||||
/* move triggers an assembler bug... */
|
||||
or $1, \rs, zero
|
||||
.word INSERT_D_MSA_INSN | (\n << 16) | (\wd << 6)
|
||||
.set pop
|
||||
.endm
|
||||
@ -399,7 +407,7 @@
|
||||
.set push
|
||||
.set noat
|
||||
SET_HARDFLOAT
|
||||
cfcmsa $1, MSA_CSR
|
||||
_cfcmsa $1, MSA_CSR
|
||||
sw $1, THREAD_MSA_CSR(\thread)
|
||||
.set pop
|
||||
.endm
|
||||
@ -409,7 +417,7 @@
|
||||
.set noat
|
||||
SET_HARDFLOAT
|
||||
lw $1, THREAD_MSA_CSR(\thread)
|
||||
ctcmsa MSA_CSR, $1
|
||||
_ctcmsa MSA_CSR, $1
|
||||
.set pop
|
||||
ld_d 0, THREAD_FPR0, \thread
|
||||
ld_d 1, THREAD_FPR1, \thread
|
||||
@ -452,9 +460,6 @@
|
||||
insert_w \wd, 2
|
||||
insert_w \wd, 3
|
||||
#endif
|
||||
.if 31-\wd
|
||||
msa_init_upper (\wd+1)
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro msa_init_all_upper
|
||||
@ -463,6 +468,37 @@
|
||||
SET_HARDFLOAT
|
||||
not $1, zero
|
||||
msa_init_upper 0
|
||||
msa_init_upper 1
|
||||
msa_init_upper 2
|
||||
msa_init_upper 3
|
||||
msa_init_upper 4
|
||||
msa_init_upper 5
|
||||
msa_init_upper 6
|
||||
msa_init_upper 7
|
||||
msa_init_upper 8
|
||||
msa_init_upper 9
|
||||
msa_init_upper 10
|
||||
msa_init_upper 11
|
||||
msa_init_upper 12
|
||||
msa_init_upper 13
|
||||
msa_init_upper 14
|
||||
msa_init_upper 15
|
||||
msa_init_upper 16
|
||||
msa_init_upper 17
|
||||
msa_init_upper 18
|
||||
msa_init_upper 19
|
||||
msa_init_upper 20
|
||||
msa_init_upper 21
|
||||
msa_init_upper 22
|
||||
msa_init_upper 23
|
||||
msa_init_upper 24
|
||||
msa_init_upper 25
|
||||
msa_init_upper 26
|
||||
msa_init_upper 27
|
||||
msa_init_upper 28
|
||||
msa_init_upper 29
|
||||
msa_init_upper 30
|
||||
msa_init_upper 31
|
||||
.set pop
|
||||
.endm
|
||||
|
||||
|
@ -48,6 +48,12 @@ enum fpu_mode {
|
||||
#define FPU_FR_MASK 0x1
|
||||
};
|
||||
|
||||
#define __disable_fpu() \
|
||||
do { \
|
||||
clear_c0_status(ST0_CU1); \
|
||||
disable_fpu_hazard(); \
|
||||
} while (0)
|
||||
|
||||
static inline int __enable_fpu(enum fpu_mode mode)
|
||||
{
|
||||
int fr;
|
||||
@ -86,7 +92,12 @@ fr_common:
|
||||
enable_fpu_hazard();
|
||||
|
||||
/* check FR has the desired value */
|
||||
return (!!(read_c0_status() & ST0_FR) == !!fr) ? 0 : SIGFPE;
|
||||
if (!!(read_c0_status() & ST0_FR) == !!fr)
|
||||
return 0;
|
||||
|
||||
/* unsupported FR value */
|
||||
__disable_fpu();
|
||||
return SIGFPE;
|
||||
|
||||
default:
|
||||
BUG();
|
||||
@ -95,12 +106,6 @@ fr_common:
|
||||
return SIGFPE;
|
||||
}
|
||||
|
||||
#define __disable_fpu() \
|
||||
do { \
|
||||
clear_c0_status(ST0_CU1); \
|
||||
disable_fpu_hazard(); \
|
||||
} while (0)
|
||||
|
||||
#define clear_fpu_owner() clear_thread_flag(TIF_USEDFPU)
|
||||
|
||||
static inline int __is_fpu_owner(void)
|
||||
@ -170,6 +175,7 @@ static inline void lose_fpu(int save)
|
||||
}
|
||||
disable_msa();
|
||||
clear_thread_flag(TIF_USEDMSA);
|
||||
__disable_fpu();
|
||||
} else if (is_fpu_owner()) {
|
||||
if (save)
|
||||
_save_fp(current);
|
||||
|
@ -105,7 +105,7 @@ union fpureg {
|
||||
#ifdef CONFIG_CPU_LITTLE_ENDIAN
|
||||
# define FPR_IDX(width, idx) (idx)
|
||||
#else
|
||||
# define FPR_IDX(width, idx) ((FPU_REG_WIDTH / (width)) - 1 - (idx))
|
||||
# define FPR_IDX(width, idx) ((idx) ^ ((64 / (width)) - 1))
|
||||
#endif
|
||||
|
||||
#define BUILD_FPR_ACCESS(width) \
|
||||
|
@ -167,72 +167,6 @@ void output_thread_fpu_defines(void)
|
||||
OFFSET(THREAD_FPR30, task_struct, thread.fpu.fpr[30]);
|
||||
OFFSET(THREAD_FPR31, task_struct, thread.fpu.fpr[31]);
|
||||
|
||||
/* the least significant 64 bits of each FP register */
|
||||
OFFSET(THREAD_FPR0_LS64, task_struct,
|
||||
thread.fpu.fpr[0].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR1_LS64, task_struct,
|
||||
thread.fpu.fpr[1].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR2_LS64, task_struct,
|
||||
thread.fpu.fpr[2].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR3_LS64, task_struct,
|
||||
thread.fpu.fpr[3].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR4_LS64, task_struct,
|
||||
thread.fpu.fpr[4].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR5_LS64, task_struct,
|
||||
thread.fpu.fpr[5].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR6_LS64, task_struct,
|
||||
thread.fpu.fpr[6].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR7_LS64, task_struct,
|
||||
thread.fpu.fpr[7].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR8_LS64, task_struct,
|
||||
thread.fpu.fpr[8].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR9_LS64, task_struct,
|
||||
thread.fpu.fpr[9].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR10_LS64, task_struct,
|
||||
thread.fpu.fpr[10].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR11_LS64, task_struct,
|
||||
thread.fpu.fpr[11].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR12_LS64, task_struct,
|
||||
thread.fpu.fpr[12].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR13_LS64, task_struct,
|
||||
thread.fpu.fpr[13].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR14_LS64, task_struct,
|
||||
thread.fpu.fpr[14].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR15_LS64, task_struct,
|
||||
thread.fpu.fpr[15].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR16_LS64, task_struct,
|
||||
thread.fpu.fpr[16].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR17_LS64, task_struct,
|
||||
thread.fpu.fpr[17].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR18_LS64, task_struct,
|
||||
thread.fpu.fpr[18].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR19_LS64, task_struct,
|
||||
thread.fpu.fpr[19].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR20_LS64, task_struct,
|
||||
thread.fpu.fpr[20].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR21_LS64, task_struct,
|
||||
thread.fpu.fpr[21].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR22_LS64, task_struct,
|
||||
thread.fpu.fpr[22].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR23_LS64, task_struct,
|
||||
thread.fpu.fpr[23].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR24_LS64, task_struct,
|
||||
thread.fpu.fpr[24].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR25_LS64, task_struct,
|
||||
thread.fpu.fpr[25].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR26_LS64, task_struct,
|
||||
thread.fpu.fpr[26].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR27_LS64, task_struct,
|
||||
thread.fpu.fpr[27].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR28_LS64, task_struct,
|
||||
thread.fpu.fpr[28].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR29_LS64, task_struct,
|
||||
thread.fpu.fpr[29].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR30_LS64, task_struct,
|
||||
thread.fpu.fpr[30].val64[FPR_IDX(64, 0)]);
|
||||
OFFSET(THREAD_FPR31_LS64, task_struct,
|
||||
thread.fpu.fpr[31].val64[FPR_IDX(64, 0)]);
|
||||
|
||||
OFFSET(THREAD_FCR31, task_struct, thread.fpu.fcr31);
|
||||
OFFSET(THREAD_MSA_CSR, task_struct, thread.fpu.msacsr);
|
||||
BLANK();
|
||||
|
@ -368,6 +368,15 @@ NESTED(nmi_handler, PT_SIZE, sp)
|
||||
STI
|
||||
.endm
|
||||
|
||||
.macro __build_clear_msa_fpe
|
||||
_cfcmsa a1, MSA_CSR
|
||||
li a2, ~(0x3f << 12)
|
||||
and a1, a1, a2
|
||||
_ctcmsa MSA_CSR, a1
|
||||
TRACE_IRQS_ON
|
||||
STI
|
||||
.endm
|
||||
|
||||
.macro __build_clear_ade
|
||||
MFC0 t0, CP0_BADVADDR
|
||||
PTR_S t0, PT_BVADDR(sp)
|
||||
@ -426,7 +435,7 @@ NESTED(nmi_handler, PT_SIZE, sp)
|
||||
BUILD_HANDLER cpu cpu sti silent /* #11 */
|
||||
BUILD_HANDLER ov ov sti silent /* #12 */
|
||||
BUILD_HANDLER tr tr sti silent /* #13 */
|
||||
BUILD_HANDLER msa_fpe msa_fpe sti silent /* #14 */
|
||||
BUILD_HANDLER msa_fpe msa_fpe msa_fpe silent /* #14 */
|
||||
BUILD_HANDLER fpe fpe fpe silent /* #15 */
|
||||
BUILD_HANDLER ftlb ftlb none silent /* #16 */
|
||||
BUILD_HANDLER msa msa sti silent /* #21 */
|
||||
|
@ -46,6 +46,26 @@
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/syscalls.h>
|
||||
|
||||
static void init_fp_ctx(struct task_struct *target)
|
||||
{
|
||||
/* If FP has been used then the target already has context */
|
||||
if (tsk_used_math(target))
|
||||
return;
|
||||
|
||||
/* Begin with data registers set to all 1s... */
|
||||
memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr));
|
||||
|
||||
/* ...and FCSR zeroed */
|
||||
target->thread.fpu.fcr31 = 0;
|
||||
|
||||
/*
|
||||
* Record that the target has "used" math, such that the context
|
||||
* just initialised, and any modifications made by the caller,
|
||||
* aren't discarded.
|
||||
*/
|
||||
set_stopped_child_used_math(target);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by kernel/ptrace.c when detaching..
|
||||
*
|
||||
@ -142,6 +162,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
|
||||
if (!access_ok(VERIFY_READ, data, 33 * 8))
|
||||
return -EIO;
|
||||
|
||||
init_fp_ctx(child);
|
||||
fregs = get_fpu_regs(child);
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
@ -439,6 +460,8 @@ static int fpr_set(struct task_struct *target,
|
||||
|
||||
/* XXX fcr31 */
|
||||
|
||||
init_fp_ctx(target);
|
||||
|
||||
if (sizeof(target->thread.fpu.fpr[i]) == sizeof(elf_fpreg_t))
|
||||
return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
|
||||
&target->thread.fpu,
|
||||
@ -660,12 +683,7 @@ long arch_ptrace(struct task_struct *child, long request,
|
||||
case FPR_BASE ... FPR_BASE + 31: {
|
||||
union fpureg *fregs = get_fpu_regs(child);
|
||||
|
||||
if (!tsk_used_math(child)) {
|
||||
/* FP not yet used */
|
||||
memset(&child->thread.fpu, ~0,
|
||||
sizeof(child->thread.fpu));
|
||||
child->thread.fpu.fcr31 = 0;
|
||||
}
|
||||
init_fp_ctx(child);
|
||||
#ifdef CONFIG_32BIT
|
||||
if (test_thread_flag(TIF_32BIT_FPREGS)) {
|
||||
/*
|
||||
|
@ -34,7 +34,6 @@
|
||||
.endm
|
||||
|
||||
.set noreorder
|
||||
.set MIPS_ISA_ARCH_LEVEL_RAW
|
||||
|
||||
LEAF(_save_fp_context)
|
||||
.set push
|
||||
@ -103,6 +102,7 @@ LEAF(_save_fp_context)
|
||||
/* Save 32-bit process floating point context */
|
||||
LEAF(_save_fp_context32)
|
||||
.set push
|
||||
.set MIPS_ISA_ARCH_LEVEL_RAW
|
||||
SET_HARDFLOAT
|
||||
cfc1 t1, fcr31
|
||||
|
||||
|
@ -701,6 +701,13 @@ asmlinkage void do_ov(struct pt_regs *regs)
|
||||
|
||||
int process_fpemu_return(int sig, void __user *fault_addr)
|
||||
{
|
||||
/*
|
||||
* We can't allow the emulated instruction to leave any of the cause
|
||||
* bits set in FCSR. If they were then the kernel would take an FP
|
||||
* exception when restoring FP context.
|
||||
*/
|
||||
current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
|
||||
|
||||
if (sig == SIGSEGV || sig == SIGBUS) {
|
||||
struct siginfo si = {0};
|
||||
si.si_addr = fault_addr;
|
||||
@ -804,18 +811,12 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
|
||||
sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1,
|
||||
&fault_addr);
|
||||
|
||||
/*
|
||||
* We can't allow the emulated instruction to leave any of
|
||||
* the cause bit set in $fcr31.
|
||||
*/
|
||||
current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X;
|
||||
/* If something went wrong, signal */
|
||||
process_fpemu_return(sig, fault_addr);
|
||||
|
||||
/* Restore the hardware register state */
|
||||
own_fpu(1); /* Using the FPU again. */
|
||||
|
||||
/* If something went wrong, signal */
|
||||
process_fpemu_return(sig, fault_addr);
|
||||
|
||||
goto out;
|
||||
} else if (fcr31 & FPU_CSR_INV_X)
|
||||
info.si_code = FPE_FLTINV;
|
||||
|
Loading…
Reference in New Issue
Block a user