summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2014-07-28 13:09:28 +0000
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2014-07-28 13:09:28 +0000
commit90a5de88a87b67668e4260ad0f69267399001714 (patch)
tree30c047eb5b341fdd1efdbbc4e19d3bb4bfe94004 /llvm/lib
parent8184d66f4b98d779abb5dd5564fb14157b5949d6 (diff)
downloadbcm5719-llvm-90a5de88a87b67668e4260ad0f69267399001714.tar.gz
bcm5719-llvm-90a5de88a87b67668e4260ad0f69267399001714.zip
[PowerPC] Support ELFv1/ELFv2 ABI selection via features
While LLVM now supports both ELFv1 and ELFv2 ABIs, their use is currently hard-coded via the target triple: powerpc64-linux is always ELFv1, while powerpc64le-linux is always ELFv2. These are of course the most common scenarios, but in principle it is possible to support the ELFv2 ABI on big-endian or the ELFv1 ABI on little-endian systems (and GCC does support that), and there are some special use cases for that (e.g. certain Linux kernel versions could only be built using ELFv1 on LE). This patch implements the LLVM side of supporting this. As precedent on other platforms suggests, ABI options are passed to the back-end as features. Thus, this patch implements two features "elfv1" and "elfv2" that select the desired ABI if present. (If not, the LLVM uses the same default rules as now.) llvm-svn: 214072
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/PowerPC/PPC.td10
-rw-r--r--llvm/lib/Target/PowerPC/PPCSubtarget.cpp12
-rw-r--r--llvm/lib/Target/PowerPC/PPCSubtarget.h10
3 files changed, 28 insertions, 4 deletions
diff --git a/llvm/lib/Target/PowerPC/PPC.td b/llvm/lib/Target/PowerPC/PPC.td
index a9842b287cb..155f3d5b5c1 100644
--- a/llvm/lib/Target/PowerPC/PPC.td
+++ b/llvm/lib/Target/PowerPC/PPC.td
@@ -108,6 +108,16 @@ def DeprecatedDST : SubtargetFeature<"", "DeprecatedDST", "true",
// VSX p7 vector-scalar instruction set
//===----------------------------------------------------------------------===//
+// ABI Selection //
+//===----------------------------------------------------------------------===//
+
+def FeatureELFv1 : SubtargetFeature<"elfv1", "TargetABI", "PPC_ABI_ELFv1",
+ "Use the ELFv1 ABI">;
+
+def FeatureELFv2 : SubtargetFeature<"elfv2", "TargetABI", "PPC_ABI_ELFv2",
+ "Use the ELFv2 ABI">;
+
+//===----------------------------------------------------------------------===//
// Classes used for relation maps.
//===----------------------------------------------------------------------===//
// RecFormRel - Filter class used to relate non-record-form instructions with
diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
index b51512d335f..b39fe10bc13 100644
--- a/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
+++ b/llvm/lib/Target/PowerPC/PPCSubtarget.cpp
@@ -78,7 +78,7 @@ PPCSubtarget::PPCSubtarget(const std::string &TT, const std::string &CPU,
const std::string &FS, PPCTargetMachine &TM,
bool is64Bit, CodeGenOpt::Level OptLevel)
: PPCGenSubtargetInfo(TT, CPU, FS), IsPPC64(is64Bit), TargetTriple(TT),
- OptLevel(OptLevel),
+ OptLevel(OptLevel), TargetABI(PPC_ABI_UNKNOWN),
FrameLowering(initializeSubtargetDependencies(CPU, FS)),
DL(getDataLayoutString(*this)), InstrInfo(*this), JITInfo(*this),
TLInfo(TM), TSInfo(&DL) {}
@@ -203,6 +203,16 @@ void PPCSubtarget::resetSubtargetFeatures(StringRef CPU, StringRef FS) {
// issues in those instructions can be addressed.
if (IsLittleEndian)
HasVSX = false;
+
+ // Determine default ABI.
+ if (TargetABI == PPC_ABI_UNKNOWN) {
+ if (!isDarwin() && IsPPC64) {
+ if (IsLittleEndian)
+ TargetABI = PPC_ABI_ELFv2;
+ else
+ TargetABI = PPC_ABI_ELFv1;
+ }
+ }
}
/// hasLazyResolverStub - Return true if accesses to the specified global have
diff --git a/llvm/lib/Target/PowerPC/PPCSubtarget.h b/llvm/lib/Target/PowerPC/PPCSubtarget.h
index a3cedafb5ef..8c4f583bdb8 100644
--- a/llvm/lib/Target/PowerPC/PPCSubtarget.h
+++ b/llvm/lib/Target/PowerPC/PPCSubtarget.h
@@ -109,6 +109,12 @@ protected:
/// OptLevel - What default optimization level we're emitting code for.
CodeGenOpt::Level OptLevel;
+ enum {
+ PPC_ABI_UNKNOWN,
+ PPC_ABI_ELFv1,
+ PPC_ABI_ELFv2
+ } TargetABI;
+
PPCFrameLowering FrameLowering;
const DataLayout DL;
PPCInstrInfo InstrInfo;
@@ -227,9 +233,7 @@ public:
bool isDarwinABI() const { return isDarwin(); }
bool isSVR4ABI() const { return !isDarwin(); }
- /// FIXME: Should use a command-line option.
- bool isELFv2ABI() const { return isPPC64() && isSVR4ABI() &&
- isLittleEndian(); }
+ bool isELFv2ABI() const { return TargetABI == PPC_ABI_ELFv2; }
bool enableEarlyIfConversion() const override { return hasISEL(); }
OpenPOWER on IntegriCloud