diff options
author | Richard Henderson <rth@twiddle.net> | 2014-06-28 11:08:28 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2015-05-18 13:03:46 -0700 |
commit | 471d4930470aee38dffe6fc4890ede3d8eaf23c4 (patch) | |
tree | 00b69d7f1049b2a85c5d2bcb923c319734b0803d /target-alpha/fpu_helper.c | |
parent | f3d3aad4a920a4436a9f5397d7a2963aefe141a9 (diff) | |
download | qemu-471d4930470aee38dffe6fc4890ede3d8eaf23c4.zip qemu-471d4930470aee38dffe6fc4890ede3d8eaf23c4.tar.gz qemu-471d4930470aee38dffe6fc4890ede3d8eaf23c4.tar.bz2 |
target-alpha: Set fpcr_exc_status even for disabled exceptions
The qualifiers can suppress the raising of exceptions, but real
hardware still records that the exceptions occurred.
Reported-by: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-alpha/fpu_helper.c')
-rw-r--r-- | target-alpha/fpu_helper.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/target-alpha/fpu_helper.c b/target-alpha/fpu_helper.c index caf8317..6e84fd3 100644 --- a/target-alpha/fpu_helper.c +++ b/target-alpha/fpu_helper.c @@ -57,18 +57,16 @@ static uint32_t soft_to_fpcr_exc(CPUAlphaState *env) static void fp_exc_raise1(CPUAlphaState *env, uintptr_t retaddr, uint32_t exc, uint32_t regno) { - if (exc) { - uint32_t hw_exc = 0; + uint32_t hw_exc = 0; - hw_exc |= CONVERT_BIT(exc, FPCR_INV, EXC_M_INV); - hw_exc |= CONVERT_BIT(exc, FPCR_DZE, EXC_M_DZE); - hw_exc |= CONVERT_BIT(exc, FPCR_OVF, EXC_M_FOV); - hw_exc |= CONVERT_BIT(exc, FPCR_UNF, EXC_M_UNF); - hw_exc |= CONVERT_BIT(exc, FPCR_INE, EXC_M_INE); - hw_exc |= CONVERT_BIT(exc, FPCR_IOV, EXC_M_IOV); + hw_exc |= CONVERT_BIT(exc, FPCR_INV, EXC_M_INV); + hw_exc |= CONVERT_BIT(exc, FPCR_DZE, EXC_M_DZE); + hw_exc |= CONVERT_BIT(exc, FPCR_OVF, EXC_M_FOV); + hw_exc |= CONVERT_BIT(exc, FPCR_UNF, EXC_M_UNF); + hw_exc |= CONVERT_BIT(exc, FPCR_INE, EXC_M_INE); + hw_exc |= CONVERT_BIT(exc, FPCR_IOV, EXC_M_IOV); - arith_excp(env, retaddr, hw_exc, 1ull << regno); - } + arith_excp(env, retaddr, hw_exc, 1ull << regno); } /* Raise exceptions for ieee fp insns without software completion. @@ -76,8 +74,14 @@ static void fp_exc_raise1(CPUAlphaState *env, uintptr_t retaddr, doesn't apply. */ void helper_fp_exc_raise(CPUAlphaState *env, uint32_t ignore, uint32_t regno) { - uint32_t exc = env->error_code & ~ignore; - fp_exc_raise1(env, GETPC(), exc, regno); + uint32_t exc = env->error_code; + if (exc) { + env->fpcr |= exc; + exc &= ~ignore; + if (exc) { + fp_exc_raise1(env, GETPC(), exc, regno); + } + } } /* Raise exceptions for ieee fp insns with software completion. */ @@ -86,8 +90,11 @@ void helper_fp_exc_raise_s(CPUAlphaState *env, uint32_t ignore, uint32_t regno) uint32_t exc = env->error_code & ~ignore; if (exc) { env->fpcr |= exc; - exc &= env->fpcr_exc_enable; - fp_exc_raise1(env, GETPC(), exc, regno); + exc &= ~ignore; + if (exc) { + exc &= env->fpcr_exc_enable; + fp_exc_raise1(env, GETPC(), exc, regno); + } } } |