Index: /trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsOneByte.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsOneByte.cpp.h	(revision 66418)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsOneByte.cpp.h	(revision 66419)
@@ -6173,49 +6173,4 @@
 FNIEMOP_DEF(iemOp_les_Gv_Mp__vex2)
 {
-    /* The LES instruction is invalid 64-bit mode. In legacy and
-       compatability mode it is invalid with MOD=3.
-       The use as a VEX prefix is made possible by assigning the inverted
-       REX.R to the top MOD bit, and the top bit in the inverted register
-       specifier to the bottom MOD bit, thereby effectively limiting 32-bit
-       to accessing registers 0..7 in this VEX form. */
-    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
-    if (   pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT
-        || (bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
-    {
-        IEMOP_MNEMONIC(vex2_prefix, "vex2");
-        if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx)
-        {
-            uint8_t bOpcode; IEM_OPCODE_GET_NEXT_U8(&bOpcode);
-            if (   (  pVCpu->iem.s.fPrefixes
-                    & (IEM_OP_PRF_SIZE_OP | IEM_OP_PRF_REPZ | IEM_OP_PRF_REPNZ | IEM_OP_PRF_LOCK | IEM_OP_PRF_REX))
-                == 0)
-            {
-                pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_VEX;
-                pVCpu->iem.s.uRexReg    = ~bRm >> (7 - 3);
-                pVCpu->iem.s.uVex3rdReg = (~bRm >> 3) & 0xf;
-                pVCpu->iem.s.uVexLength = (bRm >> 2) & 1;
-                pVCpu->iem.s.idxPrefix  = bRm & 0x3;
-
-                return FNIEMOP_CALL(g_apfnVexMap1[(uintptr_t)bOpcode * 4 + pVCpu->iem.s.idxPrefix]);
-            }
-
-            Log(("VEX2: Invalid prefix mix!\n"));
-        }
-        else
-            Log(("VEX2: AVX support disabled!\n"));
-
-        /* @todo does intel completely decode the sequence with SIB/disp before \#UD? */
-        return IEMOP_RAISE_INVALID_OPCODE();
-    }
-    IEMOP_MNEMONIC(les_Gv_Mp, "les Gv,Mp");
-    return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_ES, bRm);
-}
-
-
-/**
- * @opcode      0xc5
- */
-FNIEMOP_DEF(iemOp_lds_Gv_Mp__vex3)
-{
     /* The LDS instruction is invalid 64-bit mode. In legacy and
        compatability mode it is invalid with MOD=3.
@@ -6228,6 +6183,6 @@
         if ((bRm & X86_MODRM_MOD_MASK) != (3 << X86_MODRM_MOD_SHIFT))
         {
-            IEMOP_MNEMONIC(lds_Gv_Mp, "lds Gv,Mp");
-            return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_DS, bRm);
+            IEMOP_MNEMONIC(les_Gv_Mp, "les Gv,Mp");
+            return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_ES, bRm);
         }
         IEMOP_HLP_NO_REAL_OR_V86_MODE();
@@ -6281,4 +6236,50 @@
         Log(("VEX3: AVX support disabled!\n"));
     return IEMOP_RAISE_INVALID_OPCODE();
+}
+
+
+/**
+ * @opcode      0xc5
+ */
+FNIEMOP_DEF(iemOp_lds_Gv_Mp__vex3)
+{
+    /* The LES instruction is invalid 64-bit mode. In legacy and
+       compatability mode it is invalid with MOD=3.
+       The use as a VEX prefix is made possible by assigning the inverted
+       REX.R to the top MOD bit, and the top bit in the inverted register
+       specifier to the bottom MOD bit, thereby effectively limiting 32-bit
+       to accessing registers 0..7 in this VEX form. */
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+    if (   pVCpu->iem.s.enmCpuMode == IEMMODE_64BIT
+        || (bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
+    {
+        IEMOP_MNEMONIC(vex2_prefix, "vex2");
+        if (IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx)
+        {
+            uint8_t bOpcode; IEM_OPCODE_GET_NEXT_U8(&bOpcode);
+            if (   (  pVCpu->iem.s.fPrefixes
+                    & (IEM_OP_PRF_SIZE_OP | IEM_OP_PRF_REPZ | IEM_OP_PRF_REPNZ | IEM_OP_PRF_LOCK | IEM_OP_PRF_REX))
+                == 0)
+            {
+                pVCpu->iem.s.fPrefixes |= IEM_OP_PRF_VEX;
+                pVCpu->iem.s.uRexReg    = ~bRm >> (7 - 3);
+                pVCpu->iem.s.uVex3rdReg = (~bRm >> 3) & 0xf;
+                pVCpu->iem.s.uVexLength = (bRm >> 2) & 1;
+                pVCpu->iem.s.idxPrefix  = bRm & 0x3;
+
+                return FNIEMOP_CALL(g_apfnVexMap1[(uintptr_t)bOpcode * 4 + pVCpu->iem.s.idxPrefix]);
+            }
+
+            Log(("VEX2: Invalid prefix mix!\n"));
+        }
+        else
+            Log(("VEX2: AVX support disabled!\n"));
+
+        /* @todo does intel completely decode the sequence with SIB/disp before \#UD? */
+        return IEMOP_RAISE_INVALID_OPCODE();
+    }
+
+    IEMOP_MNEMONIC(lds_Gv_Mp, "lds Gv,Mp");
+    return FNIEMOP_CALL_2(iemOpCommonLoadSRegAndGreg, X86_SREG_DS, bRm);
 }
 
@@ -11753,5 +11754,5 @@
     /* 0xbc */  iemOp_eSP_Iv,           iemOp_eBP_Iv,           iemOp_eSI_Iv,           iemOp_eDI_Iv,
     /* 0xc0 */  iemOp_Grp2_Eb_Ib,       iemOp_Grp2_Ev_Ib,       iemOp_retn_Iw,          iemOp_retn,
-    /* 0xc4 */  iemOp_les_Gv_Mp__vex2,  iemOp_lds_Gv_Mp__vex3,  iemOp_Grp11_Eb_Ib,      iemOp_Grp11_Ev_Iz,
+    /* 0xc4 */  iemOp_les_Gv_Mp__vex3,  iemOp_lds_Gv_Mp__vex2,  iemOp_Grp11_Eb_Ib,      iemOp_Grp11_Ev_Iz,
     /* 0xc8 */  iemOp_enter_Iw_Ib,      iemOp_leave,            iemOp_retf_Iw,          iemOp_retf,
     /* 0xcc */  iemOp_int3,             iemOp_int_Ib,           iemOp_into,             iemOp_iret,
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py	(revision 66418)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsPython.py	(revision 66419)
@@ -268,18 +268,30 @@
 
 ## IEMFORM_XXX mappings.
-g_kdIemForms = { # sEncoding,   [ sWhere1, ... ]
-    'RM':       ( 'ModR/M',     [ 'reg', 'rm' ], ),
-    'RM_REG':   ( 'ModR/M',     [ 'reg', 'rm' ], ),
-    'RM_MEM':   ( 'ModR/M',     [ 'reg', 'rm' ], ),
-    'MR':       ( 'ModR/M',     [ 'rm', 'reg' ], ),
-    'MR_REG':   ( 'ModR/M',     [ 'rm', 'reg' ], ),
-    'MR_MEM':   ( 'ModR/M',     [ 'rm', 'reg' ], ),
-    'M':        ( 'ModR/M',     [ 'rm', ], ),
-    'M_REG':    ( 'ModR/M',     [ 'rm', ], ),
-    'M_MEM':    ( 'ModR/M',     [ 'rm', ], ),
-    'R':        ( 'ModR/M',     [ 'reg', ], ),
-    'RVM':      ( 'ModR/M+VEX', [ 'reg', 'vvvv', 'rm'], ),
-    'MVR':      ( 'ModR/M+VEX', [ 'rm', 'vvvv', 'reg'], ),
-    'FIXED':    ( 'fixed',      None, )
+g_kdIemForms = {     # sEncoding,   [ sWhere1, ... ]
+    'RM':           ( 'ModR/M',     [ 'reg', 'rm' ], ),
+    'RM_REG':       ( 'ModR/M',     [ 'reg', 'rm' ], ),
+    'RM_MEM':       ( 'ModR/M',     [ 'reg', 'rm' ], ),
+    'MR':           ( 'ModR/M',     [ 'rm', 'reg' ], ),
+    'MR_REG':       ( 'ModR/M',     [ 'rm', 'reg' ], ),
+    'MR_MEM':       ( 'ModR/M',     [ 'rm', 'reg' ], ),
+    'M':            ( 'ModR/M',     [ 'rm', ], ),
+    'M_REG':        ( 'ModR/M',     [ 'rm', ], ),
+    'M_MEM':        ( 'ModR/M',     [ 'rm', ], ),
+    'R':            ( 'ModR/M',     [ 'reg', ], ),
+
+    'VEX_RM':       ( 'VEX.ModR/M', [ 'reg', 'rm' ], ),
+    'VEX_RM_REG':   ( 'VEX.ModR/M', [ 'reg', 'rm' ], ),
+    'VEX_RM_MEM':   ( 'VEX.ModR/M', [ 'reg', 'rm' ], ),
+    'VEX_MR':       ( 'VEX.ModR/M', [ 'rm', 'reg' ], ),
+    'VEX_MR_REG':   ( 'VEX.ModR/M', [ 'rm', 'reg' ], ),
+    'VEX_MR_MEM':   ( 'VEX.ModR/M', [ 'rm', 'reg' ], ),
+    'VEX_M':        ( 'VEX.ModR/M', [ 'rm', ], ),
+    'VEX_M_REG':    ( 'VEX.ModR/M', [ 'rm', ], ),
+    'VEX_M_MEM':    ( 'VEX.ModR/M', [ 'rm', ], ),
+    'VEX_R':        ( 'VEX.ModR/M', [ 'reg', ], ),
+    'VEX_RVM':      ( 'VEX.ModR/M', [ 'reg', 'vvvv', 'rm'], ),
+    'VEX_MVR':      ( 'VEX.ModR/M', [ 'rm', 'vvvv', 'reg'], ),
+
+    'FIXED':        ( 'fixed',      None, )
 };
 
@@ -313,7 +325,8 @@
 ## Valid values for \@openc
 g_kdEncodings = {
-    'ModR/M':   [ 'BS3CG1ENC_MODRM', ],     ##< ModR/M
-    'fixed':    [ 'BS3CG1ENC_FIXED', ],     ##< Fixed encoding (address, registers, etc).
-    'prefix':   [ None, ],                  ##< Prefix
+    'ModR/M':       [ 'BS3CG1ENC_MODRM', ],     ##< ModR/M
+    'VEX.ModR/M':   [ 'BS3CG1ENC_VEX_MODRM', ], ##< VEX...ModR/M
+    'fixed':        [ 'BS3CG1ENC_FIXED', ],     ##< Fixed encoding (address, registers, etc).
+    'prefix':       [ None, ],                  ##< Prefix
 };
 
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h	(revision 66418)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsTwoByte0f.cpp.h	(revision 66419)
@@ -5903,8 +5903,8 @@
  * @opcode      !11/3
  * @oppfx       none
- * @opcpuid     sse
+ * @opcpuid     avx
  * @opgroup     og_avx_mxcsrsm
- * @optestign      mxcsr=0      -> op1=0
- * @optestign      mxcsr=0x2083 -> op1=0x2083
+ * @optest         mxcsr=0      -> op1=0
+ * @optest         mxcsr=0x2083 -> op1=0x2083
  * @optestign      mxcsr=0x2084 cr0|=ts -> value.xcpt=0x7
  * @optestign      mxcsr=0x2085 cr0|=em -> value.xcpt=0x6
@@ -5915,8 +5915,9 @@
  * @optestign      mxcsr=0x208a cr0|=ts,em cr4&~=osfxsr -> value.xcpt=0x6
  * @optestign      mxcsr=0x208b cr0|=ts,em,mp cr4&~=osfxsr -> value.xcpt=0x6
+ * @oponlytest
  */
 FNIEMOP_DEF_1(iemOp_VGrp15_vstmxcsr,  uint8_t, bRm)
 {
-    IEMOP_MNEMONIC1(M_MEM, VSTMXCSR, vstmxcsr, MdWO, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZE);
+    IEMOP_MNEMONIC1(VEX_M_MEM, VSTMXCSR, vstmxcsr, MdWO, DISOPTYPE_HARMLESS, IEMOPHINT_IGNORES_OP_SIZE);
     if (!IEM_GET_GUEST_CPU_FEATURES(pVCpu)->fAvx)
         return IEMOP_RAISE_INVALID_OPCODE();
Index: /trunk/src/VBox/VMM/include/IEMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/IEMInternal.h	(revision 66418)
+++ /trunk/src/VBox/VMM/include/IEMInternal.h	(revision 66419)
@@ -867,12 +867,31 @@
 #define IEMOPFORM_R             3
 
-/** ModR/M + VEX.vvvv: reg, vvvv, r/m */
-#define IEMOPFORM_RVM           4
-
-/** ModR/M + VEX.vvvv: r/m, vvvv, reg */
-#define IEMOPFORM_MVR           5
+/** VEX+ModR/M: reg, r/m */
+#define IEMOPFORM_VEX_RM        4
+/** VEX+ModR/M: reg, r/m (register) */
+#define IEMOPFORM_VEX_RM_REG        (IEMOPFORM_VEX_RM | IEMOPFORM_MOD3)
+/** VEX+ModR/M: reg, r/m (memory)   */
+#define IEMOPFORM_VEX_RM_MEM        (IEMOPFORM_VEX_RM | IEMOPFORM_NOT_MOD3)
+/** VEX+ModR/M: r/m, reg */
+#define IEMOPFORM_VEX_MR        5
+/** VEX+ModR/M: r/m (register), reg */
+#define IEMOPFORM_VEX_MR_REG        (IEMOPFORM_VEX_MR | IEMOPFORM_MOD3)
+/** VEX+ModR/M: r/m (memory), reg */
+#define IEMOPFORM_VEX_MR_MEM        (IEMOPFORM_VEX_MR | IEMOPFORM_NOT_MOD3)
+/** VEX+ModR/M: r/m only */
+#define IEMOPFORM_VEX_M         6
+/** VEX+ModR/M: r/m only (register). */
+#define IEMOPFORM_VEX_M_REG         (IEMOPFORM_VEX_M | IEMOPFORM_MOD3)
+/** VEX+ModR/M: r/m only (memory). */
+#define IEMOPFORM_VEX_M_MEM         (IEMOPFORM_VEX_M | IEMOPFORM_NOT_MOD3)
+/** VEX+ModR/M: reg only */
+#define IEMOPFORM_VEX_R         7
+/** VEX+ModR/M: reg, vvvv, r/m */
+#define IEMOPFORM_VEX_RVM       8
+/** VEX+ModR/M: r/m, vvvv, reg */
+#define IEMOPFORM_VEX_MVR       9
 
 /** Fixed register instruction, no R/M. */
-#define IEMOPFORM_FIXED         6
+#define IEMOPFORM_FIXED         16
 
 /** The r/m is a register. */
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1-template.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1-template.c	(revision 66418)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1-template.c	(revision 66419)
@@ -1055,4 +1055,79 @@
 
 
+/**
+ * Inserts a 2-byte VEX prefix.
+ *
+ * @returns New offDst value.
+ * @param   pThis       The state.
+ * @param   offDst      The current instruction offset.
+ * @param   uVexL       The VEX.L value.
+ * @param   uVexV       The VEX.V value (caller inverted it already).
+ * @param   uVexR       The VEX.R value (caller inverted it already).
+ */
+DECLINLINE(unsigned) Bs3Cg1InsertVex2bPrefix(PBS3CG1STATE pThis, unsigned offDst, uint8_t uVexV, uint8_t uVexL, uint8_t uVexR)
+{
+    uint8_t b = uVexR << 7;
+    b        |= uVexV << 3;
+    b        |= uVexL << 2;
+    switch (pThis->enmPrefixKind)
+    {
+        case BS3CG1PFXKIND_NO_F2_F3_66:     b |= 0; break;
+        case BS3CG1PFXKIND_REQ_66:          b |= 1; break;
+        case BS3CG1PFXKIND_REQ_F3:          b |= 2; break;
+        case BS3CG1PFXKIND_REQ_F2:          b |= 3; break;
+        default:
+            Bs3TestFailedF("enmPrefixKind=%d not supported for VEX!\n");
+            break;
+    }
+
+    pThis->abCurInstr[offDst]     = 0xc5; /* vex2 */
+    pThis->abCurInstr[offDst + 1] = b;
+    return offDst + 2;
+}
+
+
+/**
+ * Inserts a 3-byte VEX prefix.
+ *
+ * @returns New offDst value.
+ * @param   pThis       The state.
+ * @param   offDst      The current instruction offset.
+ * @param   uVexL       The VEX.L value.
+ * @param   uVexV       The VEX.V value (caller inverted it already).
+ * @param   uVexR       The VEX.R value (caller inverted it already).
+ * @param   uVexR       The VEX.X value (caller inverted it already).
+ * @param   uVexR       The VEX.B value (caller inverted it already).
+ * @param   uVexR       The VEX.W value (straight).
+ */
+DECLINLINE(unsigned) Bs3Cg1InsertVex3bPrefix(PBS3CG1STATE pThis, unsigned offDst, uint8_t uVexV, uint8_t uVexL,
+                                             uint8_t uVexR, uint8_t uVexX, uint8_t uVexB, uint8_t uVexW)
+{
+    uint8_t b1;
+    uint8_t b2;
+    b1        = uVexR << 7;
+    b1       |= uVexX << 6;
+    b1       |= uVexB << 5;
+    b1       |= 1; /* VEX.mmmmm = 1*/ /** @todo three byte opcode tables */
+    b2        = uVexV << 3;
+    b2       |= uVexW << 7;
+    b2       |= uVexL << 2;
+    switch (pThis->enmPrefixKind)
+    {
+        case BS3CG1PFXKIND_NO_F2_F3_66:     b2 |= 0; break;
+        case BS3CG1PFXKIND_REQ_66:          b2 |= 1; break;
+        case BS3CG1PFXKIND_REQ_F3:          b2 |= 2; break;
+        case BS3CG1PFXKIND_REQ_F2:          b2 |= 3; break;
+        default:
+            Bs3TestFailedF("enmPrefixKind=%d not supported for VEX!\n");
+            break;
+    }
+
+    pThis->abCurInstr[offDst]     = 0xc4; /* vex3 */
+    pThis->abCurInstr[offDst + 1] = b1;
+    pThis->abCurInstr[offDst + 2] = b2;
+    return offDst + 3;
+}
+
+
 DECLINLINE(unsigned) Bs3Cg1InsertReqPrefix(PBS3CG1STATE pThis, unsigned offDst)
 {
@@ -1186,4 +1261,230 @@
 
 
+unsigned Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Eb_Gb(PBS3CG1STATE pThis, unsigned iEncoding, bool *pfInvalidInstr)
+{
+    unsigned off;
+    /* Start by reg,reg encoding. */
+    if (iEncoding == 0)
+    {
+        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
+        pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX);
+        pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL;
+        pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL;
+    }
+    else if (iEncoding == 1)
+    {
+        pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_CH;
+        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, 1, 0, BS3CG1OPLOC_MEM_RW);
+    }
+    else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
+    {
+        pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_BH;
+        pThis->abCurInstr[0] = P_AZ;
+        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, 1, 0, BS3CG1OPLOC_MEM_RW);
+    }
+    else
+        return 0;
+    pThis->cbCurInstr = off;
+    return iEncoding + 1;
+}
+
+
+unsigned Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Gb_Eb(PBS3CG1STATE pThis, unsigned iEncoding, bool *pfInvalidInstr)
+{
+    unsigned off;
+    /* Start by reg,reg encoding. */
+    if (iEncoding == 0)
+    {
+        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
+        pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX);
+        pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL;
+        pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL;
+    }
+    else if (iEncoding == 1)
+    {
+        pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_CH;
+        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, 1, 0, BS3CG1OPLOC_MEM);
+    }
+    else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
+    {
+        pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_BH;
+        pThis->abCurInstr[0] = P_AZ;
+        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, 1, 0, BS3CG1OPLOC_MEM);
+    }
+    else
+        return 0;
+    pThis->cbCurInstr = off;
+    return iEncoding + 1;
+}
+
+
+unsigned Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Gv_Ev__OR__BS3CG1ENC_MODRM_Ev_Gv(PBS3CG1STATE pThis,
+                                                                           unsigned iEncoding, bool *pfInvalidInstr)
+{
+    unsigned off;
+    unsigned cbOp;
+    if (iEncoding == 0)
+    {
+        cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
+        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
+        pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
+        pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RBX;
+        pThis->aOperands[pThis->iRmOp ].idxField    = BS3CG1DST_OZ_RDX;
+    }
+    else if (iEncoding == 1)
+    {
+        cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
+        pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RBP;
+        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, cbOp, 0,
+                                       pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
+    }
+    else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
+    {
+        cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
+        pThis->abCurInstr[0] = P_OZ;
+        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
+        pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
+        pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RBX;
+        pThis->aOperands[pThis->iRmOp ].idxField    = BS3CG1DST_OZ_RDX;
+        pThis->aOperands[pThis->iRmOp ].enmLocation = BS3CG1OPLOC_CTX;
+    }
+    else if (iEncoding == 3)
+    {
+        cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
+        pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RSI;
+        pThis->abCurInstr[0] = P_OZ;
+        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xSI, cbOp, 0,
+                                       pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
+    }
+    else if (iEncoding == 4)
+    {
+        cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
+        pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RDI;
+        pThis->abCurInstr[0] = P_AZ;
+        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, cbOp, 0,
+                                       pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
+    }
+    else if (iEncoding == 5)
+    {
+        cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
+        pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RSI;
+        pThis->abCurInstr[0] = P_OZ;
+        pThis->abCurInstr[1] = P_AZ;
+        off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 2));
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xSI, cbOp, 0,
+                                       pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
+    }
+    else if (iEncoding == 6 && BS3_MODE_IS_64BIT_CODE(pThis->bMode))
+    {
+        cbOp = 8;
+        off = Bs3Cg1InsertReqPrefix(pThis, 0);
+        pThis->abCurInstr[off++] = REX_W___;
+        off = Bs3Cg1InsertOpcodes(pThis, off);
+        pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
+        pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_RBX;
+        pThis->aOperands[pThis->iRmOp ].idxField    = BS3CG1DST_RDX;
+        pThis->aOperands[pThis->iRmOp ].enmLocation = BS3CG1OPLOC_CTX;
+    }
+    else
+        return 0;
+    pThis->aOperands[0].cbOp = cbOp;
+    pThis->aOperands[1].cbOp = cbOp;
+    pThis->cbOperand  = cbOp;
+    pThis->cbCurInstr = off;
+    return iEncoding + 1;
+}
+
+
+
+static unsigned Bs3Cg1EncodeNext_BS3CG1ENC_VEX_MODRM_MdWO(PBS3CG1STATE pThis, unsigned iEncoding, bool *pfInvalidInstr)
+{
+    unsigned off;
+    if (iEncoding == 0)
+    {
+        /** @todo three by opcode needs some tweaking. */
+        off = Bs3Cg1InsertVex2bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/);
+        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
+                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
+                                       4, 0, BS3CG1OPLOC_MEM_RW);
+    }
+    else if (iEncoding == 1)
+    {
+        off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
+        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
+                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
+                                       4, 0, BS3CG1OPLOC_MEM_RW);
+    }
+    else if (iEncoding == 2)
+    {
+        off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0x7 /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
+        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
+                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
+                                       4, 0, BS3CG1OPLOC_MEM_RW);
+        *pfInvalidInstr = true;
+    }
+    else if (iEncoding == 3)
+    {
+        off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 1 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
+        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
+                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
+                                       4, 0, BS3CG1OPLOC_MEM_RW);
+        *pfInvalidInstr = true;
+    }
+    else if (iEncoding == 4)
+    {
+        pThis->abCurInstr[0] = P_OZ;
+        off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
+        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
+                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
+                                       4, 0, BS3CG1OPLOC_MEM_RW);
+        *pfInvalidInstr = true;
+    }
+    else if (iEncoding == 5)
+    {
+        pThis->abCurInstr[0] = P_RZ;
+        off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
+        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
+                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
+                                       4, 0, BS3CG1OPLOC_MEM_RW);
+        *pfInvalidInstr = true;
+    }
+    else if (iEncoding == 6)
+    {
+        pThis->abCurInstr[0] = P_RN;
+        off = Bs3Cg1InsertVex3bPrefix(pThis, 1 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 0 /*W*/);
+        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
+                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
+                                       4, 0, BS3CG1OPLOC_MEM_RW);
+        *pfInvalidInstr = true;
+    }
+    else if (iEncoding == 7)
+    {
+        off = Bs3Cg1InsertVex3bPrefix(pThis, 0 /*offDst*/, 0xf /*~V*/, 0 /*L*/, 1 /*~R*/, 1 /*~X*/, 1 /*~B*/, 1 /*W*/);
+        off = Bs3Cg1InsertOpcodes(pThis, off) - 1;
+        off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off,
+                                       (pThis->abCurInstr[off] & X86_MODRM_REG_MASK) >> X86_MODRM_REG_SHIFT,
+                                       4, 0, BS3CG1OPLOC_MEM_RW);
+    }
+    else
+        return 0;
+    pThis->cbCurInstr = off;
+    return iEncoding + 1;
+}
+
+
 /**
  * Encodes the next instruction.
@@ -1191,9 +1492,12 @@
  * @returns Next iEncoding value.  Returns @a iEncoding unchanged to indicate
  *          that there are no more encodings to test.
- * @param   pThis       The state.
- * @param   iEncoding   The encoding to produce.  Meaning is specific to each
- *                      BS3CG1ENC_XXX value and should be considered internal.
+ * @param   pThis           The state.
+ * @param   iEncoding       The encoding to produce.  Meaning is specific to
+ *                          each BS3CG1ENC_XXX value and should be considered
+ *                          internal.
+ * @param   pfInvalidInstr  Pointer to variable to set when generating an
+ *                          invalid encoding.  (Never clear this.)
  */
