+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * config/tc-aarch64.c (parse_enum_string): New function.
+       (po_enum_or_fail): New macro.
+       (parse_operands): Handle AARCH64_OPND_SVE_PATTERN and
+       AARCH64_OPND_SVE_PRFOP.
+
 2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * config/tc-aarch64.c (vector_el_type): Add NT_zero and NT_merge.
 
 
 /* Miscellaneous. */
 
+/* Parse a symbolic operand such as "pow2" at *STR.  ARRAY is an array
+   of SIZE tokens in which index I gives the token for field value I,
+   or is null if field value I is invalid.  REG_TYPE says which register
+   names should be treated as registers rather than as symbolic immediates.
+
+   Return true on success, moving *STR past the operand and storing the
+   field value in *VAL.  */
+
+static int
+parse_enum_string (char **str, int64_t *val, const char *const *array,
+                  size_t size, aarch64_reg_type reg_type)
+{
+  expressionS exp;
+  char *p, *q;
+  size_t i;
+
+  /* Match C-like tokens.  */
+  p = q = *str;
+  while (ISALNUM (*q))
+    q++;
+
+  for (i = 0; i < size; ++i)
+    if (array[i]
+       && strncasecmp (array[i], p, q - p) == 0
+       && array[i][q - p] == 0)
+      {
+       *val = i;
+       *str = q;
+       return TRUE;
+      }
+
+  if (!parse_immediate_expression (&p, &exp, reg_type))
+    return FALSE;
+
+  if (exp.X_op == O_constant
+      && (uint64_t) exp.X_add_number < size)
+    {
+      *val = exp.X_add_number;
+      *str = p;
+      return TRUE;
+    }
+
+  /* Use the default error for this operand.  */
+  return FALSE;
+}
+
 /* Parse an option for a preload instruction.  Returns the encoding for the
    option, or PARSE_FAIL.  */
 
       }                                                                \
   } while (0)
 
+#define po_enum_or_fail(array) do {                            \
+    if (!parse_enum_string (&str, &val, array,                 \
+                           ARRAY_SIZE (array), imm_reg_type))  \
+      goto failure;                                            \
+  } while (0)
+
 #define po_misc_or_fail(expr) do {                             \
     if (!expr)                                                 \
       goto failure;                                            \
     case AARCH64_OPND_WIDTH:
     case AARCH64_OPND_UIMM7:
     case AARCH64_OPND_NZCV:
+    case AARCH64_OPND_SVE_PATTERN:
+    case AARCH64_OPND_SVE_PRFOP:
       operand->imm.value = default_value;
       break;
 
          info->imm.value = val;
          break;
 
+       case AARCH64_OPND_SVE_PATTERN:
+         po_enum_or_fail (aarch64_sve_pattern_array);
+         info->imm.value = val;
+         break;
+
+       case AARCH64_OPND_SVE_PRFOP:
+         po_enum_or_fail (aarch64_sve_prfop_array);
+         info->imm.value = val;
+         break;
+
        case AARCH64_OPND_UIMM7:
          po_imm_or_fail (0, 127);
          info->imm.value = val;
 
+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * opcode/aarch64.h (AARCH64_OPND_SVE_PATTERN): New aarch64_opnd.
+       (AARCH64_OPND_SVE_PRFOP): Likewise.
+       (aarch64_sve_pattern_array): Declare.
+       (aarch64_sve_prfop_array): Likewise.
+
 2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * opcode/aarch64.h (AARCH64_OPND_QLF_P_Z): New aarch64_opnd_qualifier.
 
   AARCH64_OPND_PRFOP,          /* Prefetch operation.  */
   AARCH64_OPND_BARRIER_PSB,    /* Barrier operand for PSB.  */
 
+  AARCH64_OPND_SVE_PATTERN,    /* SVE vector pattern enumeration.  */
+  AARCH64_OPND_SVE_PRFOP,      /* SVE prefetch operation.  */
   AARCH64_OPND_SVE_Pd,         /* SVE p0-p15 in Pd.  */
   AARCH64_OPND_SVE_Pg3,                /* SVE p0-p7 in Pg.  */
   AARCH64_OPND_SVE_Pg4_5,      /* SVE p0-p15 in Pg, bits [8,5].  */
 #define DEBUG_TRACE_IF(C, M, ...) ;
 #endif /* DEBUG_AARCH64 */
 
+extern const char *const aarch64_sve_pattern_array[32];
+extern const char *const aarch64_sve_prfop_array[16];
+
 #ifdef __cplusplus
 }
 #endif
 
