[V4,6/8] opcodes: aarch64: enforce checks on subclass flags in aarch64-gen.c

Message ID 20240701025404.3361349-7-indu.bhagat@oracle.com
State New
Headers
Series Add SCFI support for aarch64 |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Indu Bhagat July 1, 2024, 2:54 a.m. UTC
  [New in V4]

Enforce some checks on the newly added subclass flags:
  - If a subclass is set of one insn of an iclass, every insn of that
    iclass must have non-zero subclass field.
  - For all other iclasses, the subclass bits are zero for all insns.

include/
        * opcode/aarch64.h (enum aarch64_insn_class): Identify the
	maximum iclass enum value.

opcodes/
        * aarch64-gen.c (iclass_has_subclasses_p): New array of bool.
        (read_table): Enforce checks on subclass flags.
---
 include/opcode/aarch64.h |  3 ++-
 opcodes/aarch64-gen.c    | 19 +++++++++++++++++++
 2 files changed, 21 insertions(+), 1 deletion(-)
  

Patch

diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index c3ac1326b9c..82171b037f6 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -1082,7 +1082,8 @@  enum aarch64_insn_class
   sve2_urqvs,
   sve_index1,
   rcpc3,
-  lut
+  lut,
+  last_iclass = lut
 };
 
 /* Opcode enumerators.  */
diff --git a/opcodes/aarch64-gen.c b/opcodes/aarch64-gen.c
index 02dcde1f676..2473f6704ce 100644
--- a/opcodes/aarch64-gen.c
+++ b/opcodes/aarch64-gen.c
@@ -123,6 +123,8 @@  get_aarch64_opcode (const opcode_node *opcode_node)
   return &index2table (opcode_node->index)[real_index (opcode_node->index)];
 }
 
+static bool iclass_has_subclasses_p[last_iclass];
+
 static void
 read_table (const struct aarch64_opcode* table)
 {
@@ -181,6 +183,9 @@  read_table (const struct aarch64_opcode* table)
 	  ++errors;
 	}
 
+      if (ent->flags & F_SUBCLASS)
+	iclass_has_subclasses_p[ent->iclass] = true;
+
       *new_ent = new_opcode_node ();
       (*new_ent)->opcode = ent->opcode;
       (*new_ent)->mask = ent->mask;
@@ -188,6 +193,20 @@  read_table (const struct aarch64_opcode* table)
       new_ent = &((*new_ent)->next);
     } while ((++ent)->name);
 
+  ent = table;
+  do
+    {
+      /* If a subclass is set for one insn of an iclass, every insn of that
+	 iclass must have non-zero subclass field.  */
+      if ((iclass_has_subclasses_p[ent->iclass] && !(ent->flags & F_SUBCLASS))
+	  || (!iclass_has_subclasses_p[ent->iclass] && (ent->flags & F_SUBCLASS)))
+	{
+	    fprintf (stderr, "%s: unexpected subclass\n", ent->name);
+	    ++errors;
+	}
+      ent++;
+    } while (ent->name);
+
   if (errors)
     {
       fprintf (stderr, "%u errors, exiting\n", errors);