m88k native support
[deliverable/binutils-gdb.git] / gdb / convex-pinsn.c
1 /* Print Convex instructions for GDB, the GNU debugger.
2 Copyright 1989, 1991 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
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.
10
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.
15
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. */
19
20 #include "defs.h"
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
37 union 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
61 struct opform {
62 int mask; /* opcode mask */
63 int shift; /* opcode align */
64 struct formstr *formstr[3]; /* ST, E0, E1 */
65 };
66
67 struct 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
73 #include "convx-opcode.h"
74
75 unsigned char formdecode [] = {
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
94 struct opform opdecode[] = {
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
111 int
112 print_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
281 int 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.03689 seconds and 4 git commands to generate.