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 timm5 operands are all marked as ImmArg in the IR 31// intrinsic and will be target constant, so use TImmLeaf rather than ImmLeaf. 32def payload1 : Operand<XLenVT>, TImmLeaf<XLenVT, [{return isUInt<1>(Imm);}]> { 33 let ParserMatchClass = UImmAsmOperand<1>; 34 let DecoderMethod = "decodeUImmOperand<1>"; 35 let OperandType = "OPERAND_UIMM1"; 36 let OperandNamespace = "RISCVOp"; 37} 38 39def payload2 : Operand<XLenVT>, TImmLeaf<XLenVT, [{return isUInt<2>(Imm);}]> { 40 let ParserMatchClass = UImmAsmOperand<2>; 41 let DecoderMethod = "decodeUImmOperand<2>"; 42 let OperandType = "OPERAND_UIMM2"; 43 let OperandNamespace = "RISCVOp"; 44} 45 46def payload5 : Operand<XLenVT>, TImmLeaf<XLenVT, [{return isUInt<5>(Imm);}]> { 47 let ParserMatchClass = UImmAsmOperand<5>; 48 let DecoderMethod = "decodeUImmOperand<5>"; 49 let OperandType = "OPERAND_UIMM5"; 50 let OperandNamespace = "RISCVOp"; 51} 52 53def timm5 : Operand<XLenVT>, TImmLeaf<XLenVT, [{return isInt<5>(Imm);}]> { 54 let ParserMatchClass = SImmAsmOperand<5>; 55 let EncoderMethod = "getImmOpValue"; 56 let DecoderMethod = "decodeSImmOperand<5>"; 57 let MCOperandPredicate = [{ 58 int64_t Imm; 59 if (MCOp.evaluateAsConstantImm(Imm)) 60 return isInt<5>(Imm); 61 return MCOp.isBareSymbolRef(); 62 }]; 63} 64 65class SwapVCIXIns<dag funct6, dag rd, dag rs2, dag rs1, bit swap> { 66 dag Ins = !con(funct6, !if(swap, rs2, rd), !if(swap, rd, rs2), rs1); 67} 68 69class RVInstVCCustom2<bits<4> funct6_hi4, bits<3> funct3, dag outs, dag ins, 70 string opcodestr, string argstr> 71 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 72 bits<5> rs2; 73 bits<5> rs1; 74 bits<5> rd; 75 bits<2> funct6_lo2; 76 bit vm; 77 78 let Inst{31-28} = funct6_hi4; 79 let Inst{27-26} = funct6_lo2; 80 let Inst{25} = vm; 81 let Inst{24-20} = rs2; 82 let Inst{19-15} = rs1; 83 let Inst{14-12} = funct3; 84 let Inst{11-7} = rd; 85 let Inst{6-0} = OPC_CUSTOM_2.Value; 86 87 let Uses = [VTYPE, VL]; 88 let RVVConstraint = NoConstraint; 89} 90 91class RVInstVCFCustom2<bits<4> funct6_hi4, bits<3> funct3, dag outs, dag ins, 92 string opcodestr, string argstr> 93 : RVInst<outs, ins, opcodestr, argstr, [], InstFormatR> { 94 bits<5> rs2; 95 bits<5> rs1; 96 bits<5> rd; 97 bit funct6_lo1; 98 bit vm; 99 100 let Inst{31-28} = funct6_hi4; 101 let Inst{27} = 1; 102 let Inst{26} = funct6_lo1; 103 let Inst{25} = vm; 104 let Inst{24-20} = rs2; 105 let Inst{19-15} = rs1; 106 let Inst{14-12} = funct3; 107 let Inst{11-7} = rd; 108 let Inst{6-0} = OPC_CUSTOM_2.Value; 109 110 let Uses = [VTYPE, VL]; 111 let RVVConstraint = NoConstraint; 112} 113 114class GetFTypeInfo<int sew> { 115 ValueType Scalar = !cond(!eq(sew, 16): f16, 116 !eq(sew, 32): f32, 117 !eq(sew, 64): f64); 118 RegisterClass ScalarRegClass = !cond(!eq(sew, 16): FPR16, 119 !eq(sew, 32): FPR32, 120 !eq(sew, 64): FPR64); 121} 122 123class VCIXInfo<string suffix, VCIXType type, DAGOperand TyRd, 124 DAGOperand TyRs2, DAGOperand TyRs1, bit HaveOutputDst> { 125 string OpcodeStr = !if(HaveOutputDst, "sf.vc.v." # suffix, 126 "sf.vc." # suffix); 127 bits<4> Funct6_hi4 = type.Val; 128 bits<3> Funct3 = !cond(!eq(TyRs1, VR): 0b000, 129 !eq(TyRs1, GPR): 0b100, 130 !eq(TyRs1, FPR32): 0b101, 131 !eq(TyRs1, simm5): 0b011); 132 dag Outs = !if(!not(HaveOutputDst), (outs), 133 !if(!or(!eq(type, VCIX_XVV), !eq(type, VCIX_XVW)), 134 (outs TyRd:$rd_wb), (outs TyRd:$rd))); 135 dag Ins = SwapVCIXIns<!if(!ne(TyRs1, FPR32), (ins uimm2:$funct6_lo2), 136 (ins uimm1:$funct6_lo1)), 137 !if(!and(HaveOutputDst, !or(!eq(type, VCIX_X), 138 !eq(type, VCIX_XV))), 139 (ins), (ins TyRd:$rd)), 140 (ins TyRs2:$rs2), 141 (ins TyRs1:$rs1), 142 !if(!eq(type, VCIX_X), 1, 0)>.Ins; 143 string Prototype = !if(!eq(type, VCIX_X), "$funct6_lo2, $rs2, $rd, $rs1", 144 !if(!ne(TyRs1, FPR32), "$funct6_lo2, $rd, $rs2, $rs1", 145 "$funct6_lo1, $rd, $rs2, $rs1")); 146 string Constraints = !if(!not(HaveOutputDst), "", 147 !if(!or(!eq(type, VCIX_XVV), 148 !eq(type, VCIX_XVW)), "$rd = $rd_wb", "")); 149 RISCVVConstraint RVVConstraint = !if(!or(!not(HaveOutputDst), 150 !ne(type, VCIX_XVW)), NoConstraint, 151 !if(!eq(TyRs1, VR), VCIXVS2VS1, VCIXVS2)); 152} 153 154class CustomSiFiveVCIX<VCIXInfo info> 155 : RVInstVCCustom2<info.Funct6_hi4, info.Funct3, info.Outs, 156 info.Ins, info.OpcodeStr, info.Prototype> { 157 let Constraints = info.Constraints; 158 let RVVConstraint = info.RVVConstraint; 159} 160 161class CustomSiFiveVCIF<VCIXInfo info> 162 : RVInstVCFCustom2<info.Funct6_hi4, info.Funct3, info.Outs, 163 info.Ins, info.OpcodeStr, info.Prototype> { 164 let Constraints = info.Constraints; 165 let RVVConstraint = info.RVVConstraint; 166} 167 168multiclass CustomSiFiveVCIXorVCIF<string suffix, VCIXType type, 169 DAGOperand TyRd, DAGOperand TyRs2, 170 DAGOperand TyRs1, bit HaveOutputDst> { 171 defvar info = VCIXInfo<suffix, type, TyRd, TyRs2, TyRs1, HaveOutputDst>; 172 if !eq(TyRs1, FPR32) then { 173 def NAME : CustomSiFiveVCIF<info>; 174 } else { 175 def NAME : CustomSiFiveVCIX<info>; 176 } 177} 178 179multiclass CustomSiFiveVCIX<string suffix, VCIXType type, 180 DAGOperand InTyRd, DAGOperand InTyRs2, 181 DAGOperand InTyRs1> { 182 let vm = 1 in 183 defm VC_ # NAME : CustomSiFiveVCIXorVCIF<suffix, type, InTyRd, InTyRs2, 184 InTyRs1, 0>; 185 let vm = 0 in 186 defm VC_V_ # NAME : CustomSiFiveVCIXorVCIF<suffix, type, VR, InTyRs2, 187 InTyRs1, 1>; 188} 189 190let Predicates = [HasVendorXSfvcp], mayLoad = 0, mayStore = 0, 191 hasSideEffects = 1, hasNoSchedulingInfo = 1, DecoderNamespace = "XSfvcp" in { 192 defm X : CustomSiFiveVCIX<"x", VCIX_X, uimm5, uimm5, GPR>, Sched<[]>; 193 defm I : CustomSiFiveVCIX<"i", VCIX_X, uimm5, uimm5, simm5>, Sched<[]>; 194 defm XV : CustomSiFiveVCIX<"xv", VCIX_XV, uimm5, VR, GPR>, Sched<[]>; 195 defm IV : CustomSiFiveVCIX<"iv", VCIX_XV, uimm5, VR, simm5>, Sched<[]>; 196 defm VV : CustomSiFiveVCIX<"vv", VCIX_XV, uimm5, VR, VR>, Sched<[]>; 197 defm FV : CustomSiFiveVCIX<"fv", VCIX_XV, uimm5, VR, FPR32>, Sched<[]>; 198 defm XVV : CustomSiFiveVCIX<"xvv", VCIX_XVV, VR, VR, GPR>, Sched<[]>; 199 defm IVV : CustomSiFiveVCIX<"ivv", VCIX_XVV, VR, VR, simm5>, Sched<[]>; 200 defm VVV : CustomSiFiveVCIX<"vvv", VCIX_XVV, VR, VR, VR>, Sched<[]>; 201 defm FVV : CustomSiFiveVCIX<"fvv", VCIX_XVV, VR, VR, FPR32>, Sched<[]>; 202 defm XVW : CustomSiFiveVCIX<"xvw", VCIX_XVW, VR, VR, GPR>, Sched<[]>; 203 defm IVW : CustomSiFiveVCIX<"ivw", VCIX_XVW, VR, VR, simm5>, Sched<[]>; 204 defm VVW : CustomSiFiveVCIX<"vvw", VCIX_XVW, VR, VR, VR>, Sched<[]>; 205 defm FVW : CustomSiFiveVCIX<"fvw", VCIX_XVW, VR, VR, FPR32>, Sched<[]>; 206} 207 208class VPseudoVC_X<Operand OpClass, DAGOperand RS1Class, 209 bit HasSideEffect = 1> : 210 Pseudo<(outs), 211 (ins OpClass:$op1, payload5:$rs2, payload5:$rd, RS1Class:$r1, 212 AVL:$vl, ixlenimm:$sew), []>, 213 RISCVVPseudo { 214 let mayLoad = 0; 215 let mayStore = 0; 216 let HasVLOp = 1; 217 let HasSEWOp = 1; 218 let hasSideEffects = HasSideEffect; 219 let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); 220} 221 222class VPseudoVC_XV<Operand OpClass, VReg RS2Class, DAGOperand RS1Class, 223 bit HasSideEffect = 1> : 224 Pseudo<(outs), 225 (ins OpClass:$op1, payload5:$rd, RS2Class:$rs2, RS1Class:$r1, 226 AVL:$vl, ixlenimm:$sew), []>, 227 RISCVVPseudo { 228 let mayLoad = 0; 229 let mayStore = 0; 230 let HasVLOp = 1; 231 let HasSEWOp = 1; 232 let hasSideEffects = HasSideEffect; 233 let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); 234} 235 236class VPseudoVC_XVV<Operand OpClass, VReg RDClass, VReg RS2Class, 237 DAGOperand RS1Class, bit HasSideEffect = 1> : 238 Pseudo<(outs), 239 (ins OpClass:$op1, RDClass:$rd, RS2Class:$rs2, RS1Class:$r1, 240 AVL:$vl, ixlenimm:$sew), []>, 241 RISCVVPseudo { 242 let mayLoad = 0; 243 let mayStore = 0; 244 let HasVLOp = 1; 245 let HasSEWOp = 1; 246 let hasSideEffects = HasSideEffect; 247 let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); 248} 249 250class VPseudoVC_V_X<Operand OpClass, VReg RDClass, DAGOperand RS1Class, 251 bit HasSideEffect = 1> : 252 Pseudo<(outs RDClass:$rd), 253 (ins OpClass:$op1, payload5:$rs2, RS1Class:$r1, 254 AVL:$vl, ixlenimm:$sew), []>, 255 RISCVVPseudo { 256 let mayLoad = 0; 257 let mayStore = 0; 258 let HasVLOp = 1; 259 let HasSEWOp = 1; 260 let hasSideEffects = HasSideEffect; 261 let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); 262} 263 264class VPseudoVC_V_XV<Operand OpClass, VReg RDClass, VReg RS2Class, 265 DAGOperand RS1Class, bit HasSideEffect = 1> : 266 Pseudo<(outs RDClass:$rd), 267 (ins OpClass:$op1, RS2Class:$rs2, RS1Class:$r1, 268 AVL:$vl, ixlenimm:$sew), []>, 269 RISCVVPseudo { 270 let mayLoad = 0; 271 let mayStore = 0; 272 let HasVLOp = 1; 273 let HasSEWOp = 1; 274 let hasSideEffects = HasSideEffect; 275 let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); 276} 277 278class VPseudoVC_V_XVV<Operand OpClass, VReg RDClass, VReg RS2Class, 279 DAGOperand RS1Class, bit HasSideEffect = 1> : 280 Pseudo<(outs RDClass:$rd), 281 (ins OpClass:$op1, RDClass:$rs3, RS2Class:$rs2, RS1Class:$r1, 282 AVL:$vl, ixlenimm:$sew), []>, 283 RISCVVPseudo { 284 let mayLoad = 0; 285 let mayStore = 0; 286 let HasVLOp = 1; 287 let HasSEWOp = 1; 288 let hasSideEffects = HasSideEffect; 289 let BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); 290} 291 292multiclass VPseudoVC_X<LMULInfo m, DAGOperand RS1Class, 293 Operand OpClass = payload2> { 294 let VLMul = m.value in { 295 def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_X<OpClass, RS1Class>; 296 def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_X<OpClass, m.vrclass, RS1Class>; 297 def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_X<OpClass, m.vrclass, RS1Class, 0>; 298 } 299} 300 301multiclass VPseudoVC_XV<LMULInfo m, DAGOperand RS1Class, 302 Operand OpClass = payload2> { 303 let VLMul = m.value in { 304 def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_XV<OpClass, m.vrclass, RS1Class>; 305 def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_XV<OpClass, m.vrclass, m.vrclass, RS1Class>; 306 def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_XV<OpClass, m.vrclass, m.vrclass, RS1Class, 0>; 307 } 308} 309 310multiclass VPseudoVC_XVV<LMULInfo m, DAGOperand RS1Class, 311 Operand OpClass = payload2> { 312 let VLMul = m.value in { 313 def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_XVV<OpClass, m.vrclass, m.vrclass, RS1Class>; 314 def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_XVV<OpClass, m.vrclass, m.vrclass, RS1Class>; 315 def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_XVV<OpClass, m.vrclass, m.vrclass, RS1Class, 0>; 316 } 317} 318 319multiclass VPseudoVC_XVW<LMULInfo m, DAGOperand RS1Class, 320 Operand OpClass = payload2> { 321 let VLMul = m.value in { 322 def "PseudoVC_" # NAME # "_SE_" # m.MX : VPseudoVC_XVV<OpClass, m.wvrclass, m.vrclass, RS1Class>; 323 let Constraints = "@earlyclobber $rd, $rd = $rs3" in { 324 def "PseudoVC_V_" # NAME # "_SE_" # m.MX : VPseudoVC_V_XVV<OpClass, m.wvrclass, m.vrclass, RS1Class>; 325 def "PseudoVC_V_" # NAME # "_" # m.MX : VPseudoVC_V_XVV<OpClass, m.wvrclass, m.vrclass, RS1Class, 0>; 326 } 327 } 328} 329 330let Predicates = [HasVendorXSfvcp] in { 331 foreach m = MxList in { 332 defm X : VPseudoVC_X<m, GPR>; 333 defm I : VPseudoVC_X<m, timm5>; 334 defm XV : VPseudoVC_XV<m, GPR>; 335 defm IV : VPseudoVC_XV<m, timm5>; 336 defm VV : VPseudoVC_XV<m, m.vrclass>; 337 defm XVV : VPseudoVC_XVV<m, GPR>; 338 defm IVV : VPseudoVC_XVV<m, timm5>; 339 defm VVV : VPseudoVC_XVV<m, m.vrclass>; 340 } 341 foreach f = FPList in { 342 foreach m = f.MxList in { 343 defm f.FX # "V" : VPseudoVC_XV<m, f.fprclass, payload1>; 344 defm f.FX # "VV" : VPseudoVC_XVV<m, f.fprclass, payload1>; 345 } 346 } 347 foreach m = MxListW in { 348 defm XVW : VPseudoVC_XVW<m, GPR>; 349 defm IVW : VPseudoVC_XVW<m, timm5>; 350 defm VVW : VPseudoVC_XVW<m, m.vrclass>; 351 } 352 foreach f = FPListW in { 353 foreach m = f.MxList in 354 defm f.FX # "VW" : VPseudoVC_XVW<m, f.fprclass, payload1>; 355 } 356} 357 358class VPatVC_OP4<string intrinsic_name, 359 string inst, 360 ValueType op2_type, 361 ValueType op3_type, 362 ValueType op4_type, 363 int sew, 364 DAGOperand op2_kind, 365 DAGOperand op3_kind, 366 DAGOperand op4_kind, 367 Operand op1_kind = payload2> : 368 Pat<(!cast<Intrinsic>(intrinsic_name) 369 (XLenVT op1_kind:$op1), 370 (op2_type op2_kind:$op2), 371 (op3_type op3_kind:$op3), 372 (op4_type op4_kind:$op4), 373 VLOpFrag), 374 (!cast<Instruction>(inst) 375 (XLenVT op1_kind:$op1), 376 (op2_type op2_kind:$op2), 377 (op3_type op3_kind:$op3), 378 (op4_type op4_kind:$op4), 379 GPR:$vl, sew)>; 380 381class VPatVC_V_OP4<string intrinsic_name, 382 string inst, 383 ValueType result_type, 384 ValueType op2_type, 385 ValueType op3_type, 386 ValueType op4_type, 387 int sew, 388 DAGOperand op2_kind, 389 DAGOperand op3_kind, 390 DAGOperand op4_kind, 391 Operand op1_kind = payload2> : 392 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 393 (XLenVT op1_kind:$op1), 394 (op2_type op2_kind:$op2), 395 (op3_type op3_kind:$op3), 396 (op4_type op4_kind:$op4), 397 VLOpFrag)), 398 (!cast<Instruction>(inst) 399 (XLenVT op1_kind:$op1), 400 (op2_type op2_kind:$op2), 401 (op3_type op3_kind:$op3), 402 (op4_type op4_kind:$op4), 403 GPR:$vl, sew)>; 404 405class VPatVC_V_OP3<string intrinsic_name, 406 string inst, 407 ValueType result_type, 408 ValueType op2_type, 409 ValueType op3_type, 410 int sew, 411 DAGOperand op2_kind, 412 DAGOperand op3_kind, 413 Operand op1_kind = payload2> : 414 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 415 (XLenVT op1_kind:$op1), 416 (op2_type op2_kind:$op2), 417 (op3_type op3_kind:$op3), 418 VLOpFrag)), 419 (!cast<Instruction>(inst) 420 (XLenVT op1_kind:$op1), 421 (op2_type op2_kind:$op2), 422 (op3_type op3_kind:$op3), 423 GPR:$vl, sew)>; 424 425multiclass VPatVC_X<string intrinsic_suffix, string instruction_suffix, 426 VTypeInfo vti, ValueType type, DAGOperand kind> { 427 def : VPatVC_OP4<"int_riscv_sf_vc_" # intrinsic_suffix # "_se_e" # vti.SEW # !tolower(vti.LMul.MX), 428 "PseudoVC_" # instruction_suffix # "_SE_" # vti.LMul.MX, 429 XLenVT, XLenVT, type, vti.Log2SEW, 430 payload5, payload5, kind>; 431 def : VPatVC_V_OP3<"int_riscv_sf_vc_v_" # intrinsic_suffix # "_se", 432 "PseudoVC_V_" # instruction_suffix # "_SE_" # vti.LMul.MX, 433 vti.Vector, XLenVT, type, vti.Log2SEW, 434 payload5, kind>; 435 def : VPatVC_V_OP3<"int_riscv_sf_vc_v_" # intrinsic_suffix, 436 "PseudoVC_V_" # instruction_suffix # "_" # vti.LMul.MX, 437 vti.Vector, XLenVT, type, vti.Log2SEW, 438 payload5, kind>; 439} 440 441multiclass VPatVC_XV<string intrinsic_suffix, string instruction_suffix, 442 VTypeInfo vti, ValueType type, DAGOperand kind, 443 Operand op1_kind = payload2> { 444 def : VPatVC_OP4<"int_riscv_sf_vc_" # intrinsic_suffix # "_se", 445 "PseudoVC_" # instruction_suffix # "_SE_" # vti.LMul.MX, 446 XLenVT, vti.Vector, type, vti.Log2SEW, 447 payload5, vti.RegClass, kind, op1_kind>; 448 def : VPatVC_V_OP3<"int_riscv_sf_vc_v_" # intrinsic_suffix # "_se", 449 "PseudoVC_V_" # instruction_suffix # "_SE_" # vti.LMul.MX, 450 vti.Vector, vti.Vector, type, vti.Log2SEW, 451 vti.RegClass, kind, op1_kind>; 452 def : VPatVC_V_OP3<"int_riscv_sf_vc_v_" # intrinsic_suffix, 453 "PseudoVC_V_" # instruction_suffix # "_" # vti.LMul.MX, 454 vti.Vector, vti.Vector, type, vti.Log2SEW, 455 vti.RegClass, kind, op1_kind>; 456} 457 458multiclass VPatVC_XVV<string intrinsic_suffix, string instruction_suffix, 459 VTypeInfo wti, VTypeInfo vti, ValueType type, DAGOperand kind, 460 Operand op1_kind = payload2> { 461 def : VPatVC_OP4<"int_riscv_sf_vc_" # intrinsic_suffix # "_se", 462 "PseudoVC_" # instruction_suffix # "_SE_" # vti.LMul.MX, 463 wti.Vector, vti.Vector, type, vti.Log2SEW, 464 wti.RegClass, vti.RegClass, kind, op1_kind>; 465 def : VPatVC_V_OP4<"int_riscv_sf_vc_v_" # intrinsic_suffix # "_se", 466 "PseudoVC_V_" # instruction_suffix # "_SE_" # vti.LMul.MX, 467 wti.Vector, wti.Vector, vti.Vector, type, vti.Log2SEW, 468 wti.RegClass, vti.RegClass, kind, op1_kind>; 469 def : VPatVC_V_OP4<"int_riscv_sf_vc_v_" # intrinsic_suffix, 470 "PseudoVC_V_" # instruction_suffix # "_" # vti.LMul.MX, 471 wti.Vector, wti.Vector, vti.Vector, type, vti.Log2SEW, 472 wti.RegClass, vti.RegClass, kind, op1_kind>; 473} 474 475let Predicates = [HasVendorXSfvcp] in { 476 foreach vti = AllIntegerVectors in { 477 defm : VPatVC_X<"x", "X", vti, vti.Scalar, vti.ScalarRegClass>; 478 defm : VPatVC_X<"i", "I", vti, XLenVT, timm5>; 479 defm : VPatVC_XV<"xv", "XV", vti, vti.Scalar, vti.ScalarRegClass>; 480 defm : VPatVC_XV<"iv", "IV", vti, XLenVT, timm5>; 481 defm : VPatVC_XV<"vv", "VV", vti, vti.Vector, vti.RegClass>; 482 defm : VPatVC_XVV<"xvv", "XVV", vti, vti, vti.Scalar, vti.ScalarRegClass>; 483 defm : VPatVC_XVV<"ivv", "IVV", vti, vti, XLenVT, timm5>; 484 defm : VPatVC_XVV<"vvv", "VVV", vti, vti, vti.Vector, vti.RegClass>; 485 if !ge(vti.SEW, 16) then { 486 defm : VPatVC_XV<"fv", "F" # vti.SEW # "V", vti, 487 GetFTypeInfo<vti.SEW>.Scalar, 488 GetFTypeInfo<vti.SEW>.ScalarRegClass, payload1>; 489 defm : VPatVC_XVV<"fvv", "F" # vti.SEW # "VV", vti, vti, 490 GetFTypeInfo<vti.SEW>.Scalar, 491 GetFTypeInfo<vti.SEW>.ScalarRegClass, payload1>; 492 } 493 } 494 foreach VtiToWti = AllWidenableIntVectors in { 495 defvar vti = VtiToWti.Vti; 496 defvar wti = VtiToWti.Wti; 497 defm : VPatVC_XVV<"xvw", "XVW", wti, vti, vti.Scalar, vti.ScalarRegClass>; 498 defm : VPatVC_XVV<"ivw", "IVW", wti, vti, XLenVT, timm5>; 499 defm : VPatVC_XVV<"vvw", "VVW", wti, vti, vti.Vector, vti.RegClass>; 500 if !ge(vti.SEW, 16) then { 501 defm : VPatVC_XVV<"fvw", "F" # vti.SEW # "VW", wti, vti, 502 GetFTypeInfo<vti.SEW>.Scalar, 503 GetFTypeInfo<vti.SEW>.ScalarRegClass, payload1>; 504 } 505 } 506} 507 508let Predicates = [HasVendorXSfcie] in { 509let hasSideEffects = 1, mayLoad = 0, mayStore = 0, DecoderNamespace = "XSfcie" in { 510def SF_CFLUSH_D_L1 : RVInstI<0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1), "cflush.d.l1","$rs1">, 511 Sched<[]> { 512 let rd = 0; 513 let imm12 = {0b1111,0b1100,0b0000}; 514} 515 516def SF_CDISCARD_D_L1 : RVInstI<0b000, OPC_SYSTEM, (outs), (ins GPR:$rs1), "cdiscard.d.l1","$rs1">, 517 Sched<[]> { 518 let rd = 0; 519 let imm12 = {0b1111,0b1100,0b0010}; 520} 521 522def SF_CEASE : RVInstI<0b000, OPC_SYSTEM, (outs), (ins), "cease","">, Sched<[]> { 523 let rs1 = 0; 524 let rd = 0; 525 let imm12 = {0b0011,0b0000,0b0101}; 526} 527} 528def : InstAlias<"cflush.d.l1", (SF_CFLUSH_D_L1 X0)>; 529def : InstAlias<"cdiscard.d.l1", (SF_CDISCARD_D_L1 X0)>; 530} // Predicates = [HasVendorXScie] 531