[llvm] [SystemZ] Removes string from the addressing mode classes (PR #215643)

Yusra Syeda via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 11 11:59:32 PDT 2026


https://github.com/ysyeda created https://github.com/llvm/llvm-project/pull/215643

None

>From f7e5ecb1d51d6063acc7c3043279bdf1c20d0c8a Mon Sep 17 00:00:00 2001
From: Yusra Syeda <yusra.syeda at ibm.com>
Date: Tue, 11 Aug 2026 14:58:28 -0400
Subject: [PATCH] remove hardcoded bitsize in addressingmode

---
 .../SystemZ/AsmParser/SystemZAsmParser.cpp    |  96 ++++-----
 llvm/lib/Target/SystemZ/SystemZFeatures.td    |   7 +
 .../lib/Target/SystemZ/SystemZInstrFormats.td |   8 +-
 llvm/lib/Target/SystemZ/SystemZOperands.td    | 189 ++++++++++--------
 .../lib/Target/SystemZ/SystemZRegisterInfo.td |  16 ++
 llvm/lib/Target/SystemZ/SystemZSubtarget.cpp  |   1 +
 llvm/lib/Target/SystemZ/SystemZSubtarget.h    |   5 +
 llvm/test/MC/SystemZ/asm-match.s              |  16 +-
 8 files changed, 192 insertions(+), 146 deletions(-)

diff --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
index 44ebabe15415f..d0a42c1a4c2fc 100644
--- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
+++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
@@ -366,6 +366,7 @@ class SystemZOperand : public MCParsedAsmOperand {
   bool isGRX32() const { return false; }
   bool isGR64() const { return isReg(GR64Reg); }
   bool isGR128() const { return isReg(GR128Reg); }
+  bool isGR() const { return isGR64() || isGR32(); }
   bool isADDR32() const { return isReg(GR32Reg); }
   bool isADDR64() const { return isReg(GR64Reg); }
   bool isADDR128() const { return false; }
@@ -381,17 +382,15 @@ class SystemZOperand : public MCParsedAsmOperand {
   bool isAR32() const { return isReg(AR32Reg); }
   bool isCR64() const { return isReg(CR64Reg); }
   bool isAnyReg() const { return (isReg() || isImm(0, 15)); }
-  bool isBDAddr32Disp12() const { return isMemDisp12(BDMem, GR32Reg); }
-  bool isBDAddr32Disp20() const { return isMemDisp20(BDMem, GR32Reg); }
-  bool isBDAddr64Disp12() const { return isMemDisp12(BDMem, GR64Reg); }
-  bool isBDAddr64Disp20() const { return isMemDisp20(BDMem, GR64Reg); }
-  bool isBDXAddr64Disp12() const { return isMemDisp12(BDXMem, GR64Reg); }
-  bool isBDXAddr64Disp20() const { return isMemDisp20(BDXMem, GR64Reg); }
-  bool isBDLAddr64Disp12Len4() const { return isMemDisp12Len4(GR64Reg); }
-  bool isBDLAddr64Disp12Len8() const { return isMemDisp12Len8(GR64Reg); }
-  bool isBDRAddr64Disp12() const { return isMemDisp12(BDRMem, GR64Reg); }
-  bool isBDVAddr64Disp12() const { return isMemDisp12(BDVMem, GR64Reg); }
-  bool isLXAAddr64Disp20() const { return isMemDisp20(LXAMem, GR64Reg); }
+  bool isBDAddrDisp12() const { return isMemDisp12(BDMem, GR64Reg); }
+  bool isBDAddrDisp20() const { return isMemDisp20(BDMem, GR64Reg); }
+  bool isBDXAddrDisp12() const { return isMemDisp12(BDXMem, GR64Reg); }
+  bool isBDXAddrDisp20() const { return isMemDisp20(BDXMem, GR64Reg); }
+  bool isBDLAddrDisp12Len4() const { return isMemDisp12Len4(GR64Reg); }
+  bool isBDLAddrDisp12Len8() const { return isMemDisp12Len8(GR64Reg); }
+  bool isBDRAddrDisp12() const { return isMemDisp12(BDRMem, GR64Reg); }
+  bool isBDVAddrDisp12() const { return isMemDisp12(BDVMem, GR64Reg); }
+  bool isLXAAddrDisp20() const { return isMemDisp20(LXAMem, GR64Reg); }
   bool isU1Imm() const { return isImm(0, 1); }
   bool isU2Imm() const { return isImm(0, 3); }
   bool isU3Imm() const { return isImm(0, 7); }
@@ -544,6 +543,10 @@ class SystemZAsmParser : public MCTargetAsmParser {
   ParseStatus parseGR128(OperandVector &Operands) {
     return parseRegister(Operands, GR128Reg);
   }
+  ParseStatus parseGR(OperandVector &Operands) {
+    // TODO GR is hardware-mode-aware; update for AMODE32.
+    return parseRegister(Operands, GR64Reg);
+  }
   ParseStatus parseADDR32(OperandVector &Operands) {
     // For the AsmParser, we will accept %r0 for ADDR32 as well.
     return parseRegister(Operands, GR32Reg);
@@ -591,25 +594,22 @@ class SystemZAsmParser : public MCTargetAsmParser {
   ParseStatus parseAnyReg(OperandVector &Operands) {
     return parseAnyRegister(Operands);
   }
-  ParseStatus parseBDAddr32(OperandVector &Operands) {
-    return parseAddress(Operands, BDMem, GR32Reg);
-  }
-  ParseStatus parseBDAddr64(OperandVector &Operands) {
+  ParseStatus parseBDAddr(OperandVector &Operands) {
     return parseAddress(Operands, BDMem, GR64Reg);
   }
-  ParseStatus parseBDXAddr64(OperandVector &Operands) {
+  ParseStatus parseBDXAddr(OperandVector &Operands) {
     return parseAddress(Operands, BDXMem, GR64Reg);
   }
-  ParseStatus parseBDLAddr64(OperandVector &Operands) {
+  ParseStatus parseBDLAddr(OperandVector &Operands) {
     return parseAddress(Operands, BDLMem, GR64Reg);
   }
-  ParseStatus parseBDRAddr64(OperandVector &Operands) {
+  ParseStatus parseBDRAddr(OperandVector &Operands) {
     return parseAddress(Operands, BDRMem, GR64Reg);
   }
-  ParseStatus parseBDVAddr64(OperandVector &Operands) {
+  ParseStatus parseBDVAddr(OperandVector &Operands) {
     return parseAddress(Operands, BDVMem, GR64Reg);
   }
-  ParseStatus parseLXAAddr64(OperandVector &Operands) {
+  ParseStatus parseLXAAddr(OperandVector &Operands) {
     return parseAddress(Operands, LXAMem, GR64Reg);
   }
   ParseStatus parsePCRel12(OperandVector &Operands) {
@@ -676,7 +676,7 @@ static struct InsnMatchEntry InsnMatchTable[] = {
   { "rilu", SystemZ::InsnRILU, 3,
     { MCK_U48Imm, MCK_AnyReg, MCK_U32Imm } },
   { "ris", SystemZ::InsnRIS, 5,
-    { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddr64Disp12 } },
+    { MCK_U48Imm, MCK_AnyReg, MCK_S8Imm, MCK_U4Imm, MCK_BDAddrDisp12 } },
   { "rr", SystemZ::InsnRR, 3,
     { MCK_U16Imm, MCK_AnyReg, MCK_AnyReg } },
   { "rre", SystemZ::InsnRRE, 3,
@@ -684,50 +684,50 @@ static struct InsnMatchEntry InsnMatchTable[] = {
   { "rrf", SystemZ::InsnRRF, 5,
     { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm } },
   { "rrs", SystemZ::InsnRRS, 5,
-    { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddr64Disp12 } },
+    { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_U4Imm, MCK_BDAddrDisp12 } },
   { "rs", SystemZ::InsnRS, 4,
-    { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
+    { MCK_U32Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddrDisp12 } },
   { "rse", SystemZ::InsnRSE, 4,
-    { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp12 } },
+    { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddrDisp12 } },
   { "rsi", SystemZ::InsnRSI, 4,
     { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_PCRel16 } },
   { "rsy", SystemZ::InsnRSY, 4,
-    { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddr64Disp20 } },
+    { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDAddrDisp20 } },
   { "rx", SystemZ::InsnRX, 3,
-    { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
+    { MCK_U32Imm, MCK_AnyReg, MCK_BDXAddrDisp12 } },
   { "rxe", SystemZ::InsnRXE, 3,
-    { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
+    { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddrDisp12 } },
   { "rxf", SystemZ::InsnRXF, 4,
-    { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddr64Disp12 } },
+    { MCK_U48Imm, MCK_AnyReg, MCK_AnyReg, MCK_BDXAddrDisp12 } },
   { "rxy", SystemZ::InsnRXY, 3,
-    { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddr64Disp20 } },
+    { MCK_U48Imm, MCK_AnyReg, MCK_BDXAddrDisp20 } },
   { "s", SystemZ::InsnS, 2,
-    { MCK_U32Imm, MCK_BDAddr64Disp12 } },
+    { MCK_U32Imm, MCK_BDAddrDisp12 } },
   { "si", SystemZ::InsnSI, 3,
-    { MCK_U32Imm, MCK_BDAddr64Disp12, MCK_S8Imm } },
+    { MCK_U32Imm, MCK_BDAddrDisp12, MCK_S8Imm } },
   { "sil", SystemZ::InsnSIL, 3,
-    { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_U16Imm } },
+    { MCK_U48Imm, MCK_BDAddrDisp12, MCK_U16Imm } },
   { "siy", SystemZ::InsnSIY, 3,
-    { MCK_U48Imm, MCK_BDAddr64Disp20, MCK_U8Imm } },
+    { MCK_U48Imm, MCK_BDAddrDisp20, MCK_U8Imm } },
   { "ss", SystemZ::InsnSS, 4,
-    { MCK_U48Imm, MCK_BDXAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
+    { MCK_U48Imm, MCK_BDXAddrDisp12, MCK_BDAddrDisp12, MCK_AnyReg } },
   { "sse", SystemZ::InsnSSE, 3,
-    { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12 } },
+    { MCK_U48Imm, MCK_BDAddrDisp12, MCK_BDAddrDisp12 } },
   { "ssf", SystemZ::InsnSSF, 4,
-    { MCK_U48Imm, MCK_BDAddr64Disp12, MCK_BDAddr64Disp12, MCK_AnyReg } },
+    { MCK_U48Imm, MCK_BDAddrDisp12, MCK_BDAddrDisp12, MCK_AnyReg } },
   { "vri", SystemZ::InsnVRI, 6,
     { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_U12Imm, MCK_U4Imm, MCK_U4Imm } },
   { "vrr", SystemZ::InsnVRR, 7,
     { MCK_U48Imm, MCK_VR128, MCK_VR128, MCK_VR128, MCK_U4Imm, MCK_U4Imm,
       MCK_U4Imm } },
   { "vrs", SystemZ::InsnVRS, 5,
-    { MCK_U48Imm, MCK_AnyReg, MCK_VR128, MCK_BDAddr64Disp12, MCK_U4Imm } },
+    { MCK_U48Imm, MCK_AnyReg, MCK_VR128, MCK_BDAddrDisp12, MCK_U4Imm } },
   { "vrv", SystemZ::InsnVRV, 4,
-    { MCK_U48Imm, MCK_VR128, MCK_BDVAddr64Disp12, MCK_U4Imm } },
+    { MCK_U48Imm, MCK_VR128, MCK_BDVAddrDisp12, MCK_U4Imm } },
   { "vrx", SystemZ::InsnVRX, 4,
-    { MCK_U48Imm, MCK_VR128, MCK_BDXAddr64Disp12, MCK_U4Imm } },
+    { MCK_U48Imm, MCK_VR128, MCK_BDXAddrDisp12, MCK_U4Imm } },
   { "vsi", SystemZ::InsnVSI, 4,
-    { MCK_U48Imm, MCK_VR128, MCK_BDAddr64Disp12, MCK_U8Imm } }
+    { MCK_U48Imm, MCK_VR128, MCK_BDAddrDisp12, MCK_U8Imm } }
 };
 
 void SystemZOperand::print(raw_ostream &OS, const MCAsmInfo &MAI) const {
@@ -1300,14 +1300,14 @@ bool SystemZAsmParser::parseDirectiveInsn(SMLoc L) {
       ResTy = parseAnyReg(Operands);
     else if (Kind == MCK_VR128)
       ResTy = parseVR128(Operands);
-    else if (Kind == MCK_BDXAddr64Disp12 || Kind == MCK_BDXAddr64Disp20)
-      ResTy = parseBDXAddr64(Operands);
-    else if (Kind == MCK_BDAddr64Disp12 || Kind == MCK_BDAddr64Disp20)
-      ResTy = parseBDAddr64(Operands);
-    else if (Kind == MCK_BDVAddr64Disp12)
-      ResTy = parseBDVAddr64(Operands);
-    else if (Kind == MCK_LXAAddr64Disp20)
-      ResTy = parseLXAAddr64(Operands);
+    else if (Kind == MCK_BDXAddrDisp12 || Kind == MCK_BDXAddrDisp20)
+      ResTy = parseBDXAddr(Operands);
+    else if (Kind == MCK_BDAddrDisp12 || Kind == MCK_BDAddrDisp20)
+      ResTy = parseBDAddr(Operands);
+    else if (Kind == MCK_BDVAddrDisp12)
+      ResTy = parseBDVAddr(Operands);
+    else if (Kind == MCK_LXAAddrDisp20)
+      ResTy = parseLXAAddr(Operands);
     else if (Kind == MCK_PCRel32)
       ResTy = parsePCRel32(Operands);
     else if (Kind == MCK_PCRel16)
diff --git a/llvm/lib/Target/SystemZ/SystemZFeatures.td b/llvm/lib/Target/SystemZ/SystemZFeatures.td
index 4ccc3d3079fc2..041178c696816 100644
--- a/llvm/lib/Target/SystemZ/SystemZFeatures.td
+++ b/llvm/lib/Target/SystemZ/SystemZFeatures.td
@@ -198,6 +198,13 @@ def FeatureNoVector : SystemZMissingFeature<"Vector">;
 
 def NoVecHwMode : HwMode<[FeatureNoVector]>;
 
+
+// Define Amode32. Default mode is Amode64.
+def IsAmode64 : Predicate<"Subtarget->is64Bit()">;
+def IsAmode32 : Predicate<"Subtarget->is32Bit()">;
+defvar Amode64 = DefaultMode;
+def Amode32 : HwMode<[IsAmode32, FeatureVector]>;
+
 def Arch11NewFeatures : SystemZFeatureList<[
     FeatureLoadAndZeroRightmostByte,
     FeatureLoadStoreOnCond2,
diff --git a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
index 82415f412509f..870b5331d8490 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
+++ b/llvm/lib/Target/SystemZ/SystemZInstrFormats.td
@@ -3032,15 +3032,15 @@ class SideEffectAddressS<string mnemonic, bits<16> opcode,
 
 class LoadAddressRX<string mnemonic, bits<8> opcode,
                     SDPatternOperator operator, AddressingMode mode>
-  : InstRXa<opcode, (outs GR64:$R1), (ins (mode $B2, $D2, $X2):$XBD2),
+  : InstRXa<opcode, (outs GR:$R1), (ins (mode $B2, $D2, $X2):$XBD2),
             mnemonic#"\t$R1, $XBD2",
-            [(set GR64:$R1, (operator mode:$XBD2))]>;
+            [(set GR:$R1, (operator mode:$XBD2))]>;
 
 class LoadAddressRXY<string mnemonic, bits<16> opcode,
                      SDPatternOperator operator, AddressingMode mode>
-  : InstRXYa<opcode, (outs GR64:$R1), (ins (mode $B2, $D2, $X2):$XBD2),
+  : InstRXYa<opcode, (outs GR:$R1), (ins (mode $B2, $D2, $X2):$XBD2),
              mnemonic#"\t$R1, $XBD2",
-             [(set GR64:$R1, (operator mode:$XBD2))]>;
+             [(set GR:$R1, (operator mode:$XBD2))]>;
 
 multiclass LoadAddressRXPair<string mnemonic, bits<8> rxOpcode,
                              bits<16> rxyOpcode, SDPatternOperator operator> {
diff --git a/llvm/lib/Target/SystemZ/SystemZOperands.td b/llvm/lib/Target/SystemZ/SystemZOperands.td
index 8a2049c518473..22f8ac4a3dec0 100644
--- a/llvm/lib/Target/SystemZ/SystemZOperands.td
+++ b/llvm/lib/Target/SystemZ/SystemZOperands.td
@@ -6,6 +6,13 @@
 //
 //===----------------------------------------------------------------------===//
 
+//===----------------------------------------------------------------------===//
+// HwMode-dependent immediates
+//===----------------------------------------------------------------------===//
+
+def XLenVT : ValueTypeByHwMode<[Amode64, Amode32],
+                               [i64,     i32]>;
+
 //===----------------------------------------------------------------------===//
 // Class definitions
 //===----------------------------------------------------------------------===//
@@ -82,33 +89,18 @@ class PCRelAddress<ValueType vt, string self, AsmOperandClass asmop>
 }
 
 // Constructs an AsmOperandClass for addressing mode FORMAT, treating the
-// registers as having BITSIZE bits and displacements as having DISPSIZE bits.
+// displacements as having DISPSIZE bits.
 // LENGTH is "LenN" for addresses with an N-bit length field, otherwise it
 // is "".
-class AddressAsmOperand<string format, string bitsize, string dispsize,
-                        string length = "">
+class AddressAsmOperand<string format, string dispsize, string length = "">
   : AsmOperandClass {
-  let Name = format#bitsize#"Disp"#dispsize#length;
-  let ParserMethod = "parse"#format#bitsize;
+  let Name = format#"Disp"#dispsize#length;
+  let ParserMethod = "parse"#format;
   let RenderMethod = "add"#format#"Operands";
 }
 
-// Constructs an instruction operand for an addressing mode.  FORMAT,
-// BITSIZE, DISPSIZE and LENGTH are the parameters to an associated
-// AddressAsmOperand.  OPERANDS is a list of individual operands
-// (base register, displacement, etc.).
-class AddressOperand<string bitsize, string dispsize, string length,
-                     string format, dag operands>
-  : Operand<!cast<ValueType>("i"#bitsize)> {
-  let PrintMethod = "print"#format#"Operand";
-  let OperandType = "OPERAND_MEMORY";
-  let MIOperandInfo = operands;
-  let ParserMatchClass =
-    !cast<AddressAsmOperand>(format#bitsize#"Disp"#dispsize#length);
-}
-
 // Constructs both a DAG pattern and instruction operand for an addressing mode.
-// FORMAT, BITSIZE, DISPSIZE and LENGTH are the parameters to an associated
+// FORMAT, DISPSIZE and LENGTH are the parameters to an associated
 // AddressAsmOperand.  OPERANDS is a list of NUMOPS individual operands
 // (base register, displacement, etc.).  SELTYPE is the type of the memory
 // operand for selection purposes; sometimes we want different selection
@@ -116,56 +108,65 @@ class AddressOperand<string bitsize, string dispsize, string length,
 // a suffix appended to the displacement for selection purposes;
 // e.g. we want to reject small 20-bit displacements if a 12-bit form
 // also exists, but we want to accept them otherwise.
-class AddressingMode<string seltype, string bitsize, string dispsize,
+// VT overrides the ComplexPattern value type (default XLenVT; use i32 for shift addressing modes).
+class AddressingMode<string seltype, string dispsize,
                      string suffix, string length, int numops, string format,
-                     dag operands>
-  : ComplexPattern<!cast<ValueType>("i"#bitsize), numops,
+                     dag operands, ValueType vt = XLenVT>
+  : ComplexPattern<vt, numops,
                    "select"#seltype#dispsize#suffix#length,
                    [add, sub, or, frameindex, z_adjdynalloc]>,
-    AddressOperand<bitsize, dispsize, length, format, operands>;
+    Operand<vt> {
+  let PrintMethod = "print"#format#"Operand";
+  let OperandType = "OPERAND_MEMORY";
+  let MIOperandInfo = operands;
+  let ParserMatchClass =
+    !cast<AddressAsmOperand>(format#"Disp"#dispsize#length);
+}
+
+class BDModeI32<string type, string dispsize, string suffix>
+  : AddressingMode<type, dispsize, suffix, "", 2, "BDAddr",
+                   (ops ADDR32, !cast<Operand>("disp"#dispsize#"imm32")), i32>;
 
 // An addressing mode with a base and displacement but no index.
-class BDMode<string type, string bitsize, string dispsize, string suffix>
-  : AddressingMode<type, bitsize, dispsize, suffix, "", 2, "BDAddr",
-                   (ops !cast<RegisterOperand>("ADDR"#bitsize),
-                        !cast<Operand>("disp"#dispsize#"imm"#bitsize))>;
+class BDMode<string type, string dispsize, string suffix>
+  : AddressingMode<type, dispsize, suffix, "", 2, "BDAddr",
+                   (ops ADDRbit,
+                        !cast<Operand>("disp"#dispsize#"immXLen"))>;
 
 // An addressing mode with a base, displacement and index.
-class BDXMode<string type, string bitsize, string dispsize, string suffix>
-  : AddressingMode<type, bitsize, dispsize, suffix, "", 3, "BDXAddr",
-                   (ops !cast<RegisterOperand>("ADDR"#bitsize),
-                        !cast<Operand>("disp"#dispsize#"imm"#bitsize),
-                        !cast<RegisterOperand>("ADDR"#bitsize))>;
+class BDXMode<string type, string dispsize, string suffix>
+  : AddressingMode<type, dispsize, suffix, "", 3, "BDXAddr",
+                   (ops ADDRbit,
+                        !cast<Operand>("disp"#dispsize#"immXLen"),
+                        ADDRbit)>;
 
 // A BDMode paired with an immediate length operand of LENSIZE bits.
-class BDLMode<string type, string bitsize, string dispsize, string suffix,
-              string lensize>
-  : AddressingMode<type, bitsize, dispsize, suffix, "Len"#lensize, 3,
-                   "BDLAddr",
-                   (ops !cast<RegisterOperand>("ADDR"#bitsize),
-                        !cast<Operand>("disp"#dispsize#"imm"#bitsize),
-                        !cast<Operand>("len"#lensize#"imm"#bitsize))>;
+class BDLMode<string type, string dispsize, string suffix, string lensize>
+  : AddressingMode<type, dispsize, suffix, "Len"#lensize, 3, "BDLAddr",
+                   (ops ADDRbit,
+                        !cast<Operand>("disp"#dispsize#"immXLen"),
+                        !cast<Operand>("len"#lensize#"immXLen"))>;
 
 // A BDMode paired with a register length operand.
-class BDRMode<string type, string bitsize, string dispsize, string suffix>
-  : AddressingMode<type, bitsize, dispsize, suffix, "", 3, "BDRAddr",
-                   (ops !cast<RegisterOperand>("ADDR"#bitsize),
-                        !cast<Operand>("disp"#dispsize#"imm"#bitsize),
-                        !cast<RegisterOperand>("GR"#bitsize))>;
+class BDRMode<string type, string dispsize, string suffix>
+  : AddressingMode<type, dispsize, suffix, "", 3, "BDRAddr",
+                   (ops ADDRbit,
+                        !cast<Operand>("disp"#dispsize#"immXLen"),
+                        GR)>;
 
 // An addressing mode with a base, displacement and a vector index.
-class BDVMode<string bitsize, string dispsize>
-  : AddressOperand<bitsize, dispsize, "", "BDVAddr",
-                   (ops !cast<RegisterOperand>("ADDR"#bitsize),
-                        !cast<Operand>("disp"#dispsize#"imm"#bitsize),
-                        !cast<RegisterOperand>("VR128"))>;
+class BDVMode<string dispsize>
+  : AddressingMode<"BDVAddr", dispsize, "", "", 3, "BDVAddr",
+                   (ops ADDRbit,
+                        !cast<Operand>("disp"#dispsize#"immXLen"),
+                        VR128)>;
 
 // An addressing mode with a base, 32-bit displacement and 32-bit index.
-class LXAMode<string bitsize, string dispsize>
-  : AddressOperand<bitsize, dispsize, "", "LXAAddr",
-                   (ops !cast<RegisterOperand>("ADDR"#bitsize),
+class LXAMode<string dispsize>
+  : AddressingMode<"LXAAddr", dispsize, "", "", 3, "LXAAddr",
+                   (ops ADDRbit,
                         !cast<Operand>("disp"#dispsize#"imm32"),
-                        !cast<RegisterOperand>("ADDR32"))>;
+                        ADDR32)>;
 
 //===----------------------------------------------------------------------===//
 // Extracting immediate operands from nodes
@@ -564,6 +565,22 @@ def len8imm64 : Imm64 {
   let DecoderMethod = "decodeLenOperand<8>";
 }
 
+//===----------------------------------------------------------------------===//
+// HwMode-dependent immediates
+//===----------------------------------------------------------------------===//
+
+// Hardware-aware length immediates
+def len4immXLen : ImmLeaf<XLenVT, [{}]>, Operand<XLenVT> {
+  let EncoderMethod = "getLenEncoding<SystemZ::FK_390_U4Imm>";
+  let DecoderMethod = "decodeLenOperand<4>";
+  let OperandType = "OPERAND_IMMEDIATE";
+}
+def len8immXLen : ImmLeaf<XLenVT, [{}]>, Operand<XLenVT> {
+  let EncoderMethod = "getLenEncoding<SystemZ::FK_390_U8Imm>";
+  let DecoderMethod = "decodeLenOperand<8>";
+  let OperandType = "OPERAND_IMMEDIATE";
+}
+
 //===----------------------------------------------------------------------===//
 // Floating-point immediates
 //===----------------------------------------------------------------------===//
@@ -643,6 +660,7 @@ let EncoderMethod = "getImmOpValue<SystemZ::FK_390_U12Imm>",
     DecoderMethod = "decodeU12ImmOperand" in {
   def disp12imm32 : DispOp<i32, [{ return Imm.isIntN(12); }]>;
   def disp12imm64 : DispOp<i64, [{ return Imm.isIntN(12); }]>;
+  def disp12immXLen : DispOp<XLenVT, [{ return Imm.isIntN(12); }]>;
 }
 
 // 20-bit displacement operands.
@@ -650,19 +668,18 @@ let EncoderMethod = "getImmOpValue<SystemZ::FK_390_S20Imm>",
     DecoderMethod = "decodeS20ImmOperand" in {
   def disp20imm32 : DispOp<i32, [{ return Imm.isSignedIntN(20); }]>;
   def disp20imm64 : DispOp<i64, [{ return Imm.isSignedIntN(20); }]>;
+  def disp20immXLen : DispOp<XLenVT, [{ return Imm.isSignedIntN(20); }]>;
 }
 
-def BDAddr32Disp12      : AddressAsmOperand<"BDAddr",   "32", "12">;
-def BDAddr32Disp20      : AddressAsmOperand<"BDAddr",   "32", "20">;
-def BDAddr64Disp12      : AddressAsmOperand<"BDAddr",   "64", "12">;
-def BDAddr64Disp20      : AddressAsmOperand<"BDAddr",   "64", "20">;
-def BDXAddr64Disp12     : AddressAsmOperand<"BDXAddr",  "64", "12">;
-def BDXAddr64Disp20     : AddressAsmOperand<"BDXAddr",  "64", "20">;
-def BDLAddr64Disp12Len4 : AddressAsmOperand<"BDLAddr",  "64", "12", "Len4">;
-def BDLAddr64Disp12Len8 : AddressAsmOperand<"BDLAddr",  "64", "12", "Len8">;
-def BDRAddr64Disp12     : AddressAsmOperand<"BDRAddr",  "64", "12">;
-def BDVAddr64Disp12     : AddressAsmOperand<"BDVAddr",  "64", "12">;
-def LXAAddr64Disp20     : AddressAsmOperand<"LXAAddr",  "64", "20">;
+def BDAddrDisp12 : AddressAsmOperand<"BDAddr", "12">;
+def BDAddrDisp20 : AddressAsmOperand<"BDAddr", "20">;
+def BDXAddrDisp12 : AddressAsmOperand<"BDXAddr", "12">;
+def BDXAddrDisp20 : AddressAsmOperand<"BDXAddr", "20">;
+def BDLAddrDisp12Len4 : AddressAsmOperand<"BDLAddr", "12", "Len4">;
+def BDLAddrDisp12Len8 : AddressAsmOperand<"BDLAddr", "12", "Len8">;
+def BDRAddrDisp12 : AddressAsmOperand<"BDRAddr", "12">;
+def BDVAddrDisp12 : AddressAsmOperand<"BDVAddr", "12">;
+def LXAAddrDisp20 : AddressAsmOperand<"LXAAddr", "20">;
 
 // DAG patterns and operands for addressing modes.  Each mode has
 // the form <type><range><group>[<len>] where:
@@ -692,27 +709,27 @@ def LXAAddr64Disp20     : AddressAsmOperand<"LXAAddr",  "64", "20">;
 //
 //   <empty>  : there is no length field
 //   len8     : the length field is 8 bits, with a range of [1, 0x100].
-def shift12only       : BDMode <"BDAddr",   "32", "12", "Only">;
-def shift20only       : BDMode <"BDAddr",   "32", "20", "Only">;
-def bdaddr12only      : BDMode <"BDAddr",   "64", "12", "Only">;
-def bdaddr12pair      : BDMode <"BDAddr",   "64", "12", "Pair">;
-def bdaddr20only      : BDMode <"BDAddr",   "64", "20", "Only">;
-def bdaddr20pair      : BDMode <"BDAddr",   "64", "20", "Pair">;
-def mviaddr12pair     : BDMode <"MVIAddr",  "64", "12", "Pair">;
-def mviaddr20pair     : BDMode <"MVIAddr",  "64", "20", "Pair">;
-def bdxaddr12only     : BDXMode<"BDXAddr",  "64", "12", "Only">;
-def bdxaddr12pair     : BDXMode<"BDXAddr",  "64", "12", "Pair">;
-def bdxaddr20only     : BDXMode<"BDXAddr",  "64", "20", "Only">;
-def bdxaddr20only128  : BDXMode<"BDXAddr",  "64", "20", "Only128">;
-def bdxaddr20pair     : BDXMode<"BDXAddr",  "64", "20", "Pair">;
-def dynalloc12only    : BDXMode<"DynAlloc", "64", "12", "Only">;
-def laaddr12pair      : BDXMode<"LAAddr",   "64", "12", "Pair">;
-def laaddr20pair      : BDXMode<"LAAddr",   "64", "20", "Pair">;
-def lxaaddr20only     : LXAMode<            "64", "20">;
-def bdladdr12onlylen4 : BDLMode<"BDLAddr",  "64", "12", "Only", "4">;
-def bdladdr12onlylen8 : BDLMode<"BDLAddr",  "64", "12", "Only", "8">;
-def bdraddr12only     : BDRMode<"BDRAddr",  "64", "12", "Only">;
-def bdvaddr12only     : BDVMode<            "64", "12">;
+def shift12only       : BDModeI32<"BDAddr", "12", "Only">;
+def shift20only       : BDModeI32<"BDAddr", "20", "Only">;
+def lxaaddr20only     : LXAMode<"20">;
+def bdladdr12onlylen4 : BDLMode<"BDLAddr", "12", "Only", "4">;
+def bdladdr12onlylen8 : BDLMode<"BDLAddr", "12", "Only", "8">;
+def bdraddr12only     : BDRMode<"BDRAddr", "12", "Only">;
+def bdvaddr12only     : BDVMode<"12">;
+def bdaddr12only      : BDMode<"BDAddr", "12", "Only">;
+def bdaddr12pair      : BDMode<"BDAddr", "12", "Pair">;
+def bdaddr20only      : BDMode<"BDAddr", "20", "Only">;
+def bdaddr20pair      : BDMode<"BDAddr", "20", "Pair">;
+def mviaddr12pair     : BDMode<"MVIAddr", "12", "Pair">;
+def mviaddr20pair     : BDMode<"MVIAddr", "20", "Pair">;
+def bdxaddr12only     : BDXMode<"BDXAddr", "12", "Only">;
+def bdxaddr12pair     : BDXMode<"BDXAddr", "12", "Pair">;
+def bdxaddr20only     : BDXMode<"BDXAddr", "20", "Only">;
+def bdxaddr20only128  : BDXMode<"BDXAddr", "20", "Only128">;
+def bdxaddr20pair     : BDXMode<"BDXAddr", "20", "Pair">;
+def dynalloc12only    : BDXMode<"DynAlloc", "12", "Only">;
+def laaddr12pair      : BDXMode<"LAAddr", "12", "Pair">;
+def laaddr20pair      : BDXMode<"LAAddr", "20", "Pair">;
 
 // 12-bit unsigned displacement variants (for NI, OI, XI)
 def bdaddr12off1 : ComplexPattern<i64, 2, "selectBDAddr12off1">;
diff --git a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.td b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.td
index 1ef8e81c8f829..8ca708b706705 100644
--- a/llvm/lib/Target/SystemZ/SystemZRegisterInfo.td
+++ b/llvm/lib/Target/SystemZ/SystemZRegisterInfo.td
@@ -374,3 +374,19 @@ foreach I = 0-15 in {
 }
 defm CR64 : SystemZRegClass<"CR64", [i64], 64,
                             (add (sequence "C%u", 0, 15)), [], 0>;
+
+// Register classes based on HwMode.
+def ADDRbit : RegClassByHwMode<[Amode64,   Amode32,   NoVecHwMode],
+                             [ADDR64Bit, ADDR32Bit, ADDR64Bit]>;
+
+def GRbit : RegClassByHwMode<[Amode64, Amode32, NoVecHwMode],
+                          [GR64Bit, GR32Bit, GR64Bit]>;
+
+def GRAsmOperand : AsmOperandClass {
+  let Name = "GR";
+  let ParserMethod = "parseGR";
+  let RenderMethod = "addRegOperands";
+}
+def GR : RegisterOperand<GRbit> {
+  let ParserMatchClass = GRAsmOperand;
+}
diff --git a/llvm/lib/Target/SystemZ/SystemZSubtarget.cpp b/llvm/lib/Target/SystemZ/SystemZSubtarget.cpp
index 942ef88385620..eaa84968f44b6 100644
--- a/llvm/lib/Target/SystemZ/SystemZSubtarget.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZSubtarget.cpp
@@ -69,6 +69,7 @@ SystemZSubtarget::SystemZSubtarget(const Triple &TT, const std::string &CPU,
                                    const std::string &FS,
                                    const TargetMachine &TM)
     : SystemZGenSubtargetInfo(TT, CPU, TuneCPU, FS), TargetTriple(TT),
+      In64BitMode(TargetTriple.isArch64Bit()),
       SpecialRegisters(initializeSpecialRegisters()),
       InstrInfo(initializeSubtargetDependencies(CPU, TuneCPU, FS)),
       TLInfo(TM, *this), FrameLowering(SystemZFrameLowering::create(*this)) {}
diff --git a/llvm/lib/Target/SystemZ/SystemZSubtarget.h b/llvm/lib/Target/SystemZ/SystemZSubtarget.h
index 761bc525b59d3..d0a9618d17fd7 100644
--- a/llvm/lib/Target/SystemZ/SystemZSubtarget.h
+++ b/llvm/lib/Target/SystemZ/SystemZSubtarget.h
@@ -40,6 +40,7 @@ class SystemZSubtarget : public SystemZGenSubtargetInfo {
 
 private:
   Triple TargetTriple;
+  bool In64BitMode;
   std::unique_ptr<SystemZCallingConventionRegisters> SpecialRegisters;
   SystemZInstrInfo InstrInfo;
   SystemZTargetLowering TLInfo;
@@ -114,6 +115,10 @@ class SystemZSubtarget : public SystemZGenSubtargetInfo {
   // and code model CM.
   bool isPC32DBLSymbol(const GlobalValue *GV, CodeModel::Model CM) const;
 
+  bool is64Bit() const { return In64BitMode; }
+
+  bool is32Bit() const { return !In64BitMode; }
+
   bool isTargetELF() const { return TargetTriple.isOSBinFormatELF(); }
 
   // Returns TRUE if we are generating GOFF object code
diff --git a/llvm/test/MC/SystemZ/asm-match.s b/llvm/test/MC/SystemZ/asm-match.s
index 286adbe202189..b8895a418cca9 100644
--- a/llvm/test/MC/SystemZ/asm-match.s
+++ b/llvm/test/MC/SystemZ/asm-match.s
@@ -7,7 +7,7 @@
 // CHECK: Trying to match opcode SLLG
 // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r3): match success using generic matcher
 // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 2 (Reg:r0): match success using generic matcher
-// CHECK: Matching formal operand class MCK_BDAddr32Disp20 against actual operand at index 3 (Mem:3): match success using generic matcher
+// CHECK: Matching formal operand class MCK_BDAddrDisp20 against actual operand at index 3 (Mem:3): match success using generic matcher
 // CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range
 // CHECK: Opcode result: complete match, selecting this opcode
 // CHECK: AsmMatcher: found 1 encodings with mnemonic 'llill'
@@ -25,32 +25,32 @@
 // CHECK: AsmMatcher: found 1 encodings with mnemonic 'lg'
 // CHECK: Trying to match opcode LG
 // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r1): match success using generic matcher
-// CHECK: Matching formal operand class MCK_BDXAddr64Disp20 against actual operand at index 2 (Mem:16(r2)): match success using generic matcher
+// CHECK: Matching formal operand class MCK_BDXAddrDisp20 against actual operand at index 2 (Mem:16(r2)): match success using generic matcher
 // CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range
 // CHECK: Opcode result: complete match, selecting this opcode
 // CHECK: AsmMatcher: found 1 encodings with mnemonic 'lg'
 // CHECK: Trying to match opcode LG
 // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r1): match success using generic matcher
-// CHECK: Matching formal operand class MCK_BDXAddr64Disp20 against actual operand at index 2 (Mem:16(r2,r3)): match success using generic matcher
+// CHECK: Matching formal operand class MCK_BDXAddrDisp20 against actual operand at index 2 (Mem:16(r2,r3)): match success using generic matcher
 // CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range
 // CHECK: Opcode result: complete match, selecting this opcode
 // CHECK: AsmMatcher: found 1 encodings with mnemonic 'stmg'
 // CHECK: Trying to match opcode STMG
 // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 1 (Reg:r13): match success using generic matcher
 // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 2 (Reg:r15): match success using generic matcher
-// CHECK: Matching formal operand class MCK_BDAddr64Disp20 against actual operand at index 3 (Mem:104(r15)): match success using generic matcher
+// CHECK: Matching formal operand class MCK_BDAddrDisp20 against actual operand at index 3 (Mem:104(r15)): match success using generic matcher
 // CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range
 // CHECK: Opcode result: complete match, selecting this opcode
 // CHECK: AsmMatcher: found 1 encodings with mnemonic 'mvc'
 // CHECK: Trying to match opcode MVC
-// CHECK: Matching formal operand class MCK_BDLAddr64Disp12Len8 against actual operand at index 1 (Mem:184(8,r15)): match success using generic matcher
-// CHECK: Matching formal operand class MCK_BDAddr64Disp12 against actual operand at index 2 (Mem:8(r2)): match success using generic matcher
+// CHECK: Matching formal operand class MCK_BDLAddrDisp12Len8 against actual operand at index 1 (Mem:184(8,r15)): match success using generic matcher
+// CHECK: Matching formal operand class MCK_BDAddrDisp12 against actual operand at index 2 (Mem:8(r2)): match success using generic matcher
 // CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 3: actual operand index out of range
 // CHECK: Opcode result: complete match, selecting this opcode
 // CHECK: AsmMatcher: found 1 encodings with mnemonic 'mvck'
 // CHECK: Trying to match opcode MVCK
-// CHECK: Matching formal operand class MCK_BDRAddr64Disp12 against actual operand at index 1 (Mem:0(r0,r1)): match success using generic matcher
-// CHECK: Matching formal operand class MCK_BDAddr64Disp12 against actual operand at index 2 (Mem:4095(r15)): match success using generic matcher
+// CHECK: Matching formal operand class MCK_BDRAddrDisp12 against actual operand at index 1 (Mem:0(r0,r1)): match success using generic matcher
+// CHECK: Matching formal operand class MCK_BDAddrDisp12 against actual operand at index 2 (Mem:4095(r15)): match success using generic matcher
 // CHECK: Matching formal operand class MCK_GR64 against actual operand at index 3 (Reg:r2): match success using generic matcher
 // CHECK: Matching formal operand class InvalidMatchClass against actual operand at index 4: actual operand index out of range
 // CHECK: Opcode result: complete match, selecting this opcode



More information about the llvm-commits mailing list