Revision f484d386

b/target-i386/ops_template.h
203 203
/* bit operations */
204 204
#if DATA_BITS >= 16
205 205

  
206
void OPPROTO glue(glue(op_bt, SUFFIX), _T0_T1_cc)(void)
207
{
208
    int count;
209
    count = T1 & SHIFT_MASK;
210
    CC_SRC = T0 >> count;
211
}
212

  
213
void OPPROTO glue(glue(op_bts, SUFFIX), _T0_T1_cc)(void)
214
{
215
    int count;
216
    count = T1 & SHIFT_MASK;
217
    T1 = T0 >> count;
218
    T0 |= (((target_long)1) << count);
219
}
220

  
221
void OPPROTO glue(glue(op_btr, SUFFIX), _T0_T1_cc)(void)
222
{
223
    int count;
224
    count = T1 & SHIFT_MASK;
225
    T1 = T0 >> count;
226
    T0 &= ~(((target_long)1) << count);
227
}
228

  
229
void OPPROTO glue(glue(op_btc, SUFFIX), _T0_T1_cc)(void)
230
{
231
    int count;
232
    count = T1 & SHIFT_MASK;
233
    T1 = T0 >> count;
234
    T0 ^= (((target_long)1) << count);
235
}
236

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

  
242 206
void OPPROTO glue(glue(op_bsf, SUFFIX), _T0_cc)(void)
243 207
{
244 208
    int count;
......
281 245

  
282 246
#endif
283 247

  
284
#if DATA_BITS == 32
285
void OPPROTO op_update_bt_cc(void)
286
{
287
    CC_SRC = T1;
288
}
289
#endif
290

  
291 248
/* string operations */
292 249

  
293 250
void OPPROTO glue(op_movl_T0_Dshift, SUFFIX)(void)
b/target-i386/translate.c
498 498
#endif
499 499
};
500 500

  
501
static GenOpFunc *gen_op_btx_T0_T1_cc[3][4] = {
502
    [0] = {
503
        gen_op_btw_T0_T1_cc,
504
        gen_op_btsw_T0_T1_cc,
505
        gen_op_btrw_T0_T1_cc,
506
        gen_op_btcw_T0_T1_cc,
507
    },
508
    [1] = {
509
        gen_op_btl_T0_T1_cc,
510
        gen_op_btsl_T0_T1_cc,
511
        gen_op_btrl_T0_T1_cc,
512
        gen_op_btcl_T0_T1_cc,
513
    },
514
#ifdef TARGET_X86_64
515
    [2] = {
516
        gen_op_btq_T0_T1_cc,
517
        gen_op_btsq_T0_T1_cc,
518
        gen_op_btrq_T0_T1_cc,
519
        gen_op_btcq_T0_T1_cc,
520
    },
521
#endif
522
};
523

  
524
static GenOpFunc *gen_op_add_bit_A0_T1[3] = {
525
    gen_op_add_bitw_A0_T1,
526
    gen_op_add_bitl_A0_T1,
527
    X86_64_ONLY(gen_op_add_bitq_A0_T1),
528
};
529

  
530 501
static GenOpFunc *gen_op_bsx_T0_cc[3][2] = {
531 502
    [0] = {
532 503
        gen_op_bsfw_T0_cc,
......
1379 1350
    }
1380 1351
}
1381 1352

  
1353
static void gen_exts(int ot, TCGv reg)
1354
{
1355
    switch(ot) {
1356
    case OT_BYTE:
1357
        tcg_gen_ext8s_tl(reg, reg);
1358
        break;
1359
    case OT_WORD:
1360
        tcg_gen_ext16s_tl(reg, reg);
1361
        break;
1362
    case OT_LONG:
1363
        tcg_gen_ext32s_tl(reg, reg);
1364
        break;
1365
    default:
1366
        break;
1367
    }
1368
}
1369

  
1382 1370
/* XXX: add faster immediate case */
1383 1371
static void gen_shift_rm_T1(DisasContext *s, int ot, int op1, 
1384 1372
                            int is_right, int is_arith)
......
1403 1391

  
1404 1392
    if (is_right) {
1405 1393
        if (is_arith) {
1406
            switch(ot) {
1407
            case OT_BYTE:
1408
                tcg_gen_ext8s_tl(cpu_T[0], cpu_T[0]);
1409
                break;
1410
            case OT_WORD:
1411
                tcg_gen_ext16s_tl(cpu_T[0], cpu_T[0]);
1412
                break;
1413
            case OT_LONG:
1414
                tcg_gen_ext32s_tl(cpu_T[0], cpu_T[0]);
1415
                break;
1416
            default:
1417
                break;
1418
            }
1394
            gen_exts(ot, cpu_T[0]);
1419 1395
            tcg_gen_sar_tl(cpu_T3, cpu_T[0], cpu_tmp5);
1420 1396
            tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1421 1397
        } else {
......
5791 5767
        if (op < 4)
5792 5768
            goto illegal_op;
5793 5769
        op -= 4;
5794
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
5795
        s->cc_op = CC_OP_SARB + ot;
5796
        if (op != 0) {
5797
            if (mod != 3)
5798
                gen_op_st_T0_A0(ot + s->mem_index);
5799
            else
5800
                gen_op_mov_reg_T0(ot, rm);
5801
            gen_op_update_bt_cc();
5802
        }
5803
        break;
5770
        goto bt_op;
5804 5771
    case 0x1a3: /* bt Gv, Ev */
5805 5772
        op = 0;
5806 5773
        goto do_btx;
......
5822 5789
        if (mod != 3) {
5823 5790
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
5824 5791
            /* specific case: we need to add a displacement */
5825
            gen_op_add_bit_A0_T1[ot - OT_WORD]();
5792
            gen_exts(ot, cpu_T[1]);
5793
            tcg_gen_sari_tl(cpu_tmp0, cpu_T[1], 3 + ot);
5794
            tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, ot);
5795
            tcg_gen_add_tl(cpu_A0, cpu_A0, cpu_tmp0);
5826 5796
            gen_op_ld_T0_A0(ot + s->mem_index);
5827 5797
        } else {
5828 5798
            gen_op_mov_TN_reg(ot, 0, rm);
5829 5799
        }
5830
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
5800
    bt_op:
5801
        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
5802
        switch(op) {
5803
        case 0:
5804
            tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]);
5805
            tcg_gen_movi_tl(cpu_cc_dst, 0);
5806
            break;
5807
        case 1:
5808
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
5809
            tcg_gen_movi_tl(cpu_tmp0, 1);
5810
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
5811
            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
5812
            break;
5813
        case 2:
5814
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
5815
            tcg_gen_movi_tl(cpu_tmp0, 1);
5816
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
5817
            tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
5818
            tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
5819
            break;
5820
        default:
5821
        case 3:
5822
            tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
5823
            tcg_gen_movi_tl(cpu_tmp0, 1);
5824
            tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
5825
            tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
5826
            break;
5827
        }
5831 5828
        s->cc_op = CC_OP_SARB + ot;
5832 5829
        if (op != 0) {
5833 5830
            if (mod != 3)
5834 5831
                gen_op_st_T0_A0(ot + s->mem_index);
5835 5832
            else
5836 5833
                gen_op_mov_reg_T0(ot, rm);
5837
            gen_op_update_bt_cc();
5834
            tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
5835
            tcg_gen_movi_tl(cpu_cc_dst, 0);
5838 5836
        }
5839 5837
        break;
5840 5838
    case 0x1bc: /* bsf */

Also available in: Unified diff