1 //===-- RegisterContextLinux_mips64.cpp ------------------------*- C++ -*-===//
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
10 #include <stddef.h>
11 #include <vector>
12
13 // For eh_frame and DWARF Register numbers
14 #include "RegisterContextLinux_mips64.h"
15
16 // For GP and FP buffers
17 #include "RegisterContext_mips.h"
18
19 // Internal codes for all mips32 and mips64 registers
20 #include "lldb-mips-linux-register-enums.h"
21
22 using namespace lldb;
23 using namespace lldb_private;
24
25 // Include RegisterInfos_mips64 to declare our g_register_infos_mips64
26 // structure.
27 #define DECLARE_REGISTER_INFOS_MIPS64_STRUCT
28 #define LINUX_MIPS64
29 #include "RegisterInfos_mips64.h"
30 #undef LINUX_MIPS64
31 #undef DECLARE_REGISTER_INFOS_MIPS64_STRUCT
32
33 // Include RegisterInfos_mips to declare our g_register_infos_mips structure.
34 #define DECLARE_REGISTER_INFOS_MIPS_STRUCT
35 #include "RegisterInfos_mips.h"
36 #undef DECLARE_REGISTER_INFOS_MIPS_STRUCT
37
38 // mips64 general purpose registers.
39 const uint32_t g_gp_regnums_mips64[] = {
40 gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64,
41 gpr_r3_mips64, gpr_r4_mips64, gpr_r5_mips64,
42 gpr_r6_mips64, gpr_r7_mips64, gpr_r8_mips64,
43 gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64,
44 gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64,
45 gpr_r15_mips64, gpr_r16_mips64, gpr_r17_mips64,
46 gpr_r18_mips64, gpr_r19_mips64, gpr_r20_mips64,
47 gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64,
48 gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64,
49 gpr_r27_mips64, gpr_gp_mips64, gpr_sp_mips64,
50 gpr_r30_mips64, gpr_ra_mips64, gpr_sr_mips64,
51 gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64,
52 gpr_cause_mips64, gpr_pc_mips64, gpr_config5_mips64,
53 LLDB_INVALID_REGNUM // register sets need to end with this flag
54 };
55
56 static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) -
57 1 ==
58 k_num_gpr_registers_mips64,
59 "g_gp_regnums_mips64 has wrong number of register infos");
60
61 // mips64 floating point registers.
62 const uint32_t g_fp_regnums_mips64[] = {
63 fpr_f0_mips64, fpr_f1_mips64, fpr_f2_mips64, fpr_f3_mips64,
64 fpr_f4_mips64, fpr_f5_mips64, fpr_f6_mips64, fpr_f7_mips64,
65 fpr_f8_mips64, fpr_f9_mips64, fpr_f10_mips64, fpr_f11_mips64,
66 fpr_f12_mips64, fpr_f13_mips64, fpr_f14_mips64, fpr_f15_mips64,
67 fpr_f16_mips64, fpr_f17_mips64, fpr_f18_mips64, fpr_f19_mips64,
68 fpr_f20_mips64, fpr_f21_mips64, fpr_f22_mips64, fpr_f23_mips64,
69 fpr_f24_mips64, fpr_f25_mips64, fpr_f26_mips64, fpr_f27_mips64,
70 fpr_f28_mips64, fpr_f29_mips64, fpr_f30_mips64, fpr_f31_mips64,
71 fpr_fcsr_mips64, fpr_fir_mips64, fpr_config5_mips64,
72 LLDB_INVALID_REGNUM // register sets need to end with this flag
73 };
74
75 static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) -
76 1 ==
77 k_num_fpr_registers_mips64,
78 "g_fp_regnums_mips64 has wrong number of register infos");
79
80 // mips64 MSA registers.
81 const uint32_t g_msa_regnums_mips64[] = {
82 msa_w0_mips64, msa_w1_mips64, msa_w2_mips64, msa_w3_mips64,
83 msa_w4_mips64, msa_w5_mips64, msa_w6_mips64, msa_w7_mips64,
84 msa_w8_mips64, msa_w9_mips64, msa_w10_mips64, msa_w11_mips64,
85 msa_w12_mips64, msa_w13_mips64, msa_w14_mips64, msa_w15_mips64,
86 msa_w16_mips64, msa_w17_mips64, msa_w18_mips64, msa_w19_mips64,
87 msa_w20_mips64, msa_w21_mips64, msa_w22_mips64, msa_w23_mips64,
88 msa_w24_mips64, msa_w25_mips64, msa_w26_mips64, msa_w27_mips64,
89 msa_w28_mips64, msa_w29_mips64, msa_w30_mips64, msa_w31_mips64,
90 msa_fcsr_mips64, msa_fir_mips64, msa_mcsr_mips64, msa_mir_mips64,
91 msa_config5_mips64,
92 LLDB_INVALID_REGNUM // register sets need to end with this flag
93 };
94
95 static_assert((sizeof(g_msa_regnums_mips64) / sizeof(g_msa_regnums_mips64[0])) -
96 1 ==
97 k_num_msa_registers_mips64,
98 "g_msa_regnums_mips64 has wrong number of register infos");
99
100 // Number of register sets provided by this context.
101 constexpr size_t k_num_register_sets = 3;
102
103 // Register sets for mips64.
104 static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = {
105 {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64,
106 g_gp_regnums_mips64},
107 {"Floating Point Registers", "fpu", k_num_fpr_registers_mips64,
108 g_fp_regnums_mips64},
109 {"MSA Registers", "msa", k_num_msa_registers_mips64, g_msa_regnums_mips64},
110 };
111
112 const RegisterSet *
GetRegisterSet(size_t set) const113 RegisterContextLinux_mips64::GetRegisterSet(size_t set) const {
114 if (set >= k_num_register_sets)
115 return nullptr;
116
117 switch (m_target_arch.GetMachine()) {
118 case llvm::Triple::mips64:
119 case llvm::Triple::mips64el:
120 return &g_reg_sets_mips64[set];
121 default:
122 assert(false && "Unhandled target architecture.");
123 return nullptr;
124 }
125 return nullptr;
126 }
127
128 size_t
GetRegisterSetCount() const129 RegisterContextLinux_mips64::GetRegisterSetCount() const {
130 return k_num_register_sets;
131 }
132
GetRegisterInfoPtr(const ArchSpec & target_arch)133 static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) {
134 switch (target_arch.GetMachine()) {
135 case llvm::Triple::mips64:
136 case llvm::Triple::mips64el:
137 return g_register_infos_mips64;
138 case llvm::Triple::mips:
139 case llvm::Triple::mipsel:
140 return g_register_infos_mips;
141 default:
142 assert(false && "Unhandled target architecture.");
143 return nullptr;
144 }
145 }
146
GetRegisterInfoCount(const ArchSpec & target_arch)147 static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) {
148 switch (target_arch.GetMachine()) {
149 case llvm::Triple::mips64:
150 case llvm::Triple::mips64el:
151 return static_cast<uint32_t>(sizeof(g_register_infos_mips64) /
152 sizeof(g_register_infos_mips64[0]));
153 case llvm::Triple::mips:
154 case llvm::Triple::mipsel:
155 return static_cast<uint32_t>(sizeof(g_register_infos_mips) /
156 sizeof(g_register_infos_mips[0]));
157 default:
158 assert(false && "Unhandled target architecture.");
159 return 0;
160 }
161 }
162
GetUserRegisterInfoCount(const ArchSpec & target_arch,bool msa_present)163 uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch,
164 bool msa_present) {
165 switch (target_arch.GetMachine()) {
166 case llvm::Triple::mips:
167 case llvm::Triple::mipsel:
168 if (msa_present)
169 return static_cast<uint32_t>(k_num_user_registers_mips);
170 return static_cast<uint32_t>(k_num_user_registers_mips -
171 k_num_msa_registers_mips);
172 case llvm::Triple::mips64el:
173 case llvm::Triple::mips64:
174 if (msa_present)
175 return static_cast<uint32_t>(k_num_user_registers_mips64);
176 return static_cast<uint32_t>(k_num_user_registers_mips64 -
177 k_num_msa_registers_mips64);
178 default:
179 assert(false && "Unhandled target architecture.");
180 return 0;
181 }
182 }
183
RegisterContextLinux_mips64(const ArchSpec & target_arch,bool msa_present)184 RegisterContextLinux_mips64::RegisterContextLinux_mips64(
185 const ArchSpec &target_arch, bool msa_present)
186 : lldb_private::RegisterInfoInterface(target_arch),
187 m_register_info_p(GetRegisterInfoPtr(target_arch)),
188 m_register_info_count(GetRegisterInfoCount(target_arch)),
189 m_user_register_count(
190 GetUserRegisterInfoCount(target_arch, msa_present)) {}
191
GetGPRSize() const192 size_t RegisterContextLinux_mips64::GetGPRSize() const {
193 return sizeof(GPR_linux_mips);
194 }
195
GetRegisterInfo() const196 const RegisterInfo *RegisterContextLinux_mips64::GetRegisterInfo() const {
197 return m_register_info_p;
198 }
199
GetRegisterCount() const200 uint32_t RegisterContextLinux_mips64::GetRegisterCount() const {
201 return m_register_info_count;
202 }
203
GetUserRegisterCount() const204 uint32_t RegisterContextLinux_mips64::GetUserRegisterCount() const {
205 return m_user_register_count;
206 }
207
208