(all-cfg.text): @set SPARCLET.
[deliverable/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",
dd3b648e
RP
34 reg_names[regno], reg_buf[regno],
35 reg_names[regno+16], reg_buf[regno+16],
36 reg_names[regno+32], reg_buf[regno+32],
37 reg_names[regno+48], reg_buf[regno+48]);
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",
dd3b648e
RP
46 reg_names[CSP_REGNUM],reg_buf[CSP_REGNUM],
47 reg_names[KSP_REGNUM], reg_buf[KSP_REGNUM], ksp,
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
73 fputs_filtered (reg_names[i], stdout);
74 printf_filtered(":");
75 print_spaces_filtered (6 - strlen (reg_names[i]), stdout);
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
199b2450 92 fprintf_unfiltered (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,
95 reg_names[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
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
199b2450 118 fprintf_unfiltered (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,
121 reg_names[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}
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;
187 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 reg_names [op_1_regno],
269 reg_names [op_2_regno]);
270 break;
271
272 case 1:
273 fprintf_unfiltered (stream, " 0x%0x,%s",
274 op_1_regno,
275 reg_names [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 reg_names [op_2_regno]);
285 break;
286 case 3:
287 fprintf_unfiltered (stream, " (%s),%s",
288 reg_names [op_1_regno],
289 reg_names [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 reg_names [op_1_regno],
299 reg_names [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 reg_names [op_1_regno],
307 reg_names [op_2_regno],
308 reg_names [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 reg_names [op_2_regno],
318 reg_names [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 reg_names [op_2_regno],
331 reg_names [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 reg_names [op_1_regno],
339 reg_names [op_2_regno],
340 reg_names [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 reg_names [op_1_regno],
354 reg_names [op_2_regno],
355 reg_names [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 reg_names [op_1_regno],
367 extra_1,
368 reg_names [op_2_regno],
369 reg_names [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 reg_names [op_2_regno],
382 reg_names [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 reg_names [op_2_regno],
398 reg_names [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 reg_names [op_1_regno],
411 extra_1,
412 reg_names [op_2_regno],
413 reg_names [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 reg_names [op_1_regno],
428 extra_2,
429 reg_names [op_2_regno],
430 reg_names [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 reg_names [op_1_regno],
438 reg_names [op_2_regno],
439 reg_names [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}
This page took 0.268888 seconds and 4 git commands to generate.