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 | for (auto it : rhs.m_kind_regnum_map) |
51 | m_kind_regnum_map[it.first] = it.second; |
52 | m_name = rhs.m_name; |
53 | return *this; |
54 | } |
55 | |
56 | bool RegisterNumber::operator==(RegisterNumber &rhs) { |
57 | if (IsValid() != rhs.IsValid()) |
58 | return false; |
59 | |
60 | if (m_kind == rhs.m_kind) { |
61 | return m_regnum == rhs.m_regnum; |
62 | } |
63 | |
64 | uint32_t rhs_regnum = rhs.GetAsKind(kind: m_kind); |
65 | if (rhs_regnum != LLDB_INVALID_REGNUM) { |
66 | return m_regnum == rhs_regnum; |
67 | } |
68 | uint32_t lhs_regnum = GetAsKind(kind: rhs.m_kind); |
69 | { return lhs_regnum == rhs.m_regnum; } |
70 | return false; |
71 | } |
72 | |
73 | bool RegisterNumber::operator!=(RegisterNumber &rhs) { return !(*this == rhs); } |
74 | |
75 | bool RegisterNumber::IsValid() const { |
76 | return m_reg_ctx_sp.get() && m_kind != lldb::kNumRegisterKinds && |
77 | m_regnum != LLDB_INVALID_REGNUM; |
78 | } |
79 | |
80 | uint32_t RegisterNumber::GetAsKind(lldb::RegisterKind kind) { |
81 | if (m_regnum == LLDB_INVALID_REGNUM) |
82 | return LLDB_INVALID_REGNUM; |
83 | |
84 | if (kind == m_kind) |
85 | return m_regnum; |
86 | |
87 | Collection::iterator iter = m_kind_regnum_map.find(x: kind); |
88 | if (iter != m_kind_regnum_map.end()) { |
89 | return iter->second; |
90 | } |
91 | uint32_t output_regnum = LLDB_INVALID_REGNUM; |
92 | if (m_reg_ctx_sp && |
93 | m_reg_ctx_sp->ConvertBetweenRegisterKinds(source_rk: m_kind, source_regnum: m_regnum, target_rk: kind, |
94 | target_regnum&: output_regnum) && |
95 | output_regnum != LLDB_INVALID_REGNUM) { |
96 | m_kind_regnum_map[kind] = output_regnum; |
97 | } |
98 | return output_regnum; |
99 | } |
100 | |
101 | uint32_t RegisterNumber::GetRegisterNumber() const { return m_regnum; } |
102 | |
103 | lldb::RegisterKind RegisterNumber::GetRegisterKind() const { return m_kind; } |
104 | |
105 | const char *RegisterNumber::GetName() { return m_name; } |
106 | |