Commit 95209f9d authored by Philip Pronin's avatar Philip Pronin Committed by Facebook Github Bot

fix silent eax clobbering in CpuId ctor

Summary:
`cpuid` uses all of `eax`, `ebx`, `ecx`, `edx` for output, but we
aren't providing such information to GCC in a couple of cases, which might
result in incorrect code being produced;

GCC (unlike clang) doesn't allow the same register to appear both in input and
clobber list, so put `eax` into output list where required.

Reviewed By: ot, lbrandy

Differential Revision: D4961841

fbshipit-source-id: 07ca1977373496bfd794d3b0c8a4ba21333820e4
parent af5ed37b
......@@ -33,7 +33,7 @@ namespace folly {
class CpuId {
public:
// Always inline in order for this to be usable from a __ifunc__.
// In shared library mde, a __ifunc__ runs at relocation time, while the
// In shared library mode, a __ifunc__ runs at relocation time, while the
// PLT hasn't been fully populated yet; thus, ifuncs cannot use symbols
// with potentially external linkage. (This issue is less likely in opt
// mode since inlining happens more likely, and it doesn't happen for
......@@ -56,7 +56,7 @@ class CpuId {
#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 it's pic register so we must specially
// reserves ebx for use of its pic register so we must specially
// handle the save and restore to avoid clobbering the register
uint32_t n;
__asm__(
......@@ -65,13 +65,14 @@ class CpuId {
"popl %%ebx\n\t"
: "=a"(n)
: "a"(0)
: "edx", "ecx");
: "ecx", "edx");
if (n >= 1) {
uint32_t f1a;
__asm__(
"pushl %%ebx\n\t"
"cpuid\n\t"
"popl %%ebx\n\t"
: "=c"(f1c_), "=d"(f1d_)
: "=a"(f1a), "=c"(f1c_), "=d"(f1d_)
: "a"(1)
:);
}
......@@ -87,12 +88,17 @@ class CpuId {
}
#elif FOLLY_X64 || defined(__i386__)
uint32_t n;
__asm__("cpuid" : "=a"(n) : "a"(0) : "ebx", "edx", "ecx");
__asm__("cpuid" : "=a"(n) : "a"(0) : "ebx", "ecx", "edx");
if (n >= 1) {
__asm__("cpuid" : "=c"(f1c_), "=d"(f1d_) : "a"(1) : "ebx");
uint32_t f1a;
__asm__("cpuid" : "=a"(f1a), "=c"(f1c_), "=d"(f1d_) : "a"(1) : "ebx");
}
if (n >= 7) {
__asm__("cpuid" : "=b"(f7b_), "=c"(f7c_) : "a"(7), "c"(0) : "edx");
uint32_t f7a;
__asm__("cpuid"
: "=a"(f7a), "=b"(f7b_), "=c"(f7c_)
: "a"(7), "c"(0)
: "edx");
}
#endif
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment