Revert r107205 and r107207.
[oota-llvm.git] / lib / Target / XCore / AsmPrinter / XCoreAsmPrinter.cpp
index d8a5d6b52a1731759453cfa5c0c7bd9c86f00bb5..c100c590135eb06b70ae2e4fb27be6f66accbb90 100644 (file)
@@ -22,7 +22,6 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
 #include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/DwarfWriter.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetLoweringObjectFile.h"
 #include "llvm/Target/TargetRegistry.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cctype>
 using namespace llvm;
@@ -53,69 +52,53 @@ namespace {
   class XCoreAsmPrinter : public AsmPrinter {
     const XCoreSubtarget &Subtarget;
   public:
-    explicit XCoreAsmPrinter(formatted_raw_ostream &O, TargetMachine &TM,
-                             MCContext &Ctx, MCStreamer &Streamer,
-                             const MCAsmInfo *T)
-      : AsmPrinter(O, TM, Ctx, Streamer, T),
-      Subtarget(TM.getSubtarget<XCoreSubtarget>()) {}
+    explicit XCoreAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
+      : AsmPrinter(TM, Streamer), Subtarget(TM.getSubtarget<XCoreSubtarget>()){}
 
     virtual const char *getPassName() const {
       return "XCore Assembly Printer";
     }
 
-    void printMemOperand(const MachineInstr *MI, int opNum);
-    void printInlineJT(const MachineInstr *MI, int opNum,
+    void printMemOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
+    void printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O,
                        const std::string &directive = ".jmptable");
-    void printInlineJT32(const MachineInstr *MI, int opNum) {
-      printInlineJT(MI, opNum, ".jmptable32");
+    void printInlineJT32(const MachineInstr *MI, int opNum, raw_ostream &O) {
+      printInlineJT(MI, opNum, O, ".jmptable32");
     }
-    void printOperand(const MachineInstr *MI, int opNum);
+    void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
-                        unsigned AsmVariant, const char *ExtraCode);
+                         unsigned AsmVariant, const char *ExtraCode,
+                         raw_ostream &O);
 
-    void emitGlobalDirective(const MCSymbol *Sym);
-    
-    void emitArrayBound(const MCSymbol *Sym, const GlobalVariable *GV);
+    void emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV);
     virtual void EmitGlobalVariable(const GlobalVariable *GV);
 
-    void emitFunctionStart(MachineFunction &MF);
-
-    void printInstruction(const MachineInstr *MI);  // autogenerated.
+    void printInstruction(const MachineInstr *MI, raw_ostream &O); // autogen'd.
     static const char *getRegisterName(unsigned RegNo);
 
-    bool runOnMachineFunction(MachineFunction &MF);
+    void EmitFunctionEntryLabel();
     void EmitInstruction(const MachineInstr *MI);
     void EmitFunctionBodyEnd();
-    
-    void getAnalysisUsage(AnalysisUsage &AU) const {
-      AsmPrinter::getAnalysisUsage(AU);
-      AU.setPreservesAll();
-      AU.addRequired<MachineModuleInfo>();
-      AU.addRequired<DwarfWriter>();
-    }
   };
 } // end of anonymous namespace
 
 #include "XCoreGenAsmWriter.inc"
 
-void XCoreAsmPrinter::emitGlobalDirective(const MCSymbol *Sym) {
-  O << MAI->getGlobalDirective() << *Sym << "\n";
-}
-
-void XCoreAsmPrinter::emitArrayBound(const MCSymbol *Sym,
-                                     const GlobalVariable *GV) {
+void XCoreAsmPrinter::emitArrayBound(MCSymbol *Sym, const GlobalVariable *GV) {
   assert(((GV->hasExternalLinkage() ||
     GV->hasWeakLinkage()) ||
     GV->hasLinkOnceLinkage()) && "Unexpected linkage");
   if (const ArrayType *ATy = dyn_cast<ArrayType>(
     cast<PointerType>(GV->getType())->getElementType())) {
-    O << MAI->getGlobalDirective() << *Sym;
-    O << ".globound" << "\n";
-    O << "\t.set\t" << *Sym;
-    O << ".globound" << "," << ATy->getNumElements() << "\n";
+    OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global);
+    // FIXME: MCStreamerize.
+    OutStreamer.EmitRawText(StringRef(".globound"));
+    OutStreamer.EmitRawText("\t.set\t" + Twine(Sym->getName()));
+    OutStreamer.EmitRawText(".globound," + Twine(ATy->getNumElements()));
     if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()) {
       // TODO Use COMDAT groups for LinkOnceLinkage
-      O << MAI->getWeakDefDirective() << *Sym << ".globound" << "\n";
+      OutStreamer.EmitRawText(MAI->getWeakDefDirective() +Twine(Sym->getName())+
+                              ".globound");
     }
   }
 }
