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