LLVM API Documentation

PPCAsmPrinter.cpp

Go to the documentation of this file.
00001 //===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --------=//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains a printer that converts from our internal representation
00011 // of machine-dependent LLVM code to PowerPC assembly language. This printer is
00012 // the output mechanism used by `llc'.
00013 //
00014 // Documentation at http://developer.apple.com/documentation/DeveloperTools/
00015 // Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
00016 //
00017 //===----------------------------------------------------------------------===//
00018 
00019 #define DEBUG_TYPE "asmprinter"
00020 #include "PPC.h"
00021 #include "PPCTargetMachine.h"
00022 #include "PPCSubtarget.h"
00023 #include "llvm/Constants.h"
00024 #include "llvm/DerivedTypes.h"
00025 #include "llvm/Module.h"
00026 #include "llvm/Assembly/Writer.h"
00027 #include "llvm/CodeGen/AsmPrinter.h"
00028 #include "llvm/CodeGen/DwarfWriter.h"
00029 #include "llvm/CodeGen/MachineDebugInfo.h"
00030 #include "llvm/CodeGen/MachineFunctionPass.h"
00031 #include "llvm/CodeGen/MachineInstr.h"
00032 #include "llvm/Support/Mangler.h"
00033 #include "llvm/Support/MathExtras.h"
00034 #include "llvm/Support/CommandLine.h"
00035 #include "llvm/Support/Debug.h"
00036 #include "llvm/Target/MRegisterInfo.h"
00037 #include "llvm/Target/TargetInstrInfo.h"
00038 #include "llvm/Target/TargetOptions.h"
00039 #include "llvm/ADT/Statistic.h"
00040 #include "llvm/ADT/StringExtras.h"
00041 #include <iostream>
00042 #include <set>
00043 using namespace llvm;
00044 
00045 namespace {
00046   Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
00047 
00048   class PPCAsmPrinter : public AsmPrinter {
00049   public:
00050     std::set<std::string> FnStubs, GVStubs;
00051     
00052     PPCAsmPrinter(std::ostream &O, TargetMachine &TM)
00053       : AsmPrinter(O, TM) {}
00054 
00055     virtual const char *getPassName() const {
00056       return "PowerPC Assembly Printer";
00057     }
00058 
00059     PPCTargetMachine &getTM() {
00060       return static_cast<PPCTargetMachine&>(TM);
00061     }
00062 
00063     unsigned enumRegToMachineReg(unsigned enumReg) {
00064       switch (enumReg) {
00065       default: assert(0 && "Unhandled register!"); break;
00066       case PPC::CR0:  return  0;
00067       case PPC::CR1:  return  1;
00068       case PPC::CR2:  return  2;
00069       case PPC::CR3:  return  3;
00070       case PPC::CR4:  return  4;
00071       case PPC::CR5:  return  5;
00072       case PPC::CR6:  return  6;
00073       case PPC::CR7:  return  7;
00074       }
00075       abort();
00076     }
00077 
00078     /// printInstruction - This method is automatically generated by tablegen
00079     /// from the instruction set description.  This method returns true if the
00080     /// machine instruction was sufficiently described to print it, otherwise it
00081     /// returns false.
00082     bool printInstruction(const MachineInstr *MI);
00083 
00084     void printMachineInstruction(const MachineInstr *MI);
00085     void printOp(const MachineOperand &MO);
00086 
00087     void printOperand(const MachineInstr *MI, unsigned OpNo) {
00088       const MachineOperand &MO = MI->getOperand(OpNo);
00089       if (MO.getType() == MachineOperand::MO_MachineRegister) {
00090         assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physreg??");
00091         O << TM.getRegisterInfo()->get(MO.getReg()).Name;
00092       } else if (MO.isImmediate()) {
00093         O << MO.getImmedValue();
00094       } else {
00095         printOp(MO);
00096       }
00097     }
00098     
00099     bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
00100                          unsigned AsmVariant, const char *ExtraCode);
00101     bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
00102                                unsigned AsmVariant, const char *ExtraCode);
00103     
00104     
00105     void printS5ImmOperand(const MachineInstr *MI, unsigned OpNo) {
00106       char value = MI->getOperand(OpNo).getImmedValue();
00107       value = (value << (32-5)) >> (32-5);
00108       O << (int)value;
00109     }
00110     void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo) {
00111       unsigned char value = MI->getOperand(OpNo).getImmedValue();
00112       assert(value <= 31 && "Invalid u5imm argument!");
00113       O << (unsigned int)value;
00114     }
00115     void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo) {
00116       unsigned char value = MI->getOperand(OpNo).getImmedValue();
00117       assert(value <= 63 && "Invalid u6imm argument!");
00118       O << (unsigned int)value;
00119     }
00120     void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo) {
00121       O << (short)MI->getOperand(OpNo).getImmedValue();
00122     }
00123     void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo) {
00124       O << (unsigned short)MI->getOperand(OpNo).getImmedValue();
00125     }
00126     void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo) {
00127       O << (short)MI->getOperand(OpNo).getImmedValue()*4;
00128     }
00129     void printBranchOperand(const MachineInstr *MI, unsigned OpNo) {
00130       // Branches can take an immediate operand.  This is used by the branch
00131       // selection pass to print $+8, an eight byte displacement from the PC.
00132       if (MI->getOperand(OpNo).isImmediate()) {
00133         O << "$+" << MI->getOperand(OpNo).getImmedValue();
00134       } else {
00135         printOp(MI->getOperand(OpNo));
00136       }
00137     }
00138     void printCallOperand(const MachineInstr *MI, unsigned OpNo) {
00139       const MachineOperand &MO = MI->getOperand(OpNo);
00140       if (TM.getRelocationModel() != Reloc::Static) {
00141         if (MO.getType() == MachineOperand::MO_GlobalAddress) {
00142           GlobalValue *GV = MO.getGlobal();
00143           if (((GV->isExternal() || GV->hasWeakLinkage() ||
00144                 GV->hasLinkOnceLinkage()))) {
00145             // Dynamically-resolved functions need a stub for the function.
00146             std::string Name = Mang->getValueName(GV);
00147             FnStubs.insert(Name);
00148             O << "L" << Name << "$stub";
00149             return;
00150           }
00151         }
00152         if (MO.getType() == MachineOperand::MO_ExternalSymbol) {
00153           std::string Name(GlobalPrefix); Name += MO.getSymbolName();
00154           FnStubs.insert(Name);
00155           O << "L" << Name << "$stub";
00156           return;
00157         }
00158       }
00159       
00160       printOp(MI->getOperand(OpNo));
00161     }
00162     void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo) {
00163      O << (int)MI->getOperand(OpNo).getImmedValue()*4;
00164     }
00165     void printPICLabel(const MachineInstr *MI, unsigned OpNo) {
00166       O << "\"L" << getFunctionNumber() << "$pb\"\n";
00167       O << "\"L" << getFunctionNumber() << "$pb\":";
00168     }
00169     void printSymbolHi(const MachineInstr *MI, unsigned OpNo) {
00170       if (MI->getOperand(OpNo).isImmediate()) {
00171         printS16ImmOperand(MI, OpNo);
00172       } else {
00173         O << "ha16(";
00174         printOp(MI->getOperand(OpNo));
00175         if (TM.getRelocationModel() == Reloc::PIC)
00176           O << "-\"L" << getFunctionNumber() << "$pb\")";
00177         else
00178           O << ')';
00179       }
00180     }
00181     void printSymbolLo(const MachineInstr *MI, unsigned OpNo) {
00182       if (MI->getOperand(OpNo).isImmediate()) {
00183         printS16ImmOperand(MI, OpNo);
00184       } else {
00185         O << "lo16(";
00186         printOp(MI->getOperand(OpNo));
00187         if (TM.getRelocationModel() == Reloc::PIC)
00188           O << "-\"L" << getFunctionNumber() << "$pb\")";
00189         else
00190           O << ')';
00191       }
00192     }
00193     void printcrbitm(const MachineInstr *MI, unsigned OpNo) {
00194       unsigned CCReg = MI->getOperand(OpNo).getReg();
00195       unsigned RegNo = enumRegToMachineReg(CCReg);
00196       O << (0x80 >> RegNo);
00197     }
00198     // The new addressing mode printers.
00199     void printMemRegImm(const MachineInstr *MI, unsigned OpNo) {
00200       printSymbolLo(MI, OpNo);
00201       O << '(';
00202       if (MI->getOperand(OpNo+1).isRegister() && 
00203           MI->getOperand(OpNo+1).getReg() == PPC::R0)
00204         O << "0";
00205       else
00206         printOperand(MI, OpNo+1);
00207       O << ')';
00208     }
00209     void printMemRegImmShifted(const MachineInstr *MI, unsigned OpNo) {
00210       if (MI->getOperand(OpNo).isImmediate())
00211         printS16X4ImmOperand(MI, OpNo);
00212       else 
00213         printSymbolLo(MI, OpNo);
00214       O << '(';
00215       if (MI->getOperand(OpNo+1).isRegister() && 
00216           MI->getOperand(OpNo+1).getReg() == PPC::R0)
00217         O << "0";
00218       else
00219         printOperand(MI, OpNo+1);
00220       O << ')';
00221     }
00222     
00223     void printMemRegReg(const MachineInstr *MI, unsigned OpNo) {
00224       // When used as the base register, r0 reads constant zero rather than
00225       // the value contained in the register.  For this reason, the darwin
00226       // assembler requires that we print r0 as 0 (no r) when used as the base.
00227       const MachineOperand &MO = MI->getOperand(OpNo);
00228       if (MO.getReg() == PPC::R0)
00229         O << '0';
00230       else
00231         O << TM.getRegisterInfo()->get(MO.getReg()).Name;
00232       O << ", ";
00233       printOperand(MI, OpNo+1);
00234     }
00235     
00236     virtual bool runOnMachineFunction(MachineFunction &F) = 0;
00237     virtual bool doFinalization(Module &M) = 0;
00238     
00239   };
00240 
00241   /// DarwinDwarfWriter - Dwarf debug info writer customized for Darwin/Mac OS X
00242   ///
00243   struct DarwinDwarfWriter : public DwarfWriter {
00244     // Ctor.
00245     DarwinDwarfWriter(std::ostream &o, AsmPrinter *ap)
00246     : DwarfWriter(o, ap)
00247     {
00248       needsSet = true;
00249       DwarfAbbrevSection = ".section __DWARFA,__debug_abbrev";
00250       DwarfInfoSection = ".section __DWARFA,__debug_info";
00251       DwarfLineSection = ".section __DWARFA,__debug_line";
00252       DwarfFrameSection = ".section __DWARFA,__debug_frame";
00253       DwarfPubNamesSection = ".section __DWARFA,__debug_pubnames";
00254       DwarfPubTypesSection = ".section __DWARFA,__debug_pubtypes";
00255       DwarfStrSection = ".section __DWARFA,__debug_str";
00256       DwarfLocSection = ".section __DWARFA,__debug_loc";
00257       DwarfARangesSection = ".section __DWARFA,__debug_aranges";
00258       DwarfRangesSection = ".section __DWARFA,__debug_ranges";
00259       DwarfMacInfoSection = ".section __DWARFA,__debug_macinfo";
00260       TextSection = ".text";
00261       DataSection = ".data";
00262     }
00263   };
00264 
00265   /// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS
00266   /// X
00267   struct DarwinAsmPrinter : public PPCAsmPrinter {
00268   
00269     DarwinDwarfWriter DW;
00270 
00271     DarwinAsmPrinter(std::ostream &O, TargetMachine &TM)
00272       : PPCAsmPrinter(O, TM), DW(O, this) {
00273       CommentString = ";";
00274       GlobalPrefix = "_";
00275       PrivateGlobalPrefix = "L";     // Marker for constant pool idxs
00276       ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
00277       Data64bitsDirective = 0;       // we can't emit a 64-bit unit
00278       AlignmentIsInBytes = false;    // Alignment is by power of 2.
00279       ConstantPoolSection = "\t.const\t";
00280       LCOMMDirective = "\t.lcomm\t";
00281       StaticCtorsSection = ".mod_init_func";
00282       StaticDtorsSection = ".mod_term_func";
00283       InlineAsmStart = InlineAsmEnd = "";  // Don't use #APP/#NO_APP
00284     }
00285 
00286     virtual const char *getPassName() const {
00287       return "Darwin PPC Assembly Printer";
00288     }
00289     
00290     bool runOnMachineFunction(MachineFunction &F);
00291     bool doInitialization(Module &M);
00292     bool doFinalization(Module &M);
00293     
00294     void getAnalysisUsage(AnalysisUsage &AU) const {
00295       AU.setPreservesAll();
00296       AU.addRequired<MachineDebugInfo>();
00297       PPCAsmPrinter::getAnalysisUsage(AU);
00298     }
00299 
00300   };
00301 
00302   /// AIXAsmPrinter - PowerPC assembly printer, customized for AIX
00303   ///
00304   struct AIXAsmPrinter : public PPCAsmPrinter {
00305     /// Map for labels corresponding to global variables
00306     ///
00307     std::map<const GlobalVariable*,std::string> GVToLabelMap;
00308 
00309     AIXAsmPrinter(std::ostream &O, TargetMachine &TM)
00310       : PPCAsmPrinter(O, TM) {
00311       CommentString = "#";
00312       GlobalPrefix = ".";
00313       ZeroDirective = "\t.space\t";  // ".space N" emits N zeros.
00314       Data64bitsDirective = 0;       // we can't emit a 64-bit unit
00315       AlignmentIsInBytes = false;    // Alignment is by power of 2.
00316       ConstantPoolSection = "\t.const\t";
00317     }
00318 
00319     virtual const char *getPassName() const {
00320       return "AIX PPC Assembly Printer";
00321     }
00322 
00323     bool runOnMachineFunction(MachineFunction &F);
00324     bool doInitialization(Module &M);
00325     bool doFinalization(Module &M);
00326   };
00327 } // end of anonymous namespace
00328 
00329 /// createDarwinAsmPrinterPass - Returns a pass that prints the PPC assembly
00330 /// code for a MachineFunction to the given output stream, in a format that the
00331 /// Darwin assembler can deal with.
00332 ///
00333 FunctionPass *llvm::createDarwinAsmPrinter(std::ostream &o,
00334                                            PPCTargetMachine &tm) {
00335   return new DarwinAsmPrinter(o, tm);
00336 }
00337 
00338 /// createAIXAsmPrinterPass - Returns a pass that prints the PPC assembly code
00339 /// for a MachineFunction to the given output stream, in a format that the
00340 /// AIX 5L assembler can deal with.
00341 ///
00342 FunctionPass *llvm::createAIXAsmPrinter(std::ostream &o, PPCTargetMachine &tm) {
00343   return new AIXAsmPrinter(o, tm);
00344 }
00345 
00346 // Include the auto-generated portion of the assembly writer
00347 #include "PPCGenAsmWriter.inc"
00348 
00349 void PPCAsmPrinter::printOp(const MachineOperand &MO) {
00350   const MRegisterInfo &RI = *TM.getRegisterInfo();
00351   int new_symbol;
00352 
00353   switch (MO.getType()) {
00354   case MachineOperand::MO_VirtualRegister:
00355     if (Value *V = MO.getVRegValueOrNull()) {
00356       O << "<" << V->getName() << ">";
00357       return;
00358     }
00359     // FALLTHROUGH
00360   case MachineOperand::MO_MachineRegister:
00361   case MachineOperand::MO_CCRegister:
00362     O << RI.get(MO.getReg()).Name;
00363     return;
00364 
00365   case MachineOperand::MO_SignExtendedImmed:
00366   case MachineOperand::MO_UnextendedImmed:
00367     std::cerr << "printOp() does not handle immediate values\n";
00368     abort();
00369     return;
00370 
00371   case MachineOperand::MO_PCRelativeDisp:
00372     std::cerr << "Shouldn't use addPCDisp() when building PPC MachineInstrs";
00373     abort();
00374     return;
00375 
00376   case MachineOperand::MO_MachineBasicBlock: {
00377     MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
00378     O << PrivateGlobalPrefix << "BB" << getFunctionNumber() << "_"
00379       << MBBOp->getNumber() << "\t; " << MBBOp->getBasicBlock()->getName();
00380     return;
00381   }
00382 
00383   case MachineOperand::MO_ConstantPoolIndex:
00384     O << PrivateGlobalPrefix << "CPI" << getFunctionNumber()
00385       << '_' << MO.getConstantPoolIndex();
00386     return;
00387   case MachineOperand::MO_ExternalSymbol:
00388     // Computing the address of an external symbol, not calling it.
00389     if (TM.getRelocationModel() != Reloc::Static) {
00390       std::string Name(GlobalPrefix); Name += MO.getSymbolName();
00391       GVStubs.insert(Name);
00392       O << "L" << Name << "$non_lazy_ptr";
00393       return;
00394     }
00395     O << GlobalPrefix << MO.getSymbolName();
00396     return;
00397   case MachineOperand::MO_GlobalAddress: {
00398     // Computing the address of a global symbol, not calling it.
00399     GlobalValue *GV = MO.getGlobal();
00400     std::string Name = Mang->getValueName(GV);
00401     int offset = MO.getOffset();
00402 
00403     // External or weakly linked global variables need non-lazily-resolved stubs
00404     if (TM.getRelocationModel() != Reloc::Static) {
00405       if (((GV->isExternal() || GV->hasWeakLinkage() ||
00406             GV->hasLinkOnceLinkage()))) {
00407         GVStubs.insert(Name);
00408         O << "L" << Name << "$non_lazy_ptr";
00409         return;
00410       }
00411     }
00412 
00413     O << Name;
00414     return;
00415   }
00416 
00417   default:
00418     O << "<unknown operand type: " << MO.getType() << ">";
00419     return;
00420   }
00421 }
00422 
00423 /// PrintAsmOperand - Print out an operand for an inline asm expression.
00424 ///
00425 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
00426                                     unsigned AsmVariant, 
00427                                     const char *ExtraCode) {
00428   // Does this asm operand have a single letter operand modifier?
00429   if (ExtraCode && ExtraCode[0]) {
00430     if (ExtraCode[1] != 0) return true; // Unknown modifier.
00431     
00432     switch (ExtraCode[0]) {
00433     default: return true;  // Unknown modifier.
00434     case 'L': // Write second word of DImode reference.  
00435       // Verify that this operand has two consecutive registers.
00436       if (!MI->getOperand(OpNo).isRegister() ||
00437           OpNo+1 == MI->getNumOperands() ||
00438           !MI->getOperand(OpNo+1).isRegister())
00439         return true;
00440       ++OpNo;   // Return the high-part.
00441       break;
00442     }
00443   }
00444   
00445   printOperand(MI, OpNo);
00446   return false;
00447 }
00448 
00449 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
00450                                           unsigned AsmVariant, 
00451                                           const char *ExtraCode) {
00452   if (ExtraCode && ExtraCode[0])
00453     return true; // Unknown modifier.
00454   printMemRegReg(MI, OpNo);
00455   return false;
00456 }
00457 
00458 /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to
00459 /// the current output stream.
00460 ///
00461 void PPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) {
00462   ++EmittedInsts;
00463 
00464   // Check for slwi/srwi mnemonics.
00465   if (MI->getOpcode() == PPC::RLWINM) {
00466     bool FoundMnemonic = false;
00467     unsigned char SH = MI->getOperand(2).getImmedValue();
00468     unsigned char MB = MI->getOperand(3).getImmedValue();
00469     unsigned char ME = MI->getOperand(4).getImmedValue();
00470     if (SH <= 31 && MB == 0 && ME == (31-SH)) {
00471       O << "slwi "; FoundMnemonic = true;
00472     }
00473     if (SH <= 31 && MB == (32-SH) && ME == 31) {
00474       O << "srwi "; FoundMnemonic = true;
00475       SH = 32-SH;
00476     }
00477     if (FoundMnemonic) {
00478       printOperand(MI, 0);
00479       O << ", ";
00480       printOperand(MI, 1);
00481       O << ", " << (unsigned int)SH << "\n";
00482       return;
00483     }
00484   } else if (MI->getOpcode() == PPC::OR4 || MI->getOpcode() == PPC::OR8) {
00485     if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
00486       O << "mr ";
00487       printOperand(MI, 0);
00488       O << ", ";
00489       printOperand(MI, 1);
00490       O << "\n";
00491       return;
00492     }
00493   }
00494 
00495   if (printInstruction(MI))
00496     return; // Printer was automatically generated
00497 
00498   assert(0 && "Unhandled instruction in asm writer!");
00499   abort();
00500   return;
00501 }
00502 
00503 
00504 /// runOnMachineFunction - This uses the printMachineInstruction()
00505 /// method to print assembly for each instruction.
00506 ///
00507 bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
00508   // FIXME - is this the earliest this can be set?
00509   DW.SetDebugInfo(&getAnalysis<MachineDebugInfo>());
00510 
00511   SetupMachineFunction(MF);
00512   O << "\n\n";
00513   
00514   // Print out constants referenced by the function
00515   EmitConstantPool(MF.getConstantPool());
00516 
00517   // Print out labels for the function.
00518   const Function *F = MF.getFunction();
00519   switch (F->getLinkage()) {
00520   default: assert(0 && "Unknown linkage type!");
00521   case Function::InternalLinkage:  // Symbols default to internal.
00522     SwitchSection(".text", F);
00523     break;
00524   case Function::ExternalLinkage:
00525     SwitchSection(".text", F);
00526     O << "\t.globl\t" << CurrentFnName << "\n";
00527     break;
00528   case Function::WeakLinkage:
00529   case Function::LinkOnceLinkage:
00530     SwitchSection(".section __TEXT,__textcoal_nt,coalesced,pure_instructions",
00531                   F);
00532     O << "\t.globl\t" << CurrentFnName << "\n";
00533     O << "\t.weak_definition\t" << CurrentFnName << "\n";
00534     break;
00535   }
00536   EmitAlignment(4, F);
00537   O << CurrentFnName << ":\n";
00538 
00539   // Emit pre-function debug information.
00540   DW.BeginFunction(&MF);
00541 
00542   // Print out code for the function.
00543   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
00544        I != E; ++I) {
00545     // Print a label for the basic block.
00546     if (I != MF.begin()) {
00547       O << PrivateGlobalPrefix << "BB" << getFunctionNumber() << '_'
00548         << I->getNumber() << ":\t";
00549       if (!I->getBasicBlock()->getName().empty())
00550         O << CommentString << " " << I->getBasicBlock()->getName();
00551       O << "\n";
00552     }
00553     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
00554          II != E; ++II) {
00555       // Print the assembly for the instruction.
00556       O << "\t";
00557       printMachineInstruction(II);
00558     }
00559   }
00560 
00561   // Emit post-function debug information.
00562   DW.EndFunction();
00563 
00564   // We didn't modify anything.
00565   return false;
00566 }
00567 
00568 
00569 bool DarwinAsmPrinter::doInitialization(Module &M) {
00570   if (TM.getSubtarget<PPCSubtarget>().isGigaProcessor())
00571     O << "\t.machine ppc970\n";
00572   AsmPrinter::doInitialization(M);
00573   
00574   // Darwin wants symbols to be quoted if they have complex names.
00575   Mang->setUseQuotes(true);
00576   
00577   // Emit initial debug information.
00578   DW.BeginModule(&M);
00579   return false;
00580 }
00581 
00582 bool DarwinAsmPrinter::doFinalization(Module &M) {
00583   const TargetData &TD = TM.getTargetData();
00584 
00585   // Print out module-level global variables here.
00586   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
00587        I != E; ++I) {
00588     if (!I->hasInitializer()) continue;   // External global require no code
00589     
00590     // Check to see if this is a special global used by LLVM, if so, emit it.
00591     if (EmitSpecialLLVMGlobal(I))
00592       continue;
00593     
00594     std::string name = Mang->getValueName(I);
00595     Constant *C = I->getInitializer();
00596     unsigned Size = TD.getTypeSize(C->getType());
00597     unsigned Align = getPreferredAlignmentLog(I);
00598 
00599     if (C->isNullValue() && /* FIXME: Verify correct */
00600         (I->hasInternalLinkage() || I->hasWeakLinkage() ||
00601          I->hasLinkOnceLinkage() ||
00602          (I->hasExternalLinkage() && !I->hasSection()))) {
00603       if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
00604       if (I->hasExternalLinkage()) {
00605         O << "\t.globl " << name << '\n';
00606         O << "\t.zerofill __DATA, __common, " << name << ", "
00607           << Size << ", " << Align;
00608       } else if (I->hasInternalLinkage()) {
00609         SwitchSection(".data", I);
00610         O << LCOMMDirective << name << "," << Size << "," << Align;
00611       } else {
00612         SwitchSection(".data", I);
00613         O << ".comm " << name << "," << Size;
00614       }
00615       O << "\t\t; '" << I->getName() << "'\n";
00616     } else {
00617       switch (I->getLinkage()) {
00618       case GlobalValue::LinkOnceLinkage:
00619       case GlobalValue::WeakLinkage:
00620         O << "\t.globl " << name << '\n'
00621           << "\t.weak_definition " << name << '\n';
00622         SwitchSection(".section __DATA,__datacoal_nt,coalesced", I);
00623         break;
00624       case GlobalValue::AppendingLinkage:
00625         // FIXME: appending linkage variables should go into a section of
00626         // their name or something.  For now, just emit them as external.
00627       case GlobalValue::ExternalLinkage:
00628         // If external or appending, declare as a global symbol
00629         O << "\t.globl " << name << "\n";
00630         // FALL THROUGH
00631       case GlobalValue::InternalLinkage:
00632         SwitchSection(".data", I);
00633         break;
00634       default:
00635         std::cerr << "Unknown linkage type!";
00636         abort();
00637       }
00638 
00639       EmitAlignment(Align, I);
00640       O << name << ":\t\t\t\t; '" << I->getName() << "'\n";
00641       EmitGlobalConstant(C);
00642       O << '\n';
00643     }
00644   }
00645 
00646   // Output stubs for dynamically-linked functions
00647   if (TM.getRelocationModel() == Reloc::PIC) {
00648     for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
00649          i != e; ++i) {
00650       SwitchSection(".section __TEXT,__picsymbolstub1,symbol_stubs,"
00651                     "pure_instructions,32", 0);
00652       EmitAlignment(2);
00653       O << "L" << *i << "$stub:\n";
00654       O << "\t.indirect_symbol " << *i << "\n";
00655       O << "\tmflr r0\n";
00656       O << "\tbcl 20,31,L0$" << *i << "\n";
00657       O << "L0$" << *i << ":\n";
00658       O << "\tmflr r11\n";
00659       O << "\taddis r11,r11,ha16(L" << *i << "$lazy_ptr-L0$" << *i << ")\n";
00660       O << "\tmtlr r0\n";
00661       O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n";
00662       O << "\tmtctr r12\n";
00663       O << "\tbctr\n";
00664       SwitchSection(".lazy_symbol_pointer", 0);
00665       O << "L" << *i << "$lazy_ptr:\n";
00666       O << "\t.indirect_symbol " << *i << "\n";
00667       O << "\t.long dyld_stub_binding_helper\n";
00668     }
00669   } else {
00670     for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
00671          i != e; ++i) {
00672       SwitchSection(".section __TEXT,__symbol_stub1,symbol_stubs,"
00673                     "pure_instructions,16", 0);
00674       EmitAlignment(4);
00675       O << "L" << *i << "$stub:\n";
00676       O << "\t.indirect_symbol " << *i << "\n";
00677       O << "\tlis r11,ha16(L" << *i << "$lazy_ptr)\n";
00678       O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr)(r11)\n";
00679       O << "\tmtctr r12\n";
00680       O << "\tbctr\n";
00681       SwitchSection(".lazy_symbol_pointer", 0);
00682       O << "L" << *i << "$lazy_ptr:\n";
00683       O << "\t.indirect_symbol " << *i << "\n";
00684       O << "\t.long dyld_stub_binding_helper\n";
00685     }
00686   }
00687 
00688   O << "\n";
00689 
00690   // Output stubs for external and common global variables.
00691   if (GVStubs.begin() != GVStubs.end()) {
00692     SwitchSection(".non_lazy_symbol_pointer", 0);
00693     for (std::set<std::string>::iterator I = GVStubs.begin(),
00694          E = GVStubs.end(); I != E; ++I) {
00695       O << "L" << *I << "$non_lazy_ptr:\n";
00696       O << "\t.indirect_symbol " << *I << "\n";
00697       O << "\t.long\t0\n";
00698     }
00699   }
00700 
00701   // Emit initial debug information.
00702   DW.EndModule();
00703 
00704   // Funny Darwin hack: This flag tells the linker that no global symbols
00705   // contain code that falls through to other global symbols (e.g. the obvious
00706   // implementation of multiple entry points).  If this doesn't occur, the
00707   // linker can safely perform dead code stripping.  Since LLVM never generates
00708   // code that does this, it is always safe to set.
00709   O << "\t.subsections_via_symbols\n";
00710 
00711   AsmPrinter::doFinalization(M);
00712   return false; // success
00713 }
00714 
00715 /// runOnMachineFunction - This uses the e()
00716 /// method to print assembly for each instruction.
00717 ///
00718 bool AIXAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
00719   SetupMachineFunction(MF);
00720   
00721   // Print out constants referenced by the function
00722   EmitConstantPool(MF.getConstantPool());
00723 
00724   // Print out header for the function.
00725   O << "\t.csect .text[PR]\n"
00726     << "\t.align 2\n"
00727     << "\t.globl "  << CurrentFnName << '\n'
00728     << "\t.globl ." << CurrentFnName << '\n'
00729     << "\t.csect "  << CurrentFnName << "[DS],3\n"
00730     << CurrentFnName << ":\n"
00731     << "\t.llong ." << CurrentFnName << ", TOC[tc0], 0\n"
00732     << "\t.csect .text[PR]\n"
00733     << '.' << CurrentFnName << ":\n";
00734 
00735   // Print out code for the function.
00736   for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
00737        I != E; ++I) {
00738     // Print a label for the basic block.
00739     O << PrivateGlobalPrefix << "BB" << getFunctionNumber() << '_'
00740       << I->getNumber()
00741       << ":\t" << CommentString << I->getBasicBlock()->getName() << '\n';
00742     for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
00743       II != E; ++II) {
00744       // Print the assembly for the instruction.
00745       O << "\t";
00746       printMachineInstruction(II);
00747     }
00748   }
00749 
00750   O << "LT.." << CurrentFnName << ":\n"
00751     << "\t.long 0\n"
00752     << "\t.byte 0,0,32,65,128,0,0,0\n"
00753     << "\t.long LT.." << CurrentFnName << "-." << CurrentFnName << '\n'
00754     << "\t.short 3\n"
00755     << "\t.byte \"" << CurrentFnName << "\"\n"
00756     << "\t.align 2\n";
00757 
00758   // We didn't modify anything.
00759   return false;
00760 }
00761 
00762 bool AIXAsmPrinter::doInitialization(Module &M) {
00763   SwitchSection("", 0);
00764   const TargetData &TD = TM.getTargetData();
00765 
00766   O << "\t.machine \"ppc64\"\n"
00767     << "\t.toc\n"
00768     << "\t.csect .text[PR]\n";
00769 
00770   // Print out module-level global variables
00771   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
00772        I != E; ++I) {
00773     if (!I->hasInitializer())
00774       continue;
00775 
00776     std::string Name = I->getName();
00777     Constant *C = I->getInitializer();
00778     // N.B.: We are defaulting to writable strings
00779     if (I->hasExternalLinkage()) {
00780       O << "\t.globl " << Name << '\n'
00781         << "\t.csect .data[RW],3\n";
00782     } else {
00783       O << "\t.csect _global.rw_c[RW],3\n";
00784     }
00785     O << Name << ":\n";
00786     EmitGlobalConstant(C);
00787   }
00788 
00789   // Output labels for globals
00790   if (M.global_begin() != M.global_end()) O << "\t.toc\n";
00791   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
00792        I != E; ++I) {
00793     const GlobalVariable *GV = I;
00794     // Do not output labels for unused variables
00795     if (GV->isExternal() && GV->use_begin() == GV->use_end())
00796       continue;
00797 
00798     IncrementFunctionNumber();
00799     std::string Name = GV->getName();
00800     std::string Label = "LC.." + utostr(getFunctionNumber());
00801     GVToLabelMap[GV] = Label;
00802     O << Label << ":\n"
00803       << "\t.tc " << Name << "[TC]," << Name;
00804     if (GV->isExternal()) O << "[RW]";
00805     O << '\n';
00806    }
00807 
00808   AsmPrinter::doInitialization(M);
00809   return false; // success
00810 }
00811 
00812 bool AIXAsmPrinter::doFinalization(Module &M) {
00813   const TargetData &TD = TM.getTargetData();
00814   // Print out module-level global variables
00815   for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
00816        I != E; ++I) {
00817     if (I->hasInitializer() || I->hasExternalLinkage())
00818       continue;
00819 
00820     std::string Name = I->getName();
00821     if (I->hasInternalLinkage()) {
00822       O << "\t.lcomm " << Name << ",16,_global.bss_c";
00823     } else {
00824       O << "\t.comm " << Name << "," << TD.getTypeSize(I->getType())
00825         << "," << Log2_32((unsigned)TD.getTypeAlignment(I->getType()));
00826     }
00827     O << "\t\t" << CommentString << " ";
00828     WriteAsOperand(O, I, false, true, &M);
00829     O << "\n";
00830   }
00831 
00832   O << "_section_.text:\n"
00833     << "\t.csect .data[RW],3\n"
00834     << "\t.llong _section_.text\n";
00835   AsmPrinter::doFinalization(M);
00836   return false; // success
00837 }