LLVM API Documentation
00001 //===-- PowerPCAsmPrinter.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 "PowerPC.h" 00021 #include "PowerPCTargetMachine.h" 00022 #include "llvm/Constants.h" 00023 #include "llvm/DerivedTypes.h" 00024 #include "llvm/Module.h" 00025 #include "llvm/Assembly/Writer.h" 00026 #include "llvm/CodeGen/AsmPrinter.h" 00027 #include "llvm/CodeGen/MachineConstantPool.h" 00028 #include "llvm/CodeGen/MachineFunctionPass.h" 00029 #include "llvm/CodeGen/MachineInstr.h" 00030 #include "llvm/CodeGen/ValueTypes.h" 00031 #include "llvm/Support/Mangler.h" 00032 #include "llvm/Support/MathExtras.h" 00033 #include "llvm/Support/CommandLine.h" 00034 #include "llvm/Support/Debug.h" 00035 #include "llvm/Target/MRegisterInfo.h" 00036 #include "llvm/Target/TargetInstrInfo.h" 00037 #include "llvm/ADT/Statistic.h" 00038 #include "llvm/ADT/StringExtras.h" 00039 #include <set> 00040 using namespace llvm; 00041 00042 namespace { 00043 Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); 00044 00045 struct PowerPCAsmPrinter : public AsmPrinter { 00046 std::set<std::string> FnStubs, GVStubs, LinkOnceStubs; 00047 std::set<std::string> Strings; 00048 00049 PowerPCAsmPrinter(std::ostream &O, TargetMachine &TM) 00050 : AsmPrinter(O, TM), LabelNumber(0) {} 00051 00052 /// Unique incrementer for label values for referencing Global values. 00053 /// 00054 unsigned LabelNumber; 00055 00056 virtual const char *getPassName() const { 00057 return "PowerPC Assembly Printer"; 00058 } 00059 00060 PowerPCTargetMachine &getTM() { 00061 return static_cast<PowerPCTargetMachine&>(TM); 00062 } 00063 00064 /// printInstruction - This method is automatically generated by tablegen 00065 /// from the instruction set description. This method returns true if the 00066 /// machine instruction was sufficiently described to print it, otherwise it 00067 /// returns false. 00068 bool printInstruction(const MachineInstr *MI); 00069 00070 void printMachineInstruction(const MachineInstr *MI); 00071 void printOp(const MachineOperand &MO, bool IsCallOp = false); 00072 00073 void printOperand(const MachineInstr *MI, unsigned OpNo, MVT::ValueType VT){ 00074 const MachineOperand &MO = MI->getOperand(OpNo); 00075 if (MO.getType() == MachineOperand::MO_MachineRegister) { 00076 assert(MRegisterInfo::isPhysicalRegister(MO.getReg())&&"Not physreg??"); 00077 O << LowercaseString(TM.getRegisterInfo()->get(MO.getReg()).Name); 00078 } else if (MO.isImmediate()) { 00079 O << MO.getImmedValue(); 00080 } else { 00081 printOp(MO); 00082 } 00083 } 00084 00085 void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo, 00086 MVT::ValueType VT) { 00087 unsigned char value = MI->getOperand(OpNo).getImmedValue(); 00088 assert(value <= 31 && "Invalid u5imm argument!"); 00089 O << (unsigned int)value; 00090 } 00091 void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo, 00092 MVT::ValueType VT) { 00093 unsigned char value = MI->getOperand(OpNo).getImmedValue(); 00094 assert(value <= 63 && "Invalid u6imm argument!"); 00095 O << (unsigned int)value; 00096 } 00097 void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo, 00098 MVT::ValueType VT) { 00099 O << (short)MI->getOperand(OpNo).getImmedValue(); 00100 } 00101 void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo, 00102 MVT::ValueType VT) { 00103 O << (unsigned short)MI->getOperand(OpNo).getImmedValue(); 00104 } 00105 void printBranchOperand(const MachineInstr *MI, unsigned OpNo, 00106 MVT::ValueType VT) { 00107 // Branches can take an immediate operand. This is used by the branch 00108 // selection pass to print $+8, an eight byte displacement from the PC. 00109 if (MI->getOperand(OpNo).isImmediate()) { 00110 O << "$+" << MI->getOperand(OpNo).getImmedValue() << '\n'; 00111 } else { 00112 printOp(MI->getOperand(OpNo), 00113 TM.getInstrInfo()->isCall(MI->getOpcode())); 00114 } 00115 } 00116 void printPICLabel(const MachineInstr *MI, unsigned OpNo, 00117 MVT::ValueType VT) { 00118 // FIXME: should probably be converted to cout.width and cout.fill 00119 O << "\"L0000" << LabelNumber << "$pb\"\n"; 00120 O << "\"L0000" << LabelNumber << "$pb\":"; 00121 } 00122 void printSymbolHi(const MachineInstr *MI, unsigned OpNo, 00123 MVT::ValueType VT) { 00124 O << "ha16("; 00125 printOp(MI->getOperand(OpNo)); 00126 O << "-\"L0000" << LabelNumber << "$pb\")"; 00127 } 00128 void printSymbolLo(const MachineInstr *MI, unsigned OpNo, 00129 MVT::ValueType VT) { 00130 // FIXME: Because LFS, LFD, and LWZ can be used either with a s16imm or 00131 // a lo16 of a global or constant pool operand, we must handle both here. 00132 // this isn't a great design, but it works for now. 00133 if (MI->getOperand(OpNo).isImmediate()) { 00134 O << (short)MI->getOperand(OpNo).getImmedValue(); 00135 } else { 00136 O << "lo16("; 00137 printOp(MI->getOperand(OpNo)); 00138 O << "-\"L0000" << LabelNumber << "$pb\")"; 00139 } 00140 } 00141 00142 virtual void printConstantPool(MachineConstantPool *MCP) = 0; 00143 virtual bool runOnMachineFunction(MachineFunction &F) = 0; 00144 virtual bool doFinalization(Module &M) = 0; 00145 }; 00146 00147 /// DarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac OS 00148 /// X 00149 /// 00150 struct DarwinAsmPrinter : public PowerPCAsmPrinter { 00151 00152 DarwinAsmPrinter(std::ostream &O, TargetMachine &TM) 00153 : PowerPCAsmPrinter(O, TM) { 00154 CommentString = ";"; 00155 GlobalPrefix = "_"; 00156 ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. 00157 Data64bitsDirective = 0; // we can't emit a 64-bit unit 00158 AlignmentIsInBytes = false; // Alignment is by power of 2. 00159 } 00160 00161 virtual const char *getPassName() const { 00162 return "Darwin PPC Assembly Printer"; 00163 } 00164 00165 void printConstantPool(MachineConstantPool *MCP); 00166 bool runOnMachineFunction(MachineFunction &F); 00167 bool doFinalization(Module &M); 00168 }; 00169 00170 /// AIXAsmPrinter - PowerPC assembly printer, customized for AIX 00171 /// 00172 struct AIXAsmPrinter : public PowerPCAsmPrinter { 00173 /// Map for labels corresponding to global variables 00174 /// 00175 std::map<const GlobalVariable*,std::string> GVToLabelMap; 00176 00177 AIXAsmPrinter(std::ostream &O, TargetMachine &TM) 00178 : PowerPCAsmPrinter(O, TM) { 00179 CommentString = "#"; 00180 GlobalPrefix = "_"; 00181 ZeroDirective = "\t.space\t"; // ".space N" emits N zeros. 00182 Data64bitsDirective = 0; // we can't emit a 64-bit unit 00183 AlignmentIsInBytes = false; // Alignment is by power of 2. 00184 } 00185 00186 virtual const char *getPassName() const { 00187 return "AIX PPC Assembly Printer"; 00188 } 00189 00190 void printConstantPool(MachineConstantPool *MCP); 00191 bool runOnMachineFunction(MachineFunction &F); 00192 bool doInitialization(Module &M); 00193 bool doFinalization(Module &M); 00194 }; 00195 } // end of anonymous namespace 00196 00197 // SwitchSection - Switch to the specified section of the executable if we are 00198 // not already in it! 00199 // 00200 static void SwitchSection(std::ostream &OS, std::string &CurSection, 00201 const char *NewSection) { 00202 if (CurSection != NewSection) { 00203 CurSection = NewSection; 00204 if (!CurSection.empty()) 00205 OS << "\t" << NewSection << "\n"; 00206 } 00207 } 00208 00209 /// isStringCompatible - Can we treat the specified array as a string? 00210 /// Only if it is an array of ubytes or non-negative sbytes. 00211 /// 00212 static bool isStringCompatible(const ConstantArray *CVA) { 00213 const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType(); 00214 if (ETy == Type::UByteTy) return true; 00215 if (ETy != Type::SByteTy) return false; 00216 00217 for (unsigned i = 0; i < CVA->getNumOperands(); ++i) 00218 if (cast<ConstantSInt>(CVA->getOperand(i))->getValue() < 0) 00219 return false; 00220 00221 return true; 00222 } 00223 00224 /// toOctal - Convert the low order bits of X into an octal digit. 00225 /// 00226 static inline char toOctal(int X) { 00227 return (X&7)+'0'; 00228 } 00229 00230 // Possible states while outputting ASCII strings 00231 namespace { 00232 enum StringSection { 00233 None, 00234 Alpha, 00235 Numeric 00236 }; 00237 } 00238 00239 /// SwitchStringSection - manage the changes required to output bytes as 00240 /// characters in a string vs. numeric decimal values 00241 /// 00242 static inline void SwitchStringSection(std::ostream &O, StringSection NewSect, 00243 StringSection &Current) { 00244 if (Current == None) { 00245 if (NewSect == Alpha) 00246 O << "\t.byte \""; 00247 else if (NewSect == Numeric) 00248 O << "\t.byte "; 00249 } else if (Current == Alpha) { 00250 if (NewSect == None) 00251 O << "\""; 00252 else if (NewSect == Numeric) 00253 O << "\"\n" 00254 << "\t.byte "; 00255 } else if (Current == Numeric) { 00256 if (NewSect == Alpha) 00257 O << '\n' 00258 << "\t.byte \""; 00259 else if (NewSect == Numeric) 00260 O << ", "; 00261 } 00262 00263 Current = NewSect; 00264 } 00265 00266 /// getAsCString - Return the specified array as a C compatible 00267 /// string, only if the predicate isStringCompatible is true. 00268 /// 00269 static void printAsCString(std::ostream &O, const ConstantArray *CVA) { 00270 assert(isStringCompatible(CVA) && "Array is not string compatible!"); 00271 00272 if (CVA->getNumOperands() == 0) 00273 return; 00274 00275 StringSection Current = None; 00276 for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i) { 00277 unsigned char C = cast<ConstantInt>(CVA->getOperand(i))->getRawValue(); 00278 if (C == '"') { 00279 SwitchStringSection(O, Alpha, Current); 00280 O << "\"\""; 00281 } else if (isprint(C)) { 00282 SwitchStringSection(O, Alpha, Current); 00283 O << C; 00284 } else { 00285 SwitchStringSection(O, Numeric, Current); 00286 O << utostr((unsigned)C); 00287 } 00288 } 00289 SwitchStringSection(O, None, Current); 00290 O << '\n'; 00291 } 00292 00293 /// createDarwinAsmPrinterPass - Returns a pass that prints the PPC assembly 00294 /// code for a MachineFunction to the given output stream, in a format that the 00295 /// Darwin assembler can deal with. 00296 /// 00297 FunctionPass *llvm::createDarwinAsmPrinter(std::ostream &o, TargetMachine &tm) { 00298 return new DarwinAsmPrinter(o, tm); 00299 } 00300 00301 /// createAIXAsmPrinterPass - Returns a pass that prints the PPC assembly code 00302 /// for a MachineFunction to the given output stream, in a format that the 00303 /// AIX 5L assembler can deal with. 00304 /// 00305 FunctionPass *llvm::createAIXAsmPrinter(std::ostream &o, TargetMachine &tm) { 00306 return new AIXAsmPrinter(o, tm); 00307 } 00308 00309 // Include the auto-generated portion of the assembly writer 00310 #include "PowerPCGenAsmWriter.inc" 00311 00312 void PowerPCAsmPrinter::printOp(const MachineOperand &MO, bool IsCallOp) { 00313 const MRegisterInfo &RI = *TM.getRegisterInfo(); 00314 int new_symbol; 00315 00316 switch (MO.getType()) { 00317 case MachineOperand::MO_VirtualRegister: 00318 if (Value *V = MO.getVRegValueOrNull()) { 00319 O << "<" << V->getName() << ">"; 00320 return; 00321 } 00322 // FALLTHROUGH 00323 case MachineOperand::MO_MachineRegister: 00324 case MachineOperand::MO_CCRegister: 00325 O << LowercaseString(RI.get(MO.getReg()).Name); 00326 return; 00327 00328 case MachineOperand::MO_SignExtendedImmed: 00329 case MachineOperand::MO_UnextendedImmed: 00330 std::cerr << "printOp() does not handle immediate values\n"; 00331 abort(); 00332 return; 00333 00334 case MachineOperand::MO_PCRelativeDisp: 00335 std::cerr << "Shouldn't use addPCDisp() when building PPC MachineInstrs"; 00336 abort(); 00337 return; 00338 00339 case MachineOperand::MO_MachineBasicBlock: { 00340 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); 00341 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) 00342 << "_" << MBBOp->getNumber() << "\t; " 00343 << MBBOp->getBasicBlock()->getName(); 00344 return; 00345 } 00346 00347 case MachineOperand::MO_ConstantPoolIndex: 00348 O << ".CPI" << CurrentFnName << "_" << MO.getConstantPoolIndex(); 00349 return; 00350 00351 case MachineOperand::MO_ExternalSymbol: 00352 O << MO.getSymbolName(); 00353 return; 00354 00355 case MachineOperand::MO_GlobalAddress: { 00356 GlobalValue *GV = MO.getGlobal(); 00357 std::string Name = Mang->getValueName(GV); 00358 00359 // Dynamically-resolved functions need a stub for the function. Be 00360 // wary however not to output $stub for external functions whose addresses 00361 // are taken. Those should be emitted as $non_lazy_ptr below. 00362 Function *F = dyn_cast<Function>(GV); 00363 if (F && IsCallOp && F->isExternal()) { 00364 FnStubs.insert(Name); 00365 O << "L" << Name << "$stub"; 00366 return; 00367 } 00368 00369 // External or weakly linked global variables need non-lazily-resolved stubs 00370 if ((GV->isExternal() || GV->hasWeakLinkage() || GV->hasLinkOnceLinkage())){ 00371 if (GV->hasLinkOnceLinkage()) 00372 LinkOnceStubs.insert(Name); 00373 else 00374 GVStubs.insert(Name); 00375 O << "L" << Name << "$non_lazy_ptr"; 00376 return; 00377 } 00378 00379 O << Mang->getValueName(GV); 00380 return; 00381 } 00382 00383 default: 00384 O << "<unknown operand type: " << MO.getType() << ">"; 00385 return; 00386 } 00387 } 00388 00389 /// printMachineInstruction -- Print out a single PowerPC MI in Darwin syntax to 00390 /// the current output stream. 00391 /// 00392 void PowerPCAsmPrinter::printMachineInstruction(const MachineInstr *MI) { 00393 ++EmittedInsts; 00394 if (printInstruction(MI)) 00395 return; // Printer was automatically generated 00396 00397 assert(0 && "Unhandled instruction in asm writer!"); 00398 abort(); 00399 return; 00400 } 00401 00402 /// runOnMachineFunction - This uses the printMachineInstruction() 00403 /// method to print assembly for each instruction. 00404 /// 00405 bool DarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 00406 setupMachineFunction(MF); 00407 O << "\n\n"; 00408 00409 // Print out constants referenced by the function 00410 printConstantPool(MF.getConstantPool()); 00411 00412 // Print out labels for the function. 00413 O << "\t.text\n"; 00414 emitAlignment(2); 00415 O << "\t.globl\t" << CurrentFnName << "\n"; 00416 O << CurrentFnName << ":\n"; 00417 00418 // Print out code for the function. 00419 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 00420 I != E; ++I) { 00421 // Print a label for the basic block. 00422 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t" 00423 << CommentString << " " << I->getBasicBlock()->getName() << "\n"; 00424 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 00425 II != E; ++II) { 00426 // Print the assembly for the instruction. 00427 O << "\t"; 00428 printMachineInstruction(II); 00429 } 00430 } 00431 ++LabelNumber; 00432 00433 // We didn't modify anything. 00434 return false; 00435 } 00436 00437 /// printConstantPool - Print to the current output stream assembly 00438 /// representations of the constants in the constant pool MCP. This is 00439 /// used to print out constants which have been "spilled to memory" by 00440 /// the code generator. 00441 /// 00442 void DarwinAsmPrinter::printConstantPool(MachineConstantPool *MCP) { 00443 const std::vector<Constant*> &CP = MCP->getConstants(); 00444 const TargetData &TD = TM.getTargetData(); 00445 00446 if (CP.empty()) return; 00447 00448 for (unsigned i = 0, e = CP.size(); i != e; ++i) { 00449 O << "\t.const\n"; 00450 emitAlignment(TD.getTypeAlignmentShift(CP[i]->getType())); 00451 O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t" << CommentString 00452 << *CP[i] << "\n"; 00453 emitGlobalConstant(CP[i]); 00454 } 00455 } 00456 00457 bool DarwinAsmPrinter::doFinalization(Module &M) { 00458 const TargetData &TD = TM.getTargetData(); 00459 std::string CurSection; 00460 00461 // Print out module-level global variables here. 00462 for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) 00463 if (I->hasInitializer()) { // External global require no code 00464 O << '\n'; 00465 std::string name = Mang->getValueName(I); 00466 Constant *C = I->getInitializer(); 00467 unsigned Size = TD.getTypeSize(C->getType()); 00468 unsigned Align = TD.getTypeAlignmentShift(C->getType()); 00469 00470 if (C->isNullValue() && /* FIXME: Verify correct */ 00471 (I->hasInternalLinkage() || I->hasWeakLinkage() || 00472 I->hasLinkOnceLinkage())) { 00473 SwitchSection(O, CurSection, ".data"); 00474 if (I->hasInternalLinkage()) 00475 O << ".lcomm " << name << "," << TD.getTypeSize(C->getType()) 00476 << "," << Align; 00477 else 00478 O << ".comm " << name << "," << TD.getTypeSize(C->getType()); 00479 O << "\t\t; "; 00480 WriteAsOperand(O, I, true, true, &M); 00481 O << '\n'; 00482 } else { 00483 switch (I->getLinkage()) { 00484 case GlobalValue::LinkOnceLinkage: 00485 O << ".section __TEXT,__textcoal_nt,coalesced,no_toc\n" 00486 << ".weak_definition " << name << '\n' 00487 << ".private_extern " << name << '\n' 00488 << ".section __DATA,__datacoal_nt,coalesced,no_toc\n"; 00489 LinkOnceStubs.insert(name); 00490 break; 00491 case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. 00492 // Nonnull linkonce -> weak 00493 O << "\t.weak " << name << "\n"; 00494 SwitchSection(O, CurSection, ""); 00495 O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"; 00496 break; 00497 case GlobalValue::AppendingLinkage: 00498 // FIXME: appending linkage variables should go into a section of 00499 // their name or something. For now, just emit them as external. 00500 case GlobalValue::ExternalLinkage: 00501 // If external or appending, declare as a global symbol 00502 O << "\t.globl " << name << "\n"; 00503 // FALL THROUGH 00504 case GlobalValue::InternalLinkage: 00505 SwitchSection(O, CurSection, ".data"); 00506 break; 00507 case GlobalValue::GhostLinkage: 00508 std::cerr << "Error: unmaterialized (GhostLinkage) function in asm!"; 00509 abort(); 00510 } 00511 00512 emitAlignment(Align); 00513 O << name << ":\t\t\t\t; "; 00514 WriteAsOperand(O, I, true, true, &M); 00515 O << " = "; 00516 WriteAsOperand(O, C, false, false, &M); 00517 O << "\n"; 00518 emitGlobalConstant(C); 00519 } 00520 } 00521 00522 // Output stubs for dynamically-linked functions 00523 for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end(); 00524 i != e; ++i) 00525 { 00526 O << ".data\n"; 00527 O << ".section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32\n"; 00528 emitAlignment(2); 00529 O << "L" << *i << "$stub:\n"; 00530 O << "\t.indirect_symbol " << *i << "\n"; 00531 O << "\tmflr r0\n"; 00532 O << "\tbcl 20,31,L0$" << *i << "\n"; 00533 O << "L0$" << *i << ":\n"; 00534 O << "\tmflr r11\n"; 00535 O << "\taddis r11,r11,ha16(L" << *i << "$lazy_ptr-L0$" << *i << ")\n"; 00536 O << "\tmtlr r0\n"; 00537 O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n"; 00538 O << "\tmtctr r12\n"; 00539 O << "\tbctr\n"; 00540 O << ".data\n"; 00541 O << ".lazy_symbol_pointer\n"; 00542 O << "L" << *i << "$lazy_ptr:\n"; 00543 O << "\t.indirect_symbol " << *i << "\n"; 00544 O << "\t.long dyld_stub_binding_helper\n"; 00545 } 00546 00547 O << "\n"; 00548 00549 // Output stubs for external global variables 00550 if (GVStubs.begin() != GVStubs.end()) 00551 O << ".data\n.non_lazy_symbol_pointer\n"; 00552 for (std::set<std::string>::iterator i = GVStubs.begin(), e = GVStubs.end(); 00553 i != e; ++i) { 00554 O << "L" << *i << "$non_lazy_ptr:\n"; 00555 O << "\t.indirect_symbol " << *i << "\n"; 00556 O << "\t.long\t0\n"; 00557 } 00558 00559 // Output stubs for link-once variables 00560 if (LinkOnceStubs.begin() != LinkOnceStubs.end()) 00561 O << ".data\n.align 2\n"; 00562 for (std::set<std::string>::iterator i = LinkOnceStubs.begin(), 00563 e = LinkOnceStubs.end(); i != e; ++i) { 00564 O << "L" << *i << "$non_lazy_ptr:\n" 00565 << "\t.long\t" << *i << '\n'; 00566 } 00567 00568 AsmPrinter::doFinalization(M); 00569 return false; // success 00570 } 00571 00572 /// runOnMachineFunction - This uses the printMachineInstruction() 00573 /// method to print assembly for each instruction. 00574 /// 00575 bool AIXAsmPrinter::runOnMachineFunction(MachineFunction &MF) { 00576 CurrentFnName = MF.getFunction()->getName(); 00577 00578 // Print out constants referenced by the function 00579 printConstantPool(MF.getConstantPool()); 00580 00581 // Print out header for the function. 00582 O << "\t.csect .text[PR]\n" 00583 << "\t.align 2\n" 00584 << "\t.globl " << CurrentFnName << '\n' 00585 << "\t.globl ." << CurrentFnName << '\n' 00586 << "\t.csect " << CurrentFnName << "[DS],3\n" 00587 << CurrentFnName << ":\n" 00588 << "\t.llong ." << CurrentFnName << ", TOC[tc0], 0\n" 00589 << "\t.csect .text[PR]\n" 00590 << '.' << CurrentFnName << ":\n"; 00591 00592 // Print out code for the function. 00593 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 00594 I != E; ++I) { 00595 // Print a label for the basic block. 00596 O << "LBB" << CurrentFnName << "_" << I->getNumber() << ":\t# " 00597 << I->getBasicBlock()->getName() << "\n"; 00598 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 00599 II != E; ++II) { 00600 // Print the assembly for the instruction. 00601 O << "\t"; 00602 printMachineInstruction(II); 00603 } 00604 } 00605 ++LabelNumber; 00606 00607 O << "LT.." << CurrentFnName << ":\n" 00608 << "\t.long 0\n" 00609 << "\t.byte 0,0,32,65,128,0,0,0\n" 00610 << "\t.long LT.." << CurrentFnName << "-." << CurrentFnName << '\n' 00611 << "\t.short 3\n" 00612 << "\t.byte \"" << CurrentFnName << "\"\n" 00613 << "\t.align 2\n"; 00614 00615 // We didn't modify anything. 00616 return false; 00617 } 00618 00619 /// printConstantPool - Print to the current output stream assembly 00620 /// representations of the constants in the constant pool MCP. This is 00621 /// used to print out constants which have been "spilled to memory" by 00622 /// the code generator. 00623 /// 00624 void AIXAsmPrinter::printConstantPool(MachineConstantPool *MCP) { 00625 const std::vector<Constant*> &CP = MCP->getConstants(); 00626 const TargetData &TD = TM.getTargetData(); 00627 00628 if (CP.empty()) return; 00629 00630 for (unsigned i = 0, e = CP.size(); i != e; ++i) { 00631 O << "\t.const\n"; 00632 O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType()) 00633 << "\n"; 00634 O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t;" 00635 << *CP[i] << "\n"; 00636 emitGlobalConstant(CP[i]); 00637 } 00638 } 00639 00640 bool AIXAsmPrinter::doInitialization(Module &M) { 00641 const TargetData &TD = TM.getTargetData(); 00642 std::string CurSection; 00643 00644 O << "\t.machine \"ppc64\"\n" 00645 << "\t.toc\n" 00646 << "\t.csect .text[PR]\n"; 00647 00648 // Print out module-level global variables 00649 for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) { 00650 if (!I->hasInitializer()) 00651 continue; 00652 00653 std::string Name = I->getName(); 00654 Constant *C = I->getInitializer(); 00655 // N.B.: We are defaulting to writable strings 00656 if (I->hasExternalLinkage()) { 00657 O << "\t.globl " << Name << '\n' 00658 << "\t.csect .data[RW],3\n"; 00659 } else { 00660 O << "\t.csect _global.rw_c[RW],3\n"; 00661 } 00662 O << Name << ":\n"; 00663 emitGlobalConstant(C); 00664 } 00665 00666 // Output labels for globals 00667 if (M.gbegin() != M.gend()) O << "\t.toc\n"; 00668 for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) { 00669 const GlobalVariable *GV = I; 00670 // Do not output labels for unused variables 00671 if (GV->isExternal() && GV->use_begin() == GV->use_end()) 00672 continue; 00673 00674 std::string Name = GV->getName(); 00675 std::string Label = "LC.." + utostr(LabelNumber++); 00676 GVToLabelMap[GV] = Label; 00677 O << Label << ":\n" 00678 << "\t.tc " << Name << "[TC]," << Name; 00679 if (GV->isExternal()) O << "[RW]"; 00680 O << '\n'; 00681 } 00682 00683 Mang = new Mangler(M, "."); 00684 return false; // success 00685 } 00686 00687 bool AIXAsmPrinter::doFinalization(Module &M) { 00688 const TargetData &TD = TM.getTargetData(); 00689 // Print out module-level global variables 00690 for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) { 00691 if (I->hasInitializer() || I->hasExternalLinkage()) 00692 continue; 00693 00694 std::string Name = I->getName(); 00695 if (I->hasInternalLinkage()) { 00696 O << "\t.lcomm " << Name << ",16,_global.bss_c"; 00697 } else { 00698 O << "\t.comm " << Name << "," << TD.getTypeSize(I->getType()) 00699 << "," << log2((unsigned)TD.getTypeAlignment(I->getType())); 00700 } 00701 O << "\t\t# "; 00702 WriteAsOperand(O, I, true, true, &M); 00703 O << "\n"; 00704 } 00705 00706 O << "_section_.text:\n" 00707 << "\t.csect .data[RW],3\n" 00708 << "\t.llong _section_.text\n"; 00709 00710 delete Mang; 00711 return false; // success 00712 }