Proper use of x86/x86_64 CPUID instruction with extended assembler
Jeffrey Walton
noloader@gmail.com
Wed Aug 19 06:28:00 GMT 2015
Forgive my ignorance....
The following retrieves information from a x86/x86_64 processor. Its
used in an inline assembly block under Linux. The function is also
inlined in a header. The other detail is, its System V ABI, so the
caller owns RBP, RBX and R12-R15 under x86_64 (I'm not sure about the
i386 variant).
struct CPUIDinfo
{
word32 EAX;
word32 EBX;
word32 ECX;
word32 EDX;
};
....
static inline void CpuId(unsigned int func, unsigned int subfunc,
CPUIDinfo& info)
{
__asm__ __volatile__ (
"cpuid"
: "=a"(info.EAX), "=b"(info.EBX), "=c"(info.ECX), "=d"(info.EDX)
: "a"(func), "c"(subfunc)
: "b"
);
}
The CPUID instruction always uses EAX/EBX/ECX/EDX, even on 64-bit
platforms. On 64-bit platforms, the CPUID instruction sets the high
32-bit words of RAX/RBX/RCX.RDX equal to 0.
My question is, will the extended assembly preserve the registers? Is
it sufficient to list "b" as a clobber? Or do I need to do something
special?
If I need to do something special, then what needs to be done?
(I also looked at
https://gcc.gnu.org/ml/gcc-patches/2007-09/msg00324.html, which is a
GCC patch for cpuid.h. But its not clear to me if the above is correct
because the operands are 32-bit in size. Naively, if I use "a" and "b"
with a 32-bit operand, then I would expect code for EAX and EBX; and
not RAX and RBX).
Thanks in advance.
More information about the Gcc-help
mailing list