summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2016-09-21 16:55:22 +0100
committerRichard Sandiford <richard.sandiford@arm.com>2016-09-21 16:55:22 +0100
commit2442d8466e221ba6cf4ec4bd2a819fdcb1e5ea7e (patch)
tree3cf11472e060354947af66613dd1b4a6361f9b02
parent245d2e3fe8d9ff35c65ed1329609fb7e59034877 (diff)
downloadbinutils-gdb-2442d8466e221ba6cf4ec4bd2a819fdcb1e5ea7e.tar.gz
[AArch64][SVE 24/32] Add AARCH64_OPND_SVE_PATTERN_SCALED
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.
-rw-r--r--gas/ChangeLog8
-rw-r--r--gas/config/tc-aarch64.c42
-rw-r--r--include/ChangeLog8
-rw-r--r--include/opcode/aarch64.h4
-rw-r--r--opcodes/ChangeLog22
-rw-r--r--opcodes/aarch64-asm-2.c14
-rw-r--r--opcodes/aarch64-asm.c13
-rw-r--r--opcodes/aarch64-asm.h1
-rw-r--r--opcodes/aarch64-dis-2.c14
-rw-r--r--opcodes/aarch64-dis.c20
-rw-r--r--opcodes/aarch64-dis.h1
-rw-r--r--opcodes/aarch64-opc-2.c1
-rw-r--r--opcodes/aarch64-opc.c54
-rw-r--r--opcodes/aarch64-opc.h1
-rw-r--r--opcodes/aarch64-tbl.h2
15 files changed, 186 insertions, 19 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index d532bb1b450..97f1a61d150 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,13 @@
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.
(po_enum_or_fail): New macro.
(parse_operands): Handle AARCH64_OPND_SVE_PATTERN and
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 7a3a39d2863..79ee0545a73 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -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;
diff --git a/include/ChangeLog b/include/ChangeLog
index 96da0a3fac9..cdac6f56de7 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,5 +1,13 @@
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.
(AARCH64_OPND_SVE_PRFOP): Likewise.
(aarch64_sve_pattern_array): Declare.
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index dd191cf805f..49b4413601c 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -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
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index a2afc0d77c6..35a10060d5f 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,27 @@
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
AARCH64_OPND_SVE_PATTERN and AARCH64_OPND_SVE_PRFOP.
* aarch64-opc.h (FLD_SVE_pattern): New aarch64_field_kind.
diff --git a/opcodes/aarch64-asm-2.c b/opcodes/aarch64-asm-2.c
index 0a6e476314f..039b9beac45 100644
--- a/opcodes/aarch64-asm-2.c
+++ b/opcodes/aarch64-asm-2.c
@@ -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 ();
}
diff --git a/opcodes/aarch64-asm.c b/opcodes/aarch64-asm.c
index c045f9e4b41..117a3c6f98e 100644
--- a/opcodes/aarch64-asm.c
+++ b/opcodes/aarch64-asm.c
@@ -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
diff --git a/opcodes/aarch64-asm.h b/opcodes/aarch64-asm.h
index ede366c00f2..ac5faebe193 100644
--- a/opcodes/aarch64-asm.h
+++ b/opcodes/aarch64-asm.h
@@ -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
diff --git a/opcodes/aarch64-dis-2.c b/opcodes/aarch64-dis-2.c
index 9f936f0b833..124385dacf5 100644
--- a/opcodes/aarch64-dis-2.c
+++ b/opcodes/aarch64-dis-2.c
@@ -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 ();
}
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
index ab93234e28a..1d00c0aa8c8 100644
--- a/opcodes/aarch64-dis.c
+++ b/opcodes/aarch64-dis.c
@@ -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;
+}
/* Bitfields that are commonly used to encode certain operands' information
may be partially used as part of the base opcode in some instructions.
diff --git a/opcodes/aarch64-dis.h b/opcodes/aarch64-dis.h
index 5efb9044ba9..92f5ad43c48 100644
--- a/opcodes/aarch64-dis.h
+++ b/opcodes/aarch64-dis.h
@@ -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
diff --git a/opcodes/aarch64-opc-2.c b/opcodes/aarch64-opc-2.c
index 39050532914..8f221b893dd 100644
--- a/opcodes/aarch64-opc-2.c
+++ b/opcodes/aarch64-opc-2.c
@@ -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"},
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index 934c14db2a3..326b94e71e9 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -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;
diff --git a/opcodes/aarch64-opc.h b/opcodes/aarch64-opc.h
index b54f35edbcf..3406f6e9f2b 100644
--- a/opcodes/aarch64-opc.h
+++ b/opcodes/aarch64-opc.h
@@ -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,
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index 73415f72222..491235f9140 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -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), \