1//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly ------===// 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 7//===----------------------------------------------------------------------===// 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'. 13// Documentation at http://developer.apple.com/documentation/DeveloperTools/ 14// Reference/Assembler/ASMIntroduction/chapter_1_section_1.html 16//===----------------------------------------------------------------------===// 85#define DEBUG_TYPE "asmprinter" 87STATISTIC(NumTOCEntries,
"Number of Total TOC Entries Emitted.");
88STATISTIC(NumTOCConstPool,
"Number of Constant Pool TOC Entries.");
90"Number of Internal Linkage Global TOC Entries.");
92"Number of External Linkage Global TOC Entries.");
93STATISTIC(NumTOCJumpTable,
"Number of Jump Table TOC Entries.");
94STATISTIC(NumTOCThreadLocal,
"Number of Thread Local TOC Entries.");
95STATISTIC(NumTOCBlockAddress,
"Number of Block Address TOC Entries.");
96STATISTIC(NumTOCEHBlock,
"Number of EH Block TOC Entries.");
102// Specialize DenseMapInfo to allow 103// std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind> in DenseMap. 104// This specialization is needed here because that type is used as keys in the 105// map representing TOC entries. 109usingTOCKey = std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>;
124}
// end namespace llvm 129// GNU attribute tags for PowerPC ABI 130 Tag_GNU_Power_ABI_FP = 4,
131 Tag_GNU_Power_ABI_Vector = 8,
132 Tag_GNU_Power_ABI_Struct_Return = 12,
134// GNU attribute values for PowerPC float ABI, as combination of two parts 135 Val_GNU_Power_ABI_NoFloat = 0b00,
136 Val_GNU_Power_ABI_HardFloat_DP = 0b01,
137 Val_GNU_Power_ABI_SoftFloat_DP = 0b10,
138 Val_GNU_Power_ABI_HardFloat_SP = 0b11,
140 Val_GNU_Power_ABI_LDBL_IBM128 = 0b0100,
141 Val_GNU_Power_ABI_LDBL_64 = 0b1000,
142 Val_GNU_Power_ABI_LDBL_IEEE128 = 0b1100,
147// For TLS on AIX, we need to be able to identify TOC entries of specific 148// VariantKind so we can add the right relocations when we generate the 149// entries. So each entry is represented by a pair of MCSymbol and 150// VariantKind. For example, we need to be able to identify the following 151// entry as a TLSGD entry so we can add the @m relocation: 153// By default, VK_None is used for the VariantKind. 159// Keep track of the number of TLS variables and their corresponding 160// addresses, which is then used for the assembly printing of 161// non-TOC-based local-exec variables. 166 std::unique_ptr<MCStreamer> Streamer)
172 TOCType_ConstantPool,
173 TOCType_GlobalExternal,
174 TOCType_GlobalInternal,
177 TOCType_BlockAddress,
183 MCSymbolRefExpr::VariantKind::VK_None);
193 /// This function is for PrintAsmOperand and PrintAsmMemoryOperand, 194 /// invoked by EmitMSInlineAsmStr and EmitGCCInlineAsmStr only. 195 /// The \p MI would be INLINEASM ONLY. 218/// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux 219classPPCLinuxAsmPrinter :
public PPCAsmPrinter {
222 std::unique_ptr<MCStreamer> Streamer)
223 : PPCAsmPrinter(
TM,
std::
move(Streamer)) {}
226return"Linux PPC Assembly Printer";
229void emitGNUAttributes(
Module &M);
231void emitStartOfAsmFile(
Module &M)
override;
232void emitEndOfAsmFile(
Module &)
override;
234void emitFunctionEntryLabel()
override;
236void emitFunctionBodyStart()
override;
237void emitFunctionBodyEnd()
override;
241classPPCAIXAsmPrinter :
public PPCAsmPrinter {
243 /// Symbols lowered from ExternalSymbolSDNodes, we will need to emit extern 244 /// linkage for them in AIX. 247 /// A format indicator and unique trailing identifier to form part of the 248 /// sinit/sterm function names. 249 std::string FormatIndicatorAndUniqueModId;
251// Record a list of GlobalAlias associated with a GlobalObject. 252// This is used for AIX's extra-label-at-definition aliasing strategy. 257void emitTracebackTable();
263// Get the offset of an alias based on its AliaseeObject. 267 PPCAIXAsmPrinter(
TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
268 : PPCAsmPrinter(
TM,
std::
move(Streamer)) {
269if (MAI->isLittleEndian())
271"cannot create AIX PPC Assembly Printer for a little-endian target");
274StringRef getPassName()
const override{
return"AIX PPC Assembly Printer"; }
276bool doInitialization(
Module &M)
override;
285void emitFunctionDescriptor()
override;
287void emitFunctionEntryLabel()
override;
289void emitFunctionBodyEnd()
override;
291void emitPGORefs(
Module &M);
295void emitEndOfAsmFile(
Module &)
override;
301bool doFinalization(
Module &M)
override;
303void emitTTypeReference(
constGlobalValue *GV,
unsigned Encoding)
override;
305void emitModuleCommandLines(
Module &M)
override;
308}
// end anonymous namespace 312// Computing the address of a global symbol, not calling it. 314 getSymbol(GV)->
print(O, MAI);
318void PPCAsmPrinter::printOperand(
constMachineInstr *
MI,
unsigned OpNo,
325// The MI is INLINEASM ONLY and UseVSXReg is always false. 328// Linux assembler (Others?) does not take register mnemonics. 329// FIXME - What about special registers used in mfspr/mtspr? 341O <<
DL.getPrivateGlobalPrefix() <<
"CPI" << getFunctionNumber() <<
'_' 348 PrintSymbolOperand(MO, O);
358/// PrintAsmOperand - Print out an operand for an inline asm expression. 360bool PPCAsmPrinter::PrintAsmOperand(
constMachineInstr *
MI,
unsigned OpNo,
362// Does this asm operand have a single letter operand modifier? 363if (ExtraCode && ExtraCode[0]) {
364if (ExtraCode[1] != 0)
returntrue;
// Unknown modifier. 366switch (ExtraCode[0]) {
368// See if this is a generic print operand 370case'L':
// Write second word of DImode reference. 371// Verify that this operand has two consecutive registers. 372if (!
MI->getOperand(OpNo).isReg() ||
373 OpNo+1 ==
MI->getNumOperands() ||
374 !
MI->getOperand(OpNo+1).isReg())
376 ++OpNo;
// Return the high-part. 379// Write 'i' if an integer constant, otherwise nothing. Used to print 381if (
MI->getOperand(OpNo).isImm())
385if(!
MI->getOperand(OpNo).isReg())
387// This operand uses VSX numbering. 388// If the operand is a VMX register, convert it to a VSX register. 391Reg = PPC::VSX32 + (
Reg - PPC::V0);
393 Reg = PPC::VSX32 + (Reg - PPC::VF0);
406// At the moment, all inline asm memory operands are a single register. 407// In any case, the output of this routine should always be just one 409bool PPCAsmPrinter::PrintAsmMemoryOperand(
constMachineInstr *
MI,
unsigned OpNo,
412if (ExtraCode && ExtraCode[0]) {
413if (ExtraCode[1] != 0)
returntrue;
// Unknown modifier. 415switch (ExtraCode[0]) {
416default:
returntrue;
// Unknown modifier. 417case'L':
// A memory reference to the upper word of a double word op. 418O << getDataLayout().getPointerSize() <<
"(";
422case'y':
// A memory reference for an X-form instruction 427// Write 'i' if an integer constant, otherwise nothing. Used to print 429if (
MI->getOperand(OpNo).isImm())
432case'U':
// Print 'u' for update form. 433case'X':
// Print 'x' for indexed form. 434// FIXME: Currently for PowerPC memory operands are always loaded 435// into a register, so we never get an update or indexed form. 436// This is bad even for offset forms, since even if we know we 437// have a value in -16(r1), we will generate a load into r<n> 438// and then load from 0(r<n>). Until that issue is fixed, 439// tolerate 'U' and 'X' but don't output anything. 440assert(
MI->getOperand(OpNo).isReg());
445assert(
MI->getOperand(OpNo).isReg());
455case PPCAsmPrinter::TOCType_ConstantPool:
458case PPCAsmPrinter::TOCType_GlobalInternal:
459 ++NumTOCGlobalInternal;
461case PPCAsmPrinter::TOCType_GlobalExternal:
462 ++NumTOCGlobalExternal;
464case PPCAsmPrinter::TOCType_JumpTable:
467case PPCAsmPrinter::TOCType_ThreadLocal:
470case PPCAsmPrinter::TOCType_BlockAddress:
471 ++NumTOCBlockAddress;
473case PPCAsmPrinter::TOCType_EHBlock:
484// If the operand is not a global address then there is no 485// global variable to carry an attribute. 490assert(GV &&
"expected global for MO_GlobalAddress");
508/// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry 509/// exists for it. If not, create one. Then return a symbol that references 512PPCAsmPrinter::lookUpOrCreateTOCEntry(
constMCSymbol *
Sym, TOCEntryType
Type,
514// If this is a new TOC entry add statistics about it. 515if (!
TOC.contains({Sym, Kind}))
520 TOCEntry = createTempSymbol(
"C");
525unsigned NumNOPBytes =
MI.getOperand(1).getImm();
527auto &Ctx = OutStreamer->getContext();
528MCSymbol *MILabel = Ctx.createTempSymbol();
529 OutStreamer->emitLabel(MILabel);
532assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
534// Scan ahead to trim the shadow. 538while (NumNOPBytes > 0) {
539if (MII ==
MBB.
end() || MII->isCall() ||
540 MII->getOpcode() == PPC::DBG_VALUE ||
541 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
542 MII->getOpcode() == TargetOpcode::STACKMAP)
549for (
unsigned i = 0; i < NumNOPBytes; i += 4)
553// Lower a patchpoint of the form: 554// [<def>], <id>, <numBytes>, <target>, <numArgs> 556auto &Ctx = OutStreamer->getContext();
557MCSymbol *MILabel = Ctx.createTempSymbol();
558 OutStreamer->emitLabel(MILabel);
563unsigned EncodedBytes = 0;
566if (CalleeMO.
isImm()) {
567 int64_t CallTarget = CalleeMO.
getImm();
569assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
570"High 16 bits of call target should be zero.");
571Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
573// Materialize the jump address: 576 .addImm((CallTarget >> 32) & 0xFFFF));
581 .addImm(32).addImm(16));
586 .addImm((CallTarget >> 16) & 0xFFFF));
591 .addImm(CallTarget & 0xFFFF));
593// Save the current TOC pointer before the remote call. 597 .addImm(TOCSaveOffset)
601// If we're on ELFv1, then we need to load the actual function pointer 602// from the function descriptor. 604// Load the new TOC pointer and the function address, but not r11 605// (needing this is rare, and loading it here would prevent passing it 606// via a 'nest' parameter. 610 .addReg(ScratchReg));
615 .addReg(ScratchReg));
620 .addReg(ScratchReg));
625// Restore the TOC pointer after the call. 628 .addImm(TOCSaveOffset)
634MCSymbol *MOSymbol = getSymbol(GValue);
642// Each instruction is 4 bytes. 646unsigned NumBytes = Opers.getNumPatchBytes();
647assert(NumBytes >= EncodedBytes &&
648"Patchpoint can't request size less than the length of a call.");
649assert((NumBytes - EncodedBytes) % 4 == 0 &&
650"Invalid number of NOP bytes requested!");
651for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
655/// This helper function creates the TlsGetAddr/TlsGetMod MCSymbol for AIX. We 656/// will create the csect and use the qual-name symbol instead of creating just 657/// the external symbol. 662 SymName =
".__tls_get_addr";
664case PPC::GETtlsTpointer32AIX:
665 SymName =
".__get_tpointer";
667case PPC::GETtlsMOD32AIX:
668case PPC::GETtlsMOD64AIX:
669 SymName =
".__tls_get_mod";
680"Only expecting to emit calls to get the thread pointer on AIX!");
685 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::BLA).addExpr(TlsRef));
688/// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a 689/// call to __tls_get_addr to the current output stream. 693unsigned Opcode = PPC::BL8_NOP_TLS;
695assert(
MI->getNumOperands() >= 3 &&
"Expecting at least 3 operands from MI");
699 Opcode = PPC::BL8_NOTOC_TLS;
701constModule *
M = MF->getFunction().getParent();
704 ((Subtarget->
isPPC64() &&
MI->getOperand(0).getReg() == PPC::X3) ||
705 (!Subtarget->
isPPC64() &&
MI->getOperand(0).getReg() == PPC::R3)) &&
706"GETtls[ld]ADDR[32] must define GPR3");
708 ((Subtarget->
isPPC64() &&
MI->getOperand(1).getReg() == PPC::X3) ||
709 (!Subtarget->
isPPC64() &&
MI->getOperand(1).getReg() == PPC::R3)) &&
710"GETtls[ld]ADDR[32] must read GPR3");
713// For TLSGD, the variable offset should already be in R4 and the region 714// handle should already be in R3. We generate an absolute branch to 715// .__tls_get_addr. For TLSLD, the module handle should already be in R3. 716// We generate an absolute branch to .__tls_get_mod. 719assert((
MI->getOpcode() == PPC::GETtlsMOD32AIX ||
720MI->getOpcode() == PPC::GETtlsMOD64AIX ||
721 (
MI->getOperand(2).isReg() &&
722MI->getOperand(2).getReg() == VarOffsetReg)) &&
723"GETtls[ld]ADDR[32] must read GPR4");
724 EmitAIXTlsCallHelper(
MI);
728MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(
"__tls_get_addr");
736// Add 32768 offset to the symbol so we follow up the latest GOT/PLT ABI. 743MCSymbol *MOSymbol = getSymbol(GValue);
745 EmitToStreamer(*OutStreamer,
747 : (
unsigned)PPC::BL_TLS)
752/// Map a machine operand for a TOC pseudo-machine instruction to its 753/// corresponding MCSymbol. 770static PPCAsmPrinter::TOCEntryType
772// Use the target flags to determine if this MO is Thread Local. 773// If we don't do this it comes out as Global. 775return PPCAsmPrinter::TOCType_ThreadLocal;
784return PPCAsmPrinter::TOCType_GlobalExternal;
786return PPCAsmPrinter::TOCType_GlobalInternal;
789return PPCAsmPrinter::TOCType_ConstantPool;
791return PPCAsmPrinter::TOCType_JumpTable;
793return PPCAsmPrinter::TOCType_BlockAddress;
798/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to 799/// the current output stream. 802 PPC_MC::verifyInstructionPredicates(
MI->getOpcode(),
803 getSubtargetInfo().getFeatureBits());
806constbool IsPPC64 = Subtarget->
isPPC64();
807constbool IsAIX = Subtarget->
isAIXABI();
808constbool HasAIXSmallLocalTLS = Subtarget->hasAIXSmallLocalExecTLS() ||
809 Subtarget->hasAIXSmallLocalDynamicTLS();
810constModule *
M = MF->getFunction().getParent();
814// Validate that SPE and FPU are mutually exclusive in codegen 815if (!
MI->isInlineAsm()) {
819if (Subtarget->hasSPE()) {
820if (PPC::F4RCRegClass.
contains(Reg) ||
829if (PPC::SPERCRegClass.
contains(Reg))
837auto getTOCRelocAdjustedExprForXCOFF = [
this](
constMCExpr *Expr,
839// Apply an offset to the TOC-based expression such that the adjusted 840// notional offset from the TOC base (to be encoded into the instruction's D 841// or DS field) is the signed 16-bit truncation of the original notional 842// offset from the TOC base. 843// This is consistent with the treatment used both by XL C/C++ and 846 OriginalOffset - llvm::SignExtend32<16>(OriginalOffset);
851auto getTOCEntryLoadingExprForXCOFF =
852 [IsPPC64, getTOCRelocAdjustedExprForXCOFF,
855 MCSymbolRefExpr::VariantKind::VK_None) ->
constMCExpr * {
856constunsigned EntryByteSize = IsPPC64 ? 8 : 4;
857constauto TOCEntryIter =
TOC.find({MOSymbol, VK});
859"Could not find the TOC entry for this symbol.");
861 (TOCEntryIter -
TOC.begin()) * EntryByteSize;
862constexpr int16_t PositiveTOCRange = INT16_MAX;
864if (EntryDistanceFromTOCBase > PositiveTOCRange)
865return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase);
870// For TLS initial-exec and local-exec accesses on AIX, we have one TOC 871// entry for the symbol (with the variable offset), which is differentiated 877assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!\n");
880return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE;
882return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
883// On AIX, TLS model opt may have turned local-dynamic accesses into 884// initial-exec accesses. 889dbgs() <<
"Current function uses IE access for default LD vars.\n");
890return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
894// For GD TLS access on AIX, we have two TOC entries for the symbol (one for 895// the variable offset and the other for the region handle). They are 896// differentiated by MO_TLSGD_FLAG and MO_TLSGDM_FLAG. 898return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM;
900return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD;
901// For local-dynamic TLS access on AIX, we have one TOC entry for the symbol 902// (the variable offset) and one shared TOC entry for the module handle. 903// They are differentiated by MO_TLSLD_FLAG and MO_TLSLDM_FLAG. 905return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD;
907return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSML;
908return MCSymbolRefExpr::VariantKind::VK_None;
911// Lower multi-instruction pseudo operations. 912switch (
MI->getOpcode()) {
914case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
916"AIX does not support patchable function entry!");
917// PATCHABLE_FUNCTION_ENTER on little endian is for XRAY support which is 918// handled in PPCLinuxAsmPrinter. 919if (MAI->isLittleEndian())
923 (void)
F.getFnAttribute(
"patchable-function-entry")
925 .getAsInteger(10, Num);
931case TargetOpcode::DBG_VALUE:
933case TargetOpcode::STACKMAP:
934return LowerSTACKMAP(SM, *
MI);
935case TargetOpcode::PATCHPOINT:
936return LowerPATCHPOINT(SM, *
MI);
938case PPC::MoveGOTtoLR: {
939// Transform %lr = MoveGOTtoLR 940// Into this: bl _GLOBAL_OFFSET_TABLE_@local-4 941// _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding 942// _GLOBAL_OFFSET_TABLE_) has exactly one instruction: 944// This will return the pointer to _GLOBAL_OFFSET_TABLE_@local 946 OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
955 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::BL).addExpr(OffsExpr));
959case PPC::MovePCtoLR8: {
960// Transform %lr = MovePCtoLR 961// Into this, where the label is the PIC base: 964MCSymbol *PICBase = MF->getPICBaseSymbol();
967 EmitToStreamer(*OutStreamer,
969// FIXME: We would like an efficient form for this, so we 970// don't have to do a lot of extra uniquing. 974 OutStreamer->emitLabel(PICBase);
977case PPC::UpdateGBR: {
978// Transform %rd = UpdateGBR(%rt, %ri) 979// Into: lwz %rt, .L0$poff - .L0$pb(%ri) 981// or into (if secure plt mode is on): 982// addis r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@ha 983// addi r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@l 984// Get the offset from the GOT Base Register to the GOT 986if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
988MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
1000MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));
1005MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
1020// Step 1: lwz %rt, .L$poff - .L$pb(%ri) 1025 EmitToStreamer(*OutStreamer, TmpInst);
1031 EmitToStreamer(*OutStreamer, TmpInst);
1036// Transform %rN = LWZtoc @op1, %r2 1039// Change the opcode to LWZ. 1044"Invalid operand for LWZtoc.");
1046// Map the operand to its corresponding MCSymbol. 1049// Create a reference to the GOT entry for the symbol. The GOT entry will be 1050// synthesized later. 1056 EmitToStreamer(*OutStreamer, TmpInst);
1062// Otherwise, use the TOC. 'TOCEntry' is a label used to reference the 1063// storage allocated in the TOC which contains the address of 1064// 'MOSymbol'. Said TOC entry will be synthesized later. 1070// AIX uses the label directly as the lwz displacement operand for 1071// references into the toc section. The displacement value will be generated 1072// relative to the toc-base. 1076"This pseudo should only be selected for 32-bit small code model.");
1077Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK);
1080// Print MO for better readability 1082 OutStreamer->getCommentOS() << MO <<
'\n';
1083 EmitToStreamer(*OutStreamer, TmpInst);
1087// Create an explicit subtract expression between the local symbol and 1088// '.LTOC' to manifest the toc-relative offset. 1090 OutContext.getOrCreateSymbol(
Twine(
".LTOC")), OutContext);
1093 EmitToStreamer(*OutStreamer, TmpInst);
1097case PPC::ADDItoc8: {
1099"PseudoOp only valid for small code model AIX");
1101// Transform %rN = ADDItoc/8 %r2, @op1. 1104// Change the opcode to load address. 1105 TmpInst.
setOpcode((!IsPPC64) ? (PPC::LA) : (PPC::LA8));
1110// Map the operand to its corresponding MCSymbol. 1117 EmitToStreamer(*OutStreamer, TmpInst);
1124// Transform %x3 = LDtoc @min1, %x2 1127// Change the opcode to LD. 1134// Map the operand to its corresponding MCSymbol. 1139// Map the machine operand to its corresponding MCSymbol, then map the 1140// global address operand to be a reference to the TOC entry we will 1149 IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK) : Exp);
1151// Print MO for better readability 1152if (isVerbose() && IsAIX)
1153 OutStreamer->getCommentOS() << MO <<
'\n';
1154 EmitToStreamer(*OutStreamer, TmpInst);
1157case PPC::ADDIStocHA: {
1161"Invalid operand for ADDIStocHA.");
1162assert((IsAIX && !IsPPC64 &&
1164"This pseudo should only be selected for 32-bit large code model on" 1167// Transform %rd = ADDIStocHA %rA, @sym(%r2) 1170// Change the opcode to ADDIS. 1173// Map the machine operand to its corresponding MCSymbol. 1178// Map the global address operand to be a reference to the TOC entry we 1179// will synthesize later. 'TOCEntry' is a label used to reference the 1180// storage allocated in the TOC which contains the address of 'MOSymbol'. 1181// If the symbol does not have the toc-data attribute, then we create the 1182// TOC entry on AIX. If the toc-data attribute is used, the TOC entry 1183// contains the data rather than the address of the MOSymbol. 1191return GV->hasAttribute(
"toc-data");
1199 EmitToStreamer(*OutStreamer, TmpInst);
1206"Invalid operand for LWZtocL.");
1207assert(IsAIX && !IsPPC64 &&
1209"This pseudo should only be selected for 32-bit large code model on" 1212// Transform %rd = LWZtocL @sym, %rs. 1215// Change the opcode to lwz. 1218// Map the machine operand to its corresponding MCSymbol. 1223// Always use TOC on AIX. Map the global address operand to be a reference 1224// to the TOC entry we will synthesize later. 'TOCEntry' is a label used to 1225// reference the storage allocated in the TOC which contains the address of 1233 EmitToStreamer(*OutStreamer, TmpInst);
1236case PPC::ADDIStocHA8: {
1237// Transform %xd = ADDIStocHA8 %x2, @sym 1240// Change the opcode to ADDIS8. If the global address is the address of 1241// an external symbol, is a jump table address, is a block address, or is a 1242// constant pool index with large code model enabled, then generate a TOC 1243// entry and reference that. Otherwise, reference the symbol directly. 1248"Invalid operand for ADDIStocHA8!");
1254constbool GlobalToc =
1276 EmitToStreamer(*OutStreamer, TmpInst);
1280// Transform %xd = LDtocL @sym, %xs 1283// Change the opcode to LD. If the global address is the address of 1284// an external symbol, is a jump table address, is a block address, or is 1285// a constant pool index with large code model enabled, then generate a 1286// TOC entry and reference that. Otherwise, reference the symbol directly. 1292"Invalid operand for LDtocL!");
1296"LDtocL used on symbol that could be accessed directly is " 1297"invalid. Must match ADDIStocHA8."));
1311 EmitToStreamer(*OutStreamer, TmpInst);
1315case PPC::ADDItocL8: {
1316// Transform %xd = ADDItocL %xs, @sym 1319unsignedOp =
MI->getOpcode();
1321// Change the opcode to load address for toc-data. 1322// ADDItocL is only used for 32-bit toc-data on AIX and will always use LA. 1323 TmpInst.
setOpcode(
Op == PPC::ADDItocL8 ? (IsAIX ? PPC::LA8 : PPC::ADDI8)
1329 : MO.
isGlobal() &&
"Invalid operand for ADDItocL8.");
1331"Interposable definitions must use indirect accesses.");
1333// Map the operand to its corresponding MCSymbol. 1342 EmitToStreamer(*OutStreamer, TmpInst);
1345case PPC::ADDISgotTprelHA: {
1346// Transform: %xd = ADDISgotTprelHA %x2, @sym 1347// Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha 1348assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1351MCSymbol *MOSymbol = getSymbol(GValue);
1352constMCExpr *SymGotTprel =
1356 .addReg(
MI->getOperand(0).getReg())
1357 .
addReg(
MI->getOperand(1).getReg())
1361case PPC::LDgotTprelL:
1362case PPC::LDgotTprelL32: {
1363// Transform %xd = LDgotTprelL @sym, %xs 1366// Change the opcode to LD. 1367 TmpInst.
setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ);
1370MCSymbol *MOSymbol = getSymbol(GValue);
1376 EmitToStreamer(*OutStreamer, TmpInst);
1380case PPC::PPC32PICGOT: {
1381MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1382MCSymbol *GOTRef = OutContext.createTempSymbol();
1383MCSymbol *NextInstr = OutContext.createTempSymbol();
1386// FIXME: We would like an efficient form for this, so we don't have to do 1387// a lot of extra uniquing. 1393 OutStreamer->emitLabel(GOTRef);
1394 OutStreamer->emitValue(OffsExpr, 4);
1395 OutStreamer->emitLabel(NextInstr);
1397 .addReg(
MI->getOperand(0).getReg()));
1399 .addReg(
MI->getOperand(1).getReg())
1401 .
addReg(
MI->getOperand(0).getReg()));
1403 .addReg(
MI->getOperand(0).getReg())
1404 .
addReg(
MI->getOperand(1).getReg())
1405 .
addReg(
MI->getOperand(0).getReg()));
1408case PPC::PPC32GOT: {
1410 OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1416 .addReg(
MI->getOperand(0).getReg())
1419 .addReg(
MI->getOperand(0).getReg())
1420 .
addReg(
MI->getOperand(0).getReg())
1424case PPC::ADDIStlsgdHA: {
1425// Transform: %xd = ADDIStlsgdHA %x2, @sym 1426// Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha 1427assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1430MCSymbol *MOSymbol = getSymbol(GValue);
1431constMCExpr *SymGotTlsGD =
1435 .addReg(
MI->getOperand(0).getReg())
1436 .
addReg(
MI->getOperand(1).getReg())
1440case PPC::ADDItlsgdL:
1441// Transform: %xd = ADDItlsgdL %xs, @sym 1442// Into: %xd = ADDI8 %xs, sym@got@tlsgd@l 1443case PPC::ADDItlsgdL32: {
1444// Transform: %rd = ADDItlsgdL32 %rs, @sym 1445// Into: %rd = ADDI %rs, sym@got@tlsgd 1448MCSymbol *MOSymbol = getSymbol(GValue);
1453 EmitToStreamer(*OutStreamer,
1455 .addReg(
MI->getOperand(0).getReg())
1456 .
addReg(
MI->getOperand(1).getReg())
1460case PPC::GETtlsMOD32AIX:
1461case PPC::GETtlsMOD64AIX:
1462// Transform: %r3 = GETtlsMODNNAIX %r3 (for NN == 32/64). 1463// Into: BLA .__tls_get_mod() 1464// Input parameter is a module handle (_$TLSML[TC]@ml) for all variables. 1465case PPC::GETtlsADDR:
1466// Transform: %x3 = GETtlsADDR %x3, @sym 1467// Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd) 1468case PPC::GETtlsADDRPCREL:
1469case PPC::GETtlsADDR32AIX:
1470case PPC::GETtlsADDR64AIX:
1471// Transform: %r3 = GETtlsADDRNNAIX %r3, %r4 (for NN == 32/64). 1472// Into: BLA .__tls_get_addr() 1473// Unlike on Linux, there is no symbol or relocation needed for this call. 1474case PPC::GETtlsADDR32: {
1475// Transform: %r3 = GETtlsADDR32 %r3, @sym 1476// Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT 1480case PPC::GETtlsTpointer32AIX: {
1481// Transform: %r3 = GETtlsTpointer32AIX 1482// Into: BLA .__get_tpointer() 1483 EmitAIXTlsCallHelper(
MI);
1486case PPC::ADDIStlsldHA: {
1487// Transform: %xd = ADDIStlsldHA %x2, @sym 1488// Into: %xd = ADDIS8 %x2, sym@got@tlsld@ha 1489assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1492MCSymbol *MOSymbol = getSymbol(GValue);
1493constMCExpr *SymGotTlsLD =
1497 .addReg(
MI->getOperand(0).getReg())
1498 .
addReg(
MI->getOperand(1).getReg())
1502case PPC::ADDItlsldL:
1503// Transform: %xd = ADDItlsldL %xs, @sym 1504// Into: %xd = ADDI8 %xs, sym@got@tlsld@l 1505case PPC::ADDItlsldL32: {
1506// Transform: %rd = ADDItlsldL32 %rs, @sym 1507// Into: %rd = ADDI %rs, sym@got@tlsld 1510MCSymbol *MOSymbol = getSymbol(GValue);
1515 EmitToStreamer(*OutStreamer,
1517 .addReg(
MI->getOperand(0).getReg())
1518 .
addReg(
MI->getOperand(1).getReg())
1522case PPC::GETtlsldADDR:
1523// Transform: %x3 = GETtlsldADDR %x3, @sym 1524// Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld) 1525case PPC::GETtlsldADDRPCREL:
1526case PPC::GETtlsldADDR32: {
1527// Transform: %r3 = GETtlsldADDR32 %r3, @sym 1528// Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT 1532case PPC::ADDISdtprelHA:
1533// Transform: %xd = ADDISdtprelHA %xs, @sym 1534// Into: %xd = ADDIS8 %xs, sym@dtprel@ha 1535case PPC::ADDISdtprelHA32: {
1536// Transform: %rd = ADDISdtprelHA32 %rs, @sym 1537// Into: %rd = ADDIS %rs, sym@dtprel@ha 1540MCSymbol *MOSymbol = getSymbol(GValue);
1547 .addReg(
MI->getOperand(0).getReg())
1548 .
addReg(
MI->getOperand(1).getReg())
1552case PPC::PADDIdtprel: {
1553// Transform: %rd = PADDIdtprel %rs, @sym 1554// Into: %rd = PADDI8 %rs, sym@dtprel 1557MCSymbol *MOSymbol = getSymbol(GValue);
1561 .addReg(
MI->getOperand(0).getReg())
1562 .
addReg(
MI->getOperand(1).getReg())
1567case PPC::ADDIdtprelL:
1568// Transform: %xd = ADDIdtprelL %xs, @sym 1569// Into: %xd = ADDI8 %xs, sym@dtprel@l 1570case PPC::ADDIdtprelL32: {
1571// Transform: %rd = ADDIdtprelL32 %rs, @sym 1572// Into: %rd = ADDI %rs, sym@dtprel@l 1575MCSymbol *MOSymbol = getSymbol(GValue);
1579 EmitToStreamer(*OutStreamer,
1581 .addReg(
MI->getOperand(0).getReg())
1582 .
addReg(
MI->getOperand(1).getReg())
1588if (!Subtarget->hasMFOCRF()) {
1589// Transform: %r3 = MFOCRF %cr7 1590// Into: %r3 = MFCR ;; cr7 1592MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
1596 .addReg(
MI->getOperand(0).getReg()));
1602if (!Subtarget->hasMFOCRF()) {
1603// Transform: %cr7 = MTOCRF %r3 1604// Into: MTCRF mask, %r3 ;; cr7 1606MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1607unsignedMask = 0x80 >> OutContext.getRegisterInfo()
1608 ->getEncodingValue(
MI->getOperand(0).getReg());
1613 .addReg(
MI->getOperand(1).getReg()));
1621// Verify alignment is legal, so we don't create relocations 1622// that can't be supported. 1623unsigned OpNum = (
MI->getOpcode() == PPC::STD) ? 2 : 1;
1624// For non-TOC-based local-exec TLS accesses with non-zero offsets, the 1625// machine operand (which is a TargetGlobalTLSAddress) is expected to be 1626// the same operand for both loads and stores. 1630 TempMO.getOperandNo() == 1)
1639// As these load/stores share common code with the following load/stores, 1640// fall through to the subsequent cases in order to either process the 1641// non-TOC-based local-exec sequence or to process the instruction normally. 1663// A faster non-TOC-based local-[exec|dynamic] sequence is represented by 1664// `addi` or a load/store instruction (that directly loads or stores off of 1665// the thread pointer) with an immediate operand having the 1666// [MO_TPREL_FLAG|MO_TLSLD_FLAG]. Such instructions do not otherwise arise. 1667if (!HasAIXSmallLocalTLS)
1669bool IsMIADDI8 =
MI->getOpcode() == PPC::ADDI8;
1670unsigned OpNum = IsMIADDI8 ? 2 : 1;
1682// Change the opcode to load address if the original opcode is an `addi`. 1686 EmitToStreamer(*OutStreamer, TmpInst);
1689// Now process the instruction normally. 1692case PPC::PseudoEIEIO: {
1695MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1698MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1699 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::EnforceIEIO));
1705 EmitToStreamer(*OutStreamer, TmpInst);
1708// For non-TOC-based local-[exec|dynamic] variables that have a non-zero offset, 1709// we need to create a new MCExpr that adds the non-zero offset to the address 1710// of the local-[exec|dynamic] variable that will be used in either an addi, 1711// load or store. However, the final displacement for these instructions must be 1712// between [-32768, 32768), so if the TLS address + its non-zero offset is 1713// greater than 32KB, a new MCExpr is produced to accommodate this situation. 1715PPCAsmPrinter::getAdjustedFasterLocalExpr(
constMachineOperand &MO,
1717// Non-zero offsets (for loads, stores or `addi`) require additional handling. 1718// When the offset is zero, there is no need to create an adjusted MCExpr. 1722assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!");
1726"Only local-[exec|dynamic] accesses are handled!");
1729// Find the GlobalVariable that corresponds to the particular TLS variable 1730// in the TLS variable-to-address mapping. All TLS variables should exist 1731// within this map, with the exception of TLS variables marked as extern. 1732constauto TLSVarsMapEntryIter = TLSVarsToAddressMapping.
find(GValue);
1733if (TLSVarsMapEntryIter == TLSVarsToAddressMapping.
end())
1734assert(IsGlobalADeclaration &&
1735"Only expecting to find extern TLS variables not present in the TLS " 1736"variable-to-address map!");
1738unsigned TLSVarAddress =
1739 IsGlobalADeclaration ? 0 : TLSVarsMapEntryIter->second;
1741// If the address of the TLS variable + the offset is less than 32KB, 1742// or if the TLS variable is extern, we simply produce an MCExpr to add the 1743// non-zero offset to the TLS variable address. 1744// For when TLS variables are extern, this is safe to do because we can 1745// assume that the address of extern TLS variables are zero. 1753if (FinalAddress >= 32768) {
1754// Handle the written offset for cases where: 1755// TLS variable address + Offset > 32KB. 1757// The assembly that is printed will look like: 1758// TLSVar@le + Offset - Delta 1759// where Delta is a multiple of 64KB: ((FinalAddress + 32768) & ~0xFFFF). 1760ptrdiff_t Delta = ((FinalAddress + 32768) & ~0xFFFF);
1761// Check that the total instruction displacement fits within [-32768,32768). 1764 ((InstDisp < 32768) && (InstDisp >= -32768)) &&
1765"Expecting the instruction displacement for local-[exec|dynamic] TLS " 1766"variables to be between [-32768, 32768)!");
1774void PPCLinuxAsmPrinter::emitGNUAttributes(
Module &M) {
1775// Emit float ABI into GNU attribute 1776Metadata *MD =
M.getModuleFlag(
"float-abi");
1777MDString *FloatABI = dyn_cast_or_null<MDString>(MD);
1781// TODO: Support emitting soft-fp and hard double/single attributes. 1782if (flt ==
"doubledouble")
1783 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1784 Val_GNU_Power_ABI_HardFloat_DP |
1785 Val_GNU_Power_ABI_LDBL_IBM128);
1786elseif (flt ==
"ieeequad")
1787 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1788 Val_GNU_Power_ABI_HardFloat_DP |
1789 Val_GNU_Power_ABI_LDBL_IEEE128);
1790elseif (flt ==
"ieeedouble")
1791 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1792 Val_GNU_Power_ABI_HardFloat_DP |
1793 Val_GNU_Power_ABI_LDBL_64);
1798return PPCAsmPrinter::emitInstruction(
MI);
1800switch (
MI->getOpcode()) {
1803case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1805// b .end # lis 0, FuncId[16..32] 1806// nop # li 0, FuncId[0..15] 1809// bl __xray_FunctionEntry 1813// Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number 1814// of instructions change. 1815// XRAY is only supported on PPC Linux little endian. 1816if (!MAI->isLittleEndian())
1818MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1819MCSymbol *EndOfSled = OutContext.createTempSymbol();
1820 OutStreamer->emitLabel(BeginOfSled);
1821 EmitToStreamer(*OutStreamer,
1827MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1828 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1829 EmitToStreamer(*OutStreamer,
1832 OutContext.getOrCreateSymbol(
"__xray_FunctionEntry"),
1834 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1835 OutStreamer->emitLabel(EndOfSled);
1836 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_ENTER, 2);
1839case TargetOpcode::PATCHABLE_RET: {
1840unsigned RetOpcode =
MI->getOperand(0).getImm();
1850if (RetOpcode == PPC::BCCLR) {
1851 IsConditional =
true;
1852 }
elseif (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1853 RetOpcode == PPC::TCRETURNai8) {
1855 }
elseif (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1856 IsConditional =
false;
1858 EmitToStreamer(*OutStreamer, RetInst);
1871// blr # lis 0, FuncId[16..32] 1872// nop # li 0, FuncId[0..15] 1875// bl __xray_FunctionExit 1880// Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number 1881// of instructions change. 1882 FallthroughLabel = OutContext.createTempSymbol();
1888 .
addReg(
MI->getOperand(2).getReg())
1895// b(lr)? # lis 0, FuncId[16..32] 1896// nop # li 0, FuncId[0..15] 1899// bl __xray_FunctionExit 1903// Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number 1904// of instructions change. 1905 OutStreamer->emitCodeAlignment(
Align(8), &getSubtargetInfo());
1906MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1907 OutStreamer->emitLabel(BeginOfSled);
1908 EmitToStreamer(*OutStreamer, RetInst);
1912MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1913 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1914 EmitToStreamer(*OutStreamer,
1917 OutContext.getOrCreateSymbol(
"__xray_FunctionExit"),
1919 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1920 EmitToStreamer(*OutStreamer, RetInst);
1922 OutStreamer->emitLabel(FallthroughLabel);
1923 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_EXIT, 2);
1926case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1928case TargetOpcode::PATCHABLE_TAIL_CALL:
1929// TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a 1930// normal function exit from a tail exit. 1932"around this assert.");
1934return PPCAsmPrinter::emitInstruction(
MI);
1937void PPCLinuxAsmPrinter::emitStartOfAsmFile(
Module &M) {
1945 !isPositionIndependent())
1951 OutStreamer->switchSection(OutContext.getELFSection(
1954MCSymbol *TOCSym = OutContext.getOrCreateSymbol(
Twine(
".LTOC"));
1955MCSymbol *CurrentPos = OutContext.createTempSymbol();
1957 OutStreamer->emitLabel(CurrentPos);
1959// The GOT pointer points to the middle of the GOT, in order to reference the 1960// entire 64kB range. 0x8000 is the midpoint. 1966 OutStreamer->emitAssignment(TOCSym, tocExpr);
1968 OutStreamer->switchSection(getObjFileLowering().getTextSection());
1971void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
1972// linux/ppc32 - Normal entry label. 1974 (!isPositionIndependent() ||
1980if (PPCFI->
usesPICBase() && !Subtarget->isSecurePlt()) {
1982MCSymbol *PICBase = MF->getPICBaseSymbol();
1983 OutStreamer->emitLabel(RelocSymbol);
1991 OutStreamer->emitValue(OffsExpr, 4);
1992 OutStreamer->emitLabel(CurrentFnSym);
1998// ELFv2 ABI - Normal entry label. 2000// In the Large code model, we allow arbitrary displacements between 2001// the text section and its associated TOC section. We place the 2002// full 8-byte offset to the TOC in memory immediately preceding 2003// the function global entry point. 2005 && !MF->getRegInfo().use_empty(PPC::X2)) {
2010constMCExpr *TOCDeltaExpr =
2017 OutStreamer->emitValue(TOCDeltaExpr, 8);
2022// Emit an official procedure descriptor. 2026 OutStreamer->switchSection(Section);
2027 OutStreamer->emitLabel(CurrentFnSym);
2028 OutStreamer->emitValueToAlignment(
Align(8));
2029MCSymbol *Symbol1 = CurrentFnSymForSize;
2030// Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function 2035// Generates a R_PPC64_TOC relocation for TOC base insertion. 2036 OutStreamer->emitValue(
2039// Emit a null environment pointer. 2040 OutStreamer->emitIntValue(0, 8
/* size */);
2041 OutStreamer->switchSection(Current.first, Current.second);
2044void PPCLinuxAsmPrinter::emitEndOfAsmFile(
Module &M) {
2047bool isPPC64 =
DL.getPointerSizeInBits() == 64;
2052// If we are using any values provided by Glibc at fixed addresses, 2053// we need to ensure that the Glibc used at link time actually provides 2054// those values. All versions of Glibc that do will define the symbol 2055// named "__parse_hwcap_and_convert_at_platform". 2057 OutStreamer->emitSymbolValue(
2058 GetExternalSymbolSymbol(
"__parse_hwcap_and_convert_at_platform"),
2059 MAI->getCodePointerSize());
2060 emitGNUAttributes(M);
2063constchar *
Name = isPPC64 ?
".toc" :
".got2";
2066 OutStreamer->switchSection(Section);
2068 OutStreamer->emitValueToAlignment(
Align(4));
2070for (
constauto &TOCMapPair : TOC) {
2071constMCSymbol *
const TOCEntryTarget = TOCMapPair.first.first;
2072MCSymbol *
const TOCEntryLabel = TOCMapPair.second;
2074 OutStreamer->emitLabel(TOCEntryLabel);
2076 TS->
emitTCEntry(*TOCEntryTarget, TOCMapPair.first.second);
2078 OutStreamer->emitSymbolValue(TOCEntryTarget, 4);
2082 PPCAsmPrinter::emitEndOfAsmFile(M);
2085/// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2. 2086void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
2087// In the ELFv2 ABI, in functions that use the TOC register, we need to 2088// provide two entry points. The ABI guarantees that when calling the 2089// local entry point, r2 is set up by the caller to contain the TOC base 2090// for this function, and when calling the global entry point, r12 is set 2091// up by the caller to hold the address of the global entry point. We 2092// thus emit a prefix sequence along the following lines: 2096// # global entry point 2097// addis r2,r12,(.TOC.-.Lfunc_gepNN)@ha 2098// addi r2,r2,(.TOC.-.Lfunc_gepNN)@l 2100// .localentry func, .Lfunc_lepNN-.Lfunc_gepNN 2101// # local entry point, followed by function body 2103// For the Large code model, we create 2106// .quad .TOC.-.Lfunc_gepNN # done by EmitFunctionEntryLabel 2109// # global entry point 2110// ld r2,.Lfunc_tocNN-.Lfunc_gepNN(r12) 2113// .localentry func, .Lfunc_lepNN-.Lfunc_gepNN 2114// # local entry point, followed by function body 2116// This ensures we have r2 set up correctly while executing the function 2117// body, no matter which entry point is called. 2119constbool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) ||
2120 !MF->getRegInfo().use_empty(PPC::R2);
2126// Only do all that if the function uses R2 as the TOC pointer 2127// in the first place. We don't need the global entry point if the 2128// function uses R2 as an allocatable register. 2129if (NonPCrelGEPRequired || PCrelGEPRequired) {
2130// Note: The logic here must be synchronized with the code in the 2131// branch-selection pass which sets the offset of the first block in the 2132// function. This matters because it affects the alignment. 2134 OutStreamer->emitLabel(GlobalEntryLabel);
2140constMCExpr *TOCDeltaExpr =
2142 GlobalEntryLabelExp, OutContext);
2148 .addExpr(TOCDeltaHi));
2154 .addExpr(TOCDeltaLo));
2157constMCExpr *TOCOffsetDeltaExpr =
2159 GlobalEntryLabelExp, OutContext);
2163 .addExpr(TOCOffsetDeltaExpr)
2172 OutStreamer->emitLabel(LocalEntryLabel);
2175constMCExpr *LocalOffsetExp =
2177 GlobalEntryLabelExp, OutContext);
2181 TS->
emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), LocalOffsetExp);
2183// When generating the entry point for a function we have a few scenarios 2184// based on whether or not that function uses R2 and whether or not that 2185// function makes calls (or is a leaf function). 2186// 1) A leaf function that does not use R2 (or treats it as callee-saved 2187// and preserves it). In this case st_other=0 and both 2188// the local and global entry points for the function are the same. 2189// No special entry point code is required. 2190// 2) A function uses the TOC pointer R2. This function may or may not have 2191// calls. In this case st_other=[2,6] and the global and local entry 2192// points are different. Code to correctly setup the TOC pointer in R2 2193// is put between the global and local entry points. This case is 2194// covered by the if statatement above. 2195// 3) A function does not use the TOC pointer R2 but does have calls. 2196// In this case st_other=1 since we do not know whether or not any 2197// of the callees clobber R2. This case is dealt with in this else if 2198// block. Tail calls are considered calls and the st_other should also 2199// be set to 1 in that case as well. 2200// 4) The function does not use the TOC pointer but R2 is used inside 2201// the function. In this case st_other=1 once again. 2202// 5) This function uses inline asm. We mark R2 as reserved if the function 2203// has inline asm as we have to assume that it may be used. 2204if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() ||
2205 MF->hasInlineAsm() || (!PPCFI->
usesTOCBasePtr() && UsesX2OrR2)) {
2214/// EmitFunctionBodyEnd - Print the traceback table before the .size 2217void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
2218// Only the 64-bit target requires a traceback table. For now, 2219// we only emit the word of zeroes that GDB requires to find 2220// the end of the function, and zeroes for the eight-byte 2222// FIXME: We should fill in the eight-byte mandatory fields as described in 2223// the PPC64 ELF ABI (this is a low-priority item because GDB does not 2224// currently make use of these fields). 2226 OutStreamer->emitIntValue(0, 4
/*size*/);
2227 OutStreamer->emitIntValue(0, 8
/*size*/);
2231void PPCAIXAsmPrinter::emitLinkage(
constGlobalValue *GV,
2252"InternalLinkage should not have other visibility setting.");
2264if (!
TM.getIgnoreXCOFFVisibility()) {
2267"Cannot not be both dllexport and non-default visibility");
2270// TODO: "internal" Visibility needs to go here. 2273 VisibilityAttr = MAI->getExportedVisibilityAttr();
2276 VisibilityAttr = MAI->getHiddenVisibilityAttr();
2279 VisibilityAttr = MAI->getProtectedVisibilityAttr();
2284// Do not emit the _$TLSML symbol. 2289 OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,
2294// Setup CurrentFnDescSym and its containing csect. 2296 cast<MCSectionXCOFF>(getObjFileLowering().getSectionForFunctionDescriptor(
2305uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
2306// Calculate the number of VRs be saved. 2307// Vector registers 20 through 31 are marked as reserved and cannot be used 2308// in the default ABI. 2310if (Subtarget.
isAIXABI() && Subtarget.hasAltivec() &&
2311TM.getAIXExtendedAltivecABI()) {
2313for (
unsigned Reg = PPC::V20;
Reg <= PPC::V31; ++
Reg)
2314if (
MRI.isPhysRegModified(Reg))
2315// Number of VRs saved. 2316return PPC::V31 - Reg + 1;
2321void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
2323if (!
TM.getXCOFFTracebackTable())
2326 emitTracebackTable();
2328// If ShouldEmitEHBlock returns true, then the eh info table 2329// will be emitted via `AIXException::endFunction`. Otherwise, we 2330// need to emit a dumy eh info table when VRs are saved. We could not 2331// consolidate these two places into one because there is no easy way 2332// to access register information in `AIXException` class. 2334 (getNumberOfVRSaved() > 0)) {
2335// Emit dummy EH Info Table. 2336 OutStreamer->switchSection(getObjFileLowering().getCompactUnwindSection());
2339 OutStreamer->emitLabel(EHInfoLabel);
2342 OutStreamer->emitInt32(0);
2344constDataLayout &
DL = MMI->getModule()->getDataLayout();
2346// Add necessary paddings in 64 bit mode. 2347 OutStreamer->emitValueToAlignment(
Align(PointerSize));
2349 OutStreamer->emitIntValue(0, PointerSize);
2350 OutStreamer->emitIntValue(0, PointerSize);
2351 OutStreamer->switchSection(MF->
getSection());
2355void PPCAIXAsmPrinter::emitTracebackTable() {
2357// Create a symbol for the end of function. 2359 OutStreamer->emitLabel(FuncEnd);
2361 OutStreamer->AddComment(
"Traceback table begin");
2362// Begin with a fullword of zero. 2363 OutStreamer->emitIntValueInHexWithPadding(0, 4
/*size*/);
2368auto EmitComment = [&]() {
2369 OutStreamer->AddComment(CommentOS.str());
2370 CommentString.
clear();
2375 OutStreamer->emitIntValueInHexWithPadding(
Value,
Size);
2379 CommentOS <<
"Version = " <<
Version;
2380 EmitCommentAndValue(Version, 1);
2382// There is a lack of information in the IR to assist with determining the 2383// source language. AIX exception handling mechanism would only search for 2384// personality routine and LSDA area when such language supports exception 2385// handling. So to be conservatively correct and allow runtime to do its job, 2386// we need to set it to C++ for now. 2390 CommentOS <<
"Language = " 2392 EmitCommentAndValue(LanguageIdentifier, 1);
2394// This is only populated for the third and fourth bytes. 2395uint32_t FirstHalfOfMandatoryField = 0;
2397// Emit the 3rd byte of the mandatory field. 2399// We always set traceback offset bit to true. 2405// Check the function uses floating-point processor instructions or not 2406for (
unsigned Reg = PPC::F0;
Reg <= PPC::F31; ++
Reg) {
2407if (
MRI.isPhysRegUsed(Reg,
/* SkipRegMaskTest */true)) {
2413#define GENBOOLCOMMENT(Prefix, V, Field) \ 2414 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
2417#define GENVALUECOMMENT(PrefixAndName, V, Field) \ 2418 CommentOS << (PrefixAndName) << " = " \
2419 << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
2420 (TracebackTable::Field##Shift))
2423GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);
2426GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasTraceBackTableOffset);
2427GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsInternalProcedure);
2430GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasControlledStorage);
2434GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsFloatingPointPresent);
2437 IsFloatingPointOperationLogOrAbortEnabled);
2440 OutStreamer->emitIntValueInHexWithPadding(
2441 (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2443// Set the 4th byte of the mandatory field. 2449if (FrameReg == (Subtarget->
isPPC64() ? PPC::X31 : PPC::R31))
2453if (!MustSaveCRs.
empty())
2459GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsInterruptHandler);
2460GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);
2464 OnConditionDirective);
2468 OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),
2471// Set the 5th byte of mandatory field. 2472uint32_t SecondHalfOfMandatoryField = 0;
2479for (
unsigned Reg = PPC::F14;
Reg <= PPC::F31; ++
Reg) {
2480if (
MRI.isPhysRegModified(Reg)) {
2481 FPRSaved = PPC::F31 -
Reg + 1;
2487GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, IsBackChainStored);
2489GENVALUECOMMENT(
", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
2491 OutStreamer->emitIntValueInHexWithPadding(
2492 (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
2494// Set the 6th byte of mandatory field. 2496// Check whether has Vector Instruction,We only treat instructions uses vector 2497// register as vector instructions. 2498bool HasVectorInst =
false;
2499for (
unsigned Reg = PPC::V0;
Reg <= PPC::V31; ++
Reg)
2500if (
MRI.isPhysRegUsed(Reg,
/* SkipRegMaskTest */true)) {
2501// Has VMX instruction. 2502 HasVectorInst =
true;
2509uint16_t NumOfVRSaved = getNumberOfVRSaved();
2510bool ShouldEmitEHBlock =
2513if (ShouldEmitEHBlock)
2518// X13 is reserved under 64-bit environment. 2519unsigned GPRBegin = Subtarget->
isPPC64() ? PPC::X14 : PPC::R13;
2520unsigned GPREnd = Subtarget->
isPPC64() ? PPC::X31 : PPC::R31;
2522for (
unsigned Reg = GPRBegin;
Reg <= GPREnd; ++
Reg) {
2523if (
MRI.isPhysRegModified(Reg)) {
2524 GPRSaved = GPREnd -
Reg + 1;
2532GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, HasExtensionTable);
2534GENVALUECOMMENT(
", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
2536 OutStreamer->emitIntValueInHexWithPadding(
2537 (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
2539// Set the 7th byte of mandatory field. 2541 SecondHalfOfMandatoryField |=
2545 NumberOfFixedParms);
2547 OutStreamer->emitIntValueInHexWithPadding(
2548 (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2550// Set the 8th byte of mandatory field. 2552// Always set parameter on stack. 2556 SecondHalfOfMandatoryField |=
2561 NumberOfFloatingPointParms);
2562GENBOOLCOMMENT(
", ", SecondHalfOfMandatoryField, HasParmsOnStack);
2564 OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
2567// Generate the optional fields of traceback table. 2570if (NumberOfFixedParms || NumberOfFPParms) {
2576 ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
2583 CommentOS <<
"Parameter type = " << ParmsType.
get();
2586 OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
2587sizeof(ParmsTypeValue));
2589// Traceback table offset. 2590 OutStreamer->AddComment(
"Function size");
2592MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
2594 OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
2597// Since we unset the Int_Handler. 2606 int16_t NameLength =
Name.size();
2607 CommentOS <<
"Function name len = " 2608 <<
static_cast<unsignedint>(NameLength);
2609 EmitCommentAndValue(NameLength, 2);
2610 OutStreamer->AddComment(
"Function Name");
2611 OutStreamer->emitBytes(
Name);
2616 OutStreamer->AddComment(
"AllocaUsed");
2617 OutStreamer->emitIntValueInHex(AllocReg,
sizeof(AllocReg));
2623// Number of VRs saved. 2626// This bit is supposed to set only when the special register 2627// VRSAVE is saved on stack. 2628// However, IBM XL compiler sets the bit when any vector registers 2629// are saved on the stack. We will follow XL's behavior on AIX 2630// so that we don't get surprise behavior change for C code. 2638// Vector parameters number. 2650 OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
2655 OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
2663 CommentOS <<
"Vector Parameter type = " << VecParmsType.
get();
2666 OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
2667sizeof(VecParmTypeValue));
2669 CommentOS <<
"Padding";
2670 EmitCommentAndValue(0, 2);
2673uint8_t ExtensionTableFlag = 0;
2675if (ShouldEmitEHBlock)
2676 ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
2679 ExtensionTableFlag |= ExtendedTBTableFlag::TB_SSP_CANARY;
2681 CommentOS <<
"ExtensionTableFlag = " 2683 EmitCommentAndValue(ExtensionTableFlag,
sizeof(ExtensionTableFlag));
2686if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
2687auto &Ctx = OutStreamer->getContext();
2690MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym, TOCType_EHBlock);
2692 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2693 ->getQualNameSymbol();
2699 OutStreamer->emitValueToAlignment(
Align(4));
2700 OutStreamer->AddComment(
"EHInfo Table");
2701 OutStreamer->emitValue(Exp,
DL.getPointerSize());
2703#undef GENBOOLCOMMENT 2704#undef GENVALUECOMMENT 2710// TODO: Linker could still eliminate the GV if we just skip 2711// handling llvm.used array. Skipping them for now until we or the 2712// AIX OS team come up with a good solution. 2713 .
Case(
"llvm.used",
true)
2714// It's correct to just skip llvm.compiler.used array here. 2715 .
Case(
"llvm.compiler.used",
true)
2721 .
Cases(
"llvm.global_ctors",
"llvm.global_dtors",
true)
2726if (
auto *GA = dyn_cast<GlobalAlias>(
C))
2727return getAliasOffset(GA->getAliasee());
2728if (
auto *CE = dyn_cast<ConstantExpr>(
C)) {
2735auto *
RHS = dyn_cast<MCConstantExpr>(CBE->
getRHS());
2738returnRHS->getValue();
2744// TODO: These asserts should be updated as more support for the toc data 2745// transformation is added (struct support, etc.). 2748"GlobalVariables with an alignment requirement stricter than TOC entry " 2749"size not supported by the toc data transformation.");
2752assert(GVType->
isSized() &&
"A GlobalVariable's size must be known to be " 2753"supported by the toc data transformation.");
2757"A GlobalVariable with size larger than a TOC entry is not currently " 2758"supported by the toc data transformation.");
2761"currently supported by the toc data transformation.");
2764void PPCAIXAsmPrinter::emitGlobalVariable(
constGlobalVariable *GV) {
2765// Special LLVM global arrays have been handled at the initialization. 2769// If the Global Variable has the toc-data attribute, it needs to be emitted 2770// when we emit the .toc section. 2774 TOCDataGlobalVars.push_back(GV);
2778 emitGlobalVariableHelper(GV);
2781void PPCAIXAsmPrinter::emitGlobalVariableHelper(
constGlobalVariable *GV) {
2783"Unhandled intrinsic global variable.");
2791 emitLinkage(GV, GVSym);
2795SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
2797 !GVKind.
isThreadLocal())
// Checks for both ThreadData and ThreadBSS. 2799"not supported yet.");
2801// Print GV in verbose mode 2806 OutStreamer->getCommentOS() <<
'\n';
2811 getObjFileLowering().SectionForGlobal(GV, GVKind, TM));
2813// Switch to the containing csect. 2814 OutStreamer->switchSection(Csect);
2818// Handle common and zero-initialized local symbols. 2827 OutStreamer->emitZeros(
Size);
2830"BSS local toc-data already handled and TLS variables " 2831"incompatible with XMC_TD");
2832 OutStreamer->emitXCOFFLocalCommonSymbol(
2836 OutStreamer->emitCommonSymbol(GVSym,
Size, Alignment);
2843// Emit linkage for the global variable and its aliases. 2844 emitLinkage(GV, EmittedInitSym);
2846 emitLinkage(GA, getSymbol(GA));
2848 emitAlignment(getGVAlignment(GV,
DL), GV);
2850// When -fdata-sections is enabled, every GlobalVariable will 2851// be put into its own csect; therefore, label is not necessary here. 2852if (!
TM.getDataSections() || GV->hasSection()) {
2854 OutStreamer->emitLabel(EmittedInitSym);
2858if (!GOAliasMap[GV].
size()) {
2859 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer());
2863// Aliases with the same offset should be aligned. Record the list of aliases 2864// associated with the offset. 2865 AliasMapTy AliasList;
2867 AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);
2869// Emit alias label and element value for global variable. 2870 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer(),
2874void PPCAIXAsmPrinter::emitFunctionDescriptor() {
2876constunsignedPointerSize =
DL.getPointerSizeInBits() == 64 ? 8 : 4;
2879// Emit function descriptor. 2880 OutStreamer->switchSection(
2881 cast<MCSymbolXCOFF>(CurrentFnDescSym)->getRepresentedCsect());
2883// Emit aliasing label for function descriptor csect. 2885 OutStreamer->emitLabel(getSymbol(Alias));
2887// Emit function entry point address. 2890// Emit TOC base address. 2892 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2893 ->getQualNameSymbol();
2896// Emit a null environment pointer. 2897 OutStreamer->emitIntValue(0, PointerSize);
2899 OutStreamer->switchSection(Current.first, Current.second);
2902void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2903// For functions without user defined section, it's not necessary to emit the 2904// label when we have individual function in its own csect. 2906 PPCAsmPrinter::emitFunctionEntryLabel();
2908// Emit aliasing label for function entry point label. 2910 OutStreamer->emitLabel(
2911 getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM));
2914void PPCAIXAsmPrinter::emitPGORefs(
Module &M) {
2915if (!OutContext.hasXCOFFSection(
2920// When inside a csect `foo`, a .ref directive referring to a csect `bar` 2921// translates into a relocation entry from `foo` to` bar`. The referring 2922// csect, `foo`, is identified by its address. If multiple csects have the 2923// same address (because one or more of them are zero-length), the referring 2924// csect cannot be determined. Hence, we don't generate the .ref directives 2925// if `__llvm_prf_cnts` is an empty section. 2926bool HasNonZeroLengthPrfCntsSection =
false;
2929if (GV.hasSection() && GV.getSection() ==
"__llvm_prf_cnts" &&
2930DL.getTypeAllocSize(GV.getValueType()) > 0) {
2931 HasNonZeroLengthPrfCntsSection =
true;
2935if (HasNonZeroLengthPrfCntsSection) {
2936MCSection *CntsSection = OutContext.getXCOFFSection(
2939/*MultiSymbolsAllowed*/true);
2941 OutStreamer->switchSection(CntsSection);
2942if (OutContext.hasXCOFFSection(
2945MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_data[RW]");
2946 OutStreamer->emitXCOFFRefDirective(S);
2948if (OutContext.hasXCOFFSection(
2951MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_names[RO]");
2952 OutStreamer->emitXCOFFRefDirective(S);
2954if (OutContext.hasXCOFFSection(
2957MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_vnds[RW]");
2958 OutStreamer->emitXCOFFRefDirective(S);
2963void PPCAIXAsmPrinter::emitGCOVRefs() {
2964if (!OutContext.hasXCOFFSection(
2965"__llvm_gcov_ctr_section",
2969MCSection *CtrSection = OutContext.getXCOFFSection(
2972/*MultiSymbolsAllowed*/true);
2974 OutStreamer->switchSection(CtrSection);
2977if (OutContext.hasXCOFFSection(
2980constchar *SymbolStr =
TM.Options.XCOFFReadOnlyPointers
2981 ?
"__llvm_covinit[RO]" 2982 :
"__llvm_covinit[RW]";
2983MCSymbol *S = OutContext.getOrCreateSymbol(SymbolStr);
2984 OutStreamer->emitXCOFFRefDirective(S);
2988void PPCAIXAsmPrinter::emitEndOfAsmFile(
Module &M) {
2989// If there are no functions and there are no toc-data definitions in this 2990// module, we will never need to reference the TOC base. 2991if (
M.empty() && TOCDataGlobalVars.empty())
2997// Switch to section to emit TOC base. 2998 OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());
3003for (
auto &
I : TOC) {
3005// Setup the csect for the current TC entry. If the variant kind is 3006// VK_PPC_AIX_TLSGDM the entry represents the region handle, we create a 3007// new symbol to prefix the name with a dot. 3008// If TLS model opt is turned on, create a new symbol to prefix the name 3010if (
I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM ||
3011 (Subtarget->hasAIXShLibTLSModelOpt() &&
3012I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD)) {
3016Name += cast<MCSymbolXCOFF>(
I.first.first)->getSymbolTableName();
3018 TCEntry = cast<MCSectionXCOFF>(
3019 getObjFileLowering().getSectionForTOCEntry(S, TM));
3021 TCEntry = cast<MCSectionXCOFF>(
3022 getObjFileLowering().getSectionForTOCEntry(
I.first.first, TM));
3024 OutStreamer->switchSection(TCEntry);
3026 OutStreamer->emitLabel(
I.second);
3030// Traverse the list of global variables twice, emitting all of the 3031// non-common global variables before the common ones, as emitting a 3032// .comm directive changes the scope from .toc to the common symbol. 3033for (
constauto *GV : TOCDataGlobalVars) {
3034if (!GV->hasCommonLinkage())
3035 emitGlobalVariableHelper(GV);
3037for (
constauto *GV : TOCDataGlobalVars) {
3038if (GV->hasCommonLinkage())
3039 emitGlobalVariableHelper(GV);
3043bool PPCAIXAsmPrinter::doInitialization(
Module &M) {
3044constboolResult = PPCAsmPrinter::doInitialization(M);
3046// Emit the .machine directive on AIX. 3049// Walk through the "target-cpu" attribute of functions and use the newest 3050// level as the CPU of the module. 3054if (FunCpuId > TargetCpuId)
3055 TargetCpuId = FunCpuId;
3057// If there is no "target-cpu" attribute within the functions, take the 3058// "-mcpu" value. If both are omitted, use getNormalizedPPCTargetCPU() to 3059// determine the default CPU. 3070auto setCsectAlignment = [
this](
constGlobalObject *GO) {
3071// Declarations have 0 alignment which is set by default. 3072if (GO->isDeclarationForLinker())
3075SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);
3077 getObjFileLowering().SectionForGlobal(GO, GOKind, TM));
3079Align GOAlign = getGVAlignment(GO, GO->getDataLayout());
3083// For all TLS variables, calculate their corresponding addresses and store 3084// them into TLSVarsToAddressMapping, which will be used to determine whether 3085// or not local-exec TLS variables require special assembly printing. 3087autoDL =
M.getDataLayout();
3088for (
constauto &
G :
M.globals()) {
3089if (
G.isThreadLocal() && !
G.isDeclaration()) {
3090 TLSVarAddress =
alignTo(TLSVarAddress, getGVAlignment(&
G,
DL));
3091 TLSVarsToAddressMapping[&
G] = TLSVarAddress;
3092 TLSVarAddress +=
DL.getTypeAllocSize(
G.getValueType());
3096// We need to know, up front, the alignment of csects for the assembly path, 3097// because once a .csect directive gets emitted, we could not change the 3098// alignment value on it. 3099for (
constauto &
G :
M.globals()) {
3104// Generate a format indicator and a unique module id to be a part of 3105// the sinit and sterm function names. 3106if (FormatIndicatorAndUniqueModId.empty()) {
3108if (UniqueModuleId !=
"")
3109// TODO: Use source file full path to generate the unique module id 3110// and add a format indicator as a part of function name in case we 3111// will support more than one format. 3112 FormatIndicatorAndUniqueModId =
"clang_" + UniqueModuleId.substr(1);
3114// Use threadId, Pid, and current time as the unique module id when we 3115// cannot generate one based on a module's strong external symbols. 3117 std::chrono::duration_cast<std::chrono::nanoseconds>(
3118 std::chrono::steady_clock::now().time_since_epoch())
3120 FormatIndicatorAndUniqueModId =
3123 llvm::itostr(CurTime);
3127 emitSpecialLLVMGlobal(&
G);
3131 setCsectAlignment(&
G);
3132 std::optional<CodeModel::Model> OptionalCodeModel =
G.getCodeModel();
3133if (OptionalCodeModel)
3135 *OptionalCodeModel);
3138for (
constauto &
F : M)
3139 setCsectAlignment(&
F);
3141// Construct an aliasing list for each GlobalObject. 3142for (
constauto &Alias :
M.aliases()) {
3146"alias without a base object is not yet supported on AIX");
3150"\n\tAlias attribute for " +
3151 Alias.getGlobalIdentifier() +
3152" is invalid because " + Aliasee->
getName() +
3158 dyn_cast_or_null<GlobalVariable>(Alias.getAliaseeObject());
3160 std::optional<CodeModel::Model> OptionalCodeModel = GVar->
getCodeModel();
3161if (OptionalCodeModel)
3163 *OptionalCodeModel);
3166 GOAliasMap[Aliasee].push_back(&Alias);
3173switch (
MI->getOpcode()) {
3180if (
MI->getNumOperands() < 5)
3186MCSymbol *TempSym = OutContext.createNamedTempSymbol();
3187 OutStreamer->emitLabel(TempSym);
3188 OutStreamer->emitXCOFFExceptDirective(
3189 CurrentFnSym, TempSym, LangMO.
getImm(), ReasonMO.
getImm(),
3190 Subtarget->
isPPC64() ?
MI->getMF()->getInstructionCount() * 8
3191 :
MI->getMF()->getInstructionCount() * 4,
3195case PPC::GETtlsMOD32AIX:
3196case PPC::GETtlsMOD64AIX:
3197case PPC::GETtlsTpointer32AIX:
3198case PPC::GETtlsADDR64AIX:
3199case PPC::GETtlsADDR32AIX: {
3200// A reference to .__tls_get_mod/.__tls_get_addr/.__get_tpointer is unknown 3201// to the assembler so we need to emit an external symbol reference. 3204 ExtSymSDNodeSymbols.insert(TlsGetAddr);
3214 cast<MCSymbolXCOFF>(OutContext.getOrCreateSymbol(MO.
getSymbolName()));
3215 ExtSymSDNodeSymbols.insert(S);
3221case PPC::BL8_NOP_TLS:
3229if (
MI->getOperand(0).isSymbol())
3242MCInstBuilder(PPC::ORI).addReg(PPC::R0).addReg(PPC::R0).addImm(0));
3245return PPCAsmPrinter::emitInstruction(
MI);
3248bool PPCAIXAsmPrinter::doFinalization(
Module &M) {
3249// Do streamer related finalization for DWARF. 3251// Emit section end. This is used to tell the debug line section where the 3252// end is for a text section if we don't use .loc to represent the debug 3254auto *Sec = OutContext.getObjectFileInfo()->getTextSection();
3255 OutStreamer->switchSectionNoPrint(Sec);
3257 OutStreamer->emitLabel(
Sym);
3262return PPCAsmPrinter::doFinalization(M);
3266if (P < 0 || P > 65535)
3273return 20 + (
P - 20) * 16;
3276return 1004 + (
P - 81);
3279return 2047 + (
P - 1124) * 33878;
3281return 2147482625u + (
P - 64512);
3285// This helper function converts clang init priority to values used in sinit 3286// and sterm functions. 3288// The conversion strategies are: 3289// We map the reserved clang/gnu priority range [0, 100] into the sinit/sterm 3290// reserved priority range [0, 1023] by 3291// - directly mapping the first 21 and the last 20 elements of the ranges 3292// - linear interpolating the intermediate values with a step size of 16. 3294// We map the non reserved clang/gnu priority range of [101, 65535] into the 3295// sinit/sterm priority range [1024, 2147483648] by: 3296// - directly mapping the first and the last 1024 elements of the ranges 3297// - linear interpolating the intermediate values with a step size of 33878. 3300 std::string PrioritySuffix;
3303return PrioritySuffix;
3306void PPCAIXAsmPrinter::emitXXStructorList(
constDataLayout &
DL,
3309 preprocessXXStructorList(
DL, List, Structors);
3310if (Structors.
empty())
3314for (Structor &S : Structors) {
3315if (
constConstantExpr *CE = dyn_cast<ConstantExpr>(S.Func))
3316 S.Func =
CE->getOperand(0);
3324 cast<Function>(S.Func));
3328void PPCAIXAsmPrinter::emitTTypeReference(
constGlobalValue *GV,
3331 TOCEntryType GlobalType = TOCType_GlobalInternal;
3336 GlobalType = TOCType_GlobalExternal;
3338MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym, GlobalType);
3340 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
3341 ->getQualNameSymbol();
3342auto &Ctx = OutStreamer->getContext();
3346 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
3348 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
3351// Return a pass that prints the PPC assembly code for a MachineFunction to the 3352// given output stream. 3355 std::unique_ptr<MCStreamer> &&Streamer) {
3357returnnew PPCAIXAsmPrinter(tm, std::move(Streamer));
3359returnnew PPCLinuxAsmPrinter(tm, std::move(Streamer));
3362void PPCAIXAsmPrinter::emitModuleCommandLines(
Module &M) {
3363constNamedMDNode *NMD =
M.getNamedMetadata(
"llvm.commandline");
3371assert(
N->getNumOperands() == 1 &&
3372"llvm.commandline metadata entry can have only one operand");
3373constMDString *MDS = cast<MDString>(
N->getOperand(0));
3374// Add "@(#)" to support retrieving the command line information with the 3375// AIX "what" command 3376 RSOS <<
"@(#)opt " << MDS->
getString() <<
"\n";
3379 OutStreamer->emitXCOFFCInfoSym(
".GCC.command.line", RSOS.str());
3382// Force static initialization. unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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
static bool hasDebugInfo(const MachineFunction *MF)
Module.h This file contains the declarations for the Module class.
static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)
This file implements a map that provides insertion order iteration.
static void collectTOCStats(PPCAsmPrinter::TOCEntryType Type)
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 void setOptionalCodeModel(MCSymbolXCOFF *XSym, CodeModel::Model CM)
static AsmPrinter * createPPCAsmPrinterPass(TargetMachine &tm, std::unique_ptr< MCStreamer > &&Streamer)
static PPCAsmPrinter::TOCEntryType getTOCEntryTypeForMO(const MachineOperand &MO)
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
static std::string convertToSinitPriority(int Priority)
static MCSymbol * createMCSymbolForTlsGetAddr(MCContext &Ctx, unsigned MIOpc)
This helper function creates the TlsGetAddr/TlsGetMod MCSymbol for AIX.
#define GENVALUECOMMENT(PrefixAndName, V, Field)
static unsigned mapToSinitPriority(int P)
static void tocDataChecks(unsigned PointerSize, const GlobalVariable *GV)
static cl::opt< bool > EnableSSPCanaryBitInTB("aix-ssp-tb-bit", cl::init(false), cl::desc("Enable Passing SSP Canary info in Trackback on AIX"), cl::Hidden)
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
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 contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
This file implements a set that has insertion order iteration characteristics.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file contains some functions that are useful when dealing with strings.
This class is intended to be used as a driving class for all asm writers.
virtual void emitInstruction(const MachineInstr *)
Targets should implement this to emit instructions.
MCSymbol * getSymbol(const GlobalValue *GV) const
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...
MCSymbol * GetJTISymbol(unsigned JTID, bool isLinkerPrivate=false) const
Return the symbol for the specified jump table entry.
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
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.
This is an important base class in LLVM.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
unsigned getPointerSize(unsigned AS=0) const
Layout pointer size in bytes, rounded up to a whole number of bytes.
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
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...
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
bool hasSection() const
Check if this global has a custom object file section.
VisibilityTypes getVisibility() const
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
LinkageTypes getLinkage() const
bool hasDefaultVisibility() const
bool hasPrivateLinkage() const
ThreadLocalMode getThreadLocalMode() const
bool hasDLLExportStorageClass() const
bool isDeclarationForLinker() const
Module * getParent()
Get the module that this global value is contained inside of...
const GlobalObject * getAliaseeObject() const
@ DefaultVisibility
The GV is visible.
@ HiddenVisibility
The GV is hidden.
@ ProtectedVisibility
The GV is protected.
const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
bool hasCommonLinkage() const
bool hasAppendingLinkage() const
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ CommonLinkage
Tentative definitions.
@ InternalLinkage
Rename collisions when linking (static functions).
@ LinkOnceAnyLinkage
Keep one copy of function when linking (inline)
@ WeakODRLinkage
Same, but only replaced by something equivalent.
@ ExternalLinkage
Externally visible function.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
@ AppendingLinkage
Special purpose, only applies to global arrays.
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ ExternalWeakLinkage
ExternalWeak linkage description.
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Type * getValueType() const
bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists.
bool hasInitializer() const
Definitions have initializers, declarations don't.
std::optional< CodeModel::Model > getCodeModel() const
Get the custom code model of this global if it has one.
Binary assembler expressions.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Opcode getOpcode() const
Get the kind of this binary expression.
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
MCSectionXCOFF * getXCOFFSection(StringRef Section, SectionKind K, std::optional< XCOFF::CsectProperties > CsectProp=std::nullopt, bool MultiSymbolsAllowed=false, std::optional< XCOFF::DwarfSectionSubtypeFlags > DwarfSubtypeFlags=std::nullopt)
Base class for the full range of assembler expressions which are needed for parsing.
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
MCRegister getReg() const
Returns the register number.
This represents a section on linux, lots of unix variants and some bare metal systems.
XCOFF::StorageMappingClass getMappingClass() const
MCSymbolXCOFF * getQualNameSymbol() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
void setAlignment(Align Value)
void ensureMinAlignment(Align MinAlignment)
Makes sure that Alignment is at least MinAlignment.
Represent a reference to a symbol from inside an expression.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
StringRef getSymbolTableName() const
void setPerSymbolCodeModel(MCSymbolXCOFF::CodeModel Model)
void setStorageClass(XCOFF::StorageClass SC)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
StringRef getString() const
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
MCSection * getSection() const
Returns the Section this function belongs to.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() 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.
iterator find(const KeyT &Key)
Root of the metadata hierarchy.
A Module instance is used to store all the information related to an LLVM module.
MDNode * getOperand(unsigned i) const
unsigned getNumOperands() const
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...
uint32_t getParmsType() const
MCSymbol * getPICOffsetSymbol(MachineFunction &MF) const
const SmallVectorImpl< Register > & getMustSaveCRs() const
unsigned getFloatingPointParmsNum() const
bool isAIXFuncUseTLSIEForLD() const
MCSymbol * getGlobalEPSymbol(MachineFunction &MF) const
MCSymbol * getLocalEPSymbol(MachineFunction &MF) const
unsigned getVectorParmsNum() const
int getVarArgsFrameIndex() const
bool usesTOCBasePtr() const
bool hasVectorParms() const
uint32_t getVecExtParmsType() const
MCSymbol * getTOCOffsetSymbol(MachineFunction &MF) const
unsigned getFixedParmsNum() const
static const char * getRegisterName(MCRegister Reg)
static bool hasTLSFlag(unsigned TF)
static const PPCMCExpr * createLo(const MCExpr *Expr, MCContext &Ctx)
static const PPCMCExpr * createHa(const MCExpr *Expr, MCContext &Ctx)
bool is32BitELFABI() const
const PPCFrameLowering * getFrameLowering() const override
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
bool isUsingPCRelativeCalls() const
CodeModel::Model getCodeModel(const TargetMachine &TM, const GlobalValue *GV) const
Calculates the effective code model for argument GV.
const PPCRegisterInfo * getRegisterInfo() const override
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.
bool hasGlibcHWCAPAccess() const
virtual void emitAbiVersion(int AbiVersion)
virtual void emitTCEntry(const MCSymbol &S, MCSymbolRefExpr::VariantKind Kind)
virtual void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset)
virtual void emitMachine(StringRef CPU)
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
MI-level patchpoint operands.
Wrapper class representing virtual and physical registers.
SectionKind - This is a simple POD value that classifies the properties of a section.
bool isThreadBSSLocal() const
static SectionKind getText()
static SectionKind getData()
bool isThreadLocal() const
bool isGlobalWriteableData() const
A SetVector that performs no allocations if smaller than a certain size.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
void recordStackMap(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
StringRef - Represent a constant reference to a string, i.e.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
static bool ShouldSetSSPCanaryBitInTB(const MachineFunction *MF)
static MCSymbol * getEHInfoTableSymbol(const MachineFunction *MF)
static XCOFF::StorageClass getStorageClassForGlobal(const GlobalValue *GV)
static bool ShouldEmitEHBlock(const MachineFunction *MF)
Primary interface to the complete machine description for the target machine.
const Triple & getTargetTriple() const
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
bool isOSAIX() const
Tests whether the OS is AIX.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
LLVM Value Representation.
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
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.
StringRef getName() const
Return a constant reference to the value's name.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
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.
@ C
The default llvm calling convention, compatible with C.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
@ MO_TLSLDM_FLAG
MO_TLSLDM_FLAG - on AIX the ML relocation type is only valid for a reference to a TOC symbol from the...
@ MO_TPREL_PCREL_FLAG
MO_TPREL_PCREL_FLAG = MO_PCREL_FLAG | MO_TPREL_FLAG.
@ MO_GOT_TPREL_PCREL_FLAG
MO_GOT_TPREL_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ MO_TLSLD_FLAG
MO_TLSLD_FLAG - If this bit is set the symbol reference is relative to TLS Local Dynamic model.
@ MO_TPREL_FLAG
MO_TPREL_FLAG - If this bit is set, the symbol reference is relative to the thread pointer and the sy...
@ MO_GOT_TLSLD_PCREL_FLAG
MO_GOT_TLSLD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
@ MO_TLSGD_FLAG
MO_TLSGD_FLAG - If this bit is set the symbol reference is relative to TLS General Dynamic model for ...
@ MO_GOT_TLSGD_PCREL_FLAG
MO_GOT_TLSGD_PCREL_FLAG - A combintaion of flags, if these bits are set they should produce the reloc...
StringRef getNormalizedPPCTargetCPU(const Triple &T, StringRef CPUName="")
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
const char * stripRegisterPrefix(const char *RegName)
stripRegisterPrefix - This method strips the character prefix from a register name so that only the n...
static bool isVRRegister(unsigned Reg)
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
static bool isVFRegister(unsigned Reg)
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
SmallString< 32 > getExtendedTBTableFlagString(uint8_t Flag)
XCOFF::CFileCpuId getCpuID(StringRef CPU)
Expected< SmallString< 32 > > parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum, unsigned VectorParmsNum)
Expected< SmallString< 32 > > parseParmsType(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum)
Expected< SmallString< 32 > > parseVectorParmsType(uint32_t Value, unsigned ParmsNum)
@ TCPU_INVALID
Invalid id - assumes POWER for old objects.
StorageMappingClass
Storage Mapping Class definitions.
@ XMC_RO
Read Only Constant.
@ XMC_TD
Scalar data item in the TOC.
StringRef getTCPUString(XCOFF::CFileCpuId TCPU)
StringRef getNameForTracebackTableLanguageId(TracebackTable::LanguageID LangId)
constexpr uint8_t AllocRegNo
@ XTY_SD
Csect definition for initialized storage.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
constexpr uint64_t PointerSize
aarch64 pointer size.
Linkage
Describes symbol linkage. This can be used to resolve definition clashes.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Target & getThePPC64LETarget()
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
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...
std::pair< MCSection *, uint32_t > MCSectionSubPair
void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)
format_hex_no_prefix - Output N as a fixed width hexadecimal.
Target & getThePPC64Target()
uint64_t get_threadid()
Return the current thread id, as used in various OS system calls.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Target & getThePPC32LETarget()
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
const char * toString(DWARFSectionKind Kind)
@ MCSA_Global
.type _foo, @gnu_unique_object
@ MCSA_Extern
.extern (XCOFF)
@ MCSA_LGlobal
.lglobl (XCOFF)
@ MCSA_Invalid
Not a valid directive.
Implement std::hash so that hash_code can be used in STL containers.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
static unsigned getHashValue(const TOCKey &PairVal)
static bool isEqual(const TOCKey &A, const TOCKey &B)
std::pair< const MCSymbol *, MCSymbolRefExpr::VariantKind > TOCKey
static TOCKey getTombstoneKey()
static TOCKey getEmptyKey()
An information struct used to provide DenseMap with the various necessary components for a given valu...
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn)
RegisterAsmPrinter - Register an AsmPrinter implementation for the given target.
static constexpr uint32_t FPRSavedMask
static constexpr uint16_t NumberOfVRSavedMask
static constexpr uint8_t NumberOfFloatingPointParmsShift
static constexpr uint32_t NumberOfFixedParmsMask
static constexpr uint16_t HasVMXInstructionMask
static constexpr uint32_t IsLRSavedMask
static constexpr uint16_t HasVarArgsMask
static constexpr uint32_t IsAllocaUsedMask
static constexpr uint16_t IsVRSavedOnStackMask
static constexpr uint16_t NumberOfVectorParmsMask
static constexpr uint32_t IsFloatingPointPresentMask
static constexpr uint32_t FPRSavedShift
static constexpr uint32_t NumberOfFloatingPointParmsMask
static constexpr uint32_t HasControlledStorageMask
static constexpr uint32_t HasExtensionTableMask
static constexpr uint32_t HasTraceBackTableOffsetMask
static constexpr uint32_t IsCRSavedMask
static constexpr uint8_t NumberOfFixedParmsShift
static constexpr uint32_t GPRSavedMask
static constexpr uint8_t NumberOfVectorParmsShift
static constexpr uint32_t HasParmsOnStackMask
static constexpr uint32_t IsFunctionNamePresentMask
static constexpr uint32_t IsBackChainStoredMask
static constexpr uint32_t IsInterruptHandlerMask
static constexpr uint32_t HasVectorInfoMask
static constexpr uint8_t NumberOfVRSavedShift
static constexpr uint32_t GPRSavedShift