]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/pyr-tdep.c
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[thirdparty/binutils-gdb.git] / gdb / pyr-tdep.c
CommitLineData
e3af0493
JG
1/* Pyramid target-dependent code for GDB.
2 Copyright (C) 1988, 1989, 1991 Free Software Foundation, Inc.
dd3b648e
RP
3
4This file is part of GDB.
5
99a7de40 6This program is free software; you can redistribute it and/or modify
dd3b648e 7it under the terms of the GNU General Public License as published by
99a7de40
JG
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
dd3b648e 10
99a7de40 11This program is distributed in the hope that it will be useful,
dd3b648e
RP
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
99a7de40 17along with this program; if not, write to the Free Software
6c9638b4 18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
dd3b648e 19
e3af0493
JG
20#include "defs.h"
21
dd3b648e
RP
22/*** Prettier register printing. ***/
23
24/* Print registers in the same format as pyramid's dbx, adb, sdb. */
25pyr_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++) {
199b2450 33 printf_unfiltered/*_filtered*/ ("%6.6s: %8x %6.6s: %8x %6s: %8x %6s: %8x\n",
d70a61e7
AC
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]);
dd3b648e
RP
38 }
39 usp = ptrace (3, inferior_pid,
e676a15f
FF
40 (PTRACE_ARG3_TYPE) ((char *)&u.u_pcb.pcb_usp) -
41 ((char *)&u), 0);
dd3b648e 42 ksp = ptrace (3, inferior_pid,
e676a15f
FF
43 (PTRACE_ARG3_TYPE) ((char *)&u.u_pcb.pcb_ksp) -
44 ((char *)&u), 0);
199b2450 45 printf_unfiltered/*_filtered*/ ("\n%6.6s: %8x %6.6s: %8x (%08x) %6.6s %8x\n",
d70a61e7
AC
46 REGISTER_NAME (CSP_REGNUM),reg_buf[CSP_REGNUM],
47 REGISTER_NAME (KSP_REGNUM), reg_buf[KSP_REGNUM], ksp,
dd3b648e
RP
48 "usp", usp);
49}
50
361bf6ee
JG
51/* Print the register regnum, or all registers if regnum is -1.
52 fpregs is currently ignored. */
dd3b648e 53
361bf6ee 54pyr_do_registers_info (regnum, fpregs)
dd3b648e 55 int regnum;
361bf6ee 56 int fpregs;
dd3b648e
RP
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
65b07ddc 73 fputs_filtered (REGISTER_NAME (i), gdb_stdout);
dd3b648e 74 printf_filtered(":");
65b07ddc 75 print_spaces_filtered (6 - strlen (REGISTER_NAME (i)), gdb_stdout);
dd3b648e
RP
76 if (val == 0)
77 printf_filtered ("0");
78 else
e3af0493 79 printf_filtered ("%s %d", local_hex_string_custom(val,"08"), val);
dd3b648e
RP
80 printf_filtered("\n");
81 }
82}
83\f
84/*** Debugging editions of various macros from m-pyr.h ****/
85
86CORE_ADDR frame_locals_address (frame)
669caa9c 87 struct frame_info *frame;
dd3b648e
RP
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
65b07ddc 92 fprintf_unfiltered (gdb_stderr,
dd3b648e
RP
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,
d70a61e7 95 REGISTER_NAME (CFP_REGNUM),
dd3b648e
RP
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
111CORE_ADDR frame_args_addr (frame)
669caa9c 112 struct frame_info *frame;
dd3b648e
RP
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
65b07ddc 118 fprintf_unfiltered (gdb_stderr,
dd3b648e
RP
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,
d70a61e7 121 REGISTER_NAME (CFP_REGNUM),
dd3b648e
RP
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}
18b46e7c
SS
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
149extern unsigned pyr_saved_pc(), pyr_frame_chain();
150
151CORE_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
159CORE_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
184int
185pyr_print_insn (memaddr, stream)
186 CORE_ADDR memaddr;
65b07ddc 187 GDB_FILE *stream;
18b46e7c
SS
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",
d70a61e7
AC
268 REGISTER_NAME (op_1_regno),
269 REGISTER_NAME (op_2_regno));
18b46e7c
SS
270 break;
271
272 case 1:
273 fprintf_unfiltered (stream, " 0x%0x,%s",
274 op_1_regno,
d70a61e7 275 REGISTER_NAME (op_2_regno));
18b46e7c
SS
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,
d70a61e7 284 REGISTER_NAME (op_2_regno));
18b46e7c
SS
285 break;
286 case 3:
287 fprintf_unfiltered (stream, " (%s),%s",
d70a61e7
AC
288 REGISTER_NAME (op_1_regno),
289 REGISTER_NAME (op_2_regno));
18b46e7c
SS
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,
d70a61e7
AC
298 REGISTER_NAME (op_1_regno),
299 REGISTER_NAME (op_2_regno));
18b46e7c
SS
300 break;
301
302 /* S1 destination mode */
303 case 5:
304 fprintf_unfiltered (stream,
305 ((index_reg_regno) ? "%s,(%s)[%s*%1d]" : "%s,(%s)"),
d70a61e7
AC
306 REGISTER_NAME (op_1_regno),
307 REGISTER_NAME (op_2_regno),
308 REGISTER_NAME (index_reg_regno),
18b46e7c
SS
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,
d70a61e7
AC
317 REGISTER_NAME (op_2_regno),
318 REGISTER_NAME (index_reg_regno),
18b46e7c
SS
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,
d70a61e7
AC
330 REGISTER_NAME (op_2_regno),
331 REGISTER_NAME (index_reg_regno),
18b46e7c
SS
332 index_multiplier);
333 break;
334
335 case 8:
336 fprintf_unfiltered (stream,
337 ((index_reg_regno) ? " (%s),(%s)[%s*%1d]" : " (%s),(%s)"),
d70a61e7
AC
338 REGISTER_NAME (op_1_regno),
339 REGISTER_NAME (op_2_regno),
340 REGISTER_NAME (index_reg_regno),
18b46e7c
SS
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,
d70a61e7
AC
353 REGISTER_NAME (op_1_regno),
354 REGISTER_NAME (op_2_regno),
355 REGISTER_NAME (index_reg_regno),
18b46e7c
SS
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)"),
d70a61e7 366 REGISTER_NAME (op_1_regno),
18b46e7c 367 extra_1,
d70a61e7
AC
368 REGISTER_NAME (op_2_regno),
369 REGISTER_NAME (index_reg_regno),
18b46e7c
SS
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,
d70a61e7
AC
381 REGISTER_NAME (op_2_regno),
382 REGISTER_NAME (index_reg_regno),
18b46e7c
SS
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,
d70a61e7
AC
397 REGISTER_NAME (op_2_regno),
398 REGISTER_NAME (index_reg_regno),
18b46e7c
SS
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)"),
d70a61e7 410 REGISTER_NAME (op_1_regno),
18b46e7c 411 extra_1,
d70a61e7
AC
412 REGISTER_NAME (op_2_regno),
413 REGISTER_NAME (index_reg_regno),
18b46e7c
SS
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,
d70a61e7 427 REGISTER_NAME (op_1_regno),
18b46e7c 428 extra_2,
d70a61e7
AC
429 REGISTER_NAME (op_2_regno),
430 REGISTER_NAME (index_reg_regno),
18b46e7c
SS
431 index_multiplier);
432 break;
433
434 default:
435 fprintf_unfiltered (stream,
436 ((index_reg_regno) ? "%s,%s [%s*%1d]" : "%s,%s"),
d70a61e7
AC
437 REGISTER_NAME (op_1_regno),
438 REGISTER_NAME (op_2_regno),
439 REGISTER_NAME (index_reg_regno),
18b46e7c
SS
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}