]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/vax-tdep.c
Revert Sparc OS abi changes.
[thirdparty/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 28
75bc7ddf
AC
29/* Return 1 if P points to an invalid floating point value.
30 LEN is the length in bytes -- not relevant on the Vax. */
31
32/* FIXME: cagney/2002-01-19: The macro below was originally defined in
33 tm-vax.h and used in values.c. Two problems. Firstly this is a
34 very non-portable and secondly it is wrong. The VAX should be
35 using floatformat and associated methods to identify and handle
36 invalid floating-point values. Adding to the poor target's woes
37 there is no floatformat_vax_{f,d} and no TARGET_FLOAT_FORMAT
38 et.al.. */
39
40/* FIXME: cagney/2002-01-19: It turns out that the only thing that
41 uses this macro is the vax disassembler code (so how old is this
42 target?). This target should instead be using the opcodes
43 disassembler. That allowing the macro to be eliminated. */
44
45#define INVALID_FLOAT(p, len) ((*(short *) p & 0xff80) == 0x8000)
46
c906108c
SS
47/* Vax instructions are never longer than this. */
48#define MAXLEN 62
49
50/* Number of elements in the opcode table. */
51#define NOPCODES (sizeof votstrs / sizeof votstrs[0])
52
53static unsigned char *print_insn_arg ();
54\f
b83266a0
SS
55/* Advance PC across any function entry prologue instructions
56 to reach some "real" code. */
57
58CORE_ADDR
fba45db2 59vax_skip_prologue (CORE_ADDR pc)
b83266a0
SS
60{
61 register int op = (unsigned char) read_memory_integer (pc, 1);
62 if (op == 0x11)
c5aa993b 63 pc += 2; /* skip brb */
b83266a0 64 if (op == 0x31)
c5aa993b 65 pc += 3; /* skip brw */
b83266a0 66 if (op == 0xC2
c5aa993b
JM
67 && ((unsigned char) read_memory_integer (pc + 2, 1)) == 0x5E)
68 pc += 3; /* skip subl2 */
b83266a0 69 if (op == 0x9E
c5aa993b
JM
70 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xAE
71 && ((unsigned char) read_memory_integer (pc + 3, 1)) == 0x5E)
72 pc += 4; /* skip movab */
b83266a0 73 if (op == 0x9E
c5aa993b
JM
74 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xCE
75 && ((unsigned char) read_memory_integer (pc + 4, 1)) == 0x5E)
76 pc += 5; /* skip movab */
b83266a0 77 if (op == 0x9E
c5aa993b
JM
78 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xEE
79 && ((unsigned char) read_memory_integer (pc + 6, 1)) == 0x5E)
80 pc += 7; /* skip movab */
b83266a0
SS
81 return pc;
82}
83
392a587b
JM
84/* Return number of args passed to a frame.
85 Can return -1, meaning no way to tell. */
86
87int
fba45db2 88vax_frame_num_args (struct frame_info *fi)
392a587b
JM
89{
90 return (0xff & read_memory_integer (FRAME_ARGS_ADDRESS (fi), 1));
91}
92
93
94
c906108c
SS
95/* Print the vax instruction at address MEMADDR in debugged memory,
96 from disassembler info INFO.
97 Returns length of the instruction, in bytes. */
98
99static int
fba45db2 100vax_print_insn (CORE_ADDR memaddr, disassemble_info *info)
c906108c
SS
101{
102 unsigned char buffer[MAXLEN];
103 register int i;
104 register unsigned char *p;
c11c3a98 105 const char *d;
c906108c
SS
106
107 int status = (*info->read_memory_func) (memaddr, buffer, MAXLEN, info);
108 if (status != 0)
109 {
110 (*info->memory_error_func) (status, memaddr, info);
111 return -1;
112 }
113
114 for (i = 0; i < NOPCODES; i++)
115 if (votstrs[i].detail.code == buffer[0]
c5aa993b 116 || votstrs[i].detail.code == *(unsigned short *) buffer)
c906108c
SS
117 break;
118
119 /* Handle undefined instructions. */
120 if (i == NOPCODES)
121 {
122 (*info->fprintf_func) (info->stream, "0%o", buffer[0]);
123 return 1;
124 }
125
126 (*info->fprintf_func) (info->stream, "%s", votstrs[i].name);
127
128 /* Point at first byte of argument data,
129 and at descriptor for first argument. */
130 p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
131 d = votstrs[i].detail.args;
132
133 if (*d)
134 (*info->fprintf_func) (info->stream, " ");
135
136 while (*d)
137 {
138 p = print_insn_arg (d, p, memaddr + (p - buffer), info);
139 d += 2;
140 if (*d)
141 (*info->fprintf_func) (info->stream, ",");
142 }
143 return p - buffer;
144}
145
146static unsigned char *
fba45db2
KB
147print_insn_arg (char *d, register char *p, CORE_ADDR addr,
148 disassemble_info *info)
c906108c
SS
149{
150 register int regnum = *p & 0xf;
151 float floatlitbuf;
152
153 if (*d == 'b')
154 {
155 if (d[1] == 'b')
156 (*info->fprintf_func) (info->stream, "0x%x", addr + *p++ + 1);
157 else
158 {
c5aa993b 159 (*info->fprintf_func) (info->stream, "0x%x", addr + *(short *) p + 2);
c906108c
SS
160 p += 2;
161 }
162 }
163 else
164 switch ((*p++ >> 4) & 0xf)
165 {
166 case 0:
167 case 1:
168 case 2:
169 case 3: /* Literal mode */
170 if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
171 {
c5aa993b 172 *(int *) &floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
c906108c
SS
173 (*info->fprintf_func) (info->stream, "$%f", floatlitbuf);
174 }
175 else
176 (*info->fprintf_func) (info->stream, "$%d", p[-1] & 0x3f);
177 break;
178
179 case 4: /* Indexed */
180 p = (char *) print_insn_arg (d, p, addr + 1, info);
181 (*info->fprintf_func) (info->stream, "[%s]", REGISTER_NAME (regnum));
182 break;
183
184 case 5: /* Register */
185 (*info->fprintf_func) (info->stream, REGISTER_NAME (regnum));
186 break;
187
188 case 7: /* Autodecrement */
189 (*info->fprintf_func) (info->stream, "-");
190 case 6: /* Register deferred */
191 (*info->fprintf_func) (info->stream, "(%s)", REGISTER_NAME (regnum));
192 break;
193
194 case 9: /* Autoincrement deferred */
195 (*info->fprintf_func) (info->stream, "@");
196 if (regnum == PC_REGNUM)
197 {
198 (*info->fprintf_func) (info->stream, "#");
c5aa993b 199 info->target = *(long *) p;
c906108c
SS
200 (*info->print_address_func) (info->target, info);
201 p += 4;
202 break;
203 }
204 case 8: /* Autoincrement */
205 if (regnum == PC_REGNUM)
206 {
207 (*info->fprintf_func) (info->stream, "#");
208 switch (d[1])
209 {
210 case 'b':
211 (*info->fprintf_func) (info->stream, "%d", *p++);
212 break;
213
214 case 'w':
c5aa993b 215 (*info->fprintf_func) (info->stream, "%d", *(short *) p);
c906108c
SS
216 p += 2;
217 break;
218
219 case 'l':
c5aa993b 220 (*info->fprintf_func) (info->stream, "%d", *(long *) p);
c906108c
SS
221 p += 4;
222 break;
223
224 case 'q':
225 (*info->fprintf_func) (info->stream, "0x%x%08x",
c5aa993b 226 ((long *) p)[1], ((long *) p)[0]);
c906108c
SS
227 p += 8;
228 break;
229
230 case 'o':
231 (*info->fprintf_func) (info->stream, "0x%x%08x%08x%08x",
c5aa993b
JM
232 ((long *) p)[3], ((long *) p)[2],
233 ((long *) p)[1], ((long *) p)[0]);
c906108c
SS
234 p += 16;
235 break;
236
237 case 'f':
238 if (INVALID_FLOAT (p, 4))
239 (*info->fprintf_func) (info->stream,
240 "<<invalid float 0x%x>>",
241 *(int *) p);
242 else
243 (*info->fprintf_func) (info->stream, "%f", *(float *) p);
244 p += 4;
245 break;
246
247 case 'd':
248 if (INVALID_FLOAT (p, 8))
249 (*info->fprintf_func) (info->stream,
250 "<<invalid float 0x%x%08x>>",
c5aa993b 251 ((long *) p)[1], ((long *) p)[0]);
c906108c
SS
252 else
253 (*info->fprintf_func) (info->stream, "%f", *(double *) p);
254 p += 8;
255 break;
256
257 case 'g':
258 (*info->fprintf_func) (info->stream, "g-float");
259 p += 8;
260 break;
261
262 case 'h':
263 (*info->fprintf_func) (info->stream, "h-float");
264 p += 16;
265 break;
266
267 }
268 }
269 else
270 (*info->fprintf_func) (info->stream, "(%s)+", REGISTER_NAME (regnum));
271 break;
272
273 case 11: /* Byte displacement deferred */
274 (*info->fprintf_func) (info->stream, "@");
275 case 10: /* Byte displacement */
276 if (regnum == PC_REGNUM)
277 {
278 info->target = addr + *p + 2;
279 (*info->print_address_func) (info->target, info);
280 }
281 else
282 (*info->fprintf_func) (info->stream, "%d(%s)", *p, REGISTER_NAME (regnum));
283 p += 1;
284 break;
285
286 case 13: /* Word displacement deferred */
287 (*info->fprintf_func) (info->stream, "@");
288 case 12: /* Word displacement */
289 if (regnum == PC_REGNUM)
290 {
c5aa993b 291 info->target = addr + *(short *) p + 3;
c906108c
SS
292 (*info->print_address_func) (info->target, info);
293 }
294 else
295 (*info->fprintf_func) (info->stream, "%d(%s)",
c5aa993b 296 *(short *) p, REGISTER_NAME (regnum));
c906108c
SS
297 p += 2;
298 break;
299
300 case 15: /* Long displacement deferred */
301 (*info->fprintf_func) (info->stream, "@");
302 case 14: /* Long displacement */
303 if (regnum == PC_REGNUM)
304 {
c5aa993b 305 info->target = addr + *(short *) p + 5;
c906108c
SS
306 (*info->print_address_func) (info->target, info);
307 }
308 else
309 (*info->fprintf_func) (info->stream, "%d(%s)",
c5aa993b 310 *(long *) p, REGISTER_NAME (regnum));
c906108c
SS
311 p += 4;
312 }
313
314 return (unsigned char *) p;
315}
316
317void
fba45db2 318_initialize_vax_tdep (void)
c906108c
SS
319{
320 tm_print_insn = vax_print_insn;
321}