+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * aarch64-tbl.h (AARCH64_OPERANDS): Add entries for
+       AARCH64_OPND_SVE_PATTERN and AARCH64_OPND_SVE_PRFOP.
+       * aarch64-opc.h (FLD_SVE_pattern): New aarch64_field_kind.
+       (FLD_SVE_prfop): Likewise.
+       * aarch64-opc.c: Include libiberty.h.
+       (aarch64_sve_pattern_array): New variable.
+       (aarch64_sve_prfop_array): Likewise.
+       (fields): Add entries for FLD_SVE_pattern and FLD_SVE_prfop.
+       (aarch64_print_operand): Handle AARCH64_OPND_SVE_PATTERN and
+       AARCH64_OPND_SVE_PRFOP.
+       * aarch64-asm-2.c: Regenerate.
+       * aarch64-dis-2.c: Likewise.
+       * aarch64-opc-2.c: Likewise.
+
 2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * aarch64-opc.c (aarch64_opnd_qualifiers): Add entries for
 
     case 27:
     case 35:
     case 36:
-    case 89:
-    case 90:
     case 91:
     case 92:
     case 93:
     case 100:
     case 101:
     case 102:
-    case 105:
+    case 103:
+    case 104:
+    case 107:
       return aarch64_ins_regno (self, info, code, inst);
     case 12:
       return aarch64_ins_reg_extended (self, info, code, inst);
     case 68:
     case 69:
     case 70:
+    case 89:
+    case 90:
       return aarch64_ins_imm (self, info, code, inst);
     case 38:
     case 39:
       return aarch64_ins_prfop (self, info, code, inst);
     case 88:
       return aarch64_ins_hint (self, info, code, inst);
-    case 103:
+    case 105:
       return aarch64_ins_sve_index (self, info, code, inst);
-    case 104:
     case 106:
+    case 108:
       return aarch64_ins_sve_reglist (self, info, code, inst);
     default: assert (0); abort ();
     }
 
     case 27:
     case 35:
     case 36:
-    case 89:
-    case 90:
     case 91:
     case 92:
     case 93:
     case 100:
     case 101:
     case 102:
-    case 105:
+    case 103:
+    case 104:
+    case 107:
       return aarch64_ext_regno (self, info, code, inst);
     case 8:
       return aarch64_ext_regrt_sysins (self, info, code, inst);
     case 68:
     case 69:
     case 70:
+    case 89:
+    case 90:
       return aarch64_ext_imm (self, info, code, inst);
     case 38:
     case 39:
       return aarch64_ext_prfop (self, info, code, inst);
     case 88:
       return aarch64_ext_hint (self, info, code, inst);
-    case 103:
+    case 105:
       return aarch64_ext_sve_index (self, info, code, inst);
-    case 104:
     case 106:
+    case 108:
       return aarch64_ext_sve_reglist (self, info, code, inst);
     default: assert (0); abort ();
     }
 
   {AARCH64_OPND_CLASS_SYSTEM, "BARRIER_ISB", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "the ISB option name SY or an optional 4-bit unsigned immediate"},
   {AARCH64_OPND_CLASS_SYSTEM, "PRFOP", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "a prefetch operation specifier"},
   {AARCH64_OPND_CLASS_SYSTEM, "BARRIER_PSB", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {}, "the PSB option name CSYNC"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_PATTERN", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_pattern}, "an enumeration value such as POW2"},
+  {AARCH64_OPND_CLASS_IMMEDIATE, "SVE_PRFOP", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_prfop}, "an enumeration value such as PLDL1KEEP"},
   {AARCH64_OPND_CLASS_PRED_REG, "SVE_Pd", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Pd}, "an SVE predicate register"},
   {AARCH64_OPND_CLASS_PRED_REG, "SVE_Pg3", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Pg3}, "an SVE predicate register"},
   {AARCH64_OPND_CLASS_PRED_REG, "SVE_Pg4_5", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_SVE_Pg4_5}, "an SVE predicate register"},
 
 #include <inttypes.h>
 
 #include "opintl.h"
+#include "libiberty.h"
 
 #include "aarch64-opc.h"
 
 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.  */
 
     { 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].  */
+    {  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].  */
 };
 
   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)
       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_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))
        {
 
   FLD_SVE_Zm_16,
   FLD_SVE_Zn,
   FLD_SVE_Zt,
+  FLD_SVE_pattern,
+  FLD_SVE_prfop,
   FLD_SVE_tszh,
 };
 
 
       "a prefetch operation specifier")                                        \
     Y (SYSTEM, hint, "BARRIER_PSB", 0, F (),                           \
       "the PSB option name CSYNC")                                     \
+    Y(IMMEDIATE, imm, "SVE_PATTERN", 0, F(FLD_SVE_pattern),            \
+      "an enumeration value such as POW2")                             \
+    Y(IMMEDIATE, imm, "SVE_PRFOP", 0, F(FLD_SVE_prfop),                        \
+      "an enumeration value such as PLDL1KEEP")                                \
     Y(PRED_REG, regno, "SVE_Pd", 0, F(FLD_SVE_Pd),                     \
       "an SVE predicate register")                                     \
     Y(PRED_REG, regno, "SVE_Pg3", 0, F(FLD_SVE_Pg3),                   \