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