Commit c138e12f authored by Atsushi Nemoto's avatar Atsushi Nemoto Committed by Ralf Baechle

[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: default avatarAtsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 73499682
...@@ -75,8 +75,8 @@ ...@@ -75,8 +75,8 @@
and t0, t0, t1 and t0, t0, t1
LONG_S t0, ST_OFF(t3) LONG_S t0, ST_OFF(t3)
fpu_save_double a0 t1 t0 t2 # c0_status passed in t1 fpu_save_double a0 t0 t1 # c0_status passed in t0
# clobbers t0 and t2 # clobbers t1
1: 1:
/* /*
...@@ -129,9 +129,9 @@ ...@@ -129,9 +129,9 @@
*/ */
LEAF(_save_fp) LEAF(_save_fp)
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
mfc0 t1, CP0_STATUS mfc0 t0, CP0_STATUS
#endif #endif
fpu_save_double a0 t1 t0 t2 # clobbers t1 fpu_save_double a0 t0 t1 # clobbers t1
jr ra jr ra
END(_save_fp) END(_save_fp)
...@@ -139,7 +139,10 @@ LEAF(_save_fp) ...@@ -139,7 +139,10 @@ LEAF(_save_fp)
* Restore a thread's fp context. * Restore a thread's fp context.
*/ */
LEAF(_restore_fp) 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 jr ra
END(_restore_fp) END(_restore_fp)
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
#include <asm/fpregdef.h> #include <asm/fpregdef.h>
#include <asm/mipsregs.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 cfc1 \tmp1, fcr31
sdc1 $f0, THREAD_FPR0(\thread) sdc1 $f0, THREAD_FPR0(\thread)
sdc1 $f2, THREAD_FPR2(\thread) sdc1 $f2, THREAD_FPR2(\thread)
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
sw \tmp, THREAD_FCR31(\thread) sw \tmp, THREAD_FCR31(\thread)
.endm .endm
.macro fpu_restore_double thread tmp=t0 .macro fpu_restore_double thread status tmp=t0
lw \tmp, THREAD_FCR31(\thread) lw \tmp, THREAD_FCR31(\thread)
ldc1 $f0, THREAD_FPR0(\thread) ldc1 $f0, THREAD_FPR0(\thread)
ldc1 $f2, THREAD_FPR2(\thread) ldc1 $f2, THREAD_FPR2(\thread)
......
...@@ -53,12 +53,12 @@ ...@@ -53,12 +53,12 @@
sdc1 $f31, THREAD_FPR31(\thread) sdc1 $f31, THREAD_FPR31(\thread)
.endm .endm
.macro fpu_save_double thread status tmp1 tmp2 .macro fpu_save_double thread status tmp
sll \tmp2, \tmp1, 5 sll \tmp, \status, 5
bgez \tmp2, 2f bgez \tmp, 2f
fpu_save_16odd \thread fpu_save_16odd \thread
2: 2:
fpu_save_16even \thread \tmp1 # clobbers t1 fpu_save_16even \thread \tmp
.endm .endm
.macro fpu_restore_16even thread tmp=t0 .macro fpu_restore_16even thread tmp=t0
...@@ -101,13 +101,12 @@ ...@@ -101,13 +101,12 @@
ldc1 $f31, THREAD_FPR31(\thread) ldc1 $f31, THREAD_FPR31(\thread)
.endm .endm
.macro fpu_restore_double thread tmp .macro fpu_restore_double thread status tmp
mfc0 t0, CP0_STATUS sll \tmp, \status, 5
sll t1, t0, 5 bgez \tmp, 1f # 16 register mode?
bgez t1, 1f # 16 register mode?
fpu_restore_16odd a0 fpu_restore_16odd \thread
1: fpu_restore_16even a0, t0 # clobbers t0 1: fpu_restore_16even \thread \tmp
.endm .endm
.macro cpu_save_nonscratch thread .macro cpu_save_nonscratch thread
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment