LLVM API Documentation
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 }