qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 18/27] arcv3: Decoder code


From: cupertinomiranda
Subject: [PATCH 18/27] arcv3: Decoder code
Date: Mon, 5 Apr 2021 15:31:29 +0100

From: Cupertino Miranda <cmiranda@synopsys.com>

---
 disas/arc.c                |   51 +-
 target/arc/decoder-v3.c    | 1547 ++++++++++++++++++++++++++++++++++++
 target/arc/decoder-v3.h    |  322 ++++++++
 target/arc/flags-v3.def    |  103 +++
 target/arc/operands-v3.def |  133 ++++
 5 files changed, 2147 insertions(+), 9 deletions(-)
 create mode 100644 target/arc/decoder-v3.c
 create mode 100644 target/arc/decoder-v3.h
 create mode 100644 target/arc/flags-v3.def
 create mode 100644 target/arc/operands-v3.def

diff --git a/disas/arc.c b/disas/arc.c
index f8b2e31be9..9a9c289948 100644
--- a/disas/arc.c
+++ b/disas/arc.c
@@ -308,8 +308,15 @@ static int arc_read_mem(bfd_vma memaddr,
     case bfd_mach_arc_arcv2hs:
         *isa_mask = ARC_OPCODE_ARCv2HS;
         break;
+    case bfd_mach_arcv3_64:
+        *isa_mask = ARC_OPCODE_V3_ARC64;
+        break;
+    case bfd_mach_arcv3_32:
+        *isa_mask = ARC_OPCODE_V3_ARC32;
+        break;
+
     default:
-        *isa_mask = ARC_OPCODE_ARCv2EM;
+        *isa_mask = ARC_OPCODE_NONE;
         break;
     }
 
@@ -390,15 +397,41 @@ int print_insn_arc(bfd_vma memaddr, struct 
disassemble_info *info)
     opcode = arc_find_format(&dis_insn, insn, insn_len, isa_mask);
 
     /* If limm is required, read it. */
