67 #define DEBUG_TYPE "asm-printer"
76 bool ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags =
false;
79 AArch64AsmPrinter(
TargetMachine &
TM, std::unique_ptr<MCStreamer> Streamer)
81 SM(*
this), FM(*
this) {}
83 StringRef getPassName()
const override {
return "AArch64 Assembly Printer"; }
91 void emitStartOfAsmFile(
Module &
M)
override;
92 void emitJumpTableInfo()
override;
94 void emitFunctionEntryLabel()
override;
112 typedef std::tuple<unsigned, bool, uint32_t> HwasanMemaccessTuple;
113 std::map<HwasanMemaccessTuple, MCSymbol *> HwasanMemaccessSymbols;
115 void emitHwasanMemaccessSymbols(
Module &
M);
121 bool emitPseudoExpansionLowering(
MCStreamer &OutStreamer,
126 void emitFunctionHeaderComment()
override;
137 SetupMachineFunction(MF);
139 if (STI->isTargetCOFF()) {
171 bool PrintAsmMemoryOperand(
const MachineInstr *
MI,
unsigned OpNum,
176 void emitFunctionBodyEnd()
override;
178 MCSymbol *GetCPISymbol(
unsigned CPID)
const override;
179 void emitEndOfAsmFile(
Module &
M)
override;
189 using MInstToMCSymbol = std::map<const MachineInstr *, MCSymbol *>;
191 MInstToMCSymbol LOHInstToLabel;
193 bool shouldEmitWeakSwiftAsyncExtendedFramePointerFlags()
const override {
194 return ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags;
200 void AArch64AsmPrinter::emitStartOfAsmFile(
Module &M) {
203 if (
TT.isOSBinFormatCOFF()) {
207 OutStreamer->beginCOFFSymbolDef(
S);
210 OutStreamer->endCOFFSymbolDef();
211 int64_t Feat00Flags = 0;
213 if (
M.getModuleFlag(
"cfguard")) {
214 Feat00Flags |= 0x800;
217 if (
M.getModuleFlag(
"ehcontguard")) {
218 Feat00Flags |= 0x4000;
222 OutStreamer->emitAssignment(
226 if (!
TT.isOSBinFormatELF())
231 if (
const auto *BTE = mdconst::extract_or_null<ConstantInt>(
232 M.getModuleFlag(
"branch-target-enforcement")))
233 if (BTE->getZExtValue())
236 if (
const auto *Sign = mdconst::extract_or_null<ConstantInt>(
237 M.getModuleFlag(
"sign-return-address")))
238 if (Sign->getZExtValue())
246 OutStreamer->getTargetStreamer()))
247 TS->emitNoteSection(Flags);
250 void AArch64AsmPrinter::emitFunctionHeaderComment() {
253 if (OutlinerString !=
None)
254 OutStreamer->getCommentOS() <<
' ' << OutlinerString;
257 void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_ENTER(
const MachineInstr &
MI)
260 if (
F.hasFnAttribute(
"patchable-function-entry")) {
262 if (
F.getFnAttribute(
"patchable-function-entry")
264 .getAsInteger(10, Num))
270 emitSled(
MI, SledKind::FUNCTION_ENTER);
273 void AArch64AsmPrinter::LowerPATCHABLE_FUNCTION_EXIT(
const MachineInstr &
MI) {
274 emitSled(
MI, SledKind::FUNCTION_EXIT);
277 void AArch64AsmPrinter::LowerPATCHABLE_TAIL_CALL(
const MachineInstr &
MI) {
282 static const int8_t NoopsInSledCount = 7;
303 OutStreamer->emitCodeAlignment(4, &getSubtargetInfo());
304 auto CurSled = OutContext.createTempSymbol(
"xray_sled_",
true);
305 OutStreamer->emitLabel(CurSled);
306 auto Target = OutContext.createTempSymbol();
313 for (int8_t
I = 0;
I < NoopsInSledCount;
I++)
314 EmitToStreamer(*OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
316 OutStreamer->emitLabel(
Target);
317 recordSled(CurSled,
MI,
Kind, 2);
320 void AArch64AsmPrinter::LowerHWASAN_CHECK_MEMACCESS(
const MachineInstr &
MI) {
323 MI.getOpcode() == AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES;
324 uint32_t AccessInfo =
MI.getOperand(1).getImm();
326 HwasanMemaccessSymbols[HwasanMemaccessTuple(
Reg, IsShort, AccessInfo)];
329 if (!
TM.getTargetTriple().isOSBinFormatELF())
332 std::string SymName =
"__hwasan_check_x" + utostr(
Reg - AArch64::X0) +
"_" +
335 SymName +=
"_short_v2";
336 Sym = OutContext.getOrCreateSymbol(SymName);
339 EmitToStreamer(*OutStreamer,
344 void AArch64AsmPrinter::emitHwasanMemaccessSymbols(
Module &M) {
345 if (HwasanMemaccessSymbols.empty())
350 std::unique_ptr<MCSubtargetInfo> STI(
351 TM.getTarget().createMCSubtargetInfo(
TT.str(),
"",
""));
352 assert(STI &&
"Unable to create subtarget info");
355 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch");
357 OutContext.getOrCreateSymbol(
"__hwasan_tag_mismatch_v2");
364 for (
auto &
P : HwasanMemaccessSymbols) {
365 unsigned Reg = std::get<0>(
P.first);
366 bool IsShort = std::get<1>(
P.first);
367 uint32_t AccessInfo = std::get<2>(
P.first);
369 IsShort ? HwasanTagMismatchV2Ref : HwasanTagMismatchV1Ref;
372 bool HasMatchAllTag =
374 uint8_t MatchAllTag =
381 OutStreamer->switchSection(OutContext.getELFSection(
387 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Weak);
388 OutStreamer->emitSymbolAttribute(Sym,
MCSA_Hidden);
389 OutStreamer->emitLabel(Sym);
397 OutStreamer->emitInstruction(
400 .
addReg(IsShort ? AArch64::X20 : AArch64::X9)
405 OutStreamer->emitInstruction(
412 MCSymbol *HandleMismatchOrPartialSym = OutContext.createTempSymbol();
413 OutStreamer->emitInstruction(
419 MCSymbol *ReturnSym = OutContext.createTempSymbol();
420 OutStreamer->emitLabel(ReturnSym);
421 OutStreamer->emitInstruction(
423 OutStreamer->emitLabel(HandleMismatchOrPartialSym);
425 if (HasMatchAllTag) {
438 OutStreamer->emitInstruction(
452 MCSymbol *HandleMismatchSym = OutContext.createTempSymbol();
453 OutStreamer->emitInstruction(
459 OutStreamer->emitInstruction(
478 OutStreamer->emitInstruction(
484 OutStreamer->emitInstruction(
495 OutStreamer->emitInstruction(
502 OutStreamer->emitInstruction(
508 OutStreamer->emitLabel(HandleMismatchSym);
525 if (
Reg != AArch64::X0)
532 OutStreamer->emitInstruction(
543 OutStreamer->emitInstruction(
549 OutStreamer->emitInstruction(
553 HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_PAGE,
556 OutStreamer->emitInstruction(
561 HwasanTagMismatchRef, AArch64MCExpr::VariantKind::VK_GOT_LO12,
564 OutStreamer->emitInstruction(
570 void AArch64AsmPrinter::emitEndOfAsmFile(
Module &M) {
571 emitHwasanMemaccessSymbols(M);
574 if (
TT.isOSBinFormatMachO()) {
585 FM.serializeToFaultMapSection();
589 void AArch64AsmPrinter::emitLOHs() {
592 for (
const auto &
D : AArch64FI->getLOHContainer()) {
594 MInstToMCSymbol::iterator LabelIt = LOHInstToLabel.find(
MI);
595 assert(LabelIt != LOHInstToLabel.end() &&
596 "Label hasn't been inserted for LOH related instruction");
597 MCArgs.push_back(LabelIt->second);
599 OutStreamer->emitLOHDirective(
D.getKind(), MCArgs);
604 void AArch64AsmPrinter::emitFunctionBodyEnd() {
605 if (!AArch64FI->getLOHRelated().empty())
610 MCSymbol *AArch64AsmPrinter::GetCPISymbol(
unsigned CPID)
const {
614 if (!getDataLayout().getLinkerPrivateGlobalPrefix().
empty())
615 return OutContext.getOrCreateSymbol(
616 Twine(getDataLayout().getLinkerPrivateGlobalPrefix()) +
"CPI" +
617 Twine(getFunctionNumber()) +
"_" +
Twine(CPID));
640 PrintSymbolOperand(MO,
O);
675 bool AArch64AsmPrinter::printAsmRegInClass(
const MachineOperand &MO,
678 assert(MO.
isReg() &&
"Should only get here with a register!");
688 bool AArch64AsmPrinter::PrintAsmOperand(
const MachineInstr *
MI,
unsigned OpNum,
697 if (ExtraCode && ExtraCode[0]) {
698 if (ExtraCode[1] != 0)
701 switch (ExtraCode[0]) {
709 unsigned Reg = ExtraCode[0] ==
'w' ? AArch64::WZR : AArch64::XZR;
723 switch (ExtraCode[0]) {
725 RC = &AArch64::FPR8RegClass;
728 RC = &AArch64::FPR16RegClass;
731 RC = &AArch64::FPR32RegClass;
734 RC = &AArch64::FPR64RegClass;
737 RC = &AArch64::FPR128RegClass;
740 RC = &AArch64::ZPRRegClass;
745 return printAsmRegInClass(MO, RC, AArch64::NoRegAltName,
O);
766 unsigned AltName = AArch64::NoRegAltName;
769 RegClass = &AArch64::ZPRRegClass;
771 RegClass = &AArch64::PPRRegClass;
773 RegClass = &AArch64::FPR128RegClass;
774 AltName = AArch64::vreg;
778 return printAsmRegInClass(MO, RegClass, AltName,
O);
785 bool AArch64AsmPrinter::PrintAsmMemoryOperand(
const MachineInstr *
MI,
787 const char *ExtraCode,
789 if (ExtraCode && ExtraCode[0] && ExtraCode[0] !=
'a')
793 assert(MO.
isReg() &&
"unexpected inline asm memory operand");
798 void AArch64AsmPrinter::PrintDebugValueComment(
const MachineInstr *
MI,
800 unsigned NOps =
MI->getNumOperands();
802 OS <<
'\t' << MAI->getCommentString() <<
"DEBUG_VALUE: ";
804 OS <<
MI->getDebugVariable()->getName();
809 for (
unsigned I = 0,
E = std::distance(
MI->debug_operands().begin(),
810 MI->debug_operands().end());
821 void AArch64AsmPrinter::emitJumpTableInfo() {
826 if (
JT.empty())
return;
830 OutStreamer->switchSection(ReadOnlySec);
833 for (
unsigned JTI = 0,
e =
JT.size(); JTI !=
e; ++JTI) {
834 const std::vector<MachineBasicBlock*> &JTBBs =
JT[JTI].MBBs;
837 if (JTBBs.empty())
continue;
839 unsigned Size = AFI->getJumpTableEntrySize(JTI);
840 emitAlignment(
Align(Size));
841 OutStreamer->emitLabel(GetJTISymbol(JTI));
843 const MCSymbol *BaseSym = AArch64FI->getJumpTableEntryPCRelSymbol(JTI);
846 for (
auto *JTBB : JTBBs) {
859 OutStreamer->emitValue(
Value, Size);
864 void AArch64AsmPrinter::emitFunctionEntryLabel() {
866 MF->getFunction().getCallingConv() ==
889 Register ScratchReg =
MI.getOperand(1).getReg();
891 STI->getRegisterInfo()->getSubReg(ScratchReg, AArch64::sub_32);
892 Register TableReg =
MI.getOperand(2).getReg();
893 Register EntryReg =
MI.getOperand(3).getReg();
894 int JTIdx =
MI.getOperand(4).getIndex();
895 int Size = AArch64FI->getJumpTableEntrySize(JTIdx);
905 Label = MF->getContext().createTempSymbol();
906 AArch64FI->setJumpTableEntryInfo(JTIdx, Size, Label);
913 .addExpr(LabelExpr));
918 case 1: LdrOpcode = AArch64::LDRBBroX;
break;
919 case 2: LdrOpcode = AArch64::LDRHHroX;
break;
920 case 4: LdrOpcode = AArch64::LDRSWroX;
break;
926 .addReg(Size == 4 ? ScratchReg : ScratchRegW)
930 .addImm(Size == 1 ? 0 : 1));
938 .addImm(Size == 4 ? 0 : 2));
943 unsigned Opcode =
MI.getOpcode();
945 assert(STI->hasMTE() || Opcode != AArch64::MOPSMemorySetTaggingPseudo);
947 const auto Ops = [Opcode]() -> std::array<unsigned, 3> {
948 if (Opcode == AArch64::MOPSMemoryCopyPseudo)
949 return {AArch64::CPYFP, AArch64::CPYFM, AArch64::CPYFE};
950 if (Opcode == AArch64::MOPSMemoryMovePseudo)
951 return {AArch64::CPYP, AArch64::CPYM, AArch64::CPYE};
952 if (Opcode == AArch64::MOPSMemorySetPseudo)
953 return {AArch64::SETP, AArch64::SETM, AArch64::SETE};
954 if (Opcode == AArch64::MOPSMemorySetTaggingPseudo)
955 return {AArch64::SETGP, AArch64::SETGM, AArch64::MOPSSETGE};
958 const bool IsSet = Opcode == AArch64::MOPSMemorySetPseudo ||
959 Opcode == AArch64::MOPSMemorySetTaggingPseudo;
961 for (
auto Op : Ops) {
965 MCIB.addReg(
MI.getOperand(
i++).getReg());
966 MCIB.addReg(
MI.getOperand(
i++).getReg());
968 MCIB.addReg(
MI.getOperand(
i++).getReg());
970 MCIB.addReg(
MI.getOperand(
i++).getReg());
971 MCIB.addReg(
MI.getOperand(
i++).getReg());
972 MCIB.addReg(
MI.getOperand(
i++).getReg());
974 EmitToStreamer(OutStreamer, MCIB);
983 MCSymbol *MILabel = Ctx.createTempSymbol();
987 assert(NumNOPBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
993 while (NumNOPBytes > 0) {
994 if (MII ==
MBB.
end() || MII->isCall() ||
995 MII->getOpcode() == AArch64::DBG_VALUE ||
996 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
997 MII->getOpcode() == TargetOpcode::STACKMAP)
1004 for (
unsigned i = 0;
i < NumNOPBytes;
i += 4)
1005 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1013 MCSymbol *MILabel = Ctx.createTempSymbol();
1019 int64_t CallTarget = Opers.getCallTarget().getImm();
1020 unsigned EncodedBytes = 0;
1022 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
1023 "High 16 bits of call target should be zero.");
1024 Register ScratchReg =
MI.getOperand(Opers.getNextScratchIdx()).getReg();
1029 .addImm((CallTarget >> 32) & 0xFFFF)
1034 .addImm((CallTarget >> 16) & 0xFFFF)
1039 .addImm(CallTarget & 0xFFFF)
1041 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::BLR).addReg(ScratchReg));
1044 unsigned NumBytes = Opers.getNumPatchBytes();
1045 assert(NumBytes >= EncodedBytes &&
1046 "Patchpoint can't request size less than the length of a call.");
1047 assert((NumBytes - EncodedBytes) % 4 == 0 &&
1048 "Invalid number of NOP bytes requested!");
1049 for (
unsigned i = EncodedBytes;
i < NumBytes;
i += 4)
1050 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1056 if (
unsigned PatchBytes = SOpers.getNumPatchBytes()) {
1057 assert(PatchBytes % 4 == 0 &&
"Invalid number of NOP bytes requested!");
1058 for (
unsigned i = 0;
i < PatchBytes;
i += 4)
1059 EmitToStreamer(OutStreamer,
MCInstBuilder(AArch64::HINT).addImm(0));
1064 unsigned CallOpcode;
1065 switch (CallTarget.
getType()) {
1068 MCInstLowering.lowerOperand(CallTarget, CallTargetMCOp);
1077 CallOpcode = AArch64::BLR;
1084 EmitToStreamer(OutStreamer,
1089 MCSymbol *MILabel = Ctx.createTempSymbol();
1094 void AArch64AsmPrinter::LowerFAULTING_OP(
const MachineInstr &FaultingMI) {
1103 unsigned OperandsBeginIdx = 4;
1106 MCSymbol *FaultingLabel = Ctx.createTempSymbol();
1110 FM.recordFaultingOp(FK, FaultingLabel, HandlerLabel);
1113 MI.setOpcode(Opcode);
1122 lowerOperand(*
I, Dest);
1123 MI.addOperand(Dest);
1131 Register DestReg =
MI.getOperand(0).getReg();
1132 if (STI->hasZeroCycleZeroingFP() && !STI->hasZeroCycleZeroingFPWorkaround() &&
1135 if (AArch64::H0 <= DestReg && DestReg <= AArch64::H31)
1136 DestReg = AArch64::D0 + (DestReg - AArch64::H0);
1137 else if (AArch64::S0 <= DestReg && DestReg <= AArch64::S31)
1138 DestReg = AArch64::D0 + (DestReg - AArch64::S0);
1140 assert(AArch64::D0 <= DestReg && DestReg <= AArch64::D31);
1143 MOVI.setOpcode(AArch64::MOVID);
1146 EmitToStreamer(*OutStreamer,
MOVI);
1149 switch (
MI.getOpcode()) {
1151 case AArch64::FMOVH0:
1156 case AArch64::FMOVS0:
1161 case AArch64::FMOVD0:
1167 EmitToStreamer(*OutStreamer, FMov);
1173 #include "AArch64GenMCPseudoLowering.inc"
1175 void AArch64AsmPrinter::emitInstruction(
const MachineInstr *
MI) {
1177 if (emitPseudoExpansionLowering(*OutStreamer,
MI))
1181 for (
auto &Opd :
MI->operands()) {
1182 if (Opd.isSymbol() &&
StringRef(Opd.getSymbolName()) ==
1183 "swift_async_extendedFramePointerFlags") {
1184 ShouldEmitWeakSwiftAsyncExtendedFramePointerFlags =
true;
1189 if (AArch64FI->getLOHRelated().count(
MI)) {
1191 MCSymbol *LOHLabel = createTempSymbol(
"loh");
1193 LOHInstToLabel[
MI] = LOHLabel;
1200 switch (
MI->getOpcode()) {
1203 case AArch64::HINT: {
1208 if (CurrentPatchableFunctionEntrySym &&
1209 CurrentPatchableFunctionEntrySym == CurrentFnBegin &&
1210 MI == &MF->front().front()) {
1211 int64_t
Imm =
MI->getOperand(0).getImm();
1212 if ((
Imm & 32) && (
Imm & 6)) {
1214 MCInstLowering.Lower(
MI, Inst);
1215 EmitToStreamer(*OutStreamer, Inst);
1216 CurrentPatchableFunctionEntrySym = createTempSymbol(
"patch");
1217 OutStreamer->
emitLabel(CurrentPatchableFunctionEntrySym);
1223 case AArch64::MOVMCSym: {
1224 Register DestReg =
MI->getOperand(0).getReg();
1232 MCInstLowering.lowerOperand(Hi_MOSym, Hi_MCSym);
1233 MCInstLowering.lowerOperand(Lo_MOSym, Lo_MCSym);
1240 EmitToStreamer(*OutStreamer, MovZ);
1248 EmitToStreamer(*OutStreamer, MovK);
1251 case AArch64::MOVIv2d_ns:
1254 if (STI->hasZeroCycleZeroingFPWorkaround() &&
1255 MI->getOperand(1).getImm() == 0) {
1257 TmpInst.
setOpcode(AArch64::MOVIv16b_ns);
1260 EmitToStreamer(*OutStreamer, TmpInst);
1265 case AArch64::DBG_VALUE:
1266 case AArch64::DBG_VALUE_LIST:
1270 PrintDebugValueComment(
MI, OS);
1275 case AArch64::EMITBKEY: {
1288 case AArch64::EMITMTETAGGED: {
1302 case AArch64::TCRETURNri:
1303 case AArch64::TCRETURNriBTI:
1304 case AArch64::TCRETURNriALL: {
1308 EmitToStreamer(*OutStreamer, TmpInst);
1311 case AArch64::TCRETURNdi: {
1313 MCInstLowering.lowerOperand(
MI->getOperand(0), Dest);
1317 EmitToStreamer(*OutStreamer, TmpInst);
1320 case AArch64::SpeculationBarrierISBDSBEndBB: {
1325 EmitToStreamer(*OutStreamer, TmpInstDSB);
1329 EmitToStreamer(*OutStreamer, TmpInstISB);
1332 case AArch64::SpeculationBarrierSBEndBB: {
1336 EmitToStreamer(*OutStreamer, TmpInstSB);
1349 MCOperand Sym, SymTLSDescLo12, SymTLSDesc;
1352 MCInstLowering.lowerOperand(MO_Sym, Sym);
1353 MCInstLowering.lowerOperand(MO_TLSDESC_LO12, SymTLSDescLo12);
1354 MCInstLowering.lowerOperand(MO_TLSDESC, SymTLSDesc);
1360 EmitToStreamer(*OutStreamer, Adrp);
1363 if (STI->isTargetILP32()) {
1373 EmitToStreamer(*OutStreamer, Ldr);
1376 if (STI->isTargetILP32()) {
1377 Add.setOpcode(AArch64::ADDWri);
1381 Add.setOpcode(AArch64::ADDXri);
1385 Add.addOperand(SymTLSDescLo12);
1387 EmitToStreamer(*OutStreamer, Add);
1392 TLSDescCall.
setOpcode(AArch64::TLSDESCCALL);
1394 EmitToStreamer(*OutStreamer, TLSDescCall);
1399 EmitToStreamer(*OutStreamer, Blr);
1404 case AArch64::JumpTableDest32:
1405 case AArch64::JumpTableDest16:
1406 case AArch64::JumpTableDest8:
1407 LowerJumpTableDest(*OutStreamer, *
MI);
1410 case AArch64::FMOVH0:
1411 case AArch64::FMOVS0:
1412 case AArch64::FMOVD0:
1416 case AArch64::MOPSMemoryCopyPseudo:
1417 case AArch64::MOPSMemoryMovePseudo:
1418 case AArch64::MOPSMemorySetPseudo:
1419 case AArch64::MOPSMemorySetTaggingPseudo:
1420 LowerMOPS(*OutStreamer, *
MI);
1423 case TargetOpcode::STACKMAP:
1424 return LowerSTACKMAP(*OutStreamer, SM, *
MI);
1426 case TargetOpcode::PATCHPOINT:
1427 return LowerPATCHPOINT(*OutStreamer, SM, *
MI);
1429 case TargetOpcode::STATEPOINT:
1430 return LowerSTATEPOINT(*OutStreamer, SM, *
MI);
1432 case TargetOpcode::FAULTING_OP:
1433 return LowerFAULTING_OP(*
MI);
1435 case TargetOpcode::PATCHABLE_FUNCTION_ENTER:
1436 LowerPATCHABLE_FUNCTION_ENTER(*
MI);
1439 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1440 LowerPATCHABLE_FUNCTION_EXIT(*
MI);
1443 case TargetOpcode::PATCHABLE_TAIL_CALL:
1444 LowerPATCHABLE_TAIL_CALL(*
MI);
1447 case AArch64::HWASAN_CHECK_MEMACCESS:
1448 case AArch64::HWASAN_CHECK_MEMACCESS_SHORTGRANULES:
1449 LowerHWASAN_CHECK_MEMACCESS(*
MI);
1452 case AArch64::SEH_StackAlloc:
1456 case AArch64::SEH_SaveFPLR:
1460 case AArch64::SEH_SaveFPLR_X:
1461 assert(
MI->getOperand(0).getImm() < 0 &&
1462 "Pre increment SEH opcode must have a negative offset");
1466 case AArch64::SEH_SaveReg:
1468 MI->getOperand(1).getImm());
1471 case AArch64::SEH_SaveReg_X:
1472 assert(
MI->getOperand(1).getImm() < 0 &&
1473 "Pre increment SEH opcode must have a negative offset");
1475 -
MI->getOperand(1).getImm());
1478 case AArch64::SEH_SaveRegP:
1479 if (
MI->getOperand(1).getImm() == 30 &&
MI->getOperand(0).getImm() >= 19 &&
1480 MI->getOperand(0).getImm() <= 28) {
1481 assert((
MI->getOperand(0).getImm() - 19) % 2 == 0 &&
1482 "Register paired with LR must be odd");
1484 MI->getOperand(2).getImm());
1487 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1488 "Non-consecutive registers not allowed for save_regp");
1490 MI->getOperand(2).getImm());
1493 case AArch64::SEH_SaveRegP_X:
1494 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1495 "Non-consecutive registers not allowed for save_regp_x");
1496 assert(
MI->getOperand(2).getImm() < 0 &&
1497 "Pre increment SEH opcode must have a negative offset");
1499 -
MI->getOperand(2).getImm());
1502 case AArch64::SEH_SaveFReg:
1504 MI->getOperand(1).getImm());
1507 case AArch64::SEH_SaveFReg_X:
1508 assert(
MI->getOperand(1).getImm() < 0 &&
1509 "Pre increment SEH opcode must have a negative offset");
1511 -
MI->getOperand(1).getImm());
1514 case AArch64::SEH_SaveFRegP:
1515 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1516 "Non-consecutive registers not allowed for save_regp");
1518 MI->getOperand(2).getImm());
1521 case AArch64::SEH_SaveFRegP_X:
1522 assert((
MI->getOperand(1).getImm() -
MI->getOperand(0).getImm() == 1) &&
1523 "Non-consecutive registers not allowed for save_regp_x");
1524 assert(
MI->getOperand(2).getImm() < 0 &&
1525 "Pre increment SEH opcode must have a negative offset");
1527 -
MI->getOperand(2).getImm());
1530 case AArch64::SEH_SetFP:
1534 case AArch64::SEH_AddFP:
1538 case AArch64::SEH_Nop:
1542 case AArch64::SEH_PrologEnd:
1546 case AArch64::SEH_EpilogStart:
1550 case AArch64::SEH_EpilogEnd:
1557 MCInstLowering.Lower(
MI, TmpInst);
1558 EmitToStreamer(*OutStreamer, TmpInst);