Make the ARM ABI selectable via SubtargetFeature.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 2 Jan 2014 13:40:08 +0000 (13:40 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 2 Jan 2014 13:40:08 +0000 (13:40 +0000)
This patch makes it possible to select the ABI with -mattr. It will be used to
forward clang's -target-abi option to llvm's CodeGen.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@198304 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARM.td
lib/Target/ARM/ARMSubtarget.cpp
lib/Target/ARM/ARMSubtarget.h
test/CodeGen/ARM/arm-abi-attr.ll [new file with mode: 0644]

index 23b6626056e0f9fbdcaf07fd773568032d0027c7..27bbcc22b640d4a0f12c65922e4209b3ed368184 100644 (file)
@@ -255,6 +255,14 @@ def ProcKrait   : SubtargetFeature<"krait", "ARMProcFamily", "Krait",
                                     FeatureHWDiv,
                                     FeatureHWDivARM]>;
 
+
+def FeatureAPCS  : SubtargetFeature<"apcs", "TargetABI", "ARM_ABI_APCS",
+                                   "Use the APCS ABI">;
+
+def FeatureAAPCS : SubtargetFeature<"aapcs", "TargetABI", "ARM_ABI_AAPCS",
+                                   "Use the AAPCS ABI">;
+
+
 class ProcNoItin<string Name, list<SubtargetFeature> Features>
  : Processor<Name, NoItineraries, Features>;
 
index 3c5bed52b7b16c484c5dda84e615a94c09ee0d4d..81fdbfd226c3dbf352568b5ec2c8fcab6e311d6a 100644 (file)
@@ -83,7 +83,7 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,
   , CPUString(CPU)
   , TargetTriple(TT)
   , Options(Options)
-  , TargetABI(ARM_ABI_APCS) {
+  , TargetABI(ARM_ABI_UNKNOWN) {
   initializeEnvironment();
   resetSubtargetFeatures(CPU, FS);
 }
@@ -189,18 +189,22 @@ void ARMSubtarget::resetSubtargetFeatures(StringRef CPU, StringRef FS) {
   // Initialize scheduling itinerary for the specified CPU.
   InstrItins = getInstrItineraryForCPU(CPUString);
 
-  switch (TargetTriple.getEnvironment()) {
-  case Triple::Android:
-  case Triple::EABI:
-  case Triple::EABIHF:
-  case Triple::GNUEABI:
-  case Triple::GNUEABIHF:
-    TargetABI = ARM_ABI_AAPCS;
-    break;
-  default:
-    if (isTargetIOS() && isMClass())
+  if (TargetABI == ARM_ABI_UNKNOWN) {
+    switch (TargetTriple.getEnvironment()) {
+    case Triple::Android:
+    case Triple::EABI:
+    case Triple::EABIHF:
+    case Triple::GNUEABI:
+    case Triple::GNUEABIHF:
       TargetABI = ARM_ABI_AAPCS;
-    break;
+      break;
+    default:
+      if (isTargetIOS() && isMClass())
+        TargetABI = ARM_ABI_AAPCS;
+      else
+        TargetABI = ARM_ABI_APCS;
+      break;
+    }
   }
 
   if (isAAPCS_ABI())
index 4893973e1c2ab8424629995d6910154d7d53382d..8c471dcfd1ace65cb4aee5dec73f04ab7d6d83ca 100644 (file)
@@ -217,6 +217,7 @@ protected:
 
  public:
   enum {
+    ARM_ABI_UNKNOWN,
     ARM_ABI_APCS,
     ARM_ABI_AAPCS // ARM EABI
   } TargetABI;
@@ -326,8 +327,14 @@ public:
            TargetTriple.getEnvironment() == Triple::EABIHF;
   }
 
-  bool isAPCS_ABI() const { return TargetABI == ARM_ABI_APCS; }
-  bool isAAPCS_ABI() const { return TargetABI == ARM_ABI_AAPCS; }
+  bool isAPCS_ABI() const {
+    assert(TargetABI != ARM_ABI_UNKNOWN);
+    return TargetABI == ARM_ABI_APCS;
+  }
+  bool isAAPCS_ABI() const {
+    assert(TargetABI != ARM_ABI_UNKNOWN);
+    return TargetABI == ARM_ABI_AAPCS;
+  }
 
   bool isThumb() const { return InThumbMode; }
   bool isThumb1Only() const { return InThumbMode && !HasThumb2; }
diff --git a/test/CodeGen/ARM/arm-abi-attr.ll b/test/CodeGen/ARM/arm-abi-attr.ll
new file mode 100644 (file)
index 0000000..f3923ae
--- /dev/null
@@ -0,0 +1,28 @@
+; RUN: llc -mtriple=arm-linux < %s | FileCheck %s --check-prefix=APCS
+; RUN: llc -mtriple=arm-linux -mattr=apcs < %s | \
+; RUN: FileCheck %s --check-prefix=APCS
+; RUN: llc -mtriple=arm-linux-gnueabi -mattr=apcs < %s | \
+; RUN: FileCheck %s --check-prefix=APCS
+
+; RUN: llc -mtriple=arm-linux-gnueabi < %s | FileCheck %s --check-prefix=AAPCS
+; RUN: llc -mtriple=arm-linux-gnueabi -mattr=aapcs < %s | \
+; RUN: FileCheck %s --check-prefix=AAPCS
+; RUN: llc -mtriple=arm-linux-gnu -mattr=aapcs < %s | \
+; RUN: FileCheck %s --check-prefix=AAPCS
+
+; The stack is 8 byte aligned on AAPCS and 4 on APCS, so we should get a BIC
+; only on APCS.
+
+define void @g() {
+; APCS: sub    sp, sp, #8
+; APCS: bic    sp, sp, #7
+
+; AAPCS: sub   sp, sp, #8
+; AAPCS-NOT: bic
+
+  %c = alloca i8, align 8
+  call void @f(i8* %c)
+  ret void
+}
+
+declare void @f(i8*)