]> Git Repo - binutils.git/blob - gdb/pyr-pinsn.c
* elfcode.h (elf_bfd_final_link): If trying to generate a shared
[binutils.git] / gdb / pyr-pinsn.c
1 /* Print Pyramid Technology 90x instructions for GDB, the GNU Debugger.
2    Copyright 1988, 1989, 1991, 1992 Free Software Foundation, Inc.
3
4 This file is part of GDB, the GNU debugger.
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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 #include "defs.h"
21 #include "symtab.h"
22 #include "opcode/pyr.h"
23 #include "gdbcore.h"
24
25 \f
26 /*  A couple of functions used for debugging frame-handling on
27     Pyramids. (The Pyramid-dependent handling of register values for
28     windowed registers is known to be buggy.)
29
30     When debugging, these functions can supplant the normal definitions of some
31     of the macros in tm-pyramid.h  The quantity of information produced
32     when these functions are used makes the gdb  unusable as a
33     debugger for user programs.  */
34     
35 extern unsigned pyr_saved_pc(), pyr_frame_chain();
36
37 CORE_ADDR pyr_frame_chain(frame)
38     CORE_ADDR frame;
39 {
40     int foo=frame - CONTROL_STACK_FRAME_SIZE;
41     /* printf_unfiltered ("...following chain from %x: got %x\n", frame, foo);*/
42     return foo;
43 }
44
45 CORE_ADDR pyr_saved_pc(frame)
46     CORE_ADDR frame;
47 {
48     int foo=0;
49     foo = read_memory_integer (((CORE_ADDR)(frame))+60, 4);
50     printf_unfiltered ("..reading pc from frame 0x%0x+%d regs: got %0x\n",
51             frame, 60/4, foo);
52     return foo;
53 }
54
55 /* Pyramid instructions are never longer than this many bytes.  */
56 #define MAXLEN 24
57
58 /* Number of elements in the opcode table.  */
59 /*const*/ static int nopcodes = (sizeof (pyr_opcodes) / sizeof( pyr_opcodes[0]));
60 #define NOPCODES (nopcodes)
61
62 /* Let's be byte-independent so we can use this as a cross-assembler.  */
63
64 #define NEXTLONG(p)  \
65   (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])
66 \f
67 /* Print one instruction at address MEMADDR in debugged memory,
68    on STREAM.  Returns length of the instruction, in bytes.  */
69
70 int
71 print_insn (memaddr, stream)
72      CORE_ADDR memaddr;
73      FILE *stream;
74 {
75   unsigned char buffer[MAXLEN];
76   register int i, nargs, insn_size =4;
77   register unsigned char *p;
78   register char *d;
79   register int insn_opcode, operand_mode;
80   register int index_multiplier, index_reg_regno, op_1_regno, op_2_regno ;
81   long insn;                    /* first word of the insn, not broken down. */
82   pyr_insn_format insn_decode;  /* the same, broken out into op{code,erands} */
83   long extra_1, extra_2;
84
85   read_memory (memaddr, buffer, MAXLEN);
86   insn_decode = *((pyr_insn_format *) buffer);
87   insn = * ((int *) buffer);
88   insn_opcode = insn_decode.operator;
89   operand_mode = insn_decode.mode;
90   index_multiplier = insn_decode.index_scale;
91   index_reg_regno = insn_decode.index_reg;
92   op_1_regno = insn_decode.operand_1;
93   op_2_regno = insn_decode.operand_2;
94   
95   
96   if (*((int *)buffer) == 0x0) {
97     /* "halt" looks just like an invalid "jump" to the insn decoder,
98        so is dealt with as a special case */
99     fprintf_unfiltered (stream, "halt");
100     return (4);
101   }
102
103   for (i = 0; i < NOPCODES; i++)
104           if (pyr_opcodes[i].datum.code == insn_opcode)
105                   break;
106
107   if (i == NOPCODES)
108           /* FIXME: Handle unrecognised instructions better.  */
109           fprintf_unfiltered (stream, "???\t#%08x\t(op=%x mode =%x)",
110                    insn, insn_decode.operator, insn_decode.mode);
111   else
112     {
113       /* Print the mnemonic for the instruction.  Pyramid insn operands
114          are so regular that we can deal with almost all of them
115          separately.
116          Unconditional branches are an exception: they are encoded as
117          conditional branches (branch if false condition, I think)
118          with no condition specified. The average user will not be
119          aware of this. To maintain their illusion that an
120          unconditional branch insn exists, we will have to FIXME to
121          treat the insn mnemnonic of all branch instructions here as a
122          special case: check the operands of branch insn and print an
123          appropriate mnemonic. */ 
124
125       fprintf_unfiltered (stream, "%s\t", pyr_opcodes[i].name);
126
127     /* Print the operands of the insn (as specified in
128        insn.operand_mode). 
129        Branch operands of branches are a special case: they are a word
130        offset, not a byte offset. */
131   
132     if (insn_decode.operator == 0x01 || insn_decode.operator == 0x02) {
133       register int bit_codes=(insn >> 16)&0xf;
134       register int i;
135       register int displacement = (insn & 0x0000ffff) << 2;
136
137       static char cc_bit_names[] = "cvzn";      /* z,n,c,v: strange order? */
138
139       /* Is bfc and no bits specified an unconditional branch?*/
140       for (i=0;i<4;i++) {
141         if ((bit_codes) & 0x1)
142                 fputc_unfiltered (cc_bit_names[i], stream);
143         bit_codes >>= 1;
144       }
145
146       fprintf_unfiltered (stream, ",%0x",
147                displacement + memaddr);
148       return (insn_size);
149     }
150
151       switch (operand_mode) {
152       case 0:
153         fprintf_unfiltered (stream, "%s,%s",
154                  reg_names [op_1_regno],
155                  reg_names [op_2_regno]);
156         break;
157             
158       case 1:
159         fprintf_unfiltered (stream, " 0x%0x,%s",
160                  op_1_regno,
161                  reg_names [op_2_regno]);
162         break;
163         
164       case 2:
165         read_memory (memaddr+4, buffer, MAXLEN);
166         insn_size += 4;
167         extra_1 = * ((int *) buffer);
168         fprintf_unfiltered (stream, " $0x%0x,%s",
169                  extra_1,
170                  reg_names [op_2_regno]);
171         break;
172       case 3:
173         fprintf_unfiltered (stream, " (%s),%s",
174                  reg_names [op_1_regno],
175                  reg_names [op_2_regno]);
176         break;
177         
178       case 4:
179         read_memory (memaddr+4, buffer, MAXLEN);
180         insn_size += 4;
181         extra_1 = * ((int *) buffer);
182         fprintf_unfiltered (stream, " 0x%0x(%s),%s",
183                  extra_1,
184                  reg_names [op_1_regno],
185                  reg_names [op_2_regno]);
186         break;
187         
188         /* S1 destination mode */
189       case 5:
190         fprintf_unfiltered (stream,
191                  ((index_reg_regno) ? "%s,(%s)[%s*%1d]" : "%s,(%s)"),
192                  reg_names [op_1_regno],
193                  reg_names [op_2_regno],
194                  reg_names [index_reg_regno],
195                  index_multiplier);
196         break;
197         
198       case 6:
199         fprintf_unfiltered (stream,
200                  ((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]"
201                   : " $%#0x,(%s)"),
202                  op_1_regno,
203                  reg_names [op_2_regno],
204                  reg_names [index_reg_regno],
205                  index_multiplier);
206         break;
207         
208       case 7:
209         read_memory (memaddr+4, buffer, MAXLEN);
210         insn_size += 4;
211         extra_1 = * ((int *) buffer);
212         fprintf_unfiltered (stream,
213                  ((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]"
214                   : " $%#0x,(%s)"),
215                  extra_1,
216                  reg_names [op_2_regno],
217                  reg_names [index_reg_regno],
218                  index_multiplier);
219         break;
220         
221       case 8:
222         fprintf_unfiltered (stream,
223                  ((index_reg_regno) ? " (%s),(%s)[%s*%1d]" : " (%s),(%s)"),
224                  reg_names [op_1_regno],
225                  reg_names [op_2_regno],
226                  reg_names [index_reg_regno],
227                  index_multiplier);
228         break;
229         
230       case 9:
231         read_memory (memaddr+4, buffer, MAXLEN);
232         insn_size += 4;
233         extra_1 = * ((int *) buffer);
234         fprintf_unfiltered (stream,
235                  ((index_reg_regno)
236                   ? "%#0x(%s),(%s)[%s*%1d]"
237                   : "%#0x(%s),(%s)"),
238                  extra_1,
239                  reg_names [op_1_regno],
240                  reg_names [op_2_regno],
241                  reg_names [index_reg_regno],
242                  index_multiplier);
243         break;
244         
245         /* S2 destination mode */
246       case 10:
247         read_memory (memaddr+4, buffer, MAXLEN);
248         insn_size += 4;
249         extra_1 = * ((int *) buffer);
250         fprintf_unfiltered (stream,
251                  ((index_reg_regno) ? "%s,%#0x(%s)[%s*%1d]" : "%s,%#0x(%s)"),
252                  reg_names [op_1_regno],
253                  extra_1,
254                  reg_names [op_2_regno],
255                  reg_names [index_reg_regno],
256                  index_multiplier);
257         break;
258       case 11:
259         read_memory (memaddr+4, buffer, MAXLEN);
260         insn_size += 4;
261         extra_1 = * ((int *) buffer);
262         fprintf_unfiltered (stream,
263                  ((index_reg_regno) ?
264                   " $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
265                  op_1_regno,
266                  extra_1,
267                  reg_names [op_2_regno],
268                  reg_names [index_reg_regno],
269                  index_multiplier);
270         break;
271       case 12:
272         read_memory (memaddr+4, buffer, MAXLEN);
273         insn_size += 4;
274         extra_1 = * ((int *) buffer);
275         read_memory (memaddr+8, buffer, MAXLEN);
276         insn_size += 4;
277         extra_2 = * ((int *) buffer);
278         fprintf_unfiltered (stream,
279                  ((index_reg_regno) ?
280                   " $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
281                  extra_1,
282                  extra_2,
283                  reg_names [op_2_regno],
284                  reg_names [index_reg_regno],
285                  index_multiplier);
286         break;
287         
288       case 13:
289         read_memory (memaddr+4, buffer, MAXLEN);
290         insn_size += 4;
291         extra_1 = * ((int *) buffer);
292         fprintf_unfiltered (stream,
293                  ((index_reg_regno)
294                   ? " (%s),%#0x(%s)[%s*%1d]" 
295                   : " (%s),%#0x(%s)"),
296                  reg_names [op_1_regno],
297                  extra_1,
298                  reg_names [op_2_regno],
299                  reg_names [index_reg_regno],
300                  index_multiplier);
301         break;
302       case 14:
303         read_memory (memaddr+4, buffer, MAXLEN);
304         insn_size += 4;
305         extra_1 = * ((int *) buffer);
306         read_memory (memaddr+8, buffer, MAXLEN);
307         insn_size += 4;
308         extra_2 = * ((int *) buffer);
309         fprintf_unfiltered (stream,
310                  ((index_reg_regno) ? "%#0x(%s),%#0x(%s)[%s*%1d]"
311                   : "%#0x(%s),%#0x(%s) "),
312                  extra_1,
313                  reg_names [op_1_regno],
314                  extra_2,
315                  reg_names [op_2_regno],
316                  reg_names [index_reg_regno],
317                  index_multiplier);
318         break;
319         
320       default:
321         fprintf_unfiltered (stream,
322                  ((index_reg_regno) ? "%s,%s [%s*%1d]" : "%s,%s"),
323                  reg_names [op_1_regno],
324                  reg_names [op_2_regno],
325                  reg_names [index_reg_regno],
326                  index_multiplier);
327         fprintf_unfiltered (stream,
328                  "\t\t# unknown mode in %08x",
329                  insn);
330         break;
331       } /* switch */
332     }
333   
334   {
335     return insn_size;
336   }
337   abort ();
338 }
This page took 0.049064 seconds and 4 git commands to generate.