[AArch64][SVE 24/32] Add AARCH64_OPND_SVE_PATTERN_SCALED
[deliverable/binutils-gdb.git] / opcodes / aarch64-opc.c
index b7b1b4a913a00e82787e4861e8eeb134b1a7d539..326b94e71e956980554b22bdaab1247832f2b3c6 100644 (file)
@@ -1,5 +1,5 @@
 /* aarch64-opc.c -- AArch64 opcode support.
 /* aarch64-opc.c -- AArch64 opcode support.
-   Copyright 2009, 2010, 2011, 2012, 2013  Free Software Foundation, Inc.
+   Copyright (C) 2009-2016 Free Software Foundation, Inc.
    Contributed by ARM Ltd.
 
    This file is part of the GNU opcodes library.
    Contributed by ARM Ltd.
 
    This file is part of the GNU opcodes library.
@@ -27,6 +27,7 @@
 #include <inttypes.h>
 
 #include "opintl.h"
 #include <inttypes.h>
 
 #include "opintl.h"
+#include "libiberty.h"
 
 #include "aarch64-opc.h"
 
 
 #include "aarch64-opc.h"
 
 int debug_dump = FALSE;
 #endif /* DEBUG_AARCH64 */
 
 int debug_dump = FALSE;
 #endif /* DEBUG_AARCH64 */
 
+/* The enumeration strings associated with each value of a 5-bit SVE
+   pattern operand.  A null entry indicates a reserved meaning.  */
+const char *const aarch64_sve_pattern_array[32] = {
+  /* 0-7.  */
+  "pow2",
+  "vl1",
+  "vl2",
+  "vl3",
+  "vl4",
+  "vl5",
+  "vl6",
+  "vl7",
+  /* 8-15.  */
+  "vl8",
+  "vl16",
+  "vl32",
+  "vl64",
+  "vl128",
+  "vl256",
+  0,
+  0,
+  /* 16-23.  */
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  0,
+  /* 24-31.  */
+  0,
+  0,
+  0,
+  0,
+  0,
+  "mul4",
+  "mul3",
+  "all"
+};
+
+/* The enumeration strings associated with each value of a 4-bit SVE
+   prefetch operand.  A null entry indicates a reserved meaning.  */
+const char *const aarch64_sve_prfop_array[16] = {
+  /* 0-7.  */
+  "pldl1keep",
+  "pldl1strm",
+  "pldl2keep",
+  "pldl2strm",
+  "pldl3keep",
+  "pldl3strm",
+  0,
+  0,
+  /* 8-15.  */
+  "pstl1keep",
+  "pstl1strm",
+  "pstl2keep",
+  "pstl2strm",
+  "pstl3keep",
+  "pstl3strm",
+  0,
+  0
+};
+
 /* Helper functions to determine which operand to be used to encode/decode
    the size:Q fields for AdvSIMD instructions.  */
 
 /* Helper functions to determine which operand to be used to encode/decode
    the size:Q fields for AdvSIMD instructions.  */
 
@@ -192,12 +257,32 @@ const aarch64_field fields[] =
     { 11,  1 },        /* index: in ld/st inst deciding the pre/post-index.  */
     { 24,  1 },        /* index2: in ld/st pair inst deciding the pre/post-index.  */
     { 31,  1 },        /* sf: in integer data processing instructions.  */
     { 11,  1 },        /* index: in ld/st inst deciding the pre/post-index.  */
     { 24,  1 },        /* index2: in ld/st pair inst deciding the pre/post-index.  */
     { 31,  1 },        /* sf: in integer data processing instructions.  */
+    { 30,  1 },        /* lse_size: in LSE extension atomic instructions.  */
     { 11,  1 },        /* H: in advsimd scalar x indexed element instructions.  */
     { 21,  1 },        /* L: in advsimd scalar x indexed element instructions.  */
     { 20,  1 },        /* M: in advsimd scalar x indexed element instructions.  */
     { 31,  1 },        /* b5: in the test bit and branch instructions.  */
     { 19,  5 },        /* b40: in the test bit and branch instructions.  */
     { 10,  6 },        /* scale: in the fixed-point scalar to fp converting inst.  */
     { 11,  1 },        /* H: in advsimd scalar x indexed element instructions.  */
     { 21,  1 },        /* L: in advsimd scalar x indexed element instructions.  */
     { 20,  1 },        /* M: in advsimd scalar x indexed element instructions.  */
     { 31,  1 },        /* b5: in the test bit and branch instructions.  */
     { 19,  5 },        /* b40: in the test bit and branch instructions.  */
     { 10,  6 },        /* scale: in the fixed-point scalar to fp converting inst.  */
+    {  0,  4 }, /* SVE_Pd: p0-p15, bits [3,0].  */
+    { 10,  3 }, /* SVE_Pg3: p0-p7, bits [12,10].  */
+    {  5,  4 }, /* SVE_Pg4_5: p0-p15, bits [8,5].  */
+    { 10,  4 }, /* SVE_Pg4_10: p0-p15, bits [13,10].  */
+    { 16,  4 }, /* SVE_Pg4_16: p0-p15, bits [19,16].  */
+    { 16,  4 }, /* SVE_Pm: p0-p15, bits [19,16].  */
+    {  5,  4 }, /* SVE_Pn: p0-p15, bits [8,5].  */
+    {  0,  4 }, /* SVE_Pt: p0-p15, bits [3,0].  */
+    {  5,  5 }, /* SVE_Za_5: SVE vector register, bits [9,5].  */
+    { 16,  5 }, /* SVE_Za_16: SVE vector register, bits [20,16].  */
+    {  0,  5 }, /* SVE_Zd: SVE vector register. bits [4,0].  */
+    {  5,  5 }, /* SVE_Zm_5: SVE vector register, bits [9,5].  */
+    { 16,  5 }, /* SVE_Zm_16: SVE vector register, bits [20,16]. */
+    {  5,  5 }, /* SVE_Zn: SVE vector register, bits [9,5].  */
+    {  0,  5 }, /* SVE_Zt: SVE vector register, bits [4,0].  */
+    { 16,  4 }, /* SVE_imm4: 4-bit immediate field.  */
+    {  5,  5 }, /* SVE_pattern: vector pattern enumeration.  */
+    {  0,  4 }, /* SVE_prfop: prefetch operation for SVE PRF[BHWD].  */
+    { 22,  2 }, /* SVE_tszh: triangular size select high, bits [23,22].  */
 };
 
 enum aarch64_operand_class
 };
 
 enum aarch64_operand_class
@@ -275,6 +360,7 @@ const struct aarch64_name_value_pair aarch64_operand_modifiers [] =
     {"sxth", 0x5},
     {"sxtw", 0x6},
     {"sxtx", 0x7},
     {"sxth", 0x5},
     {"sxtw", 0x6},
     {"sxtx", 0x7},
+    {"mul", 0x0},
     {NULL, 0},
 };
 
     {NULL, 0},
 };
 
@@ -334,6 +420,19 @@ const struct aarch64_name_value_pair aarch64_barrier_options[16] =
     { "sy",    0xf },
 };
 
     { "sy",    0xf },
 };
 
+/* Table describing the operands supported by the aliases of the HINT
+   instruction.
+
+   The name column is the operand that is accepted for the alias.  The value
+   column is the hint number of the alias.  The list of operands is terminated
+   by NULL in the name column.  */
+
+const struct aarch64_name_value_pair aarch64_hint_options[] =
+{
+  { "csync", 0x11 },    /* PSB CSYNC.  */
+  { NULL, 0x0 },
+};
+
 /* op -> op:       load = 0 instruction = 1 store = 2
    l  -> level:    1-3
    t  -> temporal: temporal (retained) = 0 non-temporal (streaming) = 1   */
 /* op -> op:       load = 0 instruction = 1 store = 2
    l  -> level:    1-3
    t  -> temporal: temporal (retained) = 0 non-temporal (streaming) = 1   */
@@ -564,6 +663,7 @@ struct operand_qualifier_data aarch64_opnd_qualifiers[] =
 
   {1, 8, 0x0, "8b", OQK_OPD_VARIANT},
   {1, 16, 0x1, "16b", OQK_OPD_VARIANT},
 
   {1, 8, 0x0, "8b", OQK_OPD_VARIANT},
   {1, 16, 0x1, "16b", OQK_OPD_VARIANT},
+  {2, 2, 0x0, "2h", OQK_OPD_VARIANT},
   {2, 4, 0x2, "4h", OQK_OPD_VARIANT},
   {2, 8, 0x3, "8h", OQK_OPD_VARIANT},
   {4, 2, 0x4, "2s", OQK_OPD_VARIANT},
   {2, 4, 0x2, "4h", OQK_OPD_VARIANT},
   {2, 8, 0x3, "8h", OQK_OPD_VARIANT},
   {4, 2, 0x4, "2s", OQK_OPD_VARIANT},
@@ -572,6 +672,9 @@ struct operand_qualifier_data aarch64_opnd_qualifiers[] =
   {8, 2, 0x7, "2d", OQK_OPD_VARIANT},
   {16, 1, 0x8, "1q", OQK_OPD_VARIANT},
 
   {8, 2, 0x7, "2d", OQK_OPD_VARIANT},
   {16, 1, 0x8, "1q", OQK_OPD_VARIANT},
 
+  {0, 0, 0, "z", OQK_OPD_VARIANT},
+  {0, 0, 0, "m", OQK_OPD_VARIANT},
+
   /* Qualifiers constraining the value range.
      First 3 fields:
      Lower bound, higher bound, unused.  */
   /* Qualifiers constraining the value range.
      First 3 fields:
      Lower bound, higher bound, unused.  */
@@ -839,7 +942,7 @@ aarch64_find_best_match (const aarch64_inst *inst,
 static int
 match_operands_qualifier (aarch64_inst *inst, bfd_boolean update_p)
 {
 static int
 match_operands_qualifier (aarch64_inst *inst, bfd_boolean update_p)
 {
-  int i;
+  int i, nops;
   aarch64_opnd_qualifier_seq_t qualifiers;
 
   if (!aarch64_find_best_match (inst, inst->opcode->qualifiers_list, -1,
   aarch64_opnd_qualifier_seq_t qualifiers;
 
   if (!aarch64_find_best_match (inst, inst->opcode->qualifiers_list, -1,
@@ -849,6 +952,15 @@ match_operands_qualifier (aarch64_inst *inst, bfd_boolean update_p)
       return 0;
     }
 
       return 0;
     }
 
+  if (inst->opcode->flags & F_STRICT)
+    {
+      /* Require an exact qualifier match, even for NIL qualifiers.  */
+      nops = aarch64_num_of_operands (inst->opcode);
+      for (i = 0; i < nops; ++i)
+       if (inst->operands[i].qualifier != qualifiers[i])
+         return FALSE;
+    }
+
   /* Update the qualifiers.  */
   if (update_p == TRUE)
     for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
   /* Update the qualifiers.  */
   if (update_p == TRUE)
     for (i = 0; i < AARCH64_MAX_OPND_NUM; ++i)
@@ -1038,16 +1150,18 @@ build_immediate_table (void)
    be accepted by logical (immediate) instructions
    e.g. ORR <Xd|SP>, <Xn>, #<imm>.
 
    be accepted by logical (immediate) instructions
    e.g. ORR <Xd|SP>, <Xn>, #<imm>.
 
-   IS32 indicates whether or not VALUE is a 32-bit immediate.
+   ESIZE is the number of bytes in the decoded immediate value.
    If ENCODING is not NULL, on the return of TRUE, the standard encoding for
    VALUE will be returned in *ENCODING.  */
 
 bfd_boolean
    If ENCODING is not NULL, on the return of TRUE, the standard encoding for
    VALUE will be returned in *ENCODING.  */
 
 bfd_boolean
-aarch64_logical_immediate_p (uint64_t value, int is32, aarch64_insn *encoding)
+aarch64_logical_immediate_p (uint64_t value, int esize, aarch64_insn *encoding)
 {
   simd_imm_encoding imm_enc;
   const simd_imm_encoding *imm_encoding;
   static bfd_boolean initialized = FALSE;
 {
   simd_imm_encoding imm_enc;
   const simd_imm_encoding *imm_encoding;
   static bfd_boolean initialized = FALSE;
+  uint64_t upper;
+  int i;
 
   DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), is32: %d", value,
               value, is32);
 
   DEBUG_TRACE ("enter with 0x%" PRIx64 "(%" PRIi64 "), is32: %d", value,
               value, is32);
@@ -1058,16 +1172,16 @@ aarch64_logical_immediate_p (uint64_t value, int is32, aarch64_insn *encoding)
       initialized = TRUE;
     }
 
       initialized = TRUE;
     }
 
-  if (is32)
-    {
-      /* Allow all zeros or all ones in top 32-bits, so that
-        constant expressions like ~1 are permitted.  */
-      if (value >> 32 != 0 && value >> 32 != 0xffffffff)
-       return 0xffffffff;
-      /* Replicate the 32 lower bits to the 32 upper bits.  */
-      value &= 0xffffffff;
-      value |= value << 32;
-    }
+  /* Allow all zeros or all ones in top bits, so that
+     constant expressions like ~1 are permitted.  */
+  upper = (uint64_t) -1 << (esize * 4) << (esize * 4);
+  if ((value & ~upper) != value && (value | upper) != value)
+    return FALSE;
+
+  /* Replicate to a full 64-bit value.  */
+  value &= ~upper;
+  for (i = esize * 8; i < 64; i *= 2)
+    value |= (value << i);
 
   imm_enc.imm = value;
   imm_encoding = (const simd_imm_encoding *)
 
   imm_enc.imm = value;
   imm_encoding = (const simd_imm_encoding *)
@@ -1120,6 +1234,15 @@ set_error (aarch64_operand_error *mismatch_detail,
   mismatch_detail->error = error;
 }
 
   mismatch_detail->error = error;
 }
 
+static inline void
+set_syntax_error (aarch64_operand_error *mismatch_detail, int idx,
+                 const char* error)
+{
+  if (mismatch_detail == NULL)
+    return;
+  set_error (mismatch_detail, AARCH64_OPDE_SYNTAX_ERROR, idx, error);
+}
+
 static inline void
 set_out_of_range_error (aarch64_operand_error *mismatch_detail,
                        int idx, int lower_bound, int upper_bound,
 static inline void
 set_out_of_range_error (aarch64_operand_error *mismatch_detail,
                        int idx, int lower_bound, int upper_bound,
@@ -1182,6 +1305,18 @@ set_sft_amount_out_of_range_error (aarch64_operand_error *mismatch_detail,
                          _("shift amount"));
 }
 
                          _("shift amount"));
 }
 
+/* Report that the MUL modifier in operand IDX should be in the range
+   [LOWER_BOUND, UPPER_BOUND].  */
+static inline void
+set_multiplier_out_of_range_error (aarch64_operand_error *mismatch_detail,
+                                  int idx, int lower_bound, int upper_bound)
+{
+  if (mismatch_detail == NULL)
+    return;
+  set_out_of_range_error (mismatch_detail, idx, lower_bound, upper_bound,
+                         _("multiplier"));
+}
+
 static inline void
 set_unaligned_error (aarch64_operand_error *mismatch_detail, int idx,
                     int alignment)
 static inline void
 set_unaligned_error (aarch64_operand_error *mismatch_detail, int idx,
                     int alignment)
@@ -1244,17 +1379,38 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
   switch (aarch64_operands[type].op_class)
     {
     case AARCH64_OPND_CLASS_INT_REG:
   switch (aarch64_operands[type].op_class)
     {
     case AARCH64_OPND_CLASS_INT_REG:
+      /* Check pair reg constraints for cas* instructions.  */
+      if (type == AARCH64_OPND_PAIRREG)
+       {
+         assert (idx == 1 || idx == 3);
+         if (opnds[idx - 1].reg.regno % 2 != 0)
+           {
+             set_syntax_error (mismatch_detail, idx - 1,
+                               _("reg pair must start from even reg"));
+             return 0;
+           }
+         if (opnds[idx].reg.regno != opnds[idx - 1].reg.regno + 1)
+           {
+             set_syntax_error (mismatch_detail, idx,
+                               _("reg pair must be contiguous"));
+             return 0;
+           }
+         break;
+       }
+
       /* <Xt> may be optional in some IC and TLBI instructions.  */
       if (type == AARCH64_OPND_Rt_SYS)
        {
          assert (idx == 1 && (aarch64_get_operand_class (opnds[0].type)
                               == AARCH64_OPND_CLASS_SYSTEM));
       /* <Xt> may be optional in some IC and TLBI instructions.  */
       if (type == AARCH64_OPND_Rt_SYS)
        {
          assert (idx == 1 && (aarch64_get_operand_class (opnds[0].type)
                               == AARCH64_OPND_CLASS_SYSTEM));
-         if (opnds[1].present && !opnds[0].sysins_op->has_xt)
+         if (opnds[1].present
+             && !aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
            {
              set_other_error (mismatch_detail, idx, _("extraneous register"));
              return 0;
            }
            {
              set_other_error (mismatch_detail, idx, _("extraneous register"));
              return 0;
            }
-         if (!opnds[1].present && opnds[0].sysins_op->has_xt)
+         if (!opnds[1].present
+             && aarch64_sys_ins_reg_has_xt (opnds[0].sysins_op))
            {
              set_other_error (mismatch_detail, idx, _("missing register"));
              return 0;
            {
              set_other_error (mismatch_detail, idx, _("missing register"));
              return 0;
@@ -1276,6 +1432,52 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
        }
       break;
 
        }
       break;
 
+    case AARCH64_OPND_CLASS_SVE_REG:
+      switch (type)
+       {
+       case AARCH64_OPND_SVE_Zn_INDEX:
+         size = aarch64_get_qualifier_esize (opnd->qualifier);
+         if (!value_in_range_p (opnd->reglane.index, 0, 64 / size - 1))
+           {
+             set_elem_idx_out_of_range_error (mismatch_detail, idx,
+                                              0, 64 / size - 1);
+             return 0;
+           }
+         break;
+
+       case AARCH64_OPND_SVE_ZnxN:
+       case AARCH64_OPND_SVE_ZtxN:
+         if (opnd->reglist.num_regs != get_opcode_dependent_value (opcode))
+           {
+             set_other_error (mismatch_detail, idx,
+                              _("invalid register list"));
+             return 0;
+           }
+         break;
+
+       default:
+         break;
+       }
+      break;
+
+    case AARCH64_OPND_CLASS_PRED_REG:
+      if (opnd->reg.regno >= 8
+         && get_operand_fields_width (get_operand_from_code (type)) == 3)
+       {
+         set_other_error (mismatch_detail, idx, _("p0-p7 expected"));
+         return 0;
+       }
+      break;
+
+    case AARCH64_OPND_CLASS_COND:
+      if (type == AARCH64_OPND_COND1
+         && (opnds[idx].cond->value & 0xe) == 0xe)
+       {
+         /* Not allow AL or NV.  */
+         set_syntax_error (mismatch_detail, idx, NULL);
+       }
+      break;
+
     case AARCH64_OPND_CLASS_ADDRESS:
       /* Check writeback.  */
       switch (opcode->iclass)
     case AARCH64_OPND_CLASS_ADDRESS:
       /* Check writeback.  */
       switch (opcode->iclass)
@@ -1287,8 +1489,8 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
        case ldst_unpriv:
          if (opnd->addr.writeback == 1)
            {
        case ldst_unpriv:
          if (opnd->addr.writeback == 1)
            {
-             set_other_error (mismatch_detail, idx,
-                              _("unexpected address writeback"));
+             set_syntax_error (mismatch_detail, idx,
+                               _("unexpected address writeback"));
              return 0;
            }
          break;
              return 0;
            }
          break;
@@ -1298,8 +1500,8 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
        case asisdlsop:
          if (opnd->addr.writeback == 0)
            {
        case asisdlsop:
          if (opnd->addr.writeback == 0)
            {
-             set_other_error (mismatch_detail, idx,
-                              _("address writeback expected"));
+             set_syntax_error (mismatch_detail, idx,
+                               _("address writeback expected"));
              return 0;
            }
          break;
              return 0;
            }
          break;
@@ -1466,6 +1668,16 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
       break;
 
     case AARCH64_OPND_CLASS_SIMD_REGLIST:
       break;
 
     case AARCH64_OPND_CLASS_SIMD_REGLIST:
+      if (type == AARCH64_OPND_LEt)
+       {
+         /* Get the upper bound for the element index.  */
+         num = 16 / aarch64_get_qualifier_esize (qualifier) - 1;
+         if (!value_in_range_p (opnd->reglist.index, 0, num))
+           {
+             set_elem_idx_out_of_range_error (mismatch_detail, idx, 0, num);
+             return 0;
+           }
+       }
       /* The opcode dependent area stores the number of elements in
         each structure to be loaded/stored.  */
       num = get_opcode_dependent_value (opcode);
       /* The opcode dependent area stores the number of elements in
         each structure to be loaded/stored.  */
       num = get_opcode_dependent_value (opcode);
@@ -1571,7 +1783,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
 
        case AARCH64_OPND_IMM_MOV:
            {
 
        case AARCH64_OPND_IMM_MOV:
            {
-             int is32 = aarch64_get_qualifier_esize (opnds[0].qualifier) == 4;
+             int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
              imm = opnd->imm.value;
              assert (idx == 1);
              switch (opcode->op)
              imm = opnd->imm.value;
              assert (idx == 1);
              switch (opcode->op)
@@ -1580,7 +1792,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
                  imm = ~imm;
                  /* Fall through...  */
                case OP_MOV_IMM_WIDE:
                  imm = ~imm;
                  /* Fall through...  */
                case OP_MOV_IMM_WIDE:
-                 if (!aarch64_wide_constant_p (imm, is32, NULL))
+                 if (!aarch64_wide_constant_p (imm, esize == 4, NULL))
                    {
                      set_other_error (mismatch_detail, idx,
                                       _("immediate out of range"));
                    {
                      set_other_error (mismatch_detail, idx,
                                       _("immediate out of range"));
@@ -1588,7 +1800,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
                    }
                  break;
                case OP_MOV_IMM_LOG:
                    }
                  break;
                case OP_MOV_IMM_LOG:
-                 if (!aarch64_logical_immediate_p (imm, is32, NULL))
+                 if (!aarch64_logical_immediate_p (imm, esize, NULL))
                    {
                      set_other_error (mismatch_detail, idx,
                                       _("immediate out of range"));
                    {
                      set_other_error (mismatch_detail, idx,
                                       _("immediate out of range"));
@@ -1620,7 +1832,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
          break;
 
        case AARCH64_OPND_WIDTH:
          break;
 
        case AARCH64_OPND_WIDTH:
-         assert (idx == 3 && opnds[idx-1].type == AARCH64_OPND_IMM
+         assert (idx > 1 && opnds[idx-1].type == AARCH64_OPND_IMM
                  && opnds[0].type == AARCH64_OPND_Rd);
          size = get_upper_bound (qualifier);
          if (opnd->imm.value + opnds[idx-1].imm.value > size)
                  && opnds[0].type == AARCH64_OPND_Rd);
          size = get_upper_bound (qualifier);
          if (opnd->imm.value + opnds[idx-1].imm.value > size)
@@ -1633,18 +1845,18 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
          break;
 
        case AARCH64_OPND_LIMM:
          break;
 
        case AARCH64_OPND_LIMM:
-           {
-             int is32 = opnds[0].qualifier == AARCH64_OPND_QLF_W;
-             uint64_t uimm = opnd->imm.value;
-             if (opcode->op == OP_BIC)
-               uimm = ~uimm;
-             if (aarch64_logical_immediate_p (uimm, is32, NULL) == FALSE)
-               {
-                 set_other_error (mismatch_detail, idx,
-                                  _("immediate out of range"));
-                 return 0;
-               }
-           }
+         {
+           int esize = aarch64_get_qualifier_esize (opnds[0].qualifier);
+           uint64_t uimm = opnd->imm.value;
+           if (opcode->op == OP_BIC)
+             uimm = ~uimm;
+           if (aarch64_logical_immediate_p (uimm, esize, NULL) == FALSE)
+             {
+               set_other_error (mismatch_detail, idx,
+                                _("immediate out of range"));
+               return 0;
+             }
+         }
          break;
 
        case AARCH64_OPND_IMM0:
          break;
 
        case AARCH64_OPND_IMM0:
@@ -1724,10 +1936,10 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
          assert (idx == 1);
          if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
            {
          assert (idx == 1);
          if (aarch64_get_qualifier_esize (opnds[0].qualifier) != 8)
            {
-             /* uimm8 */
-             if (!value_in_range_p (opnd->imm.value, 0, 255))
+             /* uimm8 or simm8 */
+             if (!value_in_range_p (opnd->imm.value, -128, 255))
                {
                {
-                 set_imm_out_of_range_error (mismatch_detail, idx, 0, 255);
+                 set_imm_out_of_range_error (mismatch_detail, idx, -128, 255);
                  return 0;
                }
            }
                  return 0;
                }
            }
@@ -1803,6 +2015,15 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
            }
          break;
 
            }
          break;
 
+       case AARCH64_OPND_SVE_PATTERN_SCALED:
+         assert (opnd->shifter.kind == AARCH64_MOD_MUL);
+         if (!value_in_range_p (opnd->shifter.amount, 1, 16))
+           {
+             set_multiplier_out_of_range_error (mismatch_detail, idx, 1, 16);
+             return 0;
+           }
+         break;
+
        default:
          break;
        }
        default:
          break;
        }
@@ -1823,6 +2044,16 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
        {
        case AARCH64_OPND_PSTATEFIELD:
          assert (idx == 0 && opnds[1].type == AARCH64_OPND_UIMM4);
        {
        case AARCH64_OPND_PSTATEFIELD:
          assert (idx == 0 && opnds[1].type == AARCH64_OPND_UIMM4);
+         /* MSR UAO, #uimm4
+            MSR PAN, #uimm4
+            The immediate must be #0 or #1.  */
+         if ((opnd->pstatefield == 0x03        /* UAO.  */
+              || opnd->pstatefield == 0x04)    /* PAN.  */
+             && opnds[1].imm.value > 1)
+           {
+             set_imm_out_of_range_error (mismatch_detail, idx, 0, 1);
+             return 0;
+           }
          /* MSR SPSel, #uimm4
             Uses uimm4 as a control value to select the stack pointer: if
             bit 0 is set it selects the current exception level's stack
          /* MSR SPSel, #uimm4
             Uses uimm4 as a control value to select the stack pointer: if
             bit 0 is set it selects the current exception level's stack
@@ -1973,6 +2204,23 @@ aarch64_match_operands_constraint (aarch64_inst *inst,
 
   DEBUG_TRACE ("enter");
 
 
   DEBUG_TRACE ("enter");
 
+  /* Check for cases where a source register needs to be the same as the
+     destination register.  Do this before matching qualifiers since if
+     an instruction has both invalid tying and invalid qualifiers,
+     the error about qualifiers would suggest several alternative
+     instructions that also have invalid tying.  */
+  i = inst->opcode->tied_operand;
+  if (i > 0 && (inst->operands[0].reg.regno != inst->operands[i].reg.regno))
+    {
+      if (mismatch_detail)
+       {
+         mismatch_detail->kind = AARCH64_OPDE_UNTIED_OPERAND;
+         mismatch_detail->index = i;
+         mismatch_detail->error = NULL;
+       }
+      return 0;
+    }
+
   /* Match operands' qualifier.
      *INST has already had qualifier establish for some, if not all, of
      its operands; we need to find out whether these established
   /* Match operands' qualifier.
      *INST has already had qualifier establish for some, if not all, of
      its operands; we need to find out whether these established
@@ -2064,32 +2312,25 @@ aarch64_operand_index (const enum aarch64_opnd *operands, enum aarch64_opnd oper
   return -1;
 }
 \f
   return -1;
 }
 \f
+/* R0...R30, followed by FOR31.  */
+#define BANK(R, FOR31) \
+  { R  (0), R  (1), R  (2), R  (3), R  (4), R  (5), R  (6), R  (7), \
+    R  (8), R  (9), R (10), R (11), R (12), R (13), R (14), R (15), \
+    R (16), R (17), R (18), R (19), R (20), R (21), R (22), R (23), \
+    R (24), R (25), R (26), R (27), R (28), R (29), R (30),  FOR31 }
 /* [0][0]  32-bit integer regs with sp   Wn
    [0][1]  64-bit integer regs with sp   Xn  sf=1
    [1][0]  32-bit integer regs with #0   Wn
    [1][1]  64-bit integer regs with #0   Xn  sf=1 */
 static const char *int_reg[2][2][32] = {
 /* [0][0]  32-bit integer regs with sp   Wn
    [0][1]  64-bit integer regs with sp   Xn  sf=1
    [1][0]  32-bit integer regs with #0   Wn
    [1][1]  64-bit integer regs with #0   Xn  sf=1 */
 static const char *int_reg[2][2][32] = {
-#define R32 "w"
-#define R64 "x"
-  { { R32  "0", R32  "1", R32  "2", R32  "3", R32  "4", R32  "5", R32  "6", R32  "7",
-      R32  "8", R32  "9", R32 "10", R32 "11", R32 "12", R32 "13", R32 "14", R32 "15",
-      R32 "16", R32 "17", R32 "18", R32 "19", R32 "20", R32 "21", R32 "22", R32 "23",
-      R32 "24", R32 "25", R32 "26", R32 "27", R32 "28", R32 "29", R32 "30",    "wsp" },
-    { R64  "0", R64  "1", R64  "2", R64  "3", R64  "4", R64  "5", R64  "6", R64  "7",
-      R64  "8", R64  "9", R64 "10", R64 "11", R64 "12", R64 "13", R64 "14", R64 "15",
-      R64 "16", R64 "17", R64 "18", R64 "19", R64 "20", R64 "21", R64 "22", R64 "23",
-      R64 "24", R64 "25", R64 "26", R64 "27", R64 "28", R64 "29", R64 "30",     "sp" } },
-  { { R32  "0", R32  "1", R32  "2", R32  "3", R32  "4", R32  "5", R32  "6", R32  "7",
-      R32  "8", R32  "9", R32 "10", R32 "11", R32 "12", R32 "13", R32 "14", R32 "15",
-      R32 "16", R32 "17", R32 "18", R32 "19", R32 "20", R32 "21", R32 "22", R32 "23",
-      R32 "24", R32 "25", R32 "26", R32 "27", R32 "28", R32 "29", R32 "30", R32 "zr" },
-    { R64  "0", R64  "1", R64  "2", R64  "3", R64  "4", R64  "5", R64  "6", R64  "7",
-      R64  "8", R64  "9", R64 "10", R64 "11", R64 "12", R64 "13", R64 "14", R64 "15",
-      R64 "16", R64 "17", R64 "18", R64 "19", R64 "20", R64 "21", R64 "22", R64 "23",
-      R64 "24", R64 "25", R64 "26", R64 "27", R64 "28", R64 "29", R64 "30", R64 "zr" } }
+#define R32(X) "w" #X
+#define R64(X) "x" #X
+  { BANK (R32, "wsp"), BANK (R64, "sp") },
+  { BANK (R32, "wzr"), BANK (R64, "xzr") }
 #undef R64
 #undef R32
 };
 #undef R64
 #undef R32
 };
+#undef BANK
 
 /* Return the integer register name.
    if SP_REG_P is not 0, R31 is an SP reg, other R31 is the zero reg.  */
 
 /* Return the integer register name.
    if SP_REG_P is not 0, R31 is an SP reg, other R31 is the zero reg.  */
@@ -2111,6 +2352,27 @@ get_64bit_int_reg_name (int regno, int sp_reg_p)
   return int_reg[has_zr][1][regno];
 }
 
   return int_reg[has_zr][1][regno];
 }
 
+/* Get the name of the integer offset register in OPND, using the shift type
+   to decide whether it's a word or doubleword.  */
+
+static inline const char *
+get_offset_int_reg_name (const aarch64_opnd_info *opnd)
+{
+  switch (opnd->shifter.kind)
+    {
+    case AARCH64_MOD_UXTW:
+    case AARCH64_MOD_SXTW:
+      return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_W, 0);
+
+    case AARCH64_MOD_LSL:
+    case AARCH64_MOD_SXTX:
+      return get_int_reg_name (opnd->addr.offset.regno, AARCH64_OPND_QLF_X, 0);
+
+    default:
+      abort ();
+    }
+}
+
 /* Types for expanding an encoded 8-bit value to a floating-point value.  */
 
 typedef union
 /* Types for expanding an encoded 8-bit value to a floating-point value.  */
 
 typedef union
@@ -2125,14 +2387,22 @@ typedef union
   float    f;
 } single_conv_t;
 
   float    f;
 } single_conv_t;
 
+typedef union
+{
+  uint32_t i;
+  float    f;
+} half_conv_t;
+
 /* IMM8 is an 8-bit floating-point constant with sign, 3-bit exponent and
    normalized 4 bits of precision, encoded in "a:b:c:d:e:f:g:h" or FLD_imm8
    (depending on the type of the instruction).  IMM8 will be expanded to a
 /* IMM8 is an 8-bit floating-point constant with sign, 3-bit exponent and
    normalized 4 bits of precision, encoded in "a:b:c:d:e:f:g:h" or FLD_imm8
    (depending on the type of the instruction).  IMM8 will be expanded to a
-   single-precision floating-point value (IS_DP == 0) or a double-precision
-   floating-point value (IS_DP == 1).  The expanded value is returned.  */
+   single-precision floating-point value (SIZE == 4) or a double-precision
+   floating-point value (SIZE == 8).  A half-precision floating-point value
+   (SIZE == 2) is expanded to a single-precision floating-point value.  The
+   expanded value is returned.  */
 
 static uint64_t
 
 static uint64_t
-expand_fp_imm (int is_dp, uint32_t imm8)
+expand_fp_imm (int size, uint32_t imm8)
 {
   uint64_t imm;
   uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
 {
   uint64_t imm;
   uint32_t imm8_7, imm8_6_0, imm8_6, imm8_6_repl4;
@@ -2142,7 +2412,7 @@ expand_fp_imm (int is_dp, uint32_t imm8)
   imm8_6 = imm8_6_0 >> 6;      /* imm8<6>   */
   imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
     | (imm8_6 << 1) | imm8_6;  /* Replicate(imm8<6>,4) */
   imm8_6 = imm8_6_0 >> 6;      /* imm8<6>   */
   imm8_6_repl4 = (imm8_6 << 3) | (imm8_6 << 2)
     | (imm8_6 << 1) | imm8_6;  /* Replicate(imm8<6>,4) */
-  if (is_dp)
+  if (size == 8)
     {
       imm = (imm8_7 << (63-32))                /* imm8<7>  */
        | ((imm8_6 ^ 1) << (62-32))     /* NOT(imm8<6)  */
     {
       imm = (imm8_7 << (63-32))                /* imm8<7>  */
        | ((imm8_6 ^ 1) << (62-32))     /* NOT(imm8<6)  */
@@ -2151,21 +2421,28 @@ expand_fp_imm (int is_dp, uint32_t imm8)
        | (imm8_6_0 << (48-32));        /* imm8<6>:imm8<5:0>    */
       imm <<= 32;
     }
        | (imm8_6_0 << (48-32));        /* imm8<6>:imm8<5:0>    */
       imm <<= 32;
     }
-  else
+  else if (size == 4 || size == 2)
     {
       imm = (imm8_7 << 31)     /* imm8<7>              */
        | ((imm8_6 ^ 1) << 30)  /* NOT(imm8<6>)         */
        | (imm8_6_repl4 << 26)  /* Replicate(imm8<6>,4) */
        | (imm8_6_0 << 19);     /* imm8<6>:imm8<5:0>    */
     }
     {
       imm = (imm8_7 << 31)     /* imm8<7>              */
        | ((imm8_6 ^ 1) << 30)  /* NOT(imm8<6>)         */
        | (imm8_6_repl4 << 26)  /* Replicate(imm8<6>,4) */
        | (imm8_6_0 << 19);     /* imm8<6>:imm8<5:0>    */
     }
+  else
+    {
+      /* An unsupported size.  */
+      assert (0);
+    }
 
   return imm;
 }
 
 /* Produce the string representation of the register list operand *OPND
 
   return imm;
 }
 
 /* Produce the string representation of the register list operand *OPND
-   in the buffer pointed by BUF of size SIZE.  */
+   in the buffer pointed by BUF of size SIZE.  PREFIX is the part of
+   the register name that comes before the register number, such as "v".  */
 static void
 static void
-print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd)
+print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd,
+                    const char *prefix)
 {
   const int num_regs = opnd->reglist.num_regs;
   const int first_reg = opnd->reglist.first_regno;
 {
   const int num_regs = opnd->reglist.num_regs;
   const int first_reg = opnd->reglist.first_regno;
@@ -2178,7 +2455,7 @@ print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd)
 
   /* Prepare the index if any.  */
   if (opnd->reglist.has_index)
 
   /* Prepare the index if any.  */
   if (opnd->reglist.has_index)
-    snprintf (tb, 8, "[%d]", opnd->reglist.index);
+    snprintf (tb, 8, "[%" PRIi64 "]", opnd->reglist.index);
   else
     tb[0] = '\0';
 
   else
     tb[0] = '\0';
 
@@ -2186,8 +2463,8 @@ print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd)
      more than two registers in the list, and the register numbers
      are monotonically increasing in increments of one.  */
   if (num_regs > 2 && last_reg > first_reg)
      more than two registers in the list, and the register numbers
      are monotonically increasing in increments of one.  */
   if (num_regs > 2 && last_reg > first_reg)
-    snprintf (buf, size, "{v%d.%s-v%d.%s}%s", first_reg, qlf_name,
-             last_reg, qlf_name, tb);
+    snprintf (buf, size, "{%s%d.%s-%s%d.%s}%s", prefix, first_reg, qlf_name,
+             prefix, last_reg, qlf_name, tb);
   else
     {
       const int reg0 = first_reg;
   else
     {
       const int reg0 = first_reg;
@@ -2198,48 +2475,63 @@ print_register_list (char *buf, size_t size, const aarch64_opnd_info *opnd)
       switch (num_regs)
        {
        case 1:
       switch (num_regs)
        {
        case 1:
-         snprintf (buf, size, "{v%d.%s}%s", reg0, qlf_name, tb);
+         snprintf (buf, size, "{%s%d.%s}%s", prefix, reg0, qlf_name, tb);
          break;
        case 2:
          break;
        case 2:
-         snprintf (buf, size, "{v%d.%s, v%d.%s}%s", reg0, qlf_name,
-                   reg1, qlf_name, tb);
+         snprintf (buf, size, "{%s%d.%s, %s%d.%s}%s", prefix, reg0, qlf_name,
+                   prefix, reg1, qlf_name, tb);
          break;
        case 3:
          break;
        case 3:
-         snprintf (buf, size, "{v%d.%s, v%d.%s, v%d.%s}%s", reg0, qlf_name,
-                   reg1, qlf_name, reg2, qlf_name, tb);
+         snprintf (buf, size, "{%s%d.%s, %s%d.%s, %s%d.%s}%s",
+                   prefix, reg0, qlf_name, prefix, reg1, qlf_name,
+                   prefix, reg2, qlf_name, tb);
          break;
        case 4:
          break;
        case 4:
-         snprintf (buf, size, "{v%d.%s, v%d.%s, v%d.%s, v%d.%s}%s",
-                   reg0, qlf_name, reg1, qlf_name, reg2, qlf_name,
-                   reg3, qlf_name, tb);
+         snprintf (buf, size, "{%s%d.%s, %s%d.%s, %s%d.%s, %s%d.%s}%s",
+                   prefix, reg0, qlf_name, prefix, reg1, qlf_name,
+                   prefix, reg2, qlf_name, prefix, reg3, qlf_name, tb);
          break;
        }
     }
 }
 
          break;
        }
     }
 }
 
