Add support for .extCondCode, .extCoreRegister and .extAuxRegister.
[deliverable/binutils-gdb.git] / opcodes / arc-opc.c
index db11a1fd78164c725cbe2ca6e44ed2918c0e49c5..5603ded68cb88e7d3758d9d90cbdbb67e7e3d934 100644 (file)
@@ -1,5 +1,5 @@
 /* Opcode table for the ARC.
-   Copyright (C) 1994-2015 Free Software Foundation, Inc.
+   Copyright (C) 1994-2016 Free Software Foundation, Inc.
 
    Contributed by Claudiu Zissulescu (claziss@synopsys.com)
 
 #include "opintl.h"
 #include "libiberty.h"
 
+/* ARC NPS400 Support: The ARC NPS400 core is an ARC700 with some custom
+   instructions.  Support for this target is available when binutils is
+   configured and built for the 'arc*-mellanox-*-*' target.  As far as
+   possible all ARC NPS400 features are built into all ARC target builds as
+   this reduces the chances that regressions might creep in.  */
+
 /* Insert RB register into a 32-bit opcode.  */
 static unsigned
 insert_rb (unsigned insn,
@@ -637,14 +643,206 @@ extract_g_s (unsigned insn ATTRIBUTE_UNUSED,
   return value;
 }
 
+/* ARC NPS400 Support: See comment near head of file.  */
+static unsigned
+insert_nps_3bit_dst (unsigned insn ATTRIBUTE_UNUSED,
+                     int value ATTRIBUTE_UNUSED,
+                     const char **errmsg ATTRIBUTE_UNUSED)
+{
+  switch (value)
+    {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+      insn |= value << 24;
+      break;
+    case 12:
+    case 13:
+    case 14:
+    case 15:
+      insn |= (value - 8) << 24;
+      break;
+    default:
+      *errmsg = _("Register must be either r0-r3 or r12-r15.");
+      break;
+    }
+  return insn;
+}
+
+static int
+extract_nps_3bit_dst (unsigned insn ATTRIBUTE_UNUSED,
+                      bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = (insn >> 24) & 0x07;
+  if (value > 3)
+    return (value + 8);
+  else
+    return value;
+}
+
+static unsigned
+insert_nps_3bit_src2 (unsigned insn ATTRIBUTE_UNUSED,
+                      int value ATTRIBUTE_UNUSED,
+                      const char **errmsg ATTRIBUTE_UNUSED)
+{
+  switch (value)
+    {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+      insn |= value << 21;
+      break;
+    case 12:
+    case 13:
+    case 14:
+    case 15:
+      insn |= (value - 8) << 21;
+      break;
+    default:
+      *errmsg = _("Register must be either r0-r3 or r12-r15.");
+      break;
+    }
+  return insn;
+}
+
+static int
+extract_nps_3bit_src2 (unsigned insn ATTRIBUTE_UNUSED,
+                       bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = (insn >> 21) & 0x07;
+  if (value > 3)
+    return (value + 8);
+  else
+    return value;
+}
+
+static unsigned
+insert_nps_bitop_size (unsigned insn ATTRIBUTE_UNUSED,
+                      int value ATTRIBUTE_UNUSED,
+                      const char **errmsg ATTRIBUTE_UNUSED)
+{
+  if (value < 1 || value > 32)
+    {
+      *errmsg = _("Invalid bit size, should be between 1 and 32 inclusive.");
+      return insn;
+    }
+
+  --value;
+  insn |= ((value & 0x1f) << 10);
+  return insn;
+}
+
+static int
+extract_nps_bitop_size (unsigned insn ATTRIBUTE_UNUSED,
+                       bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return ((insn >> 10) & 0x1f) + 1;
+}
+
+static unsigned
+insert_nps_bitop_size_2b (unsigned insn ATTRIBUTE_UNUSED,
+                          int value ATTRIBUTE_UNUSED,
+                          const char **errmsg ATTRIBUTE_UNUSED)
+{
+  switch (value)
+    {
+    case 1:
+      value = 0;
+      break;
+    case 2:
+      value = 1;
+      break;
+    case 4:
+      value = 2;
+      break;
+    case 8:
+      value = 3;
+      break;
+    default:
+      value = 0;
+      *errmsg = _("Invalid size, should be 1, 2, 4, or 8.");
+      break;
+    }
+
+  insn |= value << 10;
+  return insn;
+}
+
+static int
+extract_nps_bitop_size_2b (unsigned insn ATTRIBUTE_UNUSED,
+                           bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return  1 << ((insn >> 10) & 0x3);
+}
+
+static unsigned
+insert_nps_bitop_uimm8 (unsigned insn ATTRIBUTE_UNUSED,
+                        int value ATTRIBUTE_UNUSED,
+                        const char **errmsg ATTRIBUTE_UNUSED)
+{
+  insn |= ((value >> 5) & 7) << 12;
+  insn |= (value & 0x1f);
+  return insn;
+}
+
+static int
+extract_nps_bitop_uimm8 (unsigned insn ATTRIBUTE_UNUSED,
+                         bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return (((insn >> 12) & 0x7) << 5) | (insn & 0x1f);
+}
+
+static unsigned
+insert_nps_rflt_uimm6 (unsigned insn ATTRIBUTE_UNUSED,
+                       int value ATTRIBUTE_UNUSED,
+                       const char **errmsg ATTRIBUTE_UNUSED)
+{
+  switch (value)
+    {
+    case 1:
+    case 2:
+    case 4:
+      break;
+
+    default:
+      *errmsg = _("invalid immediate, must be 1, 2, or 4");
+      value = 0;
+    }
+
+  insn |= (value << 6);
+  return insn;
+}
+
+static int
+extract_nps_rflt_uimm6 (unsigned insn ATTRIBUTE_UNUSED,
+                         bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return (insn >> 6) & 0x3f;
+}
+
+static unsigned
+insert_nps_dst_pos_and_size (unsigned insn ATTRIBUTE_UNUSED,
+                             int value ATTRIBUTE_UNUSED,
+                             const char **errmsg ATTRIBUTE_UNUSED)
+{
+  insn |= ((value & 0x1f) | (((32 - value - 1) & 0x1f) << 10));
+  return insn;
+}
+
+static int
+extract_nps_dst_pos_and_size (unsigned insn ATTRIBUTE_UNUSED,
+                              bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return (insn & 0x1f);
+}
+
 /* Include the generic extract/insert functions.  Order is important
    as some of the functions present in the .h may be disabled via
    defines.  */
 #include "arc-fxi.h"
 
-/* Abbreviations for instruction subsets.  */
-#define BASE                   ARC_OPCODE_BASE
-
 /* The flag operands table.
 
    The format of the table is
@@ -795,6 +993,47 @@ const struct arc_flag_operand arc_flag_operands[] =
   /* Fake Flags.  */
 #define F_NE   (F_H17 + 1)
   { "ne", 0, 0, 0, 1 },
+
+  /* ARC NPS400 Support: See comment near head of file.  */
+#define F_NPS_CL (F_NE + 1)
+  { "cl", 0, 0, 0, 1 },
+
+#define F_NPS_FLAG (F_NPS_CL + 1)
+  { "f", 1, 1, 20, 1 },
+
+#define F_NPS_R     (F_NPS_FLAG + 1)
+  { "r",  1, 1, 15, 1 },
+
+#define F_NPS_RW     (F_NPS_R + 1)
+  { "rw", 0, 1, 7, 1 },
+
+#define F_NPS_RD     (F_NPS_RW + 1)
+  { "rd", 1, 1, 7, 1 },
+
+#define F_NPS_WFT     (F_NPS_RD + 1)
+  { "wft", 0, 0, 0, 1 },
+
+#define F_NPS_IE1     (F_NPS_WFT + 1)
+  { "ie1", 1, 2, 8, 1 },
+
+#define F_NPS_IE2     (F_NPS_IE1 + 1)
+  { "ie2", 2, 2, 8, 1 },
+
+#define F_NPS_IE12     (F_NPS_IE2 + 1)
+  { "ie12", 3, 2, 8, 1 },
+
+#define F_NPS_SYNC_RD     (F_NPS_IE12 + 1)
+  { "rd", 0, 1, 6, 1 },
+
+#define F_NPS_SYNC_WR     (F_NPS_SYNC_RD + 1)
+  { "wr", 1, 1, 6, 1 },
+
+#define F_NPS_HWS_OFF     (F_NPS_SYNC_WR + 1)
+  { "off", 0, 0, 0, 1 },
+
+#define F_NPS_HWS_RESTORE     (F_NPS_HWS_OFF + 1)
+  { "restore", 0, 0, 0, 1 },
+
 };
 
 const unsigned arc_num_flag_operands = ARRAY_SIZE (arc_flag_operands);
