Handle quoted names when constructing $stub's,
[oota-llvm.git] / lib / Target / ARM / ARMAsmPrinter.cpp
index 6357e1ee80679e846aae7728c5bc9faff48d3883..e850ef1983b0fa004fe5604ef7a0a09aa45f3003 100644 (file)
@@ -2,8 +2,7 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the "Instituto Nokia de Tecnologia" and
-// is distributed under the University of Illinois Open Source
+// This file is distributed under the University of Illinois Open Source
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
@@ -102,6 +101,7 @@ namespace {
     void printThumbAddrModeS4Operand(const MachineInstr *MI, int OpNo);
     void printThumbAddrModeSPOperand(const MachineInstr *MI, int OpNo);
     void printPredicateOperand(const MachineInstr *MI, int opNum);
+    void printSBitModifierOperand(const MachineInstr *MI, int opNum);
     void printPCLabel(const MachineInstr *MI, int opNum);
     void printRegisterList(const MachineInstr *MI, int opNum);
     void printCPInstOperand(const MachineInstr *MI, int opNum,
@@ -127,10 +127,10 @@ namespace {
         Name += ACPV->getSymbol();
       if (ACPV->isNonLazyPointer()) {
         GVNonLazyPtrs.insert(Name);
-        O << TAI->getPrivateGlobalPrefix() << Name << "$non_lazy_ptr";
+        printSuffixedName(Name, "$non_lazy_ptr");
       } else if (ACPV->isStub()) {
         FnStubs.insert(Name);
-        O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
+        printSuffixedName(Name, "$stub");
       } else
         O << Name;
       if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
@@ -151,6 +151,7 @@ namespace {
     }
     
     void getAnalysisUsage(AnalysisUsage &AU) const {
+      AsmPrinter::getAnalysisUsage(AU);
       AU.setPreservesAll();
       AU.addRequired<MachineModuleInfo>();
     }
@@ -232,12 +233,22 @@ bool ARMAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   // Emit pre-function debug information.
   DW.BeginFunction(&MF);
 
+  if (Subtarget->isTargetDarwin()) {
+    // If the function is empty, then we need to emit *something*. Otherwise,
+    // the function's label might be associated with something that it wasn't
+    // meant to be associated with. We emit a noop in this situation.
+    MachineFunction::iterator I = MF.begin();
+
+    if (++I == MF.end() && MF.front().empty())
+      O << "\tnop\n";
+  }
+
   // Print out code for the function.
   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
        I != E; ++I) {
     // Print a label for the basic block.
     if (I != MF.begin()) {
-      printBasicBlockLabel(I, true);
+      printBasicBlockLabel(I, true, true);
       O << '\n';
     }
     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
@@ -261,8 +272,8 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
   const MachineOperand &MO = MI->getOperand(opNum);
   switch (MO.getType()) {
   case MachineOperand::MO_Register:
-    if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
-      O << TM.getRegisterInfo()->get(MO.getReg()).Name;
+    if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
+      O << TM.getRegisterInfo()->get(MO.getReg()).AsmName;
     else
       assert(0 && "not implemented");
     break;
@@ -270,11 +281,11 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
     if (!Modifier || strcmp(Modifier, "no_hash") != 0)
       O << "#";
 
-    O << (int)MO.getImmedValue();
+    O << (int)MO.getImm();
     break;
   }
   case MachineOperand::MO_MachineBasicBlock:
-    printBasicBlockLabel(MO.getMachineBasicBlock());
+    printBasicBlockLabel(MO.getMBB());
     return;
   case MachineOperand::MO_GlobalAddress: {
     bool isCallOp = Modifier && !strcmp(Modifier, "call");
@@ -284,7 +295,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
                   GV->hasLinkOnceLinkage());
     if (isExt && isCallOp && Subtarget->isTargetDarwin() &&
         TM.getRelocationModel() != Reloc::Static) {
-      O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
+      printSuffixedName(Name, "$stub");
       FnStubs.insert(Name);
     } else
       O << Name;
@@ -307,7 +318,7 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
     Name += MO.getSymbolName();
     if (isCallOp && Subtarget->isTargetDarwin() &&
         TM.getRelocationModel() != Reloc::Static) {
-      O << TAI->getPrivateGlobalPrefix() << Name << "$stub";
+      printSuffixedName(Name, "$stub");
       FnStubs.insert(Name);
     } else
       O << Name;
@@ -318,11 +329,11 @@ void ARMAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
   }
   case MachineOperand::MO_ConstantPoolIndex:
     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
-      << '_' << MO.getConstantPoolIndex();
+      << '_' << MO.getIndex();
     break;
   case MachineOperand::MO_JumpTableIndex:
     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
-      << '_' << MO.getJumpTableIndex();
+      << '_' << MO.getIndex();
     break;
   default:
     O << "<unknown operand type>"; abort (); break;
@@ -350,7 +361,7 @@ static void printSOImm(std::ostream &O, int64_t V, const TargetAsmInfo *TAI) {
 void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
   const MachineOperand &MO = MI->getOperand(OpNum);
   assert(MO.isImmediate() && "Not a valid so_imm value!");
-  printSOImm(O, MO.getImmedValue(), TAI);
+  printSOImm(O, MO.getImm(), TAI);
 }
 
 /// printSOImm2PartOperand - SOImm is broken into two pieces using a mov
@@ -358,10 +369,12 @@ void ARMAsmPrinter::printSOImmOperand(const MachineInstr *MI, int OpNum) {
 void ARMAsmPrinter::printSOImm2PartOperand(const MachineInstr *MI, int OpNum) {
   const MachineOperand &MO = MI->getOperand(OpNum);
   assert(MO.isImmediate() && "Not a valid so_imm value!");
-  unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImmedValue());
-  unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImmedValue());
+  unsigned V1 = ARM_AM::getSOImmTwoPartFirst(MO.getImm());
+  unsigned V2 = ARM_AM::getSOImmTwoPartSecond(MO.getImm());
   printSOImm(O, ARM_AM::getSOImmVal(V1), TAI);
-  O << "\n\torr ";
+  O << "\n\torr";
+  printPredicateOperand(MI, 2);
+  O << " ";
   printOperand(MI, 0); 
   O << ", ";
   printOperand(MI, 0); 
@@ -379,17 +392,17 @@ void ARMAsmPrinter::printSORegOperand(const MachineInstr *MI, int Op) {
   const MachineOperand &MO2 = MI->getOperand(Op+1);
   const MachineOperand &MO3 = MI->getOperand(Op+2);
 
-  assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
-  O << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
+  O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
 
   // Print the shift opc.
   O << ", "
-    << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImmedValue()))
+    << ARM_AM::getShiftOpcStr(ARM_AM::getSORegShOp(MO3.getImm()))
     << " ";
 
   if (MO2.getReg()) {
-    assert(MRegisterInfo::isPhysicalRegister(MO2.getReg()));
-    O << TM.getRegisterInfo()->get(MO2.getReg()).Name;
+    assert(TargetRegisterInfo::isPhysicalRegister(MO2.getReg()));
+    O << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
     assert(ARM_AM::getSORegOffset(MO3.getImm()) == 0);
   } else {
     O << "#" << ARM_AM::getSORegOffset(MO3.getImm());
@@ -406,7 +419,7 @@ void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
     return;
   }
 
-  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
 
   if (!MO2.getReg()) {
     if (ARM_AM::getAM2Offset(MO3.getImm()))  // Don't print +0.
@@ -419,11 +432,11 @@ void ARMAsmPrinter::printAddrMode2Operand(const MachineInstr *MI, int Op) {
 
   O << ", "
     << (char)ARM_AM::getAM2Op(MO3.getImm())
-    << TM.getRegisterInfo()->get(MO2.getReg()).Name;
+    << TM.getRegisterInfo()->get(MO2.getReg()).AsmName;
   
   if (unsigned ShImm = ARM_AM::getAM2Offset(MO3.getImm()))
     O << ", "
-      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImmedValue()))
+      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO3.getImm()))
       << " #" << ShImm;
   O << "]";
 }
