-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[RISCV][MC] Implement MC for Base P extension #123271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-backend-risc-v Author: None (realqhc) ChangesThis proposed extension adds Packed-SIMD instructions for RV32 and RV64. Documentation: Patch is 152.72 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/123271.diff 15 Files Affected:
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index a1df0f7d686e62..89202a825fc643 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -335,6 +335,9 @@ The primary goal of experimental support is to assist in the process of ratifica
``experimental-svukte``
LLVM implements the `0.3 draft specification <https://github.com/riscv/riscv-isa-manual/pull/1564>`__.
+``experimental-p``, ``experimental-p``
+ LLVM implements the `012 specification <https://jhauser.us/RISCV/ext-P/RVP-baseInstrs-012.pdf>`__.
+
To use an experimental extension from `clang`, you must add `-menable-experimental-extensions` to the command line, and specify the exact version of the experimental extension you are using. To use an experimental extension with LLVM's internal developer tools (e.g. `llc`, `llvm-objdump`, `llvm-mc`), you must prefix the extension name with `experimental-`. Note that you don't need to specify the version with internal tools, and shouldn't include the `experimental-` prefix with `clang`.
Vendor Extensions
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 8177280044bf44..b941c2b15a0cb1 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -961,6 +961,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
+ bool isSImm10() const {
+ if (!isImm())
+ return false;
+ int64_t Imm;
+ RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+ bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+ return IsConstantImm && isInt<10>(fixImmediateForRV32(Imm, isRV64Imm())) &&
+ VK == RISCVMCExpr::VK_RISCV_None;
+ }
+
bool isSImm10Lsb0000NonZero() const {
if (!isImm())
return false;
@@ -1587,6 +1597,9 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, 4, (1 << 10) - 4,
"immediate must be a multiple of 4 bytes in the range");
+ case Match_InvalidSImm10:
+ return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
+ (1 << 9) - 1);
case Match_InvalidSImm10Lsb0000NonZero:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index ab04b09a7ad151..f4902099ddc3f7 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -314,6 +314,7 @@ enum OperandType : unsigned {
OPERAND_UIMM8_GE32,
OPERAND_UIMM9_LSB000,
OPERAND_UIMM10,
+ OPERAND_SIMM10,
OPERAND_UIMM10_LSB00_NONZERO,
OPERAND_UIMM11,
OPERAND_UIMM12,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index f721d7148526ba..f5832c648bff8d 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1016,6 +1016,38 @@ def HasStdExtSmctrOrSsctr : Predicate<"Subtarget->hasStdExtSmctrOrSsctr()">,
"'Smctr' (Control Transfer Records Machine Level) or "
"'Ssctr' (Control Transfer Records Supervisor Level)">;
+def FeatureStdExtP
+ : RISCVExperimentalExtension<"p", 1, 0,
+ "'Base P' (Packed SIMD)">;
+def HasStdExtP : Predicate<"Subtarget->hasStdExtP()">,
+ AssemblerPredicate<(all_of FeatureStdExtP),
+ "'Base P' (Packed SIMD)">;
+
+def HasStdExtZbaOrP
+ : Predicate<"Subtarget->hasStdExtZba() || Subtarget->hasStdExtP()">,
+ AssemblerPredicate<(any_of FeatureStdExtZba, FeatureStdExtP),
+ "'Zba' (Address Generation Instructions) or "
+ "'Base P' (Packed-SIMD)">;
+
+def HasStdExtZbbOrP
+ : Predicate<"Subtarget->hasStdExtZbb() || Subtarget->hasStdExtP()">,
+ AssemblerPredicate<(any_of FeatureStdExtZbb, FeatureStdExtP),
+ "'Zbb' (Basic Bit-Manipulation) or "
+ "'Base P' (Packed-SIMD)">;
+
+def HasStdExtZbkbOrP
+ : Predicate<"Subtarget->hasStdExtZbkb() || Subtarget->hasStdExtP()">,
+ AssemblerPredicate<(any_of FeatureStdExtZbkb, FeatureStdExtP),
+ "'Zbkb' (Bitmanip instructions for Cryptography) or "
+ "'Base P' (Packed-SIMD)">;
+
+def HasStdExtZbbOrZbkbOrP
+ : Predicate<"Subtarget->HasStdExtZbbOrZbkb()|| Subtarget->hasStdExtP()">,
+ AssemblerPredicate<(any_of FeatureStdExtZbb, FeatureStdExtZbkb, FeatureStdExtP),
+ "'Zbb' (Basic Bit-Manipulation) or "
+ "'Zbkb' (Bitmanip instructions for Cryptography) or "
+ "'Base P' (Packed-SIMD)">;
+
//===----------------------------------------------------------------------===//
// Vendor extensions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index bb5bb6352c32a5..4b72fc54715314 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2122,6 +2122,9 @@ include "RISCVInstrInfoZicbo.td"
include "RISCVInstrInfoZicond.td"
include "RISCVInstrInfoZicfiss.td"
+// Packed SIMD
+include "RISCVInstrInfoP.td"
+
//===----------------------------------------------------------------------===//
// Vendor extensions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
new file mode 100644
index 00000000000000..fd32bc70a54d68
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -0,0 +1,1068 @@
+//===-- RISCVInstrInfoP.td - RISC-V 'P' instructions -------*- 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 describes the RISC-V instructions from the standard 'Base P'
+// Packed SIMD instruction set extension.
+///
+/// This version is still experimental as the 'P' extension hasn't been
+/// ratified yet.
+///
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Operand and SDNode transformation definitions.
+//===----------------------------------------------------------------------===//
+
+def simm10 : RISCVSImmLeafOp<10> {
+ let MCOperandPredicate = [{
+ int64_t Imm;
+ if (MCOp.evaluateAsConstantImm(Imm))
+ return isInt<10>(Imm);
+ return MCOp.isBareSymbolRef();
+ }];
+}
+
+//===----------------------------------------------------------------------===//
+// Instruction class templates
+//===----------------------------------------------------------------------===//
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPUnary<bits<5> funct5, bits<7> wuimm,
+ bits<3> funct3, RISCVOpcode opcode,
+ string opcodestr>
+ : RVInstIBase<funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1),
+ opcodestr, "$rd, $rs1"> {
+ let Inst{31-27} = funct5;
+ let Inst{26-20} = wuimm;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPUnaryImm9<bits<7> funct7, RISCVOpcode opcode,
+ string opcodestr, DAGOperand TyRd = GPR>
+ : RVInstIBase<0b010, opcode, (outs TyRd:$rd), (ins simm10:$simm10),
+ opcodestr, "$rd, $simm10"> {
+ bits<10> simm10;
+
+ let Inst{31-25} = funct7;
+ let Inst{24-15} = simm10;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPUnaryImm8<bits<8> funct8, RISCVOpcode opcode,
+ string opcodestr, DAGOperand TyRd = GPR>
+ : RVInstIBase<0b010, opcode, (outs TyRd:$rd), (ins uimm8:$uimm8),
+ opcodestr, "$rd, $uimm8"> {
+ bits<8> uimm8;
+ let Inst{31-24} = funct8;
+ let Inst{23-16} = uimm8;
+ let Inst{15} = 0b0;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPUnaryWUF<bits<2> w, bits<5> uf,
+ string opcodestr>
+ : RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPR:$rd), (ins GPR:$rs1),
+ opcodestr, "$rd, $rs1"> {
+ let Inst{31-27} = 0b11100;
+ let Inst{26-25} = w;
+ let Inst{24-20} = uf;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPUnaryWUFRs1pRdp<bits<2> w, bits<5> uf, string opcodestr>
+ : RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPRPairRV32:$rdp), (ins GPRPairRV32:$rs1p),
+ opcodestr, "$rdp, $rs1p"> {
+ bits<4> rs1p;
+ bits<4> rdp;
+
+ let Inst{31-27} = 0b01100;
+ let Inst{26-25} = w;
+ let Inst{24-20} = uf;
+ let Inst{19-16} = rs1p;
+ let Inst{15} = 0b0;
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b0;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPUnaryF<bit bfr, bits<3> f, bit aft, bits<7> wuimm,
+ string opcodestr, bits<3> funct3 = 0b100,
+ dag outs = (outs GPR:$rd), dag ins = (ins GPR:$rs1),
+ string argstr = "$rd, $rs1">
+ : RVInstIBase<funct3, OPC_OP_IMM_32, outs, ins, opcodestr, argstr> {
+ let Inst{31} = bfr;
+ let Inst{30-28} = f;
+ let Inst{27} = aft;
+ let Inst{26-20} = wuimm;
+}
+
+class RVPUnary1F0<bits<3> f, bits<7> wuimm, string opcodestr>
+ : RVPUnaryF<1, f, 0, wuimm, opcodestr>;
+
+class RVPUnary0F0Rdp<bits<3> f, bits<7> wuimm, string opcodestr>
+ : RVPUnaryF<0, f, 0, wuimm, opcodestr, 0b100, (outs GPRPairRV32:$rdp),
+ (ins GPR:$rs1), "$rdp, $rs1"> {
+ bits<4> rdp;
+
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b0;
+}
+
+class RVPUnary0F0Rs1p<bits<3> f, bits<7> wuimm, string opcodestr>
+ : RVPUnaryF<0, f, 0, wuimm, opcodestr, 0b100, (outs GPR:$rd),
+ (ins GPRPairRV32:$rs1p), "$rd, $rs1p"> {
+ bits<4> rs1p;
+
+ let Inst{19-16} = rs1p;
+ let Inst{15} = 0b1;
+}
+
+class RVPUnary0F0Rs1pRdp<bits<3> f, bits<7> wuimm, string opcodestr,
+ bit aft = 0b0>
+ : RVPUnaryF<0, f, 0, wuimm, opcodestr, 0b100, (outs GPRPairRV32:$rdp),
+ (ins GPRPairRV32:$rs1p), "$rdp, $rs1p"> {
+ bits<4> rs1p;
+ bits<4> rdp;
+
+ let Inst{19-16} = rs1p;
+ let Inst{15} = aft;
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b0;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPBinaryFW<bit bfr, bits<3> f, bit aft, bits<2> w,
+ string opcodestr, bits<3> funct3, 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 RVPBinary1F1W<bits<3> f, bits<2> w, string opcodestr, bits<3> funct3,
+ RISCVOpcode Opcode = OPC_OP_32>
+ : RVPBinaryFW<1, f, 1, w, opcodestr, funct3, Opcode>;
+
+class RVPBinary1F0W<bits<3> f, bits<2> w, string opcodestr, bits<3> funct3,
+ RISCVOpcode Opcode = OPC_OP_32>
+ : RVPBinaryFW<1, f, 0, w, opcodestr, funct3, Opcode>;
+
+class RVPBinary0F1WRdp<bits<3> f, bits<2> w, string opcodestr,
+ RISCVOpcode Opcode = OPC_OP_IMM_32>
+ : RVPBinaryFW<0, f, 1, w, opcodestr, 0b010, Opcode, (outs GPRPairRV32:$rdp),
+ (ins GPR:$rs1, GPR:$rs2), "$rdp, $rs1, $rs2"> {
+ bits<4> rdp;
+
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b0;
+}
+
+class RVPBinary0F1WRs1p<bits<3> f, bits<2> w, string opcodestr,
+ bit aft = 0b0, RISCVOpcode Opcode = OPC_OP_IMM_32>
+ : RVPBinaryFW<0, f, 1, w, opcodestr, 0b100, Opcode, (outs GPR:$rd),
+ (ins GPRPairRV32:$rs1p, GPR:$rs2), "$rd, $rs1p, $rs2"> {
+ bits<4> rs1p;
+
+ let Inst{19-16} = rs1p;
+ let Inst{15} = aft;
+}
+
+class RVPBinary0F1WRs1pRdp<bits<3> f, bits<2> w, string opcodestr,
+ bit aft = 0b0, RISCVOpcode Opcode = OPC_OP_IMM_32>
+ : RVPBinaryFW<0, f, 1, w, opcodestr, 0b110, Opcode, (outs GPRPairRV32:$rdp),
+ (ins GPRPairRV32:$rs1p, GPR:$rs2), "$rdp, $rs1p, $rs2"> {
+ bits<4> rs1p;
+ bits<4> rdp;
+
+ let Inst{19-16} = rs1p;
+ let Inst{15} = aft;
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b0;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPBinary1FWRs2pRs1pRdp<bits<4> f, bits<2> w, string opcodestr,
+ bit aft = 0b0, RISCVOpcode Opcode = OPC_OP_IMM_32>
+ : RVInstRBase<0b110, Opcode, (outs GPRPairRV32:$rdp), (ins GPRPairRV32:$rs1p, GPRPairRV32:$rs2p),
+ opcodestr, "$rdp, $rs1p, $rs2p"> {
+ bits<4> rs1p;
+ bits<4> rs2p;
+ bits<4> rdp;
+
+ let Inst{31} = 0b1;
+ let Inst{30-27} = f;
+ let Inst{26-25} = w;
+ let Inst{24-21} = rs2p;
+ let Inst{20} = aft;
+ let Inst{19-16} = rs1p;
+ let Inst{15} = aft;
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b0;
+}
+
+class RVPBinary1F0WRs2pRs1pRdp<bits<3> f, bits<2> w, string opcodestr,
+ bit bfr = 0b1, bit aft = 0b0, RISCVOpcode Opcode = OPC_OP_IMM_32>
+ : RVPBinaryFW<1, f, 0, w, opcodestr, 0b110, Opcode, (outs GPRPairRV32:$rdp),
+ (ins GPRPairRV32:$rs1p, GPRPairRV32:$rs2p), "$rdp, $rs1p, $rs2p"> {
+ bits<4> rs1p;
+ bits<4> rs2p;
+ bits<4> rdp;
+
+ let Inst{24-21} = rs2p;
+ let Inst{20} = bfr;
+ let Inst{19-16} = rs1p;
+ let Inst{15} = aft;
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b0;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPBinaryLongFW<bit bfr, bits<4> f, bits<2> w,
+ string opcodestr, bits<3> funct3, dag outs = (outs GPR:$rd),
+ dag ins = (ins GPR:$rs1, GPR:$rs2),
+ string argstr = "$rd, $rs1, $rs2">
+ : RVInstRBase<funct3, OPC_OP_32, outs, ins,
+ opcodestr, argstr> {
+ let Inst{31} = bfr;
+ let Inst{30-27} = f;
+ let Inst{26-25} = w;
+}
+
+class RVPBinary1LongFW<bits<4> f, bits<2> w, string opcodestr, bits<3> funct3>
+ : RVPBinaryLongFW<1, f, w, opcodestr, funct3>;
+
+class RVPBinary0LongFW<bits<4> f, bits<2> w, string opcodestr>
+ : RVPBinaryLongFW<0, f, w, opcodestr, 0b010, (outs GPRPairRV32:$rdp),
+ (ins GPR:$rs1, GPRPairRV32:$rs2), "$rdp, $rs1, $rs2"> {
+ bits<4> rdp;
+
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b1;
+}
+
+multiclass RVPUnaryBH<bits<5> funct5, string opcodestr> {
+ def NAME # _B : RVPUnary<funct5, 0b0001000, 0b010, OPC_OP_IMM_32, opcodestr # ".b">;
+ def NAME # _H : RVPUnary<funct5, 0b0010000, 0b010, OPC_OP_IMM_32, opcodestr # ".h">;
+}
+
+multiclass RVPUnaryHNonPacked<bits<5> funct5, string opcodestr> {
+ def P # NAME # _H : RVPUnary<funct5, 0b0010000, 0b010, OPC_OP_IMM_32, "p" # opcodestr # ".h">;
+ def NAME: RVPUnary<funct5, 0b0100000, 0b010, OPC_OP_IMM_32, opcodestr>;
+}
+
+multiclass RVPUnaryBHW<bits<5> funct5, string opcodestr> {
+ defm NAME : RVPUnaryBH<funct5, opcodestr>;
+ def NAME # _W: RVPUnary<funct5, 0b0100000, 0b010, OPC_OP_IMM_32, opcodestr # ".w">;
+}
+
+multiclass RVPUnaryHW<bits<5> funct5, string opcodestr> {
+ def NAME # _H : RVPUnary<funct5, 0b0010000, 0b010, OPC_OP_IMM_32, opcodestr # ".h">;
+ def NAME # _W: RVPUnary<funct5, 0b0100000, 0b010, OPC_OP_IMM_32, opcodestr # ".w">;
+}
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasStdExtP] in {
+def CLS : RVPUnary<0b01100, 0b0000011, 0b001, OPC_OP_IMM, "cls">;
+def ABS : RVPUnary<0b01100, 0b0000111, 0b001, OPC_OP_IMM, "abs">;
+} // Predicates = [HasStdExtP]
+let DecoderNamespace = "RISCV32Only_",
+ Predicates = [HasStdExtP, IsRV32] in {
+def REV_RV32 : RVPUnary<0b01101, 0b0011111, 0b101, OPC_OP_IMM, "rev">;
+} // Predicates = [HasStdExtP, IsRV32]
+
+let Predicates = [HasStdExtP, IsRV64] in {
+def REV16 : RVPUnary<0b01101, 0b0110000, 0b101, OPC_OP_IMM, "rev16">;
+def REV_RV64 : RVPUnary<0b01111, 0b0111111, 0b101, OPC_OP_IMM, "rev">;
+
+def CLSW : RVPUnary<0b01100, 0b0000011, 0b001, OPC_OP_IMM_32, "clsw">;
+def ABSW : RVPUnary<0b01100, 0b0000111, 0b001, OPC_OP_IMM_32, "absw">;
+} // Predicates = [HasStdExtP, IsRV64]
+
+let DecoderNamespace = "RISCV32Only_",
+ Predicates = [HasStdExtP, IsRV32] in {
+ defm PSLLI_RV32 : RVPUnaryBH<0b10000, "pslli">;
+ defm SSLAI_RV32 : RVPUnaryHNonPacked<0b11010, "sslai">;
+} // Predicates = [HasStdExtP, IsRV32]
+
+let Predicates = [HasStdExtP, IsRV64] in {
+ defm PSLLI_RV64 : RVPUnaryBHW<0b10000, "pslli">;
+ defm PSSLAI_RV64 : RVPUnaryHW<0b01010, "psslai">;
+} // Predicates = [HasStdExtP, IsRV64]
+
+let Predicates = [HasStdExtP] in
+def PLI_H : RVPUnaryImm9<0b1011000, OPC_OP_IMM_32, "pli.h">;
+let Predicates = [HasStdExtP, IsRV64] in {
+def PLI_W : RVPUnaryImm9<0b1011001, OPC_OP_IMM_32, "pli.w">;
+} // Predicates = [HasStdExtP, IsRV64]
+let Predicates = [HasStdExtP] in
+def PLI_B : RVPUnaryImm8<0b10110100, OPC_OP_IMM_32, "pli.b">;
+
+let DecoderNamespace = "RISCV32Only_",
+ Predicates = [HasStdExtP, IsRV32] in {
+def PSEXTB_H_RV32 : RVPUnaryWUF<0b00, 0b00100, "psextb.h">;
+def PSABS_H_RV32 : RVPUnaryWUF<0b00, 0b00111, "psabs.h">;
+def PSABS_B_RV32 : RVPUnaryWUF<0b01, 0b00111, "psabs.b">;
+} // Predicates = [HasStdExtP, IsRV32]
+
+let Predicates = [HasStdExtP, IsRV64] in {
+def PSEXTB_H_RV64 : RVPUnaryWUF<0b00, 0b00100, "psextb.h">;
+def PSEXTB_W : RVPUnaryWUF<0b01, 0b00100, "psextb.w">;
+def PSEXTH_W : RVPUnaryWUF<0b01, 0b00101, "psexth.w">;
+def PSABS_H_RV64 : RVPUnaryWUF<0b00, 0b00111, "psabs.h">;
+def PSABS_B_RV64 : RVPUnaryWUF<0b10, 0b00111, "psabs.b">;
+} // Predicates = [HasStdExtP, IsRV64]
+
+let Predicates = [HasStdExtP] in
+def PLUI_H : RVPUnaryImm9<0b1111000, OPC_OP_IMM_32, "plui.h">;
+let Predicates = [HasStdExtP, IsRV64] in
+def PLUI_W : RVPUnaryImm9<0b1111001, OPC_OP_IMM_32, "plui.w">;
+
+let Predicates = [HasStdExtP] in {
+def PSLL_H_H0 : RVPBinary1F1W<0b000, 0b00, "psll.h.h0", 0b010, OPC_OP_IMM_32>;
+def PSLL_B_B0 : RVPBinary1F1W<0b000, 0b10, "psll.b.b0", 0b010, OPC_OP_IMM_32>;
+def PADD_H_H0 : RVPBinary1F1W<0b001, 0b00, "padd.h.h0", 0b010, OPC_OP_IMM_32>;
+def PADD_B_B0 : RVPBinary1F1W<0b001, 0b10, "padd.b.b0", 0b010, OPC_OP_IMM_32>;
+def PSSHA_H_H0 : RVPBinary1F1W<0b110, 0b00, "pssha.h.h0", 0b010, OPC_OP_IMM_32>;
+def PSSHAR_H_H0 : RVPBinary1F1W<0b111, 0b00, "psshar.h.h0", 0b010, OPC_OP_IMM_32>;
+} // Predicates = [HasStdExtP]
+let DecoderNamespace = "RISCV32Only_",
+ Predicates = [HasStdExtP, IsRV32] in {
+def SSHA : RVPBinary1F1W<0b110, 0b01, "ssha", 0b010, OPC_OP_IMM_32>;
+def SSHAR : RVPBinary1F1W<0b111, 0b01, "sshar", 0b010, OPC_OP_IMM_32>;
+} // Predicates = [HasStdExtP, IsRV32]
+
+let Predicates = [HasStdExtP, IsRV64] in {
+def PSLL_W_W0 : RVPBinary1F1W<0b000, 0b01, "psll.w.w0", 0b010, OPC_OP_IMM_32>;
+def PADD_W_W0 : RVPBinary1F1W<0b001, 0b01, "padd.w.w0", 0b010, OPC_OP_IMM_32>;
+def PSSHA_W_W0 : RVPBinary1F1W<0b110, 0b01, "pssha.w.w0", 0b010, OPC_OP_IMM_32>;
+def PSSHAR_W_W0 : RVPBinary1F1W<0b111, 0b01, "psshar.w.w0", 0b010, OPC_OP_IMM_32>;
+def SHA : RVPBinary1F1W<0b110, 0b11, "sha", 0b010, OPC_OP_IMM_32>;
+def SHAR : RVPBinary1F1W<0b111, 0b11, "shar", 0b010, OPC_OP_IMM_32>;
+} // Predicates = [HasStdExtP, IsRV64]
+
+let Predicates = [HasStdExtP] in {
+def PSRLI_B : RVPUnary1F0<0b000, 0b0001000, "psrli.b">;
+def PSRLI_H : RVPUnary1F0<0b000, 0b0010000, "psrli.h">;
+def PUSATI_H : RVPUnary1F0<0b010, 0b0010000, "pusati.h">;
+def PSRAI_B : RVPUnary1F0<0b100, 0b0001000, "psrai.b">;
+def PSRAI_H : RVPUnary1F0<0b100, 0b0010000, "psrai.h">;
+def PSRARI_H : RVPUnary1F0<0b101, 0b0010000, "psrari.h">;
+def PSATI_H : RVPUnary1F0<0b110, 0b0010000, "psati.h">;
+} // Predicates = [HasStdExtP]
+
+let DecoderNamespace = "RISCV32Only_",
+ Predicates = [HasStdExtP, IsRV32] in {
+def USATI_RV32 : RVPUn...
[truncated]
|
@llvm/pr-subscribers-mc Author: None (realqhc) ChangesThis proposed extension adds Packed-SIMD instructions for RV32 and RV64. Documentation: Patch is 152.72 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/123271.diff 15 Files Affected:
diff --git a/llvm/docs/RISCVUsage.rst b/llvm/docs/RISCVUsage.rst
index a1df0f7d686e62..89202a825fc643 100644
--- a/llvm/docs/RISCVUsage.rst
+++ b/llvm/docs/RISCVUsage.rst
@@ -335,6 +335,9 @@ The primary goal of experimental support is to assist in the process of ratifica
``experimental-svukte``
LLVM implements the `0.3 draft specification <https://github.com/riscv/riscv-isa-manual/pull/1564>`__.
+``experimental-p``, ``experimental-p``
+ LLVM implements the `012 specification <https://jhauser.us/RISCV/ext-P/RVP-baseInstrs-012.pdf>`__.
+
To use an experimental extension from `clang`, you must add `-menable-experimental-extensions` to the command line, and specify the exact version of the experimental extension you are using. To use an experimental extension with LLVM's internal developer tools (e.g. `llc`, `llvm-objdump`, `llvm-mc`), you must prefix the extension name with `experimental-`. Note that you don't need to specify the version with internal tools, and shouldn't include the `experimental-` prefix with `clang`.
Vendor Extensions
diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
index 8177280044bf44..b941c2b15a0cb1 100644
--- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
+++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp
@@ -961,6 +961,16 @@ struct RISCVOperand final : public MCParsedAsmOperand {
bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); }
+ bool isSImm10() const {
+ if (!isImm())
+ return false;
+ int64_t Imm;
+ RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
+ bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
+ return IsConstantImm && isInt<10>(fixImmediateForRV32(Imm, isRV64Imm())) &&
+ VK == RISCVMCExpr::VK_RISCV_None;
+ }
+
bool isSImm10Lsb0000NonZero() const {
if (!isImm())
return false;
@@ -1587,6 +1597,9 @@ bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
return generateImmOutOfRangeError(
Operands, ErrorInfo, 4, (1 << 10) - 4,
"immediate must be a multiple of 4 bytes in the range");
+ case Match_InvalidSImm10:
+ return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
+ (1 << 9) - 1);
case Match_InvalidSImm10Lsb0000NonZero:
return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
index ab04b09a7ad151..f4902099ddc3f7 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h
@@ -314,6 +314,7 @@ enum OperandType : unsigned {
OPERAND_UIMM8_GE32,
OPERAND_UIMM9_LSB000,
OPERAND_UIMM10,
+ OPERAND_SIMM10,
OPERAND_UIMM10_LSB00_NONZERO,
OPERAND_UIMM11,
OPERAND_UIMM12,
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index f721d7148526ba..f5832c648bff8d 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -1016,6 +1016,38 @@ def HasStdExtSmctrOrSsctr : Predicate<"Subtarget->hasStdExtSmctrOrSsctr()">,
"'Smctr' (Control Transfer Records Machine Level) or "
"'Ssctr' (Control Transfer Records Supervisor Level)">;
+def FeatureStdExtP
+ : RISCVExperimentalExtension<"p", 1, 0,
+ "'Base P' (Packed SIMD)">;
+def HasStdExtP : Predicate<"Subtarget->hasStdExtP()">,
+ AssemblerPredicate<(all_of FeatureStdExtP),
+ "'Base P' (Packed SIMD)">;
+
+def HasStdExtZbaOrP
+ : Predicate<"Subtarget->hasStdExtZba() || Subtarget->hasStdExtP()">,
+ AssemblerPredicate<(any_of FeatureStdExtZba, FeatureStdExtP),
+ "'Zba' (Address Generation Instructions) or "
+ "'Base P' (Packed-SIMD)">;
+
+def HasStdExtZbbOrP
+ : Predicate<"Subtarget->hasStdExtZbb() || Subtarget->hasStdExtP()">,
+ AssemblerPredicate<(any_of FeatureStdExtZbb, FeatureStdExtP),
+ "'Zbb' (Basic Bit-Manipulation) or "
+ "'Base P' (Packed-SIMD)">;
+
+def HasStdExtZbkbOrP
+ : Predicate<"Subtarget->hasStdExtZbkb() || Subtarget->hasStdExtP()">,
+ AssemblerPredicate<(any_of FeatureStdExtZbkb, FeatureStdExtP),
+ "'Zbkb' (Bitmanip instructions for Cryptography) or "
+ "'Base P' (Packed-SIMD)">;
+
+def HasStdExtZbbOrZbkbOrP
+ : Predicate<"Subtarget->HasStdExtZbbOrZbkb()|| Subtarget->hasStdExtP()">,
+ AssemblerPredicate<(any_of FeatureStdExtZbb, FeatureStdExtZbkb, FeatureStdExtP),
+ "'Zbb' (Basic Bit-Manipulation) or "
+ "'Zbkb' (Bitmanip instructions for Cryptography) or "
+ "'Base P' (Packed-SIMD)">;
+
//===----------------------------------------------------------------------===//
// Vendor extensions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfo.td b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
index bb5bb6352c32a5..4b72fc54715314 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfo.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfo.td
@@ -2122,6 +2122,9 @@ include "RISCVInstrInfoZicbo.td"
include "RISCVInstrInfoZicond.td"
include "RISCVInstrInfoZicfiss.td"
+// Packed SIMD
+include "RISCVInstrInfoP.td"
+
//===----------------------------------------------------------------------===//
// Vendor extensions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoP.td b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
new file mode 100644
index 00000000000000..fd32bc70a54d68
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoP.td
@@ -0,0 +1,1068 @@
+//===-- RISCVInstrInfoP.td - RISC-V 'P' instructions -------*- 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 describes the RISC-V instructions from the standard 'Base P'
+// Packed SIMD instruction set extension.
+///
+/// This version is still experimental as the 'P' extension hasn't been
+/// ratified yet.
+///
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Operand and SDNode transformation definitions.
+//===----------------------------------------------------------------------===//
+
+def simm10 : RISCVSImmLeafOp<10> {
+ let MCOperandPredicate = [{
+ int64_t Imm;
+ if (MCOp.evaluateAsConstantImm(Imm))
+ return isInt<10>(Imm);
+ return MCOp.isBareSymbolRef();
+ }];
+}
+
+//===----------------------------------------------------------------------===//
+// Instruction class templates
+//===----------------------------------------------------------------------===//
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPUnary<bits<5> funct5, bits<7> wuimm,
+ bits<3> funct3, RISCVOpcode opcode,
+ string opcodestr>
+ : RVInstIBase<funct3, opcode, (outs GPR:$rd), (ins GPR:$rs1),
+ opcodestr, "$rd, $rs1"> {
+ let Inst{31-27} = funct5;
+ let Inst{26-20} = wuimm;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPUnaryImm9<bits<7> funct7, RISCVOpcode opcode,
+ string opcodestr, DAGOperand TyRd = GPR>
+ : RVInstIBase<0b010, opcode, (outs TyRd:$rd), (ins simm10:$simm10),
+ opcodestr, "$rd, $simm10"> {
+ bits<10> simm10;
+
+ let Inst{31-25} = funct7;
+ let Inst{24-15} = simm10;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPUnaryImm8<bits<8> funct8, RISCVOpcode opcode,
+ string opcodestr, DAGOperand TyRd = GPR>
+ : RVInstIBase<0b010, opcode, (outs TyRd:$rd), (ins uimm8:$uimm8),
+ opcodestr, "$rd, $uimm8"> {
+ bits<8> uimm8;
+ let Inst{31-24} = funct8;
+ let Inst{23-16} = uimm8;
+ let Inst{15} = 0b0;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPUnaryWUF<bits<2> w, bits<5> uf,
+ string opcodestr>
+ : RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPR:$rd), (ins GPR:$rs1),
+ opcodestr, "$rd, $rs1"> {
+ let Inst{31-27} = 0b11100;
+ let Inst{26-25} = w;
+ let Inst{24-20} = uf;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPUnaryWUFRs1pRdp<bits<2> w, bits<5> uf, string opcodestr>
+ : RVInstIBase<0b010, OPC_OP_IMM_32, (outs GPRPairRV32:$rdp), (ins GPRPairRV32:$rs1p),
+ opcodestr, "$rdp, $rs1p"> {
+ bits<4> rs1p;
+ bits<4> rdp;
+
+ let Inst{31-27} = 0b01100;
+ let Inst{26-25} = w;
+ let Inst{24-20} = uf;
+ let Inst{19-16} = rs1p;
+ let Inst{15} = 0b0;
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b0;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPUnaryF<bit bfr, bits<3> f, bit aft, bits<7> wuimm,
+ string opcodestr, bits<3> funct3 = 0b100,
+ dag outs = (outs GPR:$rd), dag ins = (ins GPR:$rs1),
+ string argstr = "$rd, $rs1">
+ : RVInstIBase<funct3, OPC_OP_IMM_32, outs, ins, opcodestr, argstr> {
+ let Inst{31} = bfr;
+ let Inst{30-28} = f;
+ let Inst{27} = aft;
+ let Inst{26-20} = wuimm;
+}
+
+class RVPUnary1F0<bits<3> f, bits<7> wuimm, string opcodestr>
+ : RVPUnaryF<1, f, 0, wuimm, opcodestr>;
+
+class RVPUnary0F0Rdp<bits<3> f, bits<7> wuimm, string opcodestr>
+ : RVPUnaryF<0, f, 0, wuimm, opcodestr, 0b100, (outs GPRPairRV32:$rdp),
+ (ins GPR:$rs1), "$rdp, $rs1"> {
+ bits<4> rdp;
+
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b0;
+}
+
+class RVPUnary0F0Rs1p<bits<3> f, bits<7> wuimm, string opcodestr>
+ : RVPUnaryF<0, f, 0, wuimm, opcodestr, 0b100, (outs GPR:$rd),
+ (ins GPRPairRV32:$rs1p), "$rd, $rs1p"> {
+ bits<4> rs1p;
+
+ let Inst{19-16} = rs1p;
+ let Inst{15} = 0b1;
+}
+
+class RVPUnary0F0Rs1pRdp<bits<3> f, bits<7> wuimm, string opcodestr,
+ bit aft = 0b0>
+ : RVPUnaryF<0, f, 0, wuimm, opcodestr, 0b100, (outs GPRPairRV32:$rdp),
+ (ins GPRPairRV32:$rs1p), "$rdp, $rs1p"> {
+ bits<4> rs1p;
+ bits<4> rdp;
+
+ let Inst{19-16} = rs1p;
+ let Inst{15} = aft;
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b0;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPBinaryFW<bit bfr, bits<3> f, bit aft, bits<2> w,
+ string opcodestr, bits<3> funct3, 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 RVPBinary1F1W<bits<3> f, bits<2> w, string opcodestr, bits<3> funct3,
+ RISCVOpcode Opcode = OPC_OP_32>
+ : RVPBinaryFW<1, f, 1, w, opcodestr, funct3, Opcode>;
+
+class RVPBinary1F0W<bits<3> f, bits<2> w, string opcodestr, bits<3> funct3,
+ RISCVOpcode Opcode = OPC_OP_32>
+ : RVPBinaryFW<1, f, 0, w, opcodestr, funct3, Opcode>;
+
+class RVPBinary0F1WRdp<bits<3> f, bits<2> w, string opcodestr,
+ RISCVOpcode Opcode = OPC_OP_IMM_32>
+ : RVPBinaryFW<0, f, 1, w, opcodestr, 0b010, Opcode, (outs GPRPairRV32:$rdp),
+ (ins GPR:$rs1, GPR:$rs2), "$rdp, $rs1, $rs2"> {
+ bits<4> rdp;
+
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b0;
+}
+
+class RVPBinary0F1WRs1p<bits<3> f, bits<2> w, string opcodestr,
+ bit aft = 0b0, RISCVOpcode Opcode = OPC_OP_IMM_32>
+ : RVPBinaryFW<0, f, 1, w, opcodestr, 0b100, Opcode, (outs GPR:$rd),
+ (ins GPRPairRV32:$rs1p, GPR:$rs2), "$rd, $rs1p, $rs2"> {
+ bits<4> rs1p;
+
+ let Inst{19-16} = rs1p;
+ let Inst{15} = aft;
+}
+
+class RVPBinary0F1WRs1pRdp<bits<3> f, bits<2> w, string opcodestr,
+ bit aft = 0b0, RISCVOpcode Opcode = OPC_OP_IMM_32>
+ : RVPBinaryFW<0, f, 1, w, opcodestr, 0b110, Opcode, (outs GPRPairRV32:$rdp),
+ (ins GPRPairRV32:$rs1p, GPR:$rs2), "$rdp, $rs1p, $rs2"> {
+ bits<4> rs1p;
+ bits<4> rdp;
+
+ let Inst{19-16} = rs1p;
+ let Inst{15} = aft;
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b0;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPBinary1FWRs2pRs1pRdp<bits<4> f, bits<2> w, string opcodestr,
+ bit aft = 0b0, RISCVOpcode Opcode = OPC_OP_IMM_32>
+ : RVInstRBase<0b110, Opcode, (outs GPRPairRV32:$rdp), (ins GPRPairRV32:$rs1p, GPRPairRV32:$rs2p),
+ opcodestr, "$rdp, $rs1p, $rs2p"> {
+ bits<4> rs1p;
+ bits<4> rs2p;
+ bits<4> rdp;
+
+ let Inst{31} = 0b1;
+ let Inst{30-27} = f;
+ let Inst{26-25} = w;
+ let Inst{24-21} = rs2p;
+ let Inst{20} = aft;
+ let Inst{19-16} = rs1p;
+ let Inst{15} = aft;
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b0;
+}
+
+class RVPBinary1F0WRs2pRs1pRdp<bits<3> f, bits<2> w, string opcodestr,
+ bit bfr = 0b1, bit aft = 0b0, RISCVOpcode Opcode = OPC_OP_IMM_32>
+ : RVPBinaryFW<1, f, 0, w, opcodestr, 0b110, Opcode, (outs GPRPairRV32:$rdp),
+ (ins GPRPairRV32:$rs1p, GPRPairRV32:$rs2p), "$rdp, $rs1p, $rs2p"> {
+ bits<4> rs1p;
+ bits<4> rs2p;
+ bits<4> rdp;
+
+ let Inst{24-21} = rs2p;
+ let Inst{20} = bfr;
+ let Inst{19-16} = rs1p;
+ let Inst{15} = aft;
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b0;
+}
+
+let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
+class RVPBinaryLongFW<bit bfr, bits<4> f, bits<2> w,
+ string opcodestr, bits<3> funct3, dag outs = (outs GPR:$rd),
+ dag ins = (ins GPR:$rs1, GPR:$rs2),
+ string argstr = "$rd, $rs1, $rs2">
+ : RVInstRBase<funct3, OPC_OP_32, outs, ins,
+ opcodestr, argstr> {
+ let Inst{31} = bfr;
+ let Inst{30-27} = f;
+ let Inst{26-25} = w;
+}
+
+class RVPBinary1LongFW<bits<4> f, bits<2> w, string opcodestr, bits<3> funct3>
+ : RVPBinaryLongFW<1, f, w, opcodestr, funct3>;
+
+class RVPBinary0LongFW<bits<4> f, bits<2> w, string opcodestr>
+ : RVPBinaryLongFW<0, f, w, opcodestr, 0b010, (outs GPRPairRV32:$rdp),
+ (ins GPR:$rs1, GPRPairRV32:$rs2), "$rdp, $rs1, $rs2"> {
+ bits<4> rdp;
+
+ let Inst{11-8} = rdp;
+ let Inst{7} = 0b1;
+}
+
+multiclass RVPUnaryBH<bits<5> funct5, string opcodestr> {
+ def NAME # _B : RVPUnary<funct5, 0b0001000, 0b010, OPC_OP_IMM_32, opcodestr # ".b">;
+ def NAME # _H : RVPUnary<funct5, 0b0010000, 0b010, OPC_OP_IMM_32, opcodestr # ".h">;
+}
+
+multiclass RVPUnaryHNonPacked<bits<5> funct5, string opcodestr> {
+ def P # NAME # _H : RVPUnary<funct5, 0b0010000, 0b010, OPC_OP_IMM_32, "p" # opcodestr # ".h">;
+ def NAME: RVPUnary<funct5, 0b0100000, 0b010, OPC_OP_IMM_32, opcodestr>;
+}
+
+multiclass RVPUnaryBHW<bits<5> funct5, string opcodestr> {
+ defm NAME : RVPUnaryBH<funct5, opcodestr>;
+ def NAME # _W: RVPUnary<funct5, 0b0100000, 0b010, OPC_OP_IMM_32, opcodestr # ".w">;
+}
+
+multiclass RVPUnaryHW<bits<5> funct5, string opcodestr> {
+ def NAME # _H : RVPUnary<funct5, 0b0010000, 0b010, OPC_OP_IMM_32, opcodestr # ".h">;
+ def NAME # _W: RVPUnary<funct5, 0b0100000, 0b010, OPC_OP_IMM_32, opcodestr # ".w">;
+}
+
+//===----------------------------------------------------------------------===//
+// Instructions
+//===----------------------------------------------------------------------===//
+
+let Predicates = [HasStdExtP] in {
+def CLS : RVPUnary<0b01100, 0b0000011, 0b001, OPC_OP_IMM, "cls">;
+def ABS : RVPUnary<0b01100, 0b0000111, 0b001, OPC_OP_IMM, "abs">;
+} // Predicates = [HasStdExtP]
+let DecoderNamespace = "RISCV32Only_",
+ Predicates = [HasStdExtP, IsRV32] in {
+def REV_RV32 : RVPUnary<0b01101, 0b0011111, 0b101, OPC_OP_IMM, "rev">;
+} // Predicates = [HasStdExtP, IsRV32]
+
+let Predicates = [HasStdExtP, IsRV64] in {
+def REV16 : RVPUnary<0b01101, 0b0110000, 0b101, OPC_OP_IMM, "rev16">;
+def REV_RV64 : RVPUnary<0b01111, 0b0111111, 0b101, OPC_OP_IMM, "rev">;
+
+def CLSW : RVPUnary<0b01100, 0b0000011, 0b001, OPC_OP_IMM_32, "clsw">;
+def ABSW : RVPUnary<0b01100, 0b0000111, 0b001, OPC_OP_IMM_32, "absw">;
+} // Predicates = [HasStdExtP, IsRV64]
+
+let DecoderNamespace = "RISCV32Only_",
+ Predicates = [HasStdExtP, IsRV32] in {
+ defm PSLLI_RV32 : RVPUnaryBH<0b10000, "pslli">;
+ defm SSLAI_RV32 : RVPUnaryHNonPacked<0b11010, "sslai">;
+} // Predicates = [HasStdExtP, IsRV32]
+
+let Predicates = [HasStdExtP, IsRV64] in {
+ defm PSLLI_RV64 : RVPUnaryBHW<0b10000, "pslli">;
+ defm PSSLAI_RV64 : RVPUnaryHW<0b01010, "psslai">;
+} // Predicates = [HasStdExtP, IsRV64]
+
+let Predicates = [HasStdExtP] in
+def PLI_H : RVPUnaryImm9<0b1011000, OPC_OP_IMM_32, "pli.h">;
+let Predicates = [HasStdExtP, IsRV64] in {
+def PLI_W : RVPUnaryImm9<0b1011001, OPC_OP_IMM_32, "pli.w">;
+} // Predicates = [HasStdExtP, IsRV64]
+let Predicates = [HasStdExtP] in
+def PLI_B : RVPUnaryImm8<0b10110100, OPC_OP_IMM_32, "pli.b">;
+
+let DecoderNamespace = "RISCV32Only_",
+ Predicates = [HasStdExtP, IsRV32] in {
+def PSEXTB_H_RV32 : RVPUnaryWUF<0b00, 0b00100, "psextb.h">;
+def PSABS_H_RV32 : RVPUnaryWUF<0b00, 0b00111, "psabs.h">;
+def PSABS_B_RV32 : RVPUnaryWUF<0b01, 0b00111, "psabs.b">;
+} // Predicates = [HasStdExtP, IsRV32]
+
+let Predicates = [HasStdExtP, IsRV64] in {
+def PSEXTB_H_RV64 : RVPUnaryWUF<0b00, 0b00100, "psextb.h">;
+def PSEXTB_W : RVPUnaryWUF<0b01, 0b00100, "psextb.w">;
+def PSEXTH_W : RVPUnaryWUF<0b01, 0b00101, "psexth.w">;
+def PSABS_H_RV64 : RVPUnaryWUF<0b00, 0b00111, "psabs.h">;
+def PSABS_B_RV64 : RVPUnaryWUF<0b10, 0b00111, "psabs.b">;
+} // Predicates = [HasStdExtP, IsRV64]
+
+let Predicates = [HasStdExtP] in
+def PLUI_H : RVPUnaryImm9<0b1111000, OPC_OP_IMM_32, "plui.h">;
+let Predicates = [HasStdExtP, IsRV64] in
+def PLUI_W : RVPUnaryImm9<0b1111001, OPC_OP_IMM_32, "plui.w">;
+
+let Predicates = [HasStdExtP] in {
+def PSLL_H_H0 : RVPBinary1F1W<0b000, 0b00, "psll.h.h0", 0b010, OPC_OP_IMM_32>;
+def PSLL_B_B0 : RVPBinary1F1W<0b000, 0b10, "psll.b.b0", 0b010, OPC_OP_IMM_32>;
+def PADD_H_H0 : RVPBinary1F1W<0b001, 0b00, "padd.h.h0", 0b010, OPC_OP_IMM_32>;
+def PADD_B_B0 : RVPBinary1F1W<0b001, 0b10, "padd.b.b0", 0b010, OPC_OP_IMM_32>;
+def PSSHA_H_H0 : RVPBinary1F1W<0b110, 0b00, "pssha.h.h0", 0b010, OPC_OP_IMM_32>;
+def PSSHAR_H_H0 : RVPBinary1F1W<0b111, 0b00, "psshar.h.h0", 0b010, OPC_OP_IMM_32>;
+} // Predicates = [HasStdExtP]
+let DecoderNamespace = "RISCV32Only_",
+ Predicates = [HasStdExtP, IsRV32] in {
+def SSHA : RVPBinary1F1W<0b110, 0b01, "ssha", 0b010, OPC_OP_IMM_32>;
+def SSHAR : RVPBinary1F1W<0b111, 0b01, "sshar", 0b010, OPC_OP_IMM_32>;
+} // Predicates = [HasStdExtP, IsRV32]
+
+let Predicates = [HasStdExtP, IsRV64] in {
+def PSLL_W_W0 : RVPBinary1F1W<0b000, 0b01, "psll.w.w0", 0b010, OPC_OP_IMM_32>;
+def PADD_W_W0 : RVPBinary1F1W<0b001, 0b01, "padd.w.w0", 0b010, OPC_OP_IMM_32>;
+def PSSHA_W_W0 : RVPBinary1F1W<0b110, 0b01, "pssha.w.w0", 0b010, OPC_OP_IMM_32>;
+def PSSHAR_W_W0 : RVPBinary1F1W<0b111, 0b01, "psshar.w.w0", 0b010, OPC_OP_IMM_32>;
+def SHA : RVPBinary1F1W<0b110, 0b11, "sha", 0b010, OPC_OP_IMM_32>;
+def SHAR : RVPBinary1F1W<0b111, 0b11, "shar", 0b010, OPC_OP_IMM_32>;
+} // Predicates = [HasStdExtP, IsRV64]
+
+let Predicates = [HasStdExtP] in {
+def PSRLI_B : RVPUnary1F0<0b000, 0b0001000, "psrli.b">;
+def PSRLI_H : RVPUnary1F0<0b000, 0b0010000, "psrli.h">;
+def PUSATI_H : RVPUnary1F0<0b010, 0b0010000, "pusati.h">;
+def PSRAI_B : RVPUnary1F0<0b100, 0b0001000, "psrai.b">;
+def PSRAI_H : RVPUnary1F0<0b100, 0b0010000, "psrai.h">;
+def PSRARI_H : RVPUnary1F0<0b101, 0b0010000, "psrari.h">;
+def PSATI_H : RVPUnary1F0<0b110, 0b0010000, "psati.h">;
+} // Predicates = [HasStdExtP]
+
+let DecoderNamespace = "RISCV32Only_",
+ Predicates = [HasStdExtP, IsRV32] in {
+def USATI_RV32 : RVPUn...
[truncated]
|
This proposed extension adds Packed-SIMD instructions for RV32 and RV64. Documentation: https://jhauser.us/RISCV/ext-P/RVP-baseInstrs-012.pdf https://jhauser.us/RISCV/ext-P/RVP-instrEncodings-012.pdf This patch is MC-only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we break this up into smaller patches? The P spec is rather large. Reviewing 1000 lines of RISCVInstrInfoP.td in a single PR is very time consuming and exhausting as a reviewer.
The changes to RISCVFeatures.td and RISCVInstrInfoZb.td and other things that go with that could be the first patch. That should be easy to review and get landed.
I've created a separate patch #127160 with the changes. |
…ix encoding problems, fix indentation mismatch.
SmallVectorImpl<MCFixup> &Fixups, | ||
const MCSubtargetInfo &STI) const { | ||
const MCOperand &MO = MI.getOperand(OpNo); | ||
assert(MO.isReg() && "Expected a register."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MCOperand::getReg already asserts if it's not register, so I think you can remove this line.
Co-authored-by: Min-Yih Hsu <min@myhsu.dev>
# Conflicts: # llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp # llvm/test/CodeGen/RISCV/attributes.ll
…V32. align equal signs in class templates.
# Conflicts: # llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
✅ With the latest revision this PR passed the C/C++ code formatter. |
# Conflicts: # llvm/lib/Target/RISCV/RISCVInstrInfo.td
|
||
|
||
let Predicates = [HasStdExtP, IsRV32] in { | ||
def PWSLLI_B : RVPUnary0F0Rdp<0b000, 0b0010000, "pwslli.b">; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is missing a shift amount. This is the xxxx
in the encoding.
# Conflicts: # llvm/docs/RISCVUsage.rst # llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -2153,6 +2156,7 @@ include "RISCVInstrInfoZc.td" | |||
include "RISCVInstrInfoZcmop.td" | |||
include "RISCVInstrInfoZclsd.td" | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stray change
|
||
let Predicates = [HasStdExtP, IsRV64] in { | ||
def REV16 : Unary_r<0b011010110000, 0b101, "rev16">; | ||
def REV_RV64 : Unary_r<0b011110111111, 0b101, "rev">; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this enocding is correct. It should be '0b011010111111`. The upper 5 bits should be the same as REV_RV32 and REV16
This proposed extension adds Packed-SIMD instructions for RV32 and RV64.
Documentation:
https://jhauser.us/RISCV/ext-P/RVP-baseInstrs-014.pdf
https://jhauser.us/RISCV/ext-P/RVP-instrEncodings-014b.pdf