//===-- RISCVInstrInfoXsf.td - SiFive custom 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 SiFive. // //===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===// // XSFVCP extension instructions. //===----------------------------------------------------------------------===// def VCIXVS2 : RISCVVConstraint; def VCIXVS2VS1 : RISCVVConstraint; class VCIXType val> { bits<4> Val = val; } def VCIX_X : VCIXType<0b0000>; def VCIX_XV : VCIXType<0b0010>; def VCIX_XVV : VCIXType<0b1010>; def VCIX_XVW : VCIXType<0b1111>; // The payload and tsimm5 operands are all marked as ImmArg in the IR // intrinsic and will be target constant, so use TImmLeaf rather than ImmLeaf. class PayloadOp : RISCVOp, TImmLeaf(Imm);"> { let ParserMatchClass = UImmAsmOperand; let DecoderMethod = "decodeUImmOperand<"# bitsNum # ">"; let OperandType = "OPERAND_UIMM" # bitsNum; } def payload1 : PayloadOp<1>; def payload2 : PayloadOp<2>; def payload5 : PayloadOp<5>; def tsimm5 : Operand, TImmLeaf(Imm);}]> { let ParserMatchClass = SImmAsmOperand<5>; let EncoderMethod = "getImmOpValue"; let DecoderMethod = "decodeSImmOperand<5>"; let MCOperandPredicate = [{ int64_t Imm; if (MCOp.evaluateAsConstantImm(Imm)) return isInt<5>(Imm); return MCOp.isBareSymbolRef(); }]; } class SwapVCIXIns { dag Ins = !con(funct6, !if(swap, rs2, rd), !if(swap, rd, rs2), rs1); } class RVInstVCCustom2 funct6_hi4, bits<3> funct3, dag outs, dag ins, string opcodestr, string argstr> : RVInst { bits<5> rs2; bits<5> rs1; bits<5> rd; bits<2> funct6_lo2; bit vm; let Inst{31-28} = funct6_hi4; let Inst{27-26} = funct6_lo2; let Inst{25} = vm; let Inst{24-20} = rs2; let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-7} = rd; let Inst{6-0} = OPC_CUSTOM_2.Value; let Uses = [VTYPE, VL]; let RVVConstraint = NoConstraint; } class RVInstVCFCustom2 funct6_hi4, bits<3> funct3, dag outs, dag ins, string opcodestr, string argstr> : RVInst { bits<5> rs2; bits<5> rs1; bits<5> rd; bit funct6_lo1; bit vm; let Inst{31-28} = funct6_hi4; let Inst{27} = 1; let Inst{26} = funct6_lo1; let Inst{25} = vm; let Inst{24-20} = rs2; let Inst{19-15} = rs1; let Inst{14-12} = funct3; let Inst{11-7} = rd; let Inst{6-0} = OPC_CUSTOM_2.Value; let Uses = [VTYPE, VL]; let RVVConstraint = NoConstraint; } class VCIXInfo { string OpcodeStr = !if(HaveOutputDst, "sf.vc.v." # suffix, "sf.vc." # suffix); bits<4> Funct6_hi4 = type.Val; bits<3> Funct3 = !cond(!eq(TyRs1, VR): 0b000, !eq(TyRs1, GPR): 0b100, !eq(TyRs1, FPR32): 0b101, !eq(TyRs1, simm5): 0b011); dag Outs = !if(!not(HaveOutputDst), (outs), !if(!or(!eq(type, VCIX_XVV), !eq(type, VCIX_XVW)), (outs TyRd:$rd_wb), (outs TyRd:$rd))); dag Ins = SwapVCIXIns.Ins; string Prototype = !if(!eq(type, VCIX_X), "$funct6_lo2, $rs2, $rd, $rs1", !if(!ne(TyRs1, FPR32), "$funct6_lo2, $rd, $rs2, $rs1", "$funct6_lo1, $rd, $rs2, $rs1")); string Constraints = !if(!not(HaveOutputDst), "", !if(!or(!eq(type, VCIX_XVV), !eq(type, VCIX_XVW)), "$rd = $rd_wb", "")); RISCVVConstraint RVVConstraint = !if(!or(!not(HaveOutputDst), !ne(type, VCIX_XVW)), NoConstraint, !if(!eq(TyRs1, VR), VCIXVS2VS1, VCIXVS2)); } class CustomSiFiveVCIX : RVInstVCCustom2 { let Constraints = info.Constraints; let RVVConstraint = info.RVVConstraint; } class CustomSiFiveVCIF : RVInstVCFCustom2 { let Constraints = info.Constraints; let RVVConstraint = info.RVVConstraint; } multiclass CustomSiFiveVCIXorVCIF { defvar info = VCIXInfo; if !eq(TyRs1, FPR32) then { def NAME : CustomSiFiveVCIF; } else { def NAME : CustomSiFiveVCIX; } } multiclass CustomSiFiveVCIX { let vm = 1 in defm VC_ # NAME : CustomSiFiveVCIXorVCIF; let vm = 0 in defm VC_V_ # NAME : CustomSiFiveVCIXorVCIF; } let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { class CustomSiFiveVMACC funct6, RISCVVFormat opv, string opcodestr> : RVInstVCCustom2 { let vm = 1; let funct6_lo2 = funct6{1-0}; } } class CustomSiFiveVFNRCLIP funct6, RISCVVFormat opv, string opcodestr> : VALUVF { let Inst{6-0} = OPC_CUSTOM_2.Value; } let Predicates = [HasVendorXSfvcp], mayLoad = 0, mayStore = 0, hasSideEffects = 1, hasNoSchedulingInfo = 1, DecoderNamespace = "XSfvcp" in { defm X : CustomSiFiveVCIX<"x", VCIX_X, uimm5, uimm5, GPR>, Sched<[]>; defm I : CustomSiFiveVCIX<"i", VCIX_X, uimm5, uimm5, simm5>, Sched<[]>; defm XV : CustomSiFiveVCIX<"xv", VCIX_XV, uimm5, VR, GPR>, Sched<[]>; defm IV : CustomSiFiveVCIX<"iv", VCIX_XV, uimm5, VR, simm5>, Sched<[]>; defm VV : CustomSiFiveVCIX<"vv", VCIX_XV, uimm5, VR, VR>, Sched<[]>; defm FV : CustomSiFiveVCIX<"fv", VCIX_XV, uimm5, VR, FPR32>, Sched<[]>; defm XVV : CustomSiFiveVCIX<"xvv", VCIX_XVV, VR, VR, GPR>, Sched<[]>; defm IVV : CustomSiFiveVCIX<"ivv", VCIX_XVV, VR, VR, simm5>, Sched<[]>; defm VVV : CustomSiFiveVCIX<"vvv", VCIX_XVV, VR, VR, VR>, Sched<[]>; defm FVV : CustomSiFiveVCIX<"fvv", VCIX_XVV, VR, VR, FPR32>, Sched<[]>; defm XVW : CustomSiFiveVCIX<"xvw", VCIX_XVW, VR, VR, GPR>, Sched<[]>; defm IVW : CustomSiFiveVCIX<"ivw", VCIX_XVW, VR, VR, simm5>, Sched<[]>; defm VVW : CustomSiFiveVCIX<"vvw", VCIX_XVW, VR, VR, VR>, Sched<[]>; defm FVW : CustomSiFiveVCIX<"fvw", VCIX_XVW, VR, VR, FPR32>, Sched<[]>; } let Predicates = [HasVendorXSfvqmaccdod], DecoderNamespace = "XSfvqmaccdod" in { def VQMACCU_2x8x2 : CustomSiFiveVMACC<0b101100, OPMVV, "sf.vqmaccu.2x8x2">; def VQMACC_2x8x2 : CustomSiFiveVMACC<0b101101, OPMVV, "sf.vqmacc.2x8x2">; def VQMACCUS_2x8x2 : CustomSiFiveVMACC<0b101110, OPMVV, "sf.vqmaccus.2x8x2">; def VQMACCSU_2x8x2 : CustomSiFiveVMACC<0b101111, OPMVV, "sf.vqmaccsu.2x8x2">; } let Predicates = [HasVendorXSfvqmaccqoq], DecoderNamespace = "XSfvqmaccqoq" in { def VQMACCU_4x8x4 : CustomSiFiveVMACC<0b111100, OPMVV, "sf.vqmaccu.4x8x4">; def VQMACC_4x8x4 : CustomSiFiveVMACC<0b111101, OPMVV, "sf.vqmacc.4x8x4">; def VQMACCUS_4x8x4 : CustomSiFiveVMACC<0b111110, OPMVV, "sf.vqmaccus.4x8x4">; def VQMACCSU_4x8x4 : CustomSiFiveVMACC<0b111111, OPMVV, "sf.vqmaccsu.4x8x4">; } let Predicates = [HasVendorXSfvfwmaccqqq], DecoderNamespace = "XSfvfwmaccqqq" in { def VFWMACC_4x4x4 : CustomSiFiveVMACC<0b111100, OPFVV, "sf.vfwmacc.4x4x4">; } let Predicates = [HasVendorXSfvfnrclipxfqf], DecoderNamespace = "XSfvfnrclipxfqf" in { def VFNRCLIP_XU_F_QF : CustomSiFiveVFNRCLIP<0b100010, OPFVF, "sf.vfnrclip.xu.f.qf">; def VFNRCLIP_X_F_QF : CustomSiFiveVFNRCLIP<0b100011, OPFVF, "sf.vfnrclip.x.f.qf">; } class VPseudoVC_X : Pseudo<(outs), (ins OpClass:$op1, payload5:$rs2, payload5:$rd, RS1Class:$r1, AVL:$vl, ixlenimm:$sew), []>, RISCVVPseudo { let mayLoad = 0; let mayStore = 0; let HasVLOp = 1; let HasSEWOp = 1; let hasSideEffects = 0; let BaseInstr = !cast(PseudoToVInst.VInst); } class VPseudoVC_XV : Pseudo<(outs), (ins OpClass:$op1, payload5:$rd, RS2Class:$rs2, RS1Class:$r1, AVL:$vl, ixlenimm:$sew), []>, RISCVVPseudo { let mayLoad = 0; let mayStore = 0; let HasVLOp = 1; let HasSEWOp = 1; let hasSideEffects = 0; let BaseInstr = !cast(PseudoToVInst.VInst); } class VPseudoVC_XVV : Pseudo<(outs), (ins OpClass:$op1, RDClass:$rd, RS2Class:$rs2, RS1Class:$r1, AVL:$vl, ixlenimm:$sew), []>, RISCVVPseudo { let mayLoad = 0; let mayStore = 0; let HasVLOp = 1; let HasSEWOp = 1; let hasSideEffects = 0; let BaseInstr = !cast(PseudoToVInst.VInst); } class VPseudoVC_V_X : Pseudo<(outs RDClass:$rd), (ins OpClass:$op1, payload5:$rs2, RS1Class:$r1, AVL:$vl, ixlenimm:$sew), []>, RISCVVPseudo { let mayLoad = 0; let mayStore = 0; let HasVLOp = 1; let HasSEWOp = 1; let hasSideEffects = 0; let BaseInstr = !cast(PseudoToVInst.VInst); } class VPseudoVC_V_XV : Pseudo<(outs RDClass:$rd), (ins OpClass:$op1, RS2Class:$rs2, RS1Class:$r1, AVL:$vl, ixlenimm:$sew), []>, RISCVVPseudo { let mayLoad = 0; let mayStore = 0; let HasVLOp = 1; let HasSEWOp = 1; let hasSideEffects = 0; let BaseInstr = !cast(PseudoToVInst.VInst); } class VPseudoVC_V_XVV : Pseudo<(outs RDClass:$rd), (ins OpClass:$op1, RDClass:$rs3, RS2Class:$rs2, RS1Class:$r1, AVL:$vl, ixlenimm:$sew), []>, RISCVVPseudo { let mayLoad = 0; let mayStore = 0; let HasVLOp = 1; let HasSEWOp = 1; let hasSideEffects = 0; let BaseInstr = !cast(PseudoToVInst.VInst); } multiclass VPseudoVC_X { let VLMul = m.value in { let Defs = [VCIX_STATE], Uses = [VCIX_STATE] in { def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_X, Sched<[!cast("WriteVC_" # NAME # "_" # m.MX)]>; def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_X, Sched<[!cast("WriteVC_V_" # NAME # "_" # m.MX)]>; } def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_X, Sched<[!cast("WriteVC_V_" # NAME # "_" # m.MX)]>; } } multiclass VPseudoVC_XV { let VLMul = m.value in { let Defs = [VCIX_STATE], Uses = [VCIX_STATE] in { def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_XV, Sched<[!cast("WriteVC_" # NAME # "_" # m.MX)]>; def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_XV, Sched<[!cast("WriteVC_V_" # NAME # "_" # m.MX)]>; } def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_XV, Sched<[!cast("WriteVC_V_" # NAME # "_" # m.MX)]>; } } multiclass VPseudoVC_XVV { let VLMul = m.value in { let Defs = [VCIX_STATE], Uses = [VCIX_STATE] in { def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_XVV, Sched<[!cast("WriteVC_" # NAME # "_" # m.MX)]>; def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_XVV, Sched<[!cast("WriteVC_V_" # NAME # "_" # m.MX)]>; } def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_XVV, Sched<[!cast("WriteVC_V_" # NAME # "_" # m.MX)]>; } } multiclass VPseudoVC_XVW { let VLMul = m.value in { let Defs = [VCIX_STATE], Uses = [VCIX_STATE] in def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_XVV, Sched<[!cast("WriteVC_" # NAME # "_" # m.MX)]>; let Constraints = "@earlyclobber $rd, $rd = $rs3" in { let Defs = [VCIX_STATE], Uses = [VCIX_STATE] in def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_XVV, Sched<[!cast("WriteVC_V_" # NAME # "_" # m.MX)]>; def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_XVV, Sched<[!cast("WriteVC_V_" # NAME # "_" # m.MX)]>; } } } multiclass VPseudoSiFiveVMACC { def "Pseudo" # NAME # "_" # mx : VPseudoTernaryNoMaskWithPolicy; } multiclass VPseudoSiFiveVQMACCDOD { foreach m = MxListVF8 in let VLMul = m.value in defm NAME : VPseudoSiFiveVMACC; } multiclass VPseudoSiFiveVQMACCQOQ { foreach m = [V_MF2, V_M1, V_M2, V_M4] in let VLMul = m.value in defm NAME : VPseudoSiFiveVMACC; } multiclass VPseudoSiFiveVFWMACC { foreach m = MxListVF2 in let VLMul = m.value in defm NAME : VPseudoSiFiveVMACC; } multiclass VPseudoSiFiveVFNRCLIP { foreach i = 0-4 in let hasSideEffects = 0 in defm "Pseudo" # NAME : VPseudoBinaryRoundingMode; } let Predicates = [HasVendorXSfvcp] in { foreach m = MxList in { defm X : VPseudoVC_X; defm I : VPseudoVC_X; defm XV : VPseudoVC_XV; defm IV : VPseudoVC_XV; defm VV : VPseudoVC_XV; defm XVV : VPseudoVC_XVV; defm IVV : VPseudoVC_XVV; defm VVV : VPseudoVC_XVV; } foreach f = FPList in { foreach m = f.MxList in { defm f.FX # "V" : VPseudoVC_XV; defm f.FX # "VV" : VPseudoVC_XVV; } } foreach m = MxListW in { defm XVW : VPseudoVC_XVW; defm IVW : VPseudoVC_XVW; defm VVW : VPseudoVC_XVW; } foreach f = FPListW in { foreach m = f.MxList in defm f.FX # "VW" : VPseudoVC_XVW; } } let Predicates = [HasVendorXSfvqmaccdod] in { defm VQMACCU_2x8x2 : VPseudoSiFiveVQMACCDOD; defm VQMACC_2x8x2 : VPseudoSiFiveVQMACCDOD; defm VQMACCUS_2x8x2 : VPseudoSiFiveVQMACCDOD; defm VQMACCSU_2x8x2 : VPseudoSiFiveVQMACCDOD; } let Predicates = [HasVendorXSfvqmaccqoq] in { defm VQMACCU_4x8x4 : VPseudoSiFiveVQMACCQOQ; defm VQMACC_4x8x4 : VPseudoSiFiveVQMACCQOQ; defm VQMACCUS_4x8x4 : VPseudoSiFiveVQMACCQOQ; defm VQMACCSU_4x8x4 : VPseudoSiFiveVQMACCQOQ; } let Predicates = [HasVendorXSfvfwmaccqqq] in { defm VFWMACC_4x4x4 : VPseudoSiFiveVFWMACC; } let Predicates = [HasVendorXSfvfnrclipxfqf] in { defm VFNRCLIP_XU_F_QF : VPseudoSiFiveVFNRCLIP; defm VFNRCLIP_X_F_QF : VPseudoSiFiveVFNRCLIP; } // SDNode def SDT_SF_VC_V_X : SDTypeProfile<1, 4, [SDTCisVec<0>, SDTCisVT<1, XLenVT>, SDTCisSameAs<1, 2>, SDTCisSameAs<1, 3>, SDTCisSameAs<1, 4>]>; def SDT_SF_VC_XV : SDTypeProfile<0, 5, [SDTCisSameAs<0, 1>, SDTCisVec<2>, SDTCisSameAs<0, 4>, SDTCisVT<0, XLenVT>]>; def SDT_SF_VC_V_XV : SDTypeProfile<1, 4, [SDTCisVec<0>, SDTCisVT<1, XLenVT>, SDTCisSameAs<0, 2>, SDTCisSameAs<1, 4>]>; def SDT_SF_VC_XVV : SDTypeProfile<0, 5, [SDTCisVT<0, XLenVT>, SDTCisVec<1>, SDTCisSameAs<1, 2>, SDTCisSameAs<0, 4>]>; def SDT_SF_VC_V_XVV : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisVT<1, XLenVT>, SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3>, SDTCisSameAs<1, 5>]>; def SDT_SF_VC_XVW : SDTypeProfile<0, 5, [SDTCisVT<0, XLenVT>, SDTCisVec<1>, SDTCisVec<2>, SDTCisSameAs<0, 4>]>; def SDT_SF_VC_V_XVW : SDTypeProfile<1, 5, [SDTCisVec<0>, SDTCisVT<1, XLenVT>, SDTCisSameAs<0, 2>, SDTCisVec<3>, SDTCisSameAs<1, 5>]>; def sf_vc_v_x_se : SDNode<"RISCVISD::SF_VC_V_X_SE", SDT_SF_VC_V_X, [SDNPHasChain]>; def sf_vc_v_i_se : SDNode<"RISCVISD::SF_VC_V_I_SE", SDT_SF_VC_V_X, [SDNPHasChain]>; def sf_vc_vv_se : SDNode<"RISCVISD::SF_VC_VV_SE", SDT_SF_VC_XV, [SDNPHasChain]>; def sf_vc_xv_se : SDNode<"RISCVISD::SF_VC_XV_SE", SDT_SF_VC_XV, [SDNPHasChain]>; def sf_vc_iv_se : SDNode<"RISCVISD::SF_VC_IV_SE", SDT_SF_VC_XV, [SDNPHasChain]>; def sf_vc_fv_se : SDNode<"RISCVISD::SF_VC_FV_SE", SDT_SF_VC_XV, [SDNPHasChain]>; def sf_vc_v_vv_se : SDNode<"RISCVISD::SF_VC_V_VV_SE", SDT_SF_VC_V_XV, [SDNPHasChain]>; def sf_vc_v_xv_se : SDNode<"RISCVISD::SF_VC_V_XV_SE", SDT_SF_VC_V_XV, [SDNPHasChain]>; def sf_vc_v_iv_se : SDNode<"RISCVISD::SF_VC_V_IV_SE", SDT_SF_VC_V_XV, [SDNPHasChain]>; def sf_vc_v_fv_se : SDNode<"RISCVISD::SF_VC_V_FV_SE", SDT_SF_VC_V_XV, [SDNPHasChain]>; def sf_vc_vvv_se : SDNode<"RISCVISD::SF_VC_VVV_SE", SDT_SF_VC_XVV, [SDNPHasChain]>; def sf_vc_xvv_se : SDNode<"RISCVISD::SF_VC_XVV_SE", SDT_SF_VC_XVV, [SDNPHasChain]>; def sf_vc_ivv_se : SDNode<"RISCVISD::SF_VC_IVV_SE", SDT_SF_VC_XVV, [SDNPHasChain]>; def sf_vc_fvv_se : SDNode<"RISCVISD::SF_VC_FVV_SE", SDT_SF_VC_XVV, [SDNPHasChain]>; def sf_vc_v_vvv_se : SDNode<"RISCVISD::SF_VC_V_VVV_SE", SDT_SF_VC_V_XVV, [SDNPHasChain]>; def sf_vc_v_xvv_se : SDNode<"RISCVISD::SF_VC_V_XVV_SE", SDT_SF_VC_V_XVV, [SDNPHasChain]>; def sf_vc_v_ivv_se : SDNode<"RISCVISD::SF_VC_V_IVV_SE", SDT_SF_VC_V_XVV, [SDNPHasChain]>; def sf_vc_v_fvv_se : SDNode<"RISCVISD::SF_VC_V_FVV_SE", SDT_SF_VC_V_XVV, [SDNPHasChain]>; def sf_vc_vvw_se : SDNode<"RISCVISD::SF_VC_VVW_SE", SDT_SF_VC_XVW, [SDNPHasChain]>; def sf_vc_xvw_se : SDNode<"RISCVISD::SF_VC_XVW_SE", SDT_SF_VC_XVW, [SDNPHasChain]>; def sf_vc_ivw_se : SDNode<"RISCVISD::SF_VC_IVW_SE", SDT_SF_VC_XVW, [SDNPHasChain]>; def sf_vc_fvw_se : SDNode<"RISCVISD::SF_VC_FVW_SE", SDT_SF_VC_XVW, [SDNPHasChain]>; def sf_vc_v_vvw_se : SDNode<"RISCVISD::SF_VC_V_VVW_SE", SDT_SF_VC_V_XVW, [SDNPHasChain]>; def sf_vc_v_xvw_se : SDNode<"RISCVISD::SF_VC_V_XVW_SE", SDT_SF_VC_V_XVW, [SDNPHasChain]>; def sf_vc_v_ivw_se : SDNode<"RISCVISD::SF_VC_V_IVW_SE", SDT_SF_VC_V_XVW, [SDNPHasChain]>; def sf_vc_v_fvw_se : SDNode<"RISCVISD::SF_VC_V_FVW_SE", SDT_SF_VC_V_XVW, [SDNPHasChain]>; class VPatVC_OP4_ISD : Pat<(op (XLenVT op1_kind:$op1), (op2_type op2_kind:$op2), (op3_type op3_kind:$op3), (op4_type op4_kind:$op4), VLOpFrag), (!cast(inst) (XLenVT op1_kind:$op1), (op2_type op2_kind:$op2), (op3_type op3_kind:$op3), (op4_type op4_kind:$op4), GPR:$vl, sew)>; class VPatVC_V_OP4_ISD : Pat<(result_type (op (XLenVT op1_kind:$op1), (op2_type op2_kind:$op2), (op3_type op3_kind:$op3), (op4_type op4_kind:$op4), VLOpFrag)), (!cast(inst) (XLenVT op1_kind:$op1), (op2_type op2_kind:$op2), (op3_type op3_kind:$op3), (op4_type op4_kind:$op4), GPR:$vl, sew)>; class VPatVC_V_OP3_ISD : Pat<(result_type (op (XLenVT op1_kind:$op1), (op2_type op2_kind:$op2), (op3_type op3_kind:$op3), VLOpFrag)), (!cast(inst) (XLenVT op1_kind:$op1), (op2_type op2_kind:$op2), (op3_type op3_kind:$op3), GPR:$vl, sew)>; class VPatVC_OP4 : Pat<(!cast(intrinsic_name) (XLenVT op1_kind:$op1), (op2_type op2_kind:$op2), (op3_type op3_kind:$op3), (op4_type op4_kind:$op4), VLOpFrag), (!cast(inst) (XLenVT op1_kind:$op1), (op2_type op2_kind:$op2), (op3_type op3_kind:$op3), (op4_type op4_kind:$op4), GPR:$vl, sew)>; class VPatVC_V_OP4 : Pat<(result_type (!cast(intrinsic_name) (XLenVT op1_kind:$op1), (op2_type op2_kind:$op2), (op3_type op3_kind:$op3), (op4_type op4_kind:$op4), VLOpFrag)), (!cast(inst) (XLenVT op1_kind:$op1), (op2_type op2_kind:$op2), (op3_type op3_kind:$op3), (op4_type op4_kind:$op4), GPR:$vl, sew)>; class VPatVC_V_OP3 : Pat<(result_type (!cast(intrinsic_name) (XLenVT op1_kind:$op1), (op2_type op2_kind:$op2), (op3_type op3_kind:$op3), VLOpFrag)), (!cast(inst) (XLenVT op1_kind:$op1), (op2_type op2_kind:$op2), (op3_type op3_kind:$op3), GPR:$vl, sew)>; multiclass VPatVC_X { def : VPatVC_V_OP3_ISD("sf_vc_v_" # intrinsic_suffix # "_se"), "PseudoVC_V_" # instruction_suffix # "_SE_" # vti.LMul.MX, vti.Vector, XLenVT, type, vti.Log2SEW, payload5, kind>; def : VPatVC_V_OP3<"int_riscv_sf_vc_v_" # intrinsic_suffix, "PseudoVC_V_" # instruction_suffix # "_" # vti.LMul.MX, vti.Vector, XLenVT, type, vti.Log2SEW, payload5, kind>; } multiclass VPatVC_XV { def : VPatVC_OP4_ISD("sf_vc_" # intrinsic_suffix # "_se"), "PseudoVC_" # instruction_suffix # "_SE_" # vti.LMul.MX, XLenVT, vti.Vector, type, vti.Log2SEW, payload5, vti.RegClass, kind, op1_kind>; def : VPatVC_V_OP3_ISD("sf_vc_v_" # intrinsic_suffix # "_se"), "PseudoVC_V_" # instruction_suffix # "_SE_" # vti.LMul.MX, vti.Vector, vti.Vector, type, vti.Log2SEW, vti.RegClass, kind, op1_kind>; def : VPatVC_V_OP3<"int_riscv_sf_vc_v_" # intrinsic_suffix, "PseudoVC_V_" # instruction_suffix # "_" # vti.LMul.MX, vti.Vector, vti.Vector, type, vti.Log2SEW, vti.RegClass, kind, op1_kind>; } multiclass VPatVC_XVV { def : VPatVC_OP4_ISD("sf_vc_" # intrinsic_suffix # "_se"), "PseudoVC_" # instruction_suffix # "_SE_" # vti.LMul.MX, wti.Vector, vti.Vector, type, vti.Log2SEW, wti.RegClass, vti.RegClass, kind, op1_kind>; def : VPatVC_V_OP4_ISD("sf_vc_v_" # intrinsic_suffix # "_se"), "PseudoVC_V_" # instruction_suffix # "_SE_" # vti.LMul.MX, wti.Vector, wti.Vector, vti.Vector, type, vti.Log2SEW, wti.RegClass, vti.RegClass, kind, op1_kind>; def : VPatVC_V_OP4<"int_riscv_sf_vc_v_" # intrinsic_suffix, "PseudoVC_V_" # instruction_suffix # "_" # vti.LMul.MX, wti.Vector, wti.Vector, vti.Vector, type, vti.Log2SEW, wti.RegClass, vti.RegClass, kind, op1_kind>; } class GetFTypeInfo { ValueType Scalar = !cond(!eq(Sew, 16) : f16, !eq(Sew, 32) : f32, !eq(Sew, 64) : f64); RegisterClass ScalarRegClass = !cond(!eq(Sew, 16) : FPR16, !eq(Sew, 32) : FPR32, !eq(Sew, 64) : FPR64); string ScalarSuffix = !cond(!eq(Scalar, f16) : "FPR16", !eq(Scalar, f32) : "FPR32", !eq(Scalar, f64) : "FPR64"); } multiclass VPatVMACC info_pairs, ValueType vec_m1> { foreach pair = info_pairs in { defvar VdInfo = pair.Wti; defvar Vs2Info = pair.Vti; let Predicates = [HasVInstructions] in def : VPatTernaryNoMaskWithPolicy<"int_riscv_sf_" # intrinsic, "Pseudo" # instruction, kind, VdInfo.Vector, vec_m1, Vs2Info.Vector, Vs2Info.Log2SEW, Vs2Info.LMul, VdInfo.RegClass, VR, Vs2Info.RegClass>; } } defset list VQMACCDODInfoPairs = { def : VTypeInfoToWide; def : VTypeInfoToWide; def : VTypeInfoToWide; def : VTypeInfoToWide; } defset list VQMACCQOQInfoPairs = { def : VTypeInfoToWide; def : VTypeInfoToWide; def : VTypeInfoToWide; def : VTypeInfoToWide; } multiclass VPatVQMACCDOD : VPatVMACC; multiclass VPatVQMACCQOQ : VPatVMACC; multiclass VPatVFWMACC : VPatVMACC; defset list VFNRCLIPInfoPairs = { def : VTypeInfoToWide; def : VTypeInfoToWide; def : VTypeInfoToWide; def : VTypeInfoToWide; def : VTypeInfoToWide; } multiclass VPatVFNRCLIP { foreach pair = VFNRCLIPInfoPairs in { defvar Vti = pair.Vti; defvar Wti = pair.Wti; defm : VPatBinaryRoundingMode<"int_riscv_sf_" # intrinsic, "Pseudo" # instruction # "_" # Vti.LMul.MX, Vti.Vector, Wti.Vector, Wti.Scalar, Vti.Mask, Vti.Log2SEW, Vti.RegClass, Wti.RegClass, Wti.ScalarRegClass>; } } let Predicates = [HasVendorXSfvcp] in { foreach vti = AllIntegerVectors in { defm : VPatVC_X<"x", "X", vti, XLenVT, GPR>; defm : VPatVC_X<"i", "I", vti, XLenVT, tsimm5>; defm : VPatVC_XV<"xv", "XV", vti, XLenVT, GPR>; defm : VPatVC_XV<"iv", "IV", vti, XLenVT, tsimm5>; defm : VPatVC_XV<"vv", "VV", vti, vti.Vector, vti.RegClass>; defm : VPatVC_XVV<"xvv", "XVV", vti, vti, XLenVT, GPR>; defm : VPatVC_XVV<"ivv", "IVV", vti, vti, XLenVT, tsimm5>; defm : VPatVC_XVV<"vvv", "VVV", vti, vti, vti.Vector, vti.RegClass>; if !ne(vti.SEW, 8) then { defvar finfo = GetFTypeInfo; defm : VPatVC_XV<"fv", finfo.ScalarSuffix # "V", vti, finfo.Scalar, finfo.ScalarRegClass, payload1>; defm : VPatVC_XVV<"fvv", finfo.ScalarSuffix # "VV", vti, vti, finfo.Scalar, finfo.ScalarRegClass, payload1>; } } foreach VtiToWti = AllWidenableIntVectors in { defvar vti = VtiToWti.Vti; defvar wti = VtiToWti.Wti; defvar iinfo = GetIntVTypeInfo.Vti; defm : VPatVC_XVV<"xvw", "XVW", wti, vti, iinfo.Scalar, iinfo.ScalarRegClass>; defm : VPatVC_XVV<"ivw", "IVW", wti, vti, XLenVT, tsimm5>; defm : VPatVC_XVV<"vvw", "VVW", wti, vti, vti.Vector, vti.RegClass>; if !ne(vti.SEW, 8) then { defvar finfo = GetFTypeInfo; defm : VPatVC_XVV<"fvw", finfo.ScalarSuffix # "VW", wti, vti, finfo.Scalar, finfo.ScalarRegClass, payload1>; } } } let Predicates = [HasVendorXSfvqmaccdod] in { defm : VPatVQMACCDOD<"vqmaccu_2x8x2", "VQMACCU", "2x8x2">; defm : VPatVQMACCDOD<"vqmacc_2x8x2", "VQMACC", "2x8x2">; defm : VPatVQMACCDOD<"vqmaccus_2x8x2", "VQMACCUS", "2x8x2">; defm : VPatVQMACCDOD<"vqmaccsu_2x8x2", "VQMACCSU", "2x8x2">; } let Predicates = [HasVendorXSfvqmaccqoq] in { defm : VPatVQMACCQOQ<"vqmaccu_4x8x4", "VQMACCU", "4x8x4">; defm : VPatVQMACCQOQ<"vqmacc_4x8x4", "VQMACC", "4x8x4">; defm : VPatVQMACCQOQ<"vqmaccus_4x8x4", "VQMACCUS", "4x8x4">; defm : VPatVQMACCQOQ<"vqmaccsu_4x8x4", "VQMACCSU", "4x8x4">; } let Predicates = [HasVendorXSfvfwmaccqqq] in { defm : VPatVFWMACC<"vfwmacc_4x4x4", "VFWMACC", "4x4x4">; } let Predicates = [HasVendorXSfvfnrclipxfqf] in { defm : VPatVFNRCLIP<"vfnrclip_xu_f_qf", "VFNRCLIP_XU_F_QF">; defm : VPatVFNRCLIP<"vfnrclip_x_f_qf", "VFNRCLIP_X_F_QF">; } let Predicates = [HasVendorXSiFivecdiscarddlone] in { let hasNoSchedulingInfo = 1, hasSideEffects = 1, mayLoad = 0, mayStore = 0, DecoderNamespace = "XSiFivecdiscarddlone" in def SF_CDISCARD_D_L1 : RVInstIUnary<0b111111000010, 0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1), "sf.cdiscard.d.l1", "$rs1">, Sched<[]> { let rd = 0; } def : InstAlias<"sf.cdiscard.d.l1", (SF_CDISCARD_D_L1 X0)>; } // Predicates = [HasVendorXSifivecdiscarddlone] let Predicates = [HasVendorXSiFivecflushdlone] in { let hasNoSchedulingInfo = 1, hasSideEffects = 1, mayLoad = 0, mayStore = 0, DecoderNamespace = "XSiFivecflushdlone" in def SF_CFLUSH_D_L1 : RVInstIUnary<0b111111000000, 0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1), "sf.cflush.d.l1", "$rs1">, Sched<[]> { let rd = 0; } def : InstAlias<"sf.cflush.d.l1", (SF_CFLUSH_D_L1 X0)>; } // Predicates = [HasVendorXSifivecflushdlone] let Predicates = [HasVendorXSfcease] in { let hasNoSchedulingInfo = 1, hasSideEffects = 1, mayLoad = 0, mayStore = 0, DecoderNamespace = "XSfcease" in def SF_CEASE : RVInstIUnary<0b001100000101, 0b000, OPC_SYSTEM, (outs), (ins), "sf.cease", "">, Sched<[]> { let rs1 = 0b00000; let rd = 0b00000; } }