-    if (dis_insn.limm_p) {
-        bfd_byte buffer[4];
-        int status = (*info->read_memory_func)(memaddr + insn_len, buffer,
-                                               4, info);
-        if (status != 0) {
-            return -1;
+    if((isa_mask & ARC_OPCODE_V3_ALL) != 0) {
+        if (dis_insn.unsigned_limm_p) {
+            bfd_byte buffer[4];
+            int status = (*info->read_memory_func)(memaddr + insn_len, buffer,
+                                                   4, info);
+            if (status != 0) {
+                return -1;
+            }
+            dis_insn.limm = ARRANGE_ENDIAN (info, buffer);
+            insn_len += 4;
+        }
+        else if (dis_insn.signed_limm_p) {
+            bfd_byte buffer[4];
+            int status = (*info->read_memory_func)(memaddr + insn_len, buffer,
+                                                   4, info);
+            if (status != 0) {
+                return -1;
+            }
+            dis_insn.limm = ARRANGE_ENDIAN (info, buffer);
+            if(dis_insn.limm & 0x80000000)
+              dis_insn.limm += 0xffffffff00000000;
+            insn_len += 4;
+        }
+
+    } else {
+        if (dis_insn.limm_p) {
+            bfd_byte buffer[4];
+            int status = (*info->read_memory_func)(memaddr + insn_len, buffer,
+                                                   4, info);
+            if (status != 0) {
+                return -1;
+            }
+            dis_insn.limm = ARRANGE_ENDIAN(info, buffer);
+            insn_len += 4;
         }
-        dis_insn.limm = ARRANGE_ENDIAN(info, buffer);
-        insn_len += 4;
     }
 
     /* Print the mnemonic. */
diff --git a/target/arc/decoder-v3.c b/target/arc/decoder-v3.c
new file mode 100644
index 0000000000..ae058c706d
--- /dev/null
+++ b/target/arc/decoder-v3.c
@@ -0,0 +1,1547 @@
+/*
+ * Decoder for the ARC.
+ * Copyright (C) 2017 Free Software Foundation, Inc.
+
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with GAS or GDB; see the file COPYING3.  If not, write to
+ * the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include "qemu/osdep.h"
+#include "target/arc/decoder.h"
+#include "qemu/osdep.h"
+#include "qemu/bswap.h"
+#include "cpu.h"
+
+/* Register names. */
+static const char * const regnames[64] = {
+    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+    "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+    "r24", "r25",
+    "gp",
+    "fp", "sp", "ilink", "r30", "blink",
+
+    "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
+    "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
+    "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
+    "r56", "r57", "r58", "r59", "lp_count", "rezerved", "LIMM", "pcl"
+};
+const char *get_register_name(int value)
+{
+    return regnames[value];
+}
+
+extern bool special_flag_p(const char *opname, const char *flgname);
+
+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);
+
+  if (value == 0x3e && invalid)
+    *invalid = TRUE; /* A limm operand, it should be extracted in a
+                       different way.  */
+
+  return value;
+}
+
+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);
+
+  return value;
+}
+
+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);
+
+  return value;
+}
+
+static long long int
+extract_r0 (unsigned long long insn ATTRIBUTE_UNUSED,
+           bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
+
+static long long int
+extract_r1 (unsigned long long insn ATTRIBUTE_UNUSED,
+           bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return 1;
+}
+
+static long long int
+extract_r2 (unsigned long long insn ATTRIBUTE_UNUSED,
+           bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return 2;
+}
+
+static long long int
+extract_r3 (unsigned long long insn ATTRIBUTE_UNUSED,
+           bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return 3;
+}
+
+static long long int
+extract_sp (unsigned long long insn ATTRIBUTE_UNUSED,
+           bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return 28;
+}
+
+static long long int
+extract_gp (unsigned long long insn ATTRIBUTE_UNUSED,
+           bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return 26;
+}
+
+static long long int
+extract_pcl (unsigned long long insn ATTRIBUTE_UNUSED,
+            bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return 63;
+}
+
+static long long int
+extract_blink (unsigned long long insn ATTRIBUTE_UNUSED,
+              bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return 31;
+}
+
+static long long int
+extract_ilink1 (unsigned long long insn ATTRIBUTE_UNUSED,
+               bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return 29;
+}
+
+static long long int
+extract_ilink2 (unsigned long long insn ATTRIBUTE_UNUSED,
+               bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  return 30;
+}
+
+static long long int
+extract_ras (unsigned long long insn ATTRIBUTE_UNUSED,
+            bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = insn & 0x07;
+  if (value > 3)
+    return (value + 8);
+  else
+    return value;
+}
+
+static long long int
+extract_rbs (unsigned long long insn ATTRIBUTE_UNUSED,
+            bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = (insn >> 8) & 0x07;
+  if (value > 3)
+    return (value + 8);
+  else
+    return value;
+}
+
+static long long int
+extract_rcs (unsigned long long insn ATTRIBUTE_UNUSED,
+            bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = (insn >> 5) & 0x07;
+  if (value > 3)
+    return (value + 8);
+  else
+    return value;
+}
+
+static long long int
+extract_simm3s (unsigned long long insn ATTRIBUTE_UNUSED,
+               bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = (insn >> 8) & 0x07;
+  if (value == 7)
+    return -1;
+  else
+    return value;
+}
+
+static long long int
+extract_rrange (unsigned long long insn  ATTRIBUTE_UNUSED,
+               bfd_boolean * invalid  ATTRIBUTE_UNUSED)
+{
+  return (insn >> 1) & 0x0F;
+}
+
+static long long int
+extract_fpel (unsigned long long insn  ATTRIBUTE_UNUSED,
+             bfd_boolean * invalid  ATTRIBUTE_UNUSED)
+{
+  return (insn & 0x0100) ? 27 : -1;
+}
+
+static long long int
+extract_blinkel (unsigned long long insn  ATTRIBUTE_UNUSED,
+                bfd_boolean * invalid  ATTRIBUTE_UNUSED)
+{
+  return (insn & 0x0200) ? 31 : -1;
+}
+
+static long long int
+extract_pclel (unsigned long long insn  ATTRIBUTE_UNUSED,
+              bfd_boolean * invalid  ATTRIBUTE_UNUSED)
+{
+  return (insn & 0x0400) ? 63 : -1;
+}
+
+#define EXTRACT_W6
+/* mask = 00000000000000000000111111000000.  */
+static long long int
+extract_w6 (unsigned long long insn ATTRIBUTE_UNUSED,
+           bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  signed value = 0;
+
+  value |= ((insn >> 6) & 0x003f) << 0;
+
+  int signbit = 1 << 5;
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+
+#define EXTRACT_G_S
+/* mask = 0000011100022000.  */
+static long long int
+extract_g_s (unsigned long long insn ATTRIBUTE_UNUSED,
+            bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 8) & 0x0007) << 0;
+  value |= ((insn >> 3) & 0x0003) << 3;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (6 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+
+static long long int
+extract_uimm12_20 (unsigned long long insn ATTRIBUTE_UNUSED,
+                  bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 6) & 0x003f) << 0;
+  value |= ((insn >> 0) & 0x003f) << 6;
+
+  return value;
+}
+
+#ifndef EXTRACT_LIMM
+#define EXTRACT_LIMM
+/* mask = 00000000000000000000000000000000.  */
+static ATTRIBUTE_UNUSED int
+extract_limm (unsigned long long insn ATTRIBUTE_UNUSED, bfd_boolean * invalid 
ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  return value;
+}
+#endif /* EXTRACT_LIMM */
+
+#ifndef EXTRACT_UIMM6_20
+#define EXTRACT_UIMM6_20
+/* mask = 00000000000000000000111111000000.  */
+static long long int
+extract_uimm6_20 (unsigned long long insn ATTRIBUTE_UNUSED,
+                 bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 6) & 0x003f) << 0;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM6_20 */
+
+#ifndef EXTRACT_SIMM12_20
+#define EXTRACT_SIMM12_20
+/* mask = 00000000000000000000111111222222.  */
+static long long int
+extract_simm12_20 (unsigned long long insn ATTRIBUTE_UNUSED,
+                  bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 6) & 0x003f) << 0;
+  value |= ((insn >> 0) & 0x003f) << 6;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (12 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM12_20 */
+
+#ifndef EXTRACT_SIMM3_5_S
+#define EXTRACT_SIMM3_5_S
+/* mask = 0000011100000000.  */
+static ATTRIBUTE_UNUSED int
+extract_simm3_5_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                  bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 8) & 0x0007) << 0;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (3 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM3_5_S */
+
+#ifndef EXTRACT_LIMM_S
+#define EXTRACT_LIMM_S
+/* mask = 0000000000000000.  */
+static ATTRIBUTE_UNUSED int
+extract_limm_s (unsigned long long insn ATTRIBUTE_UNUSED, bfd_boolean * 
invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  return value;
+}
+#endif /* EXTRACT_LIMM_S */
+
+#ifndef EXTRACT_UIMM7_A32_11_S
+#define EXTRACT_UIMM7_A32_11_S
+/* mask = 0000000000011111.  */
+static long long int
+extract_uimm7_a32_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                       bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 0) & 0x001f) << 2;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM7_A32_11_S */
+
+#ifndef EXTRACT_UIMM7_9_S
+#define EXTRACT_UIMM7_9_S
+/* mask = 0000000001111111.  */
+static long long int
+extract_uimm7_9_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                  bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 0) & 0x007f) << 0;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM7_9_S */
+
+#ifndef EXTRACT_UIMM3_13_S
+#define EXTRACT_UIMM3_13_S
+/* mask = 0000000000000111.  */
+static long long int
+extract_uimm3_13_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                   bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 0) & 0x0007) << 0;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM3_13_S */
+
+#ifndef EXTRACT_SIMM11_A32_7_S
+#define EXTRACT_SIMM11_A32_7_S
+/* mask = 0000000111111111.  */
+static long long int
+extract_simm11_a32_7_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                       bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 0) & 0x01ff) << 2;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (11 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM11_A32_7_S */
+
+#ifndef EXTRACT_UIMM6_13_S
+#define EXTRACT_UIMM6_13_S
+/* mask = 0000000002220111.  */
+static long long int
+extract_uimm6_13_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                   bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 0) & 0x0007) << 0;
+  value |= ((insn >> 4) & 0x0007) << 3;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM6_13_S */
+
+#ifndef EXTRACT_UIMM5_11_S
+#define EXTRACT_UIMM5_11_S
+/* mask = 0000000000011111.  */
+static long long int
+extract_uimm5_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                   bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 0) & 0x001f) << 0;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM5_11_S */
+
+#ifndef EXTRACT_SIMM9_A16_8
+#define EXTRACT_SIMM9_A16_8
+/* mask = 00000000111111102000000000000000.  */
+static long long int
+extract_simm9_a16_8 (unsigned long long insn ATTRIBUTE_UNUSED,
+                    bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 17) & 0x007f) << 1;
+  value |= ((insn >> 15) & 0x0001) << 8;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (9 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM9_A16_8 */
+
+#ifndef EXTRACT_UIMM6_8
+#define EXTRACT_UIMM6_8
+/* mask = 00000000000000000000111111000000.  */
+static long long int
+extract_uimm6_8 (unsigned long long insn ATTRIBUTE_UNUSED,
+                bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 6) & 0x003f) << 0;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM6_8 */
+
+#ifndef EXTRACT_SIMM21_A16_5
+#define EXTRACT_SIMM21_A16_5
+/* mask = 00000111111111102222222222000000.  */
+static long long int
+extract_simm21_a16_5 (unsigned long long insn ATTRIBUTE_UNUSED,
+                     bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 17) & 0x03ff) << 1;
+  value |= ((insn >> 6) & 0x03ff) << 11;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (21 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM21_A16_5 */
+
+#ifndef EXTRACT_SIMM25_A16_5
+#define EXTRACT_SIMM25_A16_5
+/* mask = 00000111111111102222222222003333.  */
+static long long int
+extract_simm25_a16_5 (unsigned long long insn ATTRIBUTE_UNUSED,
+                     bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 17) & 0x03ff) << 1;
+  value |= ((insn >> 6) & 0x03ff) << 11;
+  value |= ((insn >> 0) & 0x000f) << 21;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (25 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM25_A16_5 */
+
+#ifndef EXTRACT_SIMM10_A16_7_S
+#define EXTRACT_SIMM10_A16_7_S
+/* mask = 0000000111111111.  */
+static long long int
+extract_simm10_a16_7_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                       bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 0) & 0x01ff) << 1;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (10 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM10_A16_7_S */
+
+#ifndef EXTRACT_SIMM7_A16_10_S
+#define EXTRACT_SIMM7_A16_10_S
+/* mask = 0000000000111111.  */
+static long long int
+extract_simm7_a16_10_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                       bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 0) & 0x003f) << 1;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (7 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM7_A16_10_S */
+
+#ifndef EXTRACT_SIMM21_A32_5
+#define EXTRACT_SIMM21_A32_5
+/* mask = 00000111111111002222222222000000.  */
+static long long int
+extract_simm21_a32_5 (unsigned long long insn ATTRIBUTE_UNUSED,
+                     bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 18) & 0x01ff) << 2;
+  value |= ((insn >> 6) & 0x03ff) << 11;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (21 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM21_A32_5 */
+
+#ifndef EXTRACT_SIMM25_A32_5
+#define EXTRACT_SIMM25_A32_5
+/* mask = 00000111111111002222222222003333.  */
+static long long int
+extract_simm25_a32_5 (unsigned long long insn ATTRIBUTE_UNUSED,
+                     bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 18) & 0x01ff) << 2;
+  value |= ((insn >> 6) & 0x03ff) << 11;
+  value |= ((insn >> 0) & 0x000f) << 21;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (25 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM25_A32_5 */
+
+#ifndef EXTRACT_SIMM13_A32_5_S
+#define EXTRACT_SIMM13_A32_5_S
+/* mask = 0000011111111111.  */
+static long long int
+extract_simm13_a32_5_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                       bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 0) & 0x07ff) << 2;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (13 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM13_A32_5_S */
+
+#ifndef EXTRACT_SIMM8_A16_9_S
+#define EXTRACT_SIMM8_A16_9_S
+/* mask = 0000000001111111.  */
+static long long int
+extract_simm8_a16_9_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                      bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 0) & 0x007f) << 1;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (8 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM8_A16_9_S */
+
+#ifndef EXTRACT_UIMM3_23
+#define EXTRACT_UIMM3_23
+/* mask = 00000000000000000000000111000000.  */
+static long long int
+extract_uimm3_23 (unsigned long long insn ATTRIBUTE_UNUSED,
+                 bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 6) & 0x0007) << 0;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM3_23 */
+
+#ifndef EXTRACT_UIMM10_6_S
+#define EXTRACT_UIMM10_6_S
+/* mask = 0000001111111111.  */
+static long long int
+extract_uimm10_6_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                   bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 0) & 0x03ff) << 0;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM10_6_S */
+
+#ifndef EXTRACT_UIMM6_11_S
+#define EXTRACT_UIMM6_11_S
+/* mask = 0000002200011110.  */
+static long long int
+extract_uimm6_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                   bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 1) & 0x000f) << 0;
+  value |= ((insn >> 8) & 0x0003) << 4;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM6_11_S */
+
+#ifndef EXTRACT_SIMM9_8
+#define EXTRACT_SIMM9_8
+/* mask = 00000000111111112000000000000000.  */
+static long long int
+extract_simm9_8 (unsigned long long insn ATTRIBUTE_UNUSED,
+                bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 16) & 0x00ff) << 0;
+  value |= ((insn >> 15) & 0x0001) << 8;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (9 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM9_8 */
+
+#ifndef EXTRACT_UIMM10_A32_8_S
+#define EXTRACT_UIMM10_A32_8_S
+/* mask = 0000000011111111.  */
+static long long int
+extract_uimm10_a32_8_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                       bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 0) & 0x00ff) << 2;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM10_A32_8_S */
+
+#ifndef EXTRACT_SIMM9_7_S
+#define EXTRACT_SIMM9_7_S
+/* mask = 0000000111111111.  */
+static long long int
+extract_simm9_7_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                  bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 0) & 0x01ff) << 0;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (9 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM9_7_S */
+
+#ifndef EXTRACT_UIMM6_A16_11_S
+#define EXTRACT_UIMM6_A16_11_S
+/* mask = 0000000000011111.  */
+static long long int
+extract_uimm6_a16_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                       bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 0) & 0x001f) << 1;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM6_A16_11_S */
+
+
+#ifndef EXTRACT_UIMM5_A32_11_S
+#define EXTRACT_UIMM5_A32_11_S
+/* mask = 0000020000011000.  */
+static long long int
+extract_uimm5_a32_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                       bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 3) & 0x0003) << 2;
+  value |= ((insn >> 10) & 0x0001) << 4;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM5_A32_11_S */
+
+#ifndef EXTRACT_SIMM11_A32_13_S
+#define EXTRACT_SIMM11_A32_13_S
+/* mask = 0000022222200111.  */
+static long long int
+extract_simm11_a32_13_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                        bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 0) & 0x0007) << 2;
+  value |= ((insn >> 5) & 0x003f) << 5;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (11 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM11_A32_13_S */
+
+#ifndef EXTRACT_UIMM7_13_S
+#define EXTRACT_UIMM7_13_S
+/* mask = 0000000022220111.  */
+static long long int
+extract_uimm7_13_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                   bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 0) & 0x0007) << 0;
+  value |= ((insn >> 4) & 0x000f) << 3;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM7_13_S */
+
+#ifndef EXTRACT_UIMM6_A16_21
+#define EXTRACT_UIMM6_A16_21
+/* mask = 00000000000000000000011111000000.  */
+static long long int
+extract_uimm6_a16_21 (unsigned long long insn ATTRIBUTE_UNUSED,
+                     bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 6) & 0x001f) << 1;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM6_A16_21 */
+
+#ifndef EXTRACT_UIMM7_11_S
+#define EXTRACT_UIMM7_11_S
+/* mask = 0000022200011110.  */
+static long long int
+extract_uimm7_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                   bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 1) & 0x000f) << 0;
+  value |= ((insn >> 8) & 0x0007) << 4;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM7_11_S */
+
+#ifndef EXTRACT_UIMM7_A16_20
+#define EXTRACT_UIMM7_A16_20
+/* mask = 00000000000000000000111111000000.  */
+static long long int
+extract_uimm7_a16_20 (unsigned long long insn ATTRIBUTE_UNUSED,
+                     bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 6) & 0x003f) << 1;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM7_A16_20 */
+
+#ifndef EXTRACT_SIMM13_A16_20
+#define EXTRACT_SIMM13_A16_20
+/* mask = 00000000000000000000111111222222.  */
+static long long int
+extract_simm13_a16_20 (unsigned long long insn ATTRIBUTE_UNUSED,
+                      bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  int value = 0;
+
+  value |= ((insn >> 6) & 0x003f) << 1;
+  value |= ((insn >> 0) & 0x003f) << 7;
+
+  /* Extend the sign.  */
+  int signbit = 1 << (13 - 1);
+  value = (value ^ signbit) - signbit;
+
+  return value;
+}
+#endif /* EXTRACT_SIMM13_A16_20 */
+
+
+#ifndef EXTRACT_UIMM8_8_S
+#define EXTRACT_UIMM8_8_S
+/* mask = 0000000011111111.  */
+static long long int
+extract_uimm8_8_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                  bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 0) & 0x00ff) << 0;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM8_8_S */
+
+#ifndef EXTRACT_UIMM6_5_S
+#define EXTRACT_UIMM6_5_S
+/* mask = 0000011111100000.  */
+static long long int
+extract_uimm6_5_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                  bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  value |= ((insn >> 5) & 0x003f) << 0;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM6_5_S */
+
+#ifndef EXTRACT_UIMM6_AXX_
+#define EXTRACT_UIMM6_AXX_
+/* mask = 00000000000000000000000000000000.  */
+static ATTRIBUTE_UNUSED int
+extract_uimm6_axx_ (unsigned long long insn ATTRIBUTE_UNUSED,
+                   bfd_boolean * invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM6_AXX_ */
+
+/* mask  = 0000022000011111.  */
+#ifndef EXTRACT_UIMM9_A32_11_S
+#define EXTRACT_UIMM9_A32_11_S
+ATTRIBUTE_UNUSED static long long int
+extract_uimm9_a32_11_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                        bfd_boolean *invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+  value |= ((insn >> 0) & 0x001f) << 2;
+  value |= ((insn >> 9) & 0x0003) << 7;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM9_A32_11_S */
+
+/* mask  = 0000022222220111.  */
+#ifndef EXTRACT_UIMM10_13_S
+#define EXTRACT_UIMM10_13_S
+ATTRIBUTE_UNUSED static long long int
+extract_uimm10_13_s (unsigned long long insn ATTRIBUTE_UNUSED,
+                     bfd_boolean *invalid ATTRIBUTE_UNUSED)
+{
+  unsigned value = 0;
+  value |= ((insn >> 0) & 0x0007) << 0;
+  value |= ((insn >> 4) & 0x007f) << 3;
+
+  return value;
+}
+#endif /* EXTRACT_UIMM10_13_S */
+
+static long long
+extract_rbb (unsigned long long  insn,
+           bfd_boolean *       invalid)
+{
+  int value = (((insn >> 1) & 0x07) << 3) | ((insn >> 8) & 0x07);
+
+  if (value == 0x3e && invalid)
+    *invalid = TRUE; /* A limm operand, it should be extracted in a
+                       different way.  */
+
+  return value;
+}
+
+/*
+ * The operands table.
+ *
+ * The format of the operands table is:
+ *
+ * BITS SHIFT FLAGS EXTRACT_FUN.
+ */
+const struct arc_operand arc_operands[] = {
+    { 0, 0, 0, 0 },
+#define ARC_OPERAND(NAME, BITS, SHIFT, RELO, FLAGS, FUN)       \
+    { BITS, SHIFT, FLAGS, FUN },
+#include "target/arc/operands-v3.def"
+#undef ARC_OPERAND
+    { 0, 0, 0, 0}
+};
+
+enum arc_operands_map {
+    OPERAND_UNUSED = 0,
+#define ARC_OPERAND(NAME, BITS, SHIFT, RELO, FLAGS, FUN) OPERAND_##NAME,
+#include "target/arc/operands-v3.def"
+#undef ARC_OPERAND
+    OPERAND_LAST
+};
+
+/*
+ * The flag operands table.
+ *
+ * The format of the table is
+ * NAME CODE BITS SHIFT FAVAIL.
+ */
+const struct arc_flag_operand arc_flag_operands[] = {
+    { 0, 0, 0, 0, 0},
+#define ARC_FLAG(NAME, MNEMONIC, CODE, BITS, SHIFT, AVAIL)      \
+    { MNEMONIC, CODE, BITS, SHIFT, AVAIL },
+#include "target/arc/flags-v3.def"
+#undef ARC_FLAG
+    { 0, 0, 0, 0, 0}
+};
+
+enum arc_flags_map {
+    F_NULL = 0,
+#define ARC_FLAG(NAME, MNEMONIC, CODE, BITS, SHIFT, AVAIL) F_##NAME,
+#include "target/arc/flags-v3.def"
+#undef ARC_FLAG
+    F_LAST
+};
+
+/*
+ * Table of the flag classes.
+ *
+ * The format of the table is
+ * CLASS {FLAG_CODE}.
+ */
+const struct arc_flag_class arc_flag_classes[] =
+{
+#define C_EMPTY     0
+  { F_CLASS_NONE, { F_NULL } },
+
+#define C_CC_EQ     (C_EMPTY + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_COND, {F_EQUAL, F_NULL} },
+
+#define C_CC_GE     (C_CC_EQ + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_COND, {F_GE, F_NULL} },
+
+#define C_CC_GT     (C_CC_GE + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_COND, {F_GT, F_NULL} },
+
+#define C_CC_HI     (C_CC_GT + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_COND, {F_HI, F_NULL} },
+
+#define C_CC_HS     (C_CC_HI + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_COND, {F_NOTCARRY, F_NULL} },
+
+#define C_CC_LE     (C_CC_HS + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_COND, {F_LE, F_NULL} },
+
+#define C_CC_LO     (C_CC_LE + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_COND, {F_CARRY, F_NULL} },
+
+#define C_CC_LS     (C_CC_LO + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_COND, {F_LS, F_NULL} },
+
+#define C_CC_LT     (C_CC_LS + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_COND, {F_LT, F_NULL} },
+
+#define C_CC_NE     (C_CC_LT + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_COND, {F_NOTEQUAL, F_NULL} },
+
+#define C_AA_AB     (C_CC_NE + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_WB, {F_AB3, F_NULL} },
+
+#define C_AA_AW     (C_AA_AB + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_WB, {F_AW3, F_NULL} },
+
+#define C_ZZ_D      (C_AA_AW + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_ZZ, {F_SIZED, F_NULL} },
+
+#define C_ZZ_L      (C_ZZ_D + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_ZZ, {F_SIZEL, F_NULL} },
+
+#define C_ZZ_W      (C_ZZ_L + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_ZZ, {F_SIZEW, F_NULL} },
+
+#define C_ZZ_H      (C_ZZ_W + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_ZZ, {F_H1, F_NULL} },
+
+#define C_ZZ_B      (C_ZZ_H + 1)
+  {F_CLASS_IMPLICIT | F_CLASS_ZZ, {F_SIZEB1, F_NULL} },
+
+#define C_CC       (C_ZZ_B + 1)
+  { F_CLASS_OPTIONAL | F_CLASS_EXTEND | F_CLASS_COND,
+    { F_ALWAYS, F_RA, F_EQUAL, F_ZERO, F_NOTEQUAL,
+      F_NOTZERO, F_POZITIVE, F_PL, F_NEGATIVE, F_MINUS,
+      F_CARRY, F_CARRYSET, F_LOWER, F_CARRYCLR,
+      F_NOTCARRY, F_HIGHER, F_OVERFLOWSET, F_OVERFLOW,
+      F_NOTOVERFLOW, F_OVERFLOWCLR, F_GT, F_GE, F_LT,
+      F_LE, F_HI, F_LS, F_PNZ, F_NJ, F_NM, F_NO_T, F_NULL } },
+
+#define C_AA_ADDR3  (C_CC + 1)
+#define C_AA27     (C_CC + 1)
+  { F_CLASS_OPTIONAL | F_CLASS_WB, { F_A3, F_AW3, F_AB3, F_AS3, F_NULL } },
+#define C_AA_ADDR9  (C_AA_ADDR3 + 1)
+#define C_AA21      (C_AA_ADDR3 + 1)
+  { F_CLASS_OPTIONAL | F_CLASS_WB, { F_A9, F_AW9, F_AB9, F_AS9, F_NULL } },
+#define C_AA_ADDR22 (C_AA_ADDR9 + 1)
+#define C_AA8     (C_AA_ADDR9 + 1)
+  { F_CLASS_OPTIONAL | F_CLASS_WB, { F_A22, F_AW22, F_AB22, F_AS22, F_NULL } },
+
+#define C_F        (C_AA_ADDR22 + 1)
+  { F_CLASS_OPTIONAL | F_CLASS_F, { F_FLAG, F_NULL } },
+#define C_FHARD            (C_F + 1)
+  { F_CLASS_OPTIONAL | F_CLASS_F, { F_FFAKE, F_NULL } },
+#define C_AQ       (C_FHARD + 1)
+  { F_CLASS_OPTIONAL, { F_AQ, F_NULL } },
+
+#define C_ATOP      (C_AQ + 1)
+  { F_CLASS_REQUIRED, {F_ATO_ADD, F_ATO_OR, F_ATO_AND, F_ATO_XOR, F_ATO_MINU,
+                      F_ATO_MAXU, F_ATO_MIN, F_ATO_MAX, F_NULL}},
+
+#define C_T        (C_ATOP + 1)
+  { F_CLASS_OPTIONAL, { F_NT, F_T, F_NULL } },
+#define C_D        (C_T + 1)
+  { F_CLASS_OPTIONAL, { F_ND, F_D, F_NULL } },
+#define C_DNZ_D     (C_D + 1)
+  { F_CLASS_OPTIONAL, { F_DNZ_ND, F_DNZ_D, F_NULL } },
+
+#define C_DHARD            (C_DNZ_D + 1)
+  { F_CLASS_OPTIONAL, { F_DFAKE, F_NULL } },
+
+#define C_DI20     (C_DHARD + 1)
+  { F_CLASS_OPTIONAL, { F_DI11, F_NULL }},
+#define C_DI14     (C_DI20 + 1)
+  { F_CLASS_OPTIONAL, { F_DI14, F_NULL }},
+#define C_DI16     (C_DI14 + 1)
+  { F_CLASS_OPTIONAL, { F_DI15, F_NULL }},
+#define C_DI26     (C_DI16 + 1)
+  { F_CLASS_OPTIONAL, { F_DI5, F_NULL }},
+
+#define C_X25      (C_DI26 + 1)
+  { F_CLASS_OPTIONAL | F_CLASS_X, { F_SIGN6, F_NULL }},
+#define C_X15     (C_X25 + 1)
+  { F_CLASS_OPTIONAL | F_CLASS_X, { F_SIGN16, F_NULL }},
+#define C_XHARD           (C_X15 + 1)
+#define C_X       (C_X15 + 1)
+  { F_CLASS_OPTIONAL | F_CLASS_X, { F_SIGNX, F_NULL }},
+
+#define C_ZZ13       (C_X + 1)
+  { F_CLASS_OPTIONAL, { F_SIZEB17, F_SIZEW17, F_H17, F_D17 , F_NULL}},
+#define C_ZZ23       (C_ZZ13 + 1)
+  { F_CLASS_OPTIONAL, { F_SIZEB7, F_SIZEW7, F_H7, F_D7, F_NULL}},
+#define C_ZZ29       (C_ZZ23 + 1)
+  { F_CLASS_OPTIONAL, { F_SIZEB1, F_SIZEW1, F_H1, F_NULL}},
+
+#define C_AS       (C_ZZ29 + 1)
+#define C_AAHARD13  (C_ZZ29 + 1)
+  { F_CLASS_OPTIONAL, { F_ASFAKE, F_NULL}},
+
+#define C_NE       (C_AS + 1)
+  { F_CLASS_REQUIRED, { F_NE, F_NULL}}
+};
+
+/* List with special cases instructions and the applicable flags. */
+const struct arc_flag_special arc_flag_special_cases[] =
+{
+  { "b", { F_ALWAYS, F_RA, F_EQUAL, F_ZERO, F_NOTEQUAL, F_NOTZERO, F_POZITIVE,
+          F_PL, F_NEGATIVE, F_MINUS, F_CARRY, F_CARRYSET, F_LOWER, F_CARRYCLR,
+          F_NOTCARRY, F_HIGHER, F_OVERFLOWSET, F_OVERFLOW, F_NOTOVERFLOW,
+          F_OVERFLOWCLR, F_GT, F_GE, F_LT, F_LE, F_HI, F_LS, F_PNZ, F_NJ, F_NM,
+          F_NO_T, F_NULL } },
+  { "bl", { F_ALWAYS, F_RA, F_EQUAL, F_ZERO, F_NOTEQUAL, F_NOTZERO, F_POZITIVE,
+           F_PL, F_NEGATIVE, F_MINUS, F_CARRY, F_CARRYSET, F_LOWER, F_CARRYCLR,
+           F_NOTCARRY, F_HIGHER, F_OVERFLOWSET, F_OVERFLOW, F_NOTOVERFLOW,
+           F_OVERFLOWCLR, F_GT, F_GE, F_LT, F_LE, F_HI, F_LS, F_PNZ, F_NULL } 
},
+  { "br", { F_ALWAYS, F_RA, F_EQUAL, F_ZERO, F_NOTEQUAL, F_NOTZERO, F_POZITIVE,
+           F_PL, F_NEGATIVE, F_MINUS, F_CARRY, F_CARRYSET, F_LOWER, F_CARRYCLR,
+           F_NOTCARRY, F_HIGHER, F_OVERFLOWSET, F_OVERFLOW, F_NOTOVERFLOW,
+           F_OVERFLOWCLR, F_GT, F_GE, F_LT, F_LE, F_HI, F_LS, F_PNZ, F_NULL } 
},
+  { "j", { F_ALWAYS, F_RA, F_EQUAL, F_ZERO, F_NOTEQUAL, F_NOTZERO, F_POZITIVE,
+          F_PL, F_NEGATIVE, F_MINUS, F_CARRY, F_CARRYSET, F_LOWER, F_CARRYCLR,
+          F_NOTCARRY, F_HIGHER, F_OVERFLOWSET, F_OVERFLOW, F_NOTOVERFLOW,
+          F_OVERFLOWCLR, F_GT, F_GE, F_LT, F_LE, F_HI, F_LS, F_PNZ, F_NULL } },
+  { "jl", { F_ALWAYS, F_RA, F_EQUAL, F_ZERO, F_NOTEQUAL, F_NOTZERO, F_POZITIVE,
+           F_PL, F_NEGATIVE, F_MINUS, F_CARRY, F_CARRYSET, F_LOWER, F_CARRYCLR,
+           F_NOTCARRY, F_HIGHER, F_OVERFLOWSET, F_OVERFLOW, F_NOTOVERFLOW,
+           F_OVERFLOWCLR, F_GT, F_GE, F_LT, F_LE, F_HI, F_LS, F_PNZ, F_NULL } 
},
+  { "lp", { F_ALWAYS, F_RA, F_EQUAL, F_ZERO, F_NOTEQUAL, F_NOTZERO, F_POZITIVE,
+           F_PL, F_NEGATIVE, F_MINUS, F_CARRY, F_CARRYSET, F_LOWER, F_CARRYCLR,
+           F_NOTCARRY, F_HIGHER, F_OVERFLOWSET, F_OVERFLOW, F_NOTOVERFLOW,
+           F_OVERFLOWCLR, F_GT, F_GE, F_LT, F_LE, F_HI, F_LS, F_PNZ, F_NULL } 
},
+  { "set", { F_ALWAYS, F_RA, F_EQUAL, F_ZERO, F_NOTEQUAL, F_NOTZERO, 
F_POZITIVE,
+            F_PL, F_NEGATIVE, F_MINUS, F_CARRY, F_CARRYSET, F_LOWER, 
F_CARRYCLR,
+            F_NOTCARRY, F_HIGHER, F_OVERFLOWSET, F_OVERFLOW, F_NOTOVERFLOW,
+            F_OVERFLOWCLR, F_GT, F_GE, F_LT, F_LE, F_HI, F_LS, F_PNZ, F_NULL } 
},
+  { "ld", { F_SIZEB17, F_SIZEW17, F_H17, F_NULL } },
+  { "st", { F_SIZEB1, F_SIZEW1, F_H1, F_NULL } }
+};
+
+const unsigned arc_num_flag_special = ARRAY_SIZE (arc_flag_special_cases);
+
+/*
+ * The opcode table.
+ *
+ * The format of the opcode table is:
+ *
+ * NAME OPCODE MASK CPU CLASS SUBCLASS { OPERANDS } { FLAGS }.
+ *
+ * The table is organised such that, where possible, all instructions with
+ * the same mnemonic are together in a block. When the assembler searches
+ * for a suitable instruction the entries are checked in table order, so
+ * more specific, or specialised cases should appear earlier in the table.
+ *
+ * As an example, consider two instructions 'add a,b,u6' and 'add
+ * a,b,limm'. The first takes a 6-bit immediate that is encoded within the
+ * 32-bit instruction, while the second takes a 32-bit immediate that is
+ * encoded in a follow-on 32-bit, making the total instruction length
+ * 64-bits. In this case the u6 variant must appear first in the table, as
+ * all u6 immediates could also be encoded using the 'limm' extension,
+ * however, we want to use the shorter instruction wherever possible.
+ *
+ * It is possible though to split instructions with the same mnemonic into
+ * multiple groups. However, the instructions are still checked in table
+ * order, even across groups. The only time that instructions with the
+ * same mnemonic should be split into different groups is when different
+ * variants of the instruction appear in different architectures, in which
+ * case, grouping all instructions from a particular architecture together
+ * might be preferable to merging the instruction into the main instruction
+ * table.
+ *
+ * An example of this split instruction groups can be found with the 'sync'
+ * instruction. The core arc architecture provides a 'sync' instruction,
+ * while the nps instruction set extension provides 'sync.rd' and
+ * 'sync.wr'. The rd/wr flags are instruction flags, not part of the
+ * mnemonic, so we end up with two groups for the sync instruction, the
+ * first within the core arc instruction table, and the second within the
+ * nps extension instructions.
+ */
+const struct arc_opcode arc_opcodes[] =
+{
+#define FASTMATH NONE
+#include "opcodes-v3.def"
+    { NULL, 0, 0, 0, 0, 0, { 0 }, { 0 } }
+#undef FASTMATH
+};
+
+/* Return length of an opcode in bytes. */
+static uint8_t arc_opcode_len(const struct arc_opcode *opcode)
+{
+    if (opcode->mask < 0x10000ull) {
+        return 2;
+    }
+
+    if (opcode->mask < 0x100000000ull) {
+        return 4;
+    }
+
+    if (opcode->mask < 0x1000000000000ull) {
+        return 6;
+    }
+
+    return 8;
+}
+
+/*
+ * Calculate the instruction length for an instruction starting with
+ * MSB and LSB, the most and least significant byte.  The ISA_MASK is
+ * used to filter the instructions considered to only those that are
+ * part of the current architecture.
+ *
+ * The instruction lengths are calculated from the ARC_OPCODE table,
+ * and cached for later use.
+ */
+unsigned int arc_insn_length(uint16_t insn, uint16_t cpu_type)
+{
+    uint8_t major_opcode;
+    uint8_t msb;
+
+    msb = (uint8_t)(insn >> 8);
+    major_opcode = msb >> 3;
+
+    switch (cpu_type) {
+      case ARC_OPCODE_V3_ARC64:
+          if(major_opcode == 0x0b)
+            return 4;
+          return (major_opcode > 0x7) ? 2 : 4;
+          break;
+
+      default:
+        g_assert_not_reached();
+    }
+}
+
+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 BBIT0:
+    case BBIT1:
+    case BI:
+    case BIH:
+    case BRCC:
+    case EI:
+    case JLI:
+    case JUMP:
+    case LOOP:
+      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 LOAD:
+    case STORE:
+    case MEMORY:
+    case ENTER:
+    case PUSH:
+    case POP:
+      insn_type = dis_dref;
+      break;
+    case LEAVE:
+      insn_type = dis_branch;
+      break;
+    default:
+      insn_type = dis_nonbranch;
+      break;
+    }
+
+  return insn_type;
+}
+
+#define REG_PCL    63
+#define REG_LIMM   62
+#define REG_LIMM_S 30
+#define REG_U32    62
+#define REG_S32    60
+
+static const struct arc_opcode *find_format(insn_t *pinsn,
+                                            uint64_t insn,
+                                            uint8_t insn_len,
+                                            uint32_t isa_mask)
+{
+    uint32_t i = 0;
+    const struct arc_opcode *opcode = NULL;
+    const uint8_t *opidx;
+    const uint8_t *flgidx;
+    bool has_limm_signed = false;
+    bool has_limm_unsigned = false;
+
+    const struct arc_opcode *ret = NULL;
+
+    do {
+        bool invalid = false;
+        uint32_t noperands = 0;
+
+        opcode = &arc_opcodes[i++];
+
+        if (!(opcode->cpu & isa_mask)) {
+            continue;
+        }
+
+        if (arc_opcode_len(opcode) != (int) insn_len) {
+            continue;
+        }
+
+        if ((insn & opcode->mask) != opcode->opcode) {
+            continue;
+        }
+
+        if(ret != NULL)
+          continue;
+
+        memset(pinsn, 0, sizeof (*pinsn));
+
+        has_limm_signed = false;
+        has_limm_unsigned = false;
+
+        /* Possible candidate, check the operands. */
+        for (opidx = opcode->operands; *opidx; ++opidx) {
+            int value, slimmind;
+            const struct arc_operand *operand = &arc_operands[*opidx];
+
+            if (operand->flags & ARC_OPERAND_FAKE) {
+                continue;
+            }
+
+            if (operand->extract) {
+                value = (*operand->extract)(insn, &invalid);
+            }
+            else {
+                value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
+            }
+
+            /* Check for (short) LIMM indicator.  If it is there, then
+               make sure we pick the right format.  */
+            slimmind = (isa_mask & (ARC_OPCODE_ARCV2 | ARC_OPCODE_V3_ARC64)) ?
+              REG_LIMM_S : REG_LIMM;
+            if (operand->flags & ARC_OPERAND_IR
+                && !(operand->flags & ARC_OPERAND_LIMM))
+              if ((value == REG_LIMM && insn_len == 4)
+                  || (value == slimmind && insn_len == 2)
+                  || (isa_mask & ARC_OPCODE_V3_ARC64
+                      && (value == REG_S32) && (insn_len == 4)))
+                {
+                  invalid = TRUE;
+                  break;
+                }
+
+
+
+            if (operand->flags & ARC_OPERAND_LIMM &&
+                !(operand->flags & ARC_OPERAND_DUPLICATE)) {
+                if(operand->flags & ARC_OPERAND_SIGNED)
+                  has_limm_signed = true;
+                else
+                  has_limm_unsigned = true;
+            }
+
+            pinsn->operands[noperands].value = value;
+            pinsn->operands[noperands].type = operand->flags;
+            noperands += 1;
+            pinsn->n_ops = noperands;
+        }
+
+        /* Preselect the insn class.  */
+        enum dis_insn_type insn_type = arc_opcode_to_insn_type (opcode);
+
+        /* Check the flags. */
+        for (flgidx = opcode->flags; *flgidx; ++flgidx) {
+            /* Get a valid flag class. */
+            const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
+            const unsigned *flgopridx;
+            bool foundA = false, foundB = false;
+            unsigned int value;
+
+            /* FIXME! Add check for EXTENSION flags. */
+
+            for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx) {
+                const struct arc_flag_operand *flg_operand =
+                &arc_flag_operands[*flgopridx];
+
+                /* Check for the implicit flags. */
+                if (cl_flags->flag_class & F_CLASS_IMPLICIT) {
+                    if (cl_flags->flag_class & F_CLASS_COND) {
+                        pinsn->cc = flg_operand->code;
+                    }
+                    else if (cl_flags->flag_class & F_CLASS_WB) {
+                        pinsn->aa = flg_operand->code;
+                    }
+                    else if (cl_flags->flag_class & F_CLASS_ZZ) {
+                        pinsn->zz_as_data_size = flg_operand->code;
+                    }
+                    continue;
+                }
+
+                value = (insn >> flg_operand->shift) &
+                        ((1 << flg_operand->bits) - 1);
+                if (value == flg_operand->code) {
+                       if (!special_flag_p (opcode->name, flg_operand->name))
+                    { }
+                    else if (insn_type == dis_dref)
+                    {
+                        switch (flg_operand->name[0]) {
+                        case 'b':
+                            pinsn->zz_as_data_size = 1;
+                            break;
+                        case 'h':
+                        case 'w':
+                            pinsn->zz_as_data_size = 2;
+                            break;
+                        default:
+                            pinsn->zz_as_data_size = 0;
+                            break;
+                        }
+                    }
+
+                    /*
+                     * TODO: This has a problem: instruction "b label"
+                     * sets this to true.
+                     */
+                    if (cl_flags->flag_class & F_CLASS_D) {
+                        pinsn->d = value ? true : false;
+                        if (cl_flags->flags[0] == F_DFAKE) {
+                            pinsn->d = true;
+                        }
+                    }
+                       if (flg_operand->name[0] == 'd'
+                               && flg_operand->name[1] == 0)
+                               pinsn->d = true;
+
+                    if (cl_flags->flag_class & F_CLASS_COND) {
+                        pinsn->cc = value;
+                    }
+
+                    if (cl_flags->flag_class & F_CLASS_WB) {
+                        pinsn->aa = value;
+                    }
+
+                    if (cl_flags->flag_class & F_CLASS_F) {
+                        pinsn->f = true;
+                    }
+
+                    if (cl_flags->flag_class & F_CLASS_DI) {
+                        pinsn->di = true;
+                    }
+
+                    if (cl_flags->flag_class & F_CLASS_X) {
+                        pinsn->x = true;
+                    }
+
+                    foundA = true;
+                }
+                if (value) {
+                    foundB = true;
+                }
+            }
+
+            if (!foundA && foundB) {
+                invalid = TRUE;
+                break;
+            }
+        }
+
+        if (invalid) {
+            continue;
+        }
+
+        /* The instruction is valid. */
+        pinsn->signed_limm_p = has_limm_signed;
+        pinsn->unsigned_limm_p = has_limm_unsigned;
+        pinsn->class = (uint32_t) opcode->insn_class;
+
+        /*
+         * FIXME: here add extra info about the instruction
+         * e.g. delay slot, data size, write back, etc.
+         */
+        if(ret == NULL)
+            ret = opcode;
+
+    } while (opcode->mask);
+
+    if(ret != NULL)
+        return ret;
+
+    memset(pinsn, 0, sizeof (*pinsn));
+    return NULL;
+}
+
+/* Helper to be used by the disassembler. */
+const struct arc_opcode *arc_find_format(insn_t *insnd,
+                                         uint64_t insn,
+                                         uint8_t insn_len,
+                                         uint32_t isa_mask)
+{
+    memset(insnd, 0, sizeof (*insnd));
+    return find_format(insnd, insn, insn_len, isa_mask);
+}
+
+
+
+/*-*-indent-tabs-mode:nil;tab-width:4;indent-line-function:'insert-tab'-*-*/
+/* vim: set ts=4 sw=4 et: */
diff --git a/target/arc/decoder-v3.h b/target/arc/decoder-v3.h
new file mode 100644
index 0000000000..7131218f35
--- /dev/null
+++ b/target/arc/decoder-v3.h
@@ -0,0 +1,322 @@
+/* Decoder for the ARC.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   You should have received a copy of the GNU General Public License
+   along with GAS or GDB; see the file COPYING3.  If not, write to
+   the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
+
+#ifndef ARC_DECODER_V3_H
+#define ARC_DECODER_V3_H
+
+#include "arc-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MAX_INSN_ARGS
+#define MAX_INSN_ARGS       16
+#endif
+
+#ifndef MAX_INSN_FLGS
+#define MAX_INSN_FLGS       4
+#endif
+
+/* Instruction Class.  */
+typedef enum {
+    NADA = 0,
+    ARC_ACL,
+    ARITH,
+    AUXREG,
+    BBIT0,
+    BBIT1,
+    BI,
+    BIH,
+    BITOP,
+    BITSTREAM,
+    BMU,
+    BRANCH,
+    BRCC,
+    CONTROL,
+    DIVREM,
+    DPI,
+    DSP,
+    EI,
+    ENTER,
+    ARC_FLOAT,
+    INVALID,
+    JLI,
+    JUMP,
+    KERNEL,
+    LEAVE,
+    LOAD,
+    LOGICAL,
+    LOOP,
+    MEMORY,
+    MOVE,
+    MPY,
+    NET,
+    PROTOCOL_DECODE,
+    PMU,
+    POP,
+    PUSH,
+    SJLI,
+    STORE,
+    SUB,
+    XY
+} insn_class_t;
+
+/* Instruction Subclass.  */
+typedef enum {
+    NONE     = 0,
+    CVT      = (1U << 1),
+    BTSCN    = (1U << 2),
+    CD       = (1U << 3),
+    CD1      = CD,
+    CD2      = CD,
+    COND     = (1U << 4),
+    DIV      = (1U << 5),
+    DP       = (1U << 6),
+    DPA      = (1U << 7),
+    DPX      = (1U << 8),
+    MPY1E    = (1U << 9),
+    MPY6E    = (1U << 10),
+    MPY7E    = (1U << 11),
+    MPY8E    = (1U << 12),
+    MPY9E    = (1U << 13),
+    QUARKSE1 = (1U << 15),
+    QUARKSE2 = (1U << 16),
+    SHFT1    = (1U << 17),
+    SHFT2    = (1U << 18),
+    SWAP     = (1U << 19),
+    SP       = (1U << 20),
+    SPX      = (1U << 21)
+} insn_subclass_t;
+
+/* Flags class.  */
+typedef enum {
+    F_CLASS_NONE = 0,
+
+    /*
+     * At most one flag from the set of flags can appear in the
+     * instruction.
+     */
+    F_CLASS_OPTIONAL = (1 << 0),
+
+  /* Exactly one from from the set of flags must appear in the
+     instruction.  */
+  F_CLASS_REQUIRED = (1 << 1),
+
+  /* The conditional code can be extended over the standard variants
+     via .extCondCode pseudo-op.  */
+  F_CLASS_EXTEND = (1 << 2),
+
+  /* Condition code flag.  */
+  F_CLASS_COND = (1 << 3),
+
+  /* Write back mode.  */
+  F_CLASS_WB = (1 << 4),
+
+  /* Data size.  */
+  F_CLASS_ZZ = (1 << 5),
+
+  /* Implicit flag.  */
+  F_CLASS_IMPLICIT = (1 << 6),
+
+  F_CLASS_F = (1 << 7),
+
+  F_CLASS_DI = (1 << 8),
+
+  F_CLASS_X = (1 << 9),
+  F_CLASS_D = (1 << 10),
+
+} flag_class_t;
+
+/* The opcode table is an array of struct arc_opcode.  */
+struct arc_opcode {
+    /* The opcode name.  */
+    const char *name;
+
+  /* The opcode itself.  Those bits which will be filled in with
+     operands are zeroes.  */
+    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 long long mask;
+
+  /* One bit flags for the opcode.  These are primarily used to
+     indicate specific processors and environments support the
+     instructions.  The defined values are listed below.  */
+    unsigned cpu;
+
+  /* The instruction class.  This is used by gdb.  */
+    insn_class_t insn_class;
+
+  /* The instruction subclass.  */
+    insn_subclass_t subclass;
+
+  /* An array of operand codes.  Each code is an index into the
+     operand table.  They appear in the order which the operands must
+     appear in assembly code, and are terminated by a zero.  */
+    unsigned char operands[MAX_INSN_ARGS + 1];
+
+  /* An array of flag codes.  Each code is an index into the flag
+     table.  They appear in the order which the flags must appear in
+     assembly code, and are terminated by a zero.  */
+    unsigned char flags[MAX_INSN_FLGS + 1];
+};
+
+/* The operands table is an array of struct arc_operand.  */
+struct arc_operand {
+  /* The number of bits in the operand.  */
+    unsigned int bits;
+
+  /* How far the operand is left shifted in the instruction.  */
+    unsigned int shift;
+
+  /* One bit syntax flags.  */
+    unsigned int flags;
+
+  /* Extraction function.  This is used by the disassembler.  To
+     extract this operand type from an instruction, check this field.
+
+     If it is NULL, compute
+        op = ((i) >> o->shift) & ((1 << o->bits) - 1);
+        if ((o->flags & ARC_OPERAND_SIGNED) != 0
+            && (op & (1 << (o->bits - 1))) != 0)
+          op -= 1 << o->bits;
+     (i is the instruction, o is a pointer to this structure, and op
+     is the result; this assumes twos complement arithmetic).
+
+     If this field is not NULL, then simply call it with the
+     instruction value.         It will return the value of the operand.  If
+     the INVALID argument is not NULL, *INVALID will be set to
+     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.  */
+    long long int (*extract) (unsigned long long instruction,
+                              bool *invalid);
+};
+
+extern const struct arc_operand arc_operands[];
+
+/* Values defined for the flags field of a struct arc_operand.  */
+
+/*
+ * This operand does not actually exist in the assembler input.  This
+ * is used to support extended mnemonics, for which two operands fields
+ * are identical.  The assembler should call the insert function with
+ * any op value.  The disassembler should call the extract function,
+ * ignore the return value, and check the value placed in the invalid
+ * argument.
+ */
+#define ARC_OPERAND_FAKE       0x0001
+
+/* This operand names an integer register.  */
+#define ARC_OPERAND_IR         0x0002
+
+/* This operand takes signed values.  */
+#define ARC_OPERAND_SIGNED     0x0004
+
+/* This operand takes unsigned values.  This exists primarily so that
+   a flags value of 0 can be treated as end-of-arguments.  */
+#define ARC_OPERAND_UNSIGNED   0x0008
+
+/* This operand takes long immediate values.  */
+#define ARC_OPERAND_LIMM       0x0010
+
+/* This operand is identical like the previous one.  */
+#define ARC_OPERAND_DUPLICATE   0x0020
+
+/* This operand is PC relative.  Used for internal relocs.  */
+#define ARC_OPERAND_PCREL       0x0040
+
+/* This operand is truncated.  The truncation is done accordingly to
+   operand alignment attribute.  */
+#define ARC_OPERAND_TRUNCATE    0x0080
+
+/* This operand is 16bit aligned.  */
+#define ARC_OPERAND_ALIGNED16   0x0100
+
+/* This operand is 32bit aligned.  */
+#define ARC_OPERAND_ALIGNED32   0x0200
+
+/* This operand can be ignored by matching process if it is not
+   present.  */
+#define ARC_OPERAND_IGNORE      0x0400
+
+/* Don't check the range when matching.         */
+#define ARC_OPERAND_NCHK       0x0800
+
+/* Mark the braket possition.  */
+#define ARC_OPERAND_BRAKET      0x1000
+
+/* Mask for selecting the type for typecheck purposes.  */
+#define ARC_OPERAND_TYPECHECK_MASK              \
+  (ARC_OPERAND_IR                               \
+   | ARC_OPERAND_LIMM     | ARC_OPERAND_SIGNED  \
+   | ARC_OPERAND_UNSIGNED | ARC_OPERAND_BRAKET)
+
+/* Macro to determine if an operand is a fake operand.  */
+#define ARC_OPERAND_IS_FAKE(op)                     \
+  ((operand->flags & ARC_OPERAND_FAKE)              \
+   && !(operand->flags & ARC_OPERAND_BRAKET))
+
+/* The flags structure.  */
+struct arc_flag_operand
+{
+  /* The flag name.  */
+  const char *name;
+
+  /* The flag code.  */
+  unsigned code;
+
+  /* The number of bits in the operand.  */
+  unsigned int bits;
+
+  /* How far the operand is left shifted in the instruction.  */
+  unsigned int shift;
+
+  /* Available for disassembler.  */
+  unsigned char favail;
+};
+
+extern const struct arc_flag_operand arc_flag_operands[];
+
+/* The flag's class structure.  */
+struct arc_flag_class
+{
+  /* Flag class.  */
+  flag_class_t flag_class;
+
+  /* List of valid flags (codes).  */
+  unsigned flags[256];
+};
+
+extern const struct arc_flag_class arc_flag_classes[];
+
+/* Structure for special cases.  */
+struct arc_flag_special
+{
+  /* Name of special case instruction.  */
+  const char *name;
+
+  /* List of flags applicable for special case instruction.  */
+  unsigned flags[32];
+};
+
+extern const struct arc_flag_special arc_flag_special_cases[];
+extern const unsigned arc_num_flag_special;
+
+const struct arc_opcode *arc_find_format (insn_t*, uint64_t, uint8_t, 
uint32_t);
+unsigned int arc_insn_length (uint16_t, uint16_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ARC_DECODER_V3_H */
diff --git a/target/arc/flags-v3.def b/target/arc/flags-v3.def
new file mode 100644
index 0000000000..0c04286dea
--- /dev/null
+++ b/target/arc/flags-v3.def
@@ -0,0 +1,103 @@
+/*
+ * QEMU ARCv3 flags
+ *
+ * Copyright (c) 2020 Synopsys, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+ARC_FLAG(ALWAYS  , "al", 0, 0, 0, 0)
+ARC_FLAG(RA, "ra", 0, 0, 0, 0)
+ARC_FLAG(EQUAL, "eq", 1, 5, 0, 1)
+ARC_FLAG(ZERO, "z",  1, 5, 0, 0)
+ARC_FLAG(NOTEQUAL, "ne", 2, 5, 0, 1)
+ARC_FLAG(NOTZERO , "nz", 2, 5, 0, 0)
+ARC_FLAG(POZITIVE, "p",  3, 5, 0, 1)
+ARC_FLAG(PL, "pl", 3, 5, 0, 0)
+ARC_FLAG(NEGATIVE, "n",  4, 5, 0, 1)
+ARC_FLAG(MINUS, "mi", 4, 5, 0, 0)
+ARC_FLAG(CARRY, "c",  5, 5, 0, 1)
+ARC_FLAG(CARRYSET, "cs", 5, 5, 0, 0)
+ARC_FLAG(LOWER, "lo", 5, 5, 0, 0)
+ARC_FLAG(CARRYCLR, "cc", 6, 5, 0, 0)
+ARC_FLAG(NOTCARRY, "nc", 6, 5, 0, 1)
+ARC_FLAG(HIGHER , "hs", 6, 5, 0, 0)
+ARC_FLAG(OVERFLOWSET, "vs", 7, 5, 0, 0)
+ARC_FLAG(OVERFLOW, "v",  7, 5, 0, 1)
+ARC_FLAG(NOTOVERFLOW, "nv", 8, 5, 0, 1)
+ARC_FLAG(OVERFLOWCLR, "vc", 8, 5, 0, 0)
+ARC_FLAG(GT, "gt", 9, 5, 0, 1)
+ARC_FLAG(GE, "ge", 10, 5, 0, 1)
+ARC_FLAG(LT, "lt", 11, 5, 0, 1)
+ARC_FLAG(LE, "le", 12, 5, 0, 1)
+ARC_FLAG(HI, "hi", 13, 5, 0, 1)
+ARC_FLAG(LS, "ls", 14, 5, 0, 1)
+ARC_FLAG(PNZ, "pnz", 15, 5, 0, 1)
+ARC_FLAG(NJ, "nj", 21, 5, 0, 1)
+ARC_FLAG(NM, "nm", 23, 5, 0, 1)
+ARC_FLAG(NO_T, "nt", 24, 5, 0, 1)
+ARC_FLAG(FLAG   , "f",  1, 1, 15, 1)
+ARC_FLAG(FFAKE  , "f",  0, 0, 0, 1)
+ARC_FLAG(AQ     , "aq",  1, 1, 15, 1)
+ARC_FLAG(RL     , "rl",  1, 1, 15, 1)
+ARC_FLAG(ATO_ADD    , "add", 0, 3, 0, 1)
+ARC_FLAG(ATO_OR    , "or", 1, 3, 0, 1)
+ARC_FLAG(ATO_AND   , "and", 2, 3, 0, 1)
+ARC_FLAG(ATO_XOR   , "xor", 3, 3, 0, 1)
+ARC_FLAG(ATO_MINU  , "minu", 4, 3, 0, 1)
+ARC_FLAG(ATO_MAXU  , "maxu", 5, 3, 0, 1)
+ARC_FLAG(ATO_MIN   , "min", 6, 3, 0, 1)
+ARC_FLAG(ATO_MAX    , "max", 7, 3, 0, 1)
+ARC_FLAG(ND, "nd", 0, 1, 5, 0)
+ARC_FLAG(D, "d",  1, 1, 5, 1)
+ARC_FLAG(DFAKE, "d",  0, 0, 0, 1)
+ARC_FLAG(DNZ_ND , "nd", 0, 1, 16, 0)
+ARC_FLAG(DNZ_D, "d",  1, 1, 16, 1)
+ARC_FLAG(SIZEB1 , "b", 1, 2, 1, 1)
+ARC_FLAG(SIZEB7 , "b", 1, 2, 7, 1)
+ARC_FLAG(SIZEB17, "b", 1, 2, 17, 1)
+ARC_FLAG(SIZEW1 , "w", 2, 2, 1, 0)
+ARC_FLAG(SIZEW7 , "w", 2, 2, 7, 0)
+ARC_FLAG(SIZEW17, "w", 2, 2, 17, 0)
+ARC_FLAG(SIGN6 , "x", 1, 1, 6, 1)
+ARC_FLAG(SIGN16, "x", 1, 1, 16, 1)
+ARC_FLAG(SIGNX , "x", 0, 0, 0, 1)
+ARC_FLAG(A3     , "a", 1, 2, 3, 0)
+ARC_FLAG(A9     , "a", 1, 2, 9, 0)
+ARC_FLAG(A22    , "a", 1, 2, 22, 0)
+ARC_FLAG(AW3    , "aw", 1, 2, 3, 1)
+ARC_FLAG(AW9    , "aw", 1, 2, 9, 1)
+ARC_FLAG(AW22   , "aw", 1, 2, 22, 1)
+ARC_FLAG(AB3    , "ab", 2, 2, 3, 1)
+ARC_FLAG(AB9    , "ab", 2, 2, 9, 1)
+ARC_FLAG(AB22   , "ab", 2, 2, 22, 1)
+ARC_FLAG(AS3    , "as", 3, 2, 3, 1)
+ARC_FLAG(AS9    , "as", 3, 2, 9, 1)
+ARC_FLAG(AS22   , "as", 3, 2, 22, 1)
+ARC_FLAG(ASFAKE , "as", 0, 0, 0, 1)
+ARC_FLAG(DI5, "di", 1, 1, 5, 1)
+ARC_FLAG(DI11, "di", 1, 1, 11, 1)
+ARC_FLAG(DI14, "di", 1, 1, 14, 1)
+ARC_FLAG(DI15, "di", 1, 1, 15, 1)
+ARC_FLAG(NT, "nt", 0, 1, 3, 1)
+ARC_FLAG(T, "t", 1, 1, 3, 1)
+ARC_FLAG(H1, "h", 2, 2, 1, 1)
+ARC_FLAG(H7, "h", 2, 2, 7, 1)
+ARC_FLAG(H17, "h", 2, 2, 17, 1)
+ARC_FLAG(D1, "d", 3, 2, 1, 1)
+ARC_FLAG(D7, "d", 3, 2, 7, 1)
+ARC_FLAG(D17, "d", 3, 2, 17, 1)
+ARC_FLAG(SIZED, "dd", 3, 0, 0, 0)
+ARC_FLAG(SIZEL, "dl", 3, 0, 0, 0)
+ARC_FLAG(SIZEW, "xx", 0, 0, 0, 0)
+ARC_FLAG(NE, "ne", 0, 0, 0, 1)
diff --git a/target/arc/operands-v3.def b/target/arc/operands-v3.def
new file mode 100644
index 0000000000..df9c636bc4
--- /dev/null
+++ b/target/arc/operands-v3.def
@@ -0,0 +1,133 @@
+/*
+ * QEMU ARCv3 operands
+ *
+ * Copyright (c) 2020 Synopsys, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+ARC_OPERAND(IGNORED, 0, 0, 0, ARC_OPERAND_IGNORE | ARC_OPERAND_UNSIGNED | 
ARC_OPERAND_NCHK, 0)
+ARC_OPERAND(RA, 6, 0, 0, ARC_OPERAND_IR, 0)
+ARC_OPERAND(RA_CHK, 6, 0, 0, ARC_OPERAND_IR, 0)
+ARC_OPERAND(RB, 6, 12, 0, ARC_OPERAND_IR, extract_rb)
+ARC_OPERAND(RB_CHK, 6, 12, 0, ARC_OPERAND_IR, extract_rb)
+ARC_OPERAND(RBB_S, 6, 12, 0, ARC_OPERAND_IR, extract_rbb)
+ARC_OPERAND(RC, 6, 6, 0, ARC_OPERAND_IR, 0)
+ARC_OPERAND(RC_CHK, 6, 6, 0, ARC_OPERAND_IR, 0)
+ARC_OPERAND(RBdup, 6, 12, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE, 
extract_rb)
+ARC_OPERAND(RAD, 6, 0, 0, ARC_OPERAND_IR | ARC_OPERAND_TRUNCATE, 0)
+ARC_OPERAND(RAD_CHK, 6, 0, 0, ARC_OPERAND_IR | ARC_OPERAND_TRUNCATE, 0)
+ARC_OPERAND(RCD, 6, 6, 0, ARC_OPERAND_IR | ARC_OPERAND_TRUNCATE, 0)
+ARC_OPERAND(RA16, 4, 0, 0, ARC_OPERAND_IR, extract_ras)
+ARC_OPERAND(RA_S, 4, 0, 0, ARC_OPERAND_IR, extract_ras)
+ARC_OPERAND(RB16, 4, 8, 0, ARC_OPERAND_IR, extract_rbs)
+ARC_OPERAND(RB_S, 4, 8, 0, ARC_OPERAND_IR, extract_rbs)
+ARC_OPERAND(RB16dup, 4, 8, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE, 
extract_rbs)
+ARC_OPERAND(RB_Sdup, 4, 8, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE, 
extract_rbs)
+ARC_OPERAND(RC16, 4, 5, 0, ARC_OPERAND_IR, extract_rcs)
+ARC_OPERAND(RC_S, 4, 5, 0, ARC_OPERAND_IR, extract_rcs)
+ARC_OPERAND(R6H, 6, 5, 0, ARC_OPERAND_IR, extract_rhv1)
+ARC_OPERAND(R5H, 5, 5, 0, ARC_OPERAND_IR, extract_rhv2)
+ARC_OPERAND(RH_S, 5, 5, 0, ARC_OPERAND_IR, extract_rhv2)
+ARC_OPERAND(R5Hdup, 5, 5, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE, 
extract_rhv2)
+ARC_OPERAND(RH_Sdup, 5, 5, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE, 
extract_rhv2)
+ARC_OPERAND(RG, 5, 5, 0, ARC_OPERAND_IR, extract_g_s)
+ARC_OPERAND(G_S, 5, 5, 0, ARC_OPERAND_IR, extract_g_s)
+ARC_OPERAND(R0, 0, 0, 0, ARC_OPERAND_IR, extract_r0)
+ARC_OPERAND(R0_S, 0, 0, 0, ARC_OPERAND_IR, extract_r0)
+ARC_OPERAND(R1, 1, 0, 0, ARC_OPERAND_IR, extract_r1)
+ARC_OPERAND(R1_S, 1, 0, 0, ARC_OPERAND_IR, extract_r1)
+ARC_OPERAND(R2, 2, 0, 0, ARC_OPERAND_IR, extract_r2)
+ARC_OPERAND(R2_S, 2, 0, 0, ARC_OPERAND_IR, extract_r2)
+ARC_OPERAND(R3, 2, 0, 0, ARC_OPERAND_IR, extract_r3)
+ARC_OPERAND(R3_S, 2, 0, 0, ARC_OPERAND_IR, extract_r3)
+ARC_OPERAND(RSP, 5, 0, 0, ARC_OPERAND_IR, extract_sp)
+ARC_OPERAND(SP_S, 5, 0, 0, ARC_OPERAND_IR, extract_sp)
+ARC_OPERAND(SPdup, 5, 0, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE, extract_sp)
+ARC_OPERAND(SP_Sdup, 5, 0, 0, ARC_OPERAND_IR | ARC_OPERAND_DUPLICATE, 
extract_sp)
+ARC_OPERAND(GP, 5, 0, 0, ARC_OPERAND_IR, extract_gp)
+ARC_OPERAND(GP_S, 5, 0, 0, ARC_OPERAND_IR, extract_gp)
+ARC_OPERAND(PCL_S, 1, 0, 0, ARC_OPERAND_IR | ARC_OPERAND_NCHK, extract_pcl)
+ARC_OPERAND(BLINK, 5, 0, 0, ARC_OPERAND_IR, extract_blink)
+ARC_OPERAND(BLINK_S, 5, 0, 0, ARC_OPERAND_IR, extract_blink)
+ARC_OPERAND(ILINK1, 5, 0, 0, ARC_OPERAND_IR, extract_ilink1)
+ARC_OPERAND(ILINK2, 5, 0, 0, ARC_OPERAND_IR, extract_ilink2)
+ARC_OPERAND(LIMM, 32, 0, 0, ARC_OPERAND_LIMM, 0)
+ARC_OPERAND(LIMM_S, 32, 0, 0, ARC_OPERAND_LIMM, 0)
+ARC_OPERAND(LO32, 32, 0, 0, ARC_OPERAND_LIMM, 0)
+ARC_OPERAND(HI32, 32, 0, 0, ARC_OPERAND_LIMM, 0)
+ARC_OPERAND(XIMM_S, 32, 0, 0, ARC_OPERAND_LIMM | ARC_OPERAND_SIGNED, 0)
+ARC_OPERAND(XIMM, 32, 0, 0, ARC_OPERAND_LIMM | ARC_OPERAND_SIGNED, 0)
+ARC_OPERAND(LIMMdup, 32, 0, 0, ARC_OPERAND_LIMM | ARC_OPERAND_DUPLICATE, 0)
+ARC_OPERAND(XIMMdup, 32, 0, 0, ARC_OPERAND_LIMM | ARC_OPERAND_DUPLICATE | 
ARC_OPERAND_SIGNED, 0)
+ARC_OPERAND(ZA, 0, 0, 0, ARC_OPERAND_UNSIGNED, 0)
+ARC_OPERAND(ZB, 0, 0, 0, ARC_OPERAND_UNSIGNED, 0)
+ARC_OPERAND(ZA_S, 0, 0, 0, ARC_OPERAND_UNSIGNED, 0)
+ARC_OPERAND(ZB_S, 0, 0, 0, ARC_OPERAND_UNSIGNED, 0)
+ARC_OPERAND(ZC_S, 0, 0, 0, ARC_OPERAND_UNSIGNED, 0)
+ARC_OPERAND(RRANGE_EL, 4, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_NCHK | 
ARC_OPERAND_TRUNCATE, extract_rrange)
+ARC_OPERAND(R13_EL, 1, 0, 0, ARC_OPERAND_IR | ARC_OPERAND_IGNORE | 
ARC_OPERAND_NCHK, extract_rrange)
+ARC_OPERAND(FP_EL, 1, 0, 0, ARC_OPERAND_IR | ARC_OPERAND_IGNORE | 
ARC_OPERAND_NCHK, extract_fpel)
+ARC_OPERAND(BLINK_EL, 1, 0, 0, ARC_OPERAND_IR | ARC_OPERAND_IGNORE | 
ARC_OPERAND_NCHK, extract_blinkel)
+ARC_OPERAND(PCL_EL, 1, 0, 0, ARC_OPERAND_IR | ARC_OPERAND_IGNORE | 
ARC_OPERAND_NCHK, extract_pclel)
+ARC_OPERAND(BRAKET, 0, 0, 0, ARC_OPERAND_FAKE | ARC_OPERAND_BRAKET, 0)
+ARC_OPERAND(BRAKETdup, 0, 0, 0, ARC_OPERAND_FAKE | ARC_OPERAND_BRAKET, 0)
+ARC_OPERAND(FKT_T, 1, 3, 0, ARC_OPERAND_FAKE, 0)
+ARC_OPERAND(FKT_NT, 1, 3, 0, ARC_OPERAND_FAKE, 0)
+ARC_OPERAND(UIMM6_20, 6, 0, 0, ARC_OPERAND_UNSIGNED, extract_uimm6_20)
+ARC_OPERAND(UIMM6_20R, 6, 0, -UIMM6_20R, ARC_OPERAND_UNSIGNED | 
ARC_OPERAND_PCREL, extract_uimm6_20)
+ARC_OPERAND(SIMM12_20, 12, 0, 0, ARC_OPERAND_SIGNED, extract_simm12_20)
+ARC_OPERAND(SIMM12_20R, 12, 0, -SIMM12_20R, ARC_OPERAND_SIGNED | 
ARC_OPERAND_PCREL,extract_simm12_20)
+ARC_OPERAND(UIMM12_20, 12, 0, 0, ARC_OPERAND_UNSIGNED, extract_uimm12_20)
+ARC_OPERAND(SIMM3_5_S, 3, 0, 0, ARC_OPERAND_SIGNED | ARC_OPERAND_NCHK, 
extract_simm3s)
+ARC_OPERAND(UIMM7_A32_11_S, 7, 0, 0, ARC_OPERAND_UNSIGNED | 
ARC_OPERAND_ALIGNED32 | ARC_OPERAND_TRUNCATE | ARC_OPERAND_IGNORE, 
extract_uimm7_a32_11_s)
+ARC_OPERAND(UIMM7_A32_11R_S, 7, 0, -UIMM7_A32_11R_S, ARC_OPERAND_UNSIGNED | 
ARC_OPERAND_ALIGNED32 | ARC_OPERAND_TRUNCATE | ARC_OPERAND_IGNORE | 
ARC_OPERAND_PCREL, extract_uimm7_a32_11_s)
+ARC_OPERAND(UIMM9_A32_11_S, 9, 0, 0, ARC_OPERAND_UNSIGNED | 
ARC_OPERAND_ALIGNED32 | ARC_OPERAND_TRUNCATE | ARC_OPERAND_IGNORE, 
extract_uimm9_a32_11_s)
+ARC_OPERAND(UIMM7_9_S, 7, 0, 0, ARC_OPERAND_UNSIGNED, extract_uimm7_9_s)
+ARC_OPERAND(UIMM3_13_S, 3, 0, 0, ARC_OPERAND_UNSIGNED, extract_uimm3_13_s)
+ARC_OPERAND(UIMM3_13R_S, 3, 0, -UIMM3_13R_S, ARC_OPERAND_UNSIGNED | 
ARC_OPERAND_PCREL, extract_uimm3_13_s)
+ARC_OPERAND(SIMM11_A32_7_S, 11, 0, 0, ARC_OPERAND_SIGNED | 
ARC_OPERAND_ALIGNED32 | ARC_OPERAND_TRUNCATE, extract_simm11_a32_7_s)
+ARC_OPERAND(UIMM6_13_S, 6, 0, 0, ARC_OPERAND_UNSIGNED, extract_uimm6_13_s)
+ARC_OPERAND(UIMM5_11_S, 5, 0, 0, ARC_OPERAND_UNSIGNED | ARC_OPERAND_IGNORE, 
extract_uimm5_11_s)
+ARC_OPERAND(SIMM9_A16_8, 9, 0, 0, ARC_OPERAND_SIGNED | ARC_OPERAND_ALIGNED16 | 
ARC_OPERAND_PCREL | ARC_OPERAND_TRUNCATE, extract_simm9_a16_8)
+ARC_OPERAND(UIMM6_8, 6, 0, 0, ARC_OPERAND_UNSIGNED, extract_uimm6_8)
+ARC_OPERAND(SIMM21_A16_5, 21, 0, 0, ARC_OPERAND_SIGNED | ARC_OPERAND_ALIGNED16 
| ARC_OPERAND_TRUNCATE | ARC_OPERAND_PCREL, extract_simm21_a16_5)
+ARC_OPERAND(SIMM25_A16_5, 25, 0, 0, ARC_OPERAND_SIGNED | ARC_OPERAND_ALIGNED16 
| ARC_OPERAND_TRUNCATE | ARC_OPERAND_PCREL, extract_simm25_a16_5)
+ARC_OPERAND(SIMM10_A16_7_S, 10, 0, 0, ARC_OPERAND_SIGNED | 
ARC_OPERAND_ALIGNED16 | ARC_OPERAND_TRUNCATE | ARC_OPERAND_PCREL, 
extract_simm10_a16_7_s)
+ARC_OPERAND(SIMM10_A16_7_Sbis, 10, 0, -SIMM10_A16_7_Sbis, ARC_OPERAND_SIGNED | 
ARC_OPERAND_ALIGNED16 | ARC_OPERAND_TRUNCATE, extract_simm10_a16_7_s)
+ARC_OPERAND(SIMM7_A16_10_S, 7, 0, 0, ARC_OPERAND_SIGNED | 
ARC_OPERAND_ALIGNED16 | ARC_OPERAND_TRUNCATE | ARC_OPERAND_PCREL, 
extract_simm7_a16_10_s)
+ARC_OPERAND(SIMM21_A32_5, 21, 0, 0, ARC_OPERAND_SIGNED | ARC_OPERAND_ALIGNED32 
| ARC_OPERAND_TRUNCATE | ARC_OPERAND_PCREL, extract_simm21_a32_5)
+ARC_OPERAND(SIMM25_A32_5, 25, 0, 0, ARC_OPERAND_SIGNED | ARC_OPERAND_ALIGNED32 
| ARC_OPERAND_TRUNCATE | ARC_OPERAND_PCREL, extract_simm25_a32_5)
+ARC_OPERAND(SIMM13_A32_5_S, 13, 0, 0, ARC_OPERAND_SIGNED | 
ARC_OPERAND_ALIGNED32 | ARC_OPERAND_TRUNCATE | ARC_OPERAND_PCREL, 
extract_simm13_a32_5_s)
+ARC_OPERAND(SIMM8_A16_9_S, 8, 0, 0, ARC_OPERAND_SIGNED | ARC_OPERAND_ALIGNED16 
| ARC_OPERAND_TRUNCATE | ARC_OPERAND_PCREL, extract_simm8_a16_9_s)
+ARC_OPERAND(UIMM10_6_S_JLIOFF, 12, 0, 0, ARC_OPERAND_UNSIGNED | 
ARC_OPERAND_ALIGNED32 | ARC_OPERAND_TRUNCATE, extract_uimm10_6_s)
+ARC_OPERAND(UIMM3_23, 3, 0, 0, ARC_OPERAND_UNSIGNED, extract_uimm3_23)
+ARC_OPERAND(UIMM10_6_S, 10, 0, 0, ARC_OPERAND_UNSIGNED, extract_uimm10_6_s)
+ARC_OPERAND(UIMM10_13_S, 10, 0, 0, ARC_OPERAND_UNSIGNED, extract_uimm10_13_s)
+ARC_OPERAND(UIMM6_11_S, 6, 0, 0, ARC_OPERAND_UNSIGNED, extract_uimm6_11_s)
+ARC_OPERAND(SIMM9_8, 9, 0, 0, ARC_OPERAND_SIGNED | ARC_OPERAND_IGNORE, 
extract_simm9_8)
+ARC_OPERAND(SIMM9_8R, 9, 0, -SIMM9_8R, ARC_OPERAND_SIGNED | ARC_OPERAND_IGNORE 
| ARC_OPERAND_PCREL, extract_simm9_8)
+ARC_OPERAND(UIMM10_A32_8_S, 10, 0, -UIMM10_A32_8_S, ARC_OPERAND_UNSIGNED | 
ARC_OPERAND_ALIGNED32 | ARC_OPERAND_TRUNCATE | ARC_OPERAND_PCREL, 
extract_uimm10_a32_8_s)
+ARC_OPERAND(SIMM9_7_S, 9, 0, 0, ARC_OPERAND_SIGNED, extract_simm9_7_s)
+ARC_OPERAND(UIMM6_A16_11_S, 6, 0, 0, ARC_OPERAND_UNSIGNED | 
ARC_OPERAND_ALIGNED16 | ARC_OPERAND_TRUNCATE  | ARC_OPERAND_IGNORE, 
extract_uimm6_a16_11_s)
+ARC_OPERAND(UIMM5_A32_11_S, 5, 0, 0, ARC_OPERAND_UNSIGNED | 
ARC_OPERAND_ALIGNED32 | ARC_OPERAND_TRUNCATE | ARC_OPERAND_IGNORE, 
extract_uimm5_a32_11_s)
+ARC_OPERAND(SIMM11_A32_13_S, 11, 0, 0, ARC_OPERAND_SIGNED | 
ARC_OPERAND_ALIGNED32 | ARC_OPERAND_TRUNCATE, extract_simm11_a32_13_s)
+ARC_OPERAND(UIMM7_13_S, 7, 0, 0, ARC_OPERAND_UNSIGNED, extract_uimm7_13_s)
+ARC_OPERAND(UIMM6_A16_21, 6, 0, 0, ARC_OPERAND_UNSIGNED | 
ARC_OPERAND_ALIGNED16 | ARC_OPERAND_TRUNCATE, extract_uimm6_a16_21)
+ARC_OPERAND(UIMM7_11_S, 7, 0, 0, ARC_OPERAND_UNSIGNED, extract_uimm7_11_s)
+ARC_OPERAND(UIMM7_A16_20, 7, 0, -UIMM7_A16_20, ARC_OPERAND_UNSIGNED | 
ARC_OPERAND_ALIGNED16 | ARC_OPERAND_TRUNCATE | ARC_OPERAND_PCREL, 
extract_uimm7_a16_20)
+ARC_OPERAND(SIMM13_A16_20, 13, 0, 0, ARC_OPERAND_SIGNED | 
ARC_OPERAND_ALIGNED16 | ARC_OPERAND_TRUNCATE | ARC_OPERAND_PCREL, 
extract_simm13_a16_20)
+ARC_OPERAND(UIMM8_8_S, 8, 0, 0, ARC_OPERAND_UNSIGNED, extract_uimm8_8_s)
+ARC_OPERAND(UIMM8_8R_S, 8, 0, -UIMM8_8R_S, ARC_OPERAND_UNSIGNED | 
ARC_OPERAND_PCREL, extract_uimm8_8_s)
+ARC_OPERAND(W6, 6, 0, 0, ARC_OPERAND_SIGNED, extract_w6)
+ARC_OPERAND(UIMM6_5_S, 6, 0, 0, ARC_OPERAND_UNSIGNED, extract_uimm6_5_s)
-- 
2.20.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]