Revision 9c605cb1 translate-i386.c

b/translate-i386.c
76 76
extern FILE *logfile;
77 77
extern int loglevel;
78 78

  
79
#define PREFIX_REPZ 1
80
#define PREFIX_REPNZ 2
81
#define PREFIX_LOCK 4
82
#define PREFIX_CS 8
83
#define PREFIX_SS 0x10
84
#define PREFIX_DS 0x20
85
#define PREFIX_ES 0x40
86
#define PREFIX_FS 0x80
87
#define PREFIX_GS 0x100
88
#define PREFIX_DATA 0x200
89
#define PREFIX_ADR 0x400
90
#define PREFIX_FWAIT 0x800
79
#define PREFIX_REPZ   0x01
80
#define PREFIX_REPNZ  0x02
81
#define PREFIX_LOCK   0x04
82
#define PREFIX_DATA   0x08
83
#define PREFIX_ADR    0x10
84
#define PREFIX_FWAIT  0x20
91 85

  
92 86
typedef struct DisasContext {
93 87
    /* current insn context */
88
    int override; /* -1 if no override */
94 89
    int prefix;
95 90
    int aflag, dflag;
96 91
    uint8_t *pc; /* pc = eip + cs_base */
......
103 98
    int cc_op;  /* current CC operation */
104 99
    int addseg; /* non zero if either DS/ES/SS have a non zero base */
105 100
    int f_st;   /* currently unused */
101
    int vm86;   /* vm86 mode */
106 102
} DisasContext;
107 103

  
108 104
/* i386 arith/logic operations */
......
130 126
};
131 127

  
132 128
enum {
133
#define DEF(s) INDEX_op_ ## s,
129
#define DEF(s, n) INDEX_op_ ## s,
134 130
#include "opc-i386.h"
135 131
#undef DEF
136 132
    NB_OPS,
......
556 552
    gen_op_stl_T0_A0,
557 553
};
558 554

  
559
static GenOpFunc *gen_op_movs[6] = {
560
    gen_op_movsb,
561
    gen_op_movsw,
562
    gen_op_movsl,
563
    gen_op_rep_movsb,
564
    gen_op_rep_movsw,
565
    gen_op_rep_movsl,
555
/* the _a32 and _a16 string operations use A0 as the base register. */
556

  
557
#define STRINGOP(x) \
558
    gen_op_ ## x ## b_fast, \
559
    gen_op_ ## x ## w_fast, \
560
    gen_op_ ## x ## l_fast, \
561
    gen_op_ ## x ## b_a32, \
562
    gen_op_ ## x ## w_a32, \
563
    gen_op_ ## x ## l_a32, \
564
    gen_op_ ## x ## b_a16, \
565
    gen_op_ ## x ## w_a16, \
566
    gen_op_ ## x ## l_a16,
567
     
568
static GenOpFunc *gen_op_movs[9 * 2] = {
569
    STRINGOP(movs)
570
    STRINGOP(rep_movs)
566 571
};
567 572

  
568
static GenOpFunc *gen_op_stos[6] = {
569
    gen_op_stosb,
570
    gen_op_stosw,
571
    gen_op_stosl,
572
    gen_op_rep_stosb,
573
    gen_op_rep_stosw,
574
    gen_op_rep_stosl,
573
static GenOpFunc *gen_op_stos[9 * 2] = {
574
    STRINGOP(stos)
575
    STRINGOP(rep_stos)
575 576
};
576 577

  
577
static GenOpFunc *gen_op_lods[6] = {
578
    gen_op_lodsb,
579
    gen_op_lodsw,
580
    gen_op_lodsl,
581
    gen_op_rep_lodsb,
582
    gen_op_rep_lodsw,
583
    gen_op_rep_lodsl,
578
static GenOpFunc *gen_op_lods[9 * 2] = {
579
    STRINGOP(lods)
580
    STRINGOP(rep_lods)
584 581
};
585 582

  
586
static GenOpFunc *gen_op_scas[9] = {
587
    gen_op_scasb,
588
    gen_op_scasw,
589
    gen_op_scasl,
590
    gen_op_repz_scasb,
591
    gen_op_repz_scasw,
592
    gen_op_repz_scasl,
593
    gen_op_repnz_scasb,
594
    gen_op_repnz_scasw,
595
    gen_op_repnz_scasl,
583
static GenOpFunc *gen_op_scas[9 * 3] = {
584
    STRINGOP(scas)
585
    STRINGOP(repz_scas)
586
    STRINGOP(repnz_scas)
596 587
};
597 588

  
598
static GenOpFunc *gen_op_cmps[9] = {
599
    gen_op_cmpsb,
600
    gen_op_cmpsw,
601
    gen_op_cmpsl,
602
    gen_op_repz_cmpsb,
603
    gen_op_repz_cmpsw,
604
    gen_op_repz_cmpsl,
605
    gen_op_repnz_cmpsb,
606
    gen_op_repnz_cmpsw,
607
    gen_op_repnz_cmpsl,
589
static GenOpFunc *gen_op_cmps[9 * 3] = {
590
    STRINGOP(cmps)
591
    STRINGOP(repz_cmps)
592
    STRINGOP(repnz_cmps)
608 593
};
609 594

  
610
static GenOpFunc *gen_op_ins[6] = {
611
    gen_op_insb,
612
    gen_op_insw,
613
    gen_op_insl,
614
    gen_op_rep_insb,
615
    gen_op_rep_insw,
616
    gen_op_rep_insl,
595
static GenOpFunc *gen_op_ins[9 * 2] = {
596
    STRINGOP(ins)
597
    STRINGOP(rep_ins)
617 598
};
618 599

  
619 600

  
620
static GenOpFunc *gen_op_outs[6] = {
621
    gen_op_outsb,
622
    gen_op_outsw,
623
    gen_op_outsl,
624
    gen_op_rep_outsb,
625
    gen_op_rep_outsw,
626
    gen_op_rep_outsl,
601
static GenOpFunc *gen_op_outs[9 * 2] = {
602
    STRINGOP(outs)
603
    STRINGOP(rep_outs)
627 604
};
628 605

  
606

  
607
static inline void gen_string_ds(DisasContext *s, int ot, GenOpFunc **func)
608
{
609
    int index, override;
610

  
611
    override = s->override;
612
    if (s->aflag) {
613
        /* 32 bit address */
614
        if (s->addseg && override < 0)
615
            override = R_DS;
616
        if (override >= 0) {
617
            gen_op_movl_A0_seg(offsetof(CPUX86State,seg_cache[override].base));
618
            index = 3 + ot;
619
        } else {
620
            index = ot;
621
        }
622
    } else {
623
        if (override < 0)
624
            override = R_DS;
625
        gen_op_movl_A0_seg(offsetof(CPUX86State,seg_cache[override].base));
626
        /* 16 address, always override */
627
        index = 6 + ot;
628
    }
629
    func[index]();
630
}
631

  
632
static inline void gen_string_es(DisasContext *s, int ot, GenOpFunc **func)
633
{
634
    int index;
635
            
636
    if (s->aflag) {
637
        if (s->addseg) {
638
            index = 3 + ot;
639
        } else {
640
            index = ot;
641
        }
642
    } else {
643
        index = 6 + ot;
644
    }
645
    func[index]();
646
}
647

  
648

  
629 649
static GenOpFunc *gen_op_in[3] = {
630 650
    gen_op_inb_T0_T1,
631 651
    gen_op_inw_T0_T1,
......
849 869
    int opreg;
850 870
    int mod, rm, code, override, must_add_seg;
851 871

  
852
    /* XXX: add a generation time variable to tell if base == 0 in DS/ES/SS */
853
    override = -1;
872
    override = s->override;
854 873
    must_add_seg = s->addseg;
855
    if (s->prefix & (PREFIX_CS | PREFIX_SS | PREFIX_DS | 
856
                     PREFIX_ES | PREFIX_FS | PREFIX_GS)) {
857
        if (s->prefix & PREFIX_ES)
858
            override = R_ES;
859
        else if (s->prefix & PREFIX_CS)
860
            override = R_CS;
861
        else if (s->prefix & PREFIX_SS)
862
            override = R_SS;
863
        else if (s->prefix & PREFIX_DS)
864
            override = R_DS;
865
        else if (s->prefix & PREFIX_FS)
866
            override = R_FS;
867
        else
868
            override = R_GS;
874
    if (override >= 0)
869 875
        must_add_seg = 1;
870
    }
871

  
872 876
    mod = (modrm >> 6) & 3;
873 877
    rm = modrm & 7;
874 878

  
......
1343 1347
    prefixes = 0;
1344 1348
    aflag = s->code32;
1345 1349
    dflag = s->code32;
1346
    //    cur_pc = s->pc; /* for insn generation */
1350
    s->override = -1;
1347 1351
 next_byte:
1348 1352
    b = ldub(s->pc);
1349 1353
    s->pc++;
......
1359 1363
        prefixes |= PREFIX_LOCK;
1360 1364
        goto next_byte;
1361 1365
    case 0x2e:
1362
        prefixes |= PREFIX_CS;
1366
        s->override = R_CS;
1363 1367
        goto next_byte;
1364 1368
    case 0x36:
1365
        prefixes |= PREFIX_SS;
1369
        s->override = R_SS;
1366 1370
        goto next_byte;
1367 1371
    case 0x3e:
1368
        prefixes |= PREFIX_DS;
1372
        s->override = R_DS;
1369 1373
        goto next_byte;
1370 1374
    case 0x26:
1371
        prefixes |= PREFIX_ES;
1375
        s->override = R_ES;
1372 1376
        goto next_byte;
1373 1377
    case 0x64:
1374
        prefixes |= PREFIX_FS;
1378
        s->override = R_FS;
1375 1379
        goto next_byte;
1376 1380
    case 0x65:
1377
        prefixes |= PREFIX_GS;
1381
        s->override = R_GS;
1378 1382
        goto next_byte;
1379 1383
    case 0x66:
1380 1384
        prefixes |= PREFIX_DATA;
......
1830 1834
        }
1831 1835
        s->cc_op = CC_OP_SUBB + ot;
1832 1836
        break;
1837
    case 0x1c7: /* cmpxchg8b */
1838
        modrm = ldub(s->pc++);
1839
        mod = (modrm >> 6) & 3;
1840
        if (mod == 3)
1841
            goto illegal_op;
1842
        if (s->cc_op != CC_OP_DYNAMIC)
1843
            gen_op_set_cc_op(s->cc_op);
1844
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1845
        gen_op_cmpxchg8b();
1846
        s->cc_op = CC_OP_EFLAGS;
1847
        break;
1833 1848
        
1834 1849
        /**************************/
1835 1850
        /* push/pop */
......
2027 2042
        modrm = ldub(s->pc++);
2028 2043
        reg = (modrm >> 3) & 7;
2029 2044
        /* we must ensure that no segment is added */
2030
        s->prefix &= ~(PREFIX_CS | PREFIX_SS | PREFIX_DS | 
2031
                       PREFIX_ES | PREFIX_FS | PREFIX_GS);
2045
        s->override = -1;
2032 2046
        val = s->addseg;
2033 2047
        s->addseg = 0;
2034 2048
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
......
2050 2064
            offset_addr = insn_get(s, OT_WORD);
2051 2065
        gen_op_movl_A0_im(offset_addr);
2052 2066
        /* handle override */
2053
        /* XXX: factorize that */
2054 2067
        {
2055 2068
            int override, must_add_seg;
2056
            override = R_DS;
2057 2069
            must_add_seg = s->addseg;
2058
            if (s->prefix & (PREFIX_CS | PREFIX_SS | PREFIX_DS | 
2059
                             PREFIX_ES | PREFIX_FS | PREFIX_GS)) {
2060
                if (s->prefix & PREFIX_ES)
2061
                    override = R_ES;
2062
                else if (s->prefix & PREFIX_CS)
2063
                    override = R_CS;
2064
                else if (s->prefix & PREFIX_SS)
2065
                    override = R_SS;
2066
                else if (s->prefix & PREFIX_DS)
2067
                    override = R_DS;
2068
                else if (s->prefix & PREFIX_FS)
2069
                    override = R_FS;
2070
                else
2071
                    override = R_GS;
2070
            if (s->override >= 0) {
2071
                override = s->override;
2072 2072
                must_add_seg = 1;
2073
            } else {
2074
                override = R_DS;
2073 2075
            }
2074 2076
            if (must_add_seg) {
2075 2077
                gen_op_addl_A0_seg(offsetof(CPUX86State,seg_cache[override].base));
......
2084 2086
        }
2085 2087
        break;
2086 2088
    case 0xd7: /* xlat */
2087
        /* handle override */
2088 2089
        gen_op_movl_A0_reg[R_EBX]();
2089 2090
        gen_op_addl_A0_AL();
2090 2091
        if (s->aflag == 0)
2091 2092
            gen_op_andl_A0_ffff();
2092
        /* XXX: factorize that */
2093
        /* handle override */
2093 2094
        {
2094 2095
            int override, must_add_seg;
2095
            override = R_DS;
2096 2096
            must_add_seg = s->addseg;
2097
            if (s->prefix & (PREFIX_CS | PREFIX_SS | PREFIX_DS | 
2098
                             PREFIX_ES | PREFIX_FS | PREFIX_GS)) {
2099
                if (s->prefix & PREFIX_ES)
2100
                    override = R_ES;
2101
                else if (s->prefix & PREFIX_CS)
2102
                    override = R_CS;
2103
                else if (s->prefix & PREFIX_SS)
2104
                    override = R_SS;
2105
                else if (s->prefix & PREFIX_DS)
2106
                    override = R_DS;
2107
                else if (s->prefix & PREFIX_FS)
2108
                    override = R_FS;
2109
                else
2110
                    override = R_GS;
2097
            override = R_DS;
2098
            if (s->override >= 0) {
2099
                override = s->override;
2111 2100
                must_add_seg = 1;
2101
            } else {
2102
                override = R_DS;
2112 2103
            }
2113 2104
            if (must_add_seg) {
2114 2105
                gen_op_addl_A0_seg(offsetof(CPUX86State,seg_cache[override].base));
......
2185 2176
        mod = (modrm >> 6) & 3;
2186 2177
        if (mod == 3)
2187 2178
            goto illegal_op;
2179
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2188 2180
        gen_op_ld_T1_A0[ot]();
2189 2181
        gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
2190 2182
        /* load the segment first to handle exceptions properly */
......
2658 2650
        break;
2659 2651
        /************************/
2660 2652
        /* string ops */
2653

  
2661 2654
    case 0xa4: /* movsS */
2662 2655
    case 0xa5:
2663 2656
        if ((b & 1) == 0)
2664 2657
            ot = OT_BYTE;
2665 2658
        else
2666 2659
            ot = dflag ? OT_LONG : OT_WORD;
2660

  
2667 2661
        if (prefixes & PREFIX_REPZ) {
2668
            gen_op_movs[3 + ot]();
2662
            gen_string_ds(s, ot, gen_op_movs + 9);
2669 2663
        } else {
2670
            gen_op_movs[ot]();
2664
            gen_string_ds(s, ot, gen_op_movs);
2671 2665
        }
2672 2666
        break;
2673 2667
        
......
2677 2671
            ot = OT_BYTE;
2678 2672
        else
2679 2673
            ot = dflag ? OT_LONG : OT_WORD;
2674

  
2680 2675
        if (prefixes & PREFIX_REPZ) {
2681
            gen_op_stos[3 + ot]();
2676
            gen_string_es(s, ot, gen_op_stos + 9);
2682 2677
        } else {
2683
            gen_op_stos[ot]();
2678
            gen_string_es(s, ot, gen_op_stos);
2684 2679
        }
2685 2680
        break;
2686 2681
    case 0xac: /* lodsS */
......
2690 2685
        else
2691 2686
            ot = dflag ? OT_LONG : OT_WORD;
2692 2687
        if (prefixes & PREFIX_REPZ) {
2693
            gen_op_lods[3 + ot]();
2688
            gen_string_ds(s, ot, gen_op_lods + 9);
2694 2689
        } else {
2695
            gen_op_lods[ot]();
2690
            gen_string_ds(s, ot, gen_op_lods);
2696 2691
        }
2697 2692
        break;
2698 2693
    case 0xae: /* scasS */
......
2700 2695
        if ((b & 1) == 0)
2701 2696
            ot = OT_BYTE;
2702 2697
        else
2703
            ot = dflag ? OT_LONG : OT_WORD;
2698
                ot = dflag ? OT_LONG : OT_WORD;
2704 2699
        if (prefixes & PREFIX_REPNZ) {
2705 2700
            if (s->cc_op != CC_OP_DYNAMIC)
2706 2701
                gen_op_set_cc_op(s->cc_op);
2707
            gen_op_scas[6 + ot]();
2702
            gen_string_es(s, ot, gen_op_scas + 9 * 2);
2708 2703
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2709 2704
        } else if (prefixes & PREFIX_REPZ) {
2710 2705
            if (s->cc_op != CC_OP_DYNAMIC)
2711 2706
                gen_op_set_cc_op(s->cc_op);
2712
            gen_op_scas[3 + ot]();
2707
            gen_string_es(s, ot, gen_op_scas + 9);
2713 2708
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2714 2709
        } else {
2715
            gen_op_scas[ot]();
2710
            gen_string_es(s, ot, gen_op_scas);
2716 2711
            s->cc_op = CC_OP_SUBB + ot;
2717 2712
        }
2718 2713
        break;
......
2726 2721
        if (prefixes & PREFIX_REPNZ) {
2727 2722
            if (s->cc_op != CC_OP_DYNAMIC)
2728 2723
                gen_op_set_cc_op(s->cc_op);
2729
            gen_op_cmps[6 + ot]();
2724
            gen_string_ds(s, ot, gen_op_cmps + 9 * 2);
2730 2725
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2731 2726
        } else if (prefixes & PREFIX_REPZ) {
2732 2727
            if (s->cc_op != CC_OP_DYNAMIC)
2733 2728
                gen_op_set_cc_op(s->cc_op);
2734
            gen_op_cmps[3 + ot]();
2729
            gen_string_ds(s, ot, gen_op_cmps + 9);
2735 2730
            s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2736 2731
        } else {
2737
            gen_op_cmps[ot]();
2732
            gen_string_ds(s, ot, gen_op_cmps);
2738 2733
            s->cc_op = CC_OP_SUBB + ot;
2739 2734
        }
2740 2735
        break;
2741
        
2742
        /************************/
2743
        /* port I/O */
2744 2736
    case 0x6c: /* insS */
2745 2737
    case 0x6d:
2746 2738
        if ((b & 1) == 0)
......
2748 2740
        else
2749 2741
            ot = dflag ? OT_LONG : OT_WORD;
2750 2742
        if (prefixes & PREFIX_REPZ) {
2751
            gen_op_ins[3 + ot]();
2743
            gen_string_es(s, ot, gen_op_ins + 9);
2752 2744
        } else {
2753
            gen_op_ins[ot]();
2745
            gen_string_es(s, ot, gen_op_ins);
2754 2746
        }
2755 2747
        break;
2756 2748
    case 0x6e: /* outsS */
......
2760 2752
        else
2761 2753
            ot = dflag ? OT_LONG : OT_WORD;
2762 2754
        if (prefixes & PREFIX_REPZ) {
2763
            gen_op_outs[3 + ot]();
2755
            gen_string_ds(s, ot, gen_op_outs + 9);
2764 2756
        } else {
2765
            gen_op_outs[ot]();
2757
            gen_string_ds(s, ot, gen_op_outs);
2766 2758
        }
2767 2759
        break;
2760

  
2761
        /************************/
2762
        /* port I/O */
2768 2763
    case 0xe4:
2769 2764
    case 0xe5:
2770 2765
        if ((b & 1) == 0)
......
3150 3145
    case 0xcd: /* int N */
3151 3146
        val = ldub(s->pc++);
3152 3147
        /* XXX: currently we ignore the interrupt number */
3153
        gen_op_int_im((long)pc_start);
3148
        gen_op_int_im(pc_start - s->cs_base);
3154 3149
        s->is_jmp = 1;
3155 3150
        break;
3156 3151
    case 0xce: /* into */
3157 3152
        if (s->cc_op != CC_OP_DYNAMIC)
3158 3153
            gen_op_set_cc_op(s->cc_op);
3159
        gen_op_into((long)pc_start, (long)s->pc);
3160
        s->is_jmp = 1;
3154
        gen_op_into();
3155
        break;
3156
    case 0x62: /* bound */
3157
        ot = dflag ? OT_LONG : OT_WORD;
3158
        modrm = ldub(s->pc++);
3159
        reg = (modrm >> 3) & 7;
3160
        mod = (modrm >> 6) & 3;
3161
        if (mod == 3)
3162
            goto illegal_op;
3163
        gen_op_mov_reg_T0[ot][reg]();
3164
        gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3165
        if (ot == OT_WORD)
3166
            gen_op_boundw();
3167
        else
3168
            gen_op_boundl();
3161 3169
        break;
3162 3170
    case 0x1c8 ... 0x1cf: /* bswap reg */
3163 3171
        reg = b & 7;
......
3188 3196
    case 0x131: /* rdtsc */
3189 3197
        gen_op_rdtsc();
3190 3198
        break;
3191
#if 0
3192 3199
    case 0x1a2: /* cpuid */
3193
        gen_insn0(OP_ASM);
3200
        gen_op_cpuid();
3194 3201
        break;
3195
#endif
3196 3202
    default:
3197 3203
        goto illegal_op;
3198 3204
    }
......
3399 3405
    [INDEX_op_bsrw_T0_cc] = CC_OSZAPC,
3400 3406
    [INDEX_op_bsrl_T0_cc] = CC_OSZAPC,
3401 3407

  
3402
    [INDEX_op_scasb] = CC_OSZAPC,
3403
    [INDEX_op_scasw] = CC_OSZAPC,
3404
    [INDEX_op_scasl] = CC_OSZAPC,
3405
    [INDEX_op_repz_scasb] = CC_OSZAPC,
3406
    [INDEX_op_repz_scasw] = CC_OSZAPC,
3407
    [INDEX_op_repz_scasl] = CC_OSZAPC,
3408
    [INDEX_op_repnz_scasb] = CC_OSZAPC,
3409
    [INDEX_op_repnz_scasw] = CC_OSZAPC,
3410
    [INDEX_op_repnz_scasl] = CC_OSZAPC,
3411

  
3412
    [INDEX_op_cmpsb] = CC_OSZAPC,
3413
    [INDEX_op_cmpsw] = CC_OSZAPC,
3414
    [INDEX_op_cmpsl] = CC_OSZAPC,
3415
    [INDEX_op_repz_cmpsb] = CC_OSZAPC,
3416
    [INDEX_op_repz_cmpsw] = CC_OSZAPC,
3417
    [INDEX_op_repz_cmpsl] = CC_OSZAPC,
3418
    [INDEX_op_repnz_cmpsb] = CC_OSZAPC,
3419
    [INDEX_op_repnz_cmpsw] = CC_OSZAPC,
3420
    [INDEX_op_repnz_cmpsl] = CC_OSZAPC,
3421

  
3408
#undef STRINGOP
3409
#define STRINGOP(x) \
3410
    [INDEX_op_ ## x ## b_fast] = CC_OSZAPC, \
3411
    [INDEX_op_ ## x ## w_fast] = CC_OSZAPC, \
3412
    [INDEX_op_ ## x ## l_fast] = CC_OSZAPC, \
3413
    [INDEX_op_ ## x ## b_a32] = CC_OSZAPC, \
3414
    [INDEX_op_ ## x ## w_a32] = CC_OSZAPC, \
3415
    [INDEX_op_ ## x ## l_a32] = CC_OSZAPC, \
3416
    [INDEX_op_ ## x ## b_a16] = CC_OSZAPC, \
3417
    [INDEX_op_ ## x ## w_a16] = CC_OSZAPC, \
3418
    [INDEX_op_ ## x ## l_a16] = CC_OSZAPC,
3419

  
3420
    STRINGOP(scas)
3421
    STRINGOP(repz_scas)
3422
    STRINGOP(repnz_scas)
3423
    STRINGOP(cmps)
3424
    STRINGOP(repz_cmps)
3425
    STRINGOP(repnz_cmps)
3426

  
3427
    [INDEX_op_cmpxchgb_T0_T1_EAX_cc] = CC_OSZAPC,
3422 3428
    [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
3423 3429
    [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC,
3430

  
3431
    [INDEX_op_cmpxchg8b] = CC_Z,
3424 3432
};
3425 3433

  
3426 3434
/* simpler form of an operation if no flags need to be generated */
......
3495 3503

  
3496 3504
#ifdef DEBUG_DISAS
3497 3505
static const char *op_str[] = {
3498
#define DEF(s) #s,
3506
#define DEF(s, n) #s,
3507
#include "opc-i386.h"
3508
#undef DEF
3509
};
3510

  
3511
static uint8_t op_nb_args[] = {
3512
#define DEF(s, n) n,
3499 3513
#include "opc-i386.h"
3500 3514
#undef DEF
3501 3515
};
3502 3516

  
3503
static void dump_ops(const uint16_t *opc_buf)
3517
static void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf)
3504 3518
{
3505 3519
    const uint16_t *opc_ptr;
3506
    int c;
3520
    const uint32_t *opparam_ptr;
3521
    int c, n, i;
3522

  
3507 3523
    opc_ptr = opc_buf;
3524
    opparam_ptr = opparam_buf;
3508 3525
    for(;;) {
3509 3526
        c = *opc_ptr++;
3510
        fprintf(logfile, "0x%04x: %s\n", opc_ptr - opc_buf - 1, op_str[c]);
3527
        n = op_nb_args[c];
3528
        fprintf(logfile, "0x%04x: %s", opc_ptr - opc_buf - 1, op_str[c]);
3529
        for(i = 0; i < n; i++) {
3530
            fprintf(logfile, " 0x%x", opparam_ptr[i]);
3531
        }
3532
        fprintf(logfile, "\n");
3511 3533
        if (c == INDEX_op_end)
3512 3534
            break;
3535
        opparam_ptr += n;
3513 3536
    }
3514 3537
}
3515 3538

  
......
3547 3570
    dc->ss32 = (flags >> GEN_FLAG_SS32_SHIFT) & 1;
3548 3571
    dc->addseg = (flags >> GEN_FLAG_ADDSEG_SHIFT) & 1;
3549 3572
    dc->f_st = (flags >> GEN_FLAG_ST_SHIFT) & 7;
3573
    dc->vm86 = (flags >> GEN_FLAG_VM_SHIFT) & 1;
3550 3574
    dc->cc_op = CC_OP_DYNAMIC;
3551 3575
    dc->cs_base = cs_base;
3552 3576

  
......
3610 3634
        fprintf(logfile, "\n");
3611 3635
        
3612 3636
        fprintf(logfile, "OP:\n");
3613
        dump_ops(gen_opc_buf);
3637
        dump_ops(gen_opc_buf, gen_opparam_buf);
3614 3638
        fprintf(logfile, "\n");
3615 3639
    }
3616 3640
#endif
......
3621 3645
#ifdef DEBUG_DISAS
3622 3646
    if (loglevel) {
3623 3647
        fprintf(logfile, "AFTER FLAGS OPT:\n");
3624
        dump_ops(gen_opc_buf);
3648
        dump_ops(gen_opc_buf, gen_opparam_buf);
3625 3649
        fprintf(logfile, "\n");
3626 3650
    }
3627 3651
#endif
......
3683 3707
    for(i = 0;i < 8; i++)
3684 3708
        env->fptags[i] = 1;
3685 3709
    env->fpuc = 0x37f;
3686
    /* flags setup */
3687
    env->eflags = 0;
3710
    /* flags setup : we activate the IRQs by default as in user mode */
3711
    env->eflags = 0x2 | IF_MASK;
3688 3712

  
3689 3713
    /* init various static tables */
3690 3714
    if (!inited) {

Also available in: Unified diff