]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/pyr-tdep.c
Initial creation of sourceware repository
[thirdparty/binutils-gdb.git] / gdb / pyr-tdep.c
1 /* Pyramid target-dependent code for GDB.
2 Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 #include "defs.h"
21
22 /*** Prettier register printing. ***/
23
24 /* Print registers in the same format as pyramid's dbx, adb, sdb. */
25 pyr_print_registers(reg_buf, regnum)
26 long *reg_buf[];
27 {
28 register int regno;
29 int usp, ksp;
30 struct user u;
31
32 for (regno = 0; regno < 16; regno++) {
33 printf_unfiltered/*_filtered*/ ("%6.6s: %8x %6.6s: %8x %6s: %8x %6s: %8x\n",
34 REGISTER_NAME (regno), reg_buf[regno],
35 REGISTER_NAME (regno+16), reg_buf[regno+16],
36 REGISTER_NAME (regno+32), reg_buf[regno+32],
37 REGISTER_NAME (regno+48), reg_buf[regno+48]);
38 }
39 usp = ptrace (3, inferior_pid,
40 (PTRACE_ARG3_TYPE) ((char *)&u.u_pcb.pcb_usp) -
41 ((char *)&u), 0);
42 ksp = ptrace (3, inferior_pid,
43 (PTRACE_ARG3_TYPE) ((char *)&u.u_pcb.pcb_ksp) -
44 ((char *)&u), 0);
45 printf_unfiltered/*_filtered*/ ("\n%6.6s: %8x %6.6s: %8x (%08x) %6.6s %8x\n",
46 REGISTER_NAME (CSP_REGNUM),reg_buf[CSP_REGNUM],
47 REGISTER_NAME (KSP_REGNUM), reg_buf[KSP_REGNUM], ksp,
48 "usp", usp);
49 }
50
51 /* Print the register regnum, or all registers if regnum is -1.
52 fpregs is currently ignored. */
53
54 pyr_do_registers_info (regnum, fpregs)
55 int regnum;
56 int fpregs;
57 {
58 /* On a pyr, we know a virtual register can always fit in an long.
59 Here (and elsewhere) we take advantage of that. Yuk. */
60 long raw_regs[MAX_REGISTER_RAW_SIZE*NUM_REGS];
61 register int i;
62
63 for (i = 0 ; i < 64 ; i++) {
64 read_relative_register_raw_bytes(i, raw_regs+i);
65 }
66 if (regnum == -1)
67 pyr_print_registers (raw_regs, regnum);
68 else
69 for (i = 0; i < NUM_REGS; i++)
70 if (i == regnum) {
71 long val = raw_regs[i];
72
73 fputs_filtered (REGISTER_NAME (i), gdb_stdout);
74 printf_filtered(":");
75 print_spaces_filtered (6 - strlen (REGISTER_NAME (i)), gdb_stdout);
76 if (val == 0)
77 printf_filtered ("0");
78 else
79 printf_filtered ("%s %d", local_hex_string_custom(val,"08"), val);
80 printf_filtered("\n");
81 }
82 }
83 \f
84 /*** Debugging editions of various macros from m-pyr.h ****/
85
86 CORE_ADDR frame_locals_address (frame)
87 struct frame_info *frame;
88 {
89 register int addr = find_saved_register (frame,CFP_REGNUM);
90 register int result = read_memory_integer (addr, 4);
91 #ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
92 fprintf_unfiltered (gdb_stderr,
93 "\t[[..frame_locals:%8x, %s= %x @%x fcfp= %x foo= %x\n\t gr13=%x pr13=%x tr13=%x @%x]]\n",
94 frame->frame,
95 REGISTER_NAME (CFP_REGNUM),
96 result, addr,
97 frame->frame_cfp, (CFP_REGNUM),
98
99
100 read_register(13), read_register(29), read_register(61),
101 find_saved_register(frame, 61));
102 #endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
103
104 /* FIXME: I thought read_register (CFP_REGNUM) should be the right answer;
105 or at least CFP_REGNUM relative to FRAME (ie, result).
106 There seems to be a bug in the way the innermost frame is set up. */
107
108 return ((frame->next) ? result: frame->frame_cfp);
109 }
110
111 CORE_ADDR frame_args_addr (frame)
112 struct frame_info *frame;
113 {
114 register int addr = find_saved_register (frame,CFP_REGNUM);
115 register int result = read_memory_integer (addr, 4);
116
117 #ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
118 fprintf_unfiltered (gdb_stderr,
119 "\t[[..frame_args:%8x, %s= %x @%x fcfp= %x r_r= %x\n\t gr13=%x pr13=%x tr13=%x @%x]]\n",
120 frame->frame,
121 REGISTER_NAME (CFP_REGNUM),
122 result, addr,
123 frame->frame_cfp, read_register(CFP_REGNUM),
124
125 read_register(13), read_register(29), read_register(61),
126 find_saved_register(frame, 61));
127 #endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
128
129 /* FIXME: I thought read_register (CFP_REGNUM) should be the right answer;
130 or at least CFP_REGNUM relative to FRAME (ie, result).
131 There seems to be a bug in the way the innermost frame is set up. */
132 return ((frame->next) ? result: frame->frame_cfp);
133 }
134
135 #include "symtab.h"
136 #include "opcode/pyr.h"
137 #include "gdbcore.h"
138
139 \f
140 /* A couple of functions used for debugging frame-handling on
141 Pyramids. (The Pyramid-dependent handling of register values for
142 windowed registers is known to be buggy.)
143
144 When debugging, these functions can supplant the normal definitions of some
145 of the macros in tm-pyramid.h The quantity of information produced
146 when these functions are used makes the gdb unusable as a
147 debugger for user programs. */
148
149 extern unsigned pyr_saved_pc(), pyr_frame_chain();
150
151 CORE_ADDR pyr_frame_chain(frame)
152 CORE_ADDR frame;
153 {
154 int foo=frame - CONTROL_STACK_FRAME_SIZE;
155 /* printf_unfiltered ("...following chain from %x: got %x\n", frame, foo);*/
156 return foo;
157 }
158
159 CORE_ADDR pyr_saved_pc(frame)
160 CORE_ADDR frame;
161 {
162 int foo=0;
163 foo = read_memory_integer (((CORE_ADDR)(frame))+60, 4);
164 printf_unfiltered ("..reading pc from frame 0x%0x+%d regs: got %0x\n",
165 frame, 60/4, foo);
166 return foo;
167 }
168
169 /* Pyramid instructions are never longer than this many bytes. */
170 #define MAXLEN 24
171
172 /* Number of elements in the opcode table. */
173 /*const*/ static int nopcodes = (sizeof (pyr_opcodes) / sizeof( pyr_opcodes[0]));
174 #define NOPCODES (nopcodes)
175
176 /* Let's be byte-independent so we can use this as a cross-assembler. */
177
178 #define NEXTLONG(p) \
179 (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])
180 \f
181 /* Print one instruction at address MEMADDR in debugged memory,
182 on STREAM. Returns length of the instruction, in bytes. */
183
184 int
185 pyr_print_insn (memaddr, stream)
186 CORE_ADDR memaddr;
187 GDB_FILE *stream;
188 {
189 unsigned char buffer[MAXLEN];
190 register int i, nargs, insn_size =4;
191 register unsigned char *p;
192 register char *d;
193 register int insn_opcode, operand_mode;
194 register int index_multiplier, index_reg_regno, op_1_regno, op_2_regno ;
195 long insn; /* first word of the insn, not broken down. */
196 pyr_insn_format insn_decode; /* the same, broken out into op{code,erands} */
197 long extra_1, extra_2;
198
199 read_memory (memaddr, buffer, MAXLEN);
200 insn_decode = *((pyr_insn_format *) buffer);
201 insn = * ((int *) buffer);
202 insn_opcode = insn_decode.operator;
203 operand_mode = insn_decode.mode;
204 index_multiplier = insn_decode.index_scale;
205 index_reg_regno = insn_decode.index_reg;
206 op_1_regno = insn_decode.operand_1;
207 op_2_regno = insn_decode.operand_2;
208
209
210 if (*((int *)buffer) == 0x0) {
211 /* "halt" looks just like an invalid "jump" to the insn decoder,
212 so is dealt with as a special case */
213 fprintf_unfiltered (stream, "halt");
214 return (4);
215 }
216
217 for (i = 0; i < NOPCODES; i++)
218 if (pyr_opcodes[i].datum.code == insn_opcode)
219 break;
220
221 if (i == NOPCODES)
222 /* FIXME: Handle unrecognised instructions better. */
223 fprintf_unfiltered (stream, "???\t#%08x\t(op=%x mode =%x)",
224 insn, insn_decode.operator, insn_decode.mode);
225 else
226 {
227 /* Print the mnemonic for the instruction. Pyramid insn operands
228 are so regular that we can deal with almost all of them
229 separately.
230 Unconditional branches are an exception: they are encoded as
231 conditional branches (branch if false condition, I think)
232 with no condition specified. The average user will not be
233 aware of this. To maintain their illusion that an
234 unconditional branch insn exists, we will have to FIXME to
235 treat the insn mnemnonic of all branch instructions here as a
236 special case: check the operands of branch insn and print an
237 appropriate mnemonic. */
238
239 fprintf_unfiltered (stream, "%s\t", pyr_opcodes[i].name);
240
241 /* Print the operands of the insn (as specified in
242 insn.operand_mode).
243 Branch operands of branches are a special case: they are a word
244 offset, not a byte offset. */
245
246 if (insn_decode.operator == 0x01 || insn_decode.operator == 0x02) {
247 register int bit_codes=(insn >> 16)&0xf;
248 register int i;
249 register int displacement = (insn & 0x0000ffff) << 2;
250
251 static char cc_bit_names[] = "cvzn"; /* z,n,c,v: strange order? */
252
253 /* Is bfc and no bits specified an unconditional branch?*/
254 for (i=0;i<4;i++) {
255 if ((bit_codes) & 0x1)
256 fputc_unfiltered (cc_bit_names[i], stream);
257 bit_codes >>= 1;
258 }
259
260 fprintf_unfiltered (stream, ",%0x",
261 displacement + memaddr);
262 return (insn_size);
263 }
264
265 switch (operand_mode) {
266 case 0:
267 fprintf_unfiltered (stream, "%s,%s",
268 REGISTER_NAME (op_1_regno),
269 REGISTER_NAME (op_2_regno));
270 break;
271
272 case 1:
273 fprintf_unfiltered (stream, " 0x%0x,%s",
274 op_1_regno,
275 REGISTER_NAME (op_2_regno));
276 break;
277
278 case 2:
279 read_memory (memaddr+4, buffer, MAXLEN);
280 insn_size += 4;
281 extra_1 = * ((int *) buffer);
282 fprintf_unfiltered (stream, " $0x%0x,%s",
283 extra_1,
284 REGISTER_NAME (op_2_regno));
285 break;
286 case 3:
287 fprintf_unfiltered (stream, " (%s),%s",
288 REGISTER_NAME (op_1_regno),
289 REGISTER_NAME (op_2_regno));
290 break;
291
292 case 4:
293 read_memory (memaddr+4, buffer, MAXLEN);
294 insn_size += 4;
295 extra_1 = * ((int *) buffer);
296 fprintf_unfiltered (stream, " 0x%0x(%s),%s",
297 extra_1,
298 REGISTER_NAME (op_1_regno),
299 REGISTER_NAME (op_2_regno));
300 break;
301
302 /* S1 destination mode */
303 case 5:
304 fprintf_unfiltered (stream,
305 ((index_reg_regno) ? "%s,(%s)[%s*%1d]" : "%s,(%s)"),
306 REGISTER_NAME (op_1_regno),
307 REGISTER_NAME (op_2_regno),
308 REGISTER_NAME (index_reg_regno),
309 index_multiplier);
310 break;
311
312 case 6:
313 fprintf_unfiltered (stream,
314 ((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]"
315 : " $%#0x,(%s)"),
316 op_1_regno,
317 REGISTER_NAME (op_2_regno),
318 REGISTER_NAME (index_reg_regno),
319 index_multiplier);
320 break;
321
322 case 7:
323 read_memory (memaddr+4, buffer, MAXLEN);
324 insn_size += 4;
325 extra_1 = * ((int *) buffer);
326 fprintf_unfiltered (stream,
327 ((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]"
328 : " $%#0x,(%s)"),
329 extra_1,
330 REGISTER_NAME (op_2_regno),
331 REGISTER_NAME (index_reg_regno),
332 index_multiplier);
333 break;
334
335 case 8:
336 fprintf_unfiltered (stream,
337 ((index_reg_regno) ? " (%s),(%s)[%s*%1d]" : " (%s),(%s)"),
338 REGISTER_NAME (op_1_regno),
339 REGISTER_NAME (op_2_regno),
340 REGISTER_NAME (index_reg_regno),
341 index_multiplier);
342 break;
343
344 case 9:
345 read_memory (memaddr+4, buffer, MAXLEN);
346 insn_size += 4;
347 extra_1 = * ((int *) buffer);
348 fprintf_unfiltered (stream,
349 ((index_reg_regno)
350 ? "%#0x(%s),(%s)[%s*%1d]"
351 : "%#0x(%s),(%s)"),
352 extra_1,
353 REGISTER_NAME (op_1_regno),
354 REGISTER_NAME (op_2_regno),
355 REGISTER_NAME (index_reg_regno),
356 index_multiplier);
357 break;
358
359 /* S2 destination mode */
360 case 10:
361 read_memory (memaddr+4, buffer, MAXLEN);
362 insn_size += 4;
363 extra_1 = * ((int *) buffer);
364 fprintf_unfiltered (stream,
365 ((index_reg_regno) ? "%s,%#0x(%s)[%s*%1d]" : "%s,%#0x(%s)"),
366 REGISTER_NAME (op_1_regno),
367 extra_1,
368 REGISTER_NAME (op_2_regno),
369 REGISTER_NAME (index_reg_regno),
370 index_multiplier);
371 break;
372 case 11:
373 read_memory (memaddr+4, buffer, MAXLEN);
374 insn_size += 4;
375 extra_1 = * ((int *) buffer);
376 fprintf_unfiltered (stream,
377 ((index_reg_regno) ?
378 " $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
379 op_1_regno,
380 extra_1,
381 REGISTER_NAME (op_2_regno),
382 REGISTER_NAME (index_reg_regno),
383 index_multiplier);
384 break;
385 case 12:
386 read_memory (memaddr+4, buffer, MAXLEN);
387 insn_size += 4;
388 extra_1 = * ((int *) buffer);
389 read_memory (memaddr+8, buffer, MAXLEN);
390 insn_size += 4;
391 extra_2 = * ((int *) buffer);
392 fprintf_unfiltered (stream,
393 ((index_reg_regno) ?
394 " $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
395 extra_1,
396 extra_2,
397 REGISTER_NAME (op_2_regno),
398 REGISTER_NAME (index_reg_regno),
399 index_multiplier);
400 break;
401
402 case 13:
403 read_memory (memaddr+4, buffer, MAXLEN);
404 insn_size += 4;
405 extra_1 = * ((int *) buffer);
406 fprintf_unfiltered (stream,
407 ((index_reg_regno)
408 ? " (%s),%#0x(%s)[%s*%1d]"
409 : " (%s),%#0x(%s)"),
410 REGISTER_NAME (op_1_regno),
411 extra_1,
412 REGISTER_NAME (op_2_regno),
413 REGISTER_NAME (index_reg_regno),
414 index_multiplier);
415 break;
416 case 14:
417 read_memory (memaddr+4, buffer, MAXLEN);
418 insn_size += 4;
419 extra_1 = * ((int *) buffer);
420 read_memory (memaddr+8, buffer, MAXLEN);
421 insn_size += 4;
422 extra_2 = * ((int *) buffer);
423 fprintf_unfiltered (stream,
424 ((index_reg_regno) ? "%#0x(%s),%#0x(%s)[%s*%1d]"
425 : "%#0x(%s),%#0x(%s) "),
426 extra_1,
427 REGISTER_NAME (op_1_regno),
428 extra_2,
429 REGISTER_NAME (op_2_regno),
430 REGISTER_NAME (index_reg_regno),
431 index_multiplier);
432 break;
433
434 default:
435 fprintf_unfiltered (stream,
436 ((index_reg_regno) ? "%s,%s [%s*%1d]" : "%s,%s"),
437 REGISTER_NAME (op_1_regno),
438 REGISTER_NAME (op_2_regno),
439 REGISTER_NAME (index_reg_regno),
440 index_multiplier);
441 fprintf_unfiltered (stream,
442 "\t\t# unknown mode in %08x",
443 insn);
444 break;
445 } /* switch */
446 }
447
448 {
449 return insn_size;
450 }
451 abort ();
452 }