Commit 4021dab0594761c939b258cad67275c492b88e4d

Authored by bellard
1 parent 626df76a

soft mmu support - moved unrelated code to help2-i386.c - synthetize string instructions


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@353 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 375 additions and 415 deletions
translate-i386.c
... ... @@ -30,8 +30,6 @@
30 30 #include "exec.h"
31 31 #include "disas.h"
32 32  
33   -//#define DEBUG_MMU
34   -
35 33 /* XXX: move that elsewhere */
36 34 static uint16_t *gen_opc_ptr;
37 35 static uint32_t *gen_opparam_ptr;
... ... @@ -62,6 +60,7 @@ typedef struct DisasContext {
62 60 int cpl;
63 61 int iopl;
64 62 int tf; /* TF cpu flag */
  63 + int mem_index; /* select memory access functions */
65 64 struct TranslationBlock *tb;
66 65 int popl_esp_hack; /* for correct popl with esp base handling */
67 66 } DisasContext;
... ... @@ -565,37 +564,81 @@ static GenOpFunc *gen_op_bsx_T0_cc[2][2] = {
565 564 },
566 565 };
567 566  
568   -static GenOpFunc *gen_op_lds_T0_A0[3] = {
  567 +static GenOpFunc *gen_op_lds_T0_A0[3 * 3] = {
569 568 gen_op_ldsb_T0_A0,
570 569 gen_op_ldsw_T0_A0,
  570 + NULL,
  571 +
  572 + gen_op_ldsb_kernel_T0_A0,
  573 + gen_op_ldsw_kernel_T0_A0,
  574 + NULL,
  575 +
  576 + gen_op_ldsb_user_T0_A0,
  577 + gen_op_ldsw_user_T0_A0,
  578 + NULL,
571 579 };
572 580  
573   -static GenOpFunc *gen_op_ldu_T0_A0[3] = {
  581 +static GenOpFunc *gen_op_ldu_T0_A0[3 * 3] = {
574 582 gen_op_ldub_T0_A0,
575 583 gen_op_lduw_T0_A0,
  584 + NULL,
  585 +
  586 + gen_op_ldub_kernel_T0_A0,
  587 + gen_op_lduw_kernel_T0_A0,
  588 + NULL,
  589 +
  590 + gen_op_ldub_user_T0_A0,
  591 + gen_op_lduw_user_T0_A0,
  592 + NULL,
576 593 };
577 594  
578   -/* sign does not matter */
579   -static GenOpFunc *gen_op_ld_T0_A0[3] = {
  595 +/* sign does not matter, except for lidt/lgdt call (TODO: fix it) */
  596 +static GenOpFunc *gen_op_ld_T0_A0[3 * 3] = {
580 597 gen_op_ldub_T0_A0,
581 598 gen_op_lduw_T0_A0,
582 599 gen_op_ldl_T0_A0,
  600 +
  601 + gen_op_ldub_kernel_T0_A0,
  602 + gen_op_lduw_kernel_T0_A0,
  603 + gen_op_ldl_kernel_T0_A0,
  604 +
  605 + gen_op_ldub_user_T0_A0,
  606 + gen_op_lduw_user_T0_A0,
  607 + gen_op_ldl_user_T0_A0,
583 608 };
584 609  
585   -static GenOpFunc *gen_op_ld_T1_A0[3] = {
  610 +static GenOpFunc *gen_op_ld_T1_A0[3 * 3] = {
586 611 gen_op_ldub_T1_A0,
587 612 gen_op_lduw_T1_A0,
588 613 gen_op_ldl_T1_A0,
  614 +
  615 + gen_op_ldub_kernel_T1_A0,
  616 + gen_op_lduw_kernel_T1_A0,
  617 + gen_op_ldl_kernel_T1_A0,
  618 +
  619 + gen_op_ldub_user_T1_A0,
  620 + gen_op_lduw_user_T1_A0,
  621 + gen_op_ldl_user_T1_A0,
589 622 };
590 623  
591   -static GenOpFunc *gen_op_st_T0_A0[3] = {
  624 +static GenOpFunc *gen_op_st_T0_A0[3 * 3] = {
592 625 gen_op_stb_T0_A0,
593 626 gen_op_stw_T0_A0,
594 627 gen_op_stl_T0_A0,
  628 +
  629 + gen_op_stb_kernel_T0_A0,
  630 + gen_op_stw_kernel_T0_A0,
  631 + gen_op_stl_kernel_T0_A0,
  632 +
  633 + gen_op_stb_user_T0_A0,
  634 + gen_op_stw_user_T0_A0,
  635 + gen_op_stl_user_T0_A0,
595 636 };
596 637  
597 638 /* the _a32 and _a16 string operations use A0 as the base register. */
598 639  
  640 +#define STRINGOP_NB 9
  641 +
599 642 #define STRINGOP(x) \
600 643 gen_op_ ## x ## b_fast, \
601 644 gen_op_ ## x ## w_fast, \
... ... @@ -607,44 +650,275 @@ static GenOpFunc *gen_op_st_T0_A0[3] = {
607 650 gen_op_ ## x ## w_a16, \
608 651 gen_op_ ## x ## l_a16,
609 652  
610   -static GenOpFunc *gen_op_movs[9 * 2] = {
611   - STRINGOP(movs)
612   - STRINGOP(rep_movs)
  653 +static GenOpFunc *gen_op_scas[STRINGOP_NB * 3] = {
  654 + STRINGOP(repz_scas)
  655 + STRINGOP(repnz_scas)
613 656 };
614 657  
615   -static GenOpFunc *gen_op_stos[9 * 2] = {
616   - STRINGOP(stos)
617   - STRINGOP(rep_stos)
  658 +static GenOpFunc *gen_op_cmps[STRINGOP_NB * 3] = {
  659 + STRINGOP(repz_cmps)
  660 + STRINGOP(repnz_cmps)
618 661 };
619 662  
620   -static GenOpFunc *gen_op_lods[9 * 2] = {
621   - STRINGOP(lods)
622   - STRINGOP(rep_lods)
623   -};
  663 +static inline void gen_string_movl_A0_ESI(DisasContext *s)
  664 +{
  665 + int override;
624 666  
625   -static GenOpFunc *gen_op_scas[9 * 3] = {
626   - STRINGOP(scas)
627   - STRINGOP(repz_scas)
628   - STRINGOP(repnz_scas)
  667 + override = s->override;
  668 + if (s->aflag) {
  669 + /* 32 bit address */
  670 + if (s->addseg && override < 0)
  671 + override = R_DS;
  672 + if (override >= 0) {
  673 + gen_op_movl_A0_seg(offsetof(CPUX86State,segs[override].base));
  674 + gen_op_addl_A0_reg_sN[0][R_ESI]();
  675 + } else {
  676 + gen_op_movl_A0_reg[R_ESI]();
  677 + }
  678 + } else {
  679 + /* 16 address, always override */
  680 + if (override < 0)
  681 + override = R_DS;
  682 + gen_op_movl_A0_reg[R_ESI]();
  683 + gen_op_andl_A0_ffff();
  684 + gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
  685 + }
  686 +}
  687 +
  688 +static inline void gen_string_movl_A0_EDI(DisasContext *s)
  689 +{
  690 + if (s->aflag) {
  691 + if (s->addseg) {
  692 + gen_op_movl_A0_seg(offsetof(CPUX86State,segs[R_ES].base));
  693 + gen_op_addl_A0_reg_sN[0][R_EDI]();
  694 + } else {
  695 + gen_op_movl_A0_reg[R_EDI]();
  696 + }
  697 + } else {
  698 + gen_op_movl_A0_reg[R_EDI]();
  699 + gen_op_andl_A0_ffff();
  700 + gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_ES].base));
  701 + }
  702 +}
  703 +
  704 +static GenOpFunc *gen_op_movl_T0_Dshift[3] = {
  705 + gen_op_movl_T0_Dshiftb,
  706 + gen_op_movl_T0_Dshiftw,
  707 + gen_op_movl_T0_Dshiftl,
629 708 };
630 709  
631   -static GenOpFunc *gen_op_cmps[9 * 3] = {
632   - STRINGOP(cmps)
633   - STRINGOP(repz_cmps)
634   - STRINGOP(repnz_cmps)
  710 +static GenOpFunc2 *gen_op_jz_ecx[2] = {
  711 + gen_op_jz_ecxw,
  712 + gen_op_jz_ecxl,
  713 +};
  714 +
  715 +static GenOpFunc *gen_op_dec_ECX[2] = {
  716 + gen_op_decw_ECX,
  717 + gen_op_decl_ECX,
635 718 };
636 719  
637   -static GenOpFunc *gen_op_ins[9 * 2] = {
638   - STRINGOP(ins)
639   - STRINGOP(rep_ins)
  720 +static GenOpFunc2 *gen_op_string_jnz_sub[2][3] = {
  721 + {
  722 + gen_op_string_jnz_subb,
  723 + gen_op_string_jnz_subw,
  724 + gen_op_string_jnz_subl,
  725 + },
  726 + {
  727 + gen_op_string_jz_subb,
  728 + gen_op_string_jz_subw,
  729 + gen_op_string_jz_subl,
  730 + },
640 731 };
641 732  
  733 +static GenOpFunc *gen_op_in_DX_T0[3] = {
  734 + gen_op_inb_DX_T0,
  735 + gen_op_inw_DX_T0,
  736 + gen_op_inl_DX_T0,
  737 +};
642 738  
643   -static GenOpFunc *gen_op_outs[9 * 2] = {
644   - STRINGOP(outs)
645   - STRINGOP(rep_outs)
  739 +static GenOpFunc *gen_op_out_DX_T0[3] = {
  740 + gen_op_outb_DX_T0,
  741 + gen_op_outw_DX_T0,
  742 + gen_op_outl_DX_T0,
646 743 };
647 744  
  745 +static inline void gen_movs(DisasContext *s, int ot)
  746 +{
  747 + gen_string_movl_A0_ESI(s);
  748 + gen_op_ld_T0_A0[ot + s->mem_index]();
  749 + gen_string_movl_A0_EDI(s);
  750 + gen_op_st_T0_A0[ot + s->mem_index]();
  751 + gen_op_movl_T0_Dshift[ot]();
  752 + if (s->aflag) {
  753 + gen_op_addl_ESI_T0();
  754 + gen_op_addl_EDI_T0();
  755 + } else {
  756 + gen_op_addw_ESI_T0();
  757 + gen_op_addw_EDI_T0();
  758 + }
  759 +}
  760 +
  761 +/* same method as Valgrind : we generate jumps to current or next
  762 + instruction */
  763 +static inline void gen_repz_movs(DisasContext *s, int ot,
  764 + unsigned int cur_eip, unsigned int next_eip)
  765 +{
  766 + if (s->cc_op != CC_OP_DYNAMIC)
  767 + gen_op_set_cc_op(s->cc_op);
  768 + gen_op_jz_ecx[s->aflag]((long)s->tb, next_eip);
  769 + gen_movs(s, ot);
  770 + gen_op_dec_ECX[s->aflag]();
  771 + gen_op_jmp_tb_next((long)s->tb, cur_eip);
  772 + s->is_jmp = 3;
  773 +}
  774 +
  775 +static inline void gen_stos(DisasContext *s, int ot)
  776 +{
  777 + gen_op_mov_TN_reg[OT_LONG][0][R_EAX]();
  778 + gen_string_movl_A0_EDI(s);
  779 + gen_op_st_T0_A0[ot + s->mem_index]();
  780 + gen_op_movl_T0_Dshift[ot]();
  781 + if (s->aflag) {
  782 + gen_op_addl_EDI_T0();
  783 + } else {
  784 + gen_op_addw_EDI_T0();
  785 + }
  786 +}
  787 +
  788 +static inline void gen_repz_stos(DisasContext *s, int ot,
  789 + unsigned int cur_eip, unsigned int next_eip)
  790 +{
  791 + if (s->cc_op != CC_OP_DYNAMIC)
  792 + gen_op_set_cc_op(s->cc_op);
  793 + gen_op_jz_ecx[s->aflag]((long)s->tb, next_eip);
  794 + gen_stos(s, ot);
  795 + gen_op_dec_ECX[s->aflag]();
  796 + gen_op_jmp_tb_next((long)s->tb, cur_eip);
  797 + s->is_jmp = 3;
  798 +}
  799 +
  800 +static inline void gen_lods(DisasContext *s, int ot)
  801 +{
  802 + gen_string_movl_A0_ESI(s);
  803 + gen_op_ld_T0_A0[ot + s->mem_index]();
  804 + gen_op_mov_reg_T0[ot][R_EAX]();
  805 + gen_op_movl_T0_Dshift[ot]();
  806 + if (s->aflag) {
  807 + gen_op_addl_ESI_T0();
  808 + } else {
  809 + gen_op_addw_ESI_T0();
  810 + }
  811 +}
  812 +
  813 +static inline void gen_repz_lods(DisasContext *s, int ot,
  814 + unsigned int cur_eip, unsigned int next_eip)
  815 +{
  816 + if (s->cc_op != CC_OP_DYNAMIC)
  817 + gen_op_set_cc_op(s->cc_op);
  818 + gen_op_jz_ecx[s->aflag]((long)s->tb, next_eip);
  819 + gen_lods(s, ot);
  820 + gen_op_dec_ECX[s->aflag]();
  821 + gen_op_jmp_tb_next((long)s->tb, cur_eip);
  822 + s->is_jmp = 3;
  823 +}
  824 +
  825 +static inline void gen_scas(DisasContext *s, int ot)
  826 +{
  827 + gen_op_mov_TN_reg[OT_LONG][0][R_EAX]();
  828 + gen_string_movl_A0_EDI(s);
  829 + gen_op_ld_T1_A0[ot + s->mem_index]();
  830 + gen_op_cmpl_T0_T1_cc();
  831 + gen_op_movl_T0_Dshift[ot]();
  832 + if (s->aflag) {
  833 + gen_op_addl_EDI_T0();
  834 + } else {
  835 + gen_op_addw_EDI_T0();
  836 + }
  837 +}
  838 +
  839 +#if 0
  840 +static inline void gen_repz_scas(DisasContext *s, int ot,
  841 + unsigned int cur_eip, unsigned int next_eip,
  842 + int nz)
  843 +{
  844 + if (s->cc_op != CC_OP_DYNAMIC)
  845 + gen_op_set_cc_op(s->cc_op);
  846 + gen_op_jz_ecx[s->aflag]((long)s->tb, next_eip);
  847 + gen_scas(s, ot);
  848 + gen_op_set_cc_op(CC_OP_SUBB + ot);
  849 + gen_op_string_jnz_sub[nz][ot]((long)s->tb, next_eip);
  850 + gen_op_dec_ECX[s->aflag]();
  851 + gen_op_jmp_tb_next((long)s->tb, cur_eip);
  852 + s->is_jmp = 3;
  853 +}
  854 +#endif
  855 +
  856 +static inline void gen_cmps(DisasContext *s, int ot)
  857 +{
  858 + gen_string_movl_A0_ESI(s);
  859 + gen_op_ld_T0_A0[ot + s->mem_index]();
  860 + gen_string_movl_A0_EDI(s);
  861 + gen_op_ld_T1_A0[ot + s->mem_index]();
  862 + gen_op_cmpl_T0_T1_cc();
  863 + gen_op_movl_T0_Dshift[ot]();
  864 + if (s->aflag) {
  865 + gen_op_addl_ESI_T0();
  866 + gen_op_addl_EDI_T0();
  867 + } else {
  868 + gen_op_addw_ESI_T0();
  869 + gen_op_addw_EDI_T0();
  870 + }
  871 +}
  872 +
  873 +static inline void gen_ins(DisasContext *s, int ot)
  874 +{
  875 + gen_op_in_DX_T0[ot]();
  876 + gen_string_movl_A0_EDI(s);
  877 + gen_op_st_T0_A0[ot + s->mem_index]();
  878 + gen_op_movl_T0_Dshift[ot]();
  879 + if (s->aflag) {
  880 + gen_op_addl_EDI_T0();
  881 + } else {
  882 + gen_op_addw_EDI_T0();
  883 + }
  884 +}
  885 +
  886 +static inline void gen_repz_ins(DisasContext *s, int ot,
  887 + unsigned int cur_eip, unsigned int next_eip)
  888 +{
  889 + if (s->cc_op != CC_OP_DYNAMIC)
  890 + gen_op_set_cc_op(s->cc_op);
  891 + gen_op_jz_ecx[s->aflag]((long)s->tb, next_eip);
  892 + gen_ins(s, ot);
  893 + gen_op_dec_ECX[s->aflag]();
  894 + gen_op_jmp_tb_next((long)s->tb, cur_eip);
  895 + s->is_jmp = 3;
  896 +}
  897 +
  898 +static inline void gen_outs(DisasContext *s, int ot)
  899 +{
  900 + gen_string_movl_A0_ESI(s);
  901 + gen_op_ld_T0_A0[ot + s->mem_index]();
  902 + gen_op_out_DX_T0[ot]();
  903 + gen_op_movl_T0_Dshift[ot]();
  904 + if (s->aflag) {
  905 + gen_op_addl_ESI_T0();
  906 + } else {
  907 + gen_op_addw_ESI_T0();
  908 + }
  909 +}
  910 +
  911 +static inline void gen_repz_outs(DisasContext *s, int ot,
  912 + unsigned int cur_eip, unsigned int next_eip)
  913 +{
  914 + if (s->cc_op != CC_OP_DYNAMIC)
  915 + gen_op_set_cc_op(s->cc_op);
  916 + gen_op_jz_ecx[s->aflag]((long)s->tb, next_eip);
  917 + gen_outs(s, ot);
  918 + gen_op_dec_ECX[s->aflag]();
  919 + gen_op_jmp_tb_next((long)s->tb, cur_eip);
  920 + s->is_jmp = 3;
  921 +}
648 922  
649 923 static inline void gen_string_ds(DisasContext *s, int ot, GenOpFunc **func)
650 924 {
... ... @@ -833,7 +1107,7 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
833 1107 if (d != OR_TMP0) {
834 1108 gen_op_mov_TN_reg[ot][0][d]();
835 1109 } else {
836   - gen_op_ld_T0_A0[ot]();
  1110 + gen_op_ld_T0_A0[ot + s1->mem_index]();
837 1111 }
838 1112 switch(op) {
839 1113 case OP_ADCL:
... ... @@ -876,7 +1150,7 @@ static void gen_op(DisasContext *s1, int op, int ot, int d)
876 1150 if (d != OR_TMP0)
877 1151 gen_op_mov_reg_T0[ot][d]();
878 1152 else
879   - gen_op_st_T0_A0[ot]();
  1153 + gen_op_st_T0_A0[ot + s1->mem_index]();
880 1154 }
881 1155 /* the flags update must happen after the memory write (precise
882 1156 exception support) */
... ... @@ -891,7 +1165,7 @@ static void gen_inc(DisasContext *s1, int ot, int d, int c)
891 1165 if (d != OR_TMP0)
892 1166 gen_op_mov_TN_reg[ot][0][d]();
893 1167 else
894   - gen_op_ld_T0_A0[ot]();
  1168 + gen_op_ld_T0_A0[ot + s1->mem_index]();
895 1169 if (s1->cc_op != CC_OP_DYNAMIC)
896 1170 gen_op_set_cc_op(s1->cc_op);
897 1171 if (c > 0) {
... ... @@ -904,7 +1178,7 @@ static void gen_inc(DisasContext *s1, int ot, int d, int c)
904 1178 if (d != OR_TMP0)
905 1179 gen_op_mov_reg_T0[ot][d]();
906 1180 else
907   - gen_op_st_T0_A0[ot]();
  1181 + gen_op_st_T0_A0[ot + s1->mem_index]();
908 1182 gen_op_update_inc_cc();
909 1183 }
910 1184  
... ... @@ -913,7 +1187,7 @@ static void gen_shift(DisasContext *s1, int op, int ot, int d, int s)
913 1187 if (d != OR_TMP0)
914 1188 gen_op_mov_TN_reg[ot][0][d]();
915 1189 else
916   - gen_op_ld_T0_A0[ot]();
  1190 + gen_op_ld_T0_A0[ot + s1->mem_index]();
917 1191 if (s != OR_TMP1)
918 1192 gen_op_mov_TN_reg[ot][1][s]();
919 1193 /* for zero counts, flags are not updated, so must do it dynamically */
... ... @@ -1107,9 +1381,9 @@ static void gen_ldst_modrm(DisasContext *s, int modrm, int ot, int reg, int is_s
1107 1381 if (is_store) {
1108 1382 if (reg != OR_TMP0)
1109 1383 gen_op_mov_TN_reg[ot][0][reg]();
1110   - gen_op_st_T0_A0[ot]();
  1384 + gen_op_st_T0_A0[ot + s->mem_index]();
1111 1385 } else {
1112   - gen_op_ld_T0_A0[ot]();
  1386 + gen_op_ld_T0_A0[ot + s->mem_index]();
1113 1387 if (reg != OR_TMP0)
1114 1388 gen_op_mov_reg_T0[ot][reg]();
1115 1389 }
... ... @@ -1376,7 +1650,7 @@ static void gen_pusha(DisasContext *s)
1376 1650 gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
1377 1651 for(i = 0;i < 8; i++) {
1378 1652 gen_op_mov_TN_reg[OT_LONG][0][7 - i]();
1379   - gen_op_st_T0_A0[OT_WORD + s->dflag]();
  1653 + gen_op_st_T0_A0[OT_WORD + s->dflag + s->mem_index]();
1380 1654 gen_op_addl_A0_im(2 << s->dflag);
1381 1655 }
1382 1656 gen_op_mov_reg_T1[OT_WORD + s->dflag][R_ESP]();
... ... @@ -1396,7 +1670,7 @@ static void gen_popa(DisasContext *s)
1396 1670 for(i = 0;i < 8; i++) {
1397 1671 /* ESP is not reloaded */
1398 1672 if (i != 3) {
1399   - gen_op_ld_T0_A0[OT_WORD + s->dflag]();
  1673 + gen_op_ld_T0_A0[OT_WORD + s->dflag + s->mem_index]();
1400 1674 gen_op_mov_reg_T0[OT_WORD + s->dflag][7 - i]();
1401 1675 }
1402 1676 gen_op_addl_A0_im(2 << s->dflag);
... ... @@ -1424,17 +1698,17 @@ static void gen_enter(DisasContext *s, int esp_addend, int level)
1424 1698 gen_op_addl_A0_seg(offsetof(CPUX86State,segs[R_SS].base));
1425 1699 /* push bp */
1426 1700 gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
1427   - gen_op_st_T0_A0[ot]();
  1701 + gen_op_st_T0_A0[ot + s->mem_index]();
1428 1702 if (level) {
1429 1703 while (level--) {
1430 1704 gen_op_addl_A0_im(-opsize);
1431 1705 gen_op_addl_T0_im(-opsize);
1432   - gen_op_st_T0_A0[ot]();
  1706 + gen_op_st_T0_A0[ot + s->mem_index]();
1433 1707 }
1434 1708 gen_op_addl_A0_im(-opsize);
1435 1709 /* XXX: add st_T1_A0 ? */
1436 1710 gen_op_movl_T0_T1();
1437   - gen_op_st_T0_A0[ot]();
  1711 + gen_op_st_T0_A0[ot + s->mem_index]();
1438 1712 }
1439 1713 gen_op_mov_reg_T1[ot][R_EBP]();
1440 1714 addend = -esp_addend;
... ... @@ -1613,7 +1887,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1613 1887 rm = modrm & 7;
1614 1888 if (mod != 3) {
1615 1889 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1616   - gen_op_ld_T1_A0[ot]();
  1890 + gen_op_ld_T1_A0[ot + s->mem_index]();
1617 1891 } else if (op == OP_XORL && rm == reg) {
1618 1892 goto xor_zero;
1619 1893 } else {
... ... @@ -1691,7 +1965,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1691 1965 op = (modrm >> 3) & 7;
1692 1966 if (mod != 3) {
1693 1967 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1694   - gen_op_ld_T0_A0[ot]();
  1968 + gen_op_ld_T0_A0[ot + s->mem_index]();
1695 1969 } else {
1696 1970 gen_op_mov_TN_reg[ot][0][rm]();
1697 1971 }
... ... @@ -1706,7 +1980,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1706 1980 case 2: /* not */
1707 1981 gen_op_notl_T0();
1708 1982 if (mod != 3) {
1709   - gen_op_st_T0_A0[ot]();
  1983 + gen_op_st_T0_A0[ot + s->mem_index]();
1710 1984 } else {
1711 1985 gen_op_mov_reg_T0[ot][rm]();
1712 1986 }
... ... @@ -1714,7 +1988,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1714 1988 case 3: /* neg */
1715 1989 gen_op_negl_T0();
1716 1990 if (mod != 3) {
1717   - gen_op_st_T0_A0[ot]();
  1991 + gen_op_st_T0_A0[ot + s->mem_index]();
1718 1992 } else {
1719 1993 gen_op_mov_reg_T0[ot][rm]();
1720 1994 }
... ... @@ -1801,7 +2075,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1801 2075 if (mod != 3) {
1802 2076 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1803 2077 if (op >= 2 && op != 3 && op != 5)
1804   - gen_op_ld_T0_A0[ot]();
  2078 + gen_op_ld_T0_A0[ot + s->mem_index]();
1805 2079 } else {
1806 2080 gen_op_mov_TN_reg[ot][0][rm]();
1807 2081 }
... ... @@ -1832,9 +2106,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1832 2106 s->is_jmp = 1;
1833 2107 break;
1834 2108 case 3: /* lcall Ev */
1835   - gen_op_ld_T1_A0[ot]();
  2109 + gen_op_ld_T1_A0[ot + s->mem_index]();
1836 2110 gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
1837   - gen_op_lduw_T0_A0();
  2111 + gen_op_ld_T0_A0[OT_WORD + s->mem_index]();
1838 2112 do_lcall:
1839 2113 if (s->pe && !s->vm86) {
1840 2114 if (s->cc_op != CC_OP_DYNAMIC)
... ... @@ -1853,7 +2127,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1853 2127 s->is_jmp = 1;
1854 2128 break;
1855 2129 case 5: /* ljmp Ev */
1856   - gen_op_ld_T1_A0[ot]();
  2130 + gen_op_ld_T1_A0[ot + s->mem_index]();
1857 2131 gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
1858 2132 gen_op_lduw_T0_A0();
1859 2133 do_ljmp:
... ... @@ -1965,9 +2239,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1965 2239 } else {
1966 2240 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1967 2241 gen_op_mov_TN_reg[ot][0][reg]();
1968   - gen_op_ld_T1_A0[ot]();
  2242 + gen_op_ld_T1_A0[ot + s->mem_index]();
1969 2243 gen_op_addl_T0_T1();
1970   - gen_op_st_T0_A0[ot]();
  2244 + gen_op_st_T0_A0[ot + s->mem_index]();
1971 2245 gen_op_mov_reg_T1[ot][reg]();
1972 2246 }
1973 2247 gen_op_update2_cc();
... ... @@ -1990,7 +2264,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1990 2264 gen_op_mov_reg_T0[ot][rm]();
1991 2265 } else {
1992 2266 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
1993   - gen_op_ld_T0_A0[ot]();
  2267 + gen_op_ld_T0_A0[ot + s->mem_index]();
1994 2268 gen_op_cmpxchg_mem_T0_T1_EAX_cc[ot]();
1995 2269 }
1996 2270 s->cc_op = CC_OP_SUBB + ot;
... ... @@ -2121,7 +2395,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2121 2395 val = insn_get(s, ot);
2122 2396 gen_op_movl_T0_im(val);
2123 2397 if (mod != 3)
2124   - gen_op_st_T0_A0[ot]();
  2398 + gen_op_st_T0_A0[ot + s->mem_index]();
2125 2399 else
2126 2400 gen_op_mov_reg_T0[ot][modrm & 7]();
2127 2401 break;
... ... @@ -2195,9 +2469,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2195 2469 } else {
2196 2470 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2197 2471 if (b & 8) {
2198   - gen_op_lds_T0_A0[ot]();
  2472 + gen_op_lds_T0_A0[ot + s->mem_index]();
2199 2473 } else {
2200   - gen_op_ldu_T0_A0[ot]();
  2474 + gen_op_ldu_T0_A0[ot + s->mem_index]();
2201 2475 }
2202 2476 gen_op_mov_reg_T0[d_ot][reg]();
2203 2477 }
... ... @@ -2245,11 +2519,11 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2245 2519 }
2246 2520 }
2247 2521 if ((b & 2) == 0) {
2248   - gen_op_ld_T0_A0[ot]();
  2522 + gen_op_ld_T0_A0[ot + s->mem_index]();
2249 2523 gen_op_mov_reg_T0[ot][R_EAX]();
2250 2524 } else {
2251 2525 gen_op_mov_TN_reg[ot][0][R_EAX]();
2252   - gen_op_st_T0_A0[ot]();
  2526 + gen_op_st_T0_A0[ot + s->mem_index]();
2253 2527 }
2254 2528 break;
2255 2529 case 0xd7: /* xlat */
... ... @@ -2272,7 +2546,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2272 2546 gen_op_addl_A0_seg(offsetof(CPUX86State,segs[override].base));
2273 2547 }
2274 2548 }
2275   - gen_op_ldub_T0_A0();
  2549 + gen_op_ldu_T0_A0[OT_BYTE + s->mem_index]();
2276 2550 gen_op_mov_reg_T0[OT_BYTE][R_EAX]();
2277 2551 break;
2278 2552 case 0xb0 ... 0xb7: /* mov R, Ib */
... ... @@ -2315,8 +2589,8 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2315 2589 /* for xchg, lock is implicit */
2316 2590 if (!(prefixes & PREFIX_LOCK))
2317 2591 gen_op_lock();
2318   - gen_op_ld_T1_A0[ot]();
2319   - gen_op_st_T0_A0[ot]();
  2592 + gen_op_ld_T1_A0[ot + s->mem_index]();
  2593 + gen_op_st_T0_A0[ot + s->mem_index]();
2320 2594 if (!(prefixes & PREFIX_LOCK))
2321 2595 gen_op_unlock();
2322 2596 gen_op_mov_reg_T1[ot][reg]();
... ... @@ -2344,7 +2618,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2344 2618 if (mod == 3)
2345 2619 goto illegal_op;
2346 2620 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2347   - gen_op_ld_T1_A0[ot]();
  2621 + gen_op_ld_T1_A0[ot + s->mem_index]();
2348 2622 gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
2349 2623 /* load the segment first to handle exceptions properly */
2350 2624 gen_op_lduw_T0_A0();
... ... @@ -2424,7 +2698,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2424 2698  
2425 2699 if (mod != 3) {
2426 2700 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
2427   - gen_op_ld_T0_A0[ot]();
  2701 + gen_op_ld_T0_A0[ot + s->mem_index]();
2428 2702 } else {
2429 2703 gen_op_mov_TN_reg[ot][0][rm]();
2430 2704 }
... ... @@ -2869,9 +3143,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2869 3143 ot = dflag ? OT_LONG : OT_WORD;
2870 3144  
2871 3145 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2872   - gen_string_ds(s, ot, gen_op_movs + 9);
  3146 + gen_repz_movs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
2873 3147 } else {
2874   - gen_string_ds(s, ot, gen_op_movs);
  3148 + gen_movs(s, ot);
2875 3149 }
2876 3150 break;
2877 3151  
... ... @@ -2883,9 +3157,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2883 3157 ot = dflag ? OT_LONG : OT_WORD;
2884 3158  
2885 3159 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2886   - gen_string_es(s, ot, gen_op_stos + 9);
  3160 + gen_repz_stos(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
2887 3161 } else {
2888   - gen_string_es(s, ot, gen_op_stos);
  3162 + gen_stos(s, ot);
2889 3163 }
2890 3164 break;
2891 3165 case 0xac: /* lodsS */
... ... @@ -2895,9 +3169,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2895 3169 else
2896 3170 ot = dflag ? OT_LONG : OT_WORD;
2897 3171 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2898   - gen_string_ds(s, ot, gen_op_lods + 9);
  3172 + gen_repz_lods(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
2899 3173 } else {
2900   - gen_string_ds(s, ot, gen_op_lods);
  3174 + gen_lods(s, ot);
2901 3175 }
2902 3176 break;
2903 3177 case 0xae: /* scasS */
... ... @@ -2909,15 +3183,15 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2909 3183 if (prefixes & PREFIX_REPNZ) {
2910 3184 if (s->cc_op != CC_OP_DYNAMIC)
2911 3185 gen_op_set_cc_op(s->cc_op);
2912   - gen_string_es(s, ot, gen_op_scas + 9 * 2);
  3186 + gen_string_es(s, ot, gen_op_scas + STRINGOP_NB);
2913 3187 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2914 3188 } else if (prefixes & PREFIX_REPZ) {
2915 3189 if (s->cc_op != CC_OP_DYNAMIC)
2916 3190 gen_op_set_cc_op(s->cc_op);
2917   - gen_string_es(s, ot, gen_op_scas + 9);
  3191 + gen_string_es(s, ot, gen_op_scas);
2918 3192 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2919 3193 } else {
2920   - gen_string_es(s, ot, gen_op_scas);
  3194 + gen_scas(s, ot);
2921 3195 s->cc_op = CC_OP_SUBB + ot;
2922 3196 }
2923 3197 break;
... ... @@ -2931,15 +3205,15 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2931 3205 if (prefixes & PREFIX_REPNZ) {
2932 3206 if (s->cc_op != CC_OP_DYNAMIC)
2933 3207 gen_op_set_cc_op(s->cc_op);
2934   - gen_string_ds(s, ot, gen_op_cmps + 9 * 2);
  3208 + gen_string_ds(s, ot, gen_op_cmps + STRINGOP_NB);
2935 3209 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2936 3210 } else if (prefixes & PREFIX_REPZ) {
2937 3211 if (s->cc_op != CC_OP_DYNAMIC)
2938 3212 gen_op_set_cc_op(s->cc_op);
2939   - gen_string_ds(s, ot, gen_op_cmps + 9);
  3213 + gen_string_ds(s, ot, gen_op_cmps);
2940 3214 s->cc_op = CC_OP_DYNAMIC; /* cannot predict flags after */
2941 3215 } else {
2942   - gen_string_ds(s, ot, gen_op_cmps);
  3216 + gen_cmps(s, ot);
2943 3217 s->cc_op = CC_OP_SUBB + ot;
2944 3218 }
2945 3219 break;
... ... @@ -2954,9 +3228,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2954 3228 else
2955 3229 ot = dflag ? OT_LONG : OT_WORD;
2956 3230 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2957   - gen_string_es(s, ot, gen_op_ins + 9);
  3231 + gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
2958 3232 } else {
2959   - gen_string_es(s, ot, gen_op_ins);
  3233 + gen_ins(s, ot);
2960 3234 }
2961 3235 }
2962 3236 break;
... ... @@ -2971,9 +3245,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2971 3245 else
2972 3246 ot = dflag ? OT_LONG : OT_WORD;
2973 3247 if (prefixes & (PREFIX_REPZ | PREFIX_REPNZ)) {
2974   - gen_string_ds(s, ot, gen_op_outs + 9);
  3248 + gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
2975 3249 } else {
2976   - gen_string_ds(s, ot, gen_op_outs);
  3250 + gen_outs(s, ot);
2977 3251 }
2978 3252 }
2979 3253 break;
... ... @@ -3071,7 +3345,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3071 3345 } else {
3072 3346 gen_stack_A0(s);
3073 3347 /* pop offset */
3074   - gen_op_ld_T0_A0[1 + s->dflag]();
  3348 + gen_op_ld_T0_A0[1 + s->dflag + s->mem_index]();
3075 3349 if (s->dflag == 0)
3076 3350 gen_op_andl_T0_ffff();
3077 3351 /* NOTE: keeping EIP updated is not a problem in case of
... ... @@ -3079,7 +3353,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3079 3353 gen_op_jmp_T0();
3080 3354 /* pop selector */
3081 3355 gen_op_addl_A0_im(2 << s->dflag);
3082   - gen_op_ld_T0_A0[1 + s->dflag]();
  3356 + gen_op_ld_T0_A0[1 + s->dflag + s->mem_index]();
3083 3357 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[R_CS]));
3084 3358 /* add stack offset */
3085 3359 gen_stack_update(s, val + (4 << s->dflag));
... ... @@ -3188,7 +3462,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3188 3462 gen_setcc(s, b);
3189 3463 if (mod != 3) {
3190 3464 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3191   - gen_op_ld_T1_A0[ot]();
  3465 + gen_op_ld_T1_A0[ot + s->mem_index]();
3192 3466 } else {
3193 3467 rm = modrm & 7;
3194 3468 gen_op_mov_TN_reg[ot][1][rm]();
... ... @@ -3279,7 +3553,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3279 3553 rm = modrm & 7;
3280 3554 if (mod != 3) {
3281 3555 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3282   - gen_op_ld_T0_A0[ot]();
  3556 + gen_op_ld_T0_A0[ot + s->mem_index]();
3283 3557 } else {
3284 3558 gen_op_mov_TN_reg[ot][0][rm]();
3285 3559 }
... ... @@ -3293,7 +3567,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3293 3567 s->cc_op = CC_OP_SARB + ot;
3294 3568 if (op != 0) {
3295 3569 if (mod != 3)
3296   - gen_op_st_T0_A0[ot]();
  3570 + gen_op_st_T0_A0[ot + s->mem_index]();
3297 3571 else
3298 3572 gen_op_mov_reg_T0[ot][rm]();
3299 3573 gen_op_update_bt_cc();
... ... @@ -3324,7 +3598,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3324 3598 gen_op_add_bitw_A0_T1();
3325 3599 else
3326 3600 gen_op_add_bitl_A0_T1();
3327   - gen_op_ld_T0_A0[ot]();
  3601 + gen_op_ld_T0_A0[ot + s->mem_index]();
3328 3602 } else {
3329 3603 gen_op_mov_TN_reg[ot][0][rm]();
3330 3604 }
... ... @@ -3332,7 +3606,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3332 3606 s->cc_op = CC_OP_SARB + ot;
3333 3607 if (op != 0) {
3334 3608 if (mod != 3)
3335   - gen_op_st_T0_A0[ot]();
  3609 + gen_op_st_T0_A0[ot + s->mem_index]();
3336 3610 else
3337 3611 gen_op_mov_reg_T0[ot][rm]();
3338 3612 gen_op_update_bt_cc();
... ... @@ -3569,7 +3843,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3569 3843 gen_op_movl_T0_env(offsetof(CPUX86State,gdt.limit));
3570 3844 else
3571 3845 gen_op_movl_T0_env(offsetof(CPUX86State,idt.limit));
3572   - gen_op_stw_T0_A0();
  3846 + gen_op_st_T0_A0[OT_WORD + s->mem_index]();
3573 3847 gen_op_addl_A0_im(2);
3574 3848 if (op == 0)
3575 3849 gen_op_movl_T0_env(offsetof(CPUX86State,gdt.base));
... ... @@ -3577,7 +3851,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3577 3851 gen_op_movl_T0_env(offsetof(CPUX86State,idt.base));
3578 3852 if (!s->dflag)
3579 3853 gen_op_andl_T0_im(0xffffff);
3580   - gen_op_stl_T0_A0();
  3854 + gen_op_st_T0_A0[OT_LONG + s->mem_index]();
3581 3855 break;
3582 3856 case 2: /* lgdt */
3583 3857 case 3: /* lidt */
... ... @@ -3587,9 +3861,9 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
3587 3861 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3588 3862 } else {
3589 3863 gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
3590   - gen_op_lduw_T1_A0();
  3864 + gen_op_ld_T1_A0[OT_WORD + s->mem_index]();
3591 3865 gen_op_addl_A0_im(2);
3592   - gen_op_ldl_T0_A0();
  3866 + gen_op_ld_T0_A0[OT_LONG + s->mem_index]();
3593 3867 if (!s->dflag)
3594 3868 gen_op_andl_T0_im(0xffffff);
3595 3869 if (op == 2) {
... ... @@ -3990,10 +4264,8 @@ static uint16_t opc_write_flags[NB_OPS] = {
3990 4264 [INDEX_op_ ## x ## w_a16] = CC_OSZAPC, \
3991 4265 [INDEX_op_ ## x ## l_a16] = CC_OSZAPC,
3992 4266  
3993   - STRINGOP(scas)
3994 4267 STRINGOP(repz_scas)
3995 4268 STRINGOP(repnz_scas)
3996   - STRINGOP(cmps)
3997 4269 STRINGOP(repz_cmps)
3998 4270 STRINGOP(repnz_cmps)
3999 4271  
... ... @@ -4050,7 +4322,7 @@ static uint16_t opc_simpler[NB_OPS] = {
4050 4322 [INDEX_op_sarl_T0_T1_cc] = INDEX_op_sarl_T0_T1,
4051 4323 };
4052 4324  
4053   -static void optimize_flags_init(void)
  4325 +void optimize_flags_init(void)
4054 4326 {
4055 4327 int i;
4056 4328 /* put default values in arrays */
... ... @@ -4120,6 +4392,14 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4120 4392 dc->cs_base = cs_base;
4121 4393 dc->tb = tb;
4122 4394 dc->popl_esp_hack = 0;
  4395 + /* select memory access functions */
  4396 + dc->mem_index = 0;
  4397 + if ((flags >> GEN_FLAG_SOFT_MMU_SHIFT) & 1) {
  4398 + if (dc->cpl == 3)
  4399 + dc->mem_index = 6;
  4400 + else
  4401 + dc->mem_index = 3;
  4402 + }
4123 4403  
4124 4404 gen_opc_ptr = gen_opc_buf;
4125 4405 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
... ... @@ -4234,323 +4514,3 @@ int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
4234 4514 return gen_intermediate_code_internal(env, tb, 1);
4235 4515 }
4236 4516  
4237   -CPUX86State *cpu_x86_init(void)
4238   -{
4239   - CPUX86State *env;
4240   - int i;
4241   - static int inited;
4242   -
4243   - cpu_exec_init();
4244   -
4245   - env = malloc(sizeof(CPUX86State));
4246   - if (!env)
4247   - return NULL;
4248   - memset(env, 0, sizeof(CPUX86State));
4249   - /* basic FPU init */
4250   - for(i = 0;i < 8; i++)
4251   - env->fptags[i] = 1;
4252   - env->fpuc = 0x37f;
4253   - /* flags setup : we activate the IRQs by default as in user mode */
4254   - env->eflags = 0x2 | IF_MASK;
4255   -
4256   - /* init various static tables */
4257   - if (!inited) {
4258   - inited = 1;
4259   - optimize_flags_init();
4260   - }
4261   - return env;
4262   -}
4263   -
4264   -void cpu_x86_close(CPUX86State *env)
4265   -{
4266   - free(env);
4267   -}
4268   -
4269   -/***********************************************************/
4270   -/* x86 mmu */
4271   -/* XXX: add PGE support */
4272   -
4273   -/* called when cr3 or PG bit are modified */
4274   -static int last_pg_state = -1;
4275   -static int last_pe_state = 0;
4276   -int phys_ram_size;
4277   -int phys_ram_fd;
4278   -uint8_t *phys_ram_base;
4279   -
4280   -void cpu_x86_update_cr0(CPUX86State *env)
4281   -{
4282   - int pg_state, pe_state;
4283   - void *map_addr;
4284   -
4285   -#ifdef DEBUG_MMU
4286   - printf("CR0 update: CR0=0x%08x\n", env->cr[0]);
4287   -#endif
4288   - pg_state = env->cr[0] & CR0_PG_MASK;
4289   - if (pg_state != last_pg_state) {
4290   - if (!pg_state) {
4291   - /* we map the physical memory at address 0 */
4292   -
4293   - map_addr = mmap((void *)0, phys_ram_size, PROT_WRITE | PROT_READ,
4294   - MAP_SHARED | MAP_FIXED, phys_ram_fd, 0);
4295   - if (map_addr == MAP_FAILED) {
4296   - fprintf(stderr,
4297   - "Could not map physical memory at host address 0x%08x\n",
4298   - 0);
4299   - exit(1);
4300   - }
4301   - page_set_flags(0, phys_ram_size,
4302   - PAGE_VALID | PAGE_READ | PAGE_WRITE | PAGE_EXEC);
4303   - } else {
4304   - /* we unmap the physical memory */
4305   - munmap((void *)0, phys_ram_size);
4306   - page_set_flags(0, phys_ram_size, 0);
4307   - }
4308   - last_pg_state = pg_state;
4309   - }
4310   - pe_state = env->cr[0] & CR0_PE_MASK;
4311   - if (last_pe_state != pe_state) {
4312   - tb_flush();
4313   - last_pe_state = pe_state;
4314   - }
4315   -}
4316   -
4317   -void cpu_x86_update_cr3(CPUX86State *env)
4318   -{
4319   - if (env->cr[0] & CR0_PG_MASK) {
4320   -#if defined(DEBUG_MMU)
4321   - printf("CR3 update: CR3=%08x\n", env->cr[3]);
4322   -#endif
4323   - page_unmap();
4324   - }
4325   -}
4326   -
4327   -void cpu_x86_init_mmu(CPUX86State *env)
4328   -{
4329   - last_pg_state = -1;
4330   - cpu_x86_update_cr0(env);
4331   -}
4332   -
4333   -/* XXX: also flush 4MB pages */
4334   -void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr)
4335   -{
4336   - int flags;
4337   - unsigned long virt_addr;
4338   -
4339   - flags = page_get_flags(addr);
4340   - if (flags & PAGE_VALID) {
4341   - virt_addr = addr & ~0xfff;
4342   - munmap((void *)virt_addr, 4096);
4343   - page_set_flags(virt_addr, virt_addr + 4096, 0);
4344   - }
4345   -}
4346   -
4347   -/* return value:
4348   - -1 = cannot handle fault
4349   - 0 = nothing more to do
4350   - 1 = generate PF fault
4351   -*/
4352   -int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write)
4353   -{
4354   - uint8_t *pde_ptr, *pte_ptr;
4355   - uint32_t pde, pte, virt_addr;
4356   - int cpl, error_code, is_dirty, is_user, prot, page_size;
4357   - void *map_addr;
4358   -
4359   - cpl = env->cpl;
4360   - is_user = (cpl == 3);
4361   -
4362   -#ifdef DEBUG_MMU
4363   - printf("MMU fault: addr=0x%08x w=%d u=%d eip=%08x\n",
4364   - addr, is_write, is_user, env->eip);
4365   -#endif
4366   -
4367   - if (env->user_mode_only) {
4368   - /* user mode only emulation */
4369   - error_code = 0;
4370   - goto do_fault;
4371   - }
4372   -
4373   - if (!(env->cr[0] & CR0_PG_MASK))
4374   - return -1;
4375   -
4376   - /* page directory entry */
4377   - pde_ptr = phys_ram_base + ((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3));
4378   - pde = ldl(pde_ptr);
4379   - if (!(pde & PG_PRESENT_MASK)) {
4380   - error_code = 0;
4381   - goto do_fault;
4382   - }
4383   - if (is_user) {
4384   - if (!(pde & PG_USER_MASK))
4385   - goto do_fault_protect;
4386   - if (is_write && !(pde & PG_RW_MASK))
4387   - goto do_fault_protect;
4388   - } else {
4389   - if ((env->cr[0] & CR0_WP_MASK) && (pde & PG_USER_MASK) &&
4390   - is_write && !(pde & PG_RW_MASK))
4391   - goto do_fault_protect;
4392   - }
4393   - /* if PSE bit is set, then we use a 4MB page */
4394   - if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
4395   - is_dirty = is_write && !(pde & PG_DIRTY_MASK);
4396   - if (!(pde & PG_ACCESSED_MASK)) {
4397   - pde |= PG_ACCESSED_MASK;
4398   - if (is_dirty)
4399   - pde |= PG_DIRTY_MASK;
4400   - stl(pde_ptr, pde);
4401   - }
4402   -
4403   - pte = pde & ~0x003ff000; /* align to 4MB */
4404   - page_size = 4096 * 1024;
4405   - virt_addr = addr & ~0x003fffff;
4406   - } else {
4407   - if (!(pde & PG_ACCESSED_MASK)) {
4408   - pde |= PG_ACCESSED_MASK;
4409   - stl(pde_ptr, pde);
4410   - }
4411   -
4412   - /* page directory entry */
4413   - pte_ptr = phys_ram_base + ((pde & ~0xfff) + ((addr >> 10) & 0xffc));
4414   - pte = ldl(pte_ptr);
4415   - if (!(pte & PG_PRESENT_MASK)) {
4416   - error_code = 0;
4417   - goto do_fault;
4418   - }
4419   - if (is_user) {
4420   - if (!(pte & PG_USER_MASK))
4421   - goto do_fault_protect;
4422   - if (is_write && !(pte & PG_RW_MASK))
4423   - goto do_fault_protect;
4424   - } else {
4425   - if ((env->cr[0] & CR0_WP_MASK) && (pte & PG_USER_MASK) &&
4426   - is_write && !(pte & PG_RW_MASK))
4427   - goto do_fault_protect;
4428   - }
4429   - is_dirty = is_write && !(pte & PG_DIRTY_MASK);
4430   - if (!(pte & PG_ACCESSED_MASK) || is_dirty) {
4431   - pte |= PG_ACCESSED_MASK;
4432   - if (is_dirty)
4433   - pte |= PG_DIRTY_MASK;
4434   - stl(pte_ptr, pte);
4435   - }
4436   - page_size = 4096;
4437   - virt_addr = addr & ~0xfff;
4438   - }
4439   - /* the page can be put in the TLB */
4440   - prot = PROT_READ;
4441   - if (is_user) {
4442   - if (pte & PG_RW_MASK)
4443   - prot |= PROT_WRITE;
4444   - } else {
4445   - if (!(env->cr[0] & CR0_WP_MASK) || !(pte & PG_USER_MASK) ||
4446   - (pte & PG_RW_MASK))
4447   - prot |= PROT_WRITE;
4448   - }
4449   - map_addr = mmap((void *)virt_addr, page_size, prot,
4450   - MAP_SHARED | MAP_FIXED, phys_ram_fd, pte & ~0xfff);
4451   - if (map_addr == MAP_FAILED) {
4452   - fprintf(stderr,
4453   - "mmap failed when mapped physical address 0x%08x to virtual address 0x%08x\n",
4454   - pte & ~0xfff, virt_addr);
4455   - exit(1);
4456   - }
4457   - page_set_flags(virt_addr, virt_addr + page_size,
4458   - PAGE_VALID | PAGE_EXEC | prot);
4459   -#ifdef DEBUG_MMU
4460   - printf("mmaping 0x%08x to virt 0x%08x pse=%d\n",
4461   - pte & ~0xfff, virt_addr, (page_size != 4096));
4462   -#endif
4463   - return 0;
4464   - do_fault_protect:
4465   - error_code = PG_ERROR_P_MASK;
4466   - do_fault:
4467   - env->cr[2] = addr;
4468   - env->error_code = (is_write << PG_ERROR_W_BIT) | error_code;
4469   - if (is_user)
4470   - env->error_code |= PG_ERROR_U_MASK;
4471   - return 1;
4472   -}
4473   -
4474   -/***********************************************************/
4475   -/* x86 debug */
4476   -
4477   -static const char *cc_op_str[] = {
4478   - "DYNAMIC",
4479   - "EFLAGS",
4480   - "MUL",
4481   - "ADDB",
4482   - "ADDW",
4483   - "ADDL",
4484   - "ADCB",
4485   - "ADCW",
4486   - "ADCL",
4487   - "SUBB",
4488   - "SUBW",
4489   - "SUBL",
4490   - "SBBB",
4491   - "SBBW",
4492   - "SBBL",
4493   - "LOGICB",
4494   - "LOGICW",
4495   - "LOGICL",
4496   - "INCB",
4497   - "INCW",
4498   - "INCL",
4499   - "DECB",
4500   - "DECW",
4501   - "DECL",
4502   - "SHLB",
4503   - "SHLW",
4504   - "SHLL",
4505   - "SARB",
4506   - "SARW",
4507   - "SARL",
4508   -};
4509   -
4510   -void cpu_x86_dump_state(CPUX86State *env, FILE *f, int flags)
4511   -{
4512   - int eflags;
4513   - char cc_op_name[32];
4514   -
4515   - eflags = env->eflags;
4516   - fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
4517   - "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
4518   - "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c]\n",
4519   - env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX],
4520   - env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], env->regs[R_ESP],
4521   - env->eip, eflags,
4522   - eflags & DF_MASK ? 'D' : '-',
4523   - eflags & CC_O ? 'O' : '-',
4524   - eflags & CC_S ? 'S' : '-',
4525   - eflags & CC_Z ? 'Z' : '-',
4526   - eflags & CC_A ? 'A' : '-',
4527   - eflags & CC_P ? 'P' : '-',
4528   - eflags & CC_C ? 'C' : '-');
4529   - fprintf(f, "CS=%04x SS=%04x DS=%04x ES=%04x FS=%04x GS=%04x\n",
4530   - env->segs[R_CS].selector,
4531   - env->segs[R_SS].selector,
4532   - env->segs[R_DS].selector,
4533   - env->segs[R_ES].selector,
4534   - env->segs[R_FS].selector,
4535   - env->segs[R_GS].selector);
4536   - if (flags & X86_DUMP_CCOP) {
4537   - if ((unsigned)env->cc_op < CC_OP_NB)
4538   - strcpy(cc_op_name, cc_op_str[env->cc_op]);
4539   - else
4540   - snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
4541   - fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
4542   - env->cc_src, env->cc_dst, cc_op_name);
4543   - }
4544   - if (flags & X86_DUMP_FPU) {
4545   - fprintf(f, "ST0=%f ST1=%f ST2=%f ST3=%f\n",
4546   - (double)env->fpregs[0],
4547   - (double)env->fpregs[1],
4548   - (double)env->fpregs[2],
4549   - (double)env->fpregs[3]);
4550   - fprintf(f, "ST4=%f ST5=%f ST6=%f ST7=%f\n",
4551   - (double)env->fpregs[4],
4552   - (double)env->fpregs[5],
4553   - (double)env->fpregs[7],
4554   - (double)env->fpregs[8]);
4555   - }
4556   -}
... ...