]> Git Repo - binutils.git/blob - gdb/vax-pinsn.c
* Makefile.in (dcache_h): Remove redundant definition.
[binutils.git] / gdb / vax-pinsn.c
1 /* Print VAX instructions for GDB, the GNU debugger.
2    Copyright 1986, 1989, 1991, 1992 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 #include "opcode/vax.h"
23
24 /* Vax instructions are never longer than this.  */
25 #define MAXLEN 62
26
27 /* Number of elements in the opcode table.  */
28 #define NOPCODES (sizeof votstrs / sizeof votstrs[0])
29
30 static unsigned char *print_insn_arg ();
31 \f
32 /* Print the vax instruction at address MEMADDR in debugged memory,
33    on STREAM.  Returns length of the instruction, in bytes.  */
34
35 int
36 print_insn (memaddr, stream)
37      CORE_ADDR memaddr;
38      GDB_FILE *stream;
39 {
40   unsigned char buffer[MAXLEN];
41   register int i;
42   register unsigned char *p;
43   register char *d;
44
45   read_memory (memaddr, buffer, MAXLEN);
46
47   for (i = 0; i < NOPCODES; i++)
48     if (votstrs[i].detail.code == buffer[0]
49         || votstrs[i].detail.code == *(unsigned short *)buffer)
50       break;
51
52   /* Handle undefined instructions.  */
53   if (i == NOPCODES)
54     {
55       fprintf_unfiltered (stream, "0%o", buffer[0]);
56       return 1;
57     }
58
59   fprintf_unfiltered (stream, "%s", votstrs[i].name);
60
61   /* Point at first byte of argument data,
62      and at descriptor for first argument.  */
63   p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
64   d = votstrs[i].detail.args;
65
66   if (*d)
67     fputc_unfiltered (' ', stream);
68
69   while (*d)
70     {
71       p = print_insn_arg (d, p, memaddr + (p - buffer), stream);
72       d += 2;
73       if (*d)
74         fprintf_unfiltered (stream, ",");
75     }
76   return p - buffer;
77 }
78
79 static unsigned char *
80 print_insn_arg (d, p, addr, stream)
81      char *d;
82      register char *p;
83      CORE_ADDR addr;
84      GDB_FILE *stream;
85 {
86   register int regnum = *p & 0xf;
87   float floatlitbuf;
88
89   if (*d == 'b')
90     {
91       if (d[1] == 'b')
92         fprintf_unfiltered (stream, "0x%x", addr + *p++ + 1);
93       else
94         {
95           fprintf_unfiltered (stream, "0x%x", addr + *(short *)p + 2);
96           p += 2;
97         }
98     }
99   else
100     switch ((*p++ >> 4) & 0xf)
101       {
102       case 0:
103       case 1:
104       case 2:
105       case 3:                   /* Literal mode */
106         if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
107           {
108             *(int *)&floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
109             fprintf_unfiltered (stream, "$%f", floatlitbuf);
110           }
111         else
112           fprintf_unfiltered (stream, "$%d", p[-1] & 0x3f);
113         break;
114
115       case 4:                   /* Indexed */
116         p = (char *) print_insn_arg (d, p, addr + 1, stream);
117         fprintf_unfiltered (stream, "[%s]", reg_names[regnum]);
118         break;
119
120       case 5:                   /* Register */
121         fprintf_unfiltered (stream, reg_names[regnum]);
122         break;
123
124       case 7:                   /* Autodecrement */
125         fputc_unfiltered ('-', stream);
126       case 6:                   /* Register deferred */
127         fprintf_unfiltered (stream, "(%s)", reg_names[regnum]);
128         break;
129
130       case 9:                   /* Autoincrement deferred */
131         fputc_unfiltered ('@', stream);
132         if (regnum == PC_REGNUM)
133           {
134             fputc_unfiltered ('#', stream);
135             print_address (*(long *)p, stream);
136             p += 4;
137             break;
138           }
139       case 8:                   /* Autoincrement */
140         if (regnum == PC_REGNUM)
141           {
142             fputc_unfiltered ('#', stream);
143             switch (d[1])
144               {
145               case 'b':
146                 fprintf_unfiltered (stream, "%d", *p++);
147                 break;
148
149               case 'w':
150                 fprintf_unfiltered (stream, "%d", *(short *)p);
151                 p += 2;
152                 break;
153
154               case 'l':
155                 fprintf_unfiltered (stream, "%d", *(long *)p);
156                 p += 4;
157                 break;
158
159               case 'q':
160                 fprintf_unfiltered (stream, "0x%x%08x", ((long *)p)[1], ((long *)p)[0]);
161                 p += 8;
162                 break;
163
164               case 'o':
165                 fprintf_unfiltered (stream, "0x%x%08x%08x%08x",
166                          ((long *)p)[3], ((long *)p)[2],
167                          ((long *)p)[1], ((long *)p)[0]);
168                 p += 16;
169                 break;
170
171               case 'f':
172                 if (INVALID_FLOAT (p, 4))
173                   fprintf_unfiltered (stream, "<<invalid float 0x%x>>", *(int *) p);
174                 else
175                   fprintf_unfiltered (stream, "%f", *(float *) p);
176                 p += 4;
177                 break;
178
179               case 'd':
180                 if (INVALID_FLOAT (p, 8))
181                   fprintf_unfiltered (stream, "<<invalid float 0x%x%08x>>",
182                            ((long *)p)[1], ((long *)p)[0]);
183                 else
184                   fprintf_unfiltered (stream, "%f", *(double *) p);
185                 p += 8;
186                 break;
187
188               case 'g':
189                 fprintf_unfiltered (stream, "g-float");
190                 p += 8;
191                 break;
192
193               case 'h':
194                 fprintf_unfiltered (stream, "h-float");
195                 p += 16;
196                 break;
197
198               }
199           }
200         else
201           fprintf_unfiltered (stream, "(%s)+", reg_names[regnum]);
202         break;
203
204       case 11:                  /* Byte displacement deferred */
205         fputc_unfiltered ('@', stream);
206       case 10:                  /* Byte displacement */
207         if (regnum == PC_REGNUM)
208           print_address (addr + *p + 2, stream);
209         else
210           fprintf_unfiltered (stream, "%d(%s)", *p, reg_names[regnum]);
211         p += 1;
212         break;
213
214       case 13:                  /* Word displacement deferred */
215         fputc_unfiltered ('@', stream);
216       case 12:                  /* Word displacement */
217         if (regnum == PC_REGNUM)
218           print_address (addr + *(short *)p + 3, stream);
219         else
220           fprintf_unfiltered (stream, "%d(%s)", *(short *)p, reg_names[regnum]);
221         p += 2;
222         break;
223
224       case 15:                  /* Long displacement deferred */
225         fputc_unfiltered ('@', stream);
226       case 14:                  /* Long displacement */
227         if (regnum == PC_REGNUM)
228           print_address (addr + *(long *)p + 5, stream);
229         else
230           fprintf_unfiltered (stream, "%d(%s)", *(long *)p, reg_names[regnum]);
231         p += 4;
232       }
233
234   return (unsigned char *) p;
235 }
This page took 0.035171 seconds and 4 git commands to generate.