80    cl::desc(
"Check pointer authentication auth/resign failures"),
 
   83#define DEBUG_TYPE "asm-printer" 
   91  bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = 
false;
 
   93  unsigned InstsEmitted;
 
   95  bool EnableImportCallOptimization = 
false;
 
   97      SectionToImportedFunctionCalls;
 
  102  AArch64AsmPrinter(
TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
 
  104        MCInstLowering(OutContext, *
this), FM(*
this) {}
 
  106  StringRef getPassName()
 const override { 
return "AArch64 Assembly Printer"; }
 
  118  void emitStartOfAsmFile(
Module &M) 
override;
 
  123  getCodeViewJumpTableInfo(
int JTI, 
const MachineInstr *BranchInstr,
 
  124                           const MCSymbol *BranchLabel) 
const override;
 
  126  void emitFunctionEntryLabel() 
override;
 
  147  void LowerPATCHABLE_EVENT_CALL(
const MachineInstr &
MI, 
bool Typed);
 
  149  typedef std::tuple<unsigned, bool, uint32_t, bool, uint64_t>
 
  150      HwasanMemaccessTuple;
 
  151  std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
 
  154  void emitHwasanMemaccessSymbols(
Module &M);
 
  161  void emitPtrauthCheckAuthenticatedValue(
Register TestedReg,
 
  169  void emitPtrauthTailCallHardening(
const MachineInstr *TC);
 
  176                             std::optional<AArch64PACKey::ID> PACKey,
 
  201                                    bool MayUseAddrAsScratch = 
false);
 
  220  void emitAttributes(
unsigned Flags, 
uint64_t PAuthABIPlatform,
 
  227  void EmitToStreamer(
const MCInst &Inst) {
 
  228    EmitToStreamer(*OutStreamer, Inst);
 
  233  void emitFunctionHeaderComment() 
override;
 
  241    if (
auto *PSIW = getAnalysisIfAvailable<ProfileSummaryInfoWrapperPass>())
 
  242      PSI = &PSIW->getPSI();
 
  244            getAnalysisIfAvailable<StaticDataProfileInfoWrapperPass>())
 
  245      SDPI = &SDPIW->getStaticDataProfileInfo();
 
  250    SetupMachineFunction(MF);
 
  252    if (STI->isTargetCOFF()) {
 
  288  bool PrintAsmMemoryOperand(
const MachineInstr *
MI, 
unsigned OpNum,
 
  293  void emitFunctionBodyEnd() 
override;
 
  296  MCSymbol *GetCPISymbol(
unsigned CPID) 
const override;
 
  297  void emitEndOfAsmFile(
Module &M) 
override;
 
  312  using MInstToMCSymbol = std::map<const MachineInstr *, MCSymbol *>;
 
  314  MInstToMCSymbol LOHInstToLabel;
 
  316  bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags()
 const override {
 
  317    return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags;
 
  337void AArch64AsmPrinter::emitStartOfAsmFile(
Module &M) {
 
  338  const Triple &
TT = 
TM.getTargetTriple();
 
  340  if (
TT.isOSBinFormatCOFF()) {
 
  341    emitCOFFFeatureSymbol(M);
 
  342    emitCOFFReplaceableFunctionData(M);
 
  344    if (
M.getModuleFlag(
"import-call-optimization"))
 
  345      EnableImportCallOptimization = 
true;
 
  348  if (!
TT.isOSBinFormatELF())
 
  353      static_cast<AArch64TargetStreamer *
>(OutStreamer->getTargetStreamer());
 
  356  unsigned BAFlags = 0;
 
  357  unsigned GNUFlags = 0;
 
  359          M.getModuleFlag(
"branch-target-enforcement"))) {
 
  360    if (!BTE->isZero()) {
 
  361      BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_BTI_Flag;
 
  367          M.getModuleFlag(
"guarded-control-stack"))) {
 
  368    if (!GCS->isZero()) {
 
  369      BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_GCS_Flag;
 
  375          M.getModuleFlag(
"sign-return-address"))) {
 
  376    if (!Sign->isZero()) {
 
  377      BAFlags |= AArch64BuildAttributes::FeatureAndBitsFlag::Feature_PAC_Flag;
 
  382  uint64_t PAuthABIPlatform = -1;
 
  384          M.getModuleFlag(
"aarch64-elf-pauthabi-platform"))) {
 
  385    PAuthABIPlatform = PAP->getZExtValue();
 
  388  uint64_t PAuthABIVersion = -1;
 
  390          M.getModuleFlag(
"aarch64-elf-pauthabi-version"))) {
 
  391    PAuthABIVersion = PAV->getZExtValue();
 
  395  emitAttributes(BAFlags, PAuthABIPlatform, PAuthABIVersion, TS);
 
  397  TS->emitNoteSection(GNUFlags, PAuthABIPlatform, PAuthABIVersion);
 
  400void AArch64AsmPrinter::emitFunctionHeaderComment() {
 
  401  const AArch64FunctionInfo *FI = MF->getInfo<AArch64FunctionInfo>();
 
  403  if (OutlinerString != std::nullopt)
 
  404    OutStreamer->getCommentOS() << 
' ' << OutlinerString;
 
  407void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr &
MI)
 
  410  if (
F.hasFnAttribute(
"patchable-function-entry")) {
 
  412    if (
F.getFnAttribute(
"patchable-function-entry")
 
  414            .getAsInteger(10, Num))
 
  420  emitSled(
MI, SledKind::FUNCTION_ENTER);
 
  423void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr &
MI) {
 
  424  emitSled(
MI, SledKind::FUNCTION_EXIT);
 
  427void AArch64AsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr &
MI) {
 
  428  emitSled(
MI, SledKind::TAIL_CALL);
 
  431void AArch64AsmPrinter::emitSled(
const MachineInstr &
MI, SledKind Kind) {
 
  432  static const int8_t NoopsInSledCount = 7;
 
  453  OutStreamer->emitCodeAlignment(
Align(4), &getSubtargetInfo());
 
  454  auto CurSled = OutContext.createTempSymbol(
"xray_sled_", 
true);
 
  455  OutStreamer->emitLabel(CurSled);
 
  456  auto Target = OutContext.createTempSymbol();
 
  461  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::B).addImm(8));
 
  463  for (int8_t 
I = 0; 
I < NoopsInSledCount; 
I++)
 
  464    EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
 
  466  OutStreamer->emitLabel(Target);
 
  467  recordSled(CurSled, 
MI, Kind, 2);
 
  470void AArch64AsmPrinter::emitAttributes(
unsigned Flags,
 
  471                                       uint64_t PAuthABIPlatform,
 
  472                                       uint64_t PAuthABIVersion,
 
  473                                       AArch64TargetStreamer *TS) {
 
  475  PAuthABIPlatform = (uint64_t(-1) == PAuthABIPlatform) ? 0 : PAuthABIPlatform;
 
  476  PAuthABIVersion = (uint64_t(-1) == PAuthABIVersion) ? 0 : PAuthABIVersion;
 
  478  if (PAuthABIPlatform || PAuthABIVersion) {
 
  482        AArch64BuildAttributes::SubsectionOptional::REQUIRED,
 
  483        AArch64BuildAttributes::SubsectionType::ULEB128);
 
  487                      PAuthABIPlatform, 
"");
 
  501  if (BTIValue || PACValue || GCSValue) {
 
  505        AArch64BuildAttributes::SubsectionOptional::OPTIONAL,
 
  506        AArch64BuildAttributes::SubsectionType::ULEB128);
 
  534void AArch64AsmPrinter::LowerPATCHABLE_EVENT_CALL(
const MachineInstr &
MI,
 
  536  auto &
O = *OutStreamer;
 
  537  MCSymbol *CurSled = OutContext.createTempSymbol(
"xray_sled_", 
true);
 
  538  O.emitLabel(CurSled);
 
  539  bool MachO = 
TM.getTargetTriple().isOSBinFormatMachO();
 
  541      OutContext.getOrCreateSymbol(
 
  542          Twine(MachO ? 
"_" : 
"") +
 
  543          (Typed ? 
"__xray_TypedEvent" : 
"__xray_CustomEvent")),
 
  546    O.AddComment(
"Begin XRay typed event");
 
  547    EmitToStreamer(O, MCInstBuilder(AArch64::B).addImm(9));
 
  548    EmitToStreamer(O, MCInstBuilder(AArch64::STPXpre)
 
  554    EmitToStreamer(O, MCInstBuilder(AArch64::STRXui)
 
  558    emitMovXReg(AArch64::X0, 
MI.getOperand(0).getReg());
 
  559    emitMovXReg(AArch64::X1, 
MI.getOperand(1).getReg());
 
  560    emitMovXReg(AArch64::X2, 
MI.getOperand(2).getReg());
 
  561    EmitToStreamer(O, MCInstBuilder(AArch64::BL).addExpr(Sym));
 
  562    EmitToStreamer(O, MCInstBuilder(AArch64::LDRXui)
 
  566    O.AddComment(
"End XRay typed event");
 
  567    EmitToStreamer(O, MCInstBuilder(AArch64::LDPXpost)
 
  574    recordSled(CurSled, 
MI, SledKind::TYPED_EVENT, 2);
 
  576    O.AddComment(
"Begin XRay custom event");
 
  577    EmitToStreamer(O, MCInstBuilder(AArch64::B).addImm(6));
 
  578    EmitToStreamer(O, MCInstBuilder(AArch64::STPXpre)
 
  584    emitMovXReg(AArch64::X0, 
MI.getOperand(0).getReg());
 
  585    emitMovXReg(AArch64::X1, 
MI.getOperand(1).getReg());
 
  586    EmitToStreamer(O, MCInstBuilder(AArch64::BL).addExpr(Sym));
 
  587    O.AddComment(
"End XRay custom event");
 
  588    EmitToStreamer(O, MCInstBuilder(AArch64::LDPXpost)
 
  595    recordSled(CurSled, 
MI, SledKind::CUSTOM_EVENT, 2);
 
  599void AArch64AsmPrinter::LowerKCFI_CHECK(
const MachineInstr &
MI) {
 
  601  assert(std::next(
MI.getIterator())->isCall() &&
 
  602         "KCFI_CHECK not followed by a call instruction");
 
  603  assert(std::next(
MI.getIterator())->getOperand(0).getReg() == AddrReg &&
 
  604         "KCFI_CHECK call target doesn't match call operand");
 
  608  unsigned ScratchRegs[] = {AArch64::W16, AArch64::W17};
 
  609  if (AddrReg == AArch64::XZR) {
 
  613    emitMovXReg(AddrReg, AArch64::XZR);
 
  619    for (
auto &
Reg : ScratchRegs) {
 
  625    assert(ScratchRegs[0] != AddrReg && ScratchRegs[1] != AddrReg &&
 
  626           "Invalid scratch registers for KCFI_CHECK");
 
  630    int64_t PrefixNops = 0;
 
  633        .getFnAttribute(
"patchable-function-prefix")
 
  635        .getAsInteger(10, PrefixNops);
 
  638    EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::LDURWi)
 
  639                                     .addReg(ScratchRegs[0])
 
  641                                     .addImm(-(PrefixNops * 4 + 4)));
 
  645  const int64_t 
Type = 
MI.getOperand(1).getImm();
 
  646  emitMOVK(ScratchRegs[1], 
Type & 0xFFFF, 0);
 
  647  emitMOVK(ScratchRegs[1], (
Type >> 16) & 0xFFFF, 16);
 
  650  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::SUBSWrs)
 
  651                                   .addReg(AArch64::WZR)
 
  652                                   .addReg(ScratchRegs[0])
 
  653                                   .addReg(ScratchRegs[1])
 
  657  EmitToStreamer(*OutStreamer,
 
  658                 MCInstBuilder(AArch64::Bcc)
 
  667  unsigned TypeIndex = ScratchRegs[1] - AArch64::W0;
 
  671    AddrIndex = AddrReg - AArch64::X0;
 
  681  assert(AddrIndex < 31 && TypeIndex < 31);
 
  683  unsigned ESR = 0x8000 | ((TypeIndex & 31) << 5) | (AddrIndex & 31);
 
  684  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::BRK).addImm(ESR));
 
  685  OutStreamer->emitLabel(
Pass);
 
  688void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
 
  696  if (
Reg == AArch64::XZR)
 
  700      ((
MI.getOpcode() == AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES) ||
 
  702        AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW));
 
  703  uint32_t AccessInfo = 
MI.getOperand(1).getImm();
 
  705      ((
MI.getOpcode() == AArch64::HWASAN_CHECK_MEMACCESS_FIXEDSHADOW) ||
 
  707        AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW));
 
  708  uint64_t FixedShadowOffset = IsFixedShadow ? 
MI.getOperand(2).getImm() : 0;
 
  710  MCSymbol *&Sym = HwasanMemaccessSymbols[HwasanMemaccessTuple(
 
  711      Reg, IsShort, AccessInfo, IsFixedShadow, FixedShadowOffset)];
 
  714    if (!
TM.getTargetTriple().isOSBinFormatELF())
 
  717    std::string SymName = 
"__hwasan_check_x" + 
utostr(
Reg - AArch64::X0) + 
"_" +
 
  720      SymName += 
"_fixed_" + 
utostr(FixedShadowOffset);
 
  722      SymName += 
"_short_v2";
 
  723    Sym = OutContext.getOrCreateSymbol(SymName);
 
  726  EmitToStreamer(*OutStreamer,
 
  727                 MCInstBuilder(AArch64::BL)
 
  731void AArch64AsmPrinter::emitHwasanMemaccessSymbols(
Module &M) {
 
  732  if (HwasanMemaccessSymbols.empty())
 
  735  const Triple &
TT = 
TM.getTargetTriple();
 
  737  std::unique_ptr<MCSubtargetInfo> STI(
 
  738      TM.getTarget().createMCSubtargetInfo(TT, 
"", 
""));
 
  739  assert(STI && 
"Unable to create subtarget info");
 
  740  this->STI = 
static_cast<const AArch64Subtarget *
>(&*STI);
 
  743      OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch");
 
  745      OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
 
  747  const MCSymbolRefExpr *HwasanTagMismatchV1Ref =
 
  749  const MCSymbolRefExpr *HwasanTagMismatchV2Ref =
 
  752  for (
auto &
P : HwasanMemaccessSymbols) {
 
  753    unsigned Reg = std::get<0>(
P.first);
 
  754    bool IsShort = std::get<1>(
P.first);
 
  755    uint32_t AccessInfo = std::get<2>(
P.first);
 
  756    bool IsFixedShadow = std::get<3>(
P.first);
 
  757    uint64_t FixedShadowOffset = std::get<4>(
P.first);
 
  758    const MCSymbolRefExpr *HwasanTagMismatchRef =
 
  759        IsShort ? HwasanTagMismatchV2Ref : HwasanTagMismatchV1Ref;
 
  762    bool HasMatchAllTag =
 
  764    uint8_t MatchAllTag =
 
  771    OutStreamer->switchSection(OutContext.getELFSection(
 
  777    OutStreamer->emitSymbolAttribute(Sym, 
MCSA_Weak);
 
  778    OutStreamer->emitSymbolAttribute(Sym, 
MCSA_Hidden);
 
  779    OutStreamer->emitLabel(Sym);
 
  781    EmitToStreamer(MCInstBuilder(AArch64::SBFMXri)
 
  782                       .addReg(AArch64::X16)
 
  792      emitMOVZ(AArch64::X17, FixedShadowOffset >> 32, 32);
 
  793      EmitToStreamer(MCInstBuilder(AArch64::LDRBBroX)
 
  794                         .addReg(AArch64::W16)
 
  795                         .addReg(AArch64::X17)
 
  796                         .addReg(AArch64::X16)
 
  800      EmitToStreamer(MCInstBuilder(AArch64::LDRBBroX)
 
  801                         .addReg(AArch64::W16)
 
  802                         .addReg(IsShort ? AArch64::X20 : AArch64::X9)
 
  803                         .addReg(AArch64::X16)
 
  808    EmitToStreamer(MCInstBuilder(AArch64::SUBSXrs)
 
  809                       .addReg(AArch64::XZR)
 
  810                       .addReg(AArch64::X16)
 
  813    MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
 
  814    EmitToStreamer(MCInstBuilder(AArch64::Bcc)
 
  817                           HandleMismatchOrPartialSym, OutContext)));
 
  818    MCSymbol *ReturnSym = OutContext.createTempSymbol();
 
  819    OutStreamer->emitLabel(ReturnSym);
 
  820    EmitToStreamer(MCInstBuilder(AArch64::RET).addReg(AArch64::LR));
 
  821    OutStreamer->emitLabel(HandleMismatchOrPartialSym);
 
  823    if (HasMatchAllTag) {
 
  824      EmitToStreamer(MCInstBuilder(AArch64::UBFMXri)
 
  825                         .addReg(AArch64::X17)
 
  829      EmitToStreamer(MCInstBuilder(AArch64::SUBSXri)
 
  830                         .addReg(AArch64::XZR)
 
  831                         .addReg(AArch64::X17)
 
  835          MCInstBuilder(AArch64::Bcc)
 
  841      EmitToStreamer(MCInstBuilder(AArch64::SUBSWri)
 
  842                         .addReg(AArch64::WZR)
 
  843                         .addReg(AArch64::W16)
 
  846      MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
 
  848          MCInstBuilder(AArch64::Bcc)
 
  852      EmitToStreamer(MCInstBuilder(AArch64::ANDXri)
 
  853                         .addReg(AArch64::X17)
 
  857        EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
 
  858                           .addReg(AArch64::X17)
 
  859                           .addReg(AArch64::X17)
 
  862      EmitToStreamer(MCInstBuilder(AArch64::SUBSWrs)
 
  863                         .addReg(AArch64::WZR)
 
  864                         .addReg(AArch64::W16)
 
  865                         .addReg(AArch64::W17)
 
  868          MCInstBuilder(AArch64::Bcc)
 
  872      EmitToStreamer(MCInstBuilder(AArch64::ORRXri)
 
  873                         .addReg(AArch64::X16)
 
  876      EmitToStreamer(MCInstBuilder(AArch64::LDRBBui)
 
  877                         .addReg(AArch64::W16)
 
  878                         .addReg(AArch64::X16)
 
  881          MCInstBuilder(AArch64::SUBSXrs)
 
  882              .addReg(AArch64::XZR)
 
  883              .addReg(AArch64::X16)
 
  887          MCInstBuilder(AArch64::Bcc)
 
  891      OutStreamer->emitLabel(HandleMismatchSym);
 
  894    EmitToStreamer(MCInstBuilder(AArch64::STPXpre)
 
  900    EmitToStreamer(MCInstBuilder(AArch64::STPXi)
 
  906    if (
Reg != AArch64::X0)
 
  907      emitMovXReg(AArch64::X0, 
Reg);
 
  914      EmitToStreamer(MCInstBuilder(AArch64::B).addExpr(HwasanTagMismatchRef));
 
  919      EmitToStreamer(MCInstBuilder(AArch64::ADRP)
 
  920                         .addReg(AArch64::X16)
 
  924      EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
 
  925                         .addReg(AArch64::X16)
 
  926                         .addReg(AArch64::X16)
 
  930      EmitToStreamer(MCInstBuilder(AArch64::BR).addReg(AArch64::X16));
 
  938                                     const MCExpr *StubAuthPtrRef) {
 
  941  OutStreamer.
emitValue(StubAuthPtrRef, 8);
 
 
  944void AArch64AsmPrinter::emitEndOfAsmFile(
Module &M) {
 
  945  emitHwasanMemaccessSymbols(M);
 
  947  const Triple &
TT = 
TM.getTargetTriple();
 
  948  if (
TT.isOSBinFormatMachO()) {
 
  950    MachineModuleInfoMachO &MMIMacho =
 
  951        MMI->getObjFileInfo<MachineModuleInfoMachO>();
 
  955    if (!Stubs.empty()) {
 
  957      OutStreamer->switchSection(
 
  960      emitAlignment(
Align(8));
 
  962      for (
const auto &Stub : Stubs)
 
  965      OutStreamer->addBlankLine();
 
  973    OutStreamer->emitSubsectionsViaSymbols();
 
  976  if (
TT.isOSBinFormatELF()) {
 
  978    MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();
 
  982    if (!Stubs.empty()) {
 
  983      const TargetLoweringObjectFile &TLOF = getObjFileLowering();
 
  985      emitAlignment(
Align(8));
 
  987      for (
const auto &Stub : Stubs)
 
  990      OutStreamer->addBlankLine();
 
 1001        M.getModuleFlag(
"ptrauth-elf-got"));
 
 1002    if (PtrAuthELFGOTFlag && PtrAuthELFGOTFlag->getZExtValue() == 1)
 
 1003      for (
const GlobalValue &GV : 
M.global_values())
 
 1005            !GV.getName().starts_with(
"llvm."))
 
 1006          OutStreamer->emitSymbolAttribute(getSymbol(&GV),
 
 1015  if (EnableImportCallOptimization && 
TT.isOSBinFormatCOFF()) {
 
 1016    OutStreamer->switchSection(getObjFileLowering().getImportCallSection());
 
 1019    constexpr char ImpCallMagic[12] = 
"Imp_Call_V1";
 
 1020    OutStreamer->emitBytes(StringRef{ImpCallMagic, 
sizeof(ImpCallMagic)});
 
 1031    for (
auto &[Section, CallsToImportedFuncs] :
 
 1032         SectionToImportedFunctionCalls) {
 
 1034          sizeof(uint32_t) * (2 + 3 * CallsToImportedFuncs.size());
 
 1035      OutStreamer->emitInt32(SectionSize);
 
 1036      OutStreamer->emitCOFFSecNumber(
Section->getBeginSymbol());
 
 1037      for (
auto &[CallsiteSymbol, CalledSymbol] : CallsToImportedFuncs) {
 
 1039        OutStreamer->emitInt32(0x13);
 
 1040        OutStreamer->emitCOFFSecOffset(CallsiteSymbol);
 
 1041        OutStreamer->emitCOFFSymbolIndex(CalledSymbol);
 
 1047void AArch64AsmPrinter::emitLOHs() {
 
 1051    for (
const MachineInstr *
MI : 
D.getArgs()) {
 
 1052      MInstToMCSymbol::iterator LabelIt = LOHInstToLabel.find(
MI);
 
 1053      assert(LabelIt != LOHInstToLabel.end() &&
 
 1054             "Label hasn't been inserted for LOH related instruction");
 
 1057    OutStreamer->emitLOHDirective(
D.getKind(), MCArgs);
 
 1062void AArch64AsmPrinter::emitFunctionBodyEnd() {
 
 1068MCSymbol *AArch64AsmPrinter::GetCPISymbol(
unsigned CPID)
 const {
 
 1072  if (!getDataLayout().getLinkerPrivateGlobalPrefix().
empty())
 
 1073    return OutContext.getOrCreateSymbol(
 
 1074        Twine(getDataLayout().getLinkerPrivateGlobalPrefix()) + 
"CPI" +
 
 1075        Twine(getFunctionNumber()) + 
"_" + Twine(CPID));
 
 1080void AArch64AsmPrinter::printOperand(
const MachineInstr *
MI, 
unsigned OpNum,
 
 1082  const MachineOperand &MO = 
MI->getOperand(OpNum);
 
 1098    PrintSymbolOperand(MO, O);
 
 1109bool AArch64AsmPrinter::printAsmMRegister(
const MachineOperand &MO, 
char Mode,
 
 1133bool AArch64AsmPrinter::printAsmRegInClass(
const MachineOperand &MO,
 
 1134                                           const TargetRegisterClass *RC,
 
 1135                                           unsigned AltName, raw_ostream &O) {
 
 1136  assert(MO.
isReg() && 
"Should only get here with a register!");
 
 1146bool AArch64AsmPrinter::PrintAsmOperand(
const MachineInstr *
MI, 
unsigned OpNum,
 
 1147                                        const char *ExtraCode, raw_ostream &O) {
 
 1148  const MachineOperand &MO = 
MI->getOperand(OpNum);
 
 1155  if (ExtraCode && ExtraCode[0]) {
 
 1156    if (ExtraCode[1] != 0)
 
 1159    switch (ExtraCode[0]) {
 
 1167        unsigned Reg = ExtraCode[0] == 
'w' ? AArch64::WZR : AArch64::XZR;
 
 1180        const TargetRegisterClass *RC;
 
 1181        switch (ExtraCode[0]) {
 
 1183          RC = &AArch64::FPR8RegClass;
 
 1186          RC = &AArch64::FPR16RegClass;
 
 1189          RC = &AArch64::FPR32RegClass;
 
 1192          RC = &AArch64::FPR64RegClass;
 
 1195          RC = &AArch64::FPR128RegClass;
 
 1198          RC = &AArch64::ZPRRegClass;
 
 1203        return printAsmRegInClass(MO, RC, AArch64::NoRegAltName, O);
 
 1224    unsigned AltName = AArch64::NoRegAltName;
 
 1225    const TargetRegisterClass *RegClass;
 
 1227      RegClass = &AArch64::ZPRRegClass;
 
 1229      RegClass = &AArch64::PPRRegClass;
 
 1231      RegClass = &AArch64::PNRRegClass;
 
 1233      RegClass = &AArch64::FPR128RegClass;
 
 1234      AltName = AArch64::vreg;
 
 1238    return printAsmRegInClass(MO, RegClass, AltName, O);
 
 1245bool AArch64AsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
 
 1247                                              const char *ExtraCode,
 
 1249  if (ExtraCode && ExtraCode[0] && ExtraCode[0] != 
'a')
 
 1252  const MachineOperand &MO = 
MI->getOperand(OpNum);
 
 1253  assert(MO.
isReg() && 
"unexpected inline asm memory operand");
 
 1258void AArch64AsmPrinter::PrintDebugValueComment(
const MachineInstr *
MI,
 
 1260  unsigned NOps = 
MI->getNumOperands();
 
 1262  OS << 
'\t' << MAI->getCommentString() << 
"DEBUG_VALUE: ";
 
 1264  OS << 
MI->getDebugVariable()->getName();
 
 1267  assert(
MI->isIndirectDebugValue());
 
 1269  for (
unsigned I = 0, 
E = std::distance(
MI->debug_operands().begin(),
 
 1270                                         MI->debug_operands().end());
 
 1281void AArch64AsmPrinter::emitJumpTableImpl(
const MachineJumpTableInfo &MJTI,
 
 1282                                          ArrayRef<unsigned> JumpTableIndices) {
 
 1284  if (JumpTableIndices.
empty())
 
 1286  const TargetLoweringObjectFile &TLOF = getObjFileLowering();
 
 1287  const auto &
F = MF->getFunction();
 
 1290  MCSection *ReadOnlySec = 
nullptr;
 
 1291  if (
TM.Options.EnableStaticDataPartitioning) {
 
 1297  OutStreamer->switchSection(ReadOnlySec);
 
 1299  auto AFI = MF->getInfo<AArch64FunctionInfo>();
 
 1300  for (
unsigned JTI : JumpTableIndices) {
 
 1301    const std::vector<MachineBasicBlock*> &JTBBs = 
JT[JTI].MBBs;
 
 1304    if (JTBBs.empty()) 
continue;
 
 1306    unsigned Size = AFI->getJumpTableEntrySize(JTI);
 
 1308    OutStreamer->emitLabel(GetJTISymbol(JTI));
 
 1313    for (
auto *JTBB : JTBBs) {
 
 1314      const MCExpr *
Value =
 
 1333AArch64AsmPrinter::getCodeViewJumpTableInfo(
int JTI,
 
 1334                                            const MachineInstr *BranchInstr,
 
 1335                                            const MCSymbol *BranchLabel)
 const {
 
 1336  const auto AFI = MF->getInfo<AArch64FunctionInfo>();
 
 1339  switch (AFI->getJumpTableEntrySize(JTI)) {
 
 1341    EntrySize = codeview::JumpTableEntrySize::UInt8ShiftLeft;
 
 1344    EntrySize = codeview::JumpTableEntrySize::UInt16ShiftLeft;
 
 1347    EntrySize = codeview::JumpTableEntrySize::Int32;
 
 1352  return std::make_tuple(
Base, 0, BranchLabel, EntrySize);
 
 1355void AArch64AsmPrinter::emitFunctionEntryLabel() {
 
 1356  const Triple &
TT = 
TM.getTargetTriple();
 
 1357  if (
TT.isOSBinFormatELF() &&
 
 1358      (MF->getFunction().getCallingConv() == CallingConv::AArch64_VectorCall ||
 
 1359       MF->getFunction().getCallingConv() ==
 
 1360           CallingConv::AArch64_SVE_VectorCall ||
 
 1361       MF->getInfo<AArch64FunctionInfo>()->isSVECC())) {
 
 1363        static_cast<AArch64TargetStreamer *
>(OutStreamer->getTargetStreamer());
 
 1369  if (
TT.isWindowsArm64EC() && !MF->getFunction().hasLocalLinkage()) {
 
 1374      OutStreamer->emitAssignment(
 
 1378    auto getSymbolFromMetadata = [&](StringRef 
Name) {
 
 1380      if (MDNode *Node = MF->getFunction().getMetadata(Name)) {
 
 1382        Sym = MMI->getContext().getOrCreateSymbol(NameStr);
 
 1388    MF->getFunction().getMetadata(
"arm64ec_unmangled_name", UnmangledNames);
 
 1389    for (MDNode *Node : UnmangledNames) {
 
 1391      MCSymbol *UnmangledSym = MMI->getContext().getOrCreateSymbol(NameStr);
 
 1392      if (std::optional<std::string> MangledName =
 
 1395            MMI->getContext().getOrCreateSymbol(*MangledName);
 
 1396        emitFunctionAlias(UnmangledSym, ECMangledSym);
 
 1399    if (MCSymbol *ECMangledSym =
 
 1400            getSymbolFromMetadata(
"arm64ec_ecmangled_name"))
 
 1401      emitFunctionAlias(ECMangledSym, CurrentFnSym);
 
 1405void AArch64AsmPrinter::emitXXStructor(
const DataLayout &
DL,
 
 1406                                       const Constant *CV) {
 
 1408    if (CPA->hasAddressDiscriminator() &&
 
 1409        !CPA->hasSpecialAddressDiscriminator(
 
 1412          "unexpected address discrimination value for ctors/dtors entry, only " 
 1413          "'ptr inttoptr (i64 1 to ptr)' is allowed");
 
 1422void AArch64AsmPrinter::emitGlobalAlias(
const Module &M,
 
 1423                                        const GlobalAlias &GA) {
 
 1429    if (MDNode *Node = 
F->getMetadata(
"arm64ec_exp_name")) {
 
 1431      MCSymbol *ExpSym = MMI->getContext().getOrCreateSymbol(ExpStr);
 
 1434      OutStreamer->beginCOFFSymbolDef(ExpSym);
 
 1438      OutStreamer->endCOFFSymbolDef();
 
 1440      OutStreamer->beginCOFFSymbolDef(Sym);
 
 1444      OutStreamer->endCOFFSymbolDef();
 
 1445      OutStreamer->emitSymbolAttribute(Sym, 
MCSA_Weak);
 
 1446      OutStreamer->emitAssignment(
 
 1463void AArch64AsmPrinter::LowerJumpTableDest(llvm::MCStreamer &OutStreamer,
 
 1464                                           const llvm::MachineInstr &
MI) {
 
 1465  Register DestReg = 
MI.getOperand(0).getReg();
 
 1466  Register ScratchReg = 
MI.getOperand(1).getReg();
 
 1469  Register TableReg = 
MI.getOperand(2).getReg();
 
 1470  Register EntryReg = 
MI.getOperand(3).getReg();
 
 1471  int JTIdx = 
MI.getOperand(4).getIndex();
 
 1477      MF->getInfo<AArch64FunctionInfo>()->getJumpTableEntryPCRelSymbol(JTIdx);
 
 1482    Label = MF->getContext().createTempSymbol();
 
 1488  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::ADR)
 
 1490                                  .addExpr(LabelExpr));
 
 1495  case 1: LdrOpcode = AArch64::LDRBBroX; 
break;
 
 1496  case 2: LdrOpcode = AArch64::LDRHHroX; 
break;
 
 1497  case 4: LdrOpcode = AArch64::LDRSWroX; 
break;
 
 1502  EmitToStreamer(OutStreamer, MCInstBuilder(LdrOpcode)
 
 1503                                  .addReg(
Size == 4 ? ScratchReg : ScratchRegW)
 
 1507                                  .addImm(
Size == 1 ? 0 : 1));
 
 1511  EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::ADDXrs)
 
 1515                                  .addImm(
Size == 4 ? 0 : 2));
 
 1518void AArch64AsmPrinter::LowerHardenedBRJumpTable(
const MachineInstr &
MI) {
 
 1519  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
 
 1520  assert(MJTI && 
"Can't lower jump-table dispatch without JTI");
 
 1522  const std::vector<MachineJumpTableEntry> &JTs = MJTI->
getJumpTables();
 
 1523  assert(!JTs.empty() && 
"Invalid JT index for jump-table dispatch");
 
 1539  MachineOperand JTOp = 
MI.getOperand(0);
 
 1543         "unsupported compressed jump table");
 
 1545  const uint64_t NumTableEntries = JTs[JTI].MBBs.size();
 
 1549  uint64_t MaxTableEntry = NumTableEntries - 1;
 
 1551    EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::SUBSXri)
 
 1552                                     .addReg(AArch64::XZR)
 
 1553                                     .addReg(AArch64::X16)
 
 1554                                     .addImm(MaxTableEntry)
 
 1557    emitMOVZ(AArch64::X17, 
static_cast<uint16_t
>(MaxTableEntry), 0);
 
 1562      if ((MaxTableEntry >> 
Offset) == 0)
 
 1564      emitMOVK(AArch64::X17, 
static_cast<uint16_t
>(MaxTableEntry >> 
Offset),
 
 1567    EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::SUBSXrs)
 
 1568                                     .addReg(AArch64::XZR)
 
 1569                                     .addReg(AArch64::X16)
 
 1570                                     .addReg(AArch64::X17)
 
 1576  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::CSELXr)
 
 1577                                   .addReg(AArch64::X16)
 
 1578                                   .addReg(AArch64::X16)
 
 1579                                   .addReg(AArch64::XZR)
 
 1583  MachineOperand JTMOHi(JTOp), JTMOLo(JTOp);
 
 1584  MCOperand JTMCHi, JTMCLo;
 
 1594      MCInstBuilder(AArch64::ADRP).addReg(AArch64::X17).
addOperand(JTMCHi));
 
 1596  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ADDXri)
 
 1597                                   .addReg(AArch64::X17)
 
 1598                                   .addReg(AArch64::X17)
 
 1602  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::LDRSWroX)
 
 1603                                   .addReg(AArch64::X16)
 
 1604                                   .addReg(AArch64::X17)
 
 1605                                   .addReg(AArch64::X16)
 
 1609  MCSymbol *AdrLabel = MF->getContext().createTempSymbol();
 
 1616      MCInstBuilder(AArch64::ADR).addReg(AArch64::X17).addExpr(AdrLabelE));
 
 1618  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ADDXrs)
 
 1619                                   .addReg(AArch64::X16)
 
 1620                                   .addReg(AArch64::X17)
 
 1621                                   .addReg(AArch64::X16)
 
 1624  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::BR).addReg(AArch64::X16));
 
 1627void AArch64AsmPrinter::LowerMOPS(llvm::MCStreamer &OutStreamer,
 
 1628                                  const llvm::MachineInstr &
MI) {
 
 1629  unsigned Opcode = 
MI.getOpcode();
 
 1631  assert(STI->hasMTE() || Opcode != AArch64::MOPSMemorySetTaggingPseudo);
 
 1633  const auto Ops = [Opcode]() -> std::array<unsigned, 3> {
 
 1634    if (Opcode == AArch64::MOPSMemoryCopyPseudo)
 
 1635      return {AArch64::CPYFP, AArch64::CPYFM, AArch64::CPYFE};
 
 1636    if (Opcode == AArch64::MOPSMemoryMovePseudo)
 
 1637      return {AArch64::CPYP, AArch64::CPYM, AArch64::CPYE};
 
 1638    if (Opcode == AArch64::MOPSMemorySetPseudo)
 
 1639      return {AArch64::SETP, AArch64::SETM, AArch64::SETE};
 
 1640    if (Opcode == AArch64::MOPSMemorySetTaggingPseudo)
 
 1641      return {AArch64::SETGP, AArch64::SETGM, AArch64::MOPSSETGE};
 
 1644  const bool IsSet = Opcode == AArch64::MOPSMemorySetPseudo ||
 
 1645                     Opcode == AArch64::MOPSMemorySetTaggingPseudo;
 
 1647  for (
auto Op : 
Ops) {
 
 1649    auto MCIB = MCInstBuilder(
Op);
 
 1651    MCIB.addReg(
MI.getOperand(i++).getReg());
 
 1652    MCIB.addReg(
MI.getOperand(i++).getReg());
 
 1654      MCIB.addReg(
MI.getOperand(i++).getReg());
 
 1656    MCIB.addReg(
MI.getOperand(i++).getReg());
 
 1657    MCIB.addReg(
MI.getOperand(i++).getReg());
 
 1658    MCIB.addReg(
MI.getOperand(i++).getReg());
 
 1660    EmitToStreamer(OutStreamer, MCIB);
 
 1664void AArch64AsmPrinter::LowerSTACKMAP(MCStreamer &OutStreamer, StackMaps &SM,
 
 1665                                      const MachineInstr &
MI) {
 
 1666  unsigned NumNOPBytes = StackMapOpers(&
MI).getNumPatchBytes();
 
 1669  MCSymbol *MILabel = Ctx.createTempSymbol();
 
 1673  assert(NumNOPBytes % 4 == 0 && 
"Invalid number of NOP bytes requested!");
 
 1676  const MachineBasicBlock &
MBB = *
MI.getParent();
 
 1679  while (NumNOPBytes > 0) {
 
 1680    if (MII == 
MBB.
end() || MII->isCall() ||
 
 1681        MII->getOpcode() == AArch64::DBG_VALUE ||
 
 1682        MII->getOpcode() == TargetOpcode::PATCHPOINT ||
 
 1683        MII->getOpcode() == TargetOpcode::STACKMAP)
 
 1690  for (
unsigned i = 0; i < NumNOPBytes; i += 4)
 
 1691    EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
 
 1696void AArch64AsmPrinter::LowerPATCHPOINT(MCStreamer &OutStreamer, StackMaps &SM,
 
 1697                                        const MachineInstr &
MI) {
 
 1699  MCSymbol *MILabel = Ctx.createTempSymbol();
 
 1703  PatchPointOpers Opers(&
MI);
 
 1705  int64_t CallTarget = Opers.getCallTarget().getImm();
 
 1706  unsigned EncodedBytes = 0;
 
 1708    assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
 
 1709           "High 16 bits of call target should be zero.");
 
 1710    Register ScratchReg = 
MI.getOperand(Opers.getNextScratchIdx()).getReg();
 
 1713    emitMOVZ(ScratchReg, (CallTarget >> 32) & 0xFFFF, 32);
 
 1714    emitMOVK(ScratchReg, (CallTarget >> 16) & 0xFFFF, 16);
 
 1715    emitMOVK(ScratchReg, CallTarget & 0xFFFF, 0);
 
 1716    EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::BLR).addReg(ScratchReg));
 
 1719  unsigned NumBytes = Opers.getNumPatchBytes();
 
 1720  assert(NumBytes >= EncodedBytes &&
 
 1721         "Patchpoint can't request size less than the length of a call.");
 
 1722  assert((NumBytes - EncodedBytes) % 4 == 0 &&
 
 1723         "Invalid number of NOP bytes requested!");
 
 1724  for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
 
 1725    EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
 
 1728void AArch64AsmPrinter::LowerSTATEPOINT(MCStreamer &OutStreamer, StackMaps &SM,
 
 1729                                        const MachineInstr &
MI) {
 
 1730  StatepointOpers SOpers(&
MI);
 
 1731  if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
 
 1732    assert(PatchBytes % 4 == 0 && 
"Invalid number of NOP bytes requested!");
 
 1733    for (
unsigned i = 0; i < PatchBytes; i += 4)
 
 1734      EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::HINT).addImm(0));
 
 1737    const MachineOperand &CallTarget = SOpers.getCallTarget();
 
 1738    MCOperand CallTargetMCOp;
 
 1739    unsigned CallOpcode;
 
 1740    switch (CallTarget.
getType()) {
 
 1743      MCInstLowering.
lowerOperand(CallTarget, CallTargetMCOp);
 
 1744      CallOpcode = AArch64::BL;
 
 1748      CallOpcode = AArch64::BL;
 
 1752      CallOpcode = AArch64::BLR;
 
 1759    EmitToStreamer(OutStreamer,
 
 1760                   MCInstBuilder(CallOpcode).
addOperand(CallTargetMCOp));
 
 1764  MCSymbol *MILabel = Ctx.createTempSymbol();
 
 1769void AArch64AsmPrinter::LowerFAULTING_OP(
const MachineInstr &FaultingMI) {
 
 1778  unsigned OperandsBeginIdx = 4;
 
 1781  MCSymbol *FaultingLabel = Ctx.createTempSymbol();
 
 1788  MI.setOpcode(Opcode);
 
 1793  for (
const MachineOperand &MO :
 
 1796    lowerOperand(MO, Dest);
 
 1797    MI.addOperand(Dest);
 
 1805  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::ORRXrs)
 
 1807                                   .addReg(AArch64::XZR)
 
 1812void AArch64AsmPrinter::emitMOVZ(
Register Dest, uint64_t Imm, 
unsigned Shift) {
 
 1813  bool Is64Bit = AArch64::GPR64RegClass.contains(Dest);
 
 1814  EmitToStreamer(*OutStreamer,
 
 1815                 MCInstBuilder(Is64Bit ? AArch64::MOVZXi : AArch64::MOVZWi)
 
 1821void AArch64AsmPrinter::emitMOVK(
Register Dest, uint64_t Imm, 
unsigned Shift) {
 
 1822  bool Is64Bit = AArch64::GPR64RegClass.contains(Dest);
 
 1823  EmitToStreamer(*OutStreamer,
 
 1824                 MCInstBuilder(Is64Bit ? AArch64::MOVKXi : AArch64::MOVKWi)
 
 1831void AArch64AsmPrinter::emitFMov0(
const MachineInstr &
MI) {
 
 1832  Register DestReg = 
MI.getOperand(0).getReg();
 
 1833  if (!STI->hasZeroCycleZeroingFPWorkaround() && STI->
isNeonAvailable()) {
 
 1834    if (STI->hasZeroCycleZeroingFPR64()) {
 
 1837      if (AArch64::FPR16RegClass.
contains(DestReg))
 
 1838        DestReg = 
TRI->getMatchingSuperReg(DestReg, AArch64::hsub,
 
 1839                                           &AArch64::FPR64RegClass);
 
 1840      else if (AArch64::FPR32RegClass.
contains(DestReg))
 
 1841        DestReg = 
TRI->getMatchingSuperReg(DestReg, AArch64::ssub,
 
 1842                                           &AArch64::FPR64RegClass);
 
 1850      EmitToStreamer(*OutStreamer, MOVI);
 
 1851    } 
else if (STI->hasZeroCycleZeroingFPR128()) {
 
 1854      if (AArch64::FPR16RegClass.
contains(DestReg)) {
 
 1855        DestReg = 
TRI->getMatchingSuperReg(DestReg, AArch64::hsub,
 
 1856                                           &AArch64::FPR128RegClass);
 
 1857      } 
else if (AArch64::FPR32RegClass.
contains(DestReg)) {
 
 1858        DestReg = 
TRI->getMatchingSuperReg(DestReg, AArch64::ssub,
 
 1859                                           &AArch64::FPR128RegClass);
 
 1862        DestReg = 
TRI->getMatchingSuperReg(DestReg, AArch64::dsub,
 
 1863                                           &AArch64::FPR128RegClass);
 
 1870      EmitToStreamer(*OutStreamer, MOVI);
 
 1872      emitFMov0AsFMov(
MI, DestReg);
 
 1875    emitFMov0AsFMov(
MI, DestReg);
 
 1879void AArch64AsmPrinter::emitFMov0AsFMov(
const MachineInstr &
MI,
 
 1882  switch (
MI.getOpcode()) {
 
 1885  case AArch64::FMOVH0:
 
 1886    FMov.
setOpcode(STI->hasFullFP16() ? AArch64::FMOVWHr : AArch64::FMOVWSr);
 
 1887    if (!STI->hasFullFP16())
 
 1888      DestReg = (AArch64::S0 + (DestReg - AArch64::H0));
 
 1892  case AArch64::FMOVS0:
 
 1897  case AArch64::FMOVD0:
 
 1903  EmitToStreamer(*OutStreamer, FMov);
 
 1906Register AArch64AsmPrinter::emitPtrauthDiscriminator(uint16_t Disc,
 
 1909                                                     bool MayUseAddrAsScratch) {
 
 1910  assert(ScratchReg == AArch64::X16 || ScratchReg == AArch64::X17 ||
 
 1913  if (AddrDisc == AArch64::NoRegister)
 
 1914    AddrDisc = AArch64::XZR;
 
 1922  if (AddrDisc == AArch64::XZR) {
 
 1923    emitMOVZ(ScratchReg, Disc, 0);
 
 1930  assert(MayUseAddrAsScratch || ScratchReg != AddrDisc);
 
 1931  bool AddrDiscIsSafe = AddrDisc == AArch64::X16 || AddrDisc == AArch64::X17 ||
 
 1933  if (MayUseAddrAsScratch && AddrDiscIsSafe)
 
 1934    ScratchReg = AddrDisc;
 
 1936    emitMovXReg(ScratchReg, AddrDisc);
 
 1938  emitMOVK(ScratchReg, Disc, 48);
 
 1946void AArch64AsmPrinter::emitPtrauthCheckAuthenticatedValue(
 
 1949    const MCSymbol *OnFailure) {
 
 1979  if (Method == AuthCheckMethod::None)
 
 1981  if (Method == AuthCheckMethod::DummyLoad) {
 
 1982    EmitToStreamer(MCInstBuilder(AArch64::LDRWui)
 
 1986    assert(ShouldTrap && !OnFailure && 
"DummyLoad always traps on error");
 
 1990  MCSymbol *SuccessSym = createTempSymbol(
"auth_success_");
 
 1991  if (Method == AuthCheckMethod::XPAC || Method == AuthCheckMethod::XPACHint) {
 
 1993    emitMovXReg(ScratchReg, TestedReg);
 
 1995    if (Method == AuthCheckMethod::XPAC) {
 
 1999          MCInstBuilder(XPACOpc).addReg(ScratchReg).addReg(ScratchReg));
 
 2004      assert(TestedReg == AArch64::LR &&
 
 2005             "XPACHint mode is only compatible with checking the LR register");
 
 2007             "XPACHint mode is only compatible with I-keys");
 
 2008      EmitToStreamer(MCInstBuilder(AArch64::XPACLRI));
 
 2012    EmitToStreamer(MCInstBuilder(AArch64::SUBSXrs)
 
 2013                       .addReg(AArch64::XZR)
 
 2020        MCInstBuilder(AArch64::Bcc)
 
 2023  } 
else if (Method == AuthCheckMethod::HighBitsNoTBI) {
 
 2025    EmitToStreamer(MCInstBuilder(AArch64::EORXrs)
 
 2032        MCInstBuilder(AArch64::TBZX)
 
 2041    assert(!OnFailure && 
"Cannot specify OnFailure with ShouldTrap");
 
 2044    EmitToStreamer(MCInstBuilder(AArch64::BRK).addImm(0xc470 | 
Key));
 
 2058    case AuthCheckMethod::XPACHint:
 
 2061    case AuthCheckMethod::XPAC:
 
 2063      emitMovXReg(TestedReg, ScratchReg);
 
 2070          MCInstBuilder(XPACOpc).addReg(TestedReg).addReg(TestedReg));
 
 2076          MCInstBuilder(AArch64::B)
 
 2090void AArch64AsmPrinter::emitPtrauthTailCallHardening(
const MachineInstr *TC) {
 
 2095  if (LRCheckMethod == AArch64PAuth::AuthCheckMethod::None)
 
 2102         "Neither x16 nor x17 is available as a scratch register");
 
 2105  emitPtrauthCheckAuthenticatedValue(
 
 2106      AArch64::LR, ScratchReg, 
Key, LRCheckMethod,
 
 2110void AArch64AsmPrinter::emitPtrauthAuthResign(
 
 2112    const MachineOperand *AUTAddrDisc, 
Register Scratch,
 
 2113    std::optional<AArch64PACKey::ID> PACKey, uint64_t PACDisc,
 
 2115  const bool IsAUTPAC = PACKey.has_value();
 
 2129  bool ShouldCheck = 
true;
 
 2131  bool ShouldTrap = MF->getFunction().hasFnAttribute(
"ptrauth-auth-traps");
 
 2136    ShouldCheck = ShouldTrap = 
false;
 
 2143    ShouldCheck = ShouldTrap = 
false;
 
 2150    ShouldCheck = ShouldTrap = 
true;
 
 2156  Register AUTDiscReg = emitPtrauthDiscriminator(
 
 2157      AUTDisc, AUTAddrDisc->
getReg(), Scratch, AUTAddrDisc->
isKill());
 
 2158  bool AUTZero = AUTDiscReg == AArch64::XZR;
 
 2169  EmitToStreamer(*OutStreamer, AUTInst);
 
 2172  if (!IsAUTPAC && (!ShouldCheck || !ShouldTrap))
 
 2178    if (IsAUTPAC && !ShouldTrap)
 
 2179      EndSym = createTempSymbol(
"resign_end_");
 
 2181    emitPtrauthCheckAuthenticatedValue(AUTVal, Scratch, AUTKey,
 
 2182                                       AArch64PAuth::AuthCheckMethod::XPAC,
 
 2183                                       ShouldTrap, EndSym);
 
 2195      emitPtrauthDiscriminator(PACDisc, PACAddrDisc, Scratch);
 
 2196  bool PACZero = PACDiscReg == AArch64::XZR;
 
 2207  EmitToStreamer(*OutStreamer, PACInst);
 
 2214void AArch64AsmPrinter::emitPtrauthSign(
const MachineInstr *
MI) {
 
 2217  uint64_t Disc = 
MI->getOperand(3).getImm();
 
 2218  Register AddrDisc = 
MI->getOperand(4).getReg();
 
 2219  bool AddrDiscKilled = 
MI->getOperand(4).isKill();
 
 2223  Register ScratchReg = Val == AArch64::X16 ? AArch64::X17 : AArch64::X16;
 
 2224  assert(ScratchReg != AddrDisc &&
 
 2225         "Neither X16 nor X17 is available as a scratch register");
 
 2229  Register DiscReg = emitPtrauthDiscriminator(
 
 2230      Disc, AddrDisc, ScratchReg, AddrDiscKilled);
 
 2231  bool IsZeroDisc = DiscReg == AArch64::XZR;
 
 2242  EmitToStreamer(*OutStreamer, PACInst);
 
 2245void AArch64AsmPrinter::emitPtrauthBranch(
const MachineInstr *
MI) {
 
 2246  bool IsCall = 
MI->getOpcode() == AArch64::BLRA;
 
 2247  unsigned BrTarget = 
MI->getOperand(0).getReg();
 
 2251         "Invalid auth call key");
 
 2253  uint64_t Disc = 
MI->getOperand(2).getImm();
 
 2256  unsigned AddrDisc = 
MI->getOperand(3).getReg();
 
 2262  if (BrTarget == AddrDisc)
 
 2279  bool AddrDiscIsImplicitDef =
 
 2280      IsCall && (AddrDisc == AArch64::X16 || AddrDisc == AArch64::X17);
 
 2281  Register DiscReg = emitPtrauthDiscriminator(Disc, AddrDisc, AArch64::X17,
 
 2282                                              AddrDiscIsImplicitDef);
 
 2283  bool IsZeroDisc = DiscReg == AArch64::XZR;
 
 2288      Opc = IsZeroDisc ? AArch64::BLRAAZ : AArch64::BLRAA;
 
 2290      Opc = IsZeroDisc ? AArch64::BLRABZ : AArch64::BLRAB;
 
 2293      Opc = IsZeroDisc ? AArch64::BRAAZ : AArch64::BRAA;
 
 2295      Opc = IsZeroDisc ? AArch64::BRABZ : AArch64::BRAB;
 
 2303  EmitToStreamer(*OutStreamer, BRInst);
 
 2307AArch64AsmPrinter::lowerConstantPtrAuth(
const ConstantPtrAuth &CPA) {
 
 2308  MCContext &Ctx = OutContext;
 
 2313      getDataLayout(), 
Offset, 
true);
 
 2321        "cannot resolve target base/addend of ptrauth constant");
 
 2339                               "' out of range [0, " +
 
 2347                               "' out of range [0, 0xFFFF]");
 
 2356void AArch64AsmPrinter::LowerLOADauthptrstatic(
const MachineInstr &
MI) {
 
 2357  unsigned DstReg = 
MI.getOperand(0).getReg();
 
 2358  const MachineOperand &GAOp = 
MI.getOperand(1);
 
 2359  const uint64_t KeyC = 
MI.getOperand(2).getImm();
 
 2361         "key is out of range [0, AArch64PACKey::LAST]");
 
 2363  const uint64_t Disc = 
MI.getOperand(3).getImm();
 
 2365         "constant discriminator is out of range [0, 0xffff]");
 
 2374  if (
TM.getTargetTriple().isOSBinFormatELF()) {
 
 2376        static_cast<const AArch64_ELFTargetObjectFile &
>(getObjFileLowering());
 
 2379           "non-zero offset for $auth_ptr$ stub slots is not supported");
 
 2381    AuthPtrStubSym = TLOF.getAuthPtrSlotSymbol(TM, MMI, GASym, 
Key, Disc);
 
 2383    assert(
TM.getTargetTriple().isOSBinFormatMachO() &&
 
 2384           "LOADauthptrstatic is implemented only for MachO/ELF");
 
 2386    const auto &TLOF = 
static_cast<const AArch64_MachoTargetObjectFile &
>(
 
 2387        getObjFileLowering());
 
 2390           "non-zero offset for $auth_ptr$ stub slots is not supported");
 
 2392    AuthPtrStubSym = TLOF.getAuthPtrSlotSymbol(TM, MMI, GASym, 
Key, Disc);
 
 2395  MachineOperand StubMOHi =
 
 2399  MCOperand StubMCHi, StubMCLo;
 
 2406      MCInstBuilder(AArch64::ADRP).addReg(DstReg).
addOperand(StubMCHi));
 
 2408  EmitToStreamer(*OutStreamer, MCInstBuilder(AArch64::LDRXui)
 
 2414void AArch64AsmPrinter::LowerMOVaddrPAC(
const MachineInstr &
MI) {
 
 2415  const bool IsGOTLoad = 
MI.getOpcode() == AArch64::LOADgotPAC;
 
 2416  const bool IsELFSignedGOT = 
MI.getParent()
 
 2418                                  ->getInfo<AArch64FunctionInfo>()
 
 2419                                  ->hasELFSignedGOT();
 
 2420  MachineOperand GAOp = 
MI.getOperand(0);
 
 2421  const uint64_t KeyC = 
MI.getOperand(1).getImm();
 
 2423         "key is out of range [0, AArch64PACKey::LAST]");
 
 2425  const unsigned AddrDisc = 
MI.getOperand(2).getReg();
 
 2426  const uint64_t Disc = 
MI.getOperand(3).getImm();
 
 2428         "constant discriminator is out of range [0, 0xffff]");
 
 2475  MachineOperand GAMOHi(GAOp), GAMOLo(GAOp);
 
 2476  MCOperand GAMCHi, GAMCLo;
 
 2489      MCInstBuilder(AArch64::ADRP)
 
 2490          .addReg(IsGOTLoad && IsELFSignedGOT ? AArch64::X17 : AArch64::X16)
 
 2494    if (IsELFSignedGOT) {
 
 2495      EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
 
 2496                         .addReg(AArch64::X17)
 
 2497                         .addReg(AArch64::X17)
 
 2501      EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
 
 2502                         .addReg(AArch64::X16)
 
 2503                         .addReg(AArch64::X17)
 
 2512      EmitToStreamer(MCInstBuilder(AuthOpcode)
 
 2513                         .addReg(AArch64::X16)
 
 2514                         .addReg(AArch64::X16)
 
 2515                         .addReg(AArch64::X17));
 
 2517      if (!STI->hasFPAC()) {
 
 2521        emitPtrauthCheckAuthenticatedValue(AArch64::X16, AArch64::X17, AuthKey,
 
 2522                                           AArch64PAuth::AuthCheckMethod::XPAC,
 
 2527      EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
 
 2528                         .addReg(AArch64::X16)
 
 2529                         .addReg(AArch64::X16)
 
 2533    EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
 
 2534                       .addReg(AArch64::X16)
 
 2535                       .addReg(AArch64::X16)
 
 2542    const bool IsNeg = 
Offset < 0;
 
 2544      for (
int BitPos = 0; BitPos != 24 && (AbsOffset >> BitPos);
 
 2547            MCInstBuilder(IsNeg ? AArch64::SUBXri : AArch64::ADDXri)
 
 2548                .addReg(AArch64::X16)
 
 2549                .addReg(AArch64::X16)
 
 2550                .addImm((AbsOffset >> BitPos) & 0xfff)
 
 2554      const uint64_t UOffset = 
Offset;
 
 2555      EmitToStreamer(MCInstBuilder(IsNeg ? AArch64::MOVNXi : AArch64::MOVZXi)
 
 2556                         .addReg(AArch64::X17)
 
 2557                         .addImm((IsNeg ? ~UOffset : UOffset) & 0xffff)
 
 2559      auto NeedMovk = [IsNeg, UOffset](
int BitPos) -> 
bool {
 
 2560        assert(BitPos == 16 || BitPos == 32 || BitPos == 48);
 
 2561        uint64_t Shifted = UOffset >> BitPos;
 
 2563          return Shifted != 0;
 
 2564        for (
int I = 0; 
I != 64 - BitPos; 
I += 16)
 
 2565          if (((Shifted >> 
I) & 0xffff) != 0xffff)
 
 2569      for (
int BitPos = 16; BitPos != 64 && NeedMovk(BitPos); BitPos += 16)
 
 2570        emitMOVK(AArch64::X17, (UOffset >> BitPos) & 0xffff, BitPos);
 
 2572      EmitToStreamer(MCInstBuilder(AArch64::ADDXrs)
 
 2573                         .addReg(AArch64::X16)
 
 2574                         .addReg(AArch64::X16)
 
 2575                         .addReg(AArch64::X17)
 
 2580  Register DiscReg = emitPtrauthDiscriminator(Disc, AddrDisc, AArch64::X17);
 
 2583                 .addReg(AArch64::X16)
 
 2584                 .addReg(AArch64::X16);
 
 2585  if (DiscReg != AArch64::XZR)
 
 2586    MIB.addReg(DiscReg);
 
 2587  EmitToStreamer(MIB);
 
 2590void AArch64AsmPrinter::LowerLOADgotAUTH(
const MachineInstr &
MI) {
 
 2592  Register AuthResultReg = STI->hasFPAC() ? DstReg : AArch64::X16;
 
 2593  const MachineOperand &GAMO = 
MI.getOperand(1);
 
 2600        MCInstBuilder(AArch64::ADR).addReg(AArch64::X17).
addOperand(GAMC));
 
 2601    EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
 
 2602                       .addReg(AuthResultReg)
 
 2603                       .addReg(AArch64::X17)
 
 2606    MachineOperand GAHiOp(GAMO);
 
 2607    MachineOperand GALoOp(GAMO);
 
 2611    MCOperand GAMCHi, GAMCLo;
 
 2616        MCInstBuilder(AArch64::ADRP).addReg(AArch64::X17).
addOperand(GAMCHi));
 
 2618    EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
 
 2619                       .addReg(AArch64::X17)
 
 2620                       .addReg(AArch64::X17)
 
 2624    EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
 
 2625                       .addReg(AuthResultReg)
 
 2626                       .addReg(AArch64::X17)
 
 2633    UndefWeakSym = createTempSymbol(
"undef_weak");
 
 2635        MCInstBuilder(AArch64::CBZX)
 
 2636            .addReg(AuthResultReg)
 
 2644  EmitToStreamer(MCInstBuilder(AuthOpcode)
 
 2645                     .addReg(AuthResultReg)
 
 2646                     .addReg(AuthResultReg)
 
 2647                     .addReg(AArch64::X17));
 
 2652  if (!STI->hasFPAC()) {
 
 2656    emitPtrauthCheckAuthenticatedValue(AuthResultReg, AArch64::X17, AuthKey,
 
 2657                                       AArch64PAuth::AuthCheckMethod::XPAC,
 
 2661    emitMovXReg(DstReg, AuthResultReg);
 
 2666AArch64AsmPrinter::lowerBlockAddressConstant(
const BlockAddress &BA) {
 
 2670  if (std::optional<uint16_t> BADisc =
 
 2678void AArch64AsmPrinter::emitCBPseudoExpansion(
const MachineInstr *
MI) {
 
 2680  bool Is32Bit = 
false;
 
 2682  switch (
MI->getOpcode()) {
 
 2685  case AArch64::CBWPrr:
 
 2688  case AArch64::CBXPrr:
 
 2691  case AArch64::CBWPri:
 
 2695  case AArch64::CBXPri:
 
 2702  bool NeedsRegSwap = 
false;
 
 2703  bool NeedsImmDec = 
false;
 
 2704  bool NeedsImmInc = 
false;
 
 2713    MCOpC = IsImm ? (Is32Bit ? AArch64::CBEQWri : AArch64::CBEQXri)
 
 2714                  : (Is32Bit ? AArch64::CBEQWrr : AArch64::CBEQXrr);
 
 2717    MCOpC = IsImm ? (Is32Bit ? AArch64::CBNEWri : AArch64::CBNEXri)
 
 2718                  : (Is32Bit ? AArch64::CBNEWrr : AArch64::CBNEXrr);
 
 2721    MCOpC = IsImm ? (Is32Bit ? AArch64::CBHIWri : AArch64::CBHIXri)
 
 2722                  : (Is32Bit ? AArch64::CBHSWrr : AArch64::CBHSXrr);
 
 2723    NeedsImmDec = IsImm;
 
 2726    MCOpC = IsImm ? (Is32Bit ? AArch64::CBLOWri : AArch64::CBLOXri)
 
 2727                  : (Is32Bit ? AArch64::CBHIWrr : AArch64::CBHIXrr);
 
 2728    NeedsRegSwap = !IsImm;
 
 2731    MCOpC = IsImm ? (Is32Bit ? AArch64::CBHIWri : AArch64::CBHIXri)
 
 2732                  : (Is32Bit ? AArch64::CBHIWrr : AArch64::CBHIXrr);
 
 2735    MCOpC = IsImm ? (Is32Bit ? AArch64::CBLOWri : AArch64::CBLOXri)
 
 2736                  : (Is32Bit ? AArch64::CBHSWrr : AArch64::CBHSXrr);
 
 2737    NeedsRegSwap = !IsImm;
 
 2738    NeedsImmInc = IsImm;
 
 2741    MCOpC = IsImm ? (Is32Bit ? AArch64::CBGTWri : AArch64::CBGTXri)
 
 2742                  : (Is32Bit ? AArch64::CBGEWrr : AArch64::CBGEXrr);
 
 2743    NeedsImmDec = IsImm;
 
 2746    MCOpC = IsImm ? (Is32Bit ? AArch64::CBLTWri : AArch64::CBLTXri)
 
 2747                  : (Is32Bit ? AArch64::CBGTWrr : AArch64::CBGTXrr);
 
 2748    NeedsRegSwap = !IsImm;
 
 2751    MCOpC = IsImm ? (Is32Bit ? AArch64::CBGTWri : AArch64::CBGTXri)
 
 2752                  : (Is32Bit ? AArch64::CBGTWrr : AArch64::CBGTXrr);
 
 2755    MCOpC = IsImm ? (Is32Bit ? AArch64::CBLTWri : AArch64::CBLTXri)
 
 2756                  : (Is32Bit ? AArch64::CBGEWrr : AArch64::CBGEXrr);
 
 2757    NeedsRegSwap = !IsImm;
 
 2758    NeedsImmInc = IsImm;
 
 2765  MCOperand Lhs, Rhs, Trgt;
 
 2766  lowerOperand(
MI->getOperand(1), Lhs);
 
 2767  lowerOperand(
MI->getOperand(2), Rhs);
 
 2768  lowerOperand(
MI->getOperand(3), Trgt);
 
 2772    assert(Lhs.
isReg() && 
"Expected register operand for CB");
 
 2773    assert(Rhs.
isReg() && 
"Expected register operand for CB");
 
 2776  } 
else if (NeedsImmDec) {
 
 2780  } 
else if (NeedsImmInc) {
 
 2790         "CB immediate operand out-of-bounds");
 
 2793  EmitToStreamer(*OutStreamer, Inst);
 
 2798#include "AArch64GenMCPseudoLowering.inc" 
 2800void AArch64AsmPrinter::EmitToStreamer(MCStreamer &S, 
const MCInst &Inst) {
 
 2807void AArch64AsmPrinter::emitInstruction(
const MachineInstr *
MI) {
 
 2808  AArch64_MC::verifyInstructionPredicates(
MI->getOpcode(), STI->getFeatureBits());
 
 2818  if (MCInst OutInst; lowerPseudoInstExpansion(
MI, OutInst)) {
 
 2819    EmitToStreamer(*OutStreamer, OutInst);
 
 2823  if (
MI->getOpcode() == AArch64::ADRP) {
 
 2824    for (
auto &Opd : 
MI->operands()) {
 
 2825      if (Opd.isSymbol() && StringRef(Opd.getSymbolName()) ==
 
 2826                                "swift_async_extendedFramePointerFlags") {
 
 2827        ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags = 
true;
 
 2834    MCSymbol *LOHLabel = createTempSymbol(
"loh");
 
 2836    LOHInstToLabel[
MI] = LOHLabel;
 
 2840  AArch64TargetStreamer *TS =
 
 2843  switch (
MI->getOpcode()) {
 
 2846           "Unhandled tail call instruction");
 
 2848  case AArch64::HINT: {
 
 2853    if (CurrentPatchableFunctionEntrySym &&
 
 2854        CurrentPatchableFunctionEntrySym == CurrentFnBegin &&
 
 2855        MI == &MF->front().front()) {
 
 2856      int64_t 
Imm = 
MI->getOperand(0).getImm();
 
 2857      if ((Imm & 32) && (Imm & 6)) {
 
 2859        MCInstLowering.
Lower(
MI, Inst);
 
 2860        EmitToStreamer(*OutStreamer, Inst);
 
 2861        CurrentPatchableFunctionEntrySym = createTempSymbol(
"patch");
 
 2862        OutStreamer->
emitLabel(CurrentPatchableFunctionEntrySym);
 
 2868    case AArch64::MOVMCSym: {
 
 2869      Register DestReg = 
MI->getOperand(0).getReg();
 
 2870      const MachineOperand &MO_Sym = 
MI->getOperand(1);
 
 2871      MachineOperand Hi_MOSym(MO_Sym), Lo_MOSym(MO_Sym);
 
 2872      MCOperand Hi_MCSym, Lo_MCSym;
 
 2885      EmitToStreamer(*OutStreamer, MovZ);
 
 2893      EmitToStreamer(*OutStreamer, MovK);
 
 2896  case AArch64::MOVIv2d_ns:
 
 2904    if (STI->hasZeroCycleZeroingFPWorkaround() &&
 
 2905        MI->getOperand(1).getImm() == 0) {
 
 2907      TmpInst.
setOpcode(AArch64::MOVIv16b_ns);
 
 2910      EmitToStreamer(*OutStreamer, TmpInst);
 
 2915  case AArch64::DBG_VALUE:
 
 2916  case AArch64::DBG_VALUE_LIST:
 
 2918      SmallString<128> TmpStr;
 
 2919      raw_svector_ostream OS(TmpStr);
 
 2920      PrintDebugValueComment(
MI, OS);
 
 2925  case AArch64::EMITBKEY: {
 
 2927      if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
 
 2928          ExceptionHandlingType != ExceptionHandling::ARM)
 
 2931      if (getFunctionCFISectionType(*MF) == CFISection::None)
 
 2938  case AArch64::EMITMTETAGGED: {
 
 2940    if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
 
 2941        ExceptionHandlingType != ExceptionHandling::ARM)
 
 2944    if (getFunctionCFISectionType(*MF) != CFISection::None)
 
 2949  case AArch64::AUTx16x17:
 
 2950    emitPtrauthAuthResign(AArch64::X16,
 
 2952                          MI->getOperand(1).getImm(), &
MI->getOperand(2),
 
 2953                          AArch64::X17, std::nullopt, 0, 0);
 
 2956  case AArch64::AUTxMxN:
 
 2957    emitPtrauthAuthResign(
MI->getOperand(0).getReg(),
 
 2959                          MI->getOperand(4).getImm(), &
MI->getOperand(5),
 
 2960                          MI->getOperand(1).getReg(), std::nullopt, 0, 0);
 
 2963  case AArch64::AUTPAC:
 
 2964    emitPtrauthAuthResign(
 
 2966        MI->getOperand(1).getImm(), &
MI->getOperand(2), AArch64::X17,
 
 2968        MI->getOperand(4).getImm(), 
MI->getOperand(5).getReg());
 
 2972    emitPtrauthSign(
MI);
 
 2975  case AArch64::LOADauthptrstatic:
 
 2976    LowerLOADauthptrstatic(*
MI);
 
 2979  case AArch64::LOADgotPAC:
 
 2980  case AArch64::MOVaddrPAC:
 
 2981    LowerMOVaddrPAC(*
MI);
 
 2984  case AArch64::LOADgotAUTH:
 
 2985    LowerLOADgotAUTH(*
MI);
 
 2990    emitPtrauthBranch(
MI);
 
 2996  case AArch64::AUTH_TCRETURN:
 
 2997  case AArch64::AUTH_TCRETURN_BTI: {
 
 2999    const uint64_t 
Key = 
MI->getOperand(2).getImm();
 
 3001           "Invalid auth key for tail-call return");
 
 3003    const uint64_t Disc = 
MI->getOperand(3).getImm();
 
 3006    Register AddrDisc = 
MI->getOperand(4).getReg();
 
 3008    Register ScratchReg = 
Callee == AArch64::X16 ? AArch64::X17 : AArch64::X16;
 
 3010    emitPtrauthTailCallHardening(
MI);
 
 3013    if (Callee == AddrDisc)
 
 3020    bool AddrDiscIsImplicitDef =
 
 3021        AddrDisc == AArch64::X16 || AddrDisc == AArch64::X17;
 
 3022    Register DiscReg = emitPtrauthDiscriminator(Disc, AddrDisc, ScratchReg,
 
 3023                                                AddrDiscIsImplicitDef);
 
 3025    const bool IsZero = DiscReg == AArch64::XZR;
 
 3026    const unsigned Opcodes[2][2] = {{AArch64::BRAA, AArch64::BRAAZ},
 
 3027                                    {AArch64::BRAB, AArch64::BRABZ}};
 
 3034    EmitToStreamer(*OutStreamer, TmpInst);
 
 3038  case AArch64::TCRETURNri:
 
 3039  case AArch64::TCRETURNrix16x17:
 
 3040  case AArch64::TCRETURNrix17:
 
 3041  case AArch64::TCRETURNrinotx16:
 
 3042  case AArch64::TCRETURNriALL: {
 
 3043    emitPtrauthTailCallHardening(
MI);
 
 3045    recordIfImportCall(
MI);
 
 3049    EmitToStreamer(*OutStreamer, TmpInst);
 
 3052  case AArch64::TCRETURNdi: {
 
 3053    emitPtrauthTailCallHardening(
MI);
 
 3057    recordIfImportCall(
MI);
 
 3061    EmitToStreamer(*OutStreamer, TmpInst);
 
 3064  case AArch64::SpeculationBarrierISBDSBEndBB: {
 
 3069    EmitToStreamer(*OutStreamer, TmpInstDSB);
 
 3073    EmitToStreamer(*OutStreamer, TmpInstISB);
 
 3076  case AArch64::SpeculationBarrierSBEndBB: {
 
 3080    EmitToStreamer(*OutStreamer, TmpInstSB);
 
 3083  case AArch64::TLSDESC_AUTH_CALLSEQ: {
 
 3090    const MachineOperand &MO_Sym = 
MI->getOperand(0);
 
 3091    MachineOperand MO_TLSDESC_LO12(MO_Sym), MO_TLSDESC(MO_Sym);
 
 3092    MCOperand SymTLSDescLo12, SymTLSDesc;
 
 3095    MCInstLowering.
lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
 
 3102    EmitToStreamer(*OutStreamer, Adrp);
 
 3110    EmitToStreamer(*OutStreamer, Ldr);
 
 3113    Add.setOpcode(AArch64::ADDXri);
 
 3116    Add.addOperand(SymTLSDescLo12);
 
 3118    EmitToStreamer(*OutStreamer, 
Add);
 
 3127    EmitToStreamer(*OutStreamer, Blraa);
 
 3131  case AArch64::TLSDESC_CALLSEQ: {
 
 3139    const MachineOperand &MO_Sym = 
MI->getOperand(0);
 
 3140    MachineOperand MO_TLSDESC_LO12(MO_Sym), MO_TLSDESC(MO_Sym);
 
 3141    MCOperand Sym, SymTLSDescLo12, SymTLSDesc;
 
 3145    MCInstLowering.
lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
 
 3152    EmitToStreamer(*OutStreamer, Adrp);
 
 3165    EmitToStreamer(*OutStreamer, Ldr);
 
 3169      Add.setOpcode(AArch64::ADDWri);
 
 3173      Add.setOpcode(AArch64::ADDXri);
 
 3177    Add.addOperand(SymTLSDescLo12);
 
 3179    EmitToStreamer(*OutStreamer, 
Add);
 
 3184    TLSDescCall.
setOpcode(AArch64::TLSDESCCALL);
 
 3186    EmitToStreamer(*OutStreamer, TLSDescCall);
 
 3194    EmitToStreamer(*OutStreamer, Blr);
 
 3199  case AArch64::JumpTableDest32:
 
 3200  case AArch64::JumpTableDest16:
 
 3201  case AArch64::JumpTableDest8:
 
 3202    LowerJumpTableDest(*OutStreamer, *
MI);
 
 3205  case AArch64::BR_JumpTable:
 
 3206    LowerHardenedBRJumpTable(*
MI);
 
 3209  case AArch64::FMOVH0:
 
 3210  case AArch64::FMOVS0:
 
 3211  case AArch64::FMOVD0:
 
 3215  case AArch64::MOPSMemoryCopyPseudo:
 
 3216  case AArch64::MOPSMemoryMovePseudo:
 
 3217  case AArch64::MOPSMemorySetPseudo:
 
 3218  case AArch64::MOPSMemorySetTaggingPseudo:
 
 3219    LowerMOPS(*OutStreamer, *
MI);
 
 3222  case TargetOpcode::STACKMAP:
 
 3223    return LowerSTACKMAP(*OutStreamer, SM, *
MI);
 
 3225  case TargetOpcode::PATCHPOINT:
 
 3226    return LowerPATCHPOINT(*OutStreamer, SM, *
MI);
 
 3228  case TargetOpcode::STATEPOINT:
 
 3229    return LowerSTATEPOINT(*OutStreamer, SM, *
MI);
 
 3231  case TargetOpcode::FAULTING_OP:
 
 3232    return LowerFAULTING_OP(*
MI);
 
 3234  case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
 
 3235    LowerPATCHABLE_FUNCTION_ENTER(*
MI);
 
 3238  case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
 
 3239    LowerPATCHABLE_FUNCTION_EXIT(*
MI);
 
 3242  case TargetOpcode::PATCHABLE_TAIL_CALL:
 
 3243    LowerPATCHABLE_TAIL_CALL(*
MI);
 
 3245  case TargetOpcode::PATCHABLE_EVENT_CALL:
 
 3246    return LowerPATCHABLE_EVENT_CALL(*
MI, 
false);
 
 3247  case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
 
 3248    return LowerPATCHABLE_EVENT_CALL(*
MI, 
true);
 
 3250  case AArch64::KCFI_CHECK:
 
 3251    LowerKCFI_CHECK(*
MI);
 
 3254  case AArch64::HWASAN_CHECK_MEMACCESS:
 
 3255  case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
 
 3256  case AArch64::HWASAN_CHECK_MEMACCESS_FIXEDSHADOW:
 
 3257  case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW:
 
 3258    LowerHWASAN_CHECK_MEMACCESS(*
MI);
 
 3261  case AArch64::SEH_StackAlloc:
 
 3265  case AArch64::SEH_SaveFPLR:
 
 3269  case AArch64::SEH_SaveFPLR_X:
 
 3270    assert(
MI->getOperand(0).getImm() < 0 &&
 
 3271           "Pre increment SEH opcode must have a negative offset");
 
 3275  case AArch64::SEH_SaveReg:
 
 3277                               MI->getOperand(1).getImm());
 
 3280  case AArch64::SEH_SaveReg_X:
 
 3281    assert(
MI->getOperand(1).getImm() < 0 &&
 
 3282           "Pre increment SEH opcode must have a negative offset");
 
 3284                                -
MI->getOperand(1).getImm());
 
 3287  case AArch64::SEH_SaveRegP:
 
 3288    if (
MI->getOperand(1).getImm() == 30 && 
MI->getOperand(0).getImm() >= 19 &&
 
 3289        MI->getOperand(0).getImm() <= 28) {
 
 3290      assert((
MI->getOperand(0).getImm() - 19) % 2 == 0 &&
 
 3291             "Register paired with LR must be odd");
 
 3293                                    MI->getOperand(2).getImm());
 
 3296    assert((
MI->getOperand(1).getImm() - 
MI->getOperand(0).getImm() == 1) &&
 
 3297            "Non-consecutive registers not allowed for save_regp");
 
 3299                                MI->getOperand(2).getImm());
 
 3302  case AArch64::SEH_SaveRegP_X:
 
 3303    assert((
MI->getOperand(1).getImm() - 
MI->getOperand(0).getImm() == 1) &&
 
 3304            "Non-consecutive registers not allowed for save_regp_x");
 
 3305    assert(
MI->getOperand(2).getImm() < 0 &&
 
 3306           "Pre increment SEH opcode must have a negative offset");
 
 3308                                 -
MI->getOperand(2).getImm());
 
 3311  case AArch64::SEH_SaveFReg:
 
 3313                                MI->getOperand(1).getImm());
 
 3316  case AArch64::SEH_SaveFReg_X:
 
 3317    assert(
MI->getOperand(1).getImm() < 0 &&
 
 3318           "Pre increment SEH opcode must have a negative offset");
 
 3320                                 -
MI->getOperand(1).getImm());
 
 3323  case AArch64::SEH_SaveFRegP:
 
 3324    assert((
MI->getOperand(1).getImm() - 
MI->getOperand(0).getImm() == 1) &&
 
 3325            "Non-consecutive registers not allowed for save_regp");
 
 3327                                 MI->getOperand(2).getImm());
 
 3330  case AArch64::SEH_SaveFRegP_X:
 
 3331    assert((
MI->getOperand(1).getImm() - 
MI->getOperand(0).getImm() == 1) &&
 
 3332            "Non-consecutive registers not allowed for save_regp_x");
 
 3333    assert(
MI->getOperand(2).getImm() < 0 &&
 
 3334           "Pre increment SEH opcode must have a negative offset");
 
 3336                                  -
MI->getOperand(2).getImm());
 
 3339  case AArch64::SEH_SetFP:
 
 3343  case AArch64::SEH_AddFP:
 
 3347  case AArch64::SEH_Nop:
 
 3351  case AArch64::SEH_PrologEnd:
 
 3355  case AArch64::SEH_EpilogStart:
 
 3359  case AArch64::SEH_EpilogEnd:
 
 3363  case AArch64::SEH_PACSignLR:
 
 3367  case AArch64::SEH_SaveAnyRegQP:
 
 3368    assert(
MI->getOperand(1).getImm() - 
MI->getOperand(0).getImm() == 1 &&
 
 3369           "Non-consecutive registers not allowed for save_any_reg");
 
 3370    assert(
MI->getOperand(2).getImm() >= 0 &&
 
 3371           "SaveAnyRegQP SEH opcode offset must be non-negative");
 
 3372    assert(
MI->getOperand(2).getImm() <= 1008 &&
 
 3373           "SaveAnyRegQP SEH opcode offset must fit into 6 bits");
 
 3375                                    MI->getOperand(2).getImm());
 
 3378  case AArch64::SEH_SaveAnyRegQPX:
 
 3379    assert(
MI->getOperand(1).getImm() - 
MI->getOperand(0).getImm() == 1 &&
 
 3380           "Non-consecutive registers not allowed for save_any_reg");
 
 3381    assert(
MI->getOperand(2).getImm() < 0 &&
 
 3382           "SaveAnyRegQPX SEH opcode offset must be negative");
 
 3383    assert(
MI->getOperand(2).getImm() >= -1008 &&
 
 3384           "SaveAnyRegQPX SEH opcode offset must fit into 6 bits");
 
 3386                                     -
MI->getOperand(2).getImm());
 
 3389  case AArch64::SEH_AllocZ:
 
 3390    assert(
MI->getOperand(0).getImm() >= 0 &&
 
 3391           "AllocZ SEH opcode offset must be non-negative");
 
 3392    assert(
MI->getOperand(0).getImm() <= 255 &&
 
 3393           "AllocZ SEH opcode offset must fit into 8 bits");
 
 3397  case AArch64::SEH_SaveZReg:
 
 3398    assert(
MI->getOperand(1).getImm() >= 0 &&
 
 3399           "SaveZReg SEH opcode offset must be non-negative");
 
 3400    assert(
MI->getOperand(1).getImm() <= 255 &&
 
 3401           "SaveZReg SEH opcode offset must fit into 8 bits");
 
 3403                                MI->getOperand(1).getImm());
 
 3406  case AArch64::SEH_SavePReg:
 
 3407    assert(
MI->getOperand(1).getImm() >= 0 &&
 
 3408           "SavePReg SEH opcode offset must be non-negative");
 
 3409    assert(
MI->getOperand(1).getImm() <= 255 &&
 
 3410           "SavePReg SEH opcode offset must fit into 8 bits");
 
 3412                                MI->getOperand(1).getImm());
 
 3417    recordIfImportCall(
MI);
 
 3419    MCInstLowering.
Lower(
MI, TmpInst);
 
 3420    EmitToStreamer(*OutStreamer, TmpInst);
 
 3423  case AArch64::CBWPri:
 
 3424  case AArch64::CBXPri:
 
 3425  case AArch64::CBWPrr:
 
 3426  case AArch64::CBXPrr:
 
 3427    emitCBPseudoExpansion(
MI);
 
 3433  MCInstLowering.
Lower(
MI, TmpInst);
 
 3434  EmitToStreamer(*OutStreamer, TmpInst);
 
 3437void AArch64AsmPrinter::recordIfImportCall(
 
 3438    const llvm::MachineInstr *BranchInst) {
 
 3439  if (!EnableImportCallOptimization)
 
 3443  if (GV && GV->hasDLLImportStorageClass()) {
 
 3444    auto *CallSiteSymbol = MMI->getContext().createNamedTempSymbol(
"impcall");
 
 3449        .push_back({CallSiteSymbol, CalledSymbol});
 
 3453void AArch64AsmPrinter::emitMachOIFuncStubBody(
Module &M, 
const GlobalIFunc &GI,
 
 3454                                               MCSymbol *LazyPointer) {
 
 3471    EmitToStreamer(Adrp);
 
 3479    MCOperand SymPageOff;
 
 3486    EmitToStreamer(Ldr);
 
 3489  EmitToStreamer(MCInstBuilder(AArch64::LDRXui)
 
 3490                     .addReg(AArch64::X16)
 
 3491                     .addReg(AArch64::X16)
 
 3494  EmitToStreamer(MCInstBuilder(
TM.getTargetTriple().isArm64e() ? AArch64::BRAAZ
 
 3496                     .addReg(AArch64::X16));
 
 3499void AArch64AsmPrinter::emitMachOIFuncStubHelperBody(
Module &M,
 
 3500                                                     const GlobalIFunc &GI,
 
 3501                                                     MCSymbol *LazyPointer) {
 
 3533  EmitToStreamer(MCInstBuilder(AArch64::STPXpre)
 
 3534                     .addReg(AArch64::SP)
 
 3535                     .addReg(AArch64::FP)
 
 3536                     .addReg(AArch64::LR)
 
 3537                     .addReg(AArch64::SP)
 
 3540  EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
 
 3541                     .addReg(AArch64::FP)
 
 3542                     .addReg(AArch64::SP)
 
 3546  for (
int I = 0; 
I != 4; ++
I)
 
 3547    EmitToStreamer(MCInstBuilder(AArch64::STPXpre)
 
 3548                       .addReg(AArch64::SP)
 
 3549                       .addReg(AArch64::X1 + 2 * 
I)
 
 3550                       .addReg(AArch64::X0 + 2 * 
I)
 
 3551                       .addReg(AArch64::SP)
 
 3554  for (
int I = 0; 
I != 4; ++
I)
 
 3555    EmitToStreamer(MCInstBuilder(AArch64::STPDpre)
 
 3556                       .addReg(AArch64::SP)
 
 3557                       .addReg(AArch64::D1 + 2 * 
I)
 
 3558                       .addReg(AArch64::D0 + 2 * 
I)
 
 3559                       .addReg(AArch64::SP)
 
 3563      MCInstBuilder(AArch64::BL)
 
 3576    EmitToStreamer(Adrp);
 
 3584    MCOperand SymPageOff;
 
 3591    EmitToStreamer(Ldr);
 
 3594  EmitToStreamer(MCInstBuilder(AArch64::STRXui)
 
 3595                     .addReg(AArch64::X0)
 
 3596                     .addReg(AArch64::X16)
 
 3599  EmitToStreamer(MCInstBuilder(AArch64::ADDXri)
 
 3600                     .addReg(AArch64::X16)
 
 3601                     .addReg(AArch64::X0)
 
 3605  for (
int I = 3; 
I != -1; --
I)
 
 3606    EmitToStreamer(MCInstBuilder(AArch64::LDPDpost)
 
 3607                       .addReg(AArch64::SP)
 
 3608                       .addReg(AArch64::D1 + 2 * 
I)
 
 3609                       .addReg(AArch64::D0 + 2 * 
I)
 
 3610                       .addReg(AArch64::SP)
 
 3613  for (
int I = 3; 
I != -1; --
I)
 
 3614    EmitToStreamer(MCInstBuilder(AArch64::LDPXpost)
 
 3615                       .addReg(AArch64::SP)
 
 3616                       .addReg(AArch64::X1 + 2 * 
I)
 
 3617                       .addReg(AArch64::X0 + 2 * 
I)
 
 3618                       .addReg(AArch64::SP)
 
 3621  EmitToStreamer(MCInstBuilder(AArch64::LDPXpost)
 
 3622                     .addReg(AArch64::SP)
 
 3623                     .addReg(AArch64::FP)
 
 3624                     .addReg(AArch64::LR)
 
 3625                     .addReg(AArch64::SP)
 
 3628  EmitToStreamer(MCInstBuilder(
TM.getTargetTriple().isArm64e() ? AArch64::BRAAZ
 
 3630                     .addReg(AArch64::X16));
 
 3633const MCExpr *AArch64AsmPrinter::lowerConstant(
const Constant *CV,
 
 3634                                               const Constant *BaseCV,
 
 3644char AArch64AsmPrinter::ID = 0;
 
 3647                "AArch64 Assembly Printer", 
false, 
false)
 
 3651LLVMInitializeAArch64AsmPrinter() {
 
 
static cl::opt< PtrauthCheckMode > PtrauthAuthChecks("aarch64-ptrauth-auth-checks", cl::Hidden, cl::values(clEnumValN(Unchecked, "none", "don't test for failure"), clEnumValN(Poison, "poison", "poison on failure"), clEnumValN(Trap, "trap", "trap on failure")), cl::desc("Check pointer authentication auth/resign failures"), cl::init(Default))
 
static void emitAuthenticatedPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, const MCExpr *StubAuthPtrRef)
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
 
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
 
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
 
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
 
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
 
#define LLVM_EXTERNAL_VISIBILITY
 
This file defines the DenseMap class.
 
Module.h This file contains the declarations for the Module class.
 
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
 
#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 make_scope_exit function, which executes user-defined cleanup logic at scope ex...
 
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
 
This file defines the SmallString class.
 
This file defines the SmallVector class.
 
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
 
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
 
static bool printAsmMRegister(const X86AsmPrinter &P, const MachineOperand &MO, char Mode, raw_ostream &O)
 
static const AArch64AuthMCExpr * create(const MCExpr *Expr, uint16_t Discriminator, AArch64PACKey::ID Key, bool HasAddressDiversity, MCContext &Ctx, SMLoc Loc=SMLoc())
 
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
 
bool shouldSignReturnAddress(const MachineFunction &MF) const
 
const SetOfInstructions & getLOHRelated() const
 
unsigned getJumpTableEntrySize(int Idx) const
 
MCSymbol * getJumpTableEntryPCRelSymbol(int Idx) const
 
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.
 
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Return the number of bytes of code the specified instruction may be.
 
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 AArch64RegisterInfo * getRegisterInfo() const override
 
bool isNeonAvailable() const
Returns true if the target has NEON and the function at runtime is known to have NEON enabled (e....
 
const AArch64InstrInfo * getInstrInfo() const override
 
bool isTargetILP32() const
 
std::optional< uint16_t > getPtrAuthBlockAddressDiscriminatorIfEnabled(const Function &ParentFn) const
Compute the integer discriminator for a given BlockAddress constant, if blockaddress signing is enabl...
 
bool isX16X17Safer() const
Returns whether the operating system makes it safer to store sensitive values in x16 and x17 as oppos...
 
AArch64PAuth::AuthCheckMethod getAuthenticatedLRCheckMethod(const MachineFunction &MF) const
Choose a method of checking LR before performing a tail call.
 
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 emitARM64WinCFISaveFRegPX(unsigned Reg, int Offset)
 
virtual void emitARM64WinCFISaveRegX(unsigned Reg, int Offset)
 
virtual void emitARM64WinCFIAllocStack(unsigned Size)
 
virtual void emitARM64WinCFISaveFPLRX(int Offset)
 
virtual void emitARM64WinCFIAllocZ(int Offset)
 
virtual void emitDirectiveVariantPCS(MCSymbol *Symbol)
Callback used to implement the .variant_pcs directive.
 
virtual void emitARM64WinCFIAddFP(unsigned Size)
 
virtual void emitARM64WinCFISaveFPLR(int Offset)
 
virtual void emitARM64WinCFISaveFRegP(unsigned Reg, int Offset)
 
virtual void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset)
 
virtual void emitARM64WinCFISaveFRegX(unsigned Reg, int Offset)
 
virtual void emitARM64WinCFISetFP()
 
virtual void emitARM64WinCFIEpilogEnd()
 
virtual void emitARM64WinCFISaveZReg(unsigned Reg, int Offset)
 
virtual void emitARM64WinCFIPrologEnd()
 
virtual void emitARM64WinCFISaveReg(unsigned Reg, int Offset)
 
virtual void emitARM64WinCFINop()
 
virtual void emitARM64WinCFISaveLRPair(unsigned Reg, int Offset)
 
virtual void emitAttribute(StringRef VendorName, unsigned Tag, unsigned Value, std::string String)
 
virtual void emitARM64WinCFIEpilogStart()
 
Represent the analysis usage information of a pass.
 
void setPreservesAll()
Set by analyses that do not transform their input at all.
 
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
 
const T & front() const
front - Get the first element.
 
bool empty() const
empty - Check if the array is empty.
 
This class is intended to be used as a driving class for all asm writers.
 
virtual void emitGlobalAlias(const Module &M, const GlobalAlias &GA)
 
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
 
virtual const MCExpr * lowerConstant(const Constant *CV, const Constant *BaseCV=nullptr, uint64_t Offset=0)
Lower the specified LLVM Constant to an MCExpr.
 
void getAnalysisUsage(AnalysisUsage &AU) const override
Record analysis usage.
 
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.
 
The address of a basic block.
 
Function * getFunction() const
 
Conditional or Unconditional Branch instruction.
 
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
 
A signed pointer, in the ptrauth sense.
 
@ AddrDiscriminator_CtorsDtors
 
Constant * getPointer() const
The pointer that is signed in this ptrauth signed pointer.
 
ConstantInt * getKey() const
The Key ID, an i32 constant.
 
bool hasAddressDiscriminator() const
Whether there is any non-null address discriminator.
 
ConstantInt * getDiscriminator() const
The integer discriminator, an i64 constant, or 0.
 
This is an important base class in LLVM.
 
A parsed version of the target data layout string in and methods for querying it.
 
void recordFaultingOp(FaultKind FaultTy, const MCSymbol *FaultingLabel, const MCSymbol *HandlerLabel)
 
void serializeToFaultMapSection()
 
const Constant * getAliasee() const
 
const Constant * getResolver() const
 
bool hasLocalLinkage() const
 
bool hasExternalWeakLinkage() const
 
Type * getValueType() const
 
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)
 
Base class for the full range of assembler expressions which are needed for parsing.
 
Instances of this class represent a single low-level machine instruction.
 
void addOperand(const MCOperand Op)
 
void setOpcode(unsigned Op)
 
MCSection * getDataSection() const
 
Instances of this class represent operands of the MCInst class.
 
static MCOperand createExpr(const MCExpr *Val)
 
static MCOperand createReg(MCRegister Reg)
 
static MCOperand createImm(int64_t Val)
 
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
 
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
 
Streaming machine code generation interface.
 
virtual void emitCFIBKeyFrame()
 
virtual void beginCOFFSymbolDef(const MCSymbol *Symbol)
Start emitting COFF symbol definition.
 
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
 
virtual void emitCOFFSymbolType(int Type)
Emit the type of the symbol.
 
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText.
 
virtual void endCOFFSymbolDef()
Marks the end of the symbol definition.
 
MCContext & getContext() const
 
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
 
virtual void emitCFIMTETaggedFrame()
 
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()
 
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 emitCOFFSymbolStorageClass(int StorageClass)
Emit the storage class of the symbol.
 
Generic base class for all target subtargets.
 
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.
 
MachineInstrBundleIterator< const MachineInstr > const_iterator
 
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for 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.
 
Function & getFunction()
Return the LLVM function that this machine code represents.
 
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
 
Representation of each machine instruction.
 
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()
 
MachineOperand class - Representation of each machine instruction operand.
 
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.
 
A Module instance is used to store all the information related to an LLVM module.
 
Wrapper class representing virtual and physical registers.
 
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.
 
StringRef - Represent a constant reference to a string, i.e.
 
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
 
virtual MCSection * getSectionForJumpTable(const Function &F, const TargetMachine &TM) const
 
Primary interface to the complete machine description for the target machine.
 
MCRegister getRegister(unsigned i) const
Return the specified register in the class.
 
bool regsOverlap(Register RegA, Register RegB) const
Returns true if the two registers are equal or alias each other.
 
The instances of the Type class are immutable: once they are created, they are never changed.
 
bool isFunctionTy() const
True if this is an instance of FunctionType.
 
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 LLVMContext & getContext() const
All values hold a context through their type.
 
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
 
This class implements an extremely fast bulk output stream that can only output to a stream.
 
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
 
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.
 
AuthCheckMethod
Variants of check performed on an authenticated pointer.
 
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))
 
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
 
@ GNU_PROPERTY_AARCH64_FEATURE_1_BTI
 
@ GNU_PROPERTY_AARCH64_FEATURE_1_PAC
 
@ GNU_PROPERTY_AARCH64_FEATURE_1_GCS
 
@ S_REGULAR
S_REGULAR - Regular section.
 
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
 
initializer< Ty > init(const Ty &Val)
 
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)
Extract a Value from Metadata, allowing null.
 
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.
 
FunctionAddr VTableAddr Value
 
LLVM_ABI std::optional< std::string > getArm64ECMangledFunctionName(StringRef Name)
Returns the ARM64EC mangled function name unless the input is already mangled.
 
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
 
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
 
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)
 
Target & getTheAArch64leTarget()
 
auto dyn_cast_or_null(const Y &Val)
 
Target & getTheAArch64_32Target()
 
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
 
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)
 
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
 
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)
 
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...