[llvm-branch-commits] [llvm] [PowerPC] Refactor immediate operand part 2 (PR #180289)
Lei Huang via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Feb 19 10:20:06 PST 2026
https://github.com/lei137 updated https://github.com/llvm/llvm-project/pull/180289
>From 45513ddf1a56250204e21a85702c3a381ce2ff13 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Fri, 30 Jan 2026 14:57:23 -0500
Subject: [PATCH 01/19] Aligned PowerPC Immediate Operand Definitions with
SystemZ Pattern
---
llvm/lib/Target/PowerPC/PPCOperands.td | 181 +++++++++++++++
llvm/lib/Target/PowerPC/PPCRegisterInfo.td | 246 +--------------------
2 files changed, 183 insertions(+), 244 deletions(-)
create mode 100644 llvm/lib/Target/PowerPC/PPCOperands.td
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
new file mode 100644
index 0000000000000..f034d3ed94d4b
--- /dev/null
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -0,0 +1,181 @@
+//===-- PPCOperands.td - PowerPC instruction operands ------*- tablegen -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines PowerPC instruction operands, including immediate operands
+// and addressing modes.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Immediate operand base classes
+//===----------------------------------------------------------------------===//
+
+// Base class for immediate AsmOperandClass definitions
+class ImmediateAsmOperand : AsmOperandClass {
+ let Name = NAME;
+ let RenderMethod = "addImmOperands";
+}
+
+// Base class for immediate AsmOperandClass with custom predicate
+class ImmediateAsmOperandWithPredicate<string predicate> : ImmediateAsmOperand {
+ let PredicateMethod = predicate;
+}
+
+// Base class for unsigned immediate AsmOperandClass with templated predicate
+class UnsignedImmAsmOperand<int width> : ImmediateAsmOperand {
+ let PredicateMethod = "isUImm<" # width # ">";
+}
+
+// Base class for signed immediate AsmOperandClass with templated predicate
+class SignedImmAsmOperand<int width> : ImmediateAsmOperand {
+ let PredicateMethod = "isSImm<" # width # ">";
+}
+
+// Base class for immediate operands
+class ImmediateOp<ValueType vt, string asmop, string decoder> : Operand<vt> {
+ let PrintMethod = "print"#asmop#"Operand";
+ let ParserMatchClass = !cast<AsmOperandClass>(asmop);
+ let DecoderMethod = decoder;
+ let OperandType = "OPERAND_IMMEDIATE";
+}
+
+// Unsigned immediate operand
+class UnsignedImmOp<ValueType vt, string asmop, int width>
+ : ImmediateOp<vt, asmop, "decodeUImmOperand<"#width#">">;
+
+// Unsigned immediate operand with encoder
+class UnsignedImmOpWithEncoder<ValueType vt, string asmop, int width, string fixup>
+ : UnsignedImmOp<vt, asmop, width> {
+ let EncoderMethod = "getImmEncoding<" # fixup # ">";
+}
+
+// Signed immediate operand
+class SignedImmOp<ValueType vt, string asmop, int width>
+ : ImmediateOp<vt, asmop, "decodeSImmOperand<"#width#">">;
+
+// Signed immediate operand with encoder
+class SignedImmOpWithEncoder<ValueType vt, string asmop, int width, string fixup>
+ : SignedImmOp<vt, asmop, width> {
+ let EncoderMethod = "getImmEncoding<" # fixup # ">";
+}
+
+// Multiclass for unsigned immediate operands with both regular and PC-relative versions
+multiclass UnsignedImmOpWithPCRel<ValueType vt, string asmop, int width,
+ string fixup_imm, string fixup_pcrel> {
+ def "" : UnsignedImmOpWithEncoder<vt, asmop, width, fixup_imm>;
+ def _pcrel : UnsignedImmOpWithEncoder<vt, asmop, width, fixup_pcrel>;
+}
+
+// Multiclass for signed immediate operands with both regular and PC-relative versions
+multiclass SignedImmOpWithPCRel<ValueType vt, string asmop, int width,
+ string fixup_imm, string fixup_pcrel> {
+ def "" : SignedImmOpWithEncoder<vt, asmop, width, fixup_imm>;
+ def _pcrel : SignedImmOpWithEncoder<vt, asmop, width, fixup_pcrel>;
+}
+
+//===----------------------------------------------------------------------===//
+// Immediate AsmOperand definitions
+//===----------------------------------------------------------------------===//
+
+def U1Imm : UnsignedImmAsmOperand<1>;
+def U2Imm : UnsignedImmAsmOperand<2>;
+def U3Imm : UnsignedImmAsmOperand<3>;
+def U4Imm : UnsignedImmAsmOperand<4>;
+def U5Imm : UnsignedImmAsmOperand<5>;
+def U6Imm : UnsignedImmAsmOperand<6>;
+def U7Imm : UnsignedImmAsmOperand<7>;
+def U8Imm : UnsignedImmAsmOperand<8>;
+def U10Imm : UnsignedImmAsmOperand<10>;
+def U12Imm : UnsignedImmAsmOperand<12>;
+
+def S5Imm : SignedImmAsmOperand<5>;
+
+// Special case: S32Imm and S34Imm have custom predicates that accept expressions
+def S32Imm : ImmediateAsmOperandWithPredicate<"isS32Imm">;
+def S34Imm : ImmediateAsmOperandWithPredicate<"isS34Imm">;
+
+// Special case: S16Imm has custom render method
+def S16Imm : ImmediateAsmOperandWithPredicate<"isS16Imm"> {
+ let RenderMethod = "addS16ImmOperands";
+}
+
+// Special case: U16Imm has custom render method
+def U16Imm : ImmediateAsmOperandWithPredicate<"isU16Imm"> {
+ let RenderMethod = "addU16ImmOperands";
+}
+
+// Special case: S17Imm has custom predicate and render method
+def S17Imm : ImmediateAsmOperandWithPredicate<"isS17Imm"> {
+ let RenderMethod = "addS16ImmOperands";
+}
+
+// Special case: ATBitsAsHint has custom predicate
+def ATBitsAsHint : ImmediateAsmOperandWithPredicate<"isATBitsAsHint">;
+
+// Special case: ImmZero has custom predicate
+def ImmZero : ImmediateAsmOperandWithPredicate<"isImmZero">;
+
+//===----------------------------------------------------------------------===//
+// i32 immediate operands
+//===----------------------------------------------------------------------===//
+
+def u1imm : UnsignedImmOp<i32, "U1Imm", 1>;
+def u2imm : UnsignedImmOp<i32, "U2Imm", 2>;
+def u3imm : UnsignedImmOp<i32, "U3Imm", 3>;
+def u4imm : UnsignedImmOp<i32, "U4Imm", 4>;
+def u5imm : UnsignedImmOp<i32, "U5Imm", 5>;
+def u6imm : UnsignedImmOp<i32, "U6Imm", 6>;
+def u7imm : UnsignedImmOp<i32, "U7Imm", 7>;
+def u8imm : UnsignedImmOp<i32, "U8Imm", 8>;
+def u10imm : UnsignedImmOp<i32, "U10Imm", 10>;
+def u12imm : UnsignedImmOp<i32, "U12Imm", 12>;
+
+def s5imm : SignedImmOp<i32, "S5Imm", 5>;
+
+// Special case: atimm has custom print method and no decoder
+def atimm : Operand<i32> {
+ let PrintMethod = "printATBitsAsHint";
+ let ParserMatchClass = ATBitsAsHint;
+ let OperandType = "OPERAND_IMMEDIATE";
+}
+
+// Special case: immZero has custom print and decoder methods
+def immZero : Operand<i32> {
+ let PrintMethod = "printImmZeroOperand";
+ let ParserMatchClass = ImmZero;
+ let DecoderMethod = "decodeImmZeroOperand";
+ let OperandType = "OPERAND_IMMEDIATE";
+}
+
+// Special cases: s16imm and u16imm have custom encoder methods
+def s16imm : SignedImmOpWithEncoder<i32, "S16Imm", 16, "PPC::fixup_ppc_half16">;
+
+def u16imm : UnsignedImmOpWithEncoder<i32, "U16Imm", 16, "PPC::fixup_ppc_half16">;
+
+//===----------------------------------------------------------------------===//
+// i64 immediate operands
+//===----------------------------------------------------------------------===//
+
+def s16imm64 : SignedImmOpWithEncoder<i64, "S16Imm", 16, "PPC::fixup_ppc_half16">;
+
+def u16imm64 : UnsignedImmOpWithEncoder<i64, "U16Imm", 16, "PPC::fixup_ppc_half16">;
+
+// Special case: s17imm uses S16Imm print method but accepts wider range
+def s17imm : SignedImmOpWithEncoder<i32, "S17Imm", 16, "PPC::fixup_ppc_half16"> {
+ let PrintMethod = "printS16ImmOperand";
+}
+
+def s17imm64 : SignedImmOpWithEncoder<i64, "S17Imm", 16, "PPC::fixup_ppc_half16"> {
+ let PrintMethod = "printS16ImmOperand";
+}
+
+defm s32imm : SignedImmOpWithPCRel<i64, "S32Imm", 32,
+ "PPC::fixup_ppc_imm32", "PPC::fixup_ppc_pcrel32">;
+
+defm s34imm : SignedImmOpWithPCRel<i64, "S34Imm", 34,
+ "PPC::fixup_ppc_imm34", "PPC::fixup_ppc_pcrel34">;
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
index 5b9ce2400c7cb..3b8116eb8f095 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
@@ -9,6 +9,8 @@
//
//===----------------------------------------------------------------------===//
+include "PPCOperands.td"
+
let Namespace = "PPC" in {
def sub_lt : SubRegIndex<1>;
def sub_gt : SubRegIndex<1, 1>;
@@ -614,250 +616,6 @@ def spe4rc : RegisterOperand<GPRC> {
let ParserMatchClass = PPCRegSPE4RCAsmOperand;
}
-def PPCU1ImmAsmOperand : AsmOperandClass {
- let Name = "U1Imm";
- let PredicateMethod = "isUImm<1>";
- let RenderMethod = "addImmOperands";
-}
-def u1imm : Operand<i32> {
- let PrintMethod = "printU1ImmOperand";
- let ParserMatchClass = PPCU1ImmAsmOperand;
- let DecoderMethod = "decodeUImmOperand<1>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-
-def PPCU2ImmAsmOperand : AsmOperandClass {
- let Name = "U2Imm";
- let PredicateMethod = "isUImm<2>";
- let RenderMethod = "addImmOperands";
-}
-def u2imm : Operand<i32> {
- let PrintMethod = "printU2ImmOperand";
- let ParserMatchClass = PPCU2ImmAsmOperand;
- let DecoderMethod = "decodeUImmOperand<2>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-
-def PPCATBitsAsHintAsmOperand : AsmOperandClass {
- let Name = "ATBitsAsHint"; let PredicateMethod = "isATBitsAsHint";
- let RenderMethod = "addImmOperands"; // Irrelevant, predicate always fails.
-}
-def atimm : Operand<i32> {
- let PrintMethod = "printATBitsAsHint";
- let ParserMatchClass = PPCATBitsAsHintAsmOperand;
- let OperandType = "OPERAND_IMMEDIATE";
-}
-
-def PPCU3ImmAsmOperand : AsmOperandClass {
- let Name = "U3Imm";
- let PredicateMethod = "isUImm<3>";
- let RenderMethod = "addImmOperands";
-}
-def u3imm : Operand<i32> {
- let PrintMethod = "printU3ImmOperand";
- let ParserMatchClass = PPCU3ImmAsmOperand;
- let DecoderMethod = "decodeUImmOperand<3>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-
-def PPCU4ImmAsmOperand : AsmOperandClass {
- let Name = "U4Imm";
- let PredicateMethod = "isUImm<4>";
- let RenderMethod = "addImmOperands";
-}
-def u4imm : Operand<i32> {
- let PrintMethod = "printU4ImmOperand";
- let ParserMatchClass = PPCU4ImmAsmOperand;
- let DecoderMethod = "decodeUImmOperand<4>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def PPCS5ImmAsmOperand : AsmOperandClass {
- let Name = "S5Imm";
- let PredicateMethod = "isSImm<5>";
- let RenderMethod = "addImmOperands";
-}
-def s5imm : Operand<i32> {
- let PrintMethod = "printS5ImmOperand";
- let ParserMatchClass = PPCS5ImmAsmOperand;
- let DecoderMethod = "decodeSImmOperand<5>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def PPCU5ImmAsmOperand : AsmOperandClass {
- let Name = "U5Imm";
- let PredicateMethod = "isUImm<5>";
- let RenderMethod = "addImmOperands";
-}
-def u5imm : Operand<i32> {
- let PrintMethod = "printU5ImmOperand";
- let ParserMatchClass = PPCU5ImmAsmOperand;
- let DecoderMethod = "decodeUImmOperand<5>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def PPCU6ImmAsmOperand : AsmOperandClass {
- let Name = "U6Imm";
- let PredicateMethod = "isUImm<6>";
- let RenderMethod = "addImmOperands";
-}
-def u6imm : Operand<i32> {
- let PrintMethod = "printU6ImmOperand";
- let ParserMatchClass = PPCU6ImmAsmOperand;
- let DecoderMethod = "decodeUImmOperand<6>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def PPCU7ImmAsmOperand : AsmOperandClass {
- let Name = "U7Imm";
- let PredicateMethod = "isUImm<7>";
- let RenderMethod = "addImmOperands";
-}
-def u7imm : Operand<i32> {
- let PrintMethod = "printU7ImmOperand";
- let ParserMatchClass = PPCU7ImmAsmOperand;
- let DecoderMethod = "decodeUImmOperand<7>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def PPCU8ImmAsmOperand : AsmOperandClass {
- let Name = "U8Imm";
- let PredicateMethod = "isUImm<8>";
- let RenderMethod = "addImmOperands";
-}
-def u8imm : Operand<i32> {
- let PrintMethod = "printU8ImmOperand";
- let ParserMatchClass = PPCU8ImmAsmOperand;
- let DecoderMethod = "decodeUImmOperand<8>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def PPCU10ImmAsmOperand : AsmOperandClass {
- let Name = "U10Imm";
- let PredicateMethod = "isUImm<10>";
- let RenderMethod = "addImmOperands";
-}
-def u10imm : Operand<i32> {
- let PrintMethod = "printU10ImmOperand";
- let ParserMatchClass = PPCU10ImmAsmOperand;
- let DecoderMethod = "decodeUImmOperand<10>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def PPCU12ImmAsmOperand : AsmOperandClass {
- let Name = "U12Imm";
- let PredicateMethod = "isUImm<12>";
- let RenderMethod = "addImmOperands";
-}
-def u12imm : Operand<i32> {
- let PrintMethod = "printU12ImmOperand";
- let ParserMatchClass = PPCU12ImmAsmOperand;
- let DecoderMethod = "decodeUImmOperand<12>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def PPCS16ImmAsmOperand : AsmOperandClass {
- let Name = "S16Imm"; let PredicateMethod = "isS16Imm";
- let RenderMethod = "addS16ImmOperands";
-}
-def s16imm : Operand<i32> {
- let PrintMethod = "printS16ImmOperand";
- let EncoderMethod = "getImmEncoding<PPC::fixup_ppc_half16>";
- let ParserMatchClass = PPCS16ImmAsmOperand;
- let DecoderMethod = "decodeSImmOperand<16>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def s16imm64 : Operand<i64> {
- let PrintMethod = "printS16ImmOperand";
- let EncoderMethod = "getImmEncoding<PPC::fixup_ppc_half16>";
- let ParserMatchClass = PPCS16ImmAsmOperand;
- let DecoderMethod = "decodeSImmOperand<16>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def PPCU16ImmAsmOperand : AsmOperandClass {
- let Name = "U16Imm"; let PredicateMethod = "isU16Imm";
- let RenderMethod = "addU16ImmOperands";
-}
-def u16imm : Operand<i32> {
- let PrintMethod = "printU16ImmOperand";
- let EncoderMethod = "getImmEncoding<PPC::fixup_ppc_half16>";
- let ParserMatchClass = PPCU16ImmAsmOperand;
- let DecoderMethod = "decodeUImmOperand<16>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def u16imm64 : Operand<i64> {
- let PrintMethod = "printU16ImmOperand";
- let EncoderMethod = "getImmEncoding<PPC::fixup_ppc_half16>";
- let ParserMatchClass = PPCU16ImmAsmOperand;
- let DecoderMethod = "decodeUImmOperand<16>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def PPCS17ImmAsmOperand : AsmOperandClass {
- let Name = "S17Imm"; let PredicateMethod = "isS17Imm";
- let RenderMethod = "addS16ImmOperands";
-}
-def s17imm : Operand<i32> {
- // This operand type is used for addis/lis to allow the assembler parser
- // to accept immediates in the range -65536..65535 for compatibility with
- // the GNU assembler. The operand is treated as 16-bit otherwise.
- let PrintMethod = "printS16ImmOperand";
- let EncoderMethod = "getImmEncoding<PPC::fixup_ppc_half16>";
- let ParserMatchClass = PPCS17ImmAsmOperand;
- let DecoderMethod = "decodeSImmOperand<16>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def s17imm64 : Operand<i64> {
- // This operand type is used for addis/lis to allow the assembler parser
- // to accept immediates in the range -65536..65535 for compatibility with
- // the GNU assembler. The operand is treated as 16-bit otherwise.
- let PrintMethod = "printS16ImmOperand";
- let EncoderMethod = "getImmEncoding<PPC::fixup_ppc_half16>";
- let ParserMatchClass = PPCS17ImmAsmOperand;
- let DecoderMethod = "decodeSImmOperand<16>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def PPCS32ImmAsmOperand : AsmOperandClass {
- let Name = "S32Imm";
- let PredicateMethod = "isS32Imm";
- let RenderMethod = "addImmOperands";
-}
-def s32imm : Operand<i64> {
- let PrintMethod = "printS32ImmOperand";
- let EncoderMethod = "getImmEncoding<PPC::fixup_ppc_imm32>";
- let ParserMatchClass = PPCS32ImmAsmOperand;
- let DecoderMethod = "decodeSImmOperand<32>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def s32imm_pcrel : Operand<i64> {
- let PrintMethod = "printS32ImmOperand";
- let EncoderMethod = "getImmEncoding<PPC::fixup_ppc_pcrel32>";
- let ParserMatchClass = PPCS32ImmAsmOperand;
- let DecoderMethod = "decodeSImmOperand<32>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def PPCS34ImmAsmOperand : AsmOperandClass {
- let Name = "S34Imm";
- let PredicateMethod = "isS34Imm";
- let RenderMethod = "addImmOperands";
-}
-def s34imm : Operand<i64> {
- let PrintMethod = "printS34ImmOperand";
- let EncoderMethod = "getImmEncoding<PPC::fixup_ppc_imm34>";
- let ParserMatchClass = PPCS34ImmAsmOperand;
- let DecoderMethod = "decodeSImmOperand<34>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def s34imm_pcrel : Operand<i64> {
- let PrintMethod = "printS34ImmOperand";
- let EncoderMethod = "getImmEncoding<PPC::fixup_ppc_pcrel34>";
- let ParserMatchClass = PPCS34ImmAsmOperand;
- let DecoderMethod = "decodeSImmOperand<34>";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-def PPCImmZeroAsmOperand : AsmOperandClass {
- let Name = "ImmZero";
- let PredicateMethod = "isImmZero";
- let RenderMethod = "addImmOperands";
-}
-def immZero : Operand<i32> {
- let PrintMethod = "printImmZeroOperand";
- let ParserMatchClass = PPCImmZeroAsmOperand;
- let DecoderMethod = "decodeImmZeroOperand";
- let OperandType = "OPERAND_IMMEDIATE";
-}
-
def fpimm0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>;
def fpimm0neg : PatLeaf<(fpimm), [{return N->isExactlyValue(-0.0);}]>;
>From 68ca629ec92ed13ea9cd71e37b9cf8b63b62114b Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Fri, 30 Jan 2026 18:43:28 -0500
Subject: [PATCH 02/19] Added class integration with SDNodeXForm and PatLeaf
---
llvm/lib/Target/PowerPC/PPCOperands.td | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index f034d3ed94d4b..d624bcef8178a 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -44,10 +44,21 @@ class ImmediateOp<ValueType vt, string asmop, string decoder> : Operand<vt> {
let OperandType = "OPERAND_IMMEDIATE";
}
+// Immediate operand with pattern matching (combines Operand + PatLeaf)
+// Similar to SystemZ's ImmOpWithPattern
+class ImmOpWithPattern<ValueType vt, string asmop, string decoder,
+ code pred, SDNodeXForm xform, SDNode ImmNode = imm>
+ : ImmediateOp<vt, asmop, decoder>, PatLeaf<(vt ImmNode), pred, xform>;
+
// Unsigned immediate operand
class UnsignedImmOp<ValueType vt, string asmop, int width>
: ImmediateOp<vt, asmop, "decodeUImmOperand<"#width#">">;
+// Unsigned immediate operand with pattern
+class UnsignedImmOpWithPattern<ValueType vt, string asmop, int width,
+ code pred, SDNodeXForm xform, SDNode ImmNode = imm>
+ : ImmOpWithPattern<vt, asmop, "decodeUImmOperand<"#width#">", pred, xform, ImmNode>;
+
// Unsigned immediate operand with encoder
class UnsignedImmOpWithEncoder<ValueType vt, string asmop, int width, string fixup>
: UnsignedImmOp<vt, asmop, width> {
@@ -58,6 +69,11 @@ class UnsignedImmOpWithEncoder<ValueType vt, string asmop, int width, string fix
class SignedImmOp<ValueType vt, string asmop, int width>
: ImmediateOp<vt, asmop, "decodeSImmOperand<"#width#">">;
+// Signed immediate operand with pattern
+class SignedImmOpWithPattern<ValueType vt, string asmop, int width,
+ code pred, SDNodeXForm xform, SDNode ImmNode = imm>
+ : ImmOpWithPattern<vt, asmop, "decodeSImmOperand<"#width#">", pred, xform, ImmNode>;
+
// Signed immediate operand with encoder
class SignedImmOpWithEncoder<ValueType vt, string asmop, int width, string fixup>
: SignedImmOp<vt, asmop, width> {
>From 88ec861868b7bed4789c93a7f1160503f27e8c40 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Fri, 30 Jan 2026 18:49:37 -0500
Subject: [PATCH 03/19] Add Multiclasses for complete immediate definitions
---
llvm/lib/Target/PowerPC/PPCOperands.td | 31 ++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index d624bcef8178a..2ffdeb94a5295 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -94,6 +94,31 @@ multiclass SignedImmOpWithPCRel<ValueType vt, string asmop, int width,
def _pcrel : SignedImmOpWithEncoder<vt, asmop, width, fixup_pcrel>;
}
+//===----------------------------------------------------------------------===//
+// Multiclasses for complete immediate definitions (AsmOperand + Operand + PatLeaf)
+// Similar to SystemZ's Immediate multiclass
+//===----------------------------------------------------------------------===//
+
+// Creates both Operand and PatLeaf for unsigned immediates
+// Similar to SystemZ's Immediate multiclass
+// Note: PowerPC needs width parameter for decoder, so we add it after asmop
+multiclass UnsignedImmediate<ValueType vt, code pred, SDNodeXForm xform, string asmop, int width> {
+ // Main operand definition with PatLeaf for imm nodes
+ def "" : UnsignedImmOpWithPattern<vt, asmop, width, pred, xform>;
+
+ // PatLeaf for timm (target immediate) nodes
+ def _timm : UnsignedImmOpWithPattern<vt, asmop, width, pred, xform, timm>;
+}
+
+// Creates both Operand and PatLeaf for signed immediates
+multiclass SignedImmediate<ValueType vt, code pred, SDNodeXForm xform, string asmop, int width> {
+ // Main operand definition with PatLeaf for imm nodes
+ def "" : SignedImmOpWithPattern<vt, asmop, width, pred, xform>;
+
+ // PatLeaf for timm (target immediate) nodes
+ def _timm : SignedImmOpWithPattern<vt, asmop, width, pred, xform, timm>;
+}
+
//===----------------------------------------------------------------------===//
// Immediate AsmOperand definitions
//===----------------------------------------------------------------------===//
@@ -140,6 +165,12 @@ def ImmZero : ImmediateAsmOperandWithPredicate<"isImmZero">;
// i32 immediate operands
//===----------------------------------------------------------------------===//
+// u1imm: 1-bit unsigned immediate (generates u1imm and u1imm_timm)
+/*
+defm u1imm : UnsignedImmediate<i32,
+ [{ return isUInt<1>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U1Imm", 1>;
+ */
+
def u1imm : UnsignedImmOp<i32, "U1Imm", 1>;
def u2imm : UnsignedImmOp<i32, "U2Imm", 2>;
def u3imm : UnsignedImmOp<i32, "U3Imm", 3>;
>From 15be3b1e988fcb897062dd65ddb1ce2bfbf65ecc Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 2 Feb 2026 11:16:24 -0500
Subject: [PATCH 04/19] migrated u1imm
---
llvm/lib/Target/PowerPC/PPCInstrAltivec.td | 6 ++--
llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td | 4 +--
llvm/lib/Target/PowerPC/PPCInstrP10.td | 8 ++---
llvm/lib/Target/PowerPC/PPCOperands.td | 36 +++++++++++---------
4 files changed, 29 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
index 461ab3a2851ab..0fca20caa70b6 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
@@ -343,7 +343,7 @@ class VXBX_Int_Ty<bits<11> xo, string opc, Intrinsic IntID, ValueType Ty>
class VXCR_Int_Ty<bits<11> xo, string opc, Intrinsic IntID, ValueType Ty>
: VXForm_CR<xo, (outs vrrc:$VD), (ins vrrc:$VA, u1imm:$ST, u4imm:$SIX),
!strconcat(opc, " $VD, $VA, $ST, $SIX"), IIC_VecFP,
- [(set Ty:$VD, (IntID Ty:$VA, timm:$ST, timm:$SIX))]>;
+ [(set Ty:$VD, (IntID Ty:$VA, u1imm_timm:$ST, timm:$SIX))]>;
//===----------------------------------------------------------------------===//
// Instruction Definitions.
@@ -1397,9 +1397,9 @@ def VUPKLSW : VX2_Int_Ty2<1742, "vupklsw", int_ppc_altivec_vupklsw,
def BCDADD_rec : VX_VT5_VA5_VB5_PS1_XO9_o<1, "bcdadd." , []>;
def BCDSUB_rec : VX_VT5_VA5_VB5_PS1_XO9_o<65, "bcdsub." , []>;
-def : Pat<(v16i8 (int_ppc_bcdadd v16i8:$vA, v16i8:$vB, timm:$PS)),
+def : Pat<(v16i8 (int_ppc_bcdadd v16i8:$vA, v16i8:$vB, u1imm_timm:$PS)),
(BCDADD_rec $vA, $vB, $PS)>;
-def : Pat<(v16i8 (int_ppc_bcdsub v16i8:$vA, v16i8:$vB, timm:$PS)),
+def : Pat<(v16i8 (int_ppc_bcdsub v16i8:$vA, v16i8:$vB, u1imm_timm:$PS)),
(BCDSUB_rec $vA, $vB, $PS)>;
// Shuffle patterns for unary and swapped (LE) vector pack modulo.
diff --git a/llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td b/llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td
index 076c7465994cf..d8554e2ef218e 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td
@@ -512,7 +512,7 @@ let Predicates = [MMA, IsISAFuture] in {
31, 14, 177, (outs dmr:$AT), (ins dmr:$ATi, dmr:$AB, u1imm:$T),
"dmsha2hash $AT, $AB, $T",
[(set v1024i1:$AT, (int_ppc_mma_dmsha2hash v1024i1:$ATi,
- v1024i1:$AB, timm:$T))]>,
+ v1024i1:$AB, u1imm_timm:$T))]>,
RegConstraint<"$ATi = $AT">;
def DMSHA3HASH
: XForm_ATp2_SR5<31, 15, 177, (outs dmrp:$ATp),
@@ -593,7 +593,7 @@ let Predicates = [MMA, IsISAFuture] in {
// Cryptography Intrinsic
def : Pat<(v1024i1 (int_ppc_mma_dmxxshapad v1024i1:$ATi, v16i8:$XB, timm:$ID,
- timm:$E, timm:$BL)),
+ u1imm_timm:$E, timm:$BL)),
(DMXXSHAPAD $ATi, RCCp.BToVSRC, $ID, $E, $BL)>;
}
diff --git a/llvm/lib/Target/PowerPC/PPCInstrP10.td b/llvm/lib/Target/PowerPC/PPCInstrP10.td
index 1b03a3db7d112..95b7315a6c65e 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrP10.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrP10.td
@@ -1629,22 +1629,22 @@ let Predicates = [IsISA3_1] in {
(ins vrrc:$VB, u1imm:$MP),
"vcntmbb $RD, $VB, $MP", IIC_VecGeneral,
[(set i64:$RD, (int_ppc_altivec_vcntmbb
- v16i8:$VB, timm:$MP))]>;
+ v16i8:$VB, u1imm_timm:$MP))]>;
def VCNTMBH : VXForm_RD5_MP_VB5<1602, 13, (outs g8rc:$RD),
(ins vrrc:$VB, u1imm:$MP),
"vcntmbh $RD, $VB, $MP", IIC_VecGeneral,
[(set i64:$RD, (int_ppc_altivec_vcntmbh
- v8i16:$VB, timm:$MP))]>;
+ v8i16:$VB, u1imm_timm:$MP))]>;
def VCNTMBW : VXForm_RD5_MP_VB5<1602, 14, (outs g8rc:$RD),
(ins vrrc:$VB, u1imm:$MP),
"vcntmbw $RD, $VB, $MP", IIC_VecGeneral,
[(set i64:$RD, (int_ppc_altivec_vcntmbw
- v4i32:$VB, timm:$MP))]>;
+ v4i32:$VB, u1imm_timm:$MP))]>;
def VCNTMBD : VXForm_RD5_MP_VB5<1602, 15, (outs g8rc:$RD),
(ins vrrc:$VB, u1imm:$MP),
"vcntmbd $RD, $VB, $MP", IIC_VecGeneral,
[(set i64:$RD, (int_ppc_altivec_vcntmbd
- v2i64:$VB, timm:$MP))]>;
+ v2i64:$VB, u1imm_timm:$MP))]>;
def VEXTDUBVLX : VAForm_1a<24, (outs vrrc:$RT),
(ins vrrc:$RA, vrrc:$RB, gprc:$RC),
"vextdubvlx $RT, $RA, $RB, $RC",
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index 2ffdeb94a5295..e6d662e75abf0 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -96,27 +96,33 @@ multiclass SignedImmOpWithPCRel<ValueType vt, string asmop, int width,
//===----------------------------------------------------------------------===//
// Multiclasses for complete immediate definitions (AsmOperand + Operand + PatLeaf)
-// Similar to SystemZ's Immediate multiclass
+// Similar to SystemZ's Immediate multiclass but GlobalISel-compatible
//===----------------------------------------------------------------------===//
-// Creates both Operand and PatLeaf for unsigned immediates
-// Similar to SystemZ's Immediate multiclass
-// Note: PowerPC needs width parameter for decoder, so we add it after asmop
+// Creates Operand and separate PatLeaf definitions for unsigned immediates
+// This approach keeps Operand and PatLeaf separate for GlobalISel compatibility
+// while maintaining SystemZ-style organization and naming
multiclass UnsignedImmediate<ValueType vt, code pred, SDNodeXForm xform, string asmop, int width> {
- // Main operand definition with PatLeaf for imm nodes
- def "" : UnsignedImmOpWithPattern<vt, asmop, width, pred, xform>;
+ // Operand definition (for instruction operands)
+ def "" : UnsignedImmOp<vt, asmop, width>;
- // PatLeaf for timm (target immediate) nodes
- def _timm : UnsignedImmOpWithPattern<vt, asmop, width, pred, xform, timm>;
+ // PatLeaf for imm nodes (for DAG pattern matching)
+ def _pat : PatLeaf<(vt imm), pred, xform>;
+
+ // PatLeaf for timm nodes (for target-specific pattern matching, e.g., intrinsics)
+ def _timm : PatLeaf<(vt timm), pred, xform>;
}
-// Creates both Operand and PatLeaf for signed immediates
+// Creates Operand and separate PatLeaf definitions for signed immediates
multiclass SignedImmediate<ValueType vt, code pred, SDNodeXForm xform, string asmop, int width> {
- // Main operand definition with PatLeaf for imm nodes
- def "" : SignedImmOpWithPattern<vt, asmop, width, pred, xform>;
+ // Operand definition (for instruction operands)
+ def "" : SignedImmOp<vt, asmop, width>;
+
+ // PatLeaf for imm nodes (for DAG pattern matching)
+ def _pat : PatLeaf<(vt imm), pred, xform>;
- // PatLeaf for timm (target immediate) nodes
- def _timm : SignedImmOpWithPattern<vt, asmop, width, pred, xform, timm>;
+ // PatLeaf for timm nodes (for target-specific pattern matching, e.g., intrinsics)
+ def _timm : PatLeaf<(vt timm), pred, xform>;
}
//===----------------------------------------------------------------------===//
@@ -166,12 +172,10 @@ def ImmZero : ImmediateAsmOperandWithPredicate<"isImmZero">;
//===----------------------------------------------------------------------===//
// u1imm: 1-bit unsigned immediate (generates u1imm and u1imm_timm)
-/*
defm u1imm : UnsignedImmediate<i32,
[{ return isUInt<1>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U1Imm", 1>;
- */
-def u1imm : UnsignedImmOp<i32, "U1Imm", 1>;
+// def u1imm : UnsignedImmOp<i32, "U1Imm", 1>;
def u2imm : UnsignedImmOp<i32, "U2Imm", 2>;
def u3imm : UnsignedImmOp<i32, "U3Imm", 3>;
def u4imm : UnsignedImmOp<i32, "U4Imm", 4>;
>From 384cf15ac096f48cf22c10e03e51a95988fb3ff1 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 2 Feb 2026 13:37:53 -0500
Subject: [PATCH 05/19] migrate u2imm
---
llvm/lib/Target/PowerPC/PPCInstr64Bit.td | 2 +-
llvm/lib/Target/PowerPC/PPCInstrAltivec.td | 6 +-
llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td | 2 +-
llvm/lib/Target/PowerPC/PPCOperands.td | 88 +++++++++-----------
4 files changed, 45 insertions(+), 53 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index d4ce03c07663f..6f39f8b7b7225 100644
--- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -1823,7 +1823,7 @@ def ADDEX8 : Z23Form_RTAB5_CY2<31, 170, (outs g8rc:$RT),
(ins g8rc:$RA, g8rc:$RB, u2imm:$CY),
"addex $RT, $RA, $RB, $CY", IIC_IntGeneral,
[(set i64:$RT, (int_ppc_addex i64:$RA, i64:$RB,
- timm:$CY))]>;
+ u2imm_timm:$CY))]>;
//===----------------------------------------------------------------------===//
// Instruction Patterns
diff --git a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
index 0fca20caa70b6..fd16a16530fbf 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
@@ -1635,13 +1635,13 @@ class VX_VT5_EO5_VB5_XO9_o<bits<5> eo, bits<9> xo, string opc,
// Decimal Convert From/to National/Zoned/Signed-QWord
def BCDCFN_rec : VX_VT5_EO5_VB5_PS1_XO9_o<7, 385, "bcdcfn." ,
- [(set v16i8:$VD, (int_ppc_national2packed v16i8:$VB, timm:$PS))]>;
+ [(set v16i8:$VD, (int_ppc_national2packed v16i8:$VB, u1imm_timm:$PS))]>;
def BCDCFZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<6, 385, "bcdcfz." ,
- [(set v16i8:$VD, (int_ppc_zoned2packed v16i8:$VB, timm:$PS))]>;
+ [(set v16i8:$VD, (int_ppc_zoned2packed v16i8:$VB, u1imm_timm:$PS))]>;
def BCDCTN_rec : VX_VT5_EO5_VB5_XO9_o <5, 385, "bcdctn." ,
[(set v16i8:$VD, (int_ppc_packed2national v16i8:$VB))]>;
def BCDCTZ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<4, 385, "bcdctz." ,
- [(set v16i8:$VD, (int_ppc_packed2zoned v16i8:$VB, timm:$PS))]>;
+ [(set v16i8:$VD, (int_ppc_packed2zoned v16i8:$VB, u1imm_timm:$PS))]>;
def BCDCFSQ_rec : VX_VT5_EO5_VB5_PS1_XO9_o<2, 385, "bcdcfsq.", []>;
def BCDCTSQ_rec : VX_VT5_EO5_VB5_XO9_o <0, 385, "bcdctsq.", []>;
diff --git a/llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td b/llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td
index d8554e2ef218e..0f9fe3f4ac589 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td
@@ -472,7 +472,7 @@ let Predicates = [MMA, IsISAFuture] in {
def DMXXINSTDMR256 : XX2Form_AT3_XBp5_P2<60, 485, (outs dmrrowp:$AT),
(ins vsrprc:$XBp, u2imm:$P),
"dmxxinstdmr256 $AT, $XBp, $P",
- [(set v256i1:$AT, (PPCInst256 v256i1:$XBp, timm:$P))]>;
+ [(set v256i1:$AT, (PPCInst256 v256i1:$XBp, u2imm_timm:$P))]>;
def DMMR
: XForm_ATB3<31, 6, 177, (outs dmr:$AT), (ins dmr:$AB), "dmmr $AT, $AB",
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index e6d662e75abf0..8fd016394ec04 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -15,28 +15,28 @@
// Immediate operand base classes
//===----------------------------------------------------------------------===//
-// Base class for immediate AsmOperandClass definitions
+// Base class for immediate AsmOperandClass definitions.
class ImmediateAsmOperand : AsmOperandClass {
let Name = NAME;
let RenderMethod = "addImmOperands";
}
-// Base class for immediate AsmOperandClass with custom predicate
+// Base class for immediate AsmOperandClass with custom predicate.
class ImmediateAsmOperandWithPredicate<string predicate> : ImmediateAsmOperand {
let PredicateMethod = predicate;
}
-// Base class for unsigned immediate AsmOperandClass with templated predicate
+// Base class for unsigned immediate AsmOperandClass with templated predicate.
class UnsignedImmAsmOperand<int width> : ImmediateAsmOperand {
let PredicateMethod = "isUImm<" # width # ">";
}
-// Base class for signed immediate AsmOperandClass with templated predicate
+// Base class for signed immediate AsmOperandClass with templated predicate.
class SignedImmAsmOperand<int width> : ImmediateAsmOperand {
let PredicateMethod = "isSImm<" # width # ">";
}
-// Base class for immediate operands
+// Base class for immediate operands.
class ImmediateOp<ValueType vt, string asmop, string decoder> : Operand<vt> {
let PrintMethod = "print"#asmop#"Operand";
let ParserMatchClass = !cast<AsmOperandClass>(asmop);
@@ -44,50 +44,49 @@ class ImmediateOp<ValueType vt, string asmop, string decoder> : Operand<vt> {
let OperandType = "OPERAND_IMMEDIATE";
}
-// Immediate operand with pattern matching (combines Operand + PatLeaf)
-// Similar to SystemZ's ImmOpWithPattern
+// Immediate operand with pattern matching (combines Operand + PatLeaf).
class ImmOpWithPattern<ValueType vt, string asmop, string decoder,
code pred, SDNodeXForm xform, SDNode ImmNode = imm>
: ImmediateOp<vt, asmop, decoder>, PatLeaf<(vt ImmNode), pred, xform>;
-// Unsigned immediate operand
+// Unsigned immediate operand.
class UnsignedImmOp<ValueType vt, string asmop, int width>
: ImmediateOp<vt, asmop, "decodeUImmOperand<"#width#">">;
-// Unsigned immediate operand with pattern
+// Unsigned immediate operand with pattern.
class UnsignedImmOpWithPattern<ValueType vt, string asmop, int width,
code pred, SDNodeXForm xform, SDNode ImmNode = imm>
: ImmOpWithPattern<vt, asmop, "decodeUImmOperand<"#width#">", pred, xform, ImmNode>;
-// Unsigned immediate operand with encoder
+// Unsigned immediate operand with encoder.
class UnsignedImmOpWithEncoder<ValueType vt, string asmop, int width, string fixup>
: UnsignedImmOp<vt, asmop, width> {
let EncoderMethod = "getImmEncoding<" # fixup # ">";
}
-// Signed immediate operand
+// Signed immediate operand.
class SignedImmOp<ValueType vt, string asmop, int width>
: ImmediateOp<vt, asmop, "decodeSImmOperand<"#width#">">;
-// Signed immediate operand with pattern
+// Signed immediate operand with pattern.
class SignedImmOpWithPattern<ValueType vt, string asmop, int width,
code pred, SDNodeXForm xform, SDNode ImmNode = imm>
: ImmOpWithPattern<vt, asmop, "decodeSImmOperand<"#width#">", pred, xform, ImmNode>;
-// Signed immediate operand with encoder
+// Signed immediate operand with encoder.
class SignedImmOpWithEncoder<ValueType vt, string asmop, int width, string fixup>
: SignedImmOp<vt, asmop, width> {
let EncoderMethod = "getImmEncoding<" # fixup # ">";
}
-// Multiclass for unsigned immediate operands with both regular and PC-relative versions
+// Multiclass for unsigned immediate operands with both regular and PC-relative versions.
multiclass UnsignedImmOpWithPCRel<ValueType vt, string asmop, int width,
string fixup_imm, string fixup_pcrel> {
def "" : UnsignedImmOpWithEncoder<vt, asmop, width, fixup_imm>;
def _pcrel : UnsignedImmOpWithEncoder<vt, asmop, width, fixup_pcrel>;
}
-// Multiclass for signed immediate operands with both regular and PC-relative versions
+// Multiclass for signed immediate operands with both regular and PC-relative versions.
multiclass SignedImmOpWithPCRel<ValueType vt, string asmop, int width,
string fixup_imm, string fixup_pcrel> {
def "" : SignedImmOpWithEncoder<vt, asmop, width, fixup_imm>;
@@ -95,33 +94,32 @@ multiclass SignedImmOpWithPCRel<ValueType vt, string asmop, int width,
}
//===----------------------------------------------------------------------===//
-// Multiclasses for complete immediate definitions (AsmOperand + Operand + PatLeaf)
-// Similar to SystemZ's Immediate multiclass but GlobalISel-compatible
+// Multiclasses for complete immediate definitions (AsmOperand + Operand + PatLeaf).
//===----------------------------------------------------------------------===//
-// Creates Operand and separate PatLeaf definitions for unsigned immediates
-// This approach keeps Operand and PatLeaf separate for GlobalISel compatibility
-// while maintaining SystemZ-style organization and naming
+// Creates Operand and separate PatLeaf definitions for unsigned immediates.
+// This approach keeps Operand and PatLeaf separate for GlobalISel compatibility.
+// while maintaining SystemZ-style organization and naming.
multiclass UnsignedImmediate<ValueType vt, code pred, SDNodeXForm xform, string asmop, int width> {
- // Operand definition (for instruction operands)
+ // Operand definition (for instruction operands).
def "" : UnsignedImmOp<vt, asmop, width>;
-
- // PatLeaf for imm nodes (for DAG pattern matching)
+
+ // PatLeaf for imm nodes (for DAG pattern matching).
def _pat : PatLeaf<(vt imm), pred, xform>;
-
- // PatLeaf for timm nodes (for target-specific pattern matching, e.g., intrinsics)
+
+ // PatLeaf for timm nodes (for target-specific pattern matching, e.g., intrinsics).
def _timm : PatLeaf<(vt timm), pred, xform>;
}
-// Creates Operand and separate PatLeaf definitions for signed immediates
+// Creates Operand and separate PatLeaf definitions for signed immediates.
multiclass SignedImmediate<ValueType vt, code pred, SDNodeXForm xform, string asmop, int width> {
// Operand definition (for instruction operands)
def "" : SignedImmOp<vt, asmop, width>;
-
- // PatLeaf for imm nodes (for DAG pattern matching)
+
+ // PatLeaf for imm nodes (for DAG pattern matching).
def _pat : PatLeaf<(vt imm), pred, xform>;
-
- // PatLeaf for timm nodes (for target-specific pattern matching, e.g., intrinsics)
+
+ // PatLeaf for timm nodes (for target-specific pattern matching, e.g., intrinsics).
def _timm : PatLeaf<(vt timm), pred, xform>;
}
@@ -142,41 +140,39 @@ def U12Imm : UnsignedImmAsmOperand<12>;
def S5Imm : SignedImmAsmOperand<5>;
-// Special case: S32Imm and S34Imm have custom predicates that accept expressions
+// Special case: S32Imm and S34Imm have custom predicates that accept expressions.
def S32Imm : ImmediateAsmOperandWithPredicate<"isS32Imm">;
def S34Imm : ImmediateAsmOperandWithPredicate<"isS34Imm">;
-// Special case: S16Imm has custom render method
+// Special case: S16Imm has custom render method.
def S16Imm : ImmediateAsmOperandWithPredicate<"isS16Imm"> {
let RenderMethod = "addS16ImmOperands";
}
-// Special case: U16Imm has custom render method
+// Special case: U16Imm has custom render method.
def U16Imm : ImmediateAsmOperandWithPredicate<"isU16Imm"> {
let RenderMethod = "addU16ImmOperands";
}
-// Special case: S17Imm has custom predicate and render method
+// Special case: S17Imm has custom predicate and render method.
def S17Imm : ImmediateAsmOperandWithPredicate<"isS17Imm"> {
let RenderMethod = "addS16ImmOperands";
}
-// Special case: ATBitsAsHint has custom predicate
+// Special case: ATBitsAsHint has custom predicate.
def ATBitsAsHint : ImmediateAsmOperandWithPredicate<"isATBitsAsHint">;
-// Special case: ImmZero has custom predicate
+// Special case: ImmZero has custom predicate.
def ImmZero : ImmediateAsmOperandWithPredicate<"isImmZero">;
//===----------------------------------------------------------------------===//
// i32 immediate operands
//===----------------------------------------------------------------------===//
-// u1imm: 1-bit unsigned immediate (generates u1imm and u1imm_timm)
defm u1imm : UnsignedImmediate<i32,
[{ return isUInt<1>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U1Imm", 1>;
-
-// def u1imm : UnsignedImmOp<i32, "U1Imm", 1>;
-def u2imm : UnsignedImmOp<i32, "U2Imm", 2>;
+defm u2imm : UnsignedImmediate<i32,
+ [{ return isUInt<2>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U2Imm", 2>;
def u3imm : UnsignedImmOp<i32, "U3Imm", 3>;
def u4imm : UnsignedImmOp<i32, "U4Imm", 4>;
def u5imm : UnsignedImmOp<i32, "U5Imm", 5>;
@@ -188,14 +184,14 @@ def u12imm : UnsignedImmOp<i32, "U12Imm", 12>;
def s5imm : SignedImmOp<i32, "S5Imm", 5>;
-// Special case: atimm has custom print method and no decoder
+// Special case: atimm has custom print method and no decoder.
def atimm : Operand<i32> {
let PrintMethod = "printATBitsAsHint";
let ParserMatchClass = ATBitsAsHint;
let OperandType = "OPERAND_IMMEDIATE";
}
-// Special case: immZero has custom print and decoder methods
+// Special case: immZero has custom print and decoder methods.
def immZero : Operand<i32> {
let PrintMethod = "printImmZeroOperand";
let ParserMatchClass = ImmZero;
@@ -203,9 +199,8 @@ def immZero : Operand<i32> {
let OperandType = "OPERAND_IMMEDIATE";
}
-// Special cases: s16imm and u16imm have custom encoder methods
+// Special cases: s16imm and u16imm have custom encoder methods.
def s16imm : SignedImmOpWithEncoder<i32, "S16Imm", 16, "PPC::fixup_ppc_half16">;
-
def u16imm : UnsignedImmOpWithEncoder<i32, "U16Imm", 16, "PPC::fixup_ppc_half16">;
//===----------------------------------------------------------------------===//
@@ -213,20 +208,17 @@ def u16imm : UnsignedImmOpWithEncoder<i32, "U16Imm", 16, "PPC::fixup_ppc_half16"
//===----------------------------------------------------------------------===//
def s16imm64 : SignedImmOpWithEncoder<i64, "S16Imm", 16, "PPC::fixup_ppc_half16">;
-
def u16imm64 : UnsignedImmOpWithEncoder<i64, "U16Imm", 16, "PPC::fixup_ppc_half16">;
-// Special case: s17imm uses S16Imm print method but accepts wider range
+// Special case: s17imm uses S16Imm print method but accepts wider range.
def s17imm : SignedImmOpWithEncoder<i32, "S17Imm", 16, "PPC::fixup_ppc_half16"> {
let PrintMethod = "printS16ImmOperand";
}
-
def s17imm64 : SignedImmOpWithEncoder<i64, "S17Imm", 16, "PPC::fixup_ppc_half16"> {
let PrintMethod = "printS16ImmOperand";
}
defm s32imm : SignedImmOpWithPCRel<i64, "S32Imm", 32,
"PPC::fixup_ppc_imm32", "PPC::fixup_ppc_pcrel32">;
-
defm s34imm : SignedImmOpWithPCRel<i64, "S34Imm", 34,
"PPC::fixup_ppc_imm34", "PPC::fixup_ppc_pcrel34">;
>From 3c94a6edfd6f5b89e8a8863171d1667274ee7788 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 2 Feb 2026 13:54:06 -0500
Subject: [PATCH 06/19] migrate u4..u12 imm
---
llvm/lib/Target/PowerPC/PPCInstrAltivec.td | 8 ++++----
llvm/lib/Target/PowerPC/PPCInstrInfo.td | 12 +++++------
llvm/lib/Target/PowerPC/PPCInstrP10.td | 16 +++++++--------
llvm/lib/Target/PowerPC/PPCOperands.td | 24 ++++++++++++++--------
4 files changed, 34 insertions(+), 26 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
index fd16a16530fbf..e25e40290addd 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
@@ -533,19 +533,19 @@ def VANDC : VXForm_1<1092, (outs vrrc:$VD), (ins vrrc:$VA, vrrc:$VB),
def VCFSX : VXForm_1<842, (outs vrrc:$VD), (ins u5imm:$VA, vrrc:$VB),
"vcfsx $VD, $VB, $VA", IIC_VecFP,
[(set v4f32:$VD,
- (int_ppc_altivec_vcfsx v4i32:$VB, timm:$VA))]>;
+ (int_ppc_altivec_vcfsx v4i32:$VB, u5imm_timm:$VA))]>;
def VCFUX : VXForm_1<778, (outs vrrc:$VD), (ins u5imm:$VA, vrrc:$VB),
"vcfux $VD, $VB, $VA", IIC_VecFP,
[(set v4f32:$VD,
- (int_ppc_altivec_vcfux v4i32:$VB, timm:$VA))]>;
+ (int_ppc_altivec_vcfux v4i32:$VB, u5imm_timm:$VA))]>;
def VCTSXS : VXForm_1<970, (outs vrrc:$VD), (ins u5imm:$VA, vrrc:$VB),
"vctsxs $VD, $VB, $VA", IIC_VecFP,
[(set v4i32:$VD,
- (int_ppc_altivec_vctsxs v4f32:$VB, timm:$VA))]>;
+ (int_ppc_altivec_vctsxs v4f32:$VB, u5imm_timm:$VA))]>;
def VCTUXS : VXForm_1<906, (outs vrrc:$VD), (ins u5imm:$VA, vrrc:$VB),
"vctuxs $VD, $VB, $VA", IIC_VecFP,
[(set v4i32:$VD,
- (int_ppc_altivec_vctuxs v4f32:$VB, timm:$VA))]>;
+ (int_ppc_altivec_vctuxs v4f32:$VB, u5imm_timm:$VA))]>;
// Defines with the UIM field set to 0 for floating-point
// to integer (fp_to_sint/fp_to_uint) conversions and integer
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 88dd4df7e4366..5a2b8ac6b67a6 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -2167,13 +2167,13 @@ def LWAT_PSEUDO : PPCCustomInserterPseudo<
(outs gprc:$dst),
(ins ptr_rc_nor0:$ptr, gprc:$val, u5imm:$fc),
"#LWAT_PSEUDO",
- [(set i32:$dst, (int_ppc_amo_lwat ptr_rc_nor0:$ptr, gprc:$val, timm:$fc))]>;
+ [(set i32:$dst, (int_ppc_amo_lwat ptr_rc_nor0:$ptr, gprc:$val, u5imm_timm:$fc))]>;
def LWAT_COND_PSEUDO : PPCCustomInserterPseudo <
(outs gprc:$dst),
(ins ptr_rc_nor0:$ptr, u5imm:$fc),
"#LWAT_COND_PSEUDO",
- [(set i32:$dst, (int_ppc_amo_lwat_cond ptr_rc_nor0:$ptr, timm:$fc))]>;
+ [(set i32:$dst, (int_ppc_amo_lwat_cond ptr_rc_nor0:$ptr, u5imm_timm:$fc))]>;
let Defs = [CR0], mayStore = 1, mayLoad = 0, hasSideEffects = 0 in {
def STBCX : XForm_1_memOp<31, 694, (outs), (ins gprc:$RST, (memrr $RA, $RB):$addr),
@@ -2191,7 +2191,7 @@ def STWCX : XForm_1_memOp<31, 150, (outs), (ins gprc:$RST, (memrr $RA, $RB):$add
let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
def STWAT : XForm_base_r3xo_memOp<31, 710, (outs), (ins gprc:$RST, ptr_rc_nor0:$RA, u5imm:$RB),
"stwat $RST, $RA, $RB", IIC_LdStStore,
- [(PPCstat i32:$RST, ptr_rc_nor0:$RA, timm:$RB)]>,
+ [(PPCstat i32:$RST, ptr_rc_nor0:$RA, u5imm_timm:$RB)]>,
Requires<[IsISA3_0]>;
let isTrap = 1, hasCtrlDep = 1 in
@@ -3092,11 +3092,11 @@ let Uses = [RM], mayRaiseFPException = 1 in {
let hasSideEffects = 1, Defs = [RM] in {
def MTFSB0 : XForm_43<63, 70, (outs), (ins u5imm:$FM),
"mtfsb0 $FM", IIC_IntMTFSB0,
- [(int_ppc_mtfsb0 timm:$FM)]>,
+ [(int_ppc_mtfsb0 u5imm_timm:$FM)]>,
PPC970_DGroup_Single, PPC970_Unit_FPU;
def MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM),
"mtfsb1 $FM", IIC_IntMTFSB0,
- [(int_ppc_mtfsb1 timm:$FM)]>,
+ [(int_ppc_mtfsb1 u5imm_timm:$FM)]>,
PPC970_DGroup_Single, PPC970_Unit_FPU;
}
@@ -4577,7 +4577,7 @@ def MCRFS : XLForm_3<63, 64, (outs crrc:$BF), (ins crrc:$BFA),
let Predicates = [HasFPU] in {
let Defs = [RM], hasSideEffects = 1 in {
let isCodeGenOnly = 1,
- Pattern = [(int_ppc_mtfsfi timm:$BF, timm:$U)], W = 0 in
+ Pattern = [(int_ppc_mtfsfi u3imm_timm:$BF, u4imm_timm:$U)], W = 0 in
def MTFSFIb : XLForm_4<63, 134, (outs), (ins u3imm:$BF, u4imm:$U),
"mtfsfi $BF, $U", IIC_IntMFFS>;
def MTFSFI : XLForm_4<63, 134, (outs), (ins u3imm:$BF, u4imm:$U, i32imm:$W),
diff --git a/llvm/lib/Target/PowerPC/PPCInstrP10.td b/llvm/lib/Target/PowerPC/PPCInstrP10.td
index 95b7315a6c65e..4e8f152dd9a7e 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrP10.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrP10.td
@@ -1448,15 +1448,15 @@ let Predicates = [IsISA3_1] in {
[(set v16i8:$VRT,
(int_ppc_altivec_vsldbi v16i8:$VRA,
v16i8:$VRB,
- timm:$SD))]>;
+ u3imm_timm:$SD))]>;
def VSRDBI : VNForm_VTAB5_SD3<22, 1, (outs vrrc:$VRT),
(ins vrrc:$VRA, vrrc:$VRB, u3imm:$SD),
"vsrdbi $VRT, $VRA, $VRB, $SD",
IIC_VecGeneral,
[(set v16i8:$VRT,
(int_ppc_altivec_vsrdbi v16i8:$VRA,
- v16i8:$VRB,
- timm:$SD))]>;
+ v16i8:$VRB,
+ u3imm_timm:$SD))]>;
defm VSTRIBR : VXForm_VTB5_RCr<13, 1, (outs vrrc:$VT), (ins vrrc:$VB),
"vstribr", "$VT, $VB", IIC_VecGeneral,
[(set v16i8:$VT,
@@ -1477,13 +1477,13 @@ let Predicates = [IsISA3_1] in {
VXForm_1<207, (outs vrrc:$VD), (ins vrrc:$VDi, u4imm:$VA, gprc:$VB),
"vinsw $VD, $VB, $VA", IIC_VecGeneral,
[(set v4i32:$VD,
- (int_ppc_altivec_vinsw v4i32:$VDi, i32:$VB, timm:$VA))]>,
+ (int_ppc_altivec_vinsw v4i32:$VDi, i32:$VB, u4imm_timm:$VA))]>,
RegConstraint<"$VDi = $VD">;
def VINSD :
VXForm_1<463, (outs vrrc:$VD), (ins vrrc:$VDi, u4imm:$VA, g8rc:$VB),
"vinsd $VD, $VB, $VA", IIC_VecGeneral,
[(set v2i64:$VD,
- (int_ppc_altivec_vinsd v2i64:$VDi, i64:$VB, timm:$VA))]>,
+ (int_ppc_altivec_vinsd v2i64:$VDi, i64:$VB, u4imm_timm:$VA))]>,
RegConstraint<"$VDi = $VD">;
def VINSBVLX :
VXForm_VTB5_RA5_ins<15, "vinsbvlx",
@@ -1730,7 +1730,7 @@ let Predicates = [IsISA3_1] in {
def VGNB : VXForm_RD5_N3_VB5<1228, (outs g8rc:$RD), (ins vrrc:$VB, u3imm:$N),
"vgnb $RD, $VB, $N", IIC_VecGeneral,
[(set i64:$RD,
- (int_ppc_altivec_vgnb v1i128:$VB, timm:$N))]>;
+ (int_ppc_altivec_vgnb v1i128:$VB, u3imm_timm:$N))]>;
def CFUGED : XForm_6<31, 220, (outs g8rc:$RA), (ins g8rc:$RST, g8rc:$RB),
"cfuged $RA, $RST, $RB", IIC_IntGeneral,
[(set i64:$RA, (int_ppc_cfuged i64:$RST, i64:$RB))]>;
@@ -1739,7 +1739,7 @@ let Predicates = [IsISA3_1] in {
vsrc:$XC, u8imm:$IMM),
"xxeval $XT, $XA, $XB, $XC, $IMM", IIC_VecGeneral,
[(set v2i64:$XT, (int_ppc_vsx_xxeval v2i64:$XA,
- v2i64:$XB, v2i64:$XC, timm:$IMM))]>;
+ v2i64:$XB, v2i64:$XC, u8imm_timm:$IMM))]>;
def VCLZDM : VXForm_1<1924, (outs vrrc:$VD), (ins vrrc:$VA, vrrc:$VB),
"vclzdm $VD, $VA, $VB", IIC_VecGeneral,
[(set v2i64:$VD,
@@ -2762,7 +2762,7 @@ let Predicates = [PrefixInstrs, HasP10Vector] in {
def : Pat<(i32 imm34:$imm), (PLI (getImmAs64BitInt imm:$imm))>;
def : Pat<(i64 imm34:$imm), (PLI8 (getImmAs64BitInt imm:$imm))>;
- def : Pat<(v16i8 (int_ppc_vsx_xxpermx v16i8:$A, v16i8:$B, v16i8:$C, timm:$D)),
+ def : Pat<(v16i8 (int_ppc_vsx_xxpermx v16i8:$A, v16i8:$B, v16i8:$C, u3imm_timm:$D)),
(COPY_TO_REGCLASS (XXPERMX (COPY_TO_REGCLASS $A, VSRC),
(COPY_TO_REGCLASS $B, VSRC),
(COPY_TO_REGCLASS $C, VSRC), $D), VSRC)>;
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index 8fd016394ec04..fde7a645e8e4a 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -173,14 +173,22 @@ defm u1imm : UnsignedImmediate<i32,
[{ return isUInt<1>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U1Imm", 1>;
defm u2imm : UnsignedImmediate<i32,
[{ return isUInt<2>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U2Imm", 2>;
-def u3imm : UnsignedImmOp<i32, "U3Imm", 3>;
-def u4imm : UnsignedImmOp<i32, "U4Imm", 4>;
-def u5imm : UnsignedImmOp<i32, "U5Imm", 5>;
-def u6imm : UnsignedImmOp<i32, "U6Imm", 6>;
-def u7imm : UnsignedImmOp<i32, "U7Imm", 7>;
-def u8imm : UnsignedImmOp<i32, "U8Imm", 8>;
-def u10imm : UnsignedImmOp<i32, "U10Imm", 10>;
-def u12imm : UnsignedImmOp<i32, "U12Imm", 12>;
+defm u3imm : UnsignedImmediate<i32,
+ [{ return isUInt<3>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U3Imm", 3>;
+defm u4imm : UnsignedImmediate<i32,
+ [{ return isUInt<4>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U4Imm", 4>;
+defm u5imm : UnsignedImmediate<i32,
+ [{ return isUInt<5>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U5Imm", 5>;
+defm u6imm : UnsignedImmediate<i32,
+ [{ return isUInt<6>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U6Imm", 6>;
+defm u7imm : UnsignedImmediate<i32,
+ [{ return isUInt<7>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U7Imm", 7>;
+defm u8imm : UnsignedImmediate<i32,
+ [{ return isUInt<8>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U8Imm", 8>;
+defm u10imm : UnsignedImmediate<i32,
+ [{ return isUInt<10>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U10Imm", 10>;
+defm u12imm : UnsignedImmediate<i32,
+ [{ return isUInt<12>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U12Imm", 12>;
def s5imm : SignedImmOp<i32, "S5Imm", 5>;
>From b9b4d31a903ca5443ae5dc000b856325262be3f1 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 2 Feb 2026 15:06:27 -0500
Subject: [PATCH 07/19] Simplify Immediate AsmOperand definitions
---
llvm/lib/Target/PowerPC/PPCOperands.td | 260 ++++++++++++-------------
1 file changed, 121 insertions(+), 139 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index fde7a645e8e4a..c568cd97a0934 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -1,4 +1,4 @@
-//===-- PPCOperands.td - PowerPC instruction operands ------*- tablegen -*-===//
+//===-- PPCOperands.td - PowerPC instruction operands -------*- tablegen -*-==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines PowerPC instruction operands, including immediate operands
-// and addressing modes.
+// This file defines PowerPC instruction operands, including immediate
+// operands and addressing modes.
//
//===----------------------------------------------------------------------===//
@@ -16,181 +16,153 @@
//===----------------------------------------------------------------------===//
// Base class for immediate AsmOperandClass definitions.
-class ImmediateAsmOperand : AsmOperandClass {
+class ImmediateAsmOperand<string predicate, string render="addImmOperands">
+: AsmOperandClass {
let Name = NAME;
- let RenderMethod = "addImmOperands";
-}
-
-// Base class for immediate AsmOperandClass with custom predicate.
-class ImmediateAsmOperandWithPredicate<string predicate> : ImmediateAsmOperand {
let PredicateMethod = predicate;
+ let RenderMethod = render;
}
-// Base class for unsigned immediate AsmOperandClass with templated predicate.
-class UnsignedImmAsmOperand<int width> : ImmediateAsmOperand {
- let PredicateMethod = "isUImm<" # width # ">";
-}
-
-// Base class for signed immediate AsmOperandClass with templated predicate.
-class SignedImmAsmOperand<int width> : ImmediateAsmOperand {
- let PredicateMethod = "isSImm<" # width # ">";
-}
-
-// Base class for immediate operands.
-class ImmediateOp<ValueType vt, string asmop, string decoder> : Operand<vt> {
+// Base class for immediate operands without encoder.
+class ImmediateOp<ValueType vt, string asmop, int width, bit is_signed = 0,
+ string decoder = ""> : Operand<vt> {
let PrintMethod = "print"#asmop#"Operand";
let ParserMatchClass = !cast<AsmOperandClass>(asmop);
- let DecoderMethod = decoder;
let OperandType = "OPERAND_IMMEDIATE";
-}
-
-// Immediate operand with pattern matching (combines Operand + PatLeaf).
-class ImmOpWithPattern<ValueType vt, string asmop, string decoder,
- code pred, SDNodeXForm xform, SDNode ImmNode = imm>
- : ImmediateOp<vt, asmop, decoder>, PatLeaf<(vt ImmNode), pred, xform>;
-
-// Unsigned immediate operand.
-class UnsignedImmOp<ValueType vt, string asmop, int width>
- : ImmediateOp<vt, asmop, "decodeUImmOperand<"#width#">">;
-
-// Unsigned immediate operand with pattern.
-class UnsignedImmOpWithPattern<ValueType vt, string asmop, int width,
- code pred, SDNodeXForm xform, SDNode ImmNode = imm>
- : ImmOpWithPattern<vt, asmop, "decodeUImmOperand<"#width#">", pred, xform, ImmNode>;
-
-// Unsigned immediate operand with encoder.
-class UnsignedImmOpWithEncoder<ValueType vt, string asmop, int width, string fixup>
- : UnsignedImmOp<vt, asmop, width> {
- let EncoderMethod = "getImmEncoding<" # fixup # ">";
-}
-
-// Signed immediate operand.
-class SignedImmOp<ValueType vt, string asmop, int width>
- : ImmediateOp<vt, asmop, "decodeSImmOperand<"#width#">">;
-
-// Signed immediate operand with pattern.
-class SignedImmOpWithPattern<ValueType vt, string asmop, int width,
- code pred, SDNodeXForm xform, SDNode ImmNode = imm>
- : ImmOpWithPattern<vt, asmop, "decodeSImmOperand<"#width#">", pred, xform, ImmNode>;
-// Signed immediate operand with encoder.
-class SignedImmOpWithEncoder<ValueType vt, string asmop, int width, string fixup>
- : SignedImmOp<vt, asmop, width> {
- let EncoderMethod = "getImmEncoding<" # fixup # ">";
+ // Set decoder method based on signedness if not explicitly provided
+ let DecoderMethod = !if(!eq(decoder, ""),
+ !if(is_signed,
+ "decodeSImmOperand<"#width#">",
+ "decodeUImmOperand<"#width#">"),
+ decoder);
}
-// Multiclass for unsigned immediate operands with both regular and PC-relative versions.
-multiclass UnsignedImmOpWithPCRel<ValueType vt, string asmop, int width,
- string fixup_imm, string fixup_pcrel> {
- def "" : UnsignedImmOpWithEncoder<vt, asmop, width, fixup_imm>;
- def _pcrel : UnsignedImmOpWithEncoder<vt, asmop, width, fixup_pcrel>;
+// Immediate operand with encoder method.
+class ImmediateOpWithEncoder<ValueType vt, string asmop, int width,
+ bit is_signed, string encoder,
+ string decoder = "">
+ : ImmediateOp<vt, asmop, width, is_signed, decoder> {
+ let EncoderMethod = "getImmEncoding<" # encoder # ">";
}
-// Multiclass for signed immediate operands with both regular and PC-relative versions.
+// Multiclass for signed immediate operands with both regular and
+// PC-relative versions.
multiclass SignedImmOpWithPCRel<ValueType vt, string asmop, int width,
- string fixup_imm, string fixup_pcrel> {
- def "" : SignedImmOpWithEncoder<vt, asmop, width, fixup_imm>;
- def _pcrel : SignedImmOpWithEncoder<vt, asmop, width, fixup_pcrel>;
+ string fixup_imm, string fixup_pcrel> {
+ def "" : ImmediateOpWithEncoder<vt, asmop, width, 1, fixup_imm>;
+ def _pcrel : ImmediateOpWithEncoder<vt, asmop, width, 1, fixup_pcrel>;
}
//===----------------------------------------------------------------------===//
-// Multiclasses for complete immediate definitions (AsmOperand + Operand + PatLeaf).
+// Multiclasses for complete immediate definitions
+// (AsmOperand + Operand + ImmLeaf).
//===----------------------------------------------------------------------===//
-// Creates Operand and separate PatLeaf definitions for unsigned immediates.
-// This approach keeps Operand and PatLeaf separate for GlobalISel compatibility.
-// while maintaining SystemZ-style organization and naming.
-multiclass UnsignedImmediate<ValueType vt, code pred, SDNodeXForm xform, string asmop, int width> {
+// Creates Operand and separate ImmLeaf definitions for unsigned immediates.
+// ImmLeaf is preferred over PatLeaf because it allows better code generator
+// reasoning and is FastISel-compatible. This approach keeps Operand and
+// ImmLeaf separate for GlobalISel compatibility while maintaining
+// SystemZ-style organization and naming.
+multiclass UnsignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
+ string asmop, int width, string encoder = ""> {
// Operand definition (for instruction operands).
- def "" : UnsignedImmOp<vt, asmop, width>;
+ if !eq(encoder, "") then {
+ def "" : ImmediateOp<vt, asmop, width, 0>;
+ } else {
+ def "" : ImmediateOpWithEncoder<vt, asmop, width, 0, encoder>;
+ }
- // PatLeaf for imm nodes (for DAG pattern matching).
- def _pat : PatLeaf<(vt imm), pred, xform>;
+ // ImmLeaf for imm nodes (for DAG pattern matching).
+ // Uses Imm (int64_t) for FastISel compatibility.
+ def _pat : ImmLeaf<vt, pred, xform>;
- // PatLeaf for timm nodes (for target-specific pattern matching, e.g., intrinsics).
- def _timm : PatLeaf<(vt timm), pred, xform>;
+ // TImmLeaf for timm nodes (for target-specific pattern matching,
+ // e.g., intrinsics).
+ def _timm : TImmLeaf<vt, pred, xform>;
}
-// Creates Operand and separate PatLeaf definitions for signed immediates.
-multiclass SignedImmediate<ValueType vt, code pred, SDNodeXForm xform, string asmop, int width> {
+// Creates Operand and separate ImmLeaf definitions for signed immediates.
+multiclass SignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
+ string asmop, int width, string encoder = ""> {
// Operand definition (for instruction operands)
- def "" : SignedImmOp<vt, asmop, width>;
+ if !eq(encoder, "") then {
+ def "" : ImmediateOp<vt, asmop, width, 1>;
+ } else {
+ def "" : ImmediateOpWithEncoder<vt, asmop, width, 1, encoder>;
+ }
- // PatLeaf for imm nodes (for DAG pattern matching).
- def _pat : PatLeaf<(vt imm), pred, xform>;
+ // ImmLeaf for imm nodes (for DAG pattern matching).
+ // Uses Imm (int64_t) for FastISel compatibility.
+ def _pat : ImmLeaf<vt, pred, xform>;
- // PatLeaf for timm nodes (for target-specific pattern matching, e.g., intrinsics).
- def _timm : PatLeaf<(vt timm), pred, xform>;
+ // TImmLeaf for timm nodes (for target-specific pattern matching,
+ // e.g., intrinsics).
+ def _timm : TImmLeaf<vt, pred, xform>;
}
//===----------------------------------------------------------------------===//
// Immediate AsmOperand definitions
//===----------------------------------------------------------------------===//
-
-def U1Imm : UnsignedImmAsmOperand<1>;
-def U2Imm : UnsignedImmAsmOperand<2>;
-def U3Imm : UnsignedImmAsmOperand<3>;
-def U4Imm : UnsignedImmAsmOperand<4>;
-def U5Imm : UnsignedImmAsmOperand<5>;
-def U6Imm : UnsignedImmAsmOperand<6>;
-def U7Imm : UnsignedImmAsmOperand<7>;
-def U8Imm : UnsignedImmAsmOperand<8>;
-def U10Imm : UnsignedImmAsmOperand<10>;
-def U12Imm : UnsignedImmAsmOperand<12>;
-
-def S5Imm : SignedImmAsmOperand<5>;
-
-// Special case: S32Imm and S34Imm have custom predicates that accept expressions.
-def S32Imm : ImmediateAsmOperandWithPredicate<"isS32Imm">;
-def S34Imm : ImmediateAsmOperandWithPredicate<"isS34Imm">;
-
-// Special case: S16Imm has custom render method.
-def S16Imm : ImmediateAsmOperandWithPredicate<"isS16Imm"> {
- let RenderMethod = "addS16ImmOperands";
-}
-
-// Special case: U16Imm has custom render method.
-def U16Imm : ImmediateAsmOperandWithPredicate<"isU16Imm"> {
- let RenderMethod = "addU16ImmOperands";
-}
-
-// Special case: S17Imm has custom predicate and render method.
-def S17Imm : ImmediateAsmOperandWithPredicate<"isS17Imm"> {
- let RenderMethod = "addS16ImmOperands";
-}
-
-// Special case: ATBitsAsHint has custom predicate.
-def ATBitsAsHint : ImmediateAsmOperandWithPredicate<"isATBitsAsHint">;
-
-// Special case: ImmZero has custom predicate.
-def ImmZero : ImmediateAsmOperandWithPredicate<"isImmZero">;
+def U1Imm : ImmediateAsmOperand<"isUImm<1>">;
+def U2Imm : ImmediateAsmOperand<"isUImm<2>">;
+def U3Imm : ImmediateAsmOperand<"isUImm<3>">;
+def U4Imm : ImmediateAsmOperand<"isUImm<4>">;
+def U5Imm : ImmediateAsmOperand<"isUImm<5>">;
+def U6Imm : ImmediateAsmOperand<"isUImm<6>">;
+def U7Imm : ImmediateAsmOperand<"isUImm<7>">;
+def U8Imm : ImmediateAsmOperand<"isUImm<8>">;
+def U10Imm : ImmediateAsmOperand<"isUImm<10>">;
+def U12Imm : ImmediateAsmOperand<"isUImm<12>">;
+def S5Imm : ImmediateAsmOperand<"isSImm<5>">;
+
+// Special cases that have custom predicate and/or render method.
+def ATBitsAsHint : ImmediateAsmOperand<"isATBitsAsHint">; //Predicate always fails.
+def ImmZero : ImmediateAsmOperand<"isImmZero">;
+def U16Imm : ImmediateAsmOperand<"isU16Imm","addU16ImmOperands">;
+def S16Imm : ImmediateAsmOperand<"isS16Imm","addS16ImmOperands">;
+def S17Imm : ImmediateAsmOperand<"isS17Imm","addS16ImmOperands">;
+def S32Imm : ImmediateAsmOperand<"isS32Imm">;
+def S34Imm : ImmediateAsmOperand<"isS34Imm">;
//===----------------------------------------------------------------------===//
// i32 immediate operands
//===----------------------------------------------------------------------===//
defm u1imm : UnsignedImmediate<i32,
- [{ return isUInt<1>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U1Imm", 1>;
+ [{ return isUInt<1>(Imm); }], NOOP_SDNodeXForm,
+ "U1Imm", 1>;
defm u2imm : UnsignedImmediate<i32,
- [{ return isUInt<2>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U2Imm", 2>;
+ [{ return isUInt<2>(Imm); }], NOOP_SDNodeXForm,
+ "U2Imm", 2>;
defm u3imm : UnsignedImmediate<i32,
- [{ return isUInt<3>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U3Imm", 3>;
+ [{ return isUInt<3>(Imm); }], NOOP_SDNodeXForm,
+ "U3Imm", 3>;
defm u4imm : UnsignedImmediate<i32,
- [{ return isUInt<4>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U4Imm", 4>;
+ [{ return isUInt<4>(Imm); }], NOOP_SDNodeXForm,
+ "U4Imm", 4>;
defm u5imm : UnsignedImmediate<i32,
- [{ return isUInt<5>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U5Imm", 5>;
+ [{ return isUInt<5>(Imm); }], NOOP_SDNodeXForm,
+ "U5Imm", 5>;
defm u6imm : UnsignedImmediate<i32,
- [{ return isUInt<6>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U6Imm", 6>;
+ [{ return isUInt<6>(Imm); }], NOOP_SDNodeXForm,
+ "U6Imm", 6>;
defm u7imm : UnsignedImmediate<i32,
- [{ return isUInt<7>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U7Imm", 7>;
+ [{ return isUInt<7>(Imm); }], NOOP_SDNodeXForm,
+ "U7Imm", 7>;
defm u8imm : UnsignedImmediate<i32,
- [{ return isUInt<8>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U8Imm", 8>;
+ [{ return isUInt<8>(Imm); }], NOOP_SDNodeXForm,
+ "U8Imm", 8>;
defm u10imm : UnsignedImmediate<i32,
- [{ return isUInt<10>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U10Imm", 10>;
+ [{ return isUInt<10>(Imm); }], NOOP_SDNodeXForm,
+ "U10Imm", 10>;
defm u12imm : UnsignedImmediate<i32,
- [{ return isUInt<12>(N->getZExtValue()); }], NOOP_SDNodeXForm, "U12Imm", 12>;
+ [{ return isUInt<12>(Imm); }], NOOP_SDNodeXForm,
+ "U12Imm", 12>;
-def s5imm : SignedImmOp<i32, "S5Imm", 5>;
+defm s5imm : SignedImmediate<i32,
+ [{ return isInt<5>(Imm); }], NOOP_SDNodeXForm,
+ "S5Imm", 5>;
// Special case: atimm has custom print method and no decoder.
def atimm : Operand<i32> {
@@ -208,25 +180,35 @@ def immZero : Operand<i32> {
}
// Special cases: s16imm and u16imm have custom encoder methods.
-def s16imm : SignedImmOpWithEncoder<i32, "S16Imm", 16, "PPC::fixup_ppc_half16">;
-def u16imm : UnsignedImmOpWithEncoder<i32, "U16Imm", 16, "PPC::fixup_ppc_half16">;
+defm s16imm : SignedImmediate<i32,
+ [{ return isInt<16>(Imm); }], NOOP_SDNodeXForm,
+ "S16Imm", 16, "PPC::fixup_ppc_half16">;
+defm u16imm : UnsignedImmediate<i32,
+ [{ return isUInt<16>(Imm); }], NOOP_SDNodeXForm,
+ "U16Imm", 16, "PPC::fixup_ppc_half16">;
//===----------------------------------------------------------------------===//
// i64 immediate operands
//===----------------------------------------------------------------------===//
-def s16imm64 : SignedImmOpWithEncoder<i64, "S16Imm", 16, "PPC::fixup_ppc_half16">;
-def u16imm64 : UnsignedImmOpWithEncoder<i64, "U16Imm", 16, "PPC::fixup_ppc_half16">;
+// Special handing for target matching.
+def s16imm64 : ImmediateOpWithEncoder<i64, "S16Imm", 16, 1, "PPC::fixup_ppc_half16">;
+def u16imm64 : ImmediateOpWithEncoder<i64, "U16Imm", 16, 0, "PPC::fixup_ppc_half16">;
// Special case: s17imm uses S16Imm print method but accepts wider range.
-def s17imm : SignedImmOpWithEncoder<i32, "S17Imm", 16, "PPC::fixup_ppc_half16"> {
+// This operand type is used for addis/lis to allow the assembler parser
+// to accept immediates in the range -65536..65535 for compatibility
+// with the GNU assembler. The operand is treated as 16-bit otherwise.
+def s17imm : ImmediateOpWithEncoder<i32, "S17Imm", 16, 1, "PPC::fixup_ppc_half16"> {
let PrintMethod = "printS16ImmOperand";
}
-def s17imm64 : SignedImmOpWithEncoder<i64, "S17Imm", 16, "PPC::fixup_ppc_half16"> {
+def s17imm64 : ImmediateOpWithEncoder<i64, "S17Imm", 16, 1, "PPC::fixup_ppc_half16"> {
let PrintMethod = "printS16ImmOperand";
}
defm s32imm : SignedImmOpWithPCRel<i64, "S32Imm", 32,
- "PPC::fixup_ppc_imm32", "PPC::fixup_ppc_pcrel32">;
+ "PPC::fixup_ppc_imm32",
+ "PPC::fixup_ppc_pcrel32">;
defm s34imm : SignedImmOpWithPCRel<i64, "S34Imm", 34,
- "PPC::fixup_ppc_imm34", "PPC::fixup_ppc_pcrel34">;
+ "PPC::fixup_ppc_imm34",
+ "PPC::fixup_ppc_pcrel34">;
>From 61fed850b0bb9ffb1e565c90d54e7638539d379c Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Tue, 3 Feb 2026 16:38:34 -0500
Subject: [PATCH 08/19] migrate over pcrel class and some code reorg
---
llvm/lib/Target/PowerPC/PPCInstr64Bit.td | 12 ++-
llvm/lib/Target/PowerPC/PPCInstrAltivec.td | 3 +-
llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td | 7 +-
llvm/lib/Target/PowerPC/PPCInstrInfo.td | 15 ++--
llvm/lib/Target/PowerPC/PPCInstrP10.td | 84 ++++++++++----------
llvm/lib/Target/PowerPC/PPCInstrVSX.td | 6 +-
llvm/lib/Target/PowerPC/PPCOperands.td | 81 +++++++++++--------
7 files changed, 114 insertions(+), 94 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
index 6f39f8b7b7225..2b62654b08986 100644
--- a/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
+++ b/llvm/lib/Target/PowerPC/PPCInstr64Bit.td
@@ -338,13 +338,15 @@ def LDAT_PSEUDO : PPCCustomInserterPseudo<
(outs g8rc:$dst),
(ins ptr_rc_nor0:$ptr, g8rc:$val, u5imm:$fc),
"#LDAT_PSEUDO",
- [(set i64:$dst, (int_ppc_amo_ldat ptr_rc_nor0:$ptr, g8rc:$val, timm:$fc))]>;
+ [(set i64:$dst, (int_ppc_amo_ldat ptr_rc_nor0:$ptr, g8rc:$val,
+ u5imm_timm:$fc))]>;
def LDAT_COND_PSEUDO : PPCCustomInserterPseudo <
(outs g8rc:$dst),
(ins ptr_rc_nor0:$ptr, u5imm:$fc),
"#LDAT_COND_PSEUDO",
- [(set i64:$dst, (int_ppc_amo_ldat_cond ptr_rc_nor0:$ptr, timm:$fc))]>;
+ [(set i64:$dst, (int_ppc_amo_ldat_cond ptr_rc_nor0:$ptr,
+ u5imm_timm:$fc))]>;
let Defs = [CR0], mayStore = 1, mayLoad = 0, hasSideEffects = 0 in {
def STDCX : XForm_1_memOp<31, 214, (outs), (ins g8rc:$RST, (memrr $RA, $RB):$addr),
@@ -412,9 +414,11 @@ def : Pat<(int_ppc_cmpxchg_i128 ForceXForm:$ptr,
g8rc:$new_hi))>;
let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
-def STDAT : XForm_base_r3xo_memOp<31, 742, (outs), (ins g8rc:$RST, ptr_rc_nor0:$RA, u5imm:$RB),
+def STDAT : XForm_base_r3xo_memOp<31, 742, (outs),
+ (ins g8rc:$RST, ptr_rc_nor0:$RA, u5imm:$RB),
"stdat $RST, $RA, $RB", IIC_LdStStore,
- [(PPCstat i64:$RST, ptr_rc_nor0:$RA, timm:$RB)]>, isPPC64,
+ [(PPCstat i64:$RST, ptr_rc_nor0:$RA,
+ u5imm_timm:$RB)]>, isPPC64,
Requires<[IsISA3_0]>;
let Interpretation64Bit = 1, isCodeGenOnly = 1 in {
diff --git a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
index e25e40290addd..156931a372136 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrAltivec.td
@@ -343,7 +343,8 @@ class VXBX_Int_Ty<bits<11> xo, string opc, Intrinsic IntID, ValueType Ty>
class VXCR_Int_Ty<bits<11> xo, string opc, Intrinsic IntID, ValueType Ty>
: VXForm_CR<xo, (outs vrrc:$VD), (ins vrrc:$VA, u1imm:$ST, u4imm:$SIX),
!strconcat(opc, " $VD, $VA, $ST, $SIX"), IIC_VecFP,
- [(set Ty:$VD, (IntID Ty:$VA, u1imm_timm:$ST, timm:$SIX))]>;
+ [(set Ty:$VD, (IntID Ty:$VA, u1imm_timm:$ST,
+ u4imm_timm:$SIX))]>;
//===----------------------------------------------------------------------===//
// Instruction Definitions.
diff --git a/llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td b/llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td
index 0f9fe3f4ac589..1b4b58f724bc8 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrFutureMMA.td
@@ -518,7 +518,8 @@ let Predicates = [MMA, IsISAFuture] in {
: XForm_ATp2_SR5<31, 15, 177, (outs dmrp:$ATp),
(ins dmrp:$ATpi, u5imm:$SR), "dmsha3hash $ATp, $SR",
[(set v2048i1:$ATp,
- (int_ppc_mma_dmsha3hash v2048i1:$ATpi, timm:$SR))]>,
+ (int_ppc_mma_dmsha3hash v2048i1:$ATpi,
+ u5imm_timm:$SR))]>,
RegConstraint<"$ATpi = $ATp">;
def DMXXSHAPAD
: XX2Form_AT3_XB6_ID2_E1_BL2<60, 421, (outs dmr:$AT),
@@ -592,8 +593,8 @@ let Predicates = [MMA, IsISAFuture] in {
(DMXVF16GERX2NN $ATi, $XAp, RCCp.BToVSRC)>;
// Cryptography Intrinsic
- def : Pat<(v1024i1 (int_ppc_mma_dmxxshapad v1024i1:$ATi, v16i8:$XB, timm:$ID,
- u1imm_timm:$E, timm:$BL)),
+ def : Pat<(v1024i1 (int_ppc_mma_dmxxshapad v1024i1:$ATi, v16i8:$XB,
+ u2imm_timm:$ID, u1imm_timm:$E, u2imm_timm:$BL)),
(DMXXSHAPAD $ATi, RCCp.BToVSRC, $ID, $E, $BL)>;
}
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 5a2b8ac6b67a6..9f27b56e60392 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -780,9 +780,6 @@ def getFPAs64BitIntLo : SDNodeXForm<fpimm, [{
return CurDAG->getTargetConstant(Lo, SDLoc(N), MVT::i32);
}]>;
-def imm34 : PatLeaf<(imm), [{
- return isInt<34>(N->getSExtValue());
-}]>;
def getImmAs64BitInt : SDNodeXForm<imm, [{
return getI64Imm(N->getSExtValue(), SDLoc(N));
@@ -1465,12 +1462,16 @@ multiclass Z22Form_FRTA5_SH6r<bits<6> opcode, bits<9> xo, dag OOL, dag IOL,
let hasCtrlDep = 1 in {
let Defs = [R1], Uses = [R1] in {
-def ADJCALLSTACKDOWN : PPCEmitTimePseudo<(outs), (ins u16imm:$amt1, u16imm:$amt2),
+def ADJCALLSTACKDOWN : PPCEmitTimePseudo<(outs),
+ (ins u16imm:$amt1, u16imm:$amt2),
"#ADJCALLSTACKDOWN $amt1 $amt2",
- [(callseq_start timm:$amt1, timm:$amt2)]>;
-def ADJCALLSTACKUP : PPCEmitTimePseudo<(outs), (ins u16imm:$amt1, u16imm:$amt2),
+ [(callseq_start u16imm_timm:$amt1,
+ u16imm_timm:$amt2)]>;
+def ADJCALLSTACKUP : PPCEmitTimePseudo<(outs),
+ (ins u16imm:$amt1, u16imm:$amt2),
"#ADJCALLSTACKUP $amt1 $amt2",
- [(callseq_end timm:$amt1, timm:$amt2)]>;
+ [(callseq_end u16imm_timm:$amt1,
+ u16imm_timm:$amt2)]>;
}
} // hasCtrlDep
diff --git a/llvm/lib/Target/PowerPC/PPCInstrP10.td b/llvm/lib/Target/PowerPC/PPCInstrP10.td
index 4e8f152dd9a7e..fdea9c5a4e0ba 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrP10.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrP10.td
@@ -657,18 +657,18 @@ def RCCp {
let Predicates = [PrefixInstrs] in {
let Interpretation64Bit = 1, isCodeGenOnly = 1 in {
defm PADDI8 :
- MLS_DForm_R_SI34_RTA5_p<14, (outs g8rc:$RT), (ins g8rc_nox0:$RA, s34imm:$SI),
- (ins immZero:$RA, s34imm_pcrel:$SI),
+ MLS_DForm_R_SI34_RTA5_p<14, (outs g8rc:$RT), (ins g8rc_nox0:$RA, s34imm64:$SI),
+ (ins immZero:$RA, s34imm64_pcrel:$SI),
"paddi $RT, $RA, $SI", IIC_LdStLFD>;
let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
def PLI8 : MLS_DForm_SI34_RT5<14, (outs g8rc:$RT),
- (ins s34imm:$SI),
+ (ins s34imm64:$SI),
"pli $RT, $SI", IIC_IntSimple, []>;
}
}
defm PADDI :
MLS_DForm_R_SI34_RTA5_p<14, (outs gprc:$RT), (ins gprc_nor0:$RA, s34imm:$SI),
- (ins immZero:$RA, s34imm_pcrel:$SI),
+ (ins immZero:$RA, s34imm64_pcrel:$SI),
"paddi $RT, $RA, $SI", IIC_LdStLFD>;
let isReMaterializable = 1, isAsCheapAsAMove = 1, isMoveImm = 1 in {
def PLI : MLS_DForm_SI34_RT5<14, (outs gprc:$RT),
@@ -681,59 +681,59 @@ let Predicates = [PrefixInstrs] in {
defm PLBZ8 :
MLS_DForm_R_SI34_RTA5_MEM_p<34, (outs g8rc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D), "plbz $RST, $addr",
+ (ins s34imm64_pcrel:$D), "plbz $RST, $addr",
"plbz $RST, $D", IIC_LdStLFD>;
defm PLHZ8 :
MLS_DForm_R_SI34_RTA5_MEM_p<40, (outs g8rc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D), "plhz $RST, $addr",
+ (ins s34imm64_pcrel:$D), "plhz $RST, $addr",
"plhz $RST, $D", IIC_LdStLFD>;
defm PLHA8 :
MLS_DForm_R_SI34_RTA5_MEM_p<42, (outs g8rc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D), "plha $RST, $addr",
+ (ins s34imm64_pcrel:$D), "plha $RST, $addr",
"plha $RST, $D", IIC_LdStLFD>;
defm PLWA8 :
8LS_DForm_R_SI34_RTA5_MEM_p<41, (outs g8rc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D),
+ (ins s34imm64_pcrel:$D),
"plwa $RST, $addr", "plwa $RST, $D", IIC_LdStLFD>;
defm PLWZ8 :
MLS_DForm_R_SI34_RTA5_MEM_p<32, (outs g8rc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D), "plwz $RST, $addr",
+ (ins s34imm64_pcrel:$D), "plwz $RST, $addr",
"plwz $RST, $D", IIC_LdStLFD>;
}
defm PLBZ :
MLS_DForm_R_SI34_RTA5_MEM_p<34, (outs gprc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D), "plbz $RST, $addr",
+ (ins s34imm64_pcrel:$D), "plbz $RST, $addr",
"plbz $RST, $D", IIC_LdStLFD>;
defm PLHZ :
MLS_DForm_R_SI34_RTA5_MEM_p<40, (outs gprc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D), "plhz $RST, $addr",
+ (ins s34imm64_pcrel:$D), "plhz $RST, $addr",
"plhz $RST, $D", IIC_LdStLFD>;
defm PLHA :
MLS_DForm_R_SI34_RTA5_MEM_p<42, (outs gprc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D), "plha $RST, $addr",
+ (ins s34imm64_pcrel:$D), "plha $RST, $addr",
"plha $RST, $D", IIC_LdStLFD>;
defm PLWZ :
MLS_DForm_R_SI34_RTA5_MEM_p<32, (outs gprc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D), "plwz $RST, $addr",
+ (ins s34imm64_pcrel:$D), "plwz $RST, $addr",
"plwz $RST, $D", IIC_LdStLFD>;
defm PLWA :
8LS_DForm_R_SI34_RTA5_MEM_p<41, (outs gprc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D),
+ (ins s34imm64_pcrel:$D),
"plwa $RST, $addr", "plwa $RST, $D",
IIC_LdStLFD>;
defm PLD :
8LS_DForm_R_SI34_RTA5_MEM_p<57, (outs g8rc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D),
+ (ins s34imm64_pcrel:$D),
"pld $RST, $addr", "pld $RST, $D",
IIC_LdStLFD>;
}
@@ -743,38 +743,38 @@ let Predicates = [PrefixInstrs] in {
defm PSTB8 :
MLS_DForm_R_SI34_RTA5_MEM_p<38, (outs), (ins g8rc:$RST, (memri34 $D, $RA):$addr),
(ins g8rc:$RST, (memri34_pcrel $D, $RA):$addr),
- (ins g8rc:$RST, s34imm_pcrel:$D),
+ (ins g8rc:$RST, s34imm64_pcrel:$D),
"pstb $RST, $addr", "pstb $RST, $D", IIC_LdStLFD>;
defm PSTH8 :
MLS_DForm_R_SI34_RTA5_MEM_p<44, (outs), (ins g8rc:$RST, (memri34 $D, $RA):$addr),
(ins g8rc:$RST, (memri34_pcrel $D, $RA):$addr),
- (ins g8rc:$RST, s34imm_pcrel:$D),
+ (ins g8rc:$RST, s34imm64_pcrel:$D),
"psth $RST, $addr", "psth $RST, $D", IIC_LdStLFD>;
defm PSTW8 :
MLS_DForm_R_SI34_RTA5_MEM_p<36, (outs), (ins g8rc:$RST, (memri34 $D, $RA):$addr),
(ins g8rc:$RST, (memri34_pcrel $D, $RA):$addr),
- (ins g8rc:$RST, s34imm_pcrel:$D),
+ (ins g8rc:$RST, s34imm64_pcrel:$D),
"pstw $RST, $addr", "pstw $RST, $D", IIC_LdStLFD>;
}
defm PSTB :
MLS_DForm_R_SI34_RTA5_MEM_p<38, (outs), (ins gprc:$RST, (memri34 $D, $RA):$addr),
(ins gprc:$RST, (memri34_pcrel $D, $RA):$addr),
- (ins gprc:$RST, s34imm_pcrel:$D),
+ (ins gprc:$RST, s34imm64_pcrel:$D),
"pstb $RST, $addr", "pstb $RST, $D", IIC_LdStLFD>;
defm PSTH :
MLS_DForm_R_SI34_RTA5_MEM_p<44, (outs), (ins gprc:$RST, (memri34 $D, $RA):$addr),
(ins gprc:$RST, (memri34_pcrel $D, $RA):$addr),
- (ins gprc:$RST, s34imm_pcrel:$D),
+ (ins gprc:$RST, s34imm64_pcrel:$D),
"psth $RST, $addr", "psth $RST, $D", IIC_LdStLFD>;
defm PSTW :
MLS_DForm_R_SI34_RTA5_MEM_p<36, (outs), (ins gprc:$RST, (memri34 $D, $RA):$addr),
(ins gprc:$RST, (memri34_pcrel $D, $RA):$addr),
- (ins gprc:$RST, s34imm_pcrel:$D),
+ (ins gprc:$RST, s34imm64_pcrel:$D),
"pstw $RST, $addr", "pstw $RST, $D", IIC_LdStLFD>;
defm PSTD :
8LS_DForm_R_SI34_RTA5_MEM_p<61, (outs), (ins g8rc:$RST, (memri34 $D, $RA):$addr),
(ins g8rc:$RST, (memri34_pcrel $D, $RA):$addr),
- (ins g8rc:$RST, s34imm_pcrel:$D),
+ (ins g8rc:$RST, s34imm64_pcrel:$D),
"pstd $RST, $addr", "pstd $RST, $D", IIC_LdStLFD>;
}
}
@@ -784,24 +784,24 @@ let Predicates = [PrefixInstrs, HasFPU] in {
defm PLFS :
MLS_DForm_R_SI34_RTA5_MEM_p<48, (outs f4rc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D), "plfs $RST, $addr",
+ (ins s34imm64_pcrel:$D), "plfs $RST, $addr",
"plfs $RST, $D", IIC_LdStLFD>;
defm PLFD :
MLS_DForm_R_SI34_RTA5_MEM_p<50, (outs f8rc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D), "plfd $RST, $addr",
+ (ins s34imm64_pcrel:$D), "plfd $RST, $addr",
"plfd $RST, $D", IIC_LdStLFD>;
}
let mayStore = 1, mayLoad = 0 in {
defm PSTFS :
MLS_DForm_R_SI34_RTA5_MEM_p<52, (outs), (ins f4rc:$RST, (memri34 $D, $RA):$addr),
(ins f4rc:$RST, (memri34_pcrel $D, $RA):$addr),
- (ins f4rc:$RST, s34imm_pcrel:$D),
+ (ins f4rc:$RST, s34imm64_pcrel:$D),
"pstfs $RST, $addr", "pstfs $RST, $D", IIC_LdStLFD>;
defm PSTFD :
MLS_DForm_R_SI34_RTA5_MEM_p<54, (outs), (ins f8rc:$RST, (memri34 $D, $RA):$addr),
(ins f8rc:$RST, (memri34_pcrel $D, $RA):$addr),
- (ins f8rc:$RST, s34imm_pcrel:$D),
+ (ins f8rc:$RST, s34imm64_pcrel:$D),
"pstfd $RST, $addr", "pstfd $RST, $D", IIC_LdStLFD>;
}
}
@@ -811,18 +811,18 @@ let Predicates = [PrefixInstrs, HasP10Vector] in {
defm PLXV :
8LS_DForm_R_SI34_XT6_RA5_MEM_p<25, (outs vsrc:$XST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D),
+ (ins s34imm64_pcrel:$D),
"plxv $XST, $addr", "plxv $XST, $D", IIC_LdStLFD>;
defm PLXSSP :
8LS_DForm_R_SI34_RTA5_MEM_p<43, (outs vfrc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D),
+ (ins s34imm64_pcrel:$D),
"plxssp $RST, $addr", "plxssp $RST, $D",
IIC_LdStLFD>;
defm PLXSD :
8LS_DForm_R_SI34_RTA5_MEM_p<42, (outs vfrc:$RST), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D),
+ (ins s34imm64_pcrel:$D),
"plxsd $RST, $addr", "plxsd $RST, $D",
IIC_LdStLFD>;
}
@@ -830,17 +830,17 @@ let Predicates = [PrefixInstrs, HasP10Vector] in {
defm PSTXV :
8LS_DForm_R_SI34_XT6_RA5_MEM_p<27, (outs), (ins vsrc:$XST, (memri34 $D, $RA):$addr),
(ins vsrc:$XST, (memri34_pcrel $D, $RA):$addr),
- (ins vsrc:$XST, s34imm_pcrel:$D),
+ (ins vsrc:$XST, s34imm64_pcrel:$D),
"pstxv $XST, $addr", "pstxv $XST, $D", IIC_LdStLFD>;
defm PSTXSSP :
8LS_DForm_R_SI34_RTA5_MEM_p<47, (outs), (ins vfrc:$RST, (memri34 $D, $RA):$addr),
(ins vfrc:$RST, (memri34_pcrel $D, $RA):$addr),
- (ins vfrc:$RST, s34imm_pcrel:$D),
+ (ins vfrc:$RST, s34imm64_pcrel:$D),
"pstxssp $RST, $addr", "pstxssp $RST, $D", IIC_LdStLFD>;
defm PSTXSD :
8LS_DForm_R_SI34_RTA5_MEM_p<46, (outs), (ins vfrc:$RST, (memri34 $D, $RA):$addr),
(ins vfrc:$RST, (memri34_pcrel $D, $RA):$addr),
- (ins vfrc:$RST, s34imm_pcrel:$D),
+ (ins vfrc:$RST, s34imm64_pcrel:$D),
"pstxsd $RST, $addr", "pstxsd $RST, $D", IIC_LdStLFD>;
}
def XXPERMX :
@@ -1189,7 +1189,7 @@ let mayLoad = 1, mayStore = 0, Predicates = [PairedVectorMemops, PrefixInstrs, H
defm PLXVP :
8LS_DForm_R_XTp5_SI34_MEM_p<58, (outs vsrprc:$XTp), (ins (memri34 $D, $RA):$addr),
(ins (memri34_pcrel $D, $RA):$addr),
- (ins s34imm_pcrel:$D),
+ (ins s34imm64_pcrel:$D),
"plxvp $XTp, $addr", "plxvp $XTp, $D",
IIC_LdStLFD>;
}
@@ -1198,7 +1198,7 @@ let mayLoad = 0, mayStore = 1, Predicates = [PairedVectorMemops, PrefixInstrs, H
defm PSTXVP :
8LS_DForm_R_XTp5_SI34_MEM_p<62, (outs), (ins vsrprc:$XTp, (memri34 $D, $RA):$addr),
(ins vsrprc:$XTp, (memri34_pcrel $D, $RA):$addr),
- (ins vsrprc:$XTp, s34imm_pcrel:$D),
+ (ins vsrprc:$XTp, s34imm64_pcrel:$D),
"pstxvp $XTp, $addr", "pstxvp $XTp, $D", IIC_LdStLFD>;
}
@@ -2760,8 +2760,8 @@ let Predicates = [PrefixInstrs, HasP10Vector] in {
}
- def : Pat<(i32 imm34:$imm), (PLI (getImmAs64BitInt imm:$imm))>;
- def : Pat<(i64 imm34:$imm), (PLI8 (getImmAs64BitInt imm:$imm))>;
+ def : Pat<(i32 s34imm_pat:$imm), (PLI (getImmAs64BitInt imm:$imm))>;
+ def : Pat<(i64 s34imm64_pat:$imm), (PLI8 (getImmAs64BitInt imm:$imm))>;
def : Pat<(v16i8 (int_ppc_vsx_xxpermx v16i8:$A, v16i8:$B, v16i8:$C, u3imm_timm:$D)),
(COPY_TO_REGCLASS (XXPERMX (COPY_TO_REGCLASS $A, VSRC),
(COPY_TO_REGCLASS $B, VSRC),
@@ -2964,26 +2964,26 @@ let Predicates = [IsISA3_1] in {
def : InstAlias<"stcisync", (SYNCP10 0, 2)>;
def : InstAlias<"stsync", (SYNCP10 0, 3)>;
- def : InstAlias<"paddi $RT, $RA, $SI", (PADDI8 g8rc:$RT, g8rc_nox0:$RA, s34imm:$SI)>;
+ def : InstAlias<"paddi $RT, $RA, $SI", (PADDI8 g8rc:$RT, g8rc_nox0:$RA, s34imm64:$SI)>;
}
let Predicates = [IsISA3_1, PrefixInstrs], isAsmParserOnly = 1, hasNoSchedulingInfo = 1 in {
let Interpretation64Bit = 1 in {
def PLA8 : MLS_DForm_SI34_RT5<14, (outs g8rc:$RT),
- (ins g8rc_nox0:$RA, s34imm:$SI),
+ (ins g8rc_nox0:$RA, s34imm64:$SI),
"pla $RT, ${SI} ${RA}", IIC_IntSimple, []>, MemriOp;
def PLA8pc : MLS_DForm_SI34_RT5<14, (outs g8rc:$RT),
- (ins s34imm_pcrel:$SI),
+ (ins s34imm64_pcrel:$SI),
"pla $RT, $SI", IIC_IntSimple, []>, isPCRel;
}
def PSUBI : PPCAsmPseudo<"psubi $RT, $RA, $SI",
- (ins g8rc:$RT, g8rc_nox0:$RA, s34imm:$SI)>;
+ (ins g8rc:$RT, g8rc_nox0:$RA, s34imm64:$SI)>;
def PLA : MLS_DForm_SI34_RT5<14, (outs gprc:$RT),
- (ins gprc_nor0:$RA, s34imm:$SI),
+ (ins gprc_nor0:$RA, s34imm64:$SI),
"pla $RT, ${SI} ${RA}", IIC_IntSimple, []>, MemriOp;
def PLApc : MLS_DForm_SI34_RT5<14, (outs gprc:$RT),
- (ins s34imm_pcrel:$SI),
+ (ins s34imm64_pcrel:$SI),
"pla $RT, $SI", IIC_IntSimple, []>, isPCRel;
}
diff --git a/llvm/lib/Target/PowerPC/PPCInstrVSX.td b/llvm/lib/Target/PowerPC/PPCInstrVSX.td
index 01cc8059f6924..81ab59657c71e 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrVSX.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrVSX.td
@@ -1657,12 +1657,14 @@ let Predicates = [HasVSX, HasP9Vector] in {
(outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
"xvtstdcsp $XT, $XB, $DCMX", IIC_VecFP,
[(set v4i32: $XT,
- (int_ppc_vsx_xvtstdcsp v4f32:$XB, timm:$DCMX))]>;
+ (int_ppc_vsx_xvtstdcsp v4f32:$XB,
+ u7imm_timm:$DCMX))]>;
def XVTSTDCDP : XX2_RD6_DCMX7_RS6<60, 15, 5,
(outs vsrc:$XT), (ins u7imm:$DCMX, vsrc:$XB),
"xvtstdcdp $XT, $XB, $DCMX", IIC_VecFP,
[(set v2i64: $XT,
- (int_ppc_vsx_xvtstdcdp v2f64:$XB, timm:$DCMX))]>;
+ (int_ppc_vsx_xvtstdcdp v2f64:$XB,
+ u7imm_timm:$DCMX))]>;
// Maximum/Minimum Type-C/Type-J DP
let mayRaiseFPException = 1 in {
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index c568cd97a0934..d1d900a05060d 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -46,14 +46,6 @@ class ImmediateOpWithEncoder<ValueType vt, string asmop, int width,
let EncoderMethod = "getImmEncoding<" # encoder # ">";
}
-// Multiclass for signed immediate operands with both regular and
-// PC-relative versions.
-multiclass SignedImmOpWithPCRel<ValueType vt, string asmop, int width,
- string fixup_imm, string fixup_pcrel> {
- def "" : ImmediateOpWithEncoder<vt, asmop, width, 1, fixup_imm>;
- def _pcrel : ImmediateOpWithEncoder<vt, asmop, width, 1, fixup_pcrel>;
-}
-
//===----------------------------------------------------------------------===//
// Multiclasses for complete immediate definitions
// (AsmOperand + Operand + ImmLeaf).
@@ -62,8 +54,7 @@ multiclass SignedImmOpWithPCRel<ValueType vt, string asmop, int width,
// Creates Operand and separate ImmLeaf definitions for unsigned immediates.
// ImmLeaf is preferred over PatLeaf because it allows better code generator
// reasoning and is FastISel-compatible. This approach keeps Operand and
-// ImmLeaf separate for GlobalISel compatibility while maintaining
-// SystemZ-style organization and naming.
+// ImmLeaf separate for GlobalISel compatibility.
multiclass UnsignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
string asmop, int width, string encoder = ""> {
// Operand definition (for instruction operands).
@@ -74,11 +65,9 @@ multiclass UnsignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
}
// ImmLeaf for imm nodes (for DAG pattern matching).
- // Uses Imm (int64_t) for FastISel compatibility.
def _pat : ImmLeaf<vt, pred, xform>;
- // TImmLeaf for timm nodes (for target-specific pattern matching,
- // e.g., intrinsics).
+ // TImmLeaf for timm nodes (for target-specific pattern matching eg: intrinsics).
def _timm : TImmLeaf<vt, pred, xform>;
}
@@ -93,14 +82,25 @@ multiclass SignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
}
// ImmLeaf for imm nodes (for DAG pattern matching).
- // Uses Imm (int64_t) for FastISel compatibility.
def _pat : ImmLeaf<vt, pred, xform>;
- // TImmLeaf for timm nodes (for target-specific pattern matching,
- // e.g., intrinsics).
+ // TImmLeaf for timm nodes (for target-specific pattern matching eg: intrinsics).
def _timm : TImmLeaf<vt, pred, xform>;
}
+// Multiclass for signed immediate operands with both regular and
+// PC-relative versions.
+multiclass SignedImmediateWithPCRel<ValueType vt, code pred,
+ SDNodeXForm xform, string asmop,
+ int width, string fixup_imm,
+ string fixup_pcrel> {
+ // Regular immediate: instantiate SignedImmediate with regular fixup
+ defm "" : SignedImmediate<vt, pred, xform, asmop, width, fixup_imm>;
+
+ // PC-relative immediate: instantiate SignedImmediate with PC-relative fixup
+ defm _pcrel : SignedImmediate<vt, pred, xform, asmop, width, fixup_pcrel>;
+}
+
//===----------------------------------------------------------------------===//
// Immediate AsmOperand definitions
//===----------------------------------------------------------------------===//
@@ -116,7 +116,7 @@ def U10Imm : ImmediateAsmOperand<"isUImm<10>">;
def U12Imm : ImmediateAsmOperand<"isUImm<12>">;
def S5Imm : ImmediateAsmOperand<"isSImm<5>">;
-// Special cases that have custom predicate and/or render method.
+// Special cases that have custom predicat and/or render method.
def ATBitsAsHint : ImmediateAsmOperand<"isATBitsAsHint">; //Predicate always fails.
def ImmZero : ImmediateAsmOperand<"isImmZero">;
def U16Imm : ImmediateAsmOperand<"isU16Imm","addU16ImmOperands">;
@@ -164,14 +164,29 @@ defm s5imm : SignedImmediate<i32,
[{ return isInt<5>(Imm); }], NOOP_SDNodeXForm,
"S5Imm", 5>;
-// Special case: atimm has custom print method and no decoder.
-def atimm : Operand<i32> {
- let PrintMethod = "printATBitsAsHint";
- let ParserMatchClass = ATBitsAsHint;
- let OperandType = "OPERAND_IMMEDIATE";
-}
+defm s32imm : SignedImmediateWithPCRel<i32,
+ [{ return isInt<32>(Imm); }], NOOP_SDNodeXForm,
+ "S32Imm", 32, "PPC::fixup_ppc_imm32", "PPC::fixup_ppc_pcrel32">;
+defm s34imm : SignedImmediate<i32,
+ [{ return isInt<34>(Imm); }], NOOP_SDNodeXForm,
+ "S34Imm", 34, "PPC::fixup_ppc_imm34">;
+
+//===----------------------------------------------------------------------===//
+// i64 immediate operands
+//===----------------------------------------------------------------------===//
+
+defm s32imm64 : SignedImmediateWithPCRel<i64,
+ [{ return isInt<32>(Imm); }], NOOP_SDNodeXForm,
+ "S32Imm", 32, "PPC::fixup_ppc_imm32", "PPC::fixup_ppc_pcrel32">;
+defm s34imm64 : SignedImmediateWithPCRel<i64,
+ [{ return isInt<34>(Imm); }], NOOP_SDNodeXForm,
+ "S34Imm", 34, "PPC::fixup_ppc_imm34", "PPC::fixup_ppc_pcrel34">;
+
+//===----------------------------------------------------------------------===//
+// Special case immediate operands
+//===----------------------------------------------------------------------===//
-// Special case: immZero has custom print and decoder methods.
+// immZero has custom print and decoder methods.
def immZero : Operand<i32> {
let PrintMethod = "printImmZeroOperand";
let ParserMatchClass = ImmZero;
@@ -179,6 +194,13 @@ def immZero : Operand<i32> {
let OperandType = "OPERAND_IMMEDIATE";
}
+// Special case: atimm has custom print method and no decoder.
+def atimm : Operand<i32> {
+ let PrintMethod = "printATBitsAsHint";
+ let ParserMatchClass = ATBitsAsHint;
+ let OperandType = "OPERAND_IMMEDIATE";
+}
+
// Special cases: s16imm and u16imm have custom encoder methods.
defm s16imm : SignedImmediate<i32,
[{ return isInt<16>(Imm); }], NOOP_SDNodeXForm,
@@ -187,10 +209,6 @@ defm u16imm : UnsignedImmediate<i32,
[{ return isUInt<16>(Imm); }], NOOP_SDNodeXForm,
"U16Imm", 16, "PPC::fixup_ppc_half16">;
-//===----------------------------------------------------------------------===//
-// i64 immediate operands
-//===----------------------------------------------------------------------===//
-
// Special handing for target matching.
def s16imm64 : ImmediateOpWithEncoder<i64, "S16Imm", 16, 1, "PPC::fixup_ppc_half16">;
def u16imm64 : ImmediateOpWithEncoder<i64, "U16Imm", 16, 0, "PPC::fixup_ppc_half16">;
@@ -205,10 +223,3 @@ def s17imm : ImmediateOpWithEncoder<i32, "S17Imm", 16, 1, "PPC::fixup_ppc_half16
def s17imm64 : ImmediateOpWithEncoder<i64, "S17Imm", 16, 1, "PPC::fixup_ppc_half16"> {
let PrintMethod = "printS16ImmOperand";
}
-
-defm s32imm : SignedImmOpWithPCRel<i64, "S32Imm", 32,
- "PPC::fixup_ppc_imm32",
- "PPC::fixup_ppc_pcrel32">;
-defm s34imm : SignedImmOpWithPCRel<i64, "S34Imm", 34,
- "PPC::fixup_ppc_imm34",
- "PPC::fixup_ppc_pcrel34">;
>From 8938008997b84238ecebc98bbc9d947b75ac7a49 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Tue, 3 Feb 2026 21:19:07 -0500
Subject: [PATCH 09/19] In these test cases: * CodeGen/PowerPC/pr52894.ll *
CodeGen/PowerPC/pr52894-32bit.ll
callseq_end is receiving a TargetConstant (524320) but our pattern expects
u16imm_timm. The value 524320 is larger than what a u16imm can hold
(max 65535), so it's being passed as a TargetConstant instead of matching our
pattern.
ADJCALLSTACKUP and ADJCALLSTACKDOWN need to accept values larger than 16 bits
but seems it's currently setup to take u16imm. Not sure what's going on
here, reverting so we don't regress current behaviour.
---
llvm/lib/Target/PowerPC/PPCInstrInfo.td | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 9f27b56e60392..206c02b899640 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -1465,13 +1465,11 @@ let Defs = [R1], Uses = [R1] in {
def ADJCALLSTACKDOWN : PPCEmitTimePseudo<(outs),
(ins u16imm:$amt1, u16imm:$amt2),
"#ADJCALLSTACKDOWN $amt1 $amt2",
- [(callseq_start u16imm_timm:$amt1,
- u16imm_timm:$amt2)]>;
+ [(callseq_start timm:$amt1, timm:$amt2)]>;
def ADJCALLSTACKUP : PPCEmitTimePseudo<(outs),
(ins u16imm:$amt1, u16imm:$amt2),
"#ADJCALLSTACKUP $amt1 $amt2",
- [(callseq_end u16imm_timm:$amt1,
- u16imm_timm:$amt2)]>;
+ [(callseq_end timm:$amt1, timm:$amt2)]>;
}
} // hasCtrlDep
>From a327f93c7ae5e039dc1b10981ac21a4d4474a2c2 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Tue, 3 Feb 2026 21:36:00 -0500
Subject: [PATCH 10/19] merge the 2 operand class into one remove unnecessary
pcrel imm
---
llvm/lib/Target/PowerPC/PPCInstrFuture.td | 8 +--
llvm/lib/Target/PowerPC/PPCOperands.td | 70 +++++++++--------------
2 files changed, 31 insertions(+), 47 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCInstrFuture.td b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
index 39e6f4f139c11..eb56fea8c9888 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrFuture.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
@@ -380,13 +380,13 @@ let Predicates = [IsISAFuture] in {
let Predicates = [IsISAFuture, PrefixInstrs] in {
defm PADDIS : MLS_DForm_R_SI32_RTA5_p<15, (outs gprc:$RT),
- (ins gprc_nor0:$RA, s32imm:$SI),
- (ins immZero:$RA, s32imm_pcrel:$SI),
+ (ins gprc_nor0:$RA, s32imm64:$SI),
+ (ins immZero:$RA, s32imm64_pcrel:$SI),
"paddis $RT, $RA, $SI", IIC_LdStLFD>;
let Interpretation64Bit = 1, isCodeGenOnly = 1 in
defm PADDIS8 : MLS_DForm_R_SI32_RTA5_p<15, (outs g8rc:$RT),
- (ins g8rc_nox0:$RA, s32imm:$SI),
- (ins immZero:$RA, s32imm_pcrel:$SI),
+ (ins g8rc_nox0:$RA, s32imm64:$SI),
+ (ins immZero:$RA, s32imm64_pcrel:$SI),
"paddis $RT, $RA, $SI", IIC_LdStLFD>;
}
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index d1d900a05060d..083369ba13e8a 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -23,9 +23,9 @@ class ImmediateAsmOperand<string predicate, string render="addImmOperands">
let RenderMethod = render;
}
-// Base class for immediate operands without encoder.
+// Base class for immediate operands with optional encoder.
class ImmediateOp<ValueType vt, string asmop, int width, bit is_signed = 0,
- string decoder = ""> : Operand<vt> {
+ string encoder = "", string decoder = ""> : Operand<vt> {
let PrintMethod = "print"#asmop#"Operand";
let ParserMatchClass = !cast<AsmOperandClass>(asmop);
let OperandType = "OPERAND_IMMEDIATE";
@@ -36,14 +36,11 @@ class ImmediateOp<ValueType vt, string asmop, int width, bit is_signed = 0,
"decodeSImmOperand<"#width#">",
"decodeUImmOperand<"#width#">"),
decoder);
-}
-// Immediate operand with encoder method.
-class ImmediateOpWithEncoder<ValueType vt, string asmop, int width,
- bit is_signed, string encoder,
- string decoder = "">
- : ImmediateOp<vt, asmop, width, is_signed, decoder> {
- let EncoderMethod = "getImmEncoding<" # encoder # ">";
+ // Set encoder method if provided
+ let EncoderMethod = !if(!eq(encoder, ""),
+ "",
+ "getImmEncoding<" # encoder # ">");
}
//===----------------------------------------------------------------------===//
@@ -51,41 +48,31 @@ class ImmediateOpWithEncoder<ValueType vt, string asmop, int width,
// (AsmOperand + Operand + ImmLeaf).
//===----------------------------------------------------------------------===//
-// Creates Operand and separate ImmLeaf definitions for unsigned immediates.
-// ImmLeaf is preferred over PatLeaf because it allows better code generator
-// reasoning and is FastISel-compatible. This approach keeps Operand and
-// ImmLeaf separate for GlobalISel compatibility.
-multiclass UnsignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
- string asmop, int width, string encoder = ""> {
- // Operand definition (for instruction operands).
- if !eq(encoder, "") then {
- def "" : ImmediateOp<vt, asmop, width, 0>;
- } else {
- def "" : ImmediateOpWithEncoder<vt, asmop, width, 0, encoder>;
- }
-
- // ImmLeaf for imm nodes (for DAG pattern matching).
+// Helper multiclass that generates operand + patterns together while keeping
+// them as separate definitions for GlobalISel compatibility.
+multiclass ImmOpWithPatterns<ValueType vt, string asmop, int width,
+ bit is_signed, code pred, SDNodeXForm xform,
+ string encoder = ""> {
+ // Operand definition (for instruction operands)
+ def "" : ImmediateOp<vt, asmop, width, is_signed, encoder>;
+
+ // ImmLeaf for imm nodes (for DAG pattern matching)
def _pat : ImmLeaf<vt, pred, xform>;
- // TImmLeaf for timm nodes (for target-specific pattern matching eg: intrinsics).
+ // TImmLeaf for timm nodes (for target-specific pattern matching, e.g., intrinsics)
def _timm : TImmLeaf<vt, pred, xform>;
}
+// Creates Operand and separate ImmLeaf definitions for unsigned immediates.
+multiclass UnsignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
+ string asmop, int width, string encoder = ""> {
+ defm "" : ImmOpWithPatterns<vt, asmop, width, 0, pred, xform, encoder>;
+}
+
// Creates Operand and separate ImmLeaf definitions for signed immediates.
multiclass SignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
string asmop, int width, string encoder = ""> {
- // Operand definition (for instruction operands)
- if !eq(encoder, "") then {
- def "" : ImmediateOp<vt, asmop, width, 1>;
- } else {
- def "" : ImmediateOpWithEncoder<vt, asmop, width, 1, encoder>;
- }
-
- // ImmLeaf for imm nodes (for DAG pattern matching).
- def _pat : ImmLeaf<vt, pred, xform>;
-
- // TImmLeaf for timm nodes (for target-specific pattern matching eg: intrinsics).
- def _timm : TImmLeaf<vt, pred, xform>;
+ defm "" : ImmOpWithPatterns<vt, asmop, width, 1, pred, xform, encoder>;
}
// Multiclass for signed immediate operands with both regular and
@@ -164,9 +151,6 @@ defm s5imm : SignedImmediate<i32,
[{ return isInt<5>(Imm); }], NOOP_SDNodeXForm,
"S5Imm", 5>;
-defm s32imm : SignedImmediateWithPCRel<i32,
- [{ return isInt<32>(Imm); }], NOOP_SDNodeXForm,
- "S32Imm", 32, "PPC::fixup_ppc_imm32", "PPC::fixup_ppc_pcrel32">;
defm s34imm : SignedImmediate<i32,
[{ return isInt<34>(Imm); }], NOOP_SDNodeXForm,
"S34Imm", 34, "PPC::fixup_ppc_imm34">;
@@ -210,16 +194,16 @@ defm u16imm : UnsignedImmediate<i32,
"U16Imm", 16, "PPC::fixup_ppc_half16">;
// Special handing for target matching.
-def s16imm64 : ImmediateOpWithEncoder<i64, "S16Imm", 16, 1, "PPC::fixup_ppc_half16">;
-def u16imm64 : ImmediateOpWithEncoder<i64, "U16Imm", 16, 0, "PPC::fixup_ppc_half16">;
+def s16imm64 : ImmediateOp<i64, "S16Imm", 16, 1, "PPC::fixup_ppc_half16">;
+def u16imm64 : ImmediateOp<i64, "U16Imm", 16, 0, "PPC::fixup_ppc_half16">;
// Special case: s17imm uses S16Imm print method but accepts wider range.
// This operand type is used for addis/lis to allow the assembler parser
// to accept immediates in the range -65536..65535 for compatibility
// with the GNU assembler. The operand is treated as 16-bit otherwise.
-def s17imm : ImmediateOpWithEncoder<i32, "S17Imm", 16, 1, "PPC::fixup_ppc_half16"> {
+def s17imm : ImmediateOp<i32, "S17Imm", 16, 1, "PPC::fixup_ppc_half16"> {
let PrintMethod = "printS16ImmOperand";
}
-def s17imm64 : ImmediateOpWithEncoder<i64, "S17Imm", 16, 1, "PPC::fixup_ppc_half16"> {
+def s17imm64 : ImmediateOp<i64, "S17Imm", 16, 1, "PPC::fixup_ppc_half16"> {
let PrintMethod = "printS16ImmOperand";
}
>From d09b116eaa46ce6d988524540af1d3973957bc96 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Wed, 4 Feb 2026 14:40:30 -0500
Subject: [PATCH 11/19] simplify multiclass def
---
llvm/lib/Target/PowerPC/PPCOperands.td | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index 083369ba13e8a..2b995cfe4190c 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -65,25 +65,21 @@ multiclass ImmOpWithPatterns<ValueType vt, string asmop, int width,
// Creates Operand and separate ImmLeaf definitions for unsigned immediates.
multiclass UnsignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
- string asmop, int width, string encoder = ""> {
- defm "" : ImmOpWithPatterns<vt, asmop, width, 0, pred, xform, encoder>;
-}
+ string asmop, int width, string encoder = "">
+ : ImmOpWithPatterns<vt, asmop, width, 0, pred, xform, encoder>;
// Creates Operand and separate ImmLeaf definitions for signed immediates.
multiclass SignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
- string asmop, int width, string encoder = ""> {
- defm "" : ImmOpWithPatterns<vt, asmop, width, 1, pred, xform, encoder>;
-}
+ string asmop, int width, string encoder = "">
+ : ImmOpWithPatterns<vt, asmop, width, 1, pred, xform, encoder>;
// Multiclass for signed immediate operands with both regular and
// PC-relative versions.
multiclass SignedImmediateWithPCRel<ValueType vt, code pred,
SDNodeXForm xform, string asmop,
int width, string fixup_imm,
- string fixup_pcrel> {
- // Regular immediate: instantiate SignedImmediate with regular fixup
- defm "" : SignedImmediate<vt, pred, xform, asmop, width, fixup_imm>;
-
+ string fixup_pcrel>
+ : SignedImmediate<vt, pred, xform, asmop, width, fixup_imm> {
// PC-relative immediate: instantiate SignedImmediate with PC-relative fixup
defm _pcrel : SignedImmediate<vt, pred, xform, asmop, width, fixup_pcrel>;
}
>From 220db2a217bf3249ac4f25c984f6dbe1b29412cc Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Wed, 4 Feb 2026 18:09:31 -0500
Subject: [PATCH 12/19] update documentation for atimm and immZero
---
llvm/lib/Target/PowerPC/PPCOperands.td | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index 2b995cfe4190c..de8eba9aeae88 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -166,7 +166,10 @@ defm s34imm64 : SignedImmediateWithPCRel<i64,
// Special case immediate operands
//===----------------------------------------------------------------------===//
-// immZero has custom print and decoder methods.
+// immZero represents a hardcoded zero register encoding, it is NOT used in DAG
+// patterns. It is only used as an instruction operand for assembly/disassembly,
+// specifically to represent a hardcoded zero register value in PC-relative
+// addressing modes.
def immZero : Operand<i32> {
let PrintMethod = "printImmZeroOperand";
let ParserMatchClass = ImmZero;
@@ -174,7 +177,10 @@ def immZero : Operand<i32> {
let OperandType = "OPERAND_IMMEDIATE";
}
-// Special case: atimm has custom print method and no decoder.
+// atimm is used to represent branch prediction hints, not a general immediate
+// value. It's a 2-bit AT (Address Translation) field in PPC branch instructions
+// and is an assembly-only operand that prints as `+` or `-` symbols, not
+// numeric values.
def atimm : Operand<i32> {
let PrintMethod = "printATBitsAsHint";
let ParserMatchClass = ATBitsAsHint;
>From 39ca857a3cdd638fdee35bd2dd12ff89a68c4dc3 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Wed, 4 Feb 2026 19:00:52 -0500
Subject: [PATCH 13/19] update doc for 16imm
---
llvm/lib/Target/PowerPC/PPCOperands.td | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index de8eba9aeae88..824397c6d03d7 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -195,8 +195,12 @@ defm u16imm : UnsignedImmediate<i32,
[{ return isUInt<16>(Imm); }], NOOP_SDNodeXForm,
"U16Imm", 16, "PPC::fixup_ppc_half16">;
-// Special handing for target matching.
+// s16imm64 uses imm64SExt16 pattern to match the operand type.
def s16imm64 : ImmediateOp<i64, "S16Imm", 16, 1, "PPC::fixup_ppc_half16">;
+
+// u16imm64 uses two different patterns depending on the instruction context:
+// * immZExt16 - For low 16-bit immediates
+// * imm16ShiftedZExt - For high 16-bit immediates (shifted)
def u16imm64 : ImmediateOp<i64, "U16Imm", 16, 0, "PPC::fixup_ppc_half16">;
// Special case: s17imm uses S16Imm print method but accepts wider range.
>From b9e0bb1c141960e4e2c48f0928eaef0d2e16f4b8 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Fri, 6 Feb 2026 15:09:43 -0500
Subject: [PATCH 14/19] consolidate printU##Imm into a template function
---
.../PowerPC/MCTargetDesc/PPCInstPrinter.cpp | 87 +++----------------
.../PowerPC/MCTargetDesc/PPCInstPrinter.h | 27 ++----
llvm/lib/Target/PowerPC/PPCInstrVSX.td | 2 +-
llvm/lib/Target/PowerPC/PPCOperands.td | 12 ++-
4 files changed, 32 insertions(+), 96 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
index 46d6093be3c17..7bbeea39de532 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
@@ -323,35 +323,14 @@ void PPCInstPrinter::printATBitsAsHint(const MCInst *MI, unsigned OpNo,
O << "+";
}
-void PPCInstPrinter::printU1ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
- unsigned int Value = MI->getOperand(OpNo).getImm();
- assert(Value <= 1 && "Invalid u1imm argument!");
- O << (unsigned int)Value;
-}
-
-void PPCInstPrinter::printU2ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
- unsigned int Value = MI->getOperand(OpNo).getImm();
- assert(Value <= 3 && "Invalid u2imm argument!");
- O << (unsigned int)Value;
-}
-
-void PPCInstPrinter::printU3ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
- unsigned int Value = MI->getOperand(OpNo).getImm();
- assert(Value <= 8 && "Invalid u3imm argument!");
- O << (unsigned int)Value;
-}
-
-void PPCInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
+// Template for unsigned immediate operands with validation.
+// Validates that the value fits within the specified width and prints it.
+template<unsigned Width>
+void PPCInstPrinter::printUImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
unsigned int Value = MI->getOperand(OpNo).getImm();
- assert(Value <= 15 && "Invalid u4imm argument!");
+ assert(Value <= ((1U << Width) - 1) && "Invalid uimm argument!");
O << (unsigned int)Value;
}
@@ -371,56 +350,16 @@ void PPCInstPrinter::printImmZeroOperand(const MCInst *MI, unsigned OpNo,
O << (unsigned int)Value;
}
-void PPCInstPrinter::printU5ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
- unsigned int Value = MI->getOperand(OpNo).getImm();
- assert(Value <= 31 && "Invalid u5imm argument!");
- O << (unsigned int)Value;
-}
-
-void PPCInstPrinter::printU6ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
- unsigned int Value = MI->getOperand(OpNo).getImm();
- assert(Value <= 63 && "Invalid u6imm argument!");
- O << (unsigned int)Value;
-}
-
-void PPCInstPrinter::printU7ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
- unsigned int Value = MI->getOperand(OpNo).getImm();
- assert(Value <= 127 && "Invalid u7imm argument!");
- O << (unsigned int)Value;
-}
-
-// Operands of BUILD_VECTOR are signed and we use this to print operands
-// of XXSPLTIB which are unsigned. So we simply truncate to 8 bits and
-// print as unsigned.
-void PPCInstPrinter::printU8ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
+// Truncating version specifically for BUILD_VECTOR operands that may be
+// sign-extended (e.g., -1 becomes 0xFFFFFFFF). Truncates to 8 bits without
+// validation, unlike the standard printUImmOperand<8> which validates.
+void PPCInstPrinter::printU8ImmOperandTrunc(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
unsigned char Value = MI->getOperand(OpNo).getImm();
O << (unsigned int)Value;
}
-void PPCInstPrinter::printU10ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
- unsigned short Value = MI->getOperand(OpNo).getImm();
- assert(Value <= 1023 && "Invalid u10imm argument!");
- O << (unsigned short)Value;
-}
-
-void PPCInstPrinter::printU12ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
- unsigned short Value = MI->getOperand(OpNo).getImm();
- assert(Value <= 4095 && "Invalid u12imm argument!");
- O << (unsigned short)Value;
-}
-
void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
index 2fbd06c5a96cf..297bfb4b8a65f 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
@@ -56,28 +56,15 @@ class PPCInstPrinter : public MCInstPrinter {
void printATBitsAsHint(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
- void printU1ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU2ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU3ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU4ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
+ // Template for unsigned immediate operands with validation
+ template<unsigned Width>
+ void printUImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+
void printS5ImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
- void printU5ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU6ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU7ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU8ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU10ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
- void printU12ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
+ void printU8ImmOperandTrunc(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
void printS16ImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printS32ImmOperand(const MCInst *MI, unsigned OpNo,
diff --git a/llvm/lib/Target/PowerPC/PPCInstrVSX.td b/llvm/lib/Target/PowerPC/PPCInstrVSX.td
index 81ab59657c71e..1f6bccaf127b8 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrVSX.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrVSX.td
@@ -1707,7 +1707,7 @@ let Predicates = [HasVSX, HasP9Vector] in {
RegConstraint<"$XTi = $XT">;
// Vector Splat Immediate Byte
- def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm:$IMM8),
+ def XXSPLTIB : X_RD6_IMM8<60, 360, (outs vsrc:$XT), (ins u8imm_trunc:$IMM8),
"xxspltib $XT, $IMM8", IIC_VecPerm, []>;
// When adding new D-Form loads/stores, be sure to update the ImmToIdxMap in
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index 824397c6d03d7..afa255cde3ccd 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -26,7 +26,9 @@ class ImmediateAsmOperand<string predicate, string render="addImmOperands">
// Base class for immediate operands with optional encoder.
class ImmediateOp<ValueType vt, string asmop, int width, bit is_signed = 0,
string encoder = "", string decoder = ""> : Operand<vt> {
- let PrintMethod = "print"#asmop#"Operand";
+ let PrintMethod = !if(is_signed,
+ "print"#asmop#"Operand",
+ "printUImmOperand<"#width#">");
let ParserMatchClass = !cast<AsmOperandClass>(asmop);
let OperandType = "OPERAND_IMMEDIATE";
@@ -136,6 +138,14 @@ defm u7imm : UnsignedImmediate<i32,
defm u8imm : UnsignedImmediate<i32,
[{ return isUInt<8>(Imm); }], NOOP_SDNodeXForm,
"U8Imm", 8>;
+
+// Truncating version for BUILD_VECTOR operands that may be sign-extended.
+// Uses the same parser class as u8imm but with a truncating print method.
+def u8imm_trunc : Operand<i32> {
+ let PrintMethod = "printU8ImmOperandTrunc";
+ let ParserMatchClass = U8Imm;
+ let OperandType = "OPERAND_IMMEDIATE";
+}
defm u10imm : UnsignedImmediate<i32,
[{ return isUInt<10>(Imm); }], NOOP_SDNodeXForm,
"U10Imm", 10>;
>From 04fe65c62458d380201cc5d36ee6641852a63f4b Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Fri, 6 Feb 2026 16:28:36 -0500
Subject: [PATCH 15/19] separate actual imm with imm with relocation
---
.../PowerPC/MCTargetDesc/PPCInstPrinter.cpp | 11 +-
.../PowerPC/MCTargetDesc/PPCInstPrinter.h | 7 +-
llvm/lib/Target/PowerPC/PPCOperands.td | 110 ++++++++++--------
3 files changed, 75 insertions(+), 53 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
index 7bbeea39de532..48605b57ffacf 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
@@ -334,11 +334,14 @@ void PPCInstPrinter::printUImmOperand(const MCInst *MI, unsigned OpNo,
O << (unsigned int)Value;
}
-void PPCInstPrinter::printS5ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI,
- raw_ostream &O) {
+// Template for signed immediate operands with sign extension.
+// Sign-extends the value to the specified width and prints it.
+template<unsigned Width>
+void PPCInstPrinter::printSImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
int Value = MI->getOperand(OpNo).getImm();
- Value = SignExtend32<5>(Value);
+ Value = SignExtend32<Width>(Value);
O << (int)Value;
}
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
index 297bfb4b8a65f..51a8809f070fd 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
@@ -61,8 +61,11 @@ class PPCInstPrinter : public MCInstPrinter {
void printUImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
- void printS5ImmOperand(const MCInst *MI, unsigned OpNo,
- const MCSubtargetInfo &STI, raw_ostream &O);
+ // Template for signed immediate operands with sign extension
+ template<unsigned Width>
+ void printSImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI, raw_ostream &O);
+
void printU8ImmOperandTrunc(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printS16ImmOperand(const MCInst *MI, unsigned OpNo,
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index afa255cde3ccd..f7374ad801e8f 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -17,73 +17,89 @@
// Base class for immediate AsmOperandClass definitions.
class ImmediateAsmOperand<string predicate, string render="addImmOperands">
-: AsmOperandClass {
+ : AsmOperandClass {
let Name = NAME;
let PredicateMethod = predicate;
let RenderMethod = render;
}
-// Base class for immediate operands with optional encoder.
-class ImmediateOp<ValueType vt, string asmop, int width, bit is_signed = 0,
- string encoder = "", string decoder = ""> : Operand<vt> {
- let PrintMethod = !if(is_signed,
- "print"#asmop#"Operand",
- "printUImmOperand<"#width#">");
+// Base class for signed immediate operands.
+class ImmediateOp<ValueType vt, string asmop, int width> : Operand<vt> {
+ let PrintMethod = "printSImmOperand<"#width#">";
+ let DecoderMethod = "decodeSImmOperand<"#width#">";
let ParserMatchClass = !cast<AsmOperandClass>(asmop);
let OperandType = "OPERAND_IMMEDIATE";
+}
+
+// Base class for unsigned immediate operands.
+class UImmediateOp<ValueType vt, string asmop, int width>
+ : ImmediateOp<vt, asmop, width> {
+ let PrintMethod = "printUImmOperand<"#width#">";
+ let DecoderMethod = "decodeUImmOperand<"#width#">";
+}
- // Set decoder method based on signedness if not explicitly provided
+// Base class for signed immediate operands with relocation.
+class ImmediateRelocOp<ValueType vt, string asmop, int width, string fixup,
+ string decoder = ""> : Operand<vt> {
+ let PrintMethod = "print"#asmop#"Operand";
let DecoderMethod = !if(!eq(decoder, ""),
- !if(is_signed,
- "decodeSImmOperand<"#width#">",
- "decodeUImmOperand<"#width#">"),
+ "decodeSImmOperand<"#width#">",
decoder);
-
- // Set encoder method if provided
- let EncoderMethod = !if(!eq(encoder, ""),
- "",
- "getImmEncoding<" # encoder # ">");
+ let ParserMatchClass = !cast<AsmOperandClass>(asmop);
+ let EncoderMethod = "getImmEncoding<" # fixup # ">";
+ let OperandType = "OPERAND_IMMEDIATE";
}
+// Base class for unsigned immediate operands with relocation.
+class UImmediateRelocOp<ValueType vt, string asmop, int width, string fixup,
+ string decoder = "">
+ : ImmediateRelocOp<vt, asmop, width, fixup> {
+ let DecoderMethod = !if(!eq(decoder, ""),
+ "decodeUImmOperand<"#width#">",
+ decoder);
+}
//===----------------------------------------------------------------------===//
// Multiclasses for complete immediate definitions
// (AsmOperand + Operand + ImmLeaf).
//===----------------------------------------------------------------------===//
-// Helper multiclass that generates operand + patterns together while keeping
-// them as separate definitions for GlobalISel compatibility.
-multiclass ImmOpWithPatterns<ValueType vt, string asmop, int width,
- bit is_signed, code pred, SDNodeXForm xform,
- string encoder = ""> {
- // Operand definition (for instruction operands)
- def "" : ImmediateOp<vt, asmop, width, is_signed, encoder>;
-
- // ImmLeaf for imm nodes (for DAG pattern matching)
+multiclass SignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
+ string asmop, int width > {
+ def "" : ImmediateOp<vt, asmop, width>;
def _pat : ImmLeaf<vt, pred, xform>;
-
- // TImmLeaf for timm nodes (for target-specific pattern matching, e.g., intrinsics)
def _timm : TImmLeaf<vt, pred, xform>;
}
-// Creates Operand and separate ImmLeaf definitions for unsigned immediates.
multiclass UnsignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
- string asmop, int width, string encoder = "">
- : ImmOpWithPatterns<vt, asmop, width, 0, pred, xform, encoder>;
+ string asmop, int width > {
+ def "" : UImmediateOp<vt, asmop, width>;
+ def _pat : ImmLeaf<vt, pred, xform>;
+ def _timm : TImmLeaf<vt, pred, xform>;
+}
-// Creates Operand and separate ImmLeaf definitions for signed immediates.
-multiclass SignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
- string asmop, int width, string encoder = "">
- : ImmOpWithPatterns<vt, asmop, width, 1, pred, xform, encoder>;
+multiclass SignedImmediateReloc<ValueType vt, code pred, SDNodeXForm xform,
+ string asmop, int width, string fixup> {
+ def "" : ImmediateRelocOp<vt, asmop, width, fixup>;
+ def _pat : ImmLeaf<vt, pred, xform>;
+ def _timm : TImmLeaf<vt, pred, xform>;
+}
+
+// Helper multiclass for unsigned immediates with relocation fixup string.
+multiclass UnsignedImmediateReloc<ValueType vt, code pred, SDNodeXForm xform,
+ string asmop, int width, string fixup> {
+ def "" : UImmediateRelocOp<vt, asmop, width, fixup>;
+ def _pat : ImmLeaf<vt, pred, xform>;
+ def _timm : TImmLeaf<vt, pred, xform>;
+}
// Multiclass for signed immediate operands with both regular and
// PC-relative versions.
-multiclass SignedImmediateWithPCRel<ValueType vt, code pred,
- SDNodeXForm xform, string asmop,
- int width, string fixup_imm,
+multiclass SignedImmediateWithPCRel<ValueType vt, code pred, SDNodeXForm xform,
+ string asmop, int width, string fixup_imm,
string fixup_pcrel>
- : SignedImmediate<vt, pred, xform, asmop, width, fixup_imm> {
- // PC-relative immediate: instantiate SignedImmediate with PC-relative fixup
- defm _pcrel : SignedImmediate<vt, pred, xform, asmop, width, fixup_pcrel>;
+ : SignedImmediateReloc<vt, pred, xform, asmop, width, fixup_imm> {
+ // PC-relative immediate: instantiate with PC-relative fixup
+ defm _pcrel : SignedImmediateReloc<vt, pred, xform, asmop, width, fixup_pcrel>;
}
//===----------------------------------------------------------------------===//
@@ -157,7 +173,7 @@ defm s5imm : SignedImmediate<i32,
[{ return isInt<5>(Imm); }], NOOP_SDNodeXForm,
"S5Imm", 5>;
-defm s34imm : SignedImmediate<i32,
+defm s34imm : SignedImmediateReloc<i32,
[{ return isInt<34>(Imm); }], NOOP_SDNodeXForm,
"S34Imm", 34, "PPC::fixup_ppc_imm34">;
@@ -198,28 +214,28 @@ def atimm : Operand<i32> {
}
// Special cases: s16imm and u16imm have custom encoder methods.
-defm s16imm : SignedImmediate<i32,
+defm s16imm : SignedImmediateReloc<i32,
[{ return isInt<16>(Imm); }], NOOP_SDNodeXForm,
"S16Imm", 16, "PPC::fixup_ppc_half16">;
-defm u16imm : UnsignedImmediate<i32,
+defm u16imm : UnsignedImmediateReloc<i32,
[{ return isUInt<16>(Imm); }], NOOP_SDNodeXForm,
"U16Imm", 16, "PPC::fixup_ppc_half16">;
// s16imm64 uses imm64SExt16 pattern to match the operand type.
-def s16imm64 : ImmediateOp<i64, "S16Imm", 16, 1, "PPC::fixup_ppc_half16">;
+def s16imm64 : ImmediateRelocOp<i64, "S16Imm", 16, "PPC::fixup_ppc_half16">;
// u16imm64 uses two different patterns depending on the instruction context:
// * immZExt16 - For low 16-bit immediates
// * imm16ShiftedZExt - For high 16-bit immediates (shifted)
-def u16imm64 : ImmediateOp<i64, "U16Imm", 16, 0, "PPC::fixup_ppc_half16">;
+def u16imm64 : UImmediateRelocOp<i64, "U16Imm", 16, "PPC::fixup_ppc_half16">;
// Special case: s17imm uses S16Imm print method but accepts wider range.
// This operand type is used for addis/lis to allow the assembler parser
// to accept immediates in the range -65536..65535 for compatibility
// with the GNU assembler. The operand is treated as 16-bit otherwise.
-def s17imm : ImmediateOp<i32, "S17Imm", 16, 1, "PPC::fixup_ppc_half16"> {
+def s17imm : ImmediateRelocOp<i32, "S17Imm", 16, "PPC::fixup_ppc_half16"> {
let PrintMethod = "printS16ImmOperand";
}
-def s17imm64 : ImmediateOp<i64, "S17Imm", 16, 1, "PPC::fixup_ppc_half16"> {
+def s17imm64 : ImmediateRelocOp<i64, "S17Imm", 16, "PPC::fixup_ppc_half16"> {
let PrintMethod = "printS16ImmOperand";
}
>From b31f068e59f91b1eb442a12168a1fb9d1c7ed3a1 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Fri, 6 Feb 2026 17:25:34 -0500
Subject: [PATCH 16/19] simplify multiclass with patterns
---
llvm/lib/Target/PowerPC/PPCOperands.td | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index f7374ad801e8f..c6f6886ea11f4 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -63,33 +63,34 @@ class UImmediateRelocOp<ValueType vt, string asmop, int width, string fixup,
// (AsmOperand + Operand + ImmLeaf).
//===----------------------------------------------------------------------===//
-multiclass SignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
- string asmop, int width > {
- def "" : ImmediateOp<vt, asmop, width>;
+multiclass ImmPatterns<ValueType vt, code pred, SDNodeXForm xform> {
def _pat : ImmLeaf<vt, pred, xform>;
def _timm : TImmLeaf<vt, pred, xform>;
}
+multiclass SignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
+ string asmop, int width >
+ : ImmPatterns<vt, pred, xform> {
+ def "" : ImmediateOp<vt, asmop, width>;
+}
+
multiclass UnsignedImmediate<ValueType vt, code pred, SDNodeXForm xform,
- string asmop, int width > {
+ string asmop, int width >
+ : ImmPatterns<vt, pred, xform> {
def "" : UImmediateOp<vt, asmop, width>;
- def _pat : ImmLeaf<vt, pred, xform>;
- def _timm : TImmLeaf<vt, pred, xform>;
}
multiclass SignedImmediateReloc<ValueType vt, code pred, SDNodeXForm xform,
- string asmop, int width, string fixup> {
+ string asmop, int width, string fixup>
+ : ImmPatterns<vt, pred, xform> {
def "" : ImmediateRelocOp<vt, asmop, width, fixup>;
- def _pat : ImmLeaf<vt, pred, xform>;
- def _timm : TImmLeaf<vt, pred, xform>;
}
// Helper multiclass for unsigned immediates with relocation fixup string.
multiclass UnsignedImmediateReloc<ValueType vt, code pred, SDNodeXForm xform,
- string asmop, int width, string fixup> {
+ string asmop, int width, string fixup>
+ : ImmPatterns<vt, pred, xform> {
def "" : UImmediateRelocOp<vt, asmop, width, fixup>;
- def _pat : ImmLeaf<vt, pred, xform>;
- def _timm : TImmLeaf<vt, pred, xform>;
}
// Multiclass for signed immediate operands with both regular and
>From d3cbbe0bb7c21c7968e56b9a8ecfb1703ba0948e Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 9 Feb 2026 14:18:37 +0000
Subject: [PATCH 17/19] update doc
---
llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
index 51a8809f070fd..ace78db324897 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
@@ -56,12 +56,12 @@ class PPCInstPrinter : public MCInstPrinter {
void printATBitsAsHint(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
- // Template for unsigned immediate operands with validation
+ // Template for unsigned immediate operands with validation.
template<unsigned Width>
void printUImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
- // Template for signed immediate operands with sign extension
+ // Template for signed immediate operands with sign extension.
template<unsigned Width>
void printSImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
>From 58c8f44224d6a5d4c790a44518efbc0dec24ba30 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 9 Feb 2026 14:20:50 +0000
Subject: [PATCH 18/19] fix spacing
---
llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp | 4 ++--
llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
index 48605b57ffacf..0cf8dba4408e8 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
@@ -325,7 +325,7 @@ void PPCInstPrinter::printATBitsAsHint(const MCInst *MI, unsigned OpNo,
// Template for unsigned immediate operands with validation.
// Validates that the value fits within the specified width and prints it.
-template<unsigned Width>
+template <unsigned Width>
void PPCInstPrinter::printUImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
@@ -336,7 +336,7 @@ void PPCInstPrinter::printUImmOperand(const MCInst *MI, unsigned OpNo,
// Template for signed immediate operands with sign extension.
// Sign-extends the value to the specified width and prints it.
-template<unsigned Width>
+template <unsigned Width>
void PPCInstPrinter::printSImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
index ace78db324897..f6781b66756cf 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
@@ -57,12 +57,12 @@ class PPCInstPrinter : public MCInstPrinter {
const MCSubtargetInfo &STI, raw_ostream &O);
// Template for unsigned immediate operands with validation.
- template<unsigned Width>
+ template <unsigned Width>
void printUImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
// Template for signed immediate operands with sign extension.
- template<unsigned Width>
+ template <unsigned Width>
void printSImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
>From d6b5f5e43979cbcaf067ea4afb24ea1a52bf0eb1 Mon Sep 17 00:00:00 2001
From: Lei Huang <lei at ca.ibm.com>
Date: Mon, 9 Feb 2026 16:48:16 +0000
Subject: [PATCH 19/19] simplify u8imm_trunc def
---
llvm/lib/Target/PowerPC/PPCOperands.td | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/llvm/lib/Target/PowerPC/PPCOperands.td b/llvm/lib/Target/PowerPC/PPCOperands.td
index c6f6886ea11f4..76071f6d7b7bb 100644
--- a/llvm/lib/Target/PowerPC/PPCOperands.td
+++ b/llvm/lib/Target/PowerPC/PPCOperands.td
@@ -158,10 +158,8 @@ defm u8imm : UnsignedImmediate<i32,
// Truncating version for BUILD_VECTOR operands that may be sign-extended.
// Uses the same parser class as u8imm but with a truncating print method.
-def u8imm_trunc : Operand<i32> {
+def u8imm_trunc : UImmediateOp<i32, "U8Imm", 8> {
let PrintMethod = "printU8ImmOperandTrunc";
- let ParserMatchClass = U8Imm;
- let OperandType = "OPERAND_IMMEDIATE";
}
defm u10imm : UnsignedImmediate<i32,
[{ return isUInt<10>(Imm); }], NOOP_SDNodeXForm,
More information about the llvm-branch-commits
mailing list