Commit 42c3c0cceddee64c22024e3e92ed636e75ea9c77

Authored by bellard
1 parent 9588b95a

native FPU support (disabled)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@641 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 47 additions and 277 deletions
target-i386/translate-copy.c
... ... @@ -31,6 +31,8 @@
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,6 +69,7 @@ typedef struct DisasContext {
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,7 +277,7 @@ static int disas_insn(DisasContext *s)
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,48 +647,37 @@ static int disas_insn(DisasContext *s)
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,102 +691,28 @@ static int disas_insn(DisasContext *s)
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,149 +725,43 @@ static int disas_insn(DisasContext *s)
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,15 +770,10 @@ static int disas_insn(DisasContext *s)
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,42 +781,20 @@ static int disas_insn(DisasContext *s)
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,49 +803,25 @@ static int disas_insn(DisasContext *s)
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,6 +1064,10 @@ static int disas_insn(DisasContext *s)
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,7 +1201,8 @@ static inline int gen_intermediate_code_internal(CPUState *env,
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,7 +1239,9 @@ static inline int gen_intermediate_code_internal(CPUState *env,
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,7 +1250,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
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,7 +1294,7 @@ int cpu_restore_state_copy(TranslationBlock *tb,
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,3 +1310,5 @@ int cpu_restore_state_copy(TranslationBlock *tb,
1542 1310 env->cc_op = CC_OP_EFLAGS;
1543 1311 return 0;
1544 1312 }
  1313 +
  1314 +#endif /* USE_CODE_COPY */
... ...