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;
2103 for (
unsigned Reg = PPC::F14;
Reg <= PPC::F31; ++
Reg) {
2104 if (
MRI.isPhysRegModified(Reg)) {
2105 FPRSaved = PPC::F31 -
Reg + 1;
2111 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, IsBackChainStored);
2113 GENVALUECOMMENT(
", NumOfFPRsSaved", SecondHalfOfMandatoryField, FPRSaved);
2115 OutStreamer->emitIntValueInHexWithPadding(
2116 (SecondHalfOfMandatoryField & 0xff000000) >> 24, 1);
2122 bool HasVectorInst =
false;
2123 for (
unsigned Reg = PPC::V0;
Reg <= PPC::V31; ++
Reg)
2124 if (
MRI.isPhysRegUsed(Reg,
true)) {
2126 HasVectorInst =
true;
2133 uint16_t NumOfVRSaved = getNumberOfVRSaved();
2134 bool ShouldEmitEHBlock =
2137 if (ShouldEmitEHBlock)
2143 unsigned GPRBegin = Subtarget->
isPPC64() ? PPC::X14 : PPC::R13;
2144 unsigned GPREnd = Subtarget->
isPPC64() ? PPC::X31 : PPC::R31;
2146 for (
unsigned Reg = GPRBegin;
Reg <= GPREnd; ++
Reg) {
2147 if (
MRI.isPhysRegModified(Reg)) {
2148 GPRSaved = GPREnd -
Reg + 1;
2156 GENBOOLCOMMENT(
"", SecondHalfOfMandatoryField, HasExtensionTable);
2158 GENVALUECOMMENT(
", NumOfGPRsSaved", SecondHalfOfMandatoryField, GPRSaved);
2160 OutStreamer->emitIntValueInHexWithPadding(
2161 (SecondHalfOfMandatoryField & 0x00ff0000) >> 16, 1);
2165 SecondHalfOfMandatoryField |=
2169 NumberOfFixedParms);
2171 OutStreamer->emitIntValueInHexWithPadding(
2172 (SecondHalfOfMandatoryField & 0x0000ff00) >> 8, 1);
2180 SecondHalfOfMandatoryField |=
2185 NumberOfFloatingPointParms);
2186 GENBOOLCOMMENT(
", ", SecondHalfOfMandatoryField, HasParmsOnStack);
2188 OutStreamer->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField & 0xff,
2194 if (NumberOfFixedParms || NumberOfFPParms) {
2200 ParmsTypeValue, NumberOfFixedParms, NumberOfFPParms,
2207 CommentOS <<
"Parameter type = " << ParmsType.
get();
2210 OutStreamer->emitIntValueInHexWithPadding(ParmsTypeValue,
2211 sizeof(ParmsTypeValue));
2214 OutStreamer->AddComment(
"Function size");
2216 MCSymbol *FuncSectSym = getObjFileLowering().getFunctionEntryPointSymbol(
2218 OutStreamer->emitAbsoluteSymbolDiff(FuncEnd, FuncSectSym, 4);
2230 int16_t NameLength =
Name.size();
2231 CommentOS <<
"Function name len = "
2232 <<
static_cast<unsigned int>(NameLength);
2233 EmitCommentAndValue(NameLength, 2);
2234 OutStreamer->AddComment(
"Function Name");
2235 OutStreamer->emitBytes(
Name);
2240 OutStreamer->AddComment(
"AllocaUsed");
2241 OutStreamer->emitIntValueInHex(AllocReg,
sizeof(AllocReg));
2274 OutStreamer->emitIntValueInHexWithPadding((VRData & 0xff00) >> 8, 1);
2279 OutStreamer->emitIntValueInHexWithPadding(VRData & 0x00ff, 1);
2287 CommentOS <<
"Vector Parameter type = " << VecParmsType.
get();
2290 OutStreamer->emitIntValueInHexWithPadding(VecParmTypeValue,
2291 sizeof(VecParmTypeValue));
2293 CommentOS <<
"Padding";
2294 EmitCommentAndValue(0, 2);
2297 uint8_t ExtensionTableFlag = 0;
2299 if (ShouldEmitEHBlock)
2300 ExtensionTableFlag |= ExtendedTBTableFlag::TB_EH_INFO;
2303 ExtensionTableFlag |= ExtendedTBTableFlag::TB_SSP_CANARY;
2305 CommentOS <<
"ExtensionTableFlag = "
2307 EmitCommentAndValue(ExtensionTableFlag,
sizeof(ExtensionTableFlag));
2310 if (ExtensionTableFlag & ExtendedTBTableFlag::TB_EH_INFO) {
2311 auto &Ctx = OutStreamer->getContext();
2314 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(EHInfoSym);
2316 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2317 ->getQualNameSymbol();
2323 OutStreamer->emitValueToAlignment(
Align(4));
2324 OutStreamer->AddComment(
"EHInfo Table");
2325 OutStreamer->emitValue(Exp,
DL.getPointerSize());
2327#undef GENBOOLCOMMENT
2328#undef GENVALUECOMMENT
2337 .
Case(
"llvm.used",
true)
2339 .
Case(
"llvm.compiler.used",
true)
2345 .
Cases(
"llvm.global_ctors",
"llvm.global_dtors",
true)
2350 if (
auto *GA = dyn_cast<GlobalAlias>(
C))
2351 return getAliasOffset(GA->getAliasee());
2352 if (
auto *CE = dyn_cast<ConstantExpr>(
C)) {
2354 const MCBinaryExpr *CBE = dyn_cast<MCBinaryExpr>(LowC);
2359 auto *
RHS = dyn_cast<MCConstantExpr>(CBE->
getRHS());
2362 return RHS->getValue();
2367void PPCAIXAsmPrinter::emitGlobalVariable(
const GlobalVariable *GV) {
2375 TOCDataGlobalVars.push_back(GV);
2379 emitGlobalVariableHelper(GV);
2382void PPCAIXAsmPrinter::emitGlobalVariableHelper(
const GlobalVariable *GV) {
2384 "Unhandled intrinsic global variable.");
2392 emitLinkage(GV, GVSym);
2396 SectionKind GVKind = getObjFileLowering().getKindForGlobal(GV,
TM);
2400 "not supported yet.");
2407 OutStreamer->getCommentOS() <<
'\n';
2412 getObjFileLowering().SectionForGlobal(GV, GVKind,
TM));
2415 OutStreamer->switchSection(Csect);
2428 OutStreamer->emitXCOFFLocalCommonSymbol(
2432 OutStreamer->emitCommonSymbol(GVSym,
Size, Alignment);
2439 emitLinkage(GV, EmittedInitSym);
2441 emitLinkage(GA, getSymbol(GA));
2443 emitAlignment(getGVAlignment(GV,
DL), GV);
2447 if (!
TM.getDataSections() || GV->hasSection())
2448 OutStreamer->emitLabel(EmittedInitSym);
2451 if (!GOAliasMap[GV].
size()) {
2452 emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());
2458 AliasMapTy AliasList;
2460 AliasList[getAliasOffset(GA->getAliasee())].push_back(GA);
2463 emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer(),
2467void PPCAIXAsmPrinter::emitFunctionDescriptor() {
2469 const unsigned PointerSize =
DL.getPointerSizeInBits() == 64 ? 8 : 4;
2473 OutStreamer->switchSection(
2474 cast<MCSymbolXCOFF>(CurrentFnDescSym)->getRepresentedCsect());
2478 OutStreamer->emitLabel(getSymbol(Alias));
2485 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2486 ->getQualNameSymbol();
2490 OutStreamer->emitIntValue(0, PointerSize);
2492 OutStreamer->switchSection(Current.first, Current.second);
2495void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2498 if (!
TM.getFunctionSections())
2499 PPCAsmPrinter::emitFunctionEntryLabel();
2503 OutStreamer->emitLabel(
2504 getObjFileLowering().getFunctionEntryPointSymbol(Alias,
TM));
2507void PPCAIXAsmPrinter::emitPGORefs() {
2508 if (OutContext.hasXCOFFSection(
2511 MCSection *CntsSection = OutContext.getXCOFFSection(
2516 OutStreamer->switchSection(CntsSection);
2517 if (OutContext.hasXCOFFSection(
2520 OutStreamer->emitXCOFFRefDirective(
"__llvm_prf_data[RW]");
2521 if (OutContext.hasXCOFFSection(
2524 OutStreamer->emitXCOFFRefDirective(
"__llvm_prf_names[RO]");
2525 if (OutContext.hasXCOFFSection(
2528 OutStreamer->emitXCOFFRefDirective(
"__llvm_prf_vnds[RW]");
2532void PPCAIXAsmPrinter::emitEndOfAsmFile(
Module &M) {
2535 if (
M.empty() && TOCDataGlobalVars.empty())
2541 OutStreamer->switchSection(getObjFileLowering().getTOCBaseSection());
2546 for (
auto &
I : TOC) {
2551 if (
I.first.second == MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM) {
2555 Name += cast<MCSymbolXCOFF>(
I.first.first)->getSymbolTableName();
2557 TCEntry = cast<MCSectionXCOFF>(
2558 getObjFileLowering().getSectionForTOCEntry(S,
TM));
2560 TCEntry = cast<MCSectionXCOFF>(
2561 getObjFileLowering().getSectionForTOCEntry(
I.first.first,
TM));
2563 OutStreamer->switchSection(TCEntry);
2565 OutStreamer->emitLabel(
I.second);
2569 for (
const auto *GV : TOCDataGlobalVars)
2570 emitGlobalVariableHelper(GV);
2573bool PPCAIXAsmPrinter::doInitialization(
Module &M) {
2574 const bool Result = PPCAsmPrinter::doInitialization(M);
2576 auto setCsectAlignment = [
this](
const GlobalObject *GO) {
2578 if (GO->isDeclarationForLinker())
2581 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO,
TM);
2583 getObjFileLowering().SectionForGlobal(GO, GOKind,
TM));
2585 Align GOAlign = getGVAlignment(GO, GO->getParent()->getDataLayout());
2592 for (
const auto &
G :
M.globals()) {
2599 if (FormatIndicatorAndUniqueModId.empty()) {
2601 if (UniqueModuleId !=
"")
2605 FormatIndicatorAndUniqueModId =
"clang_" + UniqueModuleId.substr(1);
2611 FormatIndicatorAndUniqueModId =
2613 "_" + llvm::itostr(time(
nullptr));
2616 emitSpecialLLVMGlobal(&
G);
2620 setCsectAlignment(&
G);
2623 for (
const auto &
F : M)
2624 setCsectAlignment(&
F);
2627 for (
const auto &Alias :
M.aliases()) {
2631 "alias without a base object is not yet supported on AIX");
2632 GOAliasMap[
Base].push_back(&Alias);
2639 switch (
MI->getOpcode()) {
2646 if (
MI->getNumOperands() < 5)
2652 MCSymbol *TempSym = OutContext.createNamedTempSymbol();
2653 OutStreamer->emitLabel(TempSym);
2654 OutStreamer->emitXCOFFExceptDirective(CurrentFnSym, TempSym,
2656 Subtarget->
isPPC64() ?
MI->getMF()->getInstructionCount() * 8 :
2657 MI->getMF()->getInstructionCount() * 4,
2658 MMI->hasDebugInfo());
2661 case PPC::GETtlsADDR64AIX:
2662 case PPC::GETtlsADDR32AIX: {
2666 ExtSymSDNodeSymbols.insert(TlsGetAddr);
2676 cast<MCSymbolXCOFF>(OutContext.getOrCreateSymbol(MO.
getSymbolName()));
2677 ExtSymSDNodeSymbols.insert(S);
2683 case PPC::BL8_NOP_TLS:
2690 case PPC::TAILBCTR8:
2691 if (
MI->getOperand(0).isSymbol())
2704 MCInstBuilder(PPC::ORI).addReg(PPC::R0).addReg(PPC::R0).addImm(0));
2707 return PPCAsmPrinter::emitInstruction(
MI);
2710bool PPCAIXAsmPrinter::doFinalization(
Module &M) {
2712 if (!MAI->usesDwarfFileAndLocDirectives() && MMI->hasDebugInfo())
2713 OutStreamer->doFinalizationAtSectionEnd(
2714 OutStreamer->getContext().getObjectFileInfo()->getTextSection());
2716 for (
MCSymbol *Sym : ExtSymSDNodeSymbols)
2717 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Extern);
2718 return PPCAsmPrinter::doFinalization(M);
2722 if (P < 0 || P > 65535)
2729 return 20 + (
P - 20) * 16;
2732 return 1004 + (
P - 81);
2735 return 2047 + (
P - 1124) * 33878;
2737 return 2147482625u + (
P - 64512);
2756 std::string PrioritySuffix;
2760 return PrioritySuffix;
2763void PPCAIXAsmPrinter::emitXXStructorList(
const DataLayout &
DL,
2764 const Constant *List,
bool IsCtor) {
2766 preprocessXXStructorList(
DL, List, Structors);
2767 if (Structors.
empty())
2771 for (Structor &S : Structors) {
2772 if (
const ConstantExpr *CE = dyn_cast<ConstantExpr>(S.Func))
2773 S.Func =
CE->getOperand(0);
2781 cast<Function>(S.Func));
2785void PPCAIXAsmPrinter::emitTTypeReference(
const GlobalValue *GV,
2786 unsigned Encoding) {
2789 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(TypeInfoSym);
2791 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
2792 ->getQualNameSymbol();
2793 auto &Ctx = OutStreamer->getContext();
2797 OutStreamer->emitValue(Exp, GetSizeOfEncodedValue(Encoding));
2799 OutStreamer->emitIntValue(0, GetSizeOfEncodedValue(Encoding));
2806 std::unique_ptr<MCStreamer> &&Streamer) {
2808 return new PPCAIXAsmPrinter(tm, std::move(Streamer));
2810 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This header is deprecated in favour of llvm/TargetParser/Triple.h.
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.
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.
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