This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Begin implementing ARC NPS-400 Accelerator instructions


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=db18dbabad8e7b63e98d47813ef20acac7072350

commit db18dbabad8e7b63e98d47813ef20acac7072350
Author: Graham Markall <graham.markall@embecosm.com>
Date:   Wed Jul 27 15:57:18 2016 +0100

    Begin implementing ARC NPS-400 Accelerator instructions
    
    opcodes * arc-nps400-tbl.h: Change block comments to GNU format.
            * arc-dis.c: Add new globals addrtypenames,
            addrtypenames_max, and addtypeunknown.
            (get_addrtype): New function.
            (print_insn_arc): Print colons and address types when
            required.
            * arc-opc.c: Add MAKE_INSERT_NPS_ADDRTYPE macro and use to
            define insert and extract functions for all address types.
            (arc_operands): Add operands for colon and all address
            types.
            * arc-nps-400-tbl.h: Add NPS-400 BMU instructions to opcode table.
            * arc-opc.c: Add NPS_BD_TYPE and NPS_BMU_NUM operands,
            insert_nps_bd_num_buff and extract_nps_bd_num_buff functions.
            * arc-nps-400-tbl.h: Add NPS-400 PMU instructions to opcode table.
            * arc-opc.c: Add NPS_PMU_NXT_DST and NPS_PMU_NUM_JOB operands,
            insert_nps_pmu_num_job and extract_nps_pmu_num_job functions.
    
    include * opcode/arc.h: Add ARC_OPERAND_ADDRTYPE,
            ARC_OPERAND_COLON. Add the arc_nps_address_type enum and
            ARC_NUM_ADDRTYPES.
            * opcode/arc.h: Add BMU to insn_class_t enum.
            * opcode/arc.h: Add PMU to insn_class_t enum.
    
    gas     * config/tc-arc.c: Add new global arc_addrtype_hash.
            Define O_colon and O_addrtype.
            (debug_exp): Add O_colon and O_addrtype.
            (tokenize_arguments): Handle colon and address type
            tokens.
            (declare_addrtype): New function.
            (md_begin): Initialise arc_addrtype_hash.
            (arc_parse_name): Add lookup of address types.
    	(assemble_insn): Handle colons and address types by
            ignoring them.
            * testsuite/gas/arc/nps400-8.s: New file.
            * testsuite/gas/arc/nps400-8.d: New file.
            * testsuite/gas/arc/nps400-8.s: Add PMU instruction tests.
            * testsuite/gas/arc/nps400-8.d: Add expected PMU
            instruction output.

Diff:
---
 gas/ChangeLog                    |  18 ++++
 gas/config/tc-arc.c              | 152 +++++++++++++++++++++++-------
 gas/testsuite/gas/arc/nps400-8.d |  71 ++++++++++++++
 gas/testsuite/gas/arc/nps400-8.s |  92 +++++++++++++++++++
 include/ChangeLog                |   8 ++
 include/opcode/arc.h             | 194 +++++++++++++++++++++++++++------------
 opcodes/ChangeLog                |  19 ++++
 opcodes/arc-dis.c                |  45 ++++++++-
 opcodes/arc-ext.c                |  10 +-
 opcodes/arc-nps400-tbl.h         | 110 ++++++++++++++++++++--
 opcodes/arc-opc.c                | 131 +++++++++++++++++++++++---
 11 files changed, 724 insertions(+), 126 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 617fccd..c2d132e 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,21 @@
