AArch64: Refactor verifiers to make more general.
authorTamar Christina <tamar.christina@arm.com>
Wed, 3 Oct 2018 17:37:07 +0000 (18:37 +0100)
committerTamar Christina <tamar.christina@arm.com>
Wed, 3 Oct 2018 17:40:48 +0000 (18:40 +0100)
The current verifiers only take an instruction description and encoded value as
arguments.  This was enough when the verifiers only needed to do simple checking
but it's insufficient for the purposes of validating instruction sequences.

This patch adds the required arguments and also a flag to allow a verifier to
distinguish between whether it's being run during encoding or decoding.  It also
allows for errors and warnings to be returned by a verifier instead of a simple
pass/fail.

include/

* opcode/aarch64.h (struct aarch64_opcode): Expand verifiers to take
more arguments.

opcodes/

* aarch64-dis.c (aarch64_opcode_decode): Update verifier call.
* aarch64-opc.c (verify_ldpsw): Update arguments.

include/ChangeLog
include/opcode/aarch64.h
opcodes/ChangeLog
opcodes/aarch64-dis.c
opcodes/aarch64-opc.c

index 97f36ed1920615b986aa6a42c65b10f4d46e7c6a..dc200a10c944bcec7001c8e23404d17a83f11f6d 100644 (file)
@@ -1,3 +1,8 @@
+2018-10-03  Tamar Christina  <tamar.christina@arm.com>
+
+       * opcode/aarch64.h (struct aarch64_opcode): Expand verifiers to take
+       more arguments.
+
 2018-10-03  Tamar Christina  <tamar.christina@arm.com>
 
        * opcode/aarch64.h (enum err_type): New.
index 40de440c9b91df9170c536e6231370f959e009e7..751d7bbaae5243f17ee2cb3d65818a46cdfd0b9b 100644 (file)
@@ -727,7 +727,9 @@ struct aarch64_opcode
   unsigned char tied_operand;
 
   /* If non-NULL, a function to verify that a given instruction is valid.  */
-  bfd_boolean (* verifier) (const struct aarch64_opcode *, const aarch64_insn);
+  enum err_type (* verifier) (const struct aarch64_inst *, const aarch64_insn,
+                             bfd_vma, bfd_boolean, aarch64_operand_error *,
+                             struct aarch64_instr_sequence *);
 };
 
 typedef struct aarch64_opcode aarch64_opcode;
index 1da4e80335c4581538cec562f3eb6bd8cbae511b..aae54593ff081f1673831282ff41db6c00154fb9 100644 (file)
@@ -1,3 +1,8 @@
+2018-10-03  Tamar Christina  <tamar.christina@arm.com>
+
+       * aarch64-dis.c (aarch64_opcode_decode): Update verifier call.
+       * aarch64-opc.c (verify_ldpsw): Update arguments.
+
 2018-10-03  Tamar Christina  <tamar.christina@arm.com>
 
        * aarch64-dis.c (ERR_OK, ERR_UND, ERR_UNP, ERR_NYI): Remove.
index c08c82fb9950be57808bc2fd8b59de5a1086bf22..373ddae8a126c7551388f12da356a326261b5032 100644 (file)
@@ -2885,7 +2885,8 @@ aarch64_opcode_decode (const aarch64_opcode *opcode, const aarch64_insn code,
     }
 
   /* If the opcode has a verifier, then check it now.  */
-  if (opcode->verifier && ! opcode->verifier (opcode, code))
+  if (opcode->verifier
+      && opcode->verifier (inst, code, 0, FALSE, errors, NULL) != ERR_OK)
     {
       DEBUG_TRACE ("operand verifier FAIL");
       goto decode_fail;
index ba2af7bfc26d2f760f19cdbdd07ebe5535308d72..f35f0d692d3e64a14865a6fec423f8f938473a98 100644 (file)
@@ -4486,9 +4486,12 @@ aarch64_sys_ins_reg_supported_p (const aarch64_feature_set features,
 #define BIT(INSN,BT)     (((INSN) >> (BT)) & 1)
 #define BITS(INSN,HI,LO) (((INSN) >> (LO)) & ((1 << (((HI) - (LO)) + 1)) - 1))
 
-static bfd_boolean
-verify_ldpsw (const struct aarch64_opcode * opcode ATTRIBUTE_UNUSED,
-             const aarch64_insn insn)
+static enum err_type
+verify_ldpsw (const struct aarch64_inst *inst ATTRIBUTE_UNUSED,
+             const aarch64_insn insn, bfd_vma pc ATTRIBUTE_UNUSED,
+             bfd_boolean encoding ATTRIBUTE_UNUSED,
+             aarch64_operand_error *mismatch_detail ATTRIBUTE_UNUSED,
+             aarch64_instr_sequence *insn_block ATTRIBUTE_UNUSED)
 {
   int t  = BITS (insn, 4, 0);
   int n  = BITS (insn, 9, 5);
@@ -4498,17 +4501,17 @@ verify_ldpsw (const struct aarch64_opcode * opcode ATTRIBUTE_UNUSED,
     {
       /* Write back enabled.  */
       if ((t == n || t2 == n) && n != 31)
-       return FALSE;
+       return ERR_UND;
     }
 
   if (BIT (insn, 22))
     {
       /* Load */
       if (t == t2)
-       return FALSE;
+       return ERR_UND;
     }
 
-  return TRUE;
+  return ERR_OK;
 }
 
 /* Return true if VALUE cannot be moved into an SVE register using DUP