make X86ATTAsmPrinter::PrintPICBaseSymbol forward to X86MCInstLower.
[oota-llvm.git] / lib / Target / X86 / AsmPrinter / X86ATTAsmPrinter.cpp
index f8e6e8e314ddc74012c0e9c75bd1a93c6952342d..13304c0abf90bcc38d4eda29e4df8ef6a3fe531c 100644 (file)
 
 #define DEBUG_TYPE "asm-printer"
 #include "X86ATTAsmPrinter.h"
+#include "X86MCInstLower.h"
 #include "X86.h"
 #include "X86COFF.h"
 #include "X86MachineFunctionInfo.h"
 #include "X86TargetMachine.h"
-#include "X86TargetAsmInfo.h"
 #include "llvm/CallingConv.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
-#include "llvm/MDNode.h"
 #include "llvm/Type.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/Assembly/Writer.h"
 #include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCSectionMachO.h"
 #include "llvm/MC/MCStreamer.h"
-#include "llvm/CodeGen/DwarfWriter.h"
+#include "llvm/MC/MCSymbol.h"
 #include "llvm/CodeGen/MachineJumpTableInfo.h"
-#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormattedStream.h"
 #include "llvm/Support/Mangler.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetOptions.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Statistic.h"
 using namespace llvm;
 
 STATISTIC(EmittedInsts, "Number of machine instrs printed");
 
-static cl::opt<bool> NewAsmPrinter("experimental-asm-printer",
-                                   cl::Hidden);
-
 //===----------------------------------------------------------------------===//
 // Primitive Helper Functions.
 //===----------------------------------------------------------------------===//
 
 void X86ATTAsmPrinter::PrintPICBaseSymbol() const {
-  if (Subtarget->isTargetDarwin())
-    O << "\"L" << getFunctionNumber() << "$pb\"";
-  else if (Subtarget->isTargetELF())
-    O << ".Lllvm$" << getFunctionNumber() << ".$piclabel";
-  else
-    assert(0 && "Don't know how to print PIC label!\n");
-}
-
-/// 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) {
-  for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
-       Name != E; ++Name)
-    if (isprint(*Name))
-      OS << *Name;
+  // FIXME: Gross const cast hack.
+  X86ATTAsmPrinter *AP = const_cast<X86ATTAsmPrinter*>(this);
+  X86MCInstLower(OutContext, 0, *AP).GetPICBaseSymbol()->print(O, MAI);
 }
 
 static X86MachineFunctionInfo calculateFunctionInfo(const Function *F,
@@ -100,25 +86,28 @@ static X86MachineFunctionInfo calculateFunctionInfo(const Function *F,
   return Info;
 }
 
-/// decorateName - Query FunctionInfoMap and use this information for various
-/// name decoration.
-void X86ATTAsmPrinter::decorateName(std::string &Name,
-                                    const GlobalValue *GV) {
+/// DecorateCygMingName - Query FunctionInfoMap and use this information for
+/// various name decorations for Cygwin and MingW.
+void X86ATTAsmPrinter::DecorateCygMingName(SmallVectorImpl<char> &Name,
+                                           const GlobalValue *GV) {
+  assert(Subtarget->isTargetCygMing() && "This is only for cygwin and mingw");
+  
   const Function *F = dyn_cast<Function>(GV);
   if (!F) return;
-
+  
+  // Save function name for later type emission.
+  if (F->isDeclaration())
+    CygMingStubs.insert(StringRef(Name.data(), Name.size()));
+  
   // We don't want to decorate non-stdcall or non-fastcall functions right now
-  unsigned CC = F->getCallingConv();
+  CallingConv::ID CC = F->getCallingConv();
   if (CC != CallingConv::X86_StdCall && CC != CallingConv::X86_FastCall)
     return;
-
-  // Decorate names only when we're targeting Cygwin/Mingw32 targets
-  if (!Subtarget->isTargetCygMing())
-    return;
-
-  FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F);
-
+  
+  
   const X86MachineFunctionInfo *Info;
+  
+  FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F);
   if (info_item == FunctionInfoMap.end()) {
     // Calculate apropriate function info and populate map
     FunctionInfoMap[F] = calculateFunctionInfo(F, TM.getTargetData());
@@ -126,60 +115,59 @@ void X86ATTAsmPrinter::decorateName(std::string &Name,
   } else {
     Info = &info_item->second;
   }
-
+  
+  if (Info->getDecorationStyle() == None) return;
   const FunctionType *FT = F->getFunctionType();
-  switch (Info->getDecorationStyle()) {
-  case None:
-    break;
-  case StdCall:
-    // "Pure" variadic functions do not receive @0 suffix.
-    if (!FT->isVarArg() || (FT->getNumParams() == 0) ||
-        (FT->getNumParams() == 1 && F->hasStructRetAttr()))
-      Name += '@' + utostr_32(Info->getBytesToPopOnReturn());
-    break;
-  case FastCall:
-    // "Pure" variadic functions do not receive @0 suffix.
-    if (!FT->isVarArg() || (FT->getNumParams() == 0) ||
-        (FT->getNumParams() == 1 && F->hasStructRetAttr()))
-      Name += '@' + utostr_32(Info->getBytesToPopOnReturn());
 
-    if (Name[0] == '_') {
+  // "Pure" variadic functions do not receive @0 suffix.
+  if (!FT->isVarArg() || FT->getNumParams() == 0 ||
+      (FT->getNumParams() == 1 && F->hasStructRetAttr()))
+    raw_svector_ostream(Name) << '@' << Info->getBytesToPopOnReturn();
+  
+  if (Info->getDecorationStyle() == FastCall) {
+    if (Name[0] == '_')
       Name[0] = '@';
-    } else {
-      Name = '@' + Name;
-    }
-    break;
-  default:
-    assert(0 && "Unsupported DecorationStyle");
-  }
+    else
+      Name.insert(Name.begin(), '@');
+  }    
+}
+
+/// DecorateCygMingName - Query FunctionInfoMap and use this information for
+/// various name decorations for Cygwin and MingW.
+void X86ATTAsmPrinter::DecorateCygMingName(std::string &Name,
+                                           const GlobalValue *GV) {
+  SmallString<128> NameStr(Name.begin(), Name.end());
+  DecorateCygMingName(NameStr, GV);
+  Name.assign(NameStr.begin(), NameStr.end());
 }
 
 void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
   unsigned FnAlign = MF.getAlignment();
   const Function *F = MF.getFunction();
 
-  decorateName(CurrentFnName, F);
+  if (Subtarget->isTargetCygMing())
+    DecorateCygMingName(CurrentFnName, F);
+
+  OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
+  EmitAlignment(FnAlign, F);
 
-  SwitchToSection(TAI->SectionForGlobal(F));
   switch (F->getLinkage()) {
-  default: assert(0 && "Unknown linkage type!");
+  default: llvm_unreachable("Unknown linkage type!");
   case Function::InternalLinkage:  // Symbols default to internal.
   case Function::PrivateLinkage:
-    EmitAlignment(FnAlign, F);
     break;
   case Function::DLLExportLinkage:
   case Function::ExternalLinkage:
-    EmitAlignment(FnAlign, F);
     O << "\t.globl\t" << CurrentFnName << '\n';
     break;
+  case Function::LinkerPrivateLinkage:
   case Function::LinkOnceAnyLinkage:
   case Function::LinkOnceODRLinkage:
   case Function::WeakAnyLinkage:
   case Function::WeakODRLinkage:
-    EmitAlignment(FnAlign, F);
     if (Subtarget->isTargetDarwin()) {
       O << "\t.globl\t" << CurrentFnName << '\n';
-      O << TAI->getWeakDefDirective() << CurrentFnName << '\n';
+      O << MAI->getWeakDefDirective() << CurrentFnName << '\n';
     } else if (Subtarget->isTargetCygMing()) {
       O << "\t.globl\t" << CurrentFnName << "\n"
            "\t.linkonce discard\n";
@@ -201,7 +189,14 @@ void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
       << ";\t.endef\n";
   }
 
-  O << CurrentFnName << ":\n";
+  O << CurrentFnName << ':';
+  if (VerboseAsm) {
+    O.PadToColumn(MAI->getCommentColumn());
+    O << MAI->getCommentString() << ' ';
+    WriteAsOperand(O, F, /*PrintType=*/false, F->getParent());
+  }
+  O << '\n';
+
   // Add some workaround for linkonce linkage on Cygwin\MinGW
   if (Subtarget->isTargetCygMing() &&
       (F->hasLinkOnceLinkage() || F->hasWeakLinkage()))
@@ -214,7 +209,7 @@ void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
 bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   const Function *F = MF.getFunction();
   this->MF = &MF;
-  unsigned CC = F->getCallingConv();
+  CallingConv::ID CC = F->getCallingConv();
 
   SetupMachineFunction(MF);
   O << "\n\n";
@@ -228,13 +223,13 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   EmitConstantPool(MF.getConstantPool());
 
   if (F->hasDLLExportLinkage())
-    DLLExportedFns.insert(Mang->makeNameProper(F->getName(), ""));
+    DLLExportedFns.insert(Mang->getMangledName(F));
 
   // Print the 'header' of function
   emitFunctionHeader(MF);
 
   // Emit pre-function debug and/or EH information.
-  if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling())
+  if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
     DW->BeginFunction(&MF);
 
   // Print out code for the function.
@@ -246,7 +241,7 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
       // This is an entry block or a block that's only reachable via a
       // fallthrough edge. In non-VerboseAsm mode, don't print the label.
     } else {
-      printBasicBlockLabel(I, true, true, VerboseAsm);
+      EmitBasicBlockStart(I);
       O << '\n';
     }
     for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
