88#define DEBUG_TYPE "asmprinter"
90STATISTIC(NumTOCEntries,
"Number of Total TOC Entries Emitted.");
91STATISTIC(NumTOCConstPool,
"Number of Constant Pool TOC Entries.");
93 "Number of Internal Linkage Global TOC Entries.");
95 "Number of External Linkage Global TOC Entries.");
96STATISTIC(NumTOCJumpTable,
"Number of Jump Table TOC Entries.");
97STATISTIC(NumTOCThreadLocal,
"Number of Thread Local TOC Entries.");
98STATISTIC(NumTOCBlockAddress,
"Number of Block Address TOC Entries.");
99STATISTIC(NumTOCEHBlock,
"Number of EH Block TOC Entries.");
106 "ifunc-local-if-proven",
cl::init(
false),
107 cl::desc(
"During ifunc lowering, the compiler assumes the resolver returns "
108 "dso-local functions and bails out if non-local functions are "
109 "detected; this flag flips the assumption: resolver returns "
110 "preemptible functions unless the compiler can prove all paths "
111 "return local functions."),
125 using TOCKey = std::pair<const MCSymbol *, PPCMCExpr::Specifier>;
144 Tag_GNU_Power_ABI_FP = 4,
145 Tag_GNU_Power_ABI_Vector = 8,
146 Tag_GNU_Power_ABI_Struct_Return = 12,
149 Val_GNU_Power_ABI_NoFloat = 0b00,
150 Val_GNU_Power_ABI_HardFloat_DP = 0b01,
151 Val_GNU_Power_ABI_SoftFloat_DP = 0b10,
152 Val_GNU_Power_ABI_HardFloat_SP = 0b11,
154 Val_GNU_Power_ABI_LDBL_IBM128 = 0b0100,
155 Val_GNU_Power_ABI_LDBL_64 = 0b1000,
156 Val_GNU_Power_ABI_LDBL_IEEE128 = 0b1100,
168 MapVector<std::pair<const MCSymbol *, PPCMCExpr::Specifier>,
MCSymbol *> TOC;
169 const PPCSubtarget *Subtarget =
nullptr;
174 MapVector<const GlobalValue *, uint64_t> TLSVarsToAddressMapping;
177 explicit PPCAsmPrinter(TargetMachine &TM,
178 std::unique_ptr<MCStreamer> Streamer,
char &
ID)
179 : AsmPrinter(TM, std::
move(Streamer),
ID) {}
181 StringRef getPassName()
const override {
return "PowerPC Assembly Printer"; }
184 TOCType_ConstantPool,
185 TOCType_GlobalExternal,
186 TOCType_GlobalInternal,
189 TOCType_BlockAddress,
193 MCSymbol *lookUpOrCreateTOCEntry(
const MCSymbol *Sym, TOCEntryType
Type,
196 bool doInitialization(
Module &M)
override {
202 const MCExpr *symbolWithSpecifier(
const MCSymbol *S,
209 void printOperand(
const MachineInstr *
MI,
unsigned OpNo, raw_ostream &O);
211 void PrintSymbolOperand(
const MachineOperand &MO, raw_ostream &O)
override;
212 bool PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
213 const char *ExtraCode, raw_ostream &O)
override;
214 bool PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNo,
215 const char *ExtraCode, raw_ostream &O)
override;
217 void LowerSTACKMAP(StackMaps &
SM,
const MachineInstr &
MI);
218 void LowerPATCHPOINT(StackMaps &
SM,
const MachineInstr &
MI);
220 void EmitAIXTlsCallHelper(
const MachineInstr *
MI);
221 const MCExpr *getAdjustedFasterLocalExpr(
const MachineOperand &MO,
223 bool runOnMachineFunction(MachineFunction &MF)
override {
232class PPCLinuxAsmPrinter :
public PPCAsmPrinter {
236 explicit PPCLinuxAsmPrinter(TargetMachine &TM,
237 std::unique_ptr<MCStreamer> Streamer)
238 : PPCAsmPrinter(TM, std::
move(Streamer), ID) {}
240 StringRef getPassName()
const override {
241 return "Linux PPC Assembly Printer";
244 void emitGNUAttributes(
Module &M);
246 void emitStartOfAsmFile(
Module &M)
override;
247 void emitEndOfAsmFile(
Module &)
override;
249 void emitFunctionEntryLabel()
override;
251 void emitFunctionBodyStart()
override;
252 void emitFunctionBodyEnd()
override;
256class PPCAIXAsmPrinter :
public PPCAsmPrinter {
260 SmallSetVector<MCSymbol *, 8> ExtSymSDNodeSymbols;
264 std::string FormatIndicatorAndUniqueModId;
268 DenseMap<const GlobalObject *, SmallVector<const GlobalAlias *, 1>>
271 uint16_t getNumberOfVRSaved();
272 void emitTracebackTable();
276 void emitGlobalVariableHelper(
const GlobalVariable *);
279 uint64_t getAliasOffset(
const Constant *
C);
284 PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
285 : PPCAsmPrinter(TM, std::
move(Streamer), ID) {
286 if (MAI->isLittleEndian())
288 "cannot create AIX PPC Assembly Printer for a little-endian target");
291 StringRef getPassName()
const override {
return "AIX PPC Assembly Printer"; }
293 bool doInitialization(
Module &M)
override;
295 void emitXXStructorList(
const DataLayout &
DL,
const Constant *
List,
296 bool IsCtor)
override;
298 void SetupMachineFunction(MachineFunction &MF)
override;
300 void emitGlobalVariable(
const GlobalVariable *GV)
override;
302 void emitFunctionDescriptor()
override;
304 void emitFunctionEntryLabel()
override;
306 void emitFunctionBodyEnd()
override;
308 void emitPGORefs(
Module &M);
312 void emitEndOfAsmFile(
Module &)
override;
314 void emitLinkage(
const GlobalValue *GV, MCSymbol *GVSym)
const override;
318 bool doFinalization(
Module &M)
override;
320 void emitTTypeReference(
const GlobalValue *GV,
unsigned Encoding)
override;
322 void emitModuleCommandLines(
Module &M)
override;
324 void emitRefMetadata(
const GlobalObject *);
326 void emitGlobalIFunc(
Module &M,
const GlobalIFunc &GI)
override;
335 getSymbol(GV)->
print(O, MAI);
339void PPCAsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNo,
341 const DataLayout &
DL = getDataLayout();
342 const MachineOperand &MO =
MI->getOperand(OpNo);
362 O <<
DL.getInternalSymbolPrefix() <<
"CPI" << getFunctionNumber() <<
'_'
369 PrintSymbolOperand(MO, O);
374 O <<
"<unknown operand type: " << (unsigned)MO.
getType() <<
">";
381bool PPCAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
382 const char *ExtraCode, raw_ostream &O) {
384 if (ExtraCode && ExtraCode[0]) {
385 if (ExtraCode[1] != 0)
return true;
387 switch (ExtraCode[0]) {
393 if (!
MI->getOperand(OpNo).isReg() ||
394 OpNo+1 ==
MI->getNumOperands() ||
395 !
MI->getOperand(OpNo+1).isReg())
402 if (
MI->getOperand(OpNo).isImm())
406 if(!
MI->getOperand(OpNo).isReg())
412 Reg = PPC::VSX32 + (
Reg - PPC::V0);
414 Reg = PPC::VSX32 + (
Reg - PPC::VF0);
430bool PPCAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNo,
431 const char *ExtraCode,
433 if (ExtraCode && ExtraCode[0]) {
434 if (ExtraCode[1] != 0)
return true;
436 switch (ExtraCode[0]) {
437 default:
return true;
439 O << getDataLayout().getPointerSize() <<
"(";
450 if (
MI->getOperand(OpNo).isImm())
461 assert(
MI->getOperand(OpNo).isReg());
466 assert(
MI->getOperand(OpNo).isReg());
476 case PPCAsmPrinter::TOCType_ConstantPool:
479 case PPCAsmPrinter::TOCType_GlobalInternal:
480 ++NumTOCGlobalInternal;
482 case PPCAsmPrinter::TOCType_GlobalExternal:
483 ++NumTOCGlobalExternal;
485 case PPCAsmPrinter::TOCType_JumpTable:
488 case PPCAsmPrinter::TOCType_ThreadLocal:
491 case PPCAsmPrinter::TOCType_BlockAddress:
492 ++NumTOCBlockAddress;
494 case PPCAsmPrinter::TOCType_EHBlock:
511 assert(GV &&
"expected global for MO_GlobalAddress");
532MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(
const MCSymbol *Sym,
536 auto [It,
Inserted] =
TOC.try_emplace({Sym, Spec});
542 TOCEntry = createTempSymbol(
"C");
546void PPCAsmPrinter::LowerSTACKMAP(StackMaps &
SM,
const MachineInstr &
MI) {
547 unsigned NumNOPBytes =
MI.getOperand(1).getImm();
549 auto &Ctx = OutStreamer->getContext();
550 MCSymbol *MILabel = Ctx.createTempSymbol();
551 OutStreamer->emitLabel(MILabel);
553 SM.recordStackMap(*MILabel,
MI);
554 assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
557 const MachineBasicBlock &
MBB = *
MI.getParent();
560 while (NumNOPBytes > 0) {
561 if (MII ==
MBB.
end() || MII->isCall() ||
562 MII->getOpcode() == PPC::DBG_VALUE ||
563 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
564 MII->getOpcode() == TargetOpcode::STACKMAP)
571 for (
unsigned i = 0; i < NumNOPBytes; i += 4)
572 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
577void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &
SM,
const MachineInstr &
MI) {
578 auto &Ctx = OutStreamer->getContext();
579 MCSymbol *MILabel = Ctx.createTempSymbol();
580 OutStreamer->emitLabel(MILabel);
582 SM.recordPatchPoint(*MILabel,
MI);
583 PatchPointOpers Opers(&
MI);
585 unsigned EncodedBytes = 0;
586 const MachineOperand &CalleeMO = Opers.getCallTarget();
588 if (CalleeMO.
isImm()) {
589 int64_t CallTarget = CalleeMO.
getImm();
591 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
592 "High 16 bits of call target should be zero.");
593 Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
596 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8)
598 .addImm((CallTarget >> 32) & 0xFFFF));
601 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC)
604 .addImm(32).addImm(16));
607 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8)
610 .addImm((CallTarget >> 16) & 0xFFFF));
613 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8)
616 .addImm(CallTarget & 0xFFFF));
621 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD)
623 .addImm(TOCSaveOffset)
633 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
636 .addReg(ScratchReg));
639 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
642 .addReg(ScratchReg));
646 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8)
647 .addReg(ScratchReg));
650 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8));
654 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
656 .addImm(TOCSaveOffset)
661 const GlobalValue *GValue = CalleeMO.
getGlobal();
662 MCSymbol *MOSymbol = getSymbol(GValue);
665 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP)
674 unsigned NumBytes = Opers.getNumPatchBytes();
675 if (NumBytes < EncodedBytes)
677 "Patchpoint can't request size less than the length of a call.");
679 assert((NumBytes - EncodedBytes) % 4 == 0 &&
680 "Invalid number of NOP bytes requested!");
681 for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
682 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
692 SymName =
".__tls_get_addr";
694 case PPC::GETtlsTpointer32AIX:
695 SymName =
".__get_tpointer";
697 case PPC::GETtlsMOD32AIX:
698 case PPC::GETtlsMOD64AIX:
699 SymName =
".__tls_get_mod";
705 ->getQualNameSymbol();
708void PPCAsmPrinter::EmitAIXTlsCallHelper(
const MachineInstr *
MI) {
710 "Only expecting to emit calls to get the thread pointer on AIX!");
714 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BLA).addExpr(TlsRef));
719void PPCAsmPrinter::emitTlsCall(
const MachineInstr *
MI,
722 unsigned Opcode = PPC::BL8_NOP_TLS;
724 assert(
MI->getNumOperands() >= 3 &&
"Expecting at least 3 operands from MI");
728 Opcode = PPC::BL8_NOTOC_TLS;
730 const Module *
M = MF->getFunction().getParent();
733 ((Subtarget->isPPC64() &&
MI->getOperand(0).getReg() == PPC::X3) ||
734 (!Subtarget->isPPC64() &&
MI->getOperand(0).getReg() == PPC::R3)) &&
735 "GETtls[ld]ADDR[32] must define GPR3");
737 ((Subtarget->isPPC64() &&
MI->getOperand(1).getReg() == PPC::X3) ||
738 (!Subtarget->isPPC64() &&
MI->getOperand(1).getReg() == PPC::R3)) &&
739 "GETtls[ld]ADDR[32] must read GPR3");
746 Register VarOffsetReg = Subtarget->isPPC64() ? PPC::X4 : PPC::R4;
748 assert((
MI->getOpcode() == PPC::GETtlsMOD32AIX ||
749 MI->getOpcode() == PPC::GETtlsMOD64AIX ||
750 (
MI->getOperand(2).isReg() &&
751 MI->getOperand(2).getReg() == VarOffsetReg)) &&
752 "GETtls[ld]ADDR[32] must read GPR4");
753 EmitAIXTlsCallHelper(
MI);
757 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(
"__tls_get_addr");
765 if (Kind ==
PPC::S_PLT && Subtarget->isSecurePlt() &&
769 const MachineOperand &MO =
MI->getOperand(2);
770 const GlobalValue *GValue = MO.
getGlobal();
771 MCSymbol *MOSymbol = getSymbol(GValue);
773 EmitToStreamer(*OutStreamer,
774 MCInstBuilder(Subtarget->isPPC64() ? Opcode
775 : (
unsigned)PPC::BL_TLS)
798static PPCAsmPrinter::TOCEntryType
803 return PPCAsmPrinter::TOCType_GlobalExternal;
805 return PPCAsmPrinter::TOCType_GlobalInternal;
808static PPCAsmPrinter::TOCEntryType
813 return PPCAsmPrinter::TOCType_ThreadLocal;
821 return PPCAsmPrinter::TOCType_ConstantPool;
823 return PPCAsmPrinter::TOCType_JumpTable;
825 return PPCAsmPrinter::TOCType_BlockAddress;
831const MCExpr *PPCAsmPrinter::symbolWithSpecifier(
const MCSymbol *S,
839void PPCAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
840 PPC_MC::verifyInstructionPredicates(
MI->getOpcode(),
841 getSubtargetInfo().getFeatureBits());
844 const bool IsPPC64 = Subtarget->isPPC64();
845 const bool IsAIX = Subtarget->
isAIXABI();
846 const bool HasAIXSmallLocalTLS = Subtarget->hasAIXSmallLocalExecTLS() ||
847 Subtarget->hasAIXSmallLocalDynamicTLS();
848 const Module *
M = MF->getFunction().getParent();
853 if (!
MI->isInlineAsm()) {
854 for (
const MachineOperand &MO:
MI->operands()) {
857 if (Subtarget->hasSPE()) {
875 auto getTOCRelocAdjustedExprForXCOFF = [
this](
const MCExpr *Expr,
876 ptrdiff_t OriginalOffset) {
883 ptrdiff_t Adjustment =
889 auto getTOCEntryLoadingExprForXCOFF =
890 [IsPPC64, getTOCRelocAdjustedExprForXCOFF,
891 this](
const MCSymbol *MOSymbol,
const MCExpr *Expr,
893 const unsigned EntryByteSize = IsPPC64 ? 8 : 4;
894 const auto TOCEntryIter =
TOC.find({MOSymbol, VK});
896 "Could not find the TOC entry for this symbol.");
897 const ptrdiff_t EntryDistanceFromTOCBase =
898 (TOCEntryIter -
TOC.begin()) * EntryByteSize;
899 constexpr int16_t PositiveTOCRange = INT16_MAX;
901 if (EntryDistanceFromTOCBase > PositiveTOCRange)
902 return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase);
914 assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!\n");
922 PPCFunctionInfo *FuncInfo = MF->getInfo<PPCFunctionInfo>();
926 dbgs() <<
"Current function uses IE access for default LD vars.\n");
949 switch (
MI->getOpcode()) {
951 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
953 "AIX does not support patchable function entry!");
956 (void)
F.getFnAttribute(
"patchable-function-entry")
958 .getAsInteger(10, Num);
964 case TargetOpcode::DBG_VALUE:
966 case TargetOpcode::STACKMAP:
967 return LowerSTACKMAP(
SM, *
MI);
968 case TargetOpcode::PATCHPOINT:
969 return LowerPATCHPOINT(
SM, *
MI);
971 case PPC::MoveGOTtoLR: {
979 OutContext.getOrCreateSymbol(StringRef(
"_GLOBAL_OFFSET_TABLE_"));
985 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));
988 case PPC::MovePCtoLR:
989 case PPC::MovePCtoLR8: {
994 MCSymbol *PICBase = MF->getPICBaseSymbol();
997 EmitToStreamer(*OutStreamer,
998 MCInstBuilder(PPC::BCLalways)
1004 OutStreamer->emitLabel(PICBase);
1007 case PPC::UpdateGBR: {
1016 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
1018 MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
1027 const MCExpr *DeltaHi =
1031 MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));
1033 const MCExpr *DeltaLo =
1037 MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
1041 MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol(*MF);
1048 const MCOperand PICR = TmpInst.
getOperand(0);
1055 EmitToStreamer(*OutStreamer, TmpInst);
1061 EmitToStreamer(*OutStreamer, TmpInst);
1072 const MachineOperand &MO =
MI->getOperand(1);
1074 "Invalid operand for LWZtoc.");
1082 const MCExpr *
Exp = symbolWithSpecifier(MOSymbol,
PPC::S_GOT);
1084 EmitToStreamer(*OutStreamer, TmpInst);
1103 "This pseudo should only be selected for 32-bit small code model.");
1104 Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK);
1109 OutStreamer->getCommentOS() << MO <<
'\n';
1110 EmitToStreamer(*OutStreamer, TmpInst);
1117 OutContext.getOrCreateSymbol(Twine(
".LTOC")), OutContext);
1120 EmitToStreamer(*OutStreamer, TmpInst);
1124 case PPC::ADDItoc8: {
1126 "PseudoOp only valid for small code model AIX");
1132 TmpInst.
setOpcode((!IsPPC64) ? (PPC::LA) : (PPC::LA8));
1134 const MachineOperand &MO =
MI->getOperand(2);
1143 EmitToStreamer(*OutStreamer, TmpInst);
1156 const MachineOperand &MO =
MI->getOperand(1);
1158 "Invalid operand!");
1172 const MCExpr *
Exp = symbolWithSpecifier(TOCEntry, VKExpr);
1174 IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK) : Exp);
1177 if (isVerbose() && IsAIX)
1178 OutStreamer->getCommentOS() << MO <<
'\n';
1179 EmitToStreamer(*OutStreamer, TmpInst);
1182 case PPC::ADDIStocHA: {
1183 const MachineOperand &MO =
MI->getOperand(2);
1186 "Invalid operand for ADDIStocHA.");
1187 assert((IsAIX && !IsPPC64 &&
1189 "This pseudo should only be selected for 32-bit large code model on"
1209 if ( {
1221 const MCExpr *
Exp = symbolWithSpecifier(MOSymbol,
PPC::S_U);
1223 EmitToStreamer(*OutStreamer, TmpInst);
1226 case PPC::LWZtocL: {
1227 const MachineOperand &MO =
MI->getOperand(1);
1230 "Invalid operand for LWZtocL.");
1231 assert(IsAIX && !IsPPC64 &&
1233 "This pseudo should only be selected for 32-bit large code model on"
1253 const MCExpr *
Exp = symbolWithSpecifier(TOCEntry,
PPC::S_L);
1255 EmitToStreamer(*OutStreamer, TmpInst);
1258 case PPC::ADDIStocHA8: {
1268 const MachineOperand &MO =
MI->getOperand(2);
1270 "Invalid operand for ADDIStocHA8!");
1276 const bool GlobalToc =
1288 const MCExpr *
Exp = symbolWithSpecifier(MOSymbol, VK);
1297 EmitToStreamer(*OutStreamer, TmpInst);
1310 const MachineOperand &MO =
MI->getOperand(1);
1313 "Invalid operand for LDtocL!");
1317 "LDtocL used on symbol that could be accessed directly is "
1318 "invalid. Must match ADDIStocHA8."));
1329 const MCExpr *
Exp = symbolWithSpecifier(MOSymbol, VK);
1331 EmitToStreamer(*OutStreamer, TmpInst);
1335 case PPC::ADDItocL8: {
1339 unsigned Op =
MI->getOpcode();
1343 TmpInst.
setOpcode(
Op == PPC::ADDItocL8 ? (IsAIX ? PPC::LA8 : PPC::ADDI8)
1346 const MachineOperand &MO =
MI->getOperand(2);
1349 : MO.
isGlobal() &&
"Invalid operand for ADDItocL8.");
1351 "Interposable definitions must use indirect accesses.");
1360 EmitToStreamer(*OutStreamer, TmpInst);
1363 case PPC::ADDISgotTprelHA: {
1366 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1367 const MachineOperand &MO =
MI->getOperand(2);
1368 const GlobalValue *GValue = MO.
getGlobal();
1369 MCSymbol *MOSymbol = getSymbol(GValue);
1370 const MCExpr *SymGotTprel =
1372 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1373 .addReg(
MI->getOperand(0).getReg())
1374 .addReg(
MI->getOperand(1).getReg())
1375 .addExpr(SymGotTprel));
1378 case PPC::LDgotTprelL:
1379 case PPC::LDgotTprelL32: {
1384 TmpInst.
setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ);
1385 const MachineOperand &MO =
MI->getOperand(1);
1386 const GlobalValue *GValue = MO.
getGlobal();
1387 MCSymbol *MOSymbol = getSymbol(GValue);
1388 const MCExpr *
Exp = symbolWithSpecifier(
1391 EmitToStreamer(*OutStreamer, TmpInst);
1395 case PPC::PPC32PICGOT: {
1396 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1397 MCSymbol *GOTRef = OutContext.createTempSymbol();
1398 MCSymbol *NextInstr = OutContext.createTempSymbol();
1400 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL)
1404 const MCExpr *OffsExpr =
1408 OutStreamer->emitLabel(GOTRef);
1409 OutStreamer->emitValue(OffsExpr, 4);
1410 OutStreamer->emitLabel(NextInstr);
1411 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR)
1412 .addReg(
MI->getOperand(0).getReg()));
1413 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
1414 .addReg(
MI->getOperand(1).getReg())
1416 .addReg(
MI->getOperand(0).getReg()));
1417 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4)
1418 .addReg(
MI->getOperand(0).getReg())
1419 .addReg(
MI->getOperand(1).getReg())
1420 .addReg(
MI->getOperand(0).getReg()));
1423 case PPC::PPC32GOT: {
1425 OutContext.getOrCreateSymbol(StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1426 const MCExpr *SymGotTlsL =
1428 const MCExpr *SymGotTlsHA =
1430 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI)
1431 .addReg(
MI->getOperand(0).getReg())
1432 .addExpr(SymGotTlsL));
1433 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
1434 .addReg(
MI->getOperand(0).getReg())
1435 .addReg(
MI->getOperand(0).getReg())
1436 .addExpr(SymGotTlsHA));
1439 case PPC::ADDIStlsgdHA: {
1442 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1443 const MachineOperand &MO =
MI->getOperand(2);
1444 const GlobalValue *GValue = MO.
getGlobal();
1445 MCSymbol *MOSymbol = getSymbol(GValue);
1446 const MCExpr *SymGotTlsGD =
1448 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1449 .addReg(
MI->getOperand(0).getReg())
1450 .addReg(
MI->getOperand(1).getReg())
1451 .addExpr(SymGotTlsGD));
1454 case PPC::ADDItlsgdL:
1457 case PPC::ADDItlsgdL32: {
1460 const MachineOperand &MO =
MI->getOperand(2);
1461 const GlobalValue *GValue = MO.
getGlobal();
1462 MCSymbol *MOSymbol = getSymbol(GValue);
1463 const MCExpr *SymGotTlsGD = symbolWithSpecifier(
1465 EmitToStreamer(*OutStreamer,
1466 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1467 .addReg(
MI->getOperand(0).getReg())
1468 .addReg(
MI->getOperand(1).getReg())
1469 .addExpr(SymGotTlsGD));
1472 case PPC::GETtlsMOD32AIX:
1473 case PPC::GETtlsMOD64AIX:
1477 case PPC::GETtlsADDR:
1480 case PPC::GETtlsADDRPCREL:
1481 case PPC::GETtlsADDR32AIX:
1482 case PPC::GETtlsADDR64AIX:
1486 case PPC::GETtlsADDR32: {
1492 case PPC::GETtlsTpointer32AIX: {
1495 EmitAIXTlsCallHelper(
MI);
1498 case PPC::ADDIStlsldHA: {
1501 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1502 const MachineOperand &MO =
MI->getOperand(2);
1503 const GlobalValue *GValue = MO.
getGlobal();
1504 MCSymbol *MOSymbol = getSymbol(GValue);
1505 const MCExpr *SymGotTlsLD =
1507 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1508 .addReg(
MI->getOperand(0).getReg())
1509 .addReg(
MI->getOperand(1).getReg())
1510 .addExpr(SymGotTlsLD));
1513 case PPC::ADDItlsldL:
1516 case PPC::ADDItlsldL32: {
1519 const MachineOperand &MO =
MI->getOperand(2);
1520 const GlobalValue *GValue = MO.
getGlobal();
1521 MCSymbol *MOSymbol = getSymbol(GValue);
1522 const MCExpr *SymGotTlsLD = symbolWithSpecifier(
1524 EmitToStreamer(*OutStreamer,
1525 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1526 .addReg(
MI->getOperand(0).getReg())
1527 .addReg(
MI->getOperand(1).getReg())
1528 .addExpr(SymGotTlsLD));
1531 case PPC::GETtlsldADDR:
1534 case PPC::GETtlsldADDRPCREL:
1535 case PPC::GETtlsldADDR32: {
1541 case PPC::ADDISdtprelHA:
1544 case PPC::ADDISdtprelHA32: {
1547 const MachineOperand &MO =
MI->getOperand(2);
1548 const GlobalValue *GValue = MO.
getGlobal();
1549 MCSymbol *MOSymbol = getSymbol(GValue);
1553 MCInstBuilder(IsPPC64 ? PPC::ADDIS8 : PPC::ADDIS)
1554 .addReg(
MI->getOperand(0).getReg())
1555 .addReg(
MI->getOperand(1).getReg())
1556 .addExpr(SymDtprel));
1559 case PPC::PADDIdtprel: {
1562 const MachineOperand &MO =
MI->getOperand(2);
1563 const GlobalValue *GValue = MO.
getGlobal();
1564 MCSymbol *MOSymbol = getSymbol(GValue);
1565 const MCExpr *SymDtprel = symbolWithSpecifier(MOSymbol,
PPC::S_DTPREL);
1566 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::PADDI8)
1567 .addReg(
MI->getOperand(0).getReg())
1568 .addReg(
MI->getOperand(1).getReg())
1569 .addExpr(SymDtprel));
1573 case PPC::ADDIdtprelL:
1576 case PPC::ADDIdtprelL32: {
1579 const MachineOperand &MO =
MI->getOperand(2);
1580 const GlobalValue *GValue = MO.
getGlobal();
1581 MCSymbol *MOSymbol = getSymbol(GValue);
1583 EmitToStreamer(*OutStreamer,
1584 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1585 .addReg(
MI->getOperand(0).getReg())
1586 .addReg(
MI->getOperand(1).getReg())
1587 .addExpr(SymDtprel));
1592 if (!Subtarget->hasMFOCRF()) {
1595 unsigned NewOpcode =
1596 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
1597 OutStreamer->AddComment(PPCInstPrinter::
1599 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1600 .addReg(
MI->getOperand(0).getReg()));
1606 if (!Subtarget->hasMFOCRF()) {
1609 unsigned NewOpcode =
1610 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1611 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
1612 ->getEncodingValue(
MI->getOperand(0).getReg());
1613 OutStreamer->AddComment(PPCInstPrinter::
1615 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1617 .addReg(
MI->getOperand(1).getReg()));
1627 unsigned OpNum = (
MI->getOpcode() == PPC::STD) ? 2 : 1;
1631 for (
const MachineOperand &TempMO :
MI->operands()) {
1634 TempMO.getOperandNo() == 1)
1637 const MachineOperand &MO =
MI->getOperand(OpNum);
1671 if (!HasAIXSmallLocalTLS)
1673 bool IsMIADDI8 =
MI->getOpcode() == PPC::ADDI8;
1674 unsigned OpNum = IsMIADDI8 ? 2 : 1;
1675 const MachineOperand &MO =
MI->getOperand(OpNum);
1682 const MCExpr *Expr = getAdjustedFasterLocalExpr(MO, MO.
getOffset());
1690 EmitToStreamer(*OutStreamer, TmpInst);
1696 case PPC::PseudoEIEIO: {
1699 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1702 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1703 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::EnforceIEIO));
1707 case PPC::BL8_NOP: {
1708 const MachineOperand &MO =
MI->getOperand(0);
1711 Name.consume_front(
".");
1712 Name.consume_back(
"[PR]");
1713 bool IsLWAT =
Name ==
"__lwat_csne_pseudo";
1714 bool IsLDAT =
Name ==
"__ldat_csne_pseudo";
1715 if (IsLWAT || IsLDAT) {
1716 EmitToStreamer(*OutStreamer,
1717 MCInstBuilder(IsLWAT ? PPC::LWAT : PPC::LDAT)
1730 EmitToStreamer(*OutStreamer, TmpInst);
1740PPCAsmPrinter::getAdjustedFasterLocalExpr(
const MachineOperand &MO,
1747 assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!");
1748 const GlobalValue *GValue = MO.
getGlobal();
1751 "Only local-[exec|dynamic] accesses are handled!");
1757 const auto TLSVarsMapEntryIter = TLSVarsToAddressMapping.
find(GValue);
1758 if (TLSVarsMapEntryIter == TLSVarsToAddressMapping.
end())
1759 assert(IsGlobalADeclaration &&
1760 "Only expecting to find extern TLS variables not present in the TLS "
1761 "variable-to-address map!");
1763 unsigned TLSVarAddress =
1764 IsGlobalADeclaration ? 0 : TLSVarsMapEntryIter->second;
1765 ptrdiff_t FinalAddress = (TLSVarAddress +
Offset);
1777 if (FinalAddress >= 32768) {
1784 ptrdiff_t Delta = ((FinalAddress + 32768) & ~0xFFFF);
1786 [[maybe_unused]] ptrdiff_t InstDisp = TLSVarAddress +
Offset - Delta;
1788 ((InstDisp < 32768) && (InstDisp >= -32768)) &&
1789 "Expecting the instruction displacement for local-[exec|dynamic] TLS "
1790 "variables to be between [-32768, 32768)!");
1798void PPCLinuxAsmPrinter::emitGNUAttributes(
Module &M) {
1800 Metadata *MD =
M.getModuleFlag(
"float-abi");
1806 if (flt ==
"doubledouble")
1807 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1808 Val_GNU_Power_ABI_HardFloat_DP |
1809 Val_GNU_Power_ABI_LDBL_IBM128);
1810 else if (flt ==
"ieeequad")
1811 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1812 Val_GNU_Power_ABI_HardFloat_DP |
1813 Val_GNU_Power_ABI_LDBL_IEEE128);
1814 else if (flt ==
"ieeedouble")
1815 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1816 Val_GNU_Power_ABI_HardFloat_DP |
1817 Val_GNU_Power_ABI_LDBL_64);
1820void PPCLinuxAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
1821 if (!Subtarget->isPPC64())
1822 return PPCAsmPrinter::emitInstruction(
MI);
1824 switch (
MI->getOpcode()) {
1827 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1842 (void)
F.getFnAttribute(
"patchable-function-entry")
1844 .getAsInteger(10, Num);
1846 if (!MAI->isLittleEndian() || Num)
1848 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1849 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1850 OutStreamer->emitLabel(BeginOfSled);
1851 EmitToStreamer(*OutStreamer,
1852 MCInstBuilder(PPC::B).addExpr(
1854 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1857 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1858 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1859 EmitToStreamer(*OutStreamer,
1860 MCInstBuilder(PPC::BL8_NOP)
1862 OutContext.getOrCreateSymbol(
"__xray_FunctionEntry"),
1864 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1865 OutStreamer->emitLabel(EndOfSled);
1866 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_ENTER, 2);
1869 case TargetOpcode::PATCHABLE_RET: {
1870 unsigned RetOpcode =
MI->getOperand(0).getImm();
1880 if (RetOpcode == PPC::BCCLR) {
1881 IsConditional =
true;
1882 }
else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1883 RetOpcode == PPC::TCRETURNai8) {
1885 }
else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1886 IsConditional =
false;
1888 EmitToStreamer(*OutStreamer, RetInst);
1893 if (IsConditional) {
1912 FallthroughLabel = OutContext.createTempSymbol();
1915 MCInstBuilder(PPC::BCC)
1918 .addReg(
MI->getOperand(2).getReg())
1935 OutStreamer->emitCodeAlignment(
Align(8), &getSubtargetInfo());
1936 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1937 OutStreamer->emitLabel(BeginOfSled);
1938 EmitToStreamer(*OutStreamer, RetInst);
1939 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1942 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1943 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1944 EmitToStreamer(*OutStreamer,
1945 MCInstBuilder(PPC::BL8_NOP)
1947 OutContext.getOrCreateSymbol(
"__xray_FunctionExit"),
1949 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1950 EmitToStreamer(*OutStreamer, RetInst);
1952 OutStreamer->emitLabel(FallthroughLabel);
1953 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_EXIT, 2);
1956 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1958 case TargetOpcode::PATCHABLE_TAIL_CALL:
1962 "around this assert.");
1964 return PPCAsmPrinter::emitInstruction(
MI);
1967void PPCLinuxAsmPrinter::emitStartOfAsmFile(
Module &M) {
1968 if (
static_cast<const PPCTargetMachine &
>(TM).isELFv2ABI()) {
1969 PPCTargetStreamer *TS =
1970 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
1974 if (
static_cast<const PPCTargetMachine &
>(TM).isPPC64() ||
1975 !isPositionIndependent())
1981 OutStreamer->switchSection(OutContext.getELFSection(
1984 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(
".LTOC"));
1985 MCSymbol *CurrentPos = OutContext.createTempSymbol();
1987 OutStreamer->emitLabel(CurrentPos);
1991 const MCExpr *tocExpr =
1996 OutStreamer->emitAssignment(TOCSym, tocExpr);
1998 OutStreamer->switchSection(getObjFileLowering().getTextSection());
2001void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
2003 if (!Subtarget->isPPC64() &&
2004 (!isPositionIndependent() ||
2008 if (!Subtarget->isPPC64()) {
2009 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
2010 if (PPCFI->
usesPICBase() && !Subtarget->isSecurePlt()) {
2012 MCSymbol *PICBase = MF->getPICBaseSymbol();
2013 OutStreamer->emitLabel(RelocSymbol);
2015 const MCExpr *OffsExpr =
2021 OutStreamer->emitValue(OffsExpr, 4);
2022 OutStreamer->emitLabel(CurrentFnSym);
2035 && !MF->getRegInfo().use_empty(PPC::X2)) {
2036 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
2038 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(
".TOC."));
2040 const MCExpr *TOCDeltaExpr =
2047 OutStreamer->emitValue(TOCDeltaExpr, 8);
2054 MCSectionELF *
Section = OutStreamer->getContext().getELFSection(
2056 OutStreamer->switchSection(Section);
2057 OutStreamer->emitLabel(CurrentFnSym);
2058 OutStreamer->emitValueToAlignment(
Align(8));
2059 MCSymbol *Symbol1 = CurrentFnSymForSize;
2064 MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(
".TOC."));
2066 OutStreamer->emitValue(
2069 OutStreamer->emitIntValue(0, 8 );
2070 OutStreamer->switchSection(Current.first, Current.second);
2073void PPCLinuxAsmPrinter::emitEndOfAsmFile(
Module &M) {
2074 const DataLayout &
DL = getDataLayout();
2076 bool isPPC64 =
DL.getPointerSizeInBits() == 64;
2078 PPCTargetStreamer *TS =
2079 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
2085 if (
static_cast<const PPCTargetMachine &
>(TM).hasGlibcHWCAPAccess())
2086 OutStreamer->emitSymbolValue(
2087 GetExternalSymbolSymbol(
"__parse_hwcap_and_convert_at_platform"),
2088 MAI->getCodePointerSize());
2089 emitGNUAttributes(M);
2092 const char *
Name = isPPC64 ?
".toc" :
".got2";
2093 MCSectionELF *
Section = OutContext.getELFSection(
2095 OutStreamer->switchSection(Section);
2097 OutStreamer->emitValueToAlignment(
Align(4));
2099 for (
const auto &TOCMapPair : TOC) {
2100 const MCSymbol *
const TOCEntryTarget = TOCMapPair.first.first;
2101 MCSymbol *
const TOCEntryLabel = TOCMapPair.second;
2103 OutStreamer->emitLabel(TOCEntryLabel);
2105 TS->
emitTCEntry(*TOCEntryTarget, TOCMapPair.first.second);
2107 OutStreamer->emitSymbolValue(TOCEntryTarget, 4);
2111 PPCAsmPrinter::emitEndOfAsmFile(M);
2115void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
2147 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
2148 const bool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) ||
2149 !MF->getRegInfo().use_empty(PPC::R2);
2158 if (NonPCrelGEPRequired || PCrelGEPRequired) {
2163 OutStreamer->emitLabel(GlobalEntryLabel);
2164 const MCSymbolRefExpr *GlobalEntryLabelExp =
2168 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(
".TOC."));
2169 const MCExpr *TOCDeltaExpr =
2171 GlobalEntryLabelExp, OutContext);
2173 const MCExpr *TOCDeltaHi =
2175 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
2178 .addExpr(TOCDeltaHi));
2180 const MCExpr *TOCDeltaLo =
2182 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
2185 .addExpr(TOCDeltaLo));
2188 const MCExpr *TOCOffsetDeltaExpr =
2190 GlobalEntryLabelExp, OutContext);
2192 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
2194 .addExpr(TOCOffsetDeltaExpr)
2196 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8)
2203 OutStreamer->emitLabel(LocalEntryLabel);
2204 const MCSymbolRefExpr *LocalEntryLabelExp =
2206 const MCExpr *LocalOffsetExp =
2208 GlobalEntryLabelExp, OutContext);
2210 PPCTargetStreamer *TS =
2211 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
2236 if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() ||
2237 MF->hasInlineAsm() || (!PPCFI->
usesTOCBasePtr() && UsesX2OrR2)) {
2238 PPCTargetStreamer *TS =
2239 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
2249void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
2257 if (Subtarget->isPPC64()) {
2258 OutStreamer->emitIntValue(0, 4);
2259 OutStreamer->emitIntValue(0, 8);
2263char PPCLinuxAsmPrinter::ID = 0;
2266 "Linux PPC Assembly Printer",
false,
false)
2271 switch (GV->getLinkage()) {
2272 case GlobalValue::ExternalLinkage:
2273 LinkageAttr = GV->isDeclaration() ? MCSA_Extern : MCSA_Global;
2275 case GlobalValue::LinkOnceAnyLinkage:
2276 case GlobalValue::LinkOnceODRLinkage:
2277 case GlobalValue::WeakAnyLinkage:
2278 case GlobalValue::WeakODRLinkage:
2279 case GlobalValue::ExternalWeakLinkage:
2280 LinkageAttr = MCSA_Weak;
2282 case GlobalValue::AvailableExternallyLinkage:
2283 LinkageAttr = MCSA_Extern;
2285 case GlobalValue::PrivateLinkage:
2287 case GlobalValue::InternalLinkage:
2288 assert(GV->getVisibility() == GlobalValue::DefaultVisibility &&
2289 "InternalLinkage should not have other visibility setting.");
2290 LinkageAttr = MCSA_LGlobal;
2292 case GlobalValue::AppendingLinkage:
2293 llvm_unreachable(
"Should never emit this");
2294 case GlobalValue::CommonLinkage:
2295 llvm_unreachable(
"CommonLinkage of XCOFF should not come to this path");
2301 if (!TM.getIgnoreXCOFFVisibility()) {
2302 if (GV->hasDLLExportStorageClass() && !GV->hasDefaultVisibility())
2304 "Cannot not be both dllexport and non-default visibility");
2305 switch (GV->getVisibility()) {
2308 case GlobalValue::DefaultVisibility:
2309 if (GV->hasDLLExportStorageClass())
2310 VisibilityAttr = MAI->getExportedVisibilityAttr();
2312 case GlobalValue::HiddenVisibility:
2313 VisibilityAttr = MAI->getHiddenVisibilityAttr();
2315 case GlobalValue::ProtectedVisibility:
2316 VisibilityAttr = MAI->getProtectedVisibilityAttr();
2326 OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,
2330void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
2332 auto *FnDescSec =
static_cast<MCSectionXCOFF *
>(
2333 getObjFileLowering().getSectionForFunctionDescriptor(&MF.
getFunction(),
2335 FnDescSec->setAlignment(
Align(Subtarget->isPPC64() ? 8 : 4));
2337 CurrentFnDescSym = FnDescSec->getQualNameSymbol();
2342uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
2346 const PPCSubtarget &Subtarget = MF->
getSubtarget<PPCSubtarget>();
2347 if (Subtarget.
isAIXABI() && Subtarget.hasAltivec() &&
2348 TM.getAIXExtendedAltivecABI()) {
2349 const MachineRegisterInfo &MRI = MF->
getRegInfo();
2350 for (
unsigned Reg = PPC::V20;
Reg <= PPC::V31; ++
Reg)
2353 return PPC::V31 -
Reg + 1;
2358void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
2360 if (!TM.getXCOFFTracebackTable())
2363 emitTracebackTable();
2371 (getNumberOfVRSaved() > 0)) {
2373 OutStreamer->switchSection(getObjFileLowering().getCompactUnwindSection());
2376 OutStreamer->emitLabel(EHInfoLabel);
2379 OutStreamer->emitInt32(0);
2381 const DataLayout &
DL = MMI->getModule()->getDataLayout();
2384 OutStreamer->emitValueToAlignment(
Align(PointerSize));
2386 OutStreamer->emitIntValue(0, PointerSize);
2387 OutStreamer->emitIntValue(0, PointerSize);
2388 OutStreamer->switchSection(MF->
getSection());
2392void PPCAIXAsmPrinter::emitTracebackTable() {
2396 OutStreamer->emitLabel(FuncEnd);
2398 OutStreamer->AddComment(
"Traceback table begin");
2400 OutStreamer->emitIntValueInHexWithPadding(0, 4 );
2402 SmallString<128> CommentString;
2403 raw_svector_ostream CommentOS(CommentString);
2405 auto EmitComment = [&]() {
2406 OutStreamer->AddComment(CommentOS.str());
2407 CommentString.
clear();
2410 auto EmitCommentAndValue = [&](uint64_t
Value,
int Size) {
2412 OutStreamer->emitIntValueInHexWithPadding(
Value,
Size);
2416 CommentOS <<
"Version = " <<
Version;
2417 EmitCommentAndValue(
Version, 1);
2427 CommentOS <<
"Language = "
2429 EmitCommentAndValue(LanguageIdentifier, 1);
2432 uint32_t FirstHalfOfMandatoryField = 0;
2439 const PPCFunctionInfo *FI = MF->
getInfo<PPCFunctionInfo>();
2440 const MachineRegisterInfo &MRI = MF->
getRegInfo();
2443 for (
unsigned Reg = PPC::F0;
Reg <= PPC::F31; ++
Reg) {
2444 if (MRI.isPhysRegUsed(
Reg,
true)) {
2450#define GENBOOLCOMMENT(Prefix, V, Field) \
2451 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
2454#define GENVALUECOMMENT(PrefixAndName, V, Field) \
2455 CommentOS << (PrefixAndName) << " = " \
2456 << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
2457 (TracebackTable::Field##Shift))
2460 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);
2463 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasTraceBackTableOffset);
2464 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsInternalProcedure);
2467 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasControlledStorage);
2471 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsFloatingPointPresent);
2474 IsFloatingPointOperationLogOrAbortEnabled);
2477 OutStreamer->emitIntValueInHexWithPadding(
2478 (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2485 if (FrameReg == (Subtarget->isPPC64() ? PPC::X31 : PPC::R31))
2488 const SmallVectorImpl<Register> &MustSaveCRs = FI->
getMustSaveCRs();
2489 if (!MustSaveCRs.
empty())
2495 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsInterruptHandler);
2496 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);
2500 OnConditionDirective);
2504 OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),
2508 uint32_t SecondHalfOfMandatoryField = 0;
2514 uint32_t FPRSaved = 0;
2515 for (
unsigned Reg = PPC::F14;
Reg <= PPC::F31; ++
Reg) {
2516 if (MRI.isPhysRegModified(
Reg)) {
2517 FPRSaved = PPC::F31 -
Reg + 1;
2523 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, IsBackChainStored);
2525 GENVALUECOMMENT(
", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
2527 OutStreamer->emitIntValueInHexWithPadding(
2528 (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
2534 bool HasVectorInst =
false;
2535 for (
unsigned Reg = PPC::V0;
Reg <= PPC::V31; ++
Reg)
2536 if (MRI.isPhysRegUsed(
Reg,
true)) {
2538 HasVectorInst =
true;
2545 uint16_t NumOfVRSaved = getNumberOfVRSaved();
2546 bool ShouldEmitEHBlock =
2549 if (ShouldEmitEHBlock)
2552 uint32_t GPRSaved = 0;
2555 unsigned GPRBegin = Subtarget->isPPC64() ? PPC::X14 : PPC::R13;
2556 unsigned GPREnd = Subtarget->isPPC64() ? PPC::X31 : PPC::R31;
2558 for (
unsigned Reg = GPRBegin;
Reg <= GPREnd; ++
Reg) {
2559 if (MRI.isPhysRegModified(
Reg)) {
2560 GPRSaved = GPREnd -
Reg + 1;
2568 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, HasExtensionTable);
2570 GENVALUECOMMENT(
", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
2572 OutStreamer->emitIntValueInHexWithPadding(
2573 (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
2577 SecondHalfOfMandatoryField |=
2581 NumberOfFixedParms);
2583 OutStreamer->emitIntValueInHexWithPadding(
2584 (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2592 SecondHalfOfMandatoryField |=
2597 NumberOfFloatingPointParms);
2598 GENBOOLCOMMENT(
", ", SecondHalfOfMandatoryField, HasParmsOnStack);
2600 OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
2606 if (NumberOfFixedParms || NumberOfFPParms) {
2609 Expected<SmallString<32>> ParmsType =
2612 ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
2619 CommentOS <<
"Parameter type = " << ParmsType.
get();
2622 OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
2623 sizeof(ParmsTypeValue));
2626 OutStreamer->AddComment(
"Function size");
2628 MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
2630 OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
2642 int16_t NameLength =
Name.size();
2643 CommentOS <<
"Function name len = "
2644 <<
static_cast<unsigned int>(NameLength);
2645 EmitCommentAndValue(NameLength, 2);
2646 OutStreamer->AddComment(
"Function Name");
2647 OutStreamer->emitBytes(Name);
2652 OutStreamer->AddComment(
"AllocaUsed");
2653 OutStreamer->emitIntValueInHex(AllocReg,
sizeof(AllocReg));
2657 uint16_t VRData = 0;
2686 OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
2691 OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
2695 Expected<SmallString<32>> VecParmsType =
2699 CommentOS <<
"Vector Parameter type = " << VecParmsType.
get();
2702 OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
2703 sizeof(VecParmTypeValue));
2705 CommentOS <<
"Padding";
2706 EmitCommentAndValue(0, 2);
2709 uint8_t ExtensionTableFlag = 0;
2711 if (ShouldEmitEHBlock)
2712 ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
2715 ExtensionTableFlag |= ExtendedTBTableFlag::TB_SSP_CANARY;
2717 CommentOS <<
"ExtensionTableFlag = "
2719 EmitCommentAndValue(ExtensionTableFlag,
sizeof(ExtensionTableFlag));
2722 if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
2723 auto &Ctx = OutStreamer->getContext();
2726 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym, TOCType_EHBlock);
2727 const MCSymbol *TOCBaseSym =
static_cast<const MCSectionXCOFF *
>(
2728 getObjFileLowering().getTOCBaseSection())
2729 ->getQualNameSymbol();
2734 const DataLayout &
DL = getDataLayout();
2735 OutStreamer->emitValueToAlignment(
Align(4));
2736 OutStreamer->AddComment(
"EHInfo Table");
2737 OutStreamer->emitValue(Exp,
DL.getPointerSize());
2739#undef GENBOOLCOMMENT
2740#undef GENVALUECOMMENT
2749 .
Case(
"llvm.used",
true)
2751 .
Case(
"llvm.compiler.used",
true)
2757 .
Cases({
"llvm.global_ctors",
"llvm.global_dtors"},
true)
2761uint64_t PPCAIXAsmPrinter::getAliasOffset(
const Constant *
C) {
2763 return getAliasOffset(GA->getAliasee());
2774 return RHS->getValue();
2784 "GlobalVariables with an alignment requirement stricter than TOC entry "
2785 "size not supported by the toc data transformation.");
2788 assert(GVType->
isSized() &&
"A GlobalVariable's size must be known to be "
2789 "supported by the toc data transformation.");
2793 "A GlobalVariable with size larger than a TOC entry is not currently "
2794 "supported by the toc data transformation.");
2797 "currently supported by the toc data transformation.");
2800void PPCAIXAsmPrinter::emitGlobalVariable(
const GlobalVariable *GV) {
2818 emitGlobalVariableHelper(GV);
2821void PPCAIXAsmPrinter::emitGlobalVariableHelper(
const GlobalVariable *GV) {
2823 "Unhandled intrinsic global variable.");
2828 auto *GVSym =
static_cast<MCSymbolXCOFF *
>(getSymbol(GV));
2831 emitLinkage(GV, GVSym);
2835 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
2839 "not supported yet.");
2846 OutStreamer->getCommentOS() <<
'\n';
2850 auto *Csect =
static_cast<MCSectionXCOFF *
>(
2851 getObjFileLowering().SectionForGlobal(GV, GVKind, TM));
2854 OutStreamer->switchSection(Csect);
2856 if (GV->
hasMetadata(LLVMContext::MD_implicit_ref)) {
2857 emitRefMetadata(GV);
2867 GVSym->setStorageClass(
2871 OutStreamer->emitZeros(
Size);
2874 "BSS local toc-data already handled and TLS variables "
2875 "incompatible with XMC_TD");
2876 OutStreamer->emitXCOFFLocalCommonSymbol(
2877 OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()),
Size,
2880 OutStreamer->emitCommonSymbol(GVSym,
Size, Alignment);
2888 emitLinkage(GV, EmittedInitSym);
2889 for (
const GlobalAlias *GA : GOAliasMap[GV])
2890 emitLinkage(GA, getSymbol(GA));
2892 emitAlignment(getGVAlignment(GV,
DL), GV);
2896 if (!TM.getDataSections() || GV->hasSection()) {
2898 OutStreamer->emitLabel(EmittedInitSym);
2902 if (!GOAliasMap[GV].
size()) {
2903 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer());
2909 AliasMapTy AliasList;
2910 for (
const GlobalAlias *GA : GOAliasMap[GV])
2911 AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);
2914 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer(),
2918void PPCAIXAsmPrinter::emitFunctionDescriptor() {
2919 const DataLayout &
DL = getDataLayout();
2920 const unsigned PointerSize =
DL.getPointerSizeInBits() == 64 ? 8 : 4;
2924 OutStreamer->switchSection(
2925 static_cast<MCSymbolXCOFF *
>(CurrentFnDescSym)->getRepresentedCsect());
2930 for (
const GlobalAlias *Alias : GOAliasMap[&MF->
getFunction()])
2931 OutStreamer->emitLabel(getSymbol(Alias));
2937 const MCSymbol *TOCBaseSym =
static_cast<const MCSectionXCOFF *
>(
2938 getObjFileLowering().getTOCBaseSection())
2939 ->getQualNameSymbol();
2943 OutStreamer->emitIntValue(0, PointerSize);
2945 OutStreamer->switchSection(Current.first, Current.second);
2948void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2952 PPCAsmPrinter::emitFunctionEntryLabel();
2960 for (
const GlobalAlias *Alias : GOAliasMap[
F])
2961 OutStreamer->emitLabel(
2962 getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM));
2964 if (
F->hasMetadata(LLVMContext::MD_implicit_ref)) {
2969void PPCAIXAsmPrinter::emitPGORefs(
Module &M) {
2970 if (!OutContext.hasXCOFFSection(
2981 bool HasNonZeroLengthPrfCntsSection =
false;
2982 const DataLayout &
DL =
M.getDataLayout();
2983 for (GlobalVariable &GV :
M.globals())
2984 if (GV.hasSection() && GV.getSection() ==
"__llvm_prf_cnts" &&
2985 GV.getGlobalSize(
DL) > 0) {
2986 HasNonZeroLengthPrfCntsSection =
true;
2990 if (HasNonZeroLengthPrfCntsSection) {
2991 MCSection *CntsSection = OutContext.getXCOFFSection(
2996 OutStreamer->switchSection(CntsSection);
2997 if (OutContext.hasXCOFFSection(
3000 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_data[RW]");
3001 OutStreamer->emitXCOFFRefDirective(S);
3003 if (OutContext.hasXCOFFSection(
3006 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_names[RO]");
3007 OutStreamer->emitXCOFFRefDirective(S);
3009 if (OutContext.hasXCOFFSection(
3012 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_vnds[RW]");
3013 OutStreamer->emitXCOFFRefDirective(S);
3018void PPCAIXAsmPrinter::emitGCOVRefs() {
3019 if (!OutContext.hasXCOFFSection(
3020 "__llvm_gcov_ctr_section",
3024 MCSection *CtrSection = OutContext.getXCOFFSection(
3029 OutStreamer->switchSection(CtrSection);
3032 if (OutContext.hasXCOFFSection(
3035 const char *SymbolStr = TM.Options.XCOFFReadOnlyPointers
3036 ?
"__llvm_covinit[RO]"
3037 :
"__llvm_covinit[RW]";
3038 MCSymbol *S = OutContext.getOrCreateSymbol(SymbolStr);
3039 OutStreamer->emitXCOFFRefDirective(S);
3043void PPCAIXAsmPrinter::emitEndOfAsmFile(
Module &M) {
3046 if (
M.empty() && TOCDataGlobalVars.
empty())
3053 OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());
3055 PPCTargetStreamer *TS =
3056 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
3058 for (
auto &
I : TOC) {
3059 MCSectionXCOFF *TCEntry;
3066 (Subtarget->hasAIXShLibTLSModelOpt() &&
3068 SmallString<128>
Name;
3071 Name +=
static_cast<const MCSymbolXCOFF *
>(
I.first.first)
3072 ->getSymbolTableName();
3073 MCSymbol *S = OutContext.getOrCreateSymbol(Name);
3074 TCEntry =
static_cast<MCSectionXCOFF *
>(
3075 getObjFileLowering().getSectionForTOCEntry(S, TM));
3077 TCEntry =
static_cast<MCSectionXCOFF *
>(
3078 getObjFileLowering().getSectionForTOCEntry(
I.first.first, TM));
3080 OutStreamer->switchSection(TCEntry);
3082 OutStreamer->emitLabel(
I.second);
3089 for (
const auto *GV : TOCDataGlobalVars) {
3090 if (!GV->hasCommonLinkage())
3091 emitGlobalVariableHelper(GV);
3093 for (
const auto *GV : TOCDataGlobalVars) {
3094 if (GV->hasCommonLinkage())
3095 emitGlobalVariableHelper(GV);
3099bool PPCAIXAsmPrinter::doInitialization(
Module &M) {
3100 const bool Result = PPCAsmPrinter::doInitialization(M);
3103 const Triple &
Target = TM.getTargetTriple();
3110 if (FunCpuId > TargetCpuId)
3111 TargetCpuId = FunCpuId;
3117 StringRef TargetCPU = TM.getTargetCPU();
3122 PPCTargetStreamer *TS =
3123 static_cast<PPCTargetStreamer *
>(OutStreamer->getTargetStreamer());
3126 auto setCsectAlignment = [
this](
const GlobalObject *GO) {
3128 if (GO->isDeclarationForLinker())
3131 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);
3132 auto *Csect =
static_cast<MCSectionXCOFF *
>(
3133 getObjFileLowering().SectionForGlobal(GO, GOKind, TM));
3135 Align GOAlign = getGVAlignment(GO, GO->getDataLayout());
3136 Csect->ensureMinAlignment(GOAlign);
3142 uint64_t TLSVarAddress = 0;
3143 auto DL =
M.getDataLayout();
3144 for (
const auto &
G :
M.globals()) {
3145 if (
G.isThreadLocal() && !
G.isDeclaration()) {
3146 TLSVarAddress =
alignTo(TLSVarAddress, getGVAlignment(&
G,
DL));
3147 TLSVarsToAddressMapping[&
G] = TLSVarAddress;
3148 TLSVarAddress +=
G.getGlobalSize(
DL);
3155 for (
const auto &
G :
M.globals()) {
3162 if (FormatIndicatorAndUniqueModId.empty()) {
3164 if (UniqueModuleId !=
"")
3168 FormatIndicatorAndUniqueModId =
"clang_" + UniqueModuleId.substr(1);
3173 std::chrono::duration_cast<std::chrono::nanoseconds>(
3174 std::chrono::steady_clock::now().time_since_epoch())
3176 FormatIndicatorAndUniqueModId =
3183 emitSpecialLLVMGlobal(&
G);
3187 setCsectAlignment(&
G);
3188 std::optional<CodeModel::Model> OptionalCodeModel =
G.getCodeModel();
3189 if (OptionalCodeModel)
3191 *OptionalCodeModel);
3194 for (
const auto &
F : M)
3195 setCsectAlignment(&
F);
3198 for (
const auto &Alias :
M.aliases()) {
3199 const GlobalObject *Aliasee = Alias.getAliaseeObject();
3202 "alias without a base object is not yet supported on AIX");
3206 "\n\tAlias attribute for " +
3207 Alias.getName() +
" is invalid because " +
3208 Aliasee->
getName() +
" is common.",
3212 const GlobalVariable *GVar =
3215 std::optional<CodeModel::Model> OptionalCodeModel = GVar->
getCodeModel();
3216 if (OptionalCodeModel)
3218 *OptionalCodeModel);
3221 GOAliasMap[Aliasee].push_back(&Alias);
3227void PPCAIXAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
3228 switch (
MI->getOpcode()) {
3235 if (
MI->getNumOperands() < 5)
3237 const MachineOperand &LangMO =
MI->getOperand(3);
3238 const MachineOperand &ReasonMO =
MI->getOperand(4);
3241 MCSymbol *TempSym = OutContext.createNamedTempSymbol();
3242 OutStreamer->emitLabel(TempSym);
3243 OutStreamer->emitXCOFFExceptDirective(
3244 CurrentFnSym, TempSym, LangMO.
getImm(), ReasonMO.
getImm(),
3245 Subtarget->isPPC64() ?
MI->getMF()->getInstructionCount() * 8
3246 :
MI->getMF()->getInstructionCount() * 4,
3250 case PPC::GETtlsMOD32AIX:
3251 case PPC::GETtlsMOD64AIX:
3252 case PPC::GETtlsTpointer32AIX:
3253 case PPC::GETtlsADDR64AIX:
3254 case PPC::GETtlsADDR32AIX: {
3259 ExtSymSDNodeSymbols.
insert(TlsGetAddr);
3266 const MachineOperand &MO =
MI->getOperand(0);
3268 auto *S =
static_cast<MCSymbolXCOFF *
>(
3270 ExtSymSDNodeSymbols.
insert(S);
3276 case PPC::BL8_NOP_TLS:
3283 case PPC::TAILBCTR8:
3284 if (
MI->getOperand(0).isSymbol())
3297 MCInstBuilder(PPC::ORI).addReg(PPC::R0).addReg(PPC::R0).addImm(0));
3300 return PPCAsmPrinter::emitInstruction(
MI);
3303bool PPCAIXAsmPrinter::doFinalization(
Module &M) {
3304 for (MCSymbol *Sym : ExtSymSDNodeSymbols)
3305 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Extern);
3306 return PPCAsmPrinter::doFinalization(M);
3317 return 20 + (
P - 20) * 16;
3320 return 1004 + (
P - 81);
3323 return 2047 + (
P - 1124) * 33878;
3325 return 2147482625u + (
P - 64512);
3344 std::string PrioritySuffix;
3347 return PrioritySuffix;
3350void PPCAIXAsmPrinter::emitXXStructorList(
const DataLayout &
DL,
3351 const Constant *
List,
bool IsCtor) {
3353 preprocessXXStructorList(
DL,
List, Structors);
3354 if (Structors.
empty())
3358 for (Structor &S : Structors) {
3360 S.Func =
CE->getOperand(0);
3364 (IsCtor ? llvm::Twine(
"__sinit") : llvm::Twine(
"__sterm")) +
3366 llvm::Twine(
"_", FormatIndicatorAndUniqueModId) +
3372void PPCAIXAsmPrinter::emitTTypeReference(
const GlobalValue *GV,
3373 unsigned Encoding) {
3375 TOCEntryType GlobalType = TOCType_GlobalInternal;
3380 GlobalType = TOCType_GlobalExternal;
3381 MCSymbol *TypeInfoSym = TM.getSymbol(GV);
3382 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym, GlobalType);
3383 const MCSymbol *TOCBaseSym =
static_cast<const MCSectionXCOFF *
>(
3384 getObjFileLowering().getTOCBaseSection())
3385 ->getQualNameSymbol();
3386 auto &Ctx = OutStreamer->getContext();
3390 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
3392 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
3395void PPCAIXAsmPrinter::emitRefMetadata(
const GlobalObject *GO) {
3397 GO->
getMetadata(LLVMContext::MD_implicit_ref, MDs);
3398 assert(MDs.
size() &&
"Expected !implicit.ref metadata nodes");
3400 for (
const MDNode *MD : MDs) {
3405 ? getObjFileLowering().getFunctionEntryPointSymbol(GV, TM)
3407 OutStreamer->emitXCOFFRefDirective(Referenced);
3415 std::unique_ptr<MCStreamer> &&Streamer) {
3417 return new PPCAIXAsmPrinter(tm, std::move(Streamer));
3419 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
3422void PPCAIXAsmPrinter::emitModuleCommandLines(
Module &M) {
3423 const NamedMDNode *NMD =
M.getNamedMetadata(
"llvm.commandline");
3428 raw_string_ostream RSOS(S);
3431 assert(
N->getNumOperands() == 1 &&
3432 "llvm.commandline metadata entry can have only one operand");
3436 RSOS <<
"@(#)opt " << MDS->
getString() <<
"\n";
3439 OutStreamer->emitXCOFFCInfoSym(
".GCC.command.line", RSOS.str());
3443 enum class IsLocal {
3455 if (
LHS == IsLocal::False ||
RHS == IsLocal::False)
3456 return IsLocal::False;
3457 if (
LHS == IsLocal::True &&
RHS == IsLocal::True)
3458 return IsLocal::True;
3459 return IsLocal::Unknown;
3463 auto IsLocalFunc = [](
const Function *
F) -> IsLocal {
3464 bool Result =
F->isDSOLocal();
3466 << (Result ?
"dso_local\n" :
"not dso_local\n"));
3467 return Result ? IsLocal::True : IsLocal::False;
3476 std::function<IsLocal(
const Value *)> ValueIsALocalFunc =
3477 [&IsLocalFunc, &
Combine, &ValueIsALocalFunc](
const Value *V) -> IsLocal {
3479 return IsLocalFunc(
F);
3481 return IsLocal::Unknown;
3486 return Combine(ValueIsALocalFunc(
SI->getTrueValue()),
3487 ValueIsALocalFunc(
SI->getFalseValue()));
3489 IsLocal Res = IsLocal::True;
3490 for (
unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
3491 Res =
Combine(Res, ValueIsALocalFunc(PN->getIncomingValue(i)));
3492 if (Res == IsLocal::False)
3507 return IsLocal::Unknown;
3510 return IsLocal::Unknown;
3512 IsLocal Res = IsLocal::True;
3513 for (
unsigned Idx = 0, End =
Init->getNumOperands(); Idx != End; ++Idx) {
3514 Res =
Combine(Res, ValueIsALocalFunc(
Init->getOperand(Idx)));
3515 if (Res == IsLocal::False)
3520 return IsLocal::Unknown;
3530 IsLocal Res = IsLocal::True;
3535 Value *RV = Ret->getReturnValue();
3537 Res =
Combine(Res, ValueIsALocalFunc(RV));
3538 if (Res == IsLocal::False)
3567void PPCAIXAsmPrinter::emitGlobalIFunc(
Module &M,
const GlobalIFunc &GI) {
3569 const TargetSubtargetInfo *STI =
3571 bool IsPPC64 =
static_cast<const PPCSubtarget *
>(STI)->isPPC64();
3576 MCSectionXCOFF *FnDescSec =
static_cast<MCSectionXCOFF *
>(
3577 getObjFileLowering().getSectionForFunctionDescriptor(&GI, TM));
3582 CurrentFnSym = getObjFileLowering().getFunctionEntryPointSymbol(&GI, TM);
3585 if (TM.getFunctionSections())
3586 OutStreamer->switchSection(
3587 static_cast<MCSymbolXCOFF *
>(CurrentFnSym)->getRepresentedCsect());
3589 OutStreamer->switchSection(getObjFileLowering().getTextSection());
3592 emitRefMetadata(&GI);
3595 emitLinkage(&GI, CurrentFnDescSym);
3596 emitLinkage(&GI, CurrentFnSym);
3600 emitAlignment(Alignment,
nullptr);
3603 emitFunctionDescriptor();
3605 emitFunctionEntryLabel();
3609 Twine Msg =
"unimplemented: TOC register save/restore needed for ifunc \"" +
3611 "\", because couldn't prove all candidates "
3612 "are static or hidden/protected visibility definitions";
3616 dbgs() << Msg <<
"\n";
3620 auto *FnDescTOCEntrySym =
3621 lookUpOrCreateTOCEntry(CurrentFnDescSym, FnDescTOCEntryType);
3626 auto *Exp_U = symbolWithSpecifier(FnDescTOCEntrySym,
PPC::S_U);
3627 OutStreamer->emitInstruction(MCInstBuilder(PPC::ADDIS)
3632 auto *Exp_L = symbolWithSpecifier(FnDescTOCEntrySym,
PPC::S_L);
3633 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3643 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3650 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3652 .addImm(IsPPC64 ? 16 : 8)
3656 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3662 OutStreamer->emitInstruction(
3663 MCInstBuilder(IsPPC64 ? PPC::MTCTR8 : PPC::MTCTR).addReg(PPC::X12),
3666 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::BCTR8 : PPC::BCTR),
3670char PPCAIXAsmPrinter::ID = 0;
3673 "AIX PPC Assembly Printer",
false,
false)
3677LLVMInitializePowerPCAsmPrinter() {
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)
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.
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)
Register getFrameRegister(const MachineFunction &MF) const override
bool is32BitELFABI() const
const PPCFrameLowering * getFrameLowering() const override
bool isUsingPCRelativeCalls() const
CodeModel::Model getCodeModel(const TargetMachine &TM, const GlobalValue *GV) const
Calculates the effective code model for argument GV.
const PPCRegisterInfo * getRegisterInfo() const override
bool isGVIndirectSymbol(const GlobalValue *GV) const
True if the GV will be accessed via an indirect symbol.
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)
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