80#define DEBUG_TYPE "AArch64AsmPrinter"
85 "Number of zero-cycle FPR zeroing instructions expanded from "
86 "canonical pseudo instructions");
94 bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags =
false;
95 bool PtrauthInitFini =
false;
96 bool PtrauthInitFiniAddressDisc =
false;
98 unsigned InstsEmitted;
100 bool EnableImportCallOptimization =
false;
102 SectionToImportedFunctionCalls;
103 unsigned PAuthIFuncNextUniqueID = 1;
110 MCInstLowering(OutContext, *this), FM(*this) {}
112 StringRef getPassName()
const override {
return "AArch64 Assembly Printer"; }
116 bool lowerOperand(
const MachineOperand &MO, MCOperand &MCOp)
const {
117 return MCInstLowering.lowerOperand(MO, MCOp);
120 const MCExpr *lowerConstantPtrAuth(
const ConstantPtrAuth &CPA)
override;
122 const MCExpr *lowerBlockAddressConstant(
const BlockAddress &BA)
override;
124 void emitStartOfAsmFile(
Module &M)
override;
125 void emitJumpTableImpl(
const MachineJumpTableInfo &MJTI,
126 ArrayRef<unsigned> JumpTableIndices)
override;
129 getCodeViewJumpTableInfo(
int JTI,
const MachineInstr *BranchInstr,
130 const MCSymbol *BranchLabel)
const override;
132 void emitFunctionEntryLabel()
override;
134 void emitXXStructor(
const DataLayout &
DL,
const Constant *CV)
override;
136 void LowerJumpTableDest(MCStreamer &OutStreamer,
const MachineInstr &
MI);
138 void LowerHardenedBRJumpTable(
const MachineInstr &
MI);
140 void LowerMOPS(MCStreamer &OutStreamer,
const MachineInstr &
MI);
142 void LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
143 const MachineInstr &
MI);
144 void LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
145 const MachineInstr &
MI);
146 void LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
147 const MachineInstr &
MI);
148 void LowerFAULTING_OP(
const MachineInstr &
MI);
150 void LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr &
MI);
151 void LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr &
MI);
152 void LowerPATCHABLE_TAIL_CALL(
const MachineInstr &
MI);
153 void LowerPATCHABLE_EVENT_CALL(
const MachineInstr &
MI,
bool Typed);
155 typedef std::tuple<unsigned, bool, uint32_t, bool, uint64_t>
156 HwasanMemaccessTuple;
157 std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
158 void LowerKCFI_CHECK(
const MachineInstr &
MI);
159 void LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI);
160 void emitHwasanMemaccessSymbols(
Module &M);
162 void emitSled(
const MachineInstr &
MI, SledKind Kind);
170 if (STI->isX16X17Safer())
171 return Reg == AArch64::X16 ||
Reg == AArch64::X17;
177 void emitPtrauthBranch(
const MachineInstr *
MI);
179 void emitPtrauthCheckAuthenticatedValue(
Register TestedReg,
183 const MCSymbol *OnFailure =
nullptr);
186 void emitPtrauthTailCallHardening(
const MachineInstr *TC);
188 struct PtrAuthSchema {
190 const MachineOperand &AddrDiscOp);
197 bool AddrDiscIsKilled;
200 bool addrDiscIsKilledAndNoneOf(std::initializer_list<Register> Regs) {
218 PtrAuthSchema AuthSchema,
219 std::optional<PtrAuthSchema> SignSchema,
220 std::optional<int64_t> Addend,
Value *DS);
225 bool emitDeactivationSymbolRelocation(
Value *DS);
228 void emitPtrauthSign(
const MachineInstr *
MI);
252 bool MayClobberAddrDisc =
false);
255 void LowerLOADauthptrstatic(
const MachineInstr &
MI);
259 void LowerMOVaddrPAC(
const MachineInstr &
MI);
264 void LowerLOADgotAUTH(
const MachineInstr &
MI);
266 void emitAddImm(MCRegister Val, int64_t Addend, MCRegister Tmp);
267 void emitAddress(MCRegister
Reg,
const MCExpr *Expr, MCRegister Tmp,
268 bool DSOLocal,
const MCSubtargetInfo &STI);
270 const MCExpr *emitPAuthRelocationAsIRelative(
272 bool HasAddressDiversity,
bool IsDSOLocal,
const MCExpr *DSExpr);
276 bool lowerPseudoInstExpansion(
const MachineInstr *
MI, MCInst &Inst);
279 void emitAttributes(
unsigned Flags,
uint64_t PAuthABIPlatform,
280 uint64_t PAuthABIVersion, AArch64TargetStreamer *TS);
283 void emitCBPseudoExpansion(
const MachineInstr *
MI);
286 void emitAtomicHintPseudoExpansion(
const MachineInstr *
MI);
287 void emitAtomicHintPseudoExpansionRO(
const MachineInstr *
MI);
288 void emitAtomicHintPseudoExpansionImm(
const MachineInstr *
MI);
290 void EmitToStreamer(MCStreamer &S,
const MCInst &Inst);
291 void EmitToStreamer(
const MCInst &Inst) {
292 EmitToStreamer(*OutStreamer, Inst);
297 void emitFunctionHeaderComment()
override;
299 void getAnalysisUsage(AnalysisUsage &AU)
const override {
305 if (
auto *PSIW = getAnalysisIfAvailable<ProfileSummaryInfoWrapperPass>())
306 PSI = &PSIW->getPSI();
308 getAnalysisIfAvailable<StaticDataProfileInfoWrapperPass>())
309 SDPI = &SDPIW->getStaticDataProfileInfo();
311 AArch64FI = MF.
getInfo<AArch64FunctionInfo>();
314 SetupMachineFunction(MF);
316 if (STI->isTargetCOFF()) {
323 OutStreamer->beginCOFFSymbolDef(CurrentFnSym);
324 OutStreamer->emitCOFFSymbolStorageClass(Scl);
325 OutStreamer->emitCOFFSymbolType(
Type);
326 OutStreamer->endCOFFSymbolDef();
340 const Constant *BaseCV =
nullptr,
344 void printOperand(
const MachineInstr *
MI,
unsigned OpNum, raw_ostream &O);
346 bool printAsmRegInClass(
const MachineOperand &MO,
350 bool PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNum,
351 const char *ExtraCode, raw_ostream &O)
override;
352 bool PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNum,
353 const char *ExtraCode, raw_ostream &O)
override;
355 void PrintDebugValueComment(
const MachineInstr *
MI, raw_ostream &OS);
357 void emitFunctionBodyEnd()
override;
358 void emitGlobalAlias(
const Module &M,
const GlobalAlias &GA)
override;
360 MCSymbol *GetCPISymbol(
unsigned CPID)
const override;
361 void emitEndOfAsmFile(
Module &M)
override;
363 AArch64FunctionInfo *AArch64FI =
nullptr;
378 void emitFMov0(
const MachineInstr &
MI);
379 void emitFMov0AsFMov(
const MachineInstr &
MI,
Register DestReg);
381 using MInstToMCSymbol = std::map<const MachineInstr *, MCSymbol *>;
383 MInstToMCSymbol LOHInstToLabel;
385 bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags()
const override {
386 return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags;
389 const MCSubtargetInfo *getIFuncMCSubtargetInfo()
const override {
393 void emitMachOIFuncStubBody(
Module &M,
const GlobalIFunc &GI,
394 MCSymbol *LazyPointer)
override;
395 void emitMachOIFuncStubHelperBody(
Module &M,
const GlobalIFunc &GI,
396 MCSymbol *LazyPointer)
override;
401 void recordIfImportCall(
const MachineInstr *BranchInst);
408 Metadata *Flag = M.getModuleFlag(Name);
413 assert((
Value == 0 ||
Value == 1) &&
"Boolean flag is expected, if present");
417void AArch64AsmPrinter::emitStartOfAsmFile(
Module &M) {
418 const Triple &
TT =
M.getTargetTriple();
420 if (
TT.isOSBinFormatCOFF()) {
421 emitCOFFFeatureSymbol(M);
422 emitCOFFReplaceableFunctionData(M);
424 if (
M.getModuleFlag(
"import-call-optimization"))
425 EnableImportCallOptimization =
true;
430 M,
"ptrauth-init-fini-address-discrimination");
432 if (!
TT.isOSBinFormatELF())
437 static_cast<AArch64TargetStreamer *
>(OutStreamer->getTargetStreamer());
440 unsigned BAFlags = 0;
441 unsigned GNUFlags = 0;
443 M.getModuleFlag(
"branch-target-enforcement"))) {
444 if (!BTE->isZero()) {
445 BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_BTI_Flag;
451 M.getModuleFlag(
"guarded-control-stack"))) {
452 if (!GCS->isZero()) {
453 BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_GCS_Flag;
459 M.getModuleFlag(
"sign-return-address"))) {
460 if (!Sign->isZero()) {
461 BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_PAC_Flag;
468 M.getModuleFlag(
"aarch64-elf-pauthabi-platform"))) {
469 PAuthABIPlatform = PAP->getZExtValue();
474 M.getModuleFlag(
"aarch64-elf-pauthabi-version"))) {
475 PAuthABIVersion = PAV->getZExtValue();
483 PAuthABIVersion == 0) {
489 emitAttributes(BAFlags, PAuthABIPlatform, PAuthABIVersion, TS);
491 TS->emitNoteSection(GNUFlags, PAuthABIPlatform, PAuthABIVersion);
494void AArch64AsmPrinter::emitFunctionHeaderComment() {
495 const AArch64FunctionInfo *FI = MF->
getInfo<AArch64FunctionInfo>();
497 if (OutlinerString != std::nullopt)
498 OutStreamer->getCommentOS() <<
' ' << OutlinerString;
501void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr &
MI)
504 if (
F.hasFnAttribute(
"patchable-function-entry")) {
506 if (
F.getFnAttribute(
"patchable-function-entry")
508 .getAsInteger(10, Num))
514 emitSled(
MI, SledKind::FUNCTION_ENTER);
517void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr &
MI) {
518 emitSled(
MI, SledKind::FUNCTION_EXIT);
521void AArch64AsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr &
MI) {
522 emitSled(
MI, SledKind::TAIL_CALL);
525void AArch64AsmPrinter::emitSled(
const MachineInstr &
MI, SledKind Kind) {
526 static const int8_t NoopsInSledCount = 7;
547 OutStreamer->emitCodeAlignment(
Align(4), getSubtargetInfo());
548 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
549 OutStreamer->emitLabel(CurSled);
550 auto Target = OutContext.createTempSymbol();
555 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::B).addImm(8));
557 for (int8_t
I = 0;
I < NoopsInSledCount;
I++)
558 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::NOP));
560 OutStreamer->emitLabel(Target);
561 recordSled(CurSled,
MI, Kind, 2);
564void AArch64AsmPrinter::emitAttributes(
unsigned Flags,
567 AArch64TargetStreamer *TS) {
569 PAuthABIPlatform = (
uint64_t(-1) == PAuthABIPlatform) ? 0 : PAuthABIPlatform;
570 PAuthABIVersion = (
uint64_t(-1) == PAuthABIVersion) ? 0 : PAuthABIVersion;
572 if (PAuthABIPlatform || PAuthABIVersion) {
576 AArch64BuildAttributes::SubsectionOptional::REQUIRED,
577 AArch64BuildAttributes::SubsectionType::ULEB128);
581 PAuthABIPlatform,
"");
595 if (BTIValue || PACValue || GCSValue) {
599 AArch64BuildAttributes::SubsectionOptional::OPTIONAL,
600 AArch64BuildAttributes::SubsectionType::ULEB128);
628void AArch64AsmPrinter::LowerPATCHABLE_EVENT_CALL(
const MachineInstr &
MI,
630 auto &
O = *OutStreamer;
631 MCSymbol *CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
632 O.emitLabel(CurSled);
633 bool MachO = MMI->getModule()->getTargetTriple().isOSBinFormatMachO();
635 OutContext.getOrCreateSymbol(
636 Twine(MachO ?
"_" :
"") +
637 (Typed ?
"__xray_TypedEvent" :
"__xray_CustomEvent")),
640 O.AddComment(
"Begin XRay typed event");
641 EmitToStreamer(O, MCInstBuilder(AArch64::B).addImm(9));
642 EmitToStreamer(O, MCInstBuilder(AArch64::STPXpre)
648 EmitToStreamer(O, MCInstBuilder(AArch64::STRXui)
652 emitMovXReg(AArch64::X0,
MI.getOperand(0).getReg());
653 emitMovXReg(AArch64::X1,
MI.getOperand(1).getReg());
654 emitMovXReg(AArch64::X2,
MI.getOperand(2).getReg());
655 EmitToStreamer(O, MCInstBuilder(AArch64::BL).addExpr(Sym));
656 EmitToStreamer(O, MCInstBuilder(AArch64::LDRXui)
660 O.AddComment(
"End XRay typed event");
661 EmitToStreamer(O, MCInstBuilder(AArch64::LDPXpost)
668 recordSled(CurSled,
MI, SledKind::TYPED_EVENT, 2);
670 O.AddComment(
"Begin XRay custom event");
671 EmitToStreamer(O, MCInstBuilder(AArch64::B).addImm(6));
672 EmitToStreamer(O, MCInstBuilder(AArch64::STPXpre)
678 emitMovXReg(AArch64::X0,
MI.getOperand(0).getReg());
679 emitMovXReg(AArch64::X1,
MI.getOperand(1).getReg());
680 EmitToStreamer(O, MCInstBuilder(AArch64::BL).addExpr(Sym));
681 O.AddComment(
"End XRay custom event");
682 EmitToStreamer(O, MCInstBuilder(AArch64::LDPXpost)
689 recordSled(CurSled,
MI, SledKind::CUSTOM_EVENT, 2);
693void AArch64AsmPrinter::LowerKCFI_CHECK(
const MachineInstr &
MI) {
695 assert(std::next(
MI.getIterator())->isCall() &&
696 "KCFI_CHECK not followed by a call instruction");
697 assert(std::next(
MI.getIterator())->getOperand(0).getReg() == AddrReg &&
698 "KCFI_CHECK call target doesn't match call operand");
702 unsigned ScratchRegs[] = {AArch64::W16, AArch64::W17};
703 if (AddrReg == AArch64::XZR) {
707 emitMovXReg(AddrReg, AArch64::XZR);
713 for (
auto &
Reg : ScratchRegs) {
719 assert(ScratchRegs[0] != AddrReg && ScratchRegs[1] != AddrReg &&
720 "Invalid scratch registers for KCFI_CHECK");
725 MI.getMF()->getFunction().getFnAttributeAsParsedInteger(
726 "patchable-function-prefix");
729 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::LDURWi)
730 .addReg(ScratchRegs[0])
732 .addImm(-(PrefixNops * 4 + 4)));
736 const int64_t
Type =
MI.getOperand(1).getImm();
737 emitMOVK(ScratchRegs[1],
Type & 0xFFFF, 0);
738 emitMOVK(ScratchRegs[1], (
Type >> 16) & 0xFFFF, 16);
741 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::SUBSWrs)
742 .addReg(AArch64::WZR)
743 .addReg(ScratchRegs[0])
744 .addReg(ScratchRegs[1])
748 EmitToStreamer(*OutStreamer,
749 MCInstBuilder(AArch64::Bcc)
758 unsigned TypeIndex = ScratchRegs[1] - AArch64::W0;
762 AddrIndex = AddrReg - AArch64::X0;
772 assert(AddrIndex < 31 && TypeIndex < 31);
774 unsigned ESR = 0x8000 | ((TypeIndex & 31) << 5) | (AddrIndex & 31);
775 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::BRK).addImm(ESR));
776 OutStreamer->emitLabel(
Pass);
779void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
787 if (
Reg == AArch64::XZR)
791 ((
MI.getOpcode() == AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES) ||
793 AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW));
794 uint32_t AccessInfo =
MI.getOperand(1).getImm();
796 ((
MI.getOpcode() == AArch64::HWASAN_CHECK_MEMACCESS_FIXEDSHADOW) ||
798 AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW));
799 uint64_t FixedShadowOffset = IsFixedShadow ?
MI.getOperand(2).getImm() : 0;
801 MCSymbol *&Sym = HwasanMemaccessSymbols[HwasanMemaccessTuple(
802 Reg, IsShort, AccessInfo, IsFixedShadow, FixedShadowOffset)];
805 if (!TM.getTargetTriple().isOSBinFormatELF())
808 std::string SymName =
"__hwasan_check_x" +
utostr(
Reg - AArch64::X0) +
"_" +
811 SymName +=
"_fixed_" +
utostr(FixedShadowOffset);
813 SymName +=
"_short_v2";
814 Sym = OutContext.getOrCreateSymbol(SymName);
817 EmitToStreamer(*OutStreamer,
818 MCInstBuilder(AArch64::BL)
822void AArch64AsmPrinter::emitHwasanMemaccessSymbols(
Module &M) {
823 if (HwasanMemaccessSymbols.empty())
826 const Triple &
TT =
M.getTargetTriple();
830 auto STI = std::make_unique<AArch64Subtarget>(
831 TT, TM.getTargetCPU(), TM.getTargetCPU(), TM.getTargetFeatureString(), TM,
833 this->STI = STI.get();
836 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch");
838 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
840 const MCSymbolRefExpr *HwasanTagMismatchV1Ref =
842 const MCSymbolRefExpr *HwasanTagMismatchV2Ref =
845 for (
auto &
P : HwasanMemaccessSymbols) {
846 unsigned Reg = std::get<0>(
P.first);
847 bool IsShort = std::get<1>(
P.first);
848 uint32_t AccessInfo = std::get<2>(
P.first);
849 bool IsFixedShadow = std::get<3>(
P.first);
850 uint64_t FixedShadowOffset = std::get<4>(
P.first);
851 const MCSymbolRefExpr *HwasanTagMismatchRef =
852 IsShort ? HwasanTagMismatchV2Ref : HwasanTagMismatchV1Ref;
855 bool HasMatchAllTag =
857 uint8_t MatchAllTag =
864 OutStreamer->switchSection(OutContext.getELFSection(
870 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Weak);
871 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Hidden);
872 OutStreamer->emitLabel(Sym);
874 EmitToStreamer(MCInstBuilder(AArch64::SBFMXri)
875 .addReg(AArch64::X16)
885 emitMOVZ(AArch64::X17, FixedShadowOffset >> 32, 32);
886 EmitToStreamer(MCInstBuilder(AArch64::LDRBBroX)
887 .addReg(AArch64::W16)
888 .addReg(AArch64::X17)
889 .addReg(AArch64::X16)
893 EmitToStreamer(MCInstBuilder(AArch64::LDRBBroX)
894 .addReg(AArch64::W16)
895 .addReg(IsShort ? AArch64::X20 : AArch64::X9)
896 .addReg(AArch64::X16)
901 EmitToStreamer(MCInstBuilder(AArch64::SUBSXrs)
902 .addReg(AArch64::XZR)
903 .addReg(AArch64::X16)
906 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
907 EmitToStreamer(MCInstBuilder(AArch64::Bcc)
910 HandleMismatchOrPartialSym, OutContext)));
911 MCSymbol *ReturnSym = OutContext.createTempSymbol();
912 OutStreamer->emitLabel(ReturnSym);
913 EmitToStreamer(MCInstBuilder(AArch64::RET).addReg(AArch64::LR));
914 OutStreamer->emitLabel(HandleMismatchOrPartialSym);
916 if (HasMatchAllTag) {
917 EmitToStreamer(MCInstBuilder(AArch64::UBFMXri)
918 .addReg(AArch64::X17)
922 EmitToStreamer(MCInstBuilder(AArch64::SUBSXri)
923 .addReg(AArch64::XZR)
924 .addReg(AArch64::X17)
928 MCInstBuilder(AArch64::Bcc)
934 EmitToStreamer(MCInstBuilder(AArch64::SUBSWri)
935 .addReg(AArch64::WZR)
936 .addReg(AArch64::W16)
939 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
941 MCInstBuilder(AArch64::Bcc)
945 EmitToStreamer(MCInstBuilder(AArch64::ANDXri)
946 .addReg(AArch64::X17)
950 EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
951 .addReg(AArch64::X17)
952 .addReg(AArch64::X17)
955 EmitToStreamer(MCInstBuilder(AArch64::SUBSWrs)
956 .addReg(AArch64::WZR)
957 .addReg(AArch64::W16)
958 .addReg(AArch64::W17)
961 MCInstBuilder(AArch64::Bcc)
965 EmitToStreamer(MCInstBuilder(AArch64::ORRXri)
966 .addReg(AArch64::X16)
969 EmitToStreamer(MCInstBuilder(AArch64::LDRBBui)
970 .addReg(AArch64::W16)
971 .addReg(AArch64::X16)
974 MCInstBuilder(AArch64::SUBSXrs)
975 .addReg(AArch64::XZR)
976 .addReg(AArch64::X16)
980 MCInstBuilder(AArch64::Bcc)
984 OutStreamer->emitLabel(HandleMismatchSym);
987 EmitToStreamer(MCInstBuilder(AArch64::STPXpre)
993 EmitToStreamer(MCInstBuilder(AArch64::STPXi)
999 if (
Reg != AArch64::X0)
1000 emitMovXReg(AArch64::X0,
Reg);
1003 if (CompileKernel) {
1007 EmitToStreamer(MCInstBuilder(AArch64::B).addExpr(HwasanTagMismatchRef));
1012 EmitToStreamer(MCInstBuilder(AArch64::ADRP)
1013 .addReg(AArch64::X16)
1017 EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
1018 .addReg(AArch64::X16)
1019 .addReg(AArch64::X16)
1023 EmitToStreamer(MCInstBuilder(AArch64::BR).addReg(AArch64::X16));
1026 this->STI =
nullptr;
1031 const MCExpr *StubAuthPtrRef) {
1034 OutStreamer.
emitValue(StubAuthPtrRef, 8);
1037void AArch64AsmPrinter::emitEndOfAsmFile(
Module &M) {
1038 emitHwasanMemaccessSymbols(M);
1040 const Triple &
TT =
M.getTargetTriple();
1041 if (
TT.isOSBinFormatMachO()) {
1043 MachineModuleInfoMachO &MMIMacho =
1044 MMI->getObjFileInfo<MachineModuleInfoMachO>();
1048 if (!Stubs.empty()) {
1050 OutStreamer->switchSection(
1053 emitAlignment(
Align(8));
1055 for (
const auto &Stub : Stubs)
1058 OutStreamer->addBlankLine();
1066 OutStreamer->emitSubsectionsViaSymbols();
1069 if (
TT.isOSBinFormatELF()) {
1071 MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();
1075 if (!Stubs.empty()) {
1076 const TargetLoweringObjectFile &TLOF = getObjFileLowering();
1078 emitAlignment(
Align(8));
1080 for (
const auto &Stub : Stubs)
1083 OutStreamer->addBlankLine();
1094 M.getModuleFlag(
"ptrauth-elf-got"));
1095 if (PtrAuthELFGOTFlag && PtrAuthELFGOTFlag->getZExtValue() == 1)
1096 for (
const GlobalValue &GV :
M.global_values())
1098 !GV.getName().starts_with(
"llvm."))
1099 OutStreamer->emitSymbolAttribute(getSymbol(&GV),
1108 if (EnableImportCallOptimization &&
TT.isOSBinFormatCOFF()) {
1109 OutStreamer->switchSection(getObjFileLowering().getImportCallSection());
1112 constexpr char ImpCallMagic[12] =
"Imp_Call_V1";
1113 OutStreamer->emitBytes(StringRef{ImpCallMagic,
sizeof(ImpCallMagic)});
1124 for (
auto &[Section, CallsToImportedFuncs] :
1125 SectionToImportedFunctionCalls) {
1127 sizeof(uint32_t) * (2 + 3 * CallsToImportedFuncs.size());
1128 OutStreamer->emitInt32(SectionSize);
1129 OutStreamer->emitCOFFSecNumber(
Section->getBeginSymbol());
1130 for (
auto &[CallsiteSymbol, CalledSymbol] : CallsToImportedFuncs) {
1132 OutStreamer->emitInt32(0x13);
1133 OutStreamer->emitCOFFSecOffset(CallsiteSymbol);
1134 OutStreamer->emitCOFFSymbolIndex(CalledSymbol);
1140void AArch64AsmPrinter::emitLOHs() {
1144 for (
const MachineInstr *
MI :
D.getArgs()) {
1145 MInstToMCSymbol::iterator LabelIt = LOHInstToLabel.find(
MI);
1146 assert(LabelIt != LOHInstToLabel.end() &&
1147 "Label hasn't been inserted for LOH related instruction");
1150 OutStreamer->emitLOHDirective(
D.getKind(), MCArgs);
1155void AArch64AsmPrinter::emitFunctionBodyEnd() {
1161MCSymbol *AArch64AsmPrinter::GetCPISymbol(
unsigned CPID)
const {
1165 if (!getDataLayout().getLinkerPrivateGlobalPrefix().
empty())
1166 return OutContext.getOrCreateSymbol(
1167 Twine(getDataLayout().getLinkerPrivateGlobalPrefix()) +
"CPI" +
1168 Twine(getFunctionNumber()) +
"_" + Twine(CPID));
1173void AArch64AsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNum,
1175 const MachineOperand &MO =
MI->getOperand(OpNum);
1191 PrintSymbolOperand(MO, O);
1202bool AArch64AsmPrinter::printAsmMRegister(
const MachineOperand &MO,
char Mode,
1226bool AArch64AsmPrinter::printAsmRegInClass(
const MachineOperand &MO,
1228 unsigned AltName, raw_ostream &O) {
1229 assert(MO.
isReg() &&
"Should only get here with a register!");
1230 const TargetRegisterInfo *RI = STI->getRegisterInfo();
1239bool AArch64AsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNum,
1240 const char *ExtraCode, raw_ostream &O) {
1241 const MachineOperand &MO =
MI->getOperand(OpNum);
1248 if (ExtraCode && ExtraCode[0]) {
1249 if (ExtraCode[1] != 0)
1252 switch (ExtraCode[0]) {
1260 unsigned Reg = ExtraCode[0] ==
'w' ? AArch64::WZR : AArch64::XZR;
1274 switch (ExtraCode[0]) {
1276 RC = &AArch64::FPR8RegClass;
1279 RC = &AArch64::FPR16RegClass;
1282 RC = &AArch64::FPR32RegClass;
1285 RC = &AArch64::FPR64RegClass;
1288 RC = &AArch64::FPR128RegClass;
1291 RC = &AArch64::ZPRRegClass;
1296 return printAsmRegInClass(MO, RC, AArch64::NoRegAltName, O);
1317 unsigned AltName = AArch64::NoRegAltName;
1320 RegClass = &AArch64::ZPRRegClass;
1322 RegClass = &AArch64::PPRRegClass;
1324 RegClass = &AArch64::PNRRegClass;
1326 RegClass = &AArch64::FPR128RegClass;
1327 AltName = AArch64::vreg;
1331 return printAsmRegInClass(MO, RegClass, AltName, O);
1338bool AArch64AsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
1340 const char *ExtraCode,
1342 if (ExtraCode && ExtraCode[0] && ExtraCode[0] !=
'a')
1345 const MachineOperand &MO =
MI->getOperand(OpNum);
1346 assert(MO.
isReg() &&
"unexpected inline asm memory operand");
1351void AArch64AsmPrinter::PrintDebugValueComment(
const MachineInstr *
MI,
1353 unsigned NOps =
MI->getNumOperands();
1355 OS <<
'\t' << MAI.getCommentString() <<
"DEBUG_VALUE: ";
1357 OS <<
MI->getDebugVariable()->getName();
1360 assert(
MI->isIndirectDebugValue());
1372void AArch64AsmPrinter::emitJumpTableImpl(
const MachineJumpTableInfo &MJTI,
1373 ArrayRef<unsigned> JumpTableIndices) {
1375 if (JumpTableIndices.
empty())
1377 const TargetLoweringObjectFile &TLOF = getObjFileLowering();
1381 MCSection *ReadOnlySec =
nullptr;
1382 if (TM.Options.EnableStaticDataPartitioning) {
1388 OutStreamer->switchSection(ReadOnlySec);
1390 auto AFI = MF->
getInfo<AArch64FunctionInfo>();
1391 for (
unsigned JTI : JumpTableIndices) {
1392 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1395 if (JTBBs.empty())
continue;
1397 unsigned Size = AFI->getJumpTableEntrySize(JTI);
1399 OutStreamer->emitLabel(GetJTISymbol(JTI));
1404 for (
auto *JTBB : JTBBs) {
1405 const MCExpr *
Value =
1424AArch64AsmPrinter::getCodeViewJumpTableInfo(
int JTI,
1425 const MachineInstr *BranchInstr,
1426 const MCSymbol *BranchLabel)
const {
1427 const auto AFI = MF->
getInfo<AArch64FunctionInfo>();
1430 switch (AFI->getJumpTableEntrySize(JTI)) {
1432 EntrySize = codeview::JumpTableEntrySize::UInt8ShiftLeft;
1435 EntrySize = codeview::JumpTableEntrySize::UInt16ShiftLeft;
1438 EntrySize = codeview::JumpTableEntrySize::Int32;
1443 return std::make_tuple(
Base, 0, BranchLabel, EntrySize);
1446void AArch64AsmPrinter::emitFunctionEntryLabel() {
1447 const Triple &
TT = TM.getTargetTriple();
1448 if (
TT.isOSBinFormatELF() &&
1451 CallingConv::AArch64_SVE_VectorCall ||
1452 MF->
getInfo<AArch64FunctionInfo>()->isSVECC())) {
1454 static_cast<AArch64TargetStreamer *
>(OutStreamer->getTargetStreamer());
1465 OutStreamer->emitAssignment(
1469 auto getSymbolFromMetadata = [&](StringRef
Name) {
1473 Sym = MMI->getContext().getOrCreateSymbol(NameStr);
1480 for (MDNode *Node : UnmangledNames) {
1482 MCSymbol *UnmangledSym = MMI->getContext().getOrCreateSymbol(NameStr);
1483 if (std::optional<std::string> MangledName =
1486 MMI->getContext().getOrCreateSymbol(*MangledName);
1487 emitFunctionAlias(UnmangledSym, ECMangledSym);
1490 if (MCSymbol *ECMangledSym =
1491 getSymbolFromMetadata(
"arm64ec_ecmangled_name"))
1492 emitFunctionAlias(ECMangledSym, CurrentFnSym);
1496void AArch64AsmPrinter::emitXXStructor(
const DataLayout &
DL,
1497 const Constant *CV) {
1500 "ctors/dtors are to be signed by asm printer");
1502 if (PtrauthInitFini) {
1508 ConstantInt *IntDisc = ConstantInt::get(
1512 if (PtrauthInitFiniAddressDisc) {
1526void AArch64AsmPrinter::emitGlobalAlias(
const Module &M,
1527 const GlobalAlias &GA) {
1533 if (MDNode *Node =
F->getMetadata(
"arm64ec_exp_name")) {
1535 MCSymbol *ExpSym = MMI->getContext().getOrCreateSymbol(ExpStr);
1538 OutStreamer->beginCOFFSymbolDef(ExpSym);
1542 OutStreamer->endCOFFSymbolDef();
1544 OutStreamer->beginCOFFSymbolDef(Sym);
1548 OutStreamer->endCOFFSymbolDef();
1549 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Weak);
1550 OutStreamer->emitAssignment(
1567void AArch64AsmPrinter::LowerJumpTableDest(llvm::MCStreamer &OutStreamer,
1568 const llvm::MachineInstr &
MI) {
1569 Register DestReg =
MI.getOperand(0).getReg();
1570 Register ScratchReg =
MI.getOperand(1).getReg();
1572 STI->getRegisterInfo()->getSubReg(ScratchReg, AArch64::sub_32);
1573 Register TableReg =
MI.getOperand(2).getReg();
1574 Register EntryReg =
MI.getOperand(3).getReg();
1575 int JTIdx =
MI.getOperand(4).getIndex();
1581 MF->
getInfo<AArch64FunctionInfo>()->getJumpTableEntryPCRelSymbol(JTIdx);
1592 EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::ADR)
1594 .addExpr(LabelExpr));
1599 case 1: LdrOpcode = AArch64::LDRBBroX;
break;
1600 case 2: LdrOpcode = AArch64::LDRHHroX;
break;
1601 case 4: LdrOpcode = AArch64::LDRSWroX;
break;
1606 EmitToStreamer(OutStreamer, MCInstBuilder(LdrOpcode)
1607 .addReg(
Size == 4 ? ScratchReg : ScratchRegW)
1611 .addImm(
Size == 1 ? 0 : 1));
1615 EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::ADDXrs)
1619 .addImm(
Size == 4 ? 0 : 2));
1622void AArch64AsmPrinter::LowerHardenedBRJumpTable(
const MachineInstr &
MI) {
1624 assert(MJTI &&
"Can't lower jump-table dispatch without JTI");
1626 const std::vector<MachineJumpTableEntry> &JTs = MJTI->
getJumpTables();
1627 assert(!JTs.empty() &&
"Invalid JT index for jump-table dispatch");
1643 MachineOperand JTOp =
MI.getOperand(0);
1647 "unsupported compressed jump table");
1649 const uint64_t NumTableEntries = JTs[JTI].MBBs.size();
1653 uint64_t MaxTableEntry = NumTableEntries - 1;
1655 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::SUBSXri)
1656 .addReg(AArch64::XZR)
1657 .addReg(AArch64::X16)
1658 .addImm(MaxTableEntry)
1661 emitMOVZ(AArch64::X17,
static_cast<uint16_t
>(MaxTableEntry), 0);
1666 if ((MaxTableEntry >>
Offset) == 0)
1668 emitMOVK(AArch64::X17,
static_cast<uint16_t
>(MaxTableEntry >>
Offset),
1671 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::SUBSXrs)
1672 .addReg(AArch64::XZR)
1673 .addReg(AArch64::X16)
1674 .addReg(AArch64::X17)
1680 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::CSELXr)
1681 .addReg(AArch64::X16)
1682 .addReg(AArch64::X16)
1683 .addReg(AArch64::XZR)
1687 MachineOperand JTMOHi(JTOp), JTMOLo(JTOp);
1688 MCOperand JTMCHi, JTMCLo;
1698 MCInstBuilder(AArch64::ADRP).addReg(AArch64::X17).
addOperand(JTMCHi));
1700 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ADDXri)
1701 .addReg(AArch64::X17)
1702 .addReg(AArch64::X17)
1706 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::LDRSWroX)
1707 .addReg(AArch64::X16)
1708 .addReg(AArch64::X17)
1709 .addReg(AArch64::X16)
1720 MCInstBuilder(AArch64::ADR).addReg(AArch64::X17).addExpr(AdrLabelE));
1722 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ADDXrs)
1723 .addReg(AArch64::X16)
1724 .addReg(AArch64::X17)
1725 .addReg(AArch64::X16)
1728 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::BR).addReg(AArch64::X16));
1731void AArch64AsmPrinter::LowerMOPS(llvm::MCStreamer &OutStreamer,
1732 const llvm::MachineInstr &
MI) {
1733 unsigned Opcode =
MI.getOpcode();
1735 assert(STI->hasMTE() || Opcode != AArch64::MOPSMemorySetTaggingPseudo);
1737 const auto Ops = [Opcode]() -> std::array<unsigned, 3> {
1738 if (Opcode == AArch64::MOPSMemoryCopyPseudo)
1739 return {AArch64::CPYFP, AArch64::CPYFM, AArch64::CPYFE};
1740 if (Opcode == AArch64::MOPSMemoryMovePseudo)
1741 return {AArch64::CPYP, AArch64::CPYM, AArch64::CPYE};
1742 if (Opcode == AArch64::MOPSMemorySetPseudo)
1743 return {AArch64::SETP, AArch64::SETM, AArch64::SETE};
1744 if (Opcode == AArch64::MOPSMemorySetTaggingPseudo)
1745 return {AArch64::SETGP, AArch64::SETGM, AArch64::MOPSSETGE};
1748 const bool IsSet = Opcode == AArch64::MOPSMemorySetPseudo ||
1749 Opcode == AArch64::MOPSMemorySetTaggingPseudo;
1751 for (
auto Op :
Ops) {
1753 auto MCIB = MCInstBuilder(
Op);
1755 MCIB.addReg(
MI.getOperand(i++).getReg());
1756 MCIB.addReg(
MI.getOperand(i++).getReg());
1758 MCIB.addReg(
MI.getOperand(i++).getReg());
1760 MCIB.addReg(
MI.getOperand(i++).getReg());
1761 MCIB.addReg(
MI.getOperand(i++).getReg());
1762 MCIB.addReg(
MI.getOperand(i++).getReg());
1764 EmitToStreamer(OutStreamer, MCIB);
1768void AArch64AsmPrinter::LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
1769 const MachineInstr &
MI) {
1770 unsigned NumNOPBytes = StackMapOpers(&
MI).getNumPatchBytes();
1773 MCSymbol *MILabel = Ctx.createTempSymbol();
1777 assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
1783 while (NumNOPBytes > 0) {
1784 if (MII ==
MBB.
end() || MII->isCall() ||
1785 MII->getOpcode() == AArch64::DBG_VALUE ||
1786 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
1787 MII->getOpcode() == TargetOpcode::STACKMAP)
1794 for (
unsigned i = 0; i < NumNOPBytes; i += 4)
1795 EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::NOP));
1800void AArch64AsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
1801 const MachineInstr &
MI) {
1803 MCSymbol *MILabel = Ctx.createTempSymbol();
1807 PatchPointOpers Opers(&
MI);
1809 int64_t CallTarget = Opers.getCallTarget().getImm();
1810 unsigned EncodedBytes = 0;
1812 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
1813 "High 16 bits of call target should be zero.");
1814 Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
1817 emitMOVZ(ScratchReg, (CallTarget >> 32) & 0xFFFF, 32);
1818 emitMOVK(ScratchReg, (CallTarget >> 16) & 0xFFFF, 16);
1819 emitMOVK(ScratchReg, CallTarget & 0xFFFF, 0);
1820 EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::BLR).addReg(ScratchReg));
1823 unsigned NumBytes = Opers.getNumPatchBytes();
1824 assert(NumBytes >= EncodedBytes &&
1825 "Patchpoint can't request size less than the length of a call.");
1826 assert((NumBytes - EncodedBytes) % 4 == 0 &&
1827 "Invalid number of NOP bytes requested!");
1828 for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
1829 EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::NOP));
1832void AArch64AsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
1833 const MachineInstr &
MI) {
1834 StatepointOpers SOpers(&
MI);
1835 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
1836 assert(PatchBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
1837 for (
unsigned i = 0; i < PatchBytes; i += 4)
1838 EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::NOP));
1841 const MachineOperand &CallTarget = SOpers.getCallTarget();
1842 MCOperand CallTargetMCOp;
1843 unsigned CallOpcode;
1844 switch (CallTarget.
getType()) {
1847 MCInstLowering.
lowerOperand(CallTarget, CallTargetMCOp);
1848 CallOpcode = AArch64::BL;
1852 CallOpcode = AArch64::BL;
1856 CallOpcode = AArch64::BLR;
1863 EmitToStreamer(OutStreamer,
1864 MCInstBuilder(CallOpcode).
addOperand(CallTargetMCOp));
1868 MCSymbol *MILabel = Ctx.createTempSymbol();
1873void AArch64AsmPrinter::LowerFAULTING_OP(
const MachineInstr &FaultingMI) {
1882 unsigned OperandsBeginIdx = 4;
1885 MCSymbol *FaultingLabel = Ctx.createTempSymbol();
1892 MI.setOpcode(Opcode);
1897 for (
const MachineOperand &MO :
1900 lowerOperand(MO, Dest);
1901 MI.addOperand(Dest);
1909 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ORRXrs)
1911 .addReg(AArch64::XZR)
1917 bool Is64Bit = AArch64::GPR64RegClass.contains(Dest);
1918 EmitToStreamer(*OutStreamer,
1919 MCInstBuilder(Is64Bit ? AArch64::MOVZXi : AArch64::MOVZWi)
1926 bool Is64Bit = AArch64::GPR64RegClass.contains(Dest);
1927 EmitToStreamer(*OutStreamer,
1928 MCInstBuilder(Is64Bit ? AArch64::MOVKXi : AArch64::MOVKWi)
1937 bool IsZeroDisc = Disc == AArch64::XZR;
1949 EmitToStreamer(AUTInst);
1954 bool IsZeroDisc = Disc == AArch64::XZR;
1966 EmitToStreamer(PACInst);
1971 bool IsZeroDisc = Disc == AArch64::XZR;
1981 EmitToStreamer(Inst);
1984void AArch64AsmPrinter::emitFMov0(
const MachineInstr &
MI) {
1985 Register DestReg =
MI.getOperand(0).getReg();
1986 if (!STI->hasZeroCycleZeroingFPWorkaround() && STI->isNeonAvailable()) {
1987 if (STI->hasZeroCycleZeroingFPR64()) {
1989 const AArch64RegisterInfo *
TRI = STI->getRegisterInfo();
1990 if (AArch64::FPR16RegClass.
contains(DestReg))
1991 DestReg =
TRI->getMatchingSuperReg(DestReg, AArch64::hsub,
1992 &AArch64::FPR64RegClass);
1993 else if (AArch64::FPR32RegClass.
contains(DestReg))
1994 DestReg =
TRI->getMatchingSuperReg(DestReg, AArch64::ssub,
1995 &AArch64::FPR64RegClass);
2003 EmitToStreamer(*OutStreamer, MOVI);
2004 ++NumZCZeroingInstrsFPR;
2005 }
else if (STI->hasZeroCycleZeroingFPR128()) {
2007 const AArch64RegisterInfo *
TRI = STI->getRegisterInfo();
2008 if (AArch64::FPR16RegClass.
contains(DestReg)) {
2009 DestReg =
TRI->getMatchingSuperReg(DestReg, AArch64::hsub,
2010 &AArch64::FPR128RegClass);
2011 }
else if (AArch64::FPR32RegClass.
contains(DestReg)) {
2012 DestReg =
TRI->getMatchingSuperReg(DestReg, AArch64::ssub,
2013 &AArch64::FPR128RegClass);
2016 DestReg =
TRI->getMatchingSuperReg(DestReg, AArch64::dsub,
2017 &AArch64::FPR128RegClass);
2024 EmitToStreamer(*OutStreamer, MOVI);
2025 ++NumZCZeroingInstrsFPR;
2027 emitFMov0AsFMov(
MI, DestReg);
2030 emitFMov0AsFMov(
MI, DestReg);
2034void AArch64AsmPrinter::emitFMov0AsFMov(
const MachineInstr &
MI,
2037 switch (
MI.getOpcode()) {
2040 case AArch64::FMOVH0:
2041 FMov.
setOpcode(STI->hasFullFP16() ? AArch64::FMOVWHr : AArch64::FMOVWSr);
2042 if (!STI->hasFullFP16())
2043 DestReg = (AArch64::S0 + (DestReg - AArch64::H0));
2047 case AArch64::FMOVS0:
2052 case AArch64::FMOVD0:
2058 EmitToStreamer(*OutStreamer, FMov);
2064 bool MayClobberAddrDisc) {
2065 assert(isPtrauthRegSafe(ScratchReg) &&
2066 "Safe scratch register must be provided by the caller");
2071 AddrDisc = AArch64::XZR;
2079 if (AddrDisc == AArch64::XZR) {
2080 emitMOVZ(ScratchReg, Disc, 0);
2087 if (MayClobberAddrDisc && isPtrauthRegSafe(AddrDisc)) {
2088 ScratchReg = AddrDisc;
2090 emitMovXReg(ScratchReg, AddrDisc);
2091 assert(ScratchReg != AddrDisc &&
2092 "Forbidden to clobber AddrDisc, but have to");
2095 emitMOVK(ScratchReg, Disc, 48);
2109void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue(
2141 if (Method == AuthCheckMethod::None)
2143 if (Method == AuthCheckMethod::DummyLoad) {
2144 EmitToStreamer(MCInstBuilder(AArch64::LDRWui)
2148 assert(!OnFailure &&
"DummyLoad always traps on error");
2152 MCSymbol *SuccessSym = createTempSymbol(
"auth_success_");
2153 if (Method == AuthCheckMethod::XPAC || Method == AuthCheckMethod::XPACHint) {
2155 emitMovXReg(ScratchReg, TestedReg);
2157 if (Method == AuthCheckMethod::XPAC) {
2161 MCInstBuilder(XPACOpc).addReg(ScratchReg).addReg(ScratchReg));
2166 assert(TestedReg == AArch64::LR &&
2167 "XPACHint mode is only compatible with checking the LR register");
2169 "XPACHint mode is only compatible with I-keys");
2170 EmitToStreamer(MCInstBuilder(AArch64::XPACLRI));
2174 EmitToStreamer(MCInstBuilder(AArch64::SUBSXrs)
2175 .addReg(AArch64::XZR)
2182 MCInstBuilder(AArch64::Bcc)
2185 }
else if (Method == AuthCheckMethod::HighBitsNoTBI) {
2187 EmitToStreamer(MCInstBuilder(AArch64::EORXrs)
2194 MCInstBuilder(AArch64::TBZX)
2205 EmitToStreamer(MCInstBuilder(AArch64::BRK).addImm(0xc470 |
Key));
2219 case AuthCheckMethod::XPACHint:
2222 case AuthCheckMethod::XPAC:
2224 emitMovXReg(TestedReg, ScratchReg);
2231 MCInstBuilder(XPACOpc).addReg(TestedReg).addReg(TestedReg));
2236 EmitToStreamer(MCInstBuilder(AArch64::B).addExpr(OnFailureExpr));
2248void AArch64AsmPrinter::emitPtrauthTailCallHardening(
const MachineInstr *TC) {
2252 auto LRCheckMethod = STI->getAuthenticatedLRCheckMethod(*MF);
2253 if (LRCheckMethod == AArch64PAuth::AuthCheckMethod::None)
2256 const AArch64RegisterInfo *
TRI = STI->getRegisterInfo();
2260 "Neither x16 nor x17 is available as a scratch register");
2263 emitPtrauthCheckAuthenticatedValue(AArch64::LR, ScratchReg,
Key,
2267bool AArch64AsmPrinter::emitDeactivationSymbolRelocation(
Value *DS) {
2273 EmitToStreamer(MCInstBuilder(AArch64::NOP));
2276 MCSymbol *Dot = OutContext.createTempSymbol();
2281 OutContext.getOrCreateSymbol(
DS->getName()), OutContext);
2287AArch64AsmPrinter::PtrAuthSchema AArch64AsmPrinter::PtrAuthSchema::CreateImmReg(
2289 PtrAuthSchema Schema;
2291 Schema.IntDisc = IntDisc;
2292 Schema.AddrDisc = AddrDiscOp.
getReg();
2293 Schema.AddrDiscIsKilled = AddrDiscOp.
isKill();
2298AArch64AsmPrinter::PtrAuthSchema AArch64AsmPrinter::PtrAuthSchema::CreateRegReg(
2300 assert(PCDisc.
isValid() &&
"Use CreateImmReg for non-PC schemas");
2301 PtrAuthSchema Schema;
2304 Schema.AddrDisc = AddrDisc;
2305 Schema.AddrDiscIsKilled =
false;
2306 Schema.PCDisc = PCDisc;
2310void AArch64AsmPrinter::emitPtrauthApplyIndirectAddend(
Register Pointer,
2315 EmitToStreamer(MCInstBuilder(AArch64::LDRSWpre)
2325 for (
int BitPos = 0; BitPos != 24 && (Addend >> BitPos); BitPos += 12) {
2327 MCInstBuilder(AArch64::ADDXri)
2330 .addImm((Addend >> BitPos) & 0xfff)
2336 emitMOVZ(Scratch, Addend & 0xffff, 0);
2343 EmitToStreamer(MCInstBuilder(AArch64::ADDXrs)
2350 EmitToStreamer(MCInstBuilder(AArch64::LDRSWui)
2356 EmitToStreamer(MCInstBuilder(AArch64::ADDXrs)
2367 if (std::optional<PtrauthCheckMode>
Mode =
2374 return PtrauthCheckMode::Unchecked;
2377 return ShouldTrap ? PtrauthCheckMode::Trap : PtrauthCheckMode::Poison;
2408void AArch64AsmPrinter::emitPtrauthAuthResign(
2410 std::optional<PtrAuthSchema> SignSchema, std::optional<int64_t> Addend,
2413 const bool IsAuthWithPC = AuthSchema.PCDisc.isValid();
2414 assert(!SignSchema || !SignSchema->PCDisc.isValid());
2416 Register SignAddrDiscOrNone = SignSchema ? SignSchema->AddrDisc :
Register();
2422 assert(Pointer == AArch64::X17 && Scratch == AArch64::X16 &&
2423 "AUTPCPAC must use x17/x16 as Pointer/Scratch");
2425 assert(AuthSchema.AddrDisc == AArch64::X16 &&
2426 "AUTPCPAC requires address discriminator in X16");
2428 assert(AuthSchema.PCDisc == AArch64::X15 &&
2429 "AUTPCPAC requires PC discriminator in X15");
2431 assert(AuthSchema.IntDisc == 0 &&
"AUTPCPAC does not support IntDisc");
2435 "AUTPCPAC only supports AUT-ing with IA/IB");
2437 if (!emitDeactivationSymbolRelocation(DS)) {
2439 ? AArch64::AUTIB171615
2440 : AArch64::AUTIA171615;
2441 EmitToStreamer(MCInstBuilder(AutOpc));
2451 Register AUTDiscReg = emitPtrauthDiscriminator(
2452 AuthSchema.IntDisc, AuthSchema.AddrDisc, Scratch,
2453 AuthSchema.addrDiscIsKilledAndNoneOf({Pointer, SignAddrDiscOrNone}));
2454 if (!emitDeactivationSymbolRelocation(DS))
2455 emitAUT(AuthSchema.Key, Pointer, AUTDiscReg);
2460 auto EmitCheck = [&](
MCSymbol *OnFailure =
nullptr) {
2461 emitPtrauthCheckAuthenticatedValue(Pointer, Scratch, AuthSchema.Key,
2462 AArch64PAuth::AuthCheckMethod::XPAC,
2466 auto EmitResignOnSuccess = [&]() {
2467 if (Addend.has_value())
2468 emitPtrauthApplyIndirectAddend(Pointer, Scratch, *Addend);
2470 assert(Pointer != SignSchema->AddrDisc &&
"Pointer is early-clobbered");
2472 emitPtrauthDiscriminator(SignSchema->IntDisc, SignSchema->AddrDisc,
2473 Scratch, SignSchema->AddrDiscIsKilled);
2474 emitPAC(SignSchema->Key, Pointer, PACDiscReg);
2480 if (CheckMode == PtrauthCheckMode::Trap)
2486 switch (CheckMode) {
2487 case PtrauthCheckMode::Unchecked:
2488 EmitResignOnSuccess();
2490 case PtrauthCheckMode::Trap:
2492 EmitResignOnSuccess();
2494 case PtrauthCheckMode::Poison:
2495 MCSymbol *OnFailure = createTempSymbol(
"resign_end_");
2496 EmitCheck(OnFailure);
2497 EmitResignOnSuccess();
2503void AArch64AsmPrinter::emitPtrauthSign(
const MachineInstr *
MI) {
2507 Register AddrDisc =
MI->getOperand(4).getReg();
2508 bool AddrDiscKilled =
MI->getOperand(4).isKill();
2512 Register ScratchReg = Val == AArch64::X16 ? AArch64::X17 : AArch64::X16;
2513 assert(ScratchReg != AddrDisc &&
2514 "Neither X16 nor X17 is available as a scratch register");
2517 Register DiscReg = emitPtrauthDiscriminator(
2518 Disc, AddrDisc, ScratchReg, AddrDiscKilled);
2520 if (emitDeactivationSymbolRelocation(
MI->getDeactivationSymbol()))
2523 emitPAC(
Key, Val, DiscReg);
2526void AArch64AsmPrinter::emitPtrauthBranch(
const MachineInstr *
MI) {
2527 bool IsCall =
MI->getOpcode() == AArch64::BLRA;
2528 unsigned BrTarget =
MI->getOperand(0).getReg();
2533 unsigned AddrDisc =
MI->getOperand(3).getReg();
2539 if (BrTarget == AddrDisc)
2556 bool AddrDiscIsImplicitDef =
2557 IsCall && (AddrDisc == AArch64::X16 || AddrDisc == AArch64::X17);
2558 Register DiscReg = emitPtrauthDiscriminator(Disc, AddrDisc, AArch64::X17,
2559 AddrDiscIsImplicitDef);
2560 emitBLRA(IsCall,
Key, BrTarget, DiscReg);
2563void AArch64AsmPrinter::emitAddImm(MCRegister
Reg, int64_t Addend,
2567 const bool IsNeg = Addend < 0;
2569 for (
int BitPos = 0; BitPos != 24 && (AbsOffset >> BitPos);
2572 MCInstBuilder(IsNeg ? AArch64::SUBXri : AArch64::ADDXri)
2575 .addImm((AbsOffset >> BitPos) & 0xfff)
2580 EmitToStreamer(MCInstBuilder(IsNeg ? AArch64::MOVNXi : AArch64::MOVZXi)
2582 .addImm((IsNeg ? ~UAddend : UAddend) & 0xffff)
2584 auto NeedMovk = [IsNeg, UAddend](
int BitPos) ->
bool {
2585 assert(BitPos == 16 || BitPos == 32 || BitPos == 48);
2586 uint64_t Shifted = UAddend >> BitPos;
2588 return Shifted != 0;
2589 for (
int I = 0;
I != 64 - BitPos;
I += 16)
2590 if (((Shifted >>
I) & 0xffff) != 0xffff)
2594 for (
int BitPos = 16; BitPos != 64 && NeedMovk(BitPos); BitPos += 16)
2595 emitMOVK(Tmp, (UAddend >> BitPos) & 0xffff, BitPos);
2597 EmitToStreamer(MCInstBuilder(AArch64::ADDXrs)
2606void AArch64AsmPrinter::emitAddress(MCRegister
Reg,
const MCExpr *Expr,
2607 MCRegister Tmp,
bool DSOLocal,
2608 const MCSubtargetInfo &STI) {
2614 MCInstBuilder(AArch64::ADRP)
2618 EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
2628 MCInstBuilder(AArch64::ADRP)
2633 MCInstBuilder(AArch64::LDRXui)
2644 if (!TT.isOSBinFormatELF())
2648 return TT.isOSGlibc() || TT.isAndroid() || TT.isOSFreeBSD() ||
2649 TT.isOSDragonFly() || TT.isOSNetBSD();
2703const MCExpr *AArch64AsmPrinter::emitPAuthRelocationAsIRelative(
2705 bool HasAddressDiversity,
bool IsDSOLocal,
const MCExpr *DSExpr) {
2706 const Triple &
TT = TM.getTargetTriple();
2718 auto STI = std::make_unique<AArch64Subtarget>(
2719 TT, TM.getTargetCPU(), TM.getTargetCPU(), TM.getTargetFeatureString(), TM,
2721 this->STI = STI.get();
2727 const MCSymbolELF *Group =
2742 .addReg(AArch64::X0)
2747 emitAddress(AArch64::X0, Target, AArch64::X16, IsDSOLocal, *STI);
2749 if (HasAddressDiversity) {
2754 emitAddress(AArch64::X1, PlacePlusDisc, AArch64::X16,
true,
2758 OutContext.reportError(SMLoc(),
"AArch64 PAC Discriminator '" +
2760 "' out of range [0, 0xFFFF]");
2762 emitMOVZ(AArch64::X1, Disc, 0);
2769 auto *PrePACInstExpr =
2781 const MCSymbolRefExpr *EmuPACRef =
2783 OutStreamer->
emitInstruction(MCInstBuilder(AArch64::B).addExpr(EmuPACRef),
2790 MCInstBuilder(AArch64::RET).addReg(AArch64::LR), *STI);
2799AArch64AsmPrinter::lowerConstantPtrAuth(
const ConstantPtrAuth &CPA) {
2800 MCContext &Ctx = OutContext;
2805 getDataLayout(),
Offset,
true);
2825 const MCExpr *DSExpr =
nullptr;
2837 "' out of range [0, " +
2845 if (
auto *IFuncSym = emitPAuthRelocationAsIRelative(
2847 BaseGVB && BaseGVB->isDSOLocal(), DSExpr))
2852 "' out of range [0, 0xFFFF]");
2858 "expressions on this target");
2865void AArch64AsmPrinter::LowerLOADauthptrstatic(
const MachineInstr &
MI) {
2866 unsigned DstReg =
MI.getOperand(0).getReg();
2867 const MachineOperand &GAOp =
MI.getOperand(1);
2868 const uint64_t KeyC =
MI.getOperand(2).getImm();
2870 "key is out of range [0, AArch64PACKey::LAST]");
2872 const uint64_t Disc =
MI.getOperand(3).getImm();
2874 "constant discriminator is out of range [0, 0xffff]");
2883 if (TM.getTargetTriple().isOSBinFormatELF()) {
2885 static_cast<const AArch64_ELFTargetObjectFile &
>(getObjFileLowering());
2888 "non-zero offset for $auth_ptr$ stub slots is not supported");
2890 AuthPtrStubSym = TLOF.getAuthPtrSlotSymbol(TM, MMI, GASym,
Key, Disc);
2892 assert(TM.getTargetTriple().isOSBinFormatMachO() &&
2893 "LOADauthptrstatic is implemented only for MachO/ELF");
2895 const auto &TLOF =
static_cast<const AArch64_MachoTargetObjectFile &
>(
2896 getObjFileLowering());
2899 "non-zero offset for $auth_ptr$ stub slots is not supported");
2901 AuthPtrStubSym = TLOF.getAuthPtrSlotSymbol(TM, MMI, GASym,
Key, Disc);
2904 MachineOperand StubMOHi =
2908 MCOperand StubMCHi, StubMCLo;
2915 MCInstBuilder(AArch64::ADRP).addReg(DstReg).
addOperand(StubMCHi));
2917 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::LDRXui)
2923void AArch64AsmPrinter::LowerMOVaddrPAC(
const MachineInstr &
MI) {
2924 const bool IsGOTLoad =
MI.getOpcode() == AArch64::LOADgotPAC;
2925 const bool IsELFSignedGOT =
MI.getParent()
2927 ->getInfo<AArch64FunctionInfo>()
2928 ->hasELFSignedGOT();
2929 MachineOperand GAOp =
MI.getOperand(0);
2930 const uint64_t KeyC =
MI.getOperand(1).getImm();
2932 "key is out of range [0, AArch64PACKey::LAST]");
2934 const unsigned AddrDisc =
MI.getOperand(2).getReg();
2935 const uint64_t Disc =
MI.getOperand(3).getImm();
2982 MachineOperand GAMOHi(GAOp), GAMOLo(GAOp);
2983 MCOperand GAMCHi, GAMCLo;
2996 MCInstBuilder(AArch64::ADRP)
2997 .addReg(IsGOTLoad && IsELFSignedGOT ? AArch64::X17 : AArch64::X16)
3001 if (IsELFSignedGOT) {
3002 EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
3003 .addReg(AArch64::X17)
3004 .addReg(AArch64::X17)
3008 EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
3009 .addReg(AArch64::X16)
3010 .addReg(AArch64::X17)
3018 emitAUT(AuthKey, AArch64::X16, AArch64::X17);
3020 if (!STI->hasFPAC())
3021 emitPtrauthCheckAuthenticatedValue(AArch64::X16, AArch64::X17, AuthKey,
3022 AArch64PAuth::AuthCheckMethod::XPAC);
3024 EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
3025 .addReg(AArch64::X16)
3026 .addReg(AArch64::X16)
3030 EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
3031 .addReg(AArch64::X16)
3032 .addReg(AArch64::X16)
3037 emitAddImm(AArch64::X16,
Offset, AArch64::X17);
3038 Register DiscReg = emitPtrauthDiscriminator(Disc, AddrDisc, AArch64::X17);
3040 emitPAC(
Key, AArch64::X16, DiscReg);
3043void AArch64AsmPrinter::LowerLOADgotAUTH(
const MachineInstr &
MI) {
3045 Register AuthResultReg = STI->hasFPAC() ? DstReg : AArch64::X16;
3046 const MachineOperand &GAMO =
MI.getOperand(1);
3053 MCInstBuilder(AArch64::ADR).addReg(AArch64::X17).
addOperand(GAMC));
3054 EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
3055 .addReg(AuthResultReg)
3056 .addReg(AArch64::X17)
3059 MachineOperand GAHiOp(GAMO);
3060 MachineOperand GALoOp(GAMO);
3064 MCOperand GAMCHi, GAMCLo;
3069 MCInstBuilder(AArch64::ADRP).addReg(AArch64::X17).
addOperand(GAMCHi));
3071 EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
3072 .addReg(AArch64::X17)
3073 .addReg(AArch64::X17)
3077 EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
3078 .addReg(AuthResultReg)
3079 .addReg(AArch64::X17)
3086 UndefWeakSym = createTempSymbol(
"undef_weak");
3088 MCInstBuilder(AArch64::CBZX)
3089 .addReg(AuthResultReg)
3097 emitAUT(AuthKey, AuthResultReg, AArch64::X17);
3102 if (!STI->hasFPAC()) {
3103 emitPtrauthCheckAuthenticatedValue(AuthResultReg, AArch64::X17, AuthKey,
3104 AArch64PAuth::AuthCheckMethod::XPAC);
3106 emitMovXReg(DstReg, AuthResultReg);
3111AArch64AsmPrinter::lowerBlockAddressConstant(
const BlockAddress &BA) {
3115 if (std::optional<uint16_t> BADisc =
3116 STI->getPtrAuthBlockAddressDiscriminatorIfEnabled(Fn))
3123void AArch64AsmPrinter::emitCBPseudoExpansion(
const MachineInstr *
MI) {
3127 switch (
MI->getOpcode()) {
3130 case AArch64::CBBAssertExt:
3134 case AArch64::CBHAssertExt:
3138 case AArch64::CBWPrr:
3141 case AArch64::CBXPrr:
3144 case AArch64::CBWPri:
3148 case AArch64::CBXPri:
3156 bool NeedsRegSwap =
false;
3157 bool NeedsImmDec =
false;
3158 bool NeedsImmInc =
false;
3160#define GET_CB_OPC(IsImm, Width, ImmCond, RegCond) \
3162 ? (Width == 32 ? AArch64::CB##ImmCond##Wri : AArch64::CB##ImmCond##Xri) \
3164 ? AArch64::CBB##RegCond##Wrr \
3165 : (Width == 16 ? AArch64::CBH##RegCond##Wrr \
3166 : (Width == 32 ? AArch64::CB##RegCond##Wrr \
3167 : AArch64::CB##RegCond##Xrr))))
3183 NeedsImmDec = IsImm;
3187 NeedsRegSwap = !IsImm;
3194 NeedsRegSwap = !IsImm;
3195 NeedsImmInc = IsImm;
3199 NeedsImmDec = IsImm;
3203 NeedsRegSwap = !IsImm;
3210 NeedsRegSwap = !IsImm;
3211 NeedsImmInc = IsImm;
3219 MCOperand Lhs, Rhs, Trgt;
3220 lowerOperand(
MI->getOperand(1), Lhs);
3221 lowerOperand(
MI->getOperand(2), Rhs);
3222 lowerOperand(
MI->getOperand(3), Trgt);
3226 assert(Lhs.
isReg() &&
"Expected register operand for CB");
3227 assert(Rhs.
isReg() &&
"Expected register operand for CB");
3230 }
else if (NeedsImmDec) {
3234 }
else if (NeedsImmInc) {
3244 "CB immediate operand out-of-bounds");
3247 EmitToStreamer(*OutStreamer, Inst);
3250void AArch64AsmPrinter::emitAtomicHintPseudoExpansion(
const MachineInstr *
MI) {
3253 unsigned Relaxed =
MI->getOperand(2).getImm();
3254 assert(
Relaxed < 2 &&
"Atomic hint relaxed immediate out-of-bounds");
3255 switch (
MI->getOpcode()) {
3256 case AArch64::ATOMIC_STORE_HINT_B:
3257 StOpc =
Relaxed ? AArch64::STRBBui : AArch64::STLRB;
3259 case AArch64::ATOMIC_STORE_HINT_H:
3260 StOpc =
Relaxed ? AArch64::STRHHui : AArch64::STLRH;
3262 case AArch64::ATOMIC_STORE_HINT_W:
3263 StOpc =
Relaxed ? AArch64::STRWui : AArch64::STLRW;
3265 case AArch64::ATOMIC_STORE_HINT_X:
3266 StOpc =
Relaxed ? AArch64::STRXui : AArch64::STLRX;
3273 MCInstBuilder(AArch64::HINT).addImm(
MI->getOperand(3).getImm()));
3276 Store.setOpcode(StOpc);
3279 Store.setFlags(
MI->getFlags());
3282 EmitToStreamer(*OutStreamer,
Store);
3285void AArch64AsmPrinter::emitAtomicHintPseudoExpansionRO(
3286 const MachineInstr *
MI) {
3288 assert(
MI->getOperand(5).getImm() == 1 &&
3289 "Atomic store addressing mode only supports relaxed stores");
3291 switch (
MI->getOpcode()) {
3292 case AArch64::ATOMIC_STORE_HINT_BroW:
3293 StOpc = AArch64::STRBBroW;
3295 case AArch64::ATOMIC_STORE_HINT_HroW:
3296 StOpc = AArch64::STRHHroW;
3298 case AArch64::ATOMIC_STORE_HINT_WroW:
3299 StOpc = AArch64::STRWroW;
3301 case AArch64::ATOMIC_STORE_HINT_XroW:
3302 StOpc = AArch64::STRXroW;
3304 case AArch64::ATOMIC_STORE_HINT_SroW:
3305 StOpc = AArch64::STRSroW;
3307 case AArch64::ATOMIC_STORE_HINT_DroW:
3308 StOpc = AArch64::STRDroW;
3310 case AArch64::ATOMIC_STORE_HINT_BroX:
3311 StOpc = AArch64::STRBBroX;
3313 case AArch64::ATOMIC_STORE_HINT_HroX:
3314 StOpc = AArch64::STRHHroX;
3316 case AArch64::ATOMIC_STORE_HINT_WroX:
3317 StOpc = AArch64::STRWroX;
3319 case AArch64::ATOMIC_STORE_HINT_XroX:
3320 StOpc = AArch64::STRXroX;
3322 case AArch64::ATOMIC_STORE_HINT_SroX:
3323 StOpc = AArch64::STRSroX;
3325 case AArch64::ATOMIC_STORE_HINT_DroX:
3326 StOpc = AArch64::STRDroX;
3333 MCInstBuilder(AArch64::HINT).addImm(
MI->getOperand(6).getImm()));
3336 Store.setOpcode(StOpc);
3342 Store.setFlags(
MI->getFlags());
3343 EmitToStreamer(*OutStreamer,
Store);
3346void AArch64AsmPrinter::emitAtomicHintPseudoExpansionImm(
3347 const MachineInstr *
MI) {
3349 assert(
MI->getOperand(3).getImm() == 1 &&
3350 "Atomic store addressing mode only supports relaxed stores");
3352 switch (
MI->getOpcode()) {
3353 case AArch64::ATOMIC_STORE_HINT_Bui:
3354 StOpc = AArch64::STRBBui;
3356 case AArch64::ATOMIC_STORE_HINT_Hui:
3357 StOpc = AArch64::STRHHui;
3359 case AArch64::ATOMIC_STORE_HINT_Wui:
3360 StOpc = AArch64::STRWui;
3362 case AArch64::ATOMIC_STORE_HINT_Xui:
3363 StOpc = AArch64::STRXui;
3365 case AArch64::ATOMIC_STORE_HINT_Sui:
3366 StOpc = AArch64::STRSui;
3368 case AArch64::ATOMIC_STORE_HINT_Dui:
3369 StOpc = AArch64::STRDui;
3371 case AArch64::ATOMIC_STORE_HINT_Bi:
3372 StOpc = AArch64::STURBBi;
3374 case AArch64::ATOMIC_STORE_HINT_Hi:
3375 StOpc = AArch64::STURHHi;
3377 case AArch64::ATOMIC_STORE_HINT_Wi:
3378 StOpc = AArch64::STURWi;
3380 case AArch64::ATOMIC_STORE_HINT_Xi:
3381 StOpc = AArch64::STURXi;
3383 case AArch64::ATOMIC_STORE_HINT_Si:
3384 StOpc = AArch64::STURSi;
3386 case AArch64::ATOMIC_STORE_HINT_Di:
3387 StOpc = AArch64::STURDi;
3394 MCInstBuilder(AArch64::HINT).addImm(
MI->getOperand(4).getImm()));
3397 Store.setOpcode(StOpc);
3401 Store.setFlags(
MI->getFlags());
3402 EmitToStreamer(*OutStreamer,
Store);
3407#include "AArch64GenMCPseudoLowering.inc"
3409void AArch64AsmPrinter::EmitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3416void AArch64AsmPrinter::emitInstruction(
const MachineInstr *
MI) {
3417 AArch64_MC::verifyInstructionPredicates(
MI->getOpcode(), STI->
getFeatureBits());
3422 assert(STI->getInstrInfo()->getInstSizeInBytes(*
MI) >= InstsEmitted * 4);
3427 if (MCInst OutInst; lowerPseudoInstExpansion(
MI, OutInst)) {
3428 EmitToStreamer(*OutStreamer, OutInst);
3432 if (
MI->getOpcode() == AArch64::ADRP) {
3433 for (
auto &Opd :
MI->operands()) {
3434 if (Opd.isSymbol() && StringRef(Opd.getSymbolName()) ==
3435 "swift_async_extendedFramePointerFlags") {
3436 ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags =
true;
3443 MCSymbol *LOHLabel = createTempSymbol(
"loh");
3445 LOHInstToLabel[
MI] = LOHLabel;
3449 AArch64TargetStreamer *TS =
3452 switch (
MI->getOpcode()) {
3455 "Unhandled tail call instruction");
3457 case AArch64::READ_REGISTER_GPR64:
3461 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ORRXrs)
3462 .addReg(
MI->getOperand(0).getReg())
3463 .addReg(AArch64::XZR)
3464 .addReg(
MI->getOperand(1).getImm())
3467 case AArch64::READ_REGISTER_FPR64:
3469 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::FMOVDr)
3470 .addReg(
MI->getOperand(0).getReg())
3471 .addReg(
MI->getOperand(1).getImm()));
3473 case AArch64::HINT: {
3478 if (CurrentPatchableFunctionEntrySym &&
3479 CurrentPatchableFunctionEntrySym == CurrentFnBegin &&
3481 int64_t
Imm =
MI->getOperand(0).getImm();
3482 if (
Imm == 32 ||
Imm == 34 ||
Imm == 36 ||
Imm == 38) {
3484 MCInstLowering.
Lower(
MI, Inst);
3485 EmitToStreamer(*OutStreamer, Inst);
3486 CurrentPatchableFunctionEntrySym = createTempSymbol(
"patch");
3487 OutStreamer->
emitLabel(CurrentPatchableFunctionEntrySym);
3493 case AArch64::MOVMCSym: {
3494 Register DestReg =
MI->getOperand(0).getReg();
3495 const MachineOperand &MO_Sym =
MI->getOperand(1);
3496 MachineOperand Hi_MOSym(MO_Sym), Lo_MOSym(MO_Sym);
3497 MCOperand Hi_MCSym, Lo_MCSym;
3510 EmitToStreamer(*OutStreamer, MovZ);
3518 EmitToStreamer(*OutStreamer, MovK);
3521 case AArch64::MOVIv2d_ns:
3529 if (STI->hasZeroCycleZeroingFPWorkaround() &&
3530 MI->getOperand(1).getImm() == 0) {
3532 TmpInst.
setOpcode(AArch64::MOVIv16b_ns);
3535 EmitToStreamer(*OutStreamer, TmpInst);
3540 case AArch64::DBG_VALUE:
3541 case AArch64::DBG_VALUE_LIST:
3543 SmallString<128> TmpStr;
3544 raw_svector_ostream OS(TmpStr);
3545 PrintDebugValueComment(
MI, OS);
3550 case AArch64::EMITBKEY: {
3552 if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
3553 ExceptionHandlingType != ExceptionHandling::ARM)
3556 if (getFunctionCFISectionType(*MF) == CFISection::None)
3563 case AArch64::EMITMTETAGGED: {
3565 if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
3566 ExceptionHandlingType != ExceptionHandling::ARM)
3569 if (getFunctionCFISectionType(*MF) != CFISection::None)
3574 case AArch64::AUTx16x17: {
3576 const Register Scratch = AArch64::X17;
3578 auto AuthSchema = PtrAuthSchema::CreateImmReg(
3580 MI->getOperand(1).getImm(),
MI->getOperand(2));
3582 emitPtrauthAuthResign(Pointer, Scratch, AuthSchema, std::nullopt,
3583 std::nullopt,
MI->getDeactivationSymbol());
3587 case AArch64::AUTxMxN: {
3589 const Register Scratch =
MI->getOperand(1).getReg();
3591 auto AuthSchema = PtrAuthSchema::CreateImmReg(
3593 MI->getOperand(4).getImm(),
MI->getOperand(5));
3595 emitPtrauthAuthResign(Pointer, Scratch, AuthSchema, std::nullopt,
3596 std::nullopt,
MI->getDeactivationSymbol());
3600 case AArch64::AUTPAC: {
3602 const Register Scratch = AArch64::X17;
3604 auto AuthSchema = PtrAuthSchema::CreateImmReg(
3606 MI->getOperand(1).getImm(),
MI->getOperand(2));
3608 auto SignSchema = PtrAuthSchema::CreateImmReg(
3610 MI->getOperand(4).getImm(),
MI->getOperand(5));
3612 emitPtrauthAuthResign(Pointer, Scratch, AuthSchema, SignSchema,
3613 std::nullopt,
MI->getDeactivationSymbol());
3617 case AArch64::AUTPCPAC: {
3618 auto AuthSchema = PtrAuthSchema::CreateRegReg(
3622 auto SignSchema = PtrAuthSchema::CreateImmReg(
3624 MI->getOperand(2).getImm(),
MI->getOperand(3));
3626 emitPtrauthAuthResign(AArch64::X17, AArch64::X16,
3627 AuthSchema, SignSchema, std::nullopt,
3628 MI->getDeactivationSymbol());
3632 case AArch64::AUTRELLOADPAC: {
3634 const Register Scratch = AArch64::X17;
3636 auto AuthSchema = PtrAuthSchema::CreateImmReg(
3638 MI->getOperand(1).getImm(),
MI->getOperand(2));
3640 auto SignSchema = PtrAuthSchema::CreateImmReg(
3642 MI->getOperand(4).getImm(),
MI->getOperand(5));
3644 emitPtrauthAuthResign(Pointer, Scratch, AuthSchema, SignSchema,
3645 MI->getOperand(6).getImm(),
3646 MI->getDeactivationSymbol());
3652 emitPtrauthSign(
MI);
3655 case AArch64::LOADauthptrstatic:
3656 LowerLOADauthptrstatic(*
MI);
3659 case AArch64::LOADgotPAC:
3660 case AArch64::MOVaddrPAC:
3661 LowerMOVaddrPAC(*
MI);
3664 case AArch64::LOADgotAUTH:
3665 LowerLOADgotAUTH(*
MI);
3670 emitPtrauthBranch(
MI);
3676 case AArch64::AUTH_TCRETURN:
3677 case AArch64::AUTH_TCRETURN_BTI: {
3680 const uint64_t Disc =
MI->getOperand(3).getImm();
3682 Register AddrDisc =
MI->getOperand(4).getReg();
3684 Register ScratchReg =
Callee == AArch64::X16 ? AArch64::X17 : AArch64::X16;
3686 emitPtrauthTailCallHardening(
MI);
3689 if (Callee == AddrDisc)
3696 bool AddrDiscIsImplicitDef =
3697 AddrDisc == AArch64::X16 || AddrDisc == AArch64::X17;
3698 Register DiscReg = emitPtrauthDiscriminator(Disc, AddrDisc, ScratchReg,
3699 AddrDiscIsImplicitDef);
3700 emitBLRA(
false,
Key, Callee, DiscReg);
3704 case AArch64::TCRETURNri:
3705 case AArch64::TCRETURNrix16x17:
3706 case AArch64::TCRETURNrix17:
3707 case AArch64::TCRETURNrinotx16:
3708 case AArch64::TCRETURNriALL: {
3709 emitPtrauthTailCallHardening(
MI);
3711 recordIfImportCall(
MI);
3715 EmitToStreamer(*OutStreamer, TmpInst);
3718 case AArch64::TCRETURNdi: {
3719 emitPtrauthTailCallHardening(
MI);
3723 recordIfImportCall(
MI);
3727 EmitToStreamer(*OutStreamer, TmpInst);
3730 case AArch64::SpeculationBarrierISBDSBEndBB: {
3735 EmitToStreamer(*OutStreamer, TmpInstDSB);
3739 EmitToStreamer(*OutStreamer, TmpInstISB);
3742 case AArch64::SpeculationBarrierSBEndBB: {
3746 EmitToStreamer(*OutStreamer, TmpInstSB);
3749 case AArch64::TLSDESC_AUTH_CALLSEQ: {
3757 const MachineOperand &MO_Sym =
MI->getOperand(0);
3758 MachineOperand MO_TLSDESC_LO12(MO_Sym), MO_TLSDESC(MO_Sym);
3759 MCOperand Sym, SymTLSDescLo12, SymTLSDesc;
3763 MCInstLowering.
lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
3770 EmitToStreamer(*OutStreamer, Adrp);
3778 EmitToStreamer(*OutStreamer, Ldr);
3781 Add.setOpcode(AArch64::ADDXri);
3784 Add.addOperand(SymTLSDescLo12);
3786 EmitToStreamer(*OutStreamer,
Add);
3790 MCInst TLSAuthDescCall;
3791 TLSAuthDescCall.
setOpcode(AArch64::TLSAUTHDESCCALL);
3793 EmitToStreamer(*OutStreamer, TLSAuthDescCall);
3802 EmitToStreamer(*OutStreamer, Blraa);
3806 case AArch64::TLSDESC_CALLSEQ: {
3814 const MachineOperand &MO_Sym =
MI->getOperand(0);
3815 MachineOperand MO_TLSDESC_LO12(MO_Sym), MO_TLSDESC(MO_Sym);
3816 MCOperand Sym, SymTLSDescLo12, SymTLSDesc;
3820 MCInstLowering.
lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
3827 EmitToStreamer(*OutStreamer, Adrp);
3830 if (STI->isTargetILP32()) {
3840 EmitToStreamer(*OutStreamer, Ldr);
3843 if (STI->isTargetILP32()) {
3844 Add.setOpcode(AArch64::ADDWri);
3848 Add.setOpcode(AArch64::ADDXri);
3852 Add.addOperand(SymTLSDescLo12);
3854 EmitToStreamer(*OutStreamer,
Add);
3859 TLSDescCall.
setOpcode(AArch64::TLSDESCCALL);
3861 EmitToStreamer(*OutStreamer, TLSDescCall);
3869 EmitToStreamer(*OutStreamer, Blr);
3874 case AArch64::JumpTableDest32:
3875 case AArch64::JumpTableDest16:
3876 case AArch64::JumpTableDest8:
3877 LowerJumpTableDest(*OutStreamer, *
MI);
3880 case AArch64::BR_JumpTable:
3881 LowerHardenedBRJumpTable(*
MI);
3884 case AArch64::FMOVH0:
3885 case AArch64::FMOVS0:
3886 case AArch64::FMOVD0:
3890 case AArch64::MOPSMemoryCopyPseudo:
3891 case AArch64::MOPSMemoryMovePseudo:
3892 case AArch64::MOPSMemorySetPseudo:
3893 case AArch64::MOPSMemorySetTaggingPseudo:
3894 LowerMOPS(*OutStreamer, *
MI);
3897 case TargetOpcode::STACKMAP:
3898 return LowerSTACKMAP(*OutStreamer, SM, *
MI);
3900 case TargetOpcode::PATCHPOINT:
3901 return LowerPATCHPOINT(*OutStreamer, SM, *
MI);
3903 case TargetOpcode::STATEPOINT:
3904 return LowerSTATEPOINT(*OutStreamer, SM, *
MI);
3906 case TargetOpcode::FAULTING_OP:
3907 return LowerFAULTING_OP(*
MI);
3909 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
3910 LowerPATCHABLE_FUNCTION_ENTER(*
MI);
3913 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
3914 LowerPATCHABLE_FUNCTION_EXIT(*
MI);
3917 case TargetOpcode::PATCHABLE_TAIL_CALL:
3918 LowerPATCHABLE_TAIL_CALL(*
MI);
3920 case TargetOpcode::PATCHABLE_EVENT_CALL:
3921 return LowerPATCHABLE_EVENT_CALL(*
MI,
false);
3922 case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
3923 return LowerPATCHABLE_EVENT_CALL(*
MI,
true);
3925 case AArch64::KCFI_CHECK:
3926 LowerKCFI_CHECK(*
MI);
3929 case AArch64::HWASAN_CHECK_MEMACCESS:
3930 case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
3931 case AArch64::HWASAN_CHECK_MEMACCESS_FIXEDSHADOW:
3932 case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW:
3933 LowerHWASAN_CHECK_MEMACCESS(*
MI);
3936 case AArch64::SEH_StackAlloc:
3940 case AArch64::SEH_SaveFPLR:
3944 case AArch64::SEH_SaveFPLR_X:
3945 assert(
MI->getOperand(0).getImm() < 0 &&
3946 "Pre increment SEH opcode must have a negative offset");
3950 case AArch64::SEH_SaveReg:
3952 MI->getOperand(1).getImm());
3955 case AArch64::SEH_SaveReg_X:
3956 assert(
MI->getOperand(1).getImm() < 0 &&
3957 "Pre increment SEH opcode must have a negative offset");
3959 -
MI->getOperand(1).getImm());
3962 case AArch64::SEH_SaveRegP:
3963 if (
MI->getOperand(1).getImm() == 30 &&
MI->getOperand(0).getImm() >= 19 &&
3964 MI->getOperand(0).getImm() <= 28) {
3965 assert((
MI->getOperand(0).getImm() - 19) % 2 == 0 &&
3966 "Register paired with LR must be odd");
3968 MI->getOperand(2).getImm());
3971 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
3972 "Non-consecutive registers not allowed for save_regp");
3974 MI->getOperand(2).getImm());
3977 case AArch64::SEH_SaveRegP_X:
3978 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
3979 "Non-consecutive registers not allowed for save_regp_x");
3980 assert(
MI->getOperand(2).getImm() < 0 &&
3981 "Pre increment SEH opcode must have a negative offset");
3983 -
MI->getOperand(2).getImm());
3986 case AArch64::SEH_SaveFReg:
3988 MI->getOperand(1).getImm());
3991 case AArch64::SEH_SaveFReg_X:
3992 assert(
MI->getOperand(1).getImm() < 0 &&
3993 "Pre increment SEH opcode must have a negative offset");
3995 -
MI->getOperand(1).getImm());
3998 case AArch64::SEH_SaveFRegP:
3999 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
4000 "Non-consecutive registers not allowed for save_regp");
4002 MI->getOperand(2).getImm());
4005 case AArch64::SEH_SaveFRegP_X:
4006 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
4007 "Non-consecutive registers not allowed for save_regp_x");
4008 assert(
MI->getOperand(2).getImm() < 0 &&
4009 "Pre increment SEH opcode must have a negative offset");
4011 -
MI->getOperand(2).getImm());
4014 case AArch64::SEH_SetFP:
4018 case AArch64::SEH_AddFP:
4022 case AArch64::SEH_Nop:
4026 case AArch64::SEH_PrologEnd:
4030 case AArch64::SEH_EpilogStart:
4034 case AArch64::SEH_EpilogEnd:
4038 case AArch64::SEH_PACSignLR:
4042 case AArch64::SEH_SaveAnyRegI:
4043 assert(
MI->getOperand(1).getImm() <= 1008 &&
4044 "SaveAnyRegQP SEH opcode offset must fit into 6 bits");
4046 MI->getOperand(1).getImm());
4049 case AArch64::SEH_SaveAnyRegIP:
4050 assert(
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1 &&
4051 "Non-consecutive registers not allowed for save_any_reg");
4052 assert(
MI->getOperand(2).getImm() <= 1008 &&
4053 "SaveAnyRegQP SEH opcode offset must fit into 6 bits");
4055 MI->getOperand(2).getImm());
4058 case AArch64::SEH_SaveAnyRegQP:
4059 assert(
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1 &&
4060 "Non-consecutive registers not allowed for save_any_reg");
4061 assert(
MI->getOperand(2).getImm() >= 0 &&
4062 "SaveAnyRegQP SEH opcode offset must be non-negative");
4063 assert(
MI->getOperand(2).getImm() <= 1008 &&
4064 "SaveAnyRegQP SEH opcode offset must fit into 6 bits");
4066 MI->getOperand(2).getImm());
4069 case AArch64::SEH_SaveAnyRegQPX:
4070 assert(
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1 &&
4071 "Non-consecutive registers not allowed for save_any_reg");
4072 assert(
MI->getOperand(2).getImm() < 0 &&
4073 "SaveAnyRegQPX SEH opcode offset must be negative");
4074 assert(
MI->getOperand(2).getImm() >= -1008 &&
4075 "SaveAnyRegQPX SEH opcode offset must fit into 6 bits");
4077 -
MI->getOperand(2).getImm());
4080 case AArch64::SEH_AllocZ:
4081 assert(
MI->getOperand(0).getImm() >= 0 &&
4082 "AllocZ SEH opcode offset must be non-negative");
4083 assert(
MI->getOperand(0).getImm() <= 255 &&
4084 "AllocZ SEH opcode offset must fit into 8 bits");
4088 case AArch64::SEH_SaveZReg:
4089 assert(
MI->getOperand(1).getImm() >= 0 &&
4090 "SaveZReg SEH opcode offset must be non-negative");
4091 assert(
MI->getOperand(1).getImm() <= 255 &&
4092 "SaveZReg SEH opcode offset must fit into 8 bits");
4094 MI->getOperand(1).getImm());
4097 case AArch64::SEH_SavePReg:
4098 assert(
MI->getOperand(1).getImm() >= 0 &&
4099 "SavePReg SEH opcode offset must be non-negative");
4100 assert(
MI->getOperand(1).getImm() <= 255 &&
4101 "SavePReg SEH opcode offset must fit into 8 bits");
4103 MI->getOperand(1).getImm());
4108 recordIfImportCall(
MI);
4110 MCInstLowering.
Lower(
MI, TmpInst);
4111 EmitToStreamer(*OutStreamer, TmpInst);
4114 case AArch64::CBWPri:
4115 case AArch64::CBXPri:
4116 case AArch64::CBBAssertExt:
4117 case AArch64::CBHAssertExt:
4118 case AArch64::CBWPrr:
4119 case AArch64::CBXPrr:
4120 emitCBPseudoExpansion(
MI);
4122 case AArch64::ATOMIC_STORE_HINT_B:
4123 case AArch64::ATOMIC_STORE_HINT_H:
4124 case AArch64::ATOMIC_STORE_HINT_W:
4125 case AArch64::ATOMIC_STORE_HINT_X:
4126 emitAtomicHintPseudoExpansion(
MI);
4128 case AArch64::ATOMIC_STORE_HINT_BroW:
4129 case AArch64::ATOMIC_STORE_HINT_HroW:
4130 case AArch64::ATOMIC_STORE_HINT_WroW:
4131 case AArch64::ATOMIC_STORE_HINT_XroW:
4132 case AArch64::ATOMIC_STORE_HINT_SroW:
4133 case AArch64::ATOMIC_STORE_HINT_DroW:
4134 case AArch64::ATOMIC_STORE_HINT_BroX:
4135 case AArch64::ATOMIC_STORE_HINT_HroX:
4136 case AArch64::ATOMIC_STORE_HINT_WroX:
4137 case AArch64::ATOMIC_STORE_HINT_XroX:
4138 case AArch64::ATOMIC_STORE_HINT_SroX:
4139 case AArch64::ATOMIC_STORE_HINT_DroX:
4140 emitAtomicHintPseudoExpansionRO(
MI);
4142 case AArch64::ATOMIC_STORE_HINT_Bui:
4143 case AArch64::ATOMIC_STORE_HINT_Hui:
4144 case AArch64::ATOMIC_STORE_HINT_Wui:
4145 case AArch64::ATOMIC_STORE_HINT_Xui:
4146 case AArch64::ATOMIC_STORE_HINT_Sui:
4147 case AArch64::ATOMIC_STORE_HINT_Dui:
4148 case AArch64::ATOMIC_STORE_HINT_Bi:
4149 case AArch64::ATOMIC_STORE_HINT_Hi:
4150 case AArch64::ATOMIC_STORE_HINT_Wi:
4151 case AArch64::ATOMIC_STORE_HINT_Xi:
4152 case AArch64::ATOMIC_STORE_HINT_Si:
4153 case AArch64::ATOMIC_STORE_HINT_Di:
4154 emitAtomicHintPseudoExpansionImm(
MI);
4158 if (emitDeactivationSymbolRelocation(
MI->getDeactivationSymbol()))
4163 MCInstLowering.
Lower(
MI, TmpInst);
4164 EmitToStreamer(*OutStreamer, TmpInst);
4167void AArch64AsmPrinter::recordIfImportCall(
4168 const llvm::MachineInstr *BranchInst) {
4169 if (!EnableImportCallOptimization)
4173 if (GV && GV->hasDLLImportStorageClass()) {
4174 auto *CallSiteSymbol = MMI->getContext().createNamedTempSymbol(
"impcall");
4179 .push_back({CallSiteSymbol, CalledSymbol});
4183void AArch64AsmPrinter::emitMachOIFuncStubBody(
Module &M,
const GlobalIFunc &GI,
4184 MCSymbol *LazyPointer) {
4201 EmitToStreamer(Adrp);
4209 MCOperand SymPageOff;
4216 EmitToStreamer(Ldr);
4219 EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
4220 .addReg(AArch64::X16)
4221 .addReg(AArch64::X16)
4224 EmitToStreamer(MCInstBuilder(TM.getTargetTriple().isArm64e() ? AArch64::BRAAZ
4226 .addReg(AArch64::X16));
4229void AArch64AsmPrinter::emitMachOIFuncStubHelperBody(
Module &M,
4230 const GlobalIFunc &GI,
4231 MCSymbol *LazyPointer) {
4263 EmitToStreamer(MCInstBuilder(AArch64::STPXpre)
4264 .addReg(AArch64::SP)
4265 .addReg(AArch64::FP)
4266 .addReg(AArch64::LR)
4267 .addReg(AArch64::SP)
4270 EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
4271 .addReg(AArch64::FP)
4272 .addReg(AArch64::SP)
4276 for (
int I = 0;
I != 4; ++
I)
4277 EmitToStreamer(MCInstBuilder(AArch64::STPXpre)
4278 .addReg(AArch64::SP)
4279 .addReg(AArch64::X1 + 2 *
I)
4280 .addReg(AArch64::X0 + 2 *
I)
4281 .addReg(AArch64::SP)
4284 for (
int I = 0;
I != 4; ++
I)
4285 EmitToStreamer(MCInstBuilder(AArch64::STPDpre)
4286 .addReg(AArch64::SP)
4287 .addReg(AArch64::D1 + 2 *
I)
4288 .addReg(AArch64::D0 + 2 *
I)
4289 .addReg(AArch64::SP)
4293 MCInstBuilder(AArch64::BL)
4306 EmitToStreamer(Adrp);
4314 MCOperand SymPageOff;
4321 EmitToStreamer(Ldr);
4324 EmitToStreamer(MCInstBuilder(AArch64::STRXui)
4325 .addReg(AArch64::X0)
4326 .addReg(AArch64::X16)
4329 EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
4330 .addReg(AArch64::X16)
4331 .addReg(AArch64::X0)
4335 for (
int I = 3;
I != -1; --
I)
4336 EmitToStreamer(MCInstBuilder(AArch64::LDPDpost)
4337 .addReg(AArch64::SP)
4338 .addReg(AArch64::D1 + 2 *
I)
4339 .addReg(AArch64::D0 + 2 *
I)
4340 .addReg(AArch64::SP)
4343 for (
int I = 3;
I != -1; --
I)
4344 EmitToStreamer(MCInstBuilder(AArch64::LDPXpost)
4345 .addReg(AArch64::SP)
4346 .addReg(AArch64::X1 + 2 *
I)
4347 .addReg(AArch64::X0 + 2 *
I)
4348 .addReg(AArch64::SP)
4351 EmitToStreamer(MCInstBuilder(AArch64::LDPXpost)
4352 .addReg(AArch64::SP)
4353 .addReg(AArch64::FP)
4354 .addReg(AArch64::LR)
4355 .addReg(AArch64::SP)
4358 EmitToStreamer(MCInstBuilder(TM.getTargetTriple().isArm64e() ? AArch64::BRAAZ
4360 .addReg(AArch64::X16));
4363const MCExpr *AArch64AsmPrinter::lowerConstant(
const Constant *CV,
4364 const Constant *BaseCV,
4374char AArch64AsmPrinter::ID = 0;
4377 "AArch64 Assembly Printer",
false,
false)
4381LLVMInitializeAArch64AsmPrinter() {
4391 AArch64AsmPrinter &
AsmPrinter =
static_cast<AArch64AsmPrinter &
>(
4401 AArch64AsmPrinter &
AsmPrinter =
static_cast<AArch64AsmPrinter &
>(
4412 AArch64AsmPrinter &
AsmPrinter =
static_cast<AArch64AsmPrinter &
>(
#define GET_CB_OPC(IsImm, Width, ImmCond, RegCond)
static void emitAuthenticatedPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, const MCExpr *StubAuthPtrRef)
static bool getOptionalBooleanModuleFlag(Module &M, StringRef Name)
static bool targetSupportsIRelativeRelocation(const Triple &TT)
static PtrauthCheckMode getCheckMode(const MachineFunction *MF)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
print mir2vec MIR2Vec Vocabulary Printer Pass
Machine Check Debug Module
Register const TargetRegisterInfo * TRI
Promote Memory to Register
ModuleAnalysisManager MAM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static SDValue lowerConstant(SDValue Op, SelectionDAG &DAG, const RISCVSubtarget &Subtarget)
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
This file defines the SmallString class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
std::unique_ptr< MCStreamer > && Streamer
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static bool printAsmMRegister(const X86AsmPrinter &P, const MachineInstr &MI, const MachineOperand &MO, char Mode, raw_ostream &O)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
static const AArch64AuthMCExpr * create(const MCExpr *Expr, uint16_t Discriminator, AArch64PACKey::ID Key, bool HasAddressDiversity, MCContext &Ctx, SMLoc Loc=SMLoc())
const SetOfInstructions & getLOHRelated() const
unsigned getJumpTableEntrySize(int Idx) const
MCSymbol * getJumpTableEntryPCRelSymbol(int Idx) const
static bool shouldSignReturnAddress(SignReturnAddress Condition, bool IsLRSpilled)
std::optional< std::string > getOutliningStyle() const
const MILOHContainer & getLOHContainer() const
void setJumpTableEntryInfo(int Idx, unsigned Size, MCSymbol *PCRelSym)
bool shouldSignWithBKey() const
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=AArch64::NoRegAltName)
static bool isTailCallReturnInst(const MachineInstr &MI)
Returns true if MI is one of the TCRETURN* instructions.
AArch64MCInstLower - This class is used to lower an MachineInstr into an MCInst.
MCSymbol * GetGlobalValueSymbol(const GlobalValue *GV, unsigned TargetFlags) const
void Lower(const MachineInstr *MI, MCInst &OutMI) const
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const
const AArch64Options & getCLOpts() const
virtual void emitARM64WinCFISaveRegP(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveRegPX(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveAnyRegQP(unsigned Reg, int Offset)
virtual void emitAttributesSubsection(StringRef VendorName, AArch64BuildAttributes::SubsectionOptional IsOptional, AArch64BuildAttributes::SubsectionType ParameterType)
Build attributes implementation.
virtual void emitARM64WinCFISavePReg(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveFReg(unsigned Reg, int Offset)
virtual void emitARM64WinCFIPACSignLR()
virtual void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset)
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 emitARM64WinCFIAllocZ(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 emitARM64WinCFISaveZReg(unsigned Reg, int Offset)
virtual void emitARM64WinCFIPrologEnd()
virtual void emitARM64WinCFISaveReg(unsigned Reg, int Offset)
virtual void emitARM64WinCFINop()
virtual void emitARM64WinCFISaveLRPair(unsigned Reg, int Offset)
virtual void emitAttribute(StringRef VendorName, unsigned Tag, unsigned Value, std::string String)
virtual void emitARM64WinCFIEpilogStart()
virtual void emitARM64WinCFISaveAnyRegIP(unsigned Reg, int Offset)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
void setPreservesAll()
Set by analyses that do not transform their input at all.
const T & front() const
Get the first element.
bool empty() const
Check if the array is empty.
This class is intended to be used as a driving class for all asm writers.
virtual void emitGlobalAlias(const Module &M, const GlobalAlias &GA)
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
virtual const MCExpr * lowerConstant(const Constant *CV, const Constant *BaseCV=nullptr, uint64_t Offset=0)
Lower the specified LLVM Constant to an MCExpr.
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
void getAnalysisUsage(AnalysisUsage &AU) const override
Record analysis usage.
bool doFinalization(Module &M) override
Shut down the asmprinter.
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
virtual void emitXXStructor(const DataLayout &DL, const Constant *CV)
Targets can override this to change how global constants that are part of a C++ static/global constru...
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.
virtual const MCExpr * lowerBlockAddressConstant(const BlockAddress &BA)
Lower the specified BlockAddress to an MCExpr.
Function * getFunction() const
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
@ AddrDiscriminator_CtorsDtors
Constant * getPointer() const
The pointer that is signed in this ptrauth signed pointer.
static LLVM_ABI ConstantPtrAuth * get(Constant *Ptr, ConstantInt *Key, ConstantInt *Disc, Constant *AddrDisc, Constant *DeactivationSymbol)
Return a pointer signed with the specified parameters.
ConstantInt * getKey() const
The Key ID, an i32 constant.
Constant * getDeactivationSymbol() const
bool hasAddressDiscriminator() const
Whether there is any non-null address discriminator.
ConstantInt * getDiscriminator() const
The integer discriminator, an i64 constant, or 0.
LLVM_ABI void recordFaultingOp(FaultKind FaultTy, const MCSymbol *FaultingLabel, const MCSymbol *HandlerLabel)
LLVM_ABI void serializeToFaultMapSection()
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
const Constant * getAliasee() const
const Constant * getResolver() const
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this GlobalObject.
bool hasLocalLinkage() const
bool hasExternalWeakLinkage() const
Type * getValueType() const
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
static const MCBinaryExpr * createLShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
LLVM_ABI MCSymbol * createLinkerPrivateSymbol(const Twine &Name)
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
MCSection * getDataSection() const
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getRegister(unsigned i) const
getRegister - Return the specified register in the class.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
static constexpr unsigned NonUniqueID
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Streaming machine code generation interface.
virtual void emitCFIBKeyFrame()
virtual bool popSection()
Restore the current and previous section from the section stack.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitRelocDirective(const MCExpr &Offset, StringRef Name, const MCExpr *Expr, SMLoc Loc={})
Record a relocation described by the .reloc directive.
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText.
MCContext & getContext() const
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
virtual void emitCFIMTETaggedFrame()
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
void pushSection()
Save the current and previous section on the section stack.
virtual void switchSection(MCSection *Section, uint32_t Subsec=0)
Set the current section where code is being emitted to Section.
MCSection * getCurrentSectionOnly() const
void emitRawText(const Twine &String)
If this file is backed by a assembly streamer, this dumps the specified string in the output ....
const FeatureBitset & getFeatureBits() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
LLVM_ABI void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
StringRef getName() const
getName - Get the symbol name.
const MCSymbol * getAddSym() const
int64_t getConstant() const
MachineInstrBundleIterator< const MachineInstr > const_iterator
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
CalledGlobalInfo tryGetCalledGlobal(const MachineInstr *MI) const
Tries to get the global and target flags for a call site, if the instruction is a call to a global.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MCContext & getContext() const
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...
const MachineBasicBlock & front() const
const MachineJumpTableInfo * getJumpTableInfo() const
getJumpTableInfo - Return the jump table info object for the current function.
bool readsRegister(Register Reg, const TargetRegisterInfo *TRI) const
Return true if the MachineInstr reads the specified register.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const MachineOperand & getOperand(unsigned i) const
const std::vector< MachineJumpTableEntry > & getJumpTables() const
ExprStubListTy getAuthGVStubList()
ExprStubListTy getAuthGVStubList()
unsigned getSubReg() const
static MachineOperand CreateMCSymbol(MCSymbol *Sym, unsigned TargetFlags=0)
const GlobalValue * getGlobal() const
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
void setOffset(int64_t Offset)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
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.
int64_t getOffset() const
Return the offset from the symbol in this operand.
This class implements a map that also provides access to all stored values in a deterministic order.
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
constexpr bool isValid() const
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
static SectionKind getMetadata()
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void push_back(const T &Elt)
LLVM_ABI void recordStatepoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a statepoint instruction.
LLVM_ABI void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
LLVM_ABI void recordStackMap(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
Represent a constant reference to a string, i.e.
constexpr const char * data() const
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.
bool regsOverlap(Register RegA, Register RegB) const
Returns true if the two registers are equal or alias each other.
Triple - Helper class for working with autoconf configuration names.
bool isFunctionTy() const
True if this is an instance of FunctionType.
LLVM Value Representation.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr, bool LookThroughIntToPtr=false) const
Accumulate the constant offset this value has compared to a base pointer.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI StringRef getVendorName(unsigned const Vendor)
@ 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.
PtrauthCheckMode
Ways to check pointer authentication auth/resign failures.
constexpr AArch64PACKey::ID InitFiniKey
PAuth key to be used with function pointers in .init_array and .fini_array.
AuthCheckMethod
Variants of check performed on an authenticated pointer.
constexpr unsigned InitFiniPointerConstantDiscriminator
Constant discriminator to be used with function pointers in .init_array and .fini_array.
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 ==...
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
SymbolStorageClass
Storage class tells where and what the symbol represents.
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
@ IMAGE_SYM_CLASS_STATIC
Static.
@ 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_PAUTH_PLATFORM_LLVM_LINUX
@ GNU_PROPERTY_AARCH64_FEATURE_1_BTI
@ GNU_PROPERTY_AARCH64_FEATURE_1_PAC
@ GNU_PROPERTY_AARCH64_FEATURE_1_GCS
@ S_REGULAR
S_REGULAR - Regular section.
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)
Extract a Value from Metadata, allowing null.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
NodeAddr< NodeBase * > Node
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.
LLVM_ABI std::optional< std::string > getArm64ECMangledFunctionName(StringRef Name)
Returns the ARM64EC mangled function name unless the input is already mangled.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
scope_exit(Callable) -> scope_exit< Callable >
@ Store
The extracted value is stored (ExtractElement only).
static unsigned getXPACOpcodeForKey(AArch64PACKey::ID K)
Return XPAC opcode to be used for a ptrauth strip using the given key.
Target & getTheAArch64beTarget()
std::string utostr(uint64_t X, bool isNeg=false)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
static unsigned getBranchOpcodeForKey(bool IsCall, AArch64PACKey::ID K, bool Zero)
Return B(L)RA opcode to be used for an authenticated branch or call using the given key,...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Target & getTheAArch64leTarget()
auto dyn_cast_or_null(const Y &Val)
Target & getTheAArch64_32Target()
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI void setupModuleAsmPrinter(Module &M, ModuleAnalysisManager &MAM, AsmPrinter &AsmPrinter)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
Target & getTheARM64_32Target()
static MCRegister getXRegFromWReg(MCRegister Reg)
Target & getTheARM64Target()
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
static MCRegister getXRegFromXRegTuple(MCRegister RegTuple)
static unsigned getPACOpcodeForKey(AArch64PACKey::ID K, bool Zero)
Return PAC opcode to be used for a ptrauth sign using the given key, or its PAC*Z variant that doesn'...
static MCRegister getWRegFromXReg(MCRegister Reg)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void setupMachineFunctionAsmPrinter(MachineFunctionAnalysisManager &MFAM, MachineFunction &MF, AsmPrinter &AsmPrinter)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
static unsigned getAUTOpcodeForKey(AArch64PACKey::ID K, bool Zero)
Return AUT opcode to be used for a ptrauth auth using the given key, or its AUT*Z variant that doesn'...
@ MCSA_WeakAntiDep
.weak_anti_dep (COFF)
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
@ MCSA_Hidden
.hidden (ELF)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
MCRegisterClass TargetRegisterClass
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Implement std::hash so that hash_code can be used in STL containers.
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...