+2016-07-27  Graham Markall  <graham.markall@embecosm.com>
+
+        * config/tc-arc.c: Add new global arc_addrtype_hash.
+        Define O_colon and O_addrtype.
+        (debug_exp): Add O_colon and O_addrtype.
+        (tokenize_arguments): Handle colon and address type
+        tokens.
+        (declare_addrtype): New function.
+        (md_begin): Initialise arc_addrtype_hash.
+        (arc_parse_name): Add lookup of address types.
+	(assemble_insn): Handle colons and address types by
+        ignoring them.
+        * testsuite/gas/arc/nps400-8.s: New file.
+        * testsuite/gas/arc/nps400-8.d: New file.
+        * testsuite/gas/arc/nps400-8.s: Add PMU instruction tests.
+        * testsuite/gas/arc/nps400-8.d: Add expected PMU
+        instruction output.
+
 2016-07-26  Maciej W. Rozycki  <macro@imgtec.com>
 
 	* config/tc-mips.c (RELAX_MICROMIPS_ENCODE): Add `insn32' flag.
diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c
index 70886dd..4e4dcb3 100644
--- a/gas/config/tc-arc.c
+++ b/gas/config/tc-arc.c
@@ -45,8 +45,8 @@
 
 #define MAJOR_OPCODE(x)  (((x) & 0xF8000000) >> 27)
 #define SUB_OPCODE(x)	 (((x) & 0x003F0000) >> 16)
-#define LP_INSN(x)	 ((MAJOR_OPCODE (x) == 0x4) && \
-			  (SUB_OPCODE (x) == 0x28))
+#define LP_INSN(x)	 ((MAJOR_OPCODE (x) == 0x4) \
+			  && (SUB_OPCODE (x) == 0x28))
 
 /* Equal to MAX_PRECISION in atof-ieee.c.  */
 #define MAX_LITTLENUMS 6
@@ -102,7 +102,8 @@ enum arc_rlx_types
 #define is_spfp_p(op)           (((sc) == SPX))
 #define is_dpfp_p(op)           (((sc) == DPX))
 #define is_fpuda_p(op)          (((sc) == DPA))
-#define is_br_jmp_insn_p(op)    (((op)->insn_class == BRANCH || (op)->insn_class == JUMP))
+#define is_br_jmp_insn_p(op)    (((op)->insn_class == BRANCH \
+				  || (op)->insn_class == JUMP))
 #define is_kernel_insn_p(op)    (((op)->insn_class == KERNEL))
 #define is_nps400_p(op)         (((sc) == NPS400))
 
@@ -420,6 +421,9 @@ static struct hash_control *arc_reg_hash;
 /* The hash table of aux register symbols.  */
 static struct hash_control *arc_aux_hash;
 
+/* The hash table of address types.  */
+static struct hash_control *arc_addrtype_hash;
+
 /* A table of CPU names and opcode sets.  */
 static const struct cpu_type
 {
@@ -461,6 +465,12 @@ static const struct cpu_type
 /* Used to define a bracket as operand in tokens.  */
 #define O_bracket O_md32
 
+/* Used to define a colon as an operand in tokens.  */
+#define O_colon O_md31
+
+/* Used to define address types in nps400.  */
+#define O_addrtype O_md30
+
 /* Dummy relocation, to be sorted out.  */
 #define DUMMY_RELOC_ARC_ENTRY     (BFD_RELOC_UNUSED + 1)
 
@@ -553,56 +563,56 @@ const relax_typeS md_relax_table[] =
 
   /* BL_S s13 ->
      BL s25.  */
-  RELAX_TABLE_ENTRY(13, 1, 2, ARC_RLX_BL),
-  RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE),
+  RELAX_TABLE_ENTRY (13, 1, 2, ARC_RLX_BL),
+  RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE),
 
   /* B_S s10 ->
      B s25.  */
-  RELAX_TABLE_ENTRY(10, 1, 2, ARC_RLX_B),
-  RELAX_TABLE_ENTRY(25, 1, 4, ARC_RLX_NONE),
+  RELAX_TABLE_ENTRY (10, 1, 2, ARC_RLX_B),
+  RELAX_TABLE_ENTRY (25, 1, 4, ARC_RLX_NONE),
 
   /* ADD_S c,b, u3 ->
      ADD<.f> a,b,u6 ->
      ADD<.f> a,b,limm.  */
-  RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_ADD_U6),
-  RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_LIMM),
-  RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
+  RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_ADD_U6),
+  RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_LIMM),
+  RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
 
   /* LD_S a, [b, u7] ->
      LD<zz><.x><.aa><.di> a, [b, s9] ->
      LD<zz><.x><.aa><.di> a, [b, limm] */
-  RELAX_TABLE_ENTRY(7, 0, 2, ARC_RLX_LD_S9),
-  RELAX_TABLE_ENTRY(9, 1, 4, ARC_RLX_LD_LIMM),
-  RELAX_TABLE_ENTRY_MAX(1, 8, ARC_RLX_NONE),
+  RELAX_TABLE_ENTRY (7, 0, 2, ARC_RLX_LD_S9),
+  RELAX_TABLE_ENTRY (9, 1, 4, ARC_RLX_LD_LIMM),
+  RELAX_TABLE_ENTRY_MAX (1, 8, ARC_RLX_NONE),
 
   /* MOV_S b, u8 ->
      MOV<.f> b, s12 ->
      MOV<.f> b, limm.  */
-  RELAX_TABLE_ENTRY(8, 0, 2, ARC_RLX_MOV_S12),
-  RELAX_TABLE_ENTRY(8, 0, 4, ARC_RLX_MOV_LIMM),
-  RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
+  RELAX_TABLE_ENTRY (8, 0, 2, ARC_RLX_MOV_S12),
+  RELAX_TABLE_ENTRY (8, 0, 4, ARC_RLX_MOV_LIMM),
+  RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
 
   /* SUB_S c, b, u3 ->
      SUB<.f> a, b, u6 ->
      SUB<.f> a, b, limm.  */
-  RELAX_TABLE_ENTRY(3, 0, 2, ARC_RLX_SUB_U6),
-  RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_SUB_LIMM),
-  RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
+  RELAX_TABLE_ENTRY (3, 0, 2, ARC_RLX_SUB_U6),
+  RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_SUB_LIMM),
+  RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
 
   /* MPY<.f> a, b, u6 ->
      MPY<.f> a, b, limm.  */
-  RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MPY_LIMM),
-  RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
+  RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MPY_LIMM),
+  RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
 
   /* MOV<.f><.cc> b, u6 ->
      MOV<.f><.cc> b, limm.  */
-  RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_MOV_RLIMM),
-  RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
+  RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_MOV_RLIMM),
+  RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
 
   /* ADD<.f><.cc> b, b, u6 ->
      ADD<.f><.cc> b, b, limm.  */
-  RELAX_TABLE_ENTRY(6, 0, 4, ARC_RLX_ADD_RRLIMM),
-  RELAX_TABLE_ENTRY_MAX(0, 8, ARC_RLX_NONE),
+  RELAX_TABLE_ENTRY (6, 0, 4, ARC_RLX_ADD_RRLIMM),
+  RELAX_TABLE_ENTRY_MAX (0, 8, ARC_RLX_NONE),
 };
 
 /* Order of this table's entries matters!  */
@@ -979,6 +989,8 @@ debug_exp (expressionS *t)
     case O_logical_or:		name = "O_logical_or";		break;
     case O_index:		name = "O_index";		break;
     case O_bracket:		name = "O_bracket";		break;
+    case O_colon:		name = "O_colon";               break;
+    case O_addrtype:		name = "O_addrtype";            break;
     }
 
   switch (t->X_md)
@@ -1067,6 +1079,16 @@ tokenize_arguments (char *str,
 	  ++num_args;
 	  break;
 
+        case ':':
+          input_line_pointer++;
+          if (!saw_arg || num_args == ntok)
+            goto err;
+          tok->X_op = O_colon;
+          saw_arg = FALSE;
+          ++tok;
+          ++num_args;
+          break;
+
 	case '@':
 	  /* We have labels, function names and relocations, all
 	     starting with @ symbol.  Sort them out.  */
@@ -1693,8 +1715,7 @@ find_opcode_match (const struct arc_opcode_hash_entry *entry,
 	  const struct arc_operand *operand = &arc_operands[*opidx];
 
 	  /* Only take input from real operands.  */
-	  if ((operand->flags & ARC_OPERAND_FAKE)
-	      && !(operand->flags & ARC_OPERAND_BRAKET))
+	  if (ARC_OPERAND_IS_FAKE (operand))
 	    continue;
 
 	  /* When we expect input, make sure we have it.  */
@@ -1704,6 +1725,12 @@ find_opcode_match (const struct arc_opcode_hash_entry *entry,
 	  /* Match operand type with expression type.  */
 	  switch (operand->flags & ARC_OPERAND_TYPECHECK_MASK)
 	    {
+            case ARC_OPERAND_ADDRTYPE:
+              /* Check to be an address type.  */
+              if (tok[tokidx].X_op != O_addrtype)
+                goto match_failed;
+              break;
+
 	    case ARC_OPERAND_IR:
 	      /* Check to be a register.  */
 	      if ((tok[tokidx].X_op != O_register
@@ -1755,6 +1782,12 @@ find_opcode_match (const struct arc_opcode_hash_entry *entry,
 		goto match_failed;
 	      break;
 
+            case ARC_OPERAND_COLON:
+              /* Check if colon is also in opcode table as operand.  */
+              if (tok[tokidx].X_op != O_colon)
+                goto match_failed;
+              break;
+
 	    case ARC_OPERAND_LIMM:
 	    case ARC_OPERAND_SIGNED:
 	    case ARC_OPERAND_UNSIGNED:
@@ -2010,8 +2043,9 @@ pseudo_operand_match (const expressionS *tok,
 
     case O_symbol:
       /* Handle all symbols as long immediates or signed 9.  */
-      if (operand_real->flags & ARC_OPERAND_LIMM ||
-	  ((operand_real->flags & ARC_OPERAND_SIGNED) && operand_real->bits == 9))
+      if (operand_real->flags & ARC_OPERAND_LIMM
+	  || ((operand_real->flags & ARC_OPERAND_SIGNED)
+	      && operand_real->bits == 9))
 	ret = TRUE;
       break;
 
@@ -2094,8 +2128,8 @@ find_special_case_pseudo (const char *opname,
       operand_pseudo = &pseudo_insn->operand[i];
       operand_real = &arc_operands[operand_pseudo->operand_idx];
 
-      if (operand_real->flags & ARC_OPERAND_BRAKET &&
-	  !operand_pseudo->needs_insert)
+      if (operand_real->flags & ARC_OPERAND_BRAKET
+	  && !operand_pseudo->needs_insert)
 	continue;
 
       /* Has to be inserted (i.e. this token does not exist yet).  */
@@ -2461,6 +2495,22 @@ declare_register_set (void)
     }
 }
 
+/* Construct a symbol for an address type.  */
+
+static void
+declare_addrtype (const char *name, int number)
+{
+  const char *err;
+  symbolS *addrtypeS = symbol_create (name, undefined_section,
+                                      number, &zero_address_frag);
+
+  err = hash_insert (arc_addrtype_hash, S_GET_NAME (addrtypeS),
+                     (void *) addrtypeS);
+  if (err)
+    as_fatal (_("Inserting \"%s\" into address type table failed: %s"),
+              name, err);
+}
+
 /* Port-specific assembler initialization.  This function is called
    once, at assembler startup time.  */
 
@@ -2575,6 +2625,28 @@ md_begin (void)
 	as_fatal (_("internal error: can't hash aux register '%s': %s"),
 		  auxr->name, retval);
     }
+
+  /* Address type declaration.  */
+  arc_addrtype_hash = hash_new ();
+  if (arc_addrtype_hash == NULL)
+    as_fatal (_("Virtual memory exhausted"));
+
+  declare_addrtype ("bd", ARC_NPS400_ADDRTYPE_BD);
+  declare_addrtype ("jid", ARC_NPS400_ADDRTYPE_JID);
+  declare_addrtype ("lbd", ARC_NPS400_ADDRTYPE_LBD);
+  declare_addrtype ("mbd", ARC_NPS400_ADDRTYPE_MBD);
+  declare_addrtype ("sd", ARC_NPS400_ADDRTYPE_SD);
+  declare_addrtype ("sm", ARC_NPS400_ADDRTYPE_SM);
+  declare_addrtype ("xa", ARC_NPS400_ADDRTYPE_XA);
+  declare_addrtype ("xd", ARC_NPS400_ADDRTYPE_XD);
+  declare_addrtype ("cd", ARC_NPS400_ADDRTYPE_CD);
+  declare_addrtype ("cbd", ARC_NPS400_ADDRTYPE_CBD);
+  declare_addrtype ("cjid", ARC_NPS400_ADDRTYPE_CJID);
+  declare_addrtype ("clbd", ARC_NPS400_ADDRTYPE_CLBD);
+  declare_addrtype ("cm", ARC_NPS400_ADDRTYPE_CM);
+  declare_addrtype ("csd", ARC_NPS400_ADDRTYPE_CSD);
+  declare_addrtype ("cxa", ARC_NPS400_ADDRTYPE_CXA);
+  declare_addrtype ("cxd", ARC_NPS400_ADDRTYPE_CXD);
 }
 
 /* Write a value out to the object file, using the appropriate
@@ -3254,7 +3326,7 @@ arc_parse_name (const char *name,
   if (!assembling_insn)
     return FALSE;
 
-  /* Handle only registers.  */
+  /* Handle only registers and address types.  */
   if (e->X_op != O_absent)
     return FALSE;
 
@@ -3265,6 +3337,15 @@ arc_parse_name (const char *name,
       e->X_add_number = S_GET_VALUE (sym);
       return TRUE;
     }
+
+  sym = hash_find (arc_addrtype_hash, name);
+  if (sym)
+    {
+      e->X_op = O_addrtype;
+      e->X_add_number = S_GET_VALUE (sym);
+      return TRUE;
+    }
+
   return FALSE;
 }
 
@@ -3726,8 +3807,7 @@ assemble_insn (const struct arc_opcode *opcode,
       const struct arc_operand *operand = &arc_operands[*argidx];
       const expressionS *t = (const expressionS *) 0;
 
-      if ((operand->flags & ARC_OPERAND_FAKE)
-	  && !(operand->flags & ARC_OPERAND_BRAKET))
+      if (ARC_OPERAND_IS_FAKE (operand))
 	continue;
 
       if (operand->flags & ARC_OPERAND_DUPLICATE)
@@ -3764,7 +3844,9 @@ assemble_insn (const struct arc_opcode *opcode,
 	  break;
 
 	case O_bracket:
-	  /* Ignore brackets.  */
+        case O_colon:
+        case O_addrtype:
+	  /* Ignore brackets, colons, and address types.  */
 	  break;
 
 	case O_absent:
diff --git a/gas/testsuite/gas/arc/nps400-8.d b/gas/testsuite/gas/arc/nps400-8.d
new file mode 100644
index 0000000..9f5344c
--- /dev/null
+++ b/gas/testsuite/gas/arc/nps400-8.d
@@ -0,0 +1,71 @@
+#as: -mcpu=arc700 -mnps400
+#objdump: -dr
+
+.*: +file format .*arc.*
+
+Disassembly of section .text:
+
+[0-9a-f]+ <.*>:
+   0:	3810 0000           	bdalc	r0,\[cm:r0\],r0,r0
+   4:	3a10 00c1           	bdalc	r1,\[cm:r2\],r2,r3
+   8:	3850 0840           	bdalc	r0,\[cm:r0\],r0,0,0x1
+   c:	3b50 0c42           	bdalc	r2,\[cm:r3\],r3,0x1,0x1
+  10:	3c50 0c03           	bdalc	r3,\[cm:r4\],r4,0x1,0x8
+  14:	3850 0040           	sbdalc	r0,r0,0
+  18:	3c50 0443           	sbdalc	r3,r4,0x1
+  1c:	3811 003e           	bdfre	0,\[cm:r0\],r0,r0
+  20:	3911 00be           	bdfre	0,\[cm:r1\],r1,r2
+  24:	3851 007e           	bdfre	0,\[cm:r0\],r0,0x1
+  28:	3a51 003e           	bdfre	0,\[cm:r2\],r2,0x8
+  2c:	3851 087e           	bdfre	0,\[cm:r0\],r0,0,0x1
+  30:	3e51 083e           	bdfre	0,\[cm:r6\],r6,0,0x8
+  34:	3851 0c7e           	bdfre	0,\[cm:r0\],r0,0x1,0x1
+  38:	3e51 0c3e           	bdfre	0,\[cm:r6\],r6,0x1,0x8
+  3c:	3817 003e           	sbdfre	0,r0,r0
+  40:	3917 00be           	sbdfre	0,r1,r2
+  44:	3818 003e           	bdbgt	0,r0,r0
+  48:	3c18 01be           	bdbgt	0,r4,r6
+  4c:	381c 0000           	idxalc	r0,\[cm:r0\],r0,r0
+  50:	3a1c 00c1           	idxalc	r1,\[cm:r2\],r2,r3
+  54:	3d5c 0884           	idxalc	r4,\[cm:r5\],r5,0x2
+  58:	385c 0040           	sidxalc	r0,r0
+  5c:	3a5c 0044           	sidxalc	r4,r2
+  60:	381e 003e           	idxfre	0,\[cm:r0\],r0,r0
+  64:	391e 00be           	idxfre	0,\[cm:r1\],r1,r2
+  68:	385e 007e           	idxfre	0,\[cm:r0\],r0,0x1
+  6c:	3a5e 003e           	idxfre	0,\[cm:r2\],r2,0x8
+  70:	381d 003e           	sidxfre	0,r0,r0
+  74:	391d 00be           	sidxfre	0,r1,r2
+  78:	3819 003e           	idxbgt	0,r0,r0
+  7c:	3f19 023e           	idxbgt	0,r7,r8
+  80:	3e0d 703e 0000 0000 	efabgt	0,0,r0
+  88:	3e0d 70fe ffff ffff 	efabgt	0,0xffffffff,r3
+  90:	380d 0fbe 0000 0000 	efabgt	0,r0,0
+  98:	3c0d 0fbe ffff ffff 	efabgt	0,r4,0xffffffff
+  a0:	380d 003e           	efabgt	0,r0,r0
+  a4:	3f0d 023e           	efabgt	0,r7,r8
+  a8:	3e0d 7000 0000 0000 	efabgt	r0,0,r0
+  b0:	3e0d 7184 ffff ffff 	efabgt	r4,0xffffffff,r6
+  b8:	380d 0f80 0000 0000 	efabgt	r0,r0,0
+  c0:	3b0d 0f82 ffff ffff 	efabgt	r2,r3,0xffffffff
+  c8:	380d 0000           	efabgt	r0,r0,r0
+  cc:	380d 1247           	efabgt	r7,r8,r9
+  d0:	3e2f 7020           	jobget	0,\[cjid:r0\]
+  d4:	3e2f 71a0           	jobget	0,\[cjid:r6\]
+  d8:	3e2f 7021           	jobget.cl	0,\[cjid:r0\]
+  dc:	3e2f 71a1           	jobget.cl	0,\[cjid:r6\]
+  e0:	3812 003e           	jobdn	0,\[cjid:r0\],r0,r0
+  e4:	3a12 013e           	jobdn	0,\[cjid:r2\],r2,r4
+  e8:	3852 003e           	jobdn	0,\[cjid:r0\],r0,0
+  ec:	3a52 03fe           	jobdn	0,\[cjid:r2\],r2,0xf
+  f0:	381f 0000           	jobalc	r0,\[cm:r0\],r0,r0
+  f4:	3a1f 00c1           	jobalc	r1,\[cm:r2\],r2,r3
+  f8:	385f 0840           	jobalc	r0,\[cm:r0\],r0,0x1
+  fc:	3a5f 0801           	jobalc	r1,\[cm:r2\],r2,0x4
+ 100:	385f 0040           	sjobalc	r0,r0
+ 104:	3d5f 0046           	sjobalc	r6,r5
+ 108:	381a 0000           	jobbgt	r0,r0,r0
+ 10c:	3d1a 0182           	jobbgt	r2,r5,r6
+ 110:	3e6f 70ff           	cnljob	0
+ 114:	386f 0028           	qseq	r0,\[r0\]
+ 118:	3a6f 0128           	qseq	r2,\[r4\]
diff --git a/gas/testsuite/gas/arc/nps400-8.s b/gas/testsuite/gas/arc/nps400-8.s
new file mode 100644
index 0000000..1042183
--- /dev/null
+++ b/gas/testsuite/gas/arc/nps400-8.s
@@ -0,0 +1,92 @@
+        .text
+
+        ;; bdalc / sbdalc
+        bdalc r0,[cm:r0],r0,r0
+        bdalc r1,[cm:r2],r2,r3
+        bdalc r0,[cm:r0],r0,0,1
+        bdalc r2,[cm:r3],r3,1,1
+        bdalc r3,[cm:r4],r4,1,8
+        sbdalc r0, r0, 0
+        sbdalc r3, r4, 1
+
+        ;; bdfre / sbdfre
+        bdfre 0,[cm:r0],r0,r0
+        bdfre 0,[cm:r1],r1,r2
+        bdfre 0,[cm:r0],r0,1
+        bdfre 0,[cm:r2],r2,8
+        bdfre 0,[cm:r0],r0,0,1
+        bdfre 0,[cm:r6],r6,0,8
+        bdfre 0,[cm:r0],r0,1,1
+        bdfre 0,[cm:r6],r6,1,8
+        sbdfre 0, r0, r0
+        sbdfre 0, r1, r2
+
+        ;; bdbgt
+        bdbgt 0,r0,r0
+        bdbgt 0,r4,r6
+
+        ;; idxalc / sidxalc
+        idxalc r0,[cm:r0],r0,r0
+        idxalc r1,[cm:r2],r2,r3
+        idxalc r4,[cm:r5],r5,2
+        sidxalc r0,r0
+        sidxalc r4,r2
+
+        ;; idxfre / sidxfre
+        idxfre 0,[cm:r0],r0,r0
+        idxfre 0,[cm:r1],r1,r2
+        idxfre 0,[cm:r0],r0,1
+        idxfre 0,[cm:r2],r2,8
+        sidxfre 0, r0, r0
+        sidxfre 0, r1, r2
+
+        ;; idxbgt
+        idxbgt 0,r0,r0
+        idxbgt 0,r7,r8
+
+        ;; efabgt
+        efabgt 0,0x0,r0
+        efabgt 0,0xffffffff,r3
+        efabgt 0,r0,0x0
+        efabgt 0,r4,0xffffffff
+        efabgt 0,r0,r0
+        efabgt 0,r7,r8
+        efabgt r0,0x0,r0
+        efabgt r4,0xffffffff,r6
+        efabgt r0,r0,0x0
+        efabgt r2,r3,0xffffffff
+        efabgt r0,r0,r0
+        efabgt r7,r8,r9
+
+        ;; jobget
+        jobget 0,[cjid:r0]
+        jobget 0,[cjid:r6]
+        jobget.cl 0,[cjid:r0]
+        jobget.cl 0,[cjid:r6]
+
+        ;; jobdn
+        jobdn 0,[cjid:r0],r0,r0
+        jobdn 0,[cjid:r2],r2,r4
+        jobdn 0,[cjid:r0],r0,0
+        jobdn 0,[cjid:r2],r2,15
+
+        ;; jobalc / sjobalc
+        jobalc r0,[cm:r0],r0,r0
+        jobalc r1,[cm:r2],r2,r3
+        jobalc r0,[cm:r0],r0,1
+        jobalc r1,[cm:r2],r2,4
+        sjobalc r0,r0
+        sjobalc r6,r5
+
+        ;; jobbgt
+
+        jobbgt r0,r0,r0
+        jobbgt r2,r5,r6
+
+        ;; cnljob
+
+        cnljob 0
+
+        ;; qseq
+        qseq r0,[r0]
+        qseq r2,[r4]
diff --git a/include/ChangeLog b/include/ChangeLog
index 158be71..a87c9b6 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,11 @@
+2016-07-27  Graham Markall  <graham.markall@embecosm.com>
+
+        * opcode/arc.h: Add ARC_OPERAND_ADDRTYPE,
+        ARC_OPERAND_COLON. Add the arc_nps_address_type enum and
+        ARC_NUM_ADDRTYPES.
+        * opcode/arc.h: Add BMU to insn_class_t enum.
+        * opcode/arc.h: Add PMU to insn_class_t enum.
+
 2016-07-20  Claudiu Zissulescu  <claziss@synopsys.com>
 
 	* dis-asm.h: Declare print_arc_disassembler_options.
diff --git a/include/opcode/arc.h b/include/opcode/arc.h
index f0fefbb..faa63dc 100644
--- a/include/opcode/arc.h
+++ b/include/opcode/arc.h
@@ -38,71 +38,73 @@ extern "C" {
 
 /* Instruction Class.  */
 typedef enum
-  {
-    ACL,
-    ARITH,
-    AUXREG,
-    BITOP,
-    BRANCH,
-    CONTROL,
-    DPI,
-    DSP,
-    FLOAT,
-    INVALID,
-    JUMP,
-    KERNEL,
-    LOGICAL,
-    MEMORY,
-    NET,
-  } insn_class_t;
+{
+  ACL,
+  ARITH,
+  AUXREG,
+  BITOP,
+  BMU,
+  BRANCH,
+  CONTROL,
+  DPI,
+  DSP,
+  FLOAT,
+  INVALID,
+  JUMP,
+  KERNEL,
+  LOGICAL,
+  MEMORY,
+  NET,
+  PMU
+} insn_class_t;
 
 /* Instruction Subclass.  */
 typedef enum
-  {
-    NONE,
-    CVT,
-    BTSCN,
-    CD1,
-    CD2,
-    COND,
-    DIV,
-    DP,
-    DPA,
-    DPX,
-    MPY1E,
-    MPY6E,
-    MPY7E,
-    MPY8E,
-    MPY9E,
-    NPS400,
-    QUARKSE,
-    SHFT1,
-    SHFT2,
-    SWAP,
-    SP,
-    SPX
-  } insn_subclass_t;
+{
+  NONE,
+  CVT,
+  BTSCN,
+  CD1,
+  CD2,
+  COND,
+  DIV,
+  DP,
+  DPA,
+  DPX,
+  MPY1E,
+  MPY6E,
+  MPY7E,
+  MPY8E,
+  MPY9E,
+  NPS400,
+  QUARKSE,
+  SHFT1,
+  SHFT2,
+  SWAP,
+  SP,
+  SPX
+} insn_subclass_t;
 
 /* Flags class.  */
 typedef enum
-  {
-    F_CLASS_NONE = 0,
+{
+  F_CLASS_NONE = 0,
 
-    /* At most one flag from the set of flags can appear in the
-       instruction.  */
-    F_CLASS_OPTIONAL = (1 << 0),
+  /* At most one flag from the set of flags can appear in the
+     instruction.  */
+  F_CLASS_OPTIONAL = (1 << 0),
 
-    /* Exactly one from from the set of flags must appear in the
-       instruction.  */
-    F_CLASS_REQUIRED = (1 << 1),
+  /* Exactly one from from the set of flags must appear in the
+     instruction.  */
+  F_CLASS_REQUIRED = (1 << 1),
 
-    /* The conditional code can be extended over the standard variants
-       via .extCondCode pseudo-op.  */
-    F_CLASS_EXTEND = (1 << 2),
+  /* The conditional code can be extended over the standard variants
+     via .extCondCode pseudo-op.  */
+  F_CLASS_EXTEND = (1 << 2),
 
-    /* Condition code flag.  */
-    F_CLASS_COND = (1 << 3)
-  } flag_class_t;
+  /* Condition code flag.  */
+  F_CLASS_COND = (1 << 3)
+} flag_class_t;
 
 /* The opcode table is an array of struct arc_opcode.  */
 struct arc_opcode
@@ -336,11 +338,24 @@ extern const unsigned arc_NToperand;
 /* Mark the braket possition.  */
 #define ARC_OPERAND_BRAKET      0x1000
 
+/* Address type operand for NPS400.  */
+#define ARC_OPERAND_ADDRTYPE    0x2000
+
+/* Mark the colon position.  */
+#define ARC_OPERAND_COLON       0x4000
+
 /* Mask for selecting the type for typecheck purposes.  */
-#define ARC_OPERAND_TYPECHECK_MASK		\
-  (ARC_OPERAND_IR |				\
-   ARC_OPERAND_LIMM | ARC_OPERAND_SIGNED | 	\
-   ARC_OPERAND_UNSIGNED | ARC_OPERAND_BRAKET)
+#define ARC_OPERAND_TYPECHECK_MASK		 \
+  (ARC_OPERAND_IR				 \
+   | ARC_OPERAND_LIMM     | ARC_OPERAND_SIGNED	 \
+   | ARC_OPERAND_UNSIGNED | ARC_OPERAND_BRAKET   \
+   | ARC_OPERAND_ADDRTYPE | ARC_OPERAND_COLON)
+
+/* Macro to determine if an operand is a fake operand.  */
+#define ARC_OPERAND_IS_FAKE(op)                     \
+  ((operand->flags & ARC_OPERAND_FAKE)              \
+   && !((operand->flags & ARC_OPERAND_BRAKET)	    \
+	|| (operand->flags & ARC_OPERAND_COLON)))
 
 /* The flags structure.  */
 struct arc_flag_operand
@@ -608,6 +623,67 @@ extern const unsigned char arg_32bit_rc[MAX_INSN_ARGS + 1];
 extern const unsigned char arg_32bit_u6[MAX_INSN_ARGS + 1];
 extern const unsigned char arg_32bit_limm[MAX_INSN_ARGS + 1];
 
+/* Address types used in the NPS-400. See page 367 of the NPS-400 CTOP
+   Instruction Set Reference Manual v2.4 for a description of address types.  */
+
+typedef enum
+{
+  /* Addresses in memory.  */
+
+  /* Buffer descriptor.  */
+  ARC_NPS400_ADDRTYPE_BD,
+
+  /* Job identifier.  */
+  ARC_NPS400_ADDRTYPE_JID,
+
+  /* Linked Buffer Descriptor.  */
+  ARC_NPS400_ADDRTYPE_LBD,
+
+  /* Multicast Buffer Descriptor.  */
+  ARC_NPS400_ADDRTYPE_MBD,
+
+  /* Summarized Address.  */
+  ARC_NPS400_ADDRTYPE_SD,
+
+  /* SMEM Security Context Local Memory.  */
+  ARC_NPS400_ADDRTYPE_SM,
+
+  /* Extended Address.  */
+  ARC_NPS400_ADDRTYPE_XA,
+
+  /* Extended Summarized Address.  */
+  ARC_NPS400_ADDRTYPE_XD,
+
+  /* CMEM offset addresses.  */
+
+  /* On-demand Counter Descriptor.  */
+  ARC_NPS400_ADDRTYPE_CD,
+
+  /* CMEM Buffer Descriptor.  */
+  ARC_NPS400_ADDRTYPE_CBD,
+
+  /* CMEM Job Identifier.  */
+  ARC_NPS400_ADDRTYPE_CJID,
+
+  /* CMEM Linked Buffer Descriptor.  */
+  ARC_NPS400_ADDRTYPE_CLBD,
+
+  /* CMEM Offset.  */
+  ARC_NPS400_ADDRTYPE_CM,
+
+  /* CMEM Summarized Address.  */
+  ARC_NPS400_ADDRTYPE_CSD,
+
+  /* CMEM Extended Address.  */
+  ARC_NPS400_ADDRTYPE_CXA,
+
+  /* CMEM Extended Summarized Address.  */
+  ARC_NPS400_ADDRTYPE_CXD
+
+} arc_nps_address_type;
+
+#define ARC_NUM_ADDRTYPES 16
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 66551db..c218197 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,22 @@
+2016-07-27  Graham Markall  <graham.markall@embecosm.com>
+
+        * arc-nps400-tbl.h: Change block comments to GNU format.
+        * arc-dis.c: Add new globals addrtypenames,
+        addrtypenames_max, and addtypeunknown.
+        (get_addrtype): New function.
+        (print_insn_arc): Print colons and address types when
+        required.
+        * arc-opc.c: Add MAKE_INSERT_NPS_ADDRTYPE macro and use to
+        define insert and extract functions for all address types.
+        (arc_operands): Add operands for colon and all address
+        types.
+        * arc-nps-400-tbl.h: Add NPS-400 BMU instructions to opcode table.
+        * arc-opc.c: Add NPS_BD_TYPE and NPS_BMU_NUM operands,
+        insert_nps_bd_num_buff and extract_nps_bd_num_buff functions.
+        * arc-nps-400-tbl.h: Add NPS-400 PMU instructions to opcode table.
+        * arc-opc.c: Add NPS_PMU_NXT_DST and NPS_PMU_NUM_JOB operands,
+        insert_nps_pmu_num_job and extract_nps_pmu_num_job functions.
+
 2016-07-21  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* configure: Regenerated.
diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c
index 7b78bdc..73d648d 100644
--- a/opcodes/arc-dis.c
+++ b/opcodes/arc-dis.c
@@ -85,6 +85,16 @@ static const char * const regnames[64] =
   "r56", "r57", "ACCL", "ACCH", "lp_count", "rezerved", "LIMM", "pcl"
 };
 
+static const char * const addrtypenames[ARC_NUM_ADDRTYPES] =
+{
+  "bd", "jid", "lbd", "mbd", "sd", "sm", "xa", "xd",
+  "cd", "cbd", "cjid", "clbd", "cm", "csd", "cxa", "cxd"
+};
+
+static int addrtypenames_max = ARC_NUM_ADDRTYPES - 1;
+
+static const char * const addrtypeunknown = "unknown";
+
 /* This structure keeps track which instruction class(es)
    should be ignored durring disassembling.  */
 
@@ -175,7 +185,7 @@ skip_this_opcode (const struct arc_opcode *  opcode,
   /* If we found an incompatibility then we must skip.  */
   if (t != NULL)
     return TRUE;
-  
+
   /* Even if we do not precisely know the if the right mnemonics
      is correctly displayed, keep the disassmbled code class
      consistent.  */
@@ -653,6 +663,18 @@ get_auxreg (const struct arc_opcode *opcode,
   return NULL;
 }
 
+/* Convert a value representing an address type to a string used to refer to
+   the address type in assembly code.  */
+
+static const char *
+get_addrtype (int value)
+{
+  if (value < 0 || value > addrtypenames_max)
+    return addrtypeunknown;
+
+  return addrtypenames[value];
+}
+
 /* Calculate the instruction length for an instruction starting with MSB
    and LSB, the most and least significant byte.  The ISA_MASK is used to
    filter the instructions considered to only those that are part of the
@@ -1104,8 +1126,7 @@ print_insn_arc (bfd_vma memaddr,
 	}
 
       /* Only take input from real operands.  */
-      if ((operand->flags & ARC_OPERAND_FAKE)
-	  && !(operand->flags & ARC_OPERAND_BRAKET))
+      if (ARC_OPERAND_IS_FAKE (operand))
 	continue;
 
       if ((operand->flags & ARC_OPERAND_IGNORE)
@@ -1113,6 +1134,12 @@ print_insn_arc (bfd_vma memaddr,
           && value == -1)
 	continue;
 
+      if (operand->flags & ARC_OPERAND_COLON)
+        {
+          (*info->fprintf_func) (info->stream, ":");
+          continue;
+        }
+
       if (need_comma)
 	(*info->fprintf_func) (info->stream, ",");
 
@@ -1124,6 +1151,8 @@ print_insn_arc (bfd_vma memaddr,
 	  continue;
 	}
 
+      need_comma = TRUE;
+
       /* Print the operand as directed by the flags.  */
       if (operand->flags & ARC_OPERAND_IR)
 	{
@@ -1145,6 +1174,7 @@ print_insn_arc (bfd_vma memaddr,
       else if (operand->flags & ARC_OPERAND_LIMM)
 	{
 	  const char *rname = get_auxreg (opcode, value, isa_mask);
+
 	  if (rname && open_braket)
 	    (*info->fprintf_func) (info->stream, "%s", rname);
 	  else
@@ -1172,6 +1202,13 @@ print_insn_arc (bfd_vma memaddr,
 	  else
 	    (*info->fprintf_func) (info->stream, "%d", value);
 	}
+      else if (operand->flags & ARC_OPERAND_ADDRTYPE)
+        {
+          const char *addrtype = get_addrtype (value);
+          (*info->fprintf_func) (info->stream, "%s", addrtype);
+          /* A colon follow an address type.  */
+          need_comma = FALSE;
+        }
       else
 	{
 	  if (operand->flags & ARC_OPERAND_TRUNCATE
@@ -1189,8 +1226,6 @@ print_insn_arc (bfd_vma memaddr,
 		(*info->fprintf_func) (info->stream, "%#x", value);
 	    }
 	}
-
-      need_comma = TRUE;
     }
 
   return insn_len;
diff --git a/opcodes/arc-ext.c b/opcodes/arc-ext.c
index f7d2191..c12cabe 100644
--- a/opcodes/arc-ext.c
+++ b/opcodes/arc-ext.c
@@ -53,16 +53,16 @@
 
 struct ExtAuxRegister
 {
-  long			 address;
-  char*			 name;
-  struct ExtAuxRegister* next;
+  long			  address;
+  char *		  name;
+  struct ExtAuxRegister * next;
 };
 
 struct ExtCoreRegister
 {
   short		    number;
   enum ExtReadWrite rw;
-  char*		    name;
+  char *	    name;
 };
 
 struct arcExtMap
@@ -70,7 +70,7 @@ struct arcExtMap
   struct ExtAuxRegister* auxRegisters;
   struct ExtInstruction* instructions[INST_HASH_SIZE];
   struct ExtCoreRegister coreRegisters[NUM_EXT_CORE];
-  char*			 condCodes[NUM_EXT_COND];
+  char *		 condCodes[NUM_EXT_COND];
 };
 
 
diff --git a/opcodes/arc-nps400-tbl.h b/opcodes/arc-nps400-tbl.h
index 580659a..4ac038c 100644
--- a/opcodes/arc-nps400-tbl.h
+++ b/opcodes/arc-nps400-tbl.h
@@ -1,4 +1,4 @@
-/****                  Bit Manipulation Instructions                  ****/
+/* Bit Manipulation Instructions.  */
 
 /* movl<.cl> */
 { "movh", 0x48080000, 0xf81f0000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST, NPS_R_SRC1, NPS_UIMM16 }, { 0 }},
@@ -148,7 +148,7 @@
 /* crc32<.r> 0,limm,u6		00111 110 01 110100 R 111 uuuuuu 111110 */
 { "crc32", 0x3e74703e, 0xffff703f, ARC_OPCODE_ARC700, BITOP, NPS400, { ZA, LIMM, UIMM6_20 }, { C_NPS_R }},
 
-/****                 Arithmetic & Logic Instructions                 ****/
+/* Arithmetic & Logic Instructions.  */
 
 #define ADDB_LIKE(NAME,SUBOP2)                                          \
   { NAME, (0x48000000 | SUBOP2), 0xf80f001f, ARC_OPCODE_ARC700, ARITH, NPS400, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_R_SRC2_3B, NPS_SRC1_POS, NPS_SRC2_POS, NPS_ADDB_SIZE }, { C_NPS_F, C_NPS_SX }},
@@ -367,7 +367,7 @@ ADDL_LIKE ("xorl", 0xE, NPS_UIMM16)
 /* hofs a,b,min_hofs,psbc */
 { "hofs", 0x38760000, 0xf8ff0000, ARC_OPCODE_ARC700, ARITH, NPS400, { RA, RB, NPS_MIN_HOFS, NPS_PSBC }, { C_F }},
 
-/****                  Protocol Decoder Instructions                  ****/
+/* Protocol Decoder Instructions.  */
 
 /* dctcp b,c  00111bbb001011110bbbcccccc000000 */
 { "dctcp", 0x382f0000, 0xf8ff803f, ARC_OPCODE_ARC700, NET, NPS400, { RB, RC }, { 0 }},
@@ -381,12 +381,12 @@ ADDL_LIKE ("xorl", 0xE, NPS_UIMM16)
 /* dcet a,b,c  00111bbb001000000bbbccccccaaaaaa */
 { "dcet", 0x38200000, 0xf8ff8000, ARC_OPCODE_ARC700, NET, NPS400, { RA, RB, RC }, { 0 }},
 
-/****                        ACL Instructions                         ****/
+/* ACL Instructions.  */
 
 /* dcacl<.f> a,b,c  00111bbb001001010bbbccccccaaaaaa */
 { "dcacl", 0x38250000, 0xf8ff0000, ARC_OPCODE_ARC700, ACL, NPS400, { RA, RB, RC }, { C_F }},
 
-/****                        DPI Instructions                         ****/
+/* DPI Instructions.  */
 
 /* hash dst,src1,src2,width,perm,nonlinear,basemat */
 { "hash", 0x58180000, 0xf81f0000, ARC_OPCODE_ARC700, DPI, NPS400, { NPS_DPI_DST, NPS_DPI_SRC1_3B, NPS_R_SRC2_3B, NPS_HASH_WIDTH, NPS_HASH_PERM, NPS_HASH_NONLINEAR, NPS_HASH_BASEMAT }, { 0 }},
@@ -524,7 +524,7 @@ HASH_P(3, 0xC)
 /* ldbit<.x2|.x4>.di<.cl> a,[limm,c]  001001100011011X1111CCCCCCAAAAAA */
 { "ldbit", 0x2636f000, 0xff3ef000, ARC_OPCODE_ARC700, DPI, NPS400, { RA, BRAKET, LIMM, RC, BRAKETdup }, { C_NPS_LDBIT_X_2, C_NPS_LDBIT_DI, C_NPS_LDBIT_CL2 }},
 
-/****                  Pipeline Control Instructions                  ****/
+/* Pipeline Control Instructions.  */
 
 /* schd<.rw|.rd> */
 { "schd", 0x3e6f7004, 0xffffff7f, ARC_OPCODE_ARC700, CONTROL, NPS400, { 0 }, { C_NPS_SCHD_RW }},
@@ -541,7 +541,7 @@ HASH_P(3, 0xC)
 /* hwscd.restore 0,C */
 { "hwschd", 0x3e6f7003, 0xfffff03f, ARC_OPCODE_ARC700, CONTROL, NPS400, { ZA, RC }, { C_NPS_HWS_RESTORE }},
 
-/****      Load / Store From (0x57f00000 + Offset) Instructions       ****/
+/* Load / Store From (0x57f00000 + Offset) Instructions.  */
 
 #define XLDST_LIKE(NAME,SUBOP2)                                          \
   { NAME, (0x58000000 | (SUBOP2 << 16)), 0xf81f0000, ARC_OPCODE_ARC700, MEMORY, NPS400, { NPS_R_DST, BRAKET, NPS_XLDST_UIMM16, BRAKETdup }, { 0 }},
@@ -552,3 +552,99 @@ XLDST_LIKE("xld", 0xa)
 XLDST_LIKE("xstb", 0xc)
 XLDST_LIKE("xstw", 0xd)
 XLDST_LIKE("xst", 0xe)
+
+/* BMU Instructions.  */
+
+/* sbdalc dst, src1, type */
+{ "sbdalc", 0x38500040, 0xf8ff09c0, ARC_OPCODE_ARC700, BMU, NPS400, { RA, RB, NPS_BD_TYPE }, { 0 }},
+
+/* bdalc dst, [cm:src1], src1, src2 */
+{ "bdalc", 0x38100000, 0xf8ff0000, ARC_OPCODE_ARC700, BMU, NPS400, { RA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup,  RC }, { 0 }},
+
+/* bdalc dst, [cm:src1], src1, type, num_buff */
+{ "bdalc", 0x38500800, 0xf8ff0800, ARC_OPCODE_ARC700, BMU, NPS400, { RA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, NPS_BD_TYPE, NPS_BMU_NUM }, { 0 }},
+
+/* sbdfre 0, src1, src2 */
+{ "sbdfre", 0x3817003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, RB, RC }, { 0 }},
+
+/* bdfre 0, [cm:src1], src1, src2 */
+{ "bdfre", 0x3811003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, RC }, { 0 }},
+
+/* bdfre 0, [cm:src1], src1, type, num_buff */
+{ "bdfre", 0x3851083e, 0xf8ff083f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, NPS_BD_TYPE, NPS_BMU_NUM }, { 0 }},
+
+/* bdfre 0, [cm:src1], src1, num_buff */
+{ "bdfre", 0x3851003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, NPS_BMU_NUM }, { 0 }},
+
+/* bdbgt 0, src1, src2 */
+{ "bdbgt", 0x3818003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, RB, RC }, { 0 }},
+
+/* sidxalc dst, src1 */
+{ "sidxalc", 0x385c0040, 0xf8ff0040, ARC_OPCODE_ARC700, BMU, NPS400, { RA, RB }, { 0 }},
+
+/* idxalc dst, [cm:src1], src1, src2 */
+{ "idxalc", 0x381c0000, 0xf8ff0000, ARC_OPCODE_ARC700, BMU, NPS400, { RA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, RC }, { 0 }},
+
+/* idxalc dst, [cm:src1], src1, num_idx */
+{ "idxalc", 0x385c0800, 0xf8ff0800, ARC_OPCODE_ARC700, BMU, NPS400, { RA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, NPS_BMU_NUM }, { 0 }},
+
+/* sidxfre 0, src1, src2 */
+{ "sidxfre", 0x381d003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, RB, RC }, { 0 }},
+
+/* idxfre 0, [cm:src1], src1, src2 */
+{ "idxfre", 0x381e003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, RC }, { 0 }},
+
+/* idxfre 0, [cm:src1], src1, num_buff */
+{ "idxfre", 0x385e003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, NPS_BMU_NUM }, { 0 }},
+
+/* idxbgt 0, src1, src2 */
+{ "idxbgt", 0x3819003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, RB, RC }, { 0 }},
+
+/* efabgt 0, limm, src2 */
+{ "efabgt", 0x3e0d703e, 0xfffff03f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, LIMM, RC }, { 0 }},
+
+/* efabgt 0, src1, limm */
+{ "efabgt", 0x380d0fbe, 0xf8ff80ff, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, RB, LIMM }, { 0 }},
+
+/* efabgt 0, src1, src2 */
+{ "efabgt", 0x380d003e, 0xf8ff003f, ARC_OPCODE_ARC700, BMU, NPS400, { ZA, RB, RC }, { 0 }},
+
+/* efabgt dst, limm, src2 */
+{ "efabgt", 0x3e0d7000, 0xfffff000, ARC_OPCODE_ARC700, BMU, NPS400, { RA, LIMM, RC }, { 0 }},
+
+/* efabgt dst, src1, limm */
+{ "efabgt", 0x380d0f80, 0xf8ff0fc0, ARC_OPCODE_ARC700, BMU, NPS400, { RA, RB, LIMM }, { 0 }},
+
+/* efabgt dst, src1, src2 */
+{ "efabgt", 0x380d0000, 0xf8ff8000, ARC_OPCODE_ARC700, BMU, NPS400, { RA, RB, RC }, { 0 }},
+
+/* PMU Instructions. */
+
+/* jobget<.cl> 0, [cjid:src1] */
+{ "jobget", 0x3e2f7020, 0xfffff03f, ARC_OPCODE_ARC700, PMU, NPS400, { ZA, BRAKET, NPS_CJID, COLON, RC, BRAKET }, { 0 }},
+
+{ "jobget", 0x3e2f7021, 0xfffff03f, ARC_OPCODE_ARC700, PMU, NPS400, { ZA, BRAKET, NPS_CJID, COLON, RC, BRAKET }, { C_NPS_CL }},
+
+/* jobdn 0, [cjid:src1], src1, src2 */
+{ "jobdn", 0x3812003e, 0xf8ff803f, ARC_OPCODE_ARC700, PMU, NPS400, { ZA, BRAKET, NPS_CJID, COLON, RB, BRAKETdup, RBdup, RC }, { 0 }},
+
+/* jobdn 0, [cjid:src1], src1, nxt_dst */
+{ "jobdn", 0x3852003e, 0xf8ff803f, ARC_OPCODE_ARC700, PMU, NPS400, { ZA, BRAKET, NPS_CJID, COLON, RB, BRAKETdup, RBdup, NPS_PMU_NXT_DST }, { 0 }},
+
+/* sjobalc dst, src1 */
+{ "sjobalc", 0x385f0040, 0xf8ff8fc0, ARC_OPCODE_ARC700, PMU, NPS400, { RA, RB }, { 0 }},
+
+/* jobalc dst, [cm:src1], src1, num_job */
+{ "jobalc", 0x385f0800, 0xf8ff8800, ARC_OPCODE_ARC700, PMU, NPS400, { RA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, NPS_PMU_NUM_JOB }, { 0 }},
+
+/* jobalc dst, [cm:src1], src1, src2 */
+{ "jobalc", 0x381f0000, 0xf8ff8000, ARC_OPCODE_ARC700, PMU, NPS400, { RA, BRAKET, NPS_CM, COLON, RB, BRAKETdup, RBdup, RC }, { 0 }},
+
+/* jobbgt dst, src1, src2 */
+{ "jobbgt", 0x381a0000, 0xf8ff0000, ARC_OPCODE_ARC700, PMU, NPS400, { RA, RB, RC }, { 0 }},
+
+/* cnljob 0 */
+{ "cnljob", 0x3e6f70ff, 0xffffffff, ARC_OPCODE_ARC700, PMU, NPS400, { ZA }, { 0 }},
+
+/* qseq dst, [src1] */
+{ "qseq", 0x386f0028, 0xf8ff803f, ARC_OPCODE_ARC700, PMU, NPS400, { RB, BRAKET, RC, BRAKETdup }, { 0 }},
diff --git a/opcodes/arc-opc.c b/opcodes/arc-opc.c
index ad50ebc..44dd7b2 100644
--- a/opcodes/arc-opc.c
+++ b/opcodes/arc-opc.c
@@ -962,17 +962,17 @@ extract_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED,                     \
   return ((insn >> SHIFT) & ((1 << BITS) - 1)) + BIAS;                  \
 }
 
-MAKE_BIAS_INSERT_EXTRACT_FUNCS(addb_size,2,32,5,1,5)
-MAKE_BIAS_INSERT_EXTRACT_FUNCS(andb_size,1,32,5,1,5)
-MAKE_BIAS_INSERT_EXTRACT_FUNCS(fxorb_size,8,32,5,8,5)
-MAKE_BIAS_INSERT_EXTRACT_FUNCS(wxorb_size,16,32,5,16,5)
-MAKE_BIAS_INSERT_EXTRACT_FUNCS(bitop_size,1,32,5,1,10)
-MAKE_BIAS_INSERT_EXTRACT_FUNCS(qcmp_size,1,8,3,1,9)
-MAKE_BIAS_INSERT_EXTRACT_FUNCS(bitop1_size,1,32,5,1,20)
-MAKE_BIAS_INSERT_EXTRACT_FUNCS(bitop2_size,1,32,5,1,25)
-MAKE_BIAS_INSERT_EXTRACT_FUNCS(hash_width,1,32,5,1,6)
-MAKE_BIAS_INSERT_EXTRACT_FUNCS(hash_len,1,8,3,1,2)
-MAKE_BIAS_INSERT_EXTRACT_FUNCS(index3,4,7,2,4,0)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (addb_size,2,32,5,1,5)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (andb_size,1,32,5,1,5)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (fxorb_size,8,32,5,8,5)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (wxorb_size,16,32,5,16,5)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (bitop_size,1,32,5,1,10)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (qcmp_size,1,8,3,1,9)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (bitop1_size,1,32,5,1,20)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (bitop2_size,1,32,5,1,25)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (hash_width,1,32,5,1,6)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (hash_len,1,8,3,1,2)
+MAKE_BIAS_INSERT_EXTRACT_FUNCS (index3,4,7,2,4,0)
 
 static int
 extract_nps_qcmp_m3 (unsigned insn ATTRIBUTE_UNUSED,
@@ -1134,10 +1134,12 @@ extract_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED,                     \
   return value;                                                         \
 }
 
-MAKE_1BASED_INSERT_EXTRACT_FUNCS(field_size, 6, 8, 3)
-MAKE_1BASED_INSERT_EXTRACT_FUNCS(shift_factor, 9, 8, 3)
-MAKE_1BASED_INSERT_EXTRACT_FUNCS(bits_to_scramble, 12, 8, 3)
-MAKE_1BASED_INSERT_EXTRACT_FUNCS(bdlen_max_len, 5, 256, 8)
+MAKE_1BASED_INSERT_EXTRACT_FUNCS (field_size, 6, 8, 3)
+MAKE_1BASED_INSERT_EXTRACT_FUNCS (shift_factor, 9, 8, 3)
+MAKE_1BASED_INSERT_EXTRACT_FUNCS (bits_to_scramble, 12, 8, 3)
+MAKE_1BASED_INSERT_EXTRACT_FUNCS (bdlen_max_len, 5, 256, 8)
+MAKE_1BASED_INSERT_EXTRACT_FUNCS (bd_num_buff, 6, 8, 3)
+MAKE_1BASED_INSERT_EXTRACT_FUNCS (pmu_num_job, 6, 4, 2)
 
 static unsigned
 insert_nps_min_hofs (unsigned insn ATTRIBUTE_UNUSED,
@@ -1160,6 +1162,42 @@ extract_nps_min_hofs (unsigned insn ATTRIBUTE_UNUSED,
   return value * 16;
 }
 
+#define MAKE_INSERT_NPS_ADDRTYPE(NAME,VALUE)                           \
+static unsigned                                                        \
+insert_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED,                     \
+                   int value ATTRIBUTE_UNUSED,                         \
+                   const char **errmsg ATTRIBUTE_UNUSED)               \
+{                                                                      \
+  if (value != ARC_NPS400_ADDRTYPE_##VALUE)                            \
+    *errmsg = _("Invalid address type for operand");                   \
+  return insn;                                                         \
+}                                                                      \
+                                                                       \
+static int                                                             \
+extract_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED,                    \
+                    bfd_boolean * invalid ATTRIBUTE_UNUSED)            \
+{                                                                      \
+  return ARC_NPS400_ADDRTYPE_##VALUE;                                  \
+}
+
+MAKE_INSERT_NPS_ADDRTYPE (bd, BD)
+MAKE_INSERT_NPS_ADDRTYPE (jid, JID)
+MAKE_INSERT_NPS_ADDRTYPE (lbd, LBD)
+MAKE_INSERT_NPS_ADDRTYPE (mbd, MBD)
+MAKE_INSERT_NPS_ADDRTYPE (sd, SD)
+MAKE_INSERT_NPS_ADDRTYPE (sm, SM)
+MAKE_INSERT_NPS_ADDRTYPE (xa, XA)
+MAKE_INSERT_NPS_ADDRTYPE (xd, XD)
+MAKE_INSERT_NPS_ADDRTYPE (cd, CD)
+MAKE_INSERT_NPS_ADDRTYPE (cbd, CBD)
+MAKE_INSERT_NPS_ADDRTYPE (cjid, CJID)
+MAKE_INSERT_NPS_ADDRTYPE (clbd, CLBD)
+MAKE_INSERT_NPS_ADDRTYPE (cm, CM)
+MAKE_INSERT_NPS_ADDRTYPE (csd, CSD)
+MAKE_INSERT_NPS_ADDRTYPE (cxa, CXA)
+MAKE_INSERT_NPS_ADDRTYPE (cxd, CXD)
+
+
 /* Include the generic extract/insert functions.  Order is important
    as some of the functions present in the .h may be disabled via
    defines.  */
@@ -2081,6 +2119,69 @@ const struct arc_operand arc_operands[] =
 
 #define NPS_E4BY_INDEX3       (NPS_E4BY_INDEX2 + 1)
   { 2, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_index3, extract_nps_index3 },
+
+#define COLON      (NPS_E4BY_INDEX3 + 1)
+  { 0, 0, 0, ARC_OPERAND_COLON | ARC_OPERAND_FAKE, NULL, NULL },
+
+#define NPS_BD      (COLON + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_bd, extract_nps_bd },
+
+#define NPS_JID      (NPS_BD + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_jid, extract_nps_jid },
+
+#define NPS_LBD      (NPS_JID + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_lbd, extract_nps_lbd },
+
+#define NPS_MBD      (NPS_LBD + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_mbd, extract_nps_mbd },
+
+#define NPS_SD      (NPS_MBD + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_sd, extract_nps_sd },
+
+#define NPS_SM      (NPS_SD + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_sm, extract_nps_sm },
+
+#define NPS_XA      (NPS_SM + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_xa, extract_nps_xa },
+
+#define NPS_XD      (NPS_XA + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_xd, extract_nps_xd },
+
+#define NPS_CD      (NPS_XD + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_cd, extract_nps_cd },
+
+#define NPS_CBD      (NPS_CD + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_cbd, extract_nps_cbd },
+
+#define NPS_CJID      (NPS_CBD + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_cjid, extract_nps_cjid },
+
+#define NPS_CLBD      (NPS_CJID + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_clbd, extract_nps_clbd },
+
+#define NPS_CM      (NPS_CLBD + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_cm, extract_nps_cm },
+
+#define NPS_CSD      (NPS_CM + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_csd, extract_nps_csd },
+
+#define NPS_CXA      (NPS_CSD + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_cxa, extract_nps_cxa },
+
+#define NPS_CXD      (NPS_CXA + 1)
+  { 0, 0, 0, ARC_OPERAND_ADDRTYPE | ARC_OPERAND_NCHK, insert_nps_cxd, extract_nps_cxd },
+
+#define NPS_BD_TYPE     (NPS_CXD + 1)
+  { 1, 10, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_BMU_NUM     (NPS_BD_TYPE + 1)
+  { 3, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_bd_num_buff, extract_nps_bd_num_buff },
+
+#define NPS_PMU_NXT_DST     (NPS_BMU_NUM + 1)
+  { 4, 6, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+
+#define NPS_PMU_NUM_JOB     (NPS_PMU_NXT_DST + 1)
+  { 2, 6, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_pmu_num_job, extract_nps_pmu_num_job },
 };
 
 const unsigned arc_num_operands = ARRAY_SIZE (arc_operands);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]