Multi-target: NEWS and user manual
[deliverable/binutils-gdb.git] / opcodes / arc-dis.c
index 71acc10b42f60005eda9a7585c558c20f8a87064..ac8d6aa750018eae1de5db9c6b4a4b6f35d8f7bd 100644 (file)
@@ -1,5 +1,5 @@
 /* Instruction printing code for the ARC.
-   Copyright (C) 1994-2017 Free Software Foundation, Inc.
+   Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
    Contributed by Claudiu Zissulescu (claziss@synopsys.com)
 
@@ -137,8 +137,7 @@ static bfd_boolean print_hex = FALSE;
   (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf))   \
    : bfd_getb32 (buf))
 
-#define BITS(word,s,e)  (((word) << (sizeof (word) * 8 - 1 - e)) >>    \
-                        (s + (sizeof (word) * 8 - 1 - e)))
+#define BITS(word,s,e)  (((word) >> (s)) & ((1ull << ((e) - (s)) << 1) - 1))
 #define OPCODE_32BIT_INSN(word)        (BITS ((word), 27, 31))
 
 /* Functions implementation.  */
@@ -181,7 +180,9 @@ skip_this_opcode (const struct arc_opcode *opcode)
 
   /* Check opcode for major 0x06, return if it is not in.  */
   if (arc_opcode_len (opcode) == 4
-      && OPCODE_32BIT_INSN (opcode->opcode) != 0x06)
+      && (OPCODE_32BIT_INSN (opcode->opcode) != 0x06
+         /* Can be an APEX extensions.  */
+         && OPCODE_32BIT_INSN (opcode->opcode) != 0x07))
     return FALSE;
 
   /* or not a known truble class.  */
@@ -190,6 +191,7 @@ skip_this_opcode (const struct arc_opcode *opcode)
     case FLOAT:
     case DSP:
     case ARITH:
+    case MPY:
       break;
     default:
       return FALSE;
@@ -292,7 +294,7 @@ find_format_from_table (struct disassemble_info *info,
          if (operand->extract)
            value = (*operand->extract) (insn, &invalid);
          else
-           value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
+           value = (insn >> operand->shift) & ((1ull << operand->bits) - 1);
 
          /* Check for LIMM indicator.  If it is there, then make sure
             we pick the right format.  */
@@ -669,7 +671,7 @@ arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
       break;
 
     default:
-      abort ();
+      return 0;
     }
 }
 
@@ -764,6 +766,23 @@ parse_option (const char *option)
   else if (disassembler_options_cmp (option, "fpuda") == 0)
     add_to_decodelist (FLOAT, DPA);
 
+  else if (disassembler_options_cmp (option, "nps400") == 0)
+    {
+      add_to_decodelist (ACL, NPS400);
+      add_to_decodelist (ARITH, NPS400);
+      add_to_decodelist (BITOP, NPS400);
+      add_to_decodelist (BMU, NPS400);
+      add_to_decodelist (CONTROL, NPS400);
+      add_to_decodelist (DMA, NPS400);
+      add_to_decodelist (DPI, NPS400);
+      add_to_decodelist (MEMORY, NPS400);
+      add_to_decodelist (MISC, NPS400);
+      add_to_decodelist (NET, NPS400);
+      add_to_decodelist (PMU, NPS400);
+      add_to_decodelist (PROTOCOL_DECODE, NPS400);
+      add_to_decodelist (ULTRAIP, NPS400);
+    }
+
   else if (disassembler_options_cmp (option, "fpus") == 0)
     {
       add_to_decodelist (FLOAT, SP);
@@ -778,7 +797,8 @@ parse_option (const char *option)
   else if (CONST_STRNEQ (option, "hex"))
     print_hex = TRUE;
   else
-    fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
+    /* xgettext:c-format */
+    opcodes_error_handler (_("unrecognised disassembler option: %s"), option);
 }
 
 #define ARC_CPU_TYPE_A6xx(NAME,EXTRA)                  \
@@ -820,7 +840,8 @@ parse_cpu_option (const char *option)
        }
     }
 
-  fprintf (stderr, _("Unrecognised disassembler CPU option: %s\n"), option);
+  /* xgettext:c-format */
+  opcodes_error_handler (_("unrecognised disassembler CPU option: %s"), option);
   return ARC_OPCODE_NONE;
 }
 
@@ -987,7 +1008,6 @@ print_insn_arc (bfd_vma memaddr,
      the number of bytes objdump should display on a single line.  If
      the instruction decoder sets this, it should always set it to
      the same value in order to get reasonable looking output.  */
-
   info->bytes_per_line  = 8;
 
   /* In the next lines, we set two info variables control the way
@@ -995,7 +1015,6 @@ print_insn_arc (bfd_vma memaddr,
      8 and bytes_per_chunk is 4, the output will look like this:
      00:   00000000 00000000
      with the chunks displayed according to "display_endian".  */
-
   if (info->section
       && !(info->section->flags & SEC_CODE))
     {
@@ -1050,13 +1069,16 @@ print_insn_arc (bfd_vma memaddr,
          (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data);
          break;
        default:
-         abort ();
+         return -1;
        }
       return size;
     }
 
   insn_len = arc_insn_length (buffer[highbyte], buffer[lowbyte], info);
   pr_debug ("instruction length = %d bytes\n", insn_len);
+  if (insn_len == 0)
+    return -1;
+
   arc_infop = info->private_data;
   arc_infop->insn_len = insn_len;
 
@@ -1109,7 +1131,7 @@ print_insn_arc (bfd_vma memaddr,
 
     default:
       /* There is no instruction whose length is not 2, 4, 6, or 8.  */
-      abort ();
+      return -1;
     }
 
   pr_debug ("instruction value = %llx\n", insn);
@@ -1137,24 +1159,28 @@ print_insn_arc (bfd_vma memaddr,
          (*info->fprintf_func) (info->stream, ".shor\t%#04llx",
                                 insn & 0xffff);
          break;
+
        case 4:
          (*info->fprintf_func) (info->stream, ".word\t%#08llx",
                                 insn & 0xffffffff);
          break;
+
        case 6:
          (*info->fprintf_func) (info->stream, ".long\t%#08llx",
                                 insn & 0xffffffff);
          (*info->fprintf_func) (info->stream, ".long\t%#04llx",
                                 (insn >> 32) & 0xffff);
          break;
+
        case 8:
          (*info->fprintf_func) (info->stream, ".long\t%#08llx",
                                 insn & 0xffffffff);
          (*info->fprintf_func) (info->stream, ".long\t%#08llx",
                                 insn >> 32);
          break;
+
        default:
-         abort ();
+         return -1;
        }
 
       info->insn_type = dis_noninsn;
@@ -1409,6 +1435,8 @@ with -M switch (multiple options should be separated by commas):\n"));
   fprintf (stream, _("\
   fpud            Recognize double precision FPU instructions.\n"));
   fprintf (stream, _("\
+  nps400          Recognize NPS400 instructions.\n"));
+  fprintf (stream, _("\
   hex             Use only hexadecimal number to print immediates.\n"));
 }
 
This page took 0.025243 seconds and 4 git commands to generate.