1 | //===-- RegisterInfoPOSIX_riscv64.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 <cassert> |
10 | #include <lldb/Utility/Flags.h> |
11 | #include <stddef.h> |
12 | |
13 | #include "lldb/lldb-defines.h" |
14 | #include "llvm/Support/Compiler.h" |
15 | |
16 | #include "RegisterInfoPOSIX_riscv64.h" |
17 | |
18 | #define GPR_OFFSET(idx) ((idx)*8 + 0) |
19 | #define FPR_OFFSET(idx) ((idx)*8 + sizeof(RegisterInfoPOSIX_riscv64::GPR)) |
20 | |
21 | #define REG_CONTEXT_SIZE \ |
22 | (sizeof(RegisterInfoPOSIX_riscv64::GPR) + \ |
23 | sizeof(RegisterInfoPOSIX_riscv64::FPR)) |
24 | |
25 | #define DECLARE_REGISTER_INFOS_RISCV64_STRUCT |
26 | #include "RegisterInfos_riscv64.h" |
27 | #undef DECLARE_REGISTER_INFOS_RISCV64_STRUCT |
28 | |
29 | const lldb_private::RegisterInfo *RegisterInfoPOSIX_riscv64::GetRegisterInfoPtr( |
30 | const lldb_private::ArchSpec &target_arch) { |
31 | switch (target_arch.GetMachine()) { |
32 | case llvm::Triple::riscv64: |
33 | return g_register_infos_riscv64_le; |
34 | default: |
35 | assert(false && "Unhandled target architecture." ); |
36 | return nullptr; |
37 | } |
38 | } |
39 | |
40 | uint32_t RegisterInfoPOSIX_riscv64::GetRegisterInfoCount( |
41 | const lldb_private::ArchSpec &target_arch) { |
42 | switch (target_arch.GetMachine()) { |
43 | case llvm::Triple::riscv64: |
44 | return static_cast<uint32_t>(sizeof(g_register_infos_riscv64_le) / |
45 | sizeof(g_register_infos_riscv64_le[0])); |
46 | default: |
47 | assert(false && "Unhandled target architecture." ); |
48 | return 0; |
49 | } |
50 | } |
51 | |
52 | // Number of register sets provided by this context. |
53 | enum { |
54 | k_num_gpr_registers = gpr_last_riscv - gpr_first_riscv + 1, |
55 | k_num_fpr_registers = fpr_last_riscv - fpr_first_riscv + 1, |
56 | k_num_register_sets = 2 |
57 | }; |
58 | |
59 | // RISC-V64 general purpose registers. |
60 | static const uint32_t g_gpr_regnums_riscv64[] = { |
61 | gpr_pc_riscv, gpr_ra_riscv, gpr_sp_riscv, gpr_x3_riscv, |
62 | gpr_x4_riscv, gpr_x5_riscv, gpr_x6_riscv, gpr_x7_riscv, |
63 | gpr_fp_riscv, gpr_x9_riscv, gpr_x10_riscv, gpr_x11_riscv, |
64 | gpr_x12_riscv, gpr_x13_riscv, gpr_x14_riscv, gpr_x15_riscv, |
65 | gpr_x16_riscv, gpr_x17_riscv, gpr_x18_riscv, gpr_x19_riscv, |
66 | gpr_x20_riscv, gpr_x21_riscv, gpr_x22_riscv, gpr_x23_riscv, |
67 | gpr_x24_riscv, gpr_x25_riscv, gpr_x26_riscv, gpr_x27_riscv, |
68 | gpr_x28_riscv, gpr_x29_riscv, gpr_x30_riscv, gpr_x31_riscv, |
69 | gpr_x0_riscv, LLDB_INVALID_REGNUM}; |
70 | |
71 | static_assert(((sizeof g_gpr_regnums_riscv64 / |
72 | sizeof g_gpr_regnums_riscv64[0]) - |
73 | 1) == k_num_gpr_registers, |
74 | "g_gpr_regnums_riscv64 has wrong number of register infos" ); |
75 | |
76 | // RISC-V64 floating point registers. |
77 | static const uint32_t g_fpr_regnums_riscv64[] = { |
78 | fpr_f0_riscv, fpr_f1_riscv, fpr_f2_riscv, fpr_f3_riscv, |
79 | fpr_f4_riscv, fpr_f5_riscv, fpr_f6_riscv, fpr_f7_riscv, |
80 | fpr_f8_riscv, fpr_f9_riscv, fpr_f10_riscv, fpr_f11_riscv, |
81 | fpr_f12_riscv, fpr_f13_riscv, fpr_f14_riscv, fpr_f15_riscv, |
82 | fpr_f16_riscv, fpr_f17_riscv, fpr_f18_riscv, fpr_f19_riscv, |
83 | fpr_f20_riscv, fpr_f21_riscv, fpr_f22_riscv, fpr_f23_riscv, |
84 | fpr_f24_riscv, fpr_f25_riscv, fpr_f26_riscv, fpr_f27_riscv, |
85 | fpr_f28_riscv, fpr_f29_riscv, fpr_f30_riscv, fpr_f31_riscv, |
86 | fpr_fcsr_riscv, LLDB_INVALID_REGNUM}; |
87 | |
88 | static_assert(((sizeof g_fpr_regnums_riscv64 / |
89 | sizeof g_fpr_regnums_riscv64[0]) - |
90 | 1) == k_num_fpr_registers, |
91 | "g_fpr_regnums_riscv64 has wrong number of register infos" ); |
92 | |
93 | // Register sets for RISC-V64. |
94 | static const lldb_private::RegisterSet g_reg_sets_riscv64[k_num_register_sets] = |
95 | {{.name: "General Purpose Registers" , .short_name: "gpr" , .num_registers: k_num_gpr_registers, |
96 | .registers: g_gpr_regnums_riscv64}, |
97 | {.name: "Floating Point Registers" , .short_name: "fpr" , .num_registers: k_num_fpr_registers, |
98 | .registers: g_fpr_regnums_riscv64}}; |
99 | |
100 | RegisterInfoPOSIX_riscv64::RegisterInfoPOSIX_riscv64( |
101 | const lldb_private::ArchSpec &target_arch, lldb_private::Flags flags) |
102 | : lldb_private::RegisterInfoAndSetInterface(target_arch), |
103 | m_register_info_p(GetRegisterInfoPtr(target_arch)), |
104 | m_register_info_count(GetRegisterInfoCount(target_arch)) {} |
105 | |
106 | uint32_t RegisterInfoPOSIX_riscv64::GetRegisterCount() const { |
107 | return m_register_info_count; |
108 | } |
109 | |
110 | size_t RegisterInfoPOSIX_riscv64::GetGPRSize() const { |
111 | return sizeof(struct RegisterInfoPOSIX_riscv64::GPR); |
112 | } |
113 | |
114 | size_t RegisterInfoPOSIX_riscv64::GetFPRSize() const { |
115 | return sizeof(struct RegisterInfoPOSIX_riscv64::FPR); |
116 | } |
117 | |
118 | const lldb_private::RegisterInfo * |
119 | RegisterInfoPOSIX_riscv64::GetRegisterInfo() const { |
120 | return m_register_info_p; |
121 | } |
122 | |
123 | size_t RegisterInfoPOSIX_riscv64::GetRegisterSetCount() const { |
124 | return k_num_register_sets; |
125 | } |
126 | |
127 | size_t RegisterInfoPOSIX_riscv64::GetRegisterSetFromRegisterIndex( |
128 | uint32_t reg_index) const { |
129 | // coverity[unsigned_compare] |
130 | if (reg_index >= gpr_first_riscv && reg_index <= gpr_last_riscv) |
131 | return GPRegSet; |
132 | if (reg_index >= fpr_first_riscv && reg_index <= fpr_last_riscv) |
133 | return FPRegSet; |
134 | return LLDB_INVALID_REGNUM; |
135 | } |
136 | |
137 | const lldb_private::RegisterSet * |
138 | RegisterInfoPOSIX_riscv64::GetRegisterSet(size_t set_index) const { |
139 | if (set_index < GetRegisterSetCount()) |
140 | return &g_reg_sets_riscv64[set_index]; |
141 | return nullptr; |
142 | } |
143 | |