70#define DEBUG_TYPE "asm-printer"
78 bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags =
false;
81 AArch64AsmPrinter(
TargetMachine &
TM, std::unique_ptr<MCStreamer> Streamer)
82 :
AsmPrinter(
TM, std::move(Streamer)), MCInstLowering(OutContext, *
this),
98 const MCSymbol *BranchLabel)
const override;
117 void LowerPATCHABLE_EVENT_CALL(
const MachineInstr &
MI,
bool Typed);
119 typedef std::tuple<unsigned, bool, uint32_t> HwasanMemaccessTuple;
120 std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
123 void emitHwasanMemaccessSymbols(
Module &M);
129 bool emitPseudoExpansionLowering(
MCStreamer &OutStreamer,
134 void emitFunctionHeaderComment()
override;
147 if (STI->isTargetCOFF()) {
199 using MInstToMCSymbol = std::map<const MachineInstr *, MCSymbol *>;
201 MInstToMCSymbol LOHInstToLabel;
204 return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags;
219void AArch64AsmPrinter::emitStartOfAsmFile(
Module &M) {
222 if (
TT.isOSBinFormatCOFF()) {
225 OutStreamer->beginCOFFSymbolDef(S);
228 OutStreamer->endCOFFSymbolDef();
229 int64_t Feat00Value = 0;
231 if (
M.getModuleFlag(
"cfguard")) {
233 Feat00Value |= COFF::Feat00Flags::GuardCF;
236 if (
M.getModuleFlag(
"ehcontguard")) {
238 Feat00Value |= COFF::Feat00Flags::GuardEHCont;
241 if (
M.getModuleFlag(
"ms-kernel")) {
243 Feat00Value |= COFF::Feat00Flags::Kernel;
247 OutStreamer->emitAssignment(
251 if (!
TT.isOSBinFormatELF())
256 if (
const auto *BTE = mdconst::extract_or_null<ConstantInt>(
257 M.getModuleFlag(
"branch-target-enforcement")))
258 if (BTE->getZExtValue())
261 if (
const auto *GCS = mdconst::extract_or_null<ConstantInt>(
262 M.getModuleFlag(
"guarded-control-stack")))
263 if (GCS->getZExtValue())
266 if (
const auto *Sign = mdconst::extract_or_null<ConstantInt>(
267 M.getModuleFlag(
"sign-return-address")))
268 if (Sign->getZExtValue())
272 if (
const auto *PAP = mdconst::extract_or_null<ConstantInt>(
273 M.getModuleFlag(
"aarch64-elf-pauthabi-platform")))
274 PAuthABIPlatform = PAP->getZExtValue();
276 if (
const auto *PAV = mdconst::extract_or_null<ConstantInt>(
277 M.getModuleFlag(
"aarch64-elf-pauthabi-version")))
278 PAuthABIVersion = PAV->getZExtValue();
286void AArch64AsmPrinter::emitFunctionHeaderComment() {
289 if (OutlinerString != std::nullopt)
290 OutStreamer->getCommentOS() <<
' ' << OutlinerString;
293void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr &
MI)
296 if (
F.hasFnAttribute(
"patchable-function-entry")) {
298 if (
F.getFnAttribute(
"patchable-function-entry")
300 .getAsInteger(10, Num))
306 emitSled(
MI, SledKind::FUNCTION_ENTER);
309void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr &
MI) {
310 emitSled(
MI, SledKind::FUNCTION_EXIT);
313void AArch64AsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr &
MI) {
314 emitSled(
MI, SledKind::TAIL_CALL);
317void AArch64AsmPrinter::emitSled(
const MachineInstr &
MI, SledKind Kind) {
318 static const int8_t NoopsInSledCount = 7;
339 OutStreamer->emitCodeAlignment(
Align(4), &getSubtargetInfo());
340 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
341 OutStreamer->emitLabel(CurSled);
342 auto Target = OutContext.createTempSymbol();
347 EmitToStreamer(*OutStreamer,
MCInstBuilder(AArch64::B).addImm(8));
349 for (int8_t
I = 0;
I < NoopsInSledCount;
I++)
350 EmitToStreamer(*OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
352 OutStreamer->emitLabel(
Target);
353 recordSled(CurSled,
MI, Kind, 2);
371void AArch64AsmPrinter::LowerPATCHABLE_EVENT_CALL(
const MachineInstr &
MI,
373 auto &
O = *OutStreamer;
374 MCSymbol *CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
375 O.emitLabel(CurSled);
386 bool MachO =
TM.getTargetTriple().isOSBinFormatMachO();
388 OutContext.getOrCreateSymbol(
389 Twine(MachO ?
"_" :
"") +
390 (Typed ?
"__xray_TypedEvent" :
"__xray_CustomEvent")),
393 O.AddComment(
"Begin XRay typed event");
405 EmitToStreamer(O, MovX0Op0);
406 EmitToStreamer(O, MovX1Op1);
409 .addReg(AArch64::XZR)
410 .addReg(
MI.getOperand(2).getReg())
417 O.AddComment(
"End XRay typed event");
425 recordSled(CurSled,
MI, SledKind::TYPED_EVENT, 2);
427 O.AddComment(
"Begin XRay custom event");
435 EmitToStreamer(O, MovX0Op0);
436 EmitToStreamer(O, MovX1Op1);
438 O.AddComment(
"End XRay custom event");
446 recordSled(CurSled,
MI, SledKind::CUSTOM_EVENT, 2);
452 assert(std::next(
MI.getIterator())->isCall() &&
453 "KCFI_CHECK not followed by a call instruction");
454 assert(std::next(
MI.getIterator())->getOperand(0).getReg() == AddrReg &&
455 "KCFI_CHECK call target doesn't match call operand");
459 unsigned ScratchRegs[] = {AArch64::W16, AArch64::W17};
460 if (AddrReg == AArch64::XZR) {
466 .addReg(AArch64::XZR)
467 .addReg(AArch64::XZR)
474 for (
auto &Reg : ScratchRegs) {
480 assert(ScratchRegs[0] != AddrReg && ScratchRegs[1] != AddrReg &&
481 "Invalid scratch registers for KCFI_CHECK");
485 int64_t PrefixNops = 0;
488 .getFnAttribute(
"patchable-function-prefix")
490 .getAsInteger(10, PrefixNops);
494 .addReg(ScratchRegs[0])
496 .addImm(-(PrefixNops * 4 + 4)));
500 const int64_t
Type =
MI.getOperand(1).getImm();
502 .addReg(ScratchRegs[1])
503 .addReg(ScratchRegs[1])
504 .addImm(
Type & 0xFFFF)
507 .addReg(ScratchRegs[1])
508 .addReg(ScratchRegs[1])
509 .addImm((
Type >> 16) & 0xFFFF)
514 .addReg(AArch64::WZR)
515 .addReg(ScratchRegs[0])
516 .addReg(ScratchRegs[1])
520 EmitToStreamer(*OutStreamer,
530 unsigned TypeIndex = ScratchRegs[1] - AArch64::W0;
534 AddrIndex = AddrReg - AArch64::X0;
544 assert(AddrIndex < 31 && TypeIndex < 31);
546 unsigned ESR = 0x8000 | ((TypeIndex & 31) << 5) | (AddrIndex & 31);
547 EmitToStreamer(*OutStreamer,
MCInstBuilder(AArch64::BRK).addImm(ESR));
548 OutStreamer->emitLabel(
Pass);
551void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
554 MI.getOpcode() == AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES;
555 uint32_t AccessInfo =
MI.getOperand(1).getImm();
557 HwasanMemaccessSymbols[HwasanMemaccessTuple(Reg, IsShort, AccessInfo)];
560 if (!
TM.getTargetTriple().isOSBinFormatELF())
563 std::string SymName =
"__hwasan_check_x" + utostr(Reg - AArch64::X0) +
"_" +
566 SymName +=
"_short_v2";
567 Sym = OutContext.getOrCreateSymbol(SymName);
570 EmitToStreamer(*OutStreamer,
575void AArch64AsmPrinter::emitHwasanMemaccessSymbols(
Module &M) {
576 if (HwasanMemaccessSymbols.empty())
581 std::unique_ptr<MCSubtargetInfo> STI(
582 TM.getTarget().createMCSubtargetInfo(
TT.str(),
"",
""));
583 assert(STI &&
"Unable to create subtarget info");
586 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch");
588 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
595 for (
auto &
P : HwasanMemaccessSymbols) {
596 unsigned Reg = std::get<0>(
P.first);
597 bool IsShort = std::get<1>(
P.first);
598 uint32_t AccessInfo = std::get<2>(
P.first);
600 IsShort ? HwasanTagMismatchV2Ref : HwasanTagMismatchV1Ref;
603 bool HasMatchAllTag =
605 uint8_t MatchAllTag =
612 OutStreamer->switchSection(OutContext.getELFSection(
620 OutStreamer->emitLabel(
Sym);
628 OutStreamer->emitInstruction(
631 .
addReg(IsShort ? AArch64::X20 : AArch64::X9)
636 OutStreamer->emitInstruction(
643 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
644 OutStreamer->emitInstruction(
650 MCSymbol *ReturnSym = OutContext.createTempSymbol();
651 OutStreamer->emitLabel(ReturnSym);
652 OutStreamer->emitInstruction(
654 OutStreamer->emitLabel(HandleMismatchOrPartialSym);
656 if (HasMatchAllTag) {
669 OutStreamer->emitInstruction(
683 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
684 OutStreamer->emitInstruction(
690 OutStreamer->emitInstruction(
709 OutStreamer->emitInstruction(
715 OutStreamer->emitInstruction(
726 OutStreamer->emitInstruction(
733 OutStreamer->emitInstruction(
739 OutStreamer->emitLabel(HandleMismatchSym);
756 if (Reg != AArch64::X0)
763 OutStreamer->emitInstruction(
774 OutStreamer->emitInstruction(
780 OutStreamer->emitInstruction(
784 HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_PAGE,
787 OutStreamer->emitInstruction(
792 HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_LO12,
795 OutStreamer->emitInstruction(
801void AArch64AsmPrinter::emitEndOfAsmFile(
Module &M) {
802 emitHwasanMemaccessSymbols(M);
805 if (
TT.isOSBinFormatMachO()) {
815 FM.serializeToFaultMapSection();
819void AArch64AsmPrinter::emitLOHs() {
822 for (
const auto &
D : AArch64FI->getLOHContainer()) {
824 MInstToMCSymbol::iterator LabelIt = LOHInstToLabel.find(
MI);
825 assert(LabelIt != LOHInstToLabel.end() &&
826 "Label hasn't been inserted for LOH related instruction");
829 OutStreamer->emitLOHDirective(
D.getKind(), MCArgs);
834void AArch64AsmPrinter::emitFunctionBodyEnd() {
835 if (!AArch64FI->getLOHRelated().empty())
840MCSymbol *AArch64AsmPrinter::GetCPISymbol(
unsigned CPID)
const {
844 if (!getDataLayout().getLinkerPrivateGlobalPrefix().empty())
845 return OutContext.getOrCreateSymbol(
846 Twine(getDataLayout().getLinkerPrivateGlobalPrefix()) +
"CPI" +
847 Twine(getFunctionNumber()) +
"_" +
Twine(CPID));
852void AArch64AsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNum,
870 PrintSymbolOperand(MO, O);
881bool AArch64AsmPrinter::printAsmMRegister(
const MachineOperand &MO,
char Mode,
905bool AArch64AsmPrinter::printAsmRegInClass(
const MachineOperand &MO,
908 assert(MO.
isReg() &&
"Should only get here with a register!");
918bool AArch64AsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNum,
927 if (ExtraCode && ExtraCode[0]) {
928 if (ExtraCode[1] != 0)
931 switch (ExtraCode[0]) {
939 unsigned Reg = ExtraCode[0] ==
'w' ? AArch64::WZR : AArch64::XZR;
953 switch (ExtraCode[0]) {
955 RC = &AArch64::FPR8RegClass;
958 RC = &AArch64::FPR16RegClass;
961 RC = &AArch64::FPR32RegClass;
964 RC = &AArch64::FPR64RegClass;
967 RC = &AArch64::FPR128RegClass;
970 RC = &AArch64::ZPRRegClass;
975 return printAsmRegInClass(MO, RC, AArch64::NoRegAltName, O);
988 if (AArch64::GPR32allRegClass.
contains(Reg) ||
989 AArch64::GPR64allRegClass.
contains(Reg))
993 if (AArch64::GPR64x8ClassRegClass.
contains(Reg))
996 unsigned AltName = AArch64::NoRegAltName;
998 if (AArch64::ZPRRegClass.
contains(Reg)) {
999 RegClass = &AArch64::ZPRRegClass;
1000 }
else if (AArch64::PPRRegClass.
contains(Reg)) {
1001 RegClass = &AArch64::PPRRegClass;
1002 }
else if (AArch64::PNRRegClass.
contains(Reg)) {
1003 RegClass = &AArch64::PNRRegClass;
1005 RegClass = &AArch64::FPR128RegClass;
1006 AltName = AArch64::vreg;
1010 return printAsmRegInClass(MO, RegClass, AltName, O);
1017bool AArch64AsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
1019 const char *ExtraCode,
1021 if (ExtraCode && ExtraCode[0] && ExtraCode[0] !=
'a')
1025 assert(MO.
isReg() &&
"unexpected inline asm memory operand");
1030void AArch64AsmPrinter::PrintDebugValueComment(
const MachineInstr *
MI,
1032 unsigned NOps =
MI->getNumOperands();
1034 OS <<
'\t' << MAI->getCommentString() <<
"DEBUG_VALUE: ";
1036 OS <<
MI->getDebugVariable()->getName();
1039 assert(
MI->isIndirectDebugValue());
1041 for (
unsigned I = 0, E = std::distance(
MI->debug_operands().begin(),
1042 MI->debug_operands().end());
1053void AArch64AsmPrinter::emitJumpTableInfo() {
1058 if (
JT.empty())
return;
1062 OutStreamer->switchSection(ReadOnlySec);
1065 for (
unsigned JTI = 0, e =
JT.size(); JTI !=
e; ++JTI) {
1066 const std::vector<MachineBasicBlock*> &JTBBs =
JT[JTI].MBBs;
1069 if (JTBBs.empty())
continue;
1071 unsigned Size = AFI->getJumpTableEntrySize(JTI);
1073 OutStreamer->emitLabel(GetJTISymbol(JTI));
1075 const MCSymbol *BaseSym = AArch64FI->getJumpTableEntryPCRelSymbol(JTI);
1078 for (
auto *JTBB : JTBBs) {
1098AArch64AsmPrinter::getCodeViewJumpTableInfo(
int JTI,
1100 const MCSymbol *BranchLabel)
const {
1102 const auto Base = AArch64FI->getJumpTableEntryPCRelSymbol(JTI);
1104 switch (AFI->getJumpTableEntrySize(JTI)) {
1106 EntrySize = codeview::JumpTableEntrySize::UInt8ShiftLeft;
1109 EntrySize = codeview::JumpTableEntrySize::UInt16ShiftLeft;
1112 EntrySize = codeview::JumpTableEntrySize::Int32;
1117 return std::make_tuple(
Base, 0, BranchLabel, EntrySize);
1120void AArch64AsmPrinter::emitFunctionEntryLabel() {
1122 MF->getFunction().getCallingConv() ==
1130 if (
TM.getTargetTriple().isWindowsArm64EC() &&
1131 !MF->getFunction().hasLocalLinkage()) {
1136 MF->getFunction().getMetadata(
"arm64ec_unmangled_name")) {
1140 MF->getFunction().getMetadata(
"arm64ec_ecmangled_name")) {
1142 cast<MDString>(Unmangled->getOperand(0))->getString();
1144 MMI->getContext().getOrCreateSymbol(UnmangledStr);
1146 cast<MDString>(ECMangled->getOperand(0))->getString();
1148 MMI->getContext().getOrCreateSymbol(ECMangledStr);
1150 OutStreamer->emitAssignment(
1153 MMI->getContext()));
1155 OutStreamer->emitAssignment(
1158 MMI->getContext()));
1162 cast<MDString>(Unmangled->getOperand(0))->getString();
1164 MMI->getContext().getOrCreateSymbol(UnmangledStr);
1166 OutStreamer->emitAssignment(
1169 MMI->getContext()));
1189 Register DestReg =
MI.getOperand(0).getReg();
1190 Register ScratchReg =
MI.getOperand(1).getReg();
1192 STI->getRegisterInfo()->getSubReg(ScratchReg, AArch64::sub_32);
1193 Register TableReg =
MI.getOperand(2).getReg();
1194 Register EntryReg =
MI.getOperand(3).getReg();
1195 int JTIdx =
MI.getOperand(4).getIndex();
1196 int Size = AArch64FI->getJumpTableEntrySize(JTIdx);
1206 Label = MF->getContext().createTempSymbol();
1207 AArch64FI->setJumpTableEntryInfo(JTIdx,
Size, Label);
1214 .addExpr(LabelExpr));
1219 case 1: LdrOpcode = AArch64::LDRBBroX;
break;
1220 case 2: LdrOpcode = AArch64::LDRHHroX;
break;
1221 case 4: LdrOpcode = AArch64::LDRSWroX;
break;
1227 .addReg(
Size == 4 ? ScratchReg : ScratchRegW)
1231 .addImm(
Size == 1 ? 0 : 1));
1239 .addImm(
Size == 4 ? 0 : 2));
1244 unsigned Opcode =
MI.getOpcode();
1246 assert(STI->hasMTE() || Opcode != AArch64::MOPSMemorySetTaggingPseudo);
1248 const auto Ops = [Opcode]() -> std::array<unsigned, 3> {
1249 if (Opcode == AArch64::MOPSMemoryCopyPseudo)
1250 return {AArch64::CPYFP, AArch64::CPYFM, AArch64::CPYFE};
1251 if (Opcode == AArch64::MOPSMemoryMovePseudo)
1252 return {AArch64::CPYP, AArch64::CPYM, AArch64::CPYE};
1253 if (Opcode == AArch64::MOPSMemorySetPseudo)
1254 return {AArch64::SETP, AArch64::SETM, AArch64::SETE};
1255 if (Opcode == AArch64::MOPSMemorySetTaggingPseudo)
1256 return {AArch64::SETGP, AArch64::SETGM, AArch64::MOPSSETGE};
1259 const bool IsSet = Opcode == AArch64::MOPSMemorySetPseudo ||
1260 Opcode == AArch64::MOPSMemorySetTaggingPseudo;
1262 for (
auto Op : Ops) {
1266 MCIB.addReg(
MI.getOperand(i++).getReg());
1267 MCIB.addReg(
MI.getOperand(i++).getReg());
1269 MCIB.addReg(
MI.getOperand(i++).getReg());
1271 MCIB.addReg(
MI.getOperand(i++).getReg());
1272 MCIB.addReg(
MI.getOperand(i++).getReg());
1273 MCIB.addReg(
MI.getOperand(i++).getReg());
1275 EmitToStreamer(OutStreamer, MCIB);
1284 MCSymbol *MILabel = Ctx.createTempSymbol();
1288 assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
1294 while (NumNOPBytes > 0) {
1295 if (MII ==
MBB.
end() || MII->isCall() ||
1296 MII->getOpcode() == AArch64::DBG_VALUE ||
1297 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
1298 MII->getOpcode() == TargetOpcode::STACKMAP)
1305 for (
unsigned i = 0; i < NumNOPBytes; i += 4)
1306 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1314 MCSymbol *MILabel = Ctx.createTempSymbol();
1320 int64_t CallTarget = Opers.getCallTarget().getImm();
1321 unsigned EncodedBytes = 0;
1323 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
1324 "High 16 bits of call target should be zero.");
1325 Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
1330 .addImm((CallTarget >> 32) & 0xFFFF)
1335 .addImm((CallTarget >> 16) & 0xFFFF)
1340 .addImm(CallTarget & 0xFFFF)
1342 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::BLR).addReg(ScratchReg));
1345 unsigned NumBytes = Opers.getNumPatchBytes();
1346 assert(NumBytes >= EncodedBytes &&
1347 "Patchpoint can't request size less than the length of a call.");
1348 assert((NumBytes - EncodedBytes) % 4 == 0 &&
1349 "Invalid number of NOP bytes requested!");
1350 for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
1351 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1357 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
1358 assert(PatchBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
1359 for (
unsigned i = 0; i < PatchBytes; i += 4)
1360 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1365 unsigned CallOpcode;
1366 switch (CallTarget.
getType()) {
1369 MCInstLowering.lowerOperand(CallTarget, CallTargetMCOp);
1370 CallOpcode = AArch64::BL;
1374 CallOpcode = AArch64::BL;
1378 CallOpcode = AArch64::BLR;
1385 EmitToStreamer(OutStreamer,
1390 MCSymbol *MILabel = Ctx.createTempSymbol();
1395void AArch64AsmPrinter::LowerFAULTING_OP(
const MachineInstr &FaultingMI) {
1404 unsigned OperandsBeginIdx = 4;
1407 MCSymbol *FaultingLabel = Ctx.createTempSymbol();
1411 FM.recordFaultingOp(FK, FaultingLabel, HandlerLabel);
1414 MI.setOpcode(Opcode);
1422 lowerOperand(MO, Dest);
1423 MI.addOperand(Dest);
1431 Register DestReg =
MI.getOperand(0).getReg();
1432 if (STI->hasZeroCycleZeroingFP() && !STI->hasZeroCycleZeroingFPWorkaround() &&
1433 STI->isNeonAvailable()) {
1435 if (AArch64::H0 <= DestReg && DestReg <= AArch64::H31)
1436 DestReg = AArch64::D0 + (DestReg - AArch64::H0);
1437 else if (AArch64::S0 <= DestReg && DestReg <= AArch64::S31)
1438 DestReg = AArch64::D0 + (DestReg - AArch64::S0);
1440 assert(AArch64::D0 <= DestReg && DestReg <= AArch64::D31);
1443 MOVI.setOpcode(AArch64::MOVID);
1446 EmitToStreamer(*OutStreamer, MOVI);
1449 switch (
MI.getOpcode()) {
1451 case AArch64::FMOVH0:
1452 FMov.
setOpcode(STI->hasFullFP16() ? AArch64::FMOVWHr : AArch64::FMOVWSr);
1453 if (!STI->hasFullFP16())
1454 DestReg = (AArch64::S0 + (DestReg - AArch64::H0));
1458 case AArch64::FMOVS0:
1463 case AArch64::FMOVD0:
1469 EmitToStreamer(*OutStreamer, FMov);
1475#include "AArch64GenMCPseudoLowering.inc"
1478 AArch64_MC::verifyInstructionPredicates(
MI->getOpcode(), STI->getFeatureBits());
1481 if (emitPseudoExpansionLowering(*OutStreamer,
MI))
1484 if (
MI->getOpcode() == AArch64::ADRP) {
1485 for (
auto &Opd :
MI->operands()) {
1486 if (Opd.isSymbol() &&
StringRef(Opd.getSymbolName()) ==
1487 "swift_async_extendedFramePointerFlags") {
1488 ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags =
true;
1493 if (AArch64FI->getLOHRelated().count(
MI)) {
1495 MCSymbol *LOHLabel = createTempSymbol(
"loh");
1497 LOHInstToLabel[
MI] = LOHLabel;
1504 switch (
MI->getOpcode()) {
1507 case AArch64::HINT: {
1512 if (CurrentPatchableFunctionEntrySym &&
1513 CurrentPatchableFunctionEntrySym == CurrentFnBegin &&
1514 MI == &MF->front().front()) {
1515 int64_t
Imm =
MI->getOperand(0).getImm();
1516 if ((Imm & 32) && (
Imm & 6)) {
1518 MCInstLowering.Lower(
MI, Inst);
1519 EmitToStreamer(*OutStreamer, Inst);
1520 CurrentPatchableFunctionEntrySym = createTempSymbol(
"patch");
1521 OutStreamer->
emitLabel(CurrentPatchableFunctionEntrySym);
1527 case AArch64::MOVMCSym: {
1528 Register DestReg =
MI->getOperand(0).getReg();
1536 MCInstLowering.lowerOperand(Hi_MOSym, Hi_MCSym);
1537 MCInstLowering.lowerOperand(Lo_MOSym, Lo_MCSym);
1544 EmitToStreamer(*OutStreamer, MovZ);
1552 EmitToStreamer(*OutStreamer, MovK);
1555 case AArch64::MOVIv2d_ns:
1563 if (STI->hasZeroCycleZeroingFPWorkaround() &&
1564 MI->getOperand(1).getImm() == 0) {
1566 TmpInst.
setOpcode(AArch64::MOVIv16b_ns);
1569 EmitToStreamer(*OutStreamer, TmpInst);
1574 case AArch64::DBG_VALUE:
1575 case AArch64::DBG_VALUE_LIST:
1579 PrintDebugValueComment(
MI,
OS);
1584 case AArch64::EMITBKEY: {
1586 if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
1587 ExceptionHandlingType != ExceptionHandling::ARM)
1590 if (getFunctionCFISectionType(*MF) == CFISection::None)
1597 case AArch64::EMITMTETAGGED: {
1599 if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
1600 ExceptionHandlingType != ExceptionHandling::ARM)
1603 if (getFunctionCFISectionType(*MF) != CFISection::None)
1611 case AArch64::TCRETURNri:
1612 case AArch64::TCRETURNrix16x17:
1613 case AArch64::TCRETURNrix17:
1614 case AArch64::TCRETURNrinotx16:
1615 case AArch64::TCRETURNriALL: {
1619 EmitToStreamer(*OutStreamer, TmpInst);
1622 case AArch64::TCRETURNdi: {
1624 MCInstLowering.lowerOperand(
MI->getOperand(0), Dest);
1628 EmitToStreamer(*OutStreamer, TmpInst);
1631 case AArch64::SpeculationBarrierISBDSBEndBB: {
1636 EmitToStreamer(*OutStreamer, TmpInstDSB);
1640 EmitToStreamer(*OutStreamer, TmpInstISB);
1643 case AArch64::SpeculationBarrierSBEndBB: {
1647 EmitToStreamer(*OutStreamer, TmpInstSB);
1650 case AArch64::TLSDESC_CALLSEQ: {
1663 MCInstLowering.lowerOperand(MO_Sym,
Sym);
1664 MCInstLowering.lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
1665 MCInstLowering.lowerOperand(MO_TLSDESC, SymTLSDesc);
1671 EmitToStreamer(*OutStreamer, Adrp);
1674 if (STI->isTargetILP32()) {
1684 EmitToStreamer(*OutStreamer, Ldr);
1687 if (STI->isTargetILP32()) {
1688 Add.setOpcode(AArch64::ADDWri);
1692 Add.setOpcode(AArch64::ADDXri);
1696 Add.addOperand(SymTLSDescLo12);
1698 EmitToStreamer(*OutStreamer,
Add);
1703 TLSDescCall.
setOpcode(AArch64::TLSDESCCALL);
1705 EmitToStreamer(*OutStreamer, TLSDescCall);
1710 EmitToStreamer(*OutStreamer, Blr);
1715 case AArch64::JumpTableDest32:
1716 case AArch64::JumpTableDest16:
1717 case AArch64::JumpTableDest8:
1718 LowerJumpTableDest(*OutStreamer, *
MI);
1721 case AArch64::FMOVH0:
1722 case AArch64::FMOVS0:
1723 case AArch64::FMOVD0:
1727 case AArch64::MOPSMemoryCopyPseudo:
1728 case AArch64::MOPSMemoryMovePseudo:
1729 case AArch64::MOPSMemorySetPseudo:
1730 case AArch64::MOPSMemorySetTaggingPseudo:
1731 LowerMOPS(*OutStreamer, *
MI);
1734 case TargetOpcode::STACKMAP:
1735 return LowerSTACKMAP(*OutStreamer, SM, *
MI);
1737 case TargetOpcode::PATCHPOINT:
1738 return LowerPATCHPOINT(*OutStreamer, SM, *
MI);
1740 case TargetOpcode::STATEPOINT:
1741 return LowerSTATEPOINT(*OutStreamer, SM, *
MI);
1743 case TargetOpcode::FAULTING_OP:
1744 return LowerFAULTING_OP(*
MI);
1746 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
1747 LowerPATCHABLE_FUNCTION_ENTER(*
MI);
1750 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1751 LowerPATCHABLE_FUNCTION_EXIT(*
MI);
1754 case TargetOpcode::PATCHABLE_TAIL_CALL:
1755 LowerPATCHABLE_TAIL_CALL(*
MI);
1757 case TargetOpcode::PATCHABLE_EVENT_CALL:
1758 return LowerPATCHABLE_EVENT_CALL(*
MI,
false);
1759 case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
1760 return LowerPATCHABLE_EVENT_CALL(*
MI,
true);
1762 case AArch64::KCFI_CHECK:
1763 LowerKCFI_CHECK(*
MI);
1766 case AArch64::HWASAN_CHECK_MEMACCESS:
1767 case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
1768 LowerHWASAN_CHECK_MEMACCESS(*
MI);
1771 case AArch64::SEH_StackAlloc:
1775 case AArch64::SEH_SaveFPLR:
1779 case AArch64::SEH_SaveFPLR_X:
1780 assert(
MI->getOperand(0).getImm() < 0 &&
1781 "Pre increment SEH opcode must have a negative offset");
1785 case AArch64::SEH_SaveReg:
1787 MI->getOperand(1).getImm());
1790 case AArch64::SEH_SaveReg_X:
1791 assert(
MI->getOperand(1).getImm() < 0 &&
1792 "Pre increment SEH opcode must have a negative offset");
1794 -
MI->getOperand(1).getImm());
1797 case AArch64::SEH_SaveRegP:
1798 if (
MI->getOperand(1).getImm() == 30 &&
MI->getOperand(0).getImm() >= 19 &&
1799 MI->getOperand(0).getImm() <= 28) {
1800 assert((
MI->getOperand(0).getImm() - 19) % 2 == 0 &&
1801 "Register paired with LR must be odd");
1803 MI->getOperand(2).getImm());
1806 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1807 "Non-consecutive registers not allowed for save_regp");
1809 MI->getOperand(2).getImm());
1812 case AArch64::SEH_SaveRegP_X:
1813 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1814 "Non-consecutive registers not allowed for save_regp_x");
1815 assert(
MI->getOperand(2).getImm() < 0 &&
1816 "Pre increment SEH opcode must have a negative offset");
1818 -
MI->getOperand(2).getImm());
1821 case AArch64::SEH_SaveFReg:
1823 MI->getOperand(1).getImm());
1826 case AArch64::SEH_SaveFReg_X:
1827 assert(
MI->getOperand(1).getImm() < 0 &&
1828 "Pre increment SEH opcode must have a negative offset");
1830 -
MI->getOperand(1).getImm());
1833 case AArch64::SEH_SaveFRegP:
1834 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1835 "Non-consecutive registers not allowed for save_regp");
1837 MI->getOperand(2).getImm());
1840 case AArch64::SEH_SaveFRegP_X:
1841 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1842 "Non-consecutive registers not allowed for save_regp_x");
1843 assert(
MI->getOperand(2).getImm() < 0 &&
1844 "Pre increment SEH opcode must have a negative offset");
1846 -
MI->getOperand(2).getImm());
1849 case AArch64::SEH_SetFP:
1853 case AArch64::SEH_AddFP:
1857 case AArch64::SEH_Nop:
1861 case AArch64::SEH_PrologEnd:
1865 case AArch64::SEH_EpilogStart:
1869 case AArch64::SEH_EpilogEnd:
1873 case AArch64::SEH_PACSignLR:
1877 case AArch64::SEH_SaveAnyRegQP:
1878 assert(
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1 &&
1879 "Non-consecutive registers not allowed for save_any_reg");
1880 assert(
MI->getOperand(2).getImm() >= 0 &&
1881 "SaveAnyRegQP SEH opcode offset must be non-negative");
1882 assert(
MI->getOperand(2).getImm() <= 1008 &&
1883 "SaveAnyRegQP SEH opcode offset must fit into 6 bits");
1885 MI->getOperand(2).getImm());
1888 case AArch64::SEH_SaveAnyRegQPX:
1889 assert(
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1 &&
1890 "Non-consecutive registers not allowed for save_any_reg");
1891 assert(
MI->getOperand(2).getImm() < 0 &&
1892 "SaveAnyRegQPX SEH opcode offset must be negative");
1893 assert(
MI->getOperand(2).getImm() >= -1008 &&
1894 "SaveAnyRegQPX SEH opcode offset must fit into 6 bits");
1896 -
MI->getOperand(2).getImm());
1902 MCInstLowering.Lower(
MI, TmpInst);
1903 EmitToStreamer(*OutStreamer, TmpInst);
1919 MCInstLowering.lowerOperand(
1933 MCInstLowering.lowerOperand(
1943 .addReg(AArch64::X16)
1944 .addReg(AArch64::X16)
1955void AArch64AsmPrinter::emitMachOIFuncStubHelperBody(
Module &M,
1990 .addReg(AArch64::SP)
1991 .addReg(AArch64::FP)
1992 .addReg(AArch64::LR)
1993 .addReg(AArch64::SP)
1998 .addReg(AArch64::FP)
1999 .addReg(AArch64::SP)
2004 for (
int I = 0;
I != 4; ++
I)
2006 .addReg(AArch64::SP)
2007 .addReg(AArch64::X1 + 2 *
I)
2008 .addReg(AArch64::X0 + 2 *
I)
2009 .addReg(AArch64::SP)
2013 for (
int I = 0;
I != 4; ++
I)
2015 .addReg(AArch64::SP)
2016 .addReg(AArch64::D1 + 2 *
I)
2017 .addReg(AArch64::D0 + 2 *
I)
2018 .addReg(AArch64::SP)
2032 MCInstLowering.lowerOperand(
2046 MCInstLowering.lowerOperand(
2056 .addReg(AArch64::X0)
2057 .addReg(AArch64::X16)
2062 .addReg(AArch64::X16)
2063 .addReg(AArch64::X0)
2068 for (
int I = 3;
I != -1; --
I)
2070 .addReg(AArch64::SP)
2071 .addReg(AArch64::D1 + 2 *
I)
2072 .addReg(AArch64::D0 + 2 *
I)
2073 .addReg(AArch64::SP)
2077 for (
int I = 3;
I != -1; --
I)
2079 .addReg(AArch64::SP)
2080 .addReg(AArch64::X1 + 2 *
I)
2081 .addReg(AArch64::X0 + 2 *
I)
2082 .addReg(AArch64::SP)
2087 .addReg(AArch64::SP)
2088 .addReg(AArch64::FP)
2089 .addReg(AArch64::LR)
2090 .addReg(AArch64::SP)
2101const MCExpr *AArch64AsmPrinter::lowerConstant(
const Constant *CV) {
2102 if (
const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) {
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmPrinter()
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define LLVM_EXTERNAL_VISIBILITY
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const char LLVMTargetMachineRef TM
static SDValue lowerConstant(SDValue Op, SelectionDAG &DAG, const RISCVSubtarget &Subtarget)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
This file defines the SmallString class.
This file defines the SmallVector class.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static bool printAsmMRegister(const X86AsmPrinter &P, const MachineOperand &MO, char Mode, raw_ostream &O)
AArch64FunctionInfo - This class is derived from MachineFunctionInfo and contains private AArch64-spe...
std::optional< std::string > getOutliningStyle() const
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=AArch64::NoRegAltName)
static const AArch64MCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
AArch64MCInstLower - This class is used to lower an MachineInstr into an MCInst.
bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const
virtual void emitARM64WinCFISaveRegP(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveRegPX(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveAnyRegQP(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveFReg(unsigned Reg, int Offset)
virtual void emitARM64WinCFIPACSignLR()
virtual void emitARM64WinCFISaveFRegPX(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveRegX(unsigned Reg, int Offset)
virtual void emitARM64WinCFIAllocStack(unsigned Size)
virtual void emitARM64WinCFISaveFPLRX(int Offset)
virtual void emitDirectiveVariantPCS(MCSymbol *Symbol)
Callback used to implement the .variant_pcs directive.
virtual void emitARM64WinCFIAddFP(unsigned Size)
virtual void emitARM64WinCFISaveFPLR(int Offset)
virtual void emitARM64WinCFISaveFRegP(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset)
virtual void emitARM64WinCFISaveFRegX(unsigned Reg, int Offset)
virtual void emitARM64WinCFISetFP()
virtual void emitARM64WinCFIEpilogEnd()
virtual void emitARM64WinCFIPrologEnd()
void emitNoteSection(unsigned Flags, uint64_t PAuthABIPlatform=-1, uint64_t PAuthABIVersion=-1)
Callback used to implement the .note.gnu.property section.
virtual void emitARM64WinCFISaveReg(unsigned Reg, int Offset)
virtual void emitARM64WinCFINop()
virtual void emitARM64WinCFISaveLRPair(unsigned Reg, int Offset)
virtual void emitARM64WinCFIEpilogStart()
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
This class is intended to be used as a driving class for all asm writers.
virtual void emitInstruction(const MachineInstr *)
Targets should implement this to emit instructions.
void emitXRayTable()
Emit a table with all XRay instrumentation points.
virtual MCSymbol * GetCPISymbol(unsigned CPID) const
Return the symbol for the specified constant pool entry.
virtual void emitMachOIFuncStubHelperBody(Module &M, const GlobalIFunc &GI, MCSymbol *LazyPointer)
virtual void emitJumpTableInfo()
Print assembly representations of the jump tables used by the current function to the current output ...
virtual void SetupMachineFunction(MachineFunction &MF)
This should be called when a new MachineFunction is being processed from runOnMachineFunction.
void emitFunctionBody()
This method emits the body and trailer for a function.
virtual void emitStartOfAsmFile(Module &)
This virtual method can be overridden by targets that want to emit something at the start of their fi...
virtual void emitEndOfAsmFile(Module &)
This virtual method can be overridden by targets that want to emit something at the end of their file...
virtual void emitMachOIFuncStubBody(Module &M, const GlobalIFunc &GI, MCSymbol *LazyPointer)
void getAnalysisUsage(AnalysisUsage &AU) const override
Record analysis usage.
virtual bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags() const
virtual const MCSubtargetInfo * getIFuncMCSubtargetInfo() const
getSubtargetInfo() cannot be used where this is needed because we don't have a MachineFunction when w...
bool runOnMachineFunction(MachineFunction &MF) override
Emit the specified function out to the OutStreamer.
virtual const MCExpr * lowerConstant(const Constant *CV)
Lower the specified LLVM Constant to an MCExpr.
virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
virtual void emitFunctionBodyEnd()
Targets can override this to emit stuff after the last basic block in the function.
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
virtual std::tuple< const MCSymbol *, uint64_t, const MCSymbol *, codeview::JumpTableEntrySize > getCodeViewJumpTableInfo(int JTI, const MachineInstr *BranchInstr, const MCSymbol *BranchLabel) const
Gets information required to create a CodeView debug symbol for a jump table.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
This is an important base class in LLVM.
This class represents an Operation in the Expression.
const Constant * getResolver() const
bool hasLocalLinkage() const
static const MCBinaryExpr * createLShr(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
MCInstBuilder & addExpr(const MCExpr *Val)
Add a new MCExpr operand.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
Instances of this class represent operands of the MCInst class.
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
uint16_t getEncodingValue(MCRegister RegNo) const
Returns the encoding for RegNo.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Streaming machine code generation interface.
virtual void emitCFIBKeyFrame()
virtual void beginCOFFSymbolDef(const MCSymbol *Symbol)
Start emitting COFF symbol definition.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitCOFFSymbolType(int Type)
Emit the type of the symbol.
virtual bool hasRawTextSupport() const
Return true if this asm streamer supports emitting unformatted text to the .s file with EmitRawText.
virtual void endCOFFSymbolDef()
Marks the end of the symbol definition.
MCContext & getContext() const
virtual void AddComment(const Twine &T, bool EOL=true)
Add a textual comment.
virtual void emitCFIMTETaggedFrame()
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
void emitRawText(const Twine &String)
If this file is backed by a assembly streamer, this dumps the specified string in the output ....
virtual void emitCOFFSymbolStorageClass(int StorageClass)
Emit the storage class of the symbol.
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
StringRef getName() const
getName - Get the symbol name.
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Representation of each machine instruction.
iterator_range< mop_iterator > operands()
const MachineOperand & getOperand(unsigned i) const
const std::vector< MachineJumpTableEntry > & getJumpTables() const
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
static MachineOperand CreateMCSymbol(MCSymbol *Sym, unsigned TargetFlags=0)
static MachineOperand CreateES(const char *SymName, unsigned TargetFlags=0)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
const BlockAddress * getBlockAddress() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
A Module instance is used to store all the information related to an LLVM module.
Pass interface - Implemented by all 'passes'.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
MI-level patchpoint operands.
Wrapper class representing virtual and physical registers.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MI-level stackmap operands.
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given stackmap should emit.
void recordStatepoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a statepoint instruction.
void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
void recordStackMap(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
MI-level Statepoint operands.
StringRef - Represent a constant reference to a string, i.e.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
virtual MCSection * getSectionForJumpTable(const Function &F, const TargetMachine &TM) const
Primary interface to the complete machine description for the target machine.
MCRegister getRegister(unsigned i) const
Return the specified register in the class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool regsOverlap(Register RegA, Register RegB) const
Returns true if the two registers are equal or alias each other.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ MO_NC
MO_NC - Indicates whether the linker is expected to check the symbol reference for overflow.
@ MO_G1
MO_G1 - A symbol operand with this flag (granule 1) represents the bits 16-31 of a 64-bit address,...
@ MO_S
MO_S - Indicates that the bits of the symbol operand represented by MO_G0 etc are signed.
@ MO_PAGEOFF
MO_PAGEOFF - A symbol operand with this flag represents the offset of that symbol within a 4K page.
@ MO_GOT
MO_GOT - This flag indicates that a symbol operand represents the address of the GOT entry for the sy...
@ MO_G0
MO_G0 - A symbol operand with this flag (granule 0) represents the bits 0-15 of a 64-bit address,...
@ MO_PAGE
MO_PAGE - A symbol operand with this flag represents the pc-relative offset of the 4K page containing...
@ MO_TLS
MO_TLS - Indicates that the operand being accessed is some kind of thread-local symbol.
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
SymbolStorageClass
Storage class tells where and what the symbol represents.
@ IMAGE_SYM_CLASS_EXTERNAL
External symbol.
@ IMAGE_SYM_CLASS_STATIC
Static.
@ IMAGE_SYM_DTYPE_NULL
No complex type; simple scalar variable.
@ IMAGE_SYM_DTYPE_FUNCTION
A function that returns a base type.
@ SCT_COMPLEX_TYPE_SHIFT
Type is formed as (base + (derived << SCT_COMPLEX_TYPE_SHIFT))
@ AArch64_VectorCall
Used between AArch64 Advanced SIMD functions.
@ AArch64_SVE_VectorCall
Used between AArch64 SVE functions.
@ GNU_PROPERTY_AARCH64_FEATURE_1_BTI
@ GNU_PROPERTY_AARCH64_FEATURE_1_PAC
@ GNU_PROPERTY_AARCH64_FEATURE_1_GCS
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Target & getTheAArch64beTarget()
Target & getTheAArch64leTarget()
static unsigned getXRegFromWReg(unsigned Reg)
static unsigned getXRegFromXRegTuple(unsigned RegTuple)
Target & getTheAArch64_32Target()
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Target & getTheARM64_32Target()
@ MCAF_SubsectionsViaSymbols
.subsections_via_symbols (MachO)
static unsigned getWRegFromXReg(unsigned Reg)
Target & getTheARM64Target()
@ MCSA_Global
.type _foo, @gnu_unique_object
@ MCSA_WeakAntiDep
.weak_anti_dep (COFF)
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
@ MCSA_Hidden
.hidden (ELF)
This struct is a compact representation of a valid (non-zero power of two) alignment.
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...