gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / opcodes / ns32k-dis.c
index 49facb358cec85f186b580c169dba8255fbeaedd..eac461a969269f057c7d6d23f19189639e55f30a 100644 (file)
@@ -1,27 +1,26 @@
 /* Print National Semiconductor 32000 instructions.
-   Copyright 1986, 1988, 1991, 1992, 1994, 1998, 2001
-   Free Software Foundation, Inc.
+   Copyright (C) 1986-2020 Free Software Foundation, Inc.
 
-This file is part of opcodes library.
+   This file is part of the GNU opcodes library.
 
-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.
+   This library 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 3, or (at your option)
+   any later version.
 
-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.
+   It 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 this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   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., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
-
-#include "bfd.h"
 #include "sysdep.h"
-#include "dis-asm.h"
+#include "bfd.h"
+#include "disassemble.h"
 #if !defined(const) && !defined(__STDC__)
 #define const
 #endif
@@ -30,43 +29,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 static disassemble_info *dis_info;
 
-/*
- * Hacks to get it to compile <= READ THESE AS FIXES NEEDED
- */
-#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;
+/* Hacks to get it to compile <= READ THESE AS FIXES NEEDED.  */
+#define INVALID_FLOAT(val, size) invalid_float ((bfd_byte *) val, size)
+
+static long
+read_memory_integer (unsigned char * addr, int nr)
 {
   long val;
   int i;
-  for (val = 0, i = nr - 1; i >= 0; i--) {
-    val =  (val << 8);
-    val |= (0xff & *(addr + i));
-  }
+
+  for (val = 0, i = nr - 1; i >= 0; i--)
+    {
+      val =  (val << 8);
+      val |= (0xff & *(addr + i));
+    }
   return val;
 }
 
 /* 32000 instructions are never longer than this.  */
 #define MAXLEN 62
 
-
 #include <setjmp.h>
 
 struct private
@@ -75,7 +57,7 @@ struct private
   bfd_byte *max_fetched;
   bfd_byte the_buffer[MAXLEN];
   bfd_vma insn_start;
-  jmp_buf bailout;
+  OPCODES_SIGJMP_BUF bailout;
 };
 
 
@@ -87,12 +69,10 @@ struct private
    ? 1 : fetch_data ((info), (addr)))
 
 static int
