Index: trunk/include/iprt/armv8.h
===================================================================
--- trunk/include/iprt/armv8.h	(revision 104291)
+++ trunk/include/iprt/armv8.h	(revision 104292)
@@ -4613,4 +4613,45 @@
 
 
+/** Armv8 USHR/USRA/URSRA/SSHR/SRSA/SSHR vector element size.    */
+typedef enum ARMV8INSTRUSHIFTSZ
+{
+    kArmv8InstrShiftSz_U8  = 16,  /**< Byte. */
+    kArmv8InstrShiftSz_U16 = 32,  /**< Halfword. */
+    kArmv8InstrShiftSz_U32 = 64,  /**< 32-bit. */
+    kArmv8InstrShiftSz_U64 = 128  /**< 64-bit. */
+} ARMV8INSTRUSHIFTSZ;
+
+/**
+ * A64: Encodes USHR/USRA/URSRA/SSHR/SRSA/SSHR (vector, register).
+ *
+ * @returns The encoded instruction.
+ * @param   iVecRegDst  The vector register to put the result into.
+ * @param   iVecRegSrc  The vector source register.
+ * @param   enmSz       Element size.
+ * @param   fUnsigned   Flag whether this a signed or unsigned shift,
+ * @param   fRound      Flag whether this is the rounding shift variant.
+ * @param   fAccum      Flag whether this is the accumulate shift variant.
+ * @param   f128Bit     Flag whether this operates on the full 128-bit (true, default) of the vector register
+ *                      or just the low 64-bit (false).
+ */
+DECL_FORCE_INLINE(uint32_t) Armv8A64MkVecInstrShrImm(uint32_t iVecRegDst, uint32_t iVecRegSrc, uint8_t cShift, ARMV8INSTRUSHIFTSZ enmSz,
+                                                     bool fUnsigned = true, bool fRound = false, bool fAccum = false, bool f128Bit = true)
+{
+    Assert(iVecRegDst < 32); Assert(iVecRegSrc < 32);
+    Assert(   cShift >= 1
+           && (   (enmSz == kArmv8InstrShiftSz_U8 &&  cShift <= 8)
+               || (enmSz == kArmv8InstrShiftSz_U16 && cShift <= 16)
+               || (enmSz == kArmv8InstrShiftSz_U32 && cShift <= 32)
+               || (enmSz == kArmv8InstrShiftSz_U64 && cShift <= 64)));
+
+    return UINT32_C(0xf000400)
+         | ((uint32_t)f128Bit << 30)
+         | ((uint32_t)fUnsigned << 29)
+         | (((uint32_t)enmSz - cShift) << 16)
+         | ((uint32_t)fRound << 13)
+         | ((uint32_t)fAccum << 12)
+         | (iVecRegSrc << 5)
+         | iVecRegDst;
+}
 /** @} */
 
