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