-/* Print 32000 instructions for GDB, the GNU debugger.
- Copyright (C) 1986 Free Software Foundation, Inc.
+/* Print National Semiconductor 32000 instructions for GDB, the GNU debugger.
+ Copyright 1986, 1988, 1991, 1992 Free Software Foundation, Inc.
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
+This file is part of GDB.
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
+This program 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 2 of the License, or
+(at your option) any later version.
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
+This program 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.
-#include <stdio.h>
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "defs.h"
-#include "param.h"
#include "symtab.h"
#include "ns32k-opcode.h"
+#include "gdbcore.h"
/* 32000 instructions are never longer than this. */
#define MAXLEN 62
/* Number of elements in the opcode table. */
#define NOPCODES (sizeof notstrs / sizeof notstrs[0])
-extern char *reg_names[];
-
#define NEXT_IS_ADDR '|'
/*
return result;
}
+float
+fbit_extract (buffer, offset, count)
+{
+ union {
+ int ival;
+ float fval;
+ } foo;
+
+ foo.ival = bit_extract (buffer, offset, 32);
+ return foo.fval;
+}
+
double
dbit_extract (buffer, offset, count)
{
count -= 2;
}
}
+\f
+/* Given a character C, does it represent a general addressing mode? */
+#define Is_gen(c) \
+ ((c) == 'F' || (c) == 'L' || (c) == 'B' \
+ || (c) == 'W' || (c) == 'D' || (c) == 'A')
+
+/* Adressing modes. */
+#define Adrmod_index_byte 0x1c
+#define Adrmod_index_word 0x1d
+#define Adrmod_index_doubleword 0x1e
+#define Adrmod_index_quadword 0x1f
+
+/* Is MODE an indexed addressing mode? */
+#define Adrmod_is_index(mode) \
+ (mode == Adrmod_index_byte \
+ || mode == Adrmod_index_word \
+ || mode == Adrmod_index_doubleword \
+ || mode == Adrmod_index_quadword)
\f
/* Print the 32000 instruction at address MEMADDR in debugged memory,
int
print_insn (memaddr, stream)
-CORE_ADDR memaddr;
-FILE *stream;
+ CORE_ADDR memaddr;
+ FILE *stream;
{
unsigned char buffer[MAXLEN];
register int i;
if (*d)
{
+ /* Offset in bits of the first thing beyond each index byte.
+ Element 0 is for operand A and element 1 is for operand B.
+ The rest are irrelevant, but we put them here so we don't
+ index outside the array. */
+ int index_offset[MAX_ARGS];
+
+ /* 0 for operand A, 1 for operand B, greater for other args. */
+ int whicharg = 0;
+
fputc ('\t', stream);
maxarg = 0;
+
+ /* First we have to find and keep track of the index bytes,
+ if we are using scaled indexed addressing mode, since the index
+ bytes occur right after the basic instruction, not as part
+ of the addressing extension. */
+ if (Is_gen(d[1]))
+ {
+ int addr_mode = bit_extract (buffer, ioffset - 5, 5);
+
+ if (Adrmod_is_index (addr_mode))
+ {
+ aoffset += 8;
+ index_offset[0] = aoffset;
+ }
+ }
+ if (d[2] && Is_gen(d[3]))
+ {
+ int addr_mode = bit_extract (buffer, ioffset - 10, 5);
+
+ if (Adrmod_is_index (addr_mode))
+ {
+ aoffset += 8;
+ index_offset[1] = aoffset;
+ }
+ }
+
while (*d)
{
argnum = *d - '1';
if (argnum > maxarg && argnum < MAX_ARGS)
maxarg = argnum;
ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
- memaddr, arg_bufs[argnum]);
+ memaddr, arg_bufs[argnum],
+ index_offset[whicharg]);
d++;
+ whicharg++;
}
for (argnum = 0; argnum <= maxarg; argnum++)
{
return aoffset / 8;
}
-print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result)
+/* Print an instruction operand of category given by d. IOFFSET is
+ the bit position below which small (<1 byte) parts of the operand can
+ be found (usually in the basic instruction, but for indexed
+ addressing it can be in the index byte). AOFFSETP is a pointer to the
+ bit position of the addressing extension. BUFFER contains the
+ instruction. ADDR is where BUFFER was read from. Put the disassembled
+ version of the operand in RESULT. INDEX_OFFSET is the bit position
+ of the index byte (it contains garbage if this operand is not a
+ general operand using scaled indexed addressing mode). */
+
+print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
char d;
int ioffset, *aoffsetp;
char *buffer;
CORE_ADDR addr;
char *result;
+ int index_offset;
{
int addr_mode;
float Fvalue;
{
case 0x0: case 0x1: case 0x2: case 0x3:
case 0x4: case 0x5: case 0x6: case 0x7:
- sprintf (result, "r%d", addr_mode);
+ switch (d)
+ {
+ case 'F':
+ case 'L':
+ sprintf (result, "f%d", addr_mode);
+ break;
+ default:
+ sprintf (result, "r%d", addr_mode);
+ }
break;
case 0x8: case 0x9: case 0xa: case 0xb:
case 0xc: case 0xd: case 0xe: case 0xf:
sprintf (result, "$|%d|", Ivalue);
break;
case 'F':
- Fvalue = (float) bit_extract (buffer, *aoffsetp, 32);
+ Fvalue = fbit_extract (buffer, *aoffsetp, 32);
flip_bytes (&Fvalue, 4);
*aoffsetp += 32;
sprintf (result, "$%g", Fvalue);
case 0x1d:
case 0x1e:
case 0x1f:
- index = bit_extract (buffer, *aoffsetp, 8);
- *aoffsetp += 8;
- print_insn_arg (d, *aoffsetp, aoffsetp, buffer, addr,
- result);
+ index = bit_extract (buffer, index_offset - 8, 3);
+ print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
+ result, 0);
{
static char *ind[] = {"b", "w", "d", "q"};
char *off;
off = result + strlen (result);
- sprintf (off, "[r%d:%s]", index & 7,
+ sprintf (off, "[r%d:%s]", index,
ind[addr_mode & 3]);
}
break;
*/
CORE_ADDR
-n32k_get_enter_addr (pc)
+ns32k_get_enter_addr (pc)
CORE_ADDR pc;
{
CORE_ADDR enter_addr;