ARM64: diagnose use of v16-v31 in certain indexed NEON instructions.
[oota-llvm.git] / lib / Target / ARM64 / ARM64AsmPrinter.cpp
index d01108d259d673e9842594e2fc3093d2d06e64ef..615cb2884d2ec80742d5dc1202407d2ab760a934 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "asm-printer"
 #include "ARM64.h"
 #include "ARM64MachineFunctionInfo.h"
 #include "ARM64MCInstLower.h"
 #include "ARM64RegisterInfo.h"
+#include "ARM64Subtarget.h"
 #include "InstPrinter/ARM64InstPrinter.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringSwitch.h"
@@ -24,6 +24,8 @@
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/StackMaps.h"
+#include "llvm/CodeGen/MachineModuleInfoImpls.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/Support/TargetRegistry.h"
 using namespace llvm;
 
+#define DEBUG_TYPE "asm-printer"
+
 namespace {
 
 class ARM64AsmPrinter : public AsmPrinter {
+  /// Subtarget - Keep a pointer to the ARM64Subtarget around so that we can
+  /// make the right decision when printing asm code for different targets.
+  const ARM64Subtarget *Subtarget;
+
   ARM64MCInstLower MCInstLowering;
   StackMaps SM;
 
 public:
   ARM64AsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
-      : AsmPrinter(TM, Streamer), MCInstLowering(OutContext, *Mang, *this),
-        SM(*this), ARM64FI(NULL), LOHLabelCounter(0) {}
+      : AsmPrinter(TM, Streamer), Subtarget(&TM.getSubtarget<ARM64Subtarget>()),
+        MCInstLowering(OutContext, *Mang, *this), SM(*this), ARM64FI(nullptr),
+        LOHLabelCounter(0) {}
 
   virtual const char *getPassName() const { return "ARM64 Assembly Printer"; }
 
@@ -112,13 +121,38 @@ private:
 //===----------------------------------------------------------------------===//
 
 void ARM64AsmPrinter::EmitEndOfAsmFile(Module &M) {
-  // Funny Darwin hack: This flag tells the linker that no global symbols
-  // contain code that falls through to other global symbols (e.g. the obvious
-  // implementation of multiple entry points).  If this doesn't occur, the
-  // linker can safely perform dead code stripping.  Since LLVM never
-  // generates code that does this, it is always safe to set.
-  OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
-  SM.serializeToStackMapSection();
+  if (Subtarget->isTargetMachO()) {
+    // Funny Darwin hack: This flag tells the linker that no global symbols
+    // contain code that falls through to other global symbols (e.g. the obvious
+    // implementation of multiple entry points).  If this doesn't occur, the
+    // linker can safely perform dead code stripping.  Since LLVM never
+    // generates code that does this, it is always safe to set.
+    OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
+    SM.serializeToStackMapSection();
+  }
+
+  // Emit a .data.rel section containing any stubs that were created.
+  if (Subtarget->isTargetELF()) {
+    const TargetLoweringObjectFileELF &TLOFELF =
+      static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering());
+
+    MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();
+
+    // Output stubs for external and common global variables.
+    MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
+    if (!Stubs.empty()) {
+      OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
+      const DataLayout *TD = TM.getDataLayout();
+
+      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
+        OutStreamer.EmitLabel(Stubs[i].first);
+        OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(),
+                                    TD->getPointerSize(0));
+      }
+      Stubs.clear();
+    }
+  }
+
 }
 
 MachineLocation
@@ -135,26 +169,16 @@ ARM64AsmPrinter::getDebugValueLocation(const MachineInstr *MI) const {
 }
 
 void ARM64AsmPrinter::EmitLOHs() {
-  const ARM64FunctionInfo::MILOHDirectives &LOHs =
-      const_cast<const ARM64FunctionInfo *>(ARM64FI)
-          ->getLOHContainer()
-          .getDirectives();
   SmallVector<MCSymbol *, 3> MCArgs;
 
-  for (ARM64FunctionInfo::MILOHDirectives::const_iterator It = LOHs.begin(),
-                                                          EndIt = LOHs.end();
-       It != EndIt; ++It) {
-    const ARM64FunctionInfo::MILOHArgs &MIArgs = It->getArgs();
-    for (ARM64FunctionInfo::MILOHArgs::const_iterator
-             MIArgsIt = MIArgs.begin(),
-             EndMIArgsIt = MIArgs.end();
-         MIArgsIt != EndMIArgsIt; ++MIArgsIt) {
-      MInstToMCSymbol::iterator LabelIt = LOHInstToLabel.find(*MIArgsIt);
+  for (const auto &D : ARM64FI->getLOHContainer()) {
+    for (const MachineInstr *MI : D.getArgs()) {
+      MInstToMCSymbol::iterator LabelIt = LOHInstToLabel.find(MI);
       assert(LabelIt != LOHInstToLabel.end() &&
              "Label hasn't been inserted for LOH related instruction");
       MCArgs.push_back(LabelIt->second);
     }
-    OutStreamer.EmitLOHDirective(It->getKind(), MCArgs);
+    OutStreamer.EmitLOHDirective(D.getKind(), MCArgs);
     MCArgs.clear();
   }
 }
@@ -569,5 +593,6 @@ void ARM64AsmPrinter::EmitInstruction(const MachineInstr *MI) {
 
 // Force static initialization.
 extern "C" void LLVMInitializeARM64AsmPrinter() {
-  RegisterAsmPrinter<ARM64AsmPrinter> X(TheARM64Target);
+  RegisterAsmPrinter<ARM64AsmPrinter> X(TheARM64leTarget);
+  RegisterAsmPrinter<ARM64AsmPrinter> Y(TheARM64beTarget);
 }