DavidSpickett updated this revision to Diff 557008.
DavidSpickett added a comment.

Rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D159503/new/

https://reviews.llvm.org/D159503

Files:
  lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
  lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
  lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
  lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h

Index: lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
===================================================================
--- lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
+++ lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h
@@ -135,12 +135,14 @@
   bool IsMTEReg(unsigned reg) const;
   bool IsTLSReg(unsigned reg) const;
   bool IsSMEReg(unsigned reg) const;
+  bool IsSMERegZA(unsigned reg) const;
 
   uint32_t GetRegNumSVEZ0() const;
   uint32_t GetRegNumSVEFFR() const;
   uint32_t GetRegNumFPCR() const;
   uint32_t GetRegNumFPSR() const;
   uint32_t GetRegNumSVEVG() const;
+  uint32_t GetRegNumSMESVG() const;
   uint32_t GetPAuthOffset() const;
   uint32_t GetMTEOffset() const;
   uint32_t GetTLSOffset() const;
Index: lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
===================================================================
--- lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
+++ lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.cpp
@@ -83,10 +83,11 @@
     // Only present when SME is present
     DEFINE_EXTENSION_REG(tpidr2)};
 
-static lldb_private::RegisterInfo g_register_infos_sme[] =
+static lldb_private::RegisterInfo g_register_infos_sme[] = {
+    DEFINE_EXTENSION_REG(svg),
     // 16 is a default size we will change later.
-    {{"za", nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8,
-      KIND_ALL_INVALID, nullptr, nullptr, nullptr}};
+    {"za", nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8,
+     KIND_ALL_INVALID, nullptr, nullptr, nullptr}};
 
 // Number of register sets provided by this context.
 enum {
@@ -96,7 +97,7 @@
   k_num_mte_register = 1,
   // Number of TLS registers is dynamic so it is not listed here.
   k_num_pauth_register = 2,
-  k_num_sme_register = 1,
+  k_num_sme_register = 2,
   k_num_register_sets_default = 2,
   k_num_register_sets = 3
 };
@@ -448,7 +449,7 @@
   // dynamic set and is just 1 register so we make an exception to const here.
   lldb_private::RegisterInfo *non_const_reginfo =
       const_cast<lldb_private::RegisterInfo *>(m_register_info_p);
-  non_const_reginfo[m_sme_regnum_collection[0]].byte_size =
+  non_const_reginfo[m_sme_regnum_collection[1]].byte_size =
       (za_vq * 16) * (za_vq * 16);
 }
 
@@ -471,6 +472,10 @@
   return sve_vg == reg;
 }
 
+bool RegisterInfoPOSIX_arm64::IsSMERegZA(unsigned reg) const {
+  return reg == m_sme_regnum_collection[1];
+}
+
 bool RegisterInfoPOSIX_arm64::IsPAuthReg(unsigned reg) const {
   return llvm::is_contained(pauth_regnum_collection, reg);
 }
@@ -497,6 +502,10 @@
 
 uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEVG() const { return sve_vg; }
 
+uint32_t RegisterInfoPOSIX_arm64::GetRegNumSMESVG() const {
+  return m_sme_regnum_collection[0];
+}
+
 uint32_t RegisterInfoPOSIX_arm64::GetPAuthOffset() const {
   return m_register_info_p[pauth_regnum_collection[0]].byte_offset;
 }
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.h
@@ -114,6 +114,12 @@
 
   uint64_t m_mte_ctrl_reg;
 
+  struct sme_pseudo_regs {
+    uint64_t svg_reg;
+  };
+
+  struct sme_pseudo_regs m_sme_pseudo_regs;
+
   struct tls_regs {
     uint64_t tpidr_reg;
     // Only valid when SME is present.
@@ -144,6 +150,8 @@
 
   Status WriteTLS();
 
+  Status ReadSMESVG();
+
   Status ReadZAHeader();
 
   Status ReadZA();
@@ -176,6 +184,8 @@
 
   void *GetTLSBuffer() { return &m_tls_regs; }
 
+  void *GetSMEPseudoBuffer() { return &m_sme_pseudo_regs; }
+
   void *GetSVEBuffer() { return m_sve_ptrace_payload.data(); }
 
   size_t GetSVEHeaderSize() { return sizeof(m_sve_header); }
@@ -194,6 +204,8 @@
 
   size_t GetTLSBufferSize() { return m_tls_size; }
 
+  size_t GetSMEPseudoBufferSize() { return sizeof(m_sme_pseudo_regs); }
+
   llvm::Error ReadHardwareDebugInfo() override;
 
   llvm::Error WriteHardwareDebugRegs(DREGType hwbType) override;
Index: lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -147,6 +147,7 @@
   ::memset(&m_sve_header, 0, sizeof(m_sve_header));
   ::memset(&m_pac_mask, 0, sizeof(m_pac_mask));
   ::memset(&m_tls_regs, 0, sizeof(m_tls_regs));
+  ::memset(&m_sme_pseudo_regs, 0, sizeof(m_sme_pseudo_regs));
 
   m_mte_ctrl_reg = 0;
 
@@ -329,30 +330,40 @@
     assert(offset < GetMTEControlSize());
     src = (uint8_t *)GetMTEControl() + offset;
   } else if (IsSME(reg)) {
-    error = ReadZAHeader();
-    if (error.Fail())
-      return error;
+    if (GetRegisterInfo().IsSMERegZA(reg)) {
+      error = ReadZAHeader();
+      if (error.Fail())
+        return error;
 
-    // If there is only a header and no registers, ZA is inactive. Read as 0
-    // in this case.
-    if (m_za_header.size == sizeof(m_za_header)) {
-      // This will get reconfigured/reset later, so we are safe to use it.
-      // ZA is a square of VL * VL and the ptrace buffer also includes the
-      // header itself.
-      m_za_ptrace_payload.resize(((m_za_header.vl) * (m_za_header.vl)) +
-                                 GetZAHeaderSize());
-      std::fill(m_za_ptrace_payload.begin(), m_za_ptrace_payload.end(), 0);
+      // If there is only a header and no registers, ZA is inactive. Read as 0
+      // in this case.
+      if (m_za_header.size == sizeof(m_za_header)) {
+        // This will get reconfigured/reset later, so we are safe to use it.
+        // ZA is a square of VL * VL and the ptrace buffer also includes the
+        // header itself.
+        m_za_ptrace_payload.resize(((m_za_header.vl) * (m_za_header.vl)) +
+                                   GetZAHeaderSize());
+        std::fill(m_za_ptrace_payload.begin(), m_za_ptrace_payload.end(), 0);
+      } else {
+        // ZA is active, read the real register.
+        error = ReadZA();
+        if (error.Fail())
+          return error;
+      }
+
+      // ZA is part of the SME set but uses a seperate member buffer for
+      // storage. Therefore its effective byte offset is always 0 even if it
+      // isn't 0 within the SME register set.
+      src = (uint8_t *)GetZABuffer() + GetZAHeaderSize();
     } else {
-      // ZA is active, read the real register.
-      error = ReadZA();
+      error = ReadSMESVG();
       if (error.Fail())
         return error;
-    }
 
-    // ZA is part of the SME set but uses a seperate member buffer for storage.
-    // Therefore its effective byte offset is always 0 even if it isn't 0 within
-    // the SME register set.
-    src = (uint8_t *)GetZABuffer() + GetZAHeaderSize();
+      offset = reg_info->byte_offset - GetRegisterInfo().GetSMEOffset();
+      assert(offset < GetSMEPseudoBufferSize());
+      src = (uint8_t *)GetSMEPseudoBuffer() + offset;
+    }
   } else
     return Status("failed - register wasn't recognized to be a GPR or an FPR, "
                   "write strategy unknown");
@@ -538,6 +549,9 @@
 
     return WriteTLS();
   } else if (IsSME(reg)) {
+    if (!GetRegisterInfo().IsSMERegZA(reg))
+      return Status("Writing to SVG is not supported.");
+
     error = ReadZA();
     if (error.Fail())
       return error;
@@ -1357,6 +1371,16 @@
   return sve_reg_offset;
 }
 
+Status NativeRegisterContextLinux_arm64::ReadSMESVG() {
+  // This register is the streaming vector length, so we will get it from
+  // NT_ARM_ZA regardless of the current streaming mode.
+  Status error = ReadZAHeader();
+  if (error.Success())
+    m_sme_pseudo_regs.svg_reg = m_za_header.vl / 8;
+
+  return error;
+}
+
 std::vector<uint32_t> NativeRegisterContextLinux_arm64::GetExpeditedRegisters(
     ExpeditedRegs expType) const {
   std::vector<uint32_t> expedited_reg_nums =
@@ -1364,6 +1388,10 @@
   // SVE, non-streaming vector length.
   if (m_sve_state == SVEState::FPSIMD || m_sve_state == SVEState::Full)
     expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSVEVG());
+  // SME, streaming vector length. This is used by the ZA register which is
+  // present even when streaming mode is not enabled.
+  if (GetRegisterInfo().IsSSVEEnabled())
+    expedited_reg_nums.push_back(GetRegisterInfo().GetRegNumSMESVG());
 
   return expedited_reg_nums;
 }
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to