- Timestamp:
- Apr 10, 2007 8:02:14 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r1999 r2000 47 47 #include <iprt/string.h> 48 48 49 /******************************************************************************* 50 * Structures and Typedefs * 51 *******************************************************************************/ 52 typedef EMDECL(uint32_t) PFN_EMULATE_PARAM2(uint32_t *pu32Param1, uint32_t val2); 53 typedef EMDECL(uint32_t) PFN_EMULATE_PARAM3(uint32_t *pu32Param1, uint32_t val2, uint32_t val3); 49 54 50 55 /******************************************************************************* … … 478 483 * INC and DEC emulation. 479 484 */ 480 static int emInterpretIncDec(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 485 static int emInterpretIncDec(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize, 486 PFN_EMULATE_PARAM2 pfnEmulate) 481 487 { 482 488 OP_PARAMVAL param1; … … 518 524 uint32_t eflags; 519 525 520 if (pCpu->pCurInstr->opcode == OP_DEC) 521 eflags = EMEmulateDec(&valpar1, param1.size); 522 else 523 eflags = EMEmulateInc(&valpar1, param1.size); 526 eflags = pfnEmulate(&valpar1, param1.size); 524 527 525 528 /* Write result back */ … … 627 630 } 628 631 629 /** 630 * OR Emulation. 631 */ 632 static int emInterpretOr(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 632 633 /** 634 * XOR/OR/AND Emulation. 635 */ 636 static int emInterpretOrXorAnd(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize, 637 PFN_EMULATE_PARAM3 pfnEmulate) 633 638 { 634 639 OP_PARAMVAL param1, param2; … … 641 646 return VERR_EM_INTERPRETER; 642 647 648 #ifdef DEBUG 649 char *pszInstr; 650 651 if (pCpu->pCurInstr->opcode == OP_XOR) 652 pszInstr = "Xor"; 653 else 654 if (pCpu->pCurInstr->opcode == OP_OR) 655 pszInstr = "Or"; 656 else 657 if (pCpu->pCurInstr->opcode == OP_AND) 658 pszInstr = "And"; 659 #endif 660 643 661 #ifdef IN_GC 644 662 if (TRPMHasTrap(pVM)) … … 654 672 if (pCpu->param1.size < pCpu->param2.size) 655 673 { 656 AssertMsgFailed((" Or at %VGv parameter mismatch %d vs %d!!\n", pRegFrame->eip, pCpu->param1.size, pCpu->param2.size)); /* should never happen! */674 AssertMsgFailed(("%s at %VGv parameter mismatch %d vs %d!!\n", pszInstr, pRegFrame->eip, pCpu->param1.size, pCpu->param2.size)); /* should never happen! */ 657 675 return VERR_EM_INTERPRETER; 658 676 } … … 697 715 } 698 716 699 /* Data read, emulate OR. */700 uint32_t eflags = EMEmulateOr(&valpar1, valpar2, param2.size);717 /* Data read, emulate instruction. */ 718 uint32_t eflags = pfnEmulate(&valpar1, valpar2, param2.size); 701 719 702 720 /* Update guest's eflags and finish. */ 703 721 pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)) 704 | (eflags &(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF));722 | (eflags & (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)); 705 723 706 724 /* And write it back */ … … 719 737 } 720 738 721 /** 722 * XOR Emulation. 723 */ 724 static int emInterpretXor(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 739 740 /** 741 * ADD, ADC & SUB Emulation. 742 */ 743 static int emInterpretAddSub(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize, 744 PFN_EMULATE_PARAM3 pfnEmulate) 725 745 { 726 746 OP_PARAMVAL param1, param2; … … 733 753 return VERR_EM_INTERPRETER; 734 754 755 #ifdef DEBUG 756 char *pszInstr; 757 758 if (pCpu->pCurInstr->opcode == OP_SUB) 759 pszInstr = "Sub"; 760 else 761 if (pCpu->pCurInstr->opcode == OP_ADD) 762 pszInstr = "Add"; 763 else 764 if (pCpu->pCurInstr->opcode == OP_ADC) 765 pszInstr = "Adc"; 766 #endif 767 735 768 #ifdef IN_GC 736 769 if (TRPMHasTrap(pVM)) … … 746 779 if (pCpu->param1.size < pCpu->param2.size) 747 780 { 748 AssertMsgFailed((" Xor at %VGv parameter mismatch %d vs %d!!\n", pRegFrame->eip, pCpu->param1.size, pCpu->param2.size)); /* should never happen! */781 AssertMsgFailed(("%s at %VGv parameter mismatch %d vs %d!!\n", pszInstr, pRegFrame->eip, pCpu->param1.size, pCpu->param2.size)); /* should never happen! */ 749 782 return VERR_EM_INTERPRETER; 750 783 } … … 773 806 else 774 807 { 808 #ifndef DEBUG_bird 775 809 AssertFailed(); 810 #endif 776 811 return VERR_EM_INTERPRETER; 777 812 } … … 789 824 } 790 825 791 /* Data read, emulate XOR. */792 uint32_t eflags = EMEmulateXor(&valpar1, valpar2, param2.size);826 /* Data read, emulate instruction. */ 827 uint32_t eflags = pfnEmulate(&valpar1, valpar2, param2.size); 793 828 794 829 /* Update guest's eflags and finish. */ … … 812 847 813 848 /** 814 * AND Emulation. 815 */ 816 static int emInterpretAnd(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 849 * ADC Emulation. 850 */ 851 static int emInterpretAdc(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 852 { 853 if (pRegFrame->eflags.Bits.u1CF) 854 return emInterpretAddSub(pVM, pCpu, pRegFrame, pvFault, pcbSize, EMEmulateAdcWithCarrySet); 855 else 856 return emInterpretAddSub(pVM, pCpu, pRegFrame, pvFault, pcbSize, EMEmulateAdd); 857 } 858 859 /** 860 * BTR/C/S Emulation. 861 */ 862 static int emInterpretBitTest(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize, 863 PFN_EMULATE_PARAM2 pfnEmulate) 817 864 { 818 865 OP_PARAMVAL param1, param2; … … 825 872 return VERR_EM_INTERPRETER; 826 873 874 #ifdef DEBUG 875 char *pszInstr; 876 877 if (pCpu->pCurInstr->opcode == OP_BTR) 878 pszInstr = "Btr"; 879 else 880 if (pCpu->pCurInstr->opcode == OP_BTS) 881 pszInstr = "Bts"; 882 else 883 if (pCpu->pCurInstr->opcode == OP_BTC) 884 pszInstr = "Btc"; 885 #endif 886 827 887 #ifdef IN_GC 828 888 if (TRPMHasTrap(pVM)) … … 832 892 #endif 833 893 RTGCPTR pParam1; 834 uint32_t valpar1, valpar2; 835 836 if (pCpu->param1.size != pCpu->param2.size) 837 { 838 if (pCpu->param1.size < pCpu->param2.size) 839 { 840 AssertMsgFailed(("And at %VGv parameter mismatch %d vs %d!!\n", pRegFrame->eip, pCpu->param1.size, pCpu->param2.size)); /* should never happen! */ 841 return VERR_EM_INTERPRETER; 842 } 843 /* Or %Ev, Ib -> just a hack to save some space; the data width of the 1st parameter determines the real width */ 844 pCpu->param2.size = pCpu->param1.size; 845 param2.size = param1.size; 846 } 894 uint32_t valpar1 = 0, valpar2; 895 uint32_t eflags; 847 896 848 897 /* The destination is always a virtual address */ 849 if (param1.type == PARMTYPE_ADDRESS) 850 { 851 pParam1 = (RTGCPTR)param1.val.val32; 852 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 853 854 #ifdef IN_GC 855 /* Safety check (in theory it could cross a page boundary and fault there though) */ 856 AssertMsgReturn(pParam1 == pvFault, ("pParam1 = %VGv pvFault = %VGv\n", pParam1, pvFault), VERR_EM_INTERPRETER); 857 #endif 858 rc = emRamRead(pVM, &valpar1, pParam1, param1.size); 859 if (VBOX_FAILURE(rc)) 860 { 861 AssertMsgFailed(("emRamRead %VGv size=%d failed with %Vrc\n", pParam1, param1.size, rc)); 862 return VERR_EM_INTERPRETER; 863 } 864 } 865 else 866 { 867 #ifndef DEBUG_bird 868 AssertFailed(); 869 #endif 870 return VERR_EM_INTERPRETER; 871 } 898 if (param1.type != PARMTYPE_ADDRESS) 899 return VERR_EM_INTERPRETER; 900 901 pParam1 = (RTGCPTR)param1.val.val32; 902 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 872 903 873 904 /* Register or immediate data */ … … 883 914 } 884 915 885 /* Data read, emulate AND. */ 886 uint32_t eflags = EMEmulateAnd(&valpar1, valpar2, param2.size); 887 888 /* Update guest's eflags and finish. */ 889 pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)) 890 | (eflags & (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)); 891 892 /* And write it back */ 893 rc = emRamWrite(pVM, pParam1, &valpar1, param1.size); 894 if (VBOX_SUCCESS(rc)) 895 { 896 /* All done! */ 897 *pcbSize = param2.size; 898 return VINF_SUCCESS; 899 } 900 #ifdef IN_GC 901 } 902 } 903 #endif 904 return VERR_EM_INTERPRETER; 905 } 906 907 /** 908 * ADD Emulation. 909 */ 910 static int emInterpretAdd(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 911 { 912 OP_PARAMVAL param1, param2; 913 int rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param1, ¶m1, PARAM_DEST); 914 if(VBOX_FAILURE(rc)) 915 return VERR_EM_INTERPRETER; 916 917 rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param2, ¶m2, PARAM_SOURCE); 918 if(VBOX_FAILURE(rc)) 919 return VERR_EM_INTERPRETER; 920 921 #ifdef IN_GC 922 if (TRPMHasTrap(pVM)) 923 { 924 if (TRPMGetErrorCode(pVM) & X86_TRAP_PF_RW) 925 { 926 #endif 927 RTGCPTR pParam1; 928 uint32_t valpar1, valpar2; 929 930 if (pCpu->param1.size != pCpu->param2.size) 931 { 932 if (pCpu->param1.size < pCpu->param2.size) 933 { 934 AssertMsgFailed(("Add at %VGv parameter mismatch %d vs %d!!\n", pRegFrame->eip, pCpu->param1.size, pCpu->param2.size)); /* should never happen! */ 935 return VERR_EM_INTERPRETER; 936 } 937 /* Or %Ev, Ib -> just a hack to save some space; the data width of the 1st parameter determines the real width */ 938 pCpu->param2.size = pCpu->param1.size; 939 param2.size = param1.size; 940 } 941 942 /* The destination is always a virtual address */ 943 if (param1.type == PARMTYPE_ADDRESS) 944 { 945 pParam1 = (RTGCPTR)param1.val.val32; 946 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 947 948 #ifdef IN_GC 949 /* Safety check (in theory it could cross a page boundary and fault there though) */ 950 AssertReturn(pParam1 == pvFault, VERR_EM_INTERPRETER); 951 #endif 952 rc = emRamRead(pVM, &valpar1, pParam1, param1.size); 953 if (VBOX_FAILURE(rc)) 954 { 955 AssertMsgFailed(("emRamRead %VGv size=%d failed with %Vrc\n", pParam1, param1.size, rc)); 956 return VERR_EM_INTERPRETER; 957 } 958 } 959 else 960 { 961 #ifndef DEBUG_bird 962 AssertFailed(); 963 #endif 964 return VERR_EM_INTERPRETER; 965 } 966 967 /* Register or immediate data */ 968 switch(param2.type) 969 { 970 case PARMTYPE_IMMEDIATE: /* both immediate data and register (ugly) */ 971 valpar2 = param2.val.val32; 972 break; 973 974 default: 975 AssertFailed(); 976 return VERR_EM_INTERPRETER; 977 } 978 979 /* Data read, emulate ADD. */ 980 uint32_t eflags = EMEmulateAdd(&valpar1, valpar2, param2.size); 981 982 /* Update guest's eflags and finish. */ 983 pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)) 984 | (eflags & (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)); 985 986 /* And write it back */ 987 rc = emRamWrite(pVM, pParam1, &valpar1, param1.size); 988 if (VBOX_SUCCESS(rc)) 989 { 990 /* All done! */ 991 *pcbSize = param2.size; 992 return VINF_SUCCESS; 993 } 994 #ifdef IN_GC 995 } 996 } 997 #endif 998 return VERR_EM_INTERPRETER; 999 } 1000 1001 /** 1002 * ADC Emulation. 1003 * @todo combine with add 1004 */ 1005 static int emInterpretAdc(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 1006 { 1007 OP_PARAMVAL param1, param2; 1008 int rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param1, ¶m1, PARAM_DEST); 1009 if(VBOX_FAILURE(rc)) 1010 return VERR_EM_INTERPRETER; 1011 1012 rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param2, ¶m2, PARAM_SOURCE); 1013 if(VBOX_FAILURE(rc)) 1014 return VERR_EM_INTERPRETER; 1015 1016 #ifdef IN_GC 1017 if (TRPMHasTrap(pVM)) 1018 { 1019 if (TRPMGetErrorCode(pVM) & X86_TRAP_PF_RW) 1020 { 1021 #endif 1022 RTGCPTR pParam1; 1023 uint32_t valpar1, valpar2; 1024 1025 if (pCpu->param1.size != pCpu->param2.size) 1026 { 1027 if (pCpu->param1.size < pCpu->param2.size) 1028 { 1029 AssertMsgFailed(("Adc at %VGv parameter mismatch %d vs %d!!\n", pRegFrame->eip, pCpu->param1.size, pCpu->param2.size)); /* should never happen! */ 1030 return VERR_EM_INTERPRETER; 1031 } 1032 /* Or %Ev, Ib -> just a hack to save some space; the data width of the 1st parameter determines the real width */ 1033 pCpu->param2.size = pCpu->param1.size; 1034 param2.size = param1.size; 1035 } 1036 1037 /* The destination is always a virtual address */ 1038 if (param1.type == PARMTYPE_ADDRESS) 1039 { 1040 pParam1 = (RTGCPTR)param1.val.val32; 1041 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 1042 1043 #ifdef IN_GC 1044 /* Safety check (in theory it could cross a page boundary and fault there though) */ 1045 AssertReturn(pParam1 == pvFault, VERR_EM_INTERPRETER); 1046 #endif 1047 rc = emRamRead(pVM, &valpar1, pParam1, param1.size); 1048 if (VBOX_FAILURE(rc)) 1049 { 1050 AssertMsgFailed(("emRamRead %VGv size=%d failed with %Vrc\n", pParam1, param1.size, rc)); 1051 return VERR_EM_INTERPRETER; 1052 } 1053 } 1054 else 1055 { 1056 #ifndef DEBUG_bird 1057 AssertFailed(); 1058 #endif 1059 return VERR_EM_INTERPRETER; 1060 } 1061 1062 /* Register or immediate data */ 1063 switch(param2.type) 1064 { 1065 case PARMTYPE_IMMEDIATE: /* both immediate data and register (ugly) */ 1066 valpar2 = param2.val.val32; 1067 break; 1068 1069 default: 1070 AssertFailed(); 1071 return VERR_EM_INTERPRETER; 1072 } 1073 1074 /* Data read, emulate ADC. */ 1075 uint32_t eflags; 1076 1077 if (pRegFrame->eflags.u32 & X86_EFL_CF) 1078 eflags = EMEmulateAdcWithCarrySet(&valpar1, valpar2, param2.size); 1079 else 1080 eflags = EMEmulateAdd(&valpar1, valpar2, param2.size); 1081 1082 /* Update guest's eflags and finish. */ 1083 pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)) 1084 | (eflags & (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)); 1085 1086 /* And write it back */ 1087 rc = emRamWrite(pVM, pParam1, &valpar1, param1.size); 1088 if (VBOX_SUCCESS(rc)) 1089 { 1090 /* All done! */ 1091 *pcbSize = param2.size; 1092 return VINF_SUCCESS; 1093 } 1094 #ifdef IN_GC 1095 } 1096 } 1097 #endif 1098 return VERR_EM_INTERPRETER; 1099 } 1100 1101 /** 1102 * SUB Emulation. 1103 */ 1104 static int emInterpretSub(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 1105 { 1106 OP_PARAMVAL param1, param2; 1107 int rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param1, ¶m1, PARAM_DEST); 1108 if(VBOX_FAILURE(rc)) 1109 return VERR_EM_INTERPRETER; 1110 1111 rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param2, ¶m2, PARAM_SOURCE); 1112 if(VBOX_FAILURE(rc)) 1113 return VERR_EM_INTERPRETER; 1114 1115 #ifdef IN_GC 1116 if (TRPMHasTrap(pVM)) 1117 { 1118 if (TRPMGetErrorCode(pVM) & X86_TRAP_PF_RW) 1119 { 1120 #endif 1121 RTGCPTR pParam1; 1122 uint32_t valpar1, valpar2; 1123 1124 if (pCpu->param1.size != pCpu->param2.size) 1125 { 1126 if (pCpu->param1.size < pCpu->param2.size) 1127 { 1128 AssertMsgFailed(("Sub at %VGv parameter mismatch %d vs %d!!\n", pRegFrame->eip, pCpu->param1.size, pCpu->param2.size)); /* should never happen! */ 1129 return VERR_EM_INTERPRETER; 1130 } 1131 /* Or %Ev, Ib -> just a hack to save some space; the data width of the 1st parameter determines the real width */ 1132 pCpu->param2.size = pCpu->param1.size; 1133 param2.size = param1.size; 1134 } 1135 1136 /* The destination is always a virtual address */ 1137 if (param1.type == PARMTYPE_ADDRESS) 1138 { 1139 pParam1 = (RTGCPTR)param1.val.val32; 1140 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 1141 1142 #ifdef IN_GC 1143 /* Safety check (in theory it could cross a page boundary and fault there though) */ 1144 AssertReturn(pParam1 == pvFault, VERR_EM_INTERPRETER); 1145 #endif 1146 rc = emRamRead(pVM, &valpar1, pParam1, param1.size); 1147 if (VBOX_FAILURE(rc)) 1148 { 1149 AssertMsgFailed(("emRamRead %VGv size=%d failed with %Vrc\n", pParam1, param1.size, rc)); 1150 return VERR_EM_INTERPRETER; 1151 } 1152 } 1153 else 1154 { 1155 #ifndef DEBUG_bird 1156 AssertFailed(); 1157 #endif 1158 return VERR_EM_INTERPRETER; 1159 } 1160 1161 /* Register or immediate data */ 1162 switch(param2.type) 1163 { 1164 case PARMTYPE_IMMEDIATE: /* both immediate data and register (ugly) */ 1165 valpar2 = param2.val.val32; 1166 break; 1167 1168 default: 1169 AssertFailed(); 1170 return VERR_EM_INTERPRETER; 1171 } 1172 1173 /* Data read, emulate SUB. */ 1174 uint32_t eflags = EMEmulateSub(&valpar1, valpar2, param2.size); 1175 1176 /* Update guest's eflags and finish. */ 1177 pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)) 1178 | (eflags & (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)); 1179 1180 /* And write it back */ 1181 rc = emRamWrite(pVM, pParam1, &valpar1, param1.size); 1182 if (VBOX_SUCCESS(rc)) 1183 { 1184 /* All done! */ 1185 *pcbSize = param2.size; 1186 return VINF_SUCCESS; 1187 } 1188 #ifdef IN_GC 1189 } 1190 } 1191 #endif 1192 return VERR_EM_INTERPRETER; 1193 } 1194 1195 /** 1196 * BTR/C/S Emulation. 1197 */ 1198 static int emInterpretBitTest(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 1199 { 1200 OP_PARAMVAL param1, param2; 1201 int rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param1, ¶m1, PARAM_DEST); 1202 if(VBOX_FAILURE(rc)) 1203 return VERR_EM_INTERPRETER; 1204 1205 rc = DISQueryParamVal(pRegFrame, pCpu, &pCpu->param2, ¶m2, PARAM_SOURCE); 1206 if(VBOX_FAILURE(rc)) 1207 return VERR_EM_INTERPRETER; 1208 1209 #ifdef IN_GC 1210 if (TRPMHasTrap(pVM)) 1211 { 1212 if (TRPMGetErrorCode(pVM) & X86_TRAP_PF_RW) 1213 { 1214 #endif 1215 RTGCPTR pParam1; 1216 uint32_t valpar1 = 0, valpar2; 1217 uint32_t eflags; 1218 1219 /* The destination is always a virtual address */ 1220 if (param1.type != PARMTYPE_ADDRESS) 1221 return VERR_EM_INTERPRETER; 1222 1223 pParam1 = (RTGCPTR)param1.val.val32; 1224 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 1225 1226 /* Register or immediate data */ 1227 switch(param2.type) 1228 { 1229 case PARMTYPE_IMMEDIATE: /* both immediate data and register (ugly) */ 1230 valpar2 = param2.val.val32; 1231 break; 1232 1233 default: 1234 AssertFailed(); 1235 return VERR_EM_INTERPRETER; 1236 } 1237 1238 Log2(("emInterpretBt%c: pvFault=%VGv pParam1=%VGv val2=%x\n", (pCpu->pCurInstr->opcode == OP_BTR) ? 'r' : ((pCpu->pCurInstr->opcode == OP_BTC) ? 'c' : 'r'), 1239 pvFault, pParam1, valpar2)); 916 Log2(("emInterpret%s: pvFault=%VGv pParam1=%VGv val2=%x\n", pszInstr, pvFault, pParam1, valpar2)); 1240 917 pParam1 = (RTGCPTR)((RTGCUINTPTR)pParam1 + valpar2/8); 1241 918 #ifdef IN_GC … … 1252 929 Log2(("emInterpretBtx: val=%x\n", valpar1)); 1253 930 /* Data read, emulate bit test instruction. */ 1254 switch (pCpu->pCurInstr->opcode) 1255 { 1256 case OP_BTR: 1257 eflags = EMEmulateBtr(&valpar1, valpar2 & 0x7); 1258 break; 1259 case OP_BTC: 1260 eflags = EMEmulateBtc(&valpar1, valpar2 & 0x7); 1261 break; 1262 case OP_BTS: 1263 eflags = EMEmulateBts(&valpar1, valpar2 & 0x7); 1264 break; 1265 default: 1266 AssertFailed(); 1267 eflags = 0; 1268 break; 1269 } 931 eflags = pfnEmulate(&valpar1, valpar2 & 0x7); 932 1270 933 Log2(("emInterpretBtx: val=%x CF=%d\n", valpar1, !!(eflags & X86_EFL_CF))); 1271 934 … … 2009 1672 switch (pCpu->pCurInstr->opcode) 2010 1673 { 2011 #define INTERPRET_CASE_EX (opcode,Instr,InstrFn) \1674 #define INTERPRET_CASE_EX_PARAM3(opcode,Instr,InstrFn, pfnEmulate) \ 2012 1675 case opcode:\ 2013 rc = emInterpret##InstrFn(pVM, pCpu, pRegFrame, pvFault, pcbSize ); \1676 rc = emInterpret##InstrFn(pVM, pCpu, pRegFrame, pvFault, pcbSize, pfnEmulate); \ 2014 1677 if (VBOX_SUCCESS(rc)) \ 2015 1678 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Instr)); \ … … 2017 1680 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Failed##Instr)); \ 2018 1681 return rc 2019 #define INTERPRET_CASE(opcode,Instr) INTERPRET_CASE_EX(opcode,Instr,Instr) 1682 #define INTERPRET_CASE_EX_PARAM2(opcode,Instr,InstrFn, pfnEmulate) \ 1683 case opcode:\ 1684 rc = emInterpret##InstrFn(pVM, pCpu, pRegFrame, pvFault, pcbSize, pfnEmulate); \ 1685 if (VBOX_SUCCESS(rc)) \ 1686 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Instr)); \ 1687 else \ 1688 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Failed##Instr)); \ 1689 return rc 1690 #define INTERPRET_CASE(opcode,Instr) \ 1691 case opcode:\ 1692 rc = emInterpret##Instr(pVM, pCpu, pRegFrame, pvFault, pcbSize); \ 1693 if (VBOX_SUCCESS(rc)) \ 1694 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Instr)); \ 1695 else \ 1696 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Failed##Instr)); \ 1697 return rc 2020 1698 #define INTERPRET_STAT_CASE(opcode,Instr) \ 2021 1699 case opcode: STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,Failed##Instr)); return VERR_EM_INTERPRETER; 2022 1700 2023 1701 INTERPRET_CASE(OP_XCHG,Xchg); 2024 INTERPRET_CASE_EX (OP_DEC,Dec,IncDec);2025 INTERPRET_CASE_EX (OP_INC,Inc,IncDec);1702 INTERPRET_CASE_EX_PARAM2(OP_DEC,Dec,IncDec,EMEmulateDec); 1703 INTERPRET_CASE_EX_PARAM2(OP_INC,Inc,IncDec,EMEmulateInc); 2026 1704 INTERPRET_CASE(OP_POP,Pop); 2027 INTERPRET_CASE(OP_OR,Or); 2028 INTERPRET_CASE(OP_XOR,Xor); 1705 INTERPRET_CASE_EX_PARAM3(OP_OR, Or, OrXorAnd, EMEmulateOr); 1706 INTERPRET_CASE_EX_PARAM3(OP_XOR,Xor, OrXorAnd, EMEmulateXor); 1707 INTERPRET_CASE_EX_PARAM3(OP_AND,And, OrXorAnd, EMEmulateAnd); 2029 1708 INTERPRET_CASE(OP_MOV,Mov); 2030 INTERPRET_CASE(OP_AND,And);2031 1709 INTERPRET_CASE(OP_INVLPG,InvlPg); 2032 1710 INTERPRET_CASE(OP_CPUID,CpuId); … … 2036 1714 INTERPRET_CASE(OP_MONITOR, Monitor); 2037 1715 INTERPRET_CASE(OP_MWAIT, MWait); 2038 INTERPRET_CASE(OP_ADD,Add); 1716 INTERPRET_CASE_EX_PARAM3(OP_ADD,Add, AddSub, EMEmulateAdd); 1717 INTERPRET_CASE_EX_PARAM3(OP_SUB,Sub, AddSub, EMEmulateSub); 2039 1718 INTERPRET_CASE(OP_ADC,Adc); 2040 INTERPRET_CASE(OP_SUB,Sub); 2041 INTERPRET_CASE_EX(OP_BTR,Btr, BitTest); 2042 INTERPRET_CASE_EX(OP_BTS,Bts, BitTest); 2043 INTERPRET_CASE_EX(OP_BTC,Btc, BitTest); 1719 INTERPRET_CASE_EX_PARAM2(OP_BTR,Btr, BitTest, EMEmulateBtr); 1720 INTERPRET_CASE_EX_PARAM2(OP_BTS,Bts, BitTest, EMEmulateBts); 1721 INTERPRET_CASE_EX_PARAM2(OP_BTC,Btc, BitTest, EMEmulateBtc); 2044 1722 #ifdef IN_GC 2045 1723 INTERPRET_CASE(OP_RDTSC,Rdtsc); … … 2058 1736 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->CTXMID(Stat,FailedMisc)); 2059 1737 return VERR_EM_INTERPRETER; 1738 #undef INTERPRET_CASE_EX_PARAM2 2060 1739 #undef INTERPRET_STAT_CASE 1740 #undef INTERPRET_CASE_EX 2061 1741 #undef INTERPRET_CASE 2062 1742 }
Note:
See TracChangeset
for help on using the changeset viewer.