patch-2.2.15 linux/arch/alpha/math-emu/math.c
Next file: linux/arch/alpha/math-emu/sfp-machine.h
Previous file: linux/arch/alpha/kernel/sys_nautilus.c
Back to the patch index
Back to the overall index
- Lines: 93
- Date:
Fri Apr 21 12:45:45 2000
- Orig file:
v2.2.14/arch/alpha/math-emu/math.c
- Orig date:
Tue Jan 4 21:18:39 2000
diff -u --new-file --recursive --exclude-from ../../exclude v2.2.14/arch/alpha/math-emu/math.c linux/arch/alpha/math-emu/math.c
@@ -159,8 +159,7 @@
FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
- unsigned long fa, fb, fc, func, mode, src;
- unsigned long fpcw = current->tss.flags;
+ unsigned long fa, fb, fc, func, mode, src, swcr;
unsigned long res, va, vb, vc, fpcr;
__u32 insn;
@@ -175,10 +174,11 @@
mode = (insn >> 11) & 0x3;
fpcr = rdfpcr();
+ swcr = swcr_update_status(current->tss.flags, fpcr);
if (mode == 3) {
- /* Dynamic -- get rounding mode from fpcr. */
- mode = (fpcr >> FPCR_DYN_SHIFT) & 3;
+ /* Dynamic -- get rounding mode from fpcr. */
+ mode = (fpcr >> FPCR_DYN_SHIFT) & 3;
}
switch (src) {
@@ -231,9 +231,14 @@
}
FP_CMP_D(res, DA, DB, 3);
vc = 0x4000000000000000;
- /* CMPTEQ, CMPTUN don't trap on QNaN, while CMPTLT and CMPTLE do */
- if (res == 3 && ((func & 3) >= 2 || FP_ISSIGNAN_D(DA) || FP_ISSIGNAN_D(DB)))
+ /* CMPTEQ, CMPTUN don't trap on QNaN,
+ while CMPTLT and CMPTLE do */
+ if (res == 3
+ && ((func & 3) >= 2
+ || FP_ISSIGNAN_D(DA)
+ || FP_ISSIGNAN_D(DB))) {
FP_SET_EXCEPTION(FP_EX_INVALID);
+ }
switch (func) {
case FOP_FNC_CMPxUN: if (res != 3) vc = 0; break;
case FOP_FNC_CMPxEQ: if (res) vc = 0; break;
@@ -285,9 +290,11 @@
}
case FOP_FNC_CVTxQ:
- if (DB_c == FP_CLS_NAN && (_FP_FRAC_HIGH_RAW_D(DB) & _FP_QNANBIT_D))
- vc = 0; /* AAHB Table B-2 sais QNaN should not trigger INV */
- else
+ if (DB_c == FP_CLS_NAN
+ && (_FP_FRAC_HIGH_RAW_D(DB) & _FP_QNANBIT_D)) {
+ /* AAHB Table B-2 says QNaN should not trigger INV */
+ vc = 0;
+ } else
FP_TO_INT_ROUND_D(vc, DB, 64, 2);
goto done_d;
}
@@ -321,11 +328,15 @@
pack_s:
FP_PACK_SP(&vc, SR);
+ if ((_fex & FP_EX_UNDERFLOW) && (swcr & IEEE_MAP_UMZ))
+ vc = 0;
alpha_write_fp_reg_s(fc, vc);
goto done;
pack_d:
FP_PACK_DP(&vc, DR);
+ if ((_fex & FP_EX_UNDERFLOW) && (swcr & IEEE_MAP_UMZ))
+ vc = 0;
done_d:
alpha_write_fp_reg(fc, vc);
goto done;
@@ -345,16 +356,16 @@
done:
if (_fex) {
/* Record exceptions in software control word. */
- current->tss.flags
- = fpcw |= (_fex << IEEE_STATUS_TO_EXCSUM_SHIFT);
+ swcr |= (_fex << IEEE_STATUS_TO_EXCSUM_SHIFT);
+ current->tss.flags |= (_fex << IEEE_STATUS_TO_EXCSUM_SHIFT);
/* Update hardware control register */
fpcr &= (~FPCR_MASK | FPCR_DYN_MASK);
- fpcr |= ieee_swcr_to_fpcr(fpcw);
+ fpcr |= ieee_swcr_to_fpcr(swcr);
wrfpcr(fpcr);
/* Do we generate a signal? */
- if (_fex & fpcw & IEEE_TRAP_ENABLE_MASK) {
+ if (_fex & swcr & IEEE_TRAP_ENABLE_MASK) {
MOD_DEC_USE_COUNT;
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)