1a63d08c9SGreg Clayton //===-- RegisterContextDarwin_arm.cpp ---------------------------*- C++ -*-===//
2a63d08c9SGreg Clayton //
3a63d08c9SGreg Clayton //                     The LLVM Compiler Infrastructure
4a63d08c9SGreg Clayton //
5a63d08c9SGreg Clayton // This file is distributed under the University of Illinois Open Source
6a63d08c9SGreg Clayton // License. See LICENSE.TXT for details.
7a63d08c9SGreg Clayton //
8a63d08c9SGreg Clayton //===----------------------------------------------------------------------===//
9a63d08c9SGreg Clayton 
10a67dd8fcSPeter Collingbourne #if defined(__APPLE__)
11a67dd8fcSPeter Collingbourne 
12a63d08c9SGreg Clayton #include "RegisterContextDarwin_arm.h"
13a63d08c9SGreg Clayton 
14a63d08c9SGreg Clayton // C Includes
15a63d08c9SGreg Clayton #include <mach/mach_types.h>
16a63d08c9SGreg Clayton #include <mach/thread_act.h>
17a63d08c9SGreg Clayton 
18a63d08c9SGreg Clayton // C++ Includes
19a63d08c9SGreg Clayton // Other libraries and framework includes
20a63d08c9SGreg Clayton #include "lldb/Core/DataBufferHeap.h"
21a63d08c9SGreg Clayton #include "lldb/Core/DataExtractor.h"
22a63d08c9SGreg Clayton #include "lldb/Core/Log.h"
23a63d08c9SGreg Clayton #include "lldb/Core/RegisterValue.h"
24a63d08c9SGreg Clayton #include "lldb/Core/Scalar.h"
25a63d08c9SGreg Clayton #include "lldb/Host/Endian.h"
2612a19904SDaniel Dunbar #include "llvm/Support/Compiler.h"
2712a19904SDaniel Dunbar 
28dce502edSGreg Clayton #include "Plugins/Process/Utility/InstructionUtils.h"
29dce502edSGreg Clayton 
3012a19904SDaniel Dunbar // Support building against older versions of LLVM, this macro was added
3112a19904SDaniel Dunbar // recently.
3212a19904SDaniel Dunbar #ifndef LLVM_EXTENSION
3312a19904SDaniel Dunbar #define LLVM_EXTENSION
3412a19904SDaniel Dunbar #endif
35a63d08c9SGreg Clayton 
36a63d08c9SGreg Clayton // Project includes
37a63d08c9SGreg Clayton #include "ARM_GCC_Registers.h"
38a63d08c9SGreg Clayton #include "ARM_DWARF_Registers.h"
39a63d08c9SGreg Clayton 
40*28606954SSaleem Abdulrasool #include "llvm/ADT/STLExtras.h"
41*28606954SSaleem Abdulrasool 
42a63d08c9SGreg Clayton using namespace lldb;
43a63d08c9SGreg Clayton using namespace lldb_private;
44a63d08c9SGreg Clayton 
45a63d08c9SGreg Clayton enum
46a63d08c9SGreg Clayton {
47a63d08c9SGreg Clayton     gpr_r0 = 0,
48a63d08c9SGreg Clayton     gpr_r1,
49a63d08c9SGreg Clayton     gpr_r2,
50a63d08c9SGreg Clayton     gpr_r3,
51a63d08c9SGreg Clayton     gpr_r4,
52a63d08c9SGreg Clayton     gpr_r5,
53a63d08c9SGreg Clayton     gpr_r6,
54a63d08c9SGreg Clayton     gpr_r7,
55a63d08c9SGreg Clayton     gpr_r8,
56a63d08c9SGreg Clayton     gpr_r9,
57a63d08c9SGreg Clayton     gpr_r10,
58a63d08c9SGreg Clayton     gpr_r11,
59a63d08c9SGreg Clayton     gpr_r12,
60a63d08c9SGreg Clayton     gpr_r13, gpr_sp = gpr_r13,
61a63d08c9SGreg Clayton     gpr_r14, gpr_lr = gpr_r14,
62a63d08c9SGreg Clayton     gpr_r15, gpr_pc = gpr_r15,
63a63d08c9SGreg Clayton     gpr_cpsr,
64a63d08c9SGreg Clayton 
65a63d08c9SGreg Clayton     fpu_s0,
66a63d08c9SGreg Clayton     fpu_s1,
67a63d08c9SGreg Clayton     fpu_s2,
68a63d08c9SGreg Clayton     fpu_s3,
69a63d08c9SGreg Clayton     fpu_s4,
70a63d08c9SGreg Clayton     fpu_s5,
71a63d08c9SGreg Clayton     fpu_s6,
72a63d08c9SGreg Clayton     fpu_s7,
73a63d08c9SGreg Clayton     fpu_s8,
74a63d08c9SGreg Clayton     fpu_s9,
75a63d08c9SGreg Clayton     fpu_s10,
76a63d08c9SGreg Clayton     fpu_s11,
77a63d08c9SGreg Clayton     fpu_s12,
78a63d08c9SGreg Clayton     fpu_s13,
79a63d08c9SGreg Clayton     fpu_s14,
80a63d08c9SGreg Clayton     fpu_s15,
81a63d08c9SGreg Clayton     fpu_s16,
82a63d08c9SGreg Clayton     fpu_s17,
83a63d08c9SGreg Clayton     fpu_s18,
84a63d08c9SGreg Clayton     fpu_s19,
85a63d08c9SGreg Clayton     fpu_s20,
86a63d08c9SGreg Clayton     fpu_s21,
87a63d08c9SGreg Clayton     fpu_s22,
88a63d08c9SGreg Clayton     fpu_s23,
89a63d08c9SGreg Clayton     fpu_s24,
90a63d08c9SGreg Clayton     fpu_s25,
91a63d08c9SGreg Clayton     fpu_s26,
92a63d08c9SGreg Clayton     fpu_s27,
93a63d08c9SGreg Clayton     fpu_s28,
94a63d08c9SGreg Clayton     fpu_s29,
95a63d08c9SGreg Clayton     fpu_s30,
96a63d08c9SGreg Clayton     fpu_s31,
97a63d08c9SGreg Clayton     fpu_fpscr,
98a63d08c9SGreg Clayton 
99a63d08c9SGreg Clayton     exc_exception,
100a63d08c9SGreg Clayton     exc_fsr,
101a63d08c9SGreg Clayton     exc_far,
102a63d08c9SGreg Clayton 
103a63d08c9SGreg Clayton     dbg_bvr0,
104a63d08c9SGreg Clayton     dbg_bvr1,
105a63d08c9SGreg Clayton     dbg_bvr2,
106a63d08c9SGreg Clayton     dbg_bvr3,
107a63d08c9SGreg Clayton     dbg_bvr4,
108a63d08c9SGreg Clayton     dbg_bvr5,
109a63d08c9SGreg Clayton     dbg_bvr6,
110a63d08c9SGreg Clayton     dbg_bvr7,
111a63d08c9SGreg Clayton     dbg_bvr8,
112a63d08c9SGreg Clayton     dbg_bvr9,
113a63d08c9SGreg Clayton     dbg_bvr10,
114a63d08c9SGreg Clayton     dbg_bvr11,
115a63d08c9SGreg Clayton     dbg_bvr12,
116a63d08c9SGreg Clayton     dbg_bvr13,
117a63d08c9SGreg Clayton     dbg_bvr14,
118a63d08c9SGreg Clayton     dbg_bvr15,
119a63d08c9SGreg Clayton 
120a63d08c9SGreg Clayton     dbg_bcr0,
121a63d08c9SGreg Clayton     dbg_bcr1,
122a63d08c9SGreg Clayton     dbg_bcr2,
123a63d08c9SGreg Clayton     dbg_bcr3,
124a63d08c9SGreg Clayton     dbg_bcr4,
125a63d08c9SGreg Clayton     dbg_bcr5,
126a63d08c9SGreg Clayton     dbg_bcr6,
127a63d08c9SGreg Clayton     dbg_bcr7,
128a63d08c9SGreg Clayton     dbg_bcr8,
129a63d08c9SGreg Clayton     dbg_bcr9,
130a63d08c9SGreg Clayton     dbg_bcr10,
131a63d08c9SGreg Clayton     dbg_bcr11,
132a63d08c9SGreg Clayton     dbg_bcr12,
133a63d08c9SGreg Clayton     dbg_bcr13,
134a63d08c9SGreg Clayton     dbg_bcr14,
135a63d08c9SGreg Clayton     dbg_bcr15,
136a63d08c9SGreg Clayton 
137a63d08c9SGreg Clayton     dbg_wvr0,
138a63d08c9SGreg Clayton     dbg_wvr1,
139a63d08c9SGreg Clayton     dbg_wvr2,
140a63d08c9SGreg Clayton     dbg_wvr3,
141a63d08c9SGreg Clayton     dbg_wvr4,
142a63d08c9SGreg Clayton     dbg_wvr5,
143a63d08c9SGreg Clayton     dbg_wvr6,
144a63d08c9SGreg Clayton     dbg_wvr7,
145a63d08c9SGreg Clayton     dbg_wvr8,
146a63d08c9SGreg Clayton     dbg_wvr9,
147a63d08c9SGreg Clayton     dbg_wvr10,
148a63d08c9SGreg Clayton     dbg_wvr11,
149a63d08c9SGreg Clayton     dbg_wvr12,
150a63d08c9SGreg Clayton     dbg_wvr13,
151a63d08c9SGreg Clayton     dbg_wvr14,
152a63d08c9SGreg Clayton     dbg_wvr15,
153a63d08c9SGreg Clayton 
154a63d08c9SGreg Clayton     dbg_wcr0,
155a63d08c9SGreg Clayton     dbg_wcr1,
156a63d08c9SGreg Clayton     dbg_wcr2,
157a63d08c9SGreg Clayton     dbg_wcr3,
158a63d08c9SGreg Clayton     dbg_wcr4,
159a63d08c9SGreg Clayton     dbg_wcr5,
160a63d08c9SGreg Clayton     dbg_wcr6,
161a63d08c9SGreg Clayton     dbg_wcr7,
162a63d08c9SGreg Clayton     dbg_wcr8,
163a63d08c9SGreg Clayton     dbg_wcr9,
164a63d08c9SGreg Clayton     dbg_wcr10,
165a63d08c9SGreg Clayton     dbg_wcr11,
166a63d08c9SGreg Clayton     dbg_wcr12,
167a63d08c9SGreg Clayton     dbg_wcr13,
168a63d08c9SGreg Clayton     dbg_wcr14,
169a63d08c9SGreg Clayton     dbg_wcr15,
170a63d08c9SGreg Clayton 
171a63d08c9SGreg Clayton     k_num_registers
172a63d08c9SGreg Clayton };
173a63d08c9SGreg Clayton 
174a63d08c9SGreg Clayton 
175a63d08c9SGreg Clayton RegisterContextDarwin_arm::RegisterContextDarwin_arm(Thread &thread, uint32_t concrete_frame_idx) :
176a63d08c9SGreg Clayton     RegisterContext(thread, concrete_frame_idx),
177a63d08c9SGreg Clayton     gpr(),
178a63d08c9SGreg Clayton     fpu(),
179a63d08c9SGreg Clayton     exc()
180a63d08c9SGreg Clayton {
181a63d08c9SGreg Clayton     uint32_t i;
182a63d08c9SGreg Clayton     for (i=0; i<kNumErrors; i++)
183a63d08c9SGreg Clayton     {
184a63d08c9SGreg Clayton         gpr_errs[i] = -1;
185a63d08c9SGreg Clayton         fpu_errs[i] = -1;
186a63d08c9SGreg Clayton         exc_errs[i] = -1;
187a63d08c9SGreg Clayton     }
188a63d08c9SGreg Clayton }
189a63d08c9SGreg Clayton 
190a63d08c9SGreg Clayton RegisterContextDarwin_arm::~RegisterContextDarwin_arm()
191a63d08c9SGreg Clayton {
192a63d08c9SGreg Clayton }
193a63d08c9SGreg Clayton 
194a63d08c9SGreg Clayton 
195a63d08c9SGreg Clayton #define GPR_OFFSET(idx) ((idx) * 4)
196a63d08c9SGreg Clayton #define FPU_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR))
197a63d08c9SGreg Clayton #define EXC_OFFSET(idx) ((idx) * 4 + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU))
19812a19904SDaniel Dunbar #define DBG_OFFSET(reg) ((LLVM_EXTENSION offsetof (RegisterContextDarwin_arm::DBG, reg) + sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC)))
199a63d08c9SGreg Clayton 
200e979eda7SJohnny Chen #define DEFINE_DBG(reg, i)  #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *)NULL)->reg[i]), DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, dbg_##reg##i }, NULL, NULL
201a63d08c9SGreg Clayton #define REG_CONTEXT_SIZE (sizeof (RegisterContextDarwin_arm::GPR) + sizeof (RegisterContextDarwin_arm::FPU) + sizeof (RegisterContextDarwin_arm::EXC))
202a63d08c9SGreg Clayton 
203a63d08c9SGreg Clayton static RegisterInfo g_register_infos[] = {
204a63d08c9SGreg Clayton // General purpose registers
205e979eda7SJohnny Chen //  NAME        ALT     SZ  OFFSET              ENCODING        FORMAT          COMPILER                DWARF               GENERIC                     GDB                     LLDB NATIVE   VALUE REGS    INVALIDATE REGS
206e979eda7SJohnny Chen //  ======      ======= ==  =============       =============   ============    ===============         ===============     =========================   =====================   ============= ==========    ===============
207e979eda7SJohnny Chen {   "r0",       NULL,   4,  GPR_OFFSET(0),      eEncodingUint,  eFormatHex,     { gcc_r0,               dwarf_r0,           LLDB_INVALID_REGNUM,        gdb_arm_r0,             gpr_r0      },      NULL,              NULL},
208e979eda7SJohnny Chen {   "r1",       NULL,   4,  GPR_OFFSET(1),      eEncodingUint,  eFormatHex,     { gcc_r1,               dwarf_r1,           LLDB_INVALID_REGNUM,        gdb_arm_r1,             gpr_r1      },      NULL,              NULL},
209e979eda7SJohnny Chen {   "r2",       NULL,   4,  GPR_OFFSET(2),      eEncodingUint,  eFormatHex,     { gcc_r2,               dwarf_r2,           LLDB_INVALID_REGNUM,        gdb_arm_r2,             gpr_r2      },      NULL,              NULL},
210e979eda7SJohnny Chen {   "r3",       NULL,   4,  GPR_OFFSET(3),      eEncodingUint,  eFormatHex,     { gcc_r3,               dwarf_r3,           LLDB_INVALID_REGNUM,        gdb_arm_r3,             gpr_r3      },      NULL,              NULL},
211e979eda7SJohnny Chen {   "r4",       NULL,   4,  GPR_OFFSET(4),      eEncodingUint,  eFormatHex,     { gcc_r4,               dwarf_r4,           LLDB_INVALID_REGNUM,        gdb_arm_r4,             gpr_r4      },      NULL,              NULL},
212e979eda7SJohnny Chen {   "r5",       NULL,   4,  GPR_OFFSET(5),      eEncodingUint,  eFormatHex,     { gcc_r5,               dwarf_r5,           LLDB_INVALID_REGNUM,        gdb_arm_r5,             gpr_r5      },      NULL,              NULL},
213e979eda7SJohnny Chen {   "r6",       NULL,   4,  GPR_OFFSET(6),      eEncodingUint,  eFormatHex,     { gcc_r6,               dwarf_r6,           LLDB_INVALID_REGNUM,        gdb_arm_r6,             gpr_r6      },      NULL,              NULL},
214e979eda7SJohnny Chen {   "r7",       NULL,   4,  GPR_OFFSET(7),      eEncodingUint,  eFormatHex,     { gcc_r7,               dwarf_r7,           LLDB_REGNUM_GENERIC_FP,     gdb_arm_r7,             gpr_r7      },      NULL,              NULL},
215e979eda7SJohnny Chen {   "r8",       NULL,   4,  GPR_OFFSET(8),      eEncodingUint,  eFormatHex,     { gcc_r8,               dwarf_r8,           LLDB_INVALID_REGNUM,        gdb_arm_r8,             gpr_r8      },      NULL,              NULL},
216e979eda7SJohnny Chen {   "r9",       NULL,   4,  GPR_OFFSET(9),      eEncodingUint,  eFormatHex,     { gcc_r9,               dwarf_r9,           LLDB_INVALID_REGNUM,        gdb_arm_r9,             gpr_r9      },      NULL,              NULL},
217e979eda7SJohnny Chen {   "r10",      NULL,   4,  GPR_OFFSET(10),     eEncodingUint,  eFormatHex,     { gcc_r10,              dwarf_r10,          LLDB_INVALID_REGNUM,        gdb_arm_r10,            gpr_r10     },      NULL,              NULL},
218e979eda7SJohnny Chen {   "r11",      NULL,   4,  GPR_OFFSET(11),     eEncodingUint,  eFormatHex,     { gcc_r11,              dwarf_r11,          LLDB_INVALID_REGNUM,        gdb_arm_r11,            gpr_r11     },      NULL,              NULL},
219e979eda7SJohnny Chen {   "r12",      NULL,   4,  GPR_OFFSET(12),     eEncodingUint,  eFormatHex,     { gcc_r12,              dwarf_r12,          LLDB_INVALID_REGNUM,        gdb_arm_r12,            gpr_r12     },      NULL,              NULL},
220e979eda7SJohnny Chen {   "sp",       "r13",  4,  GPR_OFFSET(13),     eEncodingUint,  eFormatHex,     { gcc_sp,               dwarf_sp,           LLDB_REGNUM_GENERIC_SP,     gdb_arm_sp,             gpr_sp      },      NULL,              NULL},
221e979eda7SJohnny Chen {   "lr",       "r14",  4,  GPR_OFFSET(14),     eEncodingUint,  eFormatHex,     { gcc_lr,               dwarf_lr,           LLDB_REGNUM_GENERIC_RA,     gdb_arm_lr,             gpr_lr      },      NULL,              NULL},
222e979eda7SJohnny Chen {   "pc",       "r15",  4,  GPR_OFFSET(15),     eEncodingUint,  eFormatHex,     { gcc_pc,               dwarf_pc,           LLDB_REGNUM_GENERIC_PC,     gdb_arm_pc,             gpr_pc      },      NULL,              NULL},
223e979eda7SJohnny Chen {   "cpsr",     "psr",  4,  GPR_OFFSET(16),     eEncodingUint,  eFormatHex,     { gcc_cpsr,             dwarf_cpsr,         LLDB_REGNUM_GENERIC_FLAGS,  gdb_arm_cpsr,           gpr_cpsr    },      NULL,              NULL},
224a63d08c9SGreg Clayton 
225e979eda7SJohnny Chen {   "s0",       NULL,   4,  FPU_OFFSET(0),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s0,           LLDB_INVALID_REGNUM,        gdb_arm_s0,             fpu_s0      },      NULL,              NULL},
226e979eda7SJohnny Chen {   "s1",       NULL,   4,  FPU_OFFSET(1),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s1,           LLDB_INVALID_REGNUM,        gdb_arm_s1,             fpu_s1      },      NULL,              NULL},
227e979eda7SJohnny Chen {   "s2",       NULL,   4,  FPU_OFFSET(2),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s2,           LLDB_INVALID_REGNUM,        gdb_arm_s2,             fpu_s2      },      NULL,              NULL},
228e979eda7SJohnny Chen {   "s3",       NULL,   4,  FPU_OFFSET(3),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s3,           LLDB_INVALID_REGNUM,        gdb_arm_s3,             fpu_s3      },      NULL,              NULL},
229e979eda7SJohnny Chen {   "s4",       NULL,   4,  FPU_OFFSET(4),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s4,           LLDB_INVALID_REGNUM,        gdb_arm_s4,             fpu_s4      },      NULL,              NULL},
230e979eda7SJohnny Chen {   "s5",       NULL,   4,  FPU_OFFSET(5),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s5,           LLDB_INVALID_REGNUM,        gdb_arm_s5,             fpu_s5      },      NULL,              NULL},
231e979eda7SJohnny Chen {   "s6",       NULL,   4,  FPU_OFFSET(6),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s6,           LLDB_INVALID_REGNUM,        gdb_arm_s6,             fpu_s6      },      NULL,              NULL},
232e979eda7SJohnny Chen {   "s7",       NULL,   4,  FPU_OFFSET(7),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s7,           LLDB_INVALID_REGNUM,        gdb_arm_s7,             fpu_s7      },      NULL,              NULL},
233e979eda7SJohnny Chen {   "s8",       NULL,   4,  FPU_OFFSET(8),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s8,           LLDB_INVALID_REGNUM,        gdb_arm_s8,             fpu_s8      },      NULL,              NULL},
234e979eda7SJohnny Chen {   "s9",       NULL,   4,  FPU_OFFSET(9),      eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s9,           LLDB_INVALID_REGNUM,        gdb_arm_s9,             fpu_s9      },      NULL,              NULL},
235e979eda7SJohnny Chen {   "s10",      NULL,   4,  FPU_OFFSET(10),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s10,          LLDB_INVALID_REGNUM,        gdb_arm_s10,            fpu_s10     },      NULL,              NULL},
236e979eda7SJohnny Chen {   "s11",      NULL,   4,  FPU_OFFSET(11),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s11,          LLDB_INVALID_REGNUM,        gdb_arm_s11,            fpu_s11     },      NULL,              NULL},
237e979eda7SJohnny Chen {   "s12",      NULL,   4,  FPU_OFFSET(12),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s12,          LLDB_INVALID_REGNUM,        gdb_arm_s12,            fpu_s12     },      NULL,              NULL},
238e979eda7SJohnny Chen {   "s13",      NULL,   4,  FPU_OFFSET(13),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s13,          LLDB_INVALID_REGNUM,        gdb_arm_s13,            fpu_s13     },      NULL,              NULL},
239e979eda7SJohnny Chen {   "s14",      NULL,   4,  FPU_OFFSET(14),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s14,          LLDB_INVALID_REGNUM,        gdb_arm_s14,            fpu_s14     },      NULL,              NULL},
240e979eda7SJohnny Chen {   "s15",      NULL,   4,  FPU_OFFSET(15),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s15,          LLDB_INVALID_REGNUM,        gdb_arm_s15,            fpu_s15     },      NULL,              NULL},
241e979eda7SJohnny Chen {   "s16",      NULL,   4,  FPU_OFFSET(16),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s16,          LLDB_INVALID_REGNUM,        gdb_arm_s16,            fpu_s16     },      NULL,              NULL},
242e979eda7SJohnny Chen {   "s17",      NULL,   4,  FPU_OFFSET(17),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s17,          LLDB_INVALID_REGNUM,        gdb_arm_s17,            fpu_s17     },      NULL,              NULL},
243e979eda7SJohnny Chen {   "s18",      NULL,   4,  FPU_OFFSET(18),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s18,          LLDB_INVALID_REGNUM,        gdb_arm_s18,            fpu_s18     },      NULL,              NULL},
244e979eda7SJohnny Chen {   "s19",      NULL,   4,  FPU_OFFSET(19),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s19,          LLDB_INVALID_REGNUM,        gdb_arm_s19,            fpu_s19     },      NULL,              NULL},
245e979eda7SJohnny Chen {   "s20",      NULL,   4,  FPU_OFFSET(20),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s20,          LLDB_INVALID_REGNUM,        gdb_arm_s20,            fpu_s20     },      NULL,              NULL},
246e979eda7SJohnny Chen {   "s21",      NULL,   4,  FPU_OFFSET(21),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s21,          LLDB_INVALID_REGNUM,        gdb_arm_s21,            fpu_s21     },      NULL,              NULL},
247e979eda7SJohnny Chen {   "s22",      NULL,   4,  FPU_OFFSET(22),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s22,          LLDB_INVALID_REGNUM,        gdb_arm_s22,            fpu_s22     },      NULL,              NULL},
248e979eda7SJohnny Chen {   "s23",      NULL,   4,  FPU_OFFSET(23),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s23,          LLDB_INVALID_REGNUM,        gdb_arm_s23,            fpu_s23     },      NULL,              NULL},
249e979eda7SJohnny Chen {   "s24",      NULL,   4,  FPU_OFFSET(24),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s24,          LLDB_INVALID_REGNUM,        gdb_arm_s24,            fpu_s24     },      NULL,              NULL},
250e979eda7SJohnny Chen {   "s25",      NULL,   4,  FPU_OFFSET(25),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s25,          LLDB_INVALID_REGNUM,        gdb_arm_s25,            fpu_s25     },      NULL,              NULL},
251e979eda7SJohnny Chen {   "s26",      NULL,   4,  FPU_OFFSET(26),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s26,          LLDB_INVALID_REGNUM,        gdb_arm_s26,            fpu_s26     },      NULL,              NULL},
252e979eda7SJohnny Chen {   "s27",      NULL,   4,  FPU_OFFSET(27),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s27,          LLDB_INVALID_REGNUM,        gdb_arm_s27,            fpu_s27     },      NULL,              NULL},
253e979eda7SJohnny Chen {   "s28",      NULL,   4,  FPU_OFFSET(28),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s28,          LLDB_INVALID_REGNUM,        gdb_arm_s28,            fpu_s28     },      NULL,              NULL},
254e979eda7SJohnny Chen {   "s29",      NULL,   4,  FPU_OFFSET(29),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s29,          LLDB_INVALID_REGNUM,        gdb_arm_s29,            fpu_s29     },      NULL,              NULL},
255e979eda7SJohnny Chen {   "s30",      NULL,   4,  FPU_OFFSET(30),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s30,          LLDB_INVALID_REGNUM,        gdb_arm_s30,            fpu_s30     },      NULL,              NULL},
256e979eda7SJohnny Chen {   "s31",      NULL,   4,  FPU_OFFSET(31),     eEncodingIEEE754,eFormatFloat,  { LLDB_INVALID_REGNUM,  dwarf_s31,          LLDB_INVALID_REGNUM,        gdb_arm_s31,            fpu_s31     },      NULL,              NULL},
257e979eda7SJohnny Chen {   "fpscr",    NULL,   4,  FPU_OFFSET(32),     eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        gdb_arm_fpscr,          fpu_fpscr   },      NULL,              NULL},
258a63d08c9SGreg Clayton 
259e979eda7SJohnny Chen {   "exception",NULL,   4,  EXC_OFFSET(0),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_exception },    NULL,              NULL},
260e979eda7SJohnny Chen {   "fsr",      NULL,   4,  EXC_OFFSET(1),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_fsr       },    NULL,              NULL},
261e979eda7SJohnny Chen {   "far",      NULL,   4,  EXC_OFFSET(2),      eEncodingUint,  eFormatHex,     { LLDB_INVALID_REGNUM,  LLDB_INVALID_REGNUM,LLDB_INVALID_REGNUM,        LLDB_INVALID_REGNUM,    exc_far       },    NULL,              NULL},
262a63d08c9SGreg Clayton 
263a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 0) },
264a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 1) },
265a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 2) },
266a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 3) },
267a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 4) },
268a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 5) },
269a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 6) },
270a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 7) },
271a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 8) },
272a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 9) },
273a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 10) },
274a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 11) },
275a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 12) },
276a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 13) },
277a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 14) },
278a63d08c9SGreg Clayton {   DEFINE_DBG (bvr, 15) },
279a63d08c9SGreg Clayton 
280a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 0) },
281a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 1) },
282a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 2) },
283a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 3) },
284a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 4) },
285a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 5) },
286a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 6) },
287a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 7) },
288a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 8) },
289a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 9) },
290a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 10) },
291a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 11) },
292a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 12) },
293a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 13) },
294a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 14) },
295a63d08c9SGreg Clayton {   DEFINE_DBG (bcr, 15) },
296a63d08c9SGreg Clayton 
297a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 0) },
298a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 1) },
299a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 2) },
300a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 3) },
301a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 4) },
302a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 5) },
303a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 6) },
304a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 7) },
305a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 8) },
306a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 9) },
307a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 10) },
308a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 11) },
309a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 12) },
310a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 13) },
311a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 14) },
312a63d08c9SGreg Clayton {   DEFINE_DBG (wvr, 15) },
313a63d08c9SGreg Clayton 
314a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 0) },
315a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 1) },
316a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 2) },
317a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 3) },
318a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 4) },
319a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 5) },
320a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 6) },
321a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 7) },
322a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 8) },
323a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 9) },
324a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 10) },
325a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 11) },
326a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 12) },
327a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 13) },
328a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 14) },
329a63d08c9SGreg Clayton {   DEFINE_DBG (wcr, 15) }
330a63d08c9SGreg Clayton };
331a63d08c9SGreg Clayton 
332a63d08c9SGreg Clayton // General purpose registers
333a63d08c9SGreg Clayton static uint32_t
334a63d08c9SGreg Clayton g_gpr_regnums[] =
335a63d08c9SGreg Clayton {
336a63d08c9SGreg Clayton     gpr_r0,
337a63d08c9SGreg Clayton     gpr_r1,
338a63d08c9SGreg Clayton     gpr_r2,
339a63d08c9SGreg Clayton     gpr_r3,
340a63d08c9SGreg Clayton     gpr_r4,
341a63d08c9SGreg Clayton     gpr_r5,
342a63d08c9SGreg Clayton     gpr_r6,
343a63d08c9SGreg Clayton     gpr_r7,
344a63d08c9SGreg Clayton     gpr_r8,
345a63d08c9SGreg Clayton     gpr_r9,
346a63d08c9SGreg Clayton     gpr_r10,
347a63d08c9SGreg Clayton     gpr_r11,
348a63d08c9SGreg Clayton     gpr_r12,
349a63d08c9SGreg Clayton     gpr_sp,
350a63d08c9SGreg Clayton     gpr_lr,
351a63d08c9SGreg Clayton     gpr_pc,
352a63d08c9SGreg Clayton     gpr_cpsr
353a63d08c9SGreg Clayton };
354a63d08c9SGreg Clayton 
355a63d08c9SGreg Clayton // Floating point registers
356a63d08c9SGreg Clayton static uint32_t
357a63d08c9SGreg Clayton g_fpu_regnums[] =
358a63d08c9SGreg Clayton {
359a63d08c9SGreg Clayton     fpu_s0,
360a63d08c9SGreg Clayton     fpu_s1,
361a63d08c9SGreg Clayton     fpu_s2,
362a63d08c9SGreg Clayton     fpu_s3,
363a63d08c9SGreg Clayton     fpu_s4,
364a63d08c9SGreg Clayton     fpu_s5,
365a63d08c9SGreg Clayton     fpu_s6,
366a63d08c9SGreg Clayton     fpu_s7,
367a63d08c9SGreg Clayton     fpu_s8,
368a63d08c9SGreg Clayton     fpu_s9,
369a63d08c9SGreg Clayton     fpu_s10,
370a63d08c9SGreg Clayton     fpu_s11,
371a63d08c9SGreg Clayton     fpu_s12,
372a63d08c9SGreg Clayton     fpu_s13,
373a63d08c9SGreg Clayton     fpu_s14,
374a63d08c9SGreg Clayton     fpu_s15,
375a63d08c9SGreg Clayton     fpu_s16,
376a63d08c9SGreg Clayton     fpu_s17,
377a63d08c9SGreg Clayton     fpu_s18,
378a63d08c9SGreg Clayton     fpu_s19,
379a63d08c9SGreg Clayton     fpu_s20,
380a63d08c9SGreg Clayton     fpu_s21,
381a63d08c9SGreg Clayton     fpu_s22,
382a63d08c9SGreg Clayton     fpu_s23,
383a63d08c9SGreg Clayton     fpu_s24,
384a63d08c9SGreg Clayton     fpu_s25,
385a63d08c9SGreg Clayton     fpu_s26,
386a63d08c9SGreg Clayton     fpu_s27,
387a63d08c9SGreg Clayton     fpu_s28,
388a63d08c9SGreg Clayton     fpu_s29,
389a63d08c9SGreg Clayton     fpu_s30,
390a63d08c9SGreg Clayton     fpu_s31,
391a63d08c9SGreg Clayton     fpu_fpscr,
392a63d08c9SGreg Clayton };
393a63d08c9SGreg Clayton 
394a63d08c9SGreg Clayton // Exception registers
395a63d08c9SGreg Clayton 
396a63d08c9SGreg Clayton static uint32_t
397a63d08c9SGreg Clayton g_exc_regnums[] =
398a63d08c9SGreg Clayton {
399a63d08c9SGreg Clayton     exc_exception,
400a63d08c9SGreg Clayton     exc_fsr,
401a63d08c9SGreg Clayton     exc_far,
402a63d08c9SGreg Clayton };
403a63d08c9SGreg Clayton 
404*28606954SSaleem Abdulrasool static size_t k_num_register_infos = llvm::array_lengthof(g_register_infos);
405a63d08c9SGreg Clayton 
406a63d08c9SGreg Clayton void
407a63d08c9SGreg Clayton RegisterContextDarwin_arm::InvalidateAllRegisters ()
408a63d08c9SGreg Clayton {
409a63d08c9SGreg Clayton     InvalidateAllRegisterStates();
410a63d08c9SGreg Clayton }
411a63d08c9SGreg Clayton 
412a63d08c9SGreg Clayton 
413a63d08c9SGreg Clayton size_t
414a63d08c9SGreg Clayton RegisterContextDarwin_arm::GetRegisterCount ()
415a63d08c9SGreg Clayton {
416a63d08c9SGreg Clayton     assert(k_num_register_infos == k_num_registers);
417a63d08c9SGreg Clayton     return k_num_registers;
418a63d08c9SGreg Clayton }
419a63d08c9SGreg Clayton 
420a63d08c9SGreg Clayton const RegisterInfo *
421c7bece56SGreg Clayton RegisterContextDarwin_arm::GetRegisterInfoAtIndex (size_t reg)
422a63d08c9SGreg Clayton {
423a63d08c9SGreg Clayton     assert(k_num_register_infos == k_num_registers);
424a63d08c9SGreg Clayton     if (reg < k_num_registers)
425a63d08c9SGreg Clayton         return &g_register_infos[reg];
426a63d08c9SGreg Clayton     return NULL;
427a63d08c9SGreg Clayton }
428a63d08c9SGreg Clayton 
429a63d08c9SGreg Clayton size_t
430a63d08c9SGreg Clayton RegisterContextDarwin_arm::GetRegisterInfosCount ()
431a63d08c9SGreg Clayton {
432a63d08c9SGreg Clayton     return k_num_register_infos;
433a63d08c9SGreg Clayton }
434a63d08c9SGreg Clayton 
435a63d08c9SGreg Clayton const RegisterInfo *
436a63d08c9SGreg Clayton RegisterContextDarwin_arm::GetRegisterInfos ()
437a63d08c9SGreg Clayton {
438a63d08c9SGreg Clayton     return g_register_infos;
439a63d08c9SGreg Clayton }
440a63d08c9SGreg Clayton 
441a63d08c9SGreg Clayton 
442a63d08c9SGreg Clayton // Number of registers in each register set
443*28606954SSaleem Abdulrasool const size_t k_num_gpr_registers = llvm::array_lengthof(g_gpr_regnums);
444*28606954SSaleem Abdulrasool const size_t k_num_fpu_registers = llvm::array_lengthof(g_fpu_regnums);
445*28606954SSaleem Abdulrasool const size_t k_num_exc_registers = llvm::array_lengthof(g_exc_regnums);
446a63d08c9SGreg Clayton 
447a63d08c9SGreg Clayton //----------------------------------------------------------------------
448a63d08c9SGreg Clayton // Register set definitions. The first definitions at register set index
449a63d08c9SGreg Clayton // of zero is for all registers, followed by other registers sets. The
450a63d08c9SGreg Clayton // register information for the all register set need not be filled in.
451a63d08c9SGreg Clayton //----------------------------------------------------------------------
452a63d08c9SGreg Clayton static const RegisterSet g_reg_sets[] =
453a63d08c9SGreg Clayton {
454a63d08c9SGreg Clayton     { "General Purpose Registers",  "gpr",  k_num_gpr_registers,    g_gpr_regnums,      },
455a63d08c9SGreg Clayton     { "Floating Point Registers",   "fpu",  k_num_fpu_registers,    g_fpu_regnums       },
456a63d08c9SGreg Clayton     { "Exception State Registers",  "exc",  k_num_exc_registers,    g_exc_regnums       }
457a63d08c9SGreg Clayton };
458a63d08c9SGreg Clayton 
459*28606954SSaleem Abdulrasool const size_t k_num_regsets = llvm::array_lengthof(g_reg_sets);
460a63d08c9SGreg Clayton 
461a63d08c9SGreg Clayton 
462a63d08c9SGreg Clayton size_t
463a63d08c9SGreg Clayton RegisterContextDarwin_arm::GetRegisterSetCount ()
464a63d08c9SGreg Clayton {
465a63d08c9SGreg Clayton     return k_num_regsets;
466a63d08c9SGreg Clayton }
467a63d08c9SGreg Clayton 
468a63d08c9SGreg Clayton const RegisterSet *
469c7bece56SGreg Clayton RegisterContextDarwin_arm::GetRegisterSet (size_t reg_set)
470a63d08c9SGreg Clayton {
471a63d08c9SGreg Clayton     if (reg_set < k_num_regsets)
472a63d08c9SGreg Clayton         return &g_reg_sets[reg_set];
473a63d08c9SGreg Clayton     return NULL;
474a63d08c9SGreg Clayton }
475a63d08c9SGreg Clayton 
476a63d08c9SGreg Clayton 
477a63d08c9SGreg Clayton //----------------------------------------------------------------------
478a63d08c9SGreg Clayton // Register information defintions for 32 bit i386.
479a63d08c9SGreg Clayton //----------------------------------------------------------------------
480a63d08c9SGreg Clayton int
481a63d08c9SGreg Clayton RegisterContextDarwin_arm::GetSetForNativeRegNum (int reg)
482a63d08c9SGreg Clayton {
483a63d08c9SGreg Clayton     if (reg < fpu_s0)
484a63d08c9SGreg Clayton         return GPRRegSet;
485a63d08c9SGreg Clayton     else if (reg < exc_exception)
486a63d08c9SGreg Clayton         return FPURegSet;
487a63d08c9SGreg Clayton     else if (reg < k_num_registers)
488a63d08c9SGreg Clayton         return EXCRegSet;
489a63d08c9SGreg Clayton     return -1;
490a63d08c9SGreg Clayton }
491a63d08c9SGreg Clayton 
492a63d08c9SGreg Clayton int
493a63d08c9SGreg Clayton RegisterContextDarwin_arm::ReadGPR (bool force)
494a63d08c9SGreg Clayton {
495a63d08c9SGreg Clayton     int set = GPRRegSet;
496a63d08c9SGreg Clayton     if (force || !RegisterSetIsCached(set))
497a63d08c9SGreg Clayton     {
498a63d08c9SGreg Clayton         SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
499a63d08c9SGreg Clayton     }
500a63d08c9SGreg Clayton     return GetError(GPRRegSet, Read);
501a63d08c9SGreg Clayton }
502a63d08c9SGreg Clayton 
503a63d08c9SGreg Clayton int
504a63d08c9SGreg Clayton RegisterContextDarwin_arm::ReadFPU (bool force)
505a63d08c9SGreg Clayton {
506a63d08c9SGreg Clayton     int set = FPURegSet;
507a63d08c9SGreg Clayton     if (force || !RegisterSetIsCached(set))
508a63d08c9SGreg Clayton     {
509a63d08c9SGreg Clayton         SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
510a63d08c9SGreg Clayton     }
511a63d08c9SGreg Clayton     return GetError(FPURegSet, Read);
512a63d08c9SGreg Clayton }
513a63d08c9SGreg Clayton 
514a63d08c9SGreg Clayton int
515a63d08c9SGreg Clayton RegisterContextDarwin_arm::ReadEXC (bool force)
516a63d08c9SGreg Clayton {
517a63d08c9SGreg Clayton     int set = EXCRegSet;
518a63d08c9SGreg Clayton     if (force || !RegisterSetIsCached(set))
519a63d08c9SGreg Clayton     {
520a63d08c9SGreg Clayton         SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
521a63d08c9SGreg Clayton     }
522a63d08c9SGreg Clayton     return GetError(EXCRegSet, Read);
523a63d08c9SGreg Clayton }
524a63d08c9SGreg Clayton 
525a63d08c9SGreg Clayton int
526a63d08c9SGreg Clayton RegisterContextDarwin_arm::ReadDBG (bool force)
527a63d08c9SGreg Clayton {
528a63d08c9SGreg Clayton     int set = DBGRegSet;
529a63d08c9SGreg Clayton     if (force || !RegisterSetIsCached(set))
530a63d08c9SGreg Clayton     {
531a63d08c9SGreg Clayton         SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));
532a63d08c9SGreg Clayton     }
533a63d08c9SGreg Clayton     return GetError(DBGRegSet, Read);
534a63d08c9SGreg Clayton }
535a63d08c9SGreg Clayton 
536a63d08c9SGreg Clayton int
537a63d08c9SGreg Clayton RegisterContextDarwin_arm::WriteGPR ()
538a63d08c9SGreg Clayton {
539a63d08c9SGreg Clayton     int set = GPRRegSet;
540a63d08c9SGreg Clayton     if (!RegisterSetIsCached(set))
541a63d08c9SGreg Clayton     {
542a63d08c9SGreg Clayton         SetError (set, Write, -1);
543a63d08c9SGreg Clayton         return KERN_INVALID_ARGUMENT;
544a63d08c9SGreg Clayton     }
545a63d08c9SGreg Clayton     SetError (set, Write, DoWriteGPR(GetThreadID(), set, gpr));
546a63d08c9SGreg Clayton     SetError (set, Read, -1);
547a63d08c9SGreg Clayton     return GetError(GPRRegSet, Write);
548a63d08c9SGreg Clayton }
549a63d08c9SGreg Clayton 
550a63d08c9SGreg Clayton int
551a63d08c9SGreg Clayton RegisterContextDarwin_arm::WriteFPU ()
552a63d08c9SGreg Clayton {
553a63d08c9SGreg Clayton     int set = FPURegSet;
554a63d08c9SGreg Clayton     if (!RegisterSetIsCached(set))
555a63d08c9SGreg Clayton     {
556a63d08c9SGreg Clayton         SetError (set, Write, -1);
557a63d08c9SGreg Clayton         return KERN_INVALID_ARGUMENT;
558a63d08c9SGreg Clayton     }
559a63d08c9SGreg Clayton     SetError (set, Write, DoWriteFPU(GetThreadID(), set, fpu));
560a63d08c9SGreg Clayton     SetError (set, Read, -1);
561a63d08c9SGreg Clayton     return GetError(FPURegSet, Write);
562a63d08c9SGreg Clayton }
563a63d08c9SGreg Clayton 
564a63d08c9SGreg Clayton int
565a63d08c9SGreg Clayton RegisterContextDarwin_arm::WriteEXC ()
566a63d08c9SGreg Clayton {
567a63d08c9SGreg Clayton     int set = EXCRegSet;
568a63d08c9SGreg Clayton     if (!RegisterSetIsCached(set))
569a63d08c9SGreg Clayton     {
570a63d08c9SGreg Clayton         SetError (set, Write, -1);
571a63d08c9SGreg Clayton         return KERN_INVALID_ARGUMENT;
572a63d08c9SGreg Clayton     }
573a63d08c9SGreg Clayton     SetError (set, Write, DoWriteEXC(GetThreadID(), set, exc));
574a63d08c9SGreg Clayton     SetError (set, Read, -1);
575a63d08c9SGreg Clayton     return GetError(EXCRegSet, Write);
576a63d08c9SGreg Clayton }
577a63d08c9SGreg Clayton 
578a63d08c9SGreg Clayton int
579a63d08c9SGreg Clayton RegisterContextDarwin_arm::WriteDBG ()
580a63d08c9SGreg Clayton {
581a63d08c9SGreg Clayton     int set = DBGRegSet;
582a63d08c9SGreg Clayton     if (!RegisterSetIsCached(set))
583a63d08c9SGreg Clayton     {
584a63d08c9SGreg Clayton         SetError (set, Write, -1);
585a63d08c9SGreg Clayton         return KERN_INVALID_ARGUMENT;
586a63d08c9SGreg Clayton     }
587a63d08c9SGreg Clayton     SetError (set, Write, DoWriteDBG(GetThreadID(), set, dbg));
588a63d08c9SGreg Clayton     SetError (set, Read, -1);
589a63d08c9SGreg Clayton     return GetError(DBGRegSet, Write);
590a63d08c9SGreg Clayton }
591a63d08c9SGreg Clayton 
592a63d08c9SGreg Clayton 
593a63d08c9SGreg Clayton int
594a63d08c9SGreg Clayton RegisterContextDarwin_arm::ReadRegisterSet (uint32_t set, bool force)
595a63d08c9SGreg Clayton {
596a63d08c9SGreg Clayton     switch (set)
597a63d08c9SGreg Clayton     {
598a63d08c9SGreg Clayton     case GPRRegSet:    return ReadGPR(force);
599a63d08c9SGreg Clayton     case FPURegSet:    return ReadFPU(force);
600a63d08c9SGreg Clayton     case EXCRegSet:    return ReadEXC(force);
601a63d08c9SGreg Clayton     case DBGRegSet:    return ReadDBG(force);
602a63d08c9SGreg Clayton     default: break;
603a63d08c9SGreg Clayton     }
604a63d08c9SGreg Clayton     return KERN_INVALID_ARGUMENT;
605a63d08c9SGreg Clayton }
606a63d08c9SGreg Clayton 
607a63d08c9SGreg Clayton int
608a63d08c9SGreg Clayton RegisterContextDarwin_arm::WriteRegisterSet (uint32_t set)
609a63d08c9SGreg Clayton {
610a63d08c9SGreg Clayton     // Make sure we have a valid context to set.
611a63d08c9SGreg Clayton     if (RegisterSetIsCached(set))
612a63d08c9SGreg Clayton     {
613a63d08c9SGreg Clayton         switch (set)
614a63d08c9SGreg Clayton         {
615a63d08c9SGreg Clayton         case GPRRegSet:    return WriteGPR();
616a63d08c9SGreg Clayton         case FPURegSet:    return WriteFPU();
617a63d08c9SGreg Clayton         case EXCRegSet:    return WriteEXC();
618a63d08c9SGreg Clayton         case DBGRegSet:    return WriteDBG();
619a63d08c9SGreg Clayton         default: break;
620a63d08c9SGreg Clayton         }
621a63d08c9SGreg Clayton     }
622a63d08c9SGreg Clayton     return KERN_INVALID_ARGUMENT;
623a63d08c9SGreg Clayton }
624a63d08c9SGreg Clayton 
625a63d08c9SGreg Clayton void
626a63d08c9SGreg Clayton RegisterContextDarwin_arm::LogDBGRegisters (Log *log, const DBG& dbg)
627a63d08c9SGreg Clayton {
628a63d08c9SGreg Clayton     if (log)
629a63d08c9SGreg Clayton     {
630a63d08c9SGreg Clayton         for (uint32_t i=0; i<16; i++)
631a63d08c9SGreg Clayton             log->Printf("BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { 0x%8.8x, 0x%8.8x }",
632a63d08c9SGreg Clayton                 i, i, dbg.bvr[i], dbg.bcr[i],
633a63d08c9SGreg Clayton                 i, i, dbg.wvr[i], dbg.wcr[i]);
634a63d08c9SGreg Clayton     }
635a63d08c9SGreg Clayton }
636a63d08c9SGreg Clayton 
637a63d08c9SGreg Clayton 
638a63d08c9SGreg Clayton bool
639a63d08c9SGreg Clayton RegisterContextDarwin_arm::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value)
640a63d08c9SGreg Clayton {
641a63d08c9SGreg Clayton     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
642a63d08c9SGreg Clayton     int set = RegisterContextDarwin_arm::GetSetForNativeRegNum (reg);
643a63d08c9SGreg Clayton 
644a63d08c9SGreg Clayton     if (set == -1)
645a63d08c9SGreg Clayton         return false;
646a63d08c9SGreg Clayton 
647a63d08c9SGreg Clayton     if (ReadRegisterSet(set, false) != KERN_SUCCESS)
648a63d08c9SGreg Clayton         return false;
649a63d08c9SGreg Clayton 
650a63d08c9SGreg Clayton     switch (reg)
651a63d08c9SGreg Clayton     {
652a63d08c9SGreg Clayton     case gpr_r0:
653a63d08c9SGreg Clayton     case gpr_r1:
654a63d08c9SGreg Clayton     case gpr_r2:
655a63d08c9SGreg Clayton     case gpr_r3:
656a63d08c9SGreg Clayton     case gpr_r4:
657a63d08c9SGreg Clayton     case gpr_r5:
658a63d08c9SGreg Clayton     case gpr_r6:
659a63d08c9SGreg Clayton     case gpr_r7:
660a63d08c9SGreg Clayton     case gpr_r8:
661a63d08c9SGreg Clayton     case gpr_r9:
662a63d08c9SGreg Clayton     case gpr_r10:
663a63d08c9SGreg Clayton     case gpr_r11:
664a63d08c9SGreg Clayton     case gpr_r12:
665a63d08c9SGreg Clayton     case gpr_sp:
666a63d08c9SGreg Clayton     case gpr_lr:
667a63d08c9SGreg Clayton     case gpr_pc:
668a63d08c9SGreg Clayton     case gpr_cpsr:
669a63d08c9SGreg Clayton         value.SetUInt32 (gpr.r[reg - gpr_r0]);
670a63d08c9SGreg Clayton         break;
671a63d08c9SGreg Clayton 
672a63d08c9SGreg Clayton     case fpu_s0:
673a63d08c9SGreg Clayton     case fpu_s1:
674a63d08c9SGreg Clayton     case fpu_s2:
675a63d08c9SGreg Clayton     case fpu_s3:
676a63d08c9SGreg Clayton     case fpu_s4:
677a63d08c9SGreg Clayton     case fpu_s5:
678a63d08c9SGreg Clayton     case fpu_s6:
679a63d08c9SGreg Clayton     case fpu_s7:
680a63d08c9SGreg Clayton     case fpu_s8:
681a63d08c9SGreg Clayton     case fpu_s9:
682a63d08c9SGreg Clayton     case fpu_s10:
683a63d08c9SGreg Clayton     case fpu_s11:
684a63d08c9SGreg Clayton     case fpu_s12:
685a63d08c9SGreg Clayton     case fpu_s13:
686a63d08c9SGreg Clayton     case fpu_s14:
687a63d08c9SGreg Clayton     case fpu_s15:
688a63d08c9SGreg Clayton     case fpu_s16:
689a63d08c9SGreg Clayton     case fpu_s17:
690a63d08c9SGreg Clayton     case fpu_s18:
691a63d08c9SGreg Clayton     case fpu_s19:
692a63d08c9SGreg Clayton     case fpu_s20:
693a63d08c9SGreg Clayton     case fpu_s21:
694a63d08c9SGreg Clayton     case fpu_s22:
695a63d08c9SGreg Clayton     case fpu_s23:
696a63d08c9SGreg Clayton     case fpu_s24:
697a63d08c9SGreg Clayton     case fpu_s25:
698a63d08c9SGreg Clayton     case fpu_s26:
699a63d08c9SGreg Clayton     case fpu_s27:
700a63d08c9SGreg Clayton     case fpu_s28:
701a63d08c9SGreg Clayton     case fpu_s29:
702a63d08c9SGreg Clayton     case fpu_s30:
703a63d08c9SGreg Clayton     case fpu_s31:
704a63d08c9SGreg Clayton         value.SetUInt32 (fpu.floats.s[reg], RegisterValue::eTypeFloat);
705a63d08c9SGreg Clayton         break;
706a63d08c9SGreg Clayton 
707a63d08c9SGreg Clayton     case fpu_fpscr:
708a63d08c9SGreg Clayton         value.SetUInt32 (fpu.fpscr);
709a63d08c9SGreg Clayton         break;
710a63d08c9SGreg Clayton 
711a63d08c9SGreg Clayton     case exc_exception:
712a63d08c9SGreg Clayton         value.SetUInt32 (exc.exception);
713a63d08c9SGreg Clayton         break;
714a63d08c9SGreg Clayton     case exc_fsr:
715a63d08c9SGreg Clayton         value.SetUInt32 (exc.fsr);
716a63d08c9SGreg Clayton         break;
717a63d08c9SGreg Clayton     case exc_far:
718a63d08c9SGreg Clayton         value.SetUInt32 (exc.far);
719a63d08c9SGreg Clayton         break;
720a63d08c9SGreg Clayton 
721a63d08c9SGreg Clayton     default:
722a63d08c9SGreg Clayton         value.SetValueToInvalid();
723a63d08c9SGreg Clayton         return false;
724a63d08c9SGreg Clayton 
725a63d08c9SGreg Clayton     }
726a63d08c9SGreg Clayton     return true;
727a63d08c9SGreg Clayton }
728a63d08c9SGreg Clayton 
729a63d08c9SGreg Clayton 
730a63d08c9SGreg Clayton bool
731a63d08c9SGreg Clayton RegisterContextDarwin_arm::WriteRegister (const RegisterInfo *reg_info,
732a63d08c9SGreg Clayton                                         const RegisterValue &value)
733a63d08c9SGreg Clayton {
734a63d08c9SGreg Clayton     const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
735a63d08c9SGreg Clayton     int set = GetSetForNativeRegNum (reg);
736a63d08c9SGreg Clayton 
737a63d08c9SGreg Clayton     if (set == -1)
738a63d08c9SGreg Clayton         return false;
739a63d08c9SGreg Clayton 
740a63d08c9SGreg Clayton     if (ReadRegisterSet(set, false) != KERN_SUCCESS)
741a63d08c9SGreg Clayton         return false;
742a63d08c9SGreg Clayton 
743a63d08c9SGreg Clayton     switch (reg)
744a63d08c9SGreg Clayton     {
745a63d08c9SGreg Clayton     case gpr_r0:
746a63d08c9SGreg Clayton     case gpr_r1:
747a63d08c9SGreg Clayton     case gpr_r2:
748a63d08c9SGreg Clayton     case gpr_r3:
749a63d08c9SGreg Clayton     case gpr_r4:
750a63d08c9SGreg Clayton     case gpr_r5:
751a63d08c9SGreg Clayton     case gpr_r6:
752a63d08c9SGreg Clayton     case gpr_r7:
753a63d08c9SGreg Clayton     case gpr_r8:
754a63d08c9SGreg Clayton     case gpr_r9:
755a63d08c9SGreg Clayton     case gpr_r10:
756a63d08c9SGreg Clayton     case gpr_r11:
757a63d08c9SGreg Clayton     case gpr_r12:
758a63d08c9SGreg Clayton     case gpr_sp:
759a63d08c9SGreg Clayton     case gpr_lr:
760a63d08c9SGreg Clayton     case gpr_pc:
761a63d08c9SGreg Clayton     case gpr_cpsr:
762a63d08c9SGreg Clayton             gpr.r[reg - gpr_r0] = value.GetAsUInt32();
763a63d08c9SGreg Clayton         break;
764a63d08c9SGreg Clayton 
765a63d08c9SGreg Clayton     case fpu_s0:
766a63d08c9SGreg Clayton     case fpu_s1:
767a63d08c9SGreg Clayton     case fpu_s2:
768a63d08c9SGreg Clayton     case fpu_s3:
769a63d08c9SGreg Clayton     case fpu_s4:
770a63d08c9SGreg Clayton     case fpu_s5:
771a63d08c9SGreg Clayton     case fpu_s6:
772a63d08c9SGreg Clayton     case fpu_s7:
773a63d08c9SGreg Clayton     case fpu_s8:
774a63d08c9SGreg Clayton     case fpu_s9:
775a63d08c9SGreg Clayton     case fpu_s10:
776a63d08c9SGreg Clayton     case fpu_s11:
777a63d08c9SGreg Clayton     case fpu_s12:
778a63d08c9SGreg Clayton     case fpu_s13:
779a63d08c9SGreg Clayton     case fpu_s14:
780a63d08c9SGreg Clayton     case fpu_s15:
781a63d08c9SGreg Clayton     case fpu_s16:
782a63d08c9SGreg Clayton     case fpu_s17:
783a63d08c9SGreg Clayton     case fpu_s18:
784a63d08c9SGreg Clayton     case fpu_s19:
785a63d08c9SGreg Clayton     case fpu_s20:
786a63d08c9SGreg Clayton     case fpu_s21:
787a63d08c9SGreg Clayton     case fpu_s22:
788a63d08c9SGreg Clayton     case fpu_s23:
789a63d08c9SGreg Clayton     case fpu_s24:
790a63d08c9SGreg Clayton     case fpu_s25:
791a63d08c9SGreg Clayton     case fpu_s26:
792a63d08c9SGreg Clayton     case fpu_s27:
793a63d08c9SGreg Clayton     case fpu_s28:
794a63d08c9SGreg Clayton     case fpu_s29:
795a63d08c9SGreg Clayton     case fpu_s30:
796a63d08c9SGreg Clayton     case fpu_s31:
797a63d08c9SGreg Clayton         fpu.floats.s[reg] = value.GetAsUInt32();
798a63d08c9SGreg Clayton         break;
799a63d08c9SGreg Clayton 
800a63d08c9SGreg Clayton     case fpu_fpscr:
801a63d08c9SGreg Clayton         fpu.fpscr = value.GetAsUInt32();
802a63d08c9SGreg Clayton         break;
803a63d08c9SGreg Clayton 
804a63d08c9SGreg Clayton     case exc_exception:
805a63d08c9SGreg Clayton         exc.exception = value.GetAsUInt32();
806a63d08c9SGreg Clayton         break;
807a63d08c9SGreg Clayton     case exc_fsr:
808a63d08c9SGreg Clayton         exc.fsr = value.GetAsUInt32();
809a63d08c9SGreg Clayton         break;
810a63d08c9SGreg Clayton     case exc_far:
811a63d08c9SGreg Clayton         exc.far = value.GetAsUInt32();
812a63d08c9SGreg Clayton         break;
813a63d08c9SGreg Clayton 
814a63d08c9SGreg Clayton     default:
815a63d08c9SGreg Clayton         return false;
816a63d08c9SGreg Clayton 
817a63d08c9SGreg Clayton     }
818a63d08c9SGreg Clayton     return WriteRegisterSet(set) == KERN_SUCCESS;
819a63d08c9SGreg Clayton }
820a63d08c9SGreg Clayton 
821a63d08c9SGreg Clayton bool
822a63d08c9SGreg Clayton RegisterContextDarwin_arm::ReadAllRegisterValues (lldb::DataBufferSP &data_sp)
823a63d08c9SGreg Clayton {
824a63d08c9SGreg Clayton     data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
825a63d08c9SGreg Clayton     if (data_sp &&
826a63d08c9SGreg Clayton         ReadGPR (false) == KERN_SUCCESS &&
827a63d08c9SGreg Clayton         ReadFPU (false) == KERN_SUCCESS &&
828a63d08c9SGreg Clayton         ReadEXC (false) == KERN_SUCCESS)
829a63d08c9SGreg Clayton     {
830a63d08c9SGreg Clayton         uint8_t *dst = data_sp->GetBytes();
831a63d08c9SGreg Clayton         ::memcpy (dst, &gpr, sizeof(gpr));
832a63d08c9SGreg Clayton         dst += sizeof(gpr);
833a63d08c9SGreg Clayton 
834a63d08c9SGreg Clayton         ::memcpy (dst, &fpu, sizeof(fpu));
835a63d08c9SGreg Clayton         dst += sizeof(gpr);
836a63d08c9SGreg Clayton 
837a63d08c9SGreg Clayton         ::memcpy (dst, &exc, sizeof(exc));
838a63d08c9SGreg Clayton         return true;
839a63d08c9SGreg Clayton     }
840a63d08c9SGreg Clayton     return false;
841a63d08c9SGreg Clayton }
842a63d08c9SGreg Clayton 
843a63d08c9SGreg Clayton bool
844a63d08c9SGreg Clayton RegisterContextDarwin_arm::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp)
845a63d08c9SGreg Clayton {
846a63d08c9SGreg Clayton     if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
847a63d08c9SGreg Clayton     {
848a63d08c9SGreg Clayton         const uint8_t *src = data_sp->GetBytes();
849a63d08c9SGreg Clayton         ::memcpy (&gpr, src, sizeof(gpr));
850a63d08c9SGreg Clayton         src += sizeof(gpr);
851a63d08c9SGreg Clayton 
852a63d08c9SGreg Clayton         ::memcpy (&fpu, src, sizeof(fpu));
853a63d08c9SGreg Clayton         src += sizeof(gpr);
854a63d08c9SGreg Clayton 
855a63d08c9SGreg Clayton         ::memcpy (&exc, src, sizeof(exc));
856a63d08c9SGreg Clayton         uint32_t success_count = 0;
857a63d08c9SGreg Clayton         if (WriteGPR() == KERN_SUCCESS)
858a63d08c9SGreg Clayton             ++success_count;
859a63d08c9SGreg Clayton         if (WriteFPU() == KERN_SUCCESS)
860a63d08c9SGreg Clayton             ++success_count;
861a63d08c9SGreg Clayton         if (WriteEXC() == KERN_SUCCESS)
862a63d08c9SGreg Clayton             ++success_count;
863a63d08c9SGreg Clayton         return success_count == 3;
864a63d08c9SGreg Clayton     }
865a63d08c9SGreg Clayton     return false;
866a63d08c9SGreg Clayton }
867a63d08c9SGreg Clayton 
868a63d08c9SGreg Clayton uint32_t
869a63d08c9SGreg Clayton RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t reg)
870a63d08c9SGreg Clayton {
871a63d08c9SGreg Clayton     if (kind == eRegisterKindGeneric)
872a63d08c9SGreg Clayton     {
873a63d08c9SGreg Clayton         switch (reg)
874a63d08c9SGreg Clayton         {
875a63d08c9SGreg Clayton         case LLDB_REGNUM_GENERIC_PC: return gpr_pc;
876a63d08c9SGreg Clayton         case LLDB_REGNUM_GENERIC_SP: return gpr_sp;
877a63d08c9SGreg Clayton         case LLDB_REGNUM_GENERIC_FP: return gpr_r7;
878a63d08c9SGreg Clayton         case LLDB_REGNUM_GENERIC_RA: return gpr_lr;
879a63d08c9SGreg Clayton         case LLDB_REGNUM_GENERIC_FLAGS: return gpr_cpsr;
880a63d08c9SGreg Clayton         default:
881a63d08c9SGreg Clayton             break;
882a63d08c9SGreg Clayton         }
883a63d08c9SGreg Clayton     }
884a63d08c9SGreg Clayton     else if (kind == eRegisterKindDWARF)
885a63d08c9SGreg Clayton     {
886a63d08c9SGreg Clayton         switch (reg)
887a63d08c9SGreg Clayton         {
888a63d08c9SGreg Clayton         case dwarf_r0:  return gpr_r0;
889a63d08c9SGreg Clayton         case dwarf_r1:  return gpr_r1;
890a63d08c9SGreg Clayton         case dwarf_r2:  return gpr_r2;
891a63d08c9SGreg Clayton         case dwarf_r3:  return gpr_r3;
892a63d08c9SGreg Clayton         case dwarf_r4:  return gpr_r4;
893a63d08c9SGreg Clayton         case dwarf_r5:  return gpr_r5;
894a63d08c9SGreg Clayton         case dwarf_r6:  return gpr_r6;
895a63d08c9SGreg Clayton         case dwarf_r7:  return gpr_r7;
896a63d08c9SGreg Clayton         case dwarf_r8:  return gpr_r8;
897a63d08c9SGreg Clayton         case dwarf_r9:  return gpr_r9;
898a63d08c9SGreg Clayton         case dwarf_r10: return gpr_r10;
899a63d08c9SGreg Clayton         case dwarf_r11: return gpr_r11;
900a63d08c9SGreg Clayton         case dwarf_r12: return gpr_r12;
901a63d08c9SGreg Clayton         case dwarf_sp:  return gpr_sp;
902a63d08c9SGreg Clayton         case dwarf_lr:  return gpr_lr;
903a63d08c9SGreg Clayton         case dwarf_pc:  return gpr_pc;
904a63d08c9SGreg Clayton         case dwarf_spsr: return gpr_cpsr;
905a63d08c9SGreg Clayton 
906a63d08c9SGreg Clayton         case dwarf_s0:  return fpu_s0;
907a63d08c9SGreg Clayton         case dwarf_s1:  return fpu_s1;
908a63d08c9SGreg Clayton         case dwarf_s2:  return fpu_s2;
909a63d08c9SGreg Clayton         case dwarf_s3:  return fpu_s3;
910a63d08c9SGreg Clayton         case dwarf_s4:  return fpu_s4;
911a63d08c9SGreg Clayton         case dwarf_s5:  return fpu_s5;
912a63d08c9SGreg Clayton         case dwarf_s6:  return fpu_s6;
913a63d08c9SGreg Clayton         case dwarf_s7:  return fpu_s7;
914a63d08c9SGreg Clayton         case dwarf_s8:  return fpu_s8;
915a63d08c9SGreg Clayton         case dwarf_s9:  return fpu_s9;
916a63d08c9SGreg Clayton         case dwarf_s10: return fpu_s10;
917a63d08c9SGreg Clayton         case dwarf_s11: return fpu_s11;
918a63d08c9SGreg Clayton         case dwarf_s12: return fpu_s12;
919a63d08c9SGreg Clayton         case dwarf_s13: return fpu_s13;
920a63d08c9SGreg Clayton         case dwarf_s14: return fpu_s14;
921a63d08c9SGreg Clayton         case dwarf_s15: return fpu_s15;
922a63d08c9SGreg Clayton         case dwarf_s16: return fpu_s16;
923a63d08c9SGreg Clayton         case dwarf_s17: return fpu_s17;
924a63d08c9SGreg Clayton         case dwarf_s18: return fpu_s18;
925a63d08c9SGreg Clayton         case dwarf_s19: return fpu_s19;
926a63d08c9SGreg Clayton         case dwarf_s20: return fpu_s20;
927a63d08c9SGreg Clayton         case dwarf_s21: return fpu_s21;
928a63d08c9SGreg Clayton         case dwarf_s22: return fpu_s22;
929a63d08c9SGreg Clayton         case dwarf_s23: return fpu_s23;
930a63d08c9SGreg Clayton         case dwarf_s24: return fpu_s24;
931a63d08c9SGreg Clayton         case dwarf_s25: return fpu_s25;
932a63d08c9SGreg Clayton         case dwarf_s26: return fpu_s26;
933a63d08c9SGreg Clayton         case dwarf_s27: return fpu_s27;
934a63d08c9SGreg Clayton         case dwarf_s28: return fpu_s28;
935a63d08c9SGreg Clayton         case dwarf_s29: return fpu_s29;
936a63d08c9SGreg Clayton         case dwarf_s30: return fpu_s30;
937a63d08c9SGreg Clayton         case dwarf_s31: return fpu_s31;
938a63d08c9SGreg Clayton 
939a63d08c9SGreg Clayton         default:
940a63d08c9SGreg Clayton             break;
941a63d08c9SGreg Clayton         }
942a63d08c9SGreg Clayton     }
943a63d08c9SGreg Clayton     else if (kind == eRegisterKindGCC)
944a63d08c9SGreg Clayton     {
945a63d08c9SGreg Clayton         switch (reg)
946a63d08c9SGreg Clayton         {
947a63d08c9SGreg Clayton         case gcc_r0:    return gpr_r0;
948a63d08c9SGreg Clayton         case gcc_r1:    return gpr_r1;
949a63d08c9SGreg Clayton         case gcc_r2:    return gpr_r2;
950a63d08c9SGreg Clayton         case gcc_r3:    return gpr_r3;
951a63d08c9SGreg Clayton         case gcc_r4:    return gpr_r4;
952a63d08c9SGreg Clayton         case gcc_r5:    return gpr_r5;
953a63d08c9SGreg Clayton         case gcc_r6:    return gpr_r6;
954a63d08c9SGreg Clayton         case gcc_r7:    return gpr_r7;
955a63d08c9SGreg Clayton         case gcc_r8:    return gpr_r8;
956a63d08c9SGreg Clayton         case gcc_r9:    return gpr_r9;
957a63d08c9SGreg Clayton         case gcc_r10:   return gpr_r10;
958a63d08c9SGreg Clayton         case gcc_r11:   return gpr_r11;
959a63d08c9SGreg Clayton         case gcc_r12:   return gpr_r12;
960a63d08c9SGreg Clayton         case gcc_sp:    return gpr_sp;
961a63d08c9SGreg Clayton         case gcc_lr:    return gpr_lr;
962a63d08c9SGreg Clayton         case gcc_pc:    return gpr_pc;
963a63d08c9SGreg Clayton         case gcc_cpsr:  return gpr_cpsr;
964a63d08c9SGreg Clayton         }
965a63d08c9SGreg Clayton     }
966a63d08c9SGreg Clayton     else if (kind == eRegisterKindLLDB)
967a63d08c9SGreg Clayton     {
968a63d08c9SGreg Clayton         return reg;
969a63d08c9SGreg Clayton     }
970a63d08c9SGreg Clayton     return LLDB_INVALID_REGNUM;
971a63d08c9SGreg Clayton }
972a63d08c9SGreg Clayton 
973a63d08c9SGreg Clayton 
974a63d08c9SGreg Clayton uint32_t
975a63d08c9SGreg Clayton RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints ()
976a63d08c9SGreg Clayton {
977a63d08c9SGreg Clayton #if defined (__arm__)
978a63d08c9SGreg Clayton     // Set the init value to something that will let us know that we need to
979a63d08c9SGreg Clayton     // autodetect how many breakpoints are supported dynamically...
980a63d08c9SGreg Clayton     static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;
981a63d08c9SGreg Clayton     if (g_num_supported_hw_breakpoints == UINT32_MAX)
982a63d08c9SGreg Clayton     {
983a63d08c9SGreg Clayton         // Set this to zero in case we can't tell if there are any HW breakpoints
984a63d08c9SGreg Clayton         g_num_supported_hw_breakpoints = 0;
985a63d08c9SGreg Clayton 
986a63d08c9SGreg Clayton         uint32_t register_DBGDIDR;
987a63d08c9SGreg Clayton 
988a63d08c9SGreg Clayton         asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
989dce502edSGreg Clayton         g_num_supported_hw_breakpoints = Bits32 (register_DBGDIDR, 27, 24);
990a63d08c9SGreg Clayton         // Zero is reserved for the BRP count, so don't increment it if it is zero
991a63d08c9SGreg Clayton         if (g_num_supported_hw_breakpoints > 0)
992a63d08c9SGreg Clayton             g_num_supported_hw_breakpoints++;
99389f138aeSGreg Clayton //        if (log) log->Printf ("DBGDIDR=0x%8.8x (number BRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_breakpoints);
994a63d08c9SGreg Clayton 
995a63d08c9SGreg Clayton     }
996a63d08c9SGreg Clayton     return g_num_supported_hw_breakpoints;
997a63d08c9SGreg Clayton #else
998a63d08c9SGreg Clayton     // TODO: figure out remote case here!
999a63d08c9SGreg Clayton     return 6;
1000a63d08c9SGreg Clayton #endif
1001a63d08c9SGreg Clayton }
1002a63d08c9SGreg Clayton 
1003a63d08c9SGreg Clayton uint32_t
1004a63d08c9SGreg Clayton RegisterContextDarwin_arm::SetHardwareBreakpoint (lldb::addr_t addr, size_t size)
1005a63d08c9SGreg Clayton {
1006a63d08c9SGreg Clayton     // Make sure our address isn't bogus
1007a63d08c9SGreg Clayton     if (addr & 1)
1008a63d08c9SGreg Clayton         return LLDB_INVALID_INDEX32;
1009a63d08c9SGreg Clayton 
1010a63d08c9SGreg Clayton     int kret = ReadDBG (false);
1011a63d08c9SGreg Clayton 
1012a63d08c9SGreg Clayton     if (kret == KERN_SUCCESS)
1013a63d08c9SGreg Clayton     {
1014a63d08c9SGreg Clayton         const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();
1015a63d08c9SGreg Clayton         uint32_t i;
1016a63d08c9SGreg Clayton         for (i=0; i<num_hw_breakpoints; ++i)
1017a63d08c9SGreg Clayton         {
1018a63d08c9SGreg Clayton             if ((dbg.bcr[i] & BCR_ENABLE) == 0)
1019a63d08c9SGreg Clayton                 break; // We found an available hw breakpoint slot (in i)
1020a63d08c9SGreg Clayton         }
1021a63d08c9SGreg Clayton 
1022a63d08c9SGreg Clayton         // See if we found an available hw breakpoint slot above
1023a63d08c9SGreg Clayton         if (i < num_hw_breakpoints)
1024a63d08c9SGreg Clayton         {
1025a63d08c9SGreg Clayton             // Make sure bits 1:0 are clear in our address
1026a63d08c9SGreg Clayton             dbg.bvr[i] = addr & ~((lldb::addr_t)3);
1027a63d08c9SGreg Clayton 
1028a63d08c9SGreg Clayton             if (size == 2 || addr & 2)
1029a63d08c9SGreg Clayton             {
1030a63d08c9SGreg Clayton                 uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;
1031a63d08c9SGreg Clayton 
1032a63d08c9SGreg Clayton                 // We have a thumb breakpoint
1033a63d08c9SGreg Clayton                 // We have an ARM breakpoint
1034a63d08c9SGreg Clayton                 dbg.bcr[i] =  BCR_M_IMVA_MATCH |    // Stop on address mismatch
1035a63d08c9SGreg Clayton                                         byte_addr_select |  // Set the correct byte address select so we only trigger on the correct opcode
1036a63d08c9SGreg Clayton                                         S_USER |            // Which modes should this breakpoint stop in?
1037a63d08c9SGreg Clayton                                         BCR_ENABLE;         // Enable this hardware breakpoint
103889f138aeSGreg Clayton //                if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (Thumb)",
103989f138aeSGreg Clayton //                        addr,
104089f138aeSGreg Clayton //                        size,
104189f138aeSGreg Clayton //                        i,
104289f138aeSGreg Clayton //                        i,
104389f138aeSGreg Clayton //                        dbg.bvr[i],
104489f138aeSGreg Clayton //                        dbg.bcr[i]);
1045a63d08c9SGreg Clayton             }
1046a63d08c9SGreg Clayton             else if (size == 4)
1047a63d08c9SGreg Clayton             {
1048a63d08c9SGreg Clayton                 // We have an ARM breakpoint
1049a63d08c9SGreg Clayton                 dbg.bcr[i] =  BCR_M_IMVA_MATCH |    // Stop on address mismatch
1050a63d08c9SGreg Clayton                                         BAS_IMVA_ALL |      // Stop on any of the four bytes following the IMVA
1051a63d08c9SGreg Clayton                                         S_USER |            // Which modes should this breakpoint stop in?
1052a63d08c9SGreg Clayton                                         BCR_ENABLE;         // Enable this hardware breakpoint
105389f138aeSGreg Clayton //                if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint( addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x / 0x%8.8x (ARM)",
105489f138aeSGreg Clayton //                        addr,
105589f138aeSGreg Clayton //                        size,
105689f138aeSGreg Clayton //                        i,
105789f138aeSGreg Clayton //                        i,
105889f138aeSGreg Clayton //                        dbg.bvr[i],
105989f138aeSGreg Clayton //                        dbg.bcr[i]);
1060a63d08c9SGreg Clayton             }
1061a63d08c9SGreg Clayton 
1062a63d08c9SGreg Clayton             kret = WriteDBG();
106389f138aeSGreg Clayton //            if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint() WriteDBG() => 0x%8.8x.", kret);
1064a63d08c9SGreg Clayton 
1065a63d08c9SGreg Clayton             if (kret == KERN_SUCCESS)
1066a63d08c9SGreg Clayton                 return i;
1067a63d08c9SGreg Clayton         }
106889f138aeSGreg Clayton //        else
106989f138aeSGreg Clayton //        {
107089f138aeSGreg Clayton //            if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr = %8.8p, size = %u) => all hardware breakpoint resources are being used.", addr, size);
107189f138aeSGreg Clayton //        }
1072a63d08c9SGreg Clayton     }
1073a63d08c9SGreg Clayton 
1074a63d08c9SGreg Clayton     return LLDB_INVALID_INDEX32;
1075a63d08c9SGreg Clayton }
1076a63d08c9SGreg Clayton 
1077a63d08c9SGreg Clayton bool
1078a63d08c9SGreg Clayton RegisterContextDarwin_arm::ClearHardwareBreakpoint (uint32_t hw_index)
1079a63d08c9SGreg Clayton {
1080a63d08c9SGreg Clayton     int kret = ReadDBG (false);
1081a63d08c9SGreg Clayton 
1082a63d08c9SGreg Clayton     const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();
1083a63d08c9SGreg Clayton     if (kret == KERN_SUCCESS)
1084a63d08c9SGreg Clayton     {
1085a63d08c9SGreg Clayton         if (hw_index < num_hw_points)
1086a63d08c9SGreg Clayton         {
1087a63d08c9SGreg Clayton             dbg.bcr[hw_index] = 0;
108889f138aeSGreg Clayton //            if (log) log->Printf ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) - BVR%u = 0x%8.8x  BCR%u = 0x%8.8x",
108989f138aeSGreg Clayton //                    hw_index,
109089f138aeSGreg Clayton //                    hw_index,
109189f138aeSGreg Clayton //                    dbg.bvr[hw_index],
109289f138aeSGreg Clayton //                    hw_index,
109389f138aeSGreg Clayton //                    dbg.bcr[hw_index]);
1094a63d08c9SGreg Clayton 
1095a63d08c9SGreg Clayton             kret = WriteDBG();
1096a63d08c9SGreg Clayton 
1097a63d08c9SGreg Clayton             if (kret == KERN_SUCCESS)
1098a63d08c9SGreg Clayton                 return true;
1099a63d08c9SGreg Clayton         }
1100a63d08c9SGreg Clayton     }
1101a63d08c9SGreg Clayton     return false;
1102a63d08c9SGreg Clayton }
1103a63d08c9SGreg Clayton 
1104a63d08c9SGreg Clayton uint32_t
1105a63d08c9SGreg Clayton RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints ()
1106a63d08c9SGreg Clayton {
1107a63d08c9SGreg Clayton #if defined (__arm__)
1108a63d08c9SGreg Clayton     // Set the init value to something that will let us know that we need to
1109a63d08c9SGreg Clayton     // autodetect how many watchpoints are supported dynamically...
1110a63d08c9SGreg Clayton     static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;
1111a63d08c9SGreg Clayton     if (g_num_supported_hw_watchpoints == UINT32_MAX)
1112a63d08c9SGreg Clayton     {
1113a63d08c9SGreg Clayton         // Set this to zero in case we can't tell if there are any HW breakpoints
1114a63d08c9SGreg Clayton         g_num_supported_hw_watchpoints = 0;
1115a63d08c9SGreg Clayton 
1116a63d08c9SGreg Clayton         uint32_t register_DBGDIDR;
1117a63d08c9SGreg Clayton         asm("mrc p14, 0, %0, c0, c0, 0" : "=r" (register_DBGDIDR));
1118dce502edSGreg Clayton         g_num_supported_hw_watchpoints = Bits32 (register_DBGDIDR, 31, 28) + 1;
111989f138aeSGreg Clayton //        if (log) log->Printf ("DBGDIDR=0x%8.8x (number WRP pairs = %u)", register_DBGDIDR, g_num_supported_hw_watchpoints);
1120a63d08c9SGreg Clayton     }
1121a63d08c9SGreg Clayton     return g_num_supported_hw_watchpoints;
1122a63d08c9SGreg Clayton #else
1123a63d08c9SGreg Clayton     // TODO: figure out remote case here!
1124a63d08c9SGreg Clayton     return 2;
1125a63d08c9SGreg Clayton #endif
1126a63d08c9SGreg Clayton }
1127a63d08c9SGreg Clayton 
1128a63d08c9SGreg Clayton 
1129a63d08c9SGreg Clayton uint32_t
1130a63d08c9SGreg Clayton RegisterContextDarwin_arm::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write)
1131a63d08c9SGreg Clayton {
113289f138aeSGreg Clayton //    if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(addr = %8.8p, size = %u, read = %u, write = %u)", addr, size, read, write);
1133a63d08c9SGreg Clayton 
1134a63d08c9SGreg Clayton     const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
1135a63d08c9SGreg Clayton 
1136a63d08c9SGreg Clayton     // Can't watch zero bytes
1137a63d08c9SGreg Clayton     if (size == 0)
1138a63d08c9SGreg Clayton         return LLDB_INVALID_INDEX32;
1139a63d08c9SGreg Clayton 
1140a63d08c9SGreg Clayton     // We must watch for either read or write
1141a63d08c9SGreg Clayton     if (read == false && write == false)
1142a63d08c9SGreg Clayton         return LLDB_INVALID_INDEX32;
1143a63d08c9SGreg Clayton 
1144a63d08c9SGreg Clayton     // Can't watch more than 4 bytes per WVR/WCR pair
1145a63d08c9SGreg Clayton     if (size > 4)
1146a63d08c9SGreg Clayton         return LLDB_INVALID_INDEX32;
1147a63d08c9SGreg Clayton 
1148a63d08c9SGreg Clayton     // We can only watch up to four bytes that follow a 4 byte aligned address
1149a63d08c9SGreg Clayton     // per watchpoint register pair. Since we have at most so we can only watch
1150a63d08c9SGreg Clayton     // until the next 4 byte boundary and we need to make sure we can properly
1151a63d08c9SGreg Clayton     // encode this.
1152a63d08c9SGreg Clayton     uint32_t addr_word_offset = addr % 4;
115389f138aeSGreg Clayton //    if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - addr_word_offset = 0x%8.8x", addr_word_offset);
1154a63d08c9SGreg Clayton 
1155a63d08c9SGreg Clayton     uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;
115689f138aeSGreg Clayton //    if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask = 0x%8.8x", byte_mask);
1157a63d08c9SGreg Clayton     if (byte_mask > 0xfu)
1158a63d08c9SGreg Clayton         return LLDB_INVALID_INDEX32;
1159a63d08c9SGreg Clayton 
1160a63d08c9SGreg Clayton     // Read the debug state
1161a63d08c9SGreg Clayton     int kret = ReadDBG (false);
1162a63d08c9SGreg Clayton 
1163a63d08c9SGreg Clayton     if (kret == KERN_SUCCESS)
1164a63d08c9SGreg Clayton     {
1165a63d08c9SGreg Clayton         // Check to make sure we have the needed hardware support
1166a63d08c9SGreg Clayton         uint32_t i = 0;
1167a63d08c9SGreg Clayton 
1168a63d08c9SGreg Clayton         for (i=0; i<num_hw_watchpoints; ++i)
1169a63d08c9SGreg Clayton         {
1170a63d08c9SGreg Clayton             if ((dbg.wcr[i] & WCR_ENABLE) == 0)
1171a63d08c9SGreg Clayton                 break; // We found an available hw breakpoint slot (in i)
1172a63d08c9SGreg Clayton         }
1173a63d08c9SGreg Clayton 
1174a63d08c9SGreg Clayton         // See if we found an available hw breakpoint slot above
1175a63d08c9SGreg Clayton         if (i < num_hw_watchpoints)
1176a63d08c9SGreg Clayton         {
1177a63d08c9SGreg Clayton             // Make the byte_mask into a valid Byte Address Select mask
1178a63d08c9SGreg Clayton             uint32_t byte_address_select = byte_mask << 5;
1179a63d08c9SGreg Clayton             // Make sure bits 1:0 are clear in our address
1180a63d08c9SGreg Clayton             dbg.wvr[i] = addr & ~((lldb::addr_t)3);
1181a63d08c9SGreg Clayton             dbg.wcr[i] =  byte_address_select |       // Which bytes that follow the IMVA that we will watch
1182a63d08c9SGreg Clayton                                     S_USER |                    // Stop only in user mode
1183a63d08c9SGreg Clayton                                     (read ? WCR_LOAD : 0) |     // Stop on read access?
1184a63d08c9SGreg Clayton                                     (write ? WCR_STORE : 0) |   // Stop on write access?
1185a63d08c9SGreg Clayton                                     WCR_ENABLE;                 // Enable this watchpoint;
1186a63d08c9SGreg Clayton 
1187a63d08c9SGreg Clayton             kret = WriteDBG();
118889f138aeSGreg Clayton //            if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() WriteDBG() => 0x%8.8x.", kret);
1189a63d08c9SGreg Clayton 
1190a63d08c9SGreg Clayton             if (kret == KERN_SUCCESS)
1191a63d08c9SGreg Clayton                 return i;
1192a63d08c9SGreg Clayton         }
1193a63d08c9SGreg Clayton         else
1194a63d08c9SGreg Clayton         {
119589f138aeSGreg Clayton //            if (log) log->Printf ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All hardware resources (%u) are in use.", num_hw_watchpoints);
1196a63d08c9SGreg Clayton         }
1197a63d08c9SGreg Clayton     }
1198a63d08c9SGreg Clayton     return LLDB_INVALID_INDEX32;
1199a63d08c9SGreg Clayton }
1200a63d08c9SGreg Clayton 
1201a63d08c9SGreg Clayton bool
1202a63d08c9SGreg Clayton RegisterContextDarwin_arm::ClearHardwareWatchpoint (uint32_t hw_index)
1203a63d08c9SGreg Clayton {
1204a63d08c9SGreg Clayton     int kret = ReadDBG (false);
1205a63d08c9SGreg Clayton 
1206a63d08c9SGreg Clayton     const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();
1207a63d08c9SGreg Clayton     if (kret == KERN_SUCCESS)
1208a63d08c9SGreg Clayton     {
1209a63d08c9SGreg Clayton         if (hw_index < num_hw_points)
1210a63d08c9SGreg Clayton         {
1211a63d08c9SGreg Clayton             dbg.wcr[hw_index] = 0;
121289f138aeSGreg Clayton //            if (log) log->Printf ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x  WCR%u = 0x%8.8x",
121389f138aeSGreg Clayton //                    hw_index,
121489f138aeSGreg Clayton //                    hw_index,
121589f138aeSGreg Clayton //                    dbg.wvr[hw_index],
121689f138aeSGreg Clayton //                    hw_index,
121789f138aeSGreg Clayton //                    dbg.wcr[hw_index]);
1218a63d08c9SGreg Clayton 
1219a63d08c9SGreg Clayton             kret = WriteDBG();
1220a63d08c9SGreg Clayton 
1221a63d08c9SGreg Clayton             if (kret == KERN_SUCCESS)
1222a63d08c9SGreg Clayton                 return true;
1223a63d08c9SGreg Clayton         }
1224a63d08c9SGreg Clayton     }
1225a63d08c9SGreg Clayton     return false;
1226a63d08c9SGreg Clayton }
1227a63d08c9SGreg Clayton 
1228a67dd8fcSPeter Collingbourne #endif
1229