87#define DEBUG_TYPE "asmprinter"
89STATISTIC(NumTOCEntries,
"Number of Total TOC Entries Emitted.");
90STATISTIC(NumTOCConstPool,
"Number of Constant Pool TOC Entries.");
92 "Number of Internal Linkage Global TOC Entries.");
94 "Number of External Linkage Global TOC Entries.");
95STATISTIC(NumTOCJumpTable,
"Number of Jump Table TOC Entries.");
96STATISTIC(NumTOCThreadLocal,
"Number of Thread Local TOC Entries.");
97STATISTIC(NumTOCBlockAddress,
"Number of Block Address TOC Entries.");
98STATISTIC(NumTOCEHBlock,
"Number of EH Block TOC Entries.");
111 using TOCKey = std::pair<const MCSymbol *, PPCMCExpr::Specifier>;
130 Tag_GNU_Power_ABI_FP = 4,
131 Tag_GNU_Power_ABI_Vector = 8,
132 Tag_GNU_Power_ABI_Struct_Return = 12,
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,
154 MapVector<std::pair<const MCSymbol *, PPCMCExpr::Specifier>,
MCSymbol *> TOC;
155 const PPCSubtarget *Subtarget =
nullptr;
160 MapVector<const GlobalValue *, uint64_t> TLSVarsToAddressMapping;
163 explicit PPCAsmPrinter(TargetMachine &TM,
164 std::unique_ptr<MCStreamer> Streamer,
char &
ID)
165 : AsmPrinter(TM, std::
move(Streamer),
ID) {}
167 StringRef getPassName()
const override {
return "PowerPC Assembly Printer"; }
170 TOCType_ConstantPool,
171 TOCType_GlobalExternal,
172 TOCType_GlobalInternal,
175 TOCType_BlockAddress,
179 MCSymbol *lookUpOrCreateTOCEntry(
const MCSymbol *Sym, TOCEntryType
Type,
182 bool doInitialization(
Module &M)
override {
188 const MCExpr *symbolWithSpecifier(
const MCSymbol *S,
195 void printOperand(
const MachineInstr *
MI,
unsigned OpNo, raw_ostream &O);
197 void PrintSymbolOperand(
const MachineOperand &MO, raw_ostream &O)
override;
198 bool PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
199 const char *ExtraCode, raw_ostream &O)
override;
200 bool PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNo,
201 const char *ExtraCode, raw_ostream &O)
override;
203 void LowerSTACKMAP(StackMaps &SM,
const MachineInstr &
MI);
204 void LowerPATCHPOINT(StackMaps &SM,
const MachineInstr &
MI);
206 void EmitAIXTlsCallHelper(
const MachineInstr *
MI);
207 const MCExpr *getAdjustedFasterLocalExpr(
const MachineOperand &MO,
209 bool runOnMachineFunction(MachineFunction &MF)
override {
218class PPCLinuxAsmPrinter :
public PPCAsmPrinter {
222 explicit PPCLinuxAsmPrinter(TargetMachine &TM,
223 std::unique_ptr<MCStreamer> Streamer)
224 : PPCAsmPrinter(TM, std::
move(Streamer), ID) {}
226 StringRef getPassName()
const override {
227 return "Linux PPC Assembly Printer";
230 void emitGNUAttributes(
Module &M);
232 void emitStartOfAsmFile(
Module &M)
override;
233 void emitEndOfAsmFile(
Module &)
override;
235 void emitFunctionEntryLabel()
override;
237 void emitFunctionBodyStart()
override;
238 void emitFunctionBodyEnd()
override;
242class PPCAIXAsmPrinter :
public PPCAsmPrinter {
246 SmallSetVector<MCSymbol *, 8> ExtSymSDNodeSymbols;
250 std::string FormatIndicatorAndUniqueModId;
254 DenseMap<const GlobalObject *, SmallVector<const GlobalAlias *, 1>>
257 uint16_t getNumberOfVRSaved();
258 void emitTracebackTable();
262 void emitGlobalVariableHelper(
const GlobalVariable *);
265 uint64_t getAliasOffset(
const Constant *
C);
270 PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
271 : PPCAsmPrinter(TM, std::
move(Streamer), ID) {
272 if (MAI->isLittleEndian())
274 "cannot create AIX PPC Assembly Printer for a little-endian target");
277 StringRef getPassName()
const override {
return "AIX PPC Assembly Printer"; }
279 bool doInitialization(
Module &M)
override;
281 void emitXXStructorList(
const DataLayout &
DL,
const Constant *
List,
282 bool IsCtor)
override;
284 void SetupMachineFunction(MachineFunction &MF)
override;
286 void emitGlobalVariable(
const GlobalVariable *GV)
override;
288 void emitFunctionDescriptor()
override;
290 void emitFunctionEntryLabel()
override;
292 void emitFunctionBodyEnd()
override;
294 void emitPGORefs(
Module &M);
298 void emitEndOfAsmFile(
Module &)
override;
300 void emitLinkage(
const GlobalValue *GV, MCSymbol *GVSym)
const override;
304 bool doFinalization(
Module &M)
override;
306 void emitTTypeReference(
const GlobalValue *GV,
unsigned Encoding)
override;
308 void emitModuleCommandLines(
Module &M)
override;
310 void emitRefMetadata(
const GlobalObject *);
319 getSymbol(GV)->
print(O, MAI);
323void PPCAsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNo,
325 const DataLayout &
DL = getDataLayout();
326 const MachineOperand &MO =
MI->getOperand(OpNo);
346 O <<
DL.getPrivateGlobalPrefix() <<
"CPI" << getFunctionNumber() <<
'_'
353 PrintSymbolOperand(MO, O);
358 O <<
"<unknown operand type: " << (unsigned)MO.
getType() <<
">";
365bool PPCAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
366 const char *ExtraCode, raw_ostream &O) {
368 if (ExtraCode && ExtraCode[0]) {
369 if (ExtraCode[1] != 0)
return true;
371 switch (ExtraCode[0]) {
377 if (!
MI->getOperand(OpNo).isReg() ||
378 OpNo+1 ==
MI->getNumOperands() ||
379 !
MI->getOperand(OpNo+1).isReg())
386 if (
MI->getOperand(OpNo).isImm())
390 if(!
MI->getOperand(OpNo).isReg())
396 Reg = PPC::VSX32 + (
Reg - PPC::V0);
398 Reg = PPC::VSX32 + (
Reg - PPC::VF0);
414bool PPCAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNo,
415 const char *ExtraCode,
417 if (ExtraCode && ExtraCode[0]) {
418 if (ExtraCode[1] != 0)
return true;
420 switch (ExtraCode[0]) {
421 default:
return true;
423 O << getDataLayout().getPointerSize() <<
"(";
434 if (
MI->getOperand(OpNo).isImm())
445 assert(
MI->getOperand(OpNo).isReg());
450 assert(
MI->getOperand(OpNo).isReg());
460 case PPCAsmPrinter::TOCType_ConstantPool:
463 case PPCAsmPrinter::TOCType_GlobalInternal:
464 ++NumTOCGlobalInternal;
466 case PPCAsmPrinter::TOCType_GlobalExternal:
467 ++NumTOCGlobalExternal;
469 case PPCAsmPrinter::TOCType_JumpTable:
472 case PPCAsmPrinter::TOCType_ThreadLocal:
475 case PPCAsmPrinter::TOCType_BlockAddress:
476 ++NumTOCBlockAddress;
478 case PPCAsmPrinter::TOCType_EHBlock:
495 assert(GV &&
"expected global for MO_GlobalAddress");
516MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(
const MCSymbol *Sym,
520 auto [It,
Inserted] =
TOC.try_emplace({Sym, Spec});
526 TOCEntry = createTempSymbol(
"C");
530void PPCAsmPrinter::LowerSTACKMAP(StackMaps &SM,
const MachineInstr &
MI) {
531 unsigned NumNOPBytes =
MI.getOperand(1).getImm();
533 auto &Ctx = OutStreamer->getContext();
534 MCSymbol *MILabel = Ctx.createTempSymbol();
535 OutStreamer->emitLabel(MILabel);
538 assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
541 const MachineBasicBlock &
MBB = *
MI.getParent();
544 while (NumNOPBytes > 0) {
545 if (MII ==
MBB.
end() || MII->isCall() ||
546 MII->getOpcode() == PPC::DBG_VALUE ||
547 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
548 MII->getOpcode() == TargetOpcode::STACKMAP)
555 for (
unsigned i = 0; i < NumNOPBytes; i += 4)
556 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
561void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM,
const MachineInstr &
MI) {
562 auto &Ctx = OutStreamer->getContext();
563 MCSymbol *MILabel = Ctx.createTempSymbol();
564 OutStreamer->emitLabel(MILabel);
567 PatchPointOpers Opers(&
MI);
569 unsigned EncodedBytes = 0;
570 const MachineOperand &CalleeMO = Opers.getCallTarget();
572 if (CalleeMO.
isImm()) {
573 int64_t CallTarget = CalleeMO.
getImm();
575 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
576 "High 16 bits of call target should be zero.");
577 Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
580 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8)
582 .addImm((CallTarget >> 32) & 0xFFFF));
585 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC)
588 .addImm(32).addImm(16));
591 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8)
594 .addImm((CallTarget >> 16) & 0xFFFF));
597 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8)
600 .addImm(CallTarget & 0xFFFF));
605 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD)
607 .addImm(TOCSaveOffset)
617 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
620 .addReg(ScratchReg));
623 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
626 .addReg(ScratchReg));
630 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8)
631 .addReg(ScratchReg));
634 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8));
638 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
640 .addImm(TOCSaveOffset)
645 const GlobalValue *GValue = CalleeMO.
getGlobal();
646 MCSymbol *MOSymbol = getSymbol(GValue);
649 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP)
658 unsigned NumBytes = Opers.getNumPatchBytes();
659 if (NumBytes < EncodedBytes)
661 "Patchpoint can't request size less than the length of a call.");
663 assert((NumBytes - EncodedBytes) % 4 == 0 &&
664 "Invalid number of NOP bytes requested!");
665 for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
666 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
676 SymName =
".__tls_get_addr";
678 case PPC::GETtlsTpointer32AIX:
679 SymName =
".__get_tpointer";
681 case PPC::GETtlsMOD32AIX:
682 case PPC::GETtlsMOD64AIX:
683 SymName =
".__tls_get_mod";
689 ->getQualNameSymbol();
692void PPCAsmPrinter::EmitAIXTlsCallHelper(
const MachineInstr *
MI) {
694 "Only expecting to emit calls to get the thread pointer on AIX!");
698 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BLA).addExpr(TlsRef));
703void PPCAsmPrinter::emitTlsCall(
const MachineInstr *
MI,
706 unsigned Opcode = PPC::BL8_NOP_TLS;
708 assert(
MI->getNumOperands() >= 3 &&
"Expecting at least 3 operands from MI");
712 Opcode = PPC::BL8_NOTOC_TLS;
714 const Module *
M = MF->getFunction().getParent();
717 ((Subtarget->isPPC64() &&
MI->getOperand(0).getReg() == PPC::X3) ||
718 (!Subtarget->isPPC64() &&
MI->getOperand(0).getReg() == PPC::R3)) &&
719 "GETtls[ld]ADDR[32] must define GPR3");
721 ((Subtarget->isPPC64() &&
MI->getOperand(1).getReg() == PPC::X3) ||
722 (!Subtarget->isPPC64() &&
MI->getOperand(1).getReg() == PPC::R3)) &&
723 "GETtls[ld]ADDR[32] must read GPR3");
730 Register VarOffsetReg = Subtarget->isPPC64() ? PPC::X4 : PPC::R4;
732 assert((
MI->getOpcode() == PPC::GETtlsMOD32AIX ||
733 MI->getOpcode() == PPC::GETtlsMOD64AIX ||
734 (
MI->getOperand(2).isReg() &&
735 MI->getOperand(2).getReg() == VarOffsetReg)) &&
736 "GETtls[ld]ADDR[32] must read GPR4");
737 EmitAIXTlsCallHelper(
MI);
741 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(
"__tls_get_addr");
749 if (Kind ==
PPC::S_PLT && Subtarget->isSecurePlt() &&
753 const MachineOperand &MO =
MI->getOperand(2);
754 const GlobalValue *GValue = MO.
getGlobal();
755 MCSymbol *MOSymbol = getSymbol(GValue);
757 EmitToStreamer(*OutStreamer,
758 MCInstBuilder(Subtarget->isPPC64() ? Opcode
759 : (
unsigned)PPC::BL_TLS)
782static PPCAsmPrinter::TOCEntryType
787 return PPCAsmPrinter::TOCType_ThreadLocal;
796 return PPCAsmPrinter::TOCType_GlobalExternal;
798 return PPCAsmPrinter::TOCType_GlobalInternal;
801 return PPCAsmPrinter::TOCType_ConstantPool;
803 return PPCAsmPrinter::TOCType_JumpTable;
805 return PPCAsmPrinter::TOCType_BlockAddress;
811const MCExpr *PPCAsmPrinter::symbolWithSpecifier(
const MCSymbol *S,
819void PPCAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
820 PPC_MC::verifyInstructionPredicates(
MI->getOpcode(),
821 getSubtargetInfo().getFeatureBits());
824 const bool IsPPC64 = Subtarget->isPPC64();
825 const bool IsAIX = Subtarget->
isAIXABI();
826 const bool HasAIXSmallLocalTLS = Subtarget->hasAIXSmallLocalExecTLS() ||
827 Subtarget->hasAIXSmallLocalDynamicTLS();
828 const Module *
M = MF->getFunction().getParent();
833 if (!
MI->isInlineAsm()) {
834 for (
const MachineOperand &MO:
MI->operands()) {
837 if (Subtarget->hasSPE()) {
855 auto getTOCRelocAdjustedExprForXCOFF = [
this](
const MCExpr *Expr,
856 ptrdiff_t OriginalOffset) {
863 ptrdiff_t Adjustment =
869 auto getTOCEntryLoadingExprForXCOFF =
870 [IsPPC64, getTOCRelocAdjustedExprForXCOFF,
871 this](
const MCSymbol *MOSymbol,
const MCExpr *Expr,
873 const unsigned EntryByteSize = IsPPC64 ? 8 : 4;
874 const auto TOCEntryIter =
TOC.find({MOSymbol, VK});
876 "Could not find the TOC entry for this symbol.");
877 const ptrdiff_t EntryDistanceFromTOCBase =
878 (TOCEntryIter -
TOC.begin()) * EntryByteSize;
879 constexpr int16_t PositiveTOCRange = INT16_MAX;
881 if (EntryDistanceFromTOCBase > PositiveTOCRange)
882 return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase);
894 assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!\n");
902 PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
906 dbgs() <<
"Current function uses IE access for default LD vars.\n");
933 MCFragment *OldFragment = OutStreamer->getCurrentFragment();
936 if (!OutStreamer->isObj())
938 MCFragment *NewFragment = OutStreamer->getCurrentFragment();
939 if (NewFragment != OldFragment)
941 unsigned ActualSize = NewFragment->
getFixedSize() - OldFragSize;
943 if (ActualSize != ExpectedSize &&
944 MI->getOpcode() != TargetOpcode::STACKMAP) {
945 dbgs() <<
"Size mismatch for: " << *
MI <<
"\n";
946 dbgs() <<
"Expected size: " << ExpectedSize <<
"\n";
947 dbgs() <<
"Actual size: " << ActualSize <<
"\n";
954 switch (
MI->getOpcode()) {
956 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
958 "AIX does not support patchable function entry!");
961 (void)
F.getFnAttribute(
"patchable-function-entry")
963 .getAsInteger(10, Num);
969 case TargetOpcode::DBG_VALUE:
971 case TargetOpcode::STACKMAP:
972 return LowerSTACKMAP(SM, *
MI);
973 case TargetOpcode::PATCHPOINT:
974 return LowerPATCHPOINT(SM, *
MI);
976 case PPC::MoveGOTtoLR: {
984 OutContext.getOrCreateSymbol(StringRef(
"_GLOBAL_OFFSET_TABLE_"));
990 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));
993 case PPC::MovePCtoLR:
994 case PPC::MovePCtoLR8: {
999 MCSymbol *PICBase = MF->getPICBaseSymbol();
1002 EmitToStreamer(*OutStreamer,
1003 MCInstBuilder(PPC::BCLalways)
1009 OutStreamer->emitLabel(PICBase);
1012 case PPC::UpdateGBR: {
1021 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
1023 MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
1032 const MCExpr *DeltaHi =
1036 MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));
1038 const MCExpr *DeltaLo =
1042 MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
1046 MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol(*MF);
1053 const MCOperand PICR = TmpInst.
getOperand(0);
1060 EmitToStreamer(*OutStreamer, TmpInst);
1066 EmitToStreamer(*OutStreamer, TmpInst);
1077 const MachineOperand &MO =
MI->getOperand(1);
1079 "Invalid operand for LWZtoc.");
1087 const MCExpr *
Exp = symbolWithSpecifier(MOSymbol,
PPC::S_GOT);
1089 EmitToStreamer(*OutStreamer, TmpInst);
1108 "This pseudo should only be selected for 32-bit small code model.");
1109 Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK);
1114 OutStreamer->getCommentOS() << MO <<
'\n';
1115 EmitToStreamer(*OutStreamer, TmpInst);
1122 OutContext.getOrCreateSymbol(Twine(
".LTOC")), OutContext);
1125 EmitToStreamer(*OutStreamer, TmpInst);
1129 case PPC::ADDItoc8: {
1131 "PseudoOp only valid for small code model AIX");
1137 TmpInst.
setOpcode((!IsPPC64) ? (PPC::LA) : (PPC::LA8));
1139 const MachineOperand &MO =
MI->getOperand(2);
1148 EmitToStreamer(*OutStreamer, TmpInst);
1161 const MachineOperand &MO =
MI->getOperand(1);
1163 "Invalid operand!");
1177 const MCExpr *
Exp = symbolWithSpecifier(TOCEntry, VKExpr);
1179 IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK) : Exp);
1182 if (isVerbose() && IsAIX)
1183 OutStreamer->getCommentOS() << MO <<
'\n';
1184 EmitToStreamer(*OutStreamer, TmpInst);
1187 case PPC::ADDIStocHA: {
1188 const MachineOperand &MO =
MI->getOperand(2);
1191 "Invalid operand for ADDIStocHA.");
1192 assert((IsAIX && !IsPPC64 &&
1194 "This pseudo should only be selected for 32-bit large code model on"
1214 if ( {
1226 const MCExpr *
Exp = symbolWithSpecifier(MOSymbol,
PPC::S_U);
1228 EmitToStreamer(*OutStreamer, TmpInst);
1231 case PPC::LWZtocL: {
1232 const MachineOperand &MO =
MI->getOperand(1);
1235 "Invalid operand for LWZtocL.");
1236 assert(IsAIX && !IsPPC64 &&
1238 "This pseudo should only be selected for 32-bit large code model on"
1258 const MCExpr *
Exp = symbolWithSpecifier(TOCEntry,
PPC::S_L);
1260 EmitToStreamer(*OutStreamer, TmpInst);
1263 case PPC::ADDIStocHA8: {
1273 const MachineOperand &MO =
MI->getOperand(2);
1275 "Invalid operand for ADDIStocHA8!");
1281 const bool GlobalToc =
1293 const MCExpr *
Exp = symbolWithSpecifier(MOSymbol, VK);
1302 EmitToStreamer(*OutStreamer, TmpInst);
1315 const MachineOperand &MO =
MI->getOperand(1);
1318 "Invalid operand for LDtocL!");
1322 "LDtocL used on symbol that could be accessed directly is "
1323 "invalid. Must match ADDIStocHA8."));
1334 const MCExpr *
Exp = symbolWithSpecifier(MOSymbol, VK);
1336 EmitToStreamer(*OutStreamer, TmpInst);
1340 case PPC::ADDItocL8: {
1344 unsigned Op =
MI->getOpcode();
1348 TmpInst.
setOpcode(
Op == PPC::ADDItocL8 ? (IsAIX ? PPC::LA8 : PPC::ADDI8)
1351 const MachineOperand &MO =
MI->getOperand(2);
1354 : MO.
isGlobal() &&
"Invalid operand for ADDItocL8.");
1356 "Interposable definitions must use indirect accesses.");
1365 EmitToStreamer(*OutStreamer, TmpInst);
1368 case PPC::ADDISgotTprelHA: {
1371 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1372 const MachineOperand &MO =
MI->getOperand(2);
1373 const GlobalValue *GValue = MO.
getGlobal();
1374 MCSymbol *MOSymbol = getSymbol(GValue);
1375 const MCExpr *SymGotTprel =
1377 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1378 .addReg(
MI->getOperand(0).getReg())
1379 .addReg(
MI->getOperand(1).getReg())
1380 .addExpr(SymGotTprel));
1383 case PPC::LDgotTprelL:
1384 case PPC::LDgotTprelL32: {
1389 TmpInst.
setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ);
1390 const MachineOperand &MO =
MI->getOperand(1);
1391 const GlobalValue *GValue = MO.
getGlobal();
1392 MCSymbol *MOSymbol = getSymbol(GValue);
1393 const MCExpr *
Exp = symbolWithSpecifier(
1396 EmitToStreamer(*OutStreamer, TmpInst);
1400 case PPC::PPC32PICGOT: {
1401 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1402 MCSymbol *GOTRef = OutContext.createTempSymbol();
1403 MCSymbol *NextInstr = OutContext.createTempSymbol();
1405 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL)
1409 const MCExpr *OffsExpr =
1413 OutStreamer->emitLabel(GOTRef);
1414 OutStreamer->emitValue(OffsExpr, 4);
1415 OutStreamer->emitLabel(NextInstr);
1416 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR)
1417 .addReg(
MI->getOperand(0).getReg()));
1418 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
1419 .addReg(
MI->getOperand(1).getReg())
1421 .addReg(
MI->getOperand(0).getReg()));
1422 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4)
1423 .addReg(
MI->getOperand(0).getReg())
1424 .addReg(
MI->getOperand(1).getReg())
1425 .addReg(
MI->getOperand(0).getReg()));
1428 case PPC::PPC32GOT: {
1430 OutContext.getOrCreateSymbol(StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1431 const MCExpr *SymGotTlsL =
1433 const MCExpr *SymGotTlsHA =
1435 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI)
1436 .addReg(
MI->getOperand(0).getReg())
1437 .addExpr(SymGotTlsL));
1438 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
1439 .addReg(
MI->getOperand(0).getReg())
1440 .addReg(
MI->getOperand(0).getReg())
1441 .addExpr(SymGotTlsHA));
1444 case PPC::ADDIStlsgdHA: {
1447 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1448 const MachineOperand &MO =
MI->getOperand(2);
1449 const GlobalValue *GValue = MO.
getGlobal();
1450 MCSymbol *MOSymbol = getSymbol(GValue);
1451 const MCExpr *SymGotTlsGD =
1453 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1454 .addReg(
MI->getOperand(0).getReg())
1455 .addReg(
MI->getOperand(1).getReg())
1456 .addExpr(SymGotTlsGD));
1459 case PPC::ADDItlsgdL:
1462 case PPC::ADDItlsgdL32: {
1465 const MachineOperand &MO =
MI->getOperand(2);
1466 const GlobalValue *GValue = MO.
getGlobal();
1467 MCSymbol *MOSymbol = getSymbol(GValue);
1468 const MCExpr *SymGotTlsGD = symbolWithSpecifier(
1470 EmitToStreamer(*OutStreamer,
1471 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1472 .addReg(
MI->getOperand(0).getReg())
1473 .addReg(
MI->getOperand(1).getReg())
1474 .addExpr(SymGotTlsGD));
1477 case PPC::GETtlsMOD32AIX:
1478 case PPC::GETtlsMOD64AIX:
1482 case PPC::GETtlsADDR:
1485 case PPC::GETtlsADDRPCREL:
1486 case PPC::GETtlsADDR32AIX:
1487 case PPC::GETtlsADDR64AIX:
1491 case PPC::GETtlsADDR32: {
1497 case PPC::GETtlsTpointer32AIX: {
1500 EmitAIXTlsCallHelper(
MI);
1503 case PPC::ADDIStlsldHA: {
1506 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1507 const MachineOperand &MO =
MI->getOperand(2);
1508 const GlobalValue *GValue = MO.
getGlobal();
1509 MCSymbol *MOSymbol = getSymbol(GValue);
1510 const MCExpr *SymGotTlsLD =
1512 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1513 .addReg(
MI->getOperand(0).getReg())
1514 .addReg(
MI->getOperand(1).getReg())
1515 .addExpr(SymGotTlsLD));
1518 case PPC::ADDItlsldL:
1521 case PPC::ADDItlsldL32: {
1524 const MachineOperand &MO =
MI->getOperand(2);
1525 const GlobalValue *GValue = MO.
getGlobal();
1526 MCSymbol *MOSymbol = getSymbol(GValue);
1527 const MCExpr *SymGotTlsLD = symbolWithSpecifier(
1529 EmitToStreamer(*OutStreamer,
1530 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1531 .addReg(
MI->getOperand(0).getReg())
1532 .addReg(
MI->getOperand(1).getReg())
1533 .addExpr(SymGotTlsLD));
1536 case PPC::GETtlsldADDR:
1539 case PPC::GETtlsldADDRPCREL:
1540 case PPC::GETtlsldADDR32: {
1546 case PPC::ADDISdtprelHA:
1549 case PPC::ADDISdtprelHA32: {
1552 const MachineOperand &MO =
MI->getOperand(2);
1553 const GlobalValue *GValue = MO.
getGlobal();
1554 MCSymbol *MOSymbol = getSymbol(GValue);
1558 MCInstBuilder(IsPPC64 ? PPC::ADDIS8 : PPC::ADDIS)
1559 .addReg(
MI->getOperand(0).getReg())
1560 .addReg(
MI->getOperand(1).getReg())
1561 .addExpr(SymDtprel));
1564 case PPC::PADDIdtprel: {
1567 const MachineOperand &MO =
MI->getOperand(2);
1568 const GlobalValue *GValue = MO.
getGlobal();
1569 MCSymbol *MOSymbol = getSymbol(GValue);
1570 const MCExpr *SymDtprel = symbolWithSpecifier(MOSymbol,
PPC::S_DTPREL);
1571 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::PADDI8)
1572 .addReg(
MI->getOperand(0).getReg())
1573 .addReg(
MI->getOperand(1).getReg())
1574 .addExpr(SymDtprel));
1578 case PPC::ADDIdtprelL:
1581 case PPC::ADDIdtprelL32: {
1584 const MachineOperand &MO =
MI->getOperand(2);
1585 const GlobalValue *GValue = MO.
getGlobal();
1586 MCSymbol *MOSymbol = getSymbol(GValue);
1588 EmitToStreamer(*OutStreamer,
1589 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1590 .addReg(
MI->getOperand(0).getReg())
1591 .addReg(
MI->getOperand(1).getReg())
1592 .addExpr(SymDtprel));
1597 if (!Subtarget->hasMFOCRF()) {
1600 unsigned NewOpcode =
1601 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
1602 OutStreamer->AddComment(PPCInstPrinter::
1604 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1605 .addReg(
MI->getOperand(0).getReg()));
1611 if (!Subtarget->hasMFOCRF()) {
1614 unsigned NewOpcode =
1615 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1616 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
1617 ->getEncodingValue(
MI->getOperand(0).getReg());
1618 OutStreamer->AddComment(PPCInstPrinter::
1620 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1622 .addReg(
MI->getOperand(1).getReg()));
1632 unsigned OpNum = (
MI->getOpcode() == PPC::STD) ? 2 : 1;
1636 for (
const MachineOperand &TempMO :
MI->operands()) {
1639 TempMO.getOperandNo() == 1)
1642 const MachineOperand &MO =
MI->getOperand(OpNum);
1676 if (!HasAIXSmallLocalTLS)
1678 bool IsMIADDI8 =
MI->getOpcode() == PPC::ADDI8;
1679 unsigned OpNum = IsMIADDI8 ? 2 : 1;
1680 const MachineOperand &MO =
MI->getOperand(OpNum);
1687 const MCExpr *Expr = getAdjustedFasterLocalExpr(MO, MO.
getOffset());
1695 EmitToStreamer(*OutStreamer, TmpInst);
1701 case PPC::PseudoEIEIO: {
1704 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1707 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1708 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::EnforceIEIO));
1714 EmitToStreamer(*OutStreamer, TmpInst);
1724PPCAsmPrinter::getAdjustedFasterLocalExpr(
const MachineOperand &MO,
1731 assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!");
1732 const GlobalValue *GValue = MO.
getGlobal();
1735 "Only local-[exec|dynamic] accesses are handled!");
1741 const auto TLSVarsMapEntryIter = TLSVarsToAddressMapping.
find(GValue);
1742 if (TLSVarsMapEntryIter == TLSVarsToAddressMapping.
end())
1743 assert(IsGlobalADeclaration &&
1744 "Only expecting to find extern TLS variables not present in the TLS "
1745 "variable-to-address map!");
1747 unsigned TLSVarAddress =
1748 IsGlobalADeclaration ? 0 : TLSVarsMapEntryIter->second;
1749 ptrdiff_t FinalAddress = (TLSVarAddress +
Offset);
1761 if (FinalAddress >= 32768) {
1768 ptrdiff_t Delta = ((FinalAddress + 32768) & ~0xFFFF);
1770 [[maybe_unused]] ptrdiff_t InstDisp = TLSVarAddress +
Offset - Delta;
1772 ((InstDisp < 32768) && (InstDisp >= -32768)) &&
1773 "Expecting the instruction displacement for local-[exec|dynamic] TLS "
1774 "variables to be between [-32768, 32768)!");
1782void PPCLinuxAsmPrinter::emitGNUAttributes(
Module &M) {
1784 Metadata *MD =
M.getModuleFlag(
"float-abi");
1790 if (flt ==
"doubledouble")
1791 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1792 Val_GNU_Power_ABI_HardFloat_DP |
1793 Val_GNU_Power_ABI_LDBL_IBM128);
1794 else if (flt ==
"ieeequad")
1795 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1796 Val_GNU_Power_ABI_HardFloat_DP |
1797 Val_GNU_Power_ABI_LDBL_IEEE128);
1798 else if (flt ==
"ieeedouble")
1799 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1800 Val_GNU_Power_ABI_HardFloat_DP |
1801 Val_GNU_Power_ABI_LDBL_64);
1804void PPCLinuxAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
1805 if (!Subtarget->isPPC64())
1806 return PPCAsmPrinter::emitInstruction(
MI);
1808 switch (
MI->getOpcode()) {
1811 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1826 (void)
F.getFnAttribute(
"patchable-function-entry")
1828 .getAsInteger(10, Num);
1830 if (!MAI->isLittleEndian() || Num)
1832 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1833 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1834 OutStreamer->emitLabel(BeginOfSled);
1835 EmitToStreamer(*OutStreamer,
1836 MCInstBuilder(PPC::B).addExpr(
1838 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1841 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1842 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1843 EmitToStreamer(*OutStreamer,
1844 MCInstBuilder(PPC::BL8_NOP)
1846 OutContext.getOrCreateSymbol(
"__xray_FunctionEntry"),
1848 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1849 OutStreamer->emitLabel(EndOfSled);
1850 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_ENTER, 2);
1853 case TargetOpcode::PATCHABLE_RET: {
1854 unsigned RetOpcode =
MI->getOperand(0).getImm();
1864 if (RetOpcode == PPC::BCCLR) {
1865 IsConditional =
true;
1866 }
else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1867 RetOpcode == PPC::TCRETURNai8) {
1869 }
else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1870 IsConditional =
false;
1872 EmitToStreamer(*OutStreamer, RetInst);
1877 if (IsConditional) {
1896 FallthroughLabel = OutContext.createTempSymbol();
1899 MCInstBuilder(PPC::BCC)
1902 .addReg(
MI->getOperand(2).getReg())
1919 OutStreamer->emitCodeAlignment(
Align(8), &getSubtargetInfo());
1920 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1921 OutStreamer->emitLabel(BeginOfSled);
1922 EmitToStreamer(*OutStreamer, RetInst);
1923 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1926 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1927 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1928 EmitToStreamer(*OutStreamer,
1929 MCInstBuilder(PPC::BL8_NOP)
1931 OutContext.getOrCreateSymbol(
"__xray_FunctionExit"),
1933 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1934 EmitToStreamer(*OutStreamer, RetInst);
1936 OutStreamer->emitLabel(FallthroughLabel);
1937 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_EXIT, 2);
1940 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1942 case TargetOpcode::PATCHABLE_TAIL_CALL:
1946 "around this assert.");
1948 return PPCAsmPrinter::emitInstruction(
MI);
1951void PPCLinuxAsmPrinter::emitStartOfAsmFile(
Module &M) {
1952 if (
static_cast<const PPCTargetMachine &
>(TM).isELFv2ABI()) {
1953 PPCTargetStreamer *TS =
1954 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
1958 if (
static_cast<const PPCTargetMachine &
>(TM).isPPC64() ||
1959 !isPositionIndependent())
1965 OutStreamer->switchSection(OutContext.getELFSection(
1968 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(
".LTOC"));
1969 MCSymbol *CurrentPos = OutContext.createTempSymbol();
1971 OutStreamer->emitLabel(CurrentPos);
1975 const MCExpr *tocExpr =
1980 OutStreamer->emitAssignment(TOCSym, tocExpr);
1982 OutStreamer->switchSection(getObjFileLowering().getTextSection());
1985void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
1987 if (!Subtarget->isPPC64() &&
1988 (!isPositionIndependent() ||
1992 if (!Subtarget->isPPC64()) {
1993 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1994 if (PPCFI->
usesPICBase() && !Subtarget->isSecurePlt()) {
1996 MCSymbol *PICBase = MF->getPICBaseSymbol();
1997 OutStreamer->emitLabel(RelocSymbol);
1999 const MCExpr *OffsExpr =
2005 OutStreamer->emitValue(OffsExpr, 4);
2006 OutStreamer->emitLabel(CurrentFnSym);
2019 && !MF->getRegInfo().use_empty(PPC::X2)) {
2020 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
2022 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(
".TOC."));
2024 const MCExpr *TOCDeltaExpr =
2031 OutStreamer->emitValue(TOCDeltaExpr, 8);
2038 MCSectionELF *
Section = OutStreamer->getContext().getELFSection(
2040 OutStreamer->switchSection(Section);
2041 OutStreamer->emitLabel(CurrentFnSym);
2042 OutStreamer->emitValueToAlignment(
Align(8));
2043 MCSymbol *Symbol1 = CurrentFnSymForSize;
2048 MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(
".TOC."));
2050 OutStreamer->emitValue(
2053 OutStreamer->emitIntValue(0, 8 );
2054 OutStreamer->switchSection(Current.first, Current.second);
2057void PPCLinuxAsmPrinter::emitEndOfAsmFile(
Module &M) {
2058 const DataLayout &
DL = getDataLayout();
2060 bool isPPC64 =
DL.getPointerSizeInBits() == 64;
2062 PPCTargetStreamer *TS =
2063 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
2069 if (
static_cast<const PPCTargetMachine &
>(TM).hasGlibcHWCAPAccess())
2070 OutStreamer->emitSymbolValue(
2071 GetExternalSymbolSymbol(
"__parse_hwcap_and_convert_at_platform"),
2072 MAI->getCodePointerSize());
2073 emitGNUAttributes(M);
2076 const char *
Name = isPPC64 ?
".toc" :
".got2";
2077 MCSectionELF *
Section = OutContext.getELFSection(
2079 OutStreamer->switchSection(Section);
2081 OutStreamer->emitValueToAlignment(
Align(4));
2083 for (
const auto &TOCMapPair : TOC) {
2084 const MCSymbol *
const TOCEntryTarget = TOCMapPair.first.first;
2085 MCSymbol *
const TOCEntryLabel = TOCMapPair.second;
2087 OutStreamer->emitLabel(TOCEntryLabel);
2089 TS->
emitTCEntry(*TOCEntryTarget, TOCMapPair.first.second);
2091 OutStreamer->emitSymbolValue(TOCEntryTarget, 4);
2095 PPCAsmPrinter::emitEndOfAsmFile(M);
2099void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
2131 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
2132 const bool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) ||
2133 !MF->getRegInfo().use_empty(PPC::R2);
2142 if (NonPCrelGEPRequired || PCrelGEPRequired) {
2147 OutStreamer->emitLabel(GlobalEntryLabel);
2148 const MCSymbolRefExpr *GlobalEntryLabelExp =
2152 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(
".TOC."));
2153 const MCExpr *TOCDeltaExpr =
2155 GlobalEntryLabelExp, OutContext);
2157 const MCExpr *TOCDeltaHi =
2159 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
2162 .addExpr(TOCDeltaHi));
2164 const MCExpr *TOCDeltaLo =
2166 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
2169 .addExpr(TOCDeltaLo));
2172 const MCExpr *TOCOffsetDeltaExpr =
2174 GlobalEntryLabelExp, OutContext);
2176 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
2178 .addExpr(TOCOffsetDeltaExpr)
2180 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8)
2187 OutStreamer->emitLabel(LocalEntryLabel);
2188 const MCSymbolRefExpr *LocalEntryLabelExp =
2190 const MCExpr *LocalOffsetExp =
2192 GlobalEntryLabelExp, OutContext);
2194 PPCTargetStreamer *TS =
2195 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
2220 if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() ||
2221 MF->hasInlineAsm() || (!PPCFI->
usesTOCBasePtr() && UsesX2OrR2)) {
2222 PPCTargetStreamer *TS =
2223 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
2233void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
2241 if (Subtarget->isPPC64()) {
2242 OutStreamer->emitIntValue(0, 4);
2243 OutStreamer->emitIntValue(0, 8);
2247char PPCLinuxAsmPrinter::ID = 0;
2250 "Linux PPC Assembly Printer",
false,
false)
2255 switch (GV->getLinkage()) {
2256 case GlobalValue::ExternalLinkage:
2257 LinkageAttr = GV->isDeclaration() ? MCSA_Extern : MCSA_Global;
2259 case GlobalValue::LinkOnceAnyLinkage:
2260 case GlobalValue::LinkOnceODRLinkage:
2261 case GlobalValue::WeakAnyLinkage:
2262 case GlobalValue::WeakODRLinkage:
2263 case GlobalValue::ExternalWeakLinkage:
2264 LinkageAttr = MCSA_Weak;
2266 case GlobalValue::AvailableExternallyLinkage:
2267 LinkageAttr = MCSA_Extern;
2269 case GlobalValue::PrivateLinkage:
2271 case GlobalValue::InternalLinkage:
2272 assert(GV->getVisibility() == GlobalValue::DefaultVisibility &&
2273 "InternalLinkage should not have other visibility setting.");
2274 LinkageAttr = MCSA_LGlobal;
2276 case GlobalValue::AppendingLinkage:
2277 llvm_unreachable(
"Should never emit this");
2278 case GlobalValue::CommonLinkage:
2279 llvm_unreachable(
"CommonLinkage of XCOFF should not come to this path");
2285 if (!TM.getIgnoreXCOFFVisibility()) {
2286 if (GV->hasDLLExportStorageClass() && !GV->hasDefaultVisibility())
2288 "Cannot not be both dllexport and non-default visibility");
2289 switch (GV->getVisibility()) {
2292 case GlobalValue::DefaultVisibility:
2293 if (GV->hasDLLExportStorageClass())
2294 VisibilityAttr = MAI->getExportedVisibilityAttr();
2296 case GlobalValue::HiddenVisibility:
2297 VisibilityAttr = MAI->getHiddenVisibilityAttr();
2299 case GlobalValue::ProtectedVisibility:
2300 VisibilityAttr = MAI->getProtectedVisibilityAttr();
2310 OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,
2314void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
2316 auto *FnDescSec =
static_cast<MCSectionXCOFF *
>(
2317 getObjFileLowering().getSectionForFunctionDescriptor(&MF.
getFunction(),
2319 FnDescSec->setAlignment(
Align(Subtarget->isPPC64() ? 8 : 4));
2321 CurrentFnDescSym = FnDescSec->getQualNameSymbol();
2326uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
2330 const PPCSubtarget &Subtarget = MF->
getSubtarget<PPCSubtarget>();
2331 if (Subtarget.
isAIXABI() && Subtarget.hasAltivec() &&
2332 TM.getAIXExtendedAltivecABI()) {
2334 for (
unsigned Reg = PPC::V20;
Reg <= PPC::V31; ++
Reg)
2335 if (
MRI.isPhysRegModified(
Reg))
2337 return PPC::V31 -
Reg + 1;
2342void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
2344 if (!TM.getXCOFFTracebackTable())
2347 emitTracebackTable();
2355 (getNumberOfVRSaved() > 0)) {
2357 OutStreamer->switchSection(getObjFileLowering().getCompactUnwindSection());
2360 OutStreamer->emitLabel(EHInfoLabel);
2363 OutStreamer->emitInt32(0);
2365 const DataLayout &
DL = MMI->getModule()->getDataLayout();
2368 OutStreamer->emitValueToAlignment(
Align(PointerSize));
2370 OutStreamer->emitIntValue(0, PointerSize);
2371 OutStreamer->emitIntValue(0, PointerSize);
2372 OutStreamer->switchSection(MF->
getSection());
2376void PPCAIXAsmPrinter::emitTracebackTable() {
2380 OutStreamer->emitLabel(FuncEnd);
2382 OutStreamer->AddComment(
"Traceback table begin");
2384 OutStreamer->emitIntValueInHexWithPadding(0, 4 );
2386 SmallString<128> CommentString;
2387 raw_svector_ostream CommentOS(CommentString);
2389 auto EmitComment = [&]() {
2390 OutStreamer->AddComment(CommentOS.str());
2391 CommentString.
clear();
2394 auto EmitCommentAndValue = [&](uint64_t
Value,
int Size) {
2396 OutStreamer->emitIntValueInHexWithPadding(
Value,
Size);
2400 CommentOS <<
"Version = " <<
Version;
2401 EmitCommentAndValue(
Version, 1);
2411 CommentOS <<
"Language = "
2413 EmitCommentAndValue(LanguageIdentifier, 1);
2416 uint32_t FirstHalfOfMandatoryField = 0;
2423 const PPCFunctionInfo *FI = MF->
getInfo<PPCFunctionInfo>();
2427 for (
unsigned Reg = PPC::F0;
Reg <= PPC::F31; ++
Reg) {
2428 if (
MRI.isPhysRegUsed(
Reg,
true)) {
2434#define GENBOOLCOMMENT(Prefix, V, Field) \
2435 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
2438#define GENVALUECOMMENT(PrefixAndName, V, Field) \
2439 CommentOS << (PrefixAndName) << " = " \
2440 << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
2441 (TracebackTable::Field##Shift))
2444 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);
2447 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasTraceBackTableOffset);
2448 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsInternalProcedure);
2451 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasControlledStorage);
2455 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsFloatingPointPresent);
2458 IsFloatingPointOperationLogOrAbortEnabled);
2461 OutStreamer->emitIntValueInHexWithPadding(
2462 (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2469 if (FrameReg == (Subtarget->isPPC64() ? PPC::X31 : PPC::R31))
2472 const SmallVectorImpl<Register> &MustSaveCRs = FI->
getMustSaveCRs();
2473 if (!MustSaveCRs.
empty())
2479 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsInterruptHandler);
2480 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);
2484 OnConditionDirective);
2488 OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),
2492 uint32_t SecondHalfOfMandatoryField = 0;
2498 uint32_t FPRSaved = 0;
2499 for (
unsigned Reg = PPC::F14;
Reg <= PPC::F31; ++
Reg) {
2500 if (
MRI.isPhysRegModified(
Reg)) {
2501 FPRSaved = PPC::F31 -
Reg + 1;
2507 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, IsBackChainStored);
2509 GENVALUECOMMENT(
", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
2511 OutStreamer->emitIntValueInHexWithPadding(
2512 (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
2518 bool HasVectorInst =
false;
2519 for (
unsigned Reg = PPC::V0;
Reg <= PPC::V31; ++
Reg)
2520 if (
MRI.isPhysRegUsed(
Reg,
true)) {
2522 HasVectorInst =
true;
2529 uint16_t NumOfVRSaved = getNumberOfVRSaved();
2530 bool ShouldEmitEHBlock =
2533 if (ShouldEmitEHBlock)
2536 uint32_t GPRSaved = 0;
2539 unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13;
2540 unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31;
2542 for (
unsigned Reg = GPRBegin;
Reg <= GPREnd; ++
Reg) {
2543 if (
MRI.isPhysRegModified(
Reg)) {
2544 GPRSaved = GPREnd -
Reg + 1;
2552 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, HasExtensionTable);
2554 GENVALUECOMMENT(
", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
2556 OutStreamer->emitIntValueInHexWithPadding(
2557 (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
2561 SecondHalfOfMandatoryField |=
2565 NumberOfFixedParms);
2567 OutStreamer->emitIntValueInHexWithPadding(
2568 (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2576 SecondHalfOfMandatoryField |=
2581 NumberOfFloatingPointParms);
2582 GENBOOLCOMMENT(
", ", SecondHalfOfMandatoryField, HasParmsOnStack);
2584 OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
2590 if (NumberOfFixedParms || NumberOfFPParms) {
2593 Expected<SmallString<32>> ParmsType =
2596 ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
2603 CommentOS <<
"Parameter type = " << ParmsType.
get();
2606 OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
2607 sizeof(ParmsTypeValue));
2610 OutStreamer->AddComment(
"Function size");
2612 MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
2614 OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
2626 int16_t NameLength =
Name.size();
2627 CommentOS <<
"Function name len = "
2628 <<
static_cast<unsigned int>(NameLength);
2629 EmitCommentAndValue(NameLength, 2);
2630 OutStreamer->AddComment(
"Function Name");
2631 OutStreamer->emitBytes(Name);
2636 OutStreamer->AddComment(
"AllocaUsed");
2637 OutStreamer->emitIntValueInHex(AllocReg,
sizeof(AllocReg));
2641 uint16_t VRData = 0;
2670 OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
2675 OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
2679 Expected<SmallString<32>> VecParmsType =
2683 CommentOS <<
"Vector Parameter type = " << VecParmsType.
get();
2686 OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
2687 sizeof(VecParmTypeValue));
2689 CommentOS <<
"Padding";
2690 EmitCommentAndValue(0, 2);
2693 uint8_t ExtensionTableFlag = 0;
2695 if (ShouldEmitEHBlock)
2696 ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
2699 ExtensionTableFlag |= ExtendedTBTableFlag::TB_SSP_CANARY;
2701 CommentOS <<
"ExtensionTableFlag = "
2703 EmitCommentAndValue(ExtensionTableFlag,
sizeof(ExtensionTableFlag));
2706 if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
2707 auto &Ctx = OutStreamer->getContext();
2710 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym, TOCType_EHBlock);
2711 const MCSymbol *TOCBaseSym =
static_cast<const MCSectionXCOFF *
>(
2712 getObjFileLowering().getTOCBaseSection())
2713 ->getQualNameSymbol();
2718 const DataLayout &
DL = getDataLayout();
2719 OutStreamer->emitValueToAlignment(
Align(4));
2720 OutStreamer->AddComment(
"EHInfo Table");
2721 OutStreamer->emitValue(Exp,
DL.getPointerSize());
2723#undef GENBOOLCOMMENT
2724#undef GENVALUECOMMENT
2733 .
Case(
"llvm.used",
true)
2735 .
Case(
"llvm.compiler.used",
true)
2741 .
Cases({
"llvm.global_ctors",
"llvm.global_dtors"},
true)
2745uint64_t PPCAIXAsmPrinter::getAliasOffset(
const Constant *
C) {
2747 return getAliasOffset(GA->getAliasee());
2758 return RHS->getValue();
2768 "GlobalVariables with an alignment requirement stricter than TOC entry "
2769 "size not supported by the toc data transformation.");
2772 assert(GVType->
isSized() &&
"A GlobalVariable's size must be known to be "
2773 "supported by the toc data transformation.");
2777 "A GlobalVariable with size larger than a TOC entry is not currently "
2778 "supported by the toc data transformation.");
2781 "currently supported by the toc data transformation.");
2784void PPCAIXAsmPrinter::emitGlobalVariable(
const GlobalVariable *GV) {
2802 emitGlobalVariableHelper(GV);
2805void PPCAIXAsmPrinter::emitGlobalVariableHelper(
const GlobalVariable *GV) {
2807 "Unhandled intrinsic global variable.");
2812 auto *GVSym =
static_cast<MCSymbolXCOFF *
>(getSymbol(GV));
2815 emitLinkage(GV, GVSym);
2819 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
2823 "not supported yet.");
2830 OutStreamer->getCommentOS() <<
'\n';
2834 auto *Csect =
static_cast<MCSectionXCOFF *
>(
2835 getObjFileLowering().SectionForGlobal(GV, GVKind, TM));
2838 OutStreamer->switchSection(Csect);
2840 if (GV->
hasMetadata(LLVMContext::MD_implicit_ref)) {
2841 emitRefMetadata(GV);
2851 GVSym->setStorageClass(
2855 OutStreamer->emitZeros(
Size);
2858 "BSS local toc-data already handled and TLS variables "
2859 "incompatible with XMC_TD");
2860 OutStreamer->emitXCOFFLocalCommonSymbol(
2861 OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()),
Size,
2864 OutStreamer->emitCommonSymbol(GVSym,
Size, Alignment);
2872 emitLinkage(GV, EmittedInitSym);
2873 for (
const GlobalAlias *GA : GOAliasMap[GV])
2874 emitLinkage(GA, getSymbol(GA));
2876 emitAlignment(getGVAlignment(GV,
DL), GV);
2880 if (!TM.getDataSections() || GV->hasSection()) {
2882 OutStreamer->emitLabel(EmittedInitSym);
2886 if (!GOAliasMap[GV].
size()) {
2887 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer());
2893 AliasMapTy AliasList;
2894 for (
const GlobalAlias *GA : GOAliasMap[GV])
2895 AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);
2898 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer(),
2902void PPCAIXAsmPrinter::emitFunctionDescriptor() {
2903 const DataLayout &
DL = getDataLayout();
2904 const unsigned PointerSize =
DL.getPointerSizeInBits() == 64 ? 8 : 4;
2908 OutStreamer->switchSection(
2909 static_cast<MCSymbolXCOFF *
>(CurrentFnDescSym)->getRepresentedCsect());
2912 for (
const GlobalAlias *Alias : GOAliasMap[&MF->
getFunction()])
2913 OutStreamer->emitLabel(getSymbol(Alias));
2919 const MCSymbol *TOCBaseSym =
static_cast<const MCSectionXCOFF *
>(
2920 getObjFileLowering().getTOCBaseSection())
2921 ->getQualNameSymbol();
2925 OutStreamer->emitIntValue(0, PointerSize);
2927 OutStreamer->switchSection(Current.first, Current.second);
2930void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2934 PPCAsmPrinter::emitFunctionEntryLabel();
2939 for (
const GlobalAlias *Alias : GOAliasMap[
F])
2940 OutStreamer->emitLabel(
2941 getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM));
2943 if (
F->hasMetadata(LLVMContext::MD_implicit_ref)) {
2948void PPCAIXAsmPrinter::emitPGORefs(
Module &M) {
2949 if (!OutContext.hasXCOFFSection(
2960 bool HasNonZeroLengthPrfCntsSection =
false;
2961 const DataLayout &
DL =
M.getDataLayout();
2962 for (GlobalVariable &GV :
M.globals())
2963 if (GV.hasSection() && GV.getSection() ==
"__llvm_prf_cnts" &&
2964 GV.getGlobalSize(
DL) > 0) {
2965 HasNonZeroLengthPrfCntsSection =
true;
2969 if (HasNonZeroLengthPrfCntsSection) {
2970 MCSection *CntsSection = OutContext.getXCOFFSection(
2975 OutStreamer->switchSection(CntsSection);
2976 if (OutContext.hasXCOFFSection(
2979 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_data[RW]");
2980 OutStreamer->emitXCOFFRefDirective(S);
2982 if (OutContext.hasXCOFFSection(
2985 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_names[RO]");
2986 OutStreamer->emitXCOFFRefDirective(S);
2988 if (OutContext.hasXCOFFSection(
2991 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_vnds[RW]");
2992 OutStreamer->emitXCOFFRefDirective(S);
2997void PPCAIXAsmPrinter::emitGCOVRefs() {
2998 if (!OutContext.hasXCOFFSection(
2999 "__llvm_gcov_ctr_section",
3003 MCSection *CtrSection = OutContext.getXCOFFSection(
3008 OutStreamer->switchSection(CtrSection);
3011 if (OutContext.hasXCOFFSection(
3014 const char *SymbolStr = TM.Options.XCOFFReadOnlyPointers
3015 ?
"__llvm_covinit[RO]"
3016 :
"__llvm_covinit[RW]";
3017 MCSymbol *S = OutContext.getOrCreateSymbol(SymbolStr);
3018 OutStreamer->emitXCOFFRefDirective(S);
3022void PPCAIXAsmPrinter::emitEndOfAsmFile(
Module &M) {
3025 if (
M.empty() && TOCDataGlobalVars.
empty())
3032 OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());
3034 PPCTargetStreamer *TS =
3035 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
3037 for (
auto &
I : TOC) {
3038 MCSectionXCOFF *TCEntry;
3045 (Subtarget->hasAIXShLibTLSModelOpt() &&
3047 SmallString<128>
Name;
3050 Name +=
static_cast<const MCSymbolXCOFF *
>(
I.first.first)
3051 ->getSymbolTableName();
3052 MCSymbol *S = OutContext.getOrCreateSymbol(Name);
3053 TCEntry =
static_cast<MCSectionXCOFF *
>(
3054 getObjFileLowering().getSectionForTOCEntry(S, TM));
3056 TCEntry =
static_cast<MCSectionXCOFF *
>(
3057 getObjFileLowering().getSectionForTOCEntry(
I.first.first, TM));
3059 OutStreamer->switchSection(TCEntry);
3061 OutStreamer->emitLabel(
I.second);
3068 for (
const auto *GV : TOCDataGlobalVars) {
3069 if (!GV->hasCommonLinkage())
3070 emitGlobalVariableHelper(GV);
3072 for (
const auto *GV : TOCDataGlobalVars) {
3073 if (GV->hasCommonLinkage())
3074 emitGlobalVariableHelper(GV);
3078bool PPCAIXAsmPrinter::doInitialization(
Module &M) {
3079 const bool Result = PPCAsmPrinter::doInitialization(M);
3082 const Triple &
Target = TM.getTargetTriple();
3089 if (FunCpuId > TargetCpuId)
3090 TargetCpuId = FunCpuId;
3096 StringRef TargetCPU = TM.getTargetCPU();
3101 PPCTargetStreamer *TS =
3102 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
3105 auto setCsectAlignment = [
this](
const GlobalObject *GO) {
3107 if (GO->isDeclarationForLinker())
3110 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);
3111 auto *Csect =
static_cast<MCSectionXCOFF *
>(
3112 getObjFileLowering().SectionForGlobal(GO, GOKind, TM));
3114 Align GOAlign = getGVAlignment(GO, GO->getDataLayout());
3115 Csect->ensureMinAlignment(GOAlign);
3121 uint64_t TLSVarAddress = 0;
3122 auto DL =
M.getDataLayout();
3123 for (
const auto &
G :
M.globals()) {
3124 if (
G.isThreadLocal() && !
G.isDeclaration()) {
3125 TLSVarAddress =
alignTo(TLSVarAddress, getGVAlignment(&
G,
DL));
3126 TLSVarsToAddressMapping[&
G] = TLSVarAddress;
3127 TLSVarAddress +=
G.getGlobalSize(
DL);
3134 for (
const auto &
G :
M.globals()) {
3141 if (FormatIndicatorAndUniqueModId.empty()) {
3143 if (UniqueModuleId !=
"")
3147 FormatIndicatorAndUniqueModId =
"clang_" + UniqueModuleId.substr(1);
3152 std::chrono::duration_cast<std::chrono::nanoseconds>(
3153 std::chrono::steady_clock::now().time_since_epoch())
3155 FormatIndicatorAndUniqueModId =
3162 emitSpecialLLVMGlobal(&
G);
3166 setCsectAlignment(&
G);
3167 std::optional<CodeModel::Model> OptionalCodeModel =
G.getCodeModel();
3168 if (OptionalCodeModel)
3170 *OptionalCodeModel);
3173 for (
const auto &
F : M)
3174 setCsectAlignment(&
F);
3177 for (
const auto &Alias :
M.aliases()) {
3178 const GlobalObject *Aliasee = Alias.getAliaseeObject();
3181 "alias without a base object is not yet supported on AIX");
3185 "\n\tAlias attribute for " +
3186 Alias.getName() +
" is invalid because " +
3187 Aliasee->
getName() +
" is common.",
3191 const GlobalVariable *GVar =
3194 std::optional<CodeModel::Model> OptionalCodeModel = GVar->
getCodeModel();
3195 if (OptionalCodeModel)
3197 *OptionalCodeModel);
3200 GOAliasMap[Aliasee].push_back(&Alias);
3206void PPCAIXAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
3207 switch (
MI->getOpcode()) {
3214 if (
MI->getNumOperands() < 5)
3216 const MachineOperand &LangMO =
MI->getOperand(3);
3217 const MachineOperand &ReasonMO =
MI->getOperand(4);
3220 MCSymbol *TempSym = OutContext.createNamedTempSymbol();
3221 OutStreamer->emitLabel(TempSym);
3222 OutStreamer->emitXCOFFExceptDirective(
3223 CurrentFnSym, TempSym, LangMO.
getImm(), ReasonMO.
getImm(),
3224 Subtarget->isPPC64() ?
MI->getMF()->getInstructionCount() * 8
3225 :
MI->getMF()->getInstructionCount() * 4,
3229 case PPC::GETtlsMOD32AIX:
3230 case PPC::GETtlsMOD64AIX:
3231 case PPC::GETtlsTpointer32AIX:
3232 case PPC::GETtlsADDR64AIX:
3233 case PPC::GETtlsADDR32AIX: {
3238 ExtSymSDNodeSymbols.
insert(TlsGetAddr);
3245 const MachineOperand &MO =
MI->getOperand(0);
3247 auto *S =
static_cast<MCSymbolXCOFF *
>(
3249 ExtSymSDNodeSymbols.
insert(S);
3255 case PPC::BL8_NOP_TLS:
3262 case PPC::TAILBCTR8:
3263 if (
MI->getOperand(0).isSymbol())
3276 MCInstBuilder(PPC::ORI).addReg(PPC::R0).addReg(PPC::R0).addImm(0));
3279 return PPCAsmPrinter::emitInstruction(
MI);
3282bool PPCAIXAsmPrinter::doFinalization(
Module &M) {
3288 auto *Sec = OutContext.getObjectFileInfo()->getTextSection();
3289 OutStreamer->switchSectionNoPrint(Sec);
3290 MCSymbol *Sym = Sec->getEndSymbol(OutContext);
3291 OutStreamer->emitLabel(Sym);
3294 for (MCSymbol *Sym : ExtSymSDNodeSymbols)
3295 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Extern);
3296 return PPCAsmPrinter::doFinalization(M);
3307 return 20 + (
P - 20) * 16;
3310 return 1004 + (
P - 81);
3313 return 2047 + (
P - 1124) * 33878;
3315 return 2147482625u + (
P - 64512);
3334 std::string PrioritySuffix;
3337 return PrioritySuffix;
3340void PPCAIXAsmPrinter::emitXXStructorList(
const DataLayout &
DL,
3341 const Constant *
List,
bool IsCtor) {
3343 preprocessXXStructorList(
DL,
List, Structors);
3344 if (Structors.
empty())
3348 for (Structor &S : Structors) {
3350 S.Func =
CE->getOperand(0);
3354 (IsCtor ? llvm::Twine(
"__sinit") : llvm::Twine(
"__sterm")) +
3356 llvm::Twine(
"_", FormatIndicatorAndUniqueModId) +
3362void PPCAIXAsmPrinter::emitTTypeReference(
const GlobalValue *GV,
3363 unsigned Encoding) {
3365 TOCEntryType GlobalType = TOCType_GlobalInternal;
3370 GlobalType = TOCType_GlobalExternal;
3371 MCSymbol *TypeInfoSym = TM.getSymbol(GV);
3372 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym, GlobalType);
3373 const MCSymbol *TOCBaseSym =
static_cast<const MCSectionXCOFF *
>(
3374 getObjFileLowering().getTOCBaseSection())
3375 ->getQualNameSymbol();
3376 auto &Ctx = OutStreamer->getContext();
3380 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
3382 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
3385void PPCAIXAsmPrinter::emitRefMetadata(
const GlobalObject *GO) {
3387 GO->
getMetadata(LLVMContext::MD_implicit_ref, MDs);
3388 assert(MDs.
size() &&
"Expected asscoiated metadata nodes");
3390 for (
const MDNode *MD : MDs) {
3393 MCSymbol *Referenced = TM.getSymbol(GV);
3394 OutStreamer->emitXCOFFRefDirective(Referenced);
3402 std::unique_ptr<MCStreamer> &&Streamer) {
3404 return new PPCAIXAsmPrinter(tm, std::move(Streamer));
3406 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
3409void PPCAIXAsmPrinter::emitModuleCommandLines(
Module &M) {
3410 const NamedMDNode *NMD =
M.getNamedMetadata(
"llvm.commandline");
3415 raw_string_ostream RSOS(S);
3418 assert(
N->getNumOperands() == 1 &&
3419 "llvm.commandline metadata entry can have only one operand");
3423 RSOS <<
"@(#)opt " << MDS->
getString() <<
"\n";
3426 OutStreamer->emitXCOFFCInfoSym(
".GCC.command.line", RSOS.str());
3429char PPCAIXAsmPrinter::ID = 0;
3432 "AIX PPC Assembly Printer",
false,
false)
3436LLVMInitializePowerPCAsmPrinter() {
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static AMDGPUMCExpr::Specifier getSpecifier(unsigned MOFlags)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_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)
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
Promote Memory to Register
static void collectTOCStats(PPCAsmPrinter::TOCEntryType Type)
static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV)
static bool isSpecialLLVMGlobalArrayToSkip(const GlobalVariable *GV)
#define GENBOOLCOMMENT(Prefix, V, Field)
static MCSymbol * getMCSymbolForTOCPseudoMO(const MachineOperand &MO, AsmPrinter &AP)
Map a machine operand for a TOC pseudo-machine instruction to its corresponding MCSymbol.
static void setOptionalCodeModel(MCSymbolXCOFF *XSym, CodeModel::Model CM)
static AsmPrinter * createPPCAsmPrinterPass(TargetMachine &tm, std::unique_ptr< MCStreamer > &&Streamer)
static PPCAsmPrinter::TOCEntryType getTOCEntryTypeForMO(const MachineOperand &MO)
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
static std::string convertToSinitPriority(int Priority)
static MCSymbol * createMCSymbolForTlsGetAddr(MCContext &Ctx, unsigned MIOpc)
This helper function creates the TlsGetAddr/TlsGetMod MCSymbol for AIX.
#define GENVALUECOMMENT(PrefixAndName, V, Field)
static unsigned mapToSinitPriority(int P)
static void tocDataChecks(unsigned PointerSize, const GlobalVariable *GV)
static cl::opt< bool > EnableSSPCanaryBitInTB("aix-ssp-tb-bit", cl::init(false), cl::desc("Enable Passing SSP Canary info in Trackback on AIX"), cl::Hidden)
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Provides a library for accessing information about this process and other processes on the operating ...
static SDValue lowerConstant(SDValue Op, SelectionDAG &DAG, const RISCVSubtarget &Subtarget)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
This file implements a set that has insertion order iteration characteristics.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This class is intended to be used as a driving class for all asm writers.
MCSymbol * getSymbol(const GlobalValue *GV) const
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
virtual void SetupMachineFunction(MachineFunction &MF)
This should be called when a new MachineFunction is being processed from runOnMachineFunction.
virtual void emitStartOfAsmFile(Module &)
This virtual method can be overridden by targets that want to emit something at the start of their fi...
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.
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
LLVM_ABI unsigned getPointerSize(unsigned AS=0) const
The pointer representation size in bytes, rounded up to a whole number of bytes.
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
StringRef getSection() const
Get the custom section of this global if it has one.
bool hasMetadata() const
Return true if this value has any metadata attached to it.
bool hasSection() const
Check if this global has a custom object file section.
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
LinkageTypes getLinkage() const
bool hasPrivateLinkage() const
ThreadLocalMode getThreadLocalMode() const
bool isDeclarationForLinker() const
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
bool hasCommonLinkage() const
bool hasAppendingLinkage() const
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ ExternalLinkage
Externally visible function.
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ ExternalWeakLinkage
ExternalWeak linkage description.
Type * getValueType() const
bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists.
bool hasInitializer() const
Definitions have initializers, declarations don't.
std::optional< CodeModel::Model > getCodeModel() const
Get the custom code model of this global if it has one.
MaybeAlign getAlign() const
Returns the alignment of the given variable.
LLVM_ABI uint64_t getGlobalSize(const DataLayout &DL) const
Get the size of this global variable in bytes.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Opcode getOpcode() const
Get the kind of this binary expression.
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
size_t getFixedSize() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
static MCOperand createExpr(const MCExpr *Val)
MCRegister getReg() const
Returns the register number.
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
void setPerSymbolCodeModel(MCSymbolXCOFF::CodeModel Model)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
LLVM_ABI StringRef getString() const
MachineInstrBundleIterator< const MachineInstr > const_iterator
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
MCSection * getSection() const
Returns the Section this function belongs to.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
const BlockAddress * getBlockAddress() const
unsigned getTargetFlags() const
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
bool isBlockAddress() const
isBlockAddress - Tests if this is a MO_BlockAddress operand.
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
int64_t getOffset() const
Return the offset from the symbol in this operand.
iterator find(const KeyT &Key)
LLVM_ABI MDNode * getOperand(unsigned i) const
LLVM_ABI unsigned getNumOperands() const
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
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)
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Return the number of bytes of code the specified instruction may be.
Register getFrameRegister(const MachineFunction &MF) const override
bool is32BitELFABI() const
const PPCFrameLowering * getFrameLowering() const override
bool isUsingPCRelativeCalls() const
const PPCInstrInfo * getInstrInfo() const override
CodeModel::Model getCodeModel(const TargetMachine &TM, const GlobalValue *GV) const
Calculates the effective code model for argument GV.
const PPCRegisterInfo * getRegisterInfo() const override
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
virtual void emitAbiVersion(int AbiVersion)
virtual void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset)
virtual void emitTCEntry(const MCSymbol &S, PPCMCExpr::Specifier Kind)
virtual void emitMachine(StringRef CPU)
bool isThreadBSSLocal() const
static SectionKind getText()
static SectionKind getData()
bool isThreadLocal() const
bool isGlobalWriteableData() const
bool insert(const value_type &X)
Insert a new element into the SetVector.
void push_back(const T &Elt)
LLVM_ABI void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
LLVM_ABI void recordStackMap(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
StringRef - Represent a constant reference to a string, i.e.
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(std::initializer_list< StringLiteral > CaseStrings, T Value)
static bool ShouldSetSSPCanaryBitInTB(const MachineFunction *MF)
static MCSymbol * getEHInfoTableSymbol(const MachineFunction *MF)
static XCOFF::StorageClass getStorageClassForGlobal(const GlobalValue *GV)
static bool ShouldEmitEHBlock(const MachineFunction *MF)
Primary interface to the complete machine description for the target machine.
const Triple & getTargetTriple() const
CodeModel::Model getCodeModel() const
Returns the code model.
bool isOSAIX() const
Tests whether the OS is AIX.
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_ABI void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
LLVM_ABI 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.
static LLVM_ABI Pid getProcessId()
Get the process's identifier.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ 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...
LLVM_ABI StringRef getNormalizedPPCTargetCPU(const Triple &T, StringRef CPUName="")
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
const char * stripRegisterPrefix(const char *RegName)
stripRegisterPrefix - This method strips the character prefix from a register name so that only the n...
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
static bool isVRRegister(MCRegister Reg)
static bool isVFRegister(MCRegister Reg)
@ CE
Windows NT (Windows on ARM)
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
LLVM_ABI SmallString< 32 > getExtendedTBTableFlagString(uint8_t Flag)
LLVM_ABI XCOFF::CFileCpuId getCpuID(StringRef CPU)
LLVM_ABI Expected< SmallString< 32 > > parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum, unsigned VectorParmsNum)
LLVM_ABI Expected< SmallString< 32 > > parseParmsType(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum)
LLVM_ABI 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.
LLVM_ABI StringRef getTCPUString(XCOFF::CFileCpuId TCPU)
LLVM_ABI 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.
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.
FunctionAddr VTableAddr Value
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool LowerPPCMachineOperandToMCOperand(const MachineOperand &MO, MCOperand &OutMO, AsmPrinter &AP)
scope_exit(Callable) -> scope_exit< Callable >
Target & getThePPC32Target()
std::string utostr(uint64_t X, bool isNeg=false)
auto dyn_cast_or_null(const Y &Val)
FunctionAddr VTableAddr uintptr_t uintptr_t Version
LLVM_ABI std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...
void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)
format_hex_no_prefix - Output N as a fixed width hexadecimal.
Target & getThePPC64Target()
LLVM_ABI 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.
DWARFExpression::Operation Op
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
constexpr int32_t SignExtend32(uint32_t X)
Sign-extend the number in the bottom B bits of X to a 32-bit integer.
Target & getThePPC32LETarget()
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
std::pair< MCSection *, uint32_t > MCSectionSubPair
std::string itostr(int64_t X)
@ MCSA_Extern
.extern (XCOFF)
@ MCSA_Invalid
Not a valid directive.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Implement std::hash so that hash_code can be used in STL containers.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
static bool isEqual(const TOCKey &A, const TOCKey &B)
std::pair< const MCSymbol *, PPCMCExpr::Specifier > TOCKey
static unsigned getHashValue(const TOCKey &PairVal)
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