* corelow.c, exec.c, inftarg.c, m3-nat.c, op50-rom.c, procfs.c,
[deliverable/binutils-gdb.git] / gdb / pyr-pinsn.c
CommitLineData
7d9884b9 1/* Print Pyramid Technology 90x instructions for GDB, the GNU Debugger.
609f87d4 2 Copyright 1988, 1989, 1991, 1992 Free Software Foundation, Inc.
dd3b648e 3
609f87d4 4This file is part of GDB, the GNU debugger.
dd3b648e 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
JG
17along with this program; if not, write to the Free Software
18Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
dd3b648e 19
dd3b648e 20#include "defs.h"
dd3b648e 21#include "symtab.h"
aab77d5f 22#include "opcode/pyr.h"
dd3b648e
RP
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
7d9884b9
JG
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
dd3b648e
RP
32 when these functions are used makes the gdb unusable as a
33 debugger for user programs. */
34
35extern unsigned pyr_saved_pc(), pyr_frame_chain();
36
37CORE_ADDR pyr_frame_chain(frame)
38 CORE_ADDR frame;
39{
40 int foo=frame - CONTROL_STACK_FRAME_SIZE;
199b2450 41 /* printf_unfiltered ("...following chain from %x: got %x\n", frame, foo);*/
dd3b648e
RP
42 return foo;
43}
44
45CORE_ADDR pyr_saved_pc(frame)
46 CORE_ADDR frame;
47{
48 int foo=0;
49 foo = read_memory_integer (((CORE_ADDR)(frame))+60, 4);
199b2450 50 printf_unfiltered ("..reading pc from frame 0x%0x+%d regs: got %0x\n",
dd3b648e
RP
51 frame, 60/4, foo);
52 return foo;
53}
dd3b648e
RP
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
609f87d4 62/* Let's be byte-independent so we can use this as a cross-assembler. */
dd3b648e
RP
63
64#define NEXTLONG(p) \
65 (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])
dd3b648e
RP
66\f
67/* Print one instruction at address MEMADDR in debugged memory,
68 on STREAM. Returns length of the instruction, in bytes. */
69
70int
71print_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 */
199b2450 99 fprintf_unfiltered (stream, "halt");
dd3b648e
RP
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. */
199b2450 109 fprintf_unfiltered (stream, "???\t#%08x\t(op=%x mode =%x)",
dd3b648e
RP
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
199b2450 125 fprintf_unfiltered (stream, "%s\t", pyr_opcodes[i].name);
dd3b648e
RP
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)
199b2450 142 fputc_unfiltered (cc_bit_names[i], stream);
dd3b648e
RP
143 bit_codes >>= 1;
144 }
145
199b2450 146 fprintf_unfiltered (stream, ",%0x",
dd3b648e
RP
147 displacement + memaddr);
148 return (insn_size);
149 }
150
151 switch (operand_mode) {
152 case 0:
199b2450 153 fprintf_unfiltered (stream, "%s,%s",
dd3b648e
RP
154 reg_names [op_1_regno],
155 reg_names [op_2_regno]);
156 break;
157
158 case 1:
199b2450 159 fprintf_unfiltered (stream, " 0x%0x,%s",
dd3b648e
RP
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);
199b2450 168 fprintf_unfiltered (stream, " $0x%0x,%s",
dd3b648e
RP
169 extra_1,
170 reg_names [op_2_regno]);
171 break;
172 case 3:
199b2450 173 fprintf_unfiltered (stream, " (%s),%s",
dd3b648e
RP
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);
199b2450 182 fprintf_unfiltered (stream, " 0x%0x(%s),%s",
dd3b648e
RP
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:
199b2450 190 fprintf_unfiltered (stream,
dd3b648e
RP
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:
199b2450 199 fprintf_unfiltered (stream,
dd3b648e
RP
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);
199b2450 212 fprintf_unfiltered (stream,
dd3b648e
RP
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:
199b2450 222 fprintf_unfiltered (stream,
dd3b648e
RP
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);
199b2450 234 fprintf_unfiltered (stream,
dd3b648e
RP
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);
199b2450 250 fprintf_unfiltered (stream,
dd3b648e
RP
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);
199b2450 262 fprintf_unfiltered (stream,
dd3b648e
RP
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);
199b2450 278 fprintf_unfiltered (stream,
dd3b648e
RP
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);
199b2450 292 fprintf_unfiltered (stream,
dd3b648e
RP
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);
199b2450 309 fprintf_unfiltered (stream,
dd3b648e
RP
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:
199b2450 321 fprintf_unfiltered (stream,
dd3b648e
RP
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);
199b2450 327 fprintf_unfiltered (stream,
dd3b648e
RP
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.19968 seconds and 4 git commands to generate.