llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfoXCV.td
Craig Topper c8243251cb
[RISCV] Remove separate immediate condition codes from RISCVCC. NFC (#145762)
This wasn't scalable and made the RISCVCC enum effectively just
a different way of spelling the branch opcodes.
    
This patch reduces RISCVCC back down to 6 enum values. The primary user
is select pseudoinstructions which now share the same encoding across
all
vendor extensions. The select opcode and condition code are used to
determine the branch opcode when expanding the pseudo.
    
The Cond SmallVector returned by analyzeBranch now returns the opcode
instead of the RISCVCC. reverseBranchCondition now works directly on
opcodes. getOppositeBranchCondition is also retained.

Stacked on #145622
2025-06-25 23:09:24 -07:00

842 lines
35 KiB
TableGen

//===-- RISCVInstrInfoXCV.td - CORE-V 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 vendor extensions defined by Core-V extensions.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
// Operand and SDNode transformation definitions.
//===----------------------------------------------------------------------===//
def CVrrAsmOperand : AsmOperandClass {
let Name = "RegReg";
let ParserMethod = "parseRegReg";
}
def CVrr : Operand<i32>,
ComplexPattern<i32, 2, "SelectAddrRegReg",[]> {
let ParserMatchClass = CVrrAsmOperand;
let PrintMethod = "printRegReg";
let MIOperandInfo = (ops GPR:$base, GPR:$offset);
}
def cv_tuimm2 : TImmLeaf<XLenVT, [{return isUInt<2>(Imm);}]>;
def cv_tuimm5 : TImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]>;
def cv_uimm10 : ImmLeaf<XLenVT, [{return isUInt<10>(Imm);}]>;
def CV_LO5: SDNodeXForm<imm, [{
return CurDAG->getTargetConstant(N->getZExtValue() & 0x1f, SDLoc(N),
N->getValueType(0));
}]>;
def CV_HI5: SDNodeXForm<imm, [{
return CurDAG->getTargetConstant(N->getZExtValue() >> 5, SDLoc(N),
N->getValueType(0));
}]>;
def powerOf2Minus1 : ImmLeaf<XLenVT, [{ return isPowerOf2_32(Imm+1); }]>;
def trailing1sPlus1 : SDNodeXForm<imm, [{
return CurDAG->getTargetConstant(
llvm::countr_one(N->getZExtValue()) + 1,
SDLoc(N), N->getValueType(0));
}]>;
//===----------------------------------------------------------------------===//
// Instruction Class Templates
//===----------------------------------------------------------------------===//
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
class CVInstBitManipRII<bits<2> funct2, bits<3> funct3, dag outs, dag ins,
string opcodestr, string argstr>
: RVInstIBase<funct3, OPC_CUSTOM_2, outs, ins, opcodestr, argstr> {
bits<5> is3;
bits<5> is2;
let Inst{31-30} = funct2;
let Inst{29-25} = is3;
let Inst{24-20} = is2;
}
class CVBitManipRII<bits<2> funct2, bits<3> funct3, string opcodestr,
Operand i3type = uimm5>
: CVInstBitManipRII<funct2, funct3, (outs GPR:$rd),
(ins GPR:$rs1, i3type:$is3, uimm5:$is2),
opcodestr, "$rd, $rs1, $is3, $is2">;
class CVBitManipRR<bits<7> funct7, string opcodestr>
: RVInstR<funct7, 0b011, OPC_CUSTOM_1, (outs GPR:$rd),
(ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2">;
class CVBitManipR<bits<7> funct7, string opcodestr>
: RVInstR<funct7, 0b011, OPC_CUSTOM_1, (outs GPR:$rd),
(ins GPR:$rs1), opcodestr, "$rd, $rs1"> {
let rs2 = 0b00000;
}
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
class CVInstMac<bits<7> funct7, bits<3> funct3, string opcodestr>
: RVInstR<funct7, funct3, OPC_CUSTOM_1,
(outs GPR:$rd_wb), (ins GPR:$rd, GPR:$rs1, GPR:$rs2),
opcodestr, "$rd, $rs1, $rs2"> {
let Constraints = "$rd = $rd_wb";
let hasSideEffects = 0;
let mayLoad = 0;
let mayStore = 0;
}
class CVInstMacMulN<bits<2> funct2, bits<3> funct3, dag outs, dag ins,
string opcodestr>
: RVInstRBase<funct3, OPC_CUSTOM_2, outs, ins, opcodestr,
"$rd, $rs1, $rs2, $imm5"> {
bits<5> imm5;
let Inst{31-30} = funct2;
let Inst{29-25} = imm5;
let hasSideEffects = 0;
let mayLoad = 0;
let mayStore = 0;
}
class CVInstMacN<bits<2> funct2, bits<3> funct3, string opcodestr>
: CVInstMacMulN<funct2, funct3, (outs GPR:$rd_wb),
(ins GPR:$rd, GPR:$rs1, GPR:$rs2, uimm5:$imm5), opcodestr> {
let Constraints = "$rd = $rd_wb";
}
class CVInstMulN<bits<2> funct2, bits<3> funct3, string opcodestr>
: CVInstMacMulN<funct2, funct3, (outs GPR:$rd),
(ins GPR:$rs1, GPR:$rs2, uimm5:$imm5), opcodestr>;
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
class CVInstAluRRI<bits<2> funct2, bits<3> funct3, string opcodestr>
: RVInstRBase<funct3, OPC_CUSTOM_2, (outs GPR:$rd),
(ins GPR:$rs1, GPR:$rs2, uimm5:$imm5), opcodestr,
"$rd, $rs1, $rs2, $imm5"> {
bits<5> imm5;
let Inst{31-30} = funct2;
let Inst{29-25} = imm5;
}
class CVInstAluRR<bits<7> funct7, bits<3> funct3, string opcodestr>
: RVInstR<funct7, funct3, OPC_CUSTOM_1, (outs GPR:$rd),
(ins GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2">;
class CVInstAluRRNR<bits<7> funct7, bits<3> funct3, string opcodestr>
: RVInstR<funct7, funct3, OPC_CUSTOM_1, (outs GPR:$rd_wb),
(ins GPR:$rd, GPR:$rs1, GPR:$rs2), opcodestr, "$rd, $rs1, $rs2"> {
let Constraints = "$rd = $rd_wb";
}
class CVInstAluRI<bits<7> funct7, bits<3> funct3, string opcodestr>
: RVInstIBase<funct3, OPC_CUSTOM_1, (outs GPR:$rd),
(ins GPR:$rs1, uimm5:$imm5), opcodestr,
"$rd, $rs1, $imm5"> {
bits<5> imm5;
let Inst{31-25} = funct7;
let Inst{24-20} = imm5;
}
class CVInstAluR<bits<7> funct7, bits<3> funct3, string opcodestr>
: RVInstR<funct7, funct3, OPC_CUSTOM_1, (outs GPR:$rd), (ins GPR:$rs1),
opcodestr, "$rd, $rs1"> {
let rs2 = 0b00000;
}
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
class CVInstSIMDRR<bits<5> funct5, bit F, bit funct1, bits<3> funct3,
RISCVOpcode opcode, dag outs,
dag ins, string opcodestr, string argstr>
: RVInstRBase<funct3, opcode, outs, ins, opcodestr, argstr> {
let Inst{31-27} = funct5;
let Inst{26} = F;
let Inst{25} = funct1;
}
class CVInstSIMDRI<bits<5> funct5, bit F, bits<3> funct3, RISCVOpcode opcode,
dag outs, dag ins, string opcodestr, string argstr>
: RVInstIBase<funct3, opcode, outs, ins, opcodestr, argstr> {
bits<6> imm6;
let Inst{31-27} = funct5;
let Inst{26} = F;
let Inst{25} = imm6{0}; // funct1 unused
let Inst{24-20} = imm6{5-1};
}
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
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,
Operand immtype = simm6>
: CVInstSIMDRI<funct5, F, funct3, OPC_CUSTOM_3, (outs GPR:$rd),
(ins GPR:$rs1, immtype:$imm6), opcodestr, "$rd, $rs1, $imm6">;
class CVSIMDRIWb<bits<5> funct5, bit F, bits<3> funct3, string opcodestr,
Operand immtype = simm6>
: CVInstSIMDRI<funct5, F, funct3, OPC_CUSTOM_3,
(outs GPR:$rd_wb), (ins GPR:$rd, GPR:$rs1, immtype:$imm6),
opcodestr, "$rd, $rs1, $imm6"> {
let Constraints = "$rd = $rd_wb";
}
class CVSIMDRU<bits<5> funct5, bit F, bits<3> funct3, string opcodestr>
: CVSIMDRI<funct5, F, funct3, opcodestr, uimm6>;
class CVSIMDRUWb<bits<5> funct5, bit F, bits<3> funct3, string opcodestr>
: CVSIMDRIWb<funct5, F, funct3, opcodestr, uimm6>;
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;
}
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0
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 : CVSIMDRI<funct5, F, 0b110, "cv." # mnemonic # ".sci.h", uimm4>;
def CV_ # NAME # _SCI_B : CVSIMDRI<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">;
}
class CVInstImmBranch<bits<3> funct3, dag outs, dag ins,
string opcodestr, string argstr>
: RVInstB<funct3, OPC_CUSTOM_0, outs, ins, opcodestr, argstr> {
bits<5> imm5;
let rs2 = imm5;
let isBranch = 1;
let isTerminator = 1;
let hasSideEffects = 0;
let mayLoad = 0;
let mayStore = 0;
}
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
class CVLoad_ri_inc<bits<3> funct3, string opcodestr>
: RVInstI<funct3, OPC_CUSTOM_0, (outs GPR:$rd, GPR:$rs1_wb),
(ins GPRMem:$rs1, simm12:$imm12),
opcodestr, "$rd, (${rs1}), ${imm12}"> {
let Constraints = "$rs1_wb = $rs1";
}
class CVLoad_rr_inc<bits<7> funct7, bits<3> funct3, string opcodestr>
: RVInstR<funct7, funct3, OPC_CUSTOM_1, (outs GPR:$rd, GPR:$rs1_wb),
(ins GPRMem:$rs1, GPR:$rs2),
opcodestr, "$rd, (${rs1}), ${rs2}"> {
let Constraints = "$rs1_wb = $rs1";
}
class CVLoad_rr<bits<7> funct7, bits<3> funct3, string opcodestr>
: RVInstR<funct7, funct3, OPC_CUSTOM_1, (outs GPR:$rd),
(ins (CVrr $rs1, $rs2):$addr),
opcodestr, "$rd, $addr">;
} // hasSideEffects = 0, mayLoad = 1, mayStore = 0
let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
class CVStore_ri_inc<bits<3> funct3, string opcodestr>
: RVInstS<funct3, OPC_CUSTOM_1, (outs GPR:$rs1_wb),
(ins GPR:$rs2, GPR:$rs1, simm12:$imm12),
opcodestr, "$rs2, (${rs1}), ${imm12}"> {
let Constraints = "$rs1_wb = $rs1";
}
class CVStore_rr_inc<bits<3> funct3, bits<7> funct7, string opcodestr>
: RVInst<(outs GPR:$rs1_wb), (ins GPR:$rs2, GPR:$rs1, GPR:$rs3), opcodestr,
"$rs2, (${rs1}), ${rs3}", [], InstFormatOther> {
bits<5> rs3;
bits<5> rs2;
bits<5> rs1;
let Inst{31-25} = funct7;
let Inst{24-20} = rs2;
let Inst{19-15} = rs1;
let Inst{14-12} = funct3;
let Inst{11-7} = rs3;
let Inst{6-0} = OPC_CUSTOM_1.Value;
let Constraints = "$rs1_wb = $rs1";
}
class CVStore_rr<bits<3> funct3, bits<7> funct7, string opcodestr>
: RVInst<(outs), (ins GPR:$rs2, (CVrr $rs1, $rs3):$addr), opcodestr,
"$rs2, $addr", [], InstFormatOther> {
bits<5> rs1;
bits<5> rs2;
bits<5> rs3;
let Inst{31-25} = funct7;
let Inst{24-20} = rs2;
let Inst{19-15} = rs1;
let Inst{14-12} = funct3;
let Inst{11-7} = rs3;
let Inst{6-0} = OPC_CUSTOM_1.Value;
}
} // hasSideEffects = 0, mayLoad = 0, mayStore = 1
class CVLoad_ri<bits<3> funct3, string opcodestr>
: RVInstI<funct3, OPC_CUSTOM_0, (outs GPR:$rd),
(ins GPRMem:$rs1, simm12:$imm12), opcodestr, "$rd, ${imm12}(${rs1})">;
//===----------------------------------------------------------------------===//
// Instructions
//===----------------------------------------------------------------------===//
let DecoderNamespace = "XCV" in {
let Predicates = [HasVendorXCVbitmanip, IsRV32] in {
def CV_EXTRACT : CVBitManipRII<0b00, 0b000, "cv.extract">;
def CV_EXTRACTU : CVBitManipRII<0b01, 0b000, "cv.extractu">;
def CV_BCLR : CVBitManipRII<0b00, 0b001, "cv.bclr">;
def CV_BSET : CVBitManipRII<0b01, 0b001, "cv.bset">;
def CV_BITREV : CVBitManipRII<0b11, 0b001, "cv.bitrev", uimm2>;
def CV_EXTRACTR : CVBitManipRR<0b0011000, "cv.extractr">;
def CV_EXTRACTUR : CVBitManipRR<0b0011001, "cv.extractur">;
let Constraints = "$rd = $rd_wb" in {
def CV_INSERT : CVInstBitManipRII<0b10, 0b000, (outs GPR:$rd_wb),
(ins GPR:$rd, GPR:$rs1, uimm5:$is3, uimm5:$is2),
"cv.insert", "$rd, $rs1, $is3, $is2">;
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in
def CV_INSERTR : RVInstR<0b0011010, 0b011, OPC_CUSTOM_1, (outs GPR:$rd_wb),
(ins GPR:$rd, GPR:$rs1, GPR:$rs2),
"cv.insertr", "$rd, $rs1, $rs2">;
}
def CV_BCLRR : CVBitManipRR<0b0011100, "cv.bclrr">;
def CV_BSETR : CVBitManipRR<0b0011101, "cv.bsetr">;
def CV_ROR : CVBitManipRR<0b0100000, "cv.ror">;
def CV_FF1 : CVBitManipR<0b0100001, "cv.ff1">;
def CV_FL1 : CVBitManipR<0b0100010, "cv.fl1">;
def CV_CLB : CVBitManipR<0b0100011, "cv.clb">;
def CV_CNT : CVBitManipR<0b0100100, "cv.cnt">;
} // Predicates = [HasVendorXCVbitmanip, IsRV32]
let Predicates = [HasVendorXCVmac, IsRV32] in {
// 32x32 bit macs
def CV_MAC : CVInstMac<0b1001000, 0b011, "cv.mac">,
Sched<[]>;
def CV_MSU : CVInstMac<0b1001001, 0b011, "cv.msu">,
Sched<[]>;
// Signed 16x16 bit macs with imm
def CV_MACSN : CVInstMacN<0b00, 0b110, "cv.macsn">,
Sched<[]>;
def CV_MACHHSN : CVInstMacN<0b01, 0b110, "cv.machhsn">,
Sched<[]>;
def CV_MACSRN : CVInstMacN<0b10, 0b110, "cv.macsrn">,
Sched<[]>;
def CV_MACHHSRN : CVInstMacN<0b11, 0b110, "cv.machhsrn">,
Sched<[]>;
// Unsigned 16x16 bit macs with imm
def CV_MACUN : CVInstMacN<0b00, 0b111, "cv.macun">,
Sched<[]>;
def CV_MACHHUN : CVInstMacN<0b01, 0b111, "cv.machhun">,
Sched<[]>;
def CV_MACURN : CVInstMacN<0b10, 0b111, "cv.macurn">,
Sched<[]>;
def CV_MACHHURN : CVInstMacN<0b11, 0b111, "cv.machhurn">,
Sched<[]>;
// Signed 16x16 bit muls with imm
def CV_MULSN : CVInstMulN<0b00, 0b100, "cv.mulsn">,
Sched<[]>;
def CV_MULHHSN : CVInstMulN<0b01, 0b100, "cv.mulhhsn">,
Sched<[]>;
def CV_MULSRN : CVInstMulN<0b10, 0b100, "cv.mulsrn">,
Sched<[]>;
def CV_MULHHSRN : CVInstMulN<0b11, 0b100, "cv.mulhhsrn">,
Sched<[]>;
// Unsigned 16x16 bit muls with imm
def CV_MULUN : CVInstMulN<0b00, 0b101, "cv.mulun">,
Sched<[]>;
def CV_MULHHUN : CVInstMulN<0b01, 0b101, "cv.mulhhun">,
Sched<[]>;
def CV_MULURN : CVInstMulN<0b10, 0b101, "cv.mulurn">,
Sched<[]>;
def CV_MULHHURN : CVInstMulN<0b11, 0b101, "cv.mulhhurn">,
Sched<[]>;
} // Predicates = [HasVendorXCVmac, IsRV32]
let Predicates = [HasVendorXCValu, IsRV32] in {
// General ALU Operations
def CV_ABS : CVInstAluR<0b0101000, 0b011, "cv.abs">,
Sched<[]>;
def CV_SLE : CVInstAluRR<0b0101001, 0b011, "cv.sle">,
Sched<[]>;
def CV_SLEU : CVInstAluRR<0b0101010, 0b011, "cv.sleu">,
Sched<[]>;
def CV_MIN : CVInstAluRR<0b0101011, 0b011, "cv.min">,
Sched<[]>;
def CV_MINU : CVInstAluRR<0b0101100, 0b011, "cv.minu">,
Sched<[]>;
def CV_MAX : CVInstAluRR<0b0101101, 0b011, "cv.max">,
Sched<[]>;
def CV_MAXU : CVInstAluRR<0b0101110, 0b011, "cv.maxu">,
Sched<[]>;
def CV_EXTHS : CVInstAluR<0b0110000, 0b011, "cv.exths">,
Sched<[]>;
def CV_EXTHZ : CVInstAluR<0b0110001, 0b011, "cv.exthz">,
Sched<[]>;
def CV_EXTBS : CVInstAluR<0b0110010, 0b011, "cv.extbs">,
Sched<[]>;
def CV_EXTBZ : CVInstAluR<0b0110011, 0b011, "cv.extbz">,
Sched<[]>;
def CV_CLIP : CVInstAluRI<0b0111000, 0b011, "cv.clip">,
Sched<[]>;
def CV_CLIPU : CVInstAluRI<0b0111001, 0b011, "cv.clipu">,
Sched<[]>;
def CV_CLIPR : CVInstAluRR<0b0111010, 0b011, "cv.clipr">,
Sched<[]>;
def CV_CLIPUR : CVInstAluRR<0b0111011, 0b011, "cv.clipur">,
Sched<[]>;
def CV_ADDN : CVInstAluRRI<0b00, 0b010, "cv.addn">,
Sched<[]>;
def CV_ADDUN : CVInstAluRRI<0b01, 0b010, "cv.addun">,
Sched<[]>;
def CV_ADDRN : CVInstAluRRI<0b10, 0b010, "cv.addrn">,
Sched<[]>;
def CV_ADDURN : CVInstAluRRI<0b11, 0b010, "cv.addurn">,
Sched<[]>;
def CV_SUBN : CVInstAluRRI<0b00, 0b011, "cv.subn">,
Sched<[]>;
def CV_SUBUN : CVInstAluRRI<0b01, 0b011, "cv.subun">,
Sched<[]>;
def CV_SUBRN : CVInstAluRRI<0b10, 0b011, "cv.subrn">,
Sched<[]>;
def CV_SUBURN : CVInstAluRRI<0b11, 0b011, "cv.suburn">,
Sched<[]>;
def CV_ADDNR : CVInstAluRRNR<0b1000000, 0b011, "cv.addnr">,
Sched<[]>;
def CV_ADDUNR : CVInstAluRRNR<0b1000001, 0b011, "cv.addunr">,
Sched<[]>;
def CV_ADDRNR : CVInstAluRRNR<0b1000010, 0b011, "cv.addrnr">,
Sched<[]>;
def CV_ADDURNR : CVInstAluRRNR<0b1000011, 0b011, "cv.addurnr">,
Sched<[]>;
def CV_SUBNR : CVInstAluRRNR<0b1000100, 0b011, "cv.subnr">,
Sched<[]>;
def CV_SUBUNR : CVInstAluRRNR<0b1000101, 0b011, "cv.subunr">,
Sched<[]>;
def CV_SUBRNR : CVInstAluRRNR<0b1000110, 0b011, "cv.subrnr">,
Sched<[]>;
def CV_SUBURNR : CVInstAluRRNR<0b1000111, 0b011, "cv.suburnr">,
Sched<[]>;
} // Predicates = [HasVendorXCValu, IsRV32]
let Predicates = [HasVendorXCVsimd, IsRV32] 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">;
}
let Predicates = [HasVendorXCVbi, IsRV32] in {
// Immediate branching operations
def CV_BEQIMM : CVInstImmBranch<0b110, (outs),
(ins GPR:$rs1, simm5:$imm5, bare_simm13_lsb0:$imm12),
"cv.beqimm", "$rs1, $imm5, $imm12">, Sched<[]>;
def CV_BNEIMM : CVInstImmBranch<0b111, (outs),
(ins GPR:$rs1, simm5:$imm5, bare_simm13_lsb0:$imm12),
"cv.bneimm", "$rs1, $imm5, $imm12">, Sched<[]>;
}
let Predicates = [HasVendorXCVmem, IsRV32] in {
// Register-Immediate load with post-increment
def CV_LB_ri_inc : CVLoad_ri_inc<0b000, "cv.lb">;
def CV_LBU_ri_inc : CVLoad_ri_inc<0b100, "cv.lbu">;
def CV_LH_ri_inc : CVLoad_ri_inc<0b001, "cv.lh">;
def CV_LHU_ri_inc : CVLoad_ri_inc<0b101, "cv.lhu">;
def CV_LW_ri_inc : CVLoad_ri_inc<0b010, "cv.lw">;
// Register-Register load with post-increment
def CV_LB_rr_inc : CVLoad_rr_inc<0b0000000, 0b011, "cv.lb">;
def CV_LBU_rr_inc : CVLoad_rr_inc<0b0001000, 0b011, "cv.lbu">;
def CV_LH_rr_inc : CVLoad_rr_inc<0b0000001, 0b011, "cv.lh">;
def CV_LHU_rr_inc : CVLoad_rr_inc<0b0001001, 0b011, "cv.lhu">;
def CV_LW_rr_inc : CVLoad_rr_inc<0b0000010, 0b011, "cv.lw">;
// Register-Register load
def CV_LB_rr : CVLoad_rr<0b0000100, 0b011, "cv.lb">;
def CV_LBU_rr : CVLoad_rr<0b0001100, 0b011, "cv.lbu">;
def CV_LH_rr : CVLoad_rr<0b0000101, 0b011, "cv.lh">;
def CV_LHU_rr : CVLoad_rr<0b0001101, 0b011, "cv.lhu">;
def CV_LW_rr : CVLoad_rr<0b0000110, 0b011, "cv.lw">;
// Register-Immediate store with post-increment
def CV_SB_ri_inc : CVStore_ri_inc<0b000, "cv.sb">;
def CV_SH_ri_inc : CVStore_ri_inc<0b001, "cv.sh">;
def CV_SW_ri_inc : CVStore_ri_inc<0b010, "cv.sw">;
// Register-Register store with post-increment
def CV_SB_rr_inc : CVStore_rr_inc<0b011, 0b0010000, "cv.sb">;
def CV_SH_rr_inc : CVStore_rr_inc<0b011, 0b0010001, "cv.sh">;
def CV_SW_rr_inc : CVStore_rr_inc<0b011, 0b0010010, "cv.sw">;
// Register-Register store
def CV_SB_rr : CVStore_rr<0b011, 0b0010100, "cv.sb">;
def CV_SH_rr : CVStore_rr<0b011, 0b0010101, "cv.sh">;
def CV_SW_rr : CVStore_rr<0b011, 0b0010110, "cv.sw">;
}
let Predicates = [HasVendorXCVelw, IsRV32], hasSideEffects = 0,
mayLoad = 1, mayStore = 0 in {
// Event load
def CV_ELW : CVLoad_ri<0b011, "cv.elw">;
}
} // DecoderNamespace = "XCV"
//===----------------------------------------------------------------------===//
// Aliases
//===----------------------------------------------------------------------===//
let Predicates = [HasVendorXCVmac, IsRV32] in {
// Xcvmac Pseudo Instructions
// Signed 16x16 bit muls
def : InstAlias<"cv.muls $rd1, $rs1, $rs2",
(CV_MULSN GPR:$rd1, GPR:$rs1, GPR:$rs2, 0)>;
def : InstAlias<"cv.mulhhs $rd1, $rs1, $rs2",
(CV_MULHHSN GPR:$rd1, GPR:$rs1, GPR:$rs2, 0)>;
// Unsigned 16x16 bit muls
def : InstAlias<"cv.mulu $rd1, $rs1, $rs2",
(CV_MULUN GPR:$rd1, GPR:$rs1, GPR:$rs2, 0)>;
def : InstAlias<"cv.mulhhu $rd1, $rs1, $rs2",
(CV_MULHHUN GPR:$rd1, GPR:$rs1, GPR:$rs2, 0)>;
} // Predicates = [HasVendorXCVmac, IsRV32]
let Predicates = [HasVendorXCValu, IsRV32] in {
def : MnemonicAlias<"cv.slet", "cv.sle">;
def : MnemonicAlias<"cv.sletu", "cv.sleu">;
}
//===----------------------------------------------------------------------===//
// Patterns for load & store operations
//===----------------------------------------------------------------------===//
class CVLdrrPat<PatFrag LoadOp, RVInst Inst>
: Pat<(XLenVT (LoadOp CVrr:$regreg)),
(Inst CVrr:$regreg)>;
class CVStriPat<PatFrag StoreOp, RVInst Inst>
: Pat<(StoreOp (XLenVT GPR:$rs2), GPR:$rs1, simm12:$imm12),
(Inst GPR:$rs2, GPR:$rs1, simm12:$imm12)>;
class CVStrriPat<PatFrag StoreOp, RVInst Inst>
: Pat<(StoreOp (XLenVT GPR:$rs2), GPR:$rs1, GPR:$rs3),
(Inst GPR:$rs2, GPR:$rs1, GPR:$rs3)>;
class CVStrrPat<PatFrag StoreOp, RVInst Inst>
: Pat<(StoreOp (XLenVT GPR:$rs2), CVrr:$regreg),
(Inst GPR:$rs2, CVrr:$regreg)>;
let Predicates = [HasVendorXCVmem, IsRV32], AddedComplexity = 1 in {
def : CVLdrrPat<sextloadi8, CV_LB_rr>;
def : CVLdrrPat<zextloadi8, CV_LBU_rr>;
def : CVLdrrPat<extloadi8, CV_LBU_rr>;
def : CVLdrrPat<sextloadi16, CV_LH_rr>;
def : CVLdrrPat<zextloadi16, CV_LHU_rr>;
def : CVLdrrPat<extloadi16, CV_LHU_rr>;
def : CVLdrrPat<load, CV_LW_rr>;
def : CVStriPat<post_truncsti8, CV_SB_ri_inc>;
def : CVStriPat<post_truncsti16, CV_SH_ri_inc>;
def : CVStriPat<post_store, CV_SW_ri_inc>;
def : CVStrriPat<post_truncsti8, CV_SB_rr_inc>;
def : CVStrriPat<post_truncsti16, CV_SH_rr_inc>;
def : CVStrriPat<post_store, CV_SW_rr_inc>;
def : CVStrrPat<truncstorei8, CV_SB_rr>;
def : CVStrrPat<truncstorei16, CV_SH_rr>;
def : CVStrrPat<store, CV_SW_rr>;
}
multiclass PatCoreVBitManip<Intrinsic intr> {
def : PatGprGpr<intr, !cast<RVInst>("CV_" # NAME # "R")>;
def : Pat<(intr GPR:$rs1, cv_uimm10:$imm),
(!cast<RVInst>("CV_" # NAME)
GPR:$rs1, (CV_HI5 cv_uimm10:$imm), (CV_LO5 cv_uimm10:$imm))>;
}
let Predicates = [HasVendorXCVbitmanip, IsRV32] in {
defm EXTRACT : PatCoreVBitManip<int_riscv_cv_bitmanip_extract>;
defm EXTRACTU : PatCoreVBitManip<int_riscv_cv_bitmanip_extractu>;
defm BCLR : PatCoreVBitManip<int_riscv_cv_bitmanip_bclr>;
defm BSET : PatCoreVBitManip<int_riscv_cv_bitmanip_bset>;
def : Pat<(int_riscv_cv_bitmanip_insert GPR:$rs1, GPR:$rs2, GPR:$rd),
(CV_INSERTR GPR:$rd, GPR:$rs1, GPR:$rs2)>;
def : Pat<(int_riscv_cv_bitmanip_insert GPR:$rs1, cv_uimm10:$imm, GPR:$rd),
(CV_INSERT GPR:$rd, GPR:$rs1, (CV_HI5 cv_uimm10:$imm),
(CV_LO5 cv_uimm10:$imm))>;
def : PatGpr<cttz, CV_FF1>;
def : PatGpr<ctlz, CV_FL1>;
def : PatGpr<int_riscv_cv_bitmanip_clb, CV_CLB>;
def : PatGpr<ctpop, CV_CNT>;
def : PatGprGpr<rotr, CV_ROR>;
def : Pat<(int_riscv_cv_bitmanip_bitrev GPR:$rs1, cv_tuimm5:$pts,
cv_tuimm2:$radix),
(CV_BITREV GPR:$rs1, cv_tuimm2:$radix, cv_tuimm5:$pts)>;
def : Pat<(bitreverse (XLenVT GPR:$rs)), (CV_BITREV GPR:$rs, 0, 0)>;
}
class PatCoreVAluGpr<string intr, string asm> :
PatGpr<!cast<Intrinsic>("int_riscv_cv_alu_" # intr),
!cast<RVInst>("CV_" # asm)>;
class PatCoreVAluGprGpr <string intr, string asm> :
PatGprGpr<!cast<Intrinsic>("int_riscv_cv_alu_" # intr),
!cast<RVInst>("CV_" # asm)>;
multiclass PatCoreVAluGprImm<Intrinsic intr> {
def : PatGprGpr<intr, !cast<RVInst>("CV_" # NAME # "R")>;
def : Pat<(intr (XLenVT GPR:$rs1), powerOf2Minus1:$upperBound),
(!cast<RVInst>("CV_" # NAME) GPR:$rs1,
(trailing1sPlus1 imm:$upperBound))>;
}
multiclass PatCoreVAluGprGprImm<Intrinsic intr> {
def : Pat<(intr GPR:$rs1, GPR:$rs2, GPR:$rs3),
(!cast<RVInst>("CV_" # NAME # "R") GPR:$rs1, GPR:$rs2, GPR:$rs3)>;
def : Pat<(intr GPR:$rs1, GPR:$rs2, uimm5:$imm),
(!cast<RVInst>("CV_" # NAME) GPR:$rs1, GPR:$rs2, uimm5:$imm)>;
}
let Predicates = [HasVendorXCValu, IsRV32], AddedComplexity = 1 in {
def : PatGpr<abs, CV_ABS>;
def : PatGprGpr<setle, CV_SLE>;
def : PatGprGpr<setule, CV_SLEU>;
def : PatGprGpr<smin, CV_MIN>;
def : PatGprGpr<umin, CV_MINU>;
def : PatGprGpr<smax, CV_MAX>;
def : PatGprGpr<umax, CV_MAXU>;
def : Pat<(sext_inreg (XLenVT GPR:$rs1), i16), (CV_EXTHS GPR:$rs1)>;
def : Pat<(sext_inreg (XLenVT GPR:$rs1), i8), (CV_EXTBS GPR:$rs1)>;
def : Pat<(and (XLenVT GPR:$rs1), 0xffff), (CV_EXTHZ GPR:$rs1)>;
def : Pat<(and (XLenVT GPR:$rs1), 0xff), (CV_EXTBZ GPR:$rs1)>;
defm CLIP : PatCoreVAluGprImm<int_riscv_cv_alu_clip>;
defm CLIPU : PatCoreVAluGprImm<int_riscv_cv_alu_clipu>;
defm ADDN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addN>;
defm ADDUN : PatCoreVAluGprGprImm<int_riscv_cv_alu_adduN>;
defm ADDRN : PatCoreVAluGprGprImm<int_riscv_cv_alu_addRN>;
defm ADDURN : PatCoreVAluGprGprImm<int_riscv_cv_alu_adduRN>;
defm SUBN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subN>;
defm SUBUN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subuN>;
defm SUBRN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subRN>;
defm SUBURN : PatCoreVAluGprGprImm<int_riscv_cv_alu_subuRN>;
} // Predicates = [HasVendorXCValu, IsRV32]
//===----------------------------------------------------------------------===//
// Patterns for immediate branching operations
//===----------------------------------------------------------------------===//
let Predicates = [HasVendorXCVbi, IsRV32], AddedComplexity = 2 in {
def : Pat<(riscv_brcc GPR:$rs1, simm5:$imm5, SETEQ, bb:$imm12),
(CV_BEQIMM GPR:$rs1, simm5:$imm5, bare_simm13_lsb0_bb:$imm12)>;
def : Pat<(riscv_brcc GPR:$rs1, simm5:$imm5, SETNE, bb:$imm12),
(CV_BNEIMM GPR:$rs1, simm5:$imm5, bare_simm13_lsb0_bb:$imm12)>;
defm CC_SImm5_CV : SelectCC_GPR_riirr<GPR, simm5>;
class Selectbi<CondCode Cond>
: Pat<(riscv_selectcc_frag:$cc (i32 GPR:$lhs), simm5:$Constant, Cond,
(i32 GPR:$truev), GPR:$falsev),
(Select_GPR_Using_CC_SImm5_CV GPR:$lhs, simm5:$Constant,
(IntCCtoRISCVCC $cc), GPR:$truev, GPR:$falsev)>;
def : Selectbi<SETEQ>;
def : Selectbi<SETNE>;
}
class PatCoreVMacGprGprGpr <string intr, string asm>
: Pat<(!cast<Intrinsic>("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, GPR:$rd),
(!cast<RVInst>("CV_" # asm) GPR:$rd, GPR:$rs1, GPR:$rs2)>;
class PatCoreVMacGprGprGprUimm5 <string intr, string asm>
: Pat<(!cast<Intrinsic>("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, GPR:$rd, cv_tuimm5:$imm5),
(!cast<RVInst>("CV_" # asm) GPR:$rd, GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5)>;
class PatCoreVMacGprGprUimm5 <string intr, string asm>
: Pat<(!cast<Intrinsic>("int_riscv_cv_mac_" # intr) GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5),
(!cast<RVInst>("CV_" # asm) GPR:$rs1, GPR:$rs2, cv_tuimm5:$imm5)>;
let Predicates = [HasVendorXCVmac] in {
def : PatCoreVMacGprGprGpr<"mac", "MAC">;
def : PatCoreVMacGprGprGpr<"msu", "MSU">;
def : PatCoreVMacGprGprUimm5<"muluN", "MULUN">;
def : PatCoreVMacGprGprUimm5<"mulhhuN", "MULHHUN">;
def : PatCoreVMacGprGprUimm5<"mulsN", "MULSN">;
def : PatCoreVMacGprGprUimm5<"mulhhsN", "MULHHSN">;
def : PatCoreVMacGprGprUimm5<"muluRN", "MULURN">;
def : PatCoreVMacGprGprUimm5<"mulhhuRN", "MULHHURN">;
def : PatCoreVMacGprGprUimm5<"mulsRN", "MULSRN">;
def : PatCoreVMacGprGprUimm5<"mulhhsRN", "MULHHSRN">;
def : PatCoreVMacGprGprGprUimm5<"macuN", "MACUN">;
def : PatCoreVMacGprGprGprUimm5<"machhuN", "MACHHUN">;
def : PatCoreVMacGprGprGprUimm5<"macsN", "MACSN">;
def : PatCoreVMacGprGprGprUimm5<"machhsN", "MACHHSN">;
def : PatCoreVMacGprGprGprUimm5<"macuRN", "MACURN">;
def : PatCoreVMacGprGprGprUimm5<"machhuRN", "MACHHURN">;
def : PatCoreVMacGprGprGprUimm5<"macsRN", "MACSRN">;
def : PatCoreVMacGprGprGprUimm5<"machhsRN", "MACHHSRN">;
}