Index: trunk/src/VBox/Runtime/Makefile.kmk
===================================================================
--- trunk/src/VBox/Runtime/Makefile.kmk	(revision 44255)
+++ trunk/src/VBox/Runtime/Makefile.kmk	(revision 44260)
@@ -182,4 +182,5 @@
 	common/asm/ASMAtomicCmpXchgU8.asm \
 	common/asm/ASMMultU64ByU32DivByU32.asm \
+	common/asm/ASMCpuId_Idx_ECX.asm \
 	common/asm/ASMNopPause.asm
 
@@ -189,5 +190,6 @@
 RuntimeWin32ASM_SOURCES = \
 	common/asm/ASMAtomicCmpXchgU8.asm \
-	common/asm/ASMMultU64ByU32DivByU32.asm
+	common/asm/ASMMultU64ByU32DivByU32.asm \
+	common/asm/ASMCpuId_Idx_ECX.asm
 
 #
Index: trunk/src/VBox/Runtime/common/asm/ASMCpuId_Idx_ECX.asm
===================================================================
--- trunk/src/VBox/Runtime/common/asm/ASMCpuId_Idx_ECX.asm	(revision 44260)
+++ trunk/src/VBox/Runtime/common/asm/ASMCpuId_Idx_ECX.asm	(revision 44260)
@@ -0,0 +1,116 @@
+; $Id$
+;; @file
+; IPRT - ASMCpuId_Idx_ECX().
+;
+
+;
+; Copyright (C) 2012 Oracle Corporation
+;
+; This file is part of VirtualBox Open Source Edition (OSE), as
+; available from http://www.virtualbox.org. This file is free software;
+; you can redistribute it and/or modify it under the terms of the GNU
+; General Public License (GPL) as published by the Free Software
+; Foundation, in version 2 as it comes in the "COPYING" file of the
+; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+;
+; The contents of this file may alternatively be used under the terms
+; of the Common Development and Distribution License Version 1.0
+; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
+; VirtualBox OSE distribution, in which case the provisions of the
+; CDDL are applicable instead of those of the GPL.
+;
+; You may elect to license modified versions of this file under the
+; terms and conditions of either the GPL or the CDDL or both.
+;
+
+;*******************************************************************************
+;* Header Files                                                                *
+;*******************************************************************************
+%include "iprt/asmdefs.mac"
+
+BEGINCODE
+
+;;
+; CPUID with EAX and ECX inputs, returning ALL output registers.
+;
+; @param    uOperator   x86:ebp+8   gcc:rdi  msc:rcx
+; @param    uIdxECX     x86:ebp+c   gcc:rsi  msc:rdx
+; @param    pvEAX       x86:ebp+10  gcc:rcx  msc:r8
+; @param    pvEBX       x86:ebp+14  gcc:rdx  msc:r9
+; @param    pvECX       x86:ebp+18  gcc:r8   msc:rsp+28h
+; @param    pvEDX       x86:ebp+1c  gcc:r9   msc:rsp+30h
+;
+; @returns  void
+;
+BEGINPROC_EXPORTED ASMCpuId_Idx_ECX
+%ifdef RT_ARCH_AMD64
+        mov     r10, rbx
+
+ %ifdef ASM_CALL64_MSC
+
+        mov     eax, ecx
+        mov     ecx, edx
+        xor     ebx, ebx
+        xor     edx, edx
+
+        cpuid
+
+        mov     [r8], eax
+        mov     [r9], ebx
+        mov     rax, [rsp + 28h]
+        mov     rbx, [rsp + 30h]
+        mov     [rax], ecx
+        mov     [rbx], edx
+
+ %else
+        mov     eax, edi
+        xchg    rcx, rsi
+        mov     ecx, ecx                ; paranoia: clear upper bits
+        mov     r11, rdx
+        xor     ebx, ebx
+        xor     edx, edx
+
+        cpuid
+
+        mov     [rsi], eax
+        mov     [r11], ebx
+        mov     [r8], ecx
+        mov     [r9], edx
+
+ %endif
+
+        mov     rbx, r10
+        ret
+
+%elifdef RT_ARCH_X86
+        push    ebp
+        mov     ebp, esp
+        push    ebx
+        push    edi
+
+        xor     edx, edx
+        xor     ebx, ebx
+        mov     eax, [ebp + 08h]
+        mov     ecx, [ebp + 0ch]
+
+        cpuid
+
+        mov     edi, [ebp + 10h]
+        mov     [edi], eax
+        mov     edi, [ebp + 14h]
+        mov     [edi], ebx
+        mov     edi, [ebp + 18h]
+        mov     [edi], ecx
+        mov     edi, [ebp + 1ch]
+        mov     [edi], edx
+
+        pop     edi
+        pop     ebx
+        leave
+        ret
+%else
+ %error unsupported arch
+%endif
+ENDPROC ASMCpuId_Idx_ECX
+
Index: trunk/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp
===================================================================
--- trunk/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp	(revision 44255)
+++ trunk/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp	(revision 44260)
@@ -210,22 +210,47 @@
                       iStd, s.uEAX, s.uEBX, s.uECX, s.uEDX, iStd <= cFunctions ? "" : "*");
 
-        if (iStd == 0x04 || iStd == 0x0b || iStd == 0x0d || iStd > cFunctions)
-            continue; /* Leaf 04 and leaf 0d output depend on the initial value of ECX
-                       * The same seems to apply to invalid standard functions */
-
-        u32 = ASMCpuId_EAX(iStd);
-        CHECKVAL(u32, s.uEAX, "%x");
-        u32 = ASMCpuId_EBX(iStd);
-        CHECKVAL(u32, s.uEBX, "%x");
-        u32 = ASMCpuId_ECX(iStd);
-        CHECKVAL(u32, s.uECX, "%x");
-        u32 = ASMCpuId_EDX(iStd);
-        CHECKVAL(u32, s.uEDX, "%x");
-
-        uECX2 = s.uECX - 1;
-        uEDX2 = s.uEDX - 1;
-        ASMCpuId_ECX_EDX(iStd, &uECX2, &uEDX2);
-        CHECKVAL(uECX2, s.uECX, "%x");
-        CHECKVAL(uEDX2, s.uEDX, "%x");
+        /* Leaf 04 and leaf 0d output depend on the initial value of ECX
+         * The same seems to apply to invalid standard functions */
+        if (iStd > cFunctions)
+            continue;
+        if (iStd != 0x04 && iStd != 0x0b && iStd != 0x0d)
+        {
+            u32 = ASMCpuId_EAX(iStd);
+            CHECKVAL(u32, s.uEAX, "%x");
+            u32 = ASMCpuId_EBX(iStd);
+            CHECKVAL(u32, s.uEBX, "%x");
+            u32 = ASMCpuId_ECX(iStd);
+            CHECKVAL(u32, s.uECX, "%x");
+            u32 = ASMCpuId_EDX(iStd);
+            CHECKVAL(u32, s.uEDX, "%x");
+
+            uECX2 = s.uECX - 1;
+            uEDX2 = s.uEDX - 1;
+            ASMCpuId_ECX_EDX(iStd, &uECX2, &uEDX2);
+            CHECKVAL(uECX2, s.uECX, "%x");
+            CHECKVAL(uEDX2, s.uEDX, "%x");
+        }
+
+        if (iStd == 0x04)
+            for (uint32_t uECX = 1; s.uEAX & 0x1f; uECX++)
+            {
+                ASMCpuId_Idx_ECX(iStd, uECX, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
+                RTTestIPrintf(RTTESTLVL_ALWAYS, "    [%02x]  %08x %08x %08x %08x\n", uECX, s.uEAX, s.uEBX, s.uECX, s.uEDX);
+                RTTESTI_CHECK_BREAK(uECX < 128);
+            }
+        else if (iStd == 0x0b)
+            for (uint32_t uECX = 1; (s.uEAX & 0x1f) && (s.uEBX & 0xffff); uECX++)
+            {
+                ASMCpuId_Idx_ECX(iStd, uECX, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
+                RTTestIPrintf(RTTESTLVL_ALWAYS, "    [%02x]  %08x %08x %08x %08x\n", uECX, s.uEAX, s.uEBX, s.uECX, s.uEDX);
+                RTTESTI_CHECK_BREAK(uECX < 128);
+            }
+        else if (iStd == 0x0d)
+            for (uint32_t uECX = 1; s.uEAX != 0 || s.uEBX != 0 || s.uECX != 0 || s.uEDX != 0; uECX++)
+            {
+                ASMCpuId_Idx_ECX(iStd, uECX, &s.uEAX, &s.uEBX, &s.uECX, &s.uEDX);
+                RTTestIPrintf(RTTESTLVL_ALWAYS, "    [%02x]  %08x %08x %08x %08x\n", uECX, s.uEAX, s.uEBX, s.uECX, s.uEDX);
+                RTTESTI_CHECK_BREAK(uECX < 128);
+            }
     }
 
@@ -1520,4 +1545,5 @@
     tstASMCpuId();
 #endif
+#if 1
     tstASMAtomicXchgU8();
     tstASMAtomicXchgU16();
@@ -1550,4 +1576,5 @@
 
     tstASMBench();
+#endif
 
     /*