+/* Print the register+immediate address in OPND to BUF, which has SIZE
+   characters.  BASE is the name of the base register.  */
+
+static void
+print_immediate_offset_address (char *buf, size_t size,
+                               const aarch64_opnd_info *opnd,
+                               const char *base)
+{
+  if (opnd->addr.writeback)
+    {
+      if (opnd->addr.preind)
+       snprintf (buf, size, "[%s,#%d]!", base, opnd->addr.offset.imm);
+      else
+       snprintf (buf, size, "[%s],#%d", base, opnd->addr.offset.imm);
+    }
+  else
+    {
+      if (opnd->addr.offset.imm)
+       snprintf (buf, size, "[%s,#%d]", base, opnd->addr.offset.imm);
+      else
+       snprintf (buf, size, "[%s]", base);
+    }
+}
+
 /* Produce the string representation of the register offset address operand
 /* Produce the string representation of the register offset address operand
-   *OPND in the buffer pointed by BUF of size SIZE.  */
+   *OPND in the buffer pointed by BUF of size SIZE.  BASE and OFFSET are
+   the names of the base and offset registers.  */
 static void
 print_register_offset_address (char *buf, size_t size,
 static void
 print_register_offset_address (char *buf, size_t size,
-                              const aarch64_opnd_info *opnd)
+                              const aarch64_opnd_info *opnd,
+                              const char *base, const char *offset)
 {
 {
-  const size_t tblen = 16;
-  char tb[tblen];              /* Temporary buffer.  */
-  bfd_boolean lsl_p = FALSE;   /* Is LSL shift operator?  */
-  bfd_boolean wm_p = FALSE;    /* Should Rm be Wm?  */
+  char tb[16];                 /* Temporary buffer.  */
   bfd_boolean print_extend_p = TRUE;
   bfd_boolean print_amount_p = TRUE;
   const char *shift_name = aarch64_operand_modifiers[opnd->shifter.kind].name;
 
   bfd_boolean print_extend_p = TRUE;
   bfd_boolean print_amount_p = TRUE;
   const char *shift_name = aarch64_operand_modifiers[opnd->shifter.kind].name;
 
-  switch (opnd->shifter.kind)
-    {
-    case AARCH64_MOD_UXTW: wm_p = TRUE; break;
-    case AARCH64_MOD_LSL : lsl_p = TRUE; break;
-    case AARCH64_MOD_SXTW: wm_p = TRUE; break;
-    case AARCH64_MOD_SXTX: break;
-    default: assert (0);
-    }
-
   if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
                                || !opnd->shifter.amount_present))
     {
   if (!opnd->shifter.amount && (opnd->qualifier != AARCH64_OPND_QLF_S_B
                                || !opnd->shifter.amount_present))
     {
@@ -2248,7 +2540,7 @@ print_register_offset_address (char *buf, size_t size,
       print_amount_p = FALSE;
       /* Likewise, no need to print the shift operator LSL in such a
         situation.  */
       print_amount_p = FALSE;
       /* Likewise, no need to print the shift operator LSL in such a
         situation.  */
-      if (lsl_p)
+      if (opnd->shifter.kind == AARCH64_MOD_LSL)
        print_extend_p = FALSE;
     }
 
        print_extend_p = FALSE;
     }
 
@@ -2256,16 +2548,15 @@ print_register_offset_address (char *buf, size_t size,
   if (print_extend_p)
     {
       if (print_amount_p)
   if (print_extend_p)
     {
       if (print_amount_p)
-       snprintf (tb, tblen, ",%s #%d", shift_name, opnd->shifter.amount);
+       snprintf (tb, sizeof (tb), ",%s #%" PRIi64, shift_name,
+                 opnd->shifter.amount);
       else
       else
-       snprintf (tb, tblen, ",%s", shift_name);
+       snprintf (tb, sizeof (tb), ",%s", shift_name);
     }
   else
     tb[0] = '\0';
 
     }
   else
     tb[0] = '\0';
 
-  snprintf (buf, size, "[%s,%c%d%s]",
-           get_64bit_int_reg_name (opnd->addr.base_regno, 1),
-           wm_p ? 'w' : 'x', opnd->addr.offset.regno, tb);
+  snprintf (buf, size, "[%s,%s%s]", base, offset, tb);
 }
 
 /* Generate the string representation of the operand OPNDS[IDX] for OPCODE
 }
 
 /* Generate the string representation of the operand OPNDS[IDX] for OPCODE
@@ -2289,7 +2580,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
   const char *name = NULL;
   const aarch64_opnd_info *opnd = opnds + idx;
   enum aarch64_modifier_kind kind;
   const char *name = NULL;
   const aarch64_opnd_info *opnd = opnds + idx;
   enum aarch64_modifier_kind kind;
-  uint64_t addr;
+  uint64_t addr, enum_value;
 
   buf[0] = '\0';
   if (pcrel_p)
 
   buf[0] = '\0';
   if (pcrel_p)
@@ -2305,6 +2596,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
     case AARCH64_OPND_Rs:
     case AARCH64_OPND_Ra:
     case AARCH64_OPND_Rt_SYS:
     case AARCH64_OPND_Rs:
     case AARCH64_OPND_Ra:
     case AARCH64_OPND_Rt_SYS:
+    case AARCH64_OPND_PAIRREG:
       /* The optional-ness of <Xt> in e.g. IC <ic_op>{, <Xt>} is determined by
         the <ic_op>, therefore we we use opnd->present to override the
         generic optional-ness information.  */
       /* The optional-ness of <Xt> in e.g. IC <ic_op>{, <Xt>} is determined by
         the <ic_op>, therefore we we use opnd->present to override the
         generic optional-ness information.  */
@@ -2352,7 +2644,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
            }
        }
       if (opnd->shifter.amount)
            }
        }
       if (opnd->shifter.amount)
-       snprintf (buf, size, "%s, %s #%d",
+       snprintf (buf, size, "%s, %s #%" PRIi64,
                  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
                  aarch64_operand_modifiers[kind].name,
                  opnd->shifter.amount);
                  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
                  aarch64_operand_modifiers[kind].name,
                  opnd->shifter.amount);
@@ -2369,7 +2661,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
        snprintf (buf, size, "%s",
                  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
       else
        snprintf (buf, size, "%s",
                  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0));
       else
-       snprintf (buf, size, "%s, %s #%d",
+       snprintf (buf, size, "%s, %s #%" PRIi64,
                  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
                  aarch64_operand_modifiers[opnd->shifter.kind].name,
                  opnd->shifter.amount);
                  get_int_reg_name (opnd->reg.regno, opnd->qualifier, 0),
                  aarch64_operand_modifiers[opnd->shifter.kind].name,
                  opnd->shifter.amount);
@@ -2398,7 +2690,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
     case AARCH64_OPND_Ed:
     case AARCH64_OPND_En:
     case AARCH64_OPND_Em:
     case AARCH64_OPND_Ed:
     case AARCH64_OPND_En:
     case AARCH64_OPND_Em:
-      snprintf (buf, size, "v%d.%s[%d]", opnd->reglane.regno,
+      snprintf (buf, size, "v%d.%s[%" PRIi64 "]", opnd->reglane.regno,
                aarch64_get_qualifier_name (opnd->qualifier),
                opnd->reglane.index);
       break;
                aarch64_get_qualifier_name (opnd->qualifier),
                opnd->reglane.index);
       break;
@@ -2412,7 +2704,51 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
     case AARCH64_OPND_LVt:
     case AARCH64_OPND_LVt_AL:
     case AARCH64_OPND_LEt:
     case AARCH64_OPND_LVt:
     case AARCH64_OPND_LVt_AL:
     case AARCH64_OPND_LEt:
-      print_register_list (buf, size, opnd);
+      print_register_list (buf, size, opnd, "v");
+      break;
+
+    case AARCH64_OPND_SVE_Pd:
+    case AARCH64_OPND_SVE_Pg3:
+    case AARCH64_OPND_SVE_Pg4_5:
+    case AARCH64_OPND_SVE_Pg4_10:
+    case AARCH64_OPND_SVE_Pg4_16:
+    case AARCH64_OPND_SVE_Pm:
+    case AARCH64_OPND_SVE_Pn:
+    case AARCH64_OPND_SVE_Pt:
+      if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
+       snprintf (buf, size, "p%d", opnd->reg.regno);
+      else if (opnd->qualifier == AARCH64_OPND_QLF_P_Z
+              || opnd->qualifier == AARCH64_OPND_QLF_P_M)
+       snprintf (buf, size, "p%d/%s", opnd->reg.regno,
+                 aarch64_get_qualifier_name (opnd->qualifier));
+      else
+       snprintf (buf, size, "p%d.%s", opnd->reg.regno,
+                 aarch64_get_qualifier_name (opnd->qualifier));
+      break;
+
+    case AARCH64_OPND_SVE_Za_5:
+    case AARCH64_OPND_SVE_Za_16:
+    case AARCH64_OPND_SVE_Zd:
+    case AARCH64_OPND_SVE_Zm_5:
+    case AARCH64_OPND_SVE_Zm_16:
+    case AARCH64_OPND_SVE_Zn:
+    case AARCH64_OPND_SVE_Zt:
+      if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
+       snprintf (buf, size, "z%d", opnd->reg.regno);
+      else
+       snprintf (buf, size, "z%d.%s", opnd->reg.regno,
+                 aarch64_get_qualifier_name (opnd->qualifier));
+      break;
+
+    case AARCH64_OPND_SVE_ZnxN:
+    case AARCH64_OPND_SVE_ZtxN:
+      print_register_list (buf, size, opnd, "z");
+      break;
+
+    case AARCH64_OPND_SVE_Zn_INDEX:
+      snprintf (buf, size, "z%d.%s[%" PRIi64 "]", opnd->reglane.regno,
+               aarch64_get_qualifier_name (opnd->qualifier),
+               opnd->reglane.index);
       break;
 
     case AARCH64_OPND_Cn:
       break;
 
     case AARCH64_OPND_Cn:
@@ -2436,6 +2772,47 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
       snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
       break;
 
       snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
       break;
 
+    case AARCH64_OPND_SVE_PATTERN:
+      if (optional_operand_p (opcode, idx)
+         && opnd->imm.value == get_optional_operand_default_value (opcode))
+       break;
+      enum_value = opnd->imm.value;
+      assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
+      if (aarch64_sve_pattern_array[enum_value])
+       snprintf (buf, size, "%s", aarch64_sve_pattern_array[enum_value]);
+      else
+       snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
+      break;
+
+    case AARCH64_OPND_SVE_PATTERN_SCALED:
+      if (optional_operand_p (opcode, idx)
+         && !opnd->shifter.operator_present
+         && opnd->imm.value == get_optional_operand_default_value (opcode))
+       break;
+      enum_value = opnd->imm.value;
+      assert (enum_value < ARRAY_SIZE (aarch64_sve_pattern_array));
+      if (aarch64_sve_pattern_array[opnd->imm.value])
+       snprintf (buf, size, "%s", aarch64_sve_pattern_array[opnd->imm.value]);
+      else
+       snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
+      if (opnd->shifter.operator_present)
+       {
+         size_t len = strlen (buf);
+         snprintf (buf + len, size - len, ", %s #%" PRIi64,
+                   aarch64_operand_modifiers[opnd->shifter.kind].name,
+                   opnd->shifter.amount);
+       }
+      break;
+
+    case AARCH64_OPND_SVE_PRFOP:
+      enum_value = opnd->imm.value;
+      assert (enum_value < ARRAY_SIZE (aarch64_sve_prfop_array));
+      if (aarch64_sve_prfop_array[enum_value])
+       snprintf (buf, size, "%s", aarch64_sve_prfop_array[enum_value]);
+      else
+       snprintf (buf, size, "#%" PRIi64, opnd->imm.value);
+      break;
+
     case AARCH64_OPND_IMM_MOV:
       switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
        {
     case AARCH64_OPND_IMM_MOV:
       switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
        {
@@ -2461,7 +2838,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
     case AARCH64_OPND_AIMM:
     case AARCH64_OPND_HALF:
       if (opnd->shifter.amount)
     case AARCH64_OPND_AIMM:
     case AARCH64_OPND_HALF:
       if (opnd->shifter.amount)
-       snprintf (buf, size, "#0x%" PRIx64 ", lsl #%d", opnd->imm.value,
+       snprintf (buf, size, "#0x%" PRIx64 ", lsl #%" PRIi64, opnd->imm.value,
                  opnd->shifter.amount);
       else
        snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
                  opnd->shifter.amount);
       else
        snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
@@ -2473,7 +2850,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
          || opnd->shifter.kind == AARCH64_MOD_NONE)
        snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
       else
          || opnd->shifter.kind == AARCH64_MOD_NONE)
        snprintf (buf, size, "#0x%" PRIx64, opnd->imm.value);
       else
-       snprintf (buf, size, "#0x%" PRIx64 ", %s #%d", opnd->imm.value,
+       snprintf (buf, size, "#0x%" PRIx64 ", %s #%" PRIi64, opnd->imm.value,
                  aarch64_operand_modifiers[opnd->shifter.kind].name,
                  opnd->shifter.amount);
       break;
                  aarch64_operand_modifiers[opnd->shifter.kind].name,
                  opnd->shifter.amount);
       break;
@@ -2482,17 +2859,24 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
     case AARCH64_OPND_SIMD_FPIMM:
       switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
        {
     case AARCH64_OPND_SIMD_FPIMM:
       switch (aarch64_get_qualifier_esize (opnds[0].qualifier))
        {
+       case 2: /* e.g. FMOV <Hd>, #<imm>.  */
+           {
+             half_conv_t c;
+             c.i = expand_fp_imm (2, opnd->imm.value);
+             snprintf (buf, size,  "#%.18e", c.f);
+           }
+         break;
        case 4: /* e.g. FMOV <Vd>.4S, #<imm>.  */
            {
              single_conv_t c;
        case 4: /* e.g. FMOV <Vd>.4S, #<imm>.  */
            {
              single_conv_t c;
-             c.i = expand_fp_imm (0, opnd->imm.value);
+             c.i = expand_fp_imm (4, opnd->imm.value);
              snprintf (buf, size,  "#%.18e", c.f);
            }
          break;
        case 8: /* e.g. FMOV <Sd>, #<imm>.  */
            {
              double_conv_t c;
              snprintf (buf, size,  "#%.18e", c.f);
            }
          break;
        case 8: /* e.g. FMOV <Sd>, #<imm>.  */
            {
              double_conv_t c;
-             c.i = expand_fp_imm (1, opnd->imm.value);
+             c.i = expand_fp_imm (8, opnd->imm.value);
              snprintf (buf, size,  "#%.18e", c.d);
            }
          break;
              snprintf (buf, size,  "#%.18e", c.d);
            }
          break;
@@ -2514,6 +2898,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
       break;
 
     case AARCH64_OPND_COND:
       break;
 
     case AARCH64_OPND_COND:
+    case AARCH64_OPND_COND1:
       snprintf (buf, size, "%s", opnd->cond->names[0]);
       break;
 
       snprintf (buf, size, "%s", opnd->cond->names[0]);
       break;
 
@@ -2563,27 +2948,16 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
       break;
 
     case AARCH64_OPND_ADDR_REGOFF:
       break;
 
     case AARCH64_OPND_ADDR_REGOFF:
-      print_register_offset_address (buf, size, opnd);
+      print_register_offset_address
+       (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1),
+        get_offset_int_reg_name (opnd));
       break;
 
     case AARCH64_OPND_ADDR_SIMM7:
     case AARCH64_OPND_ADDR_SIMM9:
     case AARCH64_OPND_ADDR_SIMM9_2:
       break;
 
     case AARCH64_OPND_ADDR_SIMM7:
     case AARCH64_OPND_ADDR_SIMM9:
     case AARCH64_OPND_ADDR_SIMM9_2:
-      name = get_64bit_int_reg_name (opnd->addr.base_regno, 1);
-      if (opnd->addr.writeback)
-       {
-         if (opnd->addr.preind)
-           snprintf (buf, size, "[%s,#%d]!", name, opnd->addr.offset.imm);
-         else
-           snprintf (buf, size, "[%s],#%d", name, opnd->addr.offset.imm);
-       }
-      else
-       {
-         if (opnd->addr.offset.imm)
-           snprintf (buf, size, "[%s,#%d]", name, opnd->addr.offset.imm);
-         else
-           snprintf (buf, size, "[%s]", name);
-       }
+      print_immediate_offset_address
+       (buf, size, opnd, get_64bit_int_reg_name (opnd->addr.base_regno, 1));
       break;
 
     case AARCH64_OPND_ADDR_UIMM12:
       break;
 
     case AARCH64_OPND_ADDR_UIMM12:
@@ -2596,7 +2970,8 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
 
     case AARCH64_OPND_SYSREG:
       for (i = 0; aarch64_sys_regs[i].name; ++i)
 
     case AARCH64_OPND_SYSREG:
       for (i = 0; aarch64_sys_regs[i].name; ++i)
-       if (aarch64_sys_regs[i].value == opnd->sysreg)
+       if (aarch64_sys_regs[i].value == opnd->sysreg
+           && ! aarch64_sys_reg_deprecated_p (&aarch64_sys_regs[i]))
          break;
       if (aarch64_sys_regs[i].name)
        snprintf (buf, size, "%s", aarch64_sys_regs[i].name);
          break;
       if (aarch64_sys_regs[i].name)
        snprintf (buf, size, "%s", aarch64_sys_regs[i].name);
@@ -2622,7 +2997,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
     case AARCH64_OPND_SYSREG_DC:
     case AARCH64_OPND_SYSREG_IC:
     case AARCH64_OPND_SYSREG_TLBI:
     case AARCH64_OPND_SYSREG_DC:
     case AARCH64_OPND_SYSREG_IC:
     case AARCH64_OPND_SYSREG_TLBI:
-      snprintf (buf, size, "%s", opnd->sysins_op->template);
+      snprintf (buf, size, "%s", opnd->sysins_op->name);
       break;
 
     case AARCH64_OPND_BARRIER:
       break;
 
     case AARCH64_OPND_BARRIER:
@@ -2644,6 +3019,10 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
        snprintf (buf, size, "#0x%02x", opnd->prfop->value);
       break;
 
        snprintf (buf, size, "#0x%02x", opnd->prfop->value);
       break;
 
+    case AARCH64_OPND_BARRIER_PSB:
+      snprintf (buf, size, "%s", opnd->hint_option->name);
+      break;
+
     default:
       assert (0);
     }
     default:
       assert (0);
     }
@@ -2673,403 +3052,639 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
 #define C14 14
 #define C15 15
 
 #define C14 14
 #define C15 15
 
+#ifdef F_DEPRECATED
+#undef F_DEPRECATED
+#endif
+#define F_DEPRECATED   0x1     /* Deprecated system register.  */
+
+#ifdef F_ARCHEXT
+#undef F_ARCHEXT
+#endif
+#define F_ARCHEXT      0x2     /* Architecture dependent system register.  */
+
+#ifdef F_HASXT
+#undef F_HASXT
+#endif
+#define F_HASXT                0x4     /* System instruction register <Xt>
+                                  operand.  */
+
+
 /* TODO there are two more issues need to be resolved
    1. handle read-only and write-only system registers
    2. handle cpu-implementation-defined system registers.  */
 /* TODO there are two more issues need to be resolved
    1. handle read-only and write-only system registers
    2. handle cpu-implementation-defined system registers.  */
