* This code is derived from software copyrighted by the Free Software
* Modified 1991 by Donn Seeley at UUNET Technologies, Inc.
static char sccsid
[] = "@(#)vax-pinsn.c 6.3 (Berkeley) 5/8/91";
/* Print vax instructions for GDB, the GNU debugger.
Copyright (C) 1986, 1989 Free Software Foundation, Inc.
This file is part of GDB.
GDB is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
GDB is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GDB; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Vax instructions are never longer than this. */
/* Number of elements in the opcode table. */
#define NOPCODES (sizeof votstrs / sizeof votstrs[0])
extern char *reg_names
[];
static unsigned char *print_insn_arg ();
/* Print the vax instruction at address MEMADDR in debugged memory,
on STREAM. Returns length of the instruction, in bytes. */
print_insn (memaddr
, stream
)
unsigned char buffer
[MAXLEN
];
register unsigned char *p
;
read_memory (memaddr
, buffer
, MAXLEN
);
for (i
= 0; i
< NOPCODES
; i
++)
if (votstrs
[i
].detail
.code
== buffer
[0]
|| votstrs
[i
].detail
.code
== *(unsigned short *)buffer
)
/* Handle undefined instructions. */
fprintf (stream
, "0%o", buffer
[0]);
fprintf (stream
, "%s", votstrs
[i
].name
);
/* Point at first byte of argument data,
and at descriptor for first argument. */
p
= buffer
+ 1 + (votstrs
[i
].detail
.code
>= 0x100);
d
= votstrs
[i
].detail
.args
;
p
= print_insn_arg (d
, p
, memaddr
+ (p
- buffer
), stream
);
print_insn_arg (d
, p
, addr
, stream
)
register int regnum
= *p
& 0xf;
fprintf (stream
, "0x%x", addr
+ *p
++ + 1);
fprintf (stream
, "0x%x", addr
+ *(short *)p
+ 2);
switch ((*p
++ >> 4) & 0xf)
case 3: /* Literal mode */
if (d
[1] == 'd' || d
[1] == 'f' || d
[1] == 'g' || d
[1] == 'h')
*(int *)&floatlitbuf
= 0x4000 + ((p
[-1] & 0x3f) << 4);
fprintf (stream
, "$%f", floatlitbuf
);
fprintf (stream
, "$%d", p
[-1] & 0x3f);
p
= (char *) print_insn_arg (d
, p
, addr
+ 1, stream
);
fprintf (stream
, "[%s]", reg_names
[regnum
]);
fprintf (stream
, reg_names
[regnum
]);
case 7: /* Autodecrement */
case 6: /* Register deferred */
fprintf (stream
, "(%s)", reg_names
[regnum
]);
case 9: /* Autoincrement deferred */
print_address (*(long *)p
, stream
);
case 8: /* Autoincrement */
fprintf (stream
, "%d", *p
++);
fprintf (stream
, "%d", *(short *)p
);
fprintf (stream
, "%d", *(long *)p
);
fprintf (stream
, "0x%x%08x", ((long *)p
)[1], ((long *)p
)[0]);
fprintf (stream
, "0x%x%08x%08x%08x",
((long *)p
)[3], ((long *)p
)[2],
((long *)p
)[1], ((long *)p
)[0]);
if (INVALID_FLOAT (p
, 4))
fprintf (stream
, "<<invalid float 0x%x>>", *(int *) p
);
fprintf (stream
, "%f", *(float *) p
);
if (INVALID_FLOAT (p
, 8))
fprintf (stream
, "<<invalid float 0x%x%08x>>",
((long *)p
)[1], ((long *)p
)[0]);
fprintf (stream
, "%f", *(double *) p
);
fprintf (stream
, "g-float");
fprintf (stream
, "h-float");
fprintf (stream
, "(%s)+", reg_names
[regnum
]);
case 11: /* Byte displacement deferred */
case 10: /* Byte displacement */
print_address (addr
+ *p
+ 2, stream
);
fprintf (stream
, "%d(%s)", *p
, reg_names
[regnum
]);
case 13: /* Word displacement deferred */
case 12: /* Word displacement */
print_address (addr
+ *(short *)p
+ 3, stream
);
fprintf (stream
, "%d(%s)", *(short *)p
, reg_names
[regnum
]);
case 15: /* Long displacement deferred */
case 14: /* Long displacement */
print_address (addr
+ *(long *)p
+ 5, stream
);
fprintf (stream
, "%d(%s)", *(long *)p
, reg_names
[regnum
]);
return (unsigned char *) p
;