@@ -135,21 +118,23 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
   unsigned Align = (unsigned)TD->getPreferredTypeAlignmentShift(C->getType());
   
   // Mark the start of the global
-  O << "\t.cc_top " << *GVSym << ".data," << *GVSym << "\n";
+  OutStreamer.EmitRawText("\t.cc_top " + Twine(GVSym->getName()) + ".data," +
+                          GVSym->getName());
 
   switch (GV->getLinkage()) {
   case GlobalValue::AppendingLinkage:
-    llvm_report_error("AppendingLinkage is not supported by this target!");
+    report_fatal_error("AppendingLinkage is not supported by this target!");
   case GlobalValue::LinkOnceAnyLinkage:
   case GlobalValue::LinkOnceODRLinkage:
   case GlobalValue::WeakAnyLinkage:
   case GlobalValue::WeakODRLinkage:
   case GlobalValue::ExternalLinkage:
     emitArrayBound(GVSym, GV);
-    emitGlobalDirective(GVSym);
+    OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
+
     // TODO Use COMDAT groups for LinkOnceLinkage
     if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())
-      O << MAI->getWeakDefDirective() << *GVSym << "\n";
+      OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak);
     // FALL THROUGH
   case GlobalValue::InternalLinkage:
   case GlobalValue::PrivateLinkage:
@@ -163,17 +148,18 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
     llvm_unreachable("Unknown linkage type!");
   }
 
-  EmitAlignment(Align, GV, 2);
+  EmitAlignment(Align > 2 ? Align : 2, GV);
   
   unsigned Size = TD->getTypeAllocSize(C->getType());
   if (GV->isThreadLocal()) {
     Size *= MaxThreads;
   }
   if (MAI->hasDotTypeDotSizeDirective()) {
-    O << "\t.type " << *GVSym << ",@object\n";
-    O << "\t.size " << *GVSym << "," << Size << "\n";
+    OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject);
+    OutStreamer.EmitRawText("\t.size " + Twine(GVSym->getName()) + "," +
+                            Twine(Size));
   }
-  O << *GVSym << ":\n";
+  OutStreamer.EmitLabel(GVSym);
   
   EmitGlobalConstant(C);
   if (GV->isThreadLocal()) {
@@ -186,87 +172,38 @@ void XCoreAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
     OutStreamer.EmitZeros(4 - Size, 0);
   
   // Mark the end of the global
-  O << "\t.cc_bottom " << *GVSym << ".data\n";
+  OutStreamer.EmitRawText("\t.cc_bottom " + Twine(GVSym->getName()) + ".data");
 }
 
-/// Emit the directives on the start of functions
-void XCoreAsmPrinter::emitFunctionStart(MachineFunction &MF) {
-  // Print out the label for the function.
-  const Function *F = MF.getFunction();
-
-  OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
-  
-  // Mark the start of the function
-  O << "\t.cc_top " << *CurrentFnSym << ".function," << *CurrentFnSym << "\n";
-
-  switch (F->getLinkage()) {
-  default: llvm_unreachable("Unknown linkage type!");
-  case Function::InternalLinkage:  // Symbols default to internal.
-  case Function::PrivateLinkage:
-  case Function::LinkerPrivateLinkage:
-    break;
-  case Function::ExternalLinkage:
-    emitGlobalDirective(CurrentFnSym);
-    break;
-  case Function::LinkOnceAnyLinkage:
-  case Function::LinkOnceODRLinkage:
-  case Function::WeakAnyLinkage:
-  case Function::WeakODRLinkage:
-    // TODO Use COMDAT groups for LinkOnceLinkage
-    O << MAI->getGlobalDirective() << *CurrentFnSym << "\n";
-    O << MAI->getWeakDefDirective() << *CurrentFnSym << "\n";
-    break;
-  }
-  // (1 << 1) byte aligned
-  EmitAlignment(MF.getAlignment(), F, 1);
-  if (MAI->hasDotTypeDotSizeDirective())
-    O << "\t.type " << *CurrentFnSym << ",@function\n";
-
-  O << *CurrentFnSym << ":\n";
-}
-
-
 /// EmitFunctionBodyEnd - Targets can override this to emit stuff after
 /// the last basic block in the function.
 void XCoreAsmPrinter::EmitFunctionBodyEnd() {
   // Emit function end directives
-  O << "\t.cc_bottom " << *CurrentFnSym << ".function\n";
+  OutStreamer.EmitRawText("\t.cc_bottom " + Twine(CurrentFnSym->getName()) +
+                          ".function");
 }
 
