aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/sh4/fpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/kernel/cpu/sh4/fpu.c')
-rw-r--r--arch/sh/kernel/cpu/sh4/fpu.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/arch/sh/kernel/cpu/sh4/fpu.c b/arch/sh/kernel/cpu/sh4/fpu.c
index 2d452f67fb87..2780917c0088 100644
--- a/arch/sh/kernel/cpu/sh4/fpu.c
+++ b/arch/sh/kernel/cpu/sh4/fpu.c
@@ -36,7 +36,7 @@ extern unsigned long int float32_add(unsigned long int a, unsigned long int b);
36extern unsigned long long float64_sub(unsigned long long a, 36extern unsigned long long float64_sub(unsigned long long a,
37 unsigned long long b); 37 unsigned long long b);
38extern unsigned long int float32_sub(unsigned long int a, unsigned long int b); 38extern unsigned long int float32_sub(unsigned long int a, unsigned long int b);
39 39extern unsigned long int float64_to_float32(unsigned long long a);
40static unsigned int fpu_exception_flags; 40static unsigned int fpu_exception_flags;
41 41
42/* 42/*
@@ -417,6 +417,29 @@ static int ieee_fpe_handler(struct pt_regs *regs)
417 417
418 regs->pc = nextpc; 418 regs->pc = nextpc;
419 return 1; 419 return 1;
420 } else if ((finsn & 0xf0bd) == 0xf0bd) {
421 /* fcnvds - double to single precision convert */
422 struct task_struct *tsk = current;
423 int m;
424 unsigned int hx;
425
426 m = (finsn >> 9) & 0x7;
427 hx = tsk->thread.fpu.hard.fp_regs[m];
428
429 if ((tsk->thread.fpu.hard.fpscr & FPSCR_CAUSE_ERROR)
430 && ((hx & 0x7fffffff) < 0x00100000)) {
431 /* subnormal double to float conversion */
432 long long llx;
433
434 llx = ((long long)tsk->thread.fpu.hard.fp_regs[m] << 32)
435 | tsk->thread.fpu.hard.fp_regs[m + 1];
436
437 tsk->thread.fpu.hard.fpul = float64_to_float32(llx);
438 } else
439 return 0;
440
441 regs->pc = nextpc;
442 return 1;
420 } 443 }
421 444
422 return 0; 445 return 0;