diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2016-09-21 16:55:22 +0100 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2016-09-21 16:55:22 +0100 |
commit | 2442d8466e221ba6cf4ec4bd2a819fdcb1e5ea7e (patch) | |
tree | 3cf11472e060354947af66613dd1b4a6361f9b02 | |
parent | 245d2e3fe8d9ff35c65ed1329609fb7e59034877 (diff) | |
download | gdb-2442d8466e221ba6cf4ec4bd2a819fdcb1e5ea7e.zip gdb-2442d8466e221ba6cf4ec4bd2a819fdcb1e5ea7e.tar.gz gdb-2442d8466e221ba6cf4ec4bd2a819fdcb1e5ea7e.tar.bz2 |
[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/ChangeLog | 8 | ||||
-rw-r--r-- | gas/config/tc-aarch64.c | 42 | ||||
-rw-r--r-- | include/ChangeLog | 8 | ||||
-rw-r--r-- | include/opcode/aarch64.h | 4 | ||||
-rw-r--r-- | opcodes/ChangeLog | 22 | ||||
-rw-r--r-- | opcodes/aarch64-asm-2.c | 14 | ||||
-rw-r--r-- | opcodes/aarch64-asm.c | 13 | ||||
-rw-r--r-- | opcodes/aarch64-asm.h | 1 | ||||
-rw-r--r-- | opcodes/aarch64-dis-2.c | 14 | ||||
-rw-r--r-- | opcodes/aarch64-dis.c | 20 | ||||
-rw-r--r-- | opcodes/aarch64-dis.h | 1 | ||||
-rw-r--r-- | opcodes/aarch64-opc-2.c | 1 | ||||
-rw-r--r-- | opcodes/aarch64-opc.c | 54 | ||||
-rw-r--r-- | opcodes/aarch64-opc.h | 1 | ||||
-rw-r--r-- | opcodes/aarch64-tbl.h | 2 |
15 files changed, 186 insertions, 19 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index d532bb1..97f1a61 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 7a3a39d..79ee054 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 96da0a3..cdac6f5 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 dd191cf..49b4413 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 a2afc0d..35a1006 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 0a6e476..039b9be 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 c045f9e..117a3c6 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 ede366c..ac5faeb 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 9f936f0..124385d 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 ab93234..1d00c0a 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 5efb904..92f5ad4 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 3905053..8f221b8 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 934c14d..326b94e 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 b54f35e..3406f6e 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 73415f7..491235f 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), \ |