DavidSpickett updated this revision to Diff 556844.
DavidSpickett added a comment.
- sme_regs -> sme_pseudo_regs, also changed the accesor method names.
- clang-format
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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits