diff options
Diffstat (limited to 'arch/sh/kernel/cpu/sh5/fpu.c')
-rw-r--r-- | arch/sh/kernel/cpu/sh5/fpu.c | 63 |
1 files changed, 5 insertions, 58 deletions
diff --git a/arch/sh/kernel/cpu/sh5/fpu.c b/arch/sh/kernel/cpu/sh5/fpu.c index 92df285fbe4b..4b3bb35e99f3 100644 --- a/arch/sh/kernel/cpu/sh5/fpu.c +++ b/arch/sh/kernel/cpu/sh5/fpu.c | |||
@@ -15,24 +15,6 @@ | |||
15 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
16 | #include <linux/signal.h> | 16 | #include <linux/signal.h> |
17 | #include <asm/processor.h> | 17 | #include <asm/processor.h> |
18 | #include <asm/user.h> | ||
19 | #include <asm/io.h> | ||
20 | #include <asm/fpu.h> | ||
21 | |||
22 | /* | ||
23 | * Initially load the FPU with signalling NANS. This bit pattern | ||
24 | * has the property that no matter whether considered as single or as | ||
25 | * double precision, it still represents a signalling NAN. | ||
26 | */ | ||
27 | #define sNAN64 0xFFFFFFFFFFFFFFFFULL | ||
28 | #define sNAN32 0xFFFFFFFFUL | ||
29 | |||
30 | static union thread_xstate init_fpuregs = { | ||
31 | .hardfpu = { | ||
32 | .fp_regs = { [0 ... 63] = sNAN32 }, | ||
33 | .fpscr = FPSCR_INIT | ||
34 | } | ||
35 | }; | ||
36 | 18 | ||
37 | void save_fpu(struct task_struct *tsk) | 19 | void save_fpu(struct task_struct *tsk) |
38 | { | 20 | { |
@@ -76,8 +58,7 @@ void save_fpu(struct task_struct *tsk) | |||
76 | : "memory"); | 58 | : "memory"); |
77 | } | 59 | } |
78 | 60 | ||
79 | static inline void | 61 | void restore_fpu(struct task_struct *tsk) |
80 | fpload(struct sh_fpu_hard_struct *fpregs) | ||
81 | { | 62 | { |
82 | asm volatile("fld.p %0, (0*8), fp0\n\t" | 63 | asm volatile("fld.p %0, (0*8), fp0\n\t" |
83 | "fld.p %0, (1*8), fp2\n\t" | 64 | "fld.p %0, (1*8), fp2\n\t" |
@@ -116,16 +97,11 @@ fpload(struct sh_fpu_hard_struct *fpregs) | |||
116 | 97 | ||
117 | "fld.p %0, (31*8), fp62\n\t" | 98 | "fld.p %0, (31*8), fp62\n\t" |
118 | : /* no output */ | 99 | : /* no output */ |
119 | : "r" (fpregs) ); | 100 | : "r" (&tsk->thread.xstate->hardfpu) |
120 | } | 101 | : "memory"); |
121 | |||
122 | void fpinit(struct sh_fpu_hard_struct *fpregs) | ||
123 | { | ||
124 | *fpregs = init_fpuregs.hardfpu; | ||
125 | } | 102 | } |
126 | 103 | ||
127 | asmlinkage void | 104 | asmlinkage void do_fpu_error(unsigned long ex, struct pt_regs *regs) |
128 | do_fpu_error(unsigned long ex, struct pt_regs *regs) | ||
129 | { | 105 | { |
130 | struct task_struct *tsk = current; | 106 | struct task_struct *tsk = current; |
131 | 107 | ||
@@ -133,35 +109,6 @@ do_fpu_error(unsigned long ex, struct pt_regs *regs) | |||
133 | 109 | ||
134 | tsk->thread.trap_no = 11; | 110 | tsk->thread.trap_no = 11; |
135 | tsk->thread.error_code = 0; | 111 | tsk->thread.error_code = 0; |
136 | force_sig(SIGFPE, tsk); | ||
137 | } | ||
138 | |||
139 | |||
140 | asmlinkage void | ||
141 | do_fpu_state_restore(unsigned long ex, struct pt_regs *regs) | ||
142 | { | ||
143 | void die(const char *str, struct pt_regs *regs, long err); | ||
144 | |||
145 | if (! user_mode(regs)) | ||
146 | die("FPU used in kernel", regs, ex); | ||
147 | 112 | ||
148 | regs->sr &= ~SR_FD; | 113 | force_sig(SIGFPE, tsk); |
149 | |||
150 | if (last_task_used_math == current) | ||
151 | return; | ||
152 | |||
153 | enable_fpu(); | ||
154 | if (last_task_used_math != NULL) | ||
155 | /* Other processes fpu state, save away */ | ||
156 | save_fpu(last_task_used_math); | ||
157 | |||
158 | last_task_used_math = current; | ||
159 | if (used_math()) { | ||
160 | fpload(¤t->thread.xstate->hardfpu); | ||
161 | } else { | ||
162 | /* First time FPU user. */ | ||
163 | fpload(&init_fpuregs.hardfpu); | ||
164 | set_used_math(); | ||
165 | } | ||
166 | disable_fpu(); | ||
167 | } | 114 | } |