Initial import from FreeBSD RELENG_4:
[games.git] / contrib / gdb / gdb / nlm / ppc.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <time.h>
5 #include <errno.h>
6
7 #include <nwtypes.h>
8 #include <nwdfs.h>
9 #include <nwconio.h>
10 #include <nwadv.h>
11 #include <nwdbgapi.h>
12 #include <nwthread.h>
13 #include "ppc.h"
14
15 extern char *mem2hex (void *mem, char *buf, int count, int may_fault);
16 extern char *hex2mem (char *buf, void *mem, int count, int may_fault);
17 extern int computeSignal (int exceptionVector);
18
19 void
20 flush_i_cache (void)
21 {
22 }
23
24 /* Get the registers out of the frame information.  */
25
26 void
27 frame_to_registers (frame, regs)
28      struct StackFrame *frame;
29      char *regs;
30 {
31   mem2hex (&frame->ExceptionState.CsavedRegs, &regs[GP0_REGNUM * 4 * 2], 4 * 32, 0);
32
33   mem2hex (&frame->ExceptionState.CSavedFPRegs, &regs[FP0_REGNUM * 4 * 2], 4 * 32, 0);
34
35   mem2hex (&frame->ExceptionPC, &regs[PC_REGNUM * 4 * 2], 4 * 1, 0);
36
37   mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, &regs[CR_REGNUM * 4 * 2], 4 * 1, 0);
38   mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, &regs[LR_REGNUM * 4 * 2], 4 * 1, 0);
39   mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, &regs[CTR_REGNUM * 4 * 2], 4 * 1, 0);
40   mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, &regs[XER_REGNUM * 4 * 2], 4 * 1, 0);
41   mem2hex (&frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, &regs[MQ_REGNUM * 4 * 2], 4 * 1, 0);
42 }
43
44 /* Put the registers back into the frame information.  */
45
46 void
47 registers_to_frame (regs, frame)
48      char *regs;
49      struct StackFrame *frame;
50 {
51   hex2mem (&regs[GP0_REGNUM * 4 * 2], &frame->ExceptionState.CsavedRegs, 4 * 32, 0);
52
53   hex2mem (&regs[FP0_REGNUM * 4 * 2], &frame->ExceptionState.CSavedFPRegs, 4 * 32, 0);
54
55   hex2mem (&regs[PC_REGNUM * 4 * 2], &frame->ExceptionPC, 4 * 1, 0);
56
57   hex2mem (&regs[CR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedSRR1, 4 * 1, 0);
58   hex2mem (&regs[LR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR, 4 * 1, 0);
59   hex2mem (&regs[CTR_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR, 4 * 1, 0);
60   hex2mem (&regs[XER_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedXER, 4 * 1, 0);
61   hex2mem (&regs[MQ_REGNUM * 4 * 2], &frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedMQ, 4 * 1, 0);
62 }
63
64
65 extern volatile int mem_err;
66
67 #ifdef ALTERNATE_MEM_FUNCS
68 extern int ReadByteAltDebugger (char* addr, char *theByte);
69 extern int WriteByteAltDebugger (char* addr, char theByte);
70 int
71 get_char (addr)
72      char *addr;
73 {
74   char c;
75
76   if (!ReadByteAltDebugger (addr, &c))
77     mem_err = 1;
78
79   return c;
80 }
81
82 void
83 set_char (addr, val)
84      char *addr;
85      int val;
86 {
87   if (!WriteByteAltDebugger (addr, val))
88     mem_err = 1;
89 }
90 #endif
91
92 int
93 mem_write (dst, src, len)
94      char *dst, *src;
95      int len;
96 {
97   while (len-- && !mem_err)
98     set_char (dst++, *src++);
99
100   return mem_err;
101 }
102
103 union inst
104 {
105   LONG l;
106
107   struct
108     {
109       union
110         {
111           struct                /* Unconditional branch */
112             {
113               unsigned opcode : 6; /* 18 */
114               signed li : 24;
115               unsigned aa : 1;
116               unsigned lk : 1;
117             } b;
118           struct                /* Conditional branch */
119             {
120               unsigned opcode : 6; /* 16 */
121               unsigned bo : 5;
122               unsigned bi : 5;
123               signed bd : 14;
124               unsigned aa : 1;
125               unsigned lk : 1;
126             } bc;
127           struct                /* Conditional branch to ctr or lr reg */
128             {
129               unsigned opcode : 6; /* 19 */
130               unsigned bo : 5;
131               unsigned bi : 5;
132               unsigned type : 15; /* 528 = ctr, 16 = lr */
133               unsigned lk : 1;
134             } bclr;
135         } variant;
136     } inst;
137 };
138
139 static LONG saved_inst;
140 static LONG *saved_inst_pc = 0;
141 static LONG saved_target_inst;
142 static LONG *saved_target_inst_pc = 0;
143
144 void
145 set_step_traps (frame)
146      struct StackFrame *frame;
147 {
148   union inst inst;
149   LONG *target;
150   int opcode;
151   int ra, rb;
152   LONG *pc = (LONG *)frame->ExceptionPC;
153
154   inst.l = *pc++;
155
156   opcode = inst.inst.variant.b.opcode;
157
158   target = pc;
159
160   switch (opcode)
161     {
162     case 18:                    /* Unconditional branch */
163
164       if (inst.inst.variant.b.aa) /* Absolute? */
165         target = 0;
166       target += inst.inst.variant.b.li;
167
168       break;
169     case 16:                    /* Conditional branch */
170
171       if (!inst.inst.variant.bc.aa) /* Absolute? */
172         target = 0;
173       target += inst.inst.variant.bc.bd;
174
175       break;
176     case 19:                    /* Cond. branch via ctr or lr reg */
177       switch (inst.inst.variant.bclr.type)
178         {
179         case 528:               /* ctr */
180           target = (LONG *)frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedCTR;
181           break;
182         case 16:                /* lr */
183           target = (LONG *)frame->ExceptionState.u.SpecialRegistersEnumerated.CsavedLR;
184           break;
185         }
186       break;
187     }
188
189   saved_inst = *pc;
190   mem_write (pc, breakpoint_insn, BREAKPOINT_SIZE);
191   saved_inst_pc = pc;
192
193   if (target != pc)
194     {
195       saved_target_inst = *target;
196       mem_write (target, breakpoint_insn, BREAKPOINT_SIZE);
197       saved_target_inst_pc = target;
198     }
199 }
200
201 /* Remove step breakpoints.  Returns non-zero if pc was at a step breakpoint,
202    zero otherwise.  This routine works even if there were no step breakpoints
203    set.  */
204
205 int
206 clear_step_traps (frame)
207      struct StackFrame *frame;
208 {
209   int retcode;
210   LONG *pc = (LONG *)frame->ExceptionPC;
211
212   if (saved_inst_pc == pc || saved_target_inst_pc == pc)
213     retcode = 1;
214   else
215     retcode = 0;
216
217   if (saved_inst_pc)
218     {
219       mem_write (saved_inst_pc, saved_inst, BREAKPOINT_SIZE);
220       saved_inst_pc = 0;
221     }
222
223   if (saved_target_inst_pc)
224     {
225       mem_write (saved_target_inst_pc, saved_target_inst, BREAKPOINT_SIZE);
226       saved_target_inst_pc = 0;
227     }
228
229   return retcode;
230 }
231
232 void
233 do_status (ptr, frame)
234      char *ptr;
235      struct StackFrame *frame;
236 {
237   int sigval;
238
239   sigval = computeSignal (frame->ExceptionNumber);
240
241   sprintf (ptr, "T%02x", sigval);
242   ptr += 3;
243
244   sprintf (ptr, "%02x:", PC_REGNUM);
245   ptr = mem2hex (&frame->ExceptionPC, ptr + 3, 4, 0);
246   *ptr++ = ';';
247
248   sprintf (ptr, "%02x:", SP_REGNUM);
249   ptr = mem2hex (&frame->ExceptionState.CsavedRegs[SP_REGNUM], ptr + 3, 4, 0);
250   *ptr++ = ';';
251
252   sprintf (ptr, "%02x:", LR_REGNUM);
253   ptr = mem2hex (&frame->ExceptionState.CsavedRegs[LR_REGNUM], ptr + 3, 4, 0);
254   *ptr++ = ';';
255
256   *ptr = '\000';
257 }