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.getInternalSymbolPrefix() <<
"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));
1733 case PPC::BL8_NOP: {
1734 const MachineOperand &MO =
MI->getOperand(0);
1737 Name.consume_front(
".");
1738 Name.consume_back(
"[PR]");
1739 bool IsLWAT =
Name ==
"__lwat_csne_pseudo";
1740 bool IsLDAT =
Name ==
"__ldat_csne_pseudo";
1741 if (IsLWAT || IsLDAT) {
1742 EmitToStreamer(*OutStreamer,
1743 MCInstBuilder(IsLWAT ? PPC::LWAT : PPC::LDAT)
1756 EmitToStreamer(*OutStreamer, TmpInst);
1766PPCAsmPrinter::getAdjustedFasterLocalExpr(
const MachineOperand &MO,
1773 assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!");
1774 const GlobalValue *GValue = MO.
getGlobal();
1777 "Only local-[exec|dynamic] accesses are handled!");
1783 const auto TLSVarsMapEntryIter = TLSVarsToAddressMapping.
find(GValue);
1784 if (TLSVarsMapEntryIter == TLSVarsToAddressMapping.
end())
1785 assert(IsGlobalADeclaration &&
1786 "Only expecting to find extern TLS variables not present in the TLS "
1787 "variable-to-address map!");
1789 unsigned TLSVarAddress =
1790 IsGlobalADeclaration ? 0 : TLSVarsMapEntryIter->second;
1791 ptrdiff_t FinalAddress = (TLSVarAddress +
Offset);
1803 if (FinalAddress >= 32768) {
1810 ptrdiff_t Delta = ((FinalAddress + 32768) & ~0xFFFF);
1812 [[maybe_unused]] ptrdiff_t InstDisp = TLSVarAddress +
Offset - Delta;
1814 ((InstDisp < 32768) && (InstDisp >= -32768)) &&
1815 "Expecting the instruction displacement for local-[exec|dynamic] TLS "
1816 "variables to be between [-32768, 32768)!");
1824void PPCLinuxAsmPrinter::emitGNUAttributes(
Module &M) {
1826 Metadata *MD =
M.getModuleFlag(
"float-abi");
1832 if (flt ==
"doubledouble")
1833 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1834 Val_GNU_Power_ABI_HardFloat_DP |
1835 Val_GNU_Power_ABI_LDBL_IBM128);
1836 else if (flt ==
"ieeequad")
1837 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1838 Val_GNU_Power_ABI_HardFloat_DP |
1839 Val_GNU_Power_ABI_LDBL_IEEE128);
1840 else if (flt ==
"ieeedouble")
1841 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1842 Val_GNU_Power_ABI_HardFloat_DP |
1843 Val_GNU_Power_ABI_LDBL_64);
1846void PPCLinuxAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
1847 if (!Subtarget->isPPC64())
1848 return PPCAsmPrinter::emitInstruction(
MI);
1850 switch (
MI->getOpcode()) {
1853 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1868 (void)
F.getFnAttribute(
"patchable-function-entry")
1870 .getAsInteger(10, Num);
1872 if (!MAI->isLittleEndian() || Num)
1874 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1875 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1876 OutStreamer->emitLabel(BeginOfSled);
1877 EmitToStreamer(*OutStreamer,
1878 MCInstBuilder(PPC::B).addExpr(
1880 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1883 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1884 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1885 EmitToStreamer(*OutStreamer,
1886 MCInstBuilder(PPC::BL8_NOP)
1888 OutContext.getOrCreateSymbol(
"__xray_FunctionEntry"),
1890 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1891 OutStreamer->emitLabel(EndOfSled);
1892 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_ENTER, 2);
1895 case TargetOpcode::PATCHABLE_RET: {
1896 unsigned RetOpcode =
MI->getOperand(0).getImm();
1906 if (RetOpcode == PPC::BCCLR) {
1907 IsConditional =
true;
1908 }
else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1909 RetOpcode == PPC::TCRETURNai8) {
1911 }
else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1912 IsConditional =
false;
1914 EmitToStreamer(*OutStreamer, RetInst);
1919 if (IsConditional) {
1938 FallthroughLabel = OutContext.createTempSymbol();
1941 MCInstBuilder(PPC::BCC)
1944 .addReg(
MI->getOperand(2).getReg())
1961 OutStreamer->emitCodeAlignment(
Align(8), &getSubtargetInfo());
1962 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1963 OutStreamer->emitLabel(BeginOfSled);
1964 EmitToStreamer(*OutStreamer, RetInst);
1965 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1968 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1969 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1970 EmitToStreamer(*OutStreamer,
1971 MCInstBuilder(PPC::BL8_NOP)
1973 OutContext.getOrCreateSymbol(
"__xray_FunctionExit"),
1975 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1976 EmitToStreamer(*OutStreamer, RetInst);
1978 OutStreamer->emitLabel(FallthroughLabel);
1979 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_EXIT, 2);
1982 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1984 case TargetOpcode::PATCHABLE_TAIL_CALL:
1988 "around this assert.");
1990 return PPCAsmPrinter::emitInstruction(
MI);
1993void PPCLinuxAsmPrinter::emitStartOfAsmFile(
Module &M) {
1994 if (
static_cast<const PPCTargetMachine &
>(TM).isELFv2ABI()) {
1995 PPCTargetStreamer *TS =
1996 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
2000 if (
static_cast<const PPCTargetMachine &
>(TM).isPPC64() ||
2001 !isPositionIndependent())
2007 OutStreamer->switchSection(OutContext.getELFSection(
2010 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(
".LTOC"));
2011 MCSymbol *CurrentPos = OutContext.createTempSymbol();
2013 OutStreamer->emitLabel(CurrentPos);
2017 const MCExpr *tocExpr =
2022 OutStreamer->emitAssignment(TOCSym, tocExpr);
2024 OutStreamer->switchSection(getObjFileLowering().getTextSection());
2027void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
2029 if (!Subtarget->isPPC64() &&
2030 (!isPositionIndependent() ||
2034 if (!Subtarget->isPPC64()) {
2035 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
2036 if (PPCFI->
usesPICBase() && !Subtarget->isSecurePlt()) {
2038 MCSymbol *PICBase = MF->getPICBaseSymbol();
2039 OutStreamer->emitLabel(RelocSymbol);
2041 const MCExpr *OffsExpr =
2047 OutStreamer->emitValue(OffsExpr, 4);
2048 OutStreamer->emitLabel(CurrentFnSym);
2061 && !MF->getRegInfo().use_empty(PPC::X2)) {
2062 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
2064 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(
".TOC."));
2066 const MCExpr *TOCDeltaExpr =
2073 OutStreamer->emitValue(TOCDeltaExpr, 8);
2080 MCSectionELF *
Section = OutStreamer->getContext().getELFSection(
2082 OutStreamer->switchSection(Section);
2083 OutStreamer->emitLabel(CurrentFnSym);
2084 OutStreamer->emitValueToAlignment(
Align(8));
2085 MCSymbol *Symbol1 = CurrentFnSymForSize;
2090 MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(
".TOC."));
2092 OutStreamer->emitValue(
2095 OutStreamer->emitIntValue(0, 8 );
2096 OutStreamer->switchSection(Current.first, Current.second);
2099void PPCLinuxAsmPrinter::emitEndOfAsmFile(
Module &M) {
2100 const DataLayout &
DL = getDataLayout();
2102 bool isPPC64 =
DL.getPointerSizeInBits() == 64;
2104 PPCTargetStreamer *TS =
2105 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
2111 if (
static_cast<const PPCTargetMachine &
>(TM).hasGlibcHWCAPAccess())
2112 OutStreamer->emitSymbolValue(
2113 GetExternalSymbolSymbol(
"__parse_hwcap_and_convert_at_platform"),
2114 MAI->getCodePointerSize());
2115 emitGNUAttributes(M);
2118 const char *
Name = isPPC64 ?
".toc" :
".got2";
2119 MCSectionELF *
Section = OutContext.getELFSection(
2121 OutStreamer->switchSection(Section);
2123 OutStreamer->emitValueToAlignment(
Align(4));
2125 for (
const auto &TOCMapPair : TOC) {
2126 const MCSymbol *
const TOCEntryTarget = TOCMapPair.first.first;
2127 MCSymbol *
const TOCEntryLabel = TOCMapPair.second;
2129 OutStreamer->emitLabel(TOCEntryLabel);
2131 TS->
emitTCEntry(*TOCEntryTarget, TOCMapPair.first.second);
2133 OutStreamer->emitSymbolValue(TOCEntryTarget, 4);
2137 PPCAsmPrinter::emitEndOfAsmFile(M);
2141void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
2173 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
2174 const bool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) ||
2175 !MF->getRegInfo().use_empty(PPC::R2);
2184 if (NonPCrelGEPRequired || PCrelGEPRequired) {
2189 OutStreamer->emitLabel(GlobalEntryLabel);
2190 const MCSymbolRefExpr *GlobalEntryLabelExp =
2194 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(
".TOC."));
2195 const MCExpr *TOCDeltaExpr =
2197 GlobalEntryLabelExp, OutContext);
2199 const MCExpr *TOCDeltaHi =
2201 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
2204 .addExpr(TOCDeltaHi));
2206 const MCExpr *TOCDeltaLo =
2208 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
2211 .addExpr(TOCDeltaLo));
2214 const MCExpr *TOCOffsetDeltaExpr =
2216 GlobalEntryLabelExp, OutContext);
2218 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
2220 .addExpr(TOCOffsetDeltaExpr)
2222 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8)
2229 OutStreamer->emitLabel(LocalEntryLabel);
2230 const MCSymbolRefExpr *LocalEntryLabelExp =
2232 const MCExpr *LocalOffsetExp =
2234 GlobalEntryLabelExp, OutContext);
2236 PPCTargetStreamer *TS =
2237 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
2262 if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() ||
2263 MF->hasInlineAsm() || (!PPCFI->
usesTOCBasePtr() && UsesX2OrR2)) {
2264 PPCTargetStreamer *TS =
2265 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
2275void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
2283 if (Subtarget->isPPC64()) {
2284 OutStreamer->emitIntValue(0, 4);
2285 OutStreamer->emitIntValue(0, 8);
2289char PPCLinuxAsmPrinter::ID = 0;
2292 "Linux PPC Assembly Printer",
false,
false)
2297 switch (GV->getLinkage()) {
2298 case GlobalValue::ExternalLinkage:
2299 LinkageAttr = GV->isDeclaration() ? MCSA_Extern : MCSA_Global;
2301 case GlobalValue::LinkOnceAnyLinkage:
2302 case GlobalValue::LinkOnceODRLinkage:
2303 case GlobalValue::WeakAnyLinkage:
2304 case GlobalValue::WeakODRLinkage:
2305 case GlobalValue::ExternalWeakLinkage:
2306 LinkageAttr = MCSA_Weak;
2308 case GlobalValue::AvailableExternallyLinkage:
2309 LinkageAttr = MCSA_Extern;
2311 case GlobalValue::PrivateLinkage:
2313 case GlobalValue::InternalLinkage:
2314 assert(GV->getVisibility() == GlobalValue::DefaultVisibility &&
2315 "InternalLinkage should not have other visibility setting.");
2316 LinkageAttr = MCSA_LGlobal;
2318 case GlobalValue::AppendingLinkage:
2319 llvm_unreachable(
"Should never emit this");
2320 case GlobalValue::CommonLinkage:
2321 llvm_unreachable(
"CommonLinkage of XCOFF should not come to this path");
2327 if (!TM.getIgnoreXCOFFVisibility()) {
2328 if (GV->hasDLLExportStorageClass() && !GV->hasDefaultVisibility())
2330 "Cannot not be both dllexport and non-default visibility");
2331 switch (GV->getVisibility()) {
2334 case GlobalValue::DefaultVisibility:
2335 if (GV->hasDLLExportStorageClass())
2336 VisibilityAttr = MAI->getExportedVisibilityAttr();
2338 case GlobalValue::HiddenVisibility:
2339 VisibilityAttr = MAI->getHiddenVisibilityAttr();
2341 case GlobalValue::ProtectedVisibility:
2342 VisibilityAttr = MAI->getProtectedVisibilityAttr();
2352 OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,
2356void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
2358 auto *FnDescSec =
static_cast<MCSectionXCOFF *
>(
2359 getObjFileLowering().getSectionForFunctionDescriptor(&MF.
getFunction(),
2361 FnDescSec->setAlignment(
Align(Subtarget->isPPC64() ? 8 : 4));
2363 CurrentFnDescSym = FnDescSec->getQualNameSymbol();
2368uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
2372 const PPCSubtarget &Subtarget = MF->
getSubtarget<PPCSubtarget>();
2373 if (Subtarget.
isAIXABI() && Subtarget.hasAltivec() &&
2374 TM.getAIXExtendedAltivecABI()) {
2375 const MachineRegisterInfo &MRI = MF->
getRegInfo();
2376 for (
unsigned Reg = PPC::V20;
Reg <= PPC::V31; ++
Reg)
2379 return PPC::V31 -
Reg + 1;
2384void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
2386 if (!TM.getXCOFFTracebackTable())
2389 emitTracebackTable();
2397 (getNumberOfVRSaved() > 0)) {
2399 OutStreamer->switchSection(getObjFileLowering().getCompactUnwindSection());
2402 OutStreamer->emitLabel(EHInfoLabel);
2405 OutStreamer->emitInt32(0);
2407 const DataLayout &
DL = MMI->getModule()->getDataLayout();
2410 OutStreamer->emitValueToAlignment(
Align(PointerSize));
2412 OutStreamer->emitIntValue(0, PointerSize);
2413 OutStreamer->emitIntValue(0, PointerSize);
2414 OutStreamer->switchSection(MF->
getSection());
2418void PPCAIXAsmPrinter::emitTracebackTable() {
2422 OutStreamer->emitLabel(FuncEnd);
2424 OutStreamer->AddComment(
"Traceback table begin");
2426 OutStreamer->emitIntValueInHexWithPadding(0, 4 );
2428 SmallString<128> CommentString;
2429 raw_svector_ostream CommentOS(CommentString);
2431 auto EmitComment = [&]() {
2432 OutStreamer->AddComment(CommentOS.str());
2433 CommentString.
clear();
2436 auto EmitCommentAndValue = [&](uint64_t
Value,
int Size) {
2438 OutStreamer->emitIntValueInHexWithPadding(
Value,
Size);
2442 CommentOS <<
"Version = " <<
Version;
2443 EmitCommentAndValue(
Version, 1);
2453 CommentOS <<
"Language = "
2455 EmitCommentAndValue(LanguageIdentifier, 1);
2458 uint32_t FirstHalfOfMandatoryField = 0;
2465 const PPCFunctionInfo *FI = MF->
getInfo<PPCFunctionInfo>();
2466 const MachineRegisterInfo &MRI = MF->
getRegInfo();
2469 for (
unsigned Reg = PPC::F0;
Reg <= PPC::F31; ++
Reg) {
2470 if (MRI.isPhysRegUsed(
Reg,
true)) {
2476#define GENBOOLCOMMENT(Prefix, V, Field) \
2477 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
2480#define GENVALUECOMMENT(PrefixAndName, V, Field) \
2481 CommentOS << (PrefixAndName) << " = " \
2482 << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
2483 (TracebackTable::Field##Shift))
2486 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);
2489 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasTraceBackTableOffset);
2490 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsInternalProcedure);
2493 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasControlledStorage);
2497 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsFloatingPointPresent);
2500 IsFloatingPointOperationLogOrAbortEnabled);
2503 OutStreamer->emitIntValueInHexWithPadding(
2504 (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2511 if (FrameReg == (Subtarget->isPPC64() ? PPC::X31 : PPC::R31))
2514 const SmallVectorImpl<Register> &MustSaveCRs = FI->
getMustSaveCRs();
2515 if (!MustSaveCRs.
empty())
2521 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsInterruptHandler);
2522 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);
2526 OnConditionDirective);
2530 OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),
2534 uint32_t SecondHalfOfMandatoryField = 0;
2540 uint32_t FPRSaved = 0;
2541 for (
unsigned Reg = PPC::F14;
Reg <= PPC::F31; ++
Reg) {
2542 if (MRI.isPhysRegModified(
Reg)) {
2543 FPRSaved = PPC::F31 -
Reg + 1;
2549 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, IsBackChainStored);
2551 GENVALUECOMMENT(
", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
2553 OutStreamer->emitIntValueInHexWithPadding(
2554 (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
2560 bool HasVectorInst =
false;
2561 for (
unsigned Reg = PPC::V0;
Reg <= PPC::V31; ++
Reg)
2562 if (MRI.isPhysRegUsed(
Reg,
true)) {
2564 HasVectorInst =
true;
2571 uint16_t NumOfVRSaved = getNumberOfVRSaved();
2572 bool ShouldEmitEHBlock =
2575 if (ShouldEmitEHBlock)
2578 uint32_t GPRSaved = 0;
2581 unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13;
2582 unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31;
2584 for (
unsigned Reg = GPRBegin;
Reg <= GPREnd; ++
Reg) {
2585 if (MRI.isPhysRegModified(
Reg)) {
2586 GPRSaved = GPREnd -
Reg + 1;
2594 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, HasExtensionTable);
2596 GENVALUECOMMENT(
", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
2598 OutStreamer->emitIntValueInHexWithPadding(
2599 (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
2603 SecondHalfOfMandatoryField |=
2607 NumberOfFixedParms);
2609 OutStreamer->emitIntValueInHexWithPadding(
2610 (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2618 SecondHalfOfMandatoryField |=
2623 NumberOfFloatingPointParms);
2624 GENBOOLCOMMENT(
", ", SecondHalfOfMandatoryField, HasParmsOnStack);
2626 OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
2632 if (NumberOfFixedParms || NumberOfFPParms) {
2635 Expected<SmallString<32>> ParmsType =
2638 ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
2645 CommentOS <<
"Parameter type = " << ParmsType.
get();
2648 OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
2649 sizeof(ParmsTypeValue));
2652 OutStreamer->AddComment(
"Function size");
2654 MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
2656 OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
2668 int16_t NameLength =
Name.size();
2669 CommentOS <<
"Function name len = "
2670 <<
static_cast<unsigned int>(NameLength);
2671 EmitCommentAndValue(NameLength, 2);
2672 OutStreamer->AddComment(
"Function Name");
2673 OutStreamer->emitBytes(Name);
2678 OutStreamer->AddComment(
"AllocaUsed");
2679 OutStreamer->emitIntValueInHex(AllocReg,
sizeof(AllocReg));
2683 uint16_t VRData = 0;
2712 OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
2717 OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
2721 Expected<SmallString<32>> VecParmsType =
2725 CommentOS <<
"Vector Parameter type = " << VecParmsType.
get();
2728 OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
2729 sizeof(VecParmTypeValue));
2731 CommentOS <<
"Padding";
2732 EmitCommentAndValue(0, 2);
2735 uint8_t ExtensionTableFlag = 0;
2737 if (ShouldEmitEHBlock)
2738 ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
2741 ExtensionTableFlag |= ExtendedTBTableFlag::TB_SSP_CANARY;
2743 CommentOS <<
"ExtensionTableFlag = "
2745 EmitCommentAndValue(ExtensionTableFlag,
sizeof(ExtensionTableFlag));
2748 if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
2749 auto &Ctx = OutStreamer->getContext();
2752 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym, TOCType_EHBlock);
2753 const MCSymbol *TOCBaseSym =
static_cast<const MCSectionXCOFF *
>(
2754 getObjFileLowering().getTOCBaseSection())
2755 ->getQualNameSymbol();
2760 const DataLayout &
DL = getDataLayout();
2761 OutStreamer->emitValueToAlignment(
Align(4));
2762 OutStreamer->AddComment(
"EHInfo Table");
2763 OutStreamer->emitValue(Exp,
DL.getPointerSize());
2765#undef GENBOOLCOMMENT
2766#undef GENVALUECOMMENT
2775 .
Case(
"llvm.used",
true)
2777 .
Case(
"llvm.compiler.used",
true)
2783 .
Cases({
"llvm.global_ctors",
"llvm.global_dtors"},
true)
2787uint64_t PPCAIXAsmPrinter::getAliasOffset(
const Constant *
C) {
2789 return getAliasOffset(GA->getAliasee());
2800 return RHS->getValue();
2810 "GlobalVariables with an alignment requirement stricter than TOC entry "
2811 "size not supported by the toc data transformation.");
2814 assert(GVType->
isSized() &&
"A GlobalVariable's size must be known to be "
2815 "supported by the toc data transformation.");
2819 "A GlobalVariable with size larger than a TOC entry is not currently "
2820 "supported by the toc data transformation.");
2823 "currently supported by the toc data transformation.");
2826void PPCAIXAsmPrinter::emitGlobalVariable(
const GlobalVariable *GV) {
2844 emitGlobalVariableHelper(GV);
2847void PPCAIXAsmPrinter::emitGlobalVariableHelper(
const GlobalVariable *GV) {
2849 "Unhandled intrinsic global variable.");
2854 auto *GVSym =
static_cast<MCSymbolXCOFF *
>(getSymbol(GV));
2857 emitLinkage(GV, GVSym);
2861 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
2865 "not supported yet.");
2872 OutStreamer->getCommentOS() <<
'\n';
2876 auto *Csect =
static_cast<MCSectionXCOFF *
>(
2877 getObjFileLowering().SectionForGlobal(GV, GVKind, TM));
2880 OutStreamer->switchSection(Csect);
2882 if (GV->
hasMetadata(LLVMContext::MD_implicit_ref)) {
2883 emitRefMetadata(GV);
2893 GVSym->setStorageClass(
2897 OutStreamer->emitZeros(
Size);
2900 "BSS local toc-data already handled and TLS variables "
2901 "incompatible with XMC_TD");
2902 OutStreamer->emitXCOFFLocalCommonSymbol(
2903 OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()),
Size,
2906 OutStreamer->emitCommonSymbol(GVSym,
Size, Alignment);
2914 emitLinkage(GV, EmittedInitSym);
2915 for (
const GlobalAlias *GA : GOAliasMap[GV])
2916 emitLinkage(GA, getSymbol(GA));
2918 emitAlignment(getGVAlignment(GV,
DL), GV);
2922 if (!TM.getDataSections() || GV->hasSection()) {
2924 OutStreamer->emitLabel(EmittedInitSym);
2928 if (!GOAliasMap[GV].
size()) {
2929 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer());
2935 AliasMapTy AliasList;
2936 for (
const GlobalAlias *GA : GOAliasMap[GV])
2937 AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);
2940 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer(),
2944void PPCAIXAsmPrinter::emitFunctionDescriptor() {
2945 const DataLayout &
DL = getDataLayout();
2946 const unsigned PointerSize =
DL.getPointerSizeInBits() == 64 ? 8 : 4;
2950 OutStreamer->switchSection(
2951 static_cast<MCSymbolXCOFF *
>(CurrentFnDescSym)->getRepresentedCsect());
2956 for (
const GlobalAlias *Alias : GOAliasMap[&MF->
getFunction()])
2957 OutStreamer->emitLabel(getSymbol(Alias));
2963 const MCSymbol *TOCBaseSym =
static_cast<const MCSectionXCOFF *
>(
2964 getObjFileLowering().getTOCBaseSection())
2965 ->getQualNameSymbol();
2969 OutStreamer->emitIntValue(0, PointerSize);
2971 OutStreamer->switchSection(Current.first, Current.second);
2974void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2978 PPCAsmPrinter::emitFunctionEntryLabel();
2986 for (
const GlobalAlias *Alias : GOAliasMap[
F])
2987 OutStreamer->emitLabel(
2988 getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM));
2990 if (
F->hasMetadata(LLVMContext::MD_implicit_ref)) {
2995void PPCAIXAsmPrinter::emitPGORefs(
Module &M) {
2996 if (!OutContext.hasXCOFFSection(
3007 bool HasNonZeroLengthPrfCntsSection =
false;
3008 const DataLayout &
DL =
M.getDataLayout();
3009 for (GlobalVariable &GV :
M.globals())
3010 if (GV.hasSection() && GV.getSection() ==
"__llvm_prf_cnts" &&
3011 GV.getGlobalSize(
DL) > 0) {
3012 HasNonZeroLengthPrfCntsSection =
true;
3016 if (HasNonZeroLengthPrfCntsSection) {
3017 MCSection *CntsSection = OutContext.getXCOFFSection(
3022 OutStreamer->switchSection(CntsSection);
3023 if (OutContext.hasXCOFFSection(
3026 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_data[RW]");
3027 OutStreamer->emitXCOFFRefDirective(S);
3029 if (OutContext.hasXCOFFSection(
3032 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_names[RO]");
3033 OutStreamer->emitXCOFFRefDirective(S);
3035 if (OutContext.hasXCOFFSection(
3038 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_vnds[RW]");
3039 OutStreamer->emitXCOFFRefDirective(S);
3044void PPCAIXAsmPrinter::emitGCOVRefs() {
3045 if (!OutContext.hasXCOFFSection(
3046 "__llvm_gcov_ctr_section",
3050 MCSection *CtrSection = OutContext.getXCOFFSection(
3055 OutStreamer->switchSection(CtrSection);
3058 if (OutContext.hasXCOFFSection(
3061 const char *SymbolStr = TM.Options.XCOFFReadOnlyPointers
3062 ?
"__llvm_covinit[RO]"
3063 :
"__llvm_covinit[RW]";
3064 MCSymbol *S = OutContext.getOrCreateSymbol(SymbolStr);
3065 OutStreamer->emitXCOFFRefDirective(S);
3069void PPCAIXAsmPrinter::emitEndOfAsmFile(
Module &M) {
3072 if (
M.empty() && TOCDataGlobalVars.
empty())
3079 OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());
3081 PPCTargetStreamer *TS =
3082 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
3084 for (
auto &
I : TOC) {
3085 MCSectionXCOFF *TCEntry;
3092 (Subtarget->hasAIXShLibTLSModelOpt() &&
3094 SmallString<128>
Name;
3097 Name +=
static_cast<const MCSymbolXCOFF *
>(
I.first.first)
3098 ->getSymbolTableName();
3099 MCSymbol *S = OutContext.getOrCreateSymbol(Name);
3100 TCEntry =
static_cast<MCSectionXCOFF *
>(
3101 getObjFileLowering().getSectionForTOCEntry(S, TM));
3103 TCEntry =
static_cast<MCSectionXCOFF *
>(
3104 getObjFileLowering().getSectionForTOCEntry(
I.first.first, TM));
3106 OutStreamer->switchSection(TCEntry);
3108 OutStreamer->emitLabel(
I.second);
3115 for (
const auto *GV : TOCDataGlobalVars) {
3116 if (!GV->hasCommonLinkage())
3117 emitGlobalVariableHelper(GV);
3119 for (
const auto *GV : TOCDataGlobalVars) {
3120 if (GV->hasCommonLinkage())
3121 emitGlobalVariableHelper(GV);
3125bool PPCAIXAsmPrinter::doInitialization(
Module &M) {
3126 const bool Result = PPCAsmPrinter::doInitialization(M);
3129 const Triple &
Target = TM.getTargetTriple();
3136 if (FunCpuId > TargetCpuId)
3137 TargetCpuId = FunCpuId;
3143 StringRef TargetCPU = TM.getTargetCPU();
3148 PPCTargetStreamer *TS =
3149 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
3152 auto setCsectAlignment = [
this](
const GlobalObject *GO) {
3154 if (GO->isDeclarationForLinker())
3157 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);
3158 auto *Csect =
static_cast<MCSectionXCOFF *
>(
3159 getObjFileLowering().SectionForGlobal(GO, GOKind, TM));
3161 Align GOAlign = getGVAlignment(GO, GO->getDataLayout());
3162 Csect->ensureMinAlignment(GOAlign);
3168 uint64_t TLSVarAddress = 0;
3169 auto DL =
M.getDataLayout();
3170 for (
const auto &
G :
M.globals()) {
3171 if (
G.isThreadLocal() && !
G.isDeclaration()) {
3172 TLSVarAddress =
alignTo(TLSVarAddress, getGVAlignment(&
G,
DL));
3173 TLSVarsToAddressMapping[&
G] = TLSVarAddress;
3174 TLSVarAddress +=
G.getGlobalSize(
DL);
3181 for (
const auto &
G :
M.globals()) {
3188 if (FormatIndicatorAndUniqueModId.empty()) {
3190 if (UniqueModuleId !=
"")
3194 FormatIndicatorAndUniqueModId =
"clang_" + UniqueModuleId.substr(1);
3199 std::chrono::duration_cast<std::chrono::nanoseconds>(
3200 std::chrono::steady_clock::now().time_since_epoch())
3202 FormatIndicatorAndUniqueModId =
3209 emitSpecialLLVMGlobal(&
G);
3213 setCsectAlignment(&
G);
3214 std::optional<CodeModel::Model> OptionalCodeModel =
G.getCodeModel();
3215 if (OptionalCodeModel)
3217 *OptionalCodeModel);
3220 for (
const auto &
F : M)
3221 setCsectAlignment(&
F);
3224 for (
const auto &Alias :
M.aliases()) {
3225 const GlobalObject *Aliasee = Alias.getAliaseeObject();
3228 "alias without a base object is not yet supported on AIX");
3232 "\n\tAlias attribute for " +
3233 Alias.getName() +
" is invalid because " +
3234 Aliasee->
getName() +
" is common.",
3238 const GlobalVariable *GVar =
3241 std::optional<CodeModel::Model> OptionalCodeModel = GVar->
getCodeModel();
3242 if (OptionalCodeModel)
3244 *OptionalCodeModel);
3247 GOAliasMap[Aliasee].push_back(&Alias);
3253void PPCAIXAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
3254 switch (
MI->getOpcode()) {
3261 if (
MI->getNumOperands() < 5)
3263 const MachineOperand &LangMO =
MI->getOperand(3);
3264 const MachineOperand &ReasonMO =
MI->getOperand(4);
3267 MCSymbol *TempSym = OutContext.createNamedTempSymbol();
3268 OutStreamer->emitLabel(TempSym);
3269 OutStreamer->emitXCOFFExceptDirective(
3270 CurrentFnSym, TempSym, LangMO.
getImm(), ReasonMO.
getImm(),
3271 Subtarget->isPPC64() ?
MI->getMF()->getInstructionCount() * 8
3272 :
MI->getMF()->getInstructionCount() * 4,
3276 case PPC::GETtlsMOD32AIX:
3277 case PPC::GETtlsMOD64AIX:
3278 case PPC::GETtlsTpointer32AIX:
3279 case PPC::GETtlsADDR64AIX:
3280 case PPC::GETtlsADDR32AIX: {
3285 ExtSymSDNodeSymbols.
insert(TlsGetAddr);
3292 const MachineOperand &MO =
MI->getOperand(0);
3294 auto *S =
static_cast<MCSymbolXCOFF *
>(
3296 ExtSymSDNodeSymbols.
insert(S);
3302 case PPC::BL8_NOP_TLS:
3309 case PPC::TAILBCTR8:
3310 if (
MI->getOperand(0).isSymbol())
3323 MCInstBuilder(PPC::ORI).addReg(PPC::R0).addReg(PPC::R0).addImm(0));
3326 return PPCAsmPrinter::emitInstruction(
MI);
3329bool PPCAIXAsmPrinter::doFinalization(
Module &M) {
3330 for (MCSymbol *Sym : ExtSymSDNodeSymbols)
3331 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Extern);
3332 return PPCAsmPrinter::doFinalization(M);
3343 return 20 + (
P - 20) * 16;
3346 return 1004 + (
P - 81);
3349 return 2047 + (
P - 1124) * 33878;
3351 return 2147482625u + (
P - 64512);
3370 std::string PrioritySuffix;
3373 return PrioritySuffix;
3376void PPCAIXAsmPrinter::emitXXStructorList(
const DataLayout &
DL,
3377 const Constant *
List,
bool IsCtor) {
3379 preprocessXXStructorList(
DL,
List, Structors);
3380 if (Structors.
empty())
3384 for (Structor &S : Structors) {
3386 S.Func =
CE->getOperand(0);
3390 (IsCtor ? llvm::Twine(
"__sinit") : llvm::Twine(
"__sterm")) +
3392 llvm::Twine(
"_", FormatIndicatorAndUniqueModId) +
3398void PPCAIXAsmPrinter::emitTTypeReference(
const GlobalValue *GV,
3399 unsigned Encoding) {
3401 TOCEntryType GlobalType = TOCType_GlobalInternal;
3406 GlobalType = TOCType_GlobalExternal;
3407 MCSymbol *TypeInfoSym = TM.getSymbol(GV);
3408 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym, GlobalType);
3409 const MCSymbol *TOCBaseSym =
static_cast<const MCSectionXCOFF *
>(
3410 getObjFileLowering().getTOCBaseSection())
3411 ->getQualNameSymbol();
3412 auto &Ctx = OutStreamer->getContext();
3416 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
3418 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
3421void PPCAIXAsmPrinter::emitRefMetadata(
const GlobalObject *GO) {
3423 GO->
getMetadata(LLVMContext::MD_implicit_ref, MDs);
3424 assert(MDs.
size() &&
"Expected !implicit.ref metadata nodes");
3426 for (
const MDNode *MD : MDs) {
3431 ? getObjFileLowering().getFunctionEntryPointSymbol(GV, TM)
3433 OutStreamer->emitXCOFFRefDirective(Referenced);
3441 std::unique_ptr<MCStreamer> &&Streamer) {
3443 return new PPCAIXAsmPrinter(tm, std::move(Streamer));
3445 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
3448void PPCAIXAsmPrinter::emitModuleCommandLines(
Module &M) {
3449 const NamedMDNode *NMD =
M.getNamedMetadata(
"llvm.commandline");
3454 raw_string_ostream RSOS(S);
3457 assert(
N->getNumOperands() == 1 &&
3458 "llvm.commandline metadata entry can have only one operand");
3462 RSOS <<
"@(#)opt " << MDS->
getString() <<
"\n";
3465 OutStreamer->emitXCOFFCInfoSym(
".GCC.command.line", RSOS.str());
3469 enum class IsLocal {
3481 if (
LHS == IsLocal::False ||
RHS == IsLocal::False)
3482 return IsLocal::False;
3483 if (
LHS == IsLocal::True &&
RHS == IsLocal::True)
3484 return IsLocal::True;
3485 return IsLocal::Unknown;
3489 auto IsLocalFunc = [](
const Function *
F) -> IsLocal {
3490 bool Result =
F->isDSOLocal();
3492 << (Result ?
"dso_local\n" :
"not dso_local\n"));
3493 return Result ? IsLocal::True : IsLocal::False;
3502 std::function<IsLocal(
const Value *)> ValueIsALocalFunc =
3503 [&IsLocalFunc, &
Combine, &ValueIsALocalFunc](
const Value *V) -> IsLocal {
3505 return IsLocalFunc(
F);
3507 return IsLocal::Unknown;
3512 return Combine(ValueIsALocalFunc(
SI->getTrueValue()),
3513 ValueIsALocalFunc(
SI->getFalseValue()));
3515 IsLocal Res = IsLocal::True;
3516 for (
unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
3517 Res =
Combine(Res, ValueIsALocalFunc(PN->getIncomingValue(i)));
3518 if (Res == IsLocal::False)
3533 return IsLocal::Unknown;
3536 return IsLocal::Unknown;
3538 IsLocal Res = IsLocal::True;
3539 for (
unsigned Idx = 0, End =
Init->getNumOperands(); Idx != End; ++Idx) {
3540 Res =
Combine(Res, ValueIsALocalFunc(
Init->getOperand(Idx)));
3541 if (Res == IsLocal::False)
3546 return IsLocal::Unknown;
3556 IsLocal Res = IsLocal::True;
3561 Value *RV = Ret->getReturnValue();
3563 Res =
Combine(Res, ValueIsALocalFunc(RV));
3564 if (Res == IsLocal::False)
3593void PPCAIXAsmPrinter::emitGlobalIFunc(
Module &M,
const GlobalIFunc &GI) {
3595 const TargetSubtargetInfo *STI =
3597 bool IsPPC64 =
static_cast<const PPCSubtarget *
>(STI)->isPPC64();
3602 MCSectionXCOFF *FnDescSec =
static_cast<MCSectionXCOFF *
>(
3603 getObjFileLowering().getSectionForFunctionDescriptor(&GI, TM));
3608 CurrentFnSym = getObjFileLowering().getFunctionEntryPointSymbol(&GI, TM);
3611 if (TM.getFunctionSections())
3612 OutStreamer->switchSection(
3613 static_cast<MCSymbolXCOFF *
>(CurrentFnSym)->getRepresentedCsect());
3615 OutStreamer->switchSection(getObjFileLowering().getTextSection());
3618 emitRefMetadata(&GI);
3621 emitLinkage(&GI, CurrentFnDescSym);
3622 emitLinkage(&GI, CurrentFnSym);
3626 emitAlignment(Alignment,
nullptr);
3629 emitFunctionDescriptor();
3631 emitFunctionEntryLabel();
3635 Twine Msg =
"unimplemented: TOC register save/restore needed for ifunc \"" +
3637 "\", because couldn't prove all candidates "
3638 "are static or hidden/protected visibility definitions";
3642 dbgs() << Msg <<
"\n";
3646 auto *FnDescTOCEntrySym =
3647 lookUpOrCreateTOCEntry(CurrentFnDescSym, FnDescTOCEntryType);
3652 auto *Exp_U = symbolWithSpecifier(FnDescTOCEntrySym,
PPC::S_U);
3653 OutStreamer->emitInstruction(MCInstBuilder(PPC::ADDIS)
3658 auto *Exp_L = symbolWithSpecifier(FnDescTOCEntrySym,
PPC::S_L);
3659 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3669 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3676 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3678 .addImm(IsPPC64 ? 16 : 8)
3682 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3688 OutStreamer->emitInstruction(
3689 MCInstBuilder(IsPPC64 ? PPC::MTCTR8 : PPC::MTCTR).addReg(PPC::X12),
3692 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::BCTR8 : PPC::BCTR),
3696char PPCAIXAsmPrinter::ID = 0;
3699 "AIX PPC Assembly Printer",
false,
false)
3703LLVMInitializePowerPCAsmPrinter() {
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.
LLVM_ABI bool isPhysRegModified(MCRegister PhysReg, bool SkipNoReturnDef=false) const
Return true if the specified register is modified in this function.
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