diff options
author | Nick Terrell <terrelln@fb.com> | 2024-03-12 12:16:55 -0700 |
---|---|---|
committer | Nick Terrell <nickrterrell@gmail.com> | 2024-03-13 09:45:40 -0400 |
commit | 94c102038b81ed89e3b013cb1977496612609f85 (patch) | |
tree | 7c4528a62d620b880a06e22c6b30a582006cc9a6 | |
parent | 4bd911ae41a62cfbaf624bfeb5a3952d37019575 (diff) | |
download | zstd-94c102038b81ed89e3b013cb1977496612609f85.tar.gz |
[cpu] Backport fix for rbx clobbering on Windows with Clang
Backport folly fix for rbx clobbering: https://github.com/facebook/folly/commit/f22f88b8b9d70160388f0f149bc9abaeb82c250b
This supercedes PR #3646.
-rw-r--r-- | lib/common/cpu.h | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/lib/common/cpu.h b/lib/common/cpu.h index 8bc34a36..0e684d9a 100644 --- a/lib/common/cpu.h +++ b/lib/common/cpu.h @@ -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); { @@ -50,6 +51,41 @@ MEM_STATIC ZSTD_cpuid_t ZSTD_cpuid(void) { f7c = (U32)reg[2]; } } +#else + /* 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 |