Commit 57a808b6 authored by Richard Henderson's avatar Richard Henderson
Browse files

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: default avatarAl Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: default avatarRichard Henderson <rth@twiddle.net>
parent 4ed069ab
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -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);
}
+2 −1
Original line number Diff line number Diff line
@@ -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)
+5 −29
Original line number Diff line number Diff line
@@ -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;