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//===----------------------------------------------------------------------===//
15
16def riscv_vmv_x_s : SDNode<"RISCVISD::VMV_X_S",
17                           SDTypeProfile<1, 1, [SDTCisInt<0>, SDTCisVec<1>,
18                                                SDTCisInt<1>]>>;
19def riscv_read_vlenb : SDNode<"RISCVISD::READ_VLENB",
20                              SDTypeProfile<1, 0, [SDTCisVT<0, XLenVT>]>>;
21
22// Operand that is allowed to be a register or a 5 bit immediate.
23// This allows us to pick between VSETIVLI and VSETVLI opcodes using the same
24// pseudo instructions.
25def AVL : RegisterOperand<GPRNoX0> {
26  let OperandNamespace = "RISCVOp";
27  let OperandType = "OPERAND_AVL";
28}
29
30// X0 has special meaning for vsetvl/vsetvli.
31//  rd | rs1 |   AVL value | Effect on vl
32//--------------------------------------------------------------
33// !X0 |  X0 |       VLMAX | Set vl to VLMAX
34//  X0 |  X0 | Value in vl | Keep current vl, just change vtype.
35def VLOp : ComplexPattern<XLenVT, 1, "selectVLOp">;
36
37def DecImm : SDNodeXForm<imm, [{
38  return CurDAG->getTargetConstant(N->getSExtValue() - 1, SDLoc(N),
39                                   N->getValueType(0));
40}]>;
41
42defvar TAIL_UNDISTURBED_MASK_UNDISTURBED = 0;
43defvar TAIL_AGNOSTIC = 1;
44
45//===----------------------------------------------------------------------===//
46// Utilities.
47//===----------------------------------------------------------------------===//
48
49class PseudoToVInst<string PseudoInst> {
50  string VInst = !subst("_M8", "",
51                 !subst("_M4", "",
52                 !subst("_M2", "",
53                 !subst("_M1", "",
54                 !subst("_MF2", "",
55                 !subst("_MF4", "",
56                 !subst("_MF8", "",
57                 !subst("_B1", "",
58                 !subst("_B2", "",
59                 !subst("_B4", "",
60                 !subst("_B8", "",
61                 !subst("_B16", "",
62                 !subst("_B32", "",
63                 !subst("_B64", "",
64                 !subst("_MASK", "",
65                 !subst("_TIED", "",
66                 !subst("_TU", "",
67                 !subst("F16", "F",
68                 !subst("F32", "F",
69                 !subst("F64", "F",
70                 !subst("Pseudo", "", PseudoInst)))))))))))))))))))));
71}
72
73// This class describes information associated to the LMUL.
74class LMULInfo<int lmul, int oct, VReg regclass, VReg wregclass,
75               VReg f2regclass, VReg f4regclass, VReg f8regclass, string mx> {
76  bits<3> value = lmul; // This is encoded as the vlmul field of vtype.
77  VReg vrclass = regclass;
78  VReg wvrclass = wregclass;
79  VReg f8vrclass = f8regclass;
80  VReg f4vrclass = f4regclass;
81  VReg f2vrclass = f2regclass;
82  string MX = mx;
83  int octuple = oct;
84}
85
86// Associate LMUL with tablegen records of register classes.
87def V_M1  : LMULInfo<0b000,  8,   VR,        VRM2,   VR,   VR, VR, "M1">;
88def V_M2  : LMULInfo<0b001, 16, VRM2,        VRM4,   VR,   VR, VR, "M2">;
89def V_M4  : LMULInfo<0b010, 32, VRM4,        VRM8, VRM2,   VR, VR, "M4">;
90def V_M8  : LMULInfo<0b011, 64, VRM8,/*NoVReg*/VR, VRM4, VRM2, VR, "M8">;
91
92def V_MF8 : LMULInfo<0b101, 1, VR, VR,/*NoVReg*/VR,/*NoVReg*/VR,/*NoVReg*/VR, "MF8">;
93def V_MF4 : LMULInfo<0b110, 2, VR, VR,          VR,/*NoVReg*/VR,/*NoVReg*/VR, "MF4">;
94def V_MF2 : LMULInfo<0b111, 4, VR, VR,          VR,          VR,/*NoVReg*/VR, "MF2">;
95
96// Used to iterate over all possible LMULs.
97defvar MxList = [V_MF8, V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8];
98// For floating point which don't need MF8.
99defvar MxListF = [V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8];
100
101// Used for widening and narrowing instructions as it doesn't contain M8.
102defvar MxListW = [V_MF8, V_MF4, V_MF2, V_M1, V_M2, V_M4];
103// For floating point which don't need MF8.
104defvar MxListFW = [V_MF4, V_MF2, V_M1, V_M2, V_M4];
105
106// Use for zext/sext.vf2
107defvar MxListVF2 = [V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8];
108
109// Use for zext/sext.vf4
110defvar MxListVF4 = [V_MF2, V_M1, V_M2, V_M4, V_M8];
111
112// Use for zext/sext.vf8
113defvar MxListVF8 = [V_M1, V_M2, V_M4, V_M8];
114
115class MxSet<int eew> {
116  list<LMULInfo> m = !cond(!eq(eew, 8) : [V_MF8, V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8],
117                           !eq(eew, 16) : [V_MF4, V_MF2, V_M1, V_M2, V_M4, V_M8],
118                           !eq(eew, 32) : [V_MF2, V_M1, V_M2, V_M4, V_M8],
119                           !eq(eew, 64) : [V_M1, V_M2, V_M4, V_M8]);
120}
121
122class FPR_Info<RegisterClass regclass, string fx, list<LMULInfo> mxlist> {
123  RegisterClass fprclass = regclass;
124  string FX = fx;
125  list<LMULInfo> MxList = mxlist;
126}
127
128def SCALAR_F16 : FPR_Info<FPR16, "F16", MxSet<16>.m>;
129def SCALAR_F32 : FPR_Info<FPR32, "F32", MxSet<32>.m>;
130def SCALAR_F64 : FPR_Info<FPR64, "F64", MxSet<64>.m>;
131
132defvar FPList = [SCALAR_F16, SCALAR_F32, SCALAR_F64];
133
134// Used for widening instructions. It excludes F64.
135defvar FPListW = [SCALAR_F16, SCALAR_F32];
136
137class NFSet<LMULInfo m> {
138  list<int> L = !cond(!eq(m.value, V_M8.value): [],
139                      !eq(m.value, V_M4.value): [2],
140                      !eq(m.value, V_M2.value): [2, 3, 4],
141                      true: [2, 3, 4, 5, 6, 7, 8]);
142}
143
144class log2<int num> {
145  int val = !if(!eq(num, 1), 0, !add(1, log2<!srl(num, 1)>.val));
146}
147
148class octuple_to_str<int octuple> {
149  string ret = !if(!eq(octuple, 1), "MF8",
150                   !if(!eq(octuple, 2), "MF4",
151                   !if(!eq(octuple, 4), "MF2",
152                   !if(!eq(octuple, 8), "M1",
153                   !if(!eq(octuple, 16), "M2",
154                   !if(!eq(octuple, 32), "M4",
155                   !if(!eq(octuple, 64), "M8",
156                   "NoDef")))))));
157}
158
159def VLOpFrag : PatFrag<(ops), (XLenVT (VLOp (XLenVT AVL:$vl)))>;
160
161// Output pattern for X0 used to represent VLMAX in the pseudo instructions.
162// We can't use X0 register becuase the AVL operands use GPRNoX0.
163// This must be kept in sync with RISCV::VLMaxSentinel.
164def VLMax : OutPatFrag<(ops), (XLenVT -1)>;
165
166// List of EEW.
167defvar EEWList = [8, 16, 32, 64];
168
169class SegRegClass<LMULInfo m, int nf> {
170  VReg RC = !cast<VReg>("VRN" # nf # !cond(!eq(m.value, V_MF8.value): V_M1.MX,
171                                           !eq(m.value, V_MF4.value): V_M1.MX,
172                                           !eq(m.value, V_MF2.value): V_M1.MX,
173                                           true: m.MX));
174}
175
176//===----------------------------------------------------------------------===//
177// Vector register and vector group type information.
178//===----------------------------------------------------------------------===//
179
180class VTypeInfo<ValueType Vec, ValueType Mas, int Sew, VReg Reg, LMULInfo M,
181                ValueType Scal = XLenVT, RegisterClass ScalarReg = GPR>
182{
183  ValueType Vector = Vec;
184  ValueType Mask = Mas;
185  int SEW = Sew;
186  int Log2SEW = log2<Sew>.val;
187  VReg RegClass = Reg;
188  LMULInfo LMul = M;
189  ValueType Scalar = Scal;
190  RegisterClass ScalarRegClass = ScalarReg;
191  // The pattern fragment which produces the AVL operand, representing the
192  // "natural" vector length for this type. For scalable vectors this is VLMax.
193  OutPatFrag AVL = VLMax;
194
195  string ScalarSuffix = !cond(!eq(Scal, XLenVT) : "X",
196                              !eq(Scal, f16) : "F16",
197                              !eq(Scal, f32) : "F32",
198                              !eq(Scal, f64) : "F64");
199}
200
201class GroupVTypeInfo<ValueType Vec, ValueType VecM1, ValueType Mas, int Sew,
202                     VReg Reg, LMULInfo M, ValueType Scal = XLenVT,
203                     RegisterClass ScalarReg = GPR>
204    : VTypeInfo<Vec, Mas, Sew, Reg, M, Scal, ScalarReg>
205{
206  ValueType VectorM1 = VecM1;
207}
208
209defset list<VTypeInfo> AllVectors = {
210  defset list<VTypeInfo> AllIntegerVectors = {
211    defset list<VTypeInfo> NoGroupIntegerVectors = {
212      defset list<VTypeInfo> FractionalGroupIntegerVectors = {
213        def VI8MF8: VTypeInfo<vint8mf8_t,  vbool64_t,  8, VR, V_MF8>;
214        def VI8MF4: VTypeInfo<vint8mf4_t,  vbool32_t,  8, VR, V_MF4>;
215        def VI8MF2: VTypeInfo<vint8mf2_t,  vbool16_t,  8, VR, V_MF2>;
216        def VI16MF4: VTypeInfo<vint16mf4_t, vbool64_t, 16, VR, V_MF4>;
217        def VI16MF2: VTypeInfo<vint16mf2_t, vbool32_t, 16, VR, V_MF2>;
218        def VI32MF2: VTypeInfo<vint32mf2_t, vbool64_t, 32, VR, V_MF2>;
219      }
220      def VI8M1: VTypeInfo<vint8m1_t,   vbool8_t,   8, VR, V_M1>;
221      def VI16M1: VTypeInfo<vint16m1_t,  vbool16_t, 16, VR, V_M1>;
222      def VI32M1: VTypeInfo<vint32m1_t,  vbool32_t, 32, VR, V_M1>;
223      def VI64M1: VTypeInfo<vint64m1_t,  vbool64_t, 64, VR, V_M1>;
224    }
225    defset list<GroupVTypeInfo> GroupIntegerVectors = {
226      def VI8M2: GroupVTypeInfo<vint8m2_t, vint8m1_t, vbool4_t, 8, VRM2, V_M2>;
227      def VI8M4: GroupVTypeInfo<vint8m4_t, vint8m1_t, vbool2_t, 8, VRM4, V_M4>;
228      def VI8M8: GroupVTypeInfo<vint8m8_t, vint8m1_t, vbool1_t, 8, VRM8, V_M8>;
229
230      def VI16M2: GroupVTypeInfo<vint16m2_t,vint16m1_t,vbool8_t, 16,VRM2, V_M2>;
231      def VI16M4: GroupVTypeInfo<vint16m4_t,vint16m1_t,vbool4_t, 16,VRM4, V_M4>;
232      def VI16M8: GroupVTypeInfo<vint16m8_t,vint16m1_t,vbool2_t, 16,VRM8, V_M8>;
233
234      def VI32M2: GroupVTypeInfo<vint32m2_t,vint32m1_t,vbool16_t,32,VRM2, V_M2>;
235      def VI32M4: GroupVTypeInfo<vint32m4_t,vint32m1_t,vbool8_t, 32,VRM4, V_M4>;
236      def VI32M8: GroupVTypeInfo<vint32m8_t,vint32m1_t,vbool4_t, 32,VRM8, V_M8>;
237
238      def VI64M2: GroupVTypeInfo<vint64m2_t,vint64m1_t,vbool32_t,64,VRM2, V_M2>;
239      def VI64M4: GroupVTypeInfo<vint64m4_t,vint64m1_t,vbool16_t,64,VRM4, V_M4>;
240      def VI64M8: GroupVTypeInfo<vint64m8_t,vint64m1_t,vbool8_t, 64,VRM8, V_M8>;
241    }
242  }
243
244  defset list<VTypeInfo> AllFloatVectors = {
245    defset list<VTypeInfo> NoGroupFloatVectors = {
246      defset list<VTypeInfo> FractionalGroupFloatVectors = {
247        def VF16MF4: VTypeInfo<vfloat16mf4_t, vbool64_t, 16, VR, V_MF4, f16, FPR16>;
248        def VF16MF2: VTypeInfo<vfloat16mf2_t, vbool32_t, 16, VR, V_MF2, f16, FPR16>;
249        def VF32MF2: VTypeInfo<vfloat32mf2_t,vbool64_t, 32, VR, V_MF2, f32, FPR32>;
250      }
251      def VF16M1:  VTypeInfo<vfloat16m1_t,  vbool16_t, 16, VR, V_M1,  f16, FPR16>;
252      def VF32M1:  VTypeInfo<vfloat32m1_t, vbool32_t, 32, VR, V_M1,  f32, FPR32>;
253      def VF64M1: VTypeInfo<vfloat64m1_t, vbool64_t, 64, VR, V_M1, f64, FPR64>;
254    }
255
256    defset list<GroupVTypeInfo> GroupFloatVectors = {
257      def VF16M2: GroupVTypeInfo<vfloat16m2_t, vfloat16m1_t, vbool8_t, 16,
258                                 VRM2, V_M2, f16, FPR16>;
259      def VF16M4: GroupVTypeInfo<vfloat16m4_t, vfloat16m1_t, vbool4_t, 16,
260                                 VRM4, V_M4, f16, FPR16>;
261      def VF16M8: GroupVTypeInfo<vfloat16m8_t, vfloat16m1_t, vbool2_t, 16,
262                                 VRM8, V_M8, f16, FPR16>;
263
264      def VF32M2: GroupVTypeInfo<vfloat32m2_t, vfloat32m1_t, vbool16_t, 32,
265                                 VRM2, V_M2, f32, FPR32>;
266      def VF32M4: GroupVTypeInfo<vfloat32m4_t, vfloat32m1_t, vbool8_t,  32,
267                                 VRM4, V_M4, f32, FPR32>;
268      def VF32M8: GroupVTypeInfo<vfloat32m8_t, vfloat32m1_t, vbool4_t,  32,
269                                 VRM8, V_M8, f32, FPR32>;
270
271      def VF64M2: GroupVTypeInfo<vfloat64m2_t, vfloat64m1_t, vbool32_t, 64,
272                                 VRM2, V_M2, f64, FPR64>;
273      def VF64M4: GroupVTypeInfo<vfloat64m4_t, vfloat64m1_t, vbool16_t, 64,
274                                 VRM4, V_M4, f64, FPR64>;
275      def VF64M8: GroupVTypeInfo<vfloat64m8_t, vfloat64m1_t, vbool8_t,  64,
276                                 VRM8, V_M8, f64, FPR64>;
277    }
278  }
279}
280
281// This functor is used to obtain the int vector type that has the same SEW and
282// multiplier as the input parameter type
283class GetIntVTypeInfo<VTypeInfo vti>
284{
285  // Equivalent integer vector type. Eg.
286  //   VI8M1 → VI8M1 (identity)
287  //   VF64M4 → VI64M4
288  VTypeInfo Vti = !cast<VTypeInfo>(!subst("VF", "VI", !cast<string>(vti)));
289}
290
291class MTypeInfo<ValueType Mas, LMULInfo M, string Bx> {
292  ValueType Mask = Mas;
293  // {SEW, VLMul} values set a valid VType to deal with this mask type.
294  // we assume SEW=1 and set corresponding LMUL. vsetvli insertion will
295  // look for SEW=1 to optimize based on surrounding instructions.
296  int SEW = 1;
297  int Log2SEW = 0;
298  LMULInfo LMul = M;
299  string BX = Bx; // Appendix of mask operations.
300  // The pattern fragment which produces the AVL operand, representing the
301  // "natural" vector length for this mask type. For scalable masks this is
302  // VLMax.
303  OutPatFrag AVL = VLMax;
304}
305
306defset list<MTypeInfo> AllMasks = {
307  // vbool<n>_t, <n> = SEW/LMUL, we assume SEW=8 and corresponding LMUL.
308  def : MTypeInfo<vbool64_t, V_MF8, "B1">;
309  def : MTypeInfo<vbool32_t, V_MF4, "B2">;
310  def : MTypeInfo<vbool16_t, V_MF2, "B4">;
311  def : MTypeInfo<vbool8_t, V_M1, "B8">;
312  def : MTypeInfo<vbool4_t, V_M2, "B16">;
313  def : MTypeInfo<vbool2_t, V_M4, "B32">;
314  def : MTypeInfo<vbool1_t, V_M8, "B64">;
315}
316
317class VTypeInfoToWide<VTypeInfo vti, VTypeInfo wti>
318{
319  VTypeInfo Vti = vti;
320  VTypeInfo Wti = wti;
321}
322
323class VTypeInfoToFraction<VTypeInfo vti, VTypeInfo fti>
324{
325  VTypeInfo Vti = vti;
326  VTypeInfo Fti = fti;
327}
328
329defset list<VTypeInfoToWide> AllWidenableIntVectors = {
330  def : VTypeInfoToWide<VI8MF8,  VI16MF4>;
331  def : VTypeInfoToWide<VI8MF4,  VI16MF2>;
332  def : VTypeInfoToWide<VI8MF2,  VI16M1>;
333  def : VTypeInfoToWide<VI8M1,   VI16M2>;
334  def : VTypeInfoToWide<VI8M2,   VI16M4>;
335  def : VTypeInfoToWide<VI8M4,   VI16M8>;
336
337  def : VTypeInfoToWide<VI16MF4, VI32MF2>;
338  def : VTypeInfoToWide<VI16MF2, VI32M1>;
339  def : VTypeInfoToWide<VI16M1,  VI32M2>;
340  def : VTypeInfoToWide<VI16M2,  VI32M4>;
341  def : VTypeInfoToWide<VI16M4,  VI32M8>;
342
343  def : VTypeInfoToWide<VI32MF2, VI64M1>;
344  def : VTypeInfoToWide<VI32M1,  VI64M2>;
345  def : VTypeInfoToWide<VI32M2,  VI64M4>;
346  def : VTypeInfoToWide<VI32M4,  VI64M8>;
347}
348
349defset list<VTypeInfoToWide> AllWidenableFloatVectors = {
350  def : VTypeInfoToWide<VF16MF4, VF32MF2>;
351  def : VTypeInfoToWide<VF16MF2, VF32M1>;
352  def : VTypeInfoToWide<VF16M1, VF32M2>;
353  def : VTypeInfoToWide<VF16M2, VF32M4>;
354  def : VTypeInfoToWide<VF16M4, VF32M8>;
355
356  def : VTypeInfoToWide<VF32MF2, VF64M1>;
357  def : VTypeInfoToWide<VF32M1, VF64M2>;
358  def : VTypeInfoToWide<VF32M2, VF64M4>;
359  def : VTypeInfoToWide<VF32M4, VF64M8>;
360}
361
362defset list<VTypeInfoToFraction> AllFractionableVF2IntVectors = {
363  def : VTypeInfoToFraction<VI16MF4, VI8MF8>;
364  def : VTypeInfoToFraction<VI16MF2, VI8MF4>;
365  def : VTypeInfoToFraction<VI16M1, VI8MF2>;
366  def : VTypeInfoToFraction<VI16M2, VI8M1>;
367  def : VTypeInfoToFraction<VI16M4, VI8M2>;
368  def : VTypeInfoToFraction<VI16M8, VI8M4>;
369  def : VTypeInfoToFraction<VI32MF2, VI16MF4>;
370  def : VTypeInfoToFraction<VI32M1, VI16MF2>;
371  def : VTypeInfoToFraction<VI32M2, VI16M1>;
372  def : VTypeInfoToFraction<VI32M4, VI16M2>;
373  def : VTypeInfoToFraction<VI32M8, VI16M4>;
374  def : VTypeInfoToFraction<VI64M1, VI32MF2>;
375  def : VTypeInfoToFraction<VI64M2, VI32M1>;
376  def : VTypeInfoToFraction<VI64M4, VI32M2>;
377  def : VTypeInfoToFraction<VI64M8, VI32M4>;
378}
379
380defset list<VTypeInfoToFraction> AllFractionableVF4IntVectors = {
381  def : VTypeInfoToFraction<VI32MF2, VI8MF8>;
382  def : VTypeInfoToFraction<VI32M1, VI8MF4>;
383  def : VTypeInfoToFraction<VI32M2, VI8MF2>;
384  def : VTypeInfoToFraction<VI32M4, VI8M1>;
385  def : VTypeInfoToFraction<VI32M8, VI8M2>;
386  def : VTypeInfoToFraction<VI64M1, VI16MF4>;
387  def : VTypeInfoToFraction<VI64M2, VI16MF2>;
388  def : VTypeInfoToFraction<VI64M4, VI16M1>;
389  def : VTypeInfoToFraction<VI64M8, VI16M2>;
390}
391
392defset list<VTypeInfoToFraction> AllFractionableVF8IntVectors = {
393  def : VTypeInfoToFraction<VI64M1, VI8MF8>;
394  def : VTypeInfoToFraction<VI64M2, VI8MF4>;
395  def : VTypeInfoToFraction<VI64M4, VI8MF2>;
396  def : VTypeInfoToFraction<VI64M8, VI8M1>;
397}
398
399defset list<VTypeInfoToWide> AllWidenableIntToFloatVectors = {
400  def : VTypeInfoToWide<VI8MF8, VF16MF4>;
401  def : VTypeInfoToWide<VI8MF4, VF16MF2>;
402  def : VTypeInfoToWide<VI8MF2, VF16M1>;
403  def : VTypeInfoToWide<VI8M1, VF16M2>;
404  def : VTypeInfoToWide<VI8M2, VF16M4>;
405  def : VTypeInfoToWide<VI8M4, VF16M8>;
406
407  def : VTypeInfoToWide<VI16MF4, VF32MF2>;
408  def : VTypeInfoToWide<VI16MF2, VF32M1>;
409  def : VTypeInfoToWide<VI16M1, VF32M2>;
410  def : VTypeInfoToWide<VI16M2, VF32M4>;
411  def : VTypeInfoToWide<VI16M4, VF32M8>;
412
413  def : VTypeInfoToWide<VI32MF2, VF64M1>;
414  def : VTypeInfoToWide<VI32M1, VF64M2>;
415  def : VTypeInfoToWide<VI32M2, VF64M4>;
416  def : VTypeInfoToWide<VI32M4, VF64M8>;
417}
418
419// This class holds the record of the RISCVVPseudoTable below.
420// This represents the information we need in codegen for each pseudo.
421// The definition should be consistent with `struct PseudoInfo` in
422// RISCVBaseInfo.h.
423class CONST8b<bits<8> val> {
424  bits<8> V = val;
425}
426def InvalidIndex : CONST8b<0x80>;
427class RISCVVPseudo {
428  Pseudo Pseudo = !cast<Pseudo>(NAME); // Used as a key.
429  Instruction BaseInstr = !cast<Instruction>(PseudoToVInst<NAME>.VInst);
430}
431
432// The actual table.
433def RISCVVPseudosTable : GenericTable {
434  let FilterClass = "RISCVVPseudo";
435  let CppTypeName = "PseudoInfo";
436  let Fields = [ "Pseudo", "BaseInstr" ];
437  let PrimaryKey = [ "Pseudo" ];
438  let PrimaryKeyName = "getPseudoInfo";
439  let PrimaryKeyEarlyOut = true;
440}
441
442def RISCVVIntrinsicsTable : GenericTable {
443  let FilterClass = "RISCVVIntrinsic";
444  let CppTypeName = "RISCVVIntrinsicInfo";
445  let Fields = ["IntrinsicID", "ScalarOperand", "VLOperand"];
446  let PrimaryKey = ["IntrinsicID"];
447  let PrimaryKeyName = "getRISCVVIntrinsicInfo";
448}
449
450class RISCVMaskedPseudo<bits<4> MaskIdx, bit HasTU = true> {
451  Pseudo MaskedPseudo = !cast<Pseudo>(NAME);
452  Pseudo UnmaskedPseudo = !cast<Pseudo>(!subst("_MASK", "", NAME));
453  Pseudo UnmaskedTUPseudo = !if(HasTU, !cast<Pseudo>(!subst("_MASK", "", NAME # "_TU")), MaskedPseudo);
454  bits<4> MaskOpIdx = MaskIdx;
455}
456
457def RISCVMaskedPseudosTable : GenericTable {
458  let FilterClass = "RISCVMaskedPseudo";
459  let CppTypeName = "RISCVMaskedPseudoInfo";
460  let Fields = ["MaskedPseudo", "UnmaskedPseudo", "UnmaskedTUPseudo", "MaskOpIdx"];
461  let PrimaryKey = ["MaskedPseudo"];
462  let PrimaryKeyName = "getMaskedPseudoInfo";
463}
464
465class RISCVVLE<bit M, bit TU, bit Str, bit F, bits<3> S, bits<3> L> {
466  bits<1> Masked = M;
467  bits<1> IsTU = TU;
468  bits<1> Strided = Str;
469  bits<1> FF = F;
470  bits<3> Log2SEW = S;
471  bits<3> LMUL = L;
472  Pseudo Pseudo = !cast<Pseudo>(NAME);
473}
474
475def RISCVVLETable : GenericTable {
476  let FilterClass = "RISCVVLE";
477  let CppTypeName = "VLEPseudo";
478  let Fields = ["Masked", "IsTU", "Strided", "FF", "Log2SEW", "LMUL", "Pseudo"];
479  let PrimaryKey = ["Masked", "IsTU", "Strided", "FF", "Log2SEW", "LMUL"];
480  let PrimaryKeyName = "getVLEPseudo";
481}
482
483class RISCVVSE<bit M, bit Str, bits<3> S, bits<3> L> {
484  bits<1> Masked = M;
485  bits<1> Strided = Str;
486  bits<3> Log2SEW = S;
487  bits<3> LMUL = L;
488  Pseudo Pseudo = !cast<Pseudo>(NAME);
489}
490
491def RISCVVSETable : GenericTable {
492  let FilterClass = "RISCVVSE";
493  let CppTypeName = "VSEPseudo";
494  let Fields = ["Masked", "Strided", "Log2SEW", "LMUL", "Pseudo"];
495  let PrimaryKey = ["Masked", "Strided", "Log2SEW", "LMUL"];
496  let PrimaryKeyName = "getVSEPseudo";
497}
498
499class RISCVVLX_VSX<bit M, bit TU, bit O, bits<3> S, bits<3> L, bits<3> IL> {
500  bits<1> Masked = M;
501  bits<1> IsTU = TU;
502  bits<1> Ordered = O;
503  bits<3> Log2SEW = S;
504  bits<3> LMUL = L;
505  bits<3> IndexLMUL = IL;
506  Pseudo Pseudo = !cast<Pseudo>(NAME);
507}
508
509class RISCVVLX<bit M, bit TU, bit O, bits<3> S, bits<3> L, bits<3> IL> :
510  RISCVVLX_VSX<M, TU, O, S, L, IL>;
511class RISCVVSX<bit M, bit O, bits<3> S, bits<3> L, bits<3> IL> :
512  RISCVVLX_VSX<M, /*TU*/0, O, S, L, IL>;
513
514class RISCVVLX_VSXTable : GenericTable {
515  let CppTypeName = "VLX_VSXPseudo";
516  let Fields = ["Masked", "IsTU", "Ordered", "Log2SEW", "LMUL", "IndexLMUL", "Pseudo"];
517  let PrimaryKey = ["Masked", "IsTU", "Ordered", "Log2SEW", "LMUL", "IndexLMUL"];
518}
519
520def RISCVVLXTable : RISCVVLX_VSXTable {
521  let FilterClass = "RISCVVLX";
522  let PrimaryKeyName = "getVLXPseudo";
523}
524
525def RISCVVSXTable : RISCVVLX_VSXTable {
526  let FilterClass = "RISCVVSX";
527  let PrimaryKeyName = "getVSXPseudo";
528}
529
530class RISCVVLSEG<bits<4> N, bit M, bit TU, bit Str, bit F, bits<3> S, bits<3> L> {
531  bits<4> NF = N;
532  bits<1> Masked = M;
533  bits<1> IsTU = TU;
534  bits<1> Strided = Str;
535  bits<1> FF = F;
536  bits<3> Log2SEW = S;
537  bits<3> LMUL = L;
538  Pseudo Pseudo = !cast<Pseudo>(NAME);
539}
540
541def RISCVVLSEGTable : GenericTable {
542  let FilterClass = "RISCVVLSEG";
543  let CppTypeName = "VLSEGPseudo";
544  let Fields = ["NF", "Masked", "IsTU", "Strided", "FF", "Log2SEW", "LMUL", "Pseudo"];
545  let PrimaryKey = ["NF", "Masked", "IsTU", "Strided", "FF", "Log2SEW", "LMUL"];
546  let PrimaryKeyName = "getVLSEGPseudo";
547}
548
549class RISCVVLXSEG<bits<4> N, bit M, bit TU, bit O, bits<3> S, bits<3> L, bits<3> IL> {
550  bits<4> NF = N;
551  bits<1> Masked = M;
552  bits<1> IsTU = TU;
553  bits<1> Ordered = O;
554  bits<3> Log2SEW = S;
555  bits<3> LMUL = L;
556  bits<3> IndexLMUL = IL;
557  Pseudo Pseudo = !cast<Pseudo>(NAME);
558}
559
560def RISCVVLXSEGTable : GenericTable {
561  let FilterClass = "RISCVVLXSEG";
562  let CppTypeName = "VLXSEGPseudo";
563  let Fields = ["NF", "Masked", "IsTU", "Ordered", "Log2SEW", "LMUL", "IndexLMUL", "Pseudo"];
564  let PrimaryKey = ["NF", "Masked", "IsTU", "Ordered", "Log2SEW", "LMUL", "IndexLMUL"];
565  let PrimaryKeyName = "getVLXSEGPseudo";
566}
567
568class RISCVVSSEG<bits<4> N, bit M, bit Str, bits<3> S, bits<3> L> {
569  bits<4> NF = N;
570  bits<1> Masked = M;
571  bits<1> Strided = Str;
572  bits<3> Log2SEW = S;
573  bits<3> LMUL = L;
574  Pseudo Pseudo = !cast<Pseudo>(NAME);
575}
576
577def RISCVVSSEGTable : GenericTable {
578  let FilterClass = "RISCVVSSEG";
579  let CppTypeName = "VSSEGPseudo";
580  let Fields = ["NF", "Masked", "Strided", "Log2SEW", "LMUL", "Pseudo"];
581  let PrimaryKey = ["NF", "Masked", "Strided", "Log2SEW", "LMUL"];
582  let PrimaryKeyName = "getVSSEGPseudo";
583}
584
585class RISCVVSXSEG<bits<4> N, bit M, bit O, bits<3> S, bits<3> L, bits<3> IL> {
586  bits<4> NF = N;
587  bits<1> Masked = M;
588  bits<1> Ordered = O;
589  bits<3> Log2SEW = S;
590  bits<3> LMUL = L;
591  bits<3> IndexLMUL = IL;
592  Pseudo Pseudo = !cast<Pseudo>(NAME);
593}
594
595def RISCVVSXSEGTable : GenericTable {
596  let FilterClass = "RISCVVSXSEG";
597  let CppTypeName = "VSXSEGPseudo";
598  let Fields = ["NF", "Masked", "Ordered", "Log2SEW", "LMUL", "IndexLMUL", "Pseudo"];
599  let PrimaryKey = ["NF", "Masked", "Ordered", "Log2SEW", "LMUL", "IndexLMUL"];
600  let PrimaryKeyName = "getVSXSEGPseudo";
601}
602
603//===----------------------------------------------------------------------===//
604// Helpers to define the different pseudo instructions.
605//===----------------------------------------------------------------------===//
606
607// The destination vector register group for a masked vector instruction cannot
608// overlap the source mask register (v0), unless the destination vector register
609// is being written with a mask value (e.g., comparisons) or the scalar result
610// of a reduction.
611class GetVRegNoV0<VReg VRegClass> {
612  VReg R = !cond(!eq(VRegClass, VR) : VRNoV0,
613                 !eq(VRegClass, VRM2) : VRM2NoV0,
614                 !eq(VRegClass, VRM4) : VRM4NoV0,
615                 !eq(VRegClass, VRM8) : VRM8NoV0,
616                 !eq(VRegClass, VRN2M1) : VRN2M1NoV0,
617                 !eq(VRegClass, VRN2M2) : VRN2M2NoV0,
618                 !eq(VRegClass, VRN2M4) : VRN2M4NoV0,
619                 !eq(VRegClass, VRN3M1) : VRN3M1NoV0,
620                 !eq(VRegClass, VRN3M2) : VRN3M2NoV0,
621                 !eq(VRegClass, VRN4M1) : VRN4M1NoV0,
622                 !eq(VRegClass, VRN4M2) : VRN4M2NoV0,
623                 !eq(VRegClass, VRN5M1) : VRN5M1NoV0,
624                 !eq(VRegClass, VRN6M1) : VRN6M1NoV0,
625                 !eq(VRegClass, VRN7M1) : VRN7M1NoV0,
626                 !eq(VRegClass, VRN8M1) : VRN8M1NoV0,
627                 true : VRegClass);
628}
629
630// Join strings in list using separator and ignoring empty elements
631class Join<list<string> strings, string separator> {
632  string ret = !foldl(!head(strings), !tail(strings), a, b,
633                      !cond(
634                        !and(!empty(a), !empty(b)) : "",
635                        !empty(a) : b,
636                        !empty(b) : a,
637                        1 : a#separator#b));
638}
639
640class VPseudo<Instruction instr, LMULInfo m, dag outs, dag ins> :
641      Pseudo<outs, ins, []>, RISCVVPseudo {
642  let BaseInstr = instr;
643  let VLMul = m.value;
644}
645
646class VPseudoUSLoadNoMask<VReg RetClass, int EEW, bit DummyMask = 1> :
647      Pseudo<(outs RetClass:$rd),
648             (ins GPR:$rs1, AVL:$vl, ixlenimm:$sew),[]>,
649      RISCVVPseudo,
650      RISCVVLE</*Masked*/0, /*TU*/0, /*Strided*/0, /*FF*/0, log2<EEW>.val, VLMul> {
651  let mayLoad = 1;
652  let mayStore = 0;
653  let hasSideEffects = 0;
654  let HasVLOp = 1;
655  let HasSEWOp = 1;
656  let HasDummyMask = DummyMask;
657}
658
659class VPseudoUSLoadNoMaskTU<VReg RetClass, int EEW> :
660      Pseudo<(outs RetClass:$rd),
661             (ins RetClass:$dest, GPR:$rs1, AVL:$vl, ixlenimm:$sew),[]>,
662      RISCVVPseudo,
663      RISCVVLE</*Masked*/0, /*TU*/1, /*Strided*/0, /*FF*/0, log2<EEW>.val, VLMul> {
664  let mayLoad = 1;
665  let mayStore = 0;
666  let hasSideEffects = 0;
667  let HasVLOp = 1;
668  let HasSEWOp = 1;
669  let HasDummyMask = 1;
670  let HasMergeOp = 1;
671  let Constraints = "$rd = $dest";
672}
673
674class VPseudoUSLoadMask<VReg RetClass, int EEW> :
675      Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd),
676              (ins GetVRegNoV0<RetClass>.R:$merge,
677                   GPR:$rs1,
678                   VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy),[]>,
679      RISCVVPseudo,
680      RISCVVLE</*Masked*/1, /*TU*/1, /*Strided*/0, /*FF*/0, log2<EEW>.val, VLMul> {
681  let mayLoad = 1;
682  let mayStore = 0;
683  let hasSideEffects = 0;
684  let Constraints = "$rd = $merge";
685  let HasVLOp = 1;
686  let HasSEWOp = 1;
687  let HasMergeOp = 1;
688  let HasVecPolicyOp = 1;
689  let UsesMaskPolicy = 1;
690}
691
692class VPseudoUSLoadFFNoMask<VReg RetClass, int EEW, bit DummyMask = 1> :
693      Pseudo<(outs RetClass:$rd, GPR:$vl),
694             (ins GPR:$rs1, AVL:$avl, ixlenimm:$sew),[]>,
695      RISCVVPseudo,
696      RISCVVLE</*Masked*/0, /*TU*/0, /*Strided*/0, /*FF*/1, log2<EEW>.val, VLMul> {
697  let mayLoad = 1;
698  let mayStore = 0;
699  let hasSideEffects = 0;
700  let HasVLOp = 1;
701  let HasSEWOp = 1;
702  let HasDummyMask = DummyMask;
703}
704
705class VPseudoUSLoadFFNoMaskTU<VReg RetClass, int EEW> :
706      Pseudo<(outs RetClass:$rd, GPR:$vl),
707             (ins RetClass:$dest, GPR:$rs1, AVL:$avl, ixlenimm:$sew),[]>,
708      RISCVVPseudo,
709      RISCVVLE</*Masked*/0, /*TU*/1, /*Strided*/0, /*FF*/1, log2<EEW>.val, VLMul> {
710  let mayLoad = 1;
711  let mayStore = 0;
712  let hasSideEffects = 0;
713  let HasVLOp = 1;
714  let HasSEWOp = 1;
715  let HasDummyMask = 1;
716  let HasMergeOp = 1;
717  let Constraints = "$rd = $dest";
718}
719
720class VPseudoUSLoadFFMask<VReg RetClass, int EEW> :
721      Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd, GPR:$vl),
722              (ins GetVRegNoV0<RetClass>.R:$merge,
723                   GPR:$rs1,
724                   VMaskOp:$vm, AVL:$avl, ixlenimm:$sew, ixlenimm:$policy),[]>,
725      RISCVVPseudo,
726      RISCVVLE</*Masked*/1, /*TU*/1, /*Strided*/0, /*FF*/1, log2<EEW>.val, VLMul> {
727  let mayLoad = 1;
728  let mayStore = 0;
729  let hasSideEffects = 0;
730  let Constraints = "$rd = $merge";
731  let HasVLOp = 1;
732  let HasSEWOp = 1;
733  let HasMergeOp = 1;
734  let HasVecPolicyOp = 1;
735  let UsesMaskPolicy = 1;
736}
737
738class VPseudoSLoadNoMask<VReg RetClass, int EEW>:
739      Pseudo<(outs RetClass:$rd),
740             (ins GPR:$rs1, GPR:$rs2, AVL:$vl, ixlenimm:$sew),[]>,
741      RISCVVPseudo,
742      RISCVVLE</*Masked*/0, /*TU*/0, /*Strided*/1, /*FF*/0, log2<EEW>.val, VLMul> {
743  let mayLoad = 1;
744  let mayStore = 0;
745  let hasSideEffects = 0;
746  let HasVLOp = 1;
747  let HasSEWOp = 1;
748  let HasDummyMask = 1;
749}
750
751class VPseudoSLoadNoMaskTU<VReg RetClass, int EEW>:
752      Pseudo<(outs RetClass:$rd),
753             (ins RetClass:$dest, GPR:$rs1, GPR:$rs2, AVL:$vl, ixlenimm:$sew),[]>,
754      RISCVVPseudo,
755      RISCVVLE</*Masked*/0, /*TU*/1, /*Strided*/1, /*FF*/0, log2<EEW>.val, VLMul> {
756  let mayLoad = 1;
757  let mayStore = 0;
758  let hasSideEffects = 0;
759  let HasVLOp = 1;
760  let HasSEWOp = 1;
761  let HasDummyMask = 1;
762  let HasMergeOp = 1;
763  let Constraints = "$rd = $dest";
764}
765
766class VPseudoSLoadMask<VReg RetClass, int EEW>:
767      Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd),
768              (ins GetVRegNoV0<RetClass>.R:$merge,
769                   GPR:$rs1, GPR:$rs2,
770                   VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy),[]>,
771      RISCVVPseudo,
772      RISCVVLE</*Masked*/1, /*TU*/1, /*Strided*/1, /*FF*/0, log2<EEW>.val, VLMul> {
773  let mayLoad = 1;
774  let mayStore = 0;
775  let hasSideEffects = 0;
776  let Constraints = "$rd = $merge";
777  let HasVLOp = 1;
778  let HasSEWOp = 1;
779  let HasMergeOp = 1;
780  let HasVecPolicyOp = 1;
781  let UsesMaskPolicy = 1;
782}
783
784class VPseudoILoadNoMask<VReg RetClass, VReg IdxClass, int EEW, bits<3> LMUL,
785                         bit Ordered, bit EarlyClobber>:
786      Pseudo<(outs RetClass:$rd),
787             (ins GPR:$rs1, IdxClass:$rs2, AVL:$vl,
788              ixlenimm:$sew),[]>,
789      RISCVVPseudo,
790      RISCVVLX</*Masked*/0, /*TU*/0, Ordered, log2<EEW>.val, VLMul, LMUL> {
791  let mayLoad = 1;
792  let mayStore = 0;
793  let hasSideEffects = 0;
794  let HasVLOp = 1;
795  let HasSEWOp = 1;
796  let HasDummyMask = 1;
797  let Constraints = !if(!eq(EarlyClobber, 1), "@earlyclobber $rd", "");
798}
799
800class VPseudoILoadNoMaskTU<VReg RetClass, VReg IdxClass, int EEW, bits<3> LMUL,
801                           bit Ordered, bit EarlyClobber>:
802      Pseudo<(outs RetClass:$rd),
803             (ins RetClass:$dest, GPR:$rs1, IdxClass:$rs2, AVL:$vl,
804              ixlenimm:$sew),[]>,
805      RISCVVPseudo,
806      RISCVVLX</*Masked*/0, /*TU*/1, Ordered, log2<EEW>.val, VLMul, LMUL> {
807  let mayLoad = 1;
808  let mayStore = 0;
809  let hasSideEffects = 0;
810  let HasVLOp = 1;
811  let HasSEWOp = 1;
812  let HasDummyMask = 1;
813  let HasMergeOp = 1;
814  let Constraints = !if(!eq(EarlyClobber, 1), "@earlyclobber $rd, $rd = $dest", "$rd = $dest");
815}
816
817class VPseudoILoadMask<VReg RetClass, VReg IdxClass, int EEW, bits<3> LMUL,
818                       bit Ordered, bit EarlyClobber>:
819      Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd),
820              (ins GetVRegNoV0<RetClass>.R:$merge,
821                   GPR:$rs1, IdxClass:$rs2,
822                   VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy),[]>,
823      RISCVVPseudo,
824      RISCVVLX</*Masked*/1, /*TU*/1, Ordered, log2<EEW>.val, VLMul, LMUL> {
825  let mayLoad = 1;
826  let mayStore = 0;
827  let hasSideEffects = 0;
828  let Constraints = !if(!eq(EarlyClobber, 1), "@earlyclobber $rd, $rd = $merge", "$rd = $merge");
829  let HasVLOp = 1;
830  let HasSEWOp = 1;
831  let HasMergeOp = 1;
832  let HasVecPolicyOp = 1;
833  let UsesMaskPolicy = 1;
834}
835
836class VPseudoUSStoreNoMask<VReg StClass, int EEW, bit DummyMask = 1>:
837      Pseudo<(outs),
838              (ins StClass:$rd, GPR:$rs1, AVL:$vl, ixlenimm:$sew),[]>,
839      RISCVVPseudo,
840      RISCVVSE</*Masked*/0, /*Strided*/0, log2<EEW>.val, VLMul> {
841  let mayLoad = 0;
842  let mayStore = 1;
843  let hasSideEffects = 0;
844  let HasVLOp = 1;
845  let HasSEWOp = 1;
846  let HasDummyMask = DummyMask;
847}
848
849class VPseudoUSStoreMask<VReg StClass, int EEW>:
850      Pseudo<(outs),
851              (ins StClass:$rd, GPR:$rs1, VMaskOp:$vm, AVL:$vl, ixlenimm:$sew),[]>,
852      RISCVVPseudo,
853      RISCVVSE</*Masked*/1, /*Strided*/0, log2<EEW>.val, VLMul> {
854  let mayLoad = 0;
855  let mayStore = 1;
856  let hasSideEffects = 0;
857  let HasVLOp = 1;
858  let HasSEWOp = 1;
859}
860
861class VPseudoSStoreNoMask<VReg StClass, int EEW>:
862      Pseudo<(outs),
863              (ins StClass:$rd, GPR:$rs1, GPR:$rs2, AVL:$vl, ixlenimm:$sew),[]>,
864      RISCVVPseudo,
865      RISCVVSE</*Masked*/0, /*Strided*/1, log2<EEW>.val, VLMul> {
866  let mayLoad = 0;
867  let mayStore = 1;
868  let hasSideEffects = 0;
869  let HasVLOp = 1;
870  let HasSEWOp = 1;
871  let HasDummyMask = 1;
872}
873
874class VPseudoSStoreMask<VReg StClass, int EEW>:
875      Pseudo<(outs),
876              (ins StClass:$rd, GPR:$rs1, GPR:$rs2, VMaskOp:$vm, AVL:$vl, ixlenimm:$sew),[]>,
877      RISCVVPseudo,
878      RISCVVSE</*Masked*/1, /*Strided*/1, log2<EEW>.val, VLMul> {
879  let mayLoad = 0;
880  let mayStore = 1;
881  let hasSideEffects = 0;
882  let HasVLOp = 1;
883  let HasSEWOp = 1;
884}
885
886// Unary instruction that is never masked so HasDummyMask=0.
887class VPseudoUnaryNoDummyMask<VReg RetClass,
888                              DAGOperand Op2Class> :
889        Pseudo<(outs RetClass:$rd),
890               (ins Op2Class:$rs1, AVL:$vl, ixlenimm:$sew), []>,
891        RISCVVPseudo {
892  let mayLoad = 0;
893  let mayStore = 0;
894  let hasSideEffects = 0;
895  let HasVLOp = 1;
896  let HasSEWOp = 1;
897}
898
899class VPseudoUnaryNoDummyMaskTU<VReg RetClass,
900                                DAGOperand Op2Class> :
901        Pseudo<(outs RetClass:$rd),
902               (ins RetClass:$dest, Op2Class:$rs1, AVL:$vl, ixlenimm:$sew), []>,
903        RISCVVPseudo {
904  let mayLoad = 0;
905  let mayStore = 0;
906  let hasSideEffects = 0;
907  let HasVLOp = 1;
908  let HasSEWOp = 1;
909  let HasMergeOp = 1;
910  let Constraints = "$rd = $dest";
911}
912
913class VPseudoNullaryNoMask<VReg RegClass>:
914      Pseudo<(outs RegClass:$rd),
915             (ins AVL:$vl, ixlenimm:$sew),
916             []>, RISCVVPseudo {
917  let mayLoad = 0;
918  let mayStore = 0;
919  let hasSideEffects = 0;
920  let HasVLOp = 1;
921  let HasSEWOp = 1;
922  let HasDummyMask = 1;
923}
924
925class VPseudoNullaryNoMaskTU<VReg RegClass>:
926      Pseudo<(outs RegClass:$rd),
927             (ins RegClass:$merge, AVL:$vl, ixlenimm:$sew),
928             []>, RISCVVPseudo {
929  let mayLoad = 0;
930  let mayStore = 0;
931  let hasSideEffects = 0;
932  let Constraints = "$rd = $merge";
933  let HasVLOp = 1;
934  let HasSEWOp = 1;
935  let HasDummyMask = 1;
936  let HasMergeOp = 1;
937}
938
939class VPseudoNullaryMask<VReg RegClass>:
940      Pseudo<(outs GetVRegNoV0<RegClass>.R:$rd),
941             (ins GetVRegNoV0<RegClass>.R:$merge, VMaskOp:$vm, AVL:$vl,
942              ixlenimm:$sew, ixlenimm:$policy), []>, RISCVVPseudo {
943  let mayLoad = 0;
944  let mayStore = 0;
945  let hasSideEffects = 0;
946  let Constraints ="$rd = $merge";
947  let HasVLOp = 1;
948  let HasSEWOp = 1;
949  let HasMergeOp = 1;
950  let UsesMaskPolicy = 1;
951  let HasVecPolicyOp = 1;
952}
953
954// Nullary for pseudo instructions. They are expanded in
955// RISCVExpandPseudoInsts pass.
956class VPseudoNullaryPseudoM<string BaseInst>
957       : Pseudo<(outs VR:$rd), (ins AVL:$vl, ixlenimm:$sew), []>,
958       RISCVVPseudo {
959  let mayLoad = 0;
960  let mayStore = 0;
961  let hasSideEffects = 0;
962  let HasVLOp = 1;
963  let HasSEWOp = 1;
964  // BaseInstr is not used in RISCVExpandPseudoInsts pass.
965  // Just fill a corresponding real v-inst to pass tablegen check.
966  let BaseInstr = !cast<Instruction>(BaseInst);
967}
968
969// RetClass could be GPR or VReg.
970class VPseudoUnaryNoMask<DAGOperand RetClass, VReg OpClass, string Constraint = ""> :
971        Pseudo<(outs RetClass:$rd),
972               (ins OpClass:$rs2, AVL:$vl, ixlenimm:$sew), []>,
973        RISCVVPseudo {
974  let mayLoad = 0;
975  let mayStore = 0;
976  let hasSideEffects = 0;
977  let Constraints = Constraint;
978  let HasVLOp = 1;
979  let HasSEWOp = 1;
980  let HasDummyMask = 1;
981}
982
983// RetClass could be GPR or VReg.
984class VPseudoUnaryNoMaskTU<DAGOperand RetClass, VReg OpClass, string Constraint = ""> :
985      Pseudo<(outs RetClass:$rd),
986        (ins RetClass:$merge, OpClass:$rs2, AVL:$vl, ixlenimm:$sew), []>,
987        RISCVVPseudo {
988  let mayLoad = 0;
989  let mayStore = 0;
990  let hasSideEffects = 0;
991  let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret;
992  let HasVLOp = 1;
993  let HasSEWOp = 1;
994  let HasDummyMask = 1;
995  let HasMergeOp = 1;
996}
997
998class VPseudoUnaryMask<VReg RetClass, VReg OpClass, string Constraint = ""> :
999        Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd),
1000               (ins GetVRegNoV0<RetClass>.R:$merge, OpClass:$rs2,
1001                    VMaskOp:$vm, AVL:$vl, ixlenimm:$sew), []>,
1002        RISCVVPseudo {
1003  let mayLoad = 0;
1004  let mayStore = 0;
1005  let hasSideEffects = 0;
1006  let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret;
1007  let HasVLOp = 1;
1008  let HasSEWOp = 1;
1009  let HasMergeOp = 1;
1010  let UsesMaskPolicy = 1;
1011}
1012
1013class VPseudoUnaryMaskTA<VReg RetClass, VReg OpClass, string Constraint = ""> :
1014        Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd),
1015               (ins GetVRegNoV0<RetClass>.R:$merge, OpClass:$rs2,
1016                    VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>,
1017        RISCVVPseudo {
1018  let mayLoad = 0;
1019  let mayStore = 0;
1020  let hasSideEffects = 0;
1021  let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret;
1022  let HasVLOp = 1;
1023  let HasSEWOp = 1;
1024  let HasMergeOp = 1;
1025  let HasVecPolicyOp = 1;
1026  let UsesMaskPolicy = 1;
1027}
1028
1029// mask unary operation without maskedoff
1030class VPseudoMaskUnarySOutMask:
1031        Pseudo<(outs GPR:$rd),
1032               (ins VR:$rs1, VMaskOp:$vm, AVL:$vl, ixlenimm:$sew), []>,
1033        RISCVVPseudo {
1034  let mayLoad = 0;
1035  let mayStore = 0;
1036  let hasSideEffects = 0;
1037  let HasVLOp = 1;
1038  let HasSEWOp = 1;
1039}
1040
1041// Mask can be V0~V31
1042class VPseudoUnaryAnyMask<VReg RetClass,
1043                          VReg Op1Class> :
1044      Pseudo<(outs RetClass:$rd),
1045             (ins RetClass:$merge,
1046                  Op1Class:$rs2,
1047                  VR:$vm, AVL:$vl, ixlenimm:$sew),
1048             []>,
1049      RISCVVPseudo {
1050  let mayLoad = 0;
1051  let mayStore = 0;
1052  let hasSideEffects = 0;
1053  let Constraints = "@earlyclobber $rd, $rd = $merge";
1054  let HasVLOp = 1;
1055  let HasSEWOp = 1;
1056  let HasMergeOp = 1;
1057}
1058
1059class VPseudoBinaryNoMask<VReg RetClass,
1060                          VReg Op1Class,
1061                          DAGOperand Op2Class,
1062                          string Constraint,
1063                          int DummyMask = 1> :
1064        Pseudo<(outs RetClass:$rd),
1065               (ins Op1Class:$rs2, Op2Class:$rs1, AVL:$vl, ixlenimm:$sew), []>,
1066        RISCVVPseudo {
1067  let mayLoad = 0;
1068  let mayStore = 0;
1069  let hasSideEffects = 0;
1070  let Constraints = Constraint;
1071  let HasVLOp = 1;
1072  let HasSEWOp = 1;
1073  let HasDummyMask = DummyMask;
1074}
1075
1076class VPseudoBinaryNoMaskTU<VReg RetClass,
1077                            VReg Op1Class,
1078                            DAGOperand Op2Class,
1079                            string Constraint> :
1080        Pseudo<(outs RetClass:$rd),
1081               (ins RetClass:$merge, Op1Class:$rs2, Op2Class:$rs1, AVL:$vl, ixlenimm:$sew), []>,
1082        RISCVVPseudo {
1083  let mayLoad = 0;
1084  let mayStore = 0;
1085  let hasSideEffects = 0;
1086  let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret;
1087  let HasVLOp = 1;
1088  let HasSEWOp = 1;
1089  let HasDummyMask = 1;
1090  let HasMergeOp = 1;
1091}
1092
1093// Special version of VPseudoBinaryNoMask where we pretend the first source is
1094// tied to the destination.
1095// This allows maskedoff and rs2 to be the same register.
1096class VPseudoTiedBinaryNoMask<VReg RetClass,
1097                              DAGOperand Op2Class,
1098                              string Constraint> :
1099        Pseudo<(outs RetClass:$rd),
1100               (ins RetClass:$rs2, Op2Class:$rs1, AVL:$vl, ixlenimm:$sew,
1101                    ixlenimm:$policy), []>,
1102        RISCVVPseudo {
1103  let mayLoad = 0;
1104  let mayStore = 0;
1105  let hasSideEffects = 0;
1106  let Constraints = Join<[Constraint, "$rd = $rs2"], ",">.ret;
1107  let HasVLOp = 1;
1108  let HasSEWOp = 1;
1109  let HasDummyMask = 1;
1110  let HasVecPolicyOp = 1;
1111  let isConvertibleToThreeAddress = 1;
1112}
1113
1114class VPseudoIStoreNoMask<VReg StClass, VReg IdxClass, int EEW, bits<3> LMUL,
1115                          bit Ordered>:
1116      Pseudo<(outs),
1117              (ins StClass:$rd, GPR:$rs1, IdxClass:$rs2, AVL:$vl, ixlenimm:$sew),[]>,
1118      RISCVVPseudo,
1119      RISCVVSX</*Masked*/0, Ordered, log2<EEW>.val, VLMul, LMUL> {
1120  let mayLoad = 0;
1121  let mayStore = 1;
1122  let hasSideEffects = 0;
1123  let HasVLOp = 1;
1124  let HasSEWOp = 1;
1125  let HasDummyMask = 1;
1126}
1127
1128class VPseudoIStoreMask<VReg StClass, VReg IdxClass, int EEW, bits<3> LMUL,
1129                        bit Ordered>:
1130      Pseudo<(outs),
1131              (ins StClass:$rd, GPR:$rs1, IdxClass:$rs2, VMaskOp:$vm, AVL:$vl, ixlenimm:$sew),[]>,
1132      RISCVVPseudo,
1133      RISCVVSX</*Masked*/1, Ordered, log2<EEW>.val, VLMul, LMUL> {
1134  let mayLoad = 0;
1135  let mayStore = 1;
1136  let hasSideEffects = 0;
1137  let HasVLOp = 1;
1138  let HasSEWOp = 1;
1139}
1140
1141class VPseudoBinaryMask<VReg RetClass,
1142                        RegisterClass Op1Class,
1143                        DAGOperand Op2Class,
1144                        string Constraint> :
1145        Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd),
1146                (ins GetVRegNoV0<RetClass>.R:$merge,
1147                     Op1Class:$rs2, Op2Class:$rs1,
1148                     VMaskOp:$vm, AVL:$vl, ixlenimm:$sew), []>,
1149        RISCVVPseudo {
1150  let mayLoad = 0;
1151  let mayStore = 0;
1152  let hasSideEffects = 0;
1153  let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret;
1154  let HasVLOp = 1;
1155  let HasSEWOp = 1;
1156  let HasMergeOp = 1;
1157}
1158
1159class VPseudoBinaryMaskPolicy<VReg RetClass,
1160                              RegisterClass Op1Class,
1161                              DAGOperand Op2Class,
1162                              string Constraint> :
1163        Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd),
1164                (ins GetVRegNoV0<RetClass>.R:$merge,
1165                     Op1Class:$rs2, Op2Class:$rs1,
1166                     VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>,
1167        RISCVVPseudo {
1168  let mayLoad = 0;
1169  let mayStore = 0;
1170  let hasSideEffects = 0;
1171  let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret;
1172  let HasVLOp = 1;
1173  let HasSEWOp = 1;
1174  let HasMergeOp = 1;
1175  let HasVecPolicyOp = 1;
1176  let UsesMaskPolicy = 1;
1177}
1178
1179// Like VPseudoBinaryMask, but output can be V0.
1180class VPseudoBinaryMOutMask<VReg RetClass,
1181                            RegisterClass Op1Class,
1182                            DAGOperand Op2Class,
1183                            string Constraint> :
1184        Pseudo<(outs RetClass:$rd),
1185                (ins RetClass:$merge,
1186                     Op1Class:$rs2, Op2Class:$rs1,
1187                     VMaskOp:$vm, AVL:$vl, ixlenimm:$sew), []>,
1188        RISCVVPseudo {
1189  let mayLoad = 0;
1190  let mayStore = 0;
1191  let hasSideEffects = 0;
1192  let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret;
1193  let HasVLOp = 1;
1194  let HasSEWOp = 1;
1195  let HasMergeOp = 1;
1196  let UsesMaskPolicy = 1;
1197}
1198
1199// Special version of VPseudoBinaryMask where we pretend the first source is
1200// tied to the destination so we can workaround the earlyclobber constraint.
1201// This allows maskedoff and rs2 to be the same register.
1202class VPseudoTiedBinaryMask<VReg RetClass,
1203                            DAGOperand Op2Class,
1204                            string Constraint> :
1205        Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd),
1206                (ins GetVRegNoV0<RetClass>.R:$merge,
1207                     Op2Class:$rs1,
1208                     VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy), []>,
1209        RISCVVPseudo {
1210  let mayLoad = 0;
1211  let mayStore = 0;
1212  let hasSideEffects = 0;
1213  let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret;
1214  let HasVLOp = 1;
1215  let HasSEWOp = 1;
1216  let HasMergeOp = 0; // Merge is also rs2.
1217  let HasVecPolicyOp = 1;
1218  let UsesMaskPolicy = 1;
1219}
1220
1221class VPseudoBinaryCarryIn<VReg RetClass,
1222                           VReg Op1Class,
1223                           DAGOperand Op2Class,
1224                           LMULInfo MInfo,
1225                           bit CarryIn,
1226                           string Constraint> :
1227        Pseudo<(outs RetClass:$rd),
1228               !if(CarryIn,
1229                  (ins Op1Class:$rs2, Op2Class:$rs1, VMV0:$carry, AVL:$vl,
1230                       ixlenimm:$sew),
1231                  (ins Op1Class:$rs2, Op2Class:$rs1, AVL:$vl, ixlenimm:$sew)), []>,
1232        RISCVVPseudo {
1233  let mayLoad = 0;
1234  let mayStore = 0;
1235  let hasSideEffects = 0;
1236  let Constraints = Constraint;
1237  let HasVLOp = 1;
1238  let HasSEWOp = 1;
1239  let HasMergeOp = 0;
1240  let VLMul = MInfo.value;
1241}
1242
1243class VPseudoTiedBinaryCarryIn<VReg RetClass,
1244                               VReg Op1Class,
1245                               DAGOperand Op2Class,
1246                               LMULInfo MInfo,
1247                               bit CarryIn,
1248                               string Constraint> :
1249        Pseudo<(outs RetClass:$rd),
1250               !if(CarryIn,
1251                  (ins RetClass:$merge, Op1Class:$rs2, Op2Class:$rs1, VMV0:$carry, AVL:$vl,
1252                       ixlenimm:$sew),
1253                  (ins RetClass:$merge, Op1Class:$rs2, Op2Class:$rs1, AVL:$vl, ixlenimm:$sew)), []>,
1254        RISCVVPseudo {
1255  let mayLoad = 0;
1256  let mayStore = 0;
1257  let hasSideEffects = 0;
1258  let Constraints = Join<[Constraint, "$rd = $merge"], ",">.ret;
1259  let HasVLOp = 1;
1260  let HasSEWOp = 1;
1261  let HasMergeOp = 1;
1262  let HasVecPolicyOp = 0;
1263  let VLMul = MInfo.value;
1264}
1265
1266class VPseudoTernaryNoMask<VReg RetClass,
1267                           RegisterClass Op1Class,
1268                           DAGOperand Op2Class,
1269                           string Constraint> :
1270        Pseudo<(outs RetClass:$rd),
1271               (ins RetClass:$rs3, Op1Class:$rs1, Op2Class:$rs2,
1272                    AVL:$vl, ixlenimm:$sew),
1273               []>,
1274        RISCVVPseudo {
1275  let mayLoad = 0;
1276  let mayStore = 0;
1277  let hasSideEffects = 0;
1278  let Constraints = Join<[Constraint, "$rd = $rs3"], ",">.ret;
1279  let HasVLOp = 1;
1280  let HasSEWOp = 1;
1281  let HasMergeOp = 1;
1282  let HasDummyMask = 1;
1283}
1284
1285class VPseudoTernaryNoMaskWithPolicy<VReg RetClass,
1286                                     RegisterClass Op1Class,
1287                                     DAGOperand Op2Class,
1288                                     string Constraint> :
1289        Pseudo<(outs RetClass:$rd),
1290               (ins RetClass:$rs3, Op1Class:$rs1, Op2Class:$rs2,
1291                    AVL:$vl, ixlenimm:$sew, ixlenimm:$policy),
1292               []>,
1293        RISCVVPseudo {
1294  let mayLoad = 0;
1295  let mayStore = 0;
1296  let hasSideEffects = 0;
1297  let Constraints = Join<[Constraint, "$rd = $rs3"], ",">.ret;
1298  let HasVecPolicyOp = 1;
1299  let HasVLOp = 1;
1300  let HasSEWOp = 1;
1301  let HasMergeOp = 1;
1302  let HasDummyMask = 1;
1303}
1304
1305class VPseudoUSSegLoadNoMask<VReg RetClass, int EEW, bits<4> NF>:
1306      Pseudo<(outs RetClass:$rd),
1307             (ins GPR:$rs1, AVL:$vl, ixlenimm:$sew),[]>,
1308      RISCVVPseudo,
1309      RISCVVLSEG<NF, /*Masked*/0, /*TU*/0, /*Strided*/0, /*FF*/0, log2<EEW>.val, VLMul> {
1310  let mayLoad = 1;
1311  let mayStore = 0;
1312  let hasSideEffects = 0;
1313  let HasVLOp = 1;
1314  let HasSEWOp = 1;
1315  let HasDummyMask = 1;
1316}
1317
1318class VPseudoUSSegLoadNoMaskTU<VReg RetClass, int EEW, bits<4> NF>:
1319      Pseudo<(outs RetClass:$rd),
1320             (ins RetClass:$dest, GPR:$rs1, AVL:$vl, ixlenimm:$sew),[]>,
1321      RISCVVPseudo,
1322      RISCVVLSEG<NF, /*Masked*/0, /*TU*/1, /*Strided*/0, /*FF*/0, log2<EEW>.val, VLMul> {
1323  let mayLoad = 1;
1324  let mayStore = 0;
1325  let hasSideEffects = 0;
1326  let HasVLOp = 1;
1327  let HasSEWOp = 1;
1328  let HasDummyMask = 1;
1329  let HasMergeOp = 1;
1330  let Constraints = "$rd = $dest";
1331}
1332
1333class VPseudoUSSegLoadMask<VReg RetClass, int EEW, bits<4> NF>:
1334      Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd),
1335             (ins GetVRegNoV0<RetClass>.R:$merge, GPR:$rs1,
1336                  VMaskOp:$vm, AVL:$vl, ixlenimm:$sew, ixlenimm:$policy),[]>,
1337      RISCVVPseudo,
1338      RISCVVLSEG<NF, /*Masked*/1, /*TU*/1, /*Strided*/0, /*FF*/0, log2<EEW>.val, VLMul> {
1339  let mayLoad = 1;
1340  let mayStore = 0;
1341  let hasSideEffects = 0;
1342  let Constraints = "$rd = $merge";
1343  let HasVLOp = 1;
1344  let HasSEWOp = 1;
1345  let HasMergeOp = 1;
1346  let HasVecPolicyOp = 1;
1347  let UsesMaskPolicy = 1;
1348}
1349
1350class VPseudoUSSegLoadFFNoMask<VReg RetClass, int EEW, bits<4> NF>:
1351      Pseudo<(outs RetClass:$rd, GPR:$vl),
1352             (ins GPR:$rs1, AVL:$avl, ixlenimm:$sew),[]>,
1353      RISCVVPseudo,
1354      RISCVVLSEG<NF, /*Masked*/0, /*TU*/0, /*Strided*/0, /*FF*/1, log2<EEW>.val, VLMul> {
1355  let mayLoad = 1;
1356  let mayStore = 0;
1357  let hasSideEffects = 0;
1358  let HasVLOp = 1;
1359  let HasSEWOp = 1;
1360  let HasDummyMask = 1;
1361}
1362
1363class VPseudoUSSegLoadFFNoMaskTU<VReg RetClass, int EEW, bits<4> NF>:
1364      Pseudo<(outs RetClass:$rd, GPR:$vl),
1365             (ins RetClass:$dest, GPR:$rs1, AVL:$avl, ixlenimm:$sew),[]>,
1366      RISCVVPseudo,
1367      RISCVVLSEG<NF, /*Masked*/0, /*TU*/1, /*Strided*/0, /*FF*/1, log2<EEW>.val, VLMul> {
1368  let mayLoad = 1;
1369  let mayStore = 0;
1370  let hasSideEffects = 0;
1371  let HasVLOp = 1;
1372  let HasSEWOp = 1;
1373  let HasDummyMask = 1;
1374  let HasMergeOp = 1;
1375  let Constraints = "$rd = $dest";
1376}
1377
1378class VPseudoUSSegLoadFFMask<VReg RetClass, int EEW, bits<4> NF>:
1379      Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd, GPR:$vl),
1380             (ins GetVRegNoV0<RetClass>.R:$merge, GPR:$rs1,
1381                  VMaskOp:$vm, AVL:$avl, ixlenimm:$sew, ixlenimm:$policy),[]>,
1382      RISCVVPseudo,
1383      RISCVVLSEG<NF, /*Masked*/1, /*TU*/1, /*Strided*/0, /*FF*/1, log2<EEW>.val, VLMul> {
1384  let mayLoad = 1;
1385  let mayStore = 0;
1386  let hasSideEffects = 0;
1387  let Constraints = "$rd = $merge";
1388  let HasVLOp = 1;
1389  let HasSEWOp = 1;
1390  let HasMergeOp = 1;
1391  let HasVecPolicyOp = 1;
1392  let UsesMaskPolicy = 1;
1393}
1394
1395class VPseudoSSegLoadNoMask<VReg RetClass, int EEW, bits<4> NF>:
1396      Pseudo<(outs RetClass:$rd),
1397             (ins GPR:$rs1, GPR:$offset, AVL:$vl, ixlenimm:$sew),[]>,
1398      RISCVVPseudo,
1399      RISCVVLSEG<NF, /*Masked*/0, /*TU*/0, /*Strided*/1, /*FF*/0, log2<EEW>.val, VLMul> {
1400  let mayLoad = 1;
1401  let mayLoad = 1;
1402  let mayStore = 0;
1403  let hasSideEffects = 0;
1404  let HasVLOp = 1;
1405  let HasSEWOp = 1;
1406  let HasDummyMask = 1;
1407}
1408
1409class VPseudoSSegLoadNoMaskTU<VReg RetClass, int EEW, bits<4> NF>:
1410      Pseudo<(outs RetClass:$rd),
1411             (ins RetClass:$merge, GPR:$rs1, GPR:$offset, AVL:$vl, ixlenimm:$sew),[]>,
1412      RISCVVPseudo,
1413      RISCVVLSEG<NF, /*Masked*/0, /*TU*/1, /*Strided*/1, /*FF*/0, log2<EEW>.val, VLMul> {
1414  let mayLoad = 1;
1415  let mayLoad = 1;
1416  let mayStore = 0;
1417  let hasSideEffects = 0;
1418  let HasVLOp = 1;
1419  let HasSEWOp = 1;
1420  let HasDummyMask = 1;
1421  let HasMergeOp = 1;
1422  let Constraints = "$rd = $merge";
1423}
1424
1425class VPseudoSSegLoadMask<VReg RetClass, int EEW, bits<4> NF>:
1426      Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd),
1427             (ins GetVRegNoV0<RetClass>.R:$merge, GPR:$rs1,
1428                  GPR:$offset, VMaskOp:$vm, AVL:$vl, ixlenimm:$sew,
1429                  ixlenimm:$policy),[]>,
1430      RISCVVPseudo,
1431      RISCVVLSEG<NF, /*Masked*/1, /*TU*/1, /*Strided*/1, /*FF*/0, log2<EEW>.val, VLMul> {
1432  let mayLoad = 1;
1433  let mayStore = 0;
1434  let hasSideEffects = 0;
1435  let Constraints = "$rd = $merge";
1436  let HasVLOp = 1;
1437  let HasSEWOp = 1;
1438  let HasMergeOp = 1;
1439  let HasVecPolicyOp = 1;
1440  let UsesMaskPolicy = 1;
1441}
1442
1443class VPseudoISegLoadNoMask<VReg RetClass, VReg IdxClass, int EEW, bits<3> LMUL,
1444                            bits<4> NF, bit Ordered>:
1445      Pseudo<(outs RetClass:$rd),
1446             (ins GPR:$rs1, IdxClass:$offset, AVL:$vl, ixlenimm:$sew),[]>,
1447      RISCVVPseudo,
1448      RISCVVLXSEG<NF, /*Masked*/0, /*TU*/0, Ordered, log2<EEW>.val, VLMul, LMUL> {
1449  let mayLoad = 1;
1450  let mayStore = 0;
1451  let hasSideEffects = 0;
1452  // For vector indexed segment loads, the destination vector register groups
1453  // cannot overlap the source vector register group
1454  let Constraints = "@earlyclobber $rd";
1455  let HasVLOp = 1;
1456  let HasSEWOp = 1;
1457  let HasDummyMask = 1;
1458}
1459
1460class VPseudoISegLoadNoMaskTU<VReg RetClass, VReg IdxClass, int EEW, bits<3> LMUL,
1461                              bits<4> NF, bit Ordered>:
1462      Pseudo<(outs RetClass:$rd),
1463             (ins RetClass:$merge, GPR:$rs1, IdxClass:$offset, AVL:$vl, ixlenimm:$sew),[]>,
1464      RISCVVPseudo,
1465      RISCVVLXSEG<NF, /*Masked*/0, /*TU*/1, Ordered, log2<EEW>.val, VLMul, LMUL> {
1466  let mayLoad = 1;
1467  let mayStore = 0;
1468  let hasSideEffects = 0;
1469  // For vector indexed segment loads, the destination vector register groups
1470  // cannot overlap the source vector register group
1471  let Constraints = "@earlyclobber $rd, $rd = $merge";
1472  let HasVLOp = 1;
1473  let HasSEWOp = 1;
1474  let HasDummyMask = 1;
1475  let HasMergeOp = 1;
1476}
1477
1478class VPseudoISegLoadMask<VReg RetClass, VReg IdxClass, int EEW, bits<3> LMUL,
1479                          bits<4> NF, bit Ordered>:
1480      Pseudo<(outs GetVRegNoV0<RetClass>.R:$rd),
1481             (ins GetVRegNoV0<RetClass>.R:$merge, GPR:$rs1,
1482                  IdxClass:$offset, VMaskOp:$vm, AVL:$vl, ixlenimm:$sew,
1483                  ixlenimm:$policy),[]>,
1484      RISCVVPseudo,
1485      RISCVVLXSEG<NF, /*Masked*/1, /*TU*/1, Ordered, log2<EEW>.val, VLMul, LMUL> {
1486  let mayLoad = 1;
1487  let mayStore = 0;
1488  let hasSideEffects = 0;
1489  // For vector indexed segment loads, the destination vector register groups
1490  // cannot overlap the source vector register group
1491  let Constraints = "@earlyclobber $rd, $rd = $merge";
1492  let HasVLOp = 1;
1493  let HasSEWOp = 1;
1494  let HasMergeOp = 1;
1495  let HasVecPolicyOp = 1;
1496  let UsesMaskPolicy = 1;
1497}
1498
1499class VPseudoUSSegStoreNoMask<VReg ValClass, int EEW, bits<4> NF>:
1500      Pseudo<(outs),
1501             (ins ValClass:$rd, GPR:$rs1, AVL:$vl, ixlenimm:$sew),[]>,
1502      RISCVVPseudo,
1503      RISCVVSSEG<NF, /*Masked*/0, /*Strided*/0, log2<EEW>.val, VLMul> {
1504  let mayLoad = 0;
1505  let mayStore = 1;
1506  let hasSideEffects = 0;
1507  let HasVLOp = 1;
1508  let HasSEWOp = 1;
1509  let HasDummyMask = 1;
1510}
1511
1512class VPseudoUSSegStoreMask<VReg ValClass, int EEW, bits<4> NF>:
1513      Pseudo<(outs),
1514             (ins ValClass:$rd, GPR:$rs1,
1515                  VMaskOp:$vm, AVL:$vl, ixlenimm:$sew),[]>,
1516      RISCVVPseudo,
1517      RISCVVSSEG<NF, /*Masked*/1, /*Strided*/0, log2<EEW>.val, VLMul> {
1518  let mayLoad = 0;
1519  let mayStore = 1;
1520  let hasSideEffects = 0;
1521  let HasVLOp = 1;
1522  let HasSEWOp = 1;
1523}
1524
1525class VPseudoSSegStoreNoMask<VReg ValClass, int EEW, bits<4> NF>:
1526      Pseudo<(outs),
1527             (ins ValClass:$rd, GPR:$rs1, GPR: $offset, AVL:$vl, ixlenimm:$sew),[]>,
1528      RISCVVPseudo,
1529      RISCVVSSEG<NF, /*Masked*/0, /*Strided*/1, log2<EEW>.val, VLMul> {
1530  let mayLoad = 0;
1531  let mayStore = 1;
1532  let hasSideEffects = 0;
1533  let HasVLOp = 1;
1534  let HasSEWOp = 1;
1535  let HasDummyMask = 1;
1536}
1537
1538class VPseudoSSegStoreMask<VReg ValClass, int EEW, bits<4> NF>:
1539      Pseudo<(outs),
1540             (ins ValClass:$rd, GPR:$rs1, GPR: $offset,
1541                  VMaskOp:$vm, AVL:$vl, ixlenimm:$sew),[]>,
1542      RISCVVPseudo,
1543      RISCVVSSEG<NF, /*Masked*/1, /*Strided*/1, log2<EEW>.val, VLMul> {
1544  let mayLoad = 0;
1545  let mayStore = 1;
1546  let hasSideEffects = 0;
1547  let HasVLOp = 1;
1548  let HasSEWOp = 1;
1549}
1550
1551class VPseudoISegStoreNoMask<VReg ValClass, VReg IdxClass, int EEW, bits<3> LMUL,
1552                             bits<4> NF, bit Ordered>:
1553      Pseudo<(outs),
1554             (ins ValClass:$rd, GPR:$rs1, IdxClass: $index,
1555                  AVL:$vl, ixlenimm:$sew),[]>,
1556      RISCVVPseudo,
1557      RISCVVSXSEG<NF, /*Masked*/0, Ordered, log2<EEW>.val, VLMul, LMUL> {
1558  let mayLoad = 0;
1559  let mayStore = 1;
1560  let hasSideEffects = 0;
1561  let HasVLOp = 1;
1562  let HasSEWOp = 1;
1563  let HasDummyMask = 1;
1564}
1565
1566class VPseudoISegStoreMask<VReg ValClass, VReg IdxClass, int EEW, bits<3> LMUL,
1567                           bits<4> NF, bit Ordered>:
1568      Pseudo<(outs),
1569             (ins ValClass:$rd, GPR:$rs1, IdxClass: $index,
1570                  VMaskOp:$vm, AVL:$vl, ixlenimm:$sew),[]>,
1571      RISCVVPseudo,
1572      RISCVVSXSEG<NF, /*Masked*/1, Ordered, log2<EEW>.val, VLMul, LMUL> {
1573  let mayLoad = 0;
1574  let mayStore = 1;
1575  let hasSideEffects = 0;
1576  let HasVLOp = 1;
1577  let HasSEWOp = 1;
1578}
1579
1580multiclass VPseudoUSLoad {
1581  foreach eew = EEWList in {
1582    foreach lmul = MxSet<eew>.m in {
1583      defvar LInfo = lmul.MX;
1584      defvar vreg = lmul.vrclass;
1585      let VLMul = lmul.value in {
1586        def "E" # eew # "_V_" # LInfo :
1587          VPseudoUSLoadNoMask<vreg, eew>,
1588          VLESched<eew>;
1589        def "E" # eew # "_V_" # LInfo # "_TU":
1590          VPseudoUSLoadNoMaskTU<vreg, eew>,
1591          VLESched<eew>;
1592        def "E" # eew # "_V_" # LInfo # "_MASK" :
1593          VPseudoUSLoadMask<vreg, eew>,
1594          VLESched<eew>;
1595      }
1596    }
1597  }
1598}
1599
1600multiclass VPseudoFFLoad {
1601  foreach eew = EEWList in {
1602    foreach lmul = MxSet<eew>.m in {
1603      defvar LInfo = lmul.MX;
1604      defvar vreg = lmul.vrclass;
1605      let VLMul = lmul.value in {
1606        def "E" # eew # "FF_V_" # LInfo:
1607          VPseudoUSLoadFFNoMask<vreg, eew>,
1608          VLFSched<eew>;
1609        def "E" # eew # "FF_V_" # LInfo # "_TU":
1610          VPseudoUSLoadFFNoMaskTU<vreg, eew>,
1611          VLFSched<eew>;
1612        def "E" # eew # "FF_V_" # LInfo # "_MASK":
1613          VPseudoUSLoadFFMask<vreg, eew>,
1614          VLFSched<eew>;
1615      }
1616    }
1617  }
1618}
1619
1620multiclass VPseudoLoadMask {
1621  foreach mti = AllMasks in {
1622    let VLMul = mti.LMul.value in {
1623      def "_V_" # mti.BX : VPseudoUSLoadNoMask<VR, /*EEW*/1, /*DummyMask*/0>;
1624    }
1625  }
1626}
1627
1628multiclass VPseudoSLoad {
1629  foreach eew = EEWList in {
1630    foreach lmul = MxSet<eew>.m in {
1631      defvar LInfo = lmul.MX;
1632      defvar vreg = lmul.vrclass;
1633      let VLMul = lmul.value in {
1634        def "E" # eew # "_V_" # LInfo : VPseudoSLoadNoMask<vreg, eew>,
1635                                        VLSSched<eew>;
1636        def "E" # eew # "_V_" # LInfo # "_TU": VPseudoSLoadNoMaskTU<vreg, eew>,
1637                                        VLSSched<eew>;
1638        def "E" # eew # "_V_" # LInfo # "_MASK" : VPseudoSLoadMask<vreg, eew>,
1639                                                  VLSSched<eew>;
1640      }
1641    }
1642  }
1643}
1644
1645multiclass VPseudoILoad<bit Ordered> {
1646  foreach eew = EEWList in {
1647    foreach sew = EEWList in {
1648      foreach lmul = MxSet<sew>.m in {
1649        defvar octuple_lmul = lmul.octuple;
1650        // Calculate emul = eew * lmul / sew
1651        defvar octuple_emul = !srl(!mul(eew, octuple_lmul), log2<sew>.val);
1652        if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then {
1653          defvar LInfo = lmul.MX;
1654          defvar IdxLInfo = octuple_to_str<octuple_emul>.ret;
1655          defvar idx_lmul = !cast<LMULInfo>("V_" # IdxLInfo);
1656          defvar Vreg = lmul.vrclass;
1657          defvar IdxVreg = idx_lmul.vrclass;
1658          defvar HasConstraint = !ne(sew, eew);
1659          defvar Order = !if(Ordered, "O", "U");
1660          let VLMul = lmul.value in {
1661            def "EI" # eew # "_V_" # IdxLInfo # "_" # LInfo :
1662              VPseudoILoadNoMask<Vreg, IdxVreg, eew, idx_lmul.value, Ordered, HasConstraint>,
1663              VLXSched<eew, Order>;
1664            def "EI" # eew # "_V_" # IdxLInfo # "_" # LInfo # "_TU":
1665              VPseudoILoadNoMaskTU<Vreg, IdxVreg, eew, idx_lmul.value, Ordered, HasConstraint>,
1666              VLXSched<eew, Order>;
1667            def "EI" # eew # "_V_" # IdxLInfo # "_" # LInfo # "_MASK" :
1668              VPseudoILoadMask<Vreg, IdxVreg, eew, idx_lmul.value, Ordered, HasConstraint>,
1669              VLXSched<eew, Order>;
1670          }
1671        }
1672      }
1673    }
1674  }
1675}
1676
1677multiclass VPseudoUSStore {
1678  foreach eew = EEWList in {
1679    foreach lmul = MxSet<eew>.m in {
1680      defvar LInfo = lmul.MX;
1681      defvar vreg = lmul.vrclass;
1682      let VLMul = lmul.value in {
1683        def "E" # eew # "_V_" # LInfo : VPseudoUSStoreNoMask<vreg, eew>,
1684                                        VSESched<eew>;
1685        def "E" # eew # "_V_" # LInfo # "_MASK" : VPseudoUSStoreMask<vreg, eew>,
1686                                                  VSESched<eew>;
1687      }
1688    }
1689  }
1690}
1691
1692multiclass VPseudoStoreMask {
1693  foreach mti = AllMasks in {
1694    let VLMul = mti.LMul.value in {
1695      def "_V_" # mti.BX : VPseudoUSStoreNoMask<VR, /*EEW*/1, /*DummyMask*/0>;
1696    }
1697  }
1698}
1699
1700multiclass VPseudoSStore {
1701  foreach eew = EEWList in {
1702    foreach lmul = MxSet<eew>.m in {
1703      defvar LInfo = lmul.MX;
1704      defvar vreg = lmul.vrclass;
1705      let VLMul = lmul.value in {
1706        def "E" # eew # "_V_" # LInfo : VPseudoSStoreNoMask<vreg, eew>,
1707                                        VSSSched<eew>;
1708        def "E" # eew # "_V_" # LInfo # "_MASK" : VPseudoSStoreMask<vreg, eew>,
1709                                                  VSSSched<eew>;
1710      }
1711    }
1712  }
1713}
1714
1715multiclass VPseudoIStore<bit Ordered> {
1716  foreach eew = EEWList in {
1717    foreach sew = EEWList in {
1718      foreach lmul = MxSet<sew>.m in {
1719        defvar octuple_lmul = lmul.octuple;
1720        // Calculate emul = eew * lmul / sew
1721        defvar octuple_emul = !srl(!mul(eew, octuple_lmul), log2<sew>.val);
1722        if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then {
1723          defvar LInfo = lmul.MX;
1724          defvar IdxLInfo = octuple_to_str<octuple_emul>.ret;
1725          defvar idx_lmul = !cast<LMULInfo>("V_" # IdxLInfo);
1726          defvar Vreg = lmul.vrclass;
1727          defvar IdxVreg = idx_lmul.vrclass;
1728          defvar Order = !if(Ordered, "O", "U");
1729          let VLMul = lmul.value in {
1730            def "EI" # eew # "_V_" # IdxLInfo # "_" # LInfo :
1731              VPseudoIStoreNoMask<Vreg, IdxVreg, eew, idx_lmul.value, Ordered>,
1732              VSXSched<eew, Order>;
1733            def "EI" # eew # "_V_" # IdxLInfo # "_" # LInfo # "_MASK" :
1734              VPseudoIStoreMask<Vreg, IdxVreg, eew, idx_lmul.value, Ordered>,
1735              VSXSched<eew, Order>;
1736          }
1737        }
1738      }
1739    }
1740  }
1741}
1742
1743multiclass VPseudoVPOP_M {
1744  foreach mti = AllMasks in
1745  {
1746    let VLMul = mti.LMul.value in {
1747      def "_M_" # mti.BX : VPseudoUnaryNoMask<GPR, VR>,
1748                           Sched<[WriteVMPopV, ReadVMPopV, ReadVMPopV]>;
1749      def "_M_" # mti.BX # "_MASK" : VPseudoMaskUnarySOutMask,
1750                                     Sched<[WriteVMPopV, ReadVMPopV, ReadVMPopV]>;
1751    }
1752  }
1753}
1754
1755multiclass VPseudoV1ST_M {
1756  foreach mti = AllMasks in
1757  {
1758    let VLMul = mti.LMul.value in {
1759      def "_M_" # mti.BX : VPseudoUnaryNoMask<GPR, VR>,
1760                           Sched<[WriteVMFFSV, ReadVMFFSV, ReadVMFFSV]>;
1761      def "_M_" # mti.BX # "_MASK" : VPseudoMaskUnarySOutMask,
1762                                     Sched<[WriteVMFFSV, ReadVMFFSV, ReadVMFFSV]>;
1763    }
1764  }
1765}
1766
1767multiclass VPseudoVSFS_M {
1768  defvar constraint = "@earlyclobber $rd";
1769  foreach mti = AllMasks in
1770  {
1771    let VLMul = mti.LMul.value in {
1772      def "_M_" # mti.BX : VPseudoUnaryNoMask<VR, VR, constraint>,
1773                           Sched<[WriteVMSFSV, ReadVMSFSV, ReadVMask]>;
1774      def "_M_" # mti.BX # "_MASK" : VPseudoUnaryMask<VR, VR, constraint>,
1775                                     Sched<[WriteVMSFSV, ReadVMSFSV, ReadVMask]>;
1776    }
1777  }
1778}
1779
1780multiclass VPseudoVID_V {
1781  foreach m = MxList in {
1782    let VLMul = m.value in {
1783      def "_V_" # m.MX : VPseudoNullaryNoMask<m.vrclass>,
1784                         Sched<[WriteVMIdxV, ReadVMask]>;
1785      def "_V_" # m.MX # "_TU": VPseudoNullaryNoMaskTU<m.vrclass>,
1786                                Sched<[WriteVMIdxV, ReadVMask]>;
1787      def "_V_" # m.MX # "_MASK" : VPseudoNullaryMask<m.vrclass>,
1788                                   Sched<[WriteVMIdxV, ReadVMask]>;
1789    }
1790  }
1791}
1792
1793multiclass VPseudoNullaryPseudoM <string BaseInst> {
1794  foreach mti = AllMasks in {
1795    let VLMul = mti.LMul.value in {
1796      def "_M_" # mti.BX : VPseudoNullaryPseudoM<BaseInst # "_MM">;
1797    }
1798  }
1799}
1800
1801multiclass VPseudoVIOT_M {
1802  defvar constraint = "@earlyclobber $rd";
1803  foreach m = MxList in {
1804    let VLMul = m.value in {
1805      def "_" # m.MX : VPseudoUnaryNoMask<m.vrclass, VR, constraint>,
1806                       Sched<[WriteVMIotV, ReadVMIotV, ReadVMask]>;
1807      def "_" # m.MX # "_TU" : VPseudoUnaryNoMaskTU<m.vrclass, VR, constraint>,
1808                               Sched<[WriteVMIotV, ReadVMIotV, ReadVMask]>;
1809      def "_" # m.MX # "_MASK" : VPseudoUnaryMaskTA<m.vrclass, VR, constraint>,
1810                                 Sched<[WriteVMIotV, ReadVMIotV, ReadVMask]>;
1811    }
1812  }
1813}
1814
1815multiclass VPseudoVCPR_V {
1816  foreach m = MxList in {
1817    let VLMul = m.value in
1818      def _VM # "_" # m.MX : VPseudoUnaryAnyMask<m.vrclass, m.vrclass>,
1819                             Sched<[WriteVCompressV, ReadVCompressV, ReadVCompressV]>;
1820  }
1821}
1822
1823multiclass VPseudoBinary<VReg RetClass,
1824                         VReg Op1Class,
1825                         DAGOperand Op2Class,
1826                         LMULInfo MInfo,
1827                         string Constraint = ""> {
1828  let VLMul = MInfo.value in {
1829    def "_" # MInfo.MX : VPseudoBinaryNoMask<RetClass, Op1Class, Op2Class,
1830                                             Constraint>;
1831    def "_" # MInfo.MX # "_TU" : VPseudoBinaryNoMaskTU<RetClass, Op1Class, Op2Class,
1832                                                       Constraint>;
1833    def "_" # MInfo.MX # "_MASK" : VPseudoBinaryMaskPolicy<RetClass, Op1Class, Op2Class,
1834                                                           Constraint>,
1835                                   RISCVMaskedPseudo</*MaskOpIdx*/ 3>;
1836  }
1837}
1838
1839multiclass VPseudoBinaryM<VReg RetClass,
1840                          VReg Op1Class,
1841                          DAGOperand Op2Class,
1842                          LMULInfo MInfo,
1843                          string Constraint = ""> {
1844  let VLMul = MInfo.value in {
1845    def "_" # MInfo.MX : VPseudoBinaryNoMask<RetClass, Op1Class, Op2Class,
1846                                             Constraint>;
1847    let ForceTailAgnostic = true in
1848    def "_" # MInfo.MX # "_MASK" : VPseudoBinaryMOutMask<RetClass, Op1Class,
1849                                                         Op2Class, Constraint>,
1850                                   RISCVMaskedPseudo</*MaskOpIdx*/ 3, /*HasTU*/ false>;
1851  }
1852}
1853
1854multiclass VPseudoBinaryEmul<VReg RetClass,
1855                             VReg Op1Class,
1856                             DAGOperand Op2Class,
1857                             LMULInfo lmul,
1858                             LMULInfo emul,
1859                             string Constraint = ""> {
1860  let VLMul = lmul.value in {
1861    def "_" # lmul.MX # "_" # emul.MX : VPseudoBinaryNoMask<RetClass, Op1Class, Op2Class,
1862                                                            Constraint>;
1863    def "_" # lmul.MX # "_" # emul.MX # "_TU": VPseudoBinaryNoMaskTU<RetClass, Op1Class, Op2Class,
1864                                                                     Constraint>;
1865    def "_" # lmul.MX # "_" # emul.MX # "_MASK" : VPseudoBinaryMaskPolicy<RetClass, Op1Class, Op2Class,
1866                                                                          Constraint>,
1867                                                  RISCVMaskedPseudo</*MaskOpIdx*/ 3>;
1868  }
1869}
1870
1871multiclass VPseudoTiedBinary<VReg RetClass,
1872                             DAGOperand Op2Class,
1873                             LMULInfo MInfo,
1874                             string Constraint = ""> {
1875  let VLMul = MInfo.value in {
1876    def "_" # MInfo.MX # "_TIED": VPseudoTiedBinaryNoMask<RetClass, Op2Class,
1877                                                          Constraint>;
1878    def "_" # MInfo.MX # "_MASK_TIED" : VPseudoTiedBinaryMask<RetClass, Op2Class,
1879                                                         Constraint>;
1880  }
1881}
1882
1883multiclass VPseudoBinaryV_VV<string Constraint = ""> {
1884  foreach m = MxList in
1885    defm _VV : VPseudoBinary<m.vrclass, m.vrclass, m.vrclass, m, Constraint>;
1886}
1887
1888// Similar to VPseudoBinaryV_VV, but uses MxListF.
1889multiclass VPseudoBinaryFV_VV<string Constraint = ""> {
1890  foreach m = MxListF in
1891    defm _VV : VPseudoBinary<m.vrclass, m.vrclass, m.vrclass, m, Constraint>;
1892}
1893
1894multiclass VPseudoVGTR_VV_EEW<int eew, string Constraint = ""> {
1895  foreach m = MxList in {
1896    foreach sew = EEWList in {
1897      defvar octuple_lmul = m.octuple;
1898      // emul = lmul * eew / sew
1899      defvar octuple_emul = !srl(!mul(octuple_lmul, eew), log2<sew>.val);
1900      if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then {
1901        defvar emulMX = octuple_to_str<octuple_emul>.ret;
1902        defvar emul = !cast<LMULInfo>("V_" # emulMX);
1903        defm _VV : VPseudoBinaryEmul<m.vrclass, m.vrclass, emul.vrclass, m, emul, Constraint>,
1904                   Sched<[WriteVGatherV, ReadVGatherV, ReadVGatherV]>;
1905      }
1906    }
1907  }
1908}
1909
1910multiclass VPseudoBinaryV_VX<string Constraint = ""> {
1911  foreach m = MxList in
1912    defm "_VX" : VPseudoBinary<m.vrclass, m.vrclass, GPR, m, Constraint>;
1913}
1914
1915multiclass VPseudoVSLD1_VX<string Constraint = ""> {
1916  foreach m = MxList in
1917    defm "_VX" : VPseudoBinary<m.vrclass, m.vrclass, GPR, m, Constraint>,
1918                 Sched<[WriteVISlide1X, ReadVISlideV, ReadVISlideX, ReadVMask]>;
1919}
1920
1921multiclass VPseudoBinaryV_VF<string Constraint = ""> {
1922  foreach f = FPList in
1923    foreach m = f.MxList in
1924      defm "_V" # f.FX : VPseudoBinary<m.vrclass, m.vrclass,
1925                                       f.fprclass, m, Constraint>;
1926}
1927
1928multiclass VPseudoVSLD1_VF<string Constraint = ""> {
1929  foreach f = FPList in
1930    foreach m = f.MxList in
1931      defm "_V" # f.FX :
1932        VPseudoBinary<m.vrclass, m.vrclass, f.fprclass, m, Constraint>,
1933        Sched<[WriteVFSlide1F, ReadVFSlideV, ReadVFSlideF, ReadVMask]>;
1934}
1935
1936multiclass VPseudoBinaryV_VI<Operand ImmType = simm5, string Constraint = ""> {
1937  foreach m = MxList in
1938    defm _VI : VPseudoBinary<m.vrclass, m.vrclass, ImmType, m, Constraint>;
1939}
1940
1941multiclass VPseudoVALU_MM {
1942  foreach m = MxList in
1943    let VLMul = m.value in {
1944      def "_MM_" # m.MX : VPseudoBinaryNoMask<VR, VR, VR, "", /*DummyMask*/0>,
1945                          Sched<[WriteVMALUV, ReadVMALUV, ReadVMALUV]>;
1946    }
1947}
1948
1949// We use earlyclobber here due to
1950// * The destination EEW is smaller than the source EEW and the overlap is
1951//   in the lowest-numbered part of the source register group is legal.
1952//   Otherwise, it is illegal.
1953// * The destination EEW is greater than the source EEW, the source EMUL is
1954//   at least 1, and the overlap is in the highest-numbered part of the
1955//   destination register group is legal. Otherwise, it is illegal.
1956multiclass VPseudoBinaryW_VV<list<LMULInfo> mxlist = MxListW> {
1957  foreach m = mxlist in
1958    defm _VV : VPseudoBinary<m.wvrclass, m.vrclass, m.vrclass, m,
1959                             "@earlyclobber $rd">;
1960}
1961
1962multiclass VPseudoBinaryW_VX {
1963  foreach m = MxListW in
1964    defm "_VX" : VPseudoBinary<m.wvrclass, m.vrclass, GPR, m,
1965                               "@earlyclobber $rd">;
1966}
1967
1968multiclass VPseudoBinaryW_VF {
1969  foreach f = FPListW in
1970    foreach m = f.MxList in
1971      defm "_V" # f.FX : VPseudoBinary<m.wvrclass, m.vrclass,
1972                                       f.fprclass, m,
1973                                       "@earlyclobber $rd">;
1974}
1975
1976multiclass VPseudoBinaryW_WV<list<LMULInfo> mxlist = MxListW> {
1977  foreach m = mxlist in {
1978    defm _WV : VPseudoBinary<m.wvrclass, m.wvrclass, m.vrclass, m,
1979                             "@earlyclobber $rd">;
1980    defm _WV : VPseudoTiedBinary<m.wvrclass, m.vrclass, m,
1981                                 "@earlyclobber $rd">;
1982  }
1983}
1984
1985multiclass VPseudoBinaryW_WX {
1986  foreach m = MxListW in
1987    defm "_WX" : VPseudoBinary<m.wvrclass, m.wvrclass, GPR, m>;
1988}
1989
1990multiclass VPseudoBinaryW_WF {
1991  foreach f = FPListW in
1992    foreach m = f.MxList in
1993      defm "_W" # f.FX : VPseudoBinary<m.wvrclass, m.wvrclass,
1994                                       f.fprclass, m>;
1995}
1996
1997// Narrowing instructions like vnsrl/vnsra/vnclip(u) don't need @earlyclobber
1998// if the source and destination have an LMUL<=1. This matches this overlap
1999// exception from the spec.
2000// "The destination EEW is smaller than the source EEW and the overlap is in the
2001//  lowest-numbered part of the source register group."
2002multiclass VPseudoBinaryV_WV {
2003  foreach m = MxListW in
2004    defm _WV : VPseudoBinary<m.vrclass, m.wvrclass, m.vrclass, m,
2005                             !if(!ge(m.octuple, 8), "@earlyclobber $rd", "")>;
2006}
2007
2008multiclass VPseudoBinaryV_WX {
2009  foreach m = MxListW in
2010    defm _WX : VPseudoBinary<m.vrclass, m.wvrclass, GPR, m,
2011                             !if(!ge(m.octuple, 8), "@earlyclobber $rd", "")>;
2012}
2013
2014multiclass VPseudoBinaryV_WI {
2015  foreach m = MxListW in
2016    defm _WI : VPseudoBinary<m.vrclass, m.wvrclass, uimm5, m,
2017                             !if(!ge(m.octuple, 8), "@earlyclobber $rd", "")>;
2018}
2019
2020// For vadc and vsbc, the instruction encoding is reserved if the destination
2021// vector register is v0.
2022// For vadc and vsbc, CarryIn == 1 and CarryOut == 0
2023multiclass VPseudoBinaryV_VM<bit CarryOut = 0, bit CarryIn = 1,
2024                             string Constraint = ""> {
2025  foreach m = MxList in
2026    def "_VV" # !if(CarryIn, "M", "") # "_" # m.MX :
2027      VPseudoBinaryCarryIn<!if(CarryOut, VR,
2028                           !if(!and(CarryIn, !not(CarryOut)),
2029                               GetVRegNoV0<m.vrclass>.R, m.vrclass)),
2030                           m.vrclass, m.vrclass, m, CarryIn, Constraint>;
2031}
2032
2033multiclass VPseudoTiedBinaryV_VM<bit CarryOut = 0, bit CarryIn = 1,
2034                                 string Constraint = ""> {
2035  foreach m = MxList in
2036    def "_VV" # !if(CarryIn, "M", "") # "_" # m.MX # "_TU" :
2037      VPseudoTiedBinaryCarryIn<!if(CarryOut, VR,
2038                               !if(!and(CarryIn, !not(CarryOut)),
2039                                   GetVRegNoV0<m.vrclass>.R, m.vrclass)),
2040                               m.vrclass, m.vrclass, m, CarryIn, Constraint>;
2041}
2042
2043multiclass VPseudoBinaryV_XM<bit CarryOut = 0, bit CarryIn = 1,
2044                             string Constraint = ""> {
2045  foreach m = MxList in
2046    def "_VX" # !if(CarryIn, "M", "") # "_" # m.MX :
2047      VPseudoBinaryCarryIn<!if(CarryOut, VR,
2048                           !if(!and(CarryIn, !not(CarryOut)),
2049                               GetVRegNoV0<m.vrclass>.R, m.vrclass)),
2050                           m.vrclass, GPR, m, CarryIn, Constraint>;
2051}
2052
2053multiclass VPseudoTiedBinaryV_XM<bit CarryOut = 0, bit CarryIn = 1,
2054                                 string Constraint = ""> {
2055  foreach m = MxList in
2056    def "_VX" # !if(CarryIn, "M", "") # "_" # m.MX # "_TU":
2057      VPseudoTiedBinaryCarryIn<!if(CarryOut, VR,
2058                               !if(!and(CarryIn, !not(CarryOut)),
2059                                   GetVRegNoV0<m.vrclass>.R, m.vrclass)),
2060                               m.vrclass, GPR, m, CarryIn, Constraint>;
2061}
2062
2063multiclass VPseudoVMRG_FM {
2064  foreach f = FPList in
2065    foreach m = f.MxList in {
2066      def "_V" # f.FX # "M_" # m.MX :
2067        VPseudoBinaryCarryIn<GetVRegNoV0<m.vrclass>.R,
2068                             m.vrclass, f.fprclass, m, /*CarryIn=*/1, "">,
2069        Sched<[WriteVFMergeV, ReadVFMergeV, ReadVFMergeF, ReadVMask]>;
2070      // Tied version to allow codegen control over the tail elements
2071      def "_V" # f.FX # "M_" # m.MX # "_TU":
2072        VPseudoTiedBinaryCarryIn<GetVRegNoV0<m.vrclass>.R,
2073                                 m.vrclass, f.fprclass, m, /*CarryIn=*/1, "">,
2074        Sched<[WriteVFMergeV, ReadVFMergeV, ReadVFMergeF, ReadVMask]>;
2075    }
2076}
2077
2078multiclass VPseudoBinaryV_IM<bit CarryOut = 0, bit CarryIn = 1,
2079                             string Constraint = ""> {
2080  foreach m = MxList in
2081    def "_VI" # !if(CarryIn, "M", "") # "_" # m.MX :
2082      VPseudoBinaryCarryIn<!if(CarryOut, VR,
2083                           !if(!and(CarryIn, !not(CarryOut)),
2084                               GetVRegNoV0<m.vrclass>.R, m.vrclass)),
2085                           m.vrclass, simm5, m, CarryIn, Constraint>;
2086}
2087
2088multiclass VPseudoTiedBinaryV_IM<bit CarryOut = 0, bit CarryIn = 1,
2089                                 string Constraint = ""> {
2090  foreach m = MxList in
2091    def "_VI" # !if(CarryIn, "M", "") # "_" # m.MX # "_TU":
2092      VPseudoTiedBinaryCarryIn<!if(CarryOut, VR,
2093                               !if(!and(CarryIn, !not(CarryOut)),
2094                                   GetVRegNoV0<m.vrclass>.R, m.vrclass)),
2095                               m.vrclass, simm5, m, CarryIn, Constraint>;
2096}
2097
2098multiclass VPseudoUnaryVMV_V_X_I {
2099  foreach m = MxList in {
2100    let VLMul = m.value in {
2101      def "_V_" # m.MX : VPseudoUnaryNoDummyMask<m.vrclass, m.vrclass>,
2102                         Sched<[WriteVIMovV, ReadVIMovV]>;
2103      def "_X_" # m.MX : VPseudoUnaryNoDummyMask<m.vrclass, GPR>,
2104                         Sched<[WriteVIMovX, ReadVIMovX]>;
2105      def "_I_" # m.MX : VPseudoUnaryNoDummyMask<m.vrclass, simm5>,
2106                         Sched<[WriteVIMovI]>;
2107      def "_V_" # m.MX # "_TU": VPseudoUnaryNoDummyMaskTU<m.vrclass, m.vrclass>,
2108                         Sched<[WriteVIMovV, ReadVIMovV]>;
2109      def "_X_" # m.MX # "_TU": VPseudoUnaryNoDummyMaskTU<m.vrclass, GPR>,
2110                         Sched<[WriteVIMovX, ReadVIMovX]>;
2111      def "_I_" # m.MX # "_TU": VPseudoUnaryNoDummyMaskTU<m.vrclass, simm5>,
2112                         Sched<[WriteVIMovI]>;
2113    }
2114  }
2115}
2116
2117multiclass VPseudoVMV_F {
2118  foreach f = FPList in {
2119    foreach m = f.MxList in {
2120      let VLMul = m.value in {
2121        def "_" # f.FX # "_" # m.MX :
2122          VPseudoUnaryNoDummyMask<m.vrclass, f.fprclass>,
2123          Sched<[WriteVFMovV, ReadVFMovF]>;
2124        def "_" # f.FX # "_" # m.MX # "_TU":
2125          VPseudoUnaryNoDummyMaskTU<m.vrclass, f.fprclass>,
2126          Sched<[WriteVFMovV, ReadVFMovF]>;
2127      }
2128    }
2129  }
2130}
2131
2132multiclass VPseudoVCLS_V {
2133  foreach m = MxListF in {
2134    let VLMul = m.value in {
2135      def "_V_" # m.MX : VPseudoUnaryNoMask<m.vrclass, m.vrclass>,
2136                         Sched<[WriteVFClassV, ReadVFClassV, ReadVMask]>;
2137      def "_V_" # m.MX # "_TU": VPseudoUnaryNoMaskTU<m.vrclass, m.vrclass>,
2138                                Sched<[WriteVFClassV, ReadVFClassV, ReadVMask]>;
2139      def "_V_" # m.MX # "_MASK" : VPseudoUnaryMaskTA<m.vrclass, m.vrclass>,
2140                                   Sched<[WriteVFClassV, ReadVFClassV, ReadVMask]>;
2141    }
2142  }
2143}
2144
2145multiclass VPseudoVSQR_V {
2146  foreach m = MxListF in {
2147    let VLMul = m.value in {
2148      def "_V_" # m.MX : VPseudoUnaryNoMask<m.vrclass, m.vrclass>,
2149                         Sched<[WriteVFSqrtV, ReadVFSqrtV, ReadVMask]>;
2150      def "_V_" # m.MX # "_TU": VPseudoUnaryNoMaskTU<m.vrclass, m.vrclass>,
2151                                Sched<[WriteVFSqrtV, ReadVFSqrtV, ReadVMask]>;
2152      def "_V_" # m.MX # "_MASK" : VPseudoUnaryMaskTA<m.vrclass, m.vrclass>,
2153                                   Sched<[WriteVFSqrtV, ReadVFSqrtV, ReadVMask]>;
2154    }
2155  }
2156}
2157
2158multiclass VPseudoVRCP_V {
2159  foreach m = MxListF in {
2160    let VLMul = m.value in {
2161      def "_V_" # m.MX : VPseudoUnaryNoMask<m.vrclass, m.vrclass>,
2162                         Sched<[WriteVFRecpV, ReadVFRecpV, ReadVMask]>;
2163      def "_V_" # m.MX # "_TU": VPseudoUnaryNoMaskTU<m.vrclass, m.vrclass>,
2164                                Sched<[WriteVFRecpV, ReadVFRecpV, ReadVMask]>;
2165      def "_V_" # m.MX # "_MASK" : VPseudoUnaryMaskTA<m.vrclass, m.vrclass>,
2166                                   Sched<[WriteVFRecpV, ReadVFRecpV, ReadVMask]>;
2167    }
2168  }
2169}
2170
2171multiclass PseudoVEXT_VF2 {
2172  defvar constraints = "@earlyclobber $rd";
2173  foreach m = MxListVF2 in
2174  {
2175    let VLMul = m.value in {
2176      def "_" # m.MX : VPseudoUnaryNoMask<m.vrclass, m.f2vrclass, constraints>,
2177                       Sched<[WriteVExtV, ReadVExtV, ReadVMask]>;
2178      def "_" # m.MX # "_TU": VPseudoUnaryNoMaskTU<m.vrclass, m.f2vrclass, constraints>,
2179                              Sched<[WriteVExtV, ReadVExtV, ReadVMask]>;
2180      def "_" # m.MX # "_MASK" :
2181        VPseudoUnaryMaskTA<m.vrclass, m.f2vrclass, constraints>,
2182        RISCVMaskedPseudo</*MaskOpIdx*/ 2>,
2183        Sched<[WriteVExtV, ReadVExtV, ReadVMask]>;
2184    }
2185  }
2186}
2187
2188multiclass PseudoVEXT_VF4 {
2189  defvar constraints = "@earlyclobber $rd";
2190  foreach m = MxListVF4 in
2191  {
2192    let VLMul = m.value in {
2193      def "_" # m.MX : VPseudoUnaryNoMask<m.vrclass, m.f4vrclass, constraints>,
2194                       Sched<[WriteVExtV, ReadVExtV, ReadVMask]>;
2195      def "_" # m.MX # "_TU": VPseudoUnaryNoMaskTU<m.vrclass, m.f4vrclass, constraints>,
2196                              Sched<[WriteVExtV, ReadVExtV, ReadVMask]>;
2197      def "_" # m.MX # "_MASK" :
2198        VPseudoUnaryMaskTA<m.vrclass, m.f4vrclass, constraints>,
2199        RISCVMaskedPseudo</*MaskOpIdx*/ 2>,
2200        Sched<[WriteVExtV, ReadVExtV, ReadVMask]>;
2201    }
2202  }
2203}
2204
2205multiclass PseudoVEXT_VF8 {
2206  defvar constraints = "@earlyclobber $rd";
2207  foreach m = MxListVF8 in
2208  {
2209    let VLMul = m.value in {
2210      def "_" # m.MX : VPseudoUnaryNoMask<m.vrclass, m.f8vrclass, constraints>,
2211                       Sched<[WriteVExtV, ReadVExtV, ReadVMask]>;
2212      def "_" # m.MX # "_TU": VPseudoUnaryNoMaskTU<m.vrclass, m.f8vrclass, constraints>,
2213                              Sched<[WriteVExtV, ReadVExtV, ReadVMask]>;
2214      def "_" # m.MX # "_MASK" :
2215        VPseudoUnaryMaskTA<m.vrclass, m.f8vrclass, constraints>,
2216        RISCVMaskedPseudo</*MaskOpIdx*/ 2>,
2217        Sched<[WriteVExtV, ReadVExtV, ReadVMask]>;
2218    }
2219  }
2220}
2221
2222// The destination EEW is 1 since "For the purposes of register group overlap
2223// constraints, mask elements have EEW=1."
2224// The source EEW is 8, 16, 32, or 64.
2225// When the destination EEW is different from source EEW, we need to use
2226// @earlyclobber to avoid the overlap between destination and source registers.
2227// We don't need @earlyclobber for LMUL<=1 since that matches this overlap
2228// exception from the spec
2229// "The destination EEW is smaller than the source EEW and the overlap is in the
2230//  lowest-numbered part of the source register group".
2231// With LMUL<=1 the source and dest occupy a single register so any overlap
2232// is in the lowest-numbered part.
2233multiclass VPseudoBinaryM_VV<list<LMULInfo> mxlist = MxList> {
2234  foreach m = mxlist in
2235    defm _VV : VPseudoBinaryM<VR, m.vrclass, m.vrclass, m,
2236                              !if(!ge(m.octuple, 16), "@earlyclobber $rd", "")>;
2237}
2238
2239multiclass VPseudoBinaryM_VX {
2240  foreach m = MxList in
2241    defm "_VX" :
2242      VPseudoBinaryM<VR, m.vrclass, GPR, m,
2243                     !if(!ge(m.octuple, 16), "@earlyclobber $rd", "")>;
2244}
2245
2246multiclass VPseudoBinaryM_VF {
2247  foreach f = FPList in
2248    foreach m = f.MxList in
2249      defm "_V" # f.FX :
2250        VPseudoBinaryM<VR, m.vrclass, f.fprclass, m,
2251                       !if(!ge(m.octuple, 16), "@earlyclobber $rd", "")>;
2252}
2253
2254multiclass VPseudoBinaryM_VI {
2255  foreach m = MxList in
2256    defm _VI : VPseudoBinaryM<VR, m.vrclass, simm5, m,
2257                              !if(!ge(m.octuple, 16), "@earlyclobber $rd", "")>;
2258}
2259
2260multiclass VPseudoVGTR_VV_VX_VI<Operand ImmType = simm5, string Constraint = ""> {
2261  defm "" : VPseudoBinaryV_VV<Constraint>,
2262            Sched<[WriteVGatherV, ReadVGatherV, ReadVGatherV, ReadVMask]>;
2263  defm "" : VPseudoBinaryV_VX<Constraint>,
2264            Sched<[WriteVGatherX, ReadVGatherV, ReadVGatherX, ReadVMask]>;
2265  defm "" : VPseudoBinaryV_VI<ImmType, Constraint>,
2266            Sched<[WriteVGatherI, ReadVGatherV, ReadVMask]>;
2267}
2268
2269multiclass VPseudoVSALU_VV_VX_VI<Operand ImmType = simm5, string Constraint = ""> {
2270  defm "" : VPseudoBinaryV_VV<Constraint>,
2271            Sched<[WriteVSALUV, ReadVSALUV, ReadVSALUV, ReadVMask]>;
2272  defm "" : VPseudoBinaryV_VX<Constraint>,
2273            Sched<[WriteVSALUX, ReadVSALUV, ReadVSALUX, ReadVMask]>;
2274  defm "" : VPseudoBinaryV_VI<ImmType, Constraint>,
2275            Sched<[WriteVSALUI, ReadVSALUV, ReadVMask]>;
2276}
2277
2278
2279multiclass VPseudoVSHT_VV_VX_VI<Operand ImmType = simm5, string Constraint = ""> {
2280  defm "" : VPseudoBinaryV_VV<Constraint>,
2281            Sched<[WriteVShiftV, ReadVShiftV, ReadVShiftV, ReadVMask]>;
2282  defm "" : VPseudoBinaryV_VX<Constraint>,
2283            Sched<[WriteVShiftX, ReadVShiftV, ReadVShiftX, ReadVMask]>;
2284  defm "" : VPseudoBinaryV_VI<ImmType, Constraint>,
2285            Sched<[WriteVShiftI, ReadVShiftV, ReadVMask]>;
2286}
2287
2288multiclass VPseudoVSSHT_VV_VX_VI<Operand ImmType = simm5, string Constraint = ""> {
2289  defm "" : VPseudoBinaryV_VV<Constraint>,
2290            Sched<[WriteVSShiftV, ReadVSShiftV, ReadVSShiftV, ReadVMask]>;
2291  defm "" : VPseudoBinaryV_VX<Constraint>,
2292            Sched<[WriteVSShiftX, ReadVSShiftV, ReadVSShiftX, ReadVMask]>;
2293  defm "" : VPseudoBinaryV_VI<ImmType, Constraint>,
2294            Sched<[WriteVSShiftI, ReadVSShiftV, ReadVMask]>;
2295}
2296
2297multiclass VPseudoVALU_VV_VX_VI<Operand ImmType = simm5, string Constraint = ""> {
2298  defm "" : VPseudoBinaryV_VV<Constraint>,
2299            Sched<[WriteVIALUV, ReadVIALUV, ReadVIALUV, ReadVMask]>;
2300  defm "" : VPseudoBinaryV_VX<Constraint>,
2301            Sched<[WriteVIALUX, ReadVIALUV, ReadVIALUX, ReadVMask]>;
2302  defm "" : VPseudoBinaryV_VI<ImmType, Constraint>,
2303            Sched<[WriteVIALUI, ReadVIALUV, ReadVMask]>;
2304}
2305
2306multiclass VPseudoVSALU_VV_VX {
2307  defm "" : VPseudoBinaryV_VV,
2308            Sched<[WriteVSALUV, ReadVSALUV, ReadVSALUV, ReadVMask]>;
2309  defm "" : VPseudoBinaryV_VX,
2310            Sched<[WriteVSALUX, ReadVSALUV, ReadVSALUX, ReadVMask]>;
2311}
2312
2313multiclass VPseudoVSMUL_VV_VX {
2314  defm "" : VPseudoBinaryV_VV,
2315            Sched<[WriteVSMulV, ReadVSMulV, ReadVSMulV, ReadVMask]>;
2316  defm "" : VPseudoBinaryV_VX,
2317            Sched<[WriteVSMulX, ReadVSMulV, ReadVSMulX, ReadVMask]>;
2318}
2319
2320multiclass VPseudoVAALU_VV_VX {
2321  defm "" : VPseudoBinaryV_VV,
2322            Sched<[WriteVAALUV, ReadVAALUV, ReadVAALUV, ReadVMask]>;
2323  defm "" : VPseudoBinaryV_VX,
2324            Sched<[WriteVAALUX, ReadVAALUV, ReadVAALUX, ReadVMask]>;
2325}
2326
2327multiclass VPseudoVMINMAX_VV_VX {
2328  defm "" : VPseudoBinaryV_VV,
2329            Sched<[WriteVICmpV, ReadVICmpV, ReadVICmpV, ReadVMask]>;
2330  defm "" : VPseudoBinaryV_VX,
2331            Sched<[WriteVICmpX, ReadVICmpV, ReadVICmpX, ReadVMask]>;
2332}
2333
2334multiclass VPseudoVMUL_VV_VX {
2335  defm "" : VPseudoBinaryV_VV,
2336            Sched<[WriteVIMulV, ReadVIMulV, ReadVIMulV, ReadVMask]>;
2337  defm "" : VPseudoBinaryV_VX,
2338            Sched<[WriteVIMulX, ReadVIMulV, ReadVIMulX, ReadVMask]>;
2339}
2340
2341multiclass VPseudoVDIV_VV_VX {
2342  defm "" : VPseudoBinaryV_VV,
2343            Sched<[WriteVIDivV, ReadVIDivV, ReadVIDivV, ReadVMask]>;
2344  defm "" : VPseudoBinaryV_VX,
2345            Sched<[WriteVIDivX, ReadVIDivV, ReadVIDivX, ReadVMask]>;
2346}
2347
2348multiclass VPseudoVFMUL_VV_VF {
2349  defm "" : VPseudoBinaryFV_VV,
2350            Sched<[WriteVFMulV, ReadVFMulV, ReadVFMulV, ReadVMask]>;
2351  defm "" : VPseudoBinaryV_VF,
2352            Sched<[WriteVFMulF, ReadVFMulV, ReadVFMulF, ReadVMask]>;
2353}
2354
2355multiclass VPseudoVFDIV_VV_VF {
2356  defm "" : VPseudoBinaryFV_VV,
2357            Sched<[WriteVFDivV, ReadVFDivV, ReadVFDivV, ReadVMask]>;
2358  defm "" : VPseudoBinaryV_VF,
2359            Sched<[WriteVFDivF, ReadVFDivV, ReadVFDivF, ReadVMask]>;
2360}
2361
2362multiclass VPseudoVFRDIV_VF {
2363  defm "" : VPseudoBinaryV_VF,
2364            Sched<[WriteVFDivF, ReadVFDivV, ReadVFDivF, ReadVMask]>;
2365}
2366
2367multiclass VPseudoVALU_VV_VX {
2368  defm "" : VPseudoBinaryV_VV,
2369            Sched<[WriteVIALUV, ReadVIALUV, ReadVIALUV, ReadVMask]>;
2370  defm "" : VPseudoBinaryV_VX,
2371            Sched<[WriteVIALUX, ReadVIALUV, ReadVIALUX, ReadVMask]>;
2372}
2373
2374multiclass VPseudoVSGNJ_VV_VF {
2375  defm "" : VPseudoBinaryFV_VV,
2376            Sched<[WriteVFSgnjV, ReadVFSgnjV, ReadVFSgnjV, ReadVMask]>;
2377  defm "" : VPseudoBinaryV_VF,
2378            Sched<[WriteVFSgnjF, ReadVFSgnjV, ReadVFSgnjF, ReadVMask]>;
2379}
2380
2381multiclass VPseudoVMAX_VV_VF {
2382  defm "" : VPseudoBinaryFV_VV,
2383            Sched<[WriteVFCmpV, ReadVFCmpV, ReadVFCmpV, ReadVMask]>;
2384  defm "" : VPseudoBinaryV_VF,
2385            Sched<[WriteVFCmpF, ReadVFCmpV, ReadVFCmpF, ReadVMask]>;
2386}
2387
2388multiclass VPseudoVALU_VV_VF {
2389  defm "" : VPseudoBinaryFV_VV,
2390            Sched<[WriteVFALUV, ReadVFALUV, ReadVFALUV, ReadVMask]>;
2391  defm "" : VPseudoBinaryV_VF,
2392            Sched<[WriteVFALUF, ReadVFALUV, ReadVFALUF, ReadVMask]>;
2393}
2394
2395multiclass VPseudoVALU_VF {
2396  defm "" : VPseudoBinaryV_VF,
2397            Sched<[WriteVFALUF, ReadVFALUV, ReadVFALUF, ReadVMask]>;
2398}
2399
2400multiclass VPseudoVALU_VX_VI<Operand ImmType = simm5> {
2401  defm "" : VPseudoBinaryV_VX,
2402            Sched<[WriteVIALUX, ReadVIALUV, ReadVIALUX, ReadVMask]>;
2403  defm "" : VPseudoBinaryV_VI<ImmType>,
2404            Sched<[WriteVIALUI, ReadVIALUV, ReadVMask]>;
2405}
2406
2407multiclass VPseudoVWALU_VV_VX {
2408  defm "" : VPseudoBinaryW_VV,
2409            Sched<[WriteVIWALUV, ReadVIWALUV, ReadVIWALUV, ReadVMask]>;
2410  defm "" : VPseudoBinaryW_VX,
2411            Sched<[WriteVIWALUX, ReadVIWALUV, ReadVIWALUX, ReadVMask]>;
2412}
2413
2414multiclass VPseudoVWMUL_VV_VX {
2415  defm "" : VPseudoBinaryW_VV,
2416            Sched<[WriteVIWMulV, ReadVIWMulV, ReadVIWMulV, ReadVMask]>;
2417  defm "" : VPseudoBinaryW_VX,
2418            Sched<[WriteVIWMulX, ReadVIWMulV, ReadVIWMulX, ReadVMask]>;
2419}
2420
2421multiclass VPseudoVWMUL_VV_VF {
2422  defm "" : VPseudoBinaryW_VV<MxListFW>,
2423            Sched<[WriteVFWMulV, ReadVFWMulV, ReadVFWMulV, ReadVMask]>;
2424  defm "" : VPseudoBinaryW_VF,
2425            Sched<[WriteVFWMulF, ReadVFWMulV, ReadVFWMulF, ReadVMask]>;
2426}
2427
2428multiclass VPseudoVWALU_WV_WX {
2429  defm "" : VPseudoBinaryW_WV,
2430            Sched<[WriteVIWALUV, ReadVIWALUV, ReadVIWALUV, ReadVMask]>;
2431  defm "" : VPseudoBinaryW_WX,
2432            Sched<[WriteVIWALUX, ReadVIWALUV, ReadVIWALUX, ReadVMask]>;
2433}
2434
2435multiclass VPseudoVFWALU_VV_VF {
2436  defm "" : VPseudoBinaryW_VV<MxListFW>,
2437            Sched<[WriteVFWALUV, ReadVFWALUV, ReadVFWALUV, ReadVMask]>;
2438  defm "" : VPseudoBinaryW_VF,
2439            Sched<[WriteVFWALUF, ReadVFWALUV, ReadVFWALUF, ReadVMask]>;
2440}
2441
2442multiclass VPseudoVFWALU_WV_WF {
2443  defm "" : VPseudoBinaryW_WV<MxListFW>,
2444            Sched<[WriteVFWALUV, ReadVFWALUV, ReadVFWALUV, ReadVMask]>;
2445  defm "" : VPseudoBinaryW_WF,
2446            Sched<[WriteVFWALUF, ReadVFWALUV, ReadVFWALUF, ReadVMask]>;
2447}
2448
2449multiclass VPseudoVMRG_VM_XM_IM {
2450  defm "" : VPseudoBinaryV_VM,
2451            Sched<[WriteVIMergeV, ReadVIMergeV, ReadVIMergeV, ReadVMask]>;
2452  defm "" : VPseudoBinaryV_XM,
2453            Sched<[WriteVIMergeX, ReadVIMergeV, ReadVIMergeX, ReadVMask]>;
2454  defm "" : VPseudoBinaryV_IM,
2455            Sched<[WriteVIMergeI, ReadVIMergeV, ReadVMask]>;
2456  // Tied versions to allow codegen control over the tail elements
2457  defm "" : VPseudoTiedBinaryV_VM,
2458            Sched<[WriteVIMergeV, ReadVIMergeV, ReadVIMergeV, ReadVMask]>;
2459  defm "" : VPseudoTiedBinaryV_XM,
2460            Sched<[WriteVIMergeX, ReadVIMergeV, ReadVIMergeX, ReadVMask]>;
2461  defm "" : VPseudoTiedBinaryV_IM,
2462            Sched<[WriteVIMergeI, ReadVIMergeV, ReadVMask]>;
2463}
2464
2465multiclass VPseudoVCALU_VM_XM_IM {
2466  defm "" : VPseudoBinaryV_VM,
2467            Sched<[WriteVICALUV, ReadVIALUCV, ReadVIALUCV, ReadVMask]>;
2468  defm "" : VPseudoBinaryV_XM,
2469            Sched<[WriteVICALUX, ReadVIALUCV, ReadVIALUCX, ReadVMask]>;
2470  defm "" : VPseudoBinaryV_IM,
2471            Sched<[WriteVICALUI, ReadVIALUCV, ReadVMask]>;
2472  // Tied versions to allow codegen control over the tail elements
2473  defm "" : VPseudoTiedBinaryV_VM,
2474            Sched<[WriteVICALUV, ReadVIALUCV, ReadVIALUCV, ReadVMask]>;
2475  defm "" : VPseudoTiedBinaryV_XM,
2476            Sched<[WriteVICALUX, ReadVIALUCV, ReadVIALUCX, ReadVMask]>;
2477  defm "" : VPseudoTiedBinaryV_IM,
2478            Sched<[WriteVICALUI, ReadVIALUCV, ReadVMask]>;
2479}
2480
2481multiclass VPseudoVCALU_VM_XM {
2482  defm "" : VPseudoBinaryV_VM,
2483            Sched<[WriteVICALUV, ReadVIALUCV, ReadVIALUCV, ReadVMask]>;
2484  defm "" : VPseudoBinaryV_XM,
2485            Sched<[WriteVICALUX, ReadVIALUCV, ReadVIALUCX, ReadVMask]>;
2486  // Tied versions to allow codegen control over the tail elements
2487  defm "" : VPseudoTiedBinaryV_VM,
2488            Sched<[WriteVICALUV, ReadVIALUCV, ReadVIALUCV, ReadVMask]>;
2489  defm "" : VPseudoTiedBinaryV_XM,
2490            Sched<[WriteVICALUX, ReadVIALUCV, ReadVIALUCX, ReadVMask]>;
2491}
2492
2493multiclass VPseudoVCALUM_VM_XM_IM<string Constraint> {
2494  defm "" : VPseudoBinaryV_VM</*CarryOut=*/1, /*CarryIn=*/1, Constraint>,
2495            Sched<[WriteVICALUV, ReadVIALUCV, ReadVIALUCV, ReadVMask]>;
2496  defm "" : VPseudoBinaryV_XM</*CarryOut=*/1, /*CarryIn=*/1, Constraint>,
2497            Sched<[WriteVICALUX, ReadVIALUCV, ReadVIALUCX, ReadVMask]>;
2498  defm "" : VPseudoBinaryV_IM</*CarryOut=*/1, /*CarryIn=*/1, Constraint>,
2499            Sched<[WriteVICALUI, ReadVIALUCV, ReadVMask]>;
2500}
2501
2502multiclass VPseudoVCALUM_VM_XM<string Constraint> {
2503  defm "" : VPseudoBinaryV_VM</*CarryOut=*/1, /*CarryIn=*/1, Constraint>,
2504            Sched<[WriteVICALUV, ReadVIALUCV, ReadVIALUCV, ReadVMask]>;
2505  defm "" : VPseudoBinaryV_XM</*CarryOut=*/1, /*CarryIn=*/1, Constraint>,
2506            Sched<[WriteVICALUX, ReadVIALUCV, ReadVIALUCX, ReadVMask]>;
2507}
2508
2509multiclass VPseudoVCALUM_V_X_I<string Constraint> {
2510  defm "" : VPseudoBinaryV_VM</*CarryOut=*/1, /*CarryIn=*/0, Constraint>,
2511            Sched<[WriteVICALUV, ReadVIALUCV, ReadVIALUCV]>;
2512  defm "" : VPseudoBinaryV_XM</*CarryOut=*/1, /*CarryIn=*/0, Constraint>,
2513            Sched<[WriteVICALUX, ReadVIALUCV, ReadVIALUCX]>;
2514  defm "" : VPseudoBinaryV_IM</*CarryOut=*/1, /*CarryIn=*/0, Constraint>,
2515            Sched<[WriteVICALUI, ReadVIALUCV]>;
2516}
2517
2518multiclass VPseudoVCALUM_V_X<string Constraint> {
2519  defm "" : VPseudoBinaryV_VM</*CarryOut=*/1, /*CarryIn=*/0, Constraint>,
2520            Sched<[WriteVICALUV, ReadVIALUCV, ReadVIALUCV]>;
2521  defm "" : VPseudoBinaryV_XM</*CarryOut=*/1, /*CarryIn=*/0, Constraint>,
2522            Sched<[WriteVICALUX, ReadVIALUCV, ReadVIALUCX]>;
2523}
2524
2525multiclass VPseudoVNCLP_WV_WX_WI {
2526  defm "" : VPseudoBinaryV_WV,
2527            Sched<[WriteVNClipV, ReadVNClipV, ReadVNClipV, ReadVMask]>;
2528  defm "" : VPseudoBinaryV_WX,
2529            Sched<[WriteVNClipX, ReadVNClipV, ReadVNClipX, ReadVMask]>;
2530  defm "" : VPseudoBinaryV_WI,
2531            Sched<[WriteVNClipI, ReadVNClipV, ReadVMask]>;
2532}
2533
2534multiclass VPseudoVNSHT_WV_WX_WI {
2535  defm "" : VPseudoBinaryV_WV,
2536            Sched<[WriteVNShiftV, ReadVNShiftV, ReadVNShiftV, ReadVMask]>;
2537  defm "" : VPseudoBinaryV_WX,
2538            Sched<[WriteVNShiftX, ReadVNShiftV, ReadVNShiftX, ReadVMask]>;
2539  defm "" : VPseudoBinaryV_WI,
2540            Sched<[WriteVNShiftI, ReadVNShiftV, ReadVMask]>;
2541}
2542
2543multiclass VPseudoTernary<VReg RetClass,
2544                          RegisterClass Op1Class,
2545                          DAGOperand Op2Class,
2546                          LMULInfo MInfo,
2547                          string Constraint = ""> {
2548  let VLMul = MInfo.value in {
2549    def "_" # MInfo.MX : VPseudoTernaryNoMask<RetClass, Op1Class, Op2Class, Constraint>;
2550    def "_" # MInfo.MX # "_MASK" : VPseudoBinaryMask<RetClass, Op1Class, Op2Class, Constraint>;
2551  }
2552}
2553
2554multiclass VPseudoTernaryNoMaskNoPolicy<VReg RetClass,
2555                                        RegisterClass Op1Class,
2556                                        DAGOperand Op2Class,
2557                                        LMULInfo MInfo,
2558                                        string Constraint = ""> {
2559  let VLMul = MInfo.value in {
2560    def "_" # MInfo.MX : VPseudoTernaryNoMask<RetClass, Op1Class, Op2Class, Constraint>;
2561    def "_" # MInfo.MX # "_MASK" : VPseudoBinaryMaskPolicy<RetClass, Op1Class, Op2Class,
2562                                                           Constraint>;
2563
2564  }
2565}
2566
2567multiclass VPseudoTernaryWithPolicy<VReg RetClass,
2568                                    RegisterClass Op1Class,
2569                                    DAGOperand Op2Class,
2570                                    LMULInfo MInfo,
2571                                    string Constraint = "",
2572                                    bit Commutable = 0> {
2573  let VLMul = MInfo.value in {
2574    let isCommutable = Commutable in
2575    def "_" # MInfo.MX : VPseudoTernaryNoMaskWithPolicy<RetClass, Op1Class, Op2Class, Constraint>;
2576    def "_" # MInfo.MX # "_MASK" : VPseudoBinaryMaskPolicy<RetClass, Op1Class, Op2Class, Constraint>;
2577  }
2578}
2579
2580multiclass VPseudoTernaryV_VV_AAXA<string Constraint = "",
2581                                   list<LMULInfo> mxlist = MxList> {
2582  foreach m = mxlist in {
2583    defm _VV : VPseudoTernaryWithPolicy<m.vrclass, m.vrclass, m.vrclass, m,
2584                                        Constraint, /*Commutable*/1>;
2585  }
2586}
2587
2588multiclass VPseudoVSLDV_VX<string Constraint = ""> {
2589  foreach m = MxList in
2590    defm _VX : VPseudoTernaryWithPolicy<m.vrclass, m.vrclass, GPR, m, Constraint>;
2591}
2592
2593multiclass VPseudoTernaryV_VX_AAXA<string Constraint = ""> {
2594  foreach m = MxList in
2595    defm "_VX" : VPseudoTernaryWithPolicy<m.vrclass, GPR, m.vrclass, m,
2596                                          Constraint, /*Commutable*/1>;
2597}
2598
2599multiclass VPseudoTernaryV_VF_AAXA<string Constraint = ""> {
2600  foreach f = FPList in
2601    foreach m = f.MxList in
2602      defm "_V" # f.FX : VPseudoTernaryWithPolicy<m.vrclass, f.fprclass,
2603                                                  m.vrclass, m, Constraint,
2604                                                  /*Commutable*/1>;
2605}
2606
2607multiclass VPseudoTernaryW_VV<list<LMULInfo> mxlist = MxListW> {
2608  defvar constraint = "@earlyclobber $rd";
2609  foreach m = mxlist in
2610    defm _VV : VPseudoTernaryWithPolicy<m.wvrclass, m.vrclass, m.vrclass, m,
2611                                        constraint>;
2612}
2613
2614multiclass VPseudoTernaryW_VX {
2615  defvar constraint = "@earlyclobber $rd";
2616  foreach m = MxListW in
2617    defm "_VX" : VPseudoTernaryWithPolicy<m.wvrclass, GPR, m.vrclass, m,
2618                                          constraint>;
2619}
2620
2621multiclass VPseudoTernaryW_VF {
2622  defvar constraint = "@earlyclobber $rd";
2623  foreach f = FPListW in
2624    foreach m = f.MxList in
2625      defm "_V" # f.FX : VPseudoTernaryWithPolicy<m.wvrclass, f.fprclass,
2626                                                  m.vrclass, m, constraint>;
2627}
2628
2629multiclass VPseudoVSLDV_VI<Operand ImmType = simm5, string Constraint = ""> {
2630  foreach m = MxList in
2631    defm _VI : VPseudoTernaryWithPolicy<m.vrclass, m.vrclass, ImmType, m, Constraint>;
2632}
2633
2634multiclass VPseudoVMAC_VV_VX_AAXA<string Constraint = ""> {
2635  defm "" : VPseudoTernaryV_VV_AAXA<Constraint>,
2636            Sched<[WriteVIMulAddV, ReadVIMulAddV, ReadVIMulAddV, ReadVIMulAddV, ReadVMask]>;
2637  defm "" : VPseudoTernaryV_VX_AAXA<Constraint>,
2638            Sched<[WriteVIMulAddX, ReadVIMulAddV, ReadVIMulAddV, ReadVIMulAddX, ReadVMask]>;
2639}
2640
2641multiclass VPseudoVMAC_VV_VF_AAXA<string Constraint = ""> {
2642  defm "" : VPseudoTernaryV_VV_AAXA<Constraint, MxListF>,
2643            Sched<[WriteVFMulAddV, ReadVFMulAddV, ReadVFMulAddV, ReadVFMulAddV, ReadVMask]>;
2644  defm "" : VPseudoTernaryV_VF_AAXA<Constraint>,
2645            Sched<[WriteVFMulAddF, ReadVFMulAddV, ReadVFMulAddV, ReadVFMulAddF, ReadVMask]>;
2646}
2647
2648multiclass VPseudoVSLD_VX_VI<Operand ImmType = simm5, string Constraint = ""> {
2649  defm "" : VPseudoVSLDV_VX<Constraint>,
2650            Sched<[WriteVISlideX, ReadVISlideV, ReadVISlideV, ReadVISlideX, ReadVMask]>;
2651  defm "" : VPseudoVSLDV_VI<ImmType, Constraint>,
2652            Sched<[WriteVISlideI, ReadVISlideV, ReadVISlideV, ReadVMask]>;
2653}
2654
2655multiclass VPseudoVWMAC_VV_VX {
2656  defm "" : VPseudoTernaryW_VV,
2657            Sched<[WriteVIWMulAddV, ReadVIWMulAddV, ReadVIWMulAddV, ReadVIWMulAddV, ReadVMask]>;
2658  defm "" : VPseudoTernaryW_VX,
2659            Sched<[WriteVIWMulAddX, ReadVIWMulAddV, ReadVIWMulAddV, ReadVIWMulAddX, ReadVMask]>;
2660}
2661
2662multiclass VPseudoVWMAC_VX {
2663  defm "" : VPseudoTernaryW_VX,
2664            Sched<[WriteVIWMulAddX, ReadVIWMulAddV, ReadVIWMulAddV, ReadVIWMulAddX, ReadVMask]>;
2665}
2666
2667multiclass VPseudoVWMAC_VV_VF {
2668  defm "" : VPseudoTernaryW_VV<MxListFW>,
2669            Sched<[WriteVFWMulAddV, ReadVFWMulAddV, ReadVFWMulAddV, ReadVFWMulAddV, ReadVMask]>;
2670  defm "" : VPseudoTernaryW_VF,
2671            Sched<[WriteVFWMulAddF, ReadVFWMulAddV, ReadVFWMulAddV, ReadVFWMulAddF, ReadVMask]>;
2672}
2673
2674multiclass VPseudoVCMPM_VV_VX_VI {
2675  defm "" : VPseudoBinaryM_VV,
2676            Sched<[WriteVICmpV, ReadVICmpV, ReadVICmpV, ReadVMask]>;
2677  defm "" : VPseudoBinaryM_VX,
2678            Sched<[WriteVICmpX, ReadVICmpV, ReadVICmpX, ReadVMask]>;
2679  defm "" : VPseudoBinaryM_VI,
2680            Sched<[WriteVICmpI, ReadVICmpV, ReadVMask]>;
2681}
2682
2683multiclass VPseudoVCMPM_VV_VX {
2684  defm "" : VPseudoBinaryM_VV,
2685            Sched<[WriteVICmpV, ReadVICmpV, ReadVICmpV, ReadVMask]>;
2686  defm "" : VPseudoBinaryM_VX,
2687            Sched<[WriteVICmpX, ReadVICmpV, ReadVICmpX, ReadVMask]>;
2688}
2689
2690multiclass VPseudoVCMPM_VV_VF {
2691  defm "" : VPseudoBinaryM_VV<MxListF>,
2692            Sched<[WriteVFCmpV, ReadVFCmpV, ReadVFCmpV, ReadVMask]>;
2693  defm "" : VPseudoBinaryM_VF,
2694            Sched<[WriteVFCmpF, ReadVFCmpV, ReadVFCmpF, ReadVMask]>;
2695}
2696
2697multiclass VPseudoVCMPM_VF {
2698  defm "" : VPseudoBinaryM_VF,
2699            Sched<[WriteVFCmpF, ReadVFCmpV, ReadVFCmpF, ReadVMask]>;
2700}
2701
2702multiclass VPseudoVCMPM_VX_VI {
2703  defm "" : VPseudoBinaryM_VX,
2704            Sched<[WriteVICmpX, ReadVICmpV, ReadVICmpX, ReadVMask]>;
2705  defm "" : VPseudoBinaryM_VI,
2706            Sched<[WriteVICmpI, ReadVICmpV, ReadVMask]>;
2707}
2708
2709multiclass VPseudoVRED_VS {
2710  foreach m = MxList in {
2711    defm _VS : VPseudoTernary<V_M1.vrclass, m.vrclass, V_M1.vrclass, m>,
2712               Sched<[WriteVIRedV, ReadVIRedV, ReadVIRedV, ReadVIRedV, ReadVMask]>;
2713  }
2714}
2715
2716multiclass VPseudoVWRED_VS {
2717  foreach m = MxList in {
2718    defm _VS : VPseudoTernary<V_M1.vrclass, m.vrclass, V_M1.vrclass, m>,
2719               Sched<[WriteVIWRedV, ReadVIWRedV, ReadVIWRedV, ReadVIWRedV, ReadVMask]>;
2720  }
2721}
2722
2723multiclass VPseudoVFRED_VS {
2724  foreach m = MxListF in {
2725    defm _VS : VPseudoTernary<V_M1.vrclass, m.vrclass, V_M1.vrclass, m>,
2726               Sched<[WriteVFRedV, ReadVFRedV, ReadVFRedV, ReadVFRedV, ReadVMask]>;
2727  }
2728}
2729
2730multiclass VPseudoVFREDO_VS {
2731  foreach m = MxListF in {
2732    defm _VS : VPseudoTernary<V_M1.vrclass, m.vrclass, V_M1.vrclass, m>,
2733               Sched<[WriteVFRedOV, ReadVFRedOV, ReadVFRedOV, ReadVFRedOV, ReadVMask]>;
2734  }
2735}
2736
2737multiclass VPseudoVFWRED_VS {
2738  foreach m = MxListF in {
2739    defm _VS : VPseudoTernary<V_M1.vrclass, m.vrclass, V_M1.vrclass, m>,
2740               Sched<[WriteVFWRedV, ReadVFWRedV, ReadVFWRedV, ReadVFWRedV, ReadVMask]>;
2741  }
2742}
2743
2744multiclass VPseudoConversion<VReg RetClass,
2745                             VReg Op1Class,
2746                             LMULInfo MInfo,
2747                             string Constraint = ""> {
2748  let VLMul = MInfo.value in {
2749    def "_" # MInfo.MX : VPseudoUnaryNoMask<RetClass, Op1Class, Constraint>;
2750    def "_" # MInfo.MX # "_TU": VPseudoUnaryNoMaskTU<RetClass, Op1Class, Constraint>;
2751    def "_" # MInfo.MX # "_MASK" : VPseudoUnaryMaskTA<RetClass, Op1Class,
2752                                                      Constraint>,
2753                                   RISCVMaskedPseudo</*MaskOpIdx*/ 2>;
2754  }
2755}
2756
2757multiclass VPseudoVCVTI_V {
2758  foreach m = MxListF in
2759    defm _V : VPseudoConversion<m.vrclass, m.vrclass, m>,
2760              Sched<[WriteVFCvtFToIV, ReadVFCvtFToIV, ReadVMask]>;
2761}
2762
2763multiclass VPseudoVCVTF_V {
2764  foreach m = MxListF in
2765    defm _V : VPseudoConversion<m.vrclass, m.vrclass, m>,
2766              Sched<[WriteVFCvtIToFV, ReadVFCvtIToFV, ReadVMask]>;
2767}
2768
2769multiclass VPseudoConversionW_V {
2770  defvar constraint = "@earlyclobber $rd";
2771  foreach m = MxListW in
2772    defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint>;
2773}
2774
2775multiclass VPseudoVWCVTI_V {
2776  defvar constraint = "@earlyclobber $rd";
2777  foreach m = MxListFW in
2778    defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint>,
2779              Sched<[WriteVFWCvtFToIV, ReadVFWCvtFToIV, ReadVMask]>;
2780}
2781
2782multiclass VPseudoVWCVTF_V {
2783  defvar constraint = "@earlyclobber $rd";
2784  foreach m = MxListW in
2785    defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint>,
2786              Sched<[WriteVFWCvtIToFV, ReadVFWCvtIToFV, ReadVMask]>;
2787}
2788
2789multiclass VPseudoVWCVTD_V {
2790  defvar constraint = "@earlyclobber $rd";
2791  foreach m = MxListFW in
2792    defm _V : VPseudoConversion<m.wvrclass, m.vrclass, m, constraint>,
2793              Sched<[WriteVFWCvtFToFV, ReadVFWCvtFToFV, ReadVMask]>;
2794}
2795
2796multiclass VPseudoVNCVTI_W {
2797  defvar constraint = "@earlyclobber $rd";
2798  foreach m = MxListW in
2799    defm _W : VPseudoConversion<m.vrclass, m.wvrclass, m, constraint>,
2800              Sched<[WriteVFNCvtFToIV, ReadVFNCvtFToIV, ReadVMask]>;
2801}
2802
2803multiclass VPseudoVNCVTF_W {
2804  defvar constraint = "@earlyclobber $rd";
2805  foreach m = MxListFW in
2806    defm _W : VPseudoConversion<m.vrclass, m.wvrclass, m, constraint>,
2807              Sched<[WriteVFNCvtIToFV, ReadVFNCvtIToFV, ReadVMask]>;
2808}
2809
2810multiclass VPseudoVNCVTD_W {
2811  defvar constraint = "@earlyclobber $rd";
2812  foreach m = MxListFW in
2813    defm _W : VPseudoConversion<m.vrclass, m.wvrclass, m, constraint>,
2814              Sched<[WriteVFNCvtFToFV, ReadVFNCvtFToFV, ReadVMask]>;
2815}
2816
2817multiclass VPseudoUSSegLoad {
2818  foreach eew = EEWList in {
2819    foreach lmul = MxSet<eew>.m in {
2820      defvar LInfo = lmul.MX;
2821      let VLMul = lmul.value in {
2822        foreach nf = NFSet<lmul>.L in {
2823          defvar vreg = SegRegClass<lmul, nf>.RC;
2824          def nf # "E" # eew # "_V_" # LInfo :
2825            VPseudoUSSegLoadNoMask<vreg, eew, nf>;
2826          def nf # "E" # eew # "_V_" # LInfo # "_TU" :
2827            VPseudoUSSegLoadNoMaskTU<vreg, eew, nf>;
2828          def nf # "E" # eew # "_V_" # LInfo # "_MASK" :
2829            VPseudoUSSegLoadMask<vreg, eew, nf>;
2830        }
2831      }
2832    }
2833  }
2834}
2835
2836multiclass VPseudoUSSegLoadFF {
2837  foreach eew = EEWList in {
2838    foreach lmul = MxSet<eew>.m in {
2839      defvar LInfo = lmul.MX;
2840      let VLMul = lmul.value in {
2841        foreach nf = NFSet<lmul>.L in {
2842          defvar vreg = SegRegClass<lmul, nf>.RC;
2843          def nf # "E" # eew # "FF_V_" # LInfo :
2844            VPseudoUSSegLoadFFNoMask<vreg, eew, nf>;
2845          def nf # "E" # eew # "FF_V_" # LInfo # "_TU" :
2846            VPseudoUSSegLoadFFNoMaskTU<vreg, eew, nf>;
2847          def nf # "E" # eew # "FF_V_" # LInfo # "_MASK" :
2848            VPseudoUSSegLoadFFMask<vreg, eew, nf>;
2849        }
2850      }
2851    }
2852  }
2853}
2854
2855multiclass VPseudoSSegLoad {
2856  foreach eew = EEWList in {
2857    foreach lmul = MxSet<eew>.m in {
2858      defvar LInfo = lmul.MX;
2859      let VLMul = lmul.value in {
2860        foreach nf = NFSet<lmul>.L in {
2861          defvar vreg = SegRegClass<lmul, nf>.RC;
2862          def nf # "E" # eew # "_V_" # LInfo : VPseudoSSegLoadNoMask<vreg, eew, nf>;
2863          def nf # "E" # eew # "_V_" # LInfo # "_TU" : VPseudoSSegLoadNoMaskTU<vreg, eew, nf>;
2864          def nf # "E" # eew # "_V_" # LInfo # "_MASK" : VPseudoSSegLoadMask<vreg, eew, nf>;
2865        }
2866      }
2867    }
2868  }
2869}
2870
2871multiclass VPseudoISegLoad<bit Ordered> {
2872  foreach idx_eew = EEWList in {
2873    foreach sew = EEWList in {
2874      foreach val_lmul = MxSet<sew>.m in {
2875        defvar octuple_lmul = val_lmul.octuple;
2876        // Calculate emul = eew * lmul / sew
2877        defvar octuple_emul = !srl(!mul(idx_eew, octuple_lmul), log2<sew>.val);
2878        if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then {
2879          defvar ValLInfo = val_lmul.MX;
2880          defvar IdxLInfo = octuple_to_str<octuple_emul>.ret;
2881          defvar idx_lmul = !cast<LMULInfo>("V_" # IdxLInfo);
2882          defvar Vreg = val_lmul.vrclass;
2883          defvar IdxVreg = idx_lmul.vrclass;
2884          let VLMul = val_lmul.value in {
2885            foreach nf = NFSet<val_lmul>.L in {
2886              defvar ValVreg = SegRegClass<val_lmul, nf>.RC;
2887              def nf # "EI" # idx_eew # "_V_" # IdxLInfo # "_" # ValLInfo :
2888                VPseudoISegLoadNoMask<ValVreg, IdxVreg, idx_eew, idx_lmul.value,
2889                                      nf, Ordered>;
2890              def nf # "EI" # idx_eew # "_V_" # IdxLInfo # "_" # ValLInfo # "_TU" :
2891                VPseudoISegLoadNoMaskTU<ValVreg, IdxVreg, idx_eew, idx_lmul.value,
2892                                        nf, Ordered>;
2893              def nf # "EI" # idx_eew # "_V_" # IdxLInfo # "_" # ValLInfo # "_MASK" :
2894                VPseudoISegLoadMask<ValVreg, IdxVreg, idx_eew, idx_lmul.value,
2895                                    nf, Ordered>;
2896            }
2897          }
2898        }
2899      }
2900    }
2901  }
2902}
2903
2904multiclass VPseudoUSSegStore {
2905  foreach eew = EEWList in {
2906    foreach lmul = MxSet<eew>.m in {
2907      defvar LInfo = lmul.MX;
2908      let VLMul = lmul.value in {
2909        foreach nf = NFSet<lmul>.L in {
2910          defvar vreg = SegRegClass<lmul, nf>.RC;
2911          def nf # "E" # eew # "_V_" # LInfo : VPseudoUSSegStoreNoMask<vreg, eew, nf>;
2912          def nf # "E" # eew # "_V_" # LInfo # "_MASK" : VPseudoUSSegStoreMask<vreg, eew, nf>;
2913        }
2914      }
2915    }
2916  }
2917}
2918
2919multiclass VPseudoSSegStore {
2920  foreach eew = EEWList in {
2921    foreach lmul = MxSet<eew>.m in {
2922      defvar LInfo = lmul.MX;
2923      let VLMul = lmul.value in {
2924        foreach nf = NFSet<lmul>.L in {
2925          defvar vreg = SegRegClass<lmul, nf>.RC;
2926          def nf # "E" # eew # "_V_" # LInfo : VPseudoSSegStoreNoMask<vreg, eew, nf>;
2927          def nf # "E" # eew # "_V_" # LInfo # "_MASK" : VPseudoSSegStoreMask<vreg, eew, nf>;
2928        }
2929      }
2930    }
2931  }
2932}
2933
2934multiclass VPseudoISegStore<bit Ordered> {
2935  foreach idx_eew = EEWList in {
2936    foreach sew = EEWList in {
2937      foreach val_lmul = MxSet<sew>.m in {
2938        defvar octuple_lmul = val_lmul.octuple;
2939        // Calculate emul = eew * lmul / sew
2940        defvar octuple_emul = !srl(!mul(idx_eew, octuple_lmul), log2<sew>.val);
2941        if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then {
2942          defvar ValLInfo = val_lmul.MX;
2943          defvar IdxLInfo = octuple_to_str<octuple_emul>.ret;
2944          defvar idx_lmul = !cast<LMULInfo>("V_" # IdxLInfo);
2945          defvar Vreg = val_lmul.vrclass;
2946          defvar IdxVreg = idx_lmul.vrclass;
2947          let VLMul = val_lmul.value in {
2948            foreach nf = NFSet<val_lmul>.L in {
2949              defvar ValVreg = SegRegClass<val_lmul, nf>.RC;
2950              def nf # "EI" # idx_eew # "_V_" # IdxLInfo # "_" # ValLInfo :
2951                VPseudoISegStoreNoMask<ValVreg, IdxVreg, idx_eew, idx_lmul.value,
2952                                       nf, Ordered>;
2953              def nf # "EI" # idx_eew # "_V_" # IdxLInfo # "_" # ValLInfo # "_MASK" :
2954                VPseudoISegStoreMask<ValVreg, IdxVreg, idx_eew, idx_lmul.value,
2955                                     nf, Ordered>;
2956            }
2957          }
2958        }
2959      }
2960    }
2961  }
2962}
2963
2964//===----------------------------------------------------------------------===//
2965// Helpers to define the intrinsic patterns.
2966//===----------------------------------------------------------------------===//
2967
2968class VPatUnaryNoMask<string intrinsic_name,
2969                      string inst,
2970                      string kind,
2971                      ValueType result_type,
2972                      ValueType op2_type,
2973                      int sew,
2974                      LMULInfo vlmul,
2975                      VReg op2_reg_class> :
2976  Pat<(result_type (!cast<Intrinsic>(intrinsic_name)
2977                   (result_type undef),
2978                   (op2_type op2_reg_class:$rs2),
2979                   VLOpFrag)),
2980                   (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX)
2981                   (op2_type op2_reg_class:$rs2),
2982                   GPR:$vl, sew)>;
2983
2984class VPatUnaryNoMaskTU<string intrinsic_name,
2985                        string inst,
2986                        string kind,
2987                        ValueType result_type,
2988                        ValueType op2_type,
2989                        int sew,
2990                        LMULInfo vlmul,
2991                        VReg result_reg_class,
2992                        VReg op2_reg_class> :
2993  Pat<(result_type (!cast<Intrinsic>(intrinsic_name)
2994                   (result_type result_reg_class:$merge),
2995                   (op2_type op2_reg_class:$rs2),
2996                   VLOpFrag)),
2997                   (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX#"_TU")
2998                   (result_type result_reg_class:$merge),
2999                   (op2_type op2_reg_class:$rs2),
3000                   GPR:$vl, sew)>;
3001
3002class VPatUnaryMask<string intrinsic_name,
3003                    string inst,
3004                    string kind,
3005                    ValueType result_type,
3006                    ValueType op2_type,
3007                    ValueType mask_type,
3008                    int sew,
3009                    LMULInfo vlmul,
3010                    VReg result_reg_class,
3011                    VReg op2_reg_class> :
3012  Pat<(result_type (!cast<Intrinsic>(intrinsic_name#"_mask")
3013                   (result_type result_reg_class:$merge),
3014                   (op2_type op2_reg_class:$rs2),
3015                   (mask_type V0),
3016                   VLOpFrag)),
3017                   (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX#"_MASK")
3018                   (result_type result_reg_class:$merge),
3019                   (op2_type op2_reg_class:$rs2),
3020                   (mask_type V0), GPR:$vl, sew)>;
3021
3022class VPatUnaryMaskTA<string intrinsic_name,
3023                      string inst,
3024                      string kind,
3025                      ValueType result_type,
3026                      ValueType op2_type,
3027                      ValueType mask_type,
3028                      int sew,
3029                      LMULInfo vlmul,
3030                      VReg result_reg_class,
3031                      VReg op2_reg_class> :
3032  Pat<(result_type (!cast<Intrinsic>(intrinsic_name#"_mask")
3033                   (result_type result_reg_class:$merge),
3034                   (op2_type op2_reg_class:$rs2),
3035                   (mask_type V0),
3036                   VLOpFrag, (XLenVT timm:$policy))),
3037                   (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX#"_MASK")
3038                   (result_type result_reg_class:$merge),
3039                   (op2_type op2_reg_class:$rs2),
3040                   (mask_type V0), GPR:$vl, sew, (XLenVT timm:$policy))>;
3041
3042class VPatMaskUnaryNoMask<string intrinsic_name,
3043                          string inst,
3044                          MTypeInfo mti> :
3045  Pat<(mti.Mask (!cast<Intrinsic>(intrinsic_name)
3046                (mti.Mask VR:$rs2),
3047                VLOpFrag)),
3048                (!cast<Instruction>(inst#"_M_"#mti.BX)
3049                (mti.Mask VR:$rs2),
3050                GPR:$vl, mti.Log2SEW)>;
3051
3052class VPatMaskUnaryMask<string intrinsic_name,
3053                        string inst,
3054                        MTypeInfo mti> :
3055  Pat<(mti.Mask (!cast<Intrinsic>(intrinsic_name#"_mask")
3056                (mti.Mask VR:$merge),
3057                (mti.Mask VR:$rs2),
3058                (mti.Mask V0),
3059                VLOpFrag)),
3060                (!cast<Instruction>(inst#"_M_"#mti.BX#"_MASK")
3061                (mti.Mask VR:$merge),
3062                (mti.Mask VR:$rs2),
3063                (mti.Mask V0), GPR:$vl, mti.Log2SEW)>;
3064
3065class VPatUnaryAnyMask<string intrinsic,
3066                       string inst,
3067                       string kind,
3068                       ValueType result_type,
3069                       ValueType op1_type,
3070                       ValueType mask_type,
3071                       int sew,
3072                       LMULInfo vlmul,
3073                       VReg result_reg_class,
3074                       VReg op1_reg_class> :
3075  Pat<(result_type (!cast<Intrinsic>(intrinsic)
3076                   (result_type result_reg_class:$merge),
3077                   (op1_type op1_reg_class:$rs1),
3078                   (mask_type VR:$rs2),
3079                   VLOpFrag)),
3080                   (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX)
3081                   (result_type result_reg_class:$merge),
3082                   (op1_type op1_reg_class:$rs1),
3083                   (mask_type VR:$rs2),
3084                   GPR:$vl, sew)>;
3085
3086class VPatBinaryM<string intrinsic_name,
3087                  string inst,
3088                  ValueType result_type,
3089                  ValueType op1_type,
3090                  ValueType op2_type,
3091                  int sew,
3092                  VReg op1_reg_class,
3093                  DAGOperand op2_kind> :
3094  Pat<(result_type (!cast<Intrinsic>(intrinsic_name)
3095                   (op1_type op1_reg_class:$rs1),
3096                   (op2_type op2_kind:$rs2),
3097                   VLOpFrag)),
3098                   (!cast<Instruction>(inst)
3099                   (op1_type op1_reg_class:$rs1),
3100                   (op2_type op2_kind:$rs2),
3101                   GPR:$vl, sew)>;
3102
3103class VPatBinaryNoMaskTA<string intrinsic_name,
3104                         string inst,
3105                         ValueType result_type,
3106                         ValueType op1_type,
3107                         ValueType op2_type,
3108                         int sew,
3109                         VReg op1_reg_class,
3110                         DAGOperand op2_kind> :
3111  Pat<(result_type (!cast<Intrinsic>(intrinsic_name)
3112                   (result_type (undef)),
3113                   (op1_type op1_reg_class:$rs1),
3114                   (op2_type op2_kind:$rs2),
3115                   VLOpFrag)),
3116                   (!cast<Instruction>(inst)
3117                   (op1_type op1_reg_class:$rs1),
3118                   (op2_type op2_kind:$rs2),
3119                   GPR:$vl, sew)>;
3120
3121class VPatBinaryNoMaskTU<string intrinsic_name,
3122                         string inst,
3123                         ValueType result_type,
3124                         ValueType op1_type,
3125                         ValueType op2_type,
3126                         int sew,
3127                         VReg result_reg_class,
3128                         VReg op1_reg_class,
3129                         DAGOperand op2_kind> :
3130  Pat<(result_type (!cast<Intrinsic>(intrinsic_name)
3131                   (result_type result_reg_class:$merge),
3132                   (op1_type op1_reg_class:$rs1),
3133                   (op2_type op2_kind:$rs2),
3134                   VLOpFrag)),
3135                   (!cast<Instruction>(inst#"_TU")
3136                   (result_type result_reg_class:$merge),
3137                   (op1_type op1_reg_class:$rs1),
3138                   (op2_type op2_kind:$rs2),
3139                   GPR:$vl, sew)>;
3140
3141// Same as above but source operands are swapped.
3142class VPatBinaryNoMaskSwapped<string intrinsic_name,
3143                              string inst,
3144                              ValueType result_type,
3145                              ValueType op1_type,
3146                              ValueType op2_type,
3147                              int sew,
3148                              VReg op1_reg_class,
3149                              DAGOperand op2_kind> :
3150  Pat<(result_type (!cast<Intrinsic>(intrinsic_name)
3151                   (op2_type op2_kind:$rs2),
3152                   (op1_type op1_reg_class:$rs1),
3153                   VLOpFrag)),
3154                   (!cast<Instruction>(inst)
3155                   (op1_type op1_reg_class:$rs1),
3156                   (op2_type op2_kind:$rs2),
3157                   GPR:$vl, sew)>;
3158
3159class VPatBinaryMask<string intrinsic_name,
3160                     string inst,
3161                     ValueType result_type,
3162                     ValueType op1_type,
3163                     ValueType op2_type,
3164                     ValueType mask_type,
3165                     int sew,
3166                     VReg result_reg_class,
3167                     VReg op1_reg_class,
3168                     DAGOperand op2_kind> :
3169  Pat<(result_type (!cast<Intrinsic>(intrinsic_name#"_mask")
3170                   (result_type result_reg_class:$merge),
3171                   (op1_type op1_reg_class:$rs1),
3172                   (op2_type op2_kind:$rs2),
3173                   (mask_type V0),
3174                   VLOpFrag)),
3175                   (!cast<Instruction>(inst#"_MASK")
3176                   (result_type result_reg_class:$merge),
3177                   (op1_type op1_reg_class:$rs1),
3178                   (op2_type op2_kind:$rs2),
3179                   (mask_type V0), GPR:$vl, sew)>;
3180
3181class VPatBinaryMaskTA<string intrinsic_name,
3182                       string inst,
3183                       ValueType result_type,
3184                       ValueType op1_type,
3185                       ValueType op2_type,
3186                       ValueType mask_type,
3187                       int sew,
3188                       VReg result_reg_class,
3189                       VReg op1_reg_class,
3190                       DAGOperand op2_kind> :
3191  Pat<(result_type (!cast<Intrinsic>(intrinsic_name#"_mask")
3192                   (result_type result_reg_class:$merge),
3193                   (op1_type op1_reg_class:$rs1),
3194                   (op2_type op2_kind:$rs2),
3195                   (mask_type V0),
3196                   VLOpFrag, (XLenVT timm:$policy))),
3197                   (!cast<Instruction>(inst#"_MASK")
3198                   (result_type result_reg_class:$merge),
3199                   (op1_type op1_reg_class:$rs1),
3200                   (op2_type op2_kind:$rs2),
3201                   (mask_type V0), GPR:$vl, sew, (XLenVT timm:$policy))>;
3202
3203// Same as above but source operands are swapped.
3204class VPatBinaryMaskSwapped<string intrinsic_name,
3205                            string inst,
3206                            ValueType result_type,
3207                            ValueType op1_type,
3208                            ValueType op2_type,
3209                            ValueType mask_type,
3210                            int sew,
3211                            VReg result_reg_class,
3212                            VReg op1_reg_class,
3213                            DAGOperand op2_kind> :
3214  Pat<(result_type (!cast<Intrinsic>(intrinsic_name#"_mask")
3215                   (result_type result_reg_class:$merge),
3216                   (op2_type op2_kind:$rs2),
3217                   (op1_type op1_reg_class:$rs1),
3218                   (mask_type V0),
3219                   VLOpFrag)),
3220                   (!cast<Instruction>(inst#"_MASK")
3221                   (result_type result_reg_class:$merge),
3222                   (op1_type op1_reg_class:$rs1),
3223                   (op2_type op2_kind:$rs2),
3224                   (mask_type V0), GPR:$vl, sew)>;
3225
3226class VPatTiedBinaryNoMask<string intrinsic_name,
3227                           string inst,
3228                           ValueType result_type,
3229                           ValueType op2_type,
3230                           int sew,
3231                           VReg result_reg_class,
3232                           DAGOperand op2_kind> :
3233  Pat<(result_type (!cast<Intrinsic>(intrinsic_name)
3234                   (result_type (undef)),
3235                   (result_type result_reg_class:$rs1),
3236                   (op2_type op2_kind:$rs2),
3237                   VLOpFrag)),
3238                   (!cast<Instruction>(inst#"_TIED")
3239                   (result_type result_reg_class:$rs1),
3240                   (op2_type op2_kind:$rs2),
3241                   GPR:$vl, sew, TAIL_AGNOSTIC)>;
3242
3243class VPatTiedBinaryNoMaskTU<string intrinsic_name,
3244                             string inst,
3245                             ValueType result_type,
3246                             ValueType op2_type,
3247                             int sew,
3248                             VReg result_reg_class,
3249                             DAGOperand op2_kind> :
3250  Pat<(result_type (!cast<Intrinsic>(intrinsic_name)
3251                   (result_type result_reg_class:$merge),
3252                   (result_type result_reg_class:$merge),
3253                   (op2_type op2_kind:$rs2),
3254                   VLOpFrag)),
3255                   (!cast<Instruction>(inst#"_TIED")
3256                   (result_type result_reg_class:$merge),
3257                   (op2_type op2_kind:$rs2),
3258                   GPR:$vl, sew, TAIL_UNDISTURBED_MASK_UNDISTURBED)>;
3259
3260class VPatTiedBinaryMask<string intrinsic_name,
3261                         string inst,
3262                         ValueType result_type,
3263                         ValueType op2_type,
3264                         ValueType mask_type,
3265                         int sew,
3266                         VReg result_reg_class,
3267                         DAGOperand op2_kind> :
3268  Pat<(result_type (!cast<Intrinsic>(intrinsic_name#"_mask")
3269                   (result_type result_reg_class:$merge),
3270                   (result_type result_reg_class:$merge),
3271                   (op2_type op2_kind:$rs2),
3272                   (mask_type V0),
3273                   VLOpFrag, (XLenVT timm:$policy))),
3274                   (!cast<Instruction>(inst#"_MASK_TIED")
3275                   (result_type result_reg_class:$merge),
3276                   (op2_type op2_kind:$rs2),
3277                   (mask_type V0), GPR:$vl, sew, (XLenVT timm:$policy))>;
3278
3279class VPatTernaryNoMask<string intrinsic,
3280                        string inst,
3281                        string kind,
3282                        ValueType result_type,
3283                        ValueType op1_type,
3284                        ValueType op2_type,
3285                        int sew,
3286                        LMULInfo vlmul,
3287                        VReg result_reg_class,
3288                        RegisterClass op1_reg_class,
3289                        DAGOperand op2_kind> :
3290  Pat<(result_type (!cast<Intrinsic>(intrinsic)
3291                    (result_type result_reg_class:$rs3),
3292                    (op1_type op1_reg_class:$rs1),
3293                    (op2_type op2_kind:$rs2),
3294                    VLOpFrag)),
3295                   (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX)
3296                    result_reg_class:$rs3,
3297                    (op1_type op1_reg_class:$rs1),
3298                    op2_kind:$rs2,
3299                    GPR:$vl, sew)>;
3300
3301class VPatTernaryNoMaskWithPolicy<string intrinsic,
3302                                  string inst,
3303                                  string kind,
3304                                  ValueType result_type,
3305                                  ValueType op1_type,
3306                                  ValueType op2_type,
3307                                  int sew,
3308                                  LMULInfo vlmul,
3309                                  VReg result_reg_class,
3310                                  RegisterClass op1_reg_class,
3311                                  DAGOperand op2_kind> :
3312  Pat<(result_type (!cast<Intrinsic>(intrinsic)
3313                    (result_type result_reg_class:$rs3),
3314                    (op1_type op1_reg_class:$rs1),
3315                    (op2_type op2_kind:$rs2),
3316                    VLOpFrag, (XLenVT timm:$policy))),
3317                   (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX)
3318                    result_reg_class:$rs3,
3319                    (op1_type op1_reg_class:$rs1),
3320                    op2_kind:$rs2,
3321                    GPR:$vl, sew, (XLenVT timm:$policy))>;
3322
3323class VPatTernaryMask<string intrinsic,
3324                      string inst,
3325                      string kind,
3326                      ValueType result_type,
3327                      ValueType op1_type,
3328                      ValueType op2_type,
3329                      ValueType mask_type,
3330                      int sew,
3331                      LMULInfo vlmul,
3332                      VReg result_reg_class,
3333                      RegisterClass op1_reg_class,
3334                      DAGOperand op2_kind> :
3335  Pat<(result_type (!cast<Intrinsic>(intrinsic#"_mask")
3336                    (result_type result_reg_class:$rs3),
3337                    (op1_type op1_reg_class:$rs1),
3338                    (op2_type op2_kind:$rs2),
3339                    (mask_type V0),
3340                    VLOpFrag)),
3341                   (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX # "_MASK")
3342                    result_reg_class:$rs3,
3343                    (op1_type op1_reg_class:$rs1),
3344                    op2_kind:$rs2,
3345                    (mask_type V0),
3346                    GPR:$vl, sew)>;
3347
3348class VPatTernaryMaskPolicy<string intrinsic,
3349                            string inst,
3350                            string kind,
3351                            ValueType result_type,
3352                            ValueType op1_type,
3353                            ValueType op2_type,
3354                            ValueType mask_type,
3355                            int sew,
3356                            LMULInfo vlmul,
3357                            VReg result_reg_class,
3358                            RegisterClass op1_reg_class,
3359                            DAGOperand op2_kind> :
3360  Pat<(result_type (!cast<Intrinsic>(intrinsic#"_mask")
3361                    (result_type result_reg_class:$rs3),
3362                    (op1_type op1_reg_class:$rs1),
3363                    (op2_type op2_kind:$rs2),
3364                    (mask_type V0),
3365                    VLOpFrag, (XLenVT timm:$policy))),
3366                   (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX # "_MASK")
3367                    result_reg_class:$rs3,
3368                    (op1_type op1_reg_class:$rs1),
3369                    op2_kind:$rs2,
3370                    (mask_type V0),
3371                    GPR:$vl, sew, (XLenVT timm:$policy))>;
3372
3373multiclass VPatUnaryS_M<string intrinsic_name,
3374                             string inst>
3375{
3376  foreach mti = AllMasks in {
3377    def : Pat<(XLenVT (!cast<Intrinsic>(intrinsic_name)
3378                      (mti.Mask VR:$rs1), VLOpFrag)),
3379                      (!cast<Instruction>(inst#"_M_"#mti.BX) $rs1,
3380                      GPR:$vl, mti.Log2SEW)>;
3381    def : Pat<(XLenVT (!cast<Intrinsic>(intrinsic_name # "_mask")
3382                      (mti.Mask VR:$rs1), (mti.Mask V0), VLOpFrag)),
3383                      (!cast<Instruction>(inst#"_M_"#mti.BX#"_MASK") $rs1,
3384                      (mti.Mask V0), GPR:$vl, mti.Log2SEW)>;
3385  }
3386}
3387
3388multiclass VPatUnaryV_V_AnyMask<string intrinsic, string instruction,
3389                                list<VTypeInfo> vtilist> {
3390  foreach vti = vtilist in {
3391    def : VPatUnaryAnyMask<intrinsic, instruction, "VM",
3392                           vti.Vector, vti.Vector, vti.Mask,
3393                           vti.Log2SEW, vti.LMul, vti.RegClass,
3394                           vti.RegClass>;
3395  }
3396}
3397
3398multiclass VPatUnaryM_M<string intrinsic,
3399                         string inst>
3400{
3401  foreach mti = AllMasks in {
3402    def : VPatMaskUnaryNoMask<intrinsic, inst, mti>;
3403    def : VPatMaskUnaryMask<intrinsic, inst, mti>;
3404  }
3405}
3406
3407multiclass VPatUnaryV_M<string intrinsic, string instruction>
3408{
3409  foreach vti = AllIntegerVectors in {
3410    def : VPatUnaryNoMask<intrinsic, instruction, "M", vti.Vector, vti.Mask,
3411                          vti.Log2SEW, vti.LMul, VR>;
3412    def : VPatUnaryNoMaskTU<intrinsic, instruction, "M", vti.Vector, vti.Mask,
3413                            vti.Log2SEW, vti.LMul, vti.RegClass,VR>;
3414    def : VPatUnaryMaskTA<intrinsic, instruction, "M", vti.Vector, vti.Mask,
3415                          vti.Mask, vti.Log2SEW, vti.LMul, vti.RegClass, VR>;
3416  }
3417}
3418
3419multiclass VPatUnaryV_VF<string intrinsic, string instruction, string suffix,
3420                         list<VTypeInfoToFraction> fractionList>
3421{
3422  foreach vtiTofti = fractionList in
3423  {
3424      defvar vti = vtiTofti.Vti;
3425      defvar fti = vtiTofti.Fti;
3426      def : VPatUnaryNoMask<intrinsic, instruction, suffix,
3427                            vti.Vector, fti.Vector,
3428                            vti.Log2SEW, vti.LMul, fti.RegClass>;
3429      def : VPatUnaryNoMaskTU<intrinsic, instruction, suffix,
3430                              vti.Vector, fti.Vector,
3431                              vti.Log2SEW, vti.LMul, vti.RegClass, fti.RegClass>;
3432      def : VPatUnaryMaskTA<intrinsic, instruction, suffix,
3433                            vti.Vector, fti.Vector, vti.Mask,
3434                            vti.Log2SEW, vti.LMul, vti.RegClass, fti.RegClass>;
3435   }
3436}
3437
3438multiclass VPatUnaryV_V<string intrinsic, string instruction,
3439                        list<VTypeInfo> vtilist> {
3440  foreach vti = vtilist in {
3441    def : VPatUnaryNoMask<intrinsic, instruction, "V",
3442                          vti.Vector, vti.Vector,
3443                          vti.Log2SEW, vti.LMul, vti.RegClass>;
3444    def : VPatUnaryNoMaskTU<intrinsic, instruction, "V",
3445                            vti.Vector, vti.Vector,
3446                            vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass>;
3447    def : VPatUnaryMaskTA<intrinsic, instruction, "V",
3448                          vti.Vector, vti.Vector, vti.Mask,
3449                          vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass>;
3450  }
3451}
3452
3453multiclass VPatNullaryV<string intrinsic, string instruction>
3454{
3455  foreach vti = AllIntegerVectors in {
3456    def : Pat<(vti.Vector (!cast<Intrinsic>(intrinsic)
3457                          (vti.Vector undef),
3458                          VLOpFrag)),
3459                          (!cast<Instruction>(instruction#"_V_" # vti.LMul.MX)
3460                          GPR:$vl, vti.Log2SEW)>;
3461    def : Pat<(vti.Vector (!cast<Intrinsic>(intrinsic)
3462                          (vti.Vector vti.RegClass:$merge),
3463                          VLOpFrag)),
3464                          (!cast<Instruction>(instruction#"_V_" # vti.LMul.MX # "_TU")
3465                          vti.RegClass:$merge, GPR:$vl, vti.Log2SEW)>;
3466    def : Pat<(vti.Vector (!cast<Intrinsic>(intrinsic # "_mask")
3467                          (vti.Vector vti.RegClass:$merge),
3468                          (vti.Mask V0), VLOpFrag, (XLenVT timm:$policy))),
3469                          (!cast<Instruction>(instruction#"_V_" # vti.LMul.MX # "_MASK")
3470                          vti.RegClass:$merge, (vti.Mask V0),
3471                          GPR:$vl, vti.Log2SEW, (XLenVT timm:$policy))>;
3472  }
3473}
3474
3475multiclass VPatNullaryM<string intrinsic, string inst> {
3476  foreach mti = AllMasks in
3477    def : Pat<(mti.Mask (!cast<Intrinsic>(intrinsic)
3478                        VLOpFrag)),
3479                        (!cast<Instruction>(inst#"_M_"#mti.BX)
3480                        GPR:$vl, mti.Log2SEW)>;
3481}
3482
3483multiclass VPatBinaryM<string intrinsic,
3484                      string inst,
3485                      ValueType result_type,
3486                      ValueType op1_type,
3487                      ValueType op2_type,
3488                      ValueType mask_type,
3489                      int sew,
3490                      VReg result_reg_class,
3491                      VReg op1_reg_class,
3492                      DAGOperand op2_kind>
3493{
3494  def : VPatBinaryM<intrinsic, inst, result_type, op1_type, op2_type,
3495                    sew, op1_reg_class, op2_kind>;
3496  def : VPatBinaryMask<intrinsic, inst, result_type, op1_type, op2_type,
3497                       mask_type, sew, result_reg_class, op1_reg_class,
3498                       op2_kind>;
3499}
3500
3501multiclass VPatBinaryTA<string intrinsic,
3502                        string inst,
3503                        ValueType result_type,
3504                        ValueType op1_type,
3505                        ValueType op2_type,
3506                        ValueType mask_type,
3507                        int sew,
3508                        VReg result_reg_class,
3509                        VReg op1_reg_class,
3510                        DAGOperand op2_kind>
3511{
3512  def : VPatBinaryNoMaskTA<intrinsic, inst, result_type, op1_type, op2_type,
3513                           sew, op1_reg_class, op2_kind>;
3514  def : VPatBinaryNoMaskTU<intrinsic, inst, result_type, op1_type, op2_type,
3515                           sew, result_reg_class, op1_reg_class, op2_kind>;
3516  def : VPatBinaryMaskTA<intrinsic, inst, result_type, op1_type, op2_type,
3517                         mask_type, sew, result_reg_class, op1_reg_class,
3518                         op2_kind>;
3519}
3520
3521multiclass VPatBinarySwapped<string intrinsic,
3522                      string inst,
3523                      ValueType result_type,
3524                      ValueType op1_type,
3525                      ValueType op2_type,
3526                      ValueType mask_type,
3527                      int sew,
3528                      VReg result_reg_class,
3529                      VReg op1_reg_class,
3530                      DAGOperand op2_kind>
3531{
3532  def : VPatBinaryNoMaskSwapped<intrinsic, inst, result_type, op1_type, op2_type,
3533                                sew, op1_reg_class, op2_kind>;
3534  def : VPatBinaryMaskSwapped<intrinsic, inst, result_type, op1_type, op2_type,
3535                              mask_type, sew, result_reg_class, op1_reg_class,
3536                              op2_kind>;
3537}
3538
3539multiclass VPatBinaryCarryInTAIL<string intrinsic,
3540                                 string inst,
3541                                 string kind,
3542                                 ValueType result_type,
3543                                 ValueType op1_type,
3544                                 ValueType op2_type,
3545                                 ValueType mask_type,
3546                                 int sew,
3547                                 LMULInfo vlmul,
3548                                 VReg result_reg_class,
3549                                 VReg op1_reg_class,
3550                                 DAGOperand op2_kind>
3551{
3552  def : Pat<(result_type (!cast<Intrinsic>(intrinsic)
3553                         (result_type undef),
3554                         (op1_type op1_reg_class:$rs1),
3555                         (op2_type op2_kind:$rs2),
3556                         (mask_type V0),
3557                         VLOpFrag)),
3558                         (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX)
3559                         (op1_type op1_reg_class:$rs1),
3560                         (op2_type op2_kind:$rs2),
3561                         (mask_type V0), GPR:$vl, sew)>;
3562  def : Pat<(result_type (!cast<Intrinsic>(intrinsic)
3563                         (result_type result_reg_class:$merge),
3564                         (op1_type op1_reg_class:$rs1),
3565                         (op2_type op2_kind:$rs2),
3566                         (mask_type V0),
3567                         VLOpFrag)),
3568                         (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX#"_TU")
3569                         (result_type result_reg_class:$merge),
3570                         (op1_type op1_reg_class:$rs1),
3571                         (op2_type op2_kind:$rs2),
3572                         (mask_type V0), GPR:$vl, sew)>;
3573}
3574
3575multiclass VPatBinaryCarryIn<string intrinsic,
3576                             string inst,
3577                             string kind,
3578                             ValueType result_type,
3579                             ValueType op1_type,
3580                             ValueType op2_type,
3581                             ValueType mask_type,
3582                             int sew,
3583                             LMULInfo vlmul,
3584                             VReg op1_reg_class,
3585                             DAGOperand op2_kind>
3586{
3587  def : Pat<(result_type (!cast<Intrinsic>(intrinsic)
3588                         (op1_type op1_reg_class:$rs1),
3589                         (op2_type op2_kind:$rs2),
3590                         (mask_type V0),
3591                         VLOpFrag)),
3592                         (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX)
3593                         (op1_type op1_reg_class:$rs1),
3594                         (op2_type op2_kind:$rs2),
3595                         (mask_type V0), GPR:$vl, sew)>;
3596}
3597
3598multiclass VPatBinaryMaskOut<string intrinsic,
3599                             string inst,
3600                             string kind,
3601                             ValueType result_type,
3602                             ValueType op1_type,
3603                             ValueType op2_type,
3604                             int sew,
3605                             LMULInfo vlmul,
3606                             VReg op1_reg_class,
3607                             DAGOperand op2_kind>
3608{
3609  def : Pat<(result_type (!cast<Intrinsic>(intrinsic)
3610                         (op1_type op1_reg_class:$rs1),
3611                         (op2_type op2_kind:$rs2),
3612                         VLOpFrag)),
3613                         (!cast<Instruction>(inst#"_"#kind#"_"#vlmul.MX)
3614                         (op1_type op1_reg_class:$rs1),
3615                         (op2_type op2_kind:$rs2),
3616                         GPR:$vl, sew)>;
3617}
3618
3619multiclass VPatConversionTA<string intrinsic,
3620                            string inst,
3621                            string kind,
3622                            ValueType result_type,
3623                            ValueType op1_type,
3624                            ValueType mask_type,
3625                            int sew,
3626                            LMULInfo vlmul,
3627                            VReg result_reg_class,
3628                            VReg op1_reg_class>
3629{
3630  def : VPatUnaryNoMask<intrinsic, inst, kind, result_type, op1_type,
3631                        sew, vlmul, op1_reg_class>;
3632  def : VPatUnaryNoMaskTU<intrinsic, inst, kind, result_type, op1_type,
3633                          sew, vlmul, result_reg_class, op1_reg_class>;
3634  def : VPatUnaryMaskTA<intrinsic, inst, kind, result_type, op1_type,
3635                        mask_type, sew, vlmul, result_reg_class, op1_reg_class>;
3636}
3637
3638multiclass VPatBinaryV_VV<string intrinsic, string instruction,
3639                          list<VTypeInfo> vtilist> {
3640  foreach vti = vtilist in
3641    defm : VPatBinaryTA<intrinsic, instruction # "_VV_" # vti.LMul.MX,
3642                        vti.Vector, vti.Vector, vti.Vector,vti.Mask,
3643                        vti.Log2SEW, vti.RegClass,
3644                        vti.RegClass, vti.RegClass>;
3645}
3646
3647multiclass VPatBinaryV_VV_INT<string intrinsic, string instruction,
3648                          list<VTypeInfo> vtilist> {
3649  foreach vti = vtilist in {
3650    defvar ivti = GetIntVTypeInfo<vti>.Vti;
3651    defm : VPatBinaryTA<intrinsic, instruction # "_VV_" # vti.LMul.MX,
3652                        vti.Vector, vti.Vector, ivti.Vector, vti.Mask,
3653                        vti.Log2SEW, vti.RegClass,
3654                        vti.RegClass, vti.RegClass>;
3655  }
3656}
3657
3658multiclass VPatBinaryV_VV_INT_EEW<string intrinsic, string instruction,
3659                                  int eew, list<VTypeInfo> vtilist> {
3660  foreach vti = vtilist in {
3661    // emul = lmul * eew / sew
3662    defvar vlmul = vti.LMul;
3663    defvar octuple_lmul = vlmul.octuple;
3664    defvar octuple_emul = !srl(!mul(octuple_lmul, eew), vti.Log2SEW);
3665    if !and(!ge(octuple_emul, 1), !le(octuple_emul, 64)) then {
3666      defvar emul_str = octuple_to_str<octuple_emul>.ret;
3667      defvar ivti = !cast<VTypeInfo>("VI" # eew # emul_str);
3668      defvar inst = instruction # "_VV_" # vti.LMul.MX # "_" # emul_str;
3669      defm : VPatBinaryTA<intrinsic, inst,
3670                          vti.Vector, vti.Vector, ivti.Vector, vti.Mask,
3671                          vti.Log2SEW, vti.RegClass,
3672                          vti.RegClass, ivti.RegClass>;
3673    }
3674  }
3675}
3676
3677multiclass VPatBinaryV_VX<string intrinsic, string instruction,
3678                          list<VTypeInfo> vtilist> {
3679  foreach vti = vtilist in {
3680    defvar kind = "V"#vti.ScalarSuffix;
3681    defm : VPatBinaryTA<intrinsic, instruction#"_"#kind#"_"#vti.LMul.MX,
3682                        vti.Vector, vti.Vector, vti.Scalar, vti.Mask,
3683                        vti.Log2SEW, vti.RegClass,
3684                        vti.RegClass, vti.ScalarRegClass>;
3685  }
3686}
3687
3688multiclass VPatBinaryV_VX_INT<string intrinsic, string instruction,
3689                          list<VTypeInfo> vtilist> {
3690  foreach vti = vtilist in
3691    defm : VPatBinaryTA<intrinsic, instruction # "_VX_" # vti.LMul.MX,
3692                        vti.Vector, vti.Vector, XLenVT, vti.Mask,
3693                        vti.Log2SEW, vti.RegClass,
3694                        vti.RegClass, GPR>;
3695}
3696
3697multiclass VPatBinaryV_VI<string intrinsic, string instruction,
3698                          list<VTypeInfo> vtilist, Operand imm_type> {
3699  foreach vti = vtilist in
3700    defm : VPatBinaryTA<intrinsic, instruction # "_VI_" # vti.LMul.MX,
3701                        vti.Vector, vti.Vector, XLenVT, vti.Mask,
3702                        vti.Log2SEW, vti.RegClass,
3703                        vti.RegClass, imm_type>;
3704}
3705
3706multiclass VPatBinaryM_MM<string intrinsic, string instruction> {
3707  foreach mti = AllMasks in
3708    def : VPatBinaryM<intrinsic, instruction # "_MM_" # mti.LMul.MX,
3709                      mti.Mask, mti.Mask, mti.Mask,
3710                      mti.Log2SEW, VR, VR>;
3711}
3712
3713multiclass VPatBinaryW_VV<string intrinsic, string instruction,
3714                          list<VTypeInfoToWide> vtilist> {
3715  foreach VtiToWti = vtilist in {
3716    defvar Vti = VtiToWti.Vti;
3717    defvar Wti = VtiToWti.Wti;
3718    defm : VPatBinaryTA<intrinsic, instruction # "_VV_" # Vti.LMul.MX,
3719                        Wti.Vector, Vti.Vector, Vti.Vector, Vti.Mask,
3720                        Vti.Log2SEW, Wti.RegClass,
3721                        Vti.RegClass, Vti.RegClass>;
3722  }
3723}
3724
3725multiclass VPatBinaryW_VX<string intrinsic, string instruction,
3726                          list<VTypeInfoToWide> vtilist> {
3727  foreach VtiToWti = vtilist in {
3728    defvar Vti = VtiToWti.Vti;
3729    defvar Wti = VtiToWti.Wti;
3730    defvar kind = "V"#Vti.ScalarSuffix;
3731    defm : VPatBinaryTA<intrinsic, instruction#"_"#kind#"_"#Vti.LMul.MX,
3732                        Wti.Vector, Vti.Vector, Vti.Scalar, Vti.Mask,
3733                        Vti.Log2SEW, Wti.RegClass,
3734                        Vti.RegClass, Vti.ScalarRegClass>;
3735  }
3736}
3737
3738multiclass VPatBinaryW_WV<string intrinsic, string instruction,
3739                          list<VTypeInfoToWide> vtilist> {
3740  foreach VtiToWti = vtilist in {
3741    defvar Vti = VtiToWti.Vti;
3742    defvar Wti = VtiToWti.Wti;
3743    def : VPatTiedBinaryNoMask<intrinsic, instruction # "_WV_" # Vti.LMul.MX,
3744                               Wti.Vector, Vti.Vector,
3745                               Vti.Log2SEW, Wti.RegClass, Vti.RegClass>;
3746    def : VPatBinaryNoMaskTU<intrinsic, instruction # "_WV_" # Vti.LMul.MX,
3747                             Wti.Vector, Wti.Vector, Vti.Vector, Vti.Log2SEW,
3748                             Wti.RegClass, Wti.RegClass, Vti.RegClass>;
3749    let AddedComplexity = 1 in {
3750    def : VPatTiedBinaryNoMaskTU<intrinsic, instruction # "_WV_" # Vti.LMul.MX,
3751                                 Wti.Vector, Vti.Vector,
3752                                 Vti.Log2SEW, Wti.RegClass, Vti.RegClass>;
3753    def : VPatTiedBinaryMask<intrinsic, instruction # "_WV_" # Vti.LMul.MX,
3754                             Wti.Vector, Vti.Vector, Vti.Mask,
3755                             Vti.Log2SEW, Wti.RegClass, Vti.RegClass>;
3756    }
3757    def : VPatBinaryMaskTA<intrinsic, instruction # "_WV_" # Vti.LMul.MX,
3758                           Wti.Vector, Wti.Vector, Vti.Vector, Vti.Mask,
3759                           Vti.Log2SEW, Wti.RegClass,
3760                           Wti.RegClass, Vti.RegClass>;
3761  }
3762}
3763
3764multiclass VPatBinaryW_WX<string intrinsic, string instruction,
3765                          list<VTypeInfoToWide> vtilist> {
3766  foreach VtiToWti = vtilist in {
3767    defvar Vti = VtiToWti.Vti;
3768    defvar Wti = VtiToWti.Wti;
3769    defvar kind = "W"#Vti.ScalarSuffix;
3770    defm : VPatBinaryTA<intrinsic, instruction#"_"#kind#"_"#Vti.LMul.MX,
3771                        Wti.Vector, Wti.Vector, Vti.Scalar, Vti.Mask,
3772                        Vti.Log2SEW, Wti.RegClass,
3773                        Wti.RegClass, Vti.ScalarRegClass>;
3774  }
3775}
3776
3777multiclass VPatBinaryV_WV<string intrinsic, string instruction,
3778                          list<VTypeInfoToWide> vtilist> {
3779  foreach VtiToWti = vtilist in {
3780    defvar Vti = VtiToWti.Vti;
3781    defvar Wti = VtiToWti.Wti;
3782    defm : VPatBinaryTA<intrinsic, instruction # "_WV_" # Vti.LMul.MX,
3783                        Vti.Vector, Wti.Vector, Vti.Vector, Vti.Mask,
3784                        Vti.Log2SEW, Vti.RegClass,
3785                        Wti.RegClass, Vti.RegClass>;
3786  }
3787}
3788
3789multiclass VPatBinaryV_WX<string intrinsic, string instruction,
3790                          list<VTypeInfoToWide> vtilist> {
3791  foreach VtiToWti = vtilist in {
3792    defvar Vti = VtiToWti.Vti;
3793    defvar Wti = VtiToWti.Wti;
3794    defvar kind = "W"#Vti.ScalarSuffix;
3795    defm : VPatBinaryTA<intrinsic, instruction#"_"#kind#"_"#Vti.LMul.MX,
3796                        Vti.Vector, Wti.Vector, Vti.Scalar, Vti.Mask,
3797                        Vti.Log2SEW, Vti.RegClass,
3798                        Wti.RegClass, Vti.ScalarRegClass>;
3799  }
3800}
3801
3802multiclass VPatBinaryV_WI<string intrinsic, string instruction,
3803                          list<VTypeInfoToWide> vtilist> {
3804  foreach VtiToWti = vtilist in {
3805    defvar Vti = VtiToWti.Vti;
3806    defvar Wti = VtiToWti.Wti;
3807    defm : VPatBinaryTA<intrinsic, instruction # "_WI_" # Vti.LMul.MX,
3808                        Vti.Vector, Wti.Vector, XLenVT, Vti.Mask,
3809                        Vti.Log2SEW, Vti.RegClass,
3810                        Wti.RegClass, uimm5>;
3811  }
3812}
3813
3814multiclass VPatBinaryV_VM<string intrinsic, string instruction,
3815                          bit CarryOut = 0,
3816                          list<VTypeInfo> vtilist = AllIntegerVectors> {
3817  foreach vti = vtilist in
3818    defm : VPatBinaryCarryIn<intrinsic, instruction, "VVM",
3819                             !if(CarryOut, vti.Mask, vti.Vector),
3820                             vti.Vector, vti.Vector, vti.Mask,
3821                             vti.Log2SEW, vti.LMul,
3822                             vti.RegClass, vti.RegClass>;
3823}
3824
3825multiclass VPatBinaryV_XM<string intrinsic, string instruction,
3826                          bit CarryOut = 0,
3827                          list<VTypeInfo> vtilist = AllIntegerVectors> {
3828  foreach vti = vtilist in
3829    defm : VPatBinaryCarryIn<intrinsic, instruction,
3830                             "V"#vti.ScalarSuffix#"M",
3831                             !if(CarryOut, vti.Mask, vti.Vector),
3832                             vti.Vector, vti.Scalar, vti.Mask,
3833                             vti.Log2SEW, vti.LMul,
3834                             vti.RegClass, vti.ScalarRegClass>;
3835}
3836
3837multiclass VPatBinaryV_IM<string intrinsic, string instruction,
3838                          bit CarryOut = 0> {
3839  foreach vti = AllIntegerVectors in
3840    defm : VPatBinaryCarryIn<intrinsic, instruction, "VIM",
3841                             !if(CarryOut, vti.Mask, vti.Vector),
3842                             vti.Vector, XLenVT, vti.Mask,
3843                             vti.Log2SEW, vti.LMul,
3844                             vti.RegClass, simm5>;
3845}
3846
3847multiclass VPatBinaryV_VM_TAIL<string intrinsic, string instruction,
3848                               bit CarryOut = 0,
3849                               list<VTypeInfo> vtilist = AllIntegerVectors> {
3850  foreach vti = vtilist in
3851    defm : VPatBinaryCarryInTAIL<intrinsic, instruction, "VVM",
3852                                 !if(CarryOut, vti.Mask, vti.Vector),
3853                                 vti.Vector, vti.Vector, vti.Mask,
3854                                 vti.Log2SEW, vti.LMul, vti.RegClass,
3855                                 vti.RegClass, vti.RegClass>;
3856}
3857
3858multiclass VPatBinaryV_XM_TAIL<string intrinsic, string instruction,
3859                               bit CarryOut = 0,
3860                               list<VTypeInfo> vtilist = AllIntegerVectors> {
3861  foreach vti = vtilist in
3862    defm : VPatBinaryCarryInTAIL<intrinsic, instruction,
3863                                 "V"#vti.ScalarSuffix#"M",
3864                                 !if(CarryOut, vti.Mask, vti.Vector),
3865                                 vti.Vector, vti.Scalar, vti.Mask,
3866                                 vti.Log2SEW, vti.LMul, vti.RegClass,
3867                                 vti.RegClass, vti.ScalarRegClass>;
3868}
3869
3870multiclass VPatBinaryV_IM_TAIL<string intrinsic, string instruction,
3871                               bit CarryOut = 0> {
3872  foreach vti = AllIntegerVectors in
3873    defm : VPatBinaryCarryInTAIL<intrinsic, instruction, "VIM",
3874                                 !if(CarryOut, vti.Mask, vti.Vector),
3875                                 vti.Vector, XLenVT, vti.Mask,
3876                                 vti.Log2SEW, vti.LMul,
3877                                 vti.RegClass, vti.RegClass, simm5>;
3878}
3879
3880multiclass VPatBinaryV_V<string intrinsic, string instruction> {
3881  foreach vti = AllIntegerVectors in
3882    defm : VPatBinaryMaskOut<intrinsic, instruction, "VV",
3883                             vti.Mask, vti.Vector, vti.Vector,
3884                             vti.Log2SEW, vti.LMul,
3885                             vti.RegClass, vti.RegClass>;
3886}
3887
3888multiclass VPatBinaryV_X<string intrinsic, string instruction> {
3889  foreach vti = AllIntegerVectors in
3890    defm : VPatBinaryMaskOut<intrinsic, instruction, "VX",
3891                             vti.Mask, vti.Vector, XLenVT,
3892                             vti.Log2SEW, vti.LMul,
3893                             vti.RegClass, GPR>;
3894}
3895
3896multiclass VPatBinaryV_I<string intrinsic, string instruction> {
3897  foreach vti = AllIntegerVectors in
3898    defm : VPatBinaryMaskOut<intrinsic, instruction, "VI",
3899                             vti.Mask, vti.Vector, XLenVT,
3900                             vti.Log2SEW, vti.LMul,
3901                             vti.RegClass, simm5>;
3902}
3903
3904multiclass VPatBinaryM_VV<string intrinsic, string instruction,
3905                          list<VTypeInfo> vtilist> {
3906  foreach vti = vtilist in
3907    defm : VPatBinaryM<intrinsic, instruction # "_VV_" # vti.LMul.MX,
3908                       vti.Mask, vti.Vector, vti.Vector, vti.Mask,
3909                       vti.Log2SEW, VR,
3910                       vti.RegClass, vti.RegClass>;
3911}
3912
3913multiclass VPatBinarySwappedM_VV<string intrinsic, string instruction,
3914                                 list<VTypeInfo> vtilist> {
3915  foreach vti = vtilist in
3916    defm : VPatBinarySwapped<intrinsic, instruction # "_VV_" # vti.LMul.MX,
3917                             vti.Mask, vti.Vector, vti.Vector, vti.Mask,
3918                             vti.Log2SEW, VR,
3919                             vti.RegClass, vti.RegClass>;
3920}
3921
3922multiclass VPatBinaryM_VX<string intrinsic, string instruction,
3923                          list<VTypeInfo> vtilist> {
3924  foreach vti = vtilist in {
3925    defvar kind = "V"#vti.ScalarSuffix;
3926    defm : VPatBinaryM<intrinsic, instruction#"_"#kind#"_"#vti.LMul.MX,
3927                       vti.Mask, vti.Vector, vti.Scalar, vti.Mask,
3928                       vti.Log2SEW, VR,
3929                       vti.RegClass, vti.ScalarRegClass>;
3930  }
3931}
3932
3933multiclass VPatBinaryM_VI<string intrinsic, string instruction,
3934                          list<VTypeInfo> vtilist> {
3935  foreach vti = vtilist in
3936    defm : VPatBinaryM<intrinsic, instruction # "_VI_" # vti.LMul.MX,
3937                       vti.Mask, vti.Vector, XLenVT, vti.Mask,
3938                       vti.Log2SEW, VR,
3939                       vti.RegClass, simm5>;
3940}
3941
3942multiclass VPatBinaryV_VV_VX_VI<string intrinsic, string instruction,
3943                                list<VTypeInfo> vtilist, Operand ImmType = simm5>
3944    : VPatBinaryV_VV<intrinsic, instruction, vtilist>,
3945      VPatBinaryV_VX<intrinsic, instruction, vtilist>,
3946      VPatBinaryV_VI<intrinsic, instruction, vtilist, ImmType>;
3947
3948multiclass VPatBinaryV_VV_VX<string intrinsic, string instruction,
3949                             list<VTypeInfo> vtilist>
3950    : VPatBinaryV_VV<intrinsic, instruction, vtilist>,
3951      VPatBinaryV_VX<intrinsic, instruction, vtilist>;
3952
3953multiclass VPatBinaryV_VX_VI<string intrinsic, string instruction,
3954                             list<VTypeInfo> vtilist>
3955    : VPatBinaryV_VX<intrinsic, instruction, vtilist>,
3956      VPatBinaryV_VI<intrinsic, instruction, vtilist, simm5>;
3957
3958multiclass VPatBinaryW_VV_VX<string intrinsic, string instruction,
3959                             list<VTypeInfoToWide> vtilist>
3960    : VPatBinaryW_VV<intrinsic, instruction, vtilist>,
3961      VPatBinaryW_VX<intrinsic, instruction, vtilist>;
3962
3963multiclass VPatBinaryW_WV_WX<string intrinsic, string instruction,
3964                             list<VTypeInfoToWide> vtilist>
3965    : VPatBinaryW_WV<intrinsic, instruction, vtilist>,
3966      VPatBinaryW_WX<intrinsic, instruction, vtilist>;
3967
3968multiclass VPatBinaryV_WV_WX_WI<string intrinsic, string instruction,
3969                                list<VTypeInfoToWide> vtilist>
3970    : VPatBinaryV_WV<intrinsic, instruction, vtilist>,
3971      VPatBinaryV_WX<intrinsic, instruction, vtilist>,
3972      VPatBinaryV_WI<intrinsic, instruction, vtilist>;
3973
3974multiclass VPatBinaryV_VM_XM_IM<string intrinsic, string instruction>
3975    : VPatBinaryV_VM_TAIL<intrinsic, instruction>,
3976      VPatBinaryV_XM_TAIL<intrinsic, instruction>,
3977      VPatBinaryV_IM_TAIL<intrinsic, instruction>;
3978
3979multiclass VPatBinaryM_VM_XM_IM<string intrinsic, string instruction>
3980    : VPatBinaryV_VM<intrinsic, instruction, /*CarryOut=*/1>,
3981      VPatBinaryV_XM<intrinsic, instruction, /*CarryOut=*/1>,
3982      VPatBinaryV_IM<intrinsic, instruction, /*CarryOut=*/1>;
3983
3984multiclass VPatBinaryM_V_X_I<string intrinsic, string instruction>
3985    : VPatBinaryV_V<intrinsic, instruction>,
3986      VPatBinaryV_X<intrinsic, instruction>,
3987      VPatBinaryV_I<intrinsic, instruction>;
3988
3989multiclass VPatBinaryV_VM_XM<string intrinsic, string instruction>
3990    : VPatBinaryV_VM_TAIL<intrinsic, instruction>,
3991      VPatBinaryV_XM_TAIL<intrinsic, instruction>;
3992
3993multiclass VPatBinaryM_VM_XM<string intrinsic, string instruction>
3994    : VPatBinaryV_VM<intrinsic, instruction, /*CarryOut=*/1>,
3995      VPatBinaryV_XM<intrinsic, instruction, /*CarryOut=*/1>;
3996
3997multiclass VPatBinaryM_V_X<string intrinsic, string instruction>
3998    : VPatBinaryV_V<intrinsic, instruction>,
3999      VPatBinaryV_X<intrinsic, instruction>;
4000
4001multiclass VPatTernary<string intrinsic,
4002                       string inst,
4003                       string kind,
4004                       ValueType result_type,
4005                       ValueType op1_type,
4006                       ValueType op2_type,
4007                       ValueType mask_type,
4008                       int sew,
4009                       LMULInfo vlmul,
4010                       VReg result_reg_class,
4011                       RegisterClass op1_reg_class,
4012                       DAGOperand op2_kind> {
4013  def : VPatTernaryNoMask<intrinsic, inst, kind, result_type, op1_type, op2_type,
4014                          sew, vlmul, result_reg_class, op1_reg_class,
4015                          op2_kind>;
4016  def : VPatTernaryMask<intrinsic, inst, kind, result_type, op1_type, op2_type,
4017                        mask_type, sew, vlmul, result_reg_class, op1_reg_class,
4018                        op2_kind>;
4019}
4020
4021multiclass VPatTernaryNoMaskNoPolicy<string intrinsic,
4022                                     string inst,
4023                                     string kind,
4024                                     ValueType result_type,
4025                                     ValueType op1_type,
4026                                     ValueType op2_type,
4027                                     ValueType mask_type,
4028                                     int sew,
4029                                     LMULInfo vlmul,
4030                                     VReg result_reg_class,
4031                                     RegisterClass op1_reg_class,
4032                                     DAGOperand op2_kind> {
4033  def : VPatTernaryNoMask<intrinsic, inst, kind, result_type, op1_type, op2_type,
4034                          sew, vlmul, result_reg_class, op1_reg_class,
4035                          op2_kind>;
4036  def : VPatTernaryMaskPolicy<intrinsic, inst, kind, result_type, op1_type, op2_type,
4037                              mask_type, sew, vlmul, result_reg_class, op1_reg_class,
4038                              op2_kind>;
4039}
4040
4041multiclass VPatTernaryWithPolicy<string intrinsic,
4042                                 string inst,
4043                                 string kind,
4044                                 ValueType result_type,
4045                                 ValueType op1_type,
4046                                 ValueType op2_type,
4047                                 ValueType mask_type,
4048                                 int sew,
4049                                 LMULInfo vlmul,
4050                                 VReg result_reg_class,
4051                                 RegisterClass op1_reg_class,
4052                                 DAGOperand op2_kind> {
4053  def : VPatTernaryNoMaskWithPolicy<intrinsic, inst, kind, result_type, op1_type,
4054                                    op2_type, sew, vlmul, result_reg_class,
4055                                    op1_reg_class, op2_kind>;
4056  def : VPatTernaryMaskPolicy<intrinsic, inst, kind, result_type, op1_type, op2_type,
4057                              mask_type, sew, vlmul, result_reg_class, op1_reg_class,
4058                              op2_kind>;
4059}
4060
4061multiclass VPatTernaryV_VV_AAXA<string intrinsic, string instruction,
4062                                list<VTypeInfo> vtilist> {
4063  foreach vti = vtilist in
4064    defm : VPatTernaryWithPolicy<intrinsic, instruction, "VV",
4065                                 vti.Vector, vti.Vector, vti.Vector, vti.Mask,
4066                                 vti.Log2SEW, vti.LMul, vti.RegClass,
4067                                 vti.RegClass, vti.RegClass>;
4068}
4069
4070multiclass VPatTernaryV_VX<string intrinsic, string instruction,
4071                           list<VTypeInfo> vtilist> {
4072  foreach vti = vtilist in
4073    defm : VPatTernaryWithPolicy<intrinsic, instruction, "VX",
4074                                 vti.Vector, vti.Vector, XLenVT, vti.Mask,
4075                                 vti.Log2SEW, vti.LMul, vti.RegClass,
4076                                 vti.RegClass, GPR>;
4077}
4078
4079multiclass VPatTernaryV_VX_AAXA<string intrinsic, string instruction,
4080                           list<VTypeInfo> vtilist> {
4081  foreach vti = vtilist in
4082    defm : VPatTernaryWithPolicy<intrinsic, instruction,
4083                                 "V"#vti.ScalarSuffix,
4084                                 vti.Vector, vti.Scalar, vti.Vector, vti.Mask,
4085                                 vti.Log2SEW, vti.LMul, vti.RegClass,
4086                                 vti.ScalarRegClass, vti.RegClass>;
4087}
4088
4089multiclass VPatTernaryV_VI<string intrinsic, string instruction,
4090                           list<VTypeInfo> vtilist, Operand Imm_type> {
4091  foreach vti = vtilist in
4092    defm : VPatTernaryWithPolicy<intrinsic, instruction, "VI",
4093                                 vti.Vector, vti.Vector, XLenVT, vti.Mask,
4094                                 vti.Log2SEW, vti.LMul, vti.RegClass,
4095                                 vti.RegClass, Imm_type>;
4096}
4097
4098multiclass VPatTernaryW_VV<string intrinsic, string instruction,
4099                           list<VTypeInfoToWide> vtilist> {
4100  foreach vtiToWti = vtilist in {
4101    defvar vti = vtiToWti.Vti;
4102    defvar wti = vtiToWti.Wti;
4103    defm : VPatTernaryWithPolicy<intrinsic, instruction, "VV",
4104                                 wti.Vector, vti.Vector, vti.Vector,
4105                                 vti.Mask, vti.Log2SEW, vti.LMul,
4106                                 wti.RegClass, vti.RegClass, vti.RegClass>;
4107  }
4108}
4109
4110multiclass VPatTernaryW_VX<string intrinsic, string instruction,
4111                           list<VTypeInfoToWide> vtilist> {
4112  foreach vtiToWti = vtilist in {
4113    defvar vti = vtiToWti.Vti;
4114    defvar wti = vtiToWti.Wti;
4115    defm : VPatTernaryWithPolicy<intrinsic, instruction,
4116                                 "V"#vti.ScalarSuffix,
4117                                 wti.Vector, vti.Scalar, vti.Vector,
4118                                 vti.Mask, vti.Log2SEW, vti.LMul,
4119                                 wti.RegClass, vti.ScalarRegClass, vti.RegClass>;
4120  }
4121}
4122
4123multiclass VPatTernaryV_VV_VX_AAXA<string intrinsic, string instruction,
4124                              list<VTypeInfo> vtilist>
4125    : VPatTernaryV_VV_AAXA<intrinsic, instruction, vtilist>,
4126      VPatTernaryV_VX_AAXA<intrinsic, instruction, vtilist>;
4127
4128multiclass VPatTernaryV_VX_VI<string intrinsic, string instruction,
4129                              list<VTypeInfo> vtilist, Operand Imm_type = simm5>
4130    : VPatTernaryV_VX<intrinsic, instruction, vtilist>,
4131      VPatTernaryV_VI<intrinsic, instruction, vtilist, Imm_type>;
4132
4133
4134multiclass VPatBinaryM_VV_VX_VI<string intrinsic, string instruction,
4135                                list<VTypeInfo> vtilist>
4136    : VPatBinaryM_VV<intrinsic, instruction, vtilist>,
4137      VPatBinaryM_VX<intrinsic, instruction, vtilist>,
4138      VPatBinaryM_VI<intrinsic, instruction, vtilist>;
4139
4140multiclass VPatTernaryW_VV_VX<string intrinsic, string instruction,
4141                              list<VTypeInfoToWide> vtilist>
4142    : VPatTernaryW_VV<intrinsic, instruction, vtilist>,
4143      VPatTernaryW_VX<intrinsic, instruction, vtilist>;
4144
4145multiclass VPatBinaryM_VV_VX<string intrinsic, string instruction,
4146                             list<VTypeInfo> vtilist>
4147    : VPatBinaryM_VV<intrinsic, instruction, vtilist>,
4148      VPatBinaryM_VX<intrinsic, instruction, vtilist>;
4149
4150multiclass VPatBinaryM_VX_VI<string intrinsic, string instruction,
4151                             list<VTypeInfo> vtilist>
4152    : VPatBinaryM_VX<intrinsic, instruction, vtilist>,
4153      VPatBinaryM_VI<intrinsic, instruction, vtilist>;
4154
4155multiclass VPatBinaryV_VV_VX_VI_INT<string intrinsic, string instruction,
4156                                    list<VTypeInfo> vtilist, Operand ImmType = simm5>
4157    : VPatBinaryV_VV_INT<intrinsic#"_vv", instruction, vtilist>,
4158      VPatBinaryV_VX_INT<intrinsic#"_vx", instruction, vtilist>,
4159      VPatBinaryV_VI<intrinsic#"_vx", instruction, vtilist, ImmType>;
4160
4161multiclass VPatReductionV_VS<string intrinsic, string instruction, bit IsFloat = 0> {
4162  foreach vti = !if(IsFloat, NoGroupFloatVectors, NoGroupIntegerVectors) in
4163  {
4164    defvar vectorM1 = !cast<VTypeInfo>(!if(IsFloat, "VF", "VI") # vti.SEW # "M1");
4165    defm : VPatTernary<intrinsic, instruction, "VS",
4166                       vectorM1.Vector, vti.Vector,
4167                       vectorM1.Vector, vti.Mask,
4168                       vti.Log2SEW, vti.LMul,
4169                       VR, vti.RegClass, VR>;
4170  }
4171  foreach gvti = !if(IsFloat, GroupFloatVectors, GroupIntegerVectors) in
4172  {
4173    defm : VPatTernary<intrinsic, instruction, "VS",
4174                       gvti.VectorM1, gvti.Vector,
4175                       gvti.VectorM1, gvti.Mask,
4176                       gvti.Log2SEW, gvti.LMul,
4177                       VR, gvti.RegClass, VR>;
4178  }
4179}
4180
4181multiclass VPatReductionW_VS<string intrinsic, string instruction, bit IsFloat = 0> {
4182  foreach vti = !if(IsFloat, AllFloatVectors, AllIntegerVectors) in
4183  {
4184    defvar wtiSEW = !mul(vti.SEW, 2);
4185    if !le(wtiSEW, 64) then {
4186      defvar wtiM1 = !cast<VTypeInfo>(!if(IsFloat, "VF", "VI") # wtiSEW # "M1");
4187      defm : VPatTernary<intrinsic, instruction, "VS",
4188                         wtiM1.Vector, vti.Vector,
4189                         wtiM1.Vector, vti.Mask,
4190                         vti.Log2SEW, vti.LMul,
4191                         wtiM1.RegClass, vti.RegClass,
4192                         wtiM1.RegClass>;
4193    }
4194  }
4195}
4196
4197multiclass VPatConversionVI_VF<string intrinsic,
4198                               string instruction>
4199{
4200  foreach fvti = AllFloatVectors in
4201  {
4202    defvar ivti = GetIntVTypeInfo<fvti>.Vti;
4203
4204    defm : VPatConversionTA<intrinsic, instruction, "V",
4205                            ivti.Vector, fvti.Vector, ivti.Mask, fvti.Log2SEW,
4206                            fvti.LMul, ivti.RegClass, fvti.RegClass>;
4207  }
4208}
4209
4210multiclass VPatConversionVF_VI<string intrinsic,
4211                               string instruction>
4212{
4213  foreach fvti = AllFloatVectors in
4214  {
4215    defvar ivti = GetIntVTypeInfo<fvti>.Vti;
4216
4217    defm : VPatConversionTA<intrinsic, instruction, "V",
4218                            fvti.Vector, ivti.Vector, fvti.Mask, ivti.Log2SEW,
4219                            ivti.LMul, fvti.RegClass, ivti.RegClass>;
4220  }
4221}
4222
4223multiclass VPatConversionWI_VF<string intrinsic, string instruction> {
4224  foreach fvtiToFWti = AllWidenableFloatVectors in
4225  {
4226    defvar fvti = fvtiToFWti.Vti;
4227    defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti;
4228
4229    defm : VPatConversionTA<intrinsic, instruction, "V",
4230                            iwti.Vector, fvti.Vector, iwti.Mask, fvti.Log2SEW,
4231                            fvti.LMul, iwti.RegClass, fvti.RegClass>;
4232  }
4233}
4234
4235multiclass VPatConversionWF_VI<string intrinsic, string instruction> {
4236  foreach vtiToWti = AllWidenableIntToFloatVectors in
4237  {
4238    defvar vti = vtiToWti.Vti;
4239    defvar fwti = vtiToWti.Wti;
4240
4241    defm : VPatConversionTA<intrinsic, instruction, "V",
4242                            fwti.Vector, vti.Vector, fwti.Mask, vti.Log2SEW,
4243                            vti.LMul, fwti.RegClass, vti.RegClass>;
4244  }
4245}
4246
4247multiclass VPatConversionWF_VF <string intrinsic, string instruction> {
4248  foreach fvtiToFWti = AllWidenableFloatVectors in
4249  {
4250    defvar fvti = fvtiToFWti.Vti;
4251    defvar fwti = fvtiToFWti.Wti;
4252
4253    defm : VPatConversionTA<intrinsic, instruction, "V",
4254                            fwti.Vector, fvti.Vector, fwti.Mask, fvti.Log2SEW,
4255                            fvti.LMul, fwti.RegClass, fvti.RegClass>;
4256  }
4257}
4258
4259multiclass VPatConversionVI_WF <string intrinsic, string instruction> {
4260  foreach vtiToWti = AllWidenableIntToFloatVectors in
4261  {
4262    defvar vti = vtiToWti.Vti;
4263    defvar fwti = vtiToWti.Wti;
4264
4265    defm : VPatConversionTA<intrinsic, instruction, "W",
4266                            vti.Vector, fwti.Vector, vti.Mask, vti.Log2SEW,
4267                            vti.LMul, vti.RegClass, fwti.RegClass>;
4268  }
4269}
4270
4271multiclass VPatConversionVF_WI <string intrinsic, string instruction> {
4272  foreach fvtiToFWti = AllWidenableFloatVectors in
4273  {
4274    defvar fvti = fvtiToFWti.Vti;
4275    defvar iwti = GetIntVTypeInfo<fvtiToFWti.Wti>.Vti;
4276
4277    defm : VPatConversionTA<intrinsic, instruction, "W",
4278                            fvti.Vector, iwti.Vector, fvti.Mask, fvti.Log2SEW,
4279                            fvti.LMul, fvti.RegClass, iwti.RegClass>;
4280  }
4281}
4282
4283multiclass VPatConversionVF_WF <string intrinsic, string instruction> {
4284  foreach fvtiToFWti = AllWidenableFloatVectors in
4285  {
4286    defvar fvti = fvtiToFWti.Vti;
4287    defvar fwti = fvtiToFWti.Wti;
4288
4289    defm : VPatConversionTA<intrinsic, instruction, "W",
4290                            fvti.Vector, fwti.Vector, fvti.Mask, fvti.Log2SEW,
4291                            fvti.LMul, fvti.RegClass, fwti.RegClass>;
4292  }
4293}
4294
4295multiclass VPatCompare_VI<string intrinsic, string inst,
4296                          ImmLeaf ImmType> {
4297  foreach vti = AllIntegerVectors in {
4298    defvar Intr = !cast<Intrinsic>(intrinsic);
4299    defvar Pseudo = !cast<Instruction>(inst#"_VI_"#vti.LMul.MX);
4300    def : Pat<(vti.Mask (Intr (vti.Vector vti.RegClass:$rs1),
4301                              (vti.Scalar ImmType:$rs2),
4302                              VLOpFrag)),
4303              (Pseudo vti.RegClass:$rs1, (DecImm ImmType:$rs2),
4304                      GPR:$vl, vti.Log2SEW)>;
4305    defvar IntrMask = !cast<Intrinsic>(intrinsic # "_mask");
4306    defvar PseudoMask = !cast<Instruction>(inst#"_VI_"#vti.LMul.MX#"_MASK");
4307    def : Pat<(vti.Mask (IntrMask (vti.Mask VR:$merge),
4308                                  (vti.Vector vti.RegClass:$rs1),
4309                                  (vti.Scalar ImmType:$rs2),
4310                                  (vti.Mask V0),
4311                                  VLOpFrag)),
4312              (PseudoMask VR:$merge, vti.RegClass:$rs1, (DecImm ImmType:$rs2),
4313                          (vti.Mask V0), GPR:$vl, vti.Log2SEW)>;
4314  }
4315}
4316
4317//===----------------------------------------------------------------------===//
4318// Pseudo instructions
4319//===----------------------------------------------------------------------===//
4320
4321let Predicates = [HasVInstructions] in {
4322
4323//===----------------------------------------------------------------------===//
4324// Pseudo Instructions for CodeGen
4325//===----------------------------------------------------------------------===//
4326let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
4327  def PseudoVMV1R_V : VPseudo<VMV1R_V, V_M1, (outs VR:$vd), (ins VR:$vs2)>;
4328  def PseudoVMV2R_V : VPseudo<VMV2R_V, V_M2, (outs VRM2:$vd), (ins VRM2:$vs2)>;
4329  def PseudoVMV4R_V : VPseudo<VMV4R_V, V_M4, (outs VRM4:$vd), (ins VRM4:$vs2)>;
4330  def PseudoVMV8R_V : VPseudo<VMV8R_V, V_M8, (outs VRM8:$vd), (ins VRM8:$vs2)>;
4331}
4332
4333let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 1 in {
4334  def PseudoReadVLENB : Pseudo<(outs GPR:$rd), (ins),
4335                               [(set GPR:$rd, (riscv_read_vlenb))]>;
4336}
4337
4338let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isCodeGenOnly = 1,
4339    Uses = [VL] in
4340def PseudoReadVL : Pseudo<(outs GPR:$rd), (ins), []>;
4341
4342let hasSideEffects = 0, mayLoad = 0, mayStore = 1, isCodeGenOnly = 1 in {
4343  def PseudoVSPILL_M1 : VPseudo<VS1R_V, V_M1, (outs), (ins VR:$rs1, GPR:$rs2)>;
4344  def PseudoVSPILL_M2 : VPseudo<VS2R_V, V_M2, (outs), (ins VRM2:$rs1, GPR:$rs2)>;
4345  def PseudoVSPILL_M4 : VPseudo<VS4R_V, V_M4, (outs), (ins VRM4:$rs1, GPR:$rs2)>;
4346  def PseudoVSPILL_M8 : VPseudo<VS8R_V, V_M8, (outs), (ins VRM8:$rs1, GPR:$rs2)>;
4347}
4348
4349let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 1 in {
4350  def PseudoVRELOAD_M1 : VPseudo<VL1RE8_V, V_M1, (outs VR:$rs1), (ins GPR:$rs2)>;
4351  def PseudoVRELOAD_M2 : VPseudo<VL2RE8_V, V_M2, (outs VRM2:$rs1), (ins GPR:$rs2)>;
4352  def PseudoVRELOAD_M4 : VPseudo<VL4RE8_V, V_M4, (outs VRM4:$rs1), (ins GPR:$rs2)>;
4353  def PseudoVRELOAD_M8 : VPseudo<VL8RE8_V, V_M8, (outs VRM8:$rs1), (ins GPR:$rs2)>;
4354}
4355
4356foreach lmul = MxList in {
4357  foreach nf = NFSet<lmul>.L in {
4358    defvar vreg = SegRegClass<lmul, nf>.RC;
4359    let hasSideEffects = 0, mayLoad = 0, mayStore = 1, isCodeGenOnly = 1,
4360        Size = !mul(4, !sub(!mul(nf, 2), 1)) in {
4361      def "PseudoVSPILL" # nf # "_" # lmul.MX :
4362        Pseudo<(outs), (ins vreg:$rs1, GPR:$rs2, GPR:$vlenb), []>;
4363    }
4364    let hasSideEffects = 0, mayLoad = 1, mayStore = 0, isCodeGenOnly = 1,
4365        Size = !mul(4, !sub(!mul(nf, 2), 1)) in {
4366      def "PseudoVRELOAD" # nf # "_" # lmul.MX :
4367        Pseudo<(outs vreg:$rs1), (ins GPR:$rs2, GPR:$vlenb), []>;
4368    }
4369  }
4370}
4371
4372//===----------------------------------------------------------------------===//
4373// 6. Configuration-Setting Instructions
4374//===----------------------------------------------------------------------===//
4375
4376// Pseudos.
4377let hasSideEffects = 1, mayLoad = 0, mayStore = 0, Defs = [VL, VTYPE] in {
4378// Due to rs1=X0 having special meaning, we need a GPRNoX0 register class for
4379// the when we aren't using one of the special X0 encodings. Otherwise it could
4380// be accidentally be made X0 by MachineIR optimizations. To satisfy the
4381// verifier, we also need a GPRX0 instruction for the special encodings.
4382def PseudoVSETVLI : Pseudo<(outs GPR:$rd), (ins GPRNoX0:$rs1, VTypeIOp11:$vtypei), []>;
4383def PseudoVSETVLIX0 : Pseudo<(outs GPR:$rd), (ins GPRX0:$rs1, VTypeIOp11:$vtypei), []>;
4384def PseudoVSETIVLI : Pseudo<(outs GPR:$rd), (ins uimm5:$rs1, VTypeIOp10:$vtypei), []>;
4385}
4386
4387//===----------------------------------------------------------------------===//
4388// 7. Vector Loads and Stores
4389//===----------------------------------------------------------------------===//
4390
4391//===----------------------------------------------------------------------===//
4392// 7.4 Vector Unit-Stride Instructions
4393//===----------------------------------------------------------------------===//
4394
4395// Pseudos Unit-Stride Loads and Stores
4396defm PseudoVL : VPseudoUSLoad;
4397defm PseudoVS : VPseudoUSStore;
4398
4399defm PseudoVLM : VPseudoLoadMask,
4400                 Sched<[WriteVLDM, ReadVLDX]>;
4401defm PseudoVSM : VPseudoStoreMask,
4402                 Sched<[WriteVSTM, ReadVSTX]>;
4403
4404//===----------------------------------------------------------------------===//
4405// 7.5 Vector Strided Instructions
4406//===----------------------------------------------------------------------===//
4407
4408// Vector Strided Loads and Stores
4409defm PseudoVLS : VPseudoSLoad;
4410defm PseudoVSS : VPseudoSStore;
4411
4412//===----------------------------------------------------------------------===//
4413// 7.6 Vector Indexed Instructions
4414//===----------------------------------------------------------------------===//
4415
4416// Vector Indexed Loads and Stores
4417defm PseudoVLUX : VPseudoILoad</*Ordered=*/false>;
4418defm PseudoVLOX : VPseudoILoad</*Ordered=*/true>;
4419defm PseudoVSOX : VPseudoIStore</*Ordered=*/true>;
4420defm PseudoVSUX : VPseudoIStore</*Ordered=*/false>;
4421
4422//===----------------------------------------------------------------------===//
4423// 7.7. Unit-stride Fault-Only-First Loads
4424//===----------------------------------------------------------------------===//
4425
4426// vleff may update VL register
4427let hasSideEffects = 1, Defs = [VL] in
4428defm PseudoVL : VPseudoFFLoad;
4429
4430//===----------------------------------------------------------------------===//
4431// 7.8. Vector Load/Store Segment Instructions
4432//===----------------------------------------------------------------------===//
4433defm PseudoVLSEG : VPseudoUSSegLoad;
4434defm PseudoVLSSEG : VPseudoSSegLoad;
4435defm PseudoVLOXSEG : VPseudoISegLoad</*Ordered=*/true>;
4436defm PseudoVLUXSEG : VPseudoISegLoad</*Ordered=*/false>;
4437defm PseudoVSSEG : VPseudoUSSegStore;
4438defm PseudoVSSSEG : VPseudoSSegStore;
4439defm PseudoVSOXSEG : VPseudoISegStore</*Ordered=*/true>;
4440defm PseudoVSUXSEG : VPseudoISegStore</*Ordered=*/false>;
4441
4442// vlseg<nf>e<eew>ff.v may update VL register
4443let hasSideEffects = 1, Defs = [VL] in {
4444defm PseudoVLSEG : VPseudoUSSegLoadFF;
4445}
4446
4447//===----------------------------------------------------------------------===//
4448// 12. Vector Integer Arithmetic Instructions
4449//===----------------------------------------------------------------------===//
4450
4451//===----------------------------------------------------------------------===//
4452// 12.1. Vector Single-Width Integer Add and Subtract
4453//===----------------------------------------------------------------------===//
4454defm PseudoVADD   : VPseudoVALU_VV_VX_VI;
4455defm PseudoVSUB   : VPseudoVALU_VV_VX;
4456defm PseudoVRSUB  : VPseudoVALU_VX_VI;
4457
4458foreach vti = AllIntegerVectors in {
4459  // Match vrsub with 2 vector operands to vsub.vv by swapping operands. This
4460  // Occurs when legalizing vrsub.vx intrinsics for i64 on RV32 since we need
4461  // to use a more complex splat sequence. Add the pattern for all VTs for
4462  // consistency.
4463  def : Pat<(vti.Vector (int_riscv_vrsub (vti.Vector (undef)),
4464                                         (vti.Vector vti.RegClass:$rs2),
4465                                         (vti.Vector vti.RegClass:$rs1),
4466                                         VLOpFrag)),
4467            (!cast<Instruction>("PseudoVSUB_VV_"#vti.LMul.MX) vti.RegClass:$rs1,
4468                                                              vti.RegClass:$rs2,
4469                                                              GPR:$vl,
4470                                                              vti.Log2SEW)>;
4471  def : Pat<(vti.Vector (int_riscv_vrsub (vti.Vector vti.RegClass:$merge),
4472                                         (vti.Vector vti.RegClass:$rs2),
4473                                         (vti.Vector vti.RegClass:$rs1),
4474                                         VLOpFrag)),
4475            (!cast<Instruction>("PseudoVSUB_VV_"#vti.LMul.MX#"_TU")
4476                                                      vti.RegClass:$merge,
4477                                                      vti.RegClass:$rs1,
4478                                                      vti.RegClass:$rs2,
4479                                                      GPR:$vl,
4480                                                      vti.Log2SEW)>;
4481  def : Pat<(vti.Vector (int_riscv_vrsub_mask (vti.Vector vti.RegClass:$merge),
4482                                              (vti.Vector vti.RegClass:$rs2),
4483                                              (vti.Vector vti.RegClass:$rs1),
4484                                              (vti.Mask V0),
4485                                              VLOpFrag,
4486                                              (XLenVT timm:$policy))),
4487            (!cast<Instruction>("PseudoVSUB_VV_"#vti.LMul.MX#"_MASK")
4488                                                      vti.RegClass:$merge,
4489                                                      vti.RegClass:$rs1,
4490                                                      vti.RegClass:$rs2,
4491                                                      (vti.Mask V0),
4492                                                      GPR:$vl,
4493                                                      vti.Log2SEW,
4494                                                      (XLenVT timm:$policy))>;
4495
4496  // Match VSUB with a small immediate to vadd.vi by negating the immediate.
4497  def : Pat<(vti.Vector (int_riscv_vsub (vti.Vector (undef)),
4498                                        (vti.Vector vti.RegClass:$rs1),
4499                                        (vti.Scalar simm5_plus1:$rs2),
4500                                        VLOpFrag)),
4501            (!cast<Instruction>("PseudoVADD_VI_"#vti.LMul.MX) vti.RegClass:$rs1,
4502                                                              (NegImm simm5_plus1:$rs2),
4503                                                              GPR:$vl,
4504                                                              vti.Log2SEW)>;
4505  def : Pat<(vti.Vector (int_riscv_vsub_mask (vti.Vector vti.RegClass:$merge),
4506                                             (vti.Vector vti.RegClass:$rs1),
4507                                             (vti.Scalar simm5_plus1:$rs2),
4508                                             (vti.Mask V0),
4509                                             VLOpFrag,
4510                                             (XLenVT timm:$policy))),
4511            (!cast<Instruction>("PseudoVADD_VI_"#vti.LMul.MX#"_MASK")
4512                                                      vti.RegClass:$merge,
4513                                                      vti.RegClass:$rs1,
4514                                                      (NegImm simm5_plus1:$rs2),
4515                                                      (vti.Mask V0),
4516                                                      GPR:$vl,
4517                                                      vti.Log2SEW,
4518                                                      (XLenVT timm:$policy))>;
4519}
4520
4521//===----------------------------------------------------------------------===//
4522// 12.2. Vector Widening Integer Add/Subtract
4523//===----------------------------------------------------------------------===//
4524defm PseudoVWADDU : VPseudoVWALU_VV_VX;
4525defm PseudoVWSUBU : VPseudoVWALU_VV_VX;
4526defm PseudoVWADD  : VPseudoVWALU_VV_VX;
4527defm PseudoVWSUB  : VPseudoVWALU_VV_VX;
4528defm PseudoVWADDU : VPseudoVWALU_WV_WX;
4529defm PseudoVWSUBU : VPseudoVWALU_WV_WX;
4530defm PseudoVWADD  : VPseudoVWALU_WV_WX;
4531defm PseudoVWSUB  : VPseudoVWALU_WV_WX;
4532
4533//===----------------------------------------------------------------------===//
4534// 12.3. Vector Integer Extension
4535//===----------------------------------------------------------------------===//
4536defm PseudoVZEXT_VF2 : PseudoVEXT_VF2;
4537defm PseudoVZEXT_VF4 : PseudoVEXT_VF4;
4538defm PseudoVZEXT_VF8 : PseudoVEXT_VF8;
4539defm PseudoVSEXT_VF2 : PseudoVEXT_VF2;
4540defm PseudoVSEXT_VF4 : PseudoVEXT_VF4;
4541defm PseudoVSEXT_VF8 : PseudoVEXT_VF8;
4542
4543//===----------------------------------------------------------------------===//
4544// 12.4. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
4545//===----------------------------------------------------------------------===//
4546defm PseudoVADC  : VPseudoVCALU_VM_XM_IM;
4547defm PseudoVMADC : VPseudoVCALUM_VM_XM_IM<"@earlyclobber $rd">;
4548defm PseudoVMADC : VPseudoVCALUM_V_X_I<"@earlyclobber $rd">;
4549
4550defm PseudoVSBC  : VPseudoVCALU_VM_XM;
4551defm PseudoVMSBC : VPseudoVCALUM_VM_XM<"@earlyclobber $rd">;
4552defm PseudoVMSBC : VPseudoVCALUM_V_X<"@earlyclobber $rd">;
4553
4554//===----------------------------------------------------------------------===//
4555// 12.5. Vector Bitwise Logical Instructions
4556//===----------------------------------------------------------------------===//
4557defm PseudoVAND : VPseudoVALU_VV_VX_VI;
4558defm PseudoVOR  : VPseudoVALU_VV_VX_VI;
4559defm PseudoVXOR : VPseudoVALU_VV_VX_VI;
4560
4561//===----------------------------------------------------------------------===//
4562// 12.6. Vector Single-Width Bit Shift Instructions
4563//===----------------------------------------------------------------------===//
4564defm PseudoVSLL : VPseudoVSHT_VV_VX_VI<uimm5>;
4565defm PseudoVSRL : VPseudoVSHT_VV_VX_VI<uimm5>;
4566defm PseudoVSRA : VPseudoVSHT_VV_VX_VI<uimm5>;
4567
4568//===----------------------------------------------------------------------===//
4569// 12.7. Vector Narrowing Integer Right Shift Instructions
4570//===----------------------------------------------------------------------===//
4571defm PseudoVNSRL : VPseudoVNSHT_WV_WX_WI;
4572defm PseudoVNSRA : VPseudoVNSHT_WV_WX_WI;
4573
4574//===----------------------------------------------------------------------===//
4575// 12.8. Vector Integer Comparison Instructions
4576//===----------------------------------------------------------------------===//
4577defm PseudoVMSEQ  : VPseudoVCMPM_VV_VX_VI;
4578defm PseudoVMSNE  : VPseudoVCMPM_VV_VX_VI;
4579defm PseudoVMSLTU : VPseudoVCMPM_VV_VX;
4580defm PseudoVMSLT  : VPseudoVCMPM_VV_VX;
4581defm PseudoVMSLEU : VPseudoVCMPM_VV_VX_VI;
4582defm PseudoVMSLE  : VPseudoVCMPM_VV_VX_VI;
4583defm PseudoVMSGTU : VPseudoVCMPM_VX_VI;
4584defm PseudoVMSGT  : VPseudoVCMPM_VX_VI;
4585
4586//===----------------------------------------------------------------------===//
4587// 12.9. Vector Integer Min/Max Instructions
4588//===----------------------------------------------------------------------===//
4589defm PseudoVMINU : VPseudoVMINMAX_VV_VX;
4590defm PseudoVMIN  : VPseudoVMINMAX_VV_VX;
4591defm PseudoVMAXU : VPseudoVMINMAX_VV_VX;
4592defm PseudoVMAX  : VPseudoVMINMAX_VV_VX;
4593
4594//===----------------------------------------------------------------------===//
4595// 12.10. Vector Single-Width Integer Multiply Instructions
4596//===----------------------------------------------------------------------===//
4597defm PseudoVMUL    : VPseudoVMUL_VV_VX;
4598defm PseudoVMULH   : VPseudoVMUL_VV_VX;
4599defm PseudoVMULHU  : VPseudoVMUL_VV_VX;
4600defm PseudoVMULHSU : VPseudoVMUL_VV_VX;
4601
4602//===----------------------------------------------------------------------===//
4603// 12.11. Vector Integer Divide Instructions
4604//===----------------------------------------------------------------------===//
4605defm PseudoVDIVU : VPseudoVDIV_VV_VX;
4606defm PseudoVDIV  : VPseudoVDIV_VV_VX;
4607defm PseudoVREMU : VPseudoVDIV_VV_VX;
4608defm PseudoVREM  : VPseudoVDIV_VV_VX;
4609
4610//===----------------------------------------------------------------------===//
4611// 12.12. Vector Widening Integer Multiply Instructions
4612//===----------------------------------------------------------------------===//
4613defm PseudoVWMUL   : VPseudoVWMUL_VV_VX;
4614defm PseudoVWMULU  : VPseudoVWMUL_VV_VX;
4615defm PseudoVWMULSU : VPseudoVWMUL_VV_VX;
4616
4617//===----------------------------------------------------------------------===//
4618// 12.13. Vector Single-Width Integer Multiply-Add Instructions
4619//===----------------------------------------------------------------------===//
4620defm PseudoVMACC  : VPseudoVMAC_VV_VX_AAXA;
4621defm PseudoVNMSAC : VPseudoVMAC_VV_VX_AAXA;
4622defm PseudoVMADD  : VPseudoVMAC_VV_VX_AAXA;
4623defm PseudoVNMSUB : VPseudoVMAC_VV_VX_AAXA;
4624
4625//===----------------------------------------------------------------------===//
4626// 12.14. Vector Widening Integer Multiply-Add Instructions
4627//===----------------------------------------------------------------------===//
4628defm PseudoVWMACCU  : VPseudoVWMAC_VV_VX;
4629defm PseudoVWMACC   : VPseudoVWMAC_VV_VX;
4630defm PseudoVWMACCSU : VPseudoVWMAC_VV_VX;
4631defm PseudoVWMACCUS : VPseudoVWMAC_VX;
4632
4633//===----------------------------------------------------------------------===//
4634// 12.15. Vector Integer Merge Instructions
4635//===----------------------------------------------------------------------===//
4636defm PseudoVMERGE : VPseudoVMRG_VM_XM_IM;
4637
4638//===----------------------------------------------------------------------===//
4639// 12.16. Vector Integer Move Instructions
4640//===----------------------------------------------------------------------===//
4641defm PseudoVMV_V : VPseudoUnaryVMV_V_X_I;
4642
4643//===----------------------------------------------------------------------===//
4644// 13.1. Vector Single-Width Saturating Add and Subtract
4645//===----------------------------------------------------------------------===//
4646let Defs = [VXSAT], hasSideEffects = 1 in {
4647  defm PseudoVSADDU : VPseudoVSALU_VV_VX_VI;
4648  defm PseudoVSADD  : VPseudoVSALU_VV_VX_VI;
4649  defm PseudoVSSUBU : VPseudoVSALU_VV_VX;
4650  defm PseudoVSSUB  : VPseudoVSALU_VV_VX;
4651}
4652
4653//===----------------------------------------------------------------------===//
4654// 13.2. Vector Single-Width Averaging Add and Subtract
4655//===----------------------------------------------------------------------===//
4656let Uses = [VXRM], hasSideEffects = 1 in {
4657  defm PseudoVAADDU : VPseudoVAALU_VV_VX;
4658  defm PseudoVAADD  : VPseudoVAALU_VV_VX;
4659  defm PseudoVASUBU : VPseudoVAALU_VV_VX;
4660  defm PseudoVASUB  : VPseudoVAALU_VV_VX;
4661}
4662
4663//===----------------------------------------------------------------------===//
4664// 13.3. Vector Single-Width Fractional Multiply with Rounding and Saturation
4665//===----------------------------------------------------------------------===//
4666let Uses = [VXRM], Defs = [VXSAT], hasSideEffects = 1 in {
4667  defm PseudoVSMUL : VPseudoVSMUL_VV_VX;
4668}
4669
4670//===----------------------------------------------------------------------===//
4671// 13.4. Vector Single-Width Scaling Shift Instructions
4672//===----------------------------------------------------------------------===//
4673let Uses = [VXRM], hasSideEffects = 1 in {
4674  defm PseudoVSSRL : VPseudoVSSHT_VV_VX_VI<uimm5>;
4675  defm PseudoVSSRA : VPseudoVSSHT_VV_VX_VI<uimm5>;
4676}
4677
4678//===----------------------------------------------------------------------===//
4679// 13.5. Vector Narrowing Fixed-Point Clip Instructions
4680//===----------------------------------------------------------------------===//
4681let Uses = [VXRM], Defs = [VXSAT], hasSideEffects = 1 in {
4682  defm PseudoVNCLIP  : VPseudoVNCLP_WV_WX_WI;
4683  defm PseudoVNCLIPU : VPseudoVNCLP_WV_WX_WI;
4684}
4685
4686} // Predicates = [HasVInstructions]
4687
4688let Predicates = [HasVInstructionsAnyF] in {
4689//===----------------------------------------------------------------------===//
4690// 14.2. Vector Single-Width Floating-Point Add/Subtract Instructions
4691//===----------------------------------------------------------------------===//
4692let Uses = [FRM], mayRaiseFPException = true in {
4693defm PseudoVFADD  : VPseudoVALU_VV_VF;
4694defm PseudoVFSUB  : VPseudoVALU_VV_VF;
4695defm PseudoVFRSUB : VPseudoVALU_VF;
4696}
4697
4698//===----------------------------------------------------------------------===//
4699// 14.3. Vector Widening Floating-Point Add/Subtract Instructions
4700//===----------------------------------------------------------------------===//
4701let Uses = [FRM], mayRaiseFPException = true in {
4702defm PseudoVFWADD : VPseudoVFWALU_VV_VF;
4703defm PseudoVFWSUB : VPseudoVFWALU_VV_VF;
4704defm PseudoVFWADD : VPseudoVFWALU_WV_WF;
4705defm PseudoVFWSUB : VPseudoVFWALU_WV_WF;
4706}
4707
4708//===----------------------------------------------------------------------===//
4709// 14.4. Vector Single-Width Floating-Point Multiply/Divide Instructions
4710//===----------------------------------------------------------------------===//
4711let Uses = [FRM], mayRaiseFPException = true in {
4712defm PseudoVFMUL  : VPseudoVFMUL_VV_VF;
4713defm PseudoVFDIV  : VPseudoVFDIV_VV_VF;
4714defm PseudoVFRDIV : VPseudoVFRDIV_VF;
4715}
4716
4717//===----------------------------------------------------------------------===//
4718// 14.5. Vector Widening Floating-Point Multiply
4719//===----------------------------------------------------------------------===//
4720let Uses = [FRM], mayRaiseFPException = true in {
4721defm PseudoVFWMUL : VPseudoVWMUL_VV_VF;
4722}
4723
4724//===----------------------------------------------------------------------===//
4725// 14.6. Vector Single-Width Floating-Point Fused Multiply-Add Instructions
4726//===----------------------------------------------------------------------===//
4727let Uses = [FRM], mayRaiseFPException = true in {
4728defm PseudoVFMACC  : VPseudoVMAC_VV_VF_AAXA;
4729defm PseudoVFNMACC : VPseudoVMAC_VV_VF_AAXA;
4730defm PseudoVFMSAC  : VPseudoVMAC_VV_VF_AAXA;
4731defm PseudoVFNMSAC : VPseudoVMAC_VV_VF_AAXA;
4732defm PseudoVFMADD  : VPseudoVMAC_VV_VF_AAXA;
4733defm PseudoVFNMADD : VPseudoVMAC_VV_VF_AAXA;
4734defm PseudoVFMSUB  : VPseudoVMAC_VV_VF_AAXA;
4735defm PseudoVFNMSUB : VPseudoVMAC_VV_VF_AAXA;
4736}
4737
4738//===----------------------------------------------------------------------===//
4739// 14.7. Vector Widening Floating-Point Fused Multiply-Add Instructions
4740//===----------------------------------------------------------------------===//
4741let Uses = [FRM], mayRaiseFPException = true in {
4742defm PseudoVFWMACC  : VPseudoVWMAC_VV_VF;
4743defm PseudoVFWNMACC : VPseudoVWMAC_VV_VF;
4744defm PseudoVFWMSAC  : VPseudoVWMAC_VV_VF;
4745defm PseudoVFWNMSAC : VPseudoVWMAC_VV_VF;
4746}
4747
4748//===----------------------------------------------------------------------===//
4749// 14.8. Vector Floating-Point Square-Root Instruction
4750//===----------------------------------------------------------------------===//
4751let Uses = [FRM], mayRaiseFPException = true in
4752defm PseudoVFSQRT : VPseudoVSQR_V;
4753
4754//===----------------------------------------------------------------------===//
4755// 14.9. Vector Floating-Point Reciprocal Square-Root Estimate Instruction
4756//===----------------------------------------------------------------------===//
4757let mayRaiseFPException = true in
4758defm PseudoVFRSQRT7 : VPseudoVRCP_V;
4759
4760//===----------------------------------------------------------------------===//
4761// 14.10. Vector Floating-Point Reciprocal Estimate Instruction
4762//===----------------------------------------------------------------------===//
4763let Uses = [FRM], mayRaiseFPException = true in
4764defm PseudoVFREC7 : VPseudoVRCP_V;
4765
4766//===----------------------------------------------------------------------===//
4767// 14.11. Vector Floating-Point Min/Max Instructions
4768//===----------------------------------------------------------------------===//
4769let mayRaiseFPException = true in {
4770defm PseudoVFMIN : VPseudoVMAX_VV_VF;
4771defm PseudoVFMAX : VPseudoVMAX_VV_VF;
4772}
4773
4774//===----------------------------------------------------------------------===//
4775// 14.12. Vector Floating-Point Sign-Injection Instructions
4776//===----------------------------------------------------------------------===//
4777defm PseudoVFSGNJ  : VPseudoVSGNJ_VV_VF;
4778defm PseudoVFSGNJN : VPseudoVSGNJ_VV_VF;
4779defm PseudoVFSGNJX : VPseudoVSGNJ_VV_VF;
4780
4781//===----------------------------------------------------------------------===//
4782// 14.13. Vector Floating-Point Compare Instructions
4783//===----------------------------------------------------------------------===//
4784let mayRaiseFPException = true in {
4785defm PseudoVMFEQ : VPseudoVCMPM_VV_VF;
4786defm PseudoVMFNE : VPseudoVCMPM_VV_VF;
4787defm PseudoVMFLT : VPseudoVCMPM_VV_VF;
4788defm PseudoVMFLE : VPseudoVCMPM_VV_VF;
4789defm PseudoVMFGT : VPseudoVCMPM_VF;
4790defm PseudoVMFGE : VPseudoVCMPM_VF;
4791}
4792
4793//===----------------------------------------------------------------------===//
4794// 14.14. Vector Floating-Point Classify Instruction
4795//===----------------------------------------------------------------------===//
4796defm PseudoVFCLASS : VPseudoVCLS_V;
4797
4798//===----------------------------------------------------------------------===//
4799// 14.15. Vector Floating-Point Merge Instruction
4800//===----------------------------------------------------------------------===//
4801defm PseudoVFMERGE : VPseudoVMRG_FM;
4802
4803//===----------------------------------------------------------------------===//
4804// 14.16. Vector Floating-Point Move Instruction
4805//===----------------------------------------------------------------------===//
4806defm PseudoVFMV_V : VPseudoVMV_F;
4807
4808//===----------------------------------------------------------------------===//
4809// 14.17. Single-Width Floating-Point/Integer Type-Convert Instructions
4810//===----------------------------------------------------------------------===//
4811defm PseudoVFCVT_XU_F : VPseudoVCVTI_V;
4812defm PseudoVFCVT_X_F : VPseudoVCVTI_V;
4813defm PseudoVFCVT_RTZ_XU_F : VPseudoVCVTI_V;
4814defm PseudoVFCVT_RTZ_X_F : VPseudoVCVTI_V;
4815defm PseudoVFCVT_F_XU : VPseudoVCVTF_V;
4816defm PseudoVFCVT_F_X : VPseudoVCVTF_V;
4817
4818//===----------------------------------------------------------------------===//
4819// 14.18. Widening Floating-Point/Integer Type-Convert Instructions
4820//===----------------------------------------------------------------------===//
4821defm PseudoVFWCVT_XU_F     : VPseudoVWCVTI_V;
4822defm PseudoVFWCVT_X_F      : VPseudoVWCVTI_V;
4823defm PseudoVFWCVT_RTZ_XU_F : VPseudoVWCVTI_V;
4824defm PseudoVFWCVT_RTZ_X_F  : VPseudoVWCVTI_V;
4825defm PseudoVFWCVT_F_XU     : VPseudoVWCVTF_V;
4826defm PseudoVFWCVT_F_X      : VPseudoVWCVTF_V;
4827defm PseudoVFWCVT_F_F      : VPseudoVWCVTD_V;
4828
4829//===----------------------------------------------------------------------===//
4830// 14.19. Narrowing Floating-Point/Integer Type-Convert Instructions
4831//===----------------------------------------------------------------------===//
4832defm PseudoVFNCVT_XU_F     : VPseudoVNCVTI_W;
4833defm PseudoVFNCVT_X_F      : VPseudoVNCVTI_W;
4834defm PseudoVFNCVT_RTZ_XU_F : VPseudoVNCVTI_W;
4835defm PseudoVFNCVT_RTZ_X_F  : VPseudoVNCVTI_W;
4836defm PseudoVFNCVT_F_XU     : VPseudoVNCVTF_W;
4837defm PseudoVFNCVT_F_X      : VPseudoVNCVTF_W;
4838defm PseudoVFNCVT_F_F      : VPseudoVNCVTD_W;
4839defm PseudoVFNCVT_ROD_F_F  : VPseudoVNCVTD_W;
4840} // Predicates = [HasVInstructionsAnyF]
4841
4842let Predicates = [HasVInstructions] in {
4843//===----------------------------------------------------------------------===//
4844// 15.1. Vector Single-Width Integer Reduction Instructions
4845//===----------------------------------------------------------------------===//
4846defm PseudoVREDSUM  : VPseudoVRED_VS;
4847defm PseudoVREDAND  : VPseudoVRED_VS;
4848defm PseudoVREDOR   : VPseudoVRED_VS;
4849defm PseudoVREDXOR  : VPseudoVRED_VS;
4850defm PseudoVREDMINU : VPseudoVRED_VS;
4851defm PseudoVREDMIN  : VPseudoVRED_VS;
4852defm PseudoVREDMAXU : VPseudoVRED_VS;
4853defm PseudoVREDMAX  : VPseudoVRED_VS;
4854
4855//===----------------------------------------------------------------------===//
4856// 15.2. Vector Widening Integer Reduction Instructions
4857//===----------------------------------------------------------------------===//
4858let IsRVVWideningReduction = 1 in {
4859defm PseudoVWREDSUMU   : VPseudoVWRED_VS;
4860defm PseudoVWREDSUM    : VPseudoVWRED_VS;
4861}
4862} // Predicates = [HasVInstructions]
4863
4864let Predicates = [HasVInstructionsAnyF] in {
4865//===----------------------------------------------------------------------===//
4866// 15.3. Vector Single-Width Floating-Point Reduction Instructions
4867//===----------------------------------------------------------------------===//
4868let Uses = [FRM], mayRaiseFPException = true in {
4869defm PseudoVFREDOSUM : VPseudoVFREDO_VS;
4870defm PseudoVFREDUSUM : VPseudoVFRED_VS;
4871}
4872let mayRaiseFPException = true in {
4873defm PseudoVFREDMIN  : VPseudoVFRED_VS;
4874defm PseudoVFREDMAX  : VPseudoVFRED_VS;
4875}
4876
4877//===----------------------------------------------------------------------===//
4878// 15.4. Vector Widening Floating-Point Reduction Instructions
4879//===----------------------------------------------------------------------===//
4880let IsRVVWideningReduction = 1,
4881    Uses = [FRM],
4882    mayRaiseFPException = true in {
4883defm PseudoVFWREDUSUM  : VPseudoVFWRED_VS;
4884defm PseudoVFWREDOSUM  : VPseudoVFWRED_VS;
4885}
4886
4887} // Predicates = [HasVInstructionsAnyF]
4888
4889//===----------------------------------------------------------------------===//
4890// 16. Vector Mask Instructions
4891//===----------------------------------------------------------------------===//
4892
4893//===----------------------------------------------------------------------===//
4894// 16.1 Vector Mask-Register Logical Instructions
4895//===----------------------------------------------------------------------===//
4896
4897defm PseudoVMAND: VPseudoVALU_MM;
4898defm PseudoVMNAND: VPseudoVALU_MM;
4899defm PseudoVMANDN: VPseudoVALU_MM;
4900defm PseudoVMXOR: VPseudoVALU_MM;
4901defm PseudoVMOR: VPseudoVALU_MM;
4902defm PseudoVMNOR: VPseudoVALU_MM;
4903defm PseudoVMORN: VPseudoVALU_MM;
4904defm PseudoVMXNOR: VPseudoVALU_MM;
4905
4906// Pseudo instructions
4907defm PseudoVMCLR : VPseudoNullaryPseudoM<"VMXOR">,
4908                   Sched<[WriteVMALUV, ReadVMALUV, ReadVMALUV]>;
4909defm PseudoVMSET : VPseudoNullaryPseudoM<"VMXNOR">,
4910                   Sched<[WriteVMALUV, ReadVMALUV, ReadVMALUV]>;
4911
4912//===----------------------------------------------------------------------===//
4913// 16.2. Vector mask population count vcpop
4914//===----------------------------------------------------------------------===//
4915
4916defm PseudoVCPOP: VPseudoVPOP_M;
4917
4918//===----------------------------------------------------------------------===//
4919// 16.3. vfirst find-first-set mask bit
4920//===----------------------------------------------------------------------===//
4921
4922defm PseudoVFIRST: VPseudoV1ST_M;
4923
4924//===----------------------------------------------------------------------===//
4925// 16.4. vmsbf.m set-before-first mask bit
4926//===----------------------------------------------------------------------===//
4927defm PseudoVMSBF: VPseudoVSFS_M;
4928
4929//===----------------------------------------------------------------------===//
4930// 16.5. vmsif.m set-including-first mask bit
4931//===----------------------------------------------------------------------===//
4932defm PseudoVMSIF: VPseudoVSFS_M;
4933
4934//===----------------------------------------------------------------------===//
4935// 16.6. vmsof.m set-only-first mask bit
4936//===----------------------------------------------------------------------===//
4937defm PseudoVMSOF: VPseudoVSFS_M;
4938
4939//===----------------------------------------------------------------------===//
4940// 16.8.  Vector Iota Instruction
4941//===----------------------------------------------------------------------===//
4942defm PseudoVIOTA_M: VPseudoVIOT_M;
4943
4944//===----------------------------------------------------------------------===//
4945// 16.9. Vector Element Index Instruction
4946//===----------------------------------------------------------------------===//
4947defm PseudoVID : VPseudoVID_V;
4948
4949//===----------------------------------------------------------------------===//
4950// 17. Vector Permutation Instructions
4951//===----------------------------------------------------------------------===//
4952
4953//===----------------------------------------------------------------------===//
4954// 17.1. Integer Scalar Move Instructions
4955//===----------------------------------------------------------------------===//
4956
4957let Predicates = [HasVInstructions] in {
4958let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
4959  foreach m = MxList in {
4960    let VLMul = m.value in {
4961      let HasSEWOp = 1, BaseInstr = VMV_X_S in
4962      def PseudoVMV_X_S # "_" # m.MX:
4963        Pseudo<(outs GPR:$rd), (ins m.vrclass:$rs2, ixlenimm:$sew), []>,
4964        Sched<[WriteVIMovVX, ReadVIMovVX]>,
4965        RISCVVPseudo;
4966      let HasVLOp = 1, HasSEWOp = 1, BaseInstr = VMV_S_X,
4967          Constraints = "$rd = $rs1" in
4968      def PseudoVMV_S_X # "_" # m.MX: Pseudo<(outs m.vrclass:$rd),
4969                                             (ins m.vrclass:$rs1, GPR:$rs2,
4970                                                  AVL:$vl, ixlenimm:$sew),
4971                                             []>,
4972        Sched<[WriteVIMovXV, ReadVIMovXV, ReadVIMovXX]>,
4973        RISCVVPseudo;
4974    }
4975  }
4976}
4977} // Predicates = [HasVInstructions]
4978
4979//===----------------------------------------------------------------------===//
4980// 17.2. Floating-Point Scalar Move Instructions
4981//===----------------------------------------------------------------------===//
4982
4983let Predicates = [HasVInstructionsAnyF] in {
4984let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
4985  foreach f = FPList in {
4986    foreach m = f.MxList in {
4987      let VLMul = m.value in {
4988        let HasSEWOp = 1, BaseInstr = VFMV_F_S in
4989        def "PseudoVFMV_" # f.FX # "_S_" # m.MX :
4990          Pseudo<(outs f.fprclass:$rd),
4991                 (ins m.vrclass:$rs2, ixlenimm:$sew), []>,
4992          Sched<[WriteVFMovVF, ReadVFMovVF]>,
4993          RISCVVPseudo;
4994        let HasVLOp = 1, HasSEWOp = 1, BaseInstr = VFMV_S_F,
4995            Constraints = "$rd = $rs1" in
4996        def "PseudoVFMV_S_" # f.FX # "_" # m.MX :
4997                                          Pseudo<(outs m.vrclass:$rd),
4998                                                 (ins m.vrclass:$rs1, f.fprclass:$rs2,
4999                                                      AVL:$vl, ixlenimm:$sew),
5000                                                 []>,
5001          Sched<[WriteVFMovFV, ReadVFMovFV, ReadVFMovFX]>,
5002          RISCVVPseudo;
5003      }
5004    }
5005  }
5006}
5007} // Predicates = [HasVInstructionsAnyF]
5008
5009//===----------------------------------------------------------------------===//
5010// 17.3. Vector Slide Instructions
5011//===----------------------------------------------------------------------===//
5012let Predicates = [HasVInstructions] in {
5013  defm PseudoVSLIDEUP    : VPseudoVSLD_VX_VI<uimm5, "@earlyclobber $rd">;
5014  defm PseudoVSLIDEDOWN  : VPseudoVSLD_VX_VI<uimm5>;
5015  defm PseudoVSLIDE1UP   : VPseudoVSLD1_VX<"@earlyclobber $rd">;
5016  defm PseudoVSLIDE1DOWN : VPseudoVSLD1_VX;
5017} // Predicates = [HasVInstructions]
5018
5019let Predicates = [HasVInstructionsAnyF] in {
5020  defm PseudoVFSLIDE1UP  : VPseudoVSLD1_VF<"@earlyclobber $rd">;
5021  defm PseudoVFSLIDE1DOWN : VPseudoVSLD1_VF;
5022} // Predicates = [HasVInstructionsAnyF]
5023
5024//===----------------------------------------------------------------------===//
5025// 17.4. Vector Register Gather Instructions
5026//===----------------------------------------------------------------------===//
5027defm PseudoVRGATHER     : VPseudoVGTR_VV_VX_VI<uimm5, "@earlyclobber $rd">;
5028defm PseudoVRGATHEREI16 : VPseudoVGTR_VV_EEW</* eew */ 16, "@earlyclobber $rd">;
5029
5030//===----------------------------------------------------------------------===//
5031// 17.5. Vector Compress Instruction
5032//===----------------------------------------------------------------------===//
5033defm PseudoVCOMPRESS : VPseudoVCPR_V;
5034
5035//===----------------------------------------------------------------------===//
5036// Patterns.
5037//===----------------------------------------------------------------------===//
5038
5039//===----------------------------------------------------------------------===//
5040// 12. Vector Integer Arithmetic Instructions
5041//===----------------------------------------------------------------------===//
5042
5043let Predicates = [HasVInstructions] in {
5044//===----------------------------------------------------------------------===//
5045// 12.1. Vector Single-Width Integer Add and Subtract
5046//===----------------------------------------------------------------------===//
5047defm : VPatBinaryV_VV_VX_VI<"int_riscv_vadd", "PseudoVADD", AllIntegerVectors>;
5048defm : VPatBinaryV_VV_VX<"int_riscv_vsub", "PseudoVSUB", AllIntegerVectors>;
5049defm : VPatBinaryV_VX_VI<"int_riscv_vrsub", "PseudoVRSUB", AllIntegerVectors>;
5050
5051//===----------------------------------------------------------------------===//
5052// 12.2. Vector Widening Integer Add/Subtract
5053//===----------------------------------------------------------------------===//
5054defm : VPatBinaryW_VV_VX<"int_riscv_vwaddu", "PseudoVWADDU", AllWidenableIntVectors>;
5055defm : VPatBinaryW_VV_VX<"int_riscv_vwsubu", "PseudoVWSUBU", AllWidenableIntVectors>;
5056defm : VPatBinaryW_VV_VX<"int_riscv_vwadd", "PseudoVWADD", AllWidenableIntVectors>;
5057defm : VPatBinaryW_VV_VX<"int_riscv_vwsub", "PseudoVWSUB", AllWidenableIntVectors>;
5058defm : VPatBinaryW_WV_WX<"int_riscv_vwaddu_w", "PseudoVWADDU", AllWidenableIntVectors>;
5059defm : VPatBinaryW_WV_WX<"int_riscv_vwsubu_w", "PseudoVWSUBU", AllWidenableIntVectors>;
5060defm : VPatBinaryW_WV_WX<"int_riscv_vwadd_w", "PseudoVWADD", AllWidenableIntVectors>;
5061defm : VPatBinaryW_WV_WX<"int_riscv_vwsub_w", "PseudoVWSUB", AllWidenableIntVectors>;
5062
5063//===----------------------------------------------------------------------===//
5064// 12.3. Vector Integer Extension
5065//===----------------------------------------------------------------------===//
5066defm : VPatUnaryV_VF<"int_riscv_vzext", "PseudoVZEXT", "VF2",
5067                     AllFractionableVF2IntVectors>;
5068defm : VPatUnaryV_VF<"int_riscv_vzext", "PseudoVZEXT", "VF4",
5069                     AllFractionableVF4IntVectors>;
5070defm : VPatUnaryV_VF<"int_riscv_vzext", "PseudoVZEXT", "VF8",
5071                     AllFractionableVF8IntVectors>;
5072defm : VPatUnaryV_VF<"int_riscv_vsext", "PseudoVSEXT", "VF2",
5073                     AllFractionableVF2IntVectors>;
5074defm : VPatUnaryV_VF<"int_riscv_vsext", "PseudoVSEXT", "VF4",
5075                     AllFractionableVF4IntVectors>;
5076defm : VPatUnaryV_VF<"int_riscv_vsext", "PseudoVSEXT", "VF8",
5077                     AllFractionableVF8IntVectors>;
5078
5079//===----------------------------------------------------------------------===//
5080// 12.4. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
5081//===----------------------------------------------------------------------===//
5082defm : VPatBinaryV_VM_XM_IM<"int_riscv_vadc", "PseudoVADC">;
5083defm : VPatBinaryM_VM_XM_IM<"int_riscv_vmadc_carry_in", "PseudoVMADC">;
5084defm : VPatBinaryM_V_X_I<"int_riscv_vmadc", "PseudoVMADC">;
5085
5086defm : VPatBinaryV_VM_XM<"int_riscv_vsbc", "PseudoVSBC">;
5087defm : VPatBinaryM_VM_XM<"int_riscv_vmsbc_borrow_in", "PseudoVMSBC">;
5088defm : VPatBinaryM_V_X<"int_riscv_vmsbc", "PseudoVMSBC">;
5089
5090//===----------------------------------------------------------------------===//
5091// 12.5. Vector Bitwise Logical Instructions
5092//===----------------------------------------------------------------------===//
5093defm : VPatBinaryV_VV_VX_VI<"int_riscv_vand", "PseudoVAND", AllIntegerVectors>;
5094defm : VPatBinaryV_VV_VX_VI<"int_riscv_vor", "PseudoVOR", AllIntegerVectors>;
5095defm : VPatBinaryV_VV_VX_VI<"int_riscv_vxor", "PseudoVXOR", AllIntegerVectors>;
5096
5097//===----------------------------------------------------------------------===//
5098// 12.6. Vector Single-Width Bit Shift Instructions
5099//===----------------------------------------------------------------------===//
5100defm : VPatBinaryV_VV_VX_VI<"int_riscv_vsll", "PseudoVSLL", AllIntegerVectors,
5101                            uimm5>;
5102defm : VPatBinaryV_VV_VX_VI<"int_riscv_vsrl", "PseudoVSRL", AllIntegerVectors,
5103                            uimm5>;
5104defm : VPatBinaryV_VV_VX_VI<"int_riscv_vsra", "PseudoVSRA", AllIntegerVectors,
5105                            uimm5>;
5106
5107foreach vti = AllIntegerVectors in {
5108  // Emit shift by 1 as an add since it might be faster.
5109  def : Pat<(vti.Vector (int_riscv_vsll (vti.Vector undef),
5110                                        (vti.Vector vti.RegClass:$rs1),
5111                                        (XLenVT 1), VLOpFrag)),
5112            (!cast<Instruction>("PseudoVADD_VV_"#vti.LMul.MX) vti.RegClass:$rs1,
5113                                                              vti.RegClass:$rs1,
5114                                                              GPR:$vl,
5115                                                              vti.Log2SEW)>;
5116  def : Pat<(vti.Vector (int_riscv_vsll_mask (vti.Vector vti.RegClass:$merge),
5117                                             (vti.Vector vti.RegClass:$rs1),
5118                                             (XLenVT 1),
5119                                             (vti.Mask V0),
5120                                             VLOpFrag,
5121                                             (XLenVT timm:$policy))),
5122            (!cast<Instruction>("PseudoVADD_VV_"#vti.LMul.MX#"_MASK")
5123                                                        vti.RegClass:$merge,
5124                                                        vti.RegClass:$rs1,
5125                                                        vti.RegClass:$rs1,
5126                                                        (vti.Mask V0),
5127                                                        GPR:$vl,
5128                                                        vti.Log2SEW,
5129                                                        (XLenVT timm:$policy))>;
5130}
5131
5132//===----------------------------------------------------------------------===//
5133// 12.7. Vector Narrowing Integer Right Shift Instructions
5134//===----------------------------------------------------------------------===//
5135defm : VPatBinaryV_WV_WX_WI<"int_riscv_vnsrl", "PseudoVNSRL", AllWidenableIntVectors>;
5136defm : VPatBinaryV_WV_WX_WI<"int_riscv_vnsra", "PseudoVNSRA", AllWidenableIntVectors>;
5137
5138//===----------------------------------------------------------------------===//
5139// 12.8. Vector Integer Comparison Instructions
5140//===----------------------------------------------------------------------===//
5141defm : VPatBinaryM_VV_VX_VI<"int_riscv_vmseq", "PseudoVMSEQ", AllIntegerVectors>;
5142defm : VPatBinaryM_VV_VX_VI<"int_riscv_vmsne", "PseudoVMSNE", AllIntegerVectors>;
5143defm : VPatBinaryM_VV_VX<"int_riscv_vmsltu", "PseudoVMSLTU", AllIntegerVectors>;
5144defm : VPatBinaryM_VV_VX<"int_riscv_vmslt", "PseudoVMSLT", AllIntegerVectors>;
5145defm : VPatBinaryM_VV_VX_VI<"int_riscv_vmsleu", "PseudoVMSLEU", AllIntegerVectors>;
5146defm : VPatBinaryM_VV_VX_VI<"int_riscv_vmsle", "PseudoVMSLE", AllIntegerVectors>;
5147
5148defm : VPatBinaryM_VX_VI<"int_riscv_vmsgtu", "PseudoVMSGTU", AllIntegerVectors>;
5149defm : VPatBinaryM_VX_VI<"int_riscv_vmsgt", "PseudoVMSGT", AllIntegerVectors>;
5150
5151// Match vmsgt with 2 vector operands to vmslt with the operands swapped.
5152defm : VPatBinarySwappedM_VV<"int_riscv_vmsgtu", "PseudoVMSLTU", AllIntegerVectors>;
5153defm : VPatBinarySwappedM_VV<"int_riscv_vmsgt", "PseudoVMSLT", AllIntegerVectors>;
5154
5155defm : VPatBinarySwappedM_VV<"int_riscv_vmsgeu", "PseudoVMSLEU", AllIntegerVectors>;
5156defm : VPatBinarySwappedM_VV<"int_riscv_vmsge", "PseudoVMSLE", AllIntegerVectors>;
5157
5158// Match vmslt(u).vx intrinsics to vmsle(u).vi if the scalar is -15 to 16 and
5159// non-zero. Zero can be .vx with x0. This avoids the user needing to know that
5160// there is no vmslt(u).vi instruction. Similar for vmsge(u).vx intrinsics
5161// using vmslt(u).vi.
5162defm : VPatCompare_VI<"int_riscv_vmslt", "PseudoVMSLE", simm5_plus1_nonzero>;
5163defm : VPatCompare_VI<"int_riscv_vmsltu", "PseudoVMSLEU", simm5_plus1_nonzero>;
5164
5165// We need to handle 0 for vmsge.vi using vmslt.vi because there is no vmsge.vx.
5166defm : VPatCompare_VI<"int_riscv_vmsge", "PseudoVMSGT", simm5_plus1>;
5167defm : VPatCompare_VI<"int_riscv_vmsgeu", "PseudoVMSGTU", simm5_plus1_nonzero>;
5168
5169//===----------------------------------------------------------------------===//
5170// 12.9. Vector Integer Min/Max Instructions
5171//===----------------------------------------------------------------------===//
5172defm : VPatBinaryV_VV_VX<"int_riscv_vminu", "PseudoVMINU", AllIntegerVectors>;
5173defm : VPatBinaryV_VV_VX<"int_riscv_vmin", "PseudoVMIN", AllIntegerVectors>;
5174defm : VPatBinaryV_VV_VX<"int_riscv_vmaxu", "PseudoVMAXU", AllIntegerVectors>;
5175defm : VPatBinaryV_VV_VX<"int_riscv_vmax", "PseudoVMAX", AllIntegerVectors>;
5176
5177//===----------------------------------------------------------------------===//
5178// 12.10. Vector Single-Width Integer Multiply Instructions
5179//===----------------------------------------------------------------------===//
5180defm : VPatBinaryV_VV_VX<"int_riscv_vmul", "PseudoVMUL", AllIntegerVectors>;
5181defm : VPatBinaryV_VV_VX<"int_riscv_vmulh", "PseudoVMULH", AllIntegerVectors>;
5182defm : VPatBinaryV_VV_VX<"int_riscv_vmulhu", "PseudoVMULHU", AllIntegerVectors>;
5183defm : VPatBinaryV_VV_VX<"int_riscv_vmulhsu", "PseudoVMULHSU", AllIntegerVectors>;
5184
5185//===----------------------------------------------------------------------===//
5186// 12.11. Vector Integer Divide Instructions
5187//===----------------------------------------------------------------------===//
5188defm : VPatBinaryV_VV_VX<"int_riscv_vdivu", "PseudoVDIVU", AllIntegerVectors>;
5189defm : VPatBinaryV_VV_VX<"int_riscv_vdiv", "PseudoVDIV", AllIntegerVectors>;
5190defm : VPatBinaryV_VV_VX<"int_riscv_vremu", "PseudoVREMU", AllIntegerVectors>;
5191defm : VPatBinaryV_VV_VX<"int_riscv_vrem", "PseudoVREM", AllIntegerVectors>;
5192
5193//===----------------------------------------------------------------------===//
5194// 12.12. Vector Widening Integer Multiply Instructions
5195//===----------------------------------------------------------------------===//
5196defm : VPatBinaryW_VV_VX<"int_riscv_vwmul", "PseudoVWMUL", AllWidenableIntVectors>;
5197defm : VPatBinaryW_VV_VX<"int_riscv_vwmulu", "PseudoVWMULU", AllWidenableIntVectors>;
5198defm : VPatBinaryW_VV_VX<"int_riscv_vwmulsu", "PseudoVWMULSU", AllWidenableIntVectors>;
5199
5200//===----------------------------------------------------------------------===//
5201// 12.13. Vector Single-Width Integer Multiply-Add Instructions
5202//===----------------------------------------------------------------------===//
5203defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vmadd", "PseudoVMADD", AllIntegerVectors>;
5204defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vnmsub", "PseudoVNMSUB", AllIntegerVectors>;
5205defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vmacc", "PseudoVMACC", AllIntegerVectors>;
5206defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vnmsac", "PseudoVNMSAC", AllIntegerVectors>;
5207
5208//===----------------------------------------------------------------------===//
5209// 12.14. Vector Widening Integer Multiply-Add Instructions
5210//===----------------------------------------------------------------------===//
5211defm : VPatTernaryW_VV_VX<"int_riscv_vwmaccu", "PseudoVWMACCU", AllWidenableIntVectors>;
5212defm : VPatTernaryW_VV_VX<"int_riscv_vwmacc", "PseudoVWMACC", AllWidenableIntVectors>;
5213defm : VPatTernaryW_VV_VX<"int_riscv_vwmaccsu", "PseudoVWMACCSU", AllWidenableIntVectors>;
5214defm : VPatTernaryW_VX<"int_riscv_vwmaccus", "PseudoVWMACCUS", AllWidenableIntVectors>;
5215
5216//===----------------------------------------------------------------------===//
5217// 12.15. Vector Integer Merge Instructions
5218//===----------------------------------------------------------------------===//
5219defm : VPatBinaryV_VM_XM_IM<"int_riscv_vmerge", "PseudoVMERGE">;
5220
5221//===----------------------------------------------------------------------===//
5222// 12.16. Vector Integer Move Instructions
5223//===----------------------------------------------------------------------===//
5224foreach vti = AllVectors in {
5225  def : Pat<(vti.Vector (int_riscv_vmv_v_v (vti.Vector undef),
5226                                           (vti.Vector vti.RegClass:$rs1),
5227                                           VLOpFrag)),
5228            (!cast<Instruction>("PseudoVMV_V_V_"#vti.LMul.MX)
5229             $rs1, GPR:$vl, vti.Log2SEW)>;
5230  def : Pat<(vti.Vector (int_riscv_vmv_v_v (vti.Vector vti.RegClass:$passthru),
5231                                           (vti.Vector vti.RegClass:$rs1),
5232                                           VLOpFrag)),
5233            (!cast<Instruction>("PseudoVMV_V_V_"#vti.LMul.MX#"_TU")
5234             $passthru, $rs1, GPR:$vl, vti.Log2SEW)>;
5235
5236  // vmv.v.x/vmv.v.i are handled in RISCInstrVInstrInfoVVLPatterns.td
5237}
5238
5239//===----------------------------------------------------------------------===//
5240// 13.1. Vector Single-Width Saturating Add and Subtract
5241//===----------------------------------------------------------------------===//
5242defm : VPatBinaryV_VV_VX_VI<"int_riscv_vsaddu", "PseudoVSADDU", AllIntegerVectors>;
5243defm : VPatBinaryV_VV_VX_VI<"int_riscv_vsadd", "PseudoVSADD", AllIntegerVectors>;
5244defm : VPatBinaryV_VV_VX<"int_riscv_vssubu", "PseudoVSSUBU", AllIntegerVectors>;
5245defm : VPatBinaryV_VV_VX<"int_riscv_vssub", "PseudoVSSUB", AllIntegerVectors>;
5246
5247//===----------------------------------------------------------------------===//
5248// 13.2. Vector Single-Width Averaging Add and Subtract
5249//===----------------------------------------------------------------------===//
5250defm : VPatBinaryV_VV_VX<"int_riscv_vaaddu", "PseudoVAADDU", AllIntegerVectors>;
5251defm : VPatBinaryV_VV_VX<"int_riscv_vaadd", "PseudoVAADD", AllIntegerVectors>;
5252defm : VPatBinaryV_VV_VX<"int_riscv_vasubu", "PseudoVASUBU", AllIntegerVectors>;
5253defm : VPatBinaryV_VV_VX<"int_riscv_vasub", "PseudoVASUB", AllIntegerVectors>;
5254
5255//===----------------------------------------------------------------------===//
5256// 13.3. Vector Single-Width Fractional Multiply with Rounding and Saturation
5257//===----------------------------------------------------------------------===//
5258defm : VPatBinaryV_VV_VX<"int_riscv_vsmul", "PseudoVSMUL", AllIntegerVectors>;
5259
5260//===----------------------------------------------------------------------===//
5261// 13.4. Vector Single-Width Scaling Shift Instructions
5262//===----------------------------------------------------------------------===//
5263defm : VPatBinaryV_VV_VX_VI<"int_riscv_vssrl", "PseudoVSSRL", AllIntegerVectors,
5264                            uimm5>;
5265defm : VPatBinaryV_VV_VX_VI<"int_riscv_vssra", "PseudoVSSRA", AllIntegerVectors,
5266                            uimm5>;
5267
5268//===----------------------------------------------------------------------===//
5269// 13.5. Vector Narrowing Fixed-Point Clip Instructions
5270//===----------------------------------------------------------------------===//
5271defm : VPatBinaryV_WV_WX_WI<"int_riscv_vnclipu", "PseudoVNCLIPU", AllWidenableIntVectors>;
5272defm : VPatBinaryV_WV_WX_WI<"int_riscv_vnclip", "PseudoVNCLIP", AllWidenableIntVectors>;
5273
5274} // Predicates = [HasVInstructions]
5275
5276let Predicates = [HasVInstructionsAnyF] in {
5277//===----------------------------------------------------------------------===//
5278// 14.2. Vector Single-Width Floating-Point Add/Subtract Instructions
5279//===----------------------------------------------------------------------===//
5280defm : VPatBinaryV_VV_VX<"int_riscv_vfadd", "PseudoVFADD", AllFloatVectors>;
5281defm : VPatBinaryV_VV_VX<"int_riscv_vfsub", "PseudoVFSUB", AllFloatVectors>;
5282defm : VPatBinaryV_VX<"int_riscv_vfrsub", "PseudoVFRSUB", AllFloatVectors>;
5283
5284//===----------------------------------------------------------------------===//
5285// 14.3. Vector Widening Floating-Point Add/Subtract Instructions
5286//===----------------------------------------------------------------------===//
5287defm : VPatBinaryW_VV_VX<"int_riscv_vfwadd", "PseudoVFWADD", AllWidenableFloatVectors>;
5288defm : VPatBinaryW_VV_VX<"int_riscv_vfwsub", "PseudoVFWSUB", AllWidenableFloatVectors>;
5289defm : VPatBinaryW_WV_WX<"int_riscv_vfwadd_w", "PseudoVFWADD", AllWidenableFloatVectors>;
5290defm : VPatBinaryW_WV_WX<"int_riscv_vfwsub_w", "PseudoVFWSUB", AllWidenableFloatVectors>;
5291
5292//===----------------------------------------------------------------------===//
5293// 14.4. Vector Single-Width Floating-Point Multiply/Divide Instructions
5294//===----------------------------------------------------------------------===//
5295defm : VPatBinaryV_VV_VX<"int_riscv_vfmul", "PseudoVFMUL", AllFloatVectors>;
5296defm : VPatBinaryV_VV_VX<"int_riscv_vfdiv", "PseudoVFDIV", AllFloatVectors>;
5297defm : VPatBinaryV_VX<"int_riscv_vfrdiv", "PseudoVFRDIV", AllFloatVectors>;
5298
5299//===----------------------------------------------------------------------===//
5300// 14.5. Vector Widening Floating-Point Multiply
5301//===----------------------------------------------------------------------===//
5302defm : VPatBinaryW_VV_VX<"int_riscv_vfwmul", "PseudoVFWMUL", AllWidenableFloatVectors>;
5303
5304//===----------------------------------------------------------------------===//
5305// 14.6. Vector Single-Width Floating-Point Fused Multiply-Add Instructions
5306//===----------------------------------------------------------------------===//
5307defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vfmacc", "PseudoVFMACC", AllFloatVectors>;
5308defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vfnmacc", "PseudoVFNMACC", AllFloatVectors>;
5309defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vfmsac", "PseudoVFMSAC", AllFloatVectors>;
5310defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vfnmsac", "PseudoVFNMSAC", AllFloatVectors>;
5311defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vfmadd", "PseudoVFMADD", AllFloatVectors>;
5312defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vfnmadd", "PseudoVFNMADD", AllFloatVectors>;
5313defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vfmsub", "PseudoVFMSUB", AllFloatVectors>;
5314defm : VPatTernaryV_VV_VX_AAXA<"int_riscv_vfnmsub", "PseudoVFNMSUB", AllFloatVectors>;
5315
5316//===----------------------------------------------------------------------===//
5317// 14.7. Vector Widening Floating-Point Fused Multiply-Add Instructions
5318//===----------------------------------------------------------------------===//
5319defm : VPatTernaryW_VV_VX<"int_riscv_vfwmacc", "PseudoVFWMACC", AllWidenableFloatVectors>;
5320defm : VPatTernaryW_VV_VX<"int_riscv_vfwnmacc", "PseudoVFWNMACC", AllWidenableFloatVectors>;
5321defm : VPatTernaryW_VV_VX<"int_riscv_vfwmsac", "PseudoVFWMSAC", AllWidenableFloatVectors>;
5322defm : VPatTernaryW_VV_VX<"int_riscv_vfwnmsac", "PseudoVFWNMSAC", AllWidenableFloatVectors>;
5323
5324//===----------------------------------------------------------------------===//
5325// 14.8. Vector Floating-Point Square-Root Instruction
5326//===----------------------------------------------------------------------===//
5327defm : VPatUnaryV_V<"int_riscv_vfsqrt", "PseudoVFSQRT", AllFloatVectors>;
5328
5329//===----------------------------------------------------------------------===//
5330// 14.9. Vector Floating-Point Reciprocal Square-Root Estimate Instruction
5331//===----------------------------------------------------------------------===//
5332defm : VPatUnaryV_V<"int_riscv_vfrsqrt7", "PseudoVFRSQRT7", AllFloatVectors>;
5333
5334//===----------------------------------------------------------------------===//
5335// 14.10. Vector Floating-Point Reciprocal Estimate Instruction
5336//===----------------------------------------------------------------------===//
5337defm : VPatUnaryV_V<"int_riscv_vfrec7", "PseudoVFREC7", AllFloatVectors>;
5338
5339//===----------------------------------------------------------------------===//
5340// 14.11. Vector Floating-Point Min/Max Instructions
5341//===----------------------------------------------------------------------===//
5342defm : VPatBinaryV_VV_VX<"int_riscv_vfmin", "PseudoVFMIN", AllFloatVectors>;
5343defm : VPatBinaryV_VV_VX<"int_riscv_vfmax", "PseudoVFMAX", AllFloatVectors>;
5344
5345//===----------------------------------------------------------------------===//
5346// 14.12. Vector Floating-Point Sign-Injection Instructions
5347//===----------------------------------------------------------------------===//
5348defm : VPatBinaryV_VV_VX<"int_riscv_vfsgnj", "PseudoVFSGNJ", AllFloatVectors>;
5349defm : VPatBinaryV_VV_VX<"int_riscv_vfsgnjn", "PseudoVFSGNJN", AllFloatVectors>;
5350defm : VPatBinaryV_VV_VX<"int_riscv_vfsgnjx", "PseudoVFSGNJX", AllFloatVectors>;
5351
5352//===----------------------------------------------------------------------===//
5353// 14.13. Vector Floating-Point Compare Instructions
5354//===----------------------------------------------------------------------===//
5355defm : VPatBinaryM_VV_VX<"int_riscv_vmfeq", "PseudoVMFEQ", AllFloatVectors>;
5356defm : VPatBinaryM_VV_VX<"int_riscv_vmfle", "PseudoVMFLE", AllFloatVectors>;
5357defm : VPatBinaryM_VV_VX<"int_riscv_vmflt", "PseudoVMFLT", AllFloatVectors>;
5358defm : VPatBinaryM_VV_VX<"int_riscv_vmfne", "PseudoVMFNE", AllFloatVectors>;
5359defm : VPatBinaryM_VX<"int_riscv_vmfgt", "PseudoVMFGT", AllFloatVectors>;
5360defm : VPatBinaryM_VX<"int_riscv_vmfge", "PseudoVMFGE", AllFloatVectors>;
5361defm : VPatBinarySwappedM_VV<"int_riscv_vmfgt", "PseudoVMFLT", AllFloatVectors>;
5362defm : VPatBinarySwappedM_VV<"int_riscv_vmfge", "PseudoVMFLE", AllFloatVectors>;
5363
5364//===----------------------------------------------------------------------===//
5365// 14.14. Vector Floating-Point Classify Instruction
5366//===----------------------------------------------------------------------===//
5367defm : VPatConversionVI_VF<"int_riscv_vfclass", "PseudoVFCLASS">;
5368
5369//===----------------------------------------------------------------------===//
5370// 14.15. Vector Floating-Point Merge Instruction
5371//===----------------------------------------------------------------------===//
5372// We can use vmerge.vvm to support vector-vector vfmerge.
5373// NOTE: Clang previously used int_riscv_vfmerge for vector-vector, but now uses
5374// int_riscv_vmerge. Support both for compatibility.
5375defm : VPatBinaryV_VM_TAIL<"int_riscv_vmerge", "PseudoVMERGE",
5376                           /*CarryOut = */0, /*vtilist=*/AllFloatVectors>;
5377defm : VPatBinaryV_VM_TAIL<"int_riscv_vfmerge", "PseudoVMERGE",
5378                           /*CarryOut = */0, /*vtilist=*/AllFloatVectors>;
5379defm : VPatBinaryV_XM_TAIL<"int_riscv_vfmerge", "PseudoVFMERGE",
5380                           /*CarryOut = */0, /*vtilist=*/AllFloatVectors>;
5381
5382foreach fvti = AllFloatVectors in {
5383  defvar instr = !cast<Instruction>("PseudoVMERGE_VIM_"#fvti.LMul.MX);
5384  def : Pat<(fvti.Vector (int_riscv_vfmerge (fvti.Vector undef),
5385                                            (fvti.Vector fvti.RegClass:$rs2),
5386                                            (fvti.Scalar (fpimm0)),
5387                                            (fvti.Mask V0), VLOpFrag)),
5388            (instr fvti.RegClass:$rs2, 0, (fvti.Mask V0), GPR:$vl, fvti.Log2SEW)>;
5389  defvar instr_tu = !cast<Instruction>("PseudoVMERGE_VIM_"#fvti.LMul.MX#"_TU");
5390  def : Pat<(fvti.Vector (int_riscv_vfmerge (fvti.Vector fvti.RegClass:$merge),
5391                                            (fvti.Vector fvti.RegClass:$rs2),
5392                                            (fvti.Scalar (fpimm0)),
5393                                            (fvti.Mask V0), VLOpFrag)),
5394            (instr_tu fvti.RegClass:$merge, fvti.RegClass:$rs2, 0,
5395                      (fvti.Mask V0), GPR:$vl, fvti.Log2SEW)>;
5396}
5397
5398//===----------------------------------------------------------------------===//
5399// 14.17. Single-Width Floating-Point/Integer Type-Convert Instructions
5400//===----------------------------------------------------------------------===//
5401defm : VPatConversionVI_VF<"int_riscv_vfcvt_xu_f_v", "PseudoVFCVT_XU_F">;
5402defm : VPatConversionVI_VF<"int_riscv_vfcvt_rtz_xu_f_v", "PseudoVFCVT_RTZ_XU_F">;
5403defm : VPatConversionVI_VF<"int_riscv_vfcvt_x_f_v", "PseudoVFCVT_X_F">;
5404defm : VPatConversionVI_VF<"int_riscv_vfcvt_rtz_x_f_v", "PseudoVFCVT_RTZ_X_F">;
5405defm : VPatConversionVF_VI<"int_riscv_vfcvt_f_x_v", "PseudoVFCVT_F_X">;
5406defm : VPatConversionVF_VI<"int_riscv_vfcvt_f_xu_v", "PseudoVFCVT_F_XU">;
5407
5408//===----------------------------------------------------------------------===//
5409// 14.18. Widening Floating-Point/Integer Type-Convert Instructions
5410//===----------------------------------------------------------------------===//
5411defm : VPatConversionWI_VF<"int_riscv_vfwcvt_xu_f_v", "PseudoVFWCVT_XU_F">;
5412defm : VPatConversionWI_VF<"int_riscv_vfwcvt_x_f_v", "PseudoVFWCVT_X_F">;
5413defm : VPatConversionWI_VF<"int_riscv_vfwcvt_rtz_xu_f_v", "PseudoVFWCVT_RTZ_XU_F">;
5414defm : VPatConversionWI_VF<"int_riscv_vfwcvt_rtz_x_f_v", "PseudoVFWCVT_RTZ_X_F">;
5415defm : VPatConversionWF_VI<"int_riscv_vfwcvt_f_xu_v", "PseudoVFWCVT_F_XU">;
5416defm : VPatConversionWF_VI<"int_riscv_vfwcvt_f_x_v", "PseudoVFWCVT_F_X">;
5417defm : VPatConversionWF_VF<"int_riscv_vfwcvt_f_f_v", "PseudoVFWCVT_F_F">;
5418
5419//===----------------------------------------------------------------------===//
5420// 14.19. Narrowing Floating-Point/Integer Type-Convert Instructions
5421//===----------------------------------------------------------------------===//
5422defm : VPatConversionVI_WF<"int_riscv_vfncvt_xu_f_w", "PseudoVFNCVT_XU_F">;
5423defm : VPatConversionVI_WF<"int_riscv_vfncvt_x_f_w", "PseudoVFNCVT_X_F">;
5424defm : VPatConversionVI_WF<"int_riscv_vfncvt_rtz_xu_f_w", "PseudoVFNCVT_RTZ_XU_F">;
5425defm : VPatConversionVI_WF<"int_riscv_vfncvt_rtz_x_f_w", "PseudoVFNCVT_RTZ_X_F">;
5426defm : VPatConversionVF_WI <"int_riscv_vfncvt_f_xu_w", "PseudoVFNCVT_F_XU">;
5427defm : VPatConversionVF_WI <"int_riscv_vfncvt_f_x_w", "PseudoVFNCVT_F_X">;
5428defm : VPatConversionVF_WF<"int_riscv_vfncvt_f_f_w", "PseudoVFNCVT_F_F">;
5429defm : VPatConversionVF_WF<"int_riscv_vfncvt_rod_f_f_w", "PseudoVFNCVT_ROD_F_F">;
5430} // Predicates = [HasVInstructionsAnyF]
5431
5432let Predicates = [HasVInstructions] in {
5433//===----------------------------------------------------------------------===//
5434// 15.1. Vector Single-Width Integer Reduction Instructions
5435//===----------------------------------------------------------------------===//
5436defm : VPatReductionV_VS<"int_riscv_vredsum", "PseudoVREDSUM">;
5437defm : VPatReductionV_VS<"int_riscv_vredand", "PseudoVREDAND">;
5438defm : VPatReductionV_VS<"int_riscv_vredor", "PseudoVREDOR">;
5439defm : VPatReductionV_VS<"int_riscv_vredxor", "PseudoVREDXOR">;
5440defm : VPatReductionV_VS<"int_riscv_vredminu", "PseudoVREDMINU">;
5441defm : VPatReductionV_VS<"int_riscv_vredmin", "PseudoVREDMIN">;
5442defm : VPatReductionV_VS<"int_riscv_vredmaxu", "PseudoVREDMAXU">;
5443defm : VPatReductionV_VS<"int_riscv_vredmax", "PseudoVREDMAX">;
5444
5445//===----------------------------------------------------------------------===//
5446// 15.2. Vector Widening Integer Reduction Instructions
5447//===----------------------------------------------------------------------===//
5448defm : VPatReductionW_VS<"int_riscv_vwredsumu", "PseudoVWREDSUMU">;
5449defm : VPatReductionW_VS<"int_riscv_vwredsum", "PseudoVWREDSUM">;
5450} // Predicates = [HasVInstructions]
5451
5452let Predicates = [HasVInstructionsAnyF] in {
5453//===----------------------------------------------------------------------===//
5454// 15.3. Vector Single-Width Floating-Point Reduction Instructions
5455//===----------------------------------------------------------------------===//
5456defm : VPatReductionV_VS<"int_riscv_vfredosum", "PseudoVFREDOSUM", /*IsFloat=*/1>;
5457defm : VPatReductionV_VS<"int_riscv_vfredusum", "PseudoVFREDUSUM", /*IsFloat=*/1>;
5458defm : VPatReductionV_VS<"int_riscv_vfredmin", "PseudoVFREDMIN", /*IsFloat=*/1>;
5459defm : VPatReductionV_VS<"int_riscv_vfredmax", "PseudoVFREDMAX", /*IsFloat=*/1>;
5460
5461//===----------------------------------------------------------------------===//
5462// 15.4. Vector Widening Floating-Point Reduction Instructions
5463//===----------------------------------------------------------------------===//
5464defm : VPatReductionW_VS<"int_riscv_vfwredusum", "PseudoVFWREDUSUM", /*IsFloat=*/1>;
5465defm : VPatReductionW_VS<"int_riscv_vfwredosum", "PseudoVFWREDOSUM", /*IsFloat=*/1>;
5466
5467} // Predicates = [HasVInstructionsAnyF]
5468
5469//===----------------------------------------------------------------------===//
5470// 16. Vector Mask Instructions
5471//===----------------------------------------------------------------------===//
5472
5473let Predicates = [HasVInstructions] in {
5474//===----------------------------------------------------------------------===//
5475// 16.1 Vector Mask-Register Logical Instructions
5476//===----------------------------------------------------------------------===//
5477defm : VPatBinaryM_MM<"int_riscv_vmand", "PseudoVMAND">;
5478defm : VPatBinaryM_MM<"int_riscv_vmnand", "PseudoVMNAND">;
5479defm : VPatBinaryM_MM<"int_riscv_vmandn", "PseudoVMANDN">;
5480defm : VPatBinaryM_MM<"int_riscv_vmxor", "PseudoVMXOR">;
5481defm : VPatBinaryM_MM<"int_riscv_vmor", "PseudoVMOR">;
5482defm : VPatBinaryM_MM<"int_riscv_vmnor", "PseudoVMNOR">;
5483defm : VPatBinaryM_MM<"int_riscv_vmorn", "PseudoVMORN">;
5484defm : VPatBinaryM_MM<"int_riscv_vmxnor", "PseudoVMXNOR">;
5485
5486// pseudo instructions
5487defm : VPatNullaryM<"int_riscv_vmclr", "PseudoVMCLR">;
5488defm : VPatNullaryM<"int_riscv_vmset", "PseudoVMSET">;
5489
5490//===----------------------------------------------------------------------===//
5491// 16.2. Vector count population in mask vcpop.m
5492//===----------------------------------------------------------------------===//
5493defm : VPatUnaryS_M<"int_riscv_vcpop", "PseudoVCPOP">;
5494
5495//===----------------------------------------------------------------------===//
5496// 16.3. vfirst find-first-set mask bit
5497//===----------------------------------------------------------------------===//
5498defm : VPatUnaryS_M<"int_riscv_vfirst", "PseudoVFIRST">;
5499
5500//===----------------------------------------------------------------------===//
5501// 16.4. vmsbf.m set-before-first mask bit
5502//===----------------------------------------------------------------------===//
5503defm : VPatUnaryM_M<"int_riscv_vmsbf", "PseudoVMSBF">;
5504
5505//===----------------------------------------------------------------------===//
5506// 16.5. vmsif.m set-including-first mask bit
5507//===----------------------------------------------------------------------===//
5508defm : VPatUnaryM_M<"int_riscv_vmsif", "PseudoVMSIF">;
5509
5510//===----------------------------------------------------------------------===//
5511// 16.6. vmsof.m set-only-first mask bit
5512//===----------------------------------------------------------------------===//
5513defm : VPatUnaryM_M<"int_riscv_vmsof", "PseudoVMSOF">;
5514
5515//===----------------------------------------------------------------------===//
5516// 16.8.  Vector Iota Instruction
5517//===----------------------------------------------------------------------===//
5518defm : VPatUnaryV_M<"int_riscv_viota", "PseudoVIOTA">;
5519
5520//===----------------------------------------------------------------------===//
5521// 16.9. Vector Element Index Instruction
5522//===----------------------------------------------------------------------===//
5523defm : VPatNullaryV<"int_riscv_vid", "PseudoVID">;
5524
5525} // Predicates = [HasVInstructions]
5526
5527//===----------------------------------------------------------------------===//
5528// 17. Vector Permutation Instructions
5529//===----------------------------------------------------------------------===//
5530
5531//===----------------------------------------------------------------------===//
5532// 17.1. Integer Scalar Move Instructions
5533//===----------------------------------------------------------------------===//
5534
5535let Predicates = [HasVInstructions] in {
5536foreach vti = AllIntegerVectors in {
5537  def : Pat<(riscv_vmv_x_s (vti.Vector vti.RegClass:$rs2)),
5538            (!cast<Instruction>("PseudoVMV_X_S_" # vti.LMul.MX) $rs2, vti.Log2SEW)>;
5539  // vmv.s.x is handled with a custom node in RISCVInstrInfoVVLPatterns.td
5540}
5541} // Predicates = [HasVInstructions]
5542
5543//===----------------------------------------------------------------------===//
5544// 17.2. Floating-Point Scalar Move Instructions
5545//===----------------------------------------------------------------------===//
5546
5547let Predicates = [HasVInstructionsAnyF] in {
5548foreach fvti = AllFloatVectors in {
5549  defvar instr = !cast<Instruction>("PseudoVFMV_"#fvti.ScalarSuffix#"_S_" #
5550                                    fvti.LMul.MX);
5551  def : Pat<(fvti.Scalar (int_riscv_vfmv_f_s (fvti.Vector fvti.RegClass:$rs2))),
5552                         (instr $rs2, fvti.Log2SEW)>;
5553
5554  def : Pat<(fvti.Vector (int_riscv_vfmv_s_f (fvti.Vector fvti.RegClass:$rs1),
5555                         (fvti.Scalar fvti.ScalarRegClass:$rs2), VLOpFrag)),
5556            (!cast<Instruction>("PseudoVFMV_S_"#fvti.ScalarSuffix#"_" #
5557                                fvti.LMul.MX)
5558             (fvti.Vector $rs1),
5559             (fvti.Scalar fvti.ScalarRegClass:$rs2),
5560             GPR:$vl, fvti.Log2SEW)>;
5561
5562  def : Pat<(fvti.Vector (int_riscv_vfmv_s_f (fvti.Vector fvti.RegClass:$rs1),
5563                         (fvti.Scalar (fpimm0)), VLOpFrag)),
5564            (!cast<Instruction>("PseudoVMV_S_X_" # fvti.LMul.MX)
5565             (fvti.Vector $rs1), X0, GPR:$vl, fvti.Log2SEW)>;
5566}
5567} // Predicates = [HasVInstructionsAnyF]
5568
5569//===----------------------------------------------------------------------===//
5570// 17.3. Vector Slide Instructions
5571//===----------------------------------------------------------------------===//
5572let Predicates = [HasVInstructions] in {
5573  defm : VPatTernaryV_VX_VI<"int_riscv_vslideup", "PseudoVSLIDEUP", AllIntegerVectors, uimm5>;
5574  defm : VPatTernaryV_VX_VI<"int_riscv_vslidedown", "PseudoVSLIDEDOWN", AllIntegerVectors, uimm5>;
5575  defm : VPatBinaryV_VX<"int_riscv_vslide1up", "PseudoVSLIDE1UP", AllIntegerVectors>;
5576  defm : VPatBinaryV_VX<"int_riscv_vslide1down", "PseudoVSLIDE1DOWN", AllIntegerVectors>;
5577} // Predicates = [HasVInstructions]
5578
5579let Predicates = [HasVInstructionsAnyF] in {
5580  defm : VPatTernaryV_VX_VI<"int_riscv_vslideup", "PseudoVSLIDEUP", AllFloatVectors, uimm5>;
5581  defm : VPatTernaryV_VX_VI<"int_riscv_vslidedown", "PseudoVSLIDEDOWN", AllFloatVectors, uimm5>;
5582  defm : VPatBinaryV_VX<"int_riscv_vfslide1up", "PseudoVFSLIDE1UP", AllFloatVectors>;
5583  defm : VPatBinaryV_VX<"int_riscv_vfslide1down", "PseudoVFSLIDE1DOWN", AllFloatVectors>;
5584} // Predicates = [HasVInstructionsAnyF]
5585
5586//===----------------------------------------------------------------------===//
5587// 17.4. Vector Register Gather Instructions
5588//===----------------------------------------------------------------------===//
5589let Predicates = [HasVInstructions] in {
5590  defm : VPatBinaryV_VV_VX_VI_INT<"int_riscv_vrgather", "PseudoVRGATHER",
5591                                  AllIntegerVectors, uimm5>;
5592  defm : VPatBinaryV_VV_INT_EEW<"int_riscv_vrgatherei16_vv", "PseudoVRGATHEREI16",
5593                                /* eew */ 16, AllIntegerVectors>;
5594} // Predicates = [HasVInstructions]
5595
5596let Predicates = [HasVInstructionsAnyF] in {
5597  defm : VPatBinaryV_VV_VX_VI_INT<"int_riscv_vrgather", "PseudoVRGATHER",
5598                                  AllFloatVectors, uimm5>;
5599  defm : VPatBinaryV_VV_INT_EEW<"int_riscv_vrgatherei16_vv", "PseudoVRGATHEREI16",
5600                                /* eew */ 16, AllFloatVectors>;
5601} // Predicates = [HasVInstructionsAnyF]
5602
5603//===----------------------------------------------------------------------===//
5604// 17.5. Vector Compress Instruction
5605//===----------------------------------------------------------------------===//
5606let Predicates = [HasVInstructions] in {
5607  defm : VPatUnaryV_V_AnyMask<"int_riscv_vcompress", "PseudoVCOMPRESS", AllIntegerVectors>;
5608} // Predicates = [HasVInstructions]
5609
5610let Predicates = [HasVInstructionsAnyF] in {
5611  defm : VPatUnaryV_V_AnyMask<"int_riscv_vcompress", "PseudoVCOMPRESS", AllFloatVectors>;
5612} // Predicates = [HasVInstructionsAnyF]
5613
5614// Include the non-intrinsic ISel patterns
5615include "RISCVInstrInfoVVLPatterns.td"
5616include "RISCVInstrInfoVSDPatterns.td"
5617