@@ -806,67 +1045,103 @@ const unsigned arc_num_flag_operands = ARRAY_SIZE (arc_flag_operands);
 const struct arc_flag_class arc_flag_classes[] =
 {
 #define C_EMPTY     0
-  { FNONE, { F_NULL } },
+  { F_CLASS_NONE, { F_NULL } },
 
 #define C_CC       (C_EMPTY + 1)
-  { CND, { F_ALWAYS, F_RA, F_EQUAL, F_ZERO, F_NOTEQUAL, F_NOTZERO,
-          F_POZITIVE, F_PL, F_NEGATIVE, F_MINUS, F_CARRY, F_CARRYSET,
-          F_LOWER, F_CARRYCLR, F_NOTCARRY, F_HIGHER, F_OVERFLOWSET,
-          F_OVERFLOW, F_NOTOVERFLOW, F_OVERFLOWCLR, F_GT, F_GE, F_LT,
-          F_LE, F_HI, F_LS, F_PNZ, F_NULL } },
+  { F_CLASS_OPTIONAL | F_CLASS_EXTEND,
+    { F_ALWAYS, F_RA, F_EQUAL, F_ZERO, F_NOTEQUAL,
+      F_NOTZERO, F_POZITIVE, F_PL, F_NEGATIVE, F_MINUS,
+      F_CARRY, F_CARRYSET, F_LOWER, F_CARRYCLR,
+      F_NOTCARRY, F_HIGHER, F_OVERFLOWSET, F_OVERFLOW,
+      F_NOTOVERFLOW, F_OVERFLOWCLR, F_GT, F_GE, F_LT,
+      F_LE, F_HI, F_LS, F_PNZ, F_NULL } },
 
 #define C_AA_ADDR3  (C_CC + 1)
 #define C_AA27     (C_CC + 1)
-  { WBM, { F_A3, F_AW3, F_AB3, F_AS3, F_NULL } },
+  { F_CLASS_OPTIONAL, { F_A3, F_AW3, F_AB3, F_AS3, F_NULL } },
 #define C_AA_ADDR9  (C_AA_ADDR3 + 1)
 #define C_AA21      (C_AA_ADDR3 + 1)
-  { WBM, { F_A9, F_AW9, F_AB9, F_AS9, F_NULL } },
+  { F_CLASS_OPTIONAL, { F_A9, F_AW9, F_AB9, F_AS9, F_NULL } },
 #define C_AA_ADDR22 (C_AA_ADDR9 + 1)
 #define C_AA8     (C_AA_ADDR9 + 1)
-  { WBM, { F_A22, F_AW22, F_AB22, F_AS22, F_NULL } },
+  { F_CLASS_OPTIONAL, { F_A22, F_AW22, F_AB22, F_AS22, F_NULL } },
 
 #define C_F        (C_AA_ADDR22 + 1)
-  { FLG, { F_FLAG, F_NULL } },
+  { F_CLASS_OPTIONAL, { F_FLAG, F_NULL } },
 #define C_FHARD            (C_F + 1)
-  { FLG, { F_FFAKE, F_NULL } },
+  { F_CLASS_OPTIONAL, { F_FFAKE, F_NULL } },
 
 #define C_T        (C_FHARD + 1)
-  { SBP, { F_NT, F_T, F_NULL } },
+  { F_CLASS_OPTIONAL, { F_NT, F_T, F_NULL } },
 #define C_D        (C_T + 1)
-  { DLY, { F_ND, F_D, F_NULL } },
+  { F_CLASS_OPTIONAL, { F_ND, F_D, F_NULL } },
 
 #define C_DHARD            (C_D + 1)
-  { DLY, { F_DFAKE, F_NULL } },
+  { F_CLASS_OPTIONAL, { F_DFAKE, F_NULL } },
 
 #define C_DI20     (C_DHARD + 1)
-  { DIF, { F_DI11, F_NULL }},
+  { F_CLASS_OPTIONAL, { F_DI11, F_NULL }},
 #define C_DI16     (C_DI20 + 1)
-  { DIF, { F_DI15, F_NULL }},
+  { F_CLASS_OPTIONAL, { F_DI15, F_NULL }},
 #define C_DI26     (C_DI16 + 1)
-  { DIF, { F_DI5, F_NULL }},
+  { F_CLASS_OPTIONAL, { F_DI5, F_NULL }},
 
 #define C_X25      (C_DI26 + 1)
-  { SGX, { F_SIGN6, F_NULL }},
+  { F_CLASS_OPTIONAL, { F_SIGN6, F_NULL }},
 #define C_X15     (C_X25 + 1)
-  { SGX, { F_SIGN16, F_NULL }},
+  { F_CLASS_OPTIONAL, { F_SIGN16, F_NULL }},
 #define C_XHARD           (C_X15 + 1)
 #define C_X       (C_X15 + 1)
-  { SGX, { F_SIGNX, F_NULL }},
+  { F_CLASS_OPTIONAL, { F_SIGNX, F_NULL }},
 
 #define C_ZZ13       (C_X + 1)
-  { SZM, { F_SIZEB17, F_SIZEW17, F_H17, F_NULL}},
+  { F_CLASS_OPTIONAL, { F_SIZEB17, F_SIZEW17, F_H17, F_NULL}},
 #define C_ZZ23       (C_ZZ13 + 1)
-  { SZM, { F_SIZEB7, F_SIZEW7, F_H7, F_NULL}},
+  { F_CLASS_OPTIONAL, { F_SIZEB7, F_SIZEW7, F_H7, F_NULL}},
 #define C_ZZ29       (C_ZZ23 + 1)
-  { SZM, { F_SIZEB1, F_SIZEW1, F_H1, F_NULL}},
+  { F_CLASS_OPTIONAL, { F_SIZEB1, F_SIZEW1, F_H1, F_NULL}},
 
 #define C_AS       (C_ZZ29 + 1)
-  { SZM, { F_ASFAKE, F_NULL}},
+  { F_CLASS_OPTIONAL, { F_ASFAKE, F_NULL}},
 
 #define C_NE       (C_AS + 1)
-  { CND, { F_NE, F_NULL}},
+  { F_CLASS_OPTIONAL, { F_NE, F_NULL}},
+
+  /* ARC NPS400 Support: See comment near head of file.  */
+#define C_NPS_CL     (C_NE + 1)
+  { F_CLASS_REQUIRED, { F_NPS_CL, F_NULL}},
+
+#define C_NPS_F     (C_NPS_CL + 1)
+  { F_CLASS_OPTIONAL, { F_NPS_FLAG, F_NULL}},
+
+#define C_NPS_R     (C_NPS_F + 1)
+  { F_CLASS_OPTIONAL, { F_NPS_R, F_NULL}},
+
+#define C_NPS_SCHD_RW     (C_NPS_R + 1)
+  { F_CLASS_REQUIRED, { F_NPS_RW, F_NPS_RD, F_NULL}},
+
+#define C_NPS_SCHD_TRIG     (C_NPS_SCHD_RW + 1)
+  { F_CLASS_REQUIRED, { F_NPS_WFT, F_NULL}},
+
+#define C_NPS_SCHD_IE     (C_NPS_SCHD_TRIG + 1)
+  { F_CLASS_OPTIONAL, { F_NPS_IE1, F_NPS_IE2, F_NPS_IE12, F_NULL}},
+
+#define C_NPS_SYNC     (C_NPS_SCHD_IE + 1)
+  { F_CLASS_REQUIRED, { F_NPS_SYNC_RD, F_NPS_SYNC_WR, F_NULL}},
+
+#define C_NPS_HWS_OFF     (C_NPS_SYNC + 1)
+  { F_CLASS_REQUIRED, { F_NPS_HWS_OFF, F_NULL}},
+
+#define C_NPS_HWS_RESTORE     (C_NPS_HWS_OFF + 1)
+  { F_CLASS_REQUIRED, { F_NPS_HWS_RESTORE, F_NULL}},
+
 };
 
+const unsigned char flags_none[] = { 0 };
+const unsigned char flags_f[]    = { C_F };
+const unsigned char flags_cc[]   = { C_CC };
+const unsigned char flags_ccf[]  = { C_CC, C_F };
+
 /* The operands table.
 
    The format of the operands table is:
@@ -938,11 +1213,11 @@ const struct arc_operand arc_operands[] =
 #define R3             (R2 + 1)
 #define R3_S           (R2 + 1)
   { 2, 0, 0, ARC_OPERAND_IR, insert_r3, extract_r3 },
-#define SP             (R3 + 1)
+#define RSP            (R3 + 1)
 #define SP_S           (R3 + 1)
   { 5, 0, 0, ARC_OPERAND_IR, insert_sp, extract_sp },
-#define SPdup          (SP + 1)
-#define SP_Sdup                (SP + 1)
+#define SPdup          (RSP + 1)
+#define SP_Sdup                (RSP + 1)
   { 5, 0, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE, insert_sp, extract_sp },
 #define GP             (SPdup + 1)
 #define GP_S           (SPdup + 1)
@@ -1183,6 +1458,46 @@ const struct arc_operand arc_operands[] =
   /* UIMM6_5_S mask = 0000011111100000.  */
 #define UIMM6_5_S      (W6 + 1)
   {6, 0, 0, ARC_OPERAND_UNSIGNED, insert_uimm6_5_s, extract_uimm6_5_s},
