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} |