@@ -266,261 +261,130 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
     O << "\tnop\n";
   }
 
-  if (TAI->hasDotTypeDotSizeDirective())
+  if (MAI->hasDotTypeDotSizeDirective())
     O << "\t.size\t" << CurrentFnName << ", .-" << CurrentFnName << '\n';
 
   // Emit post-function debug information.
-  if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling())
+  if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
     DW->EndFunction(&MF);
 
   // Print out jump tables referenced by the function.
   EmitJumpTableInfo(MF.getJumpTableInfo(), MF);
 
-  O.flush();
-
   // We didn't modify anything.
   return false;
 }
 
-/// print_pcrel_imm - This is used to print an immediate value that ends up
-/// being encoded as a pc-relative value.  These print slightly differently, for
-/// example, a $ is not emitted.
-void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
-  const MachineOperand &MO = MI->getOperand(OpNo);
+/// printSymbolOperand - Print a raw symbol reference operand.  This handles
+/// jump tables, constant pools, global address and external symbols, all of
+/// which print to a label with various suffixes for relocation types etc.
+void X86ATTAsmPrinter::printSymbolOperand(const MachineOperand &MO) {
   switch (MO.getType()) {
-  default: assert(0 && "Unknown pcrel immediate operand");
-  case MachineOperand::MO_Immediate:
-    O << MO.getImm();
-    return;
-  case MachineOperand::MO_MachineBasicBlock:
-    printBasicBlockLabel(MO.getMBB(), false, false, VerboseAsm);
-    return;
-      
+  default: llvm_unreachable("unknown symbol type!");
+  case MachineOperand::MO_JumpTableIndex:
+    O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
+      << MO.getIndex();
+    break;
+  case MachineOperand::MO_ConstantPoolIndex:
+    O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
+      << MO.getIndex();
+    printOffset(MO.getOffset());
+    break;
   case MachineOperand::MO_GlobalAddress: {
     const GlobalValue *GV = MO.getGlobal();
-    std::string Name = Mang->getValueName(GV);
-    decorateName(Name, GV);
     
-    bool needCloseParen = false;
-    if (Name[0] == '$') {
-      // The name begins with a dollar-sign. In order to avoid having it look
-      // like an integer immediate to the assembler, enclose it in parens.
-      O << '(';
-      needCloseParen = true;
-    }
+    const char *Suffix = "";
+    if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
+      Suffix = "$stub";
+    else if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
+             MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE ||
+             MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
+      Suffix = "$non_lazy_ptr";
     
-    if (Subtarget->isPICStyleStub()) {
-      // DARWIN/X86-32 in != static mode.
-      
-      // Link-once, declaration, or Weakly-linked global variables need
-      // non-lazily-resolved stubs
-      if (GV->isDeclaration() || GV->isWeakForLinker()) {
-        // Dynamically-resolved functions need a stub for the function.
-        if (isa<Function>(GV)) {
-          // Function stubs are no longer needed for Mac OS X 10.5 and up.
-          if (Subtarget->isTargetDarwin() && Subtarget->getDarwinVers() >= 9) {
-            O << Name;
-          } else {
-            FnStubs.insert(Name);
-            printSuffixedName(Name, "$stub");
-          }
-          assert(MO.getTargetFlags() == 0);
-        } else if (GV->hasHiddenVisibility()) {
-          if (!GV->isDeclaration() && !GV->hasCommonLinkage())
-            // Definition is not definitely in the current translation unit.
-            O << Name;
-          else {
-            HiddenGVStubs.insert(Name);
-            printSuffixedName(Name, "$non_lazy_ptr");
-            assert(MO.getTargetFlags() == 0);
-          }
-        } else {
-          GVStubs.insert(Name);
-          printSuffixedName(Name, "$non_lazy_ptr");
-          assert(MO.getTargetFlags() == 0);
-        }
-      } else {
-        O << Name;
-      }
-    } else {
-      // Handle dllimport linkage.
-      if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
-        O << "__imp_";
-      O << Name;
-      
-      // Assemble call via PLT for externally visible symbols.
-      if (MO.getTargetFlags() == X86II::MO_PLT)
-        O << "@PLT";
-        
-      
-      if (Subtarget->isTargetCygMing() && GV->isDeclaration())
-        // Save function name for later type emission
-        FnStubs.insert(Name);
-    }
-    
-    printOffset(MO.getOffset());
+    std::string Name = Mang->getMangledName(GV, Suffix, Suffix[0] != '\0');
+    if (Subtarget->isTargetCygMing())
+      DecorateCygMingName(Name, GV);
     
-    if (needCloseParen)
-      O << ')';
-    return;
-  }
-      
-  case MachineOperand::MO_ExternalSymbol: {
-    bool needCloseParen = false;
-    std::string Name(TAI->getGlobalPrefix());
-    Name += MO.getSymbolName();
-    // Print function stub suffix unless it's Mac OS X 10.5 and up.
-    if (Subtarget->isPICStyleStub() && 
-        // DARWIN/X86-32 in != static mode.
-        Subtarget->getDarwinVers() < 9) {
-      FnStubs.insert(Name);
-      printSuffixedName(Name, "$stub");
-      return;
-    }
+    // Handle dllimport linkage.
+    if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
+      Name = "__imp_" + Name;
     
-    if (Name[0] == '$') {
-      // The name begins with a dollar-sign. In order to avoid having it look
-      // like an integer immediate to the assembler, enclose it in parens.
-      O << '(';
-      needCloseParen = true;
-    }
-    
-    O << Name;
-    
-    if (MO.getTargetFlags() == X86II::MO_GOT_ABSOLUTE_ADDRESS) {
-      O << " + [.-";
-      PrintPICBaseSymbol();
-      O << ']';
+    if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
+        MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE) {
+      SmallString<128> NameStr;
+      Mang->getNameWithPrefix(NameStr, GV, true);
+      NameStr += "$non_lazy_ptr";
+      MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str());
+      MCSymbol *&StubSym = GVStubs[Sym];
+      if (StubSym == 0) {
+        NameStr.clear();
+        Mang->getNameWithPrefix(NameStr, GV, false);
+        StubSym = OutContext.GetOrCreateSymbol(NameStr.str());
+      }
+    } else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE){
+      SmallString<128> NameStr;
+      Mang->getNameWithPrefix(NameStr, GV, true);
+      NameStr += "$non_lazy_ptr";
+      MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str());
+      MCSymbol *&StubSym = HiddenGVStubs[Sym];
+      if (StubSym == 0) {
+        NameStr.clear();
+        Mang->getNameWithPrefix(NameStr, GV, false);
+        StubSym = OutContext.GetOrCreateSymbol(NameStr.str());
+      }
+    } else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
+      SmallString<128> NameStr;
+      Mang->getNameWithPrefix(NameStr, GV, true);
+      NameStr += "$stub";
+      MCSymbol *Sym = OutContext.GetOrCreateSymbol(NameStr.str());
+      MCSymbol *&StubSym = FnStubs[Sym];
+      if (StubSym == 0) {
+        NameStr.clear();
+        Mang->getNameWithPrefix(NameStr, GV, false);
+        StubSym = OutContext.GetOrCreateSymbol(NameStr.str());
+      }
     }
     
