[clang] [llvm] [RISCV] Support Base P RV32/64 Instructions (PR #150379)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 24 00:09:22 PDT 2025
https://github.com/realqhc created https://github.com/llvm/llvm-project/pull/150379
This patch supports RV32/64 extension instructions. The final patch split from the original pull request will add RV32 Only instructions with register pair operands.
Documentation:
https://jhauser.us/RISCV/ext-P/RVP-baseInstrs-014.pdf https://jhauser.us/RISCV/ext-P/RVP-instrEncodings-015.pdf
>From 389e2d27cdb779b91714fc3a46e4ba9f17761a89 Mon Sep 17 00:00:00 2001
From: Qihan Cai <caiqihan021 at hotmail.com>
Date: Fri, 18 Jul 2025 16:28:20 +1000
Subject: [PATCH] [RISCV] Support Base P RV32/64 Instructions
This patch supports RV32/64 extension instructions. The final patch split from the original pull request will add RV32 Only instructions with register pair operands.
Documentation:
https://jhauser.us/RISCV/ext-P/RVP-baseInstrs-014.pdf
https://jhauser.us/RISCV/ext-P/RVP-instrEncodings-015.pdf
---
.../Driver/print-supported-extensions-riscv.c | 2 +-
llvm/lib/Target/RISCV/RISCVFeatures.td | 2 +-
llvm/lib/Target/RISCV/RISCVInstrInfoP.td | 89 ++++++++++++++++++-
llvm/test/MC/RISCV/attribute-arch.s | 8 +-
llvm/test/MC/RISCV/rv32p-valid.s | 55 ++++++++++++
llvm/test/MC/RISCV/rv64p-valid.s | 72 +++++++++++++++
.../TargetParser/RISCVISAInfoTest.cpp | 2 +-
7 files changed, 222 insertions(+), 8 deletions(-)
diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c
index 2503f2473d64a..2e4d7cfa82c80 100644
--- a/clang/test/Driver/print-supported-extensions-riscv.c
+++ b/clang/test/Driver/print-supported-extensions-riscv.c
@@ -207,7 +207,7 @@
// CHECK-NEXT: xwchc 2.2 'Xwchc' (WCH/QingKe additional compressed opcodes)
// CHECK-EMPTY:
// CHECK-NEXT: Experimental extensions
-// CHECK-NEXT: p 0.14 'P' ('Base P' (Packed SIMD))
+// CHECK-NEXT: p 0.15 'P' ('Base P' (Packed SIMD))
// CHECK-NEXT: zicfilp 1.0 'Zicfilp' (Landing pad)
// CHECK-NEXT: zicfiss 1.0 'Zicfiss' (Shadow stack)
// CHECK-NEXT: zalasr 0.1 'Zalasr' (Load-Acquire and Store-Release Instructions)
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index f9c0b54be7a27..7fb8b68a4935c 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1069,7 +1069,7 @@ def HasStdExtSmctrOrSsctr : Predicate<"Subtarget->hasStdExtSmctrOrSsctr()">,
// Packed SIMD Extensions
def FeatureStdExtP
- : RISCVExperimentalExtension<0, 14,
+ : RISCVExperimentalExtension<0, 15,
"'Base P' (Packed SIMD)">;
def HasStdExtP : Predicate<"Subtarget->hasStdExtP()">,
AssemblerPredicate<(all_of FeatureStdExtP),
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
index dd365cfa1379b..5bb4d7bfed7e1 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -19,7 +19,6 @@
//===----------------------------------------------------------------------===//
def simm10 : RISCVSImmLeafOp<10>;
-
def SImm10UnsignedAsmOperand : SImmAsmOperand<10, "Unsigned"> {
let RenderMethod = "addSImm10UnsignedOperands";
}
@@ -98,6 +97,15 @@ class RVPShift_ri<bits<3> f, bits<3> funct3, string opcodestr, Operand ImmType>
let Inst{27} = 0b0;
}
+// N for non-packed RV64 instructions.
+class RVPShiftN_ri<bits<3> f, bits<3> funct3, string opcodestr>
+ : RVPShift_ri<f, funct3, opcodestr, uimm6> {
+ bits<6> shamt;
+
+ let Inst{26} = 0b1;
+ let Inst{25-20} = shamt;
+}
+
class RVPShiftW_ri<bits<3> f, bits<3> funct3, string opcodestr>
: RVPShift_ri<f, funct3, opcodestr, uimm5> {
bits<5> shamt;
@@ -131,6 +139,38 @@ class RVPUnary_ri<bits<2> w, bits<5> uf, string opcodestr>
let Inst{24-20} = uf;
}
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPBinaryScalar<bit bfr, bits<3> f, bit aft, bits<2> w, bits<3> funct3,
+ string opcodestr, RISCVOpcode Opcode = OPC_OP_32,
+ dag outs = (outs GPR:$rd), dag ins = (ins GPR:$rs1, GPR:$rs2),
+ string argstr = "$rd, $rs1, $rs2">
+ : RVInstRBase<funct3, Opcode, outs, ins, opcodestr, argstr> {
+ let Inst{31} = bfr;
+ let Inst{30-28} = f;
+ let Inst{27} = aft;
+ let Inst{26-25} = w;
+}
+
+class RVPBinaryScalar_rr<bits<3> f, bits<2> w, bits<3> funct3, string opcodestr,
+ RISCVOpcode Opcode = OPC_OP_IMM_32>
+ : RVPBinaryScalar<1, f, 1, w, funct3, opcodestr, Opcode>;
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPShiftScalar_rri<bit bfr, bits<3> f, bit aft, DAGOperand TyWUImm, string opcodestr,
+ bits<3> funct3>
+ : RVInstIBase<funct3, OPC_OP_IMM_32, (outs GPR:$rd),
+ (ins GPR:$rs1, TyWUImm:$wuimm), opcodestr, "$rd, $rs1, $wuimm"> {
+ bits<7> wuimm;
+
+ let Inst{31} = bfr;
+ let Inst{30-28} = f;
+ let Inst{27} = aft;
+ let Inst{26-20} = wuimm;
+}
+
+class RVPUnary1F0<bits<3> f, DAGOperand TyWUImm, string opcodestr>
+ : RVPShiftScalar_rri<1, f, 0, TyWUImm, opcodestr, 0b100>;
+
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
@@ -184,3 +224,50 @@ let Predicates = [HasStdExtP] in
def PLUI_H : PLUI_i<0b1111000, "plui.h">;
let Predicates = [HasStdExtP, IsRV64] in
def PLUI_W : PLUI_i<0b1111001, "plui.w">;
+
+let Predicates = [HasStdExtP] in {
+def PSLL_HS : RVPBinaryScalar_rr<0b000, 0b00, 0b010, "psll.hs">;
+def PSLL_BS : RVPBinaryScalar_rr<0b000, 0b10, 0b010, "psll.bs">;
+def PADD_HS : RVPBinaryScalar_rr<0b001, 0b00, 0b010, "padd.hs">;
+def PADD_BS : RVPBinaryScalar_rr<0b001, 0b10, 0b010, "padd.bs">;
+def PSSHA_HS : RVPBinaryScalar_rr<0b110, 0b00, 0b010, "pssha.hs">;
+def PSSHAR_HS : RVPBinaryScalar_rr<0b111, 0b00, 0b010, "psshar.hs">;
+} // Predicates = [HasStdExtP]
+let DecoderNamespace = "RV32Only",
+ Predicates = [HasStdExtP, IsRV32] in {
+def SSHA : RVPBinaryScalar_rr<0b110, 0b01, 0b010, "ssha">;
+def SSHAR : RVPBinaryScalar_rr<0b111, 0b01, 0b010, "sshar">;
+} // Predicates = [HasStdExtP, IsRV32]
+
+let Predicates = [HasStdExtP, IsRV64] in {
+def PSLL_WS : RVPBinaryScalar_rr<0b000, 0b01, 0b010, "psll.ws">;
+def PADD_WS : RVPBinaryScalar_rr<0b001, 0b01, 0b010, "padd.ws">;
+def PSSHA_WS : RVPBinaryScalar_rr<0b110, 0b01, 0b010, "pssha.ws">;
+def PSSHAR_WS : RVPBinaryScalar_rr<0b111, 0b01, 0b010, "psshar.ws">;
+def SHA : RVPBinaryScalar_rr<0b110, 0b11, 0b010, "sha">;
+def SHAR : RVPBinaryScalar_rr<0b111, 0b11, 0b010, "shar">;
+} // Predicates = [HasStdExtP, IsRV64]
+
+let Predicates = [HasStdExtP] in {
+def PSRLI_B : RVPShiftB_ri<0b000, 0b100, "psrli.b">;
+def PSRLI_H : RVPShiftH_ri<0b000, 0b100, "psrli.h">;
+def PUSATI_H : RVPShiftH_ri<0b010, 0b100, "pusati.h">;
+def PSRAI_B : RVPShiftB_ri<0b100, 0b100, "psrai.b">;
+def PSRAI_H : RVPShiftH_ri<0b100, 0b100, "psrai.h">;
+def PSRARI_H : RVPShiftH_ri<0b101, 0b100, "psrari.h">;
+def PSATI_H : RVPShiftH_ri<0b110, 0b100, "psati.h">;
+} // Predicates = [HasStdExtP]
+
+let DecoderNamespace = "RV32Only",
+ Predicates = [HasStdExtP, IsRV32] in {
+def USATI_RV32 : RVPShiftW_ri<0b010, 0b100, "usati">;
+def SRARI_RV32 : RVPShiftW_ri<0b101, 0b100, "srari">;
+def SATI_RV32 : RVPShiftW_ri<0b110, 0b100, "sati">;
+} // Predicates = [HasStdExtP, IsRV32]
+let Predicates = [HasStdExtP, IsRV64] in {
+def PSRLI_W : RVPShiftW_ri<0b000, 0b100, "psrli.w">;
+def PUSATI_W : RVPShiftW_ri<0b010, 0b100, "pusati.w">;
+def USATI_RV64 : RVPShiftN_ri<0b010, 0b100, "usati">;
+def SRARI_RV64 : RVPShiftN_ri<0b101, 0b100, "srari">;
+def SATI_RV64 : RVPShiftN_ri<0b110, 0b100, "sati">;
+} // Predicates = [HasStdExtP, IsRV64]
diff --git a/llvm/test/MC/RISCV/attribute-arch.s b/llvm/test/MC/RISCV/attribute-arch.s
index b7cd71264b785..765585d865328 100644
--- a/llvm/test/MC/RISCV/attribute-arch.s
+++ b/llvm/test/MC/RISCV/attribute-arch.s
@@ -492,8 +492,8 @@
.attribute arch, "rv32i_sdtrig1p0"
# CHECK: attribute 5, "rv32i2p1_sdtrig1p0"
-.attribute arch, "rv32i_p0p14"
-# CHECK: attribute 5, "rv32i2p1_p0p14"
+.attribute arch, "rv32i_p0p15"
+# CHECK: attribute 5, "rv32i2p1_p0p15"
-.attribute arch, "rv64i_p0p14"
-# CHECK: attribute 5, "rv64i2p1_p0p14"
+.attribute arch, "rv64i_p0p15"
+# CHECK: attribute 5, "rv64i2p1_p0p15"
diff --git a/llvm/test/MC/RISCV/rv32p-valid.s b/llvm/test/MC/RISCV/rv32p-valid.s
index ffff0f25642a3..61da5ab5b68d8 100644
--- a/llvm/test/MC/RISCV/rv32p-valid.s
+++ b/llvm/test/MC/RISCV/rv32p-valid.s
@@ -76,3 +76,58 @@ plui.h gp, 32
# CHECK-ASM-AND-OBJ: plui.h gp, -412
# CHECK-ASM: encoding: [0x9b,0x21,0x99,0xf0]
plui.h gp, 612
+# CHECK-ASM-AND-OBJ: psll.hs a0, a1, a2
+# CHECK-ASM: encoding: [0x1b,0xa5,0xc5,0x88]
+psll.hs a0, a1, a2
+# CHECK-ASM-AND-OBJ: psll.bs a3, a4, a5
+# CHECK-ASM: encoding: [0x9b,0x26,0xf7,0x8c]
+psll.bs a3, a4, a5
+# CHECK-ASM-AND-OBJ: padd.hs t0, t1, t2
+# CHECK-ASM: encoding: [0x9b,0x22,0x73,0x98]
+padd.hs t0, t1, t2
+# CHECK-ASM-AND-OBJ: padd.bs ra, a1, a2
+# CHECK-ASM: encoding: [0x9b,0xa0,0xc5,0x9c]
+padd.bs ra, a1, a2
+# CHECK-ASM-AND-OBJ: pssha.hs a3, a4, a5
+# CHECK-ASM: encoding: [0x9b,0x26,0xf7,0xe8]
+pssha.hs a3, a4, a5
+# CHECK-ASM-AND-OBJ: ssha gp, a4, a5
+# CHECK-ASM: encoding: [0x9b,0x21,0xf7,0xea]
+ssha gp, a4, a5
+# CHECK-ASM-AND-OBJ: psshar.hs a6, a7, a0
+# CHECK-ASM: encoding: [0x1b,0xa8,0xa8,0xf8]
+psshar.hs a6, a7, a0
+# CHECK-ASM-AND-OBJ: sshar t1, a7, a0
+# CHECK-ASM: encoding: [0x1b,0xa3,0xa8,0xfa]
+sshar t1, a7, a0
+# CHECK-ASM-AND-OBJ: psrli.b a1, a2, 0
+# CHECK-ASM: encoding: [0x9b,0x45,0x86,0x80]
+psrli.b a1, a2, 0
+# CHECK-ASM-AND-OBJ: psrli.h a0, a1, 1
+# CHECK-ASM: encoding: [0x1b,0xc5,0x15,0x81]
+psrli.h a0, a1, 1
+# CHECK-ASM-AND-OBJ: pusati.h a2, t1, 4
+# CHECK-ASM: encoding: [0x1b,0x46,0x43,0xa1]
+pusati.h a2, t1, 4
+# CHECK-ASM-AND-OBJ: usati a3, t2, 5
+# CHECK-ASM: encoding: [0x9b,0xc6,0x53,0xa2]
+usati a3, t2, 5
+# CHECK-ASM-AND-OBJ: psrai.b a4, a5, 0
+# CHECK-ASM: encoding: [0x1b,0xc7,0x87,0xc0]
+psrai.b a4, a5, 0
+# CHECK-ASM-AND-OBJ: psrai.h a6, a7, 2
+# CHECK-ASM: encoding: [0x1b,0xc8,0x28,0xc1]
+psrai.h a6, a7, 2
+# CHECK-ASM-AND-OBJ: psrari.h a0, a1, 1
+# CHECK-ASM: encoding: [0x1b,0xc5,0x15,0xd1]
+psrari.h a0, a1, 1
+# CHECK-ASM-AND-OBJ: srari a2, a3, 1
+# CHECK-ASM: encoding: [0x1b,0xc6,0x16,0xd2]
+srari a2, a3, 1
+# CHECK-ASM-AND-OBJ: psati.h a4, t0, 8
+# CHECK-ASM: encoding: [0x1b,0xc7,0x82,0xe1]
+psati.h a4, t0, 8
+# CHECK-ASM-AND-OBJ: sati a5, t1, 8
+# CHECK-ASM: encoding: [0x9b,0x47,0x83,0xe2]
+sati a5, t1, 8
+
diff --git a/llvm/test/MC/RISCV/rv64p-valid.s b/llvm/test/MC/RISCV/rv64p-valid.s
index a0d6eadfb6c30..fdf0816dbc688 100644
--- a/llvm/test/MC/RISCV/rv64p-valid.s
+++ b/llvm/test/MC/RISCV/rv64p-valid.s
@@ -106,3 +106,75 @@ plui.w a2, 1
# CHECK-ASM-AND-OBJ: plui.w a2, -1
# CHECK-ASM: encoding: [0x1b,0xa6,0xff,0xf3]
plui.w a2, 1023
+# CHECK-ASM-AND-OBJ: psll.hs s0, a2, s2
+# CHECK-ASM: encoding: [0x1b,0x24,0x26,0x89]
+psll.hs s0, a2, s2
+# CHECK-ASM-AND-OBJ: psll.bs a0, t3, t5
+# CHECK-ASM: encoding: [0x1b,0x25,0xee,0x8d]
+psll.bs a0, t3, t5
+# CHECK-ASM-AND-OBJ: padd.hs t1, a2, s0
+# CHECK-ASM: encoding: [0x1b,0x23,0x86,0x98]
+padd.hs t1, a2, s0
+# CHECK-ASM-AND-OBJ: padd.bs t3, t1, t3
+# CHECK-ASM: encoding: [0x1b,0x2e,0xc3,0x9d]
+padd.bs t3, t1, t3
+# CHECK-ASM-AND-OBJ: pssha.hs s0, t1, a2
+# CHECK-ASM: encoding: [0x1b,0x24,0xc3,0xe8]
+pssha.hs s0, t1, a2
+# CHECK-ASM-AND-OBJ: psshar.hs s2, t5, t3
+# CHECK-ASM: encoding: [0x1b,0x29,0xcf,0xf9]
+psshar.hs s2, t5, t3
+# CHECK-ASM-AND-OBJ: psll.ws s0, t1, a0
+# CHECK-ASM: encoding: [0x1b,0x24,0xa3,0x8a]
+psll.ws s0, t1, a0
+# CHECK-ASM-AND-OBJ: padd.ws s2, a2, a0
+# CHECK-ASM: encoding: [0x1b,0x29,0xa6,0x9a]
+padd.ws s2, a2, a0
+# CHECK-ASM-AND-OBJ: pssha.ws a4, a2, t1
+# CHECK-ASM: encoding: [0x1b,0x27,0x66,0xea]
+pssha.ws a4, a2, t1
+# CHECK-ASM-AND-OBJ: psshar.ws a2, a0, a4
+# CHECK-ASM: encoding: [0x1b,0x26,0xe5,0xfa]
+psshar.ws a2, a0, a4
+# CHECK-ASM-AND-OBJ: sha a0, t5, t5
+# CHECK-ASM: encoding: [0x1b,0x25,0xef,0xef]
+sha a0, t5, t5
+# CHECK-ASM-AND-OBJ: shar t5, t5, t3
+# CHECK-ASM: encoding: [0x1b,0x2f,0xcf,0xff]
+shar t5, t5, t3
+# CHECK-ASM-AND-OBJ: psrli.b t1, a0, 3
+# CHECK-ASM: encoding: [0x1b,0x43,0xb5,0x80]
+psrli.b t1, a0, 3
+# CHECK-ASM-AND-OBJ: psrli.h a4, s0, 5
+# CHECK-ASM: encoding: [0x1b,0x47,0x54,0x81]
+psrli.h a4, s0, 5
+# CHECK-ASM-AND-OBJ: pusati.h t3, s0, 7
+# CHECK-ASM: encoding: [0x1b,0x4e,0x74,0xa1]
+pusati.h t3, s0, 7
+# CHECK-ASM-AND-OBJ: psrai.b t1, t1, 1
+# CHECK-ASM: encoding: [0x1b,0x43,0x93,0xc0]
+psrai.b t1, t1, 1
+# CHECK-ASM-AND-OBJ: psrai.h a2, t5, 2
+# CHECK-ASM: encoding: [0x1b,0x46,0x2f,0xc1]
+psrai.h a2, t5, 2
+# CHECK-ASM-AND-OBJ: psrari.h t1, t5, 4
+# CHECK-ASM: encoding: [0x1b,0x43,0x4f,0xd1]
+psrari.h t1, t5, 4
+# CHECK-ASM-AND-OBJ: psati.h a2, s2, 6
+# CHECK-ASM: encoding: [0x1b,0x46,0x69,0xe1]
+psati.h a2, s2, 6
+# CHECK-ASM-AND-OBJ: psrli.w s2, a0, 2
+# CHECK-ASM: encoding: [0x1b,0x49,0x25,0x82]
+psrli.w s2, a0, 2
+# CHECK-ASM-AND-OBJ: pusati.w t3, a4, 4
+# CHECK-ASM: encoding: [0x1b,0x4e,0x47,0xa2]
+pusati.w t3, a4, 4
+# CHECK-ASM-AND-OBJ: usati s0, a2, 6
+# CHECK-ASM: encoding: [0x1b,0x44,0x66,0xa4]
+usati s0, a2, 6
+# CHECK-ASM-AND-OBJ: srari s0, a2, 1
+# CHECK-ASM: encoding: [0x1b,0x44,0x16,0xd4]
+srari s0, a2, 1
+# CHECK-ASM-AND-OBJ: sati s0, a2, 4
+# CHECK-ASM: encoding: [0x1b,0x44,0x46,0xe4]
+sati s0, a2, 4
\ No newline at end of file
diff --git a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
index 319538eaea135..51a820819e294 100644
--- a/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
+++ b/llvm/unittests/TargetParser/RISCVISAInfoTest.cpp
@@ -1178,7 +1178,7 @@ R"(All available -march extensions for RISC-V
xwchc 2.2
Experimental extensions
- p 0.14
+ p 0.15
zicfilp 1.0 This is a long dummy description
zicfiss 1.0
zalasr 0.1
More information about the llvm-commits
mailing list