180814287SRaphael Isemann //===-- RegisterInfoPOSIX_arm.cpp -----------------------------------------===//
24b2b6bfbSPavel Labath //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64b2b6bfbSPavel Labath //
74b2b6bfbSPavel Labath //===---------------------------------------------------------------------===//
84b2b6bfbSPavel Labath 
94b2b6bfbSPavel Labath #include <cassert>
1076e47d48SRaphael Isemann #include <cstddef>
114b2b6bfbSPavel Labath #include <vector>
124b2b6bfbSPavel Labath 
134b2b6bfbSPavel Labath #include "lldb/lldb-defines.h"
144b2b6bfbSPavel Labath #include "llvm/Support/Compiler.h"
154b2b6bfbSPavel Labath 
164b2b6bfbSPavel Labath #include "RegisterInfoPOSIX_arm.h"
174b2b6bfbSPavel Labath 
184b2b6bfbSPavel Labath using namespace lldb;
194b2b6bfbSPavel Labath using namespace lldb_private;
204b2b6bfbSPavel Labath 
214b2b6bfbSPavel Labath // Based on RegisterContextDarwin_arm.cpp
224b2b6bfbSPavel Labath #define GPR_OFFSET(idx) ((idx)*4)
234b2b6bfbSPavel Labath #define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterInfoPOSIX_arm::GPR))
244b2b6bfbSPavel Labath #define FPSCR_OFFSET                                                           \
254b2b6bfbSPavel Labath   (LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm::FPU, fpscr) +                \
264b2b6bfbSPavel Labath    sizeof(RegisterInfoPOSIX_arm::GPR))
274b2b6bfbSPavel Labath #define EXC_OFFSET(idx)                                                        \
284b2b6bfbSPavel Labath   ((idx)*4 + sizeof(RegisterInfoPOSIX_arm::GPR) +                              \
294b2b6bfbSPavel Labath    sizeof(RegisterInfoPOSIX_arm::FPU))
304b2b6bfbSPavel Labath #define DBG_OFFSET(reg)                                                        \
314b2b6bfbSPavel Labath   ((LLVM_EXTENSION offsetof(RegisterInfoPOSIX_arm::DBG, reg) +                 \
324b2b6bfbSPavel Labath     sizeof(RegisterInfoPOSIX_arm::GPR) + sizeof(RegisterInfoPOSIX_arm::FPU) +  \
334b2b6bfbSPavel Labath     sizeof(RegisterInfoPOSIX_arm::EXC)))
344b2b6bfbSPavel Labath 
354b2b6bfbSPavel Labath #define DEFINE_DBG(reg, i)                                                     \
364b2b6bfbSPavel Labath   #reg, NULL, sizeof(((RegisterInfoPOSIX_arm::DBG *) NULL)->reg[i]),           \
374b2b6bfbSPavel Labath                       DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex,           \
384b2b6bfbSPavel Labath                                  {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    \
394b2b6bfbSPavel Labath                                   LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,    \
404b2b6bfbSPavel Labath                                   dbg_##reg##i },                              \
41*202af507SPavel Labath                                   NULL, NULL,
424b2b6bfbSPavel Labath #define REG_CONTEXT_SIZE                                                       \
434b2b6bfbSPavel Labath   (sizeof(RegisterInfoPOSIX_arm::GPR) + sizeof(RegisterInfoPOSIX_arm::FPU) +   \
444b2b6bfbSPavel Labath    sizeof(RegisterInfoPOSIX_arm::EXC))
454b2b6bfbSPavel Labath 
464b2b6bfbSPavel Labath // Include RegisterInfos_arm to declare our g_register_infos_arm structure.
474b2b6bfbSPavel Labath #define DECLARE_REGISTER_INFOS_ARM_STRUCT
484b2b6bfbSPavel Labath #include "RegisterInfos_arm.h"
494b2b6bfbSPavel Labath #undef DECLARE_REGISTER_INFOS_ARM_STRUCT
504b2b6bfbSPavel Labath 
514b2b6bfbSPavel Labath static const lldb_private::RegisterInfo *
GetRegisterInfoPtr(const lldb_private::ArchSpec & target_arch)524b2b6bfbSPavel Labath GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch) {
534b2b6bfbSPavel Labath   switch (target_arch.GetMachine()) {
544b2b6bfbSPavel Labath   case llvm::Triple::arm:
554b2b6bfbSPavel Labath     return g_register_infos_arm;
564b2b6bfbSPavel Labath   default:
574b2b6bfbSPavel Labath     assert(false && "Unhandled target architecture.");
58248a1305SKonrad Kleine     return nullptr;
594b2b6bfbSPavel Labath   }
604b2b6bfbSPavel Labath }
614b2b6bfbSPavel Labath 
624b2b6bfbSPavel Labath static uint32_t
GetRegisterInfoCount(const lldb_private::ArchSpec & target_arch)634b2b6bfbSPavel Labath GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch) {
644b2b6bfbSPavel Labath   switch (target_arch.GetMachine()) {
654b2b6bfbSPavel Labath   case llvm::Triple::arm:
664b2b6bfbSPavel Labath     return static_cast<uint32_t>(sizeof(g_register_infos_arm) /
674b2b6bfbSPavel Labath                                  sizeof(g_register_infos_arm[0]));
684b2b6bfbSPavel Labath   default:
694b2b6bfbSPavel Labath     assert(false && "Unhandled target architecture.");
704b2b6bfbSPavel Labath     return 0;
714b2b6bfbSPavel Labath   }
724b2b6bfbSPavel Labath }
734b2b6bfbSPavel Labath 
7476953321SMuhammad Omair Javaid // Number of register sets provided by this context.
7576953321SMuhammad Omair Javaid enum {
7676953321SMuhammad Omair Javaid   k_num_gpr_registers = gpr_cpsr - gpr_r0 + 1,
7776953321SMuhammad Omair Javaid   k_num_fpr_registers = fpu_q15 - fpu_s0 + 1,
7876953321SMuhammad Omair Javaid   k_num_register_sets = 2
7976953321SMuhammad Omair Javaid };
8076953321SMuhammad Omair Javaid 
8176953321SMuhammad Omair Javaid // arm general purpose registers.
8276953321SMuhammad Omair Javaid static const uint32_t g_gpr_regnums_arm[] = {
8376953321SMuhammad Omair Javaid     gpr_r0,   gpr_r1,
8476953321SMuhammad Omair Javaid     gpr_r2,   gpr_r3,
8576953321SMuhammad Omair Javaid     gpr_r4,   gpr_r5,
8676953321SMuhammad Omair Javaid     gpr_r6,   gpr_r7,
8776953321SMuhammad Omair Javaid     gpr_r8,   gpr_r9,
8876953321SMuhammad Omair Javaid     gpr_r10,  gpr_r11,
8976953321SMuhammad Omair Javaid     gpr_r12,  gpr_sp,
9076953321SMuhammad Omair Javaid     gpr_lr,   gpr_pc,
9176953321SMuhammad Omair Javaid     gpr_cpsr, LLDB_INVALID_REGNUM // register sets need to end with this flag
9276953321SMuhammad Omair Javaid };
9376953321SMuhammad Omair Javaid static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) ==
9476953321SMuhammad Omair Javaid                   k_num_gpr_registers,
9576953321SMuhammad Omair Javaid               "g_gpr_regnums_arm has wrong number of register infos");
9676953321SMuhammad Omair Javaid 
9776953321SMuhammad Omair Javaid // arm floating point registers.
9876953321SMuhammad Omair Javaid static const uint32_t g_fpu_regnums_arm[] = {
9976953321SMuhammad Omair Javaid     fpu_s0,    fpu_s1,
10076953321SMuhammad Omair Javaid     fpu_s2,    fpu_s3,
10176953321SMuhammad Omair Javaid     fpu_s4,    fpu_s5,
10276953321SMuhammad Omair Javaid     fpu_s6,    fpu_s7,
10376953321SMuhammad Omair Javaid     fpu_s8,    fpu_s9,
10476953321SMuhammad Omair Javaid     fpu_s10,   fpu_s11,
10576953321SMuhammad Omair Javaid     fpu_s12,   fpu_s13,
10676953321SMuhammad Omair Javaid     fpu_s14,   fpu_s15,
10776953321SMuhammad Omair Javaid     fpu_s16,   fpu_s17,
10876953321SMuhammad Omair Javaid     fpu_s18,   fpu_s19,
10976953321SMuhammad Omair Javaid     fpu_s20,   fpu_s21,
11076953321SMuhammad Omair Javaid     fpu_s22,   fpu_s23,
11176953321SMuhammad Omair Javaid     fpu_s24,   fpu_s25,
11276953321SMuhammad Omair Javaid     fpu_s26,   fpu_s27,
11376953321SMuhammad Omair Javaid     fpu_s28,   fpu_s29,
11476953321SMuhammad Omair Javaid     fpu_s30,   fpu_s31,
11576953321SMuhammad Omair Javaid     fpu_fpscr, fpu_d0,
11676953321SMuhammad Omair Javaid     fpu_d1,    fpu_d2,
11776953321SMuhammad Omair Javaid     fpu_d3,    fpu_d4,
11876953321SMuhammad Omair Javaid     fpu_d5,    fpu_d6,
11976953321SMuhammad Omair Javaid     fpu_d7,    fpu_d8,
12076953321SMuhammad Omair Javaid     fpu_d9,    fpu_d10,
12176953321SMuhammad Omair Javaid     fpu_d11,   fpu_d12,
12276953321SMuhammad Omair Javaid     fpu_d13,   fpu_d14,
12376953321SMuhammad Omair Javaid     fpu_d15,   fpu_d16,
12476953321SMuhammad Omair Javaid     fpu_d17,   fpu_d18,
12576953321SMuhammad Omair Javaid     fpu_d19,   fpu_d20,
12676953321SMuhammad Omair Javaid     fpu_d21,   fpu_d22,
12776953321SMuhammad Omair Javaid     fpu_d23,   fpu_d24,
12876953321SMuhammad Omair Javaid     fpu_d25,   fpu_d26,
12976953321SMuhammad Omair Javaid     fpu_d27,   fpu_d28,
13076953321SMuhammad Omair Javaid     fpu_d29,   fpu_d30,
13176953321SMuhammad Omair Javaid     fpu_d31,   fpu_q0,
13276953321SMuhammad Omair Javaid     fpu_q1,    fpu_q2,
13376953321SMuhammad Omair Javaid     fpu_q3,    fpu_q4,
13476953321SMuhammad Omair Javaid     fpu_q5,    fpu_q6,
13576953321SMuhammad Omair Javaid     fpu_q7,    fpu_q8,
13676953321SMuhammad Omair Javaid     fpu_q9,    fpu_q10,
13776953321SMuhammad Omair Javaid     fpu_q11,   fpu_q12,
13876953321SMuhammad Omair Javaid     fpu_q13,   fpu_q14,
13976953321SMuhammad Omair Javaid     fpu_q15,   LLDB_INVALID_REGNUM // register sets need to end with this flag
14076953321SMuhammad Omair Javaid };
14176953321SMuhammad Omair Javaid static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) ==
14276953321SMuhammad Omair Javaid                   k_num_fpr_registers,
14376953321SMuhammad Omair Javaid               "g_fpu_regnums_arm has wrong number of register infos");
14476953321SMuhammad Omair Javaid 
14576953321SMuhammad Omair Javaid // Register sets for arm.
14676953321SMuhammad Omair Javaid static const RegisterSet g_reg_sets_arm[k_num_register_sets] = {
14776953321SMuhammad Omair Javaid     {"General Purpose Registers", "gpr", k_num_gpr_registers,
14876953321SMuhammad Omair Javaid      g_gpr_regnums_arm},
14976953321SMuhammad Omair Javaid     {"Floating Point Registers", "fpu", k_num_fpr_registers,
15076953321SMuhammad Omair Javaid      g_fpu_regnums_arm}};
15176953321SMuhammad Omair Javaid 
RegisterInfoPOSIX_arm(const lldb_private::ArchSpec & target_arch)1524b2b6bfbSPavel Labath RegisterInfoPOSIX_arm::RegisterInfoPOSIX_arm(
1534b2b6bfbSPavel Labath     const lldb_private::ArchSpec &target_arch)
15476953321SMuhammad Omair Javaid     : lldb_private::RegisterInfoAndSetInterface(target_arch),
1554b2b6bfbSPavel Labath       m_register_info_p(GetRegisterInfoPtr(target_arch)),
1564b2b6bfbSPavel Labath       m_register_info_count(GetRegisterInfoCount(target_arch)) {}
1574b2b6bfbSPavel Labath 
GetGPRSize() const1584b2b6bfbSPavel Labath size_t RegisterInfoPOSIX_arm::GetGPRSize() const {
1594b2b6bfbSPavel Labath   return sizeof(struct RegisterInfoPOSIX_arm::GPR);
1604b2b6bfbSPavel Labath }
1614b2b6bfbSPavel Labath 
GetFPRSize() const16276953321SMuhammad Omair Javaid size_t RegisterInfoPOSIX_arm::GetFPRSize() const {
16376953321SMuhammad Omair Javaid   return sizeof(struct RegisterInfoPOSIX_arm::FPU);
16476953321SMuhammad Omair Javaid }
16576953321SMuhammad Omair Javaid 
1664b2b6bfbSPavel Labath const lldb_private::RegisterInfo *
GetRegisterInfo() const1674b2b6bfbSPavel Labath RegisterInfoPOSIX_arm::GetRegisterInfo() const {
1684b2b6bfbSPavel Labath   return m_register_info_p;
1694b2b6bfbSPavel Labath }
1704b2b6bfbSPavel Labath 
GetRegisterSetCount() const17176953321SMuhammad Omair Javaid size_t RegisterInfoPOSIX_arm::GetRegisterSetCount() const {
17276953321SMuhammad Omair Javaid   return k_num_register_sets;
17376953321SMuhammad Omair Javaid }
17476953321SMuhammad Omair Javaid 
GetRegisterSetFromRegisterIndex(uint32_t reg_index) const17576953321SMuhammad Omair Javaid size_t RegisterInfoPOSIX_arm::GetRegisterSetFromRegisterIndex(
17676953321SMuhammad Omair Javaid     uint32_t reg_index) const {
17776953321SMuhammad Omair Javaid   if (reg_index <= gpr_cpsr)
17876953321SMuhammad Omair Javaid     return GPRegSet;
17976953321SMuhammad Omair Javaid   if (reg_index <= fpu_q15)
18076953321SMuhammad Omair Javaid     return FPRegSet;
18176953321SMuhammad Omair Javaid   return LLDB_INVALID_REGNUM;
18276953321SMuhammad Omair Javaid }
18376953321SMuhammad Omair Javaid 
18476953321SMuhammad Omair Javaid const lldb_private::RegisterSet *
GetRegisterSet(size_t set_index) const18576953321SMuhammad Omair Javaid RegisterInfoPOSIX_arm::GetRegisterSet(size_t set_index) const {
18676953321SMuhammad Omair Javaid   if (set_index < GetRegisterSetCount())
18776953321SMuhammad Omair Javaid     return &g_reg_sets_arm[set_index];
18876953321SMuhammad Omair Javaid   return nullptr;
18976953321SMuhammad Omair Javaid }
19076953321SMuhammad Omair Javaid 
GetRegisterCount() const1914b2b6bfbSPavel Labath uint32_t RegisterInfoPOSIX_arm::GetRegisterCount() const {
1924b2b6bfbSPavel Labath   return m_register_info_count;
1934b2b6bfbSPavel Labath }
194