11c3bbb01SEd Maste //===-- RegisterContextLinux_mips64.cpp ------------------------*- C++ -*-===//
21c3bbb01SEd Maste //
31c3bbb01SEd Maste // The LLVM Compiler Infrastructure
41c3bbb01SEd Maste //
51c3bbb01SEd Maste // This file is distributed under the University of Illinois Open Source
61c3bbb01SEd Maste // License. See LICENSE.TXT for details.
71c3bbb01SEd Maste //
81c3bbb01SEd Maste //===---------------------------------------------------------------------===//
91c3bbb01SEd Maste
101c3bbb01SEd Maste
111c3bbb01SEd Maste #include <stddef.h>
12435933ddSDimitry Andric #include <vector>
131c3bbb01SEd Maste
149f2f44ceSEd Maste // For eh_frame and DWARF Register numbers
151c3bbb01SEd Maste #include "RegisterContextLinux_mips64.h"
161c3bbb01SEd Maste
17b6c25e0eSDimitry Andric // For GP and FP buffers
18b6c25e0eSDimitry Andric #include "RegisterContext_mips.h"
19b6c25e0eSDimitry Andric
20b6c25e0eSDimitry Andric // Internal codes for all mips32 and mips64 registers
21b6c25e0eSDimitry Andric #include "lldb-mips-linux-register-enums.h"
221c3bbb01SEd Maste
231c3bbb01SEd Maste using namespace lldb;
241c3bbb01SEd Maste using namespace lldb_private;
251c3bbb01SEd Maste
261c3bbb01SEd Maste //---------------------------------------------------------------------------
27435933ddSDimitry Andric // Include RegisterInfos_mips64 to declare our g_register_infos_mips64
28435933ddSDimitry Andric // structure.
291c3bbb01SEd Maste //---------------------------------------------------------------------------
301c3bbb01SEd Maste #define DECLARE_REGISTER_INFOS_MIPS64_STRUCT
31b6c25e0eSDimitry Andric #define LINUX_MIPS64
321c3bbb01SEd Maste #include "RegisterInfos_mips64.h"
33b6c25e0eSDimitry Andric #undef LINUX_MIPS64
341c3bbb01SEd Maste #undef DECLARE_REGISTER_INFOS_MIPS64_STRUCT
351c3bbb01SEd Maste
361c3bbb01SEd Maste //---------------------------------------------------------------------------
371c3bbb01SEd Maste // Include RegisterInfos_mips to declare our g_register_infos_mips structure.
381c3bbb01SEd Maste //---------------------------------------------------------------------------
391c3bbb01SEd Maste #define DECLARE_REGISTER_INFOS_MIPS_STRUCT
401c3bbb01SEd Maste #include "RegisterInfos_mips.h"
411c3bbb01SEd Maste #undef DECLARE_REGISTER_INFOS_MIPS_STRUCT
421c3bbb01SEd Maste
43*f678e45dSDimitry Andric // mips64 general purpose registers.
44*f678e45dSDimitry Andric const uint32_t g_gp_regnums_mips64[] = {
45*f678e45dSDimitry Andric gpr_zero_mips64, gpr_r1_mips64, gpr_r2_mips64,
46*f678e45dSDimitry Andric gpr_r3_mips64, gpr_r4_mips64, gpr_r5_mips64,
47*f678e45dSDimitry Andric gpr_r6_mips64, gpr_r7_mips64, gpr_r8_mips64,
48*f678e45dSDimitry Andric gpr_r9_mips64, gpr_r10_mips64, gpr_r11_mips64,
49*f678e45dSDimitry Andric gpr_r12_mips64, gpr_r13_mips64, gpr_r14_mips64,
50*f678e45dSDimitry Andric gpr_r15_mips64, gpr_r16_mips64, gpr_r17_mips64,
51*f678e45dSDimitry Andric gpr_r18_mips64, gpr_r19_mips64, gpr_r20_mips64,
52*f678e45dSDimitry Andric gpr_r21_mips64, gpr_r22_mips64, gpr_r23_mips64,
53*f678e45dSDimitry Andric gpr_r24_mips64, gpr_r25_mips64, gpr_r26_mips64,
54*f678e45dSDimitry Andric gpr_r27_mips64, gpr_gp_mips64, gpr_sp_mips64,
55*f678e45dSDimitry Andric gpr_r30_mips64, gpr_ra_mips64, gpr_sr_mips64,
56*f678e45dSDimitry Andric gpr_mullo_mips64, gpr_mulhi_mips64, gpr_badvaddr_mips64,
57*f678e45dSDimitry Andric gpr_cause_mips64, gpr_pc_mips64, gpr_config5_mips64,
58*f678e45dSDimitry Andric LLDB_INVALID_REGNUM // register sets need to end with this flag
59*f678e45dSDimitry Andric };
60*f678e45dSDimitry Andric
61*f678e45dSDimitry Andric static_assert((sizeof(g_gp_regnums_mips64) / sizeof(g_gp_regnums_mips64[0])) -
62*f678e45dSDimitry Andric 1 ==
63*f678e45dSDimitry Andric k_num_gpr_registers_mips64,
64*f678e45dSDimitry Andric "g_gp_regnums_mips64 has wrong number of register infos");
65*f678e45dSDimitry Andric
66*f678e45dSDimitry Andric // mips64 floating point registers.
67*f678e45dSDimitry Andric const uint32_t g_fp_regnums_mips64[] = {
68*f678e45dSDimitry Andric fpr_f0_mips64, fpr_f1_mips64, fpr_f2_mips64, fpr_f3_mips64,
69*f678e45dSDimitry Andric fpr_f4_mips64, fpr_f5_mips64, fpr_f6_mips64, fpr_f7_mips64,
70*f678e45dSDimitry Andric fpr_f8_mips64, fpr_f9_mips64, fpr_f10_mips64, fpr_f11_mips64,
71*f678e45dSDimitry Andric fpr_f12_mips64, fpr_f13_mips64, fpr_f14_mips64, fpr_f15_mips64,
72*f678e45dSDimitry Andric fpr_f16_mips64, fpr_f17_mips64, fpr_f18_mips64, fpr_f19_mips64,
73*f678e45dSDimitry Andric fpr_f20_mips64, fpr_f21_mips64, fpr_f22_mips64, fpr_f23_mips64,
74*f678e45dSDimitry Andric fpr_f24_mips64, fpr_f25_mips64, fpr_f26_mips64, fpr_f27_mips64,
75*f678e45dSDimitry Andric fpr_f28_mips64, fpr_f29_mips64, fpr_f30_mips64, fpr_f31_mips64,
76*f678e45dSDimitry Andric fpr_fcsr_mips64, fpr_fir_mips64, fpr_config5_mips64,
77*f678e45dSDimitry Andric LLDB_INVALID_REGNUM // register sets need to end with this flag
78*f678e45dSDimitry Andric };
79*f678e45dSDimitry Andric
80*f678e45dSDimitry Andric static_assert((sizeof(g_fp_regnums_mips64) / sizeof(g_fp_regnums_mips64[0])) -
81*f678e45dSDimitry Andric 1 ==
82*f678e45dSDimitry Andric k_num_fpr_registers_mips64,
83*f678e45dSDimitry Andric "g_fp_regnums_mips64 has wrong number of register infos");
84*f678e45dSDimitry Andric
85*f678e45dSDimitry Andric // mips64 MSA registers.
86*f678e45dSDimitry Andric const uint32_t g_msa_regnums_mips64[] = {
87*f678e45dSDimitry Andric msa_w0_mips64, msa_w1_mips64, msa_w2_mips64, msa_w3_mips64,
88*f678e45dSDimitry Andric msa_w4_mips64, msa_w5_mips64, msa_w6_mips64, msa_w7_mips64,
89*f678e45dSDimitry Andric msa_w8_mips64, msa_w9_mips64, msa_w10_mips64, msa_w11_mips64,
90*f678e45dSDimitry Andric msa_w12_mips64, msa_w13_mips64, msa_w14_mips64, msa_w15_mips64,
91*f678e45dSDimitry Andric msa_w16_mips64, msa_w17_mips64, msa_w18_mips64, msa_w19_mips64,
92*f678e45dSDimitry Andric msa_w20_mips64, msa_w21_mips64, msa_w22_mips64, msa_w23_mips64,
93*f678e45dSDimitry Andric msa_w24_mips64, msa_w25_mips64, msa_w26_mips64, msa_w27_mips64,
94*f678e45dSDimitry Andric msa_w28_mips64, msa_w29_mips64, msa_w30_mips64, msa_w31_mips64,
95*f678e45dSDimitry Andric msa_fcsr_mips64, msa_fir_mips64, msa_mcsr_mips64, msa_mir_mips64,
96*f678e45dSDimitry Andric msa_config5_mips64,
97*f678e45dSDimitry Andric LLDB_INVALID_REGNUM // register sets need to end with this flag
98*f678e45dSDimitry Andric };
99*f678e45dSDimitry Andric
100*f678e45dSDimitry Andric static_assert((sizeof(g_msa_regnums_mips64) / sizeof(g_msa_regnums_mips64[0])) -
101*f678e45dSDimitry Andric 1 ==
102*f678e45dSDimitry Andric k_num_msa_registers_mips64,
103*f678e45dSDimitry Andric "g_msa_regnums_mips64 has wrong number of register infos");
104*f678e45dSDimitry Andric
105*f678e45dSDimitry Andric // Number of register sets provided by this context.
106*f678e45dSDimitry Andric constexpr size_t k_num_register_sets = 3;
107*f678e45dSDimitry Andric
108*f678e45dSDimitry Andric // Register sets for mips64.
109*f678e45dSDimitry Andric static const RegisterSet g_reg_sets_mips64[k_num_register_sets] = {
110*f678e45dSDimitry Andric {"General Purpose Registers", "gpr", k_num_gpr_registers_mips64,
111*f678e45dSDimitry Andric g_gp_regnums_mips64},
112*f678e45dSDimitry Andric {"Floating Point Registers", "fpu", k_num_fpr_registers_mips64,
113*f678e45dSDimitry Andric g_fp_regnums_mips64},
114*f678e45dSDimitry Andric {"MSA Registers", "msa", k_num_msa_registers_mips64, g_msa_regnums_mips64},
115*f678e45dSDimitry Andric };
116*f678e45dSDimitry Andric
117*f678e45dSDimitry Andric const RegisterSet *
GetRegisterSet(size_t set) const118*f678e45dSDimitry Andric RegisterContextLinux_mips64::GetRegisterSet(size_t set) const {
119*f678e45dSDimitry Andric if (set >= k_num_register_sets)
120*f678e45dSDimitry Andric return nullptr;
121*f678e45dSDimitry Andric
122*f678e45dSDimitry Andric switch (m_target_arch.GetMachine()) {
123*f678e45dSDimitry Andric case llvm::Triple::mips64:
124*f678e45dSDimitry Andric case llvm::Triple::mips64el:
125*f678e45dSDimitry Andric return &g_reg_sets_mips64[set];
126*f678e45dSDimitry Andric default:
127*f678e45dSDimitry Andric assert(false && "Unhandled target architecture.");
128*f678e45dSDimitry Andric return nullptr;
129*f678e45dSDimitry Andric }
130*f678e45dSDimitry Andric return nullptr;
131*f678e45dSDimitry Andric }
132*f678e45dSDimitry Andric
133*f678e45dSDimitry Andric size_t
GetRegisterSetCount() const134*f678e45dSDimitry Andric RegisterContextLinux_mips64::GetRegisterSetCount() const {
135*f678e45dSDimitry Andric return k_num_register_sets;
136*f678e45dSDimitry Andric }
137*f678e45dSDimitry Andric
GetRegisterInfoPtr(const ArchSpec & target_arch)138435933ddSDimitry Andric static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) {
139435933ddSDimitry Andric switch (target_arch.GetMachine()) {
1401c3bbb01SEd Maste case llvm::Triple::mips64:
1411c3bbb01SEd Maste case llvm::Triple::mips64el:
1421c3bbb01SEd Maste return g_register_infos_mips64;
1431c3bbb01SEd Maste case llvm::Triple::mips:
1441c3bbb01SEd Maste case llvm::Triple::mipsel:
1451c3bbb01SEd Maste return g_register_infos_mips;
1461c3bbb01SEd Maste default:
1471c3bbb01SEd Maste assert(false && "Unhandled target architecture.");
1481c3bbb01SEd Maste return nullptr;
1491c3bbb01SEd Maste }
1501c3bbb01SEd Maste }
1511c3bbb01SEd Maste
GetRegisterInfoCount(const ArchSpec & target_arch)152435933ddSDimitry Andric static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) {
153435933ddSDimitry Andric switch (target_arch.GetMachine()) {
1541c3bbb01SEd Maste case llvm::Triple::mips64:
1551c3bbb01SEd Maste case llvm::Triple::mips64el:
156435933ddSDimitry Andric return static_cast<uint32_t>(sizeof(g_register_infos_mips64) /
157435933ddSDimitry Andric sizeof(g_register_infos_mips64[0]));
1581c3bbb01SEd Maste case llvm::Triple::mips:
1591c3bbb01SEd Maste case llvm::Triple::mipsel:
160435933ddSDimitry Andric return static_cast<uint32_t>(sizeof(g_register_infos_mips) /
161435933ddSDimitry Andric sizeof(g_register_infos_mips[0]));
1621c3bbb01SEd Maste default:
1631c3bbb01SEd Maste assert(false && "Unhandled target architecture.");
1641c3bbb01SEd Maste return 0;
1651c3bbb01SEd Maste }
1661c3bbb01SEd Maste }
1671c3bbb01SEd Maste
GetUserRegisterInfoCount(const ArchSpec & target_arch,bool msa_present)168435933ddSDimitry Andric uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch,
169435933ddSDimitry Andric bool msa_present) {
170435933ddSDimitry Andric switch (target_arch.GetMachine()) {
171b6c25e0eSDimitry Andric case llvm::Triple::mips:
172b6c25e0eSDimitry Andric case llvm::Triple::mipsel:
1739f2f44ceSEd Maste if (msa_present)
174b6c25e0eSDimitry Andric return static_cast<uint32_t>(k_num_user_registers_mips);
175435933ddSDimitry Andric return static_cast<uint32_t>(k_num_user_registers_mips -
176435933ddSDimitry Andric k_num_msa_registers_mips);
177b6c25e0eSDimitry Andric case llvm::Triple::mips64el:
178b6c25e0eSDimitry Andric case llvm::Triple::mips64:
1799f2f44ceSEd Maste if (msa_present)
180b6c25e0eSDimitry Andric return static_cast<uint32_t>(k_num_user_registers_mips64);
181435933ddSDimitry Andric return static_cast<uint32_t>(k_num_user_registers_mips64 -
182435933ddSDimitry Andric k_num_msa_registers_mips64);
183b6c25e0eSDimitry Andric default:
184b6c25e0eSDimitry Andric assert(false && "Unhandled target architecture.");
185b6c25e0eSDimitry Andric return 0;
186b6c25e0eSDimitry Andric }
187b6c25e0eSDimitry Andric }
188b6c25e0eSDimitry Andric
RegisterContextLinux_mips64(const ArchSpec & target_arch,bool msa_present)189435933ddSDimitry Andric RegisterContextLinux_mips64::RegisterContextLinux_mips64(
190435933ddSDimitry Andric const ArchSpec &target_arch, bool msa_present)
191435933ddSDimitry Andric : lldb_private::RegisterInfoInterface(target_arch),
1921c3bbb01SEd Maste m_register_info_p(GetRegisterInfoPtr(target_arch)),
193b6c25e0eSDimitry Andric m_register_info_count(GetRegisterInfoCount(target_arch)),
194435933ddSDimitry Andric m_user_register_count(
195435933ddSDimitry Andric GetUserRegisterInfoCount(target_arch, msa_present)) {}
1961c3bbb01SEd Maste
GetGPRSize() const197435933ddSDimitry Andric size_t RegisterContextLinux_mips64::GetGPRSize() const {
198b6c25e0eSDimitry Andric return sizeof(GPR_linux_mips);
1991c3bbb01SEd Maste }
2001c3bbb01SEd Maste
GetRegisterInfo() const201435933ddSDimitry Andric const RegisterInfo *RegisterContextLinux_mips64::GetRegisterInfo() const {
2021c3bbb01SEd Maste return m_register_info_p;
2031c3bbb01SEd Maste }
2041c3bbb01SEd Maste
GetRegisterCount() const205435933ddSDimitry Andric uint32_t RegisterContextLinux_mips64::GetRegisterCount() const {
2061c3bbb01SEd Maste return m_register_info_count;
2071c3bbb01SEd Maste }
2081c3bbb01SEd Maste
GetUserRegisterCount() const209435933ddSDimitry Andric uint32_t RegisterContextLinux_mips64::GetUserRegisterCount() const {
210b6c25e0eSDimitry Andric return m_user_register_count;
211b6c25e0eSDimitry Andric }
212b6c25e0eSDimitry Andric
213