Commit f484d386 authored by Fabrice Bellard's avatar Fabrice Bellard
Browse files

converted bit test operations to TCG

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4473 c046a42c-6fe2-441c-8c8c-71466251a162
parent 07d2c595
Loading
Loading
Loading
Loading
+0 −43
Original line number Diff line number Diff line
@@ -203,42 +203,6 @@ void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
/* bit operations */
#if DATA_BITS >= 16

void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void)
{
    int count;
    count = T1 & SHIFT_MASK;
    CC_SRC = T0 >> count;
}

void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
{
    int count;
    count = T1 & SHIFT_MASK;
    T1 = T0 >> count;
    T0 |= (((target_long)1) << count);
}

void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
{
    int count;
    count = T1 & SHIFT_MASK;
    T1 = T0 >> count;
    T0 &= ~(((target_long)1) << count);
}

void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
{
    int count;
    count = T1 & SHIFT_MASK;
    T1 = T0 >> count;
    T0 ^= (((target_long)1) << count);
}

void OPPROTO glue(glue(op_add_bit, SUFFIX), _A0_T1)(void)
{
    A0 += ((DATA_STYPE)T1 >> (3 + SHIFT)) << SHIFT;
}

void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
{
    int count;
@@ -281,13 +245,6 @@ void OPPROTO glue(glue(op_bsr, SUFFIX), _T0_cc)(void)

#endif

#if DATA_BITS == 32
void OPPROTO op_update_bt_cc(void)
{
    CC_SRC = T1;
}
#endif

/* string operations */

void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void)
+53 −55
Original line number Diff line number Diff line
@@ -498,35 +498,6 @@ static GenOpFunc *gen_op_cmov_reg_T1_T0[NB_OP_SIZES - 1][CPU_NB_REGS] = {
#endif
};

static GenOpFunc *gen_op_btx_T0_T1_cc[3][4] = {
    [0] = {
        gen_op_btw_T0_T1_cc,
        gen_op_btsw_T0_T1_cc,
        gen_op_btrw_T0_T1_cc,
        gen_op_btcw_T0_T1_cc,
    },
    [1] = {
        gen_op_btl_T0_T1_cc,
        gen_op_btsl_T0_T1_cc,
        gen_op_btrl_T0_T1_cc,
        gen_op_btcl_T0_T1_cc,
    },
#ifdef TARGET_X86_64
    [2] = {
        gen_op_btq_T0_T1_cc,
        gen_op_btsq_T0_T1_cc,
        gen_op_btrq_T0_T1_cc,
        gen_op_btcq_T0_T1_cc,
    },
#endif
};

static GenOpFunc *gen_op_add_bit_A0_T1[3] = {
    gen_op_add_bitw_A0_T1,
    gen_op_add_bitl_A0_T1,
    X86_64_ONLY(gen_op_add_bitq_A0_T1),
};

static GenOpFunc *gen_op_bsx_T0_cc[3][2] = {
    [0] = {
        gen_op_bsfw_T0_cc,
@@ -1379,6 +1350,23 @@ static void gen_extu(int ot, TCGv reg)
    }
}

static void gen_exts(int ot, TCGv reg)
{
    switch(ot) {
    case OT_BYTE:
        tcg_gen_ext8s_tl(reg, reg);
        break;
    case OT_WORD:
        tcg_gen_ext16s_tl(reg, reg);
        break;
    case OT_LONG:
        tcg_gen_ext32s_tl(reg, reg);
        break;
    default:
        break;
    }
}

/* XXX: add faster immediate case */
static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, 
                            int is_right, int is_arith)
@@ -1403,19 +1391,7 @@ static void gen_shift_rm_T1(DisasContext *s, int ot, int op1,

    if (is_right) {
        if (is_arith) {
            switch(ot) {
            case OT_BYTE:
                tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
                break;
            case OT_WORD:
                tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
                break;
            case OT_LONG:
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
                break;
            default:
                break;
            }
            gen_exts(ot, cpu_T[0]);
            tcg_gen_sar_tl(cpu_T3, cpu_T[0], cpu_tmp5);
            tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
        } else {
@@ -5791,16 +5767,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
        if (op < 4)
            goto illegal_op;
        op -= 4;
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
        s->cc_op = CC_OP_SARB + ot;
        if (op != 0) {
            if (mod != 3)
                gen_op_st_T0_A0(ot + s->mem_index);
            else
                gen_op_mov_reg_T0(ot, rm);
            gen_op_update_bt_cc();
        }
        break;
        goto bt_op;
    case 0x1a3: /* bt Gv, Ev */
        op = 0;
        goto do_btx;
@@ -5822,19 +5789,50 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
        if (mod != 3) {
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
            /* specific case: we need to add a displacement */
            gen_op_add_bit_A0_T1[ot - OT_WORD]();
            gen_exts(ot, cpu_T[1]);
            tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot);
            tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
            gen_op_ld_T0_A0(ot + s->mem_index);
        } else {
            gen_op_mov_TN_reg(ot, 0, rm);
        }
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
    bt_op:
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
        switch(op) {
        case 0:
            tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]);
            tcg_gen_movi_tl(cpu_cc_dst, 0);
            break;
        case 1:
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
            tcg_gen_movi_tl(cpu_tmp0, 1);
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
            break;
        case 2:
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
            tcg_gen_movi_tl(cpu_tmp0, 1);
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
            tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
            tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
            break;
        default:
        case 3:
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
            tcg_gen_movi_tl(cpu_tmp0, 1);
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
            tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
            break;
        }
        s->cc_op = CC_OP_SARB + ot;
        if (op != 0) {
            if (mod != 3)
                gen_op_st_T0_A0(ot + s->mem_index);
            else
                gen_op_mov_reg_T0(ot, rm);
            gen_op_update_bt_cc();
            tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
            tcg_gen_movi_tl(cpu_cc_dst, 0);
        }
        break;
    case 0x1bc: /* bsf */