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 */ + case 0x030: /* CVTQL */ + case 0x130: /* CVTQL/V */ + case 0x530: /* CVTQL/SV */ 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 */ - 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;