Changeset 66419 in vbox
- Timestamp:
- Apr 4, 2017 3:49:07 PM (8 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsOneByte.cpp.h
r66160 r66419 6173 6173 FNIEMOP_DEF(iemOp_les_Gv_Mp__vex2) 6174 6174 { 6175 /* The LES instruction is invalid 64-bit mode. In legacy and6176 compatability mode it is invalid with MOD=3.6177 The use as a VEX prefix is made possible by assigning the inverted6178 REX.R to the top MOD bit, and the top bit in the inverted register6179 specifier to the bottom MOD bit, thereby effectively limiting 32-bit6180 to accessing registers 0..7 in this VEX form. */6181 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);6182 if ( pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT6183 || (bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))6184 {6185 IEMOP_MNEMONIC(vex2_prefix, "vex2");6186 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx)6187 {6188 uint8_t bOpcode; IEM_OPCODE_GET_NEXT_U8(&bOpcode);6189 if ( ( pVCpu->iem.s.fPrefixes6190 & (IEM_OP_PRF_SIZE_OP | IEM_OP_PRF_REPZ | IEM_OP_PRF_REPNZ | IEM_OP_PRF_LOCK | IEM_OP_PRF_REX))6191 == 0)6192 {6193 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_VEX;6194 pVCpu->iem.s.uRexReg = ~bRm >> (7 - 3);6195 pVCpu->iem.s.uVex3rdReg = (~bRm >> 3) & 0xf;6196 pVCpu->iem.s.uVexLength = (bRm >> 2) & 1;6197 pVCpu->iem.s.idxPrefix = bRm & 0x3;6198 6199 return FNIEMOP_CALL(g_apfnVexMap1[(uintptr_t)bOpcode * 4 + pVCpu->iem.s.idxPrefix]);6200 }6201 6202 Log(("VEX2: Invalid prefix mix!\n"));6203 }6204 else6205 Log(("VEX2: AVX support disabled!\n"));6206 6207 /* @todo does intel completely decode the sequence with SIB/disp before \#UD? */6208 return IEMOP_RAISE_INVALID_OPCODE();6209 }6210 IEMOP_MNEMONIC(les_Gv_Mp, "les Gv,Mp");6211 return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_ES, bRm);6212 }6213 6214 6215 /**6216 * @opcode 0xc56217 */6218 FNIEMOP_DEF(iemOp_lds_Gv_Mp__vex3)6219 {6220 6175 /* The LDS instruction is invalid 64-bit mode. In legacy and 6221 6176 compatability mode it is invalid with MOD=3. … … 6228 6183 if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT)) 6229 6184 { 6230 IEMOP_MNEMONIC(l ds_Gv_Mp, "lds Gv,Mp");6231 return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_ DS, bRm);6185 IEMOP_MNEMONIC(les_Gv_Mp, "les Gv,Mp"); 6186 return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_ES, bRm); 6232 6187 } 6233 6188 IEMOP_HLP_NO_REAL_OR_V86_MODE(); … … 6281 6236 Log(("VEX3: AVX support disabled!\n")); 6282 6237 return IEMOP_RAISE_INVALID_OPCODE(); 6238 } 6239 6240 6241 /** 6242 * @opcode 0xc5 6243 */ 6244 FNIEMOP_DEF(iemOp_lds_Gv_Mp__vex3) 6245 { 6246 /* The LES instruction is invalid 64-bit mode. In legacy and 6247 compatability mode it is invalid with MOD=3. 6248 The use as a VEX prefix is made possible by assigning the inverted 6249 REX.R to the top MOD bit, and the top bit in the inverted register 6250 specifier to the bottom MOD bit, thereby effectively limiting 32-bit 6251 to accessing registers 0..7 in this VEX form. */ 6252 uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); 6253 if ( pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT 6254 || (bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT)) 6255 { 6256 IEMOP_MNEMONIC(vex2_prefix, "vex2"); 6257 if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx) 6258 { 6259 uint8_t bOpcode; IEM_OPCODE_GET_NEXT_U8(&bOpcode); 6260 if ( ( pVCpu->iem.s.fPrefixes 6261 & (IEM_OP_PRF_SIZE_OP | IEM_OP_PRF_REPZ | IEM_OP_PRF_REPNZ | IEM_OP_PRF_LOCK | IEM_OP_PRF_REX)) 6262 == 0) 6263 { 6264 pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_VEX; 6265 pVCpu->iem.s.uRexReg = ~bRm >> (7 - 3); 6266 pVCpu->iem.s.uVex3rdReg = (~bRm >> 3) & 0xf; 6267 pVCpu->iem.s.uVexLength = (bRm >> 2) & 1; 6268 pVCpu->iem.s.idxPrefix = bRm & 0x3; 6269 6270 return FNIEMOP_CALL(g_apfnVexMap1[(uintptr_t)bOpcode * 4 + pVCpu->iem.s.idxPrefix]); 6271 } 6272 6273 Log(("VEX2: Invalid prefix mix!\n")); 6274 } 6275 else 6276 Log(("VEX2: AVX support disabled!\n")); 6277 6278 /* @todo does intel completely decode the sequence with SIB/disp before \#UD? */ 6279 return IEMOP_RAISE_INVALID_OPCODE(); 6280 } 6281 6282 IEMOP_MNEMONIC(lds_Gv_Mp, "lds Gv,Mp"); 6283 return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_DS, bRm); 6283 6284 } 6284 6285 … … 11753 11754 /* 0xbc */ iemOp_eSP_Iv, iemOp_eBP_Iv, iemOp_eSI_Iv, iemOp_eDI_Iv, 11754 11755 /* 0xc0 */ iemOp_Grp2_Eb_Ib, iemOp_Grp2_Ev_Ib, iemOp_retn_Iw, iemOp_retn, 11755 /* 0xc4 */ iemOp_les_Gv_Mp__vex 2, iemOp_lds_Gv_Mp__vex3, iemOp_Grp11_Eb_Ib, iemOp_Grp11_Ev_Iz,11756 /* 0xc4 */ iemOp_les_Gv_Mp__vex3, iemOp_lds_Gv_Mp__vex2, iemOp_Grp11_Eb_Ib, iemOp_Grp11_Ev_Iz, 11756 11757 /* 0xc8 */ iemOp_enter_Iw_Ib, iemOp_leave, iemOp_retf_Iw, iemOp_retf, 11757 11758 /* 0xcc */ iemOp_int3, iemOp_int_Ib, iemOp_into, iemOp_iret, -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py
r66412 r66419 268 268 269 269 ## IEMFORM_XXX mappings. 270 g_kdIemForms = { # sEncoding, [ sWhere1, ... ] 271 'RM': ( 'ModR/M', [ 'reg', 'rm' ], ), 272 'RM_REG': ( 'ModR/M', [ 'reg', 'rm' ], ), 273 'RM_MEM': ( 'ModR/M', [ 'reg', 'rm' ], ), 274 'MR': ( 'ModR/M', [ 'rm', 'reg' ], ), 275 'MR_REG': ( 'ModR/M', [ 'rm', 'reg' ], ), 276 'MR_MEM': ( 'ModR/M', [ 'rm', 'reg' ], ), 277 'M': ( 'ModR/M', [ 'rm', ], ), 278 'M_REG': ( 'ModR/M', [ 'rm', ], ), 279 'M_MEM': ( 'ModR/M', [ 'rm', ], ), 280 'R': ( 'ModR/M', [ 'reg', ], ), 281 'RVM': ( 'ModR/M+VEX', [ 'reg', 'vvvv', 'rm'], ), 282 'MVR': ( 'ModR/M+VEX', [ 'rm', 'vvvv', 'reg'], ), 283 'FIXED': ( 'fixed', None, ) 270 g_kdIemForms = { # sEncoding, [ sWhere1, ... ] 271 'RM': ( 'ModR/M', [ 'reg', 'rm' ], ), 272 'RM_REG': ( 'ModR/M', [ 'reg', 'rm' ], ), 273 'RM_MEM': ( 'ModR/M', [ 'reg', 'rm' ], ), 274 'MR': ( 'ModR/M', [ 'rm', 'reg' ], ), 275 'MR_REG': ( 'ModR/M', [ 'rm', 'reg' ], ), 276 'MR_MEM': ( 'ModR/M', [ 'rm', 'reg' ], ), 277 'M': ( 'ModR/M', [ 'rm', ], ), 278 'M_REG': ( 'ModR/M', [ 'rm', ], ), 279 'M_MEM': ( 'ModR/M', [ 'rm', ], ), 280 'R': ( 'ModR/M', [ 'reg', ], ), 281 282 'VEX_RM': ( 'VEX.ModR/M', [ 'reg', 'rm' ], ), 283 'VEX_RM_REG': ( 'VEX.ModR/M', [ 'reg', 'rm' ], ), 284 'VEX_RM_MEM': ( 'VEX.ModR/M', [ 'reg', 'rm' ], ), 285 'VEX_MR': ( 'VEX.ModR/M', [ 'rm', 'reg' ], ), 286 'VEX_MR_REG': ( 'VEX.ModR/M', [ 'rm', 'reg' ], ), 287 'VEX_MR_MEM': ( 'VEX.ModR/M', [ 'rm', 'reg' ], ), 288 'VEX_M': ( 'VEX.ModR/M', [ 'rm', ], ), 289 'VEX_M_REG': ( 'VEX.ModR/M', [ 'rm', ], ), 290 'VEX_M_MEM': ( 'VEX.ModR/M', [ 'rm', ], ), 291 'VEX_R': ( 'VEX.ModR/M', [ 'reg', ], ), 292 'VEX_RVM': ( 'VEX.ModR/M', [ 'reg', 'vvvv', 'rm'], ), 293 'VEX_MVR': ( 'VEX.ModR/M', [ 'rm', 'vvvv', 'reg'], ), 294 295 'FIXED': ( 'fixed', None, ) 284 296 }; 285 297 … … 313 325 ## Valid values for \@openc 314 326 g_kdEncodings = { 315 'ModR/M': [ 'BS3CG1ENC_MODRM', ], ##< ModR/M 316 'fixed': [ 'BS3CG1ENC_FIXED', ], ##< Fixed encoding (address, registers, etc). 317 'prefix': [ None, ], ##< Prefix 327 'ModR/M': [ 'BS3CG1ENC_MODRM', ], ##< ModR/M 328 'VEX.ModR/M': [ 'BS3CG1ENC_VEX_MODRM', ], ##< VEX...ModR/M 329 'fixed': [ 'BS3CG1ENC_FIXED', ], ##< Fixed encoding (address, registers, etc). 330 'prefix': [ None, ], ##< Prefix 318 331 }; 319 332 -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h
r66414 r66419 5903 5903 * @opcode !11/3 5904 5904 * @oppfx none 5905 * @opcpuid sse5905 * @opcpuid avx 5906 5906 * @opgroup og_avx_mxcsrsm 5907 * @optest ignmxcsr=0 -> op1=05908 * @optest ignmxcsr=0x2083 -> op1=0x20835907 * @optest mxcsr=0 -> op1=0 5908 * @optest mxcsr=0x2083 -> op1=0x2083 5909 5909 * @optestign mxcsr=0x2084 cr0|=ts -> value.xcpt=0x7 5910 5910 * @optestign mxcsr=0x2085 cr0|=em -> value.xcpt=0x6 … … 5915 5915 * @optestign mxcsr=0x208a cr0|=ts,em cr4&~=osfxsr -> value.xcpt=0x6 5916 5916 * @optestign mxcsr=0x208b cr0|=ts,em,mp cr4&~=osfxsr -> value.xcpt=0x6 5917 * @oponlytest 5917 5918 */ 5918 5919 FNIEMOP_DEF_1(iemOp_VGrp15_vstmxcsr, uint8_t, bRm) 5919 5920 { 5920 IEMOP_MNEMONIC1( M_MEM, VSTMXCSR, vstmxcsr, MdWO, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZE);5921 IEMOP_MNEMONIC1(VEX_M_MEM, VSTMXCSR, vstmxcsr, MdWO, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZE); 5921 5922 if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx) 5922 5923 return IEMOP_RAISE_INVALID_OPCODE(); -
trunk/src/VBox/VMM/include/IEMInternal.h
r66321 r66419 867 867 #define IEMOPFORM_R 3 868 868 869 /** ModR/M + VEX.vvvv: reg, vvvv, r/m */ 870 #define IEMOPFORM_RVM 4 871 872 /** ModR/M + VEX.vvvv: r/m, vvvv, reg */ 873 #define IEMOPFORM_MVR 5 869 /** VEX+ModR/M: reg, r/m */ 870 #define IEMOPFORM_VEX_RM 4 871 /** VEX+ModR/M: reg, r/m (register) */ 872 #define IEMOPFORM_VEX_RM_REG (IEMOPFORM_VEX_RM | IEMOPFORM_MOD3) 873 /** VEX+ModR/M: reg, r/m (memory) */ 874 #define IEMOPFORM_VEX_RM_MEM (IEMOPFORM_VEX_RM | IEMOPFORM_NOT_MOD3) 875 /** VEX+ModR/M: r/m, reg */ 876 #define IEMOPFORM_VEX_MR 5 877 /** VEX+ModR/M: r/m (register), reg */ 878 #define IEMOPFORM_VEX_MR_REG (IEMOPFORM_VEX_MR | IEMOPFORM_MOD3) 879 /** VEX+ModR/M: r/m (memory), reg */ 880 #define IEMOPFORM_VEX_MR_MEM (IEMOPFORM_VEX_MR | IEMOPFORM_NOT_MOD3) 881 /** VEX+ModR/M: r/m only */ 882 #define IEMOPFORM_VEX_M 6 883 /** VEX+ModR/M: r/m only (register). */ 884 #define IEMOPFORM_VEX_M_REG (IEMOPFORM_VEX_M | IEMOPFORM_MOD3) 885 /** VEX+ModR/M: r/m only (memory). */ 886 #define IEMOPFORM_VEX_M_MEM (IEMOPFORM_VEX_M | IEMOPFORM_NOT_MOD3) 887 /** VEX+ModR/M: reg only */ 888 #define IEMOPFORM_VEX_R 7 889 /** VEX+ModR/M: reg, vvvv, r/m */ 890 #define IEMOPFORM_VEX_RVM 8 891 /** VEX+ModR/M: r/m, vvvv, reg */ 892 #define IEMOPFORM_VEX_MVR 9 874 893 875 894 /** Fixed register instruction, no R/M. */ 876 #define IEMOPFORM_FIXED 6895 #define IEMOPFORM_FIXED 16 877 896 878 897 /** The r/m is a register. */ -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1-template.c
r66408 r66419 1055 1055 1056 1056 1057 /** 1058 * Inserts a 2-byte VEX prefix. 1059 * 1060 * @returns New offDst value. 1061 * @param pThis The state. 1062 * @param offDst The current instruction offset. 1063 * @param uVexL The VEX.L value. 1064 * @param uVexV The VEX.V value (caller inverted it already). 1065 * @param uVexR The VEX.R value (caller inverted it already). 1066 */ 1067 DECLINLINE(unsigned) Bs3Cg1InsertVex2bPrefix(PBS3CG1STATE pThis, unsigned offDst, uint8_t uVexV, uint8_t uVexL, uint8_t uVexR) 1068 { 1069 uint8_t b = uVexR << 7; 1070 b |= uVexV << 3; 1071 b |= uVexL << 2; 1072 switch (pThis->enmPrefixKind) 1073 { 1074 case BS3CG1PFXKIND_NO_F2_F3_66: b |= 0; break; 1075 case BS3CG1PFXKIND_REQ_66: b |= 1; break; 1076 case BS3CG1PFXKIND_REQ_F3: b |= 2; break; 1077 case BS3CG1PFXKIND_REQ_F2: b |= 3; break; 1078 default: 1079 Bs3TestFailedF("enmPrefixKind=%d not supported for VEX!\n"); 1080 break; 1081 } 1082 1083 pThis->abCurInstr[offDst] = 0xc5; /* vex2 */ 1084 pThis->abCurInstr[offDst + 1] = b; 1085 return offDst + 2; 1086 } 1087 1088 1089 /** 1090 * Inserts a 3-byte VEX prefix. 1091 * 1092 * @returns New offDst value. 1093 * @param pThis The state. 1094 * @param offDst The current instruction offset. 1095 * @param uVexL The VEX.L value. 1096 * @param uVexV The VEX.V value (caller inverted it already). 1097 * @param uVexR The VEX.R value (caller inverted it already). 1098 * @param uVexR The VEX.X value (caller inverted it already). 1099 * @param uVexR The VEX.B value (caller inverted it already). 1100 * @param uVexR The VEX.W value (straight). 1101 */ 1102 DECLINLINE(unsigned) Bs3Cg1InsertVex3bPrefix(PBS3CG1STATE pThis, unsigned offDst, uint8_t uVexV, uint8_t uVexL, 1103 uint8_t uVexR, uint8_t uVexX, uint8_t uVexB, uint8_t uVexW) 1104 { 1105 uint8_t b1; 1106 uint8_t b2; 1107 b1 = uVexR << 7; 1108 b1 |= uVexX << 6; 1109 b1 |= uVexB << 5; 1110 b1 |= 1; /* VEX.mmmmm = 1*/ /** @todo three byte opcode tables */ 1111 b2 = uVexV << 3; 1112 b2 |= uVexW << 7; 1113 b2 |= uVexL << 2; 1114 switch (pThis->enmPrefixKind) 1115 { 1116 case BS3CG1PFXKIND_NO_F2_F3_66: b2 |= 0; break; 1117 case BS3CG1PFXKIND_REQ_66: b2 |= 1; break; 1118 case BS3CG1PFXKIND_REQ_F3: b2 |= 2; break; 1119 case BS3CG1PFXKIND_REQ_F2: b2 |= 3; break; 1120 default: 1121 Bs3TestFailedF("enmPrefixKind=%d not supported for VEX!\n"); 1122 break; 1123 } 1124 1125 pThis->abCurInstr[offDst] = 0xc4; /* vex3 */ 1126 pThis->abCurInstr[offDst + 1] = b1; 1127 pThis->abCurInstr[offDst + 2] = b2; 1128 return offDst + 3; 1129 } 1130 1131 1057 1132 DECLINLINE(unsigned) Bs3Cg1InsertReqPrefix(PBS3CG1STATE pThis, unsigned offDst) 1058 1133 { … … 1186 1261 1187 1262 1263 unsigned Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Eb_Gb(PBS3CG1STATE pThis, unsigned iEncoding, bool *pfInvalidInstr) 1264 { 1265 unsigned off; 1266 /* Start by reg,reg encoding. */ 1267 if (iEncoding == 0) 1268 { 1269 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)); 1270 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX); 1271 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL; 1272 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL; 1273 } 1274 else if (iEncoding == 1) 1275 { 1276 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_CH; 1277 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)); 1278 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, 1, 0, BS3CG1OPLOC_MEM_RW); 1279 } 1280 else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386) 1281 { 1282 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_BH; 1283 pThis->abCurInstr[0] = P_AZ; 1284 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1)); 1285 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, 1, 0, BS3CG1OPLOC_MEM_RW); 1286 } 1287 else 1288 return 0; 1289 pThis->cbCurInstr = off; 1290 return iEncoding + 1; 1291 } 1292 1293 1294 unsigned Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Gb_Eb(PBS3CG1STATE pThis, unsigned iEncoding, bool *pfInvalidInstr) 1295 { 1296 unsigned off; 1297 /* Start by reg,reg encoding. */ 1298 if (iEncoding == 0) 1299 { 1300 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)); 1301 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX); 1302 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL; 1303 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL; 1304 } 1305 else if (iEncoding == 1) 1306 { 1307 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_CH; 1308 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)); 1309 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, 1, 0, BS3CG1OPLOC_MEM); 1310 } 1311 else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386) 1312 { 1313 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_BH; 1314 pThis->abCurInstr[0] = P_AZ; 1315 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1)); 1316 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, 1, 0, BS3CG1OPLOC_MEM); 1317 } 1318 else 1319 return 0; 1320 pThis->cbCurInstr = off; 1321 return iEncoding + 1; 1322 } 1323 1324 1325 unsigned Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Gv_Ev__OR__BS3CG1ENC_MODRM_Ev_Gv(PBS3CG1STATE pThis, 1326 unsigned iEncoding, bool *pfInvalidInstr) 1327 { 1328 unsigned off; 1329 unsigned cbOp; 1330 if (iEncoding == 0) 1331 { 1332 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4; 1333 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)); 1334 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX); 1335 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RBX; 1336 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_OZ_RDX; 1337 } 1338 else if (iEncoding == 1) 1339 { 1340 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4; 1341 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RBP; 1342 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)); 1343 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, cbOp, 0, 1344 pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW); 1345 } 1346 else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386) 1347 { 1348 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2; 1349 pThis->abCurInstr[0] = P_OZ; 1350 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1)); 1351 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX); 1352 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RBX; 1353 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_OZ_RDX; 1354 pThis->aOperands[pThis->iRmOp ].enmLocation = BS3CG1OPLOC_CTX; 1355 } 1356 else if (iEncoding == 3) 1357 { 1358 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2; 1359 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RSI; 1360 pThis->abCurInstr[0] = P_OZ; 1361 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1)); 1362 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xSI, cbOp, 0, 1363 pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW); 1364 } 1365 else if (iEncoding == 4) 1366 { 1367 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4; 1368 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RDI; 1369 pThis->abCurInstr[0] = P_AZ; 1370 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1)); 1371 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, cbOp, 0, 1372 pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW); 1373 } 1374 else if (iEncoding == 5) 1375 { 1376 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2; 1377 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RSI; 1378 pThis->abCurInstr[0] = P_OZ; 1379 pThis->abCurInstr[1] = P_AZ; 1380 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 2)); 1381 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xSI, cbOp, 0, 1382 pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW); 1383 } 1384 else if (iEncoding == 6 && BS3_MODE_IS_64BIT_CODE(pThis->bMode)) 1385 { 1386 cbOp = 8; 1387 off = Bs3Cg1InsertReqPrefix(pThis, 0); 1388 pThis->abCurInstr[off++] = REX_W___; 1389 off = Bs3Cg1InsertOpcodes(pThis, off); 1390 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX); 1391 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_RBX; 1392 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_RDX; 1393 pThis->aOperands[pThis->iRmOp ].enmLocation = BS3CG1OPLOC_CTX; 1394 } 1395 else 1396 return 0; 1397 pThis->aOperands[0].cbOp = cbOp; 1398 pThis->aOperands[1].cbOp = cbOp; 1399 pThis->cbOperand = cbOp; 1400 pThis->cbCurInstr = off; 1401 return iEncoding + 1; 1402 } 1403 1404 1405 1406 static unsigned Bs3Cg1EncodeNext_BS3CG1ENC_VEX_MODRM_MdWO(PBS3CG1STATE pThis, unsigned iEncoding, bool *pfInvalidInstr) 1407 { 1408 unsigned off; 1409 if (iEncoding == 0) 1410 { 1411 /** @todo three by opcode needs some tweaking. */ 1412 off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/); 1413 off = Bs3Cg1InsertOpcodes(pThis, off) - 1; 1414 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 1415 (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT, 1416 4, 0, BS3CG1OPLOC_MEM_RW); 1417 } 1418 else if (iEncoding == 1) 1419 { 1420 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/); 1421 off = Bs3Cg1InsertOpcodes(pThis, off) - 1; 1422 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 1423 (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT, 1424 4, 0, BS3CG1OPLOC_MEM_RW); 1425 } 1426 else if (iEncoding == 2) 1427 { 1428 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0x7 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/); 1429 off = Bs3Cg1InsertOpcodes(pThis, off) - 1; 1430 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 1431 (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT, 1432 4, 0, BS3CG1OPLOC_MEM_RW); 1433 *pfInvalidInstr = true; 1434 } 1435 else if (iEncoding == 3) 1436 { 1437 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/); 1438 off = Bs3Cg1InsertOpcodes(pThis, off) - 1; 1439 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 1440 (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT, 1441 4, 0, BS3CG1OPLOC_MEM_RW); 1442 *pfInvalidInstr = true; 1443 } 1444 else if (iEncoding == 4) 1445 { 1446 pThis->abCurInstr[0] = P_OZ; 1447 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/); 1448 off = Bs3Cg1InsertOpcodes(pThis, off) - 1; 1449 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 1450 (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT, 1451 4, 0, BS3CG1OPLOC_MEM_RW); 1452 *pfInvalidInstr = true; 1453 } 1454 else if (iEncoding == 5) 1455 { 1456 pThis->abCurInstr[0] = P_RZ; 1457 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/); 1458 off = Bs3Cg1InsertOpcodes(pThis, off) - 1; 1459 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 1460 (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT, 1461 4, 0, BS3CG1OPLOC_MEM_RW); 1462 *pfInvalidInstr = true; 1463 } 1464 else if (iEncoding == 6) 1465 { 1466 pThis->abCurInstr[0] = P_RN; 1467 off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/); 1468 off = Bs3Cg1InsertOpcodes(pThis, off) - 1; 1469 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 1470 (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT, 1471 4, 0, BS3CG1OPLOC_MEM_RW); 1472 *pfInvalidInstr = true; 1473 } 1474 else if (iEncoding == 7) 1475 { 1476 off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/); 1477 off = Bs3Cg1InsertOpcodes(pThis, off) - 1; 1478 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, 1479 (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT, 1480 4, 0, BS3CG1OPLOC_MEM_RW); 1481 } 1482 else 1483 return 0; 1484 pThis->cbCurInstr = off; 1485 return iEncoding + 1; 1486 } 1487 1488 1188 1489 /** 1189 1490 * Encodes the next instruction. … … 1191 1492 * @returns Next iEncoding value. Returns @a iEncoding unchanged to indicate 1192 1493 * that there are no more encodings to test. 1193 * @param pThis The state. 1194 * @param iEncoding The encoding to produce. Meaning is specific to each 1195 * BS3CG1ENC_XXX value and should be considered internal. 1494 * @param pThis The state. 1495 * @param iEncoding The encoding to produce. Meaning is specific to 1496 * each BS3CG1ENC_XXX value and should be considered 1497 * internal. 1498 * @param pfInvalidInstr Pointer to variable to set when generating an 1499 * invalid encoding. (Never clear this.) 1196 1500 */ 1197 static unsigned Bs3Cg1EncodeNext(PBS3CG1STATE pThis, unsigned iEncoding)1501 unsigned Bs3Cg1EncodeNext(PBS3CG1STATE pThis, unsigned iEncoding, bool *pfInvalidInstr) 1198 1502 { 1199 1503 unsigned off; … … 1205 1509 { 1206 1510 case BS3CG1ENC_MODRM_Eb_Gb: 1207 /* Start by reg,reg encoding. */ 1208 if (iEncoding == 0) 1209 { 1210 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)); 1211 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX); 1212 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL; 1213 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL; 1214 } 1215 else if (iEncoding == 1) 1216 { 1217 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_CH; 1218 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)); 1219 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, 1, 0, BS3CG1OPLOC_MEM_RW); 1220 } 1221 else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386) 1222 { 1223 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_BH; 1224 pThis->abCurInstr[0] = P_AZ; 1225 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1)); 1226 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, 1, 0, BS3CG1OPLOC_MEM_RW); 1227 } 1228 else 1229 break; 1230 pThis->cbCurInstr = off; 1231 iEncoding++; 1232 break; 1233 1511 return Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Eb_Gb(pThis, iEncoding, pfInvalidInstr); 1234 1512 case BS3CG1ENC_MODRM_Gb_Eb: 1235 /* Start by reg,reg encoding. */ 1236 if (iEncoding == 0) 1237 { 1238 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)); 1239 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX); 1240 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL; 1241 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL; 1242 } 1243 else if (iEncoding == 1) 1244 { 1245 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_CH; 1246 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)); 1247 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, 1, 0, BS3CG1OPLOC_MEM); 1248 } 1249 else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386) 1250 { 1251 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_BH; 1252 pThis->abCurInstr[0] = P_AZ; 1253 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1)); 1254 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, 1, 0, BS3CG1OPLOC_MEM); 1255 } 1256 else 1257 break; 1258 pThis->cbCurInstr = off; 1259 iEncoding++; 1260 break; 1261 1513 return Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Gb_Eb(pThis, iEncoding, pfInvalidInstr); 1262 1514 case BS3CG1ENC_MODRM_Gv_Ev: 1263 1515 case BS3CG1ENC_MODRM_Ev_Gv: 1264 if (iEncoding == 0) 1265 { 1266 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4; 1267 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)); 1268 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX); 1269 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RBX; 1270 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_OZ_RDX; 1271 } 1272 else if (iEncoding == 1) 1273 { 1274 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4; 1275 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RBP; 1276 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0)); 1277 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, cbOp, 0, 1278 pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW); 1279 } 1280 else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386) 1281 { 1282 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2; 1283 pThis->abCurInstr[0] = P_OZ; 1284 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1)); 1285 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX); 1286 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RBX; 1287 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_OZ_RDX; 1288 pThis->aOperands[pThis->iRmOp ].enmLocation = BS3CG1OPLOC_CTX; 1289 } 1290 else if (iEncoding == 3) 1291 { 1292 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2; 1293 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RSI; 1294 pThis->abCurInstr[0] = P_OZ; 1295 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1)); 1296 off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xSI, cbOp, 0, 1297 pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW); 1298 } 1299 else if (iEncoding == 4) 1300 { 1301 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4; 1302 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RDI; 1303 pThis->abCurInstr[0] = P_AZ; 1304 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1)); 1305 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, cbOp, 0, 1306 pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW); 1307 } 1308 else if (iEncoding == 5) 1309 { 1310 cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2; 1311 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_OZ_RSI; 1312 pThis->abCurInstr[0] = P_OZ; 1313 pThis->abCurInstr[1] = P_AZ; 1314 off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 2)); 1315 off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xSI, cbOp, 0, 1316 pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW); 1317 } 1318 else if (iEncoding == 6 && BS3_MODE_IS_64BIT_CODE(pThis->bMode)) 1319 { 1320 cbOp = 8; 1321 off = Bs3Cg1InsertReqPrefix(pThis, 0); 1322 pThis->abCurInstr[off++] = REX_W___; 1323 off = Bs3Cg1InsertOpcodes(pThis, off); 1324 pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX); 1325 pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_RBX; 1326 pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_RDX; 1327 pThis->aOperands[pThis->iRmOp ].enmLocation = BS3CG1OPLOC_CTX; 1328 } 1329 else 1330 break; 1331 pThis->aOperands[0].cbOp = cbOp; 1332 pThis->aOperands[1].cbOp = cbOp; 1333 pThis->cbOperand = cbOp; 1334 pThis->cbCurInstr = off; 1335 iEncoding++; 1336 break; 1516 return Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Gv_Ev__OR__BS3CG1ENC_MODRM_Ev_Gv(pThis, iEncoding, pfInvalidInstr); 1337 1517 1338 1518 case BS3CG1ENC_MODRM_Wss_Vss: … … 1592 1772 iEncoding++; 1593 1773 break; 1774 1775 case BS3CG1ENC_VEX_MODRM_MdWO: 1776 return Bs3Cg1EncodeNext_BS3CG1ENC_VEX_MODRM_MdWO(pThis, iEncoding, pfInvalidInstr); 1594 1777 1595 1778 case BS3CG1ENC_FIXED: … … 1736 1919 * 1737 1920 * @returns Success indicator (true/false). 1738 * @param pThis The state.1921 * @param pThis The state. 1739 1922 */ 1740 1923 static bool Bs3Cg1EncodePrep(PBS3CG1STATE pThis) … … 1869 2052 1870 2053 case BS3CG1ENC_MODRM_MdWO: 2054 case BS3CG1ENC_VEX_MODRM_MdWO: 1871 2055 pThis->iRmOp = 0; 1872 2056 pThis->aOperands[0].cbOp = 4; … … 2078 2262 case BS3CG1CPU_AVX: 2079 2263 if (fEcx & X86_CPUID_FEATURE_ECX_AVX) 2080 return Bs3Cg3SetupSseAndAvx(pThis) ;2264 return Bs3Cg3SetupSseAndAvx(pThis) && !BS3_MODE_IS_RM_OR_V86(pThis->bMode); 2081 2265 return false; 2082 2266 default: BS3_ASSERT(0); /* impossible */ … … 2093 2277 case BS3CG1CPU_AVX2: 2094 2278 if (fEbx & X86_CPUID_STEXT_FEATURE_EBX_AVX2) 2095 return Bs3Cg3SetupSseAndAvx(pThis) ;2279 return Bs3Cg3SetupSseAndAvx(pThis) && !BS3_MODE_IS_RM_OR_V86(pThis->bMode); 2096 2280 return false; 2097 2281 default: BS3_ASSERT(0); return false; /* impossible */ … … 2639 2823 { 2640 2824 cbAdjustPc = 0; 2641 bExpectedXcpt = bTestXcptExpected;2825 bExpectedXcpt = X86_XCPT_UD; 2642 2826 } 2643 2827 if (RT_LIKELY( pThis->TrapFrame.bXcpt == bExpectedXcpt … … 2654 2838 * Check memory output operands. 2655 2839 */ 2656 iOperand = pThis->cOperands; 2657 while (iOperand-- > 0) 2658 if (pThis->aOperands[iOperand].enmLocation == BS3CG1OPLOC_MEM_RW) 2659 { 2660 BS3PTRUNION PtrUnion; 2661 PtrUnion.pb = &pThis->pbDataPg[X86_PAGE_SIZE - pThis->aOperands[iOperand].off]; 2662 switch (pThis->aOperands[iOperand].cbOp) 2840 if (!fInvalidInstr) 2841 { 2842 iOperand = pThis->cOperands; 2843 while (iOperand-- > 0) 2844 if (pThis->aOperands[iOperand].enmLocation == BS3CG1OPLOC_MEM_RW) 2663 2845 { 2664 case 1: 2665 if (*PtrUnion.pu8 == pThis->MemOp.ab[0]) 2666 continue; 2667 Bs3TestFailedF("op%u: Wrote %#04RX8, expected %#04RX8", iOperand, *PtrUnion.pu8, pThis->MemOp.ab[0]); 2668 break; 2669 case 2: 2670 if (*PtrUnion.pu16 == pThis->MemOp.au16[0]) 2671 continue; 2672 Bs3TestFailedF("op%u: Wrote %#06RX16, expected %#06RX16", 2673 iOperand, *PtrUnion.pu16, pThis->MemOp.au16[0]); 2674 break; 2675 case 4: 2676 if (*PtrUnion.pu32 == pThis->MemOp.au32[0]) 2677 continue; 2678 Bs3TestFailedF("op%u: Wrote %#010RX32, expected %#010RX32", 2679 iOperand, *PtrUnion.pu32, pThis->MemOp.au32[0]); 2680 break; 2681 case 8: 2682 if (*PtrUnion.pu64 == pThis->MemOp.au64[0]) 2683 continue; 2684 Bs3TestFailedF("op%u: Wrote %#018RX64, expected %#018RX64", 2685 iOperand, *PtrUnion.pu64, pThis->MemOp.au64[0]); 2686 break; 2687 default: 2688 if (Bs3MemCmp(PtrUnion.pb, pThis->MemOp.ab, pThis->aOperands[iOperand].cbOp) == 0) 2689 continue; 2690 Bs3TestFailedF("op%u: Wrote %.*Rhxs, expected %.*Rhxs", 2691 iOperand, 2692 pThis->aOperands[iOperand].cbOp, PtrUnion.pb, 2693 pThis->aOperands[iOperand].cbOp, pThis->MemOp.ab); 2694 break; 2846 BS3PTRUNION PtrUnion; 2847 PtrUnion.pb = &pThis->pbDataPg[X86_PAGE_SIZE - pThis->aOperands[iOperand].off]; 2848 switch (pThis->aOperands[iOperand].cbOp) 2849 { 2850 case 1: 2851 if (*PtrUnion.pu8 == pThis->MemOp.ab[0]) 2852 continue; 2853 Bs3TestFailedF("op%u: Wrote %#04RX8, expected %#04RX8", iOperand, *PtrUnion.pu8, pThis->MemOp.ab[0]); 2854 break; 2855 case 2: 2856 if (*PtrUnion.pu16 == pThis->MemOp.au16[0]) 2857 continue; 2858 Bs3TestFailedF("op%u: Wrote %#06RX16, expected %#06RX16", 2859 iOperand, *PtrUnion.pu16, pThis->MemOp.au16[0]); 2860 break; 2861 case 4: 2862 if (*PtrUnion.pu32 == pThis->MemOp.au32[0]) 2863 continue; 2864 Bs3TestFailedF("op%u: Wrote %#010RX32, expected %#010RX32", 2865 iOperand, *PtrUnion.pu32, pThis->MemOp.au32[0]); 2866 break; 2867 case 8: 2868 if (*PtrUnion.pu64 == pThis->MemOp.au64[0]) 2869 continue; 2870 Bs3TestFailedF("op%u: Wrote %#018RX64, expected %#018RX64", 2871 iOperand, *PtrUnion.pu64, pThis->MemOp.au64[0]); 2872 break; 2873 default: 2874 if (Bs3MemCmp(PtrUnion.pb, pThis->MemOp.ab, pThis->aOperands[iOperand].cbOp) == 0) 2875 continue; 2876 Bs3TestFailedF("op%u: Wrote %.*Rhxs, expected %.*Rhxs", 2877 iOperand, 2878 pThis->aOperands[iOperand].cbOp, PtrUnion.pb, 2879 pThis->aOperands[iOperand].cbOp, pThis->MemOp.ab); 2880 break; 2881 } 2882 fOkay = false; 2695 2883 } 2696 fOkay = false; 2697 } 2884 } 2698 2885 2699 2886 /* … … 3132 3319 pThis->pabOpcodes += pThis->cbOpcodes) 3133 3320 { 3134 bool f InvalidInstr = false;3321 bool fOuterInvalidInstr = false; 3135 3322 unsigned iCpuSetup; 3136 3323 uint8_t bTestXcptExpected = BS3_MODE_IS_PAGED(pThis->bMode) ? X86_XCPT_PF : X86_XCPT_UD; … … 3175 3362 if ( !Bs3Cg1CpuSetupFirst(pThis) 3176 3363 || (pThis->fFlags & (BS3CG1INSTR_F_UNUSED | BS3CG1INSTR_F_INVALID))) 3177 { 3178 fInvalidInstr = true; 3179 bTestXcptExpected = X86_XCPT_UD; 3180 } 3364 fOuterInvalidInstr = true; 3181 3365 3182 3366 for (iCpuSetup = 0;; iCpuSetup++) … … 3199 3383 * Encode the next instruction variation. 3200 3384 */ 3201 iEncodingNext = Bs3Cg1EncodeNext(pThis, iEncoding); 3385 bool fInnerInvalidInstr = fOuterInvalidInstr; 3386 iEncodingNext = Bs3Cg1EncodeNext(pThis, iEncoding, &fInnerInvalidInstr); 3202 3387 if (iEncodingNext <= iEncoding) 3203 3388 break; 3204 BS3CG1_DPRINTF(("\ndbg: Encoding #%u: cbCurInst=%u: %.*Rhxs \n",3205 iEncoding, pThis->cbCurInstr, pThis->cbCurInstr, pThis->abCurInstr ));3389 BS3CG1_DPRINTF(("\ndbg: Encoding #%u: cbCurInst=%u: %.*Rhxs fInnerInvalidInstr=%d\n", 3390 iEncoding, pThis->cbCurInstr, pThis->cbCurInstr, pThis->abCurInstr, fInnerInvalidInstr)); 3206 3391 3207 3392 /* … … 3265 3450 pThis->Ctx.rflags.u32 |= pThis->TrapFrame.Ctx.rflags.u32 & X86_EFL_RF; 3266 3451 pThis->bValueXcpt = UINT8_MAX; 3267 if ( fIn validInstr3452 if ( fInnerInvalidInstr 3268 3453 || pThis->bAlignmentXcpt != UINT8_MAX 3269 3454 || pThis->bValueXcpt != UINT8_MAX … … 3272 3457 &pThis->TrapFrame.Ctx, NULL /*pbCode*/)) 3273 3458 { 3274 Bs3Cg1CheckResult(pThis, fIn validInstr, bTestXcptExpected, iEncoding);3459 Bs3Cg1CheckResult(pThis, fInnerInvalidInstr, bTestXcptExpected, iEncoding); 3275 3460 } 3276 3461 } … … 3294 3479 */ 3295 3480 Bs3Cg1EncodeCleanup(pThis); 3296 if (!Bs3Cg1CpuSetupNext(pThis, iCpuSetup, &f InvalidInstr))3481 if (!Bs3Cg1CpuSetupNext(pThis, iCpuSetup, &fOuterInvalidInstr)) 3297 3482 break; 3298 3483 if (pThis->fFlags & (BS3CG1INSTR_F_UNUSED | BS3CG1INSTR_F_INVALID)) 3299 fInvalidInstr = true; 3300 if (fInvalidInstr) 3301 bTestXcptExpected = X86_XCPT_UD; 3484 fOuterInvalidInstr = true; 3302 3485 } 3303 3486 } … … 3312 3495 BS3CG1STATE This; 3313 3496 3314 #if 03497 #if 1 3315 3498 /* (for debugging) */ 3316 if (bMode != BS3_MODE_PPV86)3499 if (bMode < BS3_MODE_PP16_32) 3317 3500 return BS3TESTDOMODE_SKIPPED; 3318 3501 #endif -
trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1.h
r66404 r66419 107 107 BS3CG1ENC_MODRM_MdRO, 108 108 BS3CG1ENC_MODRM_MdWO, 109 110 BS3CG1ENC_VEX_MODRM_MdWO, 109 111 110 112 BS3CG1ENC_FIXED, -
trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-ExtCtxGetSize.c
r66303 r66419 40 40 41 41 ASMCpuIdExSlow(1, 0, 0, 0, NULL, NULL, &fEcx, &fEdx); 42 #if 0/* To disable xsave/xrstor till IEM groks it... */42 #if 1 /* To disable xsave/xrstor till IEM groks it... */ 43 43 if (fEcx & X86_CPUID_FEATURE_ECX_XSAVE) 44 44 {
Note:
See TracChangeset
for help on using the changeset viewer.