Index: trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h	(revision 106315)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompFuncs.h	(revision 106319)
@@ -2057,5 +2057,5 @@
     uint8_t const idxPcRegOld = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc,
                                                                 kIemNativeGstRegUse_Calculation, true /*fNoVolatileRegs*/);
-    uint8_t const idxPcRegNew = iemNativeRegAllocTmp(pReNative, &off, false /*fPreferVolatile*/);
+    uint8_t const idxPcRegNew = iemNativeRegAllocTmpPreferNonVolatile(pReNative, &off);
 
     /* Calculate the new RIP. */
@@ -2127,5 +2127,5 @@
     uint8_t const idxPcRegOld = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc,
                                                                 kIemNativeGstRegUse_ReadOnly, true /*fNoVolatileRegs*/);
-    uint8_t const idxPcRegNew = iemNativeRegAllocTmp(pReNative, &off, false /*fPreferVolatile*/);
+    uint8_t const idxPcRegNew = iemNativeRegAllocTmpPreferNonVolatile(pReNative, &off);
 
     /* Update the EIP to get the return address. */
@@ -2194,5 +2194,5 @@
     uint8_t const idxPcRegOld = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_Pc,
                                                                 kIemNativeGstRegUse_ReadOnly, true /*fNoVolatileRegs*/);
-    uint8_t const idxPcRegNew = iemNativeRegAllocTmp(pReNative, &off, false /*fPreferVolatile*/);
+    uint8_t const idxPcRegNew = iemNativeRegAllocTmpPreferNonVolatile(pReNative, &off);
 
     /* Update the RIP to get the return address. */
@@ -9797,5 +9797,5 @@
         }
 
-        uint8_t const idxRegTmp = iemNativeRegAllocTmp(pReNative, &off, false /*fPreferVolatile*/);
+        uint8_t const idxRegTmp = iemNativeRegAllocTmpPreferNonVolatile(pReNative, &off);
         uint8_t const idxRegMxCsr = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_MxCsr,
                                                                     kIemNativeGstRegUse_ReadOnly);
@@ -9829,5 +9829,5 @@
 
 # elif defined(RT_ARCH_ARM64)
-        uint8_t const idxRegTmp = iemNativeRegAllocTmp(pReNative, &off, false /*fPreferVolatile*/);
+        uint8_t const idxRegTmp = iemNativeRegAllocTmpPreferNonVolatile(pReNative, &off);
 
         /* Need to save the host floating point control register the first time, clear FPSR. */
Index: trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp	(revision 106315)
+++ trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp	(revision 106319)
@@ -3472,5 +3472,5 @@
  *                          This will be update if we need to move a variable from
  *                          register to stack in order to satisfy the request.
- * @param   fPreferVolatile Whether to prefer volatile over non-volatile
+ * @param   a_fPreferVolatile Whether to prefer volatile over non-volatile
  *                          registers (@c true, default) or the other way around
  *                          (@c false, for iemNativeRegAllocTmpForGuestReg()).
@@ -3478,5 +3478,6 @@
  * @note    Must not modify the host status flags!
  */