Index: trunk/src/VBox/VMM/VMMAll/IEMAllInstTwoByte0f.cpp.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllInstTwoByte0f.cpp.h	(revision 104291)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllInstTwoByte0f.cpp.h	(revision 104292)
@@ -6580,5 +6580,5 @@
 {
 //    IEMOP_MNEMONIC2(RI, PSRLW, psrlw, Ux, Ib, DISOPTYPE_HARMLESS | DISOPTYPE_X86_SSE, 0);
-    SSE2_SHIFT_BODY_Imm(psrlw, bRm, 0);
+    SSE2_SHIFT_BODY_Imm(psrlw, bRm, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
 }
 
@@ -6657,5 +6657,5 @@
 {
 //    IEMOP_MNEMONIC2(RI, PSRLD, psrld, Ux, Ib, DISOPTYPE_HARMLESS | DISOPTYPE_X86_SSE, 0);
-    SSE2_SHIFT_BODY_Imm(psrld, bRm, 0);
+    SSE2_SHIFT_BODY_Imm(psrld, bRm, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
 }
 
@@ -6732,5 +6732,5 @@
 {
 //    IEMOP_MNEMONIC2(RI, PSRLQ, psrlq, Ux, Ib, DISOPTYPE_HARMLESS | DISOPTYPE_X86_SSE, 0);
-    SSE2_SHIFT_BODY_Imm(psrlq, bRm, 0);
+    SSE2_SHIFT_BODY_Imm(psrlq, bRm, RT_ARCH_VAL_AMD64 | RT_ARCH_VAL_ARM64);
 }
 
Index: trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h	(revision 104291)
+++ trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h	(revision 104292)
@@ -2042,4 +2042,59 @@
     return off;
 }
+
+
+/**
+ * Common emitter for the shift right with immediate instructions.
+ */
+#ifdef RT_ARCH_AMD64
+# define IEMNATIVE_NATIVE_EMIT_SHIFT_RIGHT_IMM_U128(a_Instr, a_cShiftMax, a_ArmElemSz, a_bOpcX86) \
+    DECL_INLINE_THROW(uint32_t) \
+    RT_CONCAT3(iemNativeEmit_,a_Instr,_ri_u128)(PIEMRECOMPILERSTATE pReNative, uint32_t off, \
+                                                uint8_t const idxSimdGstRegDst, uint8_t const bImm) \
+    { \
+        if (bImm) \
+        { \
+            uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegDst), \
+                                                                                  kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForUpdate); \
+            PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5); \
+            pCodeBuf[off++] = X86_OP_PRF_SIZE_OP; \
+            if (idxSimdRegDst >= 8) \
+                pCodeBuf[off++] = X86_OP_REX_B; \
+            pCodeBuf[off++] = 0x0f; \
+            pCodeBuf[off++] = (a_bOpcX86); \
+            pCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 2, idxSimdRegDst & 7); \
+            pCodeBuf[off++] = bImm; \
+            iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); \
+            IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); \
+        } \
+        /* Immediate 0 is a nop. */ \
+        return off; \
+    }
+#elif defined(RT_ARCH_ARM64)
+# define IEMNATIVE_NATIVE_EMIT_SHIFT_RIGHT_IMM_U128(a_Instr, a_cShiftMax, a_ArmElemSz, a_bOpcX86) \
+    DECL_INLINE_THROW(uint32_t) \
+    RT_CONCAT3(iemNativeEmit_,a_Instr,_ri_u128)(PIEMRECOMPILERSTATE pReNative, uint32_t off, \
+                                                uint8_t const idxSimdGstRegDst, uint8_t const bImm) \
+    { \
+        if (bImm) \
+        { \
+            uint8_t const idxSimdRegDst = iemNativeSimdRegAllocTmpForGuestSimdReg(pReNative, &off, IEMNATIVEGSTSIMDREG_SIMD(idxSimdGstRegDst), \
+                                                                                  kIemNativeGstSimdRegLdStSz_Low128, kIemNativeGstRegUse_ForUpdate); \
+            PIEMNATIVEINSTR const pCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1); \
+            pCodeBuf[off++] = Armv8A64MkVecInstrShrImm(idxSimdRegDst, idxSimdRegDst, RT_MIN(bImm, (a_cShiftMax)), (a_ArmElemSz)); \
+            iemNativeSimdRegFreeTmp(pReNative, idxSimdRegDst); \
+            IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off); \
+        } \
+        /* Immediate 0 is a nop. */ \
+        return off; \
+    }
+#else
+# error "Port me"
+#endif
+
+IEMNATIVE_NATIVE_EMIT_SHIFT_RIGHT_IMM_U128(psrlw, 16, kArmv8InstrShiftSz_U16, 0x71);
+IEMNATIVE_NATIVE_EMIT_SHIFT_RIGHT_IMM_U128(psrld, 32, kArmv8InstrShiftSz_U32, 0x72);
+IEMNATIVE_NATIVE_EMIT_SHIFT_RIGHT_IMM_U128(psrlq, 64, kArmv8InstrShiftSz_U64, 0x73);
+
 #endif
 
Index: trunk/src/VBox/VMM/include/IEMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/IEMInternal.h	(revision 104291)
+++ trunk/src/VBox/VMM/include/IEMInternal.h	(revision 104292)
@@ -2042,5 +2042,5 @@
     /** Statistics per threaded function call.
      * Updated by both the threaded and native recompilers. */
-    uint32_t                acThreadedFuncStats[0x5100 /*20736*/];
+    uint32_t                acThreadedFuncStats[0x5120 /*20768*/];
 # endif
 #endif