@@ -442,11 +455,11 @@ void ARMAsmPrinter::printAddrMode2OffsetOperand(const MachineInstr *MI, int Op){
   }
 
   O << (char)ARM_AM::getAM2Op(MO2.getImm())
-    << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+    << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
   
   if (unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm()))
     O << ", "
-      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImmedValue()))
+      << ARM_AM::getShiftOpcStr(ARM_AM::getAM2ShiftOpc(MO2.getImm()))
       << " #" << ShImm;
 }
 
@@ -455,13 +468,13 @@ void ARMAsmPrinter::printAddrMode3Operand(const MachineInstr *MI, int Op) {
   const MachineOperand &MO2 = MI->getOperand(Op+1);
   const MachineOperand &MO3 = MI->getOperand(Op+2);
   
-  assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
-  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
+  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
 
   if (MO2.getReg()) {
     O << ", "
       << (char)ARM_AM::getAM3Op(MO3.getImm())
-      << TM.getRegisterInfo()->get(MO2.getReg()).Name
+      << TM.getRegisterInfo()->get(MO2.getReg()).AsmName
       << "]";
     return;
   }
@@ -479,7 +492,7 @@ void ARMAsmPrinter::printAddrMode3OffsetOperand(const MachineInstr *MI, int Op){
 
   if (MO1.getReg()) {
     O << (char)ARM_AM::getAM3Op(MO2.getImm())
-      << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+      << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
     return;
   }
 
@@ -519,7 +532,7 @@ void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
     return;
   }
   
-  assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
+  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
 
   if (Modifier && strcmp(Modifier, "submode") == 0) {
     ARM_AM::AMSubMode Mode = ARM_AM::getAM5SubMode(MO2.getImm());
@@ -532,13 +545,13 @@ void ARMAsmPrinter::printAddrMode5Operand(const MachineInstr *MI, int Op,
     return;
   } else if (Modifier && strcmp(Modifier, "base") == 0) {
     // Used for FSTM{D|S} and LSTM{D|S} operations.
-    O << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+    O << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
     if (ARM_AM::getAM5WBFlag(MO2.getImm()))
       O << "!";
     return;
   }
   
-  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
   
   if (unsigned ImmOffs = ARM_AM::getAM5Offset(MO2.getImm())) {
     O << ", #"
@@ -556,16 +569,16 @@ void ARMAsmPrinter::printAddrModePCOperand(const MachineInstr *MI, int Op,
   }
 
   const MachineOperand &MO1 = MI->getOperand(Op);
-  assert(MRegisterInfo::isPhysicalRegister(MO1.getReg()));
-  O << "[pc, +" << TM.getRegisterInfo()->get(MO1.getReg()).Name << "]";
+  assert(TargetRegisterInfo::isPhysicalRegister(MO1.getReg()));
+  O << "[pc, +" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName << "]";
 }
 
 void
 ARMAsmPrinter::printThumbAddrModeRROperand(const MachineInstr *MI, int Op) {
   const MachineOperand &MO1 = MI->getOperand(Op);
   const MachineOperand &MO2 = MI->getOperand(Op+1);
-  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
-  O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).Name << "]";
+  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
+  O << ", " << TM.getRegisterInfo()->get(MO2.getReg()).AsmName << "]";
 }
 
 void
@@ -580,9 +593,9 @@ ARMAsmPrinter::printThumbAddrModeRI5Operand(const MachineInstr *MI, int Op,
     return;
   }
 
-  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
   if (MO3.getReg())
-    O << ", " << TM.getRegisterInfo()->get(MO3.getReg()).Name;
+    O << ", " << TM.getRegisterInfo()->get(MO3.getReg()).AsmName;
   else if (unsigned ImmOffs = MO2.getImm()) {
     O << ", #" << ImmOffs;
     if (Scale > 1)
@@ -607,20 +620,28 @@ ARMAsmPrinter::printThumbAddrModeS4Operand(const MachineInstr *MI, int Op) {
 void ARMAsmPrinter::printThumbAddrModeSPOperand(const MachineInstr *MI,int Op) {
   const MachineOperand &MO1 = MI->getOperand(Op);
   const MachineOperand &MO2 = MI->getOperand(Op+1);
-  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).Name;
+  O << "[" << TM.getRegisterInfo()->get(MO1.getReg()).AsmName;
   if (unsigned ImmOffs = MO2.getImm())
     O << ", #" << ImmOffs << " * 4";
   O << "]";
 }
 
 void ARMAsmPrinter::printPredicateOperand(const MachineInstr *MI, int opNum) {
-  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(opNum).getImmedValue();
+  ARMCC::CondCodes CC = (ARMCC::CondCodes)MI->getOperand(opNum).getImm();
   if (CC != ARMCC::AL)
     O << ARMCondCodeToString(CC);
 }
 
+void ARMAsmPrinter::printSBitModifierOperand(const MachineInstr *MI, int opNum){
+  unsigned Reg = MI->getOperand(opNum).getReg();
+  if (Reg) {
+    assert(Reg == ARM::CPSR && "Expect ARM CPSR register!");
+    O << 's';
+  }
+}
+
 void ARMAsmPrinter::printPCLabel(const MachineInstr *MI, int opNum) {
-  int Id = (int)MI->getOperand(opNum).getImmedValue();
+  int Id = (int)MI->getOperand(opNum).getImm();
   O << TAI->getPrivateGlobalPrefix() << "PC" << Id;
 }
 
@@ -644,7 +665,7 @@ void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNo,
       << '_' << ID << ":\n";
   } else {
     assert(!strcmp(Modifier, "cpentry") && "Unknown modifier for CPE");
-    unsigned CPI = MI->getOperand(OpNo).getConstantPoolIndex();
+    unsigned CPI = MI->getOperand(OpNo).getIndex();
 
     const MachineConstantPoolEntry &MCPE =  // Chasing pointers is fun?
       MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI];
@@ -664,9 +685,9 @@ void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNo,
 void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNo) {
   const MachineOperand &MO1 = MI->getOperand(OpNo);
   const MachineOperand &MO2 = MI->getOperand(OpNo+1); // Unique Id
-  unsigned JTI = MO1.getJumpTableIndex();
+  unsigned JTI = MO1.getIndex();
   O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
-    << '_' << JTI << '_' << MO2.getImmedValue() << ":\n";
+    << '_' << JTI << '_' << MO2.getImm() << ":\n";
 
   const char *JTEntryDirective = TAI->getJumpTableDirective();
   if (!JTEntryDirective)
@@ -681,21 +702,21 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNo) {
   for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
     MachineBasicBlock *MBB = JTBBs[i];
     if (UseSet && JTSets.insert(MBB).second)
-      printSetLabel(JTI, MO2.getImmedValue(), MBB);
+      printPICJumpTableSetLabel(JTI, MO2.getImm(), MBB);
 
     O << JTEntryDirective << ' ';
     if (UseSet)
       O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
-        << '_' << JTI << '_' << MO2.getImmedValue()
+        << '_' << JTI << '_' << MO2.getImm()
         << "_set_" << MBB->getNumber();
     else if (TM.getRelocationModel() == Reloc::PIC_) {
-      printBasicBlockLabel(MBB, false, false);
+      printBasicBlockLabel(MBB, false, false, false);
       // If the arch uses custom Jump Table directives, don't calc relative to JT
       if (!TAI->getJumpTableDirective()) 
         O << '-' << TAI->getPrivateGlobalPrefix() << "JTI"
-          << getFunctionNumber() << '_' << JTI << '_' << MO2.getImmedValue();
+          << getFunctionNumber() << '_' << JTI << '_' << MO2.getImm();
     } else
-      printBasicBlockLabel(MBB, false, false);
+      printBasicBlockLabel(MBB, false, false, false);
     if (i != e-1)
       O << '\n';
   }