-    if (MO.getTargetFlags() == X86II::MO_PLT)
-      O << "@PLT";
-    
-    if (needCloseParen)
-      O << ')';
+    // If the name begins with a dollar-sign, enclose it in parens.  We do this
+    // to avoid having it look like an integer immediate to the assembler.
+    if (Name[0] == '$') 
+      O << '(' << Name << ')';
+    else
+      O << Name;
     
-    return;
-  }
-  }
-}
-
-void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
-                                    const char *Modifier) {
-  const MachineOperand &MO = MI->getOperand(OpNo);
-  switch (MO.getType()) {
-  default: assert(0 && "unknown operand type!");
-  case MachineOperand::MO_Register: {
-    assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
-           "Virtual registers should not make it this far!");
-    O << '%';
-    unsigned Reg = MO.getReg();
-    if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
-      MVT VT = (strcmp(Modifier+6,"64") == 0) ?
-        MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 :
-                    ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8));
-      Reg = getX86SubSuperRegister(Reg, VT);
-    }
-    O << TRI->getAsmName(Reg);
-    return;
-  }
-
-  case MachineOperand::MO_Immediate:
-    if (!Modifier || (strcmp(Modifier, "debug") && strcmp(Modifier, "mem")))
-      O << '$';
-    O << MO.getImm();
-    return;
-  case MachineOperand::MO_JumpTableIndex: {
-    bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
-    if (!isMemOp) O << '$';
-    O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
-      << MO.getIndex();
-    break;
-  }
-  case MachineOperand::MO_ConstantPoolIndex: {
-    bool isMemOp  = Modifier && !strcmp(Modifier, "mem");
-    if (!isMemOp) O << '$';
-    O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
-      << MO.getIndex();
-
     printOffset(MO.getOffset());
     break;
   }
