diff options
-rw-r--r-- | target-alpha/translate.c | 70 |
1 files changed, 44 insertions, 26 deletions
diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 6ce4207adb..5c62244818 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -1772,6 +1772,13 @@ static ExitStatus gen_mtpr(DisasContext *ctx, int rb, int regno) } \ } while (0) +#define REQUIRE_REG_31(WHICH) \ + do { \ + if (WHICH != 31) { \ + goto invalid_opc; \ + } \ + } while (0) + static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) { uint32_t palcode; @@ -1780,7 +1787,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) int32_t disp12; #endif uint16_t fn11; - uint8_t opc, ra, rb, rc, fpfn, fn7, islit, real_islit; + uint8_t opc, ra, rb, rc, fpfn, fn7, islit; uint8_t lit; ExitStatus ret; @@ -1789,7 +1796,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) ra = (insn >> 21) & 0x1F; rb = (insn >> 16) & 0x1F; rc = insn & 0x1F; - real_islit = islit = (insn >> 12) & 1; + islit = (insn >> 12) & 1; if (rb == 31 && !islit) { islit = 1; lit = 0; @@ -2303,6 +2310,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x61: /* AMASK */ + REQUIRE_REG_31(ra); if (likely(rc != 31)) { uint64_t amask = ctx->tb->flags >> TB_FLAGS_AMASK_SHIFT; @@ -2323,6 +2331,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x6C: /* IMPLVER */ + REQUIRE_REG_31(ra); if (rc != 31) { tcg_gen_movi_i64(cpu_ir[rc], ctx->implver); } @@ -2544,6 +2553,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) switch (fpfn) { /* fn11 & 0x3F */ case 0x04: /* ITOFS */ + REQUIRE_REG_31(rb); if (likely(rc != 31)) { if (ra != 31) { TCGv_i32 tmp = tcg_temp_new_i32(); @@ -2556,14 +2566,17 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x0A: /* SQRTF */ + REQUIRE_REG_31(ra); gen_fsqrtf(rb, rc); break; case 0x0B: /* SQRTS */ + REQUIRE_REG_31(ra); gen_fsqrts(ctx, rb, rc, fn11); break; case 0x14: /* ITOFF */ + REQUIRE_REG_31(rb); if (likely(rc != 31)) { if (ra != 31) { TCGv_i32 tmp = tcg_temp_new_i32(); @@ -2576,6 +2589,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x24: /* ITOFT */ + REQUIRE_REG_31(rb); if (likely(rc != 31)) { if (ra != 31) { tcg_gen_mov_i64(cpu_fir[rc], cpu_ir[ra]); @@ -2586,10 +2600,12 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x2A: /* SQRTG */ + REQUIRE_REG_31(ra); gen_fsqrtg(rb, rc); break; case 0x02B: /* SQRTT */ + REQUIRE_REG_31(ra); gen_fsqrtt(ctx, rb, rc, fn11); break; default: @@ -2617,13 +2633,9 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) gen_fdivf(ra, rb, rc); break; case 0x1E: - /* CVTDG */ -#if 0 // TODO - gen_fcvtdg(rb, rc); -#else + /* CVTDG -- TODO */ + REQUIRE_REG_31(ra); goto invalid_opc; -#endif - break; case 0x20: /* ADDG */ gen_faddg(ra, rb, rc); @@ -2654,26 +2666,26 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x2C: /* CVTGF */ + REQUIRE_REG_31(ra); gen_fcvtgf(rb, rc); break; case 0x2D: - /* CVTGD */ -#if 0 // TODO - gen_fcvtgd(rb, rc); -#else + /* CVTGD -- TODO */ + REQUIRE_REG_31(ra); goto invalid_opc; -#endif - break; case 0x2F: /* CVTGQ */ + REQUIRE_REG_31(ra); gen_fcvtgq(rb, rc); break; case 0x3C: /* CVTQF */ + REQUIRE_REG_31(ra); gen_fcvtqf(rb, rc); break; case 0x3E: /* CVTQG */ + REQUIRE_REG_31(ra); gen_fcvtqg(rb, rc); break; default: @@ -2732,6 +2744,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) gen_fcmptle(ctx, ra, rb, rc, fn11); break; case 0x2C: + REQUIRE_REG_31(ra); if (fn11 == 0x2AC || fn11 == 0x6AC) { /* CVTST */ gen_fcvtst(ctx, rb, rc, fn11); @@ -2742,14 +2755,17 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x2F: /* CVTTQ */ + REQUIRE_REG_31(ra); gen_fcvttq(ctx, rb, rc, fn11); break; case 0x3C: /* CVTQS */ + REQUIRE_REG_31(ra); gen_fcvtqs(ctx, rb, rc, fn11); break; case 0x3E: /* CVTQT */ + REQUIRE_REG_31(ra); gen_fcvtqt(ctx, rb, rc, fn11); break; default: @@ -2760,6 +2776,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) switch (fn11) { case 0x010: /* CVTLQ */ + REQUIRE_REG_31(ra); gen_fcvtlq(rb, rc); break; case 0x020: @@ -2827,12 +2844,14 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) break; case 0x030: /* CVTQL */ + REQUIRE_REG_31(ra); gen_fcvtql(rb, rc); 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. */ @@ -3010,6 +3029,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) case 0x00: /* SEXTB */ REQUIRE_TB_FLAG(TB_FLAGS_AMASK_BWX); + REQUIRE_REG_31(ra); if (likely(rc != 31)) { if (islit) { tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int8_t)lit)); @@ -3021,6 +3041,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) case 0x01: /* SEXTW */ REQUIRE_TB_FLAG(TB_FLAGS_AMASK_BWX); + REQUIRE_REG_31(ra); if (likely(rc != 31)) { if (islit) { tcg_gen_movi_i64(cpu_ir[rc], (int64_t)((int16_t)lit)); @@ -3032,6 +3053,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) case 0x30: /* CTPOP */ REQUIRE_TB_FLAG(TB_FLAGS_AMASK_CIX); + REQUIRE_REG_31(ra); if (likely(rc != 31)) { if (islit) { tcg_gen_movi_i64(cpu_ir[rc], ctpop64(lit)); @@ -3048,6 +3070,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) case 0x32: /* CTLZ */ REQUIRE_TB_FLAG(TB_FLAGS_AMASK_CIX); + REQUIRE_REG_31(ra); if (likely(rc != 31)) { if (islit) { tcg_gen_movi_i64(cpu_ir[rc], clz64(lit)); @@ -3059,6 +3082,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) case 0x33: /* CTTZ */ REQUIRE_TB_FLAG(TB_FLAGS_AMASK_CIX); + REQUIRE_REG_31(ra); if (likely(rc != 31)) { if (islit) { tcg_gen_movi_i64(cpu_ir[rc], ctz64(lit)); @@ -3070,33 +3094,25 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) case 0x34: /* UNPKBW */ REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI); - if (real_islit || ra != 31) { - goto invalid_opc; - } + REQUIRE_REG_31(ra); gen_unpkbw(rb, rc); break; case 0x35: /* UNPKBL */ REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI); - if (real_islit || ra != 31) { - goto invalid_opc; - } + REQUIRE_REG_31(ra); gen_unpkbl(rb, rc); break; case 0x36: /* PKWB */ REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI); - if (real_islit || ra != 31) { - goto invalid_opc; - } + REQUIRE_REG_31(ra); gen_pkwb(rb, rc); break; case 0x37: /* PKLB */ REQUIRE_TB_FLAG(TB_FLAGS_AMASK_MVI); - if (real_islit || ra != 31) { - goto invalid_opc; - } + REQUIRE_REG_31(ra); gen_pklb(rb, rc); break; case 0x38: @@ -3142,6 +3158,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) case 0x70: /* FTOIT */ REQUIRE_TB_FLAG(TB_FLAGS_AMASK_FIX); + REQUIRE_REG_31(rb); if (likely(rc != 31)) { if (ra != 31) { tcg_gen_mov_i64(cpu_ir[rc], cpu_fir[ra]); @@ -3153,6 +3170,7 @@ static ExitStatus translate_one(DisasContext *ctx, uint32_t insn) case 0x78: /* FTOIS */ REQUIRE_TB_FLAG(TB_FLAGS_AMASK_FIX); + REQUIRE_REG_31(rb); if (rc != 31) { TCGv_i32 tmp1 = tcg_temp_new_i32(); if (ra != 31) { |