-const struct aarch64_name_value_pair aarch64_sys_regs [] =
-{
-  { "spsr_el1",         CPEN_(0,C0,0)  }, /* = spsr_svc */
-  { "elr_el1",          CPEN_(0,C0,1)  },
-  { "sp_el0",           CPEN_(0,C1,0)  },
-  { "spsel",            CPEN_(0,C2,0)  },
-  { "daif",             CPEN_(3,C2,1)  },
-  { "currentel",        CPEN_(0,C2,2)  }, /* RO */
-  { "nzcv",             CPEN_(3,C2,0)  },
-  { "fpcr",             CPEN_(3,C4,0)  },
-  { "fpsr",             CPEN_(3,C4,1)  },
-  { "dspsr_el0",        CPEN_(3,C5,0)  },
-  { "dlr_el0",          CPEN_(3,C5,1)  },
-  { "spsr_el2",         CPEN_(4,C0,0)  }, /* = spsr_hyp */
-  { "elr_el2",          CPEN_(4,C0,1)  },
-  { "sp_el1",           CPEN_(4,C1,0)  },
-  { "spsr_irq",         CPEN_(4,C3,0)  },
-  { "spsr_abt",         CPEN_(4,C3,1)  },
-  { "spsr_und",         CPEN_(4,C3,2)  },
-  { "spsr_fiq",         CPEN_(4,C3,3)  },
-  { "spsr_el3",         CPEN_(6,C0,0)  },
-  { "elr_el3",          CPEN_(6,C0,1)  },
-  { "sp_el2",           CPEN_(6,C1,0)  },
-  { "spsr_svc",         CPEN_(0,C0,0)  }, /* = spsr_el1 */
-  { "spsr_hyp",         CPEN_(4,C0,0)  }, /* = spsr_el2 */
-  { "midr_el1",         CPENC(3,0,C0,C0,0)  }, /* RO */
-  { "ctr_el0",          CPENC(3,3,C0,C0,1)  }, /* RO */
-  { "mpidr_el1",        CPENC(3,0,C0,C0,5)  }, /* RO */
-  { "revidr_el1",       CPENC(3,0,C0,C0,6)  }, /* RO */
-  { "aidr_el1",         CPENC(3,1,C0,C0,7)  }, /* RO */
-  { "dczid_el0",        CPENC(3,3,C0,C0,7)  }, /* RO */
-  { "id_dfr0_el1",      CPENC(3,0,C0,C1,2)  }, /* RO */
-  { "id_pfr0_el1",      CPENC(3,0,C0,C1,0)  }, /* RO */
-  { "id_pfr1_el1",      CPENC(3,0,C0,C1,1)  }, /* RO */
-  { "id_afr0_el1",      CPENC(3,0,C0,C1,3)  }, /* RO */
-  { "id_mmfr0_el1",     CPENC(3,0,C0,C1,4)  }, /* RO */
-  { "id_mmfr1_el1",     CPENC(3,0,C0,C1,5)  }, /* RO */
-  { "id_mmfr2_el1",     CPENC(3,0,C0,C1,6)  }, /* RO */
-  { "id_mmfr3_el1",     CPENC(3,0,C0,C1,7)  }, /* RO */
-  { "id_isar0_el1",     CPENC(3,0,C0,C2,0)  }, /* RO */
-  { "id_isar1_el1",     CPENC(3,0,C0,C2,1)  }, /* RO */
-  { "id_isar2_el1",     CPENC(3,0,C0,C2,2)  }, /* RO */
-  { "id_isar3_el1",     CPENC(3,0,C0,C2,3)  }, /* RO */
-  { "id_isar4_el1",     CPENC(3,0,C0,C2,4)  }, /* RO */
-  { "id_isar5_el1",     CPENC(3,0,C0,C2,5)  }, /* RO */
-  { "mvfr0_el1",        CPENC(3,0,C0,C3,0)  }, /* RO */
-  { "mvfr1_el1",        CPENC(3,0,C0,C3,1)  }, /* RO */
-  { "mvfr2_el1",        CPENC(3,0,C0,C3,2)  }, /* RO */
-  { "ccsidr_el1",       CPENC(3,1,C0,C0,0)  }, /* RO */
-  { "id_aa64pfr0_el1",  CPENC(3,0,C0,C4,0)  }, /* RO */
-  { "id_aa64pfr1_el1",  CPENC(3,0,C0,C4,1)  }, /* RO */
-  { "id_aa64dfr0_el1",  CPENC(3,0,C0,C5,0)  }, /* RO */
-  { "id_aa64dfr1_el1",  CPENC(3,0,C0,C5,1)  }, /* RO */
-  { "id_aa64isar0_el1", CPENC(3,0,C0,C6,0)  }, /* RO */
-  { "id_aa64isar1_el1", CPENC(3,0,C0,C6,1)  }, /* RO */
-  { "id_aa64mmfr0_el1", CPENC(3,0,C0,C7,0)  }, /* RO */
-  { "id_aa64mmfr1_el1", CPENC(3,0,C0,C7,1)  }, /* RO */
-  { "id_aa64afr0_el1",  CPENC(3,0,C0,C5,4)  }, /* RO */
-  { "id_aa64afr1_el1",  CPENC(3,0,C0,C5,5)  }, /* RO */
-  { "clidr_el1",        CPENC(3,1,C0,C0,1)  }, /* RO */
-  { "csselr_el1",       CPENC(3,2,C0,C0,0)  }, /* RO */
-  { "vpidr_el2",        CPENC(3,4,C0,C0,0)  },
-  { "vmpidr_el2",       CPENC(3,4,C0,C0,5)  },
-  { "sctlr_el1",        CPENC(3,0,C1,C0,0)  },
-  { "sctlr_el2",        CPENC(3,4,C1,C0,0)  },
-  { "sctlr_el3",        CPENC(3,6,C1,C0,0)  },
-  { "actlr_el1",        CPENC(3,0,C1,C0,1)  },
-  { "actlr_el2",        CPENC(3,4,C1,C0,1)  },
-  { "actlr_el3",        CPENC(3,6,C1,C0,1)  },
-  { "cpacr_el1",        CPENC(3,0,C1,C0,2)  },
-  { "cptr_el2",         CPENC(3,4,C1,C1,2)  },
-  { "cptr_el3",         CPENC(3,6,C1,C1,2)  },
-  { "scr_el3",          CPENC(3,6,C1,C1,0)  },
-  { "hcr_el2",          CPENC(3,4,C1,C1,0)  },
-  { "mdcr_el2",         CPENC(3,4,C1,C1,1)  },
-  { "mdcr_el3",         CPENC(3,6,C1,C3,1)  },
-  { "hstr_el2",         CPENC(3,4,C1,C1,3)  },
-  { "hacr_el2",         CPENC(3,4,C1,C1,7)  },
-  { "ttbr0_el1",        CPENC(3,0,C2,C0,0)  },
-  { "ttbr1_el1",        CPENC(3,0,C2,C0,1)  },
-  { "ttbr0_el2",        CPENC(3,4,C2,C0,0)  },
-  { "ttbr0_el3",        CPENC(3,6,C2,C0,0)  },
-  { "vttbr_el2",        CPENC(3,4,C2,C1,0)  },
-  { "tcr_el1",          CPENC(3,0,C2,C0,2)  },
-  { "tcr_el2",          CPENC(3,4,C2,C0,2)  },
-  { "tcr_el3",          CPENC(3,6,C2,C0,2)  },
-  { "vtcr_el2",         CPENC(3,4,C2,C1,2)  },
-  { "afsr0_el1",        CPENC(3,0,C5,C1,0)  },
-  { "afsr1_el1",        CPENC(3,0,C5,C1,1)  },
-  { "afsr0_el2",        CPENC(3,4,C5,C1,0)  },
-  { "afsr1_el2",        CPENC(3,4,C5,C1,1)  },
-  { "afsr0_el3",        CPENC(3,6,C5,C1,0)  },
-  { "afsr1_el3",        CPENC(3,6,C5,C1,1)  },
-  { "esr_el1",          CPENC(3,0,C5,C2,0)  },
-  { "esr_el2",          CPENC(3,4,C5,C2,0)  },
-  { "esr_el3",          CPENC(3,6,C5,C2,0)  },
-  { "fpexc32_el2",      CPENC(3,4,C5,C3,0)  },
-  { "far_el1",          CPENC(3,0,C6,C0,0)  },
-  { "far_el2",          CPENC(3,4,C6,C0,0)  },
-  { "far_el3",          CPENC(3,6,C6,C0,0)  },
-  { "hpfar_el2",        CPENC(3,4,C6,C0,4)  },
-  { "par_el1",          CPENC(3,0,C7,C4,0)  },
-  { "mair_el1",         CPENC(3,0,C10,C2,0) },
-  { "mair_el2",         CPENC(3,4,C10,C2,0) },
-  { "mair_el3",         CPENC(3,6,C10,C2,0) },
-  { "amair_el1",        CPENC(3,0,C10,C3,0) },
-  { "amair_el2",        CPENC(3,4,C10,C3,0) },
-  { "amair_el3",        CPENC(3,6,C10,C3,0) },
-  { "vbar_el1",         CPENC(3,0,C12,C0,0) },
-  { "vbar_el2",         CPENC(3,4,C12,C0,0) },
-  { "vbar_el3",         CPENC(3,6,C12,C0,0) },
-  { "rvbar_el1",        CPENC(3,0,C12,C0,1) }, /* RO */
-  { "rvbar_el2",        CPENC(3,4,C12,C0,1) }, /* RO */
-  { "rvbar_el3",        CPENC(3,6,C12,C0,1) }, /* RO */
-  { "rmr_el1",          CPENC(3,0,C12,C0,2) },
-  { "rmr_el2",          CPENC(3,4,C12,C0,2) },
-  { "rmr_el3",          CPENC(3,6,C12,C0,2) },
-  { "isr_el1",          CPENC(3,0,C12,C1,0) }, /* RO */
-  { "contextidr_el1",   CPENC(3,0,C13,C0,1) },
-  { "tpidr_el0",        CPENC(3,3,C13,C0,2) },
-  { "tpidrro_el0",      CPENC(3,3,C13,C0,3) }, /* RO */
-  { "tpidr_el1",        CPENC(3,0,C13,C0,4) },
-  { "tpidr_el2",        CPENC(3,4,C13,C0,2) },
-  { "tpidr_el3",        CPENC(3,6,C13,C0,2) },
-  { "teecr32_el1",      CPENC(2,2,C0, C0,0) }, /* See section 3.9.7.1 */
-  { "cntfrq_el0",       CPENC(3,3,C14,C0,0) }, /* RO */
-  { "cntpct_el0",       CPENC(3,3,C14,C0,1) }, /* RO */
-  { "cntvct_el0",       CPENC(3,3,C14,C0,2) }, /* RO */
-  { "cntvoff_el2",      CPENC(3,4,C14,C0,3) },
-  { "cntkctl_el1",      CPENC(3,0,C14,C1,0) },
-  { "cnthctl_el2",      CPENC(3,4,C14,C1,0) },
-  { "cntp_tval_el0",    CPENC(3,3,C14,C2,0) },
-  { "cntp_ctl_el0",     CPENC(3,3,C14,C2,1) },
-  { "cntp_cval_el0",    CPENC(3,3,C14,C2,2) },
-  { "cntv_tval_el0",    CPENC(3,3,C14,C3,0) },
-  { "cntv_ctl_el0",     CPENC(3,3,C14,C3,1) },
-  { "cntv_cval_el0",    CPENC(3,3,C14,C3,2) },
-  { "cnthp_tval_el2",   CPENC(3,4,C14,C2,0) },
-  { "cnthp_ctl_el2",    CPENC(3,4,C14,C2,1) },
-  { "cnthp_cval_el2",   CPENC(3,4,C14,C2,2) },
-  { "cntps_tval_el1",   CPENC(3,7,C14,C2,0) },
-  { "cntps_ctl_el1",    CPENC(3,7,C14,C2,1) },
-  { "cntps_cval_el1",   CPENC(3,7,C14,C2,2) },
-  { "dacr32_el2",       CPENC(3,4,C3,C0,0)  },
-  { "ifsr32_el2",       CPENC(3,4,C5,C0,1)  },
-  { "teehbr32_el1",     CPENC(2,2,C1,C0,0)  },
-  { "sder32_el3",       CPENC(3,6,C1,C1,1)  },
-  { "mdscr_el1",         CPENC(2,0,C0, C2, 2) },
-  { "mdccsr_el0",        CPENC(2,3,C0, C1, 0) },  /* r */
-  { "mdccint_el1",       CPENC(2,0,C0, C2, 0) },
-  { "dbgdtr_el0",        CPENC(2,3,C0, C4, 0) },
-  { "dbgdtrrx_el0",      CPENC(2,3,C0, C5, 0) },  /* r */
-  { "dbgdtrtx_el0",      CPENC(2,3,C0, C5, 0) },  /* w */
-  { "osdtrrx_el1",       CPENC(2,0,C0, C0, 2) },  /* r */
-  { "osdtrtx_el1",       CPENC(2,0,C0, C3, 2) },  /* w */
-  { "oseccr_el1",        CPENC(2,0,C0, C6, 2) },
-  { "dbgvcr32_el2",      CPENC(2,4,C0, C7, 0) },
-  { "dbgbvr0_el1",       CPENC(2,0,C0, C0, 4) },
-  { "dbgbvr1_el1",       CPENC(2,0,C0, C1, 4) },
-  { "dbgbvr2_el1",       CPENC(2,0,C0, C2, 4) },
-  { "dbgbvr3_el1",       CPENC(2,0,C0, C3, 4) },
-  { "dbgbvr4_el1",       CPENC(2,0,C0, C4, 4) },
-  { "dbgbvr5_el1",       CPENC(2,0,C0, C5, 4) },
-  { "dbgbvr6_el1",       CPENC(2,0,C0, C6, 4) },
-  { "dbgbvr7_el1",       CPENC(2,0,C0, C7, 4) },
-  { "dbgbvr8_el1",       CPENC(2,0,C0, C8, 4) },
-  { "dbgbvr9_el1",       CPENC(2,0,C0, C9, 4) },
-  { "dbgbvr10_el1",      CPENC(2,0,C0, C10,4) },
-  { "dbgbvr11_el1",      CPENC(2,0,C0, C11,4) },
-  { "dbgbvr12_el1",      CPENC(2,0,C0, C12,4) },
-  { "dbgbvr13_el1",      CPENC(2,0,C0, C13,4) },
-  { "dbgbvr14_el1",      CPENC(2,0,C0, C14,4) },
-  { "dbgbvr15_el1",      CPENC(2,0,C0, C15,4) },
-  { "dbgbcr0_el1",       CPENC(2,0,C0, C0, 5) },
-  { "dbgbcr1_el1",       CPENC(2,0,C0, C1, 5) },
-  { "dbgbcr2_el1",       CPENC(2,0,C0, C2, 5) },
-  { "dbgbcr3_el1",       CPENC(2,0,C0, C3, 5) },
-  { "dbgbcr4_el1",       CPENC(2,0,C0, C4, 5) },
-  { "dbgbcr5_el1",       CPENC(2,0,C0, C5, 5) },
-  { "dbgbcr6_el1",       CPENC(2,0,C0, C6, 5) },
-  { "dbgbcr7_el1",       CPENC(2,0,C0, C7, 5) },
-  { "dbgbcr8_el1",       CPENC(2,0,C0, C8, 5) },
-  { "dbgbcr9_el1",       CPENC(2,0,C0, C9, 5) },
-  { "dbgbcr10_el1",      CPENC(2,0,C0, C10,5) },
-  { "dbgbcr11_el1",      CPENC(2,0,C0, C11,5) },
-  { "dbgbcr12_el1",      CPENC(2,0,C0, C12,5) },
-  { "dbgbcr13_el1",      CPENC(2,0,C0, C13,5) },
-  { "dbgbcr14_el1",      CPENC(2,0,C0, C14,5) },
-  { "dbgbcr15_el1",      CPENC(2,0,C0, C15,5) },
-  { "dbgwvr0_el1",       CPENC(2,0,C0, C0, 6) },
-  { "dbgwvr1_el1",       CPENC(2,0,C0, C1, 6) },
-  { "dbgwvr2_el1",       CPENC(2,0,C0, C2, 6) },
-  { "dbgwvr3_el1",       CPENC(2,0,C0, C3, 6) },
-  { "dbgwvr4_el1",       CPENC(2,0,C0, C4, 6) },
-  { "dbgwvr5_el1",       CPENC(2,0,C0, C5, 6) },
-  { "dbgwvr6_el1",       CPENC(2,0,C0, C6, 6) },
-  { "dbgwvr7_el1",       CPENC(2,0,C0, C7, 6) },
-  { "dbgwvr8_el1",       CPENC(2,0,C0, C8, 6) },
-  { "dbgwvr9_el1",       CPENC(2,0,C0, C9, 6) },
-  { "dbgwvr10_el1",      CPENC(2,0,C0, C10,6) },
-  { "dbgwvr11_el1",      CPENC(2,0,C0, C11,6) },
-  { "dbgwvr12_el1",      CPENC(2,0,C0, C12,6) },
-  { "dbgwvr13_el1",      CPENC(2,0,C0, C13,6) },
-  { "dbgwvr14_el1",      CPENC(2,0,C0, C14,6) },
-  { "dbgwvr15_el1",      CPENC(2,0,C0, C15,6) },
-  { "dbgwcr0_el1",       CPENC(2,0,C0, C0, 7) },
-  { "dbgwcr1_el1",       CPENC(2,0,C0, C1, 7) },
-  { "dbgwcr2_el1",       CPENC(2,0,C0, C2, 7) },
-  { "dbgwcr3_el1",       CPENC(2,0,C0, C3, 7) },
-  { "dbgwcr4_el1",       CPENC(2,0,C0, C4, 7) },
-  { "dbgwcr5_el1",       CPENC(2,0,C0, C5, 7) },
-  { "dbgwcr6_el1",       CPENC(2,0,C0, C6, 7) },
-  { "dbgwcr7_el1",       CPENC(2,0,C0, C7, 7) },
-  { "dbgwcr8_el1",       CPENC(2,0,C0, C8, 7) },
-  { "dbgwcr9_el1",       CPENC(2,0,C0, C9, 7) },
-  { "dbgwcr10_el1",      CPENC(2,0,C0, C10,7) },
-  { "dbgwcr11_el1",      CPENC(2,0,C0, C11,7) },
-  { "dbgwcr12_el1",      CPENC(2,0,C0, C12,7) },
-  { "dbgwcr13_el1",      CPENC(2,0,C0, C13,7) },
-  { "dbgwcr14_el1",      CPENC(2,0,C0, C14,7) },
-  { "dbgwcr15_el1",      CPENC(2,0,C0, C15,7) },
-  { "mdrar_el1",         CPENC(2,0,C1, C0, 0) },  /* r */
-  { "oslar_el1",         CPENC(2,0,C1, C0, 4) },  /* w */
-  { "oslsr_el1",         CPENC(2,0,C1, C1, 4) },  /* r */
-  { "osdlr_el1",         CPENC(2,0,C1, C3, 4) },
-  { "dbgprcr_el1",       CPENC(2,0,C1, C4, 4) },
-  { "dbgclaimset_el1",   CPENC(2,0,C7, C8, 6) },
-  { "dbgclaimclr_el1",   CPENC(2,0,C7, C9, 6) },
-  { "dbgauthstatus_el1", CPENC(2,0,C7, C14,6) },  /* r */
-
-  { "pmcr_el0",          CPENC(3,3,C9,C12, 0) },
-  { "pmcntenset_el0",    CPENC(3,3,C9,C12, 1) },
-  { "pmcntenclr_el0",    CPENC(3,3,C9,C12, 2) },
-  { "pmovsclr_el0",      CPENC(3,3,C9,C12, 3) },
-  { "pmswinc_el0",       CPENC(3,3,C9,C12, 4) },  /* w */
-  { "pmselr_el0",        CPENC(3,3,C9,C12, 5) },
-  { "pmceid0_el0",       CPENC(3,3,C9,C12, 6) },  /* r */
-  { "pmceid1_el0",       CPENC(3,3,C9,C12, 7) },  /* r */
-  { "pmccntr_el0",       CPENC(3,3,C9,C13, 0) },
-  { "pmxevtyper_el0",    CPENC(3,3,C9,C13, 1) },
-  { "pmxevcntr_el0",     CPENC(3,3,C9,C13, 2) },
-  { "pmuserenr_el0",     CPENC(3,3,C9,C14, 0) },
-  { "pmintenset_el1",    CPENC(3,0,C9,C14, 1) },
-  { "pmintenclr_el1",    CPENC(3,0,C9,C14, 2) },
-  { "pmovsset_el0",      CPENC(3,3,C9,C14, 3) },
-  { "pmevcntr0_el0",     CPENC(3,3,C14,C8, 0) },
-  { "pmevcntr1_el0",     CPENC(3,3,C14,C8, 1) },
-  { "pmevcntr2_el0",     CPENC(3,3,C14,C8, 2) },
-  { "pmevcntr3_el0",     CPENC(3,3,C14,C8, 3) },
-  { "pmevcntr4_el0",     CPENC(3,3,C14,C8, 4) },
-  { "pmevcntr5_el0",     CPENC(3,3,C14,C8, 5) },
-  { "pmevcntr6_el0",     CPENC(3,3,C14,C8, 6) },
-  { "pmevcntr7_el0",     CPENC(3,3,C14,C8, 7) },
-  { "pmevcntr8_el0",     CPENC(3,3,C14,C9, 0) },
-  { "pmevcntr9_el0",     CPENC(3,3,C14,C9, 1) },
-  { "pmevcntr10_el0",    CPENC(3,3,C14,C9, 2) },
-  { "pmevcntr11_el0",    CPENC(3,3,C14,C9, 3) },
-  { "pmevcntr12_el0",    CPENC(3,3,C14,C9, 4) },
-  { "pmevcntr13_el0",    CPENC(3,3,C14,C9, 5) },
-  { "pmevcntr14_el0",    CPENC(3,3,C14,C9, 6) },
-  { "pmevcntr15_el0",    CPENC(3,3,C14,C9, 7) },
-  { "pmevcntr16_el0",    CPENC(3,3,C14,C10,0) },
-  { "pmevcntr17_el0",    CPENC(3,3,C14,C10,1) },
-  { "pmevcntr18_el0",    CPENC(3,3,C14,C10,2) },
-  { "pmevcntr19_el0",    CPENC(3,3,C14,C10,3) },
-  { "pmevcntr20_el0",    CPENC(3,3,C14,C10,4) },
-  { "pmevcntr21_el0",    CPENC(3,3,C14,C10,5) },
-  { "pmevcntr22_el0",    CPENC(3,3,C14,C10,6) },
-  { "pmevcntr23_el0",    CPENC(3,3,C14,C10,7) },
-  { "pmevcntr24_el0",    CPENC(3,3,C14,C11,0) },
-  { "pmevcntr25_el0",    CPENC(3,3,C14,C11,1) },
-  { "pmevcntr26_el0",    CPENC(3,3,C14,C11,2) },
-  { "pmevcntr27_el0",    CPENC(3,3,C14,C11,3) },
-  { "pmevcntr28_el0",    CPENC(3,3,C14,C11,4) },
-  { "pmevcntr29_el0",    CPENC(3,3,C14,C11,5) },
-  { "pmevcntr30_el0",    CPENC(3,3,C14,C11,6) },
-  { "pmevtyper0_el0",    CPENC(3,3,C14,C12,0) },
-  { "pmevtyper1_el0",    CPENC(3,3,C14,C12,1) },
-  { "pmevtyper2_el0",    CPENC(3,3,C14,C12,2) },
-  { "pmevtyper3_el0",    CPENC(3,3,C14,C12,3) },
-  { "pmevtyper4_el0",    CPENC(3,3,C14,C12,4) },
-  { "pmevtyper5_el0",    CPENC(3,3,C14,C12,5) },
-  { "pmevtyper6_el0",    CPENC(3,3,C14,C12,6) },
-  { "pmevtyper7_el0",    CPENC(3,3,C14,C12,7) },
-  { "pmevtyper8_el0",    CPENC(3,3,C14,C13,0) },
-  { "pmevtyper9_el0",    CPENC(3,3,C14,C13,1) },
-  { "pmevtyper10_el0",   CPENC(3,3,C14,C13,2) },
-  { "pmevtyper11_el0",   CPENC(3,3,C14,C13,3) },
-  { "pmevtyper12_el0",   CPENC(3,3,C14,C13,4) },
-  { "pmevtyper13_el0",   CPENC(3,3,C14,C13,5) },
-  { "pmevtyper14_el0",   CPENC(3,3,C14,C13,6) },
-  { "pmevtyper15_el0",   CPENC(3,3,C14,C13,7) },
-  { "pmevtyper16_el0",   CPENC(3,3,C14,C14,0) },
-  { "pmevtyper17_el0",   CPENC(3,3,C14,C14,1) },
-  { "pmevtyper18_el0",   CPENC(3,3,C14,C14,2) },
-  { "pmevtyper19_el0",   CPENC(3,3,C14,C14,3) },
-  { "pmevtyper20_el0",   CPENC(3,3,C14,C14,4) },
-  { "pmevtyper21_el0",   CPENC(3,3,C14,C14,5) },
-  { "pmevtyper22_el0",   CPENC(3,3,C14,C14,6) },
-  { "pmevtyper23_el0",   CPENC(3,3,C14,C14,7) },
-  { "pmevtyper24_el0",   CPENC(3,3,C14,C15,0) },
-  { "pmevtyper25_el0",   CPENC(3,3,C14,C15,1) },
-  { "pmevtyper26_el0",   CPENC(3,3,C14,C15,2) },
-  { "pmevtyper27_el0",   CPENC(3,3,C14,C15,3) },
-  { "pmevtyper28_el0",   CPENC(3,3,C14,C15,4) },
-  { "pmevtyper29_el0",   CPENC(3,3,C14,C15,5) },
-  { "pmevtyper30_el0",   CPENC(3,3,C14,C15,6) },
-  { "pmccfiltr_el0",     CPENC(3,3,C14,C15,7) },
-  { 0,          CPENC(0,0,0,0,0)  },
+const aarch64_sys_reg aarch64_sys_regs [] =
+{
+  { "spsr_el1",         CPEN_(0,C0,0), 0 }, /* = spsr_svc */
+  { "spsr_el12",       CPEN_ (5, C0, 0), F_ARCHEXT },
+  { "elr_el1",          CPEN_(0,C0,1), 0 },
+  { "elr_el12",        CPEN_ (5, C0, 1), F_ARCHEXT },
+  { "sp_el0",           CPEN_(0,C1,0), 0 },
+  { "spsel",            CPEN_(0,C2,0), 0 },
+  { "daif",             CPEN_(3,C2,1), 0 },
+  { "currentel",        CPEN_(0,C2,2), 0 }, /* RO */
+  { "pan",             CPEN_(0,C2,3),  F_ARCHEXT },
+  { "uao",             CPEN_ (0, C2, 4), F_ARCHEXT },
+  { "nzcv",             CPEN_(3,C2,0), 0 },
+  { "fpcr",             CPEN_(3,C4,0), 0 },
+  { "fpsr",             CPEN_(3,C4,1), 0 },
+  { "dspsr_el0",        CPEN_(3,C5,0), 0 },
+  { "dlr_el0",          CPEN_(3,C5,1), 0 },
+  { "spsr_el2",         CPEN_(4,C0,0), 0 }, /* = spsr_hyp */
+  { "elr_el2",          CPEN_(4,C0,1), 0 },
+  { "sp_el1",           CPEN_(4,C1,0), 0 },
+  { "spsr_irq",         CPEN_(4,C3,0), 0 },
+  { "spsr_abt",         CPEN_(4,C3,1), 0 },
+  { "spsr_und",         CPEN_(4,C3,2), 0 },
+  { "spsr_fiq",         CPEN_(4,C3,3), 0 },
+  { "spsr_el3",         CPEN_(6,C0,0), 0 },
+  { "elr_el3",          CPEN_(6,C0,1), 0 },
+  { "sp_el2",           CPEN_(6,C1,0), 0 },
+  { "spsr_svc",         CPEN_(0,C0,0), F_DEPRECATED }, /* = spsr_el1 */
+  { "spsr_hyp",         CPEN_(4,C0,0), F_DEPRECATED }, /* = spsr_el2 */
+  { "midr_el1",         CPENC(3,0,C0,C0,0),    0 }, /* RO */
+  { "ctr_el0",          CPENC(3,3,C0,C0,1),    0 }, /* RO */
+  { "mpidr_el1",        CPENC(3,0,C0,C0,5),    0 }, /* RO */
+  { "revidr_el1",       CPENC(3,0,C0,C0,6),    0 }, /* RO */
+  { "aidr_el1",         CPENC(3,1,C0,C0,7),    0 }, /* RO */
+  { "dczid_el0",        CPENC(3,3,C0,C0,7),    0 }, /* RO */
+  { "id_dfr0_el1",      CPENC(3,0,C0,C1,2),    0 }, /* RO */
+  { "id_pfr0_el1",      CPENC(3,0,C0,C1,0),    0 }, /* RO */
+  { "id_pfr1_el1",      CPENC(3,0,C0,C1,1),    0 }, /* RO */
+  { "id_afr0_el1",      CPENC(3,0,C0,C1,3),    0 }, /* RO */
+  { "id_mmfr0_el1",     CPENC(3,0,C0,C1,4),    0 }, /* RO */
+  { "id_mmfr1_el1",     CPENC(3,0,C0,C1,5),    0 }, /* RO */
+  { "id_mmfr2_el1",     CPENC(3,0,C0,C1,6),    0 }, /* RO */
+  { "id_mmfr3_el1",     CPENC(3,0,C0,C1,7),    0 }, /* RO */
+  { "id_mmfr4_el1",     CPENC(3,0,C0,C2,6),    0 }, /* RO */
+  { "id_isar0_el1",     CPENC(3,0,C0,C2,0),    0 }, /* RO */
+  { "id_isar1_el1",     CPENC(3,0,C0,C2,1),    0 }, /* RO */
+  { "id_isar2_el1",     CPENC(3,0,C0,C2,2),    0 }, /* RO */
+  { "id_isar3_el1",     CPENC(3,0,C0,C2,3),    0 }, /* RO */
+  { "id_isar4_el1",     CPENC(3,0,C0,C2,4),    0 }, /* RO */
+  { "id_isar5_el1",     CPENC(3,0,C0,C2,5),    0 }, /* RO */
+  { "mvfr0_el1",        CPENC(3,0,C0,C3,0),    0 }, /* RO */
+  { "mvfr1_el1",        CPENC(3,0,C0,C3,1),    0 }, /* RO */
+  { "mvfr2_el1",        CPENC(3,0,C0,C3,2),    0 }, /* RO */
+  { "ccsidr_el1",       CPENC(3,1,C0,C0,0),    0 }, /* RO */
+  { "id_aa64pfr0_el1",  CPENC(3,0,C0,C4,0),    0 }, /* RO */
+  { "id_aa64pfr1_el1",  CPENC(3,0,C0,C4,1),    0 }, /* RO */
+  { "id_aa64dfr0_el1",  CPENC(3,0,C0,C5,0),    0 }, /* RO */
+  { "id_aa64dfr1_el1",  CPENC(3,0,C0,C5,1),    0 }, /* RO */
+  { "id_aa64isar0_el1", CPENC(3,0,C0,C6,0),    0 }, /* RO */
+  { "id_aa64isar1_el1", CPENC(3,0,C0,C6,1),    0 }, /* RO */
+  { "id_aa64mmfr0_el1", CPENC(3,0,C0,C7,0),    0 }, /* RO */
+  { "id_aa64mmfr1_el1", CPENC(3,0,C0,C7,1),    0 }, /* RO */
+  { "id_aa64mmfr2_el1", CPENC (3, 0, C0, C7, 2), F_ARCHEXT }, /* RO */
+  { "id_aa64afr0_el1",  CPENC(3,0,C0,C5,4),    0 }, /* RO */
+  { "id_aa64afr1_el1",  CPENC(3,0,C0,C5,5),    0 }, /* RO */
+  { "clidr_el1",        CPENC(3,1,C0,C0,1),    0 }, /* RO */
+  { "csselr_el1",       CPENC(3,2,C0,C0,0),    0 }, /* RO */
+  { "vpidr_el2",        CPENC(3,4,C0,C0,0),    0 },
+  { "vmpidr_el2",       CPENC(3,4,C0,C0,5),    0 },
+  { "sctlr_el1",        CPENC(3,0,C1,C0,0),    0 },
+  { "sctlr_el2",        CPENC(3,4,C1,C0,0),    0 },
+  { "sctlr_el3",        CPENC(3,6,C1,C0,0),    0 },
+  { "sctlr_el12",      CPENC (3, 5, C1, C0, 0), F_ARCHEXT },
+  { "actlr_el1",        CPENC(3,0,C1,C0,1),    0 },
+  { "actlr_el2",        CPENC(3,4,C1,C0,1),    0 },
+  { "actlr_el3",        CPENC(3,6,C1,C0,1),    0 },
+  { "cpacr_el1",        CPENC(3,0,C1,C0,2),    0 },
+  { "cpacr_el12",      CPENC (3, 5, C1, C0, 2), F_ARCHEXT },
+  { "cptr_el2",         CPENC(3,4,C1,C1,2),    0 },
+  { "cptr_el3",         CPENC(3,6,C1,C1,2),    0 },
+  { "scr_el3",          CPENC(3,6,C1,C1,0),    0 },
+  { "hcr_el2",          CPENC(3,4,C1,C1,0),    0 },
+  { "mdcr_el2",         CPENC(3,4,C1,C1,1),    0 },
+  { "mdcr_el3",         CPENC(3,6,C1,C3,1),    0 },
+  { "hstr_el2",         CPENC(3,4,C1,C1,3),    0 },
+  { "hacr_el2",         CPENC(3,4,C1,C1,7),    0 },
+  { "ttbr0_el1",        CPENC(3,0,C2,C0,0),    0 },
+  { "ttbr1_el1",        CPENC(3,0,C2,C0,1),    0 },
+  { "ttbr0_el2",        CPENC(3,4,C2,C0,0),    0 },
+  { "ttbr1_el2",       CPENC (3, 4, C2, C0, 1), F_ARCHEXT },
+  { "ttbr0_el3",        CPENC(3,6,C2,C0,0),    0 },
+  { "ttbr0_el12",      CPENC (3, 5, C2, C0, 0), F_ARCHEXT },
+  { "ttbr1_el12",      CPENC (3, 5, C2, C0, 1), F_ARCHEXT },
+  { "vttbr_el2",        CPENC(3,4,C2,C1,0),    0 },
+  { "tcr_el1",          CPENC(3,0,C2,C0,2),    0 },
+  { "tcr_el2",          CPENC(3,4,C2,C0,2),    0 },
+  { "tcr_el3",          CPENC(3,6,C2,C0,2),    0 },
+  { "tcr_el12",                CPENC (3, 5, C2, C0, 2), F_ARCHEXT },
+  { "vtcr_el2",         CPENC(3,4,C2,C1,2),    0 },
+  { "afsr0_el1",        CPENC(3,0,C5,C1,0),    0 },
+  { "afsr1_el1",        CPENC(3,0,C5,C1,1),    0 },
+  { "afsr0_el2",        CPENC(3,4,C5,C1,0),    0 },
+  { "afsr1_el2",        CPENC(3,4,C5,C1,1),    0 },
+  { "afsr0_el3",        CPENC(3,6,C5,C1,0),    0 },
+  { "afsr0_el12",      CPENC (3, 5, C5, C1, 0), F_ARCHEXT },
+  { "afsr1_el3",        CPENC(3,6,C5,C1,1),    0 },
+  { "afsr1_el12",      CPENC (3, 5, C5, C1, 1), F_ARCHEXT },
+  { "esr_el1",          CPENC(3,0,C5,C2,0),    0 },
+  { "esr_el2",          CPENC(3,4,C5,C2,0),    0 },
+  { "esr_el3",          CPENC(3,6,C5,C2,0),    0 },
+  { "esr_el12",                CPENC (3, 5, C5, C2, 0), F_ARCHEXT },
+  { "vsesr_el2",       CPENC (3, 4, C5, C2, 3), F_ARCHEXT }, /* RO */
+  { "fpexc32_el2",      CPENC(3,4,C5,C3,0),    0 },
+  { "erridr_el1",      CPENC (3, 0, C5, C3, 0), F_ARCHEXT }, /* RO */
+  { "errselr_el1",     CPENC (3, 0, C5, C3, 1), F_ARCHEXT },
+  { "erxfr_el1",       CPENC (3, 0, C5, C4, 0), F_ARCHEXT }, /* RO */
+  { "erxctlr_el1",     CPENC (3, 0, C5, C4, 1), F_ARCHEXT },
+  { "erxstatus_el1",   CPENC (3, 0, C5, C4, 2), F_ARCHEXT },
+  { "erxaddr_el1",     CPENC (3, 0, C5, C4, 3), F_ARCHEXT },
+  { "erxmisc0_el1",    CPENC (3, 0, C5, C5, 0), F_ARCHEXT },
+  { "erxmisc1_el1",    CPENC (3, 0, C5, C5, 1), F_ARCHEXT },
+  { "far_el1",          CPENC(3,0,C6,C0,0),    0 },
+  { "far_el2",          CPENC(3,4,C6,C0,0),    0 },
+  { "far_el3",          CPENC(3,6,C6,C0,0),    0 },
+  { "far_el12",                CPENC (3, 5, C6, C0, 0), F_ARCHEXT },
+  { "hpfar_el2",        CPENC(3,4,C6,C0,4),    0 },
+  { "par_el1",          CPENC(3,0,C7,C4,0),    0 },
+  { "mair_el1",         CPENC(3,0,C10,C2,0),   0 },
+  { "mair_el2",         CPENC(3,4,C10,C2,0),   0 },
+  { "mair_el3",         CPENC(3,6,C10,C2,0),   0 },
+  { "mair_el12",       CPENC (3, 5, C10, C2, 0), F_ARCHEXT },
+  { "amair_el1",        CPENC(3,0,C10,C3,0),   0 },
+  { "amair_el2",        CPENC(3,4,C10,C3,0),   0 },
+  { "amair_el3",        CPENC(3,6,C10,C3,0),   0 },
+  { "amair_el12",      CPENC (3, 5, C10, C3, 0), F_ARCHEXT },
+  { "vbar_el1",         CPENC(3,0,C12,C0,0),   0 },
+  { "vbar_el2",         CPENC(3,4,C12,C0,0),   0 },
+  { "vbar_el3",         CPENC(3,6,C12,C0,0),   0 },
+  { "vbar_el12",       CPENC (3, 5, C12, C0, 0), F_ARCHEXT },
+  { "rvbar_el1",        CPENC(3,0,C12,C0,1),   0 }, /* RO */
+  { "rvbar_el2",        CPENC(3,4,C12,C0,1),   0 }, /* RO */
+  { "rvbar_el3",        CPENC(3,6,C12,C0,1),   0 }, /* RO */
+  { "rmr_el1",          CPENC(3,0,C12,C0,2),   0 },
+  { "rmr_el2",          CPENC(3,4,C12,C0,2),   0 },
+  { "rmr_el3",          CPENC(3,6,C12,C0,2),   0 },
+  { "isr_el1",          CPENC(3,0,C12,C1,0),   0 }, /* RO */
+  { "disr_el1",                CPENC (3, 0, C12, C1, 1), F_ARCHEXT },
+  { "vdisr_el2",       CPENC (3, 4, C12, C1, 1), F_ARCHEXT },
+  { "contextidr_el1",   CPENC(3,0,C13,C0,1),   0 },
+  { "contextidr_el2",  CPENC (3, 4, C13, C0, 1), F_ARCHEXT },
+  { "contextidr_el12", CPENC (3, 5, C13, C0, 1), F_ARCHEXT },
+  { "tpidr_el0",        CPENC(3,3,C13,C0,2),   0 },
+  { "tpidrro_el0",      CPENC(3,3,C13,C0,3),   0 }, /* RO */
+  { "tpidr_el1",        CPENC(3,0,C13,C0,4),   0 },
+  { "tpidr_el2",        CPENC(3,4,C13,C0,2),   0 },
+  { "tpidr_el3",        CPENC(3,6,C13,C0,2),   0 },
+  { "teecr32_el1",      CPENC(2,2,C0, C0,0),   0 }, /* See section 3.9.7.1 */
+  { "cntfrq_el0",       CPENC(3,3,C14,C0,0),   0 }, /* RO */
+  { "cntpct_el0",       CPENC(3,3,C14,C0,1),   0 }, /* RO */
+  { "cntvct_el0",       CPENC(3,3,C14,C0,2),   0 }, /* RO */
+  { "cntvoff_el2",      CPENC(3,4,C14,C0,3),   0 },
+  { "cntkctl_el1",      CPENC(3,0,C14,C1,0),   0 },
+  { "cntkctl_el12",    CPENC (3, 5, C14, C1, 0), F_ARCHEXT },
+  { "cnthctl_el2",      CPENC(3,4,C14,C1,0),   0 },
+  { "cntp_tval_el0",    CPENC(3,3,C14,C2,0),   0 },
+  { "cntp_tval_el02",  CPENC (3, 5, C14, C2, 0), F_ARCHEXT },
+  { "cntp_ctl_el0",     CPENC(3,3,C14,C2,1),   0 },
+  { "cntp_ctl_el02",   CPENC (3, 5, C14, C2, 1), F_ARCHEXT },
+  { "cntp_cval_el0",    CPENC(3,3,C14,C2,2),   0 },
+  { "cntp_cval_el02",  CPENC (3, 5, C14, C2, 2), F_ARCHEXT },
+  { "cntv_tval_el0",    CPENC(3,3,C14,C3,0),   0 },
+  { "cntv_tval_el02",  CPENC (3, 5, C14, C3, 0), F_ARCHEXT },
+  { "cntv_ctl_el0",     CPENC(3,3,C14,C3,1),   0 },
+  { "cntv_ctl_el02",   CPENC (3, 5, C14, C3, 1), F_ARCHEXT },
+  { "cntv_cval_el0",    CPENC(3,3,C14,C3,2),   0 },
+  { "cntv_cval_el02",  CPENC (3, 5, C14, C3, 2), F_ARCHEXT },
+  { "cnthp_tval_el2",   CPENC(3,4,C14,C2,0),   0 },
+  { "cnthp_ctl_el2",    CPENC(3,4,C14,C2,1),   0 },
+  { "cnthp_cval_el2",   CPENC(3,4,C14,C2,2),   0 },
+  { "cntps_tval_el1",   CPENC(3,7,C14,C2,0),   0 },
+  { "cntps_ctl_el1",    CPENC(3,7,C14,C2,1),   0 },
+  { "cntps_cval_el1",   CPENC(3,7,C14,C2,2),   0 },
+  { "cnthv_tval_el2",  CPENC (3, 4, C14, C3, 0), F_ARCHEXT },
+  { "cnthv_ctl_el2",   CPENC (3, 4, C14, C3, 1), F_ARCHEXT },
+  { "cnthv_cval_el2",  CPENC (3, 4, C14, C3, 2), F_ARCHEXT },
+  { "dacr32_el2",       CPENC(3,4,C3,C0,0),    0 },
+  { "ifsr32_el2",       CPENC(3,4,C5,C0,1),    0 },
+  { "teehbr32_el1",     CPENC(2,2,C1,C0,0),    0 },
+  { "sder32_el3",       CPENC(3,6,C1,C1,1),    0 },
+  { "mdscr_el1",         CPENC(2,0,C0, C2, 2), 0 },
+  { "mdccsr_el0",        CPENC(2,3,C0, C1, 0), 0 },  /* r */
+  { "mdccint_el1",       CPENC(2,0,C0, C2, 0), 0 },
+  { "dbgdtr_el0",        CPENC(2,3,C0, C4, 0), 0 },
+  { "dbgdtrrx_el0",      CPENC(2,3,C0, C5, 0), 0 },  /* r */
+  { "dbgdtrtx_el0",      CPENC(2,3,C0, C5, 0), 0 },  /* w */
+  { "osdtrrx_el1",       CPENC(2,0,C0, C0, 2), 0 },  /* r */
+  { "osdtrtx_el1",       CPENC(2,0,C0, C3, 2), 0 },  /* w */
+  { "oseccr_el1",        CPENC(2,0,C0, C6, 2), 0 },
+  { "dbgvcr32_el2",      CPENC(2,4,C0, C7, 0), 0 },
+  { "dbgbvr0_el1",       CPENC(2,0,C0, C0, 4), 0 },
+  { "dbgbvr1_el1",       CPENC(2,0,C0, C1, 4), 0 },
+  { "dbgbvr2_el1",       CPENC(2,0,C0, C2, 4), 0 },
+  { "dbgbvr3_el1",       CPENC(2,0,C0, C3, 4), 0 },
+  { "dbgbvr4_el1",       CPENC(2,0,C0, C4, 4), 0 },
+  { "dbgbvr5_el1",       CPENC(2,0,C0, C5, 4), 0 },
+  { "dbgbvr6_el1",       CPENC(2,0,C0, C6, 4), 0 },
+  { "dbgbvr7_el1",       CPENC(2,0,C0, C7, 4), 0 },
+  { "dbgbvr8_el1",       CPENC(2,0,C0, C8, 4), 0 },
+  { "dbgbvr9_el1",       CPENC(2,0,C0, C9, 4), 0 },
+  { "dbgbvr10_el1",      CPENC(2,0,C0, C10,4), 0 },
+  { "dbgbvr11_el1",      CPENC(2,0,C0, C11,4), 0 },
+  { "dbgbvr12_el1",      CPENC(2,0,C0, C12,4), 0 },
+  { "dbgbvr13_el1",      CPENC(2,0,C0, C13,4), 0 },
+  { "dbgbvr14_el1",      CPENC(2,0,C0, C14,4), 0 },
+  { "dbgbvr15_el1",      CPENC(2,0,C0, C15,4), 0 },
+  { "dbgbcr0_el1",       CPENC(2,0,C0, C0, 5), 0 },
+  { "dbgbcr1_el1",       CPENC(2,0,C0, C1, 5), 0 },
+  { "dbgbcr2_el1",       CPENC(2,0,C0, C2, 5), 0 },
+  { "dbgbcr3_el1",       CPENC(2,0,C0, C3, 5), 0 },
+  { "dbgbcr4_el1",       CPENC(2,0,C0, C4, 5), 0 },
+  { "dbgbcr5_el1",       CPENC(2,0,C0, C5, 5), 0 },
+  { "dbgbcr6_el1",       CPENC(2,0,C0, C6, 5), 0 },
+  { "dbgbcr7_el1",       CPENC(2,0,C0, C7, 5), 0 },
+  { "dbgbcr8_el1",       CPENC(2,0,C0, C8, 5), 0 },
+  { "dbgbcr9_el1",       CPENC(2,0,C0, C9, 5), 0 },
+  { "dbgbcr10_el1",      CPENC(2,0,C0, C10,5), 0 },
+  { "dbgbcr11_el1",      CPENC(2,0,C0, C11,5), 0 },
+  { "dbgbcr12_el1",      CPENC(2,0,C0, C12,5), 0 },
+  { "dbgbcr13_el1",      CPENC(2,0,C0, C13,5), 0 },
+  { "dbgbcr14_el1",      CPENC(2,0,C0, C14,5), 0 },
+  { "dbgbcr15_el1",      CPENC(2,0,C0, C15,5), 0 },
+  { "dbgwvr0_el1",       CPENC(2,0,C0, C0, 6), 0 },
+  { "dbgwvr1_el1",       CPENC(2,0,C0, C1, 6), 0 },
+  { "dbgwvr2_el1",       CPENC(2,0,C0, C2, 6), 0 },
+  { "dbgwvr3_el1",       CPENC(2,0,C0, C3, 6), 0 },
+  { "dbgwvr4_el1",       CPENC(2,0,C0, C4, 6), 0 },
+  { "dbgwvr5_el1",       CPENC(2,0,C0, C5, 6), 0 },
+  { "dbgwvr6_el1",       CPENC(2,0,C0, C6, 6), 0 },
+  { "dbgwvr7_el1",       CPENC(2,0,C0, C7, 6), 0 },
+  { "dbgwvr8_el1",       CPENC(2,0,C0, C8, 6), 0 },
+  { "dbgwvr9_el1",       CPENC(2,0,C0, C9, 6), 0 },
+  { "dbgwvr10_el1",      CPENC(2,0,C0, C10,6), 0 },
+  { "dbgwvr11_el1",      CPENC(2,0,C0, C11,6), 0 },
+  { "dbgwvr12_el1",      CPENC(2,0,C0, C12,6), 0 },
+  { "dbgwvr13_el1",      CPENC(2,0,C0, C13,6), 0 },
+  { "dbgwvr14_el1",      CPENC(2,0,C0, C14,6), 0 },
+  { "dbgwvr15_el1",      CPENC(2,0,C0, C15,6), 0 },
+  { "dbgwcr0_el1",       CPENC(2,0,C0, C0, 7), 0 },
+  { "dbgwcr1_el1",       CPENC(2,0,C0, C1, 7), 0 },
+  { "dbgwcr2_el1",       CPENC(2,0,C0, C2, 7), 0 },
+  { "dbgwcr3_el1",       CPENC(2,0,C0, C3, 7), 0 },
+  { "dbgwcr4_el1",       CPENC(2,0,C0, C4, 7), 0 },
+  { "dbgwcr5_el1",       CPENC(2,0,C0, C5, 7), 0 },
+  { "dbgwcr6_el1",       CPENC(2,0,C0, C6, 7), 0 },
+  { "dbgwcr7_el1",       CPENC(2,0,C0, C7, 7), 0 },
+  { "dbgwcr8_el1",       CPENC(2,0,C0, C8, 7), 0 },
+  { "dbgwcr9_el1",       CPENC(2,0,C0, C9, 7), 0 },
+  { "dbgwcr10_el1",      CPENC(2,0,C0, C10,7), 0 },
+  { "dbgwcr11_el1",      CPENC(2,0,C0, C11,7), 0 },
+  { "dbgwcr12_el1",      CPENC(2,0,C0, C12,7), 0 },
+  { "dbgwcr13_el1",      CPENC(2,0,C0, C13,7), 0 },
+  { "dbgwcr14_el1",      CPENC(2,0,C0, C14,7), 0 },
+  { "dbgwcr15_el1",      CPENC(2,0,C0, C15,7), 0 },
+  { "mdrar_el1",         CPENC(2,0,C1, C0, 0), 0 },  /* r */
+  { "oslar_el1",         CPENC(2,0,C1, C0, 4), 0 },  /* w */
+  { "oslsr_el1",         CPENC(2,0,C1, C1, 4), 0 },  /* r */
+  { "osdlr_el1",         CPENC(2,0,C1, C3, 4), 0 },
+  { "dbgprcr_el1",       CPENC(2,0,C1, C4, 4), 0 },
+  { "dbgclaimset_el1",   CPENC(2,0,C7, C8, 6), 0 },
+  { "dbgclaimclr_el1",   CPENC(2,0,C7, C9, 6), 0 },
+  { "dbgauthstatus_el1", CPENC(2,0,C7, C14,6), 0 },  /* r */
+  { "pmblimitr_el1",    CPENC (3, 0, C9, C10, 0), F_ARCHEXT },  /* rw */
+  { "pmbptr_el1",       CPENC (3, 0, C9, C10, 1), F_ARCHEXT },  /* rw */
+  { "pmbsr_el1",        CPENC (3, 0, C9, C10, 3), F_ARCHEXT },  /* rw */
+  { "pmbidr_el1",       CPENC (3, 0, C9, C10, 7), F_ARCHEXT },  /* ro */
+  { "pmscr_el1",        CPENC (3, 0, C9, C9, 0),  F_ARCHEXT },  /* rw */
+  { "pmsicr_el1",       CPENC (3, 0, C9, C9, 2),  F_ARCHEXT },  /* rw */
+  { "pmsirr_el1",       CPENC (3, 0, C9, C9, 3),  F_ARCHEXT },  /* rw */
+  { "pmsfcr_el1",       CPENC (3, 0, C9, C9, 4),  F_ARCHEXT },  /* rw */
+  { "pmsevfr_el1",      CPENC (3, 0, C9, C9, 5),  F_ARCHEXT },  /* rw */
+  { "pmslatfr_el1",     CPENC (3, 0, C9, C9, 6),  F_ARCHEXT },  /* rw */
+  { "pmsidr_el1",       CPENC (3, 0, C9, C9, 7),  F_ARCHEXT },  /* ro */
+  { "pmscr_el2",        CPENC (3, 4, C9, C9, 0),  F_ARCHEXT },  /* rw */
+  { "pmscr_el12",       CPENC (3, 5, C9, C9, 0),  F_ARCHEXT },  /* rw */
+  { "pmcr_el0",          CPENC(3,3,C9,C12, 0), 0 },
+  { "pmcntenset_el0",    CPENC(3,3,C9,C12, 1), 0 },
+  { "pmcntenclr_el0",    CPENC(3,3,C9,C12, 2), 0 },
+  { "pmovsclr_el0",      CPENC(3,3,C9,C12, 3), 0 },
+  { "pmswinc_el0",       CPENC(3,3,C9,C12, 4), 0 },  /* w */
+  { "pmselr_el0",        CPENC(3,3,C9,C12, 5), 0 },
+  { "pmceid0_el0",       CPENC(3,3,C9,C12, 6), 0 },  /* r */
+  { "pmceid1_el0",       CPENC(3,3,C9,C12, 7), 0 },  /* r */
+  { "pmccntr_el0",       CPENC(3,3,C9,C13, 0), 0 },
+  { "pmxevtyper_el0",    CPENC(3,3,C9,C13, 1), 0 },
+  { "pmxevcntr_el0",     CPENC(3,3,C9,C13, 2), 0 },
+  { "pmuserenr_el0",     CPENC(3,3,C9,C14, 0), 0 },
+  { "pmintenset_el1",    CPENC(3,0,C9,C14, 1), 0 },
+  { "pmintenclr_el1",    CPENC(3,0,C9,C14, 2), 0 },
+  { "pmovsset_el0",      CPENC(3,3,C9,C14, 3), 0 },
+  { "pmevcntr0_el0",     CPENC(3,3,C14,C8, 0), 0 },
+  { "pmevcntr1_el0",     CPENC(3,3,C14,C8, 1), 0 },
+  { "pmevcntr2_el0",     CPENC(3,3,C14,C8, 2), 0 },
+  { "pmevcntr3_el0",     CPENC(3,3,C14,C8, 3), 0 },
+  { "pmevcntr4_el0",     CPENC(3,3,C14,C8, 4), 0 },
+  { "pmevcntr5_el0",     CPENC(3,3,C14,C8, 5), 0 },
+  { "pmevcntr6_el0",     CPENC(3,3,C14,C8, 6), 0 },
+  { "pmevcntr7_el0",     CPENC(3,3,C14,C8, 7), 0 },
+  { "pmevcntr8_el0",     CPENC(3,3,C14,C9, 0), 0 },
+  { "pmevcntr9_el0",     CPENC(3,3,C14,C9, 1), 0 },
+  { "pmevcntr10_el0",    CPENC(3,3,C14,C9, 2), 0 },
+  { "pmevcntr11_el0",    CPENC(3,3,C14,C9, 3), 0 },
+  { "pmevcntr12_el0",    CPENC(3,3,C14,C9, 4), 0 },
+  { "pmevcntr13_el0",    CPENC(3,3,C14,C9, 5), 0 },
+  { "pmevcntr14_el0",    CPENC(3,3,C14,C9, 6), 0 },
+  { "pmevcntr15_el0",    CPENC(3,3,C14,C9, 7), 0 },
+  { "pmevcntr16_el0",    CPENC(3,3,C14,C10,0), 0 },
+  { "pmevcntr17_el0",    CPENC(3,3,C14,C10,1), 0 },
+  { "pmevcntr18_el0",    CPENC(3,3,C14,C10,2), 0 },
+  { "pmevcntr19_el0",    CPENC(3,3,C14,C10,3), 0 },
+  { "pmevcntr20_el0",    CPENC(3,3,C14,C10,4), 0 },
+  { "pmevcntr21_el0",    CPENC(3,3,C14,C10,5), 0 },
+  { "pmevcntr22_el0",    CPENC(3,3,C14,C10,6), 0 },
+  { "pmevcntr23_el0",    CPENC(3,3,C14,C10,7), 0 },
+  { "pmevcntr24_el0",    CPENC(3,3,C14,C11,0), 0 },
+  { "pmevcntr25_el0",    CPENC(3,3,C14,C11,1), 0 },
+  { "pmevcntr26_el0",    CPENC(3,3,C14,C11,2), 0 },
+  { "pmevcntr27_el0",    CPENC(3,3,C14,C11,3), 0 },
+  { "pmevcntr28_el0",    CPENC(3,3,C14,C11,4), 0 },
+  { "pmevcntr29_el0",    CPENC(3,3,C14,C11,5), 0 },
+  { "pmevcntr30_el0",    CPENC(3,3,C14,C11,6), 0 },
+  { "pmevtyper0_el0",    CPENC(3,3,C14,C12,0), 0 },
+  { "pmevtyper1_el0",    CPENC(3,3,C14,C12,1), 0 },
+  { "pmevtyper2_el0",    CPENC(3,3,C14,C12,2), 0 },
+  { "pmevtyper3_el0",    CPENC(3,3,C14,C12,3), 0 },
+  { "pmevtyper4_el0",    CPENC(3,3,C14,C12,4), 0 },
+  { "pmevtyper5_el0",    CPENC(3,3,C14,C12,5), 0 },
+  { "pmevtyper6_el0",    CPENC(3,3,C14,C12,6), 0 },
+  { "pmevtyper7_el0",    CPENC(3,3,C14,C12,7), 0 },
+  { "pmevtyper8_el0",    CPENC(3,3,C14,C13,0), 0 },
+  { "pmevtyper9_el0",    CPENC(3,3,C14,C13,1), 0 },
+  { "pmevtyper10_el0",   CPENC(3,3,C14,C13,2), 0 },
+  { "pmevtyper11_el0",   CPENC(3,3,C14,C13,3), 0 },
+  { "pmevtyper12_el0",   CPENC(3,3,C14,C13,4), 0 },
+  { "pmevtyper13_el0",   CPENC(3,3,C14,C13,5), 0 },
+  { "pmevtyper14_el0",   CPENC(3,3,C14,C13,6), 0 },
+  { "pmevtyper15_el0",   CPENC(3,3,C14,C13,7), 0 },
+  { "pmevtyper16_el0",   CPENC(3,3,C14,C14,0), 0 },
+  { "pmevtyper17_el0",   CPENC(3,3,C14,C14,1), 0 },
+  { "pmevtyper18_el0",   CPENC(3,3,C14,C14,2), 0 },
+  { "pmevtyper19_el0",   CPENC(3,3,C14,C14,3), 0 },
+  { "pmevtyper20_el0",   CPENC(3,3,C14,C14,4), 0 },
+  { "pmevtyper21_el0",   CPENC(3,3,C14,C14,5), 0 },
+  { "pmevtyper22_el0",   CPENC(3,3,C14,C14,6), 0 },
+  { "pmevtyper23_el0",   CPENC(3,3,C14,C14,7), 0 },
+  { "pmevtyper24_el0",   CPENC(3,3,C14,C15,0), 0 },
+  { "pmevtyper25_el0",   CPENC(3,3,C14,C15,1), 0 },
+  { "pmevtyper26_el0",   CPENC(3,3,C14,C15,2), 0 },
+  { "pmevtyper27_el0",   CPENC(3,3,C14,C15,3), 0 },
+  { "pmevtyper28_el0",   CPENC(3,3,C14,C15,4), 0 },
+  { "pmevtyper29_el0",   CPENC(3,3,C14,C15,5), 0 },
+  { "pmevtyper30_el0",   CPENC(3,3,C14,C15,6), 0 },
+  { "pmccfiltr_el0",     CPENC(3,3,C14,C15,7), 0 },
+  { 0,          CPENC(0,0,0,0,0),      0 },
 };
 
 };
 
