[AArch64][SVE 24/32] Add AARCH64_OPND_SVE_PATTERN_SCALED
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 21 Sep 2016 15:55:22 +0000 (16:55 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Wed, 21 Sep 2016 15:55:22 +0000 (16:55 +0100)
Some SVE instructions count the number of elements in a given vector
pattern and allow a scale factor of [1, 16] to be applied to the result.
This scale factor is written ", MUL #n", where "MUL" is a new operator.
E.g.:

UQINCD X0, POW2, MUL #2

This patch adds support for this kind of operand.

All existing operators were shifts of some kind, so there was a natural
range of [0, 63] regardless of context.  This was then narrowered further
by later checks (e.g. to [0, 31] when used for 32-bit values).

In contrast, MUL doesn't really have a natural context-independent range.
Rather than pick one arbitrarily, it seemed better to make the "shift"
amount a full 64-bit value and leave the range test to the usual
operand-checking code.  I've rearranged the fields of aarch64_opnd_info
so that this doesn't increase the size of the structure (although I don't
think its size is critical anyway).

include/
* opcode/aarch64.h (AARCH64_OPND_SVE_PATTERN_SCALED): New
aarch64_opnd.
(AARCH64_MOD_MUL): New aarch64_modifier_kind.
(aarch64_opnd_info): Make shifter.amount an int64_t and
rearrange the fields.

opcodes/
* aarch64-tbl.h (AARCH64_OPERANDS): Add an entry for
AARCH64_OPND_SVE_PATTERN_SCALED.
* aarch64-opc.h (FLD_SVE_imm4): New aarch64_field_kind.
* aarch64-opc.c (fields): Add a corresponding entry.
(set_multiplier_out_of_range_error): New function.
(aarch64_operand_modifiers): Add entry for AARCH64_MOD_MUL.
(operand_general_constraint_met_p): Handle
AARCH64_OPND_SVE_PATTERN_SCALED.
(print_register_offset_address): Use PRIi64 to print the
shift amount.
(aarch64_print_operand): Likewise.  Handle
AARCH64_OPND_SVE_PATTERN_SCALED.
* aarch64-opc-2.c: Regenerate.
* aarch64-asm.h (ins_sve_scale): New inserter.
* aarch64-asm.c (aarch64_ins_sve_scale): New function.
* aarch64-asm-2.c: Regenerate.
* aarch64-dis.h (ext_sve_scale): New inserter.
* aarch64-dis.c (aarch64_ext_sve_scale): New function.
* aarch64-dis-2.c: Regenerate.

gas/
* config/tc-aarch64.c (SHIFTED_MUL): New parse_shift_mode.
(parse_shift): Handle it.  Reject AARCH64_MOD_MUL for all other
shift modes.  Skip range tests for AARCH64_MOD_MUL.
(process_omitted_operand): Handle AARCH64_OPND_SVE_PATTERN_SCALED.
(parse_operands): Likewise.

15 files changed:
gas/ChangeLog
gas/config/tc-aarch64.c
include/ChangeLog
include/opcode/aarch64.h
opcodes/ChangeLog
opcodes/aarch64-asm-2.c
opcodes/aarch64-asm.c
opcodes/aarch64-asm.h
opcodes/aarch64-dis-2.c
opcodes/aarch64-dis.c
opcodes/aarch64-dis.h
opcodes/aarch64-opc-2.c
opcodes/aarch64-opc.c
opcodes/aarch64-opc.h
opcodes/aarch64-tbl.h

index d532bb1b4507c65eb5279fdef6b6666eed5c745a..97f1a61d150339cddff1ddbb57741ab32154bc39 100644 (file)
@@ -1,3 +1,11 @@
+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * config/tc-aarch64.c (SHIFTED_MUL): New parse_shift_mode.
+       (parse_shift): Handle it.  Reject AARCH64_MOD_MUL for all other
+       shift modes.  Skip range tests for AARCH64_MOD_MUL.
+       (process_omitted_operand): Handle AARCH64_OPND_SVE_PATTERN_SCALED.
+       (parse_operands): Likewise.
+
 2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * config/tc-aarch64.c (parse_enum_string): New function.
index 7a3a39d2863286ae686cdbbbb69456beb5342ad7..79ee0545a738c192b27d74854850be4458631a7c 100644 (file)
@@ -2882,6 +2882,7 @@ enum parse_shift_mode
   SHIFTED_LOGIC_IMM,           /* "rn{,lsl|lsr|asl|asr|ror #n}" or
                                   "#imm"  */
   SHIFTED_LSL,                 /* bare "lsl #n"  */
+  SHIFTED_MUL,                 /* bare "mul #n"  */
   SHIFTED_LSL_MSL,             /* "lsl|msl #n"  */
   SHIFTED_REG_OFFSET           /* [su]xtw|sxtx {#n} or lsl #n  */
 };
@@ -2923,6 +2924,13 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode)
       return FALSE;
     }
 
+  if (kind == AARCH64_MOD_MUL
+      && mode != SHIFTED_MUL)
+    {
+      set_syntax_error (_("invalid use of 'MUL'"));
+      return FALSE;
+    }
+
   switch (mode)
     {
     case SHIFTED_LOGIC_IMM:
@@ -2949,6 +2957,14 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode)
        }
       break;
 
+    case SHIFTED_MUL:
+      if (kind != AARCH64_MOD_MUL)
+       {
+         set_syntax_error (_("only 'MUL' is permitted"));
+         return FALSE;
+       }
+      break;
+
     case SHIFTED_REG_OFFSET:
       if (kind != AARCH64_MOD_UXTW && kind != AARCH64_MOD_LSL
          && kind != AARCH64_MOD_SXTW && kind != AARCH64_MOD_SXTX)
@@ -3001,7 +3017,11 @@ parse_shift (char **str, aarch64_opnd_info *operand, enum parse_shift_mode mode)
       set_syntax_error (_("constant shift amount required"));
       return FALSE;
     }
