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