81#define DEBUG_TYPE "asmprinter"
94 using TOCKey = std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind>;
115 Tag_GNU_Power_ABI_FP = 4,
116 Tag_GNU_Power_ABI_Vector = 8,
117 Tag_GNU_Power_ABI_Struct_Return = 12,
120 Val_GNU_Power_ABI_NoFloat = 0b00,
121 Val_GNU_Power_ABI_HardFloat_DP = 0b01,
122 Val_GNU_Power_ABI_SoftFloat_DP = 0b10,
123 Val_GNU_Power_ABI_HardFloat_SP = 0b11,
125 Val_GNU_Power_ABI_LDBL_IBM128 = 0b0100,
126 Val_GNU_Power_ABI_LDBL_64 = 0b1000,
127 Val_GNU_Power_ABI_LDBL_IEEE128 = 0b1100,
146 std::unique_ptr<MCStreamer> Streamer)
153 MCSymbolRefExpr::VariantKind::VK_None);
186class PPCLinuxAsmPrinter :
public PPCAsmPrinter {
189 std::unique_ptr<MCStreamer> Streamer)
190 : PPCAsmPrinter(
TM,
std::
move(Streamer)) {}
193 return "Linux PPC Assembly Printer";
196 void emitGNUAttributes(
Module &M);
198 void emitStartOfAsmFile(
Module &M)
override;
199 void emitEndOfAsmFile(
Module &)
override;
201 void emitFunctionEntryLabel()
override;
203 void emitFunctionBodyStart()
override;
204 void emitFunctionBodyEnd()
override;
208class PPCAIXAsmPrinter :
public PPCAsmPrinter {
216 std::string FormatIndicatorAndUniqueModId;
224 void emitTracebackTable();
234 PPCAIXAsmPrinter(
TargetMachine &
TM, std::unique_ptr<MCStreamer> Streamer)
235 : PPCAsmPrinter(
TM,
std::
move(Streamer)) {
236 if (MAI->isLittleEndian())
238 "cannot create AIX PPC Assembly Printer for a little-endian target");
241 StringRef getPassName()
const override {
return "AIX PPC Assembly Printer"; }
243 bool doInitialization(
Module &M)
override;
246 bool IsCtor)
override;
252 void emitFunctionDescriptor()
override;
254 void emitFunctionEntryLabel()
override;
256 void emitFunctionBodyEnd()
override;
260 void emitEndOfAsmFile(
Module &)
override;
266 bool doFinalization(
Module &M)
override;
268 void emitTTypeReference(
const GlobalValue *GV,
unsigned Encoding)
override;
277 getSymbol(GV)->
print(O, MAI);
281void PPCAsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNo,
304 O <<
DL.getPrivateGlobalPrefix() <<
"CPI" << getFunctionNumber() <<
'_'
311 PrintSymbolOperand(MO, O);
323bool PPCAsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNo,
326 if (ExtraCode && ExtraCode[0]) {
327 if (ExtraCode[1] != 0)
return true;
329 switch (ExtraCode[0]) {
335 if (!
MI->getOperand(OpNo).isReg() ||
336 OpNo+1 ==
MI->getNumOperands() ||
337 !
MI->getOperand(OpNo+1).isReg())
344 if (
MI->getOperand(OpNo).isImm())
348 if(!
MI->getOperand(OpNo).isReg())
354 Reg = PPC::VSX32 + (
Reg - PPC::V0);
356 Reg = PPC::VSX32 + (Reg - PPC::VF0);
372bool PPCAsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNo,
373 const char *ExtraCode,
375 if (ExtraCode && ExtraCode[0]) {
376 if (ExtraCode[1] != 0)
return true;
378 switch (ExtraCode[0]) {
379 default:
return true;
381 O << getDataLayout().getPointerSize() <<
"(";
392 if (
MI->getOperand(OpNo).isImm())
403 assert(
MI->getOperand(OpNo).isReg());
408 assert(
MI->getOperand(OpNo).isReg());
419PPCAsmPrinter::lookUpOrCreateTOCEntry(
const MCSymbol *Sym,
423 TOCEntry = createTempSymbol(
"C");
428 unsigned NumNOPBytes =
MI.getOperand(1).getImm();
430 auto &Ctx = OutStreamer->getContext();
431 MCSymbol *MILabel = Ctx.createTempSymbol();
432 OutStreamer->emitLabel(MILabel);
435 assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
441 while (NumNOPBytes > 0) {
442 if (MII ==
MBB.
end() || MII->isCall() ||
443 MII->getOpcode() == PPC::DBG_VALUE ||
444 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
445 MII->getOpcode() == TargetOpcode::STACKMAP)
452 for (
unsigned i = 0; i < NumNOPBytes; i += 4)
459 auto &Ctx = OutStreamer->getContext();
460 MCSymbol *MILabel = Ctx.createTempSymbol();
461 OutStreamer->emitLabel(MILabel);
466 unsigned EncodedBytes = 0;
469 if (CalleeMO.
isImm()) {
470 int64_t CallTarget = CalleeMO.
getImm();
472 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
473 "High 16 bits of call target should be zero.");
474 Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
479 .addImm((CallTarget >> 32) & 0xFFFF));
484 .addImm(32).addImm(16));
489 .addImm((CallTarget >> 16) & 0xFFFF));
494 .addImm(CallTarget & 0xFFFF));
500 .addImm(TOCSaveOffset)
513 .addReg(ScratchReg));
518 .addReg(ScratchReg));
523 .addReg(ScratchReg));
531 .addImm(TOCSaveOffset)
537 MCSymbol *MOSymbol = getSymbol(GValue);
549 unsigned NumBytes = Opers.getNumPatchBytes();
550 assert(NumBytes >= EncodedBytes &&
551 "Patchpoint can't request size less than the length of a call.");
552 assert((NumBytes - EncodedBytes) % 4 == 0 &&
553 "Invalid number of NOP bytes requested!");
554 for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
573 unsigned Opcode = PPC::BL8_NOP_TLS;
575 assert(
MI->getNumOperands() >= 3 &&
"Expecting at least 3 operands from MI");
579 Opcode = PPC::BL8_NOTOC_TLS;
581 const Module *
M = MF->getFunction().getParent();
584 ((Subtarget->
isPPC64() &&
MI->getOperand(0).getReg() == PPC::X3) ||
585 (!Subtarget->
isPPC64() &&
MI->getOperand(0).getReg() == PPC::R3)) &&
586 "GETtls[ld]ADDR[32] must define GPR3");
588 ((Subtarget->
isPPC64() &&
MI->getOperand(1).getReg() == PPC::X3) ||
589 (!Subtarget->
isPPC64() &&
MI->getOperand(1).getReg() == PPC::R3)) &&
590 "GETtls[ld]ADDR[32] must read GPR3");
600 MI->getOperand(2).getReg() == VarOffsetReg &&
601 "GETtls[ld]ADDR[32] must read GPR4");
605 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::BLA).addExpr(TlsRef));
609 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(
"__tls_get_addr");
624 MCSymbol *MOSymbol = getSymbol(GValue);
626 EmitToStreamer(*OutStreamer,
628 : (
unsigned)PPC::BL_TLS)
655 PPC_MC::verifyInstructionPredicates(
MI->getOpcode(),
656 getSubtargetInfo().getFeatureBits());
659 const bool IsPPC64 = Subtarget->
isPPC64();
660 const bool IsAIX = Subtarget->
isAIXABI();
661 const Module *
M = MF->getFunction().getParent();
666 if (!
MI->isInlineAsm()) {
670 if (Subtarget->hasSPE()) {
671 if (PPC::F4RCRegClass.
contains(Reg) ||
680 if (PPC::SPERCRegClass.
contains(Reg))
688 auto getTOCRelocAdjustedExprForXCOFF = [
this](
const MCExpr *Expr,
697 OriginalOffset - llvm::SignExtend32<16>(OriginalOffset);
702 auto getTOCEntryLoadingExprForXCOFF =
703 [IsPPC64, getTOCRelocAdjustedExprForXCOFF,
706 MCSymbolRefExpr::VariantKind::VK_None) ->
const MCExpr * {
707 const unsigned EntryByteSize = IsPPC64 ? 8 : 4;
708 const auto TOCEntryIter = TOC.
find({MOSymbol, VK});
710 "Could not find the TOC entry for this symbol.");
711 const ptrdiff_t EntryDistanceFromTOCBase =
712 (TOCEntryIter - TOC.
begin()) * EntryByteSize;
713 constexpr int16_t PositiveTOCRange = INT16_MAX;
715 if (EntryDistanceFromTOCBase > PositiveTOCRange)
716 return getTOCRelocAdjustedExprForXCOFF(Expr, EntryDistanceFromTOCBase);
725 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM;
727 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD;
728 return MCSymbolRefExpr::VariantKind::VK_None;
732 switch (
MI->getOpcode()) {
734 case TargetOpcode::DBG_VALUE:
736 case TargetOpcode::STACKMAP:
737 return LowerSTACKMAP(SM, *
MI);
738 case TargetOpcode::PATCHPOINT:
739 return LowerPATCHPOINT(SM, *
MI);
741 case PPC::MoveGOTtoLR: {
749 OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
758 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::BL).addExpr(OffsExpr));
761 case PPC::MovePCtoLR:
762 case PPC::MovePCtoLR8: {
767 MCSymbol *PICBase = MF->getPICBaseSymbol();
770 EmitToStreamer(*OutStreamer,
777 OutStreamer->emitLabel(PICBase);
780 case PPC::UpdateGBR: {
789 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
791 MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
803 MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));
808 MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
828 EmitToStreamer(*OutStreamer, TmpInst);
834 EmitToStreamer(*OutStreamer, TmpInst);
847 "Invalid operand for LWZtoc.");
859 EmitToStreamer(*OutStreamer, TmpInst);
868 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol, VK);
878 "This pseudo should only be selected for 32-bit small code model.");
879 Exp = getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK);
884 OutStreamer->getCommentOS() << MO <<
'\n';
885 EmitToStreamer(*OutStreamer, TmpInst);
892 OutContext.getOrCreateSymbol(
Twine(
".LTOC")), OutContext);
895 EmitToStreamer(*OutStreamer, TmpInst);
899 case PPC::ADDItoc8: {
901 "PseudoOp only valid for small code model AIX");
907 TmpInst.
setOpcode((!IsPPC64) ? (PPC::LA) : (PPC::LA8));
920 EmitToStreamer(*OutStreamer, TmpInst);
945 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol, VK);
951 IsAIX ? getTOCEntryLoadingExprForXCOFF(MOSymbol, Exp, VK) : Exp);
954 if (isVerbose() && IsAIX)
955 OutStreamer->getCommentOS() << MO <<
'\n';
956 EmitToStreamer(*OutStreamer, TmpInst);
959 case PPC::ADDIStocHA: {
961 "This pseudo should only be selected for 32-bit large code model on"
972 "Invalid operand for ADDIStocHA.");
983 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol, VK);
988 EmitToStreamer(*OutStreamer, TmpInst);
993 "This pseudo should only be selected for 32-bit large code model on"
1004 "Invalid operand for LWZtocL.");
1015 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol, VK);
1020 EmitToStreamer(*OutStreamer, TmpInst);
1023 case PPC::ADDIStocHA8: {
1035 "Invalid operand for ADDIStocHA8!");
1041 const bool GlobalToc =
1045 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, VK);
1059 EmitToStreamer(*OutStreamer, TmpInst);
1075 "Invalid operand for LDtocL!");
1079 "LDtocL used on symbol that could be accessed directly is "
1080 "invalid. Must match ADDIStocHA8."));
1087 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol, VK);
1093 EmitToStreamer(*OutStreamer, TmpInst);
1096 case PPC::ADDItocL: {
1110 "Interposable definitions must use indirect access."));
1116 EmitToStreamer(*OutStreamer, TmpInst);
1119 case PPC::ADDISgotTprelHA: {
1122 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1125 MCSymbol *MOSymbol = getSymbol(GValue);
1126 const MCExpr *SymGotTprel =
1130 .addReg(
MI->getOperand(0).getReg())
1131 .
addReg(
MI->getOperand(1).getReg())
1135 case PPC::LDgotTprelL:
1136 case PPC::LDgotTprelL32: {
1141 TmpInst.
setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ);
1144 MCSymbol *MOSymbol = getSymbol(GValue);
1150 EmitToStreamer(*OutStreamer, TmpInst);
1154 case PPC::PPC32PICGOT: {
1155 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1156 MCSymbol *GOTRef = OutContext.createTempSymbol();
1157 MCSymbol *NextInstr = OutContext.createTempSymbol();
1167 OutStreamer->emitLabel(GOTRef);
1168 OutStreamer->emitValue(OffsExpr, 4);
1169 OutStreamer->emitLabel(NextInstr);
1171 .addReg(
MI->getOperand(0).getReg()));
1173 .addReg(
MI->getOperand(1).getReg())
1175 .
addReg(
MI->getOperand(0).getReg()));
1177 .addReg(
MI->getOperand(0).getReg())
1178 .
addReg(
MI->getOperand(1).getReg())
1179 .
addReg(
MI->getOperand(0).getReg()));
1182 case PPC::PPC32GOT: {
1184 OutContext.getOrCreateSymbol(
StringRef(
"_GLOBAL_OFFSET_TABLE_"));
1190 .addReg(
MI->getOperand(0).getReg())
1193 .addReg(
MI->getOperand(0).getReg())
1194 .
addReg(
MI->getOperand(0).getReg())
1198 case PPC::ADDIStlsgdHA: {
1201 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1204 MCSymbol *MOSymbol = getSymbol(GValue);
1205 const MCExpr *SymGotTlsGD =
1209 .addReg(
MI->getOperand(0).getReg())
1210 .
addReg(
MI->getOperand(1).getReg())
1214 case PPC::ADDItlsgdL:
1217 case PPC::ADDItlsgdL32: {
1222 MCSymbol *MOSymbol = getSymbol(GValue);
1227 EmitToStreamer(*OutStreamer,
1229 .addReg(
MI->getOperand(0).getReg())
1230 .
addReg(
MI->getOperand(1).getReg())
1234 case PPC::GETtlsADDR:
1237 case PPC::GETtlsADDRPCREL:
1238 case PPC::GETtlsADDR32AIX:
1239 case PPC::GETtlsADDR64AIX:
1243 case PPC::GETtlsADDR32: {
1249 case PPC::ADDIStlsldHA: {
1252 assert(IsPPC64 &&
"Not supported for 32-bit PowerPC");
1255 MCSymbol *MOSymbol = getSymbol(GValue);
1256 const MCExpr *SymGotTlsLD =
1260 .addReg(
MI->getOperand(0).getReg())
1261 .
addReg(
MI->getOperand(1).getReg())
1265 case PPC::ADDItlsldL:
1268 case PPC::ADDItlsldL32: {
1273 MCSymbol *MOSymbol = getSymbol(GValue);
1278 EmitToStreamer(*OutStreamer,
1280 .addReg(
MI->getOperand(0).getReg())
1281 .
addReg(
MI->getOperand(1).getReg())
1285 case PPC::GETtlsldADDR:
1288 case PPC::GETtlsldADDRPCREL:
1289 case PPC::GETtlsldADDR32: {
1295 case PPC::ADDISdtprelHA:
1298 case PPC::ADDISdtprelHA32: {
1303 MCSymbol *MOSymbol = getSymbol(GValue);
1304 const MCExpr *SymDtprel =
1310 .addReg(
MI->getOperand(0).getReg())
1311 .
addReg(
MI->getOperand(1).getReg())
1315 case PPC::PADDIdtprel: {
1320 MCSymbol *MOSymbol = getSymbol(GValue);
1324 .addReg(
MI->getOperand(0).getReg())
1325 .
addReg(
MI->getOperand(1).getReg())
1330 case PPC::ADDIdtprelL:
1333 case PPC::ADDIdtprelL32: {
1338 MCSymbol *MOSymbol = getSymbol(GValue);
1339 const MCExpr *SymDtprel =
1342 EmitToStreamer(*OutStreamer,
1344 .addReg(
MI->getOperand(0).getReg())
1345 .
addReg(
MI->getOperand(1).getReg())
1351 if (!Subtarget->hasMFOCRF()) {
1354 unsigned NewOpcode =
1355 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
1359 .addReg(
MI->getOperand(0).getReg()));
1365 if (!Subtarget->hasMFOCRF()) {
1368 unsigned NewOpcode =
1369 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1370 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
1371 ->getEncodingValue(
MI->getOperand(0).getReg());
1376 .addReg(
MI->getOperand(1).getReg()));
1386 unsigned OpNum = (
MI->getOpcode() == PPC::STD) ? 2 : 1;
1396 case PPC::PseudoEIEIO: {
1399 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1402 MCInstBuilder(PPC::ORI).addReg(PPC::X2).addReg(PPC::X2).addImm(0));
1403 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::EnforceIEIO));
1409 EmitToStreamer(*OutStreamer, TmpInst);
1412void PPCLinuxAsmPrinter::emitGNUAttributes(
Module &M) {
1414 Metadata *MD =
M.getModuleFlag(
"float-abi");
1415 MDString *FloatABI = dyn_cast_or_null<MDString>(MD);
1420 if (flt ==
"doubledouble")
1421 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1422 Val_GNU_Power_ABI_HardFloat_DP |
1423 Val_GNU_Power_ABI_LDBL_IBM128);
1424 else if (flt ==
"ieeequad")
1425 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1426 Val_GNU_Power_ABI_HardFloat_DP |
1427 Val_GNU_Power_ABI_LDBL_IEEE128);
1428 else if (flt ==
"ieeedouble")
1429 OutStreamer->emitGNUAttribute(Tag_GNU_Power_ABI_FP,
1430 Val_GNU_Power_ABI_HardFloat_DP |
1431 Val_GNU_Power_ABI_LDBL_64);
1434void PPCLinuxAsmPrinter::emitInstruction(
const MachineInstr *
MI) {
1436 return PPCAsmPrinter::emitInstruction(
MI);
1438 switch (
MI->getOpcode()) {
1440 return PPCAsmPrinter::emitInstruction(
MI);
1441 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1453 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1454 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1455 OutStreamer->emitLabel(BeginOfSled);
1456 EmitToStreamer(*OutStreamer,
1462 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1463 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1464 EmitToStreamer(*OutStreamer,
1467 OutContext.getOrCreateSymbol(
"__xray_FunctionEntry"),
1469 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1470 OutStreamer->emitLabel(EndOfSled);
1471 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_ENTER, 2);
1474 case TargetOpcode::PATCHABLE_RET: {
1475 unsigned RetOpcode =
MI->getOperand(0).getImm();
1485 if (RetOpcode == PPC::BCCLR) {
1486 IsConditional =
true;
1487 }
else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1488 RetOpcode == PPC::TCRETURNai8) {
1490 }
else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1491 IsConditional =
false;
1493 EmitToStreamer(*OutStreamer, RetInst);
1498 if (IsConditional) {
1517 FallthroughLabel = OutContext.createTempSymbol();
1523 .
addReg(
MI->getOperand(2).getReg())
1540 OutStreamer->emitCodeAlignment(
Align(8), &getSubtargetInfo());
1541 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1542 OutStreamer->emitLabel(BeginOfSled);
1543 EmitToStreamer(*OutStreamer, RetInst);
1547 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1548 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1549 EmitToStreamer(*OutStreamer,
1552 OutContext.getOrCreateSymbol(
"__xray_FunctionExit"),
1554 EmitToStreamer(*OutStreamer,
MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1555 EmitToStreamer(*OutStreamer, RetInst);
1557 OutStreamer->emitLabel(FallthroughLabel);
1558 recordSled(BeginOfSled, *
MI, SledKind::FUNCTION_EXIT, 2);
1561 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1563 case TargetOpcode::PATCHABLE_TAIL_CALL:
1567 "around this assert.");
1571void PPCLinuxAsmPrinter::emitStartOfAsmFile(
Module &M) {
1579 !isPositionIndependent())
1585 OutStreamer->switchSection(OutContext.getELFSection(
1588 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(
Twine(
".LTOC"));
1589 MCSymbol *CurrentPos = OutContext.createTempSymbol();
1591 OutStreamer->emitLabel(CurrentPos);
1600 OutStreamer->emitAssignment(TOCSym, tocExpr);
1602 OutStreamer->switchSection(getObjFileLowering().getTextSection());
1605void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
1608 (!isPositionIndependent() ||
1614 if (PPCFI->
usesPICBase() && !Subtarget->isSecurePlt()) {
1616 MCSymbol *PICBase = MF->getPICBaseSymbol();
1617 OutStreamer->emitLabel(RelocSymbol);
1625 OutStreamer->emitValue(OffsExpr, 4);
1626 OutStreamer->emitLabel(CurrentFnSym);
1639 && !MF->getRegInfo().use_empty(PPC::X2)) {
1644 const MCExpr *TOCDeltaExpr =
1651 OutStreamer->emitValue(TOCDeltaExpr, 8);
1660 OutStreamer->switchSection(Section);
1661 OutStreamer->emitLabel(CurrentFnSym);
1662 OutStreamer->emitValueToAlignment(
Align(8));
1663 MCSymbol *Symbol1 = CurrentFnSymForSize;
1670 OutStreamer->emitValue(
1674 OutStreamer->emitIntValue(0, 8 );
1675 OutStreamer->switchSection(Current.first, Current.second);
1678void PPCLinuxAsmPrinter::emitEndOfAsmFile(
Module &M) {
1681 bool isPPC64 =
DL.getPointerSizeInBits() == 64;
1686 emitGNUAttributes(M);
1689 const char *
Name = isPPC64 ?
".toc" :
".got2";
1692 OutStreamer->switchSection(Section);
1694 OutStreamer->emitValueToAlignment(
Align(4));
1696 for (
const auto &TOCMapPair : TOC) {
1697 const MCSymbol *
const TOCEntryTarget = TOCMapPair.first.first;
1698 MCSymbol *
const TOCEntryLabel = TOCMapPair.second;
1700 OutStreamer->emitLabel(TOCEntryLabel);
1702 TS->
emitTCEntry(*TOCEntryTarget, TOCMapPair.first.second);
1704 OutStreamer->emitSymbolValue(TOCEntryTarget, 4);
1708 PPCAsmPrinter::emitEndOfAsmFile(M);
1712void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
1745 const bool UsesX2OrR2 = !MF->getRegInfo().use_empty(PPC::X2) ||
1746 !MF->getRegInfo().use_empty(PPC::R2);
1755 if (NonPCrelGEPRequired || PCrelGEPRequired) {
1760 OutStreamer->emitLabel(GlobalEntryLabel);
1766 const MCExpr *TOCDeltaExpr =
1768 GlobalEntryLabelExp, OutContext);
1774 .addExpr(TOCDeltaHi));
1780 .addExpr(TOCDeltaLo));
1783 const MCExpr *TOCOffsetDeltaExpr =
1785 GlobalEntryLabelExp, OutContext);
1789 .addExpr(TOCOffsetDeltaExpr)
1798 OutStreamer->emitLabel(LocalEntryLabel);
1801 const MCExpr *LocalOffsetExp =
1803 GlobalEntryLabelExp, OutContext);
1807 TS->
emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), LocalOffsetExp);
1830 if (MF->getFrameInfo().hasCalls() || MF->getFrameInfo().hasTailCall() ||
1831 MF->hasInlineAsm() || (!PPCFI->
usesTOCBasePtr() && UsesX2OrR2)) {
1843void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
1852 OutStreamer->emitIntValue(0, 4);
1853 OutStreamer->emitIntValue(0, 8);
1857void PPCAIXAsmPrinter::emitLinkage(
const GlobalValue *GV,
1860 assert(MAI->hasVisibilityOnlyWithLinkage() &&
1861 "AIX's linkage directives take a visibility setting.");
1882 "InternalLinkage should not have other visibility setting.");
1894 if (!
TM.getIgnoreXCOFFVisibility()) {
1897 "Cannot not be both dllexport and non-default visibility");
1903 VisibilityAttr = MAI->getExportedVisibilityAttr();
1906 VisibilityAttr = MAI->getHiddenVisibilityAttr();
1909 VisibilityAttr = MAI->getProtectedVisibilityAttr();
1914 OutStreamer->emitXCOFFSymbolLinkageWithVisibility(GVSym, LinkageAttr,
1921 cast<MCSectionXCOFF>(getObjFileLowering().getSectionForFunctionDescriptor(
1930uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
1935 if (Subtarget.
isAIXABI() && Subtarget.hasAltivec() &&
1936 TM.getAIXExtendedAltivecABI()) {
1938 for (
unsigned Reg = PPC::V20;
Reg <= PPC::V31; ++
Reg)
1939 if (
MRI.isPhysRegModified(Reg))
1941 return PPC::V31 - Reg + 1;
1946void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
1948 if (!
TM.getXCOFFTracebackTable())
1951 emitTracebackTable();
1959 (getNumberOfVRSaved() > 0)) {
1961 OutStreamer->switchSection(getObjFileLowering().getCompactUnwindSection());
1964 OutStreamer->emitLabel(EHInfoLabel);
1967 OutStreamer->emitInt32(0);
1969 const DataLayout &
DL = MMI->getModule()->getDataLayout();
1972 OutStreamer->emitValueToAlignment(
Align(PointerSize));
1974 OutStreamer->emitIntValue(0, PointerSize);
1975 OutStreamer->emitIntValue(0, PointerSize);
1976 OutStreamer->switchSection(MF->
getSection());
1980void PPCAIXAsmPrinter::emitTracebackTable() {
1984 OutStreamer->emitLabel(FuncEnd);
1986 OutStreamer->AddComment(
"Traceback table begin");
1988 OutStreamer->emitIntValueInHexWithPadding(0, 4 );
1993 auto EmitComment = [&]() {
1994 OutStreamer->AddComment(CommentOS.str());
1995 CommentString.
clear();
2000 OutStreamer->emitIntValueInHexWithPadding(
Value,
Size);
2004 CommentOS <<
"Version = " <<
Version;
2005 EmitCommentAndValue(Version, 1);
2015 CommentOS <<
"Language = "
2017 EmitCommentAndValue(LanguageIdentifier, 1);
2020 uint32_t FirstHalfOfMandatoryField = 0;
2031 for (
unsigned Reg = PPC::F0;
Reg <= PPC::F31; ++
Reg) {
2032 if (
MRI.isPhysRegUsed(Reg,
true)) {
2038#define GENBOOLCOMMENT(Prefix, V, Field) \
2039 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
2042#define GENVALUECOMMENT(PrefixAndName, V, Field) \
2043 CommentOS << (PrefixAndName) << " = " \
2044 << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
2045 (TracebackTable::Field##Shift))
2048 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsOutOfLineEpilogOrPrologue);
2051 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasTraceBackTableOffset);
2052 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsInternalProcedure);
2055 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, HasControlledStorage);
2059 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsFloatingPointPresent);
2062 IsFloatingPointOperationLogOrAbortEnabled);
2065 OutStreamer->emitIntValueInHexWithPadding(
2066 (FirstHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2074 if (FrameReg == (Subtarget->
isPPC64() ? PPC::X31 : PPC::R31))
2078 if (!MustSaveCRs.
empty())
2084 GENBOOLCOMMENT(
"", FirstHalfOfMandatoryField, IsInterruptHandler);
2085 GENBOOLCOMMENT(
", ", FirstHalfOfMandatoryField, IsFunctionNamePresent);
2089 OnConditionDirective);
2093 OutStreamer->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField & 0xff),
2097 uint32_t SecondHalfOfMandatoryField = 0;
2104 for (
unsigned Reg = PPC::F14;
Reg <= PPC::F31; ++
Reg) {
2105 if (
MRI.isPhysRegModified(Reg)) {
2106 FPRSaved = PPC::F31 -
Reg + 1;
2112 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, IsBackChainStored);
2114 GENVALUECOMMENT(
", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
2116 OutStreamer->emitIntValueInHexWithPadding(
2117 (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
2123 bool HasVectorInst =
false;
2124 for (
unsigned Reg = PPC::V0;
Reg <= PPC::V31; ++
Reg)
2125 if (
MRI.isPhysRegUsed(Reg,
true)) {
2127 HasVectorInst =
true;
2134 uint16_t NumOfVRSaved = getNumberOfVRSaved();
2135 bool ShouldEmitEHBlock =
2138 if (ShouldEmitEHBlock)
2144 unsigned GPRBegin = Subtarget->
isPPC64() ? PPC::X14 : PPC::R13;
2145 unsigned GPREnd = Subtarget->
isPPC64() ? PPC::X31 : PPC::R31;
2147 for (
unsigned Reg = GPRBegin;
Reg <= GPREnd; ++
Reg) {
2148 if (
MRI.isPhysRegModified(Reg)) {
2149 GPRSaved = GPREnd -
Reg + 1;
2157 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, HasExtensionTable);
2159 GENVALUECOMMENT(
", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
2161 OutStreamer->emitIntValueInHexWithPadding(
2162 (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
2166 SecondHalfOfMandatoryField |=
2170 NumberOfFixedParms);
2172 OutStreamer->emitIntValueInHexWithPadding(
2173 (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2181 SecondHalfOfMandatoryField |=
2186 NumberOfFloatingPointParms);
2187 GENBOOLCOMMENT(
", ", SecondHalfOfMandatoryField, HasParmsOnStack);
2189 OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
2195 if (NumberOfFixedParms || NumberOfFPParms) {
2201 ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
2208 CommentOS <<
"Parameter type = " << ParmsType.
get();
2211 OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
2212 sizeof(ParmsTypeValue));
2215 OutStreamer->AddComment(
"Function size");
2217 MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
2219 OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
2231 int16_t NameLength =
Name.size();
2232 CommentOS <<
"Function name len = "
2233 <<
static_cast<unsigned int>(NameLength);
2234 EmitCommentAndValue(NameLength, 2);
2235 OutStreamer->AddComment(
"Function Name");
2236 OutStreamer->emitBytes(
Name);
2241 OutStreamer->AddComment(
"AllocaUsed");
2242 OutStreamer->emitIntValueInHex(AllocReg,
sizeof(AllocReg));
2275 OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
2280 OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
2288 CommentOS <<
"Vector Parameter type = " << VecParmsType.
get();
2291 OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
2292 sizeof(VecParmTypeValue));
2294 CommentOS <<
"Padding";
2295 EmitCommentAndValue(0, 2);
2298 uint8_t ExtensionTableFlag = 0;
2300 if (ShouldEmitEHBlock)
2301 ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
2304 ExtensionTableFlag |= ExtendedTBTableFlag::TB_SSP_CANARY;
2306 CommentOS <<
"ExtensionTableFlag = "
2308 EmitCommentAndValue(ExtensionTableFlag,
sizeof(ExtensionTableFlag));
2311 if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
2312 auto &Ctx = OutStreamer->getContext();
2315 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym);
2317 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2318 ->getQualNameSymbol();
2324 OutStreamer->emitValueToAlignment(
Align(4));
2325 OutStreamer->AddComment(
"EHInfo Table");
2326 OutStreamer->emitValue(Exp,
DL.getPointerSize());
2328#undef GENBOOLCOMMENT
2329#undef GENVALUECOMMENT
2338 .
Case(
"llvm.used",
true)
2340 .
Case(
"llvm.compiler.used",
true)
2346 .
Cases(
"llvm.global_ctors",
"llvm.global_dtors",
true)
2351 if (
auto *GA = dyn_cast<GlobalAlias>(
C))
2352 return getAliasOffset(GA->getAliasee());
2353 if (
auto *CE = dyn_cast<ConstantExpr>(
C)) {
2355 const MCBinaryExpr *CBE = dyn_cast<MCBinaryExpr>(LowC);
2360 auto *
RHS = dyn_cast<MCConstantExpr>(CBE->
getRHS());
2363 return RHS->getValue();
2368void PPCAIXAsmPrinter::emitGlobalVariable(
const GlobalVariable *GV) {
2376 TOCDataGlobalVars.push_back(GV);
2380 emitGlobalVariableHelper(GV);
2383void PPCAIXAsmPrinter::emitGlobalVariableHelper(
const GlobalVariable *GV) {
2385 "Unhandled intrinsic global variable.");
2393 emitLinkage(GV, GVSym);
2397 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV,
TM);
2401 "not supported yet.");
2408 OutStreamer->getCommentOS() <<
'\n';
2413 getObjFileLowering().SectionForGlobal(GV, GVKind,
TM));
2416 OutStreamer->switchSection(Csect);
2429 OutStreamer->emitXCOFFLocalCommonSymbol(
2433 OutStreamer->emitCommonSymbol(GVSym,
Size, Alignment);
2440 emitLinkage(GV, EmittedInitSym);
2442 emitLinkage(GA, getSymbol(GA));
2444 emitAlignment(getGVAlignment(GV,
DL), GV);
2448 if (!
TM.getDataSections() || GV->hasSection())
2449 OutStreamer->emitLabel(EmittedInitSym);
2452 if (!GOAliasMap[GV].
size()) {
2453 emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());
2459 AliasMapTy AliasList;
2461 AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);
2464 emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer(),
2468void PPCAIXAsmPrinter::emitFunctionDescriptor() {
2470 const unsigned PointerSize =
DL.getPointerSizeInBits() == 64 ? 8 : 4;
2474 OutStreamer->switchSection(
2475 cast<MCSymbolXCOFF>(CurrentFnDescSym)->getRepresentedCsect());
2479 OutStreamer->emitLabel(getSymbol(Alias));
2486 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2487 ->getQualNameSymbol();
2491 OutStreamer->emitIntValue(0, PointerSize);
2493 OutStreamer->switchSection(Current.first, Current.second);
2496void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2499 if (!
TM.getFunctionSections())
2500 PPCAsmPrinter::emitFunctionEntryLabel();
2504 OutStreamer->emitLabel(
2505 getObjFileLowering().getFunctionEntryPointSymbol(Alias,
TM));
2508void PPCAIXAsmPrinter::emitPGORefs() {
2509 if (OutContext.hasXCOFFSection(
2512 MCSection *CntsSection = OutContext.getXCOFFSection(
2517 OutStreamer->switchSection(CntsSection);
2518 if (OutContext.hasXCOFFSection(
2521 OutStreamer->emitXCOFFRefDirective(
"__llvm_prf_data[RW]");
2522 if (OutContext.hasXCOFFSection(
2525 OutStreamer->emitXCOFFRefDirective(
"__llvm_prf_names[RO]");
2526 if (OutContext.hasXCOFFSection(
2529 OutStreamer->emitXCOFFRefDirective(
"__llvm_prf_vnds[RW]");
2533void PPCAIXAsmPrinter::emitEndOfAsmFile(
Module &M) {
2536 if (
M.empty() && TOCDataGlobalVars.empty())
2542 OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());
2547 for (
auto &
I : TOC) {
2552 if (
I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM) {
2556 Name += cast<MCSymbolXCOFF>(
I.first.first)->getSymbolTableName();
2558 TCEntry = cast<MCSectionXCOFF>(
2559 getObjFileLowering().getSectionForTOCEntry(S,
TM));
2561 TCEntry = cast<MCSectionXCOFF>(
2562 getObjFileLowering().getSectionForTOCEntry(
I.first.first,
TM));
2564 OutStreamer->switchSection(TCEntry);
2566 OutStreamer->emitLabel(
I.second);
2570 for (
const auto *GV : TOCDataGlobalVars)
2571 emitGlobalVariableHelper(GV);
2574bool PPCAIXAsmPrinter::doInitialization(
Module &M) {
2575 const bool Result = PPCAsmPrinter::doInitialization(M);
2577 auto setCsectAlignment = [
this](
const GlobalObject *GO) {
2579 if (GO->isDeclarationForLinker())
2582 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO,
TM);
2584 getObjFileLowering().SectionForGlobal(GO, GOKind,
TM));
2586 Align GOAlign = getGVAlignment(GO, GO->getParent()->getDataLayout());
2593 for (
const auto &
G :
M.globals()) {
2600 if (FormatIndicatorAndUniqueModId.empty()) {
2602 if (UniqueModuleId !=
"")
2606 FormatIndicatorAndUniqueModId =
"clang_" + UniqueModuleId.substr(1);
2612 FormatIndicatorAndUniqueModId =
2614 "_" + llvm::itostr(time(
nullptr));
2617 emitSpecialLLVMGlobal(&
G);
2621 setCsectAlignment(&
G);
2624 for (
const auto &
F : M)
2625 setCsectAlignment(&
F);
2628 for (
const auto &Alias :
M.aliases()) {
2632 "alias without a base object is not yet supported on AIX");
2633 GOAliasMap[
Base].push_back(&Alias);
2640 switch (
MI->getOpcode()) {
2647 if (
MI->getNumOperands() < 5)
2653 MCSymbol *TempSym = OutContext.createNamedTempSymbol();
2654 OutStreamer->emitLabel(TempSym);
2655 OutStreamer->emitXCOFFExceptDirective(CurrentFnSym, TempSym,
2657 Subtarget->
isPPC64() ?
MI->getMF()->getInstructionCount() * 8 :
2658 MI->getMF()->getInstructionCount() * 4,
2659 MMI->hasDebugInfo());
2662 case PPC::GETtlsADDR64AIX:
2663 case PPC::GETtlsADDR32AIX: {
2667 ExtSymSDNodeSymbols.insert(TlsGetAddr);
2677 cast<MCSymbolXCOFF>(OutContext.getOrCreateSymbol(MO.
getSymbolName()));
2678 ExtSymSDNodeSymbols.insert(S);
2684 case PPC::BL8_NOP_TLS:
2691 case PPC::TAILBCTR8:
2692 if (
MI->getOperand(0).isSymbol())
2705 MCInstBuilder(PPC::ORI).addReg(PPC::R0).addReg(PPC::R0).addImm(0));
2708 return PPCAsmPrinter::emitInstruction(
MI);
2711bool PPCAIXAsmPrinter::doFinalization(
Module &M) {
2713 if (!MAI->usesDwarfFileAndLocDirectives() && MMI->hasDebugInfo())
2714 OutStreamer->doFinalizationAtSectionEnd(
2715 OutStreamer->getContext().getObjectFileInfo()->getTextSection());
2717 for (
MCSymbol *Sym : ExtSymSDNodeSymbols)
2718 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Extern);
2719 return PPCAsmPrinter::doFinalization(M);
2723 if (P < 0 || P > 65535)
2730 return 20 + (
P - 20) * 16;
2733 return 1004 + (
P - 81);
2736 return 2047 + (
P - 1124) * 33878;
2738 return 2147482625u + (
P - 64512);
2757 std::string PrioritySuffix;
2761 return PrioritySuffix;
2764void PPCAIXAsmPrinter::emitXXStructorList(
const DataLayout &
DL,
2765 const Constant *List,
bool IsCtor) {
2767 preprocessXXStructorList(
DL, List, Structors);
2768 if (Structors.
empty())
2772 for (Structor &S : Structors) {
2773 if (
const ConstantExpr *CE = dyn_cast<ConstantExpr>(S.Func))
2774 S.Func =
CE->getOperand(0);
2782 cast<Function>(S.Func));
2786void PPCAIXAsmPrinter::emitTTypeReference(
const GlobalValue *GV,
2787 unsigned Encoding) {
2790 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym);
2792 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2793 ->getQualNameSymbol();
2794 auto &Ctx = OutStreamer->getContext();
2798 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
2800 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
2807 std::unique_ptr<MCStreamer> &&Streamer) {
2809 return new PPCAIXAsmPrinter(tm, std::move(Streamer));
2811 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
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 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.
return ToRemove size() > 0
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 AsmPrinter * createPPCAsmPrinterPass(TargetMachine &tm, std::unique_ptr< MCStreamer > &&Streamer)
static std::string convertToSinitPriority(int Priority)
#define GENVALUECOMMENT(PrefixAndName, V, Field)
static MCSymbol * createMCSymbolForTlsGetAddr(MCContext &Ctx)
This helper function creates the TlsGetAddr MCSymbol for AIX.
static unsigned mapToSinitPriority(int P)
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)
const char LLVMTargetMachineRef TM
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 defines the SmallPtrSet class.
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.
A parsed version of the target data layout string in and methods for querying it.
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.
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 hasDLLExportStorageClass() const
bool isDeclarationForLinker() const
Module * getParent()
Get the module that this global value is contained inside of...
@ DefaultVisibility
The GV is visible.
@ HiddenVisibility
The GV is hidden.
@ ProtectedVisibility
The GV is protected.
bool hasCommonLinkage() const
bool hasAppendingLinkage() const
@ 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.
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, const char *BeginSymName=nullptr, 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.
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 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.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
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
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 isVRRegister(unsigned Reg)
static bool isVFRegister(unsigned Reg)
static const PPCMCExpr * createLo(const MCExpr *Expr, MCContext &Ctx)
static const PPCMCExpr * createHa(const MCExpr *Expr, MCContext &Ctx)
static const char * stripRegisterPrefix(const char *RegName)
stripRegisterPrefix - This method strips the character prefix from a register name so that only the n...
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
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.
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
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
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 startswith(StringRef Prefix) const
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...
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.
@ MO_TLSGDM_FLAG
MO_TLSGDM_FLAG - If this bit is set the symbol reference is relative to the region handle of TLS Gene...
@ 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.
Predicate InvertPredicate(Predicate Opcode)
Invert the specified predicate. != -> ==, < -> >=.
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
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.
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)
static 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.
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()
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...
void LowerPPCMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, AsmPrinter &AP)
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()
std::pair< MCSection *, const MCExpr * > MCSectionSubPair
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.
This struct is a compact representation of a valid (non-zero power of two) alignment.
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...
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