1 //===-- RegisterInfoPOSIX_arm.cpp -----------------------------------------===//
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
7 //===---------------------------------------------------------------------===//
13 #include "lldb/lldb-defines.h"
14 #include "llvm/Support/Compiler.h"
16 #include "RegisterInfoPOSIX_arm.h"
19 using namespace lldb_private
;
21 // Based on RegisterContextDarwin_arm.cpp
22 #define GPR_OFFSET(idx) ((idx)*4)
23 #define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterInfoPOSIX_arm::GPR))
24 #define FPSCR_OFFSET \
25 (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm::FPU, fpscr) + \
26 sizeof(RegisterInfoPOSIX_arm::GPR))
27 #define EXC_OFFSET(idx) \
28 ((idx)*4 + sizeof(RegisterInfoPOSIX_arm::GPR) + \
29 sizeof(RegisterInfoPOSIX_arm::FPU))
30 #define DBG_OFFSET(reg) \
31 ((LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm::DBG, reg) + \
32 sizeof(RegisterInfoPOSIX_arm::GPR) + sizeof(RegisterInfoPOSIX_arm::FPU) + \
33 sizeof(RegisterInfoPOSIX_arm::EXC)))
35 #define DEFINE_DBG(reg, i) \
36 #reg, NULL, sizeof(((RegisterInfoPOSIX_arm::DBG *) NULL)->reg[i]), \
37 DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \
38 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
39 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
42 #define REG_CONTEXT_SIZE \
43 (sizeof(RegisterInfoPOSIX_arm::GPR) + sizeof(RegisterInfoPOSIX_arm::FPU) + \
44 sizeof(RegisterInfoPOSIX_arm::EXC))
46 // Include RegisterInfos_arm to declare our g_register_infos_arm structure.
47 #define DECLARE_REGISTER_INFOS_ARM_STRUCT
48 #include "RegisterInfos_arm.h"
49 #undef DECLARE_REGISTER_INFOS_ARM_STRUCT
51 static const lldb_private::RegisterInfo
*
52 GetRegisterInfoPtr(const lldb_private::ArchSpec
&target_arch
) {
53 switch (target_arch
.GetMachine()) {
54 case llvm::Triple::arm
:
55 return g_register_infos_arm
;
57 assert(false && "Unhandled target architecture.");
63 GetRegisterInfoCount(const lldb_private::ArchSpec
&target_arch
) {
64 switch (target_arch
.GetMachine()) {
65 case llvm::Triple::arm
:
66 return static_cast<uint32_t>(sizeof(g_register_infos_arm
) /
67 sizeof(g_register_infos_arm
[0]));
69 assert(false && "Unhandled target architecture.");
74 // Number of register sets provided by this context.
76 k_num_gpr_registers
= gpr_cpsr
- gpr_r0
+ 1,
77 k_num_fpr_registers
= fpu_q15
- fpu_s0
+ 1,
78 k_num_register_sets
= 2
81 // arm general purpose registers.
82 static const uint32_t g_gpr_regnums_arm
[] = {
91 gpr_cpsr
, LLDB_INVALID_REGNUM
// register sets need to end with this flag
93 static_assert(((sizeof g_gpr_regnums_arm
/ sizeof g_gpr_regnums_arm
[0]) - 1) ==
95 "g_gpr_regnums_arm has wrong number of register infos");
97 // arm floating point registers.
98 static const uint32_t g_fpu_regnums_arm
[] = {
139 fpu_q15
, LLDB_INVALID_REGNUM
// register sets need to end with this flag
141 static_assert(((sizeof g_fpu_regnums_arm
/ sizeof g_fpu_regnums_arm
[0]) - 1) ==
143 "g_fpu_regnums_arm has wrong number of register infos");
145 // Register sets for arm.
146 static const RegisterSet g_reg_sets_arm
[k_num_register_sets
] = {
147 {"General Purpose Registers", "gpr", k_num_gpr_registers
,
149 {"Floating Point Registers", "fpu", k_num_fpr_registers
,
152 RegisterInfoPOSIX_arm::RegisterInfoPOSIX_arm(
153 const lldb_private::ArchSpec
&target_arch
)
154 : lldb_private::RegisterInfoAndSetInterface(target_arch
),
155 m_register_info_p(GetRegisterInfoPtr(target_arch
)),
156 m_register_info_count(GetRegisterInfoCount(target_arch
)) {}
158 size_t RegisterInfoPOSIX_arm::GetGPRSize() const {
159 return sizeof(struct RegisterInfoPOSIX_arm::GPR
);
162 size_t RegisterInfoPOSIX_arm::GetFPRSize() const {
163 return sizeof(struct RegisterInfoPOSIX_arm::FPU
);
166 const lldb_private::RegisterInfo
*
167 RegisterInfoPOSIX_arm::GetRegisterInfo() const {
168 return m_register_info_p
;
171 size_t RegisterInfoPOSIX_arm::GetRegisterSetCount() const {
172 return k_num_register_sets
;
175 size_t RegisterInfoPOSIX_arm::GetRegisterSetFromRegisterIndex(
176 uint32_t reg_index
) const {
177 if (reg_index
<= gpr_cpsr
)
179 if (reg_index
<= fpu_q15
)
181 return LLDB_INVALID_REGNUM
;
184 const lldb_private::RegisterSet
*
185 RegisterInfoPOSIX_arm::GetRegisterSet(size_t set_index
) const {
186 if (set_index
< GetRegisterSetCount())
187 return &g_reg_sets_arm
[set_index
];
191 uint32_t RegisterInfoPOSIX_arm::GetRegisterCount() const {
192 return m_register_info_count
;