*** empty log message ***
[deliverable/binutils-gdb.git] / opcodes / ns32k-dis.c
index 808fdd204e3117e1d4352f4f5c5d37ddfd37b000..fe7144ae5054840857025e526bcb5d4a6e9ef82d 100644 (file)
@@ -1,5 +1,6 @@
 /* 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.
 
@@ -15,7 +16,7 @@ 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 
 #include "bfd.h"
@@ -25,15 +26,30 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #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;
@@ -98,14 +114,14 @@ fetch_data (info, addr)
 #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    },
@@ -118,7 +134,7 @@ static struct option opt_u[]= /* restore, exit */
   {  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    },
@@ -131,7 +147,7 @@ static struct option opt_U[]= /* save, enter */
   {  0 ,       0x00,   0x00    }
 };
 
-static struct option opt_O[]= /* setcfg */
+static const struct ns32k_option opt_O[]= /* setcfg */
 {
   { "c",       0x8,    0x8     },
   { "m",       0x4,    0x4     },
@@ -140,7 +156,7 @@ static struct option opt_O[]= /* setcfg */
   {  0 ,       0x0,    0x0     }
 };
 
-static struct option opt_C[]= /* cinv */
+static const struct ns32k_option opt_C[]= /* cinv */
 {
   { "a",       0x4,    0x4     },
   { "i",       0x2,    0x2     },
@@ -148,7 +164,7 @@ static struct option opt_C[]= /* cinv */
   {  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     },
@@ -156,7 +172,7 @@ static struct option opt_S[]= /* string inst */
   {  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     },
@@ -174,7 +190,7 @@ static struct option list_P532[]= /* lpr spr */
   {  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     },
@@ -186,7 +202,7 @@ static struct option list_M532[]= /* lmr smr */
   {  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     },
@@ -198,7 +214,7 @@ static struct option list_P032[]= /* lpr spr */
   {  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     },
@@ -219,9 +235,9 @@ static struct option list_M032[]= /* lmr smr */
  */
 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, "[]");
@@ -244,10 +260,11 @@ optlist(options, optionP, 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) {
@@ -270,7 +287,6 @@ bit_extract (buffer, offset, count)
      int count;
 {
   int result;
-  int mask;
   int bit;
 
   buffer += offset >> 3;
@@ -292,6 +308,36 @@ bit_extract (buffer, offset, count)
   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;
@@ -305,7 +351,8 @@ bit_copy (buffer, offset, count, to)
 }
 
 
-static sign_extend (value, bits)
+static int
+sign_extend (value, bits)
      int value, bits;
 {
   value = value & ((1 << bits) - 1);
@@ -314,7 +361,8 @@ static sign_extend (value, bits)
          : value);
 }
 
-static flip_bytes (ptr, count)
+static void
+flip_bytes (ptr, count)
      char *ptr;
      int count;
 {
@@ -357,11 +405,9 @@ print_insn_ns32k (memaddr, info)
      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];
@@ -384,7 +430,8 @@ print_insn_ns32k (memaddr, info)
   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) {
@@ -393,7 +440,8 @@ print_insn_ns32k (memaddr, info)
     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;
 
@@ -465,14 +513,14 @@ print_insn_ns32k (memaddr, info)
        }
       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;
@@ -499,18 +547,22 @@ print_insn_ns32k (memaddr, info)
    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;
@@ -576,7 +628,7 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
               * aoffsetp by since whatever generated this is broken
               * anyway!
               */
-             sprintf (result, "$<undefined>");
+             sprintf (result, _("$<undefined>"));
              break;
            case 'B':
              Ivalue = bit_extract (buffer, *aoffsetp, 8);
@@ -586,35 +638,35 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
              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;
@@ -651,7 +703,11 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
        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:
@@ -662,11 +718,11 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
          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;
@@ -709,9 +765,11 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
       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);
@@ -767,6 +825,7 @@ print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result, index_offset)
   return ioffset;
 }
 
+static int
 get_displacement (buffer, aoffsetp)
      char *buffer;
      int *aoffsetp;
@@ -784,13 +843,13 @@ get_displacement (buffer, 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;
@@ -800,21 +859,22 @@ get_displacement (buffer, aoffsetp)
 \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);
@@ -828,7 +888,8 @@ typedef union { double d;
                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;
 {
This page took 0.029759 seconds and 4 git commands to generate.