Commit 9c605cb13547a5faa5cb1092e3e44ac8b0d0b841

Authored by bellard
1 parent 24f9e90b

added cmpxchg8b, cpuid, bound, eflags support, vm86 mode, 16bit/override string ops


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@55 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 206 additions and 182 deletions
translate-i386.c
... ... @@ -76,21 +76,16 @@ static void inline flush_icache_range(unsigned long start, unsigned long stop)
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,6 +98,7 @@ typedef struct DisasContext {
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,7 +126,7 @@ enum {
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,76 +552,100 @@ static GenOpFunc *gen_op_st_T0_A0[3] = {
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,26 +869,10 @@ static void gen_lea_modrm(DisasContext *s, int modrm, int *reg_ptr, int *offset_
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,7 +1347,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,22 +1363,22 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,6 +1834,17 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,8 +2042,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,26 +2064,14 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,31 +2086,20 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,6 +2176,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,16 +2650,18 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,10 +2671,11 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,9 +2685,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,19 +2695,19 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,21 +2721,18 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,9 +2740,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,11 +2752,14 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,14 +3145,27 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,11 +3196,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
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,28 +3405,30 @@ static uint16_t opc_write_flags[NB_OPS] = {
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,21 +3503,36 @@ static void optimize_flags(uint16_t *opc_buf, int opc_buf_len)
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,6 +3570,7 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
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,7 +3634,7 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
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,7 +3645,7 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
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,8 +3707,8 @@ CPUX86State *cpu_x86_init(void)
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) {
... ...