Index: /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 73554)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAll.cpp	(revision 73555)
@@ -2400,4 +2400,81 @@
 # define IEM_OPCODE_GET_NEXT_S8_SX_U64(a_pu64) (*(a_pu64) = (int8_t)iemOpcodeGetNextU8Jmp(pVCpu))
 #endif
+
+
+#ifndef IEM_WITH_SETJMP
+/**
+ * Fetches the next opcode byte.
+ *
+ * @returns Strict VBox status code.
+ * @param   pVCpu               The cross context virtual CPU structure of the
+ *                              calling thread.
+ * @param   pu8                 Where to return the opcode byte.
+ */
+DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextRm(PVMCPU pVCpu, uint8_t *pu8)
+{
+    uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
+    pVCpu->iem.s.offModRm = offOpcode;
+    if (RT_LIKELY((uint8_t)offOpcode < pVCpu->iem.s.cbOpcode))
+    {
+        pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 1;
+        *pu8 = pVCpu->iem.s.abOpcode[offOpcode];
+        return VINF_SUCCESS;
+    }
+    return iemOpcodeGetNextU8Slow(pVCpu, pu8);
+}
+#else  /* IEM_WITH_SETJMP */
+/**
+ * Fetches the next opcode byte, longjmp on error.
+ *
+ * @returns The opcode byte.
+ * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
+ */
+DECLINLINE(uint8_t) iemOpcodeGetNextRmJmp(PVMCPU pVCpu)
+{
+# ifdef IEM_WITH_CODE_TLB
+    uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
+    pVCpu->iem.s.offModRm = offOpcode;
+    uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
+    if (RT_LIKELY(   pbBuf != NULL
+                  && offBuf < pVCpu->iem.s.cbInstrBuf))
+    {
+        pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 1;
+        return pbBuf[offBuf];
+    }
+# else
+    uintptr_t offOpcode = pVCpu->iem.s.offOpcode;
+    pVCpu->iem.s.offModRm = offOpcode;
+    if (RT_LIKELY((uint8_t)offOpcode < pVCpu->iem.s.cbOpcode))
+    {
+        pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 1;
+        return pVCpu->iem.s.abOpcode[offOpcode];
+    }
+# endif
+    return iemOpcodeGetNextU8SlowJmp(pVCpu);
+}
+#endif /* IEM_WITH_SETJMP */
+
+/**
+ * Fetches the next opcode byte, which is a ModR/M byte, returns automatically
+ * on failure.
+ *
+ * Will note down the position of the ModR/M byte for VT-x exits.
+ *
+ * @param   a_pbRm              Where to return the RM opcode byte.
+ * @remark Implicitly references pVCpu.
+ */
+#ifndef IEM_WITH_SETJMP
+# define IEM_OPCODE_GET_NEXT_RM(a_pbRm) \
+    do \
+    { \
+        VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextRm(pVCpu, (a_pu8)); \
+        if (rcStrict2 == VINF_SUCCESS) \
+        { /* likely */ } \
+        else \
+            return rcStrict2; \
+    } while (0)
+#else
+# define IEM_OPCODE_GET_NEXT_RM(a_pbRm) (*(a_pbRm) = iemOpcodeGetNextRmJmp(pVCpu))
+#endif /* IEM_WITH_SETJMP */
 
 
Index: /trunk/src/VBox/VMM/include/IEMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/IEMInternal.h	(revision 73554)
+++ /trunk/src/VBox/VMM/include/IEMInternal.h	(revision 73555)
@@ -422,4 +422,6 @@
     uint8_t                 iEffSeg;                                                                        /* 0x2b */
 
+    /** The offset of the ModR/M byte relative to the start of the instruction. */
+    uint8_t                 offModRm;                                                                       /* 0x2c */
 #else
     /** The size of what has currently been fetched into abOpcode. */
@@ -427,54 +429,57 @@
     /** The current offset into abOpcode. */
     uint8_t                 offOpcode;                                                                      /*       0x09 */
+    /** The offset of the ModR/M byte relative to the start of the instruction. */
+    uint8_t                 offModRm;                                                                       /*       0x0a */
 
     /** The effective segment register (X86_SREG_XXX). */
-    uint8_t                 iEffSeg;                                                                        /*       0x0a */
-
-    /** The extra REX ModR/M register field bit (REX.R << 3). */
-    uint8_t                 uRexReg;                                                                        /*       0x0b */
+    uint8_t                 iEffSeg;                                                                        /*       0x0b */
+
     /** The prefix mask (IEM_OP_PRF_XXX). */
     uint32_t                fPrefixes;                                                                      /*       0x0c */
