MachineInstr::getOpCode() --> getOpcode() in SPARC back-end.
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9AsmPrinter.cpp
index fa749b8e1fd3fd90c816c6ac6163a70987560252..af86e05a9050b8679873760c0d61a9d8b07f7518 100644 (file)
 #include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
 #include "llvm/Pass.h"
-#include "llvm/SlotCalculator.h"
 #include "llvm/Assembly/Writer.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionInfo.h"
 #include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Support/Mangler.h"
 #include "Support/StringExtras.h"
 #include "Support/Statistic.h"
 #include "SparcInternals.h"
 #include <string>
-
 using namespace llvm;
 
-namespace llvm {
-
 namespace {
-
   Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
 
-  class GlobalIdTable: public Annotation {
-    static AnnotationID AnnotId;
-    friend class AsmPrinter;              // give access to AnnotId
-  
-    typedef hash_map<const Value*, int> ValIdMap;
-    typedef ValIdMap::const_iterator ValIdMapConstIterator;
-    typedef ValIdMap::      iterator ValIdMapIterator;
-  public:
-    SlotCalculator Table;    // map anonymous values to unique integer IDs
-    ValIdMap valToIdMap;     // used for values not handled by SlotCalculator 
-    
-    GlobalIdTable(Module* M) : Annotation(AnnotId), Table(M, true) {}
-  };
-
-  AnnotationID GlobalIdTable::AnnotId = 
-  AnnotationManager::getID("ASM PRINTER GLOBAL TABLE ANNOT");
-  
   //===--------------------------------------------------------------------===//
   // Utility functions
 
-  /// Can we treat the specified array as a string?  Only if it is an array of
-  /// ubytes or non-negative sbytes.
-  ///
-  bool isStringCompatible(const ConstantArray *CVA) {
-    const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType();
-    if (ETy == Type::UByteTy) return true;
-    if (ETy != Type::SByteTy) return false;
-
-    for (unsigned i = 0; i < CVA->getNumOperands(); ++i)
-      if (cast<ConstantSInt>(CVA->getOperand(i))->getValue() < 0)
-        return false;
-
-    return true;
-  }
-
   /// getAsCString - Return the specified array as a C compatible string, only
-  /// if the predicate isStringCompatible is true.
+  /// if the predicate isString() is true.
   ///
   std::string getAsCString(const ConstantArray *CVA) {
-    assert(isStringCompatible(CVA) && "Array is not string compatible!");
+    assert(CVA->isString() && "Array is not string compatible!");
 
-    std::string Result;
-    const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType();
-    Result = "\"";
-    for (unsigned i = 0; i < CVA->getNumOperands(); ++i) {
+    std::string Result = "\"";
+    for (unsigned i = 0; i != CVA->getNumOperands(); ++i) {
       unsigned char C = cast<ConstantInt>(CVA->getOperand(i))->getRawValue();
 
       if (C == '"') {
@@ -186,20 +148,17 @@ namespace {
 
 } // End anonymous namespace
 
-} // End namespace llvm
-
 
 
 //===---------------------------------------------------------------------===//
 //   Code abstracted away from the AsmPrinter
 //===---------------------------------------------------------------------===//
 
-namespace llvm {
-
 namespace {
-
   class AsmPrinter {
-    GlobalIdTable* idTable;
+    // Mangle symbol names appropriately
+    Mangler *Mang;
+
   public:
     std::ostream &toAsm;
     const TargetMachine &Target;
@@ -213,27 +172,23 @@ namespace {
     } CurSection;
 
     AsmPrinter(std::ostream &os, const TargetMachine &T)
-      : idTable(0), toAsm(os), Target(T), CurSection(Unknown) {}
+      : /* idTable(0), */ toAsm(os), Target(T), CurSection(Unknown) {}
   
+    ~AsmPrinter() {
+      delete Mang;
+    }
+
     // (start|end)(Module|Function) - Callback methods invoked by subclasses
     void startModule(Module &M) {
-      // Create the global id table if it does not already exist
-      idTable = (GlobalIdTable*)M.getAnnotation(GlobalIdTable::AnnotId);
-      if (idTable == NULL) {
-        idTable = new GlobalIdTable(&M);
-        M.addAnnotation(idTable);
-      }
+      Mang = new Mangler(M);
     }
 
     void PrintZeroBytesToPad(int numBytes) {
-      for (/* no init */; numBytes >= 8; numBytes -= 8)
-        printSingleConstantValue(Constant::getNullValue(Type::ULongTy));
-
-      if (numBytes >= 4) {
-        printSingleConstantValue(Constant::getNullValue(Type::UIntTy));
-        numBytes -= 4;
-      }
-
+      //
+      // Always use single unsigned bytes for padding.  We don't know upon
+      // what data size the beginning address is aligned, so using anything
+      // other than a byte may cause alignment errors in the assembler.
+      //
       while (numBytes--)
         printSingleConstantValue(Constant::getNullValue(Type::UByteTy));
     }
@@ -257,13 +212,13 @@ namespace {
       toAsm << "\t.align\t" << ConstantToAlignment(CV, Target) << "\n";
   
       // Print .size and .type only if it is not a string.
-      const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
-      if (CVA && isStringCompatible(CVA)) {
-        // print it as a string and return
-        toAsm << valID << ":\n";
-        toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
-        return;
-      }
+      if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV))
+        if (CVA->isString()) {
+          // print it as a string and return
+          toAsm << valID << ":\n";
+          toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
+          return;
+        }
   
       toAsm << "\t.type" << "\t" << valID << ",#object\n";
 
@@ -276,20 +231,6 @@ namespace {
       printConstantValueOnly(CV);
     }
 
-    void startFunction(Function &F) {
-      // Make sure the slot table has information about this function...
-      idTable->Table.incorporateFunction(&F);
-    }
-    void endFunction(Function &) {
-      idTable->Table.purgeFunction();  // Forget all about F
-    }
-
-    // Check if a value is external or accessible from external code.
-    bool isExternal(const Value* V) {
-      const GlobalValue *GV = dyn_cast<GlobalValue>(V);
-      return GV && GV->hasExternalLinkage();
-    }
-  
     // enterSection - Use this method to enter a different section of the output
     // executable.  This is used to only output necessary section transitions.
     //
@@ -309,72 +250,21 @@ namespace {
       toAsm << "\n";
     }
 
-    static std::string getValidSymbolName(const std::string &S) {
-      std::string Result;
-    
-      // Symbol names in Sparc assembly language have these rules:
-      // (a) Must match { letter | _ | . | $ } { letter | _ | . | $ | digit }*
-      // (b) A name beginning in "." is treated as a local name.
-      // 
-      if (isdigit(S[0]))
-        Result = "ll";
-    
-      for (unsigned i = 0; i < S.size(); ++i) {
-        char C = S[i];
-        if (C == '_' || C == '.' || C == '$' || isalpha(C) || isdigit(C))
-          Result += C;
-        else {
-          Result += '_';
-          Result += char('0' + ((unsigned char)C >> 4));
-          Result += char('0' + (C & 0xF));
-        }
-      }
-      return Result;
-    }
-
-    // getID - Return a valid identifier for the specified value.  Base it on
-    // the name of the identifier if possible (qualified by the type), and
-    // use a numbered value based on prefix otherwise.
-    // FPrefix is always prepended to the output identifier.
-    //
-    std::string getID(const Value *V, const char *Prefix,
-                      const char *FPrefix = 0)
-    {
-      std::string Result = FPrefix ? FPrefix : "";  // "Forced prefix"
-
-      Result += V->hasName() ? V->getName() : std::string(Prefix);
-
-      // Qualify all internal names with a unique id.
-      if (!isExternal(V)) {
-        int valId = idTable->Table.getSlot(V);
-        if (valId == -1) {
-          GlobalIdTable::ValIdMapConstIterator I = idTable->valToIdMap.find(V);
-          if (I == idTable->valToIdMap.end())
-            valId = idTable->valToIdMap[V] = idTable->valToIdMap.size();
-          else
-            valId = I->second;
-        }
-        Result = Result + "_" + itostr(valId);
-
-        // Replace or prefix problem characters in the name
-        Result = getValidSymbolName(Result);
-      }
-
-      return Result;
-    }
-  
-    // getID Wrappers - Ensure consistent usage...
+    // getID Wrappers - Ensure consistent usage
+    // Symbol names in Sparc assembly language have these rules:
+    // (a) Must match { letter | _ | . | $ } { letter | _ | . | $ | digit }*
+    // (b) A name beginning in "." is treated as a local name.
     std::string getID(const Function *F) {
-      return getID(F, "LLVMFunction_");
+      return Mang->getValueName(F);
     }
     std::string getID(const BasicBlock *BB) {
-      return getID(BB, "LL", (".L_"+getID(BB->getParent())+"_").c_str());
+      return ".L_" + getID(BB->getParent()) + "_" + Mang->getValueName(BB);
     }
     std::string getID(const GlobalVariable *GV) {
-      return getID(GV, "LLVMGlobal_");
+      return Mang->getValueName(GV);
     }
     std::string getID(const Constant *CV) {
-      return getID(CV, "LLVMConst_", ".C_");
+      return ".C_" + Mang->getValueName(CV);
     }
     std::string getID(const GlobalValue *GV) {
       if (const GlobalVariable *V = dyn_cast<GlobalVariable>(GV))
@@ -404,10 +294,8 @@ namespace {
     /// 
     std::string valToExprString(const Value* V, const TargetMachine& target);
   };
-
 } // End anonymous namespace
 
-} // End namespace llvm
 
 /// Print a single constant value.
 ///
@@ -452,6 +340,8 @@ void AsmPrinter::printSingleConstantValue(const Constant* CV) {
         
       toAsm << "\t! " << CV->getType()->getDescription()
             << " value: " << Val << "\n";
+    } else if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) {
+      toAsm << (int)CB->getValue() << "\n";
     } else {
       WriteAsOperand(toAsm, CV, false, false) << "\n";
     }
@@ -464,18 +354,17 @@ void AsmPrinter::printSingleConstantValue(const Constant* CV) {
 /// Uses printSingleConstantValue() to print each individual value.
 ///
 void AsmPrinter::printConstantValueOnly(const Constant* CV,
-                                        int numPadBytesAfter)
-{
-  const ConstantArray *CVA = dyn_cast<ConstantArray>(CV);
-
-  if (CVA && isStringCompatible(CVA)) {
-    // print the string alone and return
-    toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
-  } else if (CVA) { 
-    // Not a string.  Print the values in successive locations
-    const std::vector<Use> &constValues = CVA->getValues();
-    for (unsigned i=0; i < constValues.size(); i++)
-      printConstantValueOnly(cast<Constant>(constValues[i].get()));
+                                        int numPadBytesAfter) {
+  if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) {
+    if (CVA->isString()) {
+      // print the string alone and return
+      toAsm << "\t" << ".ascii" << "\t" << getAsCString(CVA) << "\n";
+    } else {
+      // Not a string.  Print the values in successive locations
+      const std::vector<Use> &constValues = CVA->getValues();
+      for (unsigned i=0; i < constValues.size(); i++)
+        printConstantValueOnly(cast<Constant>(constValues[i].get()));
+    }
   } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) {
     // Print the fields in successive locations. Pad to align if needed!
     const StructLayout *cvsLayout =
@@ -617,8 +506,6 @@ std::string AsmPrinter::valToExprString(const Value* V,
 //   SparcAsmPrinter Code
 //===----------------------------------------------------------------------===//
 
-namespace llvm {
-
 namespace {
 
   struct SparcAsmPrinter : public FunctionPass, public AsmPrinter {
@@ -638,9 +525,7 @@ namespace {
 
     virtual bool runOnFunction(Function &F) {
       currFunction = &F;
-      startFunction(F);
       emitFunction(F);
-      endFunction(F);
       return false;
     }
 
@@ -681,7 +566,7 @@ namespace {
 inline bool
 SparcAsmPrinter::OpIsBranchTargetLabel(const MachineInstr *MI,
                                        unsigned int opNum) {
-  switch (MI->getOpCode()) {
+  switch (MI->getOpcode()) {
   case V9::JMPLCALLr:
   case V9::JMPLCALLi:
   case V9::JMPLRETr:
@@ -695,9 +580,9 @@ SparcAsmPrinter::OpIsBranchTargetLabel(const MachineInstr *MI,
 inline bool
 SparcAsmPrinter::OpIsMemoryAddressBase(const MachineInstr *MI,
                                        unsigned int opNum) {
-  if (Target.getInstrInfo().isLoad(MI->getOpCode()))
+  if (Target.getInstrInfo().isLoad(MI->getOpcode()))
     return (opNum == 0);
-  else if (Target.getInstrInfo().isStore(MI->getOpCode()))
+  else if (Target.getInstrInfo().isStore(MI->getOpcode()))
     return (opNum == 1);
   else
     return false;
@@ -716,15 +601,15 @@ SparcAsmPrinter::printOperands(const MachineInstr *MI,
   const MachineOperand& mop = MI->getOperand(opNum);
   
   if (OpIsBranchTargetLabel(MI, opNum)) {
-    PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
+    PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpcode());
     return 2;
   } else if (OpIsMemoryAddressBase(MI, opNum)) {
     toAsm << "[";
-    PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpCode());
+    PrintOp1PlusOp2(mop, MI->getOperand(opNum+1), MI->getOpcode());
     toAsm << "]";
     return 2;
   } else {
-    printOneOperand(mop, MI->getOpCode());
+    printOneOperand(mop, MI->getOpcode());
     return 1;
   }
 }
@@ -806,7 +691,7 @@ SparcAsmPrinter::printOneOperand(const MachineOperand &mop,
 }
 
 void SparcAsmPrinter::emitMachineInst(const MachineInstr *MI) {
-  unsigned Opcode = MI->getOpCode();
+  unsigned Opcode = MI->getOpcode();
 
   if (Target.getInstrInfo().isDummyPhiInstr(Opcode))
     return;  // IGNORE PHI NODES
@@ -908,8 +793,7 @@ void SparcAsmPrinter::emitGlobals(const Module &M) {
   toAsm << "\n";
 }
 
-FunctionPass *createAsmPrinterPass(std::ostream &Out, const TargetMachine &TM) {
+FunctionPass *llvm::createAsmPrinterPass(std::ostream &Out,
+                                         const TargetMachine &TM) {
   return new SparcAsmPrinter(Out, TM);
 }
-
-} // End llvm namespace