Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 118 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsRISCVXCV.td
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,64 @@ class ScalarCoreVMacGprGprGprImmIntrinsic
: Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem, IntrWillReturn, IntrSpeculatable, ImmArg<ArgIndex<3>>]>;

class ScalarCoreVSimdGprIntrinsic
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty],
[IntrNoMem, IntrSpeculatable]>;

class ScalarCoreVSimdGprGprIntrinsic
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
[IntrNoMem, IntrSpeculatable]>;

class ScalarCoreVSimdGprImmIntrinsic
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty],
[IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<1>>]>;

class ScalarCoreVSimdGprGprGprIntrinsic
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem, IntrSpeculatable]>;

class ScalarCoreVSimdGprGprImmIntrinsic
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<2>>]>;

class ScalarCoreVSimdGprGprGprImmIntrinsic
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty, llvm_i32_ty],
[IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<3>>]>;

multiclass ScalarCoreVSimdGprIntrinsicHB {
def int_riscv_cv_simd_ # NAME # _h : ScalarCoreVSimdGprIntrinsic;
def int_riscv_cv_simd_ # NAME # _b : ScalarCoreVSimdGprIntrinsic;
}

multiclass ScalarCoreVSimdGprGprIntrinsicHB {
def int_riscv_cv_simd_ # NAME # _h : ScalarCoreVSimdGprGprIntrinsic;
def int_riscv_cv_simd_ # NAME # _b : ScalarCoreVSimdGprGprIntrinsic;
}

multiclass ScalarCoreVSimdGprGprGprIntrinsicHB {
def int_riscv_cv_simd_ # NAME # _h : ScalarCoreVSimdGprGprGprIntrinsic;
def int_riscv_cv_simd_ # NAME # _b : ScalarCoreVSimdGprGprGprIntrinsic;
}

multiclass ScalarCoreVSimdGprImmIntrinsicHB {
def int_riscv_cv_simd_ # NAME # _h : ScalarCoreVSimdGprImmIntrinsic;
def int_riscv_cv_simd_ # NAME # _b : ScalarCoreVSimdGprImmIntrinsic;
}

multiclass CoreVSimdBinary <bit exclude_h = false> {
if exclude_h then {
def int_riscv_cv_simd_ # NAME # _b : ScalarCoreVSimdGprGprIntrinsic;
} else {
defm NAME : ScalarCoreVSimdGprGprIntrinsicHB;
}
defm NAME # _sc : ScalarCoreVSimdGprGprIntrinsicHB;
}

multiclass CoreVSimdTernary {
defm NAME : ScalarCoreVSimdGprGprGprIntrinsicHB;
defm NAME # _sc : ScalarCoreVSimdGprGprGprIntrinsicHB;
}

let TargetPrefix = "riscv" in {
def int_riscv_cv_bitmanip_extract : ScalarCoreVBitManipGprGprIntrinsic;
def int_riscv_cv_bitmanip_extractu : ScalarCoreVBitManipGprGprIntrinsic;
Expand Down Expand Up @@ -90,4 +148,64 @@ let TargetPrefix = "riscv" in {
def int_riscv_cv_mac_machhuRN : ScalarCoreVMacGprGprGprImmIntrinsic;
def int_riscv_cv_mac_macsRN : ScalarCoreVMacGprGprGprImmIntrinsic;
def int_riscv_cv_mac_machhsRN : ScalarCoreVMacGprGprGprImmIntrinsic;

defm add : CoreVSimdBinary<true>;
def int_riscv_cv_simd_add_h : ScalarCoreVSimdGprGprImmIntrinsic;
defm sub : CoreVSimdBinary<true>;
def int_riscv_cv_simd_sub_h : ScalarCoreVSimdGprGprImmIntrinsic;
defm avg : CoreVSimdBinary;
defm avgu : CoreVSimdBinary;
defm min : CoreVSimdBinary;
defm minu : CoreVSimdBinary;
defm max : CoreVSimdBinary;
defm maxu : CoreVSimdBinary;
defm srl : CoreVSimdBinary;
defm sra : CoreVSimdBinary;
defm sll : CoreVSimdBinary;
defm or : CoreVSimdBinary;
defm xor : CoreVSimdBinary;
defm and : CoreVSimdBinary;

defm abs : ScalarCoreVSimdGprIntrinsicHB;

defm dotup : CoreVSimdBinary;
defm dotusp : CoreVSimdBinary;
defm dotsp : CoreVSimdBinary;
defm sdotup : CoreVSimdTernary;
defm sdotusp : CoreVSimdTernary;
defm sdotsp : CoreVSimdTernary;

defm extract : ScalarCoreVSimdGprImmIntrinsicHB;
defm extractu : ScalarCoreVSimdGprImmIntrinsicHB;
def int_riscv_cv_simd_insert_b : ScalarCoreVSimdGprGprImmIntrinsic;
def int_riscv_cv_simd_insert_h : ScalarCoreVSimdGprGprImmIntrinsic;


defm shuffle : ScalarCoreVSimdGprGprIntrinsicHB;
def int_riscv_cv_simd_shuffle_sci_h : ScalarCoreVSimdGprImmIntrinsic;
def int_riscv_cv_simd_shuffle_sci_b : ScalarCoreVSimdGprImmIntrinsic;
defm shuffle2 : ScalarCoreVSimdGprGprGprIntrinsicHB;

def int_riscv_cv_simd_packhi_h : ScalarCoreVSimdGprGprIntrinsic;
def int_riscv_cv_simd_packlo_h : ScalarCoreVSimdGprGprIntrinsic;
def int_riscv_cv_simd_packhi_b : ScalarCoreVSimdGprGprGprIntrinsic;
def int_riscv_cv_simd_packlo_b : ScalarCoreVSimdGprGprGprIntrinsic;

defm cmpeq : CoreVSimdBinary;
defm cmpne : CoreVSimdBinary;
defm cmpgt : CoreVSimdBinary;
defm cmpge : CoreVSimdBinary;
defm cmplt : CoreVSimdBinary;
defm cmple : CoreVSimdBinary;
defm cmpgtu : CoreVSimdBinary;
defm cmpgeu : CoreVSimdBinary;
defm cmpltu : CoreVSimdBinary;
defm cmpleu : CoreVSimdBinary;

def int_riscv_cv_simd_cplxmul_r : ScalarCoreVSimdGprGprGprImmIntrinsic;
def int_riscv_cv_simd_cplxmul_i : ScalarCoreVSimdGprGprGprImmIntrinsic;

def int_riscv_cv_simd_cplxconj : ScalarCoreVSimdGprIntrinsic;

def int_riscv_cv_simd_subrotmj : ScalarCoreVSimdGprGprImmIntrinsic;
} // TargetPrefix = "riscv"
20 changes: 20 additions & 0 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20316,6 +20316,24 @@ static MachineBasicBlock *emitFROUND(MachineInstr &MI, MachineBasicBlock *MBB,
return DoneMBB;
}

static MachineBasicBlock *
emitCV_SHUFFLE_SCI_B(MachineInstr &MI, MachineBasicBlock *MBB,
const RISCVSubtarget &Subtarget) {
DebugLoc DL = MI.getDebugLoc();
Register DstReg = MI.getOperand(0).getReg();
Register SrcReg = MI.getOperand(1).getReg();
uint8_t Imm = MI.getOperand(2).getImm();
const unsigned Opcodes[] = {
RISCV::CV_SHUFFLEI0_SCI_B, RISCV::CV_SHUFFLEI1_SCI_B,
RISCV::CV_SHUFFLEI2_SCI_B, RISCV::CV_SHUFFLEI3_SCI_B};
const RISCVInstrInfo &TII = *Subtarget.getInstrInfo();
BuildMI(*MBB, MI, DL, TII.get(Opcodes[Imm >> 6]), DstReg)
.addReg(SrcReg)
.addImm(SignExtend64<6>(Imm));
MI.eraseFromParent();
return MBB;
}

MachineBasicBlock *
RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *BB) const {
Expand Down Expand Up @@ -20393,6 +20411,8 @@ RISCVTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
return emitFROUND(MI, BB, Subtarget);
case RISCV::PROBED_STACKALLOC_DYN:
return emitDynamicProbedAlloc(MI, BB);
case RISCV::PseudoCV_SHUFFLE_SCI_B:
return emitCV_SHUFFLE_SCI_B(MI, BB, Subtarget);
case TargetOpcode::STATEPOINT:
// STATEPOINT is a pseudo instruction which has no implicit defs/uses
// while jal call instruction (where statepoint will be lowered at the end)
Expand Down
227 changes: 227 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
Original file line number Diff line number Diff line change
Expand Up @@ -865,3 +865,230 @@ let Predicates = [HasVendorXCVmac] in {
def : PatCoreVMacGprGprGprUimm5<"macsRN", "MACSRN">;
def : PatCoreVMacGprGprGprUimm5<"machhsRN", "MACHHSRN">;
}

//===----------------------------------------------------------------------===//
// Patterns for SIMD operations
//===----------------------------------------------------------------------===//

def cv_tsimm6 : Operand<XLenVT>, TImmLeaf<XLenVT, [{return isInt<6>(Imm);}]> {
let ParserMatchClass = SImmAsmOperand<6>;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeSImmOperand<6>";
let OperandType = "OPERAND_SIMM6";
let MCOperandPredicate = [{
int64_t Imm;
return MCOp.evaluateAsConstantImm(Imm) && isUInt<6>(Imm);
}];
let OperandNamespace = "RISCVOp";
}


class CVUImmAsmOperand<int width> : AsmOperandClass {
let Name = "CVUImm" # width;
let RenderMethod = "addImmOperands";
let DiagnosticType = !strconcat("Invalid", Name);
}

def cv_uimm6 : Operand<XLenVT>, ImmLeaf<XLenVT, [{return isUInt<6>(Imm);}]> {
let ParserMatchClass = UImmAsmOperand<6>;
let EncoderMethod = "getImmOpValue";
let DecoderMethod = "decodeUImmOperand<6>";
let OperandType = "OPERAND_UIMM6";
let MCOperandPredicate = [{
int64_t Imm;
return MCOp.evaluateAsConstantImm(Imm) && isUInt<6>(Imm);
}];
let OperandNamespace = "RISCVOp";
}

def cv_imm8: Operand<XLenVT>, TImmLeaf<XLenVT, [{return isUInt<8>(Imm);}]>;

class PatCoreVGprGpr<string intr, string asm> :
PatGprGpr<!cast<Intrinsic>("int_riscv_cv_simd_" # intr),
!cast<RVInst>("CV_" # asm)>;

// Note that rd is the last argument
class PatCoreVGprGprGpr <string intr, string asm> :
Pat<(!cast<Intrinsic>("int_riscv_cv_simd_" # intr) GPR:$rs1, GPR:$rs2, GPR:$rd),
(!cast<RVInst>("CV_" # asm) GPR:$rd, GPR:$rs1, GPR:$rs2)>;

class PatCoreVGprTImm <string intr, string asm> :
PatGprImm<!cast<Intrinsic>("int_riscv_cv_simd_" # intr),
!cast<RVInst>("CV_" # asm), cv_tsimm6>;

class PatCoreVGprImm <string intr, string asm> :
PatGprImm<!cast<Intrinsic>("int_riscv_cv_simd_" # intr),
!cast<RVInst>("CV_" # asm), simm6>;

class PatCoreVGprUImm <string intr, string asm> :
PatGprImm<!cast<Intrinsic>("int_riscv_cv_simd_" # intr),
!cast<RVInst>("CV_" # asm), cv_uimm6>;

multiclass PatCoreVGprGprHB <string intr> {
def : PatCoreVGprGpr<intr # "_h", NAME # "_H">;
def : PatCoreVGprGpr<intr # "_b", NAME # "_B">;
}

multiclass PatCoreVGprGprGprHB <string intr> {
def : PatCoreVGprGprGpr<intr # "_h", NAME # "_H">;
def : PatCoreVGprGprGpr<intr # "_b", NAME # "_B">;
}

multiclass PatCoreVGprTImmHB <string intr> {
def : PatCoreVGprTImm<intr # "_h", NAME # "_H">;
def : PatCoreVGprTImm<intr # "_b", NAME # "_B">;
}

multiclass PatCoreVGprImmHB <string intr> {
def : PatCoreVGprImm<intr # "_h", NAME # "_H">;
def : PatCoreVGprImm<intr # "_b", NAME # "_B">;
}

multiclass PatCoreVGprUImmHB <string intr> {
def : PatCoreVGprUImm<intr # "_h", NAME # "_H">;
def : PatCoreVGprUImm<intr # "_b", NAME # "_B">;
}

class PatCoreVGprGprDiv <Intrinsic intr, string asm, int div> :
Pat<(intr GPR:$rs1, GPR:$rs2, (i32 div)),
(!cast<RVInst>("CV_" # asm) GPR:$rs1, GPR:$rs2)>;

class PatCoreVGprGprGprDiv <Intrinsic intr, string asm, int div> :
Pat<(intr GPR:$rd, GPR:$rs1, GPR:$rs2, (i32 div)),
(!cast<RVInst>("CV_" # asm) GPR:$rd, GPR:$rs1, GPR:$rs2)>;

class PatCoreVGprShuffle <Intrinsic intr, RVInst inst, int s> :
Pat<(intr GPR:$rs1, (i32 s)),
(inst GPR:$rs1, 0)>;

multiclass PatCoreVGprGprDivAll <Intrinsic intr> {
def : PatCoreVGprGprDiv<intr, NAME # "_DIV2", 1>;
def : PatCoreVGprGprDiv<intr, NAME # "_DIV4", 2>;
def : PatCoreVGprGprDiv<intr, NAME # "_DIV8", 3>;
}

multiclass PatCoreVGprGprGprDivAll <Intrinsic intr> {
def : PatCoreVGprGprGprDiv<intr, NAME # "_DIV2", 1>;
def : PatCoreVGprGprGprDiv<intr, NAME # "_DIV4", 2>;
def : PatCoreVGprGprGprDiv<intr, NAME # "_DIV8", 3>;
}

class PatCoreVGpr <string intr, string asm> :
PatGpr<!cast<Intrinsic>("int_riscv_cv_simd_" # intr),
!cast<RVInst>("CV_" # asm)>;

multiclass PatCoreVGprHB <string intr> {
def : PatCoreVGpr<intr # "_h", NAME # "_H">;
def : PatCoreVGpr<intr # "_b", NAME # "_B">;
}

multiclass PatCoreVBinary <string intr, bit exclude_h = false> {
if exclude_h then {
def : PatCoreVGprGpr<intr # "_b", NAME # "_B">;
} else {
defm NAME : PatCoreVGprGprHB<intr>;
}
defm NAME # "_SC" : PatCoreVGprGprHB<intr # "_sc">;
defm NAME # "_SCI" : PatCoreVGprImmHB<intr # "_sc">;
}

multiclass PatCoreVBinaryUnsigned <string intr> {
defm NAME : PatCoreVGprGprHB<intr>;
defm NAME # "_SC" : PatCoreVGprGprHB<intr # "_sc">;
defm NAME # "_SCI" : PatCoreVGprUImmHB<intr # "_sc">;
}

multiclass PatCoreVTernary <string intr> {
defm NAME : PatCoreVGprGprGprHB<intr>;
defm NAME # "_SC" : PatCoreVGprGprGprHB<intr # "_sc">;
def : Pat<(!cast<Intrinsic>("int_riscv_cv_simd_" # intr # "_sc_h") GPR:$rs1, simm6:$rs2, GPR:$rd),
(!cast<RVInst>("CV_" # NAME # "_SCI_H") GPR:$rd, GPR:$rs1, simm6:$rs2)>;
def : Pat<(!cast<Intrinsic>("int_riscv_cv_simd_" # intr # "_sc_b") GPR:$rs1, simm6:$rs2, GPR:$rd),
(!cast<RVInst>("CV_" # NAME # "_SCI_B") GPR:$rd, GPR:$rs1, simm6:$rs2)>;
}

multiclass PatCoreVTernaryUnsigned <string intr> {
defm NAME : PatCoreVGprGprGprHB<intr>;
defm NAME # "_SC" : PatCoreVGprGprGprHB<intr # "_sc">;
def : Pat<(!cast<Intrinsic>("int_riscv_cv_simd_" # intr # "_sc_h") GPR:$rs1, cv_uimm6:$rs2, GPR:$rd),
(!cast<RVInst>("CV_" # NAME # "_SCI_H") GPR:$rd, GPR:$rs1, cv_uimm6:$rs2)>;
def : Pat<(!cast<Intrinsic>("int_riscv_cv_simd_" # intr # "_sc_b") GPR:$rs1, cv_uimm6:$rs2, GPR:$rd),
(!cast<RVInst>("CV_" # NAME # "_SCI_B") GPR:$rd, GPR:$rs1, cv_uimm6:$rs2)>;
}

let Predicates = [HasVendorXCVsimd] in {
defm ADD : PatCoreVBinary<"add", true>;
def : PatCoreVGprGprDiv<int_riscv_cv_simd_add_h, "ADD_H", 0>;
defm SUB : PatCoreVBinary<"sub", true>;
def : PatCoreVGprGprDiv<int_riscv_cv_simd_sub_h, "SUB_H", 0>;
defm AVG : PatCoreVBinary<"avg">;
defm AVGU : PatCoreVBinaryUnsigned<"avgu">;
defm MIN : PatCoreVBinary<"min">;
defm MINU : PatCoreVBinaryUnsigned<"minu">;
defm MAX : PatCoreVBinary<"max">;
defm MAXU : PatCoreVBinaryUnsigned<"maxu">;
defm SRL : PatCoreVBinaryUnsigned<"srl">;
defm SRA : PatCoreVBinaryUnsigned<"sra">;
defm SLL : PatCoreVBinaryUnsigned<"sll">;
defm OR : PatCoreVBinary<"or">;
defm XOR : PatCoreVBinary<"xor">;
defm AND : PatCoreVBinary<"and">;

defm ABS : PatCoreVGprHB<"abs">;

defm DOTUP : PatCoreVBinaryUnsigned<"dotup">;
defm DOTUSP : PatCoreVBinary<"dotusp">;
defm DOTSP : PatCoreVBinary<"dotsp">;
defm SDOTUP : PatCoreVTernaryUnsigned<"sdotup">;
defm SDOTUSP : PatCoreVTernary<"sdotusp">;
defm SDOTSP : PatCoreVTernary<"sdotsp">;

defm EXTRACT : PatCoreVGprTImmHB<"extract">;
defm EXTRACTU : PatCoreVGprTImmHB<"extractu">;
def : Pat<(int_riscv_cv_simd_insert_b GPR:$rd, GPR:$rs1, cv_tsimm6:$imm),
(CV_INSERT_B GPR:$rd, GPR:$rs1, cv_tsimm6:$imm)>;
def : Pat<(int_riscv_cv_simd_insert_h GPR:$rd, GPR:$rs1, cv_tsimm6:$imm),
(CV_INSERT_H GPR:$rd, GPR:$rs1, cv_tsimm6:$imm)>;

defm SHUFFLE : PatCoreVGprGprHB<"shuffle">;
def : PatCoreVGprTImm<"shuffle_sci_h", "SHUFFLE_SCI_H">;
let usesCustomInserter = 1 in
def PseudoCV_SHUFFLE_SCI_B : Pseudo<(outs GPR:$rd), (ins GPR:$rs, cv_imm8:$imm), []>;
def : PatGprImm<int_riscv_cv_simd_shuffle_sci_b, PseudoCV_SHUFFLE_SCI_B, cv_imm8>;

def : Pat<(int_riscv_cv_simd_shuffle2_h GPR:$rs1, GPR:$rs2, GPR:$rd),
(CV_SHUFFLE2_H GPR:$rd, GPR:$rs1, GPR:$rs2)>;
def : Pat<(int_riscv_cv_simd_shuffle2_b GPR:$rs1, GPR:$rs2, GPR:$rd),
(CV_SHUFFLE2_B GPR:$rd, GPR:$rs1, GPR:$rs2)>;

def : PatCoreVGprGpr<"packhi_h", "PACK_H">;
def : PatCoreVGprGpr<"packlo_h", "PACK">;
def : Pat<(int_riscv_cv_simd_packhi_b GPR:$rd, GPR:$rs1, GPR:$rs2),
(CV_PACKHI_B GPR:$rd, GPR:$rs1, GPR:$rs2)>;
def : Pat<(int_riscv_cv_simd_packlo_b GPR:$rd, GPR:$rs1, GPR:$rs2),
(CV_PACKLO_B GPR:$rd, GPR:$rs1, GPR:$rs2)>;

defm CMPEQ : PatCoreVBinary<"cmpeq">;
defm CMPNE : PatCoreVBinary<"cmpne">;
defm CMPGT : PatCoreVBinary<"cmpgt">;
defm CMPGE : PatCoreVBinary<"cmpge">;
defm CMPLT : PatCoreVBinary<"cmplt">;
defm CMPLE : PatCoreVBinary<"cmple">;
defm CMPGTU : PatCoreVBinaryUnsigned<"cmpgtu">;
defm CMPGEU : PatCoreVBinaryUnsigned<"cmpgeu">;
defm CMPLTU : PatCoreVBinaryUnsigned<"cmpltu">;
defm CMPLEU : PatCoreVBinaryUnsigned<"cmpleu">;

def : PatCoreVGprGprGprDiv<int_riscv_cv_simd_cplxmul_r, "CPLXMUL_R", 0>;
defm CPLXMUL_R : PatCoreVGprGprGprDivAll<int_riscv_cv_simd_cplxmul_r>;
def : PatCoreVGprGprGprDiv<int_riscv_cv_simd_cplxmul_i, "CPLXMUL_I", 0>;
defm CPLXMUL_I : PatCoreVGprGprGprDivAll<int_riscv_cv_simd_cplxmul_i>;

def : PatCoreVGpr<"cplxconj", "CPLXCONJ">;

def : PatCoreVGprGprDiv<int_riscv_cv_simd_subrotmj, "SUBROTMJ", 0>;
defm SUBROTMJ : PatCoreVGprGprDivAll<int_riscv_cv_simd_subrotmj>;

defm ADD : PatCoreVGprGprDivAll<int_riscv_cv_simd_add_h>;
defm SUB : PatCoreVGprGprDivAll<int_riscv_cv_simd_sub_h>;
} // Predicates = [HasVendorXCVsimd]
Loading
Loading