Revision 4b74fe1f translate-i386.c

b/translate-i386.c
27 27
    va_list ap;
28 28

  
29 29
    va_start(ap, fmt);
30
    fprintf(stderr, "\n");
30 31
    vfprintf(stderr, fmt, ap);
32
    fprintf(stderr, "\n");
31 33
    va_end(ap);
32 34
    exit(1);
33 35
}
......
98 100
    OR_EBP,
99 101
    OR_ESI,
100 102
    OR_EDI,
101

  
102
    /* I386 float registers */
103
    OR_ST0,
104
    OR_ST1,
105
    OR_ST2,
106
    OR_ST3,
107
    OR_ST4,
108
    OR_ST5,
109
    OR_ST6,
110
    OR_ST7,
111 103
    OR_TMP0,    /* temporary operand register */
112 104
    OR_TMP1,
113 105
    OR_A0, /* temporary register used when doing address evaluation */
114
    OR_EFLAGS,  /* cpu flags */
115
    OR_ITMP0, /* used for byte/word insertion */
116
    OR_ITMP1, /* used for byte/word insertion */
117
    OR_ITMP2, /* used for byte/word insertion */
118
    OR_FTMP0, /* float temporary */
119
    OR_DF,    /* D flag, for string ops */
120 106
    OR_ZERO, /* fixed zero register */
121
    OR_IM, /* dummy immediate value register */
122 107
    NB_OREGS,
123 108
};
124 109

  
125
#if 0
126
static const double tab_const[7] = {
127
    1.0, 
128
    3.32192809488736234789, /* log2(10) */
129
    M_LOG2E,
130
    M_PI,
131
    0.30102999566398119521, /* log10(2) */
132
    M_LN2,
133
    0.0
134
};
135
#endif
136

  
137 110
typedef void (GenOpFunc)(void);
138 111
typedef void (GenOpFunc1)(long);
139 112
typedef void (GenOpFunc2)(long, long);
......
354 327
static GenOpFunc *gen_op_arith_T0_T1_cc[8] = {
355 328
    gen_op_addl_T0_T1_cc,
356 329
    gen_op_orl_T0_T1_cc,
357
    gen_op_adcl_T0_T1_cc,
358
    gen_op_sbbl_T0_T1_cc,
330
    NULL,
331
    NULL,
359 332
    gen_op_andl_T0_T1_cc,
360 333
    gen_op_subl_T0_T1_cc,
361 334
    gen_op_xorl_T0_T1_cc,
362 335
    gen_op_cmpl_T0_T1_cc,
363 336
};
364 337

  
338
static GenOpFunc *gen_op_arithc_T0_T1_cc[3][2] = {
339
    [OT_BYTE] = {
340
        gen_op_adcb_T0_T1_cc,
341
        gen_op_sbbb_T0_T1_cc,
342
    },
343
    [OT_WORD] = {
344
        gen_op_adcw_T0_T1_cc,
345
        gen_op_sbbw_T0_T1_cc,
346
    },
347
    [OT_LONG] = {
348
        gen_op_adcl_T0_T1_cc,
349
        gen_op_sbbl_T0_T1_cc,
350
    },
351
};
352

  
365 353
static const int cc_op_arithb[8] = {
366 354
    CC_OP_ADDB,
367 355
    CC_OP_LOGICB,
......
406 394
    },
