fpu.c (5bc65793cbf8da0d35f19ef025dda22887e79e80) fpu.c (74d99a5e262229ee865f6f68528d10b82471ead6)
1/* $Id: fpu.c,v 1.4 2004/01/13 05:52:11 kkojima Exp $
2 *
3 * linux/arch/sh/kernel/fpu.c
4 *
5 * Save/restore floating point context for signal handlers.
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive

--- 68 unchanged lines hidden (view full) ---

77 "fmov.s fr0, @-%0\n\t"
78 "lds %3, fpscr\n\t"
79 : "=r" (dummy)
80 : "0" ((char *)(&tsk->thread.fpu.hard.status)),
81 "r" (FPSCR_RCHG),
82 "r" (FPSCR_INIT)
83 : "memory");
84
1/* $Id: fpu.c,v 1.4 2004/01/13 05:52:11 kkojima Exp $
2 *
3 * linux/arch/sh/kernel/fpu.c
4 *
5 * Save/restore floating point context for signal handlers.
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive

--- 68 unchanged lines hidden (view full) ---

77 "fmov.s fr0, @-%0\n\t"
78 "lds %3, fpscr\n\t"
79 : "=r" (dummy)
80 : "0" ((char *)(&tsk->thread.fpu.hard.status)),
81 "r" (FPSCR_RCHG),
82 "r" (FPSCR_INIT)
83 : "memory");
84
85 disable_fpu();
86 release_fpu(regs);
85 disable_fpu();
86 release_fpu(regs);
87}
88
89static void
90restore_fpu(struct task_struct *tsk)
91{
92 unsigned long dummy;
93
87}
88
89static void
90restore_fpu(struct task_struct *tsk)
91{
92 unsigned long dummy;
93
94 enable_fpu();
94 enable_fpu();
95 asm volatile("lds %2, fpscr\n\t"
96 "fmov.s @%0+, fr0\n\t"
97 "fmov.s @%0+, fr1\n\t"
98 "fmov.s @%0+, fr2\n\t"
99 "fmov.s @%0+, fr3\n\t"
100 "fmov.s @%0+, fr4\n\t"
101 "fmov.s @%0+, fr5\n\t"
102 "fmov.s @%0+, fr6\n\t"

--- 30 unchanged lines hidden (view full) ---

133 : "0" (&tsk->thread.fpu), "r" (FPSCR_RCHG)
134 : "memory");
135 disable_fpu();
136}
137
138/*
139 * Load the FPU with signalling NANS. This bit pattern we're using
140 * has the property that no matter wether considered as single or as
95 asm volatile("lds %2, fpscr\n\t"
96 "fmov.s @%0+, fr0\n\t"
97 "fmov.s @%0+, fr1\n\t"
98 "fmov.s @%0+, fr2\n\t"
99 "fmov.s @%0+, fr3\n\t"
100 "fmov.s @%0+, fr4\n\t"
101 "fmov.s @%0+, fr5\n\t"
102 "fmov.s @%0+, fr6\n\t"

--- 30 unchanged lines hidden (view full) ---

133 : "0" (&tsk->thread.fpu), "r" (FPSCR_RCHG)
134 : "memory");
135 disable_fpu();
136}
137
138/*
139 * Load the FPU with signalling NANS. This bit pattern we're using
140 * has the property that no matter wether considered as single or as
141 * double precision represents signaling NANS.
141 * double precision represents signaling NANS.
142 */
143
144static void
145fpu_init(void)
146{
147 enable_fpu();
148 asm volatile("lds %0, fpul\n\t"
149 "lds %1, fpscr\n\t"

--- 29 unchanged lines hidden (view full) ---

179 "fsts fpul, fr12\n\t"
180 "fsts fpul, fr13\n\t"
181 "fsts fpul, fr14\n\t"
182 "fsts fpul, fr15\n\t"
183 "frchg\n\t"
184 "lds %2, fpscr\n\t"
185 : /* no output */
186 : "r" (0), "r" (FPSCR_RCHG), "r" (FPSCR_INIT));
142 */
143
144static void
145fpu_init(void)
146{
147 enable_fpu();
148 asm volatile("lds %0, fpul\n\t"
149 "lds %1, fpscr\n\t"

--- 29 unchanged lines hidden (view full) ---

179 "fsts fpul, fr12\n\t"
180 "fsts fpul, fr13\n\t"
181 "fsts fpul, fr14\n\t"
182 "fsts fpul, fr15\n\t"
183 "frchg\n\t"
184 "lds %2, fpscr\n\t"
185 : /* no output */
186 : "r" (0), "r" (FPSCR_RCHG), "r" (FPSCR_INIT));
187 disable_fpu();
187 disable_fpu();
188}
189
190/**
191 * denormal_to_double - Given denormalized float number,
192 * store double float
193 *
194 * @fpu: Pointer to sh_fpu_hard structure
195 * @n: Index to FP register

--- 37 unchanged lines hidden (view full) ---

233 (insn >> 12) & 0xf,
234 (insn >> 8) & 0xf,
235 (insn >> 4) & 0xf,
236 insn & 0xf};
237
238 if (nib[0] == 0xb ||
239 (nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb)) /* bsr & jsr */
240 regs->pr = regs->pc + 4;
188}
189
190/**
191 * denormal_to_double - Given denormalized float number,
192 * store double float
193 *
194 * @fpu: Pointer to sh_fpu_hard structure
195 * @n: Index to FP register

--- 37 unchanged lines hidden (view full) ---

233 (insn >> 12) & 0xf,
234 (insn >> 8) & 0xf,
235 (insn >> 4) & 0xf,
236 insn & 0xf};
237
238 if (nib[0] == 0xb ||
239 (nib[0] == 0x4 && nib[2] == 0x0 && nib[3] == 0xb)) /* bsr & jsr */
240 regs->pr = regs->pc + 4;
241
242 if (nib[0] == 0xa || nib[0] == 0xb) { /* bra & bsr */
243 nextpc = regs->pc + 4 + ((short) ((insn & 0xfff) << 4) >> 3);
244 finsn = *(unsigned short *) (regs->pc + 2);
245 } else if (nib[0] == 0x8 && nib[1] == 0xd) { /* bt/s */
246 if (regs->sr & 1)
247 nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1);
248 else
249 nextpc = regs->pc + 4;

