85#define DEBUG_TYPE "asmprinter"
87STATISTIC(NumTOCEntries,
"Number of Total TOC Entries Emitted.");
88STATISTIC(NumTOCConstPool,
"Number of Constant Pool TOC Entries.");
90 "Number of Internal Linkage Global TOC Entries.");
92 "Number of External Linkage Global TOC Entries.");
93STATISTIC(NumTOCJumpTable,
"Number of Jump Table TOC Entries.");
94STATISTIC(NumTOCThreadLocal,
"Number of Thread Local TOC Entries.");
95STATISTIC(NumTOCBlockAddress,
"Number of Block Address TOC Entries.");
96STATISTIC(NumTOCEHBlock,
"Number of EH Block TOC Entries.");
109 using TOCKey = std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>;
130 Tag_GNU_Power_ABI_FP = 4,
131 Tag_GNU_Power_ABI_Vector = 8,
132 Tag_GNU_Power_ABI_Struct_Return = 12,
135 Val_GNU_Power_ABI_NoFloat = 0b00,
136 Val_GNU_Power_ABI_HardFloat_DP = 0b01,
137 Val_GNU_Power_ABI_SoftFloat_DP = 0b10,
138 Val_GNU_Power_ABI_HardFloat_SP = 0b11,
140 Val_GNU_Power_ABI_LDBL_IBM128 = 0b0100,
141 Val_GNU_Power_ABI_LDBL_64 = 0b1000,
142 Val_GNU_Power_ABI_LDBL_IEEE128 = 0b1100,
166 std::unique_ptr<MCStreamer> Streamer)
172 TOCType_ConstantPool,
173 TOCType_GlobalExternal,
174 TOCType_GlobalInternal,
177 TOCType_BlockAddress,
183 MCSymbolRefExpr::VariantKind::VK_None);
219class PPCLinuxAsmPrinter :
public PPCAsmPrinter {
222 std::unique_ptr<MCStreamer> Streamer)
223 : PPCAsmPrinter(
TM,
std::
move(Streamer)) {}
226 return "Linux PPC Assembly Printer";
229 void emitGNUAttributes(
Module &M);
231 void emitStartOfAsmFile(
Module &M)
override;
232 void emitEndOfAsmFile(
Module &)
override;
234 void emitFunctionEntryLabel()
override;
236 void emitFunctionBodyStart()
override;
237 void emitFunctionBodyEnd()
override;
241class PPCAIXAsmPrinter :
public PPCAsmPrinter {
249 std::string FormatIndicatorAndUniqueModId;
257 void emitTracebackTable();
267 PPCAIXAsmPrinter(
TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
268 : PPCAsmPrinter(
TM,
std::
move(Streamer)) {
269 if (MAI->isLittleEndian())
271 "cannot create AIX PPC Assembly Printer for a little-endian target");
274 StringRef getPassName()
const override {
return "AIX PPC Assembly Printer"; }
276 bool doInitialization(
Module &M)
override;
279 bool IsCtor)
override;
285 void emitFunctionDescriptor()
override;
287 void emitFunctionEntryLabel()
override;
289 void emitFunctionBodyEnd()
override;
291 void emitPGORefs(
Module &M);
295 void emitEndOfAsmFile(
Module &)
override;
301 bool doFinalization(
Module &M)
override;
303 void emitTTypeReference(
const GlobalValue *GV,
unsigned Encoding)
override;
305 void emitModuleCommandLines(
Module &M)
override;
314 getSymbol(GV)->
print(O, MAI);
318void PPCAsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNo,
341 O <<
DL.getPrivateGlobalPrefix() <<
"CPI" << getFunctionNumber() <<
'_'
348 PrintSymbolOperand(MO, O);
360bool PPCAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
363 if (ExtraCode && ExtraCode[0]) {
364 if (ExtraCode[1] != 0)
return true;
366 switch (ExtraCode[0]) {
372 if (!
MI->getOperand(OpNo).isReg() ||
373 OpNo+1 ==
MI->getNumOperands() ||
374 !
MI->getOperand(OpNo+1).isReg())
381 if (
MI->getOperand(OpNo).isImm())
385 if(!
MI->getOperand(OpNo).isReg())
391 Reg = PPC::VSX32 + (
Reg - PPC::V0);
393 Reg = PPC::VSX32 + (Reg - PPC::VF0);
409bool PPCAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNo,
410 const char *ExtraCode,
412 if (ExtraCode && ExtraCode[0]) {
413 if (ExtraCode[1] != 0)
return true;
415 switch (ExtraCode[0]) {
416 default:
return true;
418 O << getDataLayout().getPointerSize() <<
"(";
429 if (
MI->getOperand(OpNo).isImm())
440 assert(
MI->getOperand(OpNo).isReg());
445 assert(
MI->getOperand(OpNo).isReg());
455 case PPCAsmPrinter::TOCType_ConstantPool:
458 case PPCAsmPrinter::TOCType_GlobalInternal:
459 ++NumTOCGlobalInternal;
461 case PPCAsmPrinter::TOCType_GlobalExternal:
462 ++NumTOCGlobalExternal;
464 case PPCAsmPrinter::TOCType_JumpTable:
467 case PPCAsmPrinter::TOCType_ThreadLocal:
470 case PPCAsmPrinter::TOCType_BlockAddress:
471 ++NumTOCBlockAddress;
473 case PPCAsmPrinter::TOCType_EHBlock:
490 assert(GV &&
"expected global for MO_GlobalAddress");
512PPCAsmPrinter::lookUpOrCreateTOCEntry(
const MCSymbol *
Sym, TOCEntryType
Type,
515 if (!
TOC.contains({Sym, Kind}))
520 TOCEntry = createTempSymbol(
"C");
525 unsigned NumNOPBytes =
MI.getOperand(1).getImm();
527 auto &Ctx = OutStreamer->getContext();
528 MCSymbol *MILabel = Ctx.createTempSymbol();
529 OutStreamer->emitLabel(MILabel);
532 assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
538 while (NumNOPBytes > 0) {
539 if (MII ==
MBB.
end() || MII->isCall() ||
540 MII->getOpcode() == PPC::DBG_VALUE ||
541 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
542 MII->getOpcode() == TargetOpcode::STACKMAP)
549 for (
unsigned i = 0; i < NumNOPBytes; i += 4)
556 auto &Ctx = OutStreamer->getContext();
557 MCSymbol *MILabel = Ctx.createTempSymbol();
558 OutStreamer->emitLabel(MILabel);
563 unsigned EncodedBytes = 0;
566 if (CalleeMO.
isImm()) {
567 int64_t CallTarget = CalleeMO.
getImm();
569 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
570 "High 16 bits of call target should be zero.");
571 Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
576 .addImm((CallTarget >> 32) & 0xFFFF));
581 .addImm(32).addImm(16));
586 .addImm((CallTarget >> 16) & 0xFFFF));
591 .addImm(CallTarget & 0xFFFF));
597 .addImm(TOCSaveOffset)
610 .addReg(ScratchReg));
615 .addReg(ScratchReg));
620 .addReg(ScratchReg));
628 .addImm(TOCSaveOffset)
634 MCSymbol *MOSymbol = getSymbol(GValue);
646 unsigned NumBytes = Opers.getNumPatchBytes();
647 assert(NumBytes >= EncodedBytes &&
648 "Patchpoint can't request size less than the length of a call.");
649 assert((NumBytes - EncodedBytes) % 4 == 0 &&
650 "Invalid number of NOP bytes requested!");
651 for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
662 SymName =
".__tls_get_addr";
664 case PPC::GETtlsTpointer32AIX:
665 SymName =
".__get_tpointer";
667 case PPC::GETtlsMOD32AIX:
668 case PPC::GETtlsMOD64AIX:
669 SymName =
".__tls_get_mod";
680 "Only expecting to emit calls to get the thread pointer on AIX!");
685 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::BLA).addExpr(TlsRef));
693 unsigned Opcode = PPC::BL8_NOP_TLS;
695 assert(
MI->getNumOperands() >= 3 &&
"Expecting at least 3 operands from MI");
699 Opcode = PPC::BL8_NOTOC_TLS;
701 const Module *
M = MF->getFunction().getParent();
704 ((Subtarget->
isPPC64() &&
MI->getOperand(0).getReg() == PPC::X3) ||
705 (!Subtarget->
isPPC64() &&
MI->getOperand(0).getReg() == PPC::R3)) &&
706 "GETtls[ld]ADDR[32] must define GPR3");
708 ((Subtarget->
isPPC64() &&
MI->getOperand(1).getReg() == PPC::X3) ||
709 (!Subtarget->
isPPC64() &&
MI->getOperand(1).getReg() == PPC::R3)) &&
710 "GETtls[ld]ADDR[32] must read GPR3");
719 assert((
MI->getOpcode() == PPC::GETtlsMOD32AIX ||
720 MI->getOpcode() == PPC::GETtlsMOD64AIX ||
721 (
MI->getOperand(2).isReg() &&
722 MI->getOperand(2).getReg() == VarOffsetReg)) &&
723 "GETtls[ld]ADDR[32] must read GPR4");
724 EmitAIXTlsCallHelper(
MI);
728 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(
"__tls_get_addr");
743 MCSymbol *MOSymbol = getSymbol(GValue);
745 EmitToStreamer(*OutStreamer,
747 : (
unsigned)PPC::BL_TLS)
770static PPCAsmPrinter::TOCEntryType
775 return PPCAsmPrinter::TOCType_ThreadLocal;
784 return PPCAsmPrinter::TOCType_GlobalExternal;
786 return PPCAsmPrinter::TOCType_GlobalInternal;
789 return PPCAsmPrinter::TOCType_ConstantPool;
791 return PPCAsmPrinter::TOCType_JumpTable;
793 return PPCAsmPrinter::TOCType_BlockAddress;
802 PPC_MC::verifyInstructionPredicates(
MI->getOpcode(),
803 getSubtargetInfo().getFeatureBits());
806 const bool IsPPC64 = Subtarget->
isPPC64();
807 const bool IsAIX = Subtarget->
isAIXABI();
808 const bool HasAIXSmallLocalTLS = Subtarget->hasAIXSmallLocalExecTLS() ||
809 Subtarget->hasAIXSmallLocalDynamicTLS();
810 const Module *
M = MF->getFunction().getParent();
815 if (!
MI->isInlineAsm()) {
819 if (Subtarget->hasSPE()) {
820 if (PPC::F4RCRegClass.
contains(Reg) ||
829 if (PPC::SPERCRegClass.
contains(Reg))
837 auto getTOCRelocAdjustedExprForXCOFF = [
this](
const MCExpr *Expr,
846 OriginalOffset - llvm::SignExtend32<16>(OriginalOffset);
851 auto getTOCEntryLoadingExprForXCOFF =
852 [IsPPC64, getTOCRelocAdjustedExprForXCOFF,
855 MCSymbolRefExpr::VariantKind::VK_None) ->
const MCExpr * {
856 const unsigned EntryByteSize = IsPPC64 ? 8 : 4;
857 const auto TOCEntryIter =
TOC.find({MOSymbol, VK});
859 "Could not find the TOC entry for this symbol.");
860 const ptrdiff_t EntryDistanceFromTOCBase =
861 (TOCEntryIter -
TOC.begin()) * EntryByteSize;
862 constexpr int16_t PositiveTOCRange = INT16_MAX;
864 if (EntryDistanceFromTOCBase > PositiveTOCRange)
865 return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase);
877 assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!\n");
880 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE;
882 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
889 dbgs() <<
"Current function uses IE access for default LD vars.\n");
890 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
898 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM;
900 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD;
905 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD;
907 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSML;
908 return MCSymbolRefExpr::VariantKind::VK_None;
912 switch (
MI->getOpcode()) {
914 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
916 "AIX does not support patchable function entry!");
919 if (MAI->isLittleEndian())
923 (void)
F.getFnAttribute(
"patchable-function-entry")
925 .getAsInteger(10, Num);
931 case TargetOpcode::DBG_VALUE:
933 case TargetOpcode::STACKMAP:
934 return LowerSTACKMAP(SM, *
MI);
935 case TargetOpcode::PATCHPOINT:
936 return LowerPATCHPOINT(SM, *
MI);
938 case PPC::MoveGOTtoLR: {
946 OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
955 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::BL).addExpr(OffsExpr));
958 case PPC::MovePCtoLR:
959 case PPC::MovePCtoLR8: {
964 MCSymbol *PICBase = MF->getPICBaseSymbol();
967 EmitToStreamer(*OutStreamer,
974 OutStreamer->emitLabel(PICBase);
977 case PPC::UpdateGBR: {
986 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
988 MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
1000 MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));
1005 MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
1025 EmitToStreamer(*OutStreamer, TmpInst);
1031 EmitToStreamer(*OutStreamer, TmpInst);
1044 "Invalid operand for LWZtoc.");
1056 EmitToStreamer(*OutStreamer, TmpInst);
1076 "This pseudo should only be selected for 32-bit small code model.");
1077 Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK);
1082 OutStreamer->getCommentOS() << MO <<
'\n';
1083 EmitToStreamer(*OutStreamer, TmpInst);
1090 OutContext.getOrCreateSymbol(
Twine(
".LTOC")), OutContext);
1093 EmitToStreamer(*OutStreamer, TmpInst);
1097 case PPC::ADDItoc8: {
1099 "PseudoOp only valid for small code model AIX");
1105 TmpInst.
setOpcode((!IsPPC64) ? (PPC::LA) : (PPC::LA8));
1117 EmitToStreamer(*OutStreamer, TmpInst);
1132 "Invalid operand!");
1149 IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK) : Exp);
1152 if (isVerbose() && IsAIX)
1153 OutStreamer->getCommentOS() << MO <<
'\n';
1154 EmitToStreamer(*OutStreamer, TmpInst);
1157 case PPC::ADDIStocHA: {
1161 "Invalid operand for ADDIStocHA.");
1162 assert((IsAIX && !IsPPC64 &&
1164 "This pseudo should only be selected for 32-bit large code model on"
1191 return GV->hasAttribute(
"toc-data");
1199 EmitToStreamer(*OutStreamer, TmpInst);
1202 case PPC::LWZtocL: {
1206 "Invalid operand for LWZtocL.");
1207 assert(IsAIX && !IsPPC64 &&
1209 "This pseudo should only be selected for 32-bit large code model on"
1233 EmitToStreamer(*OutStreamer, TmpInst);
1236 case PPC::ADDIStocHA8: {
1248 "Invalid operand for ADDIStocHA8!");
1254 const bool GlobalToc =
1276 EmitToStreamer(*OutStreamer, TmpInst);
1292 "Invalid operand for LDtocL!");
1296 "LDtocL used on symbol that could be accessed directly is "
1297 "invalid. Must match ADDIStocHA8."));
1311 EmitToStreamer(*OutStreamer, TmpInst);
1315 case PPC::ADDItocL8: {
1319 unsigned Op =
MI->getOpcode();
1323 TmpInst.
setOpcode(
Op == PPC::ADDItocL8 ? (IsAIX ? PPC::LA8 : PPC::ADDI8)
1329 : MO.
isGlobal() &&
"Invalid operand for ADDItocL8.");
1331 "Interposable definitions must use indirect accesses.");
1342 EmitToStreamer(*OutStreamer, TmpInst);
1345 case PPC::ADDISgotTprelHA: {
1348 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1351 MCSymbol *MOSymbol = getSymbol(GValue);
1352 const MCExpr *SymGotTprel =
1356 .addReg(
MI->getOperand(0).getReg())
1357 .
addReg(
MI->getOperand(1).getReg())
1361 case PPC::LDgotTprelL:
1362 case PPC::LDgotTprelL32: {
1367 TmpInst.
setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ);
1370 MCSymbol *MOSymbol = getSymbol(GValue);
1376 EmitToStreamer(*OutStreamer, TmpInst);
1380 case PPC::PPC32PICGOT: {
1381 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1382 MCSymbol *GOTRef = OutContext.createTempSymbol();
1383 MCSymbol *NextInstr = OutContext.createTempSymbol();
1393 OutStreamer->emitLabel(GOTRef);
1394 OutStreamer->emitValue(OffsExpr, 4);
1395 OutStreamer->emitLabel(NextInstr);
1397 .addReg(
MI->getOperand(0).getReg()));
1399 .addReg(
MI->getOperand(1).getReg())
1401 .
addReg(
MI->getOperand(0).getReg()));
1403 .addReg(
MI->getOperand(0).getReg())
1404 .
addReg(
MI->getOperand(1).getReg())
1405 .
addReg(
MI->getOperand(0).getReg()));
1408 case PPC::PPC32GOT: {
1410 OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1416 .addReg(
MI->getOperand(0).getReg())
1419 .addReg(
MI->getOperand(0).getReg())
1420 .
addReg(
MI->getOperand(0).getReg())
1424 case PPC::ADDIStlsgdHA: {
1427 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1430 MCSymbol *MOSymbol = getSymbol(GValue);
1431 const MCExpr *SymGotTlsGD =
1435 .addReg(
MI->getOperand(0).getReg())
1436 .
addReg(
MI->getOperand(1).getReg())
1440 case PPC::ADDItlsgdL:
1443 case PPC::ADDItlsgdL32: {
1448 MCSymbol *MOSymbol = getSymbol(GValue);
1453 EmitToStreamer(*OutStreamer,
1455 .addReg(
MI->getOperand(0).getReg())
1456 .
addReg(
MI->getOperand(1).getReg())
1460 case PPC::GETtlsMOD32AIX:
1461 case PPC::GETtlsMOD64AIX:
1465 case PPC::GETtlsADDR:
1468 case PPC::GETtlsADDRPCREL:
1469 case PPC::GETtlsADDR32AIX:
1470 case PPC::GETtlsADDR64AIX:
1474 case PPC::GETtlsADDR32: {
1480 case PPC::GETtlsTpointer32AIX: {
1483 EmitAIXTlsCallHelper(
MI);
1486 case PPC::ADDIStlsldHA: {
1489 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1492 MCSymbol *MOSymbol = getSymbol(GValue);
1493 const MCExpr *SymGotTlsLD =
1497 .addReg(
MI->getOperand(0).getReg())
1498 .
addReg(
MI->getOperand(1).getReg())
1502 case PPC::ADDItlsldL:
1505 case PPC::ADDItlsldL32: {
1510 MCSymbol *MOSymbol = getSymbol(GValue);
1515 EmitToStreamer(*OutStreamer,
1517 .addReg(
MI->getOperand(0).getReg())
1518 .
addReg(
MI->getOperand(1).getReg())
1522 case PPC::GETtlsldADDR:
1525 case PPC::GETtlsldADDRPCREL:
1526 case PPC::GETtlsldADDR32: {
1532 case PPC::ADDISdtprelHA:
1535 case PPC::ADDISdtprelHA32: {
1540 MCSymbol *MOSymbol = getSymbol(GValue);
1541 const MCExpr *SymDtprel =
1547 .addReg(
MI->getOperand(0).getReg())
1548 .
addReg(
MI->getOperand(1).getReg())
1552 case PPC::PADDIdtprel: {
1557 MCSymbol *MOSymbol = getSymbol(GValue);
1561 .addReg(
MI->getOperand(0).getReg())
1562 .
addReg(
MI->getOperand(1).getReg())
1567 case PPC::ADDIdtprelL:
1570 case PPC::ADDIdtprelL32: {
1575 MCSymbol *MOSymbol = getSymbol(GValue);
1576 const MCExpr *SymDtprel =
1579 EmitToStreamer(*OutStreamer,
1581 .addReg(
MI->getOperand(0).getReg())
1582 .
addReg(
MI->getOperand(1).getReg())
1588 if (!Subtarget->hasMFOCRF()) {
1591 unsigned NewOpcode =
1592 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
1596 .addReg(
MI->getOperand(0).getReg()));
1602 if (!Subtarget->hasMFOCRF()) {
1605 unsigned NewOpcode =
1606 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1607 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
1608 ->getEncodingValue(
MI->getOperand(0).getReg());
1613 .addReg(
MI->getOperand(1).getReg()));
1623 unsigned OpNum = (
MI->getOpcode() == PPC::STD) ? 2 : 1;
1630 TempMO.getOperandNo() == 1)
1667 if (!HasAIXSmallLocalTLS)
1669 bool IsMIADDI8 =
MI->getOpcode() == PPC::ADDI8;
1670 unsigned OpNum = IsMIADDI8 ? 2 : 1;
1686 EmitToStreamer(*OutStreamer, TmpInst);
1692 case PPC::PseudoEIEIO: {
1695 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1698 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1699 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::EnforceIEIO));
1705 EmitToStreamer(*OutStreamer, TmpInst);
1715PPCAsmPrinter::getAdjustedFasterLocalExpr(
const MachineOperand &MO,
1722 assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!");
1726 "Only local-[exec|dynamic] accesses are handled!");
1732 const auto TLSVarsMapEntryIter = TLSVarsToAddressMapping.
find(GValue);
1733 if (TLSVarsMapEntryIter == TLSVarsToAddressMapping.
end())
1734 assert(IsGlobalADeclaration &&
1735 "Only expecting to find extern TLS variables not present in the TLS "
1736 "variable-to-address map!");
1738 unsigned TLSVarAddress =
1739 IsGlobalADeclaration ? 0 : TLSVarsMapEntryIter->second;
1753 if (FinalAddress >= 32768) {
1760 ptrdiff_t Delta = ((FinalAddress + 32768) & ~0xFFFF);
1764 ((InstDisp < 32768) && (InstDisp >= -32768)) &&
1765 "Expecting the instruction displacement for local-[exec|dynamic] TLS "
1766 "variables to be between [-32768, 32768)!");
1774void PPCLinuxAsmPrinter::emitGNUAttributes(
Module &M) {
1776 Metadata *MD =
M.getModuleFlag(
"float-abi");
1777 MDString *FloatABI = dyn_cast_or_null<MDString>(MD);
1782 if (flt ==
"doubledouble")
1783 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1784 Val_GNU_Power_ABI_HardFloat_DP |
1785 Val_GNU_Power_ABI_LDBL_IBM128);
1786 else if (flt ==
"ieeequad")
1787 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1788 Val_GNU_Power_ABI_HardFloat_DP |
1789 Val_GNU_Power_ABI_LDBL_IEEE128);
1790 else if (flt ==
"ieeedouble")
1791 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1792 Val_GNU_Power_ABI_HardFloat_DP |
1793 Val_GNU_Power_ABI_LDBL_64);
1796void PPCLinuxAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
1798 return PPCAsmPrinter::emitInstruction(
MI);
1800 switch (
MI->getOpcode()) {
1803 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1816 if (!MAI->isLittleEndian())
1818 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1819 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1820 OutStreamer->emitLabel(BeginOfSled);
1821 EmitToStreamer(*OutStreamer,
1827 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1828 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1829 EmitToStreamer(*OutStreamer,
1832 OutContext.getOrCreateSymbol(
"__xray_FunctionEntry"),
1834 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1835 OutStreamer->emitLabel(EndOfSled);
1836 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_ENTER, 2);
1839 case TargetOpcode::PATCHABLE_RET: {
1840 unsigned RetOpcode =
MI->getOperand(0).getImm();
1850 if (RetOpcode == PPC::BCCLR) {
1851 IsConditional =
true;
1852 }
else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1853 RetOpcode == PPC::TCRETURNai8) {
1855 }
else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1856 IsConditional =
false;
1858 EmitToStreamer(*OutStreamer, RetInst);
1863 if (IsConditional) {
1882 FallthroughLabel = OutContext.createTempSymbol();
1888 .
addReg(
MI->getOperand(2).getReg())
1905 OutStreamer->emitCodeAlignment(
Align(8), &getSubtargetInfo());
1906 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1907 OutStreamer->emitLabel(BeginOfSled);
1908 EmitToStreamer(*OutStreamer, RetInst);
1912 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1913 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1914 EmitToStreamer(*OutStreamer,
1917 OutContext.getOrCreateSymbol(
"__xray_FunctionExit"),
1919 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1920 EmitToStreamer(*OutStreamer, RetInst);
1922 OutStreamer->emitLabel(FallthroughLabel);
1923 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_EXIT, 2);
1926 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1928 case TargetOpcode::PATCHABLE_TAIL_CALL:
1932 "around this assert.");
1934 return PPCAsmPrinter::emitInstruction(
MI);
1937void PPCLinuxAsmPrinter::emitStartOfAsmFile(
Module &M) {
1945 !isPositionIndependent())
1951 OutStreamer->switchSection(OutContext.getELFSection(
1954 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(
Twine(
".LTOC"));
1955 MCSymbol *CurrentPos = OutContext.createTempSymbol();
1957 OutStreamer->emitLabel(CurrentPos);
1966 OutStreamer->emitAssignment(TOCSym, tocExpr);
1968 OutStreamer->switchSection(getObjFileLowering().getTextSection());
1971void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
1974 (!isPositionIndependent() ||
1980 if (PPCFI->
usesPICBase() && !Subtarget->isSecurePlt()) {
1982 MCSymbol *PICBase = MF->getPICBaseSymbol();
1983 OutStreamer->emitLabel(RelocSymbol);
1991 OutStreamer->emitValue(OffsExpr, 4);
1992 OutStreamer->emitLabel(CurrentFnSym);
2005 && !MF->getRegInfo().use_empty(PPC::X2)) {
2010 const MCExpr *TOCDeltaExpr =
2017 OutStreamer->emitValue(TOCDeltaExpr, 8);
2026 OutStreamer->switchSection(Section);
2027 OutStreamer->emitLabel(CurrentFnSym);
2028 OutStreamer->emitValueToAlignment(
Align(8));
2029 MCSymbol *Symbol1 = CurrentFnSymForSize;
2036 OutStreamer->emitValue(
2040 OutStreamer->emitIntValue(0, 8 );
2041 OutStreamer->switchSection(Current.first, Current.second);
2044void PPCLinuxAsmPrinter::emitEndOfAsmFile(
Module &M) {
2047 bool isPPC64 =
DL.getPointerSizeInBits() == 64;
2057 OutStreamer->emitSymbolValue(
2058 GetExternalSymbolSymbol(
"__parse_hwcap_and_convert_at_platform"),
2059 MAI->getCodePointerSize());
2060 emitGNUAttributes(M);
2063 const char *
Name = isPPC64 ?
".toc" :
".got2";
2066 OutStreamer->switchSection(Section);
2068 OutStreamer->emitValueToAlignment(
Align(4));
2070 for (
const auto &TOCMapPair : TOC) {
2071 const MCSymbol *
const TOCEntryTarget = TOCMapPair.first.first;
2072 MCSymbol *
const TOCEntryLabel = TOCMapPair.second;
2074 OutStreamer->emitLabel(TOCEntryLabel);
2076 TS->
emitTCEntry(*TOCEntryTarget, TOCMapPair.first.second);
2078 OutStreamer->emitSymbolValue(TOCEntryTarget, 4);
2082 PPCAsmPrinter::emitEndOfAsmFile(M);
2086void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
2119 const bool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) ||
2120 !MF->getRegInfo().use_empty(PPC::R2);
2129 if (NonPCrelGEPRequired || PCrelGEPRequired) {
2134 OutStreamer->emitLabel(GlobalEntryLabel);
2140 const MCExpr *TOCDeltaExpr =
2142 GlobalEntryLabelExp, OutContext);
2148 .addExpr(TOCDeltaHi));
2154 .addExpr(TOCDeltaLo));
2157 const MCExpr *TOCOffsetDeltaExpr =
2159 GlobalEntryLabelExp, OutContext);
2163 .addExpr(TOCOffsetDeltaExpr)
2172 OutStreamer->emitLabel(LocalEntryLabel);
2175 const MCExpr *LocalOffsetExp =
2177 GlobalEntryLabelExp, OutContext);
2181 TS->
emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), LocalOffsetExp);
2204 if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() ||
2205 MF->hasInlineAsm() || (!PPCFI->
usesTOCBasePtr() && UsesX2OrR2)) {
2217void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
2226 OutStreamer->emitIntValue(0, 4);
2227 OutStreamer->emitIntValue(0, 8);
2231void PPCAIXAsmPrinter::emitLinkage(
const GlobalValue *GV,
2252 "InternalLinkage should not have other visibility setting.");
2264 if (!
TM.getIgnoreXCOFFVisibility()) {
2267 "Cannot not be both dllexport and non-default visibility");
2273 VisibilityAttr = MAI->getExportedVisibilityAttr();
2276 VisibilityAttr = MAI->getHiddenVisibilityAttr();
2279 VisibilityAttr = MAI->getProtectedVisibilityAttr();
2289 OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,
2296 cast<MCSectionXCOFF>(getObjFileLowering().getSectionForFunctionDescriptor(
2305uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
2310 if (Subtarget.
isAIXABI() && Subtarget.hasAltivec() &&
2311 TM.getAIXExtendedAltivecABI()) {
2313 for (
unsigned Reg = PPC::V20;
Reg <= PPC::V31; ++
Reg)
2314 if (
MRI.isPhysRegModified(Reg))
2316 return PPC::V31 - Reg + 1;
2321void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
2323 if (!
TM.getXCOFFTracebackTable())
2326 emitTracebackTable();
2334 (getNumberOfVRSaved() > 0)) {
2336 OutStreamer->switchSection(getObjFileLowering().getCompactUnwindSection());
2339 OutStreamer->emitLabel(EHInfoLabel);
2342 OutStreamer->emitInt32(0);
2344 const DataLayout &
DL = MMI->getModule()->getDataLayout();
2347 OutStreamer->emitValueToAlignment(
Align(PointerSize));
2349 OutStreamer->emitIntValue(0, PointerSize);
2350 OutStreamer->emitIntValue(0, PointerSize);
2351 OutStreamer->switchSection(MF->
getSection());
2355void PPCAIXAsmPrinter::emitTracebackTable() {
2359 OutStreamer->emitLabel(FuncEnd);
2361 OutStreamer->AddComment(
"Traceback table begin");
2363 OutStreamer->emitIntValueInHexWithPadding(0, 4 );
2368 auto EmitComment = [&]() {
2369 OutStreamer->AddComment(CommentOS.str());
2370 CommentString.
clear();
2375 OutStreamer->emitIntValueInHexWithPadding(
Value,
Size);
2379 CommentOS <<
"Version = " <<
Version;
2380 EmitCommentAndValue(Version, 1);
2390 CommentOS <<
"Language = "
2392 EmitCommentAndValue(LanguageIdentifier, 1);
2395 uint32_t FirstHalfOfMandatoryField = 0;
2406 for (
unsigned Reg = PPC::F0;
Reg <= PPC::F31; ++
Reg) {
2407 if (
MRI.isPhysRegUsed(Reg,
true)) {
2413#define GENBOOLCOMMENT(Prefix, V, Field) \
2414 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
2417#define GENVALUECOMMENT(PrefixAndName, V, Field) \
2418 CommentOS << (PrefixAndName) << " = " \
2419 << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
2420 (TracebackTable::Field##Shift))
2423 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);
2426 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasTraceBackTableOffset);
2427 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsInternalProcedure);
2430 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasControlledStorage);
2434 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsFloatingPointPresent);
2437 IsFloatingPointOperationLogOrAbortEnabled);
2440 OutStreamer->emitIntValueInHexWithPadding(
2441 (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2449 if (FrameReg == (Subtarget->
isPPC64() ? PPC::X31 : PPC::R31))
2453 if (!MustSaveCRs.
empty())
2459 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsInterruptHandler);
2460 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);
2464 OnConditionDirective);
2468 OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),
2472 uint32_t SecondHalfOfMandatoryField = 0;
2479 for (
unsigned Reg = PPC::F14;
Reg <= PPC::F31; ++
Reg) {
2480 if (
MRI.isPhysRegModified(Reg)) {
2481 FPRSaved = PPC::F31 -
Reg + 1;
2487 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, IsBackChainStored);
2489 GENVALUECOMMENT(
", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
2491 OutStreamer->emitIntValueInHexWithPadding(
2492 (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
2498 bool HasVectorInst =
false;
2499 for (
unsigned Reg = PPC::V0;
Reg <= PPC::V31; ++
Reg)
2500 if (
MRI.isPhysRegUsed(Reg,
true)) {
2502 HasVectorInst =
true;
2509 uint16_t NumOfVRSaved = getNumberOfVRSaved();
2510 bool ShouldEmitEHBlock =
2513 if (ShouldEmitEHBlock)
2519 unsigned GPRBegin = Subtarget->
isPPC64() ? PPC::X14 : PPC::R13;
2520 unsigned GPREnd = Subtarget->
isPPC64() ? PPC::X31 : PPC::R31;
2522 for (
unsigned Reg = GPRBegin;
Reg <= GPREnd; ++
Reg) {
2523 if (
MRI.isPhysRegModified(Reg)) {
2524 GPRSaved = GPREnd -
Reg + 1;
2532 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, HasExtensionTable);
2534 GENVALUECOMMENT(
", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
2536 OutStreamer->emitIntValueInHexWithPadding(
2537 (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
2541 SecondHalfOfMandatoryField |=
2545 NumberOfFixedParms);
2547 OutStreamer->emitIntValueInHexWithPadding(
2548 (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2556 SecondHalfOfMandatoryField |=
2561 NumberOfFloatingPointParms);
2562 GENBOOLCOMMENT(
", ", SecondHalfOfMandatoryField, HasParmsOnStack);
2564 OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
2570 if (NumberOfFixedParms || NumberOfFPParms) {
2576 ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
2583 CommentOS <<
"Parameter type = " << ParmsType.
get();
2586 OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
2587 sizeof(ParmsTypeValue));
2590 OutStreamer->AddComment(
"Function size");
2592 MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
2594 OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
2606 int16_t NameLength =
Name.size();
2607 CommentOS <<
"Function name len = "
2608 <<
static_cast<unsigned int>(NameLength);
2609 EmitCommentAndValue(NameLength, 2);
2610 OutStreamer->AddComment(
"Function Name");
2611 OutStreamer->emitBytes(
Name);
2616 OutStreamer->AddComment(
"AllocaUsed");
2617 OutStreamer->emitIntValueInHex(AllocReg,
sizeof(AllocReg));
2650 OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
2655 OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
2663 CommentOS <<
"Vector Parameter type = " << VecParmsType.
get();
2666 OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
2667 sizeof(VecParmTypeValue));
2669 CommentOS <<
"Padding";
2670 EmitCommentAndValue(0, 2);
2673 uint8_t ExtensionTableFlag = 0;
2675 if (ShouldEmitEHBlock)
2676 ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
2679 ExtensionTableFlag |= ExtendedTBTableFlag::TB_SSP_CANARY;
2681 CommentOS <<
"ExtensionTableFlag = "
2683 EmitCommentAndValue(ExtensionTableFlag,
sizeof(ExtensionTableFlag));
2686 if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
2687 auto &Ctx = OutStreamer->getContext();
2690 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym, TOCType_EHBlock);
2692 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2693 ->getQualNameSymbol();
2699 OutStreamer->emitValueToAlignment(
Align(4));
2700 OutStreamer->AddComment(
"EHInfo Table");
2701 OutStreamer->emitValue(Exp,
DL.getPointerSize());
2703#undef GENBOOLCOMMENT
2704#undef GENVALUECOMMENT
2713 .
Case(
"llvm.used",
true)
2715 .
Case(
"llvm.compiler.used",
true)
2721 .
Cases(
"llvm.global_ctors",
"llvm.global_dtors",
true)
2726 if (
auto *GA = dyn_cast<GlobalAlias>(
C))
2727 return getAliasOffset(GA->getAliasee());
2728 if (
auto *CE = dyn_cast<ConstantExpr>(
C)) {
2730 const MCBinaryExpr *CBE = dyn_cast<MCBinaryExpr>(LowC);
2735 auto *
RHS = dyn_cast<MCConstantExpr>(CBE->
getRHS());
2738 return RHS->getValue();
2748 "GlobalVariables with an alignment requirement stricter than TOC entry "
2749 "size not supported by the toc data transformation.");
2752 assert(GVType->
isSized() &&
"A GlobalVariable's size must be known to be "
2753 "supported by the toc data transformation.");
2757 "A GlobalVariable with size larger than a TOC entry is not currently "
2758 "supported by the toc data transformation.");
2761 "currently supported by the toc data transformation.");
2764void PPCAIXAsmPrinter::emitGlobalVariable(
const GlobalVariable *GV) {
2774 TOCDataGlobalVars.push_back(GV);
2778 emitGlobalVariableHelper(GV);
2781void PPCAIXAsmPrinter::emitGlobalVariableHelper(
const GlobalVariable *GV) {
2783 "Unhandled intrinsic global variable.");
2791 emitLinkage(GV, GVSym);
2795 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
2799 "not supported yet.");
2806 OutStreamer->getCommentOS() <<
'\n';
2811 getObjFileLowering().SectionForGlobal(GV, GVKind, TM));
2814 OutStreamer->switchSection(Csect);
2827 OutStreamer->emitZeros(
Size);
2830 "BSS local toc-data already handled and TLS variables "
2831 "incompatible with XMC_TD");
2832 OutStreamer->emitXCOFFLocalCommonSymbol(
2836 OutStreamer->emitCommonSymbol(GVSym,
Size, Alignment);
2844 emitLinkage(GV, EmittedInitSym);
2846 emitLinkage(GA, getSymbol(GA));
2848 emitAlignment(getGVAlignment(GV,
DL), GV);
2852 if (!
TM.getDataSections() || GV->hasSection()) {
2854 OutStreamer->emitLabel(EmittedInitSym);
2858 if (!GOAliasMap[GV].
size()) {
2859 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer());
2865 AliasMapTy AliasList;
2867 AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);
2870 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer(),
2874void PPCAIXAsmPrinter::emitFunctionDescriptor() {
2876 const unsigned PointerSize =
DL.getPointerSizeInBits() == 64 ? 8 : 4;
2880 OutStreamer->switchSection(
2881 cast<MCSymbolXCOFF>(CurrentFnDescSym)->getRepresentedCsect());
2885 OutStreamer->emitLabel(getSymbol(Alias));
2892 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2893 ->getQualNameSymbol();
2897 OutStreamer->emitIntValue(0, PointerSize);
2899 OutStreamer->switchSection(Current.first, Current.second);
2902void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2906 PPCAsmPrinter::emitFunctionEntryLabel();
2910 OutStreamer->emitLabel(
2911 getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM));
2914void PPCAIXAsmPrinter::emitPGORefs(
Module &M) {
2915 if (!OutContext.hasXCOFFSection(
2926 bool HasNonZeroLengthPrfCntsSection =
false;
2929 if (GV.hasSection() && GV.getSection() ==
"__llvm_prf_cnts" &&
2930 DL.getTypeAllocSize(GV.getValueType()) > 0) {
2931 HasNonZeroLengthPrfCntsSection =
true;
2935 if (HasNonZeroLengthPrfCntsSection) {
2936 MCSection *CntsSection = OutContext.getXCOFFSection(
2941 OutStreamer->switchSection(CntsSection);
2942 if (OutContext.hasXCOFFSection(
2945 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_data[RW]");
2946 OutStreamer->emitXCOFFRefDirective(S);
2948 if (OutContext.hasXCOFFSection(
2951 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_names[RO]");
2952 OutStreamer->emitXCOFFRefDirective(S);
2954 if (OutContext.hasXCOFFSection(
2957 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_vnds[RW]");
2958 OutStreamer->emitXCOFFRefDirective(S);
2963void PPCAIXAsmPrinter::emitGCOVRefs() {
2964 if (!OutContext.hasXCOFFSection(
2965 "__llvm_gcov_ctr_section",
2969 MCSection *CtrSection = OutContext.getXCOFFSection(
2974 OutStreamer->switchSection(CtrSection);
2977 if (OutContext.hasXCOFFSection(
2980 const char *SymbolStr =
TM.Options.XCOFFReadOnlyPointers
2981 ?
"__llvm_covinit[RO]"
2982 :
"__llvm_covinit[RW]";
2983 MCSymbol *S = OutContext.getOrCreateSymbol(SymbolStr);
2984 OutStreamer->emitXCOFFRefDirective(S);
2988void PPCAIXAsmPrinter::emitEndOfAsmFile(
Module &M) {
2991 if (
M.empty() && TOCDataGlobalVars.empty())
2998 OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());
3003 for (
auto &
I : TOC) {
3010 if (
I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM ||
3011 (Subtarget->hasAIXShLibTLSModelOpt() &&
3012 I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD)) {
3016 Name += cast<MCSymbolXCOFF>(
I.first.first)->getSymbolTableName();
3018 TCEntry = cast<MCSectionXCOFF>(
3019 getObjFileLowering().getSectionForTOCEntry(S, TM));
3021 TCEntry = cast<MCSectionXCOFF>(
3022 getObjFileLowering().getSectionForTOCEntry(
I.first.first, TM));
3024 OutStreamer->switchSection(TCEntry);
3026 OutStreamer->emitLabel(
I.second);
3033 for (
const auto *GV : TOCDataGlobalVars) {
3034 if (!GV->hasCommonLinkage())
3035 emitGlobalVariableHelper(GV);
3037 for (
const auto *GV : TOCDataGlobalVars) {
3038 if (GV->hasCommonLinkage())
3039 emitGlobalVariableHelper(GV);
3043bool PPCAIXAsmPrinter::doInitialization(
Module &M) {
3044 const bool Result = PPCAsmPrinter::doInitialization(M);
3054 if (FunCpuId > TargetCpuId)
3055 TargetCpuId = FunCpuId;
3070 auto setCsectAlignment = [
this](
const GlobalObject *GO) {
3072 if (GO->isDeclarationForLinker())
3075 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);
3077 getObjFileLowering().SectionForGlobal(GO, GOKind, TM));
3079 Align GOAlign = getGVAlignment(GO, GO->getDataLayout());
3087 auto DL =
M.getDataLayout();
3088 for (
const auto &
G :
M.globals()) {
3089 if (
G.isThreadLocal() && !
G.isDeclaration()) {
3090 TLSVarAddress =
alignTo(TLSVarAddress, getGVAlignment(&
G,
DL));
3091 TLSVarsToAddressMapping[&
G] = TLSVarAddress;
3092 TLSVarAddress +=
DL.getTypeAllocSize(
G.getValueType());
3099 for (
const auto &
G :
M.globals()) {
3106 if (FormatIndicatorAndUniqueModId.empty()) {
3108 if (UniqueModuleId !=
"")
3112 FormatIndicatorAndUniqueModId =
"clang_" + UniqueModuleId.substr(1);
3117 std::chrono::duration_cast<std::chrono::nanoseconds>(
3118 std::chrono::steady_clock::now().time_since_epoch())
3120 FormatIndicatorAndUniqueModId =
3123 llvm::itostr(CurTime);
3127 emitSpecialLLVMGlobal(&
G);
3131 setCsectAlignment(&
G);
3132 std::optional<CodeModel::Model> OptionalCodeModel =
G.getCodeModel();
3133 if (OptionalCodeModel)
3135 *OptionalCodeModel);
3138 for (
const auto &
F : M)
3139 setCsectAlignment(&
F);
3142 for (
const auto &Alias :
M.aliases()) {
3146 "alias without a base object is not yet supported on AIX");
3150 "\n\tAlias attribute for " +
3151 Alias.getGlobalIdentifier() +
3152 " is invalid because " + Aliasee->
getName() +
3158 dyn_cast_or_null<GlobalVariable>(Alias.getAliaseeObject());
3160 std::optional<CodeModel::Model> OptionalCodeModel = GVar->
getCodeModel();
3161 if (OptionalCodeModel)
3163 *OptionalCodeModel);
3166 GOAliasMap[Aliasee].push_back(&Alias);
3173 switch (
MI->getOpcode()) {
3180 if (
MI->getNumOperands() < 5)
3186 MCSymbol *TempSym = OutContext.createNamedTempSymbol();
3187 OutStreamer->emitLabel(TempSym);
3188 OutStreamer->emitXCOFFExceptDirective(
3189 CurrentFnSym, TempSym, LangMO.
getImm(), ReasonMO.
getImm(),
3190 Subtarget->
isPPC64() ?
MI->getMF()->getInstructionCount() * 8
3191 :
MI->getMF()->getInstructionCount() * 4,
3195 case PPC::GETtlsMOD32AIX:
3196 case PPC::GETtlsMOD64AIX:
3197 case PPC::GETtlsTpointer32AIX:
3198 case PPC::GETtlsADDR64AIX:
3199 case PPC::GETtlsADDR32AIX: {
3204 ExtSymSDNodeSymbols.insert(TlsGetAddr);
3214 cast<MCSymbolXCOFF>(OutContext.getOrCreateSymbol(MO.
getSymbolName()));
3215 ExtSymSDNodeSymbols.insert(S);
3221 case PPC::BL8_NOP_TLS:
3228 case PPC::TAILBCTR8:
3229 if (
MI->getOperand(0).isSymbol())
3242 MCInstBuilder(PPC::ORI).addReg(PPC::R0).addReg(PPC::R0).addImm(0));
3245 return PPCAsmPrinter::emitInstruction(
MI);
3248bool PPCAIXAsmPrinter::doFinalization(
Module &M) {
3251 OutStreamer->doFinalizationAtSectionEnd(
3252 OutStreamer->getContext().getObjectFileInfo()->getTextSection());
3256 return PPCAsmPrinter::doFinalization(M);
3260 if (P < 0 || P > 65535)
3267 return 20 + (
P - 20) * 16;
3270 return 1004 + (
P - 81);
3273 return 2047 + (
P - 1124) * 33878;
3275 return 2147482625u + (
P - 64512);
3294 std::string PrioritySuffix;
3297 return PrioritySuffix;
3300void PPCAIXAsmPrinter::emitXXStructorList(
const DataLayout &
DL,
3301 const Constant *List,
bool IsCtor) {
3303 preprocessXXStructorList(
DL, List, Structors);
3304 if (Structors.
empty())
3308 for (Structor &S : Structors) {
3309 if (
const ConstantExpr *CE = dyn_cast<ConstantExpr>(S.Func))
3310 S.Func =
CE->getOperand(0);
3318 cast<Function>(S.Func));
3322void PPCAIXAsmPrinter::emitTTypeReference(
const GlobalValue *GV,
3323 unsigned Encoding) {
3325 TOCEntryType GlobalType = TOCType_GlobalInternal;
3330 GlobalType = TOCType_GlobalExternal;
3332 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym, GlobalType);
3334 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
3335 ->getQualNameSymbol();
3336 auto &Ctx = OutStreamer->getContext();
3340 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
3342 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
3349 std::unique_ptr<MCStreamer> &&Streamer) {
3351 return new PPCAIXAsmPrinter(tm, std::move(Streamer));
3353 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
3356void PPCAIXAsmPrinter::emitModuleCommandLines(
Module &M) {
3357 const NamedMDNode *NMD =
M.getNamedMetadata(
"llvm.commandline");
3365 assert(
N->getNumOperands() == 1 &&
3366 "llvm.commandline metadata entry can have only one operand");
3367 const MDString *MDS = cast<MDString>(
N->getOperand(0));
3370 RSOS <<
"@(#)opt " << MDS->
getString() <<
"\n";
3373 OutStreamer->emitXCOFFCInfoSym(
".GCC.command.line", RSOS.str());
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#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)
This file implements a map that provides insertion order iteration.
static void collectTOCStats(PPCAsmPrinter::TOCEntryType Type)
static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV)
static bool isSpecialLLVMGlobalArrayToSkip(const GlobalVariable *GV)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCAsmPrinter()
#define GENBOOLCOMMENT(Prefix, V, Field)
static MCSymbol * getMCSymbolForTOCPseudoMO(const MachineOperand &MO, AsmPrinter &AP)
Map a machine operand for a TOC pseudo-machine instruction to its corresponding MCSymbol.
static void setOptionalCodeModel(MCSymbolXCOFF *XSym, CodeModel::Model CM)
static AsmPrinter * createPPCAsmPrinterPass(TargetMachine &tm, std::unique_ptr< MCStreamer > &&Streamer)
static PPCAsmPrinter::TOCEntryType getTOCEntryTypeForMO(const MachineOperand &MO)
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
static std::string convertToSinitPriority(int Priority)
static MCSymbol * createMCSymbolForTlsGetAddr(MCContext &Ctx, unsigned MIOpc)
This helper function creates the TlsGetAddr/TlsGetMod MCSymbol for AIX.
#define GENVALUECOMMENT(PrefixAndName, V, Field)
static unsigned mapToSinitPriority(int P)
static void tocDataChecks(unsigned PointerSize, const GlobalVariable *GV)
static cl::opt< bool > EnableSSPCanaryBitInTB("aix-ssp-tb-bit", cl::init(false), cl::desc("Enable Passing SSP Canary info in Trackback on AIX"), cl::Hidden)
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
virtual void emitInstruction(const MachineInstr *)
Targets should implement this to emit instructions.
MCSymbol * getSymbol(const GlobalValue *GV) const
void emitXRayTable()
Emit a table with all XRay instrumentation points.
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
virtual void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &OS)
Print the MachineOperand as a symbol.
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.
virtual bool PrintAsmMemoryOperand(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 as...
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.
A constant value that is initialized with an expression using other constant values.
This is an important base class in LLVM.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
unsigned getPointerSize(unsigned AS=0) const
Layout pointer size in bytes, rounded up to a whole number of bytes.
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
static 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...
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
bool hasSection() const
Check if this global has a custom object file section.
VisibilityTypes getVisibility() const
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
LinkageTypes getLinkage() const
bool hasDefaultVisibility() const
bool hasPrivateLinkage() const
ThreadLocalMode getThreadLocalMode() const
bool hasDLLExportStorageClass() const
bool isDeclarationForLinker() const
Module * getParent()
Get the module that this global value is contained inside of...
const GlobalObject * getAliaseeObject() const
@ DefaultVisibility
The GV is visible.
@ HiddenVisibility
The GV is hidden.
@ ProtectedVisibility
The GV is protected.
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.
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ CommonLinkage
Tentative definitions.
@ InternalLinkage
Rename collisions when linking (static functions).
@ LinkOnceAnyLinkage
Keep one copy of function when linking (inline)
@ WeakODRLinkage
Same, but only replaced by something equivalent.
@ ExternalLinkage
Externally visible function.
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
@ AppendingLinkage
Special purpose, only applies to global arrays.
@ AvailableExternallyLinkage
Available for inspection, not emission.
@ ExternalWeakLinkage
ExternalWeak linkage description.
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
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.
Binary assembler expressions.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Opcode getOpcode() const
Get the kind of this binary expression.
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
MCSectionXCOFF * getXCOFFSection(StringRef Section, SectionKind K, std::optional< XCOFF::CsectProperties > CsectProp=std::nullopt, bool MultiSymbolsAllowed=false, std::optional< XCOFF::DwarfSectionSubtypeFlags > DwarfSubtypeFlags=std::nullopt)
Base class for the full range of assembler expressions which are needed for parsing.
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Instances of this class represent operands of the MCInst class.
static MCOperand createExpr(const MCExpr *Val)
MCRegister getReg() const
Returns the register number.
This represents a section on linux, lots of unix variants and some bare metal systems.
XCOFF::StorageMappingClass getMappingClass() const
MCSymbolXCOFF * getQualNameSymbol() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
void setAlignment(Align Value)
void ensureMinAlignment(Align MinAlignment)
Makes sure that Alignment is at least MinAlignment.
Represent a reference to a symbol from inside an expression.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
StringRef getSymbolTableName() const
void setPerSymbolCodeModel(MCSymbolXCOFF::CodeModel Model)
void setStorageClass(XCOFF::StorageClass SC)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
StringRef getString() const
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...
Representation of each machine instruction.
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.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This class implements a map that also provides access to all stored values in a deterministic order.
iterator find(const KeyT &Key)
A Module instance is used to store all the information related to an LLVM module.
MDNode * getOperand(unsigned i) const
unsigned getNumOperands() const
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...
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)
static const PPCMCExpr * createLo(const MCExpr *Expr, MCContext &Ctx)
static const PPCMCExpr * createHa(const MCExpr *Expr, MCContext &Ctx)
bool is32BitELFABI() const
const PPCFrameLowering * getFrameLowering() const override
bool isPPC64() const
isPPC64 - Return true if we are generating code for 64-bit pointer mode.
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.
Common code between 32-bit and 64-bit PowerPC targets.
bool hasGlibcHWCAPAccess() const
virtual void emitAbiVersion(int AbiVersion)
virtual void emitTCEntry(const MCSymbol &S, MCSymbolRefExpr::VariantKind Kind)
virtual void emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset)
virtual void emitMachine(StringRef CPU)
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
MI-level patchpoint operands.
Wrapper class representing virtual and physical registers.
SectionKind - This is a simple POD value that classifies the properties of a section.
bool isThreadBSSLocal() const
static SectionKind getText()
static SectionKind getData()
bool isThreadLocal() const
bool isGlobalWriteableData() const
A SetVector that performs no allocations if smaller than a certain size.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
void recordStackMap(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
StringRef - Represent a constant reference to a string, i.e.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
static bool ShouldSetSSPCanaryBitInTB(const MachineFunction *MF)
static MCSymbol * getEHInfoTableSymbol(const MachineFunction *MF)
static XCOFF::StorageClass getStorageClassForGlobal(const GlobalValue *GV)
static bool ShouldEmitEHBlock(const MachineFunction *MF)
Primary interface to the complete machine description for the target machine.
const Triple & getTargetTriple() const
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
bool isOSAIX() const
Tests whether the OS is AIX.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
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.
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
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.
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.
A raw_ostream that writes to an SmallVector or SmallString.
static Pid getProcessId()
Get the process's identifier.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
@ 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...
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(unsigned Reg)
static bool isVFRegister(unsigned Reg)
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
SmallString< 32 > getExtendedTBTableFlagString(uint8_t Flag)
XCOFF::CFileCpuId getCpuID(StringRef CPU)
Expected< SmallString< 32 > > parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum, unsigned VectorParmsNum)
Expected< SmallString< 32 > > parseParmsType(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum)
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.
StringRef getTCPUString(XCOFF::CFileCpuId TCPU)
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.
Linkage
Describes symbol linkage. This can be used to resolve definition clashes.
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.
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.
bool LowerPPCMachineOperandToMCOperand(const MachineOperand &MO, MCOperand &OutMO, AsmPrinter &AP)
Target & getThePPC32Target()
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...
std::pair< MCSection *, uint32_t > MCSectionSubPair
void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
FormattedNumber format_hex_no_prefix(uint64_t N, unsigned Width, bool Upper=false)
format_hex_no_prefix - Output N as a fixed width hexadecimal.
Target & getThePPC64Target()
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.
Target & getThePPC32LETarget()
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
const char * toString(DWARFSectionKind Kind)
@ MCSA_Global
.type _foo, @gnu_unique_object
@ MCSA_Extern
.extern (XCOFF)
@ MCSA_LGlobal
.lglobl (XCOFF)
@ MCSA_Invalid
Not a valid directive.
Implement std::hash so that hash_code can be used in STL containers.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
static unsigned getHashValue(const TOCKey &PairVal)
static bool isEqual(const TOCKey &A, const TOCKey &B)
std::pair< const MCSymbol *, MCSymbolRefExpr::VariantKind > TOCKey
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