[cfe-dev] ILP32, -arch i386 and x86_64 Apple systems
Jeffrey Walton via cfe-dev
cfe-dev at lists.llvm.org
Tue Dec 1 10:16:08 PST 2015
Hi Everyone,
(Re-asking on CFE-Dev). We took a bug report on some line assembly
code (https://github.com/weidai11/cryptopp/issues/72). I have two
questions at the end on ILP32, Clang and Apple.
The code that took the bug performs the following:
asm volatile
(
// save ebx in case -fPIC is being used
# if BOOL_X32 || BOOL_X64
"pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx"
# else
"push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx"
# endif
: "=a" (output[0]), "=D" (output[1]), "=c" (output[2]),
"=d" (output[3])
: "a" (input), "c" (0)
);
The BOOL_* defines are mutually exclusive. BOOL_X32 is set when
__ILP32__ is defined. BOOL_X86 is defined when __i386__ (and friends)
is defined. BOOL_X64 is defined when __x86_64__ (and friends) is
defined. We set the defines based on " System V Application Binary
Interface, AMD64 (With LP64 and ILP32 Programming Models)" [1].
The compiler error is:
$ make cpu.o
clang++ -DNDEBUG -g2 -O2 -arch i386 -fPIC -march=native -pipe -c cpu.cpp
cpu.cpp:104:4: error: register %rbx is only available in 64-bit mode
"pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx"
^
<inline asm>:1:8: note: instantiated into assembly here
pushq %rbx; cpuid; mov %ebx, %edi; popq %rbx
^~~~~
cpu.cpp:104:4: error: register %rbx is only available in 64-bit mode
"pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx"
^
<inline asm>:1:42: note: instantiated into assembly here
pushq %rbx; cpuid; mov %ebx, %edi; popq %rbx
^~~~
2 errors generated.
It appears Clang sets ILP32 related defines when using -arch i386 on x86_64:
$ clang++ -arch i386 -dM -E - < /dev/null | egrep -i "(86|64|ilp)"
#define _ILP32 1
#define __ILP32__ 1
...
#define __i386 1
#define __i386__ 1
#define i386 1
As far as I know, when using ILP32 on x86_64, we must interact with
the stack using 64-bit values and registers.
My first question is, is _ILP32_ and _i386_ supposed to be defined
together? According to the docs I found, its not an expected/valid
configuration. _ILP32_ and _x86_64_ is an expected/valid
configuration.
My second question is, how should I work around this? Should I special
case Clang on Apple and attempt to push a 32-bit value? Or should I do
something else?
Thanks in advance.
*****
A related bug report was opened at "LLVM Bug 25688 - Clang defines
__ILP32__ when using -arch i386 on an x86_64 Intel",
https://llvm.org/bugs/show_bug.cgi?id=25688.
*****
Here are the docs I found, but its not clear to me what document is
controlling in this case.
The "OS X ABI Function Call Guide" [0] does not discuss it, and often
defers to the System V guides.
The "System V Application Binary Interface, AMD64 (With LP64 and ILP32
Programming Models)" [1] states we should see either (1) __ILP32__
alone; or (2) both __ILP32__ and __x86_64__ (some hand waiving).
The "SYSTEM V APPLICATION BINARY INTERFACE for Intel 386" [2] does not
discuss it, and does not mention __ILP32__.
[0] http://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/LowLevelABI/Mac_OS_X_ABI_Function_Calls.pdf
[1] http://sites.google.com/site/x32abi/documents/abi.pdf
[2] http://www.sco.com/developers/devspecs/abi386-4.pdf
More information about the cfe-dev
mailing list