+
+  /* ARC NPS400 Support: See comment near head of file.  */
+#define NPS_R_DST_3B   (UIMM6_5_S + 1)
+  { 3, 24, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_dst, extract_nps_3bit_dst },
+
+#define NPS_R_SRC1_3B  (NPS_R_DST_3B + 1)
+  { 3, 24, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE | ARC_OPERAND_NCHK, insert_nps_3bit_dst, extract_nps_3bit_dst },
+
+#define NPS_R_SRC2_3B  (NPS_R_SRC1_3B + 1)
+  { 3, 21, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_src2, extract_nps_3bit_src2 },
+
+#define NPS_R_DST      (NPS_R_SRC2_3B + 1)
+  { 6, 21, 0, ARC_OPERAND_IR, NULL, NULL },
+
+#define NPS_R_SRC1     (NPS_R_DST + 1)
+  { 6, 21, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE, NULL, NULL },
+
+#define NPS_BITOP_DST_POS      (NPS_R_SRC1 + 1)
+  { 5, 5, 0, ARC_OPERAND_UNSIGNED, 0, 0 },
+
+#define NPS_BITOP_SRC_POS      (NPS_BITOP_DST_POS + 1)
+  { 5, 0, 0, ARC_OPERAND_UNSIGNED, 0, 0 },
+
+#define NPS_BITOP_SIZE         (NPS_BITOP_SRC_POS + 1)
+  { 5, 10, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_bitop_size, extract_nps_bitop_size },
+
+#define NPS_BITOP_DST_POS_SZ    (NPS_BITOP_SIZE + 1)
+  { 5, 0, 0, ARC_OPERAND_UNSIGNED, insert_nps_dst_pos_and_size, extract_nps_dst_pos_and_size },
+
+#define NPS_BITOP_SIZE_2B      (NPS_BITOP_DST_POS_SZ + 1)
+  { 0, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_bitop_size_2b, extract_nps_bitop_size_2b },
+
+#define NPS_BITOP_UIMM8                (NPS_BITOP_SIZE_2B + 1)
+  { 8, 0, 0, ARC_OPERAND_UNSIGNED, insert_nps_bitop_uimm8, extract_nps_bitop_uimm8 },
+
+#define NPS_UIMM16             (NPS_BITOP_UIMM8 + 1)
+  { 16, 0, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_RFLT_UIMM6         (NPS_UIMM16 + 1)
+  { 6, 6, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_rflt_uimm6, extract_nps_rflt_uimm6 },
 };
 
 const unsigned arc_num_operands = ARRAY_SIZE (arc_operands);
@@ -1190,17 +1505,82 @@ const unsigned arc_num_operands = ARRAY_SIZE (arc_operands);
 const unsigned arc_Toperand = FKT_T;
 const unsigned arc_NToperand = FKT_NT;
 
+const unsigned char arg_none[]          = { 0 };
+const unsigned char arg_32bit_rarbrc[]  = { RA, RB, RC };
+const unsigned char arg_32bit_zarbrc[]  = { ZA, RB, RC };
+const unsigned char arg_32bit_rbrbrc[]  = { RB, RBdup, RC };
+const unsigned char arg_32bit_rarbu6[]  = { RA, RB, UIMM6_20 };
+const unsigned char arg_32bit_zarbu6[]  = { ZA, RB, UIMM6_20 };
+const unsigned char arg_32bit_rbrbu6[]  = { RB, RBdup, UIMM6_20 };
+const unsigned char arg_32bit_rbrbs12[]         = { RB, RBdup, SIMM12_20 };
+const unsigned char arg_32bit_ralimmrc[] = { RA, LIMM, RC };
+const unsigned char arg_32bit_rarblimm[] = { RA, RB, LIMM };
+const unsigned char arg_32bit_zalimmrc[] = { ZA, LIMM, RC };
+const unsigned char arg_32bit_zarblimm[] = { ZA, RB, LIMM };
+
+const unsigned char arg_32bit_rbrblimm[] = { RB, RBdup, LIMM };
+const unsigned char arg_32bit_ralimmu6[] = { RA, LIMM, UIMM6_20 };
+const unsigned char arg_32bit_zalimmu6[] = { ZA, LIMM, UIMM6_20 };
+
+const unsigned char arg_32bit_zalimms12[]  = { ZA, LIMM, SIMM12_20 };
+const unsigned char arg_32bit_ralimmlimm[] = { RA, LIMM, LIMMdup };
+const unsigned char arg_32bit_zalimmlimm[] = { ZA, LIMM, LIMMdup };
+
+const unsigned char arg_32bit_rbrc[]   = { RB, RC };
+const unsigned char arg_32bit_zarc[]   = { ZA, RC };
+const unsigned char arg_32bit_rbu6[]   = { RB, UIMM6_20 };
+const unsigned char arg_32bit_zau6[]   = { ZA, UIMM6_20 };
+const unsigned char arg_32bit_rblimm[] = { RB, LIMM };
+const unsigned char arg_32bit_zalimm[] = { ZA, LIMM };
+
+const unsigned char arg_32bit_limmrc[]   = { LIMM, RC };
+const unsigned char arg_32bit_limmu6[]   = { LIMM, UIMM6_20 };
+const unsigned char arg_32bit_limms12[]  = { LIMM, SIMM12_20 };
+const unsigned char arg_32bit_limmlimm[] = { LIMM, LIMMdup };
+
 /* The opcode table.
 
    The format of the opcode table is:
 
-   NAME OPCODE MASK CPU CLASS SUBCLASS { OPERANDS } { FLAGS }.  */
+   NAME OPCODE MASK CPU CLASS SUBCLASS { OPERANDS } { FLAGS }.
+
+   The table is organised such that, where possible, all instructions with
+   the same mnemonic are together in a block.  When the assembler searches
+   for a suitable instruction the entries are checked in table order, so
+   more specific, or specialised cases should appear earlier in the table.
+
+   As an example, consider two instructions 'add a,b,u6' and 'add
+   a,b,limm'.  The first takes a 6-bit immediate that is encoded within the
+   32-bit instruction, while the second takes a 32-bit immediate that is
+   encoded in a follow-on 32-bit, making the total instruction length
+   64-bits.  In this case the u6 variant must appear first in the table, as
+   all u6 immediates could also be encoded using the 'limm' extension,
+   however, we want to use the shorter instruction wherever possible.
+
+   It is possible though to split instructions with the same mnemonic into
+   multiple groups.  However, the instructions are still checked in table
+   order, even across groups.  The only time that instructions with the
+   same mnemonic should be split into different groups is when different
+   variants of the instruction appear in different architectures, in which
+   case, grouping all instructions from a particular architecture together
+   might be preferable to merging the instruction into the main instruction
+   table.
+
+   An example of this split instruction groups can be found with the 'sync'
+   instruction.  The core arc architecture provides a 'sync' instruction,
+   while the nps instruction set extension provides 'sync.rd' and
+   'sync.wr'.  The rd/wr flags are instruction flags, not part of the
+   mnemonic, so we end up with two groups for the sync instruction, the
+   first within the core arc instruction table, and the second within the
+   nps extension instructions.  */
 const struct arc_opcode arc_opcodes[] =
 {
 #include "arc-tbl.h"
-};
+#include "arc-nps400-tbl.h"
+#include "arc-ext-tbl.h"
 
