From 685de9132d453e08bc4ddb0c66f30d59fb4603b3 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 (#8552) Fix getcpuid(), getextcpuid() with STDCALL Fix xmmYmmStateSupport() with STDCALL --- src/vm/cgensys.h | 1 + src/vm/codeman.cpp | 2 -- src/vm/i386/cgenx86.cpp | 47 ++++++++++++++++++++++++++++++++++++++- src/vm/i386/unixstubs.cpp | 43 ----------------------------------- 4 files changed, 47 insertions(+), 46 deletions(-) diff --git a/src/vm/cgensys.h b/src/vm/cgensys.h index fb5c087c5c92..4dd1ee4b4b56 100644 --- a/src/vm/cgensys.h +++ b/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/vm/codeman.cpp b/src/vm/codeman.cpp index 74fde498d6d7..a73cb53fd1ce 100644 --- a/src/vm/codeman.cpp +++ b/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/vm/i386/cgenx86.cpp b/src/vm/i386/cgenx86.cpp index 3774ac4ee7f5..fd1834498a3f 100644 --- a/src/vm/i386/cgenx86.cpp +++ b/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/vm/i386/unixstubs.cpp b/src/vm/i386/unixstubs.cpp index bf08a1b8fa8e..6c04d2048cfe 100644 --- a/src/vm/i386/unixstubs.cpp +++ b/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) { }