[PATCH 6/7] arc: Change max instruction length to 64-bits

Graham Markall graham.markall@embecosm.com
Wed Oct 26 12:47:00 GMT 2016


From: Andrew Burgess <andrew.burgess@embecosm.com>

The current handling for arc instructions longer than 32-bits is all
handled as a special case in both the assembler and disassembler.

The problem with this approach is that it leads to code duplication,
selecting a long instruction is exactly the same process as selecting a
short instruction, except over more bits, in both cases we select based
on bit comparison, and initial operand insertion and extraction.

This commit unifies both the long and short instruction worlds,
converting the core opcodes library from being largely 32-bit focused,
to being largely 64-bit focused.

The changes are, on the whole, not too much.  There's obviously a lot of
type changes but otherwise the bulk of the code just works.  Most of the
actual functional changes are to code that previously handled the longer
48 or 64 bit instructions.  The insert/extract handlers for these have
now been brought into line with the short instruction insert/extract
handlers.

All of the special case handling code that was previously added has now
been removed again.  Overall, this commit reduces the amount of code in
the arc assembler and disassembler.

gas/ChangeLog:

	* config/tc-arc.c (struct arc_insn): Change type of insn field.
	(md_number_to_chars_midend): Support 6- and 8-byte values.
	(emit_insn0): Update debug output.
	(find_opcode_match): Likewise.
	(build_fake_opcode_hash_entry): Delete.
	(find_special_case_long_opcode): Delete.
	(find_special_case): Remove long format special case handling.
	(insert_operand): Change instruction type and update debug print
	format.
	(assemble_insn): Change instruction type, update debug print
	formats, and remove unneeded assert.

include/ChangeLog:

	* opcode/arc.h (struct arc_opcode): Change type of opcode and mask
	fields.
	(struct arc_long_opcode): Delete.
	(struct arc_operand): Change types for insert and extract
	handlers.

opcodes/ChangeLog:

	* arc-dis.c (struct arc_operand_iterator): Remove all fields
	relating to long instruction processing, add new limm field.
	(OPCODE): Rename to...
	(OPCODE_32BIT_INSN): ...this.
	(OPCODE_AC): Delete.
	(skip_this_opcode): Handle different instruction lengths, update
	macro name.
	(special_flag_p): Update parameter type.
	(find_format_from_table): Update for more instruction lengths.
	(find_format_long_instructions): Delete.
	(find_format): Update for more instruction lengths.
	(arc_insn_length): Likewise.
	(extract_operand_value): Update for more instruction lengths.
	(operand_iterator_next): Remove code relating to long
	instructions.
	(arc_opcode_to_insn_type): New function.
	(print_insn_arc):Update for more instructions lengths.
	* arc-ext.c (extInstruction_t): Change argument type.
	* arc-ext.h (extInstruction_t): Change argument type.
	* arc-fxi.h: Change type unsigned to unsigned long long
	extensively throughout.
	* arc-nps400-tbl.h: Add long instructions taken from
	arc_long_opcodes table in arc-opc.c.
	* arc-opc.c: Update parameter types on insert/extract handlers.
	(arc_long_opcodes): Delete.
	(arc_num_long_opcodes): Delete.
	(arc_opcode_len): Update for more instruction lengths.
---
 gas/ChangeLog            |  14 +
 gas/config/tc-arc.c      | 151 ++-------
 include/ChangeLog        |   8 +
 include/opcode/arc.h     |  35 +--
 opcodes/ChangeLog        |  30 ++
 opcodes/arc-dis.c        | 471 ++++++++++++----------------
 opcodes/arc-ext.c        |   2 +-
 opcodes/arc-ext.h        |   2 +-
 opcodes/arc-fxi.h        | 366 +++++++++++-----------
 opcodes/arc-nps400-tbl.h |  55 +++-
 opcodes/arc-opc.c        | 782 ++++++++++++++++++-----------------------------
 11 files changed, 802 insertions(+), 1114 deletions(-)

diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c
index 1c63ed8..4d2d9b7 100644
--- a/gas/config/tc-arc.c
+++ b/gas/config/tc-arc.c
@@ -304,7 +304,7 @@ struct arc_fixup
 
 struct arc_insn
 {
-  unsigned int insn;
+  unsigned long long int insn;
   int nfixups;
   struct arc_fixup fixups[MAX_INSN_FIXUPS];
   long limm;
@@ -740,21 +740,32 @@ arc_insert_opcode (const struct arc_opcode *opcode)
 }
 
 
-/* Like md_number_to_chars but used for limms.  The 4-byte limm value,
-   is encoded as 'middle-endian' for a little-endian target.  FIXME!
-   this function is used for regular 4 byte instructions as well.  */
+/* Like md_number_to_chars but for middle-endian values.  The 4-byte limm
+   value, is encoded as 'middle-endian' for a little-endian target.  This
+   function is used for regular 4, 6, and 8 byte instructions as well.  */
 
 static void
 md_number_to_chars_midend (char *buf, valueT val, int n)
 {
-  if (n == 4)
+  switch (n)
     {
+    case 2:
+      md_number_to_chars (buf, val, n);
+      break;
+    case 6:
+      md_number_to_chars (buf, (val & 0xffff00000000) >> 32, 2);
+      md_number_to_chars_midend (buf + 2, (val & 0xffffffff), 4);
+      break;
+    case 4:
       md_number_to_chars (buf,     (val & 0xffff0000) >> 16, 2);
       md_number_to_chars (buf + 2, (val & 0xffff), 2);
-    }
-  else
-    {
-      md_number_to_chars (buf, val, n);
+      break;
+    case 8:
+      md_number_to_chars_midend (buf, (val & 0xffffffff00000000) >> 32, 4);
+      md_number_to_chars_midend (buf + 4, (val & 0xffffffff), 4);
+      break;
+    default:
+      abort ();
     }
 }
 
@@ -1388,8 +1399,8 @@ emit_insn0 (struct arc_insn *insn, char *where, bfd_boolean relax)
   char *f = where;
   size_t total_len;
 
-  pr_debug ("Emit insn : 0x%x\n", insn->insn);
-  pr_debug ("\tShort   : 0x%d\n", (insn->len == 2));
+  pr_debug ("Emit insn : 0x%llx\n", insn->insn);
+  pr_debug ("\tLength  : 0x%d\n", insn->len);
   pr_debug ("\tLong imm: 0x%lx\n", insn->limm);
 
   /* Write out the instruction.  */
