diff options
author | Richard Henderson <rth@twiddle.net> | 2014-03-19 12:32:05 -0700 |
---|---|---|
committer | Richard Henderson <rth@twiddle.net> | 2014-04-17 11:47:42 -0700 |
commit | e20b8c04a3fde9deec9d9460d8ece769ef9484b7 (patch) | |
tree | 3c45ce83a16f6eb58024992d660c6da6aa46cd9f /target-alpha/translate.c | |
parent | 8b0190bbde2916b47c2f157f92cdc06efacbf725 (diff) |
target-alpha: Convert most ieee insns to source/sink
This one fixes a bug, previously noted as supressing exceptions
in the (unlikely) case the destination register was $f31.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-alpha/translate.c')
-rw-r--r-- | target-alpha/translate.c | 69 |
1 files changed, 17 insertions, 52 deletions
diff --git a/target-alpha/translate.c b/target-alpha/translate.c index f6ebf54be0..ec5b523ccf 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -807,18 +807,12 @@ static void gen_ieee_arith2(DisasContext *ctx, { TCGv vb; - /* ??? This is wrong: the instruction is not a nop, it still may - raise exceptions. */ - if (unlikely(rc == 31)) { - return; - } - gen_qual_roundmode(ctx, fn11); gen_qual_flushzero(ctx, fn11); gen_fp_exc_clear(); vb = gen_ieee_input(ctx, rb, fn11, 0); - helper(cpu_fir[rc], cpu_env, vb); + helper(dest_fpr(ctx, rc), cpu_env, vb); gen_fp_exc_raise(rc, fn11); } @@ -836,35 +830,30 @@ IEEE_ARITH2(cvtts) static void gen_fcvttq(DisasContext *ctx, int rb, int rc, int fn11) { - TCGv vb; + TCGv vb, vc; int ignore = 0; - /* ??? This is wrong: the instruction is not a nop, it still may - raise exceptions. */ - if (unlikely(rc == 31)) { - return; - } - /* No need to set flushzero, since we have an integer output. */ gen_fp_exc_clear(); vb = gen_ieee_input(ctx, rb, fn11, 0); + vc = dest_fpr(ctx, rc); /* Almost all integer conversions use cropped rounding, and most also do not have integer overflow enabled. Special case that. */ switch (fn11) { case QUAL_RM_C: - gen_helper_cvttq_c(cpu_fir[rc], cpu_env, vb); + gen_helper_cvttq_c(vc, cpu_env, vb); 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(cpu_fir[rc], cpu_env, vb); + gen_helper_cvttq_svic(vc, cpu_env, vb); break; default: gen_qual_roundmode(ctx, fn11); - gen_helper_cvttq(cpu_fir[rc], cpu_env, vb); + gen_helper_cvttq(vc, cpu_env, vb); ignore |= (fn11 & QUAL_V ? 0 : float_flag_overflow); ignore |= (fn11 & QUAL_I ? 0 : float_flag_inexact); break; @@ -877,35 +866,21 @@ static void gen_ieee_intcvt(DisasContext *ctx, void (*helper)(TCGv, TCGv_ptr, TCGv), int rb, int rc, int fn11) { - TCGv vb; - - /* ??? This is wrong: the instruction is not a nop, it still may - raise exceptions. */ - if (unlikely(rc == 31)) { - return; - } + TCGv vb, vc; gen_qual_roundmode(ctx, fn11); - - if (rb == 31) { - vb = tcg_const_i64(0); - } else { - vb = cpu_fir[rb]; - } + vb = load_fpr(ctx, rb); + vc = dest_fpr(ctx, rc); /* The only exception that can be raised by integer conversion is inexact. Thus we only need to worry about exceptions when inexact handling is requested. */ if (fn11 & QUAL_I) { gen_fp_exc_clear(); - helper(cpu_fir[rc], cpu_env, vb); + helper(vc, cpu_env, vb); gen_fp_exc_raise(rc, fn11); } else { - helper(cpu_fir[rc], cpu_env, vb); - } - - if (rb == 31) { - tcg_temp_free(vb); + helper(vc, cpu_env, vb); } } @@ -997,13 +972,7 @@ static void gen_ieee_arith3(DisasContext *ctx, void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv), int ra, int rb, int rc, int fn11) { - TCGv va, vb; - - /* ??? This is wrong: the instruction is not a nop, it still may - raise exceptions. */ - if (unlikely(rc == 31)) { - return; - } + TCGv va, vb, vc; gen_qual_roundmode(ctx, fn11); gen_qual_flushzero(ctx, fn11); @@ -1011,7 +980,8 @@ static void gen_ieee_arith3(DisasContext *ctx, va = gen_ieee_input(ctx, ra, fn11, 0); vb = gen_ieee_input(ctx, rb, fn11, 0); - helper(cpu_fir[rc], cpu_env, va, vb); + vc = dest_fpr(ctx, rc); + helper(vc, cpu_env, va, vb); gen_fp_exc_raise(rc, fn11); } @@ -1035,19 +1005,14 @@ static void gen_ieee_compare(DisasContext *ctx, void (*helper)(TCGv, TCGv_ptr, TCGv, TCGv), int ra, int rb, int rc, int fn11) { - TCGv va, vb; - - /* ??? This is wrong: the instruction is not a nop, it still may - raise exceptions. */ - if (unlikely(rc == 31)) { - return; - } + TCGv va, vb, vc; gen_fp_exc_clear(); va = gen_ieee_input(ctx, ra, fn11, 1); vb = gen_ieee_input(ctx, rb, fn11, 1); - helper(cpu_fir[rc], cpu_env, va, vb); + vc = dest_fpr(ctx, rc); + helper(vc, cpu_env, va, vb); gen_fp_exc_raise(rc, fn11); } |