Menu

#1271 Compilation failure with -fPIC on x86-32 (due to cpuid)

open-accepted
nobody
None
5
2014-09-09
2011-12-15
No

anttirt@anttirt-Ubu32:~/7z/C$ gcc -fPIC CpuArch.c
CpuArch.c: In function ‘MyCPUID’:
CpuArch.c:75:3: error: inconsistent operand constraints in an ‘asm’

When compiling with -fPIC (position-independent code) on x86-32 platforms on GCC, CpuArch.c fails to compile because it attempts to use the ebx register which is reserved for the global offset table (GOT, see http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html and the section on -fPIC for more information).

Attached is a patch to fix this problem. The provided code saves the ebx register to edi before calling cpuid, then swaps the result of cpuid and the stored value in edi, and returns the value from %edi to (*b).

Discussion

  • Antti Tuppurainen

     
  • Igor Pavlov

    Igor Pavlov - 2011-12-15

    Thanks!

    Please test slightly changed version of pathched code:

    __asm__ __volatile__ (
    #ifdef __PIC__
    "mov %%ebx, %%edi;"
    "cpuid;"
    "xchgl %%ebx, %%edi;"
    : "=a" (*a) ,
    "=D" (*b) ,
    #else
    "cpuid"
    : "=a" (*a) ,
    "=b" (*b) ,
    #endif
    "=c" (*c) ,
    "=d" (*d)
    : "0" (function)) ;

     
  • Igor Pavlov

    Igor Pavlov - 2011-12-15
    • status: open --> open-accepted
     
  • Antti Tuppurainen

    Hi, the changed version of the code works, but is suboptimal on amd64. On amd64, -fPIC does not use the ebx register, so the simpler version works there. The juggling with %edi only needs to be done on x86-32 with -fPIC, and not in any other case.

     
  • Igor Pavlov

    Igor Pavlov - 2011-12-16

    OK.
    I'll change that line back to:
    #if defined(MY_CPU_X86) && defined(__PIC__)

    BTW, do we need ASM code for GCC/AMD64?
    For example, all MSVC compilers for AMD64/WIN64 support __cpuid function.
    So I don't use ASM code for AMD64/WIN64.

     

Log in to post a comment.