]> Git Repo - binutils.git/blob - gdb/convex-pinsn.c
* Makefile.in (TARDIRS): Add sparclite demo dir.
[binutils.git] / gdb / convex-pinsn.c
1 /* Print Convex instructions for GDB, the GNU debugger.
2    Copyright 1989, 1991, 1993 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 "opcode/convex.h"
74
75 CONST 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 CONST 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.047015 seconds and 4 git commands to generate.