[llvm] d39f524 - [PowerPC] Implement paddis (#161572)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 27 12:22:04 PST 2025
Author: Lei Huang
Date: 2025-11-27T15:22:00-05:00
New Revision: d39f5243f8df23392e1c493f7d607cd0074222b9
URL: https://github.com/llvm/llvm-project/commit/d39f5243f8df23392e1c493f7d607cd0074222b9
DIFF: https://github.com/llvm/llvm-project/commit/d39f5243f8df23392e1c493f7d607cd0074222b9.diff
LOG: [PowerPC] Implement paddis (#161572)
Added:
Modified:
llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
llvm/lib/Target/PowerPC/PPCInstrFuture.td
llvm/lib/Target/PowerPC/PPCRegisterInfo.td
llvm/test/MC/Disassembler/PowerPC/ppc-encoding-ISAFuture.txt
llvm/test/MC/Disassembler/PowerPC/ppc64le-encoding-ISAFuture.txt
llvm/test/MC/PowerPC/ppc-encoding-ISAFuture.s
llvm/test/MC/PowerPC/ppc64-errors.s
Removed:
################################################################################
diff --git a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
index 561a9c51b9cc2..b07f95018ca90 100644
--- a/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
+++ b/llvm/lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
@@ -365,6 +365,10 @@ struct PPCOperand : public MCParsedAsmOperand {
bool isS16ImmX4() const { return isExtImm<16>(/*Signed*/ true, 4); }
bool isS16ImmX16() const { return isExtImm<16>(/*Signed*/ true, 16); }
bool isS17Imm() const { return isExtImm<17>(/*Signed*/ true, 1); }
+ bool isS32Imm() const {
+ // TODO: Is ContextImmediate needed?
+ return Kind == Expression || isSImm<32>();
+ }
bool isS34Imm() const {
// Once the PC-Rel ABI is finalized, evaluate whether a 34-bit
// ContextImmediate is needed.
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
index 04b886ae74993..558351b515a2e 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp
@@ -47,6 +47,9 @@ static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) {
case PPC::fixup_ppc_half16ds:
case PPC::fixup_ppc_half16dq:
return Value & 0xfffc;
+ case PPC::fixup_ppc_pcrel32:
+ case PPC::fixup_ppc_imm32:
+ return Value & 0xffffffff;
case PPC::fixup_ppc_pcrel34:
case PPC::fixup_ppc_imm34:
return Value & 0x3ffffffff;
@@ -71,6 +74,8 @@ static unsigned getFixupKindNumBytes(unsigned Kind) {
case PPC::fixup_ppc_br24abs:
case PPC::fixup_ppc_br24_notoc:
return 4;
+ case PPC::fixup_ppc_pcrel32:
+ case PPC::fixup_ppc_imm32:
case PPC::fixup_ppc_pcrel34:
case PPC::fixup_ppc_imm34:
case FK_Data_8:
@@ -154,6 +159,8 @@ MCFixupKindInfo PPCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{"fixup_ppc_brcond14abs", 16, 14, 0},
{"fixup_ppc_half16", 0, 16, 0},
{"fixup_ppc_half16ds", 0, 14, 0},
+ {"fixup_ppc_pcrel32", 0, 32, 0},
+ {"fixup_ppc_imm32", 0, 32, 0},
{"fixup_ppc_pcrel34", 0, 34, 0},
{"fixup_ppc_imm34", 0, 34, 0},
{"fixup_ppc_nofixup", 0, 0, 0}};
@@ -166,6 +173,8 @@ MCFixupKindInfo PPCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
{"fixup_ppc_brcond14abs", 2, 14, 0},
{"fixup_ppc_half16", 0, 16, 0},
{"fixup_ppc_half16ds", 2, 14, 0},
+ {"fixup_ppc_pcrel32", 0, 32, 0},
+ {"fixup_ppc_imm32", 0, 32, 0},
{"fixup_ppc_pcrel34", 0, 34, 0},
{"fixup_ppc_imm34", 0, 34, 0},
{"fixup_ppc_nofixup", 0, 0, 0}};
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
index df0c666f5b113..4164b697649cd 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h
@@ -40,6 +40,12 @@ enum Fixups {
/// instrs like 'std'.
fixup_ppc_half16ds,
+ // A 32-bit fixup corresponding to PC-relative paddis.
+ fixup_ppc_pcrel32,
+
+ // A 32-bit fixup corresponding to Non-PC-relative paddis.
+ fixup_ppc_imm32,
+
// A 34-bit fixup corresponding to PC-relative paddi.
fixup_ppc_pcrel34,
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
index a2f981e861511..46d6093be3c17 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.cpp
@@ -430,6 +430,17 @@ void PPCInstPrinter::printS16ImmOperand(const MCInst *MI, unsigned OpNo,
printOperand(MI, OpNo, STI, O);
}
+void PPCInstPrinter::printS32ImmOperand(const MCInst *MI, unsigned OpNo,
+ const MCSubtargetInfo &STI,
+ raw_ostream &O) {
+ if (MI->getOperand(OpNo).isImm()) {
+ long long Value = MI->getOperand(OpNo).getImm();
+ assert(isInt<32>(Value) && "Invalid s32imm argument!");
+ O << (long long)Value;
+ } else
+ printOperand(MI, OpNo, STI, O);
+}
+
void PPCInstPrinter::printS34ImmOperand(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 01ff6255f2a03..2fbd06c5a96cf 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h
@@ -80,6 +80,8 @@ class PPCInstPrinter : public MCInstPrinter {
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,
+ const MCSubtargetInfo &STI, raw_ostream &O);
void printS34ImmOperand(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI, raw_ostream &O);
void printU16ImmOperand(const MCInst *MI, unsigned OpNo,
diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
index 81d8e94b660d7..b28304b07e1a3 100644
--- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
+++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
@@ -46,6 +46,7 @@ static void addFixup(SmallVectorImpl<MCFixup> &Fixups, uint32_t Offset,
case PPC::fixup_ppc_br24_notoc:
case PPC::fixup_ppc_brcond14:
case PPC::fixup_ppc_pcrel34:
+ case PPC::fixup_ppc_pcrel32:
PCRel = true;
}
Fixups.push_back(MCFixup::create(Offset, Value, Kind, PCRel));
diff --git a/llvm/lib/Target/PowerPC/PPCInstrFuture.td b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
index e417ffe6d3677..39e6f4f139c11 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrFuture.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrFuture.td
@@ -312,9 +312,41 @@ class 8RR_XX4Form_XTABC6_P<bits<6> opcode, dag OOL, dag IOL, string asmstr,
let Inst{63} = XT{5};
}
+class MLS_DForm_R_SI32_RTA5<bits<6> opcode, dag OOL, dag IOL, string asmstr,
+ InstrItinClass itin, list<dag> pattern>
+ : PI<1, opcode, OOL, IOL, asmstr, itin> {
+ bits<5> RT;
+ bits<5> RA;
+ bits<32> SI;
+
+ let Pattern = pattern;
+
+ // The prefix.
+ let Inst{6...7} = 2;
+ let Inst{8} = 0;
+ let Inst{11} = PCRel;
+ let Inst{16...31} = SI{31...16};
+
+ // The instruction.
+ let Inst{38...42} = RT;
+ let Inst{43...47} = RA;
+ let Inst{48...63} = SI{15...0};
+}
+
+multiclass MLS_DForm_R_SI32_RTA5_p<bits<6> opcode, dag OOL, dag IOL,
+ dag PCRel_IOL, string asmstr,
+ InstrItinClass itin> {
+ def NAME : MLS_DForm_R_SI32_RTA5<opcode, OOL, IOL, !strconcat(asmstr, ", 0"),
+ itin, []>;
+ def pc : MLS_DForm_R_SI32_RTA5<opcode, OOL, PCRel_IOL,
+ !strconcat(asmstr, ", 1"), itin, []>,
+ isPCRel;
+}
+
//-------------------------- Instruction definitions -------------------------//
// Predicate combinations available:
// [IsISAFuture]
+// [IsISAFuture, PrefixInstrs]
// [HasVSX, IsISAFuture]
// [HasVSX, PrefixInstrs, IsISAFuture]
@@ -346,6 +378,18 @@ 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),
+ "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),
+ "paddis $RT, $RA, $SI", IIC_LdStLFD>;
+}
+
let Predicates = [HasVSX, IsISAFuture] in {
let mayLoad = 1 in {
def LXVRL : XX1Form_memOp<31, 525, (outs vsrc:$XT),
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
index d6b13680a057e..e23914a050359 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td
@@ -808,6 +808,25 @@ def s17imm64 : Operand<i64> {
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";
diff --git a/llvm/test/MC/Disassembler/PowerPC/ppc-encoding-ISAFuture.txt b/llvm/test/MC/Disassembler/PowerPC/ppc-encoding-ISAFuture.txt
index b27a50d93f5b9..1024c6b546c4a 100644
--- a/llvm/test/MC/Disassembler/PowerPC/ppc-encoding-ISAFuture.txt
+++ b/llvm/test/MC/Disassembler/PowerPC/ppc-encoding-ISAFuture.txt
@@ -298,6 +298,12 @@
#CHECK: mtlpl 3, 4
0x7c,0x80,0x1a,0x26
+#CHECK: paddis 10, 12, 1000000000, 0
+0x06,0x00,0x3b,0x9a,0x3d,0x4c,0xca,0x00
+
+#CHECK: paddis 10, 0, 1000000000, 1
+0x06,0x10,0x3b,0x9a,0x3d,0x40,0xca,0x00
+
#CHECK: xxmulmul 8, 3, 4, 2
0xed,0x03,0x22,0x08
diff --git a/llvm/test/MC/Disassembler/PowerPC/ppc64le-encoding-ISAFuture.txt b/llvm/test/MC/Disassembler/PowerPC/ppc64le-encoding-ISAFuture.txt
index 72662d9736740..bda8d1e69442f 100644
--- a/llvm/test/MC/Disassembler/PowerPC/ppc64le-encoding-ISAFuture.txt
+++ b/llvm/test/MC/Disassembler/PowerPC/ppc64le-encoding-ISAFuture.txt
@@ -292,6 +292,12 @@
#CHECK: mtlpl 3, 4
0x26,0x1a,0x80,0x7c
+#CHECK: paddis 10, 12, 1000000000, 0
+0x9a,0x3b,0x00,0x06,0x00,0xca,0x4c,0x3d
+
+#CHECK: paddis 10, 0, 1000000000, 1
+0x9a,0x3b,0x10,0x06,0x00,0xca,0x40,0x3d
+
#CHECK: xxmulmul 8, 3, 4, 2
0x08,0x22,0x03,0xed
diff --git a/llvm/test/MC/PowerPC/ppc-encoding-ISAFuture.s b/llvm/test/MC/PowerPC/ppc-encoding-ISAFuture.s
index ab72649fc3404..eb616a15500f1 100644
--- a/llvm/test/MC/PowerPC/ppc-encoding-ISAFuture.s
+++ b/llvm/test/MC/PowerPC/ppc-encoding-ISAFuture.s
@@ -419,6 +419,18 @@
#CHECK-BE: mtlpl 3, 4 # encoding: [0x7c,0x80,0x1a,0x26]
#CHECK-LE: mtlpl 3, 4 # encoding: [0x26,0x1a,0x80,0x7c]
+ paddis 10, 12, 1000000000, 0
+#CHECK-BE: paddis 10, 12, 1000000000, 0 # encoding: [0x06,0x00,0x3b,0x9a,
+#CHECK-BE-SAME: 0x3d,0x4c,0xca,0x00]
+#CHECK-LE: paddis 10, 12, 1000000000, 0 # encoding: [0x9a,0x3b,0x00,0x06,
+#CHECK-LE-SAME: 0x00,0xca,0x4c,0x3d]
+
+ paddis 10, 0, 1000000000, 1
+#CHECK-BE: paddis 10, 0, 1000000000, 1 # encoding: [0x06,0x10,0x3b,0x9a,
+#CHECK-BE-SAME: 0x3d,0x40,0xca,0x00]
+#CHECK-LE: paddis 10, 0, 1000000000, 1 # encoding: [0x9a,0x3b,0x10,0x06,
+#CHECK-LE-SAME: 0x00,0xca,0x40,0x3d]
+
xxmulmul 8, 3, 4, 2
#CHECK-BE: xxmulmul 8, 3, 4, 2 # encoding: [0xed,0x03,0x22,0x08]
#CHECK-LE: xxmulmul 8, 3, 4, 2 # encoding: [0x08,0x22,0x03,0xed]
diff --git a/llvm/test/MC/PowerPC/ppc64-errors.s b/llvm/test/MC/PowerPC/ppc64-errors.s
index 8598174300e42..4d4da58f650fe 100644
--- a/llvm/test/MC/PowerPC/ppc64-errors.s
+++ b/llvm/test/MC/PowerPC/ppc64-errors.s
@@ -4,6 +4,11 @@
# RUN: not llvm-mc -triple powerpc64le-unknown-unknown < %s 2> %t
# RUN: FileCheck < %t %s
+# From ISAFuture
+
+# CHECK: error: invalid operand for instruction
+paddis 10, 5, 1000000000, 1
+
# From ISA31
# CHECK: error: invalid operand for instruction
More information about the llvm-commits
mailing list