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 #include "InstPrinter/PPCInstPrinter.h"
20 #include "MCTargetDesc/PPCMCExpr.h"
21 #include "MCTargetDesc/PPCMCTargetDesc.h"
22 #include "MCTargetDesc/PPCPredicates.h"
23 #include "PPC.h"
24 #include "PPCInstrInfo.h"
25 #include "PPCMachineFunctionInfo.h"
26 #include "PPCSubtarget.h"
27 #include "PPCTargetMachine.h"
28 #include "PPCTargetStreamer.h"
29 #include "llvm/ADT/MapVector.h"
30 #include "llvm/ADT/StringRef.h"
31 #include "llvm/ADT/Triple.h"
32 #include "llvm/ADT/Twine.h"
33 #include "llvm/BinaryFormat/ELF.h"
34 #include "llvm/BinaryFormat/MachO.h"
35 #include "llvm/CodeGen/AsmPrinter.h"
36 #include "llvm/CodeGen/MachineBasicBlock.h"
37 #include "llvm/CodeGen/MachineFunction.h"
38 #include "llvm/CodeGen/MachineInstr.h"
39 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
40 #include "llvm/CodeGen/MachineOperand.h"
41 #include "llvm/CodeGen/MachineRegisterInfo.h"
42 #include "llvm/CodeGen/StackMaps.h"
43 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
44 #include "llvm/IR/DataLayout.h"
45 #include "llvm/IR/GlobalValue.h"
46 #include "llvm/IR/Module.h"
47 #include "llvm/MC/MCAsmInfo.h"
48 #include "llvm/MC/MCContext.h"
49 #include "llvm/MC/MCExpr.h"
50 #include "llvm/MC/MCInst.h"
51 #include "llvm/MC/MCInstBuilder.h"
52 #include "llvm/MC/MCSectionELF.h"
53 #include "llvm/MC/MCSectionMachO.h"
54 #include "llvm/MC/MCStreamer.h"
55 #include "llvm/MC/MCSymbol.h"
56 #include "llvm/MC/MCSymbolELF.h"
57 #include "llvm/MC/SectionKind.h"
58 #include "llvm/Support/Casting.h"
59 #include "llvm/Support/CodeGen.h"
60 #include "llvm/Support/Debug.h"
61 #include "llvm/Support/ErrorHandling.h"
62 #include "llvm/Support/TargetRegistry.h"
63 #include "llvm/Support/raw_ostream.h"
64 #include "llvm/Target/TargetMachine.h"
65 #include <algorithm>
66 #include <cassert>
67 #include <cstdint>
68 #include <memory>
69 #include <new>
70
71 using namespace llvm;
72
73 #define DEBUG_TYPE "asmprinter"
74
75 namespace {
76
77 class PPCAsmPrinter : public AsmPrinter {
78 protected:
79 MapVector<MCSymbol *, MCSymbol *> TOC;
80 const PPCSubtarget *Subtarget;
81 StackMaps SM;
82
83 public:
PPCAsmPrinter(TargetMachine & TM,std::unique_ptr<MCStreamer> Streamer)84 explicit PPCAsmPrinter(TargetMachine &TM,
85 std::unique_ptr<MCStreamer> Streamer)
86 : AsmPrinter(TM, std::move(Streamer)), SM(*this) {}
87
getPassName() const88 StringRef getPassName() const override { return "PowerPC Assembly Printer"; }
89
90 MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym);
91
doInitialization(Module & M)92 bool doInitialization(Module &M) override {
93 if (!TOC.empty())
94 TOC.clear();
95 return AsmPrinter::doInitialization(M);
96 }
97
98 void EmitInstruction(const MachineInstr *MI) override;
99
100 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
101
102 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
103 unsigned AsmVariant, const char *ExtraCode,
104 raw_ostream &O) override;
105 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
106 unsigned AsmVariant, const char *ExtraCode,
107 raw_ostream &O) override;
108
109 void EmitEndOfAsmFile(Module &M) override;
110
111 void LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI);
112 void LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI);
113 void EmitTlsCall(const MachineInstr *MI, MCSymbolRefExpr::VariantKind VK);
runOnMachineFunction(MachineFunction & MF)114 bool runOnMachineFunction(MachineFunction &MF) override {
115 Subtarget = &MF.getSubtarget<PPCSubtarget>();
116 bool Changed = AsmPrinter::runOnMachineFunction(MF);
117 emitXRayTable();
118 return Changed;
119 }
120 };
121
122 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
123 class PPCLinuxAsmPrinter : public PPCAsmPrinter {
124 public:
PPCLinuxAsmPrinter(TargetMachine & TM,std::unique_ptr<MCStreamer> Streamer)125 explicit PPCLinuxAsmPrinter(TargetMachine &TM,
126 std::unique_ptr<MCStreamer> Streamer)
127 : PPCAsmPrinter(TM, std::move(Streamer)) {}
128
getPassName() const129 StringRef getPassName() const override {
130 return "Linux PPC Assembly Printer";
131 }
132
133 bool doFinalization(Module &M) override;
134 void EmitStartOfAsmFile(Module &M) override;
135
136 void EmitFunctionEntryLabel() override;
137
138 void EmitFunctionBodyStart() override;
139 void EmitFunctionBodyEnd() override;
140 void EmitInstruction(const MachineInstr *MI) override;
141 };
142
143 /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
144 /// OS X
145 class PPCDarwinAsmPrinter : public PPCAsmPrinter {
146 public:
PPCDarwinAsmPrinter(TargetMachine & TM,std::unique_ptr<MCStreamer> Streamer)147 explicit PPCDarwinAsmPrinter(TargetMachine &TM,
148 std::unique_ptr<MCStreamer> Streamer)
149 : PPCAsmPrinter(TM, std::move(Streamer)) {}
150
getPassName() const151 StringRef getPassName() const override {
152 return "Darwin PPC Assembly Printer";
153 }
154
155 bool doFinalization(Module &M) override;
156 void EmitStartOfAsmFile(Module &M) override;
157 };
158
159 } // end anonymous namespace
160
printOperand(const MachineInstr * MI,unsigned OpNo,raw_ostream & O)161 void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
162 raw_ostream &O) {
163 const DataLayout &DL = getDataLayout();
164 const MachineOperand &MO = MI->getOperand(OpNo);
165
166 switch (MO.getType()) {
167 case MachineOperand::MO_Register: {
168 unsigned Reg = PPCInstrInfo::getRegNumForOperand(MI->getDesc(),
169 MO.getReg(), OpNo);
170
171 const char *RegName = PPCInstPrinter::getRegisterName(Reg);
172
173 // Linux assembler (Others?) does not take register mnemonics.
174 // FIXME - What about special registers used in mfspr/mtspr?
175 if (!Subtarget->isDarwin())
176 RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
177 O << RegName;
178 return;
179 }
180 case MachineOperand::MO_Immediate:
181 O << MO.getImm();
182 return;
183
184 case MachineOperand::MO_MachineBasicBlock:
185 MO.getMBB()->getSymbol()->print(O, MAI);
186 return;
187 case MachineOperand::MO_ConstantPoolIndex:
188 O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
189 << MO.getIndex();
190 return;
191 case MachineOperand::MO_BlockAddress:
192 GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
193 return;
194 case MachineOperand::MO_GlobalAddress: {
195 // Computing the address of a global symbol, not calling it.
196 const GlobalValue *GV = MO.getGlobal();
197 MCSymbol *SymToPrint;
198
199 // External or weakly linked global variables need non-lazily-resolved stubs
200 if (Subtarget->hasLazyResolverStub(GV)) {
201 SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
202 MachineModuleInfoImpl::StubValueTy &StubSym =
203 MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(
204 SymToPrint);
205 if (!StubSym.getPointer())
206 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
207 !GV->hasInternalLinkage());
208 } else {
209 SymToPrint = getSymbol(GV);
210 }
211
212 SymToPrint->print(O, MAI);
213
214 printOffset(MO.getOffset(), O);
215 return;
216 }
217
218 default:
219 O << "<unknown operand type: " << (unsigned)MO.getType() << ">";
220 return;
221 }
222 }
223
224 /// PrintAsmOperand - Print out an operand for an inline asm expression.
225 ///
PrintAsmOperand(const MachineInstr * MI,unsigned OpNo,unsigned AsmVariant,const char * ExtraCode,raw_ostream & O)226 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
227 unsigned AsmVariant,
228 const char *ExtraCode, raw_ostream &O) {
229 // Does this asm operand have a single letter operand modifier?
230 if (ExtraCode && ExtraCode[0]) {
231 if (ExtraCode[1] != 0) return true; // Unknown modifier.
232
233 switch (ExtraCode[0]) {
234 default:
235 // See if this is a generic print operand
236 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
237 case 'c': // Don't print "$" before a global var name or constant.
238 break; // PPC never has a prefix.
239 case 'L': // Write second word of DImode reference.
240 // Verify that this operand has two consecutive registers.
241 if (!MI->getOperand(OpNo).isReg() ||
242 OpNo+1 == MI->getNumOperands() ||
243 !MI->getOperand(OpNo+1).isReg())
244 return true;
245 ++OpNo; // Return the high-part.
246 break;
247 case 'I':
248 // Write 'i' if an integer constant, otherwise nothing. Used to print
249 // addi vs add, etc.
250 if (MI->getOperand(OpNo).isImm())
251 O << "i";
252 return false;
253 case 'x':
254 if(!MI->getOperand(OpNo).isReg())
255 return true;
256 // This operand uses VSX numbering.
257 // If the operand is a VMX register, convert it to a VSX register.
258 unsigned Reg = MI->getOperand(OpNo).getReg();
259 if (PPCInstrInfo::isVRRegister(Reg))
260 Reg = PPC::VSX32 + (Reg - PPC::V0);
261 else if (PPCInstrInfo::isVFRegister(Reg))
262 Reg = PPC::VSX32 + (Reg - PPC::VF0);
263 const char *RegName;
264 RegName = PPCInstPrinter::getRegisterName(Reg);
265 RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
266 O << RegName;
267 return false;
268 }
269 }
270
271 printOperand(MI, OpNo, O);
272 return false;
273 }
274
275 // At the moment, all inline asm memory operands are a single register.
276 // In any case, the output of this routine should always be just one
277 // assembler operand.
278
PrintAsmMemoryOperand(const MachineInstr * MI,unsigned OpNo,unsigned AsmVariant,const char * ExtraCode,raw_ostream & O)279 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
280 unsigned AsmVariant,
281 const char *ExtraCode,
282 raw_ostream &O) {
283 if (ExtraCode && ExtraCode[0]) {
284 if (ExtraCode[1] != 0) return true; // Unknown modifier.
285
286 switch (ExtraCode[0]) {
287 default: return true; // Unknown modifier.
288 case 'y': // A memory reference for an X-form instruction
289 {
290 const char *RegName = "r0";
291 if (!Subtarget->isDarwin())
292 RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
293 O << RegName << ", ";
294 printOperand(MI, OpNo, O);
295 return false;
296 }
297 case 'U': // Print 'u' for update form.
298 case 'X': // Print 'x' for indexed form.
299 {
300 // FIXME: Currently for PowerPC memory operands are always loaded
301 // into a register, so we never get an update or indexed form.
302 // This is bad even for offset forms, since even if we know we
303 // have a value in -16(r1), we will generate a load into r<n>
304 // and then load from 0(r<n>). Until that issue is fixed,
305 // tolerate 'U' and 'X' but don't output anything.
306 assert(MI->getOperand(OpNo).isReg());
307 return false;
308 }
309 }
310 }
311
312 assert(MI->getOperand(OpNo).isReg());
313 O << "0(";
314 printOperand(MI, OpNo, O);
315 O << ")";
316 return false;
317 }
318
319 /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
320 /// exists for it. If not, create one. Then return a symbol that references
321 /// the TOC entry.
lookUpOrCreateTOCEntry(MCSymbol * Sym)322 MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) {
323 MCSymbol *&TOCEntry = TOC[Sym];
324 if (!TOCEntry)
325 TOCEntry = createTempSymbol("C");
326 return TOCEntry;
327 }
328
EmitEndOfAsmFile(Module & M)329 void PPCAsmPrinter::EmitEndOfAsmFile(Module &M) {
330 emitStackMaps(SM);
331 }
332
LowerSTACKMAP(StackMaps & SM,const MachineInstr & MI)333 void PPCAsmPrinter::LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI) {
334 unsigned NumNOPBytes = MI.getOperand(1).getImm();
335
336 SM.recordStackMap(MI);
337 assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
338
339 // Scan ahead to trim the shadow.
340 const MachineBasicBlock &MBB = *MI.getParent();
341 MachineBasicBlock::const_iterator MII(MI);
342 ++MII;
343 while (NumNOPBytes > 0) {
344 if (MII == MBB.end() || MII->isCall() ||
345 MII->getOpcode() == PPC::DBG_VALUE ||
346 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
347 MII->getOpcode() == TargetOpcode::STACKMAP)
348 break;
349 ++MII;
350 NumNOPBytes -= 4;
351 }
352
353 // Emit nops.
354 for (unsigned i = 0; i < NumNOPBytes; i += 4)
355 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
356 }
357
358 // Lower a patchpoint of the form:
359 // [<def>], <id>, <numBytes>, <target>, <numArgs>
LowerPATCHPOINT(StackMaps & SM,const MachineInstr & MI)360 void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) {
361 SM.recordPatchPoint(MI);
362 PatchPointOpers Opers(&MI);
363
364 unsigned EncodedBytes = 0;
365 const MachineOperand &CalleeMO = Opers.getCallTarget();
366
367 if (CalleeMO.isImm()) {
368 int64_t CallTarget = CalleeMO.getImm();
369 if (CallTarget) {
370 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
371 "High 16 bits of call target should be zero.");
372 unsigned ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
373 EncodedBytes = 0;
374 // Materialize the jump address:
375 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8)
376 .addReg(ScratchReg)
377 .addImm((CallTarget >> 32) & 0xFFFF));
378 ++EncodedBytes;
379 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC)
380 .addReg(ScratchReg)
381 .addReg(ScratchReg)
382 .addImm(32).addImm(16));
383 ++EncodedBytes;
384 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8)
385 .addReg(ScratchReg)
386 .addReg(ScratchReg)
387 .addImm((CallTarget >> 16) & 0xFFFF));
388 ++EncodedBytes;
389 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8)
390 .addReg(ScratchReg)
391 .addReg(ScratchReg)
392 .addImm(CallTarget & 0xFFFF));
393
394 // Save the current TOC pointer before the remote call.
395 int TOCSaveOffset = Subtarget->getFrameLowering()->getTOCSaveOffset();
396 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD)
397 .addReg(PPC::X2)
398 .addImm(TOCSaveOffset)
399 .addReg(PPC::X1));
400 ++EncodedBytes;
401
402 // If we're on ELFv1, then we need to load the actual function pointer
403 // from the function descriptor.
404 if (!Subtarget->isELFv2ABI()) {
405 // Load the new TOC pointer and the function address, but not r11
406 // (needing this is rare, and loading it here would prevent passing it
407 // via a 'nest' parameter.
408 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
409 .addReg(PPC::X2)
410 .addImm(8)
411 .addReg(ScratchReg));
412 ++EncodedBytes;
413 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
414 .addReg(ScratchReg)
415 .addImm(0)
416 .addReg(ScratchReg));
417 ++EncodedBytes;
418 }
419
420 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8)
421 .addReg(ScratchReg));
422 ++EncodedBytes;
423 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8));
424 ++EncodedBytes;
425
426 // Restore the TOC pointer after the call.
427 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
428 .addReg(PPC::X2)
429 .addImm(TOCSaveOffset)
430 .addReg(PPC::X1));
431 ++EncodedBytes;
432 }
433 } else if (CalleeMO.isGlobal()) {
434 const GlobalValue *GValue = CalleeMO.getGlobal();
435 MCSymbol *MOSymbol = getSymbol(GValue);
436 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, OutContext);
437
438 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP)
439 .addExpr(SymVar));
440 EncodedBytes += 2;
441 }
442
443 // Each instruction is 4 bytes.
444 EncodedBytes *= 4;
445
446 // Emit padding.
447 unsigned NumBytes = Opers.getNumPatchBytes();
448 assert(NumBytes >= EncodedBytes &&
449 "Patchpoint can't request size less than the length of a call.");
450 assert((NumBytes - EncodedBytes) % 4 == 0 &&
451 "Invalid number of NOP bytes requested!");
452 for (unsigned i = EncodedBytes; i < NumBytes; i += 4)
453 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
454 }
455
456 /// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a
457 /// call to __tls_get_addr to the current output stream.
EmitTlsCall(const MachineInstr * MI,MCSymbolRefExpr::VariantKind VK)458 void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
459 MCSymbolRefExpr::VariantKind VK) {
460 StringRef Name = "__tls_get_addr";
461 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(Name);
462 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
463
464 assert(MI->getOperand(0).isReg() &&
465 ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) ||
466 (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) &&
467 "GETtls[ld]ADDR[32] must define GPR3");
468 assert(MI->getOperand(1).isReg() &&
469 ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) ||
470 (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) &&
471 "GETtls[ld]ADDR[32] must read GPR3");
472
473 if (!Subtarget->isPPC64() && !Subtarget->isDarwin() &&
474 isPositionIndependent())
475 Kind = MCSymbolRefExpr::VK_PLT;
476 const MCSymbolRefExpr *TlsRef =
477 MCSymbolRefExpr::create(TlsGetAddr, Kind, OutContext);
478 const MachineOperand &MO = MI->getOperand(2);
479 const GlobalValue *GValue = MO.getGlobal();
480 MCSymbol *MOSymbol = getSymbol(GValue);
481 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
482 EmitToStreamer(*OutStreamer,
483 MCInstBuilder(Subtarget->isPPC64() ?
484 PPC::BL8_NOP_TLS : PPC::BL_TLS)
485 .addExpr(TlsRef)
486 .addExpr(SymVar));
487 }
488
489 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
490 /// the current output stream.
491 ///
EmitInstruction(const MachineInstr * MI)492 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
493 MCInst TmpInst;
494 bool isPPC64 = Subtarget->isPPC64();
495 bool isDarwin = TM.getTargetTriple().isOSDarwin();
496 const Module *M = MF->getFunction().getParent();
497 PICLevel::Level PL = M->getPICLevel();
498
499 #ifndef NDEBUG
500 // Validate that SPE and FPU are mutually exclusive in codegen
501 if (!MI->isInlineAsm()) {
502 for (const MachineOperand &MO: MI->operands()) {
503 if (MO.isReg()) {
504 unsigned Reg = MO.getReg();
505 if (Subtarget->hasSPE()) {
506 if (PPC::F4RCRegClass.contains(Reg) ||
507 PPC::F8RCRegClass.contains(Reg) ||
508 PPC::QBRCRegClass.contains(Reg) ||
509 PPC::QFRCRegClass.contains(Reg) ||
510 PPC::QSRCRegClass.contains(Reg) ||
511 PPC::VFRCRegClass.contains(Reg) ||
512 PPC::VRRCRegClass.contains(Reg) ||
513 PPC::VSFRCRegClass.contains(Reg) ||
514 PPC::VSSRCRegClass.contains(Reg)
515 )
516 llvm_unreachable("SPE targets cannot have FPRegs!");
517 } else {
518 if (PPC::SPERCRegClass.contains(Reg))
519 llvm_unreachable("SPE register found in FPU-targeted code!");
520 }
521 }
522 }
523 }
524 #endif
525 // Lower multi-instruction pseudo operations.
526 switch (MI->getOpcode()) {
527 default: break;
528 case TargetOpcode::DBG_VALUE:
529 llvm_unreachable("Should be handled target independently");
530 case TargetOpcode::STACKMAP:
531 return LowerSTACKMAP(SM, *MI);
532 case TargetOpcode::PATCHPOINT:
533 return LowerPATCHPOINT(SM, *MI);
534
535 case PPC::MoveGOTtoLR: {
536 // Transform %lr = MoveGOTtoLR
537 // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
538 // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding
539 // _GLOBAL_OFFSET_TABLE_) has exactly one instruction:
540 // blrl
541 // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local
542 MCSymbol *GOTSymbol =
543 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
544 const MCExpr *OffsExpr =
545 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol,
546 MCSymbolRefExpr::VK_PPC_LOCAL,
547 OutContext),
548 MCConstantExpr::create(4, OutContext),
549 OutContext);
550
551 // Emit the 'bl'.
552 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));
553 return;
554 }
555 case PPC::MovePCtoLR:
556 case PPC::MovePCtoLR8: {
557 // Transform %lr = MovePCtoLR
558 // Into this, where the label is the PIC base:
559 // bl L1$pb
560 // L1$pb:
561 MCSymbol *PICBase = MF->getPICBaseSymbol();
562
563 // Emit the 'bl'.
564 EmitToStreamer(*OutStreamer,
565 MCInstBuilder(PPC::BL)
566 // FIXME: We would like an efficient form for this, so we
567 // don't have to do a lot of extra uniquing.
568 .addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));
569
570 // Emit the label.
571 OutStreamer->EmitLabel(PICBase);
572 return;
573 }
574 case PPC::UpdateGBR: {
575 // Transform %rd = UpdateGBR(%rt, %ri)
576 // Into: lwz %rt, .L0$poff - .L0$pb(%ri)
577 // add %rd, %rt, %ri
578 // or into (if secure plt mode is on):
579 // addis r30, r30, .LTOC - .L0$pb@ha
580 // addi r30, r30, .LTOC - .L0$pb@l
581 // Get the offset from the GOT Base Register to the GOT
582 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
583 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
584 unsigned PICR = TmpInst.getOperand(0).getReg();
585 MCSymbol *LTOCSymbol = OutContext.getOrCreateSymbol(StringRef(".LTOC"));
586 const MCExpr *PB =
587 MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
588 OutContext);
589
590 const MCExpr *LTOCDeltaExpr =
591 MCBinaryExpr::createSub(MCSymbolRefExpr::create(LTOCSymbol, OutContext),
592 PB, OutContext);
593
594 const MCExpr *LTOCDeltaHi =
595 PPCMCExpr::createHa(LTOCDeltaExpr, false, OutContext);
596 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
597 .addReg(PICR)
598 .addReg(PICR)
599 .addExpr(LTOCDeltaHi));
600
601 const MCExpr *LTOCDeltaLo =
602 PPCMCExpr::createLo(LTOCDeltaExpr, false, OutContext);
603 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
604 .addReg(PICR)
605 .addReg(PICR)
606 .addExpr(LTOCDeltaLo));
607 return;
608 } else {
609 MCSymbol *PICOffset =
610 MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
611 TmpInst.setOpcode(PPC::LWZ);
612 const MCExpr *Exp =
613 MCSymbolRefExpr::create(PICOffset, MCSymbolRefExpr::VK_None, OutContext);
614 const MCExpr *PB =
615 MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
616 MCSymbolRefExpr::VK_None,
617 OutContext);
618 const MCOperand TR = TmpInst.getOperand(1);
619 const MCOperand PICR = TmpInst.getOperand(0);
620
621 // Step 1: lwz %rt, .L$poff - .L$pb(%ri)
622 TmpInst.getOperand(1) =
623 MCOperand::createExpr(MCBinaryExpr::createSub(Exp, PB, OutContext));
624 TmpInst.getOperand(0) = TR;
625 TmpInst.getOperand(2) = PICR;
626 EmitToStreamer(*OutStreamer, TmpInst);
627
628 TmpInst.setOpcode(PPC::ADD4);
629 TmpInst.getOperand(0) = PICR;
630 TmpInst.getOperand(1) = TR;
631 TmpInst.getOperand(2) = PICR;
632 EmitToStreamer(*OutStreamer, TmpInst);
633 return;
634 }
635 }
636 case PPC::LWZtoc: {
637 // Transform %r3 = LWZtoc @min1, %r2
638 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
639
640 // Change the opcode to LWZ, and the global address operand to be a
641 // reference to the GOT entry we will synthesize later.
642 TmpInst.setOpcode(PPC::LWZ);
643 const MachineOperand &MO = MI->getOperand(1);
644
645 // Map symbol -> label of TOC entry
646 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress());
647 MCSymbol *MOSymbol = nullptr;
648 if (MO.isGlobal())
649 MOSymbol = getSymbol(MO.getGlobal());
650 else if (MO.isCPI())
651 MOSymbol = GetCPISymbol(MO.getIndex());
652 else if (MO.isJTI())
653 MOSymbol = GetJTISymbol(MO.getIndex());
654 else if (MO.isBlockAddress())
655 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
656
657 if (PL == PICLevel::SmallPIC) {
658 const MCExpr *Exp =
659 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_GOT,
660 OutContext);
661 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
662 } else {
663 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
664
665 const MCExpr *Exp =
666 MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_None,
667 OutContext);
668 const MCExpr *PB =
669 MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")),
670 OutContext);
671 Exp = MCBinaryExpr::createSub(Exp, PB, OutContext);
672 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
673 }
674 EmitToStreamer(*OutStreamer, TmpInst);
675 return;
676 }
677 case PPC::LDtocJTI:
678 case PPC::LDtocCPT:
679 case PPC::LDtocBA:
680 case PPC::LDtoc: {
681 // Transform %x3 = LDtoc @min1, %x2
682 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
683
684 // Change the opcode to LD, and the global address operand to be a
685 // reference to the TOC entry we will synthesize later.
686 TmpInst.setOpcode(PPC::LD);
687 const MachineOperand &MO = MI->getOperand(1);
688
689 // Map symbol -> label of TOC entry
690 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress());
691 MCSymbol *MOSymbol = nullptr;
692 if (MO.isGlobal())
693 MOSymbol = getSymbol(MO.getGlobal());
694 else if (MO.isCPI())
695 MOSymbol = GetCPISymbol(MO.getIndex());
696 else if (MO.isJTI())
697 MOSymbol = GetJTISymbol(MO.getIndex());
698 else if (MO.isBlockAddress())
699 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
700
701 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
702
703 const MCExpr *Exp =
704 MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC,
705 OutContext);
706 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
707 EmitToStreamer(*OutStreamer, TmpInst);
708 return;
709 }
710
711 case PPC::ADDIStocHA: {
712 // Transform %xd = ADDIStocHA %x2, @sym
713 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
714
715 // Change the opcode to ADDIS8. If the global address is external, has
716 // common linkage, is a non-local function address, or is a jump table
717 // address, then generate a TOC entry and reference that. Otherwise
718 // reference the symbol directly.
719 TmpInst.setOpcode(PPC::ADDIS8);
720 const MachineOperand &MO = MI->getOperand(2);
721 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
722 MO.isBlockAddress()) &&
723 "Invalid operand for ADDIStocHA!");
724 MCSymbol *MOSymbol = nullptr;
725 bool GlobalToc = false;
726
727 if (MO.isGlobal()) {
728 const GlobalValue *GV = MO.getGlobal();
729 MOSymbol = getSymbol(GV);
730 unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
731 GlobalToc = (GVFlags & PPCII::MO_NLP_FLAG);
732 } else if (MO.isCPI()) {
733 MOSymbol = GetCPISymbol(MO.getIndex());
734 } else if (MO.isJTI()) {
735 MOSymbol = GetJTISymbol(MO.getIndex());
736 } else if (MO.isBlockAddress()) {
737 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
738 }
739
740 if (GlobalToc || MO.isJTI() || MO.isBlockAddress() ||
741 TM.getCodeModel() == CodeModel::Large)
742 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
743
744 const MCExpr *Exp =
745 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA,
746 OutContext);
747
748 if (!MO.isJTI() && MO.getOffset())
749 Exp = MCBinaryExpr::createAdd(Exp,
750 MCConstantExpr::create(MO.getOffset(),
751 OutContext),
752 OutContext);
753
754 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
755 EmitToStreamer(*OutStreamer, TmpInst);
756 return;
757 }
758 case PPC::LDtocL: {
759 // Transform %xd = LDtocL @sym, %xs
760 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
761
762 // Change the opcode to LD. If the global address is external, has
763 // common linkage, or is a jump table address, then reference the
764 // associated TOC entry. Otherwise reference the symbol directly.
765 TmpInst.setOpcode(PPC::LD);
766 const MachineOperand &MO = MI->getOperand(1);
767 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
768 MO.isBlockAddress()) &&
769 "Invalid operand for LDtocL!");
770 MCSymbol *MOSymbol = nullptr;
771
772 if (MO.isJTI())
773 MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex()));
774 else if (MO.isBlockAddress()) {
775 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
776 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
777 }
778 else if (MO.isCPI()) {
779 MOSymbol = GetCPISymbol(MO.getIndex());
780 if (TM.getCodeModel() == CodeModel::Large)
781 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
782 }
783 else if (MO.isGlobal()) {
784 const GlobalValue *GV = MO.getGlobal();
785 MOSymbol = getSymbol(GV);
786 LLVM_DEBUG(
787 unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
788 assert((GVFlags & PPCII::MO_NLP_FLAG) &&
789 "LDtocL used on symbol that could be accessed directly is "
790 "invalid. Must match ADDIStocHA."));
791 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
792 }
793
794 const MCExpr *Exp =
795 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
796 OutContext);
797 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
798 EmitToStreamer(*OutStreamer, TmpInst);
799 return;
800 }
801 case PPC::ADDItocL: {
802 // Transform %xd = ADDItocL %xs, @sym
803 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
804
805 // Change the opcode to ADDI8. If the global address is external, then
806 // generate a TOC entry and reference that. Otherwise reference the
807 // symbol directly.
808 TmpInst.setOpcode(PPC::ADDI8);
809 const MachineOperand &MO = MI->getOperand(2);
810 assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL");
811 MCSymbol *MOSymbol = nullptr;
812
813 if (MO.isGlobal()) {
814 const GlobalValue *GV = MO.getGlobal();
815 LLVM_DEBUG(unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
816 assert(!(GVFlags & PPCII::MO_NLP_FLAG) &&
817 "Interposable definitions must use indirect access."));
818 MOSymbol = getSymbol(GV);
819 } else if (MO.isCPI()) {
820 MOSymbol = GetCPISymbol(MO.getIndex());
821 }
822
823 const MCExpr *Exp =
824 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
825 OutContext);
826 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
827 EmitToStreamer(*OutStreamer, TmpInst);
828 return;
829 }
830 case PPC::ADDISgotTprelHA: {
831 // Transform: %xd = ADDISgotTprelHA %x2, @sym
832 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
833 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
834 const MachineOperand &MO = MI->getOperand(2);
835 const GlobalValue *GValue = MO.getGlobal();
836 MCSymbol *MOSymbol = getSymbol(GValue);
837 const MCExpr *SymGotTprel =
838 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA,
839 OutContext);
840 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
841 .addReg(MI->getOperand(0).getReg())
842 .addReg(MI->getOperand(1).getReg())
843 .addExpr(SymGotTprel));
844 return;
845 }
846 case PPC::LDgotTprelL:
847 case PPC::LDgotTprelL32: {
848 // Transform %xd = LDgotTprelL @sym, %xs
849 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
850
851 // Change the opcode to LD.
852 TmpInst.setOpcode(isPPC64 ? PPC::LD : PPC::LWZ);
853 const MachineOperand &MO = MI->getOperand(1);
854 const GlobalValue *GValue = MO.getGlobal();
855 MCSymbol *MOSymbol = getSymbol(GValue);
856 const MCExpr *Exp =
857 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO,
858 OutContext);
859 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
860 EmitToStreamer(*OutStreamer, TmpInst);
861 return;
862 }
863
864 case PPC::PPC32PICGOT: {
865 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
866 MCSymbol *GOTRef = OutContext.createTempSymbol();
867 MCSymbol *NextInstr = OutContext.createTempSymbol();
868
869 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL)
870 // FIXME: We would like an efficient form for this, so we don't have to do
871 // a lot of extra uniquing.
872 .addExpr(MCSymbolRefExpr::create(NextInstr, OutContext)));
873 const MCExpr *OffsExpr =
874 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol, OutContext),
875 MCSymbolRefExpr::create(GOTRef, OutContext),
876 OutContext);
877 OutStreamer->EmitLabel(GOTRef);
878 OutStreamer->EmitValue(OffsExpr, 4);
879 OutStreamer->EmitLabel(NextInstr);
880 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR)
881 .addReg(MI->getOperand(0).getReg()));
882 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
883 .addReg(MI->getOperand(1).getReg())
884 .addImm(0)
885 .addReg(MI->getOperand(0).getReg()));
886 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4)
887 .addReg(MI->getOperand(0).getReg())
888 .addReg(MI->getOperand(1).getReg())
889 .addReg(MI->getOperand(0).getReg()));
890 return;
891 }
892 case PPC::PPC32GOT: {
893 MCSymbol *GOTSymbol =
894 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
895 const MCExpr *SymGotTlsL = MCSymbolRefExpr::create(
896 GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, OutContext);
897 const MCExpr *SymGotTlsHA = MCSymbolRefExpr::create(
898 GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, OutContext);
899 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI)
900 .addReg(MI->getOperand(0).getReg())
901 .addExpr(SymGotTlsL));
902 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
903 .addReg(MI->getOperand(0).getReg())
904 .addReg(MI->getOperand(0).getReg())
905 .addExpr(SymGotTlsHA));
906 return;
907 }
908 case PPC::ADDIStlsgdHA: {
909 // Transform: %xd = ADDIStlsgdHA %x2, @sym
910 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
911 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
912 const MachineOperand &MO = MI->getOperand(2);
913 const GlobalValue *GValue = MO.getGlobal();
914 MCSymbol *MOSymbol = getSymbol(GValue);
915 const MCExpr *SymGotTlsGD =
916 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA,
917 OutContext);
918 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
919 .addReg(MI->getOperand(0).getReg())
920 .addReg(MI->getOperand(1).getReg())
921 .addExpr(SymGotTlsGD));
922 return;
923 }
924 case PPC::ADDItlsgdL:
925 // Transform: %xd = ADDItlsgdL %xs, @sym
926 // Into: %xd = ADDI8 %xs, sym@got@tlsgd@l
927 case PPC::ADDItlsgdL32: {
928 // Transform: %rd = ADDItlsgdL32 %rs, @sym
929 // Into: %rd = ADDI %rs, sym@got@tlsgd
930 const MachineOperand &MO = MI->getOperand(2);
931 const GlobalValue *GValue = MO.getGlobal();
932 MCSymbol *MOSymbol = getSymbol(GValue);
933 const MCExpr *SymGotTlsGD = MCSymbolRefExpr::create(
934 MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO
935 : MCSymbolRefExpr::VK_PPC_GOT_TLSGD,
936 OutContext);
937 EmitToStreamer(*OutStreamer,
938 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI)
939 .addReg(MI->getOperand(0).getReg())
940 .addReg(MI->getOperand(1).getReg())
941 .addExpr(SymGotTlsGD));
942 return;
943 }
944 case PPC::GETtlsADDR:
945 // Transform: %x3 = GETtlsADDR %x3, @sym
946 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd)
947 case PPC::GETtlsADDR32: {
948 // Transform: %r3 = GETtlsADDR32 %r3, @sym
949 // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT
950 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSGD);
951 return;
952 }
953 case PPC::ADDIStlsldHA: {
954 // Transform: %xd = ADDIStlsldHA %x2, @sym
955 // Into: %xd = ADDIS8 %x2, sym@got@tlsld@ha
956 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
957 const MachineOperand &MO = MI->getOperand(2);
958 const GlobalValue *GValue = MO.getGlobal();
959 MCSymbol *MOSymbol = getSymbol(GValue);
960 const MCExpr *SymGotTlsLD =
961 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA,
962 OutContext);
963 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
964 .addReg(MI->getOperand(0).getReg())
965 .addReg(MI->getOperand(1).getReg())
966 .addExpr(SymGotTlsLD));
967 return;
968 }
969 case PPC::ADDItlsldL:
970 // Transform: %xd = ADDItlsldL %xs, @sym
971 // Into: %xd = ADDI8 %xs, sym@got@tlsld@l
972 case PPC::ADDItlsldL32: {
973 // Transform: %rd = ADDItlsldL32 %rs, @sym
974 // Into: %rd = ADDI %rs, sym@got@tlsld
975 const MachineOperand &MO = MI->getOperand(2);
976 const GlobalValue *GValue = MO.getGlobal();
977 MCSymbol *MOSymbol = getSymbol(GValue);
978 const MCExpr *SymGotTlsLD = MCSymbolRefExpr::create(
979 MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO
980 : MCSymbolRefExpr::VK_PPC_GOT_TLSLD,
981 OutContext);
982 EmitToStreamer(*OutStreamer,
983 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI)
984 .addReg(MI->getOperand(0).getReg())
985 .addReg(MI->getOperand(1).getReg())
986 .addExpr(SymGotTlsLD));
987 return;
988 }
989 case PPC::GETtlsldADDR:
990 // Transform: %x3 = GETtlsldADDR %x3, @sym
991 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld)
992 case PPC::GETtlsldADDR32: {
993 // Transform: %r3 = GETtlsldADDR32 %r3, @sym
994 // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT
995 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSLD);
996 return;
997 }
998 case PPC::ADDISdtprelHA:
999 // Transform: %xd = ADDISdtprelHA %xs, @sym
1000 // Into: %xd = ADDIS8 %xs, sym@dtprel@ha
1001 case PPC::ADDISdtprelHA32: {
1002 // Transform: %rd = ADDISdtprelHA32 %rs, @sym
1003 // Into: %rd = ADDIS %rs, sym@dtprel@ha
1004 const MachineOperand &MO = MI->getOperand(2);
1005 const GlobalValue *GValue = MO.getGlobal();
1006 MCSymbol *MOSymbol = getSymbol(GValue);
1007 const MCExpr *SymDtprel =
1008 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA,
1009 OutContext);
1010 EmitToStreamer(
1011 *OutStreamer,
1012 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDIS8 : PPC::ADDIS)
1013 .addReg(MI->getOperand(0).getReg())
1014 .addReg(MI->getOperand(1).getReg())
1015 .addExpr(SymDtprel));
1016 return;
1017 }
1018 case PPC::ADDIdtprelL:
1019 // Transform: %xd = ADDIdtprelL %xs, @sym
1020 // Into: %xd = ADDI8 %xs, sym@dtprel@l
1021 case PPC::ADDIdtprelL32: {
1022 // Transform: %rd = ADDIdtprelL32 %rs, @sym
1023 // Into: %rd = ADDI %rs, sym@dtprel@l
1024 const MachineOperand &MO = MI->getOperand(2);
1025 const GlobalValue *GValue = MO.getGlobal();
1026 MCSymbol *MOSymbol = getSymbol(GValue);
1027 const MCExpr *SymDtprel =
1028 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO,
1029 OutContext);
1030 EmitToStreamer(*OutStreamer,
1031 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI)
1032 .addReg(MI->getOperand(0).getReg())
1033 .addReg(MI->getOperand(1).getReg())
1034 .addExpr(SymDtprel));
1035 return;
1036 }
1037 case PPC::MFOCRF:
1038 case PPC::MFOCRF8:
1039 if (!Subtarget->hasMFOCRF()) {
1040 // Transform: %r3 = MFOCRF %cr7
1041 // Into: %r3 = MFCR ;; cr7
1042 unsigned NewOpcode =
1043 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
1044 OutStreamer->AddComment(PPCInstPrinter::
1045 getRegisterName(MI->getOperand(1).getReg()));
1046 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1047 .addReg(MI->getOperand(0).getReg()));
1048 return;
1049 }
1050 break;
1051 case PPC::MTOCRF:
1052 case PPC::MTOCRF8:
1053 if (!Subtarget->hasMFOCRF()) {
1054 // Transform: %cr7 = MTOCRF %r3
1055 // Into: MTCRF mask, %r3 ;; cr7
1056 unsigned NewOpcode =
1057 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1058 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
1059 ->getEncodingValue(MI->getOperand(0).getReg());
1060 OutStreamer->AddComment(PPCInstPrinter::
1061 getRegisterName(MI->getOperand(0).getReg()));
1062 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1063 .addImm(Mask)
1064 .addReg(MI->getOperand(1).getReg()));
1065 return;
1066 }
1067 break;
1068 case PPC::LD:
1069 case PPC::STD:
1070 case PPC::LWA_32:
1071 case PPC::LWA: {
1072 // Verify alignment is legal, so we don't create relocations
1073 // that can't be supported.
1074 // FIXME: This test is currently disabled for Darwin. The test
1075 // suite shows a handful of test cases that fail this check for
1076 // Darwin. Those need to be investigated before this sanity test
1077 // can be enabled for those subtargets.
1078 if (!Subtarget->isDarwin()) {
1079 unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
1080 const MachineOperand &MO = MI->getOperand(OpNum);
1081 if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4)
1082 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
1083 }
1084 // Now process the instruction normally.
1085 break;
1086 }
1087 }
1088
1089 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
1090 EmitToStreamer(*OutStreamer, TmpInst);
1091 }
1092
EmitInstruction(const MachineInstr * MI)1093 void PPCLinuxAsmPrinter::EmitInstruction(const MachineInstr *MI) {
1094 if (!Subtarget->isPPC64())
1095 return PPCAsmPrinter::EmitInstruction(MI);
1096
1097 switch (MI->getOpcode()) {
1098 default:
1099 return PPCAsmPrinter::EmitInstruction(MI);
1100 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1101 // .begin:
1102 // b .end # lis 0, FuncId[16..32]
1103 // nop # li 0, FuncId[0..15]
1104 // std 0, -8(1)
1105 // mflr 0
1106 // bl __xray_FunctionEntry
1107 // mtlr 0
1108 // .end:
1109 //
1110 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1111 // of instructions change.
1112 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1113 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1114 OutStreamer->EmitLabel(BeginOfSled);
1115 EmitToStreamer(*OutStreamer,
1116 MCInstBuilder(PPC::B).addExpr(
1117 MCSymbolRefExpr::create(EndOfSled, OutContext)));
1118 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1119 EmitToStreamer(
1120 *OutStreamer,
1121 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1122 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1123 EmitToStreamer(*OutStreamer,
1124 MCInstBuilder(PPC::BL8_NOP)
1125 .addExpr(MCSymbolRefExpr::create(
1126 OutContext.getOrCreateSymbol("__xray_FunctionEntry"),
1127 OutContext)));
1128 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1129 OutStreamer->EmitLabel(EndOfSled);
1130 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER);
1131 break;
1132 }
1133 case TargetOpcode::PATCHABLE_RET: {
1134 unsigned RetOpcode = MI->getOperand(0).getImm();
1135 MCInst RetInst;
1136 RetInst.setOpcode(RetOpcode);
1137 for (const auto &MO :
1138 make_range(std::next(MI->operands_begin()), MI->operands_end())) {
1139 MCOperand MCOp;
1140 if (LowerPPCMachineOperandToMCOperand(MO, MCOp, *this, false))
1141 RetInst.addOperand(MCOp);
1142 }
1143
1144 bool IsConditional;
1145 if (RetOpcode == PPC::BCCLR) {
1146 IsConditional = true;
1147 } else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1148 RetOpcode == PPC::TCRETURNai8) {
1149 break;
1150 } else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1151 IsConditional = false;
1152 } else {
1153 EmitToStreamer(*OutStreamer, RetInst);
1154 break;
1155 }
1156
1157 MCSymbol *FallthroughLabel;
1158 if (IsConditional) {
1159 // Before:
1160 // bgtlr cr0
1161 //
1162 // After:
1163 // ble cr0, .end
1164 // .p2align 3
1165 // .begin:
1166 // blr # lis 0, FuncId[16..32]
1167 // nop # li 0, FuncId[0..15]
1168 // std 0, -8(1)
1169 // mflr 0
1170 // bl __xray_FunctionExit
1171 // mtlr 0
1172 // blr
1173 // .end:
1174 //
1175 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1176 // of instructions change.
1177 FallthroughLabel = OutContext.createTempSymbol();
1178 EmitToStreamer(
1179 *OutStreamer,
1180 MCInstBuilder(PPC::BCC)
1181 .addImm(PPC::InvertPredicate(
1182 static_cast<PPC::Predicate>(MI->getOperand(1).getImm())))
1183 .addReg(MI->getOperand(2).getReg())
1184 .addExpr(MCSymbolRefExpr::create(FallthroughLabel, OutContext)));
1185 RetInst = MCInst();
1186 RetInst.setOpcode(PPC::BLR8);
1187 }
1188 // .p2align 3
1189 // .begin:
1190 // b(lr)? # lis 0, FuncId[16..32]
1191 // nop # li 0, FuncId[0..15]
1192 // std 0, -8(1)
1193 // mflr 0
1194 // bl __xray_FunctionExit
1195 // mtlr 0
1196 // b(lr)?
1197 //
1198 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1199 // of instructions change.
1200 OutStreamer->EmitCodeAlignment(8);
1201 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1202 OutStreamer->EmitLabel(BeginOfSled);
1203 EmitToStreamer(*OutStreamer, RetInst);
1204 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1205 EmitToStreamer(
1206 *OutStreamer,
1207 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1208 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1209 EmitToStreamer(*OutStreamer,
1210 MCInstBuilder(PPC::BL8_NOP)
1211 .addExpr(MCSymbolRefExpr::create(
1212 OutContext.getOrCreateSymbol("__xray_FunctionExit"),
1213 OutContext)));
1214 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1215 EmitToStreamer(*OutStreamer, RetInst);
1216 if (IsConditional)
1217 OutStreamer->EmitLabel(FallthroughLabel);
1218 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT);
1219 break;
1220 }
1221 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1222 llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted");
1223 case TargetOpcode::PATCHABLE_TAIL_CALL:
1224 // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a
1225 // normal function exit from a tail exit.
1226 llvm_unreachable("Tail call is handled in the normal case. See comments "
1227 "around this assert.");
1228 }
1229 }
1230
EmitStartOfAsmFile(Module & M)1231 void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) {
1232 if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) {
1233 PPCTargetStreamer *TS =
1234 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1235
1236 if (TS)
1237 TS->emitAbiVersion(2);
1238 }
1239
1240 if (static_cast<const PPCTargetMachine &>(TM).isPPC64() ||
1241 !isPositionIndependent())
1242 return AsmPrinter::EmitStartOfAsmFile(M);
1243
1244 if (M.getPICLevel() == PICLevel::SmallPIC)
1245 return AsmPrinter::EmitStartOfAsmFile(M);
1246
1247 OutStreamer->SwitchSection(OutContext.getELFSection(
1248 ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC));
1249
1250 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(".LTOC"));
1251 MCSymbol *CurrentPos = OutContext.createTempSymbol();
1252
1253 OutStreamer->EmitLabel(CurrentPos);
1254
1255 // The GOT pointer points to the middle of the GOT, in order to reference the
1256 // entire 64kB range. 0x8000 is the midpoint.
1257 const MCExpr *tocExpr =
1258 MCBinaryExpr::createAdd(MCSymbolRefExpr::create(CurrentPos, OutContext),
1259 MCConstantExpr::create(0x8000, OutContext),
1260 OutContext);
1261
1262 OutStreamer->EmitAssignment(TOCSym, tocExpr);
1263
1264 OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
1265 }
1266
EmitFunctionEntryLabel()1267 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
1268 // linux/ppc32 - Normal entry label.
1269 if (!Subtarget->isPPC64() &&
1270 (!isPositionIndependent() ||
1271 MF->getFunction().getParent()->getPICLevel() == PICLevel::SmallPIC))
1272 return AsmPrinter::EmitFunctionEntryLabel();
1273
1274 if (!Subtarget->isPPC64()) {
1275 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1276 if (PPCFI->usesPICBase() && !Subtarget->isSecurePlt()) {
1277 MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol();
1278 MCSymbol *PICBase = MF->getPICBaseSymbol();
1279 OutStreamer->EmitLabel(RelocSymbol);
1280
1281 const MCExpr *OffsExpr =
1282 MCBinaryExpr::createSub(
1283 MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")),
1284 OutContext),
1285 MCSymbolRefExpr::create(PICBase, OutContext),
1286 OutContext);
1287 OutStreamer->EmitValue(OffsExpr, 4);
1288 OutStreamer->EmitLabel(CurrentFnSym);
1289 return;
1290 } else
1291 return AsmPrinter::EmitFunctionEntryLabel();
1292 }
1293
1294 // ELFv2 ABI - Normal entry label.
1295 if (Subtarget->isELFv2ABI()) {
1296 // In the Large code model, we allow arbitrary displacements between
1297 // the text section and its associated TOC section. We place the
1298 // full 8-byte offset to the TOC in memory immediately preceding
1299 // the function global entry point.
1300 if (TM.getCodeModel() == CodeModel::Large
1301 && !MF->getRegInfo().use_empty(PPC::X2)) {
1302 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1303
1304 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1305 MCSymbol *GlobalEPSymbol = PPCFI->getGlobalEPSymbol();
1306 const MCExpr *TOCDeltaExpr =
1307 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1308 MCSymbolRefExpr::create(GlobalEPSymbol,
1309 OutContext),
1310 OutContext);
1311
1312 OutStreamer->EmitLabel(PPCFI->getTOCOffsetSymbol());
1313 OutStreamer->EmitValue(TOCDeltaExpr, 8);
1314 }
1315 return AsmPrinter::EmitFunctionEntryLabel();
1316 }
1317
1318 // Emit an official procedure descriptor.
1319 MCSectionSubPair Current = OutStreamer->getCurrentSection();
1320 MCSectionELF *Section = OutStreamer->getContext().getELFSection(
1321 ".opd", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1322 OutStreamer->SwitchSection(Section);
1323 OutStreamer->EmitLabel(CurrentFnSym);
1324 OutStreamer->EmitValueToAlignment(8);
1325 MCSymbol *Symbol1 = CurrentFnSymForSize;
1326 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
1327 // entry point.
1328 OutStreamer->EmitValue(MCSymbolRefExpr::create(Symbol1, OutContext),
1329 8 /*size*/);
1330 MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1331 // Generates a R_PPC64_TOC relocation for TOC base insertion.
1332 OutStreamer->EmitValue(
1333 MCSymbolRefExpr::create(Symbol2, MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext),
1334 8/*size*/);
1335 // Emit a null environment pointer.
1336 OutStreamer->EmitIntValue(0, 8 /* size */);
1337 OutStreamer->SwitchSection(Current.first, Current.second);
1338 }
1339
doFinalization(Module & M)1340 bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
1341 const DataLayout &DL = getDataLayout();
1342
1343 bool isPPC64 = DL.getPointerSizeInBits() == 64;
1344
1345 PPCTargetStreamer &TS =
1346 static_cast<PPCTargetStreamer &>(*OutStreamer->getTargetStreamer());
1347
1348 if (!TOC.empty()) {
1349 MCSectionELF *Section;
1350
1351 if (isPPC64)
1352 Section = OutStreamer->getContext().getELFSection(
1353 ".toc", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1354 else
1355 Section = OutStreamer->getContext().getELFSection(
1356 ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1357 OutStreamer->SwitchSection(Section);
1358
1359 for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
1360 E = TOC.end(); I != E; ++I) {
1361 OutStreamer->EmitLabel(I->second);
1362 MCSymbol *S = I->first;
1363 if (isPPC64) {
1364 TS.emitTCEntry(*S);
1365 } else {
1366 OutStreamer->EmitValueToAlignment(4);
1367 OutStreamer->EmitSymbolValue(S, 4);
1368 }
1369 }
1370 }
1371
1372 return AsmPrinter::doFinalization(M);
1373 }
1374
1375 /// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2.
EmitFunctionBodyStart()1376 void PPCLinuxAsmPrinter::EmitFunctionBodyStart() {
1377 // In the ELFv2 ABI, in functions that use the TOC register, we need to
1378 // provide two entry points. The ABI guarantees that when calling the
1379 // local entry point, r2 is set up by the caller to contain the TOC base
1380 // for this function, and when calling the global entry point, r12 is set
1381 // up by the caller to hold the address of the global entry point. We
1382 // thus emit a prefix sequence along the following lines:
1383 //
1384 // func:
1385 // .Lfunc_gepNN:
1386 // # global entry point
1387 // addis r2,r12,(.TOC.-.Lfunc_gepNN)@ha
1388 // addi r2,r2,(.TOC.-.Lfunc_gepNN)@l
1389 // .Lfunc_lepNN:
1390 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1391 // # local entry point, followed by function body
1392 //
1393 // For the Large code model, we create
1394 //
1395 // .Lfunc_tocNN:
1396 // .quad .TOC.-.Lfunc_gepNN # done by EmitFunctionEntryLabel
1397 // func:
1398 // .Lfunc_gepNN:
1399 // # global entry point
1400 // ld r2,.Lfunc_tocNN-.Lfunc_gepNN(r12)
1401 // add r2,r2,r12
1402 // .Lfunc_lepNN:
1403 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1404 // # local entry point, followed by function body
1405 //
1406 // This ensures we have r2 set up correctly while executing the function
1407 // body, no matter which entry point is called.
1408 if (Subtarget->isELFv2ABI()
1409 // Only do all that if the function uses r2 in the first place.
1410 && !MF->getRegInfo().use_empty(PPC::X2)) {
1411 // Note: The logic here must be synchronized with the code in the
1412 // branch-selection pass which sets the offset of the first block in the
1413 // function. This matters because it affects the alignment.
1414 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1415
1416 MCSymbol *GlobalEntryLabel = PPCFI->getGlobalEPSymbol();
1417 OutStreamer->EmitLabel(GlobalEntryLabel);
1418 const MCSymbolRefExpr *GlobalEntryLabelExp =
1419 MCSymbolRefExpr::create(GlobalEntryLabel, OutContext);
1420
1421 if (TM.getCodeModel() != CodeModel::Large) {
1422 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1423 const MCExpr *TOCDeltaExpr =
1424 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1425 GlobalEntryLabelExp, OutContext);
1426
1427 const MCExpr *TOCDeltaHi =
1428 PPCMCExpr::createHa(TOCDeltaExpr, false, OutContext);
1429 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
1430 .addReg(PPC::X2)
1431 .addReg(PPC::X12)
1432 .addExpr(TOCDeltaHi));
1433
1434 const MCExpr *TOCDeltaLo =
1435 PPCMCExpr::createLo(TOCDeltaExpr, false, OutContext);
1436 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
1437 .addReg(PPC::X2)
1438 .addReg(PPC::X2)
1439 .addExpr(TOCDeltaLo));
1440 } else {
1441 MCSymbol *TOCOffset = PPCFI->getTOCOffsetSymbol();
1442 const MCExpr *TOCOffsetDeltaExpr =
1443 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCOffset, OutContext),
1444 GlobalEntryLabelExp, OutContext);
1445
1446 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
1447 .addReg(PPC::X2)
1448 .addExpr(TOCOffsetDeltaExpr)
1449 .addReg(PPC::X12));
1450 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8)
1451 .addReg(PPC::X2)
1452 .addReg(PPC::X2)
1453 .addReg(PPC::X12));
1454 }
1455
1456 MCSymbol *LocalEntryLabel = PPCFI->getLocalEPSymbol();
1457 OutStreamer->EmitLabel(LocalEntryLabel);
1458 const MCSymbolRefExpr *LocalEntryLabelExp =
1459 MCSymbolRefExpr::create(LocalEntryLabel, OutContext);
1460 const MCExpr *LocalOffsetExp =
1461 MCBinaryExpr::createSub(LocalEntryLabelExp,
1462 GlobalEntryLabelExp, OutContext);
1463
1464 PPCTargetStreamer *TS =
1465 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1466
1467 if (TS)
1468 TS->emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), LocalOffsetExp);
1469 }
1470 }
1471
1472 /// EmitFunctionBodyEnd - Print the traceback table before the .size
1473 /// directive.
1474 ///
EmitFunctionBodyEnd()1475 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
1476 // Only the 64-bit target requires a traceback table. For now,
1477 // we only emit the word of zeroes that GDB requires to find
1478 // the end of the function, and zeroes for the eight-byte
1479 // mandatory fields.
1480 // FIXME: We should fill in the eight-byte mandatory fields as described in
1481 // the PPC64 ELF ABI (this is a low-priority item because GDB does not
1482 // currently make use of these fields).
1483 if (Subtarget->isPPC64()) {
1484 OutStreamer->EmitIntValue(0, 4/*size*/);
1485 OutStreamer->EmitIntValue(0, 8/*size*/);
1486 }
1487 }
1488
EmitStartOfAsmFile(Module & M)1489 void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
1490 static const char *const CPUDirectives[] = {
1491 "",
1492 "ppc",
1493 "ppc440",
1494 "ppc601",
1495 "ppc602",
1496 "ppc603",
1497 "ppc7400",
1498 "ppc750",
1499 "ppc970",
1500 "ppcA2",
1501 "ppce500",
1502 "ppce500mc",
1503 "ppce5500",
1504 "power3",
1505 "power4",
1506 "power5",
1507 "power5x",
1508 "power6",
1509 "power6x",
1510 "power7",
1511 // FIXME: why is power8 missing here?
1512 "ppc64",
1513 "ppc64le",
1514 "power9"
1515 };
1516
1517 // Get the numerically largest directive.
1518 // FIXME: How should we merge darwin directives?
1519 unsigned Directive = PPC::DIR_NONE;
1520 for (const Function &F : M) {
1521 const PPCSubtarget &STI = TM.getSubtarget<PPCSubtarget>(F);
1522 unsigned FDir = STI.getDarwinDirective();
1523 Directive = Directive > FDir ? FDir : STI.getDarwinDirective();
1524 if (STI.hasMFOCRF() && Directive < PPC::DIR_970)
1525 Directive = PPC::DIR_970;
1526 if (STI.hasAltivec() && Directive < PPC::DIR_7400)
1527 Directive = PPC::DIR_7400;
1528 if (STI.isPPC64() && Directive < PPC::DIR_64)
1529 Directive = PPC::DIR_64;
1530 }
1531
1532 assert(Directive <= PPC::DIR_64 && "Directive out of range.");
1533
1534 assert(Directive < array_lengthof(CPUDirectives) &&
1535 "CPUDirectives[] might not be up-to-date!");
1536 PPCTargetStreamer &TStreamer =
1537 *static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1538 TStreamer.emitMachine(CPUDirectives[Directive]);
1539
1540 // Prime text sections so they are adjacent. This reduces the likelihood a
1541 // large data or debug section causes a branch to exceed 16M limit.
1542 const TargetLoweringObjectFileMachO &TLOFMacho =
1543 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1544 OutStreamer->SwitchSection(TLOFMacho.getTextCoalSection());
1545 if (TM.getRelocationModel() == Reloc::PIC_) {
1546 OutStreamer->SwitchSection(
1547 OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
1548 MachO::S_SYMBOL_STUBS |
1549 MachO::S_ATTR_PURE_INSTRUCTIONS,
1550 32, SectionKind::getText()));
1551 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
1552 OutStreamer->SwitchSection(
1553 OutContext.getMachOSection("__TEXT","__symbol_stub1",
1554 MachO::S_SYMBOL_STUBS |
1555 MachO::S_ATTR_PURE_INSTRUCTIONS,
1556 16, SectionKind::getText()));
1557 }
1558 OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
1559 }
1560
doFinalization(Module & M)1561 bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
1562 bool isPPC64 = getDataLayout().getPointerSizeInBits() == 64;
1563
1564 // Darwin/PPC always uses mach-o.
1565 const TargetLoweringObjectFileMachO &TLOFMacho =
1566 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
1567 if (MMI) {
1568 MachineModuleInfoMachO &MMIMacho =
1569 MMI->getObjFileInfo<MachineModuleInfoMachO>();
1570
1571 if (MAI->doesSupportExceptionHandling()) {
1572 // Add the (possibly multiple) personalities to the set of global values.
1573 // Only referenced functions get into the Personalities list.
1574 for (const Function *Personality : MMI->getPersonalities()) {
1575 if (Personality) {
1576 MCSymbol *NLPSym =
1577 getSymbolWithGlobalValueBase(Personality, "$non_lazy_ptr");
1578 MachineModuleInfoImpl::StubValueTy &StubSym =
1579 MMIMacho.getGVStubEntry(NLPSym);
1580 StubSym =
1581 MachineModuleInfoImpl::StubValueTy(getSymbol(Personality), true);
1582 }
1583 }
1584 }
1585
1586 // Output stubs for dynamically-linked functions.
1587 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
1588
1589 // Output macho stubs for external and common global variables.
1590 if (!Stubs.empty()) {
1591 // Switch with ".non_lazy_symbol_pointer" directive.
1592 OutStreamer->SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1593 EmitAlignment(isPPC64 ? 3 : 2);
1594
1595 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1596 // L_foo$stub:
1597 OutStreamer->EmitLabel(Stubs[i].first);
1598 // .indirect_symbol _foo
1599 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
1600 OutStreamer->EmitSymbolAttribute(MCSym.getPointer(),
1601 MCSA_IndirectSymbol);
1602
1603 if (MCSym.getInt())
1604 // External to current translation unit.
1605 OutStreamer->EmitIntValue(0, isPPC64 ? 8 : 4 /*size*/);
1606 else
1607 // Internal to current translation unit.
1608 //
1609 // When we place the LSDA into the TEXT section, the type info
1610 // pointers
1611 // need to be indirect and pc-rel. We accomplish this by using NLPs.
1612 // However, sometimes the types are local to the file. So we need to
1613 // fill in the value for the NLP in those cases.
1614 OutStreamer->EmitValue(
1615 MCSymbolRefExpr::create(MCSym.getPointer(), OutContext),
1616 isPPC64 ? 8 : 4 /*size*/);
1617 }
1618
1619 Stubs.clear();
1620 OutStreamer->AddBlankLine();
1621 }
1622 }
1623
1624 // Funny Darwin hack: This flag tells the linker that no global symbols
1625 // contain code that falls through to other global symbols (e.g. the obvious
1626 // implementation of multiple entry points). If this doesn't occur, the
1627 // linker can safely perform dead code stripping. Since LLVM never generates
1628 // code that does this, it is always safe to set.
1629 OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
1630
1631 return AsmPrinter::doFinalization(M);
1632 }
1633
1634 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
1635 /// for a MachineFunction to the given output stream, in a format that the
1636 /// Darwin assembler can deal with.
1637 ///
1638 static AsmPrinter *
createPPCAsmPrinterPass(TargetMachine & tm,std::unique_ptr<MCStreamer> && Streamer)1639 createPPCAsmPrinterPass(TargetMachine &tm,
1640 std::unique_ptr<MCStreamer> &&Streamer) {
1641 if (tm.getTargetTriple().isMacOSX())
1642 return new PPCDarwinAsmPrinter(tm, std::move(Streamer));
1643 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
1644 }
1645
1646 // Force static initialization.
LLVMInitializePowerPCAsmPrinter()1647 extern "C" void LLVMInitializePowerPCAsmPrinter() {
1648 TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
1649 createPPCAsmPrinterPass);
1650 TargetRegistry::RegisterAsmPrinter(getThePPC64Target(),
1651 createPPCAsmPrinterPass);
1652 TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(),
1653 createPPCAsmPrinterPass);
1654 }
1655