[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 06/17] target-alpha: Set fpcr_exc_status even for
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH v2 06/17] target-alpha: Set fpcr_exc_status even for disabled exceptions |
Date: |
Tue, 12 May 2015 10:39:36 -0700 |
The qualifiers can suppress the raising of exceptions, but real
hardware still records that the exceptions occurred.
Reported-by: Al Viro <address@hidden>
Signed-off-by: Richard Henderson <address@hidden>
---
target-alpha/fpu_helper.c | 35 +++++++++++++++++++++--------------
target-alpha/translate.c | 28 +++++++++++++---------------
2 files changed, 34 insertions(+), 29 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);
+ }
}
}
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 25107f9..f121320 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -663,15 +663,24 @@ static TCGv gen_ieee_input(DisasContext *ctx, int reg,
int fn11, int is_cmp)
return val;
}
-static void gen_fp_exc_raise_ignore(int rc, int fn11, int ignore)
+static void gen_fp_exc_raise(int rc, int fn11)
{
/* ??? We ought to be able to do something with imprecise exceptions.
E.g. notice we're still in the trap shadow of something within the
TB and do not generate the code to signal the exception; end the TB
when an exception is forced to arrive, either by consumption of a
register value or TRAPB or EXCB. */
- TCGv_i32 ign = tcg_const_i32(ignore);
- TCGv_i32 reg;
+ TCGv_i32 reg, ign;
+ uint32_t ignore = 0;
+
+ if (!(fn11 & QUAL_U)) {
+ /* Note that QUAL_U == QUAL_V, so ignore either. */
+ ignore |= FPCR_UNF | FPCR_IOV;
+ }
+ if (!(fn11 & QUAL_I)) {
+ ignore |= FPCR_INE;
+ }
+ ign = tcg_const_i32(ignore);
/* ??? Pass in the regno of the destination so that the helper can
set EXC_MASK, which contains a bitmask of destination registers
@@ -679,7 +688,6 @@ static void gen_fp_exc_raise_ignore(int rc, int fn11, int
ignore)
does not require this. We do need it for a guest kernel's entArith,
or if we were to do something clever with imprecise exceptions. */
reg = tcg_const_i32(rc + 32);
-
if (fn11 & QUAL_S) {
gen_helper_fp_exc_raise_s(cpu_env, ign, reg);
} else {
@@ -690,11 +698,6 @@ static void gen_fp_exc_raise_ignore(int rc, int fn11, int
ignore)
tcg_temp_free_i32(ign);
}
-static inline void gen_fp_exc_raise(int rc, int fn11)
-{
- gen_fp_exc_raise_ignore(rc, fn11, fn11 & QUAL_I ? 0 : FPCR_INE);
-}
-
static void gen_cvtlq(TCGv vc, TCGv vb)
{
TCGv tmp = tcg_temp_new();
@@ -752,7 +755,6 @@ IEEE_ARITH2(cvtts)
static void gen_cvttq(DisasContext *ctx, int rb, int rc, int fn11)
{
TCGv vb, vc;
- int ignore = 0;
/* No need to set flushzero, since we have an integer output. */
vb = gen_ieee_input(ctx, rb, fn11, 0);
@@ -766,20 +768,16 @@ static void gen_cvttq(DisasContext *ctx, int rb, int rc,
int fn11)
break;
case QUAL_V | QUAL_RM_C:
case QUAL_S | QUAL_V | QUAL_RM_C:
- ignore = FPCR_INE;
- /* FALLTHRU */
case QUAL_S | QUAL_V | QUAL_I | QUAL_RM_C:
gen_helper_cvttq_svic(vc, cpu_env, vb);
break;
default:
gen_qual_roundmode(ctx, fn11);
gen_helper_cvttq(vc, cpu_env, vb);
- ignore |= (fn11 & QUAL_V ? 0 : FPCR_IOV);
- ignore |= (fn11 & QUAL_I ? 0 : FPCR_INE);
break;
}
- gen_fp_exc_raise_ignore(rc, fn11, ignore);
+ gen_fp_exc_raise(rc, fn11);
}
static void gen_ieee_intcvt(DisasContext *ctx,
--
2.1.0
- [Qemu-devel] [PATCH v2 00/17] target-alpha fpu improvments, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 02/17] target-alpha: Rename floating-point subroutines, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 04/17] target-alpha: Set PC correctly for floating-point exceptions, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 01/17] target-alpha: Move VAX helpers to a new file, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 05/17] target-alpha: Tidy FPCR representation, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 06/17] target-alpha: Set fpcr_exc_status even for disabled exceptions,
Richard Henderson <=
- [Qemu-devel] [PATCH v2 03/17] target-alpha: Forget installed round mode after MT_FPCR, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 07/17] target-alpha: Set EXC_M_SWC for exceptions from /S insns, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 09/17] target-alpha: Fix cvttq vs large integers, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 08/17] target-alpha: Raise IOV from CVTTQ, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 11/17] target-alpha: Fix integer overflow checking insns, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 12/17] target-alpha: Implement WH64EN, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 10/17] target-alpha: Fix cvttq vs inf, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 13/17] target-alpha: Disallow literal operand to 1C.30 to 1C.37, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 14/17] target-alpha: Raise EXC_M_INV properly for fp inputs, Richard Henderson, 2015/05/12
- [Qemu-devel] [PATCH v2 17/17] target-alpha: Rewrite helper_zapnot, Richard Henderson, 2015/05/12