mirror of https://gitee.com/openkylin/qemu.git
target-mips: use deposit instead of hardcoded version
Use the deposit op instead of and hardcoded bit field insertion. It allows the host to emit the corresponding instruction if available. At the same time remove the (lsb > msb) test. The MIPS64R2 instruction set manual says "Because of the instruction format, lsb can never be greater than msb, so there is no UNPREDICATABLE case for this instruction." (Bug reported as LP:1071149.) Cc: Никита Канунников <n.kanunnikov@sbtcom.ru> Reviewed-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
51127181cf
commit
e0d002f17d
|
@ -3928,7 +3928,6 @@ static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
|
|||
{
|
||||
TCGv t0 = tcg_temp_new();
|
||||
TCGv t1 = tcg_temp_new();
|
||||
target_ulong mask;
|
||||
|
||||
gen_load_gpr(t1, rs);
|
||||
switch (opc) {
|
||||
|
@ -3961,45 +3960,22 @@ static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
|
|||
case OPC_INS:
|
||||
if (lsb > msb)
|
||||
goto fail;
|
||||
mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
|
||||
gen_load_gpr(t0, rt);
|
||||
tcg_gen_andi_tl(t0, t0, ~mask);
|
||||
tcg_gen_shli_tl(t1, t1, lsb);
|
||||
tcg_gen_andi_tl(t1, t1, mask);
|
||||
tcg_gen_or_tl(t0, t0, t1);
|
||||
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:
|
||||
if (lsb > msb)
|
||||
goto fail;
|
||||
mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
|
||||
gen_load_gpr(t0, rt);
|
||||
tcg_gen_andi_tl(t0, t0, ~mask);
|
||||
tcg_gen_shli_tl(t1, t1, lsb);
|
||||
tcg_gen_andi_tl(t1, t1, mask);
|
||||
tcg_gen_or_tl(t0, t0, t1);
|
||||
tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
|
||||
break;
|
||||
case OPC_DINSU:
|
||||
if (lsb > msb)
|
||||
goto fail;
|
||||
mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
|
||||
gen_load_gpr(t0, rt);
|
||||
tcg_gen_andi_tl(t0, t0, ~mask);
|
||||
tcg_gen_shli_tl(t1, t1, lsb + 32);
|
||||
tcg_gen_andi_tl(t1, t1, mask);
|
||||
tcg_gen_or_tl(t0, t0, t1);
|
||||
tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
|
||||
break;
|
||||
case OPC_DINS:
|
||||
if (lsb > msb)
|
||||
goto fail;
|
||||
gen_load_gpr(t0, rt);
|
||||
mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
|
||||
gen_load_gpr(t0, rt);
|
||||
tcg_gen_andi_tl(t0, t0, ~mask);
|
||||
tcg_gen_shli_tl(t1, t1, lsb);
|
||||
tcg_gen_andi_tl(t1, t1, mask);
|
||||
tcg_gen_or_tl(t0, t0, t1);
|
||||
tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue