Remove old style hacks to register AsmPrinter into TargetMachine.
[oota-llvm.git] / lib / Target / ARM / AsmPrinter / ARMAsmPrinter.cpp
index b298ff7715c78b387d1a770c1fa6ad56da66c06b..7270e37fa2bf6718c8a0bb85dfa05769cfe21c0e 100644 (file)
@@ -31,6 +31,7 @@
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetRegistry.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringSet.h"
@@ -38,7 +39,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/FormattedStream.h"
 #include <cctype>
 using namespace llvm;
 
@@ -69,20 +70,45 @@ namespace {
 
     /// GVNonLazyPtrs - Keeps the set of GlobalValues that require
     /// non-lazy-pointers for indirect access.
-    StringSet<> GVNonLazyPtrs;
+    StringMap<std::string> GVNonLazyPtrs;
 
     /// HiddenGVNonLazyPtrs - Keeps the set of GlobalValues with hidden
     /// visibility that require non-lazy-pointers for indirect access.
-    StringSet<> HiddenGVNonLazyPtrs;
-
+    StringMap<std::string> HiddenGVNonLazyPtrs;
+
+    struct FnStubInfo {
+      std::string Stub, LazyPtr, SLP, SCV;
+      
+      FnStubInfo() {}
+      
+      void Init(const GlobalValue *GV, Mangler *Mang) {
+        // Already initialized.
+        if (!Stub.empty()) return;
+        Stub = Mang->getMangledName(GV, "$stub", true);
+        LazyPtr = Mang->getMangledName(GV, "$lazy_ptr", true);
+        SLP = Mang->getMangledName(GV, "$slp", true);
+        SCV = Mang->getMangledName(GV, "$scv", true);
+      }
+      
+      void Init(const std::string &GV, Mangler *Mang) {
+        // Already initialized.
+        if (!Stub.empty()) return;
+        Stub = Mang->makeNameProper(GV+"$stub", true);
+        LazyPtr = Mang->makeNameProper(GV+"$lazy_ptr", true);
+        SLP = Mang->makeNameProper(GV+"$slp", true);
+        SCV = Mang->makeNameProper(GV+"$scv", true);
+      }
+      
+    };
+    
     /// FnStubs - Keeps the set of external function GlobalAddresses that the
     /// asm printer should generate stubs for.
-    StringSet<> FnStubs;
+    StringMap<FnStubInfo> FnStubs;
 
     /// True if asm printer is printing a series of CONSTPOOL_ENTRY.
     bool InCPMode;
   public:
-    explicit ARMAsmPrinter(raw_ostream &O, TargetMachine &TM,
+    explicit ARMAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
                            const TargetAsmInfo *T, bool V)
       : AsmPrinter(O, TM, T, V), DW(0), AFI(NULL), MCP(NULL),
         InCPMode(false) {
@@ -155,20 +181,37 @@ namespace {
 
       ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV);
       GlobalValue *GV = ACPV->getGV();
-      std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix();
-      if (!GV)
-        Name += ACPV->getSymbol();
+      std::string Name;
+      
+      
       if (ACPV->isNonLazyPointer()) {
+        std::string SymName = Mang->getMangledName(GV);
+        Name = Mang->getMangledName(GV, "$non_lazy_ptr", true);
+        
         if (GV->hasHiddenVisibility())
-          HiddenGVNonLazyPtrs.insert(Name);
+          HiddenGVNonLazyPtrs[SymName] = Name;
         else
-          GVNonLazyPtrs.insert(Name);
-        printSuffixedName(Name, "$non_lazy_ptr");
+          GVNonLazyPtrs[SymName] = Name;
       } else if (ACPV->isStub()) {
-        FnStubs.insert(Name);
-        printSuffixedName(Name, "$stub");
-      } else
-        O << Name;
+        if (GV) {
+          FnStubInfo &FnInfo = FnStubs[Mang->getMangledName(GV)];
+          FnInfo.Init(GV, Mang);
+          Name = FnInfo.Stub;
+        } else {
+          FnStubInfo &FnInfo = FnStubs[Mang->makeNameProper(ACPV->getSymbol())];
+          FnInfo.Init(ACPV->getSymbol(), Mang);
+          Name = FnInfo.Stub;
+        }
+      } else {
+        if (GV)
+          Name = Mang->getMangledName(GV);
+        else
+          Name = Mang->makeNameProper(ACPV->getSymbol());
+      }
+      O << Name;
+      
+      
+      
       if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
       if (ACPV->getPCAdjustment() != 0) {
         O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
@@ -211,7 +254,7 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   // Print out labels for the function.
   const Function *F = MF.getFunction();
   switch (F->getLinkage()) {
-  default: LLVM_UNREACHABLE("Unknown linkage type!");
+  default: llvm_unreachable("Unknown linkage type!");
   case Function::PrivateLinkage:
   case Function::InternalLinkage:
     SwitchToTextSection("\t.text", F);
@@ -308,7 +351,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
         O << TRI->getAsmName(Reg);
       }
     } else
-      LLVM_UNREACHABLE("not implemented");
+      llvm_unreachable("not implemented");
     break;
   }
   case MachineOperand::MO_Immediate: {
@@ -324,15 +367,18 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
   case MachineOperand::MO_GlobalAddress: {
     bool isCallOp = Modifier && !strcmp(Modifier, "call");
     GlobalValue *GV = MO.getGlobal();
-    std::string Name = Mang->getValueName(GV);
-    bool isExt = (GV->isDeclaration() || GV->hasWeakLinkage() ||
-                  GV->hasLinkOnceLinkage());
+    std::string Name;
+    bool isExt = GV->isDeclaration() || GV->isWeakForLinker();
     if (isExt && isCallOp && Subtarget->isTargetDarwin() &&
         TM.getRelocationModel() != Reloc::Static) {
-      printSuffixedName(Name, "$stub");
-      FnStubs.insert(Name);
-    } else
-      O << Name;
+      FnStubInfo &FnInfo = FnStubs[Mang->getMangledName(GV)];
+      FnInfo.Init(GV, Mang);
+      Name = FnInfo.Stub;
+    } else {
+      Name = Mang->getMangledName(GV);
+    }
+    
+    O << Name;
 
     printOffset(MO.getOffset());
 
@@ -343,14 +389,16 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
   }
   case MachineOperand::MO_ExternalSymbol: {
     bool isCallOp = Modifier && !strcmp(Modifier, "call");
-    std::string Name(TAI->getGlobalPrefix());
-    Name += MO.getSymbolName();
+    std::string Name;
     if (isCallOp && Subtarget->isTargetDarwin() &&
         TM.getRelocationModel() != Reloc::Static) {
-      printSuffixedName(Name, "$stub");
-      FnStubs.insert(Name);
+      FnStubInfo &FnInfo = FnStubs[Mang->makeNameProper(MO.getSymbolName())];
+      FnInfo.Init(MO.getSymbolName(), Mang);
+      Name = FnInfo.Stub;
     } else
-      O << Name;
+      Name = Mang->makeNameProper(MO.getSymbolName());
+    
+    O << Name;
     if (isCallOp && Subtarget->isTargetELF() &&
         TM.getRelocationModel() == Reloc::PIC_)
       O << "(PLT)";
@@ -369,7 +417,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
   }
 }
 
-static void printSOImm(raw_ostream &O, int64_t V, bool VerboseAsm,
+static void printSOImm(formatted_raw_ostream &O, int64_t V, bool VerboseAsm,
                        const TargetAsmInfo *TAI) {
   // Break it up into two parts that make up a shifter immediate.
   V = ARM_AM::getSOImmVal(V);
@@ -642,7 +690,7 @@ ARMAsmPrinter::printThumbITMask(const MachineInstr *MI, int Op) {
   unsigned Mask = MI->getOperand(Op).getImm();
   unsigned NumTZ = CountTrailingZeros_32(Mask);
   assert(NumTZ <= 3 && "Invalid IT mask!");
-  for (unsigned Pos = 3, e = NumTZ; Pos >= e; --Pos) {
+  for (unsigned Pos = 3, e = NumTZ; Pos > e; --Pos) {
     bool T = (Mask & (1 << Pos)) != 0;
     if (T)
       O << 't';
@@ -974,8 +1022,8 @@ bool ARMAsmPrinter::doInitialization(Module &M) {
   bool Result = AsmPrinter::doInitialization(M);
   DW = getAnalysisIfAvailable<DwarfWriter>();
 
-  // Thumb-2 instructions are supported only in unified assembler syntax mode.
-  if (Subtarget->hasThumb2())
+  // Use unified assembler syntax mode for Thumb.
+  if (Subtarget->isThumb())
     O << "\t.syntax unified\n";
 
   // Emit ARM Build Attributes
@@ -1011,7 +1059,7 @@ bool ARMAsmPrinter::doInitialization(Module &M) {
 
 /// PrintUnmangledNameSafely - Print out the printable characters in the name.
 /// Don't print things like \\n or \\0.
-static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) {
+static void PrintUnmangledNameSafely(const Value *V, formatted_raw_ostream &OS) {
   for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
        Name != E; ++Name)
     if (isprint(*Name))
@@ -1037,7 +1085,7 @@ void ARMAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
     return;
   }
 
-  std::string name = Mang->getValueName(GVar);
+  std::string name = Mang->getMangledName(GVar);
   Constant *C = GVar->getInitializer();
   if (isa<MDNode>(C) || isa<MDString>(C))
     return;
@@ -1139,7 +1187,7 @@ void ARMAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
    case GlobalValue::InternalLinkage:
     break;
    default:
-    LLVM_UNREACHABLE("Unknown linkage type!");
+    llvm_unreachable("Unknown linkage type!");
   }
 
   EmitAlignment(Align, GVar);
@@ -1165,9 +1213,11 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
   if (Subtarget->isTargetDarwin()) {
     SwitchToDataSection("");
 
+    O << '\n';
     // Output stubs for dynamically-linked functions
-    for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
-         i != e; ++i) {
+    for (StringMap<FnStubInfo>::iterator I = FnStubs.begin(), E = FnStubs.end();
+         I != E; ++I) {
+      const FnStubInfo &Info = I->second;
       if (TM.getRelocationModel() == Reloc::PIC_)
         SwitchToTextSection(".section __TEXT,__picsymbolstub4,symbol_stubs,"
                             "none,16", 0);
@@ -1178,59 +1228,45 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
       EmitAlignment(2);
       O << "\t.code\t32\n";
 
-      const char *p = i->getKeyData();
-      printSuffixedName(p, "$stub");
-      O << ":\n";
-      O << "\t.indirect_symbol " << p << "\n";
-      O << "\tldr ip, ";
-      printSuffixedName(p, "$slp");
-      O << "\n";
+      O << Info.Stub << ":\n";
+      O << "\t.indirect_symbol " << I->getKeyData() << '\n';
+      O << "\tldr ip, " << Info.SLP << '\n';
       if (TM.getRelocationModel() == Reloc::PIC_) {
-        printSuffixedName(p, "$scv");
-        O << ":\n";
+        O << Info.SCV << ":\n";
         O << "\tadd ip, pc, ip\n";
       }
       O << "\tldr pc, [ip, #0]\n";
-      printSuffixedName(p, "$slp");
-      O << ":\n";
-      O << "\t.long\t";
-      printSuffixedName(p, "$lazy_ptr");
-      if (TM.getRelocationModel() == Reloc::PIC_) {
-        O << "-(";
-        printSuffixedName(p, "$scv");
-        O << "+8)\n";
-      } else
-        O << "\n";
+      O << Info.SLP << ":\n";
+      O << "\t.long\t" << Info.LazyPtr;
+      if (TM.getRelocationModel() == Reloc::PIC_)
+        O << "-(" << Info.SCV << "+8)";
+      O << '\n';
+      
       SwitchToDataSection(".lazy_symbol_pointer", 0);
-      printSuffixedName(p, "$lazy_ptr");
-      O << ":\n";
-      O << "\t.indirect_symbol " << p << "\n";
+      O << Info.LazyPtr << ":\n";
+      O << "\t.indirect_symbol " << I->getKeyData() << "\n";
       O << "\t.long\tdyld_stub_binding_helper\n";
     }
-    O << "\n";
+    O << '\n';
 
     // Output non-lazy-pointers for external and common global variables.
     if (!GVNonLazyPtrs.empty()) {
       SwitchToDataSection("\t.non_lazy_symbol_pointer", 0);
-      for (StringSet<>::iterator i =  GVNonLazyPtrs.begin(),
-             e = GVNonLazyPtrs.end(); i != e; ++i) {
-        const char *p = i->getKeyData();
-        printSuffixedName(p, "$non_lazy_ptr");
-        O << ":\n";
-        O << "\t.indirect_symbol " << p << "\n";
+      for (StringMap<std::string>::iterator I =  GVNonLazyPtrs.begin(),
+             E = GVNonLazyPtrs.end(); I != E; ++I) {
+        O << I->second << ":\n";
+        O << "\t.indirect_symbol " << I->getKeyData() << "\n";
         O << "\t.long\t0\n";
       }
     }
 
     if (!HiddenGVNonLazyPtrs.empty()) {
       SwitchToSection(TAI->getDataSection());
-      for (StringSet<>::iterator i = HiddenGVNonLazyPtrs.begin(),
-             e = HiddenGVNonLazyPtrs.end(); i != e; ++i) {
-        const char *p = i->getKeyData();
+      for (StringMap<std::string>::iterator I = HiddenGVNonLazyPtrs.begin(),
+             E = HiddenGVNonLazyPtrs.end(); I != E; ++I) {
         EmitAlignment(2);
-        printSuffixedName(p, "$non_lazy_ptr");
-        O << ":\n";
-        O << "\t.long " << p << "\n";
+        O << I->second << ":\n";
+        O << "\t.long " << I->getKeyData() << "\n";
       }
     }
 
@@ -1251,19 +1287,15 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
 /// using the given target machine description.  This should work
 /// regardless of whether the function is in SSA form.
 ///
-FunctionPass *llvm::createARMCodePrinterPass(raw_ostream &o,
-                                             ARMBaseTargetMachine &tm,
+FunctionPass *llvm::createARMCodePrinterPass(formatted_raw_ostream &o,
+                                             TargetMachine &tm,
                                              bool verbose) {
   return new ARMAsmPrinter(o, tm, tm.getTargetAsmInfo(), verbose);
 }
 
-namespace {
-  static struct Register {
-    Register() {
-      ARMBaseTargetMachine::registerAsmPrinter(createARMCodePrinterPass);
-    }
-  } Registrator;
-}
-
 // Force static initialization.
-extern "C" void LLVMInitializeARMAsmPrinter() { }
+extern "C" void LLVMInitializeARMAsmPrinter() { 
+  extern Target TheARMTarget, TheThumbTarget;
+  TargetRegistry::RegisterAsmPrinter(TheARMTarget, createARMCodePrinterPass);
+  TargetRegistry::RegisterAsmPrinter(TheThumbTarget, createARMCodePrinterPass);
+}