import gdb-1999-07-07 post reformat
[deliverable/binutils-gdb.git] / gdb / vax-tdep.c
CommitLineData
c906108c
SS
1/* Print VAX instructions for GDB, the GNU debugger.
2 Copyright 1986, 1989, 1991, 1992, 1996 Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
30static unsigned char *print_insn_arg ();
31\f
b83266a0
SS
32/* Advance PC across any function entry prologue instructions
33 to reach some "real" code. */
34
35CORE_ADDR
36vax_skip_prologue (pc)
37 CORE_ADDR pc;
38{
39 register int op = (unsigned char) read_memory_integer (pc, 1);
40 if (op == 0x11)
41 pc += 2; /* skip brb */
42 if (op == 0x31)
43 pc += 3; /* skip brw */
44 if (op == 0xC2
45 && ((unsigned char) read_memory_integer (pc+2, 1)) == 0x5E)
46 pc += 3; /* skip subl2 */
47 if (op == 0x9E
48 && ((unsigned char) read_memory_integer (pc+1, 1)) == 0xAE
49 && ((unsigned char) read_memory_integer(pc+3, 1)) == 0x5E)
50 pc += 4; /* skip movab */
51 if (op == 0x9E
52 && ((unsigned char) read_memory_integer (pc+1, 1)) == 0xCE
53 && ((unsigned char) read_memory_integer(pc+4, 1)) == 0x5E)
54 pc += 5; /* skip movab */
55 if (op == 0x9E
56 && ((unsigned char) read_memory_integer (pc+1, 1)) == 0xEE
57 && ((unsigned char) read_memory_integer(pc+6, 1)) == 0x5E)
58 pc += 7; /* skip movab */
59 return pc;
60}
61
392a587b
JM
62/* Return number of args passed to a frame.
63 Can return -1, meaning no way to tell. */
64
65int
66vax_frame_num_args (fi)
67 struct frame_info *fi;
68{
69 return (0xff & read_memory_integer (FRAME_ARGS_ADDRESS (fi), 1));
70}
71
72
73
c906108c
SS
74/* Print the vax instruction at address MEMADDR in debugged memory,
75 from disassembler info INFO.
76 Returns length of the instruction, in bytes. */
77
78static int
79vax_print_insn (memaddr, info)
80 CORE_ADDR memaddr;
81 disassemble_info *info;
82{
83 unsigned char buffer[MAXLEN];
84 register int i;
85 register unsigned char *p;
86 register char *d;
87
88 int status = (*info->read_memory_func) (memaddr, buffer, MAXLEN, info);
89 if (status != 0)
90 {
91 (*info->memory_error_func) (status, memaddr, info);
92 return -1;
93 }
94
95 for (i = 0; i < NOPCODES; i++)
96 if (votstrs[i].detail.code == buffer[0]
97 || votstrs[i].detail.code == *(unsigned short *)buffer)
98 break;
99
100 /* Handle undefined instructions. */
101 if (i == NOPCODES)
102 {
103 (*info->fprintf_func) (info->stream, "0%o", buffer[0]);
104 return 1;
105 }
106
107 (*info->fprintf_func) (info->stream, "%s", votstrs[i].name);
108
109 /* Point at first byte of argument data,
110 and at descriptor for first argument. */
111 p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
112 d = votstrs[i].detail.args;
113
114 if (*d)
115 (*info->fprintf_func) (info->stream, " ");
116
117 while (*d)
118 {
119 p = print_insn_arg (d, p, memaddr + (p - buffer), info);
120 d += 2;
121 if (*d)
122 (*info->fprintf_func) (info->stream, ",");
123 }
124 return p - buffer;
125}
126
127static unsigned char *
128print_insn_arg (d, p, addr, info)
129 char *d;
130 register char *p;
131 CORE_ADDR addr;
132 disassemble_info *info;
133{
134 register int regnum = *p & 0xf;
135 float floatlitbuf;
136
137 if (*d == 'b')
138 {
139 if (d[1] == 'b')
140 (*info->fprintf_func) (info->stream, "0x%x", addr + *p++ + 1);
141 else
142 {
143 (*info->fprintf_func) (info->stream, "0x%x", addr + *(short *)p + 2);
144 p += 2;
145 }
146 }
147 else
148 switch ((*p++ >> 4) & 0xf)
149 {
150 case 0:
151 case 1:
152 case 2:
153 case 3: /* Literal mode */
154 if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
155 {
156 *(int *)&floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
157 (*info->fprintf_func) (info->stream, "$%f", floatlitbuf);
158 }
159 else
160 (*info->fprintf_func) (info->stream, "$%d", p[-1] & 0x3f);
161 break;
162
163 case 4: /* Indexed */
164 p = (char *) print_insn_arg (d, p, addr + 1, info);
165 (*info->fprintf_func) (info->stream, "[%s]", REGISTER_NAME (regnum));
166 break;
167
168 case 5: /* Register */
169 (*info->fprintf_func) (info->stream, REGISTER_NAME (regnum));
170 break;
171
172 case 7: /* Autodecrement */
173 (*info->fprintf_func) (info->stream, "-");
174 case 6: /* Register deferred */
175 (*info->fprintf_func) (info->stream, "(%s)", REGISTER_NAME (regnum));
176 break;
177
178 case 9: /* Autoincrement deferred */
179 (*info->fprintf_func) (info->stream, "@");
180 if (regnum == PC_REGNUM)
181 {
182 (*info->fprintf_func) (info->stream, "#");
183 info->target = *(long *)p;
184 (*info->print_address_func) (info->target, info);
185 p += 4;
186 break;
187 }
188 case 8: /* Autoincrement */
189 if (regnum == PC_REGNUM)
190 {
191 (*info->fprintf_func) (info->stream, "#");
192 switch (d[1])
193 {
194 case 'b':
195 (*info->fprintf_func) (info->stream, "%d", *p++);
196 break;
197
198 case 'w':
199 (*info->fprintf_func) (info->stream, "%d", *(short *)p);
200 p += 2;
201 break;
202
203 case 'l':
204 (*info->fprintf_func) (info->stream, "%d", *(long *)p);
205 p += 4;
206 break;
207
208 case 'q':
209 (*info->fprintf_func) (info->stream, "0x%x%08x",
210 ((long *)p)[1], ((long *)p)[0]);
211 p += 8;
212 break;
213
214 case 'o':
215 (*info->fprintf_func) (info->stream, "0x%x%08x%08x%08x",
216 ((long *)p)[3], ((long *)p)[2],
217 ((long *)p)[1], ((long *)p)[0]);
218 p += 16;
219 break;
220
221 case 'f':
222 if (INVALID_FLOAT (p, 4))
223 (*info->fprintf_func) (info->stream,
224 "<<invalid float 0x%x>>",
225 *(int *) p);
226 else
227 (*info->fprintf_func) (info->stream, "%f", *(float *) p);
228 p += 4;
229 break;
230
231 case 'd':
232 if (INVALID_FLOAT (p, 8))
233 (*info->fprintf_func) (info->stream,
234 "<<invalid float 0x%x%08x>>",
235 ((long *)p)[1], ((long *)p)[0]);
236 else
237 (*info->fprintf_func) (info->stream, "%f", *(double *) p);
238 p += 8;
239 break;
240
241 case 'g':
242 (*info->fprintf_func) (info->stream, "g-float");
243 p += 8;
244 break;
245
246 case 'h':
247 (*info->fprintf_func) (info->stream, "h-float");
248 p += 16;
249 break;
250
251 }
252 }
253 else
254 (*info->fprintf_func) (info->stream, "(%s)+", REGISTER_NAME (regnum));
255 break;
256
257 case 11: /* Byte displacement deferred */
258 (*info->fprintf_func) (info->stream, "@");
259 case 10: /* Byte displacement */
260 if (regnum == PC_REGNUM)
261 {
262 info->target = addr + *p + 2;
263 (*info->print_address_func) (info->target, info);
264 }
265 else
266 (*info->fprintf_func) (info->stream, "%d(%s)", *p, REGISTER_NAME (regnum));
267 p += 1;
268 break;
269
270 case 13: /* Word displacement deferred */
271 (*info->fprintf_func) (info->stream, "@");
272 case 12: /* Word displacement */
273 if (regnum == PC_REGNUM)
274 {
275 info->target = addr + *(short *)p + 3;
276 (*info->print_address_func) (info->target, info);
277 }
278 else
279 (*info->fprintf_func) (info->stream, "%d(%s)",
280 *(short *)p, REGISTER_NAME (regnum));
281 p += 2;
282 break;
283
284 case 15: /* Long displacement deferred */
285 (*info->fprintf_func) (info->stream, "@");
286 case 14: /* Long displacement */
287 if (regnum == PC_REGNUM)
288 {
289 info->target = addr + *(short *)p + 5;
290 (*info->print_address_func) (info->target, info);
291 }
292 else
293 (*info->fprintf_func) (info->stream, "%d(%s)",
294 *(long *)p, REGISTER_NAME (regnum));
295 p += 4;
296 }
297
298 return (unsigned char *) p;
299}
300
301void
302_initialize_vax_tdep ()
303{
304 tm_print_insn = vax_print_insn;
305}
This page took 0.04001 seconds and 4 git commands to generate.