-static unsigned Bs3Cg1EncodeNext(PBS3CG1STATE pThis, unsigned iEncoding)
+unsigned Bs3Cg1EncodeNext(PBS3CG1STATE pThis, unsigned iEncoding, bool *pfInvalidInstr)
 {
     unsigned off;
@@ -1205,134 +1509,10 @@
     {
         case BS3CG1ENC_MODRM_Eb_Gb:
-            /* Start by reg,reg encoding. */
-            if (iEncoding == 0)
-            {
-                off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
-                pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX);
-                pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL;
-                pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL;
-            }
-            else if (iEncoding == 1)
-            {
-                pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_CH;
-                off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
-                off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, 1, 0, BS3CG1OPLOC_MEM_RW);
-            }
-            else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
-            {
-                pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_BH;
-                pThis->abCurInstr[0] = P_AZ;
-                off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
-                off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, 1, 0, BS3CG1OPLOC_MEM_RW);
-            }
-            else
-                break;
-            pThis->cbCurInstr = off;
-            iEncoding++;
-            break;
-
+            return Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Eb_Gb(pThis, iEncoding, pfInvalidInstr);
         case BS3CG1ENC_MODRM_Gb_Eb:
-            /* Start by reg,reg encoding. */
-            if (iEncoding == 0)
-            {
-                off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
-                pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xAX, X86_GREG_xCX);
-                pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_AL;
-                pThis->aOperands[pThis->iRmOp ].idxField = BS3CG1DST_CL;
-            }
-            else if (iEncoding == 1)
-            {
-                pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_CH;
-                off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
-                off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, 1, 0, BS3CG1OPLOC_MEM);
-            }
-            else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
-            {
-                pThis->aOperands[pThis->iRegOp].idxField = BS3CG1DST_BH;
-                pThis->abCurInstr[0] = P_AZ;
-                off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
-                off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, 1, 0, BS3CG1OPLOC_MEM);
-            }
-            else
-                break;
-            pThis->cbCurInstr = off;
-            iEncoding++;
-            break;
-
+            return Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Gb_Eb(pThis, iEncoding, pfInvalidInstr);
         case BS3CG1ENC_MODRM_Gv_Ev:
         case BS3CG1ENC_MODRM_Ev_Gv:
-            if (iEncoding == 0)
-            {
-                cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
-                off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
-                pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
-                pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RBX;
-                pThis->aOperands[pThis->iRmOp ].idxField    = BS3CG1DST_OZ_RDX;
-            }
-            else if (iEncoding == 1)
-            {
-                cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
-                pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RBP;
-                off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 0));
-                off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xBP, cbOp, 0,
-                                               pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
-            }
-            else if (iEncoding == 2 && (g_uBs3CpuDetected & BS3CPU_TYPE_MASK) >= BS3CPU_80386)
-            {
-                cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
-                pThis->abCurInstr[0] = P_OZ;
-                off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
-                pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
-                pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RBX;
-                pThis->aOperands[pThis->iRmOp ].idxField    = BS3CG1DST_OZ_RDX;
-                pThis->aOperands[pThis->iRmOp ].enmLocation = BS3CG1OPLOC_CTX;
-            }
-            else if (iEncoding == 3)
-            {
-                cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
-                pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RSI;
-                pThis->abCurInstr[0] = P_OZ;
-                off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
-                off = Bs3Cfg1EncodeMemMod0Disp(pThis, false, off, X86_GREG_xSI, cbOp, 0,
-                                               pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
-            }
-            else if (iEncoding == 4)
-            {
-                cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 2 : 4;
-                pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RDI;
-                pThis->abCurInstr[0] = P_AZ;
-                off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 1));
-                off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xDI, cbOp, 0,
-                                               pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
-            }
-            else if (iEncoding == 5)
-            {
-                cbOp = BS3_MODE_IS_16BIT_CODE(pThis->bMode) ? 4 : 2;
-                pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_OZ_RSI;
-                pThis->abCurInstr[0] = P_OZ;
-                pThis->abCurInstr[1] = P_AZ;
-                off = Bs3Cg1InsertOpcodes(pThis, Bs3Cg1InsertReqPrefix(pThis, 2));
-                off = Bs3Cfg1EncodeMemMod0Disp(pThis, true, off, X86_GREG_xSI, cbOp, 0,
-                                               pThis->enmEncoding == BS3CG1ENC_MODRM_Gv_Ev ? BS3CG1OPLOC_MEM : BS3CG1OPLOC_MEM_RW);
-            }
-            else if (iEncoding == 6 && BS3_MODE_IS_64BIT_CODE(pThis->bMode))
-            {
-                cbOp = 8;
-                off = Bs3Cg1InsertReqPrefix(pThis, 0);
-                pThis->abCurInstr[off++] = REX_W___;
-                off = Bs3Cg1InsertOpcodes(pThis, off);
-                pThis->abCurInstr[off++] = X86_MODRM_MAKE(3, X86_GREG_xBX, X86_GREG_xDX);
-                pThis->aOperands[pThis->iRegOp].idxField    = BS3CG1DST_RBX;
-                pThis->aOperands[pThis->iRmOp ].idxField    = BS3CG1DST_RDX;
-                pThis->aOperands[pThis->iRmOp ].enmLocation = BS3CG1OPLOC_CTX;
-            }
-            else
-                break;
-            pThis->aOperands[0].cbOp = cbOp;
-            pThis->aOperands[1].cbOp = cbOp;
-            pThis->cbOperand  = cbOp;
-            pThis->cbCurInstr = off;
-            iEncoding++;
-            break;
+            return Bs3Cg1EncodeNext_BS3CG1ENC_MODRM_Gv_Ev__OR__BS3CG1ENC_MODRM_Ev_Gv(pThis, iEncoding, pfInvalidInstr);
 
         case BS3CG1ENC_MODRM_Wss_Vss:
@@ -1592,4 +1772,7 @@
             iEncoding++;
             break;
+
+        case BS3CG1ENC_VEX_MODRM_MdWO:
+            return Bs3Cg1EncodeNext_BS3CG1ENC_VEX_MODRM_MdWO(pThis, iEncoding, pfInvalidInstr);
 
         case BS3CG1ENC_FIXED:
@@ -1736,5 +1919,5 @@
  *
  * @returns Success indicator (true/false).
- * @param   pThis       The state.
+ * @param   pThis           The state.
  */
 static bool Bs3Cg1EncodePrep(PBS3CG1STATE pThis)
@@ -1869,4 +2052,5 @@
 
         case BS3CG1ENC_MODRM_MdWO:
+        case BS3CG1ENC_VEX_MODRM_MdWO:
             pThis->iRmOp             = 0;
             pThis->aOperands[0].cbOp = 4;
@@ -2078,5 +2262,5 @@
                     case BS3CG1CPU_AVX:
                         if (fEcx & X86_CPUID_FEATURE_ECX_AVX)
-                            return Bs3Cg3SetupSseAndAvx(pThis);
+                            return Bs3Cg3SetupSseAndAvx(pThis) && !BS3_MODE_IS_RM_OR_V86(pThis->bMode);
                         return false;
                     default: BS3_ASSERT(0); /* impossible */
