1 /* Print VAX instructions for GDB, the GNU debugger.
2 Copyright 1986, 1989, 1991, 1992, 1995, 1996, 1998, 1999, 2000, 2002
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 ();
56 vax_register_name (int regno)
58 static char *register_names[] =
60 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
61 "r8", "r9", "r10", "r11", "ap", "fp", "sp", "pc",
67 if (regno >= (sizeof(register_names) / sizeof(*register_names)))
69 return (register_names[regno]);
73 vax_register_byte (int regno)
79 vax_register_raw_size (int regno)
85 vax_register_virtual_size (int regno)
91 vax_register_virtual_type (int regno)
93 return (builtin_type_int);
97 vax_frame_init_saved_regs (struct frame_info *frame)
102 if (frame->saved_regs)
105 frame_saved_regs_zalloc (frame);
107 regmask = read_memory_integer (frame->frame + 4, 4) >> 16;
109 next_addr = frame->frame + 16;
111 /* regmask's low bit is for register 0, which is the first one
112 what would be pushed. */
113 for (regnum = 0; regnum < AP_REGNUM; regnum++)
115 if (regmask & (1 << regnum))
116 frame->saved_regs[regnum] = next_addr += 4;
119 frame->saved_regs[SP_REGNUM] = next_addr + 4;
120 if (regmask & (1 << FP_REGNUM))
121 frame->saved_regs[SP_REGNUM] +=
122 4 + (4 * read_memory_integer (next_addr + 4, 4));
124 frame->saved_regs[PC_REGNUM] = frame->frame + 16;
125 frame->saved_regs[FP_REGNUM] = frame->frame + 12;
126 frame->saved_regs[AP_REGNUM] = frame->frame + 8;
127 frame->saved_regs[PS_REGNUM] = frame->frame + 4;
130 /* Advance PC across any function entry prologue instructions
131 to reach some "real" code. */
134 vax_skip_prologue (CORE_ADDR pc)
136 register int op = (unsigned char) read_memory_integer (pc, 1);
138 pc += 2; /* skip brb */
140 pc += 3; /* skip brw */
142 && ((unsigned char) read_memory_integer (pc + 2, 1)) == 0x5E)
143 pc += 3; /* skip subl2 */
145 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xAE
146 && ((unsigned char) read_memory_integer (pc + 3, 1)) == 0x5E)
147 pc += 4; /* skip movab */
149 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xCE
150 && ((unsigned char) read_memory_integer (pc + 4, 1)) == 0x5E)
151 pc += 5; /* skip movab */
153 && ((unsigned char) read_memory_integer (pc + 1, 1)) == 0xEE
154 && ((unsigned char) read_memory_integer (pc + 6, 1)) == 0x5E)
155 pc += 7; /* skip movab */
159 /* Return number of args passed to a frame.
160 Can return -1, meaning no way to tell. */
163 vax_frame_num_args (struct frame_info *fi)
165 return (0xff & read_memory_integer (FRAME_ARGS_ADDRESS (fi), 1));
170 /* Print the vax instruction at address MEMADDR in debugged memory,
171 from disassembler info INFO.
172 Returns length of the instruction, in bytes. */
175 vax_print_insn (CORE_ADDR memaddr, disassemble_info *info)
177 unsigned char buffer[MAXLEN];
179 register unsigned char *p;
182 int status = (*info->read_memory_func) (memaddr, buffer, MAXLEN, info);
185 (*info->memory_error_func) (status, memaddr, info);
189 for (i = 0; i < NOPCODES; i++)
190 if (votstrs[i].detail.code == buffer[0]
191 || votstrs[i].detail.code == *(unsigned short *) buffer)
194 /* Handle undefined instructions. */
197 (*info->fprintf_func) (info->stream, "0%o", buffer[0]);
201 (*info->fprintf_func) (info->stream, "%s", votstrs[i].name);
203 /* Point at first byte of argument data,
204 and at descriptor for first argument. */
205 p = buffer + 1 + (votstrs[i].detail.code >= 0x100);
206 d = votstrs[i].detail.args;
209 (*info->fprintf_func) (info->stream, " ");
213 p = print_insn_arg (d, p, memaddr + (p - buffer), info);
216 (*info->fprintf_func) (info->stream, ",");
221 static unsigned char *
222 print_insn_arg (char *d, register char *p, CORE_ADDR addr,
223 disassemble_info *info)
225 register int regnum = *p & 0xf;
231 (*info->fprintf_func) (info->stream, "0x%x", addr + *p++ + 1);
234 (*info->fprintf_func) (info->stream, "0x%x", addr + *(short *) p + 2);
239 switch ((*p++ >> 4) & 0xf)
244 case 3: /* Literal mode */
245 if (d[1] == 'd' || d[1] == 'f' || d[1] == 'g' || d[1] == 'h')
247 *(int *) &floatlitbuf = 0x4000 + ((p[-1] & 0x3f) << 4);
248 (*info->fprintf_func) (info->stream, "$%f", floatlitbuf);
251 (*info->fprintf_func) (info->stream, "$%d", p[-1] & 0x3f);
254 case 4: /* Indexed */
255 p = (char *) print_insn_arg (d, p, addr + 1, info);
256 (*info->fprintf_func) (info->stream, "[%s]", REGISTER_NAME (regnum));
259 case 5: /* Register */
260 (*info->fprintf_func) (info->stream, REGISTER_NAME (regnum));
263 case 7: /* Autodecrement */
264 (*info->fprintf_func) (info->stream, "-");
265 case 6: /* Register deferred */
266 (*info->fprintf_func) (info->stream, "(%s)", REGISTER_NAME (regnum));
269 case 9: /* Autoincrement deferred */
270 (*info->fprintf_func) (info->stream, "@");
271 if (regnum == PC_REGNUM)
273 (*info->fprintf_func) (info->stream, "#");
274 info->target = *(long *) p;
275 (*info->print_address_func) (info->target, info);
279 case 8: /* Autoincrement */
280 if (regnum == PC_REGNUM)
282 (*info->fprintf_func) (info->stream, "#");
286 (*info->fprintf_func) (info->stream, "%d", *p++);
290 (*info->fprintf_func) (info->stream, "%d", *(short *) p);
295 (*info->fprintf_func) (info->stream, "%d", *(long *) p);
300 (*info->fprintf_func) (info->stream, "0x%x%08x",
301 ((long *) p)[1], ((long *) p)[0]);
306 (*info->fprintf_func) (info->stream, "0x%x%08x%08x%08x",
307 ((long *) p)[3], ((long *) p)[2],
308 ((long *) p)[1], ((long *) p)[0]);
313 if (INVALID_FLOAT (p, 4))
314 (*info->fprintf_func) (info->stream,
315 "<<invalid float 0x%x>>",
318 (*info->fprintf_func) (info->stream, "%f", *(float *) p);
323 if (INVALID_FLOAT (p, 8))
324 (*info->fprintf_func) (info->stream,
325 "<<invalid float 0x%x%08x>>",
326 ((long *) p)[1], ((long *) p)[0]);
328 (*info->fprintf_func) (info->stream, "%f", *(double *) p);
333 (*info->fprintf_func) (info->stream, "g-float");
338 (*info->fprintf_func) (info->stream, "h-float");
345 (*info->fprintf_func) (info->stream, "(%s)+", REGISTER_NAME (regnum));
348 case 11: /* Byte displacement deferred */
349 (*info->fprintf_func) (info->stream, "@");
350 case 10: /* Byte displacement */
351 if (regnum == PC_REGNUM)
353 info->target = addr + *p + 2;
354 (*info->print_address_func) (info->target, info);
357 (*info->fprintf_func) (info->stream, "%d(%s)", *p, REGISTER_NAME (regnum));
361 case 13: /* Word displacement deferred */
362 (*info->fprintf_func) (info->stream, "@");
363 case 12: /* Word displacement */
364 if (regnum == PC_REGNUM)
366 info->target = addr + *(short *) p + 3;
367 (*info->print_address_func) (info->target, info);
370 (*info->fprintf_func) (info->stream, "%d(%s)",
371 *(short *) p, REGISTER_NAME (regnum));
375 case 15: /* Long displacement deferred */
376 (*info->fprintf_func) (info->stream, "@");
377 case 14: /* Long displacement */
378 if (regnum == PC_REGNUM)
380 info->target = addr + *(short *) p + 5;
381 (*info->print_address_func) (info->target, info);
384 (*info->fprintf_func) (info->stream, "%d(%s)",
385 *(long *) p, REGISTER_NAME (regnum));
389 return (unsigned char *) p;
393 _initialize_vax_tdep (void)
395 tm_print_insn = vax_print_insn;