+    /** The extra REX ModR/M register field bit (REX.R << 3). */
+    uint8_t                 uRexReg;                                                                        /*       0x10 */
     /** The extra REX ModR/M r/m field, SIB base and opcode reg bit
      * (REX.B << 3). */
-    uint8_t                 uRexB;                                                                          /*       0x10 */
+    uint8_t                 uRexB;                                                                          /*       0x11 */
     /** The extra REX SIB index field bit (REX.X << 3). */
-    uint8_t                 uRexIndex;                                                                      /*       0x11 */
+    uint8_t                 uRexIndex;                                                                      /*       0x12 */
 
 #endif
 
     /** The effective operand mode. */
-    IEMMODE                 enmEffOpSize;                                                                   /* 0x2c, 0x12 */
+    IEMMODE                 enmEffOpSize;                                                                   /* 0x2d, 0x13 */
     /** The default addressing mode. */
-    IEMMODE                 enmDefAddrMode;                                                                 /* 0x2d, 0x13 */
+    IEMMODE                 enmDefAddrMode;                                                                 /* 0x2e, 0x14 */
     /** The effective addressing mode. */
-    IEMMODE                 enmEffAddrMode;                                                                 /* 0x2e, 0x14 */
+    IEMMODE                 enmEffAddrMode;                                                                 /* 0x2f, 0x15 */
     /** The default operand mode. */
-    IEMMODE                 enmDefOpSize;                                                                   /* 0x2f, 0x15 */
+    IEMMODE                 enmDefOpSize;                                                                   /* 0x30, 0x16 */
 
     /** Prefix index (VEX.pp) for two byte and three byte tables. */
-    uint8_t                 idxPrefix;                                                                      /* 0x30, 0x16 */
+    uint8_t                 idxPrefix;                                                                      /* 0x31, 0x17 */
     /** 3rd VEX/EVEX/XOP register.
      * Please use IEM_GET_EFFECTIVE_VVVV to access.  */
-    uint8_t                 uVex3rdReg;                                                                     /* 0x31, 0x17 */
+    uint8_t                 uVex3rdReg;                                                                     /* 0x32, 0x18 */
     /** The VEX/EVEX/XOP length field. */
-    uint8_t                 uVexLength;                                                                     /* 0x32, 0x18 */
+    uint8_t                 uVexLength;                                                                     /* 0x33, 0x19 */
     /** Additional EVEX stuff. */
-    uint8_t                 fEvexStuff;                                                                     /* 0x33, 0x19 */
-
+    uint8_t                 fEvexStuff;                                                                     /* 0x34, 0x1a */
+
+    /** Explicit alignment padding. */
+    uint8_t                 abAlignment2a[1];                                                               /* 0x35, 0x1b */
     /** The FPU opcode (FOP). */
-    uint16_t                uFpuOpcode;                                                                     /* 0x34, 0x1a */
-
+    uint16_t                uFpuOpcode;                                                                     /* 0x36, 0x1c */
+#ifndef IEM_WITH_CODE_TLB
     /** Explicit alignment padding. */
-#ifdef IEM_WITH_CODE_TLB
-    uint8_t                 abAlignment2a[2];                                                               /* 0x36       */
+    uint8_t                 abAlignment2b[2];                                                               /*       0x1e */
 #endif
 
     /** The opcode bytes. */
-    uint8_t                 abOpcode[15];                                                                   /* 0x48, 0x1c */
+    uint8_t                 abOpcode[15];                                                                   /* 0x48, 0x20 */
     /** Explicit alignment padding. */
 #ifdef IEM_WITH_CODE_TLB
     uint8_t                 abAlignment2c[0x48 - 0x47];                                                     /* 0x37 */
 #else
-    uint8_t                 abAlignment2c[0x48 - 0x2b];                                                     /*       0x2b */
+    uint8_t                 abAlignment2c[0x48 - 0x2f];                                                     /*       0x2f */
 #endif
     /** @} */
Index: /trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp
===================================================================
--- /trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp	(revision 73554)
+++ /trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp	(revision 73555)
@@ -93,4 +93,5 @@
 
 
+#define IEM_OPCODE_GET_NEXT_RM(a_pu8)                       do { *(a_pu8)  = g_bRandom; CHK_PTYPE(uint8_t  *, a_pu8);  } while (0)
 #define IEM_OPCODE_GET_NEXT_U8(a_pu8)                       do { *(a_pu8)  = g_bRandom; CHK_PTYPE(uint8_t  *, a_pu8);  } while (0)
 #define IEM_OPCODE_GET_NEXT_S8(a_pi8)                       do { *(a_pi8)  = g_bRandom; CHK_PTYPE(int8_t   *, a_pi8);  } while (0)
