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

[x86/Linux] Fix getcpuid calling convention #8552

Merged
merged 1 commit into from
Dec 9, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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