aboutsummaryrefslogtreecommitdiff
path: root/target-alpha/fpu_helper.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2014-06-28 11:08:28 -0700
committerRichard Henderson <rth@twiddle.net>2015-05-18 13:03:46 -0700
commit471d4930470aee38dffe6fc4890ede3d8eaf23c4 (patch)
tree00b69d7f1049b2a85c5d2bcb923c319734b0803d /target-alpha/fpu_helper.c
parentf3d3aad4a920a4436a9f5397d7a2963aefe141a9 (diff)
downloadqemu-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.c35
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);
+ }
}
}