-const struct aarch64_name_value_pair aarch64_pstatefields [] =
+bfd_boolean
+aarch64_sys_reg_deprecated_p (const aarch64_sys_reg *reg)
 {
 {
-  { "spsel",            0x05  },
-  { "daifset",          0x1e  },
-  { "daifclr",          0x1f  },
-  { 0,          CPENC(0,0,0,0,0)  },
+  return (reg->flags & F_DEPRECATED) != 0;
+}
+
+bfd_boolean
+aarch64_sys_reg_supported_p (const aarch64_feature_set features,
+                            const aarch64_sys_reg *reg)
+{
+  if (!(reg->flags & F_ARCHEXT))
+    return TRUE;
+
+  /* PAN.  Values are from aarch64_sys_regs.  */
+  if (reg->value == CPEN_(0,C2,3)
+      && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PAN))
+    return FALSE;
+
+  /* Virtualization host extensions: system registers.  */
+  if ((reg->value == CPENC (3, 4, C2, C0, 1)
+       || reg->value == CPENC (3, 4, C13, C0, 1)
+       || reg->value == CPENC (3, 4, C14, C3, 0)
+       || reg->value == CPENC (3, 4, C14, C3, 1)
+       || reg->value == CPENC (3, 4, C14, C3, 2))
+      && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
+      return FALSE;
+
+  /* Virtualization host extensions: *_el12 names of *_el1 registers.  */
+  if ((reg->value == CPEN_ (5, C0, 0)
+       || reg->value == CPEN_ (5, C0, 1)
+       || reg->value == CPENC (3, 5, C1, C0, 0)
+       || reg->value == CPENC (3, 5, C1, C0, 2)
+       || reg->value == CPENC (3, 5, C2, C0, 0)
+       || reg->value == CPENC (3, 5, C2, C0, 1)
+       || reg->value == CPENC (3, 5, C2, C0, 2)
+       || reg->value == CPENC (3, 5, C5, C1, 0)
+       || reg->value == CPENC (3, 5, C5, C1, 1)
+       || reg->value == CPENC (3, 5, C5, C2, 0)
+       || reg->value == CPENC (3, 5, C6, C0, 0)
+       || reg->value == CPENC (3, 5, C10, C2, 0)
+       || reg->value == CPENC (3, 5, C10, C3, 0)
+       || reg->value == CPENC (3, 5, C12, C0, 0)
+       || reg->value == CPENC (3, 5, C13, C0, 1)
+       || reg->value == CPENC (3, 5, C14, C1, 0))
+      && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
+    return FALSE;
+
+  /* Virtualization host extensions: *_el02 names of *_el0 registers.  */
+  if ((reg->value == CPENC (3, 5, C14, C2, 0)
+       || reg->value == CPENC (3, 5, C14, C2, 1)
+       || reg->value == CPENC (3, 5, C14, C2, 2)
+       || reg->value == CPENC (3, 5, C14, C3, 0)
+       || reg->value == CPENC (3, 5, C14, C3, 1)
+       || reg->value == CPENC (3, 5, C14, C3, 2))
+      && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_1))
+    return FALSE;
+
+  /* ARMv8.2 features.  */
+
+  /* ID_AA64MMFR2_EL1.  */
+  if (reg->value == CPENC (3, 0, C0, C7, 2)
+      && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
+    return FALSE;
+
+  /* PSTATE.UAO.  */
+  if (reg->value == CPEN_ (0, C2, 4)
+      && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
+    return FALSE;
+
+  /* RAS extension.  */
+
+  /* ERRIDR_EL1, ERRSELR_EL1, ERXFR_EL1, ERXCTLR_EL1, ERXSTATUS_EL, ERXADDR_EL1,
+     ERXMISC0_EL1 AND ERXMISC1_EL1.  */
+  if ((reg->value == CPENC (3, 0, C5, C3, 0)
+       || reg->value == CPENC (3, 0, C5, C3, 1)
+       || reg->value == CPENC (3, 0, C5, C3, 2)
+       || reg->value == CPENC (3, 0, C5, C3, 3)
+       || reg->value == CPENC (3, 0, C5, C4, 0)
+       || reg->value == CPENC (3, 0, C5, C4, 1)
+       || reg->value == CPENC (3, 0, C5, C4, 2)
+       || reg->value == CPENC (3, 0, C5, C4, 3)
+       || reg->value == CPENC (3, 0, C5, C5, 0)
+       || reg->value == CPENC (3, 0, C5, C5, 1))
+      && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_RAS))
+    return FALSE;
+
+  /* VSESR_EL2, DISR_EL1 and VDISR_EL2.  */
+  if ((reg->value == CPENC (3, 4, C5, C2, 3)
+       || reg->value == CPENC (3, 0, C12, C1, 1)
+       || reg->value == CPENC (3, 4, C12, C1, 1))
+      && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_RAS))
+    return FALSE;
+
+  /* Statistical Profiling extension.  */
+  if ((reg->value == CPENC (3, 0, C9, C10, 0)
+       || reg->value == CPENC (3, 0, C9, C10, 1)
+       || reg->value == CPENC (3, 0, C9, C10, 3)
+       || reg->value == CPENC (3, 0, C9, C10, 7)
+       || reg->value == CPENC (3, 0, C9, C9, 0)
+       || reg->value == CPENC (3, 0, C9, C9, 2)
+       || reg->value == CPENC (3, 0, C9, C9, 3)
+       || reg->value == CPENC (3, 0, C9, C9, 4)
+       || reg->value == CPENC (3, 0, C9, C9, 5)
+       || reg->value == CPENC (3, 0, C9, C9, 6)
+       || reg->value == CPENC (3, 0, C9, C9, 7)
+       || reg->value == CPENC (3, 4, C9, C9, 0)
+       || reg->value == CPENC (3, 5, C9, C9, 0))
+      && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PROFILE))
+    return FALSE;
+
+  return TRUE;
+}
+
+const aarch64_sys_reg aarch64_pstatefields [] =
+{
+  { "spsel",            0x05,  0 },
+  { "daifset",          0x1e,  0 },
+  { "daifclr",          0x1f,  0 },
+  { "pan",             0x04,   F_ARCHEXT },
+  { "uao",             0x03,   F_ARCHEXT },
+  { 0,          CPENC(0,0,0,0,0), 0 },
 };
 
 };
 
