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 <caiqihan...@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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits