86#define DEBUG_TYPE "asmprinter"
88STATISTIC(NumTOCEntries,
"Number of Total TOC Entries Emitted.");
89STATISTIC(NumTOCConstPool,
"Number of Constant Pool TOC Entries.");
91 "Number of Internal Linkage Global TOC Entries.");
93 "Number of External Linkage Global TOC Entries.");
94STATISTIC(NumTOCJumpTable,
"Number of Jump Table TOC Entries.");
95STATISTIC(NumTOCThreadLocal,
"Number of Thread Local TOC Entries.");
96STATISTIC(NumTOCBlockAddress,
"Number of Block Address TOC Entries.");
97STATISTIC(NumTOCEHBlock,
"Number of EH Block TOC Entries.");
110 using TOCKey = std::pair<const MCSymbol *, PPCMCExpr::Specifier>;
129 Tag_GNU_Power_ABI_FP = 4,
130 Tag_GNU_Power_ABI_Vector = 8,
131 Tag_GNU_Power_ABI_Struct_Return = 12,
134 Val_GNU_Power_ABI_NoFloat = 0b00,
135 Val_GNU_Power_ABI_HardFloat_DP = 0b01,
136 Val_GNU_Power_ABI_SoftFloat_DP = 0b10,
137 Val_GNU_Power_ABI_HardFloat_SP = 0b11,
139 Val_GNU_Power_ABI_LDBL_IBM128 = 0b0100,
140 Val_GNU_Power_ABI_LDBL_64 = 0b1000,
141 Val_GNU_Power_ABI_LDBL_IEEE128 = 0b1100,
163 std::unique_ptr<MCStreamer> Streamer,
char &
ID)
169 TOCType_ConstantPool,
170 TOCType_GlobalExternal,
171 TOCType_GlobalInternal,
174 TOCType_BlockAddress,
217class PPCLinuxAsmPrinter :
public PPCAsmPrinter {
222 std::unique_ptr<MCStreamer> 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();
269 PPCAIXAsmPrinter(
TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
271 if (MAI->isLittleEndian())
273 "cannot create AIX PPC Assembly Printer for a little-endian target");
276 StringRef getPassName()
const override {
return "AIX PPC Assembly Printer"; }
278 bool doInitialization(
Module &M)
override;
281 bool IsCtor)
override;
287 void emitFunctionDescriptor()
override;
289 void emitFunctionEntryLabel()
override;
291 void emitFunctionBodyEnd()
override;
293 void emitPGORefs(
Module &M);
297 void emitEndOfAsmFile(
Module &)
override;
303 bool doFinalization(
Module &M)
override;
305 void emitTTypeReference(
const GlobalValue *GV,
unsigned Encoding)
override;
307 void emitModuleCommandLines(
Module &M)
override;
316 getSymbol(GV)->
print(O, MAI);
320void PPCAsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNo,
343 O <<
DL.getPrivateGlobalPrefix() <<
"CPI" << getFunctionNumber() <<
'_'
350 PrintSymbolOperand(MO, O);
362bool PPCAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
365 if (ExtraCode && ExtraCode[0]) {
366 if (ExtraCode[1] != 0)
return true;
368 switch (ExtraCode[0]) {
374 if (!
MI->getOperand(OpNo).isReg() ||
375 OpNo+1 ==
MI->getNumOperands() ||
376 !
MI->getOperand(OpNo+1).isReg())
383 if (
MI->getOperand(OpNo).isImm())
387 if(!
MI->getOperand(OpNo).isReg())
393 Reg = PPC::VSX32 + (
Reg - PPC::V0);
395 Reg = PPC::VSX32 + (Reg - PPC::VF0);
411bool PPCAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNo,
412 const char *ExtraCode,
414 if (ExtraCode && ExtraCode[0]) {
415 if (ExtraCode[1] != 0)
return true;
417 switch (ExtraCode[0]) {
418 default:
return true;
420 O << getDataLayout().getPointerSize() <<
"(";
431 if (
MI->getOperand(OpNo).isImm())
442 assert(
MI->getOperand(OpNo).isReg());
447 assert(
MI->getOperand(OpNo).isReg());
457 case PPCAsmPrinter::TOCType_ConstantPool:
460 case PPCAsmPrinter::TOCType_GlobalInternal:
461 ++NumTOCGlobalInternal;
463 case PPCAsmPrinter::TOCType_GlobalExternal:
464 ++NumTOCGlobalExternal;
466 case PPCAsmPrinter::TOCType_JumpTable:
469 case PPCAsmPrinter::TOCType_ThreadLocal:
472 case PPCAsmPrinter::TOCType_BlockAddress:
473 ++NumTOCBlockAddress;
475 case PPCAsmPrinter::TOCType_EHBlock:
492 assert(GV &&
"expected global for MO_GlobalAddress");
523 TOCEntry = createTempSymbol(
"C");
528 unsigned NumNOPBytes =
MI.getOperand(1).getImm();
530 auto &Ctx = OutStreamer->getContext();
531 MCSymbol *MILabel = Ctx.createTempSymbol();
532 OutStreamer->emitLabel(MILabel);
535 assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
541 while (NumNOPBytes > 0) {
542 if (MII ==
MBB.
end() || MII->isCall() ||
543 MII->getOpcode() == PPC::DBG_VALUE ||
544 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
545 MII->getOpcode() == TargetOpcode::STACKMAP)
552 for (
unsigned i = 0; i < NumNOPBytes; i += 4)
559 auto &Ctx = OutStreamer->getContext();
560 MCSymbol *MILabel = Ctx.createTempSymbol();
561 OutStreamer->emitLabel(MILabel);
566 unsigned EncodedBytes = 0;
569 if (CalleeMO.
isImm()) {
570 int64_t CallTarget = CalleeMO.
getImm();
572 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
573 "High 16 bits of call target should be zero.");
574 Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
579 .addImm((CallTarget >> 32) & 0xFFFF));
584 .addImm(32).addImm(16));
589 .addImm((CallTarget >> 16) & 0xFFFF));
594 .addImm(CallTarget & 0xFFFF));
600 .addImm(TOCSaveOffset)
613 .addReg(ScratchReg));
618 .addReg(ScratchReg));
623 .addReg(ScratchReg));
631 .addImm(TOCSaveOffset)
637 MCSymbol *MOSymbol = getSymbol(GValue);
649 unsigned NumBytes = Opers.getNumPatchBytes();
650 assert(NumBytes >= EncodedBytes &&
651 "Patchpoint can't request size less than the length of a call.");
652 assert((NumBytes - EncodedBytes) % 4 == 0 &&
653 "Invalid number of NOP bytes requested!");
654 for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
665 SymName =
".__tls_get_addr";
667 case PPC::GETtlsTpointer32AIX:
668 SymName =
".__get_tpointer";
670 case PPC::GETtlsMOD32AIX:
671 case PPC::GETtlsMOD64AIX:
672 SymName =
".__tls_get_mod";
683 "Only expecting to emit calls to get the thread pointer on AIX!");
687 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::BLA).addExpr(TlsRef));
695 unsigned Opcode = PPC::BL8_NOP_TLS;
697 assert(
MI->getNumOperands() >= 3 &&
"Expecting at least 3 operands from MI");
701 Opcode = PPC::BL8_NOTOC_TLS;
703 const Module *
M = MF->getFunction().getParent();
706 ((Subtarget->
isPPC64() &&
MI->getOperand(0).getReg() == PPC::X3) ||
707 (!Subtarget->
isPPC64() &&
MI->getOperand(0).getReg() == PPC::R3)) &&
708 "GETtls[ld]ADDR[32] must define GPR3");
710 ((Subtarget->
isPPC64() &&
MI->getOperand(1).getReg() == PPC::X3) ||
711 (!Subtarget->
isPPC64() &&
MI->getOperand(1).getReg() == PPC::R3)) &&
712 "GETtls[ld]ADDR[32] must read GPR3");
721 assert((
MI->getOpcode() == PPC::GETtlsMOD32AIX ||
722 MI->getOpcode() == PPC::GETtlsMOD64AIX ||
723 (
MI->getOperand(2).isReg() &&
724 MI->getOperand(2).getReg() == VarOffsetReg)) &&
725 "GETtls[ld]ADDR[32] must read GPR4");
726 EmitAIXTlsCallHelper(
MI);
730 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(
"__tls_get_addr");
738 if (Kind ==
PPC::S_PLT && Subtarget->isSecurePlt() &&
744 MCSymbol *MOSymbol = getSymbol(GValue);
746 EmitToStreamer(*OutStreamer,
748 : (
unsigned)PPC::BL_TLS)
771static PPCAsmPrinter::TOCEntryType
776 return PPCAsmPrinter::TOCType_ThreadLocal;
785 return PPCAsmPrinter::TOCType_GlobalExternal;
787 return PPCAsmPrinter::TOCType_GlobalInternal;
790 return PPCAsmPrinter::TOCType_ConstantPool;
792 return PPCAsmPrinter::TOCType_JumpTable;
794 return PPCAsmPrinter::TOCType_BlockAddress;
800const MCExpr *PPCAsmPrinter::symbolWithSpecifier(
const MCSymbol *S,
809 PPC_MC::verifyInstructionPredicates(
MI->getOpcode(),
810 getSubtargetInfo().getFeatureBits());
813 const bool IsPPC64 = Subtarget->
isPPC64();
814 const bool IsAIX = Subtarget->
isAIXABI();
815 const bool HasAIXSmallLocalTLS = Subtarget->hasAIXSmallLocalExecTLS() ||
816 Subtarget->hasAIXSmallLocalDynamicTLS();
817 const Module *
M = MF->getFunction().getParent();
822 if (!
MI->isInlineAsm()) {
826 if (Subtarget->hasSPE()) {
827 if (PPC::F4RCRegClass.
contains(Reg) ||
836 if (PPC::SPERCRegClass.
contains(Reg))
844 auto getTOCRelocAdjustedExprForXCOFF = [
this](
const MCExpr *Expr,
853 OriginalOffset - llvm::SignExtend32<16>(OriginalOffset);
858 auto getTOCEntryLoadingExprForXCOFF =
859 [IsPPC64, getTOCRelocAdjustedExprForXCOFF,
862 const unsigned EntryByteSize = IsPPC64 ? 8 : 4;
863 const auto TOCEntryIter =
TOC.find({MOSymbol, VK});
865 "Could not find the TOC entry for this symbol.");
866 const ptrdiff_t EntryDistanceFromTOCBase =
867 (TOCEntryIter -
TOC.begin()) * EntryByteSize;
868 constexpr int16_t PositiveTOCRange = INT16_MAX;
870 if (EntryDistanceFromTOCBase > PositiveTOCRange)
871 return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase);
883 assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!\n");
895 dbgs() <<
"Current function uses IE access for default LD vars.\n");
918 switch (
MI->getOpcode()) {
920 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
922 "AIX does not support patchable function entry!");
925 if (MAI->isLittleEndian())
929 (void)
F.getFnAttribute(
"patchable-function-entry")
931 .getAsInteger(10, Num);
937 case TargetOpcode::DBG_VALUE:
939 case TargetOpcode::STACKMAP:
940 return LowerSTACKMAP(SM, *
MI);
941 case TargetOpcode::PATCHPOINT:
942 return LowerPATCHPOINT(SM, *
MI);
944 case PPC::MoveGOTtoLR: {
952 OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
958 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::BL).addExpr(OffsExpr));
961 case PPC::MovePCtoLR:
962 case PPC::MovePCtoLR8: {
967 MCSymbol *PICBase = MF->getPICBaseSymbol();
970 EmitToStreamer(*OutStreamer,
977 OutStreamer->emitLabel(PICBase);
980 case PPC::UpdateGBR: {
989 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
991 MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
1004 MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));
1010 MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
1028 EmitToStreamer(*OutStreamer, TmpInst);
1034 EmitToStreamer(*OutStreamer, TmpInst);
1047 "Invalid operand for LWZtoc.");
1057 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));
1116 EmitToStreamer(*OutStreamer, TmpInst);
1131 "Invalid operand!");
1145 const MCExpr *
Exp = symbolWithSpecifier(TOCEntry, VKExpr);
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");
1196 EmitToStreamer(*OutStreamer, TmpInst);
1199 case PPC::LWZtocL: {
1203 "Invalid operand for LWZtocL.");
1204 assert(IsAIX && !IsPPC64 &&
1206 "This pseudo should only be selected for 32-bit large code model on"
1228 EmitToStreamer(*OutStreamer, TmpInst);
1231 case PPC::ADDIStocHA8: {
1243 "Invalid operand for ADDIStocHA8!");
1249 const bool GlobalToc =
1261 const MCExpr *
Exp = symbolWithSpecifier(MOSymbol, VK);
1270 EmitToStreamer(*OutStreamer, TmpInst);
1286 "Invalid operand for LDtocL!");
1290 "LDtocL used on symbol that could be accessed directly is "
1291 "invalid. Must match ADDIStocHA8."));
1302 const MCExpr *
Exp = symbolWithSpecifier(MOSymbol, VK);
1304 EmitToStreamer(*OutStreamer, TmpInst);
1308 case PPC::ADDItocL8: {
1312 unsigned Op =
MI->getOpcode();
1316 TmpInst.
setOpcode(
Op == PPC::ADDItocL8 ? (IsAIX ? PPC::LA8 : PPC::ADDI8)
1322 : MO.
isGlobal() &&
"Invalid operand for ADDItocL8.");
1324 "Interposable definitions must use indirect accesses.");
1333 EmitToStreamer(*OutStreamer, TmpInst);
1336 case PPC::ADDISgotTprelHA: {
1339 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1342 MCSymbol *MOSymbol = getSymbol(GValue);
1343 const MCExpr *SymGotTprel =
1346 .addReg(
MI->getOperand(0).getReg())
1347 .
addReg(
MI->getOperand(1).getReg())
1351 case PPC::LDgotTprelL:
1352 case PPC::LDgotTprelL32: {
1357 TmpInst.
setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ);
1360 MCSymbol *MOSymbol = getSymbol(GValue);
1361 const MCExpr *
Exp = symbolWithSpecifier(
1364 EmitToStreamer(*OutStreamer, TmpInst);
1368 case PPC::PPC32PICGOT: {
1369 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1370 MCSymbol *GOTRef = OutContext.createTempSymbol();
1371 MCSymbol *NextInstr = OutContext.createTempSymbol();
1381 OutStreamer->emitLabel(GOTRef);
1382 OutStreamer->emitValue(OffsExpr, 4);
1383 OutStreamer->emitLabel(NextInstr);
1385 .addReg(
MI->getOperand(0).getReg()));
1387 .addReg(
MI->getOperand(1).getReg())
1389 .
addReg(
MI->getOperand(0).getReg()));
1391 .addReg(
MI->getOperand(0).getReg())
1392 .
addReg(
MI->getOperand(1).getReg())
1393 .
addReg(
MI->getOperand(0).getReg()));
1396 case PPC::PPC32GOT: {
1398 OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1399 const MCExpr *SymGotTlsL =
1401 const MCExpr *SymGotTlsHA =
1404 .addReg(
MI->getOperand(0).getReg())
1407 .addReg(
MI->getOperand(0).getReg())
1408 .
addReg(
MI->getOperand(0).getReg())
1412 case PPC::ADDIStlsgdHA: {
1415 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1418 MCSymbol *MOSymbol = getSymbol(GValue);
1419 const MCExpr *SymGotTlsGD =
1422 .addReg(
MI->getOperand(0).getReg())
1423 .
addReg(
MI->getOperand(1).getReg())
1427 case PPC::ADDItlsgdL:
1430 case PPC::ADDItlsgdL32: {
1435 MCSymbol *MOSymbol = getSymbol(GValue);
1436 const MCExpr *SymGotTlsGD = symbolWithSpecifier(
1438 EmitToStreamer(*OutStreamer,
1440 .addReg(
MI->getOperand(0).getReg())
1441 .
addReg(
MI->getOperand(1).getReg())
1445 case PPC::GETtlsMOD32AIX:
1446 case PPC::GETtlsMOD64AIX:
1450 case PPC::GETtlsADDR:
1453 case PPC::GETtlsADDRPCREL:
1454 case PPC::GETtlsADDR32AIX:
1455 case PPC::GETtlsADDR64AIX:
1459 case PPC::GETtlsADDR32: {
1465 case PPC::GETtlsTpointer32AIX: {
1468 EmitAIXTlsCallHelper(
MI);
1471 case PPC::ADDIStlsldHA: {
1474 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1477 MCSymbol *MOSymbol = getSymbol(GValue);
1478 const MCExpr *SymGotTlsLD =
1481 .addReg(
MI->getOperand(0).getReg())
1482 .
addReg(
MI->getOperand(1).getReg())
1486 case PPC::ADDItlsldL:
1489 case PPC::ADDItlsldL32: {
1494 MCSymbol *MOSymbol = getSymbol(GValue);
1495 const MCExpr *SymGotTlsLD = symbolWithSpecifier(
1497 EmitToStreamer(*OutStreamer,
1499 .addReg(
MI->getOperand(0).getReg())
1500 .
addReg(
MI->getOperand(1).getReg())
1504 case PPC::GETtlsldADDR:
1507 case PPC::GETtlsldADDRPCREL:
1508 case PPC::GETtlsldADDR32: {
1514 case PPC::ADDISdtprelHA:
1517 case PPC::ADDISdtprelHA32: {
1522 MCSymbol *MOSymbol = getSymbol(GValue);
1527 .addReg(
MI->getOperand(0).getReg())
1528 .
addReg(
MI->getOperand(1).getReg())
1532 case PPC::PADDIdtprel: {
1537 MCSymbol *MOSymbol = getSymbol(GValue);
1540 .addReg(
MI->getOperand(0).getReg())
1541 .
addReg(
MI->getOperand(1).getReg())
1546 case PPC::ADDIdtprelL:
1549 case PPC::ADDIdtprelL32: {
1554 MCSymbol *MOSymbol = getSymbol(GValue);
1556 EmitToStreamer(*OutStreamer,
1558 .addReg(
MI->getOperand(0).getReg())
1559 .
addReg(
MI->getOperand(1).getReg())
1565 if (!Subtarget->hasMFOCRF()) {
1568 unsigned NewOpcode =
1569 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
1573 .addReg(
MI->getOperand(0).getReg()));
1579 if (!Subtarget->hasMFOCRF()) {
1582 unsigned NewOpcode =
1583 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1584 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
1585 ->getEncodingValue(
MI->getOperand(0).getReg());
1590 .addReg(
MI->getOperand(1).getReg()));
1600 unsigned OpNum = (
MI->getOpcode() == PPC::STD) ? 2 : 1;
1607 TempMO.getOperandNo() == 1)
1644 if (!HasAIXSmallLocalTLS)
1646 bool IsMIADDI8 =
MI->getOpcode() == PPC::ADDI8;
1647 unsigned OpNum = IsMIADDI8 ? 2 : 1;
1663 EmitToStreamer(*OutStreamer, TmpInst);
1669 case PPC::PseudoEIEIO: {
1672 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1675 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1676 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::EnforceIEIO));
1682 EmitToStreamer(*OutStreamer, TmpInst);
1692PPCAsmPrinter::getAdjustedFasterLocalExpr(
const MachineOperand &MO,
1699 assert(MO.
isGlobal() &&
"Only expecting a global MachineOperand here!");
1703 "Only local-[exec|dynamic] accesses are handled!");
1709 const auto TLSVarsMapEntryIter = TLSVarsToAddressMapping.
find(GValue);
1710 if (TLSVarsMapEntryIter == TLSVarsToAddressMapping.
end())
1711 assert(IsGlobalADeclaration &&
1712 "Only expecting to find extern TLS variables not present in the TLS "
1713 "variable-to-address map!");
1715 unsigned TLSVarAddress =
1716 IsGlobalADeclaration ? 0 : TLSVarsMapEntryIter->second;
1729 if (FinalAddress >= 32768) {
1736 ptrdiff_t Delta = ((FinalAddress + 32768) & ~0xFFFF);
1740 ((InstDisp < 32768) && (InstDisp >= -32768)) &&
1741 "Expecting the instruction displacement for local-[exec|dynamic] TLS "
1742 "variables to be between [-32768, 32768)!");
1750void PPCLinuxAsmPrinter::emitGNUAttributes(
Module &M) {
1752 Metadata *MD =
M.getModuleFlag(
"float-abi");
1753 MDString *FloatABI = dyn_cast_or_null<MDString>(MD);
1758 if (flt ==
"doubledouble")
1759 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1760 Val_GNU_Power_ABI_HardFloat_DP |
1761 Val_GNU_Power_ABI_LDBL_IBM128);
1762 else if (flt ==
"ieeequad")
1763 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1764 Val_GNU_Power_ABI_HardFloat_DP |
1765 Val_GNU_Power_ABI_LDBL_IEEE128);
1766 else if (flt ==
"ieeedouble")
1767 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1768 Val_GNU_Power_ABI_HardFloat_DP |
1769 Val_GNU_Power_ABI_LDBL_64);
1772void PPCLinuxAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
1774 return PPCAsmPrinter::emitInstruction(
MI);
1776 switch (
MI->getOpcode()) {
1779 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1792 if (!MAI->isLittleEndian())
1794 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1795 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1796 OutStreamer->emitLabel(BeginOfSled);
1797 EmitToStreamer(*OutStreamer,
1803 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1804 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1805 EmitToStreamer(*OutStreamer,
1808 OutContext.getOrCreateSymbol(
"__xray_FunctionEntry"),
1810 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1811 OutStreamer->emitLabel(EndOfSled);
1812 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_ENTER, 2);
1815 case TargetOpcode::PATCHABLE_RET: {
1816 unsigned RetOpcode =
MI->getOperand(0).getImm();
1826 if (RetOpcode == PPC::BCCLR) {
1827 IsConditional =
true;
1828 }
else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1829 RetOpcode == PPC::TCRETURNai8) {
1831 }
else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1832 IsConditional =
false;
1834 EmitToStreamer(*OutStreamer, RetInst);
1839 if (IsConditional) {
1858 FallthroughLabel = OutContext.createTempSymbol();
1864 .
addReg(
MI->getOperand(2).getReg())
1881 OutStreamer->emitCodeAlignment(
Align(8), &getSubtargetInfo());
1882 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1883 OutStreamer->emitLabel(BeginOfSled);
1884 EmitToStreamer(*OutStreamer, RetInst);
1888 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1889 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1890 EmitToStreamer(*OutStreamer,
1893 OutContext.getOrCreateSymbol(
"__xray_FunctionExit"),
1895 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1896 EmitToStreamer(*OutStreamer, RetInst);
1898 OutStreamer->emitLabel(FallthroughLabel);
1899 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_EXIT, 2);
1902 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1904 case TargetOpcode::PATCHABLE_TAIL_CALL:
1908 "around this assert.");
1910 return PPCAsmPrinter::emitInstruction(
MI);
1913void PPCLinuxAsmPrinter::emitStartOfAsmFile(
Module &M) {
1921 !isPositionIndependent())
1927 OutStreamer->switchSection(OutContext.getELFSection(
1930 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(
Twine(
".LTOC"));
1931 MCSymbol *CurrentPos = OutContext.createTempSymbol();
1933 OutStreamer->emitLabel(CurrentPos);
1942 OutStreamer->emitAssignment(TOCSym, tocExpr);
1944 OutStreamer->switchSection(getObjFileLowering().getTextSection());
1947void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
1950 (!isPositionIndependent() ||
1956 if (PPCFI->
usesPICBase() && !Subtarget->isSecurePlt()) {
1958 MCSymbol *PICBase = MF->getPICBaseSymbol();
1959 OutStreamer->emitLabel(RelocSymbol);
1967 OutStreamer->emitValue(OffsExpr, 4);
1968 OutStreamer->emitLabel(CurrentFnSym);
1981 && !MF->getRegInfo().use_empty(PPC::X2)) {
1986 const MCExpr *TOCDeltaExpr =
1993 OutStreamer->emitValue(TOCDeltaExpr, 8);
2002 OutStreamer->switchSection(Section);
2003 OutStreamer->emitLabel(CurrentFnSym);
2004 OutStreamer->emitValueToAlignment(
Align(8));
2005 MCSymbol *Symbol1 = CurrentFnSymForSize;
2012 OutStreamer->emitValue(
2015 OutStreamer->emitIntValue(0, 8 );
2016 OutStreamer->switchSection(Current.first, Current.second);
2019void PPCLinuxAsmPrinter::emitEndOfAsmFile(
Module &M) {
2022 bool isPPC64 =
DL.getPointerSizeInBits() == 64;
2032 OutStreamer->emitSymbolValue(
2033 GetExternalSymbolSymbol(
"__parse_hwcap_and_convert_at_platform"),
2034 MAI->getCodePointerSize());
2035 emitGNUAttributes(M);
2038 const char *
Name = isPPC64 ?
".toc" :
".got2";
2041 OutStreamer->switchSection(Section);
2043 OutStreamer->emitValueToAlignment(
Align(4));
2045 for (
const auto &TOCMapPair : TOC) {
2046 const MCSymbol *
const TOCEntryTarget = TOCMapPair.first.first;
2047 MCSymbol *
const TOCEntryLabel = TOCMapPair.second;
2049 OutStreamer->emitLabel(TOCEntryLabel);
2051 TS->
emitTCEntry(*TOCEntryTarget, TOCMapPair.first.second);
2053 OutStreamer->emitSymbolValue(TOCEntryTarget, 4);
2057 PPCAsmPrinter::emitEndOfAsmFile(M);
2061void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
2094 const bool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) ||
2095 !MF->getRegInfo().use_empty(PPC::R2);
2104 if (NonPCrelGEPRequired || PCrelGEPRequired) {
2109 OutStreamer->emitLabel(GlobalEntryLabel);
2115 const MCExpr *TOCDeltaExpr =
2117 GlobalEntryLabelExp, OutContext);
2119 const MCExpr *TOCDeltaHi =
2124 .addExpr(TOCDeltaHi));
2126 const MCExpr *TOCDeltaLo =
2131 .addExpr(TOCDeltaLo));
2134 const MCExpr *TOCOffsetDeltaExpr =
2136 GlobalEntryLabelExp, OutContext);
2140 .addExpr(TOCOffsetDeltaExpr)
2149 OutStreamer->emitLabel(LocalEntryLabel);
2152 const MCExpr *LocalOffsetExp =
2154 GlobalEntryLabelExp, OutContext);
2182 if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() ||
2183 MF->hasInlineAsm() || (!PPCFI->
usesTOCBasePtr() && UsesX2OrR2)) {
2195void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
2204 OutStreamer->emitIntValue(0, 4);
2205 OutStreamer->emitIntValue(0, 8);
2209char PPCLinuxAsmPrinter::ID = 0;
2212 "Linux PPC Assembly Printer",
false,
false)
2217 switch (GV->getLinkage()) {
2235 "InternalLinkage should not have other visibility setting.");
2247 if (!TM.getIgnoreXCOFFVisibility()) {
2248 if (GV->hasDLLExportStorageClass() && !GV->hasDefaultVisibility())
2250 "Cannot not be both dllexport and non-default visibility");
2251 switch (GV->getVisibility()) {
2255 if (GV->hasDLLExportStorageClass())
2256 VisibilityAttr = MAI->getExportedVisibilityAttr();
2259 VisibilityAttr = MAI->getHiddenVisibilityAttr();
2262 VisibilityAttr = MAI->getProtectedVisibilityAttr();
2268 if (GV->getThreadLocalMode() == GlobalVariable::LocalDynamicTLSModel &&
2269 GV->hasName() && GV->getName() ==
"_$TLSML")
2272 OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,
2279 getObjFileLowering().getSectionForFunctionDescriptor(&MF.
getFunction(),
2283 CurrentFnDescSym = FnDescSec->getQualNameSymbol();
2288uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
2293 if (Subtarget.
isAIXABI() && Subtarget.hasAltivec() &&
2294 TM.getAIXExtendedAltivecABI()) {
2296 for (
unsigned Reg = PPC::V20;
Reg <= PPC::V31; ++
Reg)
2297 if (
MRI.isPhysRegModified(Reg))
2299 return PPC::V31 - Reg + 1;
2304void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
2306 if (!
TM.getXCOFFTracebackTable())
2309 emitTracebackTable();
2317 (getNumberOfVRSaved() > 0)) {
2319 OutStreamer->switchSection(getObjFileLowering().getCompactUnwindSection());
2322 OutStreamer->emitLabel(EHInfoLabel);
2325 OutStreamer->emitInt32(0);
2327 const DataLayout &
DL = MMI->getModule()->getDataLayout();
2330 OutStreamer->emitValueToAlignment(
Align(PointerSize));
2332 OutStreamer->emitIntValue(0, PointerSize);
2333 OutStreamer->emitIntValue(0, PointerSize);
2334 OutStreamer->switchSection(MF->
getSection());
2338void PPCAIXAsmPrinter::emitTracebackTable() {
2342 OutStreamer->emitLabel(FuncEnd);
2344 OutStreamer->AddComment(
"Traceback table begin");
2346 OutStreamer->emitIntValueInHexWithPadding(0, 4 );
2351 auto EmitComment = [&]() {
2352 OutStreamer->AddComment(CommentOS.str());
2353 CommentString.
clear();
2358 OutStreamer->emitIntValueInHexWithPadding(
Value,
Size);
2362 CommentOS <<
"Version = " <<
Version;
2363 EmitCommentAndValue(Version, 1);
2373 CommentOS <<
"Language = "
2375 EmitCommentAndValue(LanguageIdentifier, 1);
2378 uint32_t FirstHalfOfMandatoryField = 0;
2389 for (
unsigned Reg = PPC::F0;
Reg <= PPC::F31; ++
Reg) {
2390 if (
MRI.isPhysRegUsed(Reg,
true)) {
2396#define GENBOOLCOMMENT(Prefix, V, Field) \
2397 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
2400#define GENVALUECOMMENT(PrefixAndName, V, Field) \
2401 CommentOS << (PrefixAndName) << " = " \
2402 << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
2403 (TracebackTable::Field##Shift))
2406 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);
2409 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasTraceBackTableOffset);
2410 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsInternalProcedure);
2413 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasControlledStorage);
2417 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsFloatingPointPresent);
2420 IsFloatingPointOperationLogOrAbortEnabled);
2423 OutStreamer->emitIntValueInHexWithPadding(
2424 (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2431 if (FrameReg == (Subtarget->
isPPC64() ? PPC::X31 : PPC::R31))
2435 if (!MustSaveCRs.
empty())
2441 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsInterruptHandler);
2442 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);
2446 OnConditionDirective);
2450 OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),
2454 uint32_t SecondHalfOfMandatoryField = 0;
2461 for (
unsigned Reg = PPC::F14;
Reg <= PPC::F31; ++
Reg) {
2462 if (
MRI.isPhysRegModified(Reg)) {
2463 FPRSaved = PPC::F31 -
Reg + 1;
2469 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, IsBackChainStored);
2471 GENVALUECOMMENT(
", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
2473 OutStreamer->emitIntValueInHexWithPadding(
2474 (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
2480 bool HasVectorInst =
false;
2481 for (
unsigned Reg = PPC::V0;
Reg <= PPC::V31; ++
Reg)
2482 if (
MRI.isPhysRegUsed(Reg,
true)) {
2484 HasVectorInst =
true;
2491 uint16_t NumOfVRSaved = getNumberOfVRSaved();
2492 bool ShouldEmitEHBlock =
2495 if (ShouldEmitEHBlock)
2501 unsigned GPRBegin = Subtarget->
isPPC64() ? PPC::X14 : PPC::R13;
2502 unsigned GPREnd = Subtarget->
isPPC64() ? PPC::X31 : PPC::R31;
2504 for (
unsigned Reg = GPRBegin;
Reg <= GPREnd; ++
Reg) {
2505 if (
MRI.isPhysRegModified(Reg)) {
2506 GPRSaved = GPREnd -
Reg + 1;
2514 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, HasExtensionTable);
2516 GENVALUECOMMENT(
", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
2518 OutStreamer->emitIntValueInHexWithPadding(
2519 (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
2523 SecondHalfOfMandatoryField |=
2527 NumberOfFixedParms);
2529 OutStreamer->emitIntValueInHexWithPadding(
2530 (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2538 SecondHalfOfMandatoryField |=
2543 NumberOfFloatingPointParms);
2544 GENBOOLCOMMENT(
", ", SecondHalfOfMandatoryField, HasParmsOnStack);
2546 OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
2552 if (NumberOfFixedParms || NumberOfFPParms) {
2558 ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
2565 CommentOS <<
"Parameter type = " << ParmsType.
get();
2568 OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
2569 sizeof(ParmsTypeValue));
2572 OutStreamer->AddComment(
"Function size");
2574 MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
2576 OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
2588 int16_t NameLength =
Name.size();
2589 CommentOS <<
"Function name len = "
2590 <<
static_cast<unsigned int>(NameLength);
2591 EmitCommentAndValue(NameLength, 2);
2592 OutStreamer->AddComment(
"Function Name");
2593 OutStreamer->emitBytes(
Name);
2598 OutStreamer->AddComment(
"AllocaUsed");
2599 OutStreamer->emitIntValueInHex(AllocReg,
sizeof(AllocReg));
2632 OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
2637 OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
2645 CommentOS <<
"Vector Parameter type = " << VecParmsType.
get();
2648 OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
2649 sizeof(VecParmTypeValue));
2651 CommentOS <<
"Padding";
2652 EmitCommentAndValue(0, 2);
2655 uint8_t ExtensionTableFlag = 0;
2657 if (ShouldEmitEHBlock)
2658 ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
2661 ExtensionTableFlag |= ExtendedTBTableFlag::TB_SSP_CANARY;
2663 CommentOS <<
"ExtensionTableFlag = "
2665 EmitCommentAndValue(ExtensionTableFlag,
sizeof(ExtensionTableFlag));
2668 if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
2669 auto &Ctx = OutStreamer->getContext();
2672 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym, TOCType_EHBlock);
2674 getObjFileLowering().getTOCBaseSection())
2675 ->getQualNameSymbol();
2681 OutStreamer->emitValueToAlignment(
Align(4));
2682 OutStreamer->AddComment(
"EHInfo Table");
2683 OutStreamer->emitValue(Exp,
DL.getPointerSize());
2685#undef GENBOOLCOMMENT
2686#undef GENVALUECOMMENT
2695 .
Case(
"llvm.used",
true)
2697 .
Case(
"llvm.compiler.used",
true)
2703 .
Cases(
"llvm.global_ctors",
"llvm.global_dtors",
true)
2708 if (
auto *GA = dyn_cast<GlobalAlias>(
C))
2709 return getAliasOffset(GA->getAliasee());
2710 if (
auto *CE = dyn_cast<ConstantExpr>(
C)) {
2712 const MCBinaryExpr *CBE = dyn_cast<MCBinaryExpr>(LowC);
2717 auto *
RHS = dyn_cast<MCConstantExpr>(CBE->
getRHS());
2720 return RHS->getValue();
2730 "GlobalVariables with an alignment requirement stricter than TOC entry "
2731 "size not supported by the toc data transformation.");
2734 assert(GVType->
isSized() &&
"A GlobalVariable's size must be known to be "
2735 "supported by the toc data transformation.");
2739 "A GlobalVariable with size larger than a TOC entry is not currently "
2740 "supported by the toc data transformation.");
2743 "currently supported by the toc data transformation.");
2746void PPCAIXAsmPrinter::emitGlobalVariable(
const GlobalVariable *GV) {
2756 TOCDataGlobalVars.push_back(GV);
2760 emitGlobalVariableHelper(GV);
2763void PPCAIXAsmPrinter::emitGlobalVariableHelper(
const GlobalVariable *GV) {
2765 "Unhandled intrinsic global variable.");
2773 emitLinkage(GV, GVSym);
2777 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV, TM);
2781 "not supported yet.");
2788 OutStreamer->getCommentOS() <<
'\n';
2793 getObjFileLowering().SectionForGlobal(GV, GVKind, TM));
2796 OutStreamer->switchSection(Csect);
2805 GVSym->setStorageClass(
2809 OutStreamer->emitZeros(
Size);
2812 "BSS local toc-data already handled and TLS variables "
2813 "incompatible with XMC_TD");
2814 OutStreamer->emitXCOFFLocalCommonSymbol(
2815 OutContext.getOrCreateSymbol(GVSym->getSymbolTableName()),
Size,
2818 OutStreamer->emitCommonSymbol(GVSym,
Size, Alignment);
2826 emitLinkage(GV, EmittedInitSym);
2828 emitLinkage(GA, getSymbol(GA));
2830 emitAlignment(getGVAlignment(GV,
DL), GV);
2834 if (!
TM.getDataSections() || GV->hasSection()) {
2836 OutStreamer->emitLabel(EmittedInitSym);
2840 if (!GOAliasMap[GV].
size()) {
2841 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer());
2847 AliasMapTy AliasList;
2849 AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);
2852 emitGlobalConstant(GV->getDataLayout(), GV->getInitializer(),
2856void PPCAIXAsmPrinter::emitFunctionDescriptor() {
2858 const unsigned PointerSize =
DL.getPointerSizeInBits() == 64 ? 8 : 4;
2862 OutStreamer->switchSection(
2863 static_cast<MCSymbolXCOFF *
>(CurrentFnDescSym)->getRepresentedCsect());
2867 OutStreamer->emitLabel(getSymbol(Alias));
2874 getObjFileLowering().getTOCBaseSection())
2875 ->getQualNameSymbol();
2879 OutStreamer->emitIntValue(0, PointerSize);
2881 OutStreamer->switchSection(Current.first, Current.second);
2884void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2888 PPCAsmPrinter::emitFunctionEntryLabel();
2892 OutStreamer->emitLabel(
2893 getObjFileLowering().getFunctionEntryPointSymbol(Alias, TM));
2896void PPCAIXAsmPrinter::emitPGORefs(
Module &M) {
2897 if (!OutContext.hasXCOFFSection(
2908 bool HasNonZeroLengthPrfCntsSection =
false;
2911 if (GV.hasSection() && GV.getSection() ==
"__llvm_prf_cnts" &&
2912 DL.getTypeAllocSize(GV.getValueType()) > 0) {
2913 HasNonZeroLengthPrfCntsSection =
true;
2917 if (HasNonZeroLengthPrfCntsSection) {
2918 MCSection *CntsSection = OutContext.getXCOFFSection(
2923 OutStreamer->switchSection(CntsSection);
2924 if (OutContext.hasXCOFFSection(
2927 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_data[RW]");
2928 OutStreamer->emitXCOFFRefDirective(S);
2930 if (OutContext.hasXCOFFSection(
2933 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_names[RO]");
2934 OutStreamer->emitXCOFFRefDirective(S);
2936 if (OutContext.hasXCOFFSection(
2939 MCSymbol *S = OutContext.getOrCreateSymbol(
"__llvm_prf_vnds[RW]");
2940 OutStreamer->emitXCOFFRefDirective(S);
2945void PPCAIXAsmPrinter::emitGCOVRefs() {
2946 if (!OutContext.hasXCOFFSection(
2947 "__llvm_gcov_ctr_section",
2951 MCSection *CtrSection = OutContext.getXCOFFSection(
2956 OutStreamer->switchSection(CtrSection);
2959 if (OutContext.hasXCOFFSection(
2962 const char *SymbolStr =
TM.Options.XCOFFReadOnlyPointers
2963 ?
"__llvm_covinit[RO]"
2964 :
"__llvm_covinit[RW]";
2965 MCSymbol *S = OutContext.getOrCreateSymbol(SymbolStr);
2966 OutStreamer->emitXCOFFRefDirective(S);
2970void PPCAIXAsmPrinter::emitEndOfAsmFile(
Module &M) {
2973 if (
M.empty() && TOCDataGlobalVars.empty())
2980 OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());
2985 for (
auto &
I : TOC) {
2993 (Subtarget->hasAIXShLibTLSModelOpt() &&
2999 ->getSymbolTableName();
3002 getObjFileLowering().getSectionForTOCEntry(S, TM));
3005 getObjFileLowering().getSectionForTOCEntry(
I.first.first, TM));
3007 OutStreamer->switchSection(TCEntry);
3009 OutStreamer->emitLabel(
I.second);
3016 for (
const auto *GV : TOCDataGlobalVars) {
3017 if (!GV->hasCommonLinkage())
3018 emitGlobalVariableHelper(GV);
3020 for (
const auto *GV : TOCDataGlobalVars) {
3021 if (GV->hasCommonLinkage())
3022 emitGlobalVariableHelper(GV);
3026bool PPCAIXAsmPrinter::doInitialization(
Module &M) {
3027 const bool Result = PPCAsmPrinter::doInitialization(M);
3037 if (FunCpuId > TargetCpuId)
3038 TargetCpuId = FunCpuId;
3053 auto setCsectAlignment = [
this](
const GlobalObject *GO) {
3055 if (GO->isDeclarationForLinker())
3058 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);
3060 getObjFileLowering().SectionForGlobal(GO, GOKind, TM));
3062 Align GOAlign = getGVAlignment(GO, GO->getDataLayout());
3063 Csect->ensureMinAlignment(GOAlign);
3070 auto DL =
M.getDataLayout();
3071 for (
const auto &
G :
M.globals()) {
3072 if (
G.isThreadLocal() && !
G.isDeclaration()) {
3073 TLSVarAddress =
alignTo(TLSVarAddress, getGVAlignment(&
G,
DL));
3074 TLSVarsToAddressMapping[&
G] = TLSVarAddress;
3075 TLSVarAddress +=
DL.getTypeAllocSize(
G.getValueType());
3082 for (
const auto &
G :
M.globals()) {
3089 if (FormatIndicatorAndUniqueModId.empty()) {
3091 if (UniqueModuleId !=
"")
3095 FormatIndicatorAndUniqueModId =
"clang_" + UniqueModuleId.substr(1);
3100 std::chrono::duration_cast<std::chrono::nanoseconds>(
3101 std::chrono::steady_clock::now().time_since_epoch())
3103 FormatIndicatorAndUniqueModId =
3106 llvm::itostr(CurTime);
3110 emitSpecialLLVMGlobal(&
G);
3114 setCsectAlignment(&
G);
3115 std::optional<CodeModel::Model> OptionalCodeModel =
G.getCodeModel();
3116 if (OptionalCodeModel)
3118 *OptionalCodeModel);
3121 for (
const auto &
F : M)
3122 setCsectAlignment(&
F);
3125 for (
const auto &Alias :
M.aliases()) {
3129 "alias without a base object is not yet supported on AIX");
3133 "\n\tAlias attribute for " +
3134 Alias.getName() +
" is invalid because " +
3135 Aliasee->
getName() +
" is common.",
3140 dyn_cast_or_null<GlobalVariable>(Alias.getAliaseeObject());
3142 std::optional<CodeModel::Model> OptionalCodeModel = GVar->
getCodeModel();
3143 if (OptionalCodeModel)
3145 *OptionalCodeModel);
3148 GOAliasMap[Aliasee].push_back(&Alias);
3155 switch (
MI->getOpcode()) {
3162 if (
MI->getNumOperands() < 5)
3168 MCSymbol *TempSym = OutContext.createNamedTempSymbol();
3169 OutStreamer->emitLabel(TempSym);
3170 OutStreamer->emitXCOFFExceptDirective(
3171 CurrentFnSym, TempSym, LangMO.
getImm(), ReasonMO.
getImm(),
3172 Subtarget->
isPPC64() ?
MI->getMF()->getInstructionCount() * 8
3173 :
MI->getMF()->getInstructionCount() * 4,
3177 case PPC::GETtlsMOD32AIX:
3178 case PPC::GETtlsMOD64AIX:
3179 case PPC::GETtlsTpointer32AIX:
3180 case PPC::GETtlsADDR64AIX:
3181 case PPC::GETtlsADDR32AIX: {
3186 ExtSymSDNodeSymbols.insert(TlsGetAddr);
3197 ExtSymSDNodeSymbols.insert(S);
3203 case PPC::BL8_NOP_TLS:
3210 case PPC::TAILBCTR8:
3211 if (
MI->getOperand(0).isSymbol())
3224 MCInstBuilder(PPC::ORI).addReg(PPC::R0).addReg(PPC::R0).addImm(0));
3227 return PPCAsmPrinter::emitInstruction(
MI);
3230bool PPCAIXAsmPrinter::doFinalization(
Module &M) {
3236 auto *Sec = OutContext.getObjectFileInfo()->getTextSection();
3237 OutStreamer->switchSectionNoPrint(Sec);
3239 OutStreamer->emitLabel(
Sym);
3244 return PPCAsmPrinter::doFinalization(M);
3248 if (P < 0 || P > 65535)
3255 return 20 + (
P - 20) * 16;
3258 return 1004 + (
P - 81);
3261 return 2047 + (
P - 1124) * 33878;
3263 return 2147482625u + (
P - 64512);
3282 std::string PrioritySuffix;
3285 return PrioritySuffix;
3288void PPCAIXAsmPrinter::emitXXStructorList(
const DataLayout &
DL,
3289 const Constant *List,
bool IsCtor) {
3291 preprocessXXStructorList(
DL, List, Structors);
3292 if (Structors.
empty())
3296 for (Structor &S : Structors) {
3297 if (
const ConstantExpr *CE = dyn_cast<ConstantExpr>(S.Func))
3298 S.Func =
CE->getOperand(0);
3306 cast<Function>(S.Func));
3310void PPCAIXAsmPrinter::emitTTypeReference(
const GlobalValue *GV,
3311 unsigned Encoding) {
3313 TOCEntryType GlobalType = TOCType_GlobalInternal;
3318 GlobalType = TOCType_GlobalExternal;
3320 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym, GlobalType);
3322 getObjFileLowering().getTOCBaseSection())
3323 ->getQualNameSymbol();
3324 auto &Ctx = OutStreamer->getContext();
3328 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
3330 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
3337 std::unique_ptr<MCStreamer> &&Streamer) {
3339 return new PPCAIXAsmPrinter(tm, std::move(Streamer));
3341 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
3344void PPCAIXAsmPrinter::emitModuleCommandLines(
Module &M) {
3345 const NamedMDNode *NMD =
M.getNamedMetadata(
"llvm.commandline");
3353 assert(
N->getNumOperands() == 1 &&
3354 "llvm.commandline metadata entry can have only one operand");
3355 const MDString *MDS = cast<MDString>(
N->getOperand(0));
3358 RSOS <<
"@(#)opt " << MDS->
getString() <<
"\n";
3361 OutStreamer->emitXCOFFCInfoSym(
".GCC.command.line", RSOS.str());
3364char PPCAIXAsmPrinter::ID = 0;
3367 "AIX PPC Assembly Printer",
false,
false)
3371LLVMInitializePowerPCAsmPrinter() {
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static AMDGPUMCExpr::Specifier getSpecifier(unsigned MOFlags)
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)
#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)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Provides a library for accessing information about this process and other processes on the operating ...
static SDValue lowerConstant(SDValue Op, SelectionDAG &DAG, const RISCVSubtarget &Subtarget)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
This file implements a set that has insertion order iteration characteristics.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This class is intended to be used as a driving class for all asm writers.
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.
LLVM_ABI unsigned getPointerSize(unsigned AS=0) const
The pointer representation size in bytes, rounded up to a whole number of bytes.
TypeSize getTypeSizeInBits(Type *Ty) const
Size examples:
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 LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
bool hasSection() const
Check if this global has a custom object file section.
LinkageTypes getLinkage() const
bool hasPrivateLinkage() const
bool isDeclarationForLinker() const
Module * getParent()
Get the module that this global value is contained inside of...
LLVM_ABI const GlobalObject * getAliaseeObject() const
@ DefaultVisibility
The GV is visible.
@ HiddenVisibility
The GV is hidden.
@ ProtectedVisibility
The GV is protected.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
bool hasCommonLinkage() const
bool hasAppendingLinkage() const
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ 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.
MaybeAlign getAlign() const
Returns the alignment of the given variable.
Binary assembler expressions.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
Opcode getOpcode() const
Get the kind of this binary expression.
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
LLVM_ABI 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.
Wrapper class representing physical registers. Should be passed by value.
This represents a section on linux, lots of unix variants and some bare metal systems.
MCSymbolXCOFF * getQualNameSymbol() const
Instances of this class represent a uniqued identifier for a section in the current translation unit.
void setAlignment(Align Value)
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Represent a reference to a symbol from inside an expression.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
void setPerSymbolCodeModel(MCSymbolXCOFF::CodeModel Model)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
LLVM_ABI StringRef getString() const
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
MCSection * getSection() const
Returns the Section this function belongs to.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
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.
LLVM_ABI MDNode * getOperand(unsigned i) const
LLVM_ABI unsigned getNumOperands() const
uint64_t getTOCSaveOffset() const
getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.
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)
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 emitLocalEntry(MCSymbolELF *S, const MCExpr *LocalOffset)
virtual void emitTCEntry(const MCSymbol &S, PPCMCExpr::Specifier Kind)
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.
LLVM_ABI void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
LLVM_ABI 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.
LLVM_ABI void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
LLVM_ABI void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
A raw_ostream that writes to an SmallVector or SmallString.
static LLVM_ABI Pid getProcessId()
Get the process's identifier.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr 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...
LLVM_ABI StringRef getNormalizedPPCTargetCPU(const Triple &T, StringRef CPUName="")
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
const char * stripRegisterPrefix(const char *RegName)
stripRegisterPrefix - This method strips the character prefix from a register name so that only the n...
static bool isVRRegister(unsigned Reg)
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
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)
LLVM_ABI SmallString< 32 > getExtendedTBTableFlagString(uint8_t Flag)
LLVM_ABI XCOFF::CFileCpuId getCpuID(StringRef CPU)
LLVM_ABI Expected< SmallString< 32 > > parseParmsTypeWithVecInfo(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum, unsigned VectorParmsNum)
LLVM_ABI Expected< SmallString< 32 > > parseParmsType(uint32_t Value, unsigned FixedParmsNum, unsigned FloatingParmsNum)
LLVM_ABI Expected< SmallString< 32 > > parseVectorParmsType(uint32_t Value, unsigned ParmsNum)
@ TCPU_INVALID
Invalid id - assumes POWER for old objects.
StorageMappingClass
Storage Mapping Class definitions.
@ XMC_RO
Read Only Constant.
@ XMC_TD
Scalar data item in the TOC.
LLVM_ABI StringRef getTCPUString(XCOFF::CFileCpuId TCPU)
LLVM_ABI StringRef getNameForTracebackTableLanguageId(TracebackTable::LanguageID LangId)
constexpr uint8_t AllocRegNo
@ XTY_SD
Csect definition for initialized storage.
@ XTY_ER
External reference.
initializer< Ty > init(const Ty &Val)
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
constexpr uint64_t PointerSize
aarch64 pointer size.
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()
LLVM_ABI std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...
std::pair< MCSection *, uint32_t > MCSectionSubPair
void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
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()
LLVM_ABI uint64_t get_threadid()
Return the current thread id, as used in various OS system calls.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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 bool isEqual(const TOCKey &A, const TOCKey &B)
std::pair< const MCSymbol *, PPCMCExpr::Specifier > TOCKey
static unsigned getHashValue(const TOCKey &PairVal)
static TOCKey getTombstoneKey()
static TOCKey getEmptyKey()
An information struct used to provide DenseMap with the various necessary components for a given valu...
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
static void RegisterAsmPrinter(Target &T, Target::AsmPrinterCtorTy Fn)
RegisterAsmPrinter - Register an AsmPrinter implementation for the given target.
static constexpr uint32_t FPRSavedMask
static constexpr uint16_t NumberOfVRSavedMask
static constexpr uint8_t NumberOfFloatingPointParmsShift
static constexpr uint32_t NumberOfFixedParmsMask
static constexpr uint16_t HasVMXInstructionMask
static constexpr uint32_t IsLRSavedMask
static constexpr uint16_t HasVarArgsMask
static constexpr uint32_t IsAllocaUsedMask
static constexpr uint16_t IsVRSavedOnStackMask
static constexpr uint16_t NumberOfVectorParmsMask
static constexpr uint32_t IsFloatingPointPresentMask
static constexpr uint32_t FPRSavedShift
static constexpr uint32_t NumberOfFloatingPointParmsMask
static constexpr uint32_t HasControlledStorageMask
static constexpr uint32_t HasExtensionTableMask
static constexpr uint32_t HasTraceBackTableOffsetMask
static constexpr uint32_t IsCRSavedMask
static constexpr uint8_t NumberOfFixedParmsShift
static constexpr uint32_t GPRSavedMask
static constexpr uint8_t NumberOfVectorParmsShift
static constexpr uint32_t HasParmsOnStackMask
static constexpr uint32_t IsFunctionNamePresentMask
static constexpr uint32_t IsBackChainStoredMask
static constexpr uint32_t IsInterruptHandlerMask
static constexpr uint32_t HasVectorInfoMask
static constexpr uint8_t NumberOfVRSavedShift
static constexpr uint32_t GPRSavedShift