1 /* Print VAX instructions for GDB, the GNU debugger.
2 Copyright 1986, 1989, 1991, 1992, 1995, 1996, 1998, 1999, 2000
3 Free Software Foundation, Inc.
5 This file is part of GDB.
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.
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.
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. */
24 #include "opcode/vax.h"
29 /* Return 1 if P points to an invalid floating point value.
30 LEN is the length in bytes -- not relevant on the Vax. */
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
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. */
45 #define INVALID_FLOAT(p, len) ((*(short *) p & 0xff80) == 0x8000)
47 /* Vax instructions are never longer than this. */
50 /* Number of elements in the opcode table. */
51 #define NOPCODES (sizeof votstrs / sizeof votstrs[0])
53 static unsigned char *print_insn_arg ();
55 /* Advance PC across any function entry prologue instructions
56 to reach some "real" code. */
59 vax_skip_prologue (CORE_ADDR pc
)
61 register int op
= (unsigned char) read_memory_integer (pc
, 1);
63 pc
+= 2; /* skip brb */
65 pc
+= 3; /* skip brw */
67 && ((unsigned char) read_memory_integer (pc
+ 2, 1)) == 0x5E)
68 pc
+= 3; /* skip subl2 */
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 */
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 */
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 */
84 /* Return number of args passed to a frame.
85 Can return -1, meaning no way to tell. */
88 vax_frame_num_args (struct frame_info
*fi
)
90 return (0xff & read_memory_integer (FRAME_ARGS_ADDRESS (fi
), 1));
95 /* Print the vax instruction at address MEMADDR in debugged memory,
96 from disassembler info INFO.
97 Returns length of the instruction, in bytes. */
100 vax_print_insn (CORE_ADDR memaddr
, disassemble_info
*info
)
102 unsigned char buffer
[MAXLEN
];
104 register unsigned char *p
;
107 int status
= (*info
->read_memory_func
) (memaddr
, buffer
, MAXLEN
, info
);
110 (*info
->memory_error_func
) (status
, memaddr
, info
);
114 for (i
= 0; i
< NOPCODES
; i
++)
115 if (votstrs
[i
].detail
.code
== buffer
[0]
116 || votstrs
[i
].detail
.code
== *(unsigned short *) buffer
)
119 /* Handle undefined instructions. */
122 (*info
->fprintf_func
) (info
->stream
, "0%o", buffer
[0]);
126 (*info
->fprintf_func
) (info
->stream
, "%s", votstrs
[i
].name
);
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
;
134 (*info
->fprintf_func
) (info
->stream
, " ");
138 p
= print_insn_arg (d
, p
, memaddr
+ (p
- buffer
), info
);
141 (*info
->fprintf_func
) (info
->stream
, ",");
146 static unsigned char *
147 print_insn_arg (char *d
, register char *p
, CORE_ADDR addr
,
148 disassemble_info
*info
)
150 register int regnum
= *p
& 0xf;
156 (*info
->fprintf_func
) (info
->stream
, "0x%x", addr
+ *p
++ + 1);
159 (*info
->fprintf_func
) (info
->stream
, "0x%x", addr
+ *(short *) p
+ 2);
164 switch ((*p
++ >> 4) & 0xf)
169 case 3: /* Literal mode */
170 if (d
[1] == 'd' || d
[1] == 'f' || d
[1] == 'g' || d
[1] == 'h')
172 *(int *) &floatlitbuf
= 0x4000 + ((p
[-1] & 0x3f) << 4);
173 (*info
->fprintf_func
) (info
->stream
, "$%f", floatlitbuf
);
176 (*info
->fprintf_func
) (info
->stream
, "$%d", p
[-1] & 0x3f);
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
));
184 case 5: /* Register */
185 (*info
->fprintf_func
) (info
->stream
, REGISTER_NAME (regnum
));
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
));
194 case 9: /* Autoincrement deferred */
195 (*info
->fprintf_func
) (info
->stream
, "@");
196 if (regnum
== PC_REGNUM
)
198 (*info
->fprintf_func
) (info
->stream
, "#");
199 info
->target
= *(long *) p
;
200 (*info
->print_address_func
) (info
->target
, info
);
204 case 8: /* Autoincrement */
205 if (regnum
== PC_REGNUM
)
207 (*info
->fprintf_func
) (info
->stream
, "#");
211 (*info
->fprintf_func
) (info
->stream
, "%d", *p
++);
215 (*info
->fprintf_func
) (info
->stream
, "%d", *(short *) p
);
220 (*info
->fprintf_func
) (info
->stream
, "%d", *(long *) p
);
225 (*info
->fprintf_func
) (info
->stream
, "0x%x%08x",
226 ((long *) p
)[1], ((long *) p
)[0]);
231 (*info
->fprintf_func
) (info
->stream
, "0x%x%08x%08x%08x",
232 ((long *) p
)[3], ((long *) p
)[2],
233 ((long *) p
)[1], ((long *) p
)[0]);
238 if (INVALID_FLOAT (p
, 4))
239 (*info
->fprintf_func
) (info
->stream
,
240 "<<invalid float 0x%x>>",
243 (*info
->fprintf_func
) (info
->stream
, "%f", *(float *) p
);
248 if (INVALID_FLOAT (p
, 8))
249 (*info
->fprintf_func
) (info
->stream
,
250 "<<invalid float 0x%x%08x>>",
251 ((long *) p
)[1], ((long *) p
)[0]);
253 (*info
->fprintf_func
) (info
->stream
, "%f", *(double *) p
);
258 (*info
->fprintf_func
) (info
->stream
, "g-float");
263 (*info
->fprintf_func
) (info
->stream
, "h-float");
270 (*info
->fprintf_func
) (info
->stream
, "(%s)+", REGISTER_NAME (regnum
));
273 case 11: /* Byte displacement deferred */
274 (*info
->fprintf_func
) (info
->stream
, "@");
275 case 10: /* Byte displacement */
276 if (regnum
== PC_REGNUM
)
278 info
->target
= addr
+ *p
+ 2;
279 (*info
->print_address_func
) (info
->target
, info
);
282 (*info
->fprintf_func
) (info
->stream
, "%d(%s)", *p
, REGISTER_NAME (regnum
));
286 case 13: /* Word displacement deferred */
287 (*info
->fprintf_func
) (info
->stream
, "@");
288 case 12: /* Word displacement */
289 if (regnum
== PC_REGNUM
)
291 info
->target
= addr
+ *(short *) p
+ 3;
292 (*info
->print_address_func
) (info
->target
, info
);
295 (*info
->fprintf_func
) (info
->stream
, "%d(%s)",
296 *(short *) p
, REGISTER_NAME (regnum
));
300 case 15: /* Long displacement deferred */
301 (*info
->fprintf_func
) (info
->stream
, "@");
302 case 14: /* Long displacement */
303 if (regnum
== PC_REGNUM
)
305 info
->target
= addr
+ *(short *) p
+ 5;
306 (*info
->print_address_func
) (info
->target
, info
);
309 (*info
->fprintf_func
) (info
->stream
, "%d(%s)",
310 *(long *) p
, REGISTER_NAME (regnum
));
314 return (unsigned char *) p
;
318 _initialize_vax_tdep (void)
320 tm_print_insn
= vax_print_insn
;
This page took 0.036627 seconds and 4 git commands to generate.