@@ -1668,7 +1679,7 @@ find_opcode_match (const struct arc_opcode_hash_entry *entry,
       int tokidx = 0;
       const expressionS *t = &emptyE;
 
-      pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08X ",
+      pr_debug ("%s:%d: find_opcode_match: trying opcode 0x%08llX ",
 		frag_now->fr_file, frag_now->fr_line, opcode->opcode);
 
       /* Don't match opcodes that don't exist on this
@@ -2216,108 +2227,6 @@ find_special_case_flag (const char *opname,
   return NULL;
 }
 
-/* The long instructions are not stored in a hash (there's not many of
-   them) and so there's no arc_opcode_hash_entry structure to return.  This
-   helper function for find_special_case_long_opcode takes an arc_opcode
-   result and places it into a fake arc_opcode_hash_entry that points to
-   the single arc_opcode OPCODE, which is then returned.  */
-
-static const struct arc_opcode_hash_entry *
-build_fake_opcode_hash_entry (const struct arc_opcode *opcode)
-{
-  static struct arc_opcode_hash_entry entry;
-  static struct arc_opcode tmp[2];
-  static const struct arc_opcode *ptr[2];
-
-  memcpy (&tmp[0], opcode, sizeof (struct arc_opcode));
-  memset (&tmp[1], 0, sizeof (struct arc_opcode));
-  entry.count = 1;
-  entry.opcode = ptr;
-  ptr[0] = tmp;
-  ptr[1] = NULL;
-  return &entry;
-}
-
-
-/* Used by the assembler to match the list of tokens against a long (48 or
-   64 bits) instruction.  If a matching long instruction is found, then
-   some of the tokens are consumed in this function and converted into a
-   single LIMM value, which is then added to the end of the token list,
-   where it will be consumed by a LIMM operand that exists in the base
-   opcode of the long instruction.  */
-
-static const struct arc_opcode_hash_entry *
-find_special_case_long_opcode (const char *opname,
-                               int *ntok ATTRIBUTE_UNUSED,
-                               expressionS *tok ATTRIBUTE_UNUSED,
-                               int *nflgs,
-                               struct arc_flags *pflags)
-{
-  unsigned i;
-
-  if (*ntok == MAX_INSN_ARGS)
-    return NULL;
-
-  for (i = 0; i < arc_num_long_opcodes; ++i)
-    {
-      struct arc_opcode fake_opcode;
-      const struct arc_opcode *opcode;
-      struct arc_insn insn;
-      expressionS *limm_token;
-
-      opcode = &arc_long_opcodes[i].base_opcode;
-
-      if (!(opcode->cpu & arc_target))
-        continue;
-
-      if (!check_cpu_feature (opcode->subclass))
-        continue;
-
-      if (strcmp (opname, opcode->name) != 0)
-        continue;
-
-      /* Check that the flags are a match.  */
-      if (!parse_opcode_flags (opcode, *nflgs, pflags))
-        continue;
-
-      /* Parse the LIMM operands into the LIMM template.  */
-      memset (&fake_opcode, 0, sizeof (fake_opcode));
-      fake_opcode.name = "fake limm";
-      fake_opcode.opcode = arc_long_opcodes[i].limm_template;
-      fake_opcode.mask = arc_long_opcodes[i].limm_mask;
-      fake_opcode.cpu = opcode->cpu;
-      fake_opcode.insn_class = opcode->insn_class;
-      fake_opcode.subclass = opcode->subclass;
-      memcpy (&fake_opcode.operands[0],
-              &arc_long_opcodes[i].operands,
-              MAX_INSN_ARGS);
-      /* Leave fake_opcode.flags as zero.  */
-
-      pr_debug ("Calling assemble_insn to build fake limm value\n");
-      assemble_insn (&fake_opcode, tok, *ntok,
-                     NULL, 0, &insn);
-      pr_debug ("   got limm value: 0x%x\n", insn.insn);
-
-      /* Now create a new token at the end of the token array (We know this
-         is safe as the token array is always created with enough space for
-         MAX_INSN_ARGS, and we check at the start at the start of this
-         function that we're not there yet).  This new token will
-         correspond to a LIMM operand that will be contained in the
-         base_opcode of the arc_long_opcode.  */
-      limm_token = &tok[(*ntok)];
-      (*ntok)++;
-
-      /* Modify the LIMM token to hold the constant.  */
-      limm_token->X_op = O_constant;
-      limm_token->X_add_number = insn.insn;
-
-      /* Return the base opcode.  */
-      return build_fake_opcode_hash_entry (opcode);
-    }
-
-    return NULL;
-}
-
 /* Used to find special case opcode.  */
 
 static const struct arc_opcode_hash_entry *
@@ -2334,9 +2243,6 @@ find_special_case (const char *opname,
   if (entry == NULL)
     entry = find_special_case_flag (opname, nflgs, pflags);
 
-  if (entry == NULL)
-    entry = find_special_case_long_opcode (opname, ntok, tok, nflgs, pflags);
-
   return entry;
 }
 
@@ -2735,8 +2641,8 @@ find_operand_for_reloc (extended_bfd_reloc_code_real_type reloc)
 
 /* Insert an operand value into an instruction.  */
 
-static unsigned
-insert_operand (unsigned insn,
+static unsigned long long
+insert_operand (unsigned long long insn,
 		const struct arc_operand *operand,
 		offsetT val,
 		const char *file,
@@ -2764,7 +2670,7 @@ insert_operand (unsigned insn,
 				   val, min, max, file, line);
     }
 
-  pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08x\n",
+  pr_debug ("insert field: %ld <= %ld <= %ld in 0x%08llx\n",
 	    min, val, max, insn);
 
   if ((operand->flags & ARC_OPERAND_ALIGNED32)
@@ -3762,7 +3668,7 @@ assemble_insn (const struct arc_opcode *opcode,
 	       struct arc_insn *insn)
 {
   const expressionS *reloc_exp = NULL;
-  unsigned image;
+  unsigned long long image;
   const unsigned char *argidx;
   int i;
   int tokidx = 0;
@@ -3774,7 +3680,7 @@ assemble_insn (const struct arc_opcode *opcode,
   memset (insn, 0, sizeof (*insn));
   image = opcode->opcode;
 
-  pr_debug ("%s:%d: assemble_insn: %s using opcode %x\n",
+  pr_debug ("%s:%d: assemble_insn: %s using opcode %llx\n",
 	    frag_now->fr_file, frag_now->fr_line, opcode->name,
 	    opcode->opcode);
 
@@ -4004,7 +3910,6 @@ assemble_insn (const struct arc_opcode *opcode,
 
   /* Instruction length.  */
   insn->len = arc_opcode_len (opcode);
-  gas_assert (insn->len == 2 || insn->len == 4);
 
   insn->insn = image;
 
diff --git a/include/opcode/arc.h b/include/opcode/arc.h
index 5e10d2a..f5cb9e9 100644
--- a/include/opcode/arc.h
+++ b/include/opcode/arc.h
@@ -116,13 +116,13 @@ struct arc_opcode
 
   /* The opcode itself.  Those bits which will be filled in with
      operands are zeroes.  */
-  unsigned opcode;
+  unsigned long long opcode;
 
   /* The opcode mask.  This is used by the disassembler.  This is a
      mask containing ones indicating those bits which must match the
      opcode field, and zeroes indicating those bits which need not
      match (and are presumably filled in by operands).  */
-  unsigned mask;
+  unsigned long long mask;
 
   /* One bit flags for the opcode.  These are primarily used to
      indicate specific processors and environments support the
@@ -146,30 +146,6 @@ struct arc_opcode
   unsigned char flags[MAX_INSN_FLGS + 1];
 };
 
-/* Structure used to describe 48 and 64 bit instructions.  */
-struct arc_long_opcode
-{
-  /* The base instruction is either 16 or 32 bits, and is described like a
-     normal instruction.  */
-  struct arc_opcode base_opcode;
-
-  /* The template value for the 32-bit LIMM extension.  Used by the
-     assembler and disassembler in the same way as the 'opcode' field of
-     'struct arc_opcode'.  */
-  unsigned limm_template;
-
-  /* The mask value for the 32-bit LIMM extension.  Used by the
-     disassembler just like the 'mask' field in 'struct arc_opcode'.  */
-  unsigned limm_mask;
-
-  /* Array of operand codes similar to the 'operands' array in 'struct
-     arc_opcode'.  These operands are used to fill in the LIMM value.  */
-  unsigned char operands[MAX_INSN_ARGS + 1];
-};
-
-extern const struct arc_long_opcode arc_long_opcodes[];
-extern const unsigned arc_num_long_opcodes;
-
 /* The table itself is sorted by major opcode number, and is otherwise
    in the order in which the disassembler should consider
    instructions.  */
@@ -262,7 +238,9 @@ struct arc_operand
      string (the operand will be inserted in any case).	 If the
      operand value is legal, *ERRMSG will be unchanged (most operands
      can accept any value).  */
-  unsigned (*insert) (unsigned instruction, int op, const char **errmsg);
+  unsigned long long (*insert) (unsigned long long instruction,
+                                long long int op,
+                                const char **errmsg);
 
   /* Extraction function.  This is used by the disassembler.  To
      extract this operand type from an instruction, check this field.
@@ -281,7 +259,8 @@ struct arc_operand
      TRUE if this operand type can not actually be extracted from
      this operand (i.e., the instruction does not match).  If the
      operand is valid, *INVALID will not be changed.  */
-  int (*extract) (unsigned instruction, bfd_boolean *invalid);
+  long long int (*extract) (unsigned long long instruction,
+                            bfd_boolean *invalid);
 };
 
 /* Elements in the table are retrieved by indexing with values from
diff --git a/opcodes/arc-dis.c b/opcodes/arc-dis.c
index 64bfecd..1c951ea 100644
--- a/opcodes/arc-dis.c
+++ b/opcodes/arc-dis.c
@@ -37,37 +37,18 @@
 
 struct arc_operand_iterator
 {
-  enum
-    {
-      OPERAND_ITERATOR_STANDARD,
-      OPERAND_ITERATOR_LONG
-    } mode;
-
-  /* The array of 32-bit values that make up this instruction.  All
-     required values have been pre-loaded into this array during the
-     find_format call.  */
-  unsigned *insn;
-
-  union
-  {
-    struct
-    {
-      /* The opcode this iterator is operating on.  */
-      const struct arc_opcode *opcode;
+  /* The complete instruction value to extract operands from.  */
+  unsigned long long insn;
 
-      /* The index into the opcodes operand index list.  */
-      const unsigned char *opidx;
-    } standard;
+  /* The LIMM if this is being tracked separately.  This field is only
+     valid if we find the LIMM operand in the operand list.  */
+  unsigned limm;
 
-    struct
-    {
-      /* The long instruction opcode this iterator is operating on.  */
-      const struct arc_long_opcode *long_opcode;
+  /* The opcode this iterator is operating on.  */
+  const struct arc_opcode *opcode;
 
-      /* Two indexes into the opcodes operand index lists.  */
-      const unsigned char *opidx_base, *opidx_limm;
-    } long_insn;
-  } state;
+  /* The index into the opcodes operand index list.  */
+  const unsigned char *opidx;
 };
 
 /* Globals variables.  */
@@ -123,9 +104,7 @@ static linkclass decodelist = NULL;
 
 #define BITS(word,s,e)  (((word) << (sizeof (word) * 8 - 1 - e)) >>	\
 			 (s + (sizeof (word) * 8 - 1 - e)))
-#define OPCODE(word)	(BITS ((word), 27, 31))
-
-#define OPCODE_AC(word)   (BITS ((word), 11, 15))
+#define OPCODE_32BIT_INSN(word)	(BITS ((word), 27, 31))
 
 /* Functions implementation.  */
 
@@ -169,7 +148,8 @@ skip_this_opcode (const struct arc_opcode *  opcode,
   bfd_boolean addme = TRUE;
 
   /* Check opcode for major 0x06, return if it is not in.  */
-  if (OPCODE (opcode->opcode) != 0x06)
+  if (arc_opcode_len (opcode) == 4
+      && OPCODE_32BIT_INSN (opcode->opcode) != 0x06)
     return FALSE;
 
   while (t != NULL
@@ -255,7 +235,7 @@ special_flag_p (const char *opname,
 static const struct arc_opcode *
 find_format_from_table (struct disassemble_info *info,
 			const struct arc_opcode *arc_table,
-                        unsigned *insn,
+                        unsigned long long insn,
 			unsigned int insn_len,
                         unsigned isa_mask,
 			bfd_boolean *has_limm,
@@ -272,23 +252,13 @@ find_format_from_table (struct disassemble_info *info,
 
       opcode = &arc_table[i++];
 
-      if ((arc_opcode_len (opcode) == 2) && (insn_len == 2))
-	{
-	  if (OPCODE_AC (opcode->opcode) != OPCODE_AC (insn[0]))
-	    continue;
-	}
-      else if ((arc_opcode_len (opcode) == 4) && (insn_len == 4))
-	{
-	  if (OPCODE (opcode->opcode) != OPCODE (insn[0]))
-	    continue;
-	}
-      else
+      if (!(opcode->cpu & isa_mask))
 	continue;
 
-      if ((insn[0] ^ opcode->opcode) & opcode->mask)
+      if (arc_opcode_len (opcode) != (int) insn_len)
 	continue;
 
-      if (!(opcode->cpu & isa_mask))
+      if ((insn & opcode->mask) != opcode->opcode)
 	continue;
 
       *has_limm = FALSE;
@@ -303,9 +273,9 @@ find_format_from_table (struct disassemble_info *info,
 	    continue;
 
 	  if (operand->extract)
-	    value = (*operand->extract) (insn[0], &invalid);
+	    value = (*operand->extract) (insn, &invalid);
 	  else
-	    value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
+	    value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
 
 	  /* Check for LIMM indicator.  If it is there, then make sure
 	     we pick the right format.  */
@@ -338,7 +308,7 @@ find_format_from_table (struct disassemble_info *info,
 	  /* Check first the extensions.  */
 	  if (cl_flags->flag_class & F_CLASS_EXTEND)
 	    {
-	      value = (insn[0] & 0x1F);
+	      value = (insn & 0x1F);
 	      if (arcExtMap_condCodeName (value))
 		continue;
 	    }
@@ -348,7 +318,7 @@ find_format_from_table (struct disassemble_info *info,
 	      const struct arc_flag_operand *flg_operand =
 		&arc_flag_operands[*flgopridx];
 
-	      value = (insn[0] >> flg_operand->shift)
+	      value = (insn >> flg_operand->shift)
 		& ((1 << flg_operand->bits) - 1);
 	      if (value == flg_operand->code)
 		foundA = 1;
@@ -379,97 +349,33 @@ find_format_from_table (struct disassemble_info *info,
   return NULL;
 }
 
-/* Find long instructions matching values in INSN array.  */
-
-static const struct arc_long_opcode *
-find_format_long_instructions (unsigned *insn,
-                               unsigned int *insn_len,
-                               unsigned isa_mask,
-                               bfd_vma memaddr,
-                               struct disassemble_info *info)
-{
-  unsigned int i;
-  unsigned limm = 0;
-  bfd_boolean limm_loaded = FALSE;
-
-  for (i = 0; i < arc_num_long_opcodes; ++i)
-    {
-      bfd_byte buffer[4];
-      int status;
-      const struct arc_opcode *opcode;
-
-      opcode = &arc_long_opcodes[i].base_opcode;
-
-      if ((arc_opcode_len (opcode) == 2) && (*insn_len == 2))
-        {
-          if (OPCODE_AC (opcode->opcode) != OPCODE_AC (insn[0]))
-            continue;
-        }
-      else if ((arc_opcode_len (opcode) == 4) && (*insn_len == 4))
-        {
-          if (OPCODE (opcode->opcode) != OPCODE (insn[0]))
-            continue;
-        }
-      else
-        continue;
-
-      if ((insn[0] ^ opcode->opcode) & opcode->mask)
-        continue;
-
-      if (!(opcode->cpu & isa_mask))
-        continue;
-
-      if (!limm_loaded)
-        {
-          status = (*info->read_memory_func) (memaddr + *insn_len, buffer,
-                                              4, info);
-          if (status != 0)
-            return NULL;
-
-          limm = ARRANGE_ENDIAN (info, buffer);
-          limm_loaded = TRUE;
-        }
-
-      /* Check the second word using the mask and template.  */
-      if ((limm & arc_long_opcodes[i].limm_mask)
-          != arc_long_opcodes[i].limm_template)
-        continue;
-
-      (*insn_len) += 4;
-      insn[1] = limm;
-      return &arc_long_opcodes[i];
-    }
-
-  return NULL;
-}
-
 /* Find opcode for INSN, trying various different sources.  The instruction
    length in INSN_LEN will be updated if the instruction requires a LIMM
-   extension, and the additional values loaded into the INSN array (which
-   must be big enough).
+   extension.
 
    A pointer to the opcode is placed into OPCODE_RESULT, and ITER is
-   initialised, ready to iterate over the operands of the found opcode.
+   initialised, ready to iterate over the operands of the found opcode.  If
+   the found opcode requires a LIMM then the LIMM value will be loaded into a
+   field of ITER.
 
    This function returns TRUE in almost all cases, FALSE is reserved to
-   indicate an error (failing to find an opcode is not an error) a
-   returned result of FALSE would indicate that the disassembler can't
-   continue.
+   indicate an error (failing to find an opcode is not an error) a returned
+   result of FALSE would indicate that the disassembler can't continue.
 
-   If no matching opcode is found then the returned result will be TRUE,
-   the value placed into OPCODE_RESULT will be NULL, ITER will be
-   undefined, and INSN_LEN will be unchanged.
+   If no matching opcode is found then the returned result will be TRUE, the
+   value placed into OPCODE_RESULT will be NULL, ITER will be undefined, and
+   INSN_LEN will be unchanged.
 
-   If a matching opcode is found, then the returned result will be TRUE,
-   the opcode pointer is placed into OPCODE_RESULT, INSN_LEN will be
-   increased by 4 if the instruction requires a LIMM, and the LIMM value
-   will have been loaded into the INSN[1].  Finally, ITER will have been
-   initialised so that calls to OPERAND_ITERATOR_NEXT will iterate over
-   the opcode's operands.  */
+   If a matching opcode is found, then the returned result will be TRUE, the
+   opcode pointer is placed into OPCODE_RESULT, INSN_LEN will be increased by
+   4 if the instruction requires a LIMM, and the LIMM value will have been
+   loaded into a field of ITER.  Finally, ITER will have been initialised so
+   that calls to OPERAND_ITERATOR_NEXT will iterate over the opcode's
+   operands.  */
 
 static bfd_boolean
 find_format (bfd_vma                       memaddr,
-	     unsigned *                    insn,
+	     unsigned long long            insn,
 	     unsigned int *                insn_len,
              unsigned                      isa_mask,
 	     struct disassemble_info *     info,
@@ -479,24 +385,28 @@ find_format (bfd_vma                       memaddr,
   const struct arc_opcode *opcode = NULL;
   bfd_boolean needs_limm;
   const extInstruction_t *einsn, *i;
+  unsigned limm = 0;
 
   /* First, try the extension instructions.  */
-  einsn = arcExtMap_insn (OPCODE (insn[0]), insn[0]);
-  for (i = einsn; (i != NULL) && (opcode == NULL); i = i->next)
+  if (*insn_len == 4)
     {
-      const char *errmsg = NULL;
-
-      opcode = arcExtMap_genOpcode (i, isa_mask, &errmsg);
-      if (opcode == NULL)
+      einsn = arcExtMap_insn (OPCODE_32BIT_INSN (insn), insn);
+      for (i = einsn; (i != NULL) && (opcode == NULL); i = i->next)
 	{
-	  (*info->fprintf_func) (info->stream, "\
+	  const char *errmsg = NULL;
+
+	  opcode = arcExtMap_genOpcode (i, isa_mask, &errmsg);
+	  if (opcode == NULL)
+	    {
+	      (*info->fprintf_func) (info->stream, "\
 An error occured while generating the extension instruction operations");
-	  *opcode_result = NULL;
-	  return FALSE;
-	}
+	      *opcode_result = NULL;
+	      return FALSE;
+	    }
 
-      opcode = find_format_from_table (info, opcode, insn, *insn_len,
-				       isa_mask, &needs_limm, FALSE);
+	  opcode = find_format_from_table (info, opcode, insn, *insn_len,
+					   isa_mask, &needs_limm, FALSE);
+	}
     }
 
   /* Then, try finding the first match in the opcode table.  */
@@ -517,38 +427,17 @@ An error occured while generating the extension instruction operations");
         }
       else
         {
-          insn[1] = ARRANGE_ENDIAN (info, buffer);
+          limm = ARRANGE_ENDIAN (info, buffer);
           *insn_len += 4;
         }
     }
 
-  if (opcode == NULL)
-    {
-      const struct arc_long_opcode *long_opcode;
-
-      /* No instruction found yet, try the long instructions.  */
-      long_opcode =
-        find_format_long_instructions (insn, insn_len, isa_mask,
-                                       memaddr, info);
-
-      if (long_opcode != NULL)
-        {
-          iter->mode = OPERAND_ITERATOR_LONG;
-          iter->insn = insn;
-          iter->state.long_insn.long_opcode = long_opcode;
-          iter->state.long_insn.opidx_base =
-            long_opcode->base_opcode.operands;
-          iter->state.long_insn.opidx_limm =
-            long_opcode->operands;
-          opcode = &long_opcode->base_opcode;
-        }
-    }
-  else
+  if (opcode != NULL)
     {
-      iter->mode = OPERAND_ITERATOR_STANDARD;
       iter->insn = insn;
-      iter->state.standard.opcode = opcode;
-      iter->state.standard.opidx = opcode->operands;
+      iter->limm = limm;
+      iter->opcode = opcode;
+      iter->opidx = opcode->operands;
     }
 
   *opcode_result = opcode;
@@ -557,7 +446,7 @@ An error occured while generating the extension instruction operations");
 
 static void
 print_flags (const struct arc_opcode *opcode,
-	     unsigned *insn,
+	     unsigned long long *insn,
 	     struct disassemble_info *info)
 {
   const unsigned char *flgidx;
@@ -701,8 +590,10 @@ arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
         {
           bfd_byte minor_opcode = lsb & 0x1f;
 
-          if (minor_opcode < 4)
-            return 2;
+	  if (minor_opcode < 4)
+	    return 6;
+	  else if (minor_opcode == 0x10 || minor_opcode == 0x11)
+	    return 8;
         }
       /* Fall through.  */
     case bfd_mach_arc_arc600:
@@ -722,7 +613,9 @@ arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
    is held in the array INSN.  */
 
 static int
-extract_operand_value (const struct arc_operand *operand, unsigned *insn)
+extract_operand_value (const struct arc_operand *operand,
+		       unsigned long long insn,
+		       unsigned limm)
 {
   int value;
 
@@ -730,22 +623,22 @@ extract_operand_value (const struct arc_operand *operand, unsigned *insn)
   if (operand->flags & ARC_OPERAND_LIMM)
     /* The second part of the instruction value will have been loaded as
        part of the find_format call made earlier.  */
-    value = insn[1];
+    value = limm;
   else
     {
       if (operand->extract)
-        value = (*operand->extract) (insn[0], (int *) NULL);
+        value = (*operand->extract) (insn, (int *) NULL);
       else
         {
           if (operand->flags & ARC_OPERAND_ALIGNED32)
             {
-              value = (insn[0] >> operand->shift)
+              value = (insn >> operand->shift)
                 & ((1 << (operand->bits - 2)) - 1);
               value = value << 2;
             }
           else
             {
-              value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
+              value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
             }
           if (operand->flags & ARC_OPERAND_SIGNED)
             {
@@ -769,66 +662,16 @@ operand_iterator_next (struct arc_operand_iterator *iter,
                        const struct arc_operand **operand,
                        int *value)
 {
-  if (iter->mode == OPERAND_ITERATOR_STANDARD)
+  if (*iter->opidx == 0)
     {
-      if (*iter->state.standard.opidx == 0)
-        {
-          *operand = NULL;
-          return FALSE;
-        }
-
-      *operand = &arc_operands[*iter->state.standard.opidx];
-      *value = extract_operand_value (*operand, iter->insn);
-      iter->state.standard.opidx++;
+      *operand = NULL;
+      return FALSE;
     }
-  else
-    {
-      const struct arc_operand *operand_base, *operand_limm;
-      int value_base, value_limm;
-
-      if (*iter->state.long_insn.opidx_limm == 0)
-        {
-          *operand = NULL;
-          return FALSE;
-        }
-
-      operand_base = &arc_operands[*iter->state.long_insn.opidx_base];
-      operand_limm = &arc_operands[*iter->state.long_insn.opidx_limm];
-
-      if (operand_base->flags & ARC_OPERAND_LIMM)
-        {
-          /* We've reached the end of the operand list.  */
-          *operand = NULL;
-          return FALSE;
-        }
-
-      value_base = value_limm = 0;
-      if (!(operand_limm->flags & ARC_OPERAND_IGNORE))
-        {
-          /* This should never happen.  If it does then the use of
-             extract_operand_value below will access memory beyond
-             the insn array.  */
-          assert ((operand_limm->flags & ARC_OPERAND_LIMM) == 0);
-
-          *operand = operand_limm;
-          value_limm = extract_operand_value (*operand, &iter->insn[1]);
-        }
 
-      if (!(operand_base->flags & ARC_OPERAND_IGNORE))
-        {
-          *operand = operand_base;
-          value_base = extract_operand_value (*operand, iter->insn);
-        }
+  *operand = &arc_operands[*iter->opidx];
+  *value = extract_operand_value (*operand, iter->insn, iter->limm);
+  iter->opidx++;
 
-      /* This is a bit of a fudge.  There's no reason why simply ORing
-         together the two values is the right thing to do, however, for all
-         the cases we currently have, it is the right thing, so, for now,
-         I've put off solving the more complex problem.  */
-      *value = value_base | value_limm;
-
-      iter->state.long_insn.opidx_base++;
-      iter->state.long_insn.opidx_limm++;
-    }
   return TRUE;
 }
 
@@ -891,17 +734,55 @@ parse_disassembler_options (char *options)
     }
 }
 
+/* Return the instruction type for an instruction described by OPCODE.  */
+
+static enum dis_insn_type
+arc_opcode_to_insn_type (const struct arc_opcode *opcode)
+{
+  enum dis_insn_type insn_type;
+
+  switch (opcode->insn_class)
+    {
+    case BRANCH:
+    case JUMP:
+      if (!strncmp (opcode->name, "bl", 2)
+	  || !strncmp (opcode->name, "jl", 2))
+	{
+	  if (opcode->subclass == COND)
+	    insn_type = dis_condjsr;
+	  else
+	    insn_type = dis_jsr;
+	}
+      else
+	{
+	  if (opcode->subclass == COND)
+	    insn_type = dis_condbranch;
+	  else
+	    insn_type = dis_branch;
+	}
+      break;
+    case MEMORY:
+      insn_type = dis_dref; /* FIXME! DB indicates mov as memory! */
+      break;
+    default:
+      insn_type = dis_nonbranch;
+      break;
+    }
+
+  return insn_type;
+}
+
 /* Disassemble ARC instructions.  */
 
 static int
 print_insn_arc (bfd_vma memaddr,
 		struct disassemble_info *info)
 {
-  bfd_byte buffer[4];
-  unsigned int lowbyte, highbyte;
+  bfd_byte buffer[8];
+  unsigned int highbyte, lowbyte;
   int status;
   unsigned int insn_len;
-  unsigned insn[2] = { 0, 0 };
+  unsigned long long insn = 0;
   unsigned isa_mask;
   const struct arc_opcode *opcode;
   bfd_boolean need_comma;
@@ -1031,26 +912,57 @@ print_insn_arc (bfd_vma memaddr,
   switch (insn_len)
     {
     case 2:
-      insn[0] = (buffer[highbyte] << 8) | buffer[lowbyte];
+      insn = (buffer[highbyte] << 8) | buffer[lowbyte];
       break;
 
-    default:
-      /* An unknown instruction is treated as being length 4.  This is
-         possibly not the best solution, but matches the behaviour that was
-         in place before the table based instruction length look-up was
-         introduced.  */
     case 4:
-      /* This is a long instruction: Read the remaning 2 bytes.  */
-      status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
-      if (status != 0)
-	{
-	  (*info->memory_error_func) (status, memaddr + 2, info);
-	  return -1;
-	}
-      insn[0] = ARRANGE_ENDIAN (info, buffer);
+      {
+	/* This is a long instruction: Read the remaning 2 bytes.  */
+	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
+	if (status != 0)
+	  {
+	    (*info->memory_error_func) (status, memaddr + 2, info);
+	    return -1;
+	  }
+	insn = (unsigned long long) ARRANGE_ENDIAN (info, buffer);
+      }
+      break;
+
+    case 6:
+      {
+	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 4, info);
+	if (status != 0)
+	  {
+	    (*info->memory_error_func) (status, memaddr + 2, info);
+	    return -1;
+	  }
+	insn = (unsigned long long) ARRANGE_ENDIAN (info, &buffer[2]);
+	insn |= ((unsigned long long) buffer[highbyte] << 40)
+	  | ((unsigned long long) buffer[lowbyte] << 32);
+      }
       break;
+
+    case 8:
+      {
+	status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 6, info);
+	if (status != 0)
+	  {
+	    (*info->memory_error_func) (status, memaddr + 2, info);
+	    return -1;
+	  }
+	insn =
+	  ((((unsigned long long) ARRANGE_ENDIAN (info, buffer)) << 32)
+	   | ((unsigned long long) ARRANGE_ENDIAN (info, &buffer[4])));
+      }
+      break;
+
+    default:
+      /* There is no instruction whose length is not 2, 4, 6, or 8.  */
+      abort ();
     }
 
+  pr_debug ("instruction value = %llx\n", insn);
+
   /* Set some defaults for the insn info.  */
   info->insn_info_valid    = 1;
   info->branch_delay_insns = 0;
@@ -1068,10 +980,31 @@ print_insn_arc (bfd_vma memaddr,
 
   if (!opcode)
     {
-      if (insn_len == 2)
-        (*info->fprintf_func) (info->stream, ".long %#04x", insn[0]);
-      else
-        (*info->fprintf_func) (info->stream, ".long %#08x", insn[0]);
+      switch (insn_len)
+	{
+	case 2:
+	  (*info->fprintf_func) (info->stream, ".long %#04llx",
+				 insn & 0xffff);
+	  break;
+	case 4:
+	  (*info->fprintf_func) (info->stream, ".long %#08llx",
+				 insn & 0xffffffff);
+	  break;
+	case 6:
+	  (*info->fprintf_func) (info->stream, ".long %#08llx",
+				 insn & 0xffffffff);
+	  (*info->fprintf_func) (info->stream, ".long %#04llx",
+				 (insn >> 32) & 0xffff);
+	  break;
+	case 8:
+	  (*info->fprintf_func) (info->stream, ".long %#08llx",
+				 insn & 0xffffffff);
+	  (*info->fprintf_func) (info->stream, ".long %#08llx",
+				 insn >> 32);
+	  break;
+	default:
+	  abort ();
+	}
 
       info->insn_type = dis_noninsn;
       return insn_len;
@@ -1081,37 +1014,11 @@ print_insn_arc (bfd_vma memaddr,
   (*info->fprintf_func) (info->stream, "%s", opcode->name);
 
   /* Preselect the insn class.  */
-  switch (opcode->insn_class)
-    {
-    case BRANCH:
-    case JUMP:
-      if (!strncmp (opcode->name, "bl", 2)
-	  || !strncmp (opcode->name, "jl", 2))
-	{
-	  if (opcode->subclass == COND)
-	    info->insn_type = dis_condjsr;
-	  else
-	    info->insn_type = dis_jsr;
-	}
-      else
-	{
-	  if (opcode->subclass == COND)
-	    info->insn_type = dis_condbranch;
-	  else
-	    info->insn_type = dis_branch;
-	}
-      break;
-    case MEMORY:
-      info->insn_type = dis_dref; /* FIXME! DB indicates mov as memory! */
-      break;
-    default:
-      info->insn_type = dis_nonbranch;
-      break;
-    }
+  info->insn_type = arc_opcode_to_insn_type (opcode);
 
-  pr_debug ("%s: 0x%08x\n", opcode->name, opcode->opcode);
+  pr_debug ("%s: 0x%08llx\n", opcode->name, opcode->opcode);
 
-  print_flags (opcode, insn, info);
+  print_flags (opcode, &insn, info);
 
   if (opcode->operands[0] != 0)
     (*info->fprintf_func) (info->stream, "\t");
diff --git a/opcodes/arc-ext.c b/opcodes/arc-ext.c
index 3cf3e2f..d0c0bcb 100644
--- a/opcodes/arc-ext.c
+++ b/opcodes/arc-ext.c
@@ -280,7 +280,7 @@ ExtReadWrite_image (enum ExtReadWrite val)
 /* Get the name of an extension instruction.  */
 
 const extInstruction_t *
-arcExtMap_insn (int opcode, int insn)
+arcExtMap_insn (int opcode, unsigned long long insn)
 {
   /* Here the following tasks need to be done.  First of all, the
      opcode stored in the Extension Map is the real opcode.  However,
diff --git a/opcodes/arc-ext.h b/opcodes/arc-ext.h
index 9e41f5b..2586776 100644
--- a/opcodes/arc-ext.h
+++ b/opcodes/arc-ext.h
@@ -127,7 +127,7 @@ extern enum ExtReadWrite arcExtMap_coreReadWrite (int);
 extern const char * arcExtMap_coreRegName (int);
 extern const char * arcExtMap_auxRegName (long);
 extern const char * arcExtMap_condCodeName (int);
-extern const extInstruction_t *arcExtMap_insn (int, int);
+extern const extInstruction_t *arcExtMap_insn (int, unsigned long long);
 extern struct arc_opcode *arcExtMap_genOpcode (const extInstruction_t *,
 					       unsigned arc_target,
 					       const char **errmsg);
diff --git a/opcodes/arc-fxi.h b/opcodes/arc-fxi.h
index a86e5b5..9d0fdb9 100644
--- a/opcodes/arc-fxi.h
+++ b/opcodes/arc-fxi.h
@@ -23,9 +23,9 @@
 #define INSERT_LIMM
 /* mask = 00000000000000000000000000000000
    insn = 00100bbb00101111FBBB111110001001.  */
-static unsigned
-insert_limm (unsigned insn ATTRIBUTE_UNUSED,
-	     int value ATTRIBUTE_UNUSED, const char **errmsg ATTRIBUTE_UNUSED)
+static unsigned long long
+insert_limm (unsigned long long insn ATTRIBUTE_UNUSED,
+	     long long int value ATTRIBUTE_UNUSED, const char **errmsg ATTRIBUTE_UNUSED)
 {
 
   return insn;
@@ -36,7 +36,7 @@ insert_limm (unsigned insn ATTRIBUTE_UNUSED,
 #define EXTRACT_LIMM
 /* mask = 00000000000000000000000000000000.  */
 static ATTRIBUTE_UNUSED int
-extract_limm (unsigned insn ATTRIBUTE_UNUSED, bfd_boolean * invalid ATTRIBUTE_UNUSED)
+extract_limm (unsigned long long insn ATTRIBUTE_UNUSED, bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
 
@@ -48,9 +48,9 @@ extract_limm (unsigned insn ATTRIBUTE_UNUSED, bfd_boolean * invalid ATTRIBUTE_UN
 #define INSERT_UIMM6_20
 /* mask = 00000000000000000000111111000000
    insn = 00100bbb01101111FBBBuuuuuu001001.  */
-static unsigned
-insert_uimm6_20 (unsigned insn ATTRIBUTE_UNUSED,
-		 int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm6_20 (unsigned long long insn ATTRIBUTE_UNUSED,
+		 long long int value ATTRIBUTE_UNUSED,
 		 const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -63,8 +63,8 @@ insert_uimm6_20 (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM6_20
 #define EXTRACT_UIMM6_20
 /* mask = 00000000000000000000111111000000.  */
-static int
-extract_uimm6_20 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm6_20 (unsigned long long insn ATTRIBUTE_UNUSED,
 		  bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -79,9 +79,9 @@ extract_uimm6_20 (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM12_20
 /* mask = 00000000000000000000111111222222
    insn = 00110bbb10101000FBBBssssssSSSSSS.  */
-static unsigned
-insert_simm12_20 (unsigned insn ATTRIBUTE_UNUSED,
-		  int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm12_20 (unsigned long long insn ATTRIBUTE_UNUSED,
+		  long long int value ATTRIBUTE_UNUSED,
 		  const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -95,8 +95,8 @@ insert_simm12_20 (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM12_20
 #define EXTRACT_SIMM12_20
 /* mask = 00000000000000000000111111222222.  */
-static int
-extract_simm12_20 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm12_20 (unsigned long long insn ATTRIBUTE_UNUSED,
 		   bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -117,8 +117,8 @@ extract_simm12_20 (unsigned insn ATTRIBUTE_UNUSED,
 /* mask = 0000011100000000
    insn = 01110ssshhh001HH.  */
 static ATTRIBUTE_UNUSED unsigned
-insert_simm3_5_s (unsigned insn ATTRIBUTE_UNUSED,
-		  int value ATTRIBUTE_UNUSED,
+insert_simm3_5_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		  long long int value ATTRIBUTE_UNUSED,
 		  const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -132,7 +132,7 @@ insert_simm3_5_s (unsigned insn ATTRIBUTE_UNUSED,
 #define EXTRACT_SIMM3_5_S
 /* mask = 0000011100000000.  */
 static ATTRIBUTE_UNUSED int
-extract_simm3_5_s (unsigned insn ATTRIBUTE_UNUSED,
+extract_simm3_5_s (unsigned long long insn ATTRIBUTE_UNUSED,
 		   bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -152,8 +152,8 @@ extract_simm3_5_s (unsigned insn ATTRIBUTE_UNUSED,
 /* mask = 0000000000000000
    insn = 01110sss11000111.  */
 static ATTRIBUTE_UNUSED unsigned
-insert_limm_s (unsigned insn ATTRIBUTE_UNUSED,
-	       int value ATTRIBUTE_UNUSED,
+insert_limm_s (unsigned long long insn ATTRIBUTE_UNUSED,
+	       long long int value ATTRIBUTE_UNUSED,
 	       const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -165,7 +165,7 @@ insert_limm_s (unsigned insn ATTRIBUTE_UNUSED,
 #define EXTRACT_LIMM_S
 /* mask = 0000000000000000.  */
 static ATTRIBUTE_UNUSED int
-extract_limm_s (unsigned insn ATTRIBUTE_UNUSED, bfd_boolean * invalid ATTRIBUTE_UNUSED)
+extract_limm_s (unsigned long long insn ATTRIBUTE_UNUSED, bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
 
@@ -177,9 +177,9 @@ extract_limm_s (unsigned insn ATTRIBUTE_UNUSED, bfd_boolean * invalid ATTRIBUTE_
 #define INSERT_UIMM7_A32_11_S
 /* mask = 0000000000011111
    insn = 11000bbb100uuuuu.  */
-static unsigned
-insert_uimm7_a32_11_s (unsigned insn ATTRIBUTE_UNUSED,
-		       int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm7_a32_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		       long long int value ATTRIBUTE_UNUSED,
 		       const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x03)
@@ -194,8 +194,8 @@ insert_uimm7_a32_11_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM7_A32_11_S
 #define EXTRACT_UIMM7_A32_11_S
 /* mask = 0000000000011111.  */
-static int
-extract_uimm7_a32_11_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm7_a32_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
 			bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -210,9 +210,9 @@ extract_uimm7_a32_11_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM7_9_S
 /* mask = 0000000001111111
    insn = 11100bbb0uuuuuuu.  */
-static unsigned
-insert_uimm7_9_s (unsigned insn ATTRIBUTE_UNUSED,
-		  int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm7_9_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		  long long int value ATTRIBUTE_UNUSED,
 		  const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -225,8 +225,8 @@ insert_uimm7_9_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM7_9_S
 #define EXTRACT_UIMM7_9_S
 /* mask = 0000000001111111.  */
-static int
-extract_uimm7_9_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm7_9_s (unsigned long long insn ATTRIBUTE_UNUSED,
 		   bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -241,9 +241,9 @@ extract_uimm7_9_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM3_13_S
 /* mask = 0000000000000111
    insn = 01101bbbccc00uuu.  */
-static unsigned
-insert_uimm3_13_s (unsigned insn ATTRIBUTE_UNUSED,
-		   int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm3_13_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		   long long int value ATTRIBUTE_UNUSED,
 		   const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -256,8 +256,8 @@ insert_uimm3_13_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM3_13_S
 #define EXTRACT_UIMM3_13_S
 /* mask = 0000000000000111.  */
-static int
-extract_uimm3_13_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm3_13_s (unsigned long long insn ATTRIBUTE_UNUSED,
 		    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -272,9 +272,9 @@ extract_uimm3_13_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM11_A32_7_S
 /* mask = 0000000111111111
    insn = 1100111sssssssss.  */
-static unsigned
-insert_simm11_a32_7_s (unsigned insn ATTRIBUTE_UNUSED,
-		       int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm11_a32_7_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		       long long int value ATTRIBUTE_UNUSED,
 		       const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x03)
@@ -289,8 +289,8 @@ insert_simm11_a32_7_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM11_A32_7_S
 #define EXTRACT_SIMM11_A32_7_S
 /* mask = 0000000111111111.  */
-static int
-extract_simm11_a32_7_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm11_a32_7_s (unsigned long long insn ATTRIBUTE_UNUSED,
 			bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -309,9 +309,9 @@ extract_simm11_a32_7_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM6_13_S
 /* mask = 0000000002220111
    insn = 01001bbb0UUU1uuu.  */
-static unsigned
-insert_uimm6_13_s (unsigned insn ATTRIBUTE_UNUSED,
-		   int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm6_13_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		   long long int value ATTRIBUTE_UNUSED,
 		   const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -325,8 +325,8 @@ insert_uimm6_13_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM6_13_S
 #define EXTRACT_UIMM6_13_S
 /* mask = 0000000002220111.  */
-static int
-extract_uimm6_13_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm6_13_s (unsigned long long insn ATTRIBUTE_UNUSED,
 		    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -342,9 +342,9 @@ extract_uimm6_13_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM5_11_S
 /* mask = 0000000000011111
    insn = 10111bbb000uuuuu.  */
-static unsigned
-insert_uimm5_11_s (unsigned insn ATTRIBUTE_UNUSED,
-		   int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm5_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		   long long int value ATTRIBUTE_UNUSED,
 		   const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -357,8 +357,8 @@ insert_uimm5_11_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM5_11_S
 #define EXTRACT_UIMM5_11_S
 /* mask = 0000000000011111.  */
-static int
-extract_uimm5_11_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm5_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
 		    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -373,9 +373,9 @@ extract_uimm5_11_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM9_A16_8
 /* mask = 00000000111111102000000000000000
    insn = 00001bbbsssssss1SBBBCCCCCCN01110.  */
-static unsigned
-insert_simm9_a16_8 (unsigned insn ATTRIBUTE_UNUSED,
-		    int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm9_a16_8 (unsigned long long insn ATTRIBUTE_UNUSED,
+		    long long int value ATTRIBUTE_UNUSED,
 		    const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x01)
@@ -391,8 +391,8 @@ insert_simm9_a16_8 (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM9_A16_8
 #define EXTRACT_SIMM9_A16_8
 /* mask = 00000000111111102000000000000000.  */
-static int
-extract_simm9_a16_8 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm9_a16_8 (unsigned long long insn ATTRIBUTE_UNUSED,
 		     bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -412,9 +412,9 @@ extract_simm9_a16_8 (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM6_8
 /* mask = 00000000000000000000111111000000
    insn = 00001bbbsssssss1SBBBuuuuuuN11110.  */
-static unsigned
-insert_uimm6_8 (unsigned insn ATTRIBUTE_UNUSED,
-		int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm6_8 (unsigned long long insn ATTRIBUTE_UNUSED,
+		long long int value ATTRIBUTE_UNUSED,
 		const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -427,8 +427,8 @@ insert_uimm6_8 (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM6_8
 #define EXTRACT_UIMM6_8
 /* mask = 00000000000000000000111111000000.  */
-static int
-extract_uimm6_8 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm6_8 (unsigned long long insn ATTRIBUTE_UNUSED,
 		 bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -443,9 +443,9 @@ extract_uimm6_8 (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM21_A16_5
 /* mask = 00000111111111102222222222000000
    insn = 00000ssssssssss0SSSSSSSSSSNQQQQQ.  */
-static unsigned
-insert_simm21_a16_5 (unsigned insn ATTRIBUTE_UNUSED,
-		     int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm21_a16_5 (unsigned long long insn ATTRIBUTE_UNUSED,
+		     long long int value ATTRIBUTE_UNUSED,
 		     const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x01)
@@ -461,8 +461,8 @@ insert_simm21_a16_5 (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM21_A16_5
 #define EXTRACT_SIMM21_A16_5
 /* mask = 00000111111111102222222222000000.  */
-static int
-extract_simm21_a16_5 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm21_a16_5 (unsigned long long insn ATTRIBUTE_UNUSED,
 		      bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -482,9 +482,9 @@ extract_simm21_a16_5 (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM25_A16_5
 /* mask = 00000111111111102222222222003333
    insn = 00000ssssssssss1SSSSSSSSSSNRtttt.  */
-static unsigned
-insert_simm25_a16_5 (unsigned insn ATTRIBUTE_UNUSED,
-		     int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm25_a16_5 (unsigned long long insn ATTRIBUTE_UNUSED,
+		     long long int value ATTRIBUTE_UNUSED,
 		     const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x01)
@@ -501,8 +501,8 @@ insert_simm25_a16_5 (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM25_A16_5
 #define EXTRACT_SIMM25_A16_5
 /* mask = 00000111111111102222222222003333.  */
-static int
-extract_simm25_a16_5 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm25_a16_5 (unsigned long long insn ATTRIBUTE_UNUSED,
 		      bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -523,9 +523,9 @@ extract_simm25_a16_5 (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM10_A16_7_S
 /* mask = 0000000111111111
    insn = 1111001sssssssss.  */
-static unsigned
-insert_simm10_a16_7_s (unsigned insn ATTRIBUTE_UNUSED,
-		       int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm10_a16_7_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		       long long int value ATTRIBUTE_UNUSED,
 		       const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x01)
@@ -540,8 +540,8 @@ insert_simm10_a16_7_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM10_A16_7_S
 #define EXTRACT_SIMM10_A16_7_S
 /* mask = 0000000111111111.  */
-static int
-extract_simm10_a16_7_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm10_a16_7_s (unsigned long long insn ATTRIBUTE_UNUSED,
 			bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -560,9 +560,9 @@ extract_simm10_a16_7_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM7_A16_10_S
 /* mask = 0000000000111111
    insn = 1111011000ssssss.  */
-static unsigned
-insert_simm7_a16_10_s (unsigned insn ATTRIBUTE_UNUSED,
-		       int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm7_a16_10_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		       long long int value ATTRIBUTE_UNUSED,
 		       const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x01)
@@ -577,8 +577,8 @@ insert_simm7_a16_10_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM7_A16_10_S
 #define EXTRACT_SIMM7_A16_10_S
 /* mask = 0000000000111111.  */
-static int
-extract_simm7_a16_10_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm7_a16_10_s (unsigned long long insn ATTRIBUTE_UNUSED,
 			bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -597,9 +597,9 @@ extract_simm7_a16_10_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM21_A32_5
 /* mask = 00000111111111002222222222000000
    insn = 00001sssssssss00SSSSSSSSSSNQQQQQ.  */
-static unsigned
-insert_simm21_a32_5 (unsigned insn ATTRIBUTE_UNUSED,
-		     int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm21_a32_5 (unsigned long long insn ATTRIBUTE_UNUSED,
+		     long long int value ATTRIBUTE_UNUSED,
 		     const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x03)
@@ -615,8 +615,8 @@ insert_simm21_a32_5 (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM21_A32_5
 #define EXTRACT_SIMM21_A32_5
 /* mask = 00000111111111002222222222000000.  */
-static int
-extract_simm21_a32_5 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm21_a32_5 (unsigned long long insn ATTRIBUTE_UNUSED,
 		      bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -636,9 +636,9 @@ extract_simm21_a32_5 (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM25_A32_5
 /* mask = 00000111111111002222222222003333
    insn = 00001sssssssss10SSSSSSSSSSNRtttt.  */
-static unsigned
-insert_simm25_a32_5 (unsigned insn ATTRIBUTE_UNUSED,
-		     int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm25_a32_5 (unsigned long long insn ATTRIBUTE_UNUSED,
+		     long long int value ATTRIBUTE_UNUSED,
 		     const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x03)
@@ -655,8 +655,8 @@ insert_simm25_a32_5 (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM25_A32_5
 #define EXTRACT_SIMM25_A32_5
 /* mask = 00000111111111002222222222003333.  */
-static int
-extract_simm25_a32_5 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm25_a32_5 (unsigned long long insn ATTRIBUTE_UNUSED,
 		      bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -677,9 +677,9 @@ extract_simm25_a32_5 (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM13_A32_5_S
 /* mask = 0000011111111111
    insn = 11111sssssssssss.  */
-static unsigned
-insert_simm13_a32_5_s (unsigned insn ATTRIBUTE_UNUSED,
-		       int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm13_a32_5_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		       long long int value ATTRIBUTE_UNUSED,
 		       const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x03)
@@ -694,8 +694,8 @@ insert_simm13_a32_5_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM13_A32_5_S
 #define EXTRACT_SIMM13_A32_5_S
 /* mask = 0000011111111111.  */
-static int
-extract_simm13_a32_5_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm13_a32_5_s (unsigned long long insn ATTRIBUTE_UNUSED,
 			bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -714,9 +714,9 @@ extract_simm13_a32_5_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM8_A16_9_S
 /* mask = 0000000001111111
    insn = 11101bbb1sssssss.  */
-static unsigned
-insert_simm8_a16_9_s (unsigned insn ATTRIBUTE_UNUSED,
-		      int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm8_a16_9_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		      long long int value ATTRIBUTE_UNUSED,
 		      const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x01)
@@ -731,8 +731,8 @@ insert_simm8_a16_9_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM8_A16_9_S
 #define EXTRACT_SIMM8_A16_9_S
 /* mask = 0000000001111111.  */
-static int
-extract_simm8_a16_9_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm8_a16_9_s (unsigned long long insn ATTRIBUTE_UNUSED,
 		       bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -751,9 +751,9 @@ extract_simm8_a16_9_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM3_23
 /* mask = 00000000000000000000000111000000
    insn = 00100011011011110001RRRuuu111111.  */
-static unsigned
-insert_uimm3_23 (unsigned insn ATTRIBUTE_UNUSED,
-		 int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm3_23 (unsigned long long insn ATTRIBUTE_UNUSED,
+		 long long int value ATTRIBUTE_UNUSED,
 		 const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -766,8 +766,8 @@ insert_uimm3_23 (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM3_23
 #define EXTRACT_UIMM3_23
 /* mask = 00000000000000000000000111000000.  */
-static int
-extract_uimm3_23 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm3_23 (unsigned long long insn ATTRIBUTE_UNUSED,
 		  bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -782,9 +782,9 @@ extract_uimm3_23 (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM10_6_S
 /* mask = 0000001111111111
    insn = 010111uuuuuuuuuu.  */
-static unsigned
-insert_uimm10_6_s (unsigned insn ATTRIBUTE_UNUSED,
-		   int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm10_6_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		   long long int value ATTRIBUTE_UNUSED,
 		   const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -797,8 +797,8 @@ insert_uimm10_6_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM10_6_S
 #define EXTRACT_UIMM10_6_S
 /* mask = 0000001111111111.  */
-static int
-extract_uimm10_6_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm10_6_s (unsigned long long insn ATTRIBUTE_UNUSED,
 		    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -813,9 +813,9 @@ extract_uimm10_6_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM6_11_S
 /* mask = 0000002200011110
    insn = 110000UU111uuuu0.  */
-static unsigned
-insert_uimm6_11_s (unsigned insn ATTRIBUTE_UNUSED,
-		   int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm6_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		   long long int value ATTRIBUTE_UNUSED,
 		   const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -829,8 +829,8 @@ insert_uimm6_11_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM6_11_S
 #define EXTRACT_UIMM6_11_S
 /* mask = 0000002200011110.  */
-static int
-extract_uimm6_11_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm6_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
 		    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -846,9 +846,9 @@ extract_uimm6_11_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM9_8
 /* mask = 00000000111111112000000000000000
    insn = 00010bbbssssssssSBBBDaaZZXAAAAAA.  */
-static unsigned
-insert_simm9_8 (unsigned insn ATTRIBUTE_UNUSED,
-		int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm9_8 (unsigned long long insn ATTRIBUTE_UNUSED,
+		long long int value ATTRIBUTE_UNUSED,
 		const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -862,8 +862,8 @@ insert_simm9_8 (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM9_8
 #define EXTRACT_SIMM9_8
 /* mask = 00000000111111112000000000000000.  */
-static int
-extract_simm9_8 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm9_8 (unsigned long long insn ATTRIBUTE_UNUSED,
 		 bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -883,9 +883,9 @@ extract_simm9_8 (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM10_A32_8_S
 /* mask = 0000000011111111
    insn = 11010bbbuuuuuuuu.  */
-static unsigned
-insert_uimm10_a32_8_s (unsigned insn ATTRIBUTE_UNUSED,
-		       int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm10_a32_8_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		       long long int value ATTRIBUTE_UNUSED,
 		       const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x03)
@@ -900,8 +900,8 @@ insert_uimm10_a32_8_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM10_A32_8_S
 #define EXTRACT_UIMM10_A32_8_S
 /* mask = 0000000011111111.  */
-static int
-extract_uimm10_a32_8_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm10_a32_8_s (unsigned long long insn ATTRIBUTE_UNUSED,
 			bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -916,9 +916,9 @@ extract_uimm10_a32_8_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM9_7_S
 /* mask = 0000000111111111
    insn = 1100101sssssssss.  */
-static unsigned
-insert_simm9_7_s (unsigned insn ATTRIBUTE_UNUSED,
-		  int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm9_7_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		  long long int value ATTRIBUTE_UNUSED,
 		  const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -931,8 +931,8 @@ insert_simm9_7_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM9_7_S
 #define EXTRACT_SIMM9_7_S
 /* mask = 0000000111111111.  */
-static int
-extract_simm9_7_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm9_7_s (unsigned long long insn ATTRIBUTE_UNUSED,
 		   bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -951,9 +951,9 @@ extract_simm9_7_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM6_A16_11_S
 /* mask = 0000000000011111
    insn = 10010bbbcccuuuuu.  */
-static unsigned
-insert_uimm6_a16_11_s (unsigned insn ATTRIBUTE_UNUSED,
-		       int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm6_a16_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		       long long int value ATTRIBUTE_UNUSED,
 		       const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x01)
@@ -968,8 +968,8 @@ insert_uimm6_a16_11_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM6_A16_11_S
 #define EXTRACT_UIMM6_A16_11_S
 /* mask = 0000000000011111.  */
-static int
-extract_uimm6_a16_11_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm6_a16_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
 			bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -984,9 +984,9 @@ extract_uimm6_a16_11_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM5_A32_11_S
 /* mask = 0000020000011000
    insn = 01000U00hhhuu1HH.  */
-static unsigned
-insert_uimm5_a32_11_s (unsigned insn ATTRIBUTE_UNUSED,
-		       int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm5_a32_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		       long long int value ATTRIBUTE_UNUSED,
 		       const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x03)
@@ -1002,8 +1002,8 @@ insert_uimm5_a32_11_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM5_A32_11_S
 #define EXTRACT_UIMM5_A32_11_S
 /* mask = 0000020000011000.  */
-static int
-extract_uimm5_a32_11_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm5_a32_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
 			bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -1019,9 +1019,9 @@ extract_uimm5_a32_11_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM11_A32_13_S
 /* mask = 0000022222200111
    insn = 01010SSSSSS00sss.  */
-static unsigned
-insert_simm11_a32_13_s (unsigned insn ATTRIBUTE_UNUSED,
-			int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm11_a32_13_s (unsigned long long insn ATTRIBUTE_UNUSED,
+			long long int value ATTRIBUTE_UNUSED,
 			const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x03)
@@ -1037,8 +1037,8 @@ insert_simm11_a32_13_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM11_A32_13_S
 #define EXTRACT_SIMM11_A32_13_S
 /* mask = 0000022222200111.  */
-static int
-extract_simm11_a32_13_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm11_a32_13_s (unsigned long long insn ATTRIBUTE_UNUSED,
 			 bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -1058,9 +1058,9 @@ extract_simm11_a32_13_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM7_13_S
 /* mask = 0000000022220111
    insn = 01010bbbUUUU1uuu.  */
-static unsigned
-insert_uimm7_13_s (unsigned insn ATTRIBUTE_UNUSED,
-		   int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm7_13_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		   long long int value ATTRIBUTE_UNUSED,
 		   const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -1074,8 +1074,8 @@ insert_uimm7_13_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM7_13_S
 #define EXTRACT_UIMM7_13_S
 /* mask = 0000000022220111.  */
-static int
-extract_uimm7_13_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm7_13_s (unsigned long long insn ATTRIBUTE_UNUSED,
 		    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -1091,9 +1091,9 @@ extract_uimm7_13_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM6_A16_21
 /* mask = 00000000000000000000011111000000
    insn = 00101bbb01001100RBBBRuuuuuAAAAAA.  */
-static unsigned
-insert_uimm6_a16_21 (unsigned insn ATTRIBUTE_UNUSED,
-		     int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm6_a16_21 (unsigned long long insn ATTRIBUTE_UNUSED,
+		     long long int value ATTRIBUTE_UNUSED,
 		     const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x01)
@@ -1108,8 +1108,8 @@ insert_uimm6_a16_21 (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM6_A16_21
 #define EXTRACT_UIMM6_A16_21
 /* mask = 00000000000000000000011111000000.  */
-static int
-extract_uimm6_a16_21 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm6_a16_21 (unsigned long long insn ATTRIBUTE_UNUSED,
 		      bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -1124,9 +1124,9 @@ extract_uimm6_a16_21 (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM7_11_S
 /* mask = 0000022200011110
    insn = 11000UUU110uuuu0.  */
-static unsigned
-insert_uimm7_11_s (unsigned insn ATTRIBUTE_UNUSED,
-		   int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm7_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		   long long int value ATTRIBUTE_UNUSED,
 		   const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -1140,8 +1140,8 @@ insert_uimm7_11_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM7_11_S
 #define EXTRACT_UIMM7_11_S
 /* mask = 0000022200011110.  */
-static int
-extract_uimm7_11_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm7_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
 		    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -1157,9 +1157,9 @@ extract_uimm7_11_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM7_A16_20
 /* mask = 00000000000000000000111111000000
    insn = 00100RRR111010000RRRuuuuuu1QQQQQ.  */
-static unsigned
-insert_uimm7_a16_20 (unsigned insn ATTRIBUTE_UNUSED,
-		     int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm7_a16_20 (unsigned long long insn ATTRIBUTE_UNUSED,
+		     long long int value ATTRIBUTE_UNUSED,
 		     const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x01)
@@ -1174,8 +1174,8 @@ insert_uimm7_a16_20 (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM7_A16_20
 #define EXTRACT_UIMM7_A16_20
 /* mask = 00000000000000000000111111000000.  */
-static int
-extract_uimm7_a16_20 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm7_a16_20 (unsigned long long insn ATTRIBUTE_UNUSED,
 		      bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -1190,9 +1190,9 @@ extract_uimm7_a16_20 (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_SIMM13_A16_20
 /* mask = 00000000000000000000111111222222
    insn = 00100RRR101010000RRRssssssSSSSSS.  */
-static unsigned
-insert_simm13_a16_20 (unsigned insn ATTRIBUTE_UNUSED,
-		      int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_simm13_a16_20 (unsigned long long insn ATTRIBUTE_UNUSED,
+		      long long int value ATTRIBUTE_UNUSED,
 		      const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x01)
@@ -1208,8 +1208,8 @@ insert_simm13_a16_20 (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_SIMM13_A16_20
 #define EXTRACT_SIMM13_A16_20
 /* mask = 00000000000000000000111111222222.  */
-static int
-extract_simm13_a16_20 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm13_a16_20 (unsigned long long insn ATTRIBUTE_UNUSED,
 		       bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -1229,9 +1229,9 @@ extract_simm13_a16_20 (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM8_8_S
 /* mask = 0000000011111111
    insn = 11011bbbuuuuuuuu.  */
-static unsigned
-insert_uimm8_8_s (unsigned insn ATTRIBUTE_UNUSED,
-		  int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm8_8_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		  long long int value ATTRIBUTE_UNUSED,
 		  const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -1244,8 +1244,8 @@ insert_uimm8_8_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM8_8_S
 #define EXTRACT_UIMM8_8_S
 /* mask = 0000000011111111.  */
-static int
-extract_uimm8_8_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm8_8_s (unsigned long long insn ATTRIBUTE_UNUSED,
 		   bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -1260,9 +1260,9 @@ extract_uimm8_8_s (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_UIMM6_5_S
 /* mask = 0000011111100000
    insn = 01111uuuuuu11111.  */
-static unsigned
-insert_uimm6_5_s (unsigned insn ATTRIBUTE_UNUSED,
-		  int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_uimm6_5_s (unsigned long long insn ATTRIBUTE_UNUSED,
+		  long long int value ATTRIBUTE_UNUSED,
 		  const char **errmsg ATTRIBUTE_UNUSED)
 {
 
@@ -1275,8 +1275,8 @@ insert_uimm6_5_s (unsigned insn ATTRIBUTE_UNUSED,
 #ifndef EXTRACT_UIMM6_5_S
 #define EXTRACT_UIMM6_5_S
 /* mask = 0000011111100000.  */
-static int
-extract_uimm6_5_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_uimm6_5_s (unsigned long long insn ATTRIBUTE_UNUSED,
 		   bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -1292,8 +1292,8 @@ extract_uimm6_5_s (unsigned insn ATTRIBUTE_UNUSED,
 /* mask = 00000000000000000000000000000000
    insn = 00110bbb11100001100001100001QQQQ.  */
 static ATTRIBUTE_UNUSED unsigned
-insert_uimm6_axx_ (unsigned insn ATTRIBUTE_UNUSED,
-		   int value ATTRIBUTE_UNUSED,
+insert_uimm6_axx_ (unsigned long long insn ATTRIBUTE_UNUSED,
+		   long long int value ATTRIBUTE_UNUSED,
 		   const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x3f)
@@ -1307,7 +1307,7 @@ insert_uimm6_axx_ (unsigned insn ATTRIBUTE_UNUSED,
 #define EXTRACT_UIMM6_AXX_
 /* mask = 00000000000000000000000000000000.  */
 static ATTRIBUTE_UNUSED int
-extract_uimm6_axx_ (unsigned insn ATTRIBUTE_UNUSED,
+extract_uimm6_axx_ (unsigned long long insn ATTRIBUTE_UNUSED,
 		    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
diff --git a/opcodes/arc-nps400-tbl.h b/opcodes/arc-nps400-tbl.h
index 7ed6bcd..e9a5d95 100644
--- a/opcodes/arc-nps400-tbl.h
+++ b/opcodes/arc-nps400-tbl.h
@@ -34,20 +34,47 @@
 /* encode1<.f> */
 { "encode1", 0x48048000, 0xf80f8000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B, NPS_R_SRC2_3B, NPS_BITOP_SRC_POS, NPS_BITOP_SIZE }, { C_NPS_F }},
 
-/* mrgb - 48 bit instruction, see arc_long_opcodes in arc-opc.c.  */
-/* mrgb.cl - 48 bit instruction, see arc_long_opcodes in arc-opc.c.  */
-/* mov2b - 48 bit instruction, see arc_long_opcodes in arc-opc.c.  */
-/* mov2b.cl - 48 bit instruction, see arc_long_opcodes in arc-opc.c.  */
-/* ext4 - 48 bit instruction, see arc_long_opcodes in arc-opc.c.  */
-/* ext4.cl - 48 bit instruction, see arc_long_opcodes in arc-opc.c.  */
-/* ins4 - 48 bit instruction, see arc_long_opcodes in arc-opc.c.  */
-/* ins4.cl - 48 bit instruction, see arc_long_opcodes in arc-opc.c.  */
-/* mov3b - 64 bit instruction, see arc_long_opcodes in arc-opc.c.  */
-/* mov4b - 64 bit instruction, see arc_long_opcodes in arc-opc.c.  */
-/* mov3bcl - 64 bit instruction, see arc_long_opcodes in arc-opc.c.  */
-/* mov4bcl - 64 bit instruction, see arc_long_opcodes in arc-opc.c.  */
-/* mov3b.cl - 64 bit instruction, see arc_long_opcodes in arc-opc.c.  */
-/* mov4b.cl - 64 bit instruction, see arc_long_opcodes in arc-opc.c.  */
+/* mrgb - 48 bit instruction.  */
+{ "mrgb", 0x580300000000, 0xf81f80000000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_48, NPS_R_SRC1_3B_48, NPS_R_SRC2_3B_48, NPS_BITOP_DST_POS1, NPS_BITOP_SRC_POS1, NPS_BITOP_SIZE1, NPS_BITOP_DST_POS2, NPS_BITOP_SRC_POS2, NPS_BITOP_SIZE2 }, { 0 }},
+
+/* mrgb.cl - 48 bit instruction.  */
+{ "mrgb", 0x580380000000, 0xf81f80000000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_48, NPS_R_SRC1_3B_48, NPS_R_SRC2_3B_48, NPS_BITOP_DST_POS1, NPS_BITOP_SRC_POS1, NPS_BITOP_SIZE1, NPS_BITOP_DST_POS2, NPS_BITOP_SRC_POS2, NPS_BITOP_SIZE2 }, { C_NPS_CL }},
+
+/* mov2b - 48 bit instruction.  */
+{ "mov2b", 0x580000000000, 0xf81f80000000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_48, NPS_R_SRC1_3B_48, NPS_R_SRC2_3B_48, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2 }, { 0 }},
+
+/* mov2b.cl - 48 bit instruction.  */
+{ "mov2b", 0x580080000000, 0xf81f80000000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_48, NPS_R_SRC2_3B_48, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2 }, { C_NPS_CL }},
+
+/* ext4 - 48 bit instruction.  */
+{ "ext4b", 0x580100000000, 0xf81f80000000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_48, NPS_R_SRC1_3B_48, NPS_R_SRC2_3B_48, NPS_BITOP_INS_EXT, NPS_BITOP_SRC_POS1, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS1, NPS_BITOP_DST_POS2 }, { 0 }},
+
+/* ext4.cl - 48 bit instruction.  */
+{ "ext4b", 0x580180000000, 0xf81f80000000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_48, NPS_R_SRC2_3B_48, NPS_BITOP_INS_EXT, NPS_BITOP_SRC_POS1, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS1, NPS_BITOP_DST_POS2 }, { C_NPS_CL }},
+
+/* ins4 - 48 bit instruction.  */
+{ "ins4b", 0x580200000000, 0xf81f80000000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_48, NPS_R_SRC1_3B_48, NPS_R_SRC2_3B_48, NPS_BITOP_SRC_POS1, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_INS_EXT }, { 0 }},
+
+/* ins4.cl - 48 bit instruction.  */
+{ "ins4b", 0x580280000000, 0xf81f80000000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_48, NPS_R_SRC2_3B_48, NPS_BITOP_SRC_POS1, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_INS_EXT }, { C_NPS_CL }},
+
+/* mov3b - 64 bit instruction.  */
+{ "mov3b", 0x5810000080000000, 0xf81f801f80000000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_64, NPS_R_SRC1_3B_64, NPS_R_SRC2_3B_64, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS3_POS4, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3}, { 0 }},
+
+/* mov4b - 64 bit instruction.  */
+{ "mov4b", 0x5810000000000000, 0xf81f000000000000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_64, NPS_R_SRC1_3B_64, NPS_R_SRC2_3B_64, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS3, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3, NPS_BITOP_DST_POS4, NPS_BITOP_MOD4, NPS_BITOP_SRC_POS4}, { 0 }},
+
+/* mov3bcl - 64 bit instruction.  */
+{ "mov3bcl", 0x5811000080000000, 0xf81f801f80000000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_64, NPS_R_SRC2_3B_64, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS3_POS4, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3}, { 0 }},
+
+/* mov4bcl - 64 bit instruction.  */
+{ "mov4bcl", 0x5811000000000000, 0xf81f000000000000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_64, NPS_R_SRC2_3B_64, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS3, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3, NPS_BITOP_DST_POS4, NPS_BITOP_MOD4, NPS_BITOP_SRC_POS4 }, { 0 }},
+
+/* mov3b.cl - 64 bit instruction.  */
+{ "mov3b", 0x5811000080000000, 0xf81f801f80000000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_64, NPS_R_SRC2_3B_64, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS3_POS4, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3 }, { C_NPS_CL }},
+
+/* mov4b.cl - 64 bit instruction.  */
+{ "mov4b", 0x5811000000000000, 0xf81f000000000000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_64, NPS_R_SRC2_3B_64, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS3, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3, NPS_BITOP_DST_POS4, NPS_BITOP_MOD4, NPS_BITOP_SRC_POS4}, { C_NPS_CL }},
 
 /* rflt a,b,c   00111bbb00101110FBBBCCCCCCAAAAAA */
 { "rflt", 0x382e0000, 0xf8ff8000, ARC_OPCODE_ARC700, BITOP, NPS400, { RA, RB, RC }, { 0 }},
diff --git a/opcodes/arc-opc.c b/opcodes/arc-opc.c
index 9eb58d3..ee14fed 100644
--- a/opcodes/arc-opc.c
+++ b/opcodes/arc-opc.c
@@ -31,16 +31,16 @@
    this reduces the chances that regressions might creep in.  */
 
 /* Insert RB register into a 32-bit opcode.  */
-static unsigned
-insert_rb (unsigned insn,
-	   int value,
+static unsigned long long
+insert_rb (unsigned long long insn,
+	   long long int value,
 	   const char **errmsg ATTRIBUTE_UNUSED)
 {
   return insn | ((value & 0x07) << 24) | (((value >> 3) & 0x07) << 12);
 }
 
-static int
-extract_rb (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_rb (unsigned long long insn ATTRIBUTE_UNUSED,
 	    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = (((insn >> 12) & 0x07) << 3) | ((insn >> 24) & 0x07);
@@ -52,9 +52,9 @@ extract_rb (unsigned insn ATTRIBUTE_UNUSED,
   return value;
 }
 
-static unsigned
-insert_rad (unsigned insn,
-	    int value,
+static unsigned long long
+insert_rad (unsigned long long insn,
+	    long long int value,
 	    const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x01)
@@ -63,9 +63,9 @@ insert_rad (unsigned insn,
   return insn | (value & 0x3F);
 }
 
-static unsigned
-insert_rcd (unsigned insn,
-	    int value,
+static unsigned long long
+insert_rcd (unsigned long long insn,
+	    long long int value,
 	    const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value & 0x01)
@@ -76,9 +76,9 @@ insert_rcd (unsigned insn,
 
 /* Dummy insert ZERO operand function.  */
 
-static unsigned
-insert_za (unsigned insn,
-	   int value,
+static unsigned long long
+insert_za (unsigned long long insn,
+	   long long int value,
 	   const char **errmsg)
 {
   if (value)
@@ -89,9 +89,9 @@ insert_za (unsigned insn,
 /* Insert Y-bit in bbit/br instructions.  This function is called only
    when solving fixups.  */
 
-static unsigned
-insert_Ybit (unsigned insn,
-	     int value,
+static unsigned long long
+insert_Ybit (unsigned long long insn,
+	     long long int value,
 	     const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value > 0)
@@ -103,9 +103,9 @@ insert_Ybit (unsigned insn,
 /* Insert Y-bit in bbit/br instructions.  This function is called only
    when solving fixups.  */
 
-static unsigned
-insert_NYbit (unsigned insn,
-	      int value,
+static unsigned long long
+insert_NYbit (unsigned long long insn,
+	      long long int value,
 	      const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value < 0)
@@ -116,16 +116,16 @@ insert_NYbit (unsigned insn,
 
 /* Insert H register into a 16-bit opcode.  */
 
-static unsigned
-insert_rhv1 (unsigned insn,
-	     int value,
+static unsigned long long
+insert_rhv1 (unsigned long long insn,
+	     long long int value,
 	     const char **errmsg ATTRIBUTE_UNUSED)
 {
   return insn |= ((value & 0x07) << 5) | ((value >> 3) & 0x07);
 }
 
-static int
-extract_rhv1 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_rhv1 (unsigned long long insn ATTRIBUTE_UNUSED,
 	      bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = ((insn & 0x7) << 3) | ((insn >> 5) & 0x7);
@@ -135,9 +135,9 @@ extract_rhv1 (unsigned insn ATTRIBUTE_UNUSED,
 
 /* Insert H register into a 16-bit opcode.  */
 
-static unsigned
-insert_rhv2 (unsigned insn,
-	     int value,
+static unsigned long long
+insert_rhv2 (unsigned long long insn,
+	     long long int value,
 	     const char **errmsg)
 {
   if (value == 0x1E)
@@ -146,8 +146,8 @@ insert_rhv2 (unsigned insn,
   return insn |= ((value & 0x07) << 5) | ((value >> 3) & 0x03);
 }
 
-static int
-extract_rhv2 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_rhv2 (unsigned long long insn ATTRIBUTE_UNUSED,
 	      bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = ((insn >> 5) & 0x07) | ((insn & 0x03) << 3);
@@ -155,9 +155,9 @@ extract_rhv2 (unsigned insn ATTRIBUTE_UNUSED,
   return value;
 }
 
-static unsigned
-insert_r0 (unsigned insn,
-	   int value,
+static unsigned long long
+insert_r0 (unsigned long long insn,
+	   long long int value,
 	   const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value != 0)
@@ -165,17 +165,17 @@ insert_r0 (unsigned insn,
   return insn;
 }
 
-static int
-extract_r0 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_r0 (unsigned long long insn ATTRIBUTE_UNUSED,
 	    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   return 0;
 }
 
 
-static unsigned
-insert_r1 (unsigned insn,
-	   int value,
+static unsigned long long
+insert_r1 (unsigned long long insn,
+	   long long int value,
 	   const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value != 1)
@@ -183,16 +183,16 @@ insert_r1 (unsigned insn,
   return insn;
 }
 
-static int
-extract_r1 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_r1 (unsigned long long insn ATTRIBUTE_UNUSED,
 	    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   return 1;
 }
 
-static unsigned
-insert_r2 (unsigned insn,
-	   int value,
+static unsigned long long
+insert_r2 (unsigned long long insn,
+	   long long int value,
 	   const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value != 2)
@@ -200,16 +200,16 @@ insert_r2 (unsigned insn,
   return insn;
 }
 
-static int
-extract_r2 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_r2 (unsigned long long insn ATTRIBUTE_UNUSED,
 	    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   return 2;
 }
 
-static unsigned
-insert_r3 (unsigned insn,
-	   int value,
+static unsigned long long
+insert_r3 (unsigned long long insn,
+	   long long int value,
 	   const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value != 3)
@@ -217,16 +217,16 @@ insert_r3 (unsigned insn,
   return insn;
 }
 
-static int
-extract_r3 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_r3 (unsigned long long insn ATTRIBUTE_UNUSED,
 	    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   return 3;
 }
 
-static unsigned
-insert_sp (unsigned insn,
-	   int value,
+static unsigned long long
+insert_sp (unsigned long long insn,
+	   long long int value,
 	   const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value != 28)
@@ -234,16 +234,16 @@ insert_sp (unsigned insn,
   return insn;
 }
 
-static int
-extract_sp (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_sp (unsigned long long insn ATTRIBUTE_UNUSED,
 	    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   return 28;
 }
 
-static unsigned
-insert_gp (unsigned insn,
-	   int value,
+static unsigned long long
+insert_gp (unsigned long long insn,
+	   long long int value,
 	   const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value != 26)
@@ -251,16 +251,16 @@ insert_gp (unsigned insn,
   return insn;
 }
 
-static int
-extract_gp (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_gp (unsigned long long insn ATTRIBUTE_UNUSED,
 	    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   return 26;
 }
 
-static unsigned
-insert_pcl (unsigned insn,
-	    int value,
+static unsigned long long
+insert_pcl (unsigned long long insn,
+	    long long int value,
 	    const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value != 63)
@@ -268,16 +268,16 @@ insert_pcl (unsigned insn,
   return insn;
 }
 
-static int
-extract_pcl (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_pcl (unsigned long long insn ATTRIBUTE_UNUSED,
 	     bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   return 63;
 }
 
-static unsigned
-insert_blink (unsigned insn,
-	      int value,
+static unsigned long long
+insert_blink (unsigned long long insn,
+	      long long int value,
 	      const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value != 31)
@@ -285,16 +285,16 @@ insert_blink (unsigned insn,
   return insn;
 }
 
-static int
-extract_blink (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_blink (unsigned long long insn ATTRIBUTE_UNUSED,
 	       bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   return 31;
 }
 
-static unsigned
-insert_ilink1 (unsigned insn,
-	       int value,
+static unsigned long long
+insert_ilink1 (unsigned long long insn,
+	       long long int value,
 	       const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value != 29)
@@ -302,16 +302,16 @@ insert_ilink1 (unsigned insn,
   return insn;
 }
 
-static int
-extract_ilink1 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_ilink1 (unsigned long long insn ATTRIBUTE_UNUSED,
 		bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   return 29;
 }
 
-static unsigned
-insert_ilink2 (unsigned insn,
-	       int value,
+static unsigned long long
+insert_ilink2 (unsigned long long insn,
+	       long long int value,
 	       const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value != 30)
@@ -319,16 +319,16 @@ insert_ilink2 (unsigned insn,
   return insn;
 }
 
-static int
-extract_ilink2 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_ilink2 (unsigned long long insn ATTRIBUTE_UNUSED,
 		bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   return 30;
 }
 
-static unsigned
-insert_ras (unsigned insn,
-	    int value,
+static unsigned long long
+insert_ras (unsigned long long insn,
+	    long long int value,
 	    const char **errmsg ATTRIBUTE_UNUSED)
 {
   switch (value)
@@ -352,8 +352,8 @@ insert_ras (unsigned insn,
   return insn;
 }
 
-static int
-extract_ras (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_ras (unsigned long long insn ATTRIBUTE_UNUSED,
 	     bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = insn & 0x07;
@@ -363,9 +363,9 @@ extract_ras (unsigned insn ATTRIBUTE_UNUSED,
     return value;
 }
 
-static unsigned
-insert_rbs (unsigned insn,
-	    int value,
+static unsigned long long
+insert_rbs (unsigned long long insn,
+	    long long int value,
 	    const char **errmsg ATTRIBUTE_UNUSED)
 {
   switch (value)
@@ -389,8 +389,8 @@ insert_rbs (unsigned insn,
   return insn;
 }
 
-static int
-extract_rbs (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_rbs (unsigned long long insn ATTRIBUTE_UNUSED,
 	     bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = (insn >> 8) & 0x07;
@@ -400,9 +400,9 @@ extract_rbs (unsigned insn ATTRIBUTE_UNUSED,
     return value;
 }
 
-static unsigned
-insert_rcs (unsigned insn,
-	    int value,
+static unsigned long long
+insert_rcs (unsigned long long insn,
+	    long long int value,
 	    const char **errmsg ATTRIBUTE_UNUSED)
 {
   switch (value)
@@ -426,8 +426,8 @@ insert_rcs (unsigned insn,
   return insn;
 }
 
-static int
-extract_rcs (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_rcs (unsigned long long insn ATTRIBUTE_UNUSED,
 	     bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = (insn >> 5) & 0x07;
@@ -437,9 +437,9 @@ extract_rcs (unsigned insn ATTRIBUTE_UNUSED,
     return value;
 }
 
-static unsigned
-insert_simm3s (unsigned insn,
-	       int value,
+static unsigned long long
+insert_simm3s (unsigned long long insn,
+	       long long int value,
 	       const char **errmsg ATTRIBUTE_UNUSED)
 {
   int tmp = 0;
@@ -478,8 +478,8 @@ insert_simm3s (unsigned insn,
   return insn;
 }
 
-static int
-extract_simm3s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_simm3s (unsigned long long insn ATTRIBUTE_UNUSED,
 		bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = (insn >> 8) & 0x07;
@@ -489,9 +489,9 @@ extract_simm3s (unsigned insn ATTRIBUTE_UNUSED,
     return value;
 }
 
-static unsigned
-insert_rrange (unsigned insn,
-	       int value,
+static unsigned long long
+insert_rrange (unsigned long long insn,
+	       long long int value,
 	       const char **errmsg ATTRIBUTE_UNUSED)
 {
   int reg1 = (value >> 16) & 0xFFFF;
@@ -510,16 +510,16 @@ insert_rrange (unsigned insn,
   return insn;
 }
 
-static int
-extract_rrange (unsigned insn  ATTRIBUTE_UNUSED,
+static long long int
+extract_rrange (unsigned long long insn  ATTRIBUTE_UNUSED,
 		bfd_boolean * invalid  ATTRIBUTE_UNUSED)
 {
   return (insn >> 1) & 0x0F;
 }
 
-static unsigned
-insert_fpel (unsigned insn,
-	     int value,
+static unsigned long long
+insert_fpel (unsigned long long insn,
+	     long long int value,
 	     const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value != 27)
@@ -532,16 +532,16 @@ insert_fpel (unsigned insn,
   return insn;
 }
 
-static int
-extract_fpel (unsigned insn  ATTRIBUTE_UNUSED,
+static long long int
+extract_fpel (unsigned long long insn  ATTRIBUTE_UNUSED,
 	      bfd_boolean * invalid  ATTRIBUTE_UNUSED)
 {
   return (insn & 0x0100) ? 27 : -1;
 }
 
-static unsigned
-insert_blinkel (unsigned insn,
-		int value,
+static unsigned long long
+insert_blinkel (unsigned long long insn,
+		long long int value,
 		const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value != 31)
@@ -554,16 +554,16 @@ insert_blinkel (unsigned insn,
   return insn;
 }
 
-static int
-extract_blinkel (unsigned insn  ATTRIBUTE_UNUSED,
+static long long int
+extract_blinkel (unsigned long long insn  ATTRIBUTE_UNUSED,
 		 bfd_boolean * invalid  ATTRIBUTE_UNUSED)
 {
   return (insn & 0x0200) ? 31 : -1;
 }
 
-static unsigned
-insert_pclel (unsigned insn,
-	      int value,
+static unsigned long long
+insert_pclel (unsigned long long insn,
+	      long long int value,
 	      const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value != 63)
@@ -576,8 +576,8 @@ insert_pclel (unsigned insn,
   return insn;
 }
 
-static int
-extract_pclel (unsigned insn  ATTRIBUTE_UNUSED,
+static long long int
+extract_pclel (unsigned long long insn  ATTRIBUTE_UNUSED,
 	       bfd_boolean * invalid  ATTRIBUTE_UNUSED)
 {
   return (insn & 0x0400) ? 63 : -1;
@@ -586,9 +586,9 @@ extract_pclel (unsigned insn  ATTRIBUTE_UNUSED,
 #define INSERT_W6
 /* mask = 00000000000000000000111111000000
    insn = 00011bbb000000000BBBwwwwwwDaaZZ1.  */
-static unsigned
-insert_w6 (unsigned insn ATTRIBUTE_UNUSED,
-	   int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_w6 (unsigned long long insn ATTRIBUTE_UNUSED,
+	   long long int value ATTRIBUTE_UNUSED,
 	   const char **errmsg ATTRIBUTE_UNUSED)
 {
   insn |= ((value >> 0) & 0x003f) << 6;
@@ -598,8 +598,8 @@ insert_w6 (unsigned insn ATTRIBUTE_UNUSED,
 
 #define EXTRACT_W6
 /* mask = 00000000000000000000111111000000.  */
-static int
-extract_w6 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_w6 (unsigned long long insn ATTRIBUTE_UNUSED,
 	    bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned value = 0;
@@ -612,9 +612,9 @@ extract_w6 (unsigned insn ATTRIBUTE_UNUSED,
 #define INSERT_G_S
 /* mask = 0000011100022000
    insn = 01000ggghhhGG0HH.  */
-static unsigned
-insert_g_s (unsigned insn ATTRIBUTE_UNUSED,
-	    int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_g_s (unsigned long long insn ATTRIBUTE_UNUSED,
+	    long long int value ATTRIBUTE_UNUSED,
 	    const char **errmsg ATTRIBUTE_UNUSED)
 {
   insn |= ((value >> 0) & 0x0007) << 8;
@@ -625,8 +625,8 @@ insert_g_s (unsigned insn ATTRIBUTE_UNUSED,
 
 #define EXTRACT_G_S
 /* mask = 0000011100022000.  */
-static int
-extract_g_s (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_g_s (unsigned long long insn ATTRIBUTE_UNUSED,
 	     bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = 0;
@@ -642,157 +642,58 @@ extract_g_s (unsigned insn ATTRIBUTE_UNUSED,
 }
 
 /* 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_dst_short (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 << 8;
-      break;
-    case 12:
-    case 13:
-    case 14:
-    case 15:
-      insn |= (value - 8) << 8;
-      break;
-    default:
-      *errmsg = _("Register must be either r0-r3 or r12-r15.");
-      break;
-    }
-  return insn;
-}
-
-static int
-extract_nps_3bit_dst_short (unsigned insn ATTRIBUTE_UNUSED,
-                            bfd_boolean * invalid ATTRIBUTE_UNUSED)
-{
-  int value = (insn >> 8) & 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_3bit_src2_short (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 << 5;
-      break;
-    case 12:
-    case 13:
-    case 14:
-    case 15:
-      insn |= (value - 8) << 5;
-      break;
-    default:
-      *errmsg = _("Register must be either r0-r3 or r12-r15.");
-      break;
-    }
-  return insn;
-}
-
-static int
-extract_nps_3bit_src2_short (unsigned insn ATTRIBUTE_UNUSED,
-                             bfd_boolean * invalid ATTRIBUTE_UNUSED)
-{
-  int value = (insn >> 5) & 0x07;
-  if (value > 3)
-    return (value + 8);
-  else
-    return value;
-}
-
-static unsigned
-insert_nps_bitop_size_2b (unsigned insn ATTRIBUTE_UNUSED,
-                          int value ATTRIBUTE_UNUSED,
+#define MAKE_3BIT_REG_INSERT_EXTRACT_FUNCS(NAME,OFFSET)          \
+static unsigned long long					 \
+insert_nps_3bit_reg_at_##OFFSET##_##NAME		         \
+                    (unsigned long long insn ATTRIBUTE_UNUSED,   \
+                     long long int value ATTRIBUTE_UNUSED,	 \
+                     const char **errmsg ATTRIBUTE_UNUSED)	 \
+{								 \
+  switch (value)						 \
+    {								 \
+    case 0:                                                      \
+    case 1:                                                      \
+    case 2:                                                      \
+    case 3:                                                      \
+      insn |= value << (OFFSET);                                 \
+      break;                                                     \
+    case 12:                                                     \
+    case 13:                                                     \
+    case 14:                                                     \
+    case 15:                                                     \
+      insn |= (value - 8) << (OFFSET);                           \
+      break;                                                     \
+    default:                                                     \
+      *errmsg = _("Register must be either r0-r3 or r12-r15.");  \
+      break;                                                     \
+    }                                                            \
+  return insn;                                                   \
+}                                                                \
+                                                                 \
+static long long int						 \
+extract_nps_3bit_reg_at_##OFFSET##_##NAME                        \
+                    (unsigned long long insn ATTRIBUTE_UNUSED,   \
+                     bfd_boolean * invalid ATTRIBUTE_UNUSED)     \
+{                                                                \
+  int value = (insn >> (OFFSET)) & 0x07;			 \
+  if (value > 3)                                                 \
+    value += 8;                                                  \
+  return value;                                                  \
+}                                                                \
+
+MAKE_3BIT_REG_INSERT_EXTRACT_FUNCS(dst,8)
+MAKE_3BIT_REG_INSERT_EXTRACT_FUNCS(dst,24)
+MAKE_3BIT_REG_INSERT_EXTRACT_FUNCS(dst,40)
+MAKE_3BIT_REG_INSERT_EXTRACT_FUNCS(dst,56)
+
+MAKE_3BIT_REG_INSERT_EXTRACT_FUNCS(src2,5)
+MAKE_3BIT_REG_INSERT_EXTRACT_FUNCS(src2,21)
+MAKE_3BIT_REG_INSERT_EXTRACT_FUNCS(src2,37)
+MAKE_3BIT_REG_INSERT_EXTRACT_FUNCS(src2,53)
+
+static unsigned long long
+insert_nps_bitop_size_2b (unsigned long long insn ATTRIBUTE_UNUSED,
+                          long long int value ATTRIBUTE_UNUSED,
                           const char **errmsg ATTRIBUTE_UNUSED)
 {
   switch (value)
@@ -819,16 +720,16 @@ insert_nps_bitop_size_2b (unsigned insn ATTRIBUTE_UNUSED,
   return insn;
 }
 
-static int
-extract_nps_bitop_size_2b (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_nps_bitop_size_2b (unsigned long long 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,
+static unsigned long long
+insert_nps_bitop_uimm8 (unsigned long long insn ATTRIBUTE_UNUSED,
+                        long long int value ATTRIBUTE_UNUSED,
                         const char **errmsg ATTRIBUTE_UNUSED)
 {
   insn |= ((value >> 5) & 7) << 12;
@@ -836,16 +737,16 @@ insert_nps_bitop_uimm8 (unsigned insn ATTRIBUTE_UNUSED,
   return insn;
 }
 
-static int
-extract_nps_bitop_uimm8 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_nps_bitop_uimm8 (unsigned long long 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,
+static unsigned long long
+insert_nps_rflt_uimm6 (unsigned long long insn ATTRIBUTE_UNUSED,
+                       long long int value ATTRIBUTE_UNUSED,
                        const char **errmsg ATTRIBUTE_UNUSED)
 {
   switch (value)
@@ -864,32 +765,32 @@ insert_nps_rflt_uimm6 (unsigned insn ATTRIBUTE_UNUSED,
   return insn;
 }
 
-static int
-extract_nps_rflt_uimm6 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_nps_rflt_uimm6 (unsigned long long 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,
+static unsigned long long
+insert_nps_dst_pos_and_size (unsigned long long insn ATTRIBUTE_UNUSED,
+                             long long 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,
+static long long int
+extract_nps_dst_pos_and_size (unsigned long long insn ATTRIBUTE_UNUSED,
                               bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   return (insn & 0x1f);
 }
 
-static unsigned
-insert_nps_cmem_uimm16 (unsigned insn ATTRIBUTE_UNUSED,
-                        int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_nps_cmem_uimm16 (unsigned long long insn ATTRIBUTE_UNUSED,
+                        long long int value ATTRIBUTE_UNUSED,
                         const char **errmsg ATTRIBUTE_UNUSED)
 {
   int top = (value >> 16) & 0xffff;
@@ -899,17 +800,17 @@ insert_nps_cmem_uimm16 (unsigned insn ATTRIBUTE_UNUSED,
   return insn;
 }
 
-static int
-extract_nps_cmem_uimm16 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_nps_cmem_uimm16 (unsigned long long insn ATTRIBUTE_UNUSED,
                          bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   return (NPS_CMEM_HIGH_VALUE << 16) | (insn & 0xffff);
 }
 
 #define MAKE_SRC_POS_INSERT_EXTRACT_FUNCS(NAME,SHIFT)         \
-static unsigned                                               \
-insert_nps_##NAME##_pos (unsigned insn ATTRIBUTE_UNUSED,      \
-                        int value ATTRIBUTE_UNUSED,           \
+static unsigned long long                                               \
+insert_nps_##NAME##_pos (unsigned long long insn ATTRIBUTE_UNUSED,      \
+                        long long int value ATTRIBUTE_UNUSED,           \
                         const char **errmsg ATTRIBUTE_UNUSED) \
 {                                                             \
  switch (value)                                               \
@@ -928,8 +829,8 @@ insert_nps_##NAME##_pos (unsigned insn ATTRIBUTE_UNUSED,      \
   return insn;                                                \
 }                                                             \
                                                               \
-static int                                                    \
-extract_nps_##NAME##_pos (unsigned insn ATTRIBUTE_UNUSED,     \
+static long long int                                                    \
+extract_nps_##NAME##_pos (unsigned long long insn ATTRIBUTE_UNUSED,     \
                           bfd_boolean * invalid ATTRIBUTE_UNUSED)     \
 {                                                                     \
   return ((insn >> SHIFT) & 0x3) * 8;                                 \
@@ -939,9 +840,9 @@ MAKE_SRC_POS_INSERT_EXTRACT_FUNCS (src2, 12)
 MAKE_SRC_POS_INSERT_EXTRACT_FUNCS (src1, 10)
 
 #define MAKE_BIAS_INSERT_EXTRACT_FUNCS(NAME,LOWER,UPPER,BITS,BIAS,SHIFT)\
-static unsigned                                                         \
-insert_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED,                      \
-                   int value ATTRIBUTE_UNUSED,                          \
+static unsigned long long                                                         \
+insert_nps_##NAME (unsigned long long insn ATTRIBUTE_UNUSED,                      \
+                   long long int value ATTRIBUTE_UNUSED,                          \
                    const char **errmsg ATTRIBUTE_UNUSED)                \
   {                                                                     \
     if (value < LOWER || value > UPPER)                                 \
@@ -955,8 +856,8 @@ insert_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED,                      \
     return insn;                                                        \
   }                                                                     \
                                                                         \
-static int                                                              \
-extract_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED,                     \
+static long long int                                                              \
+extract_nps_##NAME (unsigned long long insn ATTRIBUTE_UNUSED,                     \
                     bfd_boolean * invalid ATTRIBUTE_UNUSED)             \
 {                                                                       \
   return ((insn >> SHIFT) & ((1 << BITS) - 1)) + BIAS;                  \
@@ -974,8 +875,8 @@ 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,
+static long long int
+extract_nps_qcmp_m3 (unsigned long long insn ATTRIBUTE_UNUSED,
                      bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int m3 = (insn >> 5) & 0xf;
@@ -984,8 +885,8 @@ extract_nps_qcmp_m3 (unsigned insn ATTRIBUTE_UNUSED,
   return m3;
 }
 
-static int
-extract_nps_qcmp_m2 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_nps_qcmp_m2 (unsigned long long insn ATTRIBUTE_UNUSED,
                      bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   bfd_boolean tmp_invalid = FALSE;
@@ -997,8 +898,8 @@ extract_nps_qcmp_m2 (unsigned insn ATTRIBUTE_UNUSED,
   return m2;
 }
 
-static int
-extract_nps_qcmp_m1 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_nps_qcmp_m1 (unsigned long long insn ATTRIBUTE_UNUSED,
                      bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   bfd_boolean tmp_invalid = FALSE;
@@ -1011,9 +912,9 @@ extract_nps_qcmp_m1 (unsigned insn ATTRIBUTE_UNUSED,
   return m1;
 }
 
-static unsigned
-insert_nps_calc_entry_size (unsigned insn ATTRIBUTE_UNUSED,
-                            int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_nps_calc_entry_size (unsigned long long insn ATTRIBUTE_UNUSED,
+                            long long int value ATTRIBUTE_UNUSED,
                             const char **errmsg ATTRIBUTE_UNUSED)
 {
   unsigned pwr;
@@ -1036,64 +937,49 @@ insert_nps_calc_entry_size (unsigned insn ATTRIBUTE_UNUSED,
   return insn | (pwr << 8);
 }
 
-static int
-extract_nps_calc_entry_size (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_nps_calc_entry_size (unsigned long long insn ATTRIBUTE_UNUSED,
                              bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   unsigned entry_size = (insn >> 8) & 0xf;
   return 1 << entry_size;
 }
 
-static unsigned
-insert_nps_bitop_mod4_msb (unsigned insn ATTRIBUTE_UNUSED,
-                           int value ATTRIBUTE_UNUSED,
-                           const char **errmsg ATTRIBUTE_UNUSED)
-{
-  return insn | ((value & 0x2) << 30);
-}
-
-static int
-extract_nps_bitop_mod4_msb (unsigned insn ATTRIBUTE_UNUSED,
-                            bfd_boolean * invalid ATTRIBUTE_UNUSED)
-{
-  return (insn >> 30) & 0x2;
-}
-
-static unsigned
-insert_nps_bitop_mod4_lsb (unsigned insn ATTRIBUTE_UNUSED,
-                           int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_nps_bitop_mod4 (unsigned long long insn ATTRIBUTE_UNUSED,
+                           long long int value ATTRIBUTE_UNUSED,
                            const char **errmsg ATTRIBUTE_UNUSED)
 {
-  return insn | ((value & 0x1) << 15);
+  return insn | ((value & 0x2) << 30) | ((value & 0x1) << 47);
 }
 
-static int
-extract_nps_bitop_mod4_lsb (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_nps_bitop_mod4 (unsigned long long insn ATTRIBUTE_UNUSED,
                             bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
-  return (insn >> 15) & 0x1;
+  return ((insn >> 30) & 0x2) | ((insn >> 47) & 0x1);
 }
 
-static unsigned
-insert_nps_bitop_dst_pos3_pos4 (unsigned insn ATTRIBUTE_UNUSED,
-                                int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_nps_bitop_dst_pos3_pos4 (unsigned long long insn ATTRIBUTE_UNUSED,
+                                long long int value ATTRIBUTE_UNUSED,
                                 const char **errmsg ATTRIBUTE_UNUSED)
 {
-  return insn | (value << 10) | (value << 5);
+  return insn | (value << 42) | (value << 37);
 }
 
-static int
-extract_nps_bitop_dst_pos3_pos4 (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_nps_bitop_dst_pos3_pos4 (unsigned long long insn ATTRIBUTE_UNUSED,
                                  bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
-  if (((insn >> 10) & 0x1f) != ((insn >> 5) & 0x1f))
+  if (((insn >> 42) & 0x1f) != ((insn >> 37) & 0x1f))
     *invalid = TRUE;
-  return ((insn >> 5) & 0x1f);
+  return ((insn >> 37) & 0x1f);
 }
 
-static unsigned
-insert_nps_bitop_ins_ext (unsigned insn ATTRIBUTE_UNUSED,
-                          int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_nps_bitop_ins_ext (unsigned long long insn ATTRIBUTE_UNUSED,
+                          long long int value ATTRIBUTE_UNUSED,
                           const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value < 0 || value > 28)
@@ -1101,8 +987,8 @@ insert_nps_bitop_ins_ext (unsigned insn ATTRIBUTE_UNUSED,
   return insn | (value << 20);
 }
 
-static int
-extract_nps_bitop_ins_ext (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_nps_bitop_ins_ext (unsigned long long insn ATTRIBUTE_UNUSED,
                            bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = (insn >> 20) & 0x1f;
@@ -1112,9 +998,9 @@ extract_nps_bitop_ins_ext (unsigned insn ATTRIBUTE_UNUSED,
 }
 
 #define MAKE_1BASED_INSERT_EXTRACT_FUNCS(NAME,SHIFT,UPPER,BITS)         \
-static unsigned                                                         \
-insert_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED,                      \
-                   int value ATTRIBUTE_UNUSED,                          \
+static unsigned long long                                                         \
+insert_nps_##NAME (unsigned long long insn ATTRIBUTE_UNUSED,                      \
+                   long long int value ATTRIBUTE_UNUSED,                          \
                    const char **errmsg ATTRIBUTE_UNUSED)                \
 {                                                                       \
   if (value < 1 || value > UPPER)                                       \
@@ -1124,8 +1010,8 @@ insert_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED,                      \
   return insn | (value << SHIFT);                                       \
 }                                                                       \
                                                                         \
-static int                                                              \
-extract_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED,                     \
+static long long int                                                              \
+extract_nps_##NAME (unsigned long long insn ATTRIBUTE_UNUSED,                     \
                     bfd_boolean * invalid ATTRIBUTE_UNUSED)             \
 {                                                                       \
   int value = (insn >> SHIFT) & ((1 << BITS) - 1);                      \
@@ -1141,9 +1027,9 @@ 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,
-                     int value ATTRIBUTE_UNUSED,
+static unsigned long long
+insert_nps_min_hofs (unsigned long long insn ATTRIBUTE_UNUSED,
+                     long long int value ATTRIBUTE_UNUSED,
                      const char **errmsg ATTRIBUTE_UNUSED)
 {
   if (value < 0 || value > 240)
@@ -1154,8 +1040,8 @@ insert_nps_min_hofs (unsigned insn ATTRIBUTE_UNUSED,
   return insn | (value << 6);
 }
 
-static int
-extract_nps_min_hofs (unsigned insn ATTRIBUTE_UNUSED,
+static long long int
+extract_nps_min_hofs (unsigned long long insn ATTRIBUTE_UNUSED,
                       bfd_boolean * invalid ATTRIBUTE_UNUSED)
 {
   int value = (insn >> 6) & 0xF;
@@ -1163,9 +1049,9 @@ extract_nps_min_hofs (unsigned insn ATTRIBUTE_UNUSED,
 }
 
 #define MAKE_INSERT_NPS_ADDRTYPE(NAME,VALUE)                           \
-static unsigned                                                        \
-insert_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED,                     \
-                   int value ATTRIBUTE_UNUSED,                         \
+static unsigned long long                                              \
+insert_nps_##NAME (unsigned long long insn ATTRIBUTE_UNUSED,           \
+                   long long int value ATTRIBUTE_UNUSED,               \
                    const char **errmsg ATTRIBUTE_UNUSED)               \
 {                                                                      \
   if (value != ARC_NPS400_ADDRTYPE_##VALUE)                            \
@@ -1173,8 +1059,8 @@ insert_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED,                     \
   return insn;                                                         \
 }                                                                      \
                                                                        \
-static int                                                             \
-extract_nps_##NAME (unsigned insn ATTRIBUTE_UNUSED,                    \
+static long long int                                                   \
+extract_nps_##NAME (unsigned long long insn ATTRIBUTE_UNUSED,          \
                     bfd_boolean * invalid ATTRIBUTE_UNUSED)            \
 {                                                                      \
   return ARC_NPS400_ADDRTYPE_##VALUE;                                  \
@@ -1197,7 +1083,6 @@ 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.  */
@@ -1919,13 +1804,13 @@ const struct arc_operand arc_operands[] =
 
   /* 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 },
+  { 3, 24, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_reg_at_24_dst, extract_nps_3bit_reg_at_24_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 },
+  { 3, 24, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE | ARC_OPERAND_NCHK, insert_nps_3bit_reg_at_24_dst, extract_nps_3bit_reg_at_24_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 },
+  { 3, 21, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_reg_at_21_src2, extract_nps_3bit_reg_at_21_src2 },
 
 #define NPS_R_DST	(NPS_R_SRC2_3B + 1)
   { 6, 21, 0, ARC_OPERAND_IR, NULL, NULL },
@@ -2003,13 +1888,13 @@ const struct arc_operand arc_operands[] =
   { 0, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_calc_entry_size, extract_nps_calc_entry_size },
 
 #define NPS_R_DST_3B_SHORT	(NPS_CALC_ENTRY_SIZE + 1)
-  { 3, 8, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_dst_short, extract_nps_3bit_dst_short },
+  { 3, 8, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_reg_at_8_dst, extract_nps_3bit_reg_at_8_dst },
 
 #define NPS_R_SRC1_3B_SHORT	(NPS_R_DST_3B_SHORT + 1)
-  { 3, 8, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE | ARC_OPERAND_NCHK, insert_nps_3bit_dst_short, extract_nps_3bit_dst_short },
+  { 3, 8, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE | ARC_OPERAND_NCHK, insert_nps_3bit_reg_at_8_dst, extract_nps_3bit_reg_at_8_dst },
 
 #define NPS_R_SRC2_3B_SHORT	(NPS_R_SRC1_3B_SHORT + 1)
-  { 3, 5, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_src2_short, extract_nps_3bit_src2_short },
+  { 3, 5, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_reg_at_5_src2, extract_nps_3bit_reg_at_5_src2 },
 
 #define NPS_BITOP_SIZE2		(NPS_R_SRC2_3B_SHORT + 1)
   { 5, 25, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_bitop2_size, extract_nps_bitop2_size },
@@ -2021,10 +1906,10 @@ const struct arc_operand arc_operands[] =
   { 5, 0, 0, ARC_OPERAND_UNSIGNED, insert_nps_bitop_dst_pos3_pos4, extract_nps_bitop_dst_pos3_pos4 },
 
 #define NPS_BITOP_DST_POS4		(NPS_BITOP_DST_POS3_POS4 + 1)
-  { 5, 10, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+  { 5, 42, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
 
 #define NPS_BITOP_DST_POS3		(NPS_BITOP_DST_POS4 + 1)
-  { 5, 5, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+  { 5, 37, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
 
 #define NPS_BITOP_DST_POS2		(NPS_BITOP_DST_POS3 + 1)
   { 5, 15, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
@@ -2033,7 +1918,7 @@ const struct arc_operand arc_operands[] =
   { 5, 10, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
 
 #define NPS_BITOP_SRC_POS4		(NPS_BITOP_DST_POS1 + 1)
-  { 5, 0, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
+  { 5, 32, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
 
 #define NPS_BITOP_SRC_POS3		(NPS_BITOP_SRC_POS4 + 1)
   { 5, 20, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
@@ -2044,13 +1929,10 @@ const struct arc_operand arc_operands[] =
 #define NPS_BITOP_SRC_POS1		(NPS_BITOP_SRC_POS2 + 1)
   { 5, 0, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
 
-#define NPS_BITOP_MOD4_MSB		(NPS_BITOP_SRC_POS1 + 1)
-  { 2, 0, 0, ARC_OPERAND_UNSIGNED, insert_nps_bitop_mod4_msb, extract_nps_bitop_mod4_msb },
-
-#define NPS_BITOP_MOD4_LSB		(NPS_BITOP_MOD4_MSB + 1)
-  { 2, 0, 0, ARC_OPERAND_UNSIGNED, insert_nps_bitop_mod4_lsb, extract_nps_bitop_mod4_lsb },
+#define NPS_BITOP_MOD4			(NPS_BITOP_SRC_POS1 + 1)
+  { 2, 0, 0, ARC_OPERAND_UNSIGNED, insert_nps_bitop_mod4, extract_nps_bitop_mod4 },
 
-#define NPS_BITOP_MOD3		(NPS_BITOP_MOD4_LSB + 1)
+#define NPS_BITOP_MOD3		(NPS_BITOP_MOD4 + 1)
   { 2, 29, 0, ARC_OPERAND_UNSIGNED, NULL, NULL },
 
 #define NPS_BITOP_MOD2		(NPS_BITOP_MOD3 + 1)
@@ -2091,7 +1973,7 @@ const struct arc_operand arc_operands[] =
 
   /* NPS_DPI_SRC1_3B is similar to NPS_R_SRC1_3B but doesn't duplicate an operand */
 #define NPS_DPI_SRC1_3B    (NPS_DPI_DST + 1)
-  { 3, 24, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_dst, extract_nps_3bit_dst },
+  { 3, 24, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_reg_at_24_dst, extract_nps_3bit_reg_at_24_dst },
 
 #define NPS_HASH_WIDTH       (NPS_DPI_SRC1_3B + 1)
   { 5, 6, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK, insert_nps_hash_width, extract_nps_hash_width },
@@ -2188,6 +2070,24 @@ const struct arc_operand arc_operands[] =
 
 #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 },
+
+#define NPS_R_DST_3B_48	(NPS_PMU_NUM_JOB + 1)
+  { 3, 40, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_reg_at_40_dst, extract_nps_3bit_reg_at_40_dst },
+
+#define NPS_R_SRC1_3B_48	(NPS_R_DST_3B_48 + 1)
+  { 3, 40, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE | ARC_OPERAND_NCHK, insert_nps_3bit_reg_at_40_dst, extract_nps_3bit_reg_at_40_dst },
+
+#define NPS_R_SRC2_3B_48	(NPS_R_SRC1_3B_48 + 1)
+  { 3, 37, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_reg_at_37_src2, extract_nps_3bit_reg_at_37_src2 },
+
+#define NPS_R_DST_3B_64		(NPS_R_SRC2_3B_48 + 1)
+  { 3, 56, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_reg_at_56_dst, extract_nps_3bit_reg_at_56_dst },
+
+#define NPS_R_SRC1_3B_64	(NPS_R_DST_3B_64 + 1)
+  { 3, 56, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE | ARC_OPERAND_NCHK, insert_nps_3bit_reg_at_56_dst, extract_nps_3bit_reg_at_56_dst },
+
+#define NPS_R_SRC2_3B_64	(NPS_R_SRC1_3B_64 + 1)
+  { 3, 53, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, insert_nps_3bit_reg_at_53_src2, extract_nps_3bit_reg_at_53_src2 },
 };
 
 const unsigned arc_num_operands = ARRAY_SIZE (arc_operands);
@@ -2560,101 +2460,19 @@ const struct arc_opcode arc_relax_opcodes[] =
 
 const unsigned arc_num_relax_opcodes = ARRAY_SIZE (arc_relax_opcodes);
 
-/* The following instructions are all either 48 or 64 bits long, and
-   require special handling in the assembler and disassembler.
-
-   The first part of each ARC_LONG_OPCODE is the base ARC_OPCODE, this is
-   either the 16 or 32 bit base instruction, and its opcode list will
-   always end in a LIMM.
-
-   The rest of the ARC_LONG_OPCODE describes how to build the LIMM from the
-   instruction operands.  There are therefore two lists of operands for
-   each ARC_LONG_OPCODE, the second list contains operands that are merged
-   into the limm template, in the same way that a standard 32-bit
-   instruction is built.  This generated limm is then added to the list of
-   tokens that is passed to the standard instruction encoder, along with
-   the first list of operands (from the base arc_opcode).
-
-   The first list of operands then, describes how to build the base
-   instruction, and includes the 32-bit limm that was previously generated
-   as the last operand.
-
-   In most cases operands are either encoded into the base instruction or
-   into the limm.  When this happens the operand slot will be filled with
-   an operand identifier in one list, and will be IGNORED in the other
-   list, this special operand value causes the operand to be ignored,
-   without being encoded at this point.
-
-   However, in some cases, an operand is split between the base instruction
-   and the 32-bit limm, in this case the operand slot will be filled in
-   both operand lists (see mov4b for one example of this).   */
-const struct arc_long_opcode arc_long_opcodes[] =
-  {
-    /* mrgb - (48 bit instruction).  */
-    { { "mrgb", 0x5803, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC1_3B_SHORT, NPS_R_SRC2_3B_SHORT, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { 0 }},
-      0x00000000, 0x80000000, { IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_SRC_POS1, NPS_BITOP_SIZE1, NPS_BITOP_DST_POS2, NPS_BITOP_SRC_POS2, NPS_BITOP_SIZE2 }},
-
-    /* mrgb.cl - (48 bit instruction).  */
-    { { "mrgb", 0x5803, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC1_3B_SHORT, NPS_R_SRC2_3B_SHORT, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { C_NPS_CL }},
-      0x80000000, 0x80000000, { IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_SRC_POS1, NPS_BITOP_SIZE1, NPS_BITOP_DST_POS2, NPS_BITOP_SRC_POS2, NPS_BITOP_SIZE2 }},
-
-    /* mov2b - (48 bit instruction).  */
-    { { "mov2b", 0x5800, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC1_3B_SHORT, NPS_R_SRC2_3B_SHORT,  IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { 0 }},
-      0x00000000, 0x80000000, { IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2 }},
-
-    /* mov2b.cl - (48 bit instruction).  */
-    { { "mov2b", 0x5800, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC2_3B_SHORT,  IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { C_NPS_CL }},
-      0x80000000, 0x80000000, { IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2 }},
-
-    /* ext4 - (48 bit instruction).  */
-    { { "ext4b", 0x5801, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC1_3B_SHORT, NPS_R_SRC2_3B_SHORT,  IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { 0 }},
-      0x00000000, 0x80000000, { IGNORED, IGNORED, IGNORED, NPS_BITOP_INS_EXT, NPS_BITOP_SRC_POS1, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS1, NPS_BITOP_DST_POS2 }},
-
-    /* ext4.cl - (48 bit instruction).  */
-    { { "ext4b", 0x5801, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC2_3B_SHORT,  IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { C_NPS_CL }},
-      0x80000000, 0x80000000, { IGNORED, IGNORED, NPS_BITOP_INS_EXT, NPS_BITOP_SRC_POS1, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS1, NPS_BITOP_DST_POS2 }},
-
-    /* ins4 - (48 bit instruction).  */
-    { { "ins4b", 0x5802, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC1_3B_SHORT, NPS_R_SRC2_3B_SHORT,  IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { 0 }},
-      0x00000000, 0x80000000, { IGNORED, IGNORED, IGNORED, NPS_BITOP_SRC_POS1, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_INS_EXT }},
-
-    /* ins4.cl - (48 bit instruction).  */
-    { { "ins4b", 0x5802, 0xf81f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B_SHORT, NPS_R_SRC2_3B_SHORT,  IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, LIMM }, { C_NPS_CL }},
-      0x80000000, 0x80000000, { IGNORED, IGNORED, NPS_BITOP_SRC_POS1, NPS_BITOP_SRC_POS2, NPS_BITOP_DST_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_INS_EXT }},
-
-    /* mov3b - (64 bit instruction).  */
-    { { "mov3b", 0x58100000, 0xf81f801f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_R_SRC2_3B, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS3_POS4, IGNORED, IGNORED, LIMM }, { 0 }},
-      0x80000000, 0x80000000, { IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, IGNORED, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3 }},
-
-    /* mov4b - (64 bit instruction).  */
-    { { "mov4b", 0x58100000, 0xf81f0000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B, NPS_R_SRC1_3B, NPS_R_SRC2_3B, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS3, IGNORED, IGNORED, NPS_BITOP_DST_POS4, NPS_BITOP_MOD4_LSB, NPS_BITOP_SRC_POS4, LIMM }, { 0 }},
-      0x00000000, 0x00000000, { IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, IGNORED, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3, IGNORED, NPS_BITOP_MOD4_MSB, IGNORED}},
-
-    /* mov3bcl - (64 bit instruction).  */
-    { { "mov3bcl", 0x58110000, 0xf81f801f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B, NPS_R_SRC2_3B, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS3_POS4, IGNORED, IGNORED, LIMM }, { 0 }},
-      0x80000000, 0x80000000, { IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, IGNORED, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3 }},
-
-    /* mov4bcl - (64 bit instruction).  */
-    { { "mov4bcl", 0x58110000, 0xf81f0000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B, NPS_R_SRC2_3B, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS3, IGNORED, IGNORED, NPS_BITOP_DST_POS4, NPS_BITOP_MOD4_LSB, NPS_BITOP_SRC_POS4, LIMM }, { 0 }},
-      0x00000000, 0x00000000, { IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, IGNORED, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3, IGNORED, NPS_BITOP_MOD4_MSB, IGNORED}},
-
-    /* mov3b.cl - (64 bit instruction).  */
-    { { "mov3b", 0x58110000, 0xf81f801f, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B, NPS_R_SRC2_3B, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS3_POS4, IGNORED, IGNORED, LIMM }, { C_NPS_CL }},
-      0x80000000, 0x80000000, { IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, IGNORED, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3 }},
-
-    /* mov4b.cl - (64 bit instruction).  */
-    { { "mov4b", 0x58110000, 0xf81f0000, ARC_OPCODE_ARC700, BITOP, NPS400, { NPS_R_DST_3B, NPS_R_SRC2_3B, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, IGNORED, NPS_BITOP_DST_POS3, IGNORED, IGNORED, NPS_BITOP_DST_POS4, NPS_BITOP_MOD4_LSB, NPS_BITOP_SRC_POS4, LIMM }, { C_NPS_CL }},
-      0x00000000, 0x00000000, { IGNORED, IGNORED, NPS_BITOP_DST_POS1, NPS_BITOP_MOD1, NPS_BITOP_SRC_POS1, NPS_BITOP_DST_POS2, NPS_BITOP_MOD2, NPS_BITOP_SRC_POS2, IGNORED, NPS_BITOP_MOD3, NPS_BITOP_SRC_POS3, IGNORED, NPS_BITOP_MOD4_MSB, IGNORED}},
-};
-
-const unsigned arc_num_long_opcodes = ARRAY_SIZE (arc_long_opcodes);
-
-/* Return length of instruction represented by OPCODE in bytes.  */
+/* Return length of an opcode in bytes.  */
 
 int
 arc_opcode_len (const struct arc_opcode *opcode)
 {
   if (opcode->mask < 0x10000ull)
     return 2;
-  return 4;
+
+  if (opcode->mask < 0x100000000ull)
+    return 4;
+
+  if (opcode->mask < 0x1000000000000ull)
+    return 6;
+
+  return 8;
 }
-- 
2.7.4



More information about the Binutils mailing list