Commit e0d002f1 authored by Aurelien Jarno's avatar Aurelien Jarno
Browse files

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: default avatarRichard Henderson <rth@twiddle.net>
Signed-off-by: default avatarAurelien Jarno <aurelien@aurel32.net>
parent 51127181
Loading
Loading
Loading
Loading
+4 −28
Original line number Diff line number Diff line
@@ -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: