LLVM 23.0.0git
PPCAsmPrinter.cpp
Go to the documentation of this file.
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'.
12//
13// Documentation at http://developer.apple.com/documentation/DeveloperTools/
14// Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
15//
16//===----------------------------------------------------------------------===//
17
23#include "PPC.h"
24#include "PPCInstrInfo.h"
26#include "PPCSubtarget.h"
27#include "PPCTargetMachine.h"
29#include "llvm/ADT/MapVector.h"
30#include "llvm/ADT/SetVector.h"
31#include "llvm/ADT/Statistic.h"
33#include "llvm/ADT/StringRef.h"
34#include "llvm/ADT/Twine.h"
46#include "llvm/IR/DataLayout.h"
47#include "llvm/IR/GlobalValue.h"
49#include "llvm/IR/Module.h"
50#include "llvm/MC/MCAsmInfo.h"
51#include "llvm/MC/MCContext.h"
53#include "llvm/MC/MCExpr.h"
54#include "llvm/MC/MCInst.h"
58#include "llvm/MC/MCStreamer.h"
59#include "llvm/MC/MCSymbol.h"
60#include "llvm/MC/MCSymbolELF.h"
62#include "llvm/MC/SectionKind.h"
67#include "llvm/Support/Debug.h"
68#include "llvm/Support/Error.h"
78#include <cassert>
79#include <cstdint>
80#include <memory>
81#include <new>
82
83using namespace llvm;
84using namespace llvm::XCOFF;
85
86#define DEBUG_TYPE "asmprinter"
87
88STATISTIC(NumTOCEntries, "Number of Total TOC Entries Emitted.");
89STATISTIC(NumTOCConstPool, "Number of Constant Pool TOC Entries.");
90STATISTIC(NumTOCGlobalInternal,
91 "Number of Internal Linkage Global TOC Entries.");
92STATISTIC(NumTOCGlobalExternal,
93 "Number of External Linkage Global TOC Entries.");
94STATISTIC(NumTOCJumpTable, "Number of Jump Table TOC Entries.");
95STATISTIC(NumTOCThreadLocal, "Number of Thread Local TOC Entries.");
96STATISTIC(NumTOCBlockAddress, "Number of Block Address TOC Entries.");
97STATISTIC(NumTOCEHBlock, "Number of EH Block TOC Entries.");
98
100 "aix-ssp-tb-bit", cl::init(false),
101 cl::desc("Enable Passing SSP Canary info in Trackback on AIX"), cl::Hidden);
102
103// Specialize DenseMapInfo to allow
104// std::pair<const MCSymbol *, PPCMCExpr::Specifier> in DenseMap.
105// This specialization is needed here because that type is used as keys in the
106// map representing TOC entries.
107namespace llvm {
108template <>
109struct DenseMapInfo<std::pair<const MCSymbol *, PPCMCExpr::Specifier>> {
110 using TOCKey = std::pair<const MCSymbol *, PPCMCExpr::Specifier>;
111
112 static inline TOCKey getEmptyKey() { return {nullptr, PPC::S_None}; }
113 static inline TOCKey getTombstoneKey() {
114 return {(const MCSymbol *)1, PPC::S_None};
115 }
116 static unsigned getHashValue(const TOCKey &PairVal) {
119 DenseMapInfo<int>::getHashValue(PairVal.second));
120 }
121 static bool isEqual(const TOCKey &A, const TOCKey &B) { return A == B; }
122};
123} // end namespace llvm
124
125namespace {
126
127enum {
128 // GNU attribute tags for PowerPC ABI
129 Tag_GNU_Power_ABI_FP = 4,
130 Tag_GNU_Power_ABI_Vector = 8,
131 Tag_GNU_Power_ABI_Struct_Return = 12,
132
133 // GNU attribute values for PowerPC float ABI, as combination of two parts
134 Val_GNU_Power_ABI_NoFloat = 0b00,
135 Val_GNU_Power_ABI_HardFloat_DP = 0b01,
136 Val_GNU_Power_ABI_SoftFloat_DP = 0b10,
137 Val_GNU_Power_ABI_HardFloat_SP = 0b11,
138
139 Val_GNU_Power_ABI_LDBL_IBM128 = 0b0100,
140 Val_GNU_Power_ABI_LDBL_64 = 0b1000,
141 Val_GNU_Power_ABI_LDBL_IEEE128 = 0b1100,
142};
143
144class PPCAsmPrinter : public AsmPrinter {
145protected:
146 // For TLS on AIX, we need to be able to identify TOC entries of specific
147 // specifier so we can add the right relocations when we generate the
148 // entries. So each entry is represented by a pair of MCSymbol and
149 // VariantKind. For example, we need to be able to identify the following
150 // entry as a TLSGD entry so we can add the @m relocation:
151 // .tc .i[TC],i[TL]@m
152 // By default, 0 is used for the specifier.
153 MapVector<std::pair<const MCSymbol *, PPCMCExpr::Specifier>, MCSymbol *> TOC;
154 const PPCSubtarget *Subtarget = nullptr;
155
156 // Keep track of the number of TLS variables and their corresponding
157 // addresses, which is then used for the assembly printing of
158 // non-TOC-based local-exec variables.
159 MapVector<const GlobalValue *, uint64_t> TLSVarsToAddressMapping;
160
161public:
162 explicit PPCAsmPrinter(TargetMachine &TM,
163 std::unique_ptr<MCStreamer> Streamer, char &ID)
164 : AsmPrinter(TM, std::move(Streamer), ID) {}
165
166 StringRef getPassName() const override { return "PowerPC Assembly Printer"; }
167
168 enum TOCEntryType {
169 TOCType_ConstantPool,
170 TOCType_GlobalExternal,
171 TOCType_GlobalInternal,
172 TOCType_JumpTable,
173 TOCType_ThreadLocal,
174 TOCType_BlockAddress,
175 TOCType_EHBlock
176 };
177
178 MCSymbol *lookUpOrCreateTOCEntry(const MCSymbol *Sym, TOCEntryType Type,
180
181 bool doInitialization(Module &M) override {
182 if (!TOC.empty())
183 TOC.clear();
185 }
186
187 const MCExpr *symbolWithSpecifier(const MCSymbol *S,
189 void emitInstruction(const MachineInstr *MI) override;
190
191 /// This function is for PrintAsmOperand and PrintAsmMemoryOperand,
192 /// invoked by EmitMSInlineAsmStr and EmitGCCInlineAsmStr only.
193 /// The \p MI would be INLINEASM ONLY.
194 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
195
196 void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
197 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
198 const char *ExtraCode, raw_ostream &O) override;
199 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
200 const char *ExtraCode, raw_ostream &O) override;
201
202 void LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI);
203 void LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI);
204 void emitTlsCall(const MachineInstr *MI, PPCMCExpr::Specifier VK);
205 void EmitAIXTlsCallHelper(const MachineInstr *MI);
206 const MCExpr *getAdjustedFasterLocalExpr(const MachineOperand &MO,
207 int64_t Offset);
208 bool runOnMachineFunction(MachineFunction &MF) override {
209 Subtarget = &MF.getSubtarget<PPCSubtarget>();
211 emitXRayTable();
212 return Changed;
213 }
214};
215
216/// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
217class PPCLinuxAsmPrinter : public PPCAsmPrinter {
218public:
219 static char ID;
220
221 explicit PPCLinuxAsmPrinter(TargetMachine &TM,
222 std::unique_ptr<MCStreamer> Streamer)
223 : PPCAsmPrinter(TM, std::move(Streamer), ID) {}
224
225 StringRef getPassName() const override {
226 return "Linux PPC Assembly Printer";
227 }
228
229 void emitGNUAttributes(Module &M);
230
231 void emitStartOfAsmFile(Module &M) override;
232 void emitEndOfAsmFile(Module &) override;
233
234 void emitFunctionEntryLabel() override;
235
236 void emitFunctionBodyStart() override;
237 void emitFunctionBodyEnd() override;
238 void emitInstruction(const MachineInstr *MI) override;
239};
240
241class PPCAIXAsmPrinter : public PPCAsmPrinter {
242private:
243 /// Symbols lowered from ExternalSymbolSDNodes, we will need to emit extern
244 /// linkage for them in AIX.
245 SmallSetVector<MCSymbol *, 8> ExtSymSDNodeSymbols;
246
247 /// A format indicator and unique trailing identifier to form part of the
248 /// sinit/sterm function names.
249 std::string FormatIndicatorAndUniqueModId;
250
251 // Record a list of GlobalAlias associated with a GlobalObject.
252 // This is used for AIX's extra-label-at-definition aliasing strategy.
253 DenseMap<const GlobalObject *, SmallVector<const GlobalAlias *, 1>>
254 GOAliasMap;
255
256 uint16_t getNumberOfVRSaved();
257 void emitTracebackTable();
258
260
261 void emitGlobalVariableHelper(const GlobalVariable *);
262
263 // Get the offset of an alias based on its AliaseeObject.
264 uint64_t getAliasOffset(const Constant *C);
265
266public:
267 static char ID;
268
269 PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
270 : PPCAsmPrinter(TM, std::move(Streamer), ID) {
271 if (MAI->isLittleEndian())
273 "cannot create AIX PPC Assembly Printer for a little-endian target");
274 }
275
276 StringRef getPassName() const override { return "AIX PPC Assembly Printer"; }
277
278 bool doInitialization(Module &M) override;
279
280 void emitXXStructorList(const DataLayout &DL, const Constant *List,
281 bool IsCtor) override;
282
283 void SetupMachineFunction(MachineFunction &MF) override;
284
285 void emitGlobalVariable(const GlobalVariable *GV) override;
286
287 void emitFunctionDescriptor() override;
288
289 void emitFunctionEntryLabel() override;
290
291 void emitFunctionBodyEnd() override;
292
293 void emitPGORefs(Module &M);
294
295 void emitGCOVRefs();
296
297 void emitEndOfAsmFile(Module &) override;
298
299 void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const override;
300
301 void emitInstruction(const MachineInstr *MI) override;
302
303 bool doFinalization(Module &M) override;
304
305 void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
306
307 void emitModuleCommandLines(Module &M) override;
308
309 void emitRefMetadata(const GlobalObject *);
310};
311
312} // end anonymous namespace
313
314void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
315 raw_ostream &O) {
316 // Computing the address of a global symbol, not calling it.
317 const GlobalValue *GV = MO.getGlobal();
318 getSymbol(GV)->print(O, MAI);
319 printOffset(MO.getOffset(), O);
320}
321
322void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
323 raw_ostream &O) {
324 const DataLayout &DL = getDataLayout();
325 const MachineOperand &MO = MI->getOperand(OpNo);
326
327 switch (MO.getType()) {
329 // The MI is INLINEASM ONLY and UseVSXReg is always false.
331
332 // Linux assembler (Others?) does not take register mnemonics.
333 // FIXME - What about special registers used in mfspr/mtspr?
335 return;
336 }
338 O << MO.getImm();
339 return;
340
342 MO.getMBB()->getSymbol()->print(O, MAI);
343 return;
345 O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
346 << MO.getIndex();
347 return;
349 GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
350 return;
352 PrintSymbolOperand(MO, O);
353 return;
354 }
355
356 default:
357 O << "<unknown operand type: " << (unsigned)MO.getType() << ">";
358 return;
359 }
360}
361
362/// PrintAsmOperand - Print out an operand for an inline asm expression.
363///
364bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
365 const char *ExtraCode, raw_ostream &O) {
366 // Does this asm operand have a single letter operand modifier?
367 if (ExtraCode && ExtraCode[0]) {
368 if (ExtraCode[1] != 0) return true; // Unknown modifier.
369
370 switch (ExtraCode[0]) {
371 default:
372 // See if this is a generic print operand
373 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
374 case 'L': // Write second word of DImode reference.
375 // Verify that this operand has two consecutive registers.
376 if (!MI->getOperand(OpNo).isReg() ||
377 OpNo+1 == MI->getNumOperands() ||
378 !MI->getOperand(OpNo+1).isReg())
379 return true;
380 ++OpNo; // Return the high-part.
381 break;
382 case 'I':
383 // Write 'i' if an integer constant, otherwise nothing. Used to print
384 // addi vs add, etc.
385 if (MI->getOperand(OpNo).isImm())
386 O << "i";
387 return false;
388 case 'x':
389 if(!MI->getOperand(OpNo).isReg())
390 return true;
391 // This operand uses VSX numbering.
392 // If the operand is a VMX register, convert it to a VSX register.
393 Register Reg = MI->getOperand(OpNo).getReg();
395 Reg = PPC::VSX32 + (Reg - PPC::V0);
396 else if (PPC::isVFRegister(Reg))
397 Reg = PPC::VSX32 + (Reg - PPC::VF0);
398 const char *RegName;
401 O << RegName;
402 return false;
403 }
404 }
405
406 printOperand(MI, OpNo, O);
407 return false;
408}
409
410// At the moment, all inline asm memory operands are a single register.
411// In any case, the output of this routine should always be just one
412// assembler operand.
413bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
414 const char *ExtraCode,
415 raw_ostream &O) {
416 if (ExtraCode && ExtraCode[0]) {
417 if (ExtraCode[1] != 0) return true; // Unknown modifier.
418
419 switch (ExtraCode[0]) {
420 default: return true; // Unknown modifier.
421 case 'L': // A memory reference to the upper word of a double word op.
422 O << getDataLayout().getPointerSize() << "(";
423 printOperand(MI, OpNo, O);
424 O << ")";
425 return false;
426 case 'y': // A memory reference for an X-form instruction
427 O << "0, ";
428 printOperand(MI, OpNo, O);
429 return false;
430 case 'I':
431 // Write 'i' if an integer constant, otherwise nothing. Used to print
432 // addi vs add, etc.
433 if (MI->getOperand(OpNo).isImm())
434 O << "i";
435 return false;
436 case 'U': // Print 'u' for update form.
437 case 'X': // Print 'x' for indexed form.
438 // FIXME: Currently for PowerPC memory operands are always loaded
439 // into a register, so we never get an update or indexed form.
440 // This is bad even for offset forms, since even if we know we
441 // have a value in -16(r1), we will generate a load into r<n>
442 // and then load from 0(r<n>). Until that issue is fixed,
443 // tolerate 'U' and 'X' but don't output anything.
444 assert(MI->getOperand(OpNo).isReg());
445 return false;
446 }
447 }
448
449 assert(MI->getOperand(OpNo).isReg());
450 O << "0(";
451 printOperand(MI, OpNo, O);
452 O << ")";
453 return false;
454}
455
456static void collectTOCStats(PPCAsmPrinter::TOCEntryType Type) {
457 ++NumTOCEntries;
458 switch (Type) {
459 case PPCAsmPrinter::TOCType_ConstantPool:
460 ++NumTOCConstPool;
461 break;
462 case PPCAsmPrinter::TOCType_GlobalInternal:
463 ++NumTOCGlobalInternal;
464 break;
465 case PPCAsmPrinter::TOCType_GlobalExternal:
466 ++NumTOCGlobalExternal;
467 break;
468 case PPCAsmPrinter::TOCType_JumpTable:
469 ++NumTOCJumpTable;
470 break;
471 case PPCAsmPrinter::TOCType_ThreadLocal:
472 ++NumTOCThreadLocal;
473 break;
474 case PPCAsmPrinter::TOCType_BlockAddress:
475 ++NumTOCBlockAddress;
476 break;
477 case PPCAsmPrinter::TOCType_EHBlock:
478 ++NumTOCEHBlock;
479 break;
480 }
481}
482
484 const TargetMachine &TM,
485 const MachineOperand &MO) {
486 CodeModel::Model ModuleModel = TM.getCodeModel();
487
488 // If the operand is not a global address then there is no
489 // global variable to carry an attribute.
491 return ModuleModel;
492
493 const GlobalValue *GV = MO.getGlobal();
494 assert(GV && "expected global for MO_GlobalAddress");
495
496 return S.getCodeModel(TM, GV);
497}
498
500 switch (CM) {
501 case CodeModel::Large:
503 return;
504 case CodeModel::Small:
506 return;
507 default:
508 report_fatal_error("Invalid code model for AIX");
509 }
510}
511
512/// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
513/// exists for it. If not, create one. Then return a symbol that references
514/// the TOC entry.
515MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(const MCSymbol *Sym,
516 TOCEntryType Type,
518 // If this is a new TOC entry add statistics about it.
519 auto [It, Inserted] = TOC.try_emplace({Sym, Spec});
520 if (Inserted)
522
523 MCSymbol *&TOCEntry = It->second;
524 if (!TOCEntry)
525 TOCEntry = createTempSymbol("C");
526 return TOCEntry;
527}
528
529void PPCAsmPrinter::LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI) {
530 unsigned NumNOPBytes = MI.getOperand(1).getImm();
531
532 auto &Ctx = OutStreamer->getContext();
533 MCSymbol *MILabel = Ctx.createTempSymbol();
534 OutStreamer->emitLabel(MILabel);
535
536 SM.recordStackMap(*MILabel, MI);
537 assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
538
539 // Scan ahead to trim the shadow.
540 const MachineBasicBlock &MBB = *MI.getParent();
542 ++MII;
543 while (NumNOPBytes > 0) {
544 if (MII == MBB.end() || MII->isCall() ||
545 MII->getOpcode() == PPC::DBG_VALUE ||
546 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
547 MII->getOpcode() == TargetOpcode::STACKMAP)
548 break;
549 ++MII;
550 NumNOPBytes -= 4;
551 }
552
553 // Emit nops.
554 for (unsigned i = 0; i < NumNOPBytes; i += 4)
555 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
556}
557
558// Lower a patchpoint of the form:
559// [<def>], <id>, <numBytes>, <target>, <numArgs>
560void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) {
561 auto &Ctx = OutStreamer->getContext();
562 MCSymbol *MILabel = Ctx.createTempSymbol();
563 OutStreamer->emitLabel(MILabel);
564
565 SM.recordPatchPoint(*MILabel, MI);
566 PatchPointOpers Opers(&MI);
567
568 unsigned EncodedBytes = 0;
569 const MachineOperand &CalleeMO = Opers.getCallTarget();
570
571 if (CalleeMO.isImm()) {
572 int64_t CallTarget = CalleeMO.getImm();
573 if (CallTarget) {
574 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
575 "High 16 bits of call target should be zero.");
576 Register ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
577 EncodedBytes = 0;
578 // Materialize the jump address:
579 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8)
580 .addReg(ScratchReg)
581 .addImm((CallTarget >> 32) & 0xFFFF));
582 ++EncodedBytes;
583 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC)
584 .addReg(ScratchReg)
585 .addReg(ScratchReg)
586 .addImm(32).addImm(16));
587 ++EncodedBytes;
588 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8)
589 .addReg(ScratchReg)
590 .addReg(ScratchReg)
591 .addImm((CallTarget >> 16) & 0xFFFF));
592 ++EncodedBytes;
593 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8)
594 .addReg(ScratchReg)
595 .addReg(ScratchReg)
596 .addImm(CallTarget & 0xFFFF));
597
598 // Save the current TOC pointer before the remote call.
599 int TOCSaveOffset = Subtarget->getFrameLowering()->getTOCSaveOffset();
600 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD)
601 .addReg(PPC::X2)
602 .addImm(TOCSaveOffset)
603 .addReg(PPC::X1));
604 ++EncodedBytes;
605
606 // If we're on ELFv1, then we need to load the actual function pointer
607 // from the function descriptor.
608 if (!Subtarget->isELFv2ABI()) {
609 // Load the new TOC pointer and the function address, but not r11
610 // (needing this is rare, and loading it here would prevent passing it
611 // via a 'nest' parameter.
612 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
613 .addReg(PPC::X2)
614 .addImm(8)
615 .addReg(ScratchReg));
616 ++EncodedBytes;
617 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
618 .addReg(ScratchReg)
619 .addImm(0)
620 .addReg(ScratchReg));
621 ++EncodedBytes;
622 }
623
624 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8)
625 .addReg(ScratchReg));
626 ++EncodedBytes;
627 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8));
628 ++EncodedBytes;
629
630 // Restore the TOC pointer after the call.
631 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
632 .addReg(PPC::X2)
633 .addImm(TOCSaveOffset)
634 .addReg(PPC::X1));
635 ++EncodedBytes;
636 }
637 } else if (CalleeMO.isGlobal()) {
638 const GlobalValue *GValue = CalleeMO.getGlobal();
639 MCSymbol *MOSymbol = getSymbol(GValue);
640 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, OutContext);
641
642 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP)
643 .addExpr(SymVar));
644 EncodedBytes += 2;
645 }
646
647 // Each instruction is 4 bytes.
648 EncodedBytes *= 4;
649
650 // Emit padding.
651 unsigned NumBytes = Opers.getNumPatchBytes();
652 assert(NumBytes >= EncodedBytes &&
653 "Patchpoint can't request size less than the length of a call.");
654 assert((NumBytes - EncodedBytes) % 4 == 0 &&
655 "Invalid number of NOP bytes requested!");
656 for (unsigned i = EncodedBytes; i < NumBytes; i += 4)
657 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
658}
659
660/// This helper function creates the TlsGetAddr/TlsGetMod MCSymbol for AIX. We
661/// will create the csect and use the qual-name symbol instead of creating just
662/// the external symbol.
663static MCSymbol *createMCSymbolForTlsGetAddr(MCContext &Ctx, unsigned MIOpc) {
664 StringRef SymName;
665 switch (MIOpc) {
666 default:
667 SymName = ".__tls_get_addr";
668 break;
669 case PPC::GETtlsTpointer32AIX:
670 SymName = ".__get_tpointer";
671 break;
672 case PPC::GETtlsMOD32AIX:
673 case PPC::GETtlsMOD64AIX:
674 SymName = ".__tls_get_mod";
675 break;
676 }
677 return Ctx
678 .getXCOFFSection(SymName, SectionKind::getText(),
680 ->getQualNameSymbol();
681}
682
683void PPCAsmPrinter::EmitAIXTlsCallHelper(const MachineInstr *MI) {
684 assert(Subtarget->isAIXABI() &&
685 "Only expecting to emit calls to get the thread pointer on AIX!");
686
687 MCSymbol *TlsCall = createMCSymbolForTlsGetAddr(OutContext, MI->getOpcode());
688 const MCExpr *TlsRef = MCSymbolRefExpr::create(TlsCall, OutContext);
689 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BLA).addExpr(TlsRef));
690}
691
692/// Given a GETtls[ld]ADDR[32] instruction, print a call to __tls_get_addr to
693/// the current output stream.
694void PPCAsmPrinter::emitTlsCall(const MachineInstr *MI,
697 unsigned Opcode = PPC::BL8_NOP_TLS;
698
699 assert(MI->getNumOperands() >= 3 && "Expecting at least 3 operands from MI");
700 if (MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG ||
701 MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSLD_PCREL_FLAG) {
703 Opcode = PPC::BL8_NOTOC_TLS;
704 }
705 const Module *M = MF->getFunction().getParent();
706
707 assert(MI->getOperand(0).isReg() &&
708 ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) ||
709 (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) &&
710 "GETtls[ld]ADDR[32] must define GPR3");
711 assert(MI->getOperand(1).isReg() &&
712 ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) ||
713 (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) &&
714 "GETtls[ld]ADDR[32] must read GPR3");
715
716 if (Subtarget->isAIXABI()) {
717 // For TLSGD, the variable offset should already be in R4 and the region
718 // handle should already be in R3. We generate an absolute branch to
719 // .__tls_get_addr. For TLSLD, the module handle should already be in R3.
720 // We generate an absolute branch to .__tls_get_mod.
721 Register VarOffsetReg = Subtarget->isPPC64() ? PPC::X4 : PPC::R4;
722 (void)VarOffsetReg;
723 assert((MI->getOpcode() == PPC::GETtlsMOD32AIX ||
724 MI->getOpcode() == PPC::GETtlsMOD64AIX ||
725 (MI->getOperand(2).isReg() &&
726 MI->getOperand(2).getReg() == VarOffsetReg)) &&
727 "GETtls[ld]ADDR[32] must read GPR4");
728 EmitAIXTlsCallHelper(MI);
729 return;
730 }
731
732 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol("__tls_get_addr");
733
734 if (Subtarget->is32BitELFABI() && isPositionIndependent())
736
737 const MCExpr *TlsRef = MCSymbolRefExpr::create(TlsGetAddr, Kind, OutContext);
738
739 // Add 32768 offset to the symbol so we follow up the latest GOT/PLT ABI.
740 if (Kind == PPC::S_PLT && Subtarget->isSecurePlt() &&
741 M->getPICLevel() == PICLevel::BigPIC)
743 TlsRef, MCConstantExpr::create(32768, OutContext), OutContext);
744 const MachineOperand &MO = MI->getOperand(2);
745 const GlobalValue *GValue = MO.getGlobal();
746 MCSymbol *MOSymbol = getSymbol(GValue);
747 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
748 EmitToStreamer(*OutStreamer,
749 MCInstBuilder(Subtarget->isPPC64() ? Opcode
750 : (unsigned)PPC::BL_TLS)
751 .addExpr(TlsRef)
752 .addExpr(SymVar));
753}
754
755/// Map a machine operand for a TOC pseudo-machine instruction to its
756/// corresponding MCSymbol.
758 AsmPrinter &AP) {
759 switch (MO.getType()) {
761 return AP.getSymbol(MO.getGlobal());
763 return AP.GetCPISymbol(MO.getIndex());
765 return AP.GetJTISymbol(MO.getIndex());
768 default:
769 llvm_unreachable("Unexpected operand type to get symbol.");
770 }
771}
772
773static PPCAsmPrinter::TOCEntryType
775 // Use the target flags to determine if this MO is Thread Local.
776 // If we don't do this it comes out as Global.
778 return PPCAsmPrinter::TOCType_ThreadLocal;
779
780 switch (MO.getType()) {
782 const GlobalValue *GlobalV = MO.getGlobal();
787 return PPCAsmPrinter::TOCType_GlobalExternal;
788
789 return PPCAsmPrinter::TOCType_GlobalInternal;
790 }
792 return PPCAsmPrinter::TOCType_ConstantPool;
794 return PPCAsmPrinter::TOCType_JumpTable;
796 return PPCAsmPrinter::TOCType_BlockAddress;
797 default:
798 llvm_unreachable("Unexpected operand type to get TOC type.");
799 }
800}
801
802const MCExpr *PPCAsmPrinter::symbolWithSpecifier(const MCSymbol *S,
804 return MCSymbolRefExpr::create(S, Spec, OutContext);
805}
806
807/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
808/// the current output stream.
809///
810void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
811 PPC_MC::verifyInstructionPredicates(MI->getOpcode(),
812 getSubtargetInfo().getFeatureBits());
813
814 MCInst TmpInst;
815 const bool IsPPC64 = Subtarget->isPPC64();
816 const bool IsAIX = Subtarget->isAIXABI();
817 const bool HasAIXSmallLocalTLS = Subtarget->hasAIXSmallLocalExecTLS() ||
818 Subtarget->hasAIXSmallLocalDynamicTLS();
819 const Module *M = MF->getFunction().getParent();
820 PICLevel::Level PL = M->getPICLevel();
821
822#ifndef NDEBUG
823 // Validate that SPE and FPU are mutually exclusive in codegen
824 if (!MI->isInlineAsm()) {
825 for (const MachineOperand &MO: MI->operands()) {
826 if (MO.isReg()) {
827 Register Reg = MO.getReg();
828 if (Subtarget->hasSPE()) {
829 if (PPC::F4RCRegClass.contains(Reg) ||
830 PPC::F8RCRegClass.contains(Reg) ||
831 PPC::VFRCRegClass.contains(Reg) ||
832 PPC::VRRCRegClass.contains(Reg) ||
833 PPC::VSFRCRegClass.contains(Reg) ||
834 PPC::VSSRCRegClass.contains(Reg)
835 )
836 llvm_unreachable("SPE targets cannot have FPRegs!");
837 } else {
838 if (PPC::SPERCRegClass.contains(Reg))
839 llvm_unreachable("SPE register found in FPU-targeted code!");
840 }
841 }
842 }
843 }
844#endif
845
846 auto getTOCRelocAdjustedExprForXCOFF = [this](const MCExpr *Expr,
847 ptrdiff_t OriginalOffset) {
848 // Apply an offset to the TOC-based expression such that the adjusted
849 // notional offset from the TOC base (to be encoded into the instruction's D
850 // or DS field) is the signed 16-bit truncation of the original notional
851 // offset from the TOC base.
852 // This is consistent with the treatment used both by XL C/C++ and
853 // by AIX ld -r.
854 ptrdiff_t Adjustment =
855 OriginalOffset - llvm::SignExtend32<16>(OriginalOffset);
857 Expr, MCConstantExpr::create(-Adjustment, OutContext), OutContext);
858 };
859
860 auto getTOCEntryLoadingExprForXCOFF =
861 [IsPPC64, getTOCRelocAdjustedExprForXCOFF,
862 this](const MCSymbol *MOSymbol, const MCExpr *Expr,
863 PPCMCExpr::Specifier VK = PPC::S_None) -> const MCExpr * {
864 const unsigned EntryByteSize = IsPPC64 ? 8 : 4;
865 const auto TOCEntryIter = TOC.find({MOSymbol, VK});
866 assert(TOCEntryIter != TOC.end() &&
867 "Could not find the TOC entry for this symbol.");
868 const ptrdiff_t EntryDistanceFromTOCBase =
869 (TOCEntryIter - TOC.begin()) * EntryByteSize;
870 constexpr int16_t PositiveTOCRange = INT16_MAX;
871
872 if (EntryDistanceFromTOCBase > PositiveTOCRange)
873 return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase);
874
875 return Expr;
876 };
877 auto getSpecifier = [&](const MachineOperand &MO) {
878 // For TLS initial-exec and local-exec accesses on AIX, we have one TOC
879 // entry for the symbol (with the variable offset), which is differentiated
880 // by MO_TPREL_FLAG.
881 unsigned Flag = MO.getTargetFlags();
882 if (Flag == PPCII::MO_TPREL_FLAG ||
885 assert(MO.isGlobal() && "Only expecting a global MachineOperand here!\n");
886 TLSModel::Model Model = TM.getTLSModel(MO.getGlobal());
887 if (Model == TLSModel::LocalExec)
888 return PPC::S_AIX_TLSLE;
889 if (Model == TLSModel::InitialExec)
890 return PPC::S_AIX_TLSIE;
891 // On AIX, TLS model opt may have turned local-dynamic accesses into
892 // initial-exec accesses.
893 PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
894 if (Model == TLSModel::LocalDynamic &&
895 FuncInfo->isAIXFuncUseTLSIEForLD()) {
897 dbgs() << "Current function uses IE access for default LD vars.\n");
898 return PPC::S_AIX_TLSIE;
899 }
900 llvm_unreachable("Only expecting local-exec or initial-exec accesses!");
901 }
902 // For GD TLS access on AIX, we have two TOC entries for the symbol (one for
903 // the variable offset and the other for the region handle). They are
904 // differentiated by MO_TLSGD_FLAG and MO_TLSGDM_FLAG.
905 if (Flag == PPCII::MO_TLSGDM_FLAG)
906 return PPC::S_AIX_TLSGDM;
908 return PPC::S_AIX_TLSGD;
909 // For local-dynamic TLS access on AIX, we have one TOC entry for the symbol
910 // (the variable offset) and one shared TOC entry for the module handle.
911 // They are differentiated by MO_TLSLD_FLAG and MO_TLSLDM_FLAG.
912 if (Flag == PPCII::MO_TLSLD_FLAG && IsAIX)
913 return PPC::S_AIX_TLSLD;
914 if (Flag == PPCII::MO_TLSLDM_FLAG && IsAIX)
915 return PPC::S_AIX_TLSML;
916 return PPC::S_None;
917 };
918
919 // Lower multi-instruction pseudo operations.
920 switch (MI->getOpcode()) {
921 default: break;
922 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
923 assert(!Subtarget->isAIXABI() &&
924 "AIX does not support patchable function entry!");
925 const Function &F = MF->getFunction();
926 unsigned Num = 0;
927 (void)F.getFnAttribute("patchable-function-entry")
928 .getValueAsString()
929 .getAsInteger(10, Num);
930 if (!Num)
931 return;
932 emitNops(Num);
933 return;
934 }
935 case TargetOpcode::DBG_VALUE:
936 llvm_unreachable("Should be handled target independently");
937 case TargetOpcode::STACKMAP:
938 return LowerSTACKMAP(SM, *MI);
939 case TargetOpcode::PATCHPOINT:
940 return LowerPATCHPOINT(SM, *MI);
941
942 case PPC::MoveGOTtoLR: {
943 // Transform %lr = MoveGOTtoLR
944 // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
945 // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding
946 // _GLOBAL_OFFSET_TABLE_) has exactly one instruction:
947 // blrl
948 // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local
949 MCSymbol *GOTSymbol =
950 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
951 const MCExpr *OffsExpr = MCBinaryExpr::createSub(
952 MCSymbolRefExpr::create(GOTSymbol, PPC::S_LOCAL, OutContext),
953 MCConstantExpr::create(4, OutContext), OutContext);
954
955 // Emit the 'bl'.
956 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));
957 return;
958 }
959 case PPC::MovePCtoLR:
960 case PPC::MovePCtoLR8: {
961 // Transform %lr = MovePCtoLR
962 // Into this, where the label is the PIC base:
963 // bl L1$pb
964 // L1$pb:
965 MCSymbol *PICBase = MF->getPICBaseSymbol();
966
967 // Emit 'bcl 20,31,.+4' so the link stack is not corrupted.
968 EmitToStreamer(*OutStreamer,
969 MCInstBuilder(PPC::BCLalways)
970 // FIXME: We would like an efficient form for this, so we
971 // don't have to do a lot of extra uniquing.
972 .addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));
973
974 // Emit the label.
975 OutStreamer->emitLabel(PICBase);
976 return;
977 }
978 case PPC::UpdateGBR: {
979 // Transform %rd = UpdateGBR(%rt, %ri)
980 // Into: lwz %rt, .L0$poff - .L0$pb(%ri)
981 // add %rd, %rt, %ri
982 // or into (if secure plt mode is on):
983 // addis r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@ha
984 // addi r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@l
985 // Get the offset from the GOT Base Register to the GOT
986 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
987 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
988 MCRegister PICR = TmpInst.getOperand(0).getReg();
989 MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
990 M->getPICLevel() == PICLevel::SmallPIC ? "_GLOBAL_OFFSET_TABLE_"
991 : ".LTOC");
992 const MCExpr *PB =
993 MCSymbolRefExpr::create(MF->getPICBaseSymbol(), OutContext);
994
995 const MCExpr *DeltaExpr = MCBinaryExpr::createSub(
996 MCSymbolRefExpr::create(BaseSymbol, OutContext), PB, OutContext);
997
998 const MCExpr *DeltaHi =
999 MCSpecifierExpr::create(DeltaExpr, PPC::S_HA, OutContext);
1000 EmitToStreamer(
1001 *OutStreamer,
1002 MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));
1003
1004 const MCExpr *DeltaLo =
1005 MCSpecifierExpr::create(DeltaExpr, PPC::S_LO, OutContext);
1006 EmitToStreamer(
1007 *OutStreamer,
1008 MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
1009 return;
1010 } else {
1011 MCSymbol *PICOffset =
1012 MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol(*MF);
1013 TmpInst.setOpcode(PPC::LWZ);
1014 const MCExpr *Exp = MCSymbolRefExpr::create(PICOffset, OutContext);
1015 const MCExpr *PB =
1016 MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
1017 OutContext);
1018 const MCOperand TR = TmpInst.getOperand(1);
1019 const MCOperand PICR = TmpInst.getOperand(0);
1020
1021 // Step 1: lwz %rt, .L$poff - .L$pb(%ri)
1022 TmpInst.getOperand(1) =
1024 TmpInst.getOperand(0) = TR;
1025 TmpInst.getOperand(2) = PICR;
1026 EmitToStreamer(*OutStreamer, TmpInst);
1027
1028 TmpInst.setOpcode(PPC::ADD4);
1029 TmpInst.getOperand(0) = PICR;
1030 TmpInst.getOperand(1) = TR;
1031 TmpInst.getOperand(2) = PICR;
1032 EmitToStreamer(*OutStreamer, TmpInst);
1033 return;
1034 }
1035 }
1036 case PPC::LWZtoc: {
1037 // Transform %rN = LWZtoc @op1, %r2
1038 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1039
1040 // Change the opcode to LWZ.
1041 TmpInst.setOpcode(PPC::LWZ);
1042
1043 const MachineOperand &MO = MI->getOperand(1);
1044 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
1045 "Invalid operand for LWZtoc.");
1046
1047 // Map the operand to its corresponding MCSymbol.
1048 const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
1049
1050 // Create a reference to the GOT entry for the symbol. The GOT entry will be
1051 // synthesized later.
1052 if (PL == PICLevel::SmallPIC && !IsAIX) {
1053 const MCExpr *Exp = symbolWithSpecifier(MOSymbol, PPC::S_GOT);
1054 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
1055 EmitToStreamer(*OutStreamer, TmpInst);
1056 return;
1057 }
1058
1060
1061 // Otherwise, use the TOC. 'TOCEntry' is a label used to reference the
1062 // storage allocated in the TOC which contains the address of
1063 // 'MOSymbol'. Said TOC entry will be synthesized later.
1064 MCSymbol *TOCEntry =
1065 lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);
1066 const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry, OutContext);
1067
1068 // AIX uses the label directly as the lwz displacement operand for
1069 // references into the toc section. The displacement value will be generated
1070 // relative to the toc-base.
1071 if (IsAIX) {
1072 assert(
1073 getCodeModel(*Subtarget, TM, MO) == CodeModel::Small &&
1074 "This pseudo should only be selected for 32-bit small code model.");
1075 Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK);
1076 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
1077
1078 // Print MO for better readability
1079 if (isVerbose())
1080 OutStreamer->getCommentOS() << MO << '\n';
1081 EmitToStreamer(*OutStreamer, TmpInst);
1082 return;
1083 }
1084
1085 // Create an explicit subtract expression between the local symbol and
1086 // '.LTOC' to manifest the toc-relative offset.
1087 const MCExpr *PB = MCSymbolRefExpr::create(
1088 OutContext.getOrCreateSymbol(Twine(".LTOC")), OutContext);
1089 Exp = MCBinaryExpr::createSub(Exp, PB, OutContext);
1090 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
1091 EmitToStreamer(*OutStreamer, TmpInst);
1092 return;
1093 }
1094 case PPC::ADDItoc:
1095 case PPC::ADDItoc8: {
1096 assert(IsAIX && TM.getCodeModel() == CodeModel::Small &&
1097 "PseudoOp only valid for small code model AIX");
1098
1099 // Transform %rN = ADDItoc/8 %r2, @op1.
1100 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1101
1102 // Change the opcode to load address.
1103 TmpInst.setOpcode((!IsPPC64) ? (PPC::LA) : (PPC::LA8));
1104
1105 const MachineOperand &MO = MI->getOperand(2);
1106 assert(MO.isGlobal() && "Invalid operand for ADDItoc[8].");
1107
1108 // Map the operand to its corresponding MCSymbol.
1109 const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
1110
1111 const MCExpr *Exp = MCSymbolRefExpr::create(MOSymbol, OutContext);
1112
1113 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
1114 EmitToStreamer(*OutStreamer, TmpInst);
1115 return;
1116 }
1117 case PPC::LDtocJTI:
1118 case PPC::LDtocCPT:
1119 case PPC::LDtocBA:
1120 case PPC::LDtoc: {
1121 // Transform %x3 = LDtoc @min1, %x2
1122 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1123
1124 // Change the opcode to LD.
1125 TmpInst.setOpcode(PPC::LD);
1126
1127 const MachineOperand &MO = MI->getOperand(1);
1128 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
1129 "Invalid operand!");
1130
1131 // Map the operand to its corresponding MCSymbol.
1132 const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
1133
1135
1136 // Map the machine operand to its corresponding MCSymbol, then map the
1137 // global address operand to be a reference to the TOC entry we will
1138 // synthesize later.
1139 MCSymbol *TOCEntry =
1140 lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);
1141
1142 PPCMCExpr::Specifier VKExpr = IsAIX ? PPC::S_None : PPC::S_TOC;
1143 const MCExpr *Exp = symbolWithSpecifier(TOCEntry, VKExpr);
1144 TmpInst.getOperand(1) = MCOperand::createExpr(
1145 IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK) : Exp);
1146
1147 // Print MO for better readability
1148 if (isVerbose() && IsAIX)
1149 OutStreamer->getCommentOS() << MO << '\n';
1150 EmitToStreamer(*OutStreamer, TmpInst);
1151 return;
1152 }
1153 case PPC::ADDIStocHA: {
1154 const MachineOperand &MO = MI->getOperand(2);
1155
1156 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
1157 "Invalid operand for ADDIStocHA.");
1158 assert((IsAIX && !IsPPC64 &&
1159 getCodeModel(*Subtarget, TM, MO) == CodeModel::Large) &&
1160 "This pseudo should only be selected for 32-bit large code model on"
1161 " AIX.");
1162
1163 // Transform %rd = ADDIStocHA %rA, @sym(%r2)
1164 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1165
1166 // Change the opcode to ADDIS.
1167 TmpInst.setOpcode(PPC::ADDIS);
1168
1169 // Map the machine operand to its corresponding MCSymbol.
1170 MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
1171
1173
1174 // Map the global address operand to be a reference to the TOC entry we
1175 // will synthesize later. 'TOCEntry' is a label used to reference the
1176 // storage allocated in the TOC which contains the address of 'MOSymbol'.
1177 // If the symbol does not have the toc-data attribute, then we create the
1178 // TOC entry on AIX. If the toc-data attribute is used, the TOC entry
1179 // contains the data rather than the address of the MOSymbol.
1180 if (![](const MachineOperand &MO) {
1181 if (!MO.isGlobal())
1182 return false;
1183
1184 const GlobalVariable *GV = dyn_cast<GlobalVariable>(MO.getGlobal());
1185 if (!GV)
1186 return false;
1187 return GV->hasAttribute("toc-data");
1188 }(MO)) {
1189 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);
1190 }
1191
1192 const MCExpr *Exp = symbolWithSpecifier(MOSymbol, PPC::S_U);
1193 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
1194 EmitToStreamer(*OutStreamer, TmpInst);
1195 return;
1196 }
1197 case PPC::LWZtocL: {
1198 const MachineOperand &MO = MI->getOperand(1);
1199
1200 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
1201 "Invalid operand for LWZtocL.");
1202 assert(IsAIX && !IsPPC64 &&
1203 getCodeModel(*Subtarget, TM, MO) == CodeModel::Large &&
1204 "This pseudo should only be selected for 32-bit large code model on"
1205 " AIX.");
1206
1207 // Transform %rd = LWZtocL @sym, %rs.
1208 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1209
1210 // Change the opcode to lwz.
1211 TmpInst.setOpcode(PPC::LWZ);
1212
1213 // Map the machine operand to its corresponding MCSymbol.
1214 MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
1215
1217
1218 // Always use TOC on AIX. Map the global address operand to be a reference
1219 // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
1220 // reference the storage allocated in the TOC which contains the address of
1221 // 'MOSymbol'.
1222 MCSymbol *TOCEntry =
1223 lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);
1224 const MCExpr *Exp = symbolWithSpecifier(TOCEntry, PPC::S_L);
1225 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
1226 EmitToStreamer(*OutStreamer, TmpInst);
1227 return;
1228 }
1229 case PPC::ADDIStocHA8: {
1230 // Transform %xd = ADDIStocHA8 %x2, @sym
1231 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1232
1233 // Change the opcode to ADDIS8. If the global address is the address of
1234 // an external symbol, is a jump table address, is a block address, or is a
1235 // constant pool index with large code model enabled, then generate a TOC
1236 // entry and reference that. Otherwise, reference the symbol directly.
1237 TmpInst.setOpcode(PPC::ADDIS8);
1238
1239 const MachineOperand &MO = MI->getOperand(2);
1240 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
1241 "Invalid operand for ADDIStocHA8!");
1242
1243 const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
1244
1246
1247 const bool GlobalToc =
1248 MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal());
1249
1250 const CodeModel::Model CM =
1251 IsAIX ? getCodeModel(*Subtarget, TM, MO) : TM.getCodeModel();
1252
1253 if (GlobalToc || MO.isJTI() || MO.isBlockAddress() ||
1254 (MO.isCPI() && CM == CodeModel::Large))
1255 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);
1256
1257 VK = IsAIX ? PPC::S_U : PPC::S_TOC_HA;
1258
1259 const MCExpr *Exp = symbolWithSpecifier(MOSymbol, VK);
1260
1261 if (!MO.isJTI() && MO.getOffset())
1264 OutContext),
1265 OutContext);
1266
1267 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
1268 EmitToStreamer(*OutStreamer, TmpInst);
1269 return;
1270 }
1271 case PPC::LDtocL: {
1272 // Transform %xd = LDtocL @sym, %xs
1273 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1274
1275 // Change the opcode to LD. If the global address is the address of
1276 // an external symbol, is a jump table address, is a block address, or is
1277 // a constant pool index with large code model enabled, then generate a
1278 // TOC entry and reference that. Otherwise, reference the symbol directly.
1279 TmpInst.setOpcode(PPC::LD);
1280
1281 const MachineOperand &MO = MI->getOperand(1);
1282 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
1283 MO.isBlockAddress()) &&
1284 "Invalid operand for LDtocL!");
1285
1287 (!MO.isGlobal() || Subtarget->isGVIndirectSymbol(MO.getGlobal())) &&
1288 "LDtocL used on symbol that could be accessed directly is "
1289 "invalid. Must match ADDIStocHA8."));
1290
1291 const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
1292
1294 CodeModel::Model CM =
1295 IsAIX ? getCodeModel(*Subtarget, TM, MO) : TM.getCodeModel();
1296 if (!MO.isCPI() || CM == CodeModel::Large)
1297 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, getTOCEntryTypeForMO(MO), VK);
1298
1299 VK = IsAIX ? PPC::S_L : PPC::S_TOC_LO;
1300 const MCExpr *Exp = symbolWithSpecifier(MOSymbol, VK);
1301 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
1302 EmitToStreamer(*OutStreamer, TmpInst);
1303 return;
1304 }
1305 case PPC::ADDItocL:
1306 case PPC::ADDItocL8: {
1307 // Transform %xd = ADDItocL %xs, @sym
1308 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1309
1310 unsigned Op = MI->getOpcode();
1311
1312 // Change the opcode to load address for toc-data.
1313 // ADDItocL is only used for 32-bit toc-data on AIX and will always use LA.
1314 TmpInst.setOpcode(Op == PPC::ADDItocL8 ? (IsAIX ? PPC::LA8 : PPC::ADDI8)
1315 : PPC::LA);
1316
1317 const MachineOperand &MO = MI->getOperand(2);
1318 assert((Op == PPC::ADDItocL8)
1319 ? (MO.isGlobal() || MO.isCPI())
1320 : MO.isGlobal() && "Invalid operand for ADDItocL8.");
1321 assert(!(MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal())) &&
1322 "Interposable definitions must use indirect accesses.");
1323
1324 // Map the operand to its corresponding MCSymbol.
1325 const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
1326
1327 const MCExpr *Exp = MCSymbolRefExpr::create(
1328 MOSymbol, IsAIX ? PPC::S_L : PPC::S_TOC_LO, OutContext);
1329
1330 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
1331 EmitToStreamer(*OutStreamer, TmpInst);
1332 return;
1333 }
1334 case PPC::ADDISgotTprelHA: {
1335 // Transform: %xd = ADDISgotTprelHA %x2, @sym
1336 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
1337 assert(IsPPC64 && "Not supported for 32-bit PowerPC");
1338 const MachineOperand &MO = MI->getOperand(2);
1339 const GlobalValue *GValue = MO.getGlobal();
1340 MCSymbol *MOSymbol = getSymbol(GValue);
1341 const MCExpr *SymGotTprel =
1342 symbolWithSpecifier(MOSymbol, PPC::S_GOT_TPREL_HA);
1343 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1344 .addReg(MI->getOperand(0).getReg())
1345 .addReg(MI->getOperand(1).getReg())
1346 .addExpr(SymGotTprel));
1347 return;
1348 }
1349 case PPC::LDgotTprelL:
1350 case PPC::LDgotTprelL32: {
1351 // Transform %xd = LDgotTprelL @sym, %xs
1352 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1353
1354 // Change the opcode to LD.
1355 TmpInst.setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ);
1356 const MachineOperand &MO = MI->getOperand(1);
1357 const GlobalValue *GValue = MO.getGlobal();
1358 MCSymbol *MOSymbol = getSymbol(GValue);
1359 const MCExpr *Exp = symbolWithSpecifier(
1360 MOSymbol, IsPPC64 ? PPC::S_GOT_TPREL_LO : PPC::S_GOT_TPREL);
1361 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
1362 EmitToStreamer(*OutStreamer, TmpInst);
1363 return;
1364 }
1365
1366 case PPC::PPC32PICGOT: {
1367 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
1368 MCSymbol *GOTRef = OutContext.createTempSymbol();
1369 MCSymbol *NextInstr = OutContext.createTempSymbol();
1370
1371 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL)
1372 // FIXME: We would like an efficient form for this, so we don't have to do
1373 // a lot of extra uniquing.
1374 .addExpr(MCSymbolRefExpr::create(NextInstr, OutContext)));
1375 const MCExpr *OffsExpr =
1376 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol, OutContext),
1377 MCSymbolRefExpr::create(GOTRef, OutContext),
1378 OutContext);
1379 OutStreamer->emitLabel(GOTRef);
1380 OutStreamer->emitValue(OffsExpr, 4);
1381 OutStreamer->emitLabel(NextInstr);
1382 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR)
1383 .addReg(MI->getOperand(0).getReg()));
1384 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
1385 .addReg(MI->getOperand(1).getReg())
1386 .addImm(0)
1387 .addReg(MI->getOperand(0).getReg()));
1388 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4)
1389 .addReg(MI->getOperand(0).getReg())
1390 .addReg(MI->getOperand(1).getReg())
1391 .addReg(MI->getOperand(0).getReg()));
1392 return;
1393 }
1394 case PPC::PPC32GOT: {
1395 MCSymbol *GOTSymbol =
1396 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
1397 const MCExpr *SymGotTlsL =
1398 MCSpecifierExpr::create(GOTSymbol, PPC::S_LO, OutContext);
1399 const MCExpr *SymGotTlsHA =
1400 MCSpecifierExpr::create(GOTSymbol, PPC::S_HA, OutContext);
1401 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI)
1402 .addReg(MI->getOperand(0).getReg())
1403 .addExpr(SymGotTlsL));
1404 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
1405 .addReg(MI->getOperand(0).getReg())
1406 .addReg(MI->getOperand(0).getReg())
1407 .addExpr(SymGotTlsHA));
1408 return;
1409 }
1410 case PPC::ADDIStlsgdHA: {
1411 // Transform: %xd = ADDIStlsgdHA %x2, @sym
1412 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
1413 assert(IsPPC64 && "Not supported for 32-bit PowerPC");
1414 const MachineOperand &MO = MI->getOperand(2);
1415 const GlobalValue *GValue = MO.getGlobal();
1416 MCSymbol *MOSymbol = getSymbol(GValue);
1417 const MCExpr *SymGotTlsGD =
1418 symbolWithSpecifier(MOSymbol, PPC::S_GOT_TLSGD_HA);
1419 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1420 .addReg(MI->getOperand(0).getReg())
1421 .addReg(MI->getOperand(1).getReg())
1422 .addExpr(SymGotTlsGD));
1423 return;
1424 }
1425 case PPC::ADDItlsgdL:
1426 // Transform: %xd = ADDItlsgdL %xs, @sym
1427 // Into: %xd = ADDI8 %xs, sym@got@tlsgd@l
1428 case PPC::ADDItlsgdL32: {
1429 // Transform: %rd = ADDItlsgdL32 %rs, @sym
1430 // Into: %rd = ADDI %rs, sym@got@tlsgd
1431 const MachineOperand &MO = MI->getOperand(2);
1432 const GlobalValue *GValue = MO.getGlobal();
1433 MCSymbol *MOSymbol = getSymbol(GValue);
1434 const MCExpr *SymGotTlsGD = symbolWithSpecifier(
1435 MOSymbol, IsPPC64 ? PPC::S_GOT_TLSGD_LO : PPC::S_GOT_TLSGD);
1436 EmitToStreamer(*OutStreamer,
1437 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1438 .addReg(MI->getOperand(0).getReg())
1439 .addReg(MI->getOperand(1).getReg())
1440 .addExpr(SymGotTlsGD));
1441 return;
1442 }
1443 case PPC::GETtlsMOD32AIX:
1444 case PPC::GETtlsMOD64AIX:
1445 // Transform: %r3 = GETtlsMODNNAIX %r3 (for NN == 32/64).
1446 // Into: BLA .__tls_get_mod()
1447 // Input parameter is a module handle (_$TLSML[TC]@ml) for all variables.
1448 case PPC::GETtlsADDR:
1449 // Transform: %x3 = GETtlsADDR %x3, @sym
1450 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd)
1451 case PPC::GETtlsADDRPCREL:
1452 case PPC::GETtlsADDR32AIX:
1453 case PPC::GETtlsADDR64AIX:
1454 // Transform: %r3 = GETtlsADDRNNAIX %r3, %r4 (for NN == 32/64).
1455 // Into: BLA .__tls_get_addr()
1456 // Unlike on Linux, there is no symbol or relocation needed for this call.
1457 case PPC::GETtlsADDR32: {
1458 // Transform: %r3 = GETtlsADDR32 %r3, @sym
1459 // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT
1460 emitTlsCall(MI, PPC::S_TLSGD);
1461 return;
1462 }
1463 case PPC::GETtlsTpointer32AIX: {
1464 // Transform: %r3 = GETtlsTpointer32AIX
1465 // Into: BLA .__get_tpointer()
1466 EmitAIXTlsCallHelper(MI);
1467 return;
1468 }
1469 case PPC::ADDIStlsldHA: {
1470 // Transform: %xd = ADDIStlsldHA %x2, @sym
1471 // Into: %xd = ADDIS8 %x2, sym@got@tlsld@ha
1472 assert(IsPPC64 && "Not supported for 32-bit PowerPC");
1473 const MachineOperand &MO = MI->getOperand(2);
1474 const GlobalValue *GValue = MO.getGlobal();
1475 MCSymbol *MOSymbol = getSymbol(GValue);
1476 const MCExpr *SymGotTlsLD =
1477 symbolWithSpecifier(MOSymbol, PPC::S_GOT_TLSLD_HA);
1478 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1479 .addReg(MI->getOperand(0).getReg())
1480 .addReg(MI->getOperand(1).getReg())
1481 .addExpr(SymGotTlsLD));
1482 return;
1483 }
1484 case PPC::ADDItlsldL:
1485 // Transform: %xd = ADDItlsldL %xs, @sym
1486 // Into: %xd = ADDI8 %xs, sym@got@tlsld@l
1487 case PPC::ADDItlsldL32: {
1488 // Transform: %rd = ADDItlsldL32 %rs, @sym
1489 // Into: %rd = ADDI %rs, sym@got@tlsld
1490 const MachineOperand &MO = MI->getOperand(2);
1491 const GlobalValue *GValue = MO.getGlobal();
1492 MCSymbol *MOSymbol = getSymbol(GValue);
1493 const MCExpr *SymGotTlsLD = symbolWithSpecifier(
1494 MOSymbol, IsPPC64 ? PPC::S_GOT_TLSLD_LO : PPC::S_GOT_TLSLD);
1495 EmitToStreamer(*OutStreamer,
1496 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1497 .addReg(MI->getOperand(0).getReg())
1498 .addReg(MI->getOperand(1).getReg())
1499 .addExpr(SymGotTlsLD));
1500 return;
1501 }
1502 case PPC::GETtlsldADDR:
1503 // Transform: %x3 = GETtlsldADDR %x3, @sym
1504 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld)
1505 case PPC::GETtlsldADDRPCREL:
1506 case PPC::GETtlsldADDR32: {
1507 // Transform: %r3 = GETtlsldADDR32 %r3, @sym
1508 // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT
1509 emitTlsCall(MI, PPC::S_TLSLD);
1510 return;
1511 }
1512 case PPC::ADDISdtprelHA:
1513 // Transform: %xd = ADDISdtprelHA %xs, @sym
1514 // Into: %xd = ADDIS8 %xs, sym@dtprel@ha
1515 case PPC::ADDISdtprelHA32: {
1516 // Transform: %rd = ADDISdtprelHA32 %rs, @sym
1517 // Into: %rd = ADDIS %rs, sym@dtprel@ha
1518 const MachineOperand &MO = MI->getOperand(2);
1519 const GlobalValue *GValue = MO.getGlobal();
1520 MCSymbol *MOSymbol = getSymbol(GValue);
1521 const MCExpr *SymDtprel = symbolWithSpecifier(MOSymbol, PPC::S_DTPREL_HA);
1522 EmitToStreamer(
1523 *OutStreamer,
1524 MCInstBuilder(IsPPC64 ? PPC::ADDIS8 : PPC::ADDIS)
1525 .addReg(MI->getOperand(0).getReg())
1526 .addReg(MI->getOperand(1).getReg())
1527 .addExpr(SymDtprel));
1528 return;
1529 }
1530 case PPC::PADDIdtprel: {
1531 // Transform: %rd = PADDIdtprel %rs, @sym
1532 // Into: %rd = PADDI8 %rs, sym@dtprel
1533 const MachineOperand &MO = MI->getOperand(2);
1534 const GlobalValue *GValue = MO.getGlobal();
1535 MCSymbol *MOSymbol = getSymbol(GValue);
1536 const MCExpr *SymDtprel = symbolWithSpecifier(MOSymbol, PPC::S_DTPREL);
1537 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::PADDI8)
1538 .addReg(MI->getOperand(0).getReg())
1539 .addReg(MI->getOperand(1).getReg())
1540 .addExpr(SymDtprel));
1541 return;
1542 }
1543
1544 case PPC::ADDIdtprelL:
1545 // Transform: %xd = ADDIdtprelL %xs, @sym
1546 // Into: %xd = ADDI8 %xs, sym@dtprel@l
1547 case PPC::ADDIdtprelL32: {
1548 // Transform: %rd = ADDIdtprelL32 %rs, @sym
1549 // Into: %rd = ADDI %rs, sym@dtprel@l
1550 const MachineOperand &MO = MI->getOperand(2);
1551 const GlobalValue *GValue = MO.getGlobal();
1552 MCSymbol *MOSymbol = getSymbol(GValue);
1553 const MCExpr *SymDtprel = symbolWithSpecifier(MOSymbol, PPC::S_DTPREL_LO);
1554 EmitToStreamer(*OutStreamer,
1555 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1556 .addReg(MI->getOperand(0).getReg())
1557 .addReg(MI->getOperand(1).getReg())
1558 .addExpr(SymDtprel));
1559 return;
1560 }
1561 case PPC::MFOCRF:
1562 case PPC::MFOCRF8:
1563 if (!Subtarget->hasMFOCRF()) {
1564 // Transform: %r3 = MFOCRF %cr7
1565 // Into: %r3 = MFCR ;; cr7
1566 unsigned NewOpcode =
1567 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
1568 OutStreamer->AddComment(PPCInstPrinter::
1569 getRegisterName(MI->getOperand(1).getReg()));
1570 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1571 .addReg(MI->getOperand(0).getReg()));
1572 return;
1573 }
1574 break;
1575 case PPC::MTOCRF:
1576 case PPC::MTOCRF8:
1577 if (!Subtarget->hasMFOCRF()) {
1578 // Transform: %cr7 = MTOCRF %r3
1579 // Into: MTCRF mask, %r3 ;; cr7
1580 unsigned NewOpcode =
1581 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1582 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
1583 ->getEncodingValue(MI->getOperand(0).getReg());
1584 OutStreamer->AddComment(PPCInstPrinter::
1585 getRegisterName(MI->getOperand(0).getReg()));
1586 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1587 .addImm(Mask)
1588 .addReg(MI->getOperand(1).getReg()));
1589 return;
1590 }
1591 break;
1592 case PPC::LD:
1593 case PPC::STD:
1594 case PPC::LWA_32:
1595 case PPC::LWA: {
1596 // Verify alignment is legal, so we don't create relocations
1597 // that can't be supported.
1598 unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
1599 // For non-TOC-based local-exec TLS accesses with non-zero offsets, the
1600 // machine operand (which is a TargetGlobalTLSAddress) is expected to be
1601 // the same operand for both loads and stores.
1602 for (const MachineOperand &TempMO : MI->operands()) {
1603 if (((TempMO.getTargetFlags() == PPCII::MO_TPREL_FLAG ||
1604 TempMO.getTargetFlags() == PPCII::MO_TLSLD_FLAG)) &&
1605 TempMO.getOperandNo() == 1)
1606 OpNum = 1;
1607 }
1608 const MachineOperand &MO = MI->getOperand(OpNum);
1609 if (MO.isGlobal()) {
1610 const DataLayout &DL = MO.getGlobal()->getDataLayout();
1611 if (MO.getGlobal()->getPointerAlignment(DL) < 4)
1612 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
1613 }
1614 // As these load/stores share common code with the following load/stores,
1615 // fall through to the subsequent cases in order to either process the
1616 // non-TOC-based local-exec sequence or to process the instruction normally.
1617 [[fallthrough]];
1618 }
1619 case PPC::LBZ:
1620 case PPC::LBZ8:
1621 case PPC::LHA:
1622 case PPC::LHA8:
1623 case PPC::LHZ:
1624 case PPC::LHZ8:
1625 case PPC::LWZ:
1626 case PPC::LWZ8:
1627 case PPC::STB:
1628 case PPC::STB8:
1629 case PPC::STH:
1630 case PPC::STH8:
1631 case PPC::STW:
1632 case PPC::STW8:
1633 case PPC::LFS:
1634 case PPC::STFS:
1635 case PPC::LFD:
1636 case PPC::STFD:
1637 case PPC::ADDI8: {
1638 // A faster non-TOC-based local-[exec|dynamic] sequence is represented by
1639 // `addi` or a load/store instruction (that directly loads or stores off of
1640 // the thread pointer) with an immediate operand having the
1641 // [MO_TPREL_FLAG|MO_TLSLD_FLAG]. Such instructions do not otherwise arise.
1642 if (!HasAIXSmallLocalTLS)
1643 break;
1644 bool IsMIADDI8 = MI->getOpcode() == PPC::ADDI8;
1645 unsigned OpNum = IsMIADDI8 ? 2 : 1;
1646 const MachineOperand &MO = MI->getOperand(OpNum);
1647 unsigned Flag = MO.getTargetFlags();
1648 if (Flag == PPCII::MO_TPREL_FLAG ||
1651 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1652
1653 const MCExpr *Expr = getAdjustedFasterLocalExpr(MO, MO.getOffset());
1654 if (Expr)
1655 TmpInst.getOperand(OpNum) = MCOperand::createExpr(Expr);
1656
1657 // Change the opcode to load address if the original opcode is an `addi`.
1658 if (IsMIADDI8)
1659 TmpInst.setOpcode(PPC::LA8);
1660
1661 EmitToStreamer(*OutStreamer, TmpInst);
1662 return;
1663 }
1664 // Now process the instruction normally.
1665 break;
1666 }
1667 case PPC::PseudoEIEIO: {
1668 EmitToStreamer(
1669 *OutStreamer,
1670 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1671 EmitToStreamer(
1672 *OutStreamer,
1673 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1674 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::EnforceIEIO));
1675 return;
1676 }
1677 }
1678
1679 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1680 EmitToStreamer(*OutStreamer, TmpInst);
1681}
1682
1683// For non-TOC-based local-[exec|dynamic] variables that have a non-zero offset,
1684// we need to create a new MCExpr that adds the non-zero offset to the address
1685// of the local-[exec|dynamic] variable that will be used in either an addi,
1686// load or store. However, the final displacement for these instructions must be
1687// between [-32768, 32768), so if the TLS address + its non-zero offset is
1688// greater than 32KB, a new MCExpr is produced to accommodate this situation.
1689const MCExpr *
1690PPCAsmPrinter::getAdjustedFasterLocalExpr(const MachineOperand &MO,
1691 int64_t Offset) {
1692 // Non-zero offsets (for loads, stores or `addi`) require additional handling.
1693 // When the offset is zero, there is no need to create an adjusted MCExpr.
1694 if (!Offset)
1695 return nullptr;
1696
1697 assert(MO.isGlobal() && "Only expecting a global MachineOperand here!");
1698 const GlobalValue *GValue = MO.getGlobal();
1699 TLSModel::Model Model = TM.getTLSModel(GValue);
1700 assert((Model == TLSModel::LocalExec || Model == TLSModel::LocalDynamic) &&
1701 "Only local-[exec|dynamic] accesses are handled!");
1702
1703 bool IsGlobalADeclaration = GValue->isDeclarationForLinker();
1704 // Find the GlobalVariable that corresponds to the particular TLS variable
1705 // in the TLS variable-to-address mapping. All TLS variables should exist
1706 // within this map, with the exception of TLS variables marked as extern.
1707 const auto TLSVarsMapEntryIter = TLSVarsToAddressMapping.find(GValue);
1708 if (TLSVarsMapEntryIter == TLSVarsToAddressMapping.end())
1709 assert(IsGlobalADeclaration &&
1710 "Only expecting to find extern TLS variables not present in the TLS "
1711 "variable-to-address map!");
1712
1713 unsigned TLSVarAddress =
1714 IsGlobalADeclaration ? 0 : TLSVarsMapEntryIter->second;
1715 ptrdiff_t FinalAddress = (TLSVarAddress + Offset);
1716 // If the address of the TLS variable + the offset is less than 32KB,
1717 // or if the TLS variable is extern, we simply produce an MCExpr to add the
1718 // non-zero offset to the TLS variable address.
1719 // For when TLS variables are extern, this is safe to do because we can
1720 // assume that the address of extern TLS variables are zero.
1721 const MCExpr *Expr = MCSymbolRefExpr::create(
1722 getSymbol(GValue),
1724 OutContext);
1726 Expr, MCConstantExpr::create(Offset, OutContext), OutContext);
1727 if (FinalAddress >= 32768) {
1728 // Handle the written offset for cases where:
1729 // TLS variable address + Offset > 32KB.
1730
1731 // The assembly that is printed will look like:
1732 // TLSVar@le + Offset - Delta
1733 // where Delta is a multiple of 64KB: ((FinalAddress + 32768) & ~0xFFFF).
1734 ptrdiff_t Delta = ((FinalAddress + 32768) & ~0xFFFF);
1735 // Check that the total instruction displacement fits within [-32768,32768).
1736 [[maybe_unused]] ptrdiff_t InstDisp = TLSVarAddress + Offset - Delta;
1737 assert(
1738 ((InstDisp < 32768) && (InstDisp >= -32768)) &&
1739 "Expecting the instruction displacement for local-[exec|dynamic] TLS "
1740 "variables to be between [-32768, 32768)!");
1742 Expr, MCConstantExpr::create(-Delta, OutContext), OutContext);
1743 }
1744
1745 return Expr;
1746}
1747
1748void PPCLinuxAsmPrinter::emitGNUAttributes(Module &M) {
1749 // Emit float ABI into GNU attribute
1750 Metadata *MD = M.getModuleFlag("float-abi");
1751 MDString *FloatABI = dyn_cast_or_null<MDString>(MD);
1752 if (!FloatABI)
1753 return;
1754 StringRef flt = FloatABI->getString();
1755 // TODO: Support emitting soft-fp and hard double/single attributes.
1756 if (flt == "doubledouble")
1757 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1758 Val_GNU_Power_ABI_HardFloat_DP |
1759 Val_GNU_Power_ABI_LDBL_IBM128);
1760 else if (flt == "ieeequad")
1761 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1762 Val_GNU_Power_ABI_HardFloat_DP |
1763 Val_GNU_Power_ABI_LDBL_IEEE128);
1764 else if (flt == "ieeedouble")
1765 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1766 Val_GNU_Power_ABI_HardFloat_DP |
1767 Val_GNU_Power_ABI_LDBL_64);
1768}
1769
1770void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {
1771 if (!Subtarget->isPPC64())
1772 return PPCAsmPrinter::emitInstruction(MI);
1773
1774 switch (MI->getOpcode()) {
1775 default:
1776 break;
1777 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1778 // .begin:
1779 // b .end # lis 0, FuncId[16..32]
1780 // nop # li 0, FuncId[0..15]
1781 // std 0, -8(1)
1782 // mflr 0
1783 // bl __xray_FunctionEntry
1784 // mtlr 0
1785 // .end:
1786 //
1787 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1788 // of instructions change.
1789 // XRAY is only supported on PPC Linux little endian.
1790 const Function &F = MF->getFunction();
1791 unsigned Num = 0;
1792 (void)F.getFnAttribute("patchable-function-entry")
1793 .getValueAsString()
1794 .getAsInteger(10, Num);
1795
1796 if (!MAI->isLittleEndian() || Num)
1797 break;
1798 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1799 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1800 OutStreamer->emitLabel(BeginOfSled);
1801 EmitToStreamer(*OutStreamer,
1802 MCInstBuilder(PPC::B).addExpr(
1803 MCSymbolRefExpr::create(EndOfSled, OutContext)));
1804 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1805 EmitToStreamer(
1806 *OutStreamer,
1807 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1808 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1809 EmitToStreamer(*OutStreamer,
1810 MCInstBuilder(PPC::BL8_NOP)
1811 .addExpr(MCSymbolRefExpr::create(
1812 OutContext.getOrCreateSymbol("__xray_FunctionEntry"),
1813 OutContext)));
1814 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1815 OutStreamer->emitLabel(EndOfSled);
1816 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER, 2);
1817 break;
1818 }
1819 case TargetOpcode::PATCHABLE_RET: {
1820 unsigned RetOpcode = MI->getOperand(0).getImm();
1821 MCInst RetInst;
1822 RetInst.setOpcode(RetOpcode);
1823 for (const auto &MO : llvm::drop_begin(MI->operands())) {
1824 MCOperand MCOp;
1825 if (LowerPPCMachineOperandToMCOperand(MO, MCOp, *this))
1826 RetInst.addOperand(MCOp);
1827 }
1828
1829 bool IsConditional;
1830 if (RetOpcode == PPC::BCCLR) {
1831 IsConditional = true;
1832 } else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1833 RetOpcode == PPC::TCRETURNai8) {
1834 break;
1835 } else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1836 IsConditional = false;
1837 } else {
1838 EmitToStreamer(*OutStreamer, RetInst);
1839 return;
1840 }
1841
1842 MCSymbol *FallthroughLabel;
1843 if (IsConditional) {
1844 // Before:
1845 // bgtlr cr0
1846 //
1847 // After:
1848 // ble cr0, .end
1849 // .p2align 3
1850 // .begin:
1851 // blr # lis 0, FuncId[16..32]
1852 // nop # li 0, FuncId[0..15]
1853 // std 0, -8(1)
1854 // mflr 0
1855 // bl __xray_FunctionExit
1856 // mtlr 0
1857 // blr
1858 // .end:
1859 //
1860 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1861 // of instructions change.
1862 FallthroughLabel = OutContext.createTempSymbol();
1863 EmitToStreamer(
1864 *OutStreamer,
1865 MCInstBuilder(PPC::BCC)
1866 .addImm(PPC::InvertPredicate(
1867 static_cast<PPC::Predicate>(MI->getOperand(1).getImm())))
1868 .addReg(MI->getOperand(2).getReg())
1869 .addExpr(MCSymbolRefExpr::create(FallthroughLabel, OutContext)));
1870 RetInst = MCInst();
1871 RetInst.setOpcode(PPC::BLR8);
1872 }
1873 // .p2align 3
1874 // .begin:
1875 // b(lr)? # lis 0, FuncId[16..32]
1876 // nop # li 0, FuncId[0..15]
1877 // std 0, -8(1)
1878 // mflr 0
1879 // bl __xray_FunctionExit
1880 // mtlr 0
1881 // b(lr)?
1882 //
1883 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1884 // of instructions change.
1885 OutStreamer->emitCodeAlignment(Align(8), &getSubtargetInfo());
1886 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1887 OutStreamer->emitLabel(BeginOfSled);
1888 EmitToStreamer(*OutStreamer, RetInst);
1889 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1890 EmitToStreamer(
1891 *OutStreamer,
1892 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1893 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1894 EmitToStreamer(*OutStreamer,
1895 MCInstBuilder(PPC::BL8_NOP)
1896 .addExpr(MCSymbolRefExpr::create(
1897 OutContext.getOrCreateSymbol("__xray_FunctionExit"),
1898 OutContext)));
1899 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1900 EmitToStreamer(*OutStreamer, RetInst);
1901 if (IsConditional)
1902 OutStreamer->emitLabel(FallthroughLabel);
1903 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT, 2);
1904 return;
1905 }
1906 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1907 llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted");
1908 case TargetOpcode::PATCHABLE_TAIL_CALL:
1909 // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a
1910 // normal function exit from a tail exit.
1911 llvm_unreachable("Tail call is handled in the normal case. See comments "
1912 "around this assert.");
1913 }
1914 return PPCAsmPrinter::emitInstruction(MI);
1915}
1916
1917void PPCLinuxAsmPrinter::emitStartOfAsmFile(Module &M) {
1918 if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) {
1919 PPCTargetStreamer *TS =
1920 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1921 TS->emitAbiVersion(2);
1922 }
1923
1924 if (static_cast<const PPCTargetMachine &>(TM).isPPC64() ||
1925 !isPositionIndependent())
1927
1928 if (M.getPICLevel() == PICLevel::SmallPIC)
1930
1931 OutStreamer->switchSection(OutContext.getELFSection(
1933
1934 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(".LTOC"));
1935 MCSymbol *CurrentPos = OutContext.createTempSymbol();
1936
1937 OutStreamer->emitLabel(CurrentPos);
1938
1939 // The GOT pointer points to the middle of the GOT, in order to reference the
1940 // entire 64kB range. 0x8000 is the midpoint.
1941 const MCExpr *tocExpr =
1942 MCBinaryExpr::createAdd(MCSymbolRefExpr::create(CurrentPos, OutContext),
1943 MCConstantExpr::create(0x8000, OutContext),
1944 OutContext);
1945
1946 OutStreamer->emitAssignment(TOCSym, tocExpr);
1947
1948 OutStreamer->switchSection(getObjFileLowering().getTextSection());
1949}
1950
1951void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
1952 // linux/ppc32 - Normal entry label.
1953 if (!Subtarget->isPPC64() &&
1954 (!isPositionIndependent() ||
1955 MF->getFunction().getParent()->getPICLevel() == PICLevel::SmallPIC))
1957
1958 if (!Subtarget->isPPC64()) {
1959 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1960 if (PPCFI->usesPICBase() && !Subtarget->isSecurePlt()) {
1961 MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol(*MF);
1962 MCSymbol *PICBase = MF->getPICBaseSymbol();
1963 OutStreamer->emitLabel(RelocSymbol);
1964
1965 const MCExpr *OffsExpr =
1967 MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")),
1968 OutContext),
1969 MCSymbolRefExpr::create(PICBase, OutContext),
1970 OutContext);
1971 OutStreamer->emitValue(OffsExpr, 4);
1972 OutStreamer->emitLabel(CurrentFnSym);
1973 return;
1974 } else
1976 }
1977
1978 // ELFv2 ABI - Normal entry label.
1979 if (Subtarget->isELFv2ABI()) {
1980 // In the Large code model, we allow arbitrary displacements between
1981 // the text section and its associated TOC section. We place the
1982 // full 8-byte offset to the TOC in memory immediately preceding
1983 // the function global entry point.
1984 if (TM.getCodeModel() == CodeModel::Large
1985 && !MF->getRegInfo().use_empty(PPC::X2)) {
1986 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1987
1988 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1989 MCSymbol *GlobalEPSymbol = PPCFI->getGlobalEPSymbol(*MF);
1990 const MCExpr *TOCDeltaExpr =
1991 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1992 MCSymbolRefExpr::create(GlobalEPSymbol,
1993 OutContext),
1994 OutContext);
1995
1996 OutStreamer->emitLabel(PPCFI->getTOCOffsetSymbol(*MF));
1997 OutStreamer->emitValue(TOCDeltaExpr, 8);
1998 }
2000 }
2001
2002 // Emit an official procedure descriptor.
2003 MCSectionSubPair Current = OutStreamer->getCurrentSection();
2004 MCSectionELF *Section = OutStreamer->getContext().getELFSection(
2006 OutStreamer->switchSection(Section);
2007 OutStreamer->emitLabel(CurrentFnSym);
2008 OutStreamer->emitValueToAlignment(Align(8));
2009 MCSymbol *Symbol1 = CurrentFnSymForSize;
2010 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
2011 // entry point.
2012 OutStreamer->emitValue(MCSymbolRefExpr::create(Symbol1, OutContext),
2013 8 /*size*/);
2014 MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(".TOC."));
2015 // Generates a R_PPC64_TOC relocation for TOC base insertion.
2016 OutStreamer->emitValue(
2017 MCSymbolRefExpr::create(Symbol2, PPC::S_TOCBASE, OutContext), 8 /*size*/);
2018 // Emit a null environment pointer.
2019 OutStreamer->emitIntValue(0, 8 /* size */);
2020 OutStreamer->switchSection(Current.first, Current.second);
2021}
2022
2023void PPCLinuxAsmPrinter::emitEndOfAsmFile(Module &M) {
2024 const DataLayout &DL = getDataLayout();
2025
2026 bool isPPC64 = DL.getPointerSizeInBits() == 64;
2027
2028 PPCTargetStreamer *TS =
2029 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
2030
2031 // If we are using any values provided by Glibc at fixed addresses,
2032 // we need to ensure that the Glibc used at link time actually provides
2033 // those values. All versions of Glibc that do will define the symbol
2034 // named "__parse_hwcap_and_convert_at_platform".
2035 if (static_cast<const PPCTargetMachine &>(TM).hasGlibcHWCAPAccess())
2036 OutStreamer->emitSymbolValue(
2037 GetExternalSymbolSymbol("__parse_hwcap_and_convert_at_platform"),
2038 MAI->getCodePointerSize());
2039 emitGNUAttributes(M);
2040
2041 if (!TOC.empty()) {
2042 const char *Name = isPPC64 ? ".toc" : ".got2";
2043 MCSectionELF *Section = OutContext.getELFSection(
2045 OutStreamer->switchSection(Section);
2046 if (!isPPC64)
2047 OutStreamer->emitValueToAlignment(Align(4));
2048
2049 for (const auto &TOCMapPair : TOC) {
2050 const MCSymbol *const TOCEntryTarget = TOCMapPair.first.first;
2051 MCSymbol *const TOCEntryLabel = TOCMapPair.second;
2052
2053 OutStreamer->emitLabel(TOCEntryLabel);
2054 if (isPPC64)
2055 TS->emitTCEntry(*TOCEntryTarget, TOCMapPair.first.second);
2056 else
2057 OutStreamer->emitSymbolValue(TOCEntryTarget, 4);
2058 }
2059 }
2060
2061 PPCAsmPrinter::emitEndOfAsmFile(M);
2062}
2063
2064/// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2.
2065void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
2066 // In the ELFv2 ABI, in functions that use the TOC register, we need to
2067 // provide two entry points. The ABI guarantees that when calling the
2068 // local entry point, r2 is set up by the caller to contain the TOC base
2069 // for this function, and when calling the global entry point, r12 is set
2070 // up by the caller to hold the address of the global entry point. We
2071 // thus emit a prefix sequence along the following lines:
2072 //
2073 // func:
2074 // .Lfunc_gepNN:
2075 // # global entry point
2076 // addis r2,r12,(.TOC.-.Lfunc_gepNN)@ha
2077 // addi r2,r2,(.TOC.-.Lfunc_gepNN)@l
2078 // .Lfunc_lepNN:
2079 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
2080 // # local entry point, followed by function body
2081 //
2082 // For the Large code model, we create
2083 //
2084 // .Lfunc_tocNN:
2085 // .quad .TOC.-.Lfunc_gepNN # done by EmitFunctionEntryLabel
2086 // func:
2087 // .Lfunc_gepNN:
2088 // # global entry point
2089 // ld r2,.Lfunc_tocNN-.Lfunc_gepNN(r12)
2090 // add r2,r2,r12
2091 // .Lfunc_lepNN:
2092 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
2093 // # local entry point, followed by function body
2094 //
2095 // This ensures we have r2 set up correctly while executing the function
2096 // body, no matter which entry point is called.
2097 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
2098 const bool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) ||
2099 !MF->getRegInfo().use_empty(PPC::R2);
2100 const bool PCrelGEPRequired = Subtarget->isUsingPCRelativeCalls() &&
2101 UsesX2OrR2 && PPCFI->usesTOCBasePtr();
2102 const bool NonPCrelGEPRequired = !Subtarget->isUsingPCRelativeCalls() &&
2103 Subtarget->isELFv2ABI() && UsesX2OrR2;
2104
2105 // Only do all that if the function uses R2 as the TOC pointer
2106 // in the first place. We don't need the global entry point if the
2107 // function uses R2 as an allocatable register.
2108 if (NonPCrelGEPRequired || PCrelGEPRequired) {
2109 // Note: The logic here must be synchronized with the code in the
2110 // branch-selection pass which sets the offset of the first block in the
2111 // function. This matters because it affects the alignment.
2112 MCSymbol *GlobalEntryLabel = PPCFI->getGlobalEPSymbol(*MF);
2113 OutStreamer->emitLabel(GlobalEntryLabel);
2114 const MCSymbolRefExpr *GlobalEntryLabelExp =
2115 MCSymbolRefExpr::create(GlobalEntryLabel, OutContext);
2116
2117 if (TM.getCodeModel() != CodeModel::Large) {
2118 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
2119 const MCExpr *TOCDeltaExpr =
2120 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
2121 GlobalEntryLabelExp, OutContext);
2122
2123 const MCExpr *TOCDeltaHi =
2124 MCSpecifierExpr::create(TOCDeltaExpr, PPC::S_HA, OutContext);
2125 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
2126 .addReg(PPC::X2)
2127 .addReg(PPC::X12)
2128 .addExpr(TOCDeltaHi));
2129
2130 const MCExpr *TOCDeltaLo =
2131 MCSpecifierExpr::create(TOCDeltaExpr, PPC::S_LO, OutContext);
2132 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
2133 .addReg(PPC::X2)
2134 .addReg(PPC::X2)
2135 .addExpr(TOCDeltaLo));
2136 } else {
2137 MCSymbol *TOCOffset = PPCFI->getTOCOffsetSymbol(*MF);
2138 const MCExpr *TOCOffsetDeltaExpr =
2139 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCOffset, OutContext),
2140 GlobalEntryLabelExp, OutContext);
2141
2142 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
2143 .addReg(PPC::X2)
2144 .addExpr(TOCOffsetDeltaExpr)
2145 .addReg(PPC::X12));
2146 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8)
2147 .addReg(PPC::X2)
2148 .addReg(PPC::X2)
2149 .addReg(PPC::X12));
2150 }
2151
2152 MCSymbol *LocalEntryLabel = PPCFI->getLocalEPSymbol(*MF);
2153 OutStreamer->emitLabel(LocalEntryLabel);
2154 const MCSymbolRefExpr *LocalEntryLabelExp =
2155 MCSymbolRefExpr::create(LocalEntryLabel, OutContext);
2156 const MCExpr *LocalOffsetExp =
2157 MCBinaryExpr::createSub(LocalEntryLabelExp,
2158 GlobalEntryLabelExp, OutContext);
2159
2160 PPCTargetStreamer *TS =
2161 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
2162 TS->emitLocalEntry(static_cast<MCSymbolELF *>(CurrentFnSym),
2163 LocalOffsetExp);
2164 } else if (Subtarget->isUsingPCRelativeCalls()) {
2165 // When generating the entry point for a function we have a few scenarios
2166 // based on whether or not that function uses R2 and whether or not that
2167 // function makes calls (or is a leaf function).
2168 // 1) A leaf function that does not use R2 (or treats it as callee-saved
2169 // and preserves it). In this case st_other=0 and both
2170 // the local and global entry points for the function are the same.
2171 // No special entry point code is required.
2172 // 2) A function uses the TOC pointer R2. This function may or may not have
2173 // calls. In this case st_other=[2,6] and the global and local entry
2174 // points are different. Code to correctly setup the TOC pointer in R2
2175 // is put between the global and local entry points. This case is
2176 // covered by the if statatement above.
2177 // 3) A function does not use the TOC pointer R2 but does have calls.
2178 // In this case st_other=1 since we do not know whether or not any
2179 // of the callees clobber R2. This case is dealt with in this else if
2180 // block. Tail calls are considered calls and the st_other should also
2181 // be set to 1 in that case as well.
2182 // 4) The function does not use the TOC pointer but R2 is used inside
2183 // the function. In this case st_other=1 once again.
2184 // 5) This function uses inline asm. We mark R2 as reserved if the function
2185 // has inline asm as we have to assume that it may be used.
2186 if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() ||
2187 MF->hasInlineAsm() || (!PPCFI->usesTOCBasePtr() && UsesX2OrR2)) {
2188 PPCTargetStreamer *TS =
2189 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
2190 TS->emitLocalEntry(static_cast<MCSymbolELF *>(CurrentFnSym),
2191 MCConstantExpr::create(1, OutContext));
2192 }
2193 }
2194}
2195
2196/// EmitFunctionBodyEnd - Print the traceback table before the .size
2197/// directive.
2198///
2199void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
2200 // Only the 64-bit target requires a traceback table. For now,
2201 // we only emit the word of zeroes that GDB requires to find
2202 // the end of the function, and zeroes for the eight-byte
2203 // mandatory fields.
2204 // FIXME: We should fill in the eight-byte mandatory fields as described in
2205 // the PPC64 ELF ABI (this is a low-priority item because GDB does not
2206 // currently make use of these fields).
2207 if (Subtarget->isPPC64()) {
2208 OutStreamer->emitIntValue(0, 4/*size*/);
2209 OutStreamer->emitIntValue(0, 8/*size*/);
2210 }
2211}
2212
2213char PPCLinuxAsmPrinter::ID = 0;
2214
2215INITIALIZE_PASS(PPCLinuxAsmPrinter, "ppc-linux-asm-printer",
2216 "Linux PPC Assembly Printer", false, false)
2217
2218void PPCAIXAsmPrinter::emitLinkage(const GlobalValue *GV,
2219 MCSymbol *GVSym) const {
2220 MCSymbolAttr LinkageAttr = MCSA_Invalid;
2221 switch (GV->getLinkage()) {
2222 case GlobalValue::ExternalLinkage:
2223 LinkageAttr = GV->isDeclaration() ? MCSA_Extern : MCSA_Global;
2224 break;
2225 case GlobalValue::LinkOnceAnyLinkage:
2226 case GlobalValue::LinkOnceODRLinkage:
2227 case GlobalValue::WeakAnyLinkage:
2228 case GlobalValue::WeakODRLinkage:
2229 case GlobalValue::ExternalWeakLinkage:
2230 LinkageAttr = MCSA_Weak;
2231 break;
2232 case GlobalValue::AvailableExternallyLinkage:
2233 LinkageAttr = MCSA_Extern;
2234 break;
2235 case GlobalValue::PrivateLinkage:
2236 return;
2237 case GlobalValue::InternalLinkage:
2238 assert(GV->getVisibility() == GlobalValue::DefaultVisibility &&
2239 "InternalLinkage should not have other visibility setting.");
2240 LinkageAttr = MCSA_LGlobal;
2241 break;
2242 case GlobalValue::AppendingLinkage:
2243 llvm_unreachable("Should never emit this");
2244 case GlobalValue::CommonLinkage:
2245 llvm_unreachable("CommonLinkage of XCOFF should not come to this path");
2246 }
2247
2248 assert(LinkageAttr != MCSA_Invalid && "LinkageAttr should not MCSA_Invalid.");
2249
2250 MCSymbolAttr VisibilityAttr = MCSA_Invalid;
2251 if (!TM.getIgnoreXCOFFVisibility()) {
2252 if (GV->hasDLLExportStorageClass() && !GV->hasDefaultVisibility())
2253 report_fatal_error(
2254 "Cannot not be both dllexport and non-default visibility");
2255 switch (GV->getVisibility()) {
2256
2257 // TODO: "internal" Visibility needs to go here.
2258 case GlobalValue::DefaultVisibility:
2259 if (GV->hasDLLExportStorageClass())
2260 VisibilityAttr = MAI->getExportedVisibilityAttr();
2261 break;
2262 case GlobalValue::HiddenVisibility:
2263 VisibilityAttr = MAI->getHiddenVisibilityAttr();
2264 break;
2265 case GlobalValue::ProtectedVisibility:
2266 VisibilityAttr = MAI->getProtectedVisibilityAttr();
2267 break;
2268 }
2269 }
2270
2271 // Do not emit the _$TLSML symbol.
2272 if (GV->getThreadLocalMode() == GlobalVariable::LocalDynamicTLSModel &&
2273 GV->hasName() && GV->getName() == "_$TLSML")
2274 return;
2275
2276 OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,
2277 VisibilityAttr);
2278}
2279
2280void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
2281 // Setup CurrentFnDescSym and its containing csect.
2282 auto *FnDescSec = static_cast<MCSectionXCOFF *>(
2283 getObjFileLowering().getSectionForFunctionDescriptor(&MF.getFunction(),
2284 TM));
2285 FnDescSec->setAlignment(Align(Subtarget->isPPC64() ? 8 : 4));
2286
2287 CurrentFnDescSym = FnDescSec->getQualNameSymbol();
2288
2290}
2291
2292uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
2293 // Calculate the number of VRs be saved.
2294 // Vector registers 20 through 31 are marked as reserved and cannot be used
2295 // in the default ABI.
2296 const PPCSubtarget &Subtarget = MF->getSubtarget<PPCSubtarget>();
2297 if (Subtarget.isAIXABI() && Subtarget.hasAltivec() &&
2298 TM.getAIXExtendedAltivecABI()) {
2299 const MachineRegisterInfo &MRI = MF->getRegInfo();
2300 for (unsigned Reg = PPC::V20; Reg <= PPC::V31; ++Reg)
2301 if (MRI.isPhysRegModified(Reg))
2302 // Number of VRs saved.
2303 return PPC::V31 - Reg + 1;
2304 }
2305 return 0;
2306}
2307
2308void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
2309
2310 if (!TM.getXCOFFTracebackTable())
2311 return;
2312
2313 emitTracebackTable();
2314
2315 // If ShouldEmitEHBlock returns true, then the eh info table
2316 // will be emitted via `AIXException::endFunction`. Otherwise, we
2317 // need to emit a dumy eh info table when VRs are saved. We could not
2318 // consolidate these two places into one because there is no easy way
2319 // to access register information in `AIXException` class.
2321 (getNumberOfVRSaved() > 0)) {
2322 // Emit dummy EH Info Table.
2323 OutStreamer->switchSection(getObjFileLowering().getCompactUnwindSection());
2324 MCSymbol *EHInfoLabel =
2326 OutStreamer->emitLabel(EHInfoLabel);
2327
2328 // Version number.
2329 OutStreamer->emitInt32(0);
2330
2331 const DataLayout &DL = MMI->getModule()->getDataLayout();
2332 const unsigned PointerSize = DL.getPointerSize();
2333 // Add necessary paddings in 64 bit mode.
2334 OutStreamer->emitValueToAlignment(Align(PointerSize));
2335
2336 OutStreamer->emitIntValue(0, PointerSize);
2337 OutStreamer->emitIntValue(0, PointerSize);
2338 OutStreamer->switchSection(MF->getSection());
2339 }
2340}
2341
2342void PPCAIXAsmPrinter::emitTracebackTable() {
2343
2344 // Create a symbol for the end of function.
2345 MCSymbol *FuncEnd = createTempSymbol(MF->getName());
2346 OutStreamer->emitLabel(FuncEnd);
2347
2348 OutStreamer->AddComment("Traceback table begin");
2349 // Begin with a fullword of zero.
2350 OutStreamer->emitIntValueInHexWithPadding(0, 4 /*size*/);
2351
2352 SmallString<128> CommentString;
2353 raw_svector_ostream CommentOS(CommentString);
2354
2355 auto EmitComment = [&]() {
2356 OutStreamer->AddComment(CommentOS.str());
2357 CommentString.clear();
2358 };
2359
2360 auto EmitCommentAndValue = [&](uint64_t Value, int Size) {
2361 EmitComment();
2362 OutStreamer->emitIntValueInHexWithPadding(Value, Size);
2363 };
2364
2365 unsigned int Version = 0;
2366 CommentOS << "Version = " << Version;
2367 EmitCommentAndValue(Version, 1);
2368
2369 // There is a lack of information in the IR to assist with determining the
2370 // source language. AIX exception handling mechanism would only search for
2371 // personality routine and LSDA area when such language supports exception
2372 // handling. So to be conservatively correct and allow runtime to do its job,
2373 // we need to set it to C++ for now.
2374 TracebackTable::LanguageID LanguageIdentifier =
2376
2377 CommentOS << "Language = "
2378 << getNameForTracebackTableLanguageId(LanguageIdentifier);
2379 EmitCommentAndValue(LanguageIdentifier, 1);
2380
2381 // This is only populated for the third and fourth bytes.
2382 uint32_t FirstHalfOfMandatoryField = 0;
2383
2384 // Emit the 3rd byte of the mandatory field.
2385
2386 // We always set traceback offset bit to true.
2387 FirstHalfOfMandatoryField |= TracebackTable::HasTraceBackTableOffsetMask;
2388
2389 const PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
2390 const MachineRegisterInfo &MRI = MF->getRegInfo();
2391
2392 // Check the function uses floating-point processor instructions or not
2393 for (unsigned Reg = PPC::F0; Reg <= PPC::F31; ++Reg) {
2394 if (MRI.isPhysRegUsed(Reg, /* SkipRegMaskTest */ true)) {
2395 FirstHalfOfMandatoryField |= TracebackTable::IsFloatingPointPresentMask;
2396 break;
2397 }
2398 }
2399
2400#define GENBOOLCOMMENT(Prefix, V, Field) \
2401 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
2402 << #Field
2403
2404#define GENVALUECOMMENT(PrefixAndName, V, Field) \
2405 CommentOS << (PrefixAndName) << " = " \
2406 << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
2407 (TracebackTable::Field##Shift))
2408
2409 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsGlobalLinkage);
2410 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);
2411 EmitComment();
2412
2413 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasTraceBackTableOffset);
2414 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsInternalProcedure);
2415 EmitComment();
2416
2417 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasControlledStorage);
2418 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsTOCless);
2419 EmitComment();
2420
2421 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsFloatingPointPresent);
2422 EmitComment();
2423 GENBOOLCOMMENT("", FirstHalfOfMandatoryField,
2424 IsFloatingPointOperationLogOrAbortEnabled);
2425 EmitComment();
2426
2427 OutStreamer->emitIntValueInHexWithPadding(
2428 (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2429
2430 // Set the 4th byte of the mandatory field.
2431 FirstHalfOfMandatoryField |= TracebackTable::IsFunctionNamePresentMask;
2432
2433 const PPCRegisterInfo *RegInfo = Subtarget->getRegisterInfo();
2434 Register FrameReg = RegInfo->getFrameRegister(*MF);
2435 if (FrameReg == (Subtarget->isPPC64() ? PPC::X31 : PPC::R31))
2436 FirstHalfOfMandatoryField |= TracebackTable::IsAllocaUsedMask;
2437
2438 const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
2439 if (!MustSaveCRs.empty())
2440 FirstHalfOfMandatoryField |= TracebackTable::IsCRSavedMask;
2441
2442 if (FI->mustSaveLR())
2443 FirstHalfOfMandatoryField |= TracebackTable::IsLRSavedMask;
2444
2445 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsInterruptHandler);
2446 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);
2447 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsAllocaUsed);
2448 EmitComment();
2449 GENVALUECOMMENT("OnConditionDirective", FirstHalfOfMandatoryField,
2450 OnConditionDirective);
2451 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsCRSaved);
2452 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsLRSaved);
2453 EmitComment();
2454 OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),
2455 1);
2456
2457 // Set the 5th byte of mandatory field.
2458 uint32_t SecondHalfOfMandatoryField = 0;
2459
2460 SecondHalfOfMandatoryField |= MF->getFrameInfo().getStackSize()
2462 : 0;
2463
2464 uint32_t FPRSaved = 0;
2465 for (unsigned Reg = PPC::F14; Reg <= PPC::F31; ++Reg) {
2466 if (MRI.isPhysRegModified(Reg)) {
2467 FPRSaved = PPC::F31 - Reg + 1;
2468 break;
2469 }
2470 }
2471 SecondHalfOfMandatoryField |= (FPRSaved << TracebackTable::FPRSavedShift) &
2473 GENBOOLCOMMENT("", SecondHalfOfMandatoryField, IsBackChainStored);
2474 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, IsFixup);
2475 GENVALUECOMMENT(", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
2476 EmitComment();
2477 OutStreamer->emitIntValueInHexWithPadding(
2478 (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
2479
2480 // Set the 6th byte of mandatory field.
2481
2482 // Check whether has Vector Instruction,We only treat instructions uses vector
2483 // register as vector instructions.
2484 bool HasVectorInst = false;
2485 for (unsigned Reg = PPC::V0; Reg <= PPC::V31; ++Reg)
2486 if (MRI.isPhysRegUsed(Reg, /* SkipRegMaskTest */ true)) {
2487 // Has VMX instruction.
2488 HasVectorInst = true;
2489 break;
2490 }
2491
2492 if (FI->hasVectorParms() || HasVectorInst)
2493 SecondHalfOfMandatoryField |= TracebackTable::HasVectorInfoMask;
2494
2495 uint16_t NumOfVRSaved = getNumberOfVRSaved();
2496 bool ShouldEmitEHBlock =
2498
2499 if (ShouldEmitEHBlock)
2500 SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask;
2501
2502 uint32_t GPRSaved = 0;
2503
2504 // X13 is reserved under 64-bit environment.
2505 unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13;
2506 unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31;
2507
2508 for (unsigned Reg = GPRBegin; Reg <= GPREnd; ++Reg) {
2509 if (MRI.isPhysRegModified(Reg)) {
2510 GPRSaved = GPREnd - Reg + 1;
2511 break;
2512 }
2513 }
2514
2515 SecondHalfOfMandatoryField |= (GPRSaved << TracebackTable::GPRSavedShift) &
2517
2518 GENBOOLCOMMENT("", SecondHalfOfMandatoryField, HasExtensionTable);
2519 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasVectorInfo);
2520 GENVALUECOMMENT(", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
2521 EmitComment();
2522 OutStreamer->emitIntValueInHexWithPadding(
2523 (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
2524
2525 // Set the 7th byte of mandatory field.
2526 uint32_t NumberOfFixedParms = FI->getFixedParmsNum();
2527 SecondHalfOfMandatoryField |=
2528 (NumberOfFixedParms << TracebackTable::NumberOfFixedParmsShift) &
2530 GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField,
2531 NumberOfFixedParms);
2532 EmitComment();
2533 OutStreamer->emitIntValueInHexWithPadding(
2534 (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2535
2536 // Set the 8th byte of mandatory field.
2537
2538 // Always set parameter on stack.
2539 SecondHalfOfMandatoryField |= TracebackTable::HasParmsOnStackMask;
2540
2541 uint32_t NumberOfFPParms = FI->getFloatingPointParmsNum();
2542 SecondHalfOfMandatoryField |=
2545
2546 GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField,
2547 NumberOfFloatingPointParms);
2548 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasParmsOnStack);
2549 EmitComment();
2550 OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
2551 1);
2552
2553 // Generate the optional fields of traceback table.
2554
2555 // Parameter type.
2556 if (NumberOfFixedParms || NumberOfFPParms) {
2557 uint32_t ParmsTypeValue = FI->getParmsType();
2558
2559 Expected<SmallString<32>> ParmsType =
2560 FI->hasVectorParms()
2562 ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
2563 FI->getVectorParmsNum())
2564 : XCOFF::parseParmsType(ParmsTypeValue, NumberOfFixedParms,
2565 NumberOfFPParms);
2566
2567 assert(ParmsType && toString(ParmsType.takeError()).c_str());
2568 if (ParmsType) {
2569 CommentOS << "Parameter type = " << ParmsType.get();
2570 EmitComment();
2571 }
2572 OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
2573 sizeof(ParmsTypeValue));
2574 }
2575 // Traceback table offset.
2576 OutStreamer->AddComment("Function size");
2577 if (FirstHalfOfMandatoryField & TracebackTable::HasTraceBackTableOffsetMask) {
2578 MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
2579 &(MF->getFunction()), TM);
2580 OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
2581 }
2582
2583 // Since we unset the Int_Handler.
2584 if (FirstHalfOfMandatoryField & TracebackTable::IsInterruptHandlerMask)
2585 report_fatal_error("Hand_Mask not implement yet");
2586
2587 if (FirstHalfOfMandatoryField & TracebackTable::HasControlledStorageMask)
2588 report_fatal_error("Ctl_Info not implement yet");
2589
2590 if (FirstHalfOfMandatoryField & TracebackTable::IsFunctionNamePresentMask) {
2591 StringRef Name = MF->getName().substr(0, INT16_MAX);
2592 int16_t NameLength = Name.size();
2593 CommentOS << "Function name len = "
2594 << static_cast<unsigned int>(NameLength);
2595 EmitCommentAndValue(NameLength, 2);
2596 OutStreamer->AddComment("Function Name");
2597 OutStreamer->emitBytes(Name);
2598 }
2599
2600 if (FirstHalfOfMandatoryField & TracebackTable::IsAllocaUsedMask) {
2601 uint8_t AllocReg = XCOFF::AllocRegNo;
2602 OutStreamer->AddComment("AllocaUsed");
2603 OutStreamer->emitIntValueInHex(AllocReg, sizeof(AllocReg));
2604 }
2605
2606 if (SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) {
2607 uint16_t VRData = 0;
2608 if (NumOfVRSaved) {
2609 // Number of VRs saved.
2610 VRData |= (NumOfVRSaved << TracebackTable::NumberOfVRSavedShift) &
2612 // This bit is supposed to set only when the special register
2613 // VRSAVE is saved on stack.
2614 // However, IBM XL compiler sets the bit when any vector registers
2615 // are saved on the stack. We will follow XL's behavior on AIX
2616 // so that we don't get surprise behavior change for C code.
2618 }
2619
2620 // Set has_varargs.
2621 if (FI->getVarArgsFrameIndex())
2623
2624 // Vector parameters number.
2625 unsigned VectorParmsNum = FI->getVectorParmsNum();
2626 VRData |= (VectorParmsNum << TracebackTable::NumberOfVectorParmsShift) &
2628
2629 if (HasVectorInst)
2631
2632 GENVALUECOMMENT("NumOfVRsSaved", VRData, NumberOfVRSaved);
2633 GENBOOLCOMMENT(", ", VRData, IsVRSavedOnStack);
2634 GENBOOLCOMMENT(", ", VRData, HasVarArgs);
2635 EmitComment();
2636 OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
2637
2638 GENVALUECOMMENT("NumOfVectorParams", VRData, NumberOfVectorParms);
2639 GENBOOLCOMMENT(", ", VRData, HasVMXInstruction);
2640 EmitComment();
2641 OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
2642
2643 uint32_t VecParmTypeValue = FI->getVecExtParmsType();
2644
2645 Expected<SmallString<32>> VecParmsType =
2646 XCOFF::parseVectorParmsType(VecParmTypeValue, VectorParmsNum);
2647 assert(VecParmsType && toString(VecParmsType.takeError()).c_str());
2648 if (VecParmsType) {
2649 CommentOS << "Vector Parameter type = " << VecParmsType.get();
2650 EmitComment();
2651 }
2652 OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
2653 sizeof(VecParmTypeValue));
2654 // Padding 2 bytes.
2655 CommentOS << "Padding";
2656 EmitCommentAndValue(0, 2);
2657 }
2658
2659 uint8_t ExtensionTableFlag = 0;
2660 if (SecondHalfOfMandatoryField & TracebackTable::HasExtensionTableMask) {
2661 if (ShouldEmitEHBlock)
2662 ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
2665 ExtensionTableFlag |= ExtendedTBTableFlag::TB_SSP_CANARY;
2666
2667 CommentOS << "ExtensionTableFlag = "
2668 << getExtendedTBTableFlagString(ExtensionTableFlag);
2669 EmitCommentAndValue(ExtensionTableFlag, sizeof(ExtensionTableFlag));
2670 }
2671
2672 if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
2673 auto &Ctx = OutStreamer->getContext();
2674 MCSymbol *EHInfoSym =
2676 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym, TOCType_EHBlock);
2677 const MCSymbol *TOCBaseSym = static_cast<const MCSectionXCOFF *>(
2678 getObjFileLowering().getTOCBaseSection())
2679 ->getQualNameSymbol();
2680 const MCExpr *Exp =
2682 MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx);
2683
2684 const DataLayout &DL = getDataLayout();
2685 OutStreamer->emitValueToAlignment(Align(4));
2686 OutStreamer->AddComment("EHInfo Table");
2687 OutStreamer->emitValue(Exp, DL.getPointerSize());
2688 }
2689#undef GENBOOLCOMMENT
2690#undef GENVALUECOMMENT
2691}
2692
2694 return GV->hasAppendingLinkage() &&
2696 // TODO: Linker could still eliminate the GV if we just skip
2697 // handling llvm.used array. Skipping them for now until we or the
2698 // AIX OS team come up with a good solution.
2699 .Case("llvm.used", true)
2700 // It's correct to just skip llvm.compiler.used array here.
2701 .Case("llvm.compiler.used", true)
2702 .Default(false);
2703}
2704
2706 return StringSwitch<bool>(GV->getName())
2707 .Cases({"llvm.global_ctors", "llvm.global_dtors"}, true)
2708 .Default(false);
2709}
2710
2711uint64_t PPCAIXAsmPrinter::getAliasOffset(const Constant *C) {
2712 if (auto *GA = dyn_cast<GlobalAlias>(C))
2713 return getAliasOffset(GA->getAliasee());
2714 if (auto *CE = dyn_cast<ConstantExpr>(C)) {
2715 const MCExpr *LowC = lowerConstant(CE);
2716 const MCBinaryExpr *CBE = dyn_cast<MCBinaryExpr>(LowC);
2717 if (!CBE)
2718 return 0;
2719 if (CBE->getOpcode() != MCBinaryExpr::Add)
2720 report_fatal_error("Only adding an offset is supported now.");
2721 auto *RHS = dyn_cast<MCConstantExpr>(CBE->getRHS());
2722 if (!RHS)
2723 report_fatal_error("Unable to get the offset of alias.");
2724 return RHS->getValue();
2725 }
2726 return 0;
2727}
2728
2729static void tocDataChecks(unsigned PointerSize, const GlobalVariable *GV) {
2730 // TODO: These asserts should be updated as more support for the toc data
2731 // transformation is added (struct support, etc.).
2732 assert(
2733 PointerSize >= GV->getAlign().valueOrOne().value() &&
2734 "GlobalVariables with an alignment requirement stricter than TOC entry "
2735 "size not supported by the toc data transformation.");
2736
2737 Type *GVType = GV->getValueType();
2738 assert(GVType->isSized() && "A GlobalVariable's size must be known to be "
2739 "supported by the toc data transformation.");
2740 if (GV->getDataLayout().getTypeSizeInBits(GVType) >
2741 PointerSize * 8)
2743 "A GlobalVariable with size larger than a TOC entry is not currently "
2744 "supported by the toc data transformation.");
2745 if (GV->hasPrivateLinkage())
2746 report_fatal_error("A GlobalVariable with private linkage is not "
2747 "currently supported by the toc data transformation.");
2748}
2749
2750void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
2751 // Special LLVM global arrays have been handled at the initialization.
2753 return;
2754
2755 // Ignore non-emitted data.
2756 if (GV->getSection() == "llvm.metadata")
2757 return;
2758
2759 // If the Global Variable has the toc-data attribute, it needs to be emitted
2760 // when we emit the .toc section.
2761 if (GV->hasAttribute("toc-data")) {
2762 unsigned PointerSize = GV->getDataLayout().getPointerSize();
2763 tocDataChecks(PointerSize, GV);
2764 TOCDataGlobalVars.push_back(GV);
2765 return;
2766 }
2767
2768 emitGlobalVariableHelper(GV);
2769}
2770
2771void PPCAIXAsmPrinter::emitGlobalVariableHelper(const GlobalVariable *GV) {
2772 assert(!GV->getName().starts_with("llvm.") &&
2773 "Unhandled intrinsic global variable.");
2774
2775 if (GV->hasComdat())
2776 report_fatal_error("COMDAT not yet supported by AIX.");
2777
2778 auto *GVSym = static_cast<MCSymbolXCOFF *>(getSymbol(GV));
2779
2780 if (GV->isDeclarationForLinker()) {
2781 emitLinkage(GV, GVSym);
2782 return;
2783 }
2784
2785 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
2786 if (!GVKind.isGlobalWriteableData() && !GVKind.isReadOnly() &&
2787 !GVKind.isThreadLocal()) // Checks for both ThreadData and ThreadBSS.
2788 report_fatal_error("Encountered a global variable kind that is "
2789 "not supported yet.");
2790
2791 // Print GV in verbose mode
2792 if (isVerbose()) {
2793 if (GV->hasInitializer()) {
2794 GV->printAsOperand(OutStreamer->getCommentOS(),
2795 /*PrintType=*/false, GV->getParent());
2796 OutStreamer->getCommentOS() << '\n';
2797 }
2798 }
2799
2800 auto *Csect = static_cast<MCSectionXCOFF *>(
2801 getObjFileLowering().SectionForGlobal(GV, GVKind, TM));
2802
2803 // Switch to the containing csect.
2804 OutStreamer->switchSection(Csect);
2805
2806 if (GV->hasMetadata(LLVMContext::MD_implicit_ref)) {
2807 emitRefMetadata(GV);
2808 }
2809
2810 const DataLayout &DL = GV->getDataLayout();
2811
2812 // Handle common and zero-initialized local symbols.
2813 if (GV->hasCommonLinkage() || GVKind.isBSSLocal() ||
2814 GVKind.isThreadBSSLocal()) {
2815 Align Alignment = GV->getAlign().value_or(DL.getPreferredAlign(GV));
2816 uint64_t Size = DL.getTypeAllocSize(GV->getValueType());
2817 GVSym->setStorageClass(
2819
2820 if (GVKind.isBSSLocal() && Csect->getMappingClass() == XCOFF::XMC_TD) {
2821 OutStreamer->emitZeros(Size);
2822 } else if (GVKind.isBSSLocal() || GVKind.isThreadBSSLocal()) {
2823 assert(Csect->getMappingClass() != XCOFF::XMC_TD &&
2824 "BSS local toc-data already handled and TLS variables "
2825 "incompatible with XMC_TD");
2826 OutStreamer->emitXCOFFLocalCommonSymbol(
2827 OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()), Size,
2828 GVSym, Alignment);
2829 } else {
2830 OutStreamer->emitCommonSymbol(GVSym, Size, Alignment);
2831 }
2832 return;
2833 }
2834
2835 MCSymbol *EmittedInitSym = GVSym;
2836
2837 // Emit linkage for the global variable and its aliases.
2838 emitLinkage(GV, EmittedInitSym);
2839 for (const GlobalAlias *GA : GOAliasMap[GV])
2840 emitLinkage(GA, getSymbol(GA));
2841
2842 emitAlignment(getGVAlignment(GV, DL), GV);
2843
2844 // When -fdata-sections is enabled, every GlobalVariable will
2845 // be put into its own csect; therefore, label is not necessary here.
2846 if (!TM.getDataSections() || GV->hasSection()) {
2847 if (Csect->getMappingClass() != XCOFF::XMC_TD)
2848 OutStreamer->emitLabel(EmittedInitSym);
2849 }
2850
2851 // No alias to emit.
2852 if (!GOAliasMap[GV].size()) {
2853 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer());
2854 return;
2855 }
2856
2857 // Aliases with the same offset should be aligned. Record the list of aliases
2858 // associated with the offset.
2859 AliasMapTy AliasList;
2860 for (const GlobalAlias *GA : GOAliasMap[GV])
2861 AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);
2862
2863 // Emit alias label and element value for global variable.
2864 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer(),
2865 &AliasList);
2866}
2867
2868void PPCAIXAsmPrinter::emitFunctionDescriptor() {
2869 const DataLayout &DL = getDataLayout();
2870 const unsigned PointerSize = DL.getPointerSizeInBits() == 64 ? 8 : 4;
2871
2872 MCSectionSubPair Current = OutStreamer->getCurrentSection();
2873 // Emit function descriptor.
2874 OutStreamer->switchSection(
2875 static_cast<MCSymbolXCOFF *>(CurrentFnDescSym)->getRepresentedCsect());
2876
2877 // Emit aliasing label for function descriptor csect.
2878 for (const GlobalAlias *Alias : GOAliasMap[&MF->getFunction()])
2879 OutStreamer->emitLabel(getSymbol(Alias));
2880
2881 // Emit function entry point address.
2882 OutStreamer->emitValue(MCSymbolRefExpr::create(CurrentFnSym, OutContext),
2883 PointerSize);
2884 // Emit TOC base address.
2885 const MCSymbol *TOCBaseSym = static_cast<const MCSectionXCOFF *>(
2886 getObjFileLowering().getTOCBaseSection())
2887 ->getQualNameSymbol();
2888 OutStreamer->emitValue(MCSymbolRefExpr::create(TOCBaseSym, OutContext),
2889 PointerSize);
2890 // Emit a null environment pointer.
2891 OutStreamer->emitIntValue(0, PointerSize);
2892
2893 OutStreamer->switchSection(Current.first, Current.second);
2894}
2895
2896void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2897 // For functions without user defined section, it's not necessary to emit the
2898 // label when we have individual function in its own csect.
2899 if (!TM.getFunctionSections() || MF->getFunction().hasSection())
2900 PPCAsmPrinter::emitFunctionEntryLabel();
2901
2902 const Function *F = &MF->getFunction();
2903
2904 // Emit aliasing label for function entry point label.
2905 for (const GlobalAlias *Alias : GOAliasMap[F])
2906 OutStreamer->emitLabel(
2907 getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM));
2908
2909 if (F->hasMetadata(LLVMContext::MD_implicit_ref)) {
2910 emitRefMetadata(F);
2911 }
2912}
2913
2914void PPCAIXAsmPrinter::emitPGORefs(Module &M) {
2915 if (!OutContext.hasXCOFFSection(
2916 "__llvm_prf_cnts",
2917 XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD)))
2918 return;
2919
2920 // When inside a csect `foo`, a .ref directive referring to a csect `bar`
2921 // translates into a relocation entry from `foo` to` bar`. The referring
2922 // csect, `foo`, is identified by its address. If multiple csects have the
2923 // same address (because one or more of them are zero-length), the referring
2924 // csect cannot be determined. Hence, we don't generate the .ref directives
2925 // if `__llvm_prf_cnts` is an empty section.
2926 bool HasNonZeroLengthPrfCntsSection = false;
2927 const DataLayout &DL = M.getDataLayout();
2928 for (GlobalVariable &GV : M.globals())
2929 if (GV.hasSection() && GV.getSection() == "__llvm_prf_cnts" &&
2930 DL.getTypeAllocSize(GV.getValueType()) > 0) {
2931 HasNonZeroLengthPrfCntsSection = true;
2932 break;
2933 }
2934
2935 if (HasNonZeroLengthPrfCntsSection) {
2936 MCSection *CntsSection = OutContext.getXCOFFSection(
2937 "__llvm_prf_cnts", SectionKind::getData(),
2938 XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD),
2939 /*MultiSymbolsAllowed*/ true);
2940
2941 OutStreamer->switchSection(CntsSection);
2942 if (OutContext.hasXCOFFSection(
2943 "__llvm_prf_data",
2944 XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD))) {
2945 MCSymbol *S = OutContext.getOrCreateSymbol("__llvm_prf_data[RW]");
2946 OutStreamer->emitXCOFFRefDirective(S);
2947 }
2948 if (OutContext.hasXCOFFSection(
2949 "__llvm_prf_names",
2950 XCOFF::CsectProperties(XCOFF::XMC_RO, XCOFF::XTY_SD))) {
2951 MCSymbol *S = OutContext.getOrCreateSymbol("__llvm_prf_names[RO]");
2952 OutStreamer->emitXCOFFRefDirective(S);
2953 }
2954 if (OutContext.hasXCOFFSection(
2955 "__llvm_prf_vnds",
2956 XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD))) {
2957 MCSymbol *S = OutContext.getOrCreateSymbol("__llvm_prf_vnds[RW]");
2958 OutStreamer->emitXCOFFRefDirective(S);
2959 }
2960 }
2961}
2962
2963void PPCAIXAsmPrinter::emitGCOVRefs() {
2964 if (!OutContext.hasXCOFFSection(
2965 "__llvm_gcov_ctr_section",
2966 XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD)))
2967 return;
2968
2969 MCSection *CtrSection = OutContext.getXCOFFSection(
2970 "__llvm_gcov_ctr_section", SectionKind::getData(),
2971 XCOFF::CsectProperties(XCOFF::XMC_RW, XCOFF::XTY_SD),
2972 /*MultiSymbolsAllowed*/ true);
2973
2974 OutStreamer->switchSection(CtrSection);
2975 const XCOFF::StorageMappingClass MappingClass =
2976 TM.Options.XCOFFReadOnlyPointers ? XCOFF::XMC_RO : XCOFF::XMC_RW;
2977 if (OutContext.hasXCOFFSection(
2978 "__llvm_covinit",
2979 XCOFF::CsectProperties(MappingClass, XCOFF::XTY_SD))) {
2980 const char *SymbolStr = TM.Options.XCOFFReadOnlyPointers
2981 ? "__llvm_covinit[RO]"
2982 : "__llvm_covinit[RW]";
2983 MCSymbol *S = OutContext.getOrCreateSymbol(SymbolStr);
2984 OutStreamer->emitXCOFFRefDirective(S);
2985 }
2986}
2987
2988void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
2989 // If there are no functions and there are no toc-data definitions in this
2990 // module, we will never need to reference the TOC base.
2991 if (M.empty() && TOCDataGlobalVars.empty())
2992 return;
2993
2994 emitPGORefs(M);
2995 emitGCOVRefs();
2996
2997 // Switch to section to emit TOC base.
2998 OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());
2999
3000 PPCTargetStreamer *TS =
3001 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
3002
3003 for (auto &I : TOC) {
3004 MCSectionXCOFF *TCEntry;
3005 // Setup the csect for the current TC entry. If the variant kind is
3006 // VK_AIX_TLSGDM the entry represents the region handle, we create a
3007 // new symbol to prefix the name with a dot.
3008 // If TLS model opt is turned on, create a new symbol to prefix the name
3009 // with a dot.
3010 if (I.first.second == PPC::S_AIX_TLSGDM ||
3011 (Subtarget->hasAIXShLibTLSModelOpt() &&
3012 I.first.second == PPC::S_AIX_TLSLD)) {
3013 SmallString<128> Name;
3014 StringRef Prefix = ".";
3015 Name += Prefix;
3016 Name += static_cast<const MCSymbolXCOFF *>(I.first.first)
3017 ->getSymbolTableName();
3018 MCSymbol *S = OutContext.getOrCreateSymbol(Name);
3019 TCEntry = static_cast<MCSectionXCOFF *>(
3020 getObjFileLowering().getSectionForTOCEntry(S, TM));
3021 } else {
3022 TCEntry = static_cast<MCSectionXCOFF *>(
3023 getObjFileLowering().getSectionForTOCEntry(I.first.first, TM));
3024 }
3025 OutStreamer->switchSection(TCEntry);
3026
3027 OutStreamer->emitLabel(I.second);
3028 TS->emitTCEntry(*I.first.first, I.first.second);
3029 }
3030
3031 // Traverse the list of global variables twice, emitting all of the
3032 // non-common global variables before the common ones, as emitting a
3033 // .comm directive changes the scope from .toc to the common symbol.
3034 for (const auto *GV : TOCDataGlobalVars) {
3035 if (!GV->hasCommonLinkage())
3036 emitGlobalVariableHelper(GV);
3037 }
3038 for (const auto *GV : TOCDataGlobalVars) {
3039 if (GV->hasCommonLinkage())
3040 emitGlobalVariableHelper(GV);
3041 }
3042}
3043
3044bool PPCAIXAsmPrinter::doInitialization(Module &M) {
3045 const bool Result = PPCAsmPrinter::doInitialization(M);
3046
3047 // Emit the .machine directive on AIX.
3048 const Triple &Target = TM.getTargetTriple();
3050 // Walk through the "target-cpu" attribute of functions and use the newest
3051 // level as the CPU of the module.
3052 for (auto &F : M) {
3053 XCOFF::CFileCpuId FunCpuId =
3054 XCOFF::getCpuID(TM.getSubtargetImpl(F)->getCPU());
3055 if (FunCpuId > TargetCpuId)
3056 TargetCpuId = FunCpuId;
3057 }
3058 // If there is no "target-cpu" attribute within the functions, take the
3059 // "-mcpu" value. If both are omitted, use getNormalizedPPCTargetCPU() to
3060 // determine the default CPU.
3061 if (!TargetCpuId) {
3062 StringRef TargetCPU = TM.getTargetCPU();
3063 TargetCpuId = XCOFF::getCpuID(
3064 TargetCPU.empty() ? PPC::getNormalizedPPCTargetCPU(Target) : TargetCPU);
3065 }
3066
3067 PPCTargetStreamer *TS =
3068 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
3069 TS->emitMachine(XCOFF::getTCPUString(TargetCpuId));
3070
3071 auto setCsectAlignment = [this](const GlobalObject *GO) {
3072 // Declarations have 0 alignment which is set by default.
3073 if (GO->isDeclarationForLinker())
3074 return;
3075
3076 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);
3077 auto *Csect = static_cast<MCSectionXCOFF *>(
3078 getObjFileLowering().SectionForGlobal(GO, GOKind, TM));
3079
3080 Align GOAlign = getGVAlignment(GO, GO->getDataLayout());
3081 Csect->ensureMinAlignment(GOAlign);
3082 };
3083
3084 // For all TLS variables, calculate their corresponding addresses and store
3085 // them into TLSVarsToAddressMapping, which will be used to determine whether
3086 // or not local-exec TLS variables require special assembly printing.
3087 uint64_t TLSVarAddress = 0;
3088 auto DL = M.getDataLayout();
3089 for (const auto &G : M.globals()) {
3090 if (G.isThreadLocal() && !G.isDeclaration()) {
3091 TLSVarAddress = alignTo(TLSVarAddress, getGVAlignment(&G, DL));
3092 TLSVarsToAddressMapping[&G] = TLSVarAddress;
3093 TLSVarAddress += DL.getTypeAllocSize(G.getValueType());
3094 }
3095 }
3096
3097 // We need to know, up front, the alignment of csects for the assembly path,
3098 // because once a .csect directive gets emitted, we could not change the
3099 // alignment value on it.
3100 for (const auto &G : M.globals()) {
3102 continue;
3103
3105 // Generate a format indicator and a unique module id to be a part of
3106 // the sinit and sterm function names.
3107 if (FormatIndicatorAndUniqueModId.empty()) {
3108 std::string UniqueModuleId = getUniqueModuleId(&M);
3109 if (UniqueModuleId != "")
3110 // TODO: Use source file full path to generate the unique module id
3111 // and add a format indicator as a part of function name in case we
3112 // will support more than one format.
3113 FormatIndicatorAndUniqueModId = "clang_" + UniqueModuleId.substr(1);
3114 else {
3115 // Use threadId, Pid, and current time as the unique module id when we
3116 // cannot generate one based on a module's strong external symbols.
3117 auto CurTime =
3118 std::chrono::duration_cast<std::chrono::nanoseconds>(
3119 std::chrono::steady_clock::now().time_since_epoch())
3120 .count();
3121 FormatIndicatorAndUniqueModId =
3122 "clangPidTidTime_" + llvm::itostr(sys::Process::getProcessId()) +
3123 "_" + llvm::itostr(llvm::get_threadid()) + "_" +
3124 llvm::itostr(CurTime);
3125 }
3126 }
3127
3128 emitSpecialLLVMGlobal(&G);
3129 continue;
3130 }
3131
3132 setCsectAlignment(&G);
3133 std::optional<CodeModel::Model> OptionalCodeModel = G.getCodeModel();
3134 if (OptionalCodeModel)
3135 setOptionalCodeModel(static_cast<MCSymbolXCOFF *>(getSymbol(&G)),
3136 *OptionalCodeModel);
3137 }
3138
3139 for (const auto &F : M)
3140 setCsectAlignment(&F);
3141
3142 // Construct an aliasing list for each GlobalObject.
3143 for (const auto &Alias : M.aliases()) {
3144 const GlobalObject *Aliasee = Alias.getAliaseeObject();
3145 if (!Aliasee)
3147 "alias without a base object is not yet supported on AIX");
3148
3149 if (Aliasee->hasCommonLinkage()) {
3150 report_fatal_error("Aliases to common variables are not allowed on AIX:"
3151 "\n\tAlias attribute for " +
3152 Alias.getName() + " is invalid because " +
3153 Aliasee->getName() + " is common.",
3154 false);
3155 }
3156
3157 const GlobalVariable *GVar =
3158 dyn_cast_or_null<GlobalVariable>(Alias.getAliaseeObject());
3159 if (GVar) {
3160 std::optional<CodeModel::Model> OptionalCodeModel = GVar->getCodeModel();
3161 if (OptionalCodeModel)
3162 setOptionalCodeModel(static_cast<MCSymbolXCOFF *>(getSymbol(&Alias)),
3163 *OptionalCodeModel);
3164 }
3165
3166 GOAliasMap[Aliasee].push_back(&Alias);
3167 }
3168
3169 return Result;
3170}
3171
3172void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) {
3173 switch (MI->getOpcode()) {
3174 default:
3175 break;
3176 case PPC::TW:
3177 case PPC::TWI:
3178 case PPC::TD:
3179 case PPC::TDI: {
3180 if (MI->getNumOperands() < 5)
3181 break;
3182 const MachineOperand &LangMO = MI->getOperand(3);
3183 const MachineOperand &ReasonMO = MI->getOperand(4);
3184 if (!LangMO.isImm() || !ReasonMO.isImm())
3185 break;
3186 MCSymbol *TempSym = OutContext.createNamedTempSymbol();
3187 OutStreamer->emitLabel(TempSym);
3188 OutStreamer->emitXCOFFExceptDirective(
3189 CurrentFnSym, TempSym, LangMO.getImm(), ReasonMO.getImm(),
3190 Subtarget->isPPC64() ? MI->getMF()->getInstructionCount() * 8
3191 : MI->getMF()->getInstructionCount() * 4,
3192 hasDebugInfo());
3193 break;
3194 }
3195 case PPC::GETtlsMOD32AIX:
3196 case PPC::GETtlsMOD64AIX:
3197 case PPC::GETtlsTpointer32AIX:
3198 case PPC::GETtlsADDR64AIX:
3199 case PPC::GETtlsADDR32AIX: {
3200 // A reference to .__tls_get_mod/.__tls_get_addr/.__get_tpointer is unknown
3201 // to the assembler so we need to emit an external symbol reference.
3202 MCSymbol *TlsGetAddr =
3203 createMCSymbolForTlsGetAddr(OutContext, MI->getOpcode());
3204 ExtSymSDNodeSymbols.insert(TlsGetAddr);
3205 break;
3206 }
3207 case PPC::BL8:
3208 case PPC::BL:
3209 case PPC::BL8_NOP:
3210 case PPC::BL_NOP: {
3211 const MachineOperand &MO = MI->getOperand(0);
3212 if (MO.isSymbol()) {
3213 auto *S = static_cast<MCSymbolXCOFF *>(
3214 OutContext.getOrCreateSymbol(MO.getSymbolName()));
3215 ExtSymSDNodeSymbols.insert(S);
3216 }
3217 } break;
3218 case PPC::BL_TLS:
3219 case PPC::BL8_TLS:
3220 case PPC::BL8_TLS_:
3221 case PPC::BL8_NOP_TLS:
3222 report_fatal_error("TLS call not yet implemented");
3223 case PPC::TAILB:
3224 case PPC::TAILB8:
3225 case PPC::TAILBA:
3226 case PPC::TAILBA8:
3227 case PPC::TAILBCTR:
3228 case PPC::TAILBCTR8:
3229 if (MI->getOperand(0).isSymbol())
3230 report_fatal_error("Tail call for extern symbol not yet supported.");
3231 break;
3232 case PPC::DST:
3233 case PPC::DST64:
3234 case PPC::DSTT:
3235 case PPC::DSTT64:
3236 case PPC::DSTST:
3237 case PPC::DSTST64:
3238 case PPC::DSTSTT:
3239 case PPC::DSTSTT64:
3240 EmitToStreamer(
3241 *OutStreamer,
3242 MCInstBuilder(PPC::ORI).addReg(PPC::R0).addReg(PPC::R0).addImm(0));
3243 return;
3244 }
3245 return PPCAsmPrinter::emitInstruction(MI);
3246}
3247
3248bool PPCAIXAsmPrinter::doFinalization(Module &M) {
3249 // Do streamer related finalization for DWARF.
3250 if (hasDebugInfo()) {
3251 // Emit section end. This is used to tell the debug line section where the
3252 // end is for a text section if we don't use .loc to represent the debug
3253 // line.
3254 auto *Sec = OutContext.getObjectFileInfo()->getTextSection();
3255 OutStreamer->switchSectionNoPrint(Sec);
3256 MCSymbol *Sym = Sec->getEndSymbol(OutContext);
3257 OutStreamer->emitLabel(Sym);
3258 }
3259
3260 for (MCSymbol *Sym : ExtSymSDNodeSymbols)
3261 OutStreamer->emitSymbolAttribute(Sym, MCSA_Extern);
3262 return PPCAsmPrinter::doFinalization(M);
3263}
3264
3265static unsigned mapToSinitPriority(int P) {
3266 if (P < 0 || P > 65535)
3267 report_fatal_error("invalid init priority");
3268
3269 if (P <= 20)
3270 return P;
3271
3272 if (P < 81)
3273 return 20 + (P - 20) * 16;
3274
3275 if (P <= 1124)
3276 return 1004 + (P - 81);
3277
3278 if (P < 64512)
3279 return 2047 + (P - 1124) * 33878;
3280
3281 return 2147482625u + (P - 64512);
3282}
3283
3284static std::string convertToSinitPriority(int Priority) {
3285 // This helper function converts clang init priority to values used in sinit
3286 // and sterm functions.
3287 //
3288 // The conversion strategies are:
3289 // We map the reserved clang/gnu priority range [0, 100] into the sinit/sterm
3290 // reserved priority range [0, 1023] by
3291 // - directly mapping the first 21 and the last 20 elements of the ranges
3292 // - linear interpolating the intermediate values with a step size of 16.
3293 //
3294 // We map the non reserved clang/gnu priority range of [101, 65535] into the
3295 // sinit/sterm priority range [1024, 2147483648] by:
3296 // - directly mapping the first and the last 1024 elements of the ranges
3297 // - linear interpolating the intermediate values with a step size of 33878.
3298 unsigned int P = mapToSinitPriority(Priority);
3299
3300 std::string PrioritySuffix;
3301 llvm::raw_string_ostream os(PrioritySuffix);
3302 os << llvm::format_hex_no_prefix(P, 8);
3303 return PrioritySuffix;
3304}
3305
3306void PPCAIXAsmPrinter::emitXXStructorList(const DataLayout &DL,
3307 const Constant *List, bool IsCtor) {
3308 SmallVector<Structor, 8> Structors;
3309 preprocessXXStructorList(DL, List, Structors);
3310 if (Structors.empty())
3311 return;
3312
3313 unsigned Index = 0;
3314 for (Structor &S : Structors) {
3315 if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(S.Func))
3316 S.Func = CE->getOperand(0);
3317
3320 (IsCtor ? llvm::Twine("__sinit") : llvm::Twine("__sterm")) +
3321 llvm::Twine(convertToSinitPriority(S.Priority)) +
3322 llvm::Twine("_", FormatIndicatorAndUniqueModId) +
3323 llvm::Twine("_", llvm::utostr(Index++)),
3324 cast<Function>(S.Func));
3325 }
3326}
3327
3328void PPCAIXAsmPrinter::emitTTypeReference(const GlobalValue *GV,
3329 unsigned Encoding) {
3330 if (GV) {
3331 TOCEntryType GlobalType = TOCType_GlobalInternal;
3336 GlobalType = TOCType_GlobalExternal;
3337 MCSymbol *TypeInfoSym = TM.getSymbol(GV);
3338 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym, GlobalType);
3339 const MCSymbol *TOCBaseSym = static_cast<const MCSectionXCOFF *>(
3340 getObjFileLowering().getTOCBaseSection())
3341 ->getQualNameSymbol();
3342 auto &Ctx = OutStreamer->getContext();
3343 const MCExpr *Exp =
3345 MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx);
3346 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
3347 } else
3348 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
3349}
3350
3351void PPCAIXAsmPrinter::emitRefMetadata(const GlobalObject *GO) {
3353 GO->getMetadata(LLVMContext::MD_implicit_ref, MDs);
3354 assert(MDs.size() && "Expected asscoiated metadata nodes");
3355
3356 for (const MDNode *MD : MDs) {
3357 const ValueAsMetadata *VAM = cast<ValueAsMetadata>(MD->getOperand(0).get());
3358 const GlobalValue *GV = cast<GlobalValue>(VAM->getValue());
3359 MCSymbol *Referenced = TM.getSymbol(GV);
3360 OutStreamer->emitXCOFFRefDirective(Referenced);
3361 }
3362}
3363
3364// Return a pass that prints the PPC assembly code for a MachineFunction to the
3365// given output stream.
3366static AsmPrinter *
3368 std::unique_ptr<MCStreamer> &&Streamer) {
3369 if (tm.getTargetTriple().isOSAIX())
3370 return new PPCAIXAsmPrinter(tm, std::move(Streamer));
3371
3372 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
3373}
3374
3375void PPCAIXAsmPrinter::emitModuleCommandLines(Module &M) {
3376 const NamedMDNode *NMD = M.getNamedMetadata("llvm.commandline");
3377 if (!NMD || !NMD->getNumOperands())
3378 return;
3379
3380 std::string S;
3381 raw_string_ostream RSOS(S);
3382 for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
3383 const MDNode *N = NMD->getOperand(i);
3384 assert(N->getNumOperands() == 1 &&
3385 "llvm.commandline metadata entry can have only one operand");
3386 const MDString *MDS = cast<MDString>(N->getOperand(0));
3387 // Add "@(#)" to support retrieving the command line information with the
3388 // AIX "what" command
3389 RSOS << "@(#)opt " << MDS->getString() << "\n";
3390 RSOS.write('\0');
3391 }
3392 OutStreamer->emitXCOFFCInfoSym(".GCC.command.line", RSOS.str());
3393}
3394
3395char PPCAIXAsmPrinter::ID = 0;
3396
3397INITIALIZE_PASS(PPCAIXAsmPrinter, "ppc-aix-asm-printer",
3398 "AIX PPC Assembly Printer", false, false)
3399
3400// Force static initialization.
3401extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
3402LLVMInitializePowerPCAsmPrinter() {
3411}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
aarch64 promote const
static AMDGPUMCExpr::Specifier getSpecifier(unsigned MOFlags)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:213
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
DXIL Finalize Linkage
dxil translate DXIL Translate Metadata
static bool hasDebugInfo(const MachineFunction *MF)
@ Default
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
#define RegName(no)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)
Machine Check Debug Module
Register Reg
This file implements a map that provides insertion order iteration.
Promote Memory to Register
Definition Mem2Reg.cpp:110
#define P(N)
static void collectTOCStats(PPCAsmPrinter::TOCEntryType Type)
static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV)
static bool isSpecialLLVMGlobalArrayToSkip(const GlobalVariable *GV)
#define GENBOOLCOMMENT(Prefix, V, Field)
static MCSymbol * getMCSymbolForTOCPseudoMO(const MachineOperand &MO, AsmPrinter &AP)
Map a machine operand for a TOC pseudo-machine instruction to its corresponding MCSymbol.
static void setOptionalCodeModel(MCSymbolXCOFF *XSym, CodeModel::Model CM)
static AsmPrinter * createPPCAsmPrinterPass(TargetMachine &tm, std::unique_ptr< MCStreamer > &&Streamer)
static PPCAsmPrinter::TOCEntryType getTOCEntryTypeForMO(const MachineOperand &MO)
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
static std::string convertToSinitPriority(int Priority)
static MCSymbol * createMCSymbolForTlsGetAddr(MCContext &Ctx, unsigned MIOpc)
This helper function creates the TlsGetAddr/TlsGetMod MCSymbol for AIX.
#define GENVALUECOMMENT(PrefixAndName, V, Field)
static unsigned mapToSinitPriority(int P)
static void tocDataChecks(unsigned PointerSize, const GlobalVariable *GV)
static cl::opt< bool > EnableSSPCanaryBitInTB("aix-ssp-tb-bit", cl::init(false), cl::desc("Enable Passing SSP Canary info in Trackback on AIX"), cl::Hidden)
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
Provides a library for accessing information about this process and other processes on the operating ...
static SDValue lowerConstant(SDValue Op, SelectionDAG &DAG, const RISCVSubtarget &Subtarget)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:487
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
This file implements a set that has insertion order iteration characteristics.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:114
Value * RHS
This class is intended to be used as a driving class for all asm writers.
Definition AsmPrinter.h:91
MCSymbol * getSymbol(const GlobalValue *GV) const
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
virtual void SetupMachineFunction(MachineFunction &MF)
This should be called when a new MachineFunction is being processed from runOnMachineFunction.
virtual void emitStartOfAsmFile(Module &)
This virtual method can be overridden by targets that want to emit something at the start of their fi...
Definition AsmPrinter.h:595
MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const
Return the symbol for the specified jump table entry.
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
Definition AsmPrinter.h:441
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
LLVM_ABI unsigned getPointerSize(unsigned AS=0) const
The pointer representation size in bytes, rounded up to a whole number of bytes.
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
Definition DataLayout.h:771
Error takeError()
Take ownership of the stored error.
Definition Error.h:612
reference get()
Returns a reference to the stored T value.
Definition Error.h:582
static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
Definition Globals.cpp:598
StringRef getSection() const
Get the custom section of this global if it has one.
bool hasMetadata() const
Return true if this value has any metadata attached to it.
Definition Value.h:602
bool hasComdat() const
bool hasSection() const
Check if this global has a custom object file section.
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
Definition Value.h:576
LinkageTypes getLinkage() const
bool hasPrivateLinkage() const
ThreadLocalMode getThreadLocalMode() const
bool isDeclarationForLinker() const
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
Definition Globals.cpp:132
bool hasCommonLinkage() const
bool hasAppendingLinkage() const
LinkageTypes
An enumeration for the kinds of linkage for global values.
Definition GlobalValue.h:52
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition GlobalValue.h:54
@ ExternalWeakLinkage
ExternalWeak linkage description.
Definition GlobalValue.h:62
Type * getValueType() const
bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists.
bool hasInitializer() const
Definitions have initializers, declarations don't.
std::optional< CodeModel::Model > getCodeModel() const
Get the custom code model of this global if it has one.
MaybeAlign getAlign() const
Returns the alignment of the given variable.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:343
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition MCExpr.h:449
Opcode getOpcode() const
Get the kind of this binary expression.
Definition MCExpr.h:443
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition MCExpr.h:428
@ Add
Addition.
Definition MCExpr.h:302
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
void addOperand(const MCOperand Op)
Definition MCInst.h:215
void setOpcode(unsigned Op)
Definition MCInst.h:201
const MCOperand & getOperand(unsigned i) const
Definition MCInst.h:210
static MCOperand createExpr(const MCExpr *Val)
Definition MCInst.h:166
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:743
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:214
void setPerSymbolCodeModel(MCSymbolXCOFF::CodeModel Model)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition MCSymbol.cpp:59
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:618
MachineInstrBundleIterator< const MachineInstr > const_iterator
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
MCSection * getSection() const
Returns the Section this function belongs to.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
const BlockAddress * getBlockAddress() const
unsigned getTargetFlags() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
bool isBlockAddress() const
isBlockAddress - Tests if this is a MO_BlockAddress operand.
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
int64_t getOffset() const
Return the offset from the symbol in this operand.
iterator end()
Definition MapVector.h:67
iterator find(const KeyT &Key)
Definition MapVector.h:154
LLVM_ABI MDNode * getOperand(unsigned i) const
LLVM_ABI unsigned getNumOperands() const
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
MCSymbol * getPICOffsetSymbol(MachineFunction &MF) const
const SmallVectorImpl< Register > & getMustSaveCRs() const
unsigned getFloatingPointParmsNum() const
MCSymbol * getGlobalEPSymbol(MachineFunction &MF) const
MCSymbol * getLocalEPSymbol(MachineFunction &MF) const
MCSymbol * getTOCOffsetSymbol(MachineFunction &MF) const
static const char * getRegisterName(MCRegister Reg)
static bool hasTLSFlag(unsigned TF)
Register getFrameRegister(const MachineFunction &MF) const override
bool is32BitELFABI() const
bool isAIXABI() const
const PPCFrameLowering * getFrameLowering() const override
bool isUsingPCRelativeCalls() const
CodeModel::Model getCodeModel(const TargetMachine &TM, const GlobalValue *GV) const
Calculates the effective code model for argument GV.
bool isELFv2ABI() const
const PPCRegisterInfo * getRegisterInfo() const override
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
virtual void emitAbiVersion(int AbiVersion)
virtual void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset)
virtual void emitTCEntry(const MCSymbol &S, PPCMCExpr::Specifier Kind)
virtual void emitMachine(StringRef CPU)
bool isThreadBSSLocal() const
static SectionKind getText()
bool isBSSLocal() const
static SectionKind getData()
bool isThreadLocal() const
bool isReadOnly() const
bool isGlobalWriteableData() const
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:151
void push_back(const T &Elt)
LLVM_ABI void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
LLVM_ABI void recordStackMap(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:573
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:261
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:143
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
StringSwitch & Cases(std::initializer_list< StringLiteral > CaseStrings, T Value)
static bool ShouldSetSSPCanaryBitInTB(const MachineFunction *MF)
static MCSymbol * getEHInfoTableSymbol(const MachineFunction *MF)
static XCOFF::StorageClass getStorageClassForGlobal(const GlobalValue *GV)
static bool ShouldEmitEHBlock(const MachineFunction *MF)
Primary interface to the complete machine description for the target machine.
const Triple & getTargetTriple() const
CodeModel::Model getCodeModel() const
Returns the code model.
bool isOSAIX() const
Tests whether the OS is AIX.
Definition Triple.h:781
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition Type.h:311
Value * getValue() const
Definition Metadata.h:498
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
Definition Value.cpp:963
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
bool hasName() const
Definition Value.h:262
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:322
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
static LLVM_ABI Pid getProcessId()
Get the process's identifier.
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ SHF_ALLOC
Definition ELF.h:1248
@ SHF_WRITE
Definition ELF.h:1245
@ SHT_PROGBITS
Definition ELF.h:1147
Flag
These should be considered private to the implementation of the MCInstrDesc class.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
Definition PPC.h:146
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
Definition PPC.h:197
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
Definition PPC.h:172
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
Definition PPC.h:154
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
Definition PPC.h:150
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
Definition PPC.h:140
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
Definition PPC.h:166
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
Definition PPC.h:135
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
Definition PPC.h:160
LLVM_ABI StringRef getNormalizedPPCTargetCPU(const Triple &T, StringRef CPUName="")
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
const char * stripRegisterPrefix(const char *RegName)
stripRegisterPrefix - This method strips the character prefix from a register name so that only the n...
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
static bool isVRRegister(MCRegister Reg)
static bool isVFRegister(MCRegister Reg)
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:48
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
LLVM_ABI SmallString< 32 > getExtendedTBTableFlagString(uint8_t Flag)
Definition XCOFF.cpp:221
LLVM_ABI XCOFF::CFileCpuId getCpuID(StringRef CPU)
Definition XCOFF.cpp:112
LLVM_ABI Expected< SmallString< 32 > > parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum, unsigned VectorParmsNum)
Definition XCOFF.cpp:247
LLVM_ABI Expected< SmallString< 32 > > parseParmsType(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum)
Definition XCOFF.cpp:169
LLVM_ABI Expected< SmallString< 32 > > parseVectorParmsType(uint32_t Value, unsigned ParmsNum)
Definition XCOFF.cpp:299
@ TCPU_INVALID
Invalid id - assumes POWER for old objects.
Definition XCOFF.h:339
StorageMappingClass
Storage Mapping Class definitions.
Definition XCOFF.h:104
@ XMC_RW
Read Write Data.
Definition XCOFF.h:118
@ XMC_RO
Read Only Constant.
Definition XCOFF.h:107
@ XMC_TD
Scalar data item in the TOC.
Definition XCOFF.h:121
@ XMC_PR
Program Code.
Definition XCOFF.h:106
LLVM_ABI StringRef getTCPUString(XCOFF::CFileCpuId TCPU)
Definition XCOFF.cpp:141
LLVM_ABI StringRef getNameForTracebackTableLanguageId(TracebackTable::LanguageID LangId)
Definition XCOFF.cpp:89
constexpr uint8_t AllocRegNo
Definition XCOFF.h:45
@ XTY_SD
Csect definition for initialized storage.
Definition XCOFF.h:243
@ XTY_ER
External reference.
Definition XCOFF.h:242
initializer< Ty > init(const Ty &Val)
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
@ Offset
Definition DWP.cpp:532
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
Target & getThePPC64LETarget()
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1667
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool LowerPPCMachineOperandToMCOperand(const MachineOperand &MO, MCOperand &OutMO, AsmPrinter &AP)
Target & getThePPC32Target()
std::string utostr(uint64_t X, bool isNeg=false)
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
FunctionAddr VTableAddr uintptr_t uintptr_t Version
Definition InstrProf.h:302
LLVM_ABI std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...
void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:167
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)
format_hex_no_prefix - Output N as a fixed width hexadecimal.
Definition Format.h:204
Target & getThePPC64Target()
LLVM_ABI uint64_t get_threadid()
Return the current thread id, as used in various OS system calls.
Definition Threading.cpp:32
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
DWARFExpression::Operation Op
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
Definition MathExtras.h:554
Target & getThePPC32LETarget()
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1915
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
std::pair< MCSection *, uint32_t > MCSectionSubPair
Definition MCStreamer.h:66
std::string itostr(int64_t X)
@ MCSA_Extern
.extern (XCOFF)
@ MCSA_Invalid
Not a valid directive.
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
#define N
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
Definition Alignment.h:77
std::pair< const MCSymbol *, PPCMCExpr::Specifier > TOCKey
An information struct used to provide DenseMap with the various necessary components for a given valu...
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition Alignment.h:130
static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn)
RegisterAsmPrinter - Register an AsmPrinter implementation for the given target.
static constexpr uint32_t FPRSavedMask
Definition XCOFF.h:437
static constexpr uint16_t NumberOfVRSavedMask
Definition XCOFF.h:467
static constexpr uint8_t NumberOfFloatingPointParmsShift
Definition XCOFF.h:453
static constexpr uint32_t NumberOfFixedParmsMask
Definition XCOFF.h:447
static constexpr uint16_t HasVMXInstructionMask
Definition XCOFF.h:473
static constexpr uint32_t IsLRSavedMask
Definition XCOFF.h:431
static constexpr uint16_t HasVarArgsMask
Definition XCOFF.h:469
static constexpr uint32_t IsAllocaUsedMask
Definition XCOFF.h:428
static constexpr uint16_t IsVRSavedOnStackMask
Definition XCOFF.h:468
static constexpr uint16_t NumberOfVectorParmsMask
Definition XCOFF.h:472
static constexpr uint32_t IsFloatingPointPresentMask
Definition XCOFF.h:421
static constexpr uint32_t FPRSavedShift
Definition XCOFF.h:438
static constexpr uint32_t NumberOfFloatingPointParmsMask
Definition XCOFF.h:451
static constexpr uint32_t HasControlledStorageMask
Definition XCOFF.h:419
static constexpr uint32_t HasExtensionTableMask
Definition XCOFF.h:441
static constexpr uint32_t HasTraceBackTableOffsetMask
Definition XCOFF.h:417
static constexpr uint32_t IsCRSavedMask
Definition XCOFF.h:430
static constexpr uint8_t NumberOfFixedParmsShift
Definition XCOFF.h:448
static constexpr uint32_t GPRSavedMask
Definition XCOFF.h:443
static constexpr uint8_t NumberOfVectorParmsShift
Definition XCOFF.h:474
static constexpr uint32_t HasParmsOnStackMask
Definition XCOFF.h:452
static constexpr uint32_t IsFunctionNamePresentMask
Definition XCOFF.h:427
static constexpr uint32_t IsBackChainStoredMask
Definition XCOFF.h:435
static constexpr uint32_t IsInterruptHandlerMask
Definition XCOFF.h:426
static constexpr uint32_t HasVectorInfoMask
Definition XCOFF.h:442
static constexpr uint8_t NumberOfVRSavedShift
Definition XCOFF.h:470
static constexpr uint32_t GPRSavedShift
Definition XCOFF.h:444