This commit was generated by cvs2svn to track changes on a CVS vendor
[external/binutils.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                      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,
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                    reg_names[CSP_REGNUM],reg_buf[CSP_REGNUM],
47                    reg_names[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 (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
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 (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            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
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 (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            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 }
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      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 }