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