xref: /llvm-project/llvm/lib/Target/AArch64/SVEInstrFormats.td (revision 5d6d982df61d16b6d498e6d59dd91c059679d3d8)
1//=-- SVEInstrFormats.td -  AArch64 SVE Instruction classes -*- 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// AArch64 Scalable Vector Extension (SVE) Instruction Class Definitions.
10//
11//===----------------------------------------------------------------------===//
12
13// Helper class to hold conversions of legal fixed-length vector types.
14class NEONType<ValueType VT> {
15  // The largest legal scalable vector type that can hold VT.
16  ValueType SVEContainer = !cond(
17    !eq(VT, v8i8): nxv16i8,
18    !eq(VT, v16i8): nxv16i8,
19    !eq(VT, v4i16): nxv8i16,
20    !eq(VT, v8i16): nxv8i16,
21    !eq(VT, v2i32): nxv4i32,
22    !eq(VT, v4i32): nxv4i32,
23    !eq(VT, v1i64): nxv2i64,
24    !eq(VT, v2i64): nxv2i64,
25    !eq(VT, v4f16): nxv8f16,
26    !eq(VT, v8f16): nxv8f16,
27    !eq(VT, v2f32): nxv4f32,
28    !eq(VT, v4f32): nxv4f32,
29    !eq(VT, v1f64): nxv2f64,
30    !eq(VT, v2f64): nxv2f64,
31    !eq(VT, v4bf16): nxv8bf16,
32    !eq(VT, v8bf16): nxv8bf16,
33    true : untyped);
34}
35
36// Helper class to hold conversions of legal scalable vector types.
37class SVEType<ValueType VT> {
38  // The largest legal scalable vector type that can hold VT.
39  // Non-matches return VT because only packed types remain.
40  ValueType Packed = !cond(
41    !eq(VT, nxv2f16): nxv8f16,
42    !eq(VT, nxv4f16): nxv8f16,
43    !eq(VT, nxv2f32): nxv4f32,
44    !eq(VT, nxv2bf16): nxv8bf16,
45    !eq(VT, nxv4bf16): nxv8bf16,
46    true : VT);
47
48  // The legal scalable vector that is half the length of VT.
49  ValueType HalfLength = !cond(
50    !eq(VT, nxv8f16): nxv4f16,
51    !eq(VT, nxv4f16): nxv2f16,
52    !eq(VT, nxv4f32): nxv2f32,
53    !eq(VT, nxv8bf16): nxv4bf16,
54    !eq(VT, nxv4bf16): nxv2bf16,
55    true : untyped);
56
57  // The legal scalable vector that is quarter the length of VT.
58  ValueType QuarterLength = !cond(
59    !eq(VT, nxv8f16): nxv2f16,
60    !eq(VT, nxv8bf16): nxv2bf16,
61    true : untyped);
62
63  // The 64-bit vector subreg of VT.
64  ValueType DSub = !cond(
65    !eq(VT, nxv16i8): v8i8,
66    !eq(VT, nxv8i16): v4i16,
67    !eq(VT, nxv4i32): v2i32,
68    !eq(VT, nxv2i64): v1i64,
69    !eq(VT, nxv2f16): v4f16,
70    !eq(VT, nxv4f16): v4f16,
71    !eq(VT, nxv8f16): v4f16,
72    !eq(VT, nxv2f32): v2f32,
73    !eq(VT, nxv4f32): v2f32,
74    !eq(VT, nxv2f64): v1f64,
75    !eq(VT, nxv2bf16): v4bf16,
76    !eq(VT, nxv4bf16): v4bf16,
77    !eq(VT, nxv8bf16): v4bf16,
78    true : untyped);
79
80    // The 128-bit vector subreg of VT.
81  ValueType ZSub = !cond(
82    !eq(VT, nxv16i8): v16i8,
83    !eq(VT, nxv8i16): v8i16,
84    !eq(VT, nxv4i32): v4i32,
85    !eq(VT, nxv2i64): v2i64,
86    !eq(VT, nxv2f16): v8f16,
87    !eq(VT, nxv4f16): v8f16,
88    !eq(VT, nxv8f16): v8f16,
89    !eq(VT, nxv2f32): v4f32,
90    !eq(VT, nxv4f32): v4f32,
91    !eq(VT, nxv2f64): v2f64,
92    !eq(VT, nxv2bf16): v8bf16,
93    !eq(VT, nxv4bf16): v8bf16,
94    !eq(VT, nxv8bf16): v8bf16,
95    true : untyped);
96
97  // The legal scalar used to hold a vector element.
98  ValueType EltAsScalar = !cond(
99    !eq(VT, nxv16i8): i32,
100    !eq(VT, nxv8i16): i32,
101    !eq(VT, nxv4i32): i32,
102    !eq(VT, nxv2i64): i64,
103    !eq(VT, nxv2f16): f16,
104    !eq(VT, nxv4f16): f16,
105    !eq(VT, nxv8f16): f16,
106    !eq(VT, nxv2f32): f32,
107    !eq(VT, nxv4f32): f32,
108    !eq(VT, nxv2f64): f64,
109    !eq(VT, nxv2bf16): bf16,
110    !eq(VT, nxv4bf16): bf16,
111    !eq(VT, nxv8bf16): bf16,
112    true : untyped);
113}
114
115def SDT_AArch64Setcc : SDTypeProfile<1, 4, [
116  SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisVec<3>,
117  SDTCVecEltisVT<0, i1>, SDTCVecEltisVT<1, i1>, SDTCisSameAs<2, 3>,
118  SDTCisVT<4, OtherVT>
119]>;
120
121def AArch64setcc_z : SDNode<"AArch64ISD::SETCC_MERGE_ZERO", SDT_AArch64Setcc>;
122def AArch64setcc_z_oneuse : PatFrag<(ops node:$pg, node:$op1, node:$op2, node:$cc),
123                                    (AArch64setcc_z node:$pg, node:$op1, node:$op2, node:$cc), [{
124  return N->hasOneUse();
125}]>;
126
127def SVEPatternOperand : AsmOperandClass {
128  let Name = "SVEPattern";
129  let ParserMethod = "tryParseSVEPattern";
130  let PredicateMethod = "isSVEPattern";
131  let RenderMethod = "addImmOperands";
132  let DiagnosticType = "InvalidSVEPattern";
133}
134
135def sve_pred_enum : Operand<i32>, TImmLeaf<i32, [{
136  return (((uint32_t)Imm) < 32);
137  }]> {
138
139  let PrintMethod = "printSVEPattern";
140  let ParserMatchClass = SVEPatternOperand;
141}
142
143def SVEVecLenSpecifierOperand : AsmOperandClass {
144  let Name = "SVEVecLenSpecifier";
145  let ParserMethod = "tryParseSVEVecLenSpecifier";
146  let PredicateMethod = "isSVEVecLenSpecifier";
147  let RenderMethod = "addImmOperands";
148  let DiagnosticType = "InvalidSVEVecLenSpecifier";
149}
150
151def sve_vec_len_specifier_enum : Operand<i32>, TImmLeaf<i32, [{
152  return (((uint32_t)Imm) < 2);
153  }]> {
154
155  let PrintMethod = "printSVEVecLenSpecifier";
156  let ParserMatchClass = SVEVecLenSpecifierOperand;
157}
158
159def SVEPrefetchOperand : AsmOperandClass {
160  let Name = "SVEPrefetch";
161  let ParserMethod = "tryParsePrefetch<true>";
162  let PredicateMethod = "isPrefetch";
163  let RenderMethod = "addPrefetchOperands";
164}
165
166def sve_prfop : Operand<i32>, TImmLeaf<i32, [{
167    return (((uint32_t)Imm) <= 15);
168  }]> {
169  let PrintMethod = "printPrefetchOp<true>";
170  let ParserMatchClass = SVEPrefetchOperand;
171}
172
173class SVELogicalImmOperand<int Width> : AsmOperandClass {
174  let Name = "SVELogicalImm" # Width;
175  let DiagnosticType = "LogicalSecondSource";
176  let PredicateMethod = "isLogicalImm<int" # Width # "_t>";
177  let RenderMethod = "addLogicalImmOperands<int" # Width # "_t>";
178}
179
180def sve_logical_imm8 : Operand<i64> {
181  let ParserMatchClass = SVELogicalImmOperand<8>;
182  let PrintMethod = "printLogicalImm<int8_t>";
183
184  let MCOperandPredicate = [{
185    if (!MCOp.isImm())
186      return false;
187    int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64);
188    return AArch64_AM::isSVEMaskOfIdenticalElements<int8_t>(Val);
189  }];
190}
191
192def sve_logical_imm16 : Operand<i64> {
193  let ParserMatchClass = SVELogicalImmOperand<16>;
194  let PrintMethod = "printLogicalImm<int16_t>";
195
196  let MCOperandPredicate = [{
197    if (!MCOp.isImm())
198      return false;
199    int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64);
200    return AArch64_AM::isSVEMaskOfIdenticalElements<int16_t>(Val);
201  }];
202}
203
204def sve_logical_imm32 : Operand<i64> {
205  let ParserMatchClass = SVELogicalImmOperand<32>;
206  let PrintMethod = "printLogicalImm<int32_t>";
207
208  let MCOperandPredicate = [{
209    if (!MCOp.isImm())
210      return false;
211    int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64);
212    return AArch64_AM::isSVEMaskOfIdenticalElements<int32_t>(Val);
213  }];
214}
215
216class SVEPreferredLogicalImmOperand<int Width> : AsmOperandClass {
217  let Name = "SVEPreferredLogicalImm" # Width;
218  let PredicateMethod = "isSVEPreferredLogicalImm<int" # Width # "_t>";
219  let RenderMethod = "addLogicalImmOperands<int" # Width # "_t>";
220}
221
222def sve_preferred_logical_imm16 : Operand<i64> {
223  let ParserMatchClass = SVEPreferredLogicalImmOperand<16>;
224  let PrintMethod = "printSVELogicalImm<int16_t>";
225
226  let MCOperandPredicate = [{
227    if (!MCOp.isImm())
228      return false;
229    int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64);
230    return AArch64_AM::isSVEMaskOfIdenticalElements<int16_t>(Val) &&
231           AArch64_AM::isSVEMoveMaskPreferredLogicalImmediate(Val);
232  }];
233}
234
235def sve_preferred_logical_imm32 : Operand<i64> {
236  let ParserMatchClass =  SVEPreferredLogicalImmOperand<32>;
237  let PrintMethod = "printSVELogicalImm<int32_t>";
238
239  let MCOperandPredicate = [{
240    if (!MCOp.isImm())
241      return false;
242    int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64);
243    return AArch64_AM::isSVEMaskOfIdenticalElements<int32_t>(Val) &&
244           AArch64_AM::isSVEMoveMaskPreferredLogicalImmediate(Val);
245  }];
246}
247
248def sve_preferred_logical_imm64 : Operand<i64> {
249  let ParserMatchClass = SVEPreferredLogicalImmOperand<64>;
250  let PrintMethod = "printSVELogicalImm<int64_t>";
251
252  let MCOperandPredicate = [{
253    if (!MCOp.isImm())
254      return false;
255    int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64);
256    return AArch64_AM::isSVEMaskOfIdenticalElements<int64_t>(Val) &&
257           AArch64_AM::isSVEMoveMaskPreferredLogicalImmediate(Val);
258  }];
259}
260
261class SVELogicalImmNotOperand<int Width> : AsmOperandClass {
262  let Name = "SVELogicalImm" # Width # "Not";
263  let DiagnosticType = "LogicalSecondSource";
264  let PredicateMethod = "isLogicalImm<int" # Width # "_t>";
265  let RenderMethod = "addLogicalImmNotOperands<int" # Width # "_t>";
266}
267
268def sve_logical_imm8_not : Operand<i64> {
269  let ParserMatchClass = SVELogicalImmNotOperand<8>;
270}
271
272def sve_logical_imm16_not : Operand<i64> {
273  let ParserMatchClass = SVELogicalImmNotOperand<16>;
274}
275
276def sve_logical_imm32_not : Operand<i64> {
277  let ParserMatchClass = SVELogicalImmNotOperand<32>;
278}
279
280class SVEShiftedImmOperand<int ElementWidth, string Infix, string Predicate>
281    : AsmOperandClass {
282  let Name = "SVE" # Infix # "Imm" # ElementWidth;
283  let DiagnosticType = "Invalid" # Name;
284  let RenderMethod = "addImmWithOptionalShiftOperands<8>";
285  let ParserMethod = "tryParseImmWithOptionalShift";
286  let PredicateMethod = Predicate;
287}
288
289def SVECpyImmOperand8  : SVEShiftedImmOperand<8,  "Cpy", "isSVECpyImm<int8_t>">;
290def SVECpyImmOperand16 : SVEShiftedImmOperand<16, "Cpy", "isSVECpyImm<int16_t>">;
291def SVECpyImmOperand32 : SVEShiftedImmOperand<32, "Cpy", "isSVECpyImm<int32_t>">;
292def SVECpyImmOperand64 : SVEShiftedImmOperand<64, "Cpy", "isSVECpyImm<int64_t>">;
293
294def SVEAddSubImmOperand8  : SVEShiftedImmOperand<8,  "AddSub", "isSVEAddSubImm<int8_t>">;
295def SVEAddSubImmOperand16 : SVEShiftedImmOperand<16, "AddSub", "isSVEAddSubImm<int16_t>">;
296def SVEAddSubImmOperand32 : SVEShiftedImmOperand<32, "AddSub", "isSVEAddSubImm<int32_t>">;
297def SVEAddSubImmOperand64 : SVEShiftedImmOperand<64, "AddSub", "isSVEAddSubImm<int64_t>">;
298
299class imm8_opt_lsl<int ElementWidth, string printType,
300                   AsmOperandClass OpndClass>
301    : Operand<i32> {
302  let EncoderMethod = "getImm8OptLsl";
303  let DecoderMethod = "DecodeImm8OptLsl<" # ElementWidth # ">";
304  let PrintMethod = "printImm8OptLsl<" # printType # ">";
305  let ParserMatchClass = OpndClass;
306  let MIOperandInfo = (ops i32imm, i32imm);
307}
308
309def cpy_imm8_opt_lsl_i8  : imm8_opt_lsl<8,  "int8_t",  SVECpyImmOperand8>;
310def cpy_imm8_opt_lsl_i16 : imm8_opt_lsl<16, "int16_t", SVECpyImmOperand16>;
311def cpy_imm8_opt_lsl_i32 : imm8_opt_lsl<32, "int32_t", SVECpyImmOperand32>;
312def cpy_imm8_opt_lsl_i64 : imm8_opt_lsl<64, "int64_t", SVECpyImmOperand64>;
313
314def addsub_imm8_opt_lsl_i8  : imm8_opt_lsl<8,  "uint8_t",  SVEAddSubImmOperand8>;
315def addsub_imm8_opt_lsl_i16 : imm8_opt_lsl<16, "uint16_t", SVEAddSubImmOperand16>;
316def addsub_imm8_opt_lsl_i32 : imm8_opt_lsl<32, "uint32_t", SVEAddSubImmOperand32>;
317def addsub_imm8_opt_lsl_i64 : imm8_opt_lsl<64, "uint64_t", SVEAddSubImmOperand64>;
318
319def SVEAddSubImm8Pat  : ComplexPattern<i32, 2, "SelectSVEAddSubImm<MVT::i8>", []>;
320def SVEAddSubImm16Pat : ComplexPattern<i32, 2, "SelectSVEAddSubImm<MVT::i16>", []>;
321def SVEAddSubImm32Pat : ComplexPattern<i32, 2, "SelectSVEAddSubImm<MVT::i32>", []>;
322def SVEAddSubImm64Pat : ComplexPattern<i64, 2, "SelectSVEAddSubImm<MVT::i64>", []>;
323
324def SVEAddSubSSatNegImm8Pat  : ComplexPattern<i32, 2, "SelectSVEAddSubSSatImm<MVT::i8, true>", []>;
325def SVEAddSubSSatNegImm16Pat : ComplexPattern<i32, 2, "SelectSVEAddSubSSatImm<MVT::i16, true>", []>;
326def SVEAddSubSSatNegImm32Pat : ComplexPattern<i32, 2, "SelectSVEAddSubSSatImm<MVT::i32, true>", []>;
327def SVEAddSubSSatNegImm64Pat : ComplexPattern<i64, 2, "SelectSVEAddSubSSatImm<MVT::i64, true>", []>;
328
329def SVEAddSubSSatPosImm8Pat  : ComplexPattern<i32, 2, "SelectSVEAddSubSSatImm<MVT::i8, false>", []>;
330def SVEAddSubSSatPosImm16Pat : ComplexPattern<i32, 2, "SelectSVEAddSubSSatImm<MVT::i16, false>", []>;
331def SVEAddSubSSatPosImm32Pat : ComplexPattern<i32, 2, "SelectSVEAddSubSSatImm<MVT::i32, false>", []>;
332def SVEAddSubSSatPosImm64Pat : ComplexPattern<i64, 2, "SelectSVEAddSubSSatImm<MVT::i64, false>", []>;
333
334def SVECpyDupImm8Pat  : ComplexPattern<i32, 2, "SelectSVECpyDupImm<MVT::i8>", []>;
335def SVECpyDupImm16Pat : ComplexPattern<i32, 2, "SelectSVECpyDupImm<MVT::i16>", []>;
336def SVECpyDupImm32Pat : ComplexPattern<i32, 2, "SelectSVECpyDupImm<MVT::i32>", []>;
337def SVECpyDupImm64Pat : ComplexPattern<i64, 2, "SelectSVECpyDupImm<MVT::i64>", []>;
338
339def SVELogicalImm8Pat  : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i8>", []>;
340def SVELogicalImm16Pat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i16>", []>;
341def SVELogicalImm32Pat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i32>", []>;
342def SVELogicalImm64Pat : ComplexPattern<i64, 1, "SelectSVELogicalImm<MVT::i64>", []>;
343
344def SVELogicalImm8NotPat  : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i8, true>", []>;
345def SVELogicalImm16NotPat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i16, true>", []>;
346def SVELogicalImm32NotPat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i32, true>", []>;
347def SVELogicalImm64NotPat : ComplexPattern<i64, 1, "SelectSVELogicalImm<MVT::i64, true>", []>;
348
349def SVEArithUImm8Pat  : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i8>", []>;
350def SVEArithUImm16Pat  : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i16>", []>;
351def SVEArithUImm32Pat  : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i32>", []>;
352def SVEArithUImm64Pat  : ComplexPattern<i64, 1, "SelectSVEArithImm<MVT::i64>", []>;
353
354def SVEArithSImmPat32 : ComplexPattern<i32, 1, "SelectSVESignedArithImm", []>;
355def SVEArithSImmPat64 : ComplexPattern<i64, 1, "SelectSVESignedArithImm", []>;
356
357def SVEShiftImmL8  : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 7>",  []>;
358def SVEShiftImmL16 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 15>", []>;
359def SVEShiftImmL32 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 31>", []>;
360def SVEShiftImmL64 : ComplexPattern<i64, 1, "SelectSVEShiftImm<0, 63>", []>;
361def SVEShiftImmR8  : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 8,  true>", []>;
362def SVEShiftImmR16 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 16, true>", []>;
363def SVEShiftImmR32 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 32, true>", []>;
364def SVEShiftImmR64 : ComplexPattern<i64, 1, "SelectSVEShiftImm<1, 64, true>", []>;
365
366def SVEShiftSplatImmR : ComplexPattern<iAny, 1, "SelectSVEShiftSplatImmR", []>;
367
368def SVEAllActive : ComplexPattern<untyped, 0, "SelectAllActivePredicate", []>;
369def SVEAnyPredicate : ComplexPattern<untyped, 0, "SelectAnyPredicate", []>;
370
371class SVEExactFPImm<string Suffix, string ValA, string ValB> : AsmOperandClass {
372  let Name = "SVEExactFPImmOperand" # Suffix;
373  let DiagnosticType = "Invalid" # Name;
374  let ParserMethod = "tryParseFPImm<false>";
375  let PredicateMethod = "isExactFPImm<" # ValA # ", " # ValB # ">";
376  let RenderMethod = "addExactFPImmOperands<" # ValA # ", " # ValB # ">";
377}
378
379class SVEExactFPImmOperand<string Suffix, string ValA, string ValB> : Operand<i32> {
380  let PrintMethod = "printExactFPImm<" # ValA # ", " # ValB # ">";
381  let ParserMatchClass = SVEExactFPImm<Suffix, ValA, ValB>;
382}
383
384def sve_fpimm_half_one
385    : SVEExactFPImmOperand<"HalfOne", "AArch64ExactFPImm::half",
386                           "AArch64ExactFPImm::one">;
387def sve_fpimm_half_two
388    : SVEExactFPImmOperand<"HalfTwo", "AArch64ExactFPImm::half",
389                           "AArch64ExactFPImm::two">;
390def sve_fpimm_zero_one
391    : SVEExactFPImmOperand<"ZeroOne", "AArch64ExactFPImm::zero",
392                           "AArch64ExactFPImm::one">;
393
394def sve_incdec_imm : Operand<i32>, TImmLeaf<i32, [{
395  return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
396}]> {
397  let ParserMatchClass = Imm1_16Operand;
398  let EncoderMethod = "getSVEIncDecImm";
399  let DecoderMethod = "DecodeSVEIncDecImm";
400}
401
402// This allows i32 immediate extraction from i64 based arithmetic.
403def sve_cnt_mul_imm_i32 : ComplexPattern<i32, 1, "SelectCntImm<1, 16, 1, false>">;
404def sve_cnt_mul_imm_i64 : ComplexPattern<i64, 1, "SelectCntImm<1, 16, 1, false>">;
405def sve_cnt_shl_imm     : ComplexPattern<i64, 1, "SelectCntImm<1, 16, 1, true>">;
406
407def sve_ext_imm_0_31  : ComplexPattern<i64, 1, "SelectEXTImm<31, 8>">;
408def sve_ext_imm_0_63  : ComplexPattern<i64, 1, "SelectEXTImm<63, 4>">;
409def sve_ext_imm_0_127 : ComplexPattern<i64, 1, "SelectEXTImm<127, 2>">;
410def sve_ext_imm_0_255 : ComplexPattern<i64, 1, "SelectEXTImm<255, 1>">;
411
412def int_aarch64_sve_cntp_oneuse : PatFrag<(ops node:$pred, node:$src2),
413                                          (int_aarch64_sve_cntp node:$pred, node:$src2), [{
414  return N->hasOneUse();
415}]>;
416
417def step_vector_oneuse : PatFrag<(ops node:$idx),
418                                 (step_vector node:$idx), [{
419  return N->hasOneUse();
420}]>;
421
422
423//===----------------------------------------------------------------------===//
424// SVE PTrue - These are used extensively throughout the pattern matching so
425//             it's important we define them first.
426//===----------------------------------------------------------------------===//
427
428class sve_int_ptrue<bits<2> sz8_64, bits<3> opc, string asm, PPRRegOp pprty,
429                    ValueType vt, SDPatternOperator op>
430: I<(outs pprty:$Pd), (ins sve_pred_enum:$pattern),
431  asm, "\t$Pd, $pattern",
432  "",
433  [(set (vt pprty:$Pd), (op sve_pred_enum:$pattern))]>, Sched<[]> {
434  bits<4> Pd;
435  bits<5> pattern;
436  let Inst{31-24} = 0b00100101;
437  let Inst{23-22} = sz8_64;
438  let Inst{21-19} = 0b011;
439  let Inst{18-17} = opc{2-1};
440  let Inst{16}    = opc{0};
441  let Inst{15-10} = 0b111000;
442  let Inst{9-5}   = pattern;
443  let Inst{4}     = 0b0;
444  let Inst{3-0}   = Pd;
445
446  let Defs = !if(!eq (opc{0}, 1), [NZCV], []);
447  let ElementSize = pprty.ElementSize;
448  let hasSideEffects = 0;
449  let isReMaterializable = 1;
450  let Uses = [VG];
451}
452
453multiclass sve_int_ptrue<bits<3> opc, string asm, SDPatternOperator op> {
454  def _B : sve_int_ptrue<0b00, opc, asm, PPR8, nxv16i1, op>;
455  def _H : sve_int_ptrue<0b01, opc, asm, PPR16, nxv8i1, op>;
456  def _S : sve_int_ptrue<0b10, opc, asm, PPR32, nxv4i1, op>;
457  def _D : sve_int_ptrue<0b11, opc, asm, PPR64, nxv2i1, op>;
458
459  def : InstAlias<asm # "\t$Pd",
460                  (!cast<Instruction>(NAME # _B) PPR8:$Pd, 0b11111), 1>;
461  def : InstAlias<asm # "\t$Pd",
462                  (!cast<Instruction>(NAME # _H) PPR16:$Pd, 0b11111), 1>;
463  def : InstAlias<asm # "\t$Pd",
464                  (!cast<Instruction>(NAME # _S) PPR32:$Pd, 0b11111), 1>;
465  def : InstAlias<asm # "\t$Pd",
466                  (!cast<Instruction>(NAME # _D) PPR64:$Pd, 0b11111), 1>;
467}
468
469def SDT_AArch64PTrue : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVT<1, i32>]>;
470def AArch64ptrue : SDNode<"AArch64ISD::PTRUE", SDT_AArch64PTrue>;
471
472let Predicates = [HasSVE_or_SME] in {
473  defm PTRUE  : sve_int_ptrue<0b000, "ptrue", AArch64ptrue>;
474  defm PTRUES : sve_int_ptrue<0b001, "ptrues", null_frag>;
475
476  def : Pat<(nxv16i1 immAllOnesV), (PTRUE_B 31)>;
477  def : Pat<(nxv8i1 immAllOnesV), (PTRUE_H 31)>;
478  def : Pat<(nxv4i1 immAllOnesV), (PTRUE_S 31)>;
479  def : Pat<(nxv2i1 immAllOnesV), (PTRUE_D 31)>;
480}
481
482//===----------------------------------------------------------------------===//
483// SVE pattern match helpers.
484//===----------------------------------------------------------------------===//
485def SVEDup0 : ComplexPattern<vAny, 0, "SelectDupZero", []>;
486def SVEDup0Undef : ComplexPattern<vAny, 0, "SelectDupZeroOrUndef", []>;
487def SVEAny : ComplexPattern<vAny, 0, "SelectAny", []>;
488
489class SVE_1_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
490                   Instruction inst>
491: Pat<(vtd (op vt1:$Op1)),
492      (inst $Op1)>;
493
494class SVE_1_Op_Passthru_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
495                            ValueType vts, Instruction inst>
496: Pat<(vtd (op pg:$Op1, vts:$Op2, vtd:$Op3)),
497      (inst $Op3, $Op1, $Op2)>;
498
499
500multiclass SVE_1_Op_PassthruUndef_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
501                                 ValueType vts, Instruction inst> {
502  def : Pat<(vtd (op pg:$Op1, vts:$Op2, (vtd undef))),
503            (inst (IMPLICIT_DEF), $Op1, $Op2)>;
504  def : Pat<(vtd (op (pg (SVEAllActive:$Op1)), vts:$Op2, vtd:$Op3)),
505            (inst $Op3, $Op1, $Op2)>;
506}
507
508multiclass SVE_1_Op_PassthruUndefZero_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
509                   ValueType vts, Instruction inst> {
510  let AddedComplexity = 1 in {
511    def : Pat<(vtd (op pg:$Op1, vts:$Op2, (vtd (SVEDup0Undef)))),
512          (inst $Op1, $Op2)>;
513    def : Pat<(vtd (op (pg (SVEAllActive:$Op1)), vts:$Op2, (vtd (SVEAny)))),
514          (inst $Op1, $Op2)>;
515  }
516}
517
518// Used to match FP_ROUND_MERGE_PASSTHRU, which has an additional flag for the
519// type of rounding. This is matched by timm0_1 in pattern below and ignored.
520class SVE_1_Op_Passthru_Round_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
521                                  ValueType vts, Instruction inst>
522: Pat<(vtd (op pg:$Op1, vts:$Op2, (i64 timm0_1), vtd:$Op3)),
523      (inst $Op3, $Op1, $Op2)>;
524
525multiclass SVE_1_Op_PassthruUndef_Round_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
526                                  ValueType vts, Instruction inst>{
527  def : Pat<(vtd (op pg:$Op1, vts:$Op2, (i64 timm0_1), (vtd undef))),
528            (inst (IMPLICIT_DEF), $Op1, $Op2)>;
529  def : Pat<(vtd (op (pg (SVEAllActive:$Op1)), vts:$Op2, (i64 timm0_1), vtd:$Op3)),
530            (inst $Op3, $Op1, $Op2)>;
531}
532
533class SVE_1_Op_PassthruZero_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
534                   ValueType vt2, Instruction inst>
535   : Pat<(vtd (op (vtd (SVEDup0)), vt1:$Op1, vt2:$Op2)),
536        (inst (IMPLICIT_DEF), $Op1, $Op2)>;
537
538class SVE_1_Op_Imm_OptLsl_Pat<ValueType vt, SDPatternOperator op, ZPRRegOp zprty,
539                              ValueType it, ComplexPattern cpx, Instruction inst>
540  : Pat<(vt (op (vt zprty:$Op1), (vt (splat_vector (it (cpx i32:$imm, i32:$shift)))))),
541        (inst $Op1, i32:$imm, i32:$shift)>;
542
543class SVE_1_Op_Imm_Arith_Any_Predicate<ValueType vt, ValueType pt,
544                                       SDPatternOperator op, ZPRRegOp zprty,
545                                       ValueType it, ComplexPattern cpx,
546                                       Instruction inst>
547  : Pat<(vt (op (pt (SVEAnyPredicate)), (vt zprty:$Op1), (vt (splat_vector (it (cpx i32:$imm)))))),
548        (inst $Op1, i32:$imm)>;
549
550class SVE_1_Op_Imm_Log_Pat<ValueType vt, SDPatternOperator op, ZPRRegOp zprty,
551                           ValueType it, ComplexPattern cpx, Instruction inst>
552  : Pat<(vt (op (vt zprty:$Op1), (vt (splat_vector (it (cpx i64:$imm)))))),
553        (inst $Op1, i64:$imm)>;
554
555class SVE_2_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
556                   ValueType vt2, Instruction inst>
557: Pat<(vtd (op vt1:$Op1, vt2:$Op2)),
558      (inst $Op1, $Op2)>;
559
560class SVE_2_Op_Pred_All_Active<ValueType vtd, SDPatternOperator op,
561                               ValueType pt, ValueType vt1, ValueType vt2,
562                               Instruction inst>
563: Pat<(vtd (op (pt (SVEAllActive)), vt1:$Op1, vt2:$Op2)),
564      (inst $Op1, $Op2)>;
565
566class SVE_2_Op_Pred_All_Active_Pt<ValueType vtd, SDPatternOperator op,
567                                  ValueType pt, ValueType vt1, ValueType vt2,
568                                  Instruction inst>
569: Pat<(vtd (op (pt (SVEAllActive:$Op1)), vt1:$Op2, vt2:$Op3)),
570      (inst $Op1, $Op2, $Op3)>;
571
572class SVE_3_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
573                   ValueType vt2, ValueType vt3, Instruction inst>
574: Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3)),
575      (inst $Op1, $Op2, $Op3)>;
576
577multiclass SVE_3_Op_Undef_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
578                              ValueType vt2, ValueType vt3, Instruction inst> {
579  def : Pat<(vtd (op (vt1 undef), vt2:$Op1, vt3:$Op2)),
580            (inst (IMPLICIT_DEF), $Op1, $Op2)>;
581  def : Pat<(vtd (op vt1:$Op1, (vt2 (SVEAllActive:$Op2)), vt3:$Op3)),
582            (inst $Op1, $Op2, $Op3)>;
583}
584
585multiclass SVE_3_Op_UndefZero_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
586                             ValueType vt2, ValueType vt3, Instruction inst>  {
587  let AddedComplexity = 1 in {
588    def : Pat<(vtd (op (vt1 (SVEDup0Undef)), vt2:$Op1, vt3:$Op2)),
589              (inst $Op1, $Op2)>;
590    def : Pat<(vtd (op (vt1 (SVEAny)), (vt2 (SVEAllActive:$Op2)), vt3:$Op3)),
591              (inst $Op2, $Op3)>;
592  }
593}
594
595class SVE_4_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
596                   ValueType vt2, ValueType vt3, ValueType vt4,
597                   Instruction inst>
598: Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3, vt4:$Op4)),
599      (inst $Op1, $Op2, $Op3, $Op4)>;
600
601class SVE_2_Op_Imm_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
602                       ValueType vt2, Operand ImmTy, Instruction inst>
603: Pat<(vtd (op vt1:$Op1, (vt2 ImmTy:$Op2))),
604      (inst $Op1, ImmTy:$Op2)>;
605
606multiclass SVE2p1_Cntp_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
607                           Instruction inst> {
608  def : Pat<(vtd (op vt1:$Op1, (i32 2))), (inst $Op1, 0)>;
609  def : Pat<(vtd (op vt1:$Op1, (i32 4))), (inst $Op1, 1)>;
610}
611
612multiclass SVE2p1_While_PN_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
613                               Instruction inst> {
614  def : Pat<(vtd (op vt1:$Op1, vt1:$Op2, (i32 2))), (inst $Op1, $Op2, 0)>;
615  def : Pat<(vtd (op vt1:$Op1, vt1:$Op2, (i32 4))), (inst $Op1, $Op2, 1)>;
616}
617
618class SVE_3_Op_Imm_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
619                       ValueType vt2, ValueType vt3, Operand ImmTy,
620                       Instruction inst>
621: Pat<(vtd (op vt1:$Op1, vt2:$Op2, (vt3 ImmTy:$Op3))),
622      (inst $Op1, $Op2, ImmTy:$Op3)>;
623
624class SVE_4_Op_Imm_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
625                       ValueType vt2, ValueType vt3, ValueType vt4,
626                       Operand ImmTy, Instruction inst>
627: Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3, (vt4 ImmTy:$Op4))),
628      (inst $Op1, $Op2, $Op3, ImmTy:$Op4)>;
629
630let AddedComplexity = 1 in {
631class SVE_3_Op_Pat_SelZero<ValueType vtd, SDPatternOperator op, ValueType vt1,
632                   ValueType vt2, ValueType vt3, Instruction inst>
633: Pat<(vtd (vtd (op vt1:$Op1, (vselect vt1:$Op1, vt2:$Op2, (SVEDup0)), vt3:$Op3))),
634      (inst $Op1, $Op2, $Op3)>;
635
636class SVE_3_Op_Pat_Shift_Imm_SelZero<ValueType vtd, SDPatternOperator op,
637                                     ValueType vt1, ValueType vt2,
638                                     Operand vt3, Instruction inst>
639: Pat<(vtd (op vt1:$Op1, (vselect vt1:$Op1, vt2:$Op2, (SVEDup0)), (i32 (vt3:$Op3)))),
640      (inst $Op1, $Op2, vt3:$Op3)>;
641}
642
643//
644// Common but less generic patterns.
645//
646
647class SVE_2_Op_AllActive_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
648                             ValueType vt2, Instruction inst, Instruction ptrue>
649: Pat<(vtd (op vt1:$Op1, vt2:$Op2)),
650      (inst (ptrue 31), $Op1, $Op2)>;
651
652class SVE_InReg_Extend<ValueType vt, SDPatternOperator op, ValueType pt,
653                       ValueType inreg_vt, Instruction inst>
654: Pat<(vt (op pt:$Pg, vt:$Src, inreg_vt, vt:$PassThru)),
655      (inst $PassThru, $Pg, $Src)>;
656
657multiclass SVE_InReg_Extend_PassthruUndef<ValueType vt, SDPatternOperator op, ValueType pt,
658                                          ValueType inreg_vt, Instruction inst> {
659  def : Pat<(vt (op pt:$Pg, vt:$Src, inreg_vt, (vt undef))),
660            (inst (IMPLICIT_DEF), $Pg, $Src)>;
661  def : Pat<(vt (op (pt (SVEAllActive:$Pg)), vt:$Src, inreg_vt, vt:$PassThru)),
662            (inst $PassThru, $Pg, $Src)>;
663}
664
665multiclass SVE_InReg_Extend_PassthruUndefZero<ValueType vt, SDPatternOperator op, ValueType pt,
666                                         ValueType inreg_vt, Instruction inst> {
667  let AddedComplexity = 1 in {
668    def : Pat<(vt (op pt:$Pg, vt:$Src, inreg_vt, (vt (SVEDup0Undef)))),
669               (inst $Pg, $Src)>;
670
671    def : Pat<(vt (op (pt (SVEAllActive:$Pg)), vt:$Src, inreg_vt, (vt (SVEAny)))),
672              (inst $Pg, $Src)>;
673  }
674}
675
676class SVE_Shift_DupImm_Pred_Pat<ValueType vt, SDPatternOperator op,
677                                ValueType pt, ValueType it,
678                                ComplexPattern cast, Instruction inst>
679: Pat<(vt (op pt:$Pg, vt:$Rn, (vt (splat_vector (it (cast i32:$imm)))))),
680      (inst $Pg, $Rn, i32:$imm)>;
681
682class SVE_Shift_DupImm_Any_Predicate_Pat<ValueType vt, SDPatternOperator op,
683                                         ValueType pt, ValueType it,
684                                         ComplexPattern cast, Instruction inst>
685: Pat<(vt (op (pt (SVEAnyPredicate)), vt:$Rn, (vt (splat_vector (it (cast i32:$imm)))))),
686      (inst $Rn, i32:$imm)>;
687
688class SVE_2_Op_Imm_Pat_Zero<ValueType vt, SDPatternOperator op, ValueType pt,
689                            ValueType it, ComplexPattern cpx, Instruction inst>
690: Pat<(vt (op pt:$Pg, (vselect pt:$Pg, vt:$Op1, (SVEDup0)),
691                      (vt (splat_vector (it (cpx i32:$imm)))))),
692      (inst $Pg, $Op1, i32:$imm)>;
693
694class SVE_2_Op_Fp_Imm_Pat<ValueType vt, SDPatternOperator op,
695                          ValueType pt, ValueType it,
696                          FPImmLeaf immL, int imm,
697                          Instruction inst>
698: Pat<(vt (op (pt PPR_3b:$Pg), (vt ZPR:$Zs1), (vt (splat_vector (it immL))))),
699      (inst $Pg, $Zs1, imm)>;
700
701class SVE_2_Op_Fp_Imm_Pat_Zero<ValueType vt, SDPatternOperator op,
702                              ValueType pt, ValueType it,
703                              FPImmLeaf immL, int imm,
704                              Instruction inst>
705: Pat<(vt (op pt:$Pg, (vselect pt:$Pg, vt:$Zs1, (SVEDup0)),
706                      (vt (splat_vector (it immL))))),
707      (inst $Pg, $Zs1, imm)>;
708
709class SVE_Shift_Add_All_Active_Pat<ValueType vtd, SDPatternOperator op, ValueType pt,
710                                   ValueType vt1, ValueType vt2, ValueType vt3,
711                                   Instruction inst>
712: Pat<(vtd (add vt1:$Op1, (op (pt (SVEAllActive)), vt2:$Op2, vt3:$Op3))),
713      (inst $Op1, $Op2, $Op3)>;
714
715class SVE2p1_Sat_Shift_VG2_Pat<string name, SDPatternOperator intrinsic, ValueType out_vt, ValueType in_vt, Operand imm_ty>
716    : Pat<(out_vt (intrinsic in_vt:$Zn1, in_vt:$Zn2, (i32 imm_ty:$i))),
717                  (!cast<Instruction>(name) (REG_SEQUENCE ZPR2Mul2, in_vt:$Zn1, zsub0, in_vt:$Zn2, zsub1), imm_ty:$i)>;
718
719class SVE2p1_Cvt_VG2_Pat<string name, SDPatternOperator intrinsic, ValueType out_vt, ValueType in_vt>
720    : Pat<(out_vt (intrinsic in_vt:$Zn1, in_vt:$Zn2)),
721                  (!cast<Instruction>(name) (REG_SEQUENCE ZPR2Mul2, in_vt:$Zn1, zsub0, in_vt:$Zn2, zsub1))>;
722
723//===----------------------------------------------------------------------===//
724// SVE pattern match helpers.
725//===----------------------------------------------------------------------===//
726
727// Matches either an intrinsic, or a predicated operation with an all active predicate
728class VSelectPredOrPassthruPatFrags<SDPatternOperator intrinsic, SDPatternOperator sdnode>
729: PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [
730    (intrinsic node:$Pg, node:$Op1, node:$Op2),
731    (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op1, node:$Op2), node:$Op1),
732  ], [{
733    return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse();
734  }]>;
735// Same as above with a commutative operation
736class VSelectCommPredOrPassthruPatFrags<SDPatternOperator intrinsic, SDPatternOperator sdnode>
737: PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [
738    (intrinsic node:$Pg, node:$Op1, node:$Op2),
739    (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op1, node:$Op2), node:$Op1),
740    (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op2, node:$Op1), node:$Op1),
741  ], [{
742    return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse();
743  }]>;
744// Similarly matches either an intrinsic, or an unpredicated operation with a select
745class VSelectUnpredOrPassthruPatFrags<SDPatternOperator intrinsic, SDPatternOperator sdnode>
746: PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [
747    (intrinsic node:$Pg, node:$Op1, node:$Op2),
748    (vselect node:$Pg, (sdnode node:$Op1, node:$Op2), node:$Op1),
749  ], [{
750    return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse();
751  }]>;
752
753//
754// Pseudo -> Instruction mappings
755//
756def getSVEPseudoMap : InstrMapping {
757  let FilterClass = "SVEPseudo2Instr";
758  let RowFields = ["PseudoName"];
759  let ColFields = ["IsInstr"];
760  let KeyCol = ["0"];
761  let ValueCols = [["1"]];
762}
763
764class SVEPseudo2Instr<string name, bit instr> {
765  string PseudoName = name;
766  bit IsInstr = instr;
767}
768
769// Lookup e.g. DIV -> DIVR
770def getSVERevInstr : InstrMapping {
771  let FilterClass = "SVEInstr2Rev";
772  let RowFields = ["InstrName"];
773  let ColFields = ["isReverseInstr"];
774  let KeyCol = ["0"];
775  let ValueCols = [["1"]];
776}
777
778// Lookup e.g. DIVR -> DIV
779def getSVENonRevInstr : InstrMapping {
780  let FilterClass = "SVEInstr2Rev";
781  let RowFields = ["InstrName"];
782  let ColFields = ["isReverseInstr"];
783  let KeyCol = ["1"];
784  let ValueCols = [["0"]];
785}
786
787class SVEInstr2Rev<string name1, string name2, bit name1IsReverseInstr> {
788  string InstrName = !if(name1IsReverseInstr, name1, name2);
789  bit isReverseInstr = name1IsReverseInstr;
790}
791
792//
793// Pseudos for destructive operands
794//
795let hasNoSchedulingInfo = 1 in {
796  class PredTwoOpPseudo<string name, ZPRRegOp zprty,
797                        FalseLanesEnum flags = FalseLanesNone>
798  : SVEPseudo2Instr<name, 0>,
799    Pseudo<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zs1, zprty:$Zs2), []> {
800    let FalseLanes = flags;
801  }
802
803  class PredTwoOpImmPseudo<string name, ZPRRegOp zprty, Operand immty,
804                           FalseLanesEnum flags = FalseLanesNone>
805  : SVEPseudo2Instr<name, 0>,
806    Pseudo<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zs1, immty:$imm), []> {
807    let FalseLanes = flags;
808  }
809
810  class PredThreeOpPseudo<string name, ZPRRegOp zprty,
811                          FalseLanesEnum flags = FalseLanesNone>
812  : SVEPseudo2Instr<name, 0>,
813    Pseudo<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zs1, zprty:$Zs2, zprty:$Zs3), []> {
814    let FalseLanes = flags;
815  }
816}
817
818//
819// Pseudos for passthru operands
820//
821let hasNoSchedulingInfo = 1 in {
822  class PredOneOpPassthruPseudo<string name, ZPRRegOp zprty,
823                                FalseLanesEnum flags = FalseLanesNone>
824  : SVEPseudo2Instr<name, 0>,
825    Pseudo<(outs zprty:$Zd), (ins zprty:$Passthru, PPR3bAny:$Pg, zprty:$Zs), []> {
826    let FalseLanes = flags;
827    let Constraints = !if(!eq(flags, FalseLanesZero), "$Zd = $Passthru,@earlyclobber $Zd", "");
828  }
829}
830
831//===----------------------------------------------------------------------===//
832// SVE Predicate Misc Group
833//===----------------------------------------------------------------------===//
834
835class sve_int_pfalse<bits<6> opc, string asm>
836: I<(outs PPRorPNR8:$Pd), (ins),
837  asm, "\t$Pd",
838  "",
839  []>, Sched<[]> {
840  bits<4> Pd;
841  let Inst{31-24} = 0b00100101;
842  let Inst{23-22} = opc{5-4};
843  let Inst{21-19} = 0b011;
844  let Inst{18-16} = opc{3-1};
845  let Inst{15-10} = 0b111001;
846  let Inst{9}     = opc{0};
847  let Inst{8-4}   = 0b00000;
848  let Inst{3-0}   = Pd;
849
850  let hasSideEffects = 0;
851  let isReMaterializable = 1;
852  let Uses = [VG];
853}
854
855multiclass sve_int_pfalse<bits<6> opc, string asm> {
856  def NAME : sve_int_pfalse<opc, asm>;
857
858  def : Pat<(nxv16i1 immAllZerosV), (!cast<Instruction>(NAME))>;
859  def : Pat<(nxv8i1 immAllZerosV), (!cast<Instruction>(NAME))>;
860  def : Pat<(nxv4i1 immAllZerosV), (!cast<Instruction>(NAME))>;
861  def : Pat<(nxv2i1 immAllZerosV), (!cast<Instruction>(NAME))>;
862  def : Pat<(nxv1i1 immAllZerosV), (!cast<Instruction>(NAME))>;
863}
864
865class sve_int_ptest<bits<6> opc, string asm, SDPatternOperator op>
866: I<(outs), (ins PPRAny:$Pg, PPR8:$Pn),
867  asm, "\t$Pg, $Pn",
868  "",
869  [(set NZCV, (op (nxv16i1 PPRAny:$Pg), (nxv16i1 PPR8:$Pn)))]>, Sched<[]> {
870  bits<4> Pg;
871  bits<4> Pn;
872  let Inst{31-24} = 0b00100101;
873  let Inst{23-22} = opc{5-4};
874  let Inst{21-19} = 0b010;
875  let Inst{18-16} = opc{3-1};
876  let Inst{15-14} = 0b11;
877  let Inst{13-10} = Pg;
878  let Inst{9}     = opc{0};
879  let Inst{8-5}   = Pn;
880  let Inst{4-0}   = 0b00000;
881
882  let Defs = [NZCV];
883  let hasSideEffects = 0;
884  let isCompare = 1;
885}
886
887multiclass sve_int_ptest<bits<6> opc, string asm, SDPatternOperator op,
888                         SDPatternOperator op_any> {
889  def NAME : sve_int_ptest<opc, asm, op>;
890
891  let hasNoSchedulingInfo = 1, isCompare = 1, Defs = [NZCV] in {
892  def _ANY : Pseudo<(outs), (ins PPRAny:$Pg, PPR8:$Pn),
893                    [(set NZCV, (op_any (nxv16i1 PPRAny:$Pg), (nxv16i1 PPR8:$Pn)))]>,
894             PseudoInstExpansion<(!cast<Instruction>(NAME) PPRAny:$Pg, PPR8:$Pn)>;
895  }
896}
897
898class sve_int_pfirst_next<bits<2> sz8_64, bits<5> opc, string asm,
899                          PPRRegOp pprty>
900: I<(outs pprty:$Pdn), (ins PPRAny:$Pg, pprty:$_Pdn),
901  asm, "\t$Pdn, $Pg, $_Pdn",
902  "",
903  []>, Sched<[]> {
904  bits<4> Pdn;
905  bits<4> Pg;
906  let Inst{31-24} = 0b00100101;
907  let Inst{23-22} = sz8_64;
908  let Inst{21-19} = 0b011;
909  let Inst{18-16} = opc{4-2};
910  let Inst{15-11} = 0b11000;
911  let Inst{10-9}  = opc{1-0};
912  let Inst{8-5}   = Pg;
913  let Inst{4}     = 0;
914  let Inst{3-0}   = Pdn;
915
916  let Constraints = "$Pdn = $_Pdn";
917  let Defs = [NZCV];
918  let ElementSize = pprty.ElementSize;
919  let hasSideEffects = 0;
920  let isPTestLike = 1;
921}
922
923multiclass sve_int_pfirst<bits<5> opc, string asm, SDPatternOperator op> {
924  def _B : sve_int_pfirst_next<0b01, opc, asm, PPR8>;
925
926  def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME # _B)>;
927}
928
929multiclass sve_int_pnext<bits<5> opc, string asm, SDPatternOperator op> {
930  def _B : sve_int_pfirst_next<0b00, opc, asm, PPR8>;
931  def _H : sve_int_pfirst_next<0b01, opc, asm, PPR16>;
932  def _S : sve_int_pfirst_next<0b10, opc, asm, PPR32>;
933  def _D : sve_int_pfirst_next<0b11, opc, asm, PPR64>;
934
935  def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME # _B)>;
936  def : SVE_2_Op_Pat<nxv8i1, op, nxv8i1, nxv8i1, !cast<Instruction>(NAME # _H)>;
937  def : SVE_2_Op_Pat<nxv4i1, op, nxv4i1, nxv4i1, !cast<Instruction>(NAME # _S)>;
938  def : SVE_2_Op_Pat<nxv2i1, op, nxv2i1, nxv2i1, !cast<Instruction>(NAME # _D)>;
939}
940
941//===----------------------------------------------------------------------===//
942// SVE Predicate Count Group
943//===----------------------------------------------------------------------===//
944
945class sve_int_count_r<bits<2> sz8_64, bits<5> opc, string asm,
946                      RegisterOperand dty, PPRRegOp pprty, RegisterOperand sty>
947: I<(outs dty:$Rdn), (ins pprty:$Pg, sty:$_Rdn),
948  asm, "\t$Rdn, $Pg",
949  "",
950  []>, Sched<[]> {
951  bits<5> Rdn;
952  bits<4> Pg;
953  let Inst{31-24} = 0b00100101;
954  let Inst{23-22} = sz8_64;
955  let Inst{21-19} = 0b101;
956  let Inst{18-16} = opc{4-2};
957  let Inst{15-11} = 0b10001;
958  let Inst{10-9}  = opc{1-0};
959  let Inst{8-5}   = Pg;
960  let Inst{4-0}   = Rdn;
961
962  // Signed 32bit forms require their GPR operand printed.
963  let AsmString = !if(!eq(opc{4,2-0}, 0b0000),
964                      !strconcat(asm, "\t$Rdn, $Pg, $_Rdn"),
965                      !strconcat(asm, "\t$Rdn, $Pg"));
966  let Constraints = "$Rdn = $_Rdn";
967  let hasSideEffects = 0;
968}
969
970multiclass sve_int_count_r_s32<bits<5> opc, string asm,
971                               SDPatternOperator op> {
972  def _B : sve_int_count_r<0b00, opc, asm, GPR64z, PPR8, GPR64as32>;
973  def _H : sve_int_count_r<0b01, opc, asm, GPR64z, PPR16, GPR64as32>;
974  def _S : sve_int_count_r<0b10, opc, asm, GPR64z, PPR32, GPR64as32>;
975  def _D : sve_int_count_r<0b11, opc, asm, GPR64z, PPR64, GPR64as32>;
976
977  def : Pat<(i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))),
978            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _B) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
979  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))))),
980            (!cast<Instruction>(NAME # _B) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
981
982  def : Pat<(i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))),
983            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _H) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
984  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))))),
985            (!cast<Instruction>(NAME # _H) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
986
987  def : Pat<(i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))),
988            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _S) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
989  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))))),
990            (!cast<Instruction>(NAME # _S) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
991
992  def : Pat<(i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))),
993            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _D) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
994  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))))),
995            (!cast<Instruction>(NAME # _D) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
996}
997
998multiclass sve_int_count_r_u32<bits<5> opc, string asm,
999                               SDPatternOperator op> {
1000  def _B : sve_int_count_r<0b00, opc, asm, GPR32z, PPR8, GPR32z>;
1001  def _H : sve_int_count_r<0b01, opc, asm, GPR32z, PPR16, GPR32z>;
1002  def _S : sve_int_count_r<0b10, opc, asm, GPR32z, PPR32, GPR32z>;
1003  def _D : sve_int_count_r<0b11, opc, asm, GPR32z, PPR64, GPR32z>;
1004
1005  def : Pat<(i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))),
1006            (!cast<Instruction>(NAME # _B) PPRAny:$Pg, $Rn)>;
1007  def : Pat<(i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))),
1008            (!cast<Instruction>(NAME # _H) PPRAny:$Pg, $Rn)>;
1009  def : Pat<(i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))),
1010            (!cast<Instruction>(NAME # _S) PPRAny:$Pg, $Rn)>;
1011  def : Pat<(i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))),
1012            (!cast<Instruction>(NAME # _D) PPRAny:$Pg, $Rn)>;
1013}
1014
1015multiclass sve_int_count_r_x64<bits<5> opc, string asm,
1016                               SDPatternOperator op,
1017                               SDPatternOperator combine_op = null_frag> {
1018  def _B : sve_int_count_r<0b00, opc, asm, GPR64z, PPR8, GPR64z>;
1019  def _H : sve_int_count_r<0b01, opc, asm, GPR64z, PPR16, GPR64z>;
1020  def _S : sve_int_count_r<0b10, opc, asm, GPR64z, PPR32, GPR64z>;
1021  def _D : sve_int_count_r<0b11, opc, asm, GPR64z, PPR64, GPR64z>;
1022
1023  def : Pat<(i64 (op GPR64:$Rn, (nxv16i1 PPRAny:$Pg))),
1024            (!cast<Instruction>(NAME # _B) PPRAny:$Pg, $Rn)>;
1025  def : Pat<(i64 (op GPR64:$Rn, (nxv8i1 PPRAny:$Pg))),
1026            (!cast<Instruction>(NAME # _H) PPRAny:$Pg, $Rn)>;
1027  def : Pat<(i64 (op GPR64:$Rn, (nxv4i1 PPRAny:$Pg))),
1028            (!cast<Instruction>(NAME # _S) PPRAny:$Pg, $Rn)>;
1029  def : Pat<(i64 (op GPR64:$Rn, (nxv2i1 PPRAny:$Pg))),
1030            (!cast<Instruction>(NAME # _D) PPRAny:$Pg, $Rn)>;
1031
1032  // combine_op(x, cntp(all_active, p)) ==> inst p, x
1033  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv16i1 (SVEAllActive)), (nxv16i1 PPRAny:$pred)))),
1034            (!cast<Instruction>(NAME # _B) PPRAny:$pred, $Rn)>;
1035  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv8i1 (SVEAllActive)), (nxv8i1 PPRAny:$pred)))),
1036            (!cast<Instruction>(NAME # _H) PPRAny:$pred, $Rn)>;
1037  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv4i1 (SVEAllActive)), (nxv4i1 PPRAny:$pred)))),
1038            (!cast<Instruction>(NAME # _S) PPRAny:$pred, $Rn)>;
1039  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv2i1 (SVEAllActive)), (nxv2i1 PPRAny:$pred)))),
1040            (!cast<Instruction>(NAME # _D) PPRAny:$pred, $Rn)>;
1041
1042  // combine_op(x, cntp(p, p)) ==> inst p, x
1043  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv16i1 PPRAny:$pred), (nxv16i1 PPRAny:$pred)))),
1044            (!cast<Instruction>(NAME # _B) PPRAny:$pred, $Rn)>;
1045  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv8i1 PPRAny:$pred), (nxv8i1 PPRAny:$pred)))),
1046            (!cast<Instruction>(NAME # _H) PPRAny:$pred, $Rn)>;
1047  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv4i1 PPRAny:$pred), (nxv4i1 PPRAny:$pred)))),
1048            (!cast<Instruction>(NAME # _S) PPRAny:$pred, $Rn)>;
1049  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv2i1 PPRAny:$pred), (nxv2i1 PPRAny:$pred)))),
1050            (!cast<Instruction>(NAME # _D) PPRAny:$pred, $Rn)>;
1051
1052  // combine_op(x, trunc(cntp(all_active, p))) ==> inst p, x
1053  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv16i1 (SVEAllActive)), (nxv16i1 PPRAny:$pred))))),
1054            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _B) PPRAny:$pred,
1055                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
1056                                 sub_32)>;
1057  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv8i1 (SVEAllActive)), (nxv8i1 PPRAny:$pred))))),
1058            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _H) PPRAny:$pred,
1059                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
1060                                 sub_32)>;
1061  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv4i1 (SVEAllActive)), (nxv4i1 PPRAny:$pred))))),
1062            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _S) PPRAny:$pred,
1063                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
1064                                 sub_32)>;
1065  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv2i1 (SVEAllActive)), (nxv2i1 PPRAny:$pred))))),
1066            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _D) PPRAny:$pred,
1067                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
1068                                 sub_32)>;
1069
1070  // combine_op(x, trunc(cntp(p, p))) ==> inst p, x
1071  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv16i1 PPRAny:$pred), (nxv16i1 PPRAny:$pred))))),
1072            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _B) PPRAny:$pred,
1073                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
1074                                 sub_32)>;
1075  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv8i1 PPRAny:$pred), (nxv8i1 PPRAny:$pred))))),
1076            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _H) PPRAny:$pred,
1077                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
1078                                 sub_32)>;
1079  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv4i1 PPRAny:$pred), (nxv4i1 PPRAny:$pred))))),
1080            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _S) PPRAny:$pred,
1081                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
1082                                 sub_32)>;
1083  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv2i1 PPRAny:$pred), (nxv2i1 PPRAny:$pred))))),
1084            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _D) PPRAny:$pred,
1085                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
1086                                 sub_32)>;
1087}
1088
1089class sve_int_count_v<bits<2> sz8_64, bits<5> opc, string asm,
1090                      ZPRRegOp zprty, PPRRegOp pprty>
1091: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, pprty:$Pm),
1092  asm, "\t$Zdn, $Pm",
1093  "",
1094  []>, Sched<[]> {
1095  bits<4> Pm;
1096  bits<5> Zdn;
1097  let Inst{31-24} = 0b00100101;
1098  let Inst{23-22} = sz8_64;
1099  let Inst{21-19} = 0b101;
1100  let Inst{18-16} = opc{4-2};
1101  let Inst{15-11} = 0b10000;
1102  let Inst{10-9}  = opc{1-0};
1103  let Inst{8-5}   = Pm;
1104  let Inst{4-0}   = Zdn;
1105
1106  let Constraints = "$Zdn = $_Zdn";
1107  let DestructiveInstType = DestructiveOther;
1108  let ElementSize = ElementSizeNone;
1109  let hasSideEffects = 0;
1110}
1111
1112multiclass sve_int_count_v<bits<5> opc, string asm,
1113                           SDPatternOperator op = null_frag> {
1114  def _H : sve_int_count_v<0b01, opc, asm, ZPR16, PPR16>;
1115  def _S : sve_int_count_v<0b10, opc, asm, ZPR32, PPR32>;
1116  def _D : sve_int_count_v<0b11, opc, asm, ZPR64, PPR64>;
1117
1118  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16,  nxv8i1, !cast<Instruction>(NAME # _H)>;
1119  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32,  nxv4i1, !cast<Instruction>(NAME # _S)>;
1120  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64,  nxv2i1, !cast<Instruction>(NAME # _D)>;
1121
1122  def : InstAlias<asm # "\t$Zdn, $Pm",
1123                 (!cast<Instruction>(NAME # "_H") ZPR16:$Zdn, PPRAny:$Pm), 0>;
1124  def : InstAlias<asm # "\t$Zdn, $Pm",
1125                 (!cast<Instruction>(NAME # "_S") ZPR32:$Zdn, PPRAny:$Pm), 0>;
1126  def : InstAlias<asm # "\t$Zdn, $Pm",
1127                  (!cast<Instruction>(NAME # "_D") ZPR64:$Zdn, PPRAny:$Pm), 0>;
1128}
1129
1130class sve_int_pcount_pred<bits<2> sz8_64, bits<3> opc, string asm,
1131                          PPRRegOp pprty>
1132: I<(outs GPR64:$Rd), (ins PPRAny:$Pg, pprty:$Pn),
1133  asm, "\t$Rd, $Pg, $Pn",
1134  "",
1135  []>, Sched<[]> {
1136  bits<4> Pg;
1137  bits<4> Pn;
1138  bits<5> Rd;
1139  let Inst{31-24} = 0b00100101;
1140  let Inst{23-22} = sz8_64;
1141  let Inst{21-19} = 0b100;
1142  let Inst{18-16} = opc{2-0};
1143  let Inst{15-14} = 0b10;
1144  let Inst{13-10} = Pg;
1145  let Inst{9}     = 0b0;
1146  let Inst{8-5}   = Pn;
1147  let Inst{4-0}   = Rd;
1148
1149  let hasSideEffects = 0;
1150}
1151
1152multiclass sve_int_pcount_pred<bits<3> opc, string asm,
1153                               SDPatternOperator int_op> {
1154  def _B : sve_int_pcount_pred<0b00, opc, asm, PPR8>;
1155  def _H : sve_int_pcount_pred<0b01, opc, asm, PPR16>;
1156  def _S : sve_int_pcount_pred<0b10, opc, asm, PPR32>;
1157  def _D : sve_int_pcount_pred<0b11, opc, asm, PPR64>;
1158
1159  def : SVE_2_Op_Pat<i64, int_op, nxv16i1, nxv16i1, !cast<Instruction>(NAME # _B)>;
1160  def : SVE_2_Op_Pat<i64, int_op, nxv8i1,  nxv8i1,  !cast<Instruction>(NAME # _H)>;
1161  def : SVE_2_Op_Pat<i64, int_op, nxv4i1,  nxv4i1,  !cast<Instruction>(NAME # _S)>;
1162  def : SVE_2_Op_Pat<i64, int_op, nxv2i1,  nxv2i1,  !cast<Instruction>(NAME # _D)>;
1163}
1164
1165multiclass sve_int_pcount_pred_tmp<bits<3> opc, string asm> {
1166  def _B : sve_int_pcount_pred<0b00, opc, asm, PPR8>;
1167  def _H : sve_int_pcount_pred<0b01, opc, asm, PPR16>;
1168  def _S : sve_int_pcount_pred<0b10, opc, asm, PPR32>;
1169  def _D : sve_int_pcount_pred<0b11, opc, asm, PPR64>;
1170}
1171//===----------------------------------------------------------------------===//
1172// SVE Element Count Group
1173//===----------------------------------------------------------------------===//
1174
1175class sve_int_count<bits<3> opc, string asm>
1176: I<(outs GPR64:$Rd), (ins sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1177  asm, "\t$Rd, $pattern, mul $imm4",
1178  "",
1179  []>, Sched<[]> {
1180  bits<5> Rd;
1181  bits<4> imm4;
1182  bits<5> pattern;
1183  let Inst{31-24} = 0b00000100;
1184  let Inst{23-22} = opc{2-1};
1185  let Inst{21-20} = 0b10;
1186  let Inst{19-16} = imm4;
1187  let Inst{15-11} = 0b11100;
1188  let Inst{10}    = opc{0};
1189  let Inst{9-5}   = pattern;
1190  let Inst{4-0}   = Rd;
1191
1192  let hasSideEffects = 0;
1193  let isReMaterializable = 1;
1194  let Uses = [VG];
1195}
1196
1197multiclass sve_int_count<bits<3> opc, string asm, SDPatternOperator op> {
1198  def NAME : sve_int_count<opc, asm>;
1199
1200  def : InstAlias<asm # "\t$Rd, $pattern",
1201                  (!cast<Instruction>(NAME) GPR64:$Rd, sve_pred_enum:$pattern, 1), 1>;
1202  def : InstAlias<asm # "\t$Rd",
1203                  (!cast<Instruction>(NAME) GPR64:$Rd, 0b11111, 1), 2>;
1204
1205  def : Pat<(i64 (mul (op sve_pred_enum:$pattern), (sve_cnt_mul_imm_i64 i32:$imm))),
1206            (!cast<Instruction>(NAME) sve_pred_enum:$pattern, sve_incdec_imm:$imm)>;
1207
1208  def : Pat<(i64 (shl (op sve_pred_enum:$pattern), (sve_cnt_shl_imm i32:$imm))),
1209            (!cast<Instruction>(NAME) sve_pred_enum:$pattern, sve_incdec_imm:$imm)>;
1210
1211  def : Pat<(i64 (op sve_pred_enum:$pattern)),
1212            (!cast<Instruction>(NAME) sve_pred_enum:$pattern, 1)>;
1213}
1214
1215class sve_int_countvlv<bits<5> opc, string asm, ZPRRegOp zprty>
1216: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1217  asm, "\t$Zdn, $pattern, mul $imm4",
1218  "",
1219  []>, Sched<[]> {
1220  bits<5> Zdn;
1221  bits<5> pattern;
1222  bits<4> imm4;
1223  let Inst{31-24} = 0b00000100;
1224  let Inst{23-22} = opc{4-3};
1225  let Inst{21}    = 0b1;
1226  let Inst{20}    = opc{2};
1227  let Inst{19-16} = imm4;
1228  let Inst{15-12} = 0b1100;
1229  let Inst{11-10} = opc{1-0};
1230  let Inst{9-5}   = pattern;
1231  let Inst{4-0}   = Zdn;
1232
1233  let Constraints = "$Zdn = $_Zdn";
1234  let DestructiveInstType = DestructiveOther;
1235  let ElementSize = ElementSizeNone;
1236  let hasSideEffects = 0;
1237}
1238
1239multiclass sve_int_countvlv<bits<5> opc, string asm, ZPRRegOp zprty,
1240                            SDPatternOperator op = null_frag,
1241                            ValueType vt = OtherVT> {
1242  def NAME : sve_int_countvlv<opc, asm, zprty>;
1243
1244  def : InstAlias<asm # "\t$Zdn, $pattern",
1245                  (!cast<Instruction>(NAME) zprty:$Zdn, sve_pred_enum:$pattern, 1), 1>;
1246  def : InstAlias<asm # "\t$Zdn",
1247                  (!cast<Instruction>(NAME) zprty:$Zdn, 0b11111, 1), 2>;
1248
1249  def : Pat<(vt (op (vt zprty:$Zn), (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1250            (!cast<Instruction>(NAME) $Zn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1251}
1252
1253class sve_int_pred_pattern_a<bits<3> opc, string asm>
1254: I<(outs GPR64:$Rdn), (ins GPR64:$_Rdn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1255  asm, "\t$Rdn, $pattern, mul $imm4",
1256  "",
1257  []>, Sched<[]> {
1258  bits<5> Rdn;
1259  bits<5> pattern;
1260  bits<4> imm4;
1261  let Inst{31-24} = 0b00000100;
1262  let Inst{23-22} = opc{2-1};
1263  let Inst{21-20} = 0b11;
1264  let Inst{19-16} = imm4;
1265  let Inst{15-11} = 0b11100;
1266  let Inst{10}    = opc{0};
1267  let Inst{9-5}   = pattern;
1268  let Inst{4-0}   = Rdn;
1269
1270  let Constraints = "$Rdn = $_Rdn";
1271  let hasSideEffects = 0;
1272}
1273
1274multiclass sve_int_pred_pattern_a<bits<3> opc, string asm,
1275                                  SDPatternOperator op,
1276                                  SDPatternOperator opcnt> {
1277  let Predicates = [HasSVE_or_SME] in {
1278    def NAME : sve_int_pred_pattern_a<opc, asm>;
1279
1280    def : InstAlias<asm # "\t$Rdn, $pattern",
1281                    (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, 1), 1>;
1282    def : InstAlias<asm # "\t$Rdn",
1283                    (!cast<Instruction>(NAME) GPR64:$Rdn, 0b11111, 1), 2>;
1284  }
1285
1286  let Predicates = [HasSVE_or_SME, UseScalarIncVL] in {
1287    def : Pat<(i64 (op GPR64:$Rdn, (opcnt sve_pred_enum:$pattern))),
1288              (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, 1)>;
1289
1290    def : Pat<(i64 (op GPR64:$Rdn, (mul (opcnt sve_pred_enum:$pattern), (sve_cnt_mul_imm_i64 i32:$imm)))),
1291              (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, $imm)>;
1292
1293    def : Pat<(i64 (op GPR64:$Rdn, (shl (opcnt sve_pred_enum:$pattern), (sve_cnt_shl_imm i32:$imm)))),
1294              (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, $imm)>;
1295
1296    def : Pat<(i32 (op GPR32:$Rdn, (i32 (trunc (opcnt (sve_pred_enum:$pattern)))))),
1297              (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF),
1298                                               GPR32:$Rdn, sub_32), sve_pred_enum:$pattern, 1),
1299                                    sub_32)>;
1300
1301    def : Pat<(i32 (op GPR32:$Rdn, (mul (i32 (trunc (opcnt (sve_pred_enum:$pattern)))), (sve_cnt_mul_imm_i32 i32:$imm)))),
1302              (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF),
1303                                               GPR32:$Rdn, sub_32), sve_pred_enum:$pattern, $imm),
1304                                    sub_32)>;
1305
1306    def : Pat<(i32 (op GPR32:$Rdn, (shl (i32 (trunc (opcnt (sve_pred_enum:$pattern)))), (sve_cnt_shl_imm i32:$imm)))),
1307              (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF),
1308                                               GPR32:$Rdn, sub_32), sve_pred_enum:$pattern, $imm),
1309                                    sub_32)>;
1310  }
1311}
1312
1313class sve_int_pred_pattern_b<bits<5> opc, string asm, RegisterOperand dt,
1314                             RegisterOperand st>
1315: I<(outs dt:$Rdn), (ins st:$_Rdn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1316  asm, "\t$Rdn, $pattern, mul $imm4",
1317  "",
1318  []>, Sched<[]> {
1319  bits<5> Rdn;
1320  bits<5> pattern;
1321  bits<4> imm4;
1322  let Inst{31-24} = 0b00000100;
1323  let Inst{23-22} = opc{4-3};
1324  let Inst{21}    = 0b1;
1325  let Inst{20}    = opc{2};
1326  let Inst{19-16} = imm4;
1327  let Inst{15-12} = 0b1111;
1328  let Inst{11-10} = opc{1-0};
1329  let Inst{9-5}   = pattern;
1330  let Inst{4-0}   = Rdn;
1331
1332  // Signed 32bit forms require their GPR operand printed.
1333  let AsmString = !if(!eq(opc{2,0}, 0b00),
1334                      !strconcat(asm, "\t$Rdn, $_Rdn, $pattern, mul $imm4"),
1335                      !strconcat(asm, "\t$Rdn, $pattern, mul $imm4"));
1336
1337  let Constraints = "$Rdn = $_Rdn";
1338  let hasSideEffects = 0;
1339}
1340
1341multiclass sve_int_pred_pattern_b_s32<bits<5> opc, string asm,
1342                                      SDPatternOperator op> {
1343  def NAME : sve_int_pred_pattern_b<opc, asm, GPR64z, GPR64as32>;
1344
1345  def : InstAlias<asm # "\t$Rd, $Rn, $pattern",
1346                  (!cast<Instruction>(NAME) GPR64z:$Rd, GPR64as32:$Rn, sve_pred_enum:$pattern, 1), 1>;
1347  def : InstAlias<asm # "\t$Rd, $Rn",
1348                  (!cast<Instruction>(NAME) GPR64z:$Rd, GPR64as32:$Rn, 0b11111, 1), 2>;
1349
1350  // NOTE: Register allocation doesn't like tied operands of differing register
1351  //       class, hence the extra INSERT_SUBREG complication.
1352
1353  def : Pat<(i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1354            (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32), sve_pred_enum:$pattern, sve_incdec_imm:$imm4), sub_32)>;
1355  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))))),
1356            (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32), sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1357}
1358
1359multiclass sve_int_pred_pattern_b_u32<bits<5> opc, string asm,
1360                                      SDPatternOperator op> {
1361  def NAME : sve_int_pred_pattern_b<opc, asm, GPR32z, GPR32z>;
1362
1363  def : InstAlias<asm # "\t$Rdn, $pattern",
1364                  (!cast<Instruction>(NAME) GPR32z:$Rdn, sve_pred_enum:$pattern, 1), 1>;
1365  def : InstAlias<asm # "\t$Rdn",
1366                  (!cast<Instruction>(NAME) GPR32z:$Rdn, 0b11111, 1), 2>;
1367
1368  def : Pat<(i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1369            (!cast<Instruction>(NAME) $Rn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1370}
1371
1372multiclass sve_int_pred_pattern_b_x64<bits<5> opc, string asm,
1373                                      SDPatternOperator op> {
1374  def NAME : sve_int_pred_pattern_b<opc, asm, GPR64z, GPR64z>;
1375
1376  def : InstAlias<asm # "\t$Rdn, $pattern",
1377                  (!cast<Instruction>(NAME) GPR64z:$Rdn, sve_pred_enum:$pattern, 1), 1>;
1378  def : InstAlias<asm # "\t$Rdn",
1379                  (!cast<Instruction>(NAME) GPR64z:$Rdn, 0b11111, 1), 2>;
1380
1381  def : Pat<(i64 (op GPR64:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1382            (!cast<Instruction>(NAME) $Rn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1383}
1384
1385
1386//===----------------------------------------------------------------------===//
1387// SVE Permute - Cross Lane Group
1388//===----------------------------------------------------------------------===//
1389
1390class sve_int_perm_dup_r<bits<2> sz8_64, string asm, ZPRRegOp zprty,
1391                         ValueType vt, RegisterClass srcRegType,
1392                         SDPatternOperator op>
1393: I<(outs zprty:$Zd), (ins srcRegType:$Rn),
1394  asm, "\t$Zd, $Rn",
1395  "",
1396  [(set (vt zprty:$Zd), (op srcRegType:$Rn))]>, Sched<[]> {
1397  bits<5> Rn;
1398  bits<5> Zd;
1399  let Inst{31-24} = 0b00000101;
1400  let Inst{23-22} = sz8_64;
1401  let Inst{21-10} = 0b100000001110;
1402  let Inst{9-5}   = Rn;
1403  let Inst{4-0}   = Zd;
1404
1405  let hasSideEffects = 0;
1406}
1407
1408multiclass sve_int_perm_dup_r<string asm, SDPatternOperator op> {
1409  def _B : sve_int_perm_dup_r<0b00, asm, ZPR8, nxv16i8, GPR32sp, op>;
1410  def _H : sve_int_perm_dup_r<0b01, asm, ZPR16, nxv8i16, GPR32sp, op>;
1411  def _S : sve_int_perm_dup_r<0b10, asm, ZPR32, nxv4i32, GPR32sp, op>;
1412  def _D : sve_int_perm_dup_r<0b11, asm, ZPR64, nxv2i64, GPR64sp, op>;
1413
1414  def : InstAlias<"mov $Zd, $Rn",
1415                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, GPR32sp:$Rn), 1>;
1416  def : InstAlias<"mov $Zd, $Rn",
1417                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, GPR32sp:$Rn), 1>;
1418  def : InstAlias<"mov $Zd, $Rn",
1419                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, GPR32sp:$Rn), 1>;
1420  def : InstAlias<"mov $Zd, $Rn",
1421                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, GPR64sp:$Rn), 1>;
1422}
1423
1424class sve_int_perm_dup_i<bits<5> tsz, Operand immtype, string asm,
1425                         ZPRRegOp zprty>
1426: I<(outs zprty:$Zd), (ins zprty:$Zn, immtype:$idx),
1427  asm, "\t$Zd, $Zn$idx",
1428  "",
1429  []>, Sched<[]> {
1430  bits<5> Zd;
1431  bits<5> Zn;
1432  bits<7> idx;
1433  let Inst{31-24} = 0b00000101;
1434  let Inst{23-22} = {?,?}; // imm3h
1435  let Inst{21}    = 0b1;
1436  let Inst{20-16} = tsz;
1437  let Inst{15-10} = 0b001000;
1438  let Inst{9-5}   = Zn;
1439  let Inst{4-0}   = Zd;
1440
1441  let hasSideEffects = 0;
1442}
1443
1444multiclass sve_int_perm_dup_i<string asm> {
1445  def _B : sve_int_perm_dup_i<{?,?,?,?,1}, sve_elm_idx_extdup_b, asm, ZPR8> {
1446    let Inst{23-22} = idx{5-4};
1447    let Inst{20-17} = idx{3-0};
1448  }
1449  def _H : sve_int_perm_dup_i<{?,?,?,1,0}, sve_elm_idx_extdup_h, asm, ZPR16> {
1450    let Inst{23-22} = idx{4-3};
1451    let Inst{20-18} = idx{2-0};
1452  }
1453  def _S : sve_int_perm_dup_i<{?,?,1,0,0}, sve_elm_idx_extdup_s, asm, ZPR32> {
1454    let Inst{23-22} = idx{3-2};
1455    let Inst{20-19}    = idx{1-0};
1456  }
1457  def _D : sve_int_perm_dup_i<{?,1,0,0,0}, sve_elm_idx_extdup_d, asm, ZPR64> {
1458    let Inst{23-22} = idx{2-1};
1459    let Inst{20}    = idx{0};
1460  }
1461  def _Q : sve_int_perm_dup_i<{1,0,0,0,0}, sve_elm_idx_extdup_q, asm, ZPR128> {
1462    let Inst{23-22} = idx{1-0};
1463  }
1464
1465  def : InstAlias<"mov $Zd, $Zn$idx",
1466                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, ZPR8:$Zn, sve_elm_idx_extdup_b:$idx), 1>;
1467  def : InstAlias<"mov $Zd, $Zn$idx",
1468                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, ZPR16:$Zn, sve_elm_idx_extdup_h:$idx), 1>;
1469  def : InstAlias<"mov $Zd, $Zn$idx",
1470                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, ZPR32:$Zn, sve_elm_idx_extdup_s:$idx), 1>;
1471  def : InstAlias<"mov $Zd, $Zn$idx",
1472                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, ZPR64:$Zn, sve_elm_idx_extdup_d:$idx), 1>;
1473  def : InstAlias<"mov $Zd, $Zn$idx",
1474                  (!cast<Instruction>(NAME # _Q) ZPR128:$Zd, ZPR128:$Zn, sve_elm_idx_extdup_q:$idx), 1>;
1475  def : InstAlias<"mov $Zd, $Bn",
1476                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, FPR8asZPR:$Bn, 0), 2>;
1477  def : InstAlias<"mov $Zd, $Hn",
1478                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, FPR16asZPR:$Hn, 0), 2>;
1479  def : InstAlias<"mov $Zd, $Sn",
1480                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, FPR32asZPR:$Sn, 0), 2>;
1481  def : InstAlias<"mov $Zd, $Dn",
1482                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, FPR64asZPR:$Dn, 0), 2>;
1483  def : InstAlias<"mov $Zd, $Qn",
1484                  (!cast<Instruction>(NAME # _Q) ZPR128:$Zd, FPR128asZPR:$Qn, 0), 2>;
1485
1486  // Duplicate an extracted vector element across a vector.
1487
1488  def : Pat<(nxv16i8 (splat_vector (i32 (vector_extract (nxv16i8 ZPR:$vec), sve_elm_idx_extdup_b:$index)))),
1489            (!cast<Instruction>(NAME # _B) ZPR:$vec, sve_elm_idx_extdup_b:$index)>;
1490  def : Pat<(nxv16i8 (splat_vector (i32 (vector_extract (v16i8 V128:$vec), sve_elm_idx_extdup_b:$index)))),
1491            (!cast<Instruction>(NAME # _B) (SUBREG_TO_REG (i64 0), $vec, zsub), sve_elm_idx_extdup_b:$index)>;
1492  def : Pat<(nxv16i8 (splat_vector (i32 (vector_extract (v8i8 V64:$vec), sve_elm_idx_extdup_b:$index)))),
1493            (!cast<Instruction>(NAME # _B) (SUBREG_TO_REG (i64 0), $vec, dsub), sve_elm_idx_extdup_b:$index)>;
1494
1495  foreach VT = [nxv8i16, nxv2f16, nxv4f16, nxv8f16, nxv2bf16, nxv4bf16, nxv8bf16] in {
1496    def : Pat<(VT (splat_vector (SVEType<VT>.EltAsScalar (vector_extract (SVEType<VT>.Packed ZPR:$vec), sve_elm_idx_extdup_h:$index)))),
1497              (!cast<Instruction>(NAME # _H) ZPR:$vec, sve_elm_idx_extdup_h:$index)>;
1498    def : Pat<(VT (splat_vector (SVEType<VT>.EltAsScalar (vector_extract (SVEType<VT>.ZSub V128:$vec), sve_elm_idx_extdup_h:$index)))),
1499              (!cast<Instruction>(NAME # _H) (SUBREG_TO_REG (i64 0), $vec, zsub), sve_elm_idx_extdup_h:$index)>;
1500    def : Pat<(VT (splat_vector (SVEType<VT>.EltAsScalar (vector_extract (SVEType<VT>.DSub V64:$vec), sve_elm_idx_extdup_h:$index)))),
1501              (!cast<Instruction>(NAME # _H) (SUBREG_TO_REG (i64 0), $vec, dsub), sve_elm_idx_extdup_h:$index)>;
1502  }
1503
1504  foreach VT = [nxv4i32, nxv2f32, nxv4f32 ] in {
1505    def : Pat<(VT (splat_vector (SVEType<VT>.EltAsScalar (vector_extract (SVEType<VT>.Packed ZPR:$vec), sve_elm_idx_extdup_s:$index)))),
1506              (!cast<Instruction>(NAME # _S) ZPR:$vec, sve_elm_idx_extdup_s:$index)>;
1507    def : Pat<(VT (splat_vector (SVEType<VT>.EltAsScalar (vector_extract (SVEType<VT>.ZSub V128:$vec), sve_elm_idx_extdup_s:$index)))),
1508              (!cast<Instruction>(NAME # _S) (SUBREG_TO_REG (i64 0), $vec, zsub), sve_elm_idx_extdup_s:$index)>;
1509    def : Pat<(VT (splat_vector (SVEType<VT>.EltAsScalar (vector_extract (SVEType<VT>.DSub V64:$vec), sve_elm_idx_extdup_s:$index)))),
1510              (!cast<Instruction>(NAME # _S) (SUBREG_TO_REG (i64 0), $vec, dsub), sve_elm_idx_extdup_s:$index)>;
1511  }
1512
1513  foreach VT = [nxv2i64, nxv2f64] in {
1514    def : Pat<(VT (splat_vector (SVEType<VT>.EltAsScalar (vector_extract (VT ZPR:$vec), sve_elm_idx_extdup_d:$index)))),
1515              (!cast<Instruction>(NAME # _D) ZPR:$vec, sve_elm_idx_extdup_d:$index)>;
1516    def : Pat<(VT (splat_vector (SVEType<VT>.EltAsScalar (vector_extract (SVEType<VT>.ZSub V128:$vec), sve_elm_idx_extdup_d:$index)))),
1517              (!cast<Instruction>(NAME # _D) (SUBREG_TO_REG (i64 0), $vec, zsub), sve_elm_idx_extdup_d:$index)>;
1518    def : Pat<(VT (splat_vector (SVEType<VT>.EltAsScalar (vector_extract (SVEType<VT>.DSub V64:$vec), sve_elm_idx_extdup_d:$index)))),
1519              (!cast<Instruction>(NAME # _D) (SUBREG_TO_REG (i64 0), $vec, dsub), sve_elm_idx_extdup_d:$index)>;
1520  }
1521
1522  // When extracting from an unpacked vector the index must be scaled to account
1523  // for the "holes" in the underlying packed vector type. We get the scaling
1524  // for free by "promoting" the element type to one whose underlying vector
1525  // type is packed. This is only valid when extracting from a vector whose
1526  // length is the same or bigger than the result of the splat.
1527
1528  foreach VT = [nxv4f16, nxv4bf16] in {
1529    def : Pat<(SVEType<VT>.HalfLength (splat_vector (SVEType<VT>.EltAsScalar (vector_extract (VT ZPR:$vec), sve_elm_idx_extdup_s:$index)))),
1530              (!cast<Instruction>(NAME # _S) ZPR:$vec, sve_elm_idx_extdup_s:$index)>;
1531    def : Pat<(VT (splat_vector (SVEType<VT>.EltAsScalar (vector_extract (VT ZPR:$vec), sve_elm_idx_extdup_s:$index)))),
1532              (!cast<Instruction>(NAME # _S) ZPR:$vec, sve_elm_idx_extdup_s:$index)>;
1533  }
1534
1535  foreach VT = [nxv2f16, nxv2f32, nxv2bf16] in {
1536    def : Pat<(VT (splat_vector (SVEType<VT>.EltAsScalar (vector_extract (VT ZPR:$vec), sve_elm_idx_extdup_d:$index)))),
1537              (!cast<Instruction>(NAME # _D) ZPR:$vec, sve_elm_idx_extdup_d:$index)>;
1538  }
1539
1540  // Duplicate an indexed 128-bit segment across a vector.
1541
1542  def : Pat<(nxv16i8 (AArch64duplane128 nxv16i8:$Op1, i64:$imm)),
1543            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1544  def : Pat<(nxv8i16 (AArch64duplane128 nxv8i16:$Op1, i64:$imm)),
1545            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1546  def : Pat<(nxv4i32 (AArch64duplane128 nxv4i32:$Op1, i64:$imm)),
1547            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1548  def : Pat<(nxv2i64 (AArch64duplane128 nxv2i64:$Op1, i64:$imm)),
1549            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1550  def : Pat<(nxv8f16 (AArch64duplane128 nxv8f16:$Op1, i64:$imm)),
1551            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1552  def : Pat<(nxv4f32 (AArch64duplane128 nxv4f32:$Op1, i64:$imm)),
1553            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1554  def : Pat<(nxv2f64 (AArch64duplane128 nxv2f64:$Op1, i64:$imm)),
1555            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1556  def : Pat<(nxv8bf16 (AArch64duplane128 nxv8bf16:$Op1, i64:$imm)),
1557            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1558}
1559
1560class sve_int_perm_tbl<bits<2> sz8_64, bits<2> opc, string asm, ZPRRegOp zprty,
1561                       RegisterOperand VecList>
1562: I<(outs zprty:$Zd), (ins VecList:$Zn, zprty:$Zm),
1563  asm, "\t$Zd, $Zn, $Zm",
1564  "",
1565  []>, Sched<[]> {
1566  bits<5> Zd;
1567  bits<5> Zm;
1568  bits<5> Zn;
1569  let Inst{31-24} = 0b00000101;
1570  let Inst{23-22} = sz8_64;
1571  let Inst{21}    = 0b1;
1572  let Inst{20-16} = Zm;
1573  let Inst{15-13} = 0b001;
1574  let Inst{12-11} = opc;
1575  let Inst{10}    = 0b0;
1576  let Inst{9-5}   = Zn;
1577  let Inst{4-0}   = Zd;
1578
1579  let hasSideEffects = 0;
1580}
1581
1582multiclass sve_int_perm_tbl<string asm, SDPatternOperator op> {
1583  def _B : sve_int_perm_tbl<0b00, 0b10, asm, ZPR8,  Z_b>;
1584  def _H : sve_int_perm_tbl<0b01, 0b10, asm, ZPR16, Z_h>;
1585  def _S : sve_int_perm_tbl<0b10, 0b10, asm, ZPR32, Z_s>;
1586  def _D : sve_int_perm_tbl<0b11, 0b10, asm, ZPR64, Z_d>;
1587
1588  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1589                 (!cast<Instruction>(NAME # _B) ZPR8:$Zd, ZPR8:$Zn, ZPR8:$Zm), 0>;
1590  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1591                 (!cast<Instruction>(NAME # _H) ZPR16:$Zd, ZPR16:$Zn, ZPR16:$Zm), 0>;
1592  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1593                 (!cast<Instruction>(NAME # _S) ZPR32:$Zd, ZPR32:$Zn, ZPR32:$Zm), 0>;
1594  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1595                 (!cast<Instruction>(NAME # _D) ZPR64:$Zd, ZPR64:$Zn, ZPR64:$Zm), 0>;
1596
1597  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
1598  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1599  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1600  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1601
1602  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1603  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1604  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1605
1606  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1607}
1608
1609multiclass sve2_int_perm_tbl<string asm, SDPatternOperator op> {
1610  def _B : sve_int_perm_tbl<0b00, 0b01, asm, ZPR8,  ZZ_b>;
1611  def _H : sve_int_perm_tbl<0b01, 0b01, asm, ZPR16, ZZ_h>;
1612  def _S : sve_int_perm_tbl<0b10, 0b01, asm, ZPR32, ZZ_s>;
1613  def _D : sve_int_perm_tbl<0b11, 0b01, asm, ZPR64, ZZ_d>;
1614
1615  def : Pat<(nxv16i8 (op nxv16i8:$Op1, nxv16i8:$Op2, nxv16i8:$Op3)),
1616            (nxv16i8 (!cast<Instruction>(NAME # _B) (REG_SEQUENCE ZPR2, nxv16i8:$Op1, zsub0,
1617                                                                        nxv16i8:$Op2, zsub1),
1618                                                     nxv16i8:$Op3))>;
1619
1620  def : Pat<(nxv8i16 (op nxv8i16:$Op1, nxv8i16:$Op2, nxv8i16:$Op3)),
1621            (nxv8i16 (!cast<Instruction>(NAME # _H) (REG_SEQUENCE ZPR2, nxv8i16:$Op1, zsub0,
1622                                                                        nxv8i16:$Op2, zsub1),
1623                                                     nxv8i16:$Op3))>;
1624
1625  def : Pat<(nxv4i32 (op nxv4i32:$Op1, nxv4i32:$Op2, nxv4i32:$Op3)),
1626            (nxv4i32 (!cast<Instruction>(NAME # _S) (REG_SEQUENCE ZPR2, nxv4i32:$Op1, zsub0,
1627                                                                        nxv4i32:$Op2, zsub1),
1628                                                     nxv4i32:$Op3))>;
1629
1630  def : Pat<(nxv2i64 (op nxv2i64:$Op1, nxv2i64:$Op2, nxv2i64:$Op3)),
1631            (nxv2i64 (!cast<Instruction>(NAME # _D) (REG_SEQUENCE ZPR2, nxv2i64:$Op1, zsub0,
1632                                                                        nxv2i64:$Op2, zsub1),
1633                                                     nxv2i64:$Op3))>;
1634
1635  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8i16:$Op3)),
1636            (nxv8f16 (!cast<Instruction>(NAME # _H) (REG_SEQUENCE ZPR2, nxv8f16:$Op1, zsub0,
1637                                                                        nxv8f16:$Op2, zsub1),
1638                                                     nxv8i16:$Op3))>;
1639
1640  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4i32:$Op3)),
1641            (nxv4f32 (!cast<Instruction>(NAME # _S) (REG_SEQUENCE ZPR2, nxv4f32:$Op1, zsub0,
1642                                                                        nxv4f32:$Op2, zsub1),
1643                                                     nxv4i32:$Op3))>;
1644
1645  def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, nxv2i64:$Op3)),
1646            (nxv2f64 (!cast<Instruction>(NAME # _D) (REG_SEQUENCE ZPR2, nxv2f64:$Op1, zsub0,
1647                                                                        nxv2f64:$Op2, zsub1),
1648                                                     nxv2i64:$Op3))>;
1649
1650  def : Pat<(nxv8bf16 (op nxv8bf16:$Op1, nxv8bf16:$Op2, nxv8i16:$Op3)),
1651            (nxv8bf16 (!cast<Instruction>(NAME # _H) (REG_SEQUENCE ZPR2, nxv8bf16:$Op1, zsub0,
1652                                                                         nxv8bf16:$Op2, zsub1),
1653                                                      nxv8i16:$Op3))>;
1654}
1655
1656class sve2_int_perm_tbx<bits<2> sz8_64, bits<2> opc, string asm, ZPRRegOp zprty>
1657: I<(outs zprty:$Zd), (ins zprty:$_Zd, zprty:$Zn, zprty:$Zm),
1658  asm, "\t$Zd, $Zn, $Zm",
1659  "",
1660  []>, Sched<[]> {
1661  bits<5> Zd;
1662  bits<5> Zm;
1663  bits<5> Zn;
1664  let Inst{31-24} = 0b00000101;
1665  let Inst{23-22} = sz8_64;
1666  let Inst{21}    = 0b1;
1667  let Inst{20-16} = Zm;
1668  let Inst{15-13} = 0b001;
1669  let Inst{12-11} = opc;
1670  let Inst{10}    = 0b1;
1671  let Inst{9-5}   = Zn;
1672  let Inst{4-0}   = Zd;
1673
1674  let Constraints = "$Zd = $_Zd";
1675  let hasSideEffects = 0;
1676}
1677
1678multiclass sve2_int_perm_tbx<string asm, bits<2> opc, SDPatternOperator op> {
1679  def _B : sve2_int_perm_tbx<0b00, opc, asm, ZPR8>;
1680  def _H : sve2_int_perm_tbx<0b01, opc, asm, ZPR16>;
1681  def _S : sve2_int_perm_tbx<0b10, opc, asm, ZPR32>;
1682  def _D : sve2_int_perm_tbx<0b11, opc, asm, ZPR64>;
1683
1684  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
1685  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1686  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1687  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1688
1689  def : SVE_3_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1690  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1691  def : SVE_3_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1692
1693  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1694}
1695
1696class sve_int_perm_reverse_z<bits<2> sz8_64, string asm, ZPRRegOp zprty>
1697: I<(outs zprty:$Zd), (ins zprty:$Zn),
1698  asm, "\t$Zd, $Zn",
1699  "",
1700  []>, Sched<[]> {
1701  bits<5> Zd;
1702  bits<5> Zn;
1703  let Inst{31-24} = 0b00000101;
1704  let Inst{23-22} = sz8_64;
1705  let Inst{21-10} = 0b111000001110;
1706  let Inst{9-5}   = Zn;
1707  let Inst{4-0}   = Zd;
1708
1709  let hasSideEffects = 0;
1710}
1711
1712multiclass sve_int_perm_reverse_z<string asm, SDPatternOperator op> {
1713  def _B : sve_int_perm_reverse_z<0b00, asm, ZPR8>;
1714  def _H : sve_int_perm_reverse_z<0b01, asm, ZPR16>;
1715  def _S : sve_int_perm_reverse_z<0b10, asm, ZPR32>;
1716  def _D : sve_int_perm_reverse_z<0b11, asm, ZPR64>;
1717
1718  def : SVE_1_Op_Pat<nxv16i8, op, nxv16i8, !cast<Instruction>(NAME # _B)>;
1719  def : SVE_1_Op_Pat<nxv8i16, op, nxv8i16, !cast<Instruction>(NAME # _H)>;
1720  def : SVE_1_Op_Pat<nxv4i32, op, nxv4i32, !cast<Instruction>(NAME # _S)>;
1721  def : SVE_1_Op_Pat<nxv2i64, op, nxv2i64, !cast<Instruction>(NAME # _D)>;
1722
1723  def : SVE_1_Op_Pat<nxv2f16, op, nxv2f16, !cast<Instruction>(NAME # _D)>;
1724  def : SVE_1_Op_Pat<nxv4f16, op, nxv4f16, !cast<Instruction>(NAME # _S)>;
1725  def : SVE_1_Op_Pat<nxv8f16, op, nxv8f16, !cast<Instruction>(NAME # _H)>;
1726  def : SVE_1_Op_Pat<nxv2f32, op, nxv2f32, !cast<Instruction>(NAME # _D)>;
1727  def : SVE_1_Op_Pat<nxv4f32, op, nxv4f32, !cast<Instruction>(NAME # _S)>;
1728  def : SVE_1_Op_Pat<nxv2f64, op, nxv2f64, !cast<Instruction>(NAME # _D)>;
1729
1730  def : SVE_1_Op_Pat<nxv2bf16, op, nxv2bf16, !cast<Instruction>(NAME # _D)>;
1731  def : SVE_1_Op_Pat<nxv4bf16, op, nxv4bf16, !cast<Instruction>(NAME # _S)>;
1732  def : SVE_1_Op_Pat<nxv8bf16, op, nxv8bf16, !cast<Instruction>(NAME # _H)>;
1733}
1734
1735class sve_int_perm_reverse_p<bits<2> sz8_64, string asm, PPRRegOp pprty,
1736                             SDPatternOperator op>
1737: I<(outs pprty:$Pd), (ins pprty:$Pn),
1738  asm, "\t$Pd, $Pn",
1739  "",
1740  [(set nxv16i1:$Pd, (op nxv16i1:$Pn))]>, Sched<[]> {
1741  bits<4> Pd;
1742  bits<4> Pn;
1743  let Inst{31-24} = 0b00000101;
1744  let Inst{23-22} = sz8_64;
1745  let Inst{21-9}  = 0b1101000100000;
1746  let Inst{8-5}   = Pn;
1747  let Inst{4}     = 0b0;
1748  let Inst{3-0}   = Pd;
1749
1750  let hasSideEffects = 0;
1751}
1752
1753multiclass sve_int_perm_reverse_p<string asm, SDPatternOperator ir_op,
1754                                  SDPatternOperator op_b16,
1755                                  SDPatternOperator op_b32,
1756                                  SDPatternOperator op_b64> {
1757  def _B : sve_int_perm_reverse_p<0b00, asm, PPR8,  ir_op>;
1758  def _H : sve_int_perm_reverse_p<0b01, asm, PPR16, op_b16>;
1759  def _S : sve_int_perm_reverse_p<0b10, asm, PPR32, op_b32>;
1760  def _D : sve_int_perm_reverse_p<0b11, asm, PPR64, op_b64>;
1761
1762  def : SVE_1_Op_Pat<nxv8i1, ir_op, nxv8i1, !cast<Instruction>(NAME # _H)>;
1763  def : SVE_1_Op_Pat<nxv4i1, ir_op, nxv4i1, !cast<Instruction>(NAME # _S)>;
1764  def : SVE_1_Op_Pat<nxv2i1, ir_op, nxv2i1, !cast<Instruction>(NAME # _D)>;
1765}
1766
1767class sve_int_perm_unpk<bits<2> sz16_64, bits<2> opc, string asm,
1768                        ZPRRegOp zprty1, ZPRRegOp zprty2>
1769: I<(outs zprty1:$Zd), (ins zprty2:$Zn),
1770  asm, "\t$Zd, $Zn",
1771  "", []>, Sched<[]> {
1772  bits<5> Zd;
1773  bits<5> Zn;
1774  let Inst{31-24} = 0b00000101;
1775  let Inst{23-22} = sz16_64;
1776  let Inst{21-18} = 0b1100;
1777  let Inst{17-16} = opc;
1778  let Inst{15-10} = 0b001110;
1779  let Inst{9-5}   = Zn;
1780  let Inst{4-0}   = Zd;
1781
1782  let hasSideEffects = 0;
1783}
1784
1785multiclass sve_int_perm_unpk<bits<2> opc, string asm, SDPatternOperator op> {
1786  def _H : sve_int_perm_unpk<0b01, opc, asm, ZPR16, ZPR8>;
1787  def _S : sve_int_perm_unpk<0b10, opc, asm, ZPR32, ZPR16>;
1788  def _D : sve_int_perm_unpk<0b11, opc, asm, ZPR64, ZPR32>;
1789
1790  def : SVE_1_Op_Pat<nxv8i16, op, nxv16i8, !cast<Instruction>(NAME # _H)>;
1791  def : SVE_1_Op_Pat<nxv4i32, op, nxv8i16, !cast<Instruction>(NAME # _S)>;
1792  def : SVE_1_Op_Pat<nxv2i64, op, nxv4i32, !cast<Instruction>(NAME # _D)>;
1793}
1794
1795class sve_int_perm_insrs<bits<2> sz8_64, string asm, ZPRRegOp zprty,
1796                         RegisterClass srcRegType>
1797: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, srcRegType:$Rm),
1798  asm, "\t$Zdn, $Rm",
1799  "",
1800  []>, Sched<[]> {
1801  bits<5> Rm;
1802  bits<5> Zdn;
1803  let Inst{31-24} = 0b00000101;
1804  let Inst{23-22} = sz8_64;
1805  let Inst{21-10} = 0b100100001110;
1806  let Inst{9-5}   = Rm;
1807  let Inst{4-0}   = Zdn;
1808
1809  let Constraints = "$Zdn = $_Zdn";
1810  let DestructiveInstType = DestructiveOther;
1811  let hasSideEffects = 0;
1812}
1813
1814multiclass sve_int_perm_insrs<string asm, SDPatternOperator op> {
1815  def _B : sve_int_perm_insrs<0b00, asm, ZPR8, GPR32>;
1816  def _H : sve_int_perm_insrs<0b01, asm, ZPR16, GPR32>;
1817  def _S : sve_int_perm_insrs<0b10, asm, ZPR32, GPR32>;
1818  def _D : sve_int_perm_insrs<0b11, asm, ZPR64, GPR64>;
1819
1820  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, i32, !cast<Instruction>(NAME # _B)>;
1821  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, i32, !cast<Instruction>(NAME # _H)>;
1822  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, i32, !cast<Instruction>(NAME # _S)>;
1823  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, i64, !cast<Instruction>(NAME # _D)>;
1824}
1825
1826class sve_int_perm_insrv<bits<2> sz8_64, string asm, ZPRRegOp zprty,
1827                         FPRasZPROperand srcOpType>
1828: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, srcOpType:$Vm),
1829  asm, "\t$Zdn, $Vm",
1830  "",
1831  []>, Sched<[]> {
1832  bits<5> Vm;
1833  bits<5> Zdn;
1834  let Inst{31-24} = 0b00000101;
1835  let Inst{23-22} = sz8_64;
1836  let Inst{21-10} = 0b110100001110;
1837  let Inst{9-5}   = Vm;
1838  let Inst{4-0}   = Zdn;
1839
1840  let Constraints = "$Zdn = $_Zdn";
1841  let DestructiveInstType = DestructiveOther;
1842  let hasSideEffects = 0;
1843}
1844
1845multiclass sve_int_perm_insrv<string asm, SDPatternOperator op> {
1846  def _B : sve_int_perm_insrv<0b00, asm, ZPR8, FPR8asZPR>;
1847  def _H : sve_int_perm_insrv<0b01, asm, ZPR16, FPR16asZPR>;
1848  def _S : sve_int_perm_insrv<0b10, asm, ZPR32, FPR32asZPR>;
1849  def _D : sve_int_perm_insrv<0b11, asm, ZPR64, FPR64asZPR>;
1850
1851  def : Pat<(nxv8f16 (op nxv8f16:$Zn, f16:$Vm)),
1852            (!cast<Instruction>(NAME # _H) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, hsub))>;
1853  def : Pat<(nxv4f32 (op nxv4f32:$Zn, f32:$Vm)),
1854            (!cast<Instruction>(NAME # _S) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, ssub))>;
1855  def : Pat<(nxv2f64 (op nxv2f64:$Zn, f64:$Vm)),
1856            (!cast<Instruction>(NAME # _D) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, dsub))>;
1857
1858  def : Pat<(nxv8bf16 (op nxv8bf16:$Zn, bf16:$Vm)),
1859            (!cast<Instruction>(NAME # _H) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, hsub))>;
1860
1861  // Keep integer insertions within the vector unit.
1862  def : Pat<(nxv16i8 (op (nxv16i8 ZPR:$Zn), (i32 (vector_extract (nxv16i8 ZPR:$Vm), 0)))),
1863            (!cast<Instruction>(NAME # _B) $Zn, ZPR:$Vm)>;
1864  def : Pat<(nxv8i16 (op (nxv8i16 ZPR:$Zn), (i32 (vector_extract (nxv8i16 ZPR:$Vm), 0)))),
1865            (!cast<Instruction>(NAME # _H) $Zn, ZPR:$Vm)>;
1866  def : Pat<(nxv4i32 (op (nxv4i32 ZPR:$Zn), (i32 (vector_extract (nxv4i32 ZPR:$Vm), 0)))),
1867            (!cast<Instruction>(NAME # _S) $Zn, ZPR: $Vm)>;
1868  def : Pat<(nxv2i64 (op (nxv2i64 ZPR:$Zn), (i64 (vector_extract (nxv2i64 ZPR:$Vm), 0)))),
1869            (!cast<Instruction>(NAME # _D) $Zn, ZPR:$Vm)>;
1870
1871}
1872
1873//===----------------------------------------------------------------------===//
1874// SVE Permute - Extract Group
1875//===----------------------------------------------------------------------===//
1876
1877class sve_int_perm_extract_i<string asm>
1878: I<(outs ZPR8:$Zdn), (ins ZPR8:$_Zdn, ZPR8:$Zm, imm0_255:$imm8),
1879  asm, "\t$Zdn, $_Zdn, $Zm, $imm8",
1880  "", []>, Sched<[]> {
1881  bits<5> Zdn;
1882  bits<5> Zm;
1883  bits<8> imm8;
1884  let Inst{31-21} = 0b00000101001;
1885  let Inst{20-16} = imm8{7-3};
1886  let Inst{15-13} = 0b000;
1887  let Inst{12-10} = imm8{2-0};
1888  let Inst{9-5}   = Zm;
1889  let Inst{4-0}   = Zdn;
1890
1891  let Constraints = "$Zdn = $_Zdn";
1892  let DestructiveInstType = DestructiveOther;
1893  let ElementSize = ElementSizeNone;
1894  let hasSideEffects = 0;
1895}
1896
1897multiclass sve_int_perm_extract_i<string asm, SDPatternOperator op> {
1898  def NAME : sve_int_perm_extract_i<asm>;
1899
1900  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, imm0_255,
1901                         !cast<Instruction>(NAME)>;
1902}
1903
1904class sve2_int_perm_extract_i_cons<string asm>
1905: I<(outs ZPR8:$Zd), (ins ZZ_b:$Zn, imm0_255:$imm8),
1906  asm, "\t$Zd, $Zn, $imm8",
1907  "", []>, Sched<[]> {
1908  bits<5> Zd;
1909  bits<5> Zn;
1910  bits<8> imm8;
1911  let Inst{31-21} = 0b00000101011;
1912  let Inst{20-16} = imm8{7-3};
1913  let Inst{15-13} = 0b000;
1914  let Inst{12-10} = imm8{2-0};
1915  let Inst{9-5}   = Zn;
1916  let Inst{4-0}   = Zd;
1917
1918  let hasSideEffects = 0;
1919}
1920
1921//===----------------------------------------------------------------------===//
1922// SVE Vector Select Group
1923//===----------------------------------------------------------------------===//
1924
1925class sve_int_sel_vvv<bits<2> sz8_64, string asm, ZPRRegOp zprty>
1926: I<(outs zprty:$Zd), (ins PPRAny:$Pg, zprty:$Zn, zprty:$Zm),
1927  asm, "\t$Zd, $Pg, $Zn, $Zm",
1928  "",
1929  []>, Sched<[]> {
1930  bits<4> Pg;
1931  bits<5> Zd;
1932  bits<5> Zm;
1933  bits<5> Zn;
1934  let Inst{31-24} = 0b00000101;
1935  let Inst{23-22} = sz8_64;
1936  let Inst{21}    = 0b1;
1937  let Inst{20-16} = Zm;
1938  let Inst{15-14} = 0b11;
1939  let Inst{13-10} = Pg;
1940  let Inst{9-5}   = Zn;
1941  let Inst{4-0}   = Zd;
1942
1943  let hasSideEffects = 0;
1944}
1945
1946multiclass sve_int_sel_vvv<string asm, SDPatternOperator op> {
1947  def _B : sve_int_sel_vvv<0b00, asm, ZPR8>;
1948  def _H : sve_int_sel_vvv<0b01, asm, ZPR16>;
1949  def _S : sve_int_sel_vvv<0b10, asm, ZPR32>;
1950  def _D : sve_int_sel_vvv<0b11, asm, ZPR64>;
1951
1952  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
1953  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1954  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1955  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1956
1957  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1,  nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
1958  def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1,  nxv4f16, nxv4f16, !cast<Instruction>(NAME # _S)>;
1959  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1,  nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
1960  def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1,  nxv2f16, nxv2f16, !cast<Instruction>(NAME # _D)>;
1961  def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1,  nxv2f32, nxv2f32, !cast<Instruction>(NAME # _D)>;
1962  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1,  nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
1963
1964  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1,  nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
1965
1966  def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1967                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPRAny:$Pg, ZPR8:$Zn, ZPR8:$Zd), 1>;
1968  def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1969                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, ZPR16:$Zn, ZPR16:$Zd), 1>;
1970  def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1971                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, ZPR32:$Zn, ZPR32:$Zd), 1>;
1972  def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1973                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, ZPR64:$Zn, ZPR64:$Zd), 1>;
1974}
1975
1976
1977//===----------------------------------------------------------------------===//
1978// SVE Predicate Logical Operations Group
1979//===----------------------------------------------------------------------===//
1980
1981class sve_int_pred_log<bits<4> opc, string asm>
1982: I<(outs PPRorPNR8:$Pd), (ins PPRorPNRAny:$Pg, PPRorPNR8:$Pn, PPRorPNR8:$Pm),
1983  asm, "\t$Pd, $Pg/z, $Pn, $Pm",
1984  "",
1985  []>, Sched<[]> {
1986  bits<4> Pd;
1987  bits<4> Pg;
1988  bits<4> Pm;
1989  bits<4> Pn;
1990  let Inst{31-24} = 0b00100101;
1991  let Inst{23-22} = opc{3-2};
1992  let Inst{21-20} = 0b00;
1993  let Inst{19-16} = Pm;
1994  let Inst{15-14} = 0b01;
1995  let Inst{13-10} = Pg;
1996  let Inst{9}     = opc{1};
1997  let Inst{8-5}   = Pn;
1998  let Inst{4}     = opc{0};
1999  let Inst{3-0}   = Pd;
2000
2001  // SEL has no predication qualifier.
2002  let AsmString = !if(!eq(opc, 0b0011),
2003                      !strconcat(asm, "\t$Pd, $Pg, $Pn, $Pm"),
2004                      !strconcat(asm, "\t$Pd, $Pg/z, $Pn, $Pm"));
2005
2006  let Defs = !if(!eq (opc{2}, 1), [NZCV], []);
2007  let hasSideEffects = 0;
2008}
2009
2010multiclass sve_int_pred_log<bits<4> opc, string asm, SDPatternOperator op,
2011                            SDPatternOperator op_nopred = null_frag> {
2012  def NAME : sve_int_pred_log<opc, asm>;
2013
2014  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
2015  def : SVE_3_Op_Pat<nxv8i1, op, nxv8i1, nxv8i1, nxv8i1, !cast<Instruction>(NAME)>;
2016  def : SVE_3_Op_Pat<nxv4i1, op, nxv4i1, nxv4i1, nxv4i1, !cast<Instruction>(NAME)>;
2017  def : SVE_3_Op_Pat<nxv2i1, op, nxv2i1, nxv2i1, nxv2i1, !cast<Instruction>(NAME)>;
2018  def : SVE_3_Op_Pat<nxv1i1, op, nxv1i1, nxv1i1, nxv1i1, !cast<Instruction>(NAME)>;
2019  def : SVE_2_Op_AllActive_Pat<nxv16i1, op_nopred, nxv16i1, nxv16i1,
2020                               !cast<Instruction>(NAME), PTRUE_B>;
2021  def : SVE_2_Op_AllActive_Pat<nxv8i1, op_nopred, nxv8i1, nxv8i1,
2022                               !cast<Instruction>(NAME), PTRUE_H>;
2023  def : SVE_2_Op_AllActive_Pat<nxv4i1, op_nopred, nxv4i1, nxv4i1,
2024                               !cast<Instruction>(NAME), PTRUE_S>;
2025  def : SVE_2_Op_AllActive_Pat<nxv2i1, op_nopred, nxv2i1, nxv2i1,
2026                               !cast<Instruction>(NAME), PTRUE_D>;
2027  // Emulate .Q operation using a PTRUE_D when the other lanes don't matter.
2028  def : SVE_2_Op_AllActive_Pat<nxv1i1, op_nopred, nxv1i1, nxv1i1,
2029                               !cast<Instruction>(NAME), PTRUE_D>;
2030}
2031
2032// An instance of sve_int_pred_log_and but uses op_nopred's first operand as the
2033// general predicate.
2034multiclass sve_int_pred_log_v2<bits<4> opc, string asm, SDPatternOperator op,
2035                               SDPatternOperator op_nopred> :
2036  sve_int_pred_log<opc, asm, op> {
2037  def : Pat<(nxv16i1 (op_nopred nxv16i1:$Op1, nxv16i1:$Op2)),
2038            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
2039  def : Pat<(nxv8i1 (op_nopred nxv8i1:$Op1, nxv8i1:$Op2)),
2040            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
2041  def : Pat<(nxv4i1 (op_nopred nxv4i1:$Op1, nxv4i1:$Op2)),
2042            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
2043  def : Pat<(nxv2i1 (op_nopred nxv2i1:$Op1, nxv2i1:$Op2)),
2044            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
2045  // Emulate .Q operation using a PTRUE_D when the other lanes don't matter.
2046  def : Pat<(nxv1i1 (op_nopred nxv1i1:$Op1, nxv1i1:$Op2)),
2047            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
2048}
2049
2050//===----------------------------------------------------------------------===//
2051// SVE Logical Mask Immediate Group
2052//===----------------------------------------------------------------------===//
2053
2054class sve_int_log_imm<bits<2> opc, string asm>
2055: I<(outs ZPR64:$Zdn), (ins ZPR64:$_Zdn, logical_imm64:$imms13),
2056  asm, "\t$Zdn, $_Zdn, $imms13",
2057  "", []>, Sched<[]> {
2058  bits<5> Zdn;
2059  bits<13> imms13;
2060  let Inst{31-24} = 0b00000101;
2061  let Inst{23-22} = opc;
2062  let Inst{21-18} = 0b0000;
2063  let Inst{17-5}  = imms13;
2064  let Inst{4-0}   = Zdn;
2065
2066  let Constraints = "$Zdn = $_Zdn";
2067  let DecoderMethod = "DecodeSVELogicalImmInstruction";
2068  let DestructiveInstType = DestructiveOther;
2069  let ElementSize = ElementSizeNone;
2070  let hasSideEffects = 0;
2071}
2072
2073multiclass sve_int_log_imm<bits<2> opc, string asm, string alias, SDPatternOperator op> {
2074  def NAME : sve_int_log_imm<opc, asm>;
2075
2076  def : SVE_1_Op_Imm_Log_Pat<nxv16i8, op, ZPR8,  i32, SVELogicalImm8Pat,  !cast<Instruction>(NAME)>;
2077  def : SVE_1_Op_Imm_Log_Pat<nxv8i16, op, ZPR16, i32, SVELogicalImm16Pat, !cast<Instruction>(NAME)>;
2078  def : SVE_1_Op_Imm_Log_Pat<nxv4i32, op, ZPR32, i32, SVELogicalImm32Pat, !cast<Instruction>(NAME)>;
2079  def : SVE_1_Op_Imm_Log_Pat<nxv2i64, op, ZPR64, i64, SVELogicalImm64Pat, !cast<Instruction>(NAME)>;
2080
2081  def : InstAlias<asm # "\t$Zdn, $Zdn, $imm",
2082                  (!cast<Instruction>(NAME) ZPR8:$Zdn, sve_logical_imm8:$imm), 4>;
2083  def : InstAlias<asm # "\t$Zdn, $Zdn, $imm",
2084                  (!cast<Instruction>(NAME) ZPR16:$Zdn, sve_logical_imm16:$imm), 3>;
2085  def : InstAlias<asm # "\t$Zdn, $Zdn, $imm",
2086                  (!cast<Instruction>(NAME) ZPR32:$Zdn, sve_logical_imm32:$imm), 2>;
2087
2088  def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
2089                  (!cast<Instruction>(NAME) ZPR8:$Zdn, sve_logical_imm8_not:$imm), 0>;
2090  def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
2091                  (!cast<Instruction>(NAME) ZPR16:$Zdn, sve_logical_imm16_not:$imm), 0>;
2092  def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
2093                  (!cast<Instruction>(NAME) ZPR32:$Zdn, sve_logical_imm32_not:$imm), 0>;
2094  def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
2095                  (!cast<Instruction>(NAME) ZPR64:$Zdn, logical_imm64_not:$imm), 0>;
2096}
2097
2098multiclass sve_int_log_imm_bic<SDPatternOperator op> {
2099  def : SVE_1_Op_Imm_Log_Pat<nxv16i8, op, ZPR8,  i32, SVELogicalImm8NotPat,  !cast<Instruction>("AND_ZI")>;
2100  def : SVE_1_Op_Imm_Log_Pat<nxv8i16, op, ZPR16, i32, SVELogicalImm16NotPat, !cast<Instruction>("AND_ZI")>;
2101  def : SVE_1_Op_Imm_Log_Pat<nxv4i32, op, ZPR32, i32, SVELogicalImm32NotPat, !cast<Instruction>("AND_ZI")>;
2102  def : SVE_1_Op_Imm_Log_Pat<nxv2i64, op, ZPR64, i64, SVELogicalImm64NotPat, !cast<Instruction>("AND_ZI")>;
2103}
2104
2105class sve_int_dup_mask_imm<string asm>
2106: I<(outs ZPR64:$Zd), (ins logical_imm64:$imms),
2107  asm, "\t$Zd, $imms",
2108  "",
2109  []>, Sched<[]> {
2110  bits<5> Zd;
2111  bits<13> imms;
2112  let Inst{31-18} = 0b00000101110000;
2113  let Inst{17-5} = imms;
2114  let Inst{4-0} = Zd;
2115
2116  let DecoderMethod = "DecodeSVELogicalImmInstruction";
2117  let hasSideEffects = 0;
2118  let isReMaterializable = 1;
2119  let Uses = [VG];
2120}
2121
2122multiclass sve_int_dup_mask_imm<string asm> {
2123  def NAME : sve_int_dup_mask_imm<asm>;
2124
2125  def : InstAlias<"dupm $Zd, $imm",
2126                  (!cast<Instruction>(NAME) ZPR8:$Zd, sve_logical_imm8:$imm), 4>;
2127  def : InstAlias<"dupm $Zd, $imm",
2128                  (!cast<Instruction>(NAME) ZPR16:$Zd, sve_logical_imm16:$imm), 3>;
2129  def : InstAlias<"dupm $Zd, $imm",
2130                  (!cast<Instruction>(NAME) ZPR32:$Zd, sve_logical_imm32:$imm), 2>;
2131
2132  // All Zd.b forms have a CPY/DUP equivalent, hence no byte alias here.
2133  def : InstAlias<"mov $Zd, $imm",
2134                  (!cast<Instruction>(NAME) ZPR16:$Zd, sve_preferred_logical_imm16:$imm), 7>;
2135  def : InstAlias<"mov $Zd, $imm",
2136                  (!cast<Instruction>(NAME) ZPR32:$Zd, sve_preferred_logical_imm32:$imm), 6>;
2137  def : InstAlias<"mov $Zd, $imm",
2138                  (!cast<Instruction>(NAME) ZPR64:$Zd, sve_preferred_logical_imm64:$imm), 5>;
2139
2140  // NOTE: No pattern for nxv16i8 because DUP has full coverage.
2141  def : Pat<(nxv8i16 (splat_vector (i32 (SVELogicalImm16Pat i64:$imm)))),
2142            (!cast<Instruction>(NAME) i64:$imm)>;
2143  def : Pat<(nxv4i32 (splat_vector (i32 (SVELogicalImm32Pat i64:$imm)))),
2144            (!cast<Instruction>(NAME) i64:$imm)>;
2145  def : Pat<(nxv2i64 (splat_vector (i64 (SVELogicalImm64Pat i64:$imm)))),
2146            (!cast<Instruction>(NAME) i64:$imm)>;
2147}
2148
2149//===----------------------------------------------------------------------===//
2150// SVE Integer Arithmetic -  Unpredicated Group.
2151//===----------------------------------------------------------------------===//
2152
2153class sve_int_bin_cons_arit_0<bits<2> sz8_64, bits<3> opc, string asm,
2154                              ZPRRegOp zprty>
2155: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
2156  asm, "\t$Zd, $Zn, $Zm",
2157  "", []>, Sched<[]> {
2158  bits<5> Zd;
2159  bits<5> Zm;
2160  bits<5> Zn;
2161  let Inst{31-24} = 0b00000100;
2162  let Inst{23-22} = sz8_64;
2163  let Inst{21}    = 0b1;
2164  let Inst{20-16} = Zm;
2165  let Inst{15-13} = 0b000;
2166  let Inst{12-10} = opc;
2167  let Inst{9-5}   = Zn;
2168  let Inst{4-0}   = Zd;
2169
2170  let hasSideEffects = 0;
2171}
2172
2173multiclass sve_int_bin_cons_arit_0<bits<3> opc, string asm, SDPatternOperator op> {
2174  def _B : sve_int_bin_cons_arit_0<0b00, opc, asm, ZPR8>;
2175  def _H : sve_int_bin_cons_arit_0<0b01, opc, asm, ZPR16>;
2176  def _S : sve_int_bin_cons_arit_0<0b10, opc, asm, ZPR32>;
2177  def _D : sve_int_bin_cons_arit_0<0b11, opc, asm, ZPR64>;
2178
2179  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
2180  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2181  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2182  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2183}
2184
2185//===----------------------------------------------------------------------===//
2186// SVE Floating Point Arithmetic - Predicated Group
2187//===----------------------------------------------------------------------===//
2188
2189class sve_fp_2op_i_p_zds<bits<2> sz, bits<3> opc, string asm,
2190                         ZPRRegOp zprty,
2191                         Operand imm_ty>
2192: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, imm_ty:$i1),
2193  asm, "\t$Zdn, $Pg/m, $_Zdn, $i1",
2194  "",
2195  []>, Sched<[]> {
2196  bits<3> Pg;
2197  bits<5> Zdn;
2198  bit i1;
2199  let Inst{31-24} = 0b01100101;
2200  let Inst{23-22} = sz;
2201  let Inst{21-19} = 0b011;
2202  let Inst{18-16} = opc;
2203  let Inst{15-13} = 0b100;
2204  let Inst{12-10} = Pg;
2205  let Inst{9-6}   = 0b0000;
2206  let Inst{5}     = i1;
2207  let Inst{4-0}   = Zdn;
2208
2209  let Constraints = "$Zdn = $_Zdn";
2210  let DestructiveInstType = DestructiveOther;
2211  let ElementSize = zprty.ElementSize;
2212  let hasSideEffects = 0;
2213  let mayRaiseFPException = 1;
2214}
2215
2216multiclass sve_fp_2op_i_p_zds<bits<3> opc, string asm, string Ps, Operand imm_ty, FPImmLeaf A, FPImmLeaf B, SDPatternOperator op> {
2217  let DestructiveInstType = DestructiveBinaryImm in {
2218  def _H : SVEPseudo2Instr<Ps # _H, 1>, sve_fp_2op_i_p_zds<0b01, opc, asm, ZPR16, imm_ty>;
2219  def _S : SVEPseudo2Instr<Ps # _S, 1>, sve_fp_2op_i_p_zds<0b10, opc, asm, ZPR32, imm_ty>;
2220  def _D : SVEPseudo2Instr<Ps # _D, 1>, sve_fp_2op_i_p_zds<0b11, opc, asm, ZPR64, imm_ty>;
2221  }
2222
2223  def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, op, nxv8i1, f16, A, 0, !cast<Instruction>(NAME # "_H")>;
2224  def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, op, nxv8i1, f16, B, 1, !cast<Instruction>(NAME # "_H")>;
2225  def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, op, nxv4i1, f32, A, 0, !cast<Instruction>(NAME # "_S")>;
2226  def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, op, nxv4i1, f32, B, 1, !cast<Instruction>(NAME # "_S")>;
2227  def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, op, nxv2i1, f64, A, 0, !cast<Instruction>(NAME # "_D")>;
2228  def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, op, nxv2i1, f64, B, 1, !cast<Instruction>(NAME # "_D")>;
2229}
2230
2231class sve_fp_2op_p_zds<bits<2> sz, bits<4> opc, string asm,
2232                       ZPRRegOp zprty>
2233: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
2234  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
2235  "",
2236  []>, Sched<[]> {
2237  bits<3> Pg;
2238  bits<5> Zdn;
2239  bits<5> Zm;
2240  let Inst{31-24} = 0b01100101;
2241  let Inst{23-22} = sz;
2242  let Inst{21-20} = 0b00;
2243  let Inst{19-16} = opc;
2244  let Inst{15-13} = 0b100;
2245  let Inst{12-10} = Pg;
2246  let Inst{9-5}   = Zm;
2247  let Inst{4-0}   = Zdn;
2248
2249  let Constraints = "$Zdn = $_Zdn";
2250  let DestructiveInstType = DestructiveOther;
2251  let ElementSize = zprty.ElementSize;
2252  let hasSideEffects = 0;
2253  let mayRaiseFPException = 1;
2254}
2255
2256multiclass sve_fp_2op_p_zds<bits<4> opc, string asm, string Ps,
2257                            SDPatternOperator op, DestructiveInstTypeEnum flags,
2258                            string revname="", bit isReverseInstr=0> {
2259  let DestructiveInstType = flags in {
2260  def _H : sve_fp_2op_p_zds<0b01, opc, asm, ZPR16>,
2261           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2262  def _S : sve_fp_2op_p_zds<0b10, opc, asm, ZPR32>,
2263           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2264  def _D : sve_fp_2op_p_zds<0b11, opc, asm, ZPR64>,
2265           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2266  }
2267
2268  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2269  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2270  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2271}
2272
2273multiclass sve_fp_2op_p_zds_fscale<bits<4> opc, string asm,
2274                                   SDPatternOperator op> {
2275  def _H : sve_fp_2op_p_zds<0b01, opc, asm, ZPR16>;
2276  def _S : sve_fp_2op_p_zds<0b10, opc, asm, ZPR32>;
2277  def _D : sve_fp_2op_p_zds<0b11, opc, asm, ZPR64>;
2278
2279  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2280  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2281  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2282}
2283
2284multiclass sve_fp_2op_p_zds_bfloat<bits<4> opc, string asm, string Ps,
2285                                   SDPatternOperator op,
2286                                   DestructiveInstTypeEnum flags,
2287                                   string revname="", bit isReverseInstr=0> {
2288  let DestructiveInstType = flags in {
2289  def NAME : sve_fp_2op_p_zds<0b00, opc, asm, ZPR16>,
2290             SVEPseudo2Instr<Ps, 1>, SVEInstr2Rev<NAME , revname , isReverseInstr>;
2291  }
2292
2293  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
2294}
2295
2296class  sve_fp_2op_p_zds_bfscale<bits<4> opc, string asm,  DestructiveInstTypeEnum flags>
2297: sve_fp_2op_p_zds<0b00, opc, asm, ZPR16>{
2298  let DestructiveInstType = flags;
2299}
2300
2301multiclass sve_fp_2op_p_zds_zeroing_hsd<SDPatternOperator op> {
2302  def _H_ZERO : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesZero>;
2303  def _S_ZERO : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesZero>;
2304  def _D_ZERO : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesZero>;
2305
2306  def : SVE_3_Op_Pat_SelZero<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Pseudo>(NAME # _H_ZERO)>;
2307  def : SVE_3_Op_Pat_SelZero<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Pseudo>(NAME # _S_ZERO)>;
2308  def : SVE_3_Op_Pat_SelZero<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Pseudo>(NAME # _D_ZERO)>;
2309}
2310
2311multiclass sve_fp_2op_p_zds_zeroing_bfloat<SDPatternOperator op> {
2312  def _ZERO : PredTwoOpPseudo<NAME, ZPR16, FalseLanesZero>;
2313
2314  def : SVE_3_Op_Pat_SelZero<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Pseudo>(NAME # _ZERO)>;
2315}
2316
2317class sve_fp_ftmad<bits<2> sz, string asm, ZPRRegOp zprty>
2318: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, timm32_0_7:$imm3),
2319  asm, "\t$Zdn, $_Zdn, $Zm, $imm3",
2320  "",
2321  []>, Sched<[]> {
2322  bits<5> Zdn;
2323  bits<5> Zm;
2324  bits<3> imm3;
2325  let Inst{31-24} = 0b01100101;
2326  let Inst{23-22} = sz;
2327  let Inst{21-19} = 0b010;
2328  let Inst{18-16} = imm3;
2329  let Inst{15-10} = 0b100000;
2330  let Inst{9-5}   = Zm;
2331  let Inst{4-0}   = Zdn;
2332
2333  let Constraints = "$Zdn = $_Zdn";
2334  let DestructiveInstType = DestructiveOther;
2335  let ElementSize = ElementSizeNone;
2336  let hasSideEffects = 0;
2337  let mayRaiseFPException = 1;
2338}
2339
2340multiclass sve_fp_ftmad<string asm, SDPatternOperator op> {
2341  def _H : sve_fp_ftmad<0b01, asm, ZPR16>;
2342  def _S : sve_fp_ftmad<0b10, asm, ZPR32>;
2343  def _D : sve_fp_ftmad<0b11, asm, ZPR64>;
2344
2345  def : Pat<(nxv8f16 (op (nxv8f16 ZPR16:$Zn), (nxv8f16 ZPR16:$Zm), (i32 timm32_0_7:$imm))),
2346            (!cast<Instruction>(NAME # _H) ZPR16:$Zn, ZPR16:$Zm, timm32_0_7:$imm)>;
2347  def : Pat<(nxv4f32 (op (nxv4f32 ZPR32:$Zn), (nxv4f32 ZPR32:$Zm), (i32 timm32_0_7:$imm))),
2348            (!cast<Instruction>(NAME # _S) ZPR32:$Zn, ZPR32:$Zm, timm32_0_7:$imm)>;
2349  def : Pat<(nxv2f64 (op (nxv2f64 ZPR64:$Zn), (nxv2f64 ZPR64:$Zm), (i32 timm32_0_7:$imm))),
2350            (!cast<Instruction>(NAME # _D) ZPR64:$Zn, ZPR64:$Zm, timm32_0_7:$imm)>;
2351}
2352
2353multiclass sve_fp_2op_i_p_zds_hfd<Operand imm_ty, FPImmLeaf A, FPImmLeaf B, SDPatternOperator ir_op = null_frag> {
2354  def _H_UNDEF : PredTwoOpImmPseudo<NAME # _H, ZPR16, imm_ty, FalseLanesUndef>;
2355  def _S_UNDEF : PredTwoOpImmPseudo<NAME # _S, ZPR32, imm_ty, FalseLanesUndef>;
2356  def _D_UNDEF : PredTwoOpImmPseudo<NAME # _D, ZPR64, imm_ty, FalseLanesUndef>;
2357
2358  def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, ir_op, nxv8i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2359  def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, ir_op, nxv8i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2360  def : SVE_2_Op_Fp_Imm_Pat<nxv4f16, ir_op, nxv4i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2361  def : SVE_2_Op_Fp_Imm_Pat<nxv4f16, ir_op, nxv4i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2362  def : SVE_2_Op_Fp_Imm_Pat<nxv2f16, ir_op, nxv2i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2363  def : SVE_2_Op_Fp_Imm_Pat<nxv2f16, ir_op, nxv2i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2364  def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, ir_op, nxv4i1, f32, A, 0, !cast<Instruction>(NAME # "_S_UNDEF")>;
2365  def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, ir_op, nxv4i1, f32, B, 1, !cast<Instruction>(NAME # "_S_UNDEF")>;
2366  def : SVE_2_Op_Fp_Imm_Pat<nxv2f32, ir_op, nxv2i1, f32, A, 0, !cast<Instruction>(NAME # "_S_UNDEF")>;
2367  def : SVE_2_Op_Fp_Imm_Pat<nxv2f32, ir_op, nxv2i1, f32, B, 1, !cast<Instruction>(NAME # "_S_UNDEF")>;
2368  def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, ir_op, nxv2i1, f64, A, 0, !cast<Instruction>(NAME # "_D_UNDEF")>;
2369  def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, ir_op, nxv2i1, f64, B, 1, !cast<Instruction>(NAME # "_D_UNDEF")>;
2370}
2371
2372multiclass sve_fp_2op_i_p_zds_zeroing_hfd<Operand imm_ty, FPImmLeaf A, FPImmLeaf B, SDPatternOperator op> {
2373  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, imm_ty, FalseLanesZero>;
2374  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, imm_ty, FalseLanesZero>;
2375  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, imm_ty, FalseLanesZero>;
2376
2377  let AddedComplexity = 2 in {
2378    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv8f16, op, nxv8i1, f16, A, 0, !cast<Instruction>(NAME # "_H_ZERO")>;
2379    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv8f16, op, nxv8i1, f16, B, 1, !cast<Instruction>(NAME # "_H_ZERO")>;
2380    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv4f32, op, nxv4i1, f32, A, 0, !cast<Instruction>(NAME # "_S_ZERO")>;
2381    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv4f32, op, nxv4i1, f32, B, 1, !cast<Instruction>(NAME # "_S_ZERO")>;
2382    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv2f64, op, nxv2i1, f64, A, 0, !cast<Instruction>(NAME # "_D_ZERO")>;
2383    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv2f64, op, nxv2i1, f64, B, 1, !cast<Instruction>(NAME # "_D_ZERO")>;
2384  }
2385}
2386
2387//===----------------------------------------------------------------------===//
2388// SVE Floating Point Arithmetic - Unpredicated Group
2389//===----------------------------------------------------------------------===//
2390
2391class sve_fp_3op_u_zd<bits<2> sz, bits<3> opc, string asm, ZPRRegOp zprty>
2392: I<(outs zprty:$Zd), (ins  zprty:$Zn, zprty:$Zm),
2393  asm, "\t$Zd, $Zn, $Zm",
2394  "",
2395  []>, Sched<[]> {
2396  bits<5> Zd;
2397  bits<5> Zm;
2398  bits<5> Zn;
2399  let Inst{31-24} = 0b01100101;
2400  let Inst{23-22} = sz;
2401  let Inst{21}    = 0b0;
2402  let Inst{20-16} = Zm;
2403  let Inst{15-13} = 0b000;
2404  let Inst{12-10} = opc;
2405  let Inst{9-5}   = Zn;
2406  let Inst{4-0}   = Zd;
2407
2408  let hasSideEffects = 0;
2409  let mayRaiseFPException = 1;
2410}
2411
2412multiclass sve_fp_3op_u_zd<bits<3> opc, string asm, SDPatternOperator op> {
2413  def _H : sve_fp_3op_u_zd<0b01, opc, asm, ZPR16>;
2414  def _S : sve_fp_3op_u_zd<0b10, opc, asm, ZPR32>;
2415  def _D : sve_fp_3op_u_zd<0b11, opc, asm, ZPR64>;
2416
2417  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2418  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2419  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2420}
2421
2422multiclass sve_fp_3op_u_zd_bfloat<bits<3> opc, string asm, SDPatternOperator op> {
2423  def NAME : sve_fp_3op_u_zd<0b00, opc, asm, ZPR16>;
2424
2425  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
2426  def : SVE_2_Op_Pat<nxv4bf16, op, nxv4bf16, nxv4bf16, !cast<Instruction>(NAME)>;
2427  def : SVE_2_Op_Pat<nxv2bf16, op, nxv2bf16, nxv2bf16, !cast<Instruction>(NAME)>;
2428}
2429
2430multiclass sve_fp_3op_u_zd_ftsmul<bits<3> opc, string asm, SDPatternOperator op> {
2431  def _H : sve_fp_3op_u_zd<0b01, opc, asm, ZPR16>;
2432  def _S : sve_fp_3op_u_zd<0b10, opc, asm, ZPR32>;
2433  def _D : sve_fp_3op_u_zd<0b11, opc, asm, ZPR64>;
2434
2435  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2436  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2437  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2438}
2439
2440//===----------------------------------------------------------------------===//
2441// SVE Floating Point Fused Multiply-Add Group
2442//===----------------------------------------------------------------------===//
2443
2444class sve_fp_3op_p_zds_a<bits<2> sz, bits<2> opc, string asm, ZPRRegOp zprty>
2445: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm),
2446  asm, "\t$Zda, $Pg/m, $Zn, $Zm",
2447  "",
2448  []>, Sched<[]> {
2449  bits<3> Pg;
2450  bits<5> Zda;
2451  bits<5> Zm;
2452  bits<5> Zn;
2453  let Inst{31-24} = 0b01100101;
2454  let Inst{23-22} = sz;
2455  let Inst{21}    = 0b1;
2456  let Inst{20-16} = Zm;
2457  let Inst{15}    = 0b0;
2458  let Inst{14-13} = opc;
2459  let Inst{12-10} = Pg;
2460  let Inst{9-5}   = Zn;
2461  let Inst{4-0}   = Zda;
2462
2463  let Constraints = "$Zda = $_Zda";
2464  let ElementSize = zprty.ElementSize;
2465  let DestructiveInstType = DestructiveTernaryCommWithRev;
2466  let hasSideEffects = 0;
2467  let mayRaiseFPException = 1;
2468}
2469
2470multiclass sve_fp_3op_p_zds_a<bits<2> opc, string asm, string Ps,
2471                              SDPatternOperator op, string revname,
2472                              bit isReverseInstr=0> {
2473  def _H : sve_fp_3op_p_zds_a<0b01, opc, asm, ZPR16>,
2474           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2475  def _S : sve_fp_3op_p_zds_a<0b10, opc, asm, ZPR32>,
2476           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2477  def _D : sve_fp_3op_p_zds_a<0b11, opc, asm, ZPR64>,
2478           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2479
2480  def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2481  def : SVE_4_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H)>;
2482  def : SVE_4_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H)>;
2483  def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2484  def : SVE_4_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S)>;
2485  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2486}
2487
2488multiclass sve_fp_3op_p_zds_a_bfloat<bits<2> opc, string asm, string Ps,
2489                                     SDPatternOperator op> {
2490  def NAME : sve_fp_3op_p_zds_a<0b00, opc, asm, ZPR16>,
2491           SVEPseudo2Instr<Ps, 1>, SVEInstr2Rev<NAME, "", 0>;
2492
2493  def : SVE_4_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
2494}
2495
2496class sve_fp_3op_p_zds_b<bits<2> sz, bits<2> opc, string asm,
2497                         ZPRRegOp zprty>
2498: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm, zprty:$Za),
2499  asm, "\t$Zdn, $Pg/m, $Zm, $Za",
2500  "",
2501  []>, Sched<[]> {
2502  bits<3> Pg;
2503  bits<5> Za;
2504  bits<5> Zdn;
2505  bits<5> Zm;
2506  let Inst{31-24} = 0b01100101;
2507  let Inst{23-22} = sz;
2508  let Inst{21}    = 0b1;
2509  let Inst{20-16} = Za;
2510  let Inst{15}    = 0b1;
2511  let Inst{14-13} = opc;
2512  let Inst{12-10} = Pg;
2513  let Inst{9-5}   = Zm;
2514  let Inst{4-0}   = Zdn;
2515
2516  let Constraints = "$Zdn = $_Zdn";
2517  let DestructiveInstType = DestructiveOther;
2518  let ElementSize = zprty.ElementSize;
2519  let hasSideEffects = 0;
2520  let mayRaiseFPException = 1;
2521}
2522
2523multiclass sve_fp_3op_p_zds_b<bits<2> opc, string asm, SDPatternOperator op,
2524                              string revname, bit isReverseInstr> {
2525  def _H : sve_fp_3op_p_zds_b<0b01, opc, asm, ZPR16>,
2526           SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2527  def _S : sve_fp_3op_p_zds_b<0b10, opc, asm, ZPR32>,
2528           SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2529  def _D : sve_fp_3op_p_zds_b<0b11, opc, asm, ZPR64>,
2530           SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2531
2532  def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2533  def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2534  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2535}
2536
2537//===----------------------------------------------------------------------===//
2538// SVE Floating Point Multiply-Add - Indexed Group
2539//===----------------------------------------------------------------------===//
2540
2541class sve_fp_fma_by_indexed_elem<bits<2> sz, bits<2> opc, string asm,
2542                                 ZPRRegOp zprty1,
2543                                 ZPRRegOp zprty2, Operand itype>
2544: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty1:$Zn, zprty2:$Zm, itype:$iop),
2545  asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
2546  bits<5> Zda;
2547  bits<5> Zn;
2548  let Inst{31-24} = 0b01100100;
2549  let Inst{23-22} = sz;
2550  let Inst{21}    = 0b1;
2551  let Inst{15-12} = 0b0000;
2552  let Inst{11-10} = opc;
2553  let Inst{9-5}   = Zn;
2554  let Inst{4-0}   = Zda;
2555
2556  let Constraints = "$Zda = $_Zda";
2557  let DestructiveInstType = DestructiveOther;
2558  let ElementSize = ElementSizeNone;
2559  let hasSideEffects = 0;
2560  let mayRaiseFPException = 1;
2561}
2562
2563multiclass sve_fp_fma_by_indexed_elem<bits<2> opc, string asm,
2564                                      SDPatternOperator op> {
2565  def _H : sve_fp_fma_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2566    bits<3> Zm;
2567    bits<3> iop;
2568    let Inst{22} = iop{2};
2569    let Inst{20-19} = iop{1-0};
2570    let Inst{18-16} = Zm;
2571  }
2572  def _S : sve_fp_fma_by_indexed_elem<0b10, opc, asm, ZPR32, ZPR3b32, VectorIndexS32b> {
2573    bits<3> Zm;
2574    bits<2> iop;
2575    let Inst{20-19} = iop;
2576    let Inst{18-16} = Zm;
2577  }
2578  def _D : sve_fp_fma_by_indexed_elem<0b11, opc, asm, ZPR64, ZPR4b64, VectorIndexD32b> {
2579    bits<4> Zm;
2580    bit iop;
2581    let Inst{20} = iop;
2582    let Inst{19-16} = Zm;
2583  }
2584
2585  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 VectorIndexH32b_timm:$idx))),
2586            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, VectorIndexH32b_timm:$idx)>;
2587  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 VectorIndexS32b_timm:$idx))),
2588            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, VectorIndexS32b_timm:$idx)>;
2589  def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, (i32 VectorIndexD32b_timm:$idx))),
2590            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, VectorIndexD32b_timm:$idx)>;
2591}
2592
2593multiclass sve_fp_fma_by_indexed_elem_bfloat<string asm, bits<2> opc,
2594                                             SDPatternOperator op> {
2595  def NAME : sve_fp_fma_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2596    bits<3> Zm;
2597    bits<3> iop;
2598    let Inst{22} = iop{2};
2599    let Inst{20-19} = iop{1-0};
2600    let Inst{18-16} = Zm;
2601  }
2602
2603  def : Pat<(nxv8bf16 (op nxv8bf16:$op1, nxv8bf16:$op2, nxv8bf16:$op3, (i32 VectorIndexH32b_timm:$idx))),
2604            (!cast<Instruction>(NAME) $op1, $op2, $op3, VectorIndexH32b_timm:$idx)>;
2605}
2606
2607//===----------------------------------------------------------------------===//
2608// SVE Floating Point Multiply - Indexed Group
2609//===----------------------------------------------------------------------===//
2610
2611class sve_fp_fmul_by_indexed_elem<bits<2> sz, bit o2, string asm, ZPRRegOp zprty,
2612                                  ZPRRegOp zprty2, Operand itype>
2613: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty2:$Zm, itype:$iop),
2614  asm, "\t$Zd, $Zn, $Zm$iop", "", []>, Sched<[]> {
2615  bits<5> Zd;
2616  bits<5> Zn;
2617  let Inst{31-24} = 0b01100100;
2618  let Inst{23-22} = sz;
2619  let Inst{21}    = 0b1;
2620  let Inst{15-12} = 0b0010;
2621  let Inst{11}    = o2;
2622  let Inst{10}    = 0b0;
2623  let Inst{9-5}   = Zn;
2624  let Inst{4-0}   = Zd;
2625
2626  let hasSideEffects = 0;
2627  let mayRaiseFPException = 1;
2628}
2629
2630multiclass sve_fp_fmul_by_indexed_elem<string asm, SDPatternOperator op> {
2631  def _H : sve_fp_fmul_by_indexed_elem<{0, ?}, 0b0, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2632    bits<3> Zm;
2633    bits<3> iop;
2634    let Inst{22} = iop{2};
2635    let Inst{20-19} = iop{1-0};
2636    let Inst{18-16} = Zm;
2637  }
2638  def _S : sve_fp_fmul_by_indexed_elem<0b10, 0b0, asm, ZPR32, ZPR3b32, VectorIndexS32b> {
2639    bits<3> Zm;
2640    bits<2> iop;
2641    let Inst{20-19} = iop;
2642    let Inst{18-16} = Zm;
2643  }
2644  def _D : sve_fp_fmul_by_indexed_elem<0b11, 0b0, asm, ZPR64, ZPR4b64, VectorIndexD32b> {
2645    bits<4> Zm;
2646    bit iop;
2647    let Inst{20} = iop;
2648    let Inst{19-16} = Zm;
2649  }
2650
2651  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, (i32 VectorIndexH32b_timm:$idx))),
2652            (!cast<Instruction>(NAME # _H) $Op1, $Op2, VectorIndexH32b_timm:$idx)>;
2653  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, (i32 VectorIndexS32b_timm:$idx))),
2654            (!cast<Instruction>(NAME # _S) $Op1, $Op2, VectorIndexS32b_timm:$idx)>;
2655  def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, (i32 VectorIndexD32b_timm:$idx))),
2656            (!cast<Instruction>(NAME # _D) $Op1, $Op2, VectorIndexD32b_timm:$idx)>;
2657}
2658
2659multiclass sve_fp_fmul_by_indexed_elem_bfloat<string asm,
2660                                              SDPatternOperator op> {
2661  def NAME : sve_fp_fmul_by_indexed_elem<{0, ?}, 0b1, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2662    bits<3> Zm;
2663    bits<3> iop;
2664    let Inst{22} = iop{2};
2665    let Inst{20-19} = iop{1-0};
2666    let Inst{18-16} = Zm;
2667  }
2668  def : Pat <(nxv8bf16 (op nxv8bf16:$Op1, nxv8bf16:$Op2, (i32 VectorIndexH32b_timm:$idx))),
2669             (!cast<Instruction>(NAME) $Op1, $Op2, VectorIndexH32b_timm:$idx)>;
2670}
2671
2672//===----------------------------------------------------------------------===//
2673// SVE Floating Point Complex Multiply-Add Group
2674//===----------------------------------------------------------------------===//
2675
2676class sve_fp_fcmla<bits<2> sz, string asm, ZPRRegOp zprty>
2677: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm,
2678                        complexrotateop:$imm),
2679  asm, "\t$Zda, $Pg/m, $Zn, $Zm, $imm",
2680  "", []>, Sched<[]> {
2681  bits<5> Zda;
2682  bits<3> Pg;
2683  bits<5> Zn;
2684  bits<5> Zm;
2685  bits<2> imm;
2686  let Inst{31-24} = 0b01100100;
2687  let Inst{23-22} = sz;
2688  let Inst{21}    = 0;
2689  let Inst{20-16} = Zm;
2690  let Inst{15}    = 0;
2691  let Inst{14-13} = imm;
2692  let Inst{12-10} = Pg;
2693  let Inst{9-5}   = Zn;
2694  let Inst{4-0}   = Zda;
2695
2696  let Constraints = "$Zda = $_Zda";
2697  let DestructiveInstType = DestructiveOther;
2698  let ElementSize = zprty.ElementSize;
2699  let hasSideEffects = 0;
2700  let mayRaiseFPException = 1;
2701}
2702
2703multiclass sve_fp_fcmla<string asm, SDPatternOperator op> {
2704  def _H : sve_fp_fcmla<0b01, asm, ZPR16>;
2705  def _S : sve_fp_fcmla<0b10, asm, ZPR32>;
2706  def _D : sve_fp_fcmla<0b11, asm, ZPR64>;
2707
2708  def : Pat<(nxv8f16 (op nxv8i1:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, nxv8f16:$Op4, (i32 complexrotateop:$imm))),
2709            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2710  def : Pat<(nxv4f32 (op nxv4i1:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, nxv4f32:$Op4, (i32 complexrotateop:$imm))),
2711            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2712  def : Pat<(nxv2f64 (op nxv2i1:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, nxv2f64:$Op4, (i32 complexrotateop:$imm))),
2713            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2714}
2715
2716//===----------------------------------------------------------------------===//
2717// SVE Floating Point Complex Multiply-Add - Indexed Group
2718//===----------------------------------------------------------------------===//
2719
2720class sve_fp_fcmla_by_indexed_elem<bits<2> sz, string asm,
2721                                   ZPRRegOp zprty,
2722                                   ZPRRegOp zprty2, Operand itype>
2723: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, zprty2:$Zm, itype:$iop,
2724                        complexrotateop:$imm),
2725  asm, "\t$Zda, $Zn, $Zm$iop, $imm",
2726  "", []>, Sched<[]> {
2727  bits<5> Zda;
2728  bits<5> Zn;
2729  bits<2> imm;
2730  let Inst{31-24} = 0b01100100;
2731  let Inst{23-22} = sz;
2732  let Inst{21}    = 0b1;
2733  let Inst{15-12} = 0b0001;
2734  let Inst{11-10} = imm;
2735  let Inst{9-5}   = Zn;
2736  let Inst{4-0}   = Zda;
2737
2738  let Constraints = "$Zda = $_Zda";
2739  let DestructiveInstType = DestructiveOther;
2740  let ElementSize = ElementSizeNone;
2741  let hasSideEffects = 0;
2742  let mayRaiseFPException = 1;
2743}
2744
2745multiclass sve_fp_fcmla_by_indexed_elem<string asm, SDPatternOperator op> {
2746  def _H : sve_fp_fcmla_by_indexed_elem<0b10, asm, ZPR16, ZPR3b16, VectorIndexS32b> {
2747    bits<3> Zm;
2748    bits<2> iop;
2749    let Inst{20-19} = iop;
2750    let Inst{18-16} = Zm;
2751  }
2752  def _S : sve_fp_fcmla_by_indexed_elem<0b11, asm, ZPR32, ZPR4b32, VectorIndexD32b> {
2753    bits<4> Zm;
2754    bits<1> iop;
2755    let Inst{20} = iop;
2756    let Inst{19-16} = Zm;
2757  }
2758
2759  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
2760            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
2761  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
2762            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
2763}
2764
2765//===----------------------------------------------------------------------===//
2766// SVE Floating Point Complex Addition Group
2767//===----------------------------------------------------------------------===//
2768
2769class sve_fp_fcadd<bits<2> sz, string asm, ZPRRegOp zprty>
2770: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm,
2771                        complexrotateopodd:$imm),
2772  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm, $imm",
2773  "",
2774  []>, Sched<[]> {
2775  bits<5> Zdn;
2776  bits<5> Zm;
2777  bits<3> Pg;
2778  bit imm;
2779  let Inst{31-24} = 0b01100100;
2780  let Inst{23-22} = sz;
2781  let Inst{21-17} = 0;
2782  let Inst{16}    = imm;
2783  let Inst{15-13} = 0b100;
2784  let Inst{12-10} = Pg;
2785  let Inst{9-5}   = Zm;
2786  let Inst{4-0}   = Zdn;
2787
2788  let Constraints = "$Zdn = $_Zdn";
2789  let DestructiveInstType = DestructiveOther;
2790  let ElementSize = zprty.ElementSize;
2791  let hasSideEffects = 0;
2792  let mayRaiseFPException = 1;
2793}
2794
2795multiclass sve_fp_fcadd<string asm, SDPatternOperator op> {
2796  def _H : sve_fp_fcadd<0b01, asm, ZPR16>;
2797  def _S : sve_fp_fcadd<0b10, asm, ZPR32>;
2798  def _D : sve_fp_fcadd<0b11, asm, ZPR64>;
2799
2800  def : Pat<(nxv8f16 (op nxv8i1:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 complexrotateopodd:$imm))),
2801            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2802  def : Pat<(nxv4f32 (op nxv4i1:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 complexrotateopodd:$imm))),
2803            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2804  def : Pat<(nxv2f64 (op nxv2i1:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, (i32 complexrotateopodd:$imm))),
2805            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2806}
2807
2808//===----------------------------------------------------------------------===//
2809// SVE2 Floating Point Convert Group
2810//===----------------------------------------------------------------------===//
2811
2812class sve2_fp_convert_precision<bits<4> opc, bit merging, string asm,
2813                                ZPRRegOp zprty1, ZPRRegOp zprty2, bit destructive=merging>
2814: I<(outs zprty1:$Zd),
2815  !if(destructive, (ins zprty1:$_Zd, PPR3bAny:$Pg, zprty2:$Zn),
2816                   (ins PPR3bAny:$Pg, zprty2:$Zn)),
2817  asm, "\t$Zd, " # !if(merging, "$Pg/m", "$Pg/z")  # ", $Zn",
2818  "",
2819  []>, Sched<[]> {
2820  bits<5> Zd;
2821  bits<5> Zn;
2822  bits<3> Pg;
2823  let Inst{31-24} = 0b01100100;
2824  let Inst{23-22} = opc{3-2};
2825  let Inst{21-20} = 0b00;
2826  let Inst{19}    = merging;
2827  let Inst{18}    = 0b0;
2828  let Inst{17-16} = opc{1-0};
2829  let Inst{15-13} = 0b101;
2830  let Inst{12-10} = Pg;
2831  let Inst{9-5}   = Zn;
2832  let Inst{4-0}   = Zd;
2833
2834  let Constraints = !if(destructive, "$Zd = $_Zd", "");
2835  let hasSideEffects = 0;
2836  let mayRaiseFPException = 1;
2837}
2838
2839multiclass sve2_fp_convert_down_narrow<string asm, string op> {
2840  def _StoH : sve2_fp_convert_precision<0b1000, 0b1, asm, ZPR16, ZPR32>;
2841  def _DtoS : sve2_fp_convert_precision<0b1110, 0b1, asm, ZPR32, ZPR64>;
2842
2843  def : SVE_3_Op_Pat<nxv8f16, !cast<SDPatternOperator>(op # _f16f32), nxv8f16, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _StoH)>;
2844  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
2845}
2846
2847multiclass sve2_fp_convert_up_long<string asm, string op> {
2848  def _HtoS : sve2_fp_convert_precision<0b1001, 0b1, asm, ZPR32, ZPR16>;
2849  def _StoD : sve2_fp_convert_precision<0b1111, 0b1, asm, ZPR64, ZPR32>;
2850
2851  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f16), nxv4f32, nxv4i1, nxv8f16, !cast<Instruction>(NAME # _HtoS)>;
2852  def : SVE_3_Op_Pat<nxv2f64, !cast<SDPatternOperator>(op # _f64f32), nxv2f64, nxv2i1, nxv4f32, !cast<Instruction>(NAME # _StoD)>;
2853}
2854
2855multiclass sve2_fp_convert_down_odd_rounding_top<string asm, string op> {
2856  def _DtoS : sve2_fp_convert_precision<0b0010, 0b1, asm, ZPR32, ZPR64>;
2857
2858  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
2859}
2860
2861multiclass sve2_fp_convert_up_long_z<string asm, string op> {
2862  def _HtoS : sve2_fp_convert_precision<0b1001, 0b0, asm, ZPR32, ZPR16>;
2863  def _StoD : sve2_fp_convert_precision<0b1111, 0b0, asm, ZPR64, ZPR32>;
2864
2865  defm : SVE_3_Op_UndefZero_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f16), nxv4f32, nxv4i1, nxv8f16, !cast<Instruction>(NAME # _HtoS)>;
2866  defm : SVE_3_Op_UndefZero_Pat<nxv2f64, !cast<SDPatternOperator>(op # _f64f32), nxv2f64, nxv2i1, nxv4f32, !cast<Instruction>(NAME # _StoD)>;
2867}
2868
2869multiclass sve2_fp_convert_down_narrow_z<string asm> {
2870  def _StoH : sve2_fp_convert_precision<0b1000, 0b0, asm,  ZPR16, ZPR32, /*destructive*/ true>;
2871  def _DtoS : sve2_fp_convert_precision<0b1110, 0b0, asm,  ZPR32, ZPR64, /*destructive*/ true>;
2872}
2873
2874//===----------------------------------------------------------------------===//
2875// SVE2 Floating Point Pairwise Group
2876//===----------------------------------------------------------------------===//
2877
2878class sve2_fp_pairwise_pred<bits<2> sz, bits<3> opc, string asm,
2879                            ZPRRegOp zprty>
2880: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
2881  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
2882  "",
2883  []>, Sched<[]> {
2884  bits<3> Pg;
2885  bits<5> Zm;
2886  bits<5> Zdn;
2887  let Inst{31-24} = 0b01100100;
2888  let Inst{23-22} = sz;
2889  let Inst{21-19} = 0b010;
2890  let Inst{18-16} = opc;
2891  let Inst{15-13} = 0b100;
2892  let Inst{12-10} = Pg;
2893  let Inst{9-5}   = Zm;
2894  let Inst{4-0}   = Zdn;
2895
2896  let Constraints = "$Zdn = $_Zdn";
2897  let DestructiveInstType = DestructiveOther;
2898  let ElementSize = zprty.ElementSize;
2899  let hasSideEffects = 0;
2900  let mayRaiseFPException = 1;
2901}
2902
2903multiclass sve2_fp_pairwise_pred<bits<3> opc, string asm,
2904                                 SDPatternOperator op> {
2905  def _H : sve2_fp_pairwise_pred<0b01, opc, asm, ZPR16>;
2906  def _S : sve2_fp_pairwise_pred<0b10, opc, asm, ZPR32>;
2907  def _D : sve2_fp_pairwise_pred<0b11, opc, asm, ZPR64>;
2908
2909  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2910  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2911  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2912}
2913
2914//===----------------------------------------------------------------------===//
2915// SVE2 Floating Point Widening Multiply-Add - Indexed Group
2916//===----------------------------------------------------------------------===//
2917
2918class sve2_fp_mla_long_by_indexed_elem<bits<3> opc, string asm>
2919: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR3b16:$Zm,
2920                        VectorIndexH32b:$iop),
2921  asm, "\t$Zda, $Zn, $Zm$iop",
2922  "",
2923  []>, Sched<[]> {
2924  bits<5> Zda;
2925  bits<5> Zn;
2926  bits<3> Zm;
2927  bits<3> iop;
2928  let Inst{31-23} = 0b011001001;
2929  let Inst{22}    = opc{2};
2930  let Inst{21}    = 0b1;
2931  let Inst{20-19} = iop{2-1};
2932  let Inst{18-16} = Zm;
2933  let Inst{15-14} = 0b01;
2934  let Inst{13}    = opc{1};
2935  let Inst{12}    = 0b0;
2936  let Inst{11}    = iop{0};
2937  let Inst{10}    = opc{0};
2938  let Inst{9-5}   = Zn;
2939  let Inst{4-0}   = Zda;
2940
2941  let Constraints = "$Zda = $_Zda";
2942  let DestructiveInstType = DestructiveOther;
2943  let ElementSize = ElementSizeNone;
2944  let hasSideEffects = 0;
2945  let mayRaiseFPException = 1;
2946}
2947
2948multiclass sve2_fp_mla_long_by_indexed_elem<bits<3> opc, string asm,
2949                                            ValueType OutVT, ValueType InVT,
2950                                            SDPatternOperator op> {
2951  def NAME : sve2_fp_mla_long_by_indexed_elem<opc, asm>;
2952  def : SVE_4_Op_Imm_Pat<OutVT, op, OutVT, InVT, InVT, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME)>;
2953}
2954
2955//===----------------------------------------------------------------------===//
2956// SVE2 Floating Point Widening Multiply-Add Group
2957//===----------------------------------------------------------------------===//
2958
2959class sve2_fp_mla_long<bits<3> opc, string asm>
2960: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
2961  asm, "\t$Zda, $Zn, $Zm",
2962  "",
2963  []>, Sched<[]> {
2964  bits<5> Zda;
2965  bits<5> Zn;
2966  bits<5> Zm;
2967  let Inst{31-23} = 0b011001001;
2968  let Inst{22}    = opc{2};
2969  let Inst{21}    = 0b1;
2970  let Inst{20-16} = Zm;
2971  let Inst{15-14} = 0b10;
2972  let Inst{13}    = opc{1};
2973  let Inst{12-11} = 0b00;
2974  let Inst{10}    = opc{0};
2975  let Inst{9-5}   = Zn;
2976  let Inst{4-0}   = Zda;
2977
2978  let Constraints = "$Zda = $_Zda";
2979  let DestructiveInstType = DestructiveOther;
2980  let ElementSize = ElementSizeNone;
2981  let hasSideEffects = 0;
2982  let mayRaiseFPException = 1;
2983}
2984
2985multiclass sve2_fp_mla_long<bits<3> opc, string asm, ValueType OutVT,
2986                            ValueType InVT, SDPatternOperator op> {
2987  def NAME : sve2_fp_mla_long<opc, asm>;
2988  def : SVE_3_Op_Pat<OutVT, op, OutVT, InVT, InVT, !cast<Instruction>(NAME)>;
2989}
2990
2991//===----------------------------------------------------------------------===//
2992// SVE Stack Allocation Group
2993//===----------------------------------------------------------------------===//
2994
2995class sve_int_arith_vl<bit opc, string asm, bit streaming_sve = 0b0>
2996: I<(outs GPR64sp:$Rd), (ins GPR64sp:$Rn, simm6_32b:$imm6),
2997  asm, "\t$Rd, $Rn, $imm6",
2998  "",
2999  []>, Sched<[]> {
3000  bits<5> Rd;
3001  bits<5> Rn;
3002  bits<6> imm6;
3003  let Inst{31-23} = 0b000001000;
3004  let Inst{22}    = opc;
3005  let Inst{21}    = 0b1;
3006  let Inst{20-16} = Rn;
3007  let Inst{15-12} = 0b0101;
3008  let Inst{11}    = streaming_sve;
3009  let Inst{10-5}  = imm6;
3010  let Inst{4-0}   = Rd;
3011
3012  let hasSideEffects = 0;
3013  let Uses = [VG];
3014}
3015
3016class sve_int_read_vl_a<bit op, bits<5> opc2, string asm, bit streaming_sve = 0b0>
3017: I<(outs GPR64:$Rd), (ins simm6_32b:$imm6),
3018  asm, "\t$Rd, $imm6",
3019  "",
3020  []>, Sched<[]> {
3021  bits<5> Rd;
3022  bits<6> imm6;
3023  let Inst{31-23} = 0b000001001;
3024  let Inst{22}    = op;
3025  let Inst{21}    = 0b1;
3026  let Inst{20-16} = opc2{4-0};
3027  let Inst{15-12} = 0b0101;
3028  let Inst{11}    = streaming_sve;
3029  let Inst{10-5}  = imm6;
3030  let Inst{4-0}   = Rd;
3031
3032  let hasSideEffects = 0;
3033  let isReMaterializable = 1;
3034  let Uses = [VG];
3035}
3036
3037//===----------------------------------------------------------------------===//
3038// SVE Permute - In Lane Group
3039//===----------------------------------------------------------------------===//
3040
3041class sve_int_perm_bin_perm_zz<bits<3> opc, bits<2> sz8_64, string asm,
3042                               ZPRRegOp zprty>
3043: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
3044  asm, "\t$Zd, $Zn, $Zm",
3045  "",
3046  []>, Sched<[]> {
3047  bits<5> Zd;
3048  bits<5> Zm;
3049  bits<5> Zn;
3050  let Inst{31-24} = 0b00000101;
3051  let Inst{23-22} = sz8_64;
3052  let Inst{21}    = 0b1;
3053  let Inst{20-16} = Zm;
3054  let Inst{15-13} = 0b011;
3055  let Inst{12-10} = opc;
3056  let Inst{9-5}   = Zn;
3057  let Inst{4-0}   = Zd;
3058
3059  let hasSideEffects = 0;
3060}
3061
3062multiclass sve_int_perm_bin_perm_zz<bits<3> opc, string asm,
3063                                    SDPatternOperator op> {
3064  def _B : sve_int_perm_bin_perm_zz<opc, 0b00, asm, ZPR8>;
3065  def _H : sve_int_perm_bin_perm_zz<opc, 0b01, asm, ZPR16>;
3066  def _S : sve_int_perm_bin_perm_zz<opc, 0b10, asm, ZPR32>;
3067  def _D : sve_int_perm_bin_perm_zz<opc, 0b11, asm, ZPR64>;
3068
3069  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3070  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3071  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3072  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3073
3074  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
3075  def : SVE_2_Op_Pat<nxv4f16, op, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _S)>;
3076  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
3077  def : SVE_2_Op_Pat<nxv2f16, op, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _D)>;
3078  def : SVE_2_Op_Pat<nxv2f32, op, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _D)>;
3079  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
3080
3081  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
3082}
3083
3084//===----------------------------------------------------------------------===//
3085// SVE Floating Point Unary Operations Group
3086//===----------------------------------------------------------------------===//
3087
3088class sve_fp_2op_p_zd<bits<7> opc, string asm, RegisterOperand i_zprtype,
3089                      RegisterOperand o_zprtype, ElementSizeEnum Sz>
3090: I<(outs o_zprtype:$Zd), (ins i_zprtype:$_Zd, PPR3bAny:$Pg, i_zprtype:$Zn),
3091  asm, "\t$Zd, $Pg/m, $Zn",
3092  "",
3093  []>, Sched<[]> {
3094  bits<3> Pg;
3095  bits<5> Zd;
3096  bits<5> Zn;
3097  let Inst{31-24} = 0b01100101;
3098  let Inst{23-22} = opc{6-5};
3099  let Inst{21}    = 0b0;
3100  let Inst{20-16} = opc{4-0};
3101  let Inst{15-13} = 0b101;
3102  let Inst{12-10} = Pg;
3103  let Inst{9-5}   = Zn;
3104  let Inst{4-0}   = Zd;
3105
3106  let Constraints = "$Zd = $_Zd";
3107  let DestructiveInstType = DestructiveUnaryPassthru;
3108  let ElementSize = Sz;
3109  let hasSideEffects = 0;
3110  let mayRaiseFPException = 1;
3111}
3112
3113multiclass sve_fp_2op_p_zd<bits<7> opc, string asm,
3114                           RegisterOperand i_zprtype,
3115                           RegisterOperand o_zprtype,
3116                           SDPatternOperator int_op,
3117                           SDPatternOperator ir_op, ValueType vt1,
3118                           ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
3119  def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>,
3120             SVEPseudo2Instr<NAME, 1>;
3121  // convert vt1 to a packed type for the intrinsic patterns
3122  defvar packedvt1 = SVEType<vt1>.Packed;
3123
3124  // convert vt3 to a packed type for the intrinsic patterns
3125  defvar packedvt3 = SVEType<vt3>.Packed;
3126
3127  def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, packedvt3, !cast<Instruction>(NAME)>;
3128  def : SVE_1_Op_Passthru_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
3129
3130  def _UNDEF : PredOneOpPassthruPseudo<NAME, !cast<ZPRRegOp>(i_zprtype)>;
3131
3132  defm : SVE_1_Op_PassthruUndef_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME # _UNDEF)>;
3133}
3134
3135multiclass sve_fp_2op_p_zdr<bits<7> opc, string asm,
3136                            RegisterOperand i_zprtype,
3137                            RegisterOperand o_zprtype,
3138                            SDPatternOperator int_op,
3139                            SDPatternOperator ir_op, ValueType vt1,
3140                            ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
3141  def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>,
3142             SVEPseudo2Instr<NAME, 1>;
3143
3144  // convert vt1 to a packed type for the intrinsic patterns
3145  defvar packedvt1 = SVEType<vt1>.Packed;
3146
3147  def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, vt3, !cast<Instruction>(NAME)>;
3148  def : SVE_1_Op_Passthru_Round_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
3149
3150  def _UNDEF : PredOneOpPassthruPseudo<NAME, !cast<ZPRRegOp>(i_zprtype)>;
3151
3152  defm : SVE_1_Op_PassthruUndef_Round_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME # _UNDEF)>;
3153}
3154
3155multiclass sve_fp_2op_p_zd_HSD<bits<5> opc, string asm, SDPatternOperator op> {
3156  def _H : sve_fp_2op_p_zd<{ 0b01, opc }, asm, ZPR16, ZPR16, ElementSizeH>,
3157           SVEPseudo2Instr<NAME # _H, 1>;
3158  def _S : sve_fp_2op_p_zd<{ 0b10, opc }, asm, ZPR32, ZPR32, ElementSizeS>,
3159           SVEPseudo2Instr<NAME # _S, 1>;
3160  def _D : sve_fp_2op_p_zd<{ 0b11, opc }, asm, ZPR64, ZPR64, ElementSizeD>,
3161           SVEPseudo2Instr<NAME # _D, 1>;
3162
3163  def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
3164  def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
3165  def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
3166  def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
3167  def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
3168  def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
3169
3170  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
3171  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
3172  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
3173
3174  defm : SVE_1_Op_PassthruUndef_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H_UNDEF)>;
3175  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H_UNDEF)>;
3176  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H_UNDEF)>;
3177  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S_UNDEF)>;
3178  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S_UNDEF)>;
3179  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D_UNDEF)>;
3180}
3181
3182multiclass sve2_fp_flogb<string asm, string Ps, SDPatternOperator op> {
3183  def _H : sve_fp_2op_p_zd<0b0011010, asm, ZPR16, ZPR16, ElementSizeH>,
3184             SVEPseudo2Instr<Ps # _H, 1>;
3185  def _S : sve_fp_2op_p_zd<0b0011100, asm, ZPR32, ZPR32, ElementSizeS>,
3186             SVEPseudo2Instr<Ps # _S, 1>;
3187  def _D : sve_fp_2op_p_zd<0b0011110, asm, ZPR64, ZPR64, ElementSizeD>,
3188             SVEPseudo2Instr<Ps # _D, 1>;
3189
3190  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
3191  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
3192  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
3193}
3194
3195multiclass sve2_fp_un_pred_zeroing_hsd<SDPatternOperator op> {
3196  def _H_ZERO : PredOneOpPassthruPseudo<NAME # _H, ZPR16, FalseLanesZero>;
3197  def _S_ZERO : PredOneOpPassthruPseudo<NAME # _S, ZPR32, FalseLanesZero>;
3198  def _D_ZERO : PredOneOpPassthruPseudo<NAME # _D, ZPR64, FalseLanesZero>;
3199
3200  def : SVE_1_Op_PassthruZero_Pat<nxv8i16, op, nxv8i1, nxv8f16, !cast<Pseudo>(NAME # _H_ZERO)>;
3201  def : SVE_1_Op_PassthruZero_Pat<nxv4i32, op, nxv4i1, nxv4f32, !cast<Pseudo>(NAME # _S_ZERO)>;
3202  def : SVE_1_Op_PassthruZero_Pat<nxv2i64, op, nxv2i1, nxv2f64, !cast<Pseudo>(NAME # _D_ZERO)>;
3203}
3204
3205multiclass sve2_fp_convert_down_odd_rounding<string asm, string op, SDPatternOperator ir_op = null_frag> {
3206  def _DtoS : sve_fp_2op_p_zd<0b0001010, asm, ZPR64, ZPR32, ElementSizeD>;
3207
3208  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
3209  def : SVE_1_Op_Passthru_Pat<nxv2f32, ir_op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
3210}
3211
3212multiclass sve_fp_2op_p_zd_frint<bits<2> opc, string asm> {
3213  def _S : sve_fp_2op_p_zd<{ 0b0010, opc{1}, 0, opc{0} }, asm, ZPR32, ZPR32, ElementSizeS>;
3214  def _D : sve_fp_2op_p_zd<{ 0b0010, opc{1}, 1, opc{0} }, asm, ZPR64, ZPR64, ElementSizeD>;
3215}
3216
3217//===----------------------------------------------------------------------===//
3218// SVE Floating Point Unary Operations - Unpredicated Group
3219//===----------------------------------------------------------------------===//
3220
3221class sve_fp_2op_u_zd<bits<2> sz, bits<3> opc, string asm,
3222                      ZPRRegOp zprty>
3223: I<(outs zprty:$Zd), (ins zprty:$Zn),
3224  asm, "\t$Zd, $Zn",
3225  "",
3226  []>, Sched<[]> {
3227  bits<5> Zd;
3228  bits<5> Zn;
3229  let Inst{31-24} = 0b01100101;
3230  let Inst{23-22} = sz;
3231  let Inst{21-19} = 0b001;
3232  let Inst{18-16} = opc;
3233  let Inst{15-10} = 0b001100;
3234  let Inst{9-5}   = Zn;
3235  let Inst{4-0}   = Zd;
3236
3237  let hasSideEffects = 0;
3238  let mayRaiseFPException = 1;
3239}
3240
3241multiclass sve_fp_2op_u_zd<bits<3> opc, string asm, SDPatternOperator op> {
3242  def _H : sve_fp_2op_u_zd<0b01, opc, asm, ZPR16>;
3243  def _S : sve_fp_2op_u_zd<0b10, opc, asm, ZPR32>;
3244  def _D : sve_fp_2op_u_zd<0b11, opc, asm, ZPR64>;
3245
3246  def : SVE_1_Op_Pat<nxv8f16, op, nxv8f16, !cast<Instruction>(NAME # _H)>;
3247  def : SVE_1_Op_Pat<nxv4f32, op, nxv4f32, !cast<Instruction>(NAME # _S)>;
3248  def : SVE_1_Op_Pat<nxv2f64, op, nxv2f64, !cast<Instruction>(NAME # _D)>;
3249}
3250
3251//===----------------------------------------------------------------------===//
3252// SVE Floating Point Unary Operations - Zeroing Predicate Group
3253//===----------------------------------------------------------------------===//
3254
3255class sve_fp_z2op_p_zd<bits<7> opc,string asm, RegisterOperand i_zprtype,
3256                       RegisterOperand o_zprtype>
3257: I<(outs o_zprtype:$Zd), (ins PPR3bAny:$Pg, i_zprtype:$Zn),
3258  asm, "\t$Zd, $Pg/z, $Zn",
3259  "",
3260  []>, Sched<[]> {
3261  bits<3> Pg;
3262  bits<5> Zd;
3263  bits<5> Zn;
3264  let Inst{31-24} = 0b01100100;
3265  let Inst{23-22} = opc{6-5};
3266  let Inst{21-19} = 0b011;
3267  let Inst{18-16} = opc{4-2};
3268  let Inst{15}    = 0b1;
3269  let Inst{14-13} = opc{1-0};
3270  let Inst{12-10} = Pg;
3271  let Inst{9-5}   = Zn;
3272  let Inst{4-0}   = Zd;
3273
3274  let hasSideEffects = 0;
3275  let mayRaiseFPException = 1;
3276}
3277
3278multiclass sve_fp_z2op_p_zd<string asm, SDPatternOperator op> {
3279  def _DtoS : sve_fp_z2op_p_zd<0b0001010, asm, ZPR64, ZPR32>;
3280
3281  defm : SVE_3_Op_UndefZero_Pat<nxv4f32, op, nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
3282}
3283
3284multiclass sve_fp_z2op_p_zd_hsd<bits<5> opc, string asm, SDPatternOperator op> {
3285  def _H : sve_fp_z2op_p_zd<{ 0b01, opc }, asm, ZPR16, ZPR16>;
3286  def _S : sve_fp_z2op_p_zd<{ 0b10, opc }, asm, ZPR32, ZPR32>;
3287  def _D : sve_fp_z2op_p_zd<{ 0b11, opc }, asm, ZPR64, ZPR64>;
3288
3289  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
3290  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
3291  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
3292  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
3293  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
3294  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
3295}
3296
3297multiclass sve_fp_z2op_p_zd_frint<bits<2> opc, string asm> {
3298  def _S : sve_fp_z2op_p_zd<{ 0b0010, opc{1}, 0, opc{0} }, asm, ZPR32, ZPR32>;
3299  def _D : sve_fp_z2op_p_zd<{ 0b0010, opc{1}, 1, opc{0} }, asm, ZPR64, ZPR64>;
3300}
3301
3302multiclass sve_fp_z2op_p_zd_bfcvt<string asm, SDPatternOperator op> {
3303  def NAME : sve_fp_z2op_p_zd<0b1001010, asm, ZPR32, ZPR16>;
3304
3305  defm : SVE_3_Op_UndefZero_Pat<nxv8bf16, op, nxv8bf16, nxv4i1, nxv4f32, !cast<Instruction>(NAME)>;
3306}
3307
3308multiclass sve_fp_z2op_p_zd_d<bit U, string asm, string int_op, SDPatternOperator ir_op> {
3309  def _HtoH : sve_fp_z2op_p_zd<{ 0b011101, U }, asm, ZPR16, ZPR16>;
3310  def _HtoS : sve_fp_z2op_p_zd<{ 0b011110, U }, asm, ZPR16, ZPR32>;
3311  def _HtoD : sve_fp_z2op_p_zd<{ 0b011111, U }, asm, ZPR16, ZPR64>;
3312  def _StoS : sve_fp_z2op_p_zd<{ 0b101110, U }, asm, ZPR32, ZPR32>;
3313  def _StoD : sve_fp_z2op_p_zd<{ 0b111110, U }, asm, ZPR32, ZPR64>;
3314  def _DtoS : sve_fp_z2op_p_zd<{ 0b111100, U }, asm, ZPR64, ZPR32>;
3315  def _DtoD : sve_fp_z2op_p_zd<{ 0b111111, U }, asm, ZPR64, ZPR64>;
3316
3317  defm : SVE_3_Op_UndefZero_Pat<nxv4i32, !cast<SDPatternOperator>(int_op # _i32f64), nxv4i32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
3318  defm : SVE_3_Op_UndefZero_Pat<nxv2i64, !cast<SDPatternOperator>(int_op # _i64f32), nxv2i64, nxv2i1, nxv4f32, !cast<Instruction>(NAME # _StoD)>;
3319  defm : SVE_3_Op_UndefZero_Pat<nxv4i32, !cast<SDPatternOperator>(int_op # _i32f16), nxv4i32, nxv4i1, nxv8f16, !cast<Instruction>(NAME # _HtoS)>;
3320  defm : SVE_3_Op_UndefZero_Pat<nxv2i64, !cast<SDPatternOperator>(int_op # _i64f16), nxv2i64, nxv2i1, nxv8f16, !cast<Instruction>(NAME # _HtoD)>;
3321
3322  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv8i16, ir_op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _HtoH)>;
3323  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv4i32, ir_op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _StoS)>;
3324  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2i64, ir_op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoD)>;
3325}
3326
3327multiclass sve_fp_z2op_p_zd_c<bit U, string asm, string int_op, SDPatternOperator ir_op> {
3328  def _HtoH : sve_fp_z2op_p_zd<{ 0b011001, U }, asm, ZPR16, ZPR16>;
3329  def _StoH : sve_fp_z2op_p_zd<{ 0b011010, U }, asm, ZPR32, ZPR16>;
3330  def _StoS : sve_fp_z2op_p_zd<{ 0b101010, U }, asm, ZPR32, ZPR32>;
3331  def _StoD : sve_fp_z2op_p_zd<{ 0b111000, U }, asm, ZPR32, ZPR64>;
3332  def _DtoS : sve_fp_z2op_p_zd<{ 0b111010, U }, asm, ZPR64, ZPR32>;
3333  def _DtoH : sve_fp_z2op_p_zd<{ 0b011011, U }, asm, ZPR64, ZPR16>;
3334  def _DtoD : sve_fp_z2op_p_zd<{ 0b111011, U }, asm, ZPR64, ZPR64>;
3335
3336  defm : SVE_3_Op_UndefZero_Pat<nxv4f32, !cast<SDPatternOperator>(int_op # _f32i64), nxv4f32, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _DtoS)>;
3337  defm : SVE_3_Op_UndefZero_Pat<nxv2f64, !cast<SDPatternOperator>(int_op # _f64i32), nxv2f64, nxv2i1, nxv4i32, !cast<Instruction>(NAME # _StoD)>;
3338  defm : SVE_3_Op_UndefZero_Pat<nxv8f16, !cast<SDPatternOperator>(int_op # _f16i32), nxv8f16, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _StoH)>;
3339  defm : SVE_3_Op_UndefZero_Pat<nxv8f16, !cast<SDPatternOperator>(int_op # _f16i64), nxv8f16, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _DtoH)>;
3340
3341  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv8f16, ir_op, nxv8i1,nxv8i16, !cast<Instruction>(NAME # _HtoH)>;
3342  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv4f32, ir_op, nxv4i1,nxv4i32, !cast<Instruction>(NAME # _StoS)>;
3343  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2f64, ir_op, nxv2i1,nxv2i64, !cast<Instruction>(NAME # _DtoD)>;
3344}
3345
3346multiclass sve_fp_z2op_p_zd_d_flogb<string asm, SDPatternOperator op> {
3347  def _H : sve_fp_z2op_p_zd<0b0011001, asm, ZPR16, ZPR16>;
3348  def _S : sve_fp_z2op_p_zd<0b0011010, asm, ZPR32, ZPR32>;
3349  def _D : sve_fp_z2op_p_zd<0b0011011, asm, ZPR64, ZPR64>;
3350
3351  defm : SVE_3_Op_UndefZero_Pat<nxv8i16, op, nxv8i16, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
3352  defm : SVE_3_Op_UndefZero_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
3353  defm : SVE_3_Op_UndefZero_Pat<nxv2i64, op, nxv2i64, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
3354}
3355
3356multiclass sve_fp_z2op_p_zd_b_0<string asm, string op> {
3357  def _StoH : sve_fp_z2op_p_zd<0b1001000, asm, ZPR32, ZPR16>;
3358  def _HtoS : sve_fp_z2op_p_zd<0b1001001, asm, ZPR16, ZPR32>;
3359  def _DtoH : sve_fp_z2op_p_zd<0b1101000, asm, ZPR64, ZPR16>;
3360  def _HtoD : sve_fp_z2op_p_zd<0b1101001, asm, ZPR16, ZPR64>;
3361  def _DtoS : sve_fp_z2op_p_zd<0b1101010, asm, ZPR64, ZPR32>;
3362  def _StoD : sve_fp_z2op_p_zd<0b1101011, asm, ZPR32, ZPR64>;
3363
3364  defm : SVE_3_Op_UndefZero_Pat<nxv8f16, !cast<SDPatternOperator>(op # _f16f32), nxv8f16, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _StoH)>;
3365  defm : SVE_3_Op_UndefZero_Pat<nxv8f16, !cast<SDPatternOperator>(op # _f16f64), nxv8f16, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoH)>;
3366  defm : SVE_3_Op_UndefZero_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
3367  defm : SVE_3_Op_UndefZero_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f16), nxv4f32, nxv4i1, nxv8f16, !cast<Instruction>(NAME # _HtoS)>;
3368  defm : SVE_3_Op_UndefZero_Pat<nxv2f64, !cast<SDPatternOperator>(op # _f64f16), nxv2f64, nxv2i1, nxv8f16, !cast<Instruction>(NAME # _HtoD)>;
3369  defm : SVE_3_Op_UndefZero_Pat<nxv2f64, !cast<SDPatternOperator>(op # _f64f32), nxv2f64, nxv2i1, nxv4f32, !cast<Instruction>(NAME # _StoD)>;
3370}
3371
3372//===----------------------------------------------------------------------===//
3373// SVE Integer Arithmetic - Binary Predicated Group
3374//===----------------------------------------------------------------------===//
3375
3376class sve_int_bin_pred_arit_log<bits<2> sz8_64, bits<2> fmt, bits<3> opc,
3377                                string asm, ZPRRegOp zprty>
3378: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
3379  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm", "", []>, Sched<[]> {
3380  bits<3> Pg;
3381  bits<5> Zdn;
3382  bits<5> Zm;
3383  let Inst{31-24} = 0b00000100;
3384  let Inst{23-22} = sz8_64;
3385  let Inst{21}    = 0b0;
3386  let Inst{20-19} = fmt;
3387  let Inst{18-16} = opc;
3388  let Inst{15-13} = 0b000;
3389  let Inst{12-10} = Pg;
3390  let Inst{9-5}   = Zm;
3391  let Inst{4-0}   = Zdn;
3392
3393  let Constraints = "$Zdn = $_Zdn";
3394  let DestructiveInstType = DestructiveOther;
3395  let ElementSize = zprty.ElementSize;
3396  let hasSideEffects = 0;
3397}
3398
3399multiclass sve_int_bin_pred_log<bits<3> opc, string asm, string Ps,
3400                                SDPatternOperator op,
3401                                DestructiveInstTypeEnum flags> {
3402  let DestructiveInstType = flags in {
3403  def _B : sve_int_bin_pred_arit_log<0b00, 0b11, opc, asm, ZPR8>,
3404             SVEPseudo2Instr<Ps # _B, 1>;
3405  def _H : sve_int_bin_pred_arit_log<0b01, 0b11, opc, asm, ZPR16>,
3406             SVEPseudo2Instr<Ps # _H, 1>;
3407  def _S : sve_int_bin_pred_arit_log<0b10, 0b11, opc, asm, ZPR32>,
3408             SVEPseudo2Instr<Ps # _S, 1>;
3409  def _D : sve_int_bin_pred_arit_log<0b11, 0b11, opc, asm, ZPR64>,
3410             SVEPseudo2Instr<Ps # _D, 1>;
3411  }
3412
3413  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3414  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3415  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3416  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3417}
3418
3419multiclass sve_int_bin_pred_arit_0<bits<3> opc, string asm, string Ps,
3420                                   SDPatternOperator op,
3421                                   DestructiveInstTypeEnum flags,
3422                                   string revname="", bit isReverseInstr=0> {
3423  let DestructiveInstType = flags in {
3424  def _B : sve_int_bin_pred_arit_log<0b00, 0b00, opc, asm, ZPR8>,
3425           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3426  def _H : sve_int_bin_pred_arit_log<0b01, 0b00, opc, asm, ZPR16>,
3427           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3428  def _S : sve_int_bin_pred_arit_log<0b10, 0b00, opc, asm, ZPR32>,
3429           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3430  def _D : sve_int_bin_pred_arit_log<0b11, 0b00, opc, asm, ZPR64>,
3431           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3432  }
3433
3434  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3435  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3436  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3437  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3438}
3439
3440multiclass sve_int_bin_pred_arit_1<bits<3> opc, string asm, string Ps,
3441                                   SDPatternOperator op,
3442                                   DestructiveInstTypeEnum flags> {
3443  let DestructiveInstType = flags in {
3444  def _B : sve_int_bin_pred_arit_log<0b00, 0b01, opc, asm, ZPR8>,
3445           SVEPseudo2Instr<Ps # _B, 1>;
3446  def _H : sve_int_bin_pred_arit_log<0b01, 0b01, opc, asm, ZPR16>,
3447           SVEPseudo2Instr<Ps # _H, 1>;
3448  def _S : sve_int_bin_pred_arit_log<0b10, 0b01, opc, asm, ZPR32>,
3449           SVEPseudo2Instr<Ps # _S, 1>;
3450  def _D : sve_int_bin_pred_arit_log<0b11, 0b01, opc, asm, ZPR64>,
3451           SVEPseudo2Instr<Ps # _D, 1>;
3452  }
3453
3454  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3455  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3456  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3457  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3458}
3459
3460multiclass sve_int_bin_pred_arit_2<bits<3> opc, string asm, string Ps,
3461                                   SDPatternOperator op,
3462                                   DestructiveInstTypeEnum flags> {
3463  let DestructiveInstType = flags in {
3464  def _B : sve_int_bin_pred_arit_log<0b00, 0b10, opc, asm, ZPR8>,
3465           SVEPseudo2Instr<Ps # _B, 1>;
3466  def _H : sve_int_bin_pred_arit_log<0b01, 0b10, opc, asm, ZPR16>,
3467           SVEPseudo2Instr<Ps # _H, 1>;
3468  def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>,
3469           SVEPseudo2Instr<Ps # _S, 1>;
3470  def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>,
3471           SVEPseudo2Instr<Ps # _D, 1>;
3472  }
3473
3474  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3475  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3476  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3477  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3478}
3479
3480// Special case for divides which are not defined for 8b/16b elements.
3481multiclass sve_int_bin_pred_arit_2_div<bits<3> opc, string asm, string Ps,
3482                                       SDPatternOperator op,
3483                                       DestructiveInstTypeEnum flags,
3484                                       string revname="", bit isReverseInstr=0> {
3485  let DestructiveInstType = flags in {
3486  def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>,
3487           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3488  def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>,
3489           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3490  }
3491
3492  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3493  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3494}
3495
3496//===----------------------------------------------------------------------===//
3497// SVE Integer Multiply-Add Group
3498//===----------------------------------------------------------------------===//
3499
3500class sve_int_mladdsub_vvv_pred<bits<2> sz8_64, bits<1> opc, string asm,
3501                                ZPRRegOp zprty>
3502: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm, zprty:$Za),
3503  asm, "\t$Zdn, $Pg/m, $Zm, $Za",
3504  "",
3505  []>, Sched<[]> {
3506  bits<3> Pg;
3507  bits<5> Zdn;
3508  bits<5> Za;
3509  bits<5> Zm;
3510  let Inst{31-24} = 0b00000100;
3511  let Inst{23-22} = sz8_64;
3512  let Inst{21}    = 0b0;
3513  let Inst{20-16} = Zm;
3514  let Inst{15-14} = 0b11;
3515  let Inst{13}    = opc;
3516  let Inst{12-10} = Pg;
3517  let Inst{9-5}   = Za;
3518  let Inst{4-0}   = Zdn;
3519
3520  let Constraints = "$Zdn = $_Zdn";
3521  let DestructiveInstType = DestructiveOther;
3522  let ElementSize = zprty.ElementSize;
3523  let hasSideEffects = 0;
3524}
3525
3526multiclass sve_int_mladdsub_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
3527                                     string revname, bit isReverseInstr=0> {
3528  def _B : sve_int_mladdsub_vvv_pred<0b00, opc, asm, ZPR8>,
3529           SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3530  def _H : sve_int_mladdsub_vvv_pred<0b01, opc, asm, ZPR16>,
3531           SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3532  def _S : sve_int_mladdsub_vvv_pred<0b10, opc, asm, ZPR32>,
3533           SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3534  def _D : sve_int_mladdsub_vvv_pred<0b11, opc, asm, ZPR64>,
3535           SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3536
3537  def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3538  def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3539  def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3540  def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3541}
3542
3543class sve_int_mlas_vvv_pred<bits<2> sz8_64, bits<1> opc, string asm,
3544                            ZPRRegOp zprty>
3545: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm),
3546  asm, "\t$Zda, $Pg/m, $Zn, $Zm",
3547  "",
3548  []>, Sched<[]> {
3549  bits<3> Pg;
3550  bits<5> Zda;
3551  bits<5> Zm;
3552  bits<5> Zn;
3553  let Inst{31-24} = 0b00000100;
3554  let Inst{23-22} = sz8_64;
3555  let Inst{21}    = 0b0;
3556  let Inst{20-16} = Zm;
3557  let Inst{15-14} = 0b01;
3558  let Inst{13}    = opc;
3559  let Inst{12-10} = Pg;
3560  let Inst{9-5}   = Zn;
3561  let Inst{4-0}   = Zda;
3562
3563  let Constraints = "$Zda = $_Zda";
3564  let DestructiveInstType = DestructiveTernaryCommWithRev;
3565  let ElementSize = zprty.ElementSize;
3566  let hasSideEffects = 0;
3567}
3568
3569multiclass sve_int_mlas_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
3570                                 string Ps, string revname, bit isReverseInstr=0> {
3571  def _B : sve_int_mlas_vvv_pred<0b00, opc, asm, ZPR8>,
3572           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3573  def _H : sve_int_mlas_vvv_pred<0b01, opc, asm, ZPR16>,
3574           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3575  def _S : sve_int_mlas_vvv_pred<0b10, opc, asm, ZPR32>,
3576           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3577  def _D : sve_int_mlas_vvv_pred<0b11, opc, asm, ZPR64>,
3578           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3579
3580  def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3581  def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3582  def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3583  def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3584}
3585
3586//class for generating pseudo for SVE MLA/MAD/MLS/MSB
3587multiclass sve_int_3op_p_mladdsub<SDPatternOperator op> {
3588  def _B_UNDEF : PredThreeOpPseudo<NAME # _B, ZPR8,  FalseLanesUndef>;
3589  def _H_UNDEF : PredThreeOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
3590  def _S_UNDEF : PredThreeOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
3591  def _D_UNDEF : PredThreeOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
3592
3593  let  AddedComplexity = 9 in {
3594    def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B_UNDEF)>;
3595    def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H_UNDEF)>;
3596    def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S_UNDEF)>;
3597    def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D_UNDEF)>;
3598  }
3599}
3600
3601//===----------------------------------------------------------------------===//
3602// SVE2 Integer Multiply-Add - Unpredicated Group
3603//===----------------------------------------------------------------------===//
3604
3605class sve2_int_mla<bits<2> sz, bits<5> opc, string asm,
3606                   ZPRRegOp zprty1, ZPRRegOp zprty2>
3607: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm),
3608  asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
3609  bits<5> Zda;
3610  bits<5> Zn;
3611  bits<5> Zm;
3612  let Inst{31-24} = 0b01000100;
3613  let Inst{23-22} = sz;
3614  let Inst{21}    = 0b0;
3615  let Inst{20-16} = Zm;
3616  let Inst{15}    = 0b0;
3617  let Inst{14-10} = opc;
3618  let Inst{9-5}   = Zn;
3619  let Inst{4-0}   = Zda;
3620
3621  let Constraints = "$Zda = $_Zda";
3622  let DestructiveInstType = DestructiveOther;
3623  let ElementSize = ElementSizeNone;
3624  let hasSideEffects = 0;
3625}
3626
3627multiclass sve2_int_mla<bit S, string asm, SDPatternOperator op> {
3628  def _B : sve2_int_mla<0b00, { 0b1110, S }, asm, ZPR8, ZPR8>;
3629  def _H : sve2_int_mla<0b01, { 0b1110, S }, asm, ZPR16, ZPR16>;
3630  def _S : sve2_int_mla<0b10, { 0b1110, S }, asm, ZPR32, ZPR32>;
3631  def _D : sve2_int_mla<0b11, { 0b1110, S }, asm, ZPR64, ZPR64>;
3632
3633  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3634  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3635  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3636  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3637}
3638
3639multiclass sve2_int_mla_long<bits<5> opc, string asm, SDPatternOperator op> {
3640  def _H : sve2_int_mla<0b01, opc, asm, ZPR16, ZPR8>;
3641  def _S : sve2_int_mla<0b10, opc, asm, ZPR32, ZPR16>;
3642  def _D : sve2_int_mla<0b11, opc, asm, ZPR64, ZPR32>;
3643
3644  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3645  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
3646  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3647}
3648
3649//===----------------------------------------------------------------------===//
3650// SVE2 Integer Multiply-Add - Indexed Group
3651//===----------------------------------------------------------------------===//
3652
3653class sve2_int_mla_by_indexed_elem<bits<2> sz, bits<6> opc, string asm,
3654                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3655                                   ZPRRegOp zprty3, Operand itype>
3656: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop),
3657  asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
3658  bits<5> Zda;
3659  bits<5> Zn;
3660  let Inst{31-24} = 0b01000100;
3661  let Inst{23-22} = sz;
3662  let Inst{21}    = 0b1;
3663  let Inst{15-10} = opc;
3664  let Inst{9-5}   = Zn;
3665  let Inst{4-0}   = Zda;
3666
3667  let Constraints = "$Zda = $_Zda";
3668  let DestructiveInstType = DestructiveOther;
3669  let ElementSize = ElementSizeNone;
3670  let hasSideEffects = 0;
3671}
3672
3673multiclass sve2_int_mla_by_indexed_elem<bits<2> opc, bit S, string asm,
3674                                        SDPatternOperator op> {
3675  def _H : sve2_int_mla_by_indexed_elem<{0, ?}, { 0b000, opc, S }, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexH32b> {
3676    bits<3> Zm;
3677    bits<3> iop;
3678    let Inst{22} = iop{2};
3679    let Inst{20-19} = iop{1-0};
3680    let Inst{18-16} = Zm;
3681  }
3682  def _S : sve2_int_mla_by_indexed_elem<0b10, { 0b000, opc, S }, asm, ZPR32, ZPR32, ZPR3b32, VectorIndexS32b> {
3683    bits<3> Zm;
3684    bits<2> iop;
3685    let Inst{20-19} = iop;
3686    let Inst{18-16} = Zm;
3687  }
3688  def _D : sve2_int_mla_by_indexed_elem<0b11, { 0b000, opc, S }, asm, ZPR64, ZPR64, ZPR4b64, VectorIndexD32b> {
3689    bits<4> Zm;
3690    bit iop;
3691    let Inst{20} = iop;
3692    let Inst{19-16} = Zm;
3693  }
3694
3695  def : SVE_4_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
3696  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3697  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3698}
3699
3700//===----------------------------------------------------------------------===//
3701// SVE2 Integer Multiply-Add Long - Indexed Group
3702//===----------------------------------------------------------------------===//
3703
3704multiclass sve2_int_mla_long_by_indexed_elem<bits<4> opc, string asm,
3705                                             SDPatternOperator op> {
3706  def _S : sve2_int_mla_by_indexed_elem<0b10, { opc{3}, 0b0, opc{2-1}, ?, opc{0} },
3707                                        asm, ZPR32, ZPR16, ZPR3b16, VectorIndexH32b> {
3708    bits<3> Zm;
3709    bits<3> iop;
3710    let Inst{20-19} = iop{2-1};
3711    let Inst{18-16} = Zm;
3712    let Inst{11} = iop{0};
3713  }
3714  def _D : sve2_int_mla_by_indexed_elem<0b11, { opc{3}, 0b0, opc{2-1}, ?, opc{0} },
3715                                        asm, ZPR64, ZPR32, ZPR4b32, VectorIndexS32b> {
3716    bits<4> Zm;
3717    bits<2> iop;
3718    let Inst{20} = iop{1};
3719    let Inst{19-16} = Zm;
3720    let Inst{11} = iop{0};
3721  }
3722
3723  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _S)>;
3724  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
3725}
3726
3727//===----------------------------------------------------------------------===//
3728// SVE Integer Dot Product Group
3729//===----------------------------------------------------------------------===//
3730
3731class sve_intx_dot<bit sz, bit U, string asm, ZPRRegOp zprty1,
3732                   ZPRRegOp zprty2>
3733: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm), asm,
3734  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
3735  bits<5> Zda;
3736  bits<5> Zn;
3737  bits<5> Zm;
3738  let Inst{31-23} = 0b010001001;
3739  let Inst{22}    = sz;
3740  let Inst{21}    = 0;
3741  let Inst{20-16} = Zm;
3742  let Inst{15-11} = 0;
3743  let Inst{10}    = U;
3744  let Inst{9-5}   = Zn;
3745  let Inst{4-0}   = Zda;
3746
3747  let Constraints = "$Zda = $_Zda";
3748  let DestructiveInstType = DestructiveOther;
3749  let hasSideEffects = 0;
3750}
3751
3752multiclass sve_intx_dot<bit opc, string asm, SDPatternOperator op> {
3753  def _S : sve_intx_dot<0b0, opc, asm, ZPR32, ZPR8>;
3754  def _D : sve_intx_dot<0b1, opc, asm, ZPR64, ZPR16>;
3755
3756  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32,  nxv16i8, nxv16i8, !cast<Instruction>(NAME # _S)>;
3757  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _D)>;
3758}
3759
3760//===----------------------------------------------------------------------===//
3761// SVE Integer Dot Product Group - Indexed Group
3762//===----------------------------------------------------------------------===//
3763
3764class sve_intx_dot_by_indexed_elem<bit sz, bit U, string asm,
3765                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3766                                   ZPRRegOp zprty3, Operand itype>
3767: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop),
3768  asm, "\t$Zda, $Zn, $Zm$iop",
3769  "", []>, Sched<[]> {
3770  bits<5> Zda;
3771  bits<5> Zn;
3772  let Inst{31-23} = 0b010001001;
3773  let Inst{22}    = sz;
3774  let Inst{21}    = 0b1;
3775  let Inst{15-11} = 0;
3776  let Inst{10}    = U;
3777  let Inst{9-5}   = Zn;
3778  let Inst{4-0}   = Zda;
3779
3780  let Constraints = "$Zda = $_Zda";
3781  let DestructiveInstType = DestructiveOther;
3782  let hasSideEffects = 0;
3783}
3784
3785multiclass sve_intx_dot_by_indexed_elem<bit opc, string asm,
3786                                        SDPatternOperator op> {
3787  def _S : sve_intx_dot_by_indexed_elem<0b0, opc, asm, ZPR32, ZPR8, ZPR3b8, VectorIndexS32b_timm> {
3788    bits<2> iop;
3789    bits<3> Zm;
3790    let Inst{20-19} = iop;
3791    let Inst{18-16} = Zm;
3792  }
3793  def _D : sve_intx_dot_by_indexed_elem<0b1, opc, asm, ZPR64, ZPR16, ZPR4b16, VectorIndexD32b_timm> {
3794    bits<1> iop;
3795    bits<4> Zm;
3796    let Inst{20} = iop;
3797    let Inst{19-16} = Zm;
3798  }
3799
3800  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv16i8, nxv16i8, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3801  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv8i16, nxv8i16, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3802}
3803
3804//===----------------------------------------------------------------------===//
3805// SVE2 Complex Integer Dot Product Group
3806//===----------------------------------------------------------------------===//
3807
3808class sve2_complex_int_arith<bits<2> sz, bits<4> opc, string asm,
3809                             ZPRRegOp zprty1, ZPRRegOp zprty2>
3810: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm,
3811                         complexrotateop:$rot),
3812  asm, "\t$Zda, $Zn, $Zm, $rot", "", []>, Sched<[]> {
3813  bits<5> Zda;
3814  bits<5> Zn;
3815  bits<5> Zm;
3816  bits<2> rot;
3817  let Inst{31-24} = 0b01000100;
3818  let Inst{23-22} = sz;
3819  let Inst{21}    = 0b0;
3820  let Inst{20-16} = Zm;
3821  let Inst{15-12} = opc;
3822  let Inst{11-10} = rot;
3823  let Inst{9-5}   = Zn;
3824  let Inst{4-0}   = Zda;
3825
3826  let Constraints = "$Zda = $_Zda";
3827  let DestructiveInstType = DestructiveOther;
3828  let ElementSize = ElementSizeNone;
3829  let hasSideEffects = 0;
3830}
3831
3832multiclass sve2_cintx_dot<string asm, SDPatternOperator op> {
3833  def _S : sve2_complex_int_arith<0b10, 0b0001, asm, ZPR32, ZPR8>;
3834  def _D : sve2_complex_int_arith<0b11, 0b0001, asm, ZPR64, ZPR16>;
3835
3836  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv16i8 ZPR8:$Op2), (nxv16i8 ZPR8:$Op3),
3837                         (i32 complexrotateop:$imm))),
3838            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR8:$Op2, ZPR8:$Op3, complexrotateop:$imm)>;
3839  def : Pat<(nxv2i64 (op (nxv2i64 ZPR64:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3840                         (i32 complexrotateop:$imm))),
3841            (!cast<Instruction>(NAME # "_D") ZPR64:$Op1, ZPR16:$Op2, ZPR16:$Op3, complexrotateop:$imm)>;
3842}
3843
3844//===----------------------------------------------------------------------===//
3845// SVE2 Complex Multiply-Add Group
3846//===----------------------------------------------------------------------===//
3847
3848multiclass sve2_int_cmla<bit opc, string asm, SDPatternOperator op> {
3849  def _B : sve2_complex_int_arith<0b00, { 0b001, opc }, asm, ZPR8, ZPR8>;
3850  def _H : sve2_complex_int_arith<0b01, { 0b001, opc }, asm, ZPR16, ZPR16>;
3851  def _S : sve2_complex_int_arith<0b10, { 0b001, opc }, asm, ZPR32, ZPR32>;
3852  def _D : sve2_complex_int_arith<0b11, { 0b001, opc }, asm, ZPR64, ZPR64>;
3853
3854  def : SVE_4_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, i32, complexrotateop, !cast<Instruction>(NAME # _B)>;
3855  def : SVE_4_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, i32, complexrotateop, !cast<Instruction>(NAME # _H)>;
3856  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, i32, complexrotateop, !cast<Instruction>(NAME # _S)>;
3857  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, i32, complexrotateop, !cast<Instruction>(NAME # _D)>;
3858}
3859
3860//===----------------------------------------------------------------------===//
3861// SVE2 Complex Integer Dot Product - Indexed Group
3862//===----------------------------------------------------------------------===//
3863
3864class sve2_complex_int_arith_indexed<bits<2> sz, bits<4> opc, string asm,
3865                                     ZPRRegOp zprty1, ZPRRegOp zprty2,
3866                                     ZPRRegOp zprty3, Operand itype>
3867: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop,
3868                         complexrotateop:$rot),
3869  asm, "\t$Zda, $Zn, $Zm$iop, $rot", "", []>, Sched<[]> {
3870  bits<5> Zda;
3871  bits<5> Zn;
3872  bits<2> rot;
3873  let Inst{31-24} = 0b01000100;
3874  let Inst{23-22} = sz;
3875  let Inst{21}    = 0b1;
3876  let Inst{15-12} = opc;
3877  let Inst{11-10} = rot;
3878  let Inst{9-5}   = Zn;
3879  let Inst{4-0}   = Zda;
3880
3881  let Constraints = "$Zda = $_Zda";
3882  let DestructiveInstType = DestructiveOther;
3883  let ElementSize = ElementSizeNone;
3884  let hasSideEffects = 0;
3885}
3886
3887multiclass sve2_cintx_dot_by_indexed_elem<string asm, SDPatternOperator op> {
3888  def _S : sve2_complex_int_arith_indexed<0b10, 0b0100, asm, ZPR32, ZPR8, ZPR3b8, VectorIndexS32b> {
3889    bits<2> iop;
3890    bits<3> Zm;
3891    let Inst{20-19} = iop;
3892    let Inst{18-16} = Zm;
3893  }
3894  def _D : sve2_complex_int_arith_indexed<0b11, 0b0100, asm, ZPR64, ZPR16, ZPR4b16, VectorIndexD32b> {
3895    bit iop;
3896    bits<4> Zm;
3897    let Inst{20} = iop;
3898    let Inst{19-16} = Zm;
3899  }
3900
3901  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv16i8 ZPR8:$Op2), (nxv16i8 ZPR8:$Op3),
3902                         (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
3903            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR8:$Op2, ZPR8:$Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
3904  def : Pat<(nxv2i64 (op (nxv2i64 ZPR64:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3905                         (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
3906            (!cast<Instruction>(NAME # "_D") ZPR64:$Op1, ZPR16:$Op2, ZPR16:$Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
3907}
3908
3909//===----------------------------------------------------------------------===//
3910// SVE2 Complex Multiply-Add - Indexed Group
3911//===----------------------------------------------------------------------===//
3912
3913multiclass sve2_cmla_by_indexed_elem<bit opc, string asm,
3914                                     SDPatternOperator op> {
3915  def _H : sve2_complex_int_arith_indexed<0b10, { 0b011, opc }, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexS32b> {
3916    bits<2> iop;
3917    bits<3> Zm;
3918    let Inst{20-19} = iop;
3919    let Inst{18-16} = Zm;
3920  }
3921  def _S : sve2_complex_int_arith_indexed<0b11, { 0b011, opc }, asm, ZPR32, ZPR32, ZPR4b32, VectorIndexD32b> {
3922    bit iop;
3923    bits<4> Zm;
3924    let Inst{20} = iop;
3925    let Inst{19-16} = Zm;
3926  }
3927
3928  def : Pat<(nxv8i16 (op (nxv8i16 ZPR16:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3929                         (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
3930            (!cast<Instruction>(NAME # "_H") ZPR16:$Op1, ZPR16:$Op2, ZPR16:$Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
3931
3932  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv4i32 ZPR32:$Op2), (nxv4i32 ZPR32:$Op3),
3933                         (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
3934            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR32:$Op2, ZPR32:$Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
3935}
3936
3937//===----------------------------------------------------------------------===//
3938// SVE2 Integer Multiply - Unpredicated Group
3939//===----------------------------------------------------------------------===//
3940
3941class sve2_int_mul<bits<2> sz, bits<3> opc, string asm, ZPRRegOp zprty>
3942: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
3943  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3944  bits<5> Zd;
3945  bits<5> Zm;
3946  bits<5> Zn;
3947  let Inst{31-24} = 0b00000100;
3948  let Inst{23-22} = sz;
3949  let Inst{21}    = 0b1;
3950  let Inst{20-16} = Zm;
3951  let Inst{15-13} = 0b011;
3952  let Inst{12-10} = opc;
3953  let Inst{9-5}   = Zn;
3954  let Inst{4-0}   = Zd;
3955
3956  let hasSideEffects = 0;
3957}
3958
3959multiclass sve2_int_mul<bits<3> opc, string asm, SDPatternOperator op> {
3960  def _B : sve2_int_mul<0b00, opc, asm, ZPR8>;
3961  def _H : sve2_int_mul<0b01, opc, asm, ZPR16>;
3962  def _S : sve2_int_mul<0b10, opc, asm, ZPR32>;
3963  def _D : sve2_int_mul<0b11, opc, asm, ZPR64>;
3964
3965  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3966  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3967  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3968  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3969}
3970
3971multiclass sve2_int_mul_single<bits<3> opc, string asm, SDPatternOperator op> {
3972  def _B : sve2_int_mul<0b00, opc, asm, ZPR8>;
3973
3974  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3975}
3976
3977//===----------------------------------------------------------------------===//
3978// SVE2 Integer Multiply - Indexed Group
3979//===----------------------------------------------------------------------===//
3980
3981class sve2_int_mul_by_indexed_elem<bits<2> sz, bits<4> opc, string asm,
3982                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3983                                   ZPRRegOp zprty3, Operand itype>
3984: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty3:$Zm, itype:$iop),
3985  asm, "\t$Zd, $Zn, $Zm$iop", "", []>, Sched<[]> {
3986  bits<5> Zd;
3987  bits<5> Zn;
3988  let Inst{31-24} = 0b01000100;
3989  let Inst{23-22} = sz;
3990  let Inst{21}    = 0b1;
3991  let Inst{15-14} = 0b11;
3992  let Inst{13-10} = opc;
3993  let Inst{9-5}   = Zn;
3994  let Inst{4-0}   = Zd;
3995
3996  let hasSideEffects = 0;
3997}
3998
3999multiclass sve2_int_mul_by_indexed_elem<bits<4> opc, string asm,
4000                                        SDPatternOperator op> {
4001  def _H : sve2_int_mul_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexH32b> {
4002    bits<3> Zm;
4003    bits<3> iop;
4004    let Inst{22} = iop{2};
4005    let Inst{20-19} = iop{1-0};
4006    let Inst{18-16} = Zm;
4007  }
4008  def _S : sve2_int_mul_by_indexed_elem<0b10, opc, asm, ZPR32, ZPR32, ZPR3b32, VectorIndexS32b> {
4009    bits<3> Zm;
4010    bits<2> iop;
4011    let Inst{20-19} = iop;
4012    let Inst{18-16} = Zm;
4013  }
4014  def _D : sve2_int_mul_by_indexed_elem<0b11, opc, asm, ZPR64, ZPR64, ZPR4b64, VectorIndexD32b> {
4015    bits<4> Zm;
4016    bit iop;
4017    let Inst{20} = iop;
4018    let Inst{19-16} = Zm;
4019  }
4020
4021  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
4022  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
4023  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
4024}
4025
4026multiclass sve2_int_mul_long_by_indexed_elem<bits<3> opc, string asm,
4027                                             SDPatternOperator op> {
4028  def _S : sve2_int_mul_by_indexed_elem<0b10, { opc{2-1}, ?, opc{0} }, asm,
4029                                        ZPR32, ZPR16, ZPR3b16, VectorIndexH32b> {
4030    bits<3> Zm;
4031    bits<3> iop;
4032    let Inst{20-19} = iop{2-1};
4033    let Inst{18-16} = Zm;
4034    let Inst{11} = iop{0};
4035  }
4036  def _D : sve2_int_mul_by_indexed_elem<0b11, { opc{2-1}, ?, opc{0} }, asm,
4037                                        ZPR64, ZPR32, ZPR4b32, VectorIndexS32b> {
4038    bits<4> Zm;
4039    bits<2> iop;
4040    let Inst{20} = iop{1};
4041    let Inst{19-16} = Zm;
4042    let Inst{11} = iop{0};
4043  }
4044
4045  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _S)>;
4046  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
4047}
4048
4049//===----------------------------------------------------------------------===//
4050// SVE2 Integer - Predicated Group
4051//===----------------------------------------------------------------------===//
4052
4053class sve2_int_arith_pred<bits<2> sz, bits<6> opc, string asm,
4054                          ZPRRegOp zprty>
4055: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
4056  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm", "", []>, Sched<[]> {
4057  bits<3> Pg;
4058  bits<5> Zm;
4059  bits<5> Zdn;
4060  let Inst{31-24} = 0b01000100;
4061  let Inst{23-22} = sz;
4062  let Inst{21-20} = 0b01;
4063  let Inst{20-16} = opc{5-1};
4064  let Inst{15-14} = 0b10;
4065  let Inst{13}    = opc{0};
4066  let Inst{12-10} = Pg;
4067  let Inst{9-5}   = Zm;
4068  let Inst{4-0}   = Zdn;
4069
4070  let Constraints = "$Zdn = $_Zdn";
4071  let DestructiveInstType = DestructiveOther;
4072  let ElementSize = zprty.ElementSize;
4073  let hasSideEffects = 0;
4074}
4075
4076multiclass sve2_int_arith_pred<bits<6> opc, string asm, SDPatternOperator op,
4077                               string Ps = "",
4078                               DestructiveInstTypeEnum flags=DestructiveOther,
4079                               string revname="", bit isReverseInstr=0> {
4080  let DestructiveInstType = flags in {
4081  def _B : sve2_int_arith_pred<0b00, opc, asm, ZPR8>,
4082           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
4083  def _H : sve2_int_arith_pred<0b01, opc, asm, ZPR16>,
4084           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
4085  def _S : sve2_int_arith_pred<0b10, opc, asm, ZPR32>,
4086           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
4087  def _D : sve2_int_arith_pred<0b11, opc, asm, ZPR64>,
4088           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
4089  }
4090
4091  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4092  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4093  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4094  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4095}
4096
4097class sve2_int_sadd_long_accum_pairwise<bits<2> sz, bit U, string asm,
4098                                        ZPRRegOp zprty1, ZPRRegOp zprty2>
4099: I<(outs zprty1:$Zda), (ins PPR3bAny:$Pg, zprty1:$_Zda, zprty2:$Zn),
4100  asm, "\t$Zda, $Pg/m, $Zn", "", []>, Sched<[]> {
4101  bits<3> Pg;
4102  bits<5> Zn;
4103  bits<5> Zda;
4104  let Inst{31-24} = 0b01000100;
4105  let Inst{23-22} = sz;
4106  let Inst{21-17} = 0b00010;
4107  let Inst{16}    = U;
4108  let Inst{15-13} = 0b101;
4109  let Inst{12-10} = Pg;
4110  let Inst{9-5}   = Zn;
4111  let Inst{4-0}   = Zda;
4112
4113  let Constraints = "$Zda = $_Zda";
4114  let DestructiveInstType = DestructiveOther;
4115  let ElementSize = zprty1.ElementSize;
4116  let hasSideEffects = 0;
4117}
4118
4119multiclass sve2_int_sadd_long_accum_pairwise<bit U, string asm, SDPatternOperator op> {
4120  def _H : sve2_int_sadd_long_accum_pairwise<0b01, U, asm, ZPR16, ZPR8>;
4121  def _S : sve2_int_sadd_long_accum_pairwise<0b10, U, asm, ZPR32, ZPR16>;
4122  def _D : sve2_int_sadd_long_accum_pairwise<0b11, U, asm, ZPR64, ZPR32>;
4123
4124  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv16i8, !cast<Instruction>(NAME # _H)>;
4125  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv8i16, !cast<Instruction>(NAME # _S)>;
4126  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv4i32, !cast<Instruction>(NAME # _D)>;
4127}
4128
4129class sve2_int_un_pred_arit<bits<2> sz, bits<2> opc,
4130                            string asm, ZPRRegOp zprty>
4131: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
4132  asm, "\t$Zd, $Pg/m, $Zn",
4133  "",
4134  []>, Sched<[]> {
4135  bits<3> Pg;
4136  bits<5> Zd;
4137  bits<5> Zn;
4138  let Inst{31-24} = 0b01000100;
4139  let Inst{23-22} = sz;
4140  let Inst{21-20} = 0b00;
4141  let Inst{19}    = opc{1};
4142  let Inst{18-17} = 0b00;
4143  let Inst{16}    = opc{0};
4144  let Inst{15-13} = 0b101;
4145  let Inst{12-10} = Pg;
4146  let Inst{9-5}   = Zn;
4147  let Inst{4-0}   = Zd;
4148  let Constraints = "$Zd = $_Zd";
4149  let DestructiveInstType = DestructiveUnaryPassthru;
4150  let ElementSize = zprty.ElementSize;
4151  let hasSideEffects = 0;
4152}
4153
4154class sve2_int_un_pred_arit_z<bits<2> sz, bits<2> opc,
4155                              string asm, ZPRRegOp zprty>
4156: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
4157  asm, "\t$Zd, $Pg/z, $Zn",
4158  "",
4159  []>, Sched<[]> {
4160  bits<3> Pg;
4161  bits<5> Zd;
4162  bits<5> Zn;
4163  let Inst{31-24} = 0b01000100;
4164  let Inst{23-22} = sz;
4165  let Inst{21-20} = 0b00;
4166  let Inst{19}    = opc{1};
4167  let Inst{18-17} = 0b01;
4168  let Inst{16}    = opc{0};
4169  let Inst{15-13} = 0b101;
4170  let Inst{12-10} = Pg;
4171  let Inst{9-5}   = Zn;
4172  let Inst{4-0}   = Zd;
4173  let hasSideEffects = 0;
4174}
4175
4176multiclass sve2_int_un_pred_arit_s<bits<2> opc, string asm,
4177                                   SDPatternOperator op> {
4178  def _S : sve2_int_un_pred_arit<0b10, opc, asm, ZPR32>,
4179           SVEPseudo2Instr<NAME # _S, 1>;
4180
4181  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
4182
4183  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4184
4185  defm : SVE_3_Op_Undef_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4186}
4187
4188multiclass sve2_int_un_pred_arit<bits<2> opc, string asm, SDPatternOperator op> {
4189  def _B : sve2_int_un_pred_arit<0b00, opc, asm, ZPR8>,
4190           SVEPseudo2Instr<NAME # _B, 1>;
4191  def _H : sve2_int_un_pred_arit<0b01, opc, asm, ZPR16>,
4192           SVEPseudo2Instr<NAME # _H, 1>;
4193  def _S : sve2_int_un_pred_arit<0b10, opc, asm, ZPR32>,
4194           SVEPseudo2Instr<NAME # _S, 1>;
4195  def _D : sve2_int_un_pred_arit<0b11, opc, asm, ZPR64>,
4196           SVEPseudo2Instr<NAME # _D, 1>;
4197
4198  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
4199  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
4200  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
4201  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
4202
4203  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
4204  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4205  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4206  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4207
4208  defm : SVE_3_Op_Undef_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
4209  defm : SVE_3_Op_Undef_Pat<nxv8i16, op, nxv8i16, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4210  defm : SVE_3_Op_Undef_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4211  defm : SVE_3_Op_Undef_Pat<nxv2i64, op, nxv2i64, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4212}
4213
4214multiclass sve2_int_un_pred_arit_z_S<bits<2> opc, string asm, SDPatternOperator op> {
4215  def _S : sve2_int_un_pred_arit_z<0b10, opc, asm, ZPR32>;
4216
4217  defm : SVE_3_Op_UndefZero_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
4218}
4219
4220multiclass sve2_int_un_pred_arit_z<bits<2> opc, string asm, SDPatternOperator op> {
4221  def _B : sve2_int_un_pred_arit_z<0b00, opc, asm, ZPR8>;
4222  def _H : sve2_int_un_pred_arit_z<0b01, opc, asm, ZPR16>;
4223  def _S : sve2_int_un_pred_arit_z<0b10, opc, asm, ZPR32>;
4224  def _D : sve2_int_un_pred_arit_z<0b11, opc, asm, ZPR64>;
4225
4226  defm : SVE_3_Op_UndefZero_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
4227  defm : SVE_3_Op_UndefZero_Pat<nxv8i16, op, nxv8i16, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
4228  defm : SVE_3_Op_UndefZero_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
4229  defm : SVE_3_Op_UndefZero_Pat<nxv2i64, op, nxv2i64, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
4230}
4231
4232//===----------------------------------------------------------------------===//
4233// SVE2 Widening Integer Arithmetic Group
4234//===----------------------------------------------------------------------===//
4235
4236class sve2_wide_int_arith<bits<2> sz, bits<5> opc, string asm,
4237                          ZPRRegOp zprty1, ZPRRegOp zprty2, ZPRRegOp zprty3>
4238: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty3:$Zm),
4239  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4240  bits<5> Zd;
4241  bits<5> Zn;
4242  bits<5> Zm;
4243  let Inst{31-24} = 0b01000101;
4244  let Inst{23-22} = sz;
4245  let Inst{21}    = 0b0;
4246  let Inst{20-16} = Zm;
4247  let Inst{15}    = 0b0;
4248  let Inst{14-10} = opc;
4249  let Inst{9-5}   = Zn;
4250  let Inst{4-0}   = Zd;
4251
4252  let hasSideEffects = 0;
4253}
4254
4255multiclass sve2_wide_int_arith_long<bits<5> opc, string asm,
4256                                    SDPatternOperator op> {
4257  def _H : sve2_wide_int_arith<0b01, opc, asm, ZPR16, ZPR8, ZPR8>;
4258  def _S : sve2_wide_int_arith<0b10, opc, asm, ZPR32, ZPR16, ZPR16>;
4259  def _D : sve2_wide_int_arith<0b11, opc, asm, ZPR64, ZPR32, ZPR32>;
4260
4261  def : SVE_2_Op_Pat<nxv8i16, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
4262  def : SVE_2_Op_Pat<nxv4i32, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
4263  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
4264}
4265
4266multiclass sve2_wide_int_arith_wide<bits<3> opc, string asm,
4267                                    SDPatternOperator op> {
4268  def _H : sve2_wide_int_arith<0b01, { 0b10, opc }, asm, ZPR16, ZPR16, ZPR8>;
4269  def _S : sve2_wide_int_arith<0b10, { 0b10, opc }, asm, ZPR32, ZPR32, ZPR16>;
4270  def _D : sve2_wide_int_arith<0b11, { 0b10, opc }, asm, ZPR64, ZPR64, ZPR32>;
4271
4272  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, !cast<Instruction>(NAME # _H)>;
4273  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, !cast<Instruction>(NAME # _S)>;
4274  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, !cast<Instruction>(NAME # _D)>;
4275}
4276
4277multiclass sve2_wide_int_arith_pmul<bits<2> sz, bits<5> opc, string asm,
4278                                     SDPatternOperator op> {
4279  def NAME : sve2_wide_int_arith<sz, opc, asm, ZPR128, ZPR64, ZPR64>;
4280
4281  // To avoid using 128 bit elements in the IR, the pattern below works with
4282  // llvm intrinsics with the _pair suffix, to reflect that
4283  // _Q is implemented as a pair of _D.
4284  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4285}
4286
4287multiclass sve2_pmul_long<bits<1> opc, string asm, SDPatternOperator op> {
4288  def _H : sve2_wide_int_arith<0b01, {0b1101, opc}, asm, ZPR16, ZPR8, ZPR8>;
4289  def _D : sve2_wide_int_arith<0b11, {0b1101, opc}, asm, ZPR64, ZPR32, ZPR32>;
4290
4291  // To avoid using 128 bit elements in the IR, the patterns below work with
4292  // llvm intrinsics with the _pair suffix, to reflect that
4293  // _H is implemented as a pair of _B and _D is implemented as a pair of _S.
4294  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
4295  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
4296}
4297
4298//===----------------------------------------------------------------------===//
4299// SVE2 Misc Group
4300//===----------------------------------------------------------------------===//
4301
4302class sve2_misc<bits<2> sz, bits<4> opc, string asm,
4303                ZPRRegOp zprty1, ZPRRegOp zprty2>
4304: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty2:$Zm),
4305  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4306  bits<5> Zd;
4307  bits<5> Zn;
4308  bits<5> Zm;
4309  let Inst{31-24} = 0b01000101;
4310  let Inst{23-22} = sz;
4311  let Inst{21}    = 0b0;
4312  let Inst{20-16} = Zm;
4313  let Inst{15-14} = 0b10;
4314  let Inst{13-10} = opc;
4315  let Inst{9-5}   = Zn;
4316  let Inst{4-0}   = Zd;
4317
4318  let hasSideEffects = 0;
4319}
4320
4321multiclass sve2_misc_bitwise<bits<4> opc, string asm, SDPatternOperator op> {
4322  def _B : sve2_misc<0b00, opc, asm, ZPR8, ZPR8>;
4323  def _H : sve2_misc<0b01, opc, asm, ZPR16, ZPR16>;
4324  def _S : sve2_misc<0b10, opc, asm, ZPR32, ZPR32>;
4325  def _D : sve2_misc<0b11, opc, asm, ZPR64, ZPR64>;
4326
4327  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4328  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4329  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4330  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4331}
4332
4333multiclass sve2_misc_int_addsub_long_interleaved<bits<2> opc, string asm,
4334                                                 SDPatternOperator op> {
4335  def _H : sve2_misc<0b01, { 0b00, opc }, asm, ZPR16, ZPR8>;
4336  def _S : sve2_misc<0b10, { 0b00, opc }, asm, ZPR32, ZPR16>;
4337  def _D : sve2_misc<0b11, { 0b00, opc }, asm, ZPR64, ZPR32>;
4338
4339  def : SVE_2_Op_Pat<nxv8i16, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
4340  def : SVE_2_Op_Pat<nxv4i32, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
4341  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
4342}
4343
4344class sve2_bitwise_xor_interleaved<bits<2> sz, bits<1> opc, string asm,
4345                                   ZPRRegOp zprty1, ZPRRegOp zprty2>
4346: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, zprty2:$Zm),
4347  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4348  bits<5> Zd;
4349  bits<5> Zn;
4350  bits<5> Zm;
4351  let Inst{31-24} = 0b01000101;
4352  let Inst{23-22} = sz;
4353  let Inst{21}    = 0b0;
4354  let Inst{20-16} = Zm;
4355  let Inst{15-11} = 0b10010;
4356  let Inst{10}    = opc;
4357  let Inst{9-5}   = Zn;
4358  let Inst{4-0}   = Zd;
4359
4360  let Constraints = "$Zd = $_Zd";
4361  let DestructiveInstType = DestructiveOther;
4362  let ElementSize = ElementSizeNone;
4363  let hasSideEffects = 0;
4364}
4365
4366multiclass sve2_bitwise_xor_interleaved<bit opc, string asm,
4367                                        SDPatternOperator op> {
4368  def _B : sve2_bitwise_xor_interleaved<0b00, opc, asm, ZPR8,  ZPR8>;
4369  def _H : sve2_bitwise_xor_interleaved<0b01, opc, asm, ZPR16, ZPR16>;
4370  def _S : sve2_bitwise_xor_interleaved<0b10, opc, asm, ZPR32, ZPR32>;
4371  def _D : sve2_bitwise_xor_interleaved<0b11, opc, asm, ZPR64, ZPR64>;
4372
4373  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4374  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4375  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4376  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4377}
4378
4379class sve2_bitwise_shift_left_long<bits<3> tsz8_64, bits<2> opc, string asm,
4380                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
4381                                   Operand immtype>
4382: I<(outs zprty1:$Zd), (ins zprty2:$Zn, immtype:$imm),
4383  asm, "\t$Zd, $Zn, $imm",
4384  "", []>, Sched<[]> {
4385  bits<5> Zd;
4386  bits<5> Zn;
4387  bits<5> imm;
4388  let Inst{31-23} = 0b010001010;
4389  let Inst{22}    = tsz8_64{2};
4390  let Inst{21}    = 0b0;
4391  let Inst{20-19} = tsz8_64{1-0};
4392  let Inst{18-16} = imm{2-0}; // imm3
4393  let Inst{15-12} = 0b1010;
4394  let Inst{11-10} = opc;
4395  let Inst{9-5}   = Zn;
4396  let Inst{4-0}   = Zd;
4397
4398  let hasSideEffects = 0;
4399}
4400
4401multiclass sve2_bitwise_shift_left_long<bits<2> opc, string asm,
4402                                        SDPatternOperator op> {
4403  def _H : sve2_bitwise_shift_left_long<{0,0,1}, opc, asm,
4404                                        ZPR16, ZPR8, vecshiftL8>;
4405  def _S : sve2_bitwise_shift_left_long<{0,1,?}, opc, asm,
4406                                        ZPR32, ZPR16, vecshiftL16> {
4407    let Inst{19} = imm{3};
4408  }
4409  def _D : sve2_bitwise_shift_left_long<{1,?,?}, opc, asm,
4410                                        ZPR64, ZPR32, vecshiftL32> {
4411    let Inst{20-19} = imm{4-3};
4412  }
4413  def : SVE_2_Op_Imm_Pat<nxv8i16, op, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _H)>;
4414  def : SVE_2_Op_Imm_Pat<nxv4i32, op, nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _S)>;
4415  def : SVE_2_Op_Imm_Pat<nxv2i64, op, nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _D)>;
4416}
4417
4418//===----------------------------------------------------------------------===//
4419// SVE2 Accumulate Group
4420//===----------------------------------------------------------------------===//
4421
4422class sve2_int_bin_shift_imm<bits<4> tsz8_64, bit opc, string asm,
4423                             ZPRRegOp zprty, Operand immtype>
4424: I<(outs zprty:$Zd), (ins zprty:$_Zd, zprty:$Zn, immtype:$imm),
4425  asm, "\t$Zd, $Zn, $imm",
4426  "", []>, Sched<[]> {
4427  bits<5> Zd;
4428  bits<5> Zn;
4429  bits<6> imm;
4430  let Inst{31-24} = 0b01000101;
4431  let Inst{23-22} = tsz8_64{3-2};
4432  let Inst{21}    = 0b0;
4433  let Inst{20-19} = tsz8_64{1-0};
4434  let Inst{18-16} = imm{2-0}; // imm3
4435  let Inst{15-11} = 0b11110;
4436  let Inst{10}    = opc;
4437  let Inst{9-5}   = Zn;
4438  let Inst{4-0}   = Zd;
4439
4440  let Constraints = "$Zd = $_Zd";
4441  let hasSideEffects = 0;
4442}
4443
4444multiclass sve2_int_bin_shift_imm_left<bit opc, string asm,
4445                                       SDPatternOperator op> {
4446  def _B : sve2_int_bin_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
4447  def _H : sve2_int_bin_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
4448    let Inst{19} = imm{3};
4449  }
4450  def _S : sve2_int_bin_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
4451    let Inst{20-19} = imm{4-3};
4452  }
4453  def _D : sve2_int_bin_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
4454    let Inst{22}    = imm{5};
4455    let Inst{20-19} = imm{4-3};
4456  }
4457
4458  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _B)>;
4459  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _H)>;
4460  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _S)>;
4461  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftL64, !cast<Instruction>(NAME # _D)>;
4462}
4463
4464multiclass sve2_int_bin_shift_imm_right<bit opc, string asm,
4465                                        SDPatternOperator op> {
4466  def _B : sve2_int_bin_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
4467  def _H : sve2_int_bin_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
4468    let Inst{19} = imm{3};
4469  }
4470  def _S : sve2_int_bin_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
4471    let Inst{20-19} = imm{4-3};
4472  }
4473  def _D : sve2_int_bin_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
4474    let Inst{22}    = imm{5};
4475    let Inst{20-19} = imm{4-3};
4476  }
4477
4478  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4479  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4480  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4481  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4482}
4483
4484class sve2_int_bin_accum_shift_imm<bits<4> tsz8_64, bits<2> opc, string asm,
4485                                   ZPRRegOp zprty, Operand immtype>
4486: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, immtype:$imm),
4487  asm, "\t$Zda, $Zn, $imm",
4488  "", []>, Sched<[]> {
4489  bits<5> Zda;
4490  bits<5> Zn;
4491  bits<6> imm;
4492  let Inst{31-24} = 0b01000101;
4493  let Inst{23-22} = tsz8_64{3-2};
4494  let Inst{21}    = 0b0;
4495  let Inst{20-19} = tsz8_64{1-0};
4496  let Inst{18-16} = imm{2-0}; // imm3
4497  let Inst{15-12} = 0b1110;
4498  let Inst{11-10} = opc;
4499  let Inst{9-5}   = Zn;
4500  let Inst{4-0}   = Zda;
4501
4502  let Constraints = "$Zda = $_Zda";
4503  let DestructiveInstType = DestructiveOther;
4504  let ElementSize = ElementSizeNone;
4505  let hasSideEffects = 0;
4506}
4507
4508multiclass sve2_int_bin_accum_shift_imm_right<bits<2> opc, string asm,
4509                                              SDPatternOperator op,
4510                                              SDPatternOperator shift_op = null_frag> {
4511  def _B : sve2_int_bin_accum_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
4512  def _H : sve2_int_bin_accum_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
4513    let Inst{19} = imm{3};
4514  }
4515  def _S : sve2_int_bin_accum_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
4516    let Inst{20-19} = imm{4-3};
4517  }
4518  def _D : sve2_int_bin_accum_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
4519    let Inst{22}    = imm{5};
4520    let Inst{20-19} = imm{4-3};
4521  }
4522
4523  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4524  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4525  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4526  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4527
4528  def : SVE_Shift_Add_All_Active_Pat<nxv16i8, shift_op, nxv16i1, nxv16i8, nxv16i8, i32, !cast<Instruction>(NAME # _B)>;
4529  def : SVE_Shift_Add_All_Active_Pat<nxv8i16, shift_op, nxv8i1, nxv8i16, nxv8i16, i32, !cast<Instruction>(NAME # _H)>;
4530  def : SVE_Shift_Add_All_Active_Pat<nxv4i32, shift_op, nxv4i1, nxv4i32, nxv4i32, i32, !cast<Instruction>(NAME # _S)>;
4531  def : SVE_Shift_Add_All_Active_Pat<nxv2i64, shift_op, nxv2i1, nxv2i64, nxv2i64, i32, !cast<Instruction>(NAME # _D)>;
4532}
4533
4534class sve2_int_cadd<bits<2> sz, bit opc, string asm, ZPRRegOp zprty>
4535: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, complexrotateopodd:$rot),
4536  asm, "\t$Zdn, $_Zdn, $Zm, $rot", "", []>, Sched<[]> {
4537  bits<5> Zdn;
4538  bits<5> Zm;
4539  bit rot;
4540  let Inst{31-24} = 0b01000101;
4541  let Inst{23-22} = sz;
4542  let Inst{21-17} = 0b00000;
4543  let Inst{16}    = opc;
4544  let Inst{15-11} = 0b11011;
4545  let Inst{10}    = rot;
4546  let Inst{9-5}   = Zm;
4547  let Inst{4-0}   = Zdn;
4548
4549  let Constraints = "$Zdn = $_Zdn";
4550  let DestructiveInstType = DestructiveOther;
4551  let ElementSize = ElementSizeNone;
4552  let hasSideEffects = 0;
4553}
4554
4555multiclass sve2_int_cadd<bit opc, string asm, SDPatternOperator op> {
4556  def _B : sve2_int_cadd<0b00, opc, asm, ZPR8>;
4557  def _H : sve2_int_cadd<0b01, opc, asm, ZPR16>;
4558  def _S : sve2_int_cadd<0b10, opc, asm, ZPR32>;
4559  def _D : sve2_int_cadd<0b11, opc, asm, ZPR64>;
4560
4561  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, complexrotateopodd, !cast<Instruction>(NAME # _B)>;
4562  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, complexrotateopodd, !cast<Instruction>(NAME # _H)>;
4563  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, complexrotateopodd, !cast<Instruction>(NAME # _S)>;
4564  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, complexrotateopodd, !cast<Instruction>(NAME # _D)>;
4565}
4566
4567class sve2_int_absdiff_accum<bits<2> sz, bits<4> opc, string asm,
4568                             ZPRRegOp zprty1, ZPRRegOp zprty2>
4569: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm),
4570  asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
4571  bits<5> Zda;
4572  bits<5> Zn;
4573  bits<5> Zm;
4574  let Inst{31-24} = 0b01000101;
4575  let Inst{23-22} = sz;
4576  let Inst{21}    = 0b0;
4577  let Inst{20-16} = Zm;
4578  let Inst{15-14} = 0b11;
4579  let Inst{13-10} = opc;
4580  let Inst{9-5}   = Zn;
4581  let Inst{4-0}   = Zda;
4582
4583  let Constraints = "$Zda = $_Zda";
4584  let DestructiveInstType = DestructiveOther;
4585  let ElementSize = ElementSizeNone;
4586  let hasSideEffects = 0;
4587}
4588
4589multiclass sve2_int_absdiff_accum<bit opc, string asm, SDPatternOperator op> {
4590  def _B : sve2_int_absdiff_accum<0b00, { 0b111, opc }, asm, ZPR8, ZPR8>;
4591  def _H : sve2_int_absdiff_accum<0b01, { 0b111, opc }, asm, ZPR16, ZPR16>;
4592  def _S : sve2_int_absdiff_accum<0b10, { 0b111, opc }, asm, ZPR32, ZPR32>;
4593  def _D : sve2_int_absdiff_accum<0b11, { 0b111, opc }, asm, ZPR64, ZPR64>;
4594
4595  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4596  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4597  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4598  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4599}
4600
4601multiclass sve2_int_absdiff_accum_long<bits<2> opc, string asm,
4602                                       SDPatternOperator op> {
4603  def _H : sve2_int_absdiff_accum<0b01, { 0b00, opc }, asm, ZPR16, ZPR8>;
4604  def _S : sve2_int_absdiff_accum<0b10, { 0b00, opc }, asm, ZPR32, ZPR16>;
4605  def _D : sve2_int_absdiff_accum<0b11, { 0b00, opc }, asm, ZPR64, ZPR32>;
4606
4607  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
4608  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
4609  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
4610}
4611
4612multiclass sve2_int_addsub_long_carry<bits<2> opc, string asm,
4613                                      SDPatternOperator op> {
4614  def _S : sve2_int_absdiff_accum<{ opc{1}, 0b0 }, { 0b010, opc{0} }, asm,
4615                                  ZPR32, ZPR32>;
4616  def _D : sve2_int_absdiff_accum<{ opc{1}, 0b1 }, { 0b010, opc{0} }, asm,
4617                                  ZPR64, ZPR64>;
4618
4619  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4620  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4621}
4622
4623//===----------------------------------------------------------------------===//
4624// SVE2 Narrowing Group
4625//===----------------------------------------------------------------------===//
4626
4627class sve2_int_bin_shift_imm_narrow_bottom<bits<3> tsz8_64, bits<3> opc,
4628                                           string asm, ZPRRegOp zprty1,
4629                                           ZPRRegOp zprty2, Operand immtype>
4630: I<(outs zprty1:$Zd), (ins zprty2:$Zn, immtype:$imm),
4631  asm, "\t$Zd, $Zn, $imm",
4632  "", []>, Sched<[]> {
4633  bits<5> Zd;
4634  bits<5> Zn;
4635  bits<5> imm;
4636  let Inst{31-23} = 0b010001010;
4637  let Inst{22}    = tsz8_64{2};
4638  let Inst{21}    = 0b1;
4639  let Inst{20-19} = tsz8_64{1-0};
4640  let Inst{18-16} = imm{2-0}; // imm3
4641  let Inst{15-14} = 0b00;
4642  let Inst{13-11} = opc;
4643  let Inst{10}    = 0b0;
4644  let Inst{9-5}   = Zn;
4645  let Inst{4-0}   = Zd;
4646
4647  let hasSideEffects = 0;
4648}
4649
4650multiclass sve2_int_bin_shift_imm_right_narrow_bottom<bits<3> opc, string asm,
4651                                                      SDPatternOperator op> {
4652  def _B : sve2_int_bin_shift_imm_narrow_bottom<{0,0,1}, opc, asm, ZPR8, ZPR16,
4653                                                tvecshiftR8>;
4654  def _H : sve2_int_bin_shift_imm_narrow_bottom<{0,1,?}, opc, asm, ZPR16, ZPR32,
4655                                                tvecshiftR16> {
4656    let Inst{19} = imm{3};
4657  }
4658  def _S : sve2_int_bin_shift_imm_narrow_bottom<{1,?,?}, opc, asm, ZPR32, ZPR64,
4659                                                tvecshiftR32> {
4660    let Inst{20-19} = imm{4-3};
4661  }
4662  def : SVE_2_Op_Imm_Pat<nxv16i8, op, nxv8i16, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4663  def : SVE_2_Op_Imm_Pat<nxv8i16, op, nxv4i32, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4664  def : SVE_2_Op_Imm_Pat<nxv4i32, op, nxv2i64, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4665}
4666
4667class sve2_int_bin_shift_imm_narrow_top<bits<3> tsz8_64, bits<3> opc,
4668                                        string asm, ZPRRegOp zprty1,
4669                                        ZPRRegOp zprty2, Operand immtype>
4670: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, immtype:$imm),
4671  asm, "\t$Zd, $Zn, $imm",
4672  "", []>, Sched<[]> {
4673  bits<5> Zd;
4674  bits<5> Zn;
4675  bits<5> imm;
4676  let Inst{31-23} = 0b010001010;
4677  let Inst{22}    = tsz8_64{2};
4678  let Inst{21}    = 0b1;
4679  let Inst{20-19} = tsz8_64{1-0};
4680  let Inst{18-16} = imm{2-0}; // imm3
4681  let Inst{15-14} = 0b00;
4682  let Inst{13-11} = opc;
4683  let Inst{10}    = 0b1;
4684  let Inst{9-5}   = Zn;
4685  let Inst{4-0}   = Zd;
4686
4687  let Constraints = "$Zd = $_Zd";
4688  let hasSideEffects = 0;
4689}
4690
4691multiclass sve2_int_bin_shift_imm_right_narrow_top<bits<3> opc, string asm,
4692                                                   SDPatternOperator op> {
4693  def _B : sve2_int_bin_shift_imm_narrow_top<{0,0,1}, opc, asm, ZPR8, ZPR16,
4694                                             tvecshiftR8>;
4695  def _H : sve2_int_bin_shift_imm_narrow_top<{0,1,?}, opc, asm, ZPR16, ZPR32,
4696                                             tvecshiftR16> {
4697    let Inst{19} = imm{3};
4698  }
4699  def _S : sve2_int_bin_shift_imm_narrow_top<{1,?,?}, opc, asm, ZPR32, ZPR64,
4700                                             tvecshiftR32> {
4701    let Inst{20-19} = imm{4-3};
4702  }
4703  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv8i16, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4704  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv4i32, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4705  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv2i64, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4706}
4707
4708class sve2_int_addsub_narrow_high_bottom<bits<2> sz, bits<2> opc, string asm,
4709                                         ZPRRegOp zprty1, ZPRRegOp zprty2>
4710: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty2:$Zm),
4711  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4712  bits<5> Zd;
4713  bits<5> Zn;
4714  bits<5> Zm;
4715  let Inst{31-24} = 0b01000101;
4716  let Inst{23-22} = sz;
4717  let Inst{21}    = 0b1;
4718  let Inst{20-16} = Zm;
4719  let Inst{15-13} = 0b011;
4720  let Inst{12-11} = opc; // S, R
4721  let Inst{10}    = 0b0; // Top
4722  let Inst{9-5}   = Zn;
4723  let Inst{4-0}   = Zd;
4724
4725  let hasSideEffects = 0;
4726}
4727
4728multiclass sve2_int_addsub_narrow_high_bottom<bits<2> opc, string asm,
4729                                              SDPatternOperator op> {
4730  def _B : sve2_int_addsub_narrow_high_bottom<0b01, opc, asm, ZPR8, ZPR16>;
4731  def _H : sve2_int_addsub_narrow_high_bottom<0b10, opc, asm, ZPR16, ZPR32>;
4732  def _S : sve2_int_addsub_narrow_high_bottom<0b11, opc, asm, ZPR32, ZPR64>;
4733
4734  def : SVE_2_Op_Pat<nxv16i8, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _B)>;
4735  def : SVE_2_Op_Pat<nxv8i16, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _H)>;
4736  def : SVE_2_Op_Pat<nxv4i32, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _S)>;
4737}
4738
4739class sve2_int_addsub_narrow_high_top<bits<2> sz, bits<2> opc, string asm,
4740                                      ZPRRegOp zprty1, ZPRRegOp zprty2>
4741: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, zprty2:$Zm),
4742  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4743  bits<5> Zd;
4744  bits<5> Zn;
4745  bits<5> Zm;
4746  let Inst{31-24} = 0b01000101;
4747  let Inst{23-22} = sz;
4748  let Inst{21}    = 0b1;
4749  let Inst{20-16} = Zm;
4750  let Inst{15-13} = 0b011;
4751  let Inst{12-11} = opc; // S, R
4752  let Inst{10}    = 0b1; // Top
4753  let Inst{9-5}   = Zn;
4754  let Inst{4-0}   = Zd;
4755
4756  let Constraints = "$Zd = $_Zd";
4757  let hasSideEffects = 0;
4758}
4759
4760multiclass sve2_int_addsub_narrow_high_top<bits<2> opc, string asm,
4761                                           SDPatternOperator op> {
4762  def _B : sve2_int_addsub_narrow_high_top<0b01, opc, asm, ZPR8, ZPR16>;
4763  def _H : sve2_int_addsub_narrow_high_top<0b10, opc, asm, ZPR16, ZPR32>;
4764  def _S : sve2_int_addsub_narrow_high_top<0b11, opc, asm, ZPR32, ZPR64>;
4765
4766  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _B)>;
4767  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _H)>;
4768  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _S)>;
4769}
4770
4771class sve2_int_sat_extract_narrow_bottom<bits<3> tsz8_64, bits<2> opc, string asm,
4772                                         ZPRRegOp zprty1, ZPRRegOp zprty2>
4773: I<(outs zprty1:$Zd), (ins zprty2:$Zn),
4774  asm, "\t$Zd, $Zn", "", []>, Sched<[]> {
4775  bits<5> Zd;
4776  bits<5> Zn;
4777  let Inst{31-23} = 0b010001010;
4778  let Inst{22}    = tsz8_64{2};
4779  let Inst{21}    = 0b1;
4780  let Inst{20-19} = tsz8_64{1-0};
4781  let Inst{18-13} = 0b000010;
4782  let Inst{12-11} = opc;
4783  let Inst{10}    = 0b0;
4784  let Inst{9-5}   = Zn;
4785  let Inst{4-0}   = Zd;
4786
4787  let hasSideEffects = 0;
4788}
4789
4790multiclass sve2_int_sat_extract_narrow_bottom<bits<2> opc, string asm,
4791                                              SDPatternOperator op> {
4792  def _B : sve2_int_sat_extract_narrow_bottom<0b001, opc, asm, ZPR8, ZPR16>;
4793  def _H : sve2_int_sat_extract_narrow_bottom<0b010, opc, asm, ZPR16, ZPR32>;
4794  def _S : sve2_int_sat_extract_narrow_bottom<0b100, opc, asm, ZPR32, ZPR64>;
4795
4796  def : SVE_1_Op_Pat<nxv16i8, op, nxv8i16, !cast<Instruction>(NAME # _B)>;
4797  def : SVE_1_Op_Pat<nxv8i16, op, nxv4i32, !cast<Instruction>(NAME # _H)>;
4798  def : SVE_1_Op_Pat<nxv4i32, op, nxv2i64, !cast<Instruction>(NAME # _S)>;
4799}
4800
4801class sve2_int_sat_extract_narrow_top<bits<3> tsz8_64, bits<2> opc, string asm,
4802                                      ZPRRegOp zprty1, ZPRRegOp zprty2>
4803: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn),
4804  asm, "\t$Zd, $Zn", "", []>, Sched<[]> {
4805  bits<5> Zd;
4806  bits<5> Zn;
4807  let Inst{31-23} = 0b010001010;
4808  let Inst{22}    = tsz8_64{2};
4809  let Inst{21}    = 0b1;
4810  let Inst{20-19} = tsz8_64{1-0};
4811  let Inst{18-13} = 0b000010;
4812  let Inst{12-11} = opc;
4813  let Inst{10}    = 0b1;
4814  let Inst{9-5}   = Zn;
4815  let Inst{4-0}   = Zd;
4816
4817  let Constraints = "$Zd = $_Zd";
4818  let hasSideEffects = 0;
4819}
4820
4821multiclass sve2_int_sat_extract_narrow_top<bits<2> opc, string asm,
4822                                           SDPatternOperator op> {
4823  def _B : sve2_int_sat_extract_narrow_top<0b001, opc, asm, ZPR8, ZPR16>;
4824  def _H : sve2_int_sat_extract_narrow_top<0b010, opc, asm, ZPR16, ZPR32>;
4825  def _S : sve2_int_sat_extract_narrow_top<0b100, opc, asm, ZPR32, ZPR64>;
4826
4827  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv8i16, !cast<Instruction>(NAME # _B)>;
4828  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv4i32, !cast<Instruction>(NAME # _H)>;
4829  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
4830}
4831
4832//===----------------------------------------------------------------------===//
4833// SVE Integer Arithmetic - Unary Predicated Group
4834//===----------------------------------------------------------------------===//
4835
4836class sve_int_un_pred_arit<bits<2> sz8_64, bits<4> opc,
4837                             string asm, ZPRRegOp zprty>
4838: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
4839  asm, "\t$Zd, $Pg/m, $Zn",
4840  "",
4841  []>, Sched<[]> {
4842  bits<3> Pg;
4843  bits<5> Zd;
4844  bits<5> Zn;
4845  let Inst{31-24} = 0b00000100;
4846  let Inst{23-22} = sz8_64;
4847  let Inst{21-20} = 0b01;
4848  let Inst{19}    = opc{0};
4849  let Inst{18-16} = opc{3-1};
4850  let Inst{15-13} = 0b101;
4851  let Inst{12-10} = Pg;
4852  let Inst{9-5}   = Zn;
4853  let Inst{4-0}   = Zd;
4854
4855  let Constraints = "$Zd = $_Zd";
4856  let DestructiveInstType = DestructiveUnaryPassthru;
4857  let ElementSize = zprty.ElementSize;
4858  let hasSideEffects = 0;
4859}
4860
4861class sve_int_un_pred_arit_z<bits<2> sz8_64, bits<4> opc,
4862                            string asm, ZPRRegOp zprty>
4863: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
4864  asm, "\t$Zd, $Pg/z, $Zn",
4865  "",
4866  []>, Sched<[]> {
4867  bits<3> Pg;
4868  bits<5> Zd;
4869  bits<5> Zn;
4870  let Inst{31-24} = 0b00000100;
4871  let Inst{23-22} = sz8_64;
4872  let Inst{21-20} = 0b00;
4873  let Inst{19}    = opc{0};
4874  let Inst{18-16} = opc{3-1};
4875  let Inst{15-13} = 0b101;
4876  let Inst{12-10} = Pg;
4877  let Inst{9-5}   = Zn;
4878  let Inst{4-0}   = Zd;
4879
4880  let hasSideEffects = 0;
4881}
4882
4883multiclass sve_int_un_pred_arit<bits<3> opc, string asm,
4884                                SDPatternOperator op> {
4885  def _B : sve_int_un_pred_arit<0b00, { opc, 0b0 }, asm, ZPR8>,
4886           SVEPseudo2Instr<NAME # _B, 1>;
4887  def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>,
4888           SVEPseudo2Instr<NAME # _H, 1>;
4889  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4890           SVEPseudo2Instr<NAME # _S, 1>;
4891  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4892           SVEPseudo2Instr<NAME # _D, 1>;
4893
4894  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
4895  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
4896  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
4897  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
4898
4899  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
4900  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4901  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4902  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4903
4904  defm : SVE_1_Op_PassthruUndef_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
4905  defm : SVE_1_Op_PassthruUndef_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4906  defm : SVE_1_Op_PassthruUndef_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4907  defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4908}
4909
4910multiclass sve_int_un_pred_arit_z<bits<3> opc, string asm, SDPatternOperator op> {
4911  def _B : sve_int_un_pred_arit_z<0b00, { opc, 0b0 }, asm, ZPR8>;
4912  def _H : sve_int_un_pred_arit_z<0b01, { opc, 0b0 }, asm, ZPR16>;
4913  def _S : sve_int_un_pred_arit_z<0b10, { opc, 0b0 }, asm, ZPR32>;
4914  def _D : sve_int_un_pred_arit_z<0b11, { opc, 0b0 }, asm, ZPR64>;
4915
4916  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
4917  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
4918  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
4919  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
4920}
4921
4922multiclass sve_int_un_pred_arit_h<bits<3> opc, string asm,
4923                                  SDPatternOperator op> {
4924  def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>,
4925           SVEPseudo2Instr<NAME # _H, 1>;
4926  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4927           SVEPseudo2Instr<NAME # _S, 1>;
4928  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4929           SVEPseudo2Instr<NAME # _D, 1>;
4930
4931  def : SVE_InReg_Extend<nxv8i16, op, nxv8i1, nxv8i8, !cast<Instruction>(NAME # _H)>;
4932  def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i8, !cast<Instruction>(NAME # _S)>;
4933  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i8, !cast<Instruction>(NAME # _D)>;
4934
4935  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4936  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4937  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4938
4939  defm : SVE_InReg_Extend_PassthruUndef<nxv8i16, op, nxv8i1, nxv8i8, !cast<Pseudo>(NAME # _H_UNDEF)>;
4940  defm : SVE_InReg_Extend_PassthruUndef<nxv4i32, op, nxv4i1, nxv4i8, !cast<Pseudo>(NAME # _S_UNDEF)>;
4941  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i8, !cast<Pseudo>(NAME # _D_UNDEF)>;
4942}
4943
4944multiclass sve_int_un_pred_arit_h_z<bits<3> opc, string asm, SDPatternOperator op> {
4945  def _H : sve_int_un_pred_arit_z<0b01, { opc, 0b0 }, asm, ZPR16>;
4946  def _S : sve_int_un_pred_arit_z<0b10, { opc, 0b0 }, asm, ZPR32>;
4947  def _D : sve_int_un_pred_arit_z<0b11, { opc, 0b0 }, asm, ZPR64>;
4948
4949  defm : SVE_InReg_Extend_PassthruUndefZero<nxv8i16, op, nxv8i1, nxv8i8, !cast<Instruction>(NAME # _H)>;
4950  defm : SVE_InReg_Extend_PassthruUndefZero<nxv4i32, op, nxv4i1, nxv4i8, !cast<Instruction>(NAME # _S)>;
4951  defm : SVE_InReg_Extend_PassthruUndefZero<nxv2i64, op, nxv2i1, nxv2i8, !cast<Instruction>(NAME # _D)>;
4952}
4953
4954multiclass sve_int_un_pred_arit_w<bits<3> opc, string asm,
4955                                  SDPatternOperator op> {
4956  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4957           SVEPseudo2Instr<NAME # _S, 1>;
4958  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4959           SVEPseudo2Instr<NAME # _D, 1>;
4960
4961  def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i16, !cast<Instruction>(NAME # _S)>;
4962  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i16, !cast<Instruction>(NAME # _D)>;
4963
4964  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4965  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4966
4967  defm : SVE_InReg_Extend_PassthruUndef<nxv4i32, op, nxv4i1, nxv4i16, !cast<Pseudo>(NAME # _S_UNDEF)>;
4968  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i16, !cast<Pseudo>(NAME # _D_UNDEF)>;
4969}
4970
4971multiclass sve_int_un_pred_arit_w_z<bits<3> opc, string asm, SDPatternOperator op> {
4972  def _S : sve_int_un_pred_arit_z<0b10, { opc, 0b0 }, asm, ZPR32>;
4973  def _D : sve_int_un_pred_arit_z<0b11, { opc, 0b0 }, asm, ZPR64>;
4974
4975  defm : SVE_InReg_Extend_PassthruUndefZero<nxv4i32, op, nxv4i1, nxv4i16, !cast<Instruction>(NAME # _S)>;
4976  defm : SVE_InReg_Extend_PassthruUndefZero<nxv2i64, op, nxv2i1, nxv2i16, !cast<Instruction>(NAME # _D)>;
4977}
4978
4979multiclass sve_int_un_pred_arit_d<bits<3> opc, string asm,
4980                                  SDPatternOperator op> {
4981  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4982           SVEPseudo2Instr<NAME # _D, 1>;
4983
4984  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i32, !cast<Instruction>(NAME # _D)>;
4985
4986  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4987
4988  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i32, !cast<Pseudo>(NAME # _D_UNDEF)>;
4989}
4990
4991multiclass sve_int_un_pred_arit_d_z<bits<3> opc, string asm, SDPatternOperator op> {
4992  def _D : sve_int_un_pred_arit_z<0b11, {opc, 0b0}, asm, ZPR64>;
4993
4994  defm : SVE_InReg_Extend_PassthruUndefZero<nxv2i64, op, nxv2i1, nxv2i32, !cast<Instruction>(NAME # _D)>;
4995}
4996
4997multiclass sve_int_un_pred_arit_bitwise<bits<3> opc, string asm,
4998                                        SDPatternOperator op> {
4999  def _B : sve_int_un_pred_arit<0b00, { opc, 0b1 }, asm, ZPR8>,
5000           SVEPseudo2Instr<NAME # _B, 1>;
5001  def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>,
5002           SVEPseudo2Instr<NAME # _H, 1>;
5003  def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>,
5004           SVEPseudo2Instr<NAME # _S, 1>;
5005  def _D : sve_int_un_pred_arit<0b11, { opc, 0b1 }, asm, ZPR64>,
5006           SVEPseudo2Instr<NAME # _D, 1>;
5007
5008  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
5009  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
5010  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
5011  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
5012
5013  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
5014  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
5015  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
5016  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
5017
5018  defm : SVE_1_Op_PassthruUndef_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
5019  defm : SVE_1_Op_PassthruUndef_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
5020  defm : SVE_1_Op_PassthruUndef_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
5021  defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
5022}
5023
5024multiclass sve_int_un_pred_arit_bitwise_z<bits<3> opc, string asm, SDPatternOperator op> {
5025  def _B : sve_int_un_pred_arit_z<0b00, { opc, 0b1 }, asm, ZPR8>;
5026  def _H : sve_int_un_pred_arit_z<0b01, { opc, 0b1 }, asm, ZPR16>;
5027  def _S : sve_int_un_pred_arit_z<0b10, { opc, 0b1 }, asm, ZPR32>;
5028  def _D : sve_int_un_pred_arit_z<0b11, { opc, 0b1 }, asm, ZPR64>;
5029
5030  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
5031  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
5032  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
5033  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
5034}
5035
5036multiclass sve_int_un_pred_arit_bitwise_fp<bits<3> opc, string asm,
5037                                           SDPatternOperator op> {
5038  def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>,
5039           SVEPseudo2Instr<NAME # _H, 1>;
5040  def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>,
5041           SVEPseudo2Instr<NAME # _S, 1>;
5042  def _D : sve_int_un_pred_arit<0b11, { opc, 0b1 }, asm, ZPR64>,
5043           SVEPseudo2Instr<NAME # _D, 1>;
5044
5045  def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
5046  def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
5047  def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
5048  def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
5049  def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
5050  def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
5051
5052  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
5053  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
5054  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
5055
5056  defm : SVE_1_Op_PassthruUndef_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
5057  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
5058  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
5059  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
5060  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
5061  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Pseudo>(NAME # _D_UNDEF)>;
5062}
5063
5064multiclass sve_int_un_pred_arit_bitwise_fp_z<bits<3> opc, string asm, SDPatternOperator op> {
5065  def _H : sve_int_un_pred_arit_z<0b01, { opc, 0b1 }, asm, ZPR16>;
5066  def _S : sve_int_un_pred_arit_z<0b10, { opc, 0b1 }, asm, ZPR32>;
5067  def _D : sve_int_un_pred_arit_z<0b11, { opc, 0b1 }, asm, ZPR64>;
5068
5069  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
5070  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
5071  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
5072  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
5073  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
5074  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
5075}
5076
5077multiclass sve_fp_un_pred_arit_hsd<SDPatternOperator op> {
5078  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
5079  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
5080  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
5081
5082  defm : SVE_1_Op_PassthruUndef_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
5083  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
5084  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
5085  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
5086  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
5087  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Pseudo>(NAME # _D_UNDEF)>;
5088}
5089
5090multiclass sve_int_un_pred_arit_bhsd<SDPatternOperator op> {
5091  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
5092  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
5093  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
5094  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
5095
5096  defm : SVE_1_Op_PassthruUndef_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
5097  defm : SVE_1_Op_PassthruUndef_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
5098  defm : SVE_1_Op_PassthruUndef_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
5099  defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
5100}
5101
5102//===----------------------------------------------------------------------===//
5103// SVE Integer Wide Immediate - Unpredicated Group
5104//===----------------------------------------------------------------------===//
5105class sve_int_dup_imm<bits<2> sz8_64, string asm,
5106                      ZPRRegOp zprty, Operand immtype>
5107: I<(outs zprty:$Zd), (ins immtype:$imm),
5108  asm, "\t$Zd, $imm",
5109  "",
5110  []>, Sched<[]> {
5111  bits<5> Zd;
5112  bits<9> imm;
5113  let Inst{31-24} = 0b00100101;
5114  let Inst{23-22} = sz8_64;
5115  let Inst{21-14} = 0b11100011;
5116  let Inst{13}    = imm{8};   // sh
5117  let Inst{12-5}  = imm{7-0}; // imm8
5118  let Inst{4-0}   = Zd;
5119
5120  let hasSideEffects = 0;
5121  let isReMaterializable = 1;
5122  let Uses = [VG];
5123}
5124
5125multiclass sve_int_dup_imm<string asm> {
5126  def _B : sve_int_dup_imm<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8>;
5127  def _H : sve_int_dup_imm<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16>;
5128  def _S : sve_int_dup_imm<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32>;
5129  def _D : sve_int_dup_imm<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64>;
5130
5131  def : InstAlias<"mov $Zd, $imm",
5132                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, cpy_imm8_opt_lsl_i8:$imm), 1>;
5133  def : InstAlias<"mov $Zd, $imm",
5134                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, cpy_imm8_opt_lsl_i16:$imm), 1>;
5135  def : InstAlias<"mov $Zd, $imm",
5136                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, cpy_imm8_opt_lsl_i32:$imm), 1>;
5137  def : InstAlias<"mov $Zd, $imm",
5138                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, cpy_imm8_opt_lsl_i64:$imm), 1>;
5139
5140  def : InstAlias<"fmov $Zd, #0.0",
5141                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, 0, 0), 1>;
5142  def : InstAlias<"fmov $Zd, #0.0",
5143                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, 0, 0), 1>;
5144  def : InstAlias<"fmov $Zd, #0.0",
5145                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, 0, 0), 1>;
5146}
5147
5148class sve_int_dup_fpimm<bits<2> sz8_64, Operand fpimmtype,
5149                        string asm, ZPRRegOp zprty>
5150: I<(outs zprty:$Zd), (ins fpimmtype:$imm8),
5151  asm, "\t$Zd, $imm8",
5152  "",
5153  []>, Sched<[]> {
5154  bits<5> Zd;
5155  bits<8> imm8;
5156  let Inst{31-24} = 0b00100101;
5157  let Inst{23-22} = sz8_64;
5158  let Inst{21-14} = 0b11100111;
5159  let Inst{13}    = 0b0;
5160  let Inst{12-5}  = imm8;
5161  let Inst{4-0}   = Zd;
5162
5163  let hasSideEffects = 0;
5164  let isReMaterializable = 1;
5165  let Uses = [VG];
5166}
5167
5168multiclass sve_int_dup_fpimm<string asm> {
5169  def _H : sve_int_dup_fpimm<0b01, fpimm16, asm, ZPR16>;
5170  def _S : sve_int_dup_fpimm<0b10, fpimm32, asm, ZPR32>;
5171  def _D : sve_int_dup_fpimm<0b11, fpimm64, asm, ZPR64>;
5172
5173  def : InstAlias<"fmov $Zd, $imm8",
5174                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, fpimm16:$imm8), 1>;
5175  def : InstAlias<"fmov $Zd, $imm8",
5176                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, fpimm32:$imm8), 1>;
5177  def : InstAlias<"fmov $Zd, $imm8",
5178                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, fpimm64:$imm8), 1>;
5179}
5180
5181class sve_int_arith_imm0<bits<2> sz8_64, bits<3> opc, string asm,
5182                         ZPRRegOp zprty, Operand immtype>
5183: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, immtype:$imm),
5184  asm, "\t$Zdn, $_Zdn, $imm",
5185  "",
5186  []>, Sched<[]> {
5187  bits<5> Zdn;
5188  bits<9> imm;
5189  let Inst{31-24} = 0b00100101;
5190  let Inst{23-22} = sz8_64;
5191  let Inst{21-19} = 0b100;
5192  let Inst{18-16} = opc;
5193  let Inst{15-14} = 0b11;
5194  let Inst{13}    = imm{8};   // sh
5195  let Inst{12-5}  = imm{7-0}; // imm8
5196  let Inst{4-0}   = Zdn;
5197
5198  let Constraints = "$Zdn = $_Zdn";
5199  let DestructiveInstType = DestructiveOther;
5200  let ElementSize = ElementSizeNone;
5201  let hasSideEffects = 0;
5202}
5203
5204multiclass sve_int_arith_imm0<bits<3> opc, string asm, SDPatternOperator op> {
5205  def _B : sve_int_arith_imm0<0b00, opc, asm, ZPR8,  addsub_imm8_opt_lsl_i8>;
5206  def _H : sve_int_arith_imm0<0b01, opc, asm, ZPR16, addsub_imm8_opt_lsl_i16>;
5207  def _S : sve_int_arith_imm0<0b10, opc, asm, ZPR32, addsub_imm8_opt_lsl_i32>;
5208  def _D : sve_int_arith_imm0<0b11, opc, asm, ZPR64, addsub_imm8_opt_lsl_i64>;
5209
5210  def : SVE_1_Op_Imm_OptLsl_Pat<nxv16i8, op, ZPR8,  i32, SVEAddSubImm8Pat,  !cast<Instruction>(NAME # _B)>;
5211  def : SVE_1_Op_Imm_OptLsl_Pat<nxv8i16, op, ZPR16, i32, SVEAddSubImm16Pat, !cast<Instruction>(NAME # _H)>;
5212  def : SVE_1_Op_Imm_OptLsl_Pat<nxv4i32, op, ZPR32, i32, SVEAddSubImm32Pat, !cast<Instruction>(NAME # _S)>;
5213  def : SVE_1_Op_Imm_OptLsl_Pat<nxv2i64, op, ZPR64, i64, SVEAddSubImm64Pat, !cast<Instruction>(NAME # _D)>;
5214}
5215
5216multiclass sve_int_arith_imm0_ssat<bits<3> opc, string asm, SDPatternOperator op,
5217                                   SDPatternOperator inv_op> {
5218  def _B : sve_int_arith_imm0<0b00, opc, asm, ZPR8,  addsub_imm8_opt_lsl_i8>;
5219  def _H : sve_int_arith_imm0<0b01, opc, asm, ZPR16, addsub_imm8_opt_lsl_i16>;
5220  def _S : sve_int_arith_imm0<0b10, opc, asm, ZPR32, addsub_imm8_opt_lsl_i32>;
5221  def _D : sve_int_arith_imm0<0b11, opc, asm, ZPR64, addsub_imm8_opt_lsl_i64>;
5222
5223  def : SVE_1_Op_Imm_OptLsl_Pat<nxv16i8, op, ZPR8,  i32, SVEAddSubSSatPosImm8Pat,  !cast<Instruction>(NAME # _B)>;
5224  def : SVE_1_Op_Imm_OptLsl_Pat<nxv8i16, op, ZPR16, i32, SVEAddSubSSatPosImm16Pat, !cast<Instruction>(NAME # _H)>;
5225  def : SVE_1_Op_Imm_OptLsl_Pat<nxv4i32, op, ZPR32, i32, SVEAddSubSSatPosImm32Pat, !cast<Instruction>(NAME # _S)>;
5226  def : SVE_1_Op_Imm_OptLsl_Pat<nxv2i64, op, ZPR64, i64, SVEAddSubSSatPosImm64Pat, !cast<Instruction>(NAME # _D)>;
5227
5228  def : SVE_1_Op_Imm_OptLsl_Pat<nxv16i8, inv_op, ZPR8,  i32, SVEAddSubSSatNegImm8Pat,  !cast<Instruction>(NAME # _B)>;
5229  def : SVE_1_Op_Imm_OptLsl_Pat<nxv8i16, inv_op, ZPR16, i32, SVEAddSubSSatNegImm16Pat, !cast<Instruction>(NAME # _H)>;
5230  def : SVE_1_Op_Imm_OptLsl_Pat<nxv4i32, inv_op, ZPR32, i32, SVEAddSubSSatNegImm32Pat, !cast<Instruction>(NAME # _S)>;
5231  def : SVE_1_Op_Imm_OptLsl_Pat<nxv2i64, inv_op, ZPR64, i64, SVEAddSubSSatNegImm64Pat, !cast<Instruction>(NAME # _D)>;
5232}
5233
5234class sve_int_arith_imm<bits<2> sz8_64, bits<6> opc, string asm,
5235                        ZPRRegOp zprty, Operand immtype>
5236: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, immtype:$imm),
5237  asm, "\t$Zdn, $_Zdn, $imm",
5238  "",
5239  []>, Sched<[]> {
5240  bits<5> Zdn;
5241  bits<8> imm;
5242  let Inst{31-24} = 0b00100101;
5243  let Inst{23-22} = sz8_64;
5244  let Inst{21-16} = opc;
5245  let Inst{15-13} = 0b110;
5246  let Inst{12-5} = imm;
5247  let Inst{4-0} = Zdn;
5248
5249  let Constraints = "$Zdn = $_Zdn";
5250  let DestructiveInstType = DestructiveOther;
5251  let ElementSize = ElementSizeNone;
5252  let hasSideEffects = 0;
5253}
5254
5255multiclass sve_int_arith_imm1<bits<2> opc, string asm, SDPatternOperator op> {
5256  def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, simm8_32b>;
5257  def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, simm8_32b>;
5258  def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, simm8_32b>;
5259  def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, simm8_32b>;
5260
5261  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B)>;
5262  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1,  op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H)>;
5263  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1,  op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S)>;
5264  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1,  op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D)>;
5265}
5266
5267multiclass sve_int_arith_imm1_unsigned<bits<2> opc, string asm, SDPatternOperator op> {
5268  def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, imm0_255>;
5269  def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, imm0_255>;
5270  def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, imm0_255>;
5271  def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, imm0_255>;
5272
5273  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithUImm8Pat, !cast<Instruction>(NAME # _B)>;
5274  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithUImm16Pat, !cast<Instruction>(NAME # _H)>;
5275  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithUImm32Pat, !cast<Instruction>(NAME # _S)>;
5276  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithUImm64Pat, !cast<Instruction>(NAME # _D)>;
5277}
5278
5279multiclass sve_int_arith_imm2<string asm, SDPatternOperator op> {
5280  def _B : sve_int_arith_imm<0b00, 0b110000, asm, ZPR8,  simm8_32b>;
5281  def _H : sve_int_arith_imm<0b01, 0b110000, asm, ZPR16, simm8_32b>;
5282  def _S : sve_int_arith_imm<0b10, 0b110000, asm, ZPR32, simm8_32b>;
5283  def _D : sve_int_arith_imm<0b11, 0b110000, asm, ZPR64, simm8_32b>;
5284
5285  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B)>;
5286  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H)>;
5287  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S)>;
5288  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D)>;
5289}
5290
5291//===----------------------------------------------------------------------===//
5292// SVE Bitwise Logical - Unpredicated Group
5293//===----------------------------------------------------------------------===//
5294
5295class sve_int_bin_cons_log<bits<2> opc, string asm>
5296: I<(outs ZPR64:$Zd), (ins ZPR64:$Zn, ZPR64:$Zm),
5297  asm, "\t$Zd, $Zn, $Zm",
5298  "",
5299  []>, Sched<[]> {
5300  bits<5> Zd;
5301  bits<5> Zm;
5302  bits<5> Zn;
5303  let Inst{31-24} = 0b00000100;
5304  let Inst{23-22} = opc{1-0};
5305  let Inst{21}    = 0b1;
5306  let Inst{20-16} = Zm;
5307  let Inst{15-10} = 0b001100;
5308  let Inst{9-5}   = Zn;
5309  let Inst{4-0}   = Zd;
5310
5311  let hasSideEffects = 0;
5312}
5313
5314multiclass sve_int_bin_cons_log<bits<2> opc, string asm, SDPatternOperator op> {
5315  def NAME : sve_int_bin_cons_log<opc, asm>;
5316
5317  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
5318  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
5319  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
5320  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
5321
5322  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
5323                  (!cast<Instruction>(NAME) ZPR8:$Zd,  ZPR8:$Zn,  ZPR8:$Zm),  1>;
5324  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
5325                  (!cast<Instruction>(NAME) ZPR16:$Zd, ZPR16:$Zn, ZPR16:$Zm), 1>;
5326  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
5327                  (!cast<Instruction>(NAME) ZPR32:$Zd, ZPR32:$Zn, ZPR32:$Zm), 1>;
5328}
5329
5330class sve2_int_bitwise_ternary_op_d<bits<3> opc, string asm>
5331: I<(outs ZPR64:$Zdn), (ins ZPR64:$_Zdn, ZPR64:$Zm, ZPR64:$Zk),
5332  asm, "\t$Zdn, $_Zdn, $Zm, $Zk",
5333  "",
5334  []>, Sched<[]> {
5335  bits<5> Zdn;
5336  bits<5> Zk;
5337  bits<5> Zm;
5338  let Inst{31-24} = 0b00000100;
5339  let Inst{23-22} = opc{2-1};
5340  let Inst{21}    = 0b1;
5341  let Inst{20-16} = Zm;
5342  let Inst{15-11} = 0b00111;
5343  let Inst{10}    = opc{0};
5344  let Inst{9-5}   = Zk;
5345  let Inst{4-0}   = Zdn;
5346
5347  let Constraints = "$Zdn = $_Zdn";
5348  let DestructiveInstType = DestructiveOther;
5349  let ElementSize = ElementSizeNone;
5350  let hasSideEffects = 0;
5351}
5352
5353multiclass sve2_int_bitwise_ternary_op<bits<3> opc, string asm,
5354                                       SDPatternOperator op> {
5355  def NAME : sve2_int_bitwise_ternary_op_d<opc, asm>;
5356
5357  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
5358                  (!cast<Instruction>(NAME) ZPR8:$Zdn,  ZPR8:$Zm,  ZPR8:$Zk),  1>;
5359  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
5360                  (!cast<Instruction>(NAME) ZPR16:$Zdn, ZPR16:$Zm, ZPR16:$Zk), 1>;
5361  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
5362                  (!cast<Instruction>(NAME) ZPR32:$Zdn, ZPR32:$Zm, ZPR32:$Zk), 1>;
5363
5364  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
5365  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
5366  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
5367  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
5368}
5369
5370class sve2_int_rotate_right_imm<bits<4> tsz8_64, string asm,
5371                                ZPRRegOp zprty, Operand immtype>
5372: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, immtype:$imm),
5373  asm, "\t$Zdn, $_Zdn, $Zm, $imm",
5374  "",
5375  []>, Sched<[]> {
5376  bits<5> Zdn;
5377  bits<5> Zm;
5378  bits<6> imm;
5379  let Inst{31-24} = 0b00000100;
5380  let Inst{23-22} = tsz8_64{3-2};
5381  let Inst{21}    = 0b1;
5382  let Inst{20-19} = tsz8_64{1-0};
5383  let Inst{18-16} = imm{2-0}; // imm3
5384  let Inst{15-10} = 0b001101;
5385  let Inst{9-5}   = Zm;
5386  let Inst{4-0}   = Zdn;
5387
5388  let Constraints = "$Zdn = $_Zdn";
5389  let DestructiveInstType = DestructiveOther;
5390  let ElementSize = ElementSizeNone;
5391  let hasSideEffects = 0;
5392}
5393
5394multiclass sve2_int_rotate_right_imm<string asm, SDPatternOperator op> {
5395  def _B : sve2_int_rotate_right_imm<{0,0,0,1}, asm, ZPR8, vecshiftR8>;
5396  def _H : sve2_int_rotate_right_imm<{0,0,1,?}, asm, ZPR16, vecshiftR16> {
5397    let Inst{19} = imm{3};
5398  }
5399  def _S : sve2_int_rotate_right_imm<{0,1,?,?}, asm, ZPR32, vecshiftR32> {
5400    let Inst{20-19} = imm{4-3};
5401  }
5402  def _D : sve2_int_rotate_right_imm<{1,?,?,?}, asm, ZPR64, vecshiftR64> {
5403    let Inst{22}    = imm{5};
5404    let Inst{20-19} = imm{4-3};
5405  }
5406
5407  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
5408  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
5409  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
5410  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
5411}
5412
5413//===----------------------------------------------------------------------===//
5414// SVE Integer Wide Immediate - Predicated Group
5415//===----------------------------------------------------------------------===//
5416
5417class sve_int_dup_fpimm_pred<bits<2> sz, Operand fpimmtype,
5418                             string asm, ZPRRegOp zprty>
5419: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPRAny:$Pg, fpimmtype:$imm8),
5420  asm, "\t$Zd, $Pg/m, $imm8",
5421  "",
5422  []>, Sched<[]> {
5423  bits<4> Pg;
5424  bits<5> Zd;
5425  bits<8> imm8;
5426  let Inst{31-24} = 0b00000101;
5427  let Inst{23-22} = sz;
5428  let Inst{21-20} = 0b01;
5429  let Inst{19-16} = Pg;
5430  let Inst{15-13} = 0b110;
5431  let Inst{12-5}  = imm8;
5432  let Inst{4-0}   = Zd;
5433
5434  let Constraints = "$Zd = $_Zd";
5435  let DestructiveInstType = DestructiveOther;
5436  let ElementSize = zprty.ElementSize;
5437  let hasSideEffects = 0;
5438}
5439
5440multiclass sve_int_dup_fpimm_pred<string asm> {
5441  def _H : sve_int_dup_fpimm_pred<0b01, fpimm16, asm, ZPR16>;
5442  def _S : sve_int_dup_fpimm_pred<0b10, fpimm32, asm, ZPR32>;
5443  def _D : sve_int_dup_fpimm_pred<0b11, fpimm64, asm, ZPR64>;
5444
5445  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
5446                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, fpimm16:$imm8), 1>;
5447  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
5448                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, fpimm32:$imm8), 1>;
5449  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
5450                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, fpimm64:$imm8), 1>;
5451}
5452
5453class sve_int_dup_imm_pred<bits<2> sz8_64, bit m, string asm,
5454                           ZPRRegOp zprty, string pred_qual, dag iops>
5455: I<(outs zprty:$Zd), iops,
5456  asm, "\t$Zd, $Pg"#pred_qual#", $imm",
5457  "", []>, Sched<[]> {
5458  bits<5> Zd;
5459  bits<4> Pg;
5460  bits<9> imm;
5461  let Inst{31-24} = 0b00000101;
5462  let Inst{23-22} = sz8_64;
5463  let Inst{21-20} = 0b01;
5464  let Inst{19-16} = Pg;
5465  let Inst{15}    = 0b0;
5466  let Inst{14}    = m;
5467  let Inst{13}    = imm{8};   // sh
5468  let Inst{12-5}  = imm{7-0}; // imm8
5469  let Inst{4-0}   = Zd;
5470
5471  let DestructiveInstType = DestructiveOther;
5472  let ElementSize = zprty.ElementSize;
5473  let hasSideEffects = 0;
5474}
5475
5476multiclass sve_int_dup_imm_pred_merge_inst<
5477    bits<2> sz8_64, string asm, ZPRRegOp zprty, imm8_opt_lsl cpyimm,
5478    ValueType intty, ValueType predty, ValueType scalarty, ComplexPattern cpx> {
5479  let Constraints = "$Zd = $_Zd" in
5480  def NAME : sve_int_dup_imm_pred<sz8_64, 1, asm, zprty,  "/m",
5481                                  (ins zprty:$_Zd, PPRAny:$Pg, cpyimm:$imm)>;
5482  def : InstAlias<"mov $Zd, $Pg/m, $imm",
5483                  (!cast<Instruction>(NAME) zprty:$Zd, PPRAny:$Pg, cpyimm:$imm), 1>;
5484  def : Pat<(vselect predty:$Pg,
5485                (intty (splat_vector (scalarty (cpx i32:$imm, i32:$shift)))),
5486                ZPR:$Zd),
5487            (!cast<Instruction>(NAME) $Zd, $Pg, $imm, $shift)>;
5488}
5489
5490multiclass sve_int_dup_imm_pred_merge<string asm, SDPatternOperator op> {
5491  defm _B : sve_int_dup_imm_pred_merge_inst<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8,
5492                                            nxv16i8, nxv16i1, i32, SVECpyDupImm8Pat>;
5493  defm _H : sve_int_dup_imm_pred_merge_inst<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16,
5494                                            nxv8i16, nxv8i1, i32, SVECpyDupImm16Pat>;
5495  defm _S : sve_int_dup_imm_pred_merge_inst<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32,
5496                                            nxv4i32, nxv4i1, i32, SVECpyDupImm32Pat>;
5497  defm _D : sve_int_dup_imm_pred_merge_inst<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64,
5498                                            nxv2i64, nxv2i1, i64, SVECpyDupImm64Pat>;
5499
5500  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5501                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, 0, 0), 0>;
5502  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5503                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, 0, 0), 0>;
5504  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5505                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, 0, 0), 0>;
5506
5507  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv8f16 ZPR:$Zd)),
5508            (!cast<Instruction>(NAME # _H) $Zd, $Pg, 0, 0)>;
5509  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv4f16 ZPR:$Zd)),
5510            (!cast<Instruction>(NAME # _S) $Zd, $Pg, 0, 0)>;
5511  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f16 ZPR:$Zd)),
5512            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5513  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv4f32 ZPR:$Zd)),
5514            (!cast<Instruction>(NAME # _S) $Zd, $Pg, 0, 0)>;
5515  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f32 ZPR:$Zd)),
5516            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5517  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f64 ZPR:$Zd)),
5518            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5519
5520  def : Pat<(nxv16i8 (op nxv16i1:$pg, (i32 (SVECpyDupImm8Pat i32:$a, i32:$b)), nxv16i8:$zd)),
5521            (!cast<Instruction>(NAME # _B) $zd, $pg, $a, $b)>;
5522  def : Pat<(nxv8i16 (op nxv8i1:$pg, (i32 (SVECpyDupImm16Pat i32:$a, i32:$b)), nxv8i16:$zd)),
5523            (!cast<Instruction>(NAME # _H) $zd, $pg, $a, $b)>;
5524  def : Pat<(nxv4i32 (op nxv4i1:$pg, (i32 (SVECpyDupImm32Pat i32:$a, i32:$b)), nxv4i32:$zd)),
5525            (!cast<Instruction>(NAME # _S) $zd, $pg, $a, $b)>;
5526  def : Pat<(nxv2i64 (op nxv2i1:$pg, (i64 (SVECpyDupImm64Pat i32:$a, i32:$b)), nxv2i64:$zd)),
5527            (!cast<Instruction>(NAME # _D) $zd, $pg, $a, $b)>;
5528}
5529
5530multiclass sve_int_dup_imm_pred_zero_inst<
5531    bits<2> sz8_64, string asm, ZPRRegOp zprty, imm8_opt_lsl cpyimm,
5532    ValueType intty, ValueType predty, ValueType scalarty, ComplexPattern cpx> {
5533  def NAME : sve_int_dup_imm_pred<sz8_64, 0, asm, zprty, "/z",
5534                                  (ins PPRAny:$Pg, cpyimm:$imm)>;
5535  def : InstAlias<"mov $Zd, $Pg/z, $imm",
5536                  (!cast<Instruction>(NAME) zprty:$Zd, PPRAny:$Pg, cpyimm:$imm), 1>;
5537  def : Pat<(intty (zext (predty PPRAny:$Ps1))),
5538            (!cast<Instruction>(NAME) PPRAny:$Ps1, 1, 0)>;
5539  def : Pat<(intty (sext (predty PPRAny:$Ps1))),
5540            (!cast<Instruction>(NAME) PPRAny:$Ps1, -1, 0)>;
5541  def : Pat<(intty (anyext (predty PPRAny:$Ps1))),
5542            (!cast<Instruction>(NAME) PPRAny:$Ps1, 1, 0)>;
5543  def : Pat<(vselect predty:$Pg,
5544                (intty (splat_vector (scalarty (cpx i32:$imm, i32:$shift)))),
5545                (intty (splat_vector (scalarty 0)))),
5546            (!cast<Instruction>(NAME) $Pg, $imm, $shift)>;
5547}
5548
5549multiclass sve_int_dup_imm_pred_zero<string asm, SDPatternOperator op> {
5550  defm _B : sve_int_dup_imm_pred_zero_inst<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8,
5551                                           nxv16i8, nxv16i1, i32, SVECpyDupImm8Pat>;
5552  defm _H : sve_int_dup_imm_pred_zero_inst<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16,
5553                                           nxv8i16, nxv8i1, i32, SVECpyDupImm16Pat>;
5554  defm _S : sve_int_dup_imm_pred_zero_inst<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32,
5555                                           nxv4i32, nxv4i1, i32, SVECpyDupImm32Pat>;
5556  defm _D : sve_int_dup_imm_pred_zero_inst<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64,
5557                                           nxv2i64, nxv2i1, i64, SVECpyDupImm64Pat>;
5558
5559  def : Pat<(nxv16i8 (op nxv16i1:$pg, (i32 (SVECpyDupImm8Pat i32:$a, i32:$b)), (SVEDup0))),
5560            (!cast<Instruction>(NAME # _B) $pg, $a, $b)>;
5561  def : Pat<(nxv8i16 (op nxv8i1:$pg, (i32 (SVECpyDupImm16Pat i32:$a, i32:$b)), (SVEDup0))),
5562            (!cast<Instruction>(NAME # _H) $pg, $a, $b)>;
5563  def : Pat<(nxv4i32 (op nxv4i1:$pg, (i32 (SVECpyDupImm32Pat i32:$a, i32:$b)), (SVEDup0))),
5564            (!cast<Instruction>(NAME # _S) $pg, $a, $b)>;
5565  def : Pat<(nxv2i64 (op nxv2i1:$pg, (i64 (SVECpyDupImm64Pat i32:$a, i32:$b)), (SVEDup0))),
5566            (!cast<Instruction>(NAME # _D) $pg, $a, $b)>;
5567}
5568
5569//===----------------------------------------------------------------------===//
5570// SVE Integer Compare - Vectors Group
5571//===----------------------------------------------------------------------===//
5572
5573class sve_int_cmp<bit cmp_1, bits<2> sz8_64, bits<3> opc, string asm,
5574                  PPRRegOp pprty, ZPRRegOp zprty1, ZPRRegOp zprty2>
5575: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty1:$Zn, zprty2:$Zm),
5576  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
5577  "",
5578  []>, Sched<[]> {
5579  bits<4> Pd;
5580  bits<3> Pg;
5581  bits<5> Zm;
5582  bits<5> Zn;
5583  let Inst{31-24} = 0b00100100;
5584  let Inst{23-22} = sz8_64;
5585  let Inst{21}    = 0b0;
5586  let Inst{20-16} = Zm;
5587  let Inst{15}    = opc{2};
5588  let Inst{14}    = cmp_1;
5589  let Inst{13}    = opc{1};
5590  let Inst{12-10} = Pg;
5591  let Inst{9-5}   = Zn;
5592  let Inst{4}     = opc{0};
5593  let Inst{3-0}   = Pd;
5594
5595  let Defs = [NZCV];
5596  let ElementSize = pprty.ElementSize;
5597  let hasSideEffects = 0;
5598  let isPTestLike = 1;
5599}
5600
5601multiclass SVE_SETCC_Pat<CondCode cc, CondCode invcc, ValueType predvt,
5602                         ValueType intvt, Instruction cmp> {
5603  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, intvt:$Op3, cc)),
5604            (cmp $Op1, $Op2, $Op3)>;
5605  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, intvt:$Op3, invcc)),
5606            (cmp $Op1, $Op3, $Op2)>;
5607  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (SVEAllActive)), intvt:$Op2, intvt:$Op3, cc))),
5608            (cmp $Pg, $Op2, $Op3)>;
5609  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (SVEAllActive)), intvt:$Op2, intvt:$Op3, invcc))),
5610            (cmp $Pg, $Op3, $Op2)>;
5611}
5612
5613multiclass SVE_SETCC_Pat_With_Zero<CondCode cc, CondCode invcc, ValueType predvt,
5614                                   ValueType intvt, Instruction cmp> {
5615  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, (SVEDup0), cc)),
5616            (cmp $Op1, $Op2)>;
5617  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, (SVEDup0), intvt:$Op2, invcc)),
5618            (cmp $Op1, $Op2)>;
5619  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (SVEAllActive)), intvt:$Op1, (SVEDup0), cc))),
5620            (cmp $Pg, $Op1)>;
5621  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (SVEAllActive)), (SVEDup0), intvt:$Op1, invcc))),
5622            (cmp $Pg, $Op1)>;
5623}
5624
5625multiclass sve_int_cmp_0<bits<3> opc, string asm, CondCode cc, CondCode invcc> {
5626  def _B : sve_int_cmp<0b0, 0b00, opc, asm, PPR8, ZPR8, ZPR8>;
5627  def _H : sve_int_cmp<0b0, 0b01, opc, asm, PPR16, ZPR16, ZPR16>;
5628  def _S : sve_int_cmp<0b0, 0b10, opc, asm, PPR32, ZPR32, ZPR32>;
5629  def _D : sve_int_cmp<0b0, 0b11, opc, asm, PPR64, ZPR64, ZPR64>;
5630
5631  defm : SVE_SETCC_Pat<cc, invcc, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
5632  defm : SVE_SETCC_Pat<cc, invcc, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
5633  defm : SVE_SETCC_Pat<cc, invcc, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
5634  defm : SVE_SETCC_Pat<cc, invcc, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
5635}
5636
5637multiclass sve_int_cmp_0_wide<bits<3> opc, string asm, SDPatternOperator op> {
5638  def _B : sve_int_cmp<0b0, 0b00, opc, asm, PPR8, ZPR8, ZPR64>;
5639  def _H : sve_int_cmp<0b0, 0b01, opc, asm, PPR16, ZPR16, ZPR64>;
5640  def _S : sve_int_cmp<0b0, 0b10, opc, asm, PPR32, ZPR32, ZPR64>;
5641
5642  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
5643  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
5644  def : SVE_3_Op_Pat<nxv4i1,  op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
5645}
5646
5647multiclass sve_int_cmp_1_wide<bits<3> opc, string asm, SDPatternOperator op> {
5648  def _B : sve_int_cmp<0b1, 0b00, opc, asm, PPR8, ZPR8, ZPR64>;
5649  def _H : sve_int_cmp<0b1, 0b01, opc, asm, PPR16, ZPR16, ZPR64>;
5650  def _S : sve_int_cmp<0b1, 0b10, opc, asm, PPR32, ZPR32, ZPR64>;
5651
5652  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
5653  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
5654  def : SVE_3_Op_Pat<nxv4i1,  op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
5655}
5656
5657
5658//===----------------------------------------------------------------------===//
5659// SVE Integer Compare - Signed Immediate Group
5660//===----------------------------------------------------------------------===//
5661
5662class sve_int_scmp_vi<bits<2> sz8_64, bits<3> opc, string asm, PPRRegOp pprty,
5663                      ZPRRegOp zprty,
5664                      Operand immtype>
5665: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, immtype:$imm5),
5666  asm, "\t$Pd, $Pg/z, $Zn, $imm5",
5667  "",
5668  []>, Sched<[]> {
5669  bits<4> Pd;
5670  bits<3> Pg;
5671  bits<5> Zn;
5672  bits<5> imm5;
5673  let Inst{31-24} = 0b00100101;
5674  let Inst{23-22} = sz8_64;
5675  let Inst{21}    = 0b0;
5676  let Inst{20-16} = imm5;
5677  let Inst{15}    = opc{2};
5678  let Inst{14}    = 0b0;
5679  let Inst{13}    = opc{1};
5680  let Inst{12-10} = Pg;
5681  let Inst{9-5}   = Zn;
5682  let Inst{4}     = opc{0};
5683  let Inst{3-0}   = Pd;
5684
5685  let Defs = [NZCV];
5686  let ElementSize = pprty.ElementSize;
5687  let hasSideEffects = 0;
5688  let isPTestLike = 1;
5689}
5690
5691multiclass SVE_SETCC_Imm_Pat<CondCode cc, CondCode commuted_cc,
5692                             ValueType predvt, ValueType intvt,
5693                             Operand immtype, Instruction cmp> {
5694  def : Pat<(predvt (AArch64setcc_z (predvt PPR_3b:$Pg),
5695                                    (intvt ZPR:$Zs1),
5696                                    (intvt (splat_vector (immtype:$imm))),
5697                                    cc)),
5698            (cmp $Pg, $Zs1, immtype:$imm)>;
5699  def : Pat<(predvt (AArch64setcc_z (predvt PPR_3b:$Pg),
5700                                    (intvt (splat_vector (immtype:$imm))),
5701                                    (intvt ZPR:$Zs1),
5702                                    commuted_cc)),
5703            (cmp $Pg, $Zs1, immtype:$imm)>;
5704  def : Pat<(predvt (and predvt:$Pg,
5705                         (AArch64setcc_z_oneuse (predvt (SVEAllActive)),
5706                                         (intvt ZPR:$Zs1),
5707                                         (intvt (splat_vector (immtype:$imm))),
5708                                         cc))),
5709            (cmp $Pg, $Zs1, immtype:$imm)>;
5710  def : Pat<(predvt (and predvt:$Pg,
5711                         (AArch64setcc_z_oneuse (predvt (SVEAllActive)),
5712                                         (intvt (splat_vector (immtype:$imm))),
5713                                         (intvt ZPR:$Zs1),
5714                                         commuted_cc))),
5715            (cmp $Pg, $Zs1, immtype:$imm)>;
5716}
5717
5718multiclass sve_int_scmp_vi<bits<3> opc, string asm, CondCode cc, CondCode commuted_cc> {
5719  def _B : sve_int_scmp_vi<0b00, opc, asm, PPR8, ZPR8, simm5_32b>;
5720  def _H : sve_int_scmp_vi<0b01, opc, asm, PPR16, ZPR16, simm5_32b>;
5721  def _S : sve_int_scmp_vi<0b10, opc, asm, PPR32, ZPR32, simm5_32b>;
5722  def _D : sve_int_scmp_vi<0b11, opc, asm, PPR64, ZPR64, simm5_64b>;
5723
5724  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv16i1, nxv16i8, simm5_32b,
5725                           !cast<Instruction>(NAME # _B)>;
5726  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv8i1,  nxv8i16, simm5_32b,
5727                           !cast<Instruction>(NAME # _H)>;
5728  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv4i1,  nxv4i32, simm5_32b,
5729                           !cast<Instruction>(NAME # _S)>;
5730  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv2i1,  nxv2i64, simm5_64b,
5731                           !cast<Instruction>(NAME # _D)>;
5732}
5733
5734
5735//===----------------------------------------------------------------------===//
5736// SVE Integer Compare - Unsigned Immediate Group
5737//===----------------------------------------------------------------------===//
5738
5739class sve_int_ucmp_vi<bits<2> sz8_64, bits<2> opc, string asm, PPRRegOp pprty,
5740                      ZPRRegOp zprty, Operand immtype>
5741: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, immtype:$imm7),
5742  asm, "\t$Pd, $Pg/z, $Zn, $imm7",
5743  "",
5744  []>, Sched<[]> {
5745  bits<4> Pd;
5746  bits<3> Pg;
5747  bits<5> Zn;
5748  bits<7> imm7;
5749  let Inst{31-24} = 0b00100100;
5750  let Inst{23-22} = sz8_64;
5751  let Inst{21}    = 1;
5752  let Inst{20-14} = imm7;
5753  let Inst{13}    = opc{1};
5754  let Inst{12-10} = Pg;
5755  let Inst{9-5}   = Zn;
5756  let Inst{4}     = opc{0};
5757  let Inst{3-0}   = Pd;
5758
5759  let Defs = [NZCV];
5760  let ElementSize = pprty.ElementSize;
5761  let hasSideEffects = 0;
5762  let isPTestLike = 1;
5763}
5764
5765multiclass sve_int_ucmp_vi<bits<2> opc, string asm, CondCode cc,
5766                           CondCode commuted_cc> {
5767  def _B : sve_int_ucmp_vi<0b00, opc, asm, PPR8, ZPR8, imm0_127>;
5768  def _H : sve_int_ucmp_vi<0b01, opc, asm, PPR16, ZPR16, imm0_127>;
5769  def _S : sve_int_ucmp_vi<0b10, opc, asm, PPR32, ZPR32, imm0_127>;
5770  def _D : sve_int_ucmp_vi<0b11, opc, asm, PPR64, ZPR64, imm0_127_64b>;
5771
5772  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv16i1, nxv16i8, imm0_127,
5773                           !cast<Instruction>(NAME # _B)>;
5774  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv8i1,  nxv8i16, imm0_127,
5775                           !cast<Instruction>(NAME # _H)>;
5776  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv4i1,  nxv4i32, imm0_127,
5777                           !cast<Instruction>(NAME # _S)>;
5778  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv2i1,  nxv2i64, imm0_127_64b,
5779                           !cast<Instruction>(NAME # _D)>;
5780}
5781
5782
5783//===----------------------------------------------------------------------===//
5784// SVE Integer Compare - Scalars Group
5785//===----------------------------------------------------------------------===//
5786
5787class sve_int_cterm<bit sz, bit opc, string asm, RegisterClass rt>
5788: I<(outs), (ins rt:$Rn, rt:$Rm),
5789  asm, "\t$Rn, $Rm",
5790  "",
5791  []>, Sched<[]> {
5792  bits<5> Rm;
5793  bits<5> Rn;
5794  let Inst{31-23} = 0b001001011;
5795  let Inst{22}    = sz;
5796  let Inst{21}    = 0b1;
5797  let Inst{20-16} = Rm;
5798  let Inst{15-10} = 0b001000;
5799  let Inst{9-5}   = Rn;
5800  let Inst{4}     = opc;
5801  let Inst{3-0}   = 0b0000;
5802
5803  let Defs = [NZCV];
5804  let hasSideEffects = 0;
5805}
5806
5807class sve_int_while_rr<bits<2> sz8_64, bits<4> opc, string asm,
5808                       RegisterClass gprty, PPRRegOp pprty>
5809: I<(outs pprty:$Pd), (ins gprty:$Rn, gprty:$Rm),
5810  asm, "\t$Pd, $Rn, $Rm",
5811  "", []>, Sched<[]> {
5812  bits<4> Pd;
5813  bits<5> Rm;
5814  bits<5> Rn;
5815  let Inst{31-24} = 0b00100101;
5816  let Inst{23-22} = sz8_64;
5817  let Inst{21}    = 0b1;
5818  let Inst{20-16} = Rm;
5819  let Inst{15-13} = 0b000;
5820  let Inst{12-10} = opc{3-1};
5821  let Inst{9-5}   = Rn;
5822  let Inst{4}     = opc{0};
5823  let Inst{3-0}   = Pd;
5824
5825  let Defs = [NZCV];
5826  let ElementSize = pprty.ElementSize;
5827  let hasSideEffects = 0;
5828  let isWhile = 1;
5829}
5830
5831multiclass sve_int_while4_rr<bits<3> opc, string asm, SDPatternOperator op,
5832                             SDPatternOperator rev_op> {
5833  def _B : sve_int_while_rr<0b00, { 0, opc }, asm, GPR32, PPR8>;
5834  def _H : sve_int_while_rr<0b01, { 0, opc }, asm, GPR32, PPR16>;
5835  def _S : sve_int_while_rr<0b10, { 0, opc }, asm, GPR32, PPR32>;
5836  def _D : sve_int_while_rr<0b11, { 0, opc }, asm, GPR32, PPR64>;
5837
5838  def : SVE_2_Op_Pat<nxv16i1, op, i32, i32, !cast<Instruction>(NAME # _B)>;
5839  def : SVE_2_Op_Pat<nxv8i1,  op, i32, i32, !cast<Instruction>(NAME # _H)>;
5840  def : SVE_2_Op_Pat<nxv4i1,  op, i32, i32, !cast<Instruction>(NAME # _S)>;
5841  def : SVE_2_Op_Pat<nxv2i1,  op, i32, i32, !cast<Instruction>(NAME # _D)>;
5842
5843  def : Pat<(nxv16i1 (vector_reverse (rev_op i32:$op2, i32:$op1))),
5844            (!cast<Instruction>(NAME # "_B") $op1, $op2)>;
5845  def : Pat<(nxv8i1 (vector_reverse (rev_op i32:$op2, i32:$op1))),
5846            (!cast<Instruction>(NAME # "_H") $op1, $op2)>;
5847  def : Pat<(nxv4i1 (vector_reverse (rev_op i32:$op2, i32:$op1))),
5848            (!cast<Instruction>(NAME # "_S") $op1, $op2)>;
5849  def : Pat<(nxv2i1 (vector_reverse (rev_op i32:$op2, i32:$op1))),
5850            (!cast<Instruction>(NAME # "_D") $op1, $op2)>;
5851}
5852
5853multiclass sve_int_while8_rr<bits<3> opc, string asm, SDPatternOperator op,
5854                             SDPatternOperator rev_op> {
5855  def _B : sve_int_while_rr<0b00, { 1, opc }, asm, GPR64, PPR8>;
5856  def _H : sve_int_while_rr<0b01, { 1, opc }, asm, GPR64, PPR16>;
5857  def _S : sve_int_while_rr<0b10, { 1, opc }, asm, GPR64, PPR32>;
5858  def _D : sve_int_while_rr<0b11, { 1, opc }, asm, GPR64, PPR64>;
5859
5860  def : SVE_2_Op_Pat<nxv16i1, op, i64, i64, !cast<Instruction>(NAME # _B)>;
5861  def : SVE_2_Op_Pat<nxv8i1,  op, i64, i64, !cast<Instruction>(NAME # _H)>;
5862  def : SVE_2_Op_Pat<nxv4i1,  op, i64, i64, !cast<Instruction>(NAME # _S)>;
5863  def : SVE_2_Op_Pat<nxv2i1,  op, i64, i64, !cast<Instruction>(NAME # _D)>;
5864
5865  def : Pat<(nxv16i1 (vector_reverse (rev_op i64:$op2, i64:$op1))),
5866            (!cast<Instruction>(NAME # "_B") $op1, $op2)>;
5867  def : Pat<(nxv8i1 (vector_reverse (rev_op i64:$op2, i64:$op1))),
5868            (!cast<Instruction>(NAME # "_H") $op1, $op2)>;
5869  def : Pat<(nxv4i1 (vector_reverse (rev_op i64:$op2, i64:$op1))),
5870            (!cast<Instruction>(NAME # "_S") $op1, $op2)>;
5871  def : Pat<(nxv2i1 (vector_reverse (rev_op i64:$op2, i64:$op1))),
5872            (!cast<Instruction>(NAME # "_D") $op1, $op2)>;
5873}
5874
5875class sve2_int_while_rr<bits<2> sz8_64, bits<1> rw, string asm,
5876                        PPRRegOp pprty>
5877: I<(outs pprty:$Pd), (ins GPR64:$Rn, GPR64:$Rm),
5878  asm, "\t$Pd, $Rn, $Rm",
5879  "", []>, Sched<[]> {
5880  bits<4> Pd;
5881  bits<5> Rm;
5882  bits<5> Rn;
5883  let Inst{31-24} = 0b00100101;
5884  let Inst{23-22} = sz8_64;
5885  let Inst{21}    = 0b1;
5886  let Inst{20-16} = Rm;
5887  let Inst{15-10} = 0b001100;
5888  let Inst{9-5}   = Rn;
5889  let Inst{4}     = rw;
5890  let Inst{3-0}   = Pd;
5891
5892  let Defs = [NZCV];
5893  let ElementSize = pprty.ElementSize;
5894  let hasSideEffects = 0;
5895  let isWhile = 1;
5896}
5897
5898multiclass sve2_int_while_rr<bits<1> rw, string asm, string op> {
5899  def _B : sve2_int_while_rr<0b00, rw, asm, PPR8>;
5900  def _H : sve2_int_while_rr<0b01, rw, asm, PPR16>;
5901  def _S : sve2_int_while_rr<0b10, rw, asm, PPR32>;
5902  def _D : sve2_int_while_rr<0b11, rw, asm, PPR64>;
5903
5904  def : SVE_2_Op_Pat<nxv16i1, !cast<SDPatternOperator>(op # _b), i64, i64, !cast<Instruction>(NAME # _B)>;
5905  def : SVE_2_Op_Pat<nxv8i1,  !cast<SDPatternOperator>(op # _h), i64, i64, !cast<Instruction>(NAME # _H)>;
5906  def : SVE_2_Op_Pat<nxv4i1,  !cast<SDPatternOperator>(op # _s), i64, i64, !cast<Instruction>(NAME # _S)>;
5907  def : SVE_2_Op_Pat<nxv2i1,  !cast<SDPatternOperator>(op # _d), i64, i64, !cast<Instruction>(NAME # _D)>;
5908}
5909
5910//===----------------------------------------------------------------------===//
5911// SVE Floating Point Fast Reduction Group
5912//===----------------------------------------------------------------------===//
5913
5914class sve_fp_fast_red<bits<2> sz, bits<3> opc, string asm,
5915                      ZPRRegOp zprty, FPRasZPROperand dstOpType>
5916: I<(outs dstOpType:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
5917  asm, "\t$Vd, $Pg, $Zn",
5918  "",
5919  []>, Sched<[]> {
5920  bits<5> Zn;
5921  bits<5> Vd;
5922  bits<3> Pg;
5923  let Inst{31-24} = 0b01100101;
5924  let Inst{23-22} = sz;
5925  let Inst{21-19} = 0b000;
5926  let Inst{18-16} = opc;
5927  let Inst{15-13} = 0b001;
5928  let Inst{12-10} = Pg;
5929  let Inst{9-5}   = Zn;
5930  let Inst{4-0}   = Vd;
5931
5932  let hasSideEffects = 0;
5933  let mayRaiseFPException = 1;
5934}
5935
5936multiclass sve_fp_fast_red<bits<3> opc, string asm, SDPatternOperator op> {
5937  def _H : sve_fp_fast_red<0b01, opc, asm, ZPR16, FPR16asZPR>;
5938  def _S : sve_fp_fast_red<0b10, opc, asm, ZPR32, FPR32asZPR>;
5939  def _D : sve_fp_fast_red<0b11, opc, asm, ZPR64, FPR64asZPR>;
5940
5941  def : SVE_2_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
5942  def : SVE_2_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
5943  def : SVE_2_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
5944  def : SVE_2_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
5945  def : SVE_2_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
5946  def : SVE_2_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
5947}
5948
5949//===----------------------------------------------------------------------===//
5950// SVE Floating Point Accumulating Reduction Group
5951//===----------------------------------------------------------------------===//
5952
5953class sve_fp_2op_p_vd<bits<2> sz, bits<3> opc, string asm,
5954                      ZPRRegOp zprty, FPRasZPROperand dstOpType>
5955: I<(outs dstOpType:$Vdn), (ins PPR3bAny:$Pg, dstOpType:$_Vdn, zprty:$Zm),
5956  asm, "\t$Vdn, $Pg, $_Vdn, $Zm",
5957  "",
5958  []>,
5959  Sched<[]> {
5960  bits<3> Pg;
5961  bits<5> Vdn;
5962  bits<5> Zm;
5963  let Inst{31-24} = 0b01100101;
5964  let Inst{23-22} = sz;
5965  let Inst{21-19} = 0b011;
5966  let Inst{18-16} = opc;
5967  let Inst{15-13} = 0b001;
5968  let Inst{12-10} = Pg;
5969  let Inst{9-5}   = Zm;
5970  let Inst{4-0}   = Vdn;
5971
5972  let Constraints = "$Vdn = $_Vdn";
5973  let hasSideEffects = 0;
5974  let mayRaiseFPException = 1;
5975}
5976
5977multiclass sve_fp_2op_p_vd<bits<3> opc, string asm, SDPatternOperator op> {
5978  def _H : sve_fp_2op_p_vd<0b01, opc, asm, ZPR16, FPR16asZPR>;
5979  def _S : sve_fp_2op_p_vd<0b10, opc, asm, ZPR32, FPR32asZPR>;
5980  def _D : sve_fp_2op_p_vd<0b11, opc, asm, ZPR64, FPR64asZPR>;
5981
5982  def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H)>;
5983  def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H)>;
5984  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
5985  def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S)>;
5986  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
5987  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
5988}
5989
5990//===----------------------------------------------------------------------===//
5991// SVE Floating Point Compare - Vectors Group
5992//===----------------------------------------------------------------------===//
5993
5994class sve_fp_3op_p_pd<bits<2> sz, bits<3> opc, string asm, PPRRegOp pprty,
5995                      ZPRRegOp zprty>
5996: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
5997  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
5998  "",
5999  []>, Sched<[]> {
6000  bits<4> Pd;
6001  bits<3> Pg;
6002  bits<5> Zm;
6003  bits<5> Zn;
6004  let Inst{31-24} = 0b01100101;
6005  let Inst{23-22} = sz;
6006  let Inst{21}    = 0b0;
6007  let Inst{20-16} = Zm;
6008  let Inst{15}    = opc{2};
6009  let Inst{14}    = 0b1;
6010  let Inst{13}    = opc{1};
6011  let Inst{12-10} = Pg;
6012  let Inst{9-5}   = Zn;
6013  let Inst{4}     = opc{0};
6014  let Inst{3-0}   = Pd;
6015
6016  let hasSideEffects = 0;
6017  let mayRaiseFPException = 1;
6018}
6019
6020multiclass sve_fp_3op_p_pd<bits<3> opc, string asm, SDPatternOperator op> {
6021  def _H : sve_fp_3op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
6022  def _S : sve_fp_3op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
6023  def _D : sve_fp_3op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
6024
6025  def : SVE_3_Op_Pat<nxv8i1, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
6026  def : SVE_3_Op_Pat<nxv4i1, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
6027  def : SVE_3_Op_Pat<nxv2i1, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
6028}
6029
6030multiclass sve_fp_3op_p_pd_cc<bits<3> opc, string asm,
6031                              CondCode cc1, CondCode cc2,
6032                              CondCode invcc1, CondCode invcc2> {
6033  def _H : sve_fp_3op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
6034  def _S : sve_fp_3op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
6035  def _D : sve_fp_3op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
6036
6037  defm : SVE_SETCC_Pat<cc1, invcc1, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
6038  defm : SVE_SETCC_Pat<cc1, invcc1, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
6039  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
6040  defm : SVE_SETCC_Pat<cc1, invcc1, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
6041  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
6042  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
6043
6044  defm : SVE_SETCC_Pat<cc2, invcc2, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
6045  defm : SVE_SETCC_Pat<cc2, invcc2, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
6046  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
6047  defm : SVE_SETCC_Pat<cc2, invcc2, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
6048  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
6049  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
6050}
6051
6052//===----------------------------------------------------------------------===//
6053// SVE Floating Point Compare - with Zero Group
6054//===----------------------------------------------------------------------===//
6055
6056class sve_fp_2op_p_pd<bits<2> sz, bits<3> opc, string asm, PPRRegOp pprty,
6057                      ZPRRegOp zprty>
6058: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn),
6059  asm, "\t$Pd, $Pg/z, $Zn, #0.0",
6060  "",
6061  []>, Sched<[]> {
6062  bits<4> Pd;
6063  bits<3> Pg;
6064  bits<5> Zn;
6065  let Inst{31-24} = 0b01100101;
6066  let Inst{23-22} = sz;
6067  let Inst{21-18} = 0b0100;
6068  let Inst{17-16} = opc{2-1};
6069  let Inst{15-13} = 0b001;
6070  let Inst{12-10} = Pg;
6071  let Inst{9-5}   = Zn;
6072  let Inst{4}     = opc{0};
6073  let Inst{3-0}   = Pd;
6074
6075  let hasSideEffects = 0;
6076  let mayRaiseFPException = 1;
6077}
6078
6079multiclass sve_fp_2op_p_pd<bits<3> opc, string asm,
6080                           CondCode cc1, CondCode cc2,
6081                           CondCode invcc1, CondCode invcc2> {
6082  def _H : sve_fp_2op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
6083  def _S : sve_fp_2op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
6084  def _D : sve_fp_2op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
6085
6086  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
6087  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
6088  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
6089  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
6090  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
6091  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
6092
6093  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
6094  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
6095  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
6096  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
6097  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
6098  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
6099}
6100
6101
6102//===----------------------------------------------------------------------===//
6103//SVE Index Generation Group
6104//===----------------------------------------------------------------------===//
6105
6106def simm5_8b_tgt : TImmLeaf<i8, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]>;
6107def simm5_16b_tgt : TImmLeaf<i16, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]>;
6108def simm5_32b_tgt : TImmLeaf<i32, [{ return (int32_t)Imm >= -16 && (int32_t)Imm < 16; }]>;
6109def simm5_64b_tgt : TImmLeaf<i64, [{ return (int64_t)Imm >= -16 && (int64_t)Imm < 16; }]>;
6110def i64imm_32bit_tgt : TImmLeaf<i64, [{
6111  return (Imm & 0xffffffffULL) == static_cast<uint64_t>(Imm);
6112}]>;
6113
6114class sve_int_index_ii<bits<2> sz8_64, string asm, ZPRRegOp zprty,
6115                       Operand imm_ty>
6116: I<(outs zprty:$Zd), (ins imm_ty:$imm5, imm_ty:$imm5b),
6117  asm, "\t$Zd, $imm5, $imm5b",
6118  "", []>, Sched<[]> {
6119  bits<5> Zd;
6120  bits<5> imm5;
6121  bits<5> imm5b;
6122  let Inst{31-24} = 0b00000100;
6123  let Inst{23-22} = sz8_64;
6124  let Inst{21}    = 0b1;
6125  let Inst{20-16} = imm5b;
6126  let Inst{15-10} = 0b010000;
6127  let Inst{9-5}   = imm5;
6128  let Inst{4-0}   = Zd;
6129
6130  let hasSideEffects = 0;
6131  let isReMaterializable = 1;
6132  let Uses = [VG];
6133}
6134
6135multiclass sve_int_index_ii<string asm> {
6136  def _B : sve_int_index_ii<0b00, asm, ZPR8, simm5_8b>;
6137  def _H : sve_int_index_ii<0b01, asm, ZPR16, simm5_16b>;
6138  def _S : sve_int_index_ii<0b10, asm, ZPR32, simm5_32b>;
6139  def _D : sve_int_index_ii<0b11, asm, ZPR64, simm5_64b>;
6140
6141  def : Pat<(nxv16i8 (step_vector simm5_8b_tgt:$imm5b)),
6142            (!cast<Instruction>(NAME # "_B") (i32 0), (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
6143  def : Pat<(nxv8i16 (step_vector simm5_16b_tgt:$imm5b)),
6144            (!cast<Instruction>(NAME # "_H") (i32 0), (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
6145  def : Pat<(nxv4i32 (step_vector simm5_32b_tgt:$imm5b)),
6146            (!cast<Instruction>(NAME # "_S") (i32 0), simm5_32b:$imm5b)>;
6147  def : Pat<(nxv2i64 (step_vector simm5_64b_tgt:$imm5b)),
6148            (!cast<Instruction>(NAME # "_D") (i64 0), simm5_64b:$imm5b)>;
6149
6150  // add(step_vector(step), dup(X)) -> index(X, step).
6151  def : Pat<(add (nxv16i8 (step_vector_oneuse simm5_8b_tgt:$imm5b)), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
6152            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
6153  def : Pat<(add (nxv8i16 (step_vector_oneuse simm5_16b_tgt:$imm5b)), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
6154            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
6155  def : Pat<(add (nxv4i32 (step_vector_oneuse simm5_32b_tgt:$imm5b)), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
6156            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, simm5_32b:$imm5b)>;
6157  def : Pat<(add (nxv2i64 (step_vector_oneuse simm5_64b_tgt:$imm5b)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
6158            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, simm5_64b:$imm5b)>;
6159}
6160
6161class sve_int_index_ir<bits<2> sz8_64, string asm, ZPRRegOp zprty,
6162                       RegisterClass srcRegType, Operand imm_ty>
6163: I<(outs zprty:$Zd), (ins imm_ty:$imm5, srcRegType:$Rm),
6164  asm, "\t$Zd, $imm5, $Rm",
6165  "", []>, Sched<[]> {
6166  bits<5> Rm;
6167  bits<5> Zd;
6168  bits<5> imm5;
6169  let Inst{31-24} = 0b00000100;
6170  let Inst{23-22} = sz8_64;
6171  let Inst{21}    = 0b1;
6172  let Inst{20-16} = Rm;
6173  let Inst{15-10} = 0b010010;
6174  let Inst{9-5}   = imm5;
6175  let Inst{4-0}   = Zd;
6176
6177  let hasSideEffects = 0;
6178}
6179
6180multiclass sve_int_index_ir<string asm, SDPatternOperator mulop, SDPatternOperator muloneuseop> {
6181  def _B : sve_int_index_ir<0b00, asm, ZPR8, GPR32, simm5_8b>;
6182  def _H : sve_int_index_ir<0b01, asm, ZPR16, GPR32, simm5_16b>;
6183  def _S : sve_int_index_ir<0b10, asm, ZPR32, GPR32, simm5_32b>;
6184  def _D : sve_int_index_ir<0b11, asm, ZPR64, GPR64, simm5_64b>;
6185
6186  def : Pat<(nxv16i8 (step_vector i8:$imm)),
6187            (!cast<Instruction>(NAME # "_B") (i32 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
6188  def : Pat<(nxv8i16 (step_vector i16:$imm)),
6189            (!cast<Instruction>(NAME # "_H") (i32 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
6190  def : Pat<(nxv4i32 (step_vector i32:$imm)),
6191            (!cast<Instruction>(NAME # "_S") (i32 0), (!cast<Instruction>("MOVi32imm") $imm))>;
6192  def : Pat<(nxv2i64 (step_vector i64:$imm)),
6193            (!cast<Instruction>(NAME # "_D") (i64 0), (!cast<Instruction>("MOVi64imm") $imm))>;
6194  def : Pat<(nxv2i64 (step_vector i64imm_32bit_tgt:$imm)),
6195            (!cast<Instruction>(NAME # "_D") (i64 0), (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
6196
6197  // add(step_vector(step), dup(X)) -> index(X, step).
6198  def : Pat<(add (nxv16i8 (step_vector_oneuse i8:$imm)), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
6199            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
6200  def : Pat<(add (nxv8i16 (step_vector_oneuse i16:$imm)), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
6201            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
6202  def : Pat<(add (nxv4i32 (step_vector_oneuse i32:$imm)), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
6203            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, (!cast<Instruction>("MOVi32imm") $imm))>;
6204  def : Pat<(add (nxv2i64 (step_vector_oneuse i64:$imm)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
6205            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, (!cast<Instruction>("MOVi64imm") $imm))>;
6206  def : Pat<(add (nxv2i64 (step_vector_oneuse i64imm_32bit_tgt:$imm)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
6207            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
6208
6209  // mul(step_vector(1), dup(Y)) -> index(0, Y).
6210  def : Pat<(mulop (nxv16i1 (SVEAllActive)), (nxv16i8 (step_vector_oneuse (i8 1))), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))),
6211            (!cast<Instruction>(NAME # "_B") (i32 0), GPR32:$Rm)>;
6212  def : Pat<(mulop (nxv8i1 (SVEAllActive)), (nxv8i16 (step_vector_oneuse (i16 1))), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),
6213            (!cast<Instruction>(NAME # "_H") (i32 0), GPR32:$Rm)>;
6214  def : Pat<(mulop (nxv4i1 (SVEAllActive)), (nxv4i32 (step_vector_oneuse (i32 1))), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),
6215            (!cast<Instruction>(NAME # "_S") (i32 0), GPR32:$Rm)>;
6216  def : Pat<(mulop (nxv2i1 (SVEAllActive)), (nxv2i64 (step_vector_oneuse (i64 1))), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),
6217            (!cast<Instruction>(NAME # "_D") (i64 0), GPR64:$Rm)>;
6218
6219  // add(mul(step_vector(1), dup(Y)), dup(X)) -> index(X, Y).
6220  def : Pat<(add (muloneuseop (nxv16i1 (SVEAllActive)), (nxv16i8 (step_vector_oneuse (i8 1))), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
6221            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, GPR32:$Rm)>;
6222  def : Pat<(add (muloneuseop (nxv8i1 (SVEAllActive)), (nxv8i16 (step_vector_oneuse (i16 1))), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
6223            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, GPR32:$Rm)>;
6224  def : Pat<(add (muloneuseop (nxv4i1 (SVEAllActive)), (nxv4i32 (step_vector_oneuse (i32 1))), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
6225            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, GPR32:$Rm)>;
6226  def : Pat<(add (muloneuseop (nxv2i1 (SVEAllActive)), (nxv2i64 (step_vector_oneuse (i64 1))), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
6227            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, GPR64:$Rm)>;
6228}
6229
6230class sve_int_index_ri<bits<2> sz8_64, string asm, ZPRRegOp zprty,
6231                       RegisterClass srcRegType, Operand imm_ty>
6232: I<(outs zprty:$Zd), (ins srcRegType:$Rn, imm_ty:$imm5),
6233  asm, "\t$Zd, $Rn, $imm5",
6234  "", []>, Sched<[]> {
6235  bits<5> Rn;
6236  bits<5> Zd;
6237  bits<5> imm5;
6238  let Inst{31-24} = 0b00000100;
6239  let Inst{23-22} = sz8_64;
6240  let Inst{21}    = 0b1;
6241  let Inst{20-16} = imm5;
6242  let Inst{15-10} = 0b010001;
6243  let Inst{9-5}   = Rn;
6244  let Inst{4-0}   = Zd;
6245
6246  let hasSideEffects = 0;
6247}
6248
6249multiclass sve_int_index_ri<string asm> {
6250  def _B : sve_int_index_ri<0b00, asm, ZPR8, GPR32, simm5_8b>;
6251  def _H : sve_int_index_ri<0b01, asm, ZPR16, GPR32, simm5_16b>;
6252  def _S : sve_int_index_ri<0b10, asm, ZPR32, GPR32, simm5_32b>;
6253  def _D : sve_int_index_ri<0b11, asm, ZPR64, GPR64, simm5_64b>;
6254
6255  // add(step_vector(step), dup(X)) -> index(X, step).
6256  def : Pat<(add (nxv16i8 (step_vector_oneuse simm5_8b_tgt:$imm5)), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))),
6257            (!cast<Instruction>(NAME # "_B") GPR32:$Rm, (!cast<SDNodeXForm>("trunc_imm") $imm5))>;
6258  def : Pat<(add (nxv8i16 (step_vector_oneuse simm5_16b_tgt:$imm5)), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),
6259            (!cast<Instruction>(NAME # "_H") GPR32:$Rm, (!cast<SDNodeXForm>("trunc_imm") $imm5))>;
6260  def : Pat<(add (nxv4i32 (step_vector_oneuse simm5_32b_tgt:$imm5)), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),
6261            (!cast<Instruction>(NAME # "_S") GPR32:$Rm, simm5_32b:$imm5)>;
6262  def : Pat<(add (nxv2i64 (step_vector_oneuse simm5_64b_tgt:$imm5)), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),
6263            (!cast<Instruction>(NAME # "_D") GPR64:$Rm, simm5_64b:$imm5)>;
6264}
6265
6266class sve_int_index_rr<bits<2> sz8_64, string asm, ZPRRegOp zprty,
6267                       RegisterClass srcRegType>
6268: I<(outs zprty:$Zd), (ins srcRegType:$Rn, srcRegType:$Rm),
6269  asm, "\t$Zd, $Rn, $Rm",
6270  "", []>, Sched<[]> {
6271  bits<5> Zd;
6272  bits<5> Rm;
6273  bits<5> Rn;
6274  let Inst{31-24} = 0b00000100;
6275  let Inst{23-22} = sz8_64;
6276  let Inst{21}    = 0b1;
6277  let Inst{20-16} = Rm;
6278  let Inst{15-10} = 0b010011;
6279  let Inst{9-5}   = Rn;
6280  let Inst{4-0}   = Zd;
6281
6282  let hasSideEffects = 0;
6283}
6284
6285multiclass sve_int_index_rr<string asm, SDPatternOperator mulop> {
6286  def _B : sve_int_index_rr<0b00, asm, ZPR8, GPR32>;
6287  def _H : sve_int_index_rr<0b01, asm, ZPR16, GPR32>;
6288  def _S : sve_int_index_rr<0b10, asm, ZPR32, GPR32>;
6289  def _D : sve_int_index_rr<0b11, asm, ZPR64, GPR64>;
6290
6291  // add(step_vector(step), dup(X)) -> index(X, step).
6292  def : Pat<(add (nxv16i8 (step_vector_oneuse i8:$imm)), (nxv16i8 (splat_vector(i32 GPR32:$Rn)))),
6293            (!cast<Instruction>(NAME # "_B") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
6294  def : Pat<(add (nxv8i16 (step_vector_oneuse i16:$imm)), (nxv8i16 (splat_vector(i32 GPR32:$Rn)))),
6295            (!cast<Instruction>(NAME # "_H") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
6296  def : Pat<(add (nxv4i32 (step_vector_oneuse i32:$imm)), (nxv4i32 (splat_vector(i32 GPR32:$Rn)))),
6297            (!cast<Instruction>(NAME # "_S") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") $imm))>;
6298  def : Pat<(add (nxv2i64 (step_vector_oneuse i64:$imm)), (nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
6299            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, (!cast<Instruction>("MOVi64imm") $imm))>;
6300  def : Pat<(add (nxv2i64 (step_vector_oneuse i64imm_32bit_tgt:$imm)), (nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
6301            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
6302
6303  // add(mul(step_vector(1), dup(Y)), dup(X)) -> index(X, Y).
6304  def : Pat<(add (mulop (nxv16i1 (SVEAllActive)), (nxv16i8 (step_vector_oneuse (i8 1))), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))), (nxv16i8 (splat_vector(i32 GPR32:$Rn)))),
6305            (!cast<Instruction>(NAME # "_B") GPR32:$Rn, GPR32:$Rm)>;
6306  def : Pat<(add (mulop (nxv8i1 (SVEAllActive)), (nxv8i16 (step_vector_oneuse (i16 1))), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),(nxv8i16 (splat_vector(i32 GPR32:$Rn)))),
6307            (!cast<Instruction>(NAME # "_H") GPR32:$Rn, GPR32:$Rm)>;
6308  def : Pat<(add (mulop (nxv4i1 (SVEAllActive)), (nxv4i32 (step_vector_oneuse (i32 1))), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),(nxv4i32 (splat_vector(i32 GPR32:$Rn)))),
6309            (!cast<Instruction>(NAME # "_S") GPR32:$Rn, GPR32:$Rm)>;
6310  def : Pat<(add (mulop (nxv2i1 (SVEAllActive)), (nxv2i64 (step_vector_oneuse (i64 1))), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),(nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
6311            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, GPR64:$Rm)>;
6312}
6313
6314//===----------------------------------------------------------------------===//
6315// SVE Bitwise Shift - Predicated Group
6316//===----------------------------------------------------------------------===//
6317
6318class sve_int_bin_pred_shift_imm<bits<4> tsz8_64, bits<4> opc, string asm,
6319                                 ZPRRegOp zprty, Operand immtype>
6320: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, immtype:$imm),
6321  asm, "\t$Zdn, $Pg/m, $_Zdn, $imm",
6322  "",
6323  []>, Sched<[]> {
6324  bits<3> Pg;
6325  bits<5> Zdn;
6326  bits<6> imm;
6327  let Inst{31-24} = 0b00000100;
6328  let Inst{23-22} = tsz8_64{3-2};
6329  let Inst{21-20} = 0b00;
6330  let Inst{19-16} = opc;
6331  let Inst{15-13} = 0b100;
6332  let Inst{12-10} = Pg;
6333  let Inst{9-8}   = tsz8_64{1-0};
6334  let Inst{7-5}   = imm{2-0}; // imm3
6335  let Inst{4-0}   = Zdn;
6336
6337  let Constraints = "$Zdn = $_Zdn";
6338  let DestructiveInstType = DestructiveBinaryImm;
6339  let ElementSize = zprty.ElementSize;
6340  let hasSideEffects = 0;
6341}
6342
6343multiclass sve_int_bin_pred_shift_imm_left<bits<4> opc, string asm, string Ps,
6344                                           SDPatternOperator op = null_frag> {
6345  def _B : SVEPseudo2Instr<Ps # _B, 1>,
6346           sve_int_bin_pred_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
6347  def _H : SVEPseudo2Instr<Ps # _H, 1>,
6348           sve_int_bin_pred_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
6349    let Inst{8} = imm{3};
6350  }
6351  def _S : SVEPseudo2Instr<Ps # _S, 1>,
6352           sve_int_bin_pred_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
6353    let Inst{9-8} = imm{4-3};
6354  }
6355  def _D : SVEPseudo2Instr<Ps # _D, 1>,
6356           sve_int_bin_pred_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
6357    let Inst{22}  = imm{5};
6358    let Inst{9-8} = imm{4-3};
6359  }
6360
6361  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i1, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _B)>;
6362  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i1,  nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _H)>;
6363  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i1,  nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _S)>;
6364  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i1,  nxv2i64, i32, tvecshiftL64, !cast<Instruction>(NAME # _D)>;
6365}
6366
6367// As above but shift amount takes the form of a "vector immediate".
6368multiclass sve_int_bin_pred_shift_imm_left_dup<bits<4> opc, string asm,
6369                                               string Ps, SDPatternOperator op>
6370: sve_int_bin_pred_shift_imm_left<opc, asm, Ps, null_frag> {
6371  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8,  !cast<Instruction>(NAME # _B)>;
6372  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
6373  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
6374  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
6375}
6376
6377multiclass sve_int_bin_pred_shift_imm_left_zeroing_bhsd<SDPatternOperator op> {
6378  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8,  tvecshiftL8,  FalseLanesZero>;
6379  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, tvecshiftL16, FalseLanesZero>;
6380  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, tvecshiftL32, FalseLanesZero>;
6381  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, tvecshiftL64, FalseLanesZero>;
6382
6383  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv16i8, op, nxv16i1, nxv16i8, tvecshiftL8,  !cast<Pseudo>(NAME # _B_ZERO)>;
6384  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv8i16, op, nxv8i1,  nxv8i16, tvecshiftL16, !cast<Pseudo>(NAME # _H_ZERO)>;
6385  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv4i32, op, nxv4i1,  nxv4i32, tvecshiftL32, !cast<Pseudo>(NAME # _S_ZERO)>;
6386  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv2i64, op, nxv2i1,  nxv2i64, tvecshiftL64, !cast<Pseudo>(NAME # _D_ZERO)>;
6387}
6388
6389multiclass sve_int_bin_pred_shift_imm_right<bits<4> opc, string asm, string Ps,
6390                                            SDPatternOperator op = null_frag> {
6391  def _B : SVEPseudo2Instr<Ps # _B, 1>,
6392           sve_int_bin_pred_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
6393  def _H : SVEPseudo2Instr<Ps # _H, 1>,
6394           sve_int_bin_pred_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
6395    let Inst{8} = imm{3};
6396  }
6397  def _S : SVEPseudo2Instr<Ps # _S, 1>,
6398           sve_int_bin_pred_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
6399    let Inst{9-8} = imm{4-3};
6400  }
6401  def _D : SVEPseudo2Instr<Ps # _D, 1>,
6402           sve_int_bin_pred_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
6403    let Inst{22}  = imm{5};
6404    let Inst{9-8} = imm{4-3};
6405  }
6406
6407  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i1, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
6408  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i1,  nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
6409  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i1,  nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
6410  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i1,  nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
6411}
6412
6413// As above but shift amount takes the form of a "vector immediate".
6414multiclass sve_int_bin_pred_shift_imm_right_dup<bits<4> opc, string asm,
6415                                            string Ps, SDPatternOperator op>
6416: sve_int_bin_pred_shift_imm_right<opc, asm, Ps, null_frag> {
6417  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8,  !cast<Instruction>(NAME # _B)>;
6418  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
6419  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
6420  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
6421}
6422
6423multiclass sve_int_bin_pred_shift_imm_right_zeroing_bhsd<SDPatternOperator op = null_frag> {
6424  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8, vecshiftR8, FalseLanesZero>;
6425  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, vecshiftR16, FalseLanesZero>;
6426  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, vecshiftR32, FalseLanesZero>;
6427  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, vecshiftR64, FalseLanesZero>;
6428
6429  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv16i8, op, nxv16i1, nxv16i8, tvecshiftR8, !cast<Pseudo>(NAME # _B_ZERO)>;
6430  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv8i16, op, nxv8i1, nxv8i16, tvecshiftR16, !cast<Pseudo>(NAME # _H_ZERO)>;
6431  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv4i32, op, nxv4i1, nxv4i32, tvecshiftR32, !cast<Pseudo>(NAME # _S_ZERO)>;
6432  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv2i64, op, nxv2i1, nxv2i64, tvecshiftR64, !cast<Pseudo>(NAME # _D_ZERO)>;
6433}
6434
6435class sve_int_bin_pred_shift<bits<2> sz8_64, bit wide, bits<3> opc,
6436                             string asm, ZPRRegOp zprty, ZPRRegOp zprty2>
6437: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty2:$Zm),
6438  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
6439  "",
6440  []>, Sched<[]> {
6441  bits<3> Pg;
6442  bits<5> Zdn;
6443  bits<5> Zm;
6444  let Inst{31-24} = 0b00000100;
6445  let Inst{23-22} = sz8_64;
6446  let Inst{21-20} = 0b01;
6447  let Inst{19}    = wide;
6448  let Inst{18-16} = opc;
6449  let Inst{15-13} = 0b100;
6450  let Inst{12-10} = Pg;
6451  let Inst{9-5}   = Zm;
6452  let Inst{4-0}   = Zdn;
6453
6454  let Constraints = "$Zdn = $_Zdn";
6455  let DestructiveInstType = DestructiveOther;
6456  let ElementSize = zprty.ElementSize;
6457  let hasSideEffects = 0;
6458}
6459
6460multiclass sve_int_bin_pred_shift<bits<3> opc, string asm, string Ps,
6461                                  SDPatternOperator op, string revname, bit isReverseInstr = 0> {
6462  let DestructiveInstType = DestructiveBinaryCommWithRev in {
6463  def _B : sve_int_bin_pred_shift<0b00, 0b0, opc, asm, ZPR8, ZPR8>,
6464           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
6465  def _H : sve_int_bin_pred_shift<0b01, 0b0, opc, asm, ZPR16, ZPR16>,
6466           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
6467  def _S : sve_int_bin_pred_shift<0b10, 0b0, opc, asm, ZPR32, ZPR32>,
6468           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
6469  def _D : sve_int_bin_pred_shift<0b11, 0b0, opc, asm, ZPR64, ZPR64>,
6470           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
6471  }
6472  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
6473  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
6474  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
6475  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
6476}
6477
6478multiclass sve_int_bin_pred_zeroing_bhsd<SDPatternOperator op> {
6479  def _B_ZERO : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesZero>;
6480  def _H_ZERO : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesZero>;
6481  def _S_ZERO : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesZero>;
6482  def _D_ZERO : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesZero>;
6483
6484  def : SVE_3_Op_Pat_SelZero<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_ZERO)>;
6485  def : SVE_3_Op_Pat_SelZero<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_ZERO)>;
6486  def : SVE_3_Op_Pat_SelZero<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_ZERO)>;
6487  def : SVE_3_Op_Pat_SelZero<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_ZERO)>;
6488}
6489
6490multiclass sve_int_bin_pred_imm_zeroing_bhsd<SDPatternOperator op,
6491                                   ComplexPattern imm_b, ComplexPattern imm_h,
6492                                   ComplexPattern imm_s, ComplexPattern imm_d> {
6493  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8,  Operand<i32>, FalseLanesZero>;
6494  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, Operand<i32>, FalseLanesZero>;
6495  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, Operand<i32>, FalseLanesZero>;
6496  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, Operand<i32>, FalseLanesZero>;
6497
6498  def : SVE_2_Op_Imm_Pat_Zero<nxv16i8, op, nxv16i1, i32, imm_b, !cast<Pseudo>(NAME # _B_ZERO)>;
6499  def : SVE_2_Op_Imm_Pat_Zero<nxv8i16, op, nxv8i1,  i32, imm_h, !cast<Pseudo>(NAME # _H_ZERO)>;
6500  def : SVE_2_Op_Imm_Pat_Zero<nxv4i32, op, nxv4i1,  i32, imm_s, !cast<Pseudo>(NAME # _S_ZERO)>;
6501  def : SVE_2_Op_Imm_Pat_Zero<nxv2i64, op, nxv2i1,  i64, imm_d, !cast<Pseudo>(NAME # _D_ZERO)>;
6502}
6503
6504multiclass sve_int_bin_pred_shift_wide<bits<3> opc, string asm,
6505                                  SDPatternOperator op> {
6506  def _B : sve_int_bin_pred_shift<0b00, 0b1, opc, asm, ZPR8, ZPR64>;
6507  def _H : sve_int_bin_pred_shift<0b01, 0b1, opc, asm, ZPR16, ZPR64>;
6508  def _S : sve_int_bin_pred_shift<0b10, 0b1, opc, asm, ZPR32, ZPR64>;
6509
6510  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
6511  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
6512  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
6513}
6514
6515//===----------------------------------------------------------------------===//
6516// SVE Shift - Unpredicated Group
6517//===----------------------------------------------------------------------===//
6518
6519class sve_int_bin_cons_shift_wide<bits<2> sz8_64, bits<2> opc, string asm,
6520                               ZPRRegOp zprty>
6521: I<(outs zprty:$Zd), (ins zprty:$Zn, ZPR64:$Zm),
6522  asm, "\t$Zd, $Zn, $Zm",
6523  "",
6524  []>, Sched<[]> {
6525  bits<5> Zd;
6526  bits<5> Zm;
6527  bits<5> Zn;
6528  let Inst{31-24} = 0b00000100;
6529  let Inst{23-22} = sz8_64;
6530  let Inst{21}    = 0b1;
6531  let Inst{20-16} = Zm;
6532  let Inst{15-12} = 0b1000;
6533  let Inst{11-10} = opc;
6534  let Inst{9-5}   = Zn;
6535  let Inst{4-0}   = Zd;
6536
6537  let hasSideEffects = 0;
6538}
6539
6540multiclass sve_int_bin_cons_shift_wide<bits<2> opc, string asm, SDPatternOperator op> {
6541  def _B : sve_int_bin_cons_shift_wide<0b00, opc, asm, ZPR8>;
6542  def _H : sve_int_bin_cons_shift_wide<0b01, opc, asm, ZPR16>;
6543  def _S : sve_int_bin_cons_shift_wide<0b10, opc, asm, ZPR32>;
6544
6545  def : SVE_2_Op_Pred_All_Active<nxv16i8, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
6546  def : SVE_2_Op_Pred_All_Active<nxv8i16, op, nxv8i1, nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
6547  def : SVE_2_Op_Pred_All_Active<nxv4i32, op, nxv4i1, nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
6548}
6549
6550class sve_int_bin_cons_shift_imm<bits<4> tsz8_64, bits<2> opc, string asm,
6551                               ZPRRegOp zprty, Operand immtype>
6552: I<(outs zprty:$Zd), (ins zprty:$Zn, immtype:$imm),
6553  asm, "\t$Zd, $Zn, $imm",
6554  "",
6555  []>, Sched<[]> {
6556  bits<5> Zd;
6557  bits<5> Zn;
6558  bits<6> imm;
6559  let Inst{31-24} = 0b00000100;
6560  let Inst{23-22} = tsz8_64{3-2};
6561  let Inst{21}    = 0b1;
6562  let Inst{20-19} = tsz8_64{1-0};
6563  let Inst{18-16} = imm{2-0}; // imm3
6564  let Inst{15-12} = 0b1001;
6565  let Inst{11-10} = opc;
6566  let Inst{9-5}   = Zn;
6567  let Inst{4-0}   = Zd;
6568
6569  let hasSideEffects = 0;
6570}
6571
6572multiclass sve_int_bin_cons_shift_imm_left<bits<2> opc, string asm,
6573                                           SDPatternOperator op> {
6574  def _B : sve_int_bin_cons_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
6575  def _H : sve_int_bin_cons_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
6576    let Inst{19} = imm{3};
6577  }
6578  def _S : sve_int_bin_cons_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
6579    let Inst{20-19} = imm{4-3};
6580  }
6581  def _D : sve_int_bin_cons_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
6582    let Inst{22}    = imm{5};
6583    let Inst{20-19} = imm{4-3};
6584  }
6585
6586  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8,  !cast<Instruction>(NAME # _B)>;
6587  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
6588  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
6589  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
6590}
6591
6592multiclass sve_int_bin_cons_shift_imm_right<bits<2> opc, string asm,
6593                                            SDPatternOperator op> {
6594  def _B : sve_int_bin_cons_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
6595  def _H : sve_int_bin_cons_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
6596    let Inst{19} = imm{3};
6597  }
6598  def _S : sve_int_bin_cons_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
6599    let Inst{20-19} = imm{4-3};
6600  }
6601  def _D : sve_int_bin_cons_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
6602    let Inst{22}    = imm{5};
6603    let Inst{20-19} = imm{4-3};
6604  }
6605
6606  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8,  !cast<Instruction>(NAME # _B)>;
6607  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
6608  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
6609  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
6610}
6611
6612//===----------------------------------------------------------------------===//
6613// SVE Memory - Store Group
6614//===----------------------------------------------------------------------===//
6615
6616class sve_mem_cst_si<bits<2> msz, bits<2> esz, string asm,
6617                     RegisterOperand VecList>
6618: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
6619  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6620  "",
6621  []>, Sched<[]> {
6622  bits<3> Pg;
6623  bits<5> Rn;
6624  bits<5> Zt;
6625  bits<4> imm4;
6626  let Inst{31-25} = 0b1110010;
6627  let Inst{24-23} = msz;
6628  let Inst{22-21} = esz;
6629  let Inst{20}    = 0;
6630  let Inst{19-16} = imm4;
6631  let Inst{15-13} = 0b111;
6632  let Inst{12-10} = Pg;
6633  let Inst{9-5}   = Rn;
6634  let Inst{4-0}   = Zt;
6635
6636  let hasSideEffects = 0;
6637  let mayStore = 1;
6638}
6639
6640multiclass sve_mem_cst_si<bits<2> msz, bits<2> esz, string asm,
6641                          RegisterOperand listty, ZPRRegOp zprty>
6642{
6643  def NAME : sve_mem_cst_si<msz, esz, asm, listty>;
6644
6645  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6646                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
6647  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6648                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
6649  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6650                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6651}
6652
6653class sve_mem_est_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6654                     string asm, Operand immtype>
6655: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
6656  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6657  "",
6658  []>, Sched<[]> {
6659  bits<3> Pg;
6660  bits<5> Rn;
6661  bits<5> Zt;
6662  bits<4> imm4;
6663  let Inst{31-25} = 0b1110010;
6664  let Inst{24-23} = sz;
6665  let Inst{22-21} = nregs;
6666  let Inst{20}    = 1;
6667  let Inst{19-16} = imm4;
6668  let Inst{15-13} = 0b111;
6669  let Inst{12-10} = Pg;
6670  let Inst{9-5}   = Rn;
6671  let Inst{4-0}   = Zt;
6672
6673  let hasSideEffects = 0;
6674  let mayStore = 1;
6675}
6676
6677multiclass sve_mem_est_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6678                          string asm, Operand immtype> {
6679  def NAME : sve_mem_est_si<sz, nregs, VecList, asm, immtype>;
6680
6681  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6682                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6683}
6684
6685
6686// SVE store multiple structures (quadwords, scalar plus immediate)
6687class sve_mem_128b_est_si<bits<2> nregs, RegisterOperand VecList,
6688                          string asm, Operand immtype>
6689    : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
6690        asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6691        "", []>, Sched<[]> {
6692  bits<5> Zt;
6693  bits<5> Rn;
6694  bits<3> Pg;
6695  bits<4> imm4;
6696  let Inst{31-24} = 0b11100100;
6697  let Inst{23-22} = nregs;
6698  let Inst{21-20} = 0b00;
6699  let Inst{19-16} = imm4;
6700  let Inst{15-13} = 0b000;
6701  let Inst{12-10} = Pg;
6702  let Inst{9-5}   = Rn;
6703  let Inst{4-0}   = Zt;
6704
6705  let hasSideEffects = 0;
6706  let mayStore = 1;
6707}
6708
6709multiclass sve_mem_128b_est_si<bits<2> nregs, RegisterOperand VecList,
6710                               string asm, Operand immtype> {
6711  def NAME : sve_mem_128b_est_si<nregs, VecList, asm, immtype>;
6712
6713  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6714                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6715}
6716
6717
6718class sve_mem_est_ss<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6719                     string asm, RegisterOperand gprty>
6720: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6721  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6722  "",
6723  []>, Sched<[]> {
6724  bits<3> Pg;
6725  bits<5> Rm;
6726  bits<5> Rn;
6727  bits<5> Zt;
6728  let Inst{31-25} = 0b1110010;
6729  let Inst{24-23} = sz;
6730  let Inst{22-21} = nregs;
6731  let Inst{20-16} = Rm;
6732  let Inst{15-13} = 0b011;
6733  let Inst{12-10} = Pg;
6734  let Inst{9-5}   = Rn;
6735  let Inst{4-0}   = Zt;
6736
6737  let hasSideEffects = 0;
6738  let mayStore = 1;
6739}
6740
6741
6742// SVE store multiple structures (quadwords, scalar plus scalar)
6743class sve_mem_128b_est_ss<bits<2> nregs, RegisterOperand VecList,
6744                          string asm, RegisterOperand gprty>
6745    : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6746        asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6747        "", []>, Sched<[]> {
6748  bits<5> Zt;
6749  bits<5> Rn;
6750  bits<3> Pg;
6751  bits<5> Rm;
6752  let Inst{31-24} = 0b11100100;
6753  let Inst{23-22} = nregs;
6754  let Inst{21}    = 0b1;
6755  let Inst{20-16} = Rm;
6756  let Inst{15-13} = 0b000;
6757  let Inst{12-10} = Pg;
6758  let Inst{9-5}   = Rn;
6759  let Inst{4-0}   = Zt;
6760
6761  let hasSideEffects = 0;
6762  let mayStore = 1;
6763}
6764
6765
6766class sve_mem_cst_ss_base<bits<4> dtype, string asm,
6767                          RegisterOperand listty, RegisterOperand gprty>
6768: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6769  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6770  "",
6771  []>, Sched<[]> {
6772  bits<3> Pg;
6773  bits<5> Rm;
6774  bits<5> Rn;
6775  bits<5> Zt;
6776  let Inst{31-25} = 0b1110010;
6777  let Inst{24-21} = dtype;
6778  let Inst{20-16} = Rm;
6779  let Inst{15-13} = 0b010;
6780  let Inst{12-10} = Pg;
6781  let Inst{9-5}   = Rn;
6782  let Inst{4-0}   = Zt;
6783
6784  let hasSideEffects = 0;
6785  let mayStore = 1;
6786}
6787
6788multiclass sve_mem_cst_ss<bits<4> dtype, string asm,
6789                          RegisterOperand listty, ZPRRegOp zprty,
6790                          RegisterOperand gprty> {
6791  def NAME : sve_mem_cst_ss_base<dtype, asm, listty, gprty>;
6792
6793  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Rm]",
6794                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
6795}
6796
6797class sve_mem_cstnt_si<bits<2> msz, string asm, RegisterOperand VecList>
6798: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
6799  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6800  "",
6801  []>, Sched<[]> {
6802  bits<3> Pg;
6803  bits<5> Rn;
6804  bits<5> Zt;
6805  bits<4> imm4;
6806  let Inst{31-25} = 0b1110010;
6807  let Inst{24-23} = msz;
6808  let Inst{22-20} = 0b001;
6809  let Inst{19-16} = imm4;
6810  let Inst{15-13} = 0b111;
6811  let Inst{12-10} = Pg;
6812  let Inst{9-5}   = Rn;
6813  let Inst{4-0}   = Zt;
6814
6815  let hasSideEffects = 0;
6816  let mayStore = 1;
6817}
6818
6819multiclass sve_mem_cstnt_si<bits<2> msz, string asm, RegisterOperand listty,
6820                            ZPRRegOp zprty> {
6821  def NAME : sve_mem_cstnt_si<msz, asm, listty>;
6822
6823  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6824                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
6825  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6826                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
6827  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6828                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6829}
6830
6831class sve_mem_cstnt_ss_base<bits<2> msz, string asm, RegisterOperand listty,
6832                            RegisterOperand gprty>
6833: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6834  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6835  "",
6836  []>, Sched<[]> {
6837  bits<3> Pg;
6838  bits<5> Rm;
6839  bits<5> Rn;
6840  bits<5> Zt;
6841  let Inst{31-25} = 0b1110010;
6842  let Inst{24-23} = msz;
6843  let Inst{22-21} = 0b00;
6844  let Inst{20-16} = Rm;
6845  let Inst{15-13} = 0b011;
6846  let Inst{12-10} = Pg;
6847  let Inst{9-5}   = Rn;
6848  let Inst{4-0}   = Zt;
6849
6850  let hasSideEffects = 0;
6851  let mayStore = 1;
6852}
6853
6854multiclass sve_mem_cstnt_ss<bits<2> msz, string asm, RegisterOperand listty,
6855                            ZPRRegOp zprty, RegisterOperand gprty> {
6856  def NAME : sve_mem_cstnt_ss_base<msz, asm, listty, gprty>;
6857
6858  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Rm]",
6859                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
6860}
6861
6862class sve2_mem_sstnt_vs_base<bits<3> opc, string asm,
6863                             RegisterOperand listty, ZPRRegOp zprty>
6864: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, zprty:$Zn, GPR64:$Rm),
6865  asm, "\t$Zt, $Pg, [$Zn, $Rm]",
6866  "",
6867  []>, Sched<[]> {
6868  bits<3> Pg;
6869  bits<5> Rm;
6870  bits<5> Zn;
6871  bits<5> Zt;
6872  let Inst{31-25} = 0b1110010;
6873  let Inst{24-22} = opc;
6874  let Inst{21}    = 0b0;
6875  let Inst{20-16} = Rm;
6876  let Inst{15-13} = 0b001;
6877  let Inst{12-10} = Pg;
6878  let Inst{9-5}   = Zn;
6879  let Inst{4-0}   = Zt;
6880
6881  let hasSideEffects = 0;
6882  let mayStore = 1;
6883}
6884
6885multiclass sve2_mem_sstnt_vs_32_ptrs<bits<3> opc, string asm,
6886                             SDPatternOperator op,
6887                             ValueType vt> {
6888  def NAME : sve2_mem_sstnt_vs_base<opc, asm, Z_s, ZPR32>;
6889
6890  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $Rm]",
6891                 (!cast<Instruction>(NAME) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm), 0>;
6892  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6893                 (!cast<Instruction>(NAME) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 0>;
6894  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6895                 (!cast<Instruction>(NAME) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 1>;
6896
6897  def : Pat <(op (nxv4i32 ZPR32:$Zt), (nxv4i1 PPR3bAny:$Pg), (nxv4i32 ZPR32:$Zn), (i64 GPR64:$Rm), vt),
6898             (!cast<Instruction>(NAME) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm)>;
6899}
6900
6901multiclass sve2_mem_sstnt_vs_64_ptrs<bits<3> opc, string asm,
6902                             SDPatternOperator op,
6903                             ValueType vt> {
6904  def NAME : sve2_mem_sstnt_vs_base<opc, asm, Z_d, ZPR64>;
6905
6906  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $Rm]",
6907                 (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm), 0>;
6908  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6909                 (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 0>;
6910  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6911                 (!cast<Instruction>(NAME) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
6912
6913  def : Pat <(op (nxv2i64 ZPR64:$Zt), (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64:$Rm), vt),
6914             (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
6915}
6916
6917class sve_mem_sst_sv<bits<3> opc, bit xs, bit scaled, string asm,
6918                     RegisterOperand VecList, RegisterOperand zprext>
6919: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
6920  asm, "\t$Zt, $Pg, [$Rn, $Zm]",
6921  "",
6922  []>, Sched<[]> {
6923  bits<3> Pg;
6924  bits<5> Rn;
6925  bits<5> Zm;
6926  bits<5> Zt;
6927  let Inst{31-25} = 0b1110010;
6928  let Inst{24-22} = opc;
6929  let Inst{21}    = scaled;
6930  let Inst{20-16} = Zm;
6931  let Inst{15}    = 0b1;
6932  let Inst{14}    = xs;
6933  let Inst{13}    = 0;
6934  let Inst{12-10} = Pg;
6935  let Inst{9-5}   = Rn;
6936  let Inst{4-0}   = Zt;
6937
6938  let hasSideEffects = 0;
6939  let mayStore = 1;
6940}
6941
6942multiclass sve_mem_32b_sst_sv_32_scaled<bits<3> opc, string asm,
6943                                    SDPatternOperator sxtw_op,
6944                                    SDPatternOperator uxtw_op,
6945                                    RegisterOperand sxtw_opnd,
6946                                    RegisterOperand uxtw_opnd,
6947                                    ValueType vt > {
6948  def _UXTW_SCALED : sve_mem_sst_sv<opc, 0, 1, asm, Z_s, uxtw_opnd>;
6949  def _SXTW_SCALED : sve_mem_sst_sv<opc, 1, 1, asm, Z_s, sxtw_opnd>;
6950
6951  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6952                 (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6953  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6954                 (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6955
6956  def : Pat<(uxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6957            (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6958  def : Pat<(sxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6959            (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6960}
6961
6962multiclass sve_mem_64b_sst_sv_32_scaled<bits<3> opc, string asm,
6963                                    SDPatternOperator sxtw_op,
6964                                    SDPatternOperator uxtw_op,
6965                                    RegisterOperand sxtw_opnd,
6966                                    RegisterOperand uxtw_opnd,
6967                                    ValueType vt > {
6968  def _UXTW_SCALED : sve_mem_sst_sv<opc, 0, 1, asm, Z_d, uxtw_opnd>;
6969  def _SXTW_SCALED : sve_mem_sst_sv<opc, 1, 1, asm, Z_d, sxtw_opnd>;
6970
6971  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6972                 (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6973  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6974                 (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6975
6976  def : Pat<(uxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6977            (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6978  def : Pat<(sxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6979            (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6980}
6981
6982multiclass sve_mem_64b_sst_sv_32_unscaled<bits<3> opc, string asm,
6983                                         SDPatternOperator sxtw_op,
6984                                         SDPatternOperator uxtw_op,
6985                                         RegisterOperand sxtw_opnd,
6986                                         RegisterOperand uxtw_opnd,
6987                                         ValueType vt> {
6988  def _UXTW : sve_mem_sst_sv<opc, 0, 0, asm, Z_d, uxtw_opnd>;
6989  def _SXTW : sve_mem_sst_sv<opc, 1, 0, asm, Z_d, sxtw_opnd>;
6990
6991  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6992                 (!cast<Instruction>(NAME # _UXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6993  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6994                 (!cast<Instruction>(NAME # _SXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6995
6996  def : Pat<(uxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6997            (!cast<Instruction>(NAME # _UXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6998  def : Pat<(sxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6999            (!cast<Instruction>(NAME # _SXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
7000}
7001
7002multiclass sve_mem_32b_sst_sv_32_unscaled<bits<3> opc, string asm,
7003                                          SDPatternOperator sxtw_op,
7004                                          SDPatternOperator uxtw_op,
7005                                          RegisterOperand sxtw_opnd,
7006                                          RegisterOperand uxtw_opnd,
7007                                          ValueType vt> {
7008  def _UXTW : sve_mem_sst_sv<opc, 0, 0, asm, Z_s, uxtw_opnd>;
7009  def _SXTW : sve_mem_sst_sv<opc, 1, 0, asm, Z_s, sxtw_opnd>;
7010
7011  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
7012                 (!cast<Instruction>(NAME # _UXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
7013  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
7014                 (!cast<Instruction>(NAME # _SXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
7015
7016  def : Pat<(uxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
7017            (!cast<Instruction>(NAME # _UXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
7018  def : Pat<(sxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
7019            (!cast<Instruction>(NAME # _SXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
7020}
7021
7022class sve_mem_sst_sv2<bits<2> msz, bit scaled, string asm,
7023                      RegisterOperand zprext>
7024: I<(outs), (ins Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
7025  asm, "\t$Zt, $Pg, [$Rn, $Zm]",
7026  "",
7027  []>, Sched<[]> {
7028  bits<3> Pg;
7029  bits<5> Rn;
7030  bits<5> Zm;
7031  bits<5> Zt;
7032  let Inst{31-25} = 0b1110010;
7033  let Inst{24-23} = msz;
7034  let Inst{22}    = 0b0;
7035  let Inst{21}    = scaled;
7036  let Inst{20-16} = Zm;
7037  let Inst{15-13} = 0b101;
7038  let Inst{12-10} = Pg;
7039  let Inst{9-5}   = Rn;
7040  let Inst{4-0}   = Zt;
7041
7042  let hasSideEffects = 0;
7043  let mayStore = 1;
7044}
7045
7046multiclass sve_mem_sst_sv_64_scaled<bits<2> msz, string asm,
7047                                    SDPatternOperator op,
7048                                    RegisterOperand zprext,
7049                                    ValueType vt> {
7050  def _SCALED : sve_mem_sst_sv2<msz, 1, asm, zprext>;
7051
7052  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
7053                 (!cast<Instruction>(NAME # _SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), 0>;
7054
7055  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt),
7056            (!cast<Instruction>(NAME # _SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
7057}
7058
7059multiclass sve_mem_sst_sv_64_unscaled<bits<2> msz, string asm,
7060                                      SDPatternOperator op,
7061                                      ValueType vt> {
7062  def NAME : sve_mem_sst_sv2<msz, 0, asm, ZPR64ExtLSL8>;
7063
7064  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
7065                 (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), 0>;
7066
7067  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
7068            (!cast<Instruction>(NAME) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
7069}
7070
7071class sve_mem_sst_vi<bits<3> opc, string asm, ZPRRegOp zprty,
7072                     RegisterOperand VecList, Operand imm_ty>
7073: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, zprty:$Zn, imm_ty:$imm5),
7074  asm, "\t$Zt, $Pg, [$Zn, $imm5]",
7075  "",
7076  []>, Sched<[]> {
7077  bits<3> Pg;
7078  bits<5> imm5;
7079  bits<5> Zn;
7080  bits<5> Zt;
7081  let Inst{31-25} = 0b1110010;
7082  let Inst{24-23} = opc{2-1};
7083  let Inst{22}    = 0b1;
7084  let Inst{21}    = opc{0};
7085  let Inst{20-16} = imm5;
7086  let Inst{15-13} = 0b101;
7087  let Inst{12-10} = Pg;
7088  let Inst{9-5}   = Zn;
7089  let Inst{4-0}   = Zt;
7090
7091  let hasSideEffects = 0;
7092  let mayStore = 1;
7093}
7094
7095multiclass sve_mem_32b_sst_vi_ptrs<bits<3> opc, string asm,
7096                                   Operand imm_ty,
7097                                   SDPatternOperator op,
7098                                   ValueType vt> {
7099  def _IMM : sve_mem_sst_vi<opc, asm, ZPR32, Z_s, imm_ty>;
7100
7101  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
7102                  (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 0>;
7103  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $imm5]",
7104                  (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), 0>;
7105  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
7106                  (!cast<Instruction>(NAME # _IMM) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
7107
7108  def : Pat<(op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), (nxv4i32 ZPR:$ptrs), imm_ty:$index, vt),
7109            (!cast<Instruction>(NAME # _IMM) ZPR:$data, PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
7110}
7111
7112multiclass sve_mem_64b_sst_vi_ptrs<bits<3> opc, string asm,
7113                                   Operand imm_ty,
7114                                   SDPatternOperator op,
7115                                   ValueType vt> {
7116  def _IMM : sve_mem_sst_vi<opc, asm, ZPR64, Z_d, imm_ty>;
7117
7118  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
7119                  (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 0>;
7120  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $imm5]",
7121                  (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), 0>;
7122  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
7123                  (!cast<Instruction>(NAME # _IMM) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
7124
7125  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), (nxv2i64 ZPR:$ptrs), imm_ty:$index, vt),
7126            (!cast<Instruction>(NAME # _IMM) ZPR:$data, PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
7127}
7128
7129class sve_mem_z_spill<string asm>
7130: I<(outs), (ins ZPRAny:$Zt, GPR64sp:$Rn, simm9:$imm9),
7131  asm, "\t$Zt, [$Rn, $imm9, mul vl]",
7132  "",
7133  []>, Sched<[]> {
7134  bits<5> Rn;
7135  bits<5> Zt;
7136  bits<9> imm9;
7137  let Inst{31-22} = 0b1110010110;
7138  let Inst{21-16} = imm9{8-3};
7139  let Inst{15-13} = 0b010;
7140  let Inst{12-10} = imm9{2-0};
7141  let Inst{9-5}   = Rn;
7142  let Inst{4-0}   = Zt;
7143
7144  let hasSideEffects = 0;
7145  let mayStore = 1;
7146}
7147
7148multiclass sve_mem_z_spill<string asm> {
7149  def NAME : sve_mem_z_spill<asm>;
7150
7151  def : InstAlias<asm # "\t$Zt, [$Rn]",
7152                  (!cast<Instruction>(NAME) ZPRAny:$Zt, GPR64sp:$Rn, 0), 1>;
7153}
7154
7155class sve_mem_p_spill<string asm>
7156: I<(outs), (ins PPRorPNRAny:$Pt, GPR64sp:$Rn, simm9:$imm9),
7157  asm, "\t$Pt, [$Rn, $imm9, mul vl]",
7158  "",
7159  []>, Sched<[]> {
7160  bits<4> Pt;
7161  bits<5> Rn;
7162  bits<9> imm9;
7163  let Inst{31-22} = 0b1110010110;
7164  let Inst{21-16} = imm9{8-3};
7165  let Inst{15-13} = 0b000;
7166  let Inst{12-10} = imm9{2-0};
7167  let Inst{9-5}   = Rn;
7168  let Inst{4}     = 0b0;
7169  let Inst{3-0}   = Pt;
7170
7171  let hasSideEffects = 0;
7172  let mayStore = 1;
7173}
7174
7175multiclass sve_mem_p_spill<string asm> {
7176  def NAME : sve_mem_p_spill<asm>;
7177
7178  def : InstAlias<asm # "\t$Pt, [$Rn]",
7179                  (!cast<Instruction>(NAME) PPRorPNRAny:$Pt, GPR64sp:$Rn, 0), 1>;
7180}
7181
7182//===----------------------------------------------------------------------===//
7183// SVE Permute - Predicates Group
7184//===----------------------------------------------------------------------===//
7185
7186class sve_int_perm_bin_perm_pp<bits<3> opc, bits<2> sz8_64, string asm,
7187                               PPRRegOp pprty, SDPatternOperator op>
7188: I<(outs pprty:$Pd), (ins pprty:$Pn, pprty:$Pm),
7189  asm, "\t$Pd, $Pn, $Pm",
7190  "",
7191  [(set nxv16i1:$Pd, (op nxv16i1:$Pn, nxv16i1:$Pm))]>, Sched<[]> {
7192  bits<4> Pd;
7193  bits<4> Pm;
7194  bits<4> Pn;
7195  let Inst{31-24} = 0b00000101;
7196  let Inst{23-22} = sz8_64;
7197  let Inst{21-20} = 0b10;
7198  let Inst{19-16} = Pm;
7199  let Inst{15-13} = 0b010;
7200  let Inst{12-10} = opc;
7201  let Inst{9}     = 0b0;
7202  let Inst{8-5}   = Pn;
7203  let Inst{4}     = 0b0;
7204  let Inst{3-0}   = Pd;
7205
7206  let hasSideEffects = 0;
7207}
7208
7209multiclass sve_int_perm_bin_perm_pp<bits<3> opc, string asm,
7210                                    SDPatternOperator ir_op,
7211                                    SDPatternOperator op_b16,
7212                                    SDPatternOperator op_b32,
7213                                    SDPatternOperator op_b64> {
7214  def _B : sve_int_perm_bin_perm_pp<opc, 0b00, asm, PPR8,  ir_op>;
7215  def _H : sve_int_perm_bin_perm_pp<opc, 0b01, asm, PPR16, op_b16>;
7216  def _S : sve_int_perm_bin_perm_pp<opc, 0b10, asm, PPR32, op_b32>;
7217  def _D : sve_int_perm_bin_perm_pp<opc, 0b11, asm, PPR64, op_b64>;
7218
7219  def : SVE_2_Op_Pat<nxv8i1, ir_op, nxv8i1, nxv8i1, !cast<Instruction>(NAME # _H)>;
7220  def : SVE_2_Op_Pat<nxv4i1, ir_op, nxv4i1, nxv4i1, !cast<Instruction>(NAME # _S)>;
7221  def : SVE_2_Op_Pat<nxv2i1, ir_op, nxv2i1, nxv2i1, !cast<Instruction>(NAME # _D)>;
7222}
7223
7224class sve_int_perm_punpk<bit opc, string asm>
7225: I<(outs PPR16:$Pd), (ins PPR8:$Pn),
7226  asm, "\t$Pd, $Pn",
7227  "",
7228  []>, Sched<[]> {
7229  bits<4> Pd;
7230  bits<4> Pn;
7231  let Inst{31-17} = 0b000001010011000;
7232  let Inst{16}    = opc;
7233  let Inst{15-9}  = 0b0100000;
7234  let Inst{8-5}   = Pn;
7235  let Inst{4}     = 0b0;
7236  let Inst{3-0}   = Pd;
7237
7238  let hasSideEffects = 0;
7239}
7240
7241multiclass sve_int_perm_punpk<bit opc, string asm, SDPatternOperator op> {
7242  def NAME : sve_int_perm_punpk<opc, asm>;
7243
7244  def : SVE_1_Op_Pat<nxv8i1, op, nxv16i1, !cast<Instruction>(NAME)>;
7245  def : SVE_1_Op_Pat<nxv4i1, op, nxv8i1,  !cast<Instruction>(NAME)>;
7246  def : SVE_1_Op_Pat<nxv2i1, op, nxv4i1,  !cast<Instruction>(NAME)>;
7247}
7248
7249class sve_int_rdffr_pred<bit s, string asm, SDPatternOperator op = null_frag>
7250: I<(outs PPR8:$Pd), (ins PPRAny:$Pg),
7251  asm, "\t$Pd, $Pg/z",
7252  "",
7253  [(set (nxv16i1 PPR8:$Pd), (op (nxv16i1 PPRAny:$Pg)))]>, Sched<[]> {
7254  bits<4> Pd;
7255  bits<4> Pg;
7256  let Inst{31-23} = 0b001001010;
7257  let Inst{22}    = s;
7258  let Inst{21-9}  = 0b0110001111000;
7259  let Inst{8-5}   = Pg;
7260  let Inst{4}     = 0;
7261  let Inst{3-0}   = Pd;
7262
7263  let Defs = !if(s, [NZCV], []);
7264  let Uses = [FFR];
7265  let hasSideEffects = 1;
7266}
7267
7268class sve_int_rdffr_unpred<string asm, SDPatternOperator op> : I<
7269  (outs PPR8:$Pd), (ins),
7270  asm, "\t$Pd",
7271  "",
7272  [(set (nxv16i1 PPR8:$Pd), (op))]>, Sched<[]> {
7273  bits<4> Pd;
7274  let Inst{31-4} = 0b0010010100011001111100000000;
7275  let Inst{3-0}   = Pd;
7276
7277  let Uses = [FFR];
7278  let hasSideEffects = 1;
7279}
7280
7281class sve_int_wrffr<string asm, SDPatternOperator op>
7282: I<(outs), (ins PPR8:$Pn),
7283  asm, "\t$Pn",
7284  "",
7285  [(op (nxv16i1 PPR8:$Pn))]>, Sched<[]> {
7286  bits<4> Pn;
7287  let Inst{31-9} = 0b00100101001010001001000;
7288  let Inst{8-5}  = Pn;
7289  let Inst{4-0}  = 0b00000;
7290
7291  let Defs = [FFR];
7292  let hasSideEffects = 1;
7293}
7294
7295class sve_int_setffr<string asm, SDPatternOperator op>
7296: I<(outs), (ins),
7297  asm, "",
7298  "",
7299  [(op)]>, Sched<[]> {
7300  let Inst{31-0} = 0b00100101001011001001000000000000;
7301
7302  let Defs = [FFR];
7303  let hasSideEffects = 1;
7304}
7305
7306//===----------------------------------------------------------------------===//
7307// SVE Permute Vector - Predicated Group
7308//===----------------------------------------------------------------------===//
7309
7310class sve_int_perm_clast_rz<bits<2> sz8_64, bit ab, string asm,
7311                            ZPRRegOp zprty, RegisterClass rt>
7312: I<(outs rt:$Rdn), (ins PPR3bAny:$Pg, rt:$_Rdn, zprty:$Zm),
7313  asm, "\t$Rdn, $Pg, $_Rdn, $Zm",
7314  "",
7315  []>, Sched<[]> {
7316  bits<3> Pg;
7317  bits<5> Rdn;
7318  bits<5> Zm;
7319  let Inst{31-24} = 0b00000101;
7320  let Inst{23-22} = sz8_64;
7321  let Inst{21-17} = 0b11000;
7322  let Inst{16}    = ab;
7323  let Inst{15-13} = 0b101;
7324  let Inst{12-10} = Pg;
7325  let Inst{9-5}   = Zm;
7326  let Inst{4-0}   = Rdn;
7327
7328  let Constraints = "$Rdn = $_Rdn";
7329  let hasSideEffects = 0;
7330}
7331
7332multiclass sve_int_perm_clast_rz<bit ab, string asm, SDPatternOperator op> {
7333  def _B : sve_int_perm_clast_rz<0b00, ab, asm, ZPR8, GPR32>;
7334  def _H : sve_int_perm_clast_rz<0b01, ab, asm, ZPR16, GPR32>;
7335  def _S : sve_int_perm_clast_rz<0b10, ab, asm, ZPR32, GPR32>;
7336  def _D : sve_int_perm_clast_rz<0b11, ab, asm, ZPR64, GPR64>;
7337
7338  def : SVE_3_Op_Pat<i32, op, nxv16i1, i32, nxv16i8, !cast<Instruction>(NAME # _B)>;
7339  def : SVE_3_Op_Pat<i32, op, nxv8i1,  i32, nxv8i16, !cast<Instruction>(NAME # _H)>;
7340  def : SVE_3_Op_Pat<i32, op, nxv4i1,  i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
7341  def : SVE_3_Op_Pat<i64, op, nxv2i1,  i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
7342}
7343
7344class sve_int_perm_clast_vz<bits<2> sz8_64, bit ab, string asm,
7345                            ZPRRegOp zprty, RegisterClass rt>
7346: I<(outs rt:$Vdn), (ins PPR3bAny:$Pg, rt:$_Vdn, zprty:$Zm),
7347  asm, "\t$Vdn, $Pg, $_Vdn, $Zm",
7348  "",
7349  []>, Sched<[]> {
7350  bits<3> Pg;
7351  bits<5> Vdn;
7352  bits<5> Zm;
7353  let Inst{31-24} = 0b00000101;
7354  let Inst{23-22} = sz8_64;
7355  let Inst{21-17} = 0b10101;
7356  let Inst{16}    = ab;
7357  let Inst{15-13} = 0b100;
7358  let Inst{12-10} = Pg;
7359  let Inst{9-5}   = Zm;
7360  let Inst{4-0}   = Vdn;
7361
7362  let Constraints = "$Vdn = $_Vdn";
7363  let hasSideEffects = 0;
7364}
7365
7366multiclass sve_int_perm_clast_vz<bit ab, string asm, SDPatternOperator op> {
7367  def _B : sve_int_perm_clast_vz<0b00, ab, asm, ZPR8, FPR8>;
7368  def _H : sve_int_perm_clast_vz<0b01, ab, asm, ZPR16, FPR16>;
7369  def _S : sve_int_perm_clast_vz<0b10, ab, asm, ZPR32, FPR32>;
7370  def _D : sve_int_perm_clast_vz<0b11, ab, asm, ZPR64, FPR64>;
7371
7372  def : SVE_3_Op_Pat<f16, op, nxv8i1, f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
7373  def : SVE_3_Op_Pat<f32, op, nxv4i1, f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
7374  def : SVE_3_Op_Pat<f64, op, nxv2i1, f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
7375
7376  def : SVE_3_Op_Pat<bf16, op, nxv8i1, bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
7377}
7378
7379class sve_int_perm_clast_zz<bits<2> sz8_64, bit ab, string asm,
7380                            ZPRRegOp zprty>
7381: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
7382  asm, "\t$Zdn, $Pg, $_Zdn, $Zm",
7383  "",
7384  []>, Sched<[]> {
7385  bits<3> Pg;
7386  bits<5> Zdn;
7387  bits<5> Zm;
7388  let Inst{31-24} = 0b00000101;
7389  let Inst{23-22} = sz8_64;
7390  let Inst{21-17} = 0b10100;
7391  let Inst{16}    = ab;
7392  let Inst{15-13} = 0b100;
7393  let Inst{12-10} = Pg;
7394  let Inst{9-5}   = Zm;
7395  let Inst{4-0}   = Zdn;
7396
7397  let Constraints = "$Zdn = $_Zdn";
7398  let DestructiveInstType = DestructiveOther;
7399  let ElementSize = ElementSizeNone;
7400  let hasSideEffects = 0;
7401}
7402
7403multiclass sve_int_perm_clast_zz<bit ab, string asm, SDPatternOperator op> {
7404  def _B : sve_int_perm_clast_zz<0b00, ab, asm, ZPR8>;
7405  def _H : sve_int_perm_clast_zz<0b01, ab, asm, ZPR16>;
7406  def _S : sve_int_perm_clast_zz<0b10, ab, asm, ZPR32>;
7407  def _D : sve_int_perm_clast_zz<0b11, ab, asm, ZPR64>;
7408
7409  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
7410  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
7411  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
7412  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
7413
7414  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
7415  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
7416  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
7417
7418  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
7419}
7420
7421class sve_int_perm_last_r<bits<2> sz8_64, bit ab, string asm,
7422                          ZPRRegOp zprty, RegisterClass resultRegType>
7423: I<(outs resultRegType:$Rd), (ins PPR3bAny:$Pg, zprty:$Zn),
7424  asm, "\t$Rd, $Pg, $Zn",
7425  "",
7426  []>, Sched<[]> {
7427  bits<3> Pg;
7428  bits<5> Rd;
7429  bits<5> Zn;
7430  let Inst{31-24} = 0b00000101;
7431  let Inst{23-22} = sz8_64;
7432  let Inst{21-17} = 0b10000;
7433  let Inst{16}    = ab;
7434  let Inst{15-13} = 0b101;
7435  let Inst{12-10} = Pg;
7436  let Inst{9-5}   = Zn;
7437  let Inst{4-0}   = Rd;
7438
7439  let hasSideEffects = 0;
7440}
7441
7442multiclass sve_int_perm_last_r<bit ab, string asm, SDPatternOperator op> {
7443  def _B : sve_int_perm_last_r<0b00, ab, asm, ZPR8, GPR32>;
7444  def _H : sve_int_perm_last_r<0b01, ab, asm, ZPR16, GPR32>;
7445  def _S : sve_int_perm_last_r<0b10, ab, asm, ZPR32, GPR32>;
7446  def _D : sve_int_perm_last_r<0b11, ab, asm, ZPR64, GPR64>;
7447
7448  def : SVE_2_Op_Pat<i32, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
7449  def : SVE_2_Op_Pat<i32, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
7450  def : SVE_2_Op_Pat<i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7451  def : SVE_2_Op_Pat<i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7452}
7453
7454class sve_int_perm_last_v<bits<2> sz8_64, bit ab, string asm,
7455                          ZPRRegOp zprty, RegisterClass dstRegtype>
7456: I<(outs dstRegtype:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
7457  asm, "\t$Vd, $Pg, $Zn",
7458  "",
7459  []>, Sched<[]> {
7460  bits<3> Pg;
7461  bits<5> Vd;
7462  bits<5> Zn;
7463  let Inst{31-24} = 0b00000101;
7464  let Inst{23-22} = sz8_64;
7465  let Inst{21-17} = 0b10001;
7466  let Inst{16}    = ab;
7467  let Inst{15-13} = 0b100;
7468  let Inst{12-10} = Pg;
7469  let Inst{9-5}   = Zn;
7470  let Inst{4-0}   = Vd;
7471
7472  let hasSideEffects = 0;
7473}
7474
7475multiclass sve_int_perm_last_v<bit ab, string asm, SDPatternOperator op> {
7476  def _B : sve_int_perm_last_v<0b00, ab, asm, ZPR8, FPR8>;
7477  def _H : sve_int_perm_last_v<0b01, ab, asm, ZPR16, FPR16>;
7478  def _S : sve_int_perm_last_v<0b10, ab, asm, ZPR32, FPR32>;
7479  def _D : sve_int_perm_last_v<0b11, ab, asm, ZPR64, FPR64>;
7480
7481  def : SVE_2_Op_Pat<f16, op, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
7482  def : SVE_2_Op_Pat<f32, op, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
7483  def : SVE_2_Op_Pat<f32, op, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
7484  def : SVE_2_Op_Pat<f64, op, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
7485
7486  def : SVE_2_Op_Pat<bf16, op, nxv8i1,  nxv8bf16, !cast<Instruction>(NAME # _H)>;
7487}
7488
7489class sve_int_perm_splice<bits<2> sz8_64, string asm, ZPRRegOp zprty>
7490: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
7491  asm, "\t$Zdn, $Pg, $_Zdn, $Zm",
7492  "",
7493  []>, Sched<[]> {
7494  bits<3> Pg;
7495  bits<5> Zdn;
7496  bits<5> Zm;
7497  let Inst{31-24} = 0b00000101;
7498  let Inst{23-22} = sz8_64;
7499  let Inst{21-13} = 0b101100100;
7500  let Inst{12-10} = Pg;
7501  let Inst{9-5}   = Zm;
7502  let Inst{4-0}   = Zdn;
7503
7504  let Constraints = "$Zdn = $_Zdn";
7505  let DestructiveInstType = DestructiveOther;
7506  let ElementSize = ElementSizeNone;
7507  let hasSideEffects = 0;
7508}
7509
7510multiclass sve_int_perm_splice<string asm, SDPatternOperator op> {
7511  def _B : sve_int_perm_splice<0b00, asm, ZPR8>;
7512  def _H : sve_int_perm_splice<0b01, asm, ZPR16>;
7513  def _S : sve_int_perm_splice<0b10, asm, ZPR32>;
7514  def _D : sve_int_perm_splice<0b11, asm, ZPR64>;
7515
7516 foreach VT = [nxv16i8] in
7517   def : SVE_3_Op_Pat<VT, op, nxv16i1, VT, VT, !cast<Instruction>(NAME # _B)>;
7518
7519 foreach VT = [nxv8i16, nxv8f16, nxv8bf16] in
7520   def : SVE_3_Op_Pat<VT, op, nxv8i1, VT, VT, !cast<Instruction>(NAME # _H)>;
7521
7522 foreach VT = [nxv4i32, nxv4f16, nxv4f32, nxv4bf16] in
7523   def : SVE_3_Op_Pat<VT, op, nxv4i1, VT, VT, !cast<Instruction>(NAME # _S)>;
7524
7525 foreach VT = [nxv2i64, nxv2f16, nxv2f32, nxv2f64, nxv2bf16] in
7526   def : SVE_3_Op_Pat<VT, op, nxv2i1, VT, VT, !cast<Instruction>(NAME # _D)>;
7527}
7528
7529class sve2_int_perm_splice_cons<bits<2> sz8_64, string asm,
7530                               ZPRRegOp zprty, RegisterOperand VecList>
7531: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, VecList:$Zn),
7532  asm, "\t$Zd, $Pg, $Zn",
7533  "",
7534  []>, Sched<[]> {
7535  bits<3> Pg;
7536  bits<5> Zn;
7537  bits<5> Zd;
7538  let Inst{31-24} = 0b00000101;
7539  let Inst{23-22} = sz8_64;
7540  let Inst{21-13} = 0b101101100;
7541  let Inst{12-10} = Pg;
7542  let Inst{9-5}   = Zn;
7543  let Inst{4-0}   = Zd;
7544
7545  let hasSideEffects = 0;
7546}
7547
7548multiclass sve2_int_perm_splice_cons<string asm, SDPatternOperator op> {
7549  def _B : sve2_int_perm_splice_cons<0b00, asm, ZPR8,  ZZ_b>;
7550  def _H : sve2_int_perm_splice_cons<0b01, asm, ZPR16, ZZ_h>;
7551  def _S : sve2_int_perm_splice_cons<0b10, asm, ZPR32, ZZ_s>;
7552  def _D : sve2_int_perm_splice_cons<0b11, asm, ZPR64, ZZ_d>;
7553
7554  let AddedComplexity = 2 in {
7555  foreach VT = [nxv16i8] in
7556    def : Pat<(VT (op nxv16i1:$pred, VT:$zn1, VT:$zn2)),
7557              (!cast<Instruction>(NAME # _B)
7558               nxv16i1:$pred, (REG_SEQUENCE ZPR2, VT:$zn1, zsub0, VT:$zn2, zsub1))>;
7559
7560  foreach VT = [nxv8i16, nxv8f16, nxv8bf16] in
7561    def : Pat<(VT (op nxv8i1:$pred, VT:$zn1, VT:$zn2)),
7562              (!cast<Instruction>(NAME # _H)
7563               nxv8i1:$pred, (REG_SEQUENCE ZPR2, VT:$zn1, zsub0, VT:$zn2, zsub1))>;
7564
7565  foreach VT = [nxv4i32, nxv4f16, nxv4f32, nxv4bf16] in
7566    def : Pat<(VT (op nxv4i1:$pred, VT:$zn1, VT:$zn2)),
7567              (!cast<Instruction>(NAME # _S)
7568               nxv4i1:$pred, (REG_SEQUENCE ZPR2, VT:$zn1, zsub0, VT:$zn2, zsub1))>;
7569
7570  foreach VT = [nxv2i64, nxv2f16, nxv2f32, nxv2f64, nxv2bf16] in
7571    def : Pat<(VT (op nxv2i1:$pred, VT:$zn1, VT:$zn2)),
7572              (!cast<Instruction>(NAME # _D)
7573               nxv2i1:$pred, (REG_SEQUENCE ZPR2, VT:$zn1, zsub0, VT:$zn2, zsub1))>;
7574  }
7575}
7576
7577class sve2_int_perm_expand<bits<2> sz, string asm,
7578                           ZPRRegOp zprty>
7579: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
7580  asm, "\t$Zd, $Pg, $Zn",
7581  "",
7582  []>, Sched<[]> {
7583  bits<3> Pg;
7584  bits<5> Zn;
7585  bits<5> Zd;
7586  let Inst{31-24} = 0b00000101;
7587  let Inst{23-22} = sz;
7588  let Inst{21-13} = 0b110001100;
7589  let Inst{12-10} = Pg;
7590  let Inst{9-5}   = Zn;
7591  let Inst{4-0}   = Zd;
7592
7593  let hasSideEffects = 0;
7594}
7595
7596multiclass sve2_int_perm_expand<string asm> {
7597  def _B : sve2_int_perm_expand<0b00, asm, ZPR8>;
7598  def _H : sve2_int_perm_expand<0b01, asm, ZPR16>;
7599  def _S : sve2_int_perm_expand<0b10, asm, ZPR32>;
7600  def _D : sve2_int_perm_expand<0b11, asm, ZPR64>;
7601}
7602
7603class sve_int_perm_rev<bits<2> sz8_64, bits<2> opc, string asm,
7604                       ZPRRegOp zprty>
7605: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
7606  asm, "\t$Zd, $Pg/m, $Zn",
7607  "",
7608  []>, Sched<[]> {
7609  bits<5> Zd;
7610  bits<3> Pg;
7611  bits<5> Zn;
7612  let Inst{31-24} = 0b00000101;
7613  let Inst{23-22} = sz8_64;
7614  let Inst{21-18} = 0b1001;
7615  let Inst{17-16} = opc;
7616  let Inst{15-13} = 0b100;
7617  let Inst{12-10} = Pg;
7618  let Inst{9-5}   = Zn;
7619  let Inst{4-0}   = Zd;
7620
7621  let Constraints = "$Zd = $_Zd";
7622  let DestructiveInstType = DestructiveOther;
7623  let ElementSize = zprty.ElementSize;
7624  let hasSideEffects = 0;
7625}
7626
7627multiclass sve_int_perm_rev_rbit<string asm, SDPatternOperator op> {
7628  def _B : sve_int_perm_rev<0b00, 0b11, asm, ZPR8>;
7629  def _H : sve_int_perm_rev<0b01, 0b11, asm, ZPR16>;
7630  def _S : sve_int_perm_rev<0b10, 0b11, asm, ZPR32>;
7631  def _D : sve_int_perm_rev<0b11, 0b11, asm, ZPR64>;
7632
7633  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
7634  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
7635  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7636  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7637}
7638
7639multiclass sve_int_perm_rev_revb<string asm, SDPatternOperator op> {
7640  def _H : sve_int_perm_rev<0b01, 0b00, asm, ZPR16>;
7641  def _S : sve_int_perm_rev<0b10, 0b00, asm, ZPR32>;
7642  def _D : sve_int_perm_rev<0b11, 0b00, asm, ZPR64>;
7643
7644  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
7645  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7646  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7647}
7648
7649multiclass sve_int_perm_rev_revh<string asm, SDPatternOperator op> {
7650  def _S : sve_int_perm_rev<0b10, 0b01, asm, ZPR32>;
7651  def _D : sve_int_perm_rev<0b11, 0b01, asm, ZPR64>;
7652
7653  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7654  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7655}
7656
7657multiclass sve_int_perm_rev_revw<string asm, SDPatternOperator op> {
7658  def _D : sve_int_perm_rev<0b11, 0b10, asm, ZPR64>;
7659
7660  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7661}
7662
7663class sve_int_perm_rev_z<bits<2> sz, bits<4> opc, string asm,
7664                        ZPRRegOp zprty>
7665: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
7666  asm, "\t$Zd, $Pg/z, $Zn",
7667  "",
7668  []>, Sched<[]> {
7669  bits<5> Zd;
7670  bits<3> Pg;
7671  bits<5> Zn;
7672  let Inst{31-24} = 0b00000101;
7673  let Inst{23-22} = sz;
7674  let Inst{21-20} = 0b10;
7675  let Inst{19-16} = opc;
7676  let Inst{15-13} = 0b101;
7677  let Inst{12-10} = Pg;
7678  let Inst{9-5}   = Zn;
7679  let Inst{4-0}   = Zd;
7680
7681  let hasSideEffects = 0;
7682}
7683
7684multiclass sve_int_perm_rev_rbit_z<string asm, SDPatternOperator op> {
7685  def _B : sve_int_perm_rev_z<0b00, 0b0111, asm, ZPR8>;
7686  def _H : sve_int_perm_rev_z<0b01, 0b0111, asm, ZPR16>;
7687  def _S : sve_int_perm_rev_z<0b10, 0b0111, asm, ZPR32>;
7688  def _D : sve_int_perm_rev_z<0b11, 0b0111, asm, ZPR64>;
7689
7690  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
7691  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
7692  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7693  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7694}
7695
7696multiclass sve_int_perm_rev_revb_z<string asm, SDPatternOperator op> {
7697  def _H : sve_int_perm_rev_z<0b01, 0b0100, asm, ZPR16>;
7698  def _S : sve_int_perm_rev_z<0b10, 0b0100, asm, ZPR32>;
7699  def _D : sve_int_perm_rev_z<0b11, 0b0100, asm, ZPR64>;
7700
7701  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
7702  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
7703  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
7704}
7705
7706multiclass sve_int_perm_rev_revh_z<string asm, SDPatternOperator op> {
7707  def _S : sve_int_perm_rev_z<0b10, 0b0101, asm, ZPR32>;
7708  def _D : sve_int_perm_rev_z<0b11, 0b0101, asm, ZPR64>;
7709
7710  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
7711  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
7712}
7713
7714multiclass sve_int_perm_rev_revw_z<string asm, SDPatternOperator op> {
7715  def _D : sve_int_perm_rev_z<0b11, 0b0110, asm, ZPR64>;
7716
7717  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
7718}
7719
7720multiclass sve_int_perm_rev_revd_z<string asm, SDPatternOperator op> {
7721  def NAME : sve_int_perm_rev_z<0b00, 0b1110, asm, ZPR128>;
7722
7723  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME)>;
7724  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME)>;
7725  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME)>;
7726  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME)>;
7727
7728  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, !cast<Instruction>(NAME)>;
7729  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv8f16,  op, nxv8i1, nxv8f16,  !cast<Instruction>(NAME)>;
7730  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv4f32,  op, nxv4i1, nxv4f32,  !cast<Instruction>(NAME)>;
7731  defm : SVE_1_Op_PassthruUndefZero_Pat<nxv2f64,  op, nxv2i1, nxv2f64,  !cast<Instruction>(NAME)>;
7732}
7733
7734class sve_int_perm_cpy_r<bits<2> sz8_64, string asm, ZPRRegOp zprty,
7735                         RegisterClass srcRegType>
7736: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegType:$Rn),
7737  asm, "\t$Zd, $Pg/m, $Rn",
7738  "",
7739  []>, Sched<[]> {
7740  bits<3> Pg;
7741  bits<5> Rn;
7742  bits<5> Zd;
7743  let Inst{31-24} = 0b00000101;
7744  let Inst{23-22} = sz8_64;
7745  let Inst{21-13} = 0b101000101;
7746  let Inst{12-10} = Pg;
7747  let Inst{9-5}   = Rn;
7748  let Inst{4-0}   = Zd;
7749
7750  let Constraints = "$Zd = $_Zd";
7751  let DestructiveInstType = DestructiveOther;
7752  let ElementSize = zprty.ElementSize;
7753  let hasSideEffects = 0;
7754}
7755
7756multiclass sve_int_perm_cpy_r<string asm, SDPatternOperator op> {
7757  def _B : sve_int_perm_cpy_r<0b00, asm, ZPR8, GPR32sp>;
7758  def _H : sve_int_perm_cpy_r<0b01, asm, ZPR16, GPR32sp>;
7759  def _S : sve_int_perm_cpy_r<0b10, asm, ZPR32, GPR32sp>;
7760  def _D : sve_int_perm_cpy_r<0b11, asm, ZPR64, GPR64sp>;
7761
7762  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7763                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7764  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7765                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7766  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7767                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7768  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7769                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPR3bAny:$Pg, GPR64sp:$Rn), 1>;
7770
7771  def : Pat<(nxv16i8 (op nxv16i1:$pg, i32:$splat, nxv16i8:$passthru)),
7772            (!cast<Instruction>(NAME # _B) $passthru, $pg, $splat)>;
7773  def : Pat<(nxv8i16 (op nxv8i1:$pg, i32:$splat, nxv8i16:$passthru)),
7774            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7775  def : Pat<(nxv4i32 (op nxv4i1:$pg, i32:$splat, nxv4i32:$passthru)),
7776            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7777  def : Pat<(nxv2i64 (op nxv2i1:$pg, i64:$splat, nxv2i64:$passthru)),
7778            (!cast<Instruction>(NAME # _D) $passthru, $pg, $splat)>;
7779}
7780
7781class sve_int_perm_cpy_v<bits<2> sz8_64, string asm, ZPRRegOp zprty,
7782                         RegisterClass srcRegtype>
7783: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegtype:$Vn),
7784  asm, "\t$Zd, $Pg/m, $Vn",
7785  "",
7786  []>, Sched<[]> {
7787  bits<3> Pg;
7788  bits<5> Vn;
7789  bits<5> Zd;
7790  let Inst{31-24} = 0b00000101;
7791  let Inst{23-22} = sz8_64;
7792  let Inst{21-13} = 0b100000100;
7793  let Inst{12-10} = Pg;
7794  let Inst{9-5}   = Vn;
7795  let Inst{4-0}   = Zd;
7796
7797  let Constraints = "$Zd = $_Zd";
7798  let DestructiveInstType = DestructiveOther;
7799  let ElementSize = zprty.ElementSize;
7800  let hasSideEffects = 0;
7801}
7802
7803multiclass sve_int_perm_cpy_v<string asm, SDPatternOperator op> {
7804  def _B : sve_int_perm_cpy_v<0b00, asm, ZPR8, FPR8>;
7805  def _H : sve_int_perm_cpy_v<0b01, asm, ZPR16, FPR16>;
7806  def _S : sve_int_perm_cpy_v<0b10, asm, ZPR32, FPR32>;
7807  def _D : sve_int_perm_cpy_v<0b11, asm, ZPR64, FPR64>;
7808
7809  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7810                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPR3bAny:$Pg, FPR8:$Vn), 1>;
7811  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7812                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPR3bAny:$Pg, FPR16:$Vn), 1>;
7813  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7814                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPR3bAny:$Pg, FPR32:$Vn), 1>;
7815  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7816                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPR3bAny:$Pg, FPR64:$Vn), 1>;
7817
7818  def : Pat<(nxv8f16 (op nxv8i1:$pg, f16:$splat, nxv8f16:$passthru)),
7819            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7820  def : Pat<(nxv4f16 (op nxv4i1:$pg, f16:$splat, nxv4f16:$passthru)),
7821            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7822  def : Pat<(nxv2f16 (op nxv2i1:$pg, f16:$splat, nxv2f16:$passthru)),
7823            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7824  def : Pat<(nxv2f32 (op nxv2i1:$pg, f32:$splat, nxv2f32:$passthru)),
7825            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7826  def : Pat<(nxv4f32 (op nxv4i1:$pg, f32:$splat, nxv4f32:$passthru)),
7827            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7828  def : Pat<(nxv2f64 (op nxv2i1:$pg, f64:$splat, nxv2f64:$passthru)),
7829            (!cast<Instruction>(NAME # _D) $passthru, $pg, $splat)>;
7830
7831  def : Pat<(nxv8bf16 (op nxv8i1:$pg, bf16:$splat, nxv8bf16:$passthru)),
7832            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7833}
7834
7835class sve_int_perm_compact<bits<2> sz, string asm, ZPRRegOp zprty>
7836: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
7837  asm, "\t$Zd, $Pg, $Zn",
7838  "",
7839  []>, Sched<[]> {
7840  bits<3> Pg;
7841  bits<5> Zd;
7842  bits<5> Zn;
7843  let Inst{31-24} = 0b00000101;
7844  let Inst{23-22} = sz;
7845  let Inst{21-13} = 0b100001100;
7846  let Inst{12-10} = Pg;
7847  let Inst{9-5}   = Zn;
7848  let Inst{4-0}   = Zd;
7849
7850  let hasSideEffects = 0;
7851}
7852
7853multiclass sve_int_perm_compact_sd<string asm, SDPatternOperator op> {
7854  def _S : sve_int_perm_compact<0b10, asm, ZPR32>;
7855  def _D : sve_int_perm_compact<0b11, asm, ZPR64>;
7856
7857  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
7858  def : SVE_2_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
7859  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
7860  def : SVE_2_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
7861}
7862
7863multiclass sve_int_perm_compact_bh<string asm> {
7864  def _B : sve_int_perm_compact<0b00, asm, ZPR8>;
7865  def _H : sve_int_perm_compact<0b01, asm, ZPR16>;
7866}
7867
7868//===----------------------------------------------------------------------===//
7869// SVE Memory - Contiguous Load Group
7870//===----------------------------------------------------------------------===//
7871
7872class sve_mem_cld_si_base<bits<4> dtype, bit nf, string asm,
7873                          RegisterOperand VecList>
7874: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
7875  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7876  "",
7877  []>, Sched<[]> {
7878  bits<3> Pg;
7879  bits<5> Rn;
7880  bits<5> Zt;
7881  bits<4> imm4;
7882  let Inst{31-25} = 0b1010010;
7883  let Inst{24-21} = dtype;
7884  let Inst{20}    = nf;
7885  let Inst{19-16} = imm4;
7886  let Inst{15-13} = 0b101;
7887  let Inst{12-10} = Pg;
7888  let Inst{9-5}   = Rn;
7889  let Inst{4-0}   = Zt;
7890
7891  let Defs = !if(nf, [FFR], []);
7892  let Uses = !if(nf, [FFR], []);
7893  let hasSideEffects = nf;
7894  let mayLoad = 1;
7895}
7896
7897multiclass sve_mem_cld_si_base<bits<4> dtype, bit nf, string asm,
7898                               RegisterOperand listty, ZPRRegOp zprty> {
7899  def NAME : sve_mem_cld_si_base<dtype, nf, asm, listty>;
7900
7901  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7902                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7903  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7904                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
7905  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7906                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7907}
7908
7909multiclass sve_mem_cld_si<bits<4> dtype, string asm, RegisterOperand listty,
7910                          ZPRRegOp zprty>
7911: sve_mem_cld_si_base<dtype, 0, asm, listty, zprty>;
7912
7913multiclass sve_mem_cldnf_si<bits<4> dtype, string asm, RegisterOperand listty,
7914                            ZPRRegOp zprty>
7915: sve_mem_cld_si_base<dtype, 1, asm, listty, zprty>;
7916
7917class sve_mem_cldnt_si_base<bits<2> msz, string asm, RegisterOperand VecList>
7918: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
7919  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7920  "",
7921  []>, Sched<[]> {
7922  bits<5> Zt;
7923  bits<3> Pg;
7924  bits<5> Rn;
7925  bits<4> imm4;
7926  let Inst{31-25} = 0b1010010;
7927  let Inst{24-23} = msz;
7928  let Inst{22-20} = 0b000;
7929  let Inst{19-16} = imm4;
7930  let Inst{15-13} = 0b111;
7931  let Inst{12-10} = Pg;
7932  let Inst{9-5}   = Rn;
7933  let Inst{4-0}   = Zt;
7934
7935  let hasSideEffects = 0;
7936  let mayLoad = 1;
7937}
7938
7939multiclass sve_mem_cldnt_si<bits<2> msz, string asm, RegisterOperand listty,
7940                            ZPRRegOp zprty> {
7941  def NAME : sve_mem_cldnt_si_base<msz, asm, listty>;
7942
7943  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7944                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7945  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7946                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
7947  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7948                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7949}
7950
7951class sve_mem_cldnt_ss_base<bits<2> msz, string asm, RegisterOperand VecList,
7952                            RegisterOperand gprty>
7953: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7954  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7955  "",
7956  []>, Sched<[]> {
7957  bits<3> Pg;
7958  bits<5> Rm;
7959  bits<5> Rn;
7960  bits<5> Zt;
7961  let Inst{31-25} = 0b1010010;
7962  let Inst{24-23} = msz;
7963  let Inst{22-21} = 0b00;
7964  let Inst{20-16} = Rm;
7965  let Inst{15-13} = 0b110;
7966  let Inst{12-10} = Pg;
7967  let Inst{9-5}   = Rn;
7968  let Inst{4-0}   = Zt;
7969
7970  let hasSideEffects = 0;
7971  let mayLoad = 1;
7972}
7973
7974multiclass sve_mem_cldnt_ss<bits<2> msz, string asm, RegisterOperand listty,
7975                            ZPRRegOp zprty, RegisterOperand gprty> {
7976  def NAME : sve_mem_cldnt_ss_base<msz, asm, listty, gprty>;
7977
7978  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7979                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7980}
7981
7982class sve_mem_ldqr_si<bits<2> sz, string asm, RegisterOperand VecList>
7983: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4),
7984  asm, "\t$Zt, $Pg/z, [$Rn, $imm4]", "", []>, Sched<[]> {
7985  bits<5> Zt;
7986  bits<5> Rn;
7987  bits<3> Pg;
7988  bits<4> imm4;
7989  let Inst{31-25} = 0b1010010;
7990  let Inst{24-23} = sz;
7991  let Inst{22-20} = 0;
7992  let Inst{19-16} = imm4;
7993  let Inst{15-13} = 0b001;
7994  let Inst{12-10} = Pg;
7995  let Inst{9-5}   = Rn;
7996  let Inst{4-0}   = Zt;
7997
7998  let hasSideEffects = 0;
7999  let mayLoad = 1;
8000}
8001
8002multiclass sve_mem_ldqr_si<bits<2> sz, string asm, RegisterOperand listty,
8003                           ZPRRegOp zprty> {
8004  def NAME : sve_mem_ldqr_si<sz, asm, listty>;
8005  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
8006                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
8007  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
8008                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
8009  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4]",
8010                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4), 0>;
8011}
8012
8013class sve_mem_ldqr_ss<bits<2> sz, string asm, RegisterOperand VecList,
8014                      RegisterOperand gprty>
8015: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
8016  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]", "", []>, Sched<[]> {
8017  bits<5> Zt;
8018  bits<3> Pg;
8019  bits<5> Rn;
8020  bits<5> Rm;
8021  let Inst{31-25} = 0b1010010;
8022  let Inst{24-23} = sz;
8023  let Inst{22-21} = 0;
8024  let Inst{20-16} = Rm;
8025  let Inst{15-13} = 0;
8026  let Inst{12-10} = Pg;
8027  let Inst{9-5}   = Rn;
8028  let Inst{4-0}   = Zt;
8029
8030  let hasSideEffects = 0;
8031  let mayLoad = 1;
8032}
8033
8034multiclass sve_mem_ldqr_ss<bits<2> sz, string asm, RegisterOperand listty,
8035                           ZPRRegOp zprty, RegisterOperand gprty> {
8036  def NAME : sve_mem_ldqr_ss<sz, asm, listty, gprty>;
8037
8038  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
8039                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
8040}
8041
8042class sve_mem_ld_dup<bits<2> dtypeh, bits<2> dtypel, string asm,
8043                     RegisterOperand VecList, Operand immtype>
8044: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm6),
8045  asm, "\t$Zt, $Pg/z, [$Rn, $imm6]",
8046  "",
8047  []>, Sched<[]> {
8048  bits<3> Pg;
8049  bits<5> Rn;
8050  bits<5> Zt;
8051  bits<6> imm6;
8052  let Inst{31-25} = 0b1000010;
8053  let Inst{24-23} = dtypeh;
8054  let Inst{22}    = 1;
8055  let Inst{21-16} = imm6;
8056  let Inst{15}    = 0b1;
8057  let Inst{14-13} = dtypel;
8058  let Inst{12-10} = Pg;
8059  let Inst{9-5}   = Rn;
8060  let Inst{4-0}   = Zt;
8061
8062  let hasSideEffects = 0;
8063  let mayLoad = 1;
8064}
8065
8066multiclass sve_mem_ld_dup<bits<2> dtypeh, bits<2> dtypel, string asm,
8067                          RegisterOperand zlistty, ZPRRegOp zprty, Operand immtype> {
8068  def NAME : sve_mem_ld_dup<dtypeh, dtypel, asm, zlistty, immtype>;
8069
8070  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
8071                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
8072  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm6]",
8073                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm6), 0>;
8074  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
8075                  (!cast<Instruction>(NAME) zlistty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
8076}
8077
8078class sve_mem_cld_ss_base<bits<4> dtype, bit ff, dag iops, string asm,
8079                          RegisterOperand VecList>
8080: I<(outs VecList:$Zt), iops,
8081  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
8082  "",
8083  []>, Sched<[]> {
8084  bits<5> Zt;
8085  bits<3> Pg;
8086  bits<5> Rm;
8087  bits<5> Rn;
8088  let Inst{31-25} = 0b1010010;
8089  let Inst{24-21} = dtype;
8090  let Inst{20-16} = Rm;
8091  let Inst{15-14} = 0b01;
8092  let Inst{13}    = ff;
8093  let Inst{12-10} = Pg;
8094  let Inst{9-5}   = Rn;
8095  let Inst{4-0}   = Zt;
8096
8097  let Defs = !if(ff, [FFR], []);
8098  let Uses = !if(ff, [FFR], []);
8099  let hasSideEffects = ff;
8100  let mayLoad = 1;
8101}
8102
8103multiclass sve_mem_cld_ss<bits<4> dtype, string asm, RegisterOperand listty,
8104                          ZPRRegOp zprty, RegisterOperand gprty> {
8105  def NAME : sve_mem_cld_ss_base<dtype, 0, (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
8106                               asm, listty>;
8107
8108  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
8109                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
8110}
8111
8112multiclass sve_mem_cldff_ss<bits<4> dtype, string asm, RegisterOperand listty,
8113                            ZPRRegOp zprty, RegisterOperand gprty> {
8114  def NAME : sve_mem_cld_ss_base<dtype, 1, (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), asm, listty>;
8115
8116  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
8117                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
8118
8119  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
8120                 (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 1>;
8121
8122  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
8123                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 0>;
8124}
8125
8126class sve_mem_eld_si<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
8127                     string asm, Operand immtype>
8128: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
8129  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
8130  "",
8131  []>, Sched<[]> {
8132  bits<5> Zt;
8133  bits<3> Pg;
8134  bits<5> Rn;
8135  bits<4> imm4;
8136  let Inst{31-25} = 0b1010010;
8137  let Inst{24-23} = sz;
8138  let Inst{22-21} = nregs{1-0};
8139  let Inst{20}    = nregs{2};
8140  let Inst{19-16} = imm4;
8141  let Inst{15-13} = 0b111;
8142  let Inst{12-10} = Pg;
8143  let Inst{9-5}   = Rn;
8144  let Inst{4-0}   = Zt;
8145
8146  let hasSideEffects = 0;
8147  let mayLoad = 1;
8148}
8149
8150multiclass sve_mem_eld_si<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
8151                          string asm, Operand immtype> {
8152  def NAME : sve_mem_eld_si<sz, nregs, VecList, asm, immtype>;
8153
8154  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
8155                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
8156}
8157
8158
8159class sve_mem_eld_ss<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
8160                     string asm, RegisterOperand gprty>
8161: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
8162  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
8163  "",
8164  []>, Sched<[]> {
8165  bits<3> Pg;
8166  bits<5> Rm;
8167  bits<5> Rn;
8168  bits<5> Zt;
8169  let Inst{31-25} = 0b1010010;
8170  let Inst{24-23} = sz;
8171  let Inst{22-21} = nregs{1-0};
8172  let Inst{20-16} = Rm;
8173  let Inst{15}    = 0b1;
8174  let Inst{14}    = nregs{2};
8175  let Inst{13}    = 0b0;
8176  let Inst{12-10} = Pg;
8177  let Inst{9-5}   = Rn;
8178  let Inst{4-0}   = Zt;
8179
8180  let hasSideEffects = 0;
8181  let mayLoad = 1;
8182}
8183
8184//===----------------------------------------------------------------------===//
8185// SVE Memory - 32-bit Gather and Unsized Contiguous Group
8186//===----------------------------------------------------------------------===//
8187
8188// bit xs      is '1' if offsets are signed
8189// bit scaled  is '1' if the offsets are scaled
8190class sve_mem_32b_gld_sv<bits<4> opc, bit xs, bit scaled, string asm,
8191                         RegisterOperand zprext>
8192: I<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
8193  asm, "\t$Zt, $Pg/z, [$Rn, $Zm]",
8194  "",
8195  []>, Sched<[]> {
8196  bits<3> Pg;
8197  bits<5> Rn;
8198  bits<5> Zm;
8199  bits<5> Zt;
8200  let Inst{31-25} = 0b1000010;
8201  let Inst{24-23} = opc{3-2};
8202  let Inst{22}    = xs;
8203  let Inst{21}    = scaled;
8204  let Inst{20-16} = Zm;
8205  let Inst{15}    = 0b0;
8206  let Inst{14-13} = opc{1-0};
8207  let Inst{12-10} = Pg;
8208  let Inst{9-5}   = Rn;
8209  let Inst{4-0}   = Zt;
8210
8211
8212  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
8213  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
8214  let hasSideEffects = opc{0};
8215  let mayLoad = 1;
8216}
8217
8218multiclass sve_mem_32b_gld_sv_32_scaled<bits<4> opc, string asm,
8219                                        SDPatternOperator sxtw_op,
8220                                        SDPatternOperator uxtw_op,
8221                                        RegisterOperand sxtw_opnd,
8222                                        RegisterOperand uxtw_opnd,
8223                                        ValueType vt> {
8224  def _UXTW_SCALED : sve_mem_32b_gld_sv<opc, 0, 1, asm, uxtw_opnd>;
8225  def _SXTW_SCALED : sve_mem_32b_gld_sv<opc, 1, 1, asm, sxtw_opnd>;
8226
8227  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8228                  (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
8229  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8230                  (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
8231
8232  def : Pat<(nxv4i32 (uxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$indices), vt)),
8233            (!cast<Instruction>(NAME # _UXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8234  def : Pat<(nxv4i32 (sxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$indices), vt)),
8235            (!cast<Instruction>(NAME # _SXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8236}
8237
8238multiclass sve_mem_32b_gld_vs_32_unscaled<bits<4> opc, string asm,
8239                                          SDPatternOperator sxtw_op,
8240                                          SDPatternOperator uxtw_op,
8241                                          RegisterOperand sxtw_opnd,
8242                                          RegisterOperand uxtw_opnd,
8243                                          ValueType vt> {
8244  def _UXTW : sve_mem_32b_gld_sv<opc, 0, 0, asm, uxtw_opnd>;
8245  def _SXTW : sve_mem_32b_gld_sv<opc, 1, 0, asm, sxtw_opnd>;
8246
8247  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8248                  (!cast<Instruction>(NAME # _UXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
8249  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8250                  (!cast<Instruction>(NAME # _SXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
8251
8252  def : Pat<(nxv4i32 (uxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt)),
8253            (!cast<Instruction>(NAME # _UXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8254  def : Pat<(nxv4i32 (sxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt)),
8255            (!cast<Instruction>(NAME # _SXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8256}
8257
8258
8259class sve_mem_32b_gld_vi<bits<4> opc, string asm, Operand imm_ty>
8260: I<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5),
8261  asm, "\t$Zt, $Pg/z, [$Zn, $imm5]",
8262  "",
8263  []>, Sched<[]> {
8264  bits<3> Pg;
8265  bits<5> Zn;
8266  bits<5> Zt;
8267  bits<5> imm5;
8268  let Inst{31-25} = 0b1000010;
8269  let Inst{24-23} = opc{3-2};
8270  let Inst{22-21} = 0b01;
8271  let Inst{20-16} = imm5;
8272  let Inst{15}    = 0b1;
8273  let Inst{14-13} = opc{1-0};
8274  let Inst{12-10} = Pg;
8275  let Inst{9-5}   = Zn;
8276  let Inst{4-0}   = Zt;
8277
8278
8279  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
8280  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
8281  let hasSideEffects = opc{0};
8282  let mayLoad = 1;
8283}
8284
8285multiclass sve_mem_32b_gld_vi_32_ptrs<bits<4> opc, string asm, Operand imm_ty,
8286                                      SDPatternOperator op, ValueType vt> {
8287  def _IMM : sve_mem_32b_gld_vi<opc, asm, imm_ty>;
8288
8289  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8290                  (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 0>;
8291  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $imm5]",
8292                  (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), 0>;
8293  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8294                  (!cast<Instruction>(NAME # _IMM) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
8295
8296  def : Pat<(nxv4i32 (op (nxv4i1 PPR:$gp), (nxv4i32 ZPR:$ptrs), imm_ty:$index, vt)),
8297            (!cast<Instruction>(NAME # _IMM) PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
8298}
8299
8300class sve_mem_prfm_si<bits<2> msz, string asm>
8301: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, simm6s1:$imm6),
8302  asm, "\t$prfop, $Pg, [$Rn, $imm6, mul vl]",
8303  "",
8304  []>, Sched<[]> {
8305  bits<5> Rn;
8306  bits<3> Pg;
8307  bits<6> imm6;
8308  bits<4> prfop;
8309  let Inst{31-22} = 0b1000010111;
8310  let Inst{21-16} = imm6;
8311  let Inst{15}    = 0b0;
8312  let Inst{14-13} = msz;
8313  let Inst{12-10} = Pg;
8314  let Inst{9-5}   = Rn;
8315  let Inst{4}     = 0b0;
8316  let Inst{3-0}   = prfop;
8317
8318  let hasSideEffects = 1;
8319}
8320
8321multiclass sve_mem_prfm_si<bits<2> msz, string asm> {
8322  def NAME : sve_mem_prfm_si<msz, asm>;
8323
8324  def : InstAlias<asm # "\t$prfop, $Pg, [$Rn]",
8325                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
8326}
8327
8328class sve_mem_prfm_ss<bits<3> opc, string asm, RegisterOperand gprty>
8329: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
8330  asm, "\t$prfop, $Pg, [$Rn, $Rm]",
8331  "",
8332  []>, Sched<[]> {
8333  bits<5> Rm;
8334  bits<5> Rn;
8335  bits<3> Pg;
8336  bits<4> prfop;
8337  let Inst{31-25} = 0b1000010;
8338  let Inst{24-23} = opc{2-1};
8339  let Inst{22-21} = 0b00;
8340  let Inst{20-16} = Rm;
8341  let Inst{15}    = 0b1;
8342  let Inst{14}    = opc{0};
8343  let Inst{13}    = 0b0;
8344  let Inst{12-10} = Pg;
8345  let Inst{9-5}   = Rn;
8346  let Inst{4}     = 0b0;
8347  let Inst{3-0}   = prfop;
8348
8349  let hasSideEffects = 1;
8350}
8351
8352class sve_mem_32b_prfm_sv<bits<2> msz, bit xs, string asm,
8353                          RegisterOperand zprext>
8354: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
8355  asm, "\t$prfop, $Pg, [$Rn, $Zm]",
8356  "",
8357  []>, Sched<[]> {
8358  bits<3> Pg;
8359  bits<5> Rn;
8360  bits<5> Zm;
8361  bits<4> prfop;
8362  let Inst{31-23} = 0b100001000;
8363  let Inst{22}    = xs;
8364  let Inst{21}    = 0b1;
8365  let Inst{20-16} = Zm;
8366  let Inst{15}    = 0b0;
8367  let Inst{14-13} = msz;
8368  let Inst{12-10} = Pg;
8369  let Inst{9-5}   = Rn;
8370  let Inst{4}     = 0b0;
8371  let Inst{3-0}   = prfop;
8372
8373  let hasSideEffects = 1;
8374}
8375
8376multiclass sve_mem_32b_prfm_sv_scaled<bits<2> msz, string asm,
8377                                      RegisterOperand sxtw_opnd,
8378                                      RegisterOperand uxtw_opnd,
8379                                      SDPatternOperator op_sxtw,
8380                                      SDPatternOperator op_uxtw> {
8381  def _UXTW_SCALED : sve_mem_32b_prfm_sv<msz, 0, asm, uxtw_opnd>;
8382  def _SXTW_SCALED : sve_mem_32b_prfm_sv<msz, 1, asm, sxtw_opnd>;
8383
8384  def : Pat<(op_uxtw (nxv4i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv4i32 uxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
8385            (!cast<Instruction>(NAME # _UXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8386
8387  def : Pat<(op_sxtw (nxv4i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv4i32 sxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
8388            (!cast<Instruction>(NAME # _SXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8389}
8390
8391class sve_mem_32b_prfm_vi<bits<2> msz, string asm, Operand imm_ty>
8392: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5),
8393  asm, "\t$prfop, $Pg, [$Zn, $imm5]",
8394  "",
8395  []>, Sched<[]> {
8396  bits<3> Pg;
8397  bits<5> Zn;
8398  bits<5> imm5;
8399  bits<4> prfop;
8400  let Inst{31-25} = 0b1000010;
8401  let Inst{24-23} = msz;
8402  let Inst{22-21} = 0b00;
8403  let Inst{20-16} = imm5;
8404  let Inst{15-13} = 0b111;
8405  let Inst{12-10} = Pg;
8406  let Inst{9-5}   = Zn;
8407  let Inst{4}     = 0b0;
8408  let Inst{3-0}   = prfop;
8409
8410  let hasSideEffects = 1;
8411}
8412
8413multiclass sve_mem_32b_prfm_vi<bits<2> msz, string asm, Operand imm_ty, SDPatternOperator op> {
8414  def NAME : sve_mem_32b_prfm_vi<msz, asm, imm_ty>;
8415
8416  def : InstAlias<asm # "\t$prfop, $Pg, [$Zn]",
8417                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
8418
8419  def : Pat<(op (nxv4i1 PPR_3b:$Pg), (nxv4i32 ZPR32:$Zn), (i64 imm_ty:$imm), (i32 sve_prfop:$prfop)),
8420            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR_3b:$Pg, ZPR32:$Zn, imm_ty:$imm)>;
8421}
8422
8423class sve_mem_z_fill<string asm>
8424: I<(outs ZPRAny:$Zt), (ins GPR64sp:$Rn, simm9:$imm9),
8425  asm, "\t$Zt, [$Rn, $imm9, mul vl]",
8426  "",
8427  []>, Sched<[]> {
8428  bits<5> Rn;
8429  bits<5> Zt;
8430  bits<9> imm9;
8431  let Inst{31-22} = 0b1000010110;
8432  let Inst{21-16} = imm9{8-3};
8433  let Inst{15-13} = 0b010;
8434  let Inst{12-10} = imm9{2-0};
8435  let Inst{9-5}   = Rn;
8436  let Inst{4-0}   = Zt;
8437
8438  let hasSideEffects = 0;
8439  let mayLoad = 1;
8440}
8441
8442multiclass sve_mem_z_fill<string asm> {
8443  def NAME : sve_mem_z_fill<asm>;
8444
8445  def : InstAlias<asm # "\t$Zt, [$Rn]",
8446                  (!cast<Instruction>(NAME) ZPRAny:$Zt, GPR64sp:$Rn, 0), 1>;
8447}
8448
8449class sve_mem_p_fill<string asm>
8450: I<(outs PPRorPNRAny:$Pt), (ins GPR64sp:$Rn, simm9:$imm9),
8451  asm, "\t$Pt, [$Rn, $imm9, mul vl]",
8452  "",
8453  []>, Sched<[]> {
8454  bits<4> Pt;
8455  bits<5> Rn;
8456  bits<9> imm9;
8457  let Inst{31-22} = 0b1000010110;
8458  let Inst{21-16} = imm9{8-3};
8459  let Inst{15-13} = 0b000;
8460  let Inst{12-10} = imm9{2-0};
8461  let Inst{9-5}   = Rn;
8462  let Inst{4}     = 0b0;
8463  let Inst{3-0}   = Pt;
8464
8465  let hasSideEffects = 0;
8466  let mayLoad = 1;
8467}
8468
8469multiclass sve_mem_p_fill<string asm> {
8470  def NAME : sve_mem_p_fill<asm>;
8471
8472  def : InstAlias<asm # "\t$Pt, [$Rn]",
8473                  (!cast<Instruction>(NAME) PPRorPNRAny:$Pt, GPR64sp:$Rn, 0), 1>;
8474}
8475
8476class sve2_mem_gldnt_vs_base<bits<5> opc, dag iops, string asm,
8477                             RegisterOperand VecList>
8478: I<(outs VecList:$Zt), iops,
8479  asm, "\t$Zt, $Pg/z, [$Zn, $Rm]",
8480  "",
8481  []>, Sched<[]> {
8482  bits<3> Pg;
8483  bits<5> Rm;
8484  bits<5> Zn;
8485  bits<5> Zt;
8486  let Inst{31}    = 0b1;
8487  let Inst{30}    = opc{4};
8488  let Inst{29-25} = 0b00010;
8489  let Inst{24-23} = opc{3-2};
8490  let Inst{22-21} = 0b00;
8491  let Inst{20-16} = Rm;
8492  let Inst{15}    = 0b1;
8493  let Inst{14-13} = opc{1-0};
8494  let Inst{12-10} = Pg;
8495  let Inst{9-5}   = Zn;
8496  let Inst{4-0}   = Zt;
8497
8498  let hasSideEffects = 0;
8499  let mayLoad = 1;
8500}
8501
8502multiclass sve2_mem_gldnt_vs_32_ptrs<bits<5> opc, string asm,
8503                                  SDPatternOperator op,
8504                                  ValueType vt> {
8505  def NAME : sve2_mem_gldnt_vs_base<opc, (ins PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm), asm, Z_s>;
8506
8507  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $Rm]",
8508                 (!cast<Instruction>(NAME) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm), 0>;
8509  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8510                 (!cast<Instruction>(NAME) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 0>;
8511  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8512                 (!cast<Instruction>(NAME) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 1>;
8513
8514  def : Pat <(nxv4i32 (op (nxv4i1 PPR3bAny:$Pg), (nxv4i32 ZPR32:$Zd), (i64 GPR64:$Rm), vt)),
8515             (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR32:$Zd, GPR64:$Rm)>;
8516}
8517
8518multiclass sve2_mem_gldnt_vs_64_ptrs<bits<5> opc, string asm,
8519                                   SDPatternOperator op,
8520                                   ValueType vt> {
8521  def NAME : sve2_mem_gldnt_vs_base<opc, (ins PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm), asm, Z_d>;
8522
8523  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $Rm]",
8524                 (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm), 0>;
8525  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8526                 (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 0>;
8527  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8528                 (!cast<Instruction>(NAME) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
8529
8530  def : Pat <(nxv2i64 (op (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zd), (i64 GPR64:$Rm), vt)),
8531             (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zd, GPR64:$Rm)>;
8532}
8533
8534//===----------------------------------------------------------------------===//
8535// SVE Memory - 64-bit Gather Group
8536//===----------------------------------------------------------------------===//
8537
8538// bit xs      is '1' if offsets are signed
8539// bit scaled  is '1' if the offsets are scaled
8540// bit lsl     is '0' if the offsets are extended (uxtw/sxtw), '1' if shifted (lsl)
8541class sve_mem_64b_gld_sv<bits<4> opc, bit xs, bit scaled, bit lsl, string asm,
8542                         RegisterOperand zprext>
8543: I<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
8544  asm, "\t$Zt, $Pg/z, [$Rn, $Zm]",
8545  "",
8546  []>, Sched<[]> {
8547  bits<3> Pg;
8548  bits<5> Rn;
8549  bits<5> Zm;
8550  bits<5> Zt;
8551  let Inst{31-25} = 0b1100010;
8552  let Inst{24-23} = opc{3-2};
8553  let Inst{22}    = xs;
8554  let Inst{21}    = scaled;
8555  let Inst{20-16} = Zm;
8556  let Inst{15}    = lsl;
8557  let Inst{14-13} = opc{1-0};
8558  let Inst{12-10} = Pg;
8559  let Inst{9-5}   = Rn;
8560  let Inst{4-0}   = Zt;
8561
8562
8563  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
8564  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
8565  let hasSideEffects = opc{0};
8566  let mayLoad = 1;
8567}
8568
8569multiclass sve_mem_64b_gld_sv_32_scaled<bits<4> opc, string asm,
8570                                        SDPatternOperator sxtw_op,
8571                                        SDPatternOperator uxtw_op,
8572                                        RegisterOperand sxtw_opnd,
8573                                        RegisterOperand uxtw_opnd,
8574                                        ValueType vt> {
8575  def _UXTW_SCALED : sve_mem_64b_gld_sv<opc, 0, 1, 0, asm, uxtw_opnd>;
8576  def _SXTW_SCALED : sve_mem_64b_gld_sv<opc, 1, 1, 0, asm, sxtw_opnd>;
8577
8578  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8579                  (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
8580  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8581                  (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
8582
8583  def : Pat<(nxv2i64 (uxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8584            (!cast<Instruction>(NAME # _UXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8585  def : Pat<(nxv2i64 (sxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8586            (!cast<Instruction>(NAME # _SXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8587}
8588
8589multiclass sve_mem_64b_gld_vs_32_unscaled<bits<4> opc, string asm,
8590                                          SDPatternOperator sxtw_op,
8591                                          SDPatternOperator uxtw_op,
8592                                          RegisterOperand sxtw_opnd,
8593                                          RegisterOperand uxtw_opnd,
8594                                          ValueType vt> {
8595  def _UXTW : sve_mem_64b_gld_sv<opc, 0, 0, 0, asm, uxtw_opnd>;
8596  def _SXTW : sve_mem_64b_gld_sv<opc, 1, 0, 0, asm, sxtw_opnd>;
8597
8598  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8599                  (!cast<Instruction>(NAME # _UXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
8600  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8601                  (!cast<Instruction>(NAME # _SXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
8602
8603  def : Pat<(nxv2i64 (uxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8604            (!cast<Instruction>(NAME # _UXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8605  def : Pat<(nxv2i64 (sxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8606            (!cast<Instruction>(NAME # _SXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8607}
8608
8609multiclass sve_mem_64b_gld_sv2_64_scaled<bits<4> opc, string asm,
8610                                         SDPatternOperator op,
8611                                         RegisterOperand zprext, ValueType vt> {
8612  def _SCALED : sve_mem_64b_gld_sv<opc, 1, 1, 1, asm, zprext>;
8613
8614  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8615                  (!cast<Instruction>(NAME # _SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), 0>;
8616
8617  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8618                     (!cast<Instruction>(NAME # _SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8619}
8620
8621multiclass sve_mem_64b_gld_vs2_64_unscaled<bits<4> opc, string asm,
8622                                           SDPatternOperator op, ValueType vt> {
8623  def NAME : sve_mem_64b_gld_sv<opc, 1, 0, 1, asm, ZPR64ExtLSL8>;
8624
8625  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8626                  (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), 0>;
8627
8628  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8629            (!cast<Instruction>(NAME) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8630}
8631
8632class sve_mem_64b_gld_vi<bits<4> opc, string asm, Operand imm_ty>
8633: I<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5),
8634  asm, "\t$Zt, $Pg/z, [$Zn, $imm5]",
8635  "",
8636  []>, Sched<[]> {
8637  bits<3> Pg;
8638  bits<5> Zn;
8639  bits<5> Zt;
8640  bits<5> imm5;
8641  let Inst{31-25} = 0b1100010;
8642  let Inst{24-23} = opc{3-2};
8643  let Inst{22-21} = 0b01;
8644  let Inst{20-16} = imm5;
8645  let Inst{15}    = 0b1;
8646  let Inst{14-13} = opc{1-0};
8647  let Inst{12-10} = Pg;
8648  let Inst{9-5}   = Zn;
8649  let Inst{4-0}   = Zt;
8650
8651  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
8652  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
8653  let hasSideEffects = opc{0};
8654  let mayLoad = 1;
8655}
8656
8657multiclass sve_mem_64b_gld_vi_64_ptrs<bits<4> opc, string asm, Operand imm_ty,
8658                                      SDPatternOperator op, ValueType vt> {
8659  def _IMM : sve_mem_64b_gld_vi<opc, asm, imm_ty>;
8660
8661  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8662                  (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 0>;
8663  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $imm5]",
8664                  (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), 0>;
8665  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8666                  (!cast<Instruction>(NAME # _IMM) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
8667
8668  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), (nxv2i64 ZPR:$ptrs), imm_ty:$index, vt)),
8669            (!cast<Instruction>(NAME # _IMM) PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
8670}
8671
8672// bit lsl is '0' if the offsets are extended (uxtw/sxtw), '1' if shifted (lsl)
8673class sve_mem_64b_prfm_sv<bits<2> msz, bit xs, bit lsl, string asm,
8674                          RegisterOperand zprext>
8675: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
8676  asm, "\t$prfop, $Pg, [$Rn, $Zm]",
8677  "",
8678  []>, Sched<[]> {
8679  bits<3> Pg;
8680  bits<5> Rn;
8681  bits<5> Zm;
8682  bits<4> prfop;
8683  let Inst{31-23} = 0b110001000;
8684  let Inst{22}    = xs;
8685  let Inst{21}    = 0b1;
8686  let Inst{20-16} = Zm;
8687  let Inst{15}    = lsl;
8688  let Inst{14-13} = msz;
8689  let Inst{12-10} = Pg;
8690  let Inst{9-5}   = Rn;
8691  let Inst{4}     = 0b0;
8692  let Inst{3-0}   = prfop;
8693
8694  let hasSideEffects = 1;
8695}
8696
8697multiclass sve_mem_64b_prfm_sv_ext_scaled<bits<2> msz, string asm,
8698                                          RegisterOperand sxtw_opnd,
8699                                          RegisterOperand uxtw_opnd,
8700                                          SDPatternOperator op_sxtw,
8701                                          SDPatternOperator op_uxtw> {
8702  def _UXTW_SCALED : sve_mem_64b_prfm_sv<msz, 0, 0, asm, uxtw_opnd>;
8703  def _SXTW_SCALED : sve_mem_64b_prfm_sv<msz, 1, 0, asm, sxtw_opnd>;
8704
8705  def : Pat<(op_uxtw (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 uxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
8706            (!cast<Instruction>(NAME # _UXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8707
8708  def : Pat<(op_sxtw (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 sxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
8709            (!cast<Instruction>(NAME # _SXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8710
8711}
8712
8713multiclass sve_mem_64b_prfm_sv_lsl_scaled<bits<2> msz, string asm,
8714                                          RegisterOperand zprext, SDPatternOperator frag> {
8715  def NAME : sve_mem_64b_prfm_sv<msz, 1, 1, asm, zprext>;
8716
8717  def : Pat<(frag (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 zprext:$Zm), (i32 sve_prfop:$prfop)),
8718            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm)>;
8719
8720}
8721
8722class sve_mem_64b_prfm_vi<bits<2> msz, string asm, Operand imm_ty>
8723: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5),
8724  asm, "\t$prfop, $Pg, [$Zn, $imm5]",
8725  "",
8726  []>, Sched<[]> {
8727  bits<3> Pg;
8728  bits<5> Zn;
8729  bits<5> imm5;
8730  bits<4> prfop;
8731  let Inst{31-25} = 0b1100010;
8732  let Inst{24-23} = msz;
8733  let Inst{22-21} = 0b00;
8734  let Inst{20-16} = imm5;
8735  let Inst{15-13} = 0b111;
8736  let Inst{12-10} = Pg;
8737  let Inst{9-5}   = Zn;
8738  let Inst{4}     = 0b0;
8739  let Inst{3-0}   = prfop;
8740
8741  let hasSideEffects = 1;
8742}
8743
8744multiclass sve_mem_64b_prfm_vi<bits<2> msz, string asm, Operand imm_ty, SDPatternOperator op> {
8745  def NAME : sve_mem_64b_prfm_vi<msz, asm, imm_ty>;
8746
8747  def : InstAlias<asm # "\t$prfop, $Pg, [$Zn]",
8748                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
8749
8750  def : Pat<(op (nxv2i1 PPR_3b:$Pg), (nxv2i64 ZPR32:$Zn), (i64 imm_ty:$imm), (i32 sve_prfop:$prfop)),
8751            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR_3b:$Pg, ZPR32:$Zn, imm_ty:$imm)>;
8752}
8753
8754//===----------------------------------------------------------------------===//
8755// SVE Compute Vector Address Group
8756//===----------------------------------------------------------------------===//
8757
8758class sve_int_bin_cons_misc_0_a<bits<2> opc, bits<2> msz, string asm,
8759                                ZPRRegOp zprty, RegisterOperand zprext>
8760: I<(outs zprty:$Zd), (ins zprty:$Zn, zprext:$Zm),
8761  asm, "\t$Zd, [$Zn, $Zm]",
8762  "",
8763  []>, Sched<[]> {
8764  bits<5> Zd;
8765  bits<5> Zn;
8766  bits<5> Zm;
8767  let Inst{31-24} = 0b00000100;
8768  let Inst{23-22} = opc;
8769  let Inst{21}    = 0b1;
8770  let Inst{20-16} = Zm;
8771  let Inst{15-12} = 0b1010;
8772  let Inst{11-10} = msz;
8773  let Inst{9-5}   = Zn;
8774  let Inst{4-0}   = Zd;
8775
8776  let hasSideEffects = 0;
8777}
8778
8779multiclass sve_int_bin_cons_misc_0_a_uxtw<bits<2> opc, string asm> {
8780  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtUXTW8>;
8781  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtUXTW16>;
8782  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtUXTW32>;
8783  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtUXTW64>;
8784}
8785
8786multiclass sve_int_bin_cons_misc_0_a_sxtw<bits<2> opc, string asm> {
8787  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtSXTW8>;
8788  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtSXTW16>;
8789  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtSXTW32>;
8790  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtSXTW64>;
8791}
8792
8793multiclass sve_int_bin_cons_misc_0_a_32_lsl<bits<2> opc, string asm> {
8794  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR32, ZPR32ExtLSL8>;
8795  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR32, ZPR32ExtLSL16>;
8796  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR32, ZPR32ExtLSL32>;
8797  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR32, ZPR32ExtLSL64>;
8798}
8799
8800multiclass sve_int_bin_cons_misc_0_a_64_lsl<bits<2> opc, string asm> {
8801  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtLSL8>;
8802  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtLSL16>;
8803  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtLSL32>;
8804  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtLSL64>;
8805}
8806
8807//===----------------------------------------------------------------------===//
8808// SVE Integer Misc - Unpredicated Group
8809//===----------------------------------------------------------------------===//
8810
8811class sve_int_bin_cons_misc_0_b<bits<2> sz, string asm, ZPRRegOp zprty>
8812: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
8813  asm, "\t$Zd, $Zn, $Zm",
8814  "",
8815  []>, Sched<[]> {
8816  bits<5> Zd;
8817  bits<5> Zm;
8818  bits<5> Zn;
8819  let Inst{31-24} = 0b00000100;
8820  let Inst{23-22} = sz;
8821  let Inst{21}    = 0b1;
8822  let Inst{20-16} = Zm;
8823  let Inst{15-10} = 0b101100;
8824  let Inst{9-5}   = Zn;
8825  let Inst{4-0}   = Zd;
8826
8827  let hasSideEffects = 0;
8828}
8829
8830multiclass sve_int_bin_cons_misc_0_b<string asm, SDPatternOperator op> {
8831  def _H : sve_int_bin_cons_misc_0_b<0b01, asm, ZPR16>;
8832  def _S : sve_int_bin_cons_misc_0_b<0b10, asm, ZPR32>;
8833  def _D : sve_int_bin_cons_misc_0_b<0b11, asm, ZPR64>;
8834
8835  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
8836  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
8837  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
8838}
8839
8840class sve_int_bin_cons_misc_0_c<bits<8> opc, string asm, ZPRRegOp zprty>
8841: I<(outs zprty:$Zd), (ins zprty:$Zn),
8842  asm, "\t$Zd, $Zn",
8843  "",
8844  []>, Sched<[]> {
8845  bits<5> Zd;
8846  bits<5> Zn;
8847  let Inst{31-24} = 0b00000100;
8848  let Inst{23-22} = opc{7-6};
8849  let Inst{21}    = 0b1;
8850  let Inst{20-16} = opc{5-1};
8851  let Inst{15-11} = 0b10111;
8852  let Inst{10}    = opc{0};
8853  let Inst{9-5}   = Zn;
8854  let Inst{4-0}   = Zd;
8855
8856  let hasSideEffects = 0;
8857}
8858
8859multiclass sve_int_bin_cons_misc_0_c_fexpa<string asm, SDPatternOperator op> {
8860  def _H : sve_int_bin_cons_misc_0_c<0b01000000, asm, ZPR16>;
8861  def _S : sve_int_bin_cons_misc_0_c<0b10000000, asm, ZPR32>;
8862  def _D : sve_int_bin_cons_misc_0_c<0b11000000, asm, ZPR64>;
8863
8864  def : SVE_1_Op_Pat<nxv8f16, op, nxv8i16, !cast<Instruction>(NAME # _H)>;
8865  def : SVE_1_Op_Pat<nxv4f32, op, nxv4i32, !cast<Instruction>(NAME # _S)>;
8866  def : SVE_1_Op_Pat<nxv2f64, op, nxv2i64, !cast<Instruction>(NAME # _D)>;
8867}
8868
8869//===----------------------------------------------------------------------===//
8870// SVE Integer Reduction Group
8871//===----------------------------------------------------------------------===//
8872
8873class sve_int_reduce<bits<2> sz8_32, bits<2> fmt, bits<3> opc, string asm,
8874                     ZPRRegOp zprty, FPRasZPROperand dstOpType>
8875: I<(outs dstOpType:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
8876  asm, "\t$Vd, $Pg, $Zn",
8877  "",
8878  []>, Sched<[]> {
8879  bits<3> Pg;
8880  bits<5> Vd;
8881  bits<5> Zn;
8882  let Inst{31-24} = 0b00000100;
8883  let Inst{23-22} = sz8_32;
8884  let Inst{21}    = 0b0;
8885  let Inst{20-19} = fmt;
8886  let Inst{18-16} = opc;
8887  let Inst{15-13} = 0b001;
8888  let Inst{12-10} = Pg;
8889  let Inst{9-5}   = Zn;
8890  let Inst{4-0}   = Vd;
8891
8892  let hasSideEffects = 0;
8893}
8894
8895multiclass sve_int_reduce_0_saddv<bits<3> opc, string asm,
8896                                  SDPatternOperator op> {
8897  def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
8898  def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
8899  def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
8900
8901  def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8902  def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8903  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8904}
8905
8906multiclass sve_int_reduce_0_uaddv<bits<3> opc, string asm,
8907                                  SDPatternOperator op> {
8908  def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
8909  def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
8910  def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
8911  def _D : sve_int_reduce<0b11, 0b00, opc, asm, ZPR64, FPR64asZPR>;
8912
8913  def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8914  def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8915  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8916  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8917}
8918
8919multiclass sve_int_reduce_1<bits<3> opc, string asm,
8920                            SDPatternOperator op> {
8921  def _B : sve_int_reduce<0b00, 0b01, opc, asm, ZPR8, FPR8asZPR>;
8922  def _H : sve_int_reduce<0b01, 0b01, opc, asm, ZPR16, FPR16asZPR>;
8923  def _S : sve_int_reduce<0b10, 0b01, opc, asm, ZPR32, FPR32asZPR>;
8924  def _D : sve_int_reduce<0b11, 0b01, opc, asm, ZPR64, FPR64asZPR>;
8925
8926  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8927  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8928  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8929  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8930}
8931
8932multiclass sve_int_reduce_2<bits<3> opc, string asm,
8933                            SDPatternOperator op> {
8934  def _B : sve_int_reduce<0b00, 0b11, opc, asm, ZPR8, FPR8asZPR>;
8935  def _H : sve_int_reduce<0b01, 0b11, opc, asm, ZPR16, FPR16asZPR>;
8936  def _S : sve_int_reduce<0b10, 0b11, opc, asm, ZPR32, FPR32asZPR>;
8937  def _D : sve_int_reduce<0b11, 0b11, opc, asm, ZPR64, FPR64asZPR>;
8938
8939  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8940  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8941  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8942  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8943}
8944
8945class sve_int_movprfx_pred<bits<2> sz8_32, bits<3> opc, string asm,
8946                           ZPRRegOp zprty, string pg_suffix, dag iops>
8947: I<(outs zprty:$Zd), iops,
8948  asm, "\t$Zd, $Pg"#pg_suffix#", $Zn",
8949  "",
8950  []>, Sched<[]> {
8951  bits<3> Pg;
8952  bits<5> Zd;
8953  bits<5> Zn;
8954  let Inst{31-24} = 0b00000100;
8955  let Inst{23-22} = sz8_32;
8956  let Inst{21-19} = 0b010;
8957  let Inst{18-16} = opc;
8958  let Inst{15-13} = 0b001;
8959  let Inst{12-10} = Pg;
8960  let Inst{9-5}   = Zn;
8961  let Inst{4-0}   = Zd;
8962
8963  let ElementSize = zprty.ElementSize;
8964  let hasSideEffects = 0;
8965}
8966
8967multiclass sve_int_movprfx_pred_merge<bits<3> opc, string asm> {
8968let Constraints = "$Zd = $_Zd" in {
8969  def _B : sve_int_movprfx_pred<0b00, opc, asm, ZPR8, "/m",
8970                                (ins ZPR8:$_Zd, PPR3bAny:$Pg, ZPR8:$Zn)>;
8971  def _H : sve_int_movprfx_pred<0b01, opc, asm, ZPR16, "/m",
8972                                (ins ZPR16:$_Zd, PPR3bAny:$Pg, ZPR16:$Zn)>;
8973  def _S : sve_int_movprfx_pred<0b10, opc, asm, ZPR32, "/m",
8974                                (ins ZPR32:$_Zd, PPR3bAny:$Pg, ZPR32:$Zn)>;
8975  def _D : sve_int_movprfx_pred<0b11, opc, asm, ZPR64, "/m",
8976                                (ins ZPR64:$_Zd, PPR3bAny:$Pg, ZPR64:$Zn)>;
8977}
8978}
8979
8980multiclass sve_int_movprfx_pred_zero<bits<3> opc, string asm> {
8981  def _B : sve_int_movprfx_pred<0b00, opc, asm, ZPR8, "/z",
8982                                (ins PPR3bAny:$Pg, ZPR8:$Zn)>;
8983  def _H : sve_int_movprfx_pred<0b01, opc, asm, ZPR16, "/z",
8984                                (ins PPR3bAny:$Pg, ZPR16:$Zn)>;
8985  def _S : sve_int_movprfx_pred<0b10, opc, asm, ZPR32, "/z",
8986                                (ins PPR3bAny:$Pg, ZPR32:$Zn)>;
8987  def _D : sve_int_movprfx_pred<0b11, opc, asm, ZPR64, "/z",
8988                                (ins PPR3bAny:$Pg, ZPR64:$Zn)>;
8989}
8990
8991//===----------------------------------------------------------------------===//
8992// SVE Propagate Break Group
8993//===----------------------------------------------------------------------===//
8994
8995class sve_int_brkp<bits<2> opc, string asm>
8996: I<(outs PPR8:$Pd), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$Pm),
8997  asm, "\t$Pd, $Pg/z, $Pn, $Pm",
8998  "",
8999  []>, Sched<[]> {
9000  bits<4> Pd;
9001  bits<4> Pg;
9002  bits<4> Pm;
9003  bits<4> Pn;
9004  let Inst{31-24} = 0b00100101;
9005  let Inst{23}    = 0b0;
9006  let Inst{22}    = opc{1};
9007  let Inst{21-20} = 0b00;
9008  let Inst{19-16} = Pm;
9009  let Inst{15-14} = 0b11;
9010  let Inst{13-10} = Pg;
9011  let Inst{9}     = 0b0;
9012  let Inst{8-5}   = Pn;
9013  let Inst{4}     = opc{0};
9014  let Inst{3-0}   = Pd;
9015
9016  let Defs = !if(!eq (opc{1}, 1), [NZCV], []);
9017  let hasSideEffects = 0;
9018}
9019
9020multiclass sve_int_brkp<bits<2> opc, string asm, SDPatternOperator op> {
9021  def NAME : sve_int_brkp<opc, asm>;
9022
9023  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
9024}
9025
9026
9027//===----------------------------------------------------------------------===//
9028// SVE Partition Break Group
9029//===----------------------------------------------------------------------===//
9030
9031class sve_int_brkn<bit S, string asm>
9032: I<(outs PPR8:$Pdm), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$_Pdm),
9033  asm, "\t$Pdm, $Pg/z, $Pn, $_Pdm",
9034  "",
9035  []>, Sched<[]> {
9036  bits<4> Pdm;
9037  bits<4> Pg;
9038  bits<4> Pn;
9039  let Inst{31-23} = 0b001001010;
9040  let Inst{22}    = S;
9041  let Inst{21-14} = 0b01100001;
9042  let Inst{13-10} = Pg;
9043  let Inst{9}     = 0b0;
9044  let Inst{8-5}   = Pn;
9045  let Inst{4}     = 0b0;
9046  let Inst{3-0}   = Pdm;
9047
9048  let Constraints = "$Pdm = $_Pdm";
9049  let Defs = !if(S, [NZCV], []);
9050  let ElementSize = ElementSizeB;
9051  let hasSideEffects = 0;
9052}
9053
9054multiclass sve_int_brkn<bits<1> opc, string asm, SDPatternOperator op> {
9055  def NAME : sve_int_brkn<opc, asm>;
9056
9057  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
9058}
9059
9060class sve_int_break<bits<3> opc, string asm, string suffix, dag iops>
9061: I<(outs PPR8:$Pd), iops,
9062  asm, "\t$Pd, $Pg"#suffix#", $Pn",
9063  "",
9064  []>, Sched<[]> {
9065  bits<4> Pd;
9066  bits<4> Pg;
9067  bits<4> Pn;
9068  let Inst{31-24} = 0b00100101;
9069  let Inst{23-22} = opc{2-1};
9070  let Inst{21-14} = 0b01000001;
9071  let Inst{13-10} = Pg;
9072  let Inst{9}     = 0b0;
9073  let Inst{8-5}   = Pn;
9074  let Inst{4}     = opc{0};
9075  let Inst{3-0}   = Pd;
9076
9077  let Constraints = !if(!eq (opc{0}, 1), "$Pd = $_Pd", "");
9078  let Defs = !if(!eq (opc{1}, 1), [NZCV], []);
9079  let hasSideEffects = 0;
9080}
9081
9082multiclass sve_int_break_m<bits<3> opc, string asm, SDPatternOperator op> {
9083  def NAME : sve_int_break<opc, asm, "/m", (ins PPR8:$_Pd, PPRAny:$Pg, PPR8:$Pn)>;
9084
9085  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
9086}
9087
9088multiclass sve_int_break_z<bits<3> opc, string asm, SDPatternOperator op> {
9089  def NAME : sve_int_break<opc, asm, "/z", (ins PPRAny:$Pg, PPR8:$Pn)>;
9090
9091  def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
9092}
9093
9094//===----------------------------------------------------------------------===//
9095// SVE2 String Processing Group
9096//===----------------------------------------------------------------------===//
9097
9098class sve2_char_match<bit sz, bit opc, string asm,
9099                      PPRRegOp pprty, ZPRRegOp zprty>
9100: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
9101  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
9102  "",
9103  []>, Sched<[]> {
9104  bits<4> Pd;
9105  bits<3> Pg;
9106  bits<5> Zm;
9107  bits<5> Zn;
9108  let Inst{31-23} = 0b010001010;
9109  let Inst{22}    = sz;
9110  let Inst{21}    = 0b1;
9111  let Inst{20-16} = Zm;
9112  let Inst{15-13} = 0b100;
9113  let Inst{12-10} = Pg;
9114  let Inst{9-5}   = Zn;
9115  let Inst{4}     = opc;
9116  let Inst{3-0}   = Pd;
9117
9118  let Defs = [NZCV];
9119  let ElementSize = pprty.ElementSize;
9120  let hasSideEffects = 0;
9121  let isPTestLike = 1;
9122}
9123
9124multiclass sve2_char_match<bit opc, string asm, SDPatternOperator op> {
9125  def _B : sve2_char_match<0b0, opc, asm, PPR8, ZPR8>;
9126  def _H : sve2_char_match<0b1, opc, asm, PPR16, ZPR16>;
9127
9128  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
9129  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
9130}
9131
9132//===----------------------------------------------------------------------===//
9133// SVE2 Histogram Computation - Segment Group
9134//===----------------------------------------------------------------------===//
9135
9136class sve2_hist_gen_segment<string asm, SDPatternOperator op>
9137: I<(outs ZPR8:$Zd), (ins ZPR8:$Zn, ZPR8:$Zm),
9138  asm, "\t$Zd, $Zn, $Zm",
9139  "",
9140  [(set nxv16i8:$Zd, (op nxv16i8:$Zn, nxv16i8:$Zm))]>, Sched<[]> {
9141  bits<5> Zd;
9142  bits<5> Zn;
9143  bits<5> Zm;
9144  let Inst{31-21} = 0b01000101001;
9145  let Inst{20-16} = Zm;
9146  let Inst{15-10} = 0b101000;
9147  let Inst{9-5}   = Zn;
9148  let Inst{4-0}   = Zd;
9149
9150  let hasSideEffects = 0;
9151}
9152
9153//===----------------------------------------------------------------------===//
9154// SVE2 Histogram Computation - Vector Group
9155//===----------------------------------------------------------------------===//
9156
9157class sve2_hist_gen_vector<bit sz, string asm, ZPRRegOp zprty>
9158: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
9159  asm, "\t$Zd, $Pg/z, $Zn, $Zm",
9160  "",
9161  []>, Sched<[]> {
9162  bits<5> Zd;
9163  bits<5> Zn;
9164  bits<3> Pg;
9165  bits<5> Zm;
9166  let Inst{31-23} = 0b010001011;
9167  let Inst{22}    = sz;
9168  let Inst{21}    = 0b1;
9169  let Inst{20-16} = Zm;
9170  let Inst{15-13} = 0b110;
9171  let Inst{12-10} = Pg;
9172  let Inst{9-5}   = Zn;
9173  let Inst{4-0}   = Zd;
9174
9175  let hasSideEffects = 0;
9176}
9177
9178multiclass sve2_hist_gen_vector<string asm, SDPatternOperator op> {
9179  def _S : sve2_hist_gen_vector<0b0, asm, ZPR32>;
9180  def _D : sve2_hist_gen_vector<0b1, asm, ZPR64>;
9181
9182  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
9183  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
9184}
9185
9186//===----------------------------------------------------------------------===//
9187// SVE2 Crypto Extensions Group
9188//===----------------------------------------------------------------------===//
9189
9190class sve2_crypto_cons_bin_op<bit opc, string asm, ZPRRegOp zprty>
9191: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
9192  asm, "\t$Zd, $Zn, $Zm",
9193  "",
9194  []>, Sched<[]> {
9195  bits<5> Zd;
9196  bits<5> Zn;
9197  bits<5> Zm;
9198  let Inst{31-21} = 0b01000101001;
9199  let Inst{20-16} = Zm;
9200  let Inst{15-11} = 0b11110;
9201  let Inst{10}    = opc;
9202  let Inst{9-5}   = Zn;
9203  let Inst{4-0}   = Zd;
9204
9205  let hasSideEffects = 0;
9206}
9207
9208multiclass sve2_crypto_cons_bin_op<bit opc, string asm, ZPRRegOp zprty,
9209                                   SDPatternOperator op, ValueType vt> {
9210  def NAME : sve2_crypto_cons_bin_op<opc, asm, zprty>;
9211  def : SVE_2_Op_Pat<vt, op, vt, vt, !cast<Instruction>(NAME)>;
9212}
9213
9214class sve2_crypto_des_bin_op<bits<2> opc, string asm, ZPRRegOp zprty>
9215: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm),
9216  asm, "\t$Zdn, $_Zdn, $Zm",
9217  "",
9218  []>, Sched<[]> {
9219  bits<5> Zdn;
9220  bits<5> Zm;
9221  let Inst{31-17} = 0b010001010010001;
9222  let Inst{16}    = opc{1};
9223  let Inst{15-11} = 0b11100;
9224  let Inst{10}    = opc{0};
9225  let Inst{9-5}   = Zm;
9226  let Inst{4-0}   = Zdn;
9227
9228  let Constraints = "$Zdn = $_Zdn";
9229  let hasSideEffects = 0;
9230}
9231
9232multiclass sve2_crypto_des_bin_op<bits<2> opc, string asm, ZPRRegOp zprty,
9233                                  SDPatternOperator op, ValueType vt> {
9234  def NAME : sve2_crypto_des_bin_op<opc, asm, zprty>;
9235  def : SVE_2_Op_Pat<vt, op, vt, vt, !cast<Instruction>(NAME)>;
9236}
9237
9238class sve2_crypto_unary_op<bit opc, string asm, ZPRRegOp zprty>
9239: I<(outs zprty:$Zdn), (ins zprty:$_Zdn),
9240  asm, "\t$Zdn, $_Zdn",
9241  "",
9242  []>, Sched<[]> {
9243  bits<5> Zdn;
9244  let Inst{31-11} = 0b010001010010000011100;
9245  let Inst{10}    = opc;
9246  let Inst{9-5}   = 0b00000;
9247  let Inst{4-0}   = Zdn;
9248
9249  let Constraints = "$Zdn = $_Zdn";
9250  let hasSideEffects = 0;
9251}
9252
9253multiclass sve2_crypto_unary_op<bit opc, string asm, SDPatternOperator op> {
9254  def NAME : sve2_crypto_unary_op<opc, asm, ZPR8>;
9255  def : SVE_1_Op_Pat<nxv16i8, op, nxv16i8, !cast<Instruction>(NAME)>;
9256}
9257
9258class sve_crypto_binary_multi2<bits<3> opc, string asm>
9259: I<(outs ZZ_b_mul_r:$Zdn),
9260    (ins ZZ_b_mul_r:$_Zdn, ZPR128:$Zm, VectorIndexS32b_timm:$imm2),
9261  asm,
9262  "\t$Zdn, $_Zdn, $Zm$imm2",
9263  "",
9264  []>, Sched<[]> {
9265  bits<5> Zm;
9266  bits<4> Zdn;
9267  bits<2> imm2;
9268  let Inst{31-21} = 0b01000101001;
9269  let Inst{20-19} = imm2;
9270  let Inst{18-17} = 0b01;
9271  let Inst{16}    = opc{2};
9272  let Inst{15-11} = 0b11101;
9273  let Inst{10}    = opc{1};
9274  let Inst{9-5}   = Zm;
9275  let Inst{4-1}   = Zdn;
9276  let Inst{0}     = opc{0};
9277
9278  let Constraints = "$Zdn = $_Zdn";
9279  let hasSideEffects = 0;
9280}
9281
9282class sve_crypto_binary_multi4<bits<4> opc, string asm>
9283: I<(outs ZZZZ_b_mul_r:$Zdn),
9284    (ins ZZZZ_b_mul_r:$_Zdn, ZPR128:$Zm, VectorIndexS32b_timm:$imm2),
9285  asm,
9286  "\t$Zdn, $_Zdn, $Zm$imm2",
9287  "",
9288  []>, Sched<[]> {
9289  bits<5> Zm;
9290  bits<3> Zdn;
9291  bits<2> imm2;
9292  let Inst{31-21} = 0b01000101001;
9293  let Inst{20-19} = imm2;
9294  let Inst{18-17} = 0b11;
9295  let Inst{16}    = opc{3};
9296  let Inst{15-11} = 0b11101;
9297  let Inst{10}    = opc{2};
9298  let Inst{9-5}   = Zm;
9299  let Inst{4-2}   = Zdn;
9300  let Inst{1-0}   = opc{1-0};
9301
9302  let Constraints = "$Zdn = $_Zdn";
9303  let hasSideEffects = 0;
9304}
9305
9306class sve_crypto_pmlal_multi<string asm>
9307: I<(outs ZZ_q_mul_r:$Zda),
9308    (ins ZZ_q_mul_r:$_Zda, ZPR64:$Zn, ZPR64:$Zm),
9309  asm,
9310  "\t$Zda, $Zn, $Zm",
9311  "",
9312  []>, Sched<[]> {
9313  bits<5> Zm;
9314  bits<5> Zn;
9315  bits<4> Zda;
9316  let Inst{31-21} = 0b01000101001;
9317  let Inst{20-16} = Zm;
9318  let Inst{15-10} = 0b111111;
9319  let Inst{9-5}   = Zn;
9320  let Inst{4-1}   = Zda;
9321  let Inst{0}     = 0b0;
9322
9323  let Constraints = "$Zda = $_Zda";
9324  let hasSideEffects = 0;
9325}
9326
9327class sve_crypto_pmull_multi<string asm>
9328: I<(outs ZZ_q_mul_r:$Zd),
9329    (ins ZPR64:$Zn, ZPR64:$Zm),
9330  asm,
9331  "\t$Zd, $Zn, $Zm",
9332  "",
9333  []>, Sched<[]> {
9334  bits<5> Zm;
9335  bits<5> Zn;
9336  bits<4> Zd;
9337  let Inst{31-21} = 0b01000101001;
9338  let Inst{20-16} = Zm;
9339  let Inst{15-10} = 0b111110;
9340  let Inst{9-5}   = Zn;
9341  let Inst{4-1}   = Zd;
9342  let Inst{0}     = 0b0;
9343  let hasSideEffects = 0;
9344}
9345
9346//===----------------------------------------------------------------------===//
9347// SVE BFloat16 Group
9348//===----------------------------------------------------------------------===//
9349
9350class sve_float_dot<bit bf, bit o2, ZPRRegOp dst_ty, ZPRRegOp src_ty, string asm>
9351: I<(outs dst_ty:$Zda), (ins dst_ty:$_Zda, src_ty:$Zn, src_ty:$Zm),
9352     asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
9353  bits<5> Zda;
9354  bits<5> Zn;
9355  bits<5> Zm;
9356  let Inst{31-23} = 0b011001000;
9357  let Inst{22}    = bf;
9358  let Inst{21}    = 0b1;
9359  let Inst{20-16} = Zm;
9360  let Inst{15-11} = 0b10000;
9361  let Inst{10}    = o2;
9362  let Inst{9-5}   = Zn;
9363  let Inst{4-0}   = Zda;
9364
9365  let Constraints = "$Zda = $_Zda";
9366  let DestructiveInstType = DestructiveOther;
9367  let hasSideEffects = 0;
9368  let mayRaiseFPException = 1;
9369}
9370
9371multiclass sve_float_dot<bit bf, bit o2, ZPRRegOp dst_ty, ZPRRegOp src_ty,
9372                         string asm, ValueType InVT, SDPatternOperator op> {
9373  def NAME : sve_float_dot<bf, o2, dst_ty, src_ty, asm>;
9374  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, InVT, InVT, !cast<Instruction>(NAME)>;
9375}
9376
9377multiclass sve_fp8_dot<bit bf, ZPRRegOp dstrc, string asm, ValueType vt,
9378                       SDPatternOperator op> {
9379  def NAME : sve_float_dot<bf, 0b1, dstrc, ZPR8, asm> {
9380    let Uses = [FPMR, FPCR];
9381
9382    let mayLoad  = 1;
9383    let mayStore = 0;
9384  }
9385
9386  def : SVE_3_Op_Pat<vt, op, vt, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
9387}
9388
9389class sve_float_dot_indexed<bit bf, ZPRRegOp dst_ty, ZPRRegOp src1_ty,
9390                            ZPRRegOp src2_ty, Operand iop_ty, string asm>
9391: I<(outs dst_ty:$Zda), (ins dst_ty:$_Zda, src1_ty:$Zn, src2_ty:$Zm, iop_ty:$iop),
9392    asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
9393  bits<5> Zda;
9394  bits<5> Zn;
9395  bits<3> Zm;
9396  let Inst{31-23} = 0b011001000;
9397  let Inst{22}    = bf;
9398  let Inst{21}    = 0b1;
9399  let Inst{18-16} = Zm;
9400  let Inst{15-12} = 0b0100;
9401  let Inst{9-5}   = Zn;
9402  let Inst{4-0}   = Zda;
9403
9404  let Constraints = "$Zda = $_Zda";
9405  let DestructiveInstType = DestructiveOther;
9406  let hasSideEffects = 0;
9407  let mayRaiseFPException = 1;
9408}
9409
9410multiclass sve_float_dot_indexed<bit bf, bits<2> opc, ZPRRegOp src1_ty,
9411                                 ZPRRegOp src2_ty, string asm, ValueType InVT,
9412                                 SDPatternOperator op> {
9413  def NAME : sve_float_dot_indexed<bf, ZPR32, src1_ty, src2_ty, VectorIndexS32b, asm> {
9414    bits<2> iop;
9415    let Inst{20-19} = iop;
9416    let Inst{11-10} = opc;
9417  }
9418  def : SVE_4_Op_Imm_Pat<nxv4f32, op, nxv4f32, InVT, InVT, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
9419}
9420
9421multiclass sve_bfloat_convert<string asm, SDPatternOperator op, SDPatternOperator ir_op> {
9422  def NAME : sve_fp_2op_p_zd<0b1001010, asm, ZPR32, ZPR16, ElementSizeS>;
9423
9424  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv4i1, nxv4f32, !cast<Instruction>(NAME)>;
9425  def : SVE_1_Op_Passthru_Round_Pat<nxv4bf16, ir_op, nxv4i1, nxv4f32, !cast<Instruction>(NAME)>;
9426  def : SVE_1_Op_Passthru_Round_Pat<nxv2bf16, ir_op, nxv2i1, nxv2f32, !cast<Instruction>(NAME)>;
9427}
9428
9429multiclass sve_bfloat_convert_top<string asm,  SDPatternOperator op> {
9430  def NAME : sve2_fp_convert_precision<0b1010, 0b1, asm, ZPR16, ZPR32>;
9431
9432  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv4i1, nxv4f32, !cast<Instruction>(NAME)>;
9433}
9434
9435//===----------------------------------------------------------------------===//
9436// SVE Integer Matrix Multiply Group
9437//===----------------------------------------------------------------------===//
9438
9439class sve_int_matmul<bits<2> uns, string asm>
9440: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR8:$Zm), asm,
9441  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
9442  bits<5> Zda;
9443  bits<5> Zn;
9444  bits<5> Zm;
9445  let Inst{31-24} = 0b01000101;
9446  let Inst{23-22} = uns;
9447  let Inst{21}    = 0;
9448  let Inst{20-16} = Zm;
9449  let Inst{15-10} = 0b100110;
9450  let Inst{9-5}   = Zn;
9451  let Inst{4-0}   = Zda;
9452
9453  let Constraints = "$Zda = $_Zda";
9454  let DestructiveInstType = DestructiveOther;
9455  let ElementSize = ZPR32.ElementSize;
9456  let hasSideEffects = 0;
9457}
9458
9459multiclass sve_int_matmul<bits<2> uns, string asm, SDPatternOperator op> {
9460  def NAME : sve_int_matmul<uns, asm>;
9461
9462  def : SVE_3_Op_Pat<nxv4i32, op , nxv4i32, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
9463}
9464
9465//===----------------------------------------------------------------------===//
9466// SVE Integer Dot Product Mixed Sign Group
9467//===----------------------------------------------------------------------===//
9468
9469class sve_int_dot_mixed<string asm>
9470: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR8:$Zm), asm,
9471  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
9472  bits<5> Zda;
9473  bits<5> Zn;
9474  bits<5> Zm;
9475  let Inst{31-21} = 0b01000100100;
9476  let Inst{20-16} = Zm;
9477  let Inst{15-10} = 0b011110;
9478  let Inst{9-5}   = Zn;
9479  let Inst{4-0}   = Zda;
9480
9481  let Constraints = "$Zda = $_Zda";
9482  let DestructiveInstType = DestructiveOther;
9483  let ElementSize = ZPR32.ElementSize;
9484  let hasSideEffects = 0;
9485}
9486
9487multiclass sve_int_dot_mixed<string asm, SDPatternOperator op> {
9488  def NAME : sve_int_dot_mixed<asm>;
9489
9490  def : SVE_3_Op_Pat<nxv4i32, op , nxv4i32, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
9491}
9492
9493//===----------------------------------------------------------------------===//
9494// SVE Integer Dot Product Mixed Sign - Indexed Group
9495//===----------------------------------------------------------------------===//
9496
9497class sve_int_dot_mixed_indexed<bit U, string asm>
9498: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexS32b:$idx),
9499    asm, "\t$Zda, $Zn, $Zm$idx", "", []>, Sched<[]> {
9500  bits<5> Zda;
9501  bits<5> Zn;
9502  bits<3> Zm;
9503  bits<2> idx;
9504  let Inst{31-21} = 0b01000100101;
9505  let Inst{20-19} = idx;
9506  let Inst{18-16} = Zm;
9507  let Inst{15-11} = 0b00011;
9508  let Inst{10}    = U;
9509  let Inst{9-5}   = Zn;
9510  let Inst{4-0}   = Zda;
9511
9512  let Constraints = "$Zda = $_Zda";
9513  let DestructiveInstType = DestructiveOther;
9514  let ElementSize = ZPR32.ElementSize;
9515  let hasSideEffects = 0;
9516}
9517
9518multiclass sve_int_dot_mixed_indexed<bit U, string asm, SDPatternOperator op> {
9519  def NAME : sve_int_dot_mixed_indexed<U, asm>;
9520
9521  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv16i8, nxv16i8, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
9522}
9523
9524//===----------------------------------------------------------------------===//
9525// SVE Floating Point Matrix Multiply Accumulate Group
9526//===----------------------------------------------------------------------===//
9527
9528class sve_fp_matrix_mla<bits<2> opc, string asm, ZPRRegOp zda_ty, ZPRRegOp reg_ty>
9529: I<(outs zda_ty:$Zda), (ins zda_ty:$_Zda, reg_ty:$Zn, reg_ty:$Zm),
9530    asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
9531  bits<5> Zda;
9532  bits<5> Zn;
9533  bits<5> Zm;
9534  let Inst{31-24} = 0b01100100;
9535  let Inst{23-22} = opc;
9536  let Inst{21}    = 1;
9537  let Inst{20-16} = Zm;
9538  let Inst{15-10} = 0b111001;
9539  let Inst{9-5}   = Zn;
9540  let Inst{4-0}   = Zda;
9541
9542  let Constraints = "$Zda = $_Zda";
9543  let DestructiveInstType = DestructiveOther;
9544  let hasSideEffects = 0;
9545  let mayRaiseFPException = 1;
9546}
9547
9548multiclass sve_fp_matrix_mla<bits<2> opc, string asm, ZPRRegOp zda_ty, ZPRRegOp reg_ty, SDPatternOperator op, ValueType zda_vt, ValueType reg_vt> {
9549  def NAME : sve_fp_matrix_mla<opc, asm, zda_ty, reg_ty>;
9550
9551  def : SVE_3_Op_Pat<zda_vt, op , zda_vt, reg_vt, reg_vt, !cast<Instruction>(NAME)>;
9552}
9553
9554//===----------------------------------------------------------------------===//
9555// SVE Memory - Contiguous Load And Replicate 256-bit Group
9556//===----------------------------------------------------------------------===//
9557
9558class sve_mem_ldor_si<bits<2> sz, string asm, RegisterOperand VecList>
9559: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s32:$imm4),
9560  asm, "\t$Zt, $Pg/z, [$Rn, $imm4]", "", []>, Sched<[]> {
9561  bits<5> Zt;
9562  bits<5> Rn;
9563  bits<3> Pg;
9564  bits<4> imm4;
9565  let Inst{31-25} = 0b1010010;
9566  let Inst{24-23} = sz;
9567  let Inst{22-20} = 0b010;
9568  let Inst{19-16} = imm4;
9569  let Inst{15-13} = 0b001;
9570  let Inst{12-10} = Pg;
9571  let Inst{9-5}   = Rn;
9572  let Inst{4-0}   = Zt;
9573
9574  let hasSideEffects = 0;
9575  let mayLoad = 1;
9576}
9577
9578multiclass sve_mem_ldor_si<bits<2> sz, string asm, RegisterOperand listty,
9579                           ZPRRegOp zprty, ValueType Ty, ValueType PredTy, SDNode Ld1ro> {
9580  def NAME : sve_mem_ldor_si<sz, asm, listty>;
9581  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
9582                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
9583  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
9584                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
9585  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4]",
9586                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s32:$imm4), 0>;
9587
9588  // Base addressing mode
9589  def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$Pg), GPR64sp:$base)),
9590            (!cast<Instruction>(NAME) PPR3bAny:$Pg, GPR64sp:$base, (i64 0))>;
9591  let AddedComplexity = 2 in {
9592    // Reg + Imm addressing mode
9593    def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$Pg), (add GPR64:$base, (i64 simm4s32:$imm)))),
9594              (!cast<Instruction>(NAME) $Pg, $base, simm4s32:$imm)>;
9595  }
9596}
9597
9598class sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand VecList,
9599                      RegisterOperand gprty>
9600: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
9601  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]", "", []>, Sched<[]> {
9602  bits<5> Zt;
9603  bits<3> Pg;
9604  bits<5> Rn;
9605  bits<5> Rm;
9606  let Inst{31-25} = 0b1010010;
9607  let Inst{24-23} = sz;
9608  let Inst{22-21} = 0b01;
9609  let Inst{20-16} = Rm;
9610  let Inst{15-13} = 0;
9611  let Inst{12-10} = Pg;
9612  let Inst{9-5}   = Rn;
9613  let Inst{4-0}   = Zt;
9614
9615  let hasSideEffects = 0;
9616  let mayLoad = 1;
9617}
9618
9619multiclass sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand listty,
9620                           ZPRRegOp zprty, RegisterOperand gprty, ValueType Ty,
9621                           ValueType PredTy, SDNode Ld1ro, ComplexPattern AddrCP> {
9622  def NAME : sve_mem_ldor_ss<sz, asm, listty, gprty>;
9623
9624  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
9625                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
9626
9627  def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$gp), (AddrCP GPR64sp:$base, gprty:$offset))),
9628            (!cast<Instruction>(NAME) PPR3bAny:$gp, GPR64sp:$base, gprty:$offset)>;
9629}
9630
9631//===----------------------------------------------------------------------===//
9632// SVE Interleave 128-bit Elements Group
9633//===----------------------------------------------------------------------===//
9634
9635class sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm>
9636: I<(outs ZPR128:$Zd), (ins ZPR128:$Zn, ZPR128:$Zm),
9637  asm, "\t$Zd, $Zn, $Zm",
9638  "",
9639  []>, Sched<[]> {
9640  bits<5> Zd;
9641  bits<5> Zm;
9642  bits<5> Zn;
9643  let Inst{31-21} = 0b00000101101;
9644  let Inst{20-16} = Zm;
9645  let Inst{15-13} = 0b000;
9646  let Inst{12-11} = opc;
9647  let Inst{10}    = P;
9648  let Inst{9-5}   = Zn;
9649  let Inst{4-0}   = Zd;
9650
9651  let hasSideEffects = 0;
9652}
9653
9654multiclass sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm, SDPatternOperator op> {
9655  def NAME : sve_int_perm_bin_perm_128_zz<opc, P, asm>;
9656
9657  def : SVE_2_Op_Pat<nxv16i8,  op, nxv16i8,  nxv16i8,  !cast<Instruction>(NAME)>;
9658  def : SVE_2_Op_Pat<nxv8i16,  op, nxv8i16,  nxv8i16,  !cast<Instruction>(NAME)>;
9659  def : SVE_2_Op_Pat<nxv8f16,  op, nxv8f16,  nxv8f16,  !cast<Instruction>(NAME)>;
9660  def : SVE_2_Op_Pat<nxv4i32,  op, nxv4i32,  nxv4i32,  !cast<Instruction>(NAME)>;
9661  def : SVE_2_Op_Pat<nxv4f32,  op, nxv4f32,  nxv4f32,  !cast<Instruction>(NAME)>;
9662  def : SVE_2_Op_Pat<nxv2i64,  op, nxv2i64,  nxv2i64,  !cast<Instruction>(NAME)>;
9663  def : SVE_2_Op_Pat<nxv2f64,  op, nxv2f64,  nxv2f64,  !cast<Instruction>(NAME)>;
9664  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
9665}
9666
9667/// Addressing modes
9668let WantsRoot = true in {
9669  def am_sve_indexed_s4 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-8, 7>">;
9670  def am_sve_indexed_s6 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-32, 31>">;
9671}
9672
9673def am_sve_regreg_lsl0 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<0>", []>;
9674def am_sve_regreg_lsl1 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<1>", []>;
9675def am_sve_regreg_lsl2 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<2>", []>;
9676def am_sve_regreg_lsl3 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<3>", []>;
9677def am_sve_regreg_lsl4 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<4>", []>;
9678
9679// Predicated pseudo floating point two operand instructions.
9680multiclass sve_fp_bin_pred_hfd<SDPatternOperator op> {
9681  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9682  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9683  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9684
9685  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9686  def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9687  def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9688  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9689  def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9690  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9691}
9692
9693// Predicated pseudo floating point (BFloat) two operand instructions.
9694multiclass sve_fp_bin_pred_bfloat<SDPatternOperator op> {
9695  def _UNDEF : PredTwoOpPseudo<NAME, ZPR16, FalseLanesUndef>;
9696
9697  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1,  nxv8bf16, nxv8bf16, !cast<Pseudo>(NAME # _UNDEF)>;
9698  def : SVE_3_Op_Pat<nxv4bf16, op, nxv4i1,  nxv4bf16, nxv4bf16, !cast<Pseudo>(NAME # _UNDEF)>;
9699  def : SVE_3_Op_Pat<nxv2bf16, op, nxv2i1,  nxv2bf16, nxv2bf16, !cast<Pseudo>(NAME # _UNDEF)>;
9700}
9701
9702// Predicated pseudo floating point three operand instructions.
9703multiclass sve_fp_3op_pred_hfd<SDPatternOperator op> {
9704  def _H_UNDEF : PredThreeOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9705  def _S_UNDEF : PredThreeOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9706  def _D_UNDEF : PredThreeOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9707
9708  def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9709  def : SVE_4_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9710  def : SVE_4_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9711  def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S_UNDEF)>;
9712  def : SVE_4_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S_UNDEF)>;
9713  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D_UNDEF)>;
9714}
9715
9716// Predicated pseudo floating point (BFloat) three operand instructions.
9717multiclass sve_fp_3op_pred_bfloat<SDPatternOperator op> {
9718  def _UNDEF : PredThreeOpPseudo<NAME, ZPR16, FalseLanesUndef>;
9719
9720  def : SVE_4_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _UNDEF)>;
9721  def : SVE_4_Op_Pat<nxv4bf16, op, nxv4i1, nxv4bf16, nxv4bf16, nxv4bf16, !cast<Instruction>(NAME # _UNDEF)>;
9722  def : SVE_4_Op_Pat<nxv2bf16, op, nxv2i1, nxv2bf16, nxv2bf16, nxv2bf16, !cast<Instruction>(NAME # _UNDEF)>;
9723}
9724
9725// Predicated pseudo integer two operand instructions.
9726multiclass sve_int_bin_pred_bhsd<SDPatternOperator op> {
9727  def _B_UNDEF : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesUndef>;
9728  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9729  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9730  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9731
9732  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
9733  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9734  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9735  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9736}
9737
9738// As sve_int_bin_pred but when only i32 and i64 vector types are required.
9739multiclass sve_int_bin_pred_sd<SDPatternOperator op> {
9740  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9741  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9742
9743  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9744  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9745}
9746
9747// Predicated pseudo integer two operand instructions. Second operand is an
9748// immediate specified by imm_[bhsd].
9749multiclass sve_int_shift_pred_bhsd<SDPatternOperator op,
9750                                   ComplexPattern imm_b, ComplexPattern imm_h,
9751                                   ComplexPattern imm_s, ComplexPattern imm_d> {
9752  def _B_UNDEF : PredTwoOpImmPseudo<NAME # _B, ZPR8,  Operand<i32>, FalseLanesUndef>;
9753  def _H_UNDEF : PredTwoOpImmPseudo<NAME # _H, ZPR16, Operand<i32>, FalseLanesUndef>;
9754  def _S_UNDEF : PredTwoOpImmPseudo<NAME # _S, ZPR32, Operand<i32>, FalseLanesUndef>;
9755  def _D_UNDEF : PredTwoOpImmPseudo<NAME # _D, ZPR64, Operand<i32>, FalseLanesUndef>;
9756
9757  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, imm_b, !cast<Instruction>(NAME # _B_UNDEF)>;
9758  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, imm_h, !cast<Instruction>(NAME # _H_UNDEF)>;
9759  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, imm_s, !cast<Instruction>(NAME # _S_UNDEF)>;
9760  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, imm_d, !cast<Instruction>(NAME # _D_UNDEF)>;
9761}
9762
9763multiclass sve_int_bin_pred_all_active_bhsd<SDPatternOperator op> {
9764  def _B_UNDEF : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesUndef>;
9765  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9766  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9767  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9768
9769  def : SVE_2_Op_Pred_All_Active_Pt<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
9770  def : SVE_2_Op_Pred_All_Active_Pt<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9771  def : SVE_2_Op_Pred_All_Active_Pt<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9772  def : SVE_2_Op_Pred_All_Active_Pt<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9773}
9774
9775//===----------------------------------------------------------------------===//
9776// SME2 or SVE2.1 Instructions
9777//===----------------------------------------------------------------------===//
9778
9779class sve_fp_clamp<string asm, bits<2> sz, ZPRRegOp zpr_ty>
9780    : I<(outs zpr_ty:$Zd), (ins zpr_ty:$_Zd, zpr_ty:$Zn, zpr_ty:$Zm),
9781        asm, "\t$Zd, $Zn, $Zm", "", []>,
9782      Sched<[]> {
9783  bits<5> Zm;
9784  bits<5> Zn;
9785  bits<5> Zd;
9786  let Inst{31-24} = 0b01100100;
9787  let Inst{23-22} = sz;
9788  let Inst{21}    = 0b1;
9789  let Inst{20-16} = Zm;
9790  let Inst{15-10} = 0b001001;
9791  let Inst{9-5}   = Zn;
9792  let Inst{4-0}   = Zd;
9793
9794  let Constraints = "$Zd = $_Zd";
9795  let DestructiveInstType = DestructiveOther;
9796  let ElementSize = zpr_ty.ElementSize;
9797  let hasSideEffects = 0;
9798}
9799
9800multiclass sve_fp_clamp<string asm, SDPatternOperator op> {
9801  def _H : sve_fp_clamp<asm, 0b01, ZPR16>;
9802  def _S : sve_fp_clamp<asm, 0b10, ZPR32>;
9803  def _D : sve_fp_clamp<asm, 0b11, ZPR64>;
9804
9805  def : SVE_3_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
9806  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
9807  def : SVE_3_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
9808}
9809
9810multiclass sve_fp_clamp_bfloat<string asm, SDPatternOperator op> {
9811  def NAME : sve_fp_clamp<asm, 0b00, ZPR16>;
9812
9813  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
9814}
9815
9816// SVE two-way dot product
9817class sve2p1_two_way_dot_vv<string mnemonic, bit u>
9818    : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
9819        mnemonic, "\t$Zda, $Zn, $Zm",
9820        "", []>, Sched<[]> {
9821  bits<5> Zda;
9822  bits<5> Zn;
9823  bits<5> Zm;
9824  let Inst{31-21} = 0b01000100000;
9825  let Inst{20-16} = Zm;
9826  let Inst{15-11} = 0b11001;
9827  let Inst{10}    = u;
9828  let Inst{9-5}   = Zn;
9829  let Inst{4-0}   = Zda;
9830
9831  let Constraints = "$Zda = $_Zda";
9832  let DestructiveInstType = DestructiveOther;
9833  let hasSideEffects = 0;
9834}
9835
9836multiclass sve2p1_two_way_dot_vv<string mnemonic, bit u, SDPatternOperator intrinsic> {
9837  def NAME : sve2p1_two_way_dot_vv<mnemonic, u>;
9838
9839  def : SVE_3_Op_Pat<nxv4i32, intrinsic, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
9840}
9841
9842// SVE two-way dot product (indexed)
9843class sve2p1_two_way_dot_vvi<string mnemonic, bit u>
9844    : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR3b16:$Zm, VectorIndexS32b:$i2),
9845        mnemonic, "\t$Zda, $Zn, $Zm$i2",
9846        "", []>, Sched<[]> {
9847  bits<5> Zda;
9848  bits<5> Zn;
9849  bits<3> Zm;
9850  bits<2> i2;
9851  let Inst{31-21} = 0b01000100100;
9852  let Inst{20-19} = i2;
9853  let Inst{18-16} = Zm;
9854  let Inst{15-11} = 0b11001;
9855  let Inst{10}    = u;
9856  let Inst{9-5}   = Zn;
9857  let Inst{4-0}   = Zda;
9858
9859  let Constraints = "$Zda = $_Zda";
9860  let DestructiveInstType = DestructiveOther;
9861  let hasSideEffects = 0;
9862}
9863
9864multiclass sve2p1_two_way_dot_vvi<string mnemonic, bit u, SDPatternOperator intrinsic> {
9865  def NAME : sve2p1_two_way_dot_vvi<mnemonic, u>;
9866
9867  def : SVE_4_Op_Imm_Pat<nxv4i32, intrinsic, nxv4i32, nxv8i16, nxv8i16, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
9868}
9869
9870class sve2p1_ptrue_pn<string mnemonic, bits<2> sz, PNRP8to15RegOp pnrty, SDPatternOperator op>
9871    : I<(outs pnrty:$PNd), (ins ), mnemonic, "\t$PNd",
9872        "", [(set pnrty:$PNd, (op))]>, Sched<[]> {
9873  bits<3> PNd;
9874  let Inst{31-24}  = 0b00100101;
9875  let Inst{23-22} = sz;
9876  let Inst{21-3}  = 0b1000000111100000010;
9877  let Inst{2-0}   = PNd;
9878
9879  let hasSideEffects = 0;
9880  let isReMaterializable = 1;
9881  let Uses = [VG];
9882}
9883
9884
9885multiclass sve2p1_ptrue_pn<string mnemonic> {
9886 def _B : sve2p1_ptrue_pn<mnemonic, 0b00, PNR8_p8to15, int_aarch64_sve_ptrue_c8>;
9887 def _H : sve2p1_ptrue_pn<mnemonic, 0b01, PNR16_p8to15, int_aarch64_sve_ptrue_c16>;
9888 def _S : sve2p1_ptrue_pn<mnemonic, 0b10, PNR32_p8to15, int_aarch64_sve_ptrue_c32>;
9889 def _D : sve2p1_ptrue_pn<mnemonic, 0b11, PNR64_p8to15, int_aarch64_sve_ptrue_c64>;
9890}
9891
9892
9893// SVE extract mask predicate from predicate-as-counter
9894class sve2p1_pred_as_ctr_to_mask_base<string mnemonic, bits<2> sz, bits<3> opc,
9895                                      RegisterOperand pprty, Operand idxty>
9896    : I<(outs pprty:$Pd), (ins PNRAny_p8to15:$PNn, idxty:$index),
9897        mnemonic, "\t$Pd, $PNn$index",
9898        "", []>, Sched<[]> {
9899  bits<4> Pd;
9900  bits<3> PNn;
9901  bits<2> imm2;
9902  let Inst{31-24} = 0b00100101;
9903  let Inst{23-22} = sz;
9904  let Inst{21-11} = 0b10000001110;
9905  let Inst{10-8}  = opc;
9906  let Inst{7-5}   = PNn;
9907  let Inst{4}     = 0b1;
9908  let Inst{3-0}   = Pd;
9909
9910  let hasSideEffects = 0;
9911}
9912
9913class sve2p1_pred_as_ctr_to_mask<string mnemonic, bits<2> sz, PPRRegOp pprty>
9914    : sve2p1_pred_as_ctr_to_mask_base<mnemonic, sz, {0, ?, ?}, pprty, VectorIndexS32b_timm> {
9915  bits<2> index;
9916  let Inst{9-8} = index;
9917}
9918
9919multiclass sve2p1_pred_as_ctr_to_mask<string mnemonic, SDPatternOperator op> {
9920 def _B : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b00, PPR8>;
9921 def _H : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b01, PPR16>;
9922 def _S : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b10, PPR32>;
9923 def _D : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b11, PPR64>;
9924
9925 def : SVE_2_Op_Imm_Pat<nxv16i1, op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _B)>;
9926 def : SVE_2_Op_Imm_Pat<nxv8i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _H)>;
9927 def : SVE_2_Op_Imm_Pat<nxv4i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
9928 def : SVE_2_Op_Imm_Pat<nxv2i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
9929}
9930
9931
9932class sve2p1_pred_as_ctr_to_mask_pair<string mnemonic, bits<2> sz, RegisterOperand pprty>
9933    : sve2p1_pred_as_ctr_to_mask_base<mnemonic, sz, {1, 0, ?}, pprty, VectorIndexD> {
9934  bit index;
9935  let Inst{8}    = index;
9936}
9937
9938multiclass sve2p1_pred_as_ctr_to_mask_pair<string mnemonic> {
9939 def _B : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b00, PP_b>;
9940 def _H : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b01, PP_h>;
9941 def _S : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b10, PP_s>;
9942 def _D : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b11, PP_d>;
9943}
9944
9945
9946// SME2 multi-vec extract narrow
9947class sve2p1_multi_vec_extract_narrow<string mnemonic, bits<2> opc, bits<3> tsz>
9948    : I<(outs ZPR16:$Zd), (ins ZZ_s_mul_r:$Zn),
9949        mnemonic, "\t$Zd, $Zn",
9950        "", []>, Sched<[]> {
9951  bits<5> Zd;
9952  bits<4> Zn;
9953  let Inst{31-23} = 0b010001010;
9954  let Inst{22}    = tsz{2};
9955  let Inst{21}    = 0b1;
9956  let Inst{20-19} = tsz{1-0};
9957  let Inst{18-13} = 0b001010;
9958  let Inst{12-11} = opc;
9959  let Inst{10}    = 0b0;
9960  let Inst{9-6}   = Zn;
9961  let Inst{5}     = 0b0;
9962  let Inst{4-0}   = Zd;
9963
9964  let hasSideEffects = 0;
9965}
9966
9967multiclass sve2p1_multi_vec_extract_narrow<string mnemonic, bits<2> opc, SDPatternOperator intrinsic> {
9968  def NAME : sve2p1_multi_vec_extract_narrow<mnemonic, opc, 0b010>;
9969  def : SVE2p1_Cvt_VG2_Pat<NAME, intrinsic, nxv8i16, nxv4i32>;
9970}
9971
9972// SVE2 multi-vec shift narrow
9973class sve2p1_multi_vec_shift_narrow<string mnemonic, bits<3> opc, bits<2> tsz>
9974    : I<(outs ZPR16:$Zd), (ins ZZ_s_mul_r:$Zn, tvecshiftR16:$imm4),
9975        mnemonic, "\t$Zd, $Zn, $imm4",
9976        "", []>, Sched<[]> {
9977  bits<5> Zd;
9978  bits<4> Zn;
9979  bits<4> imm4;
9980  let Inst{31-23} = 0b010001011;
9981  let Inst{22}    = tsz{1};
9982  let Inst{21}    = 0b1;
9983  let Inst{20}    = tsz{0};
9984  let Inst{19-16} = imm4;
9985  let Inst{15-14} = 0b00;
9986  let Inst{13-11} = opc;
9987  let Inst{10}    = 0b0;
9988  let Inst{9-6}   = Zn;
9989  let Inst{5}     = 0b0;
9990  let Inst{4-0}   = Zd;
9991
9992  let hasSideEffects = 0;
9993}
9994
9995multiclass sve2p1_multi_vec_shift_narrow<string mnemonic, bits<3> opc, SDPatternOperator intrinsic> {
9996  def NAME : sve2p1_multi_vec_shift_narrow<mnemonic, opc, 0b01>;
9997
9998  def : SVE2p1_Sat_Shift_VG2_Pat<NAME, intrinsic, nxv8i16, nxv4i32, tvecshiftR16>;
9999}
10000
10001
10002// SME2 multi-vec contiguous load (scalar plus scalar, two registers)
10003class sve2p1_mem_cld_ss_2z<string mnemonic, bits<2> msz, bit n,
10004                         RegisterOperand vector_ty, RegisterOperand gpr_ty>
10005    : I<(outs vector_ty:$Zt),
10006        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
10007        mnemonic, "\t$Zt, $PNg/z, [$Rn, $Rm]",
10008        "", []>, Sched<[]> {
10009  bits<4> Zt;
10010  bits<5> Rm;
10011  bits<5> Rn;
10012  bits<3> PNg;
10013  let Inst{31-21} = 0b10100000000;
10014  let Inst{20-16} = Rm;
10015  let Inst{15}    = 0b0;
10016  let Inst{14-13} = msz;
10017  let Inst{12-10} = PNg;
10018  let Inst{9-5} = Rn;
10019  let Inst{4-1} = Zt;
10020  let Inst{0}   = n;
10021
10022  let hasSideEffects = 0;
10023  let mayLoad = 1;
10024}
10025
10026multiclass sve2p1_mem_cld_ss_2z<string mnemonic, bits<2> msz, bit n,
10027                         RegisterOperand vector_ty, RegisterOperand gpr_ty, RegisterOperand vector_pseudo_ty> {
10028  def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm), []>;
10029  def NAME : sve2p1_mem_cld_ss_2z<mnemonic, msz, n, vector_ty, gpr_ty>;
10030}
10031
10032// SME2 multi-vec contiguous load (scalar plus immediate, two registers)
10033class sve2p1_mem_cld_si_2z<string mnemonic, bits<2> msz, bit n,
10034                         RegisterOperand vector_ty>
10035    : I<(outs vector_ty:$Zt),
10036        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4),
10037        mnemonic, "\t$Zt, $PNg/z, [$Rn, $imm4, mul vl]",
10038        "", []>, Sched<[]> {
10039  bits<4> Zt;
10040  bits<5> Rn;
10041  bits<3> PNg;
10042  bits<4> imm4;
10043  let Inst{31-20} = 0b101000000100;
10044  let Inst{19-16} = imm4;
10045  let Inst{15}    = 0b0;
10046  let Inst{14-13} = msz;
10047  let Inst{12-10} = PNg;
10048  let Inst{9-5}   = Rn;
10049  let Inst{4-1}   = Zt;
10050  let Inst{0}     = n;
10051
10052  let hasSideEffects = 0;
10053  let mayLoad = 1;
10054}
10055
10056multiclass sve2p1_mem_cld_si_2z<string mnemonic, bits<2> msz, bit n,
10057                              RegisterOperand vector_ty, RegisterOperand vector_pseudo_ty> {
10058  def NAME : sve2p1_mem_cld_si_2z<mnemonic, msz, n, vector_ty>;
10059  def : InstAlias<mnemonic # " $Zt, $PNg/z, [$Rn]",
10060                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
10061  def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4), []>;
10062}
10063
10064// SME2 multi-vec contiguous load (scalar plus scalar, four registers)
10065class sve2p1_mem_cld_ss_4z<string mnemonic, bits<2> msz, bit n,
10066                         RegisterOperand vector_ty, RegisterOperand gpr_ty>
10067    : I<(outs vector_ty:$Zt),
10068        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
10069        mnemonic, "\t$Zt, $PNg/z, [$Rn, $Rm]",
10070        "", []>, Sched<[]> {
10071  bits<3> Zt;
10072  bits<5> Rm;
10073  bits<5> Rn;
10074  bits<3> PNg;
10075  let Inst{31-21} = 0b10100000000;
10076  let Inst{20-16} = Rm;
10077  let Inst{15}    = 0b1;
10078  let Inst{14-13} = msz;
10079  let Inst{12-10} = PNg;
10080  let Inst{9-5} = Rn;
10081  let Inst{4-2} = Zt;
10082  let Inst{1}   = 0b0;
10083  let Inst{0}   = n;
10084
10085  let hasSideEffects = 0;
10086  let mayLoad = 1;
10087}
10088
10089multiclass sve2p1_mem_cld_ss_4z<string mnemonic, bits<2> msz, bit n,
10090                         RegisterOperand vector_ty, RegisterOperand gpr_ty, RegisterOperand vector_pseudo_ty> {
10091  def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm), []>;
10092  def NAME : sve2p1_mem_cld_ss_4z<mnemonic, msz, n, vector_ty, gpr_ty>;
10093}
10094
10095// SME2 multi-vec contiguous load (scalar plus immediate, four registers)
10096class sve2p1_mem_cld_si_4z<string mnemonic, bits<2> msz, bit n,
10097                         RegisterOperand vector_ty>
10098    : I<(outs vector_ty:$Zt),
10099        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4),
10100        mnemonic, "\t$Zt, $PNg/z, [$Rn, $imm4, mul vl]",
10101        "", []>, Sched<[]> {
10102  bits<3> Zt;
10103  bits<5> Rn;
10104  bits<3> PNg;
10105  bits<4> imm4;
10106  let Inst{31-20} = 0b101000000100;
10107  let Inst{19-16} = imm4;
10108  let Inst{15}    = 0b1;
10109  let Inst{14-13} = msz;
10110  let Inst{12-10} = PNg;
10111  let Inst{9-5}   = Rn;
10112  let Inst{4-2}   = Zt;
10113  let Inst{1}     = 0b0;
10114  let Inst{0}     = n;
10115
10116  let hasSideEffects = 0;
10117  let mayLoad = 1;
10118}
10119
10120multiclass sve2p1_mem_cld_si_4z<string mnemonic, bits<2> msz, bit n,
10121                              RegisterOperand vector_ty, RegisterOperand vector_pseudo_ty> {
10122  def NAME : sve2p1_mem_cld_si_4z<mnemonic, msz, n, vector_ty>;
10123  def : InstAlias<mnemonic # " $Zt, $PNg/z, [$Rn]",
10124                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
10125  def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4), []>;
10126}
10127
10128// SME2 multi-vec contiguous store (scalar plus scalar, two registers)
10129class sve2p1_mem_cst_ss_2z<string mnemonic, bits<2> msz, bit n,
10130                           RegisterOperand vector_ty, RegisterOperand gpr_ty>
10131    : I<(outs ),
10132        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
10133        mnemonic, "\t$Zt, $PNg, [$Rn, $Rm]",
10134        "", []>, Sched<[]> {
10135  bits<4> Zt;
10136  bits<5> Rm;
10137  bits<5> Rn;
10138  bits<3> PNg;
10139  let Inst{31-21} = 0b10100000001;
10140  let Inst{20-16} = Rm;
10141  let Inst{15}    = 0b0;
10142  let Inst{14-13} = msz;
10143  let Inst{12-10} = PNg;
10144  let Inst{9-5} = Rn;
10145  let Inst{4-1} = Zt;
10146  let Inst{0}   = n;
10147
10148  let hasSideEffects = 0;
10149  let mayStore = 1;
10150}
10151
10152
10153// SME2 multi-vec contiguous store (scalar plus immediate, two registers)
10154class sve2p1_mem_cst_si_2z<string mnemonic, bits<2> msz, bit n,
10155                           RegisterOperand vector_ty>
10156    : I<(outs ),
10157        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4),
10158        mnemonic, "\t$Zt, $PNg, [$Rn, $imm4, mul vl]",
10159        "", []>, Sched<[]> {
10160  bits<4> Zt;
10161  bits<5> Rn;
10162  bits<3> PNg;
10163  bits<4> imm4;
10164  let Inst{31-20} = 0b101000000110;
10165  let Inst{19-16} = imm4;
10166  let Inst{15}    = 0b0;
10167  let Inst{14-13} = msz;
10168  let Inst{12-10} = PNg;
10169  let Inst{9-5}   = Rn;
10170  let Inst{4-1}   = Zt;
10171  let Inst{0}     = n;
10172
10173  let hasSideEffects = 0;
10174  let mayStore = 1;
10175}
10176
10177
10178multiclass sve2p1_mem_cst_si_2z<string mnemonic, bits<2> msz, bit n,
10179                              RegisterOperand vector_ty> {
10180  def NAME : sve2p1_mem_cst_si_2z<mnemonic, msz, n, vector_ty>;
10181
10182  def : InstAlias<mnemonic # " $Zt, $PNg, [$Rn]",
10183                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
10184}
10185
10186
10187// SME2 multi-vec contiguous store (scalar plus scalar, four registers)
10188class sve2p1_mem_cst_ss_4z<string mnemonic, bits<2> msz, bit n,
10189                           RegisterOperand vector_ty, RegisterOperand gpr_ty>
10190    : I<(outs ),
10191        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
10192        mnemonic, "\t$Zt, $PNg, [$Rn, $Rm]",
10193        "", []>, Sched<[]> {
10194  bits<3> Zt;
10195  bits<5> Rm;
10196  bits<5> Rn;
10197  bits<3> PNg;
10198  let Inst{31-21} = 0b10100000001;
10199  let Inst{20-16} = Rm;
10200  let Inst{15}    = 0b1;
10201  let Inst{14-13} = msz;
10202  let Inst{12-10} = PNg;
10203  let Inst{9-5} = Rn;
10204  let Inst{4-2} = Zt;
10205  let Inst{1}   = 0b0;
10206  let Inst{0}   = n;
10207
10208  let mayStore = 1;
10209}
10210
10211
10212// SME2 multi-vec contiguous store (scalar plus immediate, four registers)
10213class sve2p1_mem_cst_si_4z<string mnemonic, bits<2> msz, bit n,
10214                           RegisterOperand vector_ty>
10215    : I<(outs ),
10216        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4),
10217        mnemonic, "\t$Zt, $PNg, [$Rn, $imm4, mul vl]",
10218        "", []>, Sched<[]> {
10219  bits<3> Zt;
10220  bits<5> Rn;
10221  bits<3> PNg;
10222  bits<4> imm4;
10223  let Inst{31-20} = 0b101000000110;
10224  let Inst{19-16} = imm4;
10225  let Inst{15}    = 0b1;
10226  let Inst{14-13} = msz;
10227  let Inst{12-10} = PNg;
10228  let Inst{9-5}   = Rn;
10229  let Inst{4-2}   = Zt;
10230  let Inst{1}     = 0b0;
10231  let Inst{0}     = n;
10232
10233  let hasSideEffects = 0;
10234  let mayStore = 1;
10235}
10236
10237
10238multiclass sve2p1_mem_cst_si_4z<string mnemonic, bits<2> msz, bit n,
10239                                RegisterOperand vector_ty> {
10240  def NAME : sve2p1_mem_cst_si_4z<mnemonic, msz, n, vector_ty>;
10241
10242  def : InstAlias<mnemonic # " $Zt, $PNg, [$Rn]",
10243                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn,0), 1>;
10244}
10245
10246// SVE predicate count (predicate-as-counter)
10247class sve2p1_pcount_pn<string mnemonic, bits<3> opc, bits<2> sz, PNRRegOp pnrty>
10248   : I<(outs GPR64:$Rd),
10249       (ins pnrty:$PNn, sve_vec_len_specifier_enum:$vl),
10250       mnemonic, "\t$Rd, $PNn, $vl",
10251       "", []>, Sched<[]> {
10252  bits<5> Rd;
10253  bits<4> PNn;
10254  bits<1> vl;
10255  let Inst{31-24} = 0b00100101;
10256  let Inst{23-22} = sz;
10257  let Inst{21-19} = 0b100;
10258  let Inst{18-16} = opc;
10259  let Inst{15-11} = 0b10000;
10260  let Inst{10}    = vl;
10261  let Inst{9}     = 0b1;
10262  let Inst{8-5}   = PNn;
10263  let Inst{4-0}   = Rd;
10264
10265  let hasSideEffects = 0;
10266}
10267
10268multiclass sve2p1_pcount_pn<string mnemonic, bits<3> opc> {
10269  def _B : sve2p1_pcount_pn<mnemonic, opc, 0b00, PNR8>;
10270  def _H : sve2p1_pcount_pn<mnemonic, opc, 0b01, PNR16>;
10271  def _S : sve2p1_pcount_pn<mnemonic, opc, 0b10, PNR32>;
10272  def _D : sve2p1_pcount_pn<mnemonic, opc, 0b11, PNR64>;
10273
10274  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c8,  aarch64svcount, !cast<Instruction>(NAME # _B)>;
10275  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c16, aarch64svcount, !cast<Instruction>(NAME # _H)>;
10276  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c32, aarch64svcount, !cast<Instruction>(NAME # _S)>;
10277  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c64, aarch64svcount, !cast<Instruction>(NAME # _D)>;
10278}
10279
10280
10281// SVE integer compare scalar count and limit (predicate-as-counter)
10282class sve2p1_int_while_rr_pn<string mnemonic, bits<2> sz, bits<3> opc,
10283                             PNRP8to15RegOp pnrty>
10284    : I<(outs pnrty:$PNd), (ins GPR64:$Rn, GPR64:$Rm, sve_vec_len_specifier_enum:$vl),
10285        mnemonic, "\t$PNd, $Rn, $Rm, $vl",
10286        "", []>, Sched<[]> {
10287  bits<3> PNd;
10288  bits<5> Rn;
10289  bits<1> vl;
10290  bits<5> Rm;
10291  let Inst{31-24} = 0b00100101;
10292  let Inst{23-22} = sz;
10293  let Inst{21}    = 0b1;
10294  let Inst{20-16} = Rm;
10295  let Inst{15-14} = 0b01;
10296  let Inst{13}    = vl;
10297  let Inst{12}    = 0b0;
10298  let Inst{11-10} = opc{2-1};
10299  let Inst{9-5}   = Rn;
10300  let Inst{4}     = 0b1;
10301  let Inst{3}     = opc{0};
10302  let Inst{2-0}   = PNd;
10303
10304  let Defs = [NZCV];
10305  let hasSideEffects = 0;
10306}
10307
10308
10309multiclass sve2p1_int_while_rr_pn<string mnemonic, bits<3> opc> {
10310 def _B : sve2p1_int_while_rr_pn<mnemonic, 0b00, opc, PNR8_p8to15>;
10311 def _H : sve2p1_int_while_rr_pn<mnemonic, 0b01, opc, PNR16_p8to15>;
10312 def _S : sve2p1_int_while_rr_pn<mnemonic, 0b10, opc, PNR32_p8to15>;
10313 def _D : sve2p1_int_while_rr_pn<mnemonic, 0b11, opc, PNR64_p8to15>;
10314
10315 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c8"),
10316                            i64, !cast<Instruction>(NAME # _B)>;
10317 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c16"),
10318                            i64, !cast<Instruction>(NAME # _H)>;
10319 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c32"),
10320                            i64, !cast<Instruction>(NAME # _S)>;
10321 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c64"),
10322                            i64, !cast<Instruction>(NAME # _D)>;
10323}
10324
10325
10326// SVE integer compare scalar count and limit (predicate pair)
10327class sve2p1_int_while_rr_pair<string mnemonic, bits<2> sz, bits<3> opc,
10328                             RegisterOperand ppr_ty>
10329    : I<(outs ppr_ty:$Pd), (ins GPR64:$Rn, GPR64:$Rm),
10330        mnemonic, "\t$Pd, $Rn, $Rm",
10331        "", []>, Sched<[]> {
10332  bits<3> Pd;
10333  bits<5> Rn;
10334  bits<5> Rm;
10335  let Inst{31-24} = 0b00100101;
10336  let Inst{23-22} = sz;
10337  let Inst{21}    = 0b1;
10338  let Inst{20-16} = Rm;
10339  let Inst{15-12} = 0b0101;
10340  let Inst{11-10} = opc{2-1};
10341  let Inst{9-5}   = Rn;
10342  let Inst{4}     = 0b1;
10343  let Inst{3-1}   = Pd;
10344  let Inst{0}     = opc{0};
10345
10346  let Defs = [NZCV];
10347  let hasSideEffects = 0;
10348}
10349
10350
10351multiclass sve2p1_int_while_rr_pair<string mnemonic, bits<3> opc> {
10352 def _B : sve2p1_int_while_rr_pair<mnemonic, 0b00, opc, PP_b_mul_r>;
10353 def _H : sve2p1_int_while_rr_pair<mnemonic, 0b01, opc, PP_h_mul_r>;
10354 def _S : sve2p1_int_while_rr_pair<mnemonic, 0b10, opc, PP_s_mul_r>;
10355 def _D : sve2p1_int_while_rr_pair<mnemonic, 0b11, opc, PP_d_mul_r>;
10356}
10357
10358
10359class sve_mem_128b_gld_64_unscaled<string mnemonic>
10360    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
10361        mnemonic, "\t$Zt, $Pg/z, [$Zn, $Rm]",
10362        "", []>, Sched<[]> {
10363  bits<5> Zt;
10364  bits<5> Zn;
10365  bits<3> Pg;
10366  bits<5> Rm;
10367  let Inst{31-21} = 0b11000100000;
10368  let Inst{20-16} = Rm;
10369  let Inst{15-13} = 0b101;
10370  let Inst{12-10} = Pg;
10371  let Inst{9-5}   = Zn;
10372  let Inst{4-0}   = Zt;
10373
10374  let hasSideEffects = 0;
10375  let mayLoad = 1;
10376}
10377
10378
10379multiclass sve_mem_128b_gld_64_unscaled<string mnemonic, SDPatternOperator op> {
10380  def NAME : sve_mem_128b_gld_64_unscaled<mnemonic>;
10381
10382  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Zn]",
10383                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
10384
10385
10386  def : Pat<(nxv2i64 (op (nxv2i1 PPR3bAny:$Pg),  (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2i64)),
10387            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
10388  def : Pat<(nxv4i32 (op (nxv4i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn),  (i64 GPR64sp:$Rm), nxv4i32)),
10389            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
10390  def : Pat<(nxv8i16 (op (nxv8i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8i16)),
10391            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
10392  def : Pat<(nxv16i8 (op (nxv16i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv16i8)),
10393            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
10394
10395  def : Pat<(nxv2f64 (op (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2f64)),
10396            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
10397  def : Pat<(nxv4f32 (op (nxv4i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv4f32)),
10398            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
10399  def : Pat<(nxv8f16 (op (nxv8i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8f16)),
10400            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
10401  def : Pat<(nxv8bf16 (op (nxv8i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8bf16)),
10402            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
10403}
10404
10405class sve_mem_sst_128b_64_unscaled<string mnemonic>
10406    : I<(outs ), (ins Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
10407        mnemonic, "\t$Zt, $Pg, [$Zn, $Rm]",
10408        "", []>, Sched<[]> {
10409  bits<5> Zt;
10410  bits<5> Zn;
10411  bits<3> Pg;
10412  bits<5> Rm;
10413  let Inst{31-21} = 0b11100100001;
10414  let Inst{20-16} = Rm;
10415  let Inst{15-13} = 0b001;
10416  let Inst{12-10} = Pg;
10417  let Inst{9-5}   = Zn;
10418  let Inst{4-0}   = Zt;
10419
10420  let hasSideEffects = 0;
10421  let mayStore = 1;
10422}
10423
10424
10425multiclass sve_mem_sst_128b_64_unscaled<string mnemonic, SDPatternOperator op> {
10426  def NAME : sve_mem_sst_128b_64_unscaled<mnemonic>;
10427
10428  def : InstAlias<mnemonic # " $Zt, $Pg, [$Zn]",
10429                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
10430
10431  def : Pat<(op (nxv2i64 Z_q:$Zt), (nxv2i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2i64),
10432            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
10433  def : Pat<(op (nxv4i32 Z_q:$Zt), (nxv4i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv4i32),
10434            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
10435  def : Pat<(op (nxv8i16 Z_q:$Zt), (nxv8i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8i16),
10436            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp,ZPR64:$Zn, GPR64:$Rm)>;
10437  def : Pat<(op (nxv16i8 Z_q:$Zt), (nxv16i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv16i8),
10438            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
10439
10440  def : Pat<(op (nxv2f64 Z_q:$Zt), (nxv2i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2f64),
10441            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
10442  def : Pat<(op (nxv4f32 Z_q:$Zt), (nxv4i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv4f32),
10443            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
10444  def : Pat<(op (nxv8f16 Z_q:$Zt), (nxv8i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8f16),
10445            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
10446  def : Pat<(op (nxv8bf16 Z_q:$Zt), (nxv8i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8bf16),
10447            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
10448}
10449
10450
10451// SVE contiguous load (quadwords, scalar plus immediate)
10452class sve_mem_128b_cld_si<bits<2> dtype, string mnemonic>
10453    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
10454        mnemonic, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
10455        "", []>, Sched<[]> {
10456  bits<5> Zt;
10457  bits<5> Rn;
10458  bits<3> Pg;
10459  bits<4> imm4;
10460  let Inst{31-25} = 0b1010010;
10461  let Inst{24-23} = dtype;
10462  let Inst{22-20} = 0b001;
10463  let Inst{19-16} = imm4;
10464  let Inst{15-13} = 0b001;
10465  let Inst{12-10} = Pg;
10466  let Inst{9-5}   = Rn;
10467  let Inst{4-0}   = Zt;
10468
10469  let hasSideEffects = 0;
10470  let mayLoad = 1;
10471}
10472
10473multiclass sve_mem_128b_cld_si<bits<2> dtype, string mnemonic> {
10474  def NAME : sve_mem_128b_cld_si<dtype, mnemonic>;
10475
10476  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn]",
10477                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
10478  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn]",
10479                  (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
10480  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn, $imm4, mul vl]",
10481                  (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
10482}
10483
10484
10485// SVE contiguous load (quadwords, scalar plus scalar)
10486class sve_mem_128b_cld_ss<bits<2> dtype, string mnemonic, RegisterOperand gprsh_ty>
10487    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprsh_ty:$Rm),
10488        mnemonic, "\t$Zt, $Pg/z, [$Rn, $Rm]", "",
10489        []>, Sched<[]> {
10490  bits<5> Zt;
10491  bits<5> Rn;
10492  bits<3> Pg;
10493  bits<5> Rm;
10494  let Inst{31-25} = 0b1010010;
10495  let Inst{24-23} = dtype;
10496  let Inst{22-21} = 0b00;
10497  let Inst{20-16} = Rm;
10498  let Inst{15-13} = 0b100;
10499  let Inst{12-10} = Pg;
10500  let Inst{9-5}   = Rn;
10501  let Inst{4-0}   = Zt;
10502
10503  let hasSideEffects = 0;
10504  let mayLoad = 1;
10505}
10506
10507multiclass sve_mem_128b_cld_ss<bits<2> dtype, string mnemonic, RegisterOperand gprsh_ty> {
10508  def NAME : sve_mem_128b_cld_ss<dtype, mnemonic, gprsh_ty>;
10509
10510  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn, $Rm]",
10511                 (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprsh_ty:$Rm), 0>;
10512}
10513
10514
10515// SVE floating-point recursive reduction (quadwords)
10516class sve2p1_fp_reduction_q<bits<2> sz, bits<3> opc, string mnemonic,
10517                            RegisterOperand zpr_ty, string vec_sfx>
10518    : I<(outs V128:$Vd), (ins PPR3bAny:$Pg, zpr_ty:$Zn),
10519        mnemonic, "\t$Vd." # vec_sfx # ", $Pg, $Zn",
10520        "", []>, Sched<[]> {
10521  bits<5> Vd;
10522  bits<5> Zn;
10523  bits<3> Pg;
10524  let Inst{31-24} = 0b01100100;
10525  let Inst{23-22} = sz;
10526  let Inst{21-19} = 0b010;
10527  let Inst{18-16} = opc;
10528  let Inst{15-13} = 0b101;
10529  let Inst{12-10} = Pg;
10530  let Inst{9-5}   = Zn;
10531  let Inst{4-0}   = Vd;
10532
10533  let hasSideEffects = 0;
10534  let mayRaiseFPException = 1;
10535}
10536
10537multiclass sve2p1_fp_reduction_q<bits<3> opc, string mnemonic, SDPatternOperator op> {
10538  def _H : sve2p1_fp_reduction_q<0b01, opc, mnemonic, ZPR16, "8h">;
10539  def _S : sve2p1_fp_reduction_q<0b10, opc, mnemonic, ZPR32, "4s">;
10540  def _D : sve2p1_fp_reduction_q<0b11, opc, mnemonic, ZPR64, "2d">;
10541
10542  def : SVE_2_Op_Pat<v8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
10543  def : SVE_2_Op_Pat<v4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
10544  def : SVE_2_Op_Pat<v2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
10545}
10546
10547
10548// SVE Permute Vector - Quadwords (DUPQ)
10549class sve2p1_dupq<bits<5> ind_tsz, string mnemonic, ZPRRegOp zprty, Operand itype>
10550    : I<(outs zprty:$Zd), (ins zprty:$Zn, itype:$index),
10551        mnemonic, "\t$Zd, $Zn$index",
10552        "", []>, Sched<[]> {
10553  bits<5> Zd;
10554  bits<5> Zn;
10555  let Inst{31-21} = 0b00000101001;
10556  let Inst{20-16} = ind_tsz;
10557  let Inst{15-10} = 0b001001;
10558  let Inst{9-5} = Zn;
10559  let Inst{4-0} = Zd;
10560
10561  let hasSideEffects = 0;
10562}
10563
10564multiclass sve2p1_dupq<string mnemonic, SDPatternOperator Op> {
10565  def _B : sve2p1_dupq<{?, ?, ?, ?, 1}, mnemonic, ZPR8, VectorIndexB32b_timm> {
10566    bits<4> index;
10567    let Inst{20-17} = index;
10568  }
10569  def _H : sve2p1_dupq<{?, ?, ?, 1, 0}, mnemonic, ZPR16, VectorIndexH32b_timm> {
10570    bits<3> index;
10571    let Inst{20-18} = index;
10572  }
10573  def _S : sve2p1_dupq<{?, ?, 1, 0, 0}, mnemonic, ZPR32, VectorIndexS32b_timm> {
10574    bits<2> index;
10575    let Inst{20-19} = index;
10576  }
10577  def _D : sve2p1_dupq<{?, 1, 0, 0, 0}, mnemonic, ZPR64, VectorIndexD32b_timm> {
10578    bits<1> index;
10579    let Inst{20} = index;
10580  }
10581
10582  def : SVE_2_Op_Imm_Pat<nxv16i8, Op, nxv16i8, i32, VectorIndexB32b_timm, !cast<Instruction>(NAME # _B)>;
10583  def : SVE_2_Op_Imm_Pat<nxv8i16, Op, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
10584  def : SVE_2_Op_Imm_Pat<nxv4i32, Op, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
10585  def : SVE_2_Op_Imm_Pat<nxv2i64, Op, nxv2i64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
10586
10587  def : SVE_2_Op_Imm_Pat<nxv8f16, Op, nxv8f16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
10588  def : SVE_2_Op_Imm_Pat<nxv4f32, Op, nxv4f32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
10589  def : SVE_2_Op_Imm_Pat<nxv2f64, Op, nxv2f64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
10590  def : SVE_2_Op_Imm_Pat<nxv8bf16, Op, nxv8bf16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
10591}
10592
10593
10594// SVE Permute Vector - Quadwords (EXTQ)
10595class sve2p1_extq<string mnemonic>
10596    : I<(outs ZPR8:$Zdn), (ins ZPR8:$_Zdn, ZPR8:$Zm, timm32_0_15:$imm4),
10597        mnemonic, "\t$Zdn, $_Zdn, $Zm, $imm4",
10598        "", []>, Sched<[]> {
10599  bits<5> Zdn;
10600  bits<5> Zm;
10601  bits<4> imm4;
10602  let Inst{31-20} = 0b000001010110;
10603  let Inst{19-16} = imm4;
10604  let Inst{15-10} = 0b001001;
10605  let Inst{9-5} = Zm;
10606  let Inst{4-0} = Zdn;
10607
10608  let Constraints = "$Zdn = $_Zdn";
10609  let DestructiveInstType = DestructiveOther;
10610  let ElementSize = ZPR8.ElementSize;
10611  let hasSideEffects = 0;
10612}
10613
10614multiclass sve2p1_extq<string mnemonic, SDPatternOperator Op> {
10615  def NAME : sve2p1_extq<mnemonic>;
10616  def : SVE_3_Op_Imm_Pat<nxv16i8, Op, nxv16i8, nxv16i8, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10617  def : SVE_3_Op_Imm_Pat<nxv8i16, Op, nxv8i16, nxv8i16, i32, extq_timm32_0_7m2, !cast<Instruction>(NAME)>;
10618  def : SVE_3_Op_Imm_Pat<nxv4i32, Op, nxv4i32, nxv4i32, i32, extq_timm32_0_3m4, !cast<Instruction>(NAME)>;
10619  def : SVE_3_Op_Imm_Pat<nxv2i64, Op, nxv2i64, nxv2i64, i32, extq_timm32_0_1m8, !cast<Instruction>(NAME)>;
10620
10621  def : SVE_3_Op_Imm_Pat<nxv8f16, Op, nxv8f16, nxv8f16, i32, extq_timm32_0_7m2, !cast<Instruction>(NAME)>;
10622  def : SVE_3_Op_Imm_Pat<nxv4f32, Op, nxv4f32, nxv4f32, i32, extq_timm32_0_3m4, !cast<Instruction>(NAME)>;
10623  def : SVE_3_Op_Imm_Pat<nxv2f64, Op, nxv2f64, nxv2f64, i32, extq_timm32_0_1m8, !cast<Instruction>(NAME)>;
10624  def : SVE_3_Op_Imm_Pat<nxv8bf16, Op, nxv8bf16, nxv8bf16, i32, extq_timm32_0_7m2, !cast<Instruction>(NAME)>;
10625}
10626
10627// SVE move predicate from vector
10628class sve2p1_vector_to_pred<bits<4> opc, string mnemonic,
10629                            PPRRegOp ppr_ty, Operand itype>
10630    : I<(outs ppr_ty:$Pd), (ins ZPRAny:$Zn, itype:$index),
10631        mnemonic, "\t$Pd, $Zn$index",
10632        "", []>, Sched<[]> {
10633  bits<4> Pd;
10634  bits<5> Zn;
10635  let Inst{31-24} = 0b00000101;
10636  let Inst{23-22} = opc{3-2};
10637  let Inst{21-19} = 0b101;
10638  let Inst{18-17} = opc{1-0};
10639  let Inst{16-10} = 0b0001110;
10640  let Inst{9-5}   = Zn;
10641  let Inst{4}     = 0b0;
10642  let Inst{3-0}   = Pd;
10643
10644  let hasSideEffects = 0;
10645}
10646
10647multiclass sve2p1_vector_to_pred<string mnemonic, SDPatternOperator Op_lane, SDPatternOperator Op> {
10648  def _B : sve2p1_vector_to_pred<{0, 0, 0, 1}, mnemonic, PPR8,  VectorIndex032b>;
10649  def _H : sve2p1_vector_to_pred<{0, 0, 1, ?}, mnemonic, PPR16, VectorIndexD32b> {
10650    bits<1> index;
10651    let Inst{17} = index;
10652  }
10653  def _S : sve2p1_vector_to_pred<{0, 1, ?, ?}, mnemonic, PPR32, VectorIndexS32b> {
10654    bits<2> index;
10655    let Inst{18-17} = index;
10656  }
10657  def _D : sve2p1_vector_to_pred<{1, ?, ?, ?}, mnemonic, PPR64, VectorIndexH32b> {
10658    bits<3> index;
10659    let Inst{22}    = index{2};
10660    let Inst{18-17} = index{1-0};
10661  }
10662
10663  def : InstAlias<mnemonic # "\t$Pd, $Zn",
10664                 (!cast<Instruction>(NAME # _B) PPR8:$Pd, ZPRAny:$Zn, 0), 1>;
10665  def : InstAlias<mnemonic # "\t$Pd, $Zn",
10666                 (!cast<Instruction>(NAME # _H) PPR16:$Pd, ZPRAny:$Zn, 0), 0>;
10667  def : InstAlias<mnemonic # "\t$Pd, $Zn",
10668                 (!cast<Instruction>(NAME # _S) PPR32:$Pd, ZPRAny:$Zn, 0), 0>;
10669  def : InstAlias<mnemonic # "\t$Pd, $Zn",
10670                 (!cast<Instruction>(NAME # _D) PPR64:$Pd, ZPRAny:$Zn, 0), 0>;
10671
10672  // any_lane
10673  def : Pat<(nxv16i1 (Op_lane (nxv16i8 ZPRAny:$Zn), (i32 timm32_0_0:$Idx))),
10674            (!cast<Instruction>(NAME # _B) ZPRAny:$Zn, timm32_0_0:$Idx)>;
10675  def : Pat<(nxv8i1 (Op_lane (nxv8i16 ZPRAny:$Zn), (i32 timm32_0_1:$Idx))),
10676            (!cast<Instruction>(NAME # _H) ZPRAny:$Zn, timm32_0_1:$Idx)>;
10677  def : Pat<(nxv4i1 (Op_lane (nxv4i32 ZPRAny:$Zn), (i32 timm32_0_3:$Idx))),
10678            (!cast<Instruction>(NAME # _S) ZPRAny:$Zn, timm32_0_3:$Idx)>;
10679  def : Pat<(nxv2i1 (Op_lane (nxv2i64 ZPRAny:$Zn), (i32 timm32_0_7:$Idx))),
10680            (!cast<Instruction>(NAME # _D) ZPRAny:$Zn, timm32_0_7:$Idx)>;
10681 // lane_0
10682 def : Pat<(nxv16i1 (Op (nxv16i8 ZPRAny:$Zn))),
10683            (!cast<Instruction>(NAME # _B) ZPRAny:$Zn, 0)>;
10684  def : Pat<(nxv8i1 (Op (nxv8i16 ZPRAny:$Zn))),
10685            (!cast<Instruction>(NAME # _H) ZPRAny:$Zn, 0)>;
10686  def : Pat<(nxv4i1 (Op (nxv4i32 ZPRAny:$Zn))),
10687            (!cast<Instruction>(NAME # _S) ZPRAny:$Zn, 0)>;
10688  def : Pat<(nxv2i1 (Op (nxv2i64 ZPRAny:$Zn))),
10689            (!cast<Instruction>(NAME # _D) ZPRAny:$Zn, 0)>;
10690}
10691
10692
10693// SVE move predicate into vector
10694class sve2p1_pred_to_vector<bits<4> opc, string mnemonic,
10695                            PPRRegOp ppr_ty, Operand itype>
10696    : I<(outs ZPRAny:$Zd), (ins ZPRAny:$_Zd, itype:$index, ppr_ty:$Pn),
10697        mnemonic, "\t$Zd$index, $Pn",
10698        "", []>, Sched<[]> {
10699  bits<5> Zd;
10700  bits<4> Pn;
10701  let Inst{31-24} = 0b00000101;
10702  let Inst{23-22} = opc{3-2};
10703  let Inst{21-19} = 0b101;
10704  let Inst{18-17} = opc{1-0};
10705  let Inst{16-9}  = 0b10011100;
10706  let Inst{8-5}   = Pn;
10707  let Inst{4-0}   = Zd;
10708
10709  let Constraints = "$Zd = $_Zd";
10710  let hasSideEffects = 0;
10711}
10712
10713multiclass sve2p1_pred_to_vector<string mnemonic, SDPatternOperator MergeOp,
10714                                 SDPatternOperator ZeroOp> {
10715  def _B : sve2p1_pred_to_vector<{0, 0, 0, 1}, mnemonic, PPR8,  VectorIndex0>;
10716  def _H : sve2p1_pred_to_vector<{0, 0, 1, ?}, mnemonic, PPR16, VectorIndexD32b> {
10717    bits<1> index;
10718    let Inst{17} = index;
10719  }
10720  def _S : sve2p1_pred_to_vector<{0, 1, ?, ?}, mnemonic, PPR32, VectorIndexS32b> {
10721    bits<2> index;
10722    let Inst{18-17} = index;
10723  }
10724  def _D : sve2p1_pred_to_vector<{1, ?, ?, ?}, mnemonic, PPR64, VectorIndexH32b> {
10725    bits<3> index;
10726    let Inst{22}    = index{2};
10727    let Inst{18-17} = index{1-0};
10728  }
10729
10730  def : InstAlias<mnemonic # "\t$Zd, $Pn",
10731                 (!cast<Instruction>(NAME # _B) ZPRAny:$Zd, 0, PPR8:$Pn), 1>;
10732  def : InstAlias<mnemonic # "\t$Zd, $Pn",
10733                 (!cast<Instruction>(NAME # _H) ZPRAny:$Zd, 0, PPR16:$Pn), 0>;
10734  def : InstAlias<mnemonic # "\t$Zd, $Pn",
10735                 (!cast<Instruction>(NAME # _S) ZPRAny:$Zd, 0, PPR32:$Pn), 0>;
10736  def : InstAlias<mnemonic # "\t$Zd, $Pn",
10737                 (!cast<Instruction>(NAME # _D) ZPRAny:$Zd, 0, PPR64:$Pn), 0>;
10738
10739  // Merge
10740  def : Pat<(nxv8i16 (MergeOp (nxv8i16 ZPRAny:$Zd), (nxv8i1 PPR16:$Pn), (i32 timm32_1_1:$Idx))),
10741            (!cast<Instruction>(NAME # _H) ZPRAny:$Zd, timm32_1_1:$Idx, PPR16:$Pn)>;
10742  def : Pat<(nxv4i32 (MergeOp (nxv4i32 ZPRAny:$Zd), (nxv4i1 PPR32:$Pn), (i32 timm32_1_3:$Idx))),
10743            (!cast<Instruction>(NAME # _S) ZPRAny:$Zd, timm32_1_3:$Idx, PPR32:$Pn)>;
10744  def : Pat<(nxv2i64 (MergeOp (nxv2i64 ZPRAny:$Zd), (nxv2i1 PPR64:$Pn), (i32 timm32_1_7:$Idx))),
10745            (!cast<Instruction>(NAME # _D) ZPRAny:$Zd, timm32_1_7:$Idx, PPR64:$Pn)>;
10746
10747  // Zero
10748  def : Pat<(nxv16i8 (ZeroOp (nxv16i1 PPR8:$Pn))),
10749           (!cast<Instruction>(NAME # _B) (IMPLICIT_DEF), 0, PPR8:$Pn)>;
10750  def : Pat<(nxv8i16 (ZeroOp (nxv8i1 PPR16:$Pn))),
10751            (!cast<Instruction>(NAME # _H) (IMPLICIT_DEF), 0, PPR16:$Pn)>;
10752  def : Pat<(nxv4i32 (ZeroOp (nxv4i1 PPR32:$Pn))),
10753            (!cast<Instruction>(NAME # _S) (IMPLICIT_DEF), 0, PPR32:$Pn)>;
10754  def : Pat<(nxv2i64 (ZeroOp (nxv2i1 PPR64:$Pn))),
10755            (!cast<Instruction>(NAME # _D) (IMPLICIT_DEF), 0, PPR64:$Pn)>;
10756}
10757
10758
10759// SVE bitwise logical/add/min/max reductions (quadwords)
10760class sve2p1_int_reduce_q<bits<2> sz, bits<4> opc, string mnemonic,
10761                          RegisterOperand zpr_ty, string vec_sfx>
10762    : I<(outs V128:$Vd), (ins PPR3bAny:$Pg, zpr_ty:$Zn),
10763        mnemonic, "\t$Vd." # vec_sfx # ", $Pg, $Zn",
10764        "", []>, Sched<[]> {
10765  bits<5> Vd;
10766  bits<5> Zn;
10767  bits<3> Pg;
10768  let Inst{31-24} = 0b00000100;
10769  let Inst{23-22} = sz;
10770  let Inst{21}    = 0b0;
10771  let Inst{20-19} = opc{3-2};
10772  let Inst{18}    = 0b1;
10773  let Inst{17-16} = opc{1-0};
10774  let Inst{15-13} = 0b001;
10775  let Inst{12-10} = Pg;
10776  let Inst{9-5}   = Zn;
10777  let Inst{4-0}   = Vd;
10778
10779  let hasSideEffects = 0;
10780}
10781
10782multiclass sve2p1_int_reduce_q<bits<4> opc, string mnemonic, SDPatternOperator op> {
10783  def _B : sve2p1_int_reduce_q<0b00, opc, mnemonic, ZPR8,  "16b">;
10784  def _H : sve2p1_int_reduce_q<0b01, opc, mnemonic, ZPR16, "8h">;
10785  def _S : sve2p1_int_reduce_q<0b10, opc, mnemonic, ZPR32, "4s">;
10786  def _D : sve2p1_int_reduce_q<0b11, opc, mnemonic, ZPR64, "2d">;
10787
10788  def : SVE_2_Op_Pat<v16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
10789  def : SVE_2_Op_Pat<v8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
10790  def : SVE_2_Op_Pat<v4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
10791  def : SVE_2_Op_Pat<v2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
10792}
10793
10794
10795// SVE permute vector elements (quadwords)
10796class sve2p1_permute_vec_elems_q<bits<2> sz, bits<3> opc, string mnemonic,
10797                                 ZPRRegOp zpr_ty, RegisterOperand src1_ty>
10798    : I<(outs zpr_ty:$Zd), (ins src1_ty:$Zn, zpr_ty:$Zm),
10799        mnemonic, "\t$Zd, $Zn, $Zm",
10800        "", []>, Sched<[]> {
10801  bits<5> Zd;
10802  bits<5> Zn;
10803  bits<5> Zm;
10804  let Inst{31-24} = 0b01000100;
10805  let Inst{23-22} = sz;
10806  let Inst{21}    = 0b0;
10807  let Inst{20-16} = Zm;
10808  let Inst{15-13} = 0b111;
10809  let Inst{12-10} = opc;
10810  let Inst{9-5}   = Zn;
10811  let Inst{4-0}   = Zd;
10812
10813  let hasSideEffects = 0;
10814}
10815
10816multiclass sve2p1_permute_vec_elems_q<bits<3> opc, string mnemonic,
10817                                      SDPatternOperator op> {
10818  def _B : sve2p1_permute_vec_elems_q<0b00, opc, mnemonic, ZPR8,  ZPR8>;
10819  def _H : sve2p1_permute_vec_elems_q<0b01, opc, mnemonic, ZPR16, ZPR16>;
10820  def _S : sve2p1_permute_vec_elems_q<0b10, opc, mnemonic, ZPR32, ZPR32>;
10821  def _D : sve2p1_permute_vec_elems_q<0b11, opc, mnemonic, ZPR64, ZPR64>;
10822
10823  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
10824  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10825  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
10826  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
10827
10828  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
10829  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
10830  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
10831
10832  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
10833}
10834
10835multiclass sve2p1_tblq<string mnemonic, SDPatternOperator op> {
10836  def _B : sve2p1_permute_vec_elems_q<0b00, 0b110, mnemonic, ZPR8,  Z_b>;
10837  def _H : sve2p1_permute_vec_elems_q<0b01, 0b110, mnemonic, ZPR16, Z_h>;
10838  def _S : sve2p1_permute_vec_elems_q<0b10, 0b110, mnemonic, ZPR32, Z_s>;
10839  def _D : sve2p1_permute_vec_elems_q<0b11, 0b110, mnemonic, ZPR64, Z_d>;
10840
10841  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
10842  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10843  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
10844  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
10845
10846  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10847  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
10848  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
10849
10850  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10851}
10852
10853//===----------------------------------------------------------------------===//
10854// SVE2 FP8 Instructions
10855//===----------------------------------------------------------------------===//
10856
10857// FP8 upconvert
10858class sve2_fp8_cvt_single<bit L, bits<2> opc, string mnemonic,
10859                          ZPRRegOp dst_ty, ZPRRegOp src_ty>
10860    : I<(outs dst_ty:$Zd), (ins src_ty:$Zn),
10861      mnemonic, "\t$Zd, $Zn",
10862      "", []>, Sched<[]>{
10863  bits<5> Zd;
10864  bits<5> Zn;
10865  let Inst{31-17} = 0b011001010000100;
10866  let Inst{16}    = L;
10867  let Inst{15-12} = 0b0011;
10868  let Inst{11-10} = opc;
10869  let Inst{9-5}   = Zn;
10870  let Inst{4-0}   = Zd;
10871  let Uses = [FPMR, FPCR];
10872
10873  let mayLoad  = 1;
10874  let mayStore = 0;
10875}
10876
10877multiclass sve2_fp8_cvt_single<bit L, bits<2> opc, string mnemonic, ValueType vtd, SDPatternOperator op> {
10878  def _BtoH : sve2_fp8_cvt_single<L, opc, mnemonic, ZPR16, ZPR8>;
10879
10880  def : SVE_1_Op_Pat<vtd, op, nxv16i8, !cast<Instruction>(NAME # _BtoH)>;
10881}
10882
10883// FP8 downconvert
10884class sve2_fp8_down_cvt_single<bits<2> opc, string mnemonic,
10885                              ZPRRegOp dst_ty, RegisterOperand src_ty>
10886    : I<(outs dst_ty:$Zd), (ins src_ty:$Zn),
10887      mnemonic, "\t$Zd, $Zn",
10888      "", []>, Sched<[]>{
10889  bits<5> Zd;
10890  bits<4> Zn;
10891  let Inst{31-12} = 0b01100101000010100011;
10892  let Inst{11-10} = opc;
10893  let Inst{9-6} = Zn;
10894  let Inst{5} = 0b0;
10895  let Inst{4-0} = Zd;
10896  let Uses = [FPMR, FPCR];
10897
10898  let mayLoad  = 1;
10899  let mayStore = 0;
10900}
10901
10902multiclass sve2_fp8_down_cvt_single<bits<2> opc, string mnemonic, RegisterOperand src,
10903                                    ValueType ty, SDPatternOperator op> {
10904  def NAME : sve2_fp8_down_cvt_single<opc, mnemonic, ZPR8, src>;
10905
10906  def : Pat<(nxv16i8 (op ty:$Zn1, ty:$Zn2)),
10907            (!cast<Instruction>(NAME) (REG_SEQUENCE ZPR2Mul2, $Zn1, zsub0, $Zn2, zsub1))>;
10908}
10909
10910class sve2_fp8_down_cvt_single_top<bits<2> opc, string mnemonic, RegisterOperand src_ty>
10911  : I<(outs ZPR8:$Zd), (ins ZPR8:$_Zd, src_ty:$Zn), mnemonic, "\t$Zd, $Zn","", []>, Sched<[]> {
10912  bits<5> Zd;
10913  bits<4> Zn;
10914
10915  let Inst{31-12} = 0b01100101000010100011;
10916  let Inst{11-10} = opc;
10917  let Inst{9-6}   = Zn;
10918  let Inst{5}     = 0b0;
10919  let Inst{4-0}   = Zd;
10920
10921  let Constraints = "$Zd = $_Zd";
10922  let DestructiveInstType = DestructiveOther;
10923  let ElementSize         = ZPR8.ElementSize;
10924
10925  let Uses     = [FPMR, FPCR];
10926  let mayLoad  = 1;
10927  let mayStore = 0;
10928}
10929
10930multiclass sve2_fp8_down_cvt_single_top<bits<2> opc, string mnemonic, RegisterOperand src_ty,
10931                                        ValueType ty, SDPatternOperator op> {
10932  def NAME : sve2_fp8_down_cvt_single_top<opc, mnemonic, src_ty>;
10933
10934  def : Pat<(nxv16i8 (op nxv16i8:$Zd, ty:$Zn1, ty:$Zn2)),
10935            (!cast<Instruction>(NAME) $Zd, (REG_SEQUENCE ZPR2Mul2, $Zn1, zsub0, $Zn2, zsub1))>;
10936}
10937
10938// FP8 Widening Multiply-Add Long - Indexed Group
10939class sve2_fp8_mla_long_by_indexed_elem<bit T, string mnemonic>
10940    : I<(outs ZPR16:$Zda),
10941      (ins ZPR16:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexB32b:$imm4),
10942      mnemonic, "\t$Zda, $Zn, $Zm$imm4",
10943      "", []>, Sched<[]>{
10944  bits<5> Zda;
10945  bits<5> Zn;
10946  bits<3> Zm;
10947  bits<4> imm4;
10948  let Inst{31-24} = 0b01100100;
10949  let Inst{23}    = T;
10950  let Inst{22-21} = 0b01;
10951  let Inst{20-19} = imm4{3-2};
10952  let Inst{18-16} = Zm;
10953  let Inst{15-12} = 0b0101;
10954  let Inst{11-10} = imm4{1-0};
10955  let Inst{9-5}   = Zn;
10956  let Inst{4-0}   = Zda;
10957  let Constraints = "$Zda = $_Zda";
10958  let DestructiveInstType = DestructiveOther;
10959  let ElementSize         = ZPR16.ElementSize;
10960  let Uses = [FPMR, FPCR];
10961}
10962
10963multiclass sve2_fp8_mla_long_by_indexed_elem<bit T, string mnemonic, SDPatternOperator op> {
10964  def NAME : sve2_fp8_mla_long_by_indexed_elem<T, mnemonic>;
10965
10966  def : SVE_4_Op_Pat<nxv8f16, op, nxv8f16, nxv16i8, nxv16i8, i32, !cast<Instruction>(NAME)>;
10967}
10968
10969// FP8 Widening Multiply-Add (Long)/(Long Long) Group
10970class sve2_fp8_mla<bits<3>opc, ZPRRegOp dst_ty, string mnemonic>
10971    : I<(outs dst_ty:$Zda),
10972      (ins dst_ty:$_Zda, ZPR8:$Zn, ZPR8:$Zm),
10973      mnemonic, "\t$Zda, $Zn, $Zm",
10974      "", []>, Sched<[]>{
10975  bits<5> Zda;
10976  bits<5> Zn;
10977  bits<5> Zm;
10978  let Inst{31-24} = 0b01100100;
10979  let Inst{23}    = opc{2};
10980  let Inst{22-21} = 0b01;
10981  let Inst{20-16} = Zm;
10982  let Inst{15-14} = 0b10;
10983  let Inst{13-12} = opc{1-0};
10984  let Inst{11-10} = 0b10;
10985  let Inst{9-5}   = Zn;
10986  let Inst{4-0}   = Zda;
10987  let Constraints = "$Zda = $_Zda";
10988  let DestructiveInstType = DestructiveOther;
10989  let ElementSize         = dst_ty.ElementSize;
10990  let Uses = [FPMR, FPCR];
10991}
10992
10993multiclass sve2_fp8_mla<bits<3> opc,  ZPRRegOp dst_ty, string mnemonic, ValueType vta, SDPatternOperator op> {
10994  def NAME : sve2_fp8_mla<opc, dst_ty, mnemonic>;
10995
10996  def : SVE_3_Op_Pat<vta, op, vta, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
10997}
10998
10999// FP8 Widening Multiply-Add Long Long - Indexed Group
11000class sve2_fp8_mla_long_long_by_indexed_elem<bits<2> TT, string mnemonic>
11001    : I<(outs ZPR32:$Zda),
11002      (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexB32b:$imm4),
11003      mnemonic, "\t$Zda, $Zn, $Zm$imm4",
11004      "", []>, Sched<[]>{
11005  bits<5> Zda;
11006  bits<5> Zn;
11007  bits<3> Zm;
11008  bits<4> imm4;
11009  let Inst{31-24} = 0b01100100;
11010  let Inst{23-22} = TT;
11011  let Inst{21}    = 0b1;
11012  let Inst{20-19} = imm4{3-2};
11013  let Inst{18-16} = Zm;
11014  let Inst{15-12} = 0b1100;
11015  let Inst{11-10} = imm4{1-0};
11016  let Inst{9-5}   = Zn;
11017  let Inst{4-0}   = Zda;
11018  let Constraints = "$Zda = $_Zda";
11019  let DestructiveInstType = DestructiveOther;
11020  let ElementSize         = ZPR32.ElementSize;
11021  let Uses = [FPMR, FPCR];
11022}
11023
11024multiclass sve2_fp8_mla_long_long_by_indexed_elem<bits<2> TT, string mnemonic, SDPatternOperator op> {
11025  def NAME : sve2_fp8_mla_long_long_by_indexed_elem<TT, mnemonic>;
11026
11027  def : SVE_4_Op_Pat<nxv4f32, op, nxv4f32, nxv16i8, nxv16i8, i32, !cast<Instruction>(NAME)>;
11028}
11029
11030// FP8 Matrix Multiply-accumulate Group
11031class sve2_fp8_mmla<bit opc, ZPRRegOp dst_ty, string mnemonic>
11032    : I<(outs dst_ty:$Zda),
11033      (ins dst_ty:$_Zda, ZPR8:$Zn, ZPR8:$Zm),
11034      mnemonic, "\t$Zda, $Zn, $Zm",
11035      "", []>, Sched<[]>{
11036  bits<5> Zda;
11037  bits<5> Zn;
11038  bits<5> Zm;
11039  let Inst{31-23} = 0b011001000;
11040  let Inst{22}    = opc;
11041  let Inst{21}    = 0b1;
11042  let Inst{20-16} = Zm;
11043  let Inst{15-10} = 0b111000;
11044  let Inst{9-5}   = Zn;
11045  let Inst{4-0}   = Zda;
11046  let Constraints = "$Zda = $_Zda";
11047  let DestructiveInstType = DestructiveOther;
11048  let ElementSize         = dst_ty.ElementSize;
11049  let Uses = [FPMR, FPCR];
11050}
11051
11052class sve_fp8_dot_indexed<bits<4> opc, ZPRRegOp dst_ty, Operand iop_ty, string mnemonic>
11053: I<(outs dst_ty:$Zda), (ins dst_ty:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, iop_ty:$iop),
11054    mnemonic, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
11055  bits<5> Zda;
11056  bits<5> Zn;
11057  bits<3> Zm;
11058  let Inst{31-23} = 0b011001000;
11059  let Inst{22}    = opc{3};
11060  let Inst{21}    = 0b1;
11061  let Inst{20-19} = opc{2-1};
11062  let Inst{18-16} = Zm;
11063  let Inst{15-12} = 0b0100;
11064  let Inst{11}    = opc{0};
11065  let Inst{10}    = 0b1;
11066  let Inst{9-5}   = Zn;
11067  let Inst{4-0}   = Zda;
11068
11069  let Uses = [FPMR, FPCR];
11070  let Constraints = "$Zda = $_Zda";
11071  let DestructiveInstType = DestructiveOther;
11072  let hasSideEffects = 0;
11073  let mayRaiseFPException = 1;
11074
11075  let mayLoad  = 1;
11076  let mayStore = 0;
11077}
11078
11079// FP8 Widening Dot-Product - Indexed Group
11080multiclass sve2_fp8_dot_indexed_h<string asm, SDPatternOperator op> {
11081  def NAME : sve_fp8_dot_indexed<{0, ?, ?, ?}, ZPR16, VectorIndexH32b, asm> {
11082    bits<3> iop;
11083
11084    let Inst{20-19} = iop{2-1};
11085    let Inst{11}    = iop{0};
11086  }
11087
11088  def : SVE_4_Op_Pat<nxv8f16, op, nxv8f16, nxv16i8, nxv16i8, i32, !cast<Instruction>(NAME)>;
11089}
11090
11091multiclass sve2_fp8_dot_indexed_s<string asm, SDPatternOperator op> {
11092  def NAME : sve_fp8_dot_indexed<{1, ?, ?, 0}, ZPR32, VectorIndexS32b, asm> {
11093    bits<2> iop;
11094
11095    let Inst{20-19} = iop{1-0};
11096  }
11097
11098  def : SVE_4_Op_Pat<nxv4f32, op, nxv4f32, nxv16i8, nxv16i8, i32, !cast<Instruction>(NAME)>;
11099}
11100
11101// FP8 Look up table
11102class sve2_lut_vector_index<ZPRRegOp zd_ty, RegisterOperand zn_ty,
11103                            Operand idx_ty, bits<4>opc, string mnemonic>
11104    : I<(outs zd_ty:$Zd), (ins zn_ty:$Zn, ZPRAny:$Zm, idx_ty:$idx),
11105      mnemonic, "\t$Zd, $Zn, $Zm$idx",
11106      "", []>, Sched<[]> {
11107  bits<5> Zd;
11108  bits<5> Zn;
11109  bits<5> Zm;
11110  let Inst{31-24} = 0b01000101;
11111  let Inst{22}    = opc{3};
11112  let Inst{21}    = 0b1;
11113  let Inst{20-16} = Zm;
11114  let Inst{15-13} = 0b101;
11115  let Inst{12-10} = opc{2-0};
11116  let Inst{9-5}   = Zn;
11117  let Inst{4-0}   = Zd;
11118}
11119
11120// FP8 Look up table read with 2-bit indices
11121multiclass sve2_luti2_vector_index<string mnemonic> {
11122  def _B : sve2_lut_vector_index<ZPR8, Z_b, VectorIndexS32b, {?, 0b100}, mnemonic> {
11123    bits<2> idx;
11124    let Inst{23-22} = idx;
11125  }
11126  def _H : sve2_lut_vector_index<ZPR16, Z_h, VectorIndexH32b, {?,?,0b10}, mnemonic> {
11127    bits<3> idx;
11128    let Inst{23-22} = idx{2-1};
11129    let Inst{12}    = idx{0};
11130  }
11131
11132  def : SVE_3_Op_Imm_Pat<nxv16i8, int_aarch64_sve_luti2_lane, nxv16i8, nxv16i8,
11133                         i32, timm32_0_3, !cast<Instruction>(NAME # _B)>;
11134  def : SVE_3_Op_Imm_Pat<nxv8i16, int_aarch64_sve_luti2_lane, nxv8i16, nxv16i8,
11135                         i32, timm32_0_7, !cast<Instruction>(NAME # _H)>;
11136  def : SVE_3_Op_Imm_Pat<nxv8f16, int_aarch64_sve_luti2_lane, nxv8f16, nxv16i8,
11137                         i32, timm32_0_7, !cast<Instruction>(NAME # _H)>;
11138  def : SVE_3_Op_Imm_Pat<nxv8bf16, int_aarch64_sve_luti2_lane, nxv8bf16, nxv16i8,
11139                         i32, timm32_0_7, !cast<Instruction>(NAME # _H)>;
11140}
11141
11142// FP8 Look up table read with 4-bit indices
11143multiclass sve2_luti4_vector_index<string mnemonic> {
11144  def _B : sve2_lut_vector_index<ZPR8, Z_b, VectorIndexD32b, 0b1001, mnemonic> {
11145    bit idx;
11146    let Inst{23} = idx;
11147  }
11148  def _H : sve2_lut_vector_index<ZPR16, Z_h, VectorIndexS32b, {?, 0b111}, mnemonic> {
11149    bits<2> idx;
11150    let Inst{23-22} = idx;
11151  }
11152
11153  def : SVE_3_Op_Imm_Pat<nxv16i8, int_aarch64_sve_luti4_lane, nxv16i8, nxv16i8,
11154                        i32, timm32_0_1, !cast<Instruction>(NAME # _B)>;
11155  def : SVE_3_Op_Imm_Pat<nxv8i16, int_aarch64_sve_luti4_lane, nxv8i16, nxv16i8,
11156                         i32, timm32_0_3, !cast<Instruction>(NAME # _H)>;
11157  def : SVE_3_Op_Imm_Pat<nxv8f16, int_aarch64_sve_luti4_lane, nxv8f16, nxv16i8,
11158                         i32, timm32_0_3, !cast<Instruction>(NAME # _H)>;
11159  def : SVE_3_Op_Imm_Pat<nxv8bf16, int_aarch64_sve_luti4_lane, nxv8bf16, nxv16i8,
11160                         i32, timm32_0_3, !cast<Instruction>(NAME # _H)>;
11161}
11162
11163// FP8 Look up table read with 4-bit indices (two contiguous registers)
11164multiclass sve2_luti4_vector_vg2_index<string mnemonic> {
11165  def NAME : sve2_lut_vector_index<ZPR16, ZZ_h, VectorIndexS32b, {?, 0b101}, mnemonic> {
11166    bits<2> idx;
11167    let Inst{23-22} = idx;
11168  }
11169
11170  def : Pat<(nxv8i16 (int_aarch64_sve_luti4_lane_x2 nxv8i16:$Op1, nxv8i16:$Op2,
11171                      nxv16i8:$Op3, (i32 timm32_0_3:$Op4))),
11172            (nxv8i16 (!cast<Instruction>(NAME) (REG_SEQUENCE ZPR2, nxv8i16:$Op1, zsub0,
11173                                                                   nxv8i16:$Op2, zsub1),
11174                                                nxv16i8:$Op3, timm32_0_3:$Op4))>;
11175  def : Pat<(nxv8f16 (int_aarch64_sve_luti4_lane_x2 nxv8f16:$Op1, nxv8f16:$Op2,
11176                      nxv16i8:$Op3, (i32 timm32_0_3:$Op4))),
11177            (nxv8f16 (!cast<Instruction>(NAME) (REG_SEQUENCE ZPR2, nxv8f16:$Op1, zsub0,
11178                                                                   nxv8f16:$Op2, zsub1),
11179                                                nxv16i8:$Op3, timm32_0_3:$Op4))>;
11180  def : Pat<(nxv8bf16 (int_aarch64_sve_luti4_lane_x2 nxv8bf16:$Op1, nxv8bf16:$Op2,
11181                      nxv16i8:$Op3, (i32 timm32_0_3:$Op4))),
11182            (nxv8bf16 (!cast<Instruction>(NAME) (REG_SEQUENCE ZPR2, nxv8bf16:$Op1, zsub0,
11183                                                                    nxv8bf16:$Op2, zsub1),
11184                                                nxv16i8:$Op3, timm32_0_3:$Op4))>;
11185}
11186
11187//===----------------------------------------------------------------------===//
11188// Checked Pointer Arithmetic (FEAT_CPA)
11189//===----------------------------------------------------------------------===//
11190class sve_int_mad_cpa<string asm>
11191    : I<(outs ZPR64:$Zdn), (ins ZPR64:$_Zdn, ZPR64:$Zm, ZPR64:$Za),
11192        asm, "\t$Zdn, $Zm, $Za", "", []>, Sched<[]> {
11193  bits<5> Zdn;
11194  bits<5> Zm;
11195  bits<5> Za;
11196  let Inst{31-24} = 0b01000100;
11197  let Inst{23-22} = 0b11; // sz
11198  let Inst{21}    = 0b0;
11199  let Inst{20-16} = Zm;
11200  let Inst{15}    = 0b1;
11201  let Inst{14-10} = 0b10110; // opc
11202  let Inst{9-5}   = Za;
11203  let Inst{4-0}   = Zdn;
11204
11205  let Constraints = "$Zdn = $_Zdn";
11206  let DestructiveInstType = DestructiveOther;
11207  let ElementSize = ZPR64.ElementSize;
11208  let hasSideEffects = 0;
11209}
11210
11211class sve_int_mla_cpa<string asm>
11212    : sve2_int_mla<0b11, 0b10100, asm, ZPR64, ZPR64> {
11213  let Inst{15} = 0b1;
11214
11215  let ElementSize = ZPR64.ElementSize;
11216}
11217