[AArch64][SVE 13/32] Add an F_STRICT flag
authorRichard Sandiford <richard.sandiford@arm.com>
Wed, 21 Sep 2016 15:51:00 +0000 (16:51 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Wed, 21 Sep 2016 15:51:00 +0000 (16:51 +0100)
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.

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.

gas/ChangeLog
gas/config/tc-aarch64.c
include/ChangeLog
include/opcode/aarch64.h
opcodes/ChangeLog
opcodes/aarch64-opc.c

index d7df100d64e07b84f788b4b7c571e32dee70849d..ac9d359cd7d2b45eac93257f65660aaba605ae29 100644 (file)
@@ -1,3 +1,8 @@
+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * config/tc-aarch64.c (find_best_match): Simplify, allowing an
+       instruction with all-NIL qualifiers to fail to match.
+
 2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * config/tc-aarch64.c (parse_address_main): Remove reloc and
index f82fdb96456c570c402636b40dbaa8e4a120dd68..f50de702c9c3082d410e7fdbdf71a70b3c538c50 100644 (file)
@@ -4134,7 +4134,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)
@@ -4146,9 +4146,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;
        }
 
index 2c922c4e73045309c6b179b8cb3df821b135e23b..21ddbfdd8249295484864b2f9ac35d9a6f466cd0 100644 (file)
@@ -1,3 +1,7 @@
+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * opcode/aarch64.h (F_STRICT): New flag.
+
 2016-09-07  Richard Earnshaw  <rearnsha@arm.com>
 
        * opcode/arm.h (ARM_ARCH_V8A_CRC): New architecture.
index 1e38749c3019b0d7f8803044a2a91c8b1029c54d..24a2ddbdc0576a39721e19ed67f75a80fee9e097 100644 (file)
@@ -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)
index b47f034144a7c8b9ede1ed23553c210006af2130..c12ea3a9d4d61c76cf3e16778c953f44b20c192f 100644 (file)
@@ -1,3 +1,7 @@
+2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * aarch64-opc.c (match_operands_qualifier): Handle F_STRICT.
+
 2016-09-21  Richard Sandiford  <richard.sandiford@arm.com>
 
        * aarch64-gen.c (indented_print): Avoid hard-coded indentation limit.
index 322b991a4bc3e3ade711ba025747ea2664d7a714..d870fd6203c535b5e9d74056d0b1eed9a2be6861 100644 (file)
@@ -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)