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);
293 void emitEndOfAsmFile(
Module &)
override;
299 bool doFinalization(
Module &M)
override;
301 void emitTTypeReference(
const GlobalValue *GV,
unsigned Encoding)
override;
303 void emitModuleCommandLines(
Module &M)
override;
312 getSymbol(GV)->
print(O, MAI);
316void PPCAsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNo,
339 O <<
DL.getPrivateGlobalPrefix() <<
"CPI" << getFunctionNumber() <<
'_'
346 PrintSymbolOperand(MO, O);
358bool PPCAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
361 if (ExtraCode && ExtraCode[0]) {
362 if (ExtraCode[1] != 0)
return true;
364 switch (ExtraCode[0]) {
370 if (!
MI->getOperand(OpNo).isReg() ||
371 OpNo+1 ==
MI->getNumOperands() ||
372 !
MI->getOperand(OpNo+1).isReg())
379 if (
MI->getOperand(OpNo).isImm())
383 if(!
MI->getOperand(OpNo).isReg())
389 Reg = PPC::VSX32 + (
Reg - PPC::V0);
391 Reg = PPC::VSX32 + (Reg - PPC::VF0);
407bool PPCAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNo,
408 const char *ExtraCode,
410 if (ExtraCode && ExtraCode[0]) {
411 if (ExtraCode[1] != 0)
return true;
413 switch (ExtraCode[0]) {
414 default:
return true;
416 O << getDataLayout().getPointerSize() <<
"(";
427 if (
MI->getOperand(OpNo).isImm())
438 assert(
MI->getOperand(OpNo).isReg());
443 assert(
MI->getOperand(OpNo).isReg());
453 case PPCAsmPrinter::TOCType_ConstantPool:
456 case PPCAsmPrinter::TOCType_GlobalInternal:
457 ++NumTOCGlobalInternal;
459 case PPCAsmPrinter::TOCType_GlobalExternal:
460 ++NumTOCGlobalExternal;
462 case PPCAsmPrinter::TOCType_JumpTable:
465 case PPCAsmPrinter::TOCType_ThreadLocal:
468 case PPCAsmPrinter::TOCType_BlockAddress:
469 ++NumTOCBlockAddress;
471 case PPCAsmPrinter::TOCType_EHBlock:
488 assert(GV &&
"expected global for MO_GlobalAddress");
510PPCAsmPrinter::lookUpOrCreateTOCEntry(
const MCSymbol *
Sym, TOCEntryType
Type,
513 if (!
TOC.contains({Sym, Kind}))
518 TOCEntry = createTempSymbol(
"C");
523 unsigned NumNOPBytes =
MI.getOperand(1).getImm();
525 auto &Ctx = OutStreamer->getContext();
526 MCSymbol *MILabel = Ctx.createTempSymbol();
527 OutStreamer->emitLabel(MILabel);
530 assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
536 while (NumNOPBytes > 0) {
537 if (MII ==
MBB.
end() || MII->isCall() ||
538 MII->getOpcode() == PPC::DBG_VALUE ||
539 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
540 MII->getOpcode() == TargetOpcode::STACKMAP)
547 for (
unsigned i = 0; i < NumNOPBytes; i += 4)
554 auto &Ctx = OutStreamer->getContext();
555 MCSymbol *MILabel = Ctx.createTempSymbol();
556 OutStreamer->emitLabel(MILabel);
561 unsigned EncodedBytes = 0;
564 if (CalleeMO.
isImm()) {
565 int64_t CallTarget = CalleeMO.
getImm();
567 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
568 "High 16 bits of call target should be zero.");
569 Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
574 .addImm((CallTarget >> 32) & 0xFFFF));
579 .addImm(32).addImm(16));
584 .addImm((CallTarget >> 16) & 0xFFFF));
589 .addImm(CallTarget & 0xFFFF));
595 .addImm(TOCSaveOffset)
608 .addReg(ScratchReg));
613 .addReg(ScratchReg));
618 .addReg(ScratchReg));
626 .addImm(TOCSaveOffset)
632 MCSymbol *MOSymbol = getSymbol(GValue);
644 unsigned NumBytes = Opers.getNumPatchBytes();
645 assert(NumBytes >= EncodedBytes &&
646 "Patchpoint can't request size less than the length of a call.");
647 assert((NumBytes - EncodedBytes) % 4 == 0 &&
648 "Invalid number of NOP bytes requested!");
649 for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
660 SymName =
".__tls_get_addr";
662 case PPC::GETtlsTpointer32AIX:
663 SymName =
".__get_tpointer";
665 case PPC::GETtlsMOD32AIX:
666 case PPC::GETtlsMOD64AIX:
667 SymName =
".__tls_get_mod";
678 "Only expecting to emit calls to get the thread pointer on AIX!");
683 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::BLA).addExpr(TlsRef));
691 unsigned Opcode = PPC::BL8_NOP_TLS;
693 assert(
MI->getNumOperands() >= 3 &&
"Expecting at least 3 operands from MI");
697 Opcode = PPC::BL8_NOTOC_TLS;
699 const Module *
M = MF->getFunction().getParent();
702 ((Subtarget->
isPPC64() &&
MI->getOperand(0).getReg() == PPC::X3) ||
703 (!Subtarget->
isPPC64() &&
MI->getOperand(0).getReg() == PPC::R3)) &&
704 "GETtls[ld]ADDR[32] must define GPR3");
706 ((Subtarget->
isPPC64() &&
MI->getOperand(1).getReg() == PPC::X3) ||
707 (!Subtarget->
isPPC64() &&
MI->getOperand(1).getReg() == PPC::R3)) &&
708 "GETtls[ld]ADDR[32] must read GPR3");
717 assert((
MI->getOpcode() == PPC::GETtlsMOD32AIX ||
718 MI->getOpcode() == PPC::GETtlsMOD64AIX ||
719 (
MI->getOperand(2).isReg() &&
720 MI->getOperand(2).getReg() == VarOffsetReg)) &&
721 "GETtls[ld]ADDR[32] must read GPR4");
722 EmitAIXTlsCallHelper(
MI);
726 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(
"__tls_get_addr");
741 MCSymbol *MOSymbol = getSymbol(GValue);
743 EmitToStreamer(*OutStreamer,
745 : (
unsigned)PPC::BL_TLS)
768static PPCAsmPrinter::TOCEntryType
773 return PPCAsmPrinter::TOCType_ThreadLocal;
782 return PPCAsmPrinter::TOCType_GlobalExternal;
784 return PPCAsmPrinter::TOCType_GlobalInternal;
787 return PPCAsmPrinter::TOCType_ConstantPool;
789 return PPCAsmPrinter::TOCType_JumpTable;
791 return PPCAsmPrinter::TOCType_BlockAddress;
800 PPC_MC::verifyInstructionPredicates(
MI->getOpcode(),
801 getSubtargetInfo().getFeatureBits());
804 const bool IsPPC64 = Subtarget->
isPPC64();
805 const bool IsAIX = Subtarget->
isAIXABI();
806 const bool HasAIXSmallLocalTLS = Subtarget->hasAIXSmallLocalExecTLS() ||
807 Subtarget->hasAIXSmallLocalDynamicTLS();
808 const Module *
M = MF->getFunction().getParent();
813 if (!
MI->isInlineAsm()) {
817 if (Subtarget->hasSPE()) {
818 if (PPC::F4RCRegClass.
contains(Reg) ||
827 if (PPC::SPERCRegClass.
contains(Reg))
835 auto getTOCRelocAdjustedExprForXCOFF = [
this](
const MCExpr *Expr,
844 OriginalOffset - llvm::SignExtend32<16>(OriginalOffset);
849 auto getTOCEntryLoadingExprForXCOFF =
850 [IsPPC64, getTOCRelocAdjustedExprForXCOFF,
853 MCSymbolRefExpr::VariantKind::VK_None) ->
const MCExpr * {
854 const unsigned EntryByteSize = IsPPC64 ? 8 : 4;
855 const auto TOCEntryIter =
TOC.find({MOSymbol, VK});
857 "Could not find the TOC entry for this symbol.");
858 const ptrdiff_t EntryDistanceFromTOCBase =
859 (TOCEntryIter -
TOC.begin()) * EntryByteSize;
860 constexpr int16_t PositiveTOCRange = INT16_MAX;
862 if (EntryDistanceFromTOCBase > PositiveTOCRange)
863 return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase);
875 assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!\n");
878 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE;
880 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
887 dbgs() <<
"Current function uses IE access for default LD vars.\n");
888 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE;
896 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM;
898 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD;
903 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD;
905 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSML;
906 return MCSymbolRefExpr::VariantKind::VK_None;
910 switch (
MI->getOpcode()) {
912 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
914 "AIX does not support patchable function entry!");
917 if (MAI->isLittleEndian())
921 (void)
F.getFnAttribute(
"patchable-function-entry")
923 .getAsInteger(10, Num);
929 case TargetOpcode::DBG_VALUE:
931 case TargetOpcode::STACKMAP:
932 return LowerSTACKMAP(SM, *
MI);
933 case TargetOpcode::PATCHPOINT:
934 return LowerPATCHPOINT(SM, *
MI);
936 case PPC::MoveGOTtoLR: {
944 OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
953 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::BL).addExpr(OffsExpr));
956 case PPC::MovePCtoLR:
957 case PPC::MovePCtoLR8: {
962 MCSymbol *PICBase = MF->getPICBaseSymbol();
965 EmitToStreamer(*OutStreamer,
972 OutStreamer->emitLabel(PICBase);
975 case PPC::UpdateGBR: {
984 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
986 MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
998 MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));
1003 MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
1023 EmitToStreamer(*OutStreamer, TmpInst);
1029 EmitToStreamer(*OutStreamer, TmpInst);
1042 "Invalid operand for LWZtoc.");
1054 EmitToStreamer(*OutStreamer, TmpInst);
1074 "This pseudo should only be selected for 32-bit small code model.");
1075 Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK);
1080 OutStreamer->getCommentOS() << MO <<
'\n';
1081 EmitToStreamer(*OutStreamer, TmpInst);
1088 OutContext.getOrCreateSymbol(
Twine(
".LTOC")), OutContext);
1091 EmitToStreamer(*OutStreamer, TmpInst);
1095 case PPC::ADDItoc8: {
1097 "PseudoOp only valid for small code model AIX");
1103 TmpInst.
setOpcode((!IsPPC64) ? (PPC::LA) : (PPC::LA8));
1115 EmitToStreamer(*OutStreamer, TmpInst);
1130 "Invalid operand!");
1147 IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK) : Exp);
1150 if (isVerbose() && IsAIX)
1151 OutStreamer->getCommentOS() << MO <<
'\n';
1152 EmitToStreamer(*OutStreamer, TmpInst);
1155 case PPC::ADDIStocHA: {
1159 "Invalid operand for ADDIStocHA.");
1160 assert((IsAIX && !IsPPC64 &&
1162 "This pseudo should only be selected for 32-bit large code model on"
1189 return GV->hasAttribute(
"toc-data");
1197 EmitToStreamer(*OutStreamer, TmpInst);
1200 case PPC::LWZtocL: {
1204 "Invalid operand for LWZtocL.");
1205 assert(IsAIX && !IsPPC64 &&
1207 "This pseudo should only be selected for 32-bit large code model on"
1231 EmitToStreamer(*OutStreamer, TmpInst);
1234 case PPC::ADDIStocHA8: {
1246 "Invalid operand for ADDIStocHA8!");
1252 const bool GlobalToc =
1274 EmitToStreamer(*OutStreamer, TmpInst);
1290 "Invalid operand for LDtocL!");
1294 "LDtocL used on symbol that could be accessed directly is "
1295 "invalid. Must match ADDIStocHA8."));
1309 EmitToStreamer(*OutStreamer, TmpInst);
1313 case PPC::ADDItocL8: {
1317 unsigned Op =
MI->getOpcode();
1321 TmpInst.
setOpcode(
Op == PPC::ADDItocL8 ? (IsAIX ? PPC::LA8 : PPC::ADDI8)
1327 : MO.
isGlobal() &&
"Invalid operand for ADDItocL8.");
1329 "Interposable definitions must use indirect accesses.");
1340 EmitToStreamer(*OutStreamer, TmpInst);
1343 case PPC::ADDISgotTprelHA: {
1346 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1349 MCSymbol *MOSymbol = getSymbol(GValue);
1350 const MCExpr *SymGotTprel =
1354 .addReg(
MI->getOperand(0).getReg())
1355 .
addReg(
MI->getOperand(1).getReg())
1359 case PPC::LDgotTprelL:
1360 case PPC::LDgotTprelL32: {
1365 TmpInst.
setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ);
1368 MCSymbol *MOSymbol = getSymbol(GValue);
1374 EmitToStreamer(*OutStreamer, TmpInst);
1378 case PPC::PPC32PICGOT: {
1379 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1380 MCSymbol *GOTRef = OutContext.createTempSymbol();
1381 MCSymbol *NextInstr = OutContext.createTempSymbol();
1391 OutStreamer->emitLabel(GOTRef);
1392 OutStreamer->emitValue(OffsExpr, 4);
1393 OutStreamer->emitLabel(NextInstr);
1395 .addReg(
MI->getOperand(0).getReg()));
1397 .addReg(
MI->getOperand(1).getReg())
1399 .
addReg(
MI->getOperand(0).getReg()));
1401 .addReg(
MI->getOperand(0).getReg())
1402 .
addReg(
MI->getOperand(1).getReg())
1403 .
addReg(
MI->getOperand(0).getReg()));
1406 case PPC::PPC32GOT: {
1408 OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1414 .addReg(
MI->getOperand(0).getReg())
1417 .addReg(
MI->getOperand(0).getReg())
1418 .
addReg(
MI->getOperand(0).getReg())
1422 case PPC::ADDIStlsgdHA: {
1425 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1428 MCSymbol *MOSymbol = getSymbol(GValue);
1429 const MCExpr *SymGotTlsGD =
1433 .addReg(
MI->getOperand(0).getReg())
1434 .
addReg(
MI->getOperand(1).getReg())
1438 case PPC::ADDItlsgdL:
1441 case PPC::ADDItlsgdL32: {
1446 MCSymbol *MOSymbol = getSymbol(GValue);
1451 EmitToStreamer(*OutStreamer,
1453 .addReg(
MI->getOperand(0).getReg())
1454 .
addReg(
MI->getOperand(1).getReg())
1458 case PPC::GETtlsMOD32AIX:
1459 case PPC::GETtlsMOD64AIX:
1463 case PPC::GETtlsADDR:
1466 case PPC::GETtlsADDRPCREL:
1467 case PPC::GETtlsADDR32AIX:
1468 case PPC::GETtlsADDR64AIX:
1472 case PPC::GETtlsADDR32: {
1478 case PPC::GETtlsTpointer32AIX: {
1481 EmitAIXTlsCallHelper(
MI);
1484 case PPC::ADDIStlsldHA: {
1487 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1490 MCSymbol *MOSymbol = getSymbol(GValue);
1491 const MCExpr *SymGotTlsLD =
1495 .addReg(
MI->getOperand(0).getReg())
1496 .
addReg(
MI->getOperand(1).getReg())
1500 case PPC::ADDItlsldL:
1503 case PPC::ADDItlsldL32: {
1508 MCSymbol *MOSymbol = getSymbol(GValue);
1513 EmitToStreamer(*OutStreamer,
1515 .addReg(
MI->getOperand(0).getReg())
1516 .
addReg(
MI->getOperand(1).getReg())
1520 case PPC::GETtlsldADDR:
1523 case PPC::GETtlsldADDRPCREL:
1524 case PPC::GETtlsldADDR32: {
1530 case PPC::ADDISdtprelHA:
1533 case PPC::ADDISdtprelHA32: {
1538 MCSymbol *MOSymbol = getSymbol(GValue);
1539 const MCExpr *SymDtprel =
1545 .addReg(
MI->getOperand(0).getReg())
1546 .
addReg(
MI->getOperand(1).getReg())
1550 case PPC::PADDIdtprel: {
1555 MCSymbol *MOSymbol = getSymbol(GValue);
1559 .addReg(
MI->getOperand(0).getReg())
1560 .
addReg(
MI->getOperand(1).getReg())
1565 case PPC::ADDIdtprelL:
1568 case PPC::ADDIdtprelL32: {
1573 MCSymbol *MOSymbol = getSymbol(GValue);
1574 const MCExpr *SymDtprel =
1577 EmitToStreamer(*OutStreamer,
1579 .addReg(
MI->getOperand(0).getReg())
1580 .
addReg(
MI->getOperand(1).getReg())
1586 if (!Subtarget->hasMFOCRF()) {
1589 unsigned NewOpcode =
1590 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
1594 .addReg(
MI->getOperand(0).getReg()));
1600 if (!Subtarget->hasMFOCRF()) {
1603 unsigned NewOpcode =
1604 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1605 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
1606 ->getEncodingValue(
MI->getOperand(0).getReg());
1611 .addReg(
MI->getOperand(1).getReg()));
1621 unsigned OpNum = (
MI->getOpcode() == PPC::STD) ? 2 : 1;
1628 TempMO.getOperandNo() == 1)
1665 if (!HasAIXSmallLocalTLS)
1667 bool IsMIADDI8 =
MI->getOpcode() == PPC::ADDI8;
1668 unsigned OpNum = IsMIADDI8 ? 2 : 1;
1684 EmitToStreamer(*OutStreamer, TmpInst);
1690 case PPC::PseudoEIEIO: {
1693 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1696 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1697 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::EnforceIEIO));
1703 EmitToStreamer(*OutStreamer, TmpInst);
1713PPCAsmPrinter::getAdjustedFasterLocalExpr(
const MachineOperand &MO,
1720 assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!");
1724 "Only local-[exec|dynamic] accesses are handled!");
1730 const auto TLSVarsMapEntryIter = TLSVarsToAddressMapping.
find(GValue);
1731 if (TLSVarsMapEntryIter == TLSVarsToAddressMapping.
end())
1732 assert(IsGlobalADeclaration &&
1733 "Only expecting to find extern TLS variables not present in the TLS "
1734 "variable-to-address map!");
1736 unsigned TLSVarAddress =
1737 IsGlobalADeclaration ? 0 : TLSVarsMapEntryIter->second;
1751 if (FinalAddress >= 32768) {
1758 ptrdiff_t Delta = ((FinalAddress + 32768) & ~0xFFFF);
1762 ((InstDisp < 32768) && (InstDisp >= -32768)) &&
1763 "Expecting the instruction displacement for local-[exec|dynamic] TLS "
1764 "variables to be between [-32768, 32768)!");
1772void PPCLinuxAsmPrinter::emitGNUAttributes(
Module &M) {
1774 Metadata *MD =
M.getModuleFlag(
"float-abi");
1775 MDString *FloatABI = dyn_cast_or_null<MDString>(MD);
1780 if (flt ==
"doubledouble")
1781 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1782 Val_GNU_Power_ABI_HardFloat_DP |
1783 Val_GNU_Power_ABI_LDBL_IBM128);
1784 else if (flt ==
"ieeequad")
1785 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1786 Val_GNU_Power_ABI_HardFloat_DP |
1787 Val_GNU_Power_ABI_LDBL_IEEE128);
1788 else if (flt ==
"ieeedouble")
1789 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1790 Val_GNU_Power_ABI_HardFloat_DP |
1791 Val_GNU_Power_ABI_LDBL_64);
1794void PPCLinuxAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
1796 return PPCAsmPrinter::emitInstruction(
MI);
1798 switch (
MI->getOpcode()) {
1801 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1814 if (!MAI->isLittleEndian())
1816 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1817 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1818 OutStreamer->emitLabel(BeginOfSled);
1819 EmitToStreamer(*OutStreamer,
1825 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1826 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1827 EmitToStreamer(*OutStreamer,
1830 OutContext.getOrCreateSymbol(
"__xray_FunctionEntry"),
1832 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1833 OutStreamer->emitLabel(EndOfSled);
1834 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_ENTER, 2);
1837 case TargetOpcode::PATCHABLE_RET: {
1838 unsigned RetOpcode =
MI->getOperand(0).getImm();
1848 if (RetOpcode == PPC::BCCLR) {
1849 IsConditional =
true;
1850 }
else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1851 RetOpcode == PPC::TCRETURNai8) {
1853 }
else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1854 IsConditional =
false;
1856 EmitToStreamer(*OutStreamer, RetInst);
1861 if (IsConditional) {
1880 FallthroughLabel = OutContext.createTempSymbol();
1886 .
addReg(
MI->getOperand(2).getReg())
1903 OutStreamer->emitCodeAlignment(
Align(8), &getSubtargetInfo());
1904 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1905 OutStreamer->emitLabel(BeginOfSled);
1906 EmitToStreamer(*OutStreamer, RetInst);
1910 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1911 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1912 EmitToStreamer(*OutStreamer,
1915 OutContext.getOrCreateSymbol(
"__xray_FunctionExit"),
1917 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1918 EmitToStreamer(*OutStreamer, RetInst);
1920 OutStreamer->emitLabel(FallthroughLabel);
1921 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_EXIT, 2);
1924 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1926 case TargetOpcode::PATCHABLE_TAIL_CALL:
1930 "around this assert.");
1932 return PPCAsmPrinter::emitInstruction(
MI);
1935void PPCLinuxAsmPrinter::emitStartOfAsmFile(
Module &M) {
1943 !isPositionIndependent())
1949 OutStreamer->switchSection(OutContext.getELFSection(
1952 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(
Twine(
".LTOC"));
1953 MCSymbol *CurrentPos = OutContext.createTempSymbol();
1955 OutStreamer->emitLabel(CurrentPos);
1964 OutStreamer->emitAssignment(TOCSym, tocExpr);
1966 OutStreamer->switchSection(getObjFileLowering().getTextSection());
1969void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
1972 (!isPositionIndependent() ||
1978 if (PPCFI->
usesPICBase() && !Subtarget->isSecurePlt()) {
1980 MCSymbol *PICBase = MF->getPICBaseSymbol();
1981 OutStreamer->emitLabel(RelocSymbol);
1989 OutStreamer->emitValue(OffsExpr, 4);
1990 OutStreamer->emitLabel(CurrentFnSym);
2003 && !MF->getRegInfo().use_empty(PPC::X2)) {
2008 const MCExpr *TOCDeltaExpr =
2015 OutStreamer->emitValue(TOCDeltaExpr, 8);
2024 OutStreamer->switchSection(Section);
2025 OutStreamer->emitLabel(CurrentFnSym);
2026 OutStreamer->emitValueToAlignment(
Align(8));
2027 MCSymbol *Symbol1 = CurrentFnSymForSize;
2034 OutStreamer->emitValue(
2038 OutStreamer->emitIntValue(0, 8 );
2039 OutStreamer->switchSection(Current.first, Current.second);
2042void PPCLinuxAsmPrinter::emitEndOfAsmFile(
Module &M) {
2045 bool isPPC64 =
DL.getPointerSizeInBits() == 64;
2055 OutStreamer->emitSymbolValue(
2056 GetExternalSymbolSymbol(
"__parse_hwcap_and_convert_at_platform"),
2057 MAI->getCodePointerSize());
2058 emitGNUAttributes(M);
2061 const char *
Name = isPPC64 ?
".toc" :
".got2";
2064 OutStreamer->switchSection(Section);
2066 OutStreamer->emitValueToAlignment(
Align(4));
2068 for (
const auto &TOCMapPair : TOC) {
2069 const MCSymbol *
const TOCEntryTarget = TOCMapPair.first.first;
2070 MCSymbol *
const TOCEntryLabel = TOCMapPair.second;
2072 OutStreamer->emitLabel(TOCEntryLabel);
2074 TS->
emitTCEntry(*TOCEntryTarget, TOCMapPair.first.second);
2076 OutStreamer->emitSymbolValue(TOCEntryTarget, 4);
2080 PPCAsmPrinter::emitEndOfAsmFile(M);
2084void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
2117 const bool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) ||
2118 !MF->getRegInfo().use_empty(PPC::R2);
2127 if (NonPCrelGEPRequired || PCrelGEPRequired) {
2132 OutStreamer->emitLabel(GlobalEntryLabel);
2138 const MCExpr *TOCDeltaExpr =
2140 GlobalEntryLabelExp, OutContext);
2146 .addExpr(TOCDeltaHi));
2152 .addExpr(TOCDeltaLo));
2155 const MCExpr *TOCOffsetDeltaExpr =
2157 GlobalEntryLabelExp, OutContext);
2161 .addExpr(TOCOffsetDeltaExpr)
2170 OutStreamer->emitLabel(LocalEntryLabel);
2173 const MCExpr *LocalOffsetExp =
2175 GlobalEntryLabelExp, OutContext);
2179 TS->
emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), LocalOffsetExp);
2202 if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() ||
2203 MF->hasInlineAsm() || (!PPCFI->
usesTOCBasePtr() && UsesX2OrR2)) {
2215void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
2224 OutStreamer->emitIntValue(0, 4);
2225 OutStreamer->emitIntValue(0, 8);
2229void PPCAIXAsmPrinter::emitLinkage(
const GlobalValue *GV,
2232 assert(MAI->hasVisibilityOnlyWithLinkage() &&
2233 "AIX's linkage directives take a visibility setting.");
2254 "InternalLinkage should not have other visibility setting.");
2266 if (!
TM.getIgnoreXCOFFVisibility()) {
2269 "Cannot not be both dllexport and non-default visibility");
2275 VisibilityAttr = MAI->getExportedVisibilityAttr();
2278 VisibilityAttr = MAI->getHiddenVisibilityAttr();
2281 VisibilityAttr = MAI->getProtectedVisibilityAttr();
2291 OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,
2298 cast<MCSectionXCOFF>(getObjFileLowering().getSectionForFunctionDescriptor(
2307uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
2312 if (Subtarget.
isAIXABI() && Subtarget.hasAltivec() &&
2313 TM.getAIXExtendedAltivecABI()) {
2315 for (
unsigned Reg = PPC::V20;
Reg <= PPC::V31; ++
Reg)
2316 if (
MRI.isPhysRegModified(Reg))
2318 return PPC::V31 - Reg + 1;
2323void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
2325 if (!
TM.getXCOFFTracebackTable())
2328 emitTracebackTable();
2336 (getNumberOfVRSaved() > 0)) {
2338 OutStreamer->switchSection(getObjFileLowering().getCompactUnwindSection());
2341 OutStreamer->emitLabel(EHInfoLabel);
2344 OutStreamer->emitInt32(0);
2346 const DataLayout &
DL = MMI->getModule()->getDataLayout();
2349 OutStreamer->emitValueToAlignment(
Align(PointerSize));
2351 OutStreamer->emitIntValue(0, PointerSize);
2352 OutStreamer->emitIntValue(0, PointerSize);
2353 OutStreamer->switchSection(MF->
getSection());
2357void PPCAIXAsmPrinter::emitTracebackTable() {
2361 OutStreamer->emitLabel(FuncEnd);
2363 OutStreamer->AddComment(
"Traceback table begin");
2365 OutStreamer->emitIntValueInHexWithPadding(0, 4 );
2370 auto EmitComment = [&]() {
2371 OutStreamer->AddComment(CommentOS.str());
2372 CommentString.
clear();
2377 OutStreamer->emitIntValueInHexWithPadding(
Value,
Size);
2381 CommentOS <<
"Version = " <<
Version;
2382 EmitCommentAndValue(Version, 1);
2392 CommentOS <<
"Language = "
2394 EmitCommentAndValue(LanguageIdentifier, 1);
2397 uint32_t FirstHalfOfMandatoryField = 0;
2408 for (
unsigned Reg = PPC::F0;
Reg <= PPC::F31; ++
Reg) {
2409 if (
MRI.isPhysRegUsed(Reg,
true)) {
2415#define GENBOOLCOMMENT(Prefix, V, Field) \
2416 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
2419#define GENVALUECOMMENT(PrefixAndName, V, Field) \
2420 CommentOS << (PrefixAndName) << " = " \
2421 << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
2422 (TracebackTable::Field##Shift))
2425 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);
2428 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasTraceBackTableOffset);
2429 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsInternalProcedure);
2432 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasControlledStorage);
2436 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsFloatingPointPresent);
2439 IsFloatingPointOperationLogOrAbortEnabled);
2442 OutStreamer->emitIntValueInHexWithPadding(
2443 (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2451 if (FrameReg == (Subtarget->
isPPC64() ? PPC::X31 : PPC::R31))
2455 if (!MustSaveCRs.
empty())
2461 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsInterruptHandler);
2462 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);
2466 OnConditionDirective);
2470 OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),
2474 uint32_t SecondHalfOfMandatoryField = 0;
2481 for (
unsigned Reg = PPC::F14;
Reg <= PPC::F31; ++
Reg) {
2482 if (
MRI.isPhysRegModified(Reg)) {
2483 FPRSaved = PPC::F31 -
Reg + 1;
2489 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, IsBackChainStored);
2491 GENVALUECOMMENT(
", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
2493 OutStreamer->emitIntValueInHexWithPadding(
2494 (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
2500 bool HasVectorInst =
false;
2501 for (
unsigned Reg = PPC::V0;
Reg <= PPC::V31; ++
Reg)
2502 if (
MRI.isPhysRegUsed(Reg,
true)) {
2504 HasVectorInst =
true;
2511 uint16_t NumOfVRSaved = getNumberOfVRSaved();
2512 bool ShouldEmitEHBlock =
2515 if (ShouldEmitEHBlock)
2521 unsigned GPRBegin = Subtarget->
isPPC64() ? PPC::X14 : PPC::R13;
2522 unsigned GPREnd = Subtarget->
isPPC64() ? PPC::X31 : PPC::R31;
2524 for (
unsigned Reg = GPRBegin;
Reg <= GPREnd; ++
Reg) {
2525 if (
MRI.isPhysRegModified(Reg)) {
2526 GPRSaved = GPREnd -
Reg + 1;
2534 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, HasExtensionTable);
2536 GENVALUECOMMENT(
", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
2538 OutStreamer->emitIntValueInHexWithPadding(
2539 (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
2543 SecondHalfOfMandatoryField |=
2547 NumberOfFixedParms);
2549 OutStreamer->emitIntValueInHexWithPadding(
2550 (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2558 SecondHalfOfMandatoryField |=
2563 NumberOfFloatingPointParms);
2564 GENBOOLCOMMENT(
", ", SecondHalfOfMandatoryField, HasParmsOnStack);
2566 OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
2572 if (NumberOfFixedParms || NumberOfFPParms) {
2578 ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
2585 CommentOS <<
"Parameter type = " << ParmsType.
get();
2588 OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
2589 sizeof(ParmsTypeValue));
2592 OutStreamer->AddComment(
"Function size");
2594 MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
2596 OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
2608 int16_t NameLength =
Name.size();
2609 CommentOS <<
"Function name len = "
2610 <<
static_cast<unsigned int>(NameLength);
2611 EmitCommentAndValue(NameLength, 2);
2612 OutStreamer->AddComment(
"Function Name");
2613 OutStreamer->emitBytes(
Name);
2618 OutStreamer->AddComment(
"AllocaUsed");
2619 OutStreamer->emitIntValueInHex(AllocReg,
sizeof(AllocReg));
2652 OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
2657 OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
2665 CommentOS <<
"Vector Parameter type = " << VecParmsType.
get();
2668 OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
2669 sizeof(VecParmTypeValue));
2671 CommentOS <<
"Padding";
2672 EmitCommentAndValue(0, 2);
2675 uint8_t ExtensionTableFlag = 0;
2677 if (ShouldEmitEHBlock)
2678 ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
2681 ExtensionTableFlag |= ExtendedTBTableFlag::TB_SSP_CANARY;
2683 CommentOS <<
"ExtensionTableFlag = "
2685 EmitCommentAndValue(ExtensionTableFlag,
sizeof(ExtensionTableFlag));
2688 if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
2689 auto &Ctx = OutStreamer->getContext();
2692 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym, TOCType_EHBlock);
2694 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2695 ->getQualNameSymbol();
2701 OutStreamer->emitValueToAlignment(
Align(4));
2702 OutStreamer->AddComment(
"EHInfo Table");
2703 OutStreamer->emitValue(Exp,
DL.getPointerSize());
2705#undef GENBOOLCOMMENT
2706#undef GENVALUECOMMENT
2715 .
Case(
"llvm.used",
true)
2717 .
Case(
"llvm.compiler.used",
true)
2723 .
Cases(
"llvm.global_ctors",
"llvm.global_dtors",
true)
2728 if (
auto *GA = dyn_cast<GlobalAlias>(
C))
2729 return getAliasOffset(GA->getAliasee());
2730 if (
auto *CE = dyn_cast<ConstantExpr>(
C)) {
2732 const MCBinaryExpr *CBE = dyn_cast<MCBinaryExpr>(LowC);
2737 auto *
RHS = dyn_cast<MCConstantExpr>(CBE->
getRHS());
2740 return RHS->getValue();
2750 "GlobalVariables with an alignment requirement stricter than TOC entry "
2751 "size not supported by the toc data transformation.");
2754 assert(GVType->
isSized() &&
"A GlobalVariable's size must be known to be "
2755 "supported by the toc data transformation.");
2759 "A GlobalVariable with size larger than a TOC entry is not currently "
2760 "supported by the toc data transformation.");
2763 "currently supported by the toc data transformation.");
2766void PPCAIXAsmPrinter::emitGlobalVariable(
const GlobalVariable *GV) {
2776 TOCDataGlobalVars.push_back(GV);
2780 emitGlobalVariableHelper(GV);
2783void PPCAIXAsmPrinter::emitGlobalVariableHelper(
const GlobalVariable *GV) {
2785 "Unhandled intrinsic global variable.");
2793 emitLinkage(GV, GVSym);
2797 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
2801 "not supported yet.");
2808 OutStreamer->getCommentOS() <<
'\n';
2813 getObjFileLowering().SectionForGlobal(GV, GVKind, TM));
2816 OutStreamer->switchSection(Csect);
2829 OutStreamer->emitZeros(
Size);
2832 "BSS local toc-data already handled and TLS variables "
2833 "incompatible with XMC_TD");
2834 OutStreamer->emitXCOFFLocalCommonSymbol(
2838 OutStreamer->emitCommonSymbol(GVSym,
Size, Alignment);
2846 emitLinkage(GV, EmittedInitSym);
2848 emitLinkage(GA, getSymbol(GA));
2850 emitAlignment(getGVAlignment(GV,
DL), GV);
2854 if (!
TM.getDataSections() || GV->hasSection()) {
2856 OutStreamer->emitLabel(EmittedInitSym);
2860 if (!GOAliasMap[GV].
size()) {
2861 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer());
2867 AliasMapTy AliasList;
2869 AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);
2872 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer(),
2876void PPCAIXAsmPrinter::emitFunctionDescriptor() {
2878 const unsigned PointerSize =
DL.getPointerSizeInBits() == 64 ? 8 : 4;
2882 OutStreamer->switchSection(
2883 cast<MCSymbolXCOFF>(CurrentFnDescSym)->getRepresentedCsect());
2887 OutStreamer->emitLabel(getSymbol(Alias));
2894 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2895 ->getQualNameSymbol();
2899 OutStreamer->emitIntValue(0, PointerSize);
2901 OutStreamer->switchSection(Current.first, Current.second);
2904void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2908 PPCAsmPrinter::emitFunctionEntryLabel();
2912 OutStreamer->emitLabel(
2913 getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM));
2916void PPCAIXAsmPrinter::emitPGORefs(
Module &M) {
2917 if (!OutContext.hasXCOFFSection(
2928 bool HasNonZeroLengthPrfCntsSection =
false;
2931 if (GV.hasSection() && GV.getSection() ==
"__llvm_prf_cnts" &&
2932 DL.getTypeAllocSize(GV.getValueType()) > 0) {
2933 HasNonZeroLengthPrfCntsSection =
true;
2937 if (HasNonZeroLengthPrfCntsSection) {
2938 MCSection *CntsSection = OutContext.getXCOFFSection(
2943 OutStreamer->switchSection(CntsSection);
2944 if (OutContext.hasXCOFFSection(
2947 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_data[RW]");
2948 OutStreamer->emitXCOFFRefDirective(S);
2950 if (OutContext.hasXCOFFSection(
2953 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_names[RO]");
2954 OutStreamer->emitXCOFFRefDirective(S);
2956 if (OutContext.hasXCOFFSection(
2959 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_vnds[RW]");
2960 OutStreamer->emitXCOFFRefDirective(S);
2965void PPCAIXAsmPrinter::emitEndOfAsmFile(
Module &M) {
2968 if (
M.empty() && TOCDataGlobalVars.empty())
2974 OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());
2979 for (
auto &
I : TOC) {
2986 if (
I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM ||
2987 (Subtarget->hasAIXShLibTLSModelOpt() &&
2988 I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD)) {
2992 Name += cast<MCSymbolXCOFF>(
I.first.first)->getSymbolTableName();
2994 TCEntry = cast<MCSectionXCOFF>(
2995 getObjFileLowering().getSectionForTOCEntry(S, TM));
2997 TCEntry = cast<MCSectionXCOFF>(
2998 getObjFileLowering().getSectionForTOCEntry(
I.first.first, TM));
3000 OutStreamer->switchSection(TCEntry);
3002 OutStreamer->emitLabel(
I.second);
3009 for (
const auto *GV : TOCDataGlobalVars) {
3010 if (!GV->hasCommonLinkage())
3011 emitGlobalVariableHelper(GV);
3013 for (
const auto *GV : TOCDataGlobalVars) {
3014 if (GV->hasCommonLinkage())
3015 emitGlobalVariableHelper(GV);
3019bool PPCAIXAsmPrinter::doInitialization(
Module &M) {
3020 const bool Result = PPCAsmPrinter::doInitialization(M);
3022 auto setCsectAlignment = [
this](
const GlobalObject *GO) {
3024 if (GO->isDeclarationForLinker())
3027 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);
3029 getObjFileLowering().SectionForGlobal(GO, GOKind, TM));
3031 Align GOAlign = getGVAlignment(GO, GO->getDataLayout());
3039 auto DL =
M.getDataLayout();
3040 for (
const auto &
G :
M.globals()) {
3041 if (
G.isThreadLocal() && !
G.isDeclaration()) {
3042 TLSVarAddress =
alignTo(TLSVarAddress, getGVAlignment(&
G,
DL));
3043 TLSVarsToAddressMapping[&
G] = TLSVarAddress;
3044 TLSVarAddress +=
DL.getTypeAllocSize(
G.getValueType());
3051 for (
const auto &
G :
M.globals()) {
3058 if (FormatIndicatorAndUniqueModId.empty()) {
3060 if (UniqueModuleId !=
"")
3064 FormatIndicatorAndUniqueModId =
"clang_" + UniqueModuleId.substr(1);
3069 std::chrono::duration_cast<std::chrono::nanoseconds>(
3070 std::chrono::steady_clock::now().time_since_epoch())
3072 FormatIndicatorAndUniqueModId =
3075 llvm::itostr(CurTime);
3079 emitSpecialLLVMGlobal(&
G);
3083 setCsectAlignment(&
G);
3084 std::optional<CodeModel::Model> OptionalCodeModel =
G.getCodeModel();
3085 if (OptionalCodeModel)
3087 *OptionalCodeModel);
3090 for (
const auto &
F : M)
3091 setCsectAlignment(&
F);
3094 for (
const auto &Alias :
M.aliases()) {
3098 "alias without a base object is not yet supported on AIX");
3102 "\n\tAlias attribute for " +
3103 Alias.getGlobalIdentifier() +
3104 " is invalid because " + Aliasee->
getName() +
3110 dyn_cast_or_null<GlobalVariable>(Alias.getAliaseeObject());
3112 std::optional<CodeModel::Model> OptionalCodeModel = GVar->
getCodeModel();
3113 if (OptionalCodeModel)
3115 *OptionalCodeModel);
3118 GOAliasMap[Aliasee].push_back(&Alias);
3125 switch (
MI->getOpcode()) {
3132 if (
MI->getNumOperands() < 5)
3138 MCSymbol *TempSym = OutContext.createNamedTempSymbol();
3139 OutStreamer->emitLabel(TempSym);
3140 OutStreamer->emitXCOFFExceptDirective(
3141 CurrentFnSym, TempSym, LangMO.
getImm(), ReasonMO.
getImm(),
3142 Subtarget->
isPPC64() ?
MI->getMF()->getInstructionCount() * 8
3143 :
MI->getMF()->getInstructionCount() * 4,
3147 case PPC::GETtlsMOD32AIX:
3148 case PPC::GETtlsMOD64AIX:
3149 case PPC::GETtlsTpointer32AIX:
3150 case PPC::GETtlsADDR64AIX:
3151 case PPC::GETtlsADDR32AIX: {
3156 ExtSymSDNodeSymbols.insert(TlsGetAddr);
3166 cast<MCSymbolXCOFF>(OutContext.getOrCreateSymbol(MO.
getSymbolName()));
3167 ExtSymSDNodeSymbols.insert(S);
3173 case PPC::BL8_NOP_TLS:
3180 case PPC::TAILBCTR8:
3181 if (
MI->getOperand(0).isSymbol())
3194 MCInstBuilder(PPC::ORI).addReg(PPC::R0).addReg(PPC::R0).addImm(0));
3197 return PPCAsmPrinter::emitInstruction(
MI);
3200bool PPCAIXAsmPrinter::doFinalization(
Module &M) {
3202 if (!MAI->usesDwarfFileAndLocDirectives() &&
hasDebugInfo())
3203 OutStreamer->doFinalizationAtSectionEnd(
3204 OutStreamer->getContext().getObjectFileInfo()->getTextSection());
3208 return PPCAsmPrinter::doFinalization(M);
3212 if (P < 0 || P > 65535)
3219 return 20 + (
P - 20) * 16;
3222 return 1004 + (
P - 81);
3225 return 2047 + (
P - 1124) * 33878;
3227 return 2147482625u + (
P - 64512);
3246 std::string PrioritySuffix;
3250 return PrioritySuffix;
3253void PPCAIXAsmPrinter::emitXXStructorList(
const DataLayout &
DL,
3254 const Constant *List,
bool IsCtor) {
3256 preprocessXXStructorList(
DL, List, Structors);
3257 if (Structors.
empty())
3261 for (Structor &S : Structors) {
3262 if (
const ConstantExpr *CE = dyn_cast<ConstantExpr>(S.Func))
3263 S.Func =
CE->getOperand(0);
3271 cast<Function>(S.Func));
3275void PPCAIXAsmPrinter::emitTTypeReference(
const GlobalValue *GV,
3276 unsigned Encoding) {
3278 TOCEntryType GlobalType = TOCType_GlobalInternal;
3283 GlobalType = TOCType_GlobalExternal;
3285 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym, GlobalType);
3287 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
3288 ->getQualNameSymbol();
3289 auto &Ctx = OutStreamer->getContext();
3293 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
3295 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
3302 std::unique_ptr<MCStreamer> &&Streamer) {
3304 return new PPCAIXAsmPrinter(tm, std::move(Streamer));
3306 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
3309void PPCAIXAsmPrinter::emitModuleCommandLines(
Module &M) {
3310 const NamedMDNode *NMD =
M.getNamedMetadata(
"llvm.commandline");
3318 assert(
N->getNumOperands() == 1 &&
3319 "llvm.commandline metadata entry can have only one operand");
3320 const MDString *MDS = cast<MDString>(
N->getOperand(0));
3323 RSOS <<
"@(#)opt " << MDS->
getString() <<
"\n";
3326 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)
static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)
This file implements a map that provides insertion order iteration.
Module.h This file contains the declarations for the Module class.
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 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)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
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(unsigned 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)
unsigned 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 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.
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
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...
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)
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)
@ XMC_RO
Read Only Constant.
@ XMC_TD
Scalar data item in the TOC.
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.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
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.
@ 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