More templatization.
[oota-llvm.git] / lib / Target / IA64 / IA64AsmPrinter.cpp
index 1de12153e273552f6c7912953b395bc280dbd1d7..cbc86ea365697fd89277769c39da1a07eeea04e6 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
+#define DEBUG_TYPE "asm-printer"
 #include "IA64.h"
 #include "IA64TargetMachine.h"
 #include "llvm/Module.h"
 #include "llvm/Type.h"
-#include "llvm/Assembly/Writer.h"
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetMachine.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/ADT/Statistic.h"
-#include <iostream>
 using namespace llvm;
 
+STATISTIC(EmittedInsts, "Number of machine instrs printed");
+
 namespace {
-  Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
-
-  struct VISIBILITY_HIDDEN IA64TargetAsmInfo : public TargetAsmInfo {
-    IA64TargetAsmInfo() {
-      CommentString = "//";
-      Data8bitsDirective = "\tdata1\t";     // FIXME: check that we are
-      Data16bitsDirective = "\tdata2.ua\t"; // disabling auto-alignment
-      Data32bitsDirective = "\tdata4.ua\t"; // properly
-      Data64bitsDirective = "\tdata8.ua\t";
-      ZeroDirective = "\t.skip\t";
-      AsciiDirective = "\tstring\t";
-
-      GlobalVarAddrPrefix="";
-      GlobalVarAddrSuffix="";
-      FunctionAddrPrefix="@fptr(";
-      FunctionAddrSuffix=")";
-      
-      // FIXME: would be nice to have rodata (no 'w') when appropriate?
-      ConstantPoolSection = "\n\t.section .data, \"aw\", \"progbits\"\n";
-    }
-  };
-  
   struct IA64AsmPrinter : public AsmPrinter {
     std::set<std::string> ExternalFunctionNames, ExternalObjectNames;
 
-    IA64AsmPrinter(std::ostream &O, TargetMachine &TM, TargetAsmInfo *T)
+    IA64AsmPrinter(std::ostream &O, TargetMachine &TM, const TargetAsmInfo *T)
       : AsmPrinter(O, TM, T) {
     }
 
@@ -125,6 +104,8 @@ namespace {
       printOp(MI->getOperand(OpNo), true); // this is a br.call instruction
     }
 
+    std::string getSectionForFunction(const Function &F) const;
+
     void printMachineInstruction(const MachineInstr *MI);
     void printOp(const MachineOperand &MO, bool isBRCALLinsn= false);
     bool runOnMachineFunction(MachineFunction &F);
@@ -138,6 +119,11 @@ namespace {
 #include "IA64GenAsmWriter.inc"
 
 
+std::string IA64AsmPrinter::getSectionForFunction(const Function &F) const {
+  // This means "Allocated instruXions in mem, initialized".
+  return "\n\t.section .text, \"ax\", \"progbits\"\n";
+}
+
 /// runOnMachineFunction - This uses the printMachineInstruction()
 /// method to print assembly for each instruction.
 ///
@@ -148,10 +134,10 @@ bool IA64AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   // Print out constants referenced by the function
   EmitConstantPool(MF.getConstantPool());
 
+  const Function *F = MF.getFunction();
+  SwitchToTextSection(getSectionForFunction(*F).c_str(), F);
+
   // Print out labels for the function.
-  SwitchToTextSection("\n\t.section .text, \"ax\", \"progbits\"\n", 
-                      MF.getFunction());
-  // ^^  means "Allocated instruXions in mem, initialized"
   EmitAlignment(5);
   O << "\t.global\t" << CurrentFnName << "\n";
   O << "\t.type\t" << CurrentFnName << ", @function\n";
@@ -161,7 +147,7 @@ bool IA64AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
        I != E; ++I) {
     // Print a label for the basic block if there are any predecessors.
-    if (I->pred_begin() != I->pred_end()) {
+    if (!I->pred_empty()) {
       printBasicBlockLabel(I, true);
       O << '\n';
     }
@@ -207,17 +193,17 @@ void IA64AsmPrinter::printOp(const MachineOperand &MO,
     bool Needfptr=false; // if we're computing an address @ltoff(X), do
                          // we need to decorate it so it becomes
                          // @ltoff(@fptr(X)) ?
-    if (F && !isBRCALLinsn /*&& F->isExternal()*/)
+    if (F && !isBRCALLinsn /*&& F->isDeclaration()*/)
       Needfptr=true;
 
     // if this is the target of a call instruction, we should define
     // the function somewhere (GNU gas has no problem without this, but
     // Intel ias rightly complains of an 'undefined symbol')
 
-    if (F /*&& isBRCALLinsn*/ && F->isExternal())
+    if (F /*&& isBRCALLinsn*/ && F->isDeclaration())
       ExternalFunctionNames.insert(Mang->getValueName(MO.getGlobal()));
     else
-      if (GV->isExternal()) // e.g. stuff like 'stdin'
+      if (GV->isDeclaration()) // e.g. stuff like 'stdin'
         ExternalObjectNames.insert(Mang->getValueName(MO.getGlobal()));
 
     if (!isBRCALLinsn)
@@ -262,13 +248,13 @@ void IA64AsmPrinter::printMachineInstruction(const MachineInstr *MI) {
 }
 
 bool IA64AsmPrinter::doInitialization(Module &M) {
-  AsmPrinter::doInitialization(M);
+  bool Result = AsmPrinter::doInitialization(M);
 
   O << "\n.ident \"LLVM-ia64\"\n\n"
     << "\t.psr    lsb\n"  // should be "msb" on HP-UX, for starters
     << "\t.radix  C\n"
     << "\t.psr    abi64\n"; // we only support 64 bits for now
-  return false;
+  return Result;
 }
 
 bool IA64AsmPrinter::doFinalization(Module &M) {
@@ -285,24 +271,22 @@ bool IA64AsmPrinter::doFinalization(Module &M) {
       O << "\n\n";
       std::string name = Mang->getValueName(I);
       Constant *C = I->getInitializer();
-      unsigned Size = TD->getTypeSize(C->getType());
-      unsigned Align = TD->getTypeAlignmentShift(C->getType());
+      unsigned Size = TD->getABITypeSize(C->getType());
+      unsigned Align = TD->getPreferredTypeAlignmentShift(C->getType());
       
       if (C->isNullValue() &&
           (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
            I->hasWeakLinkage() /* FIXME: Verify correct */)) {
         SwitchToDataSection(".data", I);
         if (I->hasInternalLinkage()) {
-          O << "\t.lcomm " << name << "#," << TD->getTypeSize(C->getType())
+          O << "\t.lcomm " << name << "#," << TD->getABITypeSize(C->getType())
           << "," << (1 << Align);
-          O << "\t\t// ";
+          O << "\n";
         } else {
-          O << "\t.common " << name << "#," << TD->getTypeSize(C->getType())
+          O << "\t.common " << name << "#," << TD->getABITypeSize(C->getType())
           << "," << (1 << Align);
-          O << "\t\t// ";
+          O << "\n";
         }
-        WriteAsOperand(O, I, true, true, &M);
-        O << "\n";
       } else {
         switch (I->getLinkage()) {
           case GlobalValue::LinkOnceLinkage:
@@ -324,18 +308,22 @@ bool IA64AsmPrinter::doFinalization(Module &M) {
             SwitchToDataSection(C->isNullValue() ? ".bss" : ".data", I);
             break;
           case GlobalValue::GhostLinkage:
-            std::cerr << "GhostLinkage cannot appear in IA64AsmPrinter!\n";
+            cerr << "GhostLinkage cannot appear in IA64AsmPrinter!\n";
+            abort();
+          case GlobalValue::DLLImportLinkage:
+            cerr << "DLLImport linkage is not supported by this target!\n";
+            abort();
+          case GlobalValue::DLLExportLinkage:
+            cerr << "DLLExport linkage is not supported by this target!\n";
             abort();
+          default:
+            assert(0 && "Unknown linkage type!");            
         }
         
         EmitAlignment(Align);
         O << "\t.type " << name << ",@object\n";
         O << "\t.size " << name << "," << Size << "\n";
-        O << name << ":\t\t\t\t// ";
-        WriteAsOperand(O, I, true, true, &M);
-        O << " = ";
-        WriteAsOperand(O, C, false, false, &M);
-        O << "\n";
+        O << name << ":\t\t\t\t// " << *C << "\n";
         EmitGlobalConstant(C);
       }
     }
@@ -356,8 +344,7 @@ bool IA64AsmPrinter::doFinalization(Module &M) {
   }
   O << "\n\n";
   
-  AsmPrinter::doFinalization(M);
-  return false; // success
+  return AsmPrinter::doFinalization(M);
 }
 
 /// createIA64CodePrinterPass - Returns a pass that prints the IA64
@@ -366,8 +353,7 @@ bool IA64AsmPrinter::doFinalization(Module &M) {
 ///
 FunctionPass *llvm::createIA64CodePrinterPass(std::ostream &o,
                                               IA64TargetMachine &tm) {
-  IA64TargetAsmInfo *TAI = new IA64TargetAsmInfo();
-  return new IA64AsmPrinter(o, tm, TAI);
+  return new IA64AsmPrinter(o, tm, tm.getTargetAsmInfo());
 }