1//===-- RISCVInstrInfoXsf.td - SiFive custom instructions --*- tablegen -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file describes the vendor extensions defined by SiFive. 10// 11//===----------------------------------------------------------------------===// 12 13//===----------------------------------------------------------------------===// 14// XSFVCP extension instructions. 15//===----------------------------------------------------------------------===// 16 17def VCIXVS2 : RISCVVConstraint<VS2Constraint.Value>; 18def VCIXVS2VS1 : RISCVVConstraint<!or(VS2Constraint.Value, 19 VS1Constraint.Value)>; 20 21class VCIXType<bits<4> val> { 22 bits<4> Val = val; 23} 24 25def VCIX_X : VCIXType<0b0000>; 26def VCIX_XV : VCIXType<0b0010>; 27def VCIX_XVV : VCIXType<0b1010>; 28def VCIX_XVW : VCIXType<0b1111>; 29 30// The payload and tsimm5 operands are all marked as ImmArg in the IR 31// intrinsic and will be target constant, so use TImmLeaf rather than ImmLeaf. 32class PayloadOp<int bitsNum> : RISCVOp, TImmLeaf<XLenVT, "return isUInt<" # bitsNum # ">(Imm);"> { 33 let ParserMatchClass = UImmAsmOperand<bitsNum>; 34 let DecoderMethod = "decodeUImmOperand<"# bitsNum # ">"; 35 let OperandType = "OPERAND_UIMM" # bitsNum; 36} 37 38def payload1 : PayloadOp<1>; 39def payload2 : PayloadOp<2>; 40def payload5 : PayloadOp<5>; 41 42def tsimm5 : Operand<XLenVT>, TImmLeaf<XLenVT, [{return isInt<5>(Imm);}]> { 43 let ParserMatchClass = SImmAsmOperand<5>; 44 let EncoderMethod = "getImmOpValue"; 45 let DecoderMethod = "decodeSImmOperand<5>"; 46 let MCOperandPredicate = [{ 47 int64_t Imm; 48 if (MCOp.evaluateAsConstantImm(Imm)) 49 return isInt<5>(Imm); 50 return MCOp.isBareSymbolRef(); 51 }]; 52} 53 54class SwapVCIXIns<dag funct6, dag rd, dag rs2, dag rs1, bit swap> { 55 dag Ins = !con(funct6, !if(swap, rs2, rd), !if(swap, rd, rs2), rs1); 56} 57 58class RVInstVCCustom2<bits<4> funct6_hi4, bits<3> funct3, dag outs, dag ins, 59 string opcodestr, string argstr> 60 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 61 bits<5> rs2; 62 bits<5> rs1; 63 bits<5> rd; 64 bits<2> funct6_lo2; 65 bit vm; 66 67 let Inst{31-28} = funct6_hi4; 68 let Inst{27-26} = funct6_lo2; 69 let Inst{25} = vm; 70 let Inst{24-20} = rs2; 71 let Inst{19-15} = rs1; 72 let Inst{14-12} = funct3; 73 let Inst{11-7} = rd; 74 let Inst{6-0} = OPC_CUSTOM_2.Value; 75 76 let Uses = [VTYPE, VL]; 77 let RVVConstraint = NoConstraint; 78} 79 80class RVInstVCFCustom2<bits<4> funct6_hi4, bits<3> funct3, dag outs, dag ins, 81 string opcodestr, string argstr> 82 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 83 bits<5> rs2; 84 bits<5> rs1; 85 bits<5> rd; 86 bit funct6_lo1; 87 bit vm; 88 89 let Inst{31-28} = funct6_hi4; 90 let Inst{27} = 1; 91 let Inst{26} = funct6_lo1; 92 let Inst{25} = vm; 93 let Inst{24-20} = rs2; 94 let Inst{19-15} = rs1; 95 let Inst{14-12} = funct3; 96 let Inst{11-7} = rd; 97 let Inst{6-0} = OPC_CUSTOM_2.Value; 98 99 let Uses = [VTYPE, VL]; 100 let RVVConstraint = NoConstraint; 101} 102 103class VCIXInfo<string suffix, VCIXType type, DAGOperand TyRd, 104 DAGOperand TyRs2, DAGOperand TyRs1, bit HaveOutputDst> { 105 string OpcodeStr = !if(HaveOutputDst, "sf.vc.v." # suffix, 106 "sf.vc." # suffix); 107 bits<4> Funct6_hi4 = type.Val; 108 bits<3> Funct3 = !cond(!eq(TyRs1, VR): 0b000, 109 !eq(TyRs1, GPR): 0b100, 110 !eq(TyRs1, FPR32): 0b101, 111 !eq(TyRs1, simm5): 0b011); 112 dag Outs = !if(!not(HaveOutputDst), (outs), 113 !if(!or(!eq(type, VCIX_XVV), !eq(type, VCIX_XVW)), 114 (outs TyRd:$rd_wb), (outs TyRd:$rd))); 115 dag Ins = SwapVCIXIns<!if(!ne(TyRs1, FPR32), (ins uimm2:$funct6_lo2), 116 (ins uimm1:$funct6_lo1)), 117 !if(!and(HaveOutputDst, !or(!eq(type, VCIX_X), 118 !eq(type, VCIX_XV))), 119 (ins), (ins TyRd:$rd)), 120 (ins TyRs2:$rs2), 121 (ins TyRs1:$rs1), 122 !if(!eq(type, VCIX_X), 1, 0)>.Ins; 123 string Prototype = !if(!eq(type, VCIX_X), "$funct6_lo2, $rs2, $rd, $rs1", 124 !if(!ne(TyRs1, FPR32), "$funct6_lo2, $rd, $rs2, $rs1", 125 "$funct6_lo1, $rd, $rs2, $rs1")); 126 string Constraints = !if(!not(HaveOutputDst), "", 127 !if(!or(!eq(type, VCIX_XVV), 128 !eq(type, VCIX_XVW)), "$rd = $rd_wb", "")); 129 RISCVVConstraint RVVConstraint = !if(!or(!not(HaveOutputDst), 130 !ne(type, VCIX_XVW)), NoConstraint, 131 !if(!eq(TyRs1, VR), VCIXVS2VS1, VCIXVS2)); 132} 133 134class CustomSiFiveVCIX<VCIXInfo info> 135 : RVInstVCCustom2<info.Funct6_hi4, info.Funct3, info.Outs, 136 info.Ins, info.OpcodeStr, info.Prototype> { 137 let Constraints = info.Constraints; 138 let RVVConstraint = info.RVVConstraint; 139} 140 141class CustomSiFiveVCIF<VCIXInfo info> 142 : RVInstVCFCustom2<info.Funct6_hi4, info.Funct3, info.Outs, 143 info.Ins, info.OpcodeStr, info.Prototype> { 144 let Constraints = info.Constraints; 145 let RVVConstraint = info.RVVConstraint; 146} 147 148multiclass CustomSiFiveVCIXorVCIF<string suffix, VCIXType type, 149 DAGOperand TyRd, DAGOperand TyRs2, 150 DAGOperand TyRs1, bit HaveOutputDst> { 151 defvar info = VCIXInfo<suffix, type, TyRd, TyRs2, TyRs1, HaveOutputDst>; 152 if !eq(TyRs1, FPR32) then { 153 def NAME : CustomSiFiveVCIF<info>; 154 } else { 155 def NAME : CustomSiFiveVCIX<info>; 156 } 157} 158 159multiclass CustomSiFiveVCIX<string suffix, VCIXType type, 160 DAGOperand InTyRd, DAGOperand InTyRs2, 161 DAGOperand InTyRs1> { 162 let vm = 1 in 163 defm VC_ # NAME : CustomSiFiveVCIXorVCIF<suffix, type, InTyRd, InTyRs2, 164 InTyRs1, 0>; 165 let vm = 0 in 166 defm VC_V_ # NAME : CustomSiFiveVCIXorVCIF<suffix, type, VR, InTyRs2, 167 InTyRs1, 1>; 168} 169 170let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in { 171class CustomSiFiveVMACC<bits<6> funct6, RISCVVFormat opv, string opcodestr> 172 : RVInstVCCustom2<funct6{5-2}, opv.Value, (outs VR:$rd), (ins VR:$rs1, VR:$rs2), 173 opcodestr, "$rd, $rs1, $rs2"> { 174 let vm = 1; 175 let funct6_lo2 = funct6{1-0}; 176} 177} 178 179class CustomSiFiveVFNRCLIP<bits<6> funct6, RISCVVFormat opv, string opcodestr> 180 : VALUVF<funct6, opv, opcodestr> { 181 let Inst{6-0} = OPC_CUSTOM_2.Value; 182} 183 184let Predicates = [HasVendorXSfvcp], mayLoad = 0, mayStore = 0, 185 hasSideEffects = 1, hasNoSchedulingInfo = 1, DecoderNamespace = "XSfvcp" in { 186 defm X : CustomSiFiveVCIX<"x", VCIX_X, uimm5, uimm5, GPR>, Sched<[]>; 187 defm I : CustomSiFiveVCIX<"i", VCIX_X, uimm5, uimm5, simm5>, Sched<[]>; 188 defm XV : CustomSiFiveVCIX<"xv", VCIX_XV, uimm5, VR, GPR>, Sched<[]>; 189 defm IV : CustomSiFiveVCIX<"iv", VCIX_XV, uimm5, VR, simm5>, Sched<[]>; 190 defm VV : CustomSiFiveVCIX<"vv", VCIX_XV, uimm5, VR, VR>, Sched<[]>; 191 defm FV : CustomSiFiveVCIX<"fv", VCIX_XV, uimm5, VR, FPR32>, Sched<[]>; 192 defm XVV : CustomSiFiveVCIX<"xvv", VCIX_XVV, VR, VR, GPR>, Sched<[]>; 193 defm IVV : CustomSiFiveVCIX<"ivv", VCIX_XVV, VR, VR, simm5>, Sched<[]>; 194 defm VVV : CustomSiFiveVCIX<"vvv", VCIX_XVV, VR, VR, VR>, Sched<[]>; 195 defm FVV : CustomSiFiveVCIX<"fvv", VCIX_XVV, VR, VR, FPR32>, Sched<[]>; 196 defm XVW : CustomSiFiveVCIX<"xvw", VCIX_XVW, VR, VR, GPR>, Sched<[]>; 197 defm IVW : CustomSiFiveVCIX<"ivw", VCIX_XVW, VR, VR, simm5>, Sched<[]>; 198 defm VVW : CustomSiFiveVCIX<"vvw", VCIX_XVW, VR, VR, VR>, Sched<[]>; 199 defm FVW : CustomSiFiveVCIX<"fvw", VCIX_XVW, VR, VR, FPR32>, Sched<[]>; 200} 201 202let Predicates = [HasVendorXSfvqmaccdod], DecoderNamespace = "XSfvqmaccdod" in { 203 def VQMACCU_2x8x2 : CustomSiFiveVMACC<0b101100, OPMVV, "sf.vqmaccu.2x8x2">; 204 def VQMACC_2x8x2 : CustomSiFiveVMACC<0b101101, OPMVV, "sf.vqmacc.2x8x2">; 205 def VQMACCUS_2x8x2 : CustomSiFiveVMACC<0b101110, OPMVV, "sf.vqmaccus.2x8x2">; 206 def VQMACCSU_2x8x2 : CustomSiFiveVMACC<0b101111, OPMVV, "sf.vqmaccsu.2x8x2">; 207} 208 209let Predicates = [HasVendorXSfvqmaccqoq], DecoderNamespace = "XSfvqmaccqoq" in { 210 def VQMACCU_4x8x4 : CustomSiFiveVMACC<0b111100, OPMVV, "sf.vqmaccu.4x8x4">; 211 def VQMACC_4x8x4 : CustomSiFiveVMACC<0b111101, OPMVV, "sf.vqmacc.4x8x4">; 212 def VQMACCUS_4x8x4 : CustomSiFiveVMACC<0b111110, OPMVV, "sf.vqmaccus.4x8x4">; 213 def VQMACCSU_4x8x4 : CustomSiFiveVMACC<0b111111, OPMVV, "sf.vqmaccsu.4x8x4">; 214} 215 216let Predicates = [HasVendorXSfvfwmaccqqq], DecoderNamespace = "XSfvfwmaccqqq" in { 217 def VFWMACC_4x4x4 : CustomSiFiveVMACC<0b111100, OPFVV, "sf.vfwmacc.4x4x4">; 218} 219 220let Predicates = [HasVendorXSfvfnrclipxfqf], DecoderNamespace = "XSfvfnrclipxfqf" in { 221 def VFNRCLIP_XU_F_QF : CustomSiFiveVFNRCLIP<0b100010, OPFVF, "sf.vfnrclip.xu.f.qf">; 222 def VFNRCLIP_X_F_QF : CustomSiFiveVFNRCLIP<0b100011, OPFVF, "sf.vfnrclip.x.f.qf">; 223} 224class VPseudoVC_X<Operand OpClass, DAGOperand RS1Class, 225 bit HasSideEffect = 1> : 226 Pseudo<(outs), 227 (ins OpClass:$op1, payload5:$rs2, payload5:$rd, RS1Class:$r1, 228 AVL:$vl, ixlenimm:$sew), []>, 229 RISCVVPseudo { 230 let mayLoad = 0; 231 let mayStore = 0; 232 let HasVLOp = 1; 233 let HasSEWOp = 1; 234 let hasSideEffects = HasSideEffect; 235 let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); 236} 237 238class VPseudoVC_XV<Operand OpClass, VReg RS2Class, DAGOperand RS1Class, 239 bit HasSideEffect = 1> : 240 Pseudo<(outs), 241 (ins OpClass:$op1, payload5:$rd, RS2Class:$rs2, RS1Class:$r1, 242 AVL:$vl, ixlenimm:$sew), []>, 243 RISCVVPseudo { 244 let mayLoad = 0; 245 let mayStore = 0; 246 let HasVLOp = 1; 247 let HasSEWOp = 1; 248 let hasSideEffects = HasSideEffect; 249 let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); 250} 251 252class VPseudoVC_XVV<Operand OpClass, VReg RDClass, VReg RS2Class, 253 DAGOperand RS1Class, bit HasSideEffect = 1> : 254 Pseudo<(outs), 255 (ins OpClass:$op1, RDClass:$rd, RS2Class:$rs2, RS1Class:$r1, 256 AVL:$vl, ixlenimm:$sew), []>, 257 RISCVVPseudo { 258 let mayLoad = 0; 259 let mayStore = 0; 260 let HasVLOp = 1; 261 let HasSEWOp = 1; 262 let hasSideEffects = HasSideEffect; 263 let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); 264} 265 266class VPseudoVC_V_X<Operand OpClass, VReg RDClass, DAGOperand RS1Class, 267 bit HasSideEffect = 1> : 268 Pseudo<(outs RDClass:$rd), 269 (ins OpClass:$op1, payload5:$rs2, RS1Class:$r1, 270 AVL:$vl, ixlenimm:$sew), []>, 271 RISCVVPseudo { 272 let mayLoad = 0; 273 let mayStore = 0; 274 let HasVLOp = 1; 275 let HasSEWOp = 1; 276 let hasSideEffects = HasSideEffect; 277 let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); 278} 279 280class VPseudoVC_V_XV<Operand OpClass, VReg RDClass, VReg RS2Class, 281 DAGOperand RS1Class, bit HasSideEffect = 1> : 282 Pseudo<(outs RDClass:$rd), 283 (ins OpClass:$op1, RS2Class:$rs2, RS1Class:$r1, 284 AVL:$vl, ixlenimm:$sew), []>, 285 RISCVVPseudo { 286 let mayLoad = 0; 287 let mayStore = 0; 288 let HasVLOp = 1; 289 let HasSEWOp = 1; 290 let hasSideEffects = HasSideEffect; 291 let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); 292} 293 294class VPseudoVC_V_XVV<Operand OpClass, VReg RDClass, VReg RS2Class, 295 DAGOperand RS1Class, bit HasSideEffect = 1> : 296 Pseudo<(outs RDClass:$rd), 297 (ins OpClass:$op1, RDClass:$rs3, RS2Class:$rs2, RS1Class:$r1, 298 AVL:$vl, ixlenimm:$sew), []>, 299 RISCVVPseudo { 300 let mayLoad = 0; 301 let mayStore = 0; 302 let HasVLOp = 1; 303 let HasSEWOp = 1; 304 let hasSideEffects = HasSideEffect; 305 let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); 306} 307 308multiclass VPseudoVC_X<LMULInfo m, DAGOperand RS1Class, 309 Operand OpClass = payload2> { 310 let VLMul = m.value in { 311 def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_X<OpClass, RS1Class>; 312 def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_X<OpClass, m.vrclass, RS1Class>; 313 def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_X<OpClass, m.vrclass, RS1Class, 0>; 314 } 315} 316 317multiclass VPseudoVC_XV<LMULInfo m, DAGOperand RS1Class, 318 Operand OpClass = payload2> { 319 let VLMul = m.value in { 320 def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_XV<OpClass, m.vrclass, RS1Class>; 321 def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_XV<OpClass, m.vrclass, m.vrclass, RS1Class>; 322 def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_XV<OpClass, m.vrclass, m.vrclass, RS1Class, 0>; 323 } 324} 325 326multiclass VPseudoVC_XVV<LMULInfo m, DAGOperand RS1Class, 327 Operand OpClass = payload2> { 328 let VLMul = m.value in { 329 def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_XVV<OpClass, m.vrclass, m.vrclass, RS1Class>; 330 def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_XVV<OpClass, m.vrclass, m.vrclass, RS1Class>; 331 def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_XVV<OpClass, m.vrclass, m.vrclass, RS1Class, 0>; 332 } 333} 334 335multiclass VPseudoVC_XVW<LMULInfo m, DAGOperand RS1Class, 336 Operand OpClass = payload2> { 337 let VLMul = m.value in { 338 def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_XVV<OpClass, m.wvrclass, m.vrclass, RS1Class>; 339 let Constraints = "@earlyclobber $rd, $rd = $rs3" in { 340 def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_XVV<OpClass, m.wvrclass, m.vrclass, RS1Class>; 341 def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_XVV<OpClass, m.wvrclass, m.vrclass, RS1Class, 0>; 342 } 343 } 344} 345 346multiclass VPseudoSiFiveVMACC<string mx, VReg vd_type, VReg vs2_type, 347 string Constraint = ""> { 348 def "Pseudo" # NAME # "_" # mx 349 : VPseudoTernaryNoMaskWithPolicy<vd_type, V_M1.vrclass, vs2_type, Constraint>; 350} 351 352multiclass VPseudoSiFiveVQMACCDOD<string Constraint = ""> { 353 foreach m = MxListVF8 in 354 let VLMul = m.value in 355 defm NAME : VPseudoSiFiveVMACC<m.MX, m.vrclass, m.vrclass, Constraint>; 356} 357 358multiclass VPseudoSiFiveVQMACCQOQ<string Constraint = ""> { 359 foreach m = [V_MF2, V_M1, V_M2, V_M4] in 360 let VLMul = m.value in 361 defm NAME : VPseudoSiFiveVMACC<m.MX, m.wvrclass, m.vrclass, Constraint>; 362} 363 364multiclass VPseudoSiFiveVFWMACC<string Constraint = ""> { 365 foreach m = MxListVF2 in 366 let VLMul = m.value in 367 defm NAME : VPseudoSiFiveVMACC<m.MX, m.wvrclass, m.vrclass, Constraint>; 368} 369 370multiclass VPseudoSiFiveVFNRCLIP<string Constraint = "@earlyclobber $rd"> { 371 foreach i = 0-4 in 372 let hasSideEffects = 0 in 373 defm "Pseudo" # NAME : VPseudoBinaryRoundingMode<MxListW[i].vrclass, 374 MxListVF4[i].vrclass, 375 FPR32, MxListW[i], 376 Constraint, /*sew*/0, 377 UsesVXRM=0>; 378} 379 380let Predicates = [HasVendorXSfvcp] in { 381 foreach m = MxList in { 382 defm X : VPseudoVC_X<m, GPR>; 383 defm I : VPseudoVC_X<m, tsimm5>; 384 defm XV : VPseudoVC_XV<m, GPR>; 385 defm IV : VPseudoVC_XV<m, tsimm5>; 386 defm VV : VPseudoVC_XV<m, m.vrclass>; 387 defm XVV : VPseudoVC_XVV<m, GPR>; 388 defm IVV : VPseudoVC_XVV<m, tsimm5>; 389 defm VVV : VPseudoVC_XVV<m, m.vrclass>; 390 } 391 foreach f = FPList in { 392 foreach m = f.MxList in { 393 defm f.FX # "V" : VPseudoVC_XV<m, f.fprclass, payload1>; 394 defm f.FX # "VV" : VPseudoVC_XVV<m, f.fprclass, payload1>; 395 } 396 } 397 foreach m = MxListW in { 398 defm XVW : VPseudoVC_XVW<m, GPR>; 399 defm IVW : VPseudoVC_XVW<m, tsimm5>; 400 defm VVW : VPseudoVC_XVW<m, m.vrclass>; 401 } 402 foreach f = FPListW in { 403 foreach m = f.MxList in 404 defm f.FX # "VW" : VPseudoVC_XVW<m, f.fprclass, payload1>; 405 } 406} 407 408let Predicates = [HasVendorXSfvqmaccdod] in { 409 defm VQMACCU_2x8x2 : VPseudoSiFiveVQMACCDOD; 410 defm VQMACC_2x8x2 : VPseudoSiFiveVQMACCDOD; 411 defm VQMACCUS_2x8x2 : VPseudoSiFiveVQMACCDOD; 412 defm VQMACCSU_2x8x2 : VPseudoSiFiveVQMACCDOD; 413} 414 415let Predicates = [HasVendorXSfvqmaccqoq] in { 416 defm VQMACCU_4x8x4 : VPseudoSiFiveVQMACCQOQ; 417 defm VQMACC_4x8x4 : VPseudoSiFiveVQMACCQOQ; 418 defm VQMACCUS_4x8x4 : VPseudoSiFiveVQMACCQOQ; 419 defm VQMACCSU_4x8x4 : VPseudoSiFiveVQMACCQOQ; 420} 421 422let Predicates = [HasVendorXSfvfwmaccqqq] in { 423 defm VFWMACC_4x4x4 : VPseudoSiFiveVFWMACC; 424} 425 426let Predicates = [HasVendorXSfvfnrclipxfqf] in { 427 defm VFNRCLIP_XU_F_QF : VPseudoSiFiveVFNRCLIP; 428 defm VFNRCLIP_X_F_QF : VPseudoSiFiveVFNRCLIP; 429} 430 431class VPatVC_OP4<string intrinsic_name, 432 string inst, 433 ValueType op2_type, 434 ValueType op3_type, 435 ValueType op4_type, 436 int sew, 437 DAGOperand op2_kind, 438 DAGOperand op3_kind, 439 DAGOperand op4_kind, 440 Operand op1_kind = payload2> : 441 Pat<(!cast<Intrinsic>(intrinsic_name) 442 (XLenVT op1_kind:$op1), 443 (op2_type op2_kind:$op2), 444 (op3_type op3_kind:$op3), 445 (op4_type op4_kind:$op4), 446 VLOpFrag), 447 (!cast<Instruction>(inst) 448 (XLenVT op1_kind:$op1), 449 (op2_type op2_kind:$op2), 450 (op3_type op3_kind:$op3), 451 (op4_type op4_kind:$op4), 452 GPR:$vl, sew)>; 453 454class VPatVC_V_OP4<string intrinsic_name, 455 string inst, 456 ValueType result_type, 457 ValueType op2_type, 458 ValueType op3_type, 459 ValueType op4_type, 460 int sew, 461 DAGOperand op2_kind, 462 DAGOperand op3_kind, 463 DAGOperand op4_kind, 464 Operand op1_kind = payload2> : 465 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 466 (XLenVT op1_kind:$op1), 467 (op2_type op2_kind:$op2), 468 (op3_type op3_kind:$op3), 469 (op4_type op4_kind:$op4), 470 VLOpFrag)), 471 (!cast<Instruction>(inst) 472 (XLenVT op1_kind:$op1), 473 (op2_type op2_kind:$op2), 474 (op3_type op3_kind:$op3), 475 (op4_type op4_kind:$op4), 476 GPR:$vl, sew)>; 477 478class VPatVC_V_OP3<string intrinsic_name, 479 string inst, 480 ValueType result_type, 481 ValueType op2_type, 482 ValueType op3_type, 483 int sew, 484 DAGOperand op2_kind, 485 DAGOperand op3_kind, 486 Operand op1_kind = payload2> : 487 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 488 (XLenVT op1_kind:$op1), 489 (op2_type op2_kind:$op2), 490 (op3_type op3_kind:$op3), 491 VLOpFrag)), 492 (!cast<Instruction>(inst) 493 (XLenVT op1_kind:$op1), 494 (op2_type op2_kind:$op2), 495 (op3_type op3_kind:$op3), 496 GPR:$vl, sew)>; 497 498multiclass VPatVC_X<string intrinsic_suffix, string instruction_suffix, 499 VTypeInfo vti, ValueType type, DAGOperand kind> { 500 def : VPatVC_OP4<"int_riscv_sf_vc_" # intrinsic_suffix # "_se_e" # vti.SEW # !tolower(vti.LMul.MX), 501 "PseudoVC_" # instruction_suffix # "_SE_" # vti.LMul.MX, 502 XLenVT, XLenVT, type, vti.Log2SEW, 503 payload5, payload5, kind>; 504 def : VPatVC_V_OP3<"int_riscv_sf_vc_v_" # intrinsic_suffix # "_se", 505 "PseudoVC_V_" # instruction_suffix # "_SE_" # vti.LMul.MX, 506 vti.Vector, XLenVT, type, vti.Log2SEW, 507 payload5, kind>; 508 def : VPatVC_V_OP3<"int_riscv_sf_vc_v_" # intrinsic_suffix, 509 "PseudoVC_V_" # instruction_suffix # "_" # vti.LMul.MX, 510 vti.Vector, XLenVT, type, vti.Log2SEW, 511 payload5, kind>; 512} 513 514multiclass VPatVC_XV<string intrinsic_suffix, string instruction_suffix, 515 VTypeInfo vti, ValueType type, DAGOperand kind, 516 Operand op1_kind = payload2> { 517 def : VPatVC_OP4<"int_riscv_sf_vc_" # intrinsic_suffix # "_se", 518 "PseudoVC_" # instruction_suffix # "_SE_" # vti.LMul.MX, 519 XLenVT, vti.Vector, type, vti.Log2SEW, 520 payload5, vti.RegClass, kind, op1_kind>; 521 def : VPatVC_V_OP3<"int_riscv_sf_vc_v_" # intrinsic_suffix # "_se", 522 "PseudoVC_V_" # instruction_suffix # "_SE_" # vti.LMul.MX, 523 vti.Vector, vti.Vector, type, vti.Log2SEW, 524 vti.RegClass, kind, op1_kind>; 525 def : VPatVC_V_OP3<"int_riscv_sf_vc_v_" # intrinsic_suffix, 526 "PseudoVC_V_" # instruction_suffix # "_" # vti.LMul.MX, 527 vti.Vector, vti.Vector, type, vti.Log2SEW, 528 vti.RegClass, kind, op1_kind>; 529} 530 531multiclass VPatVC_XVV<string intrinsic_suffix, string instruction_suffix, 532 VTypeInfo wti, VTypeInfo vti, ValueType type, DAGOperand kind, 533 Operand op1_kind = payload2> { 534 def : VPatVC_OP4<"int_riscv_sf_vc_" # intrinsic_suffix # "_se", 535 "PseudoVC_" # instruction_suffix # "_SE_" # vti.LMul.MX, 536 wti.Vector, vti.Vector, type, vti.Log2SEW, 537 wti.RegClass, vti.RegClass, kind, op1_kind>; 538 def : VPatVC_V_OP4<"int_riscv_sf_vc_v_" # intrinsic_suffix # "_se", 539 "PseudoVC_V_" # instruction_suffix # "_SE_" # vti.LMul.MX, 540 wti.Vector, wti.Vector, vti.Vector, type, vti.Log2SEW, 541 wti.RegClass, vti.RegClass, kind, op1_kind>; 542 def : VPatVC_V_OP4<"int_riscv_sf_vc_v_" # intrinsic_suffix, 543 "PseudoVC_V_" # instruction_suffix # "_" # vti.LMul.MX, 544 wti.Vector, wti.Vector, vti.Vector, type, vti.Log2SEW, 545 wti.RegClass, vti.RegClass, kind, op1_kind>; 546} 547 548class GetFTypeInfo<int Sew> { 549 ValueType Scalar = !cond(!eq(Sew, 16) : f16, 550 !eq(Sew, 32) : f32, 551 !eq(Sew, 64) : f64); 552 RegisterClass ScalarRegClass = !cond(!eq(Sew, 16) : FPR16, 553 !eq(Sew, 32) : FPR32, 554 !eq(Sew, 64) : FPR64); 555 556 string ScalarSuffix = !cond(!eq(Scalar, f16) : "FPR16", 557 !eq(Scalar, f32) : "FPR32", 558 !eq(Scalar, f64) : "FPR64"); 559} 560 561multiclass VPatVMACC<string intrinsic, string instruction, string kind, 562 list<VTypeInfoToWide> info_pairs, ValueType vec_m1> { 563 foreach pair = info_pairs in { 564 defvar VdInfo = pair.Wti; 565 defvar Vs2Info = pair.Vti; 566 let Predicates = [HasVInstructions] in 567 def : VPatTernaryNoMaskWithPolicy<"int_riscv_sf_" # intrinsic, 568 "Pseudo" # instruction, kind, VdInfo.Vector, 569 vec_m1, Vs2Info.Vector, 570 Vs2Info.Log2SEW, Vs2Info.LMul, 571 VdInfo.RegClass, VR, Vs2Info.RegClass>; 572 } 573} 574 575defset list<VTypeInfoToWide> VQMACCDODInfoPairs = { 576 def : VTypeInfoToWide<VI8M1, VI32M1>; 577 def : VTypeInfoToWide<VI8M2, VI32M2>; 578 def : VTypeInfoToWide<VI8M4, VI32M4>; 579 def : VTypeInfoToWide<VI8M8, VI32M8>; 580} 581 582defset list<VTypeInfoToWide> VQMACCQOQInfoPairs = { 583 def : VTypeInfoToWide<VI8MF2, VI32M1>; 584 def : VTypeInfoToWide<VI8M1, VI32M2>; 585 def : VTypeInfoToWide<VI8M2, VI32M4>; 586 def : VTypeInfoToWide<VI8M4, VI32M8>; 587} 588 589multiclass VPatVQMACCDOD<string intrinsic, string instruction, string kind> 590 : VPatVMACC<intrinsic, instruction, kind, VQMACCDODInfoPairs, vint8m1_t>; 591 592multiclass VPatVQMACCQOQ<string intrinsic, string instruction, string kind> 593 : VPatVMACC<intrinsic, instruction, kind, VQMACCQOQInfoPairs, vint8m1_t>; 594 595multiclass VPatVFWMACC<string intrinsic, string instruction, string kind> 596 : VPatVMACC<intrinsic, instruction, kind, AllWidenableBFloatToFloatVectors, 597 vbfloat16m1_t>; 598 599defset list<VTypeInfoToWide> VFNRCLIPInfoPairs = { 600 def : VTypeInfoToWide<VI8MF8, VF32MF2>; 601 def : VTypeInfoToWide<VI8MF4, VF32M1>; 602 def : VTypeInfoToWide<VI8MF2, VF32M2>; 603 def : VTypeInfoToWide<VI8M1, VF32M4>; 604 def : VTypeInfoToWide<VI8M2, VF32M8>; 605} 606 607multiclass VPatVFNRCLIP<string intrinsic, string instruction> { 608 foreach pair = VFNRCLIPInfoPairs in { 609 defvar Vti = pair.Vti; 610 defvar Wti = pair.Wti; 611 defm : VPatBinaryRoundingMode<"int_riscv_sf_" # intrinsic, 612 "Pseudo" # instruction # "_" # Vti.LMul.MX, 613 Vti.Vector, Wti.Vector, Wti.Scalar, Vti.Mask, 614 Vti.Log2SEW, Vti.RegClass, 615 Wti.RegClass, Wti.ScalarRegClass>; 616 } 617} 618 619let Predicates = [HasVendorXSfvcp] in { 620 foreach vti = AllIntegerVectors in { 621 defm : VPatVC_X<"x", "X", vti, XLenVT, GPR>; 622 defm : VPatVC_X<"i", "I", vti, XLenVT, tsimm5>; 623 defm : VPatVC_XV<"xv", "XV", vti, XLenVT, GPR>; 624 defm : VPatVC_XV<"iv", "IV", vti, XLenVT, tsimm5>; 625 defm : VPatVC_XV<"vv", "VV", vti, vti.Vector, vti.RegClass>; 626 defm : VPatVC_XVV<"xvv", "XVV", vti, vti, XLenVT, GPR>; 627 defm : VPatVC_XVV<"ivv", "IVV", vti, vti, XLenVT, tsimm5>; 628 defm : VPatVC_XVV<"vvv", "VVV", vti, vti, vti.Vector, vti.RegClass>; 629 630 if !ne(vti.SEW, 8) then { 631 defvar finfo = GetFTypeInfo<vti.SEW>; 632 defm : VPatVC_XV<"fv", finfo.ScalarSuffix # "V", vti, finfo.Scalar, 633 finfo.ScalarRegClass, payload1>; 634 defm : VPatVC_XVV<"fvv", finfo.ScalarSuffix # "VV", vti, vti, finfo.Scalar, 635 finfo.ScalarRegClass, payload1>; 636 } 637 } 638 foreach VtiToWti = AllWidenableIntVectors in { 639 defvar vti = VtiToWti.Vti; 640 defvar wti = VtiToWti.Wti; 641 defvar iinfo = GetIntVTypeInfo<vti>.Vti; 642 defm : VPatVC_XVV<"xvw", "XVW", wti, vti, iinfo.Scalar, iinfo.ScalarRegClass>; 643 defm : VPatVC_XVV<"ivw", "IVW", wti, vti, XLenVT, tsimm5>; 644 defm : VPatVC_XVV<"vvw", "VVW", wti, vti, vti.Vector, vti.RegClass>; 645 646 if !ne(vti.SEW, 8) then { 647 defvar finfo = GetFTypeInfo<vti.SEW>; 648 defm : VPatVC_XVV<"fvw", finfo.ScalarSuffix # "VW", wti, vti, finfo.Scalar, 649 finfo.ScalarRegClass, payload1>; 650 } 651 } 652} 653 654let Predicates = [HasVendorXSfvqmaccdod] in { 655 defm : VPatVQMACCDOD<"vqmaccu_2x8x2", "VQMACCU", "2x8x2">; 656 defm : VPatVQMACCDOD<"vqmacc_2x8x2", "VQMACC", "2x8x2">; 657 defm : VPatVQMACCDOD<"vqmaccus_2x8x2", "VQMACCUS", "2x8x2">; 658 defm : VPatVQMACCDOD<"vqmaccsu_2x8x2", "VQMACCSU", "2x8x2">; 659} 660 661let Predicates = [HasVendorXSfvqmaccqoq] in { 662 defm : VPatVQMACCQOQ<"vqmaccu_4x8x4", "VQMACCU", "4x8x4">; 663 defm : VPatVQMACCQOQ<"vqmacc_4x8x4", "VQMACC", "4x8x4">; 664 defm : VPatVQMACCQOQ<"vqmaccus_4x8x4", "VQMACCUS", "4x8x4">; 665 defm : VPatVQMACCQOQ<"vqmaccsu_4x8x4", "VQMACCSU", "4x8x4">; 666} 667 668let Predicates = [HasVendorXSfvfwmaccqqq] in { 669 defm : VPatVFWMACC<"vfwmacc_4x4x4", "VFWMACC", "4x4x4">; 670} 671 672let Predicates = [HasVendorXSfvfnrclipxfqf] in { 673 defm : VPatVFNRCLIP<"vfnrclip_xu_f_qf", "VFNRCLIP_XU_F_QF">; 674 defm : VPatVFNRCLIP<"vfnrclip_x_f_qf", "VFNRCLIP_X_F_QF">; 675} 676