-  else if (exp.X_add_number < 0 || exp.X_add_number > 63)
+  /* For parsing purposes, MUL #n has no inherent range.  The range
+     depends on the operand and will be checked by operand-specific
+     routines.  */
+  else if (kind != AARCH64_MOD_MUL
+          && (exp.X_add_number < 0 || exp.X_add_number > 63))
     {
       set_fatal_syntax_error (_("shift amount out of range 0 to 63"));
       return FALSE;
@@ -4863,6 +4883,12 @@ process_omitted_operand (enum aarch64_opnd type, const aarch64_opcode *opcode,
       operand->imm.value = default_value;
       break;
 
+    case AARCH64_OPND_SVE_PATTERN_SCALED:
+      operand->imm.value = default_value;
+      operand->shifter.kind = AARCH64_MOD_MUL;
+      operand->shifter.amount = 1;
+      break;
+
     case AARCH64_OPND_EXCEPTION:
       inst.reloc.type = BFD_RELOC_UNUSED;
       break;
@@ -5373,6 +5399,20 @@ parse_operands (char *str, const aarch64_opcode *opcode)
          info->imm.value = val;
          break;
 
+       case AARCH64_OPND_SVE_PATTERN_SCALED:
+         po_enum_or_fail (aarch64_sve_pattern_array);
+         info->imm.value = val;
+         if (skip_past_comma (&str)
+             && !parse_shift (&str, info, SHIFTED_MUL))
+           goto failure;
+         if (!info->shifter.operator_present)
+           {
+             gas_assert (info->shifter.kind == AARCH64_MOD_NONE);
+             info->shifter.kind = AARCH64_MOD_MUL;
+             info->shifter.amount = 1;
+           }
+         break;
+
        case AARCH64_OPND_SVE_PRFOP:
          po_enum_or_fail (aarch64_sve_prfop_array);
          info->imm.value = val;
index 96da0a3fac9a0956aab79b1f22d42232250940f9..cdac6f56de78c8978e9e28e5854388160e20099b 100644 (file)
@@ -1,3 +1,11 @@
+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * opcode/aarch64.h (AARCH64_OPND_SVE_PATTERN_SCALED): New
+       aarch64_opnd.
+       (AARCH64_MOD_MUL): New aarch64_modifier_kind.
+       (aarch64_opnd_info): Make shifter.amount an int64_t and
+       rearrange the fields.
+
 2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * opcode/aarch64.h (AARCH64_OPND_SVE_PATTERN): New aarch64_opnd.
index dd191cf805f15038d49d4a48061064ccad493f2e..49b4413601c49e8e09914e6fde3c039aec7821a4 100644 (file)
@@ -245,6 +245,7 @@ enum aarch64_opnd
   AARCH64_OPND_BARRIER_PSB,    /* Barrier operand for PSB.  */
 
   AARCH64_OPND_SVE_PATTERN,    /* SVE vector pattern enumeration.  */
+  AARCH64_OPND_SVE_PATTERN_SCALED, /* Likewise, with additional MUL factor.  */
   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.  */
@@ -745,6 +746,7 @@ enum aarch64_modifier_kind
   AARCH64_MOD_SXTH,
   AARCH64_MOD_SXTW,
   AARCH64_MOD_SXTX,
+  AARCH64_MOD_MUL,
 };
 
 bfd_boolean
@@ -836,10 +838,10 @@ struct aarch64_opnd_info
   struct
     {
       enum aarch64_modifier_kind kind;
-      int amount;
       unsigned operator_present: 1;    /* Only valid during encoding.  */
       /* Value of the 'S' field in ld/st reg offset; used only in decoding.  */
       unsigned amount_present: 1;
+      int64_t amount;
     } shifter;
 
   unsigned skip:1;     /* Operand is not completed if there is a fixup needed
index a2afc0d77c6bdcdb710ae8701fdd177779280f32..35a10060d5f15f95df3bcf71a348853a9b72c01d 100644 (file)
@@ -1,3 +1,25 @@
+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * aarch64-tbl.h (AARCH64_OPERANDS): Add an entry for
+       AARCH64_OPND_SVE_PATTERN_SCALED.
+       * aarch64-opc.h (FLD_SVE_imm4): New aarch64_field_kind.
+       * aarch64-opc.c (fields): Add a corresponding entry.
+       (set_multiplier_out_of_range_error): New function.
+       (aarch64_operand_modifiers): Add entry for AARCH64_MOD_MUL.
+       (operand_general_constraint_met_p): Handle
+       AARCH64_OPND_SVE_PATTERN_SCALED.
+       (print_register_offset_address): Use PRIi64 to print the
+       shift amount.
+       (aarch64_print_operand): Likewise.  Handle
+       AARCH64_OPND_SVE_PATTERN_SCALED.
+       * aarch64-opc-2.c: Regenerate.
+       * aarch64-asm.h (ins_sve_scale): New inserter.
+       * aarch64-asm.c (aarch64_ins_sve_scale): New function.
+       * aarch64-asm-2.c: Regenerate.
+       * aarch64-dis.h (ext_sve_scale): New inserter.
+       * aarch64-dis.c (aarch64_ext_sve_scale): New function.
+       * aarch64-dis-2.c: Regenerate.
+
 2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * aarch64-tbl.h (AARCH64_OPERANDS): Add entries for
index 0a6e476314f0b99067d6fc20809c355a3e7f6d68..039b9beac453f623c7aee2e946645f42c08b459c 100644 (file)
@@ -480,7 +480,6 @@ aarch64_insert_operand (const aarch64_operand *self,
     case 27:
     case 35:
     case 36:
-    case 91:
     case 92:
     case 93:
     case 94:
@@ -494,7 +493,8 @@ aarch64_insert_operand (const aarch64_operand *self,
     case 102:
     case 103:
     case 104:
-    case 107:
+    case 105:
+    case 108:
       return aarch64_ins_regno (self, info, code, inst);
     case 12:
       return aarch64_ins_reg_extended (self, info, code, inst);
@@ -532,7 +532,7 @@ aarch64_insert_operand (const aarch64_operand *self,
     case 69:
     case 70:
     case 89:
-    case 90:
+    case 91:
       return aarch64_ins_imm (self, info, code, inst);
     case 38:
     case 39:
@@ -583,10 +583,12 @@ aarch64_insert_operand (const aarch64_operand *self,
       return aarch64_ins_prfop (self, info, code, inst);
     case 88:
       return aarch64_ins_hint (self, info, code, inst);
-    case 105:
-      return aarch64_ins_sve_index (self, info, code, inst);
+    case 90:
+      return aarch64_ins_sve_scale (self, info, code, inst);
     case 106:
-    case 108:
+      return aarch64_ins_sve_index (self, info, code, inst);
+    case 107:
+    case 109:
       return aarch64_ins_sve_reglist (self, info, code, inst);
     default: assert (0); abort ();
     }
index c045f9e4b41ffe8f2c790a2cfee5eaf5d35c02af..117a3c6f98e8bdc875e9fe28d2f9081076a8d9d4 100644 (file)
@@ -772,6 +772,19 @@ aarch64_ins_sve_reglist (const aarch64_operand *self,
   return NULL;
 }
 
+/* Encode <pattern>{, MUL #<amount>}.  The fields array specifies which
+   fields to use for <pattern>.  <amount> - 1 is encoded in the SVE_imm4
+   field.  */
+const char *
+aarch64_ins_sve_scale (const aarch64_operand *self,
+                      const aarch64_opnd_info *info, aarch64_insn *code,
+                      const aarch64_inst *inst ATTRIBUTE_UNUSED)
+{
+  insert_all_fields (self, code, info->imm.value);
+  insert_field (FLD_SVE_imm4, code, info->shifter.amount - 1, 0);
+  return NULL;
+}
+
 /* Miscellaneous encoding functions.  */
 
 /* Encode size[0], i.e. bit 22, for
index ede366c00f26b118bf87d0dab98be73ece92981f..ac5faebe193da0feeae63821c7311c10848f7026 100644 (file)
@@ -71,6 +71,7 @@ AARCH64_DECL_OPD_INSERTER (ins_reg_extended);
 AARCH64_DECL_OPD_INSERTER (ins_reg_shifted);
 AARCH64_DECL_OPD_INSERTER (ins_sve_index);
 AARCH64_DECL_OPD_INSERTER (ins_sve_reglist);
+AARCH64_DECL_OPD_INSERTER (ins_sve_scale);
 
 #undef AARCH64_DECL_OPD_INSERTER
 
index 9f936f0b833a2a469c4aec843ecbf6dd09c887b4..124385dacf5b93beb18dbc2ec3b786423921f6ee 100644 (file)
@@ -10426,7 +10426,6 @@ aarch64_extract_operand (const aarch64_operand *self,
     case 27:
     case 35:
     case 36:
-    case 91:
     case 92:
     case 93:
     case 94:
@@ -10440,7 +10439,8 @@ aarch64_extract_operand (const aarch64_operand *self,
     case 102:
     case 103:
     case 104:
-    case 107:
+    case 105:
+    case 108:
       return aarch64_ext_regno (self, info, code, inst);
     case 8:
       return aarch64_ext_regrt_sysins (self, info, code, inst);
@@ -10483,7 +10483,7 @@ aarch64_extract_operand (const aarch64_operand *self,
     case 69:
     case 70:
     case 89:
-    case 90:
+    case 91:
       return aarch64_ext_imm (self, info, code, inst);
     case 38:
     case 39:
@@ -10536,10 +10536,12 @@ aarch64_extract_operand (const aarch64_operand *self,
       return aarch64_ext_prfop (self, info, code, inst);
     case 88:
       return aarch64_ext_hint (self, info, code, inst);
-    case 105:
-      return aarch64_ext_sve_index (self, info, code, inst);
+    case 90:
+      return aarch64_ext_sve_scale (self, info, code, inst);
     case 106:
-    case 108:
+      return aarch64_ext_sve_index (self, info, code, inst);
+    case 107:
+    case 109:
       return aarch64_ext_sve_reglist (self, info, code, inst);
     default: assert (0); abort ();
     }
index ab93234e28afd54630199f2ea7ce35f7b948d070..1d00c0aa8c89cfb213a8c1312a6801face1b3c3f 100644 (file)
@@ -1219,6 +1219,26 @@ aarch64_ext_sve_reglist (const aarch64_operand *self,
   info->reglist.num_regs = get_opcode_dependent_value (inst->opcode);
   return 1;
 }
+
+/* Decode <pattern>{, MUL #<amount>}.  The fields array specifies which
+   fields to use for <pattern>.  <amount> - 1 is encoded in the SVE_imm4
+   field.  */
+int
+aarch64_ext_sve_scale (const aarch64_operand *self,
+                      aarch64_opnd_info *info, aarch64_insn code,
+                      const aarch64_inst *inst)
+{
+  int val;
+
+  if (!aarch64_ext_imm (self, info, code, inst))
+    return 0;
+  val = extract_field (FLD_SVE_imm4, code, 0);
+  info->shifter.kind = AARCH64_MOD_MUL;
+  info->shifter.amount = val + 1;
+  info->shifter.operator_present = (val != 0);
+  info->shifter.amount_present = (val != 0);
+  return 1;
+}
 \f
 /* Bitfields that are commonly used to encode certain operands' information
    may be partially used as part of the base opcode in some instructions.
index 5efb9044ba9d2840a663946dca716f2405cacc07..92f5ad43c48a7cd6eb491d850f5527b0cf37faf6 100644 (file)
@@ -93,6 +93,7 @@ AARCH64_DECL_OPD_EXTRACTOR (ext_reg_extended);
 AARCH64_DECL_OPD_EXTRACTOR (ext_reg_shifted);
 AARCH64_DECL_OPD_EXTRACTOR (ext_sve_index);
 AARCH64_DECL_OPD_EXTRACTOR (ext_sve_reglist);
+AARCH64_DECL_OPD_EXTRACTOR (ext_sve_scale);
 
 #undef AARCH64_DECL_OPD_EXTRACTOR
 
index 39050532914ac50bde1f154f5b5d3602956a8e2e..8f221b893ddc413080d3a4dcbd5c3c3bc2f78667 100644 (file)
@@ -114,6 +114,7 @@ const struct aarch64_operand aarch64_operands[] =
   {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_PATTERN_SCALED", 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"},
index 934c14db2a3c61910b1db763c5992325411ec376..326b94e71e956980554b22bdaab1247832f2b3c6 100644 (file)
@@ -279,6 +279,7 @@ const aarch64_field fields[] =
     { 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].  */
@@ -359,6 +360,7 @@ const struct aarch64_name_value_pair aarch64_operand_modifiers [] =
     {"sxth", 0x5},
     {"sxtw", 0x6},
     {"sxtx", 0x7},
+    {"mul", 0x0},
     {NULL, 0},
 };
 
