Power10 Set boolean extension
[deliverable/binutils-gdb.git] / opcodes / ns32k-dis.c
index dd52cffc0795294fbb53394e6cb5afa8f0dd467e..12df182d0a442bec0f222741126739130f7dd4c1 100644 (file)
@@ -1,5 +1,5 @@
 /* Print National Semiconductor 32000 instructions.
 /* Print National Semiconductor 32000 instructions.
-   Copyright (C) 1986-2016 Free Software Foundation, Inc.
+   Copyright (C) 1986-2020 Free Software Foundation, Inc.
 
    This file is part of the GNU opcodes library.
 
 
    This file is part of the GNU opcodes library.
 
@@ -20,7 +20,7 @@
 
 #include "sysdep.h"
 #include "bfd.h"
 
 #include "sysdep.h"
 #include "bfd.h"
-#include "dis-asm.h"
+#include "disassemble.h"
 #if !defined(const) && !defined(__STDC__)
 #define const
 #endif
 #if !defined(const) && !defined(__STDC__)
 #define const
 #endif
@@ -262,9 +262,11 @@ list_search (int reg_value, const struct ns32k_option *optionP, char *result)
 static int
 bit_extract (bfd_byte *buffer, int offset, int count)
 {
 static int
 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;
   buffer += offset >> 3;
   offset &= 7;
   bit = 1;
@@ -289,9 +291,11 @@ bit_extract (bfd_byte *buffer, int offset, int count)
 static int
 bit_extract_simple (bfd_byte *buffer, int offset, int count)
 {
 static int
 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;
   buffer += offset >> 3;
   offset &= 7;
   bit = 1;
@@ -313,18 +317,18 @@ bit_extract_simple (bfd_byte *buffer, int offset, int count)
 static void
 bit_copy (bfd_byte *buffer, int offset, int count, char *to)
 {
 static void
 bit_copy (bfd_byte *buffer, int offset, int count, char *to)
 {
+  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
   for (; count > 8; count -= 8, to++, offset += 8)
     *to = bit_extract (buffer, offset, 8);
   *to = bit_extract (buffer, offset, count);
 }
 
 static int
-sign_extend (int value, int 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
 }
 
 static void
@@ -343,9 +347,7 @@ flip_bytes (char *ptr, int count)
 }
 \f
 /* Given a character C, does it represent a general addressing mode?  */
 }
 \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
 
 /* Adressing modes.  */
 #define Adrmod_index_byte        0x1c
@@ -444,7 +446,7 @@ invalid_float (float_type_u *p, int len)
    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
    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
    general operand using scaled indexed addressing mode).  */
 
 static int
@@ -472,6 +474,7 @@ print_insn_arg (int d,
     case 'f':
       /* A "gen" operand but 5 bits from the end of instruction.  */
       ioffset -= 5;
     case 'f':
       /* A "gen" operand but 5 bits from the end of instruction.  */
       ioffset -= 5;
+      /* Fall through.  */
     case 'Z':
     case 'F':
     case 'L':
     case 'Z':
     case 'F':
     case 'L':
@@ -787,10 +790,8 @@ print_insn_ns32k (bfd_vma memaddr, disassemble_info *info)
   if (*d)
     {
       /* Offset in bits of the first thing beyond each index byte.
   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];
+        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;
 
       /* 0 for operand A, 1 for operand B, greater for other args.  */
       int whicharg = 0;
@@ -803,9 +804,12 @@ print_insn_ns32k (bfd_vma memaddr, disassemble_info *info)
         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 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]))
+      index_offset[0] = -1;
+      index_offset[1] = -1;
+      if (Is_gen (d[1]))
        {
        {
-         int addr_mode = bit_extract (buffer, ioffset - 5, 5);
+         int bitoff = d[1] == 'f' ? 10 : 5;
+         int addr_mode = bit_extract (buffer, ioffset - bitoff, 5);
 
          if (Adrmod_is_index (addr_mode))
            {
 
          if (Adrmod_is_index (addr_mode))
            {
@@ -814,7 +818,7 @@ print_insn_ns32k (bfd_vma memaddr, disassemble_info *info)
            }
        }
 
            }
        }
 
-      if (d[2] && Is_gen(d[3]))
+      if (d[2] && Is_gen (d[3]))
        {
          int addr_mode = bit_extract (buffer, ioffset - 10, 5);
 
        {
          int addr_mode = bit_extract (buffer, ioffset - 10, 5);
 
@@ -828,15 +832,18 @@ print_insn_ns32k (bfd_vma memaddr, disassemble_info *info)
       while (*d)
        {
          argnum = *d - '1';
       while (*d)
        {
          argnum = *d - '1';
+         if (argnum >= MAX_ARGS)
+           abort ();
          d++;
          d++;
-         if (argnum > maxarg && argnum < MAX_ARGS)
+         if (argnum > maxarg)
            maxarg = argnum;
          ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
                                    memaddr, arg_bufs[argnum],
            maxarg = argnum;
          ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
                                    memaddr, arg_bufs[argnum],
-                                   index_offset[whicharg]);
+                                   whicharg > 1 ? -1 : index_offset[whicharg]);
          d++;
          whicharg++;
        }
          d++;
          whicharg++;
        }
+
       for (argnum = 0; argnum <= maxarg; argnum++)
        {
          bfd_vma addr;
       for (argnum = 0; argnum <= maxarg; argnum++)
        {
          bfd_vma addr;
This page took 0.026561 seconds and 4 git commands to generate.