OSDN Git Service

ARM: update subtarget information for Windows on ARM
authorSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 2 Apr 2014 20:32:05 +0000 (20:32 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Wed, 2 Apr 2014 20:32:05 +0000 (20:32 +0000)
Update the subtarget information for Windows on ARM.  This enables using the MC
layer to target Windows on ARM.

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

13 files changed:
lib/IR/DataLayout.cpp
lib/Target/ARM/ARMISelLowering.cpp
lib/Target/ARM/ARMSubtarget.cpp
lib/Target/ARM/ARMSubtarget.h
lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.cpp
lib/Target/ARM/MCTargetDesc/ARMMCAsmInfo.h
lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
test/CodeGen/ARM/Windows/aapcs.ll [new file with mode: 0644]
test/CodeGen/ARM/Windows/hard-float.ll [new file with mode: 0644]
test/CodeGen/ARM/Windows/mangling.ll [new file with mode: 0644]
test/CodeGen/ARM/Windows/no-aeabi.ll [new file with mode: 0644]
test/CodeGen/ARM/Windows/no-arm-mode.ll [new file with mode: 0644]
test/CodeGen/ARM/Windows/no-ehabi.ll [new file with mode: 0644]

index 5654e15..6c18387 100644 (file)
@@ -155,10 +155,9 @@ DataLayout::InvalidPointerElem = { 0U, 0U, 0U, ~0U };
 const char *DataLayout::getManglingComponent(const Triple &T) {
   if (T.isOSBinFormatMachO())
     return "-m:o";
-  if (T.isOSBinFormatELF() || T.isArch64Bit())
-    return "-m:e";
-  assert(T.isOSBinFormatCOFF());
-  return "-m:w";
+  if (T.isOSWindows() && T.getArch() == Triple::x86 && T.isOSBinFormatCOFF())
+    return "-m:w";
+  return "-m:e";
 }
 
 static const LayoutAlignElem DefaultAlignments[] = {
index 1778659..0f43b32 100644 (file)
@@ -250,7 +250,8 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM)
   setLibcallName(RTLIB::SRL_I128, 0);
   setLibcallName(RTLIB::SRA_I128, 0);
 
-  if (Subtarget->isAAPCS_ABI() && !Subtarget->isTargetMachO()) {
+  if (Subtarget->isAAPCS_ABI() && !Subtarget->isTargetMachO() &&
+      !Subtarget->isTargetWindows()) {
     // Double-precision floating-point arithmetic helper functions
     // RTABI chapter 4.1.2, Table 2
     setLibcallName(RTLIB::ADD_F64, "__aeabi_dadd");
index d2f3b20..5222c1b 100644 (file)
@@ -212,6 +212,12 @@ void ARMSubtarget::resetSubtargetFeatures(StringRef CPU, StringRef FS) {
     }
   }
 
+  // FIXME: this is invalid for WindowsCE
+  if (isTargetWindows()) {
+    TargetABI = ARM_ABI_AAPCS;
+    NoARM = true;
+  }
+
   if (isAAPCS_ABI())
     stackAlignment = 8;
   if (isTargetNaCl())
index 21fa83d..804f238 100644 (file)
@@ -317,14 +317,14 @@ public:
 
   const Triple &getTargetTriple() const { return TargetTriple; }
 
-  bool isTargetIOS() const { return TargetTriple.isiOS(); }
   bool isTargetDarwin() const { return TargetTriple.isOSDarwin(); }
-  bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
+  bool isTargetIOS() const { return TargetTriple.isiOS(); }
   bool isTargetLinux() const { return TargetTriple.isOSLinux(); }
-  bool isTargetNetBSD() const {
-    return TargetTriple.getOS() == Triple::NetBSD;
-  }
+  bool isTargetNaCl() const { return TargetTriple.isOSNaCl(); }
+  bool isTargetNetBSD() const { return TargetTriple.getOS() == Triple::NetBSD; }
+  bool isTargetWindows() const { return TargetTriple.isOSWindows(); }
 
+  bool isTargetCOFF() const { return TargetTriple.isOSBinFormatCOFF(); }
   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
   bool isTargetMachO() const { return TargetTriple.isOSBinFormatMachO(); }
 
@@ -338,7 +338,7 @@ public:
   bool isTargetAEABI() const {
     return (TargetTriple.getEnvironment() == Triple::EABI ||
             TargetTriple.getEnvironment() == Triple::EABIHF) &&
-           !isTargetDarwin();
+           !isTargetDarwin() && !isTargetWindows();
   }
 
   // ARM Targets that support EHABI exception handling standard
@@ -349,12 +349,14 @@ public:
             TargetTriple.getEnvironment() == Triple::EABIHF ||
             TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
             TargetTriple.getEnvironment() == Triple::Android) &&
-           !isTargetDarwin();
+           !isTargetDarwin() && !isTargetWindows();
   }
 
   bool isTargetHardFloat() const {
+    // FIXME: this is invalid for WindowsCE
     return TargetTriple.getEnvironment() == Triple::GNUEABIHF ||
-           TargetTriple.getEnvironment() == Triple::EABIHF;
+           TargetTriple.getEnvironment() == Triple::EABIHF ||
+           isTargetWindows();
   }
   bool isTargetAndroid() const {
     return TargetTriple.getEnvironment() == Triple::Android;
index 52e1fb9..b7f96e0 100644 (file)
@@ -76,3 +76,31 @@ void ARMELFMCAsmInfo::setUseIntegratedAssembler(bool Value) {
     DwarfRegNumForCFI = true;
   }
 }
+
+void ARMCOFFMCAsmInfoMicrosoft::anchor() { }
+
+ARMCOFFMCAsmInfoMicrosoft::ARMCOFFMCAsmInfoMicrosoft() {
+  AlignmentIsInBytes = false;
+
+  PrivateGlobalPrefix = "$M";
+}
+
+void ARMCOFFMCAsmInfoGNU::anchor() { }
+
+ARMCOFFMCAsmInfoGNU::ARMCOFFMCAsmInfoGNU() {
+  AlignmentIsInBytes = false;
+
+  CommentString = "@";
+  Code16Directive = ".code\t16";
+  Code32Directive = ".code\t32";
+  PrivateGlobalPrefix = ".L";
+
+  HasLEB128 = true;
+  SupportsDebugInformation = true;
+  ExceptionsType = ExceptionHandling::None;
+  UseParensForSymbolVariant = true;
+
+  UseIntegratedAssembler = false;
+  DwarfRegNumForCFI = true;
+}
+
index be02952..beaf6a4 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef LLVM_ARMTARGETASMINFO_H
 #define LLVM_ARMTARGETASMINFO_H
 
+#include "llvm/MC/MCAsmInfoCOFF.h"
 #include "llvm/MC/MCAsmInfoDarwin.h"
 #include "llvm/MC/MCAsmInfoELF.h"
 
@@ -33,6 +34,18 @@ namespace llvm {
     void setUseIntegratedAssembler(bool Value) override;
   };
 
+  class ARMCOFFMCAsmInfoMicrosoft : public MCAsmInfoMicrosoft {
+    void anchor();
+  public:
+    explicit ARMCOFFMCAsmInfoMicrosoft();
+  };
+
+  class ARMCOFFMCAsmInfoGNU : public MCAsmInfoGNUCOFF {
+    void anchor();
+  public:
+    explicit ARMCOFFMCAsmInfoGNU();
+  };
+
 } // namespace llvm
 
 #endif
index 99e73a5..949a3d5 100644 (file)
@@ -218,10 +218,31 @@ static MCAsmInfo *createARMMCAsmInfo(const MCRegisterInfo &MRI, StringRef TT) {
   Triple TheTriple(TT);
 
   MCAsmInfo *MAI;
-  if (TheTriple.isOSBinFormatMachO())
+  switch (TheTriple.getOS()) {
+  case llvm::Triple::Darwin:
+  case llvm::Triple::IOS:
+  case llvm::Triple::MacOSX:
     MAI = new ARMMCAsmInfoDarwin(TT);
-  else
-    MAI = new ARMELFMCAsmInfo(TT);
+    break;
+  case llvm::Triple::Win32:
+    switch (TheTriple.getEnvironment()) {
+    case llvm::Triple::Itanium:
+      MAI = new ARMCOFFMCAsmInfoGNU();
+      break;
+    case llvm::Triple::MSVC:
+      MAI = new ARMCOFFMCAsmInfoMicrosoft();
+      break;
+    default:
+      llvm_unreachable("invalid environment");
+    }
+    break;
+  default:
+    if (TheTriple.isOSBinFormatMachO())
+      MAI = new ARMMCAsmInfoDarwin(TT);
+    else
+      MAI = new ARMELFMCAsmInfo(TT);
+    break;
+  }
 
   unsigned Reg = MRI.getDwarfRegNum(ARM::SP, true);
   MAI->addInitialFrameState(MCCFIInstruction::createDefCfa(0, Reg, 0));
diff --git a/test/CodeGen/ARM/Windows/aapcs.ll b/test/CodeGen/ARM/Windows/aapcs.ll
new file mode 100644 (file)
index 0000000..3f9a09f
--- /dev/null
@@ -0,0 +1,16 @@
+; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -o - %s | FileCheck %s
+
+; AAPCS mandates an 8-byte stack alignment.  The alloca is implicitly aligned,
+; and no bic is required.
+
+declare void @callee(i8 *%i)
+
+define void @caller() {
+  %i = alloca i8, align 8
+  call void @callee(i8* %i)
+  ret void
+}
+
+; CHECK: sub sp, #8
+; CHECK-NOT: bic
+
diff --git a/test/CodeGen/ARM/Windows/hard-float.ll b/test/CodeGen/ARM/Windows/hard-float.ll
new file mode 100644 (file)
index 0000000..f7b7ec2
--- /dev/null
@@ -0,0 +1,10 @@
+; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -o - %s | FileCheck %s
+
+define float @function(float %f, float %g) nounwind {
+entry:
+  %h = fadd float %f, %g
+  ret float %h
+}
+
+; CHECK: vadd.f32 s0, s0, s1
+
diff --git a/test/CodeGen/ARM/Windows/mangling.ll b/test/CodeGen/ARM/Windows/mangling.ll
new file mode 100644 (file)
index 0000000..ce1fe2e
--- /dev/null
@@ -0,0 +1,9 @@
+; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -o - %s | FileCheck %s
+
+define void @function() nounwind {
+entry:
+  ret void
+}
+
+; CHECK-LABEL: function
+
diff --git a/test/CodeGen/ARM/Windows/no-aeabi.ll b/test/CodeGen/ARM/Windows/no-aeabi.ll
new file mode 100644 (file)
index 0000000..4c6676f
--- /dev/null
@@ -0,0 +1,10 @@
+; RUN: llc -mtriple=thumbv7-windows-itanium -mcpu=cortex-a9 -o - %s | FileCheck %s
+
+define i32 @divide(i32 %i, i32 %j) nounwind {
+entry:
+  %quotient = sdiv i32 %i, %j
+  ret i32 %quotient
+}
+
+; CHECK-NOT: __aeabi_idiv
+
diff --git a/test/CodeGen/ARM/Windows/no-arm-mode.ll b/test/CodeGen/ARM/Windows/no-arm-mode.ll
new file mode 100644 (file)
index 0000000..6db031f
--- /dev/null
@@ -0,0 +1,5 @@
+; RUN: not llc -mtriple=armv7-windows-itanium -mcpu=cortex-a9 -o /dev/null %s 2>&1 \
+; RUN:  | FileCheck %s
+
+; CHECK: does not support ARM mode execution
+
diff --git a/test/CodeGen/ARM/Windows/no-ehabi.ll b/test/CodeGen/ARM/Windows/no-ehabi.ll
new file mode 100644 (file)
index 0000000..4119b6d
--- /dev/null
@@ -0,0 +1,21 @@
+; RUN: llc -mtriple=thumbv7-windows -mcpu=cortex-a9 -o - %s | FileCheck %s
+
+declare void @callee(i32 %i)
+
+define i32 @caller(i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o,
+                   i32 %p) {
+entry:
+  %q = add nsw i32 %j, %i
+  %r = add nsw i32 %q, %k
+  %s = add nsw i32 %r, %l
+  call void @callee(i32 %s)
+  %t = add nsw i32 %n, %m
+  %u = add nsw i32 %t, %o
+  %v = add nsw i32 %u, %p
+  call void @callee(i32 %v)
+  %w = add nsw i32 %v, %s
+  ret i32 %w
+}
+
+; CHECK-NOT: .save {{{.*}}}
+