Skip to content

Commit

Permalink
[cpu] Backport fix for rbx clobbering on Windows with Clang
Browse files Browse the repository at this point in the history
Backport folly fix for rbx clobbering: facebook/folly@f22f88b

This supercedes PR #3646.
  • Loading branch information
terrelln committed Mar 12, 2024
1 parent 92fbd42 commit b6c4f39
Showing 1 changed file with 37 additions and 0 deletions.
37 changes: 37 additions & 0 deletions lib/common/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
U32 f7b = 0;
U32 f7c = 0;
#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86))
#if !defined(__clang__)
int reg[4];
__cpuid((int*)reg, 0);
{
Expand All @@ -50,6 +51,42 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) {
f7c = (U32)reg[2];
}
}
#else
#error NOCOMMIT: Test to see if we have CI coverage for Windows + clang
/* Clang compiler has a bug (fixed in https://reviews.llvm.org/D101338) in
* which the `__cpuid` intrinsic does not save and restore `rbx` as it needs
* to due to being a reserved register. So in that case, do the `cpuid`
* ourselves. Clang supports inline assembly anyway.
*/
U32 n;
__asm__(
"pushq %%rbx\n\t"
"cpuid\n\t"
"popq %%rbx\n\t"
: "=a"(n)
: "a"(0)
: "rcx", "rdx");
if (n >= 1) {
U32 f1a;
__asm__(
"pushq %%rbx\n\t"
"cpuid\n\t"
"popq %%rbx\n\t"
: "=a"(f1a), "=c"(f1c), "=d"(f1d)
: "a"(1)
:);
}
if (n >= 7) {
__asm__(
"pushq %%rbx\n\t"
"cpuid\n\t"
"movq %%rbx, %%rax\n\t"
"popq %%rbx"
: "=a"(f7b), "=c"(f7c)
: "a"(7), "c"(0)
: "rdx");
}
#endif
#elif defined(__i386__) && defined(__PIC__) && !defined(__clang__) && defined(__GNUC__)
/* The following block like the normal cpuid branch below, but gcc
* reserves ebx for use of its pic register so we must specially
Expand Down

0 comments on commit b6c4f39

Please sign in to comment.