-  case MachineOperand::MO_GlobalAddress: {
-    bool isMemOp = Modifier && !strcmp(Modifier, "mem");
-    const GlobalValue *GV = MO.getGlobal();
-    std::string Name = Mang->getValueName(GV);
-    decorateName(Name, GV);
-
-    bool needCloseParen = false;
-    if (!isMemOp)
-      O << '$';
-    else if (Name[0] == '$') {
-      // The name begins with a dollar-sign. In order to avoid having it look
-      // like an integer immediate to the assembler, enclose it in parens.
-      O << '(';
-      needCloseParen = true;
-    }
-
-    if (Subtarget->isPICStyleStub()) {
-      // DARWIN/X86-32 in != static mode.
-
-      // Link-once, declaration, or Weakly-linked global variables need
-      // non-lazily-resolved stubs
-      if (GV->isDeclaration() || GV->isWeakForLinker()) {
-        if (GV->hasHiddenVisibility()) {
-          if (!GV->isDeclaration() && !GV->hasCommonLinkage())
-            // Definition is not definitely in the current translation unit.
-            O << Name;
-          else {
-            HiddenGVStubs.insert(Name);
-            printSuffixedName(Name, "$non_lazy_ptr");
-            assert(MO.getTargetFlags() == 0);
-          }
-        } else {
-          GVStubs.insert(Name);
-          printSuffixedName(Name, "$non_lazy_ptr");
-          assert(MO.getTargetFlags() == 0);
-        }
-      } else {
-        O << Name;
+  case MachineOperand::MO_ExternalSymbol: {
+    std::string Name = Mang->makeNameProper(MO.getSymbolName());
+    if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
+      Name += "$stub";
+      MCSymbol *&StubSym = FnStubs[OutContext.GetOrCreateSymbol(Name)];
+      if (StubSym == 0) {
+        Name.erase(Name.end()-5, Name.end());
+        StubSym = OutContext.GetOrCreateSymbol(Name);
       }
-
-      if (TM.getRelocationModel() == Reloc::PIC_) {
-        O << '-';
-        PrintPICBaseSymbol();
-      }        
-    } else {
-      // Handle dllimport linkage.
-      if (MO.getTargetFlags() == X86II::MO_DLLIMPORT)
-        O << "__imp_";
-      O << Name;
     }
-
-    printOffset(MO.getOffset());
-
-    if (needCloseParen)
-      O << ')';
     
+    // If the name begins with a dollar-sign, enclose it in parens.  We do this
+    // to avoid having it look like an integer immediate to the assembler.
+    if (Name[0] == '$') 
+      O << '(' << Name << ')';
+    else
+      O << Name;
     break;
   }
-  case MachineOperand::MO_ExternalSymbol:
-    /// NOTE: MO_ExternalSymbol in a non-pcrel_imm context is *only* generated
-    /// by _GLOBAL_OFFSET_TABLE_ on X86-32.  All others are call operands, which
-    /// are pcrel_imm's.
-    assert(!Subtarget->is64Bit() && !Subtarget->isPICStyleRIPRel());
-    // These are never used as memory operands.
-    assert(Modifier == 0 || strcmp(Modifier, "mem"));
-    O << '$';
-    O << TAI->getGlobalPrefix();
-    O << MO.getSymbolName();
-    break;
   }
   
   switch (MO.getTargetFlags()) {
   default:
-    assert(0 && "Unknown target flag on GV operand");
+    llvm_unreachable("Unknown target flag on GV operand");
   case X86II::MO_NO_FLAG:    // No flag.
-  case X86II::MO_DLLIMPORT:  // Prefix, not a suffix.
+    break;
+  case X86II::MO_DARWIN_NONLAZY:
+  case X86II::MO_DLLIMPORT:
+  case X86II::MO_DARWIN_STUB:
+    // These affect the name of the symbol, not any suffix.
     break;
   case X86II::MO_GOT_ABSOLUTE_ADDRESS:
     O << " + [.-";
@@ -528,6 +392,8 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
     O << ']';
     break;      
   case X86II::MO_PIC_BASE_OFFSET:
+  case X86II::MO_DARWIN_NONLAZY_PIC_BASE:
+  case X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE:
     O << '-';
     PrintPICBaseSymbol();
     break;
@@ -539,6 +405,63 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
   case X86II::MO_GOTPCREL:  O << "@GOTPCREL";  break;
   case X86II::MO_GOT:       O << "@GOT";       break;
   case X86II::MO_GOTOFF:    O << "@GOTOFF";    break;
+  case X86II::MO_PLT:       O << "@PLT";       break;
+  }
+}
+
+/// print_pcrel_imm - This is used to print an immediate value that ends up
+/// being encoded as a pc-relative value.  These print slightly differently, for
+/// example, a $ is not emitted.
+void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
+  const MachineOperand &MO = MI->getOperand(OpNo);
+  switch (MO.getType()) {
+  default: llvm_unreachable("Unknown pcrel immediate operand");
+  case MachineOperand::MO_Immediate:
+    O << MO.getImm();
+    return;
+  case MachineOperand::MO_MachineBasicBlock:
+    GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
+    return;
+  case MachineOperand::MO_GlobalAddress:
+  case MachineOperand::MO_ExternalSymbol:
+    printSymbolOperand(MO);
+    return;
+  }
+}
+
+
+void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
+                                    const char *Modifier) {
+  const MachineOperand &MO = MI->getOperand(OpNo);
+  switch (MO.getType()) {
+  default: llvm_unreachable("unknown operand type!");
+  case MachineOperand::MO_Register: {
+    assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
+           "Virtual registers should not make it this far!");
+    O << '%';
+    unsigned Reg = MO.getReg();
+    if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
+      EVT VT = (strcmp(Modifier+6,"64") == 0) ?
+        MVT::i64 : ((strcmp(Modifier+6, "32") == 0) ? MVT::i32 :
+                    ((strcmp(Modifier+6,"16") == 0) ? MVT::i16 : MVT::i8));
+      Reg = getX86SubSuperRegister(Reg, VT);
+    }
+    O << TRI->getAsmName(Reg);
+    return;
+  }
+
+  case MachineOperand::MO_Immediate:
+    O << '$' << MO.getImm();
+    return;
+
+  case MachineOperand::MO_JumpTableIndex:
+  case MachineOperand::MO_ConstantPoolIndex:
+  case MachineOperand::MO_GlobalAddress: 
+  case MachineOperand::MO_ExternalSymbol: {
+    O << '$';
+    printSymbolOperand(MO);
+    break;
+  }
   }
 }
 
