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