Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
[x86/Linux] Fix getcpuid calling convention (#8552)
Browse files Browse the repository at this point in the history
Fix getcpuid(), getextcpuid() with STDCALL
Fix xmmYmmStateSupport() with STDCALL
  • Loading branch information
seanshpark authored and janvorli committed Dec 9, 2016
1 parent 76c62b7 commit 685de91
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 46 deletions.
1 change: 1 addition & 0 deletions src/vm/cgensys.h
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 0 additions & 2 deletions src/vm/codeman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
{
Expand Down
47 changes: 46 additions & 1 deletion src/vm/i386/cgenx86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
43 changes: 0 additions & 43 deletions src/vm/i386/unixstubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
}
Expand Down

0 comments on commit 685de91

Please sign in to comment.