Index: /trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp	(revision 101180)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp	(revision 101181)
@@ -1405,4 +1405,5 @@
     AssertReturn(off != UINT32_MAX, UINT32_MAX);
 #endif
+    uint8_t const cParams = g_acIemThreadedFunctionUsedArgs[pCallEntry->enmFunction];
 
 #ifdef RT_ARCH_AMD64
@@ -1412,19 +1413,37 @@
     off = iemNativeEmitLoadGprFromGpr(pVCpu, off, X86_GREG_xCX, X86_GREG_xBX);
     AssertReturn(off != UINT32_MAX, UINT32_MAX);
-    off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_xDX, pCallEntry->auParams[0]);
-    AssertReturn(off != UINT32_MAX, UINT32_MAX);
-    off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_x8, pCallEntry->auParams[1]);
-    AssertReturn(off != UINT32_MAX, UINT32_MAX);
-    off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_x9, pCallEntry->auParams[2]);
-    AssertReturn(off != UINT32_MAX, UINT32_MAX);
+    if (cParams > 0)
+    {
+        off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_xDX, pCallEntry->auParams[0]);
+        AssertReturn(off != UINT32_MAX, UINT32_MAX);
+    }
+    if (cParams > 1)
+    {
+        off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_x8, pCallEntry->auParams[1]);
+        AssertReturn(off != UINT32_MAX, UINT32_MAX);
+    }
+    if (cParams > 2)
+    {
+        off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_x9, pCallEntry->auParams[2]);
+        AssertReturn(off != UINT32_MAX, UINT32_MAX);
+    }
 #  else  /* VBOXSTRICTRC: Returned via hidden parameter. Sigh. */
     off = iemNativeEmitLoadGprFromGpr(pVCpu, off, X86_GREG_xDX, X86_GREG_xBX);
     AssertReturn(off != UINT32_MAX, UINT32_MAX);
-    off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_x8, pCallEntry->auParams[0]);
-    AssertReturn(off != UINT32_MAX, UINT32_MAX);
-    off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_x9, pCallEntry->auParams[1]);
-    AssertReturn(off != UINT32_MAX, UINT32_MAX);
-    off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_x10, pCallEntry->auParams[2]);
-    AssertReturn(off != UINT32_MAX, UINT32_MAX);
+    if (cParams > 0)
+    {
+        off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_x8, pCallEntry->auParams[0]);
+        AssertReturn(off != UINT32_MAX, UINT32_MAX);
+    }
+    if (cParams > 1)
+    {
+        off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_x9, pCallEntry->auParams[1]);
+        AssertReturn(off != UINT32_MAX, UINT32_MAX);
+    }
+    if (cParams > 2)
+    {
+        off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_x10, pCallEntry->auParams[2]);
+        AssertReturn(off != UINT32_MAX, UINT32_MAX);
+    }
     off = iemNativeEmitStoreGprByBp(pVCpu, off, IEMNATIVE_FP_OFF_STACK_ARG0, X86_GREG_x10);
     AssertReturn(off != UINT32_MAX, UINT32_MAX);
@@ -1435,10 +1454,19 @@
     off = iemNativeEmitLoadGprFromGpr(pVCpu, off, X86_GREG_xDI, X86_GREG_xBX);
     AssertReturn(off != UINT32_MAX, UINT32_MAX);
-    off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_xSI, pCallEntry->auParams[0]);
-    AssertReturn(off != UINT32_MAX, UINT32_MAX);
-    off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_xDX, pCallEntry->auParams[1]);
-    AssertReturn(off != UINT32_MAX, UINT32_MAX);
-    off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_xCX, pCallEntry->auParams[2]);
-    AssertReturn(off != UINT32_MAX, UINT32_MAX);
+    if (cParams > 0)
+    {
+        off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_xSI, pCallEntry->auParams[0]);
+        AssertReturn(off != UINT32_MAX, UINT32_MAX);
+    }
+    if (cParams > 1)
+    {
+        off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_xDX, pCallEntry->auParams[1]);
+        AssertReturn(off != UINT32_MAX, UINT32_MAX);
+    }
+    if (cParams > 2)
+    {
+        off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_xCX, pCallEntry->auParams[2]);
+        AssertReturn(off != UINT32_MAX, UINT32_MAX);
+    }
 # endif
     off = iemNativeEmitLoadGprImm64(pVCpu, off, X86_GREG_xAX, (uintptr_t)g_apfnIemThreadedFunctions[pCallEntry->enmFunction]);
Index: /trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py	(revision 101180)
+++ /trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py	(revision 101181)
@@ -1582,35 +1582,35 @@
         ];
 
