1 /* Print Pyramid Technology 90x instructions for GDB, the GNU Debugger.
2 Copyright 1988, 1989, 1991 Free Software Foundation, Inc.
4 This file is part of GDB, the GNU disassembler.
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 ("...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 ("..reading pc from frame 0x%0x+%d regs: got %0x\n",
56 /* Pyramid instructions are never longer than this many bytes. */
59 /* Number of elements in the opcode table. */
60 /*const*/ static int nopcodes
= (sizeof (pyr_opcodes
) / sizeof( pyr_opcodes
[0]));
61 #define NOPCODES (nopcodes)
63 extern char *reg_names
[];
65 /* Let's be byte-independent so we can use this as a cross-assembler.
66 (will this ever be useful?
70 (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])
73 /* Print one instruction at address MEMADDR in debugged memory,
74 on STREAM. Returns length of the instruction, in bytes. */
77 print_insn (memaddr
, stream
)
81 unsigned char buffer
[MAXLEN
];
82 register int i
, nargs
, insn_size
=4;
83 register unsigned char *p
;
85 register int insn_opcode
, operand_mode
;
86 register int index_multiplier
, index_reg_regno
, op_1_regno
, op_2_regno
;
87 long insn
; /* first word of the insn, not broken down. */
88 pyr_insn_format insn_decode
; /* the same, broken out into op{code,erands} */
89 long extra_1
, extra_2
;
91 read_memory (memaddr
, buffer
, MAXLEN
);
92 insn_decode
= *((pyr_insn_format
*) buffer
);
93 insn
= * ((int *) buffer
);
94 insn_opcode
= insn_decode
.operator;
95 operand_mode
= insn_decode
.mode
;
96 index_multiplier
= insn_decode
.index_scale
;
97 index_reg_regno
= insn_decode
.index_reg
;
98 op_1_regno
= insn_decode
.operand_1
;
99 op_2_regno
= insn_decode
.operand_2
;
102 if (*((int *)buffer
) == 0x0) {
103 /* "halt" looks just like an invalid "jump" to the insn decoder,
104 so is dealt with as a special case */
105 fprintf (stream
, "halt");
109 for (i
= 0; i
< NOPCODES
; i
++)
110 if (pyr_opcodes
[i
].datum
.code
== insn_opcode
)
114 /* FIXME: Handle unrecognised instructions better. */
115 fprintf (stream
, "???\t#%08x\t(op=%x mode =%x)",
116 insn
, insn_decode
.operator, insn_decode
.mode
);
119 /* Print the mnemonic for the instruction. Pyramid insn operands
120 are so regular that we can deal with almost all of them
122 Unconditional branches are an exception: they are encoded as
123 conditional branches (branch if false condition, I think)
124 with no condition specified. The average user will not be
125 aware of this. To maintain their illusion that an
126 unconditional branch insn exists, we will have to FIXME to
127 treat the insn mnemnonic of all branch instructions here as a
128 special case: check the operands of branch insn and print an
129 appropriate mnemonic. */
131 fprintf (stream
, "%s\t", pyr_opcodes
[i
].name
);
133 /* Print the operands of the insn (as specified in
135 Branch operands of branches are a special case: they are a word
136 offset, not a byte offset. */
138 if (insn_decode
.operator == 0x01 || insn_decode
.operator == 0x02) {
139 register int bit_codes
=(insn
>> 16)&0xf;
141 register int displacement
= (insn
& 0x0000ffff) << 2;
143 static char cc_bit_names
[] = "cvzn"; /* z,n,c,v: strange order? */
145 /* Is bfc and no bits specified an unconditional branch?*/
147 if ((bit_codes
) & 0x1)
148 fputc (cc_bit_names
[i
], stream
);
152 fprintf (stream
, ",%0x",
153 displacement
+ memaddr
);
157 switch (operand_mode
) {
159 fprintf (stream
, "%s,%s",
160 reg_names
[op_1_regno
],
161 reg_names
[op_2_regno
]);
165 fprintf (stream
, " 0x%0x,%s",
167 reg_names
[op_2_regno
]);
171 read_memory (memaddr
+4, buffer
, MAXLEN
);
173 extra_1
= * ((int *) buffer
);
174 fprintf (stream
, " $0x%0x,%s",
176 reg_names
[op_2_regno
]);
179 fprintf (stream
, " (%s),%s",
180 reg_names
[op_1_regno
],
181 reg_names
[op_2_regno
]);
185 read_memory (memaddr
+4, buffer
, MAXLEN
);
187 extra_1
= * ((int *) buffer
);
188 fprintf (stream
, " 0x%0x(%s),%s",
190 reg_names
[op_1_regno
],
191 reg_names
[op_2_regno
]);
194 /* S1 destination mode */
197 ((index_reg_regno
) ? "%s,(%s)[%s*%1d]" : "%s,(%s)"),
198 reg_names
[op_1_regno
],
199 reg_names
[op_2_regno
],
200 reg_names
[index_reg_regno
],
206 ((index_reg_regno
) ? " $%#0x,(%s)[%s*%1d]"
209 reg_names
[op_2_regno
],
210 reg_names
[index_reg_regno
],
215 read_memory (memaddr
+4, buffer
, MAXLEN
);
217 extra_1
= * ((int *) buffer
);
219 ((index_reg_regno
) ? " $%#0x,(%s)[%s*%1d]"
222 reg_names
[op_2_regno
],
223 reg_names
[index_reg_regno
],
229 ((index_reg_regno
) ? " (%s),(%s)[%s*%1d]" : " (%s),(%s)"),
230 reg_names
[op_1_regno
],
231 reg_names
[op_2_regno
],
232 reg_names
[index_reg_regno
],
237 read_memory (memaddr
+4, buffer
, MAXLEN
);
239 extra_1
= * ((int *) buffer
);
242 ? "%#0x(%s),(%s)[%s*%1d]"
245 reg_names
[op_1_regno
],
246 reg_names
[op_2_regno
],
247 reg_names
[index_reg_regno
],
251 /* S2 destination mode */
253 read_memory (memaddr
+4, buffer
, MAXLEN
);
255 extra_1
= * ((int *) buffer
);
257 ((index_reg_regno
) ? "%s,%#0x(%s)[%s*%1d]" : "%s,%#0x(%s)"),
258 reg_names
[op_1_regno
],
260 reg_names
[op_2_regno
],
261 reg_names
[index_reg_regno
],
265 read_memory (memaddr
+4, buffer
, MAXLEN
);
267 extra_1
= * ((int *) buffer
);
270 " $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
273 reg_names
[op_2_regno
],
274 reg_names
[index_reg_regno
],
278 read_memory (memaddr
+4, buffer
, MAXLEN
);
280 extra_1
= * ((int *) buffer
);
281 read_memory (memaddr
+8, buffer
, MAXLEN
);
283 extra_2
= * ((int *) buffer
);
286 " $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
289 reg_names
[op_2_regno
],
290 reg_names
[index_reg_regno
],
295 read_memory (memaddr
+4, buffer
, MAXLEN
);
297 extra_1
= * ((int *) buffer
);
300 ? " (%s),%#0x(%s)[%s*%1d]"
302 reg_names
[op_1_regno
],
304 reg_names
[op_2_regno
],
305 reg_names
[index_reg_regno
],
309 read_memory (memaddr
+4, buffer
, MAXLEN
);
311 extra_1
= * ((int *) buffer
);
312 read_memory (memaddr
+8, buffer
, MAXLEN
);
314 extra_2
= * ((int *) buffer
);
316 ((index_reg_regno
) ? "%#0x(%s),%#0x(%s)[%s*%1d]"
317 : "%#0x(%s),%#0x(%s) "),
319 reg_names
[op_1_regno
],
321 reg_names
[op_2_regno
],
322 reg_names
[index_reg_regno
],
328 ((index_reg_regno
) ? "%s,%s [%s*%1d]" : "%s,%s"),
329 reg_names
[op_1_regno
],
330 reg_names
[op_2_regno
],
331 reg_names
[index_reg_regno
],
334 "\t\t# unknown mode in %08x",