[llvm] d6481dc - [AArch64][Windows] Add MC support for save_any_reg.
Eli Friedman via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 18 11:45:35 PDT 2022
Author: Eli Friedman
Date: 2022-10-18T11:45:27-07:00
New Revision: d6481dc88cd133359a7d043bc24ceb7dadfc2466
URL: https://github.com/llvm/llvm-project/commit/d6481dc88cd133359a7d043bc24ceb7dadfc2466
DIFF: https://github.com/llvm/llvm-project/commit/d6481dc88cd133359a7d043bc24ceb7dadfc2466.diff
LOG: [AArch64][Windows] Add MC support for save_any_reg.
Representing this as 12 separate operations is a bit ugly, but
trying to represent the different modes using a bitfield seemed worse.
Differential Revision: https://reviews.llvm.org/D135417
Added:
Modified:
llvm/include/llvm/Support/Win64EH.h
llvm/lib/MC/MCWin64EH.cpp
llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp
llvm/test/MC/AArch64/seh.s
Removed:
################################################################################
diff --git a/llvm/include/llvm/Support/Win64EH.h b/llvm/include/llvm/Support/Win64EH.h
index 93401bdc131eb..e84fd6d72bedb 100644
--- a/llvm/include/llvm/Support/Win64EH.h
+++ b/llvm/include/llvm/Support/Win64EH.h
@@ -62,6 +62,19 @@ enum UnwindOpcodes {
UOP_Context,
UOP_ClearUnwoundToCall,
UOP_PACSignLR,
+ UOP_SaveAnyRegI,
+ UOP_SaveAnyRegIP,
+ UOP_SaveAnyRegD,
+ UOP_SaveAnyRegDP,
+ UOP_SaveAnyRegQ,
+ UOP_SaveAnyRegQP,
+ UOP_SaveAnyRegIX,
+ UOP_SaveAnyRegIPX,
+ UOP_SaveAnyRegDX,
+ UOP_SaveAnyRegDPX,
+ UOP_SaveAnyRegQX,
+ UOP_SaveAnyRegQPX,
+
// The following set of unwind opcodes is for ARM. They are documented at
// https://docs.microsoft.com/en-us/cpp/build/arm-exception-handling
diff --git a/llvm/lib/MC/MCWin64EH.cpp b/llvm/lib/MC/MCWin64EH.cpp
index 2b152a33a5535..a0ba62a472c1a 100644
--- a/llvm/lib/MC/MCWin64EH.cpp
+++ b/llvm/lib/MC/MCWin64EH.cpp
@@ -417,6 +417,20 @@ static uint32_t ARM64CountOfUnwindCodes(ArrayRef<WinEH::Instruction> Insns) {
case Win64EH::UOP_PACSignLR:
Count += 1;
break;
+ case Win64EH::UOP_SaveAnyRegI:
+ case Win64EH::UOP_SaveAnyRegIP:
+ case Win64EH::UOP_SaveAnyRegD:
+ case Win64EH::UOP_SaveAnyRegDP:
+ case Win64EH::UOP_SaveAnyRegQ:
+ case Win64EH::UOP_SaveAnyRegQP:
+ case Win64EH::UOP_SaveAnyRegIX:
+ case Win64EH::UOP_SaveAnyRegIPX:
+ case Win64EH::UOP_SaveAnyRegDX:
+ case Win64EH::UOP_SaveAnyRegDPX:
+ case Win64EH::UOP_SaveAnyRegQX:
+ case Win64EH::UOP_SaveAnyRegQPX:
+ Count += 3;
+ break;
}
}
return Count;
@@ -587,6 +601,37 @@ static void ARM64EmitUnwindCode(MCStreamer &streamer,
b = 0xFC;
streamer.emitInt8(b);
break;
+ case Win64EH::UOP_SaveAnyRegI:
+ case Win64EH::UOP_SaveAnyRegIP:
+ case Win64EH::UOP_SaveAnyRegD:
+ case Win64EH::UOP_SaveAnyRegDP:
+ case Win64EH::UOP_SaveAnyRegQ:
+ case Win64EH::UOP_SaveAnyRegQP:
+ case Win64EH::UOP_SaveAnyRegIX:
+ case Win64EH::UOP_SaveAnyRegIPX:
+ case Win64EH::UOP_SaveAnyRegDX:
+ case Win64EH::UOP_SaveAnyRegDPX:
+ case Win64EH::UOP_SaveAnyRegQX:
+ case Win64EH::UOP_SaveAnyRegQPX: {
+ // This assumes the opcodes are listed in the enum in a particular order.
+ int Op = inst.Operation - Win64EH::UOP_SaveAnyRegI;
+ int Writeback = Op / 6;
+ int Paired = Op % 2;
+ int Mode = (Op / 2) % 3;
+ int Offset = inst.Offset >> 3;
+ if (Writeback || Paired || Mode == 2)
+ Offset >>= 1;
+ if (Writeback)
+ --Offset;
+ b = 0xE7;
+ streamer.emitInt8(b);
+ assert(inst.Register < 32);
+ b = inst.Register | (Writeback << 5) | (Paired << 6);
+ streamer.emitInt8(b);
+ b = Offset | (Mode << 6);
+ streamer.emitInt8(b);
+ break;
+ }
}
}
diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 6dbc3040f7391..9bfd98595a5d6 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -219,6 +219,7 @@ class AArch64AsmParser : public MCTargetAsmParser {
bool parseDirectiveSEHContext(SMLoc L);
bool parseDirectiveSEHClearUnwoundToCall(SMLoc L);
bool parseDirectiveSEHPACSignLR(SMLoc L);
+ bool parseDirectiveSEHSaveAnyReg(SMLoc L, bool Paired, bool Writeback);
bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
SmallVectorImpl<SMLoc> &Loc);
@@ -6102,6 +6103,14 @@ bool AArch64AsmParser::ParseDirective(AsmToken DirectiveID) {
parseDirectiveSEHClearUnwoundToCall(Loc);
else if (IDVal == ".seh_pac_sign_lr")
parseDirectiveSEHPACSignLR(Loc);
+ else if (IDVal == ".seh_save_any_reg")
+ parseDirectiveSEHSaveAnyReg(Loc, false, false);
+ else if (IDVal == ".seh_save_any_reg_p")
+ parseDirectiveSEHSaveAnyReg(Loc, true, false);
+ else if (IDVal == ".seh_save_any_reg_x")
+ parseDirectiveSEHSaveAnyReg(Loc, false, true);
+ else if (IDVal == ".seh_save_any_reg_px")
+ parseDirectiveSEHSaveAnyReg(Loc, true, true);
else
return true;
} else
@@ -6785,6 +6794,84 @@ bool AArch64AsmParser::parseDirectiveSEHPACSignLR(SMLoc L) {
return false;
}
+/// parseDirectiveSEHSaveAnyReg
+/// ::= .seh_save_any_reg
+/// ::= .seh_save_any_reg_p
+/// ::= .seh_save_any_reg_x
+/// ::= .seh_save_any_reg_px
+bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(SMLoc L, bool Paired,
+ bool Writeback) {
+ unsigned Reg;
+ SMLoc Start, End;
+ int64_t Offset;
+ if (check(ParseRegister(Reg, Start, End), getLoc(), "expected register") ||
+ parseComma() || parseImmExpr(Offset))
+ return true;
+
+ if (Reg == AArch64::FP || Reg == AArch64::LR ||
+ (Reg >= AArch64::X0 && Reg <= AArch64::X28)) {
+ if (Offset < 0 || Offset % (Paired || Writeback ? 16 : 8))
+ return Error(L, "invalid save_any_reg offset");
+ unsigned EncodedReg;
+ if (Reg == AArch64::FP)
+ EncodedReg = 29;
+ else if (Reg == AArch64::LR)
+ EncodedReg = 30;
+ else
+ EncodedReg = Reg - AArch64::X0;
+ if (Paired) {
+ if (Reg == AArch64::LR)
+ return Error(Start, "lr cannot be paired with another register");
+ if (Writeback)
+ getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg, Offset);
+ else
+ getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg, Offset);
+ } else {
+ if (Writeback)
+ getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg, Offset);
+ else
+ getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg, Offset);
+ }
+ } else if (Reg >= AArch64::D0 && Reg <= AArch64::D31) {
+ unsigned EncodedReg = Reg - AArch64::D0;
+ if (Offset < 0 || Offset % (Paired || Writeback ? 16 : 8))
+ return Error(L, "invalid save_any_reg offset");
+ if (Paired) {
+ if (Reg == AArch64::D31)
+ return Error(Start, "d31 cannot be paired with another register");
+ if (Writeback)
+ getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg, Offset);
+ else
+ getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg, Offset);
+ } else {
+ if (Writeback)
+ getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg, Offset);
+ else
+ getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg, Offset);
+ }
+ } else if (Reg >= AArch64::Q0 && Reg <= AArch64::Q31) {
+ unsigned EncodedReg = Reg - AArch64::Q0;
+ if (Offset < 0 || Offset % 16)
+ return Error(L, "invalid save_any_reg offset");
+ if (Paired) {
+ if (Reg == AArch64::Q31)
+ return Error(Start, "q31 cannot be paired with another register");
+ if (Writeback)
+ getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg, Offset);
+ else
+ getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg, Offset);
+ } else {
+ if (Writeback)
+ getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg, Offset);
+ else
+ getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg, Offset);
+ }
+ } else {
+ return Error(Start, "save_any_reg register must be x, q or d register");
+ }
+ return false;
+}
+
bool
AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
AArch64MCExpr::VariantKind &ELFRefKind,
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
index ec09ca2ba67d2..e4003a6c1f7b1 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp
@@ -111,6 +111,43 @@ class AArch64TargetAsmStreamer : public AArch64TargetStreamer {
OS << "\t.seh_pac_sign_lr\n";
}
+ void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_any_reg\tx" << Reg << ", " << Offset << "\n";
+ }
+ void emitARM64WinCFISaveAnyRegIP(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_any_reg_p\tx" << Reg << ", " << Offset << "\n";
+ }
+ void emitARM64WinCFISaveAnyRegD(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_any_reg\td" << Reg << ", " << Offset << "\n";
+ }
+ void emitARM64WinCFISaveAnyRegDP(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_any_reg_p\td" << Reg << ", " << Offset << "\n";
+ }
+ void emitARM64WinCFISaveAnyRegQ(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_any_reg\tq" << Reg << ", " << Offset << "\n";
+ }
+ void emitARM64WinCFISaveAnyRegQP(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_any_reg_p\tq" << Reg << ", " << Offset << "\n";
+ }
+ void emitARM64WinCFISaveAnyRegIX(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_any_reg_x\tx" << Reg << ", " << Offset << "\n";
+ }
+ void emitARM64WinCFISaveAnyRegIPX(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_any_reg_px\tx" << Reg << ", " << Offset << "\n";
+ }
+ void emitARM64WinCFISaveAnyRegDX(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_any_reg_x\td" << Reg << ", " << Offset << "\n";
+ }
+ void emitARM64WinCFISaveAnyRegDPX(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_any_reg_px\td" << Reg << ", " << Offset << "\n";
+ }
+ void emitARM64WinCFISaveAnyRegQX(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_any_reg_x\tq" << Reg << ", " << Offset << "\n";
+ }
+ void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset) override {
+ OS << "\t.seh_save_any_reg_px\tq" << Reg << ", " << Offset << "\n";
+ }
+
public:
AArch64TargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
};
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
index 0a13e8526ec62..d6dc4a529cf45 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64TargetStreamer.h
@@ -68,6 +68,18 @@ class AArch64TargetStreamer : public MCTargetStreamer {
virtual void emitARM64WinCFIContext() {}
virtual void emitARM64WinCFIClearUnwoundToCall() {}
virtual void emitARM64WinCFIPACSignLR() {}
+ virtual void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset) {}
+ virtual void emitARM64WinCFISaveAnyRegIP(unsigned Reg, int Offset) {}
+ virtual void emitARM64WinCFISaveAnyRegD(unsigned Reg, int Offset) {}
+ virtual void emitARM64WinCFISaveAnyRegDP(unsigned Reg, int Offset) {}
+ virtual void emitARM64WinCFISaveAnyRegQ(unsigned Reg, int Offset) {}
+ virtual void emitARM64WinCFISaveAnyRegQP(unsigned Reg, int Offset) {}
+ virtual void emitARM64WinCFISaveAnyRegIX(unsigned Reg, int Offset) {}
+ virtual void emitARM64WinCFISaveAnyRegIPX(unsigned Reg, int Offset) {}
+ virtual void emitARM64WinCFISaveAnyRegDX(unsigned Reg, int Offset) {}
+ virtual void emitARM64WinCFISaveAnyRegDPX(unsigned Reg, int Offset) {}
+ virtual void emitARM64WinCFISaveAnyRegQX(unsigned Reg, int Offset) {}
+ virtual void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset) {}
private:
std::unique_ptr<AssemblerConstantPools> ConstantPools;
@@ -122,6 +134,18 @@ class AArch64TargetWinCOFFStreamer : public llvm::AArch64TargetStreamer {
void emitARM64WinCFIContext() override;
void emitARM64WinCFIClearUnwoundToCall() override;
void emitARM64WinCFIPACSignLR() override;
+ void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset) override;
+ void emitARM64WinCFISaveAnyRegIP(unsigned Reg, int Offset) override;
+ void emitARM64WinCFISaveAnyRegD(unsigned Reg, int Offset) override;
+ void emitARM64WinCFISaveAnyRegDP(unsigned Reg, int Offset) override;
+ void emitARM64WinCFISaveAnyRegQ(unsigned Reg, int Offset) override;
+ void emitARM64WinCFISaveAnyRegQP(unsigned Reg, int Offset) override;
+ void emitARM64WinCFISaveAnyRegIX(unsigned Reg, int Offset) override;
+ void emitARM64WinCFISaveAnyRegIPX(unsigned Reg, int Offset) override;
+ void emitARM64WinCFISaveAnyRegDX(unsigned Reg, int Offset) override;
+ void emitARM64WinCFISaveAnyRegDPX(unsigned Reg, int Offset) override;
+ void emitARM64WinCFISaveAnyRegQX(unsigned Reg, int Offset) override;
+ void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset) override;
private:
void emitARM64WinUnwindCode(unsigned UnwindCode, int Reg, int Offset);
diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp
index 6ba230bb304df..4c8c2b437069c 100644
--- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp
+++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFStreamer.cpp
@@ -227,6 +227,66 @@ void AArch64TargetWinCOFFStreamer::emitARM64WinCFIPACSignLR() {
emitARM64WinUnwindCode(Win64EH::UOP_PACSignLR, -1, 0);
}
+void AArch64TargetWinCOFFStreamer::emitARM64WinCFISaveAnyRegI(unsigned Reg,
+ int Offset) {
+ emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegI, Reg, Offset);
+}
+
+void AArch64TargetWinCOFFStreamer::emitARM64WinCFISaveAnyRegIP(unsigned Reg,
+ int Offset) {
+ emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegIP, Reg, Offset);
+}
+
+void AArch64TargetWinCOFFStreamer::emitARM64WinCFISaveAnyRegD(unsigned Reg,
+ int Offset) {
+ emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegD, Reg, Offset);
+}
+
+void AArch64TargetWinCOFFStreamer::emitARM64WinCFISaveAnyRegDP(unsigned Reg,
+ int Offset) {
+ emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegDP, Reg, Offset);
+}
+
+void AArch64TargetWinCOFFStreamer::emitARM64WinCFISaveAnyRegQ(unsigned Reg,
+ int Offset) {
+ emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegQ, Reg, Offset);
+}
+
+void AArch64TargetWinCOFFStreamer::emitARM64WinCFISaveAnyRegQP(unsigned Reg,
+ int Offset) {
+ emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegQP, Reg, Offset);
+}
+
+void AArch64TargetWinCOFFStreamer::emitARM64WinCFISaveAnyRegIX(unsigned Reg,
+ int Offset) {
+ emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegIX, Reg, Offset);
+}
+
+void AArch64TargetWinCOFFStreamer::emitARM64WinCFISaveAnyRegIPX(unsigned Reg,
+ int Offset) {
+ emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegIPX, Reg, Offset);
+}
+
+void AArch64TargetWinCOFFStreamer::emitARM64WinCFISaveAnyRegDX(unsigned Reg,
+ int Offset) {
+ emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegDX, Reg, Offset);
+}
+
+void AArch64TargetWinCOFFStreamer::emitARM64WinCFISaveAnyRegDPX(unsigned Reg,
+ int Offset) {
+ emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegDPX, Reg, Offset);
+}
+
+void AArch64TargetWinCOFFStreamer::emitARM64WinCFISaveAnyRegQX(unsigned Reg,
+ int Offset) {
+ emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegQX, Reg, Offset);
+}
+
+void AArch64TargetWinCOFFStreamer::emitARM64WinCFISaveAnyRegQPX(unsigned Reg,
+ int Offset) {
+ emitARM64WinUnwindCode(Win64EH::UOP_SaveAnyRegQPX, Reg, Offset);
+}
+
MCWinCOFFStreamer *llvm::createAArch64WinCOFFStreamer(
MCContext &Context, std::unique_ptr<MCAsmBackend> MAB,
std::unique_ptr<MCObjectWriter> OW, std::unique_ptr<MCCodeEmitter> Emitter,
diff --git a/llvm/test/MC/AArch64/seh.s b/llvm/test/MC/AArch64/seh.s
index 81569bab378ad..4faf7daaa33ed 100644
--- a/llvm/test/MC/AArch64/seh.s
+++ b/llvm/test/MC/AArch64/seh.s
@@ -20,7 +20,7 @@
// CHECK-NEXT: }
// CHECK: Section {
// CHECK: Name: .xdata
-// CHECK: RawDataSize: 56
+// CHECK: RawDataSize: 92
// CHECK: RelocationCount: 1
// CHECK: Characteristics [
// CHECK-NEXT: ALIGN_4BYTES
@@ -41,7 +41,7 @@
// CHECK-NEXT: Relocations [
// CHECK-NEXT: Section (4) .xdata {
-// CHECK-NEXT: 0x2C IMAGE_REL_ARM64_ADDR32NB __C_specific_handler
+// CHECK-NEXT: 0x50 IMAGE_REL_ARM64_ADDR32NB __C_specific_handler
// CHECK-NEXT: }
// CHECK-NEXT: Section (5) .pdata {
// CHECK-NEXT: 0x0 IMAGE_REL_ARM64_ADDR32NB .text
@@ -54,8 +54,20 @@
// CHECK-NEXT: Function: func
// CHECK-NEXT: ExceptionRecord: .xdata
// CHECK-NEXT: ExceptionData {
-// CHECK-NEXT: FunctionLength: 104
+// CHECK-NEXT: FunctionLength: 152
// CHECK: Prologue [
+// CHECK-NEXT: 0xe76983 ; stp q9, q10, [sp, #-64]!
+// CHECK-NEXT: 0xe73d83 ; str q29, [sp, #-64]!
+// CHECK-NEXT: 0xe76243 ; stp d2, d3, [sp, #-64]!
+// CHECK-NEXT: 0xe73f43 ; str d31, [sp, #-64]!
+// CHECK-NEXT: 0xe77d03 ; stp x29, x30, [sp, #-64]!
+// CHECK-NEXT: 0xe73e03 ; str x30, [sp, #-64]!
+// CHECK-NEXT: 0xe74384 ; stp q3, q4, [sp, #64]
+// CHECK-NEXT: 0xe71e84 ; str q30, [sp, #64]
+// CHECK-NEXT: 0xe74444 ; stp d4, d5, [sp, #64]
+// CHECK-NEXT: 0xe71d48 ; str d29, [sp, #64]
+// CHECK-NEXT: 0xe74104 ; stp x1, x2, [sp, #64]
+// CHECK-NEXT: 0xe70008 ; str x0, [sp, #64]
// CHECK-NEXT: 0xfc ; pacibsp
// CHECK-NEXT: 0xec ; clear unwound to call
// CHECK-NEXT: 0xea ; context
@@ -83,8 +95,8 @@
// CHECK-NEXT: ]
// CHECK-NEXT: EpilogueScopes [
// CHECK-NEXT: EpilogueScope {
-// CHECK-NEXT: StartOffset: 24
-// CHECK-NEXT: EpilogueStartIndex: 32
+// CHECK-NEXT: StartOffset: 36
+// CHECK-NEXT: EpilogueStartIndex: 68
// CHECK-NEXT: Opcodes [
// CHECK-NEXT: 0x01 ; add sp, #16
// CHECK-NEXT: 0xe4 ; end
@@ -154,6 +166,30 @@ func:
.seh_clear_unwound_to_call
pacibsp
.seh_pac_sign_lr
+ nop
+ .seh_save_any_reg x0, 64
+ nop
+ .seh_save_any_reg_p x1, 64
+ nop
+ .seh_save_any_reg d29, 64
+ nop
+ .seh_save_any_reg_p d4, 64
+ nop
+ .seh_save_any_reg q30, 64
+ nop
+ .seh_save_any_reg_p q3, 64
+ nop
+ .seh_save_any_reg_x lr, 64
+ nop
+ .seh_save_any_reg_px fp, 64
+ nop
+ .seh_save_any_reg_x d31, 64
+ nop
+ .seh_save_any_reg_px d2, 64
+ nop
+ .seh_save_any_reg_x q29, 64
+ nop
+ .seh_save_any_reg_px q9, 64
.seh_endprologue
nop
.seh_startepilogue
More information about the llvm-commits
mailing list