@@ -1303,6 +1305,18 @@ set_sft_amount_out_of_range_error (aarch64_operand_error *mismatch_detail,
                          _("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)
@@ -2001,6 +2015,15 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
            }
          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;
        }
@@ -2525,7 +2548,8 @@ print_register_offset_address (char *buf, size_t size,
   if (print_extend_p)
     {
       if (print_amount_p)
-       snprintf (tb, sizeof (tb), ",%s #%d", shift_name, opnd->shifter.amount);
+       snprintf (tb, sizeof (tb), ",%s #%" PRIi64, shift_name,
+                 opnd->shifter.amount);
       else
        snprintf (tb, sizeof (tb), ",%s", shift_name);
     }
@@ -2620,7 +2644,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
            }
        }
       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);
@@ -2637,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, %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);
@@ -2760,6 +2784,26 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
        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));
@@ -2794,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)
-       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);
@@ -2806,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
-       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;
index b54f35edbcf20108c06d6b941861f2af5b8eafe8..3406f6e9f2b4c3897fda8f6f3027e88e8030506e 100644 (file)
@@ -106,6 +106,7 @@ enum aarch64_field_kind
   FLD_SVE_Zm_16,
   FLD_SVE_Zn,
   FLD_SVE_Zt,
+  FLD_SVE_imm4,
   FLD_SVE_pattern,
   FLD_SVE_prfop,
   FLD_SVE_tszh,
index 73415f7222249af61e9f0ab067c1069b70d109e3..491235f91404bb06e595434ae63601d1feb9e818 100644 (file)
@@ -2822,6 +2822,8 @@ struct aarch64_opcode aarch64_opcode_table[] =
       "the PSB option name CSYNC")                                     \
     Y(IMMEDIATE, imm, "SVE_PATTERN", 0, F(FLD_SVE_pattern),            \
       "an enumeration value such as POW2")                             \
+    Y(IMMEDIATE, sve_scale, "SVE_PATTERN_SCALED", 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),                     \