-/// runOnMachineFunction - This uses the printMachineInstruction()
-/// method to print assembly for each instruction.
-///
-bool XCoreAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
-  SetupMachineFunction(MF);
-
-  // Print out constants referenced by the function
-  EmitConstantPool();
-
-  // Emit the function start directives
-  emitFunctionStart(MF);
-  
-  // Emit pre-function debug information.
-  DW->BeginFunction(&MF);
-
-  EmitFunctionBody();
-  return false;
+void XCoreAsmPrinter::EmitFunctionEntryLabel() {
+  // Mark the start of the function
+  OutStreamer.EmitRawText("\t.cc_top " + Twine(CurrentFnSym->getName()) +
+                          ".function," + CurrentFnSym->getName());
+  OutStreamer.EmitLabel(CurrentFnSym);
 }
 
-void XCoreAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum)
-{
-  printOperand(MI, opNum);
+void XCoreAsmPrinter::printMemOperand(const MachineInstr *MI, int opNum,
+                                      raw_ostream &O) {
+  printOperand(MI, opNum, O);
   
-  if (MI->getOperand(opNum+1).isImm()
-    && MI->getOperand(opNum+1).getImm() == 0)
+  if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() == 0)
     return;
   
   O << "+";
-  printOperand(MI, opNum+1);
+  printOperand(MI, opNum+1, O);
 }
 
 void XCoreAsmPrinter::
-printInlineJT(const MachineInstr *MI, int opNum, const std::string &directive)
-{
+printInlineJT(const MachineInstr *MI, int opNum, raw_ostream &O,
+              const std::string &directive) {
   unsigned JTI = MI->getOperand(opNum).getIndex();
   const MachineFunction *MF = MI->getParent()->getParent();
   const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
@@ -277,11 +214,12 @@ printInlineJT(const MachineInstr *MI, int opNum, const std::string &directive)
     MachineBasicBlock *MBB = JTBBs[i];
     if (i > 0)
       O << ",";
-    O << *MBB->getSymbol(OutContext);
+    O << *MBB->getSymbol();
   }
 }
 
-void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
+void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
+                                   raw_ostream &O) {
   const MachineOperand &MO = MI->getOperand(opNum);
   switch (MO.getType()) {
   case MachineOperand::MO_Register:
@@ -291,7 +229,7 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
     O << MO.getImm();
     break;
   case MachineOperand::MO_MachineBasicBlock:
-    O << *MO.getMBB()->getSymbol(OutContext);
+    O << *MO.getMBB()->getSymbol();
     break;
   case MachineOperand::MO_GlobalAddress:
     O << *Mang->getSymbol(MO.getGlobal());
@@ -318,23 +256,25 @@ void XCoreAsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
 /// PrintAsmOperand - Print out an operand for an inline asm expression.
 ///
 bool XCoreAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
-                                      unsigned AsmVariant, 
-                                      const char *ExtraCode) {
-  printOperand(MI, OpNo);
+                                      unsigned AsmVariant,const char *ExtraCode,
+                                      raw_ostream &O) {
+  printOperand(MI, OpNo, O);
   return false;
 }
 
 void XCoreAsmPrinter::EmitInstruction(const MachineInstr *MI) {
+  SmallString<128> Str;
+  raw_svector_ostream O(Str);
+  
   // Check for mov mnemonic
   unsigned src, dst, srcSR, dstSR;
   if (TM.getInstrInfo()->isMoveInstr(*MI, src, dst, srcSR, dstSR)) {
     O << "\tmov " << getRegisterName(dst) << ", ";
     O << getRegisterName(src);
-    OutStreamer.AddBlankLine();
-    return;
+  } else {
+    printInstruction(MI, O);
   }
-  printInstruction(MI);
-  OutStreamer.AddBlankLine();
+  OutStreamer.EmitRawText(O.str());
 }
 
 // Force static initialization.