@@ -2093,5 +2277,5 @@
                     case BS3CG1CPU_AVX2:
                         if (fEbx & X86_CPUID_STEXT_FEATURE_EBX_AVX2)
-                            return Bs3Cg3SetupSseAndAvx(pThis);
+                            return Bs3Cg3SetupSseAndAvx(pThis) && !BS3_MODE_IS_RM_OR_V86(pThis->bMode);
                         return false;
                     default: BS3_ASSERT(0); return false; /* impossible */
@@ -2639,5 +2823,5 @@
     {
         cbAdjustPc = 0;
-        bExpectedXcpt = bTestXcptExpected;
+        bExpectedXcpt = X86_XCPT_UD;
     }
     if (RT_LIKELY(   pThis->TrapFrame.bXcpt     == bExpectedXcpt
@@ -2654,46 +2838,49 @@
          * Check memory output operands.
          */
-        iOperand = pThis->cOperands;
-        while (iOperand-- > 0)
-            if (pThis->aOperands[iOperand].enmLocation == BS3CG1OPLOC_MEM_RW)
-            {
-                BS3PTRUNION PtrUnion;
-                PtrUnion.pb = &pThis->pbDataPg[X86_PAGE_SIZE - pThis->aOperands[iOperand].off];
-                switch (pThis->aOperands[iOperand].cbOp)
+        if (!fInvalidInstr)
+        {
+            iOperand = pThis->cOperands;
+            while (iOperand-- > 0)
+                if (pThis->aOperands[iOperand].enmLocation == BS3CG1OPLOC_MEM_RW)
                 {
-                    case 1:
-                        if (*PtrUnion.pu8 == pThis->MemOp.ab[0])
-                            continue;
-                        Bs3TestFailedF("op%u: Wrote %#04RX8, expected %#04RX8", iOperand, *PtrUnion.pu8, pThis->MemOp.ab[0]);
-                        break;
-                    case 2:
-                        if (*PtrUnion.pu16 == pThis->MemOp.au16[0])
-                            continue;
-                        Bs3TestFailedF("op%u: Wrote %#06RX16, expected %#06RX16",
-                                       iOperand, *PtrUnion.pu16, pThis->MemOp.au16[0]);
-                        break;
-                    case 4:
-                        if (*PtrUnion.pu32 == pThis->MemOp.au32[0])
-                            continue;
-                        Bs3TestFailedF("op%u: Wrote %#010RX32, expected %#010RX32",
-                                       iOperand, *PtrUnion.pu32, pThis->MemOp.au32[0]);
-                        break;
-                    case 8:
-                        if (*PtrUnion.pu64 == pThis->MemOp.au64[0])
-                            continue;
-                        Bs3TestFailedF("op%u: Wrote %#018RX64, expected %#018RX64",
-                                       iOperand, *PtrUnion.pu64, pThis->MemOp.au64[0]);
-                        break;
-                    default:
-                        if (Bs3MemCmp(PtrUnion.pb, pThis->MemOp.ab, pThis->aOperands[iOperand].cbOp) == 0)
-                            continue;
-                        Bs3TestFailedF("op%u: Wrote %.*Rhxs, expected %.*Rhxs",
-                                       iOperand,
-                                       pThis->aOperands[iOperand].cbOp, PtrUnion.pb,
-                                       pThis->aOperands[iOperand].cbOp, pThis->MemOp.ab);
-                        break;
+                    BS3PTRUNION PtrUnion;
+                    PtrUnion.pb = &pThis->pbDataPg[X86_PAGE_SIZE - pThis->aOperands[iOperand].off];
+                    switch (pThis->aOperands[iOperand].cbOp)
+                    {
+                        case 1:
+                            if (*PtrUnion.pu8 == pThis->MemOp.ab[0])
+                                continue;
+                            Bs3TestFailedF("op%u: Wrote %#04RX8, expected %#04RX8", iOperand, *PtrUnion.pu8, pThis->MemOp.ab[0]);
+                            break;
+                        case 2:
+                            if (*PtrUnion.pu16 == pThis->MemOp.au16[0])
+                                continue;
+                            Bs3TestFailedF("op%u: Wrote %#06RX16, expected %#06RX16",
+                                           iOperand, *PtrUnion.pu16, pThis->MemOp.au16[0]);
+                            break;
+                        case 4:
+                            if (*PtrUnion.pu32 == pThis->MemOp.au32[0])
+                                continue;
+                            Bs3TestFailedF("op%u: Wrote %#010RX32, expected %#010RX32",
+                                           iOperand, *PtrUnion.pu32, pThis->MemOp.au32[0]);
+                            break;
+                        case 8:
+                            if (*PtrUnion.pu64 == pThis->MemOp.au64[0])
+                                continue;
+                            Bs3TestFailedF("op%u: Wrote %#018RX64, expected %#018RX64",
+                                           iOperand, *PtrUnion.pu64, pThis->MemOp.au64[0]);
+                            break;
+                        default:
+                            if (Bs3MemCmp(PtrUnion.pb, pThis->MemOp.ab, pThis->aOperands[iOperand].cbOp) == 0)
+                                continue;
+                            Bs3TestFailedF("op%u: Wrote %.*Rhxs, expected %.*Rhxs",
+                                           iOperand,
+                                           pThis->aOperands[iOperand].cbOp, PtrUnion.pb,
+                                           pThis->aOperands[iOperand].cbOp, pThis->MemOp.ab);
+                            break;
+                    }
+                    fOkay = false;
                 }
-                fOkay = false;
-            }
+        }
 
         /*
@@ -3132,5 +3319,5 @@
          pThis->pabOpcodes  += pThis->cbOpcodes)
     {
-        bool     fInvalidInstr = false;
+        bool     fOuterInvalidInstr = false;
         unsigned iCpuSetup;
         uint8_t  bTestXcptExpected = BS3_MODE_IS_PAGED(pThis->bMode) ? X86_XCPT_PF : X86_XCPT_UD;
@@ -3175,8 +3362,5 @@
         if (   !Bs3Cg1CpuSetupFirst(pThis)
             || (pThis->fFlags & (BS3CG1INSTR_F_UNUSED | BS3CG1INSTR_F_INVALID)))
-        {
-            fInvalidInstr = true;
-            bTestXcptExpected = X86_XCPT_UD;
-        }
+            fOuterInvalidInstr = true;
 
         for (iCpuSetup = 0;; iCpuSetup++)
@@ -3199,9 +3383,10 @@
                  * Encode the next instruction variation.
                  */
-                iEncodingNext = Bs3Cg1EncodeNext(pThis, iEncoding);
+                bool fInnerInvalidInstr = fOuterInvalidInstr;
+                iEncodingNext = Bs3Cg1EncodeNext(pThis, iEncoding, &fInnerInvalidInstr);
                 if (iEncodingNext <= iEncoding)
                     break;
-                BS3CG1_DPRINTF(("\ndbg: Encoding #%u: cbCurInst=%u: %.*Rhxs\n",
-                                iEncoding, pThis->cbCurInstr, pThis->cbCurInstr, pThis->abCurInstr));
+                BS3CG1_DPRINTF(("\ndbg: Encoding #%u: cbCurInst=%u: %.*Rhxs  fInnerInvalidInstr=%d\n",
+                                iEncoding, pThis->cbCurInstr, pThis->cbCurInstr, pThis->abCurInstr, fInnerInvalidInstr));
 
                 /*
@@ -3265,5 +3450,5 @@
                                 pThis->Ctx.rflags.u32 |= pThis->TrapFrame.Ctx.rflags.u32 & X86_EFL_RF;
                                 pThis->bValueXcpt      = UINT8_MAX;
-                                if (   fInvalidInstr
+                                if (   fInnerInvalidInstr
                                     || pThis->bAlignmentXcpt != UINT8_MAX
                                     || pThis->bValueXcpt     != UINT8_MAX
@@ -3272,5 +3457,5 @@
                                                                 &pThis->TrapFrame.Ctx, NULL /*pbCode*/))
                                 {
-                                    Bs3Cg1CheckResult(pThis, fInvalidInstr, bTestXcptExpected, iEncoding);
+                                    Bs3Cg1CheckResult(pThis, fInnerInvalidInstr, bTestXcptExpected, iEncoding);
                                 }
                             }
