1 //===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly ------===//
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
7 //===----------------------------------------------------------------------===//
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"
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/GlobalVariable.h"
47 #include "llvm/IR/Module.h"
48 #include "llvm/MC/MCAsmInfo.h"
49 #include "llvm/MC/MCContext.h"
50 #include "llvm/MC/MCExpr.h"
51 #include "llvm/MC/MCInst.h"
52 #include "llvm/MC/MCInstBuilder.h"
53 #include "llvm/MC/MCSectionELF.h"
54 #include "llvm/MC/MCSectionMachO.h"
55 #include "llvm/MC/MCSectionXCOFF.h"
56 #include "llvm/MC/MCStreamer.h"
57 #include "llvm/MC/MCSymbol.h"
58 #include "llvm/MC/MCSymbolELF.h"
59 #include "llvm/MC/MCSymbolXCOFF.h"
60 #include "llvm/MC/SectionKind.h"
61 #include "llvm/Support/Casting.h"
62 #include "llvm/Support/CodeGen.h"
63 #include "llvm/Support/Debug.h"
64 #include "llvm/Support/ErrorHandling.h"
65 #include "llvm/Support/TargetRegistry.h"
66 #include "llvm/Support/raw_ostream.h"
67 #include "llvm/Target/TargetMachine.h"
76 #define DEBUG_TYPE "asmprinter"
80 class PPCAsmPrinter : public AsmPrinter {
82 MapVector<const MCSymbol *, MCSymbol *> TOC;
83 const PPCSubtarget *Subtarget = nullptr;
86 virtual MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO);
89 explicit PPCAsmPrinter(TargetMachine &TM,
90 std::unique_ptr<MCStreamer> Streamer)
91 : AsmPrinter(TM, std::move(Streamer)), SM(*this) {}
93 StringRef getPassName() const override { return "PowerPC Assembly Printer"; }
95 MCSymbol *lookUpOrCreateTOCEntry(const MCSymbol *Sym);
97 bool doInitialization(Module &M) override {
100 return AsmPrinter::doInitialization(M);
103 void EmitInstruction(const MachineInstr *MI) override;
105 /// This function is for PrintAsmOperand and PrintAsmMemoryOperand,
106 /// invoked by EmitMSInlineAsmStr and EmitGCCInlineAsmStr only.
107 /// The \p MI would be INLINEASM ONLY.
108 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
110 void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
111 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
112 const char *ExtraCode, raw_ostream &O) override;
113 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
114 const char *ExtraCode, raw_ostream &O) override;
116 void EmitEndOfAsmFile(Module &M) override;
118 void LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI);
119 void LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI);
120 void EmitTlsCall(const MachineInstr *MI, MCSymbolRefExpr::VariantKind VK);
121 bool runOnMachineFunction(MachineFunction &MF) override {
122 Subtarget = &MF.getSubtarget<PPCSubtarget>();
123 bool Changed = AsmPrinter::runOnMachineFunction(MF);
129 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
130 class PPCLinuxAsmPrinter : public PPCAsmPrinter {
132 explicit PPCLinuxAsmPrinter(TargetMachine &TM,
133 std::unique_ptr<MCStreamer> Streamer)
134 : PPCAsmPrinter(TM, std::move(Streamer)) {}
136 StringRef getPassName() const override {
137 return "Linux PPC Assembly Printer";
140 bool doFinalization(Module &M) override;
141 void EmitStartOfAsmFile(Module &M) override;
143 void EmitFunctionEntryLabel() override;
145 void EmitFunctionBodyStart() override;
146 void EmitFunctionBodyEnd() override;
147 void EmitInstruction(const MachineInstr *MI) override;
150 class PPCAIXAsmPrinter : public PPCAsmPrinter {
152 static void ValidateGV(const GlobalVariable *GV);
154 MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO) override;
157 PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
158 : PPCAsmPrinter(TM, std::move(Streamer)) {}
160 StringRef getPassName() const override { return "AIX PPC Assembly Printer"; }
162 void SetupMachineFunction(MachineFunction &MF) override;
164 const MCExpr *lowerConstant(const Constant *CV) override;
166 void EmitGlobalVariable(const GlobalVariable *GV) override;
168 void EmitFunctionDescriptor() override;
170 void EmitEndOfAsmFile(Module &) override;
173 } // end anonymous namespace
175 void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
177 // Computing the address of a global symbol, not calling it.
178 const GlobalValue *GV = MO.getGlobal();
179 MCSymbol *SymToPrint;
181 // External or weakly linked global variables need non-lazily-resolved stubs
182 if (Subtarget->hasLazyResolverStub(GV)) {
183 SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
184 MachineModuleInfoImpl::StubValueTy &StubSym =
185 MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(
187 if (!StubSym.getPointer())
188 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
189 !GV->hasInternalLinkage());
191 SymToPrint = getSymbol(GV);
194 SymToPrint->print(O, MAI);
196 printOffset(MO.getOffset(), O);
199 void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
201 const DataLayout &DL = getDataLayout();
202 const MachineOperand &MO = MI->getOperand(OpNo);
204 switch (MO.getType()) {
205 case MachineOperand::MO_Register: {
206 // The MI is INLINEASM ONLY and UseVSXReg is always false.
207 const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg());
209 // Linux assembler (Others?) does not take register mnemonics.
210 // FIXME - What about special registers used in mfspr/mtspr?
211 if (!Subtarget->isDarwin())
212 RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
216 case MachineOperand::MO_Immediate:
220 case MachineOperand::MO_MachineBasicBlock:
221 MO.getMBB()->getSymbol()->print(O, MAI);
223 case MachineOperand::MO_ConstantPoolIndex:
224 O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
227 case MachineOperand::MO_BlockAddress:
228 GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
230 case MachineOperand::MO_GlobalAddress: {
231 PrintSymbolOperand(MO, O);
236 O << "<unknown operand type: " << (unsigned)MO.getType() << ">";
241 /// PrintAsmOperand - Print out an operand for an inline asm expression.
243 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
244 const char *ExtraCode, raw_ostream &O) {
245 // Does this asm operand have a single letter operand modifier?
246 if (ExtraCode && ExtraCode[0]) {
247 if (ExtraCode[1] != 0) return true; // Unknown modifier.
249 switch (ExtraCode[0]) {
251 // See if this is a generic print operand
252 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
253 case 'L': // Write second word of DImode reference.
254 // Verify that this operand has two consecutive registers.
255 if (!MI->getOperand(OpNo).isReg() ||
256 OpNo+1 == MI->getNumOperands() ||
257 !MI->getOperand(OpNo+1).isReg())
259 ++OpNo; // Return the high-part.
262 // Write 'i' if an integer constant, otherwise nothing. Used to print
264 if (MI->getOperand(OpNo).isImm())
268 if(!MI->getOperand(OpNo).isReg())
270 // This operand uses VSX numbering.
271 // If the operand is a VMX register, convert it to a VSX register.
272 Register Reg = MI->getOperand(OpNo).getReg();
273 if (PPCInstrInfo::isVRRegister(Reg))
274 Reg = PPC::VSX32 + (Reg - PPC::V0);
275 else if (PPCInstrInfo::isVFRegister(Reg))
276 Reg = PPC::VSX32 + (Reg - PPC::VF0);
278 RegName = PPCInstPrinter::getRegisterName(Reg);
279 RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
285 printOperand(MI, OpNo, O);
289 // At the moment, all inline asm memory operands are a single register.
290 // In any case, the output of this routine should always be just one
291 // assembler operand.
293 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
294 const char *ExtraCode,
296 if (ExtraCode && ExtraCode[0]) {
297 if (ExtraCode[1] != 0) return true; // Unknown modifier.
299 switch (ExtraCode[0]) {
300 default: return true; // Unknown modifier.
301 case 'L': // A memory reference to the upper word of a double word op.
302 O << getDataLayout().getPointerSize() << "(";
303 printOperand(MI, OpNo, O);
306 case 'y': // A memory reference for an X-form instruction
308 const char *RegName = "r0";
309 if (!Subtarget->isDarwin())
310 RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
311 O << RegName << ", ";
312 printOperand(MI, OpNo, O);
315 case 'U': // Print 'u' for update form.
316 case 'X': // Print 'x' for indexed form.
317 // FIXME: Currently for PowerPC memory operands are always loaded
318 // into a register, so we never get an update or indexed form.
319 // This is bad even for offset forms, since even if we know we
320 // have a value in -16(r1), we will generate a load into r<n>
321 // and then load from 0(r<n>). Until that issue is fixed,
322 // tolerate 'U' and 'X' but don't output anything.
323 assert(MI->getOperand(OpNo).isReg());
328 assert(MI->getOperand(OpNo).isReg());
330 printOperand(MI, OpNo, O);
335 /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
336 /// exists for it. If not, create one. Then return a symbol that references
338 MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(const MCSymbol *Sym) {
339 MCSymbol *&TOCEntry = TOC[Sym];
341 TOCEntry = createTempSymbol("C");
345 void PPCAsmPrinter::EmitEndOfAsmFile(Module &M) {
349 void PPCAsmPrinter::LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI) {
350 unsigned NumNOPBytes = MI.getOperand(1).getImm();
352 auto &Ctx = OutStreamer->getContext();
353 MCSymbol *MILabel = Ctx.createTempSymbol();
354 OutStreamer->EmitLabel(MILabel);
356 SM.recordStackMap(*MILabel, MI);
357 assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
359 // Scan ahead to trim the shadow.
360 const MachineBasicBlock &MBB = *MI.getParent();
361 MachineBasicBlock::const_iterator MII(MI);
363 while (NumNOPBytes > 0) {
364 if (MII == MBB.end() || MII->isCall() ||
365 MII->getOpcode() == PPC::DBG_VALUE ||
366 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
367 MII->getOpcode() == TargetOpcode::STACKMAP)
374 for (unsigned i = 0; i < NumNOPBytes; i += 4)
375 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
378 // Lower a patchpoint of the form:
379 // [<def>], <id>, <numBytes>, <target>, <numArgs>
380 void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) {
381 auto &Ctx = OutStreamer->getContext();
382 MCSymbol *MILabel = Ctx.createTempSymbol();
383 OutStreamer->EmitLabel(MILabel);
385 SM.recordPatchPoint(*MILabel, MI);
386 PatchPointOpers Opers(&MI);
388 unsigned EncodedBytes = 0;
389 const MachineOperand &CalleeMO = Opers.getCallTarget();
391 if (CalleeMO.isImm()) {
392 int64_t CallTarget = CalleeMO.getImm();
394 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
395 "High 16 bits of call target should be zero.");
396 Register ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
398 // Materialize the jump address:
399 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8)
401 .addImm((CallTarget >> 32) & 0xFFFF));
403 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC)
406 .addImm(32).addImm(16));
408 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8)
411 .addImm((CallTarget >> 16) & 0xFFFF));
413 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8)
416 .addImm(CallTarget & 0xFFFF));
418 // Save the current TOC pointer before the remote call.
419 int TOCSaveOffset = Subtarget->getFrameLowering()->getTOCSaveOffset();
420 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD)
422 .addImm(TOCSaveOffset)
426 // If we're on ELFv1, then we need to load the actual function pointer
427 // from the function descriptor.
428 if (!Subtarget->isELFv2ABI()) {
429 // Load the new TOC pointer and the function address, but not r11
430 // (needing this is rare, and loading it here would prevent passing it
431 // via a 'nest' parameter.
432 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
435 .addReg(ScratchReg));
437 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
440 .addReg(ScratchReg));
444 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8)
445 .addReg(ScratchReg));
447 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8));
450 // Restore the TOC pointer after the call.
451 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
453 .addImm(TOCSaveOffset)
457 } else if (CalleeMO.isGlobal()) {
458 const GlobalValue *GValue = CalleeMO.getGlobal();
459 MCSymbol *MOSymbol = getSymbol(GValue);
460 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, OutContext);
462 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP)
467 // Each instruction is 4 bytes.
471 unsigned NumBytes = Opers.getNumPatchBytes();
472 assert(NumBytes >= EncodedBytes &&
473 "Patchpoint can't request size less than the length of a call.");
474 assert((NumBytes - EncodedBytes) % 4 == 0 &&
475 "Invalid number of NOP bytes requested!");
476 for (unsigned i = EncodedBytes; i < NumBytes; i += 4)
477 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
480 /// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a
481 /// call to __tls_get_addr to the current output stream.
482 void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
483 MCSymbolRefExpr::VariantKind VK) {
484 StringRef Name = "__tls_get_addr";
485 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(Name);
486 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
487 const Module *M = MF->getFunction().getParent();
489 assert(MI->getOperand(0).isReg() &&
490 ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) ||
491 (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) &&
492 "GETtls[ld]ADDR[32] must define GPR3");
493 assert(MI->getOperand(1).isReg() &&
494 ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) ||
495 (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) &&
496 "GETtls[ld]ADDR[32] must read GPR3");
498 if (Subtarget->is32BitELFABI() && isPositionIndependent())
499 Kind = MCSymbolRefExpr::VK_PLT;
501 const MCExpr *TlsRef =
502 MCSymbolRefExpr::create(TlsGetAddr, Kind, OutContext);
504 // Add 32768 offset to the symbol so we follow up the latest GOT/PLT ABI.
505 if (Kind == MCSymbolRefExpr::VK_PLT && Subtarget->isSecurePlt() &&
506 M->getPICLevel() == PICLevel::BigPIC)
507 TlsRef = MCBinaryExpr::createAdd(
508 TlsRef, MCConstantExpr::create(32768, OutContext), OutContext);
509 const MachineOperand &MO = MI->getOperand(2);
510 const GlobalValue *GValue = MO.getGlobal();
511 MCSymbol *MOSymbol = getSymbol(GValue);
512 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
513 EmitToStreamer(*OutStreamer,
514 MCInstBuilder(Subtarget->isPPC64() ?
515 PPC::BL8_NOP_TLS : PPC::BL_TLS)
520 /// Map a machine operand for a TOC pseudo-machine instruction to its
521 /// corresponding MCSymbol.
522 MCSymbol *PPCAsmPrinter::getMCSymbolForTOCPseudoMO(const MachineOperand &MO) {
523 switch (MO.getType()) {
524 case MachineOperand::MO_GlobalAddress:
525 return getSymbol(MO.getGlobal());
526 case MachineOperand::MO_ConstantPoolIndex:
527 return GetCPISymbol(MO.getIndex());
528 case MachineOperand::MO_JumpTableIndex:
529 return GetJTISymbol(MO.getIndex());
530 case MachineOperand::MO_BlockAddress:
531 return GetBlockAddressSymbol(MO.getBlockAddress());
533 llvm_unreachable("Unexpected operand type to get symbol.");
537 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
538 /// the current output stream.
540 void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
542 const bool IsDarwin = TM.getTargetTriple().isOSDarwin();
543 const bool IsPPC64 = Subtarget->isPPC64();
544 const bool IsAIX = Subtarget->isAIXABI();
545 const Module *M = MF->getFunction().getParent();
546 PICLevel::Level PL = M->getPICLevel();
549 // Validate that SPE and FPU are mutually exclusive in codegen
550 if (!MI->isInlineAsm()) {
551 for (const MachineOperand &MO: MI->operands()) {
553 Register Reg = MO.getReg();
554 if (Subtarget->hasSPE()) {
555 if (PPC::F4RCRegClass.contains(Reg) ||
556 PPC::F8RCRegClass.contains(Reg) ||
557 PPC::QBRCRegClass.contains(Reg) ||
558 PPC::QFRCRegClass.contains(Reg) ||
559 PPC::QSRCRegClass.contains(Reg) ||
560 PPC::VFRCRegClass.contains(Reg) ||
561 PPC::VRRCRegClass.contains(Reg) ||
562 PPC::VSFRCRegClass.contains(Reg) ||
563 PPC::VSSRCRegClass.contains(Reg)
565 llvm_unreachable("SPE targets cannot have FPRegs!");
567 if (PPC::SPERCRegClass.contains(Reg))
568 llvm_unreachable("SPE register found in FPU-targeted code!");
574 // Lower multi-instruction pseudo operations.
575 switch (MI->getOpcode()) {
577 case TargetOpcode::DBG_VALUE:
578 llvm_unreachable("Should be handled target independently");
579 case TargetOpcode::STACKMAP:
580 return LowerSTACKMAP(SM, *MI);
581 case TargetOpcode::PATCHPOINT:
582 return LowerPATCHPOINT(SM, *MI);
584 case PPC::MoveGOTtoLR: {
585 // Transform %lr = MoveGOTtoLR
586 // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
587 // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding
588 // _GLOBAL_OFFSET_TABLE_) has exactly one instruction:
590 // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local
591 MCSymbol *GOTSymbol =
592 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
593 const MCExpr *OffsExpr =
594 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol,
595 MCSymbolRefExpr::VK_PPC_LOCAL,
597 MCConstantExpr::create(4, OutContext),
601 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));
604 case PPC::MovePCtoLR:
605 case PPC::MovePCtoLR8: {
606 // Transform %lr = MovePCtoLR
607 // Into this, where the label is the PIC base:
610 MCSymbol *PICBase = MF->getPICBaseSymbol();
613 EmitToStreamer(*OutStreamer,
614 MCInstBuilder(PPC::BL)
615 // FIXME: We would like an efficient form for this, so we
616 // don't have to do a lot of extra uniquing.
617 .addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));
620 OutStreamer->EmitLabel(PICBase);
623 case PPC::UpdateGBR: {
624 // Transform %rd = UpdateGBR(%rt, %ri)
625 // Into: lwz %rt, .L0$poff - .L0$pb(%ri)
627 // or into (if secure plt mode is on):
628 // addis r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@ha
629 // addi r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@l
630 // Get the offset from the GOT Base Register to the GOT
631 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
632 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
633 unsigned PICR = TmpInst.getOperand(0).getReg();
634 MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
635 M->getPICLevel() == PICLevel::SmallPIC ? "_GLOBAL_OFFSET_TABLE_"
638 MCSymbolRefExpr::create(MF->getPICBaseSymbol(), OutContext);
640 const MCExpr *DeltaExpr = MCBinaryExpr::createSub(
641 MCSymbolRefExpr::create(BaseSymbol, OutContext), PB, OutContext);
643 const MCExpr *DeltaHi = PPCMCExpr::createHa(DeltaExpr, false, OutContext);
646 MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));
648 const MCExpr *DeltaLo = PPCMCExpr::createLo(DeltaExpr, false, OutContext);
651 MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
654 MCSymbol *PICOffset =
655 MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
656 TmpInst.setOpcode(PPC::LWZ);
658 MCSymbolRefExpr::create(PICOffset, MCSymbolRefExpr::VK_None, OutContext);
660 MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
661 MCSymbolRefExpr::VK_None,
663 const MCOperand TR = TmpInst.getOperand(1);
664 const MCOperand PICR = TmpInst.getOperand(0);
666 // Step 1: lwz %rt, .L$poff - .L$pb(%ri)
667 TmpInst.getOperand(1) =
668 MCOperand::createExpr(MCBinaryExpr::createSub(Exp, PB, OutContext));
669 TmpInst.getOperand(0) = TR;
670 TmpInst.getOperand(2) = PICR;
671 EmitToStreamer(*OutStreamer, TmpInst);
673 TmpInst.setOpcode(PPC::ADD4);
674 TmpInst.getOperand(0) = PICR;
675 TmpInst.getOperand(1) = TR;
676 TmpInst.getOperand(2) = PICR;
677 EmitToStreamer(*OutStreamer, TmpInst);
682 assert(!IsDarwin && "TOC is an ELF/XCOFF construct.");
684 // Transform %rN = LWZtoc @op1, %r2
685 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
687 // Change the opcode to LWZ.
688 TmpInst.setOpcode(PPC::LWZ);
690 const MachineOperand &MO = MI->getOperand(1);
691 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
692 "Invalid operand for LWZtoc.");
694 // Map the operand to its corresponding MCSymbol.
695 const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO);
697 // Create a reference to the GOT entry for the symbol. The GOT entry will be
698 // synthesized later.
699 if (PL == PICLevel::SmallPIC && !IsAIX) {
701 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_GOT,
703 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
704 EmitToStreamer(*OutStreamer, TmpInst);
708 // Otherwise, use the TOC. 'TOCEntry' is a label used to reference the
709 // storage allocated in the TOC which contains the address of
710 // 'MOSymbol'. Said TOC entry will be synthesized later.
711 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
713 MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_None, OutContext);
715 // AIX uses the label directly as the lwz displacement operand for
716 // references into the toc section. The displacement value will be generated
717 // relative to the toc-base.
720 TM.getCodeModel() == CodeModel::Small &&
721 "This pseudo should only be selected for 32-bit small code model.");
722 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
723 EmitToStreamer(*OutStreamer, TmpInst);
727 // Create an explicit subtract expression between the local symbol and
728 // '.LTOC' to manifest the toc-relative offset.
729 const MCExpr *PB = MCSymbolRefExpr::create(
730 OutContext.getOrCreateSymbol(Twine(".LTOC")), OutContext);
731 Exp = MCBinaryExpr::createSub(Exp, PB, OutContext);
732 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
733 EmitToStreamer(*OutStreamer, TmpInst);
740 assert(!IsDarwin && "TOC is an ELF/XCOFF construct");
742 // Transform %x3 = LDtoc @min1, %x2
743 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
745 // Change the opcode to LD.
746 TmpInst.setOpcode(PPC::LD);
748 const MachineOperand &MO = MI->getOperand(1);
749 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
752 // Map the machine operand to its corresponding MCSymbol, then map the
753 // global address operand to be a reference to the TOC entry we will
756 lookUpOrCreateTOCEntry(getMCSymbolForTOCPseudoMO(MO));
758 const MCSymbolRefExpr::VariantKind VK =
759 IsAIX ? MCSymbolRefExpr::VK_None : MCSymbolRefExpr::VK_PPC_TOC;
761 MCSymbolRefExpr::create(TOCEntry, VK, OutContext);
762 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
763 EmitToStreamer(*OutStreamer, TmpInst);
766 case PPC::ADDIStocHA: {
767 assert((IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large) &&
768 "This pseudo should only be selected for 32-bit large code model on"
771 // Transform %rd = ADDIStocHA %rA, @sym(%r2)
772 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
774 // Change the opcode to ADDIS.
775 TmpInst.setOpcode(PPC::ADDIS);
777 const MachineOperand &MO = MI->getOperand(2);
778 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
779 "Invalid operand for ADDIStocHA.");
781 // Map the machine operand to its corresponding MCSymbol.
782 MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
784 // Always use TOC on AIX. Map the global address operand to be a reference
785 // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
786 // reference the storage allocated in the TOC which contains the address of
788 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
789 const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry,
790 MCSymbolRefExpr::VK_PPC_U,
792 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
793 EmitToStreamer(*OutStreamer, TmpInst);
797 assert(IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large &&
798 "This pseudo should only be selected for 32-bit large code model on"
801 // Transform %rd = LWZtocL @sym, %rs.
802 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
804 // Change the opcode to lwz.
805 TmpInst.setOpcode(PPC::LWZ);
807 const MachineOperand &MO = MI->getOperand(1);
808 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
809 "Invalid operand for LWZtocL.");
811 // Map the machine operand to its corresponding MCSymbol.
812 MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
814 // Always use TOC on AIX. Map the global address operand to be a reference
815 // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
816 // reference the storage allocated in the TOC which contains the address of
818 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
819 const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry,
820 MCSymbolRefExpr::VK_PPC_L,
822 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
823 EmitToStreamer(*OutStreamer, TmpInst);
826 case PPC::ADDIStocHA8: {
827 assert(!IsDarwin && "TOC is an ELF/XCOFF construct");
829 // Transform %xd = ADDIStocHA8 %x2, @sym
830 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
832 // Change the opcode to ADDIS8. If the global address is the address of
833 // an external symbol, is a jump table address, is a block address, or is a
834 // constant pool index with large code model enabled, then generate a TOC
835 // entry and reference that. Otherwise, reference the symbol directly.
836 TmpInst.setOpcode(PPC::ADDIS8);
838 const MachineOperand &MO = MI->getOperand(2);
839 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
840 "Invalid operand for ADDIStocHA8!");
842 const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
844 const bool GlobalToc =
845 MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal());
846 if (GlobalToc || MO.isJTI() || MO.isBlockAddress() ||
847 (MO.isCPI() && TM.getCodeModel() == CodeModel::Large))
848 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
850 const MCSymbolRefExpr::VariantKind VK =
851 IsAIX ? MCSymbolRefExpr::VK_PPC_U : MCSymbolRefExpr::VK_PPC_TOC_HA;
854 MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
856 if (!MO.isJTI() && MO.getOffset())
857 Exp = MCBinaryExpr::createAdd(Exp,
858 MCConstantExpr::create(MO.getOffset(),
862 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
863 EmitToStreamer(*OutStreamer, TmpInst);
867 assert(!IsDarwin && "TOC is an ELF/XCOFF construct");
869 // Transform %xd = LDtocL @sym, %xs
870 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
872 // Change the opcode to LD. If the global address is the address of
873 // an external symbol, is a jump table address, is a block address, or is
874 // a constant pool index with large code model enabled, then generate a
875 // TOC entry and reference that. Otherwise, reference the symbol directly.
876 TmpInst.setOpcode(PPC::LD);
878 const MachineOperand &MO = MI->getOperand(1);
879 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
880 MO.isBlockAddress()) &&
881 "Invalid operand for LDtocL!");
884 (!MO.isGlobal() || Subtarget->isGVIndirectSymbol(MO.getGlobal())) &&
885 "LDtocL used on symbol that could be accessed directly is "
886 "invalid. Must match ADDIStocHA8."));
888 const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
890 if (!MO.isCPI() || TM.getCodeModel() == CodeModel::Large)
891 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
893 const MCSymbolRefExpr::VariantKind VK =
894 IsAIX ? MCSymbolRefExpr::VK_PPC_L : MCSymbolRefExpr::VK_PPC_TOC_LO;
896 MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
897 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
898 EmitToStreamer(*OutStreamer, TmpInst);
901 case PPC::ADDItocL: {
902 // Transform %xd = ADDItocL %xs, @sym
903 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
905 // Change the opcode to ADDI8. If the global address is external, then
906 // generate a TOC entry and reference that. Otherwise, reference the
908 TmpInst.setOpcode(PPC::ADDI8);
910 const MachineOperand &MO = MI->getOperand(2);
911 assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL.");
914 !(MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal())) &&
915 "Interposable definitions must use indirect access."));
918 MCSymbolRefExpr::create(getMCSymbolForTOCPseudoMO(MO),
919 MCSymbolRefExpr::VK_PPC_TOC_LO, OutContext);
920 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
921 EmitToStreamer(*OutStreamer, TmpInst);
924 case PPC::ADDISgotTprelHA: {
925 // Transform: %xd = ADDISgotTprelHA %x2, @sym
926 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
927 assert(IsPPC64 && "Not supported for 32-bit PowerPC");
928 const MachineOperand &MO = MI->getOperand(2);
929 const GlobalValue *GValue = MO.getGlobal();
930 MCSymbol *MOSymbol = getSymbol(GValue);
931 const MCExpr *SymGotTprel =
932 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA,
934 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
935 .addReg(MI->getOperand(0).getReg())
936 .addReg(MI->getOperand(1).getReg())
937 .addExpr(SymGotTprel));
940 case PPC::LDgotTprelL:
941 case PPC::LDgotTprelL32: {
942 // Transform %xd = LDgotTprelL @sym, %xs
943 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
945 // Change the opcode to LD.
946 TmpInst.setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ);
947 const MachineOperand &MO = MI->getOperand(1);
948 const GlobalValue *GValue = MO.getGlobal();
949 MCSymbol *MOSymbol = getSymbol(GValue);
950 const MCExpr *Exp = MCSymbolRefExpr::create(
951 MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO
952 : MCSymbolRefExpr::VK_PPC_GOT_TPREL,
954 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
955 EmitToStreamer(*OutStreamer, TmpInst);
959 case PPC::PPC32PICGOT: {
960 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
961 MCSymbol *GOTRef = OutContext.createTempSymbol();
962 MCSymbol *NextInstr = OutContext.createTempSymbol();
964 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL)
965 // FIXME: We would like an efficient form for this, so we don't have to do
966 // a lot of extra uniquing.
967 .addExpr(MCSymbolRefExpr::create(NextInstr, OutContext)));
968 const MCExpr *OffsExpr =
969 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol, OutContext),
970 MCSymbolRefExpr::create(GOTRef, OutContext),
972 OutStreamer->EmitLabel(GOTRef);
973 OutStreamer->EmitValue(OffsExpr, 4);
974 OutStreamer->EmitLabel(NextInstr);
975 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR)
976 .addReg(MI->getOperand(0).getReg()));
977 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
978 .addReg(MI->getOperand(1).getReg())
980 .addReg(MI->getOperand(0).getReg()));
981 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4)
982 .addReg(MI->getOperand(0).getReg())
983 .addReg(MI->getOperand(1).getReg())
984 .addReg(MI->getOperand(0).getReg()));
987 case PPC::PPC32GOT: {
988 MCSymbol *GOTSymbol =
989 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
990 const MCExpr *SymGotTlsL = MCSymbolRefExpr::create(
991 GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, OutContext);
992 const MCExpr *SymGotTlsHA = MCSymbolRefExpr::create(
993 GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, OutContext);
994 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI)
995 .addReg(MI->getOperand(0).getReg())
996 .addExpr(SymGotTlsL));
997 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
998 .addReg(MI->getOperand(0).getReg())
999 .addReg(MI->getOperand(0).getReg())
1000 .addExpr(SymGotTlsHA));
1003 case PPC::ADDIStlsgdHA: {
1004 // Transform: %xd = ADDIStlsgdHA %x2, @sym
1005 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
1006 assert(IsPPC64 && "Not supported for 32-bit PowerPC");
1007 const MachineOperand &MO = MI->getOperand(2);
1008 const GlobalValue *GValue = MO.getGlobal();
1009 MCSymbol *MOSymbol = getSymbol(GValue);
1010 const MCExpr *SymGotTlsGD =
1011 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA,
1013 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1014 .addReg(MI->getOperand(0).getReg())
1015 .addReg(MI->getOperand(1).getReg())
1016 .addExpr(SymGotTlsGD));
1019 case PPC::ADDItlsgdL:
1020 // Transform: %xd = ADDItlsgdL %xs, @sym
1021 // Into: %xd = ADDI8 %xs, sym@got@tlsgd@l
1022 case PPC::ADDItlsgdL32: {
1023 // Transform: %rd = ADDItlsgdL32 %rs, @sym
1024 // Into: %rd = ADDI %rs, sym@got@tlsgd
1025 const MachineOperand &MO = MI->getOperand(2);
1026 const GlobalValue *GValue = MO.getGlobal();
1027 MCSymbol *MOSymbol = getSymbol(GValue);
1028 const MCExpr *SymGotTlsGD = MCSymbolRefExpr::create(
1029 MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO
1030 : MCSymbolRefExpr::VK_PPC_GOT_TLSGD,
1032 EmitToStreamer(*OutStreamer,
1033 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1034 .addReg(MI->getOperand(0).getReg())
1035 .addReg(MI->getOperand(1).getReg())
1036 .addExpr(SymGotTlsGD));
1039 case PPC::GETtlsADDR:
1040 // Transform: %x3 = GETtlsADDR %x3, @sym
1041 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd)
1042 case PPC::GETtlsADDR32: {
1043 // Transform: %r3 = GETtlsADDR32 %r3, @sym
1044 // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT
1045 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSGD);
1048 case PPC::ADDIStlsldHA: {
1049 // Transform: %xd = ADDIStlsldHA %x2, @sym
1050 // Into: %xd = ADDIS8 %x2, sym@got@tlsld@ha
1051 assert(IsPPC64 && "Not supported for 32-bit PowerPC");
1052 const MachineOperand &MO = MI->getOperand(2);
1053 const GlobalValue *GValue = MO.getGlobal();
1054 MCSymbol *MOSymbol = getSymbol(GValue);
1055 const MCExpr *SymGotTlsLD =
1056 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA,
1058 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1059 .addReg(MI->getOperand(0).getReg())
1060 .addReg(MI->getOperand(1).getReg())
1061 .addExpr(SymGotTlsLD));
1064 case PPC::ADDItlsldL:
1065 // Transform: %xd = ADDItlsldL %xs, @sym
1066 // Into: %xd = ADDI8 %xs, sym@got@tlsld@l
1067 case PPC::ADDItlsldL32: {
1068 // Transform: %rd = ADDItlsldL32 %rs, @sym
1069 // Into: %rd = ADDI %rs, sym@got@tlsld
1070 const MachineOperand &MO = MI->getOperand(2);
1071 const GlobalValue *GValue = MO.getGlobal();
1072 MCSymbol *MOSymbol = getSymbol(GValue);
1073 const MCExpr *SymGotTlsLD = MCSymbolRefExpr::create(
1074 MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO
1075 : MCSymbolRefExpr::VK_PPC_GOT_TLSLD,
1077 EmitToStreamer(*OutStreamer,
1078 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1079 .addReg(MI->getOperand(0).getReg())
1080 .addReg(MI->getOperand(1).getReg())
1081 .addExpr(SymGotTlsLD));
1084 case PPC::GETtlsldADDR:
1085 // Transform: %x3 = GETtlsldADDR %x3, @sym
1086 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld)
1087 case PPC::GETtlsldADDR32: {
1088 // Transform: %r3 = GETtlsldADDR32 %r3, @sym
1089 // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT
1090 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSLD);
1093 case PPC::ADDISdtprelHA:
1094 // Transform: %xd = ADDISdtprelHA %xs, @sym
1095 // Into: %xd = ADDIS8 %xs, sym@dtprel@ha
1096 case PPC::ADDISdtprelHA32: {
1097 // Transform: %rd = ADDISdtprelHA32 %rs, @sym
1098 // Into: %rd = ADDIS %rs, sym@dtprel@ha
1099 const MachineOperand &MO = MI->getOperand(2);
1100 const GlobalValue *GValue = MO.getGlobal();
1101 MCSymbol *MOSymbol = getSymbol(GValue);
1102 const MCExpr *SymDtprel =
1103 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA,
1107 MCInstBuilder(IsPPC64 ? PPC::ADDIS8 : PPC::ADDIS)
1108 .addReg(MI->getOperand(0).getReg())
1109 .addReg(MI->getOperand(1).getReg())
1110 .addExpr(SymDtprel));
1113 case PPC::ADDIdtprelL:
1114 // Transform: %xd = ADDIdtprelL %xs, @sym
1115 // Into: %xd = ADDI8 %xs, sym@dtprel@l
1116 case PPC::ADDIdtprelL32: {
1117 // Transform: %rd = ADDIdtprelL32 %rs, @sym
1118 // Into: %rd = ADDI %rs, sym@dtprel@l
1119 const MachineOperand &MO = MI->getOperand(2);
1120 const GlobalValue *GValue = MO.getGlobal();
1121 MCSymbol *MOSymbol = getSymbol(GValue);
1122 const MCExpr *SymDtprel =
1123 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO,
1125 EmitToStreamer(*OutStreamer,
1126 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1127 .addReg(MI->getOperand(0).getReg())
1128 .addReg(MI->getOperand(1).getReg())
1129 .addExpr(SymDtprel));
1134 if (!Subtarget->hasMFOCRF()) {
1135 // Transform: %r3 = MFOCRF %cr7
1136 // Into: %r3 = MFCR ;; cr7
1137 unsigned NewOpcode =
1138 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
1139 OutStreamer->AddComment(PPCInstPrinter::
1140 getRegisterName(MI->getOperand(1).getReg()));
1141 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1142 .addReg(MI->getOperand(0).getReg()));
1148 if (!Subtarget->hasMFOCRF()) {
1149 // Transform: %cr7 = MTOCRF %r3
1150 // Into: MTCRF mask, %r3 ;; cr7
1151 unsigned NewOpcode =
1152 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1153 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
1154 ->getEncodingValue(MI->getOperand(0).getReg());
1155 OutStreamer->AddComment(PPCInstPrinter::
1156 getRegisterName(MI->getOperand(0).getReg()));
1157 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1159 .addReg(MI->getOperand(1).getReg()));
1167 // Verify alignment is legal, so we don't create relocations
1168 // that can't be supported.
1169 // FIXME: This test is currently disabled for Darwin. The test
1170 // suite shows a handful of test cases that fail this check for
1171 // Darwin. Those need to be investigated before this sanity test
1172 // can be enabled for those subtargets.
1174 unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
1175 const MachineOperand &MO = MI->getOperand(OpNum);
1176 if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4)
1177 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
1179 // Now process the instruction normally.
1184 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, IsDarwin);
1185 EmitToStreamer(*OutStreamer, TmpInst);
1188 void PPCLinuxAsmPrinter::EmitInstruction(const MachineInstr *MI) {
1189 if (!Subtarget->isPPC64())
1190 return PPCAsmPrinter::EmitInstruction(MI);
1192 switch (MI->getOpcode()) {
1194 return PPCAsmPrinter::EmitInstruction(MI);
1195 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1197 // b .end # lis 0, FuncId[16..32]
1198 // nop # li 0, FuncId[0..15]
1201 // bl __xray_FunctionEntry
1205 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1206 // of instructions change.
1207 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1208 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1209 OutStreamer->EmitLabel(BeginOfSled);
1210 EmitToStreamer(*OutStreamer,
1211 MCInstBuilder(PPC::B).addExpr(
1212 MCSymbolRefExpr::create(EndOfSled, OutContext)));
1213 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1216 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1217 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1218 EmitToStreamer(*OutStreamer,
1219 MCInstBuilder(PPC::BL8_NOP)
1220 .addExpr(MCSymbolRefExpr::create(
1221 OutContext.getOrCreateSymbol("__xray_FunctionEntry"),
1223 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1224 OutStreamer->EmitLabel(EndOfSled);
1225 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER);
1228 case TargetOpcode::PATCHABLE_RET: {
1229 unsigned RetOpcode = MI->getOperand(0).getImm();
1231 RetInst.setOpcode(RetOpcode);
1232 for (const auto &MO :
1233 make_range(std::next(MI->operands_begin()), MI->operands_end())) {
1235 if (LowerPPCMachineOperandToMCOperand(MO, MCOp, *this, false))
1236 RetInst.addOperand(MCOp);
1240 if (RetOpcode == PPC::BCCLR) {
1241 IsConditional = true;
1242 } else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1243 RetOpcode == PPC::TCRETURNai8) {
1245 } else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1246 IsConditional = false;
1248 EmitToStreamer(*OutStreamer, RetInst);
1252 MCSymbol *FallthroughLabel;
1253 if (IsConditional) {
1261 // blr # lis 0, FuncId[16..32]
1262 // nop # li 0, FuncId[0..15]
1265 // bl __xray_FunctionExit
1270 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1271 // of instructions change.
1272 FallthroughLabel = OutContext.createTempSymbol();
1275 MCInstBuilder(PPC::BCC)
1276 .addImm(PPC::InvertPredicate(
1277 static_cast<PPC::Predicate>(MI->getOperand(1).getImm())))
1278 .addReg(MI->getOperand(2).getReg())
1279 .addExpr(MCSymbolRefExpr::create(FallthroughLabel, OutContext)));
1281 RetInst.setOpcode(PPC::BLR8);
1285 // b(lr)? # lis 0, FuncId[16..32]
1286 // nop # li 0, FuncId[0..15]
1289 // bl __xray_FunctionExit
1293 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1294 // of instructions change.
1295 OutStreamer->EmitCodeAlignment(8);
1296 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1297 OutStreamer->EmitLabel(BeginOfSled);
1298 EmitToStreamer(*OutStreamer, RetInst);
1299 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1302 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1303 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1304 EmitToStreamer(*OutStreamer,
1305 MCInstBuilder(PPC::BL8_NOP)
1306 .addExpr(MCSymbolRefExpr::create(
1307 OutContext.getOrCreateSymbol("__xray_FunctionExit"),
1309 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1310 EmitToStreamer(*OutStreamer, RetInst);
1312 OutStreamer->EmitLabel(FallthroughLabel);
1313 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT);
1316 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1317 llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted");
1318 case TargetOpcode::PATCHABLE_TAIL_CALL:
1319 // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a
1320 // normal function exit from a tail exit.
1321 llvm_unreachable("Tail call is handled in the normal case. See comments "
1322 "around this assert.");
1326 void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) {
1327 if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) {
1328 PPCTargetStreamer *TS =
1329 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1332 TS->emitAbiVersion(2);
1335 if (static_cast<const PPCTargetMachine &>(TM).isPPC64() ||
1336 !isPositionIndependent())
1337 return AsmPrinter::EmitStartOfAsmFile(M);
1339 if (M.getPICLevel() == PICLevel::SmallPIC)
1340 return AsmPrinter::EmitStartOfAsmFile(M);
1342 OutStreamer->SwitchSection(OutContext.getELFSection(
1343 ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC));
1345 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(".LTOC"));
1346 MCSymbol *CurrentPos = OutContext.createTempSymbol();
1348 OutStreamer->EmitLabel(CurrentPos);
1350 // The GOT pointer points to the middle of the GOT, in order to reference the
1351 // entire 64kB range. 0x8000 is the midpoint.
1352 const MCExpr *tocExpr =
1353 MCBinaryExpr::createAdd(MCSymbolRefExpr::create(CurrentPos, OutContext),
1354 MCConstantExpr::create(0x8000, OutContext),
1357 OutStreamer->EmitAssignment(TOCSym, tocExpr);
1359 OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
1362 void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
1363 // linux/ppc32 - Normal entry label.
1364 if (!Subtarget->isPPC64() &&
1365 (!isPositionIndependent() ||
1366 MF->getFunction().getParent()->getPICLevel() == PICLevel::SmallPIC))
1367 return AsmPrinter::EmitFunctionEntryLabel();
1369 if (!Subtarget->isPPC64()) {
1370 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1371 if (PPCFI->usesPICBase() && !Subtarget->isSecurePlt()) {
1372 MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol();
1373 MCSymbol *PICBase = MF->getPICBaseSymbol();
1374 OutStreamer->EmitLabel(RelocSymbol);
1376 const MCExpr *OffsExpr =
1377 MCBinaryExpr::createSub(
1378 MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")),
1380 MCSymbolRefExpr::create(PICBase, OutContext),
1382 OutStreamer->EmitValue(OffsExpr, 4);
1383 OutStreamer->EmitLabel(CurrentFnSym);
1386 return AsmPrinter::EmitFunctionEntryLabel();
1389 // ELFv2 ABI - Normal entry label.
1390 if (Subtarget->isELFv2ABI()) {
1391 // In the Large code model, we allow arbitrary displacements between
1392 // the text section and its associated TOC section. We place the
1393 // full 8-byte offset to the TOC in memory immediately preceding
1394 // the function global entry point.
1395 if (TM.getCodeModel() == CodeModel::Large
1396 && !MF->getRegInfo().use_empty(PPC::X2)) {
1397 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1399 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1400 MCSymbol *GlobalEPSymbol = PPCFI->getGlobalEPSymbol();
1401 const MCExpr *TOCDeltaExpr =
1402 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1403 MCSymbolRefExpr::create(GlobalEPSymbol,
1407 OutStreamer->EmitLabel(PPCFI->getTOCOffsetSymbol());
1408 OutStreamer->EmitValue(TOCDeltaExpr, 8);
1410 return AsmPrinter::EmitFunctionEntryLabel();
1413 // Emit an official procedure descriptor.
1414 MCSectionSubPair Current = OutStreamer->getCurrentSection();
1415 MCSectionELF *Section = OutStreamer->getContext().getELFSection(
1416 ".opd", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1417 OutStreamer->SwitchSection(Section);
1418 OutStreamer->EmitLabel(CurrentFnSym);
1419 OutStreamer->EmitValueToAlignment(8);
1420 MCSymbol *Symbol1 = CurrentFnSymForSize;
1421 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
1423 OutStreamer->EmitValue(MCSymbolRefExpr::create(Symbol1, OutContext),
1425 MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1426 // Generates a R_PPC64_TOC relocation for TOC base insertion.
1427 OutStreamer->EmitValue(
1428 MCSymbolRefExpr::create(Symbol2, MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext),
1430 // Emit a null environment pointer.
1431 OutStreamer->EmitIntValue(0, 8 /* size */);
1432 OutStreamer->SwitchSection(Current.first, Current.second);
1435 bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
1436 const DataLayout &DL = getDataLayout();
1438 bool isPPC64 = DL.getPointerSizeInBits() == 64;
1440 PPCTargetStreamer &TS =
1441 static_cast<PPCTargetStreamer &>(*OutStreamer->getTargetStreamer());
1444 MCSectionELF *Section;
1447 Section = OutStreamer->getContext().getELFSection(
1448 ".toc", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1450 Section = OutStreamer->getContext().getELFSection(
1451 ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1452 OutStreamer->SwitchSection(Section);
1454 for (const auto &TOCMapPair : TOC) {
1455 const MCSymbol *const TOCEntryTarget = TOCMapPair.first;
1456 MCSymbol *const TOCEntryLabel = TOCMapPair.second;
1458 OutStreamer->EmitLabel(TOCEntryLabel);
1460 TS.emitTCEntry(*TOCEntryTarget);
1462 OutStreamer->EmitValueToAlignment(4);
1463 OutStreamer->EmitSymbolValue(TOCEntryTarget, 4);
1468 return AsmPrinter::doFinalization(M);
1471 /// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2.
1472 void PPCLinuxAsmPrinter::EmitFunctionBodyStart() {
1473 // In the ELFv2 ABI, in functions that use the TOC register, we need to
1474 // provide two entry points. The ABI guarantees that when calling the
1475 // local entry point, r2 is set up by the caller to contain the TOC base
1476 // for this function, and when calling the global entry point, r12 is set
1477 // up by the caller to hold the address of the global entry point. We
1478 // thus emit a prefix sequence along the following lines:
1482 // # global entry point
1483 // addis r2,r12,(.TOC.-.Lfunc_gepNN)@ha
1484 // addi r2,r2,(.TOC.-.Lfunc_gepNN)@l
1486 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1487 // # local entry point, followed by function body
1489 // For the Large code model, we create
1492 // .quad .TOC.-.Lfunc_gepNN # done by EmitFunctionEntryLabel
1495 // # global entry point
1496 // ld r2,.Lfunc_tocNN-.Lfunc_gepNN(r12)
1499 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1500 // # local entry point, followed by function body
1502 // This ensures we have r2 set up correctly while executing the function
1503 // body, no matter which entry point is called.
1504 if (Subtarget->isELFv2ABI()
1505 // Only do all that if the function uses r2 in the first place.
1506 && !MF->getRegInfo().use_empty(PPC::X2)) {
1507 // Note: The logic here must be synchronized with the code in the
1508 // branch-selection pass which sets the offset of the first block in the
1509 // function. This matters because it affects the alignment.
1510 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1512 MCSymbol *GlobalEntryLabel = PPCFI->getGlobalEPSymbol();
1513 OutStreamer->EmitLabel(GlobalEntryLabel);
1514 const MCSymbolRefExpr *GlobalEntryLabelExp =
1515 MCSymbolRefExpr::create(GlobalEntryLabel, OutContext);
1517 if (TM.getCodeModel() != CodeModel::Large) {
1518 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1519 const MCExpr *TOCDeltaExpr =
1520 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1521 GlobalEntryLabelExp, OutContext);
1523 const MCExpr *TOCDeltaHi =
1524 PPCMCExpr::createHa(TOCDeltaExpr, false, OutContext);
1525 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
1528 .addExpr(TOCDeltaHi));
1530 const MCExpr *TOCDeltaLo =
1531 PPCMCExpr::createLo(TOCDeltaExpr, false, OutContext);
1532 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
1535 .addExpr(TOCDeltaLo));
1537 MCSymbol *TOCOffset = PPCFI->getTOCOffsetSymbol();
1538 const MCExpr *TOCOffsetDeltaExpr =
1539 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCOffset, OutContext),
1540 GlobalEntryLabelExp, OutContext);
1542 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
1544 .addExpr(TOCOffsetDeltaExpr)
1546 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8)
1552 MCSymbol *LocalEntryLabel = PPCFI->getLocalEPSymbol();
1553 OutStreamer->EmitLabel(LocalEntryLabel);
1554 const MCSymbolRefExpr *LocalEntryLabelExp =
1555 MCSymbolRefExpr::create(LocalEntryLabel, OutContext);
1556 const MCExpr *LocalOffsetExp =
1557 MCBinaryExpr::createSub(LocalEntryLabelExp,
1558 GlobalEntryLabelExp, OutContext);
1560 PPCTargetStreamer *TS =
1561 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1564 TS->emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), LocalOffsetExp);
1568 /// EmitFunctionBodyEnd - Print the traceback table before the .size
1571 void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
1572 // Only the 64-bit target requires a traceback table. For now,
1573 // we only emit the word of zeroes that GDB requires to find
1574 // the end of the function, and zeroes for the eight-byte
1575 // mandatory fields.
1576 // FIXME: We should fill in the eight-byte mandatory fields as described in
1577 // the PPC64 ELF ABI (this is a low-priority item because GDB does not
1578 // currently make use of these fields).
1579 if (Subtarget->isPPC64()) {
1580 OutStreamer->EmitIntValue(0, 4/*size*/);
1581 OutStreamer->EmitIntValue(0, 8/*size*/);
1585 void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
1586 // Get the function descriptor symbol.
1587 CurrentFnDescSym = getSymbol(&MF.getFunction());
1588 // Set the containing csect.
1589 MCSectionXCOFF *FnDescSec = OutStreamer->getContext().getXCOFFSection(
1590 CurrentFnDescSym->getName(), XCOFF::XMC_DS, XCOFF::XTY_SD,
1591 XCOFF::C_HIDEXT, SectionKind::getData());
1592 cast<MCSymbolXCOFF>(CurrentFnDescSym)->setContainingCsect(FnDescSec);
1594 return AsmPrinter::SetupMachineFunction(MF);
1597 void PPCAIXAsmPrinter::ValidateGV(const GlobalVariable *GV) {
1598 // Early error checking limiting what is supported.
1599 if (GV->isThreadLocal())
1600 report_fatal_error("Thread local not yet supported on AIX.");
1602 if (GV->hasSection())
1603 report_fatal_error("Custom section for Data not yet supported.");
1605 if (GV->hasComdat())
1606 report_fatal_error("COMDAT not yet supported by AIX.");
1609 const MCExpr *PPCAIXAsmPrinter::lowerConstant(const Constant *CV) {
1610 if (const Function *F = dyn_cast<Function>(CV)) {
1611 MCSymbolXCOFF *FSym = cast<MCSymbolXCOFF>(getSymbol(F));
1612 if (!FSym->hasContainingCsect()) {
1613 const XCOFF::StorageClass SC =
1615 ? TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(F)
1617 MCSectionXCOFF *Csect = OutStreamer->getContext().getXCOFFSection(
1618 FSym->getName(), XCOFF::XMC_DS,
1619 F->isDeclaration() ? XCOFF::XTY_ER : XCOFF::XTY_SD, SC,
1620 SectionKind::getData());
1621 FSym->setContainingCsect(Csect);
1623 return MCSymbolRefExpr::create(
1624 FSym->getContainingCsect()->getQualNameSymbol(), OutContext);
1626 return PPCAsmPrinter::lowerConstant(CV);
1629 void PPCAIXAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
1632 // External global variables are already handled.
1633 if (!GV->hasInitializer())
1636 // Create the symbol, set its storage class.
1637 MCSymbolXCOFF *GVSym = cast<MCSymbolXCOFF>(getSymbol(GV));
1638 GVSym->setStorageClass(
1639 TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV));
1641 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
1642 if ((!GVKind.isGlobalWriteableData() && !GVKind.isReadOnly()) ||
1643 GVKind.isMergeable2ByteCString() || GVKind.isMergeable4ByteCString())
1644 report_fatal_error("Encountered a global variable kind that is "
1645 "not supported yet.");
1647 // Create the containing csect and switch to it.
1648 MCSectionXCOFF *Csect = cast<MCSectionXCOFF>(
1649 getObjFileLowering().SectionForGlobal(GV, GVKind, TM));
1650 OutStreamer->SwitchSection(Csect);
1651 GVSym->setContainingCsect(Csect);
1653 const DataLayout &DL = GV->getParent()->getDataLayout();
1655 // Handle common symbols.
1656 if (GVKind.isCommon() || GVKind.isBSSLocal()) {
1658 GV->getAlignment() ? GV->getAlignment() : DL.getPreferredAlignment(GV);
1659 uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType());
1661 if (GVKind.isBSSLocal())
1662 OutStreamer->EmitXCOFFLocalCommonSymbol(
1663 GVSym, Size, Csect->getQualNameSymbol(), Align);
1665 OutStreamer->EmitCommonSymbol(Csect->getQualNameSymbol(), Size, Align);
1669 MCSymbol *EmittedInitSym = GVSym;
1670 EmitLinkage(GV, EmittedInitSym);
1671 EmitAlignment(getGVAlignment(GV, DL), GV);
1672 OutStreamer->EmitLabel(EmittedInitSym);
1673 EmitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());
1676 void PPCAIXAsmPrinter::EmitFunctionDescriptor() {
1677 const DataLayout &DL = getDataLayout();
1678 const unsigned PointerSize = DL.getPointerSizeInBits() == 64 ? 8 : 4;
1680 MCSectionSubPair Current = OutStreamer->getCurrentSection();
1681 // Emit function descriptor.
1682 OutStreamer->SwitchSection(
1683 cast<MCSymbolXCOFF>(CurrentFnDescSym)->getContainingCsect());
1684 OutStreamer->EmitLabel(CurrentFnDescSym);
1685 // Emit function entry point address.
1686 OutStreamer->EmitValue(MCSymbolRefExpr::create(CurrentFnSym, OutContext),
1688 // Emit TOC base address.
1689 const MCSectionXCOFF *TOCBaseSec = OutStreamer->getContext().getXCOFFSection(
1690 StringRef("TOC"), XCOFF::XMC_TC0, XCOFF::XTY_SD, XCOFF::C_HIDEXT,
1691 SectionKind::getData());
1692 const MCSymbol *TOCBaseSym = TOCBaseSec->getQualNameSymbol();
1693 OutStreamer->EmitValue(MCSymbolRefExpr::create(TOCBaseSym, OutContext),
1695 // Emit a null environment pointer.
1696 OutStreamer->EmitIntValue(0, PointerSize);
1698 OutStreamer->SwitchSection(Current.first, Current.second);
1701 void PPCAIXAsmPrinter::EmitEndOfAsmFile(Module &M) {
1702 // If there are no functions in this module, we will never need to reference
1708 MCSectionXCOFF *TOCBaseSection = OutStreamer->getContext().getXCOFFSection(
1709 StringRef("TOC"), XCOFF::XMC_TC0, XCOFF::XTY_SD, XCOFF::C_HIDEXT,
1710 SectionKind::getData());
1711 // The TOC-base always has 0 size, but 4 byte alignment.
1712 TOCBaseSection->setAlignment(Align(4));
1713 // Switch to section to emit TOC base.
1714 OutStreamer->SwitchSection(TOCBaseSection);
1716 PPCTargetStreamer &TS =
1717 static_cast<PPCTargetStreamer &>(*OutStreamer->getTargetStreamer());
1719 for (auto &I : TOC) {
1720 // Setup the csect for the current TC entry.
1721 MCSectionXCOFF *TCEntry = OutStreamer->getContext().getXCOFFSection(
1722 cast<MCSymbolXCOFF>(I.first)->getUnqualifiedName(), XCOFF::XMC_TC,
1723 XCOFF::XTY_SD, XCOFF::C_HIDEXT, SectionKind::getData());
1724 cast<MCSymbolXCOFF>(I.second)->setContainingCsect(TCEntry);
1725 OutStreamer->SwitchSection(TCEntry);
1727 OutStreamer->EmitLabel(I.second);
1728 TS.emitTCEntry(*I.first);
1733 PPCAIXAsmPrinter::getMCSymbolForTOCPseudoMO(const MachineOperand &MO) {
1734 const GlobalObject *GO = nullptr;
1736 // If the MO is a function or certain kind of globals, we want to make sure to
1737 // refer to the csect symbol, otherwise we can just do the default handling.
1738 if (MO.getType() != MachineOperand::MO_GlobalAddress ||
1739 !(GO = dyn_cast<const GlobalObject>(MO.getGlobal())))
1740 return PPCAsmPrinter::getMCSymbolForTOCPseudoMO(MO);
1742 // Do an early error check for globals we don't support. This will go away
1744 const auto *GV = dyn_cast<const GlobalVariable>(GO);
1749 MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(getSymbol(GO));
1751 // If the global object is a global variable without initializer or is a
1752 // declaration of a function, then XSym is an external referenced symbol.
1753 // Hence we may need to explictly create a MCSectionXCOFF for it so that we
1754 // can return its symbol later.
1755 if (GO->isDeclaration()) {
1756 if (!XSym->hasContainingCsect()) {
1757 // Make sure the storage class is set.
1758 const XCOFF::StorageClass SC =
1759 TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GO);
1760 XSym->setStorageClass(SC);
1762 MCSectionXCOFF *Csect = OutStreamer->getContext().getXCOFFSection(
1763 XSym->getName(), isa<Function>(GO) ? XCOFF::XMC_DS : XCOFF::XMC_UA,
1764 XCOFF::XTY_ER, SC, SectionKind::getMetadata());
1765 XSym->setContainingCsect(Csect);
1768 return XSym->getContainingCsect()->getQualNameSymbol();
1771 // Handle initialized global variables and defined functions.
1772 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);
1774 if (GOKind.isText()) {
1775 // If the MO is a function, we want to make sure to refer to the function
1776 // descriptor csect.
1777 return OutStreamer->getContext()
1778 .getXCOFFSection(XSym->getName(), XCOFF::XMC_DS, XCOFF::XTY_SD,
1779 XCOFF::C_HIDEXT, SectionKind::getData())
1780 ->getQualNameSymbol();
1781 } else if (GOKind.isCommon() || GOKind.isBSSLocal()) {
1782 // If the operand is a common then we should refer to the csect symbol.
1783 return cast<MCSectionXCOFF>(
1784 getObjFileLowering().SectionForGlobal(GO, GOKind, TM))
1785 ->getQualNameSymbol();
1788 // Other global variables are refered to by labels inside of a single csect,
1789 // so refer to the label directly.
1790 return getSymbol(GV);
1793 /// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
1794 /// for a MachineFunction to the given output stream, in a format that the
1795 /// Darwin assembler can deal with.
1798 createPPCAsmPrinterPass(TargetMachine &tm,
1799 std::unique_ptr<MCStreamer> &&Streamer) {
1800 if (tm.getTargetTriple().isOSAIX())
1801 return new PPCAIXAsmPrinter(tm, std::move(Streamer));
1803 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
1806 // Force static initialization.
1807 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter() {
1808 TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
1809 createPPCAsmPrinterPass);
1810 TargetRegistry::RegisterAsmPrinter(getThePPC64Target(),
1811 createPPCAsmPrinterPass);
1812 TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(),
1813 createPPCAsmPrinterPass);