1//===-- RISCVInstrInfoVPseudos.td - RISC-V 'V' Pseudos -----*- 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 contains the required infrastructure to support code generation 10/// for the standard 'V' (Vector) extension, version 1.0. 11/// 12/// This file is included from RISCVInstrInfoV.td 13/// 14/// Overview of our vector instruction pseudos. Many of the instructions 15/// have behavior which depends on the value of VTYPE. Several core aspects of 16/// the compiler - e.g. register allocation - depend on fields in this 17/// configuration register. The details of which fields matter differ by the 18/// specific instruction, but the common dimensions are: 19/// 20/// LMUL/EMUL - Most instructions can write to differently sized register groups 21/// depending on LMUL. 22/// 23/// Masked vs Unmasked - Many instructions which allow a mask disallow register 24/// overlap. As a result, masked vs unmasked require different register 25/// allocation constraints. 26/// 27/// Policy - For each of mask and tail policy, there are three options: 28/// * "Undisturbed" - As defined in the specification, required to preserve the 29/// exact bit pattern of inactive lanes. 30/// * "Agnostic" - As defined in the specification, required to either preserve 31/// the exact bit pattern of inactive lanes, or produce the bit pattern -1 for 32/// those lanes. Note that each lane can make this choice independently. 33/// Instructions which produce masks (and only those instructions) also have the 34/// option of producing a result as-if VL had been VLMAX. 35/// * "Undefined" - The bit pattern of the inactive lanes is unspecified, and 36/// can be changed without impacting the semantics of the program. Note that 37/// this concept does not exist in the specification, and requires source 38/// knowledge to be preserved. 39/// 40/// SEW - Some instructions have semantics which depend on SEW. This is 41/// relatively rare, and mostly impacts scheduling and cost estimation. 42/// 43/// We have two techniques we use to represent the impact of these fields: 44/// * For fields which don't impact register classes, we largely use 45/// dummy operands on the pseudo instructions which convey information 46/// about the value of VTYPE. 47/// * For fields which do impact register classes (and a few bits of 48/// legacy - see policy discussion below), we define a family of pseudo 49/// instructions for each actual instruction. Said differently, we encode 50/// each of the preceding fields which are relevant for a given instruction 51/// in the opcode space. 52/// 53/// Currently, the policy is represented via the following instrinsic families: 54/// * _MASK - Can represent all three policy states for both tail and mask. If 55/// passthrough is IMPLICIT_DEF (or NoReg), then represents "undefined". 56/// Otherwise, policy operand and tablegen flags drive the interpretation. 57/// (If policy operand is not present - there are a couple, though we're 58/// rapidly removing them - a non-undefined policy defaults to "tail 59/// agnostic", and "mask undisturbed". Since this is the only variant with 60/// a mask, all other variants are "mask undefined". 61/// * Unsuffixed w/ both passthrough and policy operand. Can represent all 62/// three policy states. If passthrough is IMPLICIT_DEF (or NoReg), then 63/// represents "undefined". Otherwise, policy operand and tablegen flags 64/// drive the interpretation. 65/// * Unsuffixed w/o passthrough or policy operand -- Does not have a 66/// passthrough operand, and thus represents the "undefined" state. Note 67/// that terminology in code frequently refers to these as "TA" which is 68/// confusing. We're in the process of migrating away from this 69/// representation. 70/// * _TU w/o policy operand -- Has a passthrough operand, and always 71/// represents the tail undisturbed state. 72/// * _TU w/policy operand - Can represent all three policy states. If 73/// passthrough is IMPLICIT_DEF (or NoReg), then represents "undefined". 74/// Otherwise, policy operand and tablegen flags drive the interpretation. 75/// 76//===----------------------------------------------------------------------===// 77 78def riscv_vmv_x_s : SDNode<"RISCVISD::VMV_X_S", 79 SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVec<1>, 80 SDTCisInt<1>]>>; 81def riscv_read_vlenb : SDNode<"RISCVISD::READ_VLENB", 82 SDTypeProfile<1, 0, [SDTCisVT<0, XLenVT>]>>; 83 84// Operand that is allowed to be a register other than X0, a 5 bit unsigned 85// immediate, or -1. -1 means VLMAX. This allows us to pick between VSETIVLI and 86// VSETVLI opcodes using the same pseudo instructions. 87def AVL : RegisterOperand<GPRNoX0> { 88 let OperandNamespace = "RISCVOp"; 89 let OperandType = "OPERAND_AVL"; 90} 91 92// X0 has special meaning for vsetvl/vsetvli. 93// rd | rs1 | AVL value | Effect on vl 94//-------------------------------------------------------------- 95// !X0 | X0 | VLMAX | Set vl to VLMAX 96// X0 | X0 | Value in vl | Keep current vl, just change vtype. 97def VLOp : ComplexPattern<XLenVT, 1, "selectVLOp">; 98 99def DecImm : SDNodeXForm<imm, [{ 100 return CurDAG->getTargetConstant(N->getSExtValue() - 1, SDLoc(N), 101 N->getValueType(0)); 102}]>; 103 104defvar TAIL_AGNOSTIC = 1; 105defvar TU_MU = 0; 106defvar TA_MA = 3; 107 108//===----------------------------------------------------------------------===// 109// Utilities. 110//===----------------------------------------------------------------------===// 111 112class PseudoToVInst<string PseudoInst> { 113 defvar AffixSubsts = [["Pseudo", ""], 114 ["_E64", ""], 115 ["_E32", ""], 116 ["_E16", ""], 117 ["_E8", ""], 118 ["FPR64", "F"], 119 ["FPR32", "F"], 120 ["FPR16", "F"], 121 ["_TIED", ""], 122 ["_MASK", ""], 123 ["_B64", ""], 124 ["_B32", ""], 125 ["_B16", ""], 126 ["_B8", ""], 127 ["_B4", ""], 128 ["_B2", ""], 129 ["_B1", ""], 130 ["_MF8", ""], 131 ["_MF4", ""], 132 ["_MF2", ""], 133 ["_M1", ""], 134 ["_M2", ""], 135 ["_M4", ""], 136 ["_M8", ""], 137 ["_SE", ""], 138 ["_RM", ""] 139 ]; 140 string VInst = !foldl(PseudoInst, AffixSubsts, Acc, AffixSubst, 141 !subst(AffixSubst[0], AffixSubst[1], Acc)); 142} 143 144// This class describes information associated to the LMUL. 145class LMULInfo<int lmul, int oct, VReg regclass, VReg wregclass, 146 VReg f2regclass, VReg f4regclass, VReg f8regclass, string mx> { 147 bits<3> value = lmul; // This is encoded as the vlmul field of vtype. 148 VReg vrclass = regclass; 149 VReg wvrclass = wregclass; 150 VReg f8vrclass = f8regclass; 151 VReg f4vrclass = f4regclass; 152 VReg f2vrclass = f2regclass; 153 string MX = mx; 154 int octuple = oct; 155} 156 157// Associate LMUL with tablegen records of register classes. 158def V_M1 : LMULInfo<0b000, 8, VR, VRM2, VR, VR, VR, "M1">; 159def V_M2 : LMULInfo<0b001, 16, VRM2, VRM4, VR, VR, VR, "M2">; 160def V_M4 : LMULInfo<0b010, 32, VRM4, VRM8, VRM2, VR, VR, "M4">; 161def V_M8 : LMULInfo<0b011, 64, VRM8,/*NoVReg*/VR, VRM4, VRM2, VR, "M8">; 162 163def V_MF8 : LMULInfo<0b101, 1, VR, VR,/*NoVReg*/VR,/*NoVReg*/VR,/*NoVReg*/VR, "MF8">; 164def V_MF4 : LMULInfo<0b110, 2, VR, VR, VR,/*NoVReg*/VR,/*NoVReg*/VR, "MF4">; 165def V_MF2 : LMULInfo<0b111, 4, VR, VR, VR, VR,/*NoVReg*/VR, "MF2">; 166 167// Used to iterate over all possible LMULs. 168defvar MxList = [V_MF8, V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8]; 169// For floating point which don't need MF8. 170defvar MxListF = [V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8]; 171 172// Used for widening and narrowing instructions as it doesn't contain M8. 173defvar MxListW = [V_MF8, V_MF4, V_MF2, V_M1, V_M2, V_M4]; 174// Used for widening reductions. It can contain M8 because wider operands are 175// scalar operands. 176defvar MxListWRed = MxList; 177// For floating point which don't need MF8. 178defvar MxListFW = [V_MF4, V_MF2, V_M1, V_M2, V_M4]; 179// For widening floating-point Reduction as it doesn't contain MF8. It can 180// contain M8 because wider operands are scalar operands. 181defvar MxListFWRed = [V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8]; 182 183// Use for zext/sext.vf2 184defvar MxListVF2 = [V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8]; 185 186// Use for zext/sext.vf4 and vector crypto instructions 187defvar MxListVF4 = [V_MF2, V_M1, V_M2, V_M4, V_M8]; 188 189// Use for zext/sext.vf8 190defvar MxListVF8 = [V_M1, V_M2, V_M4, V_M8]; 191 192class MxSet<int eew> { 193 list<LMULInfo> m = !cond(!eq(eew, 8) : [V_MF8, V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8], 194 !eq(eew, 16) : [V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8], 195 !eq(eew, 32) : [V_MF2, V_M1, V_M2, V_M4, V_M8], 196 !eq(eew, 64) : [V_M1, V_M2, V_M4, V_M8]); 197} 198 199class FPR_Info<int sew> { 200 RegisterClass fprclass = !cast<RegisterClass>("FPR" # sew); 201 string FX = "FPR" # sew; 202 int SEW = sew; 203 list<LMULInfo> MxList = MxSet<sew>.m; 204 list<LMULInfo> MxListFW = !if(!eq(sew, 64), [], !listremove(MxList, [V_M8])); 205} 206 207def SCALAR_F16 : FPR_Info<16>; 208def SCALAR_F32 : FPR_Info<32>; 209def SCALAR_F64 : FPR_Info<64>; 210 211// BF16 uses the same register class as F16. 212def SCALAR_BF16 : FPR_Info<16>; 213 214defvar FPList = [SCALAR_F16, SCALAR_F32, SCALAR_F64]; 215 216// Used for widening instructions. It excludes F64. 217defvar FPListW = [SCALAR_F16, SCALAR_F32]; 218 219// Used for widening bf16 instructions. 220defvar BFPListW = [SCALAR_BF16]; 221 222class NFSet<LMULInfo m> { 223 defvar lmul = !shl(1, m.value); 224 list<int> L = NFList<lmul>.L; 225} 226 227class octuple_to_str<int octuple> { 228 string ret = !cond(!eq(octuple, 1): "MF8", 229 !eq(octuple, 2): "MF4", 230 !eq(octuple, 4): "MF2", 231 !eq(octuple, 8): "M1", 232 !eq(octuple, 16): "M2", 233 !eq(octuple, 32): "M4", 234 !eq(octuple, 64): "M8"); 235} 236 237def VLOpFrag : PatFrag<(ops), (XLenVT (VLOp (XLenVT AVL:$vl)))>; 238 239// Output pattern for X0 used to represent VLMAX in the pseudo instructions. 240// We can't use X0 register becuase the AVL operands use GPRNoX0. 241// This must be kept in sync with RISCV::VLMaxSentinel. 242def VLMax : OutPatFrag<(ops), (XLenVT -1)>; 243 244def SelectFPImm : ComplexPattern<fAny, 1, "selectFPImm", [], [], 1>; 245 246// List of EEW. 247defvar EEWList = [8, 16, 32, 64]; 248 249class SegRegClass<LMULInfo m, int nf> { 250 VReg RC = !cast<VReg>("VRN" # nf # !cond(!eq(m.value, V_MF8.value): V_M1.MX, 251 !eq(m.value, V_MF4.value): V_M1.MX, 252 !eq(m.value, V_MF2.value): V_M1.MX, 253 true: m.MX)); 254} 255 256//===----------------------------------------------------------------------===// 257// Vector register and vector group type information. 258//===----------------------------------------------------------------------===// 259 260class VTypeInfo<ValueType Vec, ValueType Mas, int Sew, LMULInfo M, 261 ValueType Scal = XLenVT, RegisterClass ScalarReg = GPR> { 262 ValueType Vector = Vec; 263 ValueType Mask = Mas; 264 int SEW = Sew; 265 int Log2SEW = !logtwo(Sew); 266 VReg RegClass = M.vrclass; 267 LMULInfo LMul = M; 268 ValueType Scalar = Scal; 269 RegisterClass ScalarRegClass = ScalarReg; 270 // The pattern fragment which produces the AVL operand, representing the 271 // "natural" vector length for this type. For scalable vectors this is VLMax. 272 OutPatFrag AVL = VLMax; 273 274 string ScalarSuffix = !cond(!eq(Scal, XLenVT) : "X", 275 !eq(Scal, f16) : "FPR16", 276 !eq(Scal, bf16) : "FPR16", 277 !eq(Scal, f32) : "FPR32", 278 !eq(Scal, f64) : "FPR64"); 279} 280 281class GroupVTypeInfo<ValueType Vec, ValueType VecM1, ValueType Mas, int Sew, 282 LMULInfo M, ValueType Scal = XLenVT, 283 RegisterClass ScalarReg = GPR> 284 : VTypeInfo<Vec, Mas, Sew, M, Scal, ScalarReg> { 285 ValueType VectorM1 = VecM1; 286} 287 288defset list<VTypeInfo> AllVectors = { 289 defset list<VTypeInfo> AllIntegerVectors = { 290 defset list<VTypeInfo> NoGroupIntegerVectors = { 291 defset list<VTypeInfo> FractionalGroupIntegerVectors = { 292 def VI8MF8: VTypeInfo<vint8mf8_t, vbool64_t, 8, V_MF8>; 293 def VI8MF4: VTypeInfo<vint8mf4_t, vbool32_t, 8, V_MF4>; 294 def VI8MF2: VTypeInfo<vint8mf2_t, vbool16_t, 8, V_MF2>; 295 def VI16MF4: VTypeInfo<vint16mf4_t, vbool64_t, 16, V_MF4>; 296 def VI16MF2: VTypeInfo<vint16mf2_t, vbool32_t, 16, V_MF2>; 297 def VI32MF2: VTypeInfo<vint32mf2_t, vbool64_t, 32, V_MF2>; 298 } 299 def VI8M1: VTypeInfo<vint8m1_t, vbool8_t, 8, V_M1>; 300 def VI16M1: VTypeInfo<vint16m1_t, vbool16_t, 16, V_M1>; 301 def VI32M1: VTypeInfo<vint32m1_t, vbool32_t, 32, V_M1>; 302 def VI64M1: VTypeInfo<vint64m1_t, vbool64_t, 64, V_M1>; 303 } 304 defset list<GroupVTypeInfo> GroupIntegerVectors = { 305 def VI8M2: GroupVTypeInfo<vint8m2_t, vint8m1_t, vbool4_t, 8, V_M2>; 306 def VI8M4: GroupVTypeInfo<vint8m4_t, vint8m1_t, vbool2_t, 8, V_M4>; 307 def VI8M8: GroupVTypeInfo<vint8m8_t, vint8m1_t, vbool1_t, 8, V_M8>; 308 309 def VI16M2: GroupVTypeInfo<vint16m2_t, vint16m1_t, vbool8_t, 16, V_M2>; 310 def VI16M4: GroupVTypeInfo<vint16m4_t, vint16m1_t, vbool4_t, 16, V_M4>; 311 def VI16M8: GroupVTypeInfo<vint16m8_t, vint16m1_t, vbool2_t, 16, V_M8>; 312 313 def VI32M2: GroupVTypeInfo<vint32m2_t, vint32m1_t, vbool16_t, 32, V_M2>; 314 def VI32M4: GroupVTypeInfo<vint32m4_t, vint32m1_t, vbool8_t, 32, V_M4>; 315 def VI32M8: GroupVTypeInfo<vint32m8_t, vint32m1_t, vbool4_t, 32, V_M8>; 316 317 def VI64M2: GroupVTypeInfo<vint64m2_t, vint64m1_t, vbool32_t, 64, V_M2>; 318 def VI64M4: GroupVTypeInfo<vint64m4_t, vint64m1_t, vbool16_t, 64, V_M4>; 319 def VI64M8: GroupVTypeInfo<vint64m8_t, vint64m1_t, vbool8_t, 64, V_M8>; 320 } 321 } 322 323 defset list<VTypeInfo> AllFloatVectors = { 324 defset list<VTypeInfo> NoGroupFloatVectors = { 325 defset list<VTypeInfo> FractionalGroupFloatVectors = { 326 def VF16MF4: VTypeInfo<vfloat16mf4_t, vbool64_t, 16, V_MF4, f16, FPR16>; 327 def VF16MF2: VTypeInfo<vfloat16mf2_t, vbool32_t, 16, V_MF2, f16, FPR16>; 328 def VF32MF2: VTypeInfo<vfloat32mf2_t, vbool64_t, 32, V_MF2, f32, FPR32>; 329 } 330 def VF16M1: VTypeInfo<vfloat16m1_t, vbool16_t, 16, V_M1, f16, FPR16>; 331 def VF32M1: VTypeInfo<vfloat32m1_t, vbool32_t, 32, V_M1, f32, FPR32>; 332 def VF64M1: VTypeInfo<vfloat64m1_t, vbool64_t, 64, V_M1, f64, FPR64>; 333 } 334 335 defset list<GroupVTypeInfo> GroupFloatVectors = { 336 def VF16M2: GroupVTypeInfo<vfloat16m2_t, vfloat16m1_t, vbool8_t, 16, 337 V_M2, f16, FPR16>; 338 def VF16M4: GroupVTypeInfo<vfloat16m4_t, vfloat16m1_t, vbool4_t, 16, 339 V_M4, f16, FPR16>; 340 def VF16M8: GroupVTypeInfo<vfloat16m8_t, vfloat16m1_t, vbool2_t, 16, 341 V_M8, f16, FPR16>; 342 343 def VF32M2: GroupVTypeInfo<vfloat32m2_t, vfloat32m1_t, vbool16_t, 32, 344 V_M2, f32, FPR32>; 345 def VF32M4: GroupVTypeInfo<vfloat32m4_t, vfloat32m1_t, vbool8_t, 32, 346 V_M4, f32, FPR32>; 347 def VF32M8: GroupVTypeInfo<vfloat32m8_t, vfloat32m1_t, vbool4_t, 32, 348 V_M8, f32, FPR32>; 349 350 def VF64M2: GroupVTypeInfo<vfloat64m2_t, vfloat64m1_t, vbool32_t, 64, 351 V_M2, f64, FPR64>; 352 def VF64M4: GroupVTypeInfo<vfloat64m4_t, vfloat64m1_t, vbool16_t, 64, 353 V_M4, f64, FPR64>; 354 def VF64M8: GroupVTypeInfo<vfloat64m8_t, vfloat64m1_t, vbool8_t, 64, 355 V_M8, f64, FPR64>; 356 } 357 } 358} 359 360defset list<VTypeInfo> AllBFloatVectors = { 361 defset list<VTypeInfo> NoGroupBFloatVectors = { 362 defset list<VTypeInfo> FractionalGroupBFloatVectors = { 363 def VBF16MF4: VTypeInfo<vbfloat16mf4_t, vbool64_t, 16, V_MF4, bf16, FPR16>; 364 def VBF16MF2: VTypeInfo<vbfloat16mf2_t, vbool32_t, 16, V_MF2, bf16, FPR16>; 365 } 366 def VBF16M1: VTypeInfo<vbfloat16m1_t, vbool16_t, 16, V_M1, bf16, FPR16>; 367 } 368 369 defset list<GroupVTypeInfo> GroupBFloatVectors = { 370 def VBF16M2: GroupVTypeInfo<vbfloat16m2_t, vbfloat16m1_t, vbool8_t, 16, 371 V_M2, bf16, FPR16>; 372 def VBF16M4: GroupVTypeInfo<vbfloat16m4_t, vbfloat16m1_t, vbool4_t, 16, 373 V_M4, bf16, FPR16>; 374 def VBF16M8: GroupVTypeInfo<vbfloat16m8_t, vbfloat16m1_t, vbool2_t, 16, 375 V_M8, bf16, FPR16>; 376 } 377} 378 379// This functor is used to obtain the int vector type that has the same SEW and 380// multiplier as the input parameter type 381class GetIntVTypeInfo<VTypeInfo vti> { 382 // Equivalent integer vector type. Eg. 383 // VI8M1 → VI8M1 (identity) 384 // VF64M4 → VI64M4 385 VTypeInfo Vti = !cast<VTypeInfo>(!subst("VF", "VI", !cast<string>(vti))); 386} 387 388class MTypeInfo<ValueType Mas, LMULInfo M, string Bx> { 389 ValueType Mask = Mas; 390 // {SEW, VLMul} values set a valid VType to deal with this mask type. 391 // we assume SEW=1 and set corresponding LMUL. vsetvli insertion will 392 // look for SEW=1 to optimize based on surrounding instructions. 393 int SEW = 1; 394 int Log2SEW = 0; 395 LMULInfo LMul = M; 396 string BX = Bx; // Appendix of mask operations. 397 // The pattern fragment which produces the AVL operand, representing the 398 // "natural" vector length for this mask type. For scalable masks this is 399 // VLMax. 400 OutPatFrag AVL = VLMax; 401} 402 403defset list<MTypeInfo> AllMasks = { 404 // vbool<n>_t, <n> = SEW/LMUL, we assume SEW=8 and corresponding LMUL. 405 def : MTypeInfo<vbool64_t, V_MF8, "B1">; 406 def : MTypeInfo<vbool32_t, V_MF4, "B2">; 407 def : MTypeInfo<vbool16_t, V_MF2, "B4">; 408 def : MTypeInfo<vbool8_t, V_M1, "B8">; 409 def : MTypeInfo<vbool4_t, V_M2, "B16">; 410 def : MTypeInfo<vbool2_t, V_M4, "B32">; 411 def : MTypeInfo<vbool1_t, V_M8, "B64">; 412} 413 414class VTypeInfoToWide<VTypeInfo vti, VTypeInfo wti> { 415 VTypeInfo Vti = vti; 416 VTypeInfo Wti = wti; 417} 418 419class VTypeInfoToFraction<VTypeInfo vti, VTypeInfo fti> { 420 VTypeInfo Vti = vti; 421 VTypeInfo Fti = fti; 422} 423 424defset list<VTypeInfoToWide> AllWidenableIntVectors = { 425 def : VTypeInfoToWide<VI8MF8, VI16MF4>; 426 def : VTypeInfoToWide<VI8MF4, VI16MF2>; 427 def : VTypeInfoToWide<VI8MF2, VI16M1>; 428 def : VTypeInfoToWide<VI8M1, VI16M2>; 429 def : VTypeInfoToWide<VI8M2, VI16M4>; 430 def : VTypeInfoToWide<VI8M4, VI16M8>; 431 432 def : VTypeInfoToWide<VI16MF4, VI32MF2>; 433 def : VTypeInfoToWide<VI16MF2, VI32M1>; 434 def : VTypeInfoToWide<VI16M1, VI32M2>; 435 def : VTypeInfoToWide<VI16M2, VI32M4>; 436 def : VTypeInfoToWide<VI16M4, VI32M8>; 437 438 def : VTypeInfoToWide<VI32MF2, VI64M1>; 439 def : VTypeInfoToWide<VI32M1, VI64M2>; 440 def : VTypeInfoToWide<VI32M2, VI64M4>; 441 def : VTypeInfoToWide<VI32M4, VI64M8>; 442} 443 444defset list<VTypeInfoToWide> AllWidenableFloatVectors = { 445 def : VTypeInfoToWide<VF16MF4, VF32MF2>; 446 def : VTypeInfoToWide<VF16MF2, VF32M1>; 447 def : VTypeInfoToWide<VF16M1, VF32M2>; 448 def : VTypeInfoToWide<VF16M2, VF32M4>; 449 def : VTypeInfoToWide<VF16M4, VF32M8>; 450 451 def : VTypeInfoToWide<VF32MF2, VF64M1>; 452 def : VTypeInfoToWide<VF32M1, VF64M2>; 453 def : VTypeInfoToWide<VF32M2, VF64M4>; 454 def : VTypeInfoToWide<VF32M4, VF64M8>; 455} 456 457defset list<VTypeInfoToFraction> AllFractionableVF2IntVectors = { 458 def : VTypeInfoToFraction<VI16MF4, VI8MF8>; 459 def : VTypeInfoToFraction<VI16MF2, VI8MF4>; 460 def : VTypeInfoToFraction<VI16M1, VI8MF2>; 461 def : VTypeInfoToFraction<VI16M2, VI8M1>; 462 def : VTypeInfoToFraction<VI16M4, VI8M2>; 463 def : VTypeInfoToFraction<VI16M8, VI8M4>; 464 def : VTypeInfoToFraction<VI32MF2, VI16MF4>; 465 def : VTypeInfoToFraction<VI32M1, VI16MF2>; 466 def : VTypeInfoToFraction<VI32M2, VI16M1>; 467 def : VTypeInfoToFraction<VI32M4, VI16M2>; 468 def : VTypeInfoToFraction<VI32M8, VI16M4>; 469 def : VTypeInfoToFraction<VI64M1, VI32MF2>; 470 def : VTypeInfoToFraction<VI64M2, VI32M1>; 471 def : VTypeInfoToFraction<VI64M4, VI32M2>; 472 def : VTypeInfoToFraction<VI64M8, VI32M4>; 473} 474 475defset list<VTypeInfoToFraction> AllFractionableVF4IntVectors = { 476 def : VTypeInfoToFraction<VI32MF2, VI8MF8>; 477 def : VTypeInfoToFraction<VI32M1, VI8MF4>; 478 def : VTypeInfoToFraction<VI32M2, VI8MF2>; 479 def : VTypeInfoToFraction<VI32M4, VI8M1>; 480 def : VTypeInfoToFraction<VI32M8, VI8M2>; 481 def : VTypeInfoToFraction<VI64M1, VI16MF4>; 482 def : VTypeInfoToFraction<VI64M2, VI16MF2>; 483 def : VTypeInfoToFraction<VI64M4, VI16M1>; 484 def : VTypeInfoToFraction<VI64M8, VI16M2>; 485} 486 487defset list<VTypeInfoToFraction> AllFractionableVF8IntVectors = { 488 def : VTypeInfoToFraction<VI64M1, VI8MF8>; 489 def : VTypeInfoToFraction<VI64M2, VI8MF4>; 490 def : VTypeInfoToFraction<VI64M4, VI8MF2>; 491 def : VTypeInfoToFraction<VI64M8, VI8M1>; 492} 493 494defset list<VTypeInfoToWide> AllWidenableIntToFloatVectors = { 495 def : VTypeInfoToWide<VI8MF8, VF16MF4>; 496 def : VTypeInfoToWide<VI8MF4, VF16MF2>; 497 def : VTypeInfoToWide<VI8MF2, VF16M1>; 498 def : VTypeInfoToWide<VI8M1, VF16M2>; 499 def : VTypeInfoToWide<VI8M2, VF16M4>; 500 def : VTypeInfoToWide<VI8M4, VF16M8>; 501 502 def : VTypeInfoToWide<VI16MF4, VF32MF2>; 503 def : VTypeInfoToWide<VI16MF2, VF32M1>; 504 def : VTypeInfoToWide<VI16M1, VF32M2>; 505 def : VTypeInfoToWide<VI16M2, VF32M4>; 506 def : VTypeInfoToWide<VI16M4, VF32M8>; 507 508 def : VTypeInfoToWide<VI32MF2, VF64M1>; 509 def : VTypeInfoToWide<VI32M1, VF64M2>; 510 def : VTypeInfoToWide<VI32M2, VF64M4>; 511 def : VTypeInfoToWide<VI32M4, VF64M8>; 512} 513 514defset list<VTypeInfoToWide> AllWidenableBFloatToFloatVectors = { 515 def : VTypeInfoToWide<VBF16MF4, VF32MF2>; 516 def : VTypeInfoToWide<VBF16MF2, VF32M1>; 517 def : VTypeInfoToWide<VBF16M1, VF32M2>; 518 def : VTypeInfoToWide<VBF16M2, VF32M4>; 519 def : VTypeInfoToWide<VBF16M4, VF32M8>; 520} 521 522// This class holds the record of the RISCVVPseudoTable below. 523// This represents the information we need in codegen for each pseudo. 524// The definition should be consistent with `struct PseudoInfo` in 525// RISCVInstrInfo.h. 526class RISCVVPseudo { 527 Pseudo Pseudo = !cast<Pseudo>(NAME); // Used as a key. 528 Instruction BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst); 529 // SEW = 0 is used to denote that the Pseudo is not SEW specific (or unknown). 530 bits<8> SEW = 0; 531 bit NeedBeInPseudoTable = 1; 532} 533 534// The actual table. 535def RISCVVPseudosTable : GenericTable { 536 let FilterClass = "RISCVVPseudo"; 537 let FilterClassField = "NeedBeInPseudoTable"; 538 let CppTypeName = "PseudoInfo"; 539 let Fields = [ "Pseudo", "BaseInstr" ]; 540 let PrimaryKey = [ "Pseudo" ]; 541 let PrimaryKeyName = "getPseudoInfo"; 542 let PrimaryKeyEarlyOut = true; 543} 544 545def RISCVVInversePseudosTable : GenericTable { 546 let FilterClass = "RISCVVPseudo"; 547 let CppTypeName = "PseudoInfo"; 548 let Fields = [ "Pseudo", "BaseInstr", "VLMul", "SEW"]; 549 let PrimaryKey = [ "BaseInstr", "VLMul", "SEW"]; 550 let PrimaryKeyName = "getBaseInfo"; 551 let PrimaryKeyEarlyOut = true; 552} 553 554def RISCVVIntrinsicsTable : GenericTable { 555 let FilterClass = "RISCVVIntrinsic"; 556 let CppTypeName = "RISCVVIntrinsicInfo"; 557 let Fields = ["IntrinsicID", "ScalarOperand", "VLOperand"]; 558 let PrimaryKey = ["IntrinsicID"]; 559 let PrimaryKeyName = "getRISCVVIntrinsicInfo"; 560} 561 562// Describes the relation of a masked pseudo to the unmasked variants. 563// Note that all masked variants (in this table) have exactly one 564// unmasked variant. For all but compares, both the masked and 565// unmasked variant have a passthru and policy operand. For compares, 566// neither has a policy op, and only the masked version has a passthru. 567class RISCVMaskedPseudo<bits<4> MaskIdx, bit MaskAffectsRes=false> { 568 Pseudo MaskedPseudo = !cast<Pseudo>(NAME); 569 Pseudo UnmaskedPseudo = !cast<Pseudo>(!subst("_MASK", "", NAME)); 570 bits<4> MaskOpIdx = MaskIdx; 571 bit MaskAffectsResult = MaskAffectsRes; 572} 573 574def RISCVMaskedPseudosTable : GenericTable { 575 let FilterClass = "RISCVMaskedPseudo"; 576 let CppTypeName = "RISCVMaskedPseudoInfo"; 577 let Fields = ["MaskedPseudo", "UnmaskedPseudo", "MaskOpIdx", "MaskAffectsResult"]; 578 let PrimaryKey = ["MaskedPseudo"]; 579 let PrimaryKeyName = "getMaskedPseudoInfo"; 580} 581 582class RISCVVLE<bit M, bit Str, bit F, bits<3> S, bits<3> L> { 583 bits<1> Masked = M; 584 bits<1> Strided = Str; 585 bits<1> FF = F; 586 bits<3> Log2SEW = S; 587 bits<3> LMUL = L; 588 Pseudo Pseudo = !cast<Pseudo>(NAME); 589} 590 591def lookupMaskedIntrinsicByUnmasked : SearchIndex { 592 let Table = RISCVMaskedPseudosTable; 593 let Key = ["UnmaskedPseudo"]; 594} 595 596def RISCVVLETable : GenericTable { 597 let FilterClass = "RISCVVLE"; 598 let CppTypeName = "VLEPseudo"; 599 let Fields = ["Masked", "Strided", "FF", "Log2SEW", "LMUL", "Pseudo"]; 600 let PrimaryKey = ["Masked", "Strided", "FF", "Log2SEW", "LMUL"]; 601 let PrimaryKeyName = "getVLEPseudo"; 602} 603 604class RISCVVSE<bit M, bit Str, bits<3> S, bits<3> L> { 605 bits<1> Masked = M; 606 bits<1> Strided = Str; 607 bits<3> Log2SEW = S; 608 bits<3> LMUL = L; 609 Pseudo Pseudo = !cast<Pseudo>(NAME); 610} 611 612def RISCVVSETable : GenericTable { 613 let FilterClass = "RISCVVSE"; 614 let CppTypeName = "VSEPseudo"; 615 let Fields = ["Masked", "Strided", "Log2SEW", "LMUL", "Pseudo"]; 616 let PrimaryKey = ["Masked", "Strided", "Log2SEW", "LMUL"]; 617 let PrimaryKeyName = "getVSEPseudo"; 618} 619 620class RISCVVLX_VSX<bit M, bit O, bits<3> S, bits<3> L, bits<3> IL> { 621 bits<1> Masked = M; 622 bits<1> Ordered = O; 623 bits<3> Log2SEW = S; 624 bits<3> LMUL = L; 625 bits<3> IndexLMUL = IL; 626 Pseudo Pseudo = !cast<Pseudo>(NAME); 627} 628 629class RISCVVLX<bit M, bit O, bits<3> S, bits<3> L, bits<3> IL> : 630 RISCVVLX_VSX<M, O, S, L, IL>; 631class RISCVVSX<bit M, bit O, bits<3> S, bits<3> L, bits<3> IL> : 632 RISCVVLX_VSX<M, O, S, L, IL>; 633 634class RISCVVLX_VSXTable : GenericTable { 635 let CppTypeName = "VLX_VSXPseudo"; 636 let Fields = ["Masked", "Ordered", "Log2SEW", "LMUL", "IndexLMUL", "Pseudo"]; 637 let PrimaryKey = ["Masked", "Ordered", "Log2SEW", "LMUL", "IndexLMUL"]; 638} 639 640def RISCVVLXTable : RISCVVLX_VSXTable { 641 let FilterClass = "RISCVVLX"; 642 let PrimaryKeyName = "getVLXPseudo"; 643} 644 645def RISCVVSXTable : RISCVVLX_VSXTable { 646 let FilterClass = "RISCVVSX"; 647 let PrimaryKeyName = "getVSXPseudo"; 648} 649 650class RISCVVLSEG<bits<4> N, bit M, bit Str, bit F, bits<3> S, bits<3> L> { 651 bits<4> NF = N; 652 bits<1> Masked = M; 653 bits<1> Strided = Str; 654 bits<1> FF = F; 655 bits<3> Log2SEW = S; 656 bits<3> LMUL = L; 657 Pseudo Pseudo = !cast<Pseudo>(NAME); 658} 659 660def RISCVVLSEGTable : GenericTable { 661 let FilterClass = "RISCVVLSEG"; 662 let CppTypeName = "VLSEGPseudo"; 663 let Fields = ["NF", "Masked", "Strided", "FF", "Log2SEW", "LMUL", "Pseudo"]; 664 let PrimaryKey = ["NF", "Masked", "Strided", "FF", "Log2SEW", "LMUL"]; 665 let PrimaryKeyName = "getVLSEGPseudo"; 666} 667 668class RISCVVLXSEG<bits<4> N, bit M, bit O, bits<3> S, bits<3> L, bits<3> IL> { 669 bits<4> NF = N; 670 bits<1> Masked = M; 671 bits<1> Ordered = O; 672 bits<3> Log2SEW = S; 673 bits<3> LMUL = L; 674 bits<3> IndexLMUL = IL; 675 Pseudo Pseudo = !cast<Pseudo>(NAME); 676} 677 678def RISCVVLXSEGTable : GenericTable { 679 let FilterClass = "RISCVVLXSEG"; 680 let CppTypeName = "VLXSEGPseudo"; 681 let Fields = ["NF", "Masked", "Ordered", "Log2SEW", "LMUL", "IndexLMUL", "Pseudo"]; 682 let PrimaryKey = ["NF", "Masked", "Ordered", "Log2SEW", "LMUL", "IndexLMUL"]; 683 let PrimaryKeyName = "getVLXSEGPseudo"; 684} 685 686class RISCVVSSEG<bits<4> N, bit M, bit Str, bits<3> S, bits<3> L> { 687 bits<4> NF = N; 688 bits<1> Masked = M; 689 bits<1> Strided = Str; 690 bits<3> Log2SEW = S; 691 bits<3> LMUL = L; 692 Pseudo Pseudo = !cast<Pseudo>(NAME); 693} 694 695def RISCVVSSEGTable : GenericTable { 696 let FilterClass = "RISCVVSSEG"; 697 let CppTypeName = "VSSEGPseudo"; 698 let Fields = ["NF", "Masked", "Strided", "Log2SEW", "LMUL", "Pseudo"]; 699 let PrimaryKey = ["NF", "Masked", "Strided", "Log2SEW", "LMUL"]; 700 let PrimaryKeyName = "getVSSEGPseudo"; 701} 702 703class RISCVVSXSEG<bits<4> N, bit M, bit O, bits<3> S, bits<3> L, bits<3> IL> { 704 bits<4> NF = N; 705 bits<1> Masked = M; 706 bits<1> Ordered = O; 707 bits<3> Log2SEW = S; 708 bits<3> LMUL = L; 709 bits<3> IndexLMUL = IL; 710 Pseudo Pseudo = !cast<Pseudo>(NAME); 711} 712 713def RISCVVSXSEGTable : GenericTable { 714 let FilterClass = "RISCVVSXSEG"; 715 let CppTypeName = "VSXSEGPseudo"; 716 let Fields = ["NF", "Masked", "Ordered", "Log2SEW", "LMUL", "IndexLMUL", "Pseudo"]; 717 let PrimaryKey = ["NF", "Masked", "Ordered", "Log2SEW", "LMUL", "IndexLMUL"]; 718 let PrimaryKeyName = "getVSXSEGPseudo"; 719} 720 721//===----------------------------------------------------------------------===// 722// Helpers to define the different pseudo instructions. 723//===----------------------------------------------------------------------===// 724 725// The destination vector register group for a masked vector instruction cannot 726// overlap the source mask register (v0), unless the destination vector register 727// is being written with a mask value (e.g., comparisons) or the scalar result 728// of a reduction. 729class GetVRegNoV0<VReg VRegClass> { 730 VReg R = !cond(!eq(VRegClass, VR) : VRNoV0, 731 !eq(VRegClass, VRM2) : VRM2NoV0, 732 !eq(VRegClass, VRM4) : VRM4NoV0, 733 !eq(VRegClass, VRM8) : VRM8NoV0, 734 !eq(VRegClass, VRN2M1) : VRN2M1NoV0, 735 !eq(VRegClass, VRN2M2) : VRN2M2NoV0, 736 !eq(VRegClass, VRN2M4) : VRN2M4NoV0, 737 !eq(VRegClass, VRN3M1) : VRN3M1NoV0, 738 !eq(VRegClass, VRN3M2) : VRN3M2NoV0, 739 !eq(VRegClass, VRN4M1) : VRN4M1NoV0, 740 !eq(VRegClass, VRN4M2) : VRN4M2NoV0, 741 !eq(VRegClass, VRN5M1) : VRN5M1NoV0, 742 !eq(VRegClass, VRN6M1) : VRN6M1NoV0, 743 !eq(VRegClass, VRN7M1) : VRN7M1NoV0, 744 !eq(VRegClass, VRN8M1) : VRN8M1NoV0, 745 true : VRegClass); 746} 747 748class VPseudo<Instruction instr, LMULInfo m, dag outs, dag ins, int sew = 0> : 749 Pseudo<outs, ins, []>, RISCVVPseudo { 750 let BaseInstr = instr; 751 let VLMul = m.value; 752 let SEW = sew; 753} 754 755class GetVTypePredicates<VTypeInfo vti> { 756 list<Predicate> Predicates = !cond(!eq(vti.Scalar, f16) : [HasVInstructionsF16], 757 !eq(vti.Scalar, bf16) : [HasVInstructionsBF16], 758 !eq(vti.Scalar, f32) : [HasVInstructionsAnyF], 759 !eq(vti.Scalar, f64) : [HasVInstructionsF64], 760 !eq(vti.SEW, 64) : [HasVInstructionsI64], 761 true : [HasVInstructions]); 762} 763 764class VPseudoUSLoadNoMask<VReg RetClass, 765 int EEW> : 766 Pseudo<(outs RetClass:$rd), 767 (ins RetClass:$dest, GPRMem:$rs1, AVL:$vl, ixlenimm:$sew, 768 ixlenimm:$policy), []>, 769 RISCVVPseudo, 770 RISCVVLE</*Masked*/0, /*Strided*/0, /*FF*/0, !logtwo(EEW), VLMul> { 771 let mayLoad = 1; 772 let mayStore = 0; 773 let hasSideEffects = 0; 774 let HasVLOp = 1; 775 let HasSEWOp = 1; 776 let HasVecPolicyOp = 1; 777 let Constraints = "$rd = $dest"; 778} 779 780class VPseudoUSLoadMask<VReg RetClass, 781 int EEW> : 782 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 783 (ins GetVRegNoV0<RetClass>.R:$merge, 784 GPRMem:$rs1, 785 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 786 RISCVVPseudo, 787 RISCVVLE</*Masked*/1, /*Strided*/0, /*FF*/0, !logtwo(EEW), VLMul> { 788 let mayLoad = 1; 789 let mayStore = 0; 790 let hasSideEffects = 0; 791 let Constraints = "$rd = $merge"; 792 let HasVLOp = 1; 793 let HasSEWOp = 1; 794 let HasVecPolicyOp = 1; 795 let UsesMaskPolicy = 1; 796} 797 798class VPseudoUSLoadFFNoMask<VReg RetClass, 799 int EEW> : 800 Pseudo<(outs RetClass:$rd, GPR:$vl), 801 (ins RetClass:$dest, GPRMem:$rs1, AVL:$avl, 802 ixlenimm:$sew, ixlenimm:$policy), []>, 803 RISCVVPseudo, 804 RISCVVLE</*Masked*/0, /*Strided*/0, /*FF*/1, !logtwo(EEW), VLMul> { 805 let mayLoad = 1; 806 let mayStore = 0; 807 let hasSideEffects = 0; 808 let HasVLOp = 1; 809 let HasSEWOp = 1; 810 let HasVecPolicyOp = 1; 811 let Constraints = "$rd = $dest"; 812} 813 814class VPseudoUSLoadFFMask<VReg RetClass, 815 int EEW> : 816 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd, GPR:$vl), 817 (ins GetVRegNoV0<RetClass>.R:$merge, 818 GPRMem:$rs1, 819 VMaskOp:$vm, AVL:$avl, ixlenimm:$sew, ixlenimm:$policy), []>, 820 RISCVVPseudo, 821 RISCVVLE</*Masked*/1, /*Strided*/0, /*FF*/1, !logtwo(EEW), VLMul> { 822 let mayLoad = 1; 823 let mayStore = 0; 824 let hasSideEffects = 0; 825 let Constraints = "$rd = $merge"; 826 let HasVLOp = 1; 827 let HasSEWOp = 1; 828 let HasVecPolicyOp = 1; 829 let UsesMaskPolicy = 1; 830} 831 832class VPseudoSLoadNoMask<VReg RetClass, 833 int EEW> : 834 Pseudo<(outs RetClass:$rd), 835 (ins RetClass:$dest, GPRMem:$rs1, GPR:$rs2, AVL:$vl, 836 ixlenimm:$sew, ixlenimm:$policy), []>, 837 RISCVVPseudo, 838 RISCVVLE</*Masked*/0, /*Strided*/1, /*FF*/0, !logtwo(EEW), VLMul> { 839 let mayLoad = 1; 840 let mayStore = 0; 841 let hasSideEffects = 0; 842 let HasVLOp = 1; 843 let HasSEWOp = 1; 844 let HasVecPolicyOp = 1; 845 let Constraints = "$rd = $dest"; 846} 847 848class VPseudoSLoadMask<VReg RetClass, 849 int EEW> : 850 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 851 (ins GetVRegNoV0<RetClass>.R:$merge, 852 GPRMem:$rs1, GPR:$rs2, 853 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 854 RISCVVPseudo, 855 RISCVVLE</*Masked*/1, /*Strided*/1, /*FF*/0, !logtwo(EEW), VLMul> { 856 let mayLoad = 1; 857 let mayStore = 0; 858 let hasSideEffects = 0; 859 let Constraints = "$rd = $merge"; 860 let HasVLOp = 1; 861 let HasSEWOp = 1; 862 let HasVecPolicyOp = 1; 863 let UsesMaskPolicy = 1; 864} 865 866class VPseudoILoadNoMask<VReg RetClass, 867 VReg IdxClass, 868 int EEW, 869 bits<3> LMUL, 870 bit Ordered, 871 bit EarlyClobber, 872 int TargetConstraintType = 1> : 873 Pseudo<(outs RetClass:$rd), 874 (ins RetClass:$dest, GPRMem:$rs1, IdxClass:$rs2, AVL:$vl, 875 ixlenimm:$sew, ixlenimm:$policy), []>, 876 RISCVVPseudo, 877 RISCVVLX</*Masked*/0, Ordered, !logtwo(EEW), VLMul, LMUL> { 878 let mayLoad = 1; 879 let mayStore = 0; 880 let hasSideEffects = 0; 881 let HasVLOp = 1; 882 let HasSEWOp = 1; 883 let HasVecPolicyOp = 1; 884 let Constraints = !if(!eq(EarlyClobber, 1), "@earlyclobber $rd, $rd = $dest", "$rd = $dest"); 885 let TargetOverlapConstraintType = TargetConstraintType; 886} 887 888class VPseudoILoadMask<VReg RetClass, 889 VReg IdxClass, 890 int EEW, 891 bits<3> LMUL, 892 bit Ordered, 893 bit EarlyClobber, 894 int TargetConstraintType = 1> : 895 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 896 (ins GetVRegNoV0<RetClass>.R:$merge, 897 GPRMem:$rs1, IdxClass:$rs2, 898 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 899 RISCVVPseudo, 900 RISCVVLX</*Masked*/1, Ordered, !logtwo(EEW), VLMul, LMUL> { 901 let mayLoad = 1; 902 let mayStore = 0; 903 let hasSideEffects = 0; 904 let Constraints = !if(!eq(EarlyClobber, 1), "@earlyclobber $rd, $rd = $merge", "$rd = $merge"); 905 let TargetOverlapConstraintType = TargetConstraintType; 906 let HasVLOp = 1; 907 let HasSEWOp = 1; 908 let HasVecPolicyOp = 1; 909 let UsesMaskPolicy = 1; 910} 911 912class VPseudoUSStoreNoMask<VReg StClass, 913 int EEW> : 914 Pseudo<(outs), 915 (ins StClass:$rd, GPRMem:$rs1, AVL:$vl, ixlenimm:$sew), []>, 916 RISCVVPseudo, 917 RISCVVSE</*Masked*/0, /*Strided*/0, !logtwo(EEW), VLMul> { 918 let mayLoad = 0; 919 let mayStore = 1; 920 let hasSideEffects = 0; 921 let HasVLOp = 1; 922 let HasSEWOp = 1; 923} 924 925class VPseudoUSStoreMask<VReg StClass, 926 int EEW> : 927 Pseudo<(outs), 928 (ins StClass:$rd, GPRMem:$rs1, 929 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew), []>, 930 RISCVVPseudo, 931 RISCVVSE</*Masked*/1, /*Strided*/0, !logtwo(EEW), VLMul> { 932 let mayLoad = 0; 933 let mayStore = 1; 934 let hasSideEffects = 0; 935 let HasVLOp = 1; 936 let HasSEWOp = 1; 937} 938 939class VPseudoSStoreNoMask<VReg StClass, 940 int EEW> : 941 Pseudo<(outs), 942 (ins StClass:$rd, GPRMem:$rs1, GPR:$rs2, 943 AVL:$vl, ixlenimm:$sew), []>, 944 RISCVVPseudo, 945 RISCVVSE</*Masked*/0, /*Strided*/1, !logtwo(EEW), VLMul> { 946 let mayLoad = 0; 947 let mayStore = 1; 948 let hasSideEffects = 0; 949 let HasVLOp = 1; 950 let HasSEWOp = 1; 951} 952 953class VPseudoSStoreMask<VReg StClass, 954 int EEW> : 955 Pseudo<(outs), 956 (ins StClass:$rd, GPRMem:$rs1, GPR:$rs2, 957 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew), []>, 958 RISCVVPseudo, 959 RISCVVSE</*Masked*/1, /*Strided*/1, !logtwo(EEW), VLMul> { 960 let mayLoad = 0; 961 let mayStore = 1; 962 let hasSideEffects = 0; 963 let HasVLOp = 1; 964 let HasSEWOp = 1; 965} 966 967class VPseudoNullaryNoMask<VReg RegClass> : 968 Pseudo<(outs RegClass:$rd), 969 (ins RegClass:$merge, 970 AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 971 RISCVVPseudo { 972 let mayLoad = 0; 973 let mayStore = 0; 974 let hasSideEffects = 0; 975 let Constraints = "$rd = $merge"; 976 let HasVLOp = 1; 977 let HasSEWOp = 1; 978 let HasVecPolicyOp = 1; 979} 980 981class VPseudoNullaryMask<VReg RegClass> : 982 Pseudo<(outs GetVRegNoV0<RegClass>.R:$rd), 983 (ins GetVRegNoV0<RegClass>.R:$merge, 984 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 985 RISCVVPseudo { 986 let mayLoad = 0; 987 let mayStore = 0; 988 let hasSideEffects = 0; 989 let Constraints ="$rd = $merge"; 990 let HasVLOp = 1; 991 let HasSEWOp = 1; 992 let UsesMaskPolicy = 1; 993 let HasVecPolicyOp = 1; 994} 995 996// Nullary for pseudo instructions. They are expanded in 997// RISCVExpandPseudoInsts pass. 998class VPseudoNullaryPseudoM<string BaseInst> : 999 Pseudo<(outs VR:$rd), (ins AVL:$vl, ixlenimm:$sew), []>, 1000 RISCVVPseudo { 1001 let mayLoad = 0; 1002 let mayStore = 0; 1003 let hasSideEffects = 0; 1004 let HasVLOp = 1; 1005 let HasSEWOp = 1; 1006 // BaseInstr is not used in RISCVExpandPseudoInsts pass. 1007 // Just fill a corresponding real v-inst to pass tablegen check. 1008 let BaseInstr = !cast<Instruction>(BaseInst); 1009 // We exclude them from RISCVVPseudoTable. 1010 let NeedBeInPseudoTable = 0; 1011} 1012 1013class VPseudoUnaryNoMask<DAGOperand RetClass, 1014 DAGOperand OpClass, 1015 string Constraint = "", 1016 int TargetConstraintType = 1> : 1017 Pseudo<(outs RetClass:$rd), 1018 (ins RetClass:$merge, OpClass:$rs2, 1019 AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1020 RISCVVPseudo { 1021 let mayLoad = 0; 1022 let mayStore = 0; 1023 let hasSideEffects = 0; 1024 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1025 let TargetOverlapConstraintType = TargetConstraintType; 1026 let HasVLOp = 1; 1027 let HasSEWOp = 1; 1028 let HasVecPolicyOp = 1; 1029} 1030 1031class VPseudoUnaryNoMaskRoundingMode<DAGOperand RetClass, 1032 DAGOperand OpClass, 1033 string Constraint = "", 1034 int TargetConstraintType = 1> : 1035 Pseudo<(outs RetClass:$rd), 1036 (ins RetClass:$merge, OpClass:$rs2, ixlenimm:$rm, 1037 AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1038 RISCVVPseudo { 1039 let mayLoad = 0; 1040 let mayStore = 0; 1041 let hasSideEffects = 0; 1042 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1043 let TargetOverlapConstraintType = TargetConstraintType; 1044 let HasVLOp = 1; 1045 let HasSEWOp = 1; 1046 let HasVecPolicyOp = 1; 1047 let HasRoundModeOp = 1; 1048 let UsesVXRM = 0; 1049} 1050 1051class VPseudoUnaryMask<VReg RetClass, 1052 VReg OpClass, 1053 string Constraint = "", 1054 int TargetConstraintType = 1> : 1055 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 1056 (ins GetVRegNoV0<RetClass>.R:$merge, OpClass:$rs2, 1057 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1058 RISCVVPseudo { 1059 let mayLoad = 0; 1060 let mayStore = 0; 1061 let hasSideEffects = 0; 1062 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1063 let TargetOverlapConstraintType = TargetConstraintType; 1064 let HasVLOp = 1; 1065 let HasSEWOp = 1; 1066 let HasVecPolicyOp = 1; 1067 let UsesMaskPolicy = 1; 1068} 1069 1070class VPseudoUnaryMaskRoundingMode<VReg RetClass, 1071 VReg OpClass, 1072 string Constraint = "", 1073 int TargetConstraintType = 1> : 1074 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 1075 (ins GetVRegNoV0<RetClass>.R:$merge, OpClass:$rs2, 1076 VMaskOp:$vm, ixlenimm:$rm, 1077 AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1078 RISCVVPseudo { 1079 let mayLoad = 0; 1080 let mayStore = 0; 1081 let hasSideEffects = 0; 1082 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1083 let TargetOverlapConstraintType = TargetConstraintType; 1084 let HasVLOp = 1; 1085 let HasSEWOp = 1; 1086 let HasVecPolicyOp = 1; 1087 let UsesMaskPolicy = 1; 1088 let HasRoundModeOp = 1; 1089 let UsesVXRM = 0; 1090} 1091 1092class VPseudoUnaryMask_NoExcept<VReg RetClass, 1093 VReg OpClass, 1094 string Constraint = ""> : 1095 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 1096 (ins GetVRegNoV0<RetClass>.R:$merge, OpClass:$rs2, 1097 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []> { 1098 let mayLoad = 0; 1099 let mayStore = 0; 1100 let hasSideEffects = 0; 1101 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1102 let HasVLOp = 1; 1103 let HasSEWOp = 1; 1104 let HasVecPolicyOp = 1; 1105 let UsesMaskPolicy = 1; 1106 let usesCustomInserter = 1; 1107} 1108 1109class VPseudoUnaryNoMask_FRM<VReg RetClass, 1110 VReg OpClass, 1111 string Constraint = "", 1112 int TargetConstraintType = 1> : 1113 Pseudo<(outs RetClass:$rd), 1114 (ins RetClass:$merge, OpClass:$rs2, ixlenimm:$frm, 1115 AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1116 RISCVVPseudo { 1117 let mayLoad = 0; 1118 let mayStore = 0; 1119 let hasSideEffects = 0; 1120 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1121 let TargetOverlapConstraintType = TargetConstraintType; 1122 let HasVLOp = 1; 1123 let HasSEWOp = 1; 1124 let HasVecPolicyOp = 1; 1125 let HasRoundModeOp = 1; 1126} 1127 1128class VPseudoUnaryMask_FRM<VReg RetClass, 1129 VReg OpClass, 1130 string Constraint = "", 1131 int TargetConstraintType = 1> : 1132 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 1133 (ins GetVRegNoV0<RetClass>.R:$merge, OpClass:$rs2, 1134 VMaskOp:$vm, ixlenimm:$frm, 1135 AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1136 RISCVVPseudo { 1137 let mayLoad = 0; 1138 let mayStore = 0; 1139 let hasSideEffects = 0; 1140 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1141 let TargetOverlapConstraintType = TargetConstraintType; 1142 let HasVLOp = 1; 1143 let HasSEWOp = 1; 1144 let HasVecPolicyOp = 1; 1145 let UsesMaskPolicy = 1; 1146 let HasRoundModeOp = 1; 1147} 1148 1149class VPseudoUnaryNoMaskGPROut : 1150 Pseudo<(outs GPR:$rd), 1151 (ins VR:$rs2, AVL:$vl, ixlenimm:$sew), []>, 1152 RISCVVPseudo { 1153 let mayLoad = 0; 1154 let mayStore = 0; 1155 let hasSideEffects = 0; 1156 let HasVLOp = 1; 1157 let HasSEWOp = 1; 1158} 1159 1160class VPseudoUnaryMaskGPROut : 1161 Pseudo<(outs GPR:$rd), 1162 (ins VR:$rs1, VMaskOp:$vm, AVL:$vl, ixlenimm:$sew), []>, 1163 RISCVVPseudo { 1164 let mayLoad = 0; 1165 let mayStore = 0; 1166 let hasSideEffects = 0; 1167 let HasVLOp = 1; 1168 let HasSEWOp = 1; 1169} 1170 1171// Mask can be V0~V31 1172class VPseudoUnaryAnyMask<VReg RetClass, 1173 VReg Op1Class> : 1174 Pseudo<(outs RetClass:$rd), 1175 (ins RetClass:$merge, Op1Class:$rs2, 1176 VR:$vm, AVL:$vl, ixlenimm:$sew), []>, 1177 RISCVVPseudo { 1178 let mayLoad = 0; 1179 let mayStore = 0; 1180 let hasSideEffects = 0; 1181 let Constraints = "@earlyclobber $rd, $rd = $merge"; 1182 let HasVLOp = 1; 1183 let HasSEWOp = 1; 1184} 1185 1186class VPseudoBinaryNoMask<VReg RetClass, 1187 VReg Op1Class, 1188 DAGOperand Op2Class, 1189 string Constraint, 1190 int TargetConstraintType = 1> : 1191 Pseudo<(outs RetClass:$rd), 1192 (ins Op1Class:$rs2, Op2Class:$rs1, AVL:$vl, ixlenimm:$sew), []>, 1193 RISCVVPseudo { 1194 let mayLoad = 0; 1195 let mayStore = 0; 1196 let hasSideEffects = 0; 1197 let Constraints = Constraint; 1198 let TargetOverlapConstraintType = TargetConstraintType; 1199 let HasVLOp = 1; 1200 let HasSEWOp = 1; 1201} 1202 1203class VPseudoBinaryNoMaskTU<VReg RetClass, 1204 VReg Op1Class, 1205 DAGOperand Op2Class, 1206 string Constraint, 1207 int TargetConstraintType = 1> : 1208 Pseudo<(outs RetClass:$rd), 1209 (ins RetClass:$merge, Op1Class:$rs2, Op2Class:$rs1, AVL:$vl, 1210 ixlenimm:$sew, ixlenimm:$policy), []>, 1211 RISCVVPseudo { 1212 let mayLoad = 0; 1213 let mayStore = 0; 1214 let hasSideEffects = 0; 1215 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1216 let TargetOverlapConstraintType = TargetConstraintType; 1217 let HasVLOp = 1; 1218 let HasSEWOp = 1; 1219 let HasVecPolicyOp = 1; 1220} 1221 1222class VPseudoBinaryNoMaskRoundingMode<VReg RetClass, 1223 VReg Op1Class, 1224 DAGOperand Op2Class, 1225 string Constraint, 1226 int UsesVXRM_ = 1, 1227 int TargetConstraintType = 1> : 1228 Pseudo<(outs RetClass:$rd), 1229 (ins RetClass:$merge, Op1Class:$rs2, Op2Class:$rs1, ixlenimm:$rm, 1230 AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1231 RISCVVPseudo { 1232 let mayLoad = 0; 1233 let mayStore = 0; 1234 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1235 let TargetOverlapConstraintType = TargetConstraintType; 1236 let HasVLOp = 1; 1237 let HasSEWOp = 1; 1238 let HasVecPolicyOp = 1; 1239 let HasRoundModeOp = 1; 1240 let UsesVXRM = UsesVXRM_; 1241} 1242 1243class VPseudoBinaryMaskPolicyRoundingMode<VReg RetClass, 1244 RegisterClass Op1Class, 1245 DAGOperand Op2Class, 1246 string Constraint, 1247 int UsesVXRM_, 1248 int TargetConstraintType = 1> : 1249 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 1250 (ins GetVRegNoV0<RetClass>.R:$merge, 1251 Op1Class:$rs2, Op2Class:$rs1, 1252 VMaskOp:$vm, ixlenimm:$rm, AVL:$vl, 1253 ixlenimm:$sew, ixlenimm:$policy), []>, 1254 RISCVVPseudo { 1255 let mayLoad = 0; 1256 let mayStore = 0; 1257 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1258 let TargetOverlapConstraintType = TargetConstraintType; 1259 let HasVLOp = 1; 1260 let HasSEWOp = 1; 1261 let HasVecPolicyOp = 1; 1262 let UsesMaskPolicy = 1; 1263 let HasRoundModeOp = 1; 1264 let UsesVXRM = UsesVXRM_; 1265} 1266 1267// Special version of VPseudoBinaryNoMask where we pretend the first source is 1268// tied to the destination. 1269// This allows maskedoff and rs2 to be the same register. 1270class VPseudoTiedBinaryNoMask<VReg RetClass, 1271 DAGOperand Op2Class, 1272 string Constraint, 1273 int TargetConstraintType = 1> : 1274 Pseudo<(outs RetClass:$rd), 1275 (ins RetClass:$rs2, Op2Class:$rs1, AVL:$vl, ixlenimm:$sew, 1276 ixlenimm:$policy), []>, 1277 RISCVVPseudo { 1278 let mayLoad = 0; 1279 let mayStore = 0; 1280 let hasSideEffects = 0; 1281 let Constraints = !interleave([Constraint, "$rd = $rs2"], ","); 1282 let TargetOverlapConstraintType = TargetConstraintType; 1283 let HasVLOp = 1; 1284 let HasSEWOp = 1; 1285 let HasVecPolicyOp = 1; 1286 let isConvertibleToThreeAddress = 1; 1287 let IsTiedPseudo = 1; 1288} 1289 1290class VPseudoTiedBinaryNoMaskRoundingMode<VReg RetClass, 1291 DAGOperand Op2Class, 1292 string Constraint, 1293 int TargetConstraintType = 1> : 1294 Pseudo<(outs RetClass:$rd), 1295 (ins RetClass:$rs2, Op2Class:$rs1, 1296 ixlenimm:$rm, 1297 AVL:$vl, ixlenimm:$sew, 1298 ixlenimm:$policy), []>, 1299 RISCVVPseudo { 1300 let mayLoad = 0; 1301 let mayStore = 0; 1302 let hasSideEffects = 0; 1303 let Constraints = !interleave([Constraint, "$rd = $rs2"], ","); 1304 let TargetOverlapConstraintType = TargetConstraintType; 1305 let HasVLOp = 1; 1306 let HasSEWOp = 1; 1307 let HasVecPolicyOp = 1; 1308 let isConvertibleToThreeAddress = 1; 1309 let IsTiedPseudo = 1; 1310 let HasRoundModeOp = 1; 1311 let UsesVXRM = 0; 1312} 1313 1314class VPseudoIStoreNoMask<VReg StClass, VReg IdxClass, int EEW, bits<3> LMUL, 1315 bit Ordered>: 1316 Pseudo<(outs), 1317 (ins StClass:$rd, GPRMem:$rs1, IdxClass:$rs2, AVL:$vl, 1318 ixlenimm:$sew),[]>, 1319 RISCVVPseudo, 1320 RISCVVSX</*Masked*/0, Ordered, !logtwo(EEW), VLMul, LMUL> { 1321 let mayLoad = 0; 1322 let mayStore = 1; 1323 let hasSideEffects = 0; 1324 let HasVLOp = 1; 1325 let HasSEWOp = 1; 1326} 1327 1328class VPseudoIStoreMask<VReg StClass, VReg IdxClass, int EEW, bits<3> LMUL, 1329 bit Ordered>: 1330 Pseudo<(outs), 1331 (ins StClass:$rd, GPRMem:$rs1, IdxClass:$rs2, 1332 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew),[]>, 1333 RISCVVPseudo, 1334 RISCVVSX</*Masked*/1, Ordered, !logtwo(EEW), VLMul, LMUL> { 1335 let mayLoad = 0; 1336 let mayStore = 1; 1337 let hasSideEffects = 0; 1338 let HasVLOp = 1; 1339 let HasSEWOp = 1; 1340} 1341 1342class VPseudoBinaryMask<VReg RetClass, 1343 RegisterClass Op1Class, 1344 DAGOperand Op2Class, 1345 string Constraint> : 1346 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 1347 (ins GetVRegNoV0<RetClass>.R:$merge, 1348 Op1Class:$rs2, Op2Class:$rs1, 1349 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew), []>, 1350 RISCVVPseudo { 1351 let mayLoad = 0; 1352 let mayStore = 0; 1353 let hasSideEffects = 0; 1354 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1355 let HasVLOp = 1; 1356 let HasSEWOp = 1; 1357} 1358 1359class VPseudoBinaryMaskPolicy<VReg RetClass, 1360 RegisterClass Op1Class, 1361 DAGOperand Op2Class, 1362 string Constraint, 1363 int TargetConstraintType = 1> : 1364 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 1365 (ins GetVRegNoV0<RetClass>.R:$merge, 1366 Op1Class:$rs2, Op2Class:$rs1, 1367 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1368 RISCVVPseudo { 1369 let mayLoad = 0; 1370 let mayStore = 0; 1371 let hasSideEffects = 0; 1372 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1373 let TargetOverlapConstraintType = TargetConstraintType; 1374 let HasVLOp = 1; 1375 let HasSEWOp = 1; 1376 let HasVecPolicyOp = 1; 1377 let UsesMaskPolicy = 1; 1378} 1379 1380class VPseudoTernaryMaskPolicy<VReg RetClass, 1381 RegisterClass Op1Class, 1382 DAGOperand Op2Class, 1383 string Constraint> : 1384 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 1385 (ins GetVRegNoV0<RetClass>.R:$merge, 1386 Op1Class:$rs2, Op2Class:$rs1, 1387 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1388 RISCVVPseudo { 1389 let mayLoad = 0; 1390 let mayStore = 0; 1391 let hasSideEffects = 0; 1392 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1393 let HasVLOp = 1; 1394 let HasSEWOp = 1; 1395 let HasVecPolicyOp = 1; 1396} 1397 1398class VPseudoTernaryMaskPolicyRoundingMode<VReg RetClass, 1399 RegisterClass Op1Class, 1400 DAGOperand Op2Class, 1401 string Constraint> : 1402 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 1403 (ins GetVRegNoV0<RetClass>.R:$merge, 1404 Op1Class:$rs2, Op2Class:$rs1, 1405 VMaskOp:$vm, 1406 ixlenimm:$rm, 1407 AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1408 RISCVVPseudo { 1409 let mayLoad = 0; 1410 let mayStore = 0; 1411 let hasSideEffects = 0; 1412 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1413 let HasVLOp = 1; 1414 let HasSEWOp = 1; 1415 let HasVecPolicyOp = 1; 1416 let HasRoundModeOp = 1; 1417 let UsesVXRM = 0; 1418} 1419 1420// Like VPseudoBinaryNoMask, but output can be V0. 1421class VPseudoBinaryMOutNoMask<VReg RetClass, 1422 VReg Op1Class, 1423 DAGOperand Op2Class, 1424 string Constraint, 1425 int TargetConstraintType = 1> : 1426 Pseudo<(outs RetClass:$rd), 1427 (ins Op1Class:$rs2, Op2Class:$rs1, AVL:$vl, ixlenimm:$sew), []>, 1428 RISCVVPseudo { 1429 let mayLoad = 0; 1430 let mayStore = 0; 1431 let hasSideEffects = 0; 1432 let Constraints = Constraint; 1433 let TargetOverlapConstraintType = TargetConstraintType; 1434 let HasVLOp = 1; 1435 let HasSEWOp = 1; 1436} 1437 1438// Like VPseudoBinaryMask, but output can be V0. 1439class VPseudoBinaryMOutMask<VReg RetClass, 1440 RegisterClass Op1Class, 1441 DAGOperand Op2Class, 1442 string Constraint, 1443 int TargetConstraintType = 1> : 1444 Pseudo<(outs RetClass:$rd), 1445 (ins RetClass:$merge, 1446 Op1Class:$rs2, Op2Class:$rs1, 1447 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew), []>, 1448 RISCVVPseudo { 1449 let mayLoad = 0; 1450 let mayStore = 0; 1451 let hasSideEffects = 0; 1452 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1453 let TargetOverlapConstraintType = TargetConstraintType; 1454 let HasVLOp = 1; 1455 let HasSEWOp = 1; 1456 let UsesMaskPolicy = 1; 1457} 1458 1459// Special version of VPseudoBinaryMask where we pretend the first source is 1460// tied to the destination so we can workaround the earlyclobber constraint. 1461// This allows maskedoff and rs2 to be the same register. 1462class VPseudoTiedBinaryMask<VReg RetClass, 1463 DAGOperand Op2Class, 1464 string Constraint, 1465 int TargetConstraintType = 1> : 1466 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 1467 (ins GetVRegNoV0<RetClass>.R:$merge, 1468 Op2Class:$rs1, 1469 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1470 RISCVVPseudo { 1471 let mayLoad = 0; 1472 let mayStore = 0; 1473 let hasSideEffects = 0; 1474 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1475 let TargetOverlapConstraintType = TargetConstraintType; 1476 let HasVLOp = 1; 1477 let HasSEWOp = 1; 1478 let HasVecPolicyOp = 1; 1479 let UsesMaskPolicy = 1; 1480 let IsTiedPseudo = 1; 1481} 1482 1483class VPseudoTiedBinaryMaskRoundingMode<VReg RetClass, 1484 DAGOperand Op2Class, 1485 string Constraint, 1486 int TargetConstraintType = 1> : 1487 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 1488 (ins GetVRegNoV0<RetClass>.R:$merge, 1489 Op2Class:$rs1, 1490 VMaskOp:$vm, 1491 ixlenimm:$rm, 1492 AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1493 RISCVVPseudo { 1494 let mayLoad = 0; 1495 let mayStore = 0; 1496 let hasSideEffects = 0; 1497 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1498 let TargetOverlapConstraintType = TargetConstraintType; 1499 let HasVLOp = 1; 1500 let HasSEWOp = 1; 1501 let HasVecPolicyOp = 1; 1502 let UsesMaskPolicy = 1; 1503 let IsTiedPseudo = 1; 1504 let HasRoundModeOp = 1; 1505 let UsesVXRM = 0; 1506} 1507 1508class VPseudoBinaryCarryIn<VReg RetClass, 1509 VReg Op1Class, 1510 DAGOperand Op2Class, 1511 LMULInfo MInfo, 1512 bit CarryIn, 1513 string Constraint, 1514 int TargetConstraintType = 1> : 1515 Pseudo<(outs RetClass:$rd), 1516 !if(CarryIn, 1517 (ins Op1Class:$rs2, Op2Class:$rs1, 1518 VMV0:$carry, AVL:$vl, ixlenimm:$sew), 1519 (ins Op1Class:$rs2, Op2Class:$rs1, 1520 AVL:$vl, ixlenimm:$sew)), []>, 1521 RISCVVPseudo { 1522 let mayLoad = 0; 1523 let mayStore = 0; 1524 let hasSideEffects = 0; 1525 let Constraints = Constraint; 1526 let TargetOverlapConstraintType = TargetConstraintType; 1527 let HasVLOp = 1; 1528 let HasSEWOp = 1; 1529 let VLMul = MInfo.value; 1530} 1531 1532class VPseudoTiedBinaryCarryIn<VReg RetClass, 1533 VReg Op1Class, 1534 DAGOperand Op2Class, 1535 LMULInfo MInfo, 1536 bit CarryIn, 1537 string Constraint, 1538 int TargetConstraintType = 1> : 1539 Pseudo<(outs RetClass:$rd), 1540 !if(CarryIn, 1541 (ins RetClass:$merge, Op1Class:$rs2, Op2Class:$rs1, 1542 VMV0:$carry, AVL:$vl, ixlenimm:$sew), 1543 (ins RetClass:$merge, Op1Class:$rs2, Op2Class:$rs1, 1544 AVL:$vl, ixlenimm:$sew)), []>, 1545 RISCVVPseudo { 1546 let mayLoad = 0; 1547 let mayStore = 0; 1548 let hasSideEffects = 0; 1549 let Constraints = !interleave([Constraint, "$rd = $merge"], ","); 1550 let TargetOverlapConstraintType = TargetConstraintType; 1551 let HasVLOp = 1; 1552 let HasSEWOp = 1; 1553 let HasVecPolicyOp = 0; 1554 let VLMul = MInfo.value; 1555} 1556 1557class VPseudoTernaryNoMask<VReg RetClass, 1558 RegisterClass Op1Class, 1559 DAGOperand Op2Class, 1560 string Constraint> : 1561 Pseudo<(outs RetClass:$rd), 1562 (ins RetClass:$rs3, Op1Class:$rs1, Op2Class:$rs2, 1563 AVL:$vl, ixlenimm:$sew), []>, 1564 RISCVVPseudo { 1565 let mayLoad = 0; 1566 let mayStore = 0; 1567 let hasSideEffects = 0; 1568 let Constraints = !interleave([Constraint, "$rd = $rs3"], ","); 1569 let HasVLOp = 1; 1570 let HasSEWOp = 1; 1571} 1572 1573class VPseudoTernaryNoMaskWithPolicy<VReg RetClass, 1574 RegisterClass Op1Class, 1575 DAGOperand Op2Class, 1576 string Constraint, 1577 int TargetConstraintType = 1> : 1578 Pseudo<(outs RetClass:$rd), 1579 (ins RetClass:$rs3, Op1Class:$rs1, Op2Class:$rs2, 1580 AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1581 RISCVVPseudo { 1582 let mayLoad = 0; 1583 let mayStore = 0; 1584 let hasSideEffects = 0; 1585 let Constraints = !interleave([Constraint, "$rd = $rs3"], ","); 1586 let TargetOverlapConstraintType = TargetConstraintType; 1587 let HasVecPolicyOp = 1; 1588 let HasVLOp = 1; 1589 let HasSEWOp = 1; 1590} 1591 1592class VPseudoTernaryNoMaskWithPolicyRoundingMode<VReg RetClass, 1593 RegisterClass Op1Class, 1594 DAGOperand Op2Class, 1595 string Constraint, 1596 int TargetConstraintType = 1> : 1597 Pseudo<(outs RetClass:$rd), 1598 (ins RetClass:$rs3, Op1Class:$rs1, Op2Class:$rs2, 1599 ixlenimm:$rm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1600 RISCVVPseudo { 1601 let mayLoad = 0; 1602 let mayStore = 0; 1603 let hasSideEffects = 0; 1604 let Constraints = !interleave([Constraint, "$rd = $rs3"], ","); 1605 let TargetOverlapConstraintType = TargetConstraintType; 1606 let HasVecPolicyOp = 1; 1607 let HasVLOp = 1; 1608 let HasSEWOp = 1; 1609 let HasRoundModeOp = 1; 1610 let UsesVXRM = 0; 1611} 1612 1613class VPseudoUSSegLoadNoMask<VReg RetClass, 1614 int EEW, 1615 bits<4> NF> : 1616 Pseudo<(outs RetClass:$rd), 1617 (ins RetClass:$dest, GPRMem:$rs1, AVL:$vl, 1618 ixlenimm:$sew, ixlenimm:$policy), []>, 1619 RISCVVPseudo, 1620 RISCVVLSEG<NF, /*Masked*/0, /*Strided*/0, /*FF*/0, !logtwo(EEW), VLMul> { 1621 let mayLoad = 1; 1622 let mayStore = 0; 1623 let hasSideEffects = 0; 1624 let HasVLOp = 1; 1625 let HasSEWOp = 1; 1626 let HasVecPolicyOp = 1; 1627 let Constraints = "$rd = $dest"; 1628} 1629 1630class VPseudoUSSegLoadMask<VReg RetClass, 1631 int EEW, 1632 bits<4> NF> : 1633 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 1634 (ins GetVRegNoV0<RetClass>.R:$merge, GPRMem:$rs1, 1635 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>, 1636 RISCVVPseudo, 1637 RISCVVLSEG<NF, /*Masked*/1, /*Strided*/0, /*FF*/0, !logtwo(EEW), VLMul> { 1638 let mayLoad = 1; 1639 let mayStore = 0; 1640 let hasSideEffects = 0; 1641 let Constraints = "$rd = $merge"; 1642 let HasVLOp = 1; 1643 let HasSEWOp = 1; 1644 let HasVecPolicyOp = 1; 1645 let UsesMaskPolicy = 1; 1646} 1647 1648class VPseudoUSSegLoadFFNoMask<VReg RetClass, 1649 int EEW, 1650 bits<4> NF> : 1651 Pseudo<(outs RetClass:$rd, GPR:$vl), 1652 (ins RetClass:$dest, GPRMem:$rs1, AVL:$avl, 1653 ixlenimm:$sew, ixlenimm:$policy), []>, 1654 RISCVVPseudo, 1655 RISCVVLSEG<NF, /*Masked*/0, /*Strided*/0, /*FF*/1, !logtwo(EEW), VLMul> { 1656 let mayLoad = 1; 1657 let mayStore = 0; 1658 let hasSideEffects = 0; 1659 let HasVLOp = 1; 1660 let HasSEWOp = 1; 1661 let HasVecPolicyOp = 1; 1662 let Constraints = "$rd = $dest"; 1663} 1664 1665class VPseudoUSSegLoadFFMask<VReg RetClass, 1666 int EEW, 1667 bits<4> NF> : 1668 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd, GPR:$vl), 1669 (ins GetVRegNoV0<RetClass>.R:$merge, GPRMem:$rs1, 1670 VMaskOp:$vm, AVL:$avl, ixlenimm:$sew, ixlenimm:$policy), []>, 1671 RISCVVPseudo, 1672 RISCVVLSEG<NF, /*Masked*/1, /*Strided*/0, /*FF*/1, !logtwo(EEW), VLMul> { 1673 let mayLoad = 1; 1674 let mayStore = 0; 1675 let hasSideEffects = 0; 1676 let Constraints = "$rd = $merge"; 1677 let HasVLOp = 1; 1678 let HasSEWOp = 1; 1679 let HasVecPolicyOp = 1; 1680 let UsesMaskPolicy = 1; 1681} 1682 1683class VPseudoSSegLoadNoMask<VReg RetClass, 1684 int EEW, 1685 bits<4> NF> : 1686 Pseudo<(outs RetClass:$rd), 1687 (ins RetClass:$merge, GPRMem:$rs1, GPR:$offset, AVL:$vl, 1688 ixlenimm:$sew, ixlenimm:$policy), []>, 1689 RISCVVPseudo, 1690 RISCVVLSEG<NF, /*Masked*/0, /*Strided*/1, /*FF*/0, !logtwo(EEW), VLMul> { 1691 let mayLoad = 1; 1692 let mayStore = 0; 1693 let hasSideEffects = 0; 1694 let HasVLOp = 1; 1695 let HasSEWOp = 1; 1696 let HasVecPolicyOp = 1; 1697 let Constraints = "$rd = $merge"; 1698} 1699 1700class VPseudoSSegLoadMask<VReg RetClass, 1701 int EEW, 1702 bits<4> NF> : 1703 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 1704 (ins GetVRegNoV0<RetClass>.R:$merge, GPRMem:$rs1, 1705 GPR:$offset, VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, 1706 ixlenimm:$policy), []>, 1707 RISCVVPseudo, 1708 RISCVVLSEG<NF, /*Masked*/1, /*Strided*/1, /*FF*/0, !logtwo(EEW), VLMul> { 1709 let mayLoad = 1; 1710 let mayStore = 0; 1711 let hasSideEffects = 0; 1712 let Constraints = "$rd = $merge"; 1713 let HasVLOp = 1; 1714 let HasSEWOp = 1; 1715 let HasVecPolicyOp = 1; 1716 let UsesMaskPolicy = 1; 1717} 1718 1719class VPseudoISegLoadNoMask<VReg RetClass, 1720 VReg IdxClass, 1721 int EEW, 1722 bits<3> LMUL, 1723 bits<4> NF, 1724 bit Ordered> : 1725 Pseudo<(outs RetClass:$rd), 1726 (ins RetClass:$merge, GPRMem:$rs1, IdxClass:$offset, AVL:$vl, 1727 ixlenimm:$sew, ixlenimm:$policy), []>, 1728 RISCVVPseudo, 1729 RISCVVLXSEG<NF, /*Masked*/0, Ordered, !logtwo(EEW), VLMul, LMUL> { 1730 let mayLoad = 1; 1731 let mayStore = 0; 1732 let hasSideEffects = 0; 1733 // For vector indexed segment loads, the destination vector register groups 1734 // cannot overlap the source vector register group 1735 let Constraints = "@earlyclobber $rd, $rd = $merge"; 1736 let HasVLOp = 1; 1737 let HasSEWOp = 1; 1738 let HasVecPolicyOp = 1; 1739} 1740 1741class VPseudoISegLoadMask<VReg RetClass, 1742 VReg IdxClass, 1743 int EEW, 1744 bits<3> LMUL, 1745 bits<4> NF, 1746 bit Ordered> : 1747 Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd), 1748 (ins GetVRegNoV0<RetClass>.R:$merge, GPRMem:$rs1, 1749 IdxClass:$offset, VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, 1750 ixlenimm:$policy), []>, 1751 RISCVVPseudo, 1752 RISCVVLXSEG<NF, /*Masked*/1, Ordered, !logtwo(EEW), VLMul, LMUL> { 1753 let mayLoad = 1; 1754 let mayStore = 0; 1755 let hasSideEffects = 0; 1756 // For vector indexed segment loads, the destination vector register groups 1757 // cannot overlap the source vector register group 1758 let Constraints = "@earlyclobber $rd, $rd = $merge"; 1759 let HasVLOp = 1; 1760 let HasSEWOp = 1; 1761 let HasVecPolicyOp = 1; 1762 let UsesMaskPolicy = 1; 1763} 1764 1765class VPseudoUSSegStoreNoMask<VReg ValClass, 1766 int EEW, 1767 bits<4> NF> : 1768 Pseudo<(outs), 1769 (ins ValClass:$rd, GPRMem:$rs1, AVL:$vl, ixlenimm:$sew), []>, 1770 RISCVVPseudo, 1771 RISCVVSSEG<NF, /*Masked*/0, /*Strided*/0, !logtwo(EEW), VLMul> { 1772 let mayLoad = 0; 1773 let mayStore = 1; 1774 let hasSideEffects = 0; 1775 let HasVLOp = 1; 1776 let HasSEWOp = 1; 1777} 1778 1779class VPseudoUSSegStoreMask<VReg ValClass, 1780 int EEW, 1781 bits<4> NF> : 1782 Pseudo<(outs), 1783 (ins ValClass:$rd, GPRMem:$rs1, 1784 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew), []>, 1785 RISCVVPseudo, 1786 RISCVVSSEG<NF, /*Masked*/1, /*Strided*/0, !logtwo(EEW), VLMul> { 1787 let mayLoad = 0; 1788 let mayStore = 1; 1789 let hasSideEffects = 0; 1790 let HasVLOp = 1; 1791 let HasSEWOp = 1; 1792} 1793 1794class VPseudoSSegStoreNoMask<VReg ValClass, 1795 int EEW, 1796 bits<4> NF> : 1797 Pseudo<(outs), 1798 (ins ValClass:$rd, GPRMem:$rs1, GPR:$offset, 1799 AVL:$vl, ixlenimm:$sew), []>, 1800 RISCVVPseudo, 1801 RISCVVSSEG<NF, /*Masked*/0, /*Strided*/1, !logtwo(EEW), VLMul> { 1802 let mayLoad = 0; 1803 let mayStore = 1; 1804 let hasSideEffects = 0; 1805 let HasVLOp = 1; 1806 let HasSEWOp = 1; 1807} 1808 1809class VPseudoSSegStoreMask<VReg ValClass, 1810 int EEW, 1811 bits<4> NF> : 1812 Pseudo<(outs), 1813 (ins ValClass:$rd, GPRMem:$rs1, GPR: $offset, 1814 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew), []>, 1815 RISCVVPseudo, 1816 RISCVVSSEG<NF, /*Masked*/1, /*Strided*/1, !logtwo(EEW), VLMul> { 1817 let mayLoad = 0; 1818 let mayStore = 1; 1819 let hasSideEffects = 0; 1820 let HasVLOp = 1; 1821 let HasSEWOp = 1; 1822} 1823 1824class VPseudoISegStoreNoMask<VReg ValClass, 1825 VReg IdxClass, 1826 int EEW, 1827 bits<3> LMUL, 1828 bits<4> NF, 1829 bit Ordered> : 1830 Pseudo<(outs), 1831 (ins ValClass:$rd, GPRMem:$rs1, IdxClass: $index, 1832 AVL:$vl, ixlenimm:$sew), []>, 1833 RISCVVPseudo, 1834 RISCVVSXSEG<NF, /*Masked*/0, Ordered, !logtwo(EEW), VLMul, LMUL> { 1835 let mayLoad = 0; 1836 let mayStore = 1; 1837 let hasSideEffects = 0; 1838 let HasVLOp = 1; 1839 let HasSEWOp = 1; 1840} 1841 1842class VPseudoISegStoreMask<VReg ValClass, 1843 VReg IdxClass, 1844 int EEW, 1845 bits<3> LMUL, 1846 bits<4> NF, 1847 bit Ordered> : 1848 Pseudo<(outs), 1849 (ins ValClass:$rd, GPRMem:$rs1, IdxClass: $index, 1850 VMaskOp:$vm, AVL:$vl, ixlenimm:$sew), []>, 1851 RISCVVPseudo, 1852 RISCVVSXSEG<NF, /*Masked*/1, Ordered, !logtwo(EEW), VLMul, LMUL> { 1853 let mayLoad = 0; 1854 let mayStore = 1; 1855 let hasSideEffects = 0; 1856 let HasVLOp = 1; 1857 let HasSEWOp = 1; 1858} 1859 1860multiclass VPseudoUSLoad { 1861 foreach eew = EEWList in { 1862 foreach lmul = MxSet<eew>.m in { 1863 defvar LInfo = lmul.MX; 1864 defvar vreg = lmul.vrclass; 1865 let VLMul = lmul.value, SEW=eew in { 1866 def "E" # eew # "_V_" # LInfo : 1867 VPseudoUSLoadNoMask<vreg, eew>, 1868 VLESched<LInfo>; 1869 def "E" # eew # "_V_" # LInfo # "_MASK" : 1870 VPseudoUSLoadMask<vreg, eew>, 1871 RISCVMaskedPseudo<MaskIdx=2>, 1872 VLESched<LInfo>; 1873 } 1874 } 1875 } 1876} 1877 1878multiclass VPseudoFFLoad { 1879 foreach eew = EEWList in { 1880 foreach lmul = MxSet<eew>.m in { 1881 defvar LInfo = lmul.MX; 1882 defvar vreg = lmul.vrclass; 1883 let VLMul = lmul.value, SEW=eew in { 1884 def "E" # eew # "FF_V_" # LInfo: 1885 VPseudoUSLoadFFNoMask<vreg, eew>, 1886 VLFSched<LInfo>; 1887 def "E" # eew # "FF_V_" # LInfo # "_MASK": 1888 VPseudoUSLoadFFMask<vreg, eew>, 1889 RISCVMaskedPseudo<MaskIdx=2>, 1890 VLFSched<LInfo>; 1891 } 1892 } 1893 } 1894} 1895 1896multiclass VPseudoLoadMask { 1897 foreach mti = AllMasks in { 1898 defvar mx = mti.LMul.MX; 1899 defvar WriteVLDM_MX = !cast<SchedWrite>("WriteVLDM_" # mx); 1900 let VLMul = mti.LMul.value in { 1901 def "_V_" # mti.BX : VPseudoUSLoadNoMask<VR, EEW=1>, 1902 Sched<[WriteVLDM_MX, ReadVLDX]>; 1903 } 1904 } 1905} 1906 1907multiclass VPseudoSLoad { 1908 foreach eew = EEWList in { 1909 foreach lmul = MxSet<eew>.m in { 1910 defvar LInfo = lmul.MX; 1911 defvar vreg = lmul.vrclass; 1912 let VLMul = lmul.value, SEW=eew in { 1913 def "E" # eew # "_V_" # LInfo : VPseudoSLoadNoMask<vreg, eew>, 1914 VLSSched<eew, LInfo>; 1915 def "E" # eew # "_V_" # LInfo # "_MASK" : 1916 VPseudoSLoadMask<vreg, eew>, 1917 RISCVMaskedPseudo<MaskIdx=3>, 1918 VLSSched<eew, LInfo>; 1919 } 1920 } 1921 } 1922} 1923 1924multiclass VPseudoILoad<bit Ordered> { 1925 foreach idxEEW = EEWList in { 1926 foreach dataEEW = EEWList in { 1927 foreach dataEMUL = MxSet<dataEEW>.m in { 1928 defvar dataEMULOctuple = dataEMUL.octuple; 1929 // Calculate emul = eew * lmul / sew 1930 defvar idxEMULOctuple = 1931 !srl(!mul(idxEEW, dataEMULOctuple), !logtwo(dataEEW)); 1932 if !and(!ge(idxEMULOctuple, 1), !le(idxEMULOctuple, 64)) then { 1933 defvar DataLInfo = dataEMUL.MX; 1934 defvar IdxLInfo = octuple_to_str<idxEMULOctuple>.ret; 1935 defvar idxEMUL = !cast<LMULInfo>("V_" # IdxLInfo); 1936 defvar Vreg = dataEMUL.vrclass; 1937 defvar IdxVreg = idxEMUL.vrclass; 1938 defvar HasConstraint = !ne(dataEEW, idxEEW); 1939 defvar TypeConstraints = 1940 !if(!eq(dataEEW, idxEEW), 1, !if(!gt(dataEEW, idxEEW), !if(!ge(idxEMULOctuple, 8), 3, 1), 2)); 1941 let VLMul = dataEMUL.value in { 1942 def "EI" # idxEEW # "_V_" # IdxLInfo # "_" # DataLInfo : 1943 VPseudoILoadNoMask<Vreg, IdxVreg, idxEEW, idxEMUL.value, Ordered, HasConstraint, TypeConstraints>, 1944 VLXSched<dataEEW, Ordered, DataLInfo, IdxLInfo>; 1945 def "EI" # idxEEW # "_V_" # IdxLInfo # "_" # DataLInfo # "_MASK" : 1946 VPseudoILoadMask<Vreg, IdxVreg, idxEEW, idxEMUL.value, Ordered, HasConstraint, TypeConstraints>, 1947 RISCVMaskedPseudo<MaskIdx=3>, 1948 VLXSched<dataEEW, Ordered, DataLInfo, IdxLInfo>; 1949 } 1950 } 1951 } 1952 } 1953 } 1954} 1955 1956multiclass VPseudoUSStore { 1957 foreach eew = EEWList in { 1958 foreach lmul = MxSet<eew>.m in { 1959 defvar LInfo = lmul.MX; 1960 defvar vreg = lmul.vrclass; 1961 let VLMul = lmul.value, SEW=eew in { 1962 def "E" # eew # "_V_" # LInfo : VPseudoUSStoreNoMask<vreg, eew>, 1963 VSESched<LInfo>; 1964 def "E" # eew # "_V_" # LInfo # "_MASK" : VPseudoUSStoreMask<vreg, eew>, 1965 VSESched<LInfo>; 1966 } 1967 } 1968 } 1969} 1970 1971multiclass VPseudoStoreMask { 1972 foreach mti = AllMasks in { 1973 defvar mx = mti.LMul.MX; 1974 defvar WriteVSTM_MX = !cast<SchedWrite>("WriteVSTM_" # mx); 1975 let VLMul = mti.LMul.value in { 1976 def "_V_" # mti.BX : VPseudoUSStoreNoMask<VR, EEW=1>, 1977 Sched<[WriteVSTM_MX, ReadVSTX]>; 1978 } 1979 } 1980} 1981 1982multiclass VPseudoSStore { 1983 foreach eew = EEWList in { 1984 foreach lmul = MxSet<eew>.m in { 1985 defvar LInfo = lmul.MX; 1986 defvar vreg = lmul.vrclass; 1987 let VLMul = lmul.value, SEW=eew in { 1988 def "E" # eew # "_V_" # LInfo : VPseudoSStoreNoMask<vreg, eew>, 1989 VSSSched<eew, LInfo>; 1990 def "E" # eew # "_V_" # LInfo # "_MASK" : VPseudoSStoreMask<vreg, eew>, 1991 VSSSched<eew, LInfo>; 1992 } 1993 } 1994 } 1995} 1996 1997multiclass VPseudoIStore<bit Ordered> { 1998 foreach idxEEW = EEWList in { 1999 foreach dataEEW = EEWList in { 2000 foreach dataEMUL = MxSet<dataEEW>.m in { 2001 defvar dataEMULOctuple = dataEMUL.octuple; 2002 // Calculate emul = eew * lmul / sew 2003 defvar idxEMULOctuple = 2004 !srl(!mul(idxEEW, dataEMULOctuple), !logtwo(dataEEW)); 2005 if !and(!ge(idxEMULOctuple, 1), !le(idxEMULOctuple, 64)) then { 2006 defvar DataLInfo = dataEMUL.MX; 2007 defvar IdxLInfo = octuple_to_str<idxEMULOctuple>.ret; 2008 defvar idxEMUL = !cast<LMULInfo>("V_" # IdxLInfo); 2009 defvar Vreg = dataEMUL.vrclass; 2010 defvar IdxVreg = idxEMUL.vrclass; 2011 let VLMul = dataEMUL.value in { 2012 def "EI" # idxEEW # "_V_" # IdxLInfo # "_" # DataLInfo : 2013 VPseudoIStoreNoMask<Vreg, IdxVreg, idxEEW, idxEMUL.value, Ordered>, 2014 VSXSched<dataEEW, Ordered, DataLInfo, IdxLInfo>; 2015 def "EI" # idxEEW # "_V_" # IdxLInfo # "_" # DataLInfo # "_MASK" : 2016 VPseudoIStoreMask<Vreg, IdxVreg, idxEEW, idxEMUL.value, Ordered>, 2017 VSXSched<dataEEW, Ordered, DataLInfo, IdxLInfo>; 2018 } 2019 } 2020 } 2021 } 2022 } 2023} 2024 2025multiclass VPseudoVPOP_M { 2026 foreach mti = AllMasks in { 2027 defvar mx = mti.LMul.MX; 2028 let VLMul = mti.LMul.value in { 2029 def "_M_" # mti.BX : VPseudoUnaryNoMaskGPROut, 2030 SchedBinary<"WriteVMPopV", "ReadVMPopV", "ReadVMPopV", mx>; 2031 def "_M_" # mti.BX # "_MASK" : VPseudoUnaryMaskGPROut, 2032 SchedBinary<"WriteVMPopV", "ReadVMPopV", "ReadVMPopV", mx>; 2033 } 2034 } 2035} 2036 2037multiclass VPseudoV1ST_M { 2038 foreach mti = AllMasks in { 2039 defvar mx = mti.LMul.MX; 2040 let VLMul = mti.LMul.value in { 2041 def "_M_" #mti.BX : VPseudoUnaryNoMaskGPROut, 2042 SchedBinary<"WriteVMFFSV", "ReadVMFFSV", "ReadVMFFSV", mx>; 2043 def "_M_" # mti.BX # "_MASK" : VPseudoUnaryMaskGPROut, 2044 SchedBinary<"WriteVMFFSV", "ReadVMFFSV", "ReadVMFFSV", mx>; 2045 } 2046 } 2047} 2048 2049multiclass VPseudoVSFS_M { 2050 defvar constraint = "@earlyclobber $rd"; 2051 foreach mti = AllMasks in { 2052 defvar mx = mti.LMul.MX; 2053 let VLMul = mti.LMul.value in { 2054 def "_M_" # mti.BX : VPseudoUnaryNoMask<VR, VR, constraint>, 2055 SchedUnary<"WriteVMSFSV", "ReadVMSFSV", mx, 2056 forceMergeOpRead=true>; 2057 def "_M_" # mti.BX # "_MASK" : VPseudoUnaryMask<VR, VR, constraint>, 2058 SchedUnary<"WriteVMSFSV", "ReadVMSFSV", mx, 2059 forceMergeOpRead=true>; 2060 } 2061 } 2062} 2063 2064multiclass VPseudoVID_V { 2065 foreach m = MxList in { 2066 defvar mx = m.MX; 2067 let VLMul = m.value in { 2068 def "_V_" # mx : VPseudoNullaryNoMask<m.vrclass>, 2069 SchedNullary<"WriteVMIdxV", mx, forceMergeOpRead=true>; 2070 def "_V_" # mx # "_MASK" : VPseudoNullaryMask<m.vrclass>, 2071 RISCVMaskedPseudo<MaskIdx=1>, 2072 SchedNullary<"WriteVMIdxV", mx, 2073 forceMergeOpRead=true>; 2074 } 2075 } 2076} 2077 2078multiclass VPseudoNullaryPseudoM <string BaseInst> { 2079 foreach mti = AllMasks in { 2080 let VLMul = mti.LMul.value in { 2081 def "_M_" # mti.BX : VPseudoNullaryPseudoM<BaseInst # "_MM">, 2082 SchedBinary<"WriteVMALUV", "ReadVMALUV", "ReadVMALUV", mti.LMul.MX>; 2083 } 2084 } 2085} 2086 2087multiclass VPseudoVIOT_M { 2088 defvar constraint = "@earlyclobber $rd"; 2089 foreach m = MxList in { 2090 defvar mx = m.MX; 2091 let VLMul = m.value in { 2092 def "_" # mx : VPseudoUnaryNoMask<m.vrclass, VR, constraint>, 2093 SchedUnary<"WriteVMIotV", "ReadVMIotV", mx, 2094 forceMergeOpRead=true>; 2095 def "_" # mx # "_MASK" : VPseudoUnaryMask<m.vrclass, VR, constraint>, 2096 RISCVMaskedPseudo<MaskIdx=2, MaskAffectsRes=true>, 2097 SchedUnary<"WriteVMIotV", "ReadVMIotV", mx, 2098 forceMergeOpRead=true>; 2099 } 2100 } 2101} 2102 2103multiclass VPseudoVCPR_V { 2104 foreach m = MxList in { 2105 defvar mx = m.MX; 2106 defvar sews = SchedSEWSet<mx>.val; 2107 let VLMul = m.value in 2108 foreach e = sews in { 2109 defvar suffix = "_" # m.MX # "_E" # e; 2110 let SEW = e in 2111 def _VM # suffix 2112 : VPseudoUnaryAnyMask<m.vrclass, m.vrclass>, 2113 SchedBinary<"WriteVCompressV", "ReadVCompressV", "ReadVCompressV", 2114 mx, e>; 2115 } 2116 } 2117} 2118 2119multiclass VPseudoBinary<VReg RetClass, 2120 VReg Op1Class, 2121 DAGOperand Op2Class, 2122 LMULInfo MInfo, 2123 string Constraint = "", 2124 int sew = 0, 2125 int TargetConstraintType = 1> { 2126 let VLMul = MInfo.value, SEW=sew in { 2127 defvar suffix = !if(sew, "_" # MInfo.MX # "_E" # sew, "_" # MInfo.MX); 2128 def suffix : VPseudoBinaryNoMaskTU<RetClass, Op1Class, Op2Class, 2129 Constraint, TargetConstraintType>; 2130 def suffix # "_MASK" : VPseudoBinaryMaskPolicy<RetClass, Op1Class, Op2Class, 2131 Constraint, TargetConstraintType>, 2132 RISCVMaskedPseudo<MaskIdx=3>; 2133 } 2134} 2135 2136multiclass VPseudoBinaryNoMask<VReg RetClass, 2137 VReg Op1Class, 2138 DAGOperand Op2Class, 2139 LMULInfo MInfo, 2140 string Constraint = "", 2141 int sew = 0> { 2142 let VLMul = MInfo.value, SEW=sew in { 2143 defvar suffix = !if(sew, "_" # MInfo.MX # "_E" # sew, "_" # MInfo.MX); 2144 def suffix : VPseudoBinaryNoMaskTU<RetClass, Op1Class, Op2Class, 2145 Constraint>; 2146 } 2147} 2148 2149multiclass VPseudoBinaryRoundingMode<VReg RetClass, 2150 VReg Op1Class, 2151 DAGOperand Op2Class, 2152 LMULInfo MInfo, 2153 string Constraint = "", 2154 int sew = 0, 2155 int UsesVXRM = 1, 2156 int TargetConstraintType = 1> { 2157 let VLMul = MInfo.value, SEW=sew in { 2158 defvar suffix = !if(sew, "_" # MInfo.MX # "_E" # sew, "_" # MInfo.MX); 2159 def suffix : VPseudoBinaryNoMaskRoundingMode<RetClass, Op1Class, Op2Class, 2160 Constraint, UsesVXRM, 2161 TargetConstraintType>; 2162 def suffix # "_MASK" : VPseudoBinaryMaskPolicyRoundingMode<RetClass, 2163 Op1Class, 2164 Op2Class, 2165 Constraint, 2166 UsesVXRM, 2167 TargetConstraintType>, 2168 RISCVMaskedPseudo<MaskIdx=3>; 2169 } 2170} 2171 2172 2173multiclass VPseudoBinaryM<VReg RetClass, 2174 VReg Op1Class, 2175 DAGOperand Op2Class, 2176 LMULInfo MInfo, 2177 string Constraint = "", 2178 int TargetConstraintType = 1> { 2179 let VLMul = MInfo.value in { 2180 def "_" # MInfo.MX : VPseudoBinaryMOutNoMask<RetClass, Op1Class, Op2Class, 2181 Constraint, TargetConstraintType>; 2182 let ForceTailAgnostic = true in 2183 def "_" # MInfo.MX # "_MASK" : VPseudoBinaryMOutMask<RetClass, Op1Class, 2184 Op2Class, Constraint, TargetConstraintType>, 2185 RISCVMaskedPseudo<MaskIdx=3>; 2186 } 2187} 2188 2189multiclass VPseudoBinaryEmul<VReg RetClass, 2190 VReg Op1Class, 2191 DAGOperand Op2Class, 2192 LMULInfo lmul, 2193 LMULInfo emul, 2194 string Constraint = "", 2195 int sew = 0> { 2196 let VLMul = lmul.value, SEW=sew in { 2197 defvar suffix = !if(sew, "_" # lmul.MX # "_E" # sew, "_" # lmul.MX); 2198 def suffix # "_" # emul.MX : VPseudoBinaryNoMaskTU<RetClass, Op1Class, Op2Class, 2199 Constraint>; 2200 def suffix # "_" # emul.MX # "_MASK" : VPseudoBinaryMaskPolicy<RetClass, Op1Class, Op2Class, 2201 Constraint>, 2202 RISCVMaskedPseudo<MaskIdx=3>; 2203 } 2204} 2205 2206multiclass VPseudoTiedBinary<VReg RetClass, 2207 DAGOperand Op2Class, 2208 LMULInfo MInfo, 2209 string Constraint = "", 2210 int TargetConstraintType = 1> { 2211 let VLMul = MInfo.value in { 2212 def "_" # MInfo.MX # "_TIED": VPseudoTiedBinaryNoMask<RetClass, Op2Class, 2213 Constraint, TargetConstraintType>; 2214 def "_" # MInfo.MX # "_MASK_TIED" : VPseudoTiedBinaryMask<RetClass, Op2Class, 2215 Constraint, TargetConstraintType>; 2216 } 2217} 2218 2219multiclass VPseudoTiedBinaryRoundingMode<VReg RetClass, 2220 DAGOperand Op2Class, 2221 LMULInfo MInfo, 2222 string Constraint = "", 2223 int TargetConstraintType = 1> { 2224 let VLMul = MInfo.value in { 2225 def "_" # MInfo.MX # "_TIED": 2226 VPseudoTiedBinaryNoMaskRoundingMode<RetClass, Op2Class, Constraint, TargetConstraintType>; 2227 def "_" # MInfo.MX # "_MASK_TIED" : 2228 VPseudoTiedBinaryMaskRoundingMode<RetClass, Op2Class, Constraint, TargetConstraintType>; 2229 } 2230} 2231 2232 2233multiclass VPseudoBinaryV_VV<LMULInfo m, string Constraint = "", int sew = 0> { 2234 defm _VV : VPseudoBinary<m.vrclass, m.vrclass, m.vrclass, m, Constraint, sew>; 2235} 2236 2237multiclass VPseudoBinaryV_VV_RM<LMULInfo m, string Constraint = ""> { 2238 defm _VV : VPseudoBinaryRoundingMode<m.vrclass, m.vrclass, m.vrclass, m, Constraint>; 2239} 2240 2241// Similar to VPseudoBinaryV_VV, but uses MxListF. 2242multiclass VPseudoBinaryFV_VV<LMULInfo m, string Constraint = "", int sew = 0> { 2243 defm _VV : VPseudoBinary<m.vrclass, m.vrclass, m.vrclass, m, Constraint, sew>; 2244} 2245 2246multiclass VPseudoBinaryFV_VV_RM<LMULInfo m, string Constraint = "", int sew = 0> { 2247 defm _VV : VPseudoBinaryRoundingMode<m.vrclass, m.vrclass, m.vrclass, m, 2248 Constraint, sew, 2249 UsesVXRM=0>; 2250} 2251 2252multiclass VPseudoVGTR_VV_EEW<int eew, string Constraint = ""> { 2253 foreach m = MxList in { 2254 defvar mx = m.MX; 2255 foreach sew = EEWList in { 2256 defvar dataEMULOctuple = m.octuple; 2257 // emul = lmul * eew / sew 2258 defvar idxEMULOctuple = !srl(!mul(dataEMULOctuple, eew), !logtwo(sew)); 2259 if !and(!ge(idxEMULOctuple, 1), !le(idxEMULOctuple, 64)) then { 2260 defvar emulMX = octuple_to_str<idxEMULOctuple>.ret; 2261 defvar emul = !cast<LMULInfo>("V_" # emulMX); 2262 defvar sews = SchedSEWSet<mx>.val; 2263 foreach e = sews in { 2264 defm _VV 2265 : VPseudoBinaryEmul<m.vrclass, m.vrclass, emul.vrclass, m, emul, 2266 Constraint, e>, 2267 SchedBinary<"WriteVRGatherVV", "ReadVRGatherVV_data", 2268 "ReadVRGatherVV_index", mx, e, forceMergeOpRead=true>; 2269 } 2270 } 2271 } 2272 } 2273} 2274 2275multiclass VPseudoBinaryV_VX<LMULInfo m, string Constraint = "", int sew = 0> { 2276 defm "_VX" : VPseudoBinary<m.vrclass, m.vrclass, GPR, m, Constraint, sew>; 2277} 2278 2279multiclass VPseudoBinaryV_VX_RM<LMULInfo m, string Constraint = ""> { 2280 defm "_VX" : VPseudoBinaryRoundingMode<m.vrclass, m.vrclass, GPR, m, Constraint>; 2281} 2282 2283multiclass VPseudoVSLD1_VX<string Constraint = ""> { 2284 foreach m = MxList in { 2285 defm "_VX" : VPseudoBinary<m.vrclass, m.vrclass, GPR, m, Constraint>, 2286 SchedBinary<"WriteVISlide1X", "ReadVISlideV", "ReadVISlideX", 2287 m.MX, forceMergeOpRead=true>; 2288 } 2289} 2290 2291multiclass VPseudoBinaryV_VF<LMULInfo m, FPR_Info f, string Constraint = "", int sew = 0> { 2292 defm "_V" # f.FX : VPseudoBinary<m.vrclass, m.vrclass, 2293 f.fprclass, m, Constraint, sew>; 2294} 2295 2296multiclass VPseudoBinaryV_VF_RM<LMULInfo m, FPR_Info f, string Constraint = "", int sew = 0> { 2297 defm "_V" # f.FX : VPseudoBinaryRoundingMode<m.vrclass, m.vrclass, 2298 f.fprclass, m, Constraint, sew, 2299 UsesVXRM=0>; 2300} 2301 2302multiclass VPseudoVSLD1_VF<string Constraint = ""> { 2303 foreach f = FPList in { 2304 foreach m = f.MxList in { 2305 defm "_V" #f.FX 2306 : VPseudoBinary<m.vrclass, m.vrclass, f.fprclass, m, Constraint>, 2307 SchedBinary<"WriteVFSlide1F", "ReadVFSlideV", "ReadVFSlideF", m.MX, 2308 forceMergeOpRead=true>; 2309 } 2310 } 2311} 2312 2313multiclass VPseudoBinaryV_VI<Operand ImmType = simm5, LMULInfo m, string Constraint = ""> { 2314 defm _VI : VPseudoBinary<m.vrclass, m.vrclass, ImmType, m, Constraint>; 2315} 2316 2317multiclass VPseudoBinaryV_VI_RM<Operand ImmType = simm5, LMULInfo m, string Constraint = ""> { 2318 defm _VI : VPseudoBinaryRoundingMode<m.vrclass, m.vrclass, ImmType, m, Constraint>; 2319} 2320 2321multiclass VPseudoVALU_MM<bit Commutable = 0> { 2322 foreach m = MxList in { 2323 defvar mx = m.MX; 2324 let VLMul = m.value, isCommutable = Commutable in { 2325 def "_MM_" # mx : VPseudoBinaryNoMask<VR, VR, VR, "">, 2326 SchedBinary<"WriteVMALUV", "ReadVMALUV", "ReadVMALUV", mx>; 2327 } 2328 } 2329} 2330 2331// We use earlyclobber here due to 2332// * The destination EEW is smaller than the source EEW and the overlap is 2333// in the lowest-numbered part of the source register group is legal. 2334// Otherwise, it is illegal. 2335// * The destination EEW is greater than the source EEW, the source EMUL is 2336// at least 1, and the overlap is in the highest-numbered part of the 2337// destination register group is legal. Otherwise, it is illegal. 2338multiclass VPseudoBinaryW_VV<LMULInfo m> { 2339 defm _VV : VPseudoBinary<m.wvrclass, m.vrclass, m.vrclass, m, 2340 "@earlyclobber $rd", TargetConstraintType=3>; 2341} 2342 2343multiclass VPseudoBinaryW_VV_RM<LMULInfo m> { 2344 defm _VV : VPseudoBinaryRoundingMode<m.wvrclass, m.vrclass, m.vrclass, m, 2345 "@earlyclobber $rd", UsesVXRM=0, 2346 TargetConstraintType=3>; 2347} 2348 2349multiclass VPseudoBinaryW_VX<LMULInfo m> { 2350 defm "_VX" : VPseudoBinary<m.wvrclass, m.vrclass, GPR, m, 2351 "@earlyclobber $rd", TargetConstraintType=3>; 2352} 2353 2354multiclass VPseudoBinaryW_VI<Operand ImmType, LMULInfo m> { 2355 defm "_VI" : VPseudoBinary<m.wvrclass, m.vrclass, ImmType, m, 2356 "@earlyclobber $rd", TargetConstraintType=3>; 2357} 2358 2359multiclass VPseudoBinaryW_VF<LMULInfo m, FPR_Info f> { 2360 defm "_V" # f.FX : VPseudoBinary<m.wvrclass, m.vrclass, 2361 f.fprclass, m, 2362 "@earlyclobber $rd">; 2363} 2364 2365multiclass VPseudoBinaryW_VF_RM<LMULInfo m, FPR_Info f> { 2366 defm "_V" # f.FX : VPseudoBinaryRoundingMode<m.wvrclass, m.vrclass, 2367 f.fprclass, m, 2368 "@earlyclobber $rd", 2369 UsesVXRM=0, 2370 TargetConstraintType=3>; 2371} 2372 2373multiclass VPseudoBinaryW_WV<LMULInfo m> { 2374 defm _WV : VPseudoBinary<m.wvrclass, m.wvrclass, m.vrclass, m, 2375 "@earlyclobber $rd", TargetConstraintType=3>; 2376 defm _WV : VPseudoTiedBinary<m.wvrclass, m.vrclass, m, 2377 "@earlyclobber $rd", TargetConstraintType=3>; 2378} 2379 2380multiclass VPseudoBinaryW_WV_RM<LMULInfo m> { 2381 defm _WV : VPseudoBinaryRoundingMode<m.wvrclass, m.wvrclass, m.vrclass, m, 2382 "@earlyclobber $rd", UsesVXRM=0, TargetConstraintType=3>; 2383 defm _WV : VPseudoTiedBinaryRoundingMode<m.wvrclass, m.vrclass, m, 2384 "@earlyclobber $rd", TargetConstraintType=3>; 2385} 2386 2387multiclass VPseudoBinaryW_WX<LMULInfo m> { 2388 defm "_WX" : VPseudoBinary<m.wvrclass, m.wvrclass, GPR, m, /*Constraint*/ "", TargetConstraintType=3>; 2389} 2390 2391multiclass VPseudoBinaryW_WF<LMULInfo m, FPR_Info f, int TargetConstraintType = 1> { 2392 defm "_W" # f.FX : VPseudoBinary<m.wvrclass, m.wvrclass, 2393 f.fprclass, m, /*Constraint*/ "", TargetConstraintType=TargetConstraintType>; 2394} 2395 2396multiclass VPseudoBinaryW_WF_RM<LMULInfo m, FPR_Info f> { 2397 defm "_W" # f.FX : VPseudoBinaryRoundingMode<m.wvrclass, m.wvrclass, 2398 f.fprclass, m, 2399 Constraint="", 2400 sew=0, 2401 UsesVXRM=0, 2402 TargetConstraintType=3>; 2403} 2404 2405// Narrowing instructions like vnsrl/vnsra/vnclip(u) don't need @earlyclobber 2406// if the source and destination have an LMUL<=1. This matches this overlap 2407// exception from the spec. 2408// "The destination EEW is smaller than the source EEW and the overlap is in the 2409// lowest-numbered part of the source register group." 2410multiclass VPseudoBinaryV_WV<LMULInfo m, int TargetConstraintType = 1> { 2411 defm _WV : VPseudoBinary<m.vrclass, m.wvrclass, m.vrclass, m, 2412 !if(!ge(m.octuple, 8), "@earlyclobber $rd", ""), TargetConstraintType=TargetConstraintType>; 2413} 2414 2415multiclass VPseudoBinaryV_WV_RM<LMULInfo m> { 2416 defm _WV : VPseudoBinaryRoundingMode<m.vrclass, m.wvrclass, m.vrclass, m, 2417 !if(!ge(m.octuple, 8), 2418 "@earlyclobber $rd", "")>; 2419} 2420 2421multiclass VPseudoBinaryV_WX<LMULInfo m, int TargetConstraintType = 1> { 2422 defm _WX : VPseudoBinary<m.vrclass, m.wvrclass, GPR, m, 2423 !if(!ge(m.octuple, 8), "@earlyclobber $rd", ""), TargetConstraintType=TargetConstraintType>; 2424} 2425 2426multiclass VPseudoBinaryV_WX_RM<LMULInfo m> { 2427 defm _WX : VPseudoBinaryRoundingMode<m.vrclass, m.wvrclass, GPR, m, 2428 !if(!ge(m.octuple, 8), 2429 "@earlyclobber $rd", "")>; 2430} 2431 2432multiclass VPseudoBinaryV_WI<LMULInfo m, int TargetConstraintType = 1> { 2433 defm _WI : VPseudoBinary<m.vrclass, m.wvrclass, uimm5, m, 2434 !if(!ge(m.octuple, 8), "@earlyclobber $rd", ""), TargetConstraintType=TargetConstraintType>; 2435} 2436 2437multiclass VPseudoBinaryV_WI_RM<LMULInfo m> { 2438 defm _WI : VPseudoBinaryRoundingMode<m.vrclass, m.wvrclass, uimm5, m, 2439 !if(!ge(m.octuple, 8), 2440 "@earlyclobber $rd", "")>; 2441} 2442 2443// For vadc and vsbc, the instruction encoding is reserved if the destination 2444// vector register is v0. 2445// For vadc and vsbc, CarryIn == 1 and CarryOut == 0 2446multiclass VPseudoBinaryV_VM<LMULInfo m, bit CarryOut = 0, bit CarryIn = 1, 2447 string Constraint = "", 2448 bit Commutable = 0, 2449 int TargetConstraintType = 1> { 2450 let isCommutable = Commutable in 2451 def "_VV" # !if(CarryIn, "M", "") # "_" # m.MX : 2452 VPseudoBinaryCarryIn<!if(CarryOut, VR, 2453 !if(!and(CarryIn, !not(CarryOut)), 2454 GetVRegNoV0<m.vrclass>.R, m.vrclass)), 2455 m.vrclass, m.vrclass, m, CarryIn, Constraint, TargetConstraintType>; 2456} 2457 2458multiclass VPseudoTiedBinaryV_VM<LMULInfo m, int TargetConstraintType = 1> { 2459 def "_VVM" # "_" # m.MX: 2460 VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R, 2461 m.vrclass, m.vrclass, m, 1, "", 2462 TargetConstraintType>; 2463} 2464 2465multiclass VPseudoBinaryV_XM<LMULInfo m, bit CarryOut = 0, bit CarryIn = 1, 2466 string Constraint = "", int TargetConstraintType = 1> { 2467 def "_VX" # !if(CarryIn, "M", "") # "_" # m.MX : 2468 VPseudoBinaryCarryIn<!if(CarryOut, VR, 2469 !if(!and(CarryIn, !not(CarryOut)), 2470 GetVRegNoV0<m.vrclass>.R, m.vrclass)), 2471 m.vrclass, GPR, m, CarryIn, Constraint, TargetConstraintType>; 2472} 2473 2474multiclass VPseudoTiedBinaryV_XM<LMULInfo m, int TargetConstraintType = 1> { 2475 def "_VXM" # "_" # m.MX: 2476 VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R, 2477 m.vrclass, GPR, m, 1, "", 2478 TargetConstraintType>; 2479} 2480 2481multiclass VPseudoVMRG_FM { 2482 foreach f = FPList in { 2483 foreach m = f.MxList in { 2484 defvar mx = m.MX; 2485 def "_V" # f.FX # "M_" # mx 2486 : VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R, m.vrclass, 2487 f.fprclass, m, CarryIn=1, 2488 Constraint = "">, 2489 SchedBinary<"WriteVFMergeV", "ReadVFMergeV", "ReadVFMergeF", mx, 2490 forceMasked=1, forceMergeOpRead=true>; 2491 } 2492 } 2493} 2494 2495multiclass VPseudoBinaryV_IM<LMULInfo m, bit CarryOut = 0, bit CarryIn = 1, 2496 string Constraint = "", int TargetConstraintType = 1> { 2497 def "_VI" # !if(CarryIn, "M", "") # "_" # m.MX : 2498 VPseudoBinaryCarryIn<!if(CarryOut, VR, 2499 !if(!and(CarryIn, !not(CarryOut)), 2500 GetVRegNoV0<m.vrclass>.R, m.vrclass)), 2501 m.vrclass, simm5, m, CarryIn, Constraint, TargetConstraintType>; 2502} 2503 2504multiclass VPseudoTiedBinaryV_IM<LMULInfo m> { 2505 def "_VIM" # "_" # m.MX: 2506 VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R, 2507 m.vrclass, simm5, m, 1, "">; 2508} 2509 2510multiclass VPseudoUnaryVMV_V_X_I { 2511 foreach m = MxList in { 2512 let VLMul = m.value in { 2513 defvar mx = m.MX; 2514 let VLMul = m.value in { 2515 def "_V_" # mx : VPseudoUnaryNoMask<m.vrclass, m.vrclass>, 2516 SchedUnary<"WriteVIMovV", "ReadVIMovV", mx, 2517 forceMergeOpRead=true>; 2518 def "_X_" # mx : VPseudoUnaryNoMask<m.vrclass, GPR>, 2519 SchedUnary<"WriteVIMovX", "ReadVIMovX", mx, 2520 forceMergeOpRead=true>; 2521 def "_I_" # mx : VPseudoUnaryNoMask<m.vrclass, simm5>, 2522 SchedNullary<"WriteVIMovI", mx, 2523 forceMergeOpRead=true>; 2524 } 2525 } 2526 } 2527} 2528 2529multiclass VPseudoVMV_F { 2530 foreach f = FPList in { 2531 foreach m = f.MxList in { 2532 defvar mx = m.MX; 2533 let VLMul = m.value in { 2534 def "_" # f.FX # "_" # mx : 2535 VPseudoUnaryNoMask<m.vrclass, f.fprclass>, 2536 SchedUnary<"WriteVFMovV", "ReadVFMovF", mx, forceMergeOpRead=true>; 2537 } 2538 } 2539 } 2540} 2541 2542multiclass VPseudoVCLS_V { 2543 foreach m = MxListF in { 2544 defvar mx = m.MX; 2545 let VLMul = m.value in { 2546 def "_V_" # mx : VPseudoUnaryNoMask<m.vrclass, m.vrclass>, 2547 SchedUnary<"WriteVFClassV", "ReadVFClassV", mx, 2548 forceMergeOpRead=true>; 2549 def "_V_" # mx # "_MASK" : VPseudoUnaryMask<m.vrclass, m.vrclass>, 2550 RISCVMaskedPseudo<MaskIdx=2>, 2551 SchedUnary<"WriteVFClassV", "ReadVFClassV", mx, 2552 forceMergeOpRead=true>; 2553 } 2554 } 2555} 2556 2557multiclass VPseudoVSQR_V_RM { 2558 foreach m = MxListF in { 2559 defvar mx = m.MX; 2560 defvar sews = SchedSEWSet<m.MX, isF=1>.val; 2561 2562 let VLMul = m.value in 2563 foreach e = sews in { 2564 defvar suffix = "_" # mx # "_E" # e; 2565 let SEW = e in { 2566 def "_V" # suffix : VPseudoUnaryNoMaskRoundingMode<m.vrclass, m.vrclass>, 2567 SchedUnary<"WriteVFSqrtV", "ReadVFSqrtV", mx, e, 2568 forceMergeOpRead=true>; 2569 def "_V" #suffix # "_MASK" 2570 : VPseudoUnaryMaskRoundingMode<m.vrclass, m.vrclass>, 2571 RISCVMaskedPseudo<MaskIdx = 2>, 2572 SchedUnary<"WriteVFSqrtV", "ReadVFSqrtV", mx, e, 2573 forceMergeOpRead=true>; 2574 } 2575 } 2576 } 2577} 2578 2579multiclass VPseudoVRCP_V { 2580 foreach m = MxListF in { 2581 defvar mx = m.MX; 2582 let VLMul = m.value in { 2583 def "_V_" # mx 2584 : VPseudoUnaryNoMask<m.vrclass, m.vrclass>, 2585 SchedUnary<"WriteVFRecpV", "ReadVFRecpV", mx, forceMergeOpRead=true>; 2586 def "_V_" # mx # "_MASK" 2587 : VPseudoUnaryMask<m.vrclass, m.vrclass>, 2588 RISCVMaskedPseudo<MaskIdx = 2>, 2589 SchedUnary<"WriteVFRecpV", "ReadVFRecpV", mx, forceMergeOpRead=true>; 2590 } 2591 } 2592} 2593 2594multiclass VPseudoVRCP_V_RM { 2595 foreach m = MxListF in { 2596 defvar mx = m.MX; 2597 let VLMul = m.value in { 2598 def "_V_" # mx 2599 : VPseudoUnaryNoMaskRoundingMode<m.vrclass, m.vrclass>, 2600 SchedUnary<"WriteVFRecpV", "ReadVFRecpV", mx, forceMergeOpRead=true>; 2601 def "_V_" # mx # "_MASK" 2602 : VPseudoUnaryMaskRoundingMode<m.vrclass, m.vrclass>, 2603 RISCVMaskedPseudo<MaskIdx = 2>, 2604 SchedUnary<"WriteVFRecpV", "ReadVFRecpV", mx, forceMergeOpRead=true>; 2605 } 2606 } 2607} 2608 2609multiclass PseudoVEXT_VF2 { 2610 defvar constraints = "@earlyclobber $rd"; 2611 foreach m = MxListVF2 in { 2612 defvar mx = m.MX; 2613 defvar CurrTypeConstraints = !if(!or(!eq(mx, "MF4"), !eq(mx, "MF2"), !eq(mx, "M1")), 1, 3); 2614 let VLMul = m.value in { 2615 def "_" # mx : VPseudoUnaryNoMask<m.vrclass, m.f2vrclass, constraints, CurrTypeConstraints>, 2616 SchedUnary<"WriteVExtV", "ReadVExtV", mx, forceMergeOpRead=true>; 2617 def "_" # mx # "_MASK" : 2618 VPseudoUnaryMask<m.vrclass, m.f2vrclass, constraints, CurrTypeConstraints>, 2619 RISCVMaskedPseudo<MaskIdx=2>, 2620 SchedUnary<"WriteVExtV", "ReadVExtV", mx, forceMergeOpRead=true>; 2621 } 2622 } 2623} 2624 2625multiclass PseudoVEXT_VF4 { 2626 defvar constraints = "@earlyclobber $rd"; 2627 foreach m = MxListVF4 in { 2628 defvar mx = m.MX; 2629 defvar CurrTypeConstraints = !if(!or(!eq(mx, "MF2"), !eq(mx, "M1"), !eq(mx, "M2")), 1, 3); 2630 let VLMul = m.value in { 2631 def "_" # mx : VPseudoUnaryNoMask<m.vrclass, m.f4vrclass, constraints, CurrTypeConstraints>, 2632 SchedUnary<"WriteVExtV", "ReadVExtV", mx, forceMergeOpRead=true>; 2633 def "_" # mx # "_MASK" : 2634 VPseudoUnaryMask<m.vrclass, m.f4vrclass, constraints, CurrTypeConstraints>, 2635 RISCVMaskedPseudo<MaskIdx=2>, 2636 SchedUnary<"WriteVExtV", "ReadVExtV", mx, forceMergeOpRead=true>; 2637 } 2638 } 2639} 2640 2641multiclass PseudoVEXT_VF8 { 2642 defvar constraints = "@earlyclobber $rd"; 2643 foreach m = MxListVF8 in { 2644 defvar mx = m.MX; 2645 defvar CurrTypeConstraints = !if(!or(!eq(mx, "M1"), !eq(mx, "M2"), !eq(mx, "M4")), 1, 3); 2646 let VLMul = m.value in { 2647 def "_" # mx : VPseudoUnaryNoMask<m.vrclass, m.f8vrclass, constraints, CurrTypeConstraints>, 2648 SchedUnary<"WriteVExtV", "ReadVExtV", mx, forceMergeOpRead=true>; 2649 def "_" # mx # "_MASK" : 2650 VPseudoUnaryMask<m.vrclass, m.f8vrclass, constraints, CurrTypeConstraints>, 2651 RISCVMaskedPseudo<MaskIdx=2>, 2652 SchedUnary<"WriteVExtV", "ReadVExtV", mx, forceMergeOpRead=true>; 2653 } 2654 } 2655} 2656 2657// The destination EEW is 1 since "For the purposes of register group overlap 2658// constraints, mask elements have EEW=1." 2659// The source EEW is 8, 16, 32, or 64. 2660// When the destination EEW is different from source EEW, we need to use 2661// @earlyclobber to avoid the overlap between destination and source registers. 2662// We don't need @earlyclobber for LMUL<=1 since that matches this overlap 2663// exception from the spec 2664// "The destination EEW is smaller than the source EEW and the overlap is in the 2665// lowest-numbered part of the source register group". 2666// With LMUL<=1 the source and dest occupy a single register so any overlap 2667// is in the lowest-numbered part. 2668multiclass VPseudoBinaryM_VV<LMULInfo m, int TargetConstraintType = 1> { 2669 defm _VV : VPseudoBinaryM<VR, m.vrclass, m.vrclass, m, 2670 !if(!ge(m.octuple, 16), "@earlyclobber $rd", ""), TargetConstraintType>; 2671} 2672 2673multiclass VPseudoBinaryM_VX<LMULInfo m, int TargetConstraintType = 1> { 2674 defm "_VX" : 2675 VPseudoBinaryM<VR, m.vrclass, GPR, m, 2676 !if(!ge(m.octuple, 16), "@earlyclobber $rd", ""), TargetConstraintType>; 2677} 2678 2679multiclass VPseudoBinaryM_VF<LMULInfo m, FPR_Info f, int TargetConstraintType = 1> { 2680 defm "_V" # f.FX : 2681 VPseudoBinaryM<VR, m.vrclass, f.fprclass, m, 2682 !if(!ge(m.octuple, 16), "@earlyclobber $rd", ""), TargetConstraintType>; 2683} 2684 2685multiclass VPseudoBinaryM_VI<LMULInfo m, int TargetConstraintType = 1> { 2686 defm _VI : VPseudoBinaryM<VR, m.vrclass, simm5, m, 2687 !if(!ge(m.octuple, 16), "@earlyclobber $rd", ""), TargetConstraintType>; 2688} 2689 2690multiclass VPseudoVGTR_VV_VX_VI<Operand ImmType = simm5, string Constraint = ""> { 2691 foreach m = MxList in { 2692 defvar mx = m.MX; 2693 defm "" : VPseudoBinaryV_VX<m, Constraint>, 2694 SchedBinary<"WriteVRGatherVX", "ReadVRGatherVX_data", 2695 "ReadVRGatherVX_index", mx, forceMergeOpRead=true>; 2696 defm "" : VPseudoBinaryV_VI<ImmType, m, Constraint>, 2697 SchedUnary<"WriteVRGatherVI", "ReadVRGatherVI_data", mx, 2698 forceMergeOpRead=true>; 2699 2700 defvar sews = SchedSEWSet<mx>.val; 2701 foreach e = sews in { 2702 defm "" : VPseudoBinaryV_VV<m, Constraint, e>, 2703 SchedBinary<"WriteVRGatherVV", "ReadVRGatherVV_data", 2704 "ReadVRGatherVV_index", mx, e, forceMergeOpRead=true>; 2705 } 2706 } 2707} 2708 2709multiclass VPseudoVSALU_VV_VX_VI<Operand ImmType = simm5, string Constraint = ""> { 2710 foreach m = MxList in { 2711 defvar mx = m.MX; 2712 defm "" : VPseudoBinaryV_VV<m, Constraint>, 2713 SchedBinary<"WriteVSALUV", "ReadVSALUV", "ReadVSALUX", mx, 2714 forceMergeOpRead=true>; 2715 defm "" : VPseudoBinaryV_VX<m, Constraint>, 2716 SchedBinary<"WriteVSALUX", "ReadVSALUV", "ReadVSALUX", mx, 2717 forceMergeOpRead=true>; 2718 defm "" : VPseudoBinaryV_VI<ImmType, m, Constraint>, 2719 SchedUnary<"WriteVSALUI", "ReadVSALUV", mx, forceMergeOpRead=true>; 2720 } 2721} 2722 2723 2724multiclass VPseudoVSHT_VV_VX_VI<Operand ImmType = simm5, string Constraint = ""> { 2725 foreach m = MxList in { 2726 defvar mx = m.MX; 2727 defm "" : VPseudoBinaryV_VV<m, Constraint>, 2728 SchedBinary<"WriteVShiftV", "ReadVShiftV", "ReadVShiftV", mx, 2729 forceMergeOpRead=true>; 2730 defm "" : VPseudoBinaryV_VX<m, Constraint>, 2731 SchedBinary<"WriteVShiftX", "ReadVShiftV", "ReadVShiftX", mx, 2732 forceMergeOpRead=true>; 2733 defm "" : VPseudoBinaryV_VI<ImmType, m, Constraint>, 2734 SchedUnary<"WriteVShiftI", "ReadVShiftV", mx, forceMergeOpRead=true>; 2735 } 2736} 2737 2738multiclass VPseudoVSSHT_VV_VX_VI_RM<Operand ImmType = simm5, string Constraint = ""> { 2739 foreach m = MxList in { 2740 defvar mx = m.MX; 2741 defm "" : VPseudoBinaryV_VV_RM<m, Constraint>, 2742 SchedBinary<"WriteVSShiftV", "ReadVSShiftV", "ReadVSShiftV", mx, 2743 forceMergeOpRead=true>; 2744 defm "" : VPseudoBinaryV_VX_RM<m, Constraint>, 2745 SchedBinary<"WriteVSShiftX", "ReadVSShiftV", "ReadVSShiftX", mx, 2746 forceMergeOpRead=true>; 2747 defm "" : VPseudoBinaryV_VI_RM<ImmType, m, Constraint>, 2748 SchedUnary<"WriteVSShiftI", "ReadVSShiftV", mx, forceMergeOpRead=true>; 2749 } 2750} 2751 2752multiclass VPseudoVALU_VV_VX_VI<Operand ImmType = simm5, string Constraint = ""> { 2753 foreach m = MxList in { 2754 defvar mx = m.MX; 2755 defm "" : VPseudoBinaryV_VV<m, Constraint>, 2756 SchedBinary<"WriteVIALUV", "ReadVIALUV", "ReadVIALUV", mx, 2757 forceMergeOpRead=true>; 2758 defm "" : VPseudoBinaryV_VX<m, Constraint>, 2759 SchedBinary<"WriteVIALUX", "ReadVIALUV", "ReadVIALUX", mx, 2760 forceMergeOpRead=true>; 2761 defm "" : VPseudoBinaryV_VI<ImmType, m, Constraint>, 2762 SchedUnary<"WriteVIALUI", "ReadVIALUV", mx, forceMergeOpRead=true>; 2763 } 2764} 2765 2766multiclass VPseudoVSALU_VV_VX { 2767 foreach m = MxList in { 2768 defvar mx = m.MX; 2769 defm "" : VPseudoBinaryV_VV<m>, 2770 SchedBinary<"WriteVSALUV", "ReadVSALUV", "ReadVSALUV", mx, 2771 forceMergeOpRead=true>; 2772 defm "" : VPseudoBinaryV_VX<m>, 2773 SchedBinary<"WriteVSALUX", "ReadVSALUV", "ReadVSALUX", mx, 2774 forceMergeOpRead=true>; 2775 } 2776} 2777 2778multiclass VPseudoVSMUL_VV_VX_RM { 2779 foreach m = MxList in { 2780 defvar mx = m.MX; 2781 defm "" : VPseudoBinaryV_VV_RM<m>, 2782 SchedBinary<"WriteVSMulV", "ReadVSMulV", "ReadVSMulV", mx, 2783 forceMergeOpRead=true>; 2784 defm "" : VPseudoBinaryV_VX_RM<m>, 2785 SchedBinary<"WriteVSMulX", "ReadVSMulV", "ReadVSMulX", mx, 2786 forceMergeOpRead=true>; 2787 } 2788} 2789 2790multiclass VPseudoVAALU_VV_VX_RM { 2791 foreach m = MxList in { 2792 defvar mx = m.MX; 2793 defm "" : VPseudoBinaryV_VV_RM<m>, 2794 SchedBinary<"WriteVAALUV", "ReadVAALUV", "ReadVAALUV", mx, 2795 forceMergeOpRead=true>; 2796 defm "" : VPseudoBinaryV_VX_RM<m>, 2797 SchedBinary<"WriteVAALUX", "ReadVAALUV", "ReadVAALUX", mx, 2798 forceMergeOpRead=true>; 2799 } 2800} 2801 2802multiclass VPseudoVMINMAX_VV_VX { 2803 foreach m = MxList in { 2804 defvar mx = m.MX; 2805 defm "" : VPseudoBinaryV_VV<m>, 2806 SchedBinary<"WriteVIMinMaxV", "ReadVIMinMaxV", "ReadVIMinMaxV", mx>; 2807 defm "" : VPseudoBinaryV_VX<m>, 2808 SchedBinary<"WriteVIMinMaxX", "ReadVIMinMaxV", "ReadVIMinMaxX", mx>; 2809 } 2810} 2811 2812multiclass VPseudoVMUL_VV_VX { 2813 foreach m = MxList in { 2814 defvar mx = m.MX; 2815 defm "" : VPseudoBinaryV_VV<m>, 2816 SchedBinary<"WriteVIMulV", "ReadVIMulV", "ReadVIMulV", mx>; 2817 defm "" : VPseudoBinaryV_VX<m>, 2818 SchedBinary<"WriteVIMulX", "ReadVIMulV", "ReadVIMulX", mx>; 2819 } 2820} 2821 2822multiclass VPseudoVDIV_VV_VX { 2823 foreach m = MxList in { 2824 defvar mx = m.MX; 2825 defvar sews = SchedSEWSet<mx>.val; 2826 foreach e = sews in { 2827 defm "" : VPseudoBinaryV_VV<m, "", e>, 2828 SchedBinary<"WriteVIDivV", "ReadVIDivV", "ReadVIDivV", mx, e>; 2829 defm "" : VPseudoBinaryV_VX<m, "", e>, 2830 SchedBinary<"WriteVIDivX", "ReadVIDivV", "ReadVIDivX", mx, e>; 2831 } 2832 } 2833} 2834 2835multiclass VPseudoVFMUL_VV_VF_RM { 2836 foreach m = MxListF in { 2837 defm "" : VPseudoBinaryFV_VV_RM<m>, 2838 SchedBinary<"WriteVFMulV", "ReadVFMulV", "ReadVFMulV", m.MX, 2839 forceMergeOpRead=true>; 2840 } 2841 2842 foreach f = FPList in { 2843 foreach m = f.MxList in { 2844 defm "" : VPseudoBinaryV_VF_RM<m, f>, 2845 SchedBinary<"WriteVFMulF", "ReadVFMulV", "ReadVFMulF", m.MX, 2846 forceMergeOpRead=true>; 2847 } 2848 } 2849} 2850 2851multiclass VPseudoVFDIV_VV_VF_RM { 2852 foreach m = MxListF in { 2853 defvar mx = m.MX; 2854 defvar sews = SchedSEWSet<mx, isF=1>.val; 2855 foreach e = sews in { 2856 defm "" : VPseudoBinaryFV_VV_RM<m, "", e>, 2857 SchedBinary<"WriteVFDivV", "ReadVFDivV", "ReadVFDivV", mx, e, 2858 forceMergeOpRead=true>; 2859 } 2860 } 2861 2862 foreach f = FPList in { 2863 foreach m = f.MxList in { 2864 defm "" : VPseudoBinaryV_VF_RM<m, f, "", f.SEW>, 2865 SchedBinary<"WriteVFDivF", "ReadVFDivV", "ReadVFDivF", m.MX, f.SEW, 2866 forceMergeOpRead=true>; 2867 } 2868 } 2869} 2870 2871multiclass VPseudoVFRDIV_VF_RM { 2872 foreach f = FPList in { 2873 foreach m = f.MxList in { 2874 defm "" : VPseudoBinaryV_VF_RM<m, f, "", f.SEW>, 2875 SchedBinary<"WriteVFDivF", "ReadVFDivV", "ReadVFDivF", m.MX, f.SEW, 2876 forceMergeOpRead=true>; 2877 } 2878 } 2879} 2880 2881multiclass VPseudoVALU_VV_VX { 2882 foreach m = MxList in { 2883 defm "" : VPseudoBinaryV_VV<m>, 2884 SchedBinary<"WriteVIALUV", "ReadVIALUV", "ReadVIALUV", m.MX, 2885 forceMergeOpRead=true>; 2886 defm "" : VPseudoBinaryV_VX<m>, 2887 SchedBinary<"WriteVIALUX", "ReadVIALUV", "ReadVIALUX", m.MX, 2888 forceMergeOpRead=true>; 2889 } 2890} 2891 2892multiclass VPseudoVSGNJ_VV_VF { 2893 foreach m = MxListF in { 2894 defm "" : VPseudoBinaryFV_VV<m>, 2895 SchedBinary<"WriteVFSgnjV", "ReadVFSgnjV", "ReadVFSgnjV", m.MX, 2896 forceMergeOpRead=true>; 2897 } 2898 2899 foreach f = FPList in { 2900 foreach m = f.MxList in { 2901 defm "" : VPseudoBinaryV_VF<m, f>, 2902 SchedBinary<"WriteVFSgnjF", "ReadVFSgnjV", "ReadVFSgnjF", m.MX, 2903 forceMergeOpRead=true>; 2904 } 2905 } 2906} 2907 2908multiclass VPseudoVMAX_VV_VF { 2909 foreach m = MxListF in { 2910 defm "" : VPseudoBinaryFV_VV<m>, 2911 SchedBinary<"WriteVFMinMaxV", "ReadVFMinMaxV", "ReadVFMinMaxV", m.MX, 2912 forceMergeOpRead=true>; 2913 } 2914 2915 foreach f = FPList in { 2916 foreach m = f.MxList in { 2917 defm "" : VPseudoBinaryV_VF<m, f>, 2918 SchedBinary<"WriteVFMinMaxF", "ReadVFMinMaxV", "ReadVFMinMaxF", m.MX, 2919 forceMergeOpRead=true>; 2920 } 2921 } 2922} 2923 2924multiclass VPseudoVALU_VV_VF { 2925 foreach m = MxListF in { 2926 defm "" : VPseudoBinaryFV_VV<m>, 2927 SchedBinary<"WriteVFALUV", "ReadVFALUV", "ReadVFALUV", m.MX, 2928 forceMergeOpRead=true>; 2929 } 2930 2931 foreach f = FPList in { 2932 foreach m = f.MxList in { 2933 defm "" : VPseudoBinaryV_VF<m, f>, 2934 SchedBinary<"WriteVFALUF", "ReadVFALUV", "ReadVFALUF", m.MX, 2935 forceMergeOpRead=true>; 2936 } 2937 } 2938} 2939 2940multiclass VPseudoVALU_VV_VF_RM { 2941 foreach m = MxListF in { 2942 defm "" : VPseudoBinaryFV_VV_RM<m>, 2943 SchedBinary<"WriteVFALUV", "ReadVFALUV", "ReadVFALUV", m.MX, 2944 forceMergeOpRead=true>; 2945 } 2946 2947 foreach f = FPList in { 2948 foreach m = f.MxList in { 2949 defm "" : VPseudoBinaryV_VF_RM<m, f>, 2950 SchedBinary<"WriteVFALUF", "ReadVFALUV", "ReadVFALUF", m.MX, 2951 forceMergeOpRead=true>; 2952 } 2953 } 2954} 2955 2956multiclass VPseudoVALU_VF { 2957 foreach f = FPList in { 2958 foreach m = f.MxList in { 2959 defm "" : VPseudoBinaryV_VF<m, f>, 2960 SchedBinary<"WriteVFALUF", "ReadVFALUV", "ReadVFALUF", m.MX, 2961 forceMergeOpRead=true>; 2962 } 2963 } 2964} 2965 2966multiclass VPseudoVALU_VF_RM { 2967 foreach f = FPList in { 2968 foreach m = f.MxList in { 2969 defm "" : VPseudoBinaryV_VF_RM<m, f>, 2970 SchedBinary<"WriteVFALUF", "ReadVFALUV", "ReadVFALUF", m.MX, 2971 forceMergeOpRead=true>; 2972 } 2973 } 2974} 2975 2976multiclass VPseudoVALU_VX_VI<Operand ImmType = simm5> { 2977 foreach m = MxList in { 2978 defvar mx = m.MX; 2979 defm "" : VPseudoBinaryV_VX<m>, 2980 SchedBinary<"WriteVIALUX", "ReadVIALUV", "ReadVIALUX", mx, 2981 forceMergeOpRead=true>; 2982 defm "" : VPseudoBinaryV_VI<ImmType, m>, 2983 SchedUnary<"WriteVIALUI", "ReadVIALUV", mx, forceMergeOpRead=true>; 2984 } 2985} 2986 2987multiclass VPseudoVWALU_VV_VX { 2988 foreach m = MxListW in { 2989 defvar mx = m.MX; 2990 defm "" : VPseudoBinaryW_VV<m>, 2991 SchedBinary<"WriteVIWALUV", "ReadVIWALUV", "ReadVIWALUV", mx, 2992 forceMergeOpRead=true>; 2993 defm "" : VPseudoBinaryW_VX<m>, 2994 SchedBinary<"WriteVIWALUX", "ReadVIWALUV", "ReadVIWALUX", mx, 2995 forceMergeOpRead=true>; 2996 } 2997} 2998 2999multiclass VPseudoVWALU_VV_VX_VI<Operand ImmType> : VPseudoVWALU_VV_VX { 3000 foreach m = MxListW in { 3001 defm "" : VPseudoBinaryW_VI<ImmType, m>; 3002 } 3003} 3004 3005multiclass VPseudoVWMUL_VV_VX { 3006 foreach m = MxListW in { 3007 defvar mx = m.MX; 3008 defm "" : VPseudoBinaryW_VV<m>, 3009 SchedBinary<"WriteVIWMulV", "ReadVIWMulV", "ReadVIWMulV", mx, 3010 forceMergeOpRead=true>; 3011 defm "" : VPseudoBinaryW_VX<m>, 3012 SchedBinary<"WriteVIWMulX", "ReadVIWMulV", "ReadVIWMulX", mx, 3013 forceMergeOpRead=true>; 3014 } 3015} 3016 3017multiclass VPseudoVWMUL_VV_VF_RM { 3018 foreach m = MxListFW in { 3019 defm "" : VPseudoBinaryW_VV_RM<m>, 3020 SchedBinary<"WriteVFWMulV", "ReadVFWMulV", "ReadVFWMulV", m.MX, 3021 forceMergeOpRead=true>; 3022 } 3023 3024 foreach f = FPListW in { 3025 foreach m = f.MxListFW in { 3026 defm "" : VPseudoBinaryW_VF_RM<m, f>, 3027 SchedBinary<"WriteVFWMulF", "ReadVFWMulV", "ReadVFWMulF", m.MX, 3028 forceMergeOpRead=true>; 3029 } 3030 } 3031} 3032 3033multiclass VPseudoVWALU_WV_WX { 3034 foreach m = MxListW in { 3035 defvar mx = m.MX; 3036 defm "" : VPseudoBinaryW_WV<m>, 3037 SchedBinary<"WriteVIWALUV", "ReadVIWALUV", "ReadVIWALUV", mx, 3038 forceMergeOpRead=true>; 3039 defm "" : VPseudoBinaryW_WX<m>, 3040 SchedBinary<"WriteVIWALUX", "ReadVIWALUV", "ReadVIWALUX", mx, 3041 forceMergeOpRead=true>; 3042 } 3043} 3044 3045multiclass VPseudoVFWALU_VV_VF_RM { 3046 foreach m = MxListFW in { 3047 defm "" : VPseudoBinaryW_VV_RM<m>, 3048 SchedBinary<"WriteVFWALUV", "ReadVFWALUV", "ReadVFWALUV", m.MX, 3049 forceMergeOpRead=true>; 3050 } 3051 3052 foreach f = FPListW in { 3053 foreach m = f.MxListFW in { 3054 defm "" : VPseudoBinaryW_VF_RM<m, f>, 3055 SchedBinary<"WriteVFWALUF", "ReadVFWALUV", "ReadVFWALUF", m.MX, 3056 forceMergeOpRead=true>; 3057 } 3058 } 3059} 3060 3061multiclass VPseudoVFWALU_WV_WF_RM { 3062 foreach m = MxListFW in { 3063 defm "" : VPseudoBinaryW_WV_RM<m>, 3064 SchedBinary<"WriteVFWALUV", "ReadVFWALUV", "ReadVFWALUV", m.MX, 3065 forceMergeOpRead=true>; 3066 } 3067 foreach f = FPListW in { 3068 foreach m = f.MxListFW in { 3069 defm "" : VPseudoBinaryW_WF_RM<m, f>, 3070 SchedBinary<"WriteVFWALUF", "ReadVFWALUV", "ReadVFWALUF", m.MX, 3071 forceMergeOpRead=true>; 3072 } 3073 } 3074} 3075 3076multiclass VPseudoVMRG_VM_XM_IM { 3077 foreach m = MxList in { 3078 defvar mx = m.MX; 3079 def "_VVM" # "_" # m.MX: 3080 VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R, 3081 m.vrclass, m.vrclass, m, 1, "">, 3082 SchedBinary<"WriteVIMergeV", "ReadVIMergeV", "ReadVIMergeV", mx, 3083 forceMergeOpRead=true>; 3084 def "_VXM" # "_" # m.MX: 3085 VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R, 3086 m.vrclass, GPR, m, 1, "">, 3087 SchedBinary<"WriteVIMergeX", "ReadVIMergeV", "ReadVIMergeX", mx, 3088 forceMergeOpRead=true>; 3089 def "_VIM" # "_" # m.MX: 3090 VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R, 3091 m.vrclass, simm5, m, 1, "">, 3092 SchedUnary<"WriteVIMergeI", "ReadVIMergeV", mx, 3093 forceMergeOpRead=true>; 3094 } 3095} 3096 3097multiclass VPseudoVCALU_VM_XM_IM { 3098 foreach m = MxList in { 3099 defvar mx = m.MX; 3100 defm "" : VPseudoTiedBinaryV_VM<m>, 3101 SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx, 3102 forceMergeOpRead=true>; 3103 defm "" : VPseudoTiedBinaryV_XM<m>, 3104 SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx, 3105 forceMergeOpRead=true>; 3106 defm "" : VPseudoTiedBinaryV_IM<m>, 3107 SchedUnary<"WriteVICALUI", "ReadVICALUV", mx, 3108 forceMergeOpRead=true>; 3109 } 3110} 3111 3112multiclass VPseudoVCALU_VM_XM { 3113 foreach m = MxList in { 3114 defvar mx = m.MX; 3115 defm "" : VPseudoTiedBinaryV_VM<m>, 3116 SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx, 3117 forceMergeOpRead=true>; 3118 defm "" : VPseudoTiedBinaryV_XM<m>, 3119 SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx, 3120 forceMergeOpRead=true>; 3121 } 3122} 3123 3124multiclass VPseudoVCALUM_VM_XM_IM<string Constraint> { 3125 foreach m = MxList in { 3126 defvar mx = m.MX; 3127 defm "" : VPseudoBinaryV_VM<m, CarryOut=1, CarryIn=1, Constraint=Constraint, 3128 Commutable=1, TargetConstraintType=2>, 3129 SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx, forceMasked=1, 3130 forceMergeOpRead=true>; 3131 defm "" : VPseudoBinaryV_XM<m, CarryOut=1, CarryIn=1, Constraint=Constraint, TargetConstraintType=2>, 3132 SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx, forceMasked=1, 3133 forceMergeOpRead=true>; 3134 defm "" : VPseudoBinaryV_IM<m, CarryOut=1, CarryIn=1, Constraint=Constraint, TargetConstraintType=2>, 3135 SchedUnary<"WriteVICALUI", "ReadVICALUV", mx, forceMasked=1, 3136 forceMergeOpRead=true>; 3137 } 3138} 3139 3140multiclass VPseudoVCALUM_VM_XM<string Constraint> { 3141 foreach m = MxList in { 3142 defvar mx = m.MX; 3143 defm "" : VPseudoBinaryV_VM<m, CarryOut=1, CarryIn=1, Constraint=Constraint, TargetConstraintType=2>, 3144 SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx, forceMasked=1, 3145 forceMergeOpRead=true>; 3146 defm "" : VPseudoBinaryV_XM<m, CarryOut=1, CarryIn=1, Constraint=Constraint, TargetConstraintType=2>, 3147 SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx, forceMasked=1, 3148 forceMergeOpRead=true>; 3149 } 3150} 3151 3152multiclass VPseudoVCALUM_V_X_I<string Constraint> { 3153 foreach m = MxList in { 3154 defvar mx = m.MX; 3155 defm "" : VPseudoBinaryV_VM<m, CarryOut=1, CarryIn=0, Constraint=Constraint, 3156 Commutable=1, TargetConstraintType=2>, 3157 SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx, 3158 forceMergeOpRead=true>; 3159 defm "" : VPseudoBinaryV_XM<m, CarryOut=1, CarryIn=0, Constraint=Constraint, TargetConstraintType=2>, 3160 SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx, 3161 forceMergeOpRead=true>; 3162 defm "" : VPseudoBinaryV_IM<m, CarryOut=1, CarryIn=0, Constraint=Constraint>, 3163 SchedUnary<"WriteVICALUI", "ReadVICALUV", mx, 3164 forceMergeOpRead=true>; 3165 } 3166} 3167 3168multiclass VPseudoVCALUM_V_X<string Constraint> { 3169 foreach m = MxList in { 3170 defvar mx = m.MX; 3171 defm "" : VPseudoBinaryV_VM<m, CarryOut=1, CarryIn=0, Constraint=Constraint, TargetConstraintType=2>, 3172 SchedBinary<"WriteVICALUV", "ReadVICALUV", "ReadVICALUV", mx, 3173 forceMergeOpRead=true>; 3174 defm "" : VPseudoBinaryV_XM<m, CarryOut=1, CarryIn=0, Constraint=Constraint, TargetConstraintType=2>, 3175 SchedBinary<"WriteVICALUX", "ReadVICALUV", "ReadVICALUX", mx, 3176 forceMergeOpRead=true>; 3177 } 3178} 3179 3180multiclass VPseudoVNCLP_WV_WX_WI_RM { 3181 foreach m = MxListW in { 3182 defvar mx = m.MX; 3183 defm "" : VPseudoBinaryV_WV_RM<m>, 3184 SchedBinary<"WriteVNClipV", "ReadVNClipV", "ReadVNClipV", mx, 3185 forceMergeOpRead=true>; 3186 defm "" : VPseudoBinaryV_WX_RM<m>, 3187 SchedBinary<"WriteVNClipX", "ReadVNClipV", "ReadVNClipX", mx, 3188 forceMergeOpRead=true>; 3189 defm "" : VPseudoBinaryV_WI_RM<m>, 3190 SchedUnary<"WriteVNClipI", "ReadVNClipV", mx, 3191 forceMergeOpRead=true>; 3192 } 3193} 3194 3195multiclass VPseudoVNSHT_WV_WX_WI { 3196 foreach m = MxListW in { 3197 defvar mx = m.MX; 3198 defm "" : VPseudoBinaryV_WV<m, TargetConstraintType=2>, 3199 SchedBinary<"WriteVNShiftV", "ReadVNShiftV", "ReadVNShiftV", mx, 3200 forceMergeOpRead=true>; 3201 defm "" : VPseudoBinaryV_WX<m, TargetConstraintType=2>, 3202 SchedBinary<"WriteVNShiftX", "ReadVNShiftV", "ReadVNShiftX", mx, 3203 forceMergeOpRead=true>; 3204 defm "" : VPseudoBinaryV_WI<m, TargetConstraintType=2>, 3205 SchedUnary<"WriteVNShiftI", "ReadVNShiftV", mx, 3206 forceMergeOpRead=true>; 3207 } 3208} 3209 3210multiclass VPseudoTernaryWithTailPolicy<VReg RetClass, 3211 RegisterClass Op1Class, 3212 DAGOperand Op2Class, 3213 LMULInfo MInfo, 3214 int sew, 3215 string Constraint = "", 3216 bit Commutable = 0> { 3217 let VLMul = MInfo.value, SEW=sew in { 3218 defvar mx = MInfo.MX; 3219 let isCommutable = Commutable in 3220 def "_" # mx # "_E" # sew : VPseudoTernaryNoMaskWithPolicy<RetClass, Op1Class, Op2Class, Constraint>; 3221 def "_" # mx # "_E" # sew # "_MASK" : VPseudoTernaryMaskPolicy<RetClass, Op1Class, Op2Class, Constraint>, 3222 RISCVMaskedPseudo<MaskIdx=3, MaskAffectsRes=true>; 3223 } 3224} 3225 3226multiclass VPseudoTernaryWithTailPolicyRoundingMode<VReg RetClass, 3227 RegisterClass Op1Class, 3228 DAGOperand Op2Class, 3229 LMULInfo MInfo, 3230 int sew, 3231 string Constraint = "", 3232 bit Commutable = 0> { 3233 let VLMul = MInfo.value, SEW=sew in { 3234 defvar mx = MInfo.MX; 3235 let isCommutable = Commutable in 3236 def "_" # mx # "_E" # sew 3237 : VPseudoTernaryNoMaskWithPolicyRoundingMode<RetClass, Op1Class, 3238 Op2Class, Constraint>; 3239 def "_" # mx # "_E" # sew # "_MASK" 3240 : VPseudoTernaryMaskPolicyRoundingMode<RetClass, Op1Class, 3241 Op2Class, Constraint>, 3242 RISCVMaskedPseudo<MaskIdx=3, MaskAffectsRes=true>; 3243 } 3244} 3245 3246multiclass VPseudoTernaryWithPolicy<VReg RetClass, 3247 RegisterClass Op1Class, 3248 DAGOperand Op2Class, 3249 LMULInfo MInfo, 3250 string Constraint = "", 3251 bit Commutable = 0, 3252 int TargetConstraintType = 1> { 3253 let VLMul = MInfo.value in { 3254 let isCommutable = Commutable in 3255 def "_" # MInfo.MX : VPseudoTernaryNoMaskWithPolicy<RetClass, Op1Class, Op2Class, Constraint, TargetConstraintType>; 3256 def "_" # MInfo.MX # "_MASK" : VPseudoBinaryMaskPolicy<RetClass, Op1Class, Op2Class, Constraint, TargetConstraintType>, 3257 RISCVMaskedPseudo<MaskIdx=3>; 3258 } 3259} 3260 3261multiclass VPseudoTernaryWithPolicyRoundingMode<VReg RetClass, 3262 RegisterClass Op1Class, 3263 DAGOperand Op2Class, 3264 LMULInfo MInfo, 3265 string Constraint = "", 3266 bit Commutable = 0, 3267 int TargetConstraintType = 1> { 3268 let VLMul = MInfo.value in { 3269 let isCommutable = Commutable in 3270 def "_" # MInfo.MX : 3271 VPseudoTernaryNoMaskWithPolicyRoundingMode<RetClass, Op1Class, 3272 Op2Class, Constraint, 3273 TargetConstraintType>; 3274 def "_" # MInfo.MX # "_MASK" : 3275 VPseudoBinaryMaskPolicyRoundingMode<RetClass, Op1Class, 3276 Op2Class, Constraint, 3277 UsesVXRM_=0, 3278 TargetConstraintType=TargetConstraintType>, 3279 RISCVMaskedPseudo<MaskIdx=3>; 3280 } 3281} 3282 3283multiclass VPseudoTernaryV_VV_AAXA<LMULInfo m, string Constraint = ""> { 3284 defm _VV : VPseudoTernaryWithPolicy<m.vrclass, m.vrclass, m.vrclass, m, 3285 Constraint, Commutable=1>; 3286} 3287 3288multiclass VPseudoTernaryV_VV_AAXA_RM<LMULInfo m, string Constraint = ""> { 3289 defm _VV : VPseudoTernaryWithPolicyRoundingMode<m.vrclass, m.vrclass, m.vrclass, m, 3290 Constraint, Commutable=1>; 3291} 3292 3293multiclass VPseudoTernaryV_VX_AAXA<LMULInfo m, string Constraint = ""> { 3294 defm "_VX" : VPseudoTernaryWithPolicy<m.vrclass, GPR, m.vrclass, m, 3295 Constraint, Commutable=1>; 3296} 3297 3298multiclass VPseudoTernaryV_VF_AAXA<LMULInfo m, FPR_Info f, string Constraint = ""> { 3299 defm "_V" # f.FX : VPseudoTernaryWithPolicy<m.vrclass, f.fprclass, 3300 m.vrclass, m, Constraint, 3301 Commutable=1>; 3302} 3303 3304multiclass VPseudoTernaryV_VF_AAXA_RM<LMULInfo m, FPR_Info f, string Constraint = ""> { 3305 defm "_V" # f.FX : VPseudoTernaryWithPolicyRoundingMode<m.vrclass, f.fprclass, 3306 m.vrclass, m, Constraint, 3307 Commutable=1>; 3308} 3309 3310multiclass VPseudoTernaryW_VV<LMULInfo m> { 3311 defvar constraint = "@earlyclobber $rd"; 3312 defm _VV : VPseudoTernaryWithPolicy<m.wvrclass, m.vrclass, m.vrclass, m, 3313 constraint, /*Commutable*/ 0, TargetConstraintType=3>; 3314} 3315 3316multiclass VPseudoTernaryW_VV_RM<LMULInfo m> { 3317 defvar constraint = "@earlyclobber $rd"; 3318 defm _VV : VPseudoTernaryWithPolicyRoundingMode<m.wvrclass, m.vrclass, m.vrclass, m, 3319 constraint, /* Commutable */ 0, 3320 TargetConstraintType=3>; 3321} 3322 3323multiclass VPseudoTernaryW_VX<LMULInfo m> { 3324 defvar constraint = "@earlyclobber $rd"; 3325 defm "_VX" : VPseudoTernaryWithPolicy<m.wvrclass, GPR, m.vrclass, m, 3326 constraint, /*Commutable*/ 0, TargetConstraintType=3>; 3327} 3328 3329multiclass VPseudoTernaryW_VF<LMULInfo m, FPR_Info f, int TargetConstraintType = 1> { 3330 defvar constraint = "@earlyclobber $rd"; 3331 defm "_V" # f.FX : VPseudoTernaryWithPolicy<m.wvrclass, f.fprclass, 3332 m.vrclass, m, constraint, /*Commutable*/ 0, TargetConstraintType>; 3333} 3334 3335multiclass VPseudoTernaryW_VF_RM<LMULInfo m, FPR_Info f> { 3336 defvar constraint = "@earlyclobber $rd"; 3337 defm "_V" # f.FX : VPseudoTernaryWithPolicyRoundingMode<m.wvrclass, f.fprclass, 3338 m.vrclass, m, constraint, 3339 /* Commutable */ 0, 3340 TargetConstraintType=3>; 3341} 3342 3343multiclass VPseudoVSLDVWithPolicy<VReg RetClass, 3344 RegisterClass Op1Class, 3345 DAGOperand Op2Class, 3346 LMULInfo MInfo, 3347 string Constraint = ""> { 3348 let VLMul = MInfo.value in { 3349 def "_" # MInfo.MX : VPseudoTernaryNoMaskWithPolicy<RetClass, Op1Class, Op2Class, Constraint>; 3350 def "_" # MInfo.MX # "_MASK" : VPseudoBinaryMaskPolicy<RetClass, Op1Class, Op2Class, Constraint>, 3351 RISCVMaskedPseudo<MaskIdx=3>; 3352 } 3353} 3354 3355multiclass VPseudoVSLDV_VX<LMULInfo m, string Constraint = ""> { 3356 defm _VX : VPseudoVSLDVWithPolicy<m.vrclass, m.vrclass, GPR, m, Constraint>; 3357} 3358 3359multiclass VPseudoVSLDV_VI<Operand ImmType = simm5, LMULInfo m, string Constraint = ""> { 3360 defm _VI : VPseudoVSLDVWithPolicy<m.vrclass, m.vrclass, ImmType, m, Constraint>; 3361} 3362 3363multiclass VPseudoVMAC_VV_VX_AAXA<string Constraint = ""> { 3364 foreach m = MxList in { 3365 defvar mx = m.MX; 3366 defm "" : VPseudoTernaryV_VV_AAXA<m, Constraint>, 3367 SchedTernary<"WriteVIMulAddV", "ReadVIMulAddV", "ReadVIMulAddV", 3368 "ReadVIMulAddV", mx>; 3369 defm "" : VPseudoTernaryV_VX_AAXA<m, Constraint>, 3370 SchedTernary<"WriteVIMulAddX", "ReadVIMulAddV", "ReadVIMulAddX", 3371 "ReadVIMulAddV", mx>; 3372 } 3373} 3374 3375multiclass VPseudoVMAC_VV_VF_AAXA<string Constraint = ""> { 3376 foreach m = MxListF in { 3377 defm "" : VPseudoTernaryV_VV_AAXA<m, Constraint>, 3378 SchedTernary<"WriteVFMulAddV", "ReadVFMulAddV", "ReadVFMulAddV", 3379 "ReadVFMulAddV", m.MX>; 3380 } 3381 3382 foreach f = FPList in { 3383 foreach m = f.MxList in { 3384 defm "" : VPseudoTernaryV_VF_AAXA<m, f, Constraint>, 3385 SchedTernary<"WriteVFMulAddF", "ReadVFMulAddV", "ReadVFMulAddF", 3386 "ReadVFMulAddV", m.MX>; 3387 } 3388 } 3389} 3390 3391multiclass VPseudoVMAC_VV_VF_AAXA_RM<string Constraint = ""> { 3392 foreach m = MxListF in { 3393 defm "" : VPseudoTernaryV_VV_AAXA_RM<m, Constraint>, 3394 SchedTernary<"WriteVFMulAddV", "ReadVFMulAddV", "ReadVFMulAddV", 3395 "ReadVFMulAddV", m.MX>; 3396 } 3397 3398 foreach f = FPList in { 3399 foreach m = f.MxList in { 3400 defm "" : VPseudoTernaryV_VF_AAXA_RM<m, f, Constraint>, 3401 SchedTernary<"WriteVFMulAddF", "ReadVFMulAddV", "ReadVFMulAddF", 3402 "ReadVFMulAddV", m.MX>; 3403 } 3404 } 3405} 3406 3407multiclass VPseudoVSLD_VX_VI<Operand ImmType = simm5, string Constraint = ""> { 3408 foreach m = MxList in { 3409 defvar mx = m.MX; 3410 defm "" : VPseudoVSLDV_VX<m, Constraint>, 3411 SchedTernary<"WriteVISlideX", "ReadVISlideV", "ReadVISlideV", 3412 "ReadVISlideX", mx>; 3413 defm "" : VPseudoVSLDV_VI<ImmType, m, Constraint>, 3414 SchedBinary<"WriteVISlideI", "ReadVISlideV", "ReadVISlideV", mx>; 3415 } 3416} 3417 3418multiclass VPseudoVWMAC_VV_VX { 3419 foreach m = MxListW in { 3420 defvar mx = m.MX; 3421 defm "" : VPseudoTernaryW_VV<m>, 3422 SchedTernary<"WriteVIWMulAddV", "ReadVIWMulAddV", "ReadVIWMulAddV", 3423 "ReadVIWMulAddV", mx>; 3424 defm "" : VPseudoTernaryW_VX<m>, 3425 SchedTernary<"WriteVIWMulAddX", "ReadVIWMulAddV", "ReadVIWMulAddX", 3426 "ReadVIWMulAddV", mx>; 3427 } 3428} 3429 3430multiclass VPseudoVWMAC_VX { 3431 foreach m = MxListW in { 3432 defm "" : VPseudoTernaryW_VX<m>, 3433 SchedTernary<"WriteVIWMulAddX", "ReadVIWMulAddV", "ReadVIWMulAddX", 3434 "ReadVIWMulAddV", m.MX>; 3435 } 3436} 3437 3438multiclass VPseudoVWMAC_VV_VF_RM { 3439 foreach m = MxListFW in { 3440 defm "" : VPseudoTernaryW_VV_RM<m>, 3441 SchedTernary<"WriteVFWMulAddV", "ReadVFWMulAddV", 3442 "ReadVFWMulAddV", "ReadVFWMulAddV", m.MX>; 3443 } 3444 3445 foreach f = FPListW in { 3446 foreach m = f.MxListFW in { 3447 defm "" : VPseudoTernaryW_VF_RM<m, f>, 3448 SchedTernary<"WriteVFWMulAddF", "ReadVFWMulAddV", 3449 "ReadVFWMulAddF", "ReadVFWMulAddV", m.MX>; 3450 } 3451 } 3452} 3453 3454multiclass VPseudoVWMAC_VV_VF_BF_RM { 3455 foreach m = MxListFW in { 3456 defvar mx = m.MX; 3457 defm "" : VPseudoTernaryW_VV_RM<m>, 3458 SchedTernary<"WriteVFWMulAddV", "ReadVFWMulAddV", 3459 "ReadVFWMulAddV", "ReadVFWMulAddV", mx>; 3460 } 3461 3462 foreach f = BFPListW in { 3463 foreach m = f.MxListFW in { 3464 defvar mx = m.MX; 3465 defm "" : VPseudoTernaryW_VF_RM<m, f>, 3466 SchedTernary<"WriteVFWMulAddF", "ReadVFWMulAddV", 3467 "ReadVFWMulAddF", "ReadVFWMulAddV", mx>; 3468 } 3469 } 3470} 3471 3472multiclass VPseudoVCMPM_VV_VX_VI { 3473 foreach m = MxList in { 3474 defvar mx = m.MX; 3475 defm "" : VPseudoBinaryM_VV<m, TargetConstraintType=2>, 3476 SchedBinary<"WriteVICmpV", "ReadVICmpV", "ReadVICmpV", mx>; 3477 defm "" : VPseudoBinaryM_VX<m, TargetConstraintType=2>, 3478 SchedBinary<"WriteVICmpX", "ReadVICmpV", "ReadVICmpX", mx>; 3479 defm "" : VPseudoBinaryM_VI<m, TargetConstraintType=2>, 3480 SchedUnary<"WriteVICmpI", "ReadVICmpV", mx>; 3481 } 3482} 3483 3484multiclass VPseudoVCMPM_VV_VX { 3485 foreach m = MxList in { 3486 defvar mx = m.MX; 3487 defm "" : VPseudoBinaryM_VV<m, TargetConstraintType=2>, 3488 SchedBinary<"WriteVICmpV", "ReadVICmpV", "ReadVICmpV", mx>; 3489 defm "" : VPseudoBinaryM_VX<m, TargetConstraintType=2>, 3490 SchedBinary<"WriteVICmpX", "ReadVICmpV", "ReadVICmpX", mx>; 3491 } 3492} 3493 3494multiclass VPseudoVCMPM_VV_VF { 3495 foreach m = MxListF in { 3496 defm "" : VPseudoBinaryM_VV<m, TargetConstraintType=2>, 3497 SchedBinary<"WriteVFCmpV", "ReadVFCmpV", "ReadVFCmpV", m.MX>; 3498 } 3499 3500 foreach f = FPList in { 3501 foreach m = f.MxList in { 3502 defm "" : VPseudoBinaryM_VF<m, f, TargetConstraintType=2>, 3503 SchedBinary<"WriteVFCmpF", "ReadVFCmpV", "ReadVFCmpF", m.MX>; 3504 } 3505 } 3506} 3507 3508multiclass VPseudoVCMPM_VF { 3509 foreach f = FPList in { 3510 foreach m = f.MxList in { 3511 defm "" : VPseudoBinaryM_VF<m, f, TargetConstraintType=2>, 3512 SchedBinary<"WriteVFCmpF", "ReadVFCmpV", "ReadVFCmpF", m.MX>; 3513 } 3514 } 3515} 3516 3517multiclass VPseudoVCMPM_VX_VI { 3518 foreach m = MxList in { 3519 defvar mx = m.MX; 3520 defm "" : VPseudoBinaryM_VX<m, TargetConstraintType=2>, 3521 SchedBinary<"WriteVICmpX", "ReadVICmpV", "ReadVICmpX", mx>; 3522 defm "" : VPseudoBinaryM_VI<m, TargetConstraintType=2>, 3523 SchedUnary<"WriteVICmpI", "ReadVICmpV", mx>; 3524 } 3525} 3526 3527multiclass VPseudoVRED_VS { 3528 foreach m = MxList in { 3529 defvar mx = m.MX; 3530 foreach e = SchedSEWSet<mx>.val in { 3531 defm _VS : VPseudoTernaryWithTailPolicy<V_M1.vrclass, m.vrclass, V_M1.vrclass, m, e>, 3532 SchedReduction<"WriteVIRedV_From", "ReadVIRedV", mx, e>; 3533 } 3534 } 3535} 3536 3537multiclass VPseudoVREDMINMAX_VS { 3538 foreach m = MxList in { 3539 defvar mx = m.MX; 3540 foreach e = SchedSEWSet<mx>.val in { 3541 defm _VS : VPseudoTernaryWithTailPolicy<V_M1.vrclass, m.vrclass, V_M1.vrclass, m, e>, 3542 SchedReduction<"WriteVIRedMinMaxV_From", "ReadVIRedV", mx, e>; 3543 } 3544 } 3545} 3546 3547multiclass VPseudoVWRED_VS { 3548 foreach m = MxListWRed in { 3549 defvar mx = m.MX; 3550 foreach e = SchedSEWSet<mx, isWidening=1>.val in { 3551 defm _VS : VPseudoTernaryWithTailPolicy<V_M1.vrclass, m.vrclass, V_M1.vrclass, m, e>, 3552 SchedReduction<"WriteVIWRedV_From", "ReadVIWRedV", mx, e>; 3553 } 3554 } 3555} 3556 3557multiclass VPseudoVFRED_VS_RM { 3558 foreach m = MxListF in { 3559 defvar mx = m.MX; 3560 foreach e = SchedSEWSet<mx, isF=1>.val in { 3561 defm _VS 3562 : VPseudoTernaryWithTailPolicyRoundingMode<V_M1.vrclass, m.vrclass, 3563 V_M1.vrclass, m, e>, 3564 SchedReduction<"WriteVFRedV_From", "ReadVFRedV", mx, e>; 3565 } 3566 } 3567} 3568 3569multiclass VPseudoVFREDMINMAX_VS { 3570 foreach m = MxListF in { 3571 defvar mx = m.MX; 3572 foreach e = SchedSEWSet<mx, isF=1>.val in { 3573 defm _VS : VPseudoTernaryWithTailPolicy<V_M1.vrclass, m.vrclass, V_M1.vrclass, m, e>, 3574 SchedReduction<"WriteVFRedMinMaxV_From", "ReadVFRedV", mx, e>; 3575 } 3576 } 3577} 3578 3579multiclass VPseudoVFREDO_VS_RM { 3580 foreach m = MxListF in { 3581 defvar mx = m.MX; 3582 foreach e = SchedSEWSet<mx, isF=1>.val in { 3583 defm _VS : VPseudoTernaryWithTailPolicyRoundingMode<V_M1.vrclass, m.vrclass, 3584 V_M1.vrclass, m, e>, 3585 SchedReduction<"WriteVFRedOV_From", "ReadVFRedOV", mx, e>; 3586 } 3587 } 3588} 3589 3590multiclass VPseudoVFWRED_VS_RM { 3591 foreach m = MxListFWRed in { 3592 defvar mx = m.MX; 3593 foreach e = SchedSEWSet<mx, isF=1, isWidening=1>.val in { 3594 defm _VS 3595 : VPseudoTernaryWithTailPolicyRoundingMode<V_M1.vrclass, m.vrclass, 3596 V_M1.vrclass, m, e>, 3597 SchedReduction<"WriteVFWRedV_From", "ReadVFWRedV", mx, e>; 3598 } 3599 } 3600} 3601 3602multiclass VPseudoVFWREDO_VS_RM { 3603 foreach m = MxListFWRed in { 3604 defvar mx = m.MX; 3605 foreach e = SchedSEWSet<mx, isF=1, isWidening=1>.val in { 3606 defm _VS 3607 : VPseudoTernaryWithTailPolicyRoundingMode<V_M1.vrclass, m.vrclass, 3608 V_M1.vrclass, m, e>, 3609 SchedReduction<"WriteVFWRedOV_From", "ReadVFWRedV", mx, e>; 3610 } 3611 } 3612} 3613 3614multiclass VPseudoConversion<VReg RetClass, 3615 VReg Op1Class, 3616 LMULInfo MInfo, 3617 string Constraint = "", 3618 int TargetConstraintType = 1> { 3619 let VLMul = MInfo.value in { 3620 def "_" # MInfo.MX : VPseudoUnaryNoMask<RetClass, Op1Class, Constraint, TargetConstraintType>; 3621 def "_" # MInfo.MX # "_MASK" : VPseudoUnaryMask<RetClass, Op1Class, 3622 Constraint, TargetConstraintType>, 3623 RISCVMaskedPseudo<MaskIdx=2>; 3624 } 3625} 3626 3627multiclass VPseudoConversionRoundingMode<VReg RetClass, 3628 VReg Op1Class, 3629 LMULInfo MInfo, 3630 string Constraint = "", 3631 int TargetConstraintType = 1> { 3632 let VLMul = MInfo.value in { 3633 def "_" # MInfo.MX : VPseudoUnaryNoMaskRoundingMode<RetClass, Op1Class, Constraint, TargetConstraintType>; 3634 def "_" # MInfo.MX # "_MASK" : VPseudoUnaryMaskRoundingMode<RetClass, Op1Class, 3635 Constraint, TargetConstraintType>, 3636 RISCVMaskedPseudo<MaskIdx=2>; 3637 } 3638} 3639 3640 3641multiclass VPseudoConversionRM<VReg RetClass, 3642 VReg Op1Class, 3643 LMULInfo MInfo, 3644 string Constraint = "", 3645 int TargetConstraintType = 1> { 3646 let VLMul = MInfo.value in { 3647 def "_" # MInfo.MX : VPseudoUnaryNoMask_FRM<RetClass, Op1Class, 3648 Constraint, TargetConstraintType>; 3649 def "_" # MInfo.MX # "_MASK" : VPseudoUnaryMask_FRM<RetClass, Op1Class, 3650 Constraint, TargetConstraintType>, 3651 RISCVMaskedPseudo<MaskIdx=2>; 3652 } 3653} 3654 3655multiclass VPseudoConversionNoExcept<VReg RetClass, 3656 VReg Op1Class, 3657 LMULInfo MInfo, 3658 string Constraint = ""> { 3659 let VLMul = MInfo.value in { 3660 def "_" # MInfo.MX # "_MASK" : VPseudoUnaryMask_NoExcept<RetClass, Op1Class, Constraint>; 3661 } 3662} 3663 3664multiclass VPseudoVCVTI_V { 3665 foreach m = MxListF in { 3666 defm _V : VPseudoConversion<m.vrclass, m.vrclass, m>, 3667 SchedUnary<"WriteVFCvtFToIV", "ReadVFCvtFToIV", m.MX, 3668 forceMergeOpRead=true>; 3669 } 3670} 3671 3672multiclass VPseudoVCVTI_V_RM { 3673 foreach m = MxListF in { 3674 defm _V : VPseudoConversionRoundingMode<m.vrclass, m.vrclass, m>, 3675 SchedUnary<"WriteVFCvtFToIV", "ReadVFCvtFToIV", m.MX, 3676 forceMergeOpRead=true>; 3677 } 3678} 3679 3680multiclass VPseudoVCVTI_RM_V { 3681 foreach m = MxListF in { 3682 defm _V : VPseudoConversionRM<m.vrclass, m.vrclass, m>, 3683 SchedUnary<"WriteVFCvtFToIV", "ReadVFCvtFToIV", m.MX, 3684 forceMergeOpRead=true>; 3685 } 3686} 3687 3688multiclass VPseudoVFROUND_NOEXCEPT_V { 3689 foreach m = MxListF in { 3690 defm _V : VPseudoConversionNoExcept<m.vrclass, m.vrclass, m>, 3691 SchedUnary<"WriteVFCvtFToIV", "ReadVFCvtFToIV", m.MX, 3692 forceMergeOpRead=true>; 3693 } 3694} 3695 3696multiclass VPseudoVCVTF_V_RM { 3697 foreach m = MxListF in { 3698 defm _V : VPseudoConversionRoundingMode<m.vrclass, m.vrclass, m>, 3699 SchedUnary<"WriteVFCvtIToFV", "ReadVFCvtIToFV", m.MX, 3700 forceMergeOpRead=true>; 3701 } 3702} 3703 3704multiclass VPseudoVCVTF_RM_V { 3705 foreach m = MxListF in { 3706 defm _V : VPseudoConversionRM<m.vrclass, m.vrclass, m>, 3707 SchedUnary<"WriteVFCvtIToFV", "ReadVFCvtIToFV", m.MX, 3708 forceMergeOpRead=true>; 3709 } 3710} 3711 3712multiclass VPseudoVWCVTI_V { 3713 defvar constraint = "@earlyclobber $rd"; 3714 foreach m = MxListFW in { 3715 defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint, TargetConstraintType=3>, 3716 SchedUnary<"WriteVFWCvtFToIV", "ReadVFWCvtFToIV", m.MX, 3717 forceMergeOpRead=true>; 3718 } 3719} 3720 3721multiclass VPseudoVWCVTI_V_RM { 3722 defvar constraint = "@earlyclobber $rd"; 3723 foreach m = MxListFW in { 3724 defm _V : VPseudoConversionRoundingMode<m.wvrclass, m.vrclass, m, constraint, TargetConstraintType=3>, 3725 SchedUnary<"WriteVFWCvtFToIV", "ReadVFWCvtFToIV", m.MX, 3726 forceMergeOpRead=true>; 3727 } 3728} 3729 3730multiclass VPseudoVWCVTI_RM_V { 3731 defvar constraint = "@earlyclobber $rd"; 3732 foreach m = MxListFW in { 3733 defm _V : VPseudoConversionRM<m.wvrclass, m.vrclass, m, constraint>, 3734 SchedUnary<"WriteVFWCvtFToIV", "ReadVFWCvtFToIV", m.MX, 3735 forceMergeOpRead=true>; 3736 } 3737} 3738 3739multiclass VPseudoVWCVTF_V { 3740 defvar constraint = "@earlyclobber $rd"; 3741 foreach m = MxListW in { 3742 defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint, TargetConstraintType=3>, 3743 SchedUnary<"WriteVFWCvtIToFV", "ReadVFWCvtIToFV", m.MX, 3744 forceMergeOpRead=true>; 3745 } 3746} 3747 3748multiclass VPseudoVWCVTD_V { 3749 defvar constraint = "@earlyclobber $rd"; 3750 foreach m = MxListFW in { 3751 defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint, TargetConstraintType=3>, 3752 SchedUnary<"WriteVFWCvtFToFV", "ReadVFWCvtFToFV", m.MX, 3753 forceMergeOpRead=true>; 3754 } 3755} 3756 3757multiclass VPseudoVNCVTI_W { 3758 defvar constraint = "@earlyclobber $rd"; 3759 foreach m = MxListW in { 3760 defm _W : VPseudoConversion<m.vrclass, m.wvrclass, m, constraint, TargetConstraintType=2>, 3761 SchedUnary<"WriteVFNCvtFToIV", "ReadVFNCvtFToIV", m.MX, 3762 forceMergeOpRead=true>; 3763 } 3764} 3765 3766multiclass VPseudoVNCVTI_W_RM { 3767 defvar constraint = "@earlyclobber $rd"; 3768 foreach m = MxListW in { 3769 defm _W : VPseudoConversionRoundingMode<m.vrclass, m.wvrclass, m, constraint, TargetConstraintType=2>, 3770 SchedUnary<"WriteVFNCvtFToIV", "ReadVFNCvtFToIV", m.MX, 3771 forceMergeOpRead=true>; 3772 } 3773} 3774 3775multiclass VPseudoVNCVTI_RM_W { 3776 defvar constraint = "@earlyclobber $rd"; 3777 foreach m = MxListW in { 3778 defm _W : VPseudoConversionRM<m.vrclass, m.wvrclass, m, constraint, TargetConstraintType=2>, 3779 SchedUnary<"WriteVFNCvtFToIV", "ReadVFNCvtFToIV", m.MX, 3780 forceMergeOpRead=true>; 3781 } 3782} 3783 3784multiclass VPseudoVNCVTF_W_RM { 3785 defvar constraint = "@earlyclobber $rd"; 3786 foreach m = MxListFW in { 3787 defm _W : VPseudoConversionRoundingMode<m.vrclass, m.wvrclass, m, constraint, TargetConstraintType=2>, 3788 SchedUnary<"WriteVFNCvtIToFV", "ReadVFNCvtIToFV", m.MX, 3789 forceMergeOpRead=true>; 3790 } 3791} 3792 3793multiclass VPseudoVNCVTF_RM_W { 3794 defvar constraint = "@earlyclobber $rd"; 3795 foreach m = MxListFW in { 3796 defm _W : VPseudoConversionRM<m.vrclass, m.wvrclass, m, constraint>, 3797 SchedUnary<"WriteVFNCvtIToFV", "ReadVFNCvtIToFV", m.MX, 3798 forceMergeOpRead=true>; 3799 } 3800} 3801 3802multiclass VPseudoVNCVTD_W { 3803 defvar constraint = "@earlyclobber $rd"; 3804 foreach m = MxListFW in { 3805 defm _W : VPseudoConversion<m.vrclass, m.wvrclass, m, constraint, TargetConstraintType=2>, 3806 SchedUnary<"WriteVFNCvtFToFV", "ReadVFNCvtFToFV", m.MX, 3807 forceMergeOpRead=true>; 3808 } 3809} 3810 3811multiclass VPseudoVNCVTD_W_RM { 3812 defvar constraint = "@earlyclobber $rd"; 3813 foreach m = MxListFW in { 3814 defm _W : VPseudoConversionRoundingMode<m.vrclass, m.wvrclass, m, constraint, TargetConstraintType=2>, 3815 SchedUnary<"WriteVFNCvtFToFV", "ReadVFNCvtFToFV", m.MX, 3816 forceMergeOpRead=true>; 3817 } 3818} 3819 3820multiclass VPseudoUSSegLoad { 3821 foreach eew = EEWList in { 3822 foreach lmul = MxSet<eew>.m in { 3823 defvar LInfo = lmul.MX; 3824 let VLMul = lmul.value, SEW=eew in { 3825 foreach nf = NFSet<lmul>.L in { 3826 defvar vreg = SegRegClass<lmul, nf>.RC; 3827 def nf # "E" # eew # "_V_" # LInfo : 3828 VPseudoUSSegLoadNoMask<vreg, eew, nf>, VLSEGSched<nf, eew, LInfo>; 3829 def nf # "E" # eew # "_V_" # LInfo # "_MASK" : 3830 VPseudoUSSegLoadMask<vreg, eew, nf>, VLSEGSched<nf, eew, LInfo>; 3831 } 3832 } 3833 } 3834 } 3835} 3836 3837multiclass VPseudoUSSegLoadFF { 3838 foreach eew = EEWList in { 3839 foreach lmul = MxSet<eew>.m in { 3840 defvar LInfo = lmul.MX; 3841 let VLMul = lmul.value, SEW=eew in { 3842 foreach nf = NFSet<lmul>.L in { 3843 defvar vreg = SegRegClass<lmul, nf>.RC; 3844 def nf # "E" # eew # "FF_V_" # LInfo : 3845 VPseudoUSSegLoadFFNoMask<vreg, eew, nf>, VLSEGFFSched<nf, eew, LInfo>; 3846 def nf # "E" # eew # "FF_V_" # LInfo # "_MASK" : 3847 VPseudoUSSegLoadFFMask<vreg, eew, nf>, VLSEGFFSched<nf, eew, LInfo>; 3848 } 3849 } 3850 } 3851 } 3852} 3853 3854multiclass VPseudoSSegLoad { 3855 foreach eew = EEWList in { 3856 foreach lmul = MxSet<eew>.m in { 3857 defvar LInfo = lmul.MX; 3858 let VLMul = lmul.value, SEW=eew in { 3859 foreach nf = NFSet<lmul>.L in { 3860 defvar vreg = SegRegClass<lmul, nf>.RC; 3861 def nf # "E" # eew # "_V_" # LInfo : VPseudoSSegLoadNoMask<vreg, eew, nf>, 3862 VLSSEGSched<nf, eew, LInfo>; 3863 def nf # "E" # eew # "_V_" # LInfo # "_MASK" : VPseudoSSegLoadMask<vreg, eew, nf>, 3864 VLSSEGSched<nf, eew, LInfo>; 3865 } 3866 } 3867 } 3868 } 3869} 3870 3871multiclass VPseudoISegLoad<bit Ordered> { 3872 foreach idxEEW = EEWList in { 3873 foreach dataEEW = EEWList in { 3874 foreach dataEMUL = MxSet<dataEEW>.m in { 3875 defvar dataEMULOctuple = dataEMUL.octuple; 3876 // Calculate emul = eew * lmul / sew 3877 defvar idxEMULOctuple = !srl(!mul(idxEEW, dataEMULOctuple), !logtwo(dataEEW)); 3878 if !and(!ge(idxEMULOctuple, 1), !le(idxEMULOctuple, 64)) then { 3879 defvar DataLInfo = dataEMUL.MX; 3880 defvar IdxLInfo = octuple_to_str<idxEMULOctuple>.ret; 3881 defvar idxEMUL = !cast<LMULInfo>("V_" # IdxLInfo); 3882 defvar DataVreg = dataEMUL.vrclass; 3883 defvar IdxVreg = idxEMUL.vrclass; 3884 let VLMul = dataEMUL.value in { 3885 foreach nf = NFSet<dataEMUL>.L in { 3886 defvar Vreg = SegRegClass<dataEMUL, nf>.RC; 3887 def nf # "EI" # idxEEW # "_V_" # IdxLInfo # "_" # DataLInfo : 3888 VPseudoISegLoadNoMask<Vreg, IdxVreg, idxEEW, idxEMUL.value, 3889 nf, Ordered>, 3890 VLXSEGSched<nf, dataEEW, Ordered, DataLInfo>; 3891 def nf # "EI" # idxEEW # "_V_" # IdxLInfo # "_" # DataLInfo # "_MASK" : 3892 VPseudoISegLoadMask<Vreg, IdxVreg, idxEEW, idxEMUL.value, 3893 nf, Ordered>, 3894 VLXSEGSched<nf, dataEEW, Ordered, DataLInfo>; 3895 } 3896 } 3897 } 3898 } 3899 } 3900 } 3901} 3902 3903multiclass VPseudoUSSegStore { 3904 foreach eew = EEWList in { 3905 foreach lmul = MxSet<eew>.m in { 3906 defvar LInfo = lmul.MX; 3907 let VLMul = lmul.value, SEW=eew in { 3908 foreach nf = NFSet<lmul>.L in { 3909 defvar vreg = SegRegClass<lmul, nf>.RC; 3910 def nf # "E" # eew # "_V_" # LInfo : VPseudoUSSegStoreNoMask<vreg, eew, nf>, 3911 VSSEGSched<nf, eew, LInfo>; 3912 def nf # "E" # eew # "_V_" # LInfo # "_MASK" : VPseudoUSSegStoreMask<vreg, eew, nf>, 3913 VSSEGSched<nf, eew, LInfo>; 3914 } 3915 } 3916 } 3917 } 3918} 3919 3920multiclass VPseudoSSegStore { 3921 foreach eew = EEWList in { 3922 foreach lmul = MxSet<eew>.m in { 3923 defvar LInfo = lmul.MX; 3924 let VLMul = lmul.value, SEW=eew in { 3925 foreach nf = NFSet<lmul>.L in { 3926 defvar vreg = SegRegClass<lmul, nf>.RC; 3927 def nf # "E" # eew # "_V_" # LInfo : VPseudoSSegStoreNoMask<vreg, eew, nf>, 3928 VSSSEGSched<nf, eew, LInfo>; 3929 def nf # "E" # eew # "_V_" # LInfo # "_MASK" : VPseudoSSegStoreMask<vreg, eew, nf>, 3930 VSSSEGSched<nf, eew, LInfo>; 3931 } 3932 } 3933 } 3934 } 3935} 3936 3937multiclass VPseudoISegStore<bit Ordered> { 3938 foreach idxEEW = EEWList in { 3939 foreach dataEEW = EEWList in { 3940 foreach dataEMUL = MxSet<dataEEW>.m in { 3941 defvar dataEMULOctuple = dataEMUL.octuple; 3942 // Calculate emul = eew * lmul / sew 3943 defvar idxEMULOctuple = !srl(!mul(idxEEW, dataEMULOctuple), !logtwo(dataEEW)); 3944 if !and(!ge(idxEMULOctuple, 1), !le(idxEMULOctuple, 64)) then { 3945 defvar DataLInfo = dataEMUL.MX; 3946 defvar IdxLInfo = octuple_to_str<idxEMULOctuple>.ret; 3947 defvar idxEMUL = !cast<LMULInfo>("V_" # IdxLInfo); 3948 defvar DataVreg = dataEMUL.vrclass; 3949 defvar IdxVreg = idxEMUL.vrclass; 3950 let VLMul = dataEMUL.value in { 3951 foreach nf = NFSet<dataEMUL>.L in { 3952 defvar Vreg = SegRegClass<dataEMUL, nf>.RC; 3953 def nf # "EI" # idxEEW # "_V_" # IdxLInfo # "_" # DataLInfo : 3954 VPseudoISegStoreNoMask<Vreg, IdxVreg, idxEEW, idxEMUL.value, 3955 nf, Ordered>, 3956 VSXSEGSched<nf, idxEEW, Ordered, DataLInfo>; 3957 def nf # "EI" # idxEEW # "_V_" # IdxLInfo # "_" # DataLInfo # "_MASK" : 3958 VPseudoISegStoreMask<Vreg, IdxVreg, idxEEW, idxEMUL.value, 3959 nf, Ordered>, 3960 VSXSEGSched<nf, idxEEW, Ordered, DataLInfo>; 3961 } 3962 } 3963 } 3964 } 3965 } 3966 } 3967} 3968 3969//===----------------------------------------------------------------------===// 3970// Helpers to define the intrinsic patterns. 3971//===----------------------------------------------------------------------===// 3972 3973class VPatUnaryNoMask<string intrinsic_name, 3974 string inst, 3975 string kind, 3976 ValueType result_type, 3977 ValueType op2_type, 3978 int log2sew, 3979 LMULInfo vlmul, 3980 VReg result_reg_class, 3981 VReg op2_reg_class> : 3982 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 3983 (result_type result_reg_class:$merge), 3984 (op2_type op2_reg_class:$rs2), 3985 VLOpFrag)), 3986 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX) 3987 (result_type result_reg_class:$merge), 3988 (op2_type op2_reg_class:$rs2), 3989 GPR:$vl, log2sew, TU_MU)>; 3990 3991class VPatUnaryNoMaskRoundingMode<string intrinsic_name, 3992 string inst, 3993 string kind, 3994 ValueType result_type, 3995 ValueType op2_type, 3996 int log2sew, 3997 LMULInfo vlmul, 3998 VReg result_reg_class, 3999 VReg op2_reg_class, 4000 bit isSEWAware = 0> : 4001 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 4002 (result_type result_reg_class:$merge), 4003 (op2_type op2_reg_class:$rs2), 4004 (XLenVT timm:$round), 4005 VLOpFrag)), 4006 (!cast<Instruction>( 4007 !if(isSEWAware, 4008 inst#"_"#kind#"_"#vlmul.MX#"_E"#!shl(1, log2sew), 4009 inst#"_"#kind#"_"#vlmul.MX)) 4010 (result_type result_reg_class:$merge), 4011 (op2_type op2_reg_class:$rs2), 4012 (XLenVT timm:$round), 4013 GPR:$vl, log2sew, TU_MU)>; 4014 4015 4016class VPatUnaryMask<string intrinsic_name, 4017 string inst, 4018 string kind, 4019 ValueType result_type, 4020 ValueType op2_type, 4021 ValueType mask_type, 4022 int log2sew, 4023 LMULInfo vlmul, 4024 VReg result_reg_class, 4025 VReg op2_reg_class> : 4026 Pat<(result_type (!cast<Intrinsic>(intrinsic_name#"_mask") 4027 (result_type result_reg_class:$merge), 4028 (op2_type op2_reg_class:$rs2), 4029 (mask_type V0), 4030 VLOpFrag, (XLenVT timm:$policy))), 4031 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX#"_MASK") 4032 (result_type result_reg_class:$merge), 4033 (op2_type op2_reg_class:$rs2), 4034 (mask_type V0), GPR:$vl, log2sew, (XLenVT timm:$policy))>; 4035 4036class VPatUnaryMaskRoundingMode<string intrinsic_name, 4037 string inst, 4038 string kind, 4039 ValueType result_type, 4040 ValueType op2_type, 4041 ValueType mask_type, 4042 int log2sew, 4043 LMULInfo vlmul, 4044 VReg result_reg_class, 4045 VReg op2_reg_class, 4046 bit isSEWAware = 0> : 4047 Pat<(result_type (!cast<Intrinsic>(intrinsic_name#"_mask") 4048 (result_type result_reg_class:$merge), 4049 (op2_type op2_reg_class:$rs2), 4050 (mask_type V0), 4051 (XLenVT timm:$round), 4052 VLOpFrag, (XLenVT timm:$policy))), 4053 (!cast<Instruction>( 4054 !if(isSEWAware, 4055 inst#"_"#kind#"_"#vlmul.MX#"_E"#!shl(1, log2sew)#"_MASK", 4056 inst#"_"#kind#"_"#vlmul.MX#"_MASK")) 4057 (result_type result_reg_class:$merge), 4058 (op2_type op2_reg_class:$rs2), 4059 (mask_type V0), 4060 (XLenVT timm:$round), 4061 GPR:$vl, log2sew, (XLenVT timm:$policy))>; 4062 4063 4064class VPatMaskUnaryNoMask<string intrinsic_name, 4065 string inst, 4066 MTypeInfo mti> : 4067 Pat<(mti.Mask (!cast<Intrinsic>(intrinsic_name) 4068 (mti.Mask VR:$rs2), 4069 VLOpFrag)), 4070 (!cast<Instruction>(inst#"_M_"#mti.BX) 4071 (mti.Mask (IMPLICIT_DEF)), 4072 (mti.Mask VR:$rs2), 4073 GPR:$vl, mti.Log2SEW, TA_MA)>; 4074 4075class VPatMaskUnaryMask<string intrinsic_name, 4076 string inst, 4077 MTypeInfo mti> : 4078 Pat<(mti.Mask (!cast<Intrinsic>(intrinsic_name#"_mask") 4079 (mti.Mask VR:$merge), 4080 (mti.Mask VR:$rs2), 4081 (mti.Mask V0), 4082 VLOpFrag)), 4083 (!cast<Instruction>(inst#"_M_"#mti.BX#"_MASK") 4084 (mti.Mask VR:$merge), 4085 (mti.Mask VR:$rs2), 4086 (mti.Mask V0), GPR:$vl, mti.Log2SEW, TU_MU)>; 4087 4088class VPatUnaryAnyMask<string intrinsic, 4089 string inst, 4090 string kind, 4091 ValueType result_type, 4092 ValueType op1_type, 4093 ValueType mask_type, 4094 int log2sew, 4095 LMULInfo vlmul, 4096 VReg result_reg_class, 4097 VReg op1_reg_class> : 4098 Pat<(result_type (!cast<Intrinsic>(intrinsic) 4099 (result_type result_reg_class:$merge), 4100 (op1_type op1_reg_class:$rs1), 4101 (mask_type VR:$rs2), 4102 VLOpFrag)), 4103 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX#"_E"#!shl(1, log2sew)) 4104 (result_type result_reg_class:$merge), 4105 (op1_type op1_reg_class:$rs1), 4106 (mask_type VR:$rs2), 4107 GPR:$vl, log2sew)>; 4108 4109class VPatBinaryM<string intrinsic_name, 4110 string inst, 4111 ValueType result_type, 4112 ValueType op1_type, 4113 ValueType op2_type, 4114 int sew, 4115 VReg op1_reg_class, 4116 DAGOperand op2_kind> : 4117 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 4118 (op1_type op1_reg_class:$rs1), 4119 (op2_type op2_kind:$rs2), 4120 VLOpFrag)), 4121 (!cast<Instruction>(inst) 4122 (op1_type op1_reg_class:$rs1), 4123 (op2_type op2_kind:$rs2), 4124 GPR:$vl, sew)>; 4125 4126class VPatBinaryNoMaskTU<string intrinsic_name, 4127 string inst, 4128 ValueType result_type, 4129 ValueType op1_type, 4130 ValueType op2_type, 4131 int sew, 4132 VReg result_reg_class, 4133 VReg op1_reg_class, 4134 DAGOperand op2_kind> : 4135 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 4136 (result_type result_reg_class:$merge), 4137 (op1_type op1_reg_class:$rs1), 4138 (op2_type op2_kind:$rs2), 4139 VLOpFrag)), 4140 (!cast<Instruction>(inst) 4141 (result_type result_reg_class:$merge), 4142 (op1_type op1_reg_class:$rs1), 4143 (op2_type op2_kind:$rs2), 4144 GPR:$vl, sew, TU_MU)>; 4145 4146class VPatBinaryNoMaskRoundingMode<string intrinsic_name, 4147 string inst, 4148 ValueType result_type, 4149 ValueType op1_type, 4150 ValueType op2_type, 4151 int sew, 4152 VReg op1_reg_class, 4153 DAGOperand op2_kind> : 4154 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 4155 (result_type (undef)), 4156 (op1_type op1_reg_class:$rs1), 4157 (op2_type op2_kind:$rs2), 4158 (XLenVT timm:$round), 4159 VLOpFrag)), 4160 (!cast<Instruction>(inst) 4161 (result_type (IMPLICIT_DEF)), 4162 (op1_type op1_reg_class:$rs1), 4163 (op2_type op2_kind:$rs2), 4164 (XLenVT timm:$round), 4165 GPR:$vl, sew, TA_MA)>; 4166 4167class VPatBinaryNoMaskTURoundingMode<string intrinsic_name, 4168 string inst, 4169 ValueType result_type, 4170 ValueType op1_type, 4171 ValueType op2_type, 4172 int sew, 4173 VReg result_reg_class, 4174 VReg op1_reg_class, 4175 DAGOperand op2_kind> : 4176 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 4177 (result_type result_reg_class:$merge), 4178 (op1_type op1_reg_class:$rs1), 4179 (op2_type op2_kind:$rs2), 4180 (XLenVT timm:$round), 4181 VLOpFrag)), 4182 (!cast<Instruction>(inst) 4183 (result_type result_reg_class:$merge), 4184 (op1_type op1_reg_class:$rs1), 4185 (op2_type op2_kind:$rs2), 4186 (XLenVT timm:$round), 4187 GPR:$vl, sew, TU_MU)>; 4188 4189 4190// Same as above but source operands are swapped. 4191class VPatBinaryNoMaskSwapped<string intrinsic_name, 4192 string inst, 4193 ValueType result_type, 4194 ValueType op1_type, 4195 ValueType op2_type, 4196 int sew, 4197 VReg op1_reg_class, 4198 DAGOperand op2_kind> : 4199 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 4200 (op2_type op2_kind:$rs2), 4201 (op1_type op1_reg_class:$rs1), 4202 VLOpFrag)), 4203 (!cast<Instruction>(inst) 4204 (op1_type op1_reg_class:$rs1), 4205 (op2_type op2_kind:$rs2), 4206 GPR:$vl, sew)>; 4207 4208class VPatBinaryMask<string intrinsic_name, 4209 string inst, 4210 ValueType result_type, 4211 ValueType op1_type, 4212 ValueType op2_type, 4213 ValueType mask_type, 4214 int sew, 4215 VReg result_reg_class, 4216 VReg op1_reg_class, 4217 DAGOperand op2_kind> : 4218 Pat<(result_type (!cast<Intrinsic>(intrinsic_name#"_mask") 4219 (result_type result_reg_class:$merge), 4220 (op1_type op1_reg_class:$rs1), 4221 (op2_type op2_kind:$rs2), 4222 (mask_type V0), 4223 VLOpFrag)), 4224 (!cast<Instruction>(inst#"_MASK") 4225 (result_type result_reg_class:$merge), 4226 (op1_type op1_reg_class:$rs1), 4227 (op2_type op2_kind:$rs2), 4228 (mask_type V0), GPR:$vl, sew)>; 4229 4230class VPatBinaryMaskTA<string intrinsic_name, 4231 string inst, 4232 ValueType result_type, 4233 ValueType op1_type, 4234 ValueType op2_type, 4235 ValueType mask_type, 4236 int sew, 4237 VReg result_reg_class, 4238 VReg op1_reg_class, 4239 DAGOperand op2_kind> : 4240 Pat<(result_type (!cast<Intrinsic>(intrinsic_name#"_mask") 4241 (result_type result_reg_class:$merge), 4242 (op1_type op1_reg_class:$rs1), 4243 (op2_type op2_kind:$rs2), 4244 (mask_type V0), 4245 VLOpFrag, (XLenVT timm:$policy))), 4246 (!cast<Instruction>(inst#"_MASK") 4247 (result_type result_reg_class:$merge), 4248 (op1_type op1_reg_class:$rs1), 4249 (op2_type op2_kind:$rs2), 4250 (mask_type V0), GPR:$vl, sew, (XLenVT timm:$policy))>; 4251 4252class VPatBinaryMaskTARoundingMode<string intrinsic_name, 4253 string inst, 4254 ValueType result_type, 4255 ValueType op1_type, 4256 ValueType op2_type, 4257 ValueType mask_type, 4258 int sew, 4259 VReg result_reg_class, 4260 VReg op1_reg_class, 4261 DAGOperand op2_kind> : 4262 Pat<(result_type (!cast<Intrinsic>(intrinsic_name#"_mask") 4263 (result_type result_reg_class:$merge), 4264 (op1_type op1_reg_class:$rs1), 4265 (op2_type op2_kind:$rs2), 4266 (mask_type V0), 4267 (XLenVT timm:$round), 4268 VLOpFrag, (XLenVT timm:$policy))), 4269 (!cast<Instruction>(inst#"_MASK") 4270 (result_type result_reg_class:$merge), 4271 (op1_type op1_reg_class:$rs1), 4272 (op2_type op2_kind:$rs2), 4273 (mask_type V0), 4274 (XLenVT timm:$round), 4275 GPR:$vl, sew, (XLenVT timm:$policy))>; 4276 4277// Same as above but source operands are swapped. 4278class VPatBinaryMaskSwapped<string intrinsic_name, 4279 string inst, 4280 ValueType result_type, 4281 ValueType op1_type, 4282 ValueType op2_type, 4283 ValueType mask_type, 4284 int sew, 4285 VReg result_reg_class, 4286 VReg op1_reg_class, 4287 DAGOperand op2_kind> : 4288 Pat<(result_type (!cast<Intrinsic>(intrinsic_name#"_mask") 4289 (result_type result_reg_class:$merge), 4290 (op2_type op2_kind:$rs2), 4291 (op1_type op1_reg_class:$rs1), 4292 (mask_type V0), 4293 VLOpFrag)), 4294 (!cast<Instruction>(inst#"_MASK") 4295 (result_type result_reg_class:$merge), 4296 (op1_type op1_reg_class:$rs1), 4297 (op2_type op2_kind:$rs2), 4298 (mask_type V0), GPR:$vl, sew)>; 4299 4300class VPatTiedBinaryNoMask<string intrinsic_name, 4301 string inst, 4302 ValueType result_type, 4303 ValueType op2_type, 4304 int sew, 4305 VReg result_reg_class, 4306 DAGOperand op2_kind> : 4307 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 4308 (result_type (undef)), 4309 (result_type result_reg_class:$rs1), 4310 (op2_type op2_kind:$rs2), 4311 VLOpFrag)), 4312 (!cast<Instruction>(inst#"_TIED") 4313 (result_type result_reg_class:$rs1), 4314 (op2_type op2_kind:$rs2), 4315 GPR:$vl, sew, TAIL_AGNOSTIC)>; 4316 4317class VPatTiedBinaryNoMaskRoundingMode<string intrinsic_name, 4318 string inst, 4319 ValueType result_type, 4320 ValueType op2_type, 4321 int sew, 4322 VReg result_reg_class, 4323 DAGOperand op2_kind> : 4324 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 4325 (result_type (undef)), 4326 (result_type result_reg_class:$rs1), 4327 (op2_type op2_kind:$rs2), 4328 (XLenVT timm:$round), 4329 VLOpFrag)), 4330 (!cast<Instruction>(inst#"_TIED") 4331 (result_type result_reg_class:$rs1), 4332 (op2_type op2_kind:$rs2), 4333 (XLenVT timm:$round), 4334 GPR:$vl, sew, TAIL_AGNOSTIC)>; 4335 4336class VPatTiedBinaryNoMaskTU<string intrinsic_name, 4337 string inst, 4338 ValueType result_type, 4339 ValueType op2_type, 4340 int sew, 4341 VReg result_reg_class, 4342 DAGOperand op2_kind> : 4343 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 4344 (result_type result_reg_class:$merge), 4345 (result_type result_reg_class:$merge), 4346 (op2_type op2_kind:$rs2), 4347 VLOpFrag)), 4348 (!cast<Instruction>(inst#"_TIED") 4349 (result_type result_reg_class:$merge), 4350 (op2_type op2_kind:$rs2), 4351 GPR:$vl, sew, TU_MU)>; 4352 4353class VPatTiedBinaryNoMaskTURoundingMode<string intrinsic_name, 4354 string inst, 4355 ValueType result_type, 4356 ValueType op2_type, 4357 int sew, 4358 VReg result_reg_class, 4359 DAGOperand op2_kind> : 4360 Pat<(result_type (!cast<Intrinsic>(intrinsic_name) 4361 (result_type result_reg_class:$merge), 4362 (result_type result_reg_class:$merge), 4363 (op2_type op2_kind:$rs2), 4364 (XLenVT timm:$round), 4365 VLOpFrag)), 4366 (!cast<Instruction>(inst#"_TIED") 4367 (result_type result_reg_class:$merge), 4368 (op2_type op2_kind:$rs2), 4369 (XLenVT timm:$round), 4370 GPR:$vl, sew, TU_MU)>; 4371 4372class VPatTiedBinaryMask<string intrinsic_name, 4373 string inst, 4374 ValueType result_type, 4375 ValueType op2_type, 4376 ValueType mask_type, 4377 int sew, 4378 VReg result_reg_class, 4379 DAGOperand op2_kind> : 4380 Pat<(result_type (!cast<Intrinsic>(intrinsic_name#"_mask") 4381 (result_type result_reg_class:$merge), 4382 (result_type result_reg_class:$merge), 4383 (op2_type op2_kind:$rs2), 4384 (mask_type V0), 4385 VLOpFrag, (XLenVT timm:$policy))), 4386 (!cast<Instruction>(inst#"_MASK_TIED") 4387 (result_type result_reg_class:$merge), 4388 (op2_type op2_kind:$rs2), 4389 (mask_type V0), GPR:$vl, sew, (XLenVT timm:$policy))>; 4390 4391class VPatTiedBinaryMaskRoundingMode<string intrinsic_name, 4392 string inst, 4393 ValueType result_type, 4394 ValueType op2_type, 4395 ValueType mask_type, 4396 int sew, 4397 VReg result_reg_class, 4398 DAGOperand op2_kind> : 4399 Pat<(result_type (!cast<Intrinsic>(intrinsic_name#"_mask") 4400 (result_type result_reg_class:$merge), 4401 (result_type result_reg_class:$merge), 4402 (op2_type op2_kind:$rs2), 4403 (mask_type V0), 4404 (XLenVT timm:$round), 4405 VLOpFrag, (XLenVT timm:$policy))), 4406 (!cast<Instruction>(inst#"_MASK_TIED") 4407 (result_type result_reg_class:$merge), 4408 (op2_type op2_kind:$rs2), 4409 (mask_type V0), 4410 (XLenVT timm:$round), 4411 GPR:$vl, sew, (XLenVT timm:$policy))>; 4412 4413class VPatTernaryNoMask<string intrinsic, 4414 string inst, 4415 string kind, 4416 ValueType result_type, 4417 ValueType op1_type, 4418 ValueType op2_type, 4419 int sew, 4420 LMULInfo vlmul, 4421 VReg result_reg_class, 4422 RegisterClass op1_reg_class, 4423 DAGOperand op2_kind> : 4424 Pat<(result_type (!cast<Intrinsic>(intrinsic) 4425 (result_type result_reg_class:$rs3), 4426 (op1_type op1_reg_class:$rs1), 4427 (op2_type op2_kind:$rs2), 4428 VLOpFrag)), 4429 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX) 4430 result_reg_class:$rs3, 4431 (op1_type op1_reg_class:$rs1), 4432 op2_kind:$rs2, 4433 GPR:$vl, sew)>; 4434 4435class VPatTernaryNoMaskTA<string intrinsic, 4436 string inst, 4437 string kind, 4438 ValueType result_type, 4439 ValueType op1_type, 4440 ValueType op2_type, 4441 int log2sew, 4442 LMULInfo vlmul, 4443 VReg result_reg_class, 4444 RegisterClass op1_reg_class, 4445 DAGOperand op2_kind> : 4446 Pat<(result_type (!cast<Intrinsic>(intrinsic) 4447 (result_type result_reg_class:$rs3), 4448 (op1_type op1_reg_class:$rs1), 4449 (op2_type op2_kind:$rs2), 4450 VLOpFrag)), 4451 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX#"_E"#!shl(1, log2sew)) 4452 result_reg_class:$rs3, 4453 (op1_type op1_reg_class:$rs1), 4454 op2_kind:$rs2, 4455 GPR:$vl, log2sew, TAIL_AGNOSTIC)>; 4456 4457class VPatTernaryNoMaskTARoundingMode<string intrinsic, 4458 string inst, 4459 string kind, 4460 ValueType result_type, 4461 ValueType op1_type, 4462 ValueType op2_type, 4463 int log2sew, 4464 LMULInfo vlmul, 4465 VReg result_reg_class, 4466 RegisterClass op1_reg_class, 4467 DAGOperand op2_kind> : 4468 Pat<(result_type (!cast<Intrinsic>(intrinsic) 4469 (result_type result_reg_class:$rs3), 4470 (op1_type op1_reg_class:$rs1), 4471 (op2_type op2_kind:$rs2), 4472 (XLenVT timm:$round), 4473 VLOpFrag)), 4474 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX#"_E"#!shl(1, log2sew)) 4475 result_reg_class:$rs3, 4476 (op1_type op1_reg_class:$rs1), 4477 op2_kind:$rs2, 4478 (XLenVT timm:$round), 4479 GPR:$vl, log2sew, TAIL_AGNOSTIC)>; 4480 4481class VPatTernaryNoMaskWithPolicy<string intrinsic, 4482 string inst, 4483 string kind, 4484 ValueType result_type, 4485 ValueType op1_type, 4486 ValueType op2_type, 4487 int sew, 4488 LMULInfo vlmul, 4489 VReg result_reg_class, 4490 RegisterClass op1_reg_class, 4491 DAGOperand op2_kind> : 4492 Pat<(result_type (!cast<Intrinsic>(intrinsic) 4493 (result_type result_reg_class:$rs3), 4494 (op1_type op1_reg_class:$rs1), 4495 (op2_type op2_kind:$rs2), 4496 VLOpFrag, (XLenVT timm:$policy))), 4497 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX) 4498 result_reg_class:$rs3, 4499 (op1_type op1_reg_class:$rs1), 4500 op2_kind:$rs2, 4501 GPR:$vl, sew, (XLenVT timm:$policy))>; 4502 4503class VPatTernaryNoMaskWithPolicyRoundingMode<string intrinsic, 4504 string inst, 4505 string kind, 4506 ValueType result_type, 4507 ValueType op1_type, 4508 ValueType op2_type, 4509 int sew, 4510 LMULInfo vlmul, 4511 VReg result_reg_class, 4512 RegisterClass op1_reg_class, 4513 DAGOperand op2_kind> : 4514 Pat<(result_type (!cast<Intrinsic>(intrinsic) 4515 (result_type result_reg_class:$rs3), 4516 (op1_type op1_reg_class:$rs1), 4517 (op2_type op2_kind:$rs2), 4518 (XLenVT timm:$round), 4519 VLOpFrag, (XLenVT timm:$policy))), 4520 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX) 4521 result_reg_class:$rs3, 4522 (op1_type op1_reg_class:$rs1), 4523 op2_kind:$rs2, 4524 (XLenVT timm:$round), 4525 GPR:$vl, sew, (XLenVT timm:$policy))>; 4526 4527class VPatTernaryMask<string intrinsic, 4528 string inst, 4529 string kind, 4530 ValueType result_type, 4531 ValueType op1_type, 4532 ValueType op2_type, 4533 ValueType mask_type, 4534 int sew, 4535 LMULInfo vlmul, 4536 VReg result_reg_class, 4537 RegisterClass op1_reg_class, 4538 DAGOperand op2_kind> : 4539 Pat<(result_type (!cast<Intrinsic>(intrinsic#"_mask") 4540 (result_type result_reg_class:$rs3), 4541 (op1_type op1_reg_class:$rs1), 4542 (op2_type op2_kind:$rs2), 4543 (mask_type V0), 4544 VLOpFrag)), 4545 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX # "_MASK") 4546 result_reg_class:$rs3, 4547 (op1_type op1_reg_class:$rs1), 4548 op2_kind:$rs2, 4549 (mask_type V0), 4550 GPR:$vl, sew)>; 4551 4552class VPatTernaryMaskPolicy<string intrinsic, 4553 string inst, 4554 string kind, 4555 ValueType result_type, 4556 ValueType op1_type, 4557 ValueType op2_type, 4558 ValueType mask_type, 4559 int sew, 4560 LMULInfo vlmul, 4561 VReg result_reg_class, 4562 RegisterClass op1_reg_class, 4563 DAGOperand op2_kind> : 4564 Pat<(result_type (!cast<Intrinsic>(intrinsic#"_mask") 4565 (result_type result_reg_class:$rs3), 4566 (op1_type op1_reg_class:$rs1), 4567 (op2_type op2_kind:$rs2), 4568 (mask_type V0), 4569 VLOpFrag, (XLenVT timm:$policy))), 4570 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX # "_MASK") 4571 result_reg_class:$rs3, 4572 (op1_type op1_reg_class:$rs1), 4573 op2_kind:$rs2, 4574 (mask_type V0), 4575 GPR:$vl, sew, (XLenVT timm:$policy))>; 4576 4577class VPatTernaryMaskPolicyRoundingMode<string intrinsic, 4578 string inst, 4579 string kind, 4580 ValueType result_type, 4581 ValueType op1_type, 4582 ValueType op2_type, 4583 ValueType mask_type, 4584 int sew, 4585 LMULInfo vlmul, 4586 VReg result_reg_class, 4587 RegisterClass op1_reg_class, 4588 DAGOperand op2_kind> : 4589 Pat<(result_type (!cast<Intrinsic>(intrinsic#"_mask") 4590 (result_type result_reg_class:$rs3), 4591 (op1_type op1_reg_class:$rs1), 4592 (op2_type op2_kind:$rs2), 4593 (mask_type V0), 4594 (XLenVT timm:$round), 4595 VLOpFrag, (XLenVT timm:$policy))), 4596 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX # "_MASK") 4597 result_reg_class:$rs3, 4598 (op1_type op1_reg_class:$rs1), 4599 op2_kind:$rs2, 4600 (mask_type V0), 4601 (XLenVT timm:$round), 4602 GPR:$vl, sew, (XLenVT timm:$policy))>; 4603 4604class VPatTernaryMaskTA<string intrinsic, 4605 string inst, 4606 string kind, 4607 ValueType result_type, 4608 ValueType op1_type, 4609 ValueType op2_type, 4610 ValueType mask_type, 4611 int log2sew, 4612 LMULInfo vlmul, 4613 VReg result_reg_class, 4614 RegisterClass op1_reg_class, 4615 DAGOperand op2_kind> : 4616 Pat<(result_type (!cast<Intrinsic>(intrinsic#"_mask") 4617 (result_type result_reg_class:$rs3), 4618 (op1_type op1_reg_class:$rs1), 4619 (op2_type op2_kind:$rs2), 4620 (mask_type V0), 4621 VLOpFrag)), 4622 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX#"_E"#!shl(1, log2sew)# "_MASK") 4623 result_reg_class:$rs3, 4624 (op1_type op1_reg_class:$rs1), 4625 op2_kind:$rs2, 4626 (mask_type V0), 4627 GPR:$vl, log2sew, TAIL_AGNOSTIC)>; 4628 4629class VPatTernaryMaskTARoundingMode<string intrinsic, 4630 string inst, 4631 string kind, 4632 ValueType result_type, 4633 ValueType op1_type, 4634 ValueType op2_type, 4635 ValueType mask_type, 4636 int log2sew, 4637 LMULInfo vlmul, 4638 VReg result_reg_class, 4639 RegisterClass op1_reg_class, 4640 DAGOperand op2_kind> : 4641 Pat<(result_type (!cast<Intrinsic>(intrinsic#"_mask") 4642 (result_type result_reg_class:$rs3), 4643 (op1_type op1_reg_class:$rs1), 4644 (op2_type op2_kind:$rs2), 4645 (mask_type V0), 4646 (XLenVT timm:$round), 4647 VLOpFrag)), 4648 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX#"_E"#!shl(1, log2sew)# "_MASK") 4649 result_reg_class:$rs3, 4650 (op1_type op1_reg_class:$rs1), 4651 op2_kind:$rs2, 4652 (mask_type V0), 4653 (XLenVT timm:$round), 4654 GPR:$vl, log2sew, TAIL_AGNOSTIC)>; 4655 4656multiclass VPatUnaryS_M<string intrinsic_name, 4657 string inst> { 4658 foreach mti = AllMasks in { 4659 def : Pat<(XLenVT (!cast<Intrinsic>(intrinsic_name) 4660 (mti.Mask VR:$rs1), VLOpFrag)), 4661 (!cast<Instruction>(inst#"_M_"#mti.BX) $rs1, 4662 GPR:$vl, mti.Log2SEW)>; 4663 def : Pat<(XLenVT (!cast<Intrinsic>(intrinsic_name # "_mask") 4664 (mti.Mask VR:$rs1), (mti.Mask V0), VLOpFrag)), 4665 (!cast<Instruction>(inst#"_M_"#mti.BX#"_MASK") $rs1, 4666 (mti.Mask V0), GPR:$vl, mti.Log2SEW)>; 4667 } 4668} 4669 4670multiclass VPatUnaryV_V_AnyMask<string intrinsic, string instruction, 4671 list<VTypeInfo> vtilist> { 4672 foreach vti = vtilist in { 4673 let Predicates = GetVTypePredicates<vti>.Predicates in 4674 def : VPatUnaryAnyMask<intrinsic, instruction, "VM", 4675 vti.Vector, vti.Vector, vti.Mask, 4676 vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass>; 4677 } 4678} 4679 4680multiclass VPatUnaryM_M<string intrinsic, 4681 string inst> { 4682 foreach mti = AllMasks in { 4683 def : VPatMaskUnaryNoMask<intrinsic, inst, mti>; 4684 def : VPatMaskUnaryMask<intrinsic, inst, mti>; 4685 } 4686} 4687 4688multiclass VPatUnaryV_M<string intrinsic, string instruction> { 4689 foreach vti = AllIntegerVectors in { 4690 let Predicates = GetVTypePredicates<vti>.Predicates in { 4691 def : VPatUnaryNoMask<intrinsic, instruction, "M", vti.Vector, vti.Mask, 4692 vti.Log2SEW, vti.LMul, vti.RegClass, VR>; 4693 def : VPatUnaryMask<intrinsic, instruction, "M", vti.Vector, vti.Mask, 4694 vti.Mask, vti.Log2SEW, vti.LMul, vti.RegClass, VR>; 4695 } 4696 } 4697} 4698 4699multiclass VPatUnaryV_VF<string intrinsic, string instruction, string suffix, 4700 list<VTypeInfoToFraction> fractionList> { 4701 foreach vtiTofti = fractionList in { 4702 defvar vti = vtiTofti.Vti; 4703 defvar fti = vtiTofti.Fti; 4704 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 4705 GetVTypePredicates<fti>.Predicates) in { 4706 def : VPatUnaryNoMask<intrinsic, instruction, suffix, 4707 vti.Vector, fti.Vector, 4708 vti.Log2SEW, vti.LMul, vti.RegClass, fti.RegClass>; 4709 def : VPatUnaryMask<intrinsic, instruction, suffix, 4710 vti.Vector, fti.Vector, vti.Mask, 4711 vti.Log2SEW, vti.LMul, vti.RegClass, fti.RegClass>; 4712 } 4713 } 4714} 4715 4716multiclass VPatUnaryV_V<string intrinsic, string instruction, 4717 list<VTypeInfo> vtilist> { 4718 foreach vti = vtilist in { 4719 let Predicates = GetVTypePredicates<vti>.Predicates in { 4720 def : VPatUnaryNoMask<intrinsic, instruction, "V", 4721 vti.Vector, vti.Vector, vti.Log2SEW, 4722 vti.LMul, vti.RegClass, vti.RegClass>; 4723 def : VPatUnaryMask<intrinsic, instruction, "V", 4724 vti.Vector, vti.Vector, vti.Mask, vti.Log2SEW, 4725 vti.LMul, vti.RegClass, vti.RegClass>; 4726 } 4727 } 4728} 4729 4730multiclass VPatUnaryV_V_RM<string intrinsic, string instruction, 4731 list<VTypeInfo> vtilist, bit isSEWAware = 0> { 4732 foreach vti = vtilist in { 4733 let Predicates = GetVTypePredicates<vti>.Predicates in { 4734 def : VPatUnaryNoMaskRoundingMode<intrinsic, instruction, "V", 4735 vti.Vector, vti.Vector, vti.Log2SEW, 4736 vti.LMul, vti.RegClass, vti.RegClass, isSEWAware>; 4737 def : VPatUnaryMaskRoundingMode<intrinsic, instruction, "V", 4738 vti.Vector, vti.Vector, vti.Mask, vti.Log2SEW, 4739 vti.LMul, vti.RegClass, vti.RegClass, isSEWAware>; 4740 } 4741 } 4742} 4743 4744multiclass VPatNullaryV<string intrinsic, string instruction> { 4745 foreach vti = AllIntegerVectors in { 4746 let Predicates = GetVTypePredicates<vti>.Predicates in { 4747 def : Pat<(vti.Vector (!cast<Intrinsic>(intrinsic) 4748 (vti.Vector vti.RegClass:$merge), 4749 VLOpFrag)), 4750 (!cast<Instruction>(instruction#"_V_" # vti.LMul.MX) 4751 vti.RegClass:$merge, GPR:$vl, vti.Log2SEW, TU_MU)>; 4752 def : Pat<(vti.Vector (!cast<Intrinsic>(intrinsic # "_mask") 4753 (vti.Vector vti.RegClass:$merge), 4754 (vti.Mask V0), VLOpFrag, (XLenVT timm:$policy))), 4755 (!cast<Instruction>(instruction#"_V_" # vti.LMul.MX # "_MASK") 4756 vti.RegClass:$merge, (vti.Mask V0), 4757 GPR:$vl, vti.Log2SEW, (XLenVT timm:$policy))>; 4758 } 4759 } 4760} 4761 4762multiclass VPatNullaryM<string intrinsic, string inst> { 4763 foreach mti = AllMasks in 4764 def : Pat<(mti.Mask (!cast<Intrinsic>(intrinsic) 4765 VLOpFrag)), 4766 (!cast<Instruction>(inst#"_M_"#mti.BX) 4767 GPR:$vl, mti.Log2SEW)>; 4768} 4769 4770multiclass VPatBinaryM<string intrinsic, 4771 string inst, 4772 ValueType result_type, 4773 ValueType op1_type, 4774 ValueType op2_type, 4775 ValueType mask_type, 4776 int sew, 4777 VReg result_reg_class, 4778 VReg op1_reg_class, 4779 DAGOperand op2_kind> { 4780 def : VPatBinaryM<intrinsic, inst, result_type, op1_type, op2_type, 4781 sew, op1_reg_class, op2_kind>; 4782 def : VPatBinaryMask<intrinsic, inst, result_type, op1_type, op2_type, 4783 mask_type, sew, result_reg_class, op1_reg_class, 4784 op2_kind>; 4785} 4786 4787multiclass VPatBinary<string intrinsic, 4788 string inst, 4789 ValueType result_type, 4790 ValueType op1_type, 4791 ValueType op2_type, 4792 ValueType mask_type, 4793 int sew, 4794 VReg result_reg_class, 4795 VReg op1_reg_class, 4796 DAGOperand op2_kind> { 4797 def : VPatBinaryNoMaskTU<intrinsic, inst, result_type, op1_type, op2_type, 4798 sew, result_reg_class, op1_reg_class, op2_kind>; 4799 def : VPatBinaryMaskTA<intrinsic, inst, result_type, op1_type, op2_type, 4800 mask_type, sew, result_reg_class, op1_reg_class, 4801 op2_kind>; 4802} 4803 4804multiclass VPatBinaryRoundingMode<string intrinsic, 4805 string inst, 4806 ValueType result_type, 4807 ValueType op1_type, 4808 ValueType op2_type, 4809 ValueType mask_type, 4810 int sew, 4811 VReg result_reg_class, 4812 VReg op1_reg_class, 4813 DAGOperand op2_kind> { 4814 def : VPatBinaryNoMaskRoundingMode<intrinsic, inst, result_type, op1_type, op2_type, 4815 sew, op1_reg_class, op2_kind>; 4816 def : VPatBinaryNoMaskTURoundingMode<intrinsic, inst, result_type, op1_type, op2_type, 4817 sew, result_reg_class, op1_reg_class, op2_kind>; 4818 def : VPatBinaryMaskTARoundingMode<intrinsic, inst, result_type, op1_type, op2_type, 4819 mask_type, sew, result_reg_class, op1_reg_class, 4820 op2_kind>; 4821} 4822 4823multiclass VPatBinarySwapped<string intrinsic, 4824 string inst, 4825 ValueType result_type, 4826 ValueType op1_type, 4827 ValueType op2_type, 4828 ValueType mask_type, 4829 int sew, 4830 VReg result_reg_class, 4831 VReg op1_reg_class, 4832 DAGOperand op2_kind> { 4833 def : VPatBinaryNoMaskSwapped<intrinsic, inst, result_type, op1_type, op2_type, 4834 sew, op1_reg_class, op2_kind>; 4835 def : VPatBinaryMaskSwapped<intrinsic, inst, result_type, op1_type, op2_type, 4836 mask_type, sew, result_reg_class, op1_reg_class, 4837 op2_kind>; 4838} 4839 4840multiclass VPatBinaryCarryInTAIL<string intrinsic, 4841 string inst, 4842 string kind, 4843 ValueType result_type, 4844 ValueType op1_type, 4845 ValueType op2_type, 4846 ValueType mask_type, 4847 int sew, 4848 LMULInfo vlmul, 4849 VReg result_reg_class, 4850 VReg op1_reg_class, 4851 DAGOperand op2_kind> { 4852 def : Pat<(result_type (!cast<Intrinsic>(intrinsic) 4853 (result_type result_reg_class:$merge), 4854 (op1_type op1_reg_class:$rs1), 4855 (op2_type op2_kind:$rs2), 4856 (mask_type V0), 4857 VLOpFrag)), 4858 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX) 4859 (result_type result_reg_class:$merge), 4860 (op1_type op1_reg_class:$rs1), 4861 (op2_type op2_kind:$rs2), 4862 (mask_type V0), GPR:$vl, sew)>; 4863} 4864 4865multiclass VPatBinaryCarryIn<string intrinsic, 4866 string inst, 4867 string kind, 4868 ValueType result_type, 4869 ValueType op1_type, 4870 ValueType op2_type, 4871 ValueType mask_type, 4872 int sew, 4873 LMULInfo vlmul, 4874 VReg op1_reg_class, 4875 DAGOperand op2_kind> { 4876 def : Pat<(result_type (!cast<Intrinsic>(intrinsic) 4877 (op1_type op1_reg_class:$rs1), 4878 (op2_type op2_kind:$rs2), 4879 (mask_type V0), 4880 VLOpFrag)), 4881 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX) 4882 (op1_type op1_reg_class:$rs1), 4883 (op2_type op2_kind:$rs2), 4884 (mask_type V0), GPR:$vl, sew)>; 4885} 4886 4887multiclass VPatBinaryMaskOut<string intrinsic, 4888 string inst, 4889 string kind, 4890 ValueType result_type, 4891 ValueType op1_type, 4892 ValueType op2_type, 4893 int sew, 4894 LMULInfo vlmul, 4895 VReg op1_reg_class, 4896 DAGOperand op2_kind> { 4897 def : Pat<(result_type (!cast<Intrinsic>(intrinsic) 4898 (op1_type op1_reg_class:$rs1), 4899 (op2_type op2_kind:$rs2), 4900 VLOpFrag)), 4901 (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX) 4902 (op1_type op1_reg_class:$rs1), 4903 (op2_type op2_kind:$rs2), 4904 GPR:$vl, sew)>; 4905} 4906 4907multiclass VPatConversionTA<string intrinsic, 4908 string inst, 4909 string kind, 4910 ValueType result_type, 4911 ValueType op1_type, 4912 ValueType mask_type, 4913 int sew, 4914 LMULInfo vlmul, 4915 VReg result_reg_class, 4916 VReg op1_reg_class> { 4917 def : VPatUnaryNoMask<intrinsic, inst, kind, result_type, op1_type, 4918 sew, vlmul, result_reg_class, op1_reg_class>; 4919 def : VPatUnaryMask<intrinsic, inst, kind, result_type, op1_type, 4920 mask_type, sew, vlmul, result_reg_class, op1_reg_class>; 4921} 4922 4923multiclass VPatConversionTARoundingMode<string intrinsic, 4924 string inst, 4925 string kind, 4926 ValueType result_type, 4927 ValueType op1_type, 4928 ValueType mask_type, 4929 int sew, 4930 LMULInfo vlmul, 4931 VReg result_reg_class, 4932 VReg op1_reg_class> { 4933 def : VPatUnaryNoMaskRoundingMode<intrinsic, inst, kind, result_type, op1_type, 4934 sew, vlmul, result_reg_class, op1_reg_class>; 4935 def : VPatUnaryMaskRoundingMode<intrinsic, inst, kind, result_type, op1_type, 4936 mask_type, sew, vlmul, result_reg_class, op1_reg_class>; 4937} 4938 4939multiclass VPatBinaryV_VV<string intrinsic, string instruction, 4940 list<VTypeInfo> vtilist, bit isSEWAware = 0> { 4941 foreach vti = vtilist in 4942 let Predicates = GetVTypePredicates<vti>.Predicates in 4943 defm : VPatBinary<intrinsic, 4944 !if(isSEWAware, 4945 instruction # "_VV_" # vti.LMul.MX # "_E" # vti.SEW, 4946 instruction # "_VV_" # vti.LMul.MX), 4947 vti.Vector, vti.Vector, vti.Vector,vti.Mask, 4948 vti.Log2SEW, vti.RegClass, 4949 vti.RegClass, vti.RegClass>; 4950} 4951 4952multiclass VPatBinaryV_VV_RM<string intrinsic, string instruction, 4953 list<VTypeInfo> vtilist, bit isSEWAware = 0> { 4954 foreach vti = vtilist in 4955 let Predicates = GetVTypePredicates<vti>.Predicates in 4956 defm : VPatBinaryRoundingMode<intrinsic, 4957 !if(isSEWAware, 4958 instruction # "_VV_" # vti.LMul.MX # "_E" # vti.SEW, 4959 instruction # "_VV_" # vti.LMul.MX), 4960 vti.Vector, vti.Vector, vti.Vector,vti.Mask, 4961 vti.Log2SEW, vti.RegClass, 4962 vti.RegClass, vti.RegClass>; 4963} 4964 4965multiclass VPatBinaryV_VV_INT<string intrinsic, string instruction, 4966 list<VTypeInfo> vtilist> { 4967 foreach vti = vtilist in { 4968 defvar ivti = GetIntVTypeInfo<vti>.Vti; 4969 let Predicates = GetVTypePredicates<vti>.Predicates in 4970 defm : VPatBinary<intrinsic, 4971 instruction # "_VV_" # vti.LMul.MX # "_E" # vti.SEW, 4972 vti.Vector, vti.Vector, ivti.Vector, vti.Mask, 4973 vti.Log2SEW, vti.RegClass, 4974 vti.RegClass, vti.RegClass>; 4975 } 4976} 4977 4978multiclass VPatBinaryV_VV_INT_EEW<string intrinsic, string instruction, 4979 int eew, list<VTypeInfo> vtilist> { 4980 foreach vti = vtilist in { 4981 // emul = lmul * eew / sew 4982 defvar vlmul = vti.LMul; 4983 defvar octuple_lmul = vlmul.octuple; 4984 defvar octuple_emul = !srl(!mul(octuple_lmul, eew), vti.Log2SEW); 4985 if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then { 4986 defvar emul_str = octuple_to_str<octuple_emul>.ret; 4987 defvar ivti = !cast<VTypeInfo>("VI" # eew # emul_str); 4988 defvar inst = instruction # "_VV_" # vti.LMul.MX # "_E" # vti.SEW # "_" # emul_str; 4989 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 4990 GetVTypePredicates<ivti>.Predicates) in 4991 defm : VPatBinary<intrinsic, inst, 4992 vti.Vector, vti.Vector, ivti.Vector, vti.Mask, 4993 vti.Log2SEW, vti.RegClass, 4994 vti.RegClass, ivti.RegClass>; 4995 } 4996 } 4997} 4998 4999multiclass VPatBinaryV_VX<string intrinsic, string instruction, 5000 list<VTypeInfo> vtilist, bit isSEWAware = 0> { 5001 foreach vti = vtilist in { 5002 defvar kind = "V"#vti.ScalarSuffix; 5003 let Predicates = GetVTypePredicates<vti>.Predicates in 5004 defm : VPatBinary<intrinsic, 5005 !if(isSEWAware, 5006 instruction#"_"#kind#"_"#vti.LMul.MX#"_E"#vti.SEW, 5007 instruction#"_"#kind#"_"#vti.LMul.MX), 5008 vti.Vector, vti.Vector, vti.Scalar, vti.Mask, 5009 vti.Log2SEW, vti.RegClass, 5010 vti.RegClass, vti.ScalarRegClass>; 5011 } 5012} 5013 5014multiclass VPatBinaryV_VX_RM<string intrinsic, string instruction, 5015 list<VTypeInfo> vtilist, bit isSEWAware = 0> { 5016 foreach vti = vtilist in { 5017 defvar kind = "V"#vti.ScalarSuffix; 5018 let Predicates = GetVTypePredicates<vti>.Predicates in 5019 defm : VPatBinaryRoundingMode<intrinsic, 5020 !if(isSEWAware, 5021 instruction#"_"#kind#"_"#vti.LMul.MX#"_E"#vti.SEW, 5022 instruction#"_"#kind#"_"#vti.LMul.MX), 5023 vti.Vector, vti.Vector, vti.Scalar, vti.Mask, 5024 vti.Log2SEW, vti.RegClass, 5025 vti.RegClass, vti.ScalarRegClass>; 5026 } 5027} 5028 5029multiclass VPatBinaryV_VX_INT<string intrinsic, string instruction, 5030 list<VTypeInfo> vtilist> { 5031 foreach vti = vtilist in 5032 let Predicates = GetVTypePredicates<vti>.Predicates in 5033 defm : VPatBinary<intrinsic, instruction # "_VX_" # vti.LMul.MX, 5034 vti.Vector, vti.Vector, XLenVT, vti.Mask, 5035 vti.Log2SEW, vti.RegClass, 5036 vti.RegClass, GPR>; 5037} 5038 5039multiclass VPatBinaryV_VI<string intrinsic, string instruction, 5040 list<VTypeInfo> vtilist, Operand imm_type> { 5041 foreach vti = vtilist in 5042 let Predicates = GetVTypePredicates<vti>.Predicates in 5043 defm : VPatBinary<intrinsic, instruction # "_VI_" # vti.LMul.MX, 5044 vti.Vector, vti.Vector, XLenVT, vti.Mask, 5045 vti.Log2SEW, vti.RegClass, 5046 vti.RegClass, imm_type>; 5047} 5048 5049multiclass VPatBinaryV_VI_RM<string intrinsic, string instruction, 5050 list<VTypeInfo> vtilist, 5051 Operand imm_type> { 5052 foreach vti = vtilist in 5053 let Predicates = GetVTypePredicates<vti>.Predicates in 5054 defm : VPatBinaryRoundingMode<intrinsic, 5055 instruction # "_VI_" # vti.LMul.MX, 5056 vti.Vector, vti.Vector, XLenVT, vti.Mask, 5057 vti.Log2SEW, vti.RegClass, 5058 vti.RegClass, imm_type>; 5059} 5060 5061multiclass VPatBinaryM_MM<string intrinsic, string instruction> { 5062 foreach mti = AllMasks in 5063 let Predicates = [HasVInstructions] in 5064 def : VPatBinaryM<intrinsic, instruction # "_MM_" # mti.LMul.MX, 5065 mti.Mask, mti.Mask, mti.Mask, 5066 mti.Log2SEW, VR, VR>; 5067} 5068 5069multiclass VPatBinaryW_VV<string intrinsic, string instruction, 5070 list<VTypeInfoToWide> vtilist> { 5071 foreach VtiToWti = vtilist in { 5072 defvar Vti = VtiToWti.Vti; 5073 defvar Wti = VtiToWti.Wti; 5074 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates, 5075 GetVTypePredicates<Wti>.Predicates) in 5076 defm : VPatBinary<intrinsic, instruction # "_VV_" # Vti.LMul.MX, 5077 Wti.Vector, Vti.Vector, Vti.Vector, Vti.Mask, 5078 Vti.Log2SEW, Wti.RegClass, 5079 Vti.RegClass, Vti.RegClass>; 5080 } 5081} 5082 5083multiclass VPatBinaryW_VV_RM<string intrinsic, string instruction, 5084 list<VTypeInfoToWide> vtilist> { 5085 foreach VtiToWti = vtilist in { 5086 defvar Vti = VtiToWti.Vti; 5087 defvar Wti = VtiToWti.Wti; 5088 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates, 5089 GetVTypePredicates<Wti>.Predicates) in 5090 defm : VPatBinaryRoundingMode<intrinsic, instruction # "_VV_" # Vti.LMul.MX, 5091 Wti.Vector, Vti.Vector, Vti.Vector, Vti.Mask, 5092 Vti.Log2SEW, Wti.RegClass, 5093 Vti.RegClass, Vti.RegClass>; 5094 } 5095} 5096 5097multiclass VPatBinaryW_VX<string intrinsic, string instruction, 5098 list<VTypeInfoToWide> vtilist> { 5099 foreach VtiToWti = vtilist in { 5100 defvar Vti = VtiToWti.Vti; 5101 defvar Wti = VtiToWti.Wti; 5102 defvar kind = "V"#Vti.ScalarSuffix; 5103 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates, 5104 GetVTypePredicates<Wti>.Predicates) in 5105 defm : VPatBinary<intrinsic, instruction#"_"#kind#"_"#Vti.LMul.MX, 5106 Wti.Vector, Vti.Vector, Vti.Scalar, Vti.Mask, 5107 Vti.Log2SEW, Wti.RegClass, 5108 Vti.RegClass, Vti.ScalarRegClass>; 5109 } 5110} 5111 5112multiclass VPatBinaryW_VX_RM<string intrinsic, string instruction, 5113 list<VTypeInfoToWide> vtilist> { 5114 foreach VtiToWti = vtilist in { 5115 defvar Vti = VtiToWti.Vti; 5116 defvar Wti = VtiToWti.Wti; 5117 defvar kind = "V"#Vti.ScalarSuffix; 5118 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates, 5119 GetVTypePredicates<Wti>.Predicates) in 5120 defm : VPatBinaryRoundingMode<intrinsic, instruction#"_"#kind#"_"#Vti.LMul.MX, 5121 Wti.Vector, Vti.Vector, Vti.Scalar, Vti.Mask, 5122 Vti.Log2SEW, Wti.RegClass, 5123 Vti.RegClass, Vti.ScalarRegClass>; 5124 } 5125} 5126 5127multiclass VPatBinaryW_WV<string intrinsic, string instruction, 5128 list<VTypeInfoToWide> vtilist> { 5129 foreach VtiToWti = vtilist in { 5130 defvar Vti = VtiToWti.Vti; 5131 defvar Wti = VtiToWti.Wti; 5132 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates, 5133 GetVTypePredicates<Wti>.Predicates) in { 5134 def : VPatTiedBinaryNoMask<intrinsic, instruction # "_WV_" # Vti.LMul.MX, 5135 Wti.Vector, Vti.Vector, 5136 Vti.Log2SEW, Wti.RegClass, Vti.RegClass>; 5137 def : VPatBinaryNoMaskTU<intrinsic, instruction # "_WV_" # Vti.LMul.MX, 5138 Wti.Vector, Wti.Vector, Vti.Vector, Vti.Log2SEW, 5139 Wti.RegClass, Wti.RegClass, Vti.RegClass>; 5140 let AddedComplexity = 1 in { 5141 def : VPatTiedBinaryNoMaskTU<intrinsic, instruction # "_WV_" # Vti.LMul.MX, 5142 Wti.Vector, Vti.Vector, 5143 Vti.Log2SEW, Wti.RegClass, Vti.RegClass>; 5144 def : VPatTiedBinaryMask<intrinsic, instruction # "_WV_" # Vti.LMul.MX, 5145 Wti.Vector, Vti.Vector, Vti.Mask, 5146 Vti.Log2SEW, Wti.RegClass, Vti.RegClass>; 5147 } 5148 def : VPatBinaryMaskTA<intrinsic, instruction # "_WV_" # Vti.LMul.MX, 5149 Wti.Vector, Wti.Vector, Vti.Vector, Vti.Mask, 5150 Vti.Log2SEW, Wti.RegClass, 5151 Wti.RegClass, Vti.RegClass>; 5152 } 5153 } 5154} 5155 5156multiclass VPatBinaryW_WV_RM<string intrinsic, string instruction, 5157 list<VTypeInfoToWide> vtilist> { 5158 foreach VtiToWti = vtilist in { 5159 defvar Vti = VtiToWti.Vti; 5160 defvar Wti = VtiToWti.Wti; 5161 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates, 5162 GetVTypePredicates<Wti>.Predicates) in { 5163 def : VPatTiedBinaryNoMaskRoundingMode<intrinsic, instruction # "_WV_" # Vti.LMul.MX, 5164 Wti.Vector, Vti.Vector, 5165 Vti.Log2SEW, Wti.RegClass, Vti.RegClass>; 5166 def : VPatBinaryNoMaskTURoundingMode<intrinsic, instruction # "_WV_" # Vti.LMul.MX, 5167 Wti.Vector, Wti.Vector, Vti.Vector, Vti.Log2SEW, 5168 Wti.RegClass, Wti.RegClass, Vti.RegClass>; 5169 let AddedComplexity = 1 in { 5170 def : VPatTiedBinaryNoMaskTURoundingMode<intrinsic, instruction # "_WV_" # Vti.LMul.MX, 5171 Wti.Vector, Vti.Vector, 5172 Vti.Log2SEW, Wti.RegClass, Vti.RegClass>; 5173 def : VPatTiedBinaryMaskRoundingMode<intrinsic, instruction # "_WV_" # Vti.LMul.MX, 5174 Wti.Vector, Vti.Vector, Vti.Mask, 5175 Vti.Log2SEW, Wti.RegClass, Vti.RegClass>; 5176 } 5177 def : VPatBinaryMaskTARoundingMode<intrinsic, instruction # "_WV_" # Vti.LMul.MX, 5178 Wti.Vector, Wti.Vector, Vti.Vector, Vti.Mask, 5179 Vti.Log2SEW, Wti.RegClass, 5180 Wti.RegClass, Vti.RegClass>; 5181 } 5182 } 5183} 5184 5185multiclass VPatBinaryW_WX<string intrinsic, string instruction, 5186 list<VTypeInfoToWide> vtilist> { 5187 foreach VtiToWti = vtilist in { 5188 defvar Vti = VtiToWti.Vti; 5189 defvar Wti = VtiToWti.Wti; 5190 defvar kind = "W"#Vti.ScalarSuffix; 5191 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates, 5192 GetVTypePredicates<Wti>.Predicates) in 5193 defm : VPatBinary<intrinsic, instruction#"_"#kind#"_"#Vti.LMul.MX, 5194 Wti.Vector, Wti.Vector, Vti.Scalar, Vti.Mask, 5195 Vti.Log2SEW, Wti.RegClass, 5196 Wti.RegClass, Vti.ScalarRegClass>; 5197 } 5198} 5199 5200multiclass VPatBinaryW_WX_RM<string intrinsic, string instruction, 5201 list<VTypeInfoToWide> vtilist> { 5202 foreach VtiToWti = vtilist in { 5203 defvar Vti = VtiToWti.Vti; 5204 defvar Wti = VtiToWti.Wti; 5205 defvar kind = "W"#Vti.ScalarSuffix; 5206 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates, 5207 GetVTypePredicates<Wti>.Predicates) in 5208 defm : VPatBinaryRoundingMode<intrinsic, instruction#"_"#kind#"_"#Vti.LMul.MX, 5209 Wti.Vector, Wti.Vector, Vti.Scalar, Vti.Mask, 5210 Vti.Log2SEW, Wti.RegClass, 5211 Wti.RegClass, Vti.ScalarRegClass>; 5212 } 5213} 5214 5215multiclass VPatBinaryV_WV<string intrinsic, string instruction, 5216 list<VTypeInfoToWide> vtilist> { 5217 foreach VtiToWti = vtilist in { 5218 defvar Vti = VtiToWti.Vti; 5219 defvar Wti = VtiToWti.Wti; 5220 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates, 5221 GetVTypePredicates<Wti>.Predicates) in 5222 defm : VPatBinary<intrinsic, instruction # "_WV_" # Vti.LMul.MX, 5223 Vti.Vector, Wti.Vector, Vti.Vector, Vti.Mask, 5224 Vti.Log2SEW, Vti.RegClass, 5225 Wti.RegClass, Vti.RegClass>; 5226 } 5227} 5228 5229multiclass VPatBinaryV_WV_RM<string intrinsic, string instruction, 5230 list<VTypeInfoToWide> vtilist> { 5231 foreach VtiToWti = vtilist in { 5232 defvar Vti = VtiToWti.Vti; 5233 defvar Wti = VtiToWti.Wti; 5234 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates, 5235 GetVTypePredicates<Wti>.Predicates) in 5236 defm : VPatBinaryRoundingMode<intrinsic, 5237 instruction # "_WV_" # Vti.LMul.MX, 5238 Vti.Vector, Wti.Vector, Vti.Vector, Vti.Mask, 5239 Vti.Log2SEW, Vti.RegClass, 5240 Wti.RegClass, Vti.RegClass>; 5241 } 5242} 5243 5244multiclass VPatBinaryV_WX<string intrinsic, string instruction, 5245 list<VTypeInfoToWide> vtilist> { 5246 foreach VtiToWti = vtilist in { 5247 defvar Vti = VtiToWti.Vti; 5248 defvar Wti = VtiToWti.Wti; 5249 defvar kind = "W"#Vti.ScalarSuffix; 5250 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates, 5251 GetVTypePredicates<Wti>.Predicates) in 5252 defm : VPatBinary<intrinsic, instruction#"_"#kind#"_"#Vti.LMul.MX, 5253 Vti.Vector, Wti.Vector, Vti.Scalar, Vti.Mask, 5254 Vti.Log2SEW, Vti.RegClass, 5255 Wti.RegClass, Vti.ScalarRegClass>; 5256 } 5257} 5258 5259multiclass VPatBinaryV_WX_RM<string intrinsic, string instruction, 5260 list<VTypeInfoToWide> vtilist> { 5261 foreach VtiToWti = vtilist in { 5262 defvar Vti = VtiToWti.Vti; 5263 defvar Wti = VtiToWti.Wti; 5264 defvar kind = "W"#Vti.ScalarSuffix; 5265 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates, 5266 GetVTypePredicates<Wti>.Predicates) in 5267 defm : VPatBinaryRoundingMode<intrinsic, 5268 instruction#"_"#kind#"_"#Vti.LMul.MX, 5269 Vti.Vector, Wti.Vector, Vti.Scalar, Vti.Mask, 5270 Vti.Log2SEW, Vti.RegClass, 5271 Wti.RegClass, Vti.ScalarRegClass>; 5272 } 5273} 5274 5275 5276multiclass VPatBinaryV_WI<string intrinsic, string instruction, 5277 list<VTypeInfoToWide> vtilist> { 5278 foreach VtiToWti = vtilist in { 5279 defvar Vti = VtiToWti.Vti; 5280 defvar Wti = VtiToWti.Wti; 5281 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates, 5282 GetVTypePredicates<Wti>.Predicates) in 5283 defm : VPatBinary<intrinsic, instruction # "_WI_" # Vti.LMul.MX, 5284 Vti.Vector, Wti.Vector, XLenVT, Vti.Mask, 5285 Vti.Log2SEW, Vti.RegClass, 5286 Wti.RegClass, uimm5>; 5287 } 5288} 5289 5290multiclass VPatBinaryV_WI_RM<string intrinsic, string instruction, 5291 list<VTypeInfoToWide> vtilist> { 5292 foreach VtiToWti = vtilist in { 5293 defvar Vti = VtiToWti.Vti; 5294 defvar Wti = VtiToWti.Wti; 5295 let Predicates = !listconcat(GetVTypePredicates<Vti>.Predicates, 5296 GetVTypePredicates<Wti>.Predicates) in 5297 defm : VPatBinaryRoundingMode<intrinsic, 5298 instruction # "_WI_" # Vti.LMul.MX, 5299 Vti.Vector, Wti.Vector, XLenVT, Vti.Mask, 5300 Vti.Log2SEW, Vti.RegClass, 5301 Wti.RegClass, uimm5>; 5302 } 5303} 5304 5305multiclass VPatBinaryV_VM<string intrinsic, string instruction, 5306 bit CarryOut = 0, 5307 list<VTypeInfo> vtilist = AllIntegerVectors> { 5308 foreach vti = vtilist in 5309 let Predicates = GetVTypePredicates<vti>.Predicates in 5310 defm : VPatBinaryCarryIn<intrinsic, instruction, "VVM", 5311 !if(CarryOut, vti.Mask, vti.Vector), 5312 vti.Vector, vti.Vector, vti.Mask, 5313 vti.Log2SEW, vti.LMul, 5314 vti.RegClass, vti.RegClass>; 5315} 5316 5317multiclass VPatBinaryV_XM<string intrinsic, string instruction, 5318 bit CarryOut = 0, 5319 list<VTypeInfo> vtilist = AllIntegerVectors> { 5320 foreach vti = vtilist in 5321 let Predicates = GetVTypePredicates<vti>.Predicates in 5322 defm : VPatBinaryCarryIn<intrinsic, instruction, 5323 "V"#vti.ScalarSuffix#"M", 5324 !if(CarryOut, vti.Mask, vti.Vector), 5325 vti.Vector, vti.Scalar, vti.Mask, 5326 vti.Log2SEW, vti.LMul, 5327 vti.RegClass, vti.ScalarRegClass>; 5328} 5329 5330multiclass VPatBinaryV_IM<string intrinsic, string instruction, 5331 bit CarryOut = 0> { 5332 foreach vti = AllIntegerVectors in 5333 let Predicates = GetVTypePredicates<vti>.Predicates in 5334 defm : VPatBinaryCarryIn<intrinsic, instruction, "VIM", 5335 !if(CarryOut, vti.Mask, vti.Vector), 5336 vti.Vector, XLenVT, vti.Mask, 5337 vti.Log2SEW, vti.LMul, 5338 vti.RegClass, simm5>; 5339} 5340 5341multiclass VPatBinaryV_VM_TAIL<string intrinsic, string instruction> { 5342 foreach vti = AllIntegerVectors in 5343 let Predicates = GetVTypePredicates<vti>.Predicates in 5344 defm : VPatBinaryCarryInTAIL<intrinsic, instruction, "VVM", 5345 vti.Vector, 5346 vti.Vector, vti.Vector, vti.Mask, 5347 vti.Log2SEW, vti.LMul, vti.RegClass, 5348 vti.RegClass, vti.RegClass>; 5349} 5350 5351multiclass VPatBinaryV_XM_TAIL<string intrinsic, string instruction> { 5352 foreach vti = AllIntegerVectors in 5353 let Predicates = GetVTypePredicates<vti>.Predicates in 5354 defm : VPatBinaryCarryInTAIL<intrinsic, instruction, 5355 "V"#vti.ScalarSuffix#"M", 5356 vti.Vector, 5357 vti.Vector, vti.Scalar, vti.Mask, 5358 vti.Log2SEW, vti.LMul, vti.RegClass, 5359 vti.RegClass, vti.ScalarRegClass>; 5360} 5361 5362multiclass VPatBinaryV_IM_TAIL<string intrinsic, string instruction> { 5363 foreach vti = AllIntegerVectors in 5364 let Predicates = GetVTypePredicates<vti>.Predicates in 5365 defm : VPatBinaryCarryInTAIL<intrinsic, instruction, "VIM", 5366 vti.Vector, 5367 vti.Vector, XLenVT, vti.Mask, 5368 vti.Log2SEW, vti.LMul, 5369 vti.RegClass, vti.RegClass, simm5>; 5370} 5371 5372multiclass VPatBinaryV_V<string intrinsic, string instruction> { 5373 foreach vti = AllIntegerVectors in 5374 let Predicates = GetVTypePredicates<vti>.Predicates in 5375 defm : VPatBinaryMaskOut<intrinsic, instruction, "VV", 5376 vti.Mask, vti.Vector, vti.Vector, 5377 vti.Log2SEW, vti.LMul, 5378 vti.RegClass, vti.RegClass>; 5379} 5380 5381multiclass VPatBinaryV_X<string intrinsic, string instruction> { 5382 foreach vti = AllIntegerVectors in 5383 let Predicates = GetVTypePredicates<vti>.Predicates in 5384 defm : VPatBinaryMaskOut<intrinsic, instruction, "VX", 5385 vti.Mask, vti.Vector, XLenVT, 5386 vti.Log2SEW, vti.LMul, 5387 vti.RegClass, GPR>; 5388} 5389 5390multiclass VPatBinaryV_I<string intrinsic, string instruction> { 5391 foreach vti = AllIntegerVectors in 5392 let Predicates = GetVTypePredicates<vti>.Predicates in 5393 defm : VPatBinaryMaskOut<intrinsic, instruction, "VI", 5394 vti.Mask, vti.Vector, XLenVT, 5395 vti.Log2SEW, vti.LMul, 5396 vti.RegClass, simm5>; 5397} 5398 5399multiclass VPatBinaryM_VV<string intrinsic, string instruction, 5400 list<VTypeInfo> vtilist> { 5401 foreach vti = vtilist in 5402 let Predicates = GetVTypePredicates<vti>.Predicates in 5403 defm : VPatBinaryM<intrinsic, instruction # "_VV_" # vti.LMul.MX, 5404 vti.Mask, vti.Vector, vti.Vector, vti.Mask, 5405 vti.Log2SEW, VR, 5406 vti.RegClass, vti.RegClass>; 5407} 5408 5409multiclass VPatBinarySwappedM_VV<string intrinsic, string instruction, 5410 list<VTypeInfo> vtilist> { 5411 foreach vti = vtilist in 5412 let Predicates = GetVTypePredicates<vti>.Predicates in 5413 defm : VPatBinarySwapped<intrinsic, instruction # "_VV_" # vti.LMul.MX, 5414 vti.Mask, vti.Vector, vti.Vector, vti.Mask, 5415 vti.Log2SEW, VR, 5416 vti.RegClass, vti.RegClass>; 5417} 5418 5419multiclass VPatBinaryM_VX<string intrinsic, string instruction, 5420 list<VTypeInfo> vtilist> { 5421 foreach vti = vtilist in { 5422 defvar kind = "V"#vti.ScalarSuffix; 5423 let Predicates = GetVTypePredicates<vti>.Predicates in 5424 defm : VPatBinaryM<intrinsic, instruction#"_"#kind#"_"#vti.LMul.MX, 5425 vti.Mask, vti.Vector, vti.Scalar, vti.Mask, 5426 vti.Log2SEW, VR, 5427 vti.RegClass, vti.ScalarRegClass>; 5428 } 5429} 5430 5431multiclass VPatBinaryM_VI<string intrinsic, string instruction, 5432 list<VTypeInfo> vtilist> { 5433 foreach vti = vtilist in 5434 let Predicates = GetVTypePredicates<vti>.Predicates in 5435 defm : VPatBinaryM<intrinsic, instruction # "_VI_" # vti.LMul.MX, 5436 vti.Mask, vti.Vector, XLenVT, vti.Mask, 5437 vti.Log2SEW, VR, 5438 vti.RegClass, simm5>; 5439} 5440 5441multiclass VPatBinaryV_VV_VX_VI<string intrinsic, string instruction, 5442 list<VTypeInfo> vtilist, Operand ImmType = simm5> 5443 : VPatBinaryV_VV<intrinsic, instruction, vtilist>, 5444 VPatBinaryV_VX<intrinsic, instruction, vtilist>, 5445 VPatBinaryV_VI<intrinsic, instruction, vtilist, ImmType>; 5446 5447multiclass VPatBinaryV_VV_VX_VI_RM<string intrinsic, string instruction, 5448 list<VTypeInfo> vtilist, Operand ImmType = simm5> 5449 : VPatBinaryV_VV_RM<intrinsic, instruction, vtilist>, 5450 VPatBinaryV_VX_RM<intrinsic, instruction, vtilist>, 5451 VPatBinaryV_VI_RM<intrinsic, instruction, vtilist, ImmType>; 5452 5453multiclass VPatBinaryV_VV_VX<string intrinsic, string instruction, 5454 list<VTypeInfo> vtilist, bit isSEWAware = 0> 5455 : VPatBinaryV_VV<intrinsic, instruction, vtilist, isSEWAware>, 5456 VPatBinaryV_VX<intrinsic, instruction, vtilist, isSEWAware>; 5457 5458multiclass VPatBinaryV_VV_VX_RM<string intrinsic, string instruction, 5459 list<VTypeInfo> vtilist, bit isSEWAware = 0> 5460 : VPatBinaryV_VV_RM<intrinsic, instruction, vtilist, isSEWAware>, 5461 VPatBinaryV_VX_RM<intrinsic, instruction, vtilist, isSEWAware>; 5462 5463multiclass VPatBinaryV_VX_VI<string intrinsic, string instruction, 5464 list<VTypeInfo> vtilist> 5465 : VPatBinaryV_VX<intrinsic, instruction, vtilist>, 5466 VPatBinaryV_VI<intrinsic, instruction, vtilist, simm5>; 5467 5468multiclass VPatBinaryW_VV_VX<string intrinsic, string instruction, 5469 list<VTypeInfoToWide> vtilist> 5470 : VPatBinaryW_VV<intrinsic, instruction, vtilist>, 5471 VPatBinaryW_VX<intrinsic, instruction, vtilist>; 5472 5473multiclass VPatBinaryW_VV_VX_RM<string intrinsic, string instruction, 5474 list<VTypeInfoToWide> vtilist> 5475 : VPatBinaryW_VV_RM<intrinsic, instruction, vtilist>, 5476 VPatBinaryW_VX_RM<intrinsic, instruction, vtilist>; 5477 5478multiclass VPatBinaryW_WV_WX<string intrinsic, string instruction, 5479 list<VTypeInfoToWide> vtilist> 5480 : VPatBinaryW_WV<intrinsic, instruction, vtilist>, 5481 VPatBinaryW_WX<intrinsic, instruction, vtilist>; 5482 5483multiclass VPatBinaryW_WV_WX_RM<string intrinsic, string instruction, 5484 list<VTypeInfoToWide> vtilist> 5485 : VPatBinaryW_WV_RM<intrinsic, instruction, vtilist>, 5486 VPatBinaryW_WX_RM<intrinsic, instruction, vtilist>; 5487 5488multiclass VPatBinaryV_WV_WX_WI<string intrinsic, string instruction, 5489 list<VTypeInfoToWide> vtilist> 5490 : VPatBinaryV_WV<intrinsic, instruction, vtilist>, 5491 VPatBinaryV_WX<intrinsic, instruction, vtilist>, 5492 VPatBinaryV_WI<intrinsic, instruction, vtilist>; 5493 5494multiclass VPatBinaryV_WV_WX_WI_RM<string intrinsic, string instruction, 5495 list<VTypeInfoToWide> vtilist> 5496 : VPatBinaryV_WV_RM<intrinsic, instruction, vtilist>, 5497 VPatBinaryV_WX_RM<intrinsic, instruction, vtilist>, 5498 VPatBinaryV_WI_RM<intrinsic, instruction, vtilist>; 5499 5500multiclass VPatBinaryV_VM_XM_IM<string intrinsic, string instruction> 5501 : VPatBinaryV_VM_TAIL<intrinsic, instruction>, 5502 VPatBinaryV_XM_TAIL<intrinsic, instruction>, 5503 VPatBinaryV_IM_TAIL<intrinsic, instruction>; 5504 5505multiclass VPatBinaryM_VM_XM_IM<string intrinsic, string instruction> 5506 : VPatBinaryV_VM<intrinsic, instruction, CarryOut=1>, 5507 VPatBinaryV_XM<intrinsic, instruction, CarryOut=1>, 5508 VPatBinaryV_IM<intrinsic, instruction, CarryOut=1>; 5509 5510multiclass VPatBinaryM_V_X_I<string intrinsic, string instruction> 5511 : VPatBinaryV_V<intrinsic, instruction>, 5512 VPatBinaryV_X<intrinsic, instruction>, 5513 VPatBinaryV_I<intrinsic, instruction>; 5514 5515multiclass VPatBinaryV_VM_XM<string intrinsic, string instruction> 5516 : VPatBinaryV_VM_TAIL<intrinsic, instruction>, 5517 VPatBinaryV_XM_TAIL<intrinsic, instruction>; 5518 5519multiclass VPatBinaryM_VM_XM<string intrinsic, string instruction> 5520 : VPatBinaryV_VM<intrinsic, instruction, CarryOut=1>, 5521 VPatBinaryV_XM<intrinsic, instruction, CarryOut=1>; 5522 5523multiclass VPatBinaryM_V_X<string intrinsic, string instruction> 5524 : VPatBinaryV_V<intrinsic, instruction>, 5525 VPatBinaryV_X<intrinsic, instruction>; 5526 5527multiclass VPatTernary<string intrinsic, 5528 string inst, 5529 string kind, 5530 ValueType result_type, 5531 ValueType op1_type, 5532 ValueType op2_type, 5533 ValueType mask_type, 5534 int sew, 5535 LMULInfo vlmul, 5536 VReg result_reg_class, 5537 RegisterClass op1_reg_class, 5538 DAGOperand op2_kind> { 5539 def : VPatTernaryNoMask<intrinsic, inst, kind, result_type, op1_type, op2_type, 5540 sew, vlmul, result_reg_class, op1_reg_class, 5541 op2_kind>; 5542 def : VPatTernaryMask<intrinsic, inst, kind, result_type, op1_type, op2_type, 5543 mask_type, sew, vlmul, result_reg_class, op1_reg_class, 5544 op2_kind>; 5545} 5546 5547multiclass VPatTernaryNoMaskNoPolicy<string intrinsic, 5548 string inst, 5549 string kind, 5550 ValueType result_type, 5551 ValueType op1_type, 5552 ValueType op2_type, 5553 ValueType mask_type, 5554 int sew, 5555 LMULInfo vlmul, 5556 VReg result_reg_class, 5557 RegisterClass op1_reg_class, 5558 DAGOperand op2_kind> { 5559 def : VPatTernaryNoMask<intrinsic, inst, kind, result_type, op1_type, op2_type, 5560 sew, vlmul, result_reg_class, op1_reg_class, 5561 op2_kind>; 5562 def : VPatTernaryMaskPolicy<intrinsic, inst, kind, result_type, op1_type, op2_type, 5563 mask_type, sew, vlmul, result_reg_class, op1_reg_class, 5564 op2_kind>; 5565} 5566 5567multiclass VPatTernaryWithPolicy<string intrinsic, 5568 string inst, 5569 string kind, 5570 ValueType result_type, 5571 ValueType op1_type, 5572 ValueType op2_type, 5573 ValueType mask_type, 5574 int sew, 5575 LMULInfo vlmul, 5576 VReg result_reg_class, 5577 RegisterClass op1_reg_class, 5578 DAGOperand op2_kind> { 5579 def : VPatTernaryNoMaskWithPolicy<intrinsic, inst, kind, result_type, op1_type, 5580 op2_type, sew, vlmul, result_reg_class, 5581 op1_reg_class, op2_kind>; 5582 def : VPatTernaryMaskPolicy<intrinsic, inst, kind, result_type, op1_type, op2_type, 5583 mask_type, sew, vlmul, result_reg_class, op1_reg_class, 5584 op2_kind>; 5585} 5586 5587multiclass VPatTernaryWithPolicyRoundingMode<string intrinsic, 5588 string inst, 5589 string kind, 5590 ValueType result_type, 5591 ValueType op1_type, 5592 ValueType op2_type, 5593 ValueType mask_type, 5594 int sew, 5595 LMULInfo vlmul, 5596 VReg result_reg_class, 5597 RegisterClass op1_reg_class, 5598 DAGOperand op2_kind> { 5599 def : VPatTernaryNoMaskWithPolicyRoundingMode<intrinsic, inst, kind, result_type, 5600 op1_type, op2_type, sew, vlmul, 5601 result_reg_class, op1_reg_class, 5602 op2_kind>; 5603 def : VPatTernaryMaskPolicyRoundingMode<intrinsic, inst, kind, result_type, op1_type, 5604 op2_type, mask_type, sew, vlmul, 5605 result_reg_class, op1_reg_class, 5606 op2_kind>; 5607} 5608 5609multiclass VPatTernaryTA<string intrinsic, 5610 string inst, 5611 string kind, 5612 ValueType result_type, 5613 ValueType op1_type, 5614 ValueType op2_type, 5615 ValueType mask_type, 5616 int log2sew, 5617 LMULInfo vlmul, 5618 VReg result_reg_class, 5619 RegisterClass op1_reg_class, 5620 DAGOperand op2_kind> { 5621 def : VPatTernaryNoMaskTA<intrinsic, inst, kind, result_type, op1_type, 5622 op2_type, log2sew, vlmul, result_reg_class, 5623 op1_reg_class, op2_kind>; 5624 def : VPatTernaryMaskTA<intrinsic, inst, kind, result_type, op1_type, 5625 op2_type, mask_type, log2sew, vlmul, 5626 result_reg_class, op1_reg_class, op2_kind>; 5627} 5628 5629multiclass VPatTernaryTARoundingMode<string intrinsic, 5630 string inst, 5631 string kind, 5632 ValueType result_type, 5633 ValueType op1_type, 5634 ValueType op2_type, 5635 ValueType mask_type, 5636 int log2sew, 5637 LMULInfo vlmul, 5638 VReg result_reg_class, 5639 RegisterClass op1_reg_class, 5640 DAGOperand op2_kind> { 5641 def : VPatTernaryNoMaskTARoundingMode<intrinsic, inst, kind, result_type, op1_type, 5642 op2_type, log2sew, vlmul, result_reg_class, 5643 op1_reg_class, op2_kind>; 5644 def : VPatTernaryMaskTARoundingMode<intrinsic, inst, kind, result_type, op1_type, 5645 op2_type, mask_type, log2sew, vlmul, 5646 result_reg_class, op1_reg_class, op2_kind>; 5647} 5648 5649multiclass VPatTernaryV_VV_AAXA<string intrinsic, string instruction, 5650 list<VTypeInfo> vtilist> { 5651 foreach vti = vtilist in 5652 let Predicates = GetVTypePredicates<vti>.Predicates in 5653 defm : VPatTernaryWithPolicy<intrinsic, instruction, "VV", 5654 vti.Vector, vti.Vector, vti.Vector, vti.Mask, 5655 vti.Log2SEW, vti.LMul, vti.RegClass, 5656 vti.RegClass, vti.RegClass>; 5657} 5658 5659multiclass VPatTernaryV_VV_AAXA_RM<string intrinsic, string instruction, 5660 list<VTypeInfo> vtilist> { 5661 foreach vti = vtilist in 5662 let Predicates = GetVTypePredicates<vti>.Predicates in 5663 defm : VPatTernaryWithPolicyRoundingMode<intrinsic, instruction, "VV", 5664 vti.Vector, vti.Vector, vti.Vector, vti.Mask, 5665 vti.Log2SEW, vti.LMul, vti.RegClass, 5666 vti.RegClass, vti.RegClass>; 5667} 5668 5669multiclass VPatTernaryV_VX<string intrinsic, string instruction, 5670 list<VTypeInfo> vtilist> { 5671 foreach vti = vtilist in 5672 let Predicates = GetVTypePredicates<vti>.Predicates in 5673 defm : VPatTernaryWithPolicy<intrinsic, instruction, "VX", 5674 vti.Vector, vti.Vector, XLenVT, vti.Mask, 5675 vti.Log2SEW, vti.LMul, vti.RegClass, 5676 vti.RegClass, GPR>; 5677} 5678 5679multiclass VPatTernaryV_VX_AAXA<string intrinsic, string instruction, 5680 list<VTypeInfo> vtilist> { 5681 foreach vti = vtilist in 5682 let Predicates = GetVTypePredicates<vti>.Predicates in 5683 defm : VPatTernaryWithPolicy<intrinsic, instruction, 5684 "V"#vti.ScalarSuffix, 5685 vti.Vector, vti.Scalar, vti.Vector, vti.Mask, 5686 vti.Log2SEW, vti.LMul, vti.RegClass, 5687 vti.ScalarRegClass, vti.RegClass>; 5688} 5689 5690multiclass VPatTernaryV_VX_AAXA_RM<string intrinsic, string instruction, 5691 list<VTypeInfo> vtilist> { 5692 foreach vti = vtilist in 5693 let Predicates = GetVTypePredicates<vti>.Predicates in 5694 defm : VPatTernaryWithPolicyRoundingMode<intrinsic, instruction, 5695 "V"#vti.ScalarSuffix, 5696 vti.Vector, vti.Scalar, vti.Vector, vti.Mask, 5697 vti.Log2SEW, vti.LMul, vti.RegClass, 5698 vti.ScalarRegClass, vti.RegClass>; 5699} 5700 5701multiclass VPatTernaryV_VI<string intrinsic, string instruction, 5702 list<VTypeInfo> vtilist, Operand Imm_type> { 5703 foreach vti = vtilist in 5704 let Predicates = GetVTypePredicates<vti>.Predicates in 5705 defm : VPatTernaryWithPolicy<intrinsic, instruction, "VI", 5706 vti.Vector, vti.Vector, XLenVT, vti.Mask, 5707 vti.Log2SEW, vti.LMul, vti.RegClass, 5708 vti.RegClass, Imm_type>; 5709} 5710 5711multiclass VPatTernaryW_VV<string intrinsic, string instruction, 5712 list<VTypeInfoToWide> vtilist> { 5713 foreach vtiToWti = vtilist in { 5714 defvar vti = vtiToWti.Vti; 5715 defvar wti = vtiToWti.Wti; 5716 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 5717 GetVTypePredicates<wti>.Predicates) in 5718 defm : VPatTernaryWithPolicy<intrinsic, instruction, "VV", 5719 wti.Vector, vti.Vector, vti.Vector, 5720 vti.Mask, vti.Log2SEW, vti.LMul, 5721 wti.RegClass, vti.RegClass, vti.RegClass>; 5722 } 5723} 5724 5725multiclass VPatTernaryW_VV_RM<string intrinsic, string instruction, 5726 list<VTypeInfoToWide> vtilist> { 5727 foreach vtiToWti = vtilist in { 5728 defvar vti = vtiToWti.Vti; 5729 defvar wti = vtiToWti.Wti; 5730 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 5731 GetVTypePredicates<wti>.Predicates) in 5732 defm : VPatTernaryWithPolicyRoundingMode<intrinsic, instruction, "VV", 5733 wti.Vector, vti.Vector, vti.Vector, 5734 vti.Mask, vti.Log2SEW, vti.LMul, 5735 wti.RegClass, vti.RegClass, vti.RegClass>; 5736 } 5737} 5738 5739multiclass VPatTernaryW_VX<string intrinsic, string instruction, 5740 list<VTypeInfoToWide> vtilist> { 5741 foreach vtiToWti = vtilist in { 5742 defvar vti = vtiToWti.Vti; 5743 defvar wti = vtiToWti.Wti; 5744 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 5745 GetVTypePredicates<wti>.Predicates) in 5746 defm : VPatTernaryWithPolicy<intrinsic, instruction, 5747 "V"#vti.ScalarSuffix, 5748 wti.Vector, vti.Scalar, vti.Vector, 5749 vti.Mask, vti.Log2SEW, vti.LMul, 5750 wti.RegClass, vti.ScalarRegClass, vti.RegClass>; 5751 } 5752} 5753 5754multiclass VPatTernaryW_VX_RM<string intrinsic, string instruction, 5755 list<VTypeInfoToWide> vtilist> { 5756 foreach vtiToWti = vtilist in { 5757 defvar vti = vtiToWti.Vti; 5758 defvar wti = vtiToWti.Wti; 5759 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 5760 GetVTypePredicates<wti>.Predicates) in 5761 defm : VPatTernaryWithPolicyRoundingMode<intrinsic, instruction, 5762 "V"#vti.ScalarSuffix, 5763 wti.Vector, vti.Scalar, vti.Vector, 5764 vti.Mask, vti.Log2SEW, vti.LMul, 5765 wti.RegClass, vti.ScalarRegClass, 5766 vti.RegClass>; 5767 } 5768} 5769 5770multiclass VPatTernaryV_VV_VX_AAXA<string intrinsic, string instruction, 5771 list<VTypeInfo> vtilist> 5772 : VPatTernaryV_VV_AAXA<intrinsic, instruction, vtilist>, 5773 VPatTernaryV_VX_AAXA<intrinsic, instruction, vtilist>; 5774 5775multiclass VPatTernaryV_VV_VX_AAXA_RM<string intrinsic, string instruction, 5776 list<VTypeInfo> vtilist> 5777 : VPatTernaryV_VV_AAXA_RM<intrinsic, instruction, vtilist>, 5778 VPatTernaryV_VX_AAXA_RM<intrinsic, instruction, vtilist>; 5779 5780multiclass VPatTernaryV_VX_VI<string intrinsic, string instruction, 5781 list<VTypeInfo> vtilist, Operand Imm_type = simm5> 5782 : VPatTernaryV_VX<intrinsic, instruction, vtilist>, 5783 VPatTernaryV_VI<intrinsic, instruction, vtilist, Imm_type>; 5784 5785 5786multiclass VPatBinaryM_VV_VX_VI<string intrinsic, string instruction, 5787 list<VTypeInfo> vtilist> 5788 : VPatBinaryM_VV<intrinsic, instruction, vtilist>, 5789 VPatBinaryM_VX<intrinsic, instruction, vtilist>, 5790 VPatBinaryM_VI<intrinsic, instruction, vtilist>; 5791 5792multiclass VPatTernaryW_VV_VX<string intrinsic, string instruction, 5793 list<VTypeInfoToWide> vtilist> 5794 : VPatTernaryW_VV<intrinsic, instruction, vtilist>, 5795 VPatTernaryW_VX<intrinsic, instruction, vtilist>; 5796 5797multiclass VPatTernaryW_VV_VX_RM<string intrinsic, string instruction, 5798 list<VTypeInfoToWide> vtilist> 5799 : VPatTernaryW_VV_RM<intrinsic, instruction, vtilist>, 5800 VPatTernaryW_VX_RM<intrinsic, instruction, vtilist>; 5801 5802multiclass VPatBinaryM_VV_VX<string intrinsic, string instruction, 5803 list<VTypeInfo> vtilist> 5804 : VPatBinaryM_VV<intrinsic, instruction, vtilist>, 5805 VPatBinaryM_VX<intrinsic, instruction, vtilist>; 5806 5807multiclass VPatBinaryM_VX_VI<string intrinsic, string instruction, 5808 list<VTypeInfo> vtilist> 5809 : VPatBinaryM_VX<intrinsic, instruction, vtilist>, 5810 VPatBinaryM_VI<intrinsic, instruction, vtilist>; 5811 5812multiclass VPatBinaryV_VV_VX_VI_INT<string intrinsic, string instruction, 5813 list<VTypeInfo> vtilist, Operand ImmType = simm5> 5814 : VPatBinaryV_VV_INT<intrinsic#"_vv", instruction, vtilist>, 5815 VPatBinaryV_VX_INT<intrinsic#"_vx", instruction, vtilist>, 5816 VPatBinaryV_VI<intrinsic#"_vx", instruction, vtilist, ImmType>; 5817 5818multiclass VPatReductionV_VS<string intrinsic, string instruction, bit IsFloat = 0> { 5819 foreach vti = !if(IsFloat, NoGroupFloatVectors, NoGroupIntegerVectors) in { 5820 defvar vectorM1 = !cast<VTypeInfo>(!if(IsFloat, "VF", "VI") # vti.SEW # "M1"); 5821 let Predicates = GetVTypePredicates<vti>.Predicates in 5822 defm : VPatTernaryTA<intrinsic, instruction, "VS", 5823 vectorM1.Vector, vti.Vector, 5824 vectorM1.Vector, vti.Mask, 5825 vti.Log2SEW, vti.LMul, 5826 VR, vti.RegClass, VR>; 5827 } 5828 foreach gvti = !if(IsFloat, GroupFloatVectors, GroupIntegerVectors) in { 5829 let Predicates = GetVTypePredicates<gvti>.Predicates in 5830 defm : VPatTernaryTA<intrinsic, instruction, "VS", 5831 gvti.VectorM1, gvti.Vector, 5832 gvti.VectorM1, gvti.Mask, 5833 gvti.Log2SEW, gvti.LMul, 5834 VR, gvti.RegClass, VR>; 5835 } 5836} 5837 5838multiclass VPatReductionV_VS_RM<string intrinsic, string instruction, bit IsFloat = 0> { 5839 foreach vti = !if(IsFloat, NoGroupFloatVectors, NoGroupIntegerVectors) in { 5840 defvar vectorM1 = !cast<VTypeInfo>(!if(IsFloat, "VF", "VI") # vti.SEW # "M1"); 5841 let Predicates = GetVTypePredicates<vti>.Predicates in 5842 defm : VPatTernaryTARoundingMode<intrinsic, instruction, "VS", 5843 vectorM1.Vector, vti.Vector, 5844 vectorM1.Vector, vti.Mask, 5845 vti.Log2SEW, vti.LMul, 5846 VR, vti.RegClass, VR>; 5847 } 5848 foreach gvti = !if(IsFloat, GroupFloatVectors, GroupIntegerVectors) in { 5849 let Predicates = GetVTypePredicates<gvti>.Predicates in 5850 defm : VPatTernaryTARoundingMode<intrinsic, instruction, "VS", 5851 gvti.VectorM1, gvti.Vector, 5852 gvti.VectorM1, gvti.Mask, 5853 gvti.Log2SEW, gvti.LMul, 5854 VR, gvti.RegClass, VR>; 5855 } 5856} 5857 5858multiclass VPatReductionW_VS<string intrinsic, string instruction, bit IsFloat = 0> { 5859 foreach vti = !if(IsFloat, AllFloatVectors, AllIntegerVectors) in { 5860 defvar wtiSEW = !mul(vti.SEW, 2); 5861 if !le(wtiSEW, 64) then { 5862 defvar wtiM1 = !cast<VTypeInfo>(!if(IsFloat, "VF", "VI") # wtiSEW # "M1"); 5863 let Predicates = GetVTypePredicates<vti>.Predicates in 5864 defm : VPatTernaryTA<intrinsic, instruction, "VS", 5865 wtiM1.Vector, vti.Vector, 5866 wtiM1.Vector, vti.Mask, 5867 vti.Log2SEW, vti.LMul, 5868 wtiM1.RegClass, vti.RegClass, 5869 wtiM1.RegClass>; 5870 } 5871 } 5872} 5873 5874multiclass VPatReductionW_VS_RM<string intrinsic, string instruction, bit IsFloat = 0> { 5875 foreach vti = !if(IsFloat, AllFloatVectors, AllIntegerVectors) in { 5876 defvar wtiSEW = !mul(vti.SEW, 2); 5877 if !le(wtiSEW, 64) then { 5878 defvar wtiM1 = !cast<VTypeInfo>(!if(IsFloat, "VF", "VI") # wtiSEW # "M1"); 5879 let Predicates = GetVTypePredicates<vti>.Predicates in 5880 defm : VPatTernaryTARoundingMode<intrinsic, instruction, "VS", 5881 wtiM1.Vector, vti.Vector, 5882 wtiM1.Vector, vti.Mask, 5883 vti.Log2SEW, vti.LMul, 5884 wtiM1.RegClass, vti.RegClass, 5885 wtiM1.RegClass>; 5886 } 5887 } 5888} 5889 5890multiclass VPatConversionVI_VF<string intrinsic, 5891 string instruction> { 5892 foreach fvti = AllFloatVectors in { 5893 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 5894 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 5895 GetVTypePredicates<ivti>.Predicates) in 5896 defm : VPatConversionTA<intrinsic, instruction, "V", 5897 ivti.Vector, fvti.Vector, ivti.Mask, fvti.Log2SEW, 5898 fvti.LMul, ivti.RegClass, fvti.RegClass>; 5899 } 5900} 5901 5902multiclass VPatConversionVI_VF_RM<string intrinsic, 5903 string instruction> { 5904 foreach fvti = AllFloatVectors in { 5905 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 5906 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 5907 GetVTypePredicates<ivti>.Predicates) in 5908 defm : VPatConversionTARoundingMode<intrinsic, instruction, "V", 5909 ivti.Vector, fvti.Vector, ivti.Mask, fvti.Log2SEW, 5910 fvti.LMul, ivti.RegClass, fvti.RegClass>; 5911 } 5912} 5913 5914multiclass VPatConversionVF_VI_RM<string intrinsic, 5915 string instruction> { 5916 foreach fvti = AllFloatVectors in { 5917 defvar ivti = GetIntVTypeInfo<fvti>.Vti; 5918 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 5919 GetVTypePredicates<ivti>.Predicates) in 5920 defm : VPatConversionTARoundingMode<intrinsic, instruction, "V", 5921 fvti.Vector, ivti.Vector, fvti.Mask, ivti.Log2SEW, 5922 ivti.LMul, fvti.RegClass, ivti.RegClass>; 5923 } 5924} 5925 5926multiclass VPatConversionWI_VF<string intrinsic, string instruction> { 5927 foreach fvtiToFWti = AllWidenableFloatVectors in { 5928 defvar fvti = fvtiToFWti.Vti; 5929 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 5930 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 5931 GetVTypePredicates<iwti>.Predicates) in 5932 defm : VPatConversionTA<intrinsic, instruction, "V", 5933 iwti.Vector, fvti.Vector, iwti.Mask, fvti.Log2SEW, 5934 fvti.LMul, iwti.RegClass, fvti.RegClass>; 5935 } 5936} 5937 5938multiclass VPatConversionWI_VF_RM<string intrinsic, string instruction> { 5939 foreach fvtiToFWti = AllWidenableFloatVectors in { 5940 defvar fvti = fvtiToFWti.Vti; 5941 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 5942 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 5943 GetVTypePredicates<iwti>.Predicates) in 5944 defm : VPatConversionTARoundingMode<intrinsic, instruction, "V", 5945 iwti.Vector, fvti.Vector, iwti.Mask, fvti.Log2SEW, 5946 fvti.LMul, iwti.RegClass, fvti.RegClass>; 5947 } 5948} 5949 5950multiclass VPatConversionWF_VI<string intrinsic, string instruction> { 5951 foreach vtiToWti = AllWidenableIntToFloatVectors in { 5952 defvar vti = vtiToWti.Vti; 5953 defvar fwti = vtiToWti.Wti; 5954 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 5955 GetVTypePredicates<fwti>.Predicates) in 5956 defm : VPatConversionTA<intrinsic, instruction, "V", 5957 fwti.Vector, vti.Vector, fwti.Mask, vti.Log2SEW, 5958 vti.LMul, fwti.RegClass, vti.RegClass>; 5959 } 5960} 5961 5962multiclass VPatConversionWF_VF<string intrinsic, string instruction> { 5963 foreach fvtiToFWti = AllWidenableFloatVectors in { 5964 defvar fvti = fvtiToFWti.Vti; 5965 defvar fwti = fvtiToFWti.Wti; 5966 // Define vfwcvt.f.f.v for f16 when Zvfhmin is enable. 5967 let Predicates = !if(!eq(fvti.Scalar, f16), [HasVInstructionsF16Minimal], 5968 !listconcat(GetVTypePredicates<fvti>.Predicates, 5969 GetVTypePredicates<fwti>.Predicates)) in 5970 defm : VPatConversionTA<intrinsic, instruction, "V", 5971 fwti.Vector, fvti.Vector, fwti.Mask, fvti.Log2SEW, 5972 fvti.LMul, fwti.RegClass, fvti.RegClass>; 5973 } 5974} 5975 5976multiclass VPatConversionWF_VF_BF <string intrinsic, string instruction> { 5977 foreach fvtiToFWti = AllWidenableBFloatToFloatVectors in 5978 { 5979 defvar fvti = fvtiToFWti.Vti; 5980 defvar fwti = fvtiToFWti.Wti; 5981 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 5982 GetVTypePredicates<fwti>.Predicates) in 5983 defm : VPatConversionTA<intrinsic, instruction, "V", 5984 fwti.Vector, fvti.Vector, fwti.Mask, fvti.Log2SEW, 5985 fvti.LMul, fwti.RegClass, fvti.RegClass>; 5986 } 5987} 5988 5989multiclass VPatConversionVI_WF <string intrinsic, string instruction> { 5990 foreach vtiToWti = AllWidenableIntToFloatVectors in { 5991 defvar vti = vtiToWti.Vti; 5992 defvar fwti = vtiToWti.Wti; 5993 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 5994 GetVTypePredicates<fwti>.Predicates) in 5995 defm : VPatConversionTA<intrinsic, instruction, "W", 5996 vti.Vector, fwti.Vector, vti.Mask, vti.Log2SEW, 5997 vti.LMul, vti.RegClass, fwti.RegClass>; 5998 } 5999} 6000 6001multiclass VPatConversionVI_WF_RM <string intrinsic, string instruction> { 6002 foreach vtiToWti = AllWidenableIntToFloatVectors in { 6003 defvar vti = vtiToWti.Vti; 6004 defvar fwti = vtiToWti.Wti; 6005 let Predicates = !listconcat(GetVTypePredicates<vti>.Predicates, 6006 GetVTypePredicates<fwti>.Predicates) in 6007 defm : VPatConversionTARoundingMode<intrinsic, instruction, "W", 6008 vti.Vector, fwti.Vector, vti.Mask, vti.Log2SEW, 6009 vti.LMul, vti.RegClass, fwti.RegClass>; 6010 } 6011} 6012 6013multiclass VPatConversionVF_WI_RM <string intrinsic, string instruction> { 6014 foreach fvtiToFWti = AllWidenableFloatVectors in { 6015 defvar fvti = fvtiToFWti.Vti; 6016 defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti; 6017 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 6018 GetVTypePredicates<iwti>.Predicates) in 6019 defm : VPatConversionTARoundingMode<intrinsic, instruction, "W", 6020 fvti.Vector, iwti.Vector, fvti.Mask, fvti.Log2SEW, 6021 fvti.LMul, fvti.RegClass, iwti.RegClass>; 6022 } 6023} 6024 6025multiclass VPatConversionVF_WF <string intrinsic, string instruction> { 6026 foreach fvtiToFWti = AllWidenableFloatVectors in { 6027 defvar fvti = fvtiToFWti.Vti; 6028 defvar fwti = fvtiToFWti.Wti; 6029 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 6030 GetVTypePredicates<fwti>.Predicates) in 6031 defm : VPatConversionTA<intrinsic, instruction, "W", 6032 fvti.Vector, fwti.Vector, fvti.Mask, fvti.Log2SEW, 6033 fvti.LMul, fvti.RegClass, fwti.RegClass>; 6034 } 6035} 6036 6037multiclass VPatConversionVF_WF_RM <string intrinsic, string instruction, 6038 list<VTypeInfoToWide> wlist = AllWidenableFloatVectors> { 6039 foreach fvtiToFWti = wlist in { 6040 defvar fvti = fvtiToFWti.Vti; 6041 defvar fwti = fvtiToFWti.Wti; 6042 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 6043 GetVTypePredicates<fwti>.Predicates) in 6044 defm : VPatConversionTARoundingMode<intrinsic, instruction, "W", 6045 fvti.Vector, fwti.Vector, fvti.Mask, fvti.Log2SEW, 6046 fvti.LMul, fvti.RegClass, fwti.RegClass>; 6047 } 6048} 6049 6050multiclass VPatConversionVF_WF_BF_RM <string intrinsic, string instruction> { 6051 foreach fvtiToFWti = AllWidenableBFloatToFloatVectors in { 6052 defvar fvti = fvtiToFWti.Vti; 6053 defvar fwti = fvtiToFWti.Wti; 6054 let Predicates = !listconcat(GetVTypePredicates<fvti>.Predicates, 6055 GetVTypePredicates<fwti>.Predicates) in 6056 defm : VPatConversionTARoundingMode<intrinsic, instruction, "W", 6057 fvti.Vector, fwti.Vector, fvti.Mask, fvti.Log2SEW, 6058 fvti.LMul, fvti.RegClass, fwti.RegClass>; 6059 } 6060} 6061 6062multiclass VPatCompare_VI<string intrinsic, string inst, 6063 ImmLeaf ImmType> { 6064 foreach vti = AllIntegerVectors in { 6065 defvar Intr = !cast<Intrinsic>(intrinsic); 6066 defvar Pseudo = !cast<Instruction>(inst#"_VI_"#vti.LMul.MX); 6067 let Predicates = GetVTypePredicates<vti>.Predicates in 6068 def : Pat<(vti.Mask (Intr (vti.Vector vti.RegClass:$rs1), 6069 (vti.Scalar ImmType:$rs2), 6070 VLOpFrag)), 6071 (Pseudo vti.RegClass:$rs1, (DecImm ImmType:$rs2), 6072 GPR:$vl, vti.Log2SEW)>; 6073 defvar IntrMask = !cast<Intrinsic>(intrinsic # "_mask"); 6074 defvar PseudoMask = !cast<Instruction>(inst#"_VI_"#vti.LMul.MX#"_MASK"); 6075 let Predicates = GetVTypePredicates<vti>.Predicates in 6076 def : Pat<(vti.Mask (IntrMask (vti.Mask VR:$merge), 6077 (vti.Vector vti.RegClass:$rs1), 6078 (vti.Scalar ImmType:$rs2), 6079 (vti.Mask V0), 6080 VLOpFrag)), 6081 (PseudoMask VR:$merge, vti.RegClass:$rs1, (DecImm ImmType:$rs2), 6082 (vti.Mask V0), GPR:$vl, vti.Log2SEW)>; 6083 } 6084} 6085 6086//===----------------------------------------------------------------------===// 6087// Pseudo instructions 6088//===----------------------------------------------------------------------===// 6089 6090let Predicates = [HasVInstructions] in { 6091 6092//===----------------------------------------------------------------------===// 6093// Pseudo Instructions for CodeGen 6094//===----------------------------------------------------------------------===// 6095 6096let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 1 in { 6097 def PseudoReadVLENB : Pseudo<(outs GPR:$rd), (ins), 6098 [(set GPR:$rd, (riscv_read_vlenb))]>, 6099 PseudoInstExpansion<(CSRRS GPR:$rd, SysRegVLENB.Encoding, X0)>, 6100 Sched<[WriteRdVLENB]>; 6101} 6102 6103let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 1, 6104 Uses = [VL] in 6105def PseudoReadVL : Pseudo<(outs GPR:$rd), (ins), []>, 6106 PseudoInstExpansion<(CSRRS GPR:$rd, SysRegVL.Encoding, X0)>; 6107 6108foreach lmul = MxList in { 6109 foreach nf = NFSet<lmul>.L in { 6110 defvar vreg = SegRegClass<lmul, nf>.RC; 6111 let hasSideEffects = 0, mayLoad = 0, mayStore = 1, isCodeGenOnly = 1, 6112 Size = !mul(4, !sub(!mul(nf, 2), 1)) in { 6113 def "PseudoVSPILL" # nf # "_" # lmul.MX : 6114 Pseudo<(outs), (ins vreg:$rs1, GPR:$rs2), []>; 6115 } 6116 let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 1, 6117 Size = !mul(4, !sub(!mul(nf, 2), 1)) in { 6118 def "PseudoVRELOAD" # nf # "_" # lmul.MX : 6119 Pseudo<(outs vreg:$rs1), (ins GPR:$rs2), []>; 6120 } 6121 } 6122} 6123 6124/// Empty pseudo for RISCVInitUndefPass 6125let hasSideEffects = 0, mayLoad = 0, mayStore = 0, Size = 0, 6126 isCodeGenOnly = 1 in { 6127 def PseudoRVVInitUndefM1 : Pseudo<(outs VR:$vd), (ins), [], "">; 6128 def PseudoRVVInitUndefM2 : Pseudo<(outs VRM2:$vd), (ins), [], "">; 6129 def PseudoRVVInitUndefM4 : Pseudo<(outs VRM4:$vd), (ins), [], "">; 6130 def PseudoRVVInitUndefM8 : Pseudo<(outs VRM8:$vd), (ins), [], "">; 6131} 6132 6133//===----------------------------------------------------------------------===// 6134// 6. Configuration-Setting Instructions 6135//===----------------------------------------------------------------------===// 6136 6137// Pseudos. 6138let hasSideEffects = 1, mayLoad = 0, mayStore = 0, Defs = [VL, VTYPE] in { 6139// Due to rs1=X0 having special meaning, we need a GPRNoX0 register class for 6140// the when we aren't using one of the special X0 encodings. Otherwise it could 6141// be accidentally be made X0 by MachineIR optimizations. To satisfy the 6142// verifier, we also need a GPRX0 instruction for the special encodings. 6143def PseudoVSETVLI : Pseudo<(outs GPR:$rd), (ins GPRNoX0:$rs1, VTypeIOp11:$vtypei), []>, 6144 Sched<[WriteVSETVLI, ReadVSETVLI]>; 6145def PseudoVSETVLIX0 : Pseudo<(outs GPR:$rd), (ins GPRX0:$rs1, VTypeIOp11:$vtypei), []>, 6146 Sched<[WriteVSETVLI, ReadVSETVLI]>; 6147def PseudoVSETIVLI : Pseudo<(outs GPR:$rd), (ins uimm5:$rs1, VTypeIOp10:$vtypei), []>, 6148 Sched<[WriteVSETIVLI]>; 6149} 6150 6151//===----------------------------------------------------------------------===// 6152// 7. Vector Loads and Stores 6153//===----------------------------------------------------------------------===// 6154 6155//===----------------------------------------------------------------------===// 6156// 7.4 Vector Unit-Stride Instructions 6157//===----------------------------------------------------------------------===// 6158 6159// Pseudos Unit-Stride Loads and Stores 6160defm PseudoVL : VPseudoUSLoad; 6161defm PseudoVS : VPseudoUSStore; 6162 6163defm PseudoVLM : VPseudoLoadMask; 6164defm PseudoVSM : VPseudoStoreMask; 6165 6166//===----------------------------------------------------------------------===// 6167// 7.5 Vector Strided Instructions 6168//===----------------------------------------------------------------------===// 6169 6170// Vector Strided Loads and Stores 6171defm PseudoVLS : VPseudoSLoad; 6172defm PseudoVSS : VPseudoSStore; 6173 6174//===----------------------------------------------------------------------===// 6175// 7.6 Vector Indexed Instructions 6176//===----------------------------------------------------------------------===// 6177 6178// Vector Indexed Loads and Stores 6179defm PseudoVLUX : VPseudoILoad<Ordered=false>; 6180defm PseudoVLOX : VPseudoILoad<Ordered=true>; 6181defm PseudoVSOX : VPseudoIStore<Ordered=true>; 6182defm PseudoVSUX : VPseudoIStore<Ordered=false>; 6183 6184//===----------------------------------------------------------------------===// 6185// 7.7. Unit-stride Fault-Only-First Loads 6186//===----------------------------------------------------------------------===// 6187 6188// vleff may update VL register 6189let hasSideEffects = 1, Defs = [VL] in 6190defm PseudoVL : VPseudoFFLoad; 6191 6192//===----------------------------------------------------------------------===// 6193// 7.8. Vector Load/Store Segment Instructions 6194//===----------------------------------------------------------------------===// 6195defm PseudoVLSEG : VPseudoUSSegLoad; 6196defm PseudoVLSSEG : VPseudoSSegLoad; 6197defm PseudoVLOXSEG : VPseudoISegLoad<Ordered=true>; 6198defm PseudoVLUXSEG : VPseudoISegLoad<Ordered=false>; 6199defm PseudoVSSEG : VPseudoUSSegStore; 6200defm PseudoVSSSEG : VPseudoSSegStore; 6201defm PseudoVSOXSEG : VPseudoISegStore<Ordered=true>; 6202defm PseudoVSUXSEG : VPseudoISegStore<Ordered=false>; 6203 6204// vlseg<nf>e<eew>ff.v may update VL register 6205let hasSideEffects = 1, Defs = [VL] in { 6206defm PseudoVLSEG : VPseudoUSSegLoadFF; 6207} 6208 6209//===----------------------------------------------------------------------===// 6210// 11. Vector Integer Arithmetic Instructions 6211//===----------------------------------------------------------------------===// 6212 6213//===----------------------------------------------------------------------===// 6214// 11.1. Vector Single-Width Integer Add and Subtract 6215//===----------------------------------------------------------------------===// 6216defm PseudoVADD : VPseudoVALU_VV_VX_VI; 6217defm PseudoVSUB : VPseudoVALU_VV_VX; 6218defm PseudoVRSUB : VPseudoVALU_VX_VI; 6219 6220foreach vti = AllIntegerVectors in { 6221 // Match vrsub with 2 vector operands to vsub.vv by swapping operands. This 6222 // Occurs when legalizing vrsub.vx intrinsics for i64 on RV32 since we need 6223 // to use a more complex splat sequence. Add the pattern for all VTs for 6224 // consistency. 6225 let Predicates = GetVTypePredicates<vti>.Predicates in { 6226 def : Pat<(vti.Vector (int_riscv_vrsub (vti.Vector vti.RegClass:$merge), 6227 (vti.Vector vti.RegClass:$rs2), 6228 (vti.Vector vti.RegClass:$rs1), 6229 VLOpFrag)), 6230 (!cast<Instruction>("PseudoVSUB_VV_"#vti.LMul.MX) 6231 vti.RegClass:$merge, 6232 vti.RegClass:$rs1, 6233 vti.RegClass:$rs2, 6234 GPR:$vl, 6235 vti.Log2SEW, TU_MU)>; 6236 def : Pat<(vti.Vector (int_riscv_vrsub_mask (vti.Vector vti.RegClass:$merge), 6237 (vti.Vector vti.RegClass:$rs2), 6238 (vti.Vector vti.RegClass:$rs1), 6239 (vti.Mask V0), 6240 VLOpFrag, 6241 (XLenVT timm:$policy))), 6242 (!cast<Instruction>("PseudoVSUB_VV_"#vti.LMul.MX#"_MASK") 6243 vti.RegClass:$merge, 6244 vti.RegClass:$rs1, 6245 vti.RegClass:$rs2, 6246 (vti.Mask V0), 6247 GPR:$vl, 6248 vti.Log2SEW, 6249 (XLenVT timm:$policy))>; 6250 6251 // Match VSUB with a small immediate to vadd.vi by negating the immediate. 6252 def : Pat<(vti.Vector (int_riscv_vsub (vti.Vector (undef)), 6253 (vti.Vector vti.RegClass:$rs1), 6254 (vti.Scalar simm5_plus1:$rs2), 6255 VLOpFrag)), 6256 (!cast<Instruction>("PseudoVADD_VI_"#vti.LMul.MX) (vti.Vector (IMPLICIT_DEF)), 6257 vti.RegClass:$rs1, 6258 (NegImm simm5_plus1:$rs2), 6259 GPR:$vl, 6260 vti.Log2SEW, TA_MA)>; 6261 def : Pat<(vti.Vector (int_riscv_vsub_mask (vti.Vector vti.RegClass:$merge), 6262 (vti.Vector vti.RegClass:$rs1), 6263 (vti.Scalar simm5_plus1:$rs2), 6264 (vti.Mask V0), 6265 VLOpFrag, 6266 (XLenVT timm:$policy))), 6267 (!cast<Instruction>("PseudoVADD_VI_"#vti.LMul.MX#"_MASK") 6268 vti.RegClass:$merge, 6269 vti.RegClass:$rs1, 6270 (NegImm simm5_plus1:$rs2), 6271 (vti.Mask V0), 6272 GPR:$vl, 6273 vti.Log2SEW, 6274 (XLenVT timm:$policy))>; 6275 } 6276} 6277 6278//===----------------------------------------------------------------------===// 6279// 11.2. Vector Widening Integer Add/Subtract 6280//===----------------------------------------------------------------------===// 6281defm PseudoVWADDU : VPseudoVWALU_VV_VX; 6282defm PseudoVWSUBU : VPseudoVWALU_VV_VX; 6283defm PseudoVWADD : VPseudoVWALU_VV_VX; 6284defm PseudoVWSUB : VPseudoVWALU_VV_VX; 6285defm PseudoVWADDU : VPseudoVWALU_WV_WX; 6286defm PseudoVWSUBU : VPseudoVWALU_WV_WX; 6287defm PseudoVWADD : VPseudoVWALU_WV_WX; 6288defm PseudoVWSUB : VPseudoVWALU_WV_WX; 6289 6290//===----------------------------------------------------------------------===// 6291// 11.3. Vector Integer Extension 6292//===----------------------------------------------------------------------===// 6293defm PseudoVZEXT_VF2 : PseudoVEXT_VF2; 6294defm PseudoVZEXT_VF4 : PseudoVEXT_VF4; 6295defm PseudoVZEXT_VF8 : PseudoVEXT_VF8; 6296defm PseudoVSEXT_VF2 : PseudoVEXT_VF2; 6297defm PseudoVSEXT_VF4 : PseudoVEXT_VF4; 6298defm PseudoVSEXT_VF8 : PseudoVEXT_VF8; 6299 6300//===----------------------------------------------------------------------===// 6301// 11.4. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions 6302//===----------------------------------------------------------------------===// 6303defm PseudoVADC : VPseudoVCALU_VM_XM_IM; 6304defm PseudoVMADC : VPseudoVCALUM_VM_XM_IM<"@earlyclobber $rd">; 6305defm PseudoVMADC : VPseudoVCALUM_V_X_I<"@earlyclobber $rd">; 6306 6307defm PseudoVSBC : VPseudoVCALU_VM_XM; 6308defm PseudoVMSBC : VPseudoVCALUM_VM_XM<"@earlyclobber $rd">; 6309defm PseudoVMSBC : VPseudoVCALUM_V_X<"@earlyclobber $rd">; 6310 6311//===----------------------------------------------------------------------===// 6312// 11.5. Vector Bitwise Logical Instructions 6313//===----------------------------------------------------------------------===// 6314defm PseudoVAND : VPseudoVALU_VV_VX_VI; 6315defm PseudoVOR : VPseudoVALU_VV_VX_VI; 6316defm PseudoVXOR : VPseudoVALU_VV_VX_VI; 6317 6318//===----------------------------------------------------------------------===// 6319// 11.6. Vector Single-Width Bit Shift Instructions 6320//===----------------------------------------------------------------------===// 6321defm PseudoVSLL : VPseudoVSHT_VV_VX_VI<uimm5>; 6322defm PseudoVSRL : VPseudoVSHT_VV_VX_VI<uimm5>; 6323defm PseudoVSRA : VPseudoVSHT_VV_VX_VI<uimm5>; 6324 6325//===----------------------------------------------------------------------===// 6326// 11.7. Vector Narrowing Integer Right Shift Instructions 6327//===----------------------------------------------------------------------===// 6328defm PseudoVNSRL : VPseudoVNSHT_WV_WX_WI; 6329defm PseudoVNSRA : VPseudoVNSHT_WV_WX_WI; 6330 6331//===----------------------------------------------------------------------===// 6332// 11.8. Vector Integer Comparison Instructions 6333//===----------------------------------------------------------------------===// 6334defm PseudoVMSEQ : VPseudoVCMPM_VV_VX_VI; 6335defm PseudoVMSNE : VPseudoVCMPM_VV_VX_VI; 6336defm PseudoVMSLTU : VPseudoVCMPM_VV_VX; 6337defm PseudoVMSLT : VPseudoVCMPM_VV_VX; 6338defm PseudoVMSLEU : VPseudoVCMPM_VV_VX_VI; 6339defm PseudoVMSLE : VPseudoVCMPM_VV_VX_VI; 6340defm PseudoVMSGTU : VPseudoVCMPM_VX_VI; 6341defm PseudoVMSGT : VPseudoVCMPM_VX_VI; 6342 6343//===----------------------------------------------------------------------===// 6344// 11.9. Vector Integer Min/Max Instructions 6345//===----------------------------------------------------------------------===// 6346defm PseudoVMINU : VPseudoVMINMAX_VV_VX; 6347defm PseudoVMIN : VPseudoVMINMAX_VV_VX; 6348defm PseudoVMAXU : VPseudoVMINMAX_VV_VX; 6349defm PseudoVMAX : VPseudoVMINMAX_VV_VX; 6350 6351//===----------------------------------------------------------------------===// 6352// 11.10. Vector Single-Width Integer Multiply Instructions 6353//===----------------------------------------------------------------------===// 6354defm PseudoVMUL : VPseudoVMUL_VV_VX; 6355defm PseudoVMULH : VPseudoVMUL_VV_VX; 6356defm PseudoVMULHU : VPseudoVMUL_VV_VX; 6357defm PseudoVMULHSU : VPseudoVMUL_VV_VX; 6358 6359//===----------------------------------------------------------------------===// 6360// 11.11. Vector Integer Divide Instructions 6361//===----------------------------------------------------------------------===// 6362defm PseudoVDIVU : VPseudoVDIV_VV_VX; 6363defm PseudoVDIV : VPseudoVDIV_VV_VX; 6364defm PseudoVREMU : VPseudoVDIV_VV_VX; 6365defm PseudoVREM : VPseudoVDIV_VV_VX; 6366 6367//===----------------------------------------------------------------------===// 6368// 11.12. Vector Widening Integer Multiply Instructions 6369//===----------------------------------------------------------------------===// 6370defm PseudoVWMUL : VPseudoVWMUL_VV_VX; 6371defm PseudoVWMULU : VPseudoVWMUL_VV_VX; 6372defm PseudoVWMULSU : VPseudoVWMUL_VV_VX; 6373 6374//===----------------------------------------------------------------------===// 6375// 11.13. Vector Single-Width Integer Multiply-Add Instructions 6376//===----------------------------------------------------------------------===// 6377defm PseudoVMACC : VPseudoVMAC_VV_VX_AAXA; 6378defm PseudoVNMSAC : VPseudoVMAC_VV_VX_AAXA; 6379defm PseudoVMADD : VPseudoVMAC_VV_VX_AAXA; 6380defm PseudoVNMSUB : VPseudoVMAC_VV_VX_AAXA; 6381 6382//===----------------------------------------------------------------------===// 6383// 11.14. Vector Widening Integer Multiply-Add Instructions 6384//===----------------------------------------------------------------------===// 6385defm PseudoVWMACCU : VPseudoVWMAC_VV_VX; 6386defm PseudoVWMACC : VPseudoVWMAC_VV_VX; 6387defm PseudoVWMACCSU : VPseudoVWMAC_VV_VX; 6388defm PseudoVWMACCUS : VPseudoVWMAC_VX; 6389 6390//===----------------------------------------------------------------------===// 6391// 11.15. Vector Integer Merge Instructions 6392//===----------------------------------------------------------------------===// 6393defm PseudoVMERGE : VPseudoVMRG_VM_XM_IM; 6394 6395//===----------------------------------------------------------------------===// 6396// 11.16. Vector Integer Move Instructions 6397//===----------------------------------------------------------------------===// 6398defm PseudoVMV_V : VPseudoUnaryVMV_V_X_I; 6399 6400//===----------------------------------------------------------------------===// 6401// 12. Vector Fixed-Point Arithmetic Instructions 6402//===----------------------------------------------------------------------===// 6403 6404//===----------------------------------------------------------------------===// 6405// 12.1. Vector Single-Width Saturating Add and Subtract 6406//===----------------------------------------------------------------------===// 6407let Defs = [VXSAT], hasSideEffects = 1 in { 6408 defm PseudoVSADDU : VPseudoVSALU_VV_VX_VI; 6409 defm PseudoVSADD : VPseudoVSALU_VV_VX_VI; 6410 defm PseudoVSSUBU : VPseudoVSALU_VV_VX; 6411 defm PseudoVSSUB : VPseudoVSALU_VV_VX; 6412} 6413 6414//===----------------------------------------------------------------------===// 6415// 12.2. Vector Single-Width Averaging Add and Subtract 6416//===----------------------------------------------------------------------===// 6417defm PseudoVAADDU : VPseudoVAALU_VV_VX_RM; 6418defm PseudoVAADD : VPseudoVAALU_VV_VX_RM; 6419defm PseudoVASUBU : VPseudoVAALU_VV_VX_RM; 6420defm PseudoVASUB : VPseudoVAALU_VV_VX_RM; 6421 6422//===----------------------------------------------------------------------===// 6423// 12.3. Vector Single-Width Fractional Multiply with Rounding and Saturation 6424//===----------------------------------------------------------------------===// 6425let Defs = [VXSAT], hasSideEffects = 1 in { 6426 defm PseudoVSMUL : VPseudoVSMUL_VV_VX_RM; 6427} 6428 6429//===----------------------------------------------------------------------===// 6430// 12.4. Vector Single-Width Scaling Shift Instructions 6431//===----------------------------------------------------------------------===// 6432defm PseudoVSSRL : VPseudoVSSHT_VV_VX_VI_RM<uimm5>; 6433defm PseudoVSSRA : VPseudoVSSHT_VV_VX_VI_RM<uimm5>; 6434 6435//===----------------------------------------------------------------------===// 6436// 12.5. Vector Narrowing Fixed-Point Clip Instructions 6437//===----------------------------------------------------------------------===// 6438let Defs = [VXSAT], hasSideEffects = 1 in { 6439 defm PseudoVNCLIP : VPseudoVNCLP_WV_WX_WI_RM; 6440 defm PseudoVNCLIPU : VPseudoVNCLP_WV_WX_WI_RM; 6441} 6442 6443} // Predicates = [HasVInstructions] 6444 6445//===----------------------------------------------------------------------===// 6446// 13. Vector Floating-Point Instructions 6447//===----------------------------------------------------------------------===// 6448 6449let Predicates = [HasVInstructionsAnyF] in { 6450//===----------------------------------------------------------------------===// 6451// 13.2. Vector Single-Width Floating-Point Add/Subtract Instructions 6452//===----------------------------------------------------------------------===// 6453let mayRaiseFPException = true, hasPostISelHook = 1 in { 6454defm PseudoVFADD : VPseudoVALU_VV_VF_RM; 6455defm PseudoVFSUB : VPseudoVALU_VV_VF_RM; 6456defm PseudoVFRSUB : VPseudoVALU_VF_RM; 6457} 6458 6459//===----------------------------------------------------------------------===// 6460// 13.3. Vector Widening Floating-Point Add/Subtract Instructions 6461//===----------------------------------------------------------------------===// 6462let mayRaiseFPException = true, hasSideEffects = 0, hasPostISelHook = 1 in { 6463defm PseudoVFWADD : VPseudoVFWALU_VV_VF_RM; 6464defm PseudoVFWSUB : VPseudoVFWALU_VV_VF_RM; 6465defm PseudoVFWADD : VPseudoVFWALU_WV_WF_RM; 6466defm PseudoVFWSUB : VPseudoVFWALU_WV_WF_RM; 6467} 6468 6469//===----------------------------------------------------------------------===// 6470// 13.4. Vector Single-Width Floating-Point Multiply/Divide Instructions 6471//===----------------------------------------------------------------------===// 6472let mayRaiseFPException = true, hasSideEffects = 0, hasPostISelHook = 1 in { 6473defm PseudoVFMUL : VPseudoVFMUL_VV_VF_RM; 6474defm PseudoVFDIV : VPseudoVFDIV_VV_VF_RM; 6475defm PseudoVFRDIV : VPseudoVFRDIV_VF_RM; 6476} 6477 6478//===----------------------------------------------------------------------===// 6479// 13.5. Vector Widening Floating-Point Multiply 6480//===----------------------------------------------------------------------===// 6481let mayRaiseFPException = true, hasSideEffects = 0 in { 6482defm PseudoVFWMUL : VPseudoVWMUL_VV_VF_RM; 6483} 6484 6485//===----------------------------------------------------------------------===// 6486// 13.6. Vector Single-Width Floating-Point Fused Multiply-Add Instructions 6487//===----------------------------------------------------------------------===// 6488let mayRaiseFPException = true, hasSideEffects = 0, hasPostISelHook = 1 in { 6489defm PseudoVFMACC : VPseudoVMAC_VV_VF_AAXA_RM; 6490defm PseudoVFNMACC : VPseudoVMAC_VV_VF_AAXA_RM; 6491defm PseudoVFMSAC : VPseudoVMAC_VV_VF_AAXA_RM; 6492defm PseudoVFNMSAC : VPseudoVMAC_VV_VF_AAXA_RM; 6493defm PseudoVFMADD : VPseudoVMAC_VV_VF_AAXA_RM; 6494defm PseudoVFNMADD : VPseudoVMAC_VV_VF_AAXA_RM; 6495defm PseudoVFMSUB : VPseudoVMAC_VV_VF_AAXA_RM; 6496defm PseudoVFNMSUB : VPseudoVMAC_VV_VF_AAXA_RM; 6497} 6498 6499//===----------------------------------------------------------------------===// 6500// 13.7. Vector Widening Floating-Point Fused Multiply-Add Instructions 6501//===----------------------------------------------------------------------===// 6502let mayRaiseFPException = true, hasSideEffects = 0, hasPostISelHook = 1 in { 6503defm PseudoVFWMACC : VPseudoVWMAC_VV_VF_RM; 6504defm PseudoVFWNMACC : VPseudoVWMAC_VV_VF_RM; 6505defm PseudoVFWMSAC : VPseudoVWMAC_VV_VF_RM; 6506defm PseudoVFWNMSAC : VPseudoVWMAC_VV_VF_RM; 6507let Predicates = [HasStdExtZvfbfwma] in 6508defm PseudoVFWMACCBF16 : VPseudoVWMAC_VV_VF_BF_RM; 6509} 6510 6511//===----------------------------------------------------------------------===// 6512// 13.8. Vector Floating-Point Square-Root Instruction 6513//===----------------------------------------------------------------------===// 6514let mayRaiseFPException = true, hasSideEffects = 0 in 6515defm PseudoVFSQRT : VPseudoVSQR_V_RM; 6516 6517//===----------------------------------------------------------------------===// 6518// 13.9. Vector Floating-Point Reciprocal Square-Root Estimate Instruction 6519//===----------------------------------------------------------------------===// 6520let mayRaiseFPException = true in 6521defm PseudoVFRSQRT7 : VPseudoVRCP_V; 6522 6523//===----------------------------------------------------------------------===// 6524// 13.10. Vector Floating-Point Reciprocal Estimate Instruction 6525//===----------------------------------------------------------------------===// 6526let mayRaiseFPException = true, hasSideEffects = 0 in 6527defm PseudoVFREC7 : VPseudoVRCP_V_RM; 6528 6529//===----------------------------------------------------------------------===// 6530// 13.11. Vector Floating-Point Min/Max Instructions 6531//===----------------------------------------------------------------------===// 6532let mayRaiseFPException = true in { 6533defm PseudoVFMIN : VPseudoVMAX_VV_VF; 6534defm PseudoVFMAX : VPseudoVMAX_VV_VF; 6535} 6536 6537//===----------------------------------------------------------------------===// 6538// 13.12. Vector Floating-Point Sign-Injection Instructions 6539//===----------------------------------------------------------------------===// 6540defm PseudoVFSGNJ : VPseudoVSGNJ_VV_VF; 6541defm PseudoVFSGNJN : VPseudoVSGNJ_VV_VF; 6542defm PseudoVFSGNJX : VPseudoVSGNJ_VV_VF; 6543 6544//===----------------------------------------------------------------------===// 6545// 13.13. Vector Floating-Point Compare Instructions 6546//===----------------------------------------------------------------------===// 6547let mayRaiseFPException = true in { 6548defm PseudoVMFEQ : VPseudoVCMPM_VV_VF; 6549defm PseudoVMFNE : VPseudoVCMPM_VV_VF; 6550defm PseudoVMFLT : VPseudoVCMPM_VV_VF; 6551defm PseudoVMFLE : VPseudoVCMPM_VV_VF; 6552defm PseudoVMFGT : VPseudoVCMPM_VF; 6553defm PseudoVMFGE : VPseudoVCMPM_VF; 6554} 6555 6556//===----------------------------------------------------------------------===// 6557// 13.14. Vector Floating-Point Classify Instruction 6558//===----------------------------------------------------------------------===// 6559defm PseudoVFCLASS : VPseudoVCLS_V; 6560 6561//===----------------------------------------------------------------------===// 6562// 13.15. Vector Floating-Point Merge Instruction 6563//===----------------------------------------------------------------------===// 6564defm PseudoVFMERGE : VPseudoVMRG_FM; 6565 6566//===----------------------------------------------------------------------===// 6567// 13.16. Vector Floating-Point Move Instruction 6568//===----------------------------------------------------------------------===// 6569defm PseudoVFMV_V : VPseudoVMV_F; 6570 6571//===----------------------------------------------------------------------===// 6572// 13.17. Single-Width Floating-Point/Integer Type-Convert Instructions 6573//===----------------------------------------------------------------------===// 6574let mayRaiseFPException = true in { 6575let hasSideEffects = 0, hasPostISelHook = 1 in { 6576defm PseudoVFCVT_XU_F : VPseudoVCVTI_V_RM; 6577defm PseudoVFCVT_X_F : VPseudoVCVTI_V_RM; 6578} 6579 6580defm PseudoVFCVT_RM_XU_F : VPseudoVCVTI_RM_V; 6581defm PseudoVFCVT_RM_X_F : VPseudoVCVTI_RM_V; 6582 6583defm PseudoVFCVT_RTZ_XU_F : VPseudoVCVTI_V; 6584defm PseudoVFCVT_RTZ_X_F : VPseudoVCVTI_V; 6585 6586defm PseudoVFROUND_NOEXCEPT : VPseudoVFROUND_NOEXCEPT_V; 6587let hasSideEffects = 0, hasPostISelHook = 1 in { 6588defm PseudoVFCVT_F_XU : VPseudoVCVTF_V_RM; 6589defm PseudoVFCVT_F_X : VPseudoVCVTF_V_RM; 6590} 6591defm PseudoVFCVT_RM_F_XU : VPseudoVCVTF_RM_V; 6592defm PseudoVFCVT_RM_F_X : VPseudoVCVTF_RM_V; 6593} // mayRaiseFPException = true 6594 6595//===----------------------------------------------------------------------===// 6596// 13.18. Widening Floating-Point/Integer Type-Convert Instructions 6597//===----------------------------------------------------------------------===// 6598let mayRaiseFPException = true in { 6599let hasSideEffects = 0, hasPostISelHook = 1 in { 6600defm PseudoVFWCVT_XU_F : VPseudoVWCVTI_V_RM; 6601defm PseudoVFWCVT_X_F : VPseudoVWCVTI_V_RM; 6602} 6603defm PseudoVFWCVT_RM_XU_F : VPseudoVWCVTI_RM_V; 6604defm PseudoVFWCVT_RM_X_F : VPseudoVWCVTI_RM_V; 6605 6606defm PseudoVFWCVT_RTZ_XU_F : VPseudoVWCVTI_V; 6607defm PseudoVFWCVT_RTZ_X_F : VPseudoVWCVTI_V; 6608 6609defm PseudoVFWCVT_F_XU : VPseudoVWCVTF_V; 6610defm PseudoVFWCVT_F_X : VPseudoVWCVTF_V; 6611 6612defm PseudoVFWCVT_F_F : VPseudoVWCVTD_V; 6613defm PseudoVFWCVTBF16_F_F : VPseudoVWCVTD_V; 6614} // mayRaiseFPException = true 6615 6616//===----------------------------------------------------------------------===// 6617// 13.19. Narrowing Floating-Point/Integer Type-Convert Instructions 6618//===----------------------------------------------------------------------===// 6619let mayRaiseFPException = true in { 6620let hasSideEffects = 0, hasPostISelHook = 1 in { 6621defm PseudoVFNCVT_XU_F : VPseudoVNCVTI_W_RM; 6622defm PseudoVFNCVT_X_F : VPseudoVNCVTI_W_RM; 6623} 6624defm PseudoVFNCVT_RM_XU_F : VPseudoVNCVTI_RM_W; 6625defm PseudoVFNCVT_RM_X_F : VPseudoVNCVTI_RM_W; 6626 6627defm PseudoVFNCVT_RTZ_XU_F : VPseudoVNCVTI_W; 6628defm PseudoVFNCVT_RTZ_X_F : VPseudoVNCVTI_W; 6629 6630let hasSideEffects = 0, hasPostISelHook = 1 in { 6631defm PseudoVFNCVT_F_XU : VPseudoVNCVTF_W_RM; 6632defm PseudoVFNCVT_F_X : VPseudoVNCVTF_W_RM; 6633} 6634defm PseudoVFNCVT_RM_F_XU : VPseudoVNCVTF_RM_W; 6635defm PseudoVFNCVT_RM_F_X : VPseudoVNCVTF_RM_W; 6636 6637let hasSideEffects = 0, hasPostISelHook = 1 in 6638defm PseudoVFNCVT_F_F : VPseudoVNCVTD_W_RM; 6639defm PseudoVFNCVTBF16_F_F : VPseudoVNCVTD_W_RM; 6640 6641defm PseudoVFNCVT_ROD_F_F : VPseudoVNCVTD_W; 6642} // mayRaiseFPException = true 6643} // Predicates = [HasVInstructionsAnyF] 6644 6645//===----------------------------------------------------------------------===// 6646// 14. Vector Reduction Operations 6647//===----------------------------------------------------------------------===// 6648 6649let Predicates = [HasVInstructions] in { 6650//===----------------------------------------------------------------------===// 6651// 14.1. Vector Single-Width Integer Reduction Instructions 6652//===----------------------------------------------------------------------===// 6653defm PseudoVREDSUM : VPseudoVRED_VS; 6654defm PseudoVREDAND : VPseudoVRED_VS; 6655defm PseudoVREDOR : VPseudoVRED_VS; 6656defm PseudoVREDXOR : VPseudoVRED_VS; 6657defm PseudoVREDMINU : VPseudoVREDMINMAX_VS; 6658defm PseudoVREDMIN : VPseudoVREDMINMAX_VS; 6659defm PseudoVREDMAXU : VPseudoVREDMINMAX_VS; 6660defm PseudoVREDMAX : VPseudoVREDMINMAX_VS; 6661 6662//===----------------------------------------------------------------------===// 6663// 14.2. Vector Widening Integer Reduction Instructions 6664//===----------------------------------------------------------------------===// 6665let IsRVVWideningReduction = 1 in { 6666defm PseudoVWREDSUMU : VPseudoVWRED_VS; 6667defm PseudoVWREDSUM : VPseudoVWRED_VS; 6668} 6669} // Predicates = [HasVInstructions] 6670 6671let Predicates = [HasVInstructionsAnyF] in { 6672//===----------------------------------------------------------------------===// 6673// 14.3. Vector Single-Width Floating-Point Reduction Instructions 6674//===----------------------------------------------------------------------===// 6675let mayRaiseFPException = true, 6676 hasSideEffects = 0 in { 6677defm PseudoVFREDOSUM : VPseudoVFREDO_VS_RM; 6678defm PseudoVFREDUSUM : VPseudoVFRED_VS_RM; 6679} 6680let mayRaiseFPException = true in { 6681defm PseudoVFREDMIN : VPseudoVFREDMINMAX_VS; 6682defm PseudoVFREDMAX : VPseudoVFREDMINMAX_VS; 6683} 6684 6685//===----------------------------------------------------------------------===// 6686// 14.4. Vector Widening Floating-Point Reduction Instructions 6687//===----------------------------------------------------------------------===// 6688let IsRVVWideningReduction = 1, 6689 hasSideEffects = 0, 6690 mayRaiseFPException = true in { 6691defm PseudoVFWREDUSUM : VPseudoVFWRED_VS_RM; 6692defm PseudoVFWREDOSUM : VPseudoVFWREDO_VS_RM; 6693} 6694 6695} // Predicates = [HasVInstructionsAnyF] 6696 6697//===----------------------------------------------------------------------===// 6698// 15. Vector Mask Instructions 6699//===----------------------------------------------------------------------===// 6700 6701//===----------------------------------------------------------------------===// 6702// 15.1 Vector Mask-Register Logical Instructions 6703//===----------------------------------------------------------------------===// 6704 6705defm PseudoVMAND: VPseudoVALU_MM<Commutable=1>; 6706defm PseudoVMNAND: VPseudoVALU_MM<Commutable=1>; 6707defm PseudoVMANDN: VPseudoVALU_MM; 6708defm PseudoVMXOR: VPseudoVALU_MM<Commutable=1>; 6709defm PseudoVMOR: VPseudoVALU_MM<Commutable=1>; 6710defm PseudoVMNOR: VPseudoVALU_MM<Commutable=1>; 6711defm PseudoVMORN: VPseudoVALU_MM; 6712defm PseudoVMXNOR: VPseudoVALU_MM<Commutable=1>; 6713 6714// Pseudo instructions 6715defm PseudoVMCLR : VPseudoNullaryPseudoM<"VMXOR">; 6716defm PseudoVMSET : VPseudoNullaryPseudoM<"VMXNOR">; 6717 6718//===----------------------------------------------------------------------===// 6719// 15.2. Vector mask population count vcpop 6720//===----------------------------------------------------------------------===// 6721 6722let IsSignExtendingOpW = 1 in 6723defm PseudoVCPOP: VPseudoVPOP_M; 6724 6725//===----------------------------------------------------------------------===// 6726// 15.3. vfirst find-first-set mask bit 6727//===----------------------------------------------------------------------===// 6728 6729let IsSignExtendingOpW = 1 in 6730defm PseudoVFIRST: VPseudoV1ST_M; 6731 6732//===----------------------------------------------------------------------===// 6733// 15.4. vmsbf.m set-before-first mask bit 6734//===----------------------------------------------------------------------===// 6735defm PseudoVMSBF: VPseudoVSFS_M; 6736 6737//===----------------------------------------------------------------------===// 6738// 15.5. vmsif.m set-including-first mask bit 6739//===----------------------------------------------------------------------===// 6740defm PseudoVMSIF: VPseudoVSFS_M; 6741 6742//===----------------------------------------------------------------------===// 6743// 15.6. vmsof.m set-only-first mask bit 6744//===----------------------------------------------------------------------===// 6745defm PseudoVMSOF: VPseudoVSFS_M; 6746 6747//===----------------------------------------------------------------------===// 6748// 15.8. Vector Iota Instruction 6749//===----------------------------------------------------------------------===// 6750defm PseudoVIOTA_M: VPseudoVIOT_M; 6751 6752//===----------------------------------------------------------------------===// 6753// 15.9. Vector Element Index Instruction 6754//===----------------------------------------------------------------------===// 6755defm PseudoVID : VPseudoVID_V; 6756 6757//===----------------------------------------------------------------------===// 6758// 16. Vector Permutation Instructions 6759//===----------------------------------------------------------------------===// 6760 6761//===----------------------------------------------------------------------===// 6762// 16.1. Integer Scalar Move Instructions 6763//===----------------------------------------------------------------------===// 6764 6765let Predicates = [HasVInstructions] in { 6766let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6767 let HasSEWOp = 1, BaseInstr = VMV_X_S in 6768 def PseudoVMV_X_S: 6769 Pseudo<(outs GPR:$rd), (ins VR:$rs2, ixlenimm:$sew), []>, 6770 Sched<[WriteVIMovVX, ReadVIMovVX]>, 6771 RISCVVPseudo; 6772 let HasVLOp = 1, HasSEWOp = 1, BaseInstr = VMV_S_X, 6773 Constraints = "$rd = $rs1" in 6774 def PseudoVMV_S_X: Pseudo<(outs VR:$rd), 6775 (ins VR:$rs1, GPR:$rs2, AVL:$vl, ixlenimm:$sew), 6776 []>, 6777 Sched<[WriteVIMovXV, ReadVIMovXV, ReadVIMovXX]>, 6778 RISCVVPseudo; 6779} 6780} // Predicates = [HasVInstructions] 6781 6782//===----------------------------------------------------------------------===// 6783// 16.2. Floating-Point Scalar Move Instructions 6784//===----------------------------------------------------------------------===// 6785 6786let Predicates = [HasVInstructionsAnyF] in { 6787let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in { 6788 foreach f = FPList in { 6789 foreach m = f.MxList in { 6790 defvar mx = m.MX; 6791 let VLMul = m.value in { 6792 let HasSEWOp = 1, BaseInstr = VFMV_F_S in 6793 def "PseudoVFMV_" # f.FX # "_S_" # mx : 6794 Pseudo<(outs f.fprclass:$rd), 6795 (ins m.vrclass:$rs2, ixlenimm:$sew), []>, 6796 Sched<[WriteVFMovVF, ReadVFMovVF]>, 6797 RISCVVPseudo; 6798 let HasVLOp = 1, HasSEWOp = 1, BaseInstr = VFMV_S_F, 6799 Constraints = "$rd = $rs1" in 6800 def "PseudoVFMV_S_" # f.FX # "_" # mx : 6801 Pseudo<(outs m.vrclass:$rd), 6802 (ins m.vrclass:$rs1, f.fprclass:$rs2, 6803 AVL:$vl, ixlenimm:$sew), 6804 []>, 6805 Sched<[WriteVFMovFV, ReadVFMovFV, ReadVFMovFX]>, 6806 RISCVVPseudo; 6807 } 6808 } 6809 } 6810} 6811} // Predicates = [HasVInstructionsAnyF] 6812 6813//===----------------------------------------------------------------------===// 6814// 16.3. Vector Slide Instructions 6815//===----------------------------------------------------------------------===// 6816let Predicates = [HasVInstructions] in { 6817 defm PseudoVSLIDEUP : VPseudoVSLD_VX_VI<uimm5, "@earlyclobber $rd">; 6818 defm PseudoVSLIDEDOWN : VPseudoVSLD_VX_VI<uimm5>; 6819 defm PseudoVSLIDE1UP : VPseudoVSLD1_VX<"@earlyclobber $rd">; 6820 defm PseudoVSLIDE1DOWN : VPseudoVSLD1_VX; 6821} // Predicates = [HasVInstructions] 6822 6823let Predicates = [HasVInstructionsAnyF] in { 6824 defm PseudoVFSLIDE1UP : VPseudoVSLD1_VF<"@earlyclobber $rd">; 6825 defm PseudoVFSLIDE1DOWN : VPseudoVSLD1_VF; 6826} // Predicates = [HasVInstructionsAnyF] 6827 6828//===----------------------------------------------------------------------===// 6829// 16.4. Vector Register Gather Instructions 6830//===----------------------------------------------------------------------===// 6831defm PseudoVRGATHER : VPseudoVGTR_VV_VX_VI<uimm5, "@earlyclobber $rd">; 6832defm PseudoVRGATHEREI16 : VPseudoVGTR_VV_EEW<eew=16, 6833 Constraint="@earlyclobber $rd">; 6834 6835//===----------------------------------------------------------------------===// 6836// 16.5. Vector Compress Instruction 6837//===----------------------------------------------------------------------===// 6838defm PseudoVCOMPRESS : VPseudoVCPR_V; 6839 6840//===----------------------------------------------------------------------===// 6841// Patterns. 6842//===----------------------------------------------------------------------===// 6843 6844//===----------------------------------------------------------------------===// 6845// 11. Vector Integer Arithmetic Instructions 6846//===----------------------------------------------------------------------===// 6847 6848//===----------------------------------------------------------------------===// 6849// 11.1. Vector Single-Width Integer Add and Subtract 6850//===----------------------------------------------------------------------===// 6851defm : VPatBinaryV_VV_VX_VI<"int_riscv_vadd", "PseudoVADD", AllIntegerVectors>; 6852defm : VPatBinaryV_VV_VX<"int_riscv_vsub", "PseudoVSUB", AllIntegerVectors>; 6853defm : VPatBinaryV_VX_VI<"int_riscv_vrsub", "PseudoVRSUB", AllIntegerVectors>; 6854 6855//===----------------------------------------------------------------------===// 6856// 11.2. Vector Widening Integer Add/Subtract 6857//===----------------------------------------------------------------------===// 6858defm : VPatBinaryW_VV_VX<"int_riscv_vwaddu", "PseudoVWADDU", AllWidenableIntVectors>; 6859defm : VPatBinaryW_VV_VX<"int_riscv_vwsubu", "PseudoVWSUBU", AllWidenableIntVectors>; 6860defm : VPatBinaryW_VV_VX<"int_riscv_vwadd", "PseudoVWADD", AllWidenableIntVectors>; 6861defm : VPatBinaryW_VV_VX<"int_riscv_vwsub", "PseudoVWSUB", AllWidenableIntVectors>; 6862defm : VPatBinaryW_WV_WX<"int_riscv_vwaddu_w", "PseudoVWADDU", AllWidenableIntVectors>; 6863defm : VPatBinaryW_WV_WX<"int_riscv_vwsubu_w", "PseudoVWSUBU", AllWidenableIntVectors>; 6864defm : VPatBinaryW_WV_WX<"int_riscv_vwadd_w", "PseudoVWADD", AllWidenableIntVectors>; 6865defm : VPatBinaryW_WV_WX<"int_riscv_vwsub_w", "PseudoVWSUB", AllWidenableIntVectors>; 6866 6867//===----------------------------------------------------------------------===// 6868// 11.3. Vector Integer Extension 6869//===----------------------------------------------------------------------===// 6870defm : VPatUnaryV_VF<"int_riscv_vzext", "PseudoVZEXT", "VF2", 6871 AllFractionableVF2IntVectors>; 6872defm : VPatUnaryV_VF<"int_riscv_vzext", "PseudoVZEXT", "VF4", 6873 AllFractionableVF4IntVectors>; 6874defm : VPatUnaryV_VF<"int_riscv_vzext", "PseudoVZEXT", "VF8", 6875 AllFractionableVF8IntVectors>; 6876defm : VPatUnaryV_VF<"int_riscv_vsext", "PseudoVSEXT", "VF2", 6877 AllFractionableVF2IntVectors>; 6878defm : VPatUnaryV_VF<"int_riscv_vsext", "PseudoVSEXT", "VF4", 6879 AllFractionableVF4IntVectors>; 6880defm : VPatUnaryV_VF<"int_riscv_vsext", "PseudoVSEXT", "VF8", 6881 AllFractionableVF8IntVectors>; 6882 6883//===----------------------------------------------------------------------===// 6884// 11.4. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions 6885//===----------------------------------------------------------------------===// 6886defm : VPatBinaryV_VM_XM_IM<"int_riscv_vadc", "PseudoVADC">; 6887defm : VPatBinaryM_VM_XM_IM<"int_riscv_vmadc_carry_in", "PseudoVMADC">; 6888defm : VPatBinaryM_V_X_I<"int_riscv_vmadc", "PseudoVMADC">; 6889 6890defm : VPatBinaryV_VM_XM<"int_riscv_vsbc", "PseudoVSBC">; 6891defm : VPatBinaryM_VM_XM<"int_riscv_vmsbc_borrow_in", "PseudoVMSBC">; 6892defm : VPatBinaryM_V_X<"int_riscv_vmsbc", "PseudoVMSBC">; 6893 6894//===----------------------------------------------------------------------===// 6895// 11.5. Vector Bitwise Logical Instructions 6896//===----------------------------------------------------------------------===// 6897defm : VPatBinaryV_VV_VX_VI<"int_riscv_vand", "PseudoVAND", AllIntegerVectors>; 6898defm : VPatBinaryV_VV_VX_VI<"int_riscv_vor", "PseudoVOR", AllIntegerVectors>; 6899defm : VPatBinaryV_VV_VX_VI<"int_riscv_vxor", "PseudoVXOR", AllIntegerVectors>; 6900 6901//===----------------------------------------------------------------------===// 6902// 11.6. Vector Single-Width Bit Shift Instructions 6903//===----------------------------------------------------------------------===// 6904defm : VPatBinaryV_VV_VX_VI<"int_riscv_vsll", "PseudoVSLL", AllIntegerVectors, 6905 uimm5>; 6906defm : VPatBinaryV_VV_VX_VI<"int_riscv_vsrl", "PseudoVSRL", AllIntegerVectors, 6907 uimm5>; 6908defm : VPatBinaryV_VV_VX_VI<"int_riscv_vsra", "PseudoVSRA", AllIntegerVectors, 6909 uimm5>; 6910 6911foreach vti = AllIntegerVectors in { 6912 // Emit shift by 1 as an add since it might be faster. 6913 let Predicates = GetVTypePredicates<vti>.Predicates in { 6914 def : Pat<(vti.Vector (int_riscv_vsll (vti.Vector undef), 6915 (vti.Vector vti.RegClass:$rs1), 6916 (XLenVT 1), VLOpFrag)), 6917 (!cast<Instruction>("PseudoVADD_VV_"#vti.LMul.MX) 6918 (vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, 6919 vti.RegClass:$rs1, GPR:$vl, vti.Log2SEW, TA_MA)>; 6920 def : Pat<(vti.Vector (int_riscv_vsll_mask (vti.Vector vti.RegClass:$merge), 6921 (vti.Vector vti.RegClass:$rs1), 6922 (XLenVT 1), 6923 (vti.Mask V0), 6924 VLOpFrag, 6925 (XLenVT timm:$policy))), 6926 (!cast<Instruction>("PseudoVADD_VV_"#vti.LMul.MX#"_MASK") 6927 vti.RegClass:$merge, 6928 vti.RegClass:$rs1, 6929 vti.RegClass:$rs1, 6930 (vti.Mask V0), 6931 GPR:$vl, 6932 vti.Log2SEW, 6933 (XLenVT timm:$policy))>; 6934 } 6935} 6936 6937//===----------------------------------------------------------------------===// 6938// 11.7. Vector Narrowing Integer Right Shift Instructions 6939//===----------------------------------------------------------------------===// 6940defm : VPatBinaryV_WV_WX_WI<"int_riscv_vnsrl", "PseudoVNSRL", AllWidenableIntVectors>; 6941defm : VPatBinaryV_WV_WX_WI<"int_riscv_vnsra", "PseudoVNSRA", AllWidenableIntVectors>; 6942 6943//===----------------------------------------------------------------------===// 6944// 11.8. Vector Integer Comparison Instructions 6945//===----------------------------------------------------------------------===// 6946defm : VPatBinaryM_VV_VX_VI<"int_riscv_vmseq", "PseudoVMSEQ", AllIntegerVectors>; 6947defm : VPatBinaryM_VV_VX_VI<"int_riscv_vmsne", "PseudoVMSNE", AllIntegerVectors>; 6948defm : VPatBinaryM_VV_VX<"int_riscv_vmsltu", "PseudoVMSLTU", AllIntegerVectors>; 6949defm : VPatBinaryM_VV_VX<"int_riscv_vmslt", "PseudoVMSLT", AllIntegerVectors>; 6950defm : VPatBinaryM_VV_VX_VI<"int_riscv_vmsleu", "PseudoVMSLEU", AllIntegerVectors>; 6951defm : VPatBinaryM_VV_VX_VI<"int_riscv_vmsle", "PseudoVMSLE", AllIntegerVectors>; 6952 6953defm : VPatBinaryM_VX_VI<"int_riscv_vmsgtu", "PseudoVMSGTU", AllIntegerVectors>; 6954defm : VPatBinaryM_VX_VI<"int_riscv_vmsgt", "PseudoVMSGT", AllIntegerVectors>; 6955 6956// Match vmsgt with 2 vector operands to vmslt with the operands swapped. 6957defm : VPatBinarySwappedM_VV<"int_riscv_vmsgtu", "PseudoVMSLTU", AllIntegerVectors>; 6958defm : VPatBinarySwappedM_VV<"int_riscv_vmsgt", "PseudoVMSLT", AllIntegerVectors>; 6959 6960defm : VPatBinarySwappedM_VV<"int_riscv_vmsgeu", "PseudoVMSLEU", AllIntegerVectors>; 6961defm : VPatBinarySwappedM_VV<"int_riscv_vmsge", "PseudoVMSLE", AllIntegerVectors>; 6962 6963// Match vmslt(u).vx intrinsics to vmsle(u).vi if the scalar is -15 to 16 and 6964// non-zero. Zero can be .vx with x0. This avoids the user needing to know that 6965// there is no vmslt(u).vi instruction. Similar for vmsge(u).vx intrinsics 6966// using vmslt(u).vi. 6967defm : VPatCompare_VI<"int_riscv_vmslt", "PseudoVMSLE", simm5_plus1_nonzero>; 6968defm : VPatCompare_VI<"int_riscv_vmsltu", "PseudoVMSLEU", simm5_plus1_nonzero>; 6969 6970// We need to handle 0 for vmsge.vi using vmslt.vi because there is no vmsge.vx. 6971defm : VPatCompare_VI<"int_riscv_vmsge", "PseudoVMSGT", simm5_plus1>; 6972defm : VPatCompare_VI<"int_riscv_vmsgeu", "PseudoVMSGTU", simm5_plus1_nonzero>; 6973 6974//===----------------------------------------------------------------------===// 6975// 11.9. Vector Integer Min/Max Instructions 6976//===----------------------------------------------------------------------===// 6977defm : VPatBinaryV_VV_VX<"int_riscv_vminu", "PseudoVMINU", AllIntegerVectors>; 6978defm : VPatBinaryV_VV_VX<"int_riscv_vmin", "PseudoVMIN", AllIntegerVectors>; 6979defm : VPatBinaryV_VV_VX<"int_riscv_vmaxu", "PseudoVMAXU", AllIntegerVectors>; 6980defm : VPatBinaryV_VV_VX<"int_riscv_vmax", "PseudoVMAX", AllIntegerVectors>; 6981 6982//===----------------------------------------------------------------------===// 6983// 11.10. Vector Single-Width Integer Multiply Instructions 6984//===----------------------------------------------------------------------===// 6985defm : VPatBinaryV_VV_VX<"int_riscv_vmul", "PseudoVMUL", AllIntegerVectors>; 6986 6987defvar IntegerVectorsExceptI64 = !filter(vti, AllIntegerVectors, 6988 !ne(vti.SEW, 64)); 6989defm : VPatBinaryV_VV_VX<"int_riscv_vmulh", "PseudoVMULH", 6990 IntegerVectorsExceptI64>; 6991defm : VPatBinaryV_VV_VX<"int_riscv_vmulhu", "PseudoVMULHU", 6992 IntegerVectorsExceptI64>; 6993defm : VPatBinaryV_VV_VX<"int_riscv_vmulhsu", "PseudoVMULHSU", 6994 IntegerVectorsExceptI64>; 6995 6996// vmulh, vmulhu, vmulhsu are not included for EEW=64 in Zve64*. 6997defvar I64IntegerVectors = !filter(vti, AllIntegerVectors, !eq(vti.SEW, 64)); 6998let Predicates = [HasVInstructionsFullMultiply] in { 6999 defm : VPatBinaryV_VV_VX<"int_riscv_vmulh", "PseudoVMULH", 7000 I64IntegerVectors>; 7001 defm : VPatBinaryV_VV_VX<"int_riscv_vmulhu", "PseudoVMULHU", 7002 I64IntegerVectors>; 7003 defm : VPatBinaryV_VV_VX<"int_riscv_vmulhsu", "PseudoVMULHSU", 7004 I64IntegerVectors>; 7005} 7006 7007//===----------------------------------------------------------------------===// 7008// 11.11. Vector Integer Divide Instructions 7009//===----------------------------------------------------------------------===// 7010defm : VPatBinaryV_VV_VX<"int_riscv_vdivu", "PseudoVDIVU", AllIntegerVectors, isSEWAware=1>; 7011defm : VPatBinaryV_VV_VX<"int_riscv_vdiv", "PseudoVDIV", AllIntegerVectors, isSEWAware=1>; 7012defm : VPatBinaryV_VV_VX<"int_riscv_vremu", "PseudoVREMU", AllIntegerVectors, isSEWAware=1>; 7013defm : VPatBinaryV_VV_VX<"int_riscv_vrem", "PseudoVREM", AllIntegerVectors, isSEWAware=1>; 7014 7015//===----------------------------------------------------------------------===// 7016// 11.12. Vector Widening Integer Multiply Instructions 7017//===----------------------------------------------------------------------===// 7018defm : VPatBinaryW_VV_VX<"int_riscv_vwmul", "PseudoVWMUL", AllWidenableIntVectors>; 7019defm : VPatBinaryW_VV_VX<"int_riscv_vwmulu", "PseudoVWMULU", AllWidenableIntVectors>; 7020defm : VPatBinaryW_VV_VX<"int_riscv_vwmulsu", "PseudoVWMULSU", AllWidenableIntVectors>; 7021 7022//===----------------------------------------------------------------------===// 7023// 11.13. Vector Single-Width Integer Multiply-Add Instructions 7024//===----------------------------------------------------------------------===// 7025defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vmadd", "PseudoVMADD", AllIntegerVectors>; 7026defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vnmsub", "PseudoVNMSUB", AllIntegerVectors>; 7027defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vmacc", "PseudoVMACC", AllIntegerVectors>; 7028defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vnmsac", "PseudoVNMSAC", AllIntegerVectors>; 7029 7030//===----------------------------------------------------------------------===// 7031// 11.14. Vector Widening Integer Multiply-Add Instructions 7032//===----------------------------------------------------------------------===// 7033defm : VPatTernaryW_VV_VX<"int_riscv_vwmaccu", "PseudoVWMACCU", AllWidenableIntVectors>; 7034defm : VPatTernaryW_VV_VX<"int_riscv_vwmacc", "PseudoVWMACC", AllWidenableIntVectors>; 7035defm : VPatTernaryW_VV_VX<"int_riscv_vwmaccsu", "PseudoVWMACCSU", AllWidenableIntVectors>; 7036defm : VPatTernaryW_VX<"int_riscv_vwmaccus", "PseudoVWMACCUS", AllWidenableIntVectors>; 7037 7038//===----------------------------------------------------------------------===// 7039// 11.15. Vector Integer Merge Instructions 7040//===----------------------------------------------------------------------===// 7041defm : VPatBinaryV_VM_XM_IM<"int_riscv_vmerge", "PseudoVMERGE">; 7042 7043//===----------------------------------------------------------------------===// 7044// 11.16. Vector Integer Move Instructions 7045//===----------------------------------------------------------------------===// 7046foreach vti = AllVectors in { 7047 let Predicates = GetVTypePredicates<vti>.Predicates in { 7048 def : Pat<(vti.Vector (int_riscv_vmv_v_v (vti.Vector vti.RegClass:$passthru), 7049 (vti.Vector vti.RegClass:$rs1), 7050 VLOpFrag)), 7051 (!cast<Instruction>("PseudoVMV_V_V_"#vti.LMul.MX) 7052 $passthru, $rs1, GPR:$vl, vti.Log2SEW, TU_MU)>; 7053 7054 // vmv.v.x/vmv.v.i are handled in RISCInstrVInstrInfoVVLPatterns.td 7055 } 7056} 7057 7058//===----------------------------------------------------------------------===// 7059// 12. Vector Fixed-Point Arithmetic Instructions 7060//===----------------------------------------------------------------------===// 7061 7062//===----------------------------------------------------------------------===// 7063// 12.1. Vector Single-Width Saturating Add and Subtract 7064//===----------------------------------------------------------------------===// 7065defm : VPatBinaryV_VV_VX_VI<"int_riscv_vsaddu", "PseudoVSADDU", AllIntegerVectors>; 7066defm : VPatBinaryV_VV_VX_VI<"int_riscv_vsadd", "PseudoVSADD", AllIntegerVectors>; 7067defm : VPatBinaryV_VV_VX<"int_riscv_vssubu", "PseudoVSSUBU", AllIntegerVectors>; 7068defm : VPatBinaryV_VV_VX<"int_riscv_vssub", "PseudoVSSUB", AllIntegerVectors>; 7069 7070//===----------------------------------------------------------------------===// 7071// 12.2. Vector Single-Width Averaging Add and Subtract 7072//===----------------------------------------------------------------------===// 7073defm : VPatBinaryV_VV_VX_RM<"int_riscv_vaaddu", "PseudoVAADDU", 7074 AllIntegerVectors>; 7075defm : VPatBinaryV_VV_VX_RM<"int_riscv_vasubu", "PseudoVASUBU", 7076 AllIntegerVectors>; 7077defm : VPatBinaryV_VV_VX_RM<"int_riscv_vasub", "PseudoVASUB", 7078 AllIntegerVectors>; 7079defm : VPatBinaryV_VV_VX_RM<"int_riscv_vaadd", "PseudoVAADD", 7080 AllIntegerVectors>; 7081 7082//===----------------------------------------------------------------------===// 7083// 12.3. Vector Single-Width Fractional Multiply with Rounding and Saturation 7084//===----------------------------------------------------------------------===// 7085defm : VPatBinaryV_VV_VX_RM<"int_riscv_vsmul", "PseudoVSMUL", 7086 IntegerVectorsExceptI64>; 7087// vsmul.vv and vsmul.vx are not included in EEW=64 in Zve64*. 7088let Predicates = [HasVInstructionsFullMultiply] in 7089defm : VPatBinaryV_VV_VX_RM<"int_riscv_vsmul", "PseudoVSMUL", 7090 I64IntegerVectors>; 7091 7092//===----------------------------------------------------------------------===// 7093// 12.4. Vector Single-Width Scaling Shift Instructions 7094//===----------------------------------------------------------------------===// 7095defm : VPatBinaryV_VV_VX_VI_RM<"int_riscv_vssrl", "PseudoVSSRL", 7096 AllIntegerVectors, uimm5>; 7097defm : VPatBinaryV_VV_VX_VI_RM<"int_riscv_vssra", "PseudoVSSRA", 7098 AllIntegerVectors, uimm5>; 7099 7100//===----------------------------------------------------------------------===// 7101// 12.5. Vector Narrowing Fixed-Point Clip Instructions 7102//===----------------------------------------------------------------------===// 7103defm : VPatBinaryV_WV_WX_WI_RM<"int_riscv_vnclipu", "PseudoVNCLIPU", 7104 AllWidenableIntVectors>; 7105defm : VPatBinaryV_WV_WX_WI_RM<"int_riscv_vnclip", "PseudoVNCLIP", 7106 AllWidenableIntVectors>; 7107 7108//===----------------------------------------------------------------------===// 7109// 13. Vector Floating-Point Instructions 7110//===----------------------------------------------------------------------===// 7111 7112//===----------------------------------------------------------------------===// 7113// 13.2. Vector Single-Width Floating-Point Add/Subtract Instructions 7114//===----------------------------------------------------------------------===// 7115defm : VPatBinaryV_VV_VX_RM<"int_riscv_vfadd", "PseudoVFADD", 7116 AllFloatVectors>; 7117defm : VPatBinaryV_VV_VX_RM<"int_riscv_vfsub", "PseudoVFSUB", 7118 AllFloatVectors>; 7119defm : VPatBinaryV_VX_RM<"int_riscv_vfrsub", "PseudoVFRSUB", AllFloatVectors>; 7120 7121//===----------------------------------------------------------------------===// 7122// 13.3. Vector Widening Floating-Point Add/Subtract Instructions 7123//===----------------------------------------------------------------------===// 7124defm : VPatBinaryW_VV_VX_RM<"int_riscv_vfwadd", "PseudoVFWADD", 7125 AllWidenableFloatVectors>; 7126defm : VPatBinaryW_VV_VX_RM<"int_riscv_vfwsub", "PseudoVFWSUB", 7127 AllWidenableFloatVectors>; 7128defm : VPatBinaryW_WV_WX_RM<"int_riscv_vfwadd_w", "PseudoVFWADD", 7129 AllWidenableFloatVectors>; 7130defm : VPatBinaryW_WV_WX_RM<"int_riscv_vfwsub_w", "PseudoVFWSUB", 7131 AllWidenableFloatVectors>; 7132 7133//===----------------------------------------------------------------------===// 7134// 13.4. Vector Single-Width Floating-Point Multiply/Divide Instructions 7135//===----------------------------------------------------------------------===// 7136defm : VPatBinaryV_VV_VX_RM<"int_riscv_vfmul", "PseudoVFMUL", 7137 AllFloatVectors>; 7138defm : VPatBinaryV_VV_VX_RM<"int_riscv_vfdiv", "PseudoVFDIV", 7139 AllFloatVectors, isSEWAware=1>; 7140defm : VPatBinaryV_VX_RM<"int_riscv_vfrdiv", "PseudoVFRDIV", 7141 AllFloatVectors, isSEWAware=1>; 7142 7143//===----------------------------------------------------------------------===// 7144// 13.5. Vector Widening Floating-Point Multiply 7145//===----------------------------------------------------------------------===// 7146defm : VPatBinaryW_VV_VX_RM<"int_riscv_vfwmul", "PseudoVFWMUL", 7147 AllWidenableFloatVectors>; 7148 7149//===----------------------------------------------------------------------===// 7150// 13.6. Vector Single-Width Floating-Point Fused Multiply-Add Instructions 7151//===----------------------------------------------------------------------===// 7152defm : VPatTernaryV_VV_VX_AAXA_RM<"int_riscv_vfmacc", "PseudoVFMACC", AllFloatVectors>; 7153defm : VPatTernaryV_VV_VX_AAXA_RM<"int_riscv_vfnmacc", "PseudoVFNMACC", AllFloatVectors>; 7154defm : VPatTernaryV_VV_VX_AAXA_RM<"int_riscv_vfmsac", "PseudoVFMSAC", AllFloatVectors>; 7155defm : VPatTernaryV_VV_VX_AAXA_RM<"int_riscv_vfnmsac", "PseudoVFNMSAC", AllFloatVectors>; 7156defm : VPatTernaryV_VV_VX_AAXA_RM<"int_riscv_vfmadd", "PseudoVFMADD", AllFloatVectors>; 7157defm : VPatTernaryV_VV_VX_AAXA_RM<"int_riscv_vfnmadd", "PseudoVFNMADD", AllFloatVectors>; 7158defm : VPatTernaryV_VV_VX_AAXA_RM<"int_riscv_vfmsub", "PseudoVFMSUB", AllFloatVectors>; 7159defm : VPatTernaryV_VV_VX_AAXA_RM<"int_riscv_vfnmsub", "PseudoVFNMSUB", AllFloatVectors>; 7160 7161//===----------------------------------------------------------------------===// 7162// 13.7. Vector Widening Floating-Point Fused Multiply-Add Instructions 7163//===----------------------------------------------------------------------===// 7164defm : VPatTernaryW_VV_VX_RM<"int_riscv_vfwmacc", "PseudoVFWMACC", 7165 AllWidenableFloatVectors>; 7166defm : VPatTernaryW_VV_VX_RM<"int_riscv_vfwnmacc", "PseudoVFWNMACC", 7167 AllWidenableFloatVectors>; 7168defm : VPatTernaryW_VV_VX_RM<"int_riscv_vfwmsac", "PseudoVFWMSAC", 7169 AllWidenableFloatVectors>; 7170defm : VPatTernaryW_VV_VX_RM<"int_riscv_vfwnmsac", "PseudoVFWNMSAC", 7171 AllWidenableFloatVectors>; 7172let Predicates = [HasStdExtZvfbfwma] in 7173defm : VPatTernaryW_VV_VX_RM<"int_riscv_vfwmaccbf16", "PseudoVFWMACCBF16", 7174 AllWidenableBFloatToFloatVectors>; 7175 7176//===----------------------------------------------------------------------===// 7177// 13.8. Vector Floating-Point Square-Root Instruction 7178//===----------------------------------------------------------------------===// 7179defm : VPatUnaryV_V_RM<"int_riscv_vfsqrt", "PseudoVFSQRT", AllFloatVectors, isSEWAware=1>; 7180 7181//===----------------------------------------------------------------------===// 7182// 13.9. Vector Floating-Point Reciprocal Square-Root Estimate Instruction 7183//===----------------------------------------------------------------------===// 7184defm : VPatUnaryV_V<"int_riscv_vfrsqrt7", "PseudoVFRSQRT7", AllFloatVectors>; 7185 7186//===----------------------------------------------------------------------===// 7187// 13.10. Vector Floating-Point Reciprocal Estimate Instruction 7188//===----------------------------------------------------------------------===// 7189defm : VPatUnaryV_V_RM<"int_riscv_vfrec7", "PseudoVFREC7", AllFloatVectors>; 7190 7191//===----------------------------------------------------------------------===// 7192// 13.11. Vector Floating-Point Min/Max Instructions 7193//===----------------------------------------------------------------------===// 7194defm : VPatBinaryV_VV_VX<"int_riscv_vfmin", "PseudoVFMIN", AllFloatVectors>; 7195defm : VPatBinaryV_VV_VX<"int_riscv_vfmax", "PseudoVFMAX", AllFloatVectors>; 7196 7197//===----------------------------------------------------------------------===// 7198// 13.12. Vector Floating-Point Sign-Injection Instructions 7199//===----------------------------------------------------------------------===// 7200defm : VPatBinaryV_VV_VX<"int_riscv_vfsgnj", "PseudoVFSGNJ", AllFloatVectors>; 7201defm : VPatBinaryV_VV_VX<"int_riscv_vfsgnjn", "PseudoVFSGNJN", AllFloatVectors>; 7202defm : VPatBinaryV_VV_VX<"int_riscv_vfsgnjx", "PseudoVFSGNJX", AllFloatVectors>; 7203 7204//===----------------------------------------------------------------------===// 7205// 13.13. Vector Floating-Point Compare Instructions 7206//===----------------------------------------------------------------------===// 7207defm : VPatBinaryM_VV_VX<"int_riscv_vmfeq", "PseudoVMFEQ", AllFloatVectors>; 7208defm : VPatBinaryM_VV_VX<"int_riscv_vmfle", "PseudoVMFLE", AllFloatVectors>; 7209defm : VPatBinaryM_VV_VX<"int_riscv_vmflt", "PseudoVMFLT", AllFloatVectors>; 7210defm : VPatBinaryM_VV_VX<"int_riscv_vmfne", "PseudoVMFNE", AllFloatVectors>; 7211defm : VPatBinaryM_VX<"int_riscv_vmfgt", "PseudoVMFGT", AllFloatVectors>; 7212defm : VPatBinaryM_VX<"int_riscv_vmfge", "PseudoVMFGE", AllFloatVectors>; 7213defm : VPatBinarySwappedM_VV<"int_riscv_vmfgt", "PseudoVMFLT", AllFloatVectors>; 7214defm : VPatBinarySwappedM_VV<"int_riscv_vmfge", "PseudoVMFLE", AllFloatVectors>; 7215 7216//===----------------------------------------------------------------------===// 7217// 13.14. Vector Floating-Point Classify Instruction 7218//===----------------------------------------------------------------------===// 7219defm : VPatConversionVI_VF<"int_riscv_vfclass", "PseudoVFCLASS">; 7220 7221//===----------------------------------------------------------------------===// 7222// 13.15. Vector Floating-Point Merge Instruction 7223//===----------------------------------------------------------------------===// 7224// We can use vmerge.vvm to support vector-vector vfmerge. 7225// NOTE: Clang previously used int_riscv_vfmerge for vector-vector, but now uses 7226// int_riscv_vmerge. Support both for compatibility. 7227foreach vti = AllFloatVectors in { 7228 let Predicates = GetVTypePredicates<vti>.Predicates in { 7229 defm : VPatBinaryCarryInTAIL<"int_riscv_vmerge", "PseudoVMERGE", "VVM", 7230 vti.Vector, 7231 vti.Vector, vti.Vector, vti.Mask, 7232 vti.Log2SEW, vti.LMul, vti.RegClass, 7233 vti.RegClass, vti.RegClass>; 7234 defm : VPatBinaryCarryInTAIL<"int_riscv_vfmerge", "PseudoVMERGE", "VVM", 7235 vti.Vector, 7236 vti.Vector, vti.Vector, vti.Mask, 7237 vti.Log2SEW, vti.LMul, vti.RegClass, 7238 vti.RegClass, vti.RegClass>; 7239 defm : VPatBinaryCarryInTAIL<"int_riscv_vfmerge", "PseudoVFMERGE", 7240 "V"#vti.ScalarSuffix#"M", 7241 vti.Vector, 7242 vti.Vector, vti.Scalar, vti.Mask, 7243 vti.Log2SEW, vti.LMul, vti.RegClass, 7244 vti.RegClass, vti.ScalarRegClass>; 7245 } 7246} 7247 7248foreach fvti = AllFloatVectors in { 7249 defvar instr = !cast<Instruction>("PseudoVMERGE_VIM_"#fvti.LMul.MX); 7250 let Predicates = GetVTypePredicates<fvti>.Predicates in 7251 def : Pat<(fvti.Vector (int_riscv_vfmerge (fvti.Vector fvti.RegClass:$merge), 7252 (fvti.Vector fvti.RegClass:$rs2), 7253 (fvti.Scalar (fpimm0)), 7254 (fvti.Mask V0), VLOpFrag)), 7255 (instr fvti.RegClass:$merge, fvti.RegClass:$rs2, 0, 7256 (fvti.Mask V0), GPR:$vl, fvti.Log2SEW)>; 7257} 7258 7259//===----------------------------------------------------------------------===// 7260// 13.17. Single-Width Floating-Point/Integer Type-Convert Instructions 7261//===----------------------------------------------------------------------===// 7262defm : VPatConversionVI_VF_RM<"int_riscv_vfcvt_x_f_v", "PseudoVFCVT_X_F">; 7263defm : VPatConversionVI_VF_RM<"int_riscv_vfcvt_xu_f_v", "PseudoVFCVT_XU_F">; 7264defm : VPatConversionVI_VF<"int_riscv_vfcvt_rtz_xu_f_v", "PseudoVFCVT_RTZ_XU_F">; 7265defm : VPatConversionVI_VF<"int_riscv_vfcvt_rtz_x_f_v", "PseudoVFCVT_RTZ_X_F">; 7266defm : VPatConversionVF_VI_RM<"int_riscv_vfcvt_f_x_v", "PseudoVFCVT_F_X">; 7267defm : VPatConversionVF_VI_RM<"int_riscv_vfcvt_f_xu_v", "PseudoVFCVT_F_XU">; 7268 7269//===----------------------------------------------------------------------===// 7270// 13.18. Widening Floating-Point/Integer Type-Convert Instructions 7271//===----------------------------------------------------------------------===// 7272defm : VPatConversionWI_VF_RM<"int_riscv_vfwcvt_xu_f_v", "PseudoVFWCVT_XU_F">; 7273defm : VPatConversionWI_VF_RM<"int_riscv_vfwcvt_x_f_v", "PseudoVFWCVT_X_F">; 7274defm : VPatConversionWI_VF<"int_riscv_vfwcvt_rtz_xu_f_v", "PseudoVFWCVT_RTZ_XU_F">; 7275defm : VPatConversionWI_VF<"int_riscv_vfwcvt_rtz_x_f_v", "PseudoVFWCVT_RTZ_X_F">; 7276defm : VPatConversionWF_VI<"int_riscv_vfwcvt_f_xu_v", "PseudoVFWCVT_F_XU">; 7277defm : VPatConversionWF_VI<"int_riscv_vfwcvt_f_x_v", "PseudoVFWCVT_F_X">; 7278defm : VPatConversionWF_VF<"int_riscv_vfwcvt_f_f_v", "PseudoVFWCVT_F_F">; 7279defm : VPatConversionWF_VF_BF<"int_riscv_vfwcvtbf16_f_f_v", 7280 "PseudoVFWCVTBF16_F_F">; 7281 7282//===----------------------------------------------------------------------===// 7283// 13.19. Narrowing Floating-Point/Integer Type-Convert Instructions 7284//===----------------------------------------------------------------------===// 7285defm : VPatConversionVI_WF_RM<"int_riscv_vfncvt_xu_f_w", "PseudoVFNCVT_XU_F">; 7286defm : VPatConversionVI_WF_RM<"int_riscv_vfncvt_x_f_w", "PseudoVFNCVT_X_F">; 7287defm : VPatConversionVI_WF<"int_riscv_vfncvt_rtz_xu_f_w", "PseudoVFNCVT_RTZ_XU_F">; 7288defm : VPatConversionVI_WF<"int_riscv_vfncvt_rtz_x_f_w", "PseudoVFNCVT_RTZ_X_F">; 7289defm : VPatConversionVF_WI_RM <"int_riscv_vfncvt_f_xu_w", "PseudoVFNCVT_F_XU">; 7290defm : VPatConversionVF_WI_RM <"int_riscv_vfncvt_f_x_w", "PseudoVFNCVT_F_X">; 7291defvar WidenableFloatVectorsExceptF16 = !filter(fvtiToFWti, AllWidenableFloatVectors, 7292 !ne(fvtiToFWti.Vti.Scalar, f16)); 7293defm : VPatConversionVF_WF_RM<"int_riscv_vfncvt_f_f_w", "PseudoVFNCVT_F_F", 7294 WidenableFloatVectorsExceptF16>; 7295// Define vfncvt.f.f.w for f16 when Zvfhmin is enable. 7296defvar F16WidenableFloatVectors = !filter(fvtiToFWti, AllWidenableFloatVectors, 7297 !eq(fvtiToFWti.Vti.Scalar, f16)); 7298let Predicates = [HasVInstructionsF16Minimal] in 7299defm : VPatConversionVF_WF_RM<"int_riscv_vfncvt_f_f_w", "PseudoVFNCVT_F_F", 7300 F16WidenableFloatVectors>; 7301defm : VPatConversionVF_WF_BF_RM<"int_riscv_vfncvtbf16_f_f_w", 7302 "PseudoVFNCVTBF16_F_F">; 7303defm : VPatConversionVF_WF<"int_riscv_vfncvt_rod_f_f_w", "PseudoVFNCVT_ROD_F_F">; 7304 7305//===----------------------------------------------------------------------===// 7306// 14. Vector Reduction Operations 7307//===----------------------------------------------------------------------===// 7308 7309//===----------------------------------------------------------------------===// 7310// 14.1. Vector Single-Width Integer Reduction Instructions 7311//===----------------------------------------------------------------------===// 7312defm : VPatReductionV_VS<"int_riscv_vredsum", "PseudoVREDSUM">; 7313defm : VPatReductionV_VS<"int_riscv_vredand", "PseudoVREDAND">; 7314defm : VPatReductionV_VS<"int_riscv_vredor", "PseudoVREDOR">; 7315defm : VPatReductionV_VS<"int_riscv_vredxor", "PseudoVREDXOR">; 7316defm : VPatReductionV_VS<"int_riscv_vredminu", "PseudoVREDMINU">; 7317defm : VPatReductionV_VS<"int_riscv_vredmin", "PseudoVREDMIN">; 7318defm : VPatReductionV_VS<"int_riscv_vredmaxu", "PseudoVREDMAXU">; 7319defm : VPatReductionV_VS<"int_riscv_vredmax", "PseudoVREDMAX">; 7320 7321//===----------------------------------------------------------------------===// 7322// 14.2. Vector Widening Integer Reduction Instructions 7323//===----------------------------------------------------------------------===// 7324defm : VPatReductionW_VS<"int_riscv_vwredsumu", "PseudoVWREDSUMU">; 7325defm : VPatReductionW_VS<"int_riscv_vwredsum", "PseudoVWREDSUM">; 7326 7327//===----------------------------------------------------------------------===// 7328// 14.3. Vector Single-Width Floating-Point Reduction Instructions 7329//===----------------------------------------------------------------------===// 7330defm : VPatReductionV_VS_RM<"int_riscv_vfredosum", "PseudoVFREDOSUM", IsFloat=1>; 7331defm : VPatReductionV_VS_RM<"int_riscv_vfredusum", "PseudoVFREDUSUM", IsFloat=1>; 7332defm : VPatReductionV_VS<"int_riscv_vfredmin", "PseudoVFREDMIN", IsFloat=1>; 7333defm : VPatReductionV_VS<"int_riscv_vfredmax", "PseudoVFREDMAX", IsFloat=1>; 7334 7335//===----------------------------------------------------------------------===// 7336// 14.4. Vector Widening Floating-Point Reduction Instructions 7337//===----------------------------------------------------------------------===// 7338defm : VPatReductionW_VS_RM<"int_riscv_vfwredusum", "PseudoVFWREDUSUM", IsFloat=1>; 7339defm : VPatReductionW_VS_RM<"int_riscv_vfwredosum", "PseudoVFWREDOSUM", IsFloat=1>; 7340 7341//===----------------------------------------------------------------------===// 7342// 15. Vector Mask Instructions 7343//===----------------------------------------------------------------------===// 7344 7345//===----------------------------------------------------------------------===// 7346// 15.1 Vector Mask-Register Logical Instructions 7347//===----------------------------------------------------------------------===// 7348defm : VPatBinaryM_MM<"int_riscv_vmand", "PseudoVMAND">; 7349defm : VPatBinaryM_MM<"int_riscv_vmnand", "PseudoVMNAND">; 7350defm : VPatBinaryM_MM<"int_riscv_vmandn", "PseudoVMANDN">; 7351defm : VPatBinaryM_MM<"int_riscv_vmxor", "PseudoVMXOR">; 7352defm : VPatBinaryM_MM<"int_riscv_vmor", "PseudoVMOR">; 7353defm : VPatBinaryM_MM<"int_riscv_vmnor", "PseudoVMNOR">; 7354defm : VPatBinaryM_MM<"int_riscv_vmorn", "PseudoVMORN">; 7355defm : VPatBinaryM_MM<"int_riscv_vmxnor", "PseudoVMXNOR">; 7356 7357// pseudo instructions 7358defm : VPatNullaryM<"int_riscv_vmclr", "PseudoVMCLR">; 7359defm : VPatNullaryM<"int_riscv_vmset", "PseudoVMSET">; 7360 7361//===----------------------------------------------------------------------===// 7362// 15.2. Vector count population in mask vcpop.m 7363//===----------------------------------------------------------------------===// 7364defm : VPatUnaryS_M<"int_riscv_vcpop", "PseudoVCPOP">; 7365 7366//===----------------------------------------------------------------------===// 7367// 15.3. vfirst find-first-set mask bit 7368//===----------------------------------------------------------------------===// 7369defm : VPatUnaryS_M<"int_riscv_vfirst", "PseudoVFIRST">; 7370 7371//===----------------------------------------------------------------------===// 7372// 15.4. vmsbf.m set-before-first mask bit 7373//===----------------------------------------------------------------------===// 7374defm : VPatUnaryM_M<"int_riscv_vmsbf", "PseudoVMSBF">; 7375 7376//===----------------------------------------------------------------------===// 7377// 15.5. vmsif.m set-including-first mask bit 7378//===----------------------------------------------------------------------===// 7379defm : VPatUnaryM_M<"int_riscv_vmsif", "PseudoVMSIF">; 7380 7381//===----------------------------------------------------------------------===// 7382// 15.6. vmsof.m set-only-first mask bit 7383//===----------------------------------------------------------------------===// 7384defm : VPatUnaryM_M<"int_riscv_vmsof", "PseudoVMSOF">; 7385 7386//===----------------------------------------------------------------------===// 7387// 15.8. Vector Iota Instruction 7388//===----------------------------------------------------------------------===// 7389defm : VPatUnaryV_M<"int_riscv_viota", "PseudoVIOTA">; 7390 7391//===----------------------------------------------------------------------===// 7392// 15.9. Vector Element Index Instruction 7393//===----------------------------------------------------------------------===// 7394defm : VPatNullaryV<"int_riscv_vid", "PseudoVID">; 7395 7396 7397//===----------------------------------------------------------------------===// 7398// 16. Vector Permutation Instructions 7399//===----------------------------------------------------------------------===// 7400 7401//===----------------------------------------------------------------------===// 7402// 16.1. Integer Scalar Move Instructions 7403//===----------------------------------------------------------------------===// 7404 7405foreach vti = NoGroupIntegerVectors in { 7406 let Predicates = GetVTypePredicates<vti>.Predicates in 7407 def : Pat<(XLenVT (riscv_vmv_x_s (vti.Vector vti.RegClass:$rs2))), 7408 (PseudoVMV_X_S $rs2, vti.Log2SEW)>; 7409 // vmv.s.x is handled with a custom node in RISCVInstrInfoVVLPatterns.td 7410} 7411 7412//===----------------------------------------------------------------------===// 7413// 16.3. Vector Slide Instructions 7414//===----------------------------------------------------------------------===// 7415defm : VPatTernaryV_VX_VI<"int_riscv_vslideup", "PseudoVSLIDEUP", AllIntegerVectors, uimm5>; 7416defm : VPatTernaryV_VX_VI<"int_riscv_vslidedown", "PseudoVSLIDEDOWN", AllIntegerVectors, uimm5>; 7417defm : VPatBinaryV_VX<"int_riscv_vslide1up", "PseudoVSLIDE1UP", AllIntegerVectors>; 7418defm : VPatBinaryV_VX<"int_riscv_vslide1down", "PseudoVSLIDE1DOWN", AllIntegerVectors>; 7419 7420defm : VPatTernaryV_VX_VI<"int_riscv_vslideup", "PseudoVSLIDEUP", AllFloatVectors, uimm5>; 7421defm : VPatTernaryV_VX_VI<"int_riscv_vslidedown", "PseudoVSLIDEDOWN", AllFloatVectors, uimm5>; 7422defm : VPatBinaryV_VX<"int_riscv_vfslide1up", "PseudoVFSLIDE1UP", AllFloatVectors>; 7423defm : VPatBinaryV_VX<"int_riscv_vfslide1down", "PseudoVFSLIDE1DOWN", AllFloatVectors>; 7424 7425//===----------------------------------------------------------------------===// 7426// 16.4. Vector Register Gather Instructions 7427//===----------------------------------------------------------------------===// 7428defm : VPatBinaryV_VV_VX_VI_INT<"int_riscv_vrgather", "PseudoVRGATHER", 7429 AllIntegerVectors, uimm5>; 7430defm : VPatBinaryV_VV_INT_EEW<"int_riscv_vrgatherei16_vv", "PseudoVRGATHEREI16", 7431 eew=16, vtilist=AllIntegerVectors>; 7432 7433defm : VPatBinaryV_VV_VX_VI_INT<"int_riscv_vrgather", "PseudoVRGATHER", 7434 AllFloatVectors, uimm5>; 7435defm : VPatBinaryV_VV_INT_EEW<"int_riscv_vrgatherei16_vv", "PseudoVRGATHEREI16", 7436 eew=16, vtilist=AllFloatVectors>; 7437//===----------------------------------------------------------------------===// 7438// 16.5. Vector Compress Instruction 7439//===----------------------------------------------------------------------===// 7440defm : VPatUnaryV_V_AnyMask<"int_riscv_vcompress", "PseudoVCOMPRESS", AllIntegerVectors>; 7441defm : VPatUnaryV_V_AnyMask<"int_riscv_vcompress", "PseudoVCOMPRESS", AllFloatVectors>; 7442 7443// Include the non-intrinsic ISel patterns 7444include "RISCVInstrInfoVVLPatterns.td" 7445include "RISCVInstrInfoVSDPatterns.td" 7446