89#define DEBUG_TYPE "asmprinter"
91STATISTIC(NumTOCEntries,
"Number of Total TOC Entries Emitted.");
92STATISTIC(NumTOCConstPool,
"Number of Constant Pool TOC Entries.");
94 "Number of Internal Linkage Global TOC Entries.");
96 "Number of External Linkage Global TOC Entries.");
97STATISTIC(NumTOCJumpTable,
"Number of Jump Table TOC Entries.");
98STATISTIC(NumTOCThreadLocal,
"Number of Thread Local TOC Entries.");
99STATISTIC(NumTOCBlockAddress,
"Number of Block Address TOC Entries.");
100STATISTIC(NumTOCEHBlock,
"Number of EH Block TOC Entries.");
107 "ifunc-local-if-proven",
cl::init(
false),
108 cl::desc(
"During ifunc lowering, the compiler assumes the resolver returns "
109 "dso-local functions and bails out if non-local functions are "
110 "detected; this flag flips the assumption: resolver returns "
111 "preemptible functions unless the compiler can prove all paths "
112 "return local functions."),
126 using TOCKey = std::pair<const MCSymbol *, PPCMCExpr::Specifier>;
145 Tag_GNU_Power_ABI_FP = 4,
146 Tag_GNU_Power_ABI_Vector = 8,
147 Tag_GNU_Power_ABI_Struct_Return = 12,
150 Val_GNU_Power_ABI_NoFloat = 0b00,
151 Val_GNU_Power_ABI_HardFloat_DP = 0b01,
152 Val_GNU_Power_ABI_SoftFloat_DP = 0b10,
153 Val_GNU_Power_ABI_HardFloat_SP = 0b11,
155 Val_GNU_Power_ABI_LDBL_IBM128 = 0b0100,
156 Val_GNU_Power_ABI_LDBL_64 = 0b1000,
157 Val_GNU_Power_ABI_LDBL_IEEE128 = 0b1100,
169 MapVector<std::pair<const MCSymbol *, PPCMCExpr::Specifier>,
MCSymbol *> TOC;
170 const PPCSubtarget *Subtarget =
nullptr;
175 MapVector<const GlobalValue *, uint64_t> TLSVarsToAddressMapping;
178 explicit PPCAsmPrinter(TargetMachine &TM,
179 std::unique_ptr<MCStreamer> Streamer,
char &
ID)
180 : AsmPrinter(TM, std::
move(Streamer),
ID) {}
182 StringRef getPassName()
const override {
return "PowerPC Assembly Printer"; }
185 TOCType_ConstantPool,
186 TOCType_GlobalExternal,
187 TOCType_GlobalInternal,
190 TOCType_BlockAddress,
194 MCSymbol *lookUpOrCreateTOCEntry(
const MCSymbol *Sym, TOCEntryType
Type,
197 bool doInitialization(
Module &M)
override {
203 const MCExpr *symbolWithSpecifier(
const MCSymbol *S,
210 void printOperand(
const MachineInstr *
MI,
unsigned OpNo, raw_ostream &O);
212 void PrintSymbolOperand(
const MachineOperand &MO, raw_ostream &O)
override;
213 bool PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
214 const char *ExtraCode, raw_ostream &O)
override;
215 bool PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNo,
216 const char *ExtraCode, raw_ostream &O)
override;
218 void LowerSTACKMAP(StackMaps &
SM,
const MachineInstr &
MI);
219 void LowerPATCHPOINT(StackMaps &
SM,
const MachineInstr &
MI);
221 void EmitAIXTlsCallHelper(
const MachineInstr *
MI);
222 const MCExpr *getAdjustedFasterLocalExpr(
const MachineOperand &MO,
224 bool runOnMachineFunction(MachineFunction &MF)
override {
233class PPCLinuxAsmPrinter :
public PPCAsmPrinter {
237 explicit PPCLinuxAsmPrinter(TargetMachine &TM,
238 std::unique_ptr<MCStreamer> Streamer)
239 : PPCAsmPrinter(TM, std::
move(Streamer), ID) {}
241 StringRef getPassName()
const override {
242 return "Linux PPC Assembly Printer";
245 void emitGNUAttributes(
Module &M);
247 void emitStartOfAsmFile(
Module &M)
override;
248 void emitEndOfAsmFile(
Module &)
override;
250 void emitFunctionEntryLabel()
override;
252 void emitFunctionBodyStart()
override;
253 void emitFunctionBodyEnd()
override;
257class PPCAIXAsmPrinter :
public PPCAsmPrinter {
261 SmallSetVector<MCSymbol *, 8> ExtSymSDNodeSymbols;
265 std::string FormatIndicatorAndUniqueModId;
269 DenseMap<const GlobalObject *, SmallVector<const GlobalAlias *, 1>>
272 uint16_t getNumberOfVRSaved();
273 void emitTracebackTable();
277 void emitGlobalVariableHelper(
const GlobalVariable *);
280 uint64_t getAliasOffset(
const Constant *
C);
285 PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
286 : PPCAsmPrinter(TM, std::
move(Streamer), ID) {
287 if (MAI->isLittleEndian())
289 "cannot create AIX PPC Assembly Printer for a little-endian target");
292 StringRef getPassName()
const override {
return "AIX PPC Assembly Printer"; }
294 bool doInitialization(
Module &M)
override;
296 void emitXXStructorList(
const DataLayout &
DL,
const Constant *
List,
297 bool IsCtor)
override;
299 void SetupMachineFunction(MachineFunction &MF)
override;
301 void emitGlobalVariable(
const GlobalVariable *GV)
override;
303 void emitFunctionDescriptor()
override;
305 void emitFunctionEntryLabel()
override;
307 void emitFunctionBodyEnd()
override;
309 void emitPGORefs(
Module &M);
313 void emitEndOfAsmFile(
Module &)
override;
315 void emitLinkage(
const GlobalValue *GV, MCSymbol *GVSym)
const override;
319 bool doFinalization(
Module &M)
override;
321 void emitTTypeReference(
const GlobalValue *GV,
unsigned Encoding)
override;
323 void emitModuleCommandLines(
Module &M)
override;
325 void emitRefMetadata(
const GlobalObject *);
327 void emitGlobalIFunc(
Module &M,
const GlobalIFunc &GI)
override;
336 getSymbol(GV)->
print(O, MAI);
340void PPCAsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNo,
342 const DataLayout &
DL = getDataLayout();
343 const MachineOperand &MO =
MI->getOperand(OpNo);
363 O <<
DL.getPrivateGlobalPrefix() <<
"CPI" << getFunctionNumber() <<
'_'
370 PrintSymbolOperand(MO, O);
375 O <<
"<unknown operand type: " << (unsigned)MO.
getType() <<
">";
382bool PPCAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
383 const char *ExtraCode, raw_ostream &O) {
385 if (ExtraCode && ExtraCode[0]) {
386 if (ExtraCode[1] != 0)
return true;
388 switch (ExtraCode[0]) {
394 if (!
MI->getOperand(OpNo).isReg() ||
395 OpNo+1 ==
MI->getNumOperands() ||
396 !
MI->getOperand(OpNo+1).isReg())
403 if (
MI->getOperand(OpNo).isImm())
407 if(!
MI->getOperand(OpNo).isReg())
413 Reg = PPC::VSX32 + (
Reg - PPC::V0);
415 Reg = PPC::VSX32 + (
Reg - PPC::VF0);
431bool PPCAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNo,
432 const char *ExtraCode,
434 if (ExtraCode && ExtraCode[0]) {
435 if (ExtraCode[1] != 0)
return true;
437 switch (ExtraCode[0]) {
438 default:
return true;
440 O << getDataLayout().getPointerSize() <<
"(";
451 if (
MI->getOperand(OpNo).isImm())
462 assert(
MI->getOperand(OpNo).isReg());
467 assert(
MI->getOperand(OpNo).isReg());
477 case PPCAsmPrinter::TOCType_ConstantPool:
480 case PPCAsmPrinter::TOCType_GlobalInternal:
481 ++NumTOCGlobalInternal;
483 case PPCAsmPrinter::TOCType_GlobalExternal:
484 ++NumTOCGlobalExternal;
486 case PPCAsmPrinter::TOCType_JumpTable:
489 case PPCAsmPrinter::TOCType_ThreadLocal:
492 case PPCAsmPrinter::TOCType_BlockAddress:
493 ++NumTOCBlockAddress;
495 case PPCAsmPrinter::TOCType_EHBlock:
512 assert(GV &&
"expected global for MO_GlobalAddress");
533MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(
const MCSymbol *Sym,
537 auto [It,
Inserted] =
TOC.try_emplace({Sym, Spec});
543 TOCEntry = createTempSymbol(
"C");
547void PPCAsmPrinter::LowerSTACKMAP(StackMaps &
SM,
const MachineInstr &
MI) {
548 unsigned NumNOPBytes =
MI.getOperand(1).getImm();
550 auto &Ctx = OutStreamer->getContext();
551 MCSymbol *MILabel = Ctx.createTempSymbol();
552 OutStreamer->emitLabel(MILabel);
554 SM.recordStackMap(*MILabel,
MI);
555 assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
558 const MachineBasicBlock &
MBB = *
MI.getParent();
561 while (NumNOPBytes > 0) {
562 if (MII ==
MBB.
end() || MII->isCall() ||
563 MII->getOpcode() == PPC::DBG_VALUE ||
564 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
565 MII->getOpcode() == TargetOpcode::STACKMAP)
572 for (
unsigned i = 0; i < NumNOPBytes; i += 4)
573 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
578void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &
SM,
const MachineInstr &
MI) {
579 auto &Ctx = OutStreamer->getContext();
580 MCSymbol *MILabel = Ctx.createTempSymbol();
581 OutStreamer->emitLabel(MILabel);
583 SM.recordPatchPoint(*MILabel,
MI);
584 PatchPointOpers Opers(&
MI);
586 unsigned EncodedBytes = 0;
587 const MachineOperand &CalleeMO = Opers.getCallTarget();
589 if (CalleeMO.
isImm()) {
590 int64_t CallTarget = CalleeMO.
getImm();
592 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
593 "High 16 bits of call target should be zero.");
594 Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
597 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8)
599 .addImm((CallTarget >> 32) & 0xFFFF));
602 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC)
605 .addImm(32).addImm(16));
608 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8)
611 .addImm((CallTarget >> 16) & 0xFFFF));
614 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8)
617 .addImm(CallTarget & 0xFFFF));
622 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD)
624 .addImm(TOCSaveOffset)
634 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
637 .addReg(ScratchReg));
640 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
643 .addReg(ScratchReg));
647 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8)
648 .addReg(ScratchReg));
651 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8));
655 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
657 .addImm(TOCSaveOffset)
662 const GlobalValue *GValue = CalleeMO.
getGlobal();
663 MCSymbol *MOSymbol = getSymbol(GValue);
666 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP)
675 unsigned NumBytes = Opers.getNumPatchBytes();
676 if (NumBytes < EncodedBytes)
678 "Patchpoint can't request size less than the length of a call.");
680 assert((NumBytes - EncodedBytes) % 4 == 0 &&
681 "Invalid number of NOP bytes requested!");
682 for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
683 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
693 SymName =
".__tls_get_addr";
695 case PPC::GETtlsTpointer32AIX:
696 SymName =
".__get_tpointer";
698 case PPC::GETtlsMOD32AIX:
699 case PPC::GETtlsMOD64AIX:
700 SymName =
".__tls_get_mod";
706 ->getQualNameSymbol();
709void PPCAsmPrinter::EmitAIXTlsCallHelper(
const MachineInstr *
MI) {
711 "Only expecting to emit calls to get the thread pointer on AIX!");
715 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BLA).addExpr(TlsRef));
720void PPCAsmPrinter::emitTlsCall(
const MachineInstr *
MI,
723 unsigned Opcode = PPC::BL8_NOP_TLS;
725 assert(
MI->getNumOperands() >= 3 &&
"Expecting at least 3 operands from MI");
729 Opcode = PPC::BL8_NOTOC_TLS;
731 const Module *
M = MF->getFunction().getParent();
734 ((Subtarget->isPPC64() &&
MI->getOperand(0).getReg() == PPC::X3) ||
735 (!Subtarget->isPPC64() &&
MI->getOperand(0).getReg() == PPC::R3)) &&
736 "GETtls[ld]ADDR[32] must define GPR3");
738 ((Subtarget->isPPC64() &&
MI->getOperand(1).getReg() == PPC::X3) ||
739 (!Subtarget->isPPC64() &&
MI->getOperand(1).getReg() == PPC::R3)) &&
740 "GETtls[ld]ADDR[32] must read GPR3");
747 Register VarOffsetReg = Subtarget->isPPC64() ? PPC::X4 : PPC::R4;
749 assert((
MI->getOpcode() == PPC::GETtlsMOD32AIX ||
750 MI->getOpcode() == PPC::GETtlsMOD64AIX ||
751 (
MI->getOperand(2).isReg() &&
752 MI->getOperand(2).getReg() == VarOffsetReg)) &&
753 "GETtls[ld]ADDR[32] must read GPR4");
754 EmitAIXTlsCallHelper(
MI);
758 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(
"__tls_get_addr");
766 if (Kind ==
PPC::S_PLT && Subtarget->isSecurePlt() &&
770 const MachineOperand &MO =
MI->getOperand(2);
771 const GlobalValue *GValue = MO.
getGlobal();
772 MCSymbol *MOSymbol = getSymbol(GValue);
774 EmitToStreamer(*OutStreamer,
775 MCInstBuilder(Subtarget->isPPC64() ? Opcode
776 : (
unsigned)PPC::BL_TLS)
799static PPCAsmPrinter::TOCEntryType
804 return PPCAsmPrinter::TOCType_GlobalExternal;
806 return PPCAsmPrinter::TOCType_GlobalInternal;
809static PPCAsmPrinter::TOCEntryType
814 return PPCAsmPrinter::TOCType_ThreadLocal;
822 return PPCAsmPrinter::TOCType_ConstantPool;
824 return PPCAsmPrinter::TOCType_JumpTable;
826 return PPCAsmPrinter::TOCType_BlockAddress;
832const MCExpr *PPCAsmPrinter::symbolWithSpecifier(
const MCSymbol *S,
840void PPCAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
841 PPC_MC::verifyInstructionPredicates(
MI->getOpcode(),
842 getSubtargetInfo().getFeatureBits());
845 const bool IsPPC64 = Subtarget->isPPC64();
846 const bool IsAIX = Subtarget->
isAIXABI();
847 const bool HasAIXSmallLocalTLS = Subtarget->hasAIXSmallLocalExecTLS() ||
848 Subtarget->hasAIXSmallLocalDynamicTLS();
849 const Module *
M = MF->getFunction().getParent();
854 if (!
MI->isInlineAsm()) {
855 for (
const MachineOperand &MO:
MI->operands()) {
858 if (Subtarget->hasSPE()) {
876 auto getTOCRelocAdjustedExprForXCOFF = [
this](
const MCExpr *Expr,
877 ptrdiff_t OriginalOffset) {
884 ptrdiff_t Adjustment =
890 auto getTOCEntryLoadingExprForXCOFF =
891 [IsPPC64, getTOCRelocAdjustedExprForXCOFF,
892 this](
const MCSymbol *MOSymbol,
const MCExpr *Expr,
894 const unsigned EntryByteSize = IsPPC64 ? 8 : 4;
895 const auto TOCEntryIter =
TOC.find({MOSymbol, VK});
897 "Could not find the TOC entry for this symbol.");
898 const ptrdiff_t EntryDistanceFromTOCBase =
899 (TOCEntryIter -
TOC.begin()) * EntryByteSize;
900 constexpr int16_t PositiveTOCRange = INT16_MAX;
902 if (EntryDistanceFromTOCBase > PositiveTOCRange)
903 return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase);
915 assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!\n");
923 PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
927 dbgs() <<
"Current function uses IE access for default LD vars.\n");
954 MCFragment *OldFragment = OutStreamer->getCurrentFragment();
957 if (!OutStreamer->isObj())
959 MCFragment *NewFragment = OutStreamer->getCurrentFragment();
960 if (NewFragment != OldFragment)
962 unsigned ActualSize = NewFragment->
getFixedSize() - OldFragSize;
964 if (ActualSize != ExpectedSize &&
965 MI->getOpcode() != TargetOpcode::STACKMAP) {
966 dbgs() <<
"Size mismatch for: " << *
MI <<
"\n";
967 dbgs() <<
"Expected size: " << ExpectedSize <<
"\n";
968 dbgs() <<
"Actual size: " << ActualSize <<
"\n";
975 switch (
MI->getOpcode()) {
977 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
979 "AIX does not support patchable function entry!");
982 (void)
F.getFnAttribute(
"patchable-function-entry")
984 .getAsInteger(10, Num);
990 case TargetOpcode::DBG_VALUE:
992 case TargetOpcode::STACKMAP:
993 return LowerSTACKMAP(
SM, *
MI);
994 case TargetOpcode::PATCHPOINT:
995 return LowerPATCHPOINT(
SM, *
MI);
997 case PPC::MoveGOTtoLR: {
1005 OutContext.getOrCreateSymbol(StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1011 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));
1014 case PPC::MovePCtoLR:
1015 case PPC::MovePCtoLR8: {
1020 MCSymbol *PICBase = MF->getPICBaseSymbol();
1023 EmitToStreamer(*OutStreamer,
1024 MCInstBuilder(PPC::BCLalways)
1030 OutStreamer->emitLabel(PICBase);
1033 case PPC::UpdateGBR: {
1042 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
1044 MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
1053 const MCExpr *DeltaHi =
1057 MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));
1059 const MCExpr *DeltaLo =
1063 MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
1067 MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol(*MF);
1074 const MCOperand PICR = TmpInst.
getOperand(0);
1081 EmitToStreamer(*OutStreamer, TmpInst);
1087 EmitToStreamer(*OutStreamer, TmpInst);
1098 const MachineOperand &MO =
MI->getOperand(1);
1100 "Invalid operand for LWZtoc.");
1108 const MCExpr *
Exp = symbolWithSpecifier(MOSymbol,
PPC::S_GOT);
1110 EmitToStreamer(*OutStreamer, TmpInst);
1129 "This pseudo should only be selected for 32-bit small code model.");
1130 Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK);
1135 OutStreamer->getCommentOS() << MO <<
'\n';
1136 EmitToStreamer(*OutStreamer, TmpInst);
1143 OutContext.getOrCreateSymbol(Twine(
".LTOC")), OutContext);
1146 EmitToStreamer(*OutStreamer, TmpInst);
1150 case PPC::ADDItoc8: {
1152 "PseudoOp only valid for small code model AIX");
1158 TmpInst.
setOpcode((!IsPPC64) ? (PPC::LA) : (PPC::LA8));
1160 const MachineOperand &MO =
MI->getOperand(2);
1169 EmitToStreamer(*OutStreamer, TmpInst);
1182 const MachineOperand &MO =
MI->getOperand(1);
1184 "Invalid operand!");
1198 const MCExpr *
Exp = symbolWithSpecifier(TOCEntry, VKExpr);
1200 IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK) : Exp);
1203 if (isVerbose() && IsAIX)
1204 OutStreamer->getCommentOS() << MO <<
'\n';
1205 EmitToStreamer(*OutStreamer, TmpInst);
1208 case PPC::ADDIStocHA: {
1209 const MachineOperand &MO =
MI->getOperand(2);
1212 "Invalid operand for ADDIStocHA.");
1213 assert((IsAIX && !IsPPC64 &&
1215 "This pseudo should only be selected for 32-bit large code model on"
1235 if ( {
1247 const MCExpr *
Exp = symbolWithSpecifier(MOSymbol,
PPC::S_U);
1249 EmitToStreamer(*OutStreamer, TmpInst);
1252 case PPC::LWZtocL: {
1253 const MachineOperand &MO =
MI->getOperand(1);
1256 "Invalid operand for LWZtocL.");
1257 assert(IsAIX && !IsPPC64 &&
1259 "This pseudo should only be selected for 32-bit large code model on"
1279 const MCExpr *
Exp = symbolWithSpecifier(TOCEntry,
PPC::S_L);
1281 EmitToStreamer(*OutStreamer, TmpInst);
1284 case PPC::ADDIStocHA8: {
1294 const MachineOperand &MO =
MI->getOperand(2);
1296 "Invalid operand for ADDIStocHA8!");
1302 const bool GlobalToc =
1314 const MCExpr *
Exp = symbolWithSpecifier(MOSymbol, VK);
1323 EmitToStreamer(*OutStreamer, TmpInst);
1336 const MachineOperand &MO =
MI->getOperand(1);
1339 "Invalid operand for LDtocL!");
1343 "LDtocL used on symbol that could be accessed directly is "
1344 "invalid. Must match ADDIStocHA8."));
1355 const MCExpr *
Exp = symbolWithSpecifier(MOSymbol, VK);
1357 EmitToStreamer(*OutStreamer, TmpInst);
1361 case PPC::ADDItocL8: {
1365 unsigned Op =
MI->getOpcode();
1369 TmpInst.
setOpcode(
Op == PPC::ADDItocL8 ? (IsAIX ? PPC::LA8 : PPC::ADDI8)
1372 const MachineOperand &MO =
MI->getOperand(2);
1375 : MO.
isGlobal() &&
"Invalid operand for ADDItocL8.");
1377 "Interposable definitions must use indirect accesses.");
1386 EmitToStreamer(*OutStreamer, TmpInst);
1389 case PPC::ADDISgotTprelHA: {
1392 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1393 const MachineOperand &MO =
MI->getOperand(2);
1394 const GlobalValue *GValue = MO.
getGlobal();
1395 MCSymbol *MOSymbol = getSymbol(GValue);
1396 const MCExpr *SymGotTprel =
1398 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1399 .addReg(
MI->getOperand(0).getReg())
1400 .addReg(
MI->getOperand(1).getReg())
1401 .addExpr(SymGotTprel));
1404 case PPC::LDgotTprelL:
1405 case PPC::LDgotTprelL32: {
1410 TmpInst.
setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ);
1411 const MachineOperand &MO =
MI->getOperand(1);
1412 const GlobalValue *GValue = MO.
getGlobal();
1413 MCSymbol *MOSymbol = getSymbol(GValue);
1414 const MCExpr *
Exp = symbolWithSpecifier(
1417 EmitToStreamer(*OutStreamer, TmpInst);
1421 case PPC::PPC32PICGOT: {
1422 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1423 MCSymbol *GOTRef = OutContext.createTempSymbol();
1424 MCSymbol *NextInstr = OutContext.createTempSymbol();
1426 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL)
1430 const MCExpr *OffsExpr =
1434 OutStreamer->emitLabel(GOTRef);
1435 OutStreamer->emitValue(OffsExpr, 4);
1436 OutStreamer->emitLabel(NextInstr);
1437 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR)
1438 .addReg(
MI->getOperand(0).getReg()));
1439 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
1440 .addReg(
MI->getOperand(1).getReg())
1442 .addReg(
MI->getOperand(0).getReg()));
1443 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4)
1444 .addReg(
MI->getOperand(0).getReg())
1445 .addReg(
MI->getOperand(1).getReg())
1446 .addReg(
MI->getOperand(0).getReg()));
1449 case PPC::PPC32GOT: {
1451 OutContext.getOrCreateSymbol(StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1452 const MCExpr *SymGotTlsL =
1454 const MCExpr *SymGotTlsHA =
1456 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI)
1457 .addReg(
MI->getOperand(0).getReg())
1458 .addExpr(SymGotTlsL));
1459 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
1460 .addReg(
MI->getOperand(0).getReg())
1461 .addReg(
MI->getOperand(0).getReg())
1462 .addExpr(SymGotTlsHA));
1465 case PPC::ADDIStlsgdHA: {
1468 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1469 const MachineOperand &MO =
MI->getOperand(2);
1470 const GlobalValue *GValue = MO.
getGlobal();
1471 MCSymbol *MOSymbol = getSymbol(GValue);
1472 const MCExpr *SymGotTlsGD =
1474 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1475 .addReg(
MI->getOperand(0).getReg())
1476 .addReg(
MI->getOperand(1).getReg())
1477 .addExpr(SymGotTlsGD));
1480 case PPC::ADDItlsgdL:
1483 case PPC::ADDItlsgdL32: {
1486 const MachineOperand &MO =
MI->getOperand(2);
1487 const GlobalValue *GValue = MO.
getGlobal();
1488 MCSymbol *MOSymbol = getSymbol(GValue);
1489 const MCExpr *SymGotTlsGD = symbolWithSpecifier(
1491 EmitToStreamer(*OutStreamer,
1492 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1493 .addReg(
MI->getOperand(0).getReg())
1494 .addReg(
MI->getOperand(1).getReg())
1495 .addExpr(SymGotTlsGD));
1498 case PPC::GETtlsMOD32AIX:
1499 case PPC::GETtlsMOD64AIX:
1503 case PPC::GETtlsADDR:
1506 case PPC::GETtlsADDRPCREL:
1507 case PPC::GETtlsADDR32AIX:
1508 case PPC::GETtlsADDR64AIX:
1512 case PPC::GETtlsADDR32: {
1518 case PPC::GETtlsTpointer32AIX: {
1521 EmitAIXTlsCallHelper(
MI);
1524 case PPC::ADDIStlsldHA: {
1527 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1528 const MachineOperand &MO =
MI->getOperand(2);
1529 const GlobalValue *GValue = MO.
getGlobal();
1530 MCSymbol *MOSymbol = getSymbol(GValue);
1531 const MCExpr *SymGotTlsLD =
1533 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1534 .addReg(
MI->getOperand(0).getReg())
1535 .addReg(
MI->getOperand(1).getReg())
1536 .addExpr(SymGotTlsLD));
1539 case PPC::ADDItlsldL:
1542 case PPC::ADDItlsldL32: {
1545 const MachineOperand &MO =
MI->getOperand(2);
1546 const GlobalValue *GValue = MO.
getGlobal();
1547 MCSymbol *MOSymbol = getSymbol(GValue);
1548 const MCExpr *SymGotTlsLD = symbolWithSpecifier(
1550 EmitToStreamer(*OutStreamer,
1551 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1552 .addReg(
MI->getOperand(0).getReg())
1553 .addReg(
MI->getOperand(1).getReg())
1554 .addExpr(SymGotTlsLD));
1557 case PPC::GETtlsldADDR:
1560 case PPC::GETtlsldADDRPCREL:
1561 case PPC::GETtlsldADDR32: {
1567 case PPC::ADDISdtprelHA:
1570 case PPC::ADDISdtprelHA32: {
1573 const MachineOperand &MO =
MI->getOperand(2);
1574 const GlobalValue *GValue = MO.
getGlobal();
1575 MCSymbol *MOSymbol = getSymbol(GValue);
1579 MCInstBuilder(IsPPC64 ? PPC::ADDIS8 : PPC::ADDIS)
1580 .addReg(
MI->getOperand(0).getReg())
1581 .addReg(
MI->getOperand(1).getReg())
1582 .addExpr(SymDtprel));
1585 case PPC::PADDIdtprel: {
1588 const MachineOperand &MO =
MI->getOperand(2);
1589 const GlobalValue *GValue = MO.
getGlobal();
1590 MCSymbol *MOSymbol = getSymbol(GValue);
1591 const MCExpr *SymDtprel = symbolWithSpecifier(MOSymbol,
PPC::S_DTPREL);
1592 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::PADDI8)
1593 .addReg(
MI->getOperand(0).getReg())
1594 .addReg(
MI->getOperand(1).getReg())
1595 .addExpr(SymDtprel));
1599 case PPC::ADDIdtprelL:
1602 case PPC::ADDIdtprelL32: {
1605 const MachineOperand &MO =
MI->getOperand(2);
1606 const GlobalValue *GValue = MO.
getGlobal();
1607 MCSymbol *MOSymbol = getSymbol(GValue);
1609 EmitToStreamer(*OutStreamer,
1610 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1611 .addReg(
MI->getOperand(0).getReg())
1612 .addReg(
MI->getOperand(1).getReg())
1613 .addExpr(SymDtprel));
1618 if (!Subtarget->hasMFOCRF()) {
1621 unsigned NewOpcode =
1622 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
1623 OutStreamer->AddComment(PPCInstPrinter::
1625 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1626 .addReg(
MI->getOperand(0).getReg()));
1632 if (!Subtarget->hasMFOCRF()) {
1635 unsigned NewOpcode =
1636 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1637 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
1638 ->getEncodingValue(
MI->getOperand(0).getReg());
1639 OutStreamer->AddComment(PPCInstPrinter::
1641 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1643 .addReg(
MI->getOperand(1).getReg()));
1653 unsigned OpNum = (
MI->getOpcode() == PPC::STD) ? 2 : 1;
1657 for (
const MachineOperand &TempMO :
MI->operands()) {
1660 TempMO.getOperandNo() == 1)
1663 const MachineOperand &MO =
MI->getOperand(OpNum);
1697 if (!HasAIXSmallLocalTLS)
1699 bool IsMIADDI8 =
MI->getOpcode() == PPC::ADDI8;
1700 unsigned OpNum = IsMIADDI8 ? 2 : 1;
1701 const MachineOperand &MO =
MI->getOperand(OpNum);
1708 const MCExpr *Expr = getAdjustedFasterLocalExpr(MO, MO.
getOffset());
1716 EmitToStreamer(*OutStreamer, TmpInst);
1722 case PPC::PseudoEIEIO: {
1725 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1728 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1729 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::EnforceIEIO));
1735 EmitToStreamer(*OutStreamer, TmpInst);
1745PPCAsmPrinter::getAdjustedFasterLocalExpr(
const MachineOperand &MO,
1752 assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!");
1753 const GlobalValue *GValue = MO.
getGlobal();
1756 "Only local-[exec|dynamic] accesses are handled!");
1762 const auto TLSVarsMapEntryIter = TLSVarsToAddressMapping.
find(GValue);
1763 if (TLSVarsMapEntryIter == TLSVarsToAddressMapping.
end())
1764 assert(IsGlobalADeclaration &&
1765 "Only expecting to find extern TLS variables not present in the TLS "
1766 "variable-to-address map!");
1768 unsigned TLSVarAddress =
1769 IsGlobalADeclaration ? 0 : TLSVarsMapEntryIter->second;
1770 ptrdiff_t FinalAddress = (TLSVarAddress +
Offset);
1782 if (FinalAddress >= 32768) {
1789 ptrdiff_t Delta = ((FinalAddress + 32768) & ~0xFFFF);
1791 [[maybe_unused]] ptrdiff_t InstDisp = TLSVarAddress +
Offset - Delta;
1793 ((InstDisp < 32768) && (InstDisp >= -32768)) &&
1794 "Expecting the instruction displacement for local-[exec|dynamic] TLS "
1795 "variables to be between [-32768, 32768)!");
1803void PPCLinuxAsmPrinter::emitGNUAttributes(
Module &M) {
1805 Metadata *MD =
M.getModuleFlag(
"float-abi");
1811 if (flt ==
"doubledouble")
1812 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1813 Val_GNU_Power_ABI_HardFloat_DP |
1814 Val_GNU_Power_ABI_LDBL_IBM128);
1815 else if (flt ==
"ieeequad")
1816 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1817 Val_GNU_Power_ABI_HardFloat_DP |
1818 Val_GNU_Power_ABI_LDBL_IEEE128);
1819 else if (flt ==
"ieeedouble")
1820 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1821 Val_GNU_Power_ABI_HardFloat_DP |
1822 Val_GNU_Power_ABI_LDBL_64);
1825void PPCLinuxAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
1826 if (!Subtarget->isPPC64())
1827 return PPCAsmPrinter::emitInstruction(
MI);
1829 switch (
MI->getOpcode()) {
1832 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1847 (void)
F.getFnAttribute(
"patchable-function-entry")
1849 .getAsInteger(10, Num);
1851 if (!MAI->isLittleEndian() || Num)
1853 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1854 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1855 OutStreamer->emitLabel(BeginOfSled);
1856 EmitToStreamer(*OutStreamer,
1857 MCInstBuilder(PPC::B).addExpr(
1859 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1862 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1863 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1864 EmitToStreamer(*OutStreamer,
1865 MCInstBuilder(PPC::BL8_NOP)
1867 OutContext.getOrCreateSymbol(
"__xray_FunctionEntry"),
1869 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1870 OutStreamer->emitLabel(EndOfSled);
1871 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_ENTER, 2);
1874 case TargetOpcode::PATCHABLE_RET: {
1875 unsigned RetOpcode =
MI->getOperand(0).getImm();
1885 if (RetOpcode == PPC::BCCLR) {
1886 IsConditional =
true;
1887 }
else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1888 RetOpcode == PPC::TCRETURNai8) {
1890 }
else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1891 IsConditional =
false;
1893 EmitToStreamer(*OutStreamer, RetInst);
1898 if (IsConditional) {
1917 FallthroughLabel = OutContext.createTempSymbol();
1920 MCInstBuilder(PPC::BCC)
1923 .addReg(
MI->getOperand(2).getReg())
1940 OutStreamer->emitCodeAlignment(
Align(8), &getSubtargetInfo());
1941 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1942 OutStreamer->emitLabel(BeginOfSled);
1943 EmitToStreamer(*OutStreamer, RetInst);
1944 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1947 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1948 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1949 EmitToStreamer(*OutStreamer,
1950 MCInstBuilder(PPC::BL8_NOP)
1952 OutContext.getOrCreateSymbol(
"__xray_FunctionExit"),
1954 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1955 EmitToStreamer(*OutStreamer, RetInst);
1957 OutStreamer->emitLabel(FallthroughLabel);
1958 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_EXIT, 2);
1961 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1963 case TargetOpcode::PATCHABLE_TAIL_CALL:
1967 "around this assert.");
1969 return PPCAsmPrinter::emitInstruction(
MI);
1972void PPCLinuxAsmPrinter::emitStartOfAsmFile(
Module &M) {
1973 if (
static_cast<const PPCTargetMachine &
>(TM).isELFv2ABI()) {
1974 PPCTargetStreamer *TS =
1975 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
1979 if (
static_cast<const PPCTargetMachine &
>(TM).isPPC64() ||
1980 !isPositionIndependent())
1986 OutStreamer->switchSection(OutContext.getELFSection(
1989 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(
".LTOC"));
1990 MCSymbol *CurrentPos = OutContext.createTempSymbol();
1992 OutStreamer->emitLabel(CurrentPos);
1996 const MCExpr *tocExpr =
2001 OutStreamer->emitAssignment(TOCSym, tocExpr);
2003 OutStreamer->switchSection(getObjFileLowering().getTextSection());
2006void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
2008 if (!Subtarget->isPPC64() &&
2009 (!isPositionIndependent() ||
2013 if (!Subtarget->isPPC64()) {
2014 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
2015 if (PPCFI->
usesPICBase() && !Subtarget->isSecurePlt()) {
2017 MCSymbol *PICBase = MF->getPICBaseSymbol();
2018 OutStreamer->emitLabel(RelocSymbol);
2020 const MCExpr *OffsExpr =
2026 OutStreamer->emitValue(OffsExpr, 4);
2027 OutStreamer->emitLabel(CurrentFnSym);
2040 && !MF->getRegInfo().use_empty(PPC::X2)) {
2041 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
2043 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(
".TOC."));
2045 const MCExpr *TOCDeltaExpr =
2052 OutStreamer->emitValue(TOCDeltaExpr, 8);
2059 MCSectionELF *
Section = OutStreamer->getContext().getELFSection(
2061 OutStreamer->switchSection(Section);
2062 OutStreamer->emitLabel(CurrentFnSym);
2063 OutStreamer->emitValueToAlignment(
Align(8));
2064 MCSymbol *Symbol1 = CurrentFnSymForSize;
2069 MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(
".TOC."));
2071 OutStreamer->emitValue(
2074 OutStreamer->emitIntValue(0, 8 );
2075 OutStreamer->switchSection(Current.first, Current.second);
2078void PPCLinuxAsmPrinter::emitEndOfAsmFile(
Module &M) {
2079 const DataLayout &
DL = getDataLayout();
2081 bool isPPC64 =
DL.getPointerSizeInBits() == 64;
2083 PPCTargetStreamer *TS =
2084 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
2090 if (
static_cast<const PPCTargetMachine &
>(TM).hasGlibcHWCAPAccess())
2091 OutStreamer->emitSymbolValue(
2092 GetExternalSymbolSymbol(
"__parse_hwcap_and_convert_at_platform"),
2093 MAI->getCodePointerSize());
2094 emitGNUAttributes(M);
2097 const char *
Name = isPPC64 ?
".toc" :
".got2";
2098 MCSectionELF *
Section = OutContext.getELFSection(
2100 OutStreamer->switchSection(Section);
2102 OutStreamer->emitValueToAlignment(
Align(4));
2104 for (
const auto &TOCMapPair : TOC) {
2105 const MCSymbol *
const TOCEntryTarget = TOCMapPair.first.first;
2106 MCSymbol *
const TOCEntryLabel = TOCMapPair.second;
2108 OutStreamer->emitLabel(TOCEntryLabel);
2110 TS->
emitTCEntry(*TOCEntryTarget, TOCMapPair.first.second);
2112 OutStreamer->emitSymbolValue(TOCEntryTarget, 4);
2116 PPCAsmPrinter::emitEndOfAsmFile(M);
2120void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
2152 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
2153 const bool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) ||
2154 !MF->getRegInfo().use_empty(PPC::R2);
2163 if (NonPCrelGEPRequired || PCrelGEPRequired) {
2168 OutStreamer->emitLabel(GlobalEntryLabel);
2169 const MCSymbolRefExpr *GlobalEntryLabelExp =
2173 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(
".TOC."));
2174 const MCExpr *TOCDeltaExpr =
2176 GlobalEntryLabelExp, OutContext);
2178 const MCExpr *TOCDeltaHi =
2180 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
2183 .addExpr(TOCDeltaHi));
2185 const MCExpr *TOCDeltaLo =
2187 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
2190 .addExpr(TOCDeltaLo));
2193 const MCExpr *TOCOffsetDeltaExpr =
2195 GlobalEntryLabelExp, OutContext);
2197 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
2199 .addExpr(TOCOffsetDeltaExpr)
2201 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8)
2208 OutStreamer->emitLabel(LocalEntryLabel);
2209 const MCSymbolRefExpr *LocalEntryLabelExp =
2211 const MCExpr *LocalOffsetExp =
2213 GlobalEntryLabelExp, OutContext);
2215 PPCTargetStreamer *TS =
2216 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
2241 if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() ||
2242 MF->hasInlineAsm() || (!PPCFI->
usesTOCBasePtr() && UsesX2OrR2)) {
2243 PPCTargetStreamer *TS =
2244 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
2254void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
2262 if (Subtarget->isPPC64()) {
2263 OutStreamer->emitIntValue(0, 4);
2264 OutStreamer->emitIntValue(0, 8);
2268char PPCLinuxAsmPrinter::ID = 0;
2271 "Linux PPC Assembly Printer",
false,
false)
2276 switch (GV->getLinkage()) {
2277 case GlobalValue::ExternalLinkage:
2278 LinkageAttr = GV->isDeclaration() ? MCSA_Extern : MCSA_Global;
2280 case GlobalValue::LinkOnceAnyLinkage:
2281 case GlobalValue::LinkOnceODRLinkage:
2282 case GlobalValue::WeakAnyLinkage:
2283 case GlobalValue::WeakODRLinkage:
2284 case GlobalValue::ExternalWeakLinkage:
2285 LinkageAttr = MCSA_Weak;
2287 case GlobalValue::AvailableExternallyLinkage:
2288 LinkageAttr = MCSA_Extern;
2290 case GlobalValue::PrivateLinkage:
2292 case GlobalValue::InternalLinkage:
2293 assert(GV->getVisibility() == GlobalValue::DefaultVisibility &&
2294 "InternalLinkage should not have other visibility setting.");
2295 LinkageAttr = MCSA_LGlobal;
2297 case GlobalValue::AppendingLinkage:
2298 llvm_unreachable(
"Should never emit this");
2299 case GlobalValue::CommonLinkage:
2300 llvm_unreachable(
"CommonLinkage of XCOFF should not come to this path");
2306 if (!TM.getIgnoreXCOFFVisibility()) {
2307 if (GV->hasDLLExportStorageClass() && !GV->hasDefaultVisibility())
2309 "Cannot not be both dllexport and non-default visibility");
2310 switch (GV->getVisibility()) {
2313 case GlobalValue::DefaultVisibility:
2314 if (GV->hasDLLExportStorageClass())
2315 VisibilityAttr = MAI->getExportedVisibilityAttr();
2317 case GlobalValue::HiddenVisibility:
2318 VisibilityAttr = MAI->getHiddenVisibilityAttr();
2320 case GlobalValue::ProtectedVisibility:
2321 VisibilityAttr = MAI->getProtectedVisibilityAttr();
2331 OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,
2335void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
2337 auto *FnDescSec =
static_cast<MCSectionXCOFF *
>(
2338 getObjFileLowering().getSectionForFunctionDescriptor(&MF.
getFunction(),
2340 FnDescSec->setAlignment(
Align(Subtarget->isPPC64() ? 8 : 4));
2342 CurrentFnDescSym = FnDescSec->getQualNameSymbol();
2347uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
2351 const PPCSubtarget &Subtarget = MF->
getSubtarget<PPCSubtarget>();
2352 if (Subtarget.
isAIXABI() && Subtarget.hasAltivec() &&
2353 TM.getAIXExtendedAltivecABI()) {
2355 for (
unsigned Reg = PPC::V20;
Reg <= PPC::V31; ++
Reg)
2356 if (
MRI.isPhysRegModified(
Reg))
2358 return PPC::V31 -
Reg + 1;
2363void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
2365 if (!TM.getXCOFFTracebackTable())
2368 emitTracebackTable();
2376 (getNumberOfVRSaved() > 0)) {
2378 OutStreamer->switchSection(getObjFileLowering().getCompactUnwindSection());
2381 OutStreamer->emitLabel(EHInfoLabel);
2384 OutStreamer->emitInt32(0);
2386 const DataLayout &
DL = MMI->getModule()->getDataLayout();
2389 OutStreamer->emitValueToAlignment(
Align(PointerSize));
2391 OutStreamer->emitIntValue(0, PointerSize);
2392 OutStreamer->emitIntValue(0, PointerSize);
2393 OutStreamer->switchSection(MF->
getSection());
2397void PPCAIXAsmPrinter::emitTracebackTable() {
2401 OutStreamer->emitLabel(FuncEnd);
2403 OutStreamer->AddComment(
"Traceback table begin");
2405 OutStreamer->emitIntValueInHexWithPadding(0, 4 );
2407 SmallString<128> CommentString;
2408 raw_svector_ostream CommentOS(CommentString);
2410 auto EmitComment = [&]() {
2411 OutStreamer->AddComment(CommentOS.str());
2412 CommentString.
clear();
2415 auto EmitCommentAndValue = [&](uint64_t
Value,
int Size) {
2417 OutStreamer->emitIntValueInHexWithPadding(
Value,
Size);
2421 CommentOS <<
"Version = " <<
Version;
2422 EmitCommentAndValue(
Version, 1);
2432 CommentOS <<
"Language = "
2434 EmitCommentAndValue(LanguageIdentifier, 1);
2437 uint32_t FirstHalfOfMandatoryField = 0;
2444 const PPCFunctionInfo *FI = MF->
getInfo<PPCFunctionInfo>();
2448 for (
unsigned Reg = PPC::F0;
Reg <= PPC::F31; ++
Reg) {
2449 if (
MRI.isPhysRegUsed(
Reg,
true)) {
2455#define GENBOOLCOMMENT(Prefix, V, Field) \
2456 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
2459#define GENVALUECOMMENT(PrefixAndName, V, Field) \
2460 CommentOS << (PrefixAndName) << " = " \
2461 << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
2462 (TracebackTable::Field##Shift))
2465 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);
2468 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasTraceBackTableOffset);
2469 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsInternalProcedure);
2472 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasControlledStorage);
2476 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsFloatingPointPresent);
2479 IsFloatingPointOperationLogOrAbortEnabled);
2482 OutStreamer->emitIntValueInHexWithPadding(
2483 (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2490 if (FrameReg == (Subtarget->isPPC64() ? PPC::X31 : PPC::R31))
2493 const SmallVectorImpl<Register> &MustSaveCRs = FI->
getMustSaveCRs();
2494 if (!MustSaveCRs.
empty())
2500 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsInterruptHandler);
2501 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);
2505 OnConditionDirective);
2509 OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),
2513 uint32_t SecondHalfOfMandatoryField = 0;
2519 uint32_t FPRSaved = 0;
2520 for (
unsigned Reg = PPC::F14;
Reg <= PPC::F31; ++
Reg) {
2521 if (
MRI.isPhysRegModified(
Reg)) {
2522 FPRSaved = PPC::F31 -
Reg + 1;
2528 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, IsBackChainStored);
2530 GENVALUECOMMENT(
", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
2532 OutStreamer->emitIntValueInHexWithPadding(
2533 (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
2539 bool HasVectorInst =
false;
2540 for (
unsigned Reg = PPC::V0;
Reg <= PPC::V31; ++
Reg)
2541 if (
MRI.isPhysRegUsed(
Reg,
true)) {
2543 HasVectorInst =
true;
2550 uint16_t NumOfVRSaved = getNumberOfVRSaved();
2551 bool ShouldEmitEHBlock =
2554 if (ShouldEmitEHBlock)
2557 uint32_t GPRSaved = 0;
2560 unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13;
2561 unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31;
2563 for (
unsigned Reg = GPRBegin;
Reg <= GPREnd; ++
Reg) {
2564 if (
MRI.isPhysRegModified(
Reg)) {
2565 GPRSaved = GPREnd -
Reg + 1;
2573 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, HasExtensionTable);
2575 GENVALUECOMMENT(
", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
2577 OutStreamer->emitIntValueInHexWithPadding(
2578 (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
2582 SecondHalfOfMandatoryField |=
2586 NumberOfFixedParms);
2588 OutStreamer->emitIntValueInHexWithPadding(
2589 (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2597 SecondHalfOfMandatoryField |=
2602 NumberOfFloatingPointParms);
2603 GENBOOLCOMMENT(
", ", SecondHalfOfMandatoryField, HasParmsOnStack);
2605 OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
2611 if (NumberOfFixedParms || NumberOfFPParms) {
2614 Expected<SmallString<32>> ParmsType =
2617 ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
2624 CommentOS <<
"Parameter type = " << ParmsType.
get();
2627 OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
2628 sizeof(ParmsTypeValue));
2631 OutStreamer->AddComment(
"Function size");
2633 MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
2635 OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
2647 int16_t NameLength =
Name.size();
2648 CommentOS <<
"Function name len = "
2649 <<
static_cast<unsigned int>(NameLength);
2650 EmitCommentAndValue(NameLength, 2);
2651 OutStreamer->AddComment(
"Function Name");
2652 OutStreamer->emitBytes(Name);
2657 OutStreamer->AddComment(
"AllocaUsed");
2658 OutStreamer->emitIntValueInHex(AllocReg,
sizeof(AllocReg));
2662 uint16_t VRData = 0;
2691 OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
2696 OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
2700 Expected<SmallString<32>> VecParmsType =
2704 CommentOS <<
"Vector Parameter type = " << VecParmsType.
get();
2707 OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
2708 sizeof(VecParmTypeValue));
2710 CommentOS <<
"Padding";
2711 EmitCommentAndValue(0, 2);
2714 uint8_t ExtensionTableFlag = 0;
2716 if (ShouldEmitEHBlock)
2717 ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
2720 ExtensionTableFlag |= ExtendedTBTableFlag::TB_SSP_CANARY;
2722 CommentOS <<
"ExtensionTableFlag = "
2724 EmitCommentAndValue(ExtensionTableFlag,
sizeof(ExtensionTableFlag));
2727 if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
2728 auto &Ctx = OutStreamer->getContext();
2731 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym, TOCType_EHBlock);
2732 const MCSymbol *TOCBaseSym =
static_cast<const MCSectionXCOFF *
>(
2733 getObjFileLowering().getTOCBaseSection())
2734 ->getQualNameSymbol();
2739 const DataLayout &
DL = getDataLayout();
2740 OutStreamer->emitValueToAlignment(
Align(4));
2741 OutStreamer->AddComment(
"EHInfo Table");
2742 OutStreamer->emitValue(Exp,
DL.getPointerSize());
2744#undef GENBOOLCOMMENT
2745#undef GENVALUECOMMENT
2754 .
Case(
"llvm.used",
true)
2756 .
Case(
"llvm.compiler.used",
true)
2762 .
Cases({
"llvm.global_ctors",
"llvm.global_dtors"},
true)
2766uint64_t PPCAIXAsmPrinter::getAliasOffset(
const Constant *
C) {
2768 return getAliasOffset(GA->getAliasee());
2779 return RHS->getValue();
2789 "GlobalVariables with an alignment requirement stricter than TOC entry "
2790 "size not supported by the toc data transformation.");
2793 assert(GVType->
isSized() &&
"A GlobalVariable's size must be known to be "
2794 "supported by the toc data transformation.");
2798 "A GlobalVariable with size larger than a TOC entry is not currently "
2799 "supported by the toc data transformation.");
2802 "currently supported by the toc data transformation.");
2805void PPCAIXAsmPrinter::emitGlobalVariable(
const GlobalVariable *GV) {
2823 emitGlobalVariableHelper(GV);
2826void PPCAIXAsmPrinter::emitGlobalVariableHelper(
const GlobalVariable *GV) {
2828 "Unhandled intrinsic global variable.");
2833 auto *GVSym =
static_cast<MCSymbolXCOFF *
>(getSymbol(GV));
2836 emitLinkage(GV, GVSym);
2840 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
2844 "not supported yet.");
2851 OutStreamer->getCommentOS() <<
'\n';
2855 auto *Csect =
static_cast<MCSectionXCOFF *
>(
2856 getObjFileLowering().SectionForGlobal(GV, GVKind, TM));
2859 OutStreamer->switchSection(Csect);
2861 if (GV->
hasMetadata(LLVMContext::MD_implicit_ref)) {
2862 emitRefMetadata(GV);
2872 GVSym->setStorageClass(
2876 OutStreamer->emitZeros(
Size);
2879 "BSS local toc-data already handled and TLS variables "
2880 "incompatible with XMC_TD");
2881 OutStreamer->emitXCOFFLocalCommonSymbol(
2882 OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()),
Size,
2885 OutStreamer->emitCommonSymbol(GVSym,
Size, Alignment);
2893 emitLinkage(GV, EmittedInitSym);
2894 for (
const GlobalAlias *GA : GOAliasMap[GV])
2895 emitLinkage(GA, getSymbol(GA));
2897 emitAlignment(getGVAlignment(GV,
DL), GV);
2901 if (!TM.getDataSections() || GV->hasSection()) {
2903 OutStreamer->emitLabel(EmittedInitSym);
2907 if (!GOAliasMap[GV].
size()) {
2908 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer());
2914 AliasMapTy AliasList;
2915 for (
const GlobalAlias *GA : GOAliasMap[GV])
2916 AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);
2919 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer(),
2923void PPCAIXAsmPrinter::emitFunctionDescriptor() {
2924 const DataLayout &
DL = getDataLayout();
2925 const unsigned PointerSize =
DL.getPointerSizeInBits() == 64 ? 8 : 4;
2929 OutStreamer->switchSection(
2930 static_cast<MCSymbolXCOFF *
>(CurrentFnDescSym)->getRepresentedCsect());
2935 for (
const GlobalAlias *Alias : GOAliasMap[&MF->
getFunction()])
2936 OutStreamer->emitLabel(getSymbol(Alias));
2942 const MCSymbol *TOCBaseSym =
static_cast<const MCSectionXCOFF *
>(
2943 getObjFileLowering().getTOCBaseSection())
2944 ->getQualNameSymbol();
2948 OutStreamer->emitIntValue(0, PointerSize);
2950 OutStreamer->switchSection(Current.first, Current.second);
2953void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2957 PPCAsmPrinter::emitFunctionEntryLabel();
2965 for (
const GlobalAlias *Alias : GOAliasMap[
F])
2966 OutStreamer->emitLabel(
2967 getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM));
2969 if (
F->hasMetadata(LLVMContext::MD_implicit_ref)) {
2974void PPCAIXAsmPrinter::emitPGORefs(
Module &M) {
2975 if (!OutContext.hasXCOFFSection(
2986 bool HasNonZeroLengthPrfCntsSection =
false;
2987 const DataLayout &
DL =
M.getDataLayout();
2988 for (GlobalVariable &GV :
M.globals())
2989 if (GV.hasSection() && GV.getSection() ==
"__llvm_prf_cnts" &&
2990 GV.getGlobalSize(
DL) > 0) {
2991 HasNonZeroLengthPrfCntsSection =
true;
2995 if (HasNonZeroLengthPrfCntsSection) {
2996 MCSection *CntsSection = OutContext.getXCOFFSection(
3001 OutStreamer->switchSection(CntsSection);
3002 if (OutContext.hasXCOFFSection(
3005 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_data[RW]");
3006 OutStreamer->emitXCOFFRefDirective(S);
3008 if (OutContext.hasXCOFFSection(
3011 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_names[RO]");
3012 OutStreamer->emitXCOFFRefDirective(S);
3014 if (OutContext.hasXCOFFSection(
3017 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_vnds[RW]");
3018 OutStreamer->emitXCOFFRefDirective(S);
3023void PPCAIXAsmPrinter::emitGCOVRefs() {
3024 if (!OutContext.hasXCOFFSection(
3025 "__llvm_gcov_ctr_section",
3029 MCSection *CtrSection = OutContext.getXCOFFSection(
3034 OutStreamer->switchSection(CtrSection);
3037 if (OutContext.hasXCOFFSection(
3040 const char *SymbolStr = TM.Options.XCOFFReadOnlyPointers
3041 ?
"__llvm_covinit[RO]"
3042 :
"__llvm_covinit[RW]";
3043 MCSymbol *S = OutContext.getOrCreateSymbol(SymbolStr);
3044 OutStreamer->emitXCOFFRefDirective(S);
3048void PPCAIXAsmPrinter::emitEndOfAsmFile(
Module &M) {
3051 if (
M.empty() && TOCDataGlobalVars.
empty())
3058 OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());
3060 PPCTargetStreamer *TS =
3061 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
3063 for (
auto &
I : TOC) {
3064 MCSectionXCOFF *TCEntry;
3071 (Subtarget->hasAIXShLibTLSModelOpt() &&
3073 SmallString<128>
Name;
3076 Name +=
static_cast<const MCSymbolXCOFF *
>(
I.first.first)
3077 ->getSymbolTableName();
3078 MCSymbol *S = OutContext.getOrCreateSymbol(Name);
3079 TCEntry =
static_cast<MCSectionXCOFF *
>(
3080 getObjFileLowering().getSectionForTOCEntry(S, TM));
3082 TCEntry =
static_cast<MCSectionXCOFF *
>(
3083 getObjFileLowering().getSectionForTOCEntry(
I.first.first, TM));
3085 OutStreamer->switchSection(TCEntry);
3087 OutStreamer->emitLabel(
I.second);
3094 for (
const auto *GV : TOCDataGlobalVars) {
3095 if (!GV->hasCommonLinkage())
3096 emitGlobalVariableHelper(GV);
3098 for (
const auto *GV : TOCDataGlobalVars) {
3099 if (GV->hasCommonLinkage())
3100 emitGlobalVariableHelper(GV);
3104bool PPCAIXAsmPrinter::doInitialization(
Module &M) {
3105 const bool Result = PPCAsmPrinter::doInitialization(M);
3108 const Triple &
Target = TM.getTargetTriple();
3115 if (FunCpuId > TargetCpuId)
3116 TargetCpuId = FunCpuId;
3122 StringRef TargetCPU = TM.getTargetCPU();
3127 PPCTargetStreamer *TS =
3128 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
3131 auto setCsectAlignment = [
this](
const GlobalObject *GO) {
3133 if (GO->isDeclarationForLinker())
3136 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);
3137 auto *Csect =
static_cast<MCSectionXCOFF *
>(
3138 getObjFileLowering().SectionForGlobal(GO, GOKind, TM));
3140 Align GOAlign = getGVAlignment(GO, GO->getDataLayout());
3141 Csect->ensureMinAlignment(GOAlign);
3147 uint64_t TLSVarAddress = 0;
3148 auto DL =
M.getDataLayout();
3149 for (
const auto &
G :
M.globals()) {
3150 if (
G.isThreadLocal() && !
G.isDeclaration()) {
3151 TLSVarAddress =
alignTo(TLSVarAddress, getGVAlignment(&
G,
DL));
3152 TLSVarsToAddressMapping[&
G] = TLSVarAddress;
3153 TLSVarAddress +=
G.getGlobalSize(
DL);
3160 for (
const auto &
G :
M.globals()) {
3167 if (FormatIndicatorAndUniqueModId.empty()) {
3169 if (UniqueModuleId !=
"")
3173 FormatIndicatorAndUniqueModId =
"clang_" + UniqueModuleId.substr(1);
3178 std::chrono::duration_cast<std::chrono::nanoseconds>(
3179 std::chrono::steady_clock::now().time_since_epoch())
3181 FormatIndicatorAndUniqueModId =
3188 emitSpecialLLVMGlobal(&
G);
3192 setCsectAlignment(&
G);
3193 std::optional<CodeModel::Model> OptionalCodeModel =
G.getCodeModel();
3194 if (OptionalCodeModel)
3196 *OptionalCodeModel);
3199 for (
const auto &
F : M)
3200 setCsectAlignment(&
F);
3203 for (
const auto &Alias :
M.aliases()) {
3204 const GlobalObject *Aliasee = Alias.getAliaseeObject();
3207 "alias without a base object is not yet supported on AIX");
3211 "\n\tAlias attribute for " +
3212 Alias.getName() +
" is invalid because " +
3213 Aliasee->
getName() +
" is common.",
3217 const GlobalVariable *GVar =
3220 std::optional<CodeModel::Model> OptionalCodeModel = GVar->
getCodeModel();
3221 if (OptionalCodeModel)
3223 *OptionalCodeModel);
3226 GOAliasMap[Aliasee].push_back(&Alias);
3232void PPCAIXAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
3233 switch (
MI->getOpcode()) {
3240 if (
MI->getNumOperands() < 5)
3242 const MachineOperand &LangMO =
MI->getOperand(3);
3243 const MachineOperand &ReasonMO =
MI->getOperand(4);
3246 MCSymbol *TempSym = OutContext.createNamedTempSymbol();
3247 OutStreamer->emitLabel(TempSym);
3248 OutStreamer->emitXCOFFExceptDirective(
3249 CurrentFnSym, TempSym, LangMO.
getImm(), ReasonMO.
getImm(),
3250 Subtarget->isPPC64() ?
MI->getMF()->getInstructionCount() * 8
3251 :
MI->getMF()->getInstructionCount() * 4,
3255 case PPC::GETtlsMOD32AIX:
3256 case PPC::GETtlsMOD64AIX:
3257 case PPC::GETtlsTpointer32AIX:
3258 case PPC::GETtlsADDR64AIX:
3259 case PPC::GETtlsADDR32AIX: {
3264 ExtSymSDNodeSymbols.
insert(TlsGetAddr);
3271 const MachineOperand &MO =
MI->getOperand(0);
3273 auto *S =
static_cast<MCSymbolXCOFF *
>(
3275 ExtSymSDNodeSymbols.
insert(S);
3281 case PPC::BL8_NOP_TLS:
3288 case PPC::TAILBCTR8:
3289 if (
MI->getOperand(0).isSymbol())
3302 MCInstBuilder(PPC::ORI).addReg(PPC::R0).addReg(PPC::R0).addImm(0));
3305 return PPCAsmPrinter::emitInstruction(
MI);
3308bool PPCAIXAsmPrinter::doFinalization(
Module &M) {
3309 for (MCSymbol *Sym : ExtSymSDNodeSymbols)
3310 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Extern);
3311 return PPCAsmPrinter::doFinalization(M);
3322 return 20 + (
P - 20) * 16;
3325 return 1004 + (
P - 81);
3328 return 2047 + (
P - 1124) * 33878;
3330 return 2147482625u + (
P - 64512);
3349 std::string PrioritySuffix;
3352 return PrioritySuffix;
3355void PPCAIXAsmPrinter::emitXXStructorList(
const DataLayout &
DL,
3356 const Constant *
List,
bool IsCtor) {
3358 preprocessXXStructorList(
DL,
List, Structors);
3359 if (Structors.
empty())
3363 for (Structor &S : Structors) {
3365 S.Func =
CE->getOperand(0);
3369 (IsCtor ? llvm::Twine(
"__sinit") : llvm::Twine(
"__sterm")) +
3371 llvm::Twine(
"_", FormatIndicatorAndUniqueModId) +
3377void PPCAIXAsmPrinter::emitTTypeReference(
const GlobalValue *GV,
3378 unsigned Encoding) {
3380 TOCEntryType GlobalType = TOCType_GlobalInternal;
3385 GlobalType = TOCType_GlobalExternal;
3386 MCSymbol *TypeInfoSym = TM.getSymbol(GV);
3387 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym, GlobalType);
3388 const MCSymbol *TOCBaseSym =
static_cast<const MCSectionXCOFF *
>(
3389 getObjFileLowering().getTOCBaseSection())
3390 ->getQualNameSymbol();
3391 auto &Ctx = OutStreamer->getContext();
3395 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
3397 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
3400void PPCAIXAsmPrinter::emitRefMetadata(
const GlobalObject *GO) {
3402 GO->
getMetadata(LLVMContext::MD_implicit_ref, MDs);
3403 assert(MDs.
size() &&
"Expected !implicit.ref metadata nodes");
3405 for (
const MDNode *MD : MDs) {
3410 ? getObjFileLowering().getFunctionEntryPointSymbol(GV, TM)
3412 OutStreamer->emitXCOFFRefDirective(Referenced);
3420 std::unique_ptr<MCStreamer> &&Streamer) {
3422 return new PPCAIXAsmPrinter(tm, std::move(Streamer));
3424 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
3427void PPCAIXAsmPrinter::emitModuleCommandLines(
Module &M) {
3428 const NamedMDNode *NMD =
M.getNamedMetadata(
"llvm.commandline");
3433 raw_string_ostream RSOS(S);
3436 assert(
N->getNumOperands() == 1 &&
3437 "llvm.commandline metadata entry can have only one operand");
3441 RSOS <<
"@(#)opt " << MDS->
getString() <<
"\n";
3444 OutStreamer->emitXCOFFCInfoSym(
".GCC.command.line", RSOS.str());
3448 enum class IsLocal {
3460 if (
LHS == IsLocal::False ||
RHS == IsLocal::False)
3461 return IsLocal::False;
3462 if (
LHS == IsLocal::True &&
RHS == IsLocal::True)
3463 return IsLocal::True;
3464 return IsLocal::Unknown;
3468 auto IsLocalFunc = [](
const Function *
F) -> IsLocal {
3469 bool Result =
F->isDSOLocal();
3471 << (Result ?
"dso_local\n" :
"not dso_local\n"));
3472 return Result ? IsLocal::True : IsLocal::False;
3481 std::function<IsLocal(
const Value *)> ValueIsALocalFunc =
3482 [&IsLocalFunc, &
Combine, &ValueIsALocalFunc](
const Value *V) -> IsLocal {
3484 return IsLocalFunc(
F);
3486 return IsLocal::Unknown;
3491 return Combine(ValueIsALocalFunc(
SI->getTrueValue()),
3492 ValueIsALocalFunc(
SI->getFalseValue()));
3494 IsLocal Res = IsLocal::True;
3495 for (
unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
3496 Res =
Combine(Res, ValueIsALocalFunc(PN->getIncomingValue(i)));
3497 if (Res == IsLocal::False)
3512 return IsLocal::Unknown;
3515 return IsLocal::Unknown;
3517 IsLocal Res = IsLocal::True;
3518 for (
unsigned Idx = 0, End =
Init->getNumOperands(); Idx != End; ++Idx) {
3519 Res =
Combine(Res, ValueIsALocalFunc(
Init->getOperand(Idx)));
3520 if (Res == IsLocal::False)
3525 return IsLocal::Unknown;
3535 IsLocal Res = IsLocal::True;
3540 Value *RV = Ret->getReturnValue();
3542 Res =
Combine(Res, ValueIsALocalFunc(RV));
3543 if (Res == IsLocal::False)
3572void PPCAIXAsmPrinter::emitGlobalIFunc(
Module &M,
const GlobalIFunc &GI) {
3574 const TargetSubtargetInfo *STI =
3576 bool IsPPC64 =
static_cast<const PPCSubtarget *
>(STI)->isPPC64();
3581 MCSectionXCOFF *FnDescSec =
static_cast<MCSectionXCOFF *
>(
3582 getObjFileLowering().getSectionForFunctionDescriptor(&GI, TM));
3587 CurrentFnSym = getObjFileLowering().getFunctionEntryPointSymbol(&GI, TM);
3590 if (TM.getFunctionSections())
3591 OutStreamer->switchSection(
3592 static_cast<MCSymbolXCOFF *
>(CurrentFnSym)->getRepresentedCsect());
3594 OutStreamer->switchSection(getObjFileLowering().getTextSection());
3597 emitRefMetadata(&GI);
3600 emitLinkage(&GI, CurrentFnDescSym);
3601 emitLinkage(&GI, CurrentFnSym);
3605 emitAlignment(Alignment,
nullptr);
3608 emitFunctionDescriptor();
3610 emitFunctionEntryLabel();
3614 Twine Msg =
"unimplemented: TOC register save/restore needed for ifunc \"" +
3616 "\", because couldn't prove all candidates "
3617 "are static or hidden/protected visibility definitions";
3621 dbgs() << Msg <<
"\n";
3625 auto *FnDescTOCEntrySym =
3626 lookUpOrCreateTOCEntry(CurrentFnDescSym, FnDescTOCEntryType);
3631 auto *Exp_U = symbolWithSpecifier(FnDescTOCEntrySym,
PPC::S_U);
3632 OutStreamer->emitInstruction(MCInstBuilder(PPC::ADDIS)
3637 auto *Exp_L = symbolWithSpecifier(FnDescTOCEntrySym,
PPC::S_L);
3638 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3648 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3655 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3657 .addImm(IsPPC64 ? 16 : 8)
3661 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3667 OutStreamer->emitInstruction(
3668 MCInstBuilder(IsPPC64 ? PPC::MTCTR8 : PPC::MTCTR).addReg(PPC::X12),
3671 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::BCTR8 : PPC::BCTR),
3675char PPCAIXAsmPrinter::ID = 0;
3678 "AIX PPC Assembly Printer",
false,
false)
3682LLVMInitializePowerPCAsmPrinter() {
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 constexpr unsigned SM(unsigned Version)
static void collectTOCStats(PPCAsmPrinter::TOCEntryType Type)
static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV)
static bool isSpecialLLVMGlobalArrayToSkip(const GlobalVariable *GV)
static cl::opt< bool > IFuncLocalIfProven("ifunc-local-if-proven", cl::init(false), cl::desc("During ifunc lowering, the compiler assumes the resolver returns " "dso-local functions and bails out if non-local functions are " "detected; this flag flips the assumption: resolver returns " "preemptible functions unless the compiler can prove all paths " "return local functions."), cl::Hidden)
#define GENBOOLCOMMENT(Prefix, V, Field)
static MCSymbol * getMCSymbolForTOCPseudoMO(const MachineOperand &MO, AsmPrinter &AP)
Map a machine operand for a TOC pseudo-machine instruction to its corresponding MCSymbol.
static void setOptionalCodeModel(MCSymbolXCOFF *XSym, CodeModel::Model CM)
static AsmPrinter * createPPCAsmPrinterPass(TargetMachine &tm, std::unique_ptr< MCStreamer > &&Streamer)
static bool TOCRestoreNeededForCallToImplementation(const GlobalIFunc &GI)
static PPCAsmPrinter::TOCEntryType getTOCEntryTypeForMO(const MachineOperand &MO)
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
static PPCAsmPrinter::TOCEntryType getTOCEntryTypeForLinkage(GlobalValue::LinkageTypes Linkage)
static std::string convertToSinitPriority(int Priority)
static cl::opt< bool > IFuncWarnInsteadOfError("test-ifunc-warn-noerror", cl::init(false), cl::ReallyHidden)
static MCSymbol * createMCSymbolForTlsGetAddr(MCContext &Ctx, unsigned MIOpc)
This helper function creates the TlsGetAddr/TlsGetMod MCSymbol for AIX.
#define GENVALUECOMMENT(PrefixAndName, V, Field)
static unsigned mapToSinitPriority(int P)
static void tocDataChecks(unsigned PointerSize, const GlobalVariable *GV)
static cl::opt< bool > EnableSSPCanaryBitInTB("aix-ssp-tb-bit", cl::init(false), cl::desc("Enable Passing SSP Canary info in Trackback on AIX"), cl::Hidden)
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
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...
LLVM_ABI const Function * getResolverFunction() const
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.
MCSymbolXCOFF * getQualNameSymbol() const
void setAlignment(Align Value)
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)
Interface for looking up the initializer for a variable name, used by Init::resolveReferences.
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)
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)
Align getMinFunctionAlignment() const
Return the minimum function alignment.
static bool ShouldSetSSPCanaryBitInTB(const MachineFunction *MF)
static MCSymbol * getEHInfoTableSymbol(const MachineFunction *MF)
static XCOFF::StorageClass getStorageClassForGlobal(const GlobalValue *GV)
static bool ShouldEmitEHBlock(const MachineFunction *MF)
Primary interface to the complete machine description for the target machine.
const Triple & getTargetTriple() const
CodeModel::Model getCodeModel() const
Returns the code model.
virtual const TargetLowering * getTargetLowering() const
bool isOSAIX() const
Tests whether the OS is AIX.
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.
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)
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
auto dyn_cast_or_null(const Y &Val)
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.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
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