Index: /trunk/src/VBox/VMM/VMMAll/IEMAllInstOneByte.cpp.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllInstOneByte.cpp.h	(revision 103656)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllInstOneByte.cpp.h	(revision 103657)
@@ -145,22 +145,20 @@
 
 /**
- * Body for instructions like TEST & CMP, ++ with a byte memory/registers as
+ * Body for instructions like TEST & CMP with a byte memory/registers as
  * operands.
  */
-#define IEMOP_BODY_BINARY_rm_r8_RO(a_fnNormalU8, a_EmitterBasename, a_fNativeArchs) \
-    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); \
-    \
+#define IEMOP_BODY_BINARY_rm_r8_RO(a_bRm, a_fnNormalU8, a_EmitterBasename, a_fNativeArchs) \
     /* \
      * If rm is denoting a register, no more instruction bytes. \
      */ \
-    if (IEM_IS_MODRM_REG_MODE(bRm)) \
+    if (IEM_IS_MODRM_REG_MODE(a_bRm)) \
     { \
         IEM_MC_BEGIN(3, 0, 0, 0); \
         IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
         IEM_MC_ARG(uint8_t,         u8Src,   1); \
-        IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
+        IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
         IEM_MC_NATIVE_IF(a_fNativeArchs) { \
             IEM_MC_LOCAL(uint8_t,   u8Dst); \
-            IEM_MC_FETCH_GREG_U8(u8Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
+            IEM_MC_FETCH_GREG_U8(u8Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
             /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
             IEM_MC_LOCAL(uint32_t,  uEFlags); \
@@ -170,5 +168,5 @@
         } IEM_MC_NATIVE_ELSE() { \
             IEM_MC_ARG(uint8_t *,   pu8Dst,  0); \
-            IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
+            IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
             IEM_MC_ARG(uint32_t *,  pEFlags, 2); \
             IEM_MC_REF_EFLAGS(pEFlags); \
@@ -189,5 +187,5 @@
             IEM_MC_BEGIN(3, 3, 0, 0); \
             IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
-            IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
+            IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, a_bRm, 0); \
             IEMOP_HLP_DONE_DECODING(); \
             IEM_MC_NATIVE_IF(0) { \
@@ -195,5 +193,5 @@
                 IEM_MC_FETCH_MEM_U8(u8Dst, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
                 IEM_MC_LOCAL(uint8_t,       u8SrcEmit); \
-                IEM_MC_FETCH_GREG_U8(u8SrcEmit, IEM_GET_MODRM_REG(pVCpu, bRm)); \
+                IEM_MC_FETCH_GREG_U8(u8SrcEmit, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
                 /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
                 IEM_MC_LOCAL(uint32_t,      uEFlags); \
@@ -206,5 +204,5 @@
                 IEM_MC_MEM_MAP_U8_RO(pu8Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
                 IEM_MC_ARG(uint8_t,         u8Src,           1); \
-                IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
+                IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
                 IEM_MC_ARG_LOCAL_EFLAGS(    pEFlags, EFlags, 2); \
                 IEM_MC_FETCH_EFLAGS(EFlags); \
@@ -543,11 +541,9 @@
  * memory/register as the destination.
  */
-#define IEMOP_BODY_BINARY_rm_rv_RO(a_fnNormalU16, a_fnNormalU32, a_fnNormalU64, a_EmitterBasename, a_fNativeArchs) \
-    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm); \
-    \
+#define IEMOP_BODY_BINARY_rm_rv_RO(a_bRm, a_fnNormalU16, a_fnNormalU32, a_fnNormalU64, a_EmitterBasename, a_fNativeArchs) \
     /* \
      * If rm is denoting a register, no more instruction bytes. \
      */ \
-    if (IEM_IS_MODRM_REG_MODE(bRm)) \
+    if (IEM_IS_MODRM_REG_MODE(a_bRm)) \
     { \
         switch (pVCpu->iem.s.enmEffOpSize) \
@@ -557,8 +553,8 @@
                 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
                 IEM_MC_ARG(uint16_t,   u16Src,  1); \
-                IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
+                IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
                 IEM_MC_NATIVE_IF(a_fNativeArchs) { \
                     IEM_MC_LOCAL(uint16_t,   u16Dst); \
-                    IEM_MC_FETCH_GREG_U16(u16Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
+                    IEM_MC_FETCH_GREG_U16(u16Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
                     /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
                     IEM_MC_LOCAL(uint32_t,  uEFlags); \
@@ -568,5 +564,5 @@
                 } IEM_MC_NATIVE_ELSE() { \
                     IEM_MC_ARG(uint16_t *, pu16Dst, 0); \
-                    IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
+                    IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
                     IEM_MC_ARG(uint32_t *, pEFlags, 2); \
                     IEM_MC_REF_EFLAGS(pEFlags); \
@@ -581,8 +577,8 @@
                 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
                 IEM_MC_ARG(uint32_t,   u32Src,  1); \
-                IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
+                IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
                 IEM_MC_NATIVE_IF(a_fNativeArchs) { \
                     IEM_MC_LOCAL(uint32_t,   u32Dst); \
-                    IEM_MC_FETCH_GREG_U32(u32Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
+                    IEM_MC_FETCH_GREG_U32(u32Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
                     /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
                     IEM_MC_LOCAL(uint32_t,  uEFlags); \
@@ -592,5 +588,5 @@
                 } IEM_MC_NATIVE_ELSE() { \
                     IEM_MC_ARG(uint32_t *, pu32Dst, 0); \
-                    IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
+                    IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
                     IEM_MC_ARG(uint32_t *, pEFlags, 2); \
                     IEM_MC_REF_EFLAGS(pEFlags); \
@@ -605,8 +601,8 @@
                 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); \
                 IEM_MC_ARG(uint64_t,        u64Src,  1); \
-                IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
+                IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
                 IEM_MC_NATIVE_IF(a_fNativeArchs) { \
                     IEM_MC_LOCAL(uint64_t,  u64Dst); \
-                    IEM_MC_FETCH_GREG_U64(u64Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
+                    IEM_MC_FETCH_GREG_U64(u64Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
                     /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
                     IEM_MC_LOCAL(uint32_t,  uEFlags); \
@@ -616,5 +612,5 @@
                 } IEM_MC_NATIVE_ELSE() { \
                     IEM_MC_ARG(uint64_t *,  pu64Dst, 0); \
-                    IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm)); \
+                    IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, a_bRm)); \
                     IEM_MC_ARG(uint32_t *,  pEFlags, 2); \
                     IEM_MC_REF_EFLAGS(pEFlags); \
@@ -642,5 +638,5 @@
                     IEM_MC_BEGIN(3, 3, 0, 0); \
                     IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
-                    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
+                    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, a_bRm, 0); \
                     IEMOP_HLP_DONE_DECODING(); \
                     IEM_MC_NATIVE_IF(a_fNativeArchs) { \
@@ -648,5 +644,5 @@
                         IEM_MC_FETCH_MEM_U16(u16Dst, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
                         IEM_MC_LOCAL(uint16_t,      u16SrcEmit); \
-                        IEM_MC_FETCH_GREG_U16(u16SrcEmit, IEM_GET_MODRM_REG(pVCpu, bRm)); \
+                        IEM_MC_FETCH_GREG_U16(u16SrcEmit, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
                         /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
                         IEM_MC_LOCAL(uint32_t,  uEFlags); \
@@ -659,5 +655,5 @@
                         IEM_MC_MEM_MAP_U16_RO(pu16Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
                         IEM_MC_ARG(uint16_t,         u16Src,          1); \
-                        IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
+                        IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
                         IEM_MC_ARG_LOCAL_EFLAGS(     pEFlags, EFlags, 2); \
                         IEM_MC_FETCH_EFLAGS(EFlags); \
@@ -673,5 +669,5 @@
                     IEM_MC_BEGIN(3, 3, IEM_MC_F_MIN_386, 0); \
                     IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
-                    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
+                    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, a_bRm, 0); \
                     IEMOP_HLP_DONE_DECODING(); \
                     IEM_MC_NATIVE_IF(a_fNativeArchs) { \
@@ -679,5 +675,5 @@
                         IEM_MC_FETCH_MEM_U32(u32Dst, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
                         IEM_MC_LOCAL(uint32_t,      u32SrcEmit); \
-                        IEM_MC_FETCH_GREG_U32(u32SrcEmit, IEM_GET_MODRM_REG(pVCpu, bRm)); \
+                        IEM_MC_FETCH_GREG_U32(u32SrcEmit, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
                         /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
                         IEM_MC_LOCAL(uint32_t,  uEFlags); \
@@ -690,5 +686,5 @@
                         IEM_MC_MEM_MAP_U32_RO(pu32Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
                         IEM_MC_ARG(uint32_t,         u32Src,          1); \
-                        IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
+                        IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
                         IEM_MC_ARG_LOCAL_EFLAGS(     pEFlags, EFlags, 2); \
                         IEM_MC_FETCH_EFLAGS(EFlags); \
@@ -704,5 +700,5 @@
                     IEM_MC_BEGIN(3, 3, IEM_MC_F_64BIT, 0); \
                     IEM_MC_LOCAL(RTGCPTR, GCPtrEffDst); \
-                    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, bRm, 0); \
+                    IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffDst, a_bRm, 0); \
                     IEMOP_HLP_DONE_DECODING(); \
                     IEM_MC_NATIVE_IF(a_fNativeArchs) { \
@@ -710,5 +706,5 @@
                         IEM_MC_FETCH_MEM_U64(u64Dst, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
                         IEM_MC_LOCAL(uint64_t,      u64SrcEmit); \
-                        IEM_MC_FETCH_GREG_U64(u64SrcEmit, IEM_GET_MODRM_REG(pVCpu, bRm)); \
+                        IEM_MC_FETCH_GREG_U64(u64SrcEmit, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
                         /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */ \
                         IEM_MC_LOCAL(uint32_t,  uEFlags); \
@@ -721,5 +717,5 @@
                         IEM_MC_MEM_MAP_U64_RO(pu64Dst, bUnmapInfo, pVCpu->iem.s.iEffSeg, GCPtrEffDst); \
                         IEM_MC_ARG(uint64_t,         u64Src,          1); \
-                        IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm)); \
+                        IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, a_bRm)); \
                         IEM_MC_ARG_LOCAL_EFLAGS(     pEFlags, EFlags, 2); \
                         IEM_MC_FETCH_EFLAGS(EFlags); \
@@ -1779,5 +1775,6 @@
 {
     IEMOP_MNEMONIC(cmp_Eb_Gb, "cmp Eb,Gb");
-    IEMOP_BODY_BINARY_rm_r8_RO(iemAImpl_cmp_u8, cmp, 0);
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+    IEMOP_BODY_BINARY_rm_r8_RO(bRm, iemAImpl_cmp_u8, cmp, 0);
 }
 
@@ -1790,5 +1787,6 @@
 {
     IEMOP_MNEMONIC(cmp_Ev_Gv, "cmp Ev,Gv");
-    IEMOP_BODY_BINARY_rm_rv_RO(iemAImpl_cmp_u16, iemAImpl_cmp_u32, iemAImpl_cmp_u64, cmp, 0);
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+    IEMOP_BODY_BINARY_rm_rv_RO(bRm, iemAImpl_cmp_u16, iemAImpl_cmp_u32, iemAImpl_cmp_u64, cmp, 0);
 }
 
@@ -5361,5 +5359,36 @@
     IEMOP_MNEMONIC(test_Eb_Gb, "test Eb,Gb");
     IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
-    IEMOP_BODY_BINARY_rm_r8_RO(iemAImpl_test_u8, test, RT_ARCH_VAL_AMD64);
+
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+
+    /*
+     * Deal with special case of 'test rN, rN' which is frequently used for testing for zero/non-zero registers.
+     * This block only makes a differences when emitting native code, where we'll save a register fetch.
+     */
+    if (   (bRm >> X86_MODRM_REG_SHIFT) == ((bRm & X86_MODRM_RM_MASK) | (X86_MOD_REG << X86_MODRM_REG_SHIFT))
+        && pVCpu->iem.s.uRexReg == pVCpu->iem.s.uRexB)
+    {
+        IEM_MC_BEGIN(3, 0, 0, 0);
+        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
+        IEM_MC_ARG(uint8_t,         u8Src,   1);
+        IEM_MC_FETCH_GREG_U8(u8Src, IEM_GET_MODRM_REG(pVCpu, bRm));
+        IEM_MC_NATIVE_IF(RT_ARCH_VAL_AMD64) {
+            /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */
+            IEM_MC_LOCAL(uint32_t,  uEFlags);
+            IEM_MC_FETCH_EFLAGS(uEFlags);
+            IEM_MC_NATIVE_EMIT_4(iemNativeEmit_test_r_r_efl, u8Src, u8Src, uEFlags, 8);
+            IEM_MC_COMMIT_EFLAGS(uEFlags);
+        } IEM_MC_NATIVE_ELSE() {
+            IEM_MC_ARG(uint8_t *,   pu8Dst,  0);
+            IEM_MC_REF_GREG_U8(pu8Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
+            IEM_MC_ARG(uint32_t *,  pEFlags, 2);
+            IEM_MC_REF_EFLAGS(pEFlags);
+            IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u8, pu8Dst, u8Src, pEFlags);
+        } IEM_MC_NATIVE_ENDIF();
+        IEM_MC_ADVANCE_RIP_AND_FINISH();
+        IEM_MC_END();
+    }
+
+    IEMOP_BODY_BINARY_rm_r8_RO(bRm, iemAImpl_test_u8, test, RT_ARCH_VAL_AMD64);
 }
 
@@ -5373,5 +5402,87 @@
     IEMOP_MNEMONIC(test_Ev_Gv, "test Ev,Gv");
     IEMOP_VERIFICATION_UNDEFINED_EFLAGS(X86_EFL_AF);
-    IEMOP_BODY_BINARY_rm_rv_RO(iemAImpl_test_u16, iemAImpl_test_u32, iemAImpl_test_u64, test, RT_ARCH_VAL_AMD64);
+
+    uint8_t bRm; IEM_OPCODE_GET_NEXT_U8(&bRm);
+
+    /*
+     * Deal with special case of 'test rN, rN' which is frequently used for testing for zero/non-zero registers.
+     * This block only makes a differences when emitting native code, where we'll save a register fetch.
+     */
+    if (   (bRm >> X86_MODRM_REG_SHIFT) == ((bRm & X86_MODRM_RM_MASK) | (X86_MOD_REG << X86_MODRM_REG_SHIFT))
+        && pVCpu->iem.s.uRexReg == pVCpu->iem.s.uRexB)
+    {
+        switch (pVCpu->iem.s.enmEffOpSize)
+        {
+            case IEMMODE_16BIT:
+                IEM_MC_BEGIN(3, 0, 0, 0);
+                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
+                IEM_MC_ARG(uint16_t,   u16Src,  1);
+                IEM_MC_FETCH_GREG_U16(u16Src, IEM_GET_MODRM_REG(pVCpu, bRm));
+                IEM_MC_NATIVE_IF(RT_ARCH_VAL_AMD64) {
+                    /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */
+                    IEM_MC_LOCAL(uint32_t,  uEFlags);
+                    IEM_MC_FETCH_EFLAGS(uEFlags);
+                    IEM_MC_NATIVE_EMIT_4(iemNativeEmit_test_r_r_efl, u16Src, u16Src, uEFlags, 16);
+                    IEM_MC_COMMIT_EFLAGS(uEFlags);
+                } IEM_MC_NATIVE_ELSE() {
+                    IEM_MC_ARG(uint16_t *, pu16Dst, 0);
+                    IEM_MC_REF_GREG_U16(pu16Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
+                    IEM_MC_ARG(uint32_t *, pEFlags, 2);
+                    IEM_MC_REF_EFLAGS(pEFlags);
+                    IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u16, pu16Dst, u16Src, pEFlags);
+                } IEM_MC_NATIVE_ENDIF();
+                IEM_MC_ADVANCE_RIP_AND_FINISH();
+                IEM_MC_END();
+                break;
+
+            case IEMMODE_32BIT:
+                IEM_MC_BEGIN(3, 0, IEM_MC_F_MIN_386, 0);
+                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
+                IEM_MC_ARG(uint32_t,   u32Src,  1);
+                IEM_MC_FETCH_GREG_U32(u32Src, IEM_GET_MODRM_REG(pVCpu, bRm));
+                IEM_MC_NATIVE_IF(RT_ARCH_VAL_AMD64) {
+                    /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */
+                    IEM_MC_LOCAL(uint32_t,  uEFlags);
+                    IEM_MC_FETCH_EFLAGS(uEFlags);
+                    IEM_MC_NATIVE_EMIT_4(iemNativeEmit_test_r_r_efl, u32Src, u32Src, uEFlags, 32);
+                    IEM_MC_COMMIT_EFLAGS(uEFlags);
+                } IEM_MC_NATIVE_ELSE() {
+                    IEM_MC_ARG(uint32_t *, pu32Dst, 0);
+                    IEM_MC_REF_GREG_U32(pu32Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
+                    IEM_MC_ARG(uint32_t *, pEFlags, 2);
+                    IEM_MC_REF_EFLAGS(pEFlags);
+                    IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u32, pu32Dst, u32Src, pEFlags);
+                } IEM_MC_NATIVE_ENDIF();
+                IEM_MC_ADVANCE_RIP_AND_FINISH();
+                IEM_MC_END();
+                break;
+
+            case IEMMODE_64BIT:
+                IEM_MC_BEGIN(3, 0, IEM_MC_F_64BIT, 0);
+                IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
+                IEM_MC_ARG(uint64_t,        u64Src,  1);
+                IEM_MC_FETCH_GREG_U64(u64Src, IEM_GET_MODRM_REG(pVCpu, bRm));
+                IEM_MC_NATIVE_IF(RT_ARCH_VAL_AMD64) {
+                    /** @todo IEM_MC_LOCAL_EFLAGS(uEFlags); */
+                    IEM_MC_LOCAL(uint32_t,  uEFlags);
+                    IEM_MC_FETCH_EFLAGS(uEFlags);
+                    IEM_MC_NATIVE_EMIT_4(iemNativeEmit_test_r_r_efl, u64Src, u64Src, uEFlags, 64);
+                    IEM_MC_COMMIT_EFLAGS(uEFlags);
+                } IEM_MC_NATIVE_ELSE() {
+                    IEM_MC_ARG(uint64_t *,  pu64Dst, 0);
+                    IEM_MC_REF_GREG_U64(pu64Dst, IEM_GET_MODRM_RM(pVCpu, bRm));
+                    IEM_MC_ARG(uint32_t *,  pEFlags, 2);
+                    IEM_MC_REF_EFLAGS(pEFlags);
+                    IEM_MC_CALL_VOID_AIMPL_3(iemAImpl_test_u64, pu64Dst, u64Src, pEFlags);
+                } IEM_MC_NATIVE_ENDIF();
+                IEM_MC_ADVANCE_RIP_AND_FINISH();
+                IEM_MC_END();
+                break;
+
+            IEM_NOT_REACHED_DEFAULT_CASE_RET();
+        }
+    }
+
+    IEMOP_BODY_BINARY_rm_rv_RO(bRm, iemAImpl_test_u16, iemAImpl_test_u32, iemAImpl_test_u64, test, RT_ARCH_VAL_AMD64);
 }
 
Index: /trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h	(revision 103656)
+++ /trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h	(revision 103657)
@@ -204,5 +204,6 @@
      *        variants, and SF for 32-bit and 64-bit.  */
     uint8_t const         idxRegDst    = iemNativeVarRegisterAcquire(pReNative, idxVarDst, &off, true /*fInitialized*/);
-    uint8_t const         idxRegSrc    = iemNativeVarRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/);
+    uint8_t const         idxRegSrc    = idxVarSrc == idxVarDst ? idxRegDst /* special case of 'test samereg,samereg' */
+                                       : iemNativeVarRegisterAcquire(pReNative, idxVarSrc, &off, true /*fInitialized*/);
 #ifndef RT_ARCH_AMD64
     uint8_t const         idxRegResult = iemNativeRegAllocTmp(pReNative, &off);
@@ -244,5 +245,6 @@
 #endif
     IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
-    iemNativeVarRegisterRelease(pReNative, idxVarSrc);
+    if (idxVarSrc != idxVarDst)
+        iemNativeVarRegisterRelease(pReNative, idxVarSrc);
     iemNativeVarRegisterRelease(pReNative, idxVarDst);
 
