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);
291 void emitAtomicFetchHintPseudoExpansion(
const MachineInstr *
MI);
293 void EmitToStreamer(MCStreamer &S,
const MCInst &Inst);
294 void EmitToStreamer(
const MCInst &Inst) {
295 EmitToStreamer(*OutStreamer, Inst);
300 void emitFunctionHeaderComment()
override;
302 void getAnalysisUsage(AnalysisUsage &AU)
const override {
308 if (
auto *PSIW = getAnalysisIfAvailable<ProfileSummaryInfoWrapperPass>())
309 PSI = &PSIW->getPSI();
311 getAnalysisIfAvailable<StaticDataProfileInfoWrapperPass>())
312 SDPI = &SDPIW->getStaticDataProfileInfo();
314 AArch64FI = MF.
getInfo<AArch64FunctionInfo>();
317 SetupMachineFunction(MF);
319 if (STI->isTargetCOFF()) {
326 OutStreamer->beginCOFFSymbolDef(CurrentFnSym);
327 OutStreamer->emitCOFFSymbolStorageClass(Scl);
328 OutStreamer->emitCOFFSymbolType(
Type);
329 OutStreamer->endCOFFSymbolDef();
343 const Constant *BaseCV =
nullptr,
347 void printOperand(
const MachineInstr *
MI,
unsigned OpNum, raw_ostream &O);
349 bool printAsmRegInClass(
const MachineOperand &MO,
353 bool PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNum,
354 const char *ExtraCode, raw_ostream &O)
override;
355 bool PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNum,
356 const char *ExtraCode, raw_ostream &O)
override;
358 void PrintDebugValueComment(
const MachineInstr *
MI, raw_ostream &OS);
360 void emitFunctionBodyEnd()
override;
361 void emitBasicBlockEnd(
const MachineBasicBlock &
MBB)
override;
362 void emitGlobalAlias(
const Module &M,
const GlobalAlias &GA)
override;
364 MCSymbol *GetCPISymbol(
unsigned CPID)
const override;
365 void emitEndOfAsmFile(
Module &M)
override;
367 AArch64FunctionInfo *AArch64FI =
nullptr;
382 void emitFMov0(
const MachineInstr &
MI);
383 void emitFMov0AsFMov(
const MachineInstr &
MI,
Register DestReg);
385 using MInstToMCSymbol = std::map<const MachineInstr *, MCSymbol *>;
387 MInstToMCSymbol LOHInstToLabel;
389 bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags()
const override {
390 return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags;
393 const MCSubtargetInfo *getIFuncMCSubtargetInfo()
const override {
397 void emitMachOIFuncStubBody(
Module &M,
const GlobalIFunc &GI,
398 MCSymbol *LazyPointer)
override;
399 void emitMachOIFuncStubHelperBody(
Module &M,
const GlobalIFunc &GI,
400 MCSymbol *LazyPointer)
override;
405 void recordIfImportCall(
const MachineInstr *BranchInst);
412 Metadata *Flag = M.getModuleFlag(Name);
417 assert((
Value == 0 ||
Value == 1) &&
"Boolean flag is expected, if present");
421void AArch64AsmPrinter::emitStartOfAsmFile(
Module &M) {
422 const Triple &
TT =
M.getTargetTriple();
424 if (
TT.isOSBinFormatCOFF()) {
425 emitCOFFFeatureSymbol(M);
426 emitCOFFReplaceableFunctionData(M);
428 if (
M.getModuleFlag(
"import-call-optimization"))
429 EnableImportCallOptimization =
true;
434 M,
"ptrauth-init-fini-address-discrimination");
436 if (!
TT.isOSBinFormatELF())
441 static_cast<AArch64TargetStreamer *
>(OutStreamer->getTargetStreamer());
444 unsigned BAFlags = 0;
445 unsigned GNUFlags = 0;
447 M.getModuleFlag(
"branch-target-enforcement"))) {
448 if (!BTE->isZero()) {
449 BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_BTI_Flag;
455 M.getModuleFlag(
"guarded-control-stack"))) {
456 if (!GCS->isZero()) {
457 BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_GCS_Flag;
463 M.getModuleFlag(
"sign-return-address"))) {
464 if (!Sign->isZero()) {
465 BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_PAC_Flag;
472 M.getModuleFlag(
"aarch64-elf-pauthabi-platform"))) {
473 PAuthABIPlatform = PAP->getZExtValue();
478 M.getModuleFlag(
"aarch64-elf-pauthabi-version"))) {
479 PAuthABIVersion = PAV->getZExtValue();
487 PAuthABIVersion == 0) {
493 emitAttributes(BAFlags, PAuthABIPlatform, PAuthABIVersion, TS);
495 TS->emitNoteSection(GNUFlags, PAuthABIPlatform, PAuthABIVersion);
498void AArch64AsmPrinter::emitFunctionHeaderComment() {
499 const AArch64FunctionInfo *FI = MF->
getInfo<AArch64FunctionInfo>();
501 if (OutlinerString != std::nullopt)
502 OutStreamer->getCommentOS() <<
' ' << OutlinerString;
505void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr &
MI)
508 if (
F.hasFnAttribute(
"patchable-function-entry")) {
510 if (
F.getFnAttribute(
"patchable-function-entry")
512 .getAsInteger(10, Num))
518 emitSled(
MI, SledKind::FUNCTION_ENTER);
521void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr &
MI) {
522 emitSled(
MI, SledKind::FUNCTION_EXIT);
525void AArch64AsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr &
MI) {
526 emitSled(
MI, SledKind::TAIL_CALL);
529void AArch64AsmPrinter::emitSled(
const MachineInstr &
MI, SledKind Kind) {
530 static const int8_t NoopsInSledCount = 7;
551 OutStreamer->emitCodeAlignment(
Align(4), getSubtargetInfo());
552 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
553 OutStreamer->emitLabel(CurSled);
554 auto Target = OutContext.createTempSymbol();
559 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::B).addImm(8));
561 for (int8_t
I = 0;
I < NoopsInSledCount;
I++)
562 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::NOP));
564 OutStreamer->emitLabel(Target);
565 recordSled(CurSled,
MI, Kind, 2);
568void AArch64AsmPrinter::emitAttributes(
unsigned Flags,
571 AArch64TargetStreamer *TS) {
573 PAuthABIPlatform = (
uint64_t(-1) == PAuthABIPlatform) ? 0 : PAuthABIPlatform;
574 PAuthABIVersion = (
uint64_t(-1) == PAuthABIVersion) ? 0 : PAuthABIVersion;
576 if (PAuthABIPlatform || PAuthABIVersion) {
580 AArch64BuildAttributes::SubsectionOptional::REQUIRED,
581 AArch64BuildAttributes::SubsectionType::ULEB128);
585 PAuthABIPlatform,
"");
599 if (BTIValue || PACValue || GCSValue) {
603 AArch64BuildAttributes::SubsectionOptional::OPTIONAL,
604 AArch64BuildAttributes::SubsectionType::ULEB128);
632void AArch64AsmPrinter::LowerPATCHABLE_EVENT_CALL(
const MachineInstr &
MI,
634 auto &
O = *OutStreamer;
635 MCSymbol *CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
636 O.emitLabel(CurSled);
637 bool MachO = MMI->getModule()->getTargetTriple().isOSBinFormatMachO();
639 OutContext.getOrCreateSymbol(
640 Twine(MachO ?
"_" :
"") +
641 (Typed ?
"__xray_TypedEvent" :
"__xray_CustomEvent")),
644 O.AddComment(
"Begin XRay typed event");
645 EmitToStreamer(O, MCInstBuilder(AArch64::B).addImm(9));
646 EmitToStreamer(O, MCInstBuilder(AArch64::STPXpre)
652 EmitToStreamer(O, MCInstBuilder(AArch64::STRXui)
656 emitMovXReg(AArch64::X0,
MI.getOperand(0).getReg());
657 emitMovXReg(AArch64::X1,
MI.getOperand(1).getReg());
658 emitMovXReg(AArch64::X2,
MI.getOperand(2).getReg());
659 EmitToStreamer(O, MCInstBuilder(AArch64::BL).addExpr(Sym));
660 EmitToStreamer(O, MCInstBuilder(AArch64::LDRXui)
664 O.AddComment(
"End XRay typed event");
665 EmitToStreamer(O, MCInstBuilder(AArch64::LDPXpost)
672 recordSled(CurSled,
MI, SledKind::TYPED_EVENT, 2);
674 O.AddComment(
"Begin XRay custom event");
675 EmitToStreamer(O, MCInstBuilder(AArch64::B).addImm(6));
676 EmitToStreamer(O, MCInstBuilder(AArch64::STPXpre)
682 emitMovXReg(AArch64::X0,
MI.getOperand(0).getReg());
683 emitMovXReg(AArch64::X1,
MI.getOperand(1).getReg());
684 EmitToStreamer(O, MCInstBuilder(AArch64::BL).addExpr(Sym));
685 O.AddComment(
"End XRay custom event");
686 EmitToStreamer(O, MCInstBuilder(AArch64::LDPXpost)
693 recordSled(CurSled,
MI, SledKind::CUSTOM_EVENT, 2);
697void AArch64AsmPrinter::LowerKCFI_CHECK(
const MachineInstr &
MI) {
699 assert(std::next(
MI.getIterator())->isCall() &&
700 "KCFI_CHECK not followed by a call instruction");
701 assert(std::next(
MI.getIterator())->getOperand(0).getReg() == AddrReg &&
702 "KCFI_CHECK call target doesn't match call operand");
706 unsigned ScratchRegs[] = {AArch64::W16, AArch64::W17};
707 if (AddrReg == AArch64::XZR) {
711 emitMovXReg(AddrReg, AArch64::XZR);
717 for (
auto &
Reg : ScratchRegs) {
723 assert(ScratchRegs[0] != AddrReg && ScratchRegs[1] != AddrReg &&
724 "Invalid scratch registers for KCFI_CHECK");
729 MI.getMF()->getFunction().getFnAttributeAsParsedInteger(
730 "patchable-function-prefix");
733 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::LDURWi)
734 .addReg(ScratchRegs[0])
736 .addImm(-(PrefixNops * 4 + 4)));
740 const int64_t
Type =
MI.getOperand(1).getImm();
741 emitMOVK(ScratchRegs[1],
Type & 0xFFFF, 0);
742 emitMOVK(ScratchRegs[1], (
Type >> 16) & 0xFFFF, 16);
745 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::SUBSWrs)
746 .addReg(AArch64::WZR)
747 .addReg(ScratchRegs[0])
748 .addReg(ScratchRegs[1])
752 EmitToStreamer(*OutStreamer,
753 MCInstBuilder(AArch64::Bcc)
762 unsigned TypeIndex = ScratchRegs[1] - AArch64::W0;
766 AddrIndex = AddrReg - AArch64::X0;
776 assert(AddrIndex < 31 && TypeIndex < 31);
778 unsigned ESR = 0x8000 | ((TypeIndex & 31) << 5) | (AddrIndex & 31);
779 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::BRK).addImm(ESR));
780 OutStreamer->emitLabel(
Pass);
783void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
791 if (
Reg == AArch64::XZR)
795 ((
MI.getOpcode() == AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES) ||
797 AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW));
798 uint32_t AccessInfo =
MI.getOperand(1).getImm();
800 ((
MI.getOpcode() == AArch64::HWASAN_CHECK_MEMACCESS_FIXEDSHADOW) ||
802 AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW));
803 uint64_t FixedShadowOffset = IsFixedShadow ?
MI.getOperand(2).getImm() : 0;
805 MCSymbol *&Sym = HwasanMemaccessSymbols[HwasanMemaccessTuple(
806 Reg, IsShort, AccessInfo, IsFixedShadow, FixedShadowOffset)];
809 if (!TM.getTargetTriple().isOSBinFormatELF())
812 std::string SymName =
"__hwasan_check_x" +
utostr(
Reg - AArch64::X0) +
"_" +
815 SymName +=
"_fixed_" +
utostr(FixedShadowOffset);
817 SymName +=
"_short_v2";
818 Sym = OutContext.getOrCreateSymbol(SymName);
821 EmitToStreamer(*OutStreamer,
822 MCInstBuilder(AArch64::BL)
826void AArch64AsmPrinter::emitHwasanMemaccessSymbols(
Module &M) {
827 if (HwasanMemaccessSymbols.empty())
830 const Triple &
TT =
M.getTargetTriple();
834 auto STI = std::make_unique<AArch64Subtarget>(
835 TT, TM.getTargetCPU(), TM.getTargetCPU(), TM.getTargetFeatureString(), TM,
837 this->STI = STI.get();
840 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch");
842 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
844 const MCSymbolRefExpr *HwasanTagMismatchV1Ref =
846 const MCSymbolRefExpr *HwasanTagMismatchV2Ref =
849 for (
auto &
P : HwasanMemaccessSymbols) {
850 unsigned Reg = std::get<0>(
P.first);
851 bool IsShort = std::get<1>(
P.first);
852 uint32_t AccessInfo = std::get<2>(
P.first);
853 bool IsFixedShadow = std::get<3>(
P.first);
854 uint64_t FixedShadowOffset = std::get<4>(
P.first);
855 const MCSymbolRefExpr *HwasanTagMismatchRef =
856 IsShort ? HwasanTagMismatchV2Ref : HwasanTagMismatchV1Ref;
859 bool HasMatchAllTag =
861 uint8_t MatchAllTag =
868 OutStreamer->switchSection(OutContext.getELFSection(
874 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Weak);
875 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Hidden);
876 OutStreamer->emitLabel(Sym);
878 EmitToStreamer(MCInstBuilder(AArch64::SBFMXri)
879 .addReg(AArch64::X16)
889 emitMOVZ(AArch64::X17, FixedShadowOffset >> 32, 32);
890 EmitToStreamer(MCInstBuilder(AArch64::LDRBBroX)
891 .addReg(AArch64::W16)
892 .addReg(AArch64::X17)
893 .addReg(AArch64::X16)
897 EmitToStreamer(MCInstBuilder(AArch64::LDRBBroX)
898 .addReg(AArch64::W16)
899 .addReg(IsShort ? AArch64::X20 : AArch64::X9)
900 .addReg(AArch64::X16)
905 EmitToStreamer(MCInstBuilder(AArch64::SUBSXrs)
906 .addReg(AArch64::XZR)
907 .addReg(AArch64::X16)
910 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
911 EmitToStreamer(MCInstBuilder(AArch64::Bcc)
914 HandleMismatchOrPartialSym, OutContext)));
915 MCSymbol *ReturnSym = OutContext.createTempSymbol();
916 OutStreamer->emitLabel(ReturnSym);
917 EmitToStreamer(MCInstBuilder(AArch64::RET).addReg(AArch64::LR));
918 OutStreamer->emitLabel(HandleMismatchOrPartialSym);
920 if (HasMatchAllTag) {
921 EmitToStreamer(MCInstBuilder(AArch64::UBFMXri)
922 .addReg(AArch64::X17)
926 EmitToStreamer(MCInstBuilder(AArch64::SUBSXri)
927 .addReg(AArch64::XZR)
928 .addReg(AArch64::X17)
932 MCInstBuilder(AArch64::Bcc)
938 EmitToStreamer(MCInstBuilder(AArch64::SUBSWri)
939 .addReg(AArch64::WZR)
940 .addReg(AArch64::W16)
943 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
945 MCInstBuilder(AArch64::Bcc)
949 EmitToStreamer(MCInstBuilder(AArch64::ANDXri)
950 .addReg(AArch64::X17)
954 EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
955 .addReg(AArch64::X17)
956 .addReg(AArch64::X17)
959 EmitToStreamer(MCInstBuilder(AArch64::SUBSWrs)
960 .addReg(AArch64::WZR)
961 .addReg(AArch64::W16)
962 .addReg(AArch64::W17)
965 MCInstBuilder(AArch64::Bcc)
969 EmitToStreamer(MCInstBuilder(AArch64::ORRXri)
970 .addReg(AArch64::X16)
973 EmitToStreamer(MCInstBuilder(AArch64::LDRBBui)
974 .addReg(AArch64::W16)
975 .addReg(AArch64::X16)
978 MCInstBuilder(AArch64::SUBSXrs)
979 .addReg(AArch64::XZR)
980 .addReg(AArch64::X16)
984 MCInstBuilder(AArch64::Bcc)
988 OutStreamer->emitLabel(HandleMismatchSym);
991 EmitToStreamer(MCInstBuilder(AArch64::STPXpre)
997 EmitToStreamer(MCInstBuilder(AArch64::STPXi)
1000 .addReg(AArch64::SP)
1003 if (
Reg != AArch64::X0)
1004 emitMovXReg(AArch64::X0,
Reg);
1007 if (CompileKernel) {
1011 EmitToStreamer(MCInstBuilder(AArch64::B).addExpr(HwasanTagMismatchRef));
1016 EmitToStreamer(MCInstBuilder(AArch64::ADRP)
1017 .addReg(AArch64::X16)
1021 EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
1022 .addReg(AArch64::X16)
1023 .addReg(AArch64::X16)
1027 EmitToStreamer(MCInstBuilder(AArch64::BR).addReg(AArch64::X16));
1030 this->STI =
nullptr;
1035 const MCExpr *StubAuthPtrRef) {
1038 OutStreamer.
emitValue(StubAuthPtrRef, 8);
1041void AArch64AsmPrinter::emitEndOfAsmFile(
Module &M) {
1042 emitHwasanMemaccessSymbols(M);
1044 const Triple &
TT =
M.getTargetTriple();
1045 if (
TT.isOSBinFormatMachO()) {
1047 MachineModuleInfoMachO &MMIMacho =
1048 MMI->getObjFileInfo<MachineModuleInfoMachO>();
1052 if (!Stubs.empty()) {
1054 OutStreamer->switchSection(
1057 emitAlignment(
Align(8));
1059 for (
const auto &Stub : Stubs)
1062 OutStreamer->addBlankLine();
1070 OutStreamer->emitSubsectionsViaSymbols();
1073 if (
TT.isOSBinFormatELF()) {
1075 MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();
1079 if (!Stubs.empty()) {
1080 const TargetLoweringObjectFile &TLOF = getObjFileLowering();
1082 emitAlignment(
Align(8));
1084 for (
const auto &Stub : Stubs)
1087 OutStreamer->addBlankLine();
1098 M.getModuleFlag(
"ptrauth-elf-got"));
1099 if (PtrAuthELFGOTFlag && PtrAuthELFGOTFlag->getZExtValue() == 1)
1100 for (
const GlobalValue &GV :
M.global_values())
1102 !GV.getName().starts_with(
"llvm."))
1103 OutStreamer->emitSymbolAttribute(getSymbol(&GV),
1112 if (EnableImportCallOptimization &&
TT.isOSBinFormatCOFF()) {
1113 OutStreamer->switchSection(getObjFileLowering().getImportCallSection());
1116 constexpr char ImpCallMagic[12] =
"Imp_Call_V1";
1117 OutStreamer->emitBytes(StringRef{ImpCallMagic,
sizeof(ImpCallMagic)});
1128 for (
auto &[Section, CallsToImportedFuncs] :
1129 SectionToImportedFunctionCalls) {
1131 sizeof(uint32_t) * (2 + 3 * CallsToImportedFuncs.size());
1132 OutStreamer->emitInt32(SectionSize);
1133 OutStreamer->emitCOFFSecNumber(
Section->getBeginSymbol());
1134 for (
auto &[CallsiteSymbol, CalledSymbol] : CallsToImportedFuncs) {
1136 OutStreamer->emitInt32(0x13);
1137 OutStreamer->emitCOFFSecOffset(CallsiteSymbol);
1138 OutStreamer->emitCOFFSymbolIndex(CalledSymbol);
1144void AArch64AsmPrinter::emitLOHs() {
1148 for (
const MachineInstr *
MI :
D.getArgs()) {
1149 MInstToMCSymbol::iterator LabelIt = LOHInstToLabel.find(
MI);
1150 assert(LabelIt != LOHInstToLabel.end() &&
1151 "Label hasn't been inserted for LOH related instruction");
1154 OutStreamer->emitLOHDirective(
D.getKind(), MCArgs);
1165void AArch64AsmPrinter::emitBasicBlockEnd(
const MachineBasicBlock &
MBB) {
1168 if (
Next == MF->
end() ||
Next->isEHFuncletEntry()) {
1170 if (
MI.isMetaInstruction() || AArch64InstrInfo::isSEHInstruction(
MI))
1172 if (
MI.isCall() && !
MI.isReturn())
1173 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::BRK).addImm(1));
1182void AArch64AsmPrinter::emitFunctionBodyEnd() {
1188MCSymbol *AArch64AsmPrinter::GetCPISymbol(
unsigned CPID)
const {
1192 if (!getDataLayout().getLinkerPrivateGlobalPrefix().
empty())
1193 return OutContext.getOrCreateSymbol(
1194 Twine(getDataLayout().getLinkerPrivateGlobalPrefix()) +
"CPI" +
1195 Twine(getFunctionNumber()) +
"_" + Twine(CPID));
1200void AArch64AsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNum,
1202 const MachineOperand &MO =
MI->getOperand(OpNum);
1218 PrintSymbolOperand(MO, O);
1229bool AArch64AsmPrinter::printAsmMRegister(
const MachineOperand &MO,
char Mode,
1253bool AArch64AsmPrinter::printAsmRegInClass(
const MachineOperand &MO,
1255 unsigned AltName, raw_ostream &O) {
1256 assert(MO.
isReg() &&
"Should only get here with a register!");
1257 const TargetRegisterInfo *RI = STI->getRegisterInfo();
1266bool AArch64AsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNum,
1267 const char *ExtraCode, raw_ostream &O) {
1268 const MachineOperand &MO =
MI->getOperand(OpNum);
1275 if (ExtraCode && ExtraCode[0]) {
1276 if (ExtraCode[1] != 0)
1279 switch (ExtraCode[0]) {
1287 unsigned Reg = ExtraCode[0] ==
'w' ? AArch64::WZR : AArch64::XZR;
1301 switch (ExtraCode[0]) {
1303 RC = &AArch64::FPR8RegClass;
1306 RC = &AArch64::FPR16RegClass;
1309 RC = &AArch64::FPR32RegClass;
1312 RC = &AArch64::FPR64RegClass;
1315 RC = &AArch64::FPR128RegClass;
1318 RC = &AArch64::ZPRRegClass;
1323 return printAsmRegInClass(MO, RC, AArch64::NoRegAltName, O);
1344 unsigned AltName = AArch64::NoRegAltName;
1347 RegClass = &AArch64::ZPRRegClass;
1349 RegClass = &AArch64::PPRRegClass;
1351 RegClass = &AArch64::PNRRegClass;
1353 RegClass = &AArch64::FPR128RegClass;
1354 AltName = AArch64::vreg;
1358 return printAsmRegInClass(MO, RegClass, AltName, O);
1365bool AArch64AsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
1367 const char *ExtraCode,
1369 if (ExtraCode && ExtraCode[0] && ExtraCode[0] !=
'a')
1372 const MachineOperand &MO =
MI->getOperand(OpNum);
1373 assert(MO.
isReg() &&
"unexpected inline asm memory operand");
1378void AArch64AsmPrinter::PrintDebugValueComment(
const MachineInstr *
MI,
1380 unsigned NOps =
MI->getNumOperands();
1382 OS <<
'\t' << MAI.getCommentString() <<
"DEBUG_VALUE: ";
1384 OS <<
MI->getDebugVariable()->getName();
1387 assert(
MI->isIndirectDebugValue());
1399void AArch64AsmPrinter::emitJumpTableImpl(
const MachineJumpTableInfo &MJTI,
1400 ArrayRef<unsigned> JumpTableIndices) {
1402 if (JumpTableIndices.
empty())
1404 const TargetLoweringObjectFile &TLOF = getObjFileLowering();
1408 MCSection *ReadOnlySec =
nullptr;
1409 if (TM.Options.EnableStaticDataPartitioning) {
1415 OutStreamer->switchSection(ReadOnlySec);
1417 auto AFI = MF->
getInfo<AArch64FunctionInfo>();
1418 for (
unsigned JTI : JumpTableIndices) {
1419 const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
1422 if (JTBBs.empty())
continue;
1424 unsigned Size = AFI->getJumpTableEntrySize(JTI);
1426 OutStreamer->emitLabel(GetJTISymbol(JTI));
1431 for (
auto *JTBB : JTBBs) {
1432 const MCExpr *
Value =
1451AArch64AsmPrinter::getCodeViewJumpTableInfo(
int JTI,
1452 const MachineInstr *BranchInstr,
1453 const MCSymbol *BranchLabel)
const {
1454 const auto AFI = MF->
getInfo<AArch64FunctionInfo>();
1457 switch (AFI->getJumpTableEntrySize(JTI)) {
1459 EntrySize = codeview::JumpTableEntrySize::UInt8ShiftLeft;
1462 EntrySize = codeview::JumpTableEntrySize::UInt16ShiftLeft;
1465 EntrySize = codeview::JumpTableEntrySize::Int32;
1470 return std::make_tuple(
Base, 0, BranchLabel, EntrySize);
1473void AArch64AsmPrinter::emitFunctionEntryLabel() {
1474 const Triple &
TT = TM.getTargetTriple();
1475 if (
TT.isOSBinFormatELF() &&
1478 CallingConv::AArch64_SVE_VectorCall ||
1479 MF->
getInfo<AArch64FunctionInfo>()->isSVECC())) {
1481 static_cast<AArch64TargetStreamer *
>(OutStreamer->getTargetStreamer());
1492 OutStreamer->emitAssignment(
1496 auto getSymbolFromMetadata = [&](StringRef
Name) {
1500 Sym = MMI->getContext().getOrCreateSymbol(NameStr);
1507 for (MDNode *Node : UnmangledNames) {
1509 MCSymbol *UnmangledSym = MMI->getContext().getOrCreateSymbol(NameStr);
1510 if (std::optional<std::string> MangledName =
1513 MMI->getContext().getOrCreateSymbol(*MangledName);
1514 emitFunctionAlias(UnmangledSym, ECMangledSym);
1517 if (MCSymbol *ECMangledSym =
1518 getSymbolFromMetadata(
"arm64ec_ecmangled_name"))
1519 emitFunctionAlias(ECMangledSym, CurrentFnSym);
1523void AArch64AsmPrinter::emitXXStructor(
const DataLayout &
DL,
1524 const Constant *CV) {
1527 "ctors/dtors are to be signed by asm printer");
1529 if (PtrauthInitFini) {
1535 ConstantInt *IntDisc = ConstantInt::get(
1539 if (PtrauthInitFiniAddressDisc) {
1553void AArch64AsmPrinter::emitGlobalAlias(
const Module &M,
1554 const GlobalAlias &GA) {
1560 if (MDNode *Node =
F->getMetadata(
"arm64ec_exp_name")) {
1562 MCSymbol *ExpSym = MMI->getContext().getOrCreateSymbol(ExpStr);
1565 OutStreamer->beginCOFFSymbolDef(ExpSym);
1569 OutStreamer->endCOFFSymbolDef();
1571 OutStreamer->beginCOFFSymbolDef(Sym);
1575 OutStreamer->endCOFFSymbolDef();
1576 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Weak);
1577 OutStreamer->emitAssignment(
1594void AArch64AsmPrinter::LowerJumpTableDest(llvm::MCStreamer &OutStreamer,
1595 const llvm::MachineInstr &
MI) {
1596 Register DestReg =
MI.getOperand(0).getReg();
1597 Register ScratchReg =
MI.getOperand(1).getReg();
1599 STI->getRegisterInfo()->getSubReg(ScratchReg, AArch64::sub_32);
1600 Register TableReg =
MI.getOperand(2).getReg();
1601 Register EntryReg =
MI.getOperand(3).getReg();
1602 int JTIdx =
MI.getOperand(4).getIndex();
1608 MF->
getInfo<AArch64FunctionInfo>()->getJumpTableEntryPCRelSymbol(JTIdx);
1619 EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::ADR)
1621 .addExpr(LabelExpr));
1626 case 1: LdrOpcode = AArch64::LDRBBroX;
break;
1627 case 2: LdrOpcode = AArch64::LDRHHroX;
break;
1628 case 4: LdrOpcode = AArch64::LDRSWroX;
break;
1633 EmitToStreamer(OutStreamer, MCInstBuilder(LdrOpcode)
1634 .addReg(
Size == 4 ? ScratchReg : ScratchRegW)
1638 .addImm(
Size == 1 ? 0 : 1));
1642 EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::ADDXrs)
1646 .addImm(
Size == 4 ? 0 : 2));
1649void AArch64AsmPrinter::LowerHardenedBRJumpTable(
const MachineInstr &
MI) {
1651 assert(MJTI &&
"Can't lower jump-table dispatch without JTI");
1653 const std::vector<MachineJumpTableEntry> &JTs = MJTI->
getJumpTables();
1654 assert(!JTs.empty() &&
"Invalid JT index for jump-table dispatch");
1670 MachineOperand JTOp =
MI.getOperand(0);
1674 "unsupported compressed jump table");
1676 const uint64_t NumTableEntries = JTs[JTI].MBBs.size();
1680 uint64_t MaxTableEntry = NumTableEntries - 1;
1682 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::SUBSXri)
1683 .addReg(AArch64::XZR)
1684 .addReg(AArch64::X16)
1685 .addImm(MaxTableEntry)
1688 emitMOVZ(AArch64::X17,
static_cast<uint16_t
>(MaxTableEntry), 0);
1693 if ((MaxTableEntry >>
Offset) == 0)
1695 emitMOVK(AArch64::X17,
static_cast<uint16_t
>(MaxTableEntry >>
Offset),
1698 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::SUBSXrs)
1699 .addReg(AArch64::XZR)
1700 .addReg(AArch64::X16)
1701 .addReg(AArch64::X17)
1707 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::CSELXr)
1708 .addReg(AArch64::X16)
1709 .addReg(AArch64::X16)
1710 .addReg(AArch64::XZR)
1714 MachineOperand JTMOHi(JTOp), JTMOLo(JTOp);
1715 MCOperand JTMCHi, JTMCLo;
1725 MCInstBuilder(AArch64::ADRP).addReg(AArch64::X17).
addOperand(JTMCHi));
1727 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ADDXri)
1728 .addReg(AArch64::X17)
1729 .addReg(AArch64::X17)
1733 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::LDRSWroX)
1734 .addReg(AArch64::X16)
1735 .addReg(AArch64::X17)
1736 .addReg(AArch64::X16)
1747 MCInstBuilder(AArch64::ADR).addReg(AArch64::X17).addExpr(AdrLabelE));
1749 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ADDXrs)
1750 .addReg(AArch64::X16)
1751 .addReg(AArch64::X17)
1752 .addReg(AArch64::X16)
1755 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::BR).addReg(AArch64::X16));
1758void AArch64AsmPrinter::LowerMOPS(llvm::MCStreamer &OutStreamer,
1759 const llvm::MachineInstr &
MI) {
1760 unsigned Opcode =
MI.getOpcode();
1762 assert(STI->hasMTE() || Opcode != AArch64::MOPSMemorySetTaggingPseudo);
1764 const auto Ops = [Opcode]() -> std::array<unsigned, 3> {
1765 if (Opcode == AArch64::MOPSMemoryCopyPseudo)
1766 return {AArch64::CPYFP, AArch64::CPYFM, AArch64::CPYFE};
1767 if (Opcode == AArch64::MOPSMemoryMovePseudo)
1768 return {AArch64::CPYP, AArch64::CPYM, AArch64::CPYE};
1769 if (Opcode == AArch64::MOPSMemorySetPseudo)
1770 return {AArch64::SETP, AArch64::SETM, AArch64::SETE};
1771 if (Opcode == AArch64::MOPSMemorySetTaggingPseudo)
1772 return {AArch64::SETGP, AArch64::SETGM, AArch64::MOPSSETGE};
1775 const bool IsSet = Opcode == AArch64::MOPSMemorySetPseudo ||
1776 Opcode == AArch64::MOPSMemorySetTaggingPseudo;
1778 for (
auto Op :
Ops) {
1780 auto MCIB = MCInstBuilder(
Op);
1782 MCIB.addReg(
MI.getOperand(i++).getReg());
1783 MCIB.addReg(
MI.getOperand(i++).getReg());
1785 MCIB.addReg(
MI.getOperand(i++).getReg());
1787 MCIB.addReg(
MI.getOperand(i++).getReg());
1788 MCIB.addReg(
MI.getOperand(i++).getReg());
1789 MCIB.addReg(
MI.getOperand(i++).getReg());
1791 EmitToStreamer(OutStreamer, MCIB);
1795void AArch64AsmPrinter::LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
1796 const MachineInstr &
MI) {
1797 unsigned NumNOPBytes = StackMapOpers(&
MI).getNumPatchBytes();
1800 MCSymbol *MILabel = Ctx.createTempSymbol();
1804 assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
1810 while (NumNOPBytes > 0) {
1811 if (MII ==
MBB.
end() || MII->isCall() ||
1812 MII->getOpcode() == AArch64::DBG_VALUE ||
1813 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
1814 MII->getOpcode() == TargetOpcode::STACKMAP)
1821 for (
unsigned i = 0; i < NumNOPBytes; i += 4)
1822 EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::NOP));
1827void AArch64AsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
1828 const MachineInstr &
MI) {
1830 MCSymbol *MILabel = Ctx.createTempSymbol();
1834 PatchPointOpers Opers(&
MI);
1836 int64_t CallTarget = Opers.getCallTarget().getImm();
1837 unsigned EncodedBytes = 0;
1839 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
1840 "High 16 bits of call target should be zero.");
1841 Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
1844 emitMOVZ(ScratchReg, (CallTarget >> 32) & 0xFFFF, 32);
1845 emitMOVK(ScratchReg, (CallTarget >> 16) & 0xFFFF, 16);
1846 emitMOVK(ScratchReg, CallTarget & 0xFFFF, 0);
1847 EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::BLR).addReg(ScratchReg));
1850 unsigned NumBytes = Opers.getNumPatchBytes();
1851 assert(NumBytes >= EncodedBytes &&
1852 "Patchpoint can't request size less than the length of a call.");
1853 assert((NumBytes - EncodedBytes) % 4 == 0 &&
1854 "Invalid number of NOP bytes requested!");
1855 for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
1856 EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::NOP));
1859void AArch64AsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
1860 const MachineInstr &
MI) {
1861 StatepointOpers SOpers(&
MI);
1862 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
1863 assert(PatchBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
1864 for (
unsigned i = 0; i < PatchBytes; i += 4)
1865 EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::NOP));
1868 const MachineOperand &CallTarget = SOpers.getCallTarget();
1869 MCOperand CallTargetMCOp;
1870 unsigned CallOpcode;
1871 switch (CallTarget.
getType()) {
1874 MCInstLowering.
lowerOperand(CallTarget, CallTargetMCOp);
1875 CallOpcode = AArch64::BL;
1879 CallOpcode = AArch64::BL;
1883 CallOpcode = AArch64::BLR;
1890 EmitToStreamer(OutStreamer,
1891 MCInstBuilder(CallOpcode).
addOperand(CallTargetMCOp));
1895 MCSymbol *MILabel = Ctx.createTempSymbol();
1900void AArch64AsmPrinter::LowerFAULTING_OP(
const MachineInstr &FaultingMI) {
1909 unsigned OperandsBeginIdx = 4;
1912 MCSymbol *FaultingLabel = Ctx.createTempSymbol();
1919 MI.setOpcode(Opcode);
1924 for (
const MachineOperand &MO :
1927 lowerOperand(MO, Dest);
1928 MI.addOperand(Dest);
1936 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ORRXrs)
1938 .addReg(AArch64::XZR)
1944 bool Is64Bit = AArch64::GPR64RegClass.contains(Dest);
1945 EmitToStreamer(*OutStreamer,
1946 MCInstBuilder(Is64Bit ? AArch64::MOVZXi : AArch64::MOVZWi)
1953 bool Is64Bit = AArch64::GPR64RegClass.contains(Dest);
1954 EmitToStreamer(*OutStreamer,
1955 MCInstBuilder(Is64Bit ? AArch64::MOVKXi : AArch64::MOVKWi)
1964 bool IsZeroDisc = Disc == AArch64::XZR;
1976 EmitToStreamer(AUTInst);
1981 bool IsZeroDisc = Disc == AArch64::XZR;
1993 EmitToStreamer(PACInst);
1998 bool IsZeroDisc = Disc == AArch64::XZR;
2008 EmitToStreamer(Inst);
2011void AArch64AsmPrinter::emitFMov0(
const MachineInstr &
MI) {
2012 Register DestReg =
MI.getOperand(0).getReg();
2013 if (!STI->hasZeroCycleZeroingFPWorkaround() && STI->isNeonAvailable()) {
2014 if (STI->hasZeroCycleZeroingFPR64()) {
2016 const AArch64RegisterInfo *
TRI = STI->getRegisterInfo();
2017 if (AArch64::FPR16RegClass.
contains(DestReg))
2018 DestReg =
TRI->getMatchingSuperReg(DestReg, AArch64::hsub,
2019 &AArch64::FPR64RegClass);
2020 else if (AArch64::FPR32RegClass.
contains(DestReg))
2021 DestReg =
TRI->getMatchingSuperReg(DestReg, AArch64::ssub,
2022 &AArch64::FPR64RegClass);
2030 EmitToStreamer(*OutStreamer, MOVI);
2031 ++NumZCZeroingInstrsFPR;
2032 }
else if (STI->hasZeroCycleZeroingFPR128()) {
2034 const AArch64RegisterInfo *
TRI = STI->getRegisterInfo();
2035 if (AArch64::FPR16RegClass.
contains(DestReg)) {
2036 DestReg =
TRI->getMatchingSuperReg(DestReg, AArch64::hsub,
2037 &AArch64::FPR128RegClass);
2038 }
else if (AArch64::FPR32RegClass.
contains(DestReg)) {
2039 DestReg =
TRI->getMatchingSuperReg(DestReg, AArch64::ssub,
2040 &AArch64::FPR128RegClass);
2043 DestReg =
TRI->getMatchingSuperReg(DestReg, AArch64::dsub,
2044 &AArch64::FPR128RegClass);
2051 EmitToStreamer(*OutStreamer, MOVI);
2052 ++NumZCZeroingInstrsFPR;
2054 emitFMov0AsFMov(
MI, DestReg);
2057 emitFMov0AsFMov(
MI, DestReg);
2061void AArch64AsmPrinter::emitFMov0AsFMov(
const MachineInstr &
MI,
2064 switch (
MI.getOpcode()) {
2067 case AArch64::FMOVH0:
2068 FMov.
setOpcode(STI->hasFullFP16() ? AArch64::FMOVWHr : AArch64::FMOVWSr);
2069 if (!STI->hasFullFP16())
2070 DestReg = (AArch64::S0 + (DestReg - AArch64::H0));
2074 case AArch64::FMOVS0:
2079 case AArch64::FMOVD0:
2085 EmitToStreamer(*OutStreamer, FMov);
2091 bool MayClobberAddrDisc) {
2092 assert(isPtrauthRegSafe(ScratchReg) &&
2093 "Safe scratch register must be provided by the caller");
2098 AddrDisc = AArch64::XZR;
2106 if (AddrDisc == AArch64::XZR) {
2107 emitMOVZ(ScratchReg, Disc, 0);
2114 if (MayClobberAddrDisc && isPtrauthRegSafe(AddrDisc)) {
2115 ScratchReg = AddrDisc;
2117 emitMovXReg(ScratchReg, AddrDisc);
2118 assert(ScratchReg != AddrDisc &&
2119 "Forbidden to clobber AddrDisc, but have to");
2122 emitMOVK(ScratchReg, Disc, 48);
2136void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue(
2168 if (Method == AuthCheckMethod::None)
2170 if (Method == AuthCheckMethod::DummyLoad) {
2171 EmitToStreamer(MCInstBuilder(AArch64::LDRWui)
2175 assert(!OnFailure &&
"DummyLoad always traps on error");
2179 MCSymbol *SuccessSym = createTempSymbol(
"auth_success_");
2180 if (Method == AuthCheckMethod::XPAC || Method == AuthCheckMethod::XPACHint) {
2182 emitMovXReg(ScratchReg, TestedReg);
2184 if (Method == AuthCheckMethod::XPAC) {
2188 MCInstBuilder(XPACOpc).addReg(ScratchReg).addReg(ScratchReg));
2193 assert(TestedReg == AArch64::LR &&
2194 "XPACHint mode is only compatible with checking the LR register");
2196 "XPACHint mode is only compatible with I-keys");
2197 EmitToStreamer(MCInstBuilder(AArch64::XPACLRI));
2201 EmitToStreamer(MCInstBuilder(AArch64::SUBSXrs)
2202 .addReg(AArch64::XZR)
2209 MCInstBuilder(AArch64::Bcc)
2212 }
else if (Method == AuthCheckMethod::HighBitsNoTBI) {
2214 EmitToStreamer(MCInstBuilder(AArch64::EORXrs)
2221 MCInstBuilder(AArch64::TBZX)
2232 EmitToStreamer(MCInstBuilder(AArch64::BRK).addImm(0xc470 |
Key));
2246 case AuthCheckMethod::XPACHint:
2249 case AuthCheckMethod::XPAC:
2251 emitMovXReg(TestedReg, ScratchReg);
2258 MCInstBuilder(XPACOpc).addReg(TestedReg).addReg(TestedReg));
2263 EmitToStreamer(MCInstBuilder(AArch64::B).addExpr(OnFailureExpr));
2275void AArch64AsmPrinter::emitPtrauthTailCallHardening(
const MachineInstr *TC) {
2279 auto LRCheckMethod = STI->getAuthenticatedLRCheckMethod(*MF);
2280 if (LRCheckMethod == AArch64PAuth::AuthCheckMethod::None)
2283 const AArch64RegisterInfo *
TRI = STI->getRegisterInfo();
2287 "Neither x16 nor x17 is available as a scratch register");
2290 emitPtrauthCheckAuthenticatedValue(AArch64::LR, ScratchReg,
Key,
2294bool AArch64AsmPrinter::emitDeactivationSymbolRelocation(
Value *DS) {
2300 EmitToStreamer(MCInstBuilder(AArch64::NOP));
2303 MCSymbol *Dot = OutContext.createTempSymbol();
2308 OutContext.getOrCreateSymbol(
DS->getName()), OutContext);
2314AArch64AsmPrinter::PtrAuthSchema AArch64AsmPrinter::PtrAuthSchema::CreateImmReg(
2316 PtrAuthSchema Schema;
2318 Schema.IntDisc = IntDisc;
2319 Schema.AddrDisc = AddrDiscOp.
getReg();
2320 Schema.AddrDiscIsKilled = AddrDiscOp.
isKill();
2325AArch64AsmPrinter::PtrAuthSchema AArch64AsmPrinter::PtrAuthSchema::CreateRegReg(
2327 assert(PCDisc.
isValid() &&
"Use CreateImmReg for non-PC schemas");
2328 PtrAuthSchema Schema;
2331 Schema.AddrDisc = AddrDisc;
2332 Schema.AddrDiscIsKilled =
false;
2333 Schema.PCDisc = PCDisc;
2337void AArch64AsmPrinter::emitPtrauthApplyIndirectAddend(
Register Pointer,
2342 EmitToStreamer(MCInstBuilder(AArch64::LDRSWpre)
2352 for (
int BitPos = 0; BitPos != 24 && (Addend >> BitPos); BitPos += 12) {
2354 MCInstBuilder(AArch64::ADDXri)
2357 .addImm((Addend >> BitPos) & 0xfff)
2363 emitMOVZ(Scratch, Addend & 0xffff, 0);
2370 EmitToStreamer(MCInstBuilder(AArch64::ADDXrs)
2377 EmitToStreamer(MCInstBuilder(AArch64::LDRSWui)
2383 EmitToStreamer(MCInstBuilder(AArch64::ADDXrs)
2394 if (std::optional<PtrauthCheckMode>
Mode =
2401 return PtrauthCheckMode::Unchecked;
2404 return ShouldTrap ? PtrauthCheckMode::Trap : PtrauthCheckMode::Poison;
2435void AArch64AsmPrinter::emitPtrauthAuthResign(
2437 std::optional<PtrAuthSchema> SignSchema, std::optional<int64_t> Addend,
2440 const bool IsAuthWithPC = AuthSchema.PCDisc.isValid();
2441 assert(!SignSchema || !SignSchema->PCDisc.isValid());
2443 Register SignAddrDiscOrNone = SignSchema ? SignSchema->AddrDisc :
Register();
2449 assert(Pointer == AArch64::X17 && Scratch == AArch64::X16 &&
2450 "AUTPCPAC must use x17/x16 as Pointer/Scratch");
2452 assert(AuthSchema.AddrDisc == AArch64::X16 &&
2453 "AUTPCPAC requires address discriminator in X16");
2455 assert(AuthSchema.PCDisc == AArch64::X15 &&
2456 "AUTPCPAC requires PC discriminator in X15");
2458 assert(AuthSchema.IntDisc == 0 &&
"AUTPCPAC does not support IntDisc");
2462 "AUTPCPAC only supports AUT-ing with IA/IB");
2464 if (!emitDeactivationSymbolRelocation(DS)) {
2466 ? AArch64::AUTIB171615
2467 : AArch64::AUTIA171615;
2468 EmitToStreamer(MCInstBuilder(AutOpc));
2478 Register AUTDiscReg = emitPtrauthDiscriminator(
2479 AuthSchema.IntDisc, AuthSchema.AddrDisc, Scratch,
2480 AuthSchema.addrDiscIsKilledAndNoneOf({Pointer, SignAddrDiscOrNone}));
2481 if (!emitDeactivationSymbolRelocation(DS))
2482 emitAUT(AuthSchema.Key, Pointer, AUTDiscReg);
2487 auto EmitCheck = [&](
MCSymbol *OnFailure =
nullptr) {
2488 emitPtrauthCheckAuthenticatedValue(Pointer, Scratch, AuthSchema.Key,
2489 AArch64PAuth::AuthCheckMethod::XPAC,
2493 auto EmitResignOnSuccess = [&]() {
2494 if (Addend.has_value())
2495 emitPtrauthApplyIndirectAddend(Pointer, Scratch, *Addend);
2497 assert(Pointer != SignSchema->AddrDisc &&
"Pointer is early-clobbered");
2499 emitPtrauthDiscriminator(SignSchema->IntDisc, SignSchema->AddrDisc,
2500 Scratch, SignSchema->AddrDiscIsKilled);
2501 emitPAC(SignSchema->Key, Pointer, PACDiscReg);
2507 if (CheckMode == PtrauthCheckMode::Trap)
2513 switch (CheckMode) {
2514 case PtrauthCheckMode::Unchecked:
2515 EmitResignOnSuccess();
2517 case PtrauthCheckMode::Trap:
2519 EmitResignOnSuccess();
2521 case PtrauthCheckMode::Poison:
2522 MCSymbol *OnFailure = createTempSymbol(
"resign_end_");
2523 EmitCheck(OnFailure);
2524 EmitResignOnSuccess();
2530void AArch64AsmPrinter::emitPtrauthSign(
const MachineInstr *
MI) {
2534 Register AddrDisc =
MI->getOperand(4).getReg();
2535 bool AddrDiscKilled =
MI->getOperand(4).isKill();
2539 Register ScratchReg = Val == AArch64::X16 ? AArch64::X17 : AArch64::X16;
2540 assert(ScratchReg != AddrDisc &&
2541 "Neither X16 nor X17 is available as a scratch register");
2544 Register DiscReg = emitPtrauthDiscriminator(
2545 Disc, AddrDisc, ScratchReg, AddrDiscKilled);
2547 if (emitDeactivationSymbolRelocation(
MI->getDeactivationSymbol()))
2550 emitPAC(
Key, Val, DiscReg);
2553void AArch64AsmPrinter::emitPtrauthBranch(
const MachineInstr *
MI) {
2554 bool IsCall =
MI->getOpcode() == AArch64::BLRA;
2555 unsigned BrTarget =
MI->getOperand(0).getReg();
2560 unsigned AddrDisc =
MI->getOperand(3).getReg();
2566 if (BrTarget == AddrDisc)
2583 bool AddrDiscIsImplicitDef =
2584 IsCall && (AddrDisc == AArch64::X16 || AddrDisc == AArch64::X17);
2585 Register DiscReg = emitPtrauthDiscriminator(Disc, AddrDisc, AArch64::X17,
2586 AddrDiscIsImplicitDef);
2587 emitBLRA(IsCall,
Key, BrTarget, DiscReg);
2590void AArch64AsmPrinter::emitAddImm(MCRegister
Reg, int64_t Addend,
2594 const bool IsNeg = Addend < 0;
2596 for (
int BitPos = 0; BitPos != 24 && (AbsOffset >> BitPos);
2599 MCInstBuilder(IsNeg ? AArch64::SUBXri : AArch64::ADDXri)
2602 .addImm((AbsOffset >> BitPos) & 0xfff)
2607 EmitToStreamer(MCInstBuilder(IsNeg ? AArch64::MOVNXi : AArch64::MOVZXi)
2609 .addImm((IsNeg ? ~UAddend : UAddend) & 0xffff)
2611 auto NeedMovk = [IsNeg, UAddend](
int BitPos) ->
bool {
2612 assert(BitPos == 16 || BitPos == 32 || BitPos == 48);
2613 uint64_t Shifted = UAddend >> BitPos;
2615 return Shifted != 0;
2616 for (
int I = 0;
I != 64 - BitPos;
I += 16)
2617 if (((Shifted >>
I) & 0xffff) != 0xffff)
2621 for (
int BitPos = 16; BitPos != 64 && NeedMovk(BitPos); BitPos += 16)
2622 emitMOVK(Tmp, (UAddend >> BitPos) & 0xffff, BitPos);
2624 EmitToStreamer(MCInstBuilder(AArch64::ADDXrs)
2633void AArch64AsmPrinter::emitAddress(MCRegister
Reg,
const MCExpr *Expr,
2634 MCRegister Tmp,
bool DSOLocal,
2635 const MCSubtargetInfo &STI) {
2641 MCInstBuilder(AArch64::ADRP)
2645 EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
2655 MCInstBuilder(AArch64::ADRP)
2660 MCInstBuilder(AArch64::LDRXui)
2671 if (!TT.isOSBinFormatELF())
2675 return TT.isOSGlibc() || TT.isAndroid() || TT.isOSFreeBSD() ||
2676 TT.isOSDragonFly() || TT.isOSNetBSD();
2730const MCExpr *AArch64AsmPrinter::emitPAuthRelocationAsIRelative(
2732 bool HasAddressDiversity,
bool IsDSOLocal,
const MCExpr *DSExpr) {
2733 const Triple &
TT = TM.getTargetTriple();
2745 auto STI = std::make_unique<AArch64Subtarget>(
2746 TT, TM.getTargetCPU(), TM.getTargetCPU(), TM.getTargetFeatureString(), TM,
2748 this->STI = STI.get();
2754 const MCSymbolELF *Group =
2769 .addReg(AArch64::X0)
2774 emitAddress(AArch64::X0, Target, AArch64::X16, IsDSOLocal, *STI);
2776 if (HasAddressDiversity) {
2781 emitAddress(AArch64::X1, PlacePlusDisc, AArch64::X16,
true,
2785 OutContext.reportError(SMLoc(),
"AArch64 PAC Discriminator '" +
2787 "' out of range [0, 0xFFFF]");
2789 emitMOVZ(AArch64::X1, Disc, 0);
2796 auto *PrePACInstExpr =
2808 const MCSymbolRefExpr *EmuPACRef =
2810 OutStreamer->
emitInstruction(MCInstBuilder(AArch64::B).addExpr(EmuPACRef),
2817 MCInstBuilder(AArch64::RET).addReg(AArch64::LR), *STI);
2826AArch64AsmPrinter::lowerConstantPtrAuth(
const ConstantPtrAuth &CPA) {
2827 MCContext &Ctx = OutContext;
2832 getDataLayout(),
Offset,
true);
2852 const MCExpr *DSExpr =
nullptr;
2864 "' out of range [0, " +
2872 if (
auto *IFuncSym = emitPAuthRelocationAsIRelative(
2874 BaseGVB && BaseGVB->isDSOLocal(), DSExpr))
2879 "' out of range [0, 0xFFFF]");
2885 "expressions on this target");
2892void AArch64AsmPrinter::LowerLOADauthptrstatic(
const MachineInstr &
MI) {
2893 unsigned DstReg =
MI.getOperand(0).getReg();
2894 const MachineOperand &GAOp =
MI.getOperand(1);
2895 const uint64_t KeyC =
MI.getOperand(2).getImm();
2897 "key is out of range [0, AArch64PACKey::LAST]");
2899 const uint64_t Disc =
MI.getOperand(3).getImm();
2901 "constant discriminator is out of range [0, 0xffff]");
2910 if (TM.getTargetTriple().isOSBinFormatELF()) {
2912 static_cast<const AArch64_ELFTargetObjectFile &
>(getObjFileLowering());
2915 "non-zero offset for $auth_ptr$ stub slots is not supported");
2917 AuthPtrStubSym = TLOF.getAuthPtrSlotSymbol(TM, MMI, GASym,
Key, Disc);
2919 assert(TM.getTargetTriple().isOSBinFormatMachO() &&
2920 "LOADauthptrstatic is implemented only for MachO/ELF");
2922 const auto &TLOF =
static_cast<const AArch64_MachoTargetObjectFile &
>(
2923 getObjFileLowering());
2926 "non-zero offset for $auth_ptr$ stub slots is not supported");
2928 AuthPtrStubSym = TLOF.getAuthPtrSlotSymbol(TM, MMI, GASym,
Key, Disc);
2931 MachineOperand StubMOHi =
2935 MCOperand StubMCHi, StubMCLo;
2942 MCInstBuilder(AArch64::ADRP).addReg(DstReg).
addOperand(StubMCHi));
2944 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::LDRXui)
2950void AArch64AsmPrinter::LowerMOVaddrPAC(
const MachineInstr &
MI) {
2951 const bool IsGOTLoad =
MI.getOpcode() == AArch64::LOADgotPAC;
2952 const bool IsELFSignedGOT =
MI.getParent()
2954 ->getInfo<AArch64FunctionInfo>()
2955 ->hasELFSignedGOT();
2956 MachineOperand GAOp =
MI.getOperand(0);
2957 const uint64_t KeyC =
MI.getOperand(1).getImm();
2959 "key is out of range [0, AArch64PACKey::LAST]");
2961 const unsigned AddrDisc =
MI.getOperand(2).getReg();
2962 const uint64_t Disc =
MI.getOperand(3).getImm();
3009 MachineOperand GAMOHi(GAOp), GAMOLo(GAOp);
3010 MCOperand GAMCHi, GAMCLo;
3023 MCInstBuilder(AArch64::ADRP)
3024 .addReg(IsGOTLoad && IsELFSignedGOT ? AArch64::X17 : AArch64::X16)
3028 if (IsELFSignedGOT) {
3029 EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
3030 .addReg(AArch64::X17)
3031 .addReg(AArch64::X17)
3035 EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
3036 .addReg(AArch64::X16)
3037 .addReg(AArch64::X17)
3045 emitAUT(AuthKey, AArch64::X16, AArch64::X17);
3047 if (!STI->hasFPAC())
3048 emitPtrauthCheckAuthenticatedValue(AArch64::X16, AArch64::X17, AuthKey,
3049 AArch64PAuth::AuthCheckMethod::XPAC);
3051 EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
3052 .addReg(AArch64::X16)
3053 .addReg(AArch64::X16)
3057 EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
3058 .addReg(AArch64::X16)
3059 .addReg(AArch64::X16)
3064 emitAddImm(AArch64::X16,
Offset, AArch64::X17);
3065 Register DiscReg = emitPtrauthDiscriminator(Disc, AddrDisc, AArch64::X17);
3067 emitPAC(
Key, AArch64::X16, DiscReg);
3070void AArch64AsmPrinter::LowerLOADgotAUTH(
const MachineInstr &
MI) {
3072 Register AuthResultReg = STI->hasFPAC() ? DstReg : AArch64::X16;
3073 const MachineOperand &GAMO =
MI.getOperand(1);
3080 MCInstBuilder(AArch64::ADR).addReg(AArch64::X17).
addOperand(GAMC));
3081 EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
3082 .addReg(AuthResultReg)
3083 .addReg(AArch64::X17)
3086 MachineOperand GAHiOp(GAMO);
3087 MachineOperand GALoOp(GAMO);
3091 MCOperand GAMCHi, GAMCLo;
3096 MCInstBuilder(AArch64::ADRP).addReg(AArch64::X17).
addOperand(GAMCHi));
3098 EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
3099 .addReg(AArch64::X17)
3100 .addReg(AArch64::X17)
3104 EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
3105 .addReg(AuthResultReg)
3106 .addReg(AArch64::X17)
3113 UndefWeakSym = createTempSymbol(
"undef_weak");
3115 MCInstBuilder(AArch64::CBZX)
3116 .addReg(AuthResultReg)
3124 emitAUT(AuthKey, AuthResultReg, AArch64::X17);
3129 if (!STI->hasFPAC()) {
3130 emitPtrauthCheckAuthenticatedValue(AuthResultReg, AArch64::X17, AuthKey,
3131 AArch64PAuth::AuthCheckMethod::XPAC);
3133 emitMovXReg(DstReg, AuthResultReg);
3138AArch64AsmPrinter::lowerBlockAddressConstant(
const BlockAddress &BA) {
3142 if (std::optional<uint16_t> BADisc =
3143 STI->getPtrAuthBlockAddressDiscriminatorIfEnabled(Fn))
3150void AArch64AsmPrinter::emitCBPseudoExpansion(
const MachineInstr *
MI) {
3154 switch (
MI->getOpcode()) {
3157 case AArch64::CBBAssertExt:
3161 case AArch64::CBHAssertExt:
3165 case AArch64::CBWPrr:
3168 case AArch64::CBXPrr:
3171 case AArch64::CBWPri:
3175 case AArch64::CBXPri:
3183 bool NeedsRegSwap =
false;
3184 bool NeedsImmDec =
false;
3185 bool NeedsImmInc =
false;
3187#define GET_CB_OPC(IsImm, Width, ImmCond, RegCond) \
3189 ? (Width == 32 ? AArch64::CB##ImmCond##Wri : AArch64::CB##ImmCond##Xri) \
3191 ? AArch64::CBB##RegCond##Wrr \
3192 : (Width == 16 ? AArch64::CBH##RegCond##Wrr \
3193 : (Width == 32 ? AArch64::CB##RegCond##Wrr \
3194 : AArch64::CB##RegCond##Xrr))))
3210 NeedsImmDec = IsImm;
3214 NeedsRegSwap = !IsImm;
3221 NeedsRegSwap = !IsImm;
3222 NeedsImmInc = IsImm;
3226 NeedsImmDec = IsImm;
3230 NeedsRegSwap = !IsImm;
3237 NeedsRegSwap = !IsImm;
3238 NeedsImmInc = IsImm;
3246 MCOperand Lhs, Rhs, Trgt;
3247 lowerOperand(
MI->getOperand(1), Lhs);
3248 lowerOperand(
MI->getOperand(2), Rhs);
3249 lowerOperand(
MI->getOperand(3), Trgt);
3253 assert(Lhs.
isReg() &&
"Expected register operand for CB");
3254 assert(Rhs.
isReg() &&
"Expected register operand for CB");
3257 }
else if (NeedsImmDec) {
3261 }
else if (NeedsImmInc) {
3271 "CB immediate operand out-of-bounds");
3274 EmitToStreamer(*OutStreamer, Inst);
3277void AArch64AsmPrinter::emitAtomicHintPseudoExpansion(
const MachineInstr *
MI) {
3280 unsigned Relaxed =
MI->getOperand(2).getImm();
3281 assert(
Relaxed < 2 &&
"Atomic hint relaxed immediate out-of-bounds");
3282 switch (
MI->getOpcode()) {
3283 case AArch64::ATOMIC_STORE_HINT_B:
3284 StOpc =
Relaxed ? AArch64::STRBBui : AArch64::STLRB;
3286 case AArch64::ATOMIC_STORE_HINT_H:
3287 StOpc =
Relaxed ? AArch64::STRHHui : AArch64::STLRH;
3289 case AArch64::ATOMIC_STORE_HINT_W:
3290 StOpc =
Relaxed ? AArch64::STRWui : AArch64::STLRW;
3292 case AArch64::ATOMIC_STORE_HINT_X:
3293 StOpc =
Relaxed ? AArch64::STRXui : AArch64::STLRX;
3300 MCInstBuilder(AArch64::HINT).addImm(
MI->getOperand(3).getImm()));
3303 Store.setOpcode(StOpc);
3306 Store.setFlags(
MI->getFlags());
3309 EmitToStreamer(*OutStreamer,
Store);
3312void AArch64AsmPrinter::emitAtomicHintPseudoExpansionRO(
3313 const MachineInstr *
MI) {
3315 assert(
MI->getOperand(5).getImm() == 1 &&
3316 "Atomic store addressing mode only supports relaxed stores");
3318 switch (
MI->getOpcode()) {
3319 case AArch64::ATOMIC_STORE_HINT_BroW:
3320 StOpc = AArch64::STRBBroW;
3322 case AArch64::ATOMIC_STORE_HINT_HroW:
3323 StOpc = AArch64::STRHHroW;
3325 case AArch64::ATOMIC_STORE_HINT_WroW:
3326 StOpc = AArch64::STRWroW;
3328 case AArch64::ATOMIC_STORE_HINT_XroW:
3329 StOpc = AArch64::STRXroW;
3331 case AArch64::ATOMIC_STORE_HINT_SroW:
3332 StOpc = AArch64::STRSroW;
3334 case AArch64::ATOMIC_STORE_HINT_DroW:
3335 StOpc = AArch64::STRDroW;
3337 case AArch64::ATOMIC_STORE_HINT_BroX:
3338 StOpc = AArch64::STRBBroX;
3340 case AArch64::ATOMIC_STORE_HINT_HroX:
3341 StOpc = AArch64::STRHHroX;
3343 case AArch64::ATOMIC_STORE_HINT_WroX:
3344 StOpc = AArch64::STRWroX;
3346 case AArch64::ATOMIC_STORE_HINT_XroX:
3347 StOpc = AArch64::STRXroX;
3349 case AArch64::ATOMIC_STORE_HINT_SroX:
3350 StOpc = AArch64::STRSroX;
3352 case AArch64::ATOMIC_STORE_HINT_DroX:
3353 StOpc = AArch64::STRDroX;
3360 MCInstBuilder(AArch64::HINT).addImm(
MI->getOperand(6).getImm()));
3363 Store.setOpcode(StOpc);
3369 Store.setFlags(
MI->getFlags());
3370 EmitToStreamer(*OutStreamer,
Store);
3373void AArch64AsmPrinter::emitAtomicHintPseudoExpansionImm(
3374 const MachineInstr *
MI) {
3376 assert(
MI->getOperand(3).getImm() == 1 &&
3377 "Atomic store addressing mode only supports relaxed stores");
3379 switch (
MI->getOpcode()) {
3380 case AArch64::ATOMIC_STORE_HINT_Bui:
3381 StOpc = AArch64::STRBBui;
3383 case AArch64::ATOMIC_STORE_HINT_Hui:
3384 StOpc = AArch64::STRHHui;
3386 case AArch64::ATOMIC_STORE_HINT_Wui:
3387 StOpc = AArch64::STRWui;
3389 case AArch64::ATOMIC_STORE_HINT_Xui:
3390 StOpc = AArch64::STRXui;
3392 case AArch64::ATOMIC_STORE_HINT_Sui:
3393 StOpc = AArch64::STRSui;
3395 case AArch64::ATOMIC_STORE_HINT_Dui:
3396 StOpc = AArch64::STRDui;
3398 case AArch64::ATOMIC_STORE_HINT_Bi:
3399 StOpc = AArch64::STURBBi;
3401 case AArch64::ATOMIC_STORE_HINT_Hi:
3402 StOpc = AArch64::STURHHi;
3404 case AArch64::ATOMIC_STORE_HINT_Wi:
3405 StOpc = AArch64::STURWi;
3407 case AArch64::ATOMIC_STORE_HINT_Xi:
3408 StOpc = AArch64::STURXi;
3410 case AArch64::ATOMIC_STORE_HINT_Si:
3411 StOpc = AArch64::STURSi;
3413 case AArch64::ATOMIC_STORE_HINT_Di:
3414 StOpc = AArch64::STURDi;
3421 MCInstBuilder(AArch64::HINT).addImm(
MI->getOperand(4).getImm()));
3424 Store.setOpcode(StOpc);
3428 Store.setFlags(
MI->getFlags());
3429 EmitToStreamer(*OutStreamer,
Store);
3432void AArch64AsmPrinter::emitAtomicFetchHintPseudoExpansion(
3433 const MachineInstr *
MI) {
3435 MCInstBuilder(AArch64::HINT).addImm(
MI->getOperand(4).getImm()));
3443 EmitToStreamer(*OutStreamer, Fetch);
3448#include "AArch64GenMCPseudoLowering.inc"
3450void AArch64AsmPrinter::EmitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3457void AArch64AsmPrinter::emitInstruction(
const MachineInstr *
MI) {
3458 AArch64_MC::verifyInstructionPredicates(
MI->getOpcode(), STI->
getFeatureBits());
3463 assert(STI->getInstrInfo()->getInstSizeInBytes(*
MI) >= InstsEmitted * 4);
3468 if (MCInst OutInst; lowerPseudoInstExpansion(
MI, OutInst)) {
3469 EmitToStreamer(*OutStreamer, OutInst);
3473 if (
MI->getOpcode() == AArch64::ADRP) {
3474 for (
auto &Opd :
MI->operands()) {
3475 if (Opd.isSymbol() && StringRef(Opd.getSymbolName()) ==
3476 "swift_async_extendedFramePointerFlags") {
3477 ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags =
true;
3484 MCSymbol *LOHLabel = createTempSymbol(
"loh");
3486 LOHInstToLabel[
MI] = LOHLabel;
3490 AArch64TargetStreamer *TS =
3493 switch (
MI->getOpcode()) {
3496 "Unhandled tail call instruction");
3498 case AArch64::READ_REGISTER_GPR64:
3502 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ORRXrs)
3503 .addReg(
MI->getOperand(0).getReg())
3504 .addReg(AArch64::XZR)
3505 .addReg(
MI->getOperand(1).getImm())
3508 case AArch64::READ_REGISTER_FPR64:
3510 EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::FMOVDr)
3511 .addReg(
MI->getOperand(0).getReg())
3512 .addReg(
MI->getOperand(1).getImm()));
3514 case AArch64::HINT: {
3519 if (CurrentPatchableFunctionEntrySym &&
3520 CurrentPatchableFunctionEntrySym == CurrentFnBegin &&
3522 int64_t
Imm =
MI->getOperand(0).getImm();
3523 if (
Imm == 32 ||
Imm == 34 ||
Imm == 36 ||
Imm == 38) {
3525 MCInstLowering.
Lower(
MI, Inst);
3526 EmitToStreamer(*OutStreamer, Inst);
3527 CurrentPatchableFunctionEntrySym = createTempSymbol(
"patch");
3528 OutStreamer->
emitLabel(CurrentPatchableFunctionEntrySym);
3534 case AArch64::MOVMCSym: {
3535 Register DestReg =
MI->getOperand(0).getReg();
3536 const MachineOperand &MO_Sym =
MI->getOperand(1);
3537 MachineOperand Hi_MOSym(MO_Sym), Lo_MOSym(MO_Sym);
3538 MCOperand Hi_MCSym, Lo_MCSym;
3551 EmitToStreamer(*OutStreamer, MovZ);
3559 EmitToStreamer(*OutStreamer, MovK);
3562 case AArch64::MOVIv2d_ns:
3570 if (STI->hasZeroCycleZeroingFPWorkaround() &&
3571 MI->getOperand(1).getImm() == 0) {
3573 TmpInst.
setOpcode(AArch64::MOVIv16b_ns);
3576 EmitToStreamer(*OutStreamer, TmpInst);
3581 case AArch64::DBG_VALUE:
3582 case AArch64::DBG_VALUE_LIST:
3584 SmallString<128> TmpStr;
3585 raw_svector_ostream OS(TmpStr);
3586 PrintDebugValueComment(
MI, OS);
3591 case AArch64::EMITBKEY:
3592 case AArch64::EMITNONHINTED: {
3594 if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
3595 ExceptionHandlingType != ExceptionHandling::ARM)
3598 if (getFunctionCFISectionType(*MF) == CFISection::None)
3601 if (
MI->getOpcode() == AArch64::EMITBKEY)
3609 case AArch64::EMITMTETAGGED: {
3611 if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
3612 ExceptionHandlingType != ExceptionHandling::ARM)
3615 if (getFunctionCFISectionType(*MF) != CFISection::None)
3620 case AArch64::AUTx16x17: {
3622 const Register Scratch = AArch64::X17;
3624 auto AuthSchema = PtrAuthSchema::CreateImmReg(
3626 MI->getOperand(1).getImm(),
MI->getOperand(2));
3628 emitPtrauthAuthResign(Pointer, Scratch, AuthSchema, std::nullopt,
3629 std::nullopt,
MI->getDeactivationSymbol());
3633 case AArch64::AUTxMxN: {
3635 const Register Scratch =
MI->getOperand(1).getReg();
3637 auto AuthSchema = PtrAuthSchema::CreateImmReg(
3639 MI->getOperand(4).getImm(),
MI->getOperand(5));
3641 emitPtrauthAuthResign(Pointer, Scratch, AuthSchema, std::nullopt,
3642 std::nullopt,
MI->getDeactivationSymbol());
3646 case AArch64::AUTPAC: {
3648 const Register Scratch = AArch64::X17;
3650 auto AuthSchema = PtrAuthSchema::CreateImmReg(
3652 MI->getOperand(1).getImm(),
MI->getOperand(2));
3654 auto SignSchema = PtrAuthSchema::CreateImmReg(
3656 MI->getOperand(4).getImm(),
MI->getOperand(5));
3658 emitPtrauthAuthResign(Pointer, Scratch, AuthSchema, SignSchema,
3659 std::nullopt,
MI->getDeactivationSymbol());
3663 case AArch64::AUTPCPAC: {
3664 auto AuthSchema = PtrAuthSchema::CreateRegReg(
3668 auto SignSchema = PtrAuthSchema::CreateImmReg(
3670 MI->getOperand(2).getImm(),
MI->getOperand(3));
3672 emitPtrauthAuthResign(AArch64::X17, AArch64::X16,
3673 AuthSchema, SignSchema, std::nullopt,
3674 MI->getDeactivationSymbol());
3678 case AArch64::AUTRELLOADPAC: {
3680 const Register Scratch = AArch64::X17;
3682 auto AuthSchema = PtrAuthSchema::CreateImmReg(
3684 MI->getOperand(1).getImm(),
MI->getOperand(2));
3686 auto SignSchema = PtrAuthSchema::CreateImmReg(
3688 MI->getOperand(4).getImm(),
MI->getOperand(5));
3690 emitPtrauthAuthResign(Pointer, Scratch, AuthSchema, SignSchema,
3691 MI->getOperand(6).getImm(),
3692 MI->getDeactivationSymbol());
3698 emitPtrauthSign(
MI);
3701 case AArch64::LOADauthptrstatic:
3702 LowerLOADauthptrstatic(*
MI);
3705 case AArch64::LOADgotPAC:
3706 case AArch64::MOVaddrPAC:
3707 LowerMOVaddrPAC(*
MI);
3710 case AArch64::LOADgotAUTH:
3711 LowerLOADgotAUTH(*
MI);
3716 emitPtrauthBranch(
MI);
3722 case AArch64::AUTH_TCRETURN:
3723 case AArch64::AUTH_TCRETURN_BTI: {
3726 const uint64_t Disc =
MI->getOperand(3).getImm();
3728 Register AddrDisc =
MI->getOperand(4).getReg();
3730 Register ScratchReg =
Callee == AArch64::X16 ? AArch64::X17 : AArch64::X16;
3732 emitPtrauthTailCallHardening(
MI);
3735 if (Callee == AddrDisc)
3742 bool AddrDiscIsImplicitDef =
3743 AddrDisc == AArch64::X16 || AddrDisc == AArch64::X17;
3744 Register DiscReg = emitPtrauthDiscriminator(Disc, AddrDisc, ScratchReg,
3745 AddrDiscIsImplicitDef);
3746 emitBLRA(
false,
Key, Callee, DiscReg);
3750 case AArch64::TCRETURNri:
3751 case AArch64::TCRETURNrix16x17:
3752 case AArch64::TCRETURNrix17:
3753 case AArch64::TCRETURNrinotx16:
3754 case AArch64::TCRETURNriALL: {
3755 emitPtrauthTailCallHardening(
MI);
3757 recordIfImportCall(
MI);
3761 EmitToStreamer(*OutStreamer, TmpInst);
3764 case AArch64::TCRETURNdi: {
3765 emitPtrauthTailCallHardening(
MI);
3769 recordIfImportCall(
MI);
3773 EmitToStreamer(*OutStreamer, TmpInst);
3776 case AArch64::SpeculationBarrierISBDSBEndBB: {
3781 EmitToStreamer(*OutStreamer, TmpInstDSB);
3785 EmitToStreamer(*OutStreamer, TmpInstISB);
3788 case AArch64::SpeculationBarrierSBEndBB: {
3792 EmitToStreamer(*OutStreamer, TmpInstSB);
3795 case AArch64::TLSDESC_AUTH_CALLSEQ: {
3803 const MachineOperand &MO_Sym =
MI->getOperand(0);
3804 MachineOperand MO_TLSDESC_LO12(MO_Sym), MO_TLSDESC(MO_Sym);
3805 MCOperand Sym, SymTLSDescLo12, SymTLSDesc;
3809 MCInstLowering.
lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
3816 EmitToStreamer(*OutStreamer, Adrp);
3824 EmitToStreamer(*OutStreamer, Ldr);
3827 Add.setOpcode(AArch64::ADDXri);
3830 Add.addOperand(SymTLSDescLo12);
3832 EmitToStreamer(*OutStreamer,
Add);
3836 MCInst TLSAuthDescCall;
3837 TLSAuthDescCall.
setOpcode(AArch64::TLSAUTHDESCCALL);
3839 EmitToStreamer(*OutStreamer, TLSAuthDescCall);
3848 EmitToStreamer(*OutStreamer, Blraa);
3852 case AArch64::TLSDESC_CALLSEQ: {
3860 const MachineOperand &MO_Sym =
MI->getOperand(0);
3861 MachineOperand MO_TLSDESC_LO12(MO_Sym), MO_TLSDESC(MO_Sym);
3862 MCOperand Sym, SymTLSDescLo12, SymTLSDesc;
3866 MCInstLowering.
lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
3873 EmitToStreamer(*OutStreamer, Adrp);
3876 if (STI->isTargetILP32()) {
3886 EmitToStreamer(*OutStreamer, Ldr);
3889 if (STI->isTargetILP32()) {
3890 Add.setOpcode(AArch64::ADDWri);
3894 Add.setOpcode(AArch64::ADDXri);
3898 Add.addOperand(SymTLSDescLo12);
3900 EmitToStreamer(*OutStreamer,
Add);
3905 TLSDescCall.
setOpcode(AArch64::TLSDESCCALL);
3907 EmitToStreamer(*OutStreamer, TLSDescCall);
3915 EmitToStreamer(*OutStreamer, Blr);
3920 case AArch64::JumpTableDest32:
3921 case AArch64::JumpTableDest16:
3922 case AArch64::JumpTableDest8:
3923 LowerJumpTableDest(*OutStreamer, *
MI);
3926 case AArch64::BR_JumpTable:
3927 LowerHardenedBRJumpTable(*
MI);
3930 case AArch64::FMOVH0:
3931 case AArch64::FMOVS0:
3932 case AArch64::FMOVD0:
3936 case AArch64::MOPSMemoryCopyPseudo:
3937 case AArch64::MOPSMemoryMovePseudo:
3938 case AArch64::MOPSMemorySetPseudo:
3939 case AArch64::MOPSMemorySetTaggingPseudo:
3940 LowerMOPS(*OutStreamer, *
MI);
3943 case TargetOpcode::STACKMAP:
3944 return LowerSTACKMAP(*OutStreamer, SM, *
MI);
3946 case TargetOpcode::PATCHPOINT:
3947 return LowerPATCHPOINT(*OutStreamer, SM, *
MI);
3949 case TargetOpcode::STATEPOINT:
3950 return LowerSTATEPOINT(*OutStreamer, SM, *
MI);
3952 case TargetOpcode::FAULTING_OP:
3953 return LowerFAULTING_OP(*
MI);
3955 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
3956 LowerPATCHABLE_FUNCTION_ENTER(*
MI);
3959 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
3960 LowerPATCHABLE_FUNCTION_EXIT(*
MI);
3963 case TargetOpcode::PATCHABLE_TAIL_CALL:
3964 LowerPATCHABLE_TAIL_CALL(*
MI);
3966 case TargetOpcode::PATCHABLE_EVENT_CALL:
3967 return LowerPATCHABLE_EVENT_CALL(*
MI,
false);
3968 case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
3969 return LowerPATCHABLE_EVENT_CALL(*
MI,
true);
3971 case AArch64::KCFI_CHECK:
3972 LowerKCFI_CHECK(*
MI);
3975 case AArch64::HWASAN_CHECK_MEMACCESS:
3976 case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
3977 case AArch64::HWASAN_CHECK_MEMACCESS_FIXEDSHADOW:
3978 case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW:
3979 LowerHWASAN_CHECK_MEMACCESS(*
MI);
3982 case AArch64::SEH_EndC:
3986 case AArch64::SEH_StackAlloc:
3990 case AArch64::SEH_SaveFPLR:
3994 case AArch64::SEH_SaveFPLR_X:
3995 assert(
MI->getOperand(0).getImm() < 0 &&
3996 "Pre increment SEH opcode must have a negative offset");
4000 case AArch64::SEH_SaveReg:
4002 MI->getOperand(1).getImm());
4005 case AArch64::SEH_SaveReg_X:
4006 assert(
MI->getOperand(1).getImm() < 0 &&
4007 "Pre increment SEH opcode must have a negative offset");
4009 -
MI->getOperand(1).getImm());
4012 case AArch64::SEH_SaveRegP:
4013 if (
MI->getOperand(1).getImm() == 30 &&
MI->getOperand(0).getImm() >= 19 &&
4014 MI->getOperand(0).getImm() <= 28) {
4015 assert((
MI->getOperand(0).getImm() - 19) % 2 == 0 &&
4016 "Register paired with LR must be odd");
4018 MI->getOperand(2).getImm());
4021 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
4022 "Non-consecutive registers not allowed for save_regp");
4024 MI->getOperand(2).getImm());
4027 case AArch64::SEH_SaveRegP_X:
4028 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
4029 "Non-consecutive registers not allowed for save_regp_x");
4030 assert(
MI->getOperand(2).getImm() < 0 &&
4031 "Pre increment SEH opcode must have a negative offset");
4033 -
MI->getOperand(2).getImm());
4036 case AArch64::SEH_SaveFReg:
4038 MI->getOperand(1).getImm());
4041 case AArch64::SEH_SaveFReg_X:
4042 assert(
MI->getOperand(1).getImm() < 0 &&
4043 "Pre increment SEH opcode must have a negative offset");
4045 -
MI->getOperand(1).getImm());
4048 case AArch64::SEH_SaveFRegP:
4049 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
4050 "Non-consecutive registers not allowed for save_regp");
4052 MI->getOperand(2).getImm());
4055 case AArch64::SEH_SaveFRegP_X:
4056 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
4057 "Non-consecutive registers not allowed for save_regp_x");
4058 assert(
MI->getOperand(2).getImm() < 0 &&
4059 "Pre increment SEH opcode must have a negative offset");
4061 -
MI->getOperand(2).getImm());
4064 case AArch64::SEH_SetFP:
4068 case AArch64::SEH_AddFP:
4072 case AArch64::SEH_Nop:
4076 case AArch64::SEH_PrologEnd:
4080 case AArch64::SEH_EpilogStart:
4084 case AArch64::SEH_EpilogEnd:
4088 case AArch64::SEH_PACSignLR:
4092 case AArch64::SEH_SaveAnyRegI:
4093 assert(
MI->getOperand(1).getImm() <= 1008 &&
4094 "SaveAnyRegQP SEH opcode offset must fit into 6 bits");
4096 MI->getOperand(1).getImm());
4099 case AArch64::SEH_SaveAnyRegIP:
4100 assert(
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1 &&
4101 "Non-consecutive registers not allowed for save_any_reg");
4102 assert(
MI->getOperand(2).getImm() <= 1008 &&
4103 "SaveAnyRegQP SEH opcode offset must fit into 6 bits");
4105 MI->getOperand(2).getImm());
4108 case AArch64::SEH_SaveAnyRegQP:
4109 assert(
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1 &&
4110 "Non-consecutive registers not allowed for save_any_reg");
4111 assert(
MI->getOperand(2).getImm() >= 0 &&
4112 "SaveAnyRegQP SEH opcode offset must be non-negative");
4113 assert(
MI->getOperand(2).getImm() <= 1008 &&
4114 "SaveAnyRegQP SEH opcode offset must fit into 6 bits");
4116 MI->getOperand(2).getImm());
4119 case AArch64::SEH_SaveAnyRegQPX:
4120 assert(
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1 &&
4121 "Non-consecutive registers not allowed for save_any_reg");
4122 assert(
MI->getOperand(2).getImm() < 0 &&
4123 "SaveAnyRegQPX SEH opcode offset must be negative");
4124 assert(
MI->getOperand(2).getImm() >= -1008 &&
4125 "SaveAnyRegQPX SEH opcode offset must fit into 6 bits");
4127 -
MI->getOperand(2).getImm());
4130 case AArch64::SEH_AllocZ:
4131 assert(
MI->getOperand(0).getImm() >= 0 &&
4132 "AllocZ SEH opcode offset must be non-negative");
4133 assert(
MI->getOperand(0).getImm() <= 255 &&
4134 "AllocZ SEH opcode offset must fit into 8 bits");
4138 case AArch64::SEH_SaveZReg:
4139 assert(
MI->getOperand(1).getImm() >= 0 &&
4140 "SaveZReg SEH opcode offset must be non-negative");
4141 assert(
MI->getOperand(1).getImm() <= 255 &&
4142 "SaveZReg SEH opcode offset must fit into 8 bits");
4144 MI->getOperand(1).getImm());
4147 case AArch64::SEH_SavePReg:
4148 assert(
MI->getOperand(1).getImm() >= 0 &&
4149 "SavePReg SEH opcode offset must be non-negative");
4150 assert(
MI->getOperand(1).getImm() <= 255 &&
4151 "SavePReg SEH opcode offset must fit into 8 bits");
4153 MI->getOperand(1).getImm());
4158 recordIfImportCall(
MI);
4160 MCInstLowering.
Lower(
MI, TmpInst);
4161 EmitToStreamer(*OutStreamer, TmpInst);
4164 case AArch64::CBWPri:
4165 case AArch64::CBXPri:
4166 case AArch64::CBBAssertExt:
4167 case AArch64::CBHAssertExt:
4168 case AArch64::CBWPrr:
4169 case AArch64::CBXPrr:
4170 emitCBPseudoExpansion(
MI);
4172 case AArch64::ATOMIC_STORE_HINT_B:
4173 case AArch64::ATOMIC_STORE_HINT_H:
4174 case AArch64::ATOMIC_STORE_HINT_W:
4175 case AArch64::ATOMIC_STORE_HINT_X:
4176 emitAtomicHintPseudoExpansion(
MI);
4178 case AArch64::ATOMIC_FETCH_HINT_W:
4179 case AArch64::ATOMIC_FETCH_HINT_X:
4180 emitAtomicFetchHintPseudoExpansion(
MI);
4182 case AArch64::ATOMIC_STORE_HINT_BroW:
4183 case AArch64::ATOMIC_STORE_HINT_HroW:
4184 case AArch64::ATOMIC_STORE_HINT_WroW:
4185 case AArch64::ATOMIC_STORE_HINT_XroW:
4186 case AArch64::ATOMIC_STORE_HINT_SroW:
4187 case AArch64::ATOMIC_STORE_HINT_DroW:
4188 case AArch64::ATOMIC_STORE_HINT_BroX:
4189 case AArch64::ATOMIC_STORE_HINT_HroX:
4190 case AArch64::ATOMIC_STORE_HINT_WroX:
4191 case AArch64::ATOMIC_STORE_HINT_XroX:
4192 case AArch64::ATOMIC_STORE_HINT_SroX:
4193 case AArch64::ATOMIC_STORE_HINT_DroX:
4194 emitAtomicHintPseudoExpansionRO(
MI);
4196 case AArch64::ATOMIC_STORE_HINT_Bui:
4197 case AArch64::ATOMIC_STORE_HINT_Hui:
4198 case AArch64::ATOMIC_STORE_HINT_Wui:
4199 case AArch64::ATOMIC_STORE_HINT_Xui:
4200 case AArch64::ATOMIC_STORE_HINT_Sui:
4201 case AArch64::ATOMIC_STORE_HINT_Dui:
4202 case AArch64::ATOMIC_STORE_HINT_Bi:
4203 case AArch64::ATOMIC_STORE_HINT_Hi:
4204 case AArch64::ATOMIC_STORE_HINT_Wi:
4205 case AArch64::ATOMIC_STORE_HINT_Xi:
4206 case AArch64::ATOMIC_STORE_HINT_Si:
4207 case AArch64::ATOMIC_STORE_HINT_Di:
4208 emitAtomicHintPseudoExpansionImm(
MI);
4212 if (emitDeactivationSymbolRelocation(
MI->getDeactivationSymbol()))
4217 MCInstLowering.
Lower(
MI, TmpInst);
4218 EmitToStreamer(*OutStreamer, TmpInst);
4221void AArch64AsmPrinter::recordIfImportCall(
4222 const llvm::MachineInstr *BranchInst) {
4223 if (!EnableImportCallOptimization)
4227 if (GV && GV->hasDLLImportStorageClass()) {
4228 auto *CallSiteSymbol = MMI->getContext().createNamedTempSymbol(
"impcall");
4233 .push_back({CallSiteSymbol, CalledSymbol});
4237void AArch64AsmPrinter::emitMachOIFuncStubBody(
Module &M,
const GlobalIFunc &GI,
4238 MCSymbol *LazyPointer) {
4255 EmitToStreamer(Adrp);
4263 MCOperand SymPageOff;
4270 EmitToStreamer(Ldr);
4273 EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
4274 .addReg(AArch64::X16)
4275 .addReg(AArch64::X16)
4278 EmitToStreamer(MCInstBuilder(TM.getTargetTriple().isArm64e() ? AArch64::BRAAZ
4280 .addReg(AArch64::X16));
4283void AArch64AsmPrinter::emitMachOIFuncStubHelperBody(
Module &M,
4284 const GlobalIFunc &GI,
4285 MCSymbol *LazyPointer) {
4317 EmitToStreamer(MCInstBuilder(AArch64::STPXpre)
4318 .addReg(AArch64::SP)
4319 .addReg(AArch64::FP)
4320 .addReg(AArch64::LR)
4321 .addReg(AArch64::SP)
4324 EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
4325 .addReg(AArch64::FP)
4326 .addReg(AArch64::SP)
4330 for (
int I = 0;
I != 4; ++
I)
4331 EmitToStreamer(MCInstBuilder(AArch64::STPXpre)
4332 .addReg(AArch64::SP)
4333 .addReg(AArch64::X1 + 2 *
I)
4334 .addReg(AArch64::X0 + 2 *
I)
4335 .addReg(AArch64::SP)
4338 for (
int I = 0;
I != 4; ++
I)
4339 EmitToStreamer(MCInstBuilder(AArch64::STPDpre)
4340 .addReg(AArch64::SP)
4341 .addReg(AArch64::D1 + 2 *
I)
4342 .addReg(AArch64::D0 + 2 *
I)
4343 .addReg(AArch64::SP)
4347 MCInstBuilder(AArch64::BL)
4360 EmitToStreamer(Adrp);
4368 MCOperand SymPageOff;
4375 EmitToStreamer(Ldr);
4378 EmitToStreamer(MCInstBuilder(AArch64::STRXui)
4379 .addReg(AArch64::X0)
4380 .addReg(AArch64::X16)
4383 EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
4384 .addReg(AArch64::X16)
4385 .addReg(AArch64::X0)
4389 for (
int I = 3;
I != -1; --
I)
4390 EmitToStreamer(MCInstBuilder(AArch64::LDPDpost)
4391 .addReg(AArch64::SP)
4392 .addReg(AArch64::D1 + 2 *
I)
4393 .addReg(AArch64::D0 + 2 *
I)
4394 .addReg(AArch64::SP)
4397 for (
int I = 3;
I != -1; --
I)
4398 EmitToStreamer(MCInstBuilder(AArch64::LDPXpost)
4399 .addReg(AArch64::SP)
4400 .addReg(AArch64::X1 + 2 *
I)
4401 .addReg(AArch64::X0 + 2 *
I)
4402 .addReg(AArch64::SP)
4405 EmitToStreamer(MCInstBuilder(AArch64::LDPXpost)
4406 .addReg(AArch64::SP)
4407 .addReg(AArch64::FP)
4408 .addReg(AArch64::LR)
4409 .addReg(AArch64::SP)
4412 EmitToStreamer(MCInstBuilder(TM.getTargetTriple().isArm64e() ? AArch64::BRAAZ
4414 .addReg(AArch64::X16));
4417const MCExpr *AArch64AsmPrinter::lowerConstant(
const Constant *CV,
4418 const Constant *BaseCV,
4428char AArch64AsmPrinter::ID = 0;
4431 "AArch64 Assembly Printer",
false,
false)
4435LLVMInitializeAArch64AsmPrinter() {
4445 AArch64AsmPrinter &
AsmPrinter =
static_cast<AArch64AsmPrinter &
>(
4455 AArch64AsmPrinter &
AsmPrinter =
static_cast<AArch64AsmPrinter &
>(
4466 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 emitARM64WinCFIEndC()
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 void emitBasicBlockEnd(const MachineBasicBlock &MBB)
Targets can override this to emit stuff at the end of a basic block.
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 setFlags(unsigned F)
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 ....
virtual void emitCFINonHintPAuthFrame()
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.
bool usesWindowsUnwindInfo() const
True if this function describes its unwind information with Windows SEH unwind opcodes (....
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.
self_iterator getIterator()
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()
auto reverse(ContainerTy &&C)
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.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
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,...