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