Fix target library name
[oota-llvm.git] / lib / Target / Mips / MipsAsmPrinter.cpp
index fc7da391f281946ca54910602e3b9e5c5cda4f49..532c82df06fb8af19796845bddef6b2d2190dc29 100644 (file)
@@ -23,6 +23,7 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
 #include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/DwarfWriter.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
@@ -37,6 +38,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/MathExtras.h"
+#include "llvm/Support/raw_ostream.h"
 #include <cctype>
 
 using namespace llvm;
@@ -44,13 +46,12 @@ using namespace llvm;
 STATISTIC(EmittedInsts, "Number of machine instrs printed");
 
 namespace {
-  struct VISIBILITY_HIDDEN MipsAsmPrinter : public AsmPrinter {
-
+  class VISIBILITY_HIDDEN MipsAsmPrinter : public AsmPrinter {
     const MipsSubtarget *Subtarget;
-
-    MipsAsmPrinter(std::ostream &O, MipsTargetMachine &TM, 
-                   const TargetAsmInfo *T): 
-                   AsmPrinter(O, TM, T) {
+  public:
+    MipsAsmPrinter(raw_ostream &O, MipsTargetMachine &TM, 
+                   const TargetAsmInfo *T, bool F, bool V)
+      : AsmPrinter(O, TM, T, F, V) {
       Subtarget = &TM.getSubtarget<MipsSubtarget>();
     }
 
@@ -58,10 +59,10 @@ namespace {
       return "Mips Assembly Printer";
     }
 
-    virtual std::string getSectionForFunction(const Function &F) const;
     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 
                          unsigned AsmVariant, const char *ExtraCode);
     void printOperand(const MachineInstr *MI, int opNum);
+    void printUnsignedImm(const MachineInstr *MI, int opNum);
     void printMemOperand(const MachineInstr *MI, int opNum, 
                          const char *Modifier = 0);
     void printFCCOperand(const MachineInstr *MI, int opNum, 
@@ -88,10 +89,10 @@ namespace {
 /// assembly code for a MachineFunction to the given output stream,
 /// using the given target machine description.  This should work
 /// regardless of whether the function is in SSA form.
-FunctionPass *llvm::createMipsCodePrinterPass(std::ostream &o,
-                                              MipsTargetMachine &tm
-{
-  return new MipsAsmPrinter(o, tm, tm.getTargetAsmInfo());
+FunctionPass *llvm::createMipsCodePrinterPass(raw_ostream &o,
+                                              MipsTargetMachine &tm,
+                                              bool fast, bool verbose) {
+  return new MipsAsmPrinter(o, tm, tm.getTargetAsmInfo(), fast, verbose);
 }
 
 //===----------------------------------------------------------------------===//
@@ -174,10 +175,9 @@ printSavedRegsBitmask(MachineFunction &MF)
 void MipsAsmPrinter::
 printHex32(unsigned int Value) 
 {
-  O << "0x" << std::hex;
+  O << "0x";
   for (int i = 7; i >= 0; i--) 
-    O << std::hex << ( (Value & (0xF << (i*4))) >> (i*4) );
-  O << std::dec;
+    O << utohexstr( (Value & (0xF << (i*4))) >> (i*4) );
 }
 
 //===----------------------------------------------------------------------===//
@@ -218,18 +218,13 @@ emitCurrentABIString(void)
   return NULL;
 }  
 
-// Substitute old hook with new one temporary
-std::string MipsAsmPrinter::getSectionForFunction(const Function &F) const {
-  return TAI->SectionForGlobal(&F);
-}
-
 /// Emit the directives used by GAS on the start of functions
 void MipsAsmPrinter::
 emitFunctionStart(MachineFunction &MF)
 {
   // Print out the label for the function.
   const Function *F = MF.getFunction();
-  SwitchToTextSection(TAI->SectionForGlobal(F).c_str());
+  SwitchToSection(TAI->SectionForGlobal(F));
 
   // 2 bits aligned
   EmitAlignment(2, F);
@@ -237,6 +232,8 @@ emitFunctionStart(MachineFunction &MF)
   O << "\t.globl\t"  << CurrentFnName << '\n';
   O << "\t.ent\t"    << CurrentFnName << '\n';
 
+  printVisibility(CurrentFnName, F->getVisibility());
+
   if ((TAI->hasDotTypeDotSizeDirective()) && Subtarget->isLinux())
     O << "\t.type\t"   << CurrentFnName << ", @function\n";
 
@@ -268,6 +265,8 @@ emitFunctionEnd(MachineFunction &MF)
 bool MipsAsmPrinter::
 runOnMachineFunction(MachineFunction &MF) 
 {
+  this->MF = &MF;
+
   SetupMachineFunction(MF);
 
   // Print out constants referenced by the function
@@ -278,9 +277,6 @@ runOnMachineFunction(MachineFunction &MF)
 
   O << "\n\n";
 
-  // What's my mangled name?
-  CurrentFnName = Mang->getValueName(MF.getFunction());
-
   // Emit the function start directives
   emitFunctionStart(MF);
 
@@ -339,26 +335,24 @@ printOperand(const MachineInstr *MI, int opNum)
   // using PIC_. %call16 is used to load direct call targets
   // on PIC_ and small code size. %call_lo and %call_hi load 
   // direct call targets on PIC_ and large code size.
-  if (MI->getOpcode() == Mips::LUi && !MO.isRegister() 
-      && !MO.isImmediate()) {
+  if (MI->getOpcode() == Mips::LUi && !MO.isReg() && !MO.isImm()) {
     if ((isPIC) && (isCodeLarge))
       O << "%call_hi(";
     else
       O << "%hi(";
     closeP = true;
-  } else if ((MI->getOpcode() == Mips::ADDiu) && !MO.isRegister() 
-             && !MO.isImmediate()) {
+  } else if ((MI->getOpcode() == Mips::ADDiu) && !MO.isReg() && !MO.isImm()) {
     const MachineOperand &firstMO = MI->getOperand(opNum-1);
     if (firstMO.getReg() == Mips::GP)
       O << "%gp_rel(";
     else
       O << "%lo(";
     closeP = true;
-  } else if ((isPIC) && (MI->getOpcode() == Mips::LW)
-             && (!MO.isRegister()) && (!MO.isImmediate())) {
+  } else if ((isPIC) && (MI->getOpcode() == Mips::LW) &&
+             (!MO.isReg()) && (!MO.isImm())) {
     const MachineOperand &firstMO = MI->getOperand(opNum-1);
     const MachineOperand &lastMO  = MI->getOperand(opNum+1);
-    if ((firstMO.isRegister()) && (lastMO.isRegister())) {
+    if ((firstMO.isReg()) && (lastMO.isReg())) {
       if ((firstMO.getReg() == Mips::T9) && (lastMO.getReg() == Mips::GP) 
           && (!isCodeLarge))
         O << "%call16(";
@@ -381,11 +375,7 @@ printOperand(const MachineInstr *MI, int opNum)
       break;
 
     case MachineOperand::MO_Immediate:
-      if ((MI->getOpcode() == Mips::SLTiu) || (MI->getOpcode() == Mips::ORi) || 
-          (MI->getOpcode() == Mips::LUi)   || (MI->getOpcode() == Mips::ANDi))
-        O << (unsigned short int)MO.getImm();
-      else
-        O << (short int)MO.getImm();
+      O << (short int)MO.getImm();
       break;
 
     case MachineOperand::MO_MachineBasicBlock:
@@ -393,7 +383,10 @@ printOperand(const MachineInstr *MI, int opNum)
       return;
 
     case MachineOperand::MO_GlobalAddress:
-      O << Mang->getValueName(MO.getGlobal());
+      {
+        const GlobalValue *GV = MO.getGlobal();
+        O << Mang->getValueName(GV);
+      }
       break;
 
     case MachineOperand::MO_ExternalSymbol:
@@ -405,7 +398,6 @@ printOperand(const MachineInstr *MI, int opNum)
       << '_' << MO.getIndex();
       break;
 
-    // FIXME: Verify correct
     case MachineOperand::MO_ConstantPoolIndex:
       O << TAI->getPrivateGlobalPrefix() << "CPI"
         << getFunctionNumber() << "_" << MO.getIndex();
@@ -418,6 +410,16 @@ printOperand(const MachineInstr *MI, int opNum)
   if (closeP) O << ")";
 }
 
+void MipsAsmPrinter::
+printUnsignedImm(const MachineInstr *MI, int opNum) 
+{
+  const MachineOperand &MO = MI->getOperand(opNum);
+  if (MO.getType() == MachineOperand::MO_Immediate)
+    O << (unsigned short int)MO.getImm();
+  else 
+    printOperand(MI, opNum);
+}
+
 void MipsAsmPrinter::
 printMemOperand(const MachineInstr *MI, int opNum, const char *Modifier) 
 {
@@ -449,7 +451,7 @@ printFCCOperand(const MachineInstr *MI, int opNum, const char *Modifier)
 bool MipsAsmPrinter::
 doInitialization(Module &M) 
 {
-  Mang = new Mangler(M);
+  Mang = new Mangler(M, "", TAI->getPrivateGlobalPrefix());
 
   // Tell the assembler which ABI we are using
   O << "\t.section .mdebug." << emitCurrentABIString() << '\n';
@@ -477,11 +479,10 @@ printModuleLevelGV(const GlobalVariable* GVar) {
     return;
 
   O << "\n\n";
-  std::string SectionName = TAI->SectionForGlobal(GVar);
   std::string name = Mang->getValueName(GVar);
   Constant *C = GVar->getInitializer();
   const Type *CTy = C->getType();
-  unsigned Size = TD->getABITypeSize(CTy);
+  unsigned Size = TD->getTypePaddedSize(CTy);
   const ConstantArray *CVA = dyn_cast<ConstantArray>(C);
   bool printSizeAndType = true;
 
@@ -497,18 +498,18 @@ printModuleLevelGV(const GlobalVariable* GVar) {
   } else
     Align = TD->getPreferredTypeAlignmentShift(CTy);
 
-  // FIXME: ELF supports visibility
+  printVisibility(name, GVar->getVisibility());
 
-  SwitchToDataSection(SectionName.c_str());
+  SwitchToSection(TAI->SectionForGlobal(GVar));
 
   if (C->isNullValue() && !GVar->hasSection()) {
     if (!GVar->isThreadLocal() &&
-        (GVar->hasInternalLinkage() || GVar->isWeakForLinker())) {
+        (GVar->hasLocalLinkage() || GVar->isWeakForLinker())) {
       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
 
-      if (GVar->hasInternalLinkage())
+      if (GVar->hasLocalLinkage())
         O << "\t.local\t" << name << '\n';
-      
+
       O << TAI->getCOMMDirective() << name << ',' << Size;
       if (TAI->getCOMMDirectiveTakesAlignment())
         O << ',' << (1 << Align);
@@ -518,9 +519,11 @@ printModuleLevelGV(const GlobalVariable* GVar) {
     }
   }
   switch (GVar->getLinkage()) {
-   case GlobalValue::LinkOnceLinkage:
+   case GlobalValue::LinkOnceAnyLinkage:
+   case GlobalValue::LinkOnceODRLinkage:
    case GlobalValue::CommonLinkage:
-   case GlobalValue::WeakLinkage:
+   case GlobalValue::WeakAnyLinkage:
+   case GlobalValue::WeakODRLinkage:
     // FIXME: Verify correct for weak.
     // Nonnull linkonce -> weak
     O << "\t.weak " << name << '\n';
@@ -532,9 +535,10 @@ printModuleLevelGV(const GlobalVariable* GVar) {
     // If external or appending, declare as a global symbol
     O << TAI->getGlobalDirective() << name << '\n';
     // Fall Through
+   case GlobalValue::PrivateLinkage:
    case GlobalValue::InternalLinkage:
     if (CVA && CVA->isCString())
-      printSizeAndType = false;  
+      printSizeAndType = false;
     break;
    case GlobalValue::GhostLinkage:
     cerr << "Should not have any unmaterialized functions!\n";
@@ -549,8 +553,7 @@ printModuleLevelGV(const GlobalVariable* GVar) {
     assert(0 && "Unknown linkage type!");
   }
 
-  if (Align)
-    O << "\t.align " << Align << '\n';
+  EmitAlignment(Align, GVar);
 
   if (TAI->hasDotTypeDotSizeDirective() && printSizeAndType) {
     O << "\t.type " << name << ",@object\n";