aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authormelonedo <funanzeng@gmail.com>2023-06-11 00:18:17 +0800
committermelonedo <funanzeng@gmail.com>2023-07-28 16:52:32 +0800
commit3c0604b224e3c38b8db67d55320a0423bb4e8f49 (patch)
tree93aeeaa16a83e5853d497071fe1a6a4ba65e006c /llvm/lib
parentb395e91f2ef41e44c99857b5dd4e241a57d12b76 (diff)
downloadllvm-3c0604b224e3c38b8db67d55320a0423bb4e8f49.zip
llvm-3c0604b224e3c38b8db67d55320a0423bb4e8f49.tar.gz
llvm-3c0604b224e3c38b8db67d55320a0423bb4e8f49.tar.bz2
[RISCV] Add support for XCVsimd extension in CV32E40P
Implement XCVsimd intrinsics for CV32E40P according to the specification. This commit is part of a patch-set to upstream the 7 vendor specific extensions of CV32E40P. Contributors: @CharKeaney, @jeremybennett, @lewis-revill, @liaolucy, Nandni Jamnadas, @PaoloS, @simoncook, @xmj. Reviewed By: craig.topper Differential Revision: https://reviews.llvm.org/D153721
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Support/RISCVISAInfo.cpp1
-rw-r--r--llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp2
-rw-r--r--llvm/lib/Target/RISCV/RISCVFeatures.td8
-rw-r--r--llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td226
4 files changed, 237 insertions, 0 deletions
diff --git a/llvm/lib/Support/RISCVISAInfo.cpp b/llvm/lib/Support/RISCVISAInfo.cpp
index 21605a4..49f8383 100644
--- a/llvm/lib/Support/RISCVISAInfo.cpp
+++ b/llvm/lib/Support/RISCVISAInfo.cpp
@@ -69,6 +69,7 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
{"xcvalu", RISCVExtensionVersion{1, 0}},
{"xcvbitmanip", RISCVExtensionVersion{1, 0}},
{"xcvmac", RISCVExtensionVersion{1, 0}},
+ {"xcvsimd", RISCVExtensionVersion{1, 0}},
{"xsfcie", RISCVExtensionVersion{1, 0}},
{"xsfvcp", RISCVExtensionVersion{1, 0}},
{"xtheadba", RISCVExtensionVersion{1, 0}},
diff --git a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
index 05770680..fc5f271 100644
--- a/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
+++ b/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
@@ -567,6 +567,8 @@ DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
"CORE-V MAC custom opcode table");
TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCValu, DecoderTableXCValu32,
"CORE-V ALU custom opcode table");
+ TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVsimd, DecoderTableCoreVSIMD32,
+ "CORE-V SIMD extensions custom opcode table");
TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
return MCDisassembler::Fail;
diff --git a/llvm/lib/Target/RISCV/RISCVFeatures.td b/llvm/lib/Target/RISCV/RISCVFeatures.td
index 414fd24..f5edfae 100644
--- a/llvm/lib/Target/RISCV/RISCVFeatures.td
+++ b/llvm/lib/Target/RISCV/RISCVFeatures.td
@@ -808,6 +808,14 @@ def HasVendorXCValu : Predicate<"Subtarget->hasVendorXCValu()">,
AssemblerPredicate<(all_of FeatureVendorXCValu),
"'XCValu' (CORE-V ALU Operations)">;
+def FeatureVendorXCVsimd
+ : SubtargetFeature<"xcvsimd", "HasVendorXCvsimd", "true",
+ "'XCVsimd' (CORE-V SIMD ALU)">;
+def HasVendorXCVsimd
+ : Predicate<"Subtarget->hasVendorXCVsimd()">,
+ AssemblerPredicate<(any_of FeatureVendorXCVsimd),
+ "'XCVsimd' (CORE-V SIMD ALU)">;
+
//===----------------------------------------------------------------------===//
// LLVM specific features and extensions
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td b/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
index a92eb1e..8903feb 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
@@ -293,3 +293,229 @@ let Predicates = [HasVendorXCValu],
} // Predicates = [HasVendorXCValu],
// hasSideEffects = 0, mayLoad = 0, mayStore = 0,
// Constraints = "$rd = $rd_wb"
+
+
+class CVInstSIMDRR<bits<5> funct5, bit F, bit funct1, bits<3> funct3,
+ RISCVOpcode opcode, dag outs,
+ dag ins, string opcodestr, string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> {
+ bits<5> rs2;
+ bits<5> rs1;
+ bits<5> rd;
+
+ let Inst{31-27} = funct5;
+ let Inst{26} = F;
+ let Inst{25} = funct1;
+ let Inst{24-20} = rs2;
+ let Inst{19-15} = rs1;
+ let Inst{14-12} = funct3;
+ let Inst{11-7} = rd;
+ let Inst{6-0} = opcode.Value;
+ let DecoderNamespace = "CoreVSIMD";
+}
+
+class CVInstSIMDRI<bits<5> funct5, bit F, bits<3> funct3, RISCVOpcode opcode,
+ dag outs, dag ins, string opcodestr, string argstr>
+ : RVInst<outs, ins, opcodestr, argstr, [], InstFormatOther> {
+ bits<6> imm6;
+ bits<5> rs1;
+ bits<5> rd;
+
+ let Inst{31-27} = funct5;
+ let Inst{26} = F;
+ let Inst{25} = imm6{0}; // funct1 unused
+ let Inst{24-20} = imm6{5-1};
+ let Inst{19-15} = rs1;
+ let Inst{14-12} = funct3;
+ let Inst{11-7} = rd;
+ let Inst{6-0} = opcode.Value;
+ let DecoderNamespace = "CoreVSIMD";
+}
+
+class CVSIMDRR<bits<5> funct5, bit F, bit funct1, bits<3> funct3,
+ string opcodestr>
+ : CVInstSIMDRR<funct5, F, funct1, funct3, OPC_CUSTOM_3, (outs GPR:$rd),
+ (ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2">;
+
+class CVSIMDRRWb<bits<5> funct5, bit F, bit funct1, bits<3> funct3,
+ string opcodestr>
+ : CVInstSIMDRR<funct5, F, funct1, funct3, OPC_CUSTOM_3, (outs GPR:$rd_wb),
+ (ins GPR:$rd, GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2"> {
+ let Constraints = "$rd = $rd_wb";
+}
+
+class CVSIMDRI<bits<5> funct5, bit F, bits<3> funct3, string opcodestr>
+ : CVInstSIMDRI<funct5, F, funct3, OPC_CUSTOM_3, (outs GPR:$rd),
+ (ins GPR:$rs1, simm6:$imm6), opcodestr, "$rd, $rs1, $imm6">;
+
+class CVSIMDRIWb<bits<5> funct5, bit F, bits<3> funct3, string opcodestr>
+ : CVInstSIMDRI<funct5, F, funct3, OPC_CUSTOM_3,
+ (outs GPR:$rd_wb), (ins GPR:$rd, GPR:$rs1, simm6:$imm6),
+ opcodestr, "$rd, $rs1, $imm6"> {
+ let Constraints = "$rd = $rd_wb";
+}
+
+class CVSIMDRU<bits<5> funct5, bit F, bits<3> funct3, string opcodestr,
+ Operand immtype = uimm6>
+ : CVInstSIMDRI<funct5, F, funct3, OPC_CUSTOM_3,
+ (outs GPR:$rd), (ins GPR:$rs1, immtype:$imm6),
+ opcodestr, "$rd, $rs1, $imm6">;
+
+class CVSIMDRUWb<bits<5> funct5, bit F, bits<3> funct3, string opcodestr>
+ : CVInstSIMDRI<funct5, F, funct3, OPC_CUSTOM_3,
+ (outs GPR:$rd_wb),
+ (ins GPR:$rd, GPR:$rs1, uimm6:$imm6),
+ opcodestr, "$rd, $rs1, $imm6"> {
+ let Constraints = "$rd = $rd_wb";
+}
+
+class CVSIMDR<bits<5> funct5, bit F, bit funct1, bits<3> funct3,
+ string opcodestr>
+ : CVInstSIMDRR<funct5, F, funct1, funct3, OPC_CUSTOM_3, (outs GPR:$rd),
+ (ins GPR:$rs1), opcodestr, "$rd, $rs1"> {
+ let rs2 = 0b00000;
+}
+
+multiclass CVSIMDBinarySigned<bits<5> funct5, bit F, bit funct1, string mnemonic> {
+ def CV_ # NAME # _H : CVSIMDRR<funct5, F, funct1, 0b000, "cv." # mnemonic # ".h">;
+ def CV_ # NAME # _B : CVSIMDRR<funct5, F, funct1, 0b001, "cv." # mnemonic # ".b">;
+ def CV_ # NAME # _SC_H : CVSIMDRR<funct5, F, funct1, 0b100, "cv." # mnemonic # ".sc.h">;
+ def CV_ # NAME # _SC_B : CVSIMDRR<funct5, F, funct1, 0b101, "cv." # mnemonic # ".sc.b">;
+ def CV_ # NAME # _SCI_H : CVSIMDRI<funct5, F, 0b110, "cv." # mnemonic # ".sci.h">;
+ def CV_ # NAME # _SCI_B : CVSIMDRI<funct5, F, 0b111, "cv." # mnemonic # ".sci.b">;
+}
+
+multiclass CVSIMDBinaryUnsigned<bits<5> funct5, bit F, bit funct1, string mnemonic> {
+ def CV_ # NAME # _H : CVSIMDRR<funct5, F, funct1, 0b000, "cv." # mnemonic # ".h">;
+ def CV_ # NAME # _B : CVSIMDRR<funct5, F, funct1, 0b001, "cv." # mnemonic # ".b">;
+ def CV_ # NAME # _SC_H : CVSIMDRR<funct5, F, funct1, 0b100, "cv." # mnemonic # ".sc.h">;
+ def CV_ # NAME # _SC_B : CVSIMDRR<funct5, F, funct1, 0b101, "cv." # mnemonic # ".sc.b">;
+ def CV_ # NAME # _SCI_H : CVSIMDRU<funct5, F, 0b110, "cv." # mnemonic # ".sci.h">;
+ def CV_ # NAME # _SCI_B : CVSIMDRU<funct5, F, 0b111, "cv." # mnemonic # ".sci.b">;
+}
+
+multiclass CVSIMDShift<bits<5> funct5, bit F, bit funct1, string mnemonic> {
+ def CV_ # NAME # _H : CVSIMDRR<funct5, F, funct1, 0b000, "cv." # mnemonic # ".h">;
+ def CV_ # NAME # _B : CVSIMDRR<funct5, F, funct1, 0b001, "cv." # mnemonic # ".b">;
+ def CV_ # NAME # _SC_H : CVSIMDRR<funct5, F, funct1, 0b100, "cv." # mnemonic # ".sc.h">;
+ def CV_ # NAME # _SC_B : CVSIMDRR<funct5, F, funct1, 0b101, "cv." # mnemonic # ".sc.b">;
+ def CV_ # NAME # _SCI_H : CVSIMDRU<funct5, F, 0b110, "cv." # mnemonic # ".sci.h", uimm4>;
+ def CV_ # NAME # _SCI_B : CVSIMDRU<funct5, F, 0b111, "cv." # mnemonic # ".sci.b", uimm3>;
+}
+
+multiclass CVSIMDBinarySignedWb<bits<5> funct5, bit F, bit funct1, string mnemonic> {
+ def CV_ # NAME # _H : CVSIMDRRWb<funct5, F, funct1, 0b000, "cv." # mnemonic # ".h">;
+ def CV_ # NAME # _B : CVSIMDRRWb<funct5, F, funct1, 0b001, "cv." # mnemonic # ".b">;
+ def CV_ # NAME # _SC_H : CVSIMDRRWb<funct5, F, funct1, 0b100, "cv." # mnemonic # ".sc.h">;
+ def CV_ # NAME # _SC_B : CVSIMDRRWb<funct5, F, funct1, 0b101, "cv." # mnemonic # ".sc.b">;
+ def CV_ # NAME # _SCI_H : CVSIMDRIWb<funct5, F, 0b110, "cv." # mnemonic # ".sci.h">;
+ def CV_ # NAME # _SCI_B : CVSIMDRIWb<funct5, F, 0b111, "cv." # mnemonic # ".sci.b">;
+}
+
+multiclass CVSIMDBinaryUnsignedWb<bits<5> funct5, bit F, bit funct1, string mnemonic> {
+ def CV_ # NAME # _H : CVSIMDRRWb<funct5, F, funct1, 0b000, "cv." # mnemonic # ".h">;
+ def CV_ # NAME # _B : CVSIMDRRWb<funct5, F, funct1, 0b001, "cv." # mnemonic # ".b">;
+ def CV_ # NAME # _SC_H : CVSIMDRRWb<funct5, F, funct1, 0b100, "cv." # mnemonic # ".sc.h">;
+ def CV_ # NAME # _SC_B : CVSIMDRRWb<funct5, F, funct1, 0b101, "cv." # mnemonic # ".sc.b">;
+ def CV_ # NAME # _SCI_H : CVSIMDRUWb<funct5, F, 0b110, "cv." # mnemonic # ".sci.h">;
+ def CV_ # NAME # _SCI_B : CVSIMDRUWb<funct5, F, 0b111, "cv." # mnemonic # ".sci.b">;
+}
+
+
+let Predicates = [HasVendorXCVsimd, IsRV32],
+ hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
+ defm ADD : CVSIMDBinarySigned<0b00000, 0, 0, "add">;
+ defm SUB : CVSIMDBinarySigned<0b00001, 0, 0, "sub">;
+ defm AVG : CVSIMDBinarySigned<0b00010, 0, 0, "avg">;
+ defm AVGU : CVSIMDBinaryUnsigned<0b00011, 0, 0, "avgu">;
+ defm MIN : CVSIMDBinarySigned<0b00100, 0, 0, "min">;
+ defm MINU : CVSIMDBinaryUnsigned<0b00101, 0, 0, "minu">;
+ defm MAX : CVSIMDBinarySigned<0b00110, 0, 0, "max">;
+ defm MAXU : CVSIMDBinaryUnsigned<0b00111, 0, 0, "maxu">;
+ defm SRL : CVSIMDShift<0b01000, 0, 0, "srl">;
+ defm SRA : CVSIMDShift<0b01001, 0, 0, "sra">;
+ defm SLL : CVSIMDShift<0b01010, 0, 0, "sll">;
+ defm OR : CVSIMDBinarySigned<0b01011, 0, 0, "or">;
+ defm XOR : CVSIMDBinarySigned<0b01100, 0, 0, "xor">;
+ defm AND : CVSIMDBinarySigned<0b01101, 0, 0, "and">;
+
+ def CV_ABS_H : CVSIMDR<0b01110, 0, 0, 0b000, "cv.abs.h">;
+ def CV_ABS_B : CVSIMDR<0b01110, 0, 0, 0b001, "cv.abs.b">;
+
+ // 0b01111xx: UNDEF
+
+ defm DOTUP : CVSIMDBinaryUnsigned<0b10000, 0, 0, "dotup">;
+ defm DOTUSP : CVSIMDBinarySigned<0b10001, 0, 0, "dotusp">;
+ defm DOTSP : CVSIMDBinarySigned<0b10010, 0, 0, "dotsp">;
+ defm SDOTUP : CVSIMDBinaryUnsignedWb<0b10011, 0, 0, "sdotup">;
+ defm SDOTUSP : CVSIMDBinarySignedWb<0b10100, 0, 0, "sdotusp">;
+ defm SDOTSP : CVSIMDBinarySignedWb<0b10101, 0, 0, "sdotsp">;
+
+ // 0b10110xx: UNDEF
+
+ def CV_EXTRACT_H : CVSIMDRU<0b10111, 0, 0b000, "cv.extract.h">;
+ def CV_EXTRACT_B : CVSIMDRU<0b10111, 0, 0b001, "cv.extract.b">;
+ def CV_EXTRACTU_H : CVSIMDRU<0b10111, 0, 0b010, "cv.extractu.h">;
+ def CV_EXTRACTU_B : CVSIMDRU<0b10111, 0, 0b011, "cv.extractu.b">;
+ def CV_INSERT_H : CVSIMDRUWb<0b10111, 0, 0b100, "cv.insert.h">;
+ def CV_INSERT_B : CVSIMDRUWb<0b10111, 0, 0b101, "cv.insert.b">;
+
+ def CV_SHUFFLE_H : CVSIMDRR<0b11000, 0, 0, 0b000, "cv.shuffle.h">;
+ def CV_SHUFFLE_B : CVSIMDRR<0b11000, 0, 0, 0b001, "cv.shuffle.b">;
+ def CV_SHUFFLE_SCI_H : CVSIMDRU<0b11000, 0, 0b110, "cv.shuffle.sci.h">;
+ def CV_SHUFFLEI0_SCI_B : CVSIMDRU<0b11000, 0, 0b111, "cv.shufflei0.sci.b">;
+
+ def CV_SHUFFLEI1_SCI_B : CVSIMDRU<0b11001, 0, 0b111, "cv.shufflei1.sci.b">;
+
+ def CV_SHUFFLEI2_SCI_B : CVSIMDRU<0b11010, 0, 0b111, "cv.shufflei2.sci.b">;
+
+ def CV_SHUFFLEI3_SCI_B : CVSIMDRU<0b11011, 0, 0b111, "cv.shufflei3.sci.b">;
+
+ def CV_SHUFFLE2_H : CVSIMDRRWb<0b11100, 0, 0, 0b000, "cv.shuffle2.h">;
+ def CV_SHUFFLE2_B : CVSIMDRRWb<0b11100, 0, 0, 0b001, "cv.shuffle2.b">;
+
+ // 0b11101xx: UNDEF
+
+ def CV_PACK : CVSIMDRR<0b11110, 0, 0, 0b000, "cv.pack">;
+ def CV_PACK_H : CVSIMDRR<0b11110, 0, 1, 0b000, "cv.pack.h">;
+
+ def CV_PACKHI_B : CVSIMDRRWb<0b11111, 0, 1, 0b001, "cv.packhi.b">;
+ def CV_PACKLO_B : CVSIMDRRWb<0b11111, 0, 0, 0b001, "cv.packlo.b">;
+
+ defm CMPEQ : CVSIMDBinarySigned<0b00000, 1, 0, "cmpeq">;
+ defm CMPNE : CVSIMDBinarySigned<0b00001, 1, 0, "cmpne">;
+ defm CMPGT : CVSIMDBinarySigned<0b00010, 1, 0, "cmpgt">;
+ defm CMPGE : CVSIMDBinarySigned<0b00011, 1, 0, "cmpge">;
+ defm CMPLT : CVSIMDBinarySigned<0b00100, 1, 0, "cmplt">;
+ defm CMPLE : CVSIMDBinarySigned<0b00101, 1, 0, "cmple">;
+ defm CMPGTU : CVSIMDBinaryUnsigned<0b00110, 1, 0, "cmpgtu">;
+ defm CMPGEU : CVSIMDBinaryUnsigned<0b00111, 1, 0, "cmpgeu">;
+ defm CMPLTU : CVSIMDBinaryUnsigned<0b01000, 1, 0, "cmpltu">;
+ defm CMPLEU : CVSIMDBinaryUnsigned<0b01001, 1, 0, "cmpleu">;
+
+ def CV_CPLXMUL_R : CVSIMDRRWb<0b01010, 1, 0, 0b000, "cv.cplxmul.r">;
+ def CV_CPLXMUL_I : CVSIMDRRWb<0b01010, 1, 1, 0b000, "cv.cplxmul.i">;
+ def CV_CPLXMUL_R_DIV2 : CVSIMDRRWb<0b01010, 1, 0, 0b010, "cv.cplxmul.r.div2">;
+ def CV_CPLXMUL_I_DIV2 : CVSIMDRRWb<0b01010, 1, 1, 0b010, "cv.cplxmul.i.div2">;
+ def CV_CPLXMUL_R_DIV4 : CVSIMDRRWb<0b01010, 1, 0, 0b100, "cv.cplxmul.r.div4">;
+ def CV_CPLXMUL_I_DIV4 : CVSIMDRRWb<0b01010, 1, 1, 0b100, "cv.cplxmul.i.div4">;
+ def CV_CPLXMUL_R_DIV8 : CVSIMDRRWb<0b01010, 1, 0, 0b110, "cv.cplxmul.r.div8">;
+ def CV_CPLXMUL_I_DIV8 : CVSIMDRRWb<0b01010, 1, 1, 0b110, "cv.cplxmul.i.div8">;
+
+ def CV_CPLXCONJ : CVSIMDR<0b01011, 1, 0, 0b000, "cv.cplxconj">;
+
+ // 0b01011xx: UNDEF
+
+ def CV_SUBROTMJ : CVSIMDRR<0b01100, 1, 0, 0b000, "cv.subrotmj">;
+ def CV_SUBROTMJ_DIV2 : CVSIMDRR<0b01100, 1, 0, 0b010, "cv.subrotmj.div2">;
+ def CV_SUBROTMJ_DIV4 : CVSIMDRR<0b01100, 1, 0, 0b100, "cv.subrotmj.div4">;
+ def CV_SUBROTMJ_DIV8 : CVSIMDRR<0b01100, 1, 0, 0b110, "cv.subrotmj.div8">;
+
+ def CV_ADD_DIV2 : CVSIMDRR<0b01101, 1, 0, 0b010, "cv.add.div2">;
+ def CV_ADD_DIV4 : CVSIMDRR<0b01101, 1, 0, 0b100, "cv.add.div4">;
+ def CV_ADD_DIV8 : CVSIMDRR<0b01101, 1, 0, 0b110, "cv.add.div8">;
+
+ def CV_SUB_DIV2 : CVSIMDRR<0b01110, 1, 0, 0b010, "cv.sub.div2">;
+ def CV_SUB_DIV4 : CVSIMDRR<0b01110, 1, 0, 0b100, "cv.sub.div4">;
+ def CV_SUB_DIV8 : CVSIMDRR<0b01110, 1, 0, 0b110, "cv.sub.div8">;
+}