407 395
};
408 396

  
397
static GenOpFunc *gen_op_btx_T0_T1_cc[2][4] = {
398
    [0] = {
399
        gen_op_btw_T0_T1_cc,
400
        gen_op_btsw_T0_T1_cc,
401
        gen_op_btrw_T0_T1_cc,
402
        gen_op_btcw_T0_T1_cc,
403
    },
404
    [1] = {
405
        gen_op_btl_T0_T1_cc,
406
        gen_op_btsl_T0_T1_cc,
407
        gen_op_btrl_T0_T1_cc,
408
        gen_op_btcl_T0_T1_cc,
409
    },
410
};
411

  
409 412
static GenOpFunc *gen_op_lds_T0_A0[3] = {
410 413
    gen_op_ldsb_T0_A0,
411 414
    gen_op_ldsw_T0_A0,
......
644 647
        gen_op_mov_TN_reg[ot][0][d]();
645 648
    if (s != OR_TMP1)
646 649
        gen_op_mov_TN_reg[ot][1][s]();
647
    if ((op == OP_ADCL || op == OP_SBBL) && s1->cc_op != CC_OP_DYNAMIC)
648
        gen_op_set_cc_op(s1->cc_op);
649
    gen_op_arith_T0_T1_cc[op]();
650
    if (op == OP_ADCL || op == OP_SBBL) {
651
        if (s1->cc_op != CC_OP_DYNAMIC)
652
            gen_op_set_cc_op(s1->cc_op);
653
        gen_op_arithc_T0_T1_cc[ot][op - OP_ADCL]();
654
        s1->cc_op = CC_OP_DYNAMIC;
655
    } else {
656
        gen_op_arith_T0_T1_cc[op]();
657
        s1->cc_op = cc_op_arithb[op] + ot;
658
    }
650 659
    if (d != OR_TMP0 && op != OP_CMPL)
651 660
        gen_op_mov_reg_T0[ot][d]();
652
    s1->cc_op = cc_op_arithb[op] + ot;
653 661
}
654 662

  
655 663
static void gen_opi(DisasContext *s1, int op, int ot, int d, int c)
656 664
{
657 665
    gen_op_movl_T1_im(c);
658
    gen_op(s1, op, ot, d, OR_TMP0);
666
    gen_op(s1, op, ot, d, OR_TMP1);
659 667
}
660 668

  
661 669
static void gen_inc(DisasContext *s1, int ot, int d, int c)
......
664 672
        gen_op_mov_TN_reg[ot][0][d]();
665 673
    if (s1->cc_op != CC_OP_DYNAMIC)
666 674
        gen_op_set_cc_op(s1->cc_op);
667
    if (c > 0)
675
    if (c > 0) {
668 676
        gen_op_incl_T0_cc();
669
    else
677
        s1->cc_op = CC_OP_INCB + ot;
678
    } else {
670 679
        gen_op_decl_T0_cc();
680
        s1->cc_op = CC_OP_DECB + ot;
681
    }
671 682
    if (d != OR_TMP0)
672 683
        gen_op_mov_reg_T0[ot][d]();
673 684
}
......
678 689
        gen_op_mov_TN_reg[ot][0][d]();
679 690
    if (s != OR_TMP1)
680 691
        gen_op_mov_TN_reg[ot][1][s]();
681
    switch(op) {
682
    case OP_ROL:
683
    case OP_ROR:
684
    case OP_RCL:
685
    case OP_RCR:
686
        /* only C and O are modified, so we must update flags dynamically */
687
        if (s1->cc_op != CC_OP_DYNAMIC)
688
            gen_op_set_cc_op(s1->cc_op);
689
        gen_op_shift_T0_T1_cc[ot][op]();
690
        break;
691
    default:
692
        gen_op_shift_T0_T1_cc[ot][op]();
693
        break;
694
    }
692
    /* for zero counts, flags are not updated, so must do it dynamically */
693
    if (s1->cc_op != CC_OP_DYNAMIC)
694
        gen_op_set_cc_op(s1->cc_op);
695

  
696
    gen_op_shift_T0_T1_cc[ot][op]();
697

  
695 698
    if (d != OR_TMP0)
696 699
        gen_op_mov_reg_T0[ot][d]();
697 700
    s1->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
......
785 788
            }
786 789
            gen_op_addl_A0_reg_sN[scale][reg2]();
787 790
        }
788
        opreg = OR_A0;
