Make the aix asm printer interface properly with the parent class
[oota-llvm.git] / lib / Target / PowerPC / PPCAsmPrinter.cpp
index d68b7401db7979901e532f6d07433485b904e7a5..7969d02b23e7199573fb11d5d1ad3b39eac2866f 100644 (file)
@@ -1,4 +1,4 @@
-//===-- PowerPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --===//
+//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --------=//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -17,9 +17,9 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "asmprinter"
-#include "PowerPC.h"
-#include "PowerPCTargetMachine.h"
-#include "PowerPCSubtarget.h"
+#include "PPC.h"
+#include "PPCTargetMachine.h"
+#include "PPCSubtarget.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
@@ -43,10 +43,10 @@ using namespace llvm;
 namespace {
   Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
 
-  struct PowerPCAsmPrinter : public AsmPrinter {
+  struct PPCAsmPrinter : public AsmPrinter {
     std::set<std::string> FnStubs, GVStubs, LinkOnceStubs;
 
-    PowerPCAsmPrinter(std::ostream &O, TargetMachine &TM)
+    PPCAsmPrinter(std::ostream &O, TargetMachine &TM)
       : AsmPrinter(O, TM), LabelNumber(0) {}
 
     /// Unique incrementer for label values for referencing Global values.
@@ -57,8 +57,8 @@ namespace {
       return "PowerPC Assembly Printer";
     }
 
-    PowerPCTargetMachine &getTM() {
-      return static_cast<PowerPCTargetMachine&>(TM);
+    PPCTargetMachine &getTM() {
+      return static_cast<PPCTargetMachine&>(TM);
     }
 
     unsigned enumRegToMachineReg(unsigned enumReg) {
@@ -117,6 +117,10 @@ namespace {
                             MVT::ValueType VT) {
       O << (unsigned short)MI->getOperand(OpNo).getImmedValue();
     }
+    void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo,
+                              MVT::ValueType VT) {
+      O << (short)MI->getOperand(OpNo).getImmedValue()*4;
+    }
     void printBranchOperand(const MachineInstr *MI, unsigned OpNo,
                             MVT::ValueType VT) {
       // Branches can take an immediate operand.  This is used by the branch
@@ -175,10 +179,10 @@ namespace {
   /// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS
   /// X
   ///
-  struct DarwinAsmPrinter : public PowerPCAsmPrinter {
+  struct DarwinAsmPrinter : public PPCAsmPrinter {
 
     DarwinAsmPrinter(std::ostream &O, TargetMachine &TM)
-      : PowerPCAsmPrinter(O, TM) {
+      : PPCAsmPrinter(O, TM) {
       CommentString = ";";
       GlobalPrefix = "_";
       ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
@@ -198,15 +202,15 @@ namespace {
 
   /// AIXAsmPrinter - PowerPC assembly printer, customized for AIX
   ///
-  struct AIXAsmPrinter : public PowerPCAsmPrinter {
+  struct AIXAsmPrinter : public PPCAsmPrinter {
     /// Map for labels corresponding to global variables
     ///
     std::map<const GlobalVariable*,std::string> GVToLabelMap;
 
     AIXAsmPrinter(std::ostream &O, TargetMachine &TM)
-      : PowerPCAsmPrinter(O, TM) {
+      : PPCAsmPrinter(O, TM) {
       CommentString = "#";
-      GlobalPrefix = "_";
+      GlobalPrefix = ".";
       ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
       Data64bitsDirective = 0;       // we can't emit a 64-bit unit
       AlignmentIsInBytes = false;    // Alignment is by power of 2.
@@ -252,9 +256,9 @@ FunctionPass *llvm::createAIXAsmPrinter(std::ostream &o, TargetMachine &tm) {
 }
 
 // Include the auto-generated portion of the assembly writer
-#include "PowerPCGenAsmWriter.inc"
+#include "PPCGenAsmWriter.inc"
 
-void PowerPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
+void PPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
   const MRegisterInfo &RI = *TM.getRegisterInfo();
   int new_symbol;
 
@@ -290,7 +294,7 @@ void PowerPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
   }
 
   case MachineOperand::MO_ConstantPoolIndex:
-    O << ".CPI" << CurrentFnName << "_" << MO.getConstantPoolIndex();
+    O << "LCPI" << CurrentFnName << "_" << MO.getConstantPoolIndex();
     return;
 
   case MachineOperand::MO_ExternalSymbol:
@@ -340,8 +344,9 @@ void PowerPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) {
 /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to
 /// the current output stream.
 ///
-void PowerPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
+void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   ++EmittedInsts;
+
   // Check for slwi/srwi mnemonics.
   if (MI->getOpcode() == PPC::RLWINM) {
     bool FoundMnemonic = false;
@@ -384,8 +389,9 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
   // Print out labels for the function.
   O << "\t.text\n";
-  emitAlignment(2);
-  O << "\t.globl\t" << CurrentFnName << "\n";
+  emitAlignment(4);
+  if (!MF.getFunction()->hasInternalLinkage())
+    O << "\t.globl\t" << CurrentFnName << "\n";
   O << CurrentFnName << ":\n";
 
   // Print out code for the function.
@@ -430,7 +436,7 @@ void DarwinAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
       emitAlignment(3);
     else
       emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType()));
-    O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString
+    O << "LCPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString
       << *CP[i] << "\n";
     emitGlobalConstant(CP[i]);
   }
@@ -465,9 +471,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
           O << ".lcomm " << name << "," << Size << "," << Align;
         else
           O << ".comm " << name << "," << Size;
-        O << "\t\t; ";
-        WriteAsOperand(O, I, true, true, &M);
-        O << '\n';
+        O << "\t\t; '" << I->getName() << "'\n";
       } else {
         switch (I->getLinkage()) {
         case GlobalValue::LinkOnceLinkage:
@@ -497,11 +501,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
         }
 
         emitAlignment(Align);
-        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; '" << I->getName() << "'\n";
         emitGlobalConstant(C);
       }
     }
@@ -567,6 +567,13 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
       << "\t.long\t" << *i << '\n';
   }
 
+  // Funny Darwin hack: This flag tells the linker that no global symbols
+  // contain code that falls through to other global symbols (e.g. the obvious
+  // implementation of multiple entry points).  If this doesn't occur, the
+  // linker can safely perform dead code stripping.  Since LLVM never generates
+  // code that does this, it is always safe to set.
+  O << "\t.subsections_via_symbols\n";
+
   AsmPrinter::doFinalization(M);
   return false; // success
 }
@@ -633,7 +640,7 @@ void AIXAsmPrinter::printConstantPool(MachineConstantPool *MCP) {
     O << "\t.const\n";
     O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType())
       << "\n";
-    O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t;"
+    O << "LCPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t;"
       << *CP[i] << "\n";
     emitGlobalConstant(CP[i]);
   }
@@ -684,7 +691,7 @@ bool AIXAsmPrinter::doInitialization(Module &M) {
     O << '\n';
   }
 
-  Mang = new Mangler(M, ".");
+  AsmPrinter::doInitialization(M);
   return false; // success
 }
 
@@ -704,14 +711,13 @@ bool AIXAsmPrinter::doFinalization(Module &M) {
         << "," << Log2_32((unsigned)TD.getTypeAlignment(I->getType()));
     }
     O << "\t\t# ";
-    WriteAsOperand(O, I, true, true, &M);
+    WriteAsOperand(O, I, false, true, &M);
     O << "\n";
   }
 
   O << "_section_.text:\n"
     << "\t.csect .data[RW],3\n"
     << "\t.llong _section_.text\n";
-
-  delete Mang;
+  AsmPrinter::doFinalization(M);
   return false; // success
 }