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