DavidSpickett created this revision. Herald added subscribers: sunshaoce, ctetreau, kristof.beyls. Herald added a project: All. DavidSpickett requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
This adds a register "svg" which mirrors SVE's "vg" register. This reports the streaming vector length at all times, read from the ZA ptrace header. This register is needed first to implement ZA resizing as the streaming vector length changes. Like vg, svg will be expedited to the client so it can reconfigure its register definitions. The other use is for users to be able to know the streaming vector length without resorting to counting the (many, many) bytes in ZA, or temporarily entering streaming mode (which would be destructive). Testing for this will come in a later patch. Repository: rG LLVM Github Monorepo 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 @@ -109,6 +109,8 @@ void AddRegSetZA(); + void AddRegSetSME(); + uint32_t ConfigureVectorLength(uint32_t sve_vq); void ConfigureVectorLengthZA(uint32_t za_vq); @@ -147,6 +149,7 @@ uint32_t GetMTEOffset() const; uint32_t GetTLSOffset() const; uint32_t GetZAOffset() const; + uint32_t GetSMEOffset() const; private: typedef std::map<uint32_t, std::vector<lldb_private::RegisterInfo>> 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 @@ -88,6 +88,9 @@ {{"za", nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, KIND_ALL_INVALID, nullptr, nullptr, nullptr}}; +static lldb_private::RegisterInfo g_register_infos_sme[] = { + DEFINE_EXTENSION_REG(svg)}; + // Number of register sets provided by this context. enum { k_num_gpr_registers = gpr_w28 - gpr_x0 + 1, @@ -255,8 +258,10 @@ // present. AddRegSetTLS(m_opt_regsets.AllSet(eRegsetMaskSSVE)); - if (m_opt_regsets.AnySet(eRegsetMaskSSVE)) + if (m_opt_regsets.AnySet(eRegsetMaskSSVE)) { AddRegSetZA(); + AddRegSetSME(); + } m_register_info_count = m_dynamic_reg_infos.size(); m_register_info_p = m_dynamic_reg_infos.data(); @@ -377,6 +382,24 @@ m_dynamic_reg_sets.back().registers = m_za_regnum_collection.data(); } +void RegisterInfoPOSIX_arm64::AddRegSetSME() { + uint32_t sme_regnum = m_dynamic_reg_infos.size(); + for (uint32_t i = 0; i < k_num_sme_register; i++) { + m_sme_regnum_collection.push_back(sme_regnum + i); + m_dynamic_reg_infos.push_back(g_register_infos_sme[i]); + m_dynamic_reg_infos[sme_regnum + i].byte_offset = + m_dynamic_reg_infos[sme_regnum + i - 1].byte_offset + + m_dynamic_reg_infos[sme_regnum + i - 1].byte_size; + m_dynamic_reg_infos[sme_regnum + i].kinds[lldb::eRegisterKindLLDB] = + sme_regnum + i; + } + + m_per_regset_regnum_range[m_register_set_count] = + std::make_pair(sme_regnum, m_dynamic_reg_infos.size()); + m_dynamic_reg_sets.push_back(g_reg_set_sme_arm64); + m_dynamic_reg_sets.back().registers = m_sme_regnum_collection.data(); +} + uint32_t RegisterInfoPOSIX_arm64::ConfigureVectorLength(uint32_t sve_vq) { // sve_vq contains SVE Quad vector length in context of AArch64 SVE. // SVE register infos if enabled cannot be disabled by selecting sve_vq = 0. @@ -523,3 +546,7 @@ uint32_t RegisterInfoPOSIX_arm64::GetZAOffset() const { return m_register_info_p[m_za_regnum_collection[0]].byte_offset; } + +uint32_t RegisterInfoPOSIX_arm64::GetSMEOffset() const { + return m_register_info_p[m_sme_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_regs { + uint64_t svg_reg; + }; + + struct sme_regs m_sme_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(); @@ -159,6 +167,7 @@ bool IsPAuth(unsigned reg) const; bool IsMTE(unsigned reg) const; bool IsTLS(unsigned reg) const; + bool IsSME(unsigned reg) const; uint64_t GetSVERegVG() { return m_sve_header.vl / 8; } @@ -176,6 +185,8 @@ void *GetTLSBuffer() { return &m_tls_regs; } + void *GetSMEBuffer() { return &m_sme_regs; } + void *GetSVEBuffer() { return m_sve_ptrace_payload.data(); } size_t GetSVEHeaderSize() { return sizeof(m_sve_header); } @@ -194,6 +205,8 @@ size_t GetTLSBufferSize() { return m_tls_size; } + size_t GetSMEBufferSize() { return sizeof(m_sme_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_regs, 0, sizeof(m_sme_regs)); m_mte_ctrl_reg = 0; @@ -353,6 +354,14 @@ GetZAHeaderSize(); assert(offset < GetZABufferSize()); src = (uint8_t *)GetZABuffer() + offset; + } else if (IsSME(reg)) { + error = ReadSMESVG(); + if (error.Fail()) + return error; + + offset = reg_info->byte_offset - GetRegisterInfo().GetSMEOffset(); + assert(offset < GetSMEBufferSize()); + src = (uint8_t *)GetSMEBuffer() + offset; } else return Status("failed - register wasn't recognized to be a GPR or an FPR, " "write strategy unknown"); @@ -552,6 +561,8 @@ // way to change that is via the vg register. So here we assume the length // will always be the current length and no reconfigure is needed. return WriteZA(); + } else if (IsSME(reg)) { + return Status("Writing to SVG is not supported."); } return Status("Failed to write register value"); @@ -901,6 +912,10 @@ return GetRegisterInfo().IsTLSReg(reg); } +bool NativeRegisterContextLinux_arm64::IsSME(unsigned reg) const { + return GetRegisterInfo().IsSMEReg(reg); +} + llvm::Error NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo() { if (!m_refresh_hwdebug_info) { return llvm::Error::success(); @@ -1357,6 +1372,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_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 =
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits