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