- Timestamp:
- Oct 27, 2011 11:42:34 AM (13 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r39125 r39127 817 817 818 818 /** 819 * Deals with the problematic cases that iemOpcodeGetNext Bytedoesn't like.819 * Deals with the problematic cases that iemOpcodeGetNextU8 doesn't like. 820 820 * 821 821 * @returns Strict VBox status code. … … 823 823 * @param pb Where to return the opcode byte. 824 824 */ 825 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNext ByteSlow(PIEMCPU pIemCpu, uint8_t *pb)825 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU8Slow(PIEMCPU pIemCpu, uint8_t *pb) 826 826 { 827 827 VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 1); … … 839 839 840 840 /** 841 * Fetches the next opcode byte. 842 * 843 * @returns Strict VBox status code. 844 * @param pIemCpu The IEM state. 845 * @param pu8 Where to return the opcode byte. 846 */ 847 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU8(PIEMCPU pIemCpu, uint8_t *pu8) 848 { 849 uint8_t const offOpcode = pIemCpu->offOpcode; 850 if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode)) 851 return iemOpcodeGetNextU8Slow(pIemCpu, pu8); 852 853 *pu8 = pIemCpu->abOpcode[offOpcode]; 854 pIemCpu->offOpcode = offOpcode + 1; 855 return VINF_SUCCESS; 856 } 857 858 859 /** 860 * Fetches the next opcode byte, returns automatically on failure. 861 * 862 * @param a_pu8 Where to return the opcode byte. 863 * @remark Implicitly references pIemCpu. 864 */ 865 #define IEM_OPCODE_GET_NEXT_U8(a_pu8) \ 866 do \ 867 { \ 868 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU8(pIemCpu, (a_pu8)); \ 869 if (rcStrict2 != VINF_SUCCESS) \ 870 return rcStrict2; \ 871 } while (0) 872 873 874 /** 875 * Fetches the next signed byte from the opcode stream. 876 * 877 * @returns Strict VBox status code. 878 * @param pIemCpu The IEM state. 879 * @param pi8 Where to return the signed byte. 880 */ 881 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8(PIEMCPU pIemCpu, int8_t *pi8) 882 { 883 return iemOpcodeGetNextU8(pIemCpu, (uint8_t *)pi8); 884 } 885 886 887 /** 888 * Fetches the next signed byte from the opcode stream, returning automatically 889 * on failure. 890 * 891 * @param pi8 Where to return the signed byte. 892 * @remark Implicitly references pIemCpu. 893 */ 894 #define IEM_OPCODE_GET_NEXT_S8(a_pi8) \ 895 do \ 896 { \ 897 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8(pIemCpu, (a_pi8)); \ 898 if (rcStrict2 != VINF_SUCCESS) \ 899 return rcStrict2; \ 900 } while (0) 901 902 903 /** 841 904 * Deals with the problematic cases that iemOpcodeGetNextS8SxU16 doesn't like. 842 905 * … … 847 910 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextS8SxU16Slow(PIEMCPU pIemCpu, uint16_t *pu16) 848 911 { 849 uint8_t u8;850 VBOXSTRICTRC rcStrict = iemOpcodeGetNext ByteSlow(pIemCpu, &u8);912 uint8_t u8; 913 VBOXSTRICTRC rcStrict = iemOpcodeGetNextU8Slow(pIemCpu, &u8); 851 914 if (rcStrict == VINF_SUCCESS) 852 915 *pu16 = (int8_t)u8; … … 856 919 857 920 /** 921 * Fetches the next signed byte from the opcode stream, extending it to 922 * unsigned 16-bit. 923 * 924 * @returns Strict VBox status code. 925 * @param pIemCpu The IEM state. 926 * @param pu16 Where to return the unsigned word. 927 */ 928 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU16(PIEMCPU pIemCpu, uint16_t *pu16) 929 { 930 uint8_t const offOpcode = pIemCpu->offOpcode; 931 if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode)) 932 return iemOpcodeGetNextS8SxU16Slow(pIemCpu, pu16); 933 934 *pu16 = (int8_t)pIemCpu->abOpcode[offOpcode]; 935 pIemCpu->offOpcode = offOpcode + 1; 936 return VINF_SUCCESS; 937 } 938 939 940 /** 941 * Fetches the next signed byte from the opcode stream and sign-extending it to 942 * a word, returning automatically on failure. 943 * 944 * @param pu16 Where to return the word. 945 * @remark Implicitly references pIemCpu. 946 */ 947 #define IEM_OPCODE_GET_NEXT_S8_SX_U16(a_pu16) \ 948 do \ 949 { \ 950 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU16(pIemCpu, (a_pu16)); \ 951 if (rcStrict2 != VINF_SUCCESS) \ 952 return rcStrict2; \ 953 } while (0) 954 955 956 /** 858 957 * Deals with the problematic cases that iemOpcodeGetNextU16 doesn't like. 859 958 * … … 875 974 return rcStrict; 876 975 } 976 977 978 /** 979 * Fetches the next opcode word. 980 * 981 * @returns Strict VBox status code. 982 * @param pIemCpu The IEM state. 983 * @param pu16 Where to return the opcode word. 984 */ 985 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16(PIEMCPU pIemCpu, uint16_t *pu16) 986 { 987 uint8_t const offOpcode = pIemCpu->offOpcode; 988 if (RT_UNLIKELY(offOpcode + 2 > pIemCpu->cbOpcode)) 989 return iemOpcodeGetNextU16Slow(pIemCpu, pu16); 990 991 *pu16 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]); 992 pIemCpu->offOpcode = offOpcode + 2; 993 return VINF_SUCCESS; 994 } 995 996 997 /** 998 * Fetches the next opcode word, returns automatically on failure. 999 * 1000 * @param a_pu16 Where to return the opcode word. 1001 * @remark Implicitly references pIemCpu. 1002 */ 1003 #define IEM_OPCODE_GET_NEXT_U16(a_pu16) \ 1004 do \ 1005 { \ 1006 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16(pIemCpu, (a_pu16)); \ 1007 if (rcStrict2 != VINF_SUCCESS) \ 1008 return rcStrict2; \ 1009 } while (0) 1010 1011 1012 /** 1013 * Deals with the problematic cases that iemOpcodeGetNextU16ZxU32 doesn't like. 1014 * 1015 * @returns Strict VBox status code. 1016 * @param pIemCpu The IEM state. 1017 * @param pu32 Where to return the opcode double word. 1018 */ 1019 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU16ZxU32Slow(PIEMCPU pIemCpu, uint32_t *pu32) 1020 { 1021 VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 2); 1022 if (rcStrict == VINF_SUCCESS) 1023 { 1024 uint8_t offOpcode = pIemCpu->offOpcode; 1025 *pu32 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]); 1026 pIemCpu->offOpcode = offOpcode + 2; 1027 } 1028 else 1029 *pu32 = 0; 1030 return rcStrict; 1031 } 1032 1033 1034 /** 1035 * Fetches the next opcode word, zero extending it to a double word. 1036 * 1037 * @returns Strict VBox status code. 1038 * @param pIemCpu The IEM state. 1039 * @param pu32 Where to return the opcode double word. 1040 */ 1041 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16ZxU32(PIEMCPU pIemCpu, uint32_t *pu32) 1042 { 1043 uint8_t const offOpcode = pIemCpu->offOpcode; 1044 if (RT_UNLIKELY(offOpcode + 2 > pIemCpu->cbOpcode)) 1045 return iemOpcodeGetNextU16ZxU32Slow(pIemCpu, pu32); 1046 1047 *pu32 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]); 1048 pIemCpu->offOpcode = offOpcode + 2; 1049 return VINF_SUCCESS; 1050 } 1051 1052 1053 /** 1054 * Fetches the next opcode word and zero extends it to a double word, returns 1055 * automatically on failure. 1056 * 1057 * @param a_pu32 Where to return the opcode double word. 1058 * @remark Implicitly references pIemCpu. 1059 */ 1060 #define IEM_OPCODE_GET_NEXT_U16_ZX_U32(a_pu32) \ 1061 do \ 1062 { \ 1063 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16ZxU32(pIemCpu, (a_pu32)); \ 1064 if (rcStrict2 != VINF_SUCCESS) \ 1065 return rcStrict2; \ 1066 } while (0) 1067 1068 1069 /** 1070 * Deals with the problematic cases that iemOpcodeGetNextU16ZxU64 doesn't like. 1071 * 1072 * @returns Strict VBox status code. 1073 * @param pIemCpu The IEM state. 1074 * @param pu64 Where to return the opcode quad word. 1075 */ 1076 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU16ZxU64Slow(PIEMCPU pIemCpu, uint64_t *pu64) 1077 { 1078 VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 2); 1079 if (rcStrict == VINF_SUCCESS) 1080 { 1081 uint8_t offOpcode = pIemCpu->offOpcode; 1082 *pu64 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]); 1083 pIemCpu->offOpcode = offOpcode + 2; 1084 } 1085 else 1086 *pu64 = 0; 1087 return rcStrict; 1088 } 1089 1090 1091 /** 1092 * Fetches the next opcode word, zero extending it to a quad word. 1093 * 1094 * @returns Strict VBox status code. 1095 * @param pIemCpu The IEM state. 1096 * @param pu64 Where to return the opcode quad word. 1097 */ 1098 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16ZxU64(PIEMCPU pIemCpu, uint64_t *pu64) 1099 { 1100 uint8_t const offOpcode = pIemCpu->offOpcode; 1101 if (RT_UNLIKELY(offOpcode + 2 > pIemCpu->cbOpcode)) 1102 return iemOpcodeGetNextU16ZxU64Slow(pIemCpu, pu64); 1103 1104 *pu64 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]); 1105 pIemCpu->offOpcode = offOpcode + 2; 1106 return VINF_SUCCESS; 1107 } 1108 1109 1110 /** 1111 * Fetches the next opcode word and zero extends it to a quad word, returns 1112 * automatically on failure. 1113 * 1114 * @param a_pu64 Where to return the opcode quad word. 1115 * @remark Implicitly references pIemCpu. 1116 */ 1117 #define IEM_OPCODE_GET_NEXT_U16_ZX_U64(a_pu64) \ 1118 do \ 1119 { \ 1120 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16ZxU64(pIemCpu, (a_pu64)); \ 1121 if (rcStrict2 != VINF_SUCCESS) \ 1122 return rcStrict2; \ 1123 } while (0) 1124 1125 1126 /** 1127 * Fetches the next signed word from the opcode stream. 1128 * 1129 * @returns Strict VBox status code. 1130 * @param pIemCpu The IEM state. 1131 * @param pi16 Where to return the signed word. 1132 */ 1133 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS16(PIEMCPU pIemCpu, int16_t *pi16) 1134 { 1135 return iemOpcodeGetNextU16(pIemCpu, (uint16_t *)pi16); 1136 } 1137 1138 1139 /** 1140 * Fetches the next signed word from the opcode stream, returning automatically 1141 * on failure. 1142 * 1143 * @param pi16 Where to return the signed word. 1144 * @remark Implicitly references pIemCpu. 1145 */ 1146 #define IEM_OPCODE_GET_NEXT_S16(a_pi16) \ 1147 do \ 1148 { \ 1149 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS16(pIemCpu, (a_pi16)); \ 1150 if (rcStrict2 != VINF_SUCCESS) \ 1151 return rcStrict2; \ 1152 } while (0) 877 1153 878 1154 … … 903 1179 904 1180 /** 1181 * Fetches the next opcode dword. 1182 * 1183 * @returns Strict VBox status code. 1184 * @param pIemCpu The IEM state. 1185 * @param pu32 Where to return the opcode double word. 1186 */ 1187 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32(PIEMCPU pIemCpu, uint32_t *pu32) 1188 { 1189 uint8_t const offOpcode = pIemCpu->offOpcode; 1190 if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode)) 1191 return iemOpcodeGetNextU32Slow(pIemCpu, pu32); 1192 1193 *pu32 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode], 1194 pIemCpu->abOpcode[offOpcode + 1], 1195 pIemCpu->abOpcode[offOpcode + 2], 1196 pIemCpu->abOpcode[offOpcode + 3]); 1197 pIemCpu->offOpcode = offOpcode + 4; 1198 return VINF_SUCCESS; 1199 } 1200 1201 1202 /** 1203 * Fetches the next opcode dword, returns automatically on failure. 1204 * 1205 * @param a_pu32 Where to return the opcode dword. 1206 * @remark Implicitly references pIemCpu. 1207 */ 1208 #define IEM_OPCODE_GET_NEXT_U32(a_pu32) \ 1209 do \ 1210 { \ 1211 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32(pIemCpu, (a_pu32)); \ 1212 if (rcStrict2 != VINF_SUCCESS) \ 1213 return rcStrict2; \ 1214 } while (0) 1215 1216 1217 /** 1218 * Deals with the problematic cases that iemOpcodeGetNextU32ZxU64 doesn't like. 1219 * 1220 * @returns Strict VBox status code. 1221 * @param pIemCpu The IEM state. 1222 * @param pu32 Where to return the opcode dword. 1223 */ 1224 DECL_NO_INLINE(static, VBOXSTRICTRC) iemOpcodeGetNextU32ZxU64Slow(PIEMCPU pIemCpu, uint64_t *pu64) 1225 { 1226 VBOXSTRICTRC rcStrict = iemOpcodeFetchMoreBytes(pIemCpu, 4); 1227 if (rcStrict == VINF_SUCCESS) 1228 { 1229 uint8_t offOpcode = pIemCpu->offOpcode; 1230 *pu64 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode], 1231 pIemCpu->abOpcode[offOpcode + 1], 1232 pIemCpu->abOpcode[offOpcode + 2], 1233 pIemCpu->abOpcode[offOpcode + 3]); 1234 pIemCpu->offOpcode = offOpcode + 4; 1235 } 1236 else 1237 *pu64 = 0; 1238 return rcStrict; 1239 } 1240 1241 1242 /** 1243 * Fetches the next opcode dword, zero extending it to a quad word. 1244 * 1245 * @returns Strict VBox status code. 1246 * @param pIemCpu The IEM state. 1247 * @param pu64 Where to return the opcode quad word. 1248 */ 1249 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32ZxU64(PIEMCPU pIemCpu, uint64_t *pu64) 1250 { 1251 uint8_t const offOpcode = pIemCpu->offOpcode; 1252 if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode)) 1253 return iemOpcodeGetNextU32ZxU64Slow(pIemCpu, pu64); 1254 1255 *pu64 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode], 1256 pIemCpu->abOpcode[offOpcode + 1], 1257 pIemCpu->abOpcode[offOpcode + 2], 1258 pIemCpu->abOpcode[offOpcode + 3]); 1259 pIemCpu->offOpcode = offOpcode + 4; 1260 return VINF_SUCCESS; 1261 } 1262 1263 1264 /** 1265 * Fetches the next opcode dword and zero extends it to a quad word, returns 1266 * automatically on failure. 1267 * 1268 * @param a_pu64 Where to return the opcode quad word. 1269 * @remark Implicitly references pIemCpu. 1270 */ 1271 #define IEM_OPCODE_GET_NEXT_U32_ZX_U64(a_pu64) \ 1272 do \ 1273 { \ 1274 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32ZxU64(pIemCpu, (a_pu64)); \ 1275 if (rcStrict2 != VINF_SUCCESS) \ 1276 return rcStrict2; \ 1277 } while (0) 1278 1279 1280 /** 1281 * Fetches the next signed double word from the opcode stream. 1282 * 1283 * @returns Strict VBox status code. 1284 * @param pIemCpu The IEM state. 1285 * @param pi32 Where to return the signed double word. 1286 */ 1287 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32(PIEMCPU pIemCpu, int32_t *pi32) 1288 { 1289 return iemOpcodeGetNextU32(pIemCpu, (uint32_t *)pi32); 1290 } 1291 1292 /** 1293 * Fetches the next signed double word from the opcode stream, returning 1294 * automatically on failure. 1295 * 1296 * @param pi32 Where to return the signed double word. 1297 * @remark Implicitly references pIemCpu. 1298 */ 1299 #define IEM_OPCODE_GET_NEXT_S32(a_pi32) \ 1300 do \ 1301 { \ 1302 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32(pIemCpu, (a_pi32)); \ 1303 if (rcStrict2 != VINF_SUCCESS) \ 1304 return rcStrict2; \ 1305 } while (0) 1306 1307 1308 /** 905 1309 * Deals with the problematic cases that iemOpcodeGetNextS32SxU64 doesn't like. 906 1310 * … … 925 1329 return rcStrict; 926 1330 } 1331 1332 1333 /** 1334 * Fetches the next opcode dword, sign extending it into a quad word. 1335 * 1336 * @returns Strict VBox status code. 1337 * @param pIemCpu The IEM state. 1338 * @param pu64 Where to return the opcode quad word. 1339 */ 1340 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32SxU64(PIEMCPU pIemCpu, uint64_t *pu64) 1341 { 1342 uint8_t const offOpcode = pIemCpu->offOpcode; 1343 if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode)) 1344 return iemOpcodeGetNextS32SxU64Slow(pIemCpu, pu64); 1345 1346 int32_t i32 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode], 1347 pIemCpu->abOpcode[offOpcode + 1], 1348 pIemCpu->abOpcode[offOpcode + 2], 1349 pIemCpu->abOpcode[offOpcode + 3]); 1350 *pu64 = i32; 1351 pIemCpu->offOpcode = offOpcode + 4; 1352 return VINF_SUCCESS; 1353 } 1354 1355 1356 /** 1357 * Fetches the next opcode double word and sign extends it to a quad word, 1358 * returns automatically on failure. 1359 * 1360 * @param a_pu64 Where to return the opcode quad word. 1361 * @remark Implicitly references pIemCpu. 1362 */ 1363 #define IEM_OPCODE_GET_NEXT_S32_SX_U64(a_pu64) \ 1364 do \ 1365 { \ 1366 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32SxU64(pIemCpu, (a_pu64)); \ 1367 if (rcStrict2 != VINF_SUCCESS) \ 1368 return rcStrict2; \ 1369 } while (0) 927 1370 928 1371 … … 957 1400 958 1401 /** 959 * Fetches the next opcode byte.960 *961 * @returns Strict VBox status code.962 * @param pIemCpu The IEM state.963 * @param pu8 Where to return the opcode byte.964 */965 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU8(PIEMCPU pIemCpu, uint8_t *pu8)966 {967 uint8_t const offOpcode = pIemCpu->offOpcode;968 if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode))969 return iemOpcodeGetNextByteSlow(pIemCpu, pu8);970 971 *pu8 = pIemCpu->abOpcode[offOpcode];972 pIemCpu->offOpcode = offOpcode + 1;973 return VINF_SUCCESS;974 }975 976 /**977 * Fetches the next opcode byte, returns automatically on failure.978 *979 * @param a_pu8 Where to return the opcode byte.980 * @remark Implicitly references pIemCpu.981 */982 #define IEM_OPCODE_GET_NEXT_U8(a_pu8) \983 do \984 { \985 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU8(pIemCpu, (a_pu8)); \986 if (rcStrict2 != VINF_SUCCESS) \987 return rcStrict2; \988 } while (0)989 990 991 /**992 * Fetches the next signed byte from the opcode stream.993 *994 * @returns Strict VBox status code.995 * @param pIemCpu The IEM state.996 * @param pi8 Where to return the signed byte.997 */998 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8(PIEMCPU pIemCpu, int8_t *pi8)999 {1000 return iemOpcodeGetNextU8(pIemCpu, (uint8_t *)pi8);1001 }1002 1003 /**1004 * Fetches the next signed byte from the opcode stream, returning automatically1005 * on failure.1006 *1007 * @param pi8 Where to return the signed byte.1008 * @remark Implicitly references pIemCpu.1009 */1010 #define IEM_OPCODE_GET_NEXT_S8(a_pi8) \1011 do \1012 { \1013 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8(pIemCpu, (a_pi8)); \1014 if (rcStrict2 != VINF_SUCCESS) \1015 return rcStrict2; \1016 } while (0)1017 1018 1019 /**1020 * Fetches the next signed byte from the opcode stream, extending it to1021 * unsigned 16-bit.1022 *1023 * @returns Strict VBox status code.1024 * @param pIemCpu The IEM state.1025 * @param pu16 Where to return the unsigned word.1026 */1027 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU16(PIEMCPU pIemCpu, uint16_t *pu16)1028 {1029 uint8_t const offOpcode = pIemCpu->offOpcode;1030 if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode))1031 return iemOpcodeGetNextS8SxU16Slow(pIemCpu, pu16);1032 1033 *pu16 = (int8_t)pIemCpu->abOpcode[offOpcode];1034 pIemCpu->offOpcode = offOpcode + 1;1035 return VINF_SUCCESS;1036 }1037 1038 1039 /**1040 * Fetches the next signed byte from the opcode stream and sign-extending it to1041 * a word, returning automatically on failure.1042 *1043 * @param pu16 Where to return the word.1044 * @remark Implicitly references pIemCpu.1045 */1046 #define IEM_OPCODE_GET_NEXT_S8_SX_U16(a_pu16) \1047 do \1048 { \1049 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU16(pIemCpu, (a_pu16)); \1050 if (rcStrict2 != VINF_SUCCESS) \1051 return rcStrict2; \1052 } while (0)1053 1054 1055 /**1056 * Fetches the next opcode word.1057 *1058 * @returns Strict VBox status code.1059 * @param pIemCpu The IEM state.1060 * @param pu16 Where to return the opcode word.1061 */1062 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16(PIEMCPU pIemCpu, uint16_t *pu16)1063 {1064 uint8_t const offOpcode = pIemCpu->offOpcode;1065 if (RT_UNLIKELY(offOpcode + 2 > pIemCpu->cbOpcode))1066 return iemOpcodeGetNextU16Slow(pIemCpu, pu16);1067 1068 *pu16 = RT_MAKE_U16(pIemCpu->abOpcode[offOpcode], pIemCpu->abOpcode[offOpcode + 1]);1069 pIemCpu->offOpcode = offOpcode + 2;1070 return VINF_SUCCESS;1071 }1072 1073 /**1074 * Fetches the next opcode word, returns automatically on failure.1075 *1076 * @param a_pu16 Where to return the opcode word.1077 * @remark Implicitly references pIemCpu.1078 */1079 #define IEM_OPCODE_GET_NEXT_U16(a_pu16) \1080 do \1081 { \1082 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16(pIemCpu, (a_pu16)); \1083 if (rcStrict2 != VINF_SUCCESS) \1084 return rcStrict2; \1085 } while (0)1086 1087 1088 /**1089 * Fetches the next signed word from the opcode stream.1090 *1091 * @returns Strict VBox status code.1092 * @param pIemCpu The IEM state.1093 * @param pi16 Where to return the signed word.1094 */1095 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS16(PIEMCPU pIemCpu, int16_t *pi16)1096 {1097 return iemOpcodeGetNextU16(pIemCpu, (uint16_t *)pi16);1098 }1099 1100 /**1101 * Fetches the next signed word from the opcode stream, returning automatically1102 * on failure.1103 *1104 * @param pi16 Where to return the signed word.1105 * @remark Implicitly references pIemCpu.1106 */1107 #define IEM_OPCODE_GET_NEXT_S16(a_pi16) \1108 do \1109 { \1110 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS16(pIemCpu, (a_pi16)); \1111 if (rcStrict2 != VINF_SUCCESS) \1112 return rcStrict2; \1113 } while (0)1114 1115 1116 /**1117 * Fetches the next opcode dword.1118 *1119 * @returns Strict VBox status code.1120 * @param pIemCpu The IEM state.1121 * @param pu32 Where to return the opcode double word.1122 */1123 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32(PIEMCPU pIemCpu, uint32_t *pu32)1124 {1125 uint8_t const offOpcode = pIemCpu->offOpcode;1126 if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode))1127 return iemOpcodeGetNextU32Slow(pIemCpu, pu32);1128 1129 *pu32 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],1130 pIemCpu->abOpcode[offOpcode + 1],1131 pIemCpu->abOpcode[offOpcode + 2],1132 pIemCpu->abOpcode[offOpcode + 3]);1133 pIemCpu->offOpcode = offOpcode + 4;1134 return VINF_SUCCESS;1135 }1136 1137 /**1138 * Fetches the next opcode dword, returns automatically on failure.1139 *1140 * @param a_u32 Where to return the opcode dword.1141 * @remark Implicitly references pIemCpu.1142 */1143 #define IEM_OPCODE_GET_NEXT_U32(a_pu32) \1144 do \1145 { \1146 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32(pIemCpu, (a_pu32)); \1147 if (rcStrict2 != VINF_SUCCESS) \1148 return rcStrict2; \1149 } while (0)1150 1151 1152 /**1153 * Fetches the next signed double word from the opcode stream.1154 *1155 * @returns Strict VBox status code.1156 * @param pIemCpu The IEM state.1157 * @param pi32 Where to return the signed double word.1158 */1159 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32(PIEMCPU pIemCpu, int32_t *pi32)1160 {1161 return iemOpcodeGetNextU32(pIemCpu, (uint32_t *)pi32);1162 }1163 1164 /**1165 * Fetches the next signed double word from the opcode stream, returning1166 * automatically on failure.1167 *1168 * @param pi32 Where to return the signed double word.1169 * @remark Implicitly references pIemCpu.1170 */1171 #define IEM_OPCODE_GET_NEXT_S32(a_pi32) \1172 do \1173 { \1174 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32(pIemCpu, (a_pi32)); \1175 if (rcStrict2 != VINF_SUCCESS) \1176 return rcStrict2; \1177 } while (0)1178 1179 1180 /**1181 * Fetches the next opcode dword, sign extending it into a quad word.1182 *1183 * @returns Strict VBox status code.1184 * @param pIemCpu The IEM state.1185 * @param pu64 Where to return the opcode quad word.1186 */1187 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32SxU64(PIEMCPU pIemCpu, uint64_t *pu64)1188 {1189 uint8_t const offOpcode = pIemCpu->offOpcode;1190 if (RT_UNLIKELY(offOpcode + 4 > pIemCpu->cbOpcode))1191 return iemOpcodeGetNextS32SxU64Slow(pIemCpu, pu64);1192 1193 int32_t i32 = RT_MAKE_U32_FROM_U8(pIemCpu->abOpcode[offOpcode],1194 pIemCpu->abOpcode[offOpcode + 1],1195 pIemCpu->abOpcode[offOpcode + 2],1196 pIemCpu->abOpcode[offOpcode + 3]);1197 *pu64 = i32;1198 pIemCpu->offOpcode = offOpcode + 4;1199 return VINF_SUCCESS;1200 }1201 1202 /**1203 * Fetches the next opcode double word and sign extends it to a quad word,1204 * returns automatically on failure.1205 *1206 * @param a_pu64 Where to return the opcode quad word.1207 * @remark Implicitly references pIemCpu.1208 */1209 #define IEM_OPCODE_GET_NEXT_S32_SX_U64(a_pu64) \1210 do \1211 { \1212 VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32SxU64(pIemCpu, (a_pu64)); \1213 if (rcStrict2 != VINF_SUCCESS) \1214 return rcStrict2; \1215 } while (0)1216 1217 1218 /**1219 1402 * Fetches the next opcode qword. 1220 1403 * … … 1240 1423 return VINF_SUCCESS; 1241 1424 } 1425 1242 1426 1243 1427 /** -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
r39125 r39127 7798 7798 IEM_OPCODE_GET_NEXT_U32(&offSeg); 7799 7799 else 7800 { 7801 uint16_t offSeg16; IEM_OPCODE_GET_NEXT_U16(&offSeg16); /** @todo add GET_NEXT_U16_ZX_U32 to reduce code size. */ 7802 offSeg = offSeg16; 7803 } 7800 IEM_OPCODE_GET_NEXT_U16_ZX_U32(&offSeg); 7804 7801 uint16_t uSel; IEM_OPCODE_GET_NEXT_U16(&uSel); 7805 7802 IEMOP_HLP_NO_LOCK_PREFIX(); … … 7895 7892 { \ 7896 7893 case IEMMODE_16BIT: \ 7897 { \ 7898 uint16_t u16Off; IEM_OPCODE_GET_NEXT_U16(&u16Off); \ 7899 (a_GCPtrMemOff) = u16Off; \ 7894 IEM_OPCODE_GET_NEXT_U16_ZX_U64(&(a_GCPtrMemOff)); \ 7900 7895 break; \ 7901 } \7902 7896 case IEMMODE_32BIT: \ 7903 { \ 7904 uint32_t u32Off; IEM_OPCODE_GET_NEXT_U32(&u32Off); \ 7905 (a_GCPtrMemOff) = u32Off; \ 7897 IEM_OPCODE_GET_NEXT_U32_ZX_U64(&(a_GCPtrMemOff)); \ 7906 7898 break; \ 7907 } \7908 7899 case IEMMODE_64BIT: \ 7909 7900 IEM_OPCODE_GET_NEXT_U64(&(a_GCPtrMemOff)); \ … … 10401 10392 { 10402 10393 uint16_t u16Imm; IEM_OPCODE_GET_NEXT_U16(&u16Imm); 10403 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_call_rel_16, (int 32_t)u16Imm);10394 return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_call_rel_16, (int16_t)u16Imm); 10404 10395 } 10405 10396 … … 10463 10454 IEM_OPCODE_GET_NEXT_U32(&offSeg); 10464 10455 else 10465 { 10466 uint16_t offSeg16; IEM_OPCODE_GET_NEXT_U16(&offSeg16); 10467 offSeg = offSeg16; 10468 } 10456 IEM_OPCODE_GET_NEXT_U16_ZX_U32(&offSeg); 10469 10457 uint16_t uSel; IEM_OPCODE_GET_NEXT_U16(&uSel); 10470 10458 IEMOP_HLP_NO_LOCK_PREFIX(); -
trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp
r39125 r39127 79 79 #define IEM_OPCODE_GET_NEXT_U8(a_pu8) do { *(a_pu8) = g_bRandom; CHK_PTYPE(uint8_t *, a_pu8); } while (0) 80 80 #define IEM_OPCODE_GET_NEXT_U16(a_pu16) do { *(a_pu16) = g_bRandom; CHK_PTYPE(uint16_t *, a_pu16); } while (0) 81 #define IEM_OPCODE_GET_NEXT_U16_ZX_U32(a_pu32) do { *(a_pu32) = g_bRandom; CHK_PTYPE(uint32_t *, a_pu32); } while (0) 82 #define IEM_OPCODE_GET_NEXT_U16_ZX_U64(a_pu64) do { *(a_pu64) = g_bRandom; CHK_PTYPE(uint64_t *, a_pu64); } while (0) 81 83 #define IEM_OPCODE_GET_NEXT_U32(a_pu32) do { *(a_pu32) = g_bRandom; CHK_PTYPE(uint32_t *, a_pu32); } while (0) 84 #define IEM_OPCODE_GET_NEXT_U32_ZX_U64(a_pu64) do { *(a_pu64) = g_bRandom; CHK_PTYPE(uint64_t *, a_pu64); } while (0) 82 85 #define IEM_OPCODE_GET_NEXT_S32_SX_U64(a_pu64) do { *(a_pu64) = g_bRandom; CHK_PTYPE(uint64_t *, a_pu64); } while (0) 83 86 #define IEM_OPCODE_GET_NEXT_U64(a_pu64) do { *(a_pu64) = g_bRandom; CHK_PTYPE(uint64_t *, a_pu64); } while (0)
Note:
See TracChangeset
for help on using the changeset viewer.