PPCAsmPrinter.cpp revision 2bf183c092138e426c7f66bb072d8e0f7de36648
1//===-- PPC32/Printer.cpp - Convert X86 LLVM code to Intel assembly ---------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by the LLVM research group and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains a printer that converts from our internal 11// representation of machine-dependent LLVM code to Intel-format 12// assembly language. This printer is the output mechanism used 13// by `llc' and `lli -print-machineinstrs' on X86. 14// 15//===----------------------------------------------------------------------===// 16 17#define DEBUG_TYPE "asmprinter" 18#include "PowerPC.h" 19#include "PowerPCInstrInfo.h" 20#include "llvm/Constants.h" 21#include "llvm/DerivedTypes.h" 22#include "llvm/Module.h" 23#include "llvm/Assembly/Writer.h" 24#include "llvm/CodeGen/MachineConstantPool.h" 25#include "llvm/CodeGen/MachineFunctionPass.h" 26#include "llvm/CodeGen/MachineInstr.h" 27#include "llvm/Target/TargetMachine.h" 28#include "llvm/Support/Mangler.h" 29#include "Support/CommandLine.h" 30#include "Support/Debug.h" 31#include "Support/Statistic.h" 32#include "Support/StringExtras.h" 33#include <set> 34 35namespace llvm { 36 37namespace { 38 Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed"); 39 40 struct Printer : public MachineFunctionPass { 41 /// Output stream on which we're printing assembly code. 42 /// 43 std::ostream &O; 44 45 /// Target machine description which we query for reg. names, data 46 /// layout, etc. 47 /// 48 TargetMachine &TM; 49 50 /// Name-mangler for global names. 51 /// 52 Mangler *Mang; 53 std::set< std::string > Stubs; 54 std::set<std::string> Strings; 55 56 Printer(std::ostream &o, TargetMachine &tm) : O(o), TM(tm) { } 57 58 /// Cache of mangled name for current function. This is 59 /// recalculated at the beginning of each call to 60 /// runOnMachineFunction(). 61 /// 62 std::string CurrentFnName; 63 64 virtual const char *getPassName() const { 65 return "PowerPC Assembly Printer"; 66 } 67 68 void printMachineInstruction(const MachineInstr *MI); 69 void printOp(const MachineOperand &MO, 70 bool elideOffsetKeyword = false); 71 void printConstantPool(MachineConstantPool *MCP); 72 bool runOnMachineFunction(MachineFunction &F); 73 bool doInitialization(Module &M); 74 bool doFinalization(Module &M); 75 void emitGlobalConstant(const Constant* CV); 76 void emitConstantValueOnly(const Constant *CV); 77 }; 78} // end of anonymous namespace 79 80/// createPPCCodePrinterPass - Returns a pass that prints the X86 81/// assembly code for a MachineFunction to the given output stream, 82/// using the given target machine description. This should work 83/// regardless of whether the function is in SSA form. 84/// 85FunctionPass *createPPCCodePrinterPass(std::ostream &o,TargetMachine &tm){ 86 return new Printer(o, tm); 87} 88 89/// isStringCompatible - Can we treat the specified array as a string? 90/// Only if it is an array of ubytes or non-negative sbytes. 91/// 92static bool isStringCompatible(const ConstantArray *CVA) { 93 const Type *ETy = cast<ArrayType>(CVA->getType())->getElementType(); 94 if (ETy == Type::UByteTy) return true; 95 if (ETy != Type::SByteTy) return false; 96 97 for (unsigned i = 0; i < CVA->getNumOperands(); ++i) 98 if (cast<ConstantSInt>(CVA->getOperand(i))->getValue() < 0) 99 return false; 100 101 return true; 102} 103 104/// toOctal - Convert the low order bits of X into an octal digit. 105/// 106static inline char toOctal(int X) { 107 return (X&7)+'0'; 108} 109 110/// getAsCString - Return the specified array as a C compatible 111/// string, only if the predicate isStringCompatible is true. 112/// 113static void printAsCString(std::ostream &O, const ConstantArray *CVA) { 114 assert(isStringCompatible(CVA) && "Array is not string compatible!"); 115 116 O << "\""; 117 for (unsigned i = 0; i < CVA->getNumOperands(); ++i) { 118 unsigned char C = cast<ConstantInt>(CVA->getOperand(i))->getRawValue(); 119 120 if (C == '"') { 121 O << "\\\""; 122 } else if (C == '\\') { 123 O << "\\\\"; 124 } else if (isprint(C)) { 125 O << C; 126 } else { 127 switch(C) { 128 case '\b': O << "\\b"; break; 129 case '\f': O << "\\f"; break; 130 case '\n': O << "\\n"; break; 131 case '\r': O << "\\r"; break; 132 case '\t': O << "\\t"; break; 133 default: 134 O << '\\'; 135 O << toOctal(C >> 6); 136 O << toOctal(C >> 3); 137 O << toOctal(C >> 0); 138 break; 139 } 140 } 141 } 142 O << "\""; 143} 144 145// Print out the specified constant, without a storage class. Only the 146// constants valid in constant expressions can occur here. 147void Printer::emitConstantValueOnly(const Constant *CV) { 148 if (CV->isNullValue()) 149 O << "0"; 150 else if (const ConstantBool *CB = dyn_cast<ConstantBool>(CV)) { 151 assert(CB == ConstantBool::True); 152 O << "1"; 153 } else if (const ConstantSInt *CI = dyn_cast<ConstantSInt>(CV)) 154 O << CI->getValue(); 155 else if (const ConstantUInt *CI = dyn_cast<ConstantUInt>(CV)) 156 O << CI->getValue(); 157 else if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(CV)) 158 // This is a constant address for a global variable or function. Use the 159 // name of the variable or function as the address value. 160 O << Mang->getValueName(CPR->getValue()); 161 else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { 162 const TargetData &TD = TM.getTargetData(); 163 switch(CE->getOpcode()) { 164 case Instruction::GetElementPtr: { 165 // generate a symbolic expression for the byte address 166 const Constant *ptrVal = CE->getOperand(0); 167 std::vector<Value*> idxVec(CE->op_begin()+1, CE->op_end()); 168 if (unsigned Offset = TD.getIndexedOffset(ptrVal->getType(), idxVec)) { 169 O << "("; 170 emitConstantValueOnly(ptrVal); 171 O << ") + " << Offset; 172 } else { 173 emitConstantValueOnly(ptrVal); 174 } 175 break; 176 } 177 case Instruction::Cast: { 178 // Support only non-converting or widening casts for now, that is, ones 179 // that do not involve a change in value. This assertion is really gross, 180 // and may not even be a complete check. 181 Constant *Op = CE->getOperand(0); 182 const Type *OpTy = Op->getType(), *Ty = CE->getType(); 183 184 // Remember, kids, pointers on x86 can be losslessly converted back and 185 // forth into 32-bit or wider integers, regardless of signedness. :-P 186 assert(((isa<PointerType>(OpTy) 187 && (Ty == Type::LongTy || Ty == Type::ULongTy 188 || Ty == Type::IntTy || Ty == Type::UIntTy)) 189 || (isa<PointerType>(Ty) 190 && (OpTy == Type::LongTy || OpTy == Type::ULongTy 191 || OpTy == Type::IntTy || OpTy == Type::UIntTy)) 192 || (((TD.getTypeSize(Ty) >= TD.getTypeSize(OpTy)) 193 && OpTy->isLosslesslyConvertibleTo(Ty)))) 194 && "FIXME: Don't yet support this kind of constant cast expr"); 195 O << "("; 196 emitConstantValueOnly(Op); 197 O << ")"; 198 break; 199 } 200 case Instruction::Add: 201 O << "("; 202 emitConstantValueOnly(CE->getOperand(0)); 203 O << ") + ("; 204 emitConstantValueOnly(CE->getOperand(1)); 205 O << ")"; 206 break; 207 default: 208 assert(0 && "Unsupported operator!"); 209 } 210 } else { 211 assert(0 && "Unknown constant value!"); 212 } 213} 214 215// Print a constant value or values, with the appropriate storage class as a 216// prefix. 217void Printer::emitGlobalConstant(const Constant *CV) { 218 const TargetData &TD = TM.getTargetData(); 219 220 if (CV->isNullValue()) { 221 O << "\t.space\t " << TD.getTypeSize(CV->getType()) << "\n"; 222 return; 223 } else if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) { 224 if (isStringCompatible(CVA)) { 225 O << ".ascii"; 226 printAsCString(O, CVA); 227 O << "\n"; 228 } else { // Not a string. Print the values in successive locations 229 const std::vector<Use> &constValues = CVA->getValues(); 230 for (unsigned i=0; i < constValues.size(); i++) 231 emitGlobalConstant(cast<Constant>(constValues[i].get())); 232 } 233 return; 234 } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) { 235 // Print the fields in successive locations. Pad to align if needed! 236 const StructLayout *cvsLayout = TD.getStructLayout(CVS->getType()); 237 const std::vector<Use>& constValues = CVS->getValues(); 238 unsigned sizeSoFar = 0; 239 for (unsigned i=0, N = constValues.size(); i < N; i++) { 240 const Constant* field = cast<Constant>(constValues[i].get()); 241 242 // Check if padding is needed and insert one or more 0s. 243 unsigned fieldSize = TD.getTypeSize(field->getType()); 244 unsigned padSize = ((i == N-1? cvsLayout->StructSize 245 : cvsLayout->MemberOffsets[i+1]) 246 - cvsLayout->MemberOffsets[i]) - fieldSize; 247 sizeSoFar += fieldSize + padSize; 248 249 // Now print the actual field value 250 emitGlobalConstant(field); 251 252 // Insert the field padding unless it's zero bytes... 253 if (padSize) 254 O << "\t.space\t " << padSize << "\n"; 255 } 256 assert(sizeSoFar == cvsLayout->StructSize && 257 "Layout of constant struct may be incorrect!"); 258 return; 259 } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { 260 // FP Constants are printed as integer constants to avoid losing 261 // precision... 262 double Val = CFP->getValue(); 263 switch (CFP->getType()->getTypeID()) { 264 default: assert(0 && "Unknown floating point type!"); 265 case Type::FloatTyID: { 266 union FU { // Abide by C TBAA rules 267 float FVal; 268 unsigned UVal; 269 } U; 270 U.FVal = Val; 271 O << ".long\t" << U.UVal << "\t# float " << Val << "\n"; 272 return; 273 } 274 case Type::DoubleTyID: { 275 union DU { // Abide by C TBAA rules 276 double FVal; 277 uint64_t UVal; 278 struct { 279 uint32_t MSWord; 280 uint32_t LSWord; 281 } T; 282 } U; 283 U.FVal = Val; 284 285 O << ".long\t" << U.T.MSWord << "\t# double most significant word " 286 << Val << "\n"; 287 O << ".long\t" << U.T.LSWord << "\t# double least significant word" 288 << Val << "\n"; 289 return; 290 } 291 } 292 } else if (CV->getType()->getPrimitiveSize() == 64) { 293 if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { 294 union DU { // Abide by C TBAA rules 295 int64_t UVal; 296 struct { 297 uint32_t MSWord; 298 uint32_t LSWord; 299 } T; 300 } U; 301 U.UVal = CI->getRawValue(); 302 303 O << ".long\t" << U.T.MSWord << "\t# Double-word most significant word " 304 << U.UVal << "\n"; 305 O << ".long\t" << U.T.LSWord << "\t# Double-word least significant word" 306 << U.UVal << "\n"; 307 return; 308 } 309 } 310 311 const Type *type = CV->getType(); 312 O << "\t"; 313 switch (type->getTypeID()) { 314 case Type::UByteTyID: case Type::SByteTyID: 315 O << ".byte"; 316 break; 317 case Type::UShortTyID: case Type::ShortTyID: 318 O << ".short"; 319 break; 320 case Type::BoolTyID: 321 case Type::PointerTyID: 322 case Type::UIntTyID: case Type::IntTyID: 323 O << ".long"; 324 break; 325 case Type::ULongTyID: case Type::LongTyID: 326 assert (0 && "Should have already output double-word constant."); 327 case Type::FloatTyID: case Type::DoubleTyID: 328 assert (0 && "Should have already output floating point constant."); 329 default: 330 assert (0 && "Can't handle printing this type of thing"); 331 break; 332 } 333 O << "\t"; 334 emitConstantValueOnly(CV); 335 O << "\n"; 336} 337 338/// printConstantPool - Print to the current output stream assembly 339/// representations of the constants in the constant pool MCP. This is 340/// used to print out constants which have been "spilled to memory" by 341/// the code generator. 342/// 343void Printer::printConstantPool(MachineConstantPool *MCP) { 344 const std::vector<Constant*> &CP = MCP->getConstants(); 345 const TargetData &TD = TM.getTargetData(); 346 347 if (CP.empty()) return; 348 349 for (unsigned i = 0, e = CP.size(); i != e; ++i) { 350 O << "\t.const\n"; 351 O << "\t.align " << (unsigned)TD.getTypeAlignment(CP[i]->getType()) 352 << "\n"; 353 O << ".CPI" << CurrentFnName << "_" << i << ":\t\t\t\t\t#" 354 << *CP[i] << "\n"; 355 emitGlobalConstant(CP[i]); 356 } 357} 358 359/// runOnMachineFunction - This uses the printMachineInstruction() 360/// method to print assembly for each instruction. 361/// 362bool Printer::runOnMachineFunction(MachineFunction &MF) { 363 // BBNumber is used here so that a given Printer will never give two 364 // BBs the same name. (If you have a better way, please let me know!) 365 static unsigned BBNumber = 0; 366 367 O << "\n\n"; 368 // What's my mangled name? 369 CurrentFnName = Mang->getValueName(MF.getFunction()); 370 371 // Print out constants referenced by the function 372 printConstantPool(MF.getConstantPool()); 373 374 // Print out labels for the function. 375 O << "\t.text\n"; 376 O << "\t.globl\t" << CurrentFnName << "\n"; 377 O << "\t.align 5\n"; 378 O << CurrentFnName << ":\n"; 379 380 // Print out code for the function. 381 for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); 382 I != E; ++I) { 383 // Print a label for the basic block. 384 O << ".LBB" << CurrentFnName << "_" << I->getNumber() << ":\t# " 385 << I->getBasicBlock()->getName() << "\n"; 386 for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end(); 387 II != E; ++II) { 388 // Print the assembly for the instruction. 389 O << "\t"; 390 printMachineInstruction(II); 391 } 392 } 393 394 // We didn't modify anything. 395 return false; 396} 397 398void Printer::printOp(const MachineOperand &MO, 399 bool elideOffsetKeyword /* = false */) { 400 const MRegisterInfo &RI = *TM.getRegisterInfo(); 401 int new_symbol; 402 403 switch (MO.getType()) { 404 case MachineOperand::MO_VirtualRegister: 405 if (Value *V = MO.getVRegValueOrNull()) { 406 O << "<" << V->getName() << ">"; 407 return; 408 } 409 // FALLTHROUGH 410 case MachineOperand::MO_MachineRegister: 411 O << LowercaseString(RI.get(MO.getReg()).Name); 412 return; 413 414 case MachineOperand::MO_SignExtendedImmed: 415 case MachineOperand::MO_UnextendedImmed: 416 O << (int)MO.getImmedValue(); 417 return; 418 case MachineOperand::MO_MachineBasicBlock: { 419 MachineBasicBlock *MBBOp = MO.getMachineBasicBlock(); 420 O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction()) 421 << "_" << MBBOp->getNumber() << "\t# " 422 << MBBOp->getBasicBlock()->getName(); 423 return; 424 } 425 case MachineOperand::MO_PCRelativeDisp: 426 std::cerr << "Shouldn't use addPCDisp() when building PPC MachineInstrs"; 427 abort (); 428 return; 429 case MachineOperand::MO_GlobalAddress: 430 if (!elideOffsetKeyword) { 431 if(isa<Function>(MO.getGlobal())) { 432 Stubs.insert(Mang->getValueName(MO.getGlobal())); 433 O << "L" << Mang->getValueName(MO.getGlobal()) << "$stub"; 434 } else { 435 O << Mang->getValueName(MO.getGlobal()); 436 } 437 } 438 return; 439 case MachineOperand::MO_ExternalSymbol: 440 O << MO.getSymbolName(); 441 return; 442 default: 443 O << "<unknown operand type>"; 444 return; 445 } 446} 447 448#if 0 449static inline 450unsigned int ValidOpcodes(const MachineInstr *MI, unsigned int ArgType[5]) { 451 int i; 452 unsigned int retval = 1; 453 454 for(i = 0; i<5; i++) { 455 switch(ArgType[i]) { 456 case none: 457 break; 458 case Gpr: 459 case Gpr0: 460 Type::UIntTy 461 case Simm16: 462 case Zimm16: 463 case PCRelimm24: 464 case Imm24: 465 case Imm5: 466 case PCRelimm14: 467 case Imm14: 468 case Imm2: 469 case Crf: 470 case Imm3: 471 case Imm1: 472 case Fpr: 473 case Imm4: 474 case Imm8: 475 case Disimm16: 476 case Spr: 477 case Sgr: 478 }; 479 480 } 481 } 482} 483#endif 484 485/// printMachineInstruction -- Print out a single PPC32 LLVM instruction 486/// MI in Darwin syntax to the current output stream. 487/// 488void Printer::printMachineInstruction(const MachineInstr *MI) { 489 unsigned Opcode = MI->getOpcode(); 490 const TargetInstrInfo &TII = *TM.getInstrInfo(); 491 const TargetInstrDescriptor &Desc = TII.get(Opcode); 492 unsigned int i; 493 494 unsigned int ArgCount = Desc.TSFlags & PPC32II::ArgCountMask; 495 unsigned int ArgType[] = { 496 (Desc.TSFlags >> PPC32II::Arg0TypeShift) & PPC32II::ArgTypeMask, 497 (Desc.TSFlags >> PPC32II::Arg1TypeShift) & PPC32II::ArgTypeMask, 498 (Desc.TSFlags >> PPC32II::Arg2TypeShift) & PPC32II::ArgTypeMask, 499 (Desc.TSFlags >> PPC32II::Arg3TypeShift) & PPC32II::ArgTypeMask, 500 (Desc.TSFlags >> PPC32II::Arg4TypeShift) & PPC32II::ArgTypeMask 501 }; 502 assert(((Desc.TSFlags & PPC32II::VMX) == 0) && 503 "Instruction requires VMX support"); 504 assert(((Desc.TSFlags & PPC32II::PPC64) == 0) && 505 "Instruction requires 64 bit support"); 506 //assert ( ValidOpcodes(MI, ArgType) && "Instruction has invalid inputs"); 507 ++EmittedInsts; 508 509 if (Opcode == PPC32::MovePCtoLR) { 510 O << "mflr r0\n"; 511 O << "bcl 20,31,L" << CurrentFnName << "$pb\n"; 512 O << "L" << CurrentFnName << "$pb:\n"; 513 return; 514 } 515 516 O << TII.getName(MI->getOpcode()) << " "; 517 DEBUG(std::cerr << TII.getName(MI->getOpcode()) << " expects " 518 << ArgCount << " args\n"); 519 520 if (Opcode == PPC32::LOADLoAddr) { 521 printOp(MI->getOperand(0)); 522 O << ", "; 523 printOp(MI->getOperand(1)); 524 O << ", lo16("; 525 printOp(MI->getOperand(2)); 526 O << "-L" << CurrentFnName << "$pb)\n"; 527 return; 528 } 529 530 if (Opcode == PPC32::LOADHiAddr) { 531 printOp(MI->getOperand(0)); 532 O << ", "; 533 printOp(MI->getOperand(1)); 534 O << ", ha16(" ; 535 printOp(MI->getOperand(2)); 536 O << "-L" << CurrentFnName << "$pb)\n"; 537 return; 538 } 539 540 if (ArgCount == 3 && ArgType[1] == PPC32II::Disimm16) { 541 printOp(MI->getOperand(0)); 542 O << ", "; 543 printOp(MI->getOperand(1)); 544 O << "("; 545 if (ArgType[2] == PPC32II::Gpr0 && MI->getOperand(2).getReg() == PPC32::R0) 546 O << "0"; 547 else 548 printOp(MI->getOperand(2)); 549 O << ")\n"; 550 } else { 551 for (i = 0; i < ArgCount; ++i) { 552 if (ArgType[i] == PPC32II::Gpr0 && 553 MI->getOperand(i).getReg() == PPC32::R0) 554 O << "0"; 555 else { 556 //std::cout << "DEBUG " << (*(TM.getRegisterInfo())).get(MI->getOperand(i).getReg()).Name << "\n"; 557 printOp(MI->getOperand(i)); 558 } 559 if (ArgCount - 1 == i) 560 O << "\n"; 561 else 562 O << ", "; 563 } 564 } 565 566 return; 567} 568 569bool Printer::doInitialization(Module &M) { 570 Mang = new Mangler(M, true); 571 return false; // success 572} 573 574// SwitchSection - Switch to the specified section of the executable if we are 575// not already in it! 576// 577static void SwitchSection(std::ostream &OS, std::string &CurSection, 578 const char *NewSection) { 579 if (CurSection != NewSection) { 580 CurSection = NewSection; 581 if (!CurSection.empty()) 582 OS << "\t" << NewSection << "\n"; 583 } 584} 585 586bool Printer::doFinalization(Module &M) { 587 const TargetData &TD = TM.getTargetData(); 588 std::string CurSection; 589 590 // Print out module-level global variables here. 591 for (Module::const_giterator I = M.gbegin(), E = M.gend(); I != E; ++I) 592 if (I->hasInitializer()) { // External global require no code 593 O << "\n\n"; 594 std::string name = Mang->getValueName(I); 595 Constant *C = I->getInitializer(); 596 unsigned Size = TD.getTypeSize(C->getType()); 597 unsigned Align = TD.getTypeAlignment(C->getType()); 598 599 if (C->isNullValue() && 600 (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || 601 I->hasWeakLinkage() /* FIXME: Verify correct */)) { 602 SwitchSection(O, CurSection, ".data"); 603 if (I->hasInternalLinkage()) 604 O << "\t.local " << name << "\n"; 605 606 O << "\t.comm " << name << "," << TD.getTypeSize(C->getType()) 607 << "," << (unsigned)TD.getTypeAlignment(C->getType()); 608 O << "\t\t# "; 609 WriteAsOperand(O, I, true, true, &M); 610 O << "\n"; 611 } else { 612 switch (I->getLinkage()) { 613 case GlobalValue::LinkOnceLinkage: 614 case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak. 615 // Nonnull linkonce -> weak 616 O << "\t.weak " << name << "\n"; 617 SwitchSection(O, CurSection, ""); 618 O << "\t.section\t.llvm.linkonce.d." << name << ",\"aw\",@progbits\n"; 619 break; 620 621 case GlobalValue::AppendingLinkage: 622 // FIXME: appending linkage variables should go into a section of 623 // their name or something. For now, just emit them as external. 624 case GlobalValue::ExternalLinkage: 625 // If external or appending, declare as a global symbol 626 O << "\t.globl " << name << "\n"; 627 // FALL THROUGH 628 case GlobalValue::InternalLinkage: 629 if (C->isNullValue()) 630 SwitchSection(O, CurSection, ".bss"); 631 else 632 SwitchSection(O, CurSection, ".data"); 633 break; 634 } 635 636 O << "\t.align " << Align << "\n"; 637 O << name << ":\t\t\t\t# "; 638 WriteAsOperand(O, I, true, true, &M); 639 O << " = "; 640 WriteAsOperand(O, C, false, false, &M); 641 O << "\n"; 642 emitGlobalConstant(C); 643 } 644 } 645 646 for(std::set<std::string>::iterator i = Stubs.begin(); i != Stubs.end(); ++i) 647 { 648 O << ".data\n"; 649 O<<".section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32\n"; 650 O << "\t.align 2\n"; 651 O << "L" << *i << "$stub:\n"; 652 O << "\t.indirect_symbol " << *i << "\n"; 653 O << "\tmflr r0\n"; 654 O << "\tbcl 20,31,L0$" << *i << "\n"; 655 O << "L0$" << *i << ":\n"; 656 O << "\tmflr r11\n"; 657 O << "\taddis r11,r11,ha16(L" << *i << "$lazy_ptr-L0$" << *i << ")\n"; 658 O << "\tmtlr r0\n"; 659 O << "\tlwzu r12,lo16(L" << *i << "$lazy_ptr-L0$" << *i << ")(r11)\n"; 660 O << "\tmtctr r12\n"; 661 O << "\tbctr\n"; 662 O << ".data\n"; 663 O << ".lazy_symbol_pointer\n"; 664 O << "L" << *i << "$lazy_ptr:\n"; 665 O << ".indirect_symbol " << *i << "\n"; 666 O << ".long dyld_stub_binding_helper\n"; 667 } 668 669 delete Mang; 670 return false; // success 671} 672 673} // End llvm namespace 674