LLVM 17.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
22#include "PPC.h"
23#include "PPCInstrInfo.h"
25#include "PPCSubtarget.h"
26#include "PPCTargetMachine.h"
27#include "PPCTargetStreamer.h"
29#include "llvm/ADT/MapVector.h"
31#include "llvm/ADT/StringRef.h"
32#include "llvm/ADT/Triple.h"
33#include "llvm/ADT/Twine.h"
45#include "llvm/IR/DataLayout.h"
46#include "llvm/IR/GlobalValue.h"
48#include "llvm/IR/Module.h"
49#include "llvm/MC/MCAsmInfo.h"
50#include "llvm/MC/MCContext.h"
52#include "llvm/MC/MCExpr.h"
53#include "llvm/MC/MCInst.h"
57#include "llvm/MC/MCStreamer.h"
58#include "llvm/MC/MCSymbol.h"
59#include "llvm/MC/MCSymbolELF.h"
61#include "llvm/MC/SectionKind.h"
65#include "llvm/Support/Debug.h"
66#include "llvm/Support/Error.h"
72#include <algorithm>
73#include <cassert>
74#include <cstdint>
75#include <memory>
76#include <new>
77
78using namespace llvm;
79using namespace llvm::XCOFF;
80
81#define DEBUG_TYPE "asmprinter"
82
84 "aix-ssp-tb-bit", cl::init(false),
85 cl::desc("Enable Passing SSP Canary info in Trackback on AIX"), cl::Hidden);
86
87// Specialize DenseMapInfo to allow
88// std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind> in DenseMap.
89// This specialization is needed here because that type is used as keys in the
90// map representing TOC entries.
91namespace llvm {
92template <>
93struct DenseMapInfo<std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>> {
94 using TOCKey = std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>;
95
96 static inline TOCKey getEmptyKey() {
98 }
99 static inline TOCKey getTombstoneKey() {
101 }
102 static unsigned getHashValue(const TOCKey &PairVal) {
105 DenseMapInfo<int>::getHashValue(PairVal.second));
106 }
107 static bool isEqual(const TOCKey &A, const TOCKey &B) { return A == B; }
108};
109} // end namespace llvm
110
111namespace {
112
113enum {
114 // GNU attribute tags for PowerPC ABI
115 Tag_GNU_Power_ABI_FP = 4,
116 Tag_GNU_Power_ABI_Vector = 8,
117 Tag_GNU_Power_ABI_Struct_Return = 12,
118
119 // GNU attribute values for PowerPC float ABI, as combination of two parts
120 Val_GNU_Power_ABI_NoFloat = 0b00,
121 Val_GNU_Power_ABI_HardFloat_DP = 0b01,
122 Val_GNU_Power_ABI_SoftFloat_DP = 0b10,
123 Val_GNU_Power_ABI_HardFloat_SP = 0b11,
124
125 Val_GNU_Power_ABI_LDBL_IBM128 = 0b0100,
126 Val_GNU_Power_ABI_LDBL_64 = 0b1000,
127 Val_GNU_Power_ABI_LDBL_IEEE128 = 0b1100,
128};
129
130class PPCAsmPrinter : public AsmPrinter {
131protected:
132 // For TLS on AIX, we need to be able to identify TOC entries of specific
133 // VariantKind so we can add the right relocations when we generate the
134 // entries. So each entry is represented by a pair of MCSymbol and
135 // VariantKind. For example, we need to be able to identify the following
136 // entry as a TLSGD entry so we can add the @m relocation:
137 // .tc .i[TC],i[TL]@m
138 // By default, VK_None is used for the VariantKind.
140 MCSymbol *>
141 TOC;
142 const PPCSubtarget *Subtarget = nullptr;
143
144public:
145 explicit PPCAsmPrinter(TargetMachine &TM,
146 std::unique_ptr<MCStreamer> Streamer)
147 : AsmPrinter(TM, std::move(Streamer)) {}
148
149 StringRef getPassName() const override { return "PowerPC Assembly Printer"; }
150
151 MCSymbol *lookUpOrCreateTOCEntry(const MCSymbol *Sym,
153 MCSymbolRefExpr::VariantKind::VK_None);
154
155 bool doInitialization(Module &M) override {
156 if (!TOC.empty())
157 TOC.clear();
159 }
160
161 void emitInstruction(const MachineInstr *MI) override;
162
163 /// This function is for PrintAsmOperand and PrintAsmMemoryOperand,
164 /// invoked by EmitMSInlineAsmStr and EmitGCCInlineAsmStr only.
165 /// The \p MI would be INLINEASM ONLY.
166 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
167
168 void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
169 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
170 const char *ExtraCode, raw_ostream &O) override;
171 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
172 const char *ExtraCode, raw_ostream &O) override;
173
174 void LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI);
175 void LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI);
176 void EmitTlsCall(const MachineInstr *MI, MCSymbolRefExpr::VariantKind VK);
177 bool runOnMachineFunction(MachineFunction &MF) override {
178 Subtarget = &MF.getSubtarget<PPCSubtarget>();
179 bool Changed = AsmPrinter::runOnMachineFunction(MF);
181 return Changed;
182 }
183};
184
185/// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
186class PPCLinuxAsmPrinter : public PPCAsmPrinter {
187public:
188 explicit PPCLinuxAsmPrinter(TargetMachine &TM,
189 std::unique_ptr<MCStreamer> Streamer)
190 : PPCAsmPrinter(TM, std::move(Streamer)) {}
191
192 StringRef getPassName() const override {
193 return "Linux PPC Assembly Printer";
194 }
195
196 void emitGNUAttributes(Module &M);
197
198 void emitStartOfAsmFile(Module &M) override;
199 void emitEndOfAsmFile(Module &) override;
200
201 void emitFunctionEntryLabel() override;
202
203 void emitFunctionBodyStart() override;
204 void emitFunctionBodyEnd() override;
205 void emitInstruction(const MachineInstr *MI) override;
206};
207
208class PPCAIXAsmPrinter : public PPCAsmPrinter {
209private:
210 /// Symbols lowered from ExternalSymbolSDNodes, we will need to emit extern
211 /// linkage for them in AIX.
212 SmallPtrSet<MCSymbol *, 8> ExtSymSDNodeSymbols;
213
214 /// A format indicator and unique trailing identifier to form part of the
215 /// sinit/sterm function names.
216 std::string FormatIndicatorAndUniqueModId;
217
218 // Record a list of GlobalAlias associated with a GlobalObject.
219 // This is used for AIX's extra-label-at-definition aliasing strategy.
221 GOAliasMap;
222
223 uint16_t getNumberOfVRSaved();
224 void emitTracebackTable();
225
227
228 void emitGlobalVariableHelper(const GlobalVariable *);
229
230 // Get the offset of an alias based on its AliaseeObject.
231 uint64_t getAliasOffset(const Constant *C);
232
233public:
234 PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
235 : PPCAsmPrinter(TM, std::move(Streamer)) {
236 if (MAI->isLittleEndian())
238 "cannot create AIX PPC Assembly Printer for a little-endian target");
239 }
240
241 StringRef getPassName() const override { return "AIX PPC Assembly Printer"; }
242
243 bool doInitialization(Module &M) override;
244
245 void emitXXStructorList(const DataLayout &DL, const Constant *List,
246 bool IsCtor) override;
247
248 void SetupMachineFunction(MachineFunction &MF) override;
249
250 void emitGlobalVariable(const GlobalVariable *GV) override;
251
252 void emitFunctionDescriptor() override;
253
254 void emitFunctionEntryLabel() override;
255
256 void emitFunctionBodyEnd() override;
257
258 void emitPGORefs();
259
260 void emitEndOfAsmFile(Module &) override;
261
262 void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const override;
263
264 void emitInstruction(const MachineInstr *MI) override;
265
266 bool doFinalization(Module &M) override;
267
268 void emitTTypeReference(const GlobalValue *GV, unsigned Encoding) override;
269};
270
271} // end anonymous namespace
272
273void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
274 raw_ostream &O) {
275 // Computing the address of a global symbol, not calling it.
276 const GlobalValue *GV = MO.getGlobal();
277 getSymbol(GV)->print(O, MAI);
278 printOffset(MO.getOffset(), O);
279}
280
281void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
282 raw_ostream &O) {
283 const DataLayout &DL = getDataLayout();
284 const MachineOperand &MO = MI->getOperand(OpNo);
285
286 switch (MO.getType()) {
288 // The MI is INLINEASM ONLY and UseVSXReg is always false.
290
291 // Linux assembler (Others?) does not take register mnemonics.
292 // FIXME - What about special registers used in mfspr/mtspr?
294 return;
295 }
297 O << MO.getImm();
298 return;
299
301 MO.getMBB()->getSymbol()->print(O, MAI);
302 return;
304 O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
305 << MO.getIndex();
306 return;
308 GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
309 return;
311 PrintSymbolOperand(MO, O);
312 return;
313 }
314
315 default:
316 O << "<unknown operand type: " << (unsigned)MO.getType() << ">";
317 return;
318 }
319}
320
321/// PrintAsmOperand - Print out an operand for an inline asm expression.
322///
323bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
324 const char *ExtraCode, raw_ostream &O) {
325 // Does this asm operand have a single letter operand modifier?
326 if (ExtraCode && ExtraCode[0]) {
327 if (ExtraCode[1] != 0) return true; // Unknown modifier.
328
329 switch (ExtraCode[0]) {
330 default:
331 // See if this is a generic print operand
332 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
333 case 'L': // Write second word of DImode reference.
334 // Verify that this operand has two consecutive registers.
335 if (!MI->getOperand(OpNo).isReg() ||
336 OpNo+1 == MI->getNumOperands() ||
337 !MI->getOperand(OpNo+1).isReg())
338 return true;
339 ++OpNo; // Return the high-part.
340 break;
341 case 'I':
342 // Write 'i' if an integer constant, otherwise nothing. Used to print
343 // addi vs add, etc.
344 if (MI->getOperand(OpNo).isImm())
345 O << "i";
346 return false;
347 case 'x':
348 if(!MI->getOperand(OpNo).isReg())
349 return true;
350 // This operand uses VSX numbering.
351 // If the operand is a VMX register, convert it to a VSX register.
352 Register Reg = MI->getOperand(OpNo).getReg();
354 Reg = PPC::VSX32 + (Reg - PPC::V0);
355 else if (PPCInstrInfo::isVFRegister(Reg))
356 Reg = PPC::VSX32 + (Reg - PPC::VF0);
357 const char *RegName;
360 O << RegName;
361 return false;
362 }
363 }
364
365 printOperand(MI, OpNo, O);
366 return false;
367}
368
369// At the moment, all inline asm memory operands are a single register.
370// In any case, the output of this routine should always be just one
371// assembler operand.
372bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
373 const char *ExtraCode,
374 raw_ostream &O) {
375 if (ExtraCode && ExtraCode[0]) {
376 if (ExtraCode[1] != 0) return true; // Unknown modifier.
377
378 switch (ExtraCode[0]) {
379 default: return true; // Unknown modifier.
380 case 'L': // A memory reference to the upper word of a double word op.
381 O << getDataLayout().getPointerSize() << "(";
382 printOperand(MI, OpNo, O);
383 O << ")";
384 return false;
385 case 'y': // A memory reference for an X-form instruction
386 O << "0, ";
387 printOperand(MI, OpNo, O);
388 return false;
389 case 'I':
390 // Write 'i' if an integer constant, otherwise nothing. Used to print
391 // addi vs add, etc.
392 if (MI->getOperand(OpNo).isImm())
393 O << "i";
394 return false;
395 case 'U': // Print 'u' for update form.
396 case 'X': // Print 'x' for indexed form.
397 // FIXME: Currently for PowerPC memory operands are always loaded
398 // into a register, so we never get an update or indexed form.
399 // This is bad even for offset forms, since even if we know we
400 // have a value in -16(r1), we will generate a load into r<n>
401 // and then load from 0(r<n>). Until that issue is fixed,
402 // tolerate 'U' and 'X' but don't output anything.
403 assert(MI->getOperand(OpNo).isReg());
404 return false;
405 }
406 }
407
408 assert(MI->getOperand(OpNo).isReg());
409 O << "0(";
410 printOperand(MI, OpNo, O);
411 O << ")";
412 return false;
413}
414
415/// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
416/// exists for it. If not, create one. Then return a symbol that references
417/// the TOC entry.
418MCSymbol *
419PPCAsmPrinter::lookUpOrCreateTOCEntry(const MCSymbol *Sym,
421 MCSymbol *&TOCEntry = TOC[{Sym, Kind}];
422 if (!TOCEntry)
423 TOCEntry = createTempSymbol("C");
424 return TOCEntry;
425}
426
427void PPCAsmPrinter::LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI) {
428 unsigned NumNOPBytes = MI.getOperand(1).getImm();
429
430 auto &Ctx = OutStreamer->getContext();
431 MCSymbol *MILabel = Ctx.createTempSymbol();
432 OutStreamer->emitLabel(MILabel);
433
434 SM.recordStackMap(*MILabel, MI);
435 assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
436
437 // Scan ahead to trim the shadow.
438 const MachineBasicBlock &MBB = *MI.getParent();
440 ++MII;
441 while (NumNOPBytes > 0) {
442 if (MII == MBB.end() || MII->isCall() ||
443 MII->getOpcode() == PPC::DBG_VALUE ||
444 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
445 MII->getOpcode() == TargetOpcode::STACKMAP)
446 break;
447 ++MII;
448 NumNOPBytes -= 4;
449 }
450
451 // Emit nops.
452 for (unsigned i = 0; i < NumNOPBytes; i += 4)
453 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
454}
455
456// Lower a patchpoint of the form:
457// [<def>], <id>, <numBytes>, <target>, <numArgs>
458void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) {
459 auto &Ctx = OutStreamer->getContext();
460 MCSymbol *MILabel = Ctx.createTempSymbol();
461 OutStreamer->emitLabel(MILabel);
462
463 SM.recordPatchPoint(*MILabel, MI);
464 PatchPointOpers Opers(&MI);
465
466 unsigned EncodedBytes = 0;
467 const MachineOperand &CalleeMO = Opers.getCallTarget();
468
469 if (CalleeMO.isImm()) {
470 int64_t CallTarget = CalleeMO.getImm();
471 if (CallTarget) {
472 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
473 "High 16 bits of call target should be zero.");
474 Register ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
475 EncodedBytes = 0;
476 // Materialize the jump address:
477 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8)
478 .addReg(ScratchReg)
479 .addImm((CallTarget >> 32) & 0xFFFF));
480 ++EncodedBytes;
481 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC)
482 .addReg(ScratchReg)
483 .addReg(ScratchReg)
484 .addImm(32).addImm(16));
485 ++EncodedBytes;
486 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8)
487 .addReg(ScratchReg)
488 .addReg(ScratchReg)
489 .addImm((CallTarget >> 16) & 0xFFFF));
490 ++EncodedBytes;
491 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8)
492 .addReg(ScratchReg)
493 .addReg(ScratchReg)
494 .addImm(CallTarget & 0xFFFF));
495
496 // Save the current TOC pointer before the remote call.
497 int TOCSaveOffset = Subtarget->getFrameLowering()->getTOCSaveOffset();
498 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD)
499 .addReg(PPC::X2)
500 .addImm(TOCSaveOffset)
501 .addReg(PPC::X1));
502 ++EncodedBytes;
503
504 // If we're on ELFv1, then we need to load the actual function pointer
505 // from the function descriptor.
506 if (!Subtarget->isELFv2ABI()) {
507 // Load the new TOC pointer and the function address, but not r11
508 // (needing this is rare, and loading it here would prevent passing it
509 // via a 'nest' parameter.
510 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
511 .addReg(PPC::X2)
512 .addImm(8)
513 .addReg(ScratchReg));
514 ++EncodedBytes;
515 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
516 .addReg(ScratchReg)
517 .addImm(0)
518 .addReg(ScratchReg));
519 ++EncodedBytes;
520 }
521
522 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8)
523 .addReg(ScratchReg));
524 ++EncodedBytes;
525 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8));
526 ++EncodedBytes;
527
528 // Restore the TOC pointer after the call.
529 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
530 .addReg(PPC::X2)
531 .addImm(TOCSaveOffset)
532 .addReg(PPC::X1));
533 ++EncodedBytes;
534 }
535 } else if (CalleeMO.isGlobal()) {
536 const GlobalValue *GValue = CalleeMO.getGlobal();
537 MCSymbol *MOSymbol = getSymbol(GValue);
538 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, OutContext);
539
540 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP)
541 .addExpr(SymVar));
542 EncodedBytes += 2;
543 }
544
545 // Each instruction is 4 bytes.
546 EncodedBytes *= 4;
547
548 // Emit padding.
549 unsigned NumBytes = Opers.getNumPatchBytes();
550 assert(NumBytes >= EncodedBytes &&
551 "Patchpoint can't request size less than the length of a call.");
552 assert((NumBytes - EncodedBytes) % 4 == 0 &&
553 "Invalid number of NOP bytes requested!");
554 for (unsigned i = EncodedBytes; i < NumBytes; i += 4)
555 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
556}
557
558/// This helper function creates the TlsGetAddr MCSymbol for AIX. We will
559/// create the csect and use the qual-name symbol instead of creating just the
560/// external symbol.
562 return Ctx
563 .getXCOFFSection(".__tls_get_addr", SectionKind::getText(),
566}
567
568/// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a
569/// call to __tls_get_addr to the current output stream.
570void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
573 unsigned Opcode = PPC::BL8_NOP_TLS;
574
575 assert(MI->getNumOperands() >= 3 && "Expecting at least 3 operands from MI");
576 if (MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG ||
577 MI->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSLD_PCREL_FLAG) {
579 Opcode = PPC::BL8_NOTOC_TLS;
580 }
581 const Module *M = MF->getFunction().getParent();
582
583 assert(MI->getOperand(0).isReg() &&
584 ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) ||
585 (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) &&
586 "GETtls[ld]ADDR[32] must define GPR3");
587 assert(MI->getOperand(1).isReg() &&
588 ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) ||
589 (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) &&
590 "GETtls[ld]ADDR[32] must read GPR3");
591
592 if (Subtarget->isAIXABI()) {
593 // On AIX, the variable offset should already be in R4 and the region handle
594 // should already be in R3.
595 // For TLSGD, which currently is the only supported access model, we only
596 // need to generate an absolute branch to .__tls_get_addr.
597 Register VarOffsetReg = Subtarget->isPPC64() ? PPC::X4 : PPC::R4;
598 (void)VarOffsetReg;
599 assert(MI->getOperand(2).isReg() &&
600 MI->getOperand(2).getReg() == VarOffsetReg &&
601 "GETtls[ld]ADDR[32] must read GPR4");
602 MCSymbol *TlsGetAddr = createMCSymbolForTlsGetAddr(OutContext);
603 const MCExpr *TlsRef = MCSymbolRefExpr::create(
604 TlsGetAddr, MCSymbolRefExpr::VK_None, OutContext);
605 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BLA).addExpr(TlsRef));
606 return;
607 }
608
609 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol("__tls_get_addr");
610
611 if (Subtarget->is32BitELFABI() && isPositionIndependent())
613
614 const MCExpr *TlsRef =
615 MCSymbolRefExpr::create(TlsGetAddr, Kind, OutContext);
616
617 // Add 32768 offset to the symbol so we follow up the latest GOT/PLT ABI.
618 if (Kind == MCSymbolRefExpr::VK_PLT && Subtarget->isSecurePlt() &&
619 M->getPICLevel() == PICLevel::BigPIC)
621 TlsRef, MCConstantExpr::create(32768, OutContext), OutContext);
622 const MachineOperand &MO = MI->getOperand(2);
623 const GlobalValue *GValue = MO.getGlobal();
624 MCSymbol *MOSymbol = getSymbol(GValue);
625 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
626 EmitToStreamer(*OutStreamer,
627 MCInstBuilder(Subtarget->isPPC64() ? Opcode
628 : (unsigned)PPC::BL_TLS)
629 .addExpr(TlsRef)
630 .addExpr(SymVar));
631}
632
633/// Map a machine operand for a TOC pseudo-machine instruction to its
634/// corresponding MCSymbol.
636 AsmPrinter &AP) {
637 switch (MO.getType()) {
639 return AP.getSymbol(MO.getGlobal());
641 return AP.GetCPISymbol(MO.getIndex());
643 return AP.GetJTISymbol(MO.getIndex());
646 default:
647 llvm_unreachable("Unexpected operand type to get symbol.");
648 }
649}
650
651/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
652/// the current output stream.
653///
654void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
655 PPC_MC::verifyInstructionPredicates(MI->getOpcode(),
656 getSubtargetInfo().getFeatureBits());
657
658 MCInst TmpInst;
659 const bool IsPPC64 = Subtarget->isPPC64();
660 const bool IsAIX = Subtarget->isAIXABI();
661 const Module *M = MF->getFunction().getParent();
662 PICLevel::Level PL = M->getPICLevel();
663
664#ifndef NDEBUG
665 // Validate that SPE and FPU are mutually exclusive in codegen
666 if (!MI->isInlineAsm()) {
667 for (const MachineOperand &MO: MI->operands()) {
668 if (MO.isReg()) {
669 Register Reg = MO.getReg();
670 if (Subtarget->hasSPE()) {
671 if (PPC::F4RCRegClass.contains(Reg) ||
672 PPC::F8RCRegClass.contains(Reg) ||
673 PPC::VFRCRegClass.contains(Reg) ||
674 PPC::VRRCRegClass.contains(Reg) ||
675 PPC::VSFRCRegClass.contains(Reg) ||
676 PPC::VSSRCRegClass.contains(Reg)
677 )
678 llvm_unreachable("SPE targets cannot have FPRegs!");
679 } else {
680 if (PPC::SPERCRegClass.contains(Reg))
681 llvm_unreachable("SPE register found in FPU-targeted code!");
682 }
683 }
684 }
685 }
686#endif
687
688 auto getTOCRelocAdjustedExprForXCOFF = [this](const MCExpr *Expr,
689 ptrdiff_t OriginalOffset) {
690 // Apply an offset to the TOC-based expression such that the adjusted
691 // notional offset from the TOC base (to be encoded into the instruction's D
692 // or DS field) is the signed 16-bit truncation of the original notional
693 // offset from the TOC base.
694 // This is consistent with the treatment used both by XL C/C++ and
695 // by AIX ld -r.
696 ptrdiff_t Adjustment =
697 OriginalOffset - llvm::SignExtend32<16>(OriginalOffset);
699 Expr, MCConstantExpr::create(-Adjustment, OutContext), OutContext);
700 };
701
702 auto getTOCEntryLoadingExprForXCOFF =
703 [IsPPC64, getTOCRelocAdjustedExprForXCOFF,
704 this](const MCSymbol *MOSymbol, const MCExpr *Expr,
706 MCSymbolRefExpr::VariantKind::VK_None) -> const MCExpr * {
707 const unsigned EntryByteSize = IsPPC64 ? 8 : 4;
708 const auto TOCEntryIter = TOC.find({MOSymbol, VK});
709 assert(TOCEntryIter != TOC.end() &&
710 "Could not find the TOC entry for this symbol.");
711 const ptrdiff_t EntryDistanceFromTOCBase =
712 (TOCEntryIter - TOC.begin()) * EntryByteSize;
713 constexpr int16_t PositiveTOCRange = INT16_MAX;
714
715 if (EntryDistanceFromTOCBase > PositiveTOCRange)
716 return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase);
717
718 return Expr;
719 };
720 auto GetVKForMO = [&](const MachineOperand &MO) {
721 // For GD TLS access on AIX, we have two TOC entries for the symbol (one for
722 // the variable offset and the other for the region handle). They are
723 // differentiated by MO_TLSGD_FLAG and MO_TLSGDM_FLAG.
725 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM;
727 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD;
728 return MCSymbolRefExpr::VariantKind::VK_None;
729 };
730
731 // Lower multi-instruction pseudo operations.
732 switch (MI->getOpcode()) {
733 default: break;
734 case TargetOpcode::DBG_VALUE:
735 llvm_unreachable("Should be handled target independently");
736 case TargetOpcode::STACKMAP:
737 return LowerSTACKMAP(SM, *MI);
738 case TargetOpcode::PATCHPOINT:
739 return LowerPATCHPOINT(SM, *MI);
740
741 case PPC::MoveGOTtoLR: {
742 // Transform %lr = MoveGOTtoLR
743 // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
744 // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding
745 // _GLOBAL_OFFSET_TABLE_) has exactly one instruction:
746 // blrl
747 // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local
748 MCSymbol *GOTSymbol =
749 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
750 const MCExpr *OffsExpr =
753 OutContext),
754 MCConstantExpr::create(4, OutContext),
755 OutContext);
756
757 // Emit the 'bl'.
758 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));
759 return;
760 }
761 case PPC::MovePCtoLR:
762 case PPC::MovePCtoLR8: {
763 // Transform %lr = MovePCtoLR
764 // Into this, where the label is the PIC base:
765 // bl L1$pb
766 // L1$pb:
767 MCSymbol *PICBase = MF->getPICBaseSymbol();
768
769 // Emit the 'bl'.
770 EmitToStreamer(*OutStreamer,
771 MCInstBuilder(PPC::BL)
772 // FIXME: We would like an efficient form for this, so we
773 // don't have to do a lot of extra uniquing.
774 .addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));
775
776 // Emit the label.
777 OutStreamer->emitLabel(PICBase);
778 return;
779 }
780 case PPC::UpdateGBR: {
781 // Transform %rd = UpdateGBR(%rt, %ri)
782 // Into: lwz %rt, .L0$poff - .L0$pb(%ri)
783 // add %rd, %rt, %ri
784 // or into (if secure plt mode is on):
785 // addis r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@ha
786 // addi r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@l
787 // Get the offset from the GOT Base Register to the GOT
788 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
789 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
790 unsigned PICR = TmpInst.getOperand(0).getReg();
791 MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
792 M->getPICLevel() == PICLevel::SmallPIC ? "_GLOBAL_OFFSET_TABLE_"
793 : ".LTOC");
794 const MCExpr *PB =
795 MCSymbolRefExpr::create(MF->getPICBaseSymbol(), OutContext);
796
797 const MCExpr *DeltaExpr = MCBinaryExpr::createSub(
798 MCSymbolRefExpr::create(BaseSymbol, OutContext), PB, OutContext);
799
800 const MCExpr *DeltaHi = PPCMCExpr::createHa(DeltaExpr, OutContext);
801 EmitToStreamer(
802 *OutStreamer,
803 MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));
804
805 const MCExpr *DeltaLo = PPCMCExpr::createLo(DeltaExpr, OutContext);
806 EmitToStreamer(
807 *OutStreamer,
808 MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
809 return;
810 } else {
811 MCSymbol *PICOffset =
812 MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol(*MF);
813 TmpInst.setOpcode(PPC::LWZ);
814 const MCExpr *Exp =
816 const MCExpr *PB =
817 MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
819 OutContext);
820 const MCOperand TR = TmpInst.getOperand(1);
821 const MCOperand PICR = TmpInst.getOperand(0);
822
823 // Step 1: lwz %rt, .L$poff - .L$pb(%ri)
824 TmpInst.getOperand(1) =
826 TmpInst.getOperand(0) = TR;
827 TmpInst.getOperand(2) = PICR;
828 EmitToStreamer(*OutStreamer, TmpInst);
829
830 TmpInst.setOpcode(PPC::ADD4);
831 TmpInst.getOperand(0) = PICR;
832 TmpInst.getOperand(1) = TR;
833 TmpInst.getOperand(2) = PICR;
834 EmitToStreamer(*OutStreamer, TmpInst);
835 return;
836 }
837 }
838 case PPC::LWZtoc: {
839 // Transform %rN = LWZtoc @op1, %r2
840 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
841
842 // Change the opcode to LWZ.
843 TmpInst.setOpcode(PPC::LWZ);
844
845 const MachineOperand &MO = MI->getOperand(1);
846 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
847 "Invalid operand for LWZtoc.");
848
849 // Map the operand to its corresponding MCSymbol.
850 const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
851
852 // Create a reference to the GOT entry for the symbol. The GOT entry will be
853 // synthesized later.
854 if (PL == PICLevel::SmallPIC && !IsAIX) {
855 const MCExpr *Exp =
857 OutContext);
858 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
859 EmitToStreamer(*OutStreamer, TmpInst);
860 return;
861 }
862
863 MCSymbolRefExpr::VariantKind VK = GetVKForMO(MO);
864
865 // Otherwise, use the TOC. 'TOCEntry' is a label used to reference the
866 // storage allocated in the TOC which contains the address of
867 // 'MOSymbol'. Said TOC entry will be synthesized later.
868 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol, VK);
869 const MCExpr *Exp =
871
872 // AIX uses the label directly as the lwz displacement operand for
873 // references into the toc section. The displacement value will be generated
874 // relative to the toc-base.
875 if (IsAIX) {
876 assert(
877 TM.getCodeModel() == CodeModel::Small &&
878 "This pseudo should only be selected for 32-bit small code model.");
879 Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK);
880 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
881
882 // Print MO for better readability
883 if (isVerbose())
884 OutStreamer->getCommentOS() << MO << '\n';
885 EmitToStreamer(*OutStreamer, TmpInst);
886 return;
887 }
888
889 // Create an explicit subtract expression between the local symbol and
890 // '.LTOC' to manifest the toc-relative offset.
892 OutContext.getOrCreateSymbol(Twine(".LTOC")), OutContext);
893 Exp = MCBinaryExpr::createSub(Exp, PB, OutContext);
894 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
895 EmitToStreamer(*OutStreamer, TmpInst);
896 return;
897 }
898 case PPC::ADDItoc:
899 case PPC::ADDItoc8: {
900 assert(IsAIX && TM.getCodeModel() == CodeModel::Small &&
901 "PseudoOp only valid for small code model AIX");
902
903 // Transform %rN = ADDItoc/8 @op1, %r2.
904 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
905
906 // Change the opcode to load address.
907 TmpInst.setOpcode((!IsPPC64) ? (PPC::LA) : (PPC::LA8));
908
909 const MachineOperand &MO = MI->getOperand(1);
910 assert(MO.isGlobal() && "Invalid operand for ADDItoc[8].");
911
912 // Map the operand to its corresponding MCSymbol.
913 const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
914
915 const MCExpr *Exp =
917
918 TmpInst.getOperand(1) = TmpInst.getOperand(2);
919 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
920 EmitToStreamer(*OutStreamer, TmpInst);
921 return;
922 }
923 case PPC::LDtocJTI:
924 case PPC::LDtocCPT:
925 case PPC::LDtocBA:
926 case PPC::LDtoc: {
927 // Transform %x3 = LDtoc @min1, %x2
928 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
929
930 // Change the opcode to LD.
931 TmpInst.setOpcode(PPC::LD);
932
933 const MachineOperand &MO = MI->getOperand(1);
934 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
935 "Invalid operand!");
936
937 // Map the operand to its corresponding MCSymbol.
938 const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
939
940 MCSymbolRefExpr::VariantKind VK = GetVKForMO(MO);
941
942 // Map the machine operand to its corresponding MCSymbol, then map the
943 // global address operand to be a reference to the TOC entry we will
944 // synthesize later.
945 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol, VK);
946
949 const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry, VKExpr, OutContext);
951 IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK) : Exp);
952
953 // Print MO for better readability
954 if (isVerbose() && IsAIX)
955 OutStreamer->getCommentOS() << MO << '\n';
956 EmitToStreamer(*OutStreamer, TmpInst);
957 return;
958 }
959 case PPC::ADDIStocHA: {
960 assert((IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large) &&
961 "This pseudo should only be selected for 32-bit large code model on"
962 " AIX.");
963
964 // Transform %rd = ADDIStocHA %rA, @sym(%r2)
965 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
966
967 // Change the opcode to ADDIS.
968 TmpInst.setOpcode(PPC::ADDIS);
969
970 const MachineOperand &MO = MI->getOperand(2);
971 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
972 "Invalid operand for ADDIStocHA.");
973
974 // Map the machine operand to its corresponding MCSymbol.
975 MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
976
977 MCSymbolRefExpr::VariantKind VK = GetVKForMO(MO);
978
979 // Always use TOC on AIX. Map the global address operand to be a reference
980 // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
981 // reference the storage allocated in the TOC which contains the address of
982 // 'MOSymbol'.
983 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol, VK);
984 const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry,
986 OutContext);
987 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
988 EmitToStreamer(*OutStreamer, TmpInst);
989 return;
990 }
991 case PPC::LWZtocL: {
992 assert(IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large &&
993 "This pseudo should only be selected for 32-bit large code model on"
994 " AIX.");
995
996 // Transform %rd = LWZtocL @sym, %rs.
997 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
998
999 // Change the opcode to lwz.
1000 TmpInst.setOpcode(PPC::LWZ);
1001
1002 const MachineOperand &MO = MI->getOperand(1);
1003 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
1004 "Invalid operand for LWZtocL.");
1005
1006 // Map the machine operand to its corresponding MCSymbol.
1007 MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
1008
1009 MCSymbolRefExpr::VariantKind VK = GetVKForMO(MO);
1010
1011 // Always use TOC on AIX. Map the global address operand to be a reference
1012 // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
1013 // reference the storage allocated in the TOC which contains the address of
1014 // 'MOSymbol'.
1015 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol, VK);
1016 const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry,
1018 OutContext);
1019 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
1020 EmitToStreamer(*OutStreamer, TmpInst);
1021 return;
1022 }
1023 case PPC::ADDIStocHA8: {
1024 // Transform %xd = ADDIStocHA8 %x2, @sym
1025 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1026
1027 // Change the opcode to ADDIS8. If the global address is the address of
1028 // an external symbol, is a jump table address, is a block address, or is a
1029 // constant pool index with large code model enabled, then generate a TOC
1030 // entry and reference that. Otherwise, reference the symbol directly.
1031 TmpInst.setOpcode(PPC::ADDIS8);
1032
1033 const MachineOperand &MO = MI->getOperand(2);
1034 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&
1035 "Invalid operand for ADDIStocHA8!");
1036
1037 const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
1038
1039 MCSymbolRefExpr::VariantKind VK = GetVKForMO(MO);
1040
1041 const bool GlobalToc =
1042 MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal());
1043 if (GlobalToc || MO.isJTI() || MO.isBlockAddress() ||
1044 (MO.isCPI() && TM.getCodeModel() == CodeModel::Large))
1045 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, VK);
1046
1048
1049 const MCExpr *Exp =
1050 MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
1051
1052 if (!MO.isJTI() && MO.getOffset())
1055 OutContext),
1056 OutContext);
1057
1058 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
1059 EmitToStreamer(*OutStreamer, TmpInst);
1060 return;
1061 }
1062 case PPC::LDtocL: {
1063 // Transform %xd = LDtocL @sym, %xs
1064 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1065
1066 // Change the opcode to LD. If the global address is the address of
1067 // an external symbol, is a jump table address, is a block address, or is
1068 // a constant pool index with large code model enabled, then generate a
1069 // TOC entry and reference that. Otherwise, reference the symbol directly.
1070 TmpInst.setOpcode(PPC::LD);
1071
1072 const MachineOperand &MO = MI->getOperand(1);
1073 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
1074 MO.isBlockAddress()) &&
1075 "Invalid operand for LDtocL!");
1076
1078 (!MO.isGlobal() || Subtarget->isGVIndirectSymbol(MO.getGlobal())) &&
1079 "LDtocL used on symbol that could be accessed directly is "
1080 "invalid. Must match ADDIStocHA8."));
1081
1082 const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO, *this);
1083
1084 MCSymbolRefExpr::VariantKind VK = GetVKForMO(MO);
1085
1086 if (!MO.isCPI() || TM.getCodeModel() == CodeModel::Large)
1087 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, VK);
1088
1090 const MCExpr *Exp =
1091 MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
1092 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
1093 EmitToStreamer(*OutStreamer, TmpInst);
1094 return;
1095 }
1096 case PPC::ADDItocL: {
1097 // Transform %xd = ADDItocL %xs, @sym
1098 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1099
1100 // Change the opcode to ADDI8. If the global address is external, then
1101 // generate a TOC entry and reference that. Otherwise, reference the
1102 // symbol directly.
1103 TmpInst.setOpcode(PPC::ADDI8);
1104
1105 const MachineOperand &MO = MI->getOperand(2);
1106 assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL.");
1107
1109 !(MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal())) &&
1110 "Interposable definitions must use indirect access."));
1111
1112 const MCExpr *Exp =
1114 MCSymbolRefExpr::VK_PPC_TOC_LO, OutContext);
1115 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
1116 EmitToStreamer(*OutStreamer, TmpInst);
1117 return;
1118 }
1119 case PPC::ADDISgotTprelHA: {
1120 // Transform: %xd = ADDISgotTprelHA %x2, @sym
1121 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
1122 assert(IsPPC64 && "Not supported for 32-bit PowerPC");
1123 const MachineOperand &MO = MI->getOperand(2);
1124 const GlobalValue *GValue = MO.getGlobal();
1125 MCSymbol *MOSymbol = getSymbol(GValue);
1126 const MCExpr *SymGotTprel =
1128 OutContext);
1129 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1130 .addReg(MI->getOperand(0).getReg())
1131 .addReg(MI->getOperand(1).getReg())
1132 .addExpr(SymGotTprel));
1133 return;
1134 }
1135 case PPC::LDgotTprelL:
1136 case PPC::LDgotTprelL32: {
1137 // Transform %xd = LDgotTprelL @sym, %xs
1138 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1139
1140 // Change the opcode to LD.
1141 TmpInst.setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ);
1142 const MachineOperand &MO = MI->getOperand(1);
1143 const GlobalValue *GValue = MO.getGlobal();
1144 MCSymbol *MOSymbol = getSymbol(GValue);
1146 MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO
1148 OutContext);
1149 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
1150 EmitToStreamer(*OutStreamer, TmpInst);
1151 return;
1152 }
1153
1154 case PPC::PPC32PICGOT: {
1155 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
1156 MCSymbol *GOTRef = OutContext.createTempSymbol();
1157 MCSymbol *NextInstr = OutContext.createTempSymbol();
1158
1159 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL)
1160 // FIXME: We would like an efficient form for this, so we don't have to do
1161 // a lot of extra uniquing.
1162 .addExpr(MCSymbolRefExpr::create(NextInstr, OutContext)));
1163 const MCExpr *OffsExpr =
1164 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol, OutContext),
1165 MCSymbolRefExpr::create(GOTRef, OutContext),
1166 OutContext);
1167 OutStreamer->emitLabel(GOTRef);
1168 OutStreamer->emitValue(OffsExpr, 4);
1169 OutStreamer->emitLabel(NextInstr);
1170 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR)
1171 .addReg(MI->getOperand(0).getReg()));
1172 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
1173 .addReg(MI->getOperand(1).getReg())
1174 .addImm(0)
1175 .addReg(MI->getOperand(0).getReg()));
1176 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4)
1177 .addReg(MI->getOperand(0).getReg())
1178 .addReg(MI->getOperand(1).getReg())
1179 .addReg(MI->getOperand(0).getReg()));
1180 return;
1181 }
1182 case PPC::PPC32GOT: {
1183 MCSymbol *GOTSymbol =
1184 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
1185 const MCExpr *SymGotTlsL = MCSymbolRefExpr::create(
1186 GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, OutContext);
1187 const MCExpr *SymGotTlsHA = MCSymbolRefExpr::create(
1188 GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, OutContext);
1189 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI)
1190 .addReg(MI->getOperand(0).getReg())
1191 .addExpr(SymGotTlsL));
1192 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
1193 .addReg(MI->getOperand(0).getReg())
1194 .addReg(MI->getOperand(0).getReg())
1195 .addExpr(SymGotTlsHA));
1196 return;
1197 }
1198 case PPC::ADDIStlsgdHA: {
1199 // Transform: %xd = ADDIStlsgdHA %x2, @sym
1200 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
1201 assert(IsPPC64 && "Not supported for 32-bit PowerPC");
1202 const MachineOperand &MO = MI->getOperand(2);
1203 const GlobalValue *GValue = MO.getGlobal();
1204 MCSymbol *MOSymbol = getSymbol(GValue);
1205 const MCExpr *SymGotTlsGD =
1207 OutContext);
1208 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1209 .addReg(MI->getOperand(0).getReg())
1210 .addReg(MI->getOperand(1).getReg())
1211 .addExpr(SymGotTlsGD));
1212 return;
1213 }
1214 case PPC::ADDItlsgdL:
1215 // Transform: %xd = ADDItlsgdL %xs, @sym
1216 // Into: %xd = ADDI8 %xs, sym@got@tlsgd@l
1217 case PPC::ADDItlsgdL32: {
1218 // Transform: %rd = ADDItlsgdL32 %rs, @sym
1219 // Into: %rd = ADDI %rs, sym@got@tlsgd
1220 const MachineOperand &MO = MI->getOperand(2);
1221 const GlobalValue *GValue = MO.getGlobal();
1222 MCSymbol *MOSymbol = getSymbol(GValue);
1223 const MCExpr *SymGotTlsGD = MCSymbolRefExpr::create(
1224 MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO
1226 OutContext);
1227 EmitToStreamer(*OutStreamer,
1228 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1229 .addReg(MI->getOperand(0).getReg())
1230 .addReg(MI->getOperand(1).getReg())
1231 .addExpr(SymGotTlsGD));
1232 return;
1233 }
1234 case PPC::GETtlsADDR:
1235 // Transform: %x3 = GETtlsADDR %x3, @sym
1236 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd)
1237 case PPC::GETtlsADDRPCREL:
1238 case PPC::GETtlsADDR32AIX:
1239 case PPC::GETtlsADDR64AIX:
1240 // Transform: %r3 = GETtlsADDRNNAIX %r3, %r4 (for NN == 32/64).
1241 // Into: BLA .__tls_get_addr()
1242 // Unlike on Linux, there is no symbol or relocation needed for this call.
1243 case PPC::GETtlsADDR32: {
1244 // Transform: %r3 = GETtlsADDR32 %r3, @sym
1245 // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT
1246 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSGD);
1247 return;
1248 }
1249 case PPC::ADDIStlsldHA: {
1250 // Transform: %xd = ADDIStlsldHA %x2, @sym
1251 // Into: %xd = ADDIS8 %x2, sym@got@tlsld@ha
1252 assert(IsPPC64 && "Not supported for 32-bit PowerPC");
1253 const MachineOperand &MO = MI->getOperand(2);
1254 const GlobalValue *GValue = MO.getGlobal();
1255 MCSymbol *MOSymbol = getSymbol(GValue);
1256 const MCExpr *SymGotTlsLD =
1258 OutContext);
1259 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1260 .addReg(MI->getOperand(0).getReg())
1261 .addReg(MI->getOperand(1).getReg())
1262 .addExpr(SymGotTlsLD));
1263 return;
1264 }
1265 case PPC::ADDItlsldL:
1266 // Transform: %xd = ADDItlsldL %xs, @sym
1267 // Into: %xd = ADDI8 %xs, sym@got@tlsld@l
1268 case PPC::ADDItlsldL32: {
1269 // Transform: %rd = ADDItlsldL32 %rs, @sym
1270 // Into: %rd = ADDI %rs, sym@got@tlsld
1271 const MachineOperand &MO = MI->getOperand(2);
1272 const GlobalValue *GValue = MO.getGlobal();
1273 MCSymbol *MOSymbol = getSymbol(GValue);
1274 const MCExpr *SymGotTlsLD = MCSymbolRefExpr::create(
1275 MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO
1277 OutContext);
1278 EmitToStreamer(*OutStreamer,
1279 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1280 .addReg(MI->getOperand(0).getReg())
1281 .addReg(MI->getOperand(1).getReg())
1282 .addExpr(SymGotTlsLD));
1283 return;
1284 }
1285 case PPC::GETtlsldADDR:
1286 // Transform: %x3 = GETtlsldADDR %x3, @sym
1287 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld)
1288 case PPC::GETtlsldADDRPCREL:
1289 case PPC::GETtlsldADDR32: {
1290 // Transform: %r3 = GETtlsldADDR32 %r3, @sym
1291 // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT
1292 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSLD);
1293 return;
1294 }
1295 case PPC::ADDISdtprelHA:
1296 // Transform: %xd = ADDISdtprelHA %xs, @sym
1297 // Into: %xd = ADDIS8 %xs, sym@dtprel@ha
1298 case PPC::ADDISdtprelHA32: {
1299 // Transform: %rd = ADDISdtprelHA32 %rs, @sym
1300 // Into: %rd = ADDIS %rs, sym@dtprel@ha
1301 const MachineOperand &MO = MI->getOperand(2);
1302 const GlobalValue *GValue = MO.getGlobal();
1303 MCSymbol *MOSymbol = getSymbol(GValue);
1304 const MCExpr *SymDtprel =
1306 OutContext);
1307 EmitToStreamer(
1308 *OutStreamer,
1309 MCInstBuilder(IsPPC64 ? PPC::ADDIS8 : PPC::ADDIS)
1310 .addReg(MI->getOperand(0).getReg())
1311 .addReg(MI->getOperand(1).getReg())
1312 .addExpr(SymDtprel));
1313 return;
1314 }
1315 case PPC::PADDIdtprel: {
1316 // Transform: %rd = PADDIdtprel %rs, @sym
1317 // Into: %rd = PADDI8 %rs, sym@dtprel
1318 const MachineOperand &MO = MI->getOperand(2);
1319 const GlobalValue *GValue = MO.getGlobal();
1320 MCSymbol *MOSymbol = getSymbol(GValue);
1321 const MCExpr *SymDtprel = MCSymbolRefExpr::create(
1322 MOSymbol, MCSymbolRefExpr::VK_DTPREL, OutContext);
1323 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::PADDI8)
1324 .addReg(MI->getOperand(0).getReg())
1325 .addReg(MI->getOperand(1).getReg())
1326 .addExpr(SymDtprel));
1327 return;
1328 }
1329
1330 case PPC::ADDIdtprelL:
1331 // Transform: %xd = ADDIdtprelL %xs, @sym
1332 // Into: %xd = ADDI8 %xs, sym@dtprel@l
1333 case PPC::ADDIdtprelL32: {
1334 // Transform: %rd = ADDIdtprelL32 %rs, @sym
1335 // Into: %rd = ADDI %rs, sym@dtprel@l
1336 const MachineOperand &MO = MI->getOperand(2);
1337 const GlobalValue *GValue = MO.getGlobal();
1338 MCSymbol *MOSymbol = getSymbol(GValue);
1339 const MCExpr *SymDtprel =
1341 OutContext);
1342 EmitToStreamer(*OutStreamer,
1343 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1344 .addReg(MI->getOperand(0).getReg())
1345 .addReg(MI->getOperand(1).getReg())
1346 .addExpr(SymDtprel));
1347 return;
1348 }
1349 case PPC::MFOCRF:
1350 case PPC::MFOCRF8:
1351 if (!Subtarget->hasMFOCRF()) {
1352 // Transform: %r3 = MFOCRF %cr7
1353 // Into: %r3 = MFCR ;; cr7
1354 unsigned NewOpcode =
1355 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
1356 OutStreamer->AddComment(PPCInstPrinter::
1357 getRegisterName(MI->getOperand(1).getReg()));
1358 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1359 .addReg(MI->getOperand(0).getReg()));
1360 return;
1361 }
1362 break;
1363 case PPC::MTOCRF:
1364 case PPC::MTOCRF8:
1365 if (!Subtarget->hasMFOCRF()) {
1366 // Transform: %cr7 = MTOCRF %r3
1367 // Into: MTCRF mask, %r3 ;; cr7
1368 unsigned NewOpcode =
1369 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1370 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
1371 ->getEncodingValue(MI->getOperand(0).getReg());
1372 OutStreamer->AddComment(PPCInstPrinter::
1373 getRegisterName(MI->getOperand(0).getReg()));
1374 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1375 .addImm(Mask)
1376 .addReg(MI->getOperand(1).getReg()));
1377 return;
1378 }
1379 break;
1380 case PPC::LD:
1381 case PPC::STD:
1382 case PPC::LWA_32:
1383 case PPC::LWA: {
1384 // Verify alignment is legal, so we don't create relocations
1385 // that can't be supported.
1386 unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
1387 const MachineOperand &MO = MI->getOperand(OpNum);
1388 if (MO.isGlobal()) {
1389 const DataLayout &DL = MO.getGlobal()->getParent()->getDataLayout();
1390 if (MO.getGlobal()->getPointerAlignment(DL) < 4)
1391 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
1392 }
1393 // Now process the instruction normally.
1394 break;
1395 }
1396 case PPC::PseudoEIEIO: {
1397 EmitToStreamer(
1398 *OutStreamer,
1399 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1400 EmitToStreamer(
1401 *OutStreamer,
1402 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1403 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::EnforceIEIO));
1404 return;
1405 }
1406 }
1407
1408 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1409 EmitToStreamer(*OutStreamer, TmpInst);
1410}
1411
1412void PPCLinuxAsmPrinter::emitGNUAttributes(Module &M) {
1413 // Emit float ABI into GNU attribute
1414 Metadata *MD = M.getModuleFlag("float-abi");
1415 MDString *FloatABI = dyn_cast_or_null<MDString>(MD);
1416 if (!FloatABI)
1417 return;
1418 StringRef flt = FloatABI->getString();
1419 // TODO: Support emitting soft-fp and hard double/single attributes.
1420 if (flt == "doubledouble")
1421 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1422 Val_GNU_Power_ABI_HardFloat_DP |
1423 Val_GNU_Power_ABI_LDBL_IBM128);
1424 else if (flt == "ieeequad")
1425 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1426 Val_GNU_Power_ABI_HardFloat_DP |
1427 Val_GNU_Power_ABI_LDBL_IEEE128);
1428 else if (flt == "ieeedouble")
1429 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1430 Val_GNU_Power_ABI_HardFloat_DP |
1431 Val_GNU_Power_ABI_LDBL_64);
1432}
1433
1434void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {
1435 if (!Subtarget->isPPC64())
1436 return PPCAsmPrinter::emitInstruction(MI);
1437
1438 switch (MI->getOpcode()) {
1439 default:
1440 return PPCAsmPrinter::emitInstruction(MI);
1441 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1442 // .begin:
1443 // b .end # lis 0, FuncId[16..32]
1444 // nop # li 0, FuncId[0..15]
1445 // std 0, -8(1)
1446 // mflr 0
1447 // bl __xray_FunctionEntry
1448 // mtlr 0
1449 // .end:
1450 //
1451 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1452 // of instructions change.
1453 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1454 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1455 OutStreamer->emitLabel(BeginOfSled);
1456 EmitToStreamer(*OutStreamer,
1457 MCInstBuilder(PPC::B).addExpr(
1458 MCSymbolRefExpr::create(EndOfSled, OutContext)));
1459 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1460 EmitToStreamer(
1461 *OutStreamer,
1462 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1463 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1464 EmitToStreamer(*OutStreamer,
1465 MCInstBuilder(PPC::BL8_NOP)
1466 .addExpr(MCSymbolRefExpr::create(
1467 OutContext.getOrCreateSymbol("__xray_FunctionEntry"),
1468 OutContext)));
1469 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1470 OutStreamer->emitLabel(EndOfSled);
1471 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER, 2);
1472 break;
1473 }
1474 case TargetOpcode::PATCHABLE_RET: {
1475 unsigned RetOpcode = MI->getOperand(0).getImm();
1476 MCInst RetInst;
1477 RetInst.setOpcode(RetOpcode);
1478 for (const auto &MO : llvm::drop_begin(MI->operands())) {
1479 MCOperand MCOp;
1480 if (LowerPPCMachineOperandToMCOperand(MO, MCOp, *this))
1481 RetInst.addOperand(MCOp);
1482 }
1483
1484 bool IsConditional;
1485 if (RetOpcode == PPC::BCCLR) {
1486 IsConditional = true;
1487 } else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1488 RetOpcode == PPC::TCRETURNai8) {
1489 break;
1490 } else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1491 IsConditional = false;
1492 } else {
1493 EmitToStreamer(*OutStreamer, RetInst);
1494 break;
1495 }
1496
1497 MCSymbol *FallthroughLabel;
1498 if (IsConditional) {
1499 // Before:
1500 // bgtlr cr0
1501 //
1502 // After:
1503 // ble cr0, .end
1504 // .p2align 3
1505 // .begin:
1506 // blr # lis 0, FuncId[16..32]
1507 // nop # li 0, FuncId[0..15]
1508 // std 0, -8(1)
1509 // mflr 0
1510 // bl __xray_FunctionExit
1511 // mtlr 0
1512 // blr
1513 // .end:
1514 //
1515 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1516 // of instructions change.
1517 FallthroughLabel = OutContext.createTempSymbol();
1518 EmitToStreamer(
1519 *OutStreamer,
1520 MCInstBuilder(PPC::BCC)
1521 .addImm(PPC::InvertPredicate(
1522 static_cast<PPC::Predicate>(MI->getOperand(1).getImm())))
1523 .addReg(MI->getOperand(2).getReg())
1524 .addExpr(MCSymbolRefExpr::create(FallthroughLabel, OutContext)));
1525 RetInst = MCInst();
1526 RetInst.setOpcode(PPC::BLR8);
1527 }
1528 // .p2align 3
1529 // .begin:
1530 // b(lr)? # lis 0, FuncId[16..32]
1531 // nop # li 0, FuncId[0..15]
1532 // std 0, -8(1)
1533 // mflr 0
1534 // bl __xray_FunctionExit
1535 // mtlr 0
1536 // b(lr)?
1537 //
1538 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1539 // of instructions change.
1540 OutStreamer->emitCodeAlignment(Align(8), &getSubtargetInfo());
1541 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1542 OutStreamer->emitLabel(BeginOfSled);
1543 EmitToStreamer(*OutStreamer, RetInst);
1544 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1545 EmitToStreamer(
1546 *OutStreamer,
1547 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1548 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1549 EmitToStreamer(*OutStreamer,
1550 MCInstBuilder(PPC::BL8_NOP)
1551 .addExpr(MCSymbolRefExpr::create(
1552 OutContext.getOrCreateSymbol("__xray_FunctionExit"),
1553 OutContext)));
1554 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1555 EmitToStreamer(*OutStreamer, RetInst);
1556 if (IsConditional)
1557 OutStreamer->emitLabel(FallthroughLabel);
1558 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT, 2);
1559 break;
1560 }
1561 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1562 llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted");
1563 case TargetOpcode::PATCHABLE_TAIL_CALL:
1564 // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a
1565 // normal function exit from a tail exit.
1566 llvm_unreachable("Tail call is handled in the normal case. See comments "
1567 "around this assert.");
1568 }
1569}
1570
1571void PPCLinuxAsmPrinter::emitStartOfAsmFile(Module &M) {
1572 if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) {
1573 PPCTargetStreamer *TS =
1574 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1575 TS->emitAbiVersion(2);
1576 }
1577
1578 if (static_cast<const PPCTargetMachine &>(TM).isPPC64() ||
1579 !isPositionIndependent())
1581
1582 if (M.getPICLevel() == PICLevel::SmallPIC)
1584
1585 OutStreamer->switchSection(OutContext.getELFSection(
1587
1588 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(".LTOC"));
1589 MCSymbol *CurrentPos = OutContext.createTempSymbol();
1590
1591 OutStreamer->emitLabel(CurrentPos);
1592
1593 // The GOT pointer points to the middle of the GOT, in order to reference the
1594 // entire 64kB range. 0x8000 is the midpoint.
1595 const MCExpr *tocExpr =
1596 MCBinaryExpr::createAdd(MCSymbolRefExpr::create(CurrentPos, OutContext),
1597 MCConstantExpr::create(0x8000, OutContext),
1598 OutContext);
1599
1600 OutStreamer->emitAssignment(TOCSym, tocExpr);
1601
1602 OutStreamer->switchSection(getObjFileLowering().getTextSection());
1603}
1604
1605void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
1606 // linux/ppc32 - Normal entry label.
1607 if (!Subtarget->isPPC64() &&
1608 (!isPositionIndependent() ||
1609 MF->getFunction().getParent()->getPICLevel() == PICLevel::SmallPIC))
1611
1612 if (!Subtarget->isPPC64()) {
1613 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1614 if (PPCFI->usesPICBase() && !Subtarget->isSecurePlt()) {
1615 MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol(*MF);
1616 MCSymbol *PICBase = MF->getPICBaseSymbol();
1617 OutStreamer->emitLabel(RelocSymbol);
1618
1619 const MCExpr *OffsExpr =
1621 MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")),
1622 OutContext),
1623 MCSymbolRefExpr::create(PICBase, OutContext),
1624 OutContext);
1625 OutStreamer->emitValue(OffsExpr, 4);
1626 OutStreamer->emitLabel(CurrentFnSym);
1627 return;
1628 } else
1630 }
1631
1632 // ELFv2 ABI - Normal entry label.
1633 if (Subtarget->isELFv2ABI()) {
1634 // In the Large code model, we allow arbitrary displacements between
1635 // the text section and its associated TOC section. We place the
1636 // full 8-byte offset to the TOC in memory immediately preceding
1637 // the function global entry point.
1638 if (TM.getCodeModel() == CodeModel::Large
1639 && !MF->getRegInfo().use_empty(PPC::X2)) {
1640 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1641
1642 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1643 MCSymbol *GlobalEPSymbol = PPCFI->getGlobalEPSymbol(*MF);
1644 const MCExpr *TOCDeltaExpr =
1645 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1646 MCSymbolRefExpr::create(GlobalEPSymbol,
1647 OutContext),
1648 OutContext);
1649
1650 OutStreamer->emitLabel(PPCFI->getTOCOffsetSymbol(*MF));
1651 OutStreamer->emitValue(TOCDeltaExpr, 8);
1652 }
1654 }
1655
1656 // Emit an official procedure descriptor.
1657 MCSectionSubPair Current = OutStreamer->getCurrentSection();
1658 MCSectionELF *Section = OutStreamer->getContext().getELFSection(
1660 OutStreamer->switchSection(Section);
1661 OutStreamer->emitLabel(CurrentFnSym);
1662 OutStreamer->emitValueToAlignment(Align(8));
1663 MCSymbol *Symbol1 = CurrentFnSymForSize;
1664 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
1665 // entry point.
1666 OutStreamer->emitValue(MCSymbolRefExpr::create(Symbol1, OutContext),
1667 8 /*size*/);
1668 MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1669 // Generates a R_PPC64_TOC relocation for TOC base insertion.
1670 OutStreamer->emitValue(
1672 8/*size*/);
1673 // Emit a null environment pointer.
1674 OutStreamer->emitIntValue(0, 8 /* size */);
1675 OutStreamer->switchSection(Current.first, Current.second);
1676}
1677
1678void PPCLinuxAsmPrinter::emitEndOfAsmFile(Module &M) {
1679 const DataLayout &DL = getDataLayout();
1680
1681 bool isPPC64 = DL.getPointerSizeInBits() == 64;
1682
1683 PPCTargetStreamer *TS =
1684 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1685
1686 emitGNUAttributes(M);
1687
1688 if (!TOC.empty()) {
1689 const char *Name = isPPC64 ? ".toc" : ".got2";
1690 MCSectionELF *Section = OutContext.getELFSection(
1692 OutStreamer->switchSection(Section);
1693 if (!isPPC64)
1694 OutStreamer->emitValueToAlignment(Align(4));
1695
1696 for (const auto &TOCMapPair : TOC) {
1697 const MCSymbol *const TOCEntryTarget = TOCMapPair.first.first;
1698 MCSymbol *const TOCEntryLabel = TOCMapPair.second;
1699
1700 OutStreamer->emitLabel(TOCEntryLabel);
1701 if (isPPC64)
1702 TS->emitTCEntry(*TOCEntryTarget, TOCMapPair.first.second);
1703 else
1704 OutStreamer->emitSymbolValue(TOCEntryTarget, 4);
1705 }
1706 }
1707
1708 PPCAsmPrinter::emitEndOfAsmFile(M);
1709}
1710
1711/// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2.
1712void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
1713 // In the ELFv2 ABI, in functions that use the TOC register, we need to
1714 // provide two entry points. The ABI guarantees that when calling the
1715 // local entry point, r2 is set up by the caller to contain the TOC base
1716 // for this function, and when calling the global entry point, r12 is set
1717 // up by the caller to hold the address of the global entry point. We
1718 // thus emit a prefix sequence along the following lines:
1719 //
1720 // func:
1721 // .Lfunc_gepNN:
1722 // # global entry point
1723 // addis r2,r12,(.TOC.-.Lfunc_gepNN)@ha
1724 // addi r2,r2,(.TOC.-.Lfunc_gepNN)@l
1725 // .Lfunc_lepNN:
1726 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1727 // # local entry point, followed by function body
1728 //
1729 // For the Large code model, we create
1730 //
1731 // .Lfunc_tocNN:
1732 // .quad .TOC.-.Lfunc_gepNN # done by EmitFunctionEntryLabel
1733 // func:
1734 // .Lfunc_gepNN:
1735 // # global entry point
1736 // ld r2,.Lfunc_tocNN-.Lfunc_gepNN(r12)
1737 // add r2,r2,r12
1738 // .Lfunc_lepNN:
1739 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1740 // # local entry point, followed by function body
1741 //
1742 // This ensures we have r2 set up correctly while executing the function
1743 // body, no matter which entry point is called.
1744 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1745 const bool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) ||
1746 !MF->getRegInfo().use_empty(PPC::R2);
1747 const bool PCrelGEPRequired = Subtarget->isUsingPCRelativeCalls() &&
1748 UsesX2OrR2 && PPCFI->usesTOCBasePtr();
1749 const bool NonPCrelGEPRequired = !Subtarget->isUsingPCRelativeCalls() &&
1750 Subtarget->isELFv2ABI() && UsesX2OrR2;
1751
1752 // Only do all that if the function uses R2 as the TOC pointer
1753 // in the first place. We don't need the global entry point if the
1754 // function uses R2 as an allocatable register.
1755 if (NonPCrelGEPRequired || PCrelGEPRequired) {
1756 // Note: The logic here must be synchronized with the code in the
1757 // branch-selection pass which sets the offset of the first block in the
1758 // function. This matters because it affects the alignment.
1759 MCSymbol *GlobalEntryLabel = PPCFI->getGlobalEPSymbol(*MF);
1760 OutStreamer->emitLabel(GlobalEntryLabel);
1761 const MCSymbolRefExpr *GlobalEntryLabelExp =
1762 MCSymbolRefExpr::create(GlobalEntryLabel, OutContext);
1763
1764 if (TM.getCodeModel() != CodeModel::Large) {
1765 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1766 const MCExpr *TOCDeltaExpr =
1767 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1768 GlobalEntryLabelExp, OutContext);
1769
1770 const MCExpr *TOCDeltaHi = PPCMCExpr::createHa(TOCDeltaExpr, OutContext);
1771 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
1772 .addReg(PPC::X2)
1773 .addReg(PPC::X12)
1774 .addExpr(TOCDeltaHi));
1775
1776 const MCExpr *TOCDeltaLo = PPCMCExpr::createLo(TOCDeltaExpr, OutContext);
1777 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
1778 .addReg(PPC::X2)
1779 .addReg(PPC::X2)
1780 .addExpr(TOCDeltaLo));
1781 } else {
1782 MCSymbol *TOCOffset = PPCFI->getTOCOffsetSymbol(*MF);
1783 const MCExpr *TOCOffsetDeltaExpr =
1784 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCOffset, OutContext),
1785 GlobalEntryLabelExp, OutContext);
1786
1787 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
1788 .addReg(PPC::X2)
1789 .addExpr(TOCOffsetDeltaExpr)
1790 .addReg(PPC::X12));
1791 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8)
1792 .addReg(PPC::X2)
1793 .addReg(PPC::X2)
1794 .addReg(PPC::X12));
1795 }
1796
1797 MCSymbol *LocalEntryLabel = PPCFI->getLocalEPSymbol(*MF);
1798 OutStreamer->emitLabel(LocalEntryLabel);
1799 const MCSymbolRefExpr *LocalEntryLabelExp =
1800 MCSymbolRefExpr::create(LocalEntryLabel, OutContext);
1801 const MCExpr *LocalOffsetExp =
1802 MCBinaryExpr::createSub(LocalEntryLabelExp,
1803 GlobalEntryLabelExp, OutContext);
1804
1805 PPCTargetStreamer *TS =
1806 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1807 TS->emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), LocalOffsetExp);
1808 } else if (Subtarget->isUsingPCRelativeCalls()) {
1809 // When generating the entry point for a function we have a few scenarios
1810 // based on whether or not that function uses R2 and whether or not that
1811 // function makes calls (or is a leaf function).
1812 // 1) A leaf function that does not use R2 (or treats it as callee-saved
1813 // and preserves it). In this case st_other=0 and both
1814 // the local and global entry points for the function are the same.
1815 // No special entry point code is required.
1816 // 2) A function uses the TOC pointer R2. This function may or may not have
1817 // calls. In this case st_other=[2,6] and the global and local entry
1818 // points are different. Code to correctly setup the TOC pointer in R2
1819 // is put between the global and local entry points. This case is
1820 // covered by the if statatement above.
1821 // 3) A function does not use the TOC pointer R2 but does have calls.
1822 // In this case st_other=1 since we do not know whether or not any
1823 // of the callees clobber R2. This case is dealt with in this else if
1824 // block. Tail calls are considered calls and the st_other should also
1825 // be set to 1 in that case as well.
1826 // 4) The function does not use the TOC pointer but R2 is used inside
1827 // the function. In this case st_other=1 once again.
1828 // 5) This function uses inline asm. We mark R2 as reserved if the function
1829 // has inline asm as we have to assume that it may be used.
1830 if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() ||
1831 MF->hasInlineAsm() || (!PPCFI->usesTOCBasePtr() && UsesX2OrR2)) {
1832 PPCTargetStreamer *TS =
1833 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1834 TS->emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym),
1835 MCConstantExpr::create(1, OutContext));
1836 }
1837 }
1838}
1839
1840/// EmitFunctionBodyEnd - Print the traceback table before the .size
1841/// directive.
1842///
1843void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
1844 // Only the 64-bit target requires a traceback table. For now,
1845 // we only emit the word of zeroes that GDB requires to find
1846 // the end of the function, and zeroes for the eight-byte
1847 // mandatory fields.
1848 // FIXME: We should fill in the eight-byte mandatory fields as described in
1849 // the PPC64 ELF ABI (this is a low-priority item because GDB does not
1850 // currently make use of these fields).
1851 if (Subtarget->isPPC64()) {
1852 OutStreamer->emitIntValue(0, 4/*size*/);
1853 OutStreamer->emitIntValue(0, 8/*size*/);
1854 }
1855}
1856
1857void PPCAIXAsmPrinter::emitLinkage(const GlobalValue *GV,
1858 MCSymbol *GVSym) const {
1859
1860 assert(MAI->hasVisibilityOnlyWithLinkage() &&
1861 "AIX's linkage directives take a visibility setting.");
1862
1863 MCSymbolAttr LinkageAttr = MCSA_Invalid;
1864 switch (GV->getLinkage()) {
1866 LinkageAttr = GV->isDeclaration() ? MCSA_Extern : MCSA_Global;
1867 break;
1873 LinkageAttr = MCSA_Weak;
1874 break;
1876 LinkageAttr = MCSA_Extern;
1877 break;
1879 return;
1882 "InternalLinkage should not have other visibility setting.");
1883 LinkageAttr = MCSA_LGlobal;
1884 break;
1886 llvm_unreachable("Should never emit this");
1888 llvm_unreachable("CommonLinkage of XCOFF should not come to this path");
1889 }
1890
1891 assert(LinkageAttr != MCSA_Invalid && "LinkageAttr should not MCSA_Invalid.");
1892
1893 MCSymbolAttr VisibilityAttr = MCSA_Invalid;
1894 if (!TM.getIgnoreXCOFFVisibility()) {
1897 "Cannot not be both dllexport and non-default visibility");
1898 switch (GV->getVisibility()) {
1899
1900 // TODO: "internal" Visibility needs to go here.
1902 if (GV->hasDLLExportStorageClass())
1903 VisibilityAttr = MAI->getExportedVisibilityAttr();
1904 break;
1906 VisibilityAttr = MAI->getHiddenVisibilityAttr();
1907 break;
1909 VisibilityAttr = MAI->getProtectedVisibilityAttr();
1910 break;
1911 }
1912 }
1913
1914 OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,
1915 VisibilityAttr);
1916}
1917
1918void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
1919 // Setup CurrentFnDescSym and its containing csect.
1920 MCSectionXCOFF *FnDescSec =
1921 cast<MCSectionXCOFF>(getObjFileLowering().getSectionForFunctionDescriptor(
1922 &MF.getFunction(), TM));
1923 FnDescSec->setAlignment(Align(Subtarget->isPPC64() ? 8 : 4));
1924
1925 CurrentFnDescSym = FnDescSec->getQualNameSymbol();
1926
1928}
1929
1930uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
1931 // Calculate the number of VRs be saved.
1932 // Vector registers 20 through 31 are marked as reserved and cannot be used
1933 // in the default ABI.
1934 const PPCSubtarget &Subtarget = MF->getSubtarget<PPCSubtarget>();
1935 if (Subtarget.isAIXABI() && Subtarget.hasAltivec() &&
1936 TM.getAIXExtendedAltivecABI()) {
1937 const MachineRegisterInfo &MRI = MF->getRegInfo();
1938 for (unsigned Reg = PPC::V20; Reg <= PPC::V31; ++Reg)
1939 if (MRI.isPhysRegModified(Reg))
1940 // Number of VRs saved.
1941 return PPC::V31 - Reg + 1;
1942 }
1943 return 0;
1944}
1945
1946void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
1947
1948 if (!TM.getXCOFFTracebackTable())
1949 return;
1950
1951 emitTracebackTable();
1952
1953 // If ShouldEmitEHBlock returns true, then the eh info table
1954 // will be emitted via `AIXException::endFunction`. Otherwise, we
1955 // need to emit a dumy eh info table when VRs are saved. We could not
1956 // consolidate these two places into one because there is no easy way
1957 // to access register information in `AIXException` class.
1959 (getNumberOfVRSaved() > 0)) {
1960 // Emit dummy EH Info Table.
1961 OutStreamer->switchSection(getObjFileLowering().getCompactUnwindSection());
1962 MCSymbol *EHInfoLabel =
1964 OutStreamer->emitLabel(EHInfoLabel);
1965
1966 // Version number.
1967 OutStreamer->emitInt32(0);
1968
1969 const DataLayout &DL = MMI->getModule()->getDataLayout();
1970 const unsigned PointerSize = DL.getPointerSize();
1971 // Add necessary paddings in 64 bit mode.
1972 OutStreamer->emitValueToAlignment(Align(PointerSize));
1973
1974 OutStreamer->emitIntValue(0, PointerSize);
1975 OutStreamer->emitIntValue(0, PointerSize);
1976 OutStreamer->switchSection(MF->getSection());
1977 }
1978}
1979
1980void PPCAIXAsmPrinter::emitTracebackTable() {
1981
1982 // Create a symbol for the end of function.
1983 MCSymbol *FuncEnd = createTempSymbol(MF->getName());
1984 OutStreamer->emitLabel(FuncEnd);
1985
1986 OutStreamer->AddComment("Traceback table begin");
1987 // Begin with a fullword of zero.
1988 OutStreamer->emitIntValueInHexWithPadding(0, 4 /*size*/);
1989
1990 SmallString<128> CommentString;
1991 raw_svector_ostream CommentOS(CommentString);
1992
1993 auto EmitComment = [&]() {
1994 OutStreamer->AddComment(CommentOS.str());
1995 CommentString.clear();
1996 };
1997
1998 auto EmitCommentAndValue = [&](uint64_t Value, int Size) {
1999 EmitComment();
2000 OutStreamer->emitIntValueInHexWithPadding(Value, Size);
2001 };
2002
2003 unsigned int Version = 0;
2004 CommentOS << "Version = " << Version;
2005 EmitCommentAndValue(Version, 1);
2006
2007 // There is a lack of information in the IR to assist with determining the
2008 // source language. AIX exception handling mechanism would only search for
2009 // personality routine and LSDA area when such language supports exception
2010 // handling. So to be conservatively correct and allow runtime to do its job,
2011 // we need to set it to C++ for now.
2012 TracebackTable::LanguageID LanguageIdentifier =
2014
2015 CommentOS << "Language = "
2016 << getNameForTracebackTableLanguageId(LanguageIdentifier);
2017 EmitCommentAndValue(LanguageIdentifier, 1);
2018
2019 // This is only populated for the third and fourth bytes.
2020 uint32_t FirstHalfOfMandatoryField = 0;
2021
2022 // Emit the 3rd byte of the mandatory field.
2023
2024 // We always set traceback offset bit to true.
2025 FirstHalfOfMandatoryField |= TracebackTable::HasTraceBackTableOffsetMask;
2026
2027 const PPCFunctionInfo *FI = MF->getInfo<PPCFunctionInfo>();
2028 const MachineRegisterInfo &MRI = MF->getRegInfo();
2029
2030 // Check the function uses floating-point processor instructions or not
2031 for (unsigned Reg = PPC::F0; Reg <= PPC::F31; ++Reg) {
2032 if (MRI.isPhysRegUsed(Reg, /* SkipRegMaskTest */ true)) {
2033 FirstHalfOfMandatoryField |= TracebackTable::IsFloatingPointPresentMask;
2034 break;
2035 }
2036 }
2037
2038#define GENBOOLCOMMENT(Prefix, V, Field) \
2039 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
2040 << #Field
2041
2042#define GENVALUECOMMENT(PrefixAndName, V, Field) \
2043 CommentOS << (PrefixAndName) << " = " \
2044 << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
2045 (TracebackTable::Field##Shift))
2046
2047 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsGlobaLinkage);
2048 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);
2049 EmitComment();
2050
2051 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasTraceBackTableOffset);
2052 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsInternalProcedure);
2053 EmitComment();
2054
2055 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, HasControlledStorage);
2056 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsTOCless);
2057 EmitComment();
2058
2059 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsFloatingPointPresent);
2060 EmitComment();
2061 GENBOOLCOMMENT("", FirstHalfOfMandatoryField,
2062 IsFloatingPointOperationLogOrAbortEnabled);
2063 EmitComment();
2064
2065 OutStreamer->emitIntValueInHexWithPadding(
2066 (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2067
2068 // Set the 4th byte of the mandatory field.
2069 FirstHalfOfMandatoryField |= TracebackTable::IsFunctionNamePresentMask;
2070
2071 const PPCRegisterInfo *RegInfo =
2072 static_cast<const PPCRegisterInfo *>(Subtarget->getRegisterInfo());
2073 Register FrameReg = RegInfo->getFrameRegister(*MF);
2074 if (FrameReg == (Subtarget->isPPC64() ? PPC::X31 : PPC::R31))
2075 FirstHalfOfMandatoryField |= TracebackTable::IsAllocaUsedMask;
2076
2077 const SmallVectorImpl<Register> &MustSaveCRs = FI->getMustSaveCRs();
2078 if (!MustSaveCRs.empty())
2079 FirstHalfOfMandatoryField |= TracebackTable::IsCRSavedMask;
2080
2081 if (FI->mustSaveLR())
2082 FirstHalfOfMandatoryField |= TracebackTable::IsLRSavedMask;
2083
2084 GENBOOLCOMMENT("", FirstHalfOfMandatoryField, IsInterruptHandler);
2085 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);
2086 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsAllocaUsed);
2087 EmitComment();
2088 GENVALUECOMMENT("OnConditionDirective", FirstHalfOfMandatoryField,
2089 OnConditionDirective);
2090 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsCRSaved);
2091 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField, IsLRSaved);
2092 EmitComment();
2093 OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),
2094 1);
2095
2096 // Set the 5th byte of mandatory field.
2097 uint32_t SecondHalfOfMandatoryField = 0;
2098
2099 // Always store back chain.
2100 SecondHalfOfMandatoryField |= TracebackTable::IsBackChainStoredMask;
2101
2102 uint32_t FPRSaved = 0;
2103 for (unsigned Reg = PPC::F14; Reg <= PPC::F31; ++Reg) {
2104 if (MRI.isPhysRegModified(Reg)) {
2105 FPRSaved = PPC::F31 - Reg + 1;
2106 break;
2107 }
2108 }
2109 SecondHalfOfMandatoryField |= (FPRSaved << TracebackTable::FPRSavedShift) &
2111 GENBOOLCOMMENT("", SecondHalfOfMandatoryField, IsBackChainStored);
2112 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, IsFixup);
2113 GENVALUECOMMENT(", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
2114 EmitComment();
2115 OutStreamer->emitIntValueInHexWithPadding(
2116 (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
2117
2118 // Set the 6th byte of mandatory field.
2119
2120 // Check whether has Vector Instruction,We only treat instructions uses vector
2121 // register as vector instructions.
2122 bool HasVectorInst = false;
2123 for (unsigned Reg = PPC::V0; Reg <= PPC::V31; ++Reg)
2124 if (MRI.isPhysRegUsed(Reg, /* SkipRegMaskTest */ true)) {
2125 // Has VMX instruction.
2126 HasVectorInst = true;
2127 break;
2128 }
2129
2130 if (FI->hasVectorParms() || HasVectorInst)
2131 SecondHalfOfMandatoryField |= TracebackTable::HasVectorInfoMask;
2132
2133 uint16_t NumOfVRSaved = getNumberOfVRSaved();
2134 bool ShouldEmitEHBlock =
2136
2137 if (ShouldEmitEHBlock)
2138 SecondHalfOfMandatoryField |= TracebackTable::HasExtensionTableMask;
2139
2140 uint32_t GPRSaved = 0;
2141
2142 // X13 is reserved under 64-bit environment.
2143 unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13;
2144 unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31;
2145
2146 for (unsigned Reg = GPRBegin; Reg <= GPREnd; ++Reg) {
2147 if (MRI.isPhysRegModified(Reg)) {
2148 GPRSaved = GPREnd - Reg + 1;
2149 break;
2150 }
2151 }
2152
2153 SecondHalfOfMandatoryField |= (GPRSaved << TracebackTable::GPRSavedShift) &
2155
2156 GENBOOLCOMMENT("", SecondHalfOfMandatoryField, HasExtensionTable);
2157 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasVectorInfo);
2158 GENVALUECOMMENT(", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
2159 EmitComment();
2160 OutStreamer->emitIntValueInHexWithPadding(
2161 (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
2162
2163 // Set the 7th byte of mandatory field.
2164 uint32_t NumberOfFixedParms = FI->getFixedParmsNum();
2165 SecondHalfOfMandatoryField |=
2166 (NumberOfFixedParms << TracebackTable::NumberOfFixedParmsShift) &
2168 GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField,
2169 NumberOfFixedParms);
2170 EmitComment();
2171 OutStreamer->emitIntValueInHexWithPadding(
2172 (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2173
2174 // Set the 8th byte of mandatory field.
2175
2176 // Always set parameter on stack.
2177 SecondHalfOfMandatoryField |= TracebackTable::HasParmsOnStackMask;
2178
2179 uint32_t NumberOfFPParms = FI->getFloatingPointParmsNum();
2180 SecondHalfOfMandatoryField |=
2183
2184 GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField,
2185 NumberOfFloatingPointParms);
2186 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField, HasParmsOnStack);
2187 EmitComment();
2188 OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
2189 1);
2190
2191 // Generate the optional fields of traceback table.
2192
2193 // Parameter type.
2194 if (NumberOfFixedParms || NumberOfFPParms) {
2195 uint32_t ParmsTypeValue = FI->getParmsType();
2196
2197 Expected<SmallString<32>> ParmsType =
2198 FI->hasVectorParms()
2200 ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
2201 FI->getVectorParmsNum())
2202 : XCOFF::parseParmsType(ParmsTypeValue, NumberOfFixedParms,
2203 NumberOfFPParms);
2204
2205 assert(ParmsType && toString(ParmsType.takeError()).c_str());
2206 if (ParmsType) {
2207 CommentOS << "Parameter type = " << ParmsType.get();
2208 EmitComment();
2209 }
2210 OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
2211 sizeof(ParmsTypeValue));
2212 }
2213 // Traceback table offset.
2214 OutStreamer->AddComment("Function size");
2215 if (FirstHalfOfMandatoryField & TracebackTable::HasTraceBackTableOffsetMask) {
2216 MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
2217 &(MF->getFunction()), TM);
2218 OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
2219 }
2220
2221 // Since we unset the Int_Handler.
2222 if (FirstHalfOfMandatoryField & TracebackTable::IsInterruptHandlerMask)
2223 report_fatal_error("Hand_Mask not implement yet");
2224
2225 if (FirstHalfOfMandatoryField & TracebackTable::HasControlledStorageMask)
2226 report_fatal_error("Ctl_Info not implement yet");
2227
2228 if (FirstHalfOfMandatoryField & TracebackTable::IsFunctionNamePresentMask) {
2229 StringRef Name = MF->getName().substr(0, INT16_MAX);
2230 int16_t NameLength = Name.size();
2231 CommentOS << "Function name len = "
2232 << static_cast<unsigned int>(NameLength);
2233 EmitCommentAndValue(NameLength, 2);
2234 OutStreamer->AddComment("Function Name");
2235 OutStreamer->emitBytes(Name);
2236 }
2237
2238 if (FirstHalfOfMandatoryField & TracebackTable::IsAllocaUsedMask) {
2239 uint8_t AllocReg = XCOFF::AllocRegNo;
2240 OutStreamer->AddComment("AllocaUsed");
2241 OutStreamer->emitIntValueInHex(AllocReg, sizeof(AllocReg));
2242 }
2243
2244 if (SecondHalfOfMandatoryField & TracebackTable::HasVectorInfoMask) {
2245 uint16_t VRData = 0;
2246 if (NumOfVRSaved) {
2247 // Number of VRs saved.
2248 VRData |= (NumOfVRSaved << TracebackTable::NumberOfVRSavedShift) &
2250 // This bit is supposed to set only when the special register
2251 // VRSAVE is saved on stack.
2252 // However, IBM XL compiler sets the bit when any vector registers
2253 // are saved on the stack. We will follow XL's behavior on AIX
2254 // so that we don't get surprise behavior change for C code.
2256 }
2257
2258 // Set has_varargs.
2259 if (FI->getVarArgsFrameIndex())
2261
2262 // Vector parameters number.
2263 unsigned VectorParmsNum = FI->getVectorParmsNum();
2264 VRData |= (VectorParmsNum << TracebackTable::NumberOfVectorParmsShift) &
2266
2267 if (HasVectorInst)
2269
2270 GENVALUECOMMENT("NumOfVRsSaved", VRData, NumberOfVRSaved);
2271 GENBOOLCOMMENT(", ", VRData, IsVRSavedOnStack);
2272 GENBOOLCOMMENT(", ", VRData, HasVarArgs);
2273 EmitComment();
2274 OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
2275
2276 GENVALUECOMMENT("NumOfVectorParams", VRData, NumberOfVectorParms);
2277 GENBOOLCOMMENT(", ", VRData, HasVMXInstruction);
2278 EmitComment();
2279 OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
2280
2281 uint32_t VecParmTypeValue = FI->getVecExtParmsType();
2282
2283 Expected<SmallString<32>> VecParmsType =
2284 XCOFF::parseVectorParmsType(VecParmTypeValue, VectorParmsNum);
2285 assert(VecParmsType && toString(VecParmsType.takeError()).c_str());
2286 if (VecParmsType) {
2287 CommentOS << "Vector Parameter type = " << VecParmsType.get();
2288 EmitComment();
2289 }
2290 OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
2291 sizeof(VecParmTypeValue));
2292 // Padding 2 bytes.
2293 CommentOS << "Padding";
2294 EmitCommentAndValue(0, 2);
2295 }
2296
2297 uint8_t ExtensionTableFlag = 0;
2298 if (SecondHalfOfMandatoryField & TracebackTable::HasExtensionTableMask) {
2299 if (ShouldEmitEHBlock)
2300 ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
2303 ExtensionTableFlag |= ExtendedTBTableFlag::TB_SSP_CANARY;
2304
2305 CommentOS << "ExtensionTableFlag = "
2306 << getExtendedTBTableFlagString(ExtensionTableFlag);
2307 EmitCommentAndValue(ExtensionTableFlag, sizeof(ExtensionTableFlag));
2308 }
2309
2310 if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
2311 auto &Ctx = OutStreamer->getContext();
2312 MCSymbol *EHInfoSym =
2314 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym);
2315 const MCSymbol *TOCBaseSym =
2316 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2317 ->getQualNameSymbol();
2318 const MCExpr *Exp =
2320 MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx);
2321
2322 const DataLayout &DL = getDataLayout();
2323 OutStreamer->emitValueToAlignment(Align(4));
2324 OutStreamer->AddComment("EHInfo Table");
2325 OutStreamer->emitValue(Exp, DL.getPointerSize());
2326 }
2327#undef GENBOOLCOMMENT
2328#undef GENVALUECOMMENT
2329}
2330
2332 return GV->hasAppendingLinkage() &&
2334 // TODO: Linker could still eliminate the GV if we just skip
2335 // handling llvm.used array. Skipping them for now until we or the
2336 // AIX OS team come up with a good solution.
2337 .Case("llvm.used", true)
2338 // It's correct to just skip llvm.compiler.used array here.
2339 .Case("llvm.compiler.used", true)
2340 .Default(false);
2341}
2342
2344 return StringSwitch<bool>(GV->getName())
2345 .Cases("llvm.global_ctors", "llvm.global_dtors", true)
2346 .Default(false);
2347}
2348
2349uint64_t PPCAIXAsmPrinter::getAliasOffset(const Constant *C) {
2350 if (auto *GA = dyn_cast<GlobalAlias>(C))
2351 return getAliasOffset(GA->getAliasee());
2352 if (auto *CE = dyn_cast<ConstantExpr>(C)) {
2353 const MCExpr *LowC = lowerConstant(CE);
2354 const MCBinaryExpr *CBE = dyn_cast<MCBinaryExpr>(LowC);
2355 if (!CBE)
2356 return 0;
2357 if (CBE->getOpcode() != MCBinaryExpr::Add)
2358 report_fatal_error("Only adding an offset is supported now.");
2359 auto *RHS = dyn_cast<MCConstantExpr>(CBE->getRHS());
2360 if (!RHS)
2361 report_fatal_error("Unable to get the offset of alias.");
2362 return RHS->getValue();
2363 }
2364 return 0;
2365}
2366
2367void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
2368 // Special LLVM global arrays have been handled at the initialization.
2370 return;
2371
2372 // If the Global Variable has the toc-data attribute, it needs to be emitted
2373 // when we emit the .toc section.
2374 if (GV->hasAttribute("toc-data")) {
2375 TOCDataGlobalVars.push_back(GV);
2376 return;
2377 }
2378
2379 emitGlobalVariableHelper(GV);
2380}
2381
2382void PPCAIXAsmPrinter::emitGlobalVariableHelper(const GlobalVariable *GV) {
2383 assert(!GV->getName().startswith("llvm.") &&
2384 "Unhandled intrinsic global variable.");
2385
2386 if (GV->hasComdat())
2387 report_fatal_error("COMDAT not yet supported by AIX.");
2388
2389 MCSymbolXCOFF *GVSym = cast<MCSymbolXCOFF>(getSymbol(GV));
2390
2391 if (GV->isDeclarationForLinker()) {
2392 emitLinkage(GV, GVSym);
2393 return;
2394 }
2395
2396 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
2397 if (!GVKind.isGlobalWriteableData() && !GVKind.isReadOnly() &&
2398 !GVKind.isThreadLocal()) // Checks for both ThreadData and ThreadBSS.
2399 report_fatal_error("Encountered a global variable kind that is "
2400 "not supported yet.");
2401
2402 // Print GV in verbose mode
2403 if (isVerbose()) {
2404 if (GV->hasInitializer()) {
2405 GV->printAsOperand(OutStreamer->getCommentOS(),
2406 /*PrintType=*/false, GV->getParent());
2407 OutStreamer->getCommentOS() << '\n';
2408 }
2409 }
2410
2411 MCSectionXCOFF *Csect = cast<MCSectionXCOFF>(
2412 getObjFileLowering().SectionForGlobal(GV, GVKind, TM));
2413
2414 // Switch to the containing csect.
2415 OutStreamer->switchSection(Csect);
2416
2417 const DataLayout &DL = GV->getParent()->getDataLayout();
2418
2419 // Handle common and zero-initialized local symbols.
2420 if (GV->hasCommonLinkage() || GVKind.isBSSLocal() ||
2421 GVKind.isThreadBSSLocal()) {
2422 Align Alignment = GV->getAlign().value_or(DL.getPreferredAlign(GV));
2423 uint64_t Size = DL.getTypeAllocSize(GV->getValueType());
2424 GVSym->setStorageClass(
2426
2427 if (GVKind.isBSSLocal() || GVKind.isThreadBSSLocal())
2428 OutStreamer->emitXCOFFLocalCommonSymbol(
2429 OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()), Size,
2430 GVSym, Alignment);
2431 else
2432 OutStreamer->emitCommonSymbol(GVSym, Size, Alignment);
2433 return;
2434 }
2435
2436 MCSymbol *EmittedInitSym = GVSym;
2437
2438 // Emit linkage for the global variable and its aliases.
2439 emitLinkage(GV, EmittedInitSym);
2440 for (const GlobalAlias *GA : GOAliasMap[GV])
2441 emitLinkage(GA, getSymbol(GA));
2442
2443 emitAlignment(getGVAlignment(GV, DL), GV);
2444
2445 // When -fdata-sections is enabled, every GlobalVariable will
2446 // be put into its own csect; therefore, label is not necessary here.
2447 if (!TM.getDataSections() || GV->hasSection())
2448 OutStreamer->emitLabel(EmittedInitSym);
2449
2450 // No alias to emit.
2451 if (!GOAliasMap[GV].size()) {
2452 emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());
2453 return;
2454 }
2455
2456 // Aliases with the same offset should be aligned. Record the list of aliases
2457 // associated with the offset.
2458 AliasMapTy AliasList;
2459 for (const GlobalAlias *GA : GOAliasMap[GV])
2460 AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);
2461
2462 // Emit alias label and element value for global variable.
2463 emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer(),
2464 &AliasList);
2465}
2466
2467void PPCAIXAsmPrinter::emitFunctionDescriptor() {
2468 const DataLayout &DL = getDataLayout();
2469 const unsigned PointerSize = DL.getPointerSizeInBits() == 64 ? 8 : 4;
2470
2471 MCSectionSubPair Current = OutStreamer->getCurrentSection();
2472 // Emit function descriptor.
2473 OutStreamer->switchSection(
2474 cast<MCSymbolXCOFF>(CurrentFnDescSym)->getRepresentedCsect());
2475
2476 // Emit aliasing label for function descriptor csect.
2477 for (const GlobalAlias *Alias : GOAliasMap[&MF->getFunction()])
2478 OutStreamer->emitLabel(getSymbol(Alias));
2479
2480 // Emit function entry point address.
2481 OutStreamer->emitValue(MCSymbolRefExpr::create(CurrentFnSym, OutContext),
2482 PointerSize);
2483 // Emit TOC base address.
2484 const MCSymbol *TOCBaseSym =
2485 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2486 ->getQualNameSymbol();
2487 OutStreamer->emitValue(MCSymbolRefExpr::create(TOCBaseSym, OutContext),
2488 PointerSize);
2489 // Emit a null environment pointer.
2490 OutStreamer->emitIntValue(0, PointerSize);
2491
2492 OutStreamer->switchSection(Current.first, Current.second);
2493}
2494
2495void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2496 // It's not necessary to emit the label when we have individual
2497 // function in its own csect.
2498 if (!TM.getFunctionSections())
2499 PPCAsmPrinter::emitFunctionEntryLabel();
2500
2501 // Emit aliasing label for function entry point label.
2502 for (const GlobalAlias *Alias : GOAliasMap[&MF->getFunction()])
2503 OutStreamer->emitLabel(
2504 getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM));
2505}
2506
2507void PPCAIXAsmPrinter::emitPGORefs() {
2508 if (OutContext.hasXCOFFSection(
2509 "__llvm_prf_cnts",
2511 MCSection *CntsSection = OutContext.getXCOFFSection(
2512 "__llvm_prf_cnts", SectionKind::getData(),
2514 /*MultiSymbolsAllowed*/ true);
2515
2516 OutStreamer->switchSection(CntsSection);
2517 if (OutContext.hasXCOFFSection(
2518 "__llvm_prf_data",
2520 OutStreamer->emitXCOFFRefDirective("__llvm_prf_data[RW]");
2521 if (OutContext.hasXCOFFSection(
2522 "__llvm_prf_names",
2524 OutStreamer->emitXCOFFRefDirective("__llvm_prf_names[RO]");
2525 if (OutContext.hasXCOFFSection(
2526 "__llvm_prf_vnds",
2528 OutStreamer->emitXCOFFRefDirective("__llvm_prf_vnds[RW]");
2529 }
2530}
2531
2532void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
2533 // If there are no functions and there are no toc-data definitions in this
2534 // module, we will never need to reference the TOC base.
2535 if (M.empty() && TOCDataGlobalVars.empty())
2536 return;
2537
2538 emitPGORefs();
2539
2540 // Switch to section to emit TOC base.
2541 OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());
2542
2543 PPCTargetStreamer *TS =
2544 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
2545
2546 for (auto &I : TOC) {
2547 MCSectionXCOFF *TCEntry;
2548 // Setup the csect for the current TC entry. If the variant kind is
2549 // VK_PPC_AIX_TLSGDM the entry represents the region handle, we create a
2550 // new symbol to prefix the name with a dot.
2551 if (I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM) {
2553 StringRef Prefix = ".";
2554 Name += Prefix;
2555 Name += cast<MCSymbolXCOFF>(I.first.first)->getSymbolTableName();
2556 MCSymbol *S = OutContext.getOrCreateSymbol(Name);
2557 TCEntry = cast<MCSectionXCOFF>(
2558 getObjFileLowering().getSectionForTOCEntry(S, TM));
2559 } else {
2560 TCEntry = cast<MCSectionXCOFF>(
2561 getObjFileLowering().getSectionForTOCEntry(I.first.first, TM));
2562 }
2563 OutStreamer->switchSection(TCEntry);
2564
2565 OutStreamer->emitLabel(I.second);
2566 TS->emitTCEntry(*I.first.first, I.first.second);
2567 }
2568
2569 for (const auto *GV : TOCDataGlobalVars)
2570 emitGlobalVariableHelper(GV);
2571}
2572
2573bool PPCAIXAsmPrinter::doInitialization(Module &M) {
2574 const bool Result = PPCAsmPrinter::doInitialization(M);
2575
2576 auto setCsectAlignment = [this](const GlobalObject *GO) {
2577 // Declarations have 0 alignment which is set by default.
2578 if (GO->isDeclarationForLinker())
2579 return;
2580
2581 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);
2582 MCSectionXCOFF *Csect = cast<MCSectionXCOFF>(
2583 getObjFileLowering().SectionForGlobal(GO, GOKind, TM));
2584
2585 Align GOAlign = getGVAlignment(GO, GO->getParent()->getDataLayout());
2586 Csect->ensureMinAlignment(GOAlign);
2587 };
2588
2589 // We need to know, up front, the alignment of csects for the assembly path,
2590 // because once a .csect directive gets emitted, we could not change the
2591 // alignment value on it.
2592 for (const auto &G : M.globals()) {
2594 continue;
2595
2597 // Generate a format indicator and a unique module id to be a part of
2598 // the sinit and sterm function names.
2599 if (FormatIndicatorAndUniqueModId.empty()) {
2600 std::string UniqueModuleId = getUniqueModuleId(&M);
2601 if (UniqueModuleId != "")
2602 // TODO: Use source file full path to generate the unique module id
2603 // and add a format indicator as a part of function name in case we
2604 // will support more than one format.
2605 FormatIndicatorAndUniqueModId = "clang_" + UniqueModuleId.substr(1);
2606 else
2607 // Use the Pid and current time as the unique module id when we cannot
2608 // generate one based on a module's strong external symbols.
2609 // FIXME: Adjust the comment accordingly after we use source file full
2610 // path instead.
2611 FormatIndicatorAndUniqueModId =
2612 "clangPidTime_" + llvm::itostr(sys::Process::getProcessId()) +
2613 "_" + llvm::itostr(time(nullptr));
2614 }
2615
2616 emitSpecialLLVMGlobal(&G);
2617 continue;
2618 }
2619
2620 setCsectAlignment(&G);
2621 }
2622
2623 for (const auto &F : M)
2624 setCsectAlignment(&F);
2625
2626 // Construct an aliasing list for each GlobalObject.
2627 for (const auto &Alias : M.aliases()) {
2628 const GlobalObject *Base = Alias.getAliaseeObject();
2629 if (!Base)
2631 "alias without a base object is not yet supported on AIX");
2632 GOAliasMap[Base].push_back(&Alias);
2633 }
2634
2635 return Result;
2636}
2637
2638void PPCAIXAsmPrinter::emitInstruction(const MachineInstr *MI) {
2639 switch (MI->getOpcode()) {
2640 default:
2641 break;
2642 case PPC::TW:
2643 case PPC::TWI:
2644 case PPC::TD:
2645 case PPC::TDI: {
2646 if (MI->getNumOperands() < 5)
2647 break;
2648 const MachineOperand &LangMO = MI->getOperand(3);
2649 const MachineOperand &ReasonMO = MI->getOperand(4);
2650 if (!LangMO.isImm() || !ReasonMO.isImm())
2651 break;
2652 MCSymbol *TempSym = OutContext.createNamedTempSymbol();
2653 OutStreamer->emitLabel(TempSym);
2654 OutStreamer->emitXCOFFExceptDirective(CurrentFnSym, TempSym,
2655 LangMO.getImm(), ReasonMO.getImm(),
2656 Subtarget->isPPC64() ? MI->getMF()->getInstructionCount() * 8 :
2657 MI->getMF()->getInstructionCount() * 4,
2658 MMI->hasDebugInfo());
2659 break;
2660 }
2661 case PPC::GETtlsADDR64AIX:
2662 case PPC::GETtlsADDR32AIX: {
2663 // The reference to .__tls_get_addr is unknown to the assembler
2664 // so we need to emit an external symbol reference.
2665 MCSymbol *TlsGetAddr = createMCSymbolForTlsGetAddr(OutContext);
2666 ExtSymSDNodeSymbols.insert(TlsGetAddr);
2667 break;
2668 }
2669 case PPC::BL8:
2670 case PPC::BL:
2671 case PPC::BL8_NOP:
2672 case PPC::BL_NOP: {
2673 const MachineOperand &MO = MI->getOperand(0);
2674 if (MO.isSymbol()) {
2675 MCSymbolXCOFF *S =
2676 cast<MCSymbolXCOFF>(OutContext.getOrCreateSymbol(MO.getSymbolName()));
2677 ExtSymSDNodeSymbols.insert(S);
2678 }
2679 } break;
2680 case PPC::BL_TLS:
2681 case PPC::BL8_TLS:
2682 case PPC::BL8_TLS_:
2683 case PPC::BL8_NOP_TLS:
2684 report_fatal_error("TLS call not yet implemented");
2685 case PPC::TAILB:
2686 case PPC::TAILB8:
2687 case PPC::TAILBA:
2688 case PPC::TAILBA8:
2689 case PPC::TAILBCTR:
2690 case PPC::TAILBCTR8:
2691 if (MI->getOperand(0).isSymbol())
2692 report_fatal_error("Tail call for extern symbol not yet supported.");
2693 break;
2694 case PPC::DST:
2695 case PPC::DST64:
2696 case PPC::DSTT:
2697 case PPC::DSTT64:
2698 case PPC::DSTST:
2699 case PPC::DSTST64:
2700 case PPC::DSTSTT:
2701 case PPC::DSTSTT64:
2702 EmitToStreamer(
2703 *OutStreamer,
2704 MCInstBuilder(PPC::ORI).addReg(PPC::R0).addReg(PPC::R0).addImm(0));
2705 return;
2706 }
2707 return PPCAsmPrinter::emitInstruction(MI);
2708}
2709
2710bool PPCAIXAsmPrinter::doFinalization(Module &M) {
2711 // Do streamer related finalization for DWARF.
2712 if (!MAI->usesDwarfFileAndLocDirectives() && MMI->hasDebugInfo())
2713 OutStreamer->doFinalizationAtSectionEnd(
2714 OutStreamer->getContext().getObjectFileInfo()->getTextSection());
2715
2716 for (MCSymbol *Sym : ExtSymSDNodeSymbols)
2717 OutStreamer->emitSymbolAttribute(Sym, MCSA_Extern);
2718 return PPCAsmPrinter::doFinalization(M);
2719}
2720
2721static unsigned mapToSinitPriority(int P) {
2722 if (P < 0 || P > 65535)
2723 report_fatal_error("invalid init priority");
2724
2725 if (P <= 20)
2726 return P;
2727
2728 if (P < 81)
2729 return 20 + (P - 20) * 16;
2730
2731 if (P <= 1124)
2732 return 1004 + (P - 81);
2733
2734 if (P < 64512)
2735 return 2047 + (P - 1124) * 33878;
2736
2737 return 2147482625u + (P - 64512);
2738}
2739
2740static std::string convertToSinitPriority(int Priority) {
2741 // This helper function converts clang init priority to values used in sinit
2742 // and sterm functions.
2743 //
2744 // The conversion strategies are:
2745 // We map the reserved clang/gnu priority range [0, 100] into the sinit/sterm
2746 // reserved priority range [0, 1023] by
2747 // - directly mapping the first 21 and the last 20 elements of the ranges
2748 // - linear interpolating the intermediate values with a step size of 16.
2749 //
2750 // We map the non reserved clang/gnu priority range of [101, 65535] into the
2751 // sinit/sterm priority range [1024, 2147483648] by:
2752 // - directly mapping the first and the last 1024 elements of the ranges
2753 // - linear interpolating the intermediate values with a step size of 33878.
2754 unsigned int P = mapToSinitPriority(Priority);
2755
2756 std::string PrioritySuffix;
2757 llvm::raw_string_ostream os(PrioritySuffix);
2758 os << llvm::format_hex_no_prefix(P, 8);
2759 os.flush();
2760 return PrioritySuffix;
2761}
2762
2763void PPCAIXAsmPrinter::emitXXStructorList(const DataLayout &DL,
2764 const Constant *List, bool IsCtor) {
2765 SmallVector<Structor, 8> Structors;
2766 preprocessXXStructorList(DL, List, Structors);
2767 if (Structors.empty())
2768 return;
2769
2770 unsigned Index = 0;
2771 for (Structor &S : Structors) {
2772 if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(S.Func))
2773 S.Func = CE->getOperand(0);
2774
2777 (IsCtor ? llvm::Twine("__sinit") : llvm::Twine("__sterm")) +
2778 llvm::Twine(convertToSinitPriority(S.Priority)) +
2779 llvm::Twine("_", FormatIndicatorAndUniqueModId) +
2780 llvm::Twine("_", llvm::utostr(Index++)),
2781 cast<Function>(S.Func));
2782 }
2783}
2784
2785void PPCAIXAsmPrinter::emitTTypeReference(const GlobalValue *GV,
2786 unsigned Encoding) {
2787 if (GV) {
2788 MCSymbol *TypeInfoSym = TM.getSymbol(GV);
2789 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym);
2790 const MCSymbol *TOCBaseSym =
2791 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2792 ->getQualNameSymbol();
2793 auto &Ctx = OutStreamer->getContext();
2794 const MCExpr *Exp =
2796 MCSymbolRefExpr::create(TOCBaseSym, Ctx), Ctx);
2797 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
2798 } else
2799 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
2800}
2801
2802// Return a pass that prints the PPC assembly code for a MachineFunction to the
2803// given output stream.
2804static AsmPrinter *
2806 std::unique_ptr<MCStreamer> &&Streamer) {
2807 if (tm.getTargetTriple().isOSAIX())
2808 return new PPCAIXAsmPrinter(tm, std::move(Streamer));
2809
2810 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
2811}
2812
2813// Force static initialization.
2823}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This header is deprecated in favour of llvm/TargetParser/Triple.h.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:127
#define LLVM_DEBUG(X)
Definition: Debug.h:101
std::string Name
uint64_t Size
IRTranslator LLVM IR MI
#define RegName(no)
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)
Definition: MIParser.cpp:1397
This file implements a map that provides insertion order iteration.
Module.h This file contains the declarations for the Module class.
return ToRemove size() > 0
#define P(N)
static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV)
static bool isSpecialLLVMGlobalArrayToSkip(const GlobalVariable *GV)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter()
#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 AsmPrinter * createPPCAsmPrinterPass(TargetMachine &tm, std::unique_ptr< MCStreamer > &&Streamer)
static std::string convertToSinitPriority(int Priority)
#define GENVALUECOMMENT(PrefixAndName, V, Field)
static MCSymbol * createMCSymbolForTlsGetAddr(MCContext &Ctx)
This helper function creates the TlsGetAddr MCSymbol for AIX.
static unsigned mapToSinitPriority(int P)
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)
const char LLVMTargetMachineRef TM
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
This file defines the SmallPtrSet class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:467
Value * RHS
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:84
virtual void emitInstruction(const MachineInstr *)
Targets should implement this to emit instructions.
Definition: AsmPrinter.h:567
MCSymbol * getSymbol(const GlobalValue *GV) const
Definition: AsmPrinter.cpp:643
void emitXRayTable()
Emit a table with all XRay instrumentation points.
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)
Print the MachineOperand as a symbol.
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:543
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.
Definition: AsmPrinter.cpp:419
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
Definition: AsmPrinter.h:395
virtual bool PrintAsmMemoryOperand(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 as...
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.
A constant value that is initialized with an expression using other constant values.
Definition: Constants.h:998
This is an important base class in LLVM.
Definition: Constant.h:41
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:114
Tagged union holding either a T or a Error.
Definition: Error.h:470
Error takeError()
Take ownership of the stored error.
Definition: Error.h:597
reference get()
Returns a reference to the stored T value.
Definition: Error.h:567
static 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:520
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
Definition: GlobalObject.h:79
bool hasComdat() const
Definition: GlobalObject.h:127
VisibilityTypes getVisibility() const
Definition: GlobalValue.h:244
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:275
LinkageTypes getLinkage() const
Definition: GlobalValue.h:541
bool hasDefaultVisibility() const
Definition: GlobalValue.h:245
bool hasDLLExportStorageClass() const
Definition: GlobalValue.h:277
bool isDeclarationForLinker() const
Definition: GlobalValue.h:614
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:652
@ DefaultVisibility
The GV is visible.
Definition: GlobalValue.h:63
@ HiddenVisibility
The GV is hidden.
Definition: GlobalValue.h:64
@ ProtectedVisibility
The GV is protected.
Definition: GlobalValue.h:65
bool hasCommonLinkage() const
Definition: GlobalValue.h:527
bool hasAppendingLinkage() const
Definition: GlobalValue.h:520
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition: GlobalValue.h:56
@ CommonLinkage
Tentative definitions.
Definition: GlobalValue.h:58
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:55
@ LinkOnceAnyLinkage
Keep one copy of function when linking (inline)
Definition: GlobalValue.h:50
@ WeakODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:53
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
Definition: GlobalValue.h:52
@ AppendingLinkage
Special purpose, only applies to global arrays.
Definition: GlobalValue.h:54
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition: GlobalValue.h:49
@ ExternalWeakLinkage
ExternalWeak linkage description.
Definition: GlobalValue.h:57
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:51
Type * getValueType() const
Definition: GlobalValue.h:292
bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists.
bool hasInitializer() const
Definitions have initializers, declarations don't.
Binary assembler expressions.
Definition: MCExpr.h:481
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Definition: MCExpr.h:631
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:525
Opcode getOpcode() const
Get the kind of this binary expression.
Definition: MCExpr.h:625
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:610
@ Add
Addition.
Definition: MCExpr.h:484
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
Context object for machine code objects.
Definition: MCContext.h:76
MCSectionXCOFF * getXCOFFSection(StringRef Section, SectionKind K, std::optional< XCOFF::CsectProperties > CsectProp=std::nullopt, bool MultiSymbolsAllowed=false, const char *BeginSymName=nullptr, std::optional< XCOFF::DwarfSectionSubtypeFlags > DwarfSubtypeFlags=std::nullopt)
Definition: MCContext.cpp:773
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
Definition: MCInstBuilder.h:31
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:37
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Definition: MCInstBuilder.h:55
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
void setOpcode(unsigned Op)
Definition: MCInst.h:197
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:206
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
static MCOperand createExpr(const MCExpr *Val)
Definition: MCInst.h:162
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:69
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:26
MCSymbolXCOFF * getQualNameSymbol() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
void setAlignment(Align Value)
Definition: MCSection.h:141
void ensureMinAlignment(Align MinAlignment)
Makes sure that Alignment is at least MinAlignment.
Definition: MCSection.h:144
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:386
StringRef getSymbolTableName() const
Definition: MCSymbolXCOFF.h:59
void setStorageClass(XCOFF::StorageClass SC)
Definition: MCSymbolXCOFF.h:36
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:58
A single uniqued string.
Definition: Metadata.h:611
StringRef getString() const
Definition: Metadata.cpp:507
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
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.
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...
Representation of each machine instruction.
Definition: MachineInstr.h:68
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.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:37
iterator end()
Definition: MapVector.h:72
iterator find(const KeyT &Key)
Definition: MapVector.h:148
bool empty() const
Definition: MapVector.h:80
iterator begin()
Definition: MapVector.h:70
void clear()
Definition: MapVector.h:89
Root of the metadata hierarchy.
Definition: Metadata.h:61
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition: Module.cpp:398
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
MCSymbol * getPICOffsetSymbol(MachineFunction &MF) const
const SmallVectorImpl< Register > & getMustSaveCRs() const
unsigned getFloatingPointParmsNum() const
MCSymbol * getGlobalEPSymbol(MachineFunction &MF) const
MCSymbol * getLocalEPSymbol(MachineFunction &MF) const
unsigned getVectorParmsNum() const
uint32_t getVecExtParmsType() const
MCSymbol * getTOCOffsetSymbol(MachineFunction &MF) const
unsigned getFixedParmsNum() const
static const char * getRegisterName(MCRegister Reg)
static bool isVRRegister(unsigned Reg)
Definition: PPCInstrInfo.h:714
static bool isVFRegister(unsigned Reg)
Definition: PPCInstrInfo.h:711
static const PPCMCExpr * createLo(const MCExpr *Expr, MCContext &Ctx)
Definition: PPCMCExpr.h:49
static const PPCMCExpr * createHa(const MCExpr *Expr, MCContext &Ctx)
Definition: PPCMCExpr.h:57
static const char * stripRegisterPrefix(const char *RegName)
stripRegisterPrefix - This method strips the character prefix from a register name so that only the n...
bool is32BitELFABI() const
Definition: PPCSubtarget.h:219
bool isAIXABI() const
Definition: PPCSubtarget.h:214
const PPCFrameLowering * getFrameLowering() const override
Definition: PPCSubtarget.h:142
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
bool isUsingPCRelativeCalls() const
bool isELFv2ABI() const
const PPCRegisterInfo * getRegisterInfo() const override
Definition: PPCSubtarget.h:152
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
Common code between 32-bit and 64-bit PowerPC targets.
virtual void emitAbiVersion(int AbiVersion)
virtual void emitTCEntry(const MCSymbol &S, MCSymbolRefExpr::VariantKind Kind)
virtual void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset)
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:81
MI-level patchpoint operands.
Definition: StackMaps.h:76
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition: SectionKind.h:22
bool isThreadBSSLocal() const
Definition: SectionKind.h:163
static SectionKind getText()
Definition: SectionKind.h:190
bool isBSSLocal() const
Definition: SectionKind.h:170
static SectionKind getData()
Definition: SectionKind.h:213
bool isThreadLocal() const
Definition: SectionKind.h:157
bool isReadOnly() const
Definition: SectionKind.h:131
bool isGlobalWriteableData() const
Definition: SectionKind.h:165
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:450
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
bool empty() const
Definition: SmallVector.h:94
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
Definition: StackMaps.cpp:551
void recordStackMap(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
Definition: StackMaps.cpp:541
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:559
bool startswith(StringRef Prefix) const
Definition: StringRef.h:261
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Definition: StringSwitch.h:90
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.
Definition: TargetMachine.h:78
const Triple & getTargetTriple() const
bool isOSAIX() const
Tests whether the OS is AIX.
Definition: Triple.h:669
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
LLVM Value Representation.
Definition: Value.h:74
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:4695
Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
Definition: Value.cpp:918
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.
Definition: AsmWriter.cpp:4778
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:308
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:642
A raw_ostream that writes to an SmallVector or SmallString.
Definition: raw_ostream.h:672
static Pid getProcessId()
Get the process's identifier.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
Definition: BitmaskEnum.h:80
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
@ SHF_ALLOC
Definition: ELF.h:1083
@ SHF_WRITE
Definition: ELF.h:1080
@ SHT_PROGBITS
Definition: ELF.h:995
const uint64_t Version
Definition: InstrProf.h:1058
@ 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: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:150
@ 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:128
@ 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:145
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
Definition: PPCPredicates.h:26
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
SmallString< 32 > getExtendedTBTableFlagString(uint8_t Flag)
Definition: XCOFF.cpp:162
Expected< SmallString< 32 > > parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum, unsigned VectorParmsNum)
Definition: XCOFF.cpp:188
Expected< SmallString< 32 > > parseParmsType(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum)
Definition: XCOFF.cpp:110
Expected< SmallString< 32 > > parseVectorParmsType(uint32_t Value, unsigned ParmsNum)
Definition: XCOFF.cpp:240
@ XMC_RW
Read Write Data.
Definition: XCOFF.h:116
@ XMC_RO
Read Only Constant.
Definition: XCOFF.h:105
@ XMC_PR
Program Code.
Definition: XCOFF.h:104
StringRef getNameForTracebackTableLanguageId(TracebackTable::LanguageID LangId)
Definition: XCOFF.cpp:87
constexpr uint8_t AllocRegNo
Definition: XCOFF.h:43
@ XTY_SD
Csect definition for initialized storage.
Definition: XCOFF.h:241
@ XTY_ER
External reference.
Definition: XCOFF.h:240
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:445
static unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
Definition: DenseMapInfo.h:30
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:386
Target & getThePPC64LETarget()
bool LowerPPCMachineOperandToMCOperand(const MachineOperand &MO, MCOperand &OutMO, AsmPrinter &AP)
Target & getThePPC32Target()
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)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:145
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:199
Target & getThePPC64Target()
std::pair< MCSection *, const MCExpr * > MCSectionSubPair
Definition: MCStreamer.h:66
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:1862
MCSymbolAttr
Definition: MCDirectives.h:18
@ MCSA_Weak
.weak
Definition: MCDirectives.h:45
@ MCSA_Global
.type _foo, @gnu_unique_object
Definition: MCDirectives.h:30
@ MCSA_Extern
.extern (XCOFF)
Definition: MCDirectives.h:32
@ MCSA_LGlobal
.lglobl (XCOFF)
Definition: MCDirectives.h:31
@ MCSA_Invalid
Not a valid directive.
Definition: MCDirectives.h:19
Definition: BitVector.h:851
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
std::pair< const MCSymbol *, MCSymbolRefExpr::VariantKind > TOCKey
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:51
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:410
static constexpr uint16_t NumberOfVRSavedMask
Definition: XCOFF.h:440
static constexpr uint8_t NumberOfFloatingPointParmsShift
Definition: XCOFF.h:426
static constexpr uint32_t NumberOfFixedParmsMask
Definition: XCOFF.h:420
static constexpr uint16_t HasVMXInstructionMask
Definition: XCOFF.h:446
static constexpr uint32_t IsLRSavedMask
Definition: XCOFF.h:404
static constexpr uint16_t HasVarArgsMask
Definition: XCOFF.h:442
static constexpr uint32_t IsAllocaUsedMask
Definition: XCOFF.h:401
static constexpr uint16_t IsVRSavedOnStackMask
Definition: XCOFF.h:441
static constexpr uint16_t NumberOfVectorParmsMask
Definition: XCOFF.h:445
static constexpr uint32_t IsFloatingPointPresentMask
Definition: XCOFF.h:394
static constexpr uint32_t FPRSavedShift
Definition: XCOFF.h:411
static constexpr uint32_t NumberOfFloatingPointParmsMask
Definition: XCOFF.h:424
static constexpr uint32_t HasControlledStorageMask
Definition: XCOFF.h:392
static constexpr uint32_t HasExtensionTableMask
Definition: XCOFF.h:414
static constexpr uint32_t HasTraceBackTableOffsetMask
Definition: XCOFF.h:390
static constexpr uint32_t IsCRSavedMask
Definition: XCOFF.h:403
static constexpr uint8_t NumberOfFixedParmsShift
Definition: XCOFF.h:421
static constexpr uint32_t GPRSavedMask
Definition: XCOFF.h:416
static constexpr uint8_t NumberOfVectorParmsShift
Definition: XCOFF.h:447
static constexpr uint32_t HasParmsOnStackMask
Definition: XCOFF.h:425
static constexpr uint32_t IsFunctionNamePresentMask
Definition: XCOFF.h:400
static constexpr uint32_t IsBackChainStoredMask
Definition: XCOFF.h:408
static constexpr uint32_t IsInterruptHandlerMask
Definition: XCOFF.h:399
static constexpr uint32_t HasVectorInfoMask
Definition: XCOFF.h:415
static constexpr uint8_t NumberOfVRSavedShift
Definition: XCOFF.h:443
static constexpr uint32_t GPRSavedShift
Definition: XCOFF.h:417