@@ -3294,10 +3479,8 @@
              */
             Bs3Cg1EncodeCleanup(pThis);
-            if (!Bs3Cg1CpuSetupNext(pThis, iCpuSetup, &fInvalidInstr))
+            if (!Bs3Cg1CpuSetupNext(pThis, iCpuSetup, &fOuterInvalidInstr))
                 break;
             if (pThis->fFlags & (BS3CG1INSTR_F_UNUSED | BS3CG1INSTR_F_INVALID))
-                fInvalidInstr = true;
-            if (fInvalidInstr)
-                bTestXcptExpected = X86_XCPT_UD;
+                fOuterInvalidInstr = true;
         }
     }
@@ -3312,7 +3495,7 @@
     BS3CG1STATE This;
 
-#if 0
+#if 1
     /* (for debugging) */
-    if (bMode != BS3_MODE_PPV86)
+    if (bMode < BS3_MODE_PP16_32)
         return BS3TESTDOMODE_SKIPPED;
 #endif
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1.h
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1.h	(revision 66418)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3-cpu-generated-1.h	(revision 66419)
@@ -107,4 +107,6 @@
     BS3CG1ENC_MODRM_MdRO,
     BS3CG1ENC_MODRM_MdWO,
+
+    BS3CG1ENC_VEX_MODRM_MdWO,
 
     BS3CG1ENC_FIXED,
Index: /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-ExtCtxGetSize.c
===================================================================
--- /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-ExtCtxGetSize.c	(revision 66418)
+++ /trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-cmn-ExtCtxGetSize.c	(revision 66419)
@@ -40,5 +40,5 @@
 
     ASMCpuIdExSlow(1, 0, 0, 0, NULL, NULL, &fEcx, &fEdx);
-#if 0 /* To disable xsave/xrstor till IEM groks it... */
+#if 1 /* To disable xsave/xrstor till IEM groks it... */
     if (fEcx & X86_CPUID_FEATURE_ECX_XSAVE)
     {
