diff options
author | Richard Henderson <rth@twiddle.net> | 2015-08-03 12:35:53 -0700 |
---|---|---|
committer | Leon Alrae <leon.alrae@imgtec.com> | 2015-08-04 11:53:15 +0100 |
commit | b7f26e523914b982a1c1bfa8295f77ff9787c33c (patch) | |
tree | 2193e63204cf93b0a9b8c538d8f471f86f53e34d | |
parent | 060ebfef1a09b58fb219b3769b72efb407515bf1 (diff) |
target-mips: Copy restrictions from ext/ins to dext/dins
The checks in dins is required to avoid triggering an assertion
in tcg_gen_deposit_tl. The check in dext is just for completeness.
Fold the other D cases in via fallthru.
In this case the errant dins appears to be data, not code, as
translation failed to stop after a break insn.
Signed-off-by: Richard Henderson <rth@twiddle.net>
Reviewed-by: Aurelien Jarno <aurelien@aurel32.net>
Reviewed-by: Leon Alrae <leon.alrae@imgtec.com>
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
-rw-r--r-- | target-mips/translate.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/target-mips/translate.c b/target-mips/translate.c index e299643e04..22ef84df9e 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -4750,48 +4750,53 @@ static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt, gen_load_gpr(t1, rs); switch (opc) { case OPC_EXT: - if (lsb + msb > 31) + if (lsb + msb > 31) { goto fail; + } tcg_gen_shri_tl(t0, t1, lsb); if (msb != 31) { - tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1); + tcg_gen_andi_tl(t0, t0, (1U << (msb + 1)) - 1); } else { tcg_gen_ext32s_tl(t0, t0); } break; #if defined(TARGET_MIPS64) - case OPC_DEXTM: - tcg_gen_shri_tl(t0, t1, lsb); - if (msb != 31) { - tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1); - } - break; case OPC_DEXTU: - tcg_gen_shri_tl(t0, t1, lsb + 32); - tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1); - break; + lsb += 32; + goto do_dext; + case OPC_DEXTM: + msb += 32; + goto do_dext; case OPC_DEXT: + do_dext: + if (lsb + msb > 63) { + goto fail; + } tcg_gen_shri_tl(t0, t1, lsb); - tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1); + if (msb != 63) { + tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1); + } break; #endif case OPC_INS: - if (lsb > msb) + if (lsb > msb) { goto fail; + } gen_load_gpr(t0, rt); tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); tcg_gen_ext32s_tl(t0, t0); break; #if defined(TARGET_MIPS64) - case OPC_DINSM: - gen_load_gpr(t0, rt); - tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1); - break; case OPC_DINSU: - gen_load_gpr(t0, rt); - tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1); - break; + lsb += 32; + /* FALLTHRU */ + case OPC_DINSM: + msb += 32; + /* FALLTHRU */ case OPC_DINS: + if (lsb > msb) { + goto fail; + } gen_load_gpr(t0, rt); tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1); break; |