1 /* Print Pyramid Technology 90x instructions for GDB, the GNU Debugger.
2 Copyright 1988, 1989, 1991, 1992 Free Software Foundation, Inc.
4 This file is part of GDB, the GNU debugger.
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.
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.
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. */
22 #include "opcode/pyr.h"
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.)
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. */
35 extern unsigned pyr_saved_pc(), pyr_frame_chain();
37 CORE_ADDR pyr_frame_chain(frame)
40 int foo=frame - CONTROL_STACK_FRAME_SIZE;
41 /* printf_unfiltered ("...following chain from %x: got %x\n", frame, foo);*/
45 CORE_ADDR pyr_saved_pc(frame)
49 foo = read_memory_integer (((CORE_ADDR)(frame))+60, 4);
50 printf_unfiltered ("..reading pc from frame 0x%0x+%d regs: got %0x\n",
55 /* Pyramid instructions are never longer than this many bytes. */
58 /* Number of elements in the opcode table. */
59 /*const*/ static int nopcodes = (sizeof (pyr_opcodes) / sizeof( pyr_opcodes[0]));
60 #define NOPCODES (nopcodes)
62 /* Let's be byte-independent so we can use this as a cross-assembler. */
65 (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])
67 /* Print one instruction at address MEMADDR in debugged memory,
68 on STREAM. Returns length of the instruction, in bytes. */
71 print_insn (memaddr, stream)
75 unsigned char buffer[MAXLEN];
76 register int i, nargs, insn_size =4;
77 register unsigned char *p;
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;
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;
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");
103 for (i = 0; i < NOPCODES; i++)
104 if (pyr_opcodes[i].datum.code == insn_opcode)
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);
113 /* Print the mnemonic for the instruction. Pyramid insn operands
114 are so regular that we can deal with almost all of them
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. */
125 fprintf_unfiltered (stream, "%s\t", pyr_opcodes[i].name);
127 /* Print the operands of the insn (as specified in
129 Branch operands of branches are a special case: they are a word
130 offset, not a byte offset. */
132 if (insn_decode.operator == 0x01 || insn_decode.operator == 0x02) {
133 register int bit_codes=(insn >> 16)&0xf;
135 register int displacement = (insn & 0x0000ffff) << 2;
137 static char cc_bit_names[] = "cvzn"; /* z,n,c,v: strange order? */
139 /* Is bfc and no bits specified an unconditional branch?*/
141 if ((bit_codes) & 0x1)
142 fputc_unfiltered (cc_bit_names[i], stream);
146 fprintf_unfiltered (stream, ",%0x",
147 displacement + memaddr);
151 switch (operand_mode) {
153 fprintf_unfiltered (stream, "%s,%s",
154 reg_names [op_1_regno],
155 reg_names [op_2_regno]);
159 fprintf_unfiltered (stream, " 0x%0x,%s",
161 reg_names [op_2_regno]);
165 read_memory (memaddr+4, buffer, MAXLEN);
167 extra_1 = * ((int *) buffer);
168 fprintf_unfiltered (stream, " $0x%0x,%s",
170 reg_names [op_2_regno]);
173 fprintf_unfiltered (stream, " (%s),%s",
174 reg_names [op_1_regno],
175 reg_names [op_2_regno]);
179 read_memory (memaddr+4, buffer, MAXLEN);
181 extra_1 = * ((int *) buffer);
182 fprintf_unfiltered (stream, " 0x%0x(%s),%s",
184 reg_names [op_1_regno],
185 reg_names [op_2_regno]);
188 /* S1 destination mode */
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],
199 fprintf_unfiltered (stream,
200 ((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]"
203 reg_names [op_2_regno],
204 reg_names [index_reg_regno],
209 read_memory (memaddr+4, buffer, MAXLEN);
211 extra_1 = * ((int *) buffer);
212 fprintf_unfiltered (stream,
213 ((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]"
216 reg_names [op_2_regno],
217 reg_names [index_reg_regno],
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],
231 read_memory (memaddr+4, buffer, MAXLEN);
233 extra_1 = * ((int *) buffer);
234 fprintf_unfiltered (stream,
236 ? "%#0x(%s),(%s)[%s*%1d]"
239 reg_names [op_1_regno],
240 reg_names [op_2_regno],
241 reg_names [index_reg_regno],
245 /* S2 destination mode */
247 read_memory (memaddr+4, buffer, MAXLEN);
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],
254 reg_names [op_2_regno],
255 reg_names [index_reg_regno],
259 read_memory (memaddr+4, buffer, MAXLEN);
261 extra_1 = * ((int *) buffer);
262 fprintf_unfiltered (stream,
264 " $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
267 reg_names [op_2_regno],
268 reg_names [index_reg_regno],
272 read_memory (memaddr+4, buffer, MAXLEN);
274 extra_1 = * ((int *) buffer);
275 read_memory (memaddr+8, buffer, MAXLEN);
277 extra_2 = * ((int *) buffer);
278 fprintf_unfiltered (stream,
280 " $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
283 reg_names [op_2_regno],
284 reg_names [index_reg_regno],
289 read_memory (memaddr+4, buffer, MAXLEN);
291 extra_1 = * ((int *) buffer);
292 fprintf_unfiltered (stream,
294 ? " (%s),%#0x(%s)[%s*%1d]"
296 reg_names [op_1_regno],
298 reg_names [op_2_regno],
299 reg_names [index_reg_regno],
303 read_memory (memaddr+4, buffer, MAXLEN);
305 extra_1 = * ((int *) buffer);
306 read_memory (memaddr+8, buffer, MAXLEN);
308 extra_2 = * ((int *) buffer);
309 fprintf_unfiltered (stream,
310 ((index_reg_regno) ? "%#0x(%s),%#0x(%s)[%s*%1d]"
311 : "%#0x(%s),%#0x(%s) "),
313 reg_names [op_1_regno],
315 reg_names [op_2_regno],
316 reg_names [index_reg_regno],
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],
327 fprintf_unfiltered (stream,
328 "\t\t# unknown mode in %08x",