diff options
Diffstat (limited to 'arch/powerpc/math-emu/math_efp.c')
-rw-r--r-- | arch/powerpc/math-emu/math_efp.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/arch/powerpc/math-emu/math_efp.c b/arch/powerpc/math-emu/math_efp.c index a73f0884d358..59835c625dc6 100644 --- a/arch/powerpc/math-emu/math_efp.c +++ b/arch/powerpc/math-emu/math_efp.c | |||
@@ -630,9 +630,27 @@ update_ccr: | |||
630 | regs->ccr |= (IR << ((7 - ((speinsn >> 23) & 0x7)) << 2)); | 630 | regs->ccr |= (IR << ((7 - ((speinsn >> 23) & 0x7)) << 2)); |
631 | 631 | ||
632 | update_regs: | 632 | update_regs: |
633 | __FPU_FPSCR &= ~FP_EX_MASK; | 633 | /* |
634 | * If the "invalid" exception sticky bit was set by the | ||
635 | * processor for non-finite input, but was not set before the | ||
636 | * instruction being emulated, clear it. Likewise for the | ||
637 | * "underflow" bit, which may have been set by the processor | ||
638 | * for exact underflow, not just inexact underflow when the | ||
639 | * flag should be set for IEEE 754 semantics. Other sticky | ||
640 | * exceptions will only be set by the processor when they are | ||
641 | * correct according to IEEE 754 semantics, and we must not | ||
642 | * clear sticky bits that were already set before the emulated | ||
643 | * instruction as they represent the user-visible sticky | ||
644 | * exception status. "inexact" traps to kernel are not | ||
645 | * required for IEEE semantics and are not enabled by default, | ||
646 | * so the "inexact" sticky bit may have been set by a previous | ||
647 | * instruction without the kernel being aware of it. | ||
648 | */ | ||
649 | __FPU_FPSCR | ||
650 | &= ~(FP_EX_INVALID | FP_EX_UNDERFLOW) | current->thread.spefscr_last; | ||
634 | __FPU_FPSCR |= (FP_CUR_EXCEPTIONS & FP_EX_MASK); | 651 | __FPU_FPSCR |= (FP_CUR_EXCEPTIONS & FP_EX_MASK); |
635 | mtspr(SPRN_SPEFSCR, __FPU_FPSCR); | 652 | mtspr(SPRN_SPEFSCR, __FPU_FPSCR); |
653 | current->thread.spefscr_last = __FPU_FPSCR; | ||
636 | 654 | ||
637 | current->thread.evr[fc] = vc.wp[0]; | 655 | current->thread.evr[fc] = vc.wp[0]; |
638 | regs->gpr[fc] = vc.wp[1]; | 656 | regs->gpr[fc] = vc.wp[1]; |