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 SmallString<128> Msg;
3610 Msg.
append(
"unimplemented: TOC register save/restore needed for ifunc \"");
3611 getNameWithPrefix(Msg, &GI);
3612 Msg.
append(
"\", because couldn't prove all candidates are static or "
3613 "hidden/protected visibility definitions");
3617 dbgs() << Msg <<
"\n";
3621 auto *FnDescTOCEntrySym =
3622 lookUpOrCreateTOCEntry(CurrentFnDescSym, FnDescTOCEntryType);
3627 auto *Exp_U = symbolWithSpecifier(FnDescTOCEntrySym,
PPC::S_U);
3628 OutStreamer->emitInstruction(MCInstBuilder(PPC::ADDIS)
3633 auto *Exp_L = symbolWithSpecifier(FnDescTOCEntrySym,
PPC::S_L);
3634 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3644 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3651 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3653 .addImm(IsPPC64 ? 16 : 8)
3657 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::LD : PPC::LWZ)
3663 OutStreamer->emitInstruction(
3664 MCInstBuilder(IsPPC64 ? PPC::MTCTR8 : PPC::MTCTR).addReg(PPC::X12),
3667 OutStreamer->emitInstruction(MCInstBuilder(IsPPC64 ? PPC::BCTR8 : PPC::BCTR),
3671char PPCAIXAsmPrinter::ID = 0;
3674 "AIX PPC Assembly Printer",
false,
false)
3678LLVMInitializePowerPCAsmPrinter() {
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 GlobalObject has any metadata attached to it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this GlobalObject.
bool hasSection() const
Check if this global has a custom object file section.
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 append(StringRef RHS)
Append from a StringRef.
StringRef str() const
Explicit conversion to StringRef.
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)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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.
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