-DECL_HIDDEN_THROW(uint8_t) iemNativeRegAllocTmp(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, bool fPreferVolatile /*= true*/)
+template<bool const a_fPreferVolatile>
+DECL_FORCE_INLINE_THROW(uint8_t) iemNativeRegAllocTmpInt(PIEMRECOMPILERSTATE pReNative, uint32_t *poff)
 {
     /*
@@ -3489,5 +3490,5 @@
     if (fRegs)
     {
-        if (fPreferVolatile)
+        if (a_fPreferVolatile)
             idxReg = (uint8_t)ASMBitFirstSetU32(  fRegs & IEMNATIVE_CALL_VOLATILE_GREG_MASK
                                                 ? fRegs & IEMNATIVE_CALL_VOLATILE_GREG_MASK : fRegs) - 1;
@@ -3501,9 +3502,23 @@
     else
     {
-        idxReg = iemNativeRegAllocFindFree(pReNative, poff, fPreferVolatile);
+        idxReg = iemNativeRegAllocFindFree(pReNative, poff, a_fPreferVolatile);
         AssertStmt(idxReg != UINT8_MAX, IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_REG_ALLOCATOR_NO_FREE_TMP));
         Log12(("iemNativeRegAllocTmp: %s (slow)\n", g_apszIemNativeHstRegNames[idxReg]));
     }
     return iemNativeRegMarkAllocated(pReNative, idxReg, kIemNativeWhat_Tmp);
+}
+
+
+/** See iemNativeRegAllocTmpInt for details.   */
+DECL_HIDDEN_THROW(uint8_t) iemNativeRegAllocTmp(PIEMRECOMPILERSTATE pReNative, uint32_t *poff)
+{
+    return iemNativeRegAllocTmpInt<true>(pReNative, poff);
+}
+
+
+/** See iemNativeRegAllocTmpInt for details.   */
+DECL_HIDDEN_THROW(uint8_t) iemNativeRegAllocTmpPreferNonVolatile(PIEMRECOMPILERSTATE pReNative, uint32_t *poff)
+{
+    return iemNativeRegAllocTmpInt<false>(pReNative, poff);
 }
 
@@ -3524,6 +3539,6 @@
  *                          (@c false, for iemNativeRegAllocTmpForGuestReg()).
  */
-DECL_HIDDEN_THROW(uint8_t) iemNativeRegAllocTmpEx(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint32_t fRegMask,
-                                                  bool fPreferVolatile /*= true*/)
+template<bool const a_fPreferVolatile>
+DECL_FORCE_INLINE_THROW(uint8_t) iemNativeRegAllocTmpExInt(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint32_t fRegMask)
 {
     Assert(!(fRegMask & ~IEMNATIVE_HST_GREG_MASK));
@@ -3540,5 +3555,5 @@
     if (fRegs)
     {
-        if (fPreferVolatile)
+        if RT_CONSTEXPR_IF(a_fPreferVolatile)
             idxReg = (uint8_t)ASMBitFirstSetU32(  fRegs & IEMNATIVE_CALL_VOLATILE_GREG_MASK
                                                 ? fRegs & IEMNATIVE_CALL_VOLATILE_GREG_MASK : fRegs) - 1;
@@ -3548,11 +3563,62 @@
         Assert(pReNative->Core.aHstRegs[idxReg].fGstRegShadows == 0);
         Assert(!(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxReg)));
-        Log12(("iemNativeRegAllocTmpEx: %s\n", g_apszIemNativeHstRegNames[idxReg]));
+        Log12(("iemNativeRegAllocTmpExInt: %s\n", g_apszIemNativeHstRegNames[idxReg]));
     }
     else
     {
-        idxReg = iemNativeRegAllocFindFree(pReNative, poff, fPreferVolatile, fRegMask);
+        idxReg = iemNativeRegAllocFindFree(pReNative, poff, a_fPreferVolatile, fRegMask);
         AssertStmt(idxReg != UINT8_MAX, IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_REG_ALLOCATOR_NO_FREE_TMP));
-        Log12(("iemNativeRegAllocTmpEx: %s (slow)\n", g_apszIemNativeHstRegNames[idxReg]));
+        Log12(("iemNativeRegAllocTmpExInt: %s (slow)\n", g_apszIemNativeHstRegNames[idxReg]));
+    }
+    return iemNativeRegMarkAllocated(pReNative, idxReg, kIemNativeWhat_Tmp);
+}
+
+
+/** See iemNativeRegAllocTmpExInt for details. */
+DECL_HIDDEN_THROW(uint8_t) iemNativeRegAllocTmpEx(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint32_t fRegMask)
+{
+    return iemNativeRegAllocTmpExInt<true>(pReNative, poff, fRegMask);
+}
+
+
+/** See iemNativeRegAllocTmpExInt for details. */
+DECL_HIDDEN_THROW(uint8_t) iemNativeRegAllocTmpExPreferNonVolatile(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint32_t fRegMask)
+{
+    return iemNativeRegAllocTmpExInt<false>(pReNative, poff, fRegMask);
+}
+
+
+/** Internal templated variation of iemNativeRegAllocTmpEx. */
+template<uint32_t const a_fRegMask, bool const a_fPreferVolatile>
+DECL_FORCE_INLINE_THROW(uint8_t) iemNativeRegAllocTmpExInt(PIEMRECOMPILERSTATE pReNative, uint32_t *poff)
+{
+    AssertCompile(!(a_fRegMask & ~IEMNATIVE_HST_GREG_MASK));
+    AssertCompile(!(a_fRegMask & IEMNATIVE_REG_FIXED_MASK));
+
+    /*
+     * Try find a completely unused register, preferably a call-volatile one.
+     */
+    uint8_t  idxReg;
+    uint32_t fRegs = ~pReNative->Core.bmHstRegs
+                   & ~pReNative->Core.bmHstRegsWithGstShadow
+                   & (~IEMNATIVE_REG_FIXED_MASK & IEMNATIVE_HST_GREG_MASK)
+                   & a_fRegMask;
+    if (fRegs)
+    {
+        if RT_CONSTEXPR_IF(a_fPreferVolatile)
+            idxReg = (uint8_t)ASMBitFirstSetU32(  fRegs & IEMNATIVE_CALL_VOLATILE_GREG_MASK
+                                                ? fRegs & IEMNATIVE_CALL_VOLATILE_GREG_MASK : fRegs) - 1;
+        else
+            idxReg = (uint8_t)ASMBitFirstSetU32(  fRegs & ~IEMNATIVE_CALL_VOLATILE_GREG_MASK
+                                                ? fRegs & ~IEMNATIVE_CALL_VOLATILE_GREG_MASK : fRegs) - 1;
+        Assert(pReNative->Core.aHstRegs[idxReg].fGstRegShadows == 0);
+        Assert(!(pReNative->Core.bmHstRegsWithGstShadow & RT_BIT_32(idxReg)));
+        Log12(("iemNativeRegAllocTmpExInt: %s\n", g_apszIemNativeHstRegNames[idxReg]));
+    }
+    else
+    {
+        idxReg = iemNativeRegAllocFindFree(pReNative, poff, a_fPreferVolatile, a_fRegMask);
+        AssertStmt(idxReg != UINT8_MAX, IEMNATIVE_DO_LONGJMP(pReNative, VERR_IEM_REG_ALLOCATOR_NO_FREE_TMP));
+        Log12(("iemNativeRegAllocTmpExInt: %s (slow)\n", g_apszIemNativeHstRegNames[idxReg]));
     }
     return iemNativeRegMarkAllocated(pReNative, idxReg, kIemNativeWhat_Tmp);
@@ -3575,14 +3641,11 @@
  * @param   uImm            The immediate value that the register must hold upon
  *                          return.
- * @param   fPreferVolatile Whether to prefer volatile over non-volatile
- *                          registers (@c true, default) or the other way around
- *                          (@c false).
- *
+ * @note    Prefers volatile registers.
  * @note    Reusing immediate values has not been implemented yet.
  */
 DECL_HIDDEN_THROW(uint8_t)
-iemNativeRegAllocTmpImm(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint64_t uImm, bool fPreferVolatile /*= true*/)
-{
-    uint8_t const idxReg = iemNativeRegAllocTmp(pReNative, poff, fPreferVolatile);
+iemNativeRegAllocTmpImm(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint64_t uImm)
+{
+    uint8_t const idxReg = iemNativeRegAllocTmp(pReNative, poff);
     *poff = iemNativeEmitLoadGprImm64(pReNative, *poff, idxReg, uImm);
     return idxReg;
@@ -3630,5 +3693,5 @@
                     & (~IEMNATIVE_REG_FIXED_MASK & IEMNATIVE_HST_GREG_MASK)))
             {
-                uint8_t const idxRegNew = iemNativeRegAllocTmpEx(pReNative, poff, a_fRegMask);
+                uint8_t const idxRegNew = iemNativeRegAllocTmpExInt<a_fRegMask, true>(pReNative, poff);
 
                 *poff = iemNativeEmitLoadGprFromGpr(pReNative, *poff, idxRegNew, idxReg);
@@ -3662,7 +3725,8 @@
             {
                 Assert(!(a_fRegMask & IEMNATIVE_CALL_VOLATILE_GREG_MASK));
-                uint8_t const idxRegNew = iemNativeRegAllocTmpEx(pReNative, poff, a_fRegMask & ~RT_BIT_32(idxReg),
-                                                                    (a_fRegMask & IEMNATIVE_CALL_VOLATILE_GREG_MASK)
-                                                                 && a_enmIntendedUse == kIemNativeGstRegUse_Calculation);
+                uint8_t const idxRegNew =    (a_fRegMask & IEMNATIVE_CALL_VOLATILE_GREG_MASK)
+                                          && a_enmIntendedUse == kIemNativeGstRegUse_Calculation
+                                        ? iemNativeRegAllocTmpEx(pReNative, poff, a_fRegMask & ~RT_BIT_32(idxReg))
+                                        : iemNativeRegAllocTmpExPreferNonVolatile(pReNative, poff, a_fRegMask & ~RT_BIT_32(idxReg));
                 *poff = iemNativeEmitLoadGprFromGpr(pReNative, *poff, idxRegNew, idxReg);
                 if RT_CONSTEXPR_IF(a_enmIntendedUse != kIemNativeGstRegUse_Calculation)
@@ -3694,6 +3758,7 @@
 
             /** @todo share register for readonly access. */
-            uint8_t const idxRegNew = iemNativeRegAllocTmpEx(pReNative, poff, a_fRegMask,
-                                                             a_enmIntendedUse == kIemNativeGstRegUse_Calculation);
+            uint8_t const idxRegNew = a_enmIntendedUse == kIemNativeGstRegUse_Calculation
+                                    ? iemNativeRegAllocTmpExInt<a_fRegMask, true>(pReNative, poff)
+                                    : iemNativeRegAllocTmpExInt<a_fRegMask, false>(pReNative, poff);
 
             if RT_CONSTEXPR_IF(a_enmIntendedUse != kIemNativeGstRegUse_ForFullWrite)
@@ -3743,6 +3808,7 @@
      * Allocate a new register, load it with the guest value and designate it as a copy of the
      */
-    uint8_t const idxRegNew = iemNativeRegAllocTmpEx(pReNative, poff, a_fRegMask,
-                                                     a_enmIntendedUse == kIemNativeGstRegUse_Calculation);
+    uint8_t const idxRegNew = a_enmIntendedUse != kIemNativeGstRegUse_Calculation
+                            ? iemNativeRegAllocTmpExInt<a_fRegMask, false>(pReNative, poff)
+                            : iemNativeRegAllocTmpExInt<a_fRegMask, true>(pReNative, poff);
 
     if RT_CONSTEXPR_IF(a_enmIntendedUse != kIemNativeGstRegUse_ForFullWrite)
Index: trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h
===================================================================
--- trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h	(revision 106315)
+++ trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllN8veEmit-x86.h	(revision 106319)
@@ -599,5 +599,5 @@
         pReNative->PostponedEfl.enmOp    = kIemNativePostponedEflOp_Logical;
         pReNative->PostponedEfl.cOpBits  = cOpBits;
-        pReNative->PostponedEfl.idxReg1  = iemNativeRegAllocTmpEx(pReNative, &off, IEMNATIVE_POSTPONING_REG_MASK, false);
+        pReNative->PostponedEfl.idxReg1  = iemNativeRegAllocTmpExPreferNonVolatile(pReNative, &off, IEMNATIVE_POSTPONING_REG_MASK);
         /** @todo it would normally be possible to use idxRegResult, iff it is
          *        already a non-volatile register and we can be user the caller
Index: trunk/src/VBox/VMM/include/IEMN8veRecompiler.h
===================================================================
--- trunk/src/VBox/VMM/include/IEMN8veRecompiler.h	(revision 106315)
+++ trunk/src/VBox/VMM/include/IEMN8veRecompiler.h	(revision 106319)
@@ -2225,9 +2225,9 @@
 DECL_HIDDEN_THROW(PIEMNATIVEINSTR) iemNativeInstrBufEnsureSlow(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t cInstrReq);
 
-DECL_HIDDEN_THROW(uint8_t)  iemNativeRegAllocTmp(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, bool fPreferVolatile = true);
-DECL_HIDDEN_THROW(uint8_t)  iemNativeRegAllocTmpEx(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint32_t fRegMask,
-                                                   bool fPreferVolatile = true);
-DECL_HIDDEN_THROW(uint8_t)  iemNativeRegAllocTmpImm(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint64_t uImm,
-                                                    bool fPreferVolatile = true);
+DECL_HIDDEN_THROW(uint8_t)  iemNativeRegAllocTmp(PIEMRECOMPILERSTATE pReNative, uint32_t *poff);
+DECL_HIDDEN_THROW(uint8_t)  iemNativeRegAllocTmpPreferNonVolatile(PIEMRECOMPILERSTATE pReNative, uint32_t *poff);
+DECL_HIDDEN_THROW(uint8_t)  iemNativeRegAllocTmpEx(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint32_t fRegMask);
+DECL_HIDDEN_THROW(uint8_t)  iemNativeRegAllocTmpExPreferNonVolatile(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint32_t fRegMask);
+DECL_HIDDEN_THROW(uint8_t)  iemNativeRegAllocTmpImm(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, uint64_t uImm);
 
 DECL_HIDDEN_THROW(uint8_t)  iemNativeRegAllocTmpForGuestRegReadOnly(PIEMRECOMPILERSTATE pReNative, uint32_t *poff, IEMNATIVEGSTREG enmGstReg);
