make X86ATTAsmPrinter::PrintPICBaseSymbol forward to X86MCInstLower.
[oota-llvm.git] / lib / Target / X86 / AsmPrinter / X86ATTAsmPrinter.cpp
index 0be7f351d7b9523e004eb828d61f5032183bf8ef..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/Metadata.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/MCSection.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/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
-    llvm_unreachable("Don't know how to print PIC label!");
-}
-
-/// PrintUnmangledNameSafely - Print out the printable characters in the name.
-/// Don't print things like \\n or \\0.
-static void PrintUnmangledNameSafely(const Value *V, 
-                                     formatted_raw_ostream &OS) {
-  for (StringRef::iterator it = V->getName().begin(), 
-         ie = V->getName().end(); it != ie; ++it)
-    if (isprint(*it))
-      OS << *it;
+  // 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,
@@ -106,23 +88,23 @@ static X86MachineFunctionInfo calculateFunctionInfo(const Function *F,
 
 /// DecorateCygMingName - Query FunctionInfoMap and use this information for
 /// various name decorations for Cygwin and MingW.
-void X86ATTAsmPrinter::DecorateCygMingName(std::string &Name,
+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(Name);
+    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;
-
-
+  
+  
   const X86MachineFunctionInfo *Info;
   
   FMFInfoMap::const_iterator info_item = FunctionInfoMap.find(F);
@@ -133,32 +115,30 @@ void X86ATTAsmPrinter::DecorateCygMingName(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:
-    llvm_unreachable("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) {
@@ -168,27 +148,26 @@ void X86ATTAsmPrinter::emitFunctionHeader(const MachineFunction &MF) {
   if (Subtarget->isTargetCygMing())
     DecorateCygMingName(CurrentFnName, F);
 
-  SwitchToSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
+  OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
+  EmitAlignment(FnAlign, F);
+
   switch (F->getLinkage()) {
   default: llvm_unreachable("Unknown linkage type!");
   case Function::InternalLinkage:  // Symbols default to internal.
   case Function::PrivateLinkage:
-  case Function::LinkerPrivateLinkage:
-    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";
@@ -210,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()))
@@ -223,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";
@@ -243,7 +229,7 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   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.
@@ -255,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();
@@ -275,18 +261,16 @@ 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;
 }
@@ -298,11 +282,11 @@ void X86ATTAsmPrinter::printSymbolOperand(const MachineOperand &MO) {
   switch (MO.getType()) {
   default: llvm_unreachable("unknown symbol type!");
   case MachineOperand::MO_JumpTableIndex:
-    O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
+    O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_'
       << MO.getIndex();
     break;
   case MachineOperand::MO_ConstantPoolIndex:
-    O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
+    O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
       << MO.getIndex();
     printOffset(MO.getOffset());
     break;
@@ -314,7 +298,6 @@ void X86ATTAsmPrinter::printSymbolOperand(const MachineOperand &MO) {
       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 ||
              MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
       Suffix = "$non_lazy_ptr";
     
@@ -327,13 +310,40 @@ void X86ATTAsmPrinter::printSymbolOperand(const MachineOperand &MO) {
       Name = "__imp_" + Name;
     
     if (MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY ||
-        MO.getTargetFlags() == X86II::MO_DARWIN_NONLAZY_PIC_BASE)
-      GVStubs[Name] = Mang->getMangledName(GV);
-    else if (MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY ||
-             MO.getTargetFlags() == X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE)
-      HiddenGVStubs[Name] = Mang->getMangledName(GV);
-    else if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB)
-      FnStubs[Name] = Mang->getMangledName(GV);
+        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 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.
@@ -348,8 +358,12 @@ void X86ATTAsmPrinter::printSymbolOperand(const MachineOperand &MO) {
   case MachineOperand::MO_ExternalSymbol: {
     std::string Name = Mang->makeNameProper(MO.getSymbolName());
     if (MO.getTargetFlags() == X86II::MO_DARWIN_STUB) {
-      FnStubs[Name+"$stub"] = Name;
       Name += "$stub";
+      MCSymbol *&StubSym = FnStubs[OutContext.GetOrCreateSymbol(Name)];
+      if (StubSym == 0) {
+        Name.erase(Name.end()-5, Name.end());
+        StubSym = OutContext.GetOrCreateSymbol(Name);
+      }
     }
     
     // If the name begins with a dollar-sign, enclose it in parens.  We do this
@@ -368,7 +382,6 @@ void X86ATTAsmPrinter::printSymbolOperand(const MachineOperand &MO) {
   case X86II::MO_NO_FLAG:    // No flag.
     break;
   case X86II::MO_DARWIN_NONLAZY:
-  case X86II::MO_DARWIN_HIDDEN_NONLAZY:
   case X86II::MO_DLLIMPORT:
   case X86II::MO_DARWIN_STUB:
     // These affect the name of the symbol, not any suffix.
@@ -407,7 +420,7 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
     O << MO.getImm();
     return;
   case MachineOperand::MO_MachineBasicBlock:
-    printBasicBlockLabel(MO.getMBB(), false, false, VerboseAsm);
+    GetMBBSymbol(MO.getMBB()->getNumber())->print(O, MAI);
     return;
   case MachineOperand::MO_GlobalAddress:
   case MachineOperand::MO_ExternalSymbol:
@@ -417,7 +430,6 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
 }
 
 
-
 void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
                                     const char *Modifier) {
   const MachineOperand &MO = MI->getOperand(OpNo);
@@ -429,7 +441,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
     O << '%';
     unsigned Reg = MO.getReg();
     if (Modifier && strncmp(Modifier, "subreg", strlen("subreg")) == 0) {
-      MVT VT = (strcmp(Modifier+6,"64") == 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);
@@ -525,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 << '-';
@@ -553,23 +567,22 @@ void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
   O << ':';
 }
 
-
 void X86ATTAsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI,
                                               const MachineBasicBlock *MBB,
                                               unsigned uid) const {
   const char *JTEntryDirective = MJTI->getEntrySize() == 4 ?
-    TAI->getData32bitsDirective() : TAI->getData64bitsDirective();
+    MAI->getData32bitsDirective() : MAI->getData64bitsDirective();
 
   O << JTEntryDirective << ' ';
 
   if (Subtarget->isPICStyleRIPRel() || Subtarget->isPICStyleStubPIC()) {
-    O << TAI->getPrivateGlobalPrefix() << getFunctionNumber()
+    O << MAI->getPrivateGlobalPrefix() << getFunctionNumber()
       << '_' << uid << "_set_" << MBB->getNumber();
   } else if (Subtarget->isPICStyleGOT()) {
-    printBasicBlockLabel(MBB, false, false, false);
+    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) {
@@ -610,6 +623,23 @@ bool X86ATTAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned 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.
       if (MO.isImm())
         O << MO.getImm();
@@ -681,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.
@@ -699,59 +719,13 @@ 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 = MCOperand::CreateReg(MO.getReg());
-      } else if (MO.isImm()) {
-        MCOp = MCOperand::CreateImm(MO.getImm());
-      } else if (MO.isMBB()) {
-        MCOp = MCOperand::CreateMBBLabel(getFunctionNumber(), 
-                                         MO.getMBB()->getNumber());
-      } else {
-        llvm_unreachable("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());
+  
+  printInstructionThroughMCStreamer(MI);
   
-  // Call the autogenerated instruction printer routines.
-  printInstruction(MI);
+  if (VerboseAsm && !MI->getDebugLoc().isUnknown())
+    EmitComments(*MI);
+  O << '\n';
 }
 
 void X86ATTAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
@@ -774,8 +748,6 @@ void X86ATTAsmPrinter::PrintGlobalVariable(const GlobalVariable* 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);
@@ -785,15 +757,18 @@ void X86ATTAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
   if (Subtarget->isTargetELF())
     O << "\t.type\t" << name << ",@object\n";
 
+  
+  SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GVar, TM);
   const MCSection *TheSection =
-    getObjFileLowering().SectionForGlobal(GVar, Mang, TM);
-  SwitchToSection(TheSection);
+    getObjFileLowering().SectionForGlobal(GVar, GVKind, Mang, TM);
+  OutStreamer.SwitchSection(TheSection);
 
+  // FIXME: get this stuff from section kind flags.
   if (C->isNullValue() && !GVar->hasSection() &&
       // 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';
@@ -805,40 +780,42 @@ void X86ATTAsmPrinter::PrintGlobalVariable(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;
@@ -851,9 +828,10 @@ void X86ATTAsmPrinter::PrintGlobalVariable(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";
@@ -870,7 +848,6 @@ void X86ATTAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
     O << "\t.globl " << name << '\n';
     // FALL THROUGH
   case GlobalValue::PrivateLinkage:
-  case GlobalValue::LinkerPrivateLinkage:
   case GlobalValue::InternalLinkage:
      break;
   default:
@@ -880,14 +857,32 @@ void X86ATTAsmPrinter::PrintGlobalVariable(const GlobalVariable* GVar) {
   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) {
@@ -905,50 +900,79 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
     
     // 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])
-          GVStubs[Mang->getMangledName(Personalities[i], "$non_lazy_ptr",
-                                       true /*private label*/)] = 
-            Mang->getMangledName(Personalities[i]);
+        if (Personalities[i] == 0)
+          continue;
+        
+        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()) {
       const MCSection *TheSection = 
-      TLOFMacho.getMachOSection("\t.section __IMPORT,__jump_table,symbol_stubs,"
-                                "self_modifying_code+pure_instructions,5", true,
-                                SectionKind::getMetadata());
-      SwitchToSection(TheSection);
-      for (StringMap<std::string>::iterator I = FnStubs.begin(),
-           E = FnStubs.end(); I != E; ++I)
-        O << I->getKeyData() << ":\n" << "\t.indirect_symbol " << I->second
-          << "\n\thlt ; hlt ; hlt ; hlt ; hlt\n";
+        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()) {
       const MCSection *TheSection = 
-        TLOFMacho.getMachOSection("\t.section __IMPORT,__pointers,"
-                                  "non_lazy_symbol_pointers", true,
+        TLOFMacho.getMachOSection("__IMPORT", "__pointers",
+                                  MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS,
                                   SectionKind::getMetadata());
-      SwitchToSection(TheSection);
-      for (StringMap<std::string>::iterator I = GVStubs.begin(),
-           E = GVStubs.end(); I != E; ++I)
-        O << I->getKeyData() << ":\n\t.indirect_symbol "
-          << I->second << "\n\t.long\t0\n";
+      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(getObjFileLowering().getDataSection());
+      OutStreamer.SwitchSection(getObjFileLowering().getDataSection());
       EmitAlignment(2);
-      for (StringMap<std::string>::iterator I = HiddenGVStubs.begin(),
-           E = HiddenGVStubs.end(); I != E; ++I)
-        O << I->getKeyData() << ":\n" << TAI->getData32bitsDirective()
-          << I->second << '\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';
+      }
     }
 
     // Funny Darwin hack: This flag tells the linker that no global symbols
@@ -975,8 +999,8 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
     TargetLoweringObjectFileCOFF &TLOFMacho = 
       static_cast<TargetLoweringObjectFileCOFF&>(getObjFileLowering());
     
-    SwitchToSection(TLOFMacho.getCOFFSection(".section .drectve", true,
-                                             SectionKind::getMetadata()));
+    OutStreamer.SwitchSection(TLOFMacho.getCOFFSection(".section .drectve",true,
+                                                 SectionKind::getMetadata()));
   
     for (StringSet<>::iterator i = DLLExportedGVs.begin(),
          e = DLLExportedGVs.end(); i != e; ++i)
@@ -992,5 +1016,3 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
   return AsmPrinter::doFinalization(M);
 }
 
-// Include the auto-generated portion of the assembly writer.
-#include "X86GenAsmWriter.inc"