[MIPS] Fix fpu_save_double on 64-bit.
> Without this fix, _save_fp() in 64-bit kernel is seriously broken. > > ffffffff8010bec0 <_save_fp>: > ffffffff8010bec0: 400d6000 mfc0 t1,c0_status > ffffffff8010bec4: 000c7140 sll t2,t0,0x5 > ffffffff8010bec8: 05c10011 bgez t2,ffffffff8010bf10 <_save_fp+0x50> > ffffffff8010becc: 00000000 nop > ffffffff8010bed0: f4810328 sdc1 $f1,808(a0) > ... Fix register usage in fpu_save_double() and make fpu_restore_double() more symmetric with fpu_save_double(). Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
734996820f
commit
c138e12f3a
3 changed files with 19 additions and 17 deletions
|
@ -75,8 +75,8 @@
|
|||
and t0, t0, t1
|
||||
LONG_S t0, ST_OFF(t3)
|
||||
|
||||
fpu_save_double a0 t1 t0 t2 # c0_status passed in t1
|
||||
# clobbers t0 and t2
|
||||
fpu_save_double a0 t0 t1 # c0_status passed in t0
|
||||
# clobbers t1
|
||||
1:
|
||||
|
||||
/*
|
||||
|
@ -129,9 +129,9 @@
|
|||
*/
|
||||
LEAF(_save_fp)
|
||||
#ifdef CONFIG_64BIT
|
||||
mfc0 t1, CP0_STATUS
|
||||
mfc0 t0, CP0_STATUS
|
||||
#endif
|
||||
fpu_save_double a0 t1 t0 t2 # clobbers t1
|
||||
fpu_save_double a0 t0 t1 # clobbers t1
|
||||
jr ra
|
||||
END(_save_fp)
|
||||
|
||||
|
@ -139,7 +139,10 @@ LEAF(_save_fp)
|
|||
* Restore a thread's fp context.
|
||||
*/
|
||||
LEAF(_restore_fp)
|
||||
fpu_restore_double a0, t1 # clobbers t1
|
||||
#ifdef CONFIG_64BIT
|
||||
mfc0 t0, CP0_STATUS
|
||||
#endif
|
||||
fpu_restore_double a0 t0 t1 # clobbers t1
|
||||
jr ra
|
||||
END(_restore_fp)
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <asm/fpregdef.h>
|
||||
#include <asm/mipsregs.h>
|
||||
|
||||
.macro fpu_save_double thread status tmp1=t0 tmp2
|
||||
.macro fpu_save_double thread status tmp1=t0
|
||||
cfc1 \tmp1, fcr31
|
||||
sdc1 $f0, THREAD_FPR0(\thread)
|
||||
sdc1 $f2, THREAD_FPR2(\thread)
|
||||
|
@ -70,7 +70,7 @@
|
|||
sw \tmp, THREAD_FCR31(\thread)
|
||||
.endm
|
||||
|
||||
.macro fpu_restore_double thread tmp=t0
|
||||
.macro fpu_restore_double thread status tmp=t0
|
||||
lw \tmp, THREAD_FCR31(\thread)
|
||||
ldc1 $f0, THREAD_FPR0(\thread)
|
||||
ldc1 $f2, THREAD_FPR2(\thread)
|
||||
|
|
|
@ -53,12 +53,12 @@
|
|||
sdc1 $f31, THREAD_FPR31(\thread)
|
||||
.endm
|
||||
|
||||
.macro fpu_save_double thread status tmp1 tmp2
|
||||
sll \tmp2, \tmp1, 5
|
||||
bgez \tmp2, 2f
|
||||
.macro fpu_save_double thread status tmp
|
||||
sll \tmp, \status, 5
|
||||
bgez \tmp, 2f
|
||||
fpu_save_16odd \thread
|
||||
2:
|
||||
fpu_save_16even \thread \tmp1 # clobbers t1
|
||||
fpu_save_16even \thread \tmp
|
||||
.endm
|
||||
|
||||
.macro fpu_restore_16even thread tmp=t0
|
||||
|
@ -101,13 +101,12 @@
|
|||
ldc1 $f31, THREAD_FPR31(\thread)
|
||||
.endm
|
||||
|
||||
.macro fpu_restore_double thread tmp
|
||||
mfc0 t0, CP0_STATUS
|
||||
sll t1, t0, 5
|
||||
bgez t1, 1f # 16 register mode?
|
||||
.macro fpu_restore_double thread status tmp
|
||||
sll \tmp, \status, 5
|
||||
bgez \tmp, 1f # 16 register mode?
|
||||
|
||||
fpu_restore_16odd a0
|
||||
1: fpu_restore_16even a0, t0 # clobbers t0
|
||||
fpu_restore_16odd \thread
|
||||
1: fpu_restore_16even \thread \tmp
|
||||
.endm
|
||||
|
||||
.macro cpu_save_nonscratch thread
|
||||
|
|
Loading…
Reference in a new issue