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