[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