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. */
24 #include "pyr-opcode.h"
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.)
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. */
37 extern unsigned pyr_saved_pc(), pyr_frame_chain();
39 CORE_ADDR
pyr_frame_chain(frame
)
42 int foo
=frame
- CONTROL_STACK_FRAME_SIZE
;
43 /* printf ("...following chain from %x: got %x\n", frame, foo);*/
47 CORE_ADDR
pyr_saved_pc(frame
)
51 foo
= read_memory_integer (((CORE_ADDR
)(frame
))+60, 4);
52 printf ("..reading pc from frame 0x%0x+%d regs: got %0x\n",
58 /* Pyramid instructions are never longer than this many bytes. */
61 /* Number of elements in the opcode table. */
62 /*const*/ static int nopcodes
= (sizeof (pyr_opcodes
) / sizeof( pyr_opcodes
[0]));
63 #define NOPCODES (nopcodes)
65 extern char *reg_names
[];
67 /* Let's be byte-independent so we can use this as a cross-assembler.
68 (will this ever be useful?
72 (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])
75 /* Print one instruction at address MEMADDR in debugged memory,
76 on STREAM. Returns length of the instruction, in bytes. */
79 print_insn (memaddr
, stream
)
83 unsigned char buffer
[MAXLEN
];
84 register int i
, nargs
, insn_size
=4;
85 register unsigned char *p
;
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
;
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
;
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");
111 for (i
= 0; i
< NOPCODES
; i
++)
112 if (pyr_opcodes
[i
].datum
.code
== insn_opcode
)
116 /* FIXME: Handle unrecognised instructions better. */
117 fprintf (stream
, "???\t#%08x\t(op=%x mode =%x)",
118 insn
, insn_decode
.operator, insn_decode
.mode
);
121 /* Print the mnemonic for the instruction. Pyramid insn operands
122 are so regular that we can deal with almost all of them
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. */
133 fprintf (stream
, "%s\t", pyr_opcodes
[i
].name
);
135 /* Print the operands of the insn (as specified in
137 Branch operands of branches are a special case: they are a word
138 offset, not a byte offset. */
140 if (insn_decode
.operator == 0x01 || insn_decode
.operator == 0x02) {
141 register int bit_codes
=(insn
>> 16)&0xf;
143 register int displacement
= (insn
& 0x0000ffff) << 2;
145 static char cc_bit_names
[] = "cvzn"; /* z,n,c,v: strange order? */
147 /* Is bfc and no bits specified an unconditional branch?*/
149 if ((bit_codes
) & 0x1)
150 fputc (cc_bit_names
[i
], stream
);
154 fprintf (stream
, ",%0x",
155 displacement
+ memaddr
);
159 switch (operand_mode
) {
161 fprintf (stream
, "%s,%s",
162 reg_names
[op_1_regno
],
163 reg_names
[op_2_regno
]);
167 fprintf (stream
, " 0x%0x,%s",
169 reg_names
[op_2_regno
]);
173 read_memory (memaddr
+4, buffer
, MAXLEN
);
175 extra_1
= * ((int *) buffer
);
176 fprintf (stream
, " $0x%0x,%s",
178 reg_names
[op_2_regno
]);
181 fprintf (stream
, " (%s),%s",
182 reg_names
[op_1_regno
],
183 reg_names
[op_2_regno
]);
187 read_memory (memaddr
+4, buffer
, MAXLEN
);
189 extra_1
= * ((int *) buffer
);
190 fprintf (stream
, " 0x%0x(%s),%s",
192 reg_names
[op_1_regno
],
193 reg_names
[op_2_regno
]);
196 /* S1 destination mode */
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
],
208 ((index_reg_regno
) ? " $%#0x,(%s)[%s*%1d]"
211 reg_names
[op_2_regno
],
212 reg_names
[index_reg_regno
],
217 read_memory (memaddr
+4, buffer
, MAXLEN
);
219 extra_1
= * ((int *) buffer
);
221 ((index_reg_regno
) ? " $%#0x,(%s)[%s*%1d]"
224 reg_names
[op_2_regno
],
225 reg_names
[index_reg_regno
],
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
],
239 read_memory (memaddr
+4, buffer
, MAXLEN
);
241 extra_1
= * ((int *) buffer
);
244 ? "%#0x(%s),(%s)[%s*%1d]"
247 reg_names
[op_1_regno
],
248 reg_names
[op_2_regno
],
249 reg_names
[index_reg_regno
],
253 /* S2 destination mode */
255 read_memory (memaddr
+4, buffer
, MAXLEN
);
257 extra_1
= * ((int *) buffer
);
259 ((index_reg_regno
) ? "%s,%#0x(%s)[%s*%1d]" : "%s,%#0x(%s)"),
260 reg_names
[op_1_regno
],
262 reg_names
[op_2_regno
],
263 reg_names
[index_reg_regno
],
267 read_memory (memaddr
+4, buffer
, MAXLEN
);
269 extra_1
= * ((int *) buffer
);
272 " $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
275 reg_names
[op_2_regno
],
276 reg_names
[index_reg_regno
],
280 read_memory (memaddr
+4, buffer
, MAXLEN
);
282 extra_1
= * ((int *) buffer
);
283 read_memory (memaddr
+8, buffer
, MAXLEN
);
285 extra_2
= * ((int *) buffer
);
288 " $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
291 reg_names
[op_2_regno
],
292 reg_names
[index_reg_regno
],
297 read_memory (memaddr
+4, buffer
, MAXLEN
);
299 extra_1
= * ((int *) buffer
);
302 ? " (%s),%#0x(%s)[%s*%1d]"
304 reg_names
[op_1_regno
],
306 reg_names
[op_2_regno
],
307 reg_names
[index_reg_regno
],
311 read_memory (memaddr
+4, buffer
, MAXLEN
);
313 extra_1
= * ((int *) buffer
);
314 read_memory (memaddr
+8, buffer
, MAXLEN
);
316 extra_2
= * ((int *) buffer
);
318 ((index_reg_regno
) ? "%#0x(%s),%#0x(%s)[%s*%1d]"
319 : "%#0x(%s),%#0x(%s) "),
321 reg_names
[op_1_regno
],
323 reg_names
[op_2_regno
],
324 reg_names
[index_reg_regno
],
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
],
336 "\t\t# unknown mode in %08x",