/* Print National Semiconductor 32000 instructions.
- Copyright 1986, 1988, 1991, 1992, 1994 Free Software Foundation, Inc.
+ Copyright 1986, 1988, 1991, 1992, 1994, 1998, 2001, 2002
+ Free Software Foundation, Inc.
This file is part of opcodes library.
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. */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#define const
#endif
#include "opcode/ns32k.h"
+#include "opintl.h"
static disassemble_info *dis_info;
/*
* Hacks to get it to compile <= READ THESE AS FIXES NEEDED
*/
-#define CORE_ADDR unsigned long
#define INVALID_FLOAT(val, size) invalid_float((char *)val, size)
+static int print_insn_arg
+ PARAMS ((int, int, int *, char *, bfd_vma, char *, int));
+static int get_displacement PARAMS ((char *, int *));
+static int invalid_float PARAMS ((char *, int));
+static long int read_memory_integer PARAMS ((unsigned char *, int));
+static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
+struct ns32k_option;
+static void optlist PARAMS ((int, const struct ns32k_option *, char *));
+static void list_search PARAMS ((int, const struct ns32k_option *, char *));
+static int bit_extract PARAMS ((bfd_byte *, int, int));
+static int bit_extract_simple PARAMS ((bfd_byte *, int, int));
+static void bit_copy PARAMS ((char *, int, int, char *));
+static int sign_extend PARAMS ((int, int));
+static void flip_bytes PARAMS ((char *, int));
+
static long read_memory_integer(addr, nr)
unsigned char *addr;
int nr;
#define NEXT_IS_ADDR '|'
\f
-struct option {
+struct ns32k_option {
char *pattern; /* the option itself */
unsigned long value; /* binary value of the option */
unsigned long match; /* these bits must match */
};
\f
-static struct option opt_u[]= /* restore, exit */
+static const struct ns32k_option opt_u[]= /* restore, exit */
{
{ "r0", 0x80, 0x80 },
{ "r1", 0x40, 0x40 },
{ 0 , 0x00, 0x00 }
};
-static struct option opt_U[]= /* save, enter */
+static const struct ns32k_option opt_U[]= /* save, enter */
{
{ "r0", 0x01, 0x01 },
{ "r1", 0x02, 0x02 },
{ 0 , 0x00, 0x00 }
};
-static struct option opt_O[]= /* setcfg */
+static const struct ns32k_option opt_O[]= /* setcfg */
{
{ "c", 0x8, 0x8 },
{ "m", 0x4, 0x4 },
{ 0 , 0x0, 0x0 }
};
-static struct option opt_C[]= /* cinv */
+static const struct ns32k_option opt_C[]= /* cinv */
{
{ "a", 0x4, 0x4 },
{ "i", 0x2, 0x2 },
{ 0 , 0x0, 0x0 }
};
-static struct option opt_S[]= /* string inst */
+static const struct ns32k_option opt_S[]= /* string inst */
{
{ "b", 0x1, 0x1 },
{ "u", 0x6, 0x6 },
{ 0 , 0x0, 0x0 }
};
-static struct option list_P532[]= /* lpr spr */
+static const struct ns32k_option list_P532[]= /* lpr spr */
{
{ "us", 0x0, 0xf },
{ "dcr", 0x1, 0xf },
{ 0 , 0x00, 0xf }
};
-static struct option list_M532[]= /* lmr smr */
+static const struct ns32k_option list_M532[]= /* lmr smr */
{
{ "mcr", 0x9, 0xf },
{ "msr", 0xa, 0xf },
{ 0 , 0x0, 0xf }
};
-static struct option list_P032[]= /* lpr spr */
+static const struct ns32k_option list_P032[]= /* lpr spr */
{
{ "upsr", 0x0, 0xf },
{ "fp", 0x8, 0xf },
{ 0 , 0x0, 0xf }
};
-static struct option list_M032[]= /* lmr smr */
+static const struct ns32k_option list_M032[]= /* lmr smr */
{
{ "bpr0", 0x0, 0xf },
{ "bpr1", 0x1, 0xf },
*/
static void
optlist(options, optionP, result)
- int options;
- struct option *optionP;
- char *result;
+ int options;
+ const struct ns32k_option *optionP;
+ char *result;
{
if (options == 0) {
sprintf(result, "[]");
strcat(result, "]");
}
-static list_search(reg_value, optionP, result)
- int reg_value;
- struct option *optionP;
- char *result;
+static void
+list_search (reg_value, optionP, result)
+ int reg_value;
+ const struct ns32k_option *optionP;
+ char *result;
{
for (; optionP->pattern; optionP++) {
if ((reg_value & optionP->match) == optionP->value) {
int count;
{
int result;
- int mask;
int bit;
buffer += offset >> 3;
return result;
}
+/* Like bit extract but the buffer is valid and doen't need to be
+ * fetched
+ */
+static int
+bit_extract_simple (buffer, offset, count)
+ bfd_byte *buffer;
+ int offset;
+ int count;
+{
+ int result;
+ int bit;
+
+ buffer += offset >> 3;
+ offset &= 7;
+ bit = 1;
+ result = 0;
+ while (count--)
+ {
+ if ((*buffer & (1 << offset)))
+ result |= bit;
+ if (++offset == 8)
+ {
+ offset = 0;
+ buffer++;
+ }
+ bit <<= 1;
+ }
+ return result;
+}
+
static void
bit_copy (buffer, offset, count, to)
char *buffer;
}
-static sign_extend (value, bits)
+static int
+sign_extend (value, bits)
int value, bits;
{
value = value & ((1 << bits) - 1);
: value);
}
-static flip_bytes (ptr, count)
+static void
+flip_bytes (ptr, count)
char *ptr;
int count;
{
bfd_vma memaddr;
disassemble_info *info;
{
- register int i;
- register unsigned char *p;
- register char *d;
+ unsigned int i;
+ const char *d;
unsigned short first_word;
- int gen, disp;
int ioffset; /* bits into instruction */
int aoffset; /* bits into arguments */
char arg_bufs[MAX_ARGS+1][ARG_LEN];
FETCH_DATA(info, buffer + 1);
for (i = 0; i < NOPCODES; i++)
if (ns32k_opcodes[i].opcode_id_size <= 8
- && ((buffer[0] & ((1 << ns32k_opcodes[i].opcode_id_size) - 1))
+ && ((buffer[0]
+ & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
== ns32k_opcodes[i].opcode_seed))
break;
if (i == NOPCODES) {
first_word = read_memory_integer(buffer, 2);
for (i = 0; i < NOPCODES; i++)
- if ((first_word & ((1 << ns32k_opcodes[i].opcode_id_size) - 1))
+ if ((first_word
+ & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
== ns32k_opcodes[i].opcode_seed)
break;
}
for (argnum = 0; argnum <= maxarg; argnum++)
{
- CORE_ADDR addr;
+ bfd_vma addr;
char *ch;
for (ch = arg_bufs[argnum]; *ch;)
{
if (*ch == NEXT_IS_ADDR)
{
++ch;
- addr = atoi (ch);
+ addr = bfd_scan_vma (ch, NULL, 16);
(*dis_info->print_address_func) (addr, dis_info);
while (*ch && *ch != NEXT_IS_ADDR)
++ch;
of the index byte (it contains garbage if this operand is not a
general operand using scaled indexed addressing mode). */
+static int
print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
- char d;
+ int d;
int ioffset, *aoffsetp;
char *buffer;
- CORE_ADDR addr;
+ bfd_vma addr;
char *result;
int index_offset;
{
- int addr_mode;
- float Fvalue;
- double Lvalue;
+ union {
+ float f;
+ double d;
+ int i[2];
+ } value;
int Ivalue;
+ int addr_mode;
int disp1, disp2;
int index;
int size;
* aoffsetp by since whatever generated this is broken
* anyway!
*/
- sprintf (result, "$<undefined>");
+ sprintf (result, _("$<undefined>"));
break;
case 'B':
Ivalue = bit_extract (buffer, *aoffsetp, 8);
break;
case 'W':
Ivalue = bit_extract (buffer, *aoffsetp, 16);
- flip_bytes (&Ivalue, 2);
+ flip_bytes ((char *) & Ivalue, 2);
*aoffsetp += 16;
Ivalue = sign_extend (Ivalue, 16);
sprintf (result, "$%d", Ivalue);
break;
case 'D':
Ivalue = bit_extract (buffer, *aoffsetp, 32);
- flip_bytes (&Ivalue, 4);
+ flip_bytes ((char *) & Ivalue, 4);
*aoffsetp += 32;
sprintf (result, "$%d", Ivalue);
break;
case 'F':
- bit_copy (buffer, *aoffsetp, 32, (char *) &Fvalue);
- flip_bytes (&Fvalue, 4);
+ bit_copy (buffer, *aoffsetp, 32, (char *) &value.f);
+ flip_bytes ((char *) &value.f, 4);
*aoffsetp += 32;
- if (INVALID_FLOAT (&Fvalue, 4))
- sprintf (result, "<<invalid float 0x%.8x>>", *(int *) &Fvalue);
+ if (INVALID_FLOAT (&value.f, 4))
+ sprintf (result, "<<invalid float 0x%.8x>>", value.i[0]);
else /* assume host has ieee float */
- sprintf (result, "$%g", Fvalue);
+ sprintf (result, "$%g", value.f);
break;
case 'L':
- bit_copy (buffer, *aoffsetp, 64, (char *) &Lvalue);
- flip_bytes (&Lvalue, 8);
+ bit_copy (buffer, *aoffsetp, 64, (char *) &value.d);
+ flip_bytes ((char *) &value.d, 8);
*aoffsetp += 64;
- if (INVALID_FLOAT (&Lvalue, 8))
- sprintf (result, "<<invalid long 0x%.8x%.8x>>",
- *(((int *) &Lvalue) + 1), *(int *) &Lvalue);
+ if (INVALID_FLOAT (&value.d, 8))
+ sprintf (result, "<<invalid double 0x%.8x%.8x>>",
+ value.i[1], value.i[0]);
else /* assume host has ieee float */
- sprintf (result, "$%g", Lvalue);
+ sprintf (result, "$%g", value.d);
break;
}
break;
case 0x1b:
/* Memory space disp(PC) */
disp1 = get_displacement (buffer, aoffsetp);
- sprintf (result, "|%d|", addr + disp1);
+ *result++ = NEXT_IS_ADDR;
+ sprintf_vma (result, addr + disp1);
+ result += strlen (result);
+ *result++ = NEXT_IS_ADDR;
+ *result = '\0';
break;
case 0x1c:
case 0x1d:
print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
result, 0);
{
- static char *ind[] = {"b", "w", "d", "q"};
+ static const char *ind = "bwdq";
char *off;
off = result + strlen (result);
- sprintf (off, "[r%d:%s]", index,
+ sprintf (off, "[r%d:%c]", index,
ind[addr_mode & 3]);
}
break;
sprintf (result, "%d", (Ivalue / size) + 1);
break;
case 'p':
- sprintf (result, "%c%d%c", NEXT_IS_ADDR,
- addr + get_displacement (buffer, aoffsetp),
- NEXT_IS_ADDR);
+ *result++ = NEXT_IS_ADDR;
+ sprintf_vma (result, addr + get_displacement (buffer, aoffsetp));
+ result += strlen (result);
+ *result++ = NEXT_IS_ADDR;
+ *result = '\0';
break;
case 'i':
Ivalue = bit_extract (buffer, *aoffsetp, 8);
return ioffset;
}
+static int
get_displacement (buffer, aoffsetp)
char *buffer;
int *aoffsetp;
break;
case 0x80:
Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
- flip_bytes (&Ivalue2, 2);
+ flip_bytes ((char *) & Ivalue2, 2);
Ivalue = sign_extend (Ivalue2, 14);
*aoffsetp += 16;
break;
case 0xc0:
Ivalue = bit_extract (buffer, *aoffsetp, 32);
- flip_bytes (&Ivalue, 4);
+ flip_bytes ((char *) & Ivalue, 4);
Ivalue = sign_extend (Ivalue, 30);
*aoffsetp += 32;
break;
\f
#if 1 /* a version that should work on ns32k f's&d's on any machine */
-int invalid_float(p, len)
+static int
+invalid_float (p, len)
register char *p;
register int len;
{
- register val;
+ register int val;
if ( len == 4 )
- val = (bit_extract(p, 23, 8)/*exponent*/ == 0xff
- || (bit_extract(p, 23, 8)/*exponent*/ == 0 &&
- bit_extract(p, 0, 23)/*mantisa*/ != 0));
+ val = (bit_extract_simple(p, 23, 8)/*exponent*/ == 0xff
+ || (bit_extract_simple(p, 23, 8)/*exponent*/ == 0 &&
+ bit_extract_simple(p, 0, 23)/*mantisa*/ != 0));
else if ( len == 8 )
- val = (bit_extract(p, 52, 11)/*exponent*/ == 0x7ff
- || (bit_extract(p, 52, 11)/*exponent*/ == 0
- && (bit_extract(p, 0, 32)/*low mantisa*/ != 0
- || bit_extract(p, 32, 20)/*high mantisa*/ != 0)));
+ val = (bit_extract_simple(p, 52, 11)/*exponent*/ == 0x7ff
+ || (bit_extract_simple(p, 52, 11)/*exponent*/ == 0
+ && (bit_extract_simple(p, 0, 32)/*low mantisa*/ != 0
+ || bit_extract_simple(p, 32, 20)/*high mantisa*/ != 0)));
else
val = 1;
return (val);
struct { unsigned lm; unsigned m:20, e:11, :1;} sd;
} float_type_u;
-int invalid_float(p, len)
+static int
+invalid_float (p, len)
register float_type_u *p;
register int len;
{