Revision 4021dab0 translate-i386.c

b/translate-i386.c
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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
}

Also available in: Unified diff