PPCAsmPrinter.cpp revision dd57417c08d3fbb52935b70cf14edef34535d045
1//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly --------=// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains a printer that converts from our internal representation 11// of machine-dependent LLVM code to PowerPC assembly language. This printer is 12// the output mechanism used by `llc'. 13// 14// Documentation at http://developer.apple.com/documentation/DeveloperTools/ 15// Reference/Assembler/ASMIntroduction/chapter_1_section_1.html 16// 17//===----------------------------------------------------------------------===// 18 19#define DEBUG_TYPE "asmprinter" 20#include "PPC.h" 21#include "PPCPredicates.h" 22#include "PPCTargetMachine.h" 23#include "PPCSubtarget.h" 24#include "llvm/Analysis/DebugInfo.h" 25#include "llvm/Constants.h" 26#include "llvm/DerivedTypes.h" 27#include "llvm/Module.h" 28#include "llvm/Assembly/Writer.h" 29#include "llvm/CodeGen/AsmPrinter.h" 30#include "llvm/CodeGen/MachineFunctionPass.h" 31#include "llvm/CodeGen/MachineInstr.h" 32#include "llvm/CodeGen/MachineInstrBuilder.h" 33#include "llvm/CodeGen/MachineModuleInfoImpls.h" 34#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" 35#include "llvm/MC/MCAsmInfo.h" 36#include "llvm/MC/MCContext.h" 37#include "llvm/MC/MCExpr.h" 38#include "llvm/MC/MCInst.h" 39#include "llvm/MC/MCSectionMachO.h" 40#include "llvm/MC/MCStreamer.h" 41#include "llvm/MC/MCSymbol.h" 42#include "llvm/Target/Mangler.h" 43#include "llvm/Target/TargetRegisterInfo.h" 44#include "llvm/Target/TargetInstrInfo.h" 45#include "llvm/Target/TargetOptions.h" 46#include "llvm/Target/TargetRegistry.h" 47#include "llvm/Support/CommandLine.h" 48#include "llvm/Support/Debug.h" 49#include "llvm/Support/MathExtras.h" 50#include "llvm/Support/ErrorHandling.h" 51#include "llvm/Support/raw_ostream.h" 52#include "llvm/ADT/StringExtras.h" 53#include "llvm/ADT/StringSet.h" 54#include "llvm/ADT/SmallString.h" 55#include "InstPrinter/PPCInstPrinter.h" 56using namespace llvm; 57 58// This option tells the asmprinter to use the new (experimental) MCInstPrinter 59// path. 60static cl::opt<bool> UseInstPrinter("enable-ppc-inst-printer", 61 cl::ReallyHidden 62 //, cl::init(true) 63 ); 64 65namespace { 66 class PPCAsmPrinter : public AsmPrinter { 67 protected: 68 DenseMap<MCSymbol*, MCSymbol*> TOC; 69 const PPCSubtarget &Subtarget; 70 uint64_t LabelID; 71 public: 72 explicit PPCAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 73 : AsmPrinter(TM, Streamer), 74 Subtarget(TM.getSubtarget<PPCSubtarget>()), LabelID(0) {} 75 76 virtual const char *getPassName() const { 77 return "PowerPC Assembly Printer"; 78 } 79 80 unsigned enumRegToMachineReg(unsigned enumReg) { 81 switch (enumReg) { 82 default: llvm_unreachable("Unhandled register!"); 83 case PPC::CR0: return 0; 84 case PPC::CR1: return 1; 85 case PPC::CR2: return 2; 86 case PPC::CR3: return 3; 87 case PPC::CR4: return 4; 88 case PPC::CR5: return 5; 89 case PPC::CR6: return 6; 90 case PPC::CR7: return 7; 91 } 92 llvm_unreachable(0); 93 } 94 95 /// printInstruction - This method is automatically generated by tablegen 96 /// from the instruction set description. This method returns true if the 97 /// machine instruction was sufficiently described to print it, otherwise it 98 /// returns false. 99 void printInstruction(const MachineInstr *MI, raw_ostream &O); 100 static const char *getRegisterName(unsigned RegNo); 101 102 103 virtual void EmitInstruction(const MachineInstr *MI); 104 void printOp(const MachineOperand &MO, raw_ostream &O); 105 106 /// stripRegisterPrefix - This method strips the character prefix from a 107 /// register name so that only the number is left. Used by for linux asm. 108 const char *stripRegisterPrefix(const char *RegName) { 109 switch (RegName[0]) { 110 case 'r': 111 case 'f': 112 case 'v': return RegName + 1; 113 case 'c': if (RegName[1] == 'r') return RegName + 2; 114 } 115 116 return RegName; 117 } 118 119 /// printRegister - Print register according to target requirements. 120 /// 121 void printRegister(const MachineOperand &MO, bool R0AsZero, raw_ostream &O){ 122 unsigned RegNo = MO.getReg(); 123 assert(TargetRegisterInfo::isPhysicalRegister(RegNo) && "Not physreg??"); 124 125 // If we should use 0 for R0. 126 if (R0AsZero && RegNo == PPC::R0) { 127 O << "0"; 128 return; 129 } 130 131 const char *RegName = getRegisterName(RegNo); 132 // Linux assembler (Others?) does not take register mnemonics. 133 // FIXME - What about special registers used in mfspr/mtspr? 134 if (!Subtarget.isDarwin()) RegName = stripRegisterPrefix(RegName); 135 O << RegName; 136 } 137 138 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 139 const MachineOperand &MO = MI->getOperand(OpNo); 140 if (MO.isReg()) { 141 printRegister(MO, false, O); 142 } else if (MO.isImm()) { 143 O << MO.getImm(); 144 } else { 145 printOp(MO, O); 146 } 147 } 148 149 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 150 unsigned AsmVariant, const char *ExtraCode, 151 raw_ostream &O); 152 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 153 unsigned AsmVariant, const char *ExtraCode, 154 raw_ostream &O); 155 156 157 void printS5ImmOperand(const MachineInstr *MI, unsigned OpNo, 158 raw_ostream &O) { 159 char value = MI->getOperand(OpNo).getImm(); 160 value = (value << (32-5)) >> (32-5); 161 O << (int)value; 162 } 163 void printU5ImmOperand(const MachineInstr *MI, unsigned OpNo, 164 raw_ostream &O) { 165 unsigned char value = MI->getOperand(OpNo).getImm(); 166 assert(value <= 31 && "Invalid u5imm argument!"); 167 O << (unsigned int)value; 168 } 169 void printU6ImmOperand(const MachineInstr *MI, unsigned OpNo, 170 raw_ostream &O) { 171 unsigned char value = MI->getOperand(OpNo).getImm(); 172 assert(value <= 63 && "Invalid u6imm argument!"); 173 O << (unsigned int)value; 174 } 175 void printS16ImmOperand(const MachineInstr *MI, unsigned OpNo, 176 raw_ostream &O) { 177 O << (short)MI->getOperand(OpNo).getImm(); 178 } 179 void printU16ImmOperand(const MachineInstr *MI, unsigned OpNo, 180 raw_ostream &O) { 181 O << (unsigned short)MI->getOperand(OpNo).getImm(); 182 } 183 void printS16X4ImmOperand(const MachineInstr *MI, unsigned OpNo, 184 raw_ostream &O) { 185 if (MI->getOperand(OpNo).isImm()) { 186 O << (short)(MI->getOperand(OpNo).getImm()*4); 187 } else { 188 O << "lo16("; 189 printOp(MI->getOperand(OpNo), O); 190 if (TM.getRelocationModel() == Reloc::PIC_) 191 O << "-\"L" << getFunctionNumber() << "$pb\")"; 192 else 193 O << ')'; 194 } 195 } 196 void printBranchOperand(const MachineInstr *MI, unsigned OpNo, 197 raw_ostream &O) { 198 // Branches can take an immediate operand. This is used by the branch 199 // selection pass to print $+8, an eight byte displacement from the PC. 200 if (MI->getOperand(OpNo).isImm()) { 201 O << "$+" << MI->getOperand(OpNo).getImm()*4; 202 } else { 203 printOp(MI->getOperand(OpNo), O); 204 } 205 } 206 void printCallOperand(const MachineInstr *MI, unsigned OpNo, 207 raw_ostream &O) { 208 const MachineOperand &MO = MI->getOperand(OpNo); 209 if (TM.getRelocationModel() != Reloc::Static) { 210 if (MO.isGlobal()) { 211 const GlobalValue *GV = MO.getGlobal(); 212 if (GV->isDeclaration() || GV->isWeakForLinker()) { 213 // Dynamically-resolved functions need a stub for the function. 214 MCSymbol *Sym = GetSymbolWithGlobalValueBase(GV, "$stub"); 215 MachineModuleInfoImpl::StubValueTy &StubSym = 216 MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym); 217 if (StubSym.getPointer() == 0) 218 StubSym = MachineModuleInfoImpl:: 219 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 220 O << *Sym; 221 return; 222 } 223 } 224 if (MO.isSymbol()) { 225 SmallString<128> TempNameStr; 226 TempNameStr += StringRef(MO.getSymbolName()); 227 TempNameStr += StringRef("$stub"); 228 229 MCSymbol *Sym = GetExternalSymbolSymbol(TempNameStr.str()); 230 MachineModuleInfoImpl::StubValueTy &StubSym = 231 MMI->getObjFileInfo<MachineModuleInfoMachO>().getFnStubEntry(Sym); 232 if (StubSym.getPointer() == 0) 233 StubSym = MachineModuleInfoImpl:: 234 StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true); 235 O << *Sym; 236 return; 237 } 238 } 239 240 printOp(MI->getOperand(OpNo), O); 241 } 242 void printAbsAddrOperand(const MachineInstr *MI, unsigned OpNo, 243 raw_ostream &O) { 244 O << (int)MI->getOperand(OpNo).getImm()*4; 245 } 246 void printPICLabel(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 247 O << "\"L" << getFunctionNumber() << "$pb\"\n"; 248 O << "\"L" << getFunctionNumber() << "$pb\":"; 249 } 250 void printSymbolHi(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 251 if (MI->getOperand(OpNo).isImm()) { 252 printS16ImmOperand(MI, OpNo, O); 253 } else { 254 if (Subtarget.isDarwin()) O << "ha16("; 255 printOp(MI->getOperand(OpNo), O); 256 if (TM.getRelocationModel() == Reloc::PIC_) 257 O << "-L" << getFunctionNumber() << "$pb"; 258 if (Subtarget.isDarwin()) 259 O << ')'; 260 else 261 O << "@ha"; 262 } 263 } 264 void printSymbolLo(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 265 if (MI->getOperand(OpNo).isImm()) { 266 printS16ImmOperand(MI, OpNo, O); 267 } else { 268 if (Subtarget.isDarwin()) O << "lo16("; 269 printOp(MI->getOperand(OpNo), O); 270 if (TM.getRelocationModel() == Reloc::PIC_) 271 O << "-L" << getFunctionNumber() << "$pb"; 272 if (Subtarget.isDarwin()) 273 O << ')'; 274 else 275 O << "@l"; 276 } 277 } 278 void printcrbitm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 279 unsigned CCReg = MI->getOperand(OpNo).getReg(); 280 unsigned RegNo = enumRegToMachineReg(CCReg); 281 O << (0x80 >> RegNo); 282 } 283 // The new addressing mode printers. 284 void printMemRegImm(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 285 printSymbolLo(MI, OpNo, O); 286 O << '('; 287 if (MI->getOperand(OpNo+1).isReg() && 288 MI->getOperand(OpNo+1).getReg() == PPC::R0) 289 O << "0"; 290 else 291 printOperand(MI, OpNo+1, O); 292 O << ')'; 293 } 294 void printMemRegImmShifted(const MachineInstr *MI, unsigned OpNo, 295 raw_ostream &O) { 296 if (MI->getOperand(OpNo).isImm()) 297 printS16X4ImmOperand(MI, OpNo, O); 298 else 299 printSymbolLo(MI, OpNo, O); 300 O << '('; 301 if (MI->getOperand(OpNo+1).isReg() && 302 MI->getOperand(OpNo+1).getReg() == PPC::R0) 303 O << "0"; 304 else 305 printOperand(MI, OpNo+1, O); 306 O << ')'; 307 } 308 309 void printMemRegReg(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { 310 // When used as the base register, r0 reads constant zero rather than 311 // the value contained in the register. For this reason, the darwin 312 // assembler requires that we print r0 as 0 (no r) when used as the base. 313 const MachineOperand &MO = MI->getOperand(OpNo); 314 printRegister(MO, true, O); 315 O << ", "; 316 printOperand(MI, OpNo+1, O); 317 } 318 319 void printTOCEntryLabel(const MachineInstr *MI, unsigned OpNo, 320 raw_ostream &O) { 321 const MachineOperand &MO = MI->getOperand(OpNo); 322 assert(MO.isGlobal()); 323 MCSymbol *Sym = Mang->getSymbol(MO.getGlobal()); 324 325 // Map symbol -> label of TOC entry. 326 MCSymbol *&TOCEntry = TOC[Sym]; 327 if (TOCEntry == 0) 328 TOCEntry = OutContext. 329 GetOrCreateSymbol(StringRef(MAI->getPrivateGlobalPrefix()) + 330 "C" + Twine(LabelID++)); 331 332 O << *TOCEntry << "@toc"; 333 } 334 335 void printPredicateOperand(const MachineInstr *MI, unsigned OpNo, 336 raw_ostream &O, const char *Modifier); 337 338 MachineLocation getDebugValueLocation(const MachineInstr *MI) const { 339 340 MachineLocation Location; 341 assert (MI->getNumOperands() == 4 && "Invalid no. of machine operands!"); 342 // Frame address. Currently handles register +- offset only. 343 if (MI->getOperand(0).isReg() && MI->getOperand(2).isImm()) 344 Location.set(MI->getOperand(0).getReg(), MI->getOperand(2).getImm()); 345 else { 346 DEBUG(dbgs() << "DBG_VALUE instruction ignored! " << *MI << "\n"); 347 } 348 return Location; 349 } 350 }; 351 352 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux 353 class PPCLinuxAsmPrinter : public PPCAsmPrinter { 354 public: 355 explicit PPCLinuxAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 356 : PPCAsmPrinter(TM, Streamer) {} 357 358 virtual const char *getPassName() const { 359 return "Linux PPC Assembly Printer"; 360 } 361 362 bool doFinalization(Module &M); 363 364 virtual void EmitFunctionEntryLabel(); 365 }; 366 367 /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac 368 /// OS X 369 class PPCDarwinAsmPrinter : public PPCAsmPrinter { 370 public: 371 explicit PPCDarwinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer) 372 : PPCAsmPrinter(TM, Streamer) {} 373 374 virtual const char *getPassName() const { 375 return "Darwin PPC Assembly Printer"; 376 } 377 378 bool doFinalization(Module &M); 379 void EmitStartOfAsmFile(Module &M); 380 381 void EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs); 382 }; 383} // end of anonymous namespace 384 385// Include the auto-generated portion of the assembly writer 386#include "PPCGenAsmWriter.inc" 387 388void PPCAsmPrinter::printOp(const MachineOperand &MO, raw_ostream &O) { 389 switch (MO.getType()) { 390 case MachineOperand::MO_Immediate: 391 llvm_unreachable("printOp() does not handle immediate values"); 392 393 case MachineOperand::MO_MachineBasicBlock: 394 O << *MO.getMBB()->getSymbol(); 395 return; 396 case MachineOperand::MO_JumpTableIndex: 397 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() 398 << '_' << MO.getIndex(); 399 // FIXME: PIC relocation model 400 return; 401 case MachineOperand::MO_ConstantPoolIndex: 402 O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() 403 << '_' << MO.getIndex(); 404 return; 405 case MachineOperand::MO_BlockAddress: 406 O << *GetBlockAddressSymbol(MO.getBlockAddress()); 407 return; 408 case MachineOperand::MO_ExternalSymbol: { 409 // Computing the address of an external symbol, not calling it. 410 if (TM.getRelocationModel() == Reloc::Static) { 411 O << *GetExternalSymbolSymbol(MO.getSymbolName()); 412 return; 413 } 414 415 MCSymbol *NLPSym = 416 OutContext.GetOrCreateSymbol(StringRef(MAI->getGlobalPrefix())+ 417 MO.getSymbolName()+"$non_lazy_ptr"); 418 MachineModuleInfoImpl::StubValueTy &StubSym = 419 MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(NLPSym); 420 if (StubSym.getPointer() == 0) 421 StubSym = MachineModuleInfoImpl:: 422 StubValueTy(GetExternalSymbolSymbol(MO.getSymbolName()), true); 423 424 O << *NLPSym; 425 return; 426 } 427 case MachineOperand::MO_GlobalAddress: { 428 // Computing the address of a global symbol, not calling it. 429 const GlobalValue *GV = MO.getGlobal(); 430 MCSymbol *SymToPrint; 431 432 // External or weakly linked global variables need non-lazily-resolved stubs 433 if (TM.getRelocationModel() != Reloc::Static && 434 (GV->isDeclaration() || GV->isWeakForLinker())) { 435 if (!GV->hasHiddenVisibility()) { 436 SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 437 MachineModuleInfoImpl::StubValueTy &StubSym = 438 MMI->getObjFileInfo<MachineModuleInfoMachO>() 439 .getGVStubEntry(SymToPrint); 440 if (StubSym.getPointer() == 0) 441 StubSym = MachineModuleInfoImpl:: 442 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 443 } else if (GV->isDeclaration() || GV->hasCommonLinkage() || 444 GV->hasAvailableExternallyLinkage()) { 445 SymToPrint = GetSymbolWithGlobalValueBase(GV, "$non_lazy_ptr"); 446 447 MachineModuleInfoImpl::StubValueTy &StubSym = 448 MMI->getObjFileInfo<MachineModuleInfoMachO>(). 449 getHiddenGVStubEntry(SymToPrint); 450 if (StubSym.getPointer() == 0) 451 StubSym = MachineModuleInfoImpl:: 452 StubValueTy(Mang->getSymbol(GV), !GV->hasInternalLinkage()); 453 } else { 454 SymToPrint = Mang->getSymbol(GV); 455 } 456 } else { 457 SymToPrint = Mang->getSymbol(GV); 458 } 459 460 O << *SymToPrint; 461 462 printOffset(MO.getOffset(), O); 463 return; 464 } 465 466 default: 467 O << "<unknown operand type: " << MO.getType() << ">"; 468 return; 469 } 470} 471 472/// PrintAsmOperand - Print out an operand for an inline asm expression. 473/// 474bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, 475 unsigned AsmVariant, 476 const char *ExtraCode, raw_ostream &O) { 477 // Does this asm operand have a single letter operand modifier? 478 if (ExtraCode && ExtraCode[0]) { 479 if (ExtraCode[1] != 0) return true; // Unknown modifier. 480 481 switch (ExtraCode[0]) { 482 default: return true; // Unknown modifier. 483 case 'c': // Don't print "$" before a global var name or constant. 484 // PPC never has a prefix. 485 printOperand(MI, OpNo, O); 486 return false; 487 case 'L': // Write second word of DImode reference. 488 // Verify that this operand has two consecutive registers. 489 if (!MI->getOperand(OpNo).isReg() || 490 OpNo+1 == MI->getNumOperands() || 491 !MI->getOperand(OpNo+1).isReg()) 492 return true; 493 ++OpNo; // Return the high-part. 494 break; 495 case 'I': 496 // Write 'i' if an integer constant, otherwise nothing. Used to print 497 // addi vs add, etc. 498 if (MI->getOperand(OpNo).isImm()) 499 O << "i"; 500 return false; 501 } 502 } 503 504 printOperand(MI, OpNo, O); 505 return false; 506} 507 508// At the moment, all inline asm memory operands are a single register. 509// In any case, the output of this routine should always be just one 510// assembler operand. 511 512bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, 513 unsigned AsmVariant, 514 const char *ExtraCode, 515 raw_ostream &O) { 516 if (ExtraCode && ExtraCode[0]) 517 return true; // Unknown modifier. 518 assert (MI->getOperand(OpNo).isReg()); 519 O << "0("; 520 printOperand(MI, OpNo, O); 521 O << ")"; 522 return false; 523} 524 525void PPCAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo, 526 raw_ostream &O, const char *Modifier){ 527 assert(Modifier && "Must specify 'cc' or 'reg' as predicate op modifier!"); 528 unsigned Code = MI->getOperand(OpNo).getImm(); 529 if (!strcmp(Modifier, "cc")) { 530 switch ((PPC::Predicate)Code) { 531 case PPC::PRED_ALWAYS: return; // Don't print anything for always. 532 case PPC::PRED_LT: O << "lt"; return; 533 case PPC::PRED_LE: O << "le"; return; 534 case PPC::PRED_EQ: O << "eq"; return; 535 case PPC::PRED_GE: O << "ge"; return; 536 case PPC::PRED_GT: O << "gt"; return; 537 case PPC::PRED_NE: O << "ne"; return; 538 case PPC::PRED_UN: O << "un"; return; 539 case PPC::PRED_NU: O << "nu"; return; 540 } 541 542 } else { 543 assert(!strcmp(Modifier, "reg") && 544 "Need to specify 'cc' or 'reg' as predicate op modifier!"); 545 // Don't print the register for 'always'. 546 if (Code == PPC::PRED_ALWAYS) return; 547 printOperand(MI, OpNo+1, O); 548 } 549} 550 551/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to 552/// the current output stream. 553/// 554void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) { 555 if (UseInstPrinter) { 556 MCInst TmpInst; 557 558 // Lower multi-instruction pseudo operations. 559 switch (MI->getOpcode()) { 560 default: break; 561 case PPC::MovePCtoLR: 562 case PPC::MovePCtoLR8: { 563 // Transform %LR = MovePCtoLR 564 // Into this, where the label is the PIC base: 565 // bl L1$pb 566 // L1$pb: 567 MCSymbol *PICBase = MF->getPICBaseSymbol(); 568 569 // Emit the 'bl'. 570 TmpInst.setOpcode(PPC::BL_Darwin); // Darwin vs SVR4 doesn't matter here. 571 572 573 // FIXME: We would like an efficient form for this, so we don't have to do 574 // a lot of extra uniquing. 575 TmpInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr:: 576 Create(PICBase, OutContext))); 577 OutStreamer.EmitInstruction(TmpInst); 578 579 // Emit the label. 580 OutStreamer.EmitLabel(PICBase); 581 return; 582 } 583 case PPC::LDtoc: { 584 // Transform %X3 = LDtoc <ga:@min1>, %X2 585 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); 586 587 // Change the opcode to LD, and the global address operand to be a 588 // reference to the TOC entry we will synthesize later. 589 TmpInst.setOpcode(PPC::LD); 590 const MachineOperand &MO = MI->getOperand(1); 591 assert(MO.isGlobal()); 592 593 // Map symbol -> label of TOC entry. 594 MCSymbol *&TOCEntry = TOC[Mang->getSymbol(MO.getGlobal())]; 595 if (TOCEntry == 0) { 596 TOCEntry = OutContext. 597 GetOrCreateSymbol(StringRef(MAI->getPrivateGlobalPrefix()) + 598 "C" + Twine(LabelID++)); 599 } 600 601 const MCExpr *Exp = 602 MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC, 603 OutContext); 604 TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp); 605 OutStreamer.EmitInstruction(TmpInst); 606 return; 607 } 608 609 case PPC::MFCRpseud: 610 // Transform: %R3 = MFCRpseud %CR7 611 // Into: %R3 = MFCR ;; cr7 612 OutStreamer.AddComment(getRegisterName(MI->getOperand(1).getReg())); 613 TmpInst.setOpcode(PPC::MFCR); 614 TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg())); 615 OutStreamer.EmitInstruction(TmpInst); 616 return; 617 } 618 619 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this); 620 OutStreamer.EmitInstruction(TmpInst); 621 return; 622 } 623 624 625 SmallString<128> Str; 626 raw_svector_ostream O(Str); 627 628 if (MI->getOpcode() == TargetOpcode::DBG_VALUE) { 629 unsigned NOps = MI->getNumOperands(); 630 assert(NOps==4); 631 O << '\t' << MAI->getCommentString() << "DEBUG_VALUE: "; 632 // cast away const; DIetc do not take const operands for some reason. 633 DIVariable V(const_cast<MDNode *>(MI->getOperand(NOps-1).getMetadata())); 634 O << V.getName(); 635 O << " <- "; 636 // Frame address. Currently handles register +- offset only. 637 assert(MI->getOperand(0).isReg() && MI->getOperand(1).isImm()); 638 O << '['; printOperand(MI, 0, O); O << '+'; printOperand(MI, 1, O); 639 O << ']'; 640 O << "+"; 641 printOperand(MI, NOps-2, O); 642 OutStreamer.EmitRawText(O.str()); 643 return; 644 } 645 // Check for slwi/srwi mnemonics. 646 if (MI->getOpcode() == PPC::RLWINM) { 647 unsigned char SH = MI->getOperand(2).getImm(); 648 unsigned char MB = MI->getOperand(3).getImm(); 649 unsigned char ME = MI->getOperand(4).getImm(); 650 bool useSubstituteMnemonic = false; 651 if (SH <= 31 && MB == 0 && ME == (31-SH)) { 652 O << "\tslwi "; useSubstituteMnemonic = true; 653 } 654 if (SH <= 31 && MB == (32-SH) && ME == 31) { 655 O << "\tsrwi "; useSubstituteMnemonic = true; 656 SH = 32-SH; 657 } 658 if (useSubstituteMnemonic) { 659 printOperand(MI, 0, O); 660 O << ", "; 661 printOperand(MI, 1, O); 662 O << ", " << (unsigned int)SH; 663 OutStreamer.EmitRawText(O.str()); 664 return; 665 } 666 } 667 668 if ((MI->getOpcode() == PPC::OR || MI->getOpcode() == PPC::OR8) && 669 MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { 670 O << "\tmr "; 671 printOperand(MI, 0, O); 672 O << ", "; 673 printOperand(MI, 1, O); 674 OutStreamer.EmitRawText(O.str()); 675 return; 676 } 677 678 if (MI->getOpcode() == PPC::RLDICR) { 679 unsigned char SH = MI->getOperand(2).getImm(); 680 unsigned char ME = MI->getOperand(3).getImm(); 681 // rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH 682 if (63-SH == ME) { 683 O << "\tsldi "; 684 printOperand(MI, 0, O); 685 O << ", "; 686 printOperand(MI, 1, O); 687 O << ", " << (unsigned int)SH; 688 OutStreamer.EmitRawText(O.str()); 689 return; 690 } 691 } 692 693 printInstruction(MI, O); 694 OutStreamer.EmitRawText(O.str()); 695} 696 697void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() { 698 if (!Subtarget.isPPC64()) // linux/ppc32 - Normal entry label. 699 return AsmPrinter::EmitFunctionEntryLabel(); 700 701 // Emit an official procedure descriptor. 702 // FIXME 64-bit SVR4: Use MCSection here! 703 OutStreamer.EmitRawText(StringRef("\t.section\t\".opd\",\"aw\"")); 704 OutStreamer.EmitRawText(StringRef("\t.align 3")); 705 OutStreamer.EmitLabel(CurrentFnSym); 706 OutStreamer.EmitRawText("\t.quad .L." + Twine(CurrentFnSym->getName()) + 707 ",.TOC.@tocbase"); 708 OutStreamer.EmitRawText(StringRef("\t.previous")); 709 OutStreamer.EmitRawText(".L." + Twine(CurrentFnSym->getName()) + ":"); 710} 711 712 713bool PPCLinuxAsmPrinter::doFinalization(Module &M) { 714 const TargetData *TD = TM.getTargetData(); 715 716 bool isPPC64 = TD->getPointerSizeInBits() == 64; 717 718 if (isPPC64 && !TOC.empty()) { 719 // FIXME 64-bit SVR4: Use MCSection here? 720 OutStreamer.EmitRawText(StringRef("\t.section\t\".toc\",\"aw\"")); 721 722 // FIXME: This is nondeterminstic! 723 for (DenseMap<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(), 724 E = TOC.end(); I != E; ++I) { 725 OutStreamer.EmitLabel(I->second); 726 OutStreamer.EmitRawText("\t.tc " + Twine(I->first->getName()) + 727 "[TC]," + I->first->getName()); 728 } 729 } 730 731 return AsmPrinter::doFinalization(M); 732} 733 734void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) { 735 static const char *const CPUDirectives[] = { 736 "", 737 "ppc", 738 "ppc601", 739 "ppc602", 740 "ppc603", 741 "ppc7400", 742 "ppc750", 743 "ppc970", 744 "ppc64" 745 }; 746 747 unsigned Directive = Subtarget.getDarwinDirective(); 748 if (Subtarget.isGigaProcessor() && Directive < PPC::DIR_970) 749 Directive = PPC::DIR_970; 750 if (Subtarget.hasAltivec() && Directive < PPC::DIR_7400) 751 Directive = PPC::DIR_7400; 752 if (Subtarget.isPPC64() && Directive < PPC::DIR_970) 753 Directive = PPC::DIR_64; 754 assert(Directive <= PPC::DIR_64 && "Directive out of range."); 755 OutStreamer.EmitRawText("\t.machine " + Twine(CPUDirectives[Directive])); 756 757 // Prime text sections so they are adjacent. This reduces the likelihood a 758 // large data or debug section causes a branch to exceed 16M limit. 759 const TargetLoweringObjectFileMachO &TLOFMacho = 760 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 761 OutStreamer.SwitchSection(TLOFMacho.getTextCoalSection()); 762 if (TM.getRelocationModel() == Reloc::PIC_) { 763 OutStreamer.SwitchSection( 764 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 765 MCSectionMachO::S_SYMBOL_STUBS | 766 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 767 32, SectionKind::getText())); 768 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) { 769 OutStreamer.SwitchSection( 770 OutContext.getMachOSection("__TEXT","__symbol_stub1", 771 MCSectionMachO::S_SYMBOL_STUBS | 772 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 773 16, SectionKind::getText())); 774 } 775 OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); 776} 777 778static MCSymbol *GetLazyPtr(MCSymbol *Sym, MCContext &Ctx) { 779 // Remove $stub suffix, add $lazy_ptr. 780 SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end()-5); 781 TmpStr += "$lazy_ptr"; 782 return Ctx.GetOrCreateSymbol(TmpStr.str()); 783} 784 785static MCSymbol *GetAnonSym(MCSymbol *Sym, MCContext &Ctx) { 786 // Add $tmp suffix to $stub, yielding $stub$tmp. 787 SmallString<128> TmpStr(Sym->getName().begin(), Sym->getName().end()); 788 TmpStr += "$tmp"; 789 return Ctx.GetOrCreateSymbol(TmpStr.str()); 790} 791 792void PPCDarwinAsmPrinter:: 793EmitFunctionStubs(const MachineModuleInfoMachO::SymbolListTy &Stubs) { 794 bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64; 795 796 const TargetLoweringObjectFileMachO &TLOFMacho = 797 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 798 799 // .lazy_symbol_pointer 800 const MCSection *LSPSection = TLOFMacho.getLazySymbolPointerSection(); 801 802 // Output stubs for dynamically-linked functions 803 if (TM.getRelocationModel() == Reloc::PIC_) { 804 const MCSection *StubSection = 805 OutContext.getMachOSection("__TEXT", "__picsymbolstub1", 806 MCSectionMachO::S_SYMBOL_STUBS | 807 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 808 32, SectionKind::getText()); 809 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 810 OutStreamer.SwitchSection(StubSection); 811 EmitAlignment(4); 812 813 MCSymbol *Stub = Stubs[i].first; 814 MCSymbol *RawSym = Stubs[i].second.getPointer(); 815 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 816 MCSymbol *AnonSymbol = GetAnonSym(Stub, OutContext); 817 818 OutStreamer.EmitLabel(Stub); 819 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 820 // FIXME: MCize this. 821 OutStreamer.EmitRawText(StringRef("\tmflr r0")); 822 OutStreamer.EmitRawText("\tbcl 20,31," + Twine(AnonSymbol->getName())); 823 OutStreamer.EmitLabel(AnonSymbol); 824 OutStreamer.EmitRawText(StringRef("\tmflr r11")); 825 OutStreamer.EmitRawText("\taddis r11,r11,ha16("+Twine(LazyPtr->getName())+ 826 "-" + AnonSymbol->getName() + ")"); 827 OutStreamer.EmitRawText(StringRef("\tmtlr r0")); 828 829 if (isPPC64) 830 OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) + 831 "-" + AnonSymbol->getName() + ")(r11)"); 832 else 833 OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) + 834 "-" + AnonSymbol->getName() + ")(r11)"); 835 OutStreamer.EmitRawText(StringRef("\tmtctr r12")); 836 OutStreamer.EmitRawText(StringRef("\tbctr")); 837 838 OutStreamer.SwitchSection(LSPSection); 839 OutStreamer.EmitLabel(LazyPtr); 840 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 841 842 if (isPPC64) 843 OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper")); 844 else 845 OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper")); 846 } 847 OutStreamer.AddBlankLine(); 848 return; 849 } 850 851 const MCSection *StubSection = 852 OutContext.getMachOSection("__TEXT","__symbol_stub1", 853 MCSectionMachO::S_SYMBOL_STUBS | 854 MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, 855 16, SectionKind::getText()); 856 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 857 MCSymbol *Stub = Stubs[i].first; 858 MCSymbol *RawSym = Stubs[i].second.getPointer(); 859 MCSymbol *LazyPtr = GetLazyPtr(Stub, OutContext); 860 861 OutStreamer.SwitchSection(StubSection); 862 EmitAlignment(4); 863 OutStreamer.EmitLabel(Stub); 864 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 865 OutStreamer.EmitRawText("\tlis r11,ha16(" + Twine(LazyPtr->getName()) +")"); 866 if (isPPC64) 867 OutStreamer.EmitRawText("\tldu r12,lo16(" + Twine(LazyPtr->getName()) + 868 ")(r11)"); 869 else 870 OutStreamer.EmitRawText("\tlwzu r12,lo16(" + Twine(LazyPtr->getName()) + 871 ")(r11)"); 872 OutStreamer.EmitRawText(StringRef("\tmtctr r12")); 873 OutStreamer.EmitRawText(StringRef("\tbctr")); 874 OutStreamer.SwitchSection(LSPSection); 875 OutStreamer.EmitLabel(LazyPtr); 876 OutStreamer.EmitSymbolAttribute(RawSym, MCSA_IndirectSymbol); 877 878 if (isPPC64) 879 OutStreamer.EmitRawText(StringRef("\t.quad dyld_stub_binding_helper")); 880 else 881 OutStreamer.EmitRawText(StringRef("\t.long dyld_stub_binding_helper")); 882 } 883 884 OutStreamer.AddBlankLine(); 885} 886 887 888bool PPCDarwinAsmPrinter::doFinalization(Module &M) { 889 bool isPPC64 = TM.getTargetData()->getPointerSizeInBits() == 64; 890 891 // Darwin/PPC always uses mach-o. 892 const TargetLoweringObjectFileMachO &TLOFMacho = 893 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering()); 894 MachineModuleInfoMachO &MMIMacho = 895 MMI->getObjFileInfo<MachineModuleInfoMachO>(); 896 897 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetFnStubList(); 898 if (!Stubs.empty()) 899 EmitFunctionStubs(Stubs); 900 901 if (MAI->doesSupportExceptionHandling() && MMI) { 902 // Add the (possibly multiple) personalities to the set of global values. 903 // Only referenced functions get into the Personalities list. 904 const std::vector<const Function*> &Personalities = MMI->getPersonalities(); 905 for (std::vector<const Function*>::const_iterator I = Personalities.begin(), 906 E = Personalities.end(); I != E; ++I) { 907 if (*I) { 908 MCSymbol *NLPSym = GetSymbolWithGlobalValueBase(*I, "$non_lazy_ptr"); 909 MachineModuleInfoImpl::StubValueTy &StubSym = 910 MMIMacho.getGVStubEntry(NLPSym); 911 StubSym = MachineModuleInfoImpl::StubValueTy(Mang->getSymbol(*I), true); 912 } 913 } 914 } 915 916 // Output stubs for dynamically-linked functions. 917 Stubs = MMIMacho.GetGVStubList(); 918 919 // Output macho stubs for external and common global variables. 920 if (!Stubs.empty()) { 921 // Switch with ".non_lazy_symbol_pointer" directive. 922 OutStreamer.SwitchSection(TLOFMacho.getNonLazySymbolPointerSection()); 923 EmitAlignment(isPPC64 ? 3 : 2); 924 925 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 926 // L_foo$stub: 927 OutStreamer.EmitLabel(Stubs[i].first); 928 // .indirect_symbol _foo 929 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; 930 OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); 931 932 if (MCSym.getInt()) 933 // External to current translation unit. 934 OutStreamer.EmitIntValue(0, isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/); 935 else 936 // Internal to current translation unit. 937 // 938 // When we place the LSDA into the TEXT section, the type info pointers 939 // need to be indirect and pc-rel. We accomplish this by using NLPs. 940 // However, sometimes the types are local to the file. So we need to 941 // fill in the value for the NLP in those cases. 942 OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), 943 OutContext), 944 isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/); 945 } 946 947 Stubs.clear(); 948 OutStreamer.AddBlankLine(); 949 } 950 951 Stubs = MMIMacho.GetHiddenGVStubList(); 952 if (!Stubs.empty()) { 953 OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); 954 EmitAlignment(isPPC64 ? 3 : 2); 955 956 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { 957 // L_foo$stub: 958 OutStreamer.EmitLabel(Stubs[i].first); 959 // .long _foo 960 OutStreamer.EmitValue(MCSymbolRefExpr:: 961 Create(Stubs[i].second.getPointer(), 962 OutContext), 963 isPPC64 ? 8 : 4/*size*/, 0/*addrspace*/); 964 } 965 966 Stubs.clear(); 967 OutStreamer.AddBlankLine(); 968 } 969 970 // Funny Darwin hack: This flag tells the linker that no global symbols 971 // contain code that falls through to other global symbols (e.g. the obvious 972 // implementation of multiple entry points). If this doesn't occur, the 973 // linker can safely perform dead code stripping. Since LLVM never generates 974 // code that does this, it is always safe to set. 975 OutStreamer.EmitAssemblerFlag(MCAF_SubsectionsViaSymbols); 976 977 return AsmPrinter::doFinalization(M); 978} 979 980/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code 981/// for a MachineFunction to the given output stream, in a format that the 982/// Darwin assembler can deal with. 983/// 984static AsmPrinter *createPPCAsmPrinterPass(TargetMachine &tm, 985 MCStreamer &Streamer) { 986 const PPCSubtarget *Subtarget = &tm.getSubtarget<PPCSubtarget>(); 987 988 if (Subtarget->isDarwin()) 989 return new PPCDarwinAsmPrinter(tm, Streamer); 990 return new PPCLinuxAsmPrinter(tm, Streamer); 991} 992 993static MCInstPrinter *createPPCMCInstPrinter(const Target &T, 994 unsigned SyntaxVariant, 995 const MCAsmInfo &MAI) { 996 return new PPCInstPrinter(MAI, SyntaxVariant); 997} 998 999 1000// Force static initialization. 1001extern "C" void LLVMInitializePowerPCAsmPrinter() { 1002 TargetRegistry::RegisterAsmPrinter(ThePPC32Target, createPPCAsmPrinterPass); 1003 TargetRegistry::RegisterAsmPrinter(ThePPC64Target, createPPCAsmPrinterPass); 1004 1005 TargetRegistry::RegisterMCInstPrinter(ThePPC32Target, createPPCMCInstPrinter); 1006 TargetRegistry::RegisterMCInstPrinter(ThePPC64Target, createPPCMCInstPrinter); 1007} 1008