From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, viro@ZenIV.linux.org.uk
Subject: [Qemu-devel] [PULL 04/18] target-alpha: Set fpcr_exc_status even for disabled exceptions
Date: Wed, 9 Jul 2014 09:20:20 -0700 [thread overview]
Message-ID: <1404922834-28169-5-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1404922834-28169-1-git-send-email-rth@twiddle.net>
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>
---
target-alpha/fpu_helper.c | 67 ++++++++++++++++++++++++++---------------------
target-alpha/translate.c | 41 ++++++++++-------------------
2 files changed, 51 insertions(+), 57 deletions(-)
diff --git a/target-alpha/fpu_helper.c b/target-alpha/fpu_helper.c
index aa83766..efc5dfa 100644
--- a/target-alpha/fpu_helper.c
+++ b/target-alpha/fpu_helper.c
@@ -44,50 +44,57 @@ uint32_t helper_fp_exc_get(CPUAlphaState *env)
return get_float_exception_flags(&FP_STATUS);
}
-static inline void inline_fp_exc_raise(CPUAlphaState *env, uintptr_t retaddr,
- uint32_t exc, uint32_t regno)
+static inline void fp_exc_raise1(CPUAlphaState *env, uintptr_t retaddr,
+ uint32_t exc, uint32_t regno)
{
- if (exc) {
- uint32_t hw_exc = 0;
-
- if (exc & float_flag_invalid) {
- hw_exc |= EXC_M_INV;
- }
- if (exc & float_flag_int_overflow) {
- hw_exc |= EXC_M_IOV;
- }
- if (exc & float_flag_divbyzero) {
- hw_exc |= EXC_M_DZE;
- }
- if (exc & float_flag_overflow) {
- hw_exc |= EXC_M_FOV;
- }
- if (exc & float_flag_underflow) {
- hw_exc |= EXC_M_UNF;
- }
- if (exc & float_flag_inexact) {
- hw_exc |= EXC_M_INE;
- }
-
- arith_excp(env, retaddr, hw_exc, 1ull << regno);
+ uint32_t hw_exc = 0;
+ if (exc & float_flag_invalid) {
+ hw_exc |= EXC_M_INV;
+ }
+ if (exc & float_flag_int_overflow) {
+ hw_exc |= EXC_M_IOV;
}
+ if (exc & float_flag_divbyzero) {
+ hw_exc |= EXC_M_DZE;
+ }
+ if (exc & float_flag_overflow) {
+ hw_exc |= EXC_M_FOV;
+ }
+ if (exc & float_flag_underflow) {
+ hw_exc |= EXC_M_UNF;
+ }
+ if (exc & float_flag_inexact) {
+ hw_exc |= EXC_M_INE;
+ }
+ arith_excp(env, retaddr, hw_exc, 1ull << regno);
}
/* Raise exceptions for ieee fp insns without software completion.
In that case there are no exceptions that don't trap; the mask
doesn't apply. */
-void helper_fp_exc_raise(CPUAlphaState *env, uint32_t exc, uint32_t regno)
+void helper_fp_exc_raise(CPUAlphaState *env, uint32_t ignore, uint32_t regno)
{
- inline_fp_exc_raise(env, GETPC(), exc, regno);
+ uint32_t exc = (uint8_t)env->fp_status.float_exception_flags;
+ if (exc) {
+ env->fpcr_exc_status |= exc;
+ exc &= ~ignore;
+ if (exc) {
+ fp_exc_raise1(env, GETPC(), exc, regno, 0);
+ }
+ }
}
/* Raise exceptions for ieee fp insns with software completion. */
-void helper_fp_exc_raise_s(CPUAlphaState *env, uint32_t exc, uint32_t regno)
+void helper_fp_exc_raise_s(CPUAlphaState *env, uint32_t ignore, uint32_t regno)
{
+ uint32_t exc = (uint8_t)env->fp_status.float_exception_flags;
if (exc) {
env->fpcr_exc_status |= exc;
- exc &= ~env->fpcr_exc_mask;
- inline_fp_exc_raise(env, GETPC(), exc, regno);
+ exc &= ~ignore;
+ if (exc) {
+ exc &= ~env->fpcr_exc_mask;
+ fp_exc_raise1(env, GETPC(), exc, regno);
+ }
}
}
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 0bd903c..1c2d72e 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -672,26 +672,24 @@ static void gen_fp_exc_clear(void)
#endif
}
-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 exc = tcg_temp_new_i32();
- TCGv_i32 reg;
+ TCGv_i32 reg, ign;
+ uint32_t ignore = 0;
-#if defined(CONFIG_SOFTFLOAT_INLINE)
- tcg_gen_ld8u_i32(exc, cpu_env,
- offsetof(CPUAlphaState, fp_status.float_exception_flags));
-#else
- gen_helper_fp_exc_get(exc, cpu_env);
-#endif
-
- if (ignore) {
- tcg_gen_andi_i32(exc, exc, ~ignore);
+ if (!(fn11 & QUAL_U)) {
+ /* Note that QUAL_U == QUAL_V, so ignore either. */
+ ignore |= float_flag_underflow | float_flag_int_overflow;
+ }
+ if (!(fn11 & QUAL_I)) {
+ ignore |= float_flag_inexact;
}
+ 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
@@ -699,20 +697,14 @@ 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, exc, reg);
+ gen_helper_fp_exc_raise_s(cpu_env, ign, reg);
} else {
- gen_helper_fp_exc_raise(cpu_env, exc, reg);
+ gen_helper_fp_exc_raise(cpu_env, ign, reg);
}
tcg_temp_free_i32(reg);
- tcg_temp_free_i32(exc);
-}
-
-static inline void gen_fp_exc_raise(int rc, int fn11)
-{
- gen_fp_exc_raise_ignore(rc, fn11, fn11 & QUAL_I ? 0 : float_flag_inexact);
+ tcg_temp_free_i32(ign);
}
static void gen_fcvtlq(TCGv vc, TCGv vb)
@@ -773,7 +765,6 @@ IEEE_ARITH2(cvtts)
static void gen_fcvttq(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. */
gen_fp_exc_clear();
@@ -788,20 +779,16 @@ static void gen_fcvttq(DisasContext *ctx, int rb, int rc, int fn11)
break;
case QUAL_V | QUAL_RM_C:
case QUAL_S | QUAL_V | QUAL_RM_C:
- ignore = float_flag_inexact;
- /* 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 : float_flag_overflow);
- ignore |= (fn11 & QUAL_I ? 0 : float_flag_inexact);
break;
}
- gen_fp_exc_raise_ignore(rc, fn11, ignore);
+ gen_fp_exc_raise(rc, fn11);
}
static void gen_ieee_intcvt(DisasContext *ctx,
--
1.9.3
next prev parent reply other threads:[~2014-07-09 16:20 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-09 16:20 [Qemu-devel] [PULL for-2.1 00/18] target-alpha patch queue Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 01/18] target-alpha: Forget installed round mode after MT_FPCR Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 02/18] target-alpha: Set PC correctly for floating-point exceptions Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 03/18] target-alpha: Store IOV exception in fp_status Richard Henderson
2014-07-09 16:28 ` Peter Maydell
2014-07-09 16:48 ` Richard Henderson
2014-07-09 16:20 ` Richard Henderson [this message]
2014-07-09 16:20 ` [Qemu-devel] [PULL 05/18] target-alpha: Set EXC_M_SWC for exceptions from /S insns Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 06/18] target-alpha: Raise IOV from CVTTQ Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 07/18] target-alpha: Fix cvttq vs large integers Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 08/18] target-alpha: Fix cvttq vs inf Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 09/18] target-alpha: Fix integer overflow checking insns Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 10/18] target-alpha: Implement WH64EN Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 11/18] target-alpha: Disallow literal operand to 1C.30 to 1C.37 Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 12/18] target-alpha: Ignore the unused fp_status exceptions Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 13/18] target-alpha: Raise EXC_M_INV properly for fp inputs Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 14/18] target-alpha: Suppress underflow from CVTTQ if DNZ Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 15/18] target-alpha: Raise IOV from CVTQL Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 16/18] target-alpha: Rename fcvtql Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 17/18] target-alpha: Fix fpcr_flush_to_zero initialization Richard Henderson
2014-07-09 16:20 ` [Qemu-devel] [PULL 18/18] target-alpha: Remove DNOD bit from FPCR Richard Henderson
2014-07-09 16:30 ` [Qemu-devel] [PULL for-2.1 00/18] target-alpha patch queue Peter Maydell
2014-07-09 16:37 ` Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1404922834-28169-5-git-send-email-rth@twiddle.net \
--to=rth@twiddle.net \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=viro@ZenIV.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).