789 791
    } else {
790
        fprintf(stderr, "16 bit addressing not supported\n");
791
        disp = 0;
792
        opreg = 0;
792
        switch (mod) {
793
        case 0:
794
            if (rm == 6) {
795
                disp = lduw(s->pc);
796
                s->pc += 2;
797
                gen_op_movl_A0_im(disp);
798
                goto no_rm;
799
            } else {
800
                disp = 0;
801
            }
802
            break;
803
        case 1:
804
            disp = (int8_t)ldub(s->pc++);
805
            break;
806
        default:
807
        case 2:
808
            disp = lduw(s->pc);
809
            s->pc += 2;
810
            break;
811
        }
812
        switch(rm) {
813
        case 0:
814
            gen_op_movl_A0_reg[R_EBX]();
815
            gen_op_addl_A0_reg_sN[0][R_ESI]();
816
            break;
817
        case 1:
818
            gen_op_movl_A0_reg[R_EBX]();
819
            gen_op_addl_A0_reg_sN[0][R_EDI]();
820
            break;
821
        case 2:
822
            gen_op_movl_A0_reg[R_EBP]();
823
            gen_op_addl_A0_reg_sN[0][R_ESI]();
824
            break;
825
        case 3:
826
            gen_op_movl_A0_reg[R_EBP]();
827
            gen_op_addl_A0_reg_sN[0][R_EDI]();
828
            break;
829
        case 4:
830
            gen_op_movl_A0_reg[R_ESI]();
831
            break;
832
        case 5:
833
            gen_op_movl_A0_reg[R_EDI]();
834
            break;
835
        case 6:
836
            gen_op_movl_A0_reg[R_EBP]();
837
            break;
838
        default:
839
        case 7:
840
            gen_op_movl_A0_reg[R_EBX]();
841
            break;
842
        }
843
        if (disp != 0)
844
            gen_op_addl_A0_im(disp);
845
        gen_op_andl_A0_ffff();
846
    no_rm: ;
793 847
    }
848
    opreg = OR_A0;
849
    disp = 0;
794 850
    *reg_ptr = opreg;
795 851
    *offset_ptr = disp;
796 852
}
......
870 926
    case CC_OP_ADDB:
871 927
    case CC_OP_ADDW:
872 928
    case CC_OP_ADDL:
929
    case CC_OP_ADCB:
930
    case CC_OP_ADCW:
931
    case CC_OP_ADCL:
932
    case CC_OP_SBBB:
933
    case CC_OP_SBBW:
934
    case CC_OP_SBBL:
873 935
    case CC_OP_LOGICB:
874 936
    case CC_OP_LOGICW:
875 937
    case CC_OP_LOGICL:
......
882 944
    case CC_OP_SHLB:
883 945
    case CC_OP_SHLW:
884 946
    case CC_OP_SHLL:
947
    case CC_OP_SARB:
948
    case CC_OP_SARW:
949
    case CC_OP_SARL:
885 950
        switch(jcc_op) {
886 951
        case JCC_Z:
887 952
            func = gen_jcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
......
1284 1349
            gen_inc(s, ot, OR_TMP0, 1);
1285 1350
            if (mod != 3)
1286 1351
                gen_op_st_T0_A0[ot]();
1352
            else
1353
                gen_op_mov_reg_T0[ot][rm]();
1287 1354
            break;
1288 1355
        case 1: /* dec Ev */
1289 1356
            gen_inc(s, ot, OR_TMP0, -1);
1290 1357
            if (mod != 3)
1291 1358
                gen_op_st_T0_A0[ot]();
1359
            else
1360
                gen_op_mov_reg_T0[ot][rm]();
1292 1361
            break;
1293 1362
        case 2: /* call Ev */
1294 1363
            gen_op_movl_T1_im((long)s->pc);
......
1359 1428
        ot = dflag ? OT_LONG : OT_WORD;
1360 1429
        modrm = ldub(s->pc++);
1361 1430
        reg = ((modrm >> 3) & 7) + OR_EAX;
1362
        
1363 1431
        gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);
