Revision 42c3c0cc

b/target-i386/translate-copy.c
31 31
#include "exec-all.h"
32 32
#include "disas.h"
33 33

  
34
#ifdef USE_CODE_COPY
35

  
34 36
extern char exec_loop;
35 37

  
36 38
/* operand size */
......
67 69
    int vm86;   /* vm86 mode */
68 70
    int cpl;
69 71
    int iopl;
72
    int flags;
70 73
    struct TranslationBlock *tb;
71 74
} DisasContext;
72 75

  
......
274 277
    uint8_t *pc_start, *pc_tmp, *pc_start_insn;
275 278
    int b, prefixes, aflag, dflag, next_eip, val;
276 279
    int ot;
277
    int modrm, mod, op;
280
    int modrm, mod, op, rm;
278 281

  
279 282
    pc_start = s->pc;
280 283
    prefixes = 0;
......
644 647
        op = R_GS;
645 648
    do_lxx:
646 649
        goto unsupported_op;
647
#if 0
648 650
        /************************/
649 651
        /* floats */
650 652
    case 0xd8 ... 0xdf: 
653
#if 1
654
        /* currently not stable enough */
655
        goto unsupported_op;
656
#else
657
        if (s->flags & (HF_EM_MASK | HF_TS_MASK))
658
            goto unsupported_op;
659
#endif
660
#if 0
661
        /* for testing FPU context switch */
662
        {
663
            static int count;
664
            count = (count + 1) % 3;
665
            if (count != 0)
666
                goto unsupported_op;
667
        }
668
#endif
651 669
        modrm = ldub_code(s->pc++);
652 670
        mod = (modrm >> 6) & 3;
653 671
        rm = modrm & 7;
654 672
        op = ((b & 7) << 3) | ((modrm >> 3) & 7);
