* hppa-tdep.c (hppa_frame_find_saved_regs): Change "frame" to
[deliverable/binutils-gdb.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.247142 seconds and 4 git commands to generate.