--- 38 unchanged lines hidden (view full) ---

288
289 regs->pc = nextpc;
290 return 1;
291 }
292
293 return 0;
294}
295
241 if (nib[0] == 0xa || nib[0] == 0xb) { /* bra & bsr */
242 nextpc = regs->pc + 4 + ((short) ((insn & 0xfff) << 4) >> 3);
243 finsn = *(unsigned short *) (regs->pc + 2);
244 } else if (nib[0] == 0x8 && nib[1] == 0xd) { /* bt/s */
245 if (regs->sr & 1)
246 nextpc = regs->pc + 4 + ((char) (insn & 0xff) << 1);
247 else
248 nextpc = regs->pc + 4;

--- 38 unchanged lines hidden (view full) ---

287
288 regs->pc = nextpc;
289 return 1;
290 }
291
292 return 0;
293}
294
296asmlinkage void
297do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6,
298 unsigned long r7, struct pt_regs __regs)
295BUILD_TRAP_HANDLER(fpu_error)
299{
296{
300 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
301 struct task_struct *tsk = current;
297 struct task_struct *tsk = current;
298 TRAP_HANDLER_DECL;
302
303 if (ieee_fpe_handler(regs))
304 return;
305
306 regs->pc += 2;
307 save_fpu(tsk, regs);
308 force_sig(SIGFPE, tsk);
309}
310
299
300 if (ieee_fpe_handler(regs))
301 return;
302
303 regs->pc += 2;
304 save_fpu(tsk, regs);
305 force_sig(SIGFPE, tsk);
306}
307
311asmlinkage void
312do_fpu_state_restore(unsigned long r4, unsigned long r5, unsigned long r6,
313 unsigned long r7, struct pt_regs __regs)
308BUILD_TRAP_HANDLER(fpu_state_restore)
314{
309{
315 struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
316 struct task_struct *tsk = current;
310 struct task_struct *tsk = current;
311 TRAP_HANDLER_DECL;
317
318 grab_fpu(regs);
319 if (!user_mode(regs)) {
320 printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
321 return;
322 }
323
324 if (used_math()) {
325 /* Using the FPU again. */
326 restore_fpu(tsk);
327 } else {
328 /* First time FPU user. */
329 fpu_init();
330 set_used_math();
331 }
332 set_tsk_thread_flag(tsk, TIF_USEDFPU);
333}
312
313 grab_fpu(regs);
314 if (!user_mode(regs)) {
315 printk(KERN_ERR "BUG: FPU is used in kernel mode.\n");
316 return;
317 }
318
319 if (used_math()) {
320 /* Using the FPU again. */
321 restore_fpu(tsk);
322 } else {
323 /* First time FPU user. */
324 fpu_init();
325 set_used_math();
326 }
327 set_tsk_thread_flag(tsk, TIF_USEDFPU);
328}