655 673
        if (mod != 3) {
656 674
            /* memory op */
657
            gen_lea_modrm(s, modrm, &reg_addr, &offset_addr);
675
            parse_modrm(s, modrm);
658 676
            switch(op) {
659 677
            case 0x00 ... 0x07: /* fxxxs */
660 678
            case 0x10 ... 0x17: /* fixxxl */
661 679
            case 0x20 ... 0x27: /* fxxxl */
662 680
            case 0x30 ... 0x37: /* fixxx */
663
                {
664
                    int op1;
665
                    op1 = op & 7;
666

  
667
                    switch(op >> 4) {
668
                    case 0:
669
                        gen_op_flds_FT0_A0();
670
                        break;
671
                    case 1:
672
                        gen_op_fildl_FT0_A0();
673
                        break;
674
                    case 2:
675
                        gen_op_fldl_FT0_A0();
676
                        break;
677
                    case 3:
678
                    default:
679
                        gen_op_fild_FT0_A0();
680
                        break;
681
                    }
682
                    
683
                    gen_op_fp_arith_ST0_FT0[op1]();
684
                    if (op1 == 3) {
685
                        /* fcomp needs pop */
686
                        gen_op_fpop();
687
                    }
688
                }
689 681
                break;
690 682
            case 0x08: /* flds */
691 683
            case 0x0a: /* fsts */
......
699 691
            case 0x38: /* filds */
700 692
            case 0x3a: /* fists */
701 693
            case 0x3b: /* fistps */
702
                
703
                switch(op & 7) {
704
                case 0:
705
                    switch(op >> 4) {
706
                    case 0:
707
                        gen_op_flds_ST0_A0();
708
                        break;
709
                    case 1:
710
                        gen_op_fildl_ST0_A0();
711
                        break;
712
                    case 2:
713
                        gen_op_fldl_ST0_A0();
714
                        break;
715
                    case 3:
716
                    default:
717
                        gen_op_fild_ST0_A0();
718
                        break;
719
                    }
720
                    break;
721
                default:
722
                    switch(op >> 4) {
723
                    case 0:
724
                        gen_op_fsts_ST0_A0();
725
                        break;
726
                    case 1:
727
                        gen_op_fistl_ST0_A0();
728
                        break;
729
                    case 2:
730
                        gen_op_fstl_ST0_A0();
731
                        break;
732
                    case 3:
733
                    default:
734
                        gen_op_fist_ST0_A0();
735
                        break;
736
                    }
737
                    if ((op & 7) == 3)
738
                        gen_op_fpop();
739
                    break;
740
                }
741
                break;
742 694
            case 0x0c: /* fldenv mem */
743
                gen_op_fldenv_A0(s->dflag);
744
                break;
745 695
            case 0x0d: /* fldcw mem */
746
                gen_op_fldcw_A0();
747
                break;
748 696
            case 0x0e: /* fnstenv mem */
749
                gen_op_fnstenv_A0(s->dflag);
750
                break;
751 697
            case 0x0f: /* fnstcw mem */
752
                gen_op_fnstcw_A0();
753
                break;
754 698
            case 0x1d: /* fldt mem */
755
                gen_op_fldt_ST0_A0();
756
                break;
757 699
            case 0x1f: /* fstpt mem */
758
                gen_op_fstt_ST0_A0();
759
                gen_op_fpop();
760
                break;
761 700
            case 0x2c: /* frstor mem */
762
                gen_op_frstor_A0(s->dflag);
763
                break;
764 701
            case 0x2e: /* fnsave mem */
765
                gen_op_fnsave_A0(s->dflag);
766
                break;
767 702
            case 0x2f: /* fnstsw mem */
768
                gen_op_fnstsw_A0();
769
                break;
770 703
            case 0x3c: /* fbld */
771
                gen_op_fbld_ST0_A0();
772
                break;
773 704
            case 0x3e: /* fbstp */
774
                gen_op_fbst_ST0_A0();
775
                gen_op_fpop();
776
                break;
777 705
            case 0x3d: /* fildll */
778
                gen_op_fildll_ST0_A0();
779
                break;
780 706
            case 0x3f: /* fistpll */
781
                gen_op_fistll_ST0_A0();
782
                gen_op_fpop();
783 707
                break;
784 708
            default:
785 709
                goto illegal_op;
786 710
            }
787 711
        } else {
788 712
            /* register float ops */
789
            opreg = rm;
790

  
791 713
            switch(op) {
792 714
            case 0x08: /* fld sti */
793
                gen_op_fpush();
794
                gen_op_fmov_ST0_STN((opreg + 1) & 7);
795
                break;
796 715
            case 0x09: /* fxchg sti */
797
                gen_op_fxchg_ST0_STN(opreg);
798 716
                break;
799 717
            case 0x0a: /* grp d9/2 */
800 718
                switch(rm) {
......
807 725
            case 0x0c: /* grp d9/4 */
808 726
                switch(rm) {
809 727
                case 0: /* fchs */
810
                    gen_op_fchs_ST0();
811
                    break;
812 728
                case 1: /* fabs */
813
                    gen_op_fabs_ST0();
814
                    break;
815 729
                case 4: /* ftst */
816
                    gen_op_fldz_FT0();
817
                    gen_op_fcom_ST0_FT0();
818
                    break;
819 730
                case 5: /* fxam */
820
                    gen_op_fxam_ST0();
821 731
                    break;
822 732
                default:
823 733
                    goto illegal_op;
824 734
                }
825 735
                break;
826 736
            case 0x0d: /* grp d9/5 */
827
                {
828
                    switch(rm) {
829
                    case 0:
830
                        gen_op_fpush();
831
                        gen_op_fld1_ST0();
832
                        break;
833
                    case 1:
834
                        gen_op_fpush();
835
                        gen_op_fldl2t_ST0();
836
                        break;
837
                    case 2:
838
                        gen_op_fpush();
839
                        gen_op_fldl2e_ST0();
840
                        break;
841
                    case 3:
842
                        gen_op_fpush();
843
                        gen_op_fldpi_ST0();
844
                        break;
845
                    case 4:
846
                        gen_op_fpush();
847
                        gen_op_fldlg2_ST0();
848
                        break;
849
                    case 5:
850
                        gen_op_fpush();
851
                        gen_op_fldln2_ST0();
852
                        break;
853
                    case 6:
854
                        gen_op_fpush();
855
                        gen_op_fldz_ST0();
856
                        break;
857
                    default:
858
                        goto illegal_op;
859
                    }
860
                }
861
                break;
862
            case 0x0e: /* grp d9/6 */
863 737
                switch(rm) {
864
                case 0: /* f2xm1 */
865
                    gen_op_f2xm1();
866
                    break;
867
                case 1: /* fyl2x */
868
                    gen_op_fyl2x();
869
                    break;
870
                case 2: /* fptan */
871
                    gen_op_fptan();
872
                    break;
873
                case 3: /* fpatan */
874
                    gen_op_fpatan();
875
                    break;
876
                case 4: /* fxtract */
877
                    gen_op_fxtract();
878
                    break;
879
                case 5: /* fprem1 */
880
                    gen_op_fprem1();
881
                    break;
882
                case 6: /* fdecstp */
883
                    gen_op_fdecstp();
738
                case 0:
739
                case 1:
740
                case 2:
741
                case 3:
742
                case 4:
743
                case 5:
744
                case 6:
884 745
                    break;
885 746
                default:
886
                case 7: /* fincstp */
887
                    gen_op_fincstp();
888
                    break;
747
                    goto illegal_op;
889 748
                }
890 749
                break;
750
            case 0x0e: /* grp d9/6 */
751
                break;
891 752
            case 0x0f: /* grp d9/7 */
892
                switch(rm) {
893
                case 0: /* fprem */
894
                    gen_op_fprem();
895
                    break;
896
                case 1: /* fyl2xp1 */
897
                    gen_op_fyl2xp1();
898
                    break;
899
                case 2: /* fsqrt */
900
                    gen_op_fsqrt();
901
                    break;
902
                case 3: /* fsincos */
903
                    gen_op_fsincos();
904
                    break;
905
                case 5: /* fscale */
906
                    gen_op_fscale();
907
                    break;
908
                case 4: /* frndint */
909
                    gen_op_frndint();
910
                    break;
911
                case 6: /* fsin */
912
                    gen_op_fsin();
913
                    break;
914
                default:
915
                case 7: /* fcos */
916
                    gen_op_fcos();
917
                    break;
918
                }
919 753
                break;
920 754
            case 0x00: case 0x01: case 0x04 ... 0x07: /* fxxx st, sti */
921 755
            case 0x20: case 0x21: case 0x24 ... 0x27: /* fxxx sti, st */
922 756
            case 0x30: case 0x31: case 0x34 ... 0x37: /* fxxxp sti, st */
923
                {
924
                    int op1;
925
                    
926
                    op1 = op & 7;
927
                    if (op >= 0x20) {
928
                        gen_op_fp_arith_STN_ST0[op1](opreg);
929
                        if (op >= 0x30)
930
                            gen_op_fpop();
931
                    } else {
932
                        gen_op_fmov_FT0_STN(opreg);
933
                        gen_op_fp_arith_ST0_FT0[op1]();
934
                    }
935
                }
936 757
                break;
937 758
            case 0x02: /* fcom */
938
                gen_op_fmov_FT0_STN(opreg);
939
                gen_op_fcom_ST0_FT0();
940 759
                break;
941 760
            case 0x03: /* fcomp */
942
                gen_op_fmov_FT0_STN(opreg);
943
                gen_op_fcom_ST0_FT0();
944
                gen_op_fpop();
945 761
                break;
946 762
            case 0x15: /* da/5 */
947 763
                switch(rm) {
948 764
                case 1: /* fucompp */
949
                    gen_op_fmov_FT0_STN(1);
950
                    gen_op_fucom_ST0_FT0();
951
                    gen_op_fpop();
952
                    gen_op_fpop();
953 765
                    break;
954 766
                default:
955 767
                    goto illegal_op;
......
958 770
            case 0x1c:
959 771
                switch(rm) {
960 772
                case 0: /* feni (287 only, just do nop here) */
961
                    break;
962 773
                case 1: /* fdisi (287 only, just do nop here) */
963
                    break;
774
                    goto unsupported_op;
964 775
                case 2: /* fclex */
965
                    gen_op_fclex();
966
                    break;
967 776
                case 3: /* fninit */
968
                    gen_op_fninit();
969
                    break;
970 777
                case 4: /* fsetpm (287 only, just do nop here) */
971 778
                    break;
972 779
                default:
......
974 781
                }
975 782
                break;
976 783
            case 0x1d: /* fucomi */
977
                if (s->cc_op != CC_OP_DYNAMIC)
978
                    gen_op_set_cc_op(s->cc_op);
979
                gen_op_fmov_FT0_STN(opreg);
980
                gen_op_fucomi_ST0_FT0();
981
                s->cc_op = CC_OP_EFLAGS;
982 784
                break;
983 785
            case 0x1e: /* fcomi */
984
                if (s->cc_op != CC_OP_DYNAMIC)
985
                    gen_op_set_cc_op(s->cc_op);
986
                gen_op_fmov_FT0_STN(opreg);
987
                gen_op_fcomi_ST0_FT0();
988
                s->cc_op = CC_OP_EFLAGS;
989 786
                break;
990 787
            case 0x2a: /* fst sti */
991
                gen_op_fmov_STN_ST0(opreg);
992 788
                break;
993 789
            case 0x2b: /* fstp sti */
994
                gen_op_fmov_STN_ST0(opreg);
995
                gen_op_fpop();
996 790
                break;
997 791
            case 0x2c: /* fucom st(i) */
998
                gen_op_fmov_FT0_STN(opreg);
999
                gen_op_fucom_ST0_FT0();
1000 792
                break;
1001 793
            case 0x2d: /* fucomp st(i) */
1002
                gen_op_fmov_FT0_STN(opreg);
1003
                gen_op_fucom_ST0_FT0();
1004
                gen_op_fpop();
1005 794
                break;
1006 795
            case 0x33: /* de/3 */
1007 796
                switch(rm) {
1008 797
                case 1: /* fcompp */
1009
                    gen_op_fmov_FT0_STN(1);
1010
                    gen_op_fcom_ST0_FT0();
1011
                    gen_op_fpop();
1012
                    gen_op_fpop();
1013 798
                    break;
1014 799
                default:
1015 800
                    goto illegal_op;
......
1018 803
            case 0x3c: /* df/4 */
1019 804
                switch(rm) {
1020 805
                case 0:
1021
                    gen_op_fnstsw_EAX();
1022 806
                    break;
1023 807
                default:
1024 808
                    goto illegal_op;
1025 809
                }
1026 810
                break;
1027 811
            case 0x3d: /* fucomip */
1028
                if (s->cc_op != CC_OP_DYNAMIC)
1029
                    gen_op_set_cc_op(s->cc_op);
1030
                gen_op_fmov_FT0_STN(opreg);
1031
                gen_op_fucomi_ST0_FT0();
1032
                gen_op_fpop();
1033
                s->cc_op = CC_OP_EFLAGS;
1034 812
                break;
1035 813
            case 0x3e: /* fcomip */
1036
                if (s->cc_op != CC_OP_DYNAMIC)
1037
                    gen_op_set_cc_op(s->cc_op);
1038
                gen_op_fmov_FT0_STN(opreg);
1039
                gen_op_fcomi_ST0_FT0();
1040
                gen_op_fpop();
1041
                s->cc_op = CC_OP_EFLAGS;
1042 814
                break;
1043 815
            case 0x10 ... 0x13: /* fcmovxx */
1044 816
            case 0x18 ... 0x1b:
1045
                {
1046
                    int op1;
1047
                    const static uint8_t fcmov_cc[8] = {
1048
                        (JCC_B << 1),
1049
                        (JCC_Z << 1),
1050
                        (JCC_BE << 1),
1051
                        (JCC_P << 1),
1052
                    };
1053
                    op1 = fcmov_cc[op & 3] | ((op >> 3) & 1);
1054
                    gen_setcc(s, op1);
1055
                    gen_op_fcmov_ST0_STN_T0(opreg);
1056
                }
1057 817
                break;
1058 818
            default:
1059 819
                goto illegal_op;
1060 820
            }
1061 821
        }
822
        s->tb->cflags |= CF_TB_FP_USED;
1062 823
        break;
1063
#endif
824

  
1064 825
        /**************************/
1065 826
        /* mov */
1066 827
    case 0xc6:
......
1303 1064
    case 0x90: /* nop */
1304 1065
        break;
1305 1066
    case 0x9b: /* fwait */
1067
        if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) == 
1068
            (HF_MP_MASK | HF_TS_MASK)) {
1069
            goto unsupported_op;
1070
        }
1306 1071
        break;
1307 1072
    case 0xcc: /* int3 */
1308 1073
        goto unsupported_op;
......
1436 1201
    dc->cpl = (flags >> HF_CPL_SHIFT) & 3;
1437 1202
    dc->iopl = (flags >> IOPL_SHIFT) & 3;
1438 1203
    dc->tb = tb;
1439
    
1204
    dc->flags = flags;
1205

  
1440 1206
    dc->is_jmp = 0;
1441 1207

  
1442 1208
    for(;;) {
......
1473 1239
#ifdef DEBUG_DISAS
1474 1240
    if (loglevel) {
1475 1241
        fprintf(logfile, "----------------\n");
1476
        fprintf(logfile, "IN: COPY: %s\n", lookup_symbol(pc_start));
1242
        fprintf(logfile, "IN: COPY: %s fpu=%d\n", 
1243
                lookup_symbol(pc_start),
1244
                tb->cflags & CF_TB_FP_USED ? 1 : 0);
1477 1245
	disas(logfile, pc_start, dc->pc - pc_start, 0, !dc->code32);
1478 1246
        fprintf(logfile, "\n");
1479 1247
    }
......
1482 1250
    if (!search_pc) {
1483 1251
        *gen_code_size_ptr = dc->gen_code_ptr - dc->gen_code_start;
1484 1252
        tb->size = dc->pc - pc_start;
1485
        tb->cflags = CF_CODE_COPY;
1253
        tb->cflags |= CF_CODE_COPY;
1486 1254
        return 0;
1487 1255
    } else {
1488 1256
        return -1;
......
1526 1294
    if (ret < 0)
1527 1295
        return ret;
1528 1296
    /* restore all the CPU state from the CPU context from the
1529
       signal */
1297
       signal. The FPU context stays in the host CPU. */
1530 1298
    
1531 1299
    env->regs[R_EAX] = uc->uc_mcontext.gregs[REG_EAX];
1532 1300
    env->regs[R_ECX] = uc->uc_mcontext.gregs[REG_ECX];
......
1542 1310
    env->cc_op = CC_OP_EFLAGS;
1543 1311
    return 0;
1544 1312
}
1313

  
1314
#endif /* USE_CODE_COPY */

Also available in: Unified diff