[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
Fri Mar 20 10:52:45 PDT 2026


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

>From 027040218c7682a512c6011e2b87e1ff4757146d 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/6] [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 36001c3a9966315cb8aa449d8fad4883c5a62610 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/6] 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 f100978bc79ef8c89a55ce763f1d45af720e30c3 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/6] 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 4b31699c05a743a9feb2832857a44df18beed6d3 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/6] 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 b2ab1e9a4648c989fa9e2c315bb4505079bb7c32 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/6] 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 7c02dbd879699966eb871b13896d1cf18f80da2c 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/6] fixup! Move nxs bit into TLBIEntry rather than override

---
 .../Target/AArch64/AArch64SystemOperands.td   | 47 +++++++------------
 1 file changed, 17 insertions(+), 30 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td
index eb50391bb9692..807b5a0766cad 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,18 @@ 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;
+    def : TLBIPEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, 1, I.RegUse> {
       let Requires = ["AArch64::FeatureD128"];
     }
   }
@@ -1026,24 +1022,20 @@ 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;
+    def : TLBIPEntry<!strconcat(I.Name, "nXS"), I.Op1, I.CRn, I.CRm, I.Op2, 1, I.RegUse> {
       let Requires = ["AArch64::FeatureD128"];
     }
   }
@@ -1060,9 +1052,7 @@ 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;
-  }
+  def : TLBIEntry<I.Name, I.Op1, I.CRn, I.CRm, I.Op2, 0, I.RegUse>;
 }
 }
 
@@ -1076,12 +1066,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<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"];
   }
 }



More information about the llvm-branch-commits mailing list