Revert 49006 for the moment.
[oota-llvm.git] / lib / Target / PowerPC / PPCAsmPrinter.cpp
index 7126af286782e0ca6c3dc5841a2ca984f518472f..2537d67ddaadf82858daa5bb3a1d8e819d7b401e 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Target/TargetAsmInfo.h"
-#include "llvm/Target/MRegisterInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/ADT/Statistic.h"
@@ -104,7 +105,7 @@ namespace {
     ///
     void printRegister(const MachineOperand &MO, bool R0AsZero) {
       unsigned RegNo = MO.getReg();
-      assert(MRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??");
+      assert(TargetRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??");
       
       // If we should use 0 for R0.
       if (R0AsZero && RegNo == PPC::R0) {
@@ -112,7 +113,7 @@ namespace {
         return;
       }
       
-      const char *RegName = TM.getRegisterInfo()->get(RegNo).Name;
+      const char *RegName = TM.getRegisterInfo()->get(RegNo).AsmName;
       // Linux assembler (Others?) does not take register mnemonics.
       // FIXME - What about special registers used in mfspr/mtspr?
       if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
@@ -124,7 +125,7 @@ namespace {
       if (MO.isRegister()) {
         printRegister(MO, false);
       } else if (MO.isImmediate()) {
-        O << MO.getImmedValue();
+        O << MO.getImm();
       } else {
         printOp(MO);
       }
@@ -137,29 +138,29 @@ namespace {
     
     
     void printS5ImmOperand(const MachineInstr *MI, unsigned OpNo) {
-      char value = MI->getOperand(OpNo).getImmedValue();
+      char value = MI->getOperand(OpNo).getImm();
       value = (value << (32-5)) >> (32-5);
       O << (int)value;
     }
     void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo) {
-      unsigned char value = MI->getOperand(OpNo).getImmedValue();
+      unsigned char value = MI->getOperand(OpNo).getImm();
       assert(value <= 31 && "Invalid u5imm argument!");
       O << (unsigned int)value;
     }
     void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo) {
-      unsigned char value = MI->getOperand(OpNo).getImmedValue();
+      unsigned char value = MI->getOperand(OpNo).getImm();
       assert(value <= 63 && "Invalid u6imm argument!");
       O << (unsigned int)value;
     }
     void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo) {
-      O << (short)MI->getOperand(OpNo).getImmedValue();
+      O << (short)MI->getOperand(OpNo).getImm();
     }
     void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo) {
-      O << (unsigned short)MI->getOperand(OpNo).getImmedValue();
+      O << (unsigned short)MI->getOperand(OpNo).getImm();
     }
     void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo) {
       if (MI->getOperand(OpNo).isImmediate()) {
-        O << (short)(MI->getOperand(OpNo).getImmedValue()*4);
+        O << (short)(MI->getOperand(OpNo).getImm()*4);
       } else {
         O << "lo16(";
         printOp(MI->getOperand(OpNo));
@@ -173,7 +174,7 @@ namespace {
       // Branches can take an immediate operand.  This is used by the branch
       // selection pass to print $+8, an eight byte displacement from the PC.
       if (MI->getOperand(OpNo).isImmediate()) {
-        O << "$+" << MI->getOperand(OpNo).getImmedValue()*4;
+        O << "$+" << MI->getOperand(OpNo).getImm()*4;
       } else {
         printOp(MI->getOperand(OpNo));
       }
@@ -183,7 +184,7 @@ namespace {
       if (TM.getRelocationModel() != Reloc::Static) {
         if (MO.getType() == MachineOperand::MO_GlobalAddress) {
           GlobalValue *GV = MO.getGlobal();
-          if (((GV->isExternal() || GV->hasWeakLinkage() ||
+          if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
                 GV->hasLinkOnceLinkage()))) {
             // Dynamically-resolved functions need a stub for the function.
             std::string Name = Mang->getValueName(GV);
@@ -205,7 +206,7 @@ namespace {
       printOp(MI->getOperand(OpNo));
     }
     void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo) {
-     O << (int)MI->getOperand(OpNo).getImmedValue()*4;
+     O << (int)MI->getOperand(OpNo).getImm()*4;
     }
     void printPICLabel(const MachineInstr *MI, unsigned OpNo) {
       O << "\"L" << getFunctionNumber() << "$pb\"\n";
@@ -215,24 +216,28 @@ namespace {
       if (MI->getOperand(OpNo).isImmediate()) {
         printS16ImmOperand(MI, OpNo);
       } else {
-        O << "ha16(";
+        if (Subtarget.isDarwin()) O << "ha16(";
         printOp(MI->getOperand(OpNo));
         if (TM.getRelocationModel() == Reloc::PIC_)
-          O << "-\"L" << getFunctionNumber() << "$pb\")";
-        else
+          O << "-\"L" << getFunctionNumber() << "$pb\"";
+        if (Subtarget.isDarwin())
           O << ')';
+        else
+          O << "@ha";
       }
     }
     void printSymbolLo(const MachineInstr *MI, unsigned OpNo) {
       if (MI->getOperand(OpNo).isImmediate()) {
         printS16ImmOperand(MI, OpNo);
       } else {
-        O << "lo16(";
+        if (Subtarget.isDarwin()) O << "lo16(";
         printOp(MI->getOperand(OpNo));
         if (TM.getRelocationModel() == Reloc::PIC_)
-          O << "-\"L" << getFunctionNumber() << "$pb\")";
-        else
+          O << "-\"L" << getFunctionNumber() << "$pb\"";
+        if (Subtarget.isDarwin())
           O << ')';
+        else
+          O << "@l";
       }
     }
     void printcrbitm(const MachineInstr *MI, unsigned OpNo) {
@@ -280,6 +285,8 @@ namespace {
     
     virtual bool runOnMachineFunction(MachineFunction &F) = 0;
     virtual bool doFinalization(Module &M) = 0;
+
+    virtual void EmitExternalGlobal(const GlobalVariable *GV);
   };
 
   /// LinuxAsmPrinter - PowerPC assembly printer, customized for Linux
@@ -316,10 +323,11 @@ namespace {
   struct VISIBILITY_HIDDEN DarwinAsmPrinter : public PPCAsmPrinter {
   
     DwarfWriter DW;
+    MachineModuleInfo *MMI;
 
     DarwinAsmPrinter(std::ostream &O, PPCTargetMachine &TM,
                      const TargetAsmInfo *T)
-      : PPCAsmPrinter(O, TM, T), DW(O, this, T) {
+      : PPCAsmPrinter(O, TM, T), DW(O, this, T), MMI(0) {
     }
 
     virtual const char *getPassName() const {
@@ -353,16 +361,16 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
     return;
 
   case MachineOperand::MO_MachineBasicBlock:
-    printBasicBlockLabel(MO.getMachineBasicBlock());
+    printBasicBlockLabel(MO.getMBB());
     return;
   case MachineOperand::MO_JumpTableIndex:
     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
-      << '_' << MO.getJumpTableIndex();
+      << '_' << MO.getIndex();
     // FIXME: PIC relocation model
     return;
   case MachineOperand::MO_ConstantPoolIndex:
     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
-      << '_' << MO.getConstantPoolIndex();
+      << '_' << MO.getIndex();
     return;
   case MachineOperand::MO_ExternalSymbol:
     // Computing the address of an external symbol, not calling it.
@@ -381,7 +389,7 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
 
     // External or weakly linked global variables need non-lazily-resolved stubs
     if (TM.getRelocationModel() != Reloc::Static) {
-      if (((GV->isExternal() || GV->hasWeakLinkage() ||
+      if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
             GV->hasLinkOnceLinkage()))) {
         GVStubs.insert(Name);
         O << "L" << Name << "$non_lazy_ptr";
@@ -390,6 +398,11 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
     }
     O << Name;
     
+    if (MO.getOffset() > 0)
+      O << "+" << MO.getOffset();
+    else if (MO.getOffset() < 0)
+      O << MO.getOffset();
+    
     if (GV->hasExternalWeakLinkage())
       ExtWeakSymbols.insert(GV);
     return;
@@ -401,6 +414,18 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
   }
 }
 
+/// EmitExternalGlobal - In this case we need to use the indirect symbol.
+///
+void PPCAsmPrinter::EmitExternalGlobal(const GlobalVariable *GV) {
+  std::string Name = getGlobalLinkName(GV);
+  if (TM.getRelocationModel() != Reloc::Static) {
+    GVStubs.insert(Name);
+    O << "L" << Name << "$non_lazy_ptr";
+    return;
+  }
+  O << Name;
+}
+
 /// PrintAsmOperand - Print out an operand for an inline asm expression.
 ///
 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
@@ -424,6 +449,12 @@ bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
         return true;
       ++OpNo;   // Return the high-part.
       break;
+    case 'I':
+      // Write 'i' if an integer constant, otherwise nothing.  Used to print
+      // addi vs add, etc.
+      if (MI->getOperand(OpNo).isImmediate())
+        O << "i";
+      return false;
     }
   }
   
@@ -436,7 +467,10 @@ bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
                                           const char *ExtraCode) {
   if (ExtraCode && ExtraCode[0])
     return true; // Unknown modifier.
-  printMemRegReg(MI, OpNo);
+  if (MI->getOperand(OpNo).isRegister())
+    printMemRegReg(MI, OpNo);
+  else
+    printMemRegImm(MI, OpNo);
   return false;
 }
 
@@ -476,14 +510,14 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   // Check for slwi/srwi mnemonics.
   if (MI->getOpcode() == PPC::RLWINM) {
     bool FoundMnemonic = false;
-    unsigned char SH = MI->getOperand(2).getImmedValue();
-    unsigned char MB = MI->getOperand(3).getImmedValue();
-    unsigned char ME = MI->getOperand(4).getImmedValue();
+    unsigned char SH = MI->getOperand(2).getImm();
+    unsigned char MB = MI->getOperand(3).getImm();
+    unsigned char ME = MI->getOperand(4).getImm();
     if (SH <= 31 && MB == 0 && ME == (31-SH)) {
-      O << "slwi "; FoundMnemonic = true;
+      O << "\tslwi "; FoundMnemonic = true;
     }
     if (SH <= 31 && MB == (32-SH) && ME == 31) {
-      O << "srwi "; FoundMnemonic = true;
+      O << "\tsrwi "; FoundMnemonic = true;
       SH = 32-SH;
     }
     if (FoundMnemonic) {
@@ -495,7 +529,7 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
     }
   } else if (MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) {
     if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
-      O << "mr ";
+      O << "\tmr ";
       printOperand(MI, 0);
       O << ", ";
       printOperand(MI, 1);
@@ -503,11 +537,11 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
       return;
     }
   } else if (MI->getOpcode() == PPC::RLDICR) {
-    unsigned char SH = MI->getOperand(2).getImmedValue();
-    unsigned char ME = MI->getOperand(3).getImmedValue();
+    unsigned char SH = MI->getOperand(2).getImm();
+    unsigned char ME = MI->getOperand(3).getImm();
     // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
     if (63-SH == ME) {
-      O << "sldi ";
+      O << "\tsldi ";
       printOperand(MI, 0);
       O << ", ";
       printOperand(MI, 1);
@@ -570,13 +604,12 @@ bool LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
        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();
          II != E; ++II) {
       // Print the assembly for the instruction.
-      O << "\t";
       printMachineInstruction(II);
     }
   }
@@ -594,7 +627,7 @@ bool LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 }
 
 bool LinuxAsmPrinter::doInitialization(Module &M) {
-  AsmPrinter::doInitialization(M);
+  bool Result = AsmPrinter::doInitialization(M);
   
   // GNU as handles section names wrapped in quotes
   Mang->setUseQuotes(true);
@@ -603,7 +636,16 @@ bool LinuxAsmPrinter::doInitialization(Module &M) {
   
   // Emit initial debug information.
   DW.BeginModule(&M);
-  return false;
+  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 LinuxAsmPrinter::doFinalization(Module &M) {
@@ -625,19 +667,21 @@ bool LinuxAsmPrinter::doFinalization(Module &M) {
         O << Directive << name << "\n";
     
     Constant *C = I->getInitializer();
-    unsigned Size = TD->getTypeSize(C->getType());
+    unsigned Size = TD->getABITypeSize(C->getType());
     unsigned Align = TD->getPreferredAlignmentLog(I);
 
     if (C->isNullValue() && /* FIXME: Verify correct */
+        !I->hasSection() &&
         (I->hasInternalLinkage() || I->hasWeakLinkage() ||
-         I->hasLinkOnceLinkage() ||
-         (I->hasExternalLinkage() && !I->hasSection()))) {
+         I->hasLinkOnceLinkage() || I->hasExternalLinkage())) {
       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
       if (I->hasExternalLinkage()) {
         O << "\t.global " << name << '\n';
         O << "\t.type " << name << ", @object\n";
-        //O << "\t.zerofill __DATA, __common, " << name << ", "
-        //  << Size << ", " << Align;
+        if (TAI->getBSSSection())
+          SwitchToDataSection(TAI->getBSSSection(), I);
+        O << name << ":\n";
+        O << "\t.zero " << Size << "\n";
       } else if (I->hasInternalLinkage()) {
         SwitchToDataSection("\t.data", I);
         O << TAI->getLCOMMDirective() << name << "," << Size;
@@ -645,7 +689,9 @@ bool LinuxAsmPrinter::doFinalization(Module &M) {
         SwitchToDataSection("\t.data", I);
         O << ".comm " << name << "," << Size;
       }
-      O << "\t\t" << TAI->getCommentString() << " '" << I->getName() << "'\n";
+      O << "\t\t" << TAI->getCommentString() << " '";
+      PrintUnmangledNameSafely(I, O);
+      O << "'\n";
     } else {
       switch (I->getLinkage()) {
       case GlobalValue::LinkOnceLinkage:
@@ -680,7 +726,10 @@ bool LinuxAsmPrinter::doFinalization(Module &M) {
                                                 + ",\"aw\",@progbits";
           SwitchToDataSection(SectionName.c_str());
         } else {
-          SwitchToDataSection(TAI->getDataSection(), I);
+          if (I->isConstant() && TAI->getReadOnlySection())
+            SwitchToDataSection(TAI->getReadOnlySection(), I);
+          else
+            SwitchToDataSection(TAI->getDataSection(), I);
         }
         break;
       default:
@@ -689,8 +738,9 @@ bool LinuxAsmPrinter::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 the initializer is a extern weak symbol, remember to emit the weak
       // reference!
@@ -708,8 +758,7 @@ bool LinuxAsmPrinter::doFinalization(Module &M) {
   // Emit initial debug information.
   DW.EndModule();
 
-  AsmPrinter::doFinalization(M);
-  return false; // success
+  return AsmPrinter::doFinalization(M);
 }
 
 std::string LinuxAsmPrinter::getSectionForFunction(const Function &F) const {
@@ -730,7 +779,7 @@ std::string DarwinAsmPrinter::getSectionForFunction(const Function &F) const {
   case Function::InternalLinkage: return TAI->getTextSection();
   case Function::WeakLinkage:
   case Function::LinkOnceLinkage:
-    return ".section __TEXT,__textcoal_nt,coalesced,pure_instructions";
+    return "\t.section __TEXT,__textcoal_nt,coalesced,pure_instructions";
   }
 }
 
@@ -738,11 +787,13 @@ std::string DarwinAsmPrinter::getSectionForFunction(const Function &F) const {
 /// method to print assembly for each instruction.
 ///
 bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
-  DW.SetModuleInfo(&getAnalysis<MachineModuleInfo>());
+  // We need this for Personality functions.
+  MMI = &getAnalysis<MachineModuleInfo>();
+  DW.SetModuleInfo(MMI);
 
   SetupMachineFunction(MF);
   O << "\n\n";
-  
+
   // Print out constants referenced by the function
   EmitConstantPool(MF.getConstantPool());
 
@@ -768,24 +819,31 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
     if (const char *Directive = TAI->getHiddenDirective())
       O << Directive << CurrentFnName << "\n";
   
-  EmitAlignment(4, F);
+  EmitAlignment(OptimizeForSize ? 2 : 4, F);
   O << CurrentFnName << ":\n";
 
   // Emit pre-function debug information.
   DW.BeginFunction(&MF);
 
+  // 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();
-         II != E; ++II) {
+    for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
+         II != IE; ++II) {
       // Print the assembly for the instruction.
-      O << "\t";
       printMachineInstruction(II);
     }
   }
@@ -802,7 +860,8 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
 
 bool DarwinAsmPrinter::doInitialization(Module &M) {
-  static const char *CPUDirectives[] = {
+  static const char *const CPUDirectives[] = {
+    "",
     "ppc",
     "ppc601",
     "ppc602",
@@ -823,27 +882,27 @@ bool DarwinAsmPrinter::doInitialization(Module &M) {
   assert(Directive <= PPC::DIR_64 && "Directive out of range.");
   O << "\t.machine " << CPUDirectives[Directive] << "\n";
      
-  AsmPrinter::doInitialization(M);
+  bool Result = AsmPrinter::doInitialization(M);
   
   // Darwin wants symbols to be quoted if they have complex names.
   Mang->setUseQuotes(true);
   
   // Prime text sections so they are adjacent.  This reduces the likelihood a
   // large data or debug section causes a branch to exceed 16M limit.
-  SwitchToTextSection(".section __TEXT,__textcoal_nt,coalesced,"
+  SwitchToTextSection("\t.section __TEXT,__textcoal_nt,coalesced,"
                       "pure_instructions");
   if (TM.getRelocationModel() == Reloc::PIC_) {
-    SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs,"
+    SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs,"
                           "pure_instructions,32");
   } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
-    SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs,"
+    SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs,"
                         "pure_instructions,16");
   }
   SwitchToTextSection(TAI->getTextSection());
   
   // Emit initial debug information.
   DW.BeginModule(&M);
-  return false;
+  return Result;
 }
 
 bool DarwinAsmPrinter::doFinalization(Module &M) {
@@ -872,13 +931,14 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
         O << Directive << name << "\n";
     
     Constant *C = I->getInitializer();
-    unsigned Size = TD->getTypeSize(C->getType());
+    const Type *Type = C->getType();
+    unsigned Size = TD->getABITypeSize(Type);
     unsigned Align = TD->getPreferredAlignmentLog(I);
 
     if (C->isNullValue() && /* FIXME: Verify correct */
+        !I->hasSection() &&
         (I->hasInternalLinkage() || I->hasWeakLinkage() ||
-         I->hasLinkOnceLinkage() ||
-         (I->hasExternalLinkage() && !I->hasSection()))) {
+         I->hasLinkOnceLinkage() || I->hasExternalLinkage())) {
       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
       if (I->hasExternalLinkage()) {
         O << "\t.globl " << name << '\n';
@@ -890,15 +950,20 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
       } else {
         SwitchToDataSection("\t.data", I);
         O << ".comm " << name << "," << Size;
+        // Darwin 9 and above support aligned common data.
+        if (Subtarget.isDarwin9())
+          O << "," << Align;
       }
-      O << "\t\t" << TAI->getCommentString() << " '" << I->getName() << "'\n";
+      O << "\t\t" << TAI->getCommentString() << " '";
+      PrintUnmangledNameSafely(I, O);
+      O << "'\n";
     } else {
       switch (I->getLinkage()) {
       case GlobalValue::LinkOnceLinkage:
       case GlobalValue::WeakLinkage:
         O << "\t.globl " << name << '\n'
           << "\t.weak_definition " << name << '\n';
-        SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I);
+        SwitchToDataSection("\t.section __DATA,__datacoal_nt,coalesced", I);
         break;
       case GlobalValue::AppendingLinkage:
         // FIXME: appending linkage variables should go into a section of
@@ -915,8 +980,32 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
             break;
           }
         }
-
-        SwitchToDataSection("\t.data", I);
+        if (I->hasSection()) {
+          // Honor all section names on Darwin; ObjC uses this
+          std::string SectionName = ".section " + I->getSection();
+          SwitchToDataSection(SectionName.c_str());
+        } else if (!I->isConstant())
+          SwitchToDataSection(TAI->getDataSection(), I);
+        else {
+          // Read-only data.
+          bool HasReloc = C->ContainsRelocations();
+          if (HasReloc &&
+              TM.getRelocationModel() != Reloc::Static)
+            SwitchToDataSection("\t.const_data\n");
+          else if (!HasReloc && Size == 4 &&
+                   TAI->getFourByteConstantSection())
+            SwitchToDataSection(TAI->getFourByteConstantSection(), I);
+          else if (!HasReloc && Size == 8 &&
+                   TAI->getEightByteConstantSection())
+            SwitchToDataSection(TAI->getEightByteConstantSection(), I);
+          else if (!HasReloc && Size == 16 &&
+                   TAI->getSixteenByteConstantSection())
+            SwitchToDataSection(TAI->getSixteenByteConstantSection(), I);
+          else if (TAI->getReadOnlySection())
+            SwitchToDataSection(TAI->getReadOnlySection(), I);
+          else
+            SwitchToDataSection(TAI->getDataSection(), I);
+        }
         break;
       default:
         cerr << "Unknown linkage type!";
@@ -924,8 +1013,9 @@ bool DarwinAsmPrinter::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 the initializer is a extern weak symbol, remember to emit the weak
       // reference!
@@ -944,7 +1034,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
   if (TM.getRelocationModel() == Reloc::PIC_) {
     for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
          i != e; ++i) {
-      SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs,"
+      SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs,"
                           "pure_instructions,32");
       EmitAlignment(4);
       O << "L" << *i << "$stub:\n";
@@ -972,7 +1062,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
   } else {
     for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
          i != e; ++i) {
-      SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs,"
+      SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs,"
                           "pure_instructions,16");
       EmitAlignment(4);
       O << "L" << *i << "$stub:\n";
@@ -996,8 +1086,17 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
 
   O << "\n";
 
+  if (ExceptionHandling && TAI->doesSupportExceptionHandling() && MMI) {
+    // Add the (possibly multiple) personalities to the set of global values.
+    const std::vector<Function *>& Personalities = MMI->getPersonalities();
+
+    for (std::vector<Function *>::const_iterator I = Personalities.begin(),
+           E = Personalities.end(); I != E; ++I)
+      if (*I) GVStubs.insert("_" + (*I)->getName());
+  }
+
   // Output stubs for external and common global variables.
-  if (GVStubs.begin() != GVStubs.end()) {
+  if (!GVStubs.empty()) {
     SwitchToDataSection(".non_lazy_symbol_pointer");
     for (std::set<std::string>::iterator I = GVStubs.begin(),
          E = GVStubs.end(); I != E; ++I) {
@@ -1021,8 +1120,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
   // code that does this, it is always safe to set.
   O << "\t.subsections_via_symbols\n";
 
-  AsmPrinter::doFinalization(M);
-  return false; // success
+  return AsmPrinter::doFinalization(M);
 }