1 //===-- DNBArchImpl.cpp -----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Created by Greg Clayton on 6/25/07.
12 //===----------------------------------------------------------------------===//
14 #if defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__)
17 #define PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(reg) __##reg
19 #define PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(reg) reg
22 #include "MacOSX/ppc/DNBArchImpl.h"
23 #include "DNBBreakpoint.h"
25 #include "DNBRegisterInfo.h"
26 #include "MacOSX/MachThread.h"
28 static const uint8_t g_breakpoint_opcode[] = {0x7F, 0xC0, 0x00, 0x08};
30 const uint8_t *DNBArchMachPPC::SoftwareBreakpointOpcode(nub_size_t size) {
32 return g_breakpoint_opcode;
36 uint32_t DNBArchMachPPC::GetCPUType() { return CPU_TYPE_POWERPC; }
38 uint64_t DNBArchMachPPC::GetPC(uint64_t failValue) {
39 // Get program counter
40 if (GetGPRState(false) == KERN_SUCCESS)
41 return m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0);
45 kern_return_t DNBArchMachPPC::SetPC(uint64_t value) {
46 // Get program counter
47 kern_return_t err = GetGPRState(false);
48 if (err == KERN_SUCCESS) {
49 m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0) = value;
52 return err == KERN_SUCCESS;
55 uint64_t DNBArchMachPPC::GetSP(uint64_t failValue) {
57 if (GetGPRState(false) == KERN_SUCCESS)
58 return m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(r1);
62 kern_return_t DNBArchMachPPC::GetGPRState(bool force) {
63 if (force || m_state.GetError(e_regSetGPR, Read)) {
64 mach_msg_type_number_t count = e_regSetWordSizeGPR;
65 m_state.SetError(e_regSetGPR, Read,
66 ::thread_get_state(m_thread->MachPortNumber(), e_regSetGPR,
67 (thread_state_t)&m_state.gpr, &count));
69 return m_state.GetError(e_regSetGPR, Read);
72 kern_return_t DNBArchMachPPC::GetFPRState(bool force) {
73 if (force || m_state.GetError(e_regSetFPR, Read)) {
74 mach_msg_type_number_t count = e_regSetWordSizeFPR;
75 m_state.SetError(e_regSetFPR, Read,
76 ::thread_get_state(m_thread->MachPortNumber(), e_regSetFPR,
77 (thread_state_t)&m_state.fpr, &count));
79 return m_state.GetError(e_regSetFPR, Read);
82 kern_return_t DNBArchMachPPC::GetEXCState(bool force) {
83 if (force || m_state.GetError(e_regSetEXC, Read)) {
84 mach_msg_type_number_t count = e_regSetWordSizeEXC;
85 m_state.SetError(e_regSetEXC, Read,
86 ::thread_get_state(m_thread->MachPortNumber(), e_regSetEXC,
87 (thread_state_t)&m_state.exc, &count));
89 return m_state.GetError(e_regSetEXC, Read);
92 kern_return_t DNBArchMachPPC::GetVECState(bool force) {
93 if (force || m_state.GetError(e_regSetVEC, Read)) {
94 mach_msg_type_number_t count = e_regSetWordSizeVEC;
95 m_state.SetError(e_regSetVEC, Read,
96 ::thread_get_state(m_thread->MachPortNumber(), e_regSetVEC,
97 (thread_state_t)&m_state.vec, &count));
99 return m_state.GetError(e_regSetVEC, Read);
102 kern_return_t DNBArchMachPPC::SetGPRState() {
103 m_state.SetError(e_regSetGPR, Write,
104 ::thread_set_state(m_thread->MachPortNumber(), e_regSetGPR,
105 (thread_state_t)&m_state.gpr,
106 e_regSetWordSizeGPR));
107 return m_state.GetError(e_regSetGPR, Write);
110 kern_return_t DNBArchMachPPC::SetFPRState() {
111 m_state.SetError(e_regSetFPR, Write,
112 ::thread_set_state(m_thread->MachPortNumber(), e_regSetFPR,
113 (thread_state_t)&m_state.fpr,
114 e_regSetWordSizeFPR));
115 return m_state.GetError(e_regSetFPR, Write);
118 kern_return_t DNBArchMachPPC::SetEXCState() {
119 m_state.SetError(e_regSetEXC, Write,
120 ::thread_set_state(m_thread->MachPortNumber(), e_regSetEXC,
121 (thread_state_t)&m_state.exc,
122 e_regSetWordSizeEXC));
123 return m_state.GetError(e_regSetEXC, Write);
126 kern_return_t DNBArchMachPPC::SetVECState() {
127 m_state.SetError(e_regSetVEC, Write,
128 ::thread_set_state(m_thread->MachPortNumber(), e_regSetVEC,
129 (thread_state_t)&m_state.vec,
130 e_regSetWordSizeVEC));
131 return m_state.GetError(e_regSetVEC, Write);
134 bool DNBArchMachPPC::ThreadWillResume() {
137 // Do we need to step this thread? If so, let the mach thread tell us so.
138 if (m_thread->IsStepping()) {
139 // This is the primary thread, let the arch do anything it needs
140 success = EnableHardwareSingleStep(true) == KERN_SUCCESS;
145 bool DNBArchMachPPC::ThreadDidStop() {
148 m_state.InvalidateAllRegisterStates();
150 // Are we stepping a single instruction?
151 if (GetGPRState(true) == KERN_SUCCESS) {
152 // We are single stepping, was this the primary thread?
153 if (m_thread->IsStepping()) {
154 // This was the primary thread, we need to clear the trace
156 success = EnableHardwareSingleStep(false) == KERN_SUCCESS;
158 // The MachThread will automatically restore the suspend count
159 // in ThreadDidStop(), so we don't need to do anything here if
160 // we weren't the primary thread the last time
166 // Set the single step bit in the processor status register.
167 kern_return_t DNBArchMachPPC::EnableHardwareSingleStep(bool enable) {
168 DNBLogThreadedIf(LOG_STEP,
169 "DNBArchMachPPC::EnableHardwareSingleStep( enable = %d )",
171 if (GetGPRState(false) == KERN_SUCCESS) {
172 const uint32_t trace_bit = 0x400;
174 m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr1) |= trace_bit;
176 m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr1) &= ~trace_bit;
177 return SetGPRState();
179 return m_state.GetError(e_regSetGPR, Read);
182 //----------------------------------------------------------------------
183 // Register information definitions for 32 bit PowerPC.
184 //----------------------------------------------------------------------
229 // General purpose registers
230 static DNBRegisterInfo g_gpr_registers[] = {
231 {"srr0", Uint, 4, Hex}, {"srr1", Uint, 4, Hex}, {"r0", Uint, 4, Hex},
232 {"r1", Uint, 4, Hex}, {"r2", Uint, 4, Hex}, {"r3", Uint, 4, Hex},
233 {"r4", Uint, 4, Hex}, {"r5", Uint, 4, Hex}, {"r6", Uint, 4, Hex},
234 {"r7", Uint, 4, Hex}, {"r8", Uint, 4, Hex}, {"r9", Uint, 4, Hex},
235 {"r10", Uint, 4, Hex}, {"r11", Uint, 4, Hex}, {"r12", Uint, 4, Hex},
236 {"r13", Uint, 4, Hex}, {"r14", Uint, 4, Hex}, {"r15", Uint, 4, Hex},
237 {"r16", Uint, 4, Hex}, {"r17", Uint, 4, Hex}, {"r18", Uint, 4, Hex},
238 {"r19", Uint, 4, Hex}, {"r20", Uint, 4, Hex}, {"r21", Uint, 4, Hex},
239 {"r22", Uint, 4, Hex}, {"r23", Uint, 4, Hex}, {"r24", Uint, 4, Hex},
240 {"r25", Uint, 4, Hex}, {"r26", Uint, 4, Hex}, {"r27", Uint, 4, Hex},
241 {"r28", Uint, 4, Hex}, {"r29", Uint, 4, Hex}, {"r30", Uint, 4, Hex},
242 {"r31", Uint, 4, Hex}, {"cr", Uint, 4, Hex}, {"xer", Uint, 4, Hex},
243 {"lr", Uint, 4, Hex}, {"ctr", Uint, 4, Hex}, {"mq", Uint, 4, Hex},
244 {"vrsave", Uint, 4, Hex},
247 // Floating point registers
248 static DNBRegisterInfo g_fpr_registers[] = {
249 {"fp0", IEEE754, 8, Float}, {"fp1", IEEE754, 8, Float},
250 {"fp2", IEEE754, 8, Float}, {"fp3", IEEE754, 8, Float},
251 {"fp4", IEEE754, 8, Float}, {"fp5", IEEE754, 8, Float},
252 {"fp6", IEEE754, 8, Float}, {"fp7", IEEE754, 8, Float},
253 {"fp8", IEEE754, 8, Float}, {"fp9", IEEE754, 8, Float},
254 {"fp10", IEEE754, 8, Float}, {"fp11", IEEE754, 8, Float},
255 {"fp12", IEEE754, 8, Float}, {"fp13", IEEE754, 8, Float},
256 {"fp14", IEEE754, 8, Float}, {"fp15", IEEE754, 8, Float},
257 {"fp16", IEEE754, 8, Float}, {"fp17", IEEE754, 8, Float},
258 {"fp18", IEEE754, 8, Float}, {"fp19", IEEE754, 8, Float},
259 {"fp20", IEEE754, 8, Float}, {"fp21", IEEE754, 8, Float},
260 {"fp22", IEEE754, 8, Float}, {"fp23", IEEE754, 8, Float},
261 {"fp24", IEEE754, 8, Float}, {"fp25", IEEE754, 8, Float},
262 {"fp26", IEEE754, 8, Float}, {"fp27", IEEE754, 8, Float},
263 {"fp28", IEEE754, 8, Float}, {"fp29", IEEE754, 8, Float},
264 {"fp30", IEEE754, 8, Float}, {"fp31", IEEE754, 8, Float},
265 {"fpscr", Uint, 4, Hex}};
267 // Exception registers
269 static DNBRegisterInfo g_exc_registers[] = {{"dar", Uint, 4, Hex},
270 {"dsisr", Uint, 4, Hex},
271 {"exception", Uint, 4, Hex}};
274 static DNBRegisterInfo g_vec_registers[] = {
275 {"vr0", Vector, 16, VectorOfFloat32},
276 {"vr1", Vector, 16, VectorOfFloat32},
277 {"vr2", Vector, 16, VectorOfFloat32},
278 {"vr3", Vector, 16, VectorOfFloat32},
279 {"vr4", Vector, 16, VectorOfFloat32},
280 {"vr5", Vector, 16, VectorOfFloat32},
281 {"vr6", Vector, 16, VectorOfFloat32},
282 {"vr7", Vector, 16, VectorOfFloat32},
283 {"vr8", Vector, 16, VectorOfFloat32},
284 {"vr9", Vector, 16, VectorOfFloat32},
285 {"vr10", Vector, 16, VectorOfFloat32},
286 {"vr11", Vector, 16, VectorOfFloat32},
287 {"vr12", Vector, 16, VectorOfFloat32},
288 {"vr13", Vector, 16, VectorOfFloat32},
289 {"vr14", Vector, 16, VectorOfFloat32},
290 {"vr15", Vector, 16, VectorOfFloat32},
291 {"vr16", Vector, 16, VectorOfFloat32},
292 {"vr17", Vector, 16, VectorOfFloat32},
293 {"vr18", Vector, 16, VectorOfFloat32},
294 {"vr19", Vector, 16, VectorOfFloat32},
295 {"vr20", Vector, 16, VectorOfFloat32},
296 {"vr21", Vector, 16, VectorOfFloat32},
297 {"vr22", Vector, 16, VectorOfFloat32},
298 {"vr23", Vector, 16, VectorOfFloat32},
299 {"vr24", Vector, 16, VectorOfFloat32},
300 {"vr25", Vector, 16, VectorOfFloat32},
301 {"vr26", Vector, 16, VectorOfFloat32},
302 {"vr27", Vector, 16, VectorOfFloat32},
303 {"vr28", Vector, 16, VectorOfFloat32},
304 {"vr29", Vector, 16, VectorOfFloat32},
305 {"vr30", Vector, 16, VectorOfFloat32},
306 {"vr31", Vector, 16, VectorOfFloat32},
307 {"vscr", Uint, 16, Hex},
308 {"vrvalid", Uint, 4, Hex}};
310 // Number of registers in each register set
311 const size_t k_num_gpr_registers =
312 sizeof(g_gpr_registers) / sizeof(DNBRegisterInfo);
313 const size_t k_num_fpr_registers =
314 sizeof(g_fpr_registers) / sizeof(DNBRegisterInfo);
315 const size_t k_num_exc_registers =
316 sizeof(g_exc_registers) / sizeof(DNBRegisterInfo);
317 const size_t k_num_vec_registers =
318 sizeof(g_vec_registers) / sizeof(DNBRegisterInfo);
319 // Total number of registers for this architecture
320 const size_t k_num_ppc_registers = k_num_gpr_registers + k_num_fpr_registers +
321 k_num_exc_registers + k_num_vec_registers;
323 //----------------------------------------------------------------------
324 // Register set definitions. The first definitions at register set index
325 // of zero is for all registers, followed by other registers sets. The
326 // register information for the all register set need not be filled in.
327 //----------------------------------------------------------------------
328 static const DNBRegisterSetInfo g_reg_sets[] = {
329 {"PowerPC Registers", NULL, k_num_ppc_registers},
330 {"General Purpose Registers", g_gpr_registers, k_num_gpr_registers},
331 {"Floating Point Registers", g_fpr_registers, k_num_fpr_registers},
332 {"Exception State Registers", g_exc_registers, k_num_exc_registers},
333 {"Altivec Registers", g_vec_registers, k_num_vec_registers}};
334 // Total number of register sets for this architecture
335 const size_t k_num_register_sets =
336 sizeof(g_reg_sets) / sizeof(DNBRegisterSetInfo);
338 const DNBRegisterSetInfo *
339 DNBArchMachPPC::GetRegisterSetInfo(nub_size_t *num_reg_sets) const {
340 *num_reg_sets = k_num_register_sets;
344 bool DNBArchMachPPC::GetRegisterValue(uint32_t set, uint32_t reg,
345 DNBRegisterValue *value) const {
346 if (set == REGISTER_SET_GENERIC) {
348 case GENERIC_REGNUM_PC: // Program Counter
350 reg = e_regNumGPR_srr0;
353 case GENERIC_REGNUM_SP: // Stack Pointer
355 reg = e_regNumGPR_r1;
358 case GENERIC_REGNUM_FP: // Frame Pointer
359 // Return false for now instead of returning r30 as gcc 3.x would
360 // use a variety of registers for the FP and it takes inspecting
361 // the stack to make sure there is a frame pointer before we can
365 case GENERIC_REGNUM_RA: // Return Address
367 reg = e_regNumGPR_lr;
370 case GENERIC_REGNUM_FLAGS: // Processor flags register
372 reg = e_regNumGPR_srr1;
380 if (!m_state.RegsAreValid(set))
383 const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg);
385 value->info = *regInfo;
388 if (reg < k_num_gpr_registers) {
389 value->value.uint32 =
390 (&m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0))[reg];
397 value->value.float64 =
398 m_state.fpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(fpregs)[reg];
400 } else if (reg == 32) {
401 value->value.uint32 =
402 m_state.fpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(fpscr);
408 if (reg < k_num_exc_registers) {
409 value->value.uint32 =
410 (&m_state.exc.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(dar))[reg];
416 if (reg < k_num_vec_registers) {
417 if (reg < 33) // FP0 - FP31 and VSCR
419 // Copy all 4 uint32 values for this vector register
420 value->value.v_uint32[0] =
421 m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg]
423 value->value.v_uint32[1] =
424 m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg]
426 value->value.v_uint32[2] =
427 m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg]
429 value->value.v_uint32[3] =
430 m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg]
433 } else if (reg == 34) // VRVALID
435 value->value.uint32 =
436 m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vrvalid);
446 kern_return_t DNBArchMachPPC::GetRegisterState(int set, bool force) {
449 return GetGPRState(force) | GetFPRState(force) | GetEXCState(force) |
452 return GetGPRState(force);
454 return GetFPRState(force);
456 return GetEXCState(force);
458 return GetVECState(force);
462 return KERN_INVALID_ARGUMENT;
465 kern_return_t DNBArchMachPPC::SetRegisterState(int set) {
466 // Make sure we have a valid context to set.
467 kern_return_t err = GetRegisterState(set, false);
468 if (err != KERN_SUCCESS)
473 return SetGPRState() | SetFPRState() | SetEXCState() | SetVECState();
475 return SetGPRState();
477 return SetFPRState();
479 return SetEXCState();
481 return SetVECState();
485 return KERN_INVALID_ARGUMENT;
488 bool DNBArchMachPPC::RegisterSetStateIsValid(int set) const {
489 return m_state.RegsAreValid(set);
492 #endif // #if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__)