@@ -579,7 +502,7 @@ void X86ATTAsmPrinter::printLeaMemReference(const MachineInstr *MI, unsigned Op,
   } else {
     assert(DispSpec.isGlobal() || DispSpec.isCPI() ||
            DispSpec.isJTI() || DispSpec.isSymbol());
-    printOperand(MI, Op+3, "mem");
+    printSymbolOperand(MI->getOperand(Op+3));
   }
 
   if (HasParenPart) {
@@ -614,18 +537,20 @@ void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op,
 
 void X86ATTAsmPrinter::printPICJumpTableSetLabel(unsigned uid,
                                            const MachineBasicBlock *MBB) const {
-  if (!TAI->getSetDirective())
+  if (!MAI->getSetDirective())
     return;
 
   // We don't need .set machinery if we have GOT-style relocations
   if (Subtarget->isPICStyleGOT())
     return;
 
-  O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix()
+  O << MAI->getSetDirective() << ' ' << MAI->getPrivateGlobalPrefix()
     << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ',';
-  printBasicBlockLabel(MBB, false, false, false);
+  
+  GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+  
   if (Subtarget->isPICStyleRIPRel())
-    O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
+    O << '-' << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
       << '_' << uid << '\n';
   else {
     O << '-';
@@ -642,27 +567,22 @@ void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
   O << ':';
 }
 
-
 void X86ATTAsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI,
                                               const MachineBasicBlock *MBB,
-                                              unsigned uid) const
-{
+                                              unsigned uid) const {
   const char *JTEntryDirective = MJTI->getEntrySize() == 4 ?
-    TAI->getData32bitsDirective() : TAI->getData64bitsDirective();
+    MAI->getData32bitsDirective() : MAI->getData64bitsDirective();
 
   O << JTEntryDirective << ' ';
 
-  if (TM.getRelocationModel() == Reloc::PIC_) {
-    if (Subtarget->isPICStyleRIPRel() || Subtarget->isPICStyleStub()) {
-      O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
-        << '_' << uid << "_set_" << MBB->getNumber();
-    } else if (Subtarget->isPICStyleGOT()) {
-      printBasicBlockLabel(MBB, false, false, false);
-      O << "@GOTOFF";
-    } else
-      assert(0 && "Don't know how to print MBB label for this PIC mode");
+  if (Subtarget->isPICStyleRIPRel() || Subtarget->isPICStyleStubPIC()) {
+    O << MAI->getPrivateGlobalPrefix() << getFunctionNumber()
+      << '_' << uid << "_set_" << MBB->getNumber();
+  } else if (Subtarget->isPICStyleGOT()) {
+    GetMBBSymbol(MBB->getNumber())->print(O, MAI);
+    O << "@GOTOFF";
   } else
-    printBasicBlockLabel(MBB, false, false, false);
+    GetMBBSymbol(MBB->getNumber())->print(O, MAI);
 }
 
 bool X86ATTAsmPrinter::printAsmMRegister(const MachineOperand &MO, char Mode) {
@@ -699,18 +619,51 @@ bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
   if (ExtraCode && ExtraCode[0]) {
     if (ExtraCode[1] != 0) return true; // Unknown modifier.
 
+    const MachineOperand &MO = MI->getOperand(OpNo);
+    
     switch (ExtraCode[0]) {
     default: return true;  // Unknown modifier.
+    case 'a': // This is an address.  Currently only 'i' and 'r' are expected.
+      if (MO.isImm()) {
+        O << MO.getImm();
+        return false;
+      } 
+      if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol()) {
+        printSymbolOperand(MO);
+        return false;
+      }
+      if (MO.isReg()) {
+        O << '(';
+        printOperand(MI, OpNo);
+        O << ')';
+        return false;
+      }
+      return true;
+
     case 'c': // Don't print "$" before a global var name or constant.
-      printOperand(MI, OpNo, "mem");
+      if (MO.isImm())
+        O << MO.getImm();
+      else if (MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isSymbol())
+        printSymbolOperand(MO);
+      else
+        printOperand(MI, OpNo);
       return false;
+
+    case 'A': // Print '*' before a register (it must be a register)
+      if (MO.isReg()) {
+        O << '*';
+        printOperand(MI, OpNo);
+        return false;
+      }
+      return true;
+
     case 'b': // Print QImode register
     case 'h': // Print QImode high register
     case 'w': // Print HImode register
     case 'k': // Print SImode register
     case 'q': // Print DImode register
-      if (MI->getOperand(OpNo).isReg())
-        return printAsmMRegister(MI->getOperand(OpNo), ExtraCode[0]);
+      if (MO.isReg())
+        return printAsmMRegister(MO, ExtraCode[0]);
       printOperand(MI, OpNo);
       return false;
 
@@ -718,17 +671,15 @@ bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
       print_pcrel_imm(MI, OpNo);
       return false;
 
-    case 'n': { // Negate the immediate or print a '-' before the operand.
+    case 'n':  // Negate the immediate or print a '-' before the operand.
       // Note: this is a temporary solution. It should be handled target
       // independently as part of the 'MC' work.
-      const MachineOperand &MO = MI->getOperand(OpNo);
       if (MO.isImm()) {
         O << -MO.getImm();
         return false;
       }
       O << '-';
     }
-    }
   }
 
   printOperand(MI, OpNo);
@@ -760,17 +711,7 @@ bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
   return false;
 }
 
-static void lower_lea64_32mem(MCInst *MI, unsigned OpNo) {
-  // Convert registers in the addr mode according to subreg64.
-  for (unsigned i = 0; i != 4; ++i) {
-    if (!MI->getOperand(i).isReg()) continue;
-    
-    unsigned Reg = MI->getOperand(i).getReg();
-    if (Reg == 0) continue;
-    
-    MI->getOperand(i).setReg(getX86SubSuperRegister(Reg, MVT::i64));
-  }
-}
+
 
 /// printMachineInstruction -- Print out a single X86 LLVM instruction MI in
 /// AT&T syntax to the current output stream.
@@ -778,73 +719,16 @@ static void lower_lea64_32mem(MCInst *MI, unsigned OpNo) {
 void X86ATTAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   ++EmittedInsts;
 
-  if (NewAsmPrinter) {
-    if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {
-      O << "\t";
-      printInlineAsm(MI);
-      return;
-    } else if (MI->isLabel()) {
-      printLabel(MI);
-      return;
-    } else if (MI->getOpcode() == TargetInstrInfo::DECLARE) {
-      printDeclare(MI);
-      return;
-    } else if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
-      printImplicitDef(MI);
-      return;
-    }
-    
-    O << "NEW: ";
-    MCInst TmpInst;
-    
-    TmpInst.setOpcode(MI->getOpcode());
-    
-    for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
-      const MachineOperand &MO = MI->getOperand(i);
-      
-      MCOperand MCOp;
-      if (MO.isReg()) {
-        MCOp.MakeReg(MO.getReg());
-      } else if (MO.isImm()) {
-        MCOp.MakeImm(MO.getImm());
-      } else if (MO.isMBB()) {
-        MCOp.MakeMBBLabel(getFunctionNumber(), MO.getMBB()->getNumber());
-      } else {
-        assert(0 && "Unimp");
-      }
-      
-      TmpInst.addOperand(MCOp);
-    }
-    
-    switch (TmpInst.getOpcode()) {
-    case X86::LEA64_32r:
-      // Handle the 'subreg rewriting' for the lea64_32mem operand.
-      lower_lea64_32mem(&TmpInst, 1);
-      break;
-    }
-    
-    // FIXME: Convert TmpInst.
-    printInstruction(&TmpInst);
-    O << "OLD: ";
-  }
+  processDebugLoc(MI->getDebugLoc());
   