1364 1432
        if (b == 0x69) {
1365 1433
            val = insn_get(s, ot);
......
1372 1440
        }
1373 1441

  
1374 1442
        if (ot == OT_LONG) {
1375
            op_imull_T0_T1();
1443
            gen_op_imull_T0_T1();
1376 1444
        } else {
1377
            op_imulw_T0_T1();
1445
            gen_op_imulw_T0_T1();
1378 1446
        }
1379 1447
        gen_op_mov_reg_T0[ot][reg]();
1380 1448
        s->cc_op = CC_OP_MUL;
......
1522 1590
            offset_addr = insn_get(s, OT_LONG);
1523 1591
        else
1524 1592
            offset_addr = insn_get(s, OT_WORD);
1525
            
1593
        gen_op_movl_A0_im(offset_addr);
1526 1594
        if ((b & 2) == 0) {
1527 1595
            gen_op_ld_T0_A0[ot]();
1528 1596
            gen_op_mov_reg_T0[ot][R_EAX]();
......
1717 1785
                    break;
1718 1786
                }
1719 1787
                break;
1720
#if 0
1788
            case 0x0d: /* fldcw mem */
1789
                gen_op_fldcw_A0();
1790
                break;
1791
            case 0x0f: /* fnstcw mem */
1792
                gen_op_fnstcw_A0();
1793
                break;
1721 1794
            case 0x2f: /* fnstsw mem */
1722
                gen_insn3(OP_FNSTS, OR_TMP0, OR_ZERO, OR_ZERO);
1723
                gen_st(OP_STW, OR_TMP0, reg_addr, offset_addr);
1795
                gen_op_fnstsw_A0();
1724 1796
                break;
1725

  
1726 1797
            case 0x3c: /* fbld */
1727 1798
            case 0x3e: /* fbstp */
1728 1799
                error("float BCD not hanlded");
1729 1800
                return -1;
1730
#endif
1731 1801
            case 0x3d: /* fildll */
1732 1802
                gen_op_fpush();
1733 1803
                gen_op_fildll_ST0_A0();
......
1737 1807
                gen_op_fpop();
1738 1808
                break;
1739 1809
            default:
1740
                error("unhandled memory FP\n");
1810
                error("unhandled memory FP [op=0x%02x]\n", op);
1741 1811
                return -1;
1742 1812
            }
