mgorny updated this revision to Diff 373515. mgorny added a comment. Rebased. Updated the code to assume dedupe and cleanup happens in `Finalize()`, and to use new test assertions.
CHANGES SINCE LAST ACTION https://reviews.llvm.org/D110023/new/ https://reviews.llvm.org/D110023 Files: lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h lldb/unittests/Process/Utility/DynamicRegisterInfoTest.cpp
Index: lldb/unittests/Process/Utility/DynamicRegisterInfoTest.cpp =================================================================== --- lldb/unittests/Process/Utility/DynamicRegisterInfoTest.cpp +++ lldb/unittests/Process/Utility/DynamicRegisterInfoTest.cpp @@ -149,3 +149,59 @@ ASSERT_REG(i1, LLDB_INVALID_INDEX32); ASSERT_REG(i2, LLDB_INVALID_INDEX32); } + +TEST(DynamicRegisterInfoTest, add_supplementary_register) { + TestDynamicRegisterInfo info; + + // Add a base register + uint32_t rax = info.AddTestRegister("rax", 8); + + // Register numbers + uint32_t eax = 1; + uint32_t ax = 2; + uint32_t ah = 3; + uint32_t al = 4; + + 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, nullptr, 0 + }; + info.AddSupplementaryRegister(eax_reg, group); + + 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, nullptr, 0 + }; + info.AddSupplementaryRegister(ax_reg, group); + + struct RegisterInfo ah_reg { + "ah", nullptr, 1, LLDB_INVALID_INDEX32, lldb::eEncodingUint, + lldb::eFormatUnsigned, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, ah, ah}, + value_regs, nullptr, nullptr, 0 + }; + info.AddSupplementaryRegister(ah_reg, group); + + 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, nullptr, 0 + }; + info.AddSupplementaryRegister(al_reg, group); + + info.Finalize(lldb_private::ArchSpec()); + + ASSERT_REG(rax, 0, {}, {eax, ax, ah, al}); + ASSERT_REG(eax, 0, {rax}, {rax, ax, ah, al}); + ASSERT_REG(ax, 0, {rax}, {rax, eax, ah, al}); + ASSERT_REG(ah, 0, {rax}, {rax, eax, ax, al}); + ASSERT_REG(al, 0, {rax}, {rax, eax, ax, ah}); +} Index: lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h =================================================================== --- lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -38,6 +38,11 @@ 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; Index: lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp =================================================================== --- lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -432,6 +432,32 @@ 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 to_add; + for (uint32_t value_reg : m_value_regs_map[reg_num]) { + if (value_reg == LLDB_INVALID_REGNUM) + break; + + // copy value_regs to invalidate_regs + to_add[reg_num].push_back(value_reg); + + // copy invalidate_regs from the parent register + llvm::append_range(to_add[reg_num], m_invalidate_regs_map[value_reg]); + + // add reverse invalidate entries + for (uint32_t x : to_add[reg_num]) + to_add[x].push_back(new_reg_info.kinds[eRegisterKindLLDB]); + } + + for (reg_to_regs_map::value_type &x : to_add) + llvm::append_range(m_invalidate_regs_map[x.first], x.second); +} + void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { if (m_finalized) return;
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits