879 lines
29 KiB
TableGen
879 lines
29 KiB
TableGen
//===-- RISCVInstrInfoXAndes.td ----------------------------*- 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 vendor extensions defined by Andes Technology.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// RISC-V specific DAG Nodes.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
def SDT_NDS_FMV_BF16_X
|
|
: SDTypeProfile<1, 1, [SDTCisVT<0, bf16>, SDTCisVT<1, XLenVT>]>;
|
|
def SDT_NDS_FMV_X_ANYEXTBF16
|
|
: SDTypeProfile<1, 1, [SDTCisVT<0, XLenVT>, SDTCisVT<1, bf16>]>;
|
|
|
|
def riscv_nds_fmv_bf16_x
|
|
: SDNode<"RISCVISD::NDS_FMV_BF16_X", SDT_NDS_FMV_BF16_X>;
|
|
def riscv_nds_fmv_x_anyextbf16
|
|
: SDNode<"RISCVISD::NDS_FMV_X_ANYEXTBF16", SDT_NDS_FMV_X_ANYEXTBF16>;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Operand and SDNode transformation definitions.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// A 11-bit signed immediate where the least significant bit is zero.
|
|
def bare_simm11_lsb0 : Operand<OtherVT> {
|
|
let ParserMatchClass = BareSImmNLsb0AsmOperand<11>;
|
|
let PrintMethod = "printBranchOperand";
|
|
let EncoderMethod = "getImmOpValueAsrN<1>";
|
|
let DecoderMethod = "decodeSImmOperandAndLslN<11, 1>";
|
|
let MCOperandPredicate = [{
|
|
int64_t Imm;
|
|
if (MCOp.evaluateAsConstantImm(Imm))
|
|
return isShiftedInt<10, 1>(Imm);
|
|
return MCOp.isBareSymbolRef();
|
|
}];
|
|
let OperandType = "OPERAND_PCREL";
|
|
}
|
|
|
|
def simm18 : Operand<XLenVT> {
|
|
let ParserMatchClass = SImmAsmOperand<18>;
|
|
let EncoderMethod = "getImmOpValue";
|
|
let DecoderMethod = "decodeSImmOperand<18>";
|
|
}
|
|
|
|
def simm18_lsb0 : Operand<XLenVT> {
|
|
let ParserMatchClass = SImmAsmOperand<18, "Lsb0">;
|
|
let EncoderMethod = "getImmOpValueAsrN<1>";
|
|
let DecoderMethod = "decodeSImmOperandAndLslN<18, 1>";
|
|
}
|
|
|
|
def simm19_lsb00 : Operand<XLenVT> {
|
|
let ParserMatchClass = SImmAsmOperand<19, "Lsb00">;
|
|
let EncoderMethod = "getImmOpValueAsrN<2>";
|
|
let DecoderMethod = "decodeSImmOperandAndLslN<19, 2>";
|
|
}
|
|
|
|
def simm20_lsb000 : Operand<XLenVT> {
|
|
let ParserMatchClass = SImmAsmOperand<20, "Lsb000">;
|
|
let EncoderMethod = "getImmOpValueAsrN<3>";
|
|
let DecoderMethod = "decodeSImmOperandAndLslN<20, 3>";
|
|
}
|
|
|
|
// Predicate: True if immediate is a power of 2.
|
|
def PowerOf2 : PatLeaf<(imm), [{
|
|
return isPowerOf2_64(N->getZExtValue());
|
|
}]>;
|
|
|
|
// Transformation function: Get log2 of immediate.
|
|
def Log2 : SDNodeXForm<imm, [{
|
|
uint64_t Imm = Log2_64(N->getZExtValue());
|
|
return CurDAG->getTargetConstant(Imm, SDLoc(N), N->getValueType(0));
|
|
}]>;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Pseudo table
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
class RISCVNDSVLN<bit M, bit U, bits<3> S, bits<3> L> {
|
|
bits<1> Masked = M;
|
|
bits<1> Unsigned = U;
|
|
bits<3> Log2SEW = S;
|
|
bits<3> LMUL = L;
|
|
Pseudo Pseudo = !cast<Pseudo>(NAME);
|
|
}
|
|
|
|
def RISCVNDSVLNTable : GenericTable {
|
|
let FilterClass = "RISCVNDSVLN";
|
|
let CppTypeName = "NDSVLNPseudo";
|
|
let Fields = ["Masked", "Unsigned", "Log2SEW", "LMUL", "Pseudo"];
|
|
let PrimaryKey = ["Masked", "Unsigned", "Log2SEW", "LMUL"];
|
|
let PrimaryKeyName = "getNDSVLNPseudo";
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Instruction Class Templates
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
class NDSRVInstBB<bit cs, string opcodestr>
|
|
: RVInst<(outs),
|
|
(ins GPR:$rs1, uimmlog2xlen:$cimm, bare_simm11_lsb0:$imm10),
|
|
opcodestr, "$rs1, $cimm, $imm10", [], InstFormatNDS_BRANCH_10>,
|
|
Sched<[WriteJmp, ReadIALU]> {
|
|
bits<10> imm10;
|
|
bits<5> rs1;
|
|
bits<6> cimm;
|
|
|
|
let Inst{31} = imm10{9};
|
|
let Inst{30} = cs;
|
|
let Inst{29-25} = imm10{8-4};
|
|
let Inst{24-20} = cimm{4-0};
|
|
let Inst{19-15} = rs1;
|
|
let Inst{14-12} = 0b111;
|
|
let Inst{11-8} = imm10{3-0};
|
|
let Inst{7} = cimm{5};
|
|
let Inst{6-0} = OPC_CUSTOM_2.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 0;
|
|
let isBranch = 1;
|
|
let isTerminator = 1;
|
|
}
|
|
|
|
class NDSRVInstBC<bits<3> funct3, string opcodestr>
|
|
: RVInst<(outs), (ins GPR:$rs1, uimm7:$cimm, bare_simm11_lsb0:$imm10),
|
|
opcodestr, "$rs1, $cimm, $imm10", [], InstFormatNDS_BRANCH_10>,
|
|
Sched<[WriteJmp, ReadIALU]> {
|
|
bits<10> imm10;
|
|
bits<5> rs1;
|
|
bits<7> cimm;
|
|
|
|
let Inst{31} = imm10{9};
|
|
let Inst{30} = cimm{6};
|
|
let Inst{29-25} = imm10{8-4};
|
|
let Inst{24-20} = cimm{4-0};
|
|
let Inst{19-15} = rs1;
|
|
let Inst{14-12} = funct3;
|
|
let Inst{11-8} = imm10{3-0};
|
|
let Inst{7} = cimm{5};
|
|
let Inst{6-0} = OPC_CUSTOM_2.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 0;
|
|
let isBranch = 1;
|
|
let isTerminator = 1;
|
|
}
|
|
|
|
class NDSRVInstBFO<bits<3> funct3, string opcodestr>
|
|
: RVInst<(outs GPR:$rd),
|
|
(ins GPR:$rs1, uimmlog2xlen:$msb, uimmlog2xlen:$lsb),
|
|
opcodestr, "$rd, $rs1, $msb, $lsb", [], InstFormatOther>,
|
|
Sched<[WriteIALU, ReadIALU]> {
|
|
bits<5> rd;
|
|
bits<5> rs1;
|
|
bits<6> msb;
|
|
bits<6> lsb;
|
|
|
|
let Inst{31-26} = msb;
|
|
let Inst{25-20} = lsb;
|
|
let Inst{19-15} = rs1;
|
|
let Inst{14-12} = funct3;
|
|
let Inst{11-7} = rd;
|
|
let Inst{6-0} = OPC_CUSTOM_2.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 0;
|
|
}
|
|
|
|
class NDSRVInstRR<bits<7> funct7, string opcodestr>
|
|
: RVInstR<funct7, 0b000, OPC_CUSTOM_2,
|
|
(outs GPR:$rd), (ins GPR:$rs1, GPR:$rs2),
|
|
opcodestr, "$rd, $rs1, $rs2">,
|
|
Sched<[WriteIALU, ReadIALU, ReadIALU]> {
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 0;
|
|
}
|
|
|
|
class NDSRVInstLEA<bits<7> funct7, string opcodestr>
|
|
: RVInstR<funct7, 0b000, OPC_CUSTOM_2,
|
|
(outs GPR:$rd), (ins GPR:$rs2, GPR:$rs1),
|
|
opcodestr, "$rd, $rs1, $rs2">,
|
|
Sched<[WriteIALU, ReadIALU, ReadIALU]> {
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 0;
|
|
}
|
|
|
|
// GP: ADDI, LB, LBU
|
|
class NDSRVInstLBGP<bits<2> funct2, string opcodestr>
|
|
: RVInst<(outs GPR:$rd), (ins simm18:$imm18),
|
|
opcodestr, "$rd, ${imm18}", [], InstFormatOther> {
|
|
bits<18> imm18;
|
|
bits<5> rd;
|
|
|
|
let Inst{31} = imm18{17};
|
|
let Inst{30-21} = imm18{10-1};
|
|
let Inst{20} = imm18{11};
|
|
let Inst{19-17} = imm18{14-12};
|
|
let Inst{16-15} = imm18{16-15};
|
|
let Inst{14} = imm18{0};
|
|
let Inst{13-12} = funct2;
|
|
let Inst{11-7} = rd;
|
|
let Inst{6-0} = OPC_CUSTOM_0.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 1;
|
|
let mayStore = 0;
|
|
}
|
|
|
|
// GP: LH, LHU
|
|
class NDSRVInstLHGP<bits<3> funct3, string opcodestr>
|
|
: RVInst<(outs GPR:$rd), (ins simm18_lsb0:$imm17),
|
|
opcodestr, "$rd, ${imm17}", [], InstFormatOther> {
|
|
bits<17> imm17;
|
|
bits<5> rd;
|
|
|
|
let Inst{31} = imm17{16};
|
|
let Inst{30-21} = imm17{9-0};
|
|
let Inst{20} = imm17{10};
|
|
let Inst{19-17} = imm17{13-11};
|
|
let Inst{16-15} = imm17{15-14};
|
|
let Inst{14-12} = funct3;
|
|
let Inst{11-7} = rd;
|
|
let Inst{6-0} = OPC_CUSTOM_1.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 1;
|
|
let mayStore = 0;
|
|
}
|
|
|
|
// GP: LW, LWU
|
|
class NDSRVInstLWGP<bits<3> funct3, string opcodestr>
|
|
: RVInst<(outs GPR:$rd), (ins simm19_lsb00:$imm17),
|
|
opcodestr, "$rd, ${imm17}", [], InstFormatOther> {
|
|
bits<17> imm17;
|
|
bits<5> rd;
|
|
|
|
let Inst{31} = imm17{16};
|
|
let Inst{30-22} = imm17{8-0};
|
|
let Inst{21} = imm17{15};
|
|
let Inst{20} = imm17{9};
|
|
let Inst{19-17} = imm17{12-10};
|
|
let Inst{16-15} = imm17{14-13};
|
|
let Inst{14-12} = funct3;
|
|
let Inst{11-7} = rd;
|
|
let Inst{6-0} = OPC_CUSTOM_1.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 1;
|
|
let mayStore = 0;
|
|
}
|
|
|
|
// GP: LD
|
|
class NDSRVInstLDGP<bits<3> funct3, string opcodestr>
|
|
: RVInst<(outs GPR:$rd), (ins simm20_lsb000:$imm17),
|
|
opcodestr, "$rd, ${imm17}", [], InstFormatOther> {
|
|
bits<17> imm17;
|
|
bits<5> rd;
|
|
|
|
let Inst{31} = imm17{16};
|
|
let Inst{30-23} = imm17{7-0};
|
|
let Inst{22-21} = imm17{15-14};
|
|
let Inst{20} = imm17{8};
|
|
let Inst{19-17} = imm17{11-9};
|
|
let Inst{16-15} = imm17{13-12};
|
|
let Inst{14-12} = funct3;
|
|
let Inst{11-7} = rd;
|
|
let Inst{6-0} = OPC_CUSTOM_1.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 1;
|
|
let mayStore = 0;
|
|
}
|
|
|
|
// GP: SB
|
|
class NDSRVInstSBGP<bits<2> funct2, string opcodestr>
|
|
: RVInst<(outs), (ins GPR:$rs2, simm18:$imm18),
|
|
opcodestr, "$rs2, ${imm18}", [], InstFormatOther> {
|
|
bits<18> imm18;
|
|
bits<5> rs2;
|
|
|
|
let Inst{31} = imm18{17};
|
|
let Inst{30-25} = imm18{10-5};
|
|
let Inst{24-20} = rs2;
|
|
let Inst{19-17} = imm18{14-12};
|
|
let Inst{16-15} = imm18{16-15};
|
|
let Inst{14} = imm18{0};
|
|
let Inst{13-12} = funct2;
|
|
let Inst{11-8} = imm18{4-1};
|
|
let Inst{7} = imm18{11};
|
|
let Inst{6-0} = OPC_CUSTOM_0.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 1;
|
|
}
|
|
|
|
// GP: SH
|
|
class NDSRVInstSHGP<bits<3> funct3, string opcodestr>
|
|
: RVInst<(outs), (ins GPR:$rs2, simm18_lsb0:$imm17),
|
|
opcodestr, "$rs2, ${imm17}", [], InstFormatOther> {
|
|
bits<17> imm17;
|
|
bits<5> rs2;
|
|
|
|
let Inst{31} = imm17{16};
|
|
let Inst{30-25} = imm17{9-4};
|
|
let Inst{24-20} = rs2;
|
|
let Inst{19-17} = imm17{13-11};
|
|
let Inst{16-15} = imm17{15-14};
|
|
let Inst{14-12} = funct3;
|
|
let Inst{11-8} = imm17{3-0};
|
|
let Inst{7} = imm17{10};
|
|
let Inst{6-0} = OPC_CUSTOM_1.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 1;
|
|
}
|
|
|
|
// GP: SW
|
|
class NDSRVInstSWGP<bits<3> funct3, string opcodestr>
|
|
: RVInst<(outs), (ins GPR:$rs2, simm19_lsb00:$imm17),
|
|
opcodestr, "$rs2, ${imm17}", [], InstFormatOther> {
|
|
bits<17> imm17;
|
|
bits<5> rs2;
|
|
|
|
let Inst{31} = imm17{16};
|
|
let Inst{30-25} = imm17{8-3};
|
|
let Inst{24-20} = rs2;
|
|
let Inst{19-17} = imm17{12-10};
|
|
let Inst{16-15} = imm17{14-13};
|
|
let Inst{14-12} = funct3;
|
|
let Inst{11-9} = imm17{2-0};
|
|
let Inst{8} = imm17{15};
|
|
let Inst{7} = imm17{9};
|
|
let Inst{6-0} = OPC_CUSTOM_1.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 1;
|
|
}
|
|
|
|
// GP: SD
|
|
class NDSRVInstSDGP<bits<3> funct3, string opcodestr>
|
|
: RVInst<(outs), (ins GPR:$rs2, simm20_lsb000:$imm17),
|
|
opcodestr, "$rs2, ${imm17}", [], InstFormatOther> {
|
|
bits<17> imm17;
|
|
bits<5> rs2;
|
|
|
|
let Inst{31} = imm17{16};
|
|
let Inst{30-25} = imm17{7-2};
|
|
let Inst{24-20} = rs2;
|
|
let Inst{19-17} = imm17{11-9};
|
|
let Inst{16-15} = imm17{13-12};
|
|
let Inst{14-12} = funct3;
|
|
let Inst{11-10} = imm17{1-0};
|
|
let Inst{9-8} = imm17{15-14};
|
|
let Inst{7} = imm17{8};
|
|
let Inst{6-0} = OPC_CUSTOM_1.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 1;
|
|
}
|
|
|
|
class NDSRVInstBFHCvt<bits<7> funct7, bits<5> rs1val, DAGOperand rdty,
|
|
DAGOperand rs2ty, string opcodestr>
|
|
: RVInstR<funct7, 0b100, OPC_CUSTOM_2, (outs rdty:$rd),
|
|
(ins rs2ty:$rs2), opcodestr, "$rd, $rs2"> {
|
|
let rs1 = rs1val;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 0;
|
|
let mayRaiseFPException = 1;
|
|
}
|
|
|
|
class NDSRVInstVFPMAD<bits<6> funct6, string opcodestr>
|
|
: RVInst<(outs VR:$vd), (ins VR:$vs2, FPR32:$rs1, VMaskOp:$vm),
|
|
opcodestr # "." # "vf", "$vd, $rs1, $vs2$vm", [], InstFormatR>,
|
|
SchedBinaryMC<"WriteVFMulAddF", "ReadVFMulAddV", "ReadVFMulAddF"> {
|
|
bits<5> vs2;
|
|
bits<5> rs1;
|
|
bits<5> vd;
|
|
bit vm;
|
|
|
|
let Inst{31-26} = funct6;
|
|
let Inst{25} = vm;
|
|
let Inst{24-20} = vs2;
|
|
let Inst{19-15} = rs1;
|
|
let Inst{14-12} = 0b100;
|
|
let Inst{11-7} = vd;
|
|
let Inst{6-0} = OPC_CUSTOM_2.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 0;
|
|
|
|
let RVVConstraint = VMConstraint;
|
|
}
|
|
|
|
class NDSRVInstVD4DOT<bits<6> funct6, string opcodestr>
|
|
: RVInst<(outs VR:$vd), (ins VR:$vs1, VR:$vs2, VMaskOp:$vm),
|
|
opcodestr # "." # "vv", "$vd, $vs1, $vs2$vm", [], InstFormatR>,
|
|
SchedBinaryMC<"WriteVIMulAddV", "ReadVIMulAddV", "ReadVIMulAddV"> {
|
|
bits<5> vs2;
|
|
bits<5> vs1;
|
|
bits<5> vd;
|
|
bit vm;
|
|
|
|
let Inst{31-26} = funct6;
|
|
let Inst{25} = vm;
|
|
let Inst{24-20} = vs2;
|
|
let Inst{19-15} = vs1;
|
|
let Inst{14-12} = 0b100;
|
|
let Inst{11-7} = vd;
|
|
let Inst{6-0} = OPC_CUSTOM_2.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 0;
|
|
|
|
let RVVConstraint = VMConstraint;
|
|
}
|
|
|
|
class NDSRVInstVBFHCvt<bits<5> vs1, string opcodestr>
|
|
: RVInst<(outs VR:$vd), (ins VR:$vs2),
|
|
opcodestr, "$vd, $vs2", [], InstFormatR> {
|
|
bits<5> vs2;
|
|
bits<5> vd;
|
|
|
|
let Inst{31-25} = 0b0000000;
|
|
let Inst{24-20} = vs2;
|
|
let Inst{19-15} = vs1;
|
|
let Inst{14-12} = 0b100;
|
|
let Inst{11-7} = vd;
|
|
let Inst{6-0} = OPC_CUSTOM_2.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 0;
|
|
let mayStore = 0;
|
|
|
|
let Uses = [VL, VTYPE];
|
|
}
|
|
|
|
class NDSRVInstVLN<bits<5> funct5, string opcodestr>
|
|
: RVInst<(outs VR:$vd), (ins GPRMemZeroOffset:$rs1, VMaskOp:$vm),
|
|
opcodestr, "$vd, ${rs1}$vm", [], InstFormatR>,
|
|
VLESchedMC {
|
|
bits<5> rs1;
|
|
bits<5> vd;
|
|
bit vm;
|
|
|
|
let Inst{31-26} = 0b000001;
|
|
let Inst{25} = vm;
|
|
let Inst{24-20} = funct5;
|
|
let Inst{19-15} = rs1;
|
|
let Inst{14-12} = 0b100;
|
|
let Inst{11-7} = vd;
|
|
let Inst{6-0} = OPC_CUSTOM_2.Value;
|
|
let hasSideEffects = 0;
|
|
let mayLoad = 1;
|
|
let mayStore = 0;
|
|
|
|
let Uses = [VTYPE, VL];
|
|
let RVVConstraint = VMConstraint;
|
|
}
|
|
|
|
class VPseudoVLN8NoMask<VReg RetClass, bit U> :
|
|
RISCVVPseudo<(outs RetClass:$rd),
|
|
(ins RetClass:$dest,
|
|
GPRMemZeroOffset:$rs1,
|
|
AVL:$vl, sew:$sew, vec_policy:$policy), []>,
|
|
RISCVNDSVLN</*Masked*/0, /*Unsigned*/U, !logtwo(8), VLMul> {
|
|
let mayLoad = 1;
|
|
let mayStore = 0;
|
|
let hasSideEffects = 0;
|
|
let HasVLOp = 1;
|
|
let HasSEWOp = 1;
|
|
let HasVecPolicyOp = 1;
|
|
let Constraints = "$rd = $dest";
|
|
}
|
|
|
|
class VPseudoVLN8Mask<VReg RetClass, bit U> :
|
|
RISCVVPseudo<(outs GetVRegNoV0<RetClass>.R:$rd),
|
|
(ins GetVRegNoV0<RetClass>.R:$passthru,
|
|
GPRMemZeroOffset:$rs1,
|
|
VMaskOp:$vm, AVL:$vl, sew:$sew, vec_policy:$policy),
|
|
[]>,
|
|
RISCVNDSVLN</*Masked*/1, /*Unsigned*/U, !logtwo(8), VLMul> {
|
|
let mayLoad = 1;
|
|
let mayStore = 0;
|
|
let hasSideEffects = 0;
|
|
let HasVLOp = 1;
|
|
let HasSEWOp = 1;
|
|
let HasVecPolicyOp = 1;
|
|
let UsesMaskPolicy = 1;
|
|
let Constraints = "$rd = $passthru";
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Multiclass
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
multiclass VPseudoVWCVT_S_BF16 {
|
|
defvar constraint = "@earlyclobber $rd";
|
|
foreach m = MxListFW in {
|
|
let VLMul = m.value, SEW=16 in
|
|
def "_" # m.MX : VPseudoUnaryNoMask<m.wvrclass, m.vrclass, constraint>,
|
|
SchedUnary<"WriteVFWCvtIToFV", "ReadVFWCvtIToFV", m.MX, 16,
|
|
forcePassthruRead=true>;
|
|
}
|
|
}
|
|
|
|
multiclass VPseudoVNCVT_BF16_S {
|
|
defvar constraint = "@earlyclobber $rd";
|
|
foreach m = MxListFW in {
|
|
let VLMul = m.value, SEW=16 in
|
|
def "_" # m.MX : VPseudoUnaryNoMaskRoundingMode<m.vrclass, m.wvrclass,
|
|
constraint>,
|
|
SchedUnary<"WriteVFNCvtFToFV", "ReadVFNCvtFToFV", m.MX, 16,
|
|
forcePassthruRead=true>;
|
|
}
|
|
}
|
|
|
|
multiclass VPatConversionS_BF16<string intrinsic, string instruction> {
|
|
foreach fvtiToFWti = AllWidenableBFloatToFloatVectors in {
|
|
defvar fvti = fvtiToFWti.Vti;
|
|
defvar fwti = fvtiToFWti.Wti;
|
|
let Predicates = [HasVendorXAndesVBFHCvt] in
|
|
def : VPatUnaryNoMask<intrinsic, instruction, "BF16",
|
|
fwti.Vector, fvti.Vector,
|
|
fvti.Log2SEW, fvti.LMul,
|
|
fwti.RegClass, fvti.RegClass>;
|
|
}
|
|
}
|
|
|
|
multiclass VPatConversionBF16_S<string intrinsic, string instruction> {
|
|
foreach fvtiToFWti = AllWidenableBFloatToFloatVectors in {
|
|
defvar fvti = fvtiToFWti.Vti;
|
|
defvar fwti = fvtiToFWti.Wti;
|
|
let Predicates = [HasVendorXAndesVBFHCvt] in
|
|
def : VPatUnaryNoMaskRoundingMode<intrinsic, instruction, "S",
|
|
fvti.Vector, fwti.Vector,
|
|
fvti.Log2SEW, fvti.LMul,
|
|
fvti.RegClass, fwti.RegClass>;
|
|
}
|
|
}
|
|
|
|
multiclass VPseudoVLN8<bit U> {
|
|
foreach lmul = MxSet<8>.m in {
|
|
defvar LInfo = lmul.MX;
|
|
defvar vreg = lmul.vrclass;
|
|
let VLMul = lmul.value in {
|
|
def "_V_" # LInfo :
|
|
VPseudoVLN8NoMask<vreg, U>,
|
|
VLESched<LInfo>;
|
|
def "_V_" # LInfo # "_MASK" :
|
|
VPseudoVLN8Mask<vreg, U>,
|
|
RISCVMaskedPseudo<MaskIdx=2>,
|
|
VLESched<LInfo>;
|
|
}
|
|
}
|
|
}
|
|
|
|
let fprclass = !cast<RegisterClass>("FPR32") in
|
|
def SCALAR_F16_FPR32 : FPR_Info<16>;
|
|
|
|
let hasSideEffects = 0 in
|
|
multiclass VPseudoVFPMAD_VF_RM {
|
|
foreach m = SCALAR_F16_FPR32.MxList in {
|
|
defm "" : VPseudoBinaryV_VF_RM<m, SCALAR_F16_FPR32, 0>,
|
|
SchedBinary<"WriteVFMulAddF", "ReadVFMulAddV", "ReadVFMulAddF",
|
|
m.MX, SCALAR_F16_FPR32.SEW, forcePassthruRead=true>;
|
|
}
|
|
}
|
|
|
|
multiclass VPatVFPMADBinaryV_VX_RM<string intrinsic, string instruction,
|
|
list<VTypeInfo> vtilist> {
|
|
foreach vti = vtilist in {
|
|
defvar kind = "V"#vti.ScalarSuffix;
|
|
defm : VPatBinaryRoundingMode<intrinsic,
|
|
instruction#"_"#kind#"_"#vti.LMul.MX,
|
|
vti.Vector, vti.Vector, f32, vti.Mask,
|
|
vti.Log2SEW, vti.RegClass,
|
|
vti.RegClass, FPR32>;
|
|
}
|
|
}
|
|
|
|
multiclass VPseudoVD4DOT_VV {
|
|
foreach m = [V_MF2, V_M1, V_M2, V_M4, V_M8] in {
|
|
defm "" : VPseudoBinaryV_VV<m>,
|
|
SchedBinary<"WriteVIALUV", "ReadVIALUV", "ReadVIALUV", m.MX,
|
|
forcePassthruRead=true>;
|
|
}
|
|
}
|
|
|
|
multiclass VPatTernaryVD4DOT_VV<string intrinsic, string instruction,
|
|
list<VTypeInfoToWide> vtilist> {
|
|
foreach vtiToWti = vtilist in {
|
|
defvar vti = vtiToWti.Vti;
|
|
defvar wti = vtiToWti.Wti;
|
|
let Predicates = GetVTypePredicates<wti>.Predicates in
|
|
defm : VPatTernaryWithPolicy<intrinsic, instruction, "VV",
|
|
wti.Vector, vti.Vector, vti.Vector,
|
|
wti.Mask, wti.Log2SEW, vti.LMul,
|
|
wti.RegClass, vti.RegClass, vti.RegClass>;
|
|
}
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// XAndesPerf
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
let DecoderNamespace = "XAndes" in {
|
|
|
|
let Predicates = [HasVendorXAndesPerf] in {
|
|
def NDS_BBC : NDSRVInstBB<0, "nds.bbc">;
|
|
def NDS_BBS : NDSRVInstBB<1, "nds.bbs">;
|
|
|
|
def NDS_BEQC : NDSRVInstBC<0b101, "nds.beqc">;
|
|
def NDS_BNEC : NDSRVInstBC<0b110, "nds.bnec">;
|
|
|
|
def NDS_BFOS : NDSRVInstBFO<0b011, "nds.bfos">;
|
|
def NDS_BFOZ : NDSRVInstBFO<0b010, "nds.bfoz">;
|
|
|
|
def NDS_LEA_H : NDSRVInstLEA<0b0000101, "nds.lea.h">;
|
|
def NDS_LEA_W : NDSRVInstLEA<0b0000110, "nds.lea.w">;
|
|
def NDS_LEA_D : NDSRVInstLEA<0b0000111, "nds.lea.d">;
|
|
|
|
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
|
|
def NDS_ADDIGP : NDSRVInstLBGP<0b01, "nds.addigp">;
|
|
|
|
def NDS_LBGP : NDSRVInstLBGP<0b00, "nds.lbgp">;
|
|
def NDS_LBUGP : NDSRVInstLBGP<0b10, "nds.lbugp">;
|
|
def NDS_LHGP : NDSRVInstLHGP<0b001, "nds.lhgp">;
|
|
def NDS_LHUGP : NDSRVInstLHGP<0b101, "nds.lhugp">;
|
|
def NDS_LWGP : NDSRVInstLWGP<0b010, "nds.lwgp">;
|
|
|
|
def NDS_SBGP : NDSRVInstSBGP<0b11, "nds.sbgp">;
|
|
def NDS_SHGP : NDSRVInstSHGP<0b000, "nds.shgp">;
|
|
def NDS_SWGP : NDSRVInstSWGP<0b100, "nds.swgp">;
|
|
|
|
def NDS_FFB : NDSRVInstRR<0b0010000, "nds.ffb">;
|
|
def NDS_FFZMISM : NDSRVInstRR<0b0010001, "nds.ffzmism">;
|
|
def NDS_FFMISM : NDSRVInstRR<0b0010010, "nds.ffmism">;
|
|
def NDS_FLMISM : NDSRVInstRR<0b0010011, "nds.flmism">;
|
|
} // Predicates = [HasVendorXAndesPerf]
|
|
|
|
let Predicates = [HasVendorXAndesPerf, IsRV64] in {
|
|
def NDS_LEA_B_ZE : NDSRVInstLEA<0b0001000, "nds.lea.b.ze">;
|
|
def NDS_LEA_H_ZE : NDSRVInstLEA<0b0001001, "nds.lea.h.ze">;
|
|
def NDS_LEA_W_ZE : NDSRVInstLEA<0b0001010, "nds.lea.w.ze">;
|
|
def NDS_LEA_D_ZE : NDSRVInstLEA<0b0001011, "nds.lea.d.ze">;
|
|
|
|
def NDS_LWUGP : NDSRVInstLWGP<0b110, "nds.lwugp">;
|
|
def NDS_LDGP : NDSRVInstLDGP<0b011, "nds.ldgp">;
|
|
|
|
def NDS_SDGP : NDSRVInstSDGP<0b111, "nds.sdgp">;
|
|
} // Predicates = [HasVendorXAndesPerf, IsRV64]
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// XAndesBFHCvt
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
let Predicates = [HasVendorXAndesBFHCvt] in {
|
|
def NDS_FCVT_S_BF16 : NDSRVInstBFHCvt<0b0000000, 0b00010,
|
|
FPR32, FPR16, "nds.fcvt.s.bf16">,
|
|
Sched<[WriteFCvtF16ToF32, ReadFCvtF16ToF32]>;
|
|
def NDS_FCVT_BF16_S : NDSRVInstBFHCvt<0b0000000, 0b00011,
|
|
FPR16, FPR32, "nds.fcvt.bf16.s">,
|
|
Sched<[WriteFCvtF32ToF16, ReadFCvtF32ToF16]>;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// XAndesVBFHCvt
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
let Predicates = [HasVendorXAndesVBFHCvt], Constraints = "@earlyclobber $vd",
|
|
mayRaiseFPException = true in {
|
|
let RVVConstraint = VS2Constraint, DestEEW = EEWSEWx2 in
|
|
def NDS_VFWCVT_S_BF16 : NDSRVInstVBFHCvt<0b00000, "nds.vfwcvt.s.bf16">;
|
|
let Uses = [FRM, VL, VTYPE] in
|
|
def NDS_VFNCVT_BF16_S : NDSRVInstVBFHCvt<0b00001, "nds.vfncvt.bf16.s">;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// XAndesVSIntLoad
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
let Predicates = [HasVendorXAndesVSIntLoad] in {
|
|
def NDS_VLN8_V : NDSRVInstVLN<0b00010, "nds.vln8.v">;
|
|
def NDS_VLNU8_V : NDSRVInstVLN<0b00011, "nds.vlnu8.v">;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// XAndesVPackFPH
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
let Predicates = [HasVendorXAndesVPackFPH],
|
|
Uses = [FRM, VL, VTYPE], mayRaiseFPException = true in {
|
|
def NDS_VFPMADT_VF : NDSRVInstVFPMAD<0b000010, "nds.vfpmadt">;
|
|
def NDS_VFPMADB_VF : NDSRVInstVFPMAD<0b000011, "nds.vfpmadb">;
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// XAndesVDot
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
let Predicates = [HasVendorXAndesVDot], Uses = [VL, VTYPE] in {
|
|
def NDS_VD4DOTS_VV : NDSRVInstVD4DOT<0b000100, "nds.vd4dots">;
|
|
def NDS_VD4DOTU_VV : NDSRVInstVD4DOT<0b000111, "nds.vd4dotu">;
|
|
def NDS_VD4DOTSU_VV : NDSRVInstVD4DOT<0b000101, "nds.vd4dotsu">;
|
|
}
|
|
} // DecoderNamespace = "XAndes"
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Pseudo-instructions and codegen patterns
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
class NDS_BBPat<CondCode Cond, NDSRVInstBB Inst>
|
|
: Pat<(riscv_brcc (and(XLenVT GPR:$rs1), PowerOf2:$mask), 0, Cond,
|
|
bb:$imm10),
|
|
(Inst GPR:$rs1, (Log2 PowerOf2:$mask), bare_simm11_lsb0:$imm10)>;
|
|
|
|
class NDS_BCPat<CondCode Cond, NDSRVInstBC Inst>
|
|
: Pat<(riscv_brcc (XLenVT GPR:$rs1), uimm7:$cimm, Cond, bb:$imm10),
|
|
(Inst GPR:$rs1, uimm7:$cimm, bare_simm11_lsb0:$imm10)>;
|
|
|
|
defm CC_UImmLog2XLen_NDS : SelectCC_GPR_riirr<GPR, uimmlog2xlen>;
|
|
defm CC_UImm7_NDS : SelectCC_GPR_riirr<GPR, uimm7>;
|
|
|
|
class SelectNDS_BB<CondCode Cond>
|
|
: Pat<(riscv_selectcc_frag:$cc (and(XLenVT GPR:$lhs), PowerOf2:$mask), 0,
|
|
Cond, (XLenVT GPR:$truev), GPR:$falsev),
|
|
(Select_GPR_Using_CC_UImmLog2XLen_NDS GPR:$lhs, (Log2 PowerOf2:$mask),
|
|
(IntCCtoRISCVCC $cc), GPR:$truev, GPR:$falsev)>;
|
|
|
|
class SelectNDS_BC<CondCode Cond>
|
|
: Pat<(riscv_selectcc_frag:$cc (XLenVT GPR:$lhs), uimm7:$cimm, Cond,
|
|
(XLenVT GPR:$truev), GPR:$falsev),
|
|
(Select_GPR_Using_CC_UImm7_NDS GPR:$lhs, uimm7:$cimm,
|
|
(IntCCtoRISCVCC $cc), GPR:$truev, GPR:$falsev)>;
|
|
|
|
let Predicates = [HasVendorXAndesPerf] in {
|
|
|
|
def : NDS_BBPat<SETEQ, NDS_BBC>;
|
|
def : NDS_BBPat<SETNE, NDS_BBS>;
|
|
|
|
def : SelectNDS_BB<SETEQ>;
|
|
def : SelectNDS_BB<SETNE>;
|
|
|
|
def : NDS_BCPat<SETEQ, NDS_BEQC>;
|
|
def : NDS_BCPat<SETNE, NDS_BNEC>;
|
|
|
|
def : SelectNDS_BC<SETEQ>;
|
|
def : SelectNDS_BC<SETNE>;
|
|
|
|
def : Pat<(sext_inreg (XLenVT GPR:$rs1), i16), (NDS_BFOS GPR:$rs1, 15, 0)>;
|
|
def : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (NDS_BFOS GPR:$rs1, 7, 0)>;
|
|
def : Pat<(sext_inreg (XLenVT GPR:$rs1), i1), (NDS_BFOS GPR:$rs1, 0, 0)>;
|
|
|
|
defm : ShxAddPat<1, NDS_LEA_H>;
|
|
defm : ShxAddPat<2, NDS_LEA_W>;
|
|
defm : ShxAddPat<3, NDS_LEA_D>;
|
|
|
|
def : CSImm12MulBy4Pat<NDS_LEA_W>;
|
|
def : CSImm12MulBy8Pat<NDS_LEA_D>;
|
|
} // Predicates = [HasVendorXAndesPerf]
|
|
|
|
let Predicates = [HasVendorXAndesPerf, IsRV64] in {
|
|
|
|
defm : ADD_UWPat<NDS_LEA_B_ZE>;
|
|
|
|
defm : ShxAdd_UWPat<1, NDS_LEA_H_ZE>;
|
|
defm : ShxAdd_UWPat<2, NDS_LEA_W_ZE>;
|
|
defm : ShxAdd_UWPat<3, NDS_LEA_D_ZE>;
|
|
|
|
defm : Sh1Add_UWPat<NDS_LEA_H_ZE>;
|
|
defm : Sh2Add_UWPat<NDS_LEA_W_ZE>;
|
|
defm : Sh3Add_UWPat<NDS_LEA_D_ZE>;
|
|
|
|
def : Sh1AddPat<NDS_LEA_H_ZE>;
|
|
def : Sh2AddPat<NDS_LEA_W_ZE>;
|
|
def : Sh3AddPat<NDS_LEA_D_ZE>;
|
|
} // Predicates = [HasVendorXAndesPerf, IsRV64]
|
|
|
|
let Predicates = [HasVendorXAndesBFHCvt] in {
|
|
def : Pat<(fpextend (bf16 FPR16:$rs)),
|
|
(NDS_FCVT_S_BF16 (bf16 FPR16:$rs))>;
|
|
def : Pat<(bf16 (fpround FPR32:$rs)),
|
|
(NDS_FCVT_BF16_S FPR32:$rs)>;
|
|
} // Predicates = [HasVendorXAndesBFHCvt]
|
|
|
|
let isCodeGenOnly = 1 in {
|
|
def NDS_FMV_BF16_X : FPUnaryOp_r<0b1111000, 0b00000, 0b000, FPR16, GPR, "fmv.w.x">,
|
|
Sched<[WriteFMovI32ToF32, ReadFMovI32ToF32]>;
|
|
def NDS_FMV_X_BF16 : FPUnaryOp_r<0b1110000, 0b00000, 0b000, GPR, FPR16, "fmv.x.w">,
|
|
Sched<[WriteFMovF32ToI32, ReadFMovF32ToI32]>;
|
|
}
|
|
|
|
let Predicates = [HasVendorXAndesBFHCvt] in {
|
|
def : Pat<(riscv_nds_fmv_bf16_x GPR:$src), (NDS_FMV_BF16_X GPR:$src)>;
|
|
def : Pat<(riscv_nds_fmv_x_anyextbf16 (bf16 FPR16:$src)),
|
|
(NDS_FMV_X_BF16 (bf16 FPR16:$src))>;
|
|
} // Predicates = [HasVendorXAndesBFHCvt]
|
|
|
|
// Use flh/fsh to load/store bf16 if zfh is enabled.
|
|
let Predicates = [HasStdExtZfh, HasVendorXAndesBFHCvt] in {
|
|
def : LdPat<load, FLH, bf16>;
|
|
def : StPat<store, FSH, FPR16, bf16>;
|
|
} // Predicates = [HasStdExtZfh, HasVendorXAndesBFHCvt]
|
|
|
|
let Predicates = [HasVendorXAndesVBFHCvt] in {
|
|
defm PseudoNDS_VFWCVT_S_BF16 : VPseudoVWCVT_S_BF16;
|
|
defm PseudoNDS_VFNCVT_BF16_S : VPseudoVNCVT_BF16_S;
|
|
} // Predicates = [HasVendorXAndesVBFHCvt]
|
|
|
|
defm : VPatConversionS_BF16<"int_riscv_nds_vfwcvt_s_bf16",
|
|
"PseudoNDS_VFWCVT_S">;
|
|
defm : VPatConversionBF16_S<"int_riscv_nds_vfncvt_bf16_s",
|
|
"PseudoNDS_VFNCVT_BF16">;
|
|
|
|
let Predicates = [HasVendorXAndesVSIntLoad] in {
|
|
defm PseudoNDS_VLN8 : VPseudoVLN8<0>;
|
|
defm PseudoNDS_VLNU8 : VPseudoVLN8<1>;
|
|
} // Predicates = [HasVendorXAndesVSIntLoad]
|
|
|
|
let Predicates = [HasVendorXAndesVPackFPH],
|
|
mayRaiseFPException = true in {
|
|
defm PseudoNDS_VFPMADT : VPseudoVFPMAD_VF_RM;
|
|
defm PseudoNDS_VFPMADB : VPseudoVFPMAD_VF_RM;
|
|
} // Predicates = [HasVendorXAndesVPackFPH]
|
|
|
|
defm : VPatVFPMADBinaryV_VX_RM<"int_riscv_nds_vfpmadt", "PseudoNDS_VFPMADT",
|
|
AllFP16Vectors>;
|
|
defm : VPatVFPMADBinaryV_VX_RM<"int_riscv_nds_vfpmadb", "PseudoNDS_VFPMADB",
|
|
AllFP16Vectors>;
|
|
|
|
let Predicates = [HasVendorXAndesVDot] in {
|
|
defm PseudoNDS_VD4DOTS : VPseudoVD4DOT_VV;
|
|
defm PseudoNDS_VD4DOTU : VPseudoVD4DOT_VV;
|
|
defm PseudoNDS_VD4DOTSU : VPseudoVD4DOT_VV;
|
|
}
|
|
|
|
defset list<VTypeInfoToWide> AllQuadWidenableVD4DOTVectors = {
|
|
def : VTypeInfoToWide<VI8MF2, VI32MF2>;
|
|
def : VTypeInfoToWide<VI8M1, VI32M1>;
|
|
def : VTypeInfoToWide<VI8M2, VI32M2>;
|
|
def : VTypeInfoToWide<VI8M4, VI32M4>;
|
|
def : VTypeInfoToWide<VI8M8, VI32M8>;
|
|
def : VTypeInfoToWide<VI16M1, VI64M1>;
|
|
def : VTypeInfoToWide<VI16M2, VI64M2>;
|
|
def : VTypeInfoToWide<VI16M4, VI64M4>;
|
|
def : VTypeInfoToWide<VI16M8, VI64M8>;
|
|
}
|
|
|
|
defm : VPatTernaryVD4DOT_VV<"int_riscv_nds_vd4dots", "PseudoNDS_VD4DOTS",
|
|
AllQuadWidenableVD4DOTVectors>;
|
|
defm : VPatTernaryVD4DOT_VV<"int_riscv_nds_vd4dotu", "PseudoNDS_VD4DOTU",
|
|
AllQuadWidenableVD4DOTVectors>;
|
|
defm : VPatTernaryVD4DOT_VV<"int_riscv_nds_vd4dotsu", "PseudoNDS_VD4DOTSU",
|
|
AllQuadWidenableVD4DOTVectors>;
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Pseudo-instructions for SFB (Short Forward Branch)
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
let Predicates = [HasShortForwardBranchOpt], hasSideEffects = 0,
|
|
mayLoad = 0, mayStore = 0, Size = 8, Constraints = "$dst = $falsev" in {
|
|
def PseudoCCNDS_BFOS : Pseudo<(outs GPR:$dst),
|
|
(ins GPR:$lhs, GPR:$rhs, cond_code:$cc,
|
|
GPR:$falsev, GPR:$rs1,
|
|
uimmlog2xlen:$msb, uimmlog2xlen:$lsb), []>,
|
|
Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
|
|
ReadSFBALU]>;
|
|
def PseudoCCNDS_BFOZ : Pseudo<(outs GPR:$dst),
|
|
(ins GPR:$lhs, GPR:$rhs, cond_code:$cc,
|
|
GPR:$falsev, GPR:$rs1,
|
|
uimmlog2xlen:$msb, uimmlog2xlen:$lsb), []>,
|
|
Sched<[WriteSFB, ReadSFBJmp, ReadSFBJmp, ReadSFBALU,
|
|
ReadSFBALU]>;
|
|
}
|