[llvm-branch-commits] [llvm] [AArch64][llvm] Separate TLBI-only feature gating from TLBIP aliases (PR #187400)

Jonathan Thackray via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Mar 26 09:56:54 PDT 2026


https://github.com/jthackray updated https://github.com/llvm/llvm-project/pull/187400

>From 0ea39f7eb7ec564f1281ec398f690ac3e8468f63 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Wed, 18 Mar 2026 20:54:50 +0000
Subject: [PATCH 1/7] [AArch64][llvm] Separate TLBI-only feature gating from
 TLBIP aliases

Refactor the TLBI system operand definitions so that TLBI and TLBIP
records are emitted through separate helper multiclasses, whilst keeping
the table layout readable.

The feature-scoped wrappers now apply FeatureTLB_RMI, FeatureRME, and
FeatureTLBIW only to TLBI records (it was previously incorrectly also
applied to TLBIP instructions), while TLBIP aliases remain gated only
by FeatureD128, including their nXS forms.

Update testcases accordingly.
---
 .../Target/AArch64/AArch64SystemOperands.td   | 178 ++++++++++--------
 llvm/test/MC/AArch64/armv9a-tlbip.s           |  17 +-
 2 files changed, 111 insertions(+), 84 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index 257a4958e8305..d914b253c5358 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -903,24 +903,54 @@ multiclass TLBITableBase {
 defm TLBI  : TLBITableBase;
 defm TLBIP : TLBITableBase;
 
-multiclass TLBI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn, bits<4> crm,
-             bits<3> op2, int reguse = REG_REQUIRED> {
-  def : TLBIEntry<name, op1, crn, crm, op2, reguse>;
-  def : TLBIEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, reguse> {
-    let Encoding{7} = 1;
-    let ExtraRequires = ["AArch64::FeatureXS"];
-  }
-  if !eq(hasTLBIP, true) then {
-    def : TLBIPEntry<name, op1, crn, crm, op2, reguse> {
-      let ExtraRequires = ["AArch64::FeatureD128"];
+multiclass TLBI_Base<string name, bits<3> op1, bits<4> crn, bits<4> crm,
+                     bits<3> op2, int reguse = REG_REQUIRED,
+                     list<string> extra_requires = []> {
+  foreach nxs = [0, 1] in {
+    defvar VariantName = !if(nxs, !strconcat(name, "nXS"), name);
+    defvar VariantRequires = !if(nxs,
+                                 extra_requires # ["AArch64::FeatureXS"],
+                                 extra_requires);
+    def : TLBIEntry<VariantName, op1, crn, crm, op2, reguse> {
+      let Encoding{7} = nxs;
+      let ExtraRequires = VariantRequires;
     }
-    def : TLBIPEntry<!strconcat(name, "nXS"), op1, crn, crm, op2, reguse> {
-      let Encoding{7} = 1;
-      let ExtraRequires = ["AArch64::FeatureD128"];
+  }
+}
+
+multiclass TLBIP_Base<string name, bits<3> op1, bits<4> crn, bits<4> crm,
+                      bits<3> op2, int reguse = REG_REQUIRED,
+                      list<string> extra_requires = ["AArch64::FeatureD128"]> {
+  foreach nxs = [0, 1] in {
+    // TLBIP instructions aren't gated by FeatureXS like TLBI ones
+    defvar VariantName = !if(nxs, !strconcat(name, "nXS"), name);
+    def : TLBIPEntry<VariantName, op1, crn, crm, op2, reguse> {
+      let Encoding{7} = nxs;
+      let ExtraRequires = extra_requires;
     }
   }
 }
 
+multiclass TLBI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn,
+                bits<4> crm, bits<3> op2, int reguse = REG_REQUIRED> {
+  defm : TLBI_Base<name, op1, crn, crm, op2, reguse>;
+  if !eq(hasTLBIP, true) then {
+    defm : TLBIP_Base<name, op1, crn, crm, op2, reguse>;
+  }
+}
+
+multiclass TLBI_RMI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn,
+                    bits<4> crm, bits<3> op2, int reguse = REG_REQUIRED> {
+  let Requires = ["AArch64::FeatureTLB_RMI"] in {
+    defm : TLBI_Base<name, op1, crn, crm, op2, reguse>;
+  }
+  // TLBIP instructions aren't gated by FeatureTLB_RMI
+  if !eq(hasTLBIP, true) then {
+    defm : TLBIP_Base<name, op1, crn, crm, op2, reguse>;
+  }
+}
+
+// TLBI and TLBIP instructions encodings
 //                   hasTLBIP  op1    CRn     CRm     op2    reguse
 defm : TLBI<"IPAS2E1IS",    1, 0b100, 0b1000, 0b0000, 0b001, REG_REQUIRED>;
 defm : TLBI<"IPAS2LE1IS",   1, 0b100, 0b1000, 0b0000, 0b101, REG_REQUIRED>;
@@ -955,76 +985,74 @@ defm : TLBI<"VALE3",        1, 0b110, 0b1000, 0b0111, 0b101, REG_REQUIRED>;
 defm : TLBI<"VMALLS12E1",   0, 0b100, 0b1000, 0b0111, 0b110, REG_NONE>;
 defm : TLBI<"VAALE1",       1, 0b000, 0b1000, 0b0111, 0b111, REG_REQUIRED>;
 
-// Armv8.4-A Translation Lookaside Buffer Instructions (TLBI)
-let Requires = ["AArch64::FeatureTLB_RMI"] in {
+// Armv8.4-A Translation Lookaside Buffer Instructions (TLBI and TLBIP)
 // Armv8.4-A Outer Sharable TLB Maintenance instructions:
-//                   hasTLBIP  op1    CRn     CRm     op2    reguse
-defm : TLBI<"VMALLE1OS",    0, 0b000, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
-defm : TLBI<"VAE1OS",       1, 0b000, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
-defm : TLBI<"ASIDE1OS",     0, 0b000, 0b1000, 0b0001, 0b010, REG_REQUIRED>;
-defm : TLBI<"VAAE1OS",      1, 0b000, 0b1000, 0b0001, 0b011, REG_REQUIRED>;
-defm : TLBI<"VALE1OS",      1, 0b000, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
-defm : TLBI<"VAALE1OS",     1, 0b000, 0b1000, 0b0001, 0b111, REG_REQUIRED>;
-defm : TLBI<"IPAS2E1OS",    1, 0b100, 0b1000, 0b0100, 0b000, REG_REQUIRED>;
-defm : TLBI<"IPAS2LE1OS",   1, 0b100, 0b1000, 0b0100, 0b100, REG_REQUIRED>;
-defm : TLBI<"VAE2OS",       1, 0b100, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
-defm : TLBI<"VALE2OS",      1, 0b100, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
-defm : TLBI<"VMALLS12E1OS", 0, 0b100, 0b1000, 0b0001, 0b110, REG_OPTIONAL>;
-defm : TLBI<"VAE3OS",       1, 0b110, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
-defm : TLBI<"VALE3OS",      1, 0b110, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
-defm : TLBI<"ALLE2OS",      0, 0b100, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
-defm : TLBI<"ALLE1OS",      0, 0b100, 0b1000, 0b0001, 0b100, REG_OPTIONAL>;
-defm : TLBI<"ALLE3OS",      0, 0b110, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
-
-// Armv8.4-A TLB Range Maintenance instructions:
-//                   hasTLBIP  op1    CRn     CRm     op2
-defm : TLBI<"RVAE1",        1, 0b000, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
-defm : TLBI<"RVAAE1",       1, 0b000, 0b1000, 0b0110, 0b011, REG_REQUIRED>;
-defm : TLBI<"RVALE1",       1, 0b000, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
-defm : TLBI<"RVAALE1",      1, 0b000, 0b1000, 0b0110, 0b111, REG_REQUIRED>;
-defm : TLBI<"RVAE1IS",      1, 0b000, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
-defm : TLBI<"RVAAE1IS",     1, 0b000, 0b1000, 0b0010, 0b011, REG_REQUIRED>;
-defm : TLBI<"RVALE1IS",     1, 0b000, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
-defm : TLBI<"RVAALE1IS",    1, 0b000, 0b1000, 0b0010, 0b111, REG_REQUIRED>;
-defm : TLBI<"RVAE1OS",      1, 0b000, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
-defm : TLBI<"RVAAE1OS",     1, 0b000, 0b1000, 0b0101, 0b011, REG_REQUIRED>;
-defm : TLBI<"RVALE1OS",     1, 0b000, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
-defm : TLBI<"RVAALE1OS",    1, 0b000, 0b1000, 0b0101, 0b111, REG_REQUIRED>;
-defm : TLBI<"RIPAS2E1IS",   1, 0b100, 0b1000, 0b0000, 0b010, REG_REQUIRED>;
-defm : TLBI<"RIPAS2LE1IS",  1, 0b100, 0b1000, 0b0000, 0b110, REG_REQUIRED>;
-defm : TLBI<"RIPAS2E1",     1, 0b100, 0b1000, 0b0100, 0b010, REG_REQUIRED>;
-defm : TLBI<"RIPAS2LE1",    1, 0b100, 0b1000, 0b0100, 0b110, REG_REQUIRED>;
-defm : TLBI<"RIPAS2E1OS",   1, 0b100, 0b1000, 0b0100, 0b011, REG_REQUIRED>;
-defm : TLBI<"RIPAS2LE1OS",  1, 0b100, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
-defm : TLBI<"RVAE2",        1, 0b100, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
-defm : TLBI<"RVALE2",       1, 0b100, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
-defm : TLBI<"RVAE2IS",      1, 0b100, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
-defm : TLBI<"RVALE2IS",     1, 0b100, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
-defm : TLBI<"RVAE2OS",      1, 0b100, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
-defm : TLBI<"RVALE2OS",     1, 0b100, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
-defm : TLBI<"RVAE3",        1, 0b110, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
-defm : TLBI<"RVALE3",       1, 0b110, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
-defm : TLBI<"RVAE3IS",      1, 0b110, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
-defm : TLBI<"RVALE3IS",     1, 0b110, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
-defm : TLBI<"RVAE3OS",      1, 0b110, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
-defm : TLBI<"RVALE3OS",     1, 0b110, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
-} //FeatureTLB_RMI
+//                       hasTLBIP  op1    CRn     CRm     op2    reguse
+defm : TLBI_RMI<"VMALLE1OS",    0, 0b000, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
+defm : TLBI_RMI<"VAE1OS",       1, 0b000, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
+defm : TLBI_RMI<"ASIDE1OS",     0, 0b000, 0b1000, 0b0001, 0b010, REG_REQUIRED>;
+defm : TLBI_RMI<"VAAE1OS",      1, 0b000, 0b1000, 0b0001, 0b011, REG_REQUIRED>;
+defm : TLBI_RMI<"VALE1OS",      1, 0b000, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
+defm : TLBI_RMI<"VAALE1OS",     1, 0b000, 0b1000, 0b0001, 0b111, REG_REQUIRED>;
+defm : TLBI_RMI<"IPAS2E1OS",    1, 0b100, 0b1000, 0b0100, 0b000, REG_REQUIRED>;
+defm : TLBI_RMI<"IPAS2LE1OS",   1, 0b100, 0b1000, 0b0100, 0b100, REG_REQUIRED>;
+defm : TLBI_RMI<"VAE2OS",       1, 0b100, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
+defm : TLBI_RMI<"VALE2OS",      1, 0b100, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
+defm : TLBI_RMI<"VMALLS12E1OS", 0, 0b100, 0b1000, 0b0001, 0b110, REG_OPTIONAL>;
+defm : TLBI_RMI<"VAE3OS",       1, 0b110, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
+defm : TLBI_RMI<"VALE3OS",      1, 0b110, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
+defm : TLBI_RMI<"ALLE2OS",      0, 0b100, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
+defm : TLBI_RMI<"ALLE1OS",      0, 0b100, 0b1000, 0b0001, 0b100, REG_OPTIONAL>;
+defm : TLBI_RMI<"ALLE3OS",      0, 0b110, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
+
+// Armv8.4-A TLB and TLBIP Range Maintenance instructions:
+//                       hasTLBIP  op1    CRn     CRm     op2    reguse
+defm : TLBI_RMI<"RVAE1",        1, 0b000, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
+defm : TLBI_RMI<"RVAAE1",       1, 0b000, 0b1000, 0b0110, 0b011, REG_REQUIRED>;
+defm : TLBI_RMI<"RVALE1",       1, 0b000, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
+defm : TLBI_RMI<"RVAALE1",      1, 0b000, 0b1000, 0b0110, 0b111, REG_REQUIRED>;
+defm : TLBI_RMI<"RVAE1IS",      1, 0b000, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
+defm : TLBI_RMI<"RVAAE1IS",     1, 0b000, 0b1000, 0b0010, 0b011, REG_REQUIRED>;
+defm : TLBI_RMI<"RVALE1IS",     1, 0b000, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
+defm : TLBI_RMI<"RVAALE1IS",    1, 0b000, 0b1000, 0b0010, 0b111, REG_REQUIRED>;
+defm : TLBI_RMI<"RVAE1OS",      1, 0b000, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
+defm : TLBI_RMI<"RVAAE1OS",     1, 0b000, 0b1000, 0b0101, 0b011, REG_REQUIRED>;
+defm : TLBI_RMI<"RVALE1OS",     1, 0b000, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
+defm : TLBI_RMI<"RVAALE1OS",    1, 0b000, 0b1000, 0b0101, 0b111, REG_REQUIRED>;
+defm : TLBI_RMI<"RIPAS2E1IS",   1, 0b100, 0b1000, 0b0000, 0b010, REG_REQUIRED>;
+defm : TLBI_RMI<"RIPAS2LE1IS",  1, 0b100, 0b1000, 0b0000, 0b110, REG_REQUIRED>;
+defm : TLBI_RMI<"RIPAS2E1",     1, 0b100, 0b1000, 0b0100, 0b010, REG_REQUIRED>;
+defm : TLBI_RMI<"RIPAS2LE1",    1, 0b100, 0b1000, 0b0100, 0b110, REG_REQUIRED>;
+defm : TLBI_RMI<"RIPAS2E1OS",   1, 0b100, 0b1000, 0b0100, 0b011, REG_REQUIRED>;
+defm : TLBI_RMI<"RIPAS2LE1OS",  1, 0b100, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
+defm : TLBI_RMI<"RVAE2",        1, 0b100, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
+defm : TLBI_RMI<"RVALE2",       1, 0b100, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
+defm : TLBI_RMI<"RVAE2IS",      1, 0b100, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
+defm : TLBI_RMI<"RVALE2IS",     1, 0b100, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
+defm : TLBI_RMI<"RVAE2OS",      1, 0b100, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
+defm : TLBI_RMI<"RVALE2OS",     1, 0b100, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
+defm : TLBI_RMI<"RVAE3",        1, 0b110, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
+defm : TLBI_RMI<"RVALE3",       1, 0b110, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
+defm : TLBI_RMI<"RVAE3IS",      1, 0b110, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
+defm : TLBI_RMI<"RVALE3IS",     1, 0b110, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
+defm : TLBI_RMI<"RVAE3OS",      1, 0b110, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
+defm : TLBI_RMI<"RVALE3OS",     1, 0b110, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
 
 // Armv9-A Realm Management Extension TLBI Instructions
 let Requires = ["AArch64::FeatureRME"] in {
-//                   hasTLBIP  op1    CRn     CRm     op2    reguse
-defm : TLBI<"RPAOS",        0, 0b110, 0b1000, 0b0100, 0b011, REG_REQUIRED>;
-defm : TLBI<"RPALOS",       0, 0b110, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
-defm : TLBI<"PAALLOS",      0, 0b110, 0b1000, 0b0001, 0b100, REG_NONE>;
-defm : TLBI<"PAALL",        0, 0b110, 0b1000, 0b0111, 0b100, REG_NONE>;
+//                                 op1    CRn     CRm     op2    reguse
+defm : TLBI_Base<"RPAOS",          0b110, 0b1000, 0b0100, 0b011, REG_REQUIRED>;
+defm : TLBI_Base<"RPALOS",         0b110, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
+defm : TLBI_Base<"PAALLOS",        0b110, 0b1000, 0b0001, 0b100, REG_NONE>;
+defm : TLBI_Base<"PAALL",          0b110, 0b1000, 0b0111, 0b100, REG_NONE>;
 }
 
 // Armv9.5-A TLBI VMALL for Dirty State
 let Requires = ["AArch64::FeatureTLBIW"] in {
-//                   hasTLBIP  op1    CRn     CRm     op2    reguse
-defm : TLBI<"VMALLWS2E1",   0, 0b100, 0b1000, 0b0110, 0b010, REG_NONE>;
-defm : TLBI<"VMALLWS2E1IS", 0, 0b100, 0b1000, 0b0010, 0b010, REG_OPTIONAL>;
-defm : TLBI<"VMALLWS2E1OS", 0, 0b100, 0b1000, 0b0101, 0b010, REG_OPTIONAL>;
+//                                 op1    CRn     CRm     op2    reguse
+defm : TLBI_Base<"VMALLWS2E1",     0b100, 0b1000, 0b0110, 0b010, REG_NONE>;
+defm : TLBI_Base<"VMALLWS2E1IS",   0b100, 0b1000, 0b0010, 0b010, REG_OPTIONAL>;
+defm : TLBI_Base<"VMALLWS2E1OS",   0b100, 0b1000, 0b0101, 0b010, REG_OPTIONAL>;
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/MC/AArch64/armv9a-tlbip.s b/llvm/test/MC/AArch64/armv9a-tlbip.s
index 7985b3d0c2e2e..263059cb7a007 100644
--- a/llvm/test/MC/AArch64/armv9a-tlbip.s
+++ b/llvm/test/MC/AArch64/armv9a-tlbip.s
@@ -1,19 +1,18 @@
-// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+d128,+tlb-rmi < %s \
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+d128 < %s \
 // RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
-// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+tlb-rmi < %s 2>&1 \
+// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
 // RUN:        | FileCheck %s --check-prefixes=CHECK-ERROR
-// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+d128,+tlb-rmi < %s \
-// RUN:        | llvm-objdump -d --mattr=+d128,+tlb-rmi --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST
-// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+d128,+tlb-rmi < %s \
-// RUN:        | llvm-objdump -d --mattr=-d128,-tlb-rmi --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+d128 < %s \
+// RUN:        | llvm-objdump -d --mattr=+d128 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+d128 < %s \
+// RUN:        | llvm-objdump -d --mattr=-d128 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN
 // Disassemble encoding and check the re-encoding (-show-encoding) matches.
-// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+d128,+tlb-rmi < %s \
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+d128 < %s \
 // RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
-// RUN:        | llvm-mc -triple=aarch64 -mattr=+d128,+tlb-rmi -disassemble -show-encoding \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+d128 -disassemble -show-encoding \
 // RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
 
 // +d128 required for tlbip
-// +tbl-rmi required for RIPA*/RVA*
 
 tlbip IPAS2E1, x4, x5
 // CHECK-INST: tlbip ipas2e1, x4, x5

>From c2aab46b5b004676578f73f74d2e119a19976592 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Thu, 19 Mar 2026 15:24:14 +0000
Subject: [PATCH 2/7] fixup! Change tablegen as suggested

---
 .../Target/AArch64/AArch64SystemOperands.td   | 73 +++++++++----------
 1 file changed, 35 insertions(+), 38 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index d914b253c5358..4c70c09fec1a2 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -903,50 +903,47 @@ multiclass TLBITableBase {
 defm TLBI  : TLBITableBase;
 defm TLBIP : TLBITableBase;
 
-multiclass TLBI_Base<string name, bits<3> op1, bits<4> crn, bits<4> crm,
-                     bits<3> op2, int reguse = REG_REQUIRED,
-                     list<string> extra_requires = []> {
+multiclass TLBI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn,
+                bits<4> crm, bits<3> op2, int reguse = REG_REQUIRED> {
   foreach nxs = [0, 1] in {
     defvar VariantName = !if(nxs, !strconcat(name, "nXS"), name);
-    defvar VariantRequires = !if(nxs,
-                                 extra_requires # ["AArch64::FeatureXS"],
-                                 extra_requires);
     def : TLBIEntry<VariantName, op1, crn, crm, op2, reguse> {
       let Encoding{7} = nxs;
-      let ExtraRequires = VariantRequires;
+      let ExtraRequires = !if(nxs, ["AArch64::FeatureXS"], []);
     }
   }
-}
 
-multiclass TLBIP_Base<string name, bits<3> op1, bits<4> crn, bits<4> crm,
-                      bits<3> op2, int reguse = REG_REQUIRED,
-                      list<string> extra_requires = ["AArch64::FeatureD128"]> {
-  foreach nxs = [0, 1] in {
-    // TLBIP instructions aren't gated by FeatureXS like TLBI ones
-    defvar VariantName = !if(nxs, !strconcat(name, "nXS"), name);
-    def : TLBIPEntry<VariantName, op1, crn, crm, op2, reguse> {
-      let Encoding{7} = nxs;
-      let ExtraRequires = extra_requires;
-    }
-  }
-}
-
-multiclass TLBI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn,
-                bits<4> crm, bits<3> op2, int reguse = REG_REQUIRED> {
-  defm : TLBI_Base<name, op1, crn, crm, op2, reguse>;
   if !eq(hasTLBIP, true) then {
-    defm : TLBIP_Base<name, op1, crn, crm, op2, reguse>;
+    foreach nxs = [0, 1] in {
+      defvar VariantName = !if(nxs, !strconcat(name, "nXS"), name);
+      def : TLBIPEntry<VariantName, op1, crn, crm, op2, reguse> {
+        let Encoding{7} = nxs;
+        let Requires = ["AArch64::FeatureD128"];
+      }
+    }
   }
 }
 
 multiclass TLBI_RMI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn,
                     bits<4> crm, bits<3> op2, int reguse = REG_REQUIRED> {
-  let Requires = ["AArch64::FeatureTLB_RMI"] in {
-    defm : TLBI_Base<name, op1, crn, crm, op2, reguse>;
+  foreach nxs = [0, 1] in {
+    defvar VariantName = !if(nxs, !strconcat(name, "nXS"), name);
+    def : TLBIEntry<VariantName, op1, crn, crm, op2, reguse> {
+      let Encoding{7} = nxs;
+      let Requires = !if(nxs,
+                         ["AArch64::FeatureTLB_RMI", "AArch64::FeatureXS"],
+                         ["AArch64::FeatureTLB_RMI"]);
+    }
   }
-  // TLBIP instructions aren't gated by FeatureTLB_RMI
+
   if !eq(hasTLBIP, true) then {
-    defm : TLBIP_Base<name, op1, crn, crm, op2, reguse>;
+    foreach nxs = [0, 1] in {
+      defvar VariantName = !if(nxs, !strconcat(name, "nXS"), name);
+      def : TLBIPEntry<VariantName, op1, crn, crm, op2, reguse> {
+        let Encoding{7} = nxs;
+        let Requires = ["AArch64::FeatureD128"];
+      }
+    }
   }
 }
 
@@ -1040,19 +1037,19 @@ defm : TLBI_RMI<"RVALE3OS",     1, 0b110, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
 
 // Armv9-A Realm Management Extension TLBI Instructions
 let Requires = ["AArch64::FeatureRME"] in {
-//                                 op1    CRn     CRm     op2    reguse
-defm : TLBI_Base<"RPAOS",          0b110, 0b1000, 0b0100, 0b011, REG_REQUIRED>;
-defm : TLBI_Base<"RPALOS",         0b110, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
-defm : TLBI_Base<"PAALLOS",        0b110, 0b1000, 0b0001, 0b100, REG_NONE>;
-defm : TLBI_Base<"PAALL",          0b110, 0b1000, 0b0111, 0b100, REG_NONE>;
+//                   hasTLBIP  op1    CRn     CRm     op2    reguse
+defm : TLBI<"RPAOS",        0, 0b110, 0b1000, 0b0100, 0b011, REG_REQUIRED>;
+defm : TLBI<"RPALOS",       0, 0b110, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
+defm : TLBI<"PAALLOS",      0, 0b110, 0b1000, 0b0001, 0b100, REG_NONE>;
+defm : TLBI<"PAALL",        0, 0b110, 0b1000, 0b0111, 0b100, REG_NONE>;
 }
 
 // Armv9.5-A TLBI VMALL for Dirty State
 let Requires = ["AArch64::FeatureTLBIW"] in {
-//                                 op1    CRn     CRm     op2    reguse
-defm : TLBI_Base<"VMALLWS2E1",     0b100, 0b1000, 0b0110, 0b010, REG_NONE>;
-defm : TLBI_Base<"VMALLWS2E1IS",   0b100, 0b1000, 0b0010, 0b010, REG_OPTIONAL>;
-defm : TLBI_Base<"VMALLWS2E1OS",   0b100, 0b1000, 0b0101, 0b010, REG_OPTIONAL>;
+//                   hasTLBIP  op1    CRn     CRm     op2    reguse
+defm : TLBI<"VMALLWS2E1",   0, 0b100, 0b1000, 0b0110, 0b010, REG_NONE>;
+defm : TLBI<"VMALLWS2E1IS", 0, 0b100, 0b1000, 0b0010, 0b010, REG_OPTIONAL>;
+defm : TLBI<"VMALLWS2E1OS", 0, 0b100, 0b1000, 0b0101, 0b010, REG_OPTIONAL>;
 }
 
 //===----------------------------------------------------------------------===//

>From b86651e61a0fe39fb4f16f4e521503f4f1d6ba39 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Fri, 20 Mar 2026 15:24:54 +0000
Subject: [PATCH 3/7] fixup! Refactor TLBI tablegen

---
 .../Target/AArch64/AArch64SystemOperands.td   | 333 +++++++++++-------
 1 file changed, 215 insertions(+), 118 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index 4c70c09fec1a2..2f53d2fd7af3c 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -903,20 +903,77 @@ multiclass TLBITableBase {
 defm TLBI  : TLBITableBase;
 defm TLBIP : TLBITableBase;
 
-multiclass TLBI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn,
-                bits<4> crm, bits<3> op2, int reguse = REG_REQUIRED> {
-  foreach nxs = [0, 1] in {
-    defvar VariantName = !if(nxs, !strconcat(name, "nXS"), name);
-    def : TLBIEntry<VariantName, op1, crn, crm, op2, reguse> {
-      let Encoding{7} = nxs;
-      let ExtraRequires = !if(nxs, ["AArch64::FeatureXS"], []);
-    }
+class TLBI<bit hasTLBIP, bits<3> op1, bits<4> crn,
+               bits<4> crm, bits<3> op2, int reguse = REG_REQUIRED> {
+  string Name = NAME;
+  bit HasTLBIP = hasTLBIP;
+  bits<3> Op1 = op1;
+  bits<4> CRn = crn;
+  bits<4> CRm = crm;
+  bits<3> Op2 = op2;
+  int RegUse = reguse;
+}
+
+// TLBI and TLBIP instructions encodings
+//               hasTLBIP  op1    CRn     CRm     op2    reguse
+def IPAS2E1IS    : TLBI<1, 0b100, 0b1000, 0b0000, 0b001, REG_REQUIRED>;
+def IPAS2LE1IS   : TLBI<1, 0b100, 0b1000, 0b0000, 0b101, REG_REQUIRED>;
+def VMALLE1IS    : TLBI<0, 0b000, 0b1000, 0b0011, 0b000, REG_OPTIONAL>;
+def ALLE2IS      : TLBI<0, 0b100, 0b1000, 0b0011, 0b000, REG_OPTIONAL>;
+def ALLE3IS      : TLBI<0, 0b110, 0b1000, 0b0011, 0b000, REG_OPTIONAL>;
+def VAE1IS       : TLBI<1, 0b000, 0b1000, 0b0011, 0b001, REG_REQUIRED>;
+def VAE2IS       : TLBI<1, 0b100, 0b1000, 0b0011, 0b001, REG_REQUIRED>;
+def VAE3IS       : TLBI<1, 0b110, 0b1000, 0b0011, 0b001, REG_REQUIRED>;
+def ASIDE1IS     : TLBI<0, 0b000, 0b1000, 0b0011, 0b010, REG_REQUIRED>;
+def VAAE1IS      : TLBI<1, 0b000, 0b1000, 0b0011, 0b011, REG_REQUIRED>;
+def ALLE1IS      : TLBI<0, 0b100, 0b1000, 0b0011, 0b100, REG_OPTIONAL>;
+def VALE1IS      : TLBI<1, 0b000, 0b1000, 0b0011, 0b101, REG_REQUIRED>;
+def VALE2IS      : TLBI<1, 0b100, 0b1000, 0b0011, 0b101, REG_REQUIRED>;
+def VALE3IS      : TLBI<1, 0b110, 0b1000, 0b0011, 0b101, REG_REQUIRED>;
+def VMALLS12E1IS : TLBI<0, 0b100, 0b1000, 0b0011, 0b110, REG_OPTIONAL>;
+def VAALE1IS     : TLBI<1, 0b000, 0b1000, 0b0011, 0b111, REG_REQUIRED>;
+def IPAS2E1      : TLBI<1, 0b100, 0b1000, 0b0100, 0b001, REG_REQUIRED>;
+def IPAS2LE1     : TLBI<1, 0b100, 0b1000, 0b0100, 0b101, REG_REQUIRED>;
+def VMALLE1      : TLBI<0, 0b000, 0b1000, 0b0111, 0b000, REG_NONE>;
+def ALLE2        : TLBI<0, 0b100, 0b1000, 0b0111, 0b000, REG_NONE>;
+def ALLE3        : TLBI<0, 0b110, 0b1000, 0b0111, 0b000, REG_NONE>;
+def VAE1         : TLBI<1, 0b000, 0b1000, 0b0111, 0b001, REG_REQUIRED>;
+def VAE2         : TLBI<1, 0b100, 0b1000, 0b0111, 0b001, REG_REQUIRED>;
+def VAE3         : TLBI<1, 0b110, 0b1000, 0b0111, 0b001, REG_REQUIRED>;
+def ASIDE1       : TLBI<0, 0b000, 0b1000, 0b0111, 0b010, REG_REQUIRED>;
+def VAAE1        : TLBI<1, 0b000, 0b1000, 0b0111, 0b011, REG_REQUIRED>;
+def ALLE1        : TLBI<0, 0b100, 0b1000, 0b0111, 0b100, REG_NONE>;
+def VALE1        : TLBI<1, 0b000, 0b1000, 0b0111, 0b101, REG_REQUIRED>;
+def VALE2        : TLBI<1, 0b100, 0b1000, 0b0111, 0b101, REG_REQUIRED>;
+def VALE3        : TLBI<1, 0b110, 0b1000, 0b0111, 0b101, REG_REQUIRED>;
+def VMALLS12E1   : TLBI<0, 0b100, 0b1000, 0b0111, 0b110, REG_NONE>;
+def VAALE1       : TLBI<1, 0b000, 0b1000, 0b0111, 0b111, REG_REQUIRED>;
+
+defvar TLBINames = [
+  "IPAS2E1IS", "IPAS2LE1IS", "VMALLE1IS", "ALLE2IS", "ALLE3IS",
+  "VAE1IS", "VAE2IS", "VAE3IS", "ASIDE1IS", "VAAE1IS",
+  "ALLE1IS", "VALE1IS", "VALE2IS", "VALE3IS", "VMALLS12E1IS",
+  "VAALE1IS", "IPAS2E1", "IPAS2LE1", "VMALLE1", "ALLE2",
+  "ALLE3", "VAE1", "VAE2", "VAE3", "ASIDE1", "VAAE1",
+  "ALLE1", "VALE1", "VALE2", "VALE3", "VMALLS12E1", "VAALE1"
+];
+
+foreach I = TLBINames in {
+  defvar Info = !cast<TLBI>(I);
+  def : TLBIEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+    let Encoding{7} = 0;
+  }
+
+  def : TLBIEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+    let Encoding{7} = 1;
+    let ExtraRequires = ["AArch64::FeatureXS"];
   }
 
-  if !eq(hasTLBIP, true) then {
+  if !eq(Info.HasTLBIP, true) then {
     foreach nxs = [0, 1] in {
-      defvar VariantName = !if(nxs, !strconcat(name, "nXS"), name);
-      def : TLBIPEntry<VariantName, op1, crn, crm, op2, reguse> {
+      defvar VariantName = !if(nxs, !strconcat(I, "nXS"), I);
+      def : TLBIPEntry<VariantName, Info.Op1, Info.CRn, Info.CRm, Info.Op2,
+                       Info.RegUse> {
         let Encoding{7} = nxs;
         let Requires = ["AArch64::FeatureD128"];
       }
@@ -924,22 +981,50 @@ multiclass TLBI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn,
   }
 }
 
-multiclass TLBI_RMI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn,
-                    bits<4> crm, bits<3> op2, int reguse = REG_REQUIRED> {
-  foreach nxs = [0, 1] in {
-    defvar VariantName = !if(nxs, !strconcat(name, "nXS"), name);
-    def : TLBIEntry<VariantName, op1, crn, crm, op2, reguse> {
-      let Encoding{7} = nxs;
-      let Requires = !if(nxs,
-                         ["AArch64::FeatureTLB_RMI", "AArch64::FeatureXS"],
-                         ["AArch64::FeatureTLB_RMI"]);
-    }
+// Armv8.4-A Translation Lookaside Buffer Instructions (TLBI and TLBIP)
+// Armv8.4-A Outer Sharable TLB Maintenance instructions:
+//               hasTLBIP  op1    CRn     CRm     op2    reguse
+def VMALLE1OS    : TLBI<0, 0b000, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
+def VAE1OS       : TLBI<1, 0b000, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
+def ASIDE1OS     : TLBI<0, 0b000, 0b1000, 0b0001, 0b010, REG_REQUIRED>;
+def VAAE1OS      : TLBI<1, 0b000, 0b1000, 0b0001, 0b011, REG_REQUIRED>;
+def VALE1OS      : TLBI<1, 0b000, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
+def VAALE1OS     : TLBI<1, 0b000, 0b1000, 0b0001, 0b111, REG_REQUIRED>;
+def IPAS2E1OS    : TLBI<1, 0b100, 0b1000, 0b0100, 0b000, REG_REQUIRED>;
+def IPAS2LE1OS   : TLBI<1, 0b100, 0b1000, 0b0100, 0b100, REG_REQUIRED>;
+def VAE2OS       : TLBI<1, 0b100, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
+def VALE2OS      : TLBI<1, 0b100, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
+def VMALLS12E1OS : TLBI<0, 0b100, 0b1000, 0b0001, 0b110, REG_OPTIONAL>;
+def VAE3OS       : TLBI<1, 0b110, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
+def VALE3OS      : TLBI<1, 0b110, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
+def ALLE2OS      : TLBI<0, 0b100, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
+def ALLE1OS      : TLBI<0, 0b100, 0b1000, 0b0001, 0b100, REG_OPTIONAL>;
+def ALLE3OS      : TLBI<0, 0b110, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
+
+defvar TLBI_RMI_OuterShareable = [
+  "VMALLE1OS", "VAE1OS", "ASIDE1OS", "VAAE1OS",
+  "VALE1OS", "VAALE1OS", "IPAS2E1OS", "IPAS2LE1OS",
+  "VAE2OS", "VALE2OS", "VMALLS12E1OS", "VAE3OS",
+  "VALE3OS", "ALLE2OS", "ALLE1OS", "ALLE3OS"
+];
+
+foreach I = TLBI_RMI_OuterShareable in {
+  defvar Info = !cast<TLBI>(I);
+  def : TLBIEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+    let Encoding{7} = 0;
+    let Requires = ["AArch64::FeatureTLB_RMI"];
   }
 
-  if !eq(hasTLBIP, true) then {
+  def : TLBIEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+    let Encoding{7} = 1;
+    let Requires = ["AArch64::FeatureTLB_RMI", "AArch64::FeatureXS"];
+  }
+
+  if !eq(Info.HasTLBIP, true) then {
     foreach nxs = [0, 1] in {
-      defvar VariantName = !if(nxs, !strconcat(name, "nXS"), name);
-      def : TLBIPEntry<VariantName, op1, crn, crm, op2, reguse> {
+      defvar VariantName = !if(nxs, !strconcat(I, "nXS"), I);
+      def : TLBIPEntry<VariantName, Info.Op1, Info.CRn, Info.CRm, Info.Op2,
+                       Info.RegUse> {
         let Encoding{7} = nxs;
         let Requires = ["AArch64::FeatureD128"];
       }
@@ -947,109 +1032,121 @@ multiclass TLBI_RMI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn,
   }
 }
 
-// TLBI and TLBIP instructions encodings
-//                   hasTLBIP  op1    CRn     CRm     op2    reguse
-defm : TLBI<"IPAS2E1IS",    1, 0b100, 0b1000, 0b0000, 0b001, REG_REQUIRED>;
-defm : TLBI<"IPAS2LE1IS",   1, 0b100, 0b1000, 0b0000, 0b101, REG_REQUIRED>;
-defm : TLBI<"VMALLE1IS",    0, 0b000, 0b1000, 0b0011, 0b000, REG_OPTIONAL>;
-defm : TLBI<"ALLE2IS",      0, 0b100, 0b1000, 0b0011, 0b000, REG_OPTIONAL>;
-defm : TLBI<"ALLE3IS",      0, 0b110, 0b1000, 0b0011, 0b000, REG_OPTIONAL>;
-defm : TLBI<"VAE1IS",       1, 0b000, 0b1000, 0b0011, 0b001, REG_REQUIRED>;
-defm : TLBI<"VAE2IS",       1, 0b100, 0b1000, 0b0011, 0b001, REG_REQUIRED>;
-defm : TLBI<"VAE3IS",       1, 0b110, 0b1000, 0b0011, 0b001, REG_REQUIRED>;
-defm : TLBI<"ASIDE1IS",     0, 0b000, 0b1000, 0b0011, 0b010, REG_REQUIRED>;
-defm : TLBI<"VAAE1IS",      1, 0b000, 0b1000, 0b0011, 0b011, REG_REQUIRED>;
-defm : TLBI<"ALLE1IS",      0, 0b100, 0b1000, 0b0011, 0b100, REG_OPTIONAL>;
-defm : TLBI<"VALE1IS",      1, 0b000, 0b1000, 0b0011, 0b101, REG_REQUIRED>;
-defm : TLBI<"VALE2IS",      1, 0b100, 0b1000, 0b0011, 0b101, REG_REQUIRED>;
-defm : TLBI<"VALE3IS",      1, 0b110, 0b1000, 0b0011, 0b101, REG_REQUIRED>;
-defm : TLBI<"VMALLS12E1IS", 0, 0b100, 0b1000, 0b0011, 0b110, REG_OPTIONAL>;
-defm : TLBI<"VAALE1IS",     1, 0b000, 0b1000, 0b0011, 0b111, REG_REQUIRED>;
-defm : TLBI<"IPAS2E1",      1, 0b100, 0b1000, 0b0100, 0b001, REG_REQUIRED>;
-defm : TLBI<"IPAS2LE1",     1, 0b100, 0b1000, 0b0100, 0b101, REG_REQUIRED>;
-defm : TLBI<"VMALLE1",      0, 0b000, 0b1000, 0b0111, 0b000, REG_NONE>;
-defm : TLBI<"ALLE2",        0, 0b100, 0b1000, 0b0111, 0b000, REG_NONE>;
-defm : TLBI<"ALLE3",        0, 0b110, 0b1000, 0b0111, 0b000, REG_NONE>;
-defm : TLBI<"VAE1",         1, 0b000, 0b1000, 0b0111, 0b001, REG_REQUIRED>;
-defm : TLBI<"VAE2",         1, 0b100, 0b1000, 0b0111, 0b001, REG_REQUIRED>;
-defm : TLBI<"VAE3",         1, 0b110, 0b1000, 0b0111, 0b001, REG_REQUIRED>;
-defm : TLBI<"ASIDE1",       0, 0b000, 0b1000, 0b0111, 0b010, REG_REQUIRED>;
-defm : TLBI<"VAAE1",        1, 0b000, 0b1000, 0b0111, 0b011, REG_REQUIRED>;
-defm : TLBI<"ALLE1",        0, 0b100, 0b1000, 0b0111, 0b100, REG_NONE>;
-defm : TLBI<"VALE1",        1, 0b000, 0b1000, 0b0111, 0b101, REG_REQUIRED>;
-defm : TLBI<"VALE2",        1, 0b100, 0b1000, 0b0111, 0b101, REG_REQUIRED>;
-defm : TLBI<"VALE3",        1, 0b110, 0b1000, 0b0111, 0b101, REG_REQUIRED>;
-defm : TLBI<"VMALLS12E1",   0, 0b100, 0b1000, 0b0111, 0b110, REG_NONE>;
-defm : TLBI<"VAALE1",       1, 0b000, 0b1000, 0b0111, 0b111, REG_REQUIRED>;
+// Armv8.4-A TLB and TLBIP Range Maintenance instructions:
+//               hasTLBIP  op1    CRn     CRm     op2    reguse
+def RVAE1        : TLBI<1, 0b000, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
+def RVAAE1       : TLBI<1, 0b000, 0b1000, 0b0110, 0b011, REG_REQUIRED>;
+def RVALE1       : TLBI<1, 0b000, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
+def RVAALE1      : TLBI<1, 0b000, 0b1000, 0b0110, 0b111, REG_REQUIRED>;
+def RVAE1IS      : TLBI<1, 0b000, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
+def RVAAE1IS     : TLBI<1, 0b000, 0b1000, 0b0010, 0b011, REG_REQUIRED>;
+def RVALE1IS     : TLBI<1, 0b000, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
+def RVAALE1IS    : TLBI<1, 0b000, 0b1000, 0b0010, 0b111, REG_REQUIRED>;
+def RVAE1OS      : TLBI<1, 0b000, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
+def RVAAE1OS     : TLBI<1, 0b000, 0b1000, 0b0101, 0b011, REG_REQUIRED>;
+def RVALE1OS     : TLBI<1, 0b000, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
+def RVAALE1OS    : TLBI<1, 0b000, 0b1000, 0b0101, 0b111, REG_REQUIRED>;
+def RIPAS2E1IS   : TLBI<1, 0b100, 0b1000, 0b0000, 0b010, REG_REQUIRED>;
+def RIPAS2LE1IS  : TLBI<1, 0b100, 0b1000, 0b0000, 0b110, REG_REQUIRED>;
+def RIPAS2E1     : TLBI<1, 0b100, 0b1000, 0b0100, 0b010, REG_REQUIRED>;
+def RIPAS2LE1    : TLBI<1, 0b100, 0b1000, 0b0100, 0b110, REG_REQUIRED>;
+def RIPAS2E1OS   : TLBI<1, 0b100, 0b1000, 0b0100, 0b011, REG_REQUIRED>;
+def RIPAS2LE1OS  : TLBI<1, 0b100, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
+def RVAE2        : TLBI<1, 0b100, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
+def RVALE2       : TLBI<1, 0b100, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
+def RVAE2IS      : TLBI<1, 0b100, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
+def RVALE2IS     : TLBI<1, 0b100, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
+def RVAE2OS      : TLBI<1, 0b100, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
+def RVALE2OS     : TLBI<1, 0b100, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
+def RVAE3        : TLBI<1, 0b110, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
+def RVALE3       : TLBI<1, 0b110, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
+def RVAE3IS      : TLBI<1, 0b110, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
+def RVALE3IS     : TLBI<1, 0b110, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
+def RVAE3OS      : TLBI<1, 0b110, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
+def RVALE3OS     : TLBI<1, 0b110, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
+
+defvar TLBI_RMI_Range = [
+  "RVAE1", "RVAAE1", "RVALE1", "RVAALE1",
+  "RVAE1IS", "RVAAE1IS", "RVALE1IS", "RVAALE1IS",
+  "RVAE1OS", "RVAAE1OS", "RVALE1OS", "RVAALE1OS",
+  "RIPAS2E1IS", "RIPAS2LE1IS", "RIPAS2E1",
+  "RIPAS2LE1", "RIPAS2E1OS", "RIPAS2LE1OS",
+  "RVAE2", "RVALE2", "RVAE2IS", "RVALE2IS",
+  "RVAE2OS", "RVALE2OS", "RVAE3", "RVALE3",
+  "RVAE3IS", "RVALE3IS", "RVAE3OS", "RVALE3OS"
+];
+
+foreach I = TLBI_RMI_Range in {
+  defvar Info = !cast<TLBI>(I);
+  def : TLBIEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+    let Encoding{7} = 0;
+    let Requires = ["AArch64::FeatureTLB_RMI"];
+  }
 
-// Armv8.4-A Translation Lookaside Buffer Instructions (TLBI and TLBIP)
-// Armv8.4-A Outer Sharable TLB Maintenance instructions:
-//                       hasTLBIP  op1    CRn     CRm     op2    reguse
-defm : TLBI_RMI<"VMALLE1OS",    0, 0b000, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
-defm : TLBI_RMI<"VAE1OS",       1, 0b000, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
-defm : TLBI_RMI<"ASIDE1OS",     0, 0b000, 0b1000, 0b0001, 0b010, REG_REQUIRED>;
-defm : TLBI_RMI<"VAAE1OS",      1, 0b000, 0b1000, 0b0001, 0b011, REG_REQUIRED>;
-defm : TLBI_RMI<"VALE1OS",      1, 0b000, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
-defm : TLBI_RMI<"VAALE1OS",     1, 0b000, 0b1000, 0b0001, 0b111, REG_REQUIRED>;
-defm : TLBI_RMI<"IPAS2E1OS",    1, 0b100, 0b1000, 0b0100, 0b000, REG_REQUIRED>;
-defm : TLBI_RMI<"IPAS2LE1OS",   1, 0b100, 0b1000, 0b0100, 0b100, REG_REQUIRED>;
-defm : TLBI_RMI<"VAE2OS",       1, 0b100, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
-defm : TLBI_RMI<"VALE2OS",      1, 0b100, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
-defm : TLBI_RMI<"VMALLS12E1OS", 0, 0b100, 0b1000, 0b0001, 0b110, REG_OPTIONAL>;
-defm : TLBI_RMI<"VAE3OS",       1, 0b110, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
-defm : TLBI_RMI<"VALE3OS",      1, 0b110, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
-defm : TLBI_RMI<"ALLE2OS",      0, 0b100, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
-defm : TLBI_RMI<"ALLE1OS",      0, 0b100, 0b1000, 0b0001, 0b100, REG_OPTIONAL>;
-defm : TLBI_RMI<"ALLE3OS",      0, 0b110, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
+  def : TLBIEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+    let Encoding{7} = 1;
+    let Requires = ["AArch64::FeatureTLB_RMI", "AArch64::FeatureXS"];
+  }
 
-// Armv8.4-A TLB and TLBIP Range Maintenance instructions:
-//                       hasTLBIP  op1    CRn     CRm     op2    reguse
-defm : TLBI_RMI<"RVAE1",        1, 0b000, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
-defm : TLBI_RMI<"RVAAE1",       1, 0b000, 0b1000, 0b0110, 0b011, REG_REQUIRED>;
-defm : TLBI_RMI<"RVALE1",       1, 0b000, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
-defm : TLBI_RMI<"RVAALE1",      1, 0b000, 0b1000, 0b0110, 0b111, REG_REQUIRED>;
-defm : TLBI_RMI<"RVAE1IS",      1, 0b000, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
-defm : TLBI_RMI<"RVAAE1IS",     1, 0b000, 0b1000, 0b0010, 0b011, REG_REQUIRED>;
-defm : TLBI_RMI<"RVALE1IS",     1, 0b000, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
-defm : TLBI_RMI<"RVAALE1IS",    1, 0b000, 0b1000, 0b0010, 0b111, REG_REQUIRED>;
-defm : TLBI_RMI<"RVAE1OS",      1, 0b000, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
-defm : TLBI_RMI<"RVAAE1OS",     1, 0b000, 0b1000, 0b0101, 0b011, REG_REQUIRED>;
-defm : TLBI_RMI<"RVALE1OS",     1, 0b000, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
-defm : TLBI_RMI<"RVAALE1OS",    1, 0b000, 0b1000, 0b0101, 0b111, REG_REQUIRED>;
-defm : TLBI_RMI<"RIPAS2E1IS",   1, 0b100, 0b1000, 0b0000, 0b010, REG_REQUIRED>;
-defm : TLBI_RMI<"RIPAS2LE1IS",  1, 0b100, 0b1000, 0b0000, 0b110, REG_REQUIRED>;
-defm : TLBI_RMI<"RIPAS2E1",     1, 0b100, 0b1000, 0b0100, 0b010, REG_REQUIRED>;
-defm : TLBI_RMI<"RIPAS2LE1",    1, 0b100, 0b1000, 0b0100, 0b110, REG_REQUIRED>;
-defm : TLBI_RMI<"RIPAS2E1OS",   1, 0b100, 0b1000, 0b0100, 0b011, REG_REQUIRED>;
-defm : TLBI_RMI<"RIPAS2LE1OS",  1, 0b100, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
-defm : TLBI_RMI<"RVAE2",        1, 0b100, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
-defm : TLBI_RMI<"RVALE2",       1, 0b100, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
-defm : TLBI_RMI<"RVAE2IS",      1, 0b100, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
-defm : TLBI_RMI<"RVALE2IS",     1, 0b100, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
-defm : TLBI_RMI<"RVAE2OS",      1, 0b100, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
-defm : TLBI_RMI<"RVALE2OS",     1, 0b100, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
-defm : TLBI_RMI<"RVAE3",        1, 0b110, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
-defm : TLBI_RMI<"RVALE3",       1, 0b110, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
-defm : TLBI_RMI<"RVAE3IS",      1, 0b110, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
-defm : TLBI_RMI<"RVALE3IS",     1, 0b110, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
-defm : TLBI_RMI<"RVAE3OS",      1, 0b110, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
-defm : TLBI_RMI<"RVALE3OS",     1, 0b110, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
+  if !eq(Info.HasTLBIP, true) then {
+    foreach nxs = [0, 1] in {
+      defvar VariantName = !if(nxs, !strconcat(I, "nXS"), I);
+      def : TLBIPEntry<VariantName, Info.Op1, Info.CRn, Info.CRm, Info.Op2,
+                       Info.RegUse> {
+        let Encoding{7} = nxs;
+        let Requires = ["AArch64::FeatureD128"];
+      }
+    }
+  }
+}
 
 // Armv9-A Realm Management Extension TLBI Instructions
+//          hasTLBIP  op1    CRn     CRm     op2    reguse
+def RPAOS   : TLBI<0, 0b110, 0b1000, 0b0100, 0b011, REG_REQUIRED>;
+def RPALOS  : TLBI<0, 0b110, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
+def PAALLOS : TLBI<0, 0b110, 0b1000, 0b0001, 0b100, REG_NONE>;
+def PAALL   : TLBI<0, 0b110, 0b1000, 0b0111, 0b100, REG_NONE>;
+
+defvar TLBI_RME = [
+  "RPAOS", "RPALOS", "PAALLOS", "PAALL"
+];
+
 let Requires = ["AArch64::FeatureRME"] in {
-//                   hasTLBIP  op1    CRn     CRm     op2    reguse
-defm : TLBI<"RPAOS",        0, 0b110, 0b1000, 0b0100, 0b011, REG_REQUIRED>;
-defm : TLBI<"RPALOS",       0, 0b110, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
-defm : TLBI<"PAALLOS",      0, 0b110, 0b1000, 0b0001, 0b100, REG_NONE>;
-defm : TLBI<"PAALL",        0, 0b110, 0b1000, 0b0111, 0b100, REG_NONE>;
+foreach I = TLBI_RME in {
+  defvar Info = !cast<TLBI>(I);
+  def : TLBIEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+    let Encoding{7} = 0;
+  }
+
+  def : TLBIEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+    let Encoding{7} = 1;
+    let ExtraRequires = ["AArch64::FeatureXS"];
+  }
+}
 }
 
 // Armv9.5-A TLBI VMALL for Dirty State
+//               hasTLBIP  op1    CRn     CRm     op2    reguse
+def VMALLWS2E1   : TLBI<0, 0b100, 0b1000, 0b0110, 0b010, REG_NONE>;
+def VMALLWS2E1IS : TLBI<0, 0b100, 0b1000, 0b0010, 0b010, REG_OPTIONAL>;
+def VMALLWS2E1OS : TLBI<0, 0b100, 0b1000, 0b0101, 0b010, REG_OPTIONAL>;
+
+defvar TLBI_TLBIW = [
+  "VMALLWS2E1", "VMALLWS2E1IS", "VMALLWS2E1OS"
+];
+
 let Requires = ["AArch64::FeatureTLBIW"] in {
-//                   hasTLBIP  op1    CRn     CRm     op2    reguse
-defm : TLBI<"VMALLWS2E1",   0, 0b100, 0b1000, 0b0110, 0b010, REG_NONE>;
-defm : TLBI<"VMALLWS2E1IS", 0, 0b100, 0b1000, 0b0010, 0b010, REG_OPTIONAL>;
-defm : TLBI<"VMALLWS2E1OS", 0, 0b100, 0b1000, 0b0101, 0b010, REG_OPTIONAL>;
+foreach I = TLBI_TLBIW in {
+  defvar Info = !cast<TLBI>(I);
+  def : TLBIEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+    let Encoding{7} = 0;
+  }
+
+  def : TLBIEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+    let Encoding{7} = 1;
+    let ExtraRequires = ["AArch64::FeatureXS"];
+  }
+}
 }
 
 //===----------------------------------------------------------------------===//

>From 0512f08dc570640b790a3e73bf22c3dc5d6e1721 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Fri, 20 Mar 2026 16:38:16 +0000
Subject: [PATCH 4/7] fixup! More tablegen fixes

---
 .../Target/AArch64/AArch64SystemOperands.td   | 102 ++++++------------
 1 file changed, 32 insertions(+), 70 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index 2f53d2fd7af3c..3b686709022ba 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -904,7 +904,7 @@ defm TLBI  : TLBITableBase;
 defm TLBIP : TLBITableBase;
 
 class TLBI<bit hasTLBIP, bits<3> op1, bits<4> crn,
-               bits<4> crm, bits<3> op2, int reguse = REG_REQUIRED> {
+           bits<4> crm, bits<3> op2, int reguse = REG_REQUIRED> {
   string Name = NAME;
   bit HasTLBIP = hasTLBIP;
   bits<3> Op1 = op1;
@@ -949,16 +949,14 @@ def VALE3        : TLBI<1, 0b110, 0b1000, 0b0111, 0b101, REG_REQUIRED>;
 def VMALLS12E1   : TLBI<0, 0b100, 0b1000, 0b0111, 0b110, REG_NONE>;
 def VAALE1       : TLBI<1, 0b000, 0b1000, 0b0111, 0b111, REG_REQUIRED>;
 
-defvar TLBINames = [
+foreach I = [
   "IPAS2E1IS", "IPAS2LE1IS", "VMALLE1IS", "ALLE2IS", "ALLE3IS",
   "VAE1IS", "VAE2IS", "VAE3IS", "ASIDE1IS", "VAAE1IS",
   "ALLE1IS", "VALE1IS", "VALE2IS", "VALE3IS", "VMALLS12E1IS",
   "VAALE1IS", "IPAS2E1", "IPAS2LE1", "VMALLE1", "ALLE2",
   "ALLE3", "VAE1", "VAE2", "VAE3", "ASIDE1", "VAAE1",
   "ALLE1", "VALE1", "VALE2", "VALE3", "VMALLS12E1", "VAALE1"
-];
-
-foreach I = TLBINames in {
+  ] in {
   defvar Info = !cast<TLBI>(I);
   def : TLBIEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
     let Encoding{7} = 0;
@@ -970,13 +968,14 @@ foreach I = TLBINames in {
   }
 
   if !eq(Info.HasTLBIP, true) then {
-    foreach nxs = [0, 1] in {
-      defvar VariantName = !if(nxs, !strconcat(I, "nXS"), I);
-      def : TLBIPEntry<VariantName, Info.Op1, Info.CRn, Info.CRm, Info.Op2,
-                       Info.RegUse> {
-        let Encoding{7} = nxs;
-        let Requires = ["AArch64::FeatureD128"];
-      }
+    def : TLBIPEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+      let Encoding{7} = 0;
+      let Requires = ["AArch64::FeatureD128"];
+    }
+
+    def : TLBIPEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+      let Encoding{7} = 1;
+      let Requires = ["AArch64::FeatureD128"];
     }
   }
 }
@@ -1001,37 +1000,6 @@ def ALLE2OS      : TLBI<0, 0b100, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
 def ALLE1OS      : TLBI<0, 0b100, 0b1000, 0b0001, 0b100, REG_OPTIONAL>;
 def ALLE3OS      : TLBI<0, 0b110, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
 
-defvar TLBI_RMI_OuterShareable = [
-  "VMALLE1OS", "VAE1OS", "ASIDE1OS", "VAAE1OS",
-  "VALE1OS", "VAALE1OS", "IPAS2E1OS", "IPAS2LE1OS",
-  "VAE2OS", "VALE2OS", "VMALLS12E1OS", "VAE3OS",
-  "VALE3OS", "ALLE2OS", "ALLE1OS", "ALLE3OS"
-];
-
-foreach I = TLBI_RMI_OuterShareable in {
-  defvar Info = !cast<TLBI>(I);
-  def : TLBIEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
-    let Encoding{7} = 0;
-    let Requires = ["AArch64::FeatureTLB_RMI"];
-  }
-
-  def : TLBIEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
-    let Encoding{7} = 1;
-    let Requires = ["AArch64::FeatureTLB_RMI", "AArch64::FeatureXS"];
-  }
-
-  if !eq(Info.HasTLBIP, true) then {
-    foreach nxs = [0, 1] in {
-      defvar VariantName = !if(nxs, !strconcat(I, "nXS"), I);
-      def : TLBIPEntry<VariantName, Info.Op1, Info.CRn, Info.CRm, Info.Op2,
-                       Info.RegUse> {
-        let Encoding{7} = nxs;
-        let Requires = ["AArch64::FeatureD128"];
-      }
-    }
-  }
-}
-
 // Armv8.4-A TLB and TLBIP Range Maintenance instructions:
 //               hasTLBIP  op1    CRn     CRm     op2    reguse
 def RVAE1        : TLBI<1, 0b000, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
@@ -1065,7 +1033,11 @@ def RVALE3IS     : TLBI<1, 0b110, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
 def RVAE3OS      : TLBI<1, 0b110, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
 def RVALE3OS     : TLBI<1, 0b110, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
 
-defvar TLBI_RMI_Range = [
+foreach I = [
+  "VMALLE1OS", "VAE1OS", "ASIDE1OS", "VAAE1OS",
+  "VALE1OS", "VAALE1OS", "IPAS2E1OS", "IPAS2LE1OS",
+  "VAE2OS", "VALE2OS", "VMALLS12E1OS", "VAE3OS",
+  "VALE3OS", "ALLE2OS", "ALLE1OS", "ALLE3OS",
   "RVAE1", "RVAAE1", "RVALE1", "RVAALE1",
   "RVAE1IS", "RVAAE1IS", "RVALE1IS", "RVAALE1IS",
   "RVAE1OS", "RVAAE1OS", "RVALE1OS", "RVAALE1OS",
@@ -1074,9 +1046,7 @@ defvar TLBI_RMI_Range = [
   "RVAE2", "RVALE2", "RVAE2IS", "RVALE2IS",
   "RVAE2OS", "RVALE2OS", "RVAE3", "RVALE3",
   "RVAE3IS", "RVALE3IS", "RVAE3OS", "RVALE3OS"
-];
-
-foreach I = TLBI_RMI_Range in {
+  ] in {
   defvar Info = !cast<TLBI>(I);
   def : TLBIEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
     let Encoding{7} = 0;
@@ -1085,17 +1055,18 @@ foreach I = TLBI_RMI_Range in {
 
   def : TLBIEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
     let Encoding{7} = 1;
-    let Requires = ["AArch64::FeatureTLB_RMI", "AArch64::FeatureXS"];
+    let Requires = ["AArch64::FeatureXS"];
   }
 
   if !eq(Info.HasTLBIP, true) then {
-    foreach nxs = [0, 1] in {
-      defvar VariantName = !if(nxs, !strconcat(I, "nXS"), I);
-      def : TLBIPEntry<VariantName, Info.Op1, Info.CRn, Info.CRm, Info.Op2,
-                       Info.RegUse> {
-        let Encoding{7} = nxs;
-        let Requires = ["AArch64::FeatureD128"];
-      }
+    def : TLBIPEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+      let Encoding{7} = 0;
+      let Requires = ["AArch64::FeatureD128"];
+    }
+
+    def : TLBIPEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+      let Encoding{7} = 1;
+      let Requires = ["AArch64::FeatureD128"];
     }
   }
 }
@@ -1107,21 +1078,14 @@ def RPALOS  : TLBI<0, 0b110, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
 def PAALLOS : TLBI<0, 0b110, 0b1000, 0b0001, 0b100, REG_NONE>;
 def PAALL   : TLBI<0, 0b110, 0b1000, 0b0111, 0b100, REG_NONE>;
 
-defvar TLBI_RME = [
-  "RPAOS", "RPALOS", "PAALLOS", "PAALL"
-];
-
 let Requires = ["AArch64::FeatureRME"] in {
-foreach I = TLBI_RME in {
+foreach I = [
+  "RPAOS", "RPALOS", "PAALLOS", "PAALL"
+  ] in {
   defvar Info = !cast<TLBI>(I);
   def : TLBIEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
     let Encoding{7} = 0;
   }
-
-  def : TLBIEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
-    let Encoding{7} = 1;
-    let ExtraRequires = ["AArch64::FeatureXS"];
-  }
 }
 }
 
@@ -1131,12 +1095,10 @@ def VMALLWS2E1   : TLBI<0, 0b100, 0b1000, 0b0110, 0b010, REG_NONE>;
 def VMALLWS2E1IS : TLBI<0, 0b100, 0b1000, 0b0010, 0b010, REG_OPTIONAL>;
 def VMALLWS2E1OS : TLBI<0, 0b100, 0b1000, 0b0101, 0b010, REG_OPTIONAL>;
 
-defvar TLBI_TLBIW = [
-  "VMALLWS2E1", "VMALLWS2E1IS", "VMALLWS2E1OS"
-];
-
 let Requires = ["AArch64::FeatureTLBIW"] in {
-foreach I = TLBI_TLBIW in {
+foreach I = [
+  "VMALLWS2E1", "VMALLWS2E1IS", "VMALLWS2E1OS"
+  ] in {
   defvar Info = !cast<TLBI>(I);
   def : TLBIEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
     let Encoding{7} = 0;

>From ffca4f1b31379c0a51f05f1f609cfb4457cb09fb Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Fri, 20 Mar 2026 17:33:54 +0000
Subject: [PATCH 5/7] fixup! Another tablegen optimisation

---
 .../Target/AArch64/AArch64SystemOperands.td   | 262 ++++++++----------
 1 file changed, 119 insertions(+), 143 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index 3b686709022ba..eb50391bb9692 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -903,9 +903,9 @@ multiclass TLBITableBase {
 defm TLBI  : TLBITableBase;
 defm TLBIP : TLBITableBase;
 
-class TLBI<bit hasTLBIP, bits<3> op1, bits<4> crn,
+class TLBI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn,
            bits<4> crm, bits<3> op2, int reguse = REG_REQUIRED> {
-  string Name = NAME;
+  string Name = name;
   bit HasTLBIP = hasTLBIP;
   bits<3> Op1 = op1;
   bits<4> CRn = crn;
@@ -914,66 +914,60 @@ class TLBI<bit hasTLBIP, bits<3> op1, bits<4> crn,
   int RegUse = reguse;
 }
 
-// TLBI and TLBIP instructions encodings
-//               hasTLBIP  op1    CRn     CRm     op2    reguse
-def IPAS2E1IS    : TLBI<1, 0b100, 0b1000, 0b0000, 0b001, REG_REQUIRED>;
-def IPAS2LE1IS   : TLBI<1, 0b100, 0b1000, 0b0000, 0b101, REG_REQUIRED>;
-def VMALLE1IS    : TLBI<0, 0b000, 0b1000, 0b0011, 0b000, REG_OPTIONAL>;
-def ALLE2IS      : TLBI<0, 0b100, 0b1000, 0b0011, 0b000, REG_OPTIONAL>;
-def ALLE3IS      : TLBI<0, 0b110, 0b1000, 0b0011, 0b000, REG_OPTIONAL>;
-def VAE1IS       : TLBI<1, 0b000, 0b1000, 0b0011, 0b001, REG_REQUIRED>;
-def VAE2IS       : TLBI<1, 0b100, 0b1000, 0b0011, 0b001, REG_REQUIRED>;
-def VAE3IS       : TLBI<1, 0b110, 0b1000, 0b0011, 0b001, REG_REQUIRED>;
-def ASIDE1IS     : TLBI<0, 0b000, 0b1000, 0b0011, 0b010, REG_REQUIRED>;
-def VAAE1IS      : TLBI<1, 0b000, 0b1000, 0b0011, 0b011, REG_REQUIRED>;
-def ALLE1IS      : TLBI<0, 0b100, 0b1000, 0b0011, 0b100, REG_OPTIONAL>;
-def VALE1IS      : TLBI<1, 0b000, 0b1000, 0b0011, 0b101, REG_REQUIRED>;
-def VALE2IS      : TLBI<1, 0b100, 0b1000, 0b0011, 0b101, REG_REQUIRED>;
-def VALE3IS      : TLBI<1, 0b110, 0b1000, 0b0011, 0b101, REG_REQUIRED>;
-def VMALLS12E1IS : TLBI<0, 0b100, 0b1000, 0b0011, 0b110, REG_OPTIONAL>;
-def VAALE1IS     : TLBI<1, 0b000, 0b1000, 0b0011, 0b111, REG_REQUIRED>;
-def IPAS2E1      : TLBI<1, 0b100, 0b1000, 0b0100, 0b001, REG_REQUIRED>;
-def IPAS2LE1     : TLBI<1, 0b100, 0b1000, 0b0100, 0b101, REG_REQUIRED>;
-def VMALLE1      : TLBI<0, 0b000, 0b1000, 0b0111, 0b000, REG_NONE>;
-def ALLE2        : TLBI<0, 0b100, 0b1000, 0b0111, 0b000, REG_NONE>;
-def ALLE3        : TLBI<0, 0b110, 0b1000, 0b0111, 0b000, REG_NONE>;
-def VAE1         : TLBI<1, 0b000, 0b1000, 0b0111, 0b001, REG_REQUIRED>;
-def VAE2         : TLBI<1, 0b100, 0b1000, 0b0111, 0b001, REG_REQUIRED>;
-def VAE3         : TLBI<1, 0b110, 0b1000, 0b0111, 0b001, REG_REQUIRED>;
-def ASIDE1       : TLBI<0, 0b000, 0b1000, 0b0111, 0b010, REG_REQUIRED>;
-def VAAE1        : TLBI<1, 0b000, 0b1000, 0b0111, 0b011, REG_REQUIRED>;
-def ALLE1        : TLBI<0, 0b100, 0b1000, 0b0111, 0b100, REG_NONE>;
-def VALE1        : TLBI<1, 0b000, 0b1000, 0b0111, 0b101, REG_REQUIRED>;
-def VALE2        : TLBI<1, 0b100, 0b1000, 0b0111, 0b101, REG_REQUIRED>;
-def VALE3        : TLBI<1, 0b110, 0b1000, 0b0111, 0b101, REG_REQUIRED>;
-def VMALLS12E1   : TLBI<0, 0b100, 0b1000, 0b0111, 0b110, REG_NONE>;
-def VAALE1       : TLBI<1, 0b000, 0b1000, 0b0111, 0b111, REG_REQUIRED>;
-
-foreach I = [
-  "IPAS2E1IS", "IPAS2LE1IS", "VMALLE1IS", "ALLE2IS", "ALLE3IS",
-  "VAE1IS", "VAE2IS", "VAE3IS", "ASIDE1IS", "VAAE1IS",
-  "ALLE1IS", "VALE1IS", "VALE2IS", "VALE3IS", "VMALLS12E1IS",
-  "VAALE1IS", "IPAS2E1", "IPAS2LE1", "VMALLE1", "ALLE2",
-  "ALLE3", "VAE1", "VAE2", "VAE3", "ASIDE1", "VAAE1",
-  "ALLE1", "VALE1", "VALE2", "VALE3", "VMALLS12E1", "VAALE1"
-  ] in {
-  defvar Info = !cast<TLBI>(I);
-  def : TLBIEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+// TLBI and TLBIP instructions encodings.
+defvar TLBIBase = [
+  //    name    hasTLBIP  op1    CRn     CRm     op2    reguse
+  TLBI<"IPAS2E1IS",    1, 0b100, 0b1000, 0b0000, 0b001, REG_REQUIRED>,
+  TLBI<"IPAS2LE1IS",   1, 0b100, 0b1000, 0b0000, 0b101, REG_REQUIRED>,
+  TLBI<"VMALLE1IS",    0, 0b000, 0b1000, 0b0011, 0b000, REG_OPTIONAL>,
+  TLBI<"ALLE2IS",      0, 0b100, 0b1000, 0b0011, 0b000, REG_OPTIONAL>,
+  TLBI<"ALLE3IS",      0, 0b110, 0b1000, 0b0011, 0b000, REG_OPTIONAL>,
+  TLBI<"VAE1IS",       1, 0b000, 0b1000, 0b0011, 0b001, REG_REQUIRED>,
+  TLBI<"VAE2IS",       1, 0b100, 0b1000, 0b0011, 0b001, REG_REQUIRED>,
+  TLBI<"VAE3IS",       1, 0b110, 0b1000, 0b0011, 0b001, REG_REQUIRED>,
+  TLBI<"ASIDE1IS",     0, 0b000, 0b1000, 0b0011, 0b010, REG_REQUIRED>,
+  TLBI<"VAAE1IS",      1, 0b000, 0b1000, 0b0011, 0b011, REG_REQUIRED>,
+  TLBI<"ALLE1IS",      0, 0b100, 0b1000, 0b0011, 0b100, REG_OPTIONAL>,
+  TLBI<"VALE1IS",      1, 0b000, 0b1000, 0b0011, 0b101, REG_REQUIRED>,
+  TLBI<"VALE2IS",      1, 0b100, 0b1000, 0b0011, 0b101, REG_REQUIRED>,
+  TLBI<"VALE3IS",      1, 0b110, 0b1000, 0b0011, 0b101, REG_REQUIRED>,
+  TLBI<"VMALLS12E1IS", 0, 0b100, 0b1000, 0b0011, 0b110, REG_OPTIONAL>,
+  TLBI<"VAALE1IS",     1, 0b000, 0b1000, 0b0011, 0b111, REG_REQUIRED>,
+  TLBI<"IPAS2E1",      1, 0b100, 0b1000, 0b0100, 0b001, REG_REQUIRED>,
+  TLBI<"IPAS2LE1",     1, 0b100, 0b1000, 0b0100, 0b101, REG_REQUIRED>,
+  TLBI<"VMALLE1",      0, 0b000, 0b1000, 0b0111, 0b000, REG_NONE>,
+  TLBI<"ALLE2",        0, 0b100, 0b1000, 0b0111, 0b000, REG_NONE>,
+  TLBI<"ALLE3",        0, 0b110, 0b1000, 0b0111, 0b000, REG_NONE>,
+  TLBI<"VAE1",         1, 0b000, 0b1000, 0b0111, 0b001, REG_REQUIRED>,
+  TLBI<"VAE2",         1, 0b100, 0b1000, 0b0111, 0b001, REG_REQUIRED>,
+  TLBI<"VAE3",         1, 0b110, 0b1000, 0b0111, 0b001, REG_REQUIRED>,
+  TLBI<"ASIDE1",       0, 0b000, 0b1000, 0b0111, 0b010, REG_REQUIRED>,
+  TLBI<"VAAE1",        1, 0b000, 0b1000, 0b0111, 0b011, REG_REQUIRED>,
+  TLBI<"ALLE1",        0, 0b100, 0b1000, 0b0111, 0b100, REG_NONE>,
+  TLBI<"VALE1",        1, 0b000, 0b1000, 0b0111, 0b101, REG_REQUIRED>,
+  TLBI<"VALE2",        1, 0b100, 0b1000, 0b0111, 0b101, REG_REQUIRED>,
+  TLBI<"VALE3",        1, 0b110, 0b1000, 0b0111, 0b101, REG_REQUIRED>,
+  TLBI<"VMALLS12E1",   0, 0b100, 0b1000, 0b0111, 0b110, REG_NONE>,
+  TLBI<"VAALE1",       1, 0b000, 0b1000, 0b0111, 0b111, REG_REQUIRED>
+];
+
+foreach I = TLBIBase in {
+  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
     let Encoding{7} = 0;
   }
 
-  def : TLBIEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+  def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
     let Encoding{7} = 1;
     let ExtraRequires = ["AArch64::FeatureXS"];
   }
 
-  if !eq(Info.HasTLBIP, true) then {
-    def : TLBIPEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+  if !eq(I.HasTLBIP, true) then {
+    def : TLBIPEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
       let Encoding{7} = 0;
       let Requires = ["AArch64::FeatureD128"];
     }
 
-    def : TLBIPEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+    def : TLBIPEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
       let Encoding{7} = 1;
       let Requires = ["AArch64::FeatureD128"];
     }
@@ -981,90 +975,74 @@ foreach I = [
 }
 
 // Armv8.4-A Translation Lookaside Buffer Instructions (TLBI and TLBIP)
-// Armv8.4-A Outer Sharable TLB Maintenance instructions:
-//               hasTLBIP  op1    CRn     CRm     op2    reguse
-def VMALLE1OS    : TLBI<0, 0b000, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
-def VAE1OS       : TLBI<1, 0b000, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
-def ASIDE1OS     : TLBI<0, 0b000, 0b1000, 0b0001, 0b010, REG_REQUIRED>;
-def VAAE1OS      : TLBI<1, 0b000, 0b1000, 0b0001, 0b011, REG_REQUIRED>;
-def VALE1OS      : TLBI<1, 0b000, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
-def VAALE1OS     : TLBI<1, 0b000, 0b1000, 0b0001, 0b111, REG_REQUIRED>;
-def IPAS2E1OS    : TLBI<1, 0b100, 0b1000, 0b0100, 0b000, REG_REQUIRED>;
-def IPAS2LE1OS   : TLBI<1, 0b100, 0b1000, 0b0100, 0b100, REG_REQUIRED>;
-def VAE2OS       : TLBI<1, 0b100, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
-def VALE2OS      : TLBI<1, 0b100, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
-def VMALLS12E1OS : TLBI<0, 0b100, 0b1000, 0b0001, 0b110, REG_OPTIONAL>;
-def VAE3OS       : TLBI<1, 0b110, 0b1000, 0b0001, 0b001, REG_REQUIRED>;
-def VALE3OS      : TLBI<1, 0b110, 0b1000, 0b0001, 0b101, REG_REQUIRED>;
-def ALLE2OS      : TLBI<0, 0b100, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
-def ALLE1OS      : TLBI<0, 0b100, 0b1000, 0b0001, 0b100, REG_OPTIONAL>;
-def ALLE3OS      : TLBI<0, 0b110, 0b1000, 0b0001, 0b000, REG_OPTIONAL>;
-
-// Armv8.4-A TLB and TLBIP Range Maintenance instructions:
-//               hasTLBIP  op1    CRn     CRm     op2    reguse
-def RVAE1        : TLBI<1, 0b000, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
-def RVAAE1       : TLBI<1, 0b000, 0b1000, 0b0110, 0b011, REG_REQUIRED>;
-def RVALE1       : TLBI<1, 0b000, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
-def RVAALE1      : TLBI<1, 0b000, 0b1000, 0b0110, 0b111, REG_REQUIRED>;
-def RVAE1IS      : TLBI<1, 0b000, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
-def RVAAE1IS     : TLBI<1, 0b000, 0b1000, 0b0010, 0b011, REG_REQUIRED>;
-def RVALE1IS     : TLBI<1, 0b000, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
-def RVAALE1IS    : TLBI<1, 0b000, 0b1000, 0b0010, 0b111, REG_REQUIRED>;
-def RVAE1OS      : TLBI<1, 0b000, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
-def RVAAE1OS     : TLBI<1, 0b000, 0b1000, 0b0101, 0b011, REG_REQUIRED>;
-def RVALE1OS     : TLBI<1, 0b000, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
-def RVAALE1OS    : TLBI<1, 0b000, 0b1000, 0b0101, 0b111, REG_REQUIRED>;
-def RIPAS2E1IS   : TLBI<1, 0b100, 0b1000, 0b0000, 0b010, REG_REQUIRED>;
-def RIPAS2LE1IS  : TLBI<1, 0b100, 0b1000, 0b0000, 0b110, REG_REQUIRED>;
-def RIPAS2E1     : TLBI<1, 0b100, 0b1000, 0b0100, 0b010, REG_REQUIRED>;
-def RIPAS2LE1    : TLBI<1, 0b100, 0b1000, 0b0100, 0b110, REG_REQUIRED>;
-def RIPAS2E1OS   : TLBI<1, 0b100, 0b1000, 0b0100, 0b011, REG_REQUIRED>;
-def RIPAS2LE1OS  : TLBI<1, 0b100, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
-def RVAE2        : TLBI<1, 0b100, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
-def RVALE2       : TLBI<1, 0b100, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
-def RVAE2IS      : TLBI<1, 0b100, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
-def RVALE2IS     : TLBI<1, 0b100, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
-def RVAE2OS      : TLBI<1, 0b100, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
-def RVALE2OS     : TLBI<1, 0b100, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
-def RVAE3        : TLBI<1, 0b110, 0b1000, 0b0110, 0b001, REG_REQUIRED>;
-def RVALE3       : TLBI<1, 0b110, 0b1000, 0b0110, 0b101, REG_REQUIRED>;
-def RVAE3IS      : TLBI<1, 0b110, 0b1000, 0b0010, 0b001, REG_REQUIRED>;
-def RVALE3IS     : TLBI<1, 0b110, 0b1000, 0b0010, 0b101, REG_REQUIRED>;
-def RVAE3OS      : TLBI<1, 0b110, 0b1000, 0b0101, 0b001, REG_REQUIRED>;
-def RVALE3OS     : TLBI<1, 0b110, 0b1000, 0b0101, 0b101, REG_REQUIRED>;
-
-foreach I = [
-  "VMALLE1OS", "VAE1OS", "ASIDE1OS", "VAAE1OS",
-  "VALE1OS", "VAALE1OS", "IPAS2E1OS", "IPAS2LE1OS",
-  "VAE2OS", "VALE2OS", "VMALLS12E1OS", "VAE3OS",
-  "VALE3OS", "ALLE2OS", "ALLE1OS", "ALLE3OS",
-  "RVAE1", "RVAAE1", "RVALE1", "RVAALE1",
-  "RVAE1IS", "RVAAE1IS", "RVALE1IS", "RVAALE1IS",
-  "RVAE1OS", "RVAAE1OS", "RVALE1OS", "RVAALE1OS",
-  "RIPAS2E1IS", "RIPAS2LE1IS", "RIPAS2E1",
-  "RIPAS2LE1", "RIPAS2E1OS", "RIPAS2LE1OS",
-  "RVAE2", "RVALE2", "RVAE2IS", "RVALE2IS",
-  "RVAE2OS", "RVALE2OS", "RVAE3", "RVALE3",
-  "RVAE3IS", "RVALE3IS", "RVAE3OS", "RVALE3OS"
-  ] in {
-  defvar Info = !cast<TLBI>(I);
-  def : TLBIEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+defvar TLBIRMI = [
+  //    name    hasTLBIP  op1    CRn     CRm     op2    reguse
+  TLBI<"VMALLE1OS",    0, 0b000, 0b1000, 0b0001, 0b000, REG_OPTIONAL>,
+  TLBI<"VAE1OS",       1, 0b000, 0b1000, 0b0001, 0b001, REG_REQUIRED>,
+  TLBI<"ASIDE1OS",     0, 0b000, 0b1000, 0b0001, 0b010, REG_REQUIRED>,
+  TLBI<"VAAE1OS",      1, 0b000, 0b1000, 0b0001, 0b011, REG_REQUIRED>,
+  TLBI<"VALE1OS",      1, 0b000, 0b1000, 0b0001, 0b101, REG_REQUIRED>,
+  TLBI<"VAALE1OS",     1, 0b000, 0b1000, 0b0001, 0b111, REG_REQUIRED>,
+  TLBI<"IPAS2E1OS",    1, 0b100, 0b1000, 0b0100, 0b000, REG_REQUIRED>,
+  TLBI<"IPAS2LE1OS",   1, 0b100, 0b1000, 0b0100, 0b100, REG_REQUIRED>,
+  TLBI<"VAE2OS",       1, 0b100, 0b1000, 0b0001, 0b001, REG_REQUIRED>,
+  TLBI<"VALE2OS",      1, 0b100, 0b1000, 0b0001, 0b101, REG_REQUIRED>,
+  TLBI<"VMALLS12E1OS", 0, 0b100, 0b1000, 0b0001, 0b110, REG_OPTIONAL>,
+  TLBI<"VAE3OS",       1, 0b110, 0b1000, 0b0001, 0b001, REG_REQUIRED>,
+  TLBI<"VALE3OS",      1, 0b110, 0b1000, 0b0001, 0b101, REG_REQUIRED>,
+  TLBI<"ALLE2OS",      0, 0b100, 0b1000, 0b0001, 0b000, REG_OPTIONAL>,
+  TLBI<"ALLE1OS",      0, 0b100, 0b1000, 0b0001, 0b100, REG_OPTIONAL>,
+  TLBI<"ALLE3OS",      0, 0b110, 0b1000, 0b0001, 0b000, REG_OPTIONAL>,
+  TLBI<"RVAE1",        1, 0b000, 0b1000, 0b0110, 0b001, REG_REQUIRED>,
+  TLBI<"RVAAE1",       1, 0b000, 0b1000, 0b0110, 0b011, REG_REQUIRED>,
+  TLBI<"RVALE1",       1, 0b000, 0b1000, 0b0110, 0b101, REG_REQUIRED>,
+  TLBI<"RVAALE1",      1, 0b000, 0b1000, 0b0110, 0b111, REG_REQUIRED>,
+  TLBI<"RVAE1IS",      1, 0b000, 0b1000, 0b0010, 0b001, REG_REQUIRED>,
+  TLBI<"RVAAE1IS",     1, 0b000, 0b1000, 0b0010, 0b011, REG_REQUIRED>,
+  TLBI<"RVALE1IS",     1, 0b000, 0b1000, 0b0010, 0b101, REG_REQUIRED>,
+  TLBI<"RVAALE1IS",    1, 0b000, 0b1000, 0b0010, 0b111, REG_REQUIRED>,
+  TLBI<"RVAE1OS",      1, 0b000, 0b1000, 0b0101, 0b001, REG_REQUIRED>,
+  TLBI<"RVAAE1OS",     1, 0b000, 0b1000, 0b0101, 0b011, REG_REQUIRED>,
+  TLBI<"RVALE1OS",     1, 0b000, 0b1000, 0b0101, 0b101, REG_REQUIRED>,
+  TLBI<"RVAALE1OS",    1, 0b000, 0b1000, 0b0101, 0b111, REG_REQUIRED>,
+  TLBI<"RIPAS2E1IS",   1, 0b100, 0b1000, 0b0000, 0b010, REG_REQUIRED>,
+  TLBI<"RIPAS2LE1IS",  1, 0b100, 0b1000, 0b0000, 0b110, REG_REQUIRED>,
+  TLBI<"RIPAS2E1",     1, 0b100, 0b1000, 0b0100, 0b010, REG_REQUIRED>,
+  TLBI<"RIPAS2LE1",    1, 0b100, 0b1000, 0b0100, 0b110, REG_REQUIRED>,
+  TLBI<"RIPAS2E1OS",   1, 0b100, 0b1000, 0b0100, 0b011, REG_REQUIRED>,
+  TLBI<"RIPAS2LE1OS",  1, 0b100, 0b1000, 0b0100, 0b111, REG_REQUIRED>,
+  TLBI<"RVAE2",        1, 0b100, 0b1000, 0b0110, 0b001, REG_REQUIRED>,
+  TLBI<"RVALE2",       1, 0b100, 0b1000, 0b0110, 0b101, REG_REQUIRED>,
+  TLBI<"RVAE2IS",      1, 0b100, 0b1000, 0b0010, 0b001, REG_REQUIRED>,
+  TLBI<"RVALE2IS",     1, 0b100, 0b1000, 0b0010, 0b101, REG_REQUIRED>,
+  TLBI<"RVAE2OS",      1, 0b100, 0b1000, 0b0101, 0b001, REG_REQUIRED>,
+  TLBI<"RVALE2OS",     1, 0b100, 0b1000, 0b0101, 0b101, REG_REQUIRED>,
+  TLBI<"RVAE3",        1, 0b110, 0b1000, 0b0110, 0b001, REG_REQUIRED>,
+  TLBI<"RVALE3",       1, 0b110, 0b1000, 0b0110, 0b101, REG_REQUIRED>,
+  TLBI<"RVAE3IS",      1, 0b110, 0b1000, 0b0010, 0b001, REG_REQUIRED>,
+  TLBI<"RVALE3IS",     1, 0b110, 0b1000, 0b0010, 0b101, REG_REQUIRED>,
+  TLBI<"RVAE3OS",      1, 0b110, 0b1000, 0b0101, 0b001, REG_REQUIRED>,
+  TLBI<"RVALE3OS",     1, 0b110, 0b1000, 0b0101, 0b101, REG_REQUIRED>
+];
+
+foreach I = TLBIRMI in {
+  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
     let Encoding{7} = 0;
     let Requires = ["AArch64::FeatureTLB_RMI"];
   }
 
-  def : TLBIEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+  def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
     let Encoding{7} = 1;
     let Requires = ["AArch64::FeatureXS"];
   }
 
-  if !eq(Info.HasTLBIP, true) then {
-    def : TLBIPEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+  if !eq(I.HasTLBIP, true) then {
+    def : TLBIPEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
       let Encoding{7} = 0;
       let Requires = ["AArch64::FeatureD128"];
     }
 
-    def : TLBIPEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+    def : TLBIPEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
       let Encoding{7} = 1;
       let Requires = ["AArch64::FeatureD128"];
     }
@@ -1072,39 +1050,37 @@ foreach I = [
 }
 
 // Armv9-A Realm Management Extension TLBI Instructions
-//          hasTLBIP  op1    CRn     CRm     op2    reguse
-def RPAOS   : TLBI<0, 0b110, 0b1000, 0b0100, 0b011, REG_REQUIRED>;
-def RPALOS  : TLBI<0, 0b110, 0b1000, 0b0100, 0b111, REG_REQUIRED>;
-def PAALLOS : TLBI<0, 0b110, 0b1000, 0b0001, 0b100, REG_NONE>;
-def PAALL   : TLBI<0, 0b110, 0b1000, 0b0111, 0b100, REG_NONE>;
+defvar TLBIRME = [
+  //    name hasTLBIP  op1    CRn     CRm     op2    reguse
+  TLBI<"RPAOS",     0, 0b110, 0b1000, 0b0100, 0b011, REG_REQUIRED>,
+  TLBI<"RPALOS",    0, 0b110, 0b1000, 0b0100, 0b111, REG_REQUIRED>,
+  TLBI<"PAALLOS",   0, 0b110, 0b1000, 0b0001, 0b100, REG_NONE>,
+  TLBI<"PAALL",     0, 0b110, 0b1000, 0b0111, 0b100, REG_NONE>
+];
 
 let Requires = ["AArch64::FeatureRME"] in {
-foreach I = [
-  "RPAOS", "RPALOS", "PAALLOS", "PAALL"
-  ] in {
-  defvar Info = !cast<TLBI>(I);
-  def : TLBIEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+foreach I = TLBIRME in {
+  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
     let Encoding{7} = 0;
   }
 }
 }
 
 // Armv9.5-A TLBI VMALL for Dirty State
-//               hasTLBIP  op1    CRn     CRm     op2    reguse
-def VMALLWS2E1   : TLBI<0, 0b100, 0b1000, 0b0110, 0b010, REG_NONE>;
-def VMALLWS2E1IS : TLBI<0, 0b100, 0b1000, 0b0010, 0b010, REG_OPTIONAL>;
-def VMALLWS2E1OS : TLBI<0, 0b100, 0b1000, 0b0101, 0b010, REG_OPTIONAL>;
+defvar TLBITLBIW = [
+  //    name    hasTLBIP  op1    CRn     CRm     op2    reguse
+  TLBI<"VMALLWS2E1",   0, 0b100, 0b1000, 0b0110, 0b010, REG_NONE>,
+  TLBI<"VMALLWS2E1IS", 0, 0b100, 0b1000, 0b0010, 0b010, REG_OPTIONAL>,
+  TLBI<"VMALLWS2E1OS", 0, 0b100, 0b1000, 0b0101, 0b010, REG_OPTIONAL>
+];
 
 let Requires = ["AArch64::FeatureTLBIW"] in {
-foreach I = [
-  "VMALLWS2E1", "VMALLWS2E1IS", "VMALLWS2E1OS"
-  ] in {
-  defvar Info = !cast<TLBI>(I);
-  def : TLBIEntry<I, Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+foreach I = TLBITLBIW in {
+  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
     let Encoding{7} = 0;
   }
 
-  def : TLBIEntry<!strconcat(I, "nXS"), Info.Op1, Info.CRn, Info.CRm, Info.Op2, Info.RegUse> {
+  def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
     let Encoding{7} = 1;
     let ExtraRequires = ["AArch64::FeatureXS"];
   }

>From bcf4bf8d922cb83b8955d1c4a855542a7f2b68a3 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Fri, 20 Mar 2026 17:50:31 +0000
Subject: [PATCH 6/7] fixup! Move nxs bit into TLBIEntry rather than override

---
 .../Target/AArch64/AArch64SystemOperands.td   |  54 ++++-----
 llvm/test/MC/AArch64/armv8.7a-xs.s            | 113 +++++++++---------
 llvm/test/MC/AArch64/armv9.5a-tlbiw.s         |  20 ++--
 3 files changed, 88 insertions(+), 99 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index eb50391bb9692..7264fd2674e04 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -866,11 +866,12 @@ class SysAliasRegUse<int reguse> {
 }
 
 class TLBICommon<string name, bits<3> op1, bits<4> crn, bits<4> crm,
-                 bits<3> op2, int reguse> : SysAliasRegUse<reguse> {
+                 bits<3> op2, bit nxs, int reguse> : SysAliasRegUse<reguse> {
   string Name = name;
   bits<14> Encoding;
   let Encoding{13-11} = op1;
   let Encoding{10-7} = crn;
+  let Encoding{7} = nxs;
   let Encoding{6-3} = crm;
   let Encoding{2-0} = op2;
   list<string> Requires = [];
@@ -879,12 +880,12 @@ class TLBICommon<string name, bits<3> op1, bits<4> crn, bits<4> crm,
 }
 
 class TLBIEntry<string name, bits<3> op1, bits<4> crn, bits<4> crm,
-                bits<3> op2, int reguse>
-  : TLBICommon<name, op1, crn, crm, op2, reguse>;
+                bits<3> op2, bit nxs, int reguse>
+  : TLBICommon<name, op1, crn, crm, op2, nxs, reguse>;
 
 class TLBIPEntry<string name, bits<3> op1, bits<4> crn, bits<4> crm,
-                 bits<3> op2, int reguse>
-  : TLBICommon<name, op1, crn, crm, op2, reguse>;
+                 bits<3> op2, bit nxs, int reguse>
+  : TLBICommon<name, op1, crn, crm, op2, nxs, reguse>;
 
 multiclass TLBITableBase {
   def NAME # Table : GenericTable {
@@ -952,23 +953,19 @@ defvar TLBIBase = [
 ];
 
 foreach I = TLBIBase in {
-  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
-    let Encoding{7} = 0;
-  }
+  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, 0, I.RegUse>;
 
-  def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
-    let Encoding{7} = 1;
+  def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, 1, I.RegUse> {
     let ExtraRequires = ["AArch64::FeatureXS"];
   }
 
   if !eq(I.HasTLBIP, true) then {
-    def : TLBIPEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
-      let Encoding{7} = 0;
+    def : TLBIPEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, 0, I.RegUse> {
       let Requires = ["AArch64::FeatureD128"];
     }
 
-    def : TLBIPEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
-      let Encoding{7} = 1;
+    // *nxs variants are gated by `FEAT_D128` not `FEAT_XS`
+    def : TLBIPEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, 1, I.RegUse> {
       let Requires = ["AArch64::FeatureD128"];
     }
   }
@@ -1026,24 +1023,21 @@ defvar TLBIRMI = [
 ];
 
 foreach I = TLBIRMI in {
-  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
-    let Encoding{7} = 0;
+  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, 0, I.RegUse> {
     let Requires = ["AArch64::FeatureTLB_RMI"];
   }
 
-  def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
-    let Encoding{7} = 1;
+  def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, 1, I.RegUse> {
     let Requires = ["AArch64::FeatureXS"];
   }
 
   if !eq(I.HasTLBIP, true) then {
-    def : TLBIPEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
-      let Encoding{7} = 0;
+    def : TLBIPEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, 0, I.RegUse> {
       let Requires = ["AArch64::FeatureD128"];
     }
 
-    def : TLBIPEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
-      let Encoding{7} = 1;
+    // *nxs variants are gated by `FEAT_D128` not `FEAT_XS`
+    def : TLBIPEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, 1, I.RegUse> {
       let Requires = ["AArch64::FeatureD128"];
     }
   }
@@ -1060,9 +1054,8 @@ defvar TLBIRME = [
 
 let Requires = ["AArch64::FeatureRME"] in {
 foreach I = TLBIRME in {
-  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
-    let Encoding{7} = 0;
-  }
+  // No *nxs variants
+  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, 0, I.RegUse>;
 }
 }
 
@@ -1076,14 +1069,9 @@ defvar TLBITLBIW = [
 
 let Requires = ["AArch64::FeatureTLBIW"] in {
 foreach I = TLBITLBIW in {
-  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
-    let Encoding{7} = 0;
-  }
-
-  def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, I.RegUse> {
-    let Encoding{7} = 1;
-    let ExtraRequires = ["AArch64::FeatureXS"];
-  }
+  // *nxs variants are gated by `FEAT_TLBIW` not `FEAT_XS`
+  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, 0, I.RegUse>;
+  def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, 1, I.RegUse>;
 }
 }
 
diff --git a/llvm/test/MC/AArch64/armv8.7a-xs.s b/llvm/test/MC/AArch64/armv8.7a-xs.s
index e3a1e12aae9a5..da9fa98b2d78d 100644
--- a/llvm/test/MC/AArch64/armv8.7a-xs.s
+++ b/llvm/test/MC/AArch64/armv8.7a-xs.s
@@ -1,9 +1,11 @@
+// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+xs < %s 2>%t | FileCheck %s
+// RUN: FileCheck --check-prefix=CHECK-ERR %s < %t
 // RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.4a,+xs < %s 2>%t | FileCheck %s
 // RUN: FileCheck --check-prefix=CHECK-ERR %s < %t
 // RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.7a < %s 2>%t | FileCheck %s
 // RUN: FileCheck --check-prefix=CHECK-ERR %s < %t
 // RUN: not llvm-mc -triple aarch64-none-linux-gnu -mattr=+v8.4a < %s 2> %t
-// RUN: FileCheck --check-prefixes=CHECK-ERR,CHECK-NO-XS-ERR %s < %t
+// RUN: FileCheck --check-prefixes=CHECK-ERR,CHECK_NO_XS_ERR %s < %t
 
   dsb #16
   dsb #20
@@ -21,14 +23,14 @@
 // CHECK: dsb nshnxs                   // encoding: [0x3f,0x36,0x03,0xd5]
 // CHECK: dsb ishnxs                   // encoding: [0x3f,0x3a,0x03,0xd5]
 // CHECK: dsb synxs                    // encoding: [0x3f,0x3e,0x03,0xd5]
-// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs
-// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs
-// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs
-// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs
-// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs
-// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs
-// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs
-// CHECK-NO-XS-ERR: [[@LINE-16]]:3: error: instruction requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-16]]:3: error: instruction requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-16]]:3: error: instruction requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-16]]:3: error: instruction requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-16]]:3: error: instruction requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-16]]:3: error: instruction requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-16]]:3: error: instruction requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-16]]:3: error: instruction requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-16]]:3: error: instruction requires: xs
 
   dsb #17
   dsb nshstnxs
@@ -128,7 +130,6 @@
 // CHECK_NO_XS_ERR: [[@LINE-64]]:8: error: TLBI ALLE1nXS requires: xs
 // CHECK_NO_XS_ERR: [[@LINE-64]]:8: error: TLBI VALE1nXS requires: xs
 // CHECK_NO_XS_ERR: [[@LINE-64]]:8: error: TLBI VALE2nXS requires: xs
-// CHECK_NO_XS_ERR: [[@LINE-64]]:8: error: TLBI VALE2nXS requires: xs
 // CHECK_NO_XS_ERR: [[@LINE-64]]:8: error: TLBI VALE3nXS requires: xs
 // CHECK_NO_XS_ERR: [[@LINE-64]]:8: error: TLBI VMALLS12E1nXS requires: xs
 // CHECK_NO_XS_ERR: [[@LINE-64]]:8: error: TLBI VAALE1nXS requires: xs
@@ -225,49 +226,49 @@
 // CHECK: tlbi rvale3isnxs, x1         // encoding: [0xa1,0x92,0x0e,0xd5]
 // CHECK: tlbi rvae3osnxs, x1          // encoding: [0x21,0x95,0x0e,0xd5]
 // CHECK: tlbi rvale3osnxs, x1         // encoding: [0xa1,0x95,0x0e,0xd5]
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VMALLE1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VAE1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI ASIDE1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VAAE1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VALE1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VAALE1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI IPAS2E1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI IPAS2LE1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VAE2OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VALE2OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VMALLS12E1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VAE3OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VALE3OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI ALLE2OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI ALLE1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI ALLE3OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE1nXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAAE1nXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE1nXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAALE1nXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE1ISnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAAE1ISnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE1ISnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAALE1ISnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAAE1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAALE1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RIPAS2E1ISnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RIPAS2LE1ISnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RIPAS2E1nXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RIPAS2LE1nXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RIPAS2E1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RIPAS2LE1OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE2nXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE2nXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE2ISnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE2ISnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE2OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE2OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE3nXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE3nXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE3ISnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE3ISnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE3OSnXS requires: tlb-rmi, xs
-// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE3OSnXS requires: tlb-rmi, xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VMALLE1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VAE1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI ASIDE1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VAAE1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VALE1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VAALE1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI IPAS2E1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI IPAS2LE1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VAE2OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VALE2OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VMALLS12E1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VAE3OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI VALE3OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI ALLE2OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI ALLE1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI ALLE3OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE1nXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAAE1nXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE1nXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAALE1nXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE1ISnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAAE1ISnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE1ISnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAALE1ISnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAAE1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAALE1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RIPAS2E1ISnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RIPAS2LE1ISnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RIPAS2E1nXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RIPAS2LE1nXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RIPAS2E1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RIPAS2LE1OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE2nXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE2nXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE2ISnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE2ISnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE2OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE2OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE3nXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE3nXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE3ISnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE3ISnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVAE3OSnXS requires: xs
+// CHECK_NO_XS_ERR: [[@LINE-92]]:8: error: TLBI RVALE3OSnXS requires: xs
diff --git a/llvm/test/MC/AArch64/armv9.5a-tlbiw.s b/llvm/test/MC/AArch64/armv9.5a-tlbiw.s
index efd410c1c2c59..faee34d5dea4f 100644
--- a/llvm/test/MC/AArch64/armv9.5a-tlbiw.s
+++ b/llvm/test/MC/AArch64/armv9.5a-tlbiw.s
@@ -1,15 +1,15 @@
-// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+tlbiw,+xs < %s \
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+tlbiw < %s \
 // RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
 // RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \
 // RUN:        | FileCheck %s --check-prefixes=CHECK-ERROR
-// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+tlbiw,+xs < %s \
-// RUN:        | llvm-objdump -d --mattr=+tlbiw,+xs --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST
-// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+tlbiw,+xs < %s \
-// RUN:   | llvm-objdump -d --mattr=-tlbiw,-xs --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+tlbiw < %s \
+// RUN:        | llvm-objdump -d --mattr=+tlbiw --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+tlbiw < %s \
+// RUN:   | llvm-objdump -d --mattr=-tlbiw --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN
 // Disassemble encoding and check the re-encoding (-show-encoding) matches.
-// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+tlbiw,+xs < %s \
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+tlbiw < %s \
 // RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
-// RUN:        | llvm-mc -triple=aarch64 -mattr=+tlbiw,+xs -disassemble -show-encoding \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+tlbiw -disassemble -show-encoding \
 // RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
 
 
@@ -34,17 +34,17 @@ tlbi VMALLWS2E1OS
 tlbi VMALLWS2E1nXS
 // CHECK-INST: tlbi vmallws2e1nxs
 // CHECK-ENCODING: encoding: [0x5f,0x96,0x0c,0xd5]
-// CHECK-ERROR: :[[@LINE-3]]:6: error: TLBI VMALLWS2E1nXS requires: xs, tlbiw
+// CHECK-ERROR: :[[@LINE-3]]:6: error: TLBI VMALLWS2E1nXS requires: tlbiw
 // CHECK-UNKNOWN:  d50c965f      sys #4, c9, c6, #2
 
 tlbi VMALLWS2E1ISnXS
 // CHECK-INST: tlbi vmallws2e1isnxs
 // CHECK-ENCODING: encoding: [0x5f,0x92,0x0c,0xd5]
-// CHECK-ERROR: :[[@LINE-3]]:6: error: TLBI VMALLWS2E1ISnXS requires: xs, tlbiw
+// CHECK-ERROR: :[[@LINE-3]]:6: error: TLBI VMALLWS2E1ISnXS requires: tlbiw
 // CHECK-UNKNOWN:  d50c925f      sys #4, c9, c2, #2
 
 tlbi VMALLWS2E1OSnXS
 // CHECK-INST: tlbi vmallws2e1osnxs
 // CHECK-ENCODING: encoding: [0x5f,0x95,0x0c,0xd5]
-// CHECK-ERROR: :[[@LINE-3]]:6: error: TLBI VMALLWS2E1OSnXS requires: xs, tlbiw
+// CHECK-ERROR: :[[@LINE-3]]:6: error: TLBI VMALLWS2E1OSnXS requires: tlbiw
 // CHECK-UNKNOWN:  d50c955f      sys #4, c9, c5, #2

>From 240687d681b1006fcecb61b2f9a1a053862d68e3 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
Date: Thu, 26 Mar 2026 16:47:01 +0000
Subject: [PATCH 7/7] fixup! More optimisations

---
 .../Target/AArch64/AArch64SystemOperands.td   | 254 +++++++++---------
 1 file changed, 121 insertions(+), 133 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index 7264fd2674e04..645d401e1c38d 100644
--- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td
+++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
@@ -865,12 +865,12 @@ class SysAliasRegUse<int reguse> {
   bit OptionalReg = !eq(reguse, REG_OPTIONAL);
 }
 
-class TLBICommon<string name, bits<3> op1, bits<4> crn, bits<4> crm,
-                 bits<3> op2, bit nxs, int reguse> : SysAliasRegUse<reguse> {
+class TLBICommon<string name, bits<3> op1, bits<4> crm, bits<3> op2, bit nxs,
+                 int reguse> : SysAliasRegUse<reguse> {
   string Name = name;
   bits<14> Encoding;
   let Encoding{13-11} = op1;
-  let Encoding{10-7} = crn;
+  let Encoding{10-8} = 0b100;
   let Encoding{7} = nxs;
   let Encoding{6-3} = crm;
   let Encoding{2-0} = op2;
@@ -879,13 +879,13 @@ class TLBICommon<string name, bits<3> op1, bits<4> crn, bits<4> crm,
   code RequiresStr = [{ { }] # !interleave(Requires # ExtraRequires, [{, }]) # [{ } }];
 }
 
-class TLBIEntry<string name, bits<3> op1, bits<4> crn, bits<4> crm,
-                bits<3> op2, bit nxs, int reguse>
-  : TLBICommon<name, op1, crn, crm, op2, nxs, reguse>;
+class TLBIEntry<string name, bits<3> op1, bits<4> crm, bits<3> op2, bit nxs,
+                int reguse>
+  : TLBICommon<name, op1, crm, op2, nxs, reguse>;
 
-class TLBIPEntry<string name, bits<3> op1, bits<4> crn, bits<4> crm,
-                 bits<3> op2, bit nxs, int reguse>
-  : TLBICommon<name, op1, crn, crm, op2, nxs, reguse>;
+class TLBIPEntry<string name, bits<3> op1, bits<4> crm, bits<3> op2, bit nxs,
+                 int reguse>
+  : TLBICommon<name, op1, crm, op2, nxs, reguse>;
 
 multiclass TLBITableBase {
   def NAME # Table : GenericTable {
@@ -904,12 +904,11 @@ multiclass TLBITableBase {
 defm TLBI  : TLBITableBase;
 defm TLBIP : TLBITableBase;
 
-class TLBI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn,
-           bits<4> crm, bits<3> op2, int reguse = REG_REQUIRED> {
+class TLBI<string name, bit hasTLBIP, bits<3> op1, bits<4> crm, bits<3> op2,
+           int reguse = REG_REQUIRED> {
   string Name = name;
   bit HasTLBIP = hasTLBIP;
   bits<3> Op1 = op1;
-  bits<4> CRn = crn;
   bits<4> CRm = crm;
   bits<3> Op2 = op2;
   int RegUse = reguse;
@@ -917,162 +916,151 @@ class TLBI<string name, bit hasTLBIP, bits<3> op1, bits<4> crn,
 
 // TLBI and TLBIP instructions encodings.
 defvar TLBIBase = [
-  //    name    hasTLBIP  op1    CRn     CRm     op2    reguse
-  TLBI<"IPAS2E1IS",    1, 0b100, 0b1000, 0b0000, 0b001, REG_REQUIRED>,
-  TLBI<"IPAS2LE1IS",   1, 0b100, 0b1000, 0b0000, 0b101, REG_REQUIRED>,
-  TLBI<"VMALLE1IS",    0, 0b000, 0b1000, 0b0011, 0b000, REG_OPTIONAL>,
-  TLBI<"ALLE2IS",      0, 0b100, 0b1000, 0b0011, 0b000, REG_OPTIONAL>,
-  TLBI<"ALLE3IS",      0, 0b110, 0b1000, 0b0011, 0b000, REG_OPTIONAL>,
-  TLBI<"VAE1IS",       1, 0b000, 0b1000, 0b0011, 0b001, REG_REQUIRED>,
-  TLBI<"VAE2IS",       1, 0b100, 0b1000, 0b0011, 0b001, REG_REQUIRED>,
-  TLBI<"VAE3IS",       1, 0b110, 0b1000, 0b0011, 0b001, REG_REQUIRED>,
-  TLBI<"ASIDE1IS",     0, 0b000, 0b1000, 0b0011, 0b010, REG_REQUIRED>,
-  TLBI<"VAAE1IS",      1, 0b000, 0b1000, 0b0011, 0b011, REG_REQUIRED>,
-  TLBI<"ALLE1IS",      0, 0b100, 0b1000, 0b0011, 0b100, REG_OPTIONAL>,
-  TLBI<"VALE1IS",      1, 0b000, 0b1000, 0b0011, 0b101, REG_REQUIRED>,
-  TLBI<"VALE2IS",      1, 0b100, 0b1000, 0b0011, 0b101, REG_REQUIRED>,
-  TLBI<"VALE3IS",      1, 0b110, 0b1000, 0b0011, 0b101, REG_REQUIRED>,
-  TLBI<"VMALLS12E1IS", 0, 0b100, 0b1000, 0b0011, 0b110, REG_OPTIONAL>,
-  TLBI<"VAALE1IS",     1, 0b000, 0b1000, 0b0011, 0b111, REG_REQUIRED>,
-  TLBI<"IPAS2E1",      1, 0b100, 0b1000, 0b0100, 0b001, REG_REQUIRED>,
-  TLBI<"IPAS2LE1",     1, 0b100, 0b1000, 0b0100, 0b101, REG_REQUIRED>,
-  TLBI<"VMALLE1",      0, 0b000, 0b1000, 0b0111, 0b000, REG_NONE>,
-  TLBI<"ALLE2",        0, 0b100, 0b1000, 0b0111, 0b000, REG_NONE>,
-  TLBI<"ALLE3",        0, 0b110, 0b1000, 0b0111, 0b000, REG_NONE>,
-  TLBI<"VAE1",         1, 0b000, 0b1000, 0b0111, 0b001, REG_REQUIRED>,
-  TLBI<"VAE2",         1, 0b100, 0b1000, 0b0111, 0b001, REG_REQUIRED>,
-  TLBI<"VAE3",         1, 0b110, 0b1000, 0b0111, 0b001, REG_REQUIRED>,
-  TLBI<"ASIDE1",       0, 0b000, 0b1000, 0b0111, 0b010, REG_REQUIRED>,
-  TLBI<"VAAE1",        1, 0b000, 0b1000, 0b0111, 0b011, REG_REQUIRED>,
-  TLBI<"ALLE1",        0, 0b100, 0b1000, 0b0111, 0b100, REG_NONE>,
-  TLBI<"VALE1",        1, 0b000, 0b1000, 0b0111, 0b101, REG_REQUIRED>,
-  TLBI<"VALE2",        1, 0b100, 0b1000, 0b0111, 0b101, REG_REQUIRED>,
-  TLBI<"VALE3",        1, 0b110, 0b1000, 0b0111, 0b101, REG_REQUIRED>,
-  TLBI<"VMALLS12E1",   0, 0b100, 0b1000, 0b0111, 0b110, REG_NONE>,
-  TLBI<"VAALE1",       1, 0b000, 0b1000, 0b0111, 0b111, REG_REQUIRED>
+  //    name    hasTLBIP  op1    CRm     op2    reguse
+  TLBI<"IPAS2E1IS",    1, 0b100, 0b0000, 0b001, REG_REQUIRED>,
+  TLBI<"IPAS2LE1IS",   1, 0b100, 0b0000, 0b101, REG_REQUIRED>,
+  TLBI<"VMALLE1IS",    0, 0b000, 0b0011, 0b000, REG_OPTIONAL>,
+  TLBI<"ALLE2IS",      0, 0b100, 0b0011, 0b000, REG_OPTIONAL>,
+  TLBI<"ALLE3IS",      0, 0b110, 0b0011, 0b000, REG_OPTIONAL>,
+  TLBI<"VAE1IS",       1, 0b000, 0b0011, 0b001, REG_REQUIRED>,
+  TLBI<"VAE2IS",       1, 0b100, 0b0011, 0b001, REG_REQUIRED>,
+  TLBI<"VAE3IS",       1, 0b110, 0b0011, 0b001, REG_REQUIRED>,
+  TLBI<"ASIDE1IS",     0, 0b000, 0b0011, 0b010, REG_REQUIRED>,
+  TLBI<"VAAE1IS",      1, 0b000, 0b0011, 0b011, REG_REQUIRED>,
+  TLBI<"ALLE1IS",      0, 0b100, 0b0011, 0b100, REG_OPTIONAL>,
+  TLBI<"VALE1IS",      1, 0b000, 0b0011, 0b101, REG_REQUIRED>,
+  TLBI<"VALE2IS",      1, 0b100, 0b0011, 0b101, REG_REQUIRED>,
+  TLBI<"VALE3IS",      1, 0b110, 0b0011, 0b101, REG_REQUIRED>,
+  TLBI<"VMALLS12E1IS", 0, 0b100, 0b0011, 0b110, REG_OPTIONAL>,
+  TLBI<"VAALE1IS",     1, 0b000, 0b0011, 0b111, REG_REQUIRED>,
+  TLBI<"IPAS2E1",      1, 0b100, 0b0100, 0b001, REG_REQUIRED>,
+  TLBI<"IPAS2LE1",     1, 0b100, 0b0100, 0b101, REG_REQUIRED>,
+  TLBI<"VMALLE1",      0, 0b000, 0b0111, 0b000, REG_NONE>,
+  TLBI<"ALLE2",        0, 0b100, 0b0111, 0b000, REG_NONE>,
+  TLBI<"ALLE3",        0, 0b110, 0b0111, 0b000, REG_NONE>,
+  TLBI<"VAE1",         1, 0b000, 0b0111, 0b001, REG_REQUIRED>,
+  TLBI<"VAE2",         1, 0b100, 0b0111, 0b001, REG_REQUIRED>,
+  TLBI<"VAE3",         1, 0b110, 0b0111, 0b001, REG_REQUIRED>,
+  TLBI<"ASIDE1",       0, 0b000, 0b0111, 0b010, REG_REQUIRED>,
+  TLBI<"VAAE1",        1, 0b000, 0b0111, 0b011, REG_REQUIRED>,
+  TLBI<"ALLE1",        0, 0b100, 0b0111, 0b100, REG_NONE>,
+  TLBI<"VALE1",        1, 0b000, 0b0111, 0b101, REG_REQUIRED>,
+  TLBI<"VALE2",        1, 0b100, 0b0111, 0b101, REG_REQUIRED>,
+  TLBI<"VALE3",        1, 0b110, 0b0111, 0b101, REG_REQUIRED>,
+  TLBI<"VMALLS12E1",   0, 0b100, 0b0111, 0b110, REG_NONE>,
+  TLBI<"VAALE1",       1, 0b000, 0b0111, 0b111, REG_REQUIRED>
 ];
 
 foreach I = TLBIBase in {
-  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, 0, I.RegUse>;
-
-  def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, 1, I.RegUse> {
+  def : TLBIEntry<I.Name, I.Op1, I.CRm, I.Op2, 0, I.RegUse>;
+  def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRm, I.Op2, 1, I.RegUse> {
     let ExtraRequires = ["AArch64::FeatureXS"];
   }
 
-  if !eq(I.HasTLBIP, true) then {
-    def : TLBIPEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, 0, I.RegUse> {
-      let Requires = ["AArch64::FeatureD128"];
-    }
-
-    // *nxs variants are gated by `FEAT_D128` not `FEAT_XS`
-    def : TLBIPEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, 1, I.RegUse> {
-      let Requires = ["AArch64::FeatureD128"];
+  if I.HasTLBIP then {
+    let Requires = ["AArch64::FeatureD128"] in {
+      def : TLBIPEntry<I.Name, I.Op1, I.CRm, I.Op2, 0, I.RegUse>;
+      def : TLBIPEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRm, I.Op2, 1, I.RegUse>;
     }
   }
 }
 
 // Armv8.4-A Translation Lookaside Buffer Instructions (TLBI and TLBIP)
 defvar TLBIRMI = [
-  //    name    hasTLBIP  op1    CRn     CRm     op2    reguse
-  TLBI<"VMALLE1OS",    0, 0b000, 0b1000, 0b0001, 0b000, REG_OPTIONAL>,
-  TLBI<"VAE1OS",       1, 0b000, 0b1000, 0b0001, 0b001, REG_REQUIRED>,
-  TLBI<"ASIDE1OS",     0, 0b000, 0b1000, 0b0001, 0b010, REG_REQUIRED>,
-  TLBI<"VAAE1OS",      1, 0b000, 0b1000, 0b0001, 0b011, REG_REQUIRED>,
-  TLBI<"VALE1OS",      1, 0b000, 0b1000, 0b0001, 0b101, REG_REQUIRED>,
-  TLBI<"VAALE1OS",     1, 0b000, 0b1000, 0b0001, 0b111, REG_REQUIRED>,
-  TLBI<"IPAS2E1OS",    1, 0b100, 0b1000, 0b0100, 0b000, REG_REQUIRED>,
-  TLBI<"IPAS2LE1OS",   1, 0b100, 0b1000, 0b0100, 0b100, REG_REQUIRED>,
-  TLBI<"VAE2OS",       1, 0b100, 0b1000, 0b0001, 0b001, REG_REQUIRED>,
-  TLBI<"VALE2OS",      1, 0b100, 0b1000, 0b0001, 0b101, REG_REQUIRED>,
-  TLBI<"VMALLS12E1OS", 0, 0b100, 0b1000, 0b0001, 0b110, REG_OPTIONAL>,
-  TLBI<"VAE3OS",       1, 0b110, 0b1000, 0b0001, 0b001, REG_REQUIRED>,
-  TLBI<"VALE3OS",      1, 0b110, 0b1000, 0b0001, 0b101, REG_REQUIRED>,
-  TLBI<"ALLE2OS",      0, 0b100, 0b1000, 0b0001, 0b000, REG_OPTIONAL>,
-  TLBI<"ALLE1OS",      0, 0b100, 0b1000, 0b0001, 0b100, REG_OPTIONAL>,
-  TLBI<"ALLE3OS",      0, 0b110, 0b1000, 0b0001, 0b000, REG_OPTIONAL>,
-  TLBI<"RVAE1",        1, 0b000, 0b1000, 0b0110, 0b001, REG_REQUIRED>,
-  TLBI<"RVAAE1",       1, 0b000, 0b1000, 0b0110, 0b011, REG_REQUIRED>,
-  TLBI<"RVALE1",       1, 0b000, 0b1000, 0b0110, 0b101, REG_REQUIRED>,
-  TLBI<"RVAALE1",      1, 0b000, 0b1000, 0b0110, 0b111, REG_REQUIRED>,
-  TLBI<"RVAE1IS",      1, 0b000, 0b1000, 0b0010, 0b001, REG_REQUIRED>,
-  TLBI<"RVAAE1IS",     1, 0b000, 0b1000, 0b0010, 0b011, REG_REQUIRED>,
-  TLBI<"RVALE1IS",     1, 0b000, 0b1000, 0b0010, 0b101, REG_REQUIRED>,
-  TLBI<"RVAALE1IS",    1, 0b000, 0b1000, 0b0010, 0b111, REG_REQUIRED>,
-  TLBI<"RVAE1OS",      1, 0b000, 0b1000, 0b0101, 0b001, REG_REQUIRED>,
-  TLBI<"RVAAE1OS",     1, 0b000, 0b1000, 0b0101, 0b011, REG_REQUIRED>,
-  TLBI<"RVALE1OS",     1, 0b000, 0b1000, 0b0101, 0b101, REG_REQUIRED>,
-  TLBI<"RVAALE1OS",    1, 0b000, 0b1000, 0b0101, 0b111, REG_REQUIRED>,
-  TLBI<"RIPAS2E1IS",   1, 0b100, 0b1000, 0b0000, 0b010, REG_REQUIRED>,
-  TLBI<"RIPAS2LE1IS",  1, 0b100, 0b1000, 0b0000, 0b110, REG_REQUIRED>,
-  TLBI<"RIPAS2E1",     1, 0b100, 0b1000, 0b0100, 0b010, REG_REQUIRED>,
-  TLBI<"RIPAS2LE1",    1, 0b100, 0b1000, 0b0100, 0b110, REG_REQUIRED>,
-  TLBI<"RIPAS2E1OS",   1, 0b100, 0b1000, 0b0100, 0b011, REG_REQUIRED>,
-  TLBI<"RIPAS2LE1OS",  1, 0b100, 0b1000, 0b0100, 0b111, REG_REQUIRED>,
-  TLBI<"RVAE2",        1, 0b100, 0b1000, 0b0110, 0b001, REG_REQUIRED>,
-  TLBI<"RVALE2",       1, 0b100, 0b1000, 0b0110, 0b101, REG_REQUIRED>,
-  TLBI<"RVAE2IS",      1, 0b100, 0b1000, 0b0010, 0b001, REG_REQUIRED>,
-  TLBI<"RVALE2IS",     1, 0b100, 0b1000, 0b0010, 0b101, REG_REQUIRED>,
-  TLBI<"RVAE2OS",      1, 0b100, 0b1000, 0b0101, 0b001, REG_REQUIRED>,
-  TLBI<"RVALE2OS",     1, 0b100, 0b1000, 0b0101, 0b101, REG_REQUIRED>,
-  TLBI<"RVAE3",        1, 0b110, 0b1000, 0b0110, 0b001, REG_REQUIRED>,
-  TLBI<"RVALE3",       1, 0b110, 0b1000, 0b0110, 0b101, REG_REQUIRED>,
-  TLBI<"RVAE3IS",      1, 0b110, 0b1000, 0b0010, 0b001, REG_REQUIRED>,
-  TLBI<"RVALE3IS",     1, 0b110, 0b1000, 0b0010, 0b101, REG_REQUIRED>,
-  TLBI<"RVAE3OS",      1, 0b110, 0b1000, 0b0101, 0b001, REG_REQUIRED>,
-  TLBI<"RVALE3OS",     1, 0b110, 0b1000, 0b0101, 0b101, REG_REQUIRED>
+  //    name    hasTLBIP  op1    CRm     op2    reguse
+  TLBI<"VMALLE1OS",    0, 0b000, 0b0001, 0b000, REG_OPTIONAL>,
+  TLBI<"VAE1OS",       1, 0b000, 0b0001, 0b001, REG_REQUIRED>,
+  TLBI<"ASIDE1OS",     0, 0b000, 0b0001, 0b010, REG_REQUIRED>,
+  TLBI<"VAAE1OS",      1, 0b000, 0b0001, 0b011, REG_REQUIRED>,
+  TLBI<"VALE1OS",      1, 0b000, 0b0001, 0b101, REG_REQUIRED>,
+  TLBI<"VAALE1OS",     1, 0b000, 0b0001, 0b111, REG_REQUIRED>,
+  TLBI<"IPAS2E1OS",    1, 0b100, 0b0100, 0b000, REG_REQUIRED>,
+  TLBI<"IPAS2LE1OS",   1, 0b100, 0b0100, 0b100, REG_REQUIRED>,
+  TLBI<"VAE2OS",       1, 0b100, 0b0001, 0b001, REG_REQUIRED>,
+  TLBI<"VALE2OS",      1, 0b100, 0b0001, 0b101, REG_REQUIRED>,
+  TLBI<"VMALLS12E1OS", 0, 0b100, 0b0001, 0b110, REG_OPTIONAL>,
+  TLBI<"VAE3OS",       1, 0b110, 0b0001, 0b001, REG_REQUIRED>,
+  TLBI<"VALE3OS",      1, 0b110, 0b0001, 0b101, REG_REQUIRED>,
+  TLBI<"ALLE2OS",      0, 0b100, 0b0001, 0b000, REG_OPTIONAL>,
+  TLBI<"ALLE1OS",      0, 0b100, 0b0001, 0b100, REG_OPTIONAL>,
+  TLBI<"ALLE3OS",      0, 0b110, 0b0001, 0b000, REG_OPTIONAL>,
+  TLBI<"RVAE1",        1, 0b000, 0b0110, 0b001, REG_REQUIRED>,
+  TLBI<"RVAAE1",       1, 0b000, 0b0110, 0b011, REG_REQUIRED>,
+  TLBI<"RVALE1",       1, 0b000, 0b0110, 0b101, REG_REQUIRED>,
+  TLBI<"RVAALE1",      1, 0b000, 0b0110, 0b111, REG_REQUIRED>,
+  TLBI<"RVAE1IS",      1, 0b000, 0b0010, 0b001, REG_REQUIRED>,
+  TLBI<"RVAAE1IS",     1, 0b000, 0b0010, 0b011, REG_REQUIRED>,
+  TLBI<"RVALE1IS",     1, 0b000, 0b0010, 0b101, REG_REQUIRED>,
+  TLBI<"RVAALE1IS",    1, 0b000, 0b0010, 0b111, REG_REQUIRED>,
+  TLBI<"RVAE1OS",      1, 0b000, 0b0101, 0b001, REG_REQUIRED>,
+  TLBI<"RVAAE1OS",     1, 0b000, 0b0101, 0b011, REG_REQUIRED>,
+  TLBI<"RVALE1OS",     1, 0b000, 0b0101, 0b101, REG_REQUIRED>,
+  TLBI<"RVAALE1OS",    1, 0b000, 0b0101, 0b111, REG_REQUIRED>,
+  TLBI<"RIPAS2E1IS",   1, 0b100, 0b0000, 0b010, REG_REQUIRED>,
+  TLBI<"RIPAS2LE1IS",  1, 0b100, 0b0000, 0b110, REG_REQUIRED>,
+  TLBI<"RIPAS2E1",     1, 0b100, 0b0100, 0b010, REG_REQUIRED>,
+  TLBI<"RIPAS2LE1",    1, 0b100, 0b0100, 0b110, REG_REQUIRED>,
+  TLBI<"RIPAS2E1OS",   1, 0b100, 0b0100, 0b011, REG_REQUIRED>,
+  TLBI<"RIPAS2LE1OS",  1, 0b100, 0b0100, 0b111, REG_REQUIRED>,
+  TLBI<"RVAE2",        1, 0b100, 0b0110, 0b001, REG_REQUIRED>,
+  TLBI<"RVALE2",       1, 0b100, 0b0110, 0b101, REG_REQUIRED>,
+  TLBI<"RVAE2IS",      1, 0b100, 0b0010, 0b001, REG_REQUIRED>,
+  TLBI<"RVALE2IS",     1, 0b100, 0b0010, 0b101, REG_REQUIRED>,
+  TLBI<"RVAE2OS",      1, 0b100, 0b0101, 0b001, REG_REQUIRED>,
+  TLBI<"RVALE2OS",     1, 0b100, 0b0101, 0b101, REG_REQUIRED>,
+  TLBI<"RVAE3",        1, 0b110, 0b0110, 0b001, REG_REQUIRED>,
+  TLBI<"RVALE3",       1, 0b110, 0b0110, 0b101, REG_REQUIRED>,
+  TLBI<"RVAE3IS",      1, 0b110, 0b0010, 0b001, REG_REQUIRED>,
+  TLBI<"RVALE3IS",     1, 0b110, 0b0010, 0b101, REG_REQUIRED>,
+  TLBI<"RVAE3OS",      1, 0b110, 0b0101, 0b001, REG_REQUIRED>,
+  TLBI<"RVALE3OS",     1, 0b110, 0b0101, 0b101, REG_REQUIRED>
 ];
 
 foreach I = TLBIRMI in {
-  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, 0, I.RegUse> {
-    let Requires = ["AArch64::FeatureTLB_RMI"];
+  let Requires = ["AArch64::FeatureTLB_RMI"] in {
+    def : TLBIEntry<I.Name, I.Op1, I.CRm, I.Op2, 0, I.RegUse>;
   }
 
-  def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, 1, I.RegUse> {
-    let Requires = ["AArch64::FeatureXS"];
+  let Requires = ["AArch64::FeatureXS"] in {
+    def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRm, I.Op2, 1, I.RegUse>;
   }
 
-  if !eq(I.HasTLBIP, true) then {
-    def : TLBIPEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, 0, I.RegUse> {
-      let Requires = ["AArch64::FeatureD128"];
-    }
-
-    // *nxs variants are gated by `FEAT_D128` not `FEAT_XS`
-    def : TLBIPEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, 1, I.RegUse> {
-      let Requires = ["AArch64::FeatureD128"];
+  if I.HasTLBIP then {
+    let Requires = ["AArch64::FeatureD128"] in {
+      def : TLBIPEntry<I.Name, I.Op1, I.CRm, I.Op2, 0, I.RegUse>;
+      def : TLBIPEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRm, I.Op2, 1, I.RegUse>;
     }
   }
 }
 
 // Armv9-A Realm Management Extension TLBI Instructions
 defvar TLBIRME = [
-  //    name hasTLBIP  op1    CRn     CRm     op2    reguse
-  TLBI<"RPAOS",     0, 0b110, 0b1000, 0b0100, 0b011, REG_REQUIRED>,
-  TLBI<"RPALOS",    0, 0b110, 0b1000, 0b0100, 0b111, REG_REQUIRED>,
-  TLBI<"PAALLOS",   0, 0b110, 0b1000, 0b0001, 0b100, REG_NONE>,
-  TLBI<"PAALL",     0, 0b110, 0b1000, 0b0111, 0b100, REG_NONE>
+  //    name hasTLBIP  op1    CRm     op2    reguse
+  TLBI<"RPAOS",     0, 0b110, 0b0100, 0b011, REG_REQUIRED>,
+  TLBI<"RPALOS",    0, 0b110, 0b0100, 0b111, REG_REQUIRED>,
+  TLBI<"PAALLOS",   0, 0b110, 0b0001, 0b100, REG_NONE>,
+  TLBI<"PAALL",     0, 0b110, 0b0111, 0b100, REG_NONE>
 ];
 
 let Requires = ["AArch64::FeatureRME"] in {
-foreach I = TLBIRME in {
-  // No *nxs variants
-  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, 0, I.RegUse>;
-}
+  foreach I = TLBIRME in {
+    def : TLBIEntry<I.Name, I.Op1, I.CRm, I.Op2, 0, I.RegUse>;
+  }
 }
 
 // Armv9.5-A TLBI VMALL for Dirty State
 defvar TLBITLBIW = [
-  //    name    hasTLBIP  op1    CRn     CRm     op2    reguse
-  TLBI<"VMALLWS2E1",   0, 0b100, 0b1000, 0b0110, 0b010, REG_NONE>,
-  TLBI<"VMALLWS2E1IS", 0, 0b100, 0b1000, 0b0010, 0b010, REG_OPTIONAL>,
-  TLBI<"VMALLWS2E1OS", 0, 0b100, 0b1000, 0b0101, 0b010, REG_OPTIONAL>
+  //    name    hasTLBIP  op1    CRm     op2    reguse
+  TLBI<"VMALLWS2E1",   0, 0b100, 0b0110, 0b010, REG_NONE>,
+  TLBI<"VMALLWS2E1IS", 0, 0b100, 0b0010, 0b010, REG_OPTIONAL>,
+  TLBI<"VMALLWS2E1OS", 0, 0b100, 0b0101, 0b010, REG_OPTIONAL>
 ];
 
 let Requires = ["AArch64::FeatureTLBIW"] in {
-foreach I = TLBITLBIW in {
-  // *nxs variants are gated by `FEAT_TLBIW` not `FEAT_XS`
-  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, 0, I.RegUse>;
-  def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, 1, I.RegUse>;
-}
+  foreach I = TLBITLBIW in {
+    def : TLBIEntry<I.Name, I.Op1, I.CRm, I.Op2, 0, I.RegUse>;
+    def : TLBIEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRm, I.Op2, 1, I.RegUse>;
+  }
 }
 
 //===----------------------------------------------------------------------===//



More information about the llvm-branch-commits mailing list