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())
280void AArch64AsmPrinter::emitFunctionHeaderComment() {
283 if (OutlinerString != std::nullopt)
284 OutStreamer->getCommentOS() <<
' ' << OutlinerString;
287void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr &
MI)
290 if (
F.hasFnAttribute(
"patchable-function-entry")) {
292 if (
F.getFnAttribute(
"patchable-function-entry")
294 .getAsInteger(10, Num))
300 emitSled(
MI, SledKind::FUNCTION_ENTER);
303void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr &
MI) {
304 emitSled(
MI, SledKind::FUNCTION_EXIT);
307void AArch64AsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr &
MI) {
308 emitSled(
MI, SledKind::TAIL_CALL);
311void AArch64AsmPrinter::emitSled(
const MachineInstr &
MI, SledKind Kind) {
312 static const int8_t NoopsInSledCount = 7;
333 OutStreamer->emitCodeAlignment(
Align(4), &getSubtargetInfo());
334 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
335 OutStreamer->emitLabel(CurSled);
336 auto Target = OutContext.createTempSymbol();
341 EmitToStreamer(*OutStreamer,
MCInstBuilder(AArch64::B).addImm(8));
343 for (int8_t
I = 0;
I < NoopsInSledCount;
I++)
344 EmitToStreamer(*OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
346 OutStreamer->emitLabel(
Target);
347 recordSled(CurSled,
MI, Kind, 2);
365void AArch64AsmPrinter::LowerPATCHABLE_EVENT_CALL(
const MachineInstr &
MI,
367 auto &
O = *OutStreamer;
368 MCSymbol *CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
369 O.emitLabel(CurSled);
380 bool MachO =
TM.getTargetTriple().isOSBinFormatMachO();
382 OutContext.getOrCreateSymbol(
383 Twine(MachO ?
"_" :
"") +
384 (Typed ?
"__xray_TypedEvent" :
"__xray_CustomEvent")),
387 O.AddComment(
"Begin XRay typed event");
399 EmitToStreamer(O, MovX0Op0);
400 EmitToStreamer(O, MovX1Op1);
403 .addReg(AArch64::XZR)
404 .addReg(
MI.getOperand(2).getReg())
411 O.AddComment(
"End XRay typed event");
419 recordSled(CurSled,
MI, SledKind::TYPED_EVENT, 2);
421 O.AddComment(
"Begin XRay custom event");
429 EmitToStreamer(O, MovX0Op0);
430 EmitToStreamer(O, MovX1Op1);
432 O.AddComment(
"End XRay custom event");
440 recordSled(CurSled,
MI, SledKind::CUSTOM_EVENT, 2);
446 assert(std::next(
MI.getIterator())->isCall() &&
447 "KCFI_CHECK not followed by a call instruction");
448 assert(std::next(
MI.getIterator())->getOperand(0).getReg() == AddrReg &&
449 "KCFI_CHECK call target doesn't match call operand");
453 unsigned ScratchRegs[] = {AArch64::W16, AArch64::W17};
454 if (AddrReg == AArch64::XZR) {
460 .addReg(AArch64::XZR)
461 .addReg(AArch64::XZR)
468 for (
auto &Reg : ScratchRegs) {
474 assert(ScratchRegs[0] != AddrReg && ScratchRegs[1] != AddrReg &&
475 "Invalid scratch registers for KCFI_CHECK");
479 int64_t PrefixNops = 0;
482 .getFnAttribute(
"patchable-function-prefix")
484 .getAsInteger(10, PrefixNops);
488 .addReg(ScratchRegs[0])
490 .addImm(-(PrefixNops * 4 + 4)));
494 const int64_t
Type =
MI.getOperand(1).getImm();
496 .addReg(ScratchRegs[1])
497 .addReg(ScratchRegs[1])
498 .addImm(
Type & 0xFFFF)
501 .addReg(ScratchRegs[1])
502 .addReg(ScratchRegs[1])
503 .addImm((
Type >> 16) & 0xFFFF)
508 .addReg(AArch64::WZR)
509 .addReg(ScratchRegs[0])
510 .addReg(ScratchRegs[1])
514 EmitToStreamer(*OutStreamer,
524 unsigned TypeIndex = ScratchRegs[1] - AArch64::W0;
528 AddrIndex = AddrReg - AArch64::X0;
538 assert(AddrIndex < 31 && TypeIndex < 31);
540 unsigned ESR = 0x8000 | ((TypeIndex & 31) << 5) | (AddrIndex & 31);
541 EmitToStreamer(*OutStreamer,
MCInstBuilder(AArch64::BRK).addImm(ESR));
542 OutStreamer->emitLabel(
Pass);
545void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
548 MI.getOpcode() == AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES;
549 uint32_t AccessInfo =
MI.getOperand(1).getImm();
551 HwasanMemaccessSymbols[HwasanMemaccessTuple(Reg, IsShort, AccessInfo)];
554 if (!
TM.getTargetTriple().isOSBinFormatELF())
557 std::string SymName =
"__hwasan_check_x" + utostr(Reg - AArch64::X0) +
"_" +
560 SymName +=
"_short_v2";
561 Sym = OutContext.getOrCreateSymbol(SymName);
564 EmitToStreamer(*OutStreamer,
569void AArch64AsmPrinter::emitHwasanMemaccessSymbols(
Module &M) {
570 if (HwasanMemaccessSymbols.empty())
575 std::unique_ptr<MCSubtargetInfo> STI(
576 TM.getTarget().createMCSubtargetInfo(
TT.str(),
"",
""));
577 assert(STI &&
"Unable to create subtarget info");
580 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch");
582 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
589 for (
auto &
P : HwasanMemaccessSymbols) {
590 unsigned Reg = std::get<0>(
P.first);
591 bool IsShort = std::get<1>(
P.first);
592 uint32_t AccessInfo = std::get<2>(
P.first);
594 IsShort ? HwasanTagMismatchV2Ref : HwasanTagMismatchV1Ref;
597 bool HasMatchAllTag =
599 uint8_t MatchAllTag =
606 OutStreamer->switchSection(OutContext.getELFSection(
614 OutStreamer->emitLabel(
Sym);
622 OutStreamer->emitInstruction(
625 .
addReg(IsShort ? AArch64::X20 : AArch64::X9)
630 OutStreamer->emitInstruction(
637 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
638 OutStreamer->emitInstruction(
644 MCSymbol *ReturnSym = OutContext.createTempSymbol();
645 OutStreamer->emitLabel(ReturnSym);
646 OutStreamer->emitInstruction(
648 OutStreamer->emitLabel(HandleMismatchOrPartialSym);
650 if (HasMatchAllTag) {
663 OutStreamer->emitInstruction(
677 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
678 OutStreamer->emitInstruction(
684 OutStreamer->emitInstruction(
703 OutStreamer->emitInstruction(
709 OutStreamer->emitInstruction(
720 OutStreamer->emitInstruction(
727 OutStreamer->emitInstruction(
733 OutStreamer->emitLabel(HandleMismatchSym);
750 if (Reg != AArch64::X0)
757 OutStreamer->emitInstruction(
768 OutStreamer->emitInstruction(
774 OutStreamer->emitInstruction(
778 HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_PAGE,
781 OutStreamer->emitInstruction(
786 HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_LO12,
789 OutStreamer->emitInstruction(
795void AArch64AsmPrinter::emitEndOfAsmFile(
Module &M) {
796 emitHwasanMemaccessSymbols(M);
799 if (
TT.isOSBinFormatMachO()) {
809 FM.serializeToFaultMapSection();
813void AArch64AsmPrinter::emitLOHs() {
816 for (
const auto &
D : AArch64FI->getLOHContainer()) {
818 MInstToMCSymbol::iterator LabelIt = LOHInstToLabel.find(
MI);
819 assert(LabelIt != LOHInstToLabel.end() &&
820 "Label hasn't been inserted for LOH related instruction");
823 OutStreamer->emitLOHDirective(
D.getKind(), MCArgs);
828void AArch64AsmPrinter::emitFunctionBodyEnd() {
829 if (!AArch64FI->getLOHRelated().empty())
834MCSymbol *AArch64AsmPrinter::GetCPISymbol(
unsigned CPID)
const {
838 if (!getDataLayout().getLinkerPrivateGlobalPrefix().empty())
839 return OutContext.getOrCreateSymbol(
840 Twine(getDataLayout().getLinkerPrivateGlobalPrefix()) +
"CPI" +
841 Twine(getFunctionNumber()) +
"_" +
Twine(CPID));
846void AArch64AsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNum,
864 PrintSymbolOperand(MO, O);
875bool AArch64AsmPrinter::printAsmMRegister(
const MachineOperand &MO,
char Mode,
899bool AArch64AsmPrinter::printAsmRegInClass(
const MachineOperand &MO,
902 assert(MO.
isReg() &&
"Should only get here with a register!");
912bool AArch64AsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNum,
921 if (ExtraCode && ExtraCode[0]) {
922 if (ExtraCode[1] != 0)
925 switch (ExtraCode[0]) {
933 unsigned Reg = ExtraCode[0] ==
'w' ? AArch64::WZR : AArch64::XZR;
947 switch (ExtraCode[0]) {
949 RC = &AArch64::FPR8RegClass;
952 RC = &AArch64::FPR16RegClass;
955 RC = &AArch64::FPR32RegClass;
958 RC = &AArch64::FPR64RegClass;
961 RC = &AArch64::FPR128RegClass;
964 RC = &AArch64::ZPRRegClass;
969 return printAsmRegInClass(MO, RC, AArch64::NoRegAltName, O);
982 if (AArch64::GPR32allRegClass.
contains(Reg) ||
983 AArch64::GPR64allRegClass.
contains(Reg))
987 if (AArch64::GPR64x8ClassRegClass.
contains(Reg))
990 unsigned AltName = AArch64::NoRegAltName;
992 if (AArch64::ZPRRegClass.
contains(Reg)) {
993 RegClass = &AArch64::ZPRRegClass;
994 }
else if (AArch64::PPRRegClass.
contains(Reg)) {
995 RegClass = &AArch64::PPRRegClass;
996 }
else if (AArch64::PNRRegClass.
contains(Reg)) {
997 RegClass = &AArch64::PNRRegClass;
999 RegClass = &AArch64::FPR128RegClass;
1000 AltName = AArch64::vreg;
1004 return printAsmRegInClass(MO, RegClass, AltName, O);
1011bool AArch64AsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
1013 const char *ExtraCode,
1015 if (ExtraCode && ExtraCode[0] && ExtraCode[0] !=
'a')
1019 assert(MO.
isReg() &&
"unexpected inline asm memory operand");
1024void AArch64AsmPrinter::PrintDebugValueComment(
const MachineInstr *
MI,
1026 unsigned NOps =
MI->getNumOperands();
1028 OS <<
'\t' << MAI->getCommentString() <<
"DEBUG_VALUE: ";
1030 OS <<
MI->getDebugVariable()->getName();
1033 assert(
MI->isIndirectDebugValue());
1035 for (
unsigned I = 0, E = std::distance(
MI->debug_operands().begin(),
1036 MI->debug_operands().end());
1047void AArch64AsmPrinter::emitJumpTableInfo() {
1052 if (
JT.empty())
return;
1056 OutStreamer->switchSection(ReadOnlySec);
1059 for (
unsigned JTI = 0, e =
JT.size(); JTI !=
e; ++JTI) {
1060 const std::vector<MachineBasicBlock*> &JTBBs =
JT[JTI].MBBs;
1063 if (JTBBs.empty())
continue;
1065 unsigned Size = AFI->getJumpTableEntrySize(JTI);
1067 OutStreamer->emitLabel(GetJTISymbol(JTI));
1069 const MCSymbol *BaseSym = AArch64FI->getJumpTableEntryPCRelSymbol(JTI);
1072 for (
auto *JTBB : JTBBs) {
1092AArch64AsmPrinter::getCodeViewJumpTableInfo(
int JTI,
1094 const MCSymbol *BranchLabel)
const {
1096 const auto Base = AArch64FI->getJumpTableEntryPCRelSymbol(JTI);
1098 switch (AFI->getJumpTableEntrySize(JTI)) {
1100 EntrySize = codeview::JumpTableEntrySize::UInt8ShiftLeft;
1103 EntrySize = codeview::JumpTableEntrySize::UInt16ShiftLeft;
1106 EntrySize = codeview::JumpTableEntrySize::Int32;
1111 return std::make_tuple(
Base, 0, BranchLabel, EntrySize);
1114void AArch64AsmPrinter::emitFunctionEntryLabel() {
1116 MF->getFunction().getCallingConv() ==
1124 if (
TM.getTargetTriple().isWindowsArm64EC() &&
1125 !MF->getFunction().hasLocalLinkage()) {
1130 MF->getFunction().getMetadata(
"arm64ec_unmangled_name")) {
1134 MF->getFunction().getMetadata(
"arm64ec_ecmangled_name")) {
1136 cast<MDString>(Unmangled->getOperand(0))->getString();
1138 MMI->getContext().getOrCreateSymbol(UnmangledStr);
1140 cast<MDString>(ECMangled->getOperand(0))->getString();
1142 MMI->getContext().getOrCreateSymbol(ECMangledStr);
1144 OutStreamer->emitAssignment(
1147 MMI->getContext()));
1149 OutStreamer->emitAssignment(
1152 MMI->getContext()));
1156 cast<MDString>(Unmangled->getOperand(0))->getString();
1158 MMI->getContext().getOrCreateSymbol(UnmangledStr);
1160 OutStreamer->emitAssignment(
1163 MMI->getContext()));
1183 Register DestReg =
MI.getOperand(0).getReg();
1184 Register ScratchReg =
MI.getOperand(1).getReg();
1186 STI->getRegisterInfo()->getSubReg(ScratchReg, AArch64::sub_32);
1187 Register TableReg =
MI.getOperand(2).getReg();
1188 Register EntryReg =
MI.getOperand(3).getReg();
1189 int JTIdx =
MI.getOperand(4).getIndex();
1190 int Size = AArch64FI->getJumpTableEntrySize(JTIdx);
1200 Label = MF->getContext().createTempSymbol();
1201 AArch64FI->setJumpTableEntryInfo(JTIdx,
Size, Label);
1208 .addExpr(LabelExpr));
1213 case 1: LdrOpcode = AArch64::LDRBBroX;
break;
1214 case 2: LdrOpcode = AArch64::LDRHHroX;
break;
1215 case 4: LdrOpcode = AArch64::LDRSWroX;
break;
1221 .addReg(
Size == 4 ? ScratchReg : ScratchRegW)
1225 .addImm(
Size == 1 ? 0 : 1));
1233 .addImm(
Size == 4 ? 0 : 2));
1238 unsigned Opcode =
MI.getOpcode();
1240 assert(STI->hasMTE() || Opcode != AArch64::MOPSMemorySetTaggingPseudo);
1242 const auto Ops = [Opcode]() -> std::array<unsigned, 3> {
1243 if (Opcode == AArch64::MOPSMemoryCopyPseudo)
1244 return {AArch64::CPYFP, AArch64::CPYFM, AArch64::CPYFE};
1245 if (Opcode == AArch64::MOPSMemoryMovePseudo)
1246 return {AArch64::CPYP, AArch64::CPYM, AArch64::CPYE};
1247 if (Opcode == AArch64::MOPSMemorySetPseudo)
1248 return {AArch64::SETP, AArch64::SETM, AArch64::SETE};
1249 if (Opcode == AArch64::MOPSMemorySetTaggingPseudo)
1250 return {AArch64::SETGP, AArch64::SETGM, AArch64::MOPSSETGE};
1253 const bool IsSet = Opcode == AArch64::MOPSMemorySetPseudo ||
1254 Opcode == AArch64::MOPSMemorySetTaggingPseudo;
1256 for (
auto Op : Ops) {
1260 MCIB.addReg(
MI.getOperand(i++).getReg());
1261 MCIB.addReg(
MI.getOperand(i++).getReg());
1263 MCIB.addReg(
MI.getOperand(i++).getReg());
1265 MCIB.addReg(
MI.getOperand(i++).getReg());
1266 MCIB.addReg(
MI.getOperand(i++).getReg());
1267 MCIB.addReg(
MI.getOperand(i++).getReg());
1269 EmitToStreamer(OutStreamer, MCIB);
1278 MCSymbol *MILabel = Ctx.createTempSymbol();
1282 assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
1288 while (NumNOPBytes > 0) {
1289 if (MII ==
MBB.
end() || MII->isCall() ||
1290 MII->getOpcode() == AArch64::DBG_VALUE ||
1291 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
1292 MII->getOpcode() == TargetOpcode::STACKMAP)
1299 for (
unsigned i = 0; i < NumNOPBytes; i += 4)
1300 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1308 MCSymbol *MILabel = Ctx.createTempSymbol();
1314 int64_t CallTarget = Opers.getCallTarget().getImm();
1315 unsigned EncodedBytes = 0;
1317 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
1318 "High 16 bits of call target should be zero.");
1319 Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
1324 .addImm((CallTarget >> 32) & 0xFFFF)
1329 .addImm((CallTarget >> 16) & 0xFFFF)
1334 .addImm(CallTarget & 0xFFFF)
1336 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::BLR).addReg(ScratchReg));
1339 unsigned NumBytes = Opers.getNumPatchBytes();
1340 assert(NumBytes >= EncodedBytes &&
1341 "Patchpoint can't request size less than the length of a call.");
1342 assert((NumBytes - EncodedBytes) % 4 == 0 &&
1343 "Invalid number of NOP bytes requested!");
1344 for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
1345 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1351 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
1352 assert(PatchBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
1353 for (
unsigned i = 0; i < PatchBytes; i += 4)
1354 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1359 unsigned CallOpcode;
1360 switch (CallTarget.
getType()) {
1363 MCInstLowering.lowerOperand(CallTarget, CallTargetMCOp);
1364 CallOpcode = AArch64::BL;
1368 CallOpcode = AArch64::BL;
1372 CallOpcode = AArch64::BLR;
1379 EmitToStreamer(OutStreamer,
1384 MCSymbol *MILabel = Ctx.createTempSymbol();
1389void AArch64AsmPrinter::LowerFAULTING_OP(
const MachineInstr &FaultingMI) {
1398 unsigned OperandsBeginIdx = 4;
1401 MCSymbol *FaultingLabel = Ctx.createTempSymbol();
1405 FM.recordFaultingOp(FK, FaultingLabel, HandlerLabel);
1408 MI.setOpcode(Opcode);
1416 lowerOperand(MO, Dest);
1417 MI.addOperand(Dest);
1425 Register DestReg =
MI.getOperand(0).getReg();
1426 if (STI->hasZeroCycleZeroingFP() && !STI->hasZeroCycleZeroingFPWorkaround() &&
1427 STI->isNeonAvailable()) {
1429 if (AArch64::H0 <= DestReg && DestReg <= AArch64::H31)
1430 DestReg = AArch64::D0 + (DestReg - AArch64::H0);
1431 else if (AArch64::S0 <= DestReg && DestReg <= AArch64::S31)
1432 DestReg = AArch64::D0 + (DestReg - AArch64::S0);
1434 assert(AArch64::D0 <= DestReg && DestReg <= AArch64::D31);
1437 MOVI.setOpcode(AArch64::MOVID);
1440 EmitToStreamer(*OutStreamer, MOVI);
1443 switch (
MI.getOpcode()) {
1445 case AArch64::FMOVH0:
1446 FMov.
setOpcode(STI->hasFullFP16() ? AArch64::FMOVWHr : AArch64::FMOVWSr);
1447 if (!STI->hasFullFP16())
1448 DestReg = (AArch64::S0 + (DestReg - AArch64::H0));
1452 case AArch64::FMOVS0:
1457 case AArch64::FMOVD0:
1463 EmitToStreamer(*OutStreamer, FMov);
1469#include "AArch64GenMCPseudoLowering.inc"
1472 AArch64_MC::verifyInstructionPredicates(
MI->getOpcode(), STI->getFeatureBits());
1475 if (emitPseudoExpansionLowering(*OutStreamer,
MI))
1478 if (
MI->getOpcode() == AArch64::ADRP) {
1479 for (
auto &Opd :
MI->operands()) {
1480 if (Opd.isSymbol() &&
StringRef(Opd.getSymbolName()) ==
1481 "swift_async_extendedFramePointerFlags") {
1482 ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags =
true;
1487 if (AArch64FI->getLOHRelated().count(
MI)) {
1489 MCSymbol *LOHLabel = createTempSymbol(
"loh");
1491 LOHInstToLabel[
MI] = LOHLabel;
1498 switch (
MI->getOpcode()) {
1501 case AArch64::HINT: {
1506 if (CurrentPatchableFunctionEntrySym &&
1507 CurrentPatchableFunctionEntrySym == CurrentFnBegin &&
1508 MI == &MF->front().front()) {
1509 int64_t
Imm =
MI->getOperand(0).getImm();
1510 if ((Imm & 32) && (
Imm & 6)) {
1512 MCInstLowering.Lower(
MI, Inst);
1513 EmitToStreamer(*OutStreamer, Inst);
1514 CurrentPatchableFunctionEntrySym = createTempSymbol(
"patch");
1515 OutStreamer->
emitLabel(CurrentPatchableFunctionEntrySym);
1521 case AArch64::MOVMCSym: {
1522 Register DestReg =
MI->getOperand(0).getReg();
1530 MCInstLowering.lowerOperand(Hi_MOSym, Hi_MCSym);
1531 MCInstLowering.lowerOperand(Lo_MOSym, Lo_MCSym);
1538 EmitToStreamer(*OutStreamer, MovZ);
1546 EmitToStreamer(*OutStreamer, MovK);
1549 case AArch64::MOVIv2d_ns:
1557 if (STI->hasZeroCycleZeroingFPWorkaround() &&
1558 MI->getOperand(1).getImm() == 0) {
1560 TmpInst.
setOpcode(AArch64::MOVIv16b_ns);
1563 EmitToStreamer(*OutStreamer, TmpInst);
1568 case AArch64::DBG_VALUE:
1569 case AArch64::DBG_VALUE_LIST:
1573 PrintDebugValueComment(
MI,
OS);
1578 case AArch64::EMITBKEY: {
1580 if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
1581 ExceptionHandlingType != ExceptionHandling::ARM)
1584 if (getFunctionCFISectionType(*MF) == CFISection::None)
1591 case AArch64::EMITMTETAGGED: {
1593 if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
1594 ExceptionHandlingType != ExceptionHandling::ARM)
1597 if (getFunctionCFISectionType(*MF) != CFISection::None)
1605 case AArch64::TCRETURNri:
1606 case AArch64::TCRETURNrix16x17:
1607 case AArch64::TCRETURNrix17:
1608 case AArch64::TCRETURNrinotx16:
1609 case AArch64::TCRETURNriALL: {
1613 EmitToStreamer(*OutStreamer, TmpInst);
1616 case AArch64::TCRETURNdi: {
1618 MCInstLowering.lowerOperand(
MI->getOperand(0), Dest);
1622 EmitToStreamer(*OutStreamer, TmpInst);
1625 case AArch64::SpeculationBarrierISBDSBEndBB: {
1630 EmitToStreamer(*OutStreamer, TmpInstDSB);
1634 EmitToStreamer(*OutStreamer, TmpInstISB);
1637 case AArch64::SpeculationBarrierSBEndBB: {
1641 EmitToStreamer(*OutStreamer, TmpInstSB);
1644 case AArch64::TLSDESC_CALLSEQ: {
1657 MCInstLowering.lowerOperand(MO_Sym,
Sym);
1658 MCInstLowering.lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
1659 MCInstLowering.lowerOperand(MO_TLSDESC, SymTLSDesc);
1665 EmitToStreamer(*OutStreamer, Adrp);
1668 if (STI->isTargetILP32()) {
1678 EmitToStreamer(*OutStreamer, Ldr);
1681 if (STI->isTargetILP32()) {
1682 Add.setOpcode(AArch64::ADDWri);
1686 Add.setOpcode(AArch64::ADDXri);
1690 Add.addOperand(SymTLSDescLo12);
1692 EmitToStreamer(*OutStreamer,
Add);
1697 TLSDescCall.
setOpcode(AArch64::TLSDESCCALL);
1699 EmitToStreamer(*OutStreamer, TLSDescCall);
1704 EmitToStreamer(*OutStreamer, Blr);
1709 case AArch64::JumpTableDest32:
1710 case AArch64::JumpTableDest16:
1711 case AArch64::JumpTableDest8:
1712 LowerJumpTableDest(*OutStreamer, *
MI);
1715 case AArch64::FMOVH0:
1716 case AArch64::FMOVS0:
1717 case AArch64::FMOVD0:
1721 case AArch64::MOPSMemoryCopyPseudo:
1722 case AArch64::MOPSMemoryMovePseudo:
1723 case AArch64::MOPSMemorySetPseudo:
1724 case AArch64::MOPSMemorySetTaggingPseudo:
1725 LowerMOPS(*OutStreamer, *
MI);
1728 case TargetOpcode::STACKMAP:
1729 return LowerSTACKMAP(*OutStreamer, SM, *
MI);
1731 case TargetOpcode::PATCHPOINT:
1732 return LowerPATCHPOINT(*OutStreamer, SM, *
MI);
1734 case TargetOpcode::STATEPOINT:
1735 return LowerSTATEPOINT(*OutStreamer, SM, *
MI);
1737 case TargetOpcode::FAULTING_OP:
1738 return LowerFAULTING_OP(*
MI);
1740 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
1741 LowerPATCHABLE_FUNCTION_ENTER(*
MI);
1744 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1745 LowerPATCHABLE_FUNCTION_EXIT(*
MI);
1748 case TargetOpcode::PATCHABLE_TAIL_CALL:
1749 LowerPATCHABLE_TAIL_CALL(*
MI);
1751 case TargetOpcode::PATCHABLE_EVENT_CALL:
1752 return LowerPATCHABLE_EVENT_CALL(*
MI,
false);
1753 case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
1754 return LowerPATCHABLE_EVENT_CALL(*
MI,
true);
1756 case AArch64::KCFI_CHECK:
1757 LowerKCFI_CHECK(*
MI);
1760 case AArch64::HWASAN_CHECK_MEMACCESS:
1761 case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
1762 LowerHWASAN_CHECK_MEMACCESS(*
MI);
1765 case AArch64::SEH_StackAlloc:
1769 case AArch64::SEH_SaveFPLR:
1773 case AArch64::SEH_SaveFPLR_X:
1774 assert(
MI->getOperand(0).getImm() < 0 &&
1775 "Pre increment SEH opcode must have a negative offset");
1779 case AArch64::SEH_SaveReg:
1781 MI->getOperand(1).getImm());
1784 case AArch64::SEH_SaveReg_X:
1785 assert(
MI->getOperand(1).getImm() < 0 &&
1786 "Pre increment SEH opcode must have a negative offset");
1788 -
MI->getOperand(1).getImm());
1791 case AArch64::SEH_SaveRegP:
1792 if (
MI->getOperand(1).getImm() == 30 &&
MI->getOperand(0).getImm() >= 19 &&
1793 MI->getOperand(0).getImm() <= 28) {
1794 assert((
MI->getOperand(0).getImm() - 19) % 2 == 0 &&
1795 "Register paired with LR must be odd");
1797 MI->getOperand(2).getImm());
1800 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1801 "Non-consecutive registers not allowed for save_regp");
1803 MI->getOperand(2).getImm());
1806 case AArch64::SEH_SaveRegP_X:
1807 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1808 "Non-consecutive registers not allowed for save_regp_x");
1809 assert(
MI->getOperand(2).getImm() < 0 &&
1810 "Pre increment SEH opcode must have a negative offset");
1812 -
MI->getOperand(2).getImm());
1815 case AArch64::SEH_SaveFReg:
1817 MI->getOperand(1).getImm());
1820 case AArch64::SEH_SaveFReg_X:
1821 assert(
MI->getOperand(1).getImm() < 0 &&
1822 "Pre increment SEH opcode must have a negative offset");
1824 -
MI->getOperand(1).getImm());
1827 case AArch64::SEH_SaveFRegP:
1828 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1829 "Non-consecutive registers not allowed for save_regp");
1831 MI->getOperand(2).getImm());
1834 case AArch64::SEH_SaveFRegP_X:
1835 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1836 "Non-consecutive registers not allowed for save_regp_x");
1837 assert(
MI->getOperand(2).getImm() < 0 &&
1838 "Pre increment SEH opcode must have a negative offset");
1840 -
MI->getOperand(2).getImm());
1843 case AArch64::SEH_SetFP:
1847 case AArch64::SEH_AddFP:
1851 case AArch64::SEH_Nop:
1855 case AArch64::SEH_PrologEnd:
1859 case AArch64::SEH_EpilogStart:
1863 case AArch64::SEH_EpilogEnd:
1867 case AArch64::SEH_PACSignLR:
1871 case AArch64::SEH_SaveAnyRegQP:
1872 assert(
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1 &&
1873 "Non-consecutive registers not allowed for save_any_reg");
1874 assert(
MI->getOperand(2).getImm() >= 0 &&
1875 "SaveAnyRegQP SEH opcode offset must be non-negative");
1876 assert(
MI->getOperand(2).getImm() <= 1008 &&
1877 "SaveAnyRegQP SEH opcode offset must fit into 6 bits");
1879 MI->getOperand(2).getImm());
1882 case AArch64::SEH_SaveAnyRegQPX:
1883 assert(
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1 &&
1884 "Non-consecutive registers not allowed for save_any_reg");
1885 assert(
MI->getOperand(2).getImm() < 0 &&
1886 "SaveAnyRegQPX SEH opcode offset must be negative");
1887 assert(
MI->getOperand(2).getImm() >= -1008 &&
1888 "SaveAnyRegQPX SEH opcode offset must fit into 6 bits");
1890 -
MI->getOperand(2).getImm());
1896 MCInstLowering.Lower(
MI, TmpInst);
1897 EmitToStreamer(*OutStreamer, TmpInst);
1913 MCInstLowering.lowerOperand(
1927 MCInstLowering.lowerOperand(
1937 .addReg(AArch64::X16)
1938 .addReg(AArch64::X16)
1949void AArch64AsmPrinter::emitMachOIFuncStubHelperBody(
Module &M,
1984 .addReg(AArch64::SP)
1985 .addReg(AArch64::FP)
1986 .addReg(AArch64::LR)
1987 .addReg(AArch64::SP)
1992 .addReg(AArch64::FP)
1993 .addReg(AArch64::SP)
1998 for (
int I = 0;
I != 4; ++
I)
2000 .addReg(AArch64::SP)
2001 .addReg(AArch64::X1 + 2 *
I)
2002 .addReg(AArch64::X0 + 2 *
I)
2003 .addReg(AArch64::SP)
2007 for (
int I = 0;
I != 4; ++
I)
2009 .addReg(AArch64::SP)
2010 .addReg(AArch64::D1 + 2 *
I)
2011 .addReg(AArch64::D0 + 2 *
I)
2012 .addReg(AArch64::SP)
2026 MCInstLowering.lowerOperand(
2040 MCInstLowering.lowerOperand(
2050 .addReg(AArch64::X0)
2051 .addReg(AArch64::X16)
2056 .addReg(AArch64::X16)
2057 .addReg(AArch64::X0)
2062 for (
int I = 3;
I != -1; --
I)
2064 .addReg(AArch64::SP)
2065 .addReg(AArch64::D1 + 2 *
I)
2066 .addReg(AArch64::D0 + 2 *
I)
2067 .addReg(AArch64::SP)
2071 for (
int I = 3;
I != -1; --
I)
2073 .addReg(AArch64::SP)
2074 .addReg(AArch64::X1 + 2 *
I)
2075 .addReg(AArch64::X0 + 2 *
I)
2076 .addReg(AArch64::SP)
2081 .addReg(AArch64::SP)
2082 .addReg(AArch64::FP)
2083 .addReg(AArch64::LR)
2084 .addReg(AArch64::SP)
2095const MCExpr *AArch64AsmPrinter::lowerConstant(
const Constant *CV) {
2096 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)
void emitNoteSection(unsigned Flags)
Callback used to implement the .note.gnu.property section.
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()
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,...