]> Git Repo - binutils.git/blob - gdb/convex-pinsn.c
This commit was generated by cvs2svn to track changes on a CVS vendor
[binutils.git] / gdb / convex-pinsn.c
1 /* Print Convex instructions for GDB, the GNU debugger.
2    Copyright (C) 1989 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 GDB 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 1, or (at your option)
9 any later version.
10
11 GDB 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 GDB; see the file COPYING.  If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
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
40 union 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
64 struct opform {
65     int mask;                   /* opcode mask */
66     int shift;                  /* opcode align */
67     struct formstr *formstr[3]; /* ST, E0, E1 */
68 };
69
70 struct 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
76 #include "convex-opcode.h"
77
78 unsigned 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
97 struct 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
114 int
115 print_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
284 int 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.042123 seconds and 4 git commands to generate.