+bfd_boolean
+aarch64_pstatefield_supported_p (const aarch64_feature_set features,
+                                const aarch64_sys_reg *reg)
+{
+  if (!(reg->flags & F_ARCHEXT))
+    return TRUE;
+
+  /* PAN.  Values are from aarch64_pstatefields.  */
+  if (reg->value == 0x04
+      && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_PAN))
+    return FALSE;
+
+  /* UAO.  Values are from aarch64_pstatefields.  */
+  if (reg->value == 0x03
+      && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
+    return FALSE;
+
+  return TRUE;
+}
+
 const aarch64_sys_ins_reg aarch64_sys_regs_ic[] =
 {
     { "ialluis", CPENS(0,C7,C1,0), 0 },
     { "iallu",   CPENS(0,C7,C5,0), 0 },
 const aarch64_sys_ins_reg aarch64_sys_regs_ic[] =
 {
     { "ialluis", CPENS(0,C7,C1,0), 0 },
     { "iallu",   CPENS(0,C7,C5,0), 0 },
-    { "ivau",    CPENS(3,C7,C5,1), 1 },
+    { "ivau",    CPENS (3, C7, C5, 1), F_HASXT },
     { 0, CPENS(0,0,0,0), 0 }
 };
 
 const aarch64_sys_ins_reg aarch64_sys_regs_dc[] =
 {
     { 0, CPENS(0,0,0,0), 0 }
 };
 
 const aarch64_sys_ins_reg aarch64_sys_regs_dc[] =
 {
-    { "zva",        CPENS(3,C7,C4,1),  1 },
-    { "ivac",       CPENS(0,C7,C6,1),  1 },
-    { "isw",        CPENS(0,C7,C6,2),  1 },
-    { "cvac",       CPENS(3,C7,C10,1), 1 },
-    { "csw",        CPENS(0,C7,C10,2), 1 },
-    { "cvau",       CPENS(3,C7,C11,1), 1 },
-    { "civac",      CPENS(3,C7,C14,1), 1 },
-    { "cisw",       CPENS(0,C7,C14,2), 1 },
+    { "zva",       CPENS (3, C7, C4, 1),  F_HASXT },
+    { "ivac",       CPENS (0, C7, C6, 1),  F_HASXT },
+    { "isw",       CPENS (0, C7, C6, 2),  F_HASXT },
+    { "cvac",       CPENS (3, C7, C10, 1), F_HASXT },
+    { "csw",       CPENS (0, C7, C10, 2), F_HASXT },
+    { "cvau",       CPENS (3, C7, C11, 1), F_HASXT },
+    { "cvap",       CPENS (3, C7, C12, 1), F_HASXT | F_ARCHEXT },
+    { "civac",      CPENS (3, C7, C14, 1), F_HASXT },
+    { "cisw",       CPENS (0, C7, C14, 2), F_HASXT },
     { 0,       CPENS(0,0,0,0), 0 }
 };
 
 const aarch64_sys_ins_reg aarch64_sys_regs_at[] =
 {
     { 0,       CPENS(0,0,0,0), 0 }
 };
 
 const aarch64_sys_ins_reg aarch64_sys_regs_at[] =
 {
-    { "s1e1r",      CPENS(0,C7,C8,0), 1 },
-    { "s1e1w",      CPENS(0,C7,C8,1), 1 },
-    { "s1e0r",      CPENS(0,C7,C8,2), 1 },
-    { "s1e0w",      CPENS(0,C7,C8,3), 1 },
-    { "s12e1r",     CPENS(4,C7,C8,4), 1 },
-    { "s12e1w",     CPENS(4,C7,C8,5), 1 },
-    { "s12e0r",     CPENS(4,C7,C8,6), 1 },
-    { "s12e0w",     CPENS(4,C7,C8,7), 1 },
-    { "s1e2r",      CPENS(4,C7,C8,0), 1 },
-    { "s1e2w",      CPENS(4,C7,C8,1), 1 },
-    { "s1e3r",      CPENS(6,C7,C8,0), 1 },
-    { "s1e3w",      CPENS(6,C7,C8,1), 1 },
+    { "s1e1r",      CPENS (0, C7, C8, 0), F_HASXT },
+    { "s1e1w",      CPENS (0, C7, C8, 1), F_HASXT },
+    { "s1e0r",      CPENS (0, C7, C8, 2), F_HASXT },
+    { "s1e0w",      CPENS (0, C7, C8, 3), F_HASXT },
+    { "s12e1r",     CPENS (4, C7, C8, 4), F_HASXT },
+    { "s12e1w",     CPENS (4, C7, C8, 5), F_HASXT },
+    { "s12e0r",     CPENS (4, C7, C8, 6), F_HASXT },
+    { "s12e0w",     CPENS (4, C7, C8, 7), F_HASXT },
+    { "s1e2r",      CPENS (4, C7, C8, 0), F_HASXT },
+    { "s1e2w",      CPENS (4, C7, C8, 1), F_HASXT },
+    { "s1e3r",      CPENS (6, C7, C8, 0), F_HASXT },
+    { "s1e3w",      CPENS (6, C7, C8, 1), F_HASXT },
+    { "s1e1rp",     CPENS (0, C7, C9, 0), F_HASXT | F_ARCHEXT },
+    { "s1e1wp",     CPENS (0, C7, C9, 1), F_HASXT | F_ARCHEXT },
     { 0,       CPENS(0,0,0,0), 0 }
 };
 
 const aarch64_sys_ins_reg aarch64_sys_regs_tlbi[] =
 {
     { "vmalle1",   CPENS(0,C8,C7,0), 0 },
     { 0,       CPENS(0,0,0,0), 0 }
 };
 
 const aarch64_sys_ins_reg aarch64_sys_regs_tlbi[] =
 {
     { "vmalle1",   CPENS(0,C8,C7,0), 0 },
-    { "vae1",      CPENS(0,C8,C7,1), 1 },
-    { "aside1",    CPENS(0,C8,C7,2), 1 },
-    { "vaae1",     CPENS(0,C8,C7,3), 1 },
+    { "vae1",      CPENS (0, C8, C7, 1), F_HASXT },
+    { "aside1",    CPENS (0, C8, C7, 2), F_HASXT },
+    { "vaae1",     CPENS (0, C8, C7, 3), F_HASXT },
     { "vmalle1is", CPENS(0,C8,C3,0), 0 },
     { "vmalle1is", CPENS(0,C8,C3,0), 0 },
-    { "vae1is",    CPENS(0,C8,C3,1), 1 },
-    { "aside1is",  CPENS(0,C8,C3,2), 1 },
-    { "vaae1is",   CPENS(0,C8,C3,3), 1 },
-    { "ipas2e1is", CPENS(4,C8,C0,1), 1 },
-    { "ipas2le1is",CPENS(4,C8,C0,5), 1 },
-    { "ipas2e1",   CPENS(4,C8,C4,1), 1 },
-    { "ipas2le1",  CPENS(4,C8,C4,5), 1 },
-    { "vae2",      CPENS(4,C8,C7,1), 1 },
-    { "vae2is",    CPENS(4,C8,C3,1), 1 },
+    { "vae1is",    CPENS (0, C8, C3, 1), F_HASXT },
+    { "aside1is",  CPENS (0, C8, C3, 2), F_HASXT },
+    { "vaae1is",   CPENS (0, C8, C3, 3), F_HASXT },
+    { "ipas2e1is", CPENS (4, C8, C0, 1), F_HASXT },
+    { "ipas2le1is",CPENS (4, C8, C0, 5), F_HASXT },
+    { "ipas2e1",   CPENS (4, C8, C4, 1), F_HASXT },
+    { "ipas2le1",  CPENS (4, C8, C4, 5), F_HASXT },
+    { "vae2",      CPENS (4, C8, C7, 1), F_HASXT },
+    { "vae2is",    CPENS (4, C8, C3, 1), F_HASXT },
     { "vmalls12e1",CPENS(4,C8,C7,6), 0 },
     { "vmalls12e1is",CPENS(4,C8,C3,6), 0 },
     { "vmalls12e1",CPENS(4,C8,C7,6), 0 },
     { "vmalls12e1is",CPENS(4,C8,C3,6), 0 },
-    { "vae3",      CPENS(6,C8,C7,1), 1 },
-    { "vae3is",    CPENS(6,C8,C3,1), 1 },
+    { "vae3",      CPENS (6, C8, C7, 1), F_HASXT },
+    { "vae3is",    CPENS (6, C8, C3, 1), F_HASXT },
     { "alle2",     CPENS(4,C8,C7,0), 0 },
     { "alle2is",   CPENS(4,C8,C3,0), 0 },
     { "alle1",     CPENS(4,C8,C7,4), 0 },
     { "alle1is",   CPENS(4,C8,C3,4), 0 },
     { "alle3",     CPENS(6,C8,C7,0), 0 },
     { "alle3is",   CPENS(6,C8,C3,0), 0 },
     { "alle2",     CPENS(4,C8,C7,0), 0 },
     { "alle2is",   CPENS(4,C8,C3,0), 0 },
     { "alle1",     CPENS(4,C8,C7,4), 0 },
     { "alle1is",   CPENS(4,C8,C3,4), 0 },
     { "alle3",     CPENS(6,C8,C7,0), 0 },
     { "alle3is",   CPENS(6,C8,C3,0), 0 },
-    { "vale1is",   CPENS(0,C8,C3,5), 1 },
-    { "vale2is",   CPENS(4,C8,C3,5), 1 },
-    { "vale3is",   CPENS(6,C8,C3,5), 1 },
-    { "vaale1is",  CPENS(0,C8,C3,7), 1 },
-    { "vale1",     CPENS(0,C8,C7,5), 1 },
-    { "vale2",     CPENS(4,C8,C7,5), 1 },
-    { "vale3",     CPENS(6,C8,C7,5), 1 },
-    { "vaale1",    CPENS(0,C8,C7,7), 1 },
+    { "vale1is",   CPENS (0, C8, C3, 5), F_HASXT },
+    { "vale2is",   CPENS (4, C8, C3, 5), F_HASXT },
+    { "vale3is",   CPENS (6, C8, C3, 5), F_HASXT },
+    { "vaale1is",  CPENS (0, C8, C3, 7), F_HASXT },
+    { "vale1",     CPENS (0, C8, C7, 5), F_HASXT },
+    { "vale2",     CPENS (4, C8, C7, 5), F_HASXT },
+    { "vale3",     CPENS (6, C8, C7, 5), F_HASXT },
+    { "vaale1",    CPENS (0, C8, C7, 7), F_HASXT },
     { 0,       CPENS(0,0,0,0), 0 }
 };
 
     { 0,       CPENS(0,0,0,0), 0 }
 };
 