-    ## List of built-in threaded functions.
-    kasBltIns = (
-        'DeferToCImpl0',
-        'CheckIrq',
-        'CheckMode',
-        'CheckHwInstrBps',
-        'CheckCsLim',
-
-        'CheckCsLimAndOpcodes',
-        'CheckOpcodes',
-        'CheckOpcodesConsiderCsLim',
-
-        'CheckCsLimAndPcAndOpcodes',
-        'CheckPcAndOpcodes',
-        'CheckPcAndOpcodesConsiderCsLim',
-
-        'CheckCsLimAndOpcodesAcrossPageLoadingTlb',
-        'CheckOpcodesAcrossPageLoadingTlb',
-        'CheckOpcodesAcrossPageLoadingTlbConsiderCsLim',
-
-        'CheckCsLimAndOpcodesLoadingTlb',
-        'CheckOpcodesLoadingTlb',
-        'CheckOpcodesLoadingTlbConsiderCsLim',
-
-        'CheckCsLimAndOpcodesOnNextPageLoadingTlb',
-        'CheckOpcodesOnNextPageLoadingTlb',
-        'CheckOpcodesOnNextPageLoadingTlbConsiderCsLim',
-
-        'CheckCsLimAndOpcodesOnNewPageLoadingTlb',
-        'CheckOpcodesOnNewPageLoadingTlb',
-        'CheckOpcodesOnNewPageLoadingTlbConsiderCsLim',
+    ## List of built-in threaded functions with user argument counts.
+    katBltIns = (
+        ( 'DeferToCImpl0',                                      2 ),
+        ( 'CheckIrq',                                           0 ),
+        ( 'CheckMode',                                          1 ),
+        ( 'CheckHwInstrBps',                                    0 ),
+        ( 'CheckCsLim',                                         1 ),
+
+        ( 'CheckCsLimAndOpcodes',                               3 ),
+        ( 'CheckOpcodes',                                       3 ),
+        ( 'CheckOpcodesConsiderCsLim',                          3 ),
+
+        ( 'CheckCsLimAndPcAndOpcodes',                          3 ),
+        ( 'CheckPcAndOpcodes',                                  3 ),
+        ( 'CheckPcAndOpcodesConsiderCsLim',                     3 ),
+
+        ( 'CheckCsLimAndOpcodesAcrossPageLoadingTlb',           3 ),
+        ( 'CheckOpcodesAcrossPageLoadingTlb',                   3 ),
+        ( 'CheckOpcodesAcrossPageLoadingTlbConsiderCsLim',      2 ),
+
+        ( 'CheckCsLimAndOpcodesLoadingTlb',                     3 ),
+        ( 'CheckOpcodesLoadingTlb',                             3 ),
+        ( 'CheckOpcodesLoadingTlbConsiderCsLim',                3 ),
+
+        ( 'CheckCsLimAndOpcodesOnNextPageLoadingTlb',           2 ),
+        ( 'CheckOpcodesOnNextPageLoadingTlb',                   2 ),
+        ( 'CheckOpcodesOnNextPageLoadingTlbConsiderCsLim',      2 ),
+
+        ( 'CheckCsLimAndOpcodesOnNewPageLoadingTlb',            3 ), # actually 2 params, but asserts uParam2 == 0.
+        ( 'CheckOpcodesOnNewPageLoadingTlb',                    3 ), # actually 2 params, but asserts uParam2 == 0.
+        ( 'CheckOpcodesOnNewPageLoadingTlbConsiderCsLim',       3 ), # actually 2 params, but asserts uParam2 == 0.
     );
 
@@ -1633,5 +1633,5 @@
             '     */',
         ];
-        asLines += ['    kIemThreadedFunc_BltIn_%s,' % (sFuncNm,) for sFuncNm in self.kasBltIns];
+        asLines += ['    kIemThreadedFunc_BltIn_%s,' % (sFuncNm,) for sFuncNm, _ in self.katBltIns];
 
         iThreadedFunction = 1;
@@ -1661,4 +1661,5 @@
             'extern const char * const       g_apszIemThreadedFunctions[kIemThreadedFunc_End];',
             '#endif',
+            'extern uint8_t const            g_acIemThreadedFunctionUsedArgs[kIemThreadedFunc_End];',
         ];
 
@@ -1762,60 +1763,53 @@
 
         #
-        # Emit the function table.
-        #
-        oOut.write(  '\n'
-                   + '\n'
-                   + '/**\n'
-                   + ' * Function table.\n'
-                   + ' */\n'
-                   + 'const PFNIEMTHREADEDFUNC g_apfnIemThreadedFunctions[kIemThreadedFunc_End] =\n'
-                   + '{\n'
-                   + '    /*Invalid*/ NULL,\n'
-                   + '\n'
-                   + '    /*\n'
-                   + '     * Predefined.\n'
-                   + '     */\n');
-        for sFuncNm in self.kasBltIns:
-            oOut.write('    iemThreadedFunc_BltIn_%s,\n' % (sFuncNm,));
+        # Generate the output tables in parallel.
+        #
+        asFuncTable = [
+            '/**',
+            ' * Function pointer table.',
+            ' */',
+            'PFNIEMTHREADEDFUNC const g_apfnIemThreadedFunctions[kIemThreadedFunc_End] =',
+            '{',
+            '    /*Invalid*/ NULL,',
+        ];
+        asNameTable = [
+            '/**',
+            ' * Function name table.',
+            ' */',
+            'const char * const g_apszIemThreadedFunctions[kIemThreadedFunc_End] =',
+            '{',
+            '    "Invalid",',
+        ];
+        asArgCntTab = [
+            '/**',
+            ' * Argument count table.',
+            ' */',
+            'uint8_t const g_acIemThreadedFunctionUsedArgs[kIemThreadedFunc_End] =',
+            '{',
+            '    0, /*Invalid*/',
+        ];
+        aasTables = (asFuncTable, asNameTable, asArgCntTab,);
+
+        for asTable in aasTables:
+            asTable.extend((
+                '',
+                '    /*',
+                '     * Predefined.',
+                '     */',
+            ));
+        for sFuncNm, cArgs in self.katBltIns:
+            asFuncTable.append('    iemThreadedFunc_BltIn_%s,' % (sFuncNm,));
+            asNameTable.append('    "BltIn_%s",' % (sFuncNm,));
+            asArgCntTab.append('    %d, /*BltIn_%s*/' % (cArgs, sFuncNm,));
 
         iThreadedFunction = 1;
         for sVariation in ThreadedFunctionVariation.kasVariationsEmitOrder:
-            oOut.write(  '\n'
-                       + '    /*\n'
-                       + '     * Variation: ' + ThreadedFunctionVariation.kdVariationNames[sVariation] + '\n'
-                       + '     */\n');
-            for oThreadedFunction in self.aoThreadedFuncs:
-                oVariation = oThreadedFunction.dVariations.get(sVariation, None);
-                if oVariation:
-                    iThreadedFunction += 1;
-                    assert oVariation.iEnumValue == iThreadedFunction;
-                    oOut.write('    /*%4u*/ %s,\n' % (iThreadedFunction, oVariation.getFunctionName(),));
-        oOut.write('};\n');
-
-        #
-        # Emit the function name table.
-        #
-        oOut.write(  '\n'
-                   + '\n'
-                   + '#if defined(IN_RING3) || defined(LOG_ENABLED)\n'
-                   + '/**\n'
-                   + ' * Function table.\n'
-                   + ' */\n'
-                   + 'const char * const g_apszIemThreadedFunctions[kIemThreadedFunc_End] =\n'
-                   + '{\n'
-                   + '    "Invalid",\n'
-                   + '\n'
-                   + '    /*\n'
-                   + '     * Predefined.\n'
-                   + '     */\n');
-        for sFuncNm in self.kasBltIns:
-            oOut.write('    "BltIn_%s",\n' % (sFuncNm,));
-
-        iThreadedFunction = 1;
-        for sVariation in ThreadedFunctionVariation.kasVariationsEmitOrder:
-            oOut.write(  '\n'
-                       + '    /*\n'
-                       + '     * Variation: ' + ThreadedFunctionVariation.kdVariationNames[sVariation] + '\n'
-                       + '     */\n');
+            for asTable in aasTables:
+                asTable.extend((
+                    '',
+                    '    /*',
+                    '     * Variation: ' + ThreadedFunctionVariation.kdVariationNames[sVariation],
+                    '     */',
+                ));
             for oThreadedFunction in self.aoThreadedFuncs:
                 oVariation = oThreadedFunction.dVariations.get(sVariation, None);
@@ -1824,9 +1818,28 @@
                     assert oVariation.iEnumValue == iThreadedFunction;
                     sName = oVariation.getFunctionName();
-                    if sName.startswith('iemThreadedFunc_'):
-                        sName = sName[len('iemThreadedFunc_'):];
-                    oOut.write('    /*%4u*/ "%s",\n' % (iThreadedFunction, sName,));
-        oOut.write(  '};\n'
-                   + '#endif /* IN_RING3 || LOG_ENABLED */\n');
+                    asFuncTable.append('    /*%4u*/ %s,' % (iThreadedFunction, sName,));
+                    asNameTable.append('    /*%4u*/ "%s",' % (iThreadedFunction, sName,));
+                    asArgCntTab.append('    /*%4u*/ %d, /*%s*/' % (iThreadedFunction, oVariation.cMinParams, sName,));
+
+        for asTable in aasTables:
+            asTable.append('};');
+
+        #
+        # Output the tables.
+        #
+        oOut.write(  '\n'
+                   + '\n');
+        oOut.write('\n'.join(asFuncTable));
+        oOut.write(  '\n'
+                   + '\n'
+                   + '\n'
+                   + '#if defined(IN_RING3) || defined(LOG_ENABLED)\n');
+        oOut.write('\n'.join(asNameTable));
+        oOut.write(  '\n'
+                   + '#endif /* IN_RING3 || LOG_ENABLED */\n'
+                   + '\n'
+                   + '\n');
+        oOut.write('\n'.join(asArgCntTab));
+        oOut.write('\n');
 
         return True;