-  // Call the autogenerated instruction printer routines.
-  printInstruction(MI);
-}
-
-/// doInitialization
-bool X86ATTAsmPrinter::doInitialization(Module &M) {
-  if (NewAsmPrinter) {
-    Context = new MCContext();
-    // FIXME: Send this to "O" instead of outs().  For now, we force it to
-    // stdout to make it easy to compare.
-    Streamer = createAsmStreamer(*Context, outs());
-  }
+  printInstructionThroughMCStreamer(MI);
   
-  return AsmPrinter::doInitialization(M);
+  if (VerboseAsm && !MI->getDebugLoc().isUnknown())
+    EmitComments(*MI);
+  O << '\n';
 }
 
-void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
+void X86ATTAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
   const TargetData *TD = TM.getTargetData();
 
   if (!GVar->hasInitializer())
@@ -862,10 +746,8 @@ void X86ATTAsmPrinter::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;
   const Type *Type = C->getType();
   unsigned Size = TD->getTypeAllocSize(Type);
   unsigned Align = TD->getPreferredAlignmentLog(GVar);
@@ -875,14 +757,18 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
   if (Subtarget->isTargetELF())
     O << "\t.type\t" << name << ",@object\n";
 
-  SwitchToSection(TAI->SectionForGlobal(GVar));
+  
+  SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
+  const MCSection *TheSection =
+    getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
+  OutStreamer.SwitchSection(TheSection);
 
