70#define DEBUG_TYPE "asm-printer"
78 bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags =
false;
81 AArch64AsmPrinter(
TargetMachine &
TM, std::unique_ptr<MCStreamer> Streamer)
82 :
AsmPrinter(
TM, std::move(Streamer)), MCInstLowering(OutContext, *
this),
98 const MCSymbol *BranchLabel)
const override;
117 void LowerPATCHABLE_EVENT_CALL(
const MachineInstr &
MI,
bool Typed);
119 typedef std::tuple<unsigned, bool, uint32_t, bool, uint64_t>
120 HwasanMemaccessTuple;
121 std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
124 void emitHwasanMemaccessSymbols(
Module &M);
130 bool emitPseudoExpansionLowering(
MCStreamer &OutStreamer,
135 void emitFunctionHeaderComment()
override;
148 if (STI->isTargetCOFF()) {
200 using MInstToMCSymbol = std::map<const MachineInstr *, MCSymbol *>;
202 MInstToMCSymbol LOHInstToLabel;
205 return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags;
220void AArch64AsmPrinter::emitStartOfAsmFile(
Module &M) {
223 if (
TT.isOSBinFormatCOFF()) {
226 OutStreamer->beginCOFFSymbolDef(S);
229 OutStreamer->endCOFFSymbolDef();
230 int64_t Feat00Value = 0;
232 if (
M.getModuleFlag(
"cfguard")) {
234 Feat00Value |= COFF::Feat00Flags::GuardCF;
237 if (
M.getModuleFlag(
"ehcontguard")) {
239 Feat00Value |= COFF::Feat00Flags::GuardEHCont;
242 if (
M.getModuleFlag(
"ms-kernel")) {
244 Feat00Value |= COFF::Feat00Flags::Kernel;
248 OutStreamer->emitAssignment(
252 if (!
TT.isOSBinFormatELF())
257 if (
const auto *BTE = mdconst::extract_or_null<ConstantInt>(
258 M.getModuleFlag(
"branch-target-enforcement")))
259 if (BTE->getZExtValue())
262 if (
const auto *GCS = mdconst::extract_or_null<ConstantInt>(
263 M.getModuleFlag(
"guarded-control-stack")))
264 if (GCS->getZExtValue())
267 if (
const auto *Sign = mdconst::extract_or_null<ConstantInt>(
268 M.getModuleFlag(
"sign-return-address")))
269 if (Sign->getZExtValue())
273 if (
const auto *PAP = mdconst::extract_or_null<ConstantInt>(
274 M.getModuleFlag(
"aarch64-elf-pauthabi-platform")))
275 PAuthABIPlatform = PAP->getZExtValue();
277 if (
const auto *PAV = mdconst::extract_or_null<ConstantInt>(
278 M.getModuleFlag(
"aarch64-elf-pauthabi-version")))
279 PAuthABIVersion = PAV->getZExtValue();
287void AArch64AsmPrinter::emitFunctionHeaderComment() {
290 if (OutlinerString != std::nullopt)
291 OutStreamer->getCommentOS() <<
' ' << OutlinerString;
294void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr &
MI)
297 if (
F.hasFnAttribute(
"patchable-function-entry")) {
299 if (
F.getFnAttribute(
"patchable-function-entry")
301 .getAsInteger(10, Num))
307 emitSled(
MI, SledKind::FUNCTION_ENTER);
310void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr &
MI) {
311 emitSled(
MI, SledKind::FUNCTION_EXIT);
314void AArch64AsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr &
MI) {
315 emitSled(
MI, SledKind::TAIL_CALL);
318void AArch64AsmPrinter::emitSled(
const MachineInstr &
MI, SledKind Kind) {
319 static const int8_t NoopsInSledCount = 7;
340 OutStreamer->emitCodeAlignment(
Align(4), &getSubtargetInfo());
341 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
342 OutStreamer->emitLabel(CurSled);
343 auto Target = OutContext.createTempSymbol();
348 EmitToStreamer(*OutStreamer,
MCInstBuilder(AArch64::B).addImm(8));
350 for (int8_t
I = 0;
I < NoopsInSledCount;
I++)
351 EmitToStreamer(*OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
353 OutStreamer->emitLabel(
Target);
354 recordSled(CurSled,
MI, Kind, 2);
372void AArch64AsmPrinter::LowerPATCHABLE_EVENT_CALL(
const MachineInstr &
MI,
374 auto &
O = *OutStreamer;
375 MCSymbol *CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
376 O.emitLabel(CurSled);
387 bool MachO =
TM.getTargetTriple().isOSBinFormatMachO();
389 OutContext.getOrCreateSymbol(
390 Twine(MachO ?
"_" :
"") +
391 (Typed ?
"__xray_TypedEvent" :
"__xray_CustomEvent")),
394 O.AddComment(
"Begin XRay typed event");
406 EmitToStreamer(O, MovX0Op0);
407 EmitToStreamer(O, MovX1Op1);
410 .addReg(AArch64::XZR)
411 .addReg(
MI.getOperand(2).getReg())
418 O.AddComment(
"End XRay typed event");
426 recordSled(CurSled,
MI, SledKind::TYPED_EVENT, 2);
428 O.AddComment(
"Begin XRay custom event");
436 EmitToStreamer(O, MovX0Op0);
437 EmitToStreamer(O, MovX1Op1);
439 O.AddComment(
"End XRay custom event");
447 recordSled(CurSled,
MI, SledKind::CUSTOM_EVENT, 2);
453 assert(std::next(
MI.getIterator())->isCall() &&
454 "KCFI_CHECK not followed by a call instruction");
455 assert(std::next(
MI.getIterator())->getOperand(0).getReg() == AddrReg &&
456 "KCFI_CHECK call target doesn't match call operand");
460 unsigned ScratchRegs[] = {AArch64::W16, AArch64::W17};
461 if (AddrReg == AArch64::XZR) {
467 .addReg(AArch64::XZR)
468 .addReg(AArch64::XZR)
475 for (
auto &Reg : ScratchRegs) {
481 assert(ScratchRegs[0] != AddrReg && ScratchRegs[1] != AddrReg &&
482 "Invalid scratch registers for KCFI_CHECK");
486 int64_t PrefixNops = 0;
489 .getFnAttribute(
"patchable-function-prefix")
491 .getAsInteger(10, PrefixNops);
495 .addReg(ScratchRegs[0])
497 .addImm(-(PrefixNops * 4 + 4)));
501 const int64_t
Type =
MI.getOperand(1).getImm();
503 .addReg(ScratchRegs[1])
504 .addReg(ScratchRegs[1])
505 .addImm(
Type & 0xFFFF)
508 .addReg(ScratchRegs[1])
509 .addReg(ScratchRegs[1])
510 .addImm((
Type >> 16) & 0xFFFF)
515 .addReg(AArch64::WZR)
516 .addReg(ScratchRegs[0])
517 .addReg(ScratchRegs[1])
521 EmitToStreamer(*OutStreamer,
531 unsigned TypeIndex = ScratchRegs[1] - AArch64::W0;
535 AddrIndex = AddrReg - AArch64::X0;
545 assert(AddrIndex < 31 && TypeIndex < 31);
547 unsigned ESR = 0x8000 | ((TypeIndex & 31) << 5) | (AddrIndex & 31);
548 EmitToStreamer(*OutStreamer,
MCInstBuilder(AArch64::BRK).addImm(ESR));
549 OutStreamer->emitLabel(
Pass);
552void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
555 ((
MI.getOpcode() == AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES) ||
557 AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW));
558 uint32_t AccessInfo =
MI.getOperand(1).getImm();
560 ((
MI.getOpcode() == AArch64::HWASAN_CHECK_MEMACCESS_FIXEDSHADOW) ||
562 AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW));
563 uint64_t FixedShadowOffset = IsFixedShadow ?
MI.getOperand(2).getImm() : 0;
565 MCSymbol *&
Sym = HwasanMemaccessSymbols[HwasanMemaccessTuple(
566 Reg, IsShort, AccessInfo, IsFixedShadow, FixedShadowOffset)];
569 if (!
TM.getTargetTriple().isOSBinFormatELF())
572 std::string SymName =
"__hwasan_check_x" + utostr(Reg - AArch64::X0) +
"_" +
575 SymName +=
"_fixed_" + utostr(FixedShadowOffset);
577 SymName +=
"_short_v2";
578 Sym = OutContext.getOrCreateSymbol(SymName);
581 EmitToStreamer(*OutStreamer,
586void AArch64AsmPrinter::emitHwasanMemaccessSymbols(
Module &M) {
587 if (HwasanMemaccessSymbols.empty())
592 std::unique_ptr<MCSubtargetInfo> STI(
593 TM.getTarget().createMCSubtargetInfo(
TT.str(),
"",
""));
594 assert(STI &&
"Unable to create subtarget info");
597 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch");
599 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
606 for (
auto &
P : HwasanMemaccessSymbols) {
607 unsigned Reg = std::get<0>(
P.first);
608 bool IsShort = std::get<1>(
P.first);
609 uint32_t AccessInfo = std::get<2>(
P.first);
610 bool IsFixedShadow = std::get<3>(
P.first);
611 uint64_t FixedShadowOffset = std::get<4>(
P.first);
613 IsShort ? HwasanTagMismatchV2Ref : HwasanTagMismatchV1Ref;
616 bool HasMatchAllTag =
618 uint8_t MatchAllTag =
625 OutStreamer->switchSection(OutContext.getELFSection(
633 OutStreamer->emitLabel(
Sym);
649 .
addImm(FixedShadowOffset >> 32)
652 OutStreamer->emitInstruction(
MCInstBuilder(AArch64::LDRBBroX)
660 OutStreamer->emitInstruction(
663 .
addReg(IsShort ? AArch64::X20 : AArch64::X9)
670 OutStreamer->emitInstruction(
677 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
678 OutStreamer->emitInstruction(
684 MCSymbol *ReturnSym = OutContext.createTempSymbol();
685 OutStreamer->emitLabel(ReturnSym);
686 OutStreamer->emitInstruction(
688 OutStreamer->emitLabel(HandleMismatchOrPartialSym);
690 if (HasMatchAllTag) {
703 OutStreamer->emitInstruction(
717 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
718 OutStreamer->emitInstruction(
724 OutStreamer->emitInstruction(
743 OutStreamer->emitInstruction(
749 OutStreamer->emitInstruction(
760 OutStreamer->emitInstruction(
767 OutStreamer->emitInstruction(
773 OutStreamer->emitLabel(HandleMismatchSym);
790 if (Reg != AArch64::X0)
797 OutStreamer->emitInstruction(
808 OutStreamer->emitInstruction(
814 OutStreamer->emitInstruction(
818 HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_PAGE,
821 OutStreamer->emitInstruction(
826 HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_LO12,
829 OutStreamer->emitInstruction(
835void AArch64AsmPrinter::emitEndOfAsmFile(
Module &M) {
836 emitHwasanMemaccessSymbols(M);
839 if (
TT.isOSBinFormatMachO()) {
849 FM.serializeToFaultMapSection();
853void AArch64AsmPrinter::emitLOHs() {
856 for (
const auto &
D : AArch64FI->getLOHContainer()) {
858 MInstToMCSymbol::iterator LabelIt = LOHInstToLabel.find(
MI);
859 assert(LabelIt != LOHInstToLabel.end() &&
860 "Label hasn't been inserted for LOH related instruction");
863 OutStreamer->emitLOHDirective(
D.getKind(), MCArgs);
868void AArch64AsmPrinter::emitFunctionBodyEnd() {
869 if (!AArch64FI->getLOHRelated().empty())
874MCSymbol *AArch64AsmPrinter::GetCPISymbol(
unsigned CPID)
const {
878 if (!getDataLayout().getLinkerPrivateGlobalPrefix().empty())
879 return OutContext.getOrCreateSymbol(
880 Twine(getDataLayout().getLinkerPrivateGlobalPrefix()) +
"CPI" +
881 Twine(getFunctionNumber()) +
"_" +
Twine(CPID));
886void AArch64AsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNum,
904 PrintSymbolOperand(MO, O);
915bool AArch64AsmPrinter::printAsmMRegister(
const MachineOperand &MO,
char Mode,
939bool AArch64AsmPrinter::printAsmRegInClass(
const MachineOperand &MO,
942 assert(MO.
isReg() &&
"Should only get here with a register!");
952bool AArch64AsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNum,
961 if (ExtraCode && ExtraCode[0]) {
962 if (ExtraCode[1] != 0)
965 switch (ExtraCode[0]) {
973 unsigned Reg = ExtraCode[0] ==
'w' ? AArch64::WZR : AArch64::XZR;
987 switch (ExtraCode[0]) {
989 RC = &AArch64::FPR8RegClass;
992 RC = &AArch64::FPR16RegClass;
995 RC = &AArch64::FPR32RegClass;
998 RC = &AArch64::FPR64RegClass;
1001 RC = &AArch64::FPR128RegClass;
1004 RC = &AArch64::ZPRRegClass;
1009 return printAsmRegInClass(MO, RC, AArch64::NoRegAltName, O);
1022 if (AArch64::GPR32allRegClass.
contains(Reg) ||
1023 AArch64::GPR64allRegClass.
contains(Reg))
1027 if (AArch64::GPR64x8ClassRegClass.
contains(Reg))
1030 unsigned AltName = AArch64::NoRegAltName;
1032 if (AArch64::ZPRRegClass.
contains(Reg)) {
1033 RegClass = &AArch64::ZPRRegClass;
1034 }
else if (AArch64::PPRRegClass.
contains(Reg)) {
1035 RegClass = &AArch64::PPRRegClass;
1036 }
else if (AArch64::PNRRegClass.
contains(Reg)) {
1037 RegClass = &AArch64::PNRRegClass;
1039 RegClass = &AArch64::FPR128RegClass;
1040 AltName = AArch64::vreg;
1044 return printAsmRegInClass(MO, RegClass, AltName, O);
1051bool AArch64AsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
1053 const char *ExtraCode,
1055 if (ExtraCode && ExtraCode[0] && ExtraCode[0] !=
'a')
1059 assert(MO.
isReg() &&
"unexpected inline asm memory operand");
1064void AArch64AsmPrinter::PrintDebugValueComment(
const MachineInstr *
MI,
1066 unsigned NOps =
MI->getNumOperands();
1068 OS <<
'\t' << MAI->getCommentString() <<
"DEBUG_VALUE: ";
1070 OS <<
MI->getDebugVariable()->getName();
1073 assert(
MI->isIndirectDebugValue());
1075 for (
unsigned I = 0, E = std::distance(
MI->debug_operands().begin(),
1076 MI->debug_operands().end());
1087void AArch64AsmPrinter::emitJumpTableInfo() {
1092 if (
JT.empty())
return;
1096 OutStreamer->switchSection(ReadOnlySec);
1099 for (
unsigned JTI = 0, e =
JT.size(); JTI !=
e; ++JTI) {
1100 const std::vector<MachineBasicBlock*> &JTBBs =
JT[JTI].MBBs;
1103 if (JTBBs.empty())
continue;
1105 unsigned Size = AFI->getJumpTableEntrySize(JTI);
1107 OutStreamer->emitLabel(GetJTISymbol(JTI));
1109 const MCSymbol *BaseSym = AArch64FI->getJumpTableEntryPCRelSymbol(JTI);
1112 for (
auto *JTBB : JTBBs) {
1132AArch64AsmPrinter::getCodeViewJumpTableInfo(
int JTI,
1134 const MCSymbol *BranchLabel)
const {
1136 const auto Base = AArch64FI->getJumpTableEntryPCRelSymbol(JTI);
1138 switch (AFI->getJumpTableEntrySize(JTI)) {
1140 EntrySize = codeview::JumpTableEntrySize::UInt8ShiftLeft;
1143 EntrySize = codeview::JumpTableEntrySize::UInt16ShiftLeft;
1146 EntrySize = codeview::JumpTableEntrySize::Int32;
1151 return std::make_tuple(
Base, 0, BranchLabel, EntrySize);
1154void AArch64AsmPrinter::emitFunctionEntryLabel() {
1156 MF->getFunction().getCallingConv() ==
1164 if (
TM.getTargetTriple().isWindowsArm64EC() &&
1165 !MF->getFunction().hasLocalLinkage()) {
1170 MF->getFunction().getMetadata(
"arm64ec_unmangled_name")) {
1174 MF->getFunction().getMetadata(
"arm64ec_ecmangled_name")) {
1176 cast<MDString>(Unmangled->getOperand(0))->getString();
1178 MMI->getContext().getOrCreateSymbol(UnmangledStr);
1180 cast<MDString>(ECMangled->getOperand(0))->getString();
1182 MMI->getContext().getOrCreateSymbol(ECMangledStr);
1184 OutStreamer->emitAssignment(
1187 MMI->getContext()));
1189 OutStreamer->emitAssignment(
1192 MMI->getContext()));
1196 cast<MDString>(Unmangled->getOperand(0))->getString();
1198 MMI->getContext().getOrCreateSymbol(UnmangledStr);
1200 OutStreamer->emitAssignment(
1203 MMI->getContext()));
1223 Register DestReg =
MI.getOperand(0).getReg();
1224 Register ScratchReg =
MI.getOperand(1).getReg();
1226 STI->getRegisterInfo()->getSubReg(ScratchReg, AArch64::sub_32);
1227 Register TableReg =
MI.getOperand(2).getReg();
1228 Register EntryReg =
MI.getOperand(3).getReg();
1229 int JTIdx =
MI.getOperand(4).getIndex();
1230 int Size = AArch64FI->getJumpTableEntrySize(JTIdx);
1240 Label = MF->getContext().createTempSymbol();
1241 AArch64FI->setJumpTableEntryInfo(JTIdx,
Size, Label);
1248 .addExpr(LabelExpr));
1253 case 1: LdrOpcode = AArch64::LDRBBroX;
break;
1254 case 2: LdrOpcode = AArch64::LDRHHroX;
break;
1255 case 4: LdrOpcode = AArch64::LDRSWroX;
break;
1261 .addReg(
Size == 4 ? ScratchReg : ScratchRegW)
1265 .addImm(
Size == 1 ? 0 : 1));
1273 .addImm(
Size == 4 ? 0 : 2));
1278 unsigned Opcode =
MI.getOpcode();
1280 assert(STI->hasMTE() || Opcode != AArch64::MOPSMemorySetTaggingPseudo);
1282 const auto Ops = [Opcode]() -> std::array<unsigned, 3> {
1283 if (Opcode == AArch64::MOPSMemoryCopyPseudo)
1284 return {AArch64::CPYFP, AArch64::CPYFM, AArch64::CPYFE};
1285 if (Opcode == AArch64::MOPSMemoryMovePseudo)
1286 return {AArch64::CPYP, AArch64::CPYM, AArch64::CPYE};
1287 if (Opcode == AArch64::MOPSMemorySetPseudo)
1288 return {AArch64::SETP, AArch64::SETM, AArch64::SETE};
1289 if (Opcode == AArch64::MOPSMemorySetTaggingPseudo)
1290 return {AArch64::SETGP, AArch64::SETGM, AArch64::MOPSSETGE};
1293 const bool IsSet = Opcode == AArch64::MOPSMemorySetPseudo ||
1294 Opcode == AArch64::MOPSMemorySetTaggingPseudo;
1296 for (
auto Op : Ops) {
1300 MCIB.addReg(
MI.getOperand(i++).getReg());
1301 MCIB.addReg(
MI.getOperand(i++).getReg());
1303 MCIB.addReg(
MI.getOperand(i++).getReg());
1305 MCIB.addReg(
MI.getOperand(i++).getReg());
1306 MCIB.addReg(
MI.getOperand(i++).getReg());
1307 MCIB.addReg(
MI.getOperand(i++).getReg());
1309 EmitToStreamer(OutStreamer, MCIB);
1318 MCSymbol *MILabel = Ctx.createTempSymbol();
1322 assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
1328 while (NumNOPBytes > 0) {
1329 if (MII ==
MBB.
end() || MII->isCall() ||
1330 MII->getOpcode() == AArch64::DBG_VALUE ||
1331 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
1332 MII->getOpcode() == TargetOpcode::STACKMAP)
1339 for (
unsigned i = 0; i < NumNOPBytes; i += 4)
1340 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1348 MCSymbol *MILabel = Ctx.createTempSymbol();
1354 int64_t CallTarget = Opers.getCallTarget().getImm();
1355 unsigned EncodedBytes = 0;
1357 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
1358 "High 16 bits of call target should be zero.");
1359 Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
1364 .addImm((CallTarget >> 32) & 0xFFFF)
1369 .addImm((CallTarget >> 16) & 0xFFFF)
1374 .addImm(CallTarget & 0xFFFF)
1376 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::BLR).addReg(ScratchReg));
1379 unsigned NumBytes = Opers.getNumPatchBytes();
1380 assert(NumBytes >= EncodedBytes &&
1381 "Patchpoint can't request size less than the length of a call.");
1382 assert((NumBytes - EncodedBytes) % 4 == 0 &&
1383 "Invalid number of NOP bytes requested!");
1384 for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
1385 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1391 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
1392 assert(PatchBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
1393 for (
unsigned i = 0; i < PatchBytes; i += 4)
1394 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1399 unsigned CallOpcode;
1400 switch (CallTarget.
getType()) {
1403 MCInstLowering.lowerOperand(CallTarget, CallTargetMCOp);
1404 CallOpcode = AArch64::BL;
1408 CallOpcode = AArch64::BL;
1412 CallOpcode = AArch64::BLR;
1419 EmitToStreamer(OutStreamer,
1424 MCSymbol *MILabel = Ctx.createTempSymbol();
1429void AArch64AsmPrinter::LowerFAULTING_OP(
const MachineInstr &FaultingMI) {
1438 unsigned OperandsBeginIdx = 4;
1441 MCSymbol *FaultingLabel = Ctx.createTempSymbol();
1445 FM.recordFaultingOp(FK, FaultingLabel, HandlerLabel);
1448 MI.setOpcode(Opcode);
1456 lowerOperand(MO, Dest);
1457 MI.addOperand(Dest);
1465 Register DestReg =
MI.getOperand(0).getReg();
1466 if (STI->hasZeroCycleZeroingFP() && !STI->hasZeroCycleZeroingFPWorkaround() &&
1467 STI->isNeonAvailable()) {
1469 if (AArch64::H0 <= DestReg && DestReg <= AArch64::H31)
1470 DestReg = AArch64::D0 + (DestReg - AArch64::H0);
1471 else if (AArch64::S0 <= DestReg && DestReg <= AArch64::S31)
1472 DestReg = AArch64::D0 + (DestReg - AArch64::S0);
1474 assert(AArch64::D0 <= DestReg && DestReg <= AArch64::D31);
1477 MOVI.setOpcode(AArch64::MOVID);
1480 EmitToStreamer(*OutStreamer, MOVI);
1483 switch (
MI.getOpcode()) {
1485 case AArch64::FMOVH0:
1486 FMov.
setOpcode(STI->hasFullFP16() ? AArch64::FMOVWHr : AArch64::FMOVWSr);
1487 if (!STI->hasFullFP16())
1488 DestReg = (AArch64::S0 + (DestReg - AArch64::H0));
1492 case AArch64::FMOVS0:
1497 case AArch64::FMOVD0:
1503 EmitToStreamer(*OutStreamer, FMov);
1509#include "AArch64GenMCPseudoLowering.inc"
1512 AArch64_MC::verifyInstructionPredicates(
MI->getOpcode(), STI->getFeatureBits());
1515 if (emitPseudoExpansionLowering(*OutStreamer,
MI))
1518 if (
MI->getOpcode() == AArch64::ADRP) {
1519 for (
auto &Opd :
MI->operands()) {
1520 if (Opd.isSymbol() &&
StringRef(Opd.getSymbolName()) ==
1521 "swift_async_extendedFramePointerFlags") {
1522 ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags =
true;
1527 if (AArch64FI->getLOHRelated().count(
MI)) {
1529 MCSymbol *LOHLabel = createTempSymbol(
"loh");
1531 LOHInstToLabel[
MI] = LOHLabel;
1538 switch (
MI->getOpcode()) {
1541 case AArch64::HINT: {
1546 if (CurrentPatchableFunctionEntrySym &&
1547 CurrentPatchableFunctionEntrySym == CurrentFnBegin &&
1548 MI == &MF->front().front()) {
1549 int64_t
Imm =
MI->getOperand(0).getImm();
1550 if ((Imm & 32) && (
Imm & 6)) {
1552 MCInstLowering.Lower(
MI, Inst);
1553 EmitToStreamer(*OutStreamer, Inst);
1554 CurrentPatchableFunctionEntrySym = createTempSymbol(
"patch");
1555 OutStreamer->
emitLabel(CurrentPatchableFunctionEntrySym);
1561 case AArch64::MOVMCSym: {
1562 Register DestReg =
MI->getOperand(0).getReg();
1570 MCInstLowering.lowerOperand(Hi_MOSym, Hi_MCSym);
1571 MCInstLowering.lowerOperand(Lo_MOSym, Lo_MCSym);
1578 EmitToStreamer(*OutStreamer, MovZ);
1586 EmitToStreamer(*OutStreamer, MovK);
1589 case AArch64::MOVIv2d_ns:
1597 if (STI->hasZeroCycleZeroingFPWorkaround() &&
1598 MI->getOperand(1).getImm() == 0) {
1600 TmpInst.
setOpcode(AArch64::MOVIv16b_ns);
1603 EmitToStreamer(*OutStreamer, TmpInst);
1608 case AArch64::DBG_VALUE:
1609 case AArch64::DBG_VALUE_LIST:
1613 PrintDebugValueComment(
MI,
OS);
1618 case AArch64::EMITBKEY: {
1620 if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
1621 ExceptionHandlingType != ExceptionHandling::ARM)
1624 if (getFunctionCFISectionType(*MF) == CFISection::None)
1631 case AArch64::EMITMTETAGGED: {
1633 if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
1634 ExceptionHandlingType != ExceptionHandling::ARM)
1637 if (getFunctionCFISectionType(*MF) != CFISection::None)
1645 case AArch64::TCRETURNri:
1646 case AArch64::TCRETURNrix16x17:
1647 case AArch64::TCRETURNrix17:
1648 case AArch64::TCRETURNrinotx16:
1649 case AArch64::TCRETURNriALL: {
1653 EmitToStreamer(*OutStreamer, TmpInst);
1656 case AArch64::TCRETURNdi: {
1658 MCInstLowering.lowerOperand(
MI->getOperand(0), Dest);
1662 EmitToStreamer(*OutStreamer, TmpInst);
1665 case AArch64::SpeculationBarrierISBDSBEndBB: {
1670 EmitToStreamer(*OutStreamer, TmpInstDSB);
1674 EmitToStreamer(*OutStreamer, TmpInstISB);
1677 case AArch64::SpeculationBarrierSBEndBB: {
1681 EmitToStreamer(*OutStreamer, TmpInstSB);
1684 case AArch64::TLSDESC_CALLSEQ: {
1697 MCInstLowering.lowerOperand(MO_Sym,
Sym);
1698 MCInstLowering.lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
1699 MCInstLowering.lowerOperand(MO_TLSDESC, SymTLSDesc);
1705 EmitToStreamer(*OutStreamer, Adrp);
1708 if (STI->isTargetILP32()) {
1718 EmitToStreamer(*OutStreamer, Ldr);
1721 if (STI->isTargetILP32()) {
1722 Add.setOpcode(AArch64::ADDWri);
1726 Add.setOpcode(AArch64::ADDXri);
1730 Add.addOperand(SymTLSDescLo12);
1732 EmitToStreamer(*OutStreamer,
Add);
1737 TLSDescCall.
setOpcode(AArch64::TLSDESCCALL);
1739 EmitToStreamer(*OutStreamer, TLSDescCall);
1744 EmitToStreamer(*OutStreamer, Blr);
1749 case AArch64::JumpTableDest32:
1750 case AArch64::JumpTableDest16:
1751 case AArch64::JumpTableDest8:
1752 LowerJumpTableDest(*OutStreamer, *
MI);
1755 case AArch64::FMOVH0:
1756 case AArch64::FMOVS0:
1757 case AArch64::FMOVD0:
1761 case AArch64::MOPSMemoryCopyPseudo:
1762 case AArch64::MOPSMemoryMovePseudo:
1763 case AArch64::MOPSMemorySetPseudo:
1764 case AArch64::MOPSMemorySetTaggingPseudo:
1765 LowerMOPS(*OutStreamer, *
MI);
1768 case TargetOpcode::STACKMAP:
1769 return LowerSTACKMAP(*OutStreamer, SM, *
MI);
1771 case TargetOpcode::PATCHPOINT:
1772 return LowerPATCHPOINT(*OutStreamer, SM, *
MI);
1774 case TargetOpcode::STATEPOINT:
1775 return LowerSTATEPOINT(*OutStreamer, SM, *
MI);
1777 case TargetOpcode::FAULTING_OP:
1778 return LowerFAULTING_OP(*
MI);
1780 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
1781 LowerPATCHABLE_FUNCTION_ENTER(*
MI);
1784 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1785 LowerPATCHABLE_FUNCTION_EXIT(*
MI);
1788 case TargetOpcode::PATCHABLE_TAIL_CALL:
1789 LowerPATCHABLE_TAIL_CALL(*
MI);
1791 case TargetOpcode::PATCHABLE_EVENT_CALL:
1792 return LowerPATCHABLE_EVENT_CALL(*
MI,
false);
1793 case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
1794 return LowerPATCHABLE_EVENT_CALL(*
MI,
true);
1796 case AArch64::KCFI_CHECK:
1797 LowerKCFI_CHECK(*
MI);
1800 case AArch64::HWASAN_CHECK_MEMACCESS:
1801 case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
1802 case AArch64::HWASAN_CHECK_MEMACCESS_FIXEDSHADOW:
1803 case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW:
1804 LowerHWASAN_CHECK_MEMACCESS(*
MI);
1807 case AArch64::SEH_StackAlloc:
1811 case AArch64::SEH_SaveFPLR:
1815 case AArch64::SEH_SaveFPLR_X:
1816 assert(
MI->getOperand(0).getImm() < 0 &&
1817 "Pre increment SEH opcode must have a negative offset");
1821 case AArch64::SEH_SaveReg:
1823 MI->getOperand(1).getImm());
1826 case AArch64::SEH_SaveReg_X:
1827 assert(
MI->getOperand(1).getImm() < 0 &&
1828 "Pre increment SEH opcode must have a negative offset");
1830 -
MI->getOperand(1).getImm());
1833 case AArch64::SEH_SaveRegP:
1834 if (
MI->getOperand(1).getImm() == 30 &&
MI->getOperand(0).getImm() >= 19 &&
1835 MI->getOperand(0).getImm() <= 28) {
1836 assert((
MI->getOperand(0).getImm() - 19) % 2 == 0 &&
1837 "Register paired with LR must be odd");
1839 MI->getOperand(2).getImm());
1842 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1843 "Non-consecutive registers not allowed for save_regp");
1845 MI->getOperand(2).getImm());
1848 case AArch64::SEH_SaveRegP_X:
1849 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1850 "Non-consecutive registers not allowed for save_regp_x");
1851 assert(
MI->getOperand(2).getImm() < 0 &&
1852 "Pre increment SEH opcode must have a negative offset");
1854 -
MI->getOperand(2).getImm());
1857 case AArch64::SEH_SaveFReg:
1859 MI->getOperand(1).getImm());
1862 case AArch64::SEH_SaveFReg_X:
1863 assert(
MI->getOperand(1).getImm() < 0 &&
1864 "Pre increment SEH opcode must have a negative offset");
1866 -
MI->getOperand(1).getImm());
1869 case AArch64::SEH_SaveFRegP:
1870 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1871 "Non-consecutive registers not allowed for save_regp");
1873 MI->getOperand(2).getImm());
1876 case AArch64::SEH_SaveFRegP_X:
1877 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1878 "Non-consecutive registers not allowed for save_regp_x");
1879 assert(
MI->getOperand(2).getImm() < 0 &&
1880 "Pre increment SEH opcode must have a negative offset");
1882 -
MI->getOperand(2).getImm());
1885 case AArch64::SEH_SetFP:
1889 case AArch64::SEH_AddFP:
1893 case AArch64::SEH_Nop:
1897 case AArch64::SEH_PrologEnd:
1901 case AArch64::SEH_EpilogStart:
1905 case AArch64::SEH_EpilogEnd:
1909 case AArch64::SEH_PACSignLR:
1913 case AArch64::SEH_SaveAnyRegQP:
1914 assert(
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1 &&
1915 "Non-consecutive registers not allowed for save_any_reg");
1916 assert(
MI->getOperand(2).getImm() >= 0 &&
1917 "SaveAnyRegQP SEH opcode offset must be non-negative");
1918 assert(
MI->getOperand(2).getImm() <= 1008 &&
1919 "SaveAnyRegQP SEH opcode offset must fit into 6 bits");
1921 MI->getOperand(2).getImm());
1924 case AArch64::SEH_SaveAnyRegQPX:
1925 assert(
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1 &&
1926 "Non-consecutive registers not allowed for save_any_reg");
1927 assert(
MI->getOperand(2).getImm() < 0 &&
1928 "SaveAnyRegQPX SEH opcode offset must be negative");
1929 assert(
MI->getOperand(2).getImm() >= -1008 &&
1930 "SaveAnyRegQPX SEH opcode offset must fit into 6 bits");
1932 -
MI->getOperand(2).getImm());
1938 MCInstLowering.Lower(
MI, TmpInst);
1939 EmitToStreamer(*OutStreamer, TmpInst);
1955 MCInstLowering.lowerOperand(
1969 MCInstLowering.lowerOperand(
1979 .addReg(AArch64::X16)
1980 .addReg(AArch64::X16)
1991void AArch64AsmPrinter::emitMachOIFuncStubHelperBody(
Module &M,
2026 .addReg(AArch64::SP)
2027 .addReg(AArch64::FP)
2028 .addReg(AArch64::LR)
2029 .addReg(AArch64::SP)
2034 .addReg(AArch64::FP)
2035 .addReg(AArch64::SP)
2040 for (
int I = 0;
I != 4; ++
I)
2042 .addReg(AArch64::SP)
2043 .addReg(AArch64::X1 + 2 *
I)
2044 .addReg(AArch64::X0 + 2 *
I)
2045 .addReg(AArch64::SP)
2049 for (
int I = 0;
I != 4; ++
I)
2051 .addReg(AArch64::SP)
2052 .addReg(AArch64::D1 + 2 *
I)
2053 .addReg(AArch64::D0 + 2 *
I)
2054 .addReg(AArch64::SP)
2068 MCInstLowering.lowerOperand(
2082 MCInstLowering.lowerOperand(
2092 .addReg(AArch64::X0)
2093 .addReg(AArch64::X16)
2098 .addReg(AArch64::X16)
2099 .addReg(AArch64::X0)
2104 for (
int I = 3;
I != -1; --
I)
2106 .addReg(AArch64::SP)
2107 .addReg(AArch64::D1 + 2 *
I)
2108 .addReg(AArch64::D0 + 2 *
I)
2109 .addReg(AArch64::SP)
2113 for (
int I = 3;
I != -1; --
I)
2115 .addReg(AArch64::SP)
2116 .addReg(AArch64::X1 + 2 *
I)
2117 .addReg(AArch64::X0 + 2 *
I)
2118 .addReg(AArch64::SP)
2123 .addReg(AArch64::SP)
2124 .addReg(AArch64::FP)
2125 .addReg(AArch64::LR)
2126 .addReg(AArch64::SP)
2137const MCExpr *AArch64AsmPrinter::lowerConstant(
const Constant *CV) {
2138 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmPrinter()
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define LLVM_EXTERNAL_VISIBILITY
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const char LLVMTargetMachineRef TM
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 SmallString class.
This file defines the SmallVector class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool printAsmMRegister(const X86AsmPrinter &P, const MachineOperand &MO, char Mode, raw_ostream &O)
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
std::optional< std::string > getOutliningStyle() const
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=AArch64::NoRegAltName)
static const AArch64MCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
AArch64MCInstLower - This class is used to lower an MachineInstr into an MCInst.
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const
virtual void emitARM64WinCFISaveRegP(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveRegPX(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveAnyRegQP(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveFReg(unsigned Reg, int Offset)
virtual void emitARM64WinCFIPACSignLR()
virtual void emitARM64WinCFISaveFRegPX(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveRegX(unsigned Reg, int Offset)
virtual void emitARM64WinCFIAllocStack(unsigned Size)
virtual void emitARM64WinCFISaveFPLRX(int Offset)
virtual void emitDirectiveVariantPCS(MCSymbol *Symbol)
Callback used to implement the .variant_pcs directive.
virtual void emitARM64WinCFIAddFP(unsigned Size)
virtual void emitARM64WinCFISaveFPLR(int Offset)
virtual void emitARM64WinCFISaveFRegP(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveFRegX(unsigned Reg, int Offset)
virtual void emitARM64WinCFISetFP()
virtual void emitARM64WinCFIEpilogEnd()
virtual void emitARM64WinCFIPrologEnd()
void emitNoteSection(unsigned Flags, uint64_t PAuthABIPlatform=-1, uint64_t PAuthABIVersion=-1)
Callback used to implement the .note.gnu.property section.
virtual void emitARM64WinCFISaveReg(unsigned Reg, int Offset)
virtual void emitARM64WinCFINop()
virtual void emitARM64WinCFISaveLRPair(unsigned Reg, int Offset)
virtual void emitARM64WinCFIEpilogStart()
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
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.
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 emitMachOIFuncStubHelperBody(Module &M, const GlobalIFunc &GI, MCSymbol *LazyPointer)
virtual void emitJumpTableInfo()
Print assembly representations of the jump tables used by the current function to the current output ...
virtual void SetupMachineFunction(MachineFunction &MF)
This should be called when a new MachineFunction is being processed from runOnMachineFunction.
void emitFunctionBody()
This method emits the body and trailer for a function.
virtual void emitStartOfAsmFile(Module &)
This virtual method can be overridden by targets that want to emit something at the start of their fi...
virtual void emitEndOfAsmFile(Module &)
This virtual method can be overridden by targets that want to emit something at the end of their file...
virtual void emitMachOIFuncStubBody(Module &M, const GlobalIFunc &GI, MCSymbol *LazyPointer)
void getAnalysisUsage(AnalysisUsage &AU) const override
Record analysis usage.
virtual bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags() const
virtual const MCSubtargetInfo * getIFuncMCSubtargetInfo() const
getSubtargetInfo() cannot be used where this is needed because we don't have a MachineFunction when w...
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
virtual const MCExpr * lowerConstant(const Constant *CV)
Lower the specified LLVM Constant to an MCExpr.
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...
virtual void emitFunctionBodyEnd()
Targets can override this to emit stuff after the last basic block in the function.
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
virtual std::tuple< const MCSymbol *, uint64_t, const MCSymbol *, codeview::JumpTableEntrySize > getCodeViewJumpTableInfo(int JTI, const MachineInstr *BranchInstr, const MCSymbol *BranchLabel) const
Gets information required to create a CodeView debug symbol for a jump table.
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.
This is an important base class in LLVM.
This class represents an Operation in the Expression.
const Constant * getResolver() const
bool hasLocalLinkage() const
static const MCBinaryExpr * createLShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
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)
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)
Instances of this class represent operands of the MCInst class.
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
uint16_t getEncodingValue(MCRegister RegNo) const
Returns the encoding for RegNo.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Streaming machine code generation interface.
virtual void emitCFIBKeyFrame()
virtual void beginCOFFSymbolDef(const MCSymbol *Symbol)
Start emitting COFF symbol definition.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitCOFFSymbolType(int Type)
Emit the type of the symbol.
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText.
virtual void endCOFFSymbolDef()
Marks the end of the symbol definition.
MCContext & getContext() const
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
virtual void emitCFIMTETaggedFrame()
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
void emitRawText(const Twine &String)
If this file is backed by a assembly streamer, this dumps the specified string in the output ....
virtual void emitCOFFSymbolStorageClass(int StorageClass)
Emit the storage class of the symbol.
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
StringRef getName() const
getName - Get the symbol name.
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.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
iterator_range< mop_iterator > operands()
const MachineOperand & getOperand(unsigned i) const
const std::vector< MachineJumpTableEntry > & getJumpTables() const
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
static MachineOperand CreateMCSymbol(MCSymbol *Sym, unsigned TargetFlags=0)
static MachineOperand CreateES(const char *SymName, unsigned TargetFlags=0)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
const BlockAddress * getBlockAddress() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
A Module instance is used to store all the information related to an LLVM module.
Pass interface - Implemented by all 'passes'.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
MI-level patchpoint operands.
Wrapper class representing virtual and physical registers.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MI-level stackmap operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given stackmap should emit.
void recordStatepoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a statepoint instruction.
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.
MI-level Statepoint operands.
StringRef - Represent a constant reference to a string, i.e.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
virtual MCSection * getSectionForJumpTable(const Function &F, const TargetMachine &TM) const
Primary interface to the complete machine description for the target machine.
MCRegister getRegister(unsigned i) const
Return the specified register in the class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool regsOverlap(Register RegA, Register RegB) const
Returns true if the two registers are equal or alias each other.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MO_NC
MO_NC - Indicates whether the linker is expected to check the symbol reference for overflow.
@ MO_G1
MO_G1 - A symbol operand with this flag (granule 1) represents the bits 16-31 of a 64-bit address,...
@ MO_S
MO_S - Indicates that the bits of the symbol operand represented by MO_G0 etc are signed.
@ MO_PAGEOFF
MO_PAGEOFF - A symbol operand with this flag represents the offset of that symbol within a 4K page.
@ MO_GOT
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
@ MO_G0
MO_G0 - A symbol operand with this flag (granule 0) represents the bits 0-15 of a 64-bit address,...
@ MO_PAGE
MO_PAGE - A symbol operand with this flag represents the pc-relative offset of the 4K page containing...
@ MO_TLS
MO_TLS - Indicates that the operand being accessed is some kind of thread-local symbol.
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
SymbolStorageClass
Storage class tells where and what the symbol represents.
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
@ IMAGE_SYM_CLASS_STATIC
Static.
@ IMAGE_SYM_DTYPE_NULL
No complex type; simple scalar variable.
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
@ SCT_COMPLEX_TYPE_SHIFT
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
@ AArch64_VectorCall
Used between AArch64 Advanced SIMD functions.
@ AArch64_SVE_VectorCall
Used between AArch64 SVE functions.
@ GNU_PROPERTY_AARCH64_FEATURE_1_BTI
@ GNU_PROPERTY_AARCH64_FEATURE_1_PAC
@ GNU_PROPERTY_AARCH64_FEATURE_1_GCS
Reg
All possible values of the reg field in the ModR/M byte.
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 & getTheAArch64beTarget()
Target & getTheAArch64leTarget()
static unsigned getXRegFromWReg(unsigned Reg)
static unsigned getXRegFromXRegTuple(unsigned RegTuple)
Target & getTheAArch64_32Target()
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Target & getTheARM64_32Target()
@ MCAF_SubsectionsViaSymbols
.subsections_via_symbols (MachO)
static unsigned getWRegFromXReg(unsigned Reg)
Target & getTheARM64Target()
@ MCSA_Global
.type _foo, @gnu_unique_object
@ MCSA_WeakAntiDep
.weak_anti_dep (COFF)
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
@ MCSA_Hidden
.hidden (ELF)
This struct is a compact representation of a valid (non-zero power of two) alignment.
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...