This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Proper use of x86/x86_64 CPUID instruction with extended assembler


On 08/19/2015 09:28 AM, Jeffrey Walton wrote:
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"

This "b" clobber is unneeded, since "b" is an output register.

         );
     }

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?

It will not preserve the registers, except those that are required to by the ABI ("b"). The clobber tells gcc which registers are destroyed by the instruction, not which registers to preserve; it already knows the latter.


If I need to do something special, then what needs to be done?

Nothing much; just drop that "b" clobber.


(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).

It is correct.

Thanks in advance.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]