* {gdb.t01, gdb.t02, gdb.t03, gdb.t04, gdb.t05, gdb.t06, gdb.t07,
[deliverable/binutils-gdb.git] / gdb / convex-pinsn.c
CommitLineData
dd3b648e 1/* Print Convex instructions for GDB, the GNU debugger.
b076f024 2 Copyright 1989, 1991, 1993 Free Software Foundation, Inc.
dd3b648e
RP
3
4This file is part of GDB.
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
RP
21#include "symtab.h"
22
23/* reg (fmt_field, inst_field) --
24 the {first,second,third} operand of instruction as fmt_field = [ijk]
25 gets the value of the field from the [ijk] position of the instruction */
26
27#define reg(a,b) ((char (*)[3])(op[fmt->a]))[inst.f0.b]
28
29/* lit (fmt_field) -- field [ijk] is a literal (PSW, VL, eg) */
30
31#define lit(i) op[fmt->i]
32
33/* aj[j] -- name for A register j */
34
35#define aj ((char (*)[3])(op[A]))
36\f
37union inst {
38 struct {
39 unsigned : 7;
40 unsigned i : 3;
41 unsigned j : 3;
42 unsigned k : 3;
43 unsigned : 16;
44 unsigned : 32;
45 } f0;
46 struct {
47 unsigned : 8;
48 unsigned indir : 1;
49 unsigned len : 1;
50 unsigned j : 3;
51 unsigned k : 3;
52 unsigned : 16;
53 unsigned : 32;
54 } f1;
55 unsigned char byte[8];
56 unsigned short half[4];
57 char signed_byte[8];
58 short signed_half[4];
59};
60
61struct opform {
62 int mask; /* opcode mask */
63 int shift; /* opcode align */
64 struct formstr *formstr[3]; /* ST, E0, E1 */
65};
66
67struct formstr {
68 unsigned lop:8, rop:5; /* opcode */
69 unsigned fmt:5; /* inst format */
70 unsigned i:5, j:5, k:2; /* operand formats */
71};
72
b076f024 73#include "opcode/convex.h"
dd3b648e 74
b076f024 75CONST unsigned char formdecode [] = {
dd3b648e
RP
76 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
77 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
78 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
79 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
80 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
81 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
82 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
83 4,4,4,4,4,4,4,4,5,5,5,5,6,6,7,8,
84 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
85 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
86 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
87 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
88 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
89 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
90 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
91 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
92};
93
b076f024 94CONST struct opform opdecode[] = {
dd3b648e
RP
95 0x7e00, 9, format0, e0_format0, e1_format0,
96 0x3f00, 8, format1, e0_format1, e1_format1,
97 0x1fc0, 6, format2, e0_format2, e1_format2,
98 0x0fc0, 6, format3, e0_format3, e1_format3,
99 0x0700, 8, format4, e0_format4, e1_format4,
100 0x03c0, 6, format5, e0_format5, e1_format5,
101 0x01f8, 3, format6, e0_format6, e1_format6,
102 0x00f8, 3, format7, e0_format7, e1_format7,
103 0x0000, 0, formatx, formatx, formatx,
104 0x0f80, 7, formatx, formatx, formatx,
105 0x0f80, 7, formatx, formatx, formatx,
106};
107\f
108/* Print the instruction at address MEMADDR in debugged memory,
109 on STREAM. Returns length of the instruction, in bytes. */
110
111int
112print_insn (memaddr, stream)
113 CORE_ADDR memaddr;
114 FILE *stream;
115{
116 union inst inst;
117 struct formstr *fmt;
118 register int format, op1, pfx;
119 int l;
120
121 read_memory (memaddr, &inst, sizeof inst);
122
123 /* Remove and note prefix, if present */
124
125 pfx = inst.half[0];
126 if ((pfx & 0xfff0) == 0x7ef0)
127 {
128 pfx = ((pfx >> 3) & 1) + 1;
129 *(long long *) &inst = *(long long *) &inst.half[1];
130 }
131 else pfx = 0;
132
133 /* Split opcode into format.op1 and look up in appropriate table */
134
135 format = formdecode[inst.byte[0]];
136 op1 = (inst.half[0] & opdecode[format].mask) >> opdecode[format].shift;
137 if (format == 9)
138 {
139 if (pfx)
140 fmt = formatx;
141 else if (inst.f1.j == 0)
142 fmt = &format1a[op1];
143 else if (inst.f1.j == 1)
144 fmt = &format1b[op1];
145 else
146 fmt = formatx;
147 }
148 else
149 fmt = &opdecode[format].formstr[pfx][op1];
150
151 /* Print it */
152
153 if (fmt->fmt == xxx)
154 {
155 /* noninstruction */
156 fprintf (stream, "0x%04x", pfx ? pfx : inst.half[0]);
157 return 2;
158 }
159
160 if (pfx)
161 pfx = 2;
162
163 fprintf (stream, "%s%s%s", lop[fmt->lop], rop[fmt->rop],
164 &" "[strlen(lop[fmt->lop]) + strlen(rop[fmt->rop])]);
165
166 switch (fmt->fmt)
167 {
168 case rrr: /* three register */
169 fprintf (stream, "%s,%s,%s", reg(i,i), reg(j,j), reg(k,k));
170 return pfx + 2;
171
172 case rr: /* two register */
173 fprintf (stream, "%s,%s", reg(i,j), reg(j,k));
174 return pfx + 2;
175
176 case rxr: /* two register, reversed i and j fields */
177 fprintf (stream, "%s,%s", reg(i,k), reg(j,j));
178 return pfx + 2;
179
180 case r: /* one register */
181 fprintf (stream, "%s", reg(i,k));
182 return pfx + 2;
183
184 case nops: /* no operands */
185 return pfx + 2;
186
187 case nr: /* short immediate, one register */
188 fprintf (stream, "#%d,%s", inst.f0.j, reg(i,k));
189 return pfx + 2;
190
191 case pcrel: /* pc relative */
192 print_address (memaddr + 2 * inst.signed_byte[1], stream);
193 return pfx + 2;
194
195 case lr: /* literal, one register */
196 fprintf (stream, "%s,%s", lit(i), reg(j,k));
197 return pfx + 2;
198
199 case rxl: /* one register, literal */
200 fprintf (stream, "%s,%s", reg(i,k), lit(j));
201 return pfx + 2;
202
203 case rlr: /* register, literal, register */
204 fprintf (stream, "%s,%s,%s", reg(i,j), lit(j), reg(k,k));
205 return pfx + 2;
206
207 case rrl: /* register, register, literal */
208 fprintf (stream, "%s,%s,%s", reg(i,j), reg(j,k), lit(k));
209 return pfx + 2;
210
211 case iml: /* immediate, literal */
212 if (inst.f1.len)
213 {
214 fprintf (stream, "#%#x,%s",
215 (inst.signed_half[1] << 16) + inst.half[2], lit(i));
216 return pfx + 6;
217 }
218 else
219 {
220 fprintf (stream, "#%d,%s", inst.signed_half[1], lit(i));
221 return pfx + 4;
222 }
223
224 case imr: /* immediate, register */
225 if (inst.f1.len)
226 {
227 fprintf (stream, "#%#x,%s",
228 (inst.signed_half[1] << 16) + inst.half[2], reg(i,k));
229 return pfx + 6;
230 }
231 else
232 {
233 fprintf (stream, "#%d,%s", inst.signed_half[1], reg(i,k));
234 return pfx + 4;
235 }
236
237 case a1r: /* memory, register */
238 l = print_effa (inst, stream);
239 fprintf (stream, ",%s", reg(i,k));
240 return pfx + l;
241
242 case a1l: /* memory, literal */
243 l = print_effa (inst, stream);
244 fprintf (stream, ",%s", lit(i));
245 return pfx + l;
246
247 case a2r: /* register, memory */
248 fprintf (stream, "%s,", reg(i,k));
249 return pfx + print_effa (inst, stream);
250
251 case a2l: /* literal, memory */
252 fprintf (stream, "%s,", lit(i));
253 return pfx + print_effa (inst, stream);
254
255 case a3: /* memory */
256 return pfx + print_effa (inst, stream);
257
258 case a4: /* system call */
259 l = 29; goto a4a5;
260 case a5: /* trap */
261 l = 27;
262 a4a5:
263 if (inst.f1.len)
264 {
265 unsigned int m = (inst.signed_half[1] << 16) + inst.half[2];
266 fprintf (stream, "#%d,#%d", m >> l, m & (-1 >> (32-l)));
267 return pfx + 6;
268 }
269 else
270 {
271 unsigned int m = inst.signed_half[1];
272 fprintf (stream, "#%d,#%d", m >> l, m & (-1 >> (32-l)));
273 return pfx + 4;
274 }
275 }
276}
277
278
279/* print effective address @nnn(aj), return instruction length */
280
281int print_effa (inst, stream)
282 union inst inst;
283 FILE *stream;
284{
285 int n, l;
286
287 if (inst.f1.len)
288 {
289 n = (inst.signed_half[1] << 16) + inst.half[2];
290 l = 6;
291 }
292 else
293 {
294 n = inst.signed_half[1];
295 l = 4;
296 }
297
298 if (inst.f1.indir)
299 printf ("@");
300
301 if (!inst.f1.j)
302 {
303 print_address (n, stream);
304 return l;
305 }
306
307 fprintf (stream, (n & 0xf0000000) == 0x80000000 ? "%#x(%s)" : "%d(%s)",
308 n, aj[inst.f1.j]);
309
310 return l;
311}
This page took 0.102258 seconds and 4 git commands to generate.