This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [AArch64][SVE 13/32] Add an F_STRICT flag
On 23/08/16 10:14, Richard Sandiford wrote:
> SVE predicate operands can appear in three forms:
>
> 1. unsuffixed: "Pn"
> 2. with a predication type: "Pn/[ZM]"
> 3. with a size suffix: "Pn.[BHSD]"
>
> No variation is allowed: unsuffixed operands cannot have a (redundant)
> suffix, and the suffixes can never be dropped. Unsuffixed Pn are used
> in LDR and STR, but they are also used for Pg operands in cases where
> the result is scalar and where there is therefore no choice to be made
> between "merging" and "zeroing". This means that some Pg operands have
> suffixes and others don't.
>
> It would be possible to use context-sensitive parsing to handle
> this difference. The tc-aarch64.c code would then raise an error
> if the wrong kind of suffix is used for a particular instruction.
>
> However, we get much more user-friendly error messages if we parse
> all three forms for all SVE instructions and record the suffix as a
> qualifier. The normal qualifier matching code can then report cases
> where the wrong kind of suffix is used. This is a slight extension
> of existing usage, which really only checks for the wrong choice of
> suffix within a particular kind of suffix.
>
> The only catch is a that a "NIL" entry in the qualifier list
> specifically means "no suffix should be present" (case 1 above).
> NIL isn't a wildcard here. It also means that an instruction that
> requires all-NIL qualifiers can fail to match (because a suffix was
> supplied when it shouldn't have been); this requires a slight change
> to find_best_match.
>
> This patch adds an F_STRICT flag to select this behaviour.
> The flag will be set for all SVE instructions. The behaviour
> for other instructions doesn't change.
>
> OK to install?
>
> Thanks,
> Richard
>
>
> include/opcode/
> * aarch64.h (F_STRICT): New flag.
>
> opcodes/
> * aarch64-opc.c (match_operands_qualifier): Handle F_STRICT.
>
> gas/
> * config/tc-aarch64.c (find_best_match): Simplify, allowing an
> instruction with all-NIL qualifiers to fail to match.
OK.
R.
>
> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index 165ab9a..9591704 100644
> --- a/gas/config/tc-aarch64.c
> +++ b/gas/config/tc-aarch64.c
> @@ -4182,7 +4182,7 @@ find_best_match (const aarch64_inst *instr,
> }
>
> max_num_matched = 0;
> - idx = -1;
> + idx = 0;
>
> /* For each pattern. */
> for (i = 0; i < AARCH64_MAX_QLF_SEQ_NUM; ++i, ++qualifiers_list)
> @@ -4194,9 +4194,6 @@ find_best_match (const aarch64_inst *instr,
> if (empty_qualifier_sequence_p (qualifiers) == TRUE)
> {
> DEBUG_TRACE_IF (i == 0, "empty list of qualifier sequence");
> - if (i != 0 && idx == -1)
> - /* If nothing has been matched, return the 1st sequence. */
> - idx = 0;
> break;
> }
>
> diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
> index 1e38749..24a2ddb 100644
> --- a/include/opcode/aarch64.h
> +++ b/include/opcode/aarch64.h
> @@ -598,7 +598,9 @@ extern aarch64_opcode aarch64_opcode_table[];
> #define F_OD(X) (((X) & 0x7) << 24)
> /* Instruction has the field of 'sz'. */
> #define F_LSE_SZ (1 << 27)
> -/* Next bit is 28. */
> +/* Require an exact qualifier match, even for NIL qualifiers. */
> +#define F_STRICT (1ULL << 28)
> +/* Next bit is 29. */
>
> static inline bfd_boolean
> alias_opcode_p (const aarch64_opcode *opcode)
> diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
> index 322b991..d870fd6 100644
> --- a/opcodes/aarch64-opc.c
> +++ b/opcodes/aarch64-opc.c
> @@ -854,7 +854,7 @@ aarch64_find_best_match (const aarch64_inst *inst,
> 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,
> @@ -864,6 +864,15 @@ match_operands_qualifier (aarch64_inst *inst, bfd_boolean update_p)
> 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)
>