[LLVMdev] [NEW PATCH] X32 ABI support for Clang/compiler-rt (Clang patch)
Steven Newbury
steve at snewbury.org.uk
Thu Aug 22 07:22:54 PDT 2013
This patch is still not creating elf32_x86_64 objects. No idea
why. :( It does however, fix elf_x86_64 (-m64) code generation on x32
hosts which is nice. :)
--- ./tools/clang/include/clang/Driver/Options.td.orig 2013-05-16
21:51:51.286129820 +0000
+++ ./tools/clang/include/clang/Driver/Options.td 2013-05-16
21:53:24.875004239 +0000
@@ -841,6 +841,7 @@
HelpText<"Enable hexagon-qdsp6 backward compatibility">;
def m3dnowa : Flag<["-"], "m3dnowa">, Group<m_x86_Features_Group>;
def m3dnow : Flag<["-"], "m3dnow">, Group<m_x86_Features_Group>;
+def mx32 : Flag<["-"], "mx32">, Group<m_Group>, Flags<[DriverOption]>;
def m64 : Flag<["-"], "m64">, Group<m_Group>, Flags<[DriverOption]>;
def mabi_EQ : Joined<["-"], "mabi=">, Group<m_Group>;
def march_EQ : Joined<["-"], "march=">, Group<m_Group>;
--- ./tools/clang/lib/Basic/Targets.cpp.orig 2013-08-18
12:00:04.501402572 +0000
+++ ./tools/clang/lib/Basic/Targets.cpp 2013-08-18 12:08:11.086175660
+0000
@@ -2384,6 +2384,14 @@
Builder.defineMacro("__amd64");
Builder.defineMacro("__x86_64");
Builder.defineMacro("__x86_64__");
+ if (PointerWidth == 64 && getLongWidth() == 64) {
+ Builder.defineMacro("_LP64");
+ Builder.defineMacro("__LP64__");
+ } else if (PointerWidth == 32 && getLongWidth() == 32 &&
+ getIntWidth() == 32) {
+ Builder.defineMacro("_ILP32");
+ Builder.defineMacro("__ILP32__");
+ }
} else {
DefineStd(Builder, "i386", Opts);
}
@@ -3013,20 +3021,31 @@
class X86_64TargetInfo : public X86TargetInfo {
public:
X86_64TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple)
{
- LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+ const bool IsX32 = (getTriple().getEnvironment() ==
llvm::Triple::GNUX32);
+ LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 :
64;
LongDoubleWidth = 128;
LongDoubleAlign = 128;
LargeArrayMinWidth = 128;
LargeArrayAlign = 128;
SuitableAlign = 128;
- IntMaxType = SignedLong;
- UIntMaxType = UnsignedLong;
- Int64Type = SignedLong;
+ if (IsX32) {
+ SizeType = UnsignedInt;
+ PtrDiffType = SignedInt;
+ IntPtrType = SignedInt;
+ } else {
+ IntMaxType = SignedLong;
+ UIntMaxType = UnsignedLong;
+ Int64Type = SignedLong;
+ }
RegParmMax = 6;
- DescriptionString =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
-
"a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128";
+ DescriptionString = IsX32 ?
+ "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
+ "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" :
+ "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
+ "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128";
// Use fpret only for long double.
RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
--- ./tools/clang/lib/Driver/ToolChains.h.orig 2013-08-18
13:38:36.158022094 +0000
+++ ./tools/clang/lib/Driver/ToolChains.h 2013-08-18 13:39:12.822210498
+0000
@@ -121,7 +121,7 @@
SmallVectorImpl<StringRef> &BiarchLibDirs,
SmallVectorImpl<StringRef>
&BiarchTripleAliases);
- void ScanLibDirForGCCTriple(llvm::Triple::ArchType TargetArch,
+ void ScanLibDirForGCCTriple(llvm::Triple TargetTriple,
const llvm::opt::ArgList &Args,
const std::string &LibDir,
StringRef CandidateTriple,
--- ./tools/clang/lib/Driver/Tools.cpp.orig 2013-08-18
13:35:35.783789840 +0000
+++ ./tools/clang/lib/Driver/Tools.cpp 2013-08-18 13:42:18.806549941
+0000
@@ -6045,6 +6045,8 @@
ToolChain.getArch() == llvm::Triple::ppc64le ||
ToolChain.getArch() == llvm::Triple::systemz)
return "/lib64/ld64.so.1";
+ else if (ToolChain.getTriple().getEnvironment() ==
llvm::Triple::GNUX32)
+ return "/libx32/ld-linux-x32.so.2";
else
return "/lib64/ld-linux-x86-64.so.2";
}
@@ -6125,8 +6127,12 @@
}
else if (ToolChain.getArch() == llvm::Triple::systemz)
CmdArgs.push_back("elf64_s390");
- else
- CmdArgs.push_back("elf_x86_64");
+ else if (ToolChain.getArch() == llvm::Triple::x86_64)
+ CmdArgs.push_back(ToolChain.getTriple().getEnvironment() ==
+ llvm::Triple::GNUX32
+ ? "elf32_x86_64" : "elf_x86_64");
+ else
+ llvm_unreachable("unknown arch");
if (Args.hasArg(options::OPT_static)) {
if (ToolChain.getArch() == llvm::Triple::arm
--- ./tools/clang/lib/Driver/ToolChains.cpp.orig 2013-08-18
14:18:42.527568969 +0000
+++ ./tools/clang/lib/Driver/ToolChains.cpp 2013-08-18
14:20:41.647025183 +0000
@@ -998,7 +998,6 @@
llvm::Triple BiarchVariantTriple =
TargetTriple.isArch32Bit() ? TargetTriple.get64BitArchVariant()
: TargetTriple.get32BitArchVariant();
- llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
// The library directories which may contain GCC installations.
SmallVector<StringRef, 4> CandidateLibDirs, CandidateBiarchLibDirs;
// The compatible GCC triples for this particular architecture.
@@ -1035,7 +1034,7 @@
if (!llvm::sys::fs::exists(LibDir))
continue;
for (unsigned k = 0, ke = CandidateTripleAliases.size(); k < ke;
++k)
- ScanLibDirForGCCTriple(TargetArch, Args, LibDir,
+ ScanLibDirForGCCTriple(TargetTriple, Args, LibDir,
CandidateTripleAliases[k]);
}
for (unsigned j = 0, je = CandidateBiarchLibDirs.size(); j < je;
++j) {
@@ -1044,7 +1043,7 @@
continue;
for (unsigned k = 0, ke = CandidateBiarchTripleAliases.size(); k
< ke;
++k)
- ScanLibDirForGCCTriple(TargetArch, Args, LibDir,
+ ScanLibDirForGCCTriple(TargetTriple, Args, LibDir,
CandidateBiarchTripleAliases[k],
/*NeedsBiarchSuffix=*/ true);
}
@@ -1321,6 +1351,7 @@
}
static bool findTargetBiarchSuffix(std::string &Suffix, StringRef Path,
+ llvm::Triple TargetTriple,
llvm::Triple::ArchType TargetArch,
const ArgList &Args) {
// FIXME: This routine was only intended to model bi-arch toolchains
which
@@ -1351,6 +1382,8 @@
TargetArch == llvm::Triple::ppc64 ||
TargetArch == llvm::Triple::systemz)
Suffix = "/64";
+ else if (TargetTriple.getEnvironment() == llvm::Triple::GNUX32)
+ Suffix = "/x32";
else
Suffix = "/32";
@@ -1358,9 +1391,10 @@
}
void Generic_GCC::GCCInstallationDetector::ScanLibDirForGCCTriple(
- llvm::Triple::ArchType TargetArch, const ArgList &Args,
+ llvm::Triple TargetTriple, const ArgList &Args,
const std::string &LibDir, StringRef CandidateTriple,
bool NeedsBiarchSuffix) {
+ llvm::Triple::ArchType TargetArch = TargetTriple.getArch();
// There are various different suffixes involving the triple we
// check for. We also record what is necessary to walk from each back
// up to the lib directory.
@@ -1413,7 +1447,7 @@
// crtbegin.o without the subdirectory.
std::string BiarchSuffix;
- if (findTargetBiarchSuffix(BiarchSuffix, LI->path(), TargetArch,
Args)) {
+ if (findTargetBiarchSuffix(BiarchSuffix, LI->path(),
TargetTriple, TargetArch, Args)) {
GCCBiarchSuffix = BiarchSuffix;
} else {
if (NeedsBiarchSuffix ||
@@ -2186,8 +2220,9 @@
static StringRef getMultilibDir(const llvm::Triple &Triple,
const ArgList &Args) {
+ const bool IsX32 = Triple.getEnvironment() == llvm::Triple::GNUX32;
if (!isMipsArch(Triple.getArch()))
- return Triple.isArch32Bit() ? "lib32" : "lib64";
+ return Triple.isArch32Bit() ? "lib32" : IsX32 ? "libx32" : "lib64";
// lib32 directory has a special meaning on MIPS targets.
// It contains N32 ABI binaries. Use this folder if produce
--- ./lib/Target/X86/X86JITInfo.cpp.orig 2013-08-19 11:38:44.998820677
+0000
+++ ./lib/Target/X86/X86JITInfo.cpp 2013-08-19 11:39:14.769549714 +0000
@@ -396,6 +396,7 @@
// PC-relative branch instead of loading the actual address. (This
is
// considerably shorter than the 64-bit immediate load already
there.)
// We assume here intptr_t is 64 bits.
+#if defined (__LP64__)
intptr_t diff = NewVal-RetAddr+7;
if (diff >= -2147483648LL && diff <= 2147483647LL) {
*(unsigned char*)(RetAddr-0xc) = 0xE9;
@@ -405,6 +406,11 @@
((unsigned char*)RetAddr)[0] = (2 | (4 << 3) | (3 << 6));
}
sys::ValgrindDiscardTranslations((void*)(RetAddr-0xc), 0xd);
+#else // If intptr_t is only 32 bits, always use a PC-relative branch.
+ *(unsigned char*)(RetAddr-0xc) = 0xE9;
+ *(intptr_t *)(RetAddr-0xb) = NewVal-RetAddr+7;
+ sys::ValgrindDiscardTranslations((void*)(RetAddr-0xc), 0xd);
+#endif
#else
((unsigned char*)RetAddr)[-1] = 0xE9;
sys::ValgrindDiscardTranslations((void*)(RetAddr-1), 5);
@@ -442,7 +448,7 @@
void *X86JITInfo::emitGlobalValueIndirectSym(const GlobalValue* GV,
void *ptr,
JITCodeEmitter &JCE) {
-#if defined (X86_64_JIT)
+#if defined (X86_64_JIT) && defined (__LP64__)
const unsigned Alignment = 8;
uint8_t Buffer[8];
uint8_t *Cur = Buffer;
@@ -481,7 +487,7 @@
JCE.emitAlignment(4);
void *Result = (void*)JCE.getCurrentPCValue();
if (NotCC) {
-#if defined (X86_64_JIT)
+#if defined (X86_64_JIT) && defined (__LP64__)
JCE.emitByte(0x49); // REX prefix
JCE.emitByte(0xB8+2); // movabsq r10
JCE.emitWordLE((unsigned)(intptr_t)Target);
@@ -496,7 +502,7 @@
return Result;
}
-#if defined (X86_64_JIT)
+#if defined (X86_64_JIT) && defined (__LP64__)
JCE.emitByte(0x49); // REX prefix
JCE.emitByte(0xB8+2); // movabsq r10
JCE.emitWordLE((unsigned)(intptr_t)Target);
--- tools/clang/lib/Driver/Driver.cpp.orig 2013-08-22 14:07:13.397091755
+0000
+++ tools/clang/lib/Driver/Driver.cpp 2013-08-22 14:05:55.275249307
+0000
@@ -1897,6 +1897,8 @@
// Handle pseudo-target flags '-m32' and '-m64'.
// FIXME: Should this information be in llvm::Triple?
if (Arg *A = Args.getLastArg(options::OPT_m32, options::OPT_m64)) {
+ if (Target.getEnvironment() == llvm::Triple::GNUX32)
+ Target.setEnvironment(llvm::Triple::GNU);
if (A->getOption().matches(options::OPT_m32)) {
if (Target.getArch() == llvm::Triple::x86_64)
Target.setArch(llvm::Triple::x86);
@@ -1908,6 +1910,9 @@
if (Target.getArch() == llvm::Triple::ppc)
Target.setArch(llvm::Triple::ppc64);
}
+ } else if (Args.getLastArg(options::OPT_mx32)) {
+ if (Target.getArch() == llvm::Triple::x86_64)
+ Target.setEnvironment(llvm::Triple::GNUX32);
}
return Target;
More information about the llvm-dev
mailing list