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, bool, uint64_t>
120 HwasanMemaccessTuple;
121 std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
124 void emitHwasanMemaccessSymbols(
Module &M);
130 bool emitPseudoExpansionLowering(
MCStreamer &OutStreamer,
135 void emitFunctionHeaderComment()
override;
148 if (STI->isTargetCOFF()) {
200 using MInstToMCSymbol = std::map<const MachineInstr *, MCSymbol *>;
202 MInstToMCSymbol LOHInstToLabel;
205 return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags;
220void AArch64AsmPrinter::emitStartOfAsmFile(
Module &M) {
223 if (
TT.isOSBinFormatCOFF()) {
226 OutStreamer->beginCOFFSymbolDef(S);
229 OutStreamer->endCOFFSymbolDef();
230 int64_t Feat00Value = 0;
232 if (
M.getModuleFlag(
"cfguard")) {
234 Feat00Value |= COFF::Feat00Flags::GuardCF;
237 if (
M.getModuleFlag(
"ehcontguard")) {
239 Feat00Value |= COFF::Feat00Flags::GuardEHCont;
242 if (
M.getModuleFlag(
"ms-kernel")) {
244 Feat00Value |= COFF::Feat00Flags::Kernel;
248 OutStreamer->emitAssignment(
252 if (!
TT.isOSBinFormatELF())
257 if (
const auto *BTE = mdconst::extract_or_null<ConstantInt>(
258 M.getModuleFlag(
"branch-target-enforcement")))
259 if (BTE->getZExtValue())
262 if (
const auto *GCS = mdconst::extract_or_null<ConstantInt>(
263 M.getModuleFlag(
"guarded-control-stack")))
264 if (GCS->getZExtValue())
267 if (
const auto *Sign = mdconst::extract_or_null<ConstantInt>(
268 M.getModuleFlag(
"sign-return-address")))
269 if (Sign->getZExtValue())
273 if (
const auto *PAP = mdconst::extract_or_null<ConstantInt>(
274 M.getModuleFlag(
"aarch64-elf-pauthabi-platform")))
275 PAuthABIPlatform = PAP->getZExtValue();
277 if (
const auto *PAV = mdconst::extract_or_null<ConstantInt>(
278 M.getModuleFlag(
"aarch64-elf-pauthabi-version")))
279 PAuthABIVersion = PAV->getZExtValue();
287void AArch64AsmPrinter::emitFunctionHeaderComment() {
290 if (OutlinerString != std::nullopt)
291 OutStreamer->getCommentOS() <<
' ' << OutlinerString;
294void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr &
MI)
297 if (
F.hasFnAttribute(
"patchable-function-entry")) {
299 if (
F.getFnAttribute(
"patchable-function-entry")
301 .getAsInteger(10, Num))
307 emitSled(
MI, SledKind::FUNCTION_ENTER);
310void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr &
MI) {
311 emitSled(
MI, SledKind::FUNCTION_EXIT);
314void AArch64AsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr &
MI) {
315 emitSled(
MI, SledKind::TAIL_CALL);
318void AArch64AsmPrinter::emitSled(
const MachineInstr &
MI, SledKind Kind) {
319 static const int8_t NoopsInSledCount = 7;
340 OutStreamer->emitCodeAlignment(
Align(4), &getSubtargetInfo());
341 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
342 OutStreamer->emitLabel(CurSled);
343 auto Target = OutContext.createTempSymbol();
348 EmitToStreamer(*OutStreamer,
MCInstBuilder(AArch64::B).addImm(8));
350 for (int8_t
I = 0;
I < NoopsInSledCount;
I++)
351 EmitToStreamer(*OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
353 OutStreamer->emitLabel(
Target);
354 recordSled(CurSled,
MI, Kind, 2);
372void AArch64AsmPrinter::LowerPATCHABLE_EVENT_CALL(
const MachineInstr &
MI,
374 auto &
O = *OutStreamer;
375 MCSymbol *CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
376 O.emitLabel(CurSled);
387 bool MachO =
TM.getTargetTriple().isOSBinFormatMachO();
389 OutContext.getOrCreateSymbol(
390 Twine(MachO ?
"_" :
"") +
391 (Typed ?
"__xray_TypedEvent" :
"__xray_CustomEvent")),
394 O.AddComment(
"Begin XRay typed event");
406 EmitToStreamer(O, MovX0Op0);
407 EmitToStreamer(O, MovX1Op1);
410 .addReg(AArch64::XZR)
411 .addReg(
MI.getOperand(2).getReg())
418 O.AddComment(
"End XRay typed event");
426 recordSled(CurSled,
MI, SledKind::TYPED_EVENT, 2);
428 O.AddComment(
"Begin XRay custom event");
436 EmitToStreamer(O, MovX0Op0);
437 EmitToStreamer(O, MovX1Op1);
439 O.AddComment(
"End XRay custom event");
447 recordSled(CurSled,
MI, SledKind::CUSTOM_EVENT, 2);
453 assert(std::next(
MI.getIterator())->isCall() &&
454 "KCFI_CHECK not followed by a call instruction");
455 assert(std::next(
MI.getIterator())->getOperand(0).getReg() == AddrReg &&
456 "KCFI_CHECK call target doesn't match call operand");
460 unsigned ScratchRegs[] = {AArch64::W16, AArch64::W17};
461 if (AddrReg == AArch64::XZR) {
467 .addReg(AArch64::XZR)
468 .addReg(AArch64::XZR)
475 for (
auto &Reg : ScratchRegs) {
481 assert(ScratchRegs[0] != AddrReg && ScratchRegs[1] != AddrReg &&
482 "Invalid scratch registers for KCFI_CHECK");
486 int64_t PrefixNops = 0;
489 .getFnAttribute(
"patchable-function-prefix")
491 .getAsInteger(10, PrefixNops);
495 .addReg(ScratchRegs[0])
497 .addImm(-(PrefixNops * 4 + 4)));
501 const int64_t
Type =
MI.getOperand(1).getImm();
503 .addReg(ScratchRegs[1])
504 .addReg(ScratchRegs[1])
505 .addImm(
Type & 0xFFFF)
508 .addReg(ScratchRegs[1])
509 .addReg(ScratchRegs[1])
510 .addImm((
Type >> 16) & 0xFFFF)
515 .addReg(AArch64::WZR)
516 .addReg(ScratchRegs[0])
517 .addReg(ScratchRegs[1])
521 EmitToStreamer(*OutStreamer,
531 unsigned TypeIndex = ScratchRegs[1] - AArch64::W0;
535 AddrIndex = AddrReg - AArch64::X0;
545 assert(AddrIndex < 31 && TypeIndex < 31);
547 unsigned ESR = 0x8000 | ((TypeIndex & 31) << 5) | (AddrIndex & 31);
548 EmitToStreamer(*OutStreamer,
MCInstBuilder(AArch64::BRK).addImm(ESR));
549 OutStreamer->emitLabel(
Pass);
552void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
555 ((
MI.getOpcode() == AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES) ||
557 AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW));
558 uint32_t AccessInfo =
MI.getOperand(1).getImm();
560 ((
MI.getOpcode() == AArch64::HWASAN_CHECK_MEMACCESS_FIXEDSHADOW) ||
562 AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW));
563 uint64_t FixedShadowOffset = IsFixedShadow ?
MI.getOperand(2).getImm() : 0;
565 MCSymbol *&
Sym = HwasanMemaccessSymbols[HwasanMemaccessTuple(
566 Reg, IsShort, AccessInfo, IsFixedShadow, FixedShadowOffset)];
569 if (!
TM.getTargetTriple().isOSBinFormatELF())
572 std::string SymName =
"__hwasan_check_x" + utostr(Reg - AArch64::X0) +
"_" +
575 SymName +=
"_fixed_" + utostr(FixedShadowOffset);
577 SymName +=
"_short_v2";
578 Sym = OutContext.getOrCreateSymbol(SymName);
581 EmitToStreamer(*OutStreamer,
586void AArch64AsmPrinter::emitHwasanMemaccessSymbols(
Module &M) {
587 if (HwasanMemaccessSymbols.empty())
592 std::unique_ptr<MCSubtargetInfo> STI(
593 TM.getTarget().createMCSubtargetInfo(
TT.str(),
"",
""));
594 assert(STI &&
"Unable to create subtarget info");
597 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch");
599 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
606 for (
auto &
P : HwasanMemaccessSymbols) {
607 unsigned Reg = std::get<0>(
P.first);
608 bool IsShort = std::get<1>(
P.first);
609 uint32_t AccessInfo = std::get<2>(
P.first);
610 bool IsFixedShadow = std::get<3>(
P.first);
611 uint64_t FixedShadowOffset = std::get<4>(
P.first);
613 IsShort ? HwasanTagMismatchV2Ref : HwasanTagMismatchV1Ref;
616 bool HasMatchAllTag =
618 uint8_t MatchAllTag =
625 OutStreamer->switchSection(OutContext.getELFSection(
633 OutStreamer->emitLabel(
Sym);
649 .
addImm(FixedShadowOffset >> 32)
652 OutStreamer->emitInstruction(
MCInstBuilder(AArch64::LDRBBroX)
660 OutStreamer->emitInstruction(
663 .
addReg(IsShort ? AArch64::X20 : AArch64::X9)
670 OutStreamer->emitInstruction(
677 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
678 OutStreamer->emitInstruction(
684 MCSymbol *ReturnSym = OutContext.createTempSymbol();
685 OutStreamer->emitLabel(ReturnSym);
686 OutStreamer->emitInstruction(
688 OutStreamer->emitLabel(HandleMismatchOrPartialSym);
690 if (HasMatchAllTag) {
703 OutStreamer->emitInstruction(
717 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
718 OutStreamer->emitInstruction(
724 OutStreamer->emitInstruction(
743 OutStreamer->emitInstruction(
749 OutStreamer->emitInstruction(
760 OutStreamer->emitInstruction(
767 OutStreamer->emitInstruction(
773 OutStreamer->emitLabel(HandleMismatchSym);
790 if (Reg != AArch64::X0)
797 OutStreamer->emitInstruction(
808 OutStreamer->emitInstruction(
814 OutStreamer->emitInstruction(
818 HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_PAGE,
821 OutStreamer->emitInstruction(
826 HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_LO12,
829 OutStreamer->emitInstruction(
835void AArch64AsmPrinter::emitEndOfAsmFile(
Module &M) {
836 emitHwasanMemaccessSymbols(M);
839 if (
TT.isOSBinFormatMachO()) {
849 FM.serializeToFaultMapSection();
853void AArch64AsmPrinter::emitLOHs() {
856 for (
const auto &
D : AArch64FI->getLOHContainer()) {
858 MInstToMCSymbol::iterator LabelIt = LOHInstToLabel.find(
MI);
859 assert(LabelIt != LOHInstToLabel.end() &&
860 "Label hasn't been inserted for LOH related instruction");
863 OutStreamer->emitLOHDirective(
D.getKind(), MCArgs);
868void AArch64AsmPrinter::emitFunctionBodyEnd() {
869 if (!AArch64FI->getLOHRelated().empty())
874MCSymbol *AArch64AsmPrinter::GetCPISymbol(
unsigned CPID)
const {
878 if (!getDataLayout().getLinkerPrivateGlobalPrefix().empty())
879 return OutContext.getOrCreateSymbol(
880 Twine(getDataLayout().getLinkerPrivateGlobalPrefix()) +
"CPI" +
881 Twine(getFunctionNumber()) +
"_" +
Twine(CPID));
886void AArch64AsmPrinter::printOperand(
const MachineInstr *
MI,
unsigned OpNum,
904 PrintSymbolOperand(MO, O);
915bool AArch64AsmPrinter::printAsmMRegister(
const MachineOperand &MO,
char Mode,
939bool AArch64AsmPrinter::printAsmRegInClass(
const MachineOperand &MO,
942 assert(MO.
isReg() &&
"Should only get here with a register!");
952bool AArch64AsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNum,
961 if (ExtraCode && ExtraCode[0]) {
962 if (ExtraCode[1] != 0)
965 switch (ExtraCode[0]) {
973 unsigned Reg = ExtraCode[0] ==
'w' ? AArch64::WZR : AArch64::XZR;
987 switch (ExtraCode[0]) {
989 RC = &AArch64::FPR8RegClass;
992 RC = &AArch64::FPR16RegClass;
995 RC = &AArch64::FPR32RegClass;
998 RC = &AArch64::FPR64RegClass;
1001 RC = &AArch64::FPR128RegClass;
1004 RC = &AArch64::ZPRRegClass;
1009 return printAsmRegInClass(MO, RC, AArch64::NoRegAltName, O);
1022 if (AArch64::GPR32allRegClass.
contains(Reg) ||
1023 AArch64::GPR64allRegClass.
contains(Reg))
1027 if (AArch64::GPR64x8ClassRegClass.
contains(Reg))
1030 unsigned AltName = AArch64::NoRegAltName;
1032 if (AArch64::ZPRRegClass.
contains(Reg)) {
1033 RegClass = &AArch64::ZPRRegClass;
1034 }
else if (AArch64::PPRRegClass.
contains(Reg)) {
1035 RegClass = &AArch64::PPRRegClass;
1036 }
else if (AArch64::PNRRegClass.
contains(Reg)) {
1037 RegClass = &AArch64::PNRRegClass;
1039 RegClass = &AArch64::FPR128RegClass;
1040 AltName = AArch64::vreg;
1044 return printAsmRegInClass(MO, RegClass, AltName, O);
1051bool AArch64AsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
1053 const char *ExtraCode,
1055 if (ExtraCode && ExtraCode[0] && ExtraCode[0] !=
'a')
1059 assert(MO.
isReg() &&
"unexpected inline asm memory operand");
1064void AArch64AsmPrinter::PrintDebugValueComment(
const MachineInstr *
MI,
1066 unsigned NOps =
MI->getNumOperands();
1068 OS <<
'\t' << MAI->getCommentString() <<
"DEBUG_VALUE: ";
1070 OS <<
MI->getDebugVariable()->getName();
1073 assert(
MI->isIndirectDebugValue());
1075 for (
unsigned I = 0, E = std::distance(
MI->debug_operands().begin(),
1076 MI->debug_operands().end());
1087void AArch64AsmPrinter::emitJumpTableInfo() {
1092 if (
JT.empty())
return;
1096 OutStreamer->switchSection(ReadOnlySec);
1099 for (
unsigned JTI = 0, e =
JT.size(); JTI !=
e; ++JTI) {
1100 const std::vector<MachineBasicBlock*> &JTBBs =
JT[JTI].MBBs;
1103 if (JTBBs.empty())
continue;
1105 unsigned Size = AFI->getJumpTableEntrySize(JTI);
1107 OutStreamer->emitLabel(GetJTISymbol(JTI));
1109 const MCSymbol *BaseSym = AArch64FI->getJumpTableEntryPCRelSymbol(JTI);
1112 for (
auto *JTBB : JTBBs) {
1132AArch64AsmPrinter::getCodeViewJumpTableInfo(
int JTI,
1134 const MCSymbol *BranchLabel)
const {
1136 const auto Base = AArch64FI->getJumpTableEntryPCRelSymbol(JTI);
1138 switch (AFI->getJumpTableEntrySize(JTI)) {
1140 EntrySize = codeview::JumpTableEntrySize::UInt8ShiftLeft;
1143 EntrySize = codeview::JumpTableEntrySize::UInt16ShiftLeft;
1146 EntrySize = codeview::JumpTableEntrySize::Int32;
1151 return std::make_tuple(
Base, 0, BranchLabel, EntrySize);
1154void AArch64AsmPrinter::emitFunctionEntryLabel() {
1156 MF->getFunction().getCallingConv() ==
1166 if (
TM.getTargetTriple().isWindowsArm64EC() &&
1167 !MF->getFunction().hasLocalLinkage()) {
1172 OutStreamer->emitAssignment(
1174 MMI->getContext()));
1180 StringRef NameStr = cast<MDString>(
Node->getOperand(0))->getString();
1181 Sym = MMI->getContext().getOrCreateSymbol(NameStr);
1187 getSymbolFromMetadata(
"arm64ec_unmangled_name")) {
1188 MCSymbol *ECMangledSym = getSymbolFromMetadata(
"arm64ec_ecmangled_name");
1194 emitFunctionAlias(UnmangledSym, ECMangledSym);
1195 emitFunctionAlias(ECMangledSym, CurrentFnSym);
1199 emitFunctionAlias(UnmangledSym, CurrentFnSym);
1216 Register DestReg =
MI.getOperand(0).getReg();
1217 Register ScratchReg =
MI.getOperand(1).getReg();
1219 STI->getRegisterInfo()->getSubReg(ScratchReg, AArch64::sub_32);
1220 Register TableReg =
MI.getOperand(2).getReg();
1221 Register EntryReg =
MI.getOperand(3).getReg();
1222 int JTIdx =
MI.getOperand(4).getIndex();
1223 int Size = AArch64FI->getJumpTableEntrySize(JTIdx);
1233 Label = MF->getContext().createTempSymbol();
1234 AArch64FI->setJumpTableEntryInfo(JTIdx,
Size, Label);
1241 .addExpr(LabelExpr));
1246 case 1: LdrOpcode = AArch64::LDRBBroX;
break;
1247 case 2: LdrOpcode = AArch64::LDRHHroX;
break;
1248 case 4: LdrOpcode = AArch64::LDRSWroX;
break;
1254 .addReg(
Size == 4 ? ScratchReg : ScratchRegW)
1258 .addImm(
Size == 1 ? 0 : 1));
1266 .addImm(
Size == 4 ? 0 : 2));
1271 unsigned Opcode =
MI.getOpcode();
1273 assert(STI->hasMTE() || Opcode != AArch64::MOPSMemorySetTaggingPseudo);
1275 const auto Ops = [Opcode]() -> std::array<unsigned, 3> {
1276 if (Opcode == AArch64::MOPSMemoryCopyPseudo)
1277 return {AArch64::CPYFP, AArch64::CPYFM, AArch64::CPYFE};
1278 if (Opcode == AArch64::MOPSMemoryMovePseudo)
1279 return {AArch64::CPYP, AArch64::CPYM, AArch64::CPYE};
1280 if (Opcode == AArch64::MOPSMemorySetPseudo)
1281 return {AArch64::SETP, AArch64::SETM, AArch64::SETE};
1282 if (Opcode == AArch64::MOPSMemorySetTaggingPseudo)
1283 return {AArch64::SETGP, AArch64::SETGM, AArch64::MOPSSETGE};
1286 const bool IsSet = Opcode == AArch64::MOPSMemorySetPseudo ||
1287 Opcode == AArch64::MOPSMemorySetTaggingPseudo;
1289 for (
auto Op : Ops) {
1293 MCIB.addReg(
MI.getOperand(i++).getReg());
1294 MCIB.addReg(
MI.getOperand(i++).getReg());
1296 MCIB.addReg(
MI.getOperand(i++).getReg());
1298 MCIB.addReg(
MI.getOperand(i++).getReg());
1299 MCIB.addReg(
MI.getOperand(i++).getReg());
1300 MCIB.addReg(
MI.getOperand(i++).getReg());
1302 EmitToStreamer(OutStreamer, MCIB);
1311 MCSymbol *MILabel = Ctx.createTempSymbol();
1315 assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
1321 while (NumNOPBytes > 0) {
1322 if (MII ==
MBB.
end() || MII->isCall() ||
1323 MII->getOpcode() == AArch64::DBG_VALUE ||
1324 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
1325 MII->getOpcode() == TargetOpcode::STACKMAP)
1332 for (
unsigned i = 0; i < NumNOPBytes; i += 4)
1333 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1341 MCSymbol *MILabel = Ctx.createTempSymbol();
1347 int64_t CallTarget = Opers.getCallTarget().getImm();
1348 unsigned EncodedBytes = 0;
1350 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
1351 "High 16 bits of call target should be zero.");
1352 Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
1357 .addImm((CallTarget >> 32) & 0xFFFF)
1362 .addImm((CallTarget >> 16) & 0xFFFF)
1367 .addImm(CallTarget & 0xFFFF)
1369 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::BLR).addReg(ScratchReg));
1372 unsigned NumBytes = Opers.getNumPatchBytes();
1373 assert(NumBytes >= EncodedBytes &&
1374 "Patchpoint can't request size less than the length of a call.");
1375 assert((NumBytes - EncodedBytes) % 4 == 0 &&
1376 "Invalid number of NOP bytes requested!");
1377 for (
unsigned i = EncodedBytes; i < NumBytes; i += 4)
1378 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1384 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
1385 assert(PatchBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
1386 for (
unsigned i = 0; i < PatchBytes; i += 4)
1387 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1392 unsigned CallOpcode;
1393 switch (CallTarget.
getType()) {
1396 MCInstLowering.lowerOperand(CallTarget, CallTargetMCOp);
1397 CallOpcode = AArch64::BL;
1401 CallOpcode = AArch64::BL;
1405 CallOpcode = AArch64::BLR;
1412 EmitToStreamer(OutStreamer,
1417 MCSymbol *MILabel = Ctx.createTempSymbol();
1422void AArch64AsmPrinter::LowerFAULTING_OP(
const MachineInstr &FaultingMI) {
1431 unsigned OperandsBeginIdx = 4;
1434 MCSymbol *FaultingLabel = Ctx.createTempSymbol();
1438 FM.recordFaultingOp(FK, FaultingLabel, HandlerLabel);
1441 MI.setOpcode(Opcode);
1449 lowerOperand(MO, Dest);
1450 MI.addOperand(Dest);
1458 Register DestReg =
MI.getOperand(0).getReg();
1459 if (STI->hasZeroCycleZeroingFP() && !STI->hasZeroCycleZeroingFPWorkaround() &&
1460 STI->isNeonAvailable()) {
1462 if (AArch64::H0 <= DestReg && DestReg <= AArch64::H31)
1463 DestReg = AArch64::D0 + (DestReg - AArch64::H0);
1464 else if (AArch64::S0 <= DestReg && DestReg <= AArch64::S31)
1465 DestReg = AArch64::D0 + (DestReg - AArch64::S0);
1467 assert(AArch64::D0 <= DestReg && DestReg <= AArch64::D31);
1470 MOVI.setOpcode(AArch64::MOVID);
1473 EmitToStreamer(*OutStreamer, MOVI);
1476 switch (
MI.getOpcode()) {
1478 case AArch64::FMOVH0:
1479 FMov.
setOpcode(STI->hasFullFP16() ? AArch64::FMOVWHr : AArch64::FMOVWSr);
1480 if (!STI->hasFullFP16())
1481 DestReg = (AArch64::S0 + (DestReg - AArch64::H0));
1485 case AArch64::FMOVS0:
1490 case AArch64::FMOVD0:
1496 EmitToStreamer(*OutStreamer, FMov);
1502#include "AArch64GenMCPseudoLowering.inc"
1505 AArch64_MC::verifyInstructionPredicates(
MI->getOpcode(), STI->getFeatureBits());
1508 if (emitPseudoExpansionLowering(*OutStreamer,
MI))
1511 if (
MI->getOpcode() == AArch64::ADRP) {
1512 for (
auto &Opd :
MI->operands()) {
1513 if (Opd.isSymbol() &&
StringRef(Opd.getSymbolName()) ==
1514 "swift_async_extendedFramePointerFlags") {
1515 ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags =
true;
1520 if (AArch64FI->getLOHRelated().count(
MI)) {
1522 MCSymbol *LOHLabel = createTempSymbol(
"loh");
1524 LOHInstToLabel[
MI] = LOHLabel;
1531 switch (
MI->getOpcode()) {
1534 case AArch64::HINT: {
1539 if (CurrentPatchableFunctionEntrySym &&
1540 CurrentPatchableFunctionEntrySym == CurrentFnBegin &&
1541 MI == &MF->front().front()) {
1542 int64_t
Imm =
MI->getOperand(0).getImm();
1543 if ((Imm & 32) && (
Imm & 6)) {
1545 MCInstLowering.Lower(
MI, Inst);
1546 EmitToStreamer(*OutStreamer, Inst);
1547 CurrentPatchableFunctionEntrySym = createTempSymbol(
"patch");
1548 OutStreamer->
emitLabel(CurrentPatchableFunctionEntrySym);
1554 case AArch64::MOVMCSym: {
1555 Register DestReg =
MI->getOperand(0).getReg();
1563 MCInstLowering.lowerOperand(Hi_MOSym, Hi_MCSym);
1564 MCInstLowering.lowerOperand(Lo_MOSym, Lo_MCSym);
1571 EmitToStreamer(*OutStreamer, MovZ);
1579 EmitToStreamer(*OutStreamer, MovK);
1582 case AArch64::MOVIv2d_ns:
1590 if (STI->hasZeroCycleZeroingFPWorkaround() &&
1591 MI->getOperand(1).getImm() == 0) {
1593 TmpInst.
setOpcode(AArch64::MOVIv16b_ns);
1596 EmitToStreamer(*OutStreamer, TmpInst);
1601 case AArch64::DBG_VALUE:
1602 case AArch64::DBG_VALUE_LIST:
1606 PrintDebugValueComment(
MI,
OS);
1611 case AArch64::EMITBKEY: {
1613 if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
1614 ExceptionHandlingType != ExceptionHandling::ARM)
1617 if (getFunctionCFISectionType(*MF) == CFISection::None)
1624 case AArch64::EMITMTETAGGED: {
1626 if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
1627 ExceptionHandlingType != ExceptionHandling::ARM)
1630 if (getFunctionCFISectionType(*MF) != CFISection::None)
1638 case AArch64::TCRETURNri:
1639 case AArch64::TCRETURNrix16x17:
1640 case AArch64::TCRETURNrix17:
1641 case AArch64::TCRETURNrinotx16:
1642 case AArch64::TCRETURNriALL: {
1646 EmitToStreamer(*OutStreamer, TmpInst);
1649 case AArch64::TCRETURNdi: {
1651 MCInstLowering.lowerOperand(
MI->getOperand(0), Dest);
1655 EmitToStreamer(*OutStreamer, TmpInst);
1658 case AArch64::SpeculationBarrierISBDSBEndBB: {
1663 EmitToStreamer(*OutStreamer, TmpInstDSB);
1667 EmitToStreamer(*OutStreamer, TmpInstISB);
1670 case AArch64::SpeculationBarrierSBEndBB: {
1674 EmitToStreamer(*OutStreamer, TmpInstSB);
1677 case AArch64::TLSDESC_CALLSEQ: {
1690 MCInstLowering.lowerOperand(MO_Sym,
Sym);
1691 MCInstLowering.lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
1692 MCInstLowering.lowerOperand(MO_TLSDESC, SymTLSDesc);
1698 EmitToStreamer(*OutStreamer, Adrp);
1701 if (STI->isTargetILP32()) {
1711 EmitToStreamer(*OutStreamer, Ldr);
1714 if (STI->isTargetILP32()) {
1715 Add.setOpcode(AArch64::ADDWri);
1719 Add.setOpcode(AArch64::ADDXri);
1723 Add.addOperand(SymTLSDescLo12);
1725 EmitToStreamer(*OutStreamer,
Add);
1730 TLSDescCall.
setOpcode(AArch64::TLSDESCCALL);
1732 EmitToStreamer(*OutStreamer, TLSDescCall);
1737 EmitToStreamer(*OutStreamer, Blr);
1742 case AArch64::JumpTableDest32:
1743 case AArch64::JumpTableDest16:
1744 case AArch64::JumpTableDest8:
1745 LowerJumpTableDest(*OutStreamer, *
MI);
1748 case AArch64::FMOVH0:
1749 case AArch64::FMOVS0:
1750 case AArch64::FMOVD0:
1754 case AArch64::MOPSMemoryCopyPseudo:
1755 case AArch64::MOPSMemoryMovePseudo:
1756 case AArch64::MOPSMemorySetPseudo:
1757 case AArch64::MOPSMemorySetTaggingPseudo:
1758 LowerMOPS(*OutStreamer, *
MI);
1761 case TargetOpcode::STACKMAP:
1762 return LowerSTACKMAP(*OutStreamer, SM, *
MI);
1764 case TargetOpcode::PATCHPOINT:
1765 return LowerPATCHPOINT(*OutStreamer, SM, *
MI);
1767 case TargetOpcode::STATEPOINT:
1768 return LowerSTATEPOINT(*OutStreamer, SM, *
MI);
1770 case TargetOpcode::FAULTING_OP:
1771 return LowerFAULTING_OP(*
MI);
1773 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
1774 LowerPATCHABLE_FUNCTION_ENTER(*
MI);
1777 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1778 LowerPATCHABLE_FUNCTION_EXIT(*
MI);
1781 case TargetOpcode::PATCHABLE_TAIL_CALL:
1782 LowerPATCHABLE_TAIL_CALL(*
MI);
1784 case TargetOpcode::PATCHABLE_EVENT_CALL:
1785 return LowerPATCHABLE_EVENT_CALL(*
MI,
false);
1786 case TargetOpcode::PATCHABLE_TYPED_EVENT_CALL:
1787 return LowerPATCHABLE_EVENT_CALL(*
MI,
true);
1789 case AArch64::KCFI_CHECK:
1790 LowerKCFI_CHECK(*
MI);
1793 case AArch64::HWASAN_CHECK_MEMACCESS:
1794 case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
1795 case AArch64::HWASAN_CHECK_MEMACCESS_FIXEDSHADOW:
1796 case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES_FIXEDSHADOW:
1797 LowerHWASAN_CHECK_MEMACCESS(*
MI);
1800 case AArch64::SEH_StackAlloc:
1804 case AArch64::SEH_SaveFPLR:
1808 case AArch64::SEH_SaveFPLR_X:
1809 assert(
MI->getOperand(0).getImm() < 0 &&
1810 "Pre increment SEH opcode must have a negative offset");
1814 case AArch64::SEH_SaveReg:
1816 MI->getOperand(1).getImm());
1819 case AArch64::SEH_SaveReg_X:
1820 assert(
MI->getOperand(1).getImm() < 0 &&
1821 "Pre increment SEH opcode must have a negative offset");
1823 -
MI->getOperand(1).getImm());
1826 case AArch64::SEH_SaveRegP:
1827 if (
MI->getOperand(1).getImm() == 30 &&
MI->getOperand(0).getImm() >= 19 &&
1828 MI->getOperand(0).getImm() <= 28) {
1829 assert((
MI->getOperand(0).getImm() - 19) % 2 == 0 &&
1830 "Register paired with LR must be odd");
1832 MI->getOperand(2).getImm());
1835 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1836 "Non-consecutive registers not allowed for save_regp");
1838 MI->getOperand(2).getImm());
1841 case AArch64::SEH_SaveRegP_X:
1842 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1843 "Non-consecutive registers not allowed for save_regp_x");
1844 assert(
MI->getOperand(2).getImm() < 0 &&
1845 "Pre increment SEH opcode must have a negative offset");
1847 -
MI->getOperand(2).getImm());
1850 case AArch64::SEH_SaveFReg:
1852 MI->getOperand(1).getImm());
1855 case AArch64::SEH_SaveFReg_X:
1856 assert(
MI->getOperand(1).getImm() < 0 &&
1857 "Pre increment SEH opcode must have a negative offset");
1859 -
MI->getOperand(1).getImm());
1862 case AArch64::SEH_SaveFRegP:
1863 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1864 "Non-consecutive registers not allowed for save_regp");
1866 MI->getOperand(2).getImm());
1869 case AArch64::SEH_SaveFRegP_X:
1870 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1871 "Non-consecutive registers not allowed for save_regp_x");
1872 assert(
MI->getOperand(2).getImm() < 0 &&
1873 "Pre increment SEH opcode must have a negative offset");
1875 -
MI->getOperand(2).getImm());
1878 case AArch64::SEH_SetFP:
1882 case AArch64::SEH_AddFP:
1886 case AArch64::SEH_Nop:
1890 case AArch64::SEH_PrologEnd:
1894 case AArch64::SEH_EpilogStart:
1898 case AArch64::SEH_EpilogEnd:
1902 case AArch64::SEH_PACSignLR:
1906 case AArch64::SEH_SaveAnyRegQP:
1907 assert(
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1 &&
1908 "Non-consecutive registers not allowed for save_any_reg");
1909 assert(
MI->getOperand(2).getImm() >= 0 &&
1910 "SaveAnyRegQP SEH opcode offset must be non-negative");
1911 assert(
MI->getOperand(2).getImm() <= 1008 &&
1912 "SaveAnyRegQP SEH opcode offset must fit into 6 bits");
1914 MI->getOperand(2).getImm());
1917 case AArch64::SEH_SaveAnyRegQPX:
1918 assert(
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1 &&
1919 "Non-consecutive registers not allowed for save_any_reg");
1920 assert(
MI->getOperand(2).getImm() < 0 &&
1921 "SaveAnyRegQPX SEH opcode offset must be negative");
1922 assert(
MI->getOperand(2).getImm() >= -1008 &&
1923 "SaveAnyRegQPX SEH opcode offset must fit into 6 bits");
1925 -
MI->getOperand(2).getImm());
1931 MCInstLowering.Lower(
MI, TmpInst);
1932 EmitToStreamer(*OutStreamer, TmpInst);
1948 MCInstLowering.lowerOperand(
1962 MCInstLowering.lowerOperand(
1972 .addReg(AArch64::X16)
1973 .addReg(AArch64::X16)
1984void AArch64AsmPrinter::emitMachOIFuncStubHelperBody(
Module &M,
2019 .addReg(AArch64::SP)
2020 .addReg(AArch64::FP)
2021 .addReg(AArch64::LR)
2022 .addReg(AArch64::SP)
2027 .addReg(AArch64::FP)
2028 .addReg(AArch64::SP)
2033 for (
int I = 0;
I != 4; ++
I)
2035 .addReg(AArch64::SP)
2036 .addReg(AArch64::X1 + 2 *
I)
2037 .addReg(AArch64::X0 + 2 *
I)
2038 .addReg(AArch64::SP)
2042 for (
int I = 0;
I != 4; ++
I)
2044 .addReg(AArch64::SP)
2045 .addReg(AArch64::D1 + 2 *
I)
2046 .addReg(AArch64::D0 + 2 *
I)
2047 .addReg(AArch64::SP)
2061 MCInstLowering.lowerOperand(
2075 MCInstLowering.lowerOperand(
2085 .addReg(AArch64::X0)
2086 .addReg(AArch64::X16)
2091 .addReg(AArch64::X16)
2092 .addReg(AArch64::X0)
2097 for (
int I = 3;
I != -1; --
I)
2099 .addReg(AArch64::SP)
2100 .addReg(AArch64::D1 + 2 *
I)
2101 .addReg(AArch64::D0 + 2 *
I)
2102 .addReg(AArch64::SP)
2106 for (
int I = 3;
I != -1; --
I)
2108 .addReg(AArch64::SP)
2109 .addReg(AArch64::X1 + 2 *
I)
2110 .addReg(AArch64::X0 + 2 *
I)
2111 .addReg(AArch64::SP)
2116 .addReg(AArch64::SP)
2117 .addReg(AArch64::FP)
2118 .addReg(AArch64::LR)
2119 .addReg(AArch64::SP)
2130const MCExpr *AArch64AsmPrinter::lowerConstant(
const Constant *CV) {
2131 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,...