-fetch_data (info, addr)
-     struct disassemble_info *info;
-     bfd_byte *addr;
+fetch_data (struct disassemble_info *info, bfd_byte *addr)
 {
   int status;
-  struct private *priv = (struct private *)info->private_data;
+  struct private *priv = (struct private *) info->private_data;
   bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
 
   status = (*info->read_memory_func) (start,
@@ -102,26 +82,28 @@ fetch_data (info, addr)
   if (status != 0)
     {
       (*info->memory_error_func) (status, start, info);
-      longjmp (priv->bailout, 1);
+      OPCODES_SIGLONGJMP (priv->bailout, 1);
     }
   else
     priv->max_fetched = addr;
   return 1;
 }
+
 /* Number of elements in the opcode table.  */
 #define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
 
 #define NEXT_IS_ADDR   '|'
 
 \f
-struct ns32k_option {
-  char *pattern;               /* the option itself */
-  unsigned long value;         /* binary value of the option */
-  unsigned long match;         /* these bits must match */
+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 const struct ns32k_option opt_u[]= /* restore, exit */
+static const struct ns32k_option opt_u[]= /* Restore, exit.  */
 {
   { "r0",      0x80,   0x80    },
   { "r1",      0x40,   0x40    },
@@ -134,7 +116,7 @@ static const struct ns32k_option opt_u[]= /* restore, exit */
   {  0 ,       0x00,   0x00    }
 };
 
-static const struct ns32k_option opt_U[]= /* save, enter */
+static const struct ns32k_option opt_U[]= /* Save, enter.  */
 {
   { "r0",      0x01,   0x01    },
   { "r1",      0x02,   0x02    },
@@ -147,7 +129,7 @@ static const struct ns32k_option opt_U[]= /* save, enter */
   {  0 ,       0x00,   0x00    }
 };
 
-static const struct ns32k_option opt_O[]= /* setcfg */
+static const struct ns32k_option opt_O[]= /* Setcfg.  */
 {
   { "c",       0x8,    0x8     },
   { "m",       0x4,    0x4     },
@@ -156,7 +138,7 @@ static const struct ns32k_option opt_O[]= /* setcfg */
   {  0 ,       0x0,    0x0     }
 };
 
-static const struct ns32k_option opt_C[]= /* cinv */
+static const struct ns32k_option opt_C[]= /* Cinv.  */
 {
   { "a",       0x4,    0x4     },
   { "i",       0x2,    0x2     },
@@ -164,7 +146,7 @@ static const struct ns32k_option opt_C[]= /* cinv */
   {  0 ,       0x0,    0x0     }
 };
 
-static const struct ns32k_option opt_S[]= /* string inst */
+static const struct ns32k_option opt_S[]= /* String inst.  */
 {
   { "b",       0x1,    0x1     },
   { "u",       0x6,    0x6     },
@@ -172,7 +154,7 @@ static const struct ns32k_option opt_S[]= /* string inst */
   {  0 ,       0x0,    0x0     }
 };
 
-static const struct ns32k_option list_P532[]= /* lpr spr */
+static const struct ns32k_option list_P532[]= /* Lpr spr.  */
 {
   { "us",      0x0,    0xf     },
   { "dcr",     0x1,    0xf     },
@@ -190,7 +172,7 @@ static const struct ns32k_option list_P532[]= /* lpr spr */
   {  0 ,       0x00,   0xf     }
 };
 
-static const struct ns32k_option list_M532[]= /* lmr smr */
+static const struct ns32k_option list_M532[]= /* Lmr smr.  */
 {
   { "mcr",     0x9,    0xf     },
   { "msr",     0xa,    0xf     },
@@ -202,7 +184,7 @@ static const struct ns32k_option list_M532[]= /* lmr smr */
   {  0 ,       0x0,    0xf     }
 };
 
-static const struct ns32k_option list_P032[]= /* lpr spr */
+static const struct ns32k_option list_P032[]= /* Lpr spr.  */
 {
   { "upsr",    0x0,    0xf     },
   { "fp",      0x8,    0xf     },
@@ -214,7 +196,7 @@ static const struct ns32k_option list_P032[]= /* lpr spr */
   {  0 ,       0x0,    0xf     }
 };
 
-static const struct ns32k_option list_M032[]= /* lmr smr */
+static const struct ns32k_option list_M032[]= /* Lmr smr.  */
 {
   { "bpr0",    0x0,    0xf     },
   { "bpr1",    0x1,    0xf     },
@@ -230,72 +212,68 @@ static const struct ns32k_option list_M032[]= /* lmr smr */
 };
 
 
-/*
- * figure out which options are present
- */
+/* Figure out which options are present.   */
+
 static void
-optlist(options, optionP, result)
-     int options;
-     const struct ns32k_option *optionP;
-     char *result;
+optlist (int options, const struct ns32k_option * optionP, char * result)
 {
-    if (options == 0) {
-       sprintf(result, "[]");
-       return;
+  if (options == 0)
+    {
+      sprintf (result, "[]");
+      return;
     }
-    sprintf(result, "[");
-
-    for (; (options != 0) && optionP->pattern; optionP++) {
-       if ((options & optionP->match) == optionP->value) {
-           /* we found a match, update result and options */
-           strcat(result, optionP->pattern);
-           options &= ~optionP->value;
-           if (options != 0)   /* more options to come */
-               strcat(result, ",");
+
+  sprintf (result, "[");
+
+  for (; (options != 0) && optionP->pattern; optionP++)
+    {
+      if ((options & optionP->match) == optionP->value)
+       {
+         /* We found a match, update result and options.  */
+         strcat (result, optionP->pattern);
+         options &= ~optionP->value;
+         if (options != 0)     /* More options to come.  */
+           strcat (result, ",");
        }
     }
-    if (options != 0)
-       strcat(result, "undefined");
 
-    strcat(result, "]");
+  if (options != 0)
+    strcat (result, "undefined");
+
+  strcat (result, "]");
 }
 
 static void
-list_search (reg_value, optionP, result)
-     int reg_value;
-     const struct ns32k_option *optionP;
-     char *result;
+list_search (int reg_value, const struct ns32k_option *optionP, char *result)
 {
-    for (; optionP->pattern; optionP++) {
-       if ((reg_value & optionP->match) == optionP->value) {
-           sprintf(result, "%s", optionP->pattern);
-           return;
+  for (; optionP->pattern; optionP++)
+    {
+      if ((reg_value & optionP->match) == optionP->value)
+       {
+         sprintf (result, "%s", optionP->pattern);
+         return;
        }
     }
-    sprintf(result, "undefined");
+  sprintf (result, "undefined");
 }
 \f
-/*
- * extract "count" bits starting "offset" bits
- * into buffer
- */
+/* Extract "count" bits starting "offset" bits into buffer.  */
 
 static int
-bit_extract (buffer, offset, count)
-     bfd_byte *buffer;
-     int offset;
-     int count;
+bit_extract (bfd_byte *buffer, int offset, int count)
 {
-  int result;
-  int bit;
+  unsigned int result;
+  unsigned int bit;
 
+  if (offset < 0 || count < 0)
+    return 0;
   buffer += offset >> 3;
   offset &= 7;
   bit = 1;
   result = 0;
   while (count--)
     {
-      FETCH_DATA(dis_info, buffer + 1);
+      FETCH_DATA (dis_info, buffer + 1);
       if ((*buffer & (1 << offset)))
        result |= bit;
       if (++offset == 8)
@@ -308,18 +286,16 @@ bit_extract (buffer, offset, count)
   return result;
 }
 
-/* Like bit extract but the buffer is valid and doen't need to be
- * fetched
- */
+/* 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;
+bit_extract_simple (bfd_byte *buffer, int offset, int count)
 {
-  int result;
-  int bit;
+  unsigned int result;
+  unsigned int bit;
 
+  if (offset < 0 || count < 0)
+    return 0;
   buffer += offset >> 3;
   offset &= 7;
   bit = 1;
@@ -339,203 +315,129 @@ bit_extract_simple (buffer, offset, count)
 }
 
 static void
-bit_copy (buffer, offset, count, to)
-     char *buffer;
-     int offset;
-     int count;
-     char *to;
+bit_copy (bfd_byte *buffer, int offset, int count, char *to)
 {
-  for(; count > 8; count -= 8, to++, offset += 8)
+  if (offset < 0 || count < 0)
+    return;
+  for (; count > 8; count -= 8, to++, offset += 8)
     *to = bit_extract (buffer, offset, 8);
   *to = bit_extract (buffer, offset, count);
 }
 
-
 static int
-sign_extend (value, bits)
-     int value, bits;
+sign_extend (unsigned int value, unsigned int bits)
 {
-  value = value & ((1 << bits) - 1);
-  return (value & (1 << (bits-1))
-         ? value | (~((1 << bits) - 1))
-         : value);
+  unsigned int sign = 1u << (bits - 1);
+  return ((value & (sign + sign - 1)) ^ sign) - sign;
 }
 
 static void
-flip_bytes (ptr, count)
-     char *ptr;
-     int count;
+flip_bytes (char *ptr, int count)
 {
   char tmp;
 
   while (count > 0)
     {
       tmp = ptr[0];
-      ptr[0] = ptr[count-1];
-      ptr[count-1] = tmp;
+      ptr[0] = ptr[count - 1];
+      ptr[count - 1] = tmp;
       ptr++;
       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' || (c) == 'I' || (c) == 'Z')
+#define Is_gen(c) (strchr ("FLBWDAIZf", (c)) != NULL)
 
 /* Adressing modes.  */
-#define Adrmod_index_byte 0x1c
-#define Adrmod_index_word 0x1d
-#define Adrmod_index_doubleword 0x1e
-#define Adrmod_index_quadword 0x1f
+#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_byte \
    || mode == Adrmod_index_word \
    || mode == Adrmod_index_doubleword \
    || mode == Adrmod_index_quadword)
 
 \f
-/* Print the 32000 instruction at address MEMADDR in debugged memory,
-   on STREAM.  Returns length of the instruction, in bytes.  */
-
-int
-print_insn_ns32k (memaddr, info)
-     bfd_vma memaddr;
-     disassemble_info *info;
+static int
+get_displacement (bfd_byte *buffer, int *aoffsetp)
 {
-  register unsigned int i;
-  register char *d;
-  unsigned short first_word;
-  int ioffset;         /* bits into instruction */
-  int aoffset;         /* bits into arguments */
-  char arg_bufs[MAX_ARGS+1][ARG_LEN];
-  int argnum;
-  int maxarg;
-  struct private priv;
-  bfd_byte *buffer = priv.the_buffer;
-  dis_info = info;
-
-  info->private_data = (PTR) &priv;
-  priv.max_fetched = priv.the_buffer;
-  priv.insn_start = memaddr;
-  if (setjmp (priv.bailout) != 0)
-    /* Error return.  */
-    return -1;
-
-  /* Look for 8bit opcodes first. Other wise, fetching two bytes could take
-   * us over the end of accessible data unnecessarilly
-   */
-  FETCH_DATA(info, buffer + 1);
-  for (i = 0; i < NOPCODES; i++)
-    if (ns32k_opcodes[i].opcode_id_size <= 8
-       && ((buffer[0]
-            & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
-           == ns32k_opcodes[i].opcode_seed))
-      break;
-  if (i == NOPCODES) {
-    /* Maybe it is 9 to 16 bits big */
-    FETCH_DATA(info, buffer + 2);
-    first_word = read_memory_integer(buffer, 2);
-
-    for (i = 0; i < NOPCODES; i++)
-      if ((first_word
-          & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
-         == ns32k_opcodes[i].opcode_seed)
-       break;
-
-    /* Handle undefined instructions.  */
-    if (i == NOPCODES)
-      {
-       (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
-       return 1;
-      }
-  }
-
-  (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
-
-  ioffset = ns32k_opcodes[i].opcode_size;
-  aoffset = ns32k_opcodes[i].opcode_size;
-  d = ns32k_opcodes[i].operands;
+  int Ivalue;
+  short Ivalue2;
 
-  if (*d)
+  Ivalue = bit_extract (buffer, *aoffsetp, 8);
+  switch (Ivalue & 0xc0)
     {
-      /* 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;
-      
-      (*dis_info->fprintf_func)(dis_info->stream, "\t");
-
-      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);
+    case 0x00:
+    case 0x40:
+      Ivalue = sign_extend (Ivalue, 7);
+      *aoffsetp += 8;
+      break;
+    case 0x80:
+      Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
+      flip_bytes ((char *) & Ivalue2, 2);
+      Ivalue = sign_extend (Ivalue2, 14);
+      *aoffsetp += 16;
+      break;
+    case 0xc0:
+      Ivalue = bit_extract (buffer, *aoffsetp, 32);
+      flip_bytes ((char *) & Ivalue, 4);
+      Ivalue = sign_extend (Ivalue, 30);
+      *aoffsetp += 32;
+      break;
+    }
+  return Ivalue;
+}
 
-         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 1 /* A version that should work on ns32k f's&d's on any machine.  */
+static int
+invalid_float (bfd_byte *p, int len)
+{
+  int val;
+
+  if (len == 4)
+    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_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);
+}
+#else
+/* Assumes the bytes have been swapped to local order.  */
+typedef union
+{
+  double d;
+  float f;
+  struct { unsigned m:23, e:8, :1;} sf;
+  struct { unsigned lm; unsigned m:20, e:11, :1;} sd;
+} float_type_u;
 
-         if (Adrmod_is_index (addr_mode))
-           {
-             aoffset += 8;
-             index_offset[1] = aoffset;
-           }
-       }
+static int
+invalid_float (float_type_u *p, int len)
+{
+  int val;
 
-      while (*d)
-       {
-         argnum = *d - '1';
-         d++;
-         if (argnum > maxarg && argnum < MAX_ARGS)
-           maxarg = argnum;
-         ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
-                                   memaddr, arg_bufs[argnum],
-                                   index_offset[whicharg]);
-         d++;
-         whicharg++;
-       }
-      for (argnum = 0; argnum <= maxarg; argnum++)
-       {
-         bfd_vma addr;
-         char *ch;
-         for (ch = arg_bufs[argnum]; *ch;)
-           {
-             if (*ch == NEXT_IS_ADDR)
-               {
-                 ++ch;
-                 addr = bfd_scan_vma (ch, NULL, 16);
-                 (*dis_info->print_address_func) (addr, dis_info);
-                 while (*ch && *ch != NEXT_IS_ADDR)
-                   ++ch;
-                 if (*ch)
-                   ++ch;
-               }
-             else
-               (*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
-           }
-         if (argnum < maxarg)
-           (*dis_info->fprintf_func)(dis_info->stream, ", ");
-       }
-    }
-  return aoffset / 8;
+  if (len == sizeof (float))
+    val = (p->sf.e == 0xff
+          || (p->sf.e == 0 && p->sf.m != 0));
+  else if (len == sizeof (double))
+    val = (p->sd.e == 0x7ff
+          || (p->sd.e == 0 && (p->sd.m != 0 || p->sd.lm != 0)));
+  else
+    val = 1;
+  return val;
 }
+#endif
 
 /* Print an instruction operand of category given by d.  IOFFSET is
    the bit position below which small (<1 byte) parts of the operand can
@@ -544,31 +446,35 @@ print_insn_ns32k (memaddr, info)
    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
+   of the index byte (it contains -1 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)
-     int d;
-     int ioffset, *aoffsetp;
-     char *buffer;
-     bfd_vma addr;
-     char *result;
-     int index_offset;
+print_insn_arg (int d,
+               int ioffset,
+               int *aoffsetp,
+               bfd_byte *buffer,
+               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;
 
   switch (d)
     {
     case 'f':
-      /* a "gen" operand but 5 bits from the end of instruction */
+      /* A "gen" operand but 5 bits from the end of instruction.  */
       ioffset -= 5;
+      /* Fall through.  */
     case 'Z':
     case 'F':
     case 'L':
@@ -577,13 +483,13 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
     case 'W':
     case 'D':
     case 'A':
-      addr_mode = bit_extract (buffer, ioffset-5, 5);
+      addr_mode = bit_extract (buffer, ioffset - 5, 5);
       ioffset -= 5;
       switch (addr_mode)
        {
        case 0x0: case 0x1: case 0x2: case 0x3:
        case 0x4: case 0x5: case 0x6: case 0x7:
-         /* register mode R0 -- R7 */
+         /* Register mode R0 -- R7.  */
          switch (d)
            {
            case 'F':
@@ -597,34 +503,33 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
          break;
        case 0x8: case 0x9: case 0xa: case 0xb:
        case 0xc: case 0xd: case 0xe: case 0xf:
-         /* Register relative disp(R0 -- R7) */
+         /* Register relative disp(R0 -- R7) */
          disp1 = get_displacement (buffer, aoffsetp);
          sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
          break;
        case 0x10:
        case 0x11:
        case 0x12:
-         /* Memory relative disp2(disp1(FP, SP, SB)) */
+         /* Memory relative disp2(disp1(FP, SP, SB)) */
          disp1 = get_displacement (buffer, aoffsetp);
          disp2 = get_displacement (buffer, aoffsetp);
          sprintf (result, "%d(%d(%s))", disp2, disp1,
-                  addr_mode==0x10?"fp":addr_mode==0x11?"sp":"sb");
+                  addr_mode == 0x10 ? "fp" : addr_mode == 0x11 ? "sp" : "sb");
          break;
        case 0x13:
-         /* reserved */
+         /* Reserved.  */
          sprintf (result, "reserved");
          break;
        case 0x14:
-         /* Immediate */
+         /* Immediate */
          switch (d)
            {
-           case 'I': case 'Z': case 'A':
+           default:
              /* I and Z are output operands and can`t be immediate
-              * A is an address and we can`t have the address of
-              * an immediate either. We don't know how much to increase
-              * aoffsetp by since whatever generated this is broken
-              * anyway!
-              */
+                A is an address and we can`t have the address of
+                an immediate either. We don't know how much to increase
+                aoffsetp by since whatever generated this is broken
+                anyway!  */
              sprintf (result, _("$<undefined>"));
              break;
            case 'B':
@@ -647,58 +552,58 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
              sprintf (result, "$%d", Ivalue);
              break;
            case 'F':
-             bit_copy (buffer, *aoffsetp, 32, (char *) &Fvalue);
-             flip_bytes ((char *) & 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);
-             else /* assume host has ieee float */
-               sprintf (result, "$%g", 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", value.f);
              break;
            case 'L':
-             bit_copy (buffer, *aoffsetp, 64, (char *) &Lvalue);
-             flip_bytes ((char *) & 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);
-             else /* assume host has ieee float */
-               sprintf (result, "$%g", 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", value.d);
              break;
            }
          break;
        case 0x15:
-         /* Absolute @disp */
+         /* Absolute @disp */
          disp1 = get_displacement (buffer, aoffsetp);
          sprintf (result, "@|%d|", disp1);
          break;
        case 0x16:
-         /* External EXT(disp1) + disp2 (Mod table stuff) */
+         /* External EXT(disp1) + disp2 (Mod table stuff) */
          disp1 = get_displacement (buffer, aoffsetp);
          disp2 = get_displacement (buffer, aoffsetp);
          sprintf (result, "EXT(%d) + %d", disp1, disp2);
          break;
        case 0x17:
-         /* Top of stack tos */
+         /* Top of stack tos */
          sprintf (result, "tos");
          break;
        case 0x18:
-         /* Memory space disp(FP) */
+         /* Memory space disp(FP) */
          disp1 = get_displacement (buffer, aoffsetp);
          sprintf (result, "%d(fp)", disp1);
          break;
        case 0x19:
-         /* Memory space disp(SP) */
+         /* Memory space disp(SP) */
          disp1 = get_displacement (buffer, aoffsetp);
          sprintf (result, "%d(sp)", disp1);
          break;
        case 0x1a:
-         /* Memory space disp(SB) */
+         /* Memory space disp(SB) */
          disp1 = get_displacement (buffer, aoffsetp);
          sprintf (result, "%d(sb)", disp1);
          break;
        case 0x1b:
-         /* Memory space disp(PC) */
+         /* Memory space disp(PC) */
          disp1 = get_displacement (buffer, aoffsetp);
          *result++ = NEXT_IS_ADDR;
          sprintf_vma (result, addr + disp1);
@@ -710,17 +615,17 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
        case 0x1d:
        case 0x1e:
        case 0x1f:
-         /* Scaled index basemode[R0 -- R7:B,W,D,Q] */
-         index = bit_extract (buffer, index_offset - 8, 3);
-         print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
-                         result, 0);
          {
+           int bit_index;
            static const char *ind = "bwdq";
            char *off;
 
+           /* Scaled index basemode[R0 -- R7:B,W,D,Q].  */
+           bit_index = bit_extract (buffer, index_offset - 8, 3);
+           print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
+                           result, 0);
            off = result + strlen (result);
-           sprintf (off, "[r%d:%c]", index,
-                    ind[addr_mode & 3]);
+           sprintf (off, "[r%d:%c]", bit_index, ind[addr_mode & 3]);
          }
          break;
        }
@@ -742,22 +647,19 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
       break;
     case 'b':
       Ivalue = get_displacement (buffer, aoffsetp);
-      /*
-       * Warning!!  HACK ALERT!
-       * Operand type 'b' is only used by the cmp{b,w,d} and
-       * movm{b,w,d} instructions; we need to know whether
-       * it's a `b' or `w' or `d' instruction; and for both
-       * cmpm and movm it's stored at the same place so we
-       * just grab two bits of the opcode and look at it...
-       * 
-       */
+      /* Warning!!  HACK ALERT!
+         Operand type 'b' is only used by the cmp{b,w,d} and
+         movm{b,w,d} instructions; we need to know whether
+         it's a `b' or `w' or `d' instruction; and for both
+         cmpm and movm it's stored at the same place so we
+         just grab two bits of the opcode and look at it...  */
       size = bit_extract(buffer, ioffset-6, 2);
-      if (size == 0)           /* 00 => b */
+      if (size == 0)           /* 00 => b */
        size = 1;
-      else if (size == 1)      /* 01 => w */
+      else if (size == 1)      /* 01 => w */
        size = 2;
       else
-       size = 4;               /* 11 => d */
+       size = 4;               /* 11 => d */
 
       sprintf (result, "%d", (Ivalue / size) + 1);
       break;
@@ -775,130 +677,194 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
       break;
     case 'u':
       Ivalue = bit_extract (buffer, *aoffsetp, 8);
-      optlist(Ivalue, opt_u, result);
+      optlist (Ivalue, opt_u, result);
       *aoffsetp += 8;
       break;
     case 'U':
-      Ivalue = bit_extract(buffer, *aoffsetp, 8);
-      optlist(Ivalue, opt_U, result);
+      Ivalue = bit_extract (buffer, *aoffsetp, 8);
+      optlist (Ivalue, opt_U, result);
       *aoffsetp += 8;
       break;
     case 'O':
-      Ivalue = bit_extract(buffer, ioffset-9, 9);
-      optlist(Ivalue, opt_O, result);
+      Ivalue = bit_extract (buffer, ioffset - 9, 9);
+      optlist (Ivalue, opt_O, result);
       ioffset -= 9;
       break;
     case 'C':
-      Ivalue = bit_extract(buffer, ioffset-4, 4);
-      optlist(Ivalue, opt_C, result);
+      Ivalue = bit_extract (buffer, ioffset - 4, 4);
+      optlist (Ivalue, opt_C, result);
       ioffset -= 4;
       break;
     case 'S':
-      Ivalue = bit_extract(buffer, ioffset - 8, 8);
-      optlist(Ivalue, opt_S, result);
+      Ivalue = bit_extract (buffer, ioffset - 8, 8);
+      optlist (Ivalue, opt_S, result);
       ioffset -= 8;
       break;
     case 'M':
-      Ivalue = bit_extract(buffer, ioffset-4, 4);
-      list_search(Ivalue, 0 ? list_M032 : list_M532, result);
+      Ivalue = bit_extract (buffer, ioffset - 4, 4);
+      list_search (Ivalue, 0 ? list_M032 : list_M532, result);
       ioffset -= 4;
       break;
     case 'P':
-      Ivalue = bit_extract(buffer, ioffset-4, 4);
-      list_search(Ivalue, 0 ? list_P032 : list_P532, result);
+      Ivalue = bit_extract (buffer, ioffset - 4, 4);
+      list_search (Ivalue, 0 ? list_P032 : list_P532, result);
       ioffset -= 4;
       break;
     case 'g':
-      Ivalue = bit_extract(buffer, *aoffsetp, 3);
-      sprintf(result, "%d", Ivalue);
+      Ivalue = bit_extract (buffer, *aoffsetp, 3);
+      sprintf (result, "%d", Ivalue);
       *aoffsetp += 3;
       break;
     case 'G':
       Ivalue = bit_extract(buffer, *aoffsetp, 5);
-      sprintf(result, "%d", Ivalue + 1);
+      sprintf (result, "%d", Ivalue + 1);
       *aoffsetp += 5;
       break;
     }
   return ioffset;
 }
 
-static int
-get_displacement (buffer, aoffsetp)
-     char *buffer;
-     int *aoffsetp;
+\f
+/* Print the 32000 instruction at address MEMADDR in debugged memory,
+   on STREAM.  Returns length of the instruction, in bytes.  */
+
+int
+print_insn_ns32k (bfd_vma memaddr, disassemble_info *info)
 {
-  int Ivalue;
-  short Ivalue2;
+  unsigned int i;
+  const char *d;
+  unsigned short first_word;
+  int ioffset;         /* Bits into instruction.  */
+  int aoffset;         /* Bits into arguments.  */
+  char arg_bufs[MAX_ARGS+1][ARG_LEN];
+  int argnum;
+  int maxarg;
+  struct private priv;
+  bfd_byte *buffer = priv.the_buffer;
+  dis_info = info;
 
-  Ivalue = bit_extract (buffer, *aoffsetp, 8);
-  switch (Ivalue & 0xc0)
-    {
-    case 0x00:
-    case 0x40:
-      Ivalue = sign_extend (Ivalue, 7);
-      *aoffsetp += 8;
-      break;
-    case 0x80:
-      Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
-      flip_bytes ((char *) & Ivalue2, 2);
-      Ivalue = sign_extend (Ivalue2, 14);
-      *aoffsetp += 16;
-      break;
-    case 0xc0:
-      Ivalue = bit_extract (buffer, *aoffsetp, 32);
-      flip_bytes ((char *) & Ivalue, 4);
-      Ivalue = sign_extend (Ivalue, 30);
-      *aoffsetp += 32;
+  info->private_data = & priv;
+  priv.max_fetched = priv.the_buffer;
+  priv.insn_start = memaddr;
+  if (OPCODES_SIGSETJMP (priv.bailout) != 0)
+    /* Error return.  */
+    return -1;
+
+  /* Look for 8bit opcodes first. Other wise, fetching two bytes could take
+     us over the end of accessible data unnecessarilly.  */
+  FETCH_DATA (info, buffer + 1);
+  for (i = 0; i < NOPCODES; i++)
+    if (ns32k_opcodes[i].opcode_id_size <= 8
+       && ((buffer[0]
+            & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
+           == ns32k_opcodes[i].opcode_seed))
       break;
+  if (i == NOPCODES)
+    {
+      /* Maybe it is 9 to 16 bits big.  */
+      FETCH_DATA (info, buffer + 2);
+      first_word = read_memory_integer(buffer, 2);
+
+      for (i = 0; i < NOPCODES; i++)
+       if ((first_word
+            & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
+           == ns32k_opcodes[i].opcode_seed)
+         break;
+
+      /* Handle undefined instructions.  */
+      if (i == NOPCODES)
+       {
+         (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
+         return 1;
+       }
     }
-  return Ivalue;
-}
-\f
 
-#if 1 /* a version that should work on ns32k f's&d's on any machine */
-static int
-invalid_float (p, len)
-     register char *p;
-     register int len;
-{
-  register int val;
-
-  if ( len == 4 )
-    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_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);
-}
-#else
+  (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
 
-/* assumes the bytes have been swapped to local order */
-typedef union { double d;
-               float f;
-               struct { unsigned m:23, e:8, :1;} sf;
-               struct { unsigned lm; unsigned m:20, e:11, :1;} sd;
-             } float_type_u;
+  ioffset = ns32k_opcodes[i].opcode_size;
+  aoffset = ns32k_opcodes[i].opcode_size;
+  d = ns32k_opcodes[i].operands;
 
-static int
-invalid_float (p, len)
-     register float_type_u *p;
-     register int len;
-{
-  register int val;
-  if ( len == sizeof (float) )
-    val = (p->sf.e == 0xff
-          || (p->sf.e == 0 && p->sf.m != 0));
-  else if ( len == sizeof (double) )
-    val = (p->sd.e == 0x7ff
-          || (p->sd.e == 0 && (p->sd.m != 0 || p->sd.lm != 0)));
-  else
-    val = 1;
-  return (val);
+  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.  */
+      int index_offset[2];
+
+      /* 0 for operand A, 1 for operand B, greater for other args.  */
+      int whicharg = 0;
+
+      (*dis_info->fprintf_func)(dis_info->stream, "\t");
+
+      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.  */
+      index_offset[0] = -1;
+      index_offset[1] = -1;
+      if (Is_gen (d[1]))
+       {
+         int bitoff = d[1] == 'f' ? 10 : 5;
+         int addr_mode = bit_extract (buffer, ioffset - bitoff, 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 >= MAX_ARGS)
+           abort ();
+         d++;
+         if (argnum > maxarg)
+           maxarg = argnum;
+         ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
+                                   memaddr, arg_bufs[argnum],
+                                   whicharg > 1 ? -1 : index_offset[whicharg]);
+         d++;
+         whicharg++;
+       }
+
+      for (argnum = 0; argnum <= maxarg; argnum++)
+       {
+         bfd_vma addr;
+         char *ch;
+
+         for (ch = arg_bufs[argnum]; *ch;)
+           {
+             if (*ch == NEXT_IS_ADDR)
+               {
+                 ++ch;
+                 addr = bfd_scan_vma (ch, NULL, 16);
+                 (*dis_info->print_address_func) (addr, dis_info);
+                 while (*ch && *ch != NEXT_IS_ADDR)
+                   ++ch;
+                 if (*ch)
+                   ++ch;
+               }
+             else
+               (*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
+           }
+         if (argnum < maxarg)
+           (*dis_info->fprintf_func)(dis_info->stream, ", ");
+       }
+    }
+  return aoffset / 8;
 }
-#endif
This page took 0.038519 seconds and 4 git commands to generate.