| 1 | //===-- RegisterNumber.cpp ------------------------------------------------===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #include "lldb/Target/RegisterNumber.h" |
| 10 | #include "lldb/Target/RegisterContext.h" |
| 11 | #include "lldb/Target/Thread.h" |
| 12 | |
| 13 | using namespace lldb_private; |
| 14 | |
| 15 | RegisterNumber::RegisterNumber(lldb_private::Thread &thread, |
| 16 | lldb::RegisterKind kind, uint32_t num) |
| 17 | : m_reg_ctx_sp(thread.GetRegisterContext()), m_regnum(num), m_kind(kind), |
| 18 | m_kind_regnum_map(), m_name("" ) { |
| 19 | if (m_reg_ctx_sp.get()) { |
| 20 | const lldb_private::RegisterInfo *reginfo = |
| 21 | m_reg_ctx_sp->GetRegisterInfoAtIndex( |
| 22 | reg: GetAsKind(kind: lldb::eRegisterKindLLDB)); |
| 23 | if (reginfo && reginfo->name) { |
| 24 | m_name = reginfo->name; |
| 25 | } |
| 26 | } |
| 27 | } |
| 28 | |
| 29 | RegisterNumber::RegisterNumber() : m_reg_ctx_sp(), m_kind_regnum_map() {} |
| 30 | |
| 31 | void RegisterNumber::init(lldb_private::Thread &thread, lldb::RegisterKind kind, |
| 32 | uint32_t num) { |
| 33 | m_reg_ctx_sp = thread.GetRegisterContext(); |
| 34 | m_regnum = num; |
| 35 | m_kind = kind; |
| 36 | if (m_reg_ctx_sp.get()) { |
| 37 | const lldb_private::RegisterInfo *reginfo = |
| 38 | m_reg_ctx_sp->GetRegisterInfoAtIndex( |
| 39 | reg: GetAsKind(kind: lldb::eRegisterKindLLDB)); |
| 40 | if (reginfo && reginfo->name) { |
| 41 | m_name = reginfo->name; |
| 42 | } |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | const RegisterNumber &RegisterNumber::operator=(const RegisterNumber &rhs) { |
| 47 | m_reg_ctx_sp = rhs.m_reg_ctx_sp; |
| 48 | m_regnum = rhs.m_regnum; |
| 49 | m_kind = rhs.m_kind; |
| 50 | m_kind_regnum_map.clear(); |
| 51 | for (auto it : rhs.m_kind_regnum_map) |
| 52 | m_kind_regnum_map[it.first] = it.second; |
| 53 | m_name = rhs.m_name; |
| 54 | return *this; |
| 55 | } |
| 56 | |
| 57 | bool RegisterNumber::operator==(RegisterNumber &rhs) { |
| 58 | if (IsValid() != rhs.IsValid()) |
| 59 | return false; |
| 60 | |
| 61 | if (m_kind == rhs.m_kind) { |
| 62 | return m_regnum == rhs.m_regnum; |
| 63 | } |
| 64 | |
| 65 | uint32_t rhs_regnum = rhs.GetAsKind(kind: m_kind); |
| 66 | if (rhs_regnum != LLDB_INVALID_REGNUM) { |
| 67 | return m_regnum == rhs_regnum; |
| 68 | } |
| 69 | uint32_t lhs_regnum = GetAsKind(kind: rhs.m_kind); |
| 70 | { return lhs_regnum == rhs.m_regnum; } |
| 71 | return false; |
| 72 | } |
| 73 | |
| 74 | bool RegisterNumber::operator!=(RegisterNumber &rhs) { return !(*this == rhs); } |
| 75 | |
| 76 | bool RegisterNumber::IsValid() const { |
| 77 | return m_reg_ctx_sp.get() && m_kind != lldb::kNumRegisterKinds && |
| 78 | m_regnum != LLDB_INVALID_REGNUM; |
| 79 | } |
| 80 | |
| 81 | uint32_t RegisterNumber::GetAsKind(lldb::RegisterKind kind) { |
| 82 | if (m_regnum == LLDB_INVALID_REGNUM) |
| 83 | return LLDB_INVALID_REGNUM; |
| 84 | |
| 85 | if (kind == m_kind) |
| 86 | return m_regnum; |
| 87 | |
| 88 | Collection::iterator iter = m_kind_regnum_map.find(x: kind); |
| 89 | if (iter != m_kind_regnum_map.end()) { |
| 90 | return iter->second; |
| 91 | } |
| 92 | uint32_t output_regnum = LLDB_INVALID_REGNUM; |
| 93 | if (m_reg_ctx_sp && |
| 94 | m_reg_ctx_sp->ConvertBetweenRegisterKinds(source_rk: m_kind, source_regnum: m_regnum, target_rk: kind, |
| 95 | target_regnum&: output_regnum) && |
| 96 | output_regnum != LLDB_INVALID_REGNUM) { |
| 97 | m_kind_regnum_map[kind] = output_regnum; |
| 98 | } |
| 99 | return output_regnum; |
| 100 | } |
| 101 | |
| 102 | uint32_t RegisterNumber::GetRegisterNumber() const { return m_regnum; } |
| 103 | |
| 104 | lldb::RegisterKind RegisterNumber::GetRegisterKind() const { return m_kind; } |
| 105 | |
| 106 | const char *RegisterNumber::GetName() { return m_name; } |
| 107 | |