From c1c3321a97dfce1312a6acbf4a6bbd4d0ce58de8 Mon Sep 17 00:00:00 2001 From: SaeHie Park Date: Fri, 9 Dec 2016 18:29:16 +0900 Subject: [PATCH] [x86/Linux] Fix getcpuid calling convention (dotnet/coreclr#8552) Fix getcpuid(), getextcpuid() with STDCALL Fix xmmYmmStateSupport() with STDCALL Commit migrated from https://github.com/dotnet/coreclr/commit/685de9132d453e08bc4ddb0c66f30d59fb4603b3 --- src/coreclr/src/vm/cgensys.h | 1 + src/coreclr/src/vm/codeman.cpp | 2 -- src/coreclr/src/vm/i386/cgenx86.cpp | 47 ++++++++++++++++++++++++++++++++++- src/coreclr/src/vm/i386/unixstubs.cpp | 43 -------------------------------- 4 files changed, 47 insertions(+), 46 deletions(-) diff --git a/src/coreclr/src/vm/cgensys.h b/src/coreclr/src/vm/cgensys.h index fb5c087..4dd1ee4 100644 --- a/src/coreclr/src/vm/cgensys.h +++ b/src/coreclr/src/vm/cgensys.h @@ -105,6 +105,7 @@ inline void GetSpecificCpuInfo(CORINFO_CPU * cpuInfo) #if (defined(_TARGET_X86_) || defined(_TARGET_AMD64_)) && !defined(CROSSGEN_COMPILE) extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]); +extern "C" DWORD __stdcall xmmYmmStateSupport(); #endif inline bool TargetHasAVXSupport() diff --git a/src/coreclr/src/vm/codeman.cpp b/src/coreclr/src/vm/codeman.cpp index 74fde49..a73cb53f 100644 --- a/src/coreclr/src/vm/codeman.cpp +++ b/src/coreclr/src/vm/codeman.cpp @@ -1216,8 +1216,6 @@ EEJitManager::EEJitManager() } #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) -extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]); -extern "C" DWORD __stdcall xmmYmmStateSupport(); bool DoesOSSupportAVX() { diff --git a/src/coreclr/src/vm/i386/cgenx86.cpp b/src/coreclr/src/vm/i386/cgenx86.cpp index 3774ac4..fd18344 100644 --- a/src/coreclr/src/vm/i386/cgenx86.cpp +++ b/src/coreclr/src/vm/i386/cgenx86.cpp @@ -1761,7 +1761,52 @@ extern "C" DWORD __stdcall xmmYmmStateSupport() #pragma warning(pop) -#endif +#else // !FEATURE_PAL + +extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]) +{ + DWORD eax; + __asm(" xor %%ecx, %%ecx\n" \ + " cpuid\n" \ + " mov %%eax, 0(%[result])\n" \ + " mov %%ebx, 4(%[result])\n" \ + " mov %%ecx, 8(%[result])\n" \ + " mov %%edx, 12(%[result])\n" \ + : "=a"(eax) /*output in eax*/\ + : "a"(arg), [result]"r"(result) /*inputs - arg in eax, result in any register*/\ + : "eax", "rbx", "ecx", "edx", "memory" /* registers that are clobbered, *result is clobbered */ + ); + return eax; +} + +extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]) +{ + DWORD eax; + __asm(" cpuid\n" \ + " mov %%eax, 0(%[result])\n" \ + " mov %%ebx, 4(%[result])\n" \ + " mov %%ecx, 8(%[result])\n" \ + " mov %%edx, 12(%[result])\n" \ + : "=a"(eax) /*output in eax*/\ + : "c"(arg1), "a"(arg2), [result]"r"(result) /*inputs - arg1 in ecx, arg2 in eax, result in any register*/\ + : "eax", "rbx", "ecx", "edx", "memory" /* registers that are clobbered, *result is clobbered */ + ); + return eax; +} + +extern "C" DWORD __stdcall xmmYmmStateSupport() +{ + DWORD eax; + __asm(" xgetbv\n" \ + : "=a"(eax) /*output in eax*/\ + : "c"(0) /*inputs - 0 in ecx*/\ + : "eax", "edx" /* registers that are clobbered*/ + ); + // check OS has enabled both XMM and YMM state support + return ((eax & 0x06) == 0x06) ? 1 : 0; +} + +#endif // !FEATURE_PAL // This function returns the number of logical processors on a given physical chip. If it cannot // determine the number of logical cpus, or the machine is not populated uniformly with the same diff --git a/src/coreclr/src/vm/i386/unixstubs.cpp b/src/coreclr/src/vm/i386/unixstubs.cpp index bf08a1b..6c04d20 100644 --- a/src/coreclr/src/vm/i386/unixstubs.cpp +++ b/src/coreclr/src/vm/i386/unixstubs.cpp @@ -41,49 +41,6 @@ extern "C" PORTABILITY_ASSERT("Implement for PAL"); } - DWORD getcpuid(DWORD arg, unsigned char result[16]) - { - DWORD eax; - __asm(" xor %%ecx, %%ecx\n" \ - " cpuid\n" \ - " mov %%eax, 0(%[result])\n" \ - " mov %%ebx, 4(%[result])\n" \ - " mov %%ecx, 8(%[result])\n" \ - " mov %%edx, 12(%[result])\n" \ - : "=a"(eax) /*output in eax*/\ - : "a"(arg), [result]"r"(result) /*inputs - arg in eax, result in any register*/\ - : "eax", "rbx", "ecx", "edx", "memory" /* registers that are clobbered, *result is clobbered */ - ); - return eax; - } - - DWORD getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]) - { - DWORD eax; - __asm(" cpuid\n" \ - " mov %%eax, 0(%[result])\n" \ - " mov %%ebx, 4(%[result])\n" \ - " mov %%ecx, 8(%[result])\n" \ - " mov %%edx, 12(%[result])\n" \ - : "=a"(eax) /*output in eax*/\ - : "c"(arg1), "a"(arg2), [result]"r"(result) /*inputs - arg1 in ecx, arg2 in eax, result in any register*/\ - : "eax", "rbx", "ecx", "edx", "memory" /* registers that are clobbered, *result is clobbered */ - ); - return eax; - } - - DWORD xmmYmmStateSupport() - { - DWORD eax; - __asm(" xgetbv\n" \ - : "=a"(eax) /*output in eax*/\ - : "c"(0) /*inputs - 0 in ecx*/\ - : "eax", "edx" /* registers that are clobbered*/ - ); - // check OS has enabled both XMM and YMM state support - return ((eax & 0x06) == 0x06) ? 1 : 0; - } - void STDCALL JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle) { } -- 2.7.4