@@ -765,7 +786,6 @@ void ARMAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
     case ARM::tPICADD:
       break;
     default:
-      O << "\t";
       break;
     }
   }}
@@ -778,7 +798,22 @@ bool ARMAsmPrinter::doInitialization(Module &M) {
   // Emit initial debug information.
   DW.BeginModule(&M);
   
-  return AsmPrinter::doInitialization(M);
+  bool Result = AsmPrinter::doInitialization(M);
+
+  // Darwin wants symbols to be quoted if they have complex names.
+  if (Subtarget->isTargetDarwin())
+    Mang->setUseQuotes(true);
+
+  return Result;
+}
+
+/// PrintUnmangledNameSafely - Print out the printable characters in the name.
+/// Don't print things like \n or \0.
+static void PrintUnmangledNameSafely(const Value *V, std::ostream &OS) {
+  for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
+       Name != E; ++Name)
+    if (isprint(*Name))
+      OS << *Name;
 }
 
 bool ARMAsmPrinter::doFinalization(Module &M) {
@@ -803,7 +838,7 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
     std::string name = Mang->getValueName(I);
     Constant *C = I->getInitializer();
     const Type *Type = C->getType();
-    unsigned Size = TD->getTypeSize(Type);
+    unsigned Size = TD->getABITypeSize(Type);
     unsigned Align = TD->getPreferredAlignmentLog(I);
 
     const char *VisibilityDirective = NULL;
@@ -818,19 +853,18 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
     if (Subtarget->isTargetELF())
       O << "\t.type " << name << ",%object\n";
     
-    if (C->isNullValue()) {
+    if (C->isNullValue() && !I->hasSection() && !I->isThreadLocal()) {
       if (I->hasExternalLinkage()) {
         if (const char *Directive = TAI->getZeroFillDirective()) {
           O << "\t.globl\t" << name << "\n";
-          O << Directive << "__DATA__, __common, " << name << ", "
+          O << Directive << "__DATA, __common, " << name << ", "
             << Size << ", " << Align << "\n";
           continue;
         }
       }
 
-      if (!I->hasSection() &&
-          (I->hasInternalLinkage() || I->hasWeakLinkage() ||
-           I->hasLinkOnceLinkage())) {
+      if (I->hasInternalLinkage() || I->hasWeakLinkage() ||
+          I->hasLinkOnceLinkage()) {
         if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
         if (!NoZerosInBSS && TAI->getBSSSection())
           SwitchToDataSection(TAI->getBSSSection(), I);
@@ -850,7 +884,9 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
           if (TAI->getCOMMDirectiveTakesAlignment())
             O << "," << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
         }
-        O << "\t\t" << TAI->getCommentString() << " " << I->getName() << "\n";
+        O << "\t\t" << TAI->getCommentString() << " ";
+        PrintUnmangledNameSafely(I, O);
+        O << "\n";
         continue;
       }
     }
@@ -861,7 +897,7 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
       if (Subtarget->isTargetDarwin()) {
         O << "\t.globl " << name << "\n"
           << "\t.weak_definition " << name << "\n";
-        SwitchToDataSection("\t.section __DATA,__const_coal,coalesced", I);
+        SwitchToDataSection("\t.section __DATA,__datacoal_nt,coalesced", I);
       } else {
         std::string SectionName("\t.section\t.llvm.linkonce.d." +
                                 name +
@@ -892,6 +928,10 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
         std::string SectionName = ".section " + I->getSection();
         SectionName += ",\"aw\",%progbits";
         SwitchToDataSection(SectionName.c_str());
+      } else if (I->hasSection() && Subtarget->isTargetDarwin()) {
+        // Honor all section names on Darwin; ObjC uses this
+        std::string SectionName = ".section " + I->getSection();
+        SwitchToDataSection(SectionName.c_str());
       } else {
         if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection())
           SwitchToDataSection(I->isThreadLocal() ? TAI->getTLSBSSSection() :
@@ -932,8 +972,9 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
     }
 
     EmitAlignment(Align, I);
-    O << name << ":\t\t\t\t" << TAI->getCommentString() << " " << I->getName()
-      << "\n";
+    O << name << ":\t\t\t\t" << TAI->getCommentString() << " ";
+    PrintUnmangledNameSafely(I, O);
+    O << "\n";
     if (TAI->hasDotTypeDotSizeDirective())
       O << "\t.size " << name << ", " << Size << "\n";
     // If the initializer is a extern weak symbol, remember to emit the weak
@@ -963,32 +1004,45 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
       EmitAlignment(2);
       O << "\t.code\t32\n";
 
-      O << "L" << *i << "$stub:\n";
+      std::string p = *i;
+      printSuffixedName(p, "$stub");
+      O << ":\n";
       O << "\t.indirect_symbol " << *i << "\n";
-      O << "\tldr ip, L" << *i << "$slp\n";
+      O << "\tldr ip, ";
+      printSuffixedName(p, "$slp");
+      O << "\n";
       if (TM.getRelocationModel() == Reloc::PIC_) {
-        O << "L" << *i << "$scv:\n";
+        printSuffixedName(p, "$scv");
+        O << ":\n";
         O << "\tadd ip, pc, ip\n";
       }
       O << "\tldr pc, [ip, #0]\n";
-      O << "L" << *i << "$slp:\n";
-      if (TM.getRelocationModel() == Reloc::PIC_)
-        O << "\t.long\tL" << *i << "$lazy_ptr-(L" << *i << "$scv+8)\n";
-      else
-        O << "\t.long\tL" << *i << "$lazy_ptr\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";
       SwitchToDataSection(".lazy_symbol_pointer", 0);
-      O << "L" << *i << "$lazy_ptr:\n";
+      printSuffixedName(p, "$lazy_ptr");
+      O << ":\n";
       O << "\t.indirect_symbol " << *i << "\n";
       O << "\t.long\tdyld_stub_binding_helper\n";
     }
     O << "\n";
 
     // Output non-lazy-pointers for external and common global variables.
-    if (GVNonLazyPtrs.begin() != GVNonLazyPtrs.end())
+    if (!GVNonLazyPtrs.empty())
       SwitchToDataSection(".non_lazy_symbol_pointer", 0);
     for (std::set<std::string>::iterator i = GVNonLazyPtrs.begin(),
            e = GVNonLazyPtrs.end(); i != e; ++i) {
-      O << "L" << *i << "$non_lazy_ptr:\n";
+      std::string p = *i;
+      printSuffixedName(p, "$non_lazy_ptr");
+      O << ":\n";
       O << "\t.indirect_symbol " << *i << "\n";
       O << "\t.long\t0\n";
     }
@@ -1007,6 +1061,5 @@ bool ARMAsmPrinter::doFinalization(Module &M) {
     DW.EndModule();
   }
 
-  AsmPrinter::doFinalization(M);
-  return false; // success
+  return AsmPrinter::doFinalization(M);
 }