+bfd_boolean
+aarch64_sys_ins_reg_has_xt (const aarch64_sys_ins_reg *sys_ins_reg)
+{
+  return (sys_ins_reg->flags & F_HASXT) != 0;
+}
+
+extern bfd_boolean
+aarch64_sys_ins_reg_supported_p (const aarch64_feature_set features,
+                                const aarch64_sys_ins_reg *reg)
+{
+  if (!(reg->flags & F_ARCHEXT))
+    return TRUE;
+
+  /* DC CVAP.  Values are from aarch64_sys_regs_dc.  */
+  if (reg->value == CPENS (3, C7, C12, 1)
+      && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
+    return FALSE;
+
+  /* AT S1E1RP, AT S1E1WP.  Values are from aarch64_sys_regs_at.  */
+  if ((reg->value == CPENS (0, C7, C9, 0)
+       || reg->value == CPENS (0, C7, C9, 1))
+      && !AARCH64_CPU_HAS_FEATURE (features, AARCH64_FEATURE_V8_2))
+    return FALSE;
+
+  return TRUE;
+}
+
 #undef C0
 #undef C1
 #undef C2
 #undef C0
 #undef C1
 #undef C2
@@ -3087,6 +3702,35 @@ const aarch64_sys_ins_reg aarch64_sys_regs_tlbi[] =
 #undef C14
 #undef C15
 
 #undef C14
 #undef C15
 
+#define BIT(INSN,BT)     (((INSN) >> (BT)) & 1)
+#define BITS(INSN,HI,LO) (((INSN) >> (LO)) & ((1 << (((HI) - (LO)) + 1)) - 1))
+
+static bfd_boolean
+verify_ldpsw (const struct aarch64_opcode * opcode ATTRIBUTE_UNUSED,
+             const aarch64_insn insn)
+{
+  int t  = BITS (insn, 4, 0);
+  int n  = BITS (insn, 9, 5);
+  int t2 = BITS (insn, 14, 10);
+
+  if (BIT (insn, 23))
+    {
+      /* Write back enabled.  */
+      if ((t == n || t2 == n) && n != 31)
+       return FALSE;
+    }
+
+  if (BIT (insn, 22))
+    {
+      /* Load */
+      if (t == t2)
+       return FALSE;
+    }
+
+  return TRUE;
+}
+
 /* Include the opcode description table as well as the operand description
    table.  */
 /* Include the opcode description table as well as the operand description
    table.  */
+#define VERIFIER(x) verify_##x
 #include "aarch64-tbl.h"
 #include "aarch64-tbl.h"
This page took 0.05009 seconds and 4 git commands to generate.