DavidSpickett updated this revision to Diff 556672.
DavidSpickett added a comment.
Rebase.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D159504/new/
https://reviews.llvm.org/D159504
Files:
lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
lldb/source/Target/DynamicRegisterInfo.cpp
Index: lldb/source/Target/DynamicRegisterInfo.cpp
===================================================================
--- lldb/source/Target/DynamicRegisterInfo.cpp
+++ lldb/source/Target/DynamicRegisterInfo.cpp
@@ -614,10 +614,11 @@
ConfigureOffsets();
// Check if register info is reconfigurable
- // AArch64 SVE register set has configurable register sizes
+ // AArch64 SVE register set has configurable register sizes, as does the ZA
+ // register that SME added (the streaming state of SME reuses the SVE state).
if (arch.GetTriple().isAArch64()) {
for (const auto ® : m_regs) {
- if (strcmp(reg.name, "vg") == 0) {
+ if ((strcmp(reg.name, "vg") == 0) || (strcmp(reg.name, "svg") == 0)) {
m_is_reconfigurable = true;
break;
}
Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1660,17 +1660,19 @@
gdb_thread->PrivateSetRegisterValue(lldb_regnum, buffer_sp->GetData());
}
- // AArch64 SVE specific code below calls AArch64SVEReconfigure to update
- // SVE register sizes and offsets if value of VG register has changed
- // since last stop.
+ // AArch64 SVE/SME specific code below updates SVE and ZA register sizes and
+ // offsets if value of VG or SVG registers has changed since last stop.
const ArchSpec &arch = GetTarget().GetArchitecture();
if (arch.IsValid() && arch.GetTriple().isAArch64()) {
GDBRemoteRegisterContext *reg_ctx_sp =
static_cast<GDBRemoteRegisterContext *>(
gdb_thread->GetRegisterContext().get());
- if (reg_ctx_sp)
+ if (reg_ctx_sp) {
reg_ctx_sp->AArch64SVEReconfigure();
+ reg_ctx_sp->AArch64SMEReconfigure();
+ reg_ctx_sp->InvalidateAllRegisters();
+ }
}
thread_sp->SetName(thread_name.empty() ? nullptr : thread_name.c_str());
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
@@ -39,6 +39,7 @@
~GDBRemoteDynamicRegisterInfo() override = default;
void UpdateARM64SVERegistersInfos(uint64_t vg);
+ void UpdateARM64SMERegistersInfos(uint64_t svg);
};
class GDBRemoteRegisterContext : public RegisterContext {
@@ -77,7 +78,9 @@
uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
uint32_t num) override;
- bool AArch64SVEReconfigure();
+ void AArch64SVEReconfigure();
+
+ void AArch64SMEReconfigure();
protected:
friend class ThreadGDBRemote;
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -373,14 +373,14 @@
if (dst == nullptr)
return false;
- // Code below is specific to AArch64 target in SVE state
+ // Code below is specific to AArch64 target in SVE or SME state
// If vector granule (vg) register is being written then thread's
// register context reconfiguration is triggered on success.
- bool do_reconfigure_arm64_sve = false;
+ // We do not allow writes to SVG so it is not mentioned here.
const ArchSpec &arch = process->GetTarget().GetArchitecture();
- if (arch.IsValid() && arch.GetTriple().isAArch64())
- if (strcmp(reg_info->name, "vg") == 0)
- do_reconfigure_arm64_sve = true;
+ bool do_reconfigure_arm64_sve = arch.IsValid() &&
+ arch.GetTriple().isAArch64() &&
+ (strcmp(reg_info->name, "vg") == 0);
if (data.CopyByteOrderedData(data_offset, // src offset
reg_info->byte_size, // src length
@@ -400,10 +400,12 @@
{m_reg_data.GetDataStart(), size_t(m_reg_data.GetByteSize())}))
{
- SetAllRegisterValid(false);
-
- if (do_reconfigure_arm64_sve)
+ if (do_reconfigure_arm64_sve) {
AArch64SVEReconfigure();
+ AArch64SMEReconfigure();
+ }
+
+ InvalidateAllRegisters();
return true;
}
@@ -435,8 +437,11 @@
// This is an actual register, write it
success = SetPrimordialRegister(reg_info, gdb_comm);
- if (success && do_reconfigure_arm64_sve)
+ if (success && do_reconfigure_arm64_sve) {
AArch64SVEReconfigure();
+ AArch64SMEReconfigure();
+ InvalidateAllRegisters();
+ }
}
// Check if writing this register will invalidate any other register
@@ -760,37 +765,52 @@
return m_reg_info_sp->ConvertRegisterKindToRegisterNumber(kind, num);
}
-bool GDBRemoteRegisterContext::AArch64SVEReconfigure() {
- if (!m_reg_info_sp)
- return false;
-
+void GDBRemoteRegisterContext::AArch64SVEReconfigure() {
+ assert(m_reg_info_sp);
const RegisterInfo *reg_info = m_reg_info_sp->GetRegisterInfo("vg");
if (!reg_info)
- return false;
+ return;
uint64_t fail_value = LLDB_INVALID_ADDRESS;
uint32_t vg_reg_num = reg_info->kinds[eRegisterKindLLDB];
uint64_t vg_reg_value = ReadRegisterAsUnsigned(vg_reg_num, fail_value);
if (vg_reg_value == fail_value || vg_reg_value > 32)
- return false;
+ return;
reg_info = m_reg_info_sp->GetRegisterInfo("p0");
// Predicate registers have 1 bit per byte in the vector so their size is
// VL / 8. VG is in units of 8 bytes already, so if the size of p0 == VG
// already, we do not have to reconfigure.
if (!reg_info || vg_reg_value == reg_info->byte_size)
- return false;
+ return;
m_reg_info_sp->UpdateARM64SVERegistersInfos(vg_reg_value);
// Make a heap based buffer that is big enough to store all registers
m_reg_data.SetData(std::make_shared<DataBufferHeap>(
m_reg_info_sp->GetRegisterDataByteSize(), 0));
m_reg_data.SetByteOrder(GetByteOrder());
+}
- InvalidateAllRegisters();
+void GDBRemoteRegisterContext::AArch64SMEReconfigure() {
+ assert(m_reg_info_sp);
+ const RegisterInfo *reg_info = m_reg_info_sp->GetRegisterInfo("svg");
+ // Target does not have SME, nothing for us to reconfigure.
+ if (!reg_info)
+ return;
- return true;
+ uint64_t fail_value = LLDB_INVALID_ADDRESS;
+ uint32_t svg_reg_num = reg_info->kinds[eRegisterKindLLDB];
+ uint64_t svg_reg_value = ReadRegisterAsUnsigned(svg_reg_num, fail_value);
+
+ if (svg_reg_value == LLDB_INVALID_ADDRESS || svg_reg_value > 32)
+ return;
+
+ m_reg_info_sp->UpdateARM64SMERegistersInfos(svg_reg_value);
+ // Make a heap based buffer that is big enough to store all registers
+ m_reg_data.SetData(std::make_shared<DataBufferHeap>(
+ m_reg_info_sp->GetRegisterDataByteSize(), 0));
+ m_reg_data.SetByteOrder(GetByteOrder());
}
void GDBRemoteDynamicRegisterInfo::UpdateARM64SVERegistersInfos(uint64_t vg) {
@@ -815,3 +835,15 @@
// Re-calculate register offsets
ConfigureOffsets();
}
+
+void GDBRemoteDynamicRegisterInfo::UpdateARM64SMERegistersInfos(uint64_t svg) {
+ for (auto ® : m_regs) {
+ if (strcmp(reg.name, "za") == 0) {
+ // ZA is a register with size (svg*8) * (svg*8). A square essentially.
+ reg.byte_size = (svg * 8) * (svg * 8);
+ }
+ reg.byte_offset = LLDB_INVALID_INDEX32;
+ }
+
+ ConfigureOffsets();
+}
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits