Revert 49006 for the moment.
[oota-llvm.git] / lib / Target / PowerPC / PPCAsmPrinter.cpp
index 9e5f1032bafd13dc1cfbe52fc9ae4ec5759e6b98..2537d67ddaadf82858daa5bb3a1d8e819d7b401e 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineInstrBuilder.h"
 #include "llvm/Support/Mangler.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Target/TargetAsmInfo.h"
-#include "llvm/Target/MRegisterInfo.h"
+#include "llvm/Target/TargetRegisterInfo.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/ADT/Statistic.h"
@@ -104,7 +105,7 @@ namespace {
     ///
     void printRegister(const MachineOperand &MO, bool R0AsZero) {
       unsigned RegNo = MO.getReg();
-      assert(MRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??");
+      assert(TargetRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??");
       
       // If we should use 0 for R0.
       if (R0AsZero && RegNo == PPC::R0) {
@@ -112,7 +113,7 @@ namespace {
         return;
       }
       
-      const char *RegName = TM.getRegisterInfo()->get(RegNo).Name;
+      const char *RegName = TM.getRegisterInfo()->get(RegNo).AsmName;
       // Linux assembler (Others?) does not take register mnemonics.
       // FIXME - What about special registers used in mfspr/mtspr?
       if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName);
@@ -124,7 +125,7 @@ namespace {
       if (MO.isRegister()) {
         printRegister(MO, false);
       } else if (MO.isImmediate()) {
-        O << MO.getImmedValue();
+        O << MO.getImm();
       } else {
         printOp(MO);
       }
@@ -137,29 +138,29 @@ namespace {
     
     
     void printS5ImmOperand(const MachineInstr *MI, unsigned OpNo) {
-      char value = MI->getOperand(OpNo).getImmedValue();
+      char value = MI->getOperand(OpNo).getImm();
       value = (value << (32-5)) >> (32-5);
       O << (int)value;
     }
     void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo) {
-      unsigned char value = MI->getOperand(OpNo).getImmedValue();
+      unsigned char value = MI->getOperand(OpNo).getImm();
       assert(value <= 31 && "Invalid u5imm argument!");
       O << (unsigned int)value;
     }
     void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo) {
-      unsigned char value = MI->getOperand(OpNo).getImmedValue();
+      unsigned char value = MI->getOperand(OpNo).getImm();
       assert(value <= 63 && "Invalid u6imm argument!");
       O << (unsigned int)value;
     }
     void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo) {
-      O << (short)MI->getOperand(OpNo).getImmedValue();
+      O << (short)MI->getOperand(OpNo).getImm();
     }
     void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo) {
-      O << (unsigned short)MI->getOperand(OpNo).getImmedValue();
+      O << (unsigned short)MI->getOperand(OpNo).getImm();
     }
     void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo) {
       if (MI->getOperand(OpNo).isImmediate()) {
-        O << (short)(MI->getOperand(OpNo).getImmedValue()*4);
+        O << (short)(MI->getOperand(OpNo).getImm()*4);
       } else {
         O << "lo16(";
         printOp(MI->getOperand(OpNo));
@@ -173,7 +174,7 @@ namespace {
       // Branches can take an immediate operand.  This is used by the branch
       // selection pass to print $+8, an eight byte displacement from the PC.
       if (MI->getOperand(OpNo).isImmediate()) {
-        O << "$+" << MI->getOperand(OpNo).getImmedValue()*4;
+        O << "$+" << MI->getOperand(OpNo).getImm()*4;
       } else {
         printOp(MI->getOperand(OpNo));
       }
@@ -205,7 +206,7 @@ namespace {
       printOp(MI->getOperand(OpNo));
     }
     void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo) {
-     O << (int)MI->getOperand(OpNo).getImmedValue()*4;
+     O << (int)MI->getOperand(OpNo).getImm()*4;
     }
     void printPICLabel(const MachineInstr *MI, unsigned OpNo) {
       O << "\"L" << getFunctionNumber() << "$pb\"\n";
@@ -322,10 +323,11 @@ namespace {
   struct VISIBILITY_HIDDEN DarwinAsmPrinter : public PPCAsmPrinter {
   
     DwarfWriter DW;
+    MachineModuleInfo *MMI;
 
     DarwinAsmPrinter(std::ostream &O, PPCTargetMachine &TM,
                      const TargetAsmInfo *T)
-      : PPCAsmPrinter(O, TM, T), DW(O, this, T) {
+      : PPCAsmPrinter(O, TM, T), DW(O, this, T), MMI(0) {
     }
 
     virtual const char *getPassName() const {
@@ -359,16 +361,16 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
     return;
 
   case MachineOperand::MO_MachineBasicBlock:
-    printBasicBlockLabel(MO.getMachineBasicBlock());
+    printBasicBlockLabel(MO.getMBB());
     return;
   case MachineOperand::MO_JumpTableIndex:
     O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
-      << '_' << MO.getJumpTableIndex();
+      << '_' << MO.getIndex();
     // FIXME: PIC relocation model
     return;
   case MachineOperand::MO_ConstantPoolIndex:
     O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber()
-      << '_' << MO.getConstantPoolIndex();
+      << '_' << MO.getIndex();
     return;
   case MachineOperand::MO_ExternalSymbol:
     // Computing the address of an external symbol, not calling it.
@@ -508,14 +510,14 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
   // Check for slwi/srwi mnemonics.
   if (MI->getOpcode() == PPC::RLWINM) {
     bool FoundMnemonic = false;
-    unsigned char SH = MI->getOperand(2).getImmedValue();
-    unsigned char MB = MI->getOperand(3).getImmedValue();
-    unsigned char ME = MI->getOperand(4).getImmedValue();
+    unsigned char SH = MI->getOperand(2).getImm();
+    unsigned char MB = MI->getOperand(3).getImm();
+    unsigned char ME = MI->getOperand(4).getImm();
     if (SH <= 31 && MB == 0 && ME == (31-SH)) {
-      O << "slwi "; FoundMnemonic = true;
+      O << "\tslwi "; FoundMnemonic = true;
     }
     if (SH <= 31 && MB == (32-SH) && ME == 31) {
-      O << "srwi "; FoundMnemonic = true;
+      O << "\tsrwi "; FoundMnemonic = true;
       SH = 32-SH;
     }
     if (FoundMnemonic) {
@@ -527,7 +529,7 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
     }
   } else if (MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) {
     if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
-      O << "mr ";
+      O << "\tmr ";
       printOperand(MI, 0);
       O << ", ";
       printOperand(MI, 1);
@@ -535,11 +537,11 @@ void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
       return;
     }
   } else if (MI->getOpcode() == PPC::RLDICR) {
-    unsigned char SH = MI->getOperand(2).getImmedValue();
-    unsigned char ME = MI->getOperand(3).getImmedValue();
+    unsigned char SH = MI->getOperand(2).getImm();
+    unsigned char ME = MI->getOperand(3).getImm();
     // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
     if (63-SH == ME) {
-      O << "sldi ";
+      O << "\tsldi ";
       printOperand(MI, 0);
       O << ", ";
       printOperand(MI, 1);
@@ -602,13 +604,12 @@ bool LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
        I != E; ++I) {
     // Print a label for the basic block.
     if (I != MF.begin()) {
-      printBasicBlockLabel(I, true);
+      printBasicBlockLabel(I, true, true);
       O << '\n';
     }
     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
          II != E; ++II) {
       // Print the assembly for the instruction.
-      O << "\t";
       printMachineInstruction(II);
     }
   }
@@ -638,6 +639,15 @@ bool LinuxAsmPrinter::doInitialization(Module &M) {
   return Result;
 }
 
+/// PrintUnmangledNameSafely - Print out the printable characters in the name.
+/// Don't print things like \n or \0.
+static void PrintUnmangledNameSafely(const Value *V, std::ostream &OS) {
+  for (const char *Name = V->getNameStart(), *E = Name+V->getNameLen();
+       Name != E; ++Name)
+    if (isprint(*Name))
+      OS << *Name;
+}
+
 bool LinuxAsmPrinter::doFinalization(Module &M) {
   const TargetData *TD = TM.getTargetData();
 
@@ -657,17 +667,19 @@ bool LinuxAsmPrinter::doFinalization(Module &M) {
         O << Directive << name << "\n";
     
     Constant *C = I->getInitializer();
-    unsigned Size = TD->getTypeSize(C->getType());
+    unsigned Size = TD->getABITypeSize(C->getType());
     unsigned Align = TD->getPreferredAlignmentLog(I);
 
     if (C->isNullValue() && /* FIXME: Verify correct */
+        !I->hasSection() &&
         (I->hasInternalLinkage() || I->hasWeakLinkage() ||
-         I->hasLinkOnceLinkage() ||
-         (I->hasExternalLinkage() && !I->hasSection()))) {
+         I->hasLinkOnceLinkage() || I->hasExternalLinkage())) {
       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
       if (I->hasExternalLinkage()) {
         O << "\t.global " << name << '\n';
         O << "\t.type " << name << ", @object\n";
+        if (TAI->getBSSSection())
+          SwitchToDataSection(TAI->getBSSSection(), I);
         O << name << ":\n";
         O << "\t.zero " << Size << "\n";
       } else if (I->hasInternalLinkage()) {
@@ -677,7 +689,9 @@ bool LinuxAsmPrinter::doFinalization(Module &M) {
         SwitchToDataSection("\t.data", I);
         O << ".comm " << name << "," << Size;
       }
-      O << "\t\t" << TAI->getCommentString() << " '" << I->getName() << "'\n";
+      O << "\t\t" << TAI->getCommentString() << " '";
+      PrintUnmangledNameSafely(I, O);
+      O << "'\n";
     } else {
       switch (I->getLinkage()) {
       case GlobalValue::LinkOnceLinkage:
@@ -724,8 +738,9 @@ bool LinuxAsmPrinter::doFinalization(Module &M) {
       }
 
       EmitAlignment(Align, I);
-      O << name << ":\t\t\t\t" << TAI->getCommentString() << " '"
-        << I->getName() << "'\n";
+      O << name << ":\t\t\t\t" << TAI->getCommentString() << " '";
+      PrintUnmangledNameSafely(I, O);
+      O << "'\n";
 
       // If the initializer is a extern weak symbol, remember to emit the weak
       // reference!
@@ -764,7 +779,7 @@ std::string DarwinAsmPrinter::getSectionForFunction(const Function &F) const {
   case Function::InternalLinkage: return TAI->getTextSection();
   case Function::WeakLinkage:
   case Function::LinkOnceLinkage:
-    return ".section __TEXT,__textcoal_nt,coalesced,pure_instructions";
+    return "\t.section __TEXT,__textcoal_nt,coalesced,pure_instructions";
   }
 }
 
@@ -772,11 +787,13 @@ std::string DarwinAsmPrinter::getSectionForFunction(const Function &F) const {
 /// method to print assembly for each instruction.
 ///
 bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
-  DW.SetModuleInfo(&getAnalysis<MachineModuleInfo>());
+  // We need this for Personality functions.
+  MMI = &getAnalysis<MachineModuleInfo>();
+  DW.SetModuleInfo(MMI);
 
   SetupMachineFunction(MF);
   O << "\n\n";
-  
+
   // Print out constants referenced by the function
   EmitConstantPool(MF.getConstantPool());
 
@@ -802,24 +819,31 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
     if (const char *Directive = TAI->getHiddenDirective())
       O << Directive << CurrentFnName << "\n";
   
-  EmitAlignment(4, F);
+  EmitAlignment(OptimizeForSize ? 2 : 4, F);
   O << CurrentFnName << ":\n";
 
   // Emit pre-function debug information.
   DW.BeginFunction(&MF);
 
+  // If the function is empty, then we need to emit *something*. Otherwise, the
+  // function's label might be associated with something that it wasn't meant to
+  // be associated with. We emit a noop in this situation.
+  MachineFunction::iterator I = MF.begin();
+
+  if (++I == MF.end() && MF.front().empty())
+    O << "\tnop\n";
+
   // Print out code for the function.
   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
        I != E; ++I) {
     // Print a label for the basic block.
     if (I != MF.begin()) {
-      printBasicBlockLabel(I, true);
+      printBasicBlockLabel(I, true, true);
       O << '\n';
     }
-    for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
-         II != E; ++II) {
+    for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
+         II != IE; ++II) {
       // Print the assembly for the instruction.
-      O << "\t";
       printMachineInstruction(II);
     }
   }
@@ -836,7 +860,8 @@ bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
 
 
 bool DarwinAsmPrinter::doInitialization(Module &M) {
-  static const char *CPUDirectives[] = {
+  static const char *const CPUDirectives[] = {
+    "",
     "ppc",
     "ppc601",
     "ppc602",
@@ -864,13 +889,13 @@ bool DarwinAsmPrinter::doInitialization(Module &M) {
   
   // Prime text sections so they are adjacent.  This reduces the likelihood a
   // large data or debug section causes a branch to exceed 16M limit.
-  SwitchToTextSection(".section __TEXT,__textcoal_nt,coalesced,"
+  SwitchToTextSection("\t.section __TEXT,__textcoal_nt,coalesced,"
                       "pure_instructions");
   if (TM.getRelocationModel() == Reloc::PIC_) {
-    SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs,"
+    SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs,"
                           "pure_instructions,32");
   } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
-    SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs,"
+    SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs,"
                         "pure_instructions,16");
   }
   SwitchToTextSection(TAI->getTextSection());
@@ -907,7 +932,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
     
     Constant *C = I->getInitializer();
     const Type *Type = C->getType();
-    unsigned Size = TD->getTypeSize(Type);
+    unsigned Size = TD->getABITypeSize(Type);
     unsigned Align = TD->getPreferredAlignmentLog(I);
 
     if (C->isNullValue() && /* FIXME: Verify correct */
@@ -925,15 +950,20 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
       } else {
         SwitchToDataSection("\t.data", I);
         O << ".comm " << name << "," << Size;
+        // Darwin 9 and above support aligned common data.
+        if (Subtarget.isDarwin9())
+          O << "," << Align;
       }
-      O << "\t\t" << TAI->getCommentString() << " '" << I->getName() << "'\n";
+      O << "\t\t" << TAI->getCommentString() << " '";
+      PrintUnmangledNameSafely(I, O);
+      O << "'\n";
     } else {
       switch (I->getLinkage()) {
       case GlobalValue::LinkOnceLinkage:
       case GlobalValue::WeakLinkage:
         O << "\t.globl " << name << '\n'
           << "\t.weak_definition " << name << '\n';
-        SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I);
+        SwitchToDataSection("\t.section __DATA,__datacoal_nt,coalesced", I);
         break;
       case GlobalValue::AppendingLinkage:
         // FIXME: appending linkage variables should go into a section of
@@ -950,8 +980,11 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
             break;
           }
         }
-
-        if (!I->isConstant())
+        if (I->hasSection()) {
+          // Honor all section names on Darwin; ObjC uses this
+          std::string SectionName = ".section " + I->getSection();
+          SwitchToDataSection(SectionName.c_str());
+        } else if (!I->isConstant())
           SwitchToDataSection(TAI->getDataSection(), I);
         else {
           // Read-only data.
@@ -980,8 +1013,9 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
       }
 
       EmitAlignment(Align, I);
-      O << name << ":\t\t\t\t" << TAI->getCommentString() << " '"
-        << I->getName() << "'\n";
+      O << name << ":\t\t\t\t" << TAI->getCommentString() << " '";
+      PrintUnmangledNameSafely(I, O);
+      O << "'\n";
 
       // If the initializer is a extern weak symbol, remember to emit the weak
       // reference!
@@ -1000,7 +1034,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
   if (TM.getRelocationModel() == Reloc::PIC_) {
     for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
          i != e; ++i) {
-      SwitchToTextSection(".section __TEXT,__picsymbolstub1,symbol_stubs,"
+      SwitchToTextSection("\t.section __TEXT,__picsymbolstub1,symbol_stubs,"
                           "pure_instructions,32");
       EmitAlignment(4);
       O << "L" << *i << "$stub:\n";
@@ -1028,7 +1062,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
   } else {
     for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
          i != e; ++i) {
-      SwitchToTextSection(".section __TEXT,__symbol_stub1,symbol_stubs,"
+      SwitchToTextSection("\t.section __TEXT,__symbol_stub1,symbol_stubs,"
                           "pure_instructions,16");
       EmitAlignment(4);
       O << "L" << *i << "$stub:\n";
@@ -1052,8 +1086,17 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
 
   O << "\n";
 
+  if (ExceptionHandling && TAI->doesSupportExceptionHandling() && MMI) {
+    // Add the (possibly multiple) personalities to the set of global values.
+    const std::vector<Function *>& Personalities = MMI->getPersonalities();
+
+    for (std::vector<Function *>::const_iterator I = Personalities.begin(),
+           E = Personalities.end(); I != E; ++I)
+      if (*I) GVStubs.insert("_" + (*I)->getName());
+  }
+
   // Output stubs for external and common global variables.
-  if (GVStubs.begin() != GVStubs.end()) {
+  if (!GVStubs.empty()) {
     SwitchToDataSection(".non_lazy_symbol_pointer");
     for (std::set<std::string>::iterator I = GVStubs.begin(),
          E = GVStubs.end(); I != E; ++I) {