aboutsummaryrefslogtreecommitdiff
path: root/target-alpha
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2014-07-08 10:42:55 -0700
committerRichard Henderson <rth@twiddle.net>2015-05-18 13:03:47 -0700
commit57a808b6d7f52a62111f6070933dfca6cd88a0fd (patch)
treef67dbfd1e90490321d26ad2337ac21466d9631f5 /target-alpha
parent4ed069ab5334a495b49d0704795524fa34e8dbfc (diff)
target-alpha: Raise IOV from CVTQL
Even if an exception isn't taken, the status flags need updating and the result should be written to the destination. Move the body of cvtql out of line, since we now always need a call. Reported-by: Al Viro <viro@ZenIV.linux.org.uk> Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-alpha')
-rw-r--r--target-alpha/fpu_helper.c8
-rw-r--r--target-alpha/helper.h3
-rw-r--r--target-alpha/translate.c34
3 files changed, 13 insertions, 32 deletions
diff --git a/target-alpha/fpu_helper.c b/target-alpha/fpu_helper.c
index fa4401d4d6..b091aa842a 100644
--- a/target-alpha/fpu_helper.c
+++ b/target-alpha/fpu_helper.c
@@ -539,9 +539,13 @@ uint64_t helper_cvtqt(CPUAlphaState *env, uint64_t a)
return float64_to_t(fr);
}
-void helper_cvtql_v_input(CPUAlphaState *env, uint64_t val)
+uint64_t helper_cvtql(CPUAlphaState *env, uint64_t val)
{
+ uint32_t exc = 0;
if (val != (int32_t)val) {
- arith_excp(env, GETPC(), EXC_M_IOV, 0);
+ exc = FPCR_IOV | FPCR_INE;
}
+ env->error_code = exc;
+
+ return ((val & 0xc0000000) << 32) | ((val & 0x3fffffff) << 29);
}
diff --git a/target-alpha/helper.h b/target-alpha/helper.h
index 780b0dce8c..d221f0d7d6 100644
--- a/target-alpha/helper.h
+++ b/target-alpha/helper.h
@@ -79,6 +79,8 @@ DEF_HELPER_FLAGS_2(cvtqg, TCG_CALL_NO_RWG, i64, env, i64)
DEF_HELPER_FLAGS_2(cvttq, TCG_CALL_NO_RWG, i64, env, i64)
DEF_HELPER_FLAGS_2(cvttq_c, TCG_CALL_NO_RWG, i64, env, i64)
+DEF_HELPER_FLAGS_2(cvtql, TCG_CALL_NO_RWG, i64, env, i64)
+
DEF_HELPER_FLAGS_2(setroundmode, TCG_CALL_NO_RWG, void, env, i32)
DEF_HELPER_FLAGS_2(setflushzero, TCG_CALL_NO_RWG, void, env, i32)
DEF_HELPER_FLAGS_3(fp_exc_raise, TCG_CALL_NO_WG, void, env, i32, i32)
@@ -87,7 +89,6 @@ DEF_HELPER_FLAGS_3(fp_exc_raise_s, TCG_CALL_NO_WG, void, env, i32, i32)
DEF_HELPER_FLAGS_2(ieee_input, TCG_CALL_NO_WG, void, env, i64)
DEF_HELPER_FLAGS_2(ieee_input_cmp, TCG_CALL_NO_WG, void, env, i64)
DEF_HELPER_FLAGS_2(ieee_input_s, TCG_CALL_NO_WG, void, env, i64)
-DEF_HELPER_FLAGS_2(cvtql_v_input, TCG_CALL_NO_WG, void, env, i64)
#if !defined (CONFIG_USER_ONLY)
DEF_HELPER_2(hw_ret, void, env, i64)
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 4c441a91a3..e9927b56b4 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -720,19 +720,6 @@ static void gen_cvtlq(TCGv vc, TCGv vb)
tcg_temp_free(tmp);
}
-static void gen_cvtql(TCGv vc, TCGv vb)
-{
- TCGv tmp = tcg_temp_new();
-
- tcg_gen_andi_i64(tmp, vb, (int32_t)0xc0000000);
- tcg_gen_andi_i64(vc, vb, 0x3FFFFFFF);
- tcg_gen_shli_i64(tmp, tmp, 32);
- tcg_gen_shli_i64(vc, vc, 29);
- tcg_gen_or_i64(vc, vc, tmp);
-
- tcg_temp_free(tmp);
-}
-
static void gen_ieee_arith2(DisasContext *ctx,
void (*helper)(TCGv, TCGv_ptr, TCGv),
int rb, int rc, int fn11)
@@ -2254,25 +2241,14 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn)
/* FCMOVGT */
gen_fcmov(ctx, TCG_COND_GT, ra, rb, rc);
break;
- case 0x030:
- /* CVTQL */
- REQUIRE_REG_31(ra);
- vc = dest_fpr(ctx, rc);
- vb = load_fpr(ctx, rb);
- gen_cvtql(vc, vb);
- break;
- case 0x130:
- /* CVTQL/V */
- case 0x530:
- /* CVTQL/SV */
+ case 0x030: /* CVTQL */
+ case 0x130: /* CVTQL/V */
+ case 0x530: /* CVTQL/SV */
REQUIRE_REG_31(ra);
- /* ??? I'm pretty sure there's nothing that /sv needs to do that
- /v doesn't do. The only thing I can think is that /sv is a
- valid instruction merely for completeness in the ISA. */
vc = dest_fpr(ctx, rc);
vb = load_fpr(ctx, rb);
- gen_helper_cvtql_v_input(cpu_env, vb);
- gen_cvtql(vc, vb);
+ gen_helper_cvtql(vc, cpu_env, vb);
+ gen_fp_exc_raise(rc, fn11);
break;
default:
goto invalid_opc;