diff --git a/lldb/include/lldb/Target/DynamicRegisterInfo.h b/lldb/include/lldb/Target/DynamicRegisterInfo.h --- a/lldb/include/lldb/Target/DynamicRegisterInfo.h +++ b/lldb/include/lldb/Target/DynamicRegisterInfo.h @@ -56,11 +56,6 @@ void AddRegister(lldb_private::RegisterInfo reg_info, lldb_private::ConstString &set_name); - // Add a new register and cross-link it via invalidate_regs with other - // registers sharing its value_regs. - void AddSupplementaryRegister(lldb_private::RegisterInfo reg_info, - lldb_private::ConstString &set_name); - void Finalize(const lldb_private::ArchSpec &arch); size_t GetNumRegisters() const; @@ -130,6 +125,9 @@ bool m_is_reconfigurable = false; }; +void addSupplementaryRegister(std::vector ®s, + DynamicRegisterInfo::Register new_reg_info); + } // namespace lldb_private #endif // LLDB_TARGET_DYNAMICREGISTERINFO_H diff --git a/lldb/source/Target/DynamicRegisterInfo.cpp b/lldb/source/Target/DynamicRegisterInfo.cpp --- a/lldb/source/Target/DynamicRegisterInfo.cpp +++ b/lldb/source/Target/DynamicRegisterInfo.cpp @@ -408,29 +408,6 @@ m_set_reg_nums[set].push_back(reg_num); } -void DynamicRegisterInfo::AddSupplementaryRegister(RegisterInfo new_reg_info, - ConstString &set_name) { - assert(new_reg_info.value_regs != nullptr); - const uint32_t reg_num = m_regs.size(); - AddRegister(new_reg_info, set_name); - - reg_to_regs_map new_invalidates; - for (uint32_t value_reg : m_value_regs_map[reg_num]) { - // copy value_regs to invalidate_regs - new_invalidates[reg_num].push_back(value_reg); - - // copy invalidate_regs from the parent register - llvm::append_range(new_invalidates[reg_num], m_invalidate_regs_map[value_reg]); - - // add reverse invalidate entries - for (uint32_t x : new_invalidates[reg_num]) - new_invalidates[x].push_back(new_reg_info.kinds[eRegisterKindLLDB]); - } - - for (const auto &x : new_invalidates) - llvm::append_range(m_invalidate_regs_map[x.first], x.second); -} - void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { if (m_finalized) return; @@ -802,3 +779,28 @@ return ®_info; return nullptr; } + +void lldb_private::addSupplementaryRegister( + std::vector ®s, + DynamicRegisterInfo::Register new_reg_info) { + assert(!new_reg_info.value_regs.empty()); + const uint32_t reg_num = regs.size(); + regs.push_back(new_reg_info); + + std::map> new_invalidates; + for (uint32_t value_reg : new_reg_info.value_regs) { + // copy value_regs to invalidate_regs + new_invalidates[reg_num].push_back(value_reg); + + // copy invalidate_regs from the parent register + llvm::append_range(new_invalidates[reg_num], + regs[value_reg].invalidate_regs); + + // add reverse invalidate entries + for (uint32_t x : new_invalidates[reg_num]) + new_invalidates[x].push_back(reg_num); + } + + for (const auto &x : new_invalidates) + llvm::append_range(regs[x.first].invalidate_regs, x.second); +} diff --git a/lldb/unittests/Target/DynamicRegisterInfoTest.cpp b/lldb/unittests/Target/DynamicRegisterInfoTest.cpp --- a/lldb/unittests/Target/DynamicRegisterInfoTest.cpp +++ b/lldb/unittests/Target/DynamicRegisterInfoTest.cpp @@ -12,6 +12,8 @@ #include "lldb/Target/DynamicRegisterInfo.h" #include "lldb/Utility/ArchSpec.h" +#include + using namespace lldb_private; static std::vector regs_to_vector(uint32_t *regs) { @@ -69,9 +71,10 @@ } }; -#define ASSERT_REG(reg, ...) { \ - SCOPED_TRACE("at register " #reg); \ - AssertRegisterInfo(reg, #reg, __VA_ARGS__); \ +#define ASSERT_REG(reg, ...) \ + { \ + SCOPED_TRACE("at register " #reg); \ + AssertRegisterInfo(reg, #reg, __VA_ARGS__); \ } TEST_F(DynamicRegisterInfoTest, finalize_regs) { @@ -124,46 +127,62 @@ ASSERT_REG(i2, LLDB_INVALID_INDEX32); } -TEST_F(DynamicRegisterInfoTest, add_supplementary_register) { - // Add a base register - uint32_t rax = AddTestRegister("rax", 8); - - // Register numbers - uint32_t eax = 1; - uint32_t ax = 2; - uint32_t al = 3; - - ConstString group{"supplementary registers"}; - uint32_t value_regs[2] = {rax, LLDB_INVALID_REGNUM}; - struct RegisterInfo eax_reg { - "eax", nullptr, 4, LLDB_INVALID_INDEX32, lldb::eEncodingUint, - lldb::eFormatUnsigned, - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, eax, - eax}, - value_regs, nullptr - }; - info.AddSupplementaryRegister(eax_reg, group); +class DynamicRegisterInfoRegisterTest : public ::testing::Test { +protected: + std::vector m_regs; + + uint32_t AddTestRegister( + const char *name, const char *group, uint32_t byte_size, + std::function adder, + std::vector value_regs = {}, + std::vector invalidate_regs = {}) { + DynamicRegisterInfo::Register new_reg{ + ConstString(name), ConstString(), + ConstString(group), byte_size, + LLDB_INVALID_INDEX32, lldb::eEncodingUint, + lldb::eFormatUnsigned, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, value_regs, + invalidate_regs}; + adder(new_reg); + return m_regs.size() - 1; + } - struct RegisterInfo ax_reg { - "ax", nullptr, 2, LLDB_INVALID_INDEX32, lldb::eEncodingUint, - lldb::eFormatUnsigned, - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, ax, ax}, - value_regs, nullptr - }; - info.AddSupplementaryRegister(ax_reg, group); + void ExpectInRegs(uint32_t reg_num, const char *reg_name, + std::vector value_regs, + std::vector invalidate_regs) { + ASSERT_GT(m_regs.size(), reg_num); - struct RegisterInfo al_reg { - "al", nullptr, 1, LLDB_INVALID_INDEX32, lldb::eEncodingUint, - lldb::eFormatUnsigned, - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, al, al}, - value_regs, nullptr - }; - info.AddSupplementaryRegister(al_reg, group); + const DynamicRegisterInfo::Register ® = m_regs[reg_num]; + ConstString expected_reg_name{reg_name}; + EXPECT_EQ(reg.name, expected_reg_name); + EXPECT_EQ(reg.value_regs, value_regs); + EXPECT_EQ(reg.invalidate_regs, invalidate_regs); + } +}; - info.Finalize(lldb_private::ArchSpec()); +#define EXPECT_IN_REGS(reg, ...) \ + { \ + SCOPED_TRACE("at register " #reg); \ + ExpectInRegs(reg, #reg, __VA_ARGS__); \ + } - ASSERT_REG(rax, 0, {}, {eax, ax, al}); - ASSERT_REG(eax, 0, {rax}, {rax, ax, al}); - ASSERT_REG(ax, 0, {rax}, {rax, eax, al}); - ASSERT_REG(al, 0, {rax}, {rax, eax, ax}); +TEST_F(DynamicRegisterInfoRegisterTest, addSupplementaryRegister) { + // Add a base register + uint32_t rax = AddTestRegister( + "rax", "group", 8, + [this](const DynamicRegisterInfo::Register &r) { m_regs.push_back(r); }); + + // Add supplementary registers + auto suppl_adder = [this](const DynamicRegisterInfo::Register &r) { + addSupplementaryRegister(m_regs, r); + }; + uint32_t eax = AddTestRegister("eax", "supplementary", 4, suppl_adder, {rax}); + uint32_t ax = AddTestRegister("ax", "supplementary", 2, suppl_adder, {rax}); + uint32_t al = AddTestRegister("al", "supplementary", 1, suppl_adder, {rax}); + + EXPECT_IN_REGS(rax, {}, {eax, ax, al}); + EXPECT_IN_REGS(eax, {rax}, {rax, ax, al}); + EXPECT_IN_REGS(ax, {rax}, {rax, eax, al}); + EXPECT_IN_REGS(al, {rax}, {rax, eax, ax}); }