blob: abd1a353158588b4d5789b331359a5958b34d9c9 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- DNBArchImpl.cpp -----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Created by Greg Clayton on 6/25/07.
11//
12//===----------------------------------------------------------------------===//
13
14#if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__)
15
16#if __DARWIN_UNIX03
17#define PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(reg) __##reg
18#else
19#define PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(reg) reg
20#endif
21
22#include "MacOSX/ppc/DNBArchImpl.h"
23#include "MacOSX/MachThread.h"
24#include "DNBBreakpoint.h"
25#include "DNBLog.h"
26#include "DNBRegisterInfo.h"
27
28static const uint8_t g_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 };
29
30const uint8_t * const
31DNBArchMachPPC::SoftwareBreakpointOpcode (nub_size_t size)
32{
33 if (size == 4)
34 return g_breakpoint_opcode;
35 return NULL;
36}
37
38uint32_t
39DNBArchMachPPC::GetCPUType()
40{
41 return CPU_TYPE_POWERPC;
42}
43
44uint64_t
45DNBArchMachPPC::GetPC(uint64_t failValue)
46{
47 // Get program counter
48 if (GetGPRState(false) == KERN_SUCCESS)
49 return m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0);
50 return failValue;
51}
52
53kern_return_t
54DNBArchMachPPC::SetPC(uint64_t value)
55{
56 // Get program counter
57 kern_return_t err = GetGPRState(false);
58 if (err == KERN_SUCCESS)
59 {
60 m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0) = value;
61 err = SetGPRState();
62 }
63 return err == KERN_SUCCESS;
64}
65
66uint64_t
67DNBArchMachPPC::GetSP(uint64_t failValue)
68{
69 // Get stack pointer
70 if (GetGPRState(false) == KERN_SUCCESS)
71 return m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(r1);
72 return failValue;
73}
74
75kern_return_t
76DNBArchMachPPC::GetGPRState(bool force)
77{
78 if (force || m_state.GetError(e_regSetGPR, Read))
79 {
80 mach_msg_type_number_t count = e_regSetWordSizeGPR;
81 m_state.SetError(e_regSetGPR, Read, ::thread_get_state(m_thread->ThreadID(), e_regSetGPR, (thread_state_t)&m_state.gpr, &count));
82 }
83 return m_state.GetError(e_regSetGPR, Read);
84}
85
86kern_return_t
87DNBArchMachPPC::GetFPRState(bool force)
88{
89 if (force || m_state.GetError(e_regSetFPR, Read))
90 {
91 mach_msg_type_number_t count = e_regSetWordSizeFPR;
92 m_state.SetError(e_regSetFPR, Read, ::thread_get_state(m_thread->ThreadID(), e_regSetFPR, (thread_state_t)&m_state.fpr, &count));
93 }
94 return m_state.GetError(e_regSetFPR, Read);
95}
96
97kern_return_t
98DNBArchMachPPC::GetEXCState(bool force)
99{
100 if (force || m_state.GetError(e_regSetEXC, Read))
101 {
102 mach_msg_type_number_t count = e_regSetWordSizeEXC;
103 m_state.SetError(e_regSetEXC, Read, ::thread_get_state(m_thread->ThreadID(), e_regSetEXC, (thread_state_t)&m_state.exc, &count));
104 }
105 return m_state.GetError(e_regSetEXC, Read);
106}
107
108kern_return_t
109DNBArchMachPPC::GetVECState(bool force)
110{
111 if (force || m_state.GetError(e_regSetVEC, Read))
112 {
113 mach_msg_type_number_t count = e_regSetWordSizeVEC;
114 m_state.SetError(e_regSetVEC, Read, ::thread_get_state(m_thread->ThreadID(), e_regSetVEC, (thread_state_t)&m_state.vec, &count));
115 }
116 return m_state.GetError(e_regSetVEC, Read);
117}
118
119kern_return_t
120DNBArchMachPPC::SetGPRState()
121{
122 m_state.SetError(e_regSetGPR, Write, ::thread_set_state(m_thread->ThreadID(), e_regSetGPR, (thread_state_t)&m_state.gpr, e_regSetWordSizeGPR));
123 return m_state.GetError(e_regSetGPR, Write);
124}
125
126kern_return_t
127DNBArchMachPPC::SetFPRState()
128{
129 m_state.SetError(e_regSetFPR, Write, ::thread_set_state(m_thread->ThreadID(), e_regSetFPR, (thread_state_t)&m_state.fpr, e_regSetWordSizeFPR));
130 return m_state.GetError(e_regSetFPR, Write);
131}
132
133kern_return_t
134DNBArchMachPPC::SetEXCState()
135{
136 m_state.SetError(e_regSetEXC, Write, ::thread_set_state(m_thread->ThreadID(), e_regSetEXC, (thread_state_t)&m_state.exc, e_regSetWordSizeEXC));
137 return m_state.GetError(e_regSetEXC, Write);
138}
139
140kern_return_t
141DNBArchMachPPC::SetVECState()
142{
143 m_state.SetError(e_regSetVEC, Write, ::thread_set_state(m_thread->ThreadID(), e_regSetVEC, (thread_state_t)&m_state.vec, e_regSetWordSizeVEC));
144 return m_state.GetError(e_regSetVEC, Write);
145}
146
147bool
148DNBArchMachPPC::ThreadWillResume()
149{
150 bool success = true;
151
152 // Do we need to step this thread? If so, let the mach thread tell us so.
153 if (m_thread->IsStepping())
154 {
155 // This is the primary thread, let the arch do anything it needs
156 success = EnableHardwareSingleStep(true) == KERN_SUCCESS;
157 }
158 return success;
159}
160
161bool
162DNBArchMachPPC::ThreadDidStop()
163{
164 bool success = true;
165
166 m_state.InvalidateAllRegisterStates();
167
168 // Are we stepping a single instruction?
169 if (GetGPRState(true) == KERN_SUCCESS)
170 {
171 // We are single stepping, was this the primary thread?
172 if (m_thread->IsStepping())
173 {
174 // This was the primary thread, we need to clear the trace
175 // bit if so.
176 success = EnableHardwareSingleStep(false) == KERN_SUCCESS;
177 }
178 else
179 {
180 // The MachThread will automatically restore the suspend count
181 // in ThreadDidStop(), so we don't need to do anything here if
182 // we weren't the primary thread the last time
183 }
184 }
185 return success;
186}
187
188
189// Set the single step bit in the processor status register.
190kern_return_t
191DNBArchMachPPC::EnableHardwareSingleStep (bool enable)
192{
193 DNBLogThreadedIf(LOG_STEP, "DNBArchMachPPC::EnableHardwareSingleStep( enable = %d )", enable);
194 if (GetGPRState(false) == KERN_SUCCESS)
195 {
196 const uint32_t trace_bit = 0x400;
197 if (enable)
198 m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr1) |= trace_bit;
199 else
200 m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr1) &= ~trace_bit;
201 return SetGPRState();
202 }
203 return m_state.GetError(e_regSetGPR, Read);
204}
205
206//----------------------------------------------------------------------
207// Register information defintions for 32 bit PowerPC.
208//----------------------------------------------------------------------
209
210enum gpr_regnums
211{
212 e_regNumGPR_srr0,
213 e_regNumGPR_srr1,
214 e_regNumGPR_r0,
215 e_regNumGPR_r1,
216 e_regNumGPR_r2,
217 e_regNumGPR_r3,
218 e_regNumGPR_r4,
219 e_regNumGPR_r5,
220 e_regNumGPR_r6,
221 e_regNumGPR_r7,
222 e_regNumGPR_r8,
223 e_regNumGPR_r9,
224 e_regNumGPR_r10,
225 e_regNumGPR_r11,
226 e_regNumGPR_r12,
227 e_regNumGPR_r13,
228 e_regNumGPR_r14,
229 e_regNumGPR_r15,
230 e_regNumGPR_r16,
231 e_regNumGPR_r17,
232 e_regNumGPR_r18,
233 e_regNumGPR_r19,
234 e_regNumGPR_r20,
235 e_regNumGPR_r21,
236 e_regNumGPR_r22,
237 e_regNumGPR_r23,
238 e_regNumGPR_r24,
239 e_regNumGPR_r25,
240 e_regNumGPR_r26,
241 e_regNumGPR_r27,
242 e_regNumGPR_r28,
243 e_regNumGPR_r29,
244 e_regNumGPR_r30,
245 e_regNumGPR_r31,
246 e_regNumGPR_cr,
247 e_regNumGPR_xer,
248 e_regNumGPR_lr,
249 e_regNumGPR_ctr,
250 e_regNumGPR_mq,
251 e_regNumGPR_vrsave
252};
253
254
255
256
257// General purpose registers
258static DNBRegisterInfo g_gpr_registers[] =
259{
260 { "srr0" , Uint, 4, Hex },
261 { "srr1" , Uint, 4, Hex },
262 { "r0" , Uint, 4, Hex },
263 { "r1" , Uint, 4, Hex },
264 { "r2" , Uint, 4, Hex },
265 { "r3" , Uint, 4, Hex },
266 { "r4" , Uint, 4, Hex },
267 { "r5" , Uint, 4, Hex },
268 { "r6" , Uint, 4, Hex },
269 { "r7" , Uint, 4, Hex },
270 { "r8" , Uint, 4, Hex },
271 { "r9" , Uint, 4, Hex },
272 { "r10" , Uint, 4, Hex },
273 { "r11" , Uint, 4, Hex },
274 { "r12" , Uint, 4, Hex },
275 { "r13" , Uint, 4, Hex },
276 { "r14" , Uint, 4, Hex },
277 { "r15" , Uint, 4, Hex },
278 { "r16" , Uint, 4, Hex },
279 { "r17" , Uint, 4, Hex },
280 { "r18" , Uint, 4, Hex },
281 { "r19" , Uint, 4, Hex },
282 { "r20" , Uint, 4, Hex },
283 { "r21" , Uint, 4, Hex },
284 { "r22" , Uint, 4, Hex },
285 { "r23" , Uint, 4, Hex },
286 { "r24" , Uint, 4, Hex },
287 { "r25" , Uint, 4, Hex },
288 { "r26" , Uint, 4, Hex },
289 { "r27" , Uint, 4, Hex },
290 { "r28" , Uint, 4, Hex },
291 { "r29" , Uint, 4, Hex },
292 { "r30" , Uint, 4, Hex },
293 { "r31" , Uint, 4, Hex },
294 { "cr" , Uint, 4, Hex },
295 { "xer" , Uint, 4, Hex },
296 { "lr" , Uint, 4, Hex },
297 { "ctr" , Uint, 4, Hex },
298 { "mq" , Uint, 4, Hex },
299 { "vrsave", Uint, 4, Hex },
300};
301
302// Floating point registers
303static DNBRegisterInfo g_fpr_registers[] =
304{
305 { "fp0" , IEEE754, 8, Float },
306 { "fp1" , IEEE754, 8, Float },
307 { "fp2" , IEEE754, 8, Float },
308 { "fp3" , IEEE754, 8, Float },
309 { "fp4" , IEEE754, 8, Float },
310 { "fp5" , IEEE754, 8, Float },
311 { "fp6" , IEEE754, 8, Float },
312 { "fp7" , IEEE754, 8, Float },
313 { "fp8" , IEEE754, 8, Float },
314 { "fp9" , IEEE754, 8, Float },
315 { "fp10" , IEEE754, 8, Float },
316 { "fp11" , IEEE754, 8, Float },
317 { "fp12" , IEEE754, 8, Float },
318 { "fp13" , IEEE754, 8, Float },
319 { "fp14" , IEEE754, 8, Float },
320 { "fp15" , IEEE754, 8, Float },
321 { "fp16" , IEEE754, 8, Float },
322 { "fp17" , IEEE754, 8, Float },
323 { "fp18" , IEEE754, 8, Float },
324 { "fp19" , IEEE754, 8, Float },
325 { "fp20" , IEEE754, 8, Float },
326 { "fp21" , IEEE754, 8, Float },
327 { "fp22" , IEEE754, 8, Float },
328 { "fp23" , IEEE754, 8, Float },
329 { "fp24" , IEEE754, 8, Float },
330 { "fp25" , IEEE754, 8, Float },
331 { "fp26" , IEEE754, 8, Float },
332 { "fp27" , IEEE754, 8, Float },
333 { "fp28" , IEEE754, 8, Float },
334 { "fp29" , IEEE754, 8, Float },
335 { "fp30" , IEEE754, 8, Float },
336 { "fp31" , IEEE754, 8, Float },
337 { "fpscr" , Uint, 4, Hex }
338};
339
340// Exception registers
341
342static DNBRegisterInfo g_exc_registers[] =
343{
344 { "dar" , Uint, 4, Hex },
345 { "dsisr" , Uint, 4, Hex },
346 { "exception" , Uint, 4, Hex }
347};
348
349// Altivec registers
350static DNBRegisterInfo g_vec_registers[] =
351{
352 { "vr0" , Vector, 16, VectorOfFloat32 },
353 { "vr1" , Vector, 16, VectorOfFloat32 },
354 { "vr2" , Vector, 16, VectorOfFloat32 },
355 { "vr3" , Vector, 16, VectorOfFloat32 },
356 { "vr4" , Vector, 16, VectorOfFloat32 },
357 { "vr5" , Vector, 16, VectorOfFloat32 },
358 { "vr6" , Vector, 16, VectorOfFloat32 },
359 { "vr7" , Vector, 16, VectorOfFloat32 },
360 { "vr8" , Vector, 16, VectorOfFloat32 },
361 { "vr9" , Vector, 16, VectorOfFloat32 },
362 { "vr10" , Vector, 16, VectorOfFloat32 },
363 { "vr11" , Vector, 16, VectorOfFloat32 },
364 { "vr12" , Vector, 16, VectorOfFloat32 },
365 { "vr13" , Vector, 16, VectorOfFloat32 },
366 { "vr14" , Vector, 16, VectorOfFloat32 },
367 { "vr15" , Vector, 16, VectorOfFloat32 },
368 { "vr16" , Vector, 16, VectorOfFloat32 },
369 { "vr17" , Vector, 16, VectorOfFloat32 },
370 { "vr18" , Vector, 16, VectorOfFloat32 },
371 { "vr19" , Vector, 16, VectorOfFloat32 },
372 { "vr20" , Vector, 16, VectorOfFloat32 },
373 { "vr21" , Vector, 16, VectorOfFloat32 },
374 { "vr22" , Vector, 16, VectorOfFloat32 },
375 { "vr23" , Vector, 16, VectorOfFloat32 },
376 { "vr24" , Vector, 16, VectorOfFloat32 },
377 { "vr25" , Vector, 16, VectorOfFloat32 },
378 { "vr26" , Vector, 16, VectorOfFloat32 },
379 { "vr27" , Vector, 16, VectorOfFloat32 },
380 { "vr28" , Vector, 16, VectorOfFloat32 },
381 { "vr29" , Vector, 16, VectorOfFloat32 },
382 { "vr30" , Vector, 16, VectorOfFloat32 },
383 { "vr31" , Vector, 16, VectorOfFloat32 },
384 { "vscr" , Uint, 16, Hex },
385 { "vrvalid" , Uint, 4, Hex }
386};
387
388// Number of registers in each register set
389const size_t k_num_gpr_registers = sizeof(g_gpr_registers)/sizeof(DNBRegisterInfo);
390const size_t k_num_fpr_registers = sizeof(g_fpr_registers)/sizeof(DNBRegisterInfo);
391const size_t k_num_exc_registers = sizeof(g_exc_registers)/sizeof(DNBRegisterInfo);
392const size_t k_num_vec_registers = sizeof(g_vec_registers)/sizeof(DNBRegisterInfo);
393// Total number of registers for this architecture
394const size_t k_num_ppc_registers = k_num_gpr_registers + k_num_fpr_registers + k_num_exc_registers + k_num_vec_registers;
395
396//----------------------------------------------------------------------
397// Register set definitions. The first definitions at register set index
398// of zero is for all registers, followed by other registers sets. The
399// register information for the all register set need not be filled in.
400//----------------------------------------------------------------------
401static const DNBRegisterSetInfo g_reg_sets[] =
402{
403 { "PowerPC Registers", NULL, k_num_ppc_registers },
404 { "General Purpose Registers", g_gpr_registers, k_num_gpr_registers },
405 { "Floating Point Registers", g_fpr_registers, k_num_fpr_registers },
406 { "Exception State Registers", g_exc_registers, k_num_exc_registers },
407 { "Altivec Registers", g_vec_registers, k_num_vec_registers }
408};
409// Total number of register sets for this architecture
410const size_t k_num_register_sets = sizeof(g_reg_sets)/sizeof(DNBRegisterSetInfo);
411
412
413const DNBRegisterSetInfo *
414DNBArchMachPPC::GetRegisterSetInfo(nub_size_t *num_reg_sets) const
415{
416 *num_reg_sets = k_num_register_sets;
417 return g_reg_sets;
418}
419
420bool
421DNBArchMachPPC::GetRegisterValue(int set, int reg, DNBRegisterValue *value) const
422{
423 if (set == REGISTER_SET_GENERIC)
424 {
425 switch (reg)
426 {
427 case GENERIC_REGNUM_PC: // Program Counter
428 set = e_regSetGPR;
429 reg = e_regNumGPR_srr0;
430 break;
431
432 case GENERIC_REGNUM_SP: // Stack Pointer
433 set = e_regSetGPR;
434 reg = e_regNumGPR_r1;
435 break;
436
437 case GENERIC_REGNUM_FP: // Frame Pointer
438 // Return false for now instead of returning r30 as gcc 3.x would
439 // use a variety of registers for the FP and it takes inspecting
440 // the stack to make sure there is a frame pointer before we can
441 // determine the FP.
442 return false;
443
444 case GENERIC_REGNUM_RA: // Return Address
445 set = e_regSetGPR;
446 reg = e_regNumGPR_lr;
447 break;
448
449 case GENERIC_REGNUM_FLAGS: // Processor flags register
450 set = e_regSetGPR;
451 reg = e_regNumGPR_srr1;
452 break;
453
454 default:
455 return false;
456 }
457 }
458
459 if (!m_state.RegsAreValid(set))
460 return false;
461
462 const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg);
463 if (regInfo)
464 {
465 value->info = *regInfo;
466 switch (set)
467 {
468 case e_regSetGPR:
469 if (reg < k_num_gpr_registers)
470 {
471 value->value.uint32 = (&m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0))[reg];
472 return true;
473 }
474 break;
475
476 case e_regSetFPR:
477 if (reg < 32)
478 {
479 value->value.float64 = m_state.fpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(fpregs)[reg];
480 return true;
481 }
482 else if (reg == 32)
483 {
484 value->value.uint32 = m_state.fpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(fpscr);
485 return true;
486 }
487 break;
488
489 case e_regSetEXC:
490 if (reg < k_num_exc_registers)
491 {
492 value->value.uint32 = (&m_state.exc.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(dar))[reg];
493 return true;
494 }
495 break;
496
497 case e_regSetVEC:
498 if (reg < k_num_vec_registers)
499 {
500 if (reg < 33) // FP0 - FP31 and VSCR
501 {
502 // Copy all 4 uint32 values for this vector register
503 value->value.v_uint32[0] = m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg][0];
504 value->value.v_uint32[1] = m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg][1];
505 value->value.v_uint32[2] = m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg][2];
506 value->value.v_uint32[3] = m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg][3];
507 return true;
508 }
509 else if (reg == 34) // VRVALID
510 {
511 value->value.uint32 = m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vrvalid);
512 return true;
513 }
514 }
515 break;
516 }
517 }
518 return false;
519}
520
521
522kern_return_t
523DNBArchMachPPC::GetRegisterState(int set, bool force)
524{
525 switch (set)
526 {
527 case e_regSetALL:
528 return GetGPRState(force) |
529 GetFPRState(force) |
530 GetEXCState(force) |
531 GetVECState(force);
532 case e_regSetGPR: return GetGPRState(force);
533 case e_regSetFPR: return GetFPRState(force);
534 case e_regSetEXC: return GetEXCState(force);
535 case e_regSetVEC: return GetVECState(force);
536 default: break;
537 }
538 return KERN_INVALID_ARGUMENT;
539}
540
541kern_return_t
542DNBArchMachPPC::SetRegisterState(int set)
543{
544 // Make sure we have a valid context to set.
545 kern_return_t err = GetRegisterState(set, false);
546 if (err != KERN_SUCCESS)
547 return err;
548
549 switch (set)
550 {
551 case e_regSetALL: return SetGPRState() | SetFPRState() | SetEXCState() | SetVECState();
552 case e_regSetGPR: return SetGPRState();
553 case e_regSetFPR: return SetFPRState();
554 case e_regSetEXC: return SetEXCState();
555 case e_regSetVEC: return SetVECState();
556 default: break;
557 }
558 return KERN_INVALID_ARGUMENT;
559}
560
561bool
562DNBArchMachPPC::RegisterSetStateIsValid (int set) const
563{
564 return m_state.RegsAreValid(set);
565}
566
567
568#endif // #if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__)
569