+  // FIXME: get this stuff from section kind flags.
   if (C->isNullValue() && !GVar->hasSection() &&
-      !(Subtarget->isTargetDarwin() &&
-        TAI->SectionKindForGlobal(GVar) == SectionKind::RODataMergeStr)) {
-    // FIXME: This seems to be pretty darwin-specific
+      // Don't put things that should go in the cstring section into "comm".
+      !TheSection->getKind().isMergeableCString()) {
     if (GVar->hasExternalLinkage()) {
-      if (const char *Directive = TAI->getZeroFillDirective()) {
+      if (const char *Directive = MAI->getZeroFillDirective()) {
         O << "\t.globl " << name << '\n';
         O << Directive << "__DATA, __common, " << name << ", "
           << Size << ", " << Align << '\n';
@@ -894,40 +780,42 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
         (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
 
-      if (TAI->getLCOMMDirective() != NULL) {
+      if (MAI->getLCOMMDirective() != NULL) {
         if (GVar->hasLocalLinkage()) {
-          O << TAI->getLCOMMDirective() << name << ',' << Size;
+          O << MAI->getLCOMMDirective() << name << ',' << Size;
           if (Subtarget->isTargetDarwin())
             O << ',' << Align;
         } else if (Subtarget->isTargetDarwin() && !GVar->hasCommonLinkage()) {
           O << "\t.globl " << name << '\n'
-            << TAI->getWeakDefDirective() << name << '\n';
+            << MAI->getWeakDefDirective() << name << '\n';
           EmitAlignment(Align, GVar);
           O << name << ":";
           if (VerboseAsm) {
-            O << "\t\t\t\t" << TAI->getCommentString() << ' ';
-            PrintUnmangledNameSafely(GVar, O);
+            O.PadToColumn(MAI->getCommentColumn());
+            O << MAI->getCommentString() << ' ';
+            WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
           }
           O << '\n';
           EmitGlobalConstant(C);
           return;
         } else {
-          O << TAI->getCOMMDirective()  << name << ',' << Size;
-          if (TAI->getCOMMDirectiveTakesAlignment())
-            O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+          O << MAI->getCOMMDirective()  << name << ',' << Size;
+          if (MAI->getCOMMDirectiveTakesAlignment())
+            O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
         }
       } else {
         if (!Subtarget->isTargetCygMing()) {
           if (GVar->hasLocalLinkage())
             O << "\t.local\t" << name << '\n';
         }
-        O << TAI->getCOMMDirective()  << name << ',' << Size;
-        if (TAI->getCOMMDirectiveTakesAlignment())
-          O << ',' << (TAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
+        O << MAI->getCOMMDirective()  << name << ',' << Size;
+        if (MAI->getCOMMDirectiveTakesAlignment())
+          O << ',' << (MAI->getAlignmentIsInBytes() ? (1 << Align) : Align);
       }
       if (VerboseAsm) {
-        O << "\t\t" << TAI->getCommentString() << ' ';
-        PrintUnmangledNameSafely(GVar, O);
+        O.PadToColumn(MAI->getCommentColumn());
+        O << MAI->getCommentString() << ' ';
+        WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
       }
       O << '\n';
       return;
@@ -940,9 +828,10 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
   case GlobalValue::LinkOnceODRLinkage:
   case GlobalValue::WeakAnyLinkage:
   case GlobalValue::WeakODRLinkage:
+  case GlobalValue::LinkerPrivateLinkage:
     if (Subtarget->isTargetDarwin()) {
       O << "\t.globl " << name << '\n'
-        << TAI->getWeakDefDirective() << name << '\n';
+        << MAI->getWeakDefDirective() << name << '\n';
     } else if (Subtarget->isTargetCygMing()) {
       O << "\t.globl\t" << name << "\n"
            "\t.linkonce same_size\n";
@@ -962,83 +851,127 @@ void X86ATTAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) {
   case GlobalValue::InternalLinkage:
      break;
   default:
-    assert(0 && "Unknown linkage type!");
+    llvm_unreachable("Unknown linkage type!");
   }
 
   EmitAlignment(Align, GVar);
   O << name << ":";
   if (VerboseAsm){
-    O << "\t\t\t\t" << TAI->getCommentString() << ' ';
-    PrintUnmangledNameSafely(GVar, O);
+    O.PadToColumn(MAI->getCommentColumn());
+    O << MAI->getCommentString() << ' ';
+    WriteAsOperand(O, GVar, /*PrintType=*/false, GVar->getParent());
   }
   O << '\n';
-  if (TAI->hasDotTypeDotSizeDirective())
-    O << "\t.size\t" << name << ", " << Size << '\n';
 
   EmitGlobalConstant(C);
+
+  if (MAI->hasDotTypeDotSizeDirective())
+    O << "\t.size\t" << name << ", " << Size << '\n';
+}
+
+static int SortSymbolPair(const void *LHS, const void *RHS) {
+  MCSymbol *LHSS = ((const std::pair<MCSymbol*, MCSymbol*>*)LHS)->first;
+  MCSymbol *RHSS = ((const std::pair<MCSymbol*, MCSymbol*>*)RHS)->first;
+  return LHSS->getName().compare(RHSS->getName());
+}
+
+/// GetSortedStubs - Return the entries from a DenseMap in a deterministic
+/// sorted orer.
+static std::vector<std::pair<MCSymbol*, MCSymbol*> >
+GetSortedStubs(const DenseMap<MCSymbol*, MCSymbol*> &Map) {
+  assert(!Map.empty());
+  std::vector<std::pair<MCSymbol*, MCSymbol*> > List(Map.begin(), Map.end());
+  qsort(&List[0], List.size(), sizeof(List[0]), SortSymbolPair);
+  return List;
 }
 
 bool X86ATTAsmPrinter::doFinalization(Module &M) {
   // Print out module-level global variables here.
   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
        I != E; ++I) {
-    printModuleLevelGV(I);
-
     if (I->hasDLLExportLinkage())
-      DLLExportedGVs.insert(Mang->makeNameProper(I->getName(),""));
+      DLLExportedGVs.insert(Mang->getMangledName(I));
   }
 
   if (Subtarget->isTargetDarwin()) {
-    SwitchToDataSection("");
+    // All darwin targets use mach-o.
+    TargetLoweringObjectFileMachO &TLOFMacho = 
+      static_cast<TargetLoweringObjectFileMachO &>(getObjFileLowering());
     
     // Add the (possibly multiple) personalities to the set of global value
     // stubs.  Only referenced functions get into the Personalities list.
-    if (TAI->doesSupportExceptionHandling() && MMI && !Subtarget->is64Bit()) {
+    if (MAI->doesSupportExceptionHandling() && MMI && !Subtarget->is64Bit()) {
       const std::vector<Function*> &Personalities = MMI->getPersonalities();
       for (unsigned i = 0, e = Personalities.size(); i != e; ++i) {
         if (Personalities[i] == 0)
           continue;
-        std::string Name = Mang->getValueName(Personalities[i]);
-        decorateName(Name, Personalities[i]);
-        GVStubs.insert(Name);
+        
+        SmallString<128> Name;
+        Mang->getNameWithPrefix(Name, Personalities[i], true /*private label*/);
+        Name += "$non_lazy_ptr";
+        MCSymbol *NLPName = OutContext.GetOrCreateSymbol(Name.str());
+
+        MCSymbol *&StubName = GVStubs[NLPName];
+        if (StubName != 0) continue;
+        
+
+        Name.clear();
+        Mang->getNameWithPrefix(Name, Personalities[i], false);
+        StubName = OutContext.GetOrCreateSymbol(Name.str());
       }
     }
 
     // Output stubs for dynamically-linked functions
     if (!FnStubs.empty()) {
-      for (StringSet<>::iterator I = FnStubs.begin(), E = FnStubs.end();
-           I != E; ++I) {
-        SwitchToDataSection("\t.section __IMPORT,__jump_table,symbol_stubs,"
-                            "self_modifying_code+pure_instructions,5", 0);
-        const char *Name = I->getKeyData();
-        printSuffixedName(Name, "$stub");
-        O << ":\n"
-             "\t.indirect_symbol " << Name << "\n"
-             "\thlt ; hlt ; hlt ; hlt ; hlt\n";
+      const MCSection *TheSection = 
+        TLOFMacho.getMachOSection("__IMPORT", "__jump_table",
+                                  MCSectionMachO::S_SYMBOL_STUBS |
+                                  MCSectionMachO::S_ATTR_SELF_MODIFYING_CODE |
+                                  MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+                                  5, SectionKind::getMetadata());
+      OutStreamer.SwitchSection(TheSection);
+
+      std::vector<std::pair<MCSymbol*, MCSymbol*> > Stubs
+        = GetSortedStubs(FnStubs);
+      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
+        Stubs[i].first->print(O, MAI);
+        O << ":\n" << "\t.indirect_symbol ";
+        // Get the MCSymbol without the $stub suffix.
+        Stubs[i].second->print(O, MAI);
+        O << "\n\thlt ; hlt ; hlt ; hlt ; hlt\n";
       }
       O << '\n';
     }
 
     // Output stubs for external and common global variables.
     if (!GVStubs.empty()) {
-      SwitchToDataSection(
-                    "\t.section __IMPORT,__pointers,non_lazy_symbol_pointers");
-      for (StringSet<>::iterator I = GVStubs.begin(), E = GVStubs.end();
-           I != E; ++I) {
-        const char *Name = I->getKeyData();
-        printSuffixedName(Name, "$non_lazy_ptr");
-        O << ":\n\t.indirect_symbol " << Name << "\n\t.long\t0\n";
+      const MCSection *TheSection = 
+        TLOFMacho.getMachOSection("__IMPORT", "__pointers",
+                                  MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
+                                  SectionKind::getMetadata());
+      OutStreamer.SwitchSection(TheSection);
+
+      std::vector<std::pair<MCSymbol*, MCSymbol*> > Stubs
+        = GetSortedStubs(GVStubs);
+      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
+        Stubs[i].first->print(O, MAI);
+        O << ":\n\t.indirect_symbol ";
+        Stubs[i].second->print(O, MAI);
+        O << "\n\t.long\t0\n";
       }
     }
 
     if (!HiddenGVStubs.empty()) {
-      SwitchToSection(TAI->getDataSection());
+      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
       EmitAlignment(2);
-      for (StringSet<>::iterator I = HiddenGVStubs.begin(),
-           E = HiddenGVStubs.end(); I != E; ++I) {
-        const char *Name = I->getKeyData();
-        printSuffixedName(Name, "$non_lazy_ptr");
-        O << ":\n" << TAI->getData32bitsDirective() << Name << '\n';
+
+      std::vector<std::pair<MCSymbol*, MCSymbol*> > Stubs
+        = GetSortedStubs(HiddenGVStubs);
+      for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
+        Stubs[i].first->print(O, MAI);
+        O << ":\n" << MAI->getData32bitsDirective();
+        Stubs[i].second->print(O, MAI);
+        O << '\n';
       }
     }
 
@@ -1050,7 +983,7 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
     O << "\t.subsections_via_symbols\n";
   } else if (Subtarget->isTargetCygMing()) {
     // Emit type information for external functions
-    for (StringSet<>::iterator i = FnStubs.begin(), e = FnStubs.end();
+    for (StringSet<>::iterator i = CygMingStubs.begin(), e = CygMingStubs.end();
          i != e; ++i) {
       O << "\t.def\t " << i->getKeyData()
         << ";\t.scl\t" << COFF::C_EXT
@@ -1061,16 +994,17 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
   
   
   // Output linker support code for dllexported globals on windows.
-  if (!DLLExportedGVs.empty()) {
-    SwitchToDataSection(".section .drectve");
+  if (!DLLExportedGVs.empty() || !DLLExportedFns.empty()) {
+    // dllexport symbols only exist on coff targets.
+    TargetLoweringObjectFileCOFF &TLOFMacho = 
+      static_cast<TargetLoweringObjectFileCOFF&>(getObjFileLowering());
+    
+    OutStreamer.SwitchSection(TLOFMacho.getCOFFSection(".section .drectve",true,
+                                                 SectionKind::getMetadata()));
   
     for (StringSet<>::iterator i = DLLExportedGVs.begin(),
          e = DLLExportedGVs.end(); i != e; ++i)
       O << "\t.ascii \" -export:" << i->getKeyData() << ",data\"\n";
-  }
-  
-  if (!DLLExportedFns.empty()) {
-    SwitchToDataSection(".section .drectve");
   
     for (StringSet<>::iterator i = DLLExportedFns.begin(),
          e = DLLExportedFns.end();
@@ -1079,19 +1013,6 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
   }
   
   // Do common shutdown.
-  bool Changed = AsmPrinter::doFinalization(M);
-  
-  if (NewAsmPrinter) {
-    Streamer->Finish();
-    
-    delete Streamer;
-    delete Context;
-    Streamer = 0;
-    Context = 0;
-  }
-  
-  return Changed;
+  return AsmPrinter::doFinalization(M);
 }
 
-// Include the auto-generated portion of the assembly writer.
-#include "X86GenAsmWriter.inc"