-const unsigned arc_num_opcodes = ARRAY_SIZE (arc_opcodes);
+  { NULL, 0, 0, 0, 0, 0, { 0 }, { 0 } }
+};
 
 /* List with special cases instructions and the applicable flags.  */
 const struct arc_flag_special arc_flag_special_cases[] =
@@ -1240,38 +1620,52 @@ const struct arc_flag_special arc_flag_special_cases[] =
 const unsigned arc_num_flag_special = ARRAY_SIZE (arc_flag_special_cases);
 
 /* Relocations.  */
-#undef DEF
-#define DEF(NAME, EXC1, EXC2, RELOC1, RELOC2)  \
-  { #NAME, EXC1, EXC2, RELOC1, RELOC2}
-
 const struct arc_reloc_equiv_tab arc_reloc_equiv[] =
 {
-  DEF (sda, "ld", F_AS9, BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST2),
-  DEF (sda, "st", F_AS9, BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST2),
-  DEF (sda, "ldw", F_AS9, BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST1),
-  DEF (sda, "ldh", F_AS9, BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST1),
-  DEF (sda, "stw", F_AS9, BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST1),
-  DEF (sda, "sth", F_AS9, BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST1),
+  { "sda", "ld", { F_ASFAKE, F_H1, F_NULL },
+    BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST1 },
+  { "sda", "st", { F_ASFAKE, F_H1, F_NULL },
+    BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST1 },
+  { "sda", "ld", { F_ASFAKE, F_SIZEW7, F_NULL },
+    BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST1 },
+  { "sda", "st", { F_ASFAKE, F_SIZEW7, F_NULL },
+    BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST1 },
+
+  /* Next two entries will cover the undefined behavior ldb/stb with
+     address scaling.  */
+  { "sda", "ld", { F_ASFAKE, F_SIZEB7, F_NULL },
+    BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST },
+  { "sda", "st", { F_ASFAKE, F_SIZEB7, F_NULL },
+    BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST},
+
+  { "sda", "ld", { F_ASFAKE, F_NULL },
+    BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST2 },
+  { "sda", "st", { F_ASFAKE, F_NULL },
+    BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST2},
+  { "sda", "ldd", { F_ASFAKE, F_NULL },
+    BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST2 },
+  { "sda", "std", { F_ASFAKE, F_NULL },
+    BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST2},
 
   /* Short instructions.  */
-  DEF (sda, 0, F_NULL, BFD_RELOC_ARC_SDA16_LD, BFD_RELOC_ARC_SDA16_LD),
-  DEF (sda, 0, F_NULL, -SIMM10_A16_7_Sbis, BFD_RELOC_ARC_SDA16_LD1),
-  DEF (sda, 0, F_NULL, BFD_RELOC_ARC_SDA16_LD2, BFD_RELOC_ARC_SDA16_LD2),
-  DEF (sda, 0, F_NULL, BFD_RELOC_ARC_SDA16_ST2, BFD_RELOC_ARC_SDA16_ST2),
-
-  DEF (sda, 0, F_NULL, BFD_RELOC_ARC_32_ME, BFD_RELOC_ARC_SDA32_ME),
-  DEF (sda, 0, F_NULL, BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST),
-
-  DEF (plt, 0, F_NULL, BFD_RELOC_ARC_S25H_PCREL,
-       BFD_RELOC_ARC_S25H_PCREL_PLT),
-  DEF (plt, 0, F_NULL, BFD_RELOC_ARC_S21H_PCREL,
-       BFD_RELOC_ARC_S21H_PCREL_PLT),
-  DEF (plt, 0, F_NULL, BFD_RELOC_ARC_S25W_PCREL,
-       BFD_RELOC_ARC_S25W_PCREL_PLT),
-  DEF (plt, 0, F_NULL, BFD_RELOC_ARC_S21W_PCREL,
-       BFD_RELOC_ARC_S21W_PCREL_PLT),
-
-  DEF (plt, 0, F_NULL, BFD_RELOC_ARC_32_ME, BFD_RELOC_ARC_PLT32),
+  { "sda", 0, { F_NULL }, BFD_RELOC_ARC_SDA16_LD, BFD_RELOC_ARC_SDA16_LD },
+  { "sda", 0, { F_NULL }, -SIMM10_A16_7_Sbis, BFD_RELOC_ARC_SDA16_LD1 },
+  { "sda", 0, { F_NULL }, BFD_RELOC_ARC_SDA16_LD2, BFD_RELOC_ARC_SDA16_LD2 },
+  { "sda", 0, { F_NULL }, BFD_RELOC_ARC_SDA16_ST2, BFD_RELOC_ARC_SDA16_ST2 },
+
+  { "sda", 0, { F_NULL }, BFD_RELOC_ARC_32_ME, BFD_RELOC_ARC_SDA32_ME },
+  { "sda", 0, { F_NULL }, BFD_RELOC_ARC_SDA_LDST, BFD_RELOC_ARC_SDA_LDST },
+
+  { "plt", 0, { F_NULL }, BFD_RELOC_ARC_S25H_PCREL,
+    BFD_RELOC_ARC_S25H_PCREL_PLT },
+  { "plt", 0, { F_NULL }, BFD_RELOC_ARC_S21H_PCREL,
+    BFD_RELOC_ARC_S21H_PCREL_PLT },
+  { "plt", 0, { F_NULL }, BFD_RELOC_ARC_S25W_PCREL,
+    BFD_RELOC_ARC_S25W_PCREL_PLT },
+  { "plt", 0, { F_NULL }, BFD_RELOC_ARC_S21W_PCREL,
+    BFD_RELOC_ARC_S21W_PCREL_PLT },
+
+  { "plt", 0, { F_NULL }, BFD_RELOC_ARC_32_ME, BFD_RELOC_ARC_PLT32 }
 };
 
 const unsigned arc_num_equiv_tab = ARRAY_SIZE (arc_reloc_equiv);
@@ -1336,8 +1730,8 @@ const unsigned arc_num_pseudo_insn =
 const struct arc_aux_reg arc_aux_regs[] =
 {
 #undef DEF
-#define DEF(ADDR, NAME)                                \
-  { ADDR, #NAME, sizeof (#NAME)-1 },
+#define DEF(ADDR, CPU, SUBCLASS, NAME)         \
+  { ADDR, CPU, SUBCLASS, #NAME, sizeof (#NAME)-1 },
 
 #include "arc-regs.h"
 
@@ -1345,3 +1739,129 @@ const struct arc_aux_reg arc_aux_regs[] =
 };
 
 const unsigned arc_num_aux_regs = ARRAY_SIZE (arc_aux_regs);
+
+/* NOTE: The order of this array MUST be consistent with 'enum
+   arc_rlx_types' located in tc-arc.h!  */
+const struct arc_opcode arc_relax_opcodes[] =
+{
+  { NULL, 0x0, 0x0, 0x0, ARITH, NONE, { UNUSED }, { 0 } },
+
+  /* bl_s s13 11111sssssssssss.  */
+  { "bl_s", 0x0000F800, 0x0000F800, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, BRANCH, NONE,
+    { SIMM13_A32_5_S }, { 0 }},
+
+  /* bl<.d> s25 00001sssssssss10SSSSSSSSSSNRtttt.  */
+  { "bl", 0x08020000, 0xF8030000, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, BRANCH, NONE,
+    { SIMM25_A32_5 }, { C_D }},
+
+  /* b_s s10 1111000sssssssss.  */
+  { "b_s", 0x0000F000, 0x0000FE00, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, BRANCH, NONE,
+    { SIMM10_A16_7_S }, { 0 }},
+
+  /* b<.d> s25 00000ssssssssss1SSSSSSSSSSNRtttt.  */
+  { "b", 0x00010000, 0xF8010000, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, BRANCH, NONE,
+    { SIMM25_A16_5 }, { C_D }},
+
+  /* add_s c,b,u3 01101bbbccc00uuu.  Wants UIMM3_13_S_PCREL.  */
+  { "add_s", 0x00006800, 0x0000F818, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
+    { RC_S, RB_S, UIMM3_13_S }, { 0 }},
+
+  /* add<.f> a,b,u6 00100bbb01000000FBBBuuuuuuAAAAAA.  Wants
+     UIMM6_20_PCREL.  */
+  { "add", 0x20400000, 0xF8FF0000, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
+    { RA, RB, UIMM6_20 }, { C_F }},
+
+  /* add<.f> a,b,limm 00100bbb00000000FBBB111110AAAAAA.  */
+  { "add", 0x20000F80, 0xF8FF0FC0, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
+    { RA, RB, LIMM }, { C_F }},
+
+  /* ld_s c,b,u7 10000bbbcccuuuuu.  Wants UIMM7_A32_11_S_PCREL.  */
+  { "ld_s", 0x00008000, 0x0000F800, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
+    { RC_S, BRAKET, RB_S, UIMM7_A32_11_S, BRAKETdup }, { 0 }},
+
+  /* ld<.di><.aa><.x><zz> a,b,s9
+     00010bbbssssssssSBBBDaaZZXAAAAAA.  Wants SIMM9_8_PCREL.  */
+  { "ld", 0x10000000, 0xF8000000, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
+    { RA, BRAKET, RB, SIMM9_8, BRAKETdup },
+    { C_ZZ23, C_DI20, C_AA21, C_X25 }},
+
+  /* ld<.di><.aa><.x><zz> a,b,limm 00100bbbaa110ZZXDBBB111110AAAAAA.  */
+  { "ld", 0x20300F80, 0xF8380FC0, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
+    { RA, BRAKET, RB, LIMM, BRAKETdup },
+    { C_ZZ13, C_DI16, C_AA8, C_X15 }},
+
+  /* mov_s b,u8 11011bbbuuuuuuuu.  Wants UIMM8_8_S_PCREL.  */
+  { "mov_s", 0x0000D800, 0x0000F800, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
+    { RB_S, UIMM8_8_S }, { 0 }},
+
+  /* mov<.f> b,s12 00100bbb10001010FBBBssssssSSSSSS.  Wants
+     SIMM12_20_PCREL.  */
+  { "mov", 0x208A0000, 0xF8FF0000, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
+    { RB, SIMM12_20 }, { C_F }},
+
+  /* mov<.f> b,limm 00100bbb00001010FBBB111110RRRRRR.  */
+  { "mov", 0x200A0F80, 0xF8FF0FC0, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
+    { RB, LIMM }, { C_F }},
+
+  /* sub_s c,b,u3 01101bbbccc01uuu.  UIMM3_13_S_PCREL.  */
+  { "sub_s", 0x00006808, 0x0000F818, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
+    { RC_S, RB_S, UIMM3_13_S }, { 0 }},
+
+  /* sub<.f> a,b,u6 00100bbb01000010FBBBuuuuuuAAAAAA.
+     UIMM6_20_PCREL.  */
+  { "sub", 0x20420000, 0xF8FF0000, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
+    { RA, RB, UIMM6_20 }, { C_F }},
+
+  /* sub<.f> a,b,limm 00100bbb00000010FBBB111110AAAAAA.  */
+  { "sub", 0x20020F80, 0xF8FF0FC0, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
+    { RA, RB, LIMM }, { C_F }},
+
+  /* mpy<.f> a,b,u6 00100bbb01011010FBBBuuuuuuAAAAAA.
+     UIMM6_20_PCREL.  */
+  { "mpy", 0x205A0000, 0xF8FF0000, ARC_OPCODE_ARC700 | ARC_OPCODE_ARCv2EM
+    | ARC_OPCODE_ARCv2HS, ARITH, MPY6E, { RA, RB, UIMM6_20 }, { C_F }},
+
+  /* mpy<.f> a,b,limm 00100bbb00011010FBBB111110AAAAAA.  */
+  { "mpy", 0x201A0F80, 0xF8FF0FC0, ARC_OPCODE_ARC700 | ARC_OPCODE_ARCv2EM
+    | ARC_OPCODE_ARCv2HS, ARITH, MPY6E, { RA, RB, LIMM }, { C_F }},
+
+  /* mov<.f><.cc> b,u6 00100bbb11001010FBBBuuuuuu1QQQQQ.
+     UIMM6_20_PCREL.  */
+  { "mov", 0x20CA0020, 0xF8FF0020, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
+    { RB, UIMM6_20 }, { C_F, C_CC }},
+
+  /* mov<.f><.cc> b,limm 00100bbb11001010FBBB1111100QQQQQ.  */
+  { "mov", 0x20CA0F80, 0xF8FF0FE0, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, MEMORY, NONE,
+    { RB, LIMM }, { C_F, C_CC }},
+
+  /* add<.f><.cc> b,b,u6 00100bbb11000000FBBBuuuuuu1QQQQQ.
+     UIMM6_20_PCREL.  */
+  { "add", 0x20C00020, 0xF8FF0020, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
+    { RB, RBdup, UIMM6_20 }, { C_F, C_CC }},
+
+  /* add<.f><.cc> b,b,limm 00100bbb11000000FBBB1111100QQQQQ.  */
+  { "add", 0x20C00F80, 0xF8FF0FE0, ARC_OPCODE_ARC600 | ARC_OPCODE_ARC700
+    | ARC_OPCODE_ARCv2EM | ARC_OPCODE_ARCv2HS, ARITH, NONE,
+    { RB, RBdup, LIMM }, { C_F, C_CC }}
+};
+
+const unsigned arc_num_relax_opcodes = ARRAY_SIZE (arc_relax_opcodes);
This page took 0.046057 seconds and 4 git commands to generate.