1743 1813
        } else {
......
1987 2057
        else
1988 2058
            ot = dflag ? OT_LONG : OT_WORD;
1989 2059
        if (prefixes & PREFIX_REPNZ) {
2060
            if (s->cc_op != CC_OP_DYNAMIC)
2061
                gen_op_set_cc_op(s->cc_op);
1990 2062
            gen_op_scas[6 + ot]();
2063
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1991 2064
        } else if (prefixes & PREFIX_REPZ) {
2065
            if (s->cc_op != CC_OP_DYNAMIC)
2066
                gen_op_set_cc_op(s->cc_op);
1992 2067
            gen_op_scas[3 + ot]();
2068
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
1993 2069
        } else {
1994 2070
            gen_op_scas[ot]();
2071
            s->cc_op = CC_OP_SUBB + ot;
1995 2072
        }
1996 2073
        break;
1997 2074

  
......
2002 2079
        else
2003 2080
            ot = dflag ? OT_LONG : OT_WORD;
2004 2081
        if (prefixes & PREFIX_REPNZ) {
2082
            if (s->cc_op != CC_OP_DYNAMIC)
2083
                gen_op_set_cc_op(s->cc_op);
2005 2084
            gen_op_cmps[6 + ot]();
2085
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2006 2086
        } else if (prefixes & PREFIX_REPZ) {
2087
            if (s->cc_op != CC_OP_DYNAMIC)
2088
                gen_op_set_cc_op(s->cc_op);
2007 2089
            gen_op_cmps[3 + ot]();
2090
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2008 2091
        } else {
2009 2092
            gen_op_cmps[ot]();
2093
            s->cc_op = CC_OP_SUBB + ot;
2010 2094
        }
2011 2095
        break;
2012 2096
        
......
2187 2271
        break;
2188 2272

  
2189 2273
        /************************/
2274
        /* bit operations */
2275
    case 0x1ba: /* bt/bts/btr/btc Gv, im */
2276
        ot = dflag ? OT_LONG : OT_WORD;
2277
        modrm = ldub(s->pc++);
2278
        op = (modrm >> 3) & 7;
2279
        mod = (modrm >> 6) & 3;
2280
        rm = modrm & 7;
2281
        if (mod != 3) {
2282
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2283
            gen_op_ld_T0_A0[ot]();
2284
        } else {
2285
            gen_op_mov_TN_reg[ot][0][rm]();
2286
        }
2287
        /* load shift */
2288
        val = ldub(s->pc++);
2289
        gen_op_movl_T1_im(val);
2290
        if (op < 4)
2291
            return -1;
2292
        op -= 4;
2293
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2294
        s->cc_op = CC_OP_SHLB + ot;
2295
        if (op != 0) {
2296
            if (mod != 3)
2297
                gen_op_st_T0_A0[ot]();
2298
            else
2299
                gen_op_mov_reg_T0[ot][rm]();
2300
        }
2301
        break;
2302
    case 0x1a3: /* bt Gv, Ev */
2303
        op = 0;
2304
        goto do_btx;
2305
    case 0x1ab: /* bts */
2306
        op = 1;
2307
        goto do_btx;
2308
    case 0x1b3: /* btr */
2309
        op = 2;
2310
        goto do_btx;
2311
    case 0x1bb: /* btc */
2312
        op = 3;
2313
    do_btx:
2314
        ot = dflag ? OT_LONG : OT_WORD;
2315
        modrm = ldub(s->pc++);
2316
        reg = (modrm >> 3) & 7;
2317
        mod = (modrm >> 6) & 3;
2318
        rm = modrm & 7;
2319
        gen_op_mov_TN_reg[OT_LONG][1][reg]();
2320
        if (mod != 3) {
2321
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2322
            /* specific case: we need to add a displacement */
2323
            if (ot == OT_WORD)
2324
                gen_op_add_bitw_A0_T1();
2325
            else
2326
                gen_op_add_bitl_A0_T1();
2327
            gen_op_ld_T0_A0[ot]();
2328
        } else {
2329
            gen_op_mov_TN_reg[ot][0][rm]();
2330
        }
2331
        gen_op_btx_T0_T1_cc[ot - OT_WORD][op]();
2332
        s->cc_op = CC_OP_SHLB + ot;
2333
        if (op != 0) {
2334
            if (mod != 3)
2335
                gen_op_st_T0_A0[ot]();
2336
            else
2337
                gen_op_mov_reg_T0[ot][rm]();
2338
        }
2339
        break;
2340

  
2341
        /************************/
2190 2342
        /* misc */
2191 2343
    case 0x90: /* nop */
2192 2344
        break;
......
2206 2358
        gen_op_into((long)pc_start, (long)s->pc);
2207 2359
        *is_jmp_ptr = 1;
2208 2360
        break;
2361
    case 0x1c8 ... 0x1cf: /* bswap reg */
2362
      reg = b & 7;
2363
      gen_op_mov_TN_reg[OT_LONG][0][reg]();
2364
      gen_op_bswapl_T0();
2365
      gen_op_mov_reg_T0[OT_LONG][reg]();
2366
      break;
2367
      
2209 2368
#if 0
2210 2369
    case 0x1a2: /* cpuid */
2211 2370
        gen_insn0(OP_ASM);

Also available in: Unified diff