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 find the largest legal scalable vector type that can hold VT.
14// Non-matches return VT, which often means VT is the container type.
15class SVEContainerVT<ValueType VT> {
16  ValueType Value = !cond(
17    // fixed length vectors
18    !eq(VT, v8i8): nxv16i8,
19    !eq(VT, v16i8): nxv16i8,
20    !eq(VT, v4i16): nxv8i16,
21    !eq(VT, v8i16): nxv8i16,
22    !eq(VT, v2i32): nxv4i32,
23    !eq(VT, v4i32): nxv4i32,
24    !eq(VT, v1i64): nxv2i64,
25    !eq(VT, v2i64): nxv2i64,
26    !eq(VT, v4f16): nxv8f16,
27    !eq(VT, v8f16): nxv8f16,
28    !eq(VT, v2f32): nxv4f32,
29    !eq(VT, v4f32): nxv4f32,
30    !eq(VT, v1f64): nxv2f64,
31    !eq(VT, v2f64): nxv2f64,
32    !eq(VT, v4bf16): nxv8bf16,
33    !eq(VT, v8bf16): nxv8bf16,
34    // unpacked scalable vectors
35    !eq(VT, nxv2f16): nxv8f16,
36    !eq(VT, nxv4f16): nxv8f16,
37    !eq(VT, nxv2f32): nxv4f32,
38    !eq(VT, nxv2bf16): nxv8bf16,
39    !eq(VT, nxv4bf16): nxv8bf16,
40    true : VT);
41}
42
43def SDT_AArch64Setcc : SDTypeProfile<1, 4, [
44  SDTCisVec<0>, SDTCisVec<1>, SDTCisVec<2>, SDTCisVec<3>,
45  SDTCVecEltisVT<0, i1>, SDTCVecEltisVT<1, i1>, SDTCisSameAs<2, 3>,
46  SDTCisVT<4, OtherVT>
47]>;
48
49def AArch64setcc_z : SDNode<"AArch64ISD::SETCC_MERGE_ZERO", SDT_AArch64Setcc>;
50def AArch64setcc_z_oneuse : PatFrag<(ops node:$pg, node:$op1, node:$op2, node:$cc),
51                                    (AArch64setcc_z node:$pg, node:$op1, node:$op2, node:$cc), [{
52  return N->hasOneUse();
53}]>;
54
55def SVEPatternOperand : AsmOperandClass {
56  let Name = "SVEPattern";
57  let ParserMethod = "tryParseSVEPattern";
58  let PredicateMethod = "isSVEPattern";
59  let RenderMethod = "addImmOperands";
60  let DiagnosticType = "InvalidSVEPattern";
61}
62
63def sve_pred_enum : Operand<i32>, TImmLeaf<i32, [{
64  return (((uint32_t)Imm) < 32);
65  }]> {
66
67  let PrintMethod = "printSVEPattern";
68  let ParserMatchClass = SVEPatternOperand;
69}
70
71def SVEVecLenSpecifierOperand : AsmOperandClass {
72  let Name = "SVEVecLenSpecifier";
73  let ParserMethod = "tryParseSVEVecLenSpecifier";
74  let PredicateMethod = "isSVEVecLenSpecifier";
75  let RenderMethod = "addImmOperands";
76  let DiagnosticType = "InvalidSVEVecLenSpecifier";
77}
78
79def sve_vec_len_specifier_enum : Operand<i32>, TImmLeaf<i32, [{
80  return (((uint32_t)Imm) < 2);
81  }]> {
82
83  let PrintMethod = "printSVEVecLenSpecifier";
84  let ParserMatchClass = SVEVecLenSpecifierOperand;
85}
86
87def SVEPrefetchOperand : AsmOperandClass {
88  let Name = "SVEPrefetch";
89  let ParserMethod = "tryParsePrefetch<true>";
90  let PredicateMethod = "isPrefetch";
91  let RenderMethod = "addPrefetchOperands";
92}
93
94def sve_prfop : Operand<i32>, TImmLeaf<i32, [{
95    return (((uint32_t)Imm) <= 15);
96  }]> {
97  let PrintMethod = "printPrefetchOp<true>";
98  let ParserMatchClass = SVEPrefetchOperand;
99}
100
101class SVELogicalImmOperand<int Width> : AsmOperandClass {
102  let Name = "SVELogicalImm" # Width;
103  let DiagnosticType = "LogicalSecondSource";
104  let PredicateMethod = "isLogicalImm<int" # Width # "_t>";
105  let RenderMethod = "addLogicalImmOperands<int" # Width # "_t>";
106}
107
108def sve_logical_imm8 : Operand<i64> {
109  let ParserMatchClass = SVELogicalImmOperand<8>;
110  let PrintMethod = "printLogicalImm<int8_t>";
111
112  let MCOperandPredicate = [{
113    if (!MCOp.isImm())
114      return false;
115    int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64);
116    return AArch64_AM::isSVEMaskOfIdenticalElements<int8_t>(Val);
117  }];
118}
119
120def sve_logical_imm16 : Operand<i64> {
121  let ParserMatchClass = SVELogicalImmOperand<16>;
122  let PrintMethod = "printLogicalImm<int16_t>";
123
124  let MCOperandPredicate = [{
125    if (!MCOp.isImm())
126      return false;
127    int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64);
128    return AArch64_AM::isSVEMaskOfIdenticalElements<int16_t>(Val);
129  }];
130}
131
132def sve_logical_imm32 : Operand<i64> {
133  let ParserMatchClass = SVELogicalImmOperand<32>;
134  let PrintMethod = "printLogicalImm<int32_t>";
135
136  let MCOperandPredicate = [{
137    if (!MCOp.isImm())
138      return false;
139    int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64);
140    return AArch64_AM::isSVEMaskOfIdenticalElements<int32_t>(Val);
141  }];
142}
143
144class SVEPreferredLogicalImmOperand<int Width> : AsmOperandClass {
145  let Name = "SVEPreferredLogicalImm" # Width;
146  let PredicateMethod = "isSVEPreferredLogicalImm<int" # Width # "_t>";
147  let RenderMethod = "addLogicalImmOperands<int" # Width # "_t>";
148}
149
150def sve_preferred_logical_imm16 : Operand<i64> {
151  let ParserMatchClass = SVEPreferredLogicalImmOperand<16>;
152  let PrintMethod = "printSVELogicalImm<int16_t>";
153
154  let MCOperandPredicate = [{
155    if (!MCOp.isImm())
156      return false;
157    int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64);
158    return AArch64_AM::isSVEMaskOfIdenticalElements<int16_t>(Val) &&
159           AArch64_AM::isSVEMoveMaskPreferredLogicalImmediate(Val);
160  }];
161}
162
163def sve_preferred_logical_imm32 : Operand<i64> {
164  let ParserMatchClass =  SVEPreferredLogicalImmOperand<32>;
165  let PrintMethod = "printSVELogicalImm<int32_t>";
166
167  let MCOperandPredicate = [{
168    if (!MCOp.isImm())
169      return false;
170    int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64);
171    return AArch64_AM::isSVEMaskOfIdenticalElements<int32_t>(Val) &&
172           AArch64_AM::isSVEMoveMaskPreferredLogicalImmediate(Val);
173  }];
174}
175
176def sve_preferred_logical_imm64 : Operand<i64> {
177  let ParserMatchClass = SVEPreferredLogicalImmOperand<64>;
178  let PrintMethod = "printSVELogicalImm<int64_t>";
179
180  let MCOperandPredicate = [{
181    if (!MCOp.isImm())
182      return false;
183    int64_t Val = AArch64_AM::decodeLogicalImmediate(MCOp.getImm(), 64);
184    return AArch64_AM::isSVEMaskOfIdenticalElements<int64_t>(Val) &&
185           AArch64_AM::isSVEMoveMaskPreferredLogicalImmediate(Val);
186  }];
187}
188
189class SVELogicalImmNotOperand<int Width> : AsmOperandClass {
190  let Name = "SVELogicalImm" # Width # "Not";
191  let DiagnosticType = "LogicalSecondSource";
192  let PredicateMethod = "isLogicalImm<int" # Width # "_t>";
193  let RenderMethod = "addLogicalImmNotOperands<int" # Width # "_t>";
194}
195
196def sve_logical_imm8_not : Operand<i64> {
197  let ParserMatchClass = SVELogicalImmNotOperand<8>;
198}
199
200def sve_logical_imm16_not : Operand<i64> {
201  let ParserMatchClass = SVELogicalImmNotOperand<16>;
202}
203
204def sve_logical_imm32_not : Operand<i64> {
205  let ParserMatchClass = SVELogicalImmNotOperand<32>;
206}
207
208class SVEShiftedImmOperand<int ElementWidth, string Infix, string Predicate>
209    : AsmOperandClass {
210  let Name = "SVE" # Infix # "Imm" # ElementWidth;
211  let DiagnosticType = "Invalid" # Name;
212  let RenderMethod = "addImmWithOptionalShiftOperands<8>";
213  let ParserMethod = "tryParseImmWithOptionalShift";
214  let PredicateMethod = Predicate;
215}
216
217def SVECpyImmOperand8  : SVEShiftedImmOperand<8,  "Cpy", "isSVECpyImm<int8_t>">;
218def SVECpyImmOperand16 : SVEShiftedImmOperand<16, "Cpy", "isSVECpyImm<int16_t>">;
219def SVECpyImmOperand32 : SVEShiftedImmOperand<32, "Cpy", "isSVECpyImm<int32_t>">;
220def SVECpyImmOperand64 : SVEShiftedImmOperand<64, "Cpy", "isSVECpyImm<int64_t>">;
221
222def SVEAddSubImmOperand8  : SVEShiftedImmOperand<8,  "AddSub", "isSVEAddSubImm<int8_t>">;
223def SVEAddSubImmOperand16 : SVEShiftedImmOperand<16, "AddSub", "isSVEAddSubImm<int16_t>">;
224def SVEAddSubImmOperand32 : SVEShiftedImmOperand<32, "AddSub", "isSVEAddSubImm<int32_t>">;
225def SVEAddSubImmOperand64 : SVEShiftedImmOperand<64, "AddSub", "isSVEAddSubImm<int64_t>">;
226
227class imm8_opt_lsl<int ElementWidth, string printType,
228                   AsmOperandClass OpndClass>
229    : Operand<i32> {
230  let EncoderMethod = "getImm8OptLsl";
231  let DecoderMethod = "DecodeImm8OptLsl<" # ElementWidth # ">";
232  let PrintMethod = "printImm8OptLsl<" # printType # ">";
233  let ParserMatchClass = OpndClass;
234  let MIOperandInfo = (ops i32imm, i32imm);
235}
236
237def cpy_imm8_opt_lsl_i8  : imm8_opt_lsl<8,  "int8_t",  SVECpyImmOperand8>;
238def cpy_imm8_opt_lsl_i16 : imm8_opt_lsl<16, "int16_t", SVECpyImmOperand16>;
239def cpy_imm8_opt_lsl_i32 : imm8_opt_lsl<32, "int32_t", SVECpyImmOperand32>;
240def cpy_imm8_opt_lsl_i64 : imm8_opt_lsl<64, "int64_t", SVECpyImmOperand64>;
241
242def addsub_imm8_opt_lsl_i8  : imm8_opt_lsl<8,  "uint8_t",  SVEAddSubImmOperand8>;
243def addsub_imm8_opt_lsl_i16 : imm8_opt_lsl<16, "uint16_t", SVEAddSubImmOperand16>;
244def addsub_imm8_opt_lsl_i32 : imm8_opt_lsl<32, "uint32_t", SVEAddSubImmOperand32>;
245def addsub_imm8_opt_lsl_i64 : imm8_opt_lsl<64, "uint64_t", SVEAddSubImmOperand64>;
246
247def SVEAddSubImm8Pat  : ComplexPattern<i32, 2, "SelectSVEAddSubImm<MVT::i8>", []>;
248def SVEAddSubImm16Pat : ComplexPattern<i32, 2, "SelectSVEAddSubImm<MVT::i16>", []>;
249def SVEAddSubImm32Pat : ComplexPattern<i32, 2, "SelectSVEAddSubImm<MVT::i32>", []>;
250def SVEAddSubImm64Pat : ComplexPattern<i64, 2, "SelectSVEAddSubImm<MVT::i64>", []>;
251
252def SVECpyDupImm8Pat  : ComplexPattern<i32, 2, "SelectSVECpyDupImm<MVT::i8>", []>;
253def SVECpyDupImm16Pat : ComplexPattern<i32, 2, "SelectSVECpyDupImm<MVT::i16>", []>;
254def SVECpyDupImm32Pat : ComplexPattern<i32, 2, "SelectSVECpyDupImm<MVT::i32>", []>;
255def SVECpyDupImm64Pat : ComplexPattern<i64, 2, "SelectSVECpyDupImm<MVT::i64>", []>;
256
257def SVELogicalImm8Pat  : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i8>", []>;
258def SVELogicalImm16Pat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i16>", []>;
259def SVELogicalImm32Pat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i32>", []>;
260def SVELogicalImm64Pat : ComplexPattern<i64, 1, "SelectSVELogicalImm<MVT::i64>", []>;
261
262def SVELogicalImm8NotPat  : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i8, true>", []>;
263def SVELogicalImm16NotPat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i16, true>", []>;
264def SVELogicalImm32NotPat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i32, true>", []>;
265def SVELogicalImm64NotPat : ComplexPattern<i64, 1, "SelectSVELogicalImm<MVT::i64, true>", []>;
266
267def SVEArithUImm8Pat  : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i8>", []>;
268def SVEArithUImm16Pat  : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i16>", []>;
269def SVEArithUImm32Pat  : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i32>", []>;
270def SVEArithUImm64Pat  : ComplexPattern<i64, 1, "SelectSVEArithImm<MVT::i64>", []>;
271
272def SVEArithSImmPat32 : ComplexPattern<i32, 1, "SelectSVESignedArithImm", []>;
273def SVEArithSImmPat64 : ComplexPattern<i64, 1, "SelectSVESignedArithImm", []>;
274
275def SVEShiftImmL8  : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 7>",  []>;
276def SVEShiftImmL16 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 15>", []>;
277def SVEShiftImmL32 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 31>", []>;
278def SVEShiftImmL64 : ComplexPattern<i64, 1, "SelectSVEShiftImm<0, 63>", []>;
279def SVEShiftImmR8  : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 8,  true>", []>;
280def SVEShiftImmR16 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 16, true>", []>;
281def SVEShiftImmR32 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 32, true>", []>;
282def SVEShiftImmR64 : ComplexPattern<i64, 1, "SelectSVEShiftImm<1, 64, true>", []>;
283
284def SVEShiftSplatImmR : ComplexPattern<iAny, 1, "SelectSVEShiftSplatImmR", []>;
285
286def SVEAllActive : ComplexPattern<untyped, 0, "SelectAllActivePredicate", []>;
287def SVEAnyPredicate : ComplexPattern<untyped, 0, "SelectAnyPredicate", []>;
288
289class SVEExactFPImm<string Suffix, string ValA, string ValB> : AsmOperandClass {
290  let Name = "SVEExactFPImmOperand" # Suffix;
291  let DiagnosticType = "Invalid" # Name;
292  let ParserMethod = "tryParseFPImm<false>";
293  let PredicateMethod = "isExactFPImm<" # ValA # ", " # ValB # ">";
294  let RenderMethod = "addExactFPImmOperands<" # ValA # ", " # ValB # ">";
295}
296
297class SVEExactFPImmOperand<string Suffix, string ValA, string ValB> : Operand<i32> {
298  let PrintMethod = "printExactFPImm<" # ValA # ", " # ValB # ">";
299  let ParserMatchClass = SVEExactFPImm<Suffix, ValA, ValB>;
300}
301
302def sve_fpimm_half_one
303    : SVEExactFPImmOperand<"HalfOne", "AArch64ExactFPImm::half",
304                           "AArch64ExactFPImm::one">;
305def sve_fpimm_half_two
306    : SVEExactFPImmOperand<"HalfTwo", "AArch64ExactFPImm::half",
307                           "AArch64ExactFPImm::two">;
308def sve_fpimm_zero_one
309    : SVEExactFPImmOperand<"ZeroOne", "AArch64ExactFPImm::zero",
310                           "AArch64ExactFPImm::one">;
311
312def sve_incdec_imm : Operand<i32>, TImmLeaf<i32, [{
313  return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
314}]> {
315  let ParserMatchClass = Imm1_16Operand;
316  let EncoderMethod = "getSVEIncDecImm";
317  let DecoderMethod = "DecodeSVEIncDecImm";
318}
319
320// This allows i32 immediate extraction from i64 based arithmetic.
321def sve_cnt_mul_imm_i32 : ComplexPattern<i32, 1, "SelectCntImm<1, 16, 1, false>">;
322def sve_cnt_mul_imm_i64 : ComplexPattern<i64, 1, "SelectCntImm<1, 16, 1, false>">;
323def sve_cnt_shl_imm     : ComplexPattern<i64, 1, "SelectCntImm<1, 16, 1, true>">;
324
325def sve_ext_imm_0_31  : ComplexPattern<i64, 1, "SelectEXTImm<31, 8>">;
326def sve_ext_imm_0_63  : ComplexPattern<i64, 1, "SelectEXTImm<63, 4>">;
327def sve_ext_imm_0_127 : ComplexPattern<i64, 1, "SelectEXTImm<127, 2>">;
328def sve_ext_imm_0_255 : ComplexPattern<i64, 1, "SelectEXTImm<255, 1>">;
329
330def int_aarch64_sve_cntp_oneuse : PatFrag<(ops node:$pred, node:$src2),
331                                          (int_aarch64_sve_cntp node:$pred, node:$src2), [{
332  return N->hasOneUse();
333}]>;
334
335def step_vector_oneuse : PatFrag<(ops node:$idx),
336                                 (step_vector node:$idx), [{
337  return N->hasOneUse();
338}]>;
339
340
341//===----------------------------------------------------------------------===//
342// SVE PTrue - These are used extensively throughout the pattern matching so
343//             it's important we define them first.
344//===----------------------------------------------------------------------===//
345
346class sve_int_ptrue<bits<2> sz8_64, bits<3> opc, string asm, PPRRegOp pprty,
347                    ValueType vt, SDPatternOperator op>
348: I<(outs pprty:$Pd), (ins sve_pred_enum:$pattern),
349  asm, "\t$Pd, $pattern",
350  "",
351  [(set (vt pprty:$Pd), (op sve_pred_enum:$pattern))]>, Sched<[]> {
352  bits<4> Pd;
353  bits<5> pattern;
354  let Inst{31-24} = 0b00100101;
355  let Inst{23-22} = sz8_64;
356  let Inst{21-19} = 0b011;
357  let Inst{18-17} = opc{2-1};
358  let Inst{16}    = opc{0};
359  let Inst{15-10} = 0b111000;
360  let Inst{9-5}   = pattern;
361  let Inst{4}     = 0b0;
362  let Inst{3-0}   = Pd;
363
364  let Defs = !if(!eq (opc{0}, 1), [NZCV], []);
365  let ElementSize = pprty.ElementSize;
366  let hasSideEffects = 0;
367  let isReMaterializable = 1;
368}
369
370multiclass sve_int_ptrue<bits<3> opc, string asm, SDPatternOperator op> {
371  def _B : sve_int_ptrue<0b00, opc, asm, PPR8, nxv16i1, op>;
372  def _H : sve_int_ptrue<0b01, opc, asm, PPR16, nxv8i1, op>;
373  def _S : sve_int_ptrue<0b10, opc, asm, PPR32, nxv4i1, op>;
374  def _D : sve_int_ptrue<0b11, opc, asm, PPR64, nxv2i1, op>;
375
376  def : InstAlias<asm # "\t$Pd",
377                  (!cast<Instruction>(NAME # _B) PPR8:$Pd, 0b11111), 1>;
378  def : InstAlias<asm # "\t$Pd",
379                  (!cast<Instruction>(NAME # _H) PPR16:$Pd, 0b11111), 1>;
380  def : InstAlias<asm # "\t$Pd",
381                  (!cast<Instruction>(NAME # _S) PPR32:$Pd, 0b11111), 1>;
382  def : InstAlias<asm # "\t$Pd",
383                  (!cast<Instruction>(NAME # _D) PPR64:$Pd, 0b11111), 1>;
384}
385
386def SDT_AArch64PTrue : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVT<1, i32>]>;
387def AArch64ptrue : SDNode<"AArch64ISD::PTRUE", SDT_AArch64PTrue>;
388
389let Predicates = [HasSVEorSME] in {
390  defm PTRUE  : sve_int_ptrue<0b000, "ptrue", AArch64ptrue>;
391  defm PTRUES : sve_int_ptrue<0b001, "ptrues", null_frag>;
392
393  def : Pat<(nxv16i1 immAllOnesV), (PTRUE_B 31)>;
394  def : Pat<(nxv8i1 immAllOnesV), (PTRUE_H 31)>;
395  def : Pat<(nxv4i1 immAllOnesV), (PTRUE_S 31)>;
396  def : Pat<(nxv2i1 immAllOnesV), (PTRUE_D 31)>;
397}
398
399//===----------------------------------------------------------------------===//
400// SVE pattern match helpers.
401//===----------------------------------------------------------------------===//
402
403class SVE_1_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
404                   Instruction inst>
405: Pat<(vtd (op vt1:$Op1)),
406      (inst $Op1)>;
407
408class SVE_1_Op_Passthru_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
409                            ValueType vts, Instruction inst>
410: Pat<(vtd (op pg:$Op1, vts:$Op2, vtd:$Op3)),
411      (inst $Op3, $Op1, $Op2)>;
412
413
414multiclass SVE_1_Op_PassthruUndef_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
415                                 ValueType vts, Instruction inst> {
416  def : Pat<(vtd (op pg:$Op1, vts:$Op2, (vtd undef))),
417            (inst (IMPLICIT_DEF), $Op1, $Op2)>;
418  def : Pat<(vtd (op (pg (SVEAllActive:$Op1)), vts:$Op2, vtd:$Op3)),
419            (inst $Op3, $Op1, $Op2)>;
420}
421
422// Used to match FP_ROUND_MERGE_PASSTHRU, which has an additional flag for the
423// type of rounding. This is matched by timm0_1 in pattern below and ignored.
424class SVE_1_Op_Passthru_Round_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
425                                  ValueType vts, Instruction inst>
426: Pat<(vtd (op pg:$Op1, vts:$Op2, (i64 timm0_1), vtd:$Op3)),
427      (inst $Op3, $Op1, $Op2)>;
428
429multiclass SVE_1_Op_PassthruUndef_Round_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
430                                  ValueType vts, Instruction inst>{
431  def : Pat<(vtd (op pg:$Op1, vts:$Op2, (i64 timm0_1), (vtd undef))),
432            (inst (IMPLICIT_DEF), $Op1, $Op2)>;
433  def : Pat<(vtd (op (pg (SVEAllActive:$Op1)), vts:$Op2, (i64 timm0_1), vtd:$Op3)),
434            (inst $Op3, $Op1, $Op2)>;
435}
436
437def SVEDup0 : ComplexPattern<vAny, 0, "SelectDupZero", []>;
438def SVEDupNeg0 : ComplexPattern<vAny, 0, "SelectDupNegativeZero", []>;
439
440class SVE_1_Op_PassthruZero_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
441                   ValueType vt2, Instruction inst>
442   : Pat<(vtd (op (vtd (SVEDup0)), vt1:$Op1, vt2:$Op2)),
443        (inst (IMPLICIT_DEF), $Op1, $Op2)>;
444
445class SVE_1_Op_Imm_OptLsl_Pat<ValueType vt, SDPatternOperator op, ZPRRegOp zprty,
446                              ValueType it, ComplexPattern cpx, Instruction inst>
447  : Pat<(vt (op (vt zprty:$Op1), (vt (splat_vector (it (cpx i32:$imm, i32:$shift)))))),
448        (inst $Op1, i32:$imm, i32:$shift)>;
449
450class SVE_1_Op_Imm_Arith_Any_Predicate<ValueType vt, ValueType pt,
451                                       SDPatternOperator op, ZPRRegOp zprty,
452                                       ValueType it, ComplexPattern cpx,
453                                       Instruction inst>
454  : Pat<(vt (op (pt (SVEAnyPredicate)), (vt zprty:$Op1), (vt (splat_vector (it (cpx i32:$imm)))))),
455        (inst $Op1, i32:$imm)>;
456
457class SVE_1_Op_Imm_Log_Pat<ValueType vt, SDPatternOperator op, ZPRRegOp zprty,
458                           ValueType it, ComplexPattern cpx, Instruction inst>
459  : Pat<(vt (op (vt zprty:$Op1), (vt (splat_vector (it (cpx i64:$imm)))))),
460        (inst $Op1, i64:$imm)>;
461
462class SVE_2_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
463                   ValueType vt2, Instruction inst>
464: Pat<(vtd (op vt1:$Op1, vt2:$Op2)),
465      (inst $Op1, $Op2)>;
466
467class SVE_2_Op_Pred_All_Active<ValueType vtd, SDPatternOperator op,
468                               ValueType pt, ValueType vt1, ValueType vt2,
469                               Instruction inst>
470: Pat<(vtd (op (pt (SVEAllActive)), vt1:$Op1, vt2:$Op2)),
471      (inst $Op1, $Op2)>;
472
473class SVE_2_Op_Pred_All_Active_Pt<ValueType vtd, SDPatternOperator op,
474                                  ValueType pt, ValueType vt1, ValueType vt2,
475                                  Instruction inst>
476: Pat<(vtd (op (pt (SVEAllActive:$Op1)), vt1:$Op2, vt2:$Op3)),
477      (inst $Op1, $Op2, $Op3)>;
478
479class SVE_2_Op_Pred_Any_Predicate<ValueType vtd, SDPatternOperator op,
480                                  ValueType pt, ValueType vt1, ValueType vt2,
481                                  Instruction inst>
482: Pat<(vtd (op (pt (SVEAnyPredicate)), vt1:$Op1, vt2:$Op2)),
483      (inst $Op1, $Op2)>;
484
485class SVE_3_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
486                   ValueType vt2, ValueType vt3, Instruction inst>
487: Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3)),
488      (inst $Op1, $Op2, $Op3)>;
489
490multiclass SVE_3_Op_Undef_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
491                              ValueType vt2, ValueType vt3, Instruction inst> {
492  def : Pat<(vtd (op (vt1 undef), vt2:$Op1, vt3:$Op2)),
493            (inst (IMPLICIT_DEF), $Op1, $Op2)>;
494  def : Pat<(vtd (op vt1:$Op1, (vt2 (SVEAllActive:$Op2)), vt3:$Op3)),
495            (inst $Op1, $Op2, $Op3)>;
496}
497
498class SVE_4_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
499                   ValueType vt2, ValueType vt3, ValueType vt4,
500                   Instruction inst>
501: Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3, vt4:$Op4)),
502      (inst $Op1, $Op2, $Op3, $Op4)>;
503
504class SVE_2_Op_Imm_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
505                       ValueType vt2, Operand ImmTy, Instruction inst>
506: Pat<(vtd (op vt1:$Op1, (vt2 ImmTy:$Op2))),
507      (inst $Op1, ImmTy:$Op2)>;
508
509multiclass SVE2p1_Cntp_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
510                           Instruction inst> {
511  def : Pat<(vtd (op vt1:$Op1, (i32 2))), (inst $Op1, 0)>;
512  def : Pat<(vtd (op vt1:$Op1, (i32 4))), (inst $Op1, 1)>;
513}
514
515multiclass SVE2p1_While_PN_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
516                               Instruction inst> {
517  def : Pat<(vtd (op vt1:$Op1, vt1:$Op2, (i32 2))), (inst $Op1, $Op2, 0)>;
518  def : Pat<(vtd (op vt1:$Op1, vt1:$Op2, (i32 4))), (inst $Op1, $Op2, 1)>;
519}
520
521class SVE_3_Op_Imm_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
522                       ValueType vt2, ValueType vt3, Operand ImmTy,
523                       Instruction inst>
524: Pat<(vtd (op vt1:$Op1, vt2:$Op2, (vt3 ImmTy:$Op3))),
525      (inst $Op1, $Op2, ImmTy:$Op3)>;
526
527class SVE_4_Op_Imm_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
528                       ValueType vt2, ValueType vt3, ValueType vt4,
529                       Operand ImmTy, Instruction inst>
530: Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3, (vt4 ImmTy:$Op4))),
531      (inst $Op1, $Op2, $Op3, ImmTy:$Op4)>;
532
533def SVEDup0Undef : ComplexPattern<vAny, 0, "SelectDupZeroOrUndef", []>;
534
535let AddedComplexity = 1 in {
536class SVE_3_Op_Pat_SelZero<ValueType vtd, SDPatternOperator op, ValueType vt1,
537                   ValueType vt2, ValueType vt3, Instruction inst>
538: Pat<(vtd (vtd (op vt1:$Op1, (vselect vt1:$Op1, vt2:$Op2, (SVEDup0)), vt3:$Op3))),
539      (inst $Op1, $Op2, $Op3)>;
540
541class SVE_3_Op_Pat_Shift_Imm_SelZero<ValueType vtd, SDPatternOperator op,
542                                     ValueType vt1, ValueType vt2,
543                                     Operand vt3, Instruction inst>
544: Pat<(vtd (op vt1:$Op1, (vselect vt1:$Op1, vt2:$Op2, (SVEDup0)), (i32 (vt3:$Op3)))),
545      (inst $Op1, $Op2, vt3:$Op3)>;
546}
547
548//
549// Common but less generic patterns.
550//
551
552class SVE_1_Op_AllActive_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
553                             Instruction inst, Instruction ptrue>
554: Pat<(vtd (op vt1:$Op1)),
555      (inst (IMPLICIT_DEF), (ptrue 31), $Op1)>;
556
557class SVE_2_Op_AllActive_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
558                             ValueType vt2, Instruction inst, Instruction ptrue>
559: Pat<(vtd (op vt1:$Op1, vt2:$Op2)),
560      (inst (ptrue 31), $Op1, $Op2)>;
561
562class SVE_InReg_Extend<ValueType vt, SDPatternOperator op, ValueType pt,
563                       ValueType inreg_vt, Instruction inst>
564: Pat<(vt (op pt:$Pg, vt:$Src, inreg_vt, vt:$PassThru)),
565      (inst $PassThru, $Pg, $Src)>;
566
567multiclass SVE_InReg_Extend_PassthruUndef<ValueType vt, SDPatternOperator op, ValueType pt,
568                                          ValueType inreg_vt, Instruction inst> {
569  def : Pat<(vt (op pt:$Pg, vt:$Src, inreg_vt, (vt undef))),
570            (inst (IMPLICIT_DEF), $Pg, $Src)>;
571  def : Pat<(vt (op (pt (SVEAllActive:$Pg)), vt:$Src, inreg_vt, vt:$PassThru)),
572            (inst $PassThru, $Pg, $Src)>;
573}
574
575class SVE_Shift_DupImm_Pred_Pat<ValueType vt, SDPatternOperator op,
576                                ValueType pt, ValueType it,
577                                ComplexPattern cast, Instruction inst>
578: Pat<(vt (op pt:$Pg, vt:$Rn, (vt (splat_vector (it (cast i32:$imm)))))),
579      (inst $Pg, $Rn, i32:$imm)>;
580
581class SVE_Shift_DupImm_Any_Predicate_Pat<ValueType vt, SDPatternOperator op,
582                                         ValueType pt, ValueType it,
583                                         ComplexPattern cast, Instruction inst>
584: Pat<(vt (op (pt (SVEAnyPredicate)), vt:$Rn, (vt (splat_vector (it (cast i32:$imm)))))),
585      (inst $Rn, i32:$imm)>;
586
587class SVE_2_Op_Imm_Pat_Zero<ValueType vt, SDPatternOperator op, ValueType pt,
588                            ValueType it, ComplexPattern cpx, Instruction inst>
589: Pat<(vt (op pt:$Pg, (vselect pt:$Pg, vt:$Op1, (SVEDup0)),
590                      (vt (splat_vector (it (cpx i32:$imm)))))),
591      (inst $Pg, $Op1, i32:$imm)>;
592
593class SVE_2_Op_Fp_Imm_Pat<ValueType vt, SDPatternOperator op,
594                          ValueType pt, ValueType it,
595                          FPImmLeaf immL, int imm,
596                          Instruction inst>
597: Pat<(vt (op (pt PPR_3b:$Pg), (vt ZPR:$Zs1), (vt (splat_vector (it immL))))),
598      (inst $Pg, $Zs1, imm)>;
599
600class SVE_2_Op_Fp_Imm_Pat_Zero<ValueType vt, SDPatternOperator op,
601                              ValueType pt, ValueType it,
602                              FPImmLeaf immL, int imm,
603                              Instruction inst>
604: Pat<(vt (op pt:$Pg, (vselect pt:$Pg, vt:$Zs1, (SVEDup0)),
605                      (vt (splat_vector (it immL))))),
606      (inst $Pg, $Zs1, imm)>;
607
608// Used to re-order the operands of BSP when lowering to BSL. BSP has the order:
609// mask, in1, in2 whereas BSL for SVE2 has them ordered in1, in2, mask
610class SVE_3_Op_BSP_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
611                   ValueType vt2, ValueType vt3, Instruction inst>
612: Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3)),
613      (inst $Op2, $Op3, $Op1)>;
614
615class SVE_Shift_Add_All_Active_Pat<ValueType vtd, SDPatternOperator op, ValueType pt,
616                                   ValueType vt1, ValueType vt2, ValueType vt3,
617                                   Instruction inst>
618: Pat<(vtd (add vt1:$Op1, (op (pt (SVEAllActive)), vt2:$Op2, vt3:$Op3))),
619      (inst $Op1, $Op2, $Op3)>;
620
621class SVE2p1_Sat_Shift_VG2_Pat<string name, SDPatternOperator intrinsic, ValueType out_vt, ValueType in_vt, Operand imm_ty>
622    : Pat<(out_vt (intrinsic in_vt:$Zn1, in_vt:$Zn2, (i32 imm_ty:$i))),
623                  (!cast<Instruction>(name) (REG_SEQUENCE ZPR2Mul2, in_vt:$Zn1, zsub0, in_vt:$Zn2, zsub1), imm_ty:$i)>;
624
625class SVE2p1_Cvt_VG2_Pat<string name, SDPatternOperator intrinsic, ValueType out_vt, ValueType in_vt>
626    : Pat<(out_vt (intrinsic in_vt:$Zn1, in_vt:$Zn2)),
627                  (!cast<Instruction>(name) (REG_SEQUENCE ZPR2Mul2, in_vt:$Zn1, zsub0, in_vt:$Zn2, zsub1))>;
628
629//===----------------------------------------------------------------------===//
630// SVE pattern match helpers.
631//===----------------------------------------------------------------------===//
632
633// Matches either an intrinsic, or a predicated operation with an all active predicate
634class VSelectPredOrPassthruPatFrags<SDPatternOperator intrinsic, SDPatternOperator sdnode>
635: PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [
636    (intrinsic node:$Pg, node:$Op1, node:$Op2),
637    (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op1, node:$Op2), node:$Op1),
638  ], [{
639    return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse();
640  }]>;
641// Same as above with a commutative operation
642class VSelectCommPredOrPassthruPatFrags<SDPatternOperator intrinsic, SDPatternOperator sdnode>
643: PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [
644    (intrinsic node:$Pg, node:$Op1, node:$Op2),
645    (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op1, node:$Op2), node:$Op1),
646    (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op2, node:$Op1), node:$Op1),
647  ], [{
648    return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse();
649  }]>;
650// Similarly matches either an intrinsic, or an unpredicated operation with a select
651class VSelectUnpredOrPassthruPatFrags<SDPatternOperator intrinsic, SDPatternOperator sdnode>
652: PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [
653    (intrinsic node:$Pg, node:$Op1, node:$Op2),
654    (vselect node:$Pg, (sdnode node:$Op1, node:$Op2), node:$Op1),
655  ], [{
656    return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse();
657  }]>;
658
659//
660// Pseudo -> Instruction mappings
661//
662def getSVEPseudoMap : InstrMapping {
663  let FilterClass = "SVEPseudo2Instr";
664  let RowFields = ["PseudoName"];
665  let ColFields = ["IsInstr"];
666  let KeyCol = ["0"];
667  let ValueCols = [["1"]];
668}
669
670class SVEPseudo2Instr<string name, bit instr> {
671  string PseudoName = name;
672  bit IsInstr = instr;
673}
674
675// Lookup e.g. DIV -> DIVR
676def getSVERevInstr : InstrMapping {
677  let FilterClass = "SVEInstr2Rev";
678  let RowFields = ["InstrName"];
679  let ColFields = ["isReverseInstr"];
680  let KeyCol = ["0"];
681  let ValueCols = [["1"]];
682}
683
684// Lookup e.g. DIVR -> DIV
685def getSVENonRevInstr : InstrMapping {
686  let FilterClass = "SVEInstr2Rev";
687  let RowFields = ["InstrName"];
688  let ColFields = ["isReverseInstr"];
689  let KeyCol = ["1"];
690  let ValueCols = [["0"]];
691}
692
693class SVEInstr2Rev<string name1, string name2, bit name1IsReverseInstr> {
694  string InstrName = !if(name1IsReverseInstr, name1, name2);
695  bit isReverseInstr = name1IsReverseInstr;
696}
697
698//
699// Pseudos for destructive operands
700//
701let hasNoSchedulingInfo = 1 in {
702  class PredTwoOpPseudo<string name, ZPRRegOp zprty,
703                        FalseLanesEnum flags = FalseLanesNone>
704  : SVEPseudo2Instr<name, 0>,
705    Pseudo<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zs1, zprty:$Zs2), []> {
706    let FalseLanes = flags;
707  }
708
709  class PredTwoOpImmPseudo<string name, ZPRRegOp zprty, Operand immty,
710                           FalseLanesEnum flags = FalseLanesNone>
711  : SVEPseudo2Instr<name, 0>,
712    Pseudo<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zs1, immty:$imm), []> {
713    let FalseLanes = flags;
714  }
715
716  class PredThreeOpPseudo<string name, ZPRRegOp zprty,
717                          FalseLanesEnum flags = FalseLanesNone>
718  : SVEPseudo2Instr<name, 0>,
719    Pseudo<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zs1, zprty:$Zs2, zprty:$Zs3), []> {
720    let FalseLanes = flags;
721  }
722}
723
724//
725// Pseudos for passthru operands
726//
727let hasNoSchedulingInfo = 1 in {
728  class PredOneOpPassthruPseudo<string name, ZPRRegOp zprty,
729                                FalseLanesEnum flags = FalseLanesNone>
730  : SVEPseudo2Instr<name, 0>,
731    Pseudo<(outs zprty:$Zd), (ins zprty:$Passthru, PPR3bAny:$Pg, zprty:$Zs), []> {
732    let FalseLanes = flags;
733    let Constraints = !if(!eq(flags, FalseLanesZero), "$Zd = $Passthru,@earlyclobber $Zd", "");
734  }
735}
736
737//===----------------------------------------------------------------------===//
738// SVE Predicate Misc Group
739//===----------------------------------------------------------------------===//
740
741class sve_int_pfalse<bits<6> opc, string asm>
742: I<(outs PPR8:$Pd), (ins),
743  asm, "\t$Pd",
744  "",
745  []>, Sched<[]> {
746  bits<4> Pd;
747  let Inst{31-24} = 0b00100101;
748  let Inst{23-22} = opc{5-4};
749  let Inst{21-19} = 0b011;
750  let Inst{18-16} = opc{3-1};
751  let Inst{15-10} = 0b111001;
752  let Inst{9}     = opc{0};
753  let Inst{8-4}   = 0b00000;
754  let Inst{3-0}   = Pd;
755
756  let hasSideEffects = 0;
757  let isReMaterializable = 1;
758}
759
760multiclass sve_int_pfalse<bits<6> opc, string asm> {
761  def NAME : sve_int_pfalse<opc, asm>;
762
763  def : Pat<(nxv16i1 immAllZerosV), (!cast<Instruction>(NAME))>;
764  def : Pat<(nxv8i1 immAllZerosV), (!cast<Instruction>(NAME))>;
765  def : Pat<(nxv4i1 immAllZerosV), (!cast<Instruction>(NAME))>;
766  def : Pat<(nxv2i1 immAllZerosV), (!cast<Instruction>(NAME))>;
767  def : Pat<(nxv1i1 immAllZerosV), (!cast<Instruction>(NAME))>;
768}
769
770class sve_int_ptest<bits<6> opc, string asm, SDPatternOperator op>
771: I<(outs), (ins PPRAny:$Pg, PPR8:$Pn),
772  asm, "\t$Pg, $Pn",
773  "",
774  [(op (nxv16i1 PPRAny:$Pg), (nxv16i1 PPR8:$Pn))]>, Sched<[]> {
775  bits<4> Pg;
776  bits<4> Pn;
777  let Inst{31-24} = 0b00100101;
778  let Inst{23-22} = opc{5-4};
779  let Inst{21-19} = 0b010;
780  let Inst{18-16} = opc{3-1};
781  let Inst{15-14} = 0b11;
782  let Inst{13-10} = Pg;
783  let Inst{9}     = opc{0};
784  let Inst{8-5}   = Pn;
785  let Inst{4-0}   = 0b00000;
786
787  let Defs = [NZCV];
788  let hasSideEffects = 0;
789  let isCompare = 1;
790}
791
792multiclass sve_int_ptest<bits<6> opc, string asm, SDPatternOperator op,
793                         SDPatternOperator op_any> {
794  def NAME : sve_int_ptest<opc, asm, op>;
795
796  let hasNoSchedulingInfo = 1, isCompare = 1, Defs = [NZCV] in {
797  def _ANY : Pseudo<(outs), (ins PPRAny:$Pg, PPR8:$Pn),
798                    [(op_any (nxv16i1 PPRAny:$Pg), (nxv16i1 PPR8:$Pn))]>,
799             PseudoInstExpansion<(!cast<Instruction>(NAME) PPRAny:$Pg, PPR8:$Pn)>;
800  }
801}
802
803class sve_int_pfirst_next<bits<2> sz8_64, bits<5> opc, string asm,
804                          PPRRegOp pprty>
805: I<(outs pprty:$Pdn), (ins PPRAny:$Pg, pprty:$_Pdn),
806  asm, "\t$Pdn, $Pg, $_Pdn",
807  "",
808  []>, Sched<[]> {
809  bits<4> Pdn;
810  bits<4> Pg;
811  let Inst{31-24} = 0b00100101;
812  let Inst{23-22} = sz8_64;
813  let Inst{21-19} = 0b011;
814  let Inst{18-16} = opc{4-2};
815  let Inst{15-11} = 0b11000;
816  let Inst{10-9}  = opc{1-0};
817  let Inst{8-5}   = Pg;
818  let Inst{4}     = 0;
819  let Inst{3-0}   = Pdn;
820
821  let Constraints = "$Pdn = $_Pdn";
822  let Defs = [NZCV];
823  let ElementSize = pprty.ElementSize;
824  let hasSideEffects = 0;
825  let isPTestLike = 1;
826}
827
828multiclass sve_int_pfirst<bits<5> opc, string asm, SDPatternOperator op> {
829  def _B : sve_int_pfirst_next<0b01, opc, asm, PPR8>;
830
831  def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME # _B)>;
832}
833
834multiclass sve_int_pnext<bits<5> opc, string asm, SDPatternOperator op> {
835  def _B : sve_int_pfirst_next<0b00, opc, asm, PPR8>;
836  def _H : sve_int_pfirst_next<0b01, opc, asm, PPR16>;
837  def _S : sve_int_pfirst_next<0b10, opc, asm, PPR32>;
838  def _D : sve_int_pfirst_next<0b11, opc, asm, PPR64>;
839
840  def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME # _B)>;
841  def : SVE_2_Op_Pat<nxv8i1, op, nxv8i1, nxv8i1, !cast<Instruction>(NAME # _H)>;
842  def : SVE_2_Op_Pat<nxv4i1, op, nxv4i1, nxv4i1, !cast<Instruction>(NAME # _S)>;
843  def : SVE_2_Op_Pat<nxv2i1, op, nxv2i1, nxv2i1, !cast<Instruction>(NAME # _D)>;
844}
845
846//===----------------------------------------------------------------------===//
847// SVE Predicate Count Group
848//===----------------------------------------------------------------------===//
849
850class sve_int_count_r<bits<2> sz8_64, bits<5> opc, string asm,
851                      RegisterOperand dty, PPRRegOp pprty, RegisterOperand sty>
852: I<(outs dty:$Rdn), (ins pprty:$Pg, sty:$_Rdn),
853  asm, "\t$Rdn, $Pg",
854  "",
855  []>, Sched<[]> {
856  bits<5> Rdn;
857  bits<4> Pg;
858  let Inst{31-24} = 0b00100101;
859  let Inst{23-22} = sz8_64;
860  let Inst{21-19} = 0b101;
861  let Inst{18-16} = opc{4-2};
862  let Inst{15-11} = 0b10001;
863  let Inst{10-9}  = opc{1-0};
864  let Inst{8-5}   = Pg;
865  let Inst{4-0}   = Rdn;
866
867  // Signed 32bit forms require their GPR operand printed.
868  let AsmString = !if(!eq(opc{4,2-0}, 0b0000),
869                      !strconcat(asm, "\t$Rdn, $Pg, $_Rdn"),
870                      !strconcat(asm, "\t$Rdn, $Pg"));
871  let Constraints = "$Rdn = $_Rdn";
872  let hasSideEffects = 0;
873}
874
875multiclass sve_int_count_r_s32<bits<5> opc, string asm,
876                               SDPatternOperator op> {
877  def _B : sve_int_count_r<0b00, opc, asm, GPR64z, PPR8, GPR64as32>;
878  def _H : sve_int_count_r<0b01, opc, asm, GPR64z, PPR16, GPR64as32>;
879  def _S : sve_int_count_r<0b10, opc, asm, GPR64z, PPR32, GPR64as32>;
880  def _D : sve_int_count_r<0b11, opc, asm, GPR64z, PPR64, GPR64as32>;
881
882  def : Pat<(i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))),
883            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _B) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
884  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))))),
885            (!cast<Instruction>(NAME # _B) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
886
887  def : Pat<(i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))),
888            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _H) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
889  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))))),
890            (!cast<Instruction>(NAME # _H) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
891
892  def : Pat<(i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))),
893            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _S) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
894  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))))),
895            (!cast<Instruction>(NAME # _S) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
896
897  def : Pat<(i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))),
898            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _D) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
899  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))))),
900            (!cast<Instruction>(NAME # _D) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
901}
902
903multiclass sve_int_count_r_u32<bits<5> opc, string asm,
904                               SDPatternOperator op> {
905  def _B : sve_int_count_r<0b00, opc, asm, GPR32z, PPR8, GPR32z>;
906  def _H : sve_int_count_r<0b01, opc, asm, GPR32z, PPR16, GPR32z>;
907  def _S : sve_int_count_r<0b10, opc, asm, GPR32z, PPR32, GPR32z>;
908  def _D : sve_int_count_r<0b11, opc, asm, GPR32z, PPR64, GPR32z>;
909
910  def : Pat<(i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))),
911            (!cast<Instruction>(NAME # _B) PPRAny:$Pg, $Rn)>;
912  def : Pat<(i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))),
913            (!cast<Instruction>(NAME # _H) PPRAny:$Pg, $Rn)>;
914  def : Pat<(i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))),
915            (!cast<Instruction>(NAME # _S) PPRAny:$Pg, $Rn)>;
916  def : Pat<(i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))),
917            (!cast<Instruction>(NAME # _D) PPRAny:$Pg, $Rn)>;
918}
919
920multiclass sve_int_count_r_x64<bits<5> opc, string asm,
921                               SDPatternOperator op,
922                               SDPatternOperator combine_op = null_frag> {
923  def _B : sve_int_count_r<0b00, opc, asm, GPR64z, PPR8, GPR64z>;
924  def _H : sve_int_count_r<0b01, opc, asm, GPR64z, PPR16, GPR64z>;
925  def _S : sve_int_count_r<0b10, opc, asm, GPR64z, PPR32, GPR64z>;
926  def _D : sve_int_count_r<0b11, opc, asm, GPR64z, PPR64, GPR64z>;
927
928  def : Pat<(i64 (op GPR64:$Rn, (nxv16i1 PPRAny:$Pg))),
929            (!cast<Instruction>(NAME # _B) PPRAny:$Pg, $Rn)>;
930  def : Pat<(i64 (op GPR64:$Rn, (nxv8i1 PPRAny:$Pg))),
931            (!cast<Instruction>(NAME # _H) PPRAny:$Pg, $Rn)>;
932  def : Pat<(i64 (op GPR64:$Rn, (nxv4i1 PPRAny:$Pg))),
933            (!cast<Instruction>(NAME # _S) PPRAny:$Pg, $Rn)>;
934  def : Pat<(i64 (op GPR64:$Rn, (nxv2i1 PPRAny:$Pg))),
935            (!cast<Instruction>(NAME # _D) PPRAny:$Pg, $Rn)>;
936
937  // combine_op(x, cntp(all_active, p)) ==> inst p, x
938  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv16i1 (SVEAllActive)), (nxv16i1 PPRAny:$pred)))),
939            (!cast<Instruction>(NAME # _B) PPRAny:$pred, $Rn)>;
940  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv8i1 (SVEAllActive)), (nxv8i1 PPRAny:$pred)))),
941            (!cast<Instruction>(NAME # _H) PPRAny:$pred, $Rn)>;
942  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv4i1 (SVEAllActive)), (nxv4i1 PPRAny:$pred)))),
943            (!cast<Instruction>(NAME # _S) PPRAny:$pred, $Rn)>;
944  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv2i1 (SVEAllActive)), (nxv2i1 PPRAny:$pred)))),
945            (!cast<Instruction>(NAME # _D) PPRAny:$pred, $Rn)>;
946
947  // combine_op(x, cntp(p, p)) ==> inst p, x
948  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv16i1 PPRAny:$pred), (nxv16i1 PPRAny:$pred)))),
949            (!cast<Instruction>(NAME # _B) PPRAny:$pred, $Rn)>;
950  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv8i1 PPRAny:$pred), (nxv8i1 PPRAny:$pred)))),
951            (!cast<Instruction>(NAME # _H) PPRAny:$pred, $Rn)>;
952  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv4i1 PPRAny:$pred), (nxv4i1 PPRAny:$pred)))),
953            (!cast<Instruction>(NAME # _S) PPRAny:$pred, $Rn)>;
954  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv2i1 PPRAny:$pred), (nxv2i1 PPRAny:$pred)))),
955            (!cast<Instruction>(NAME # _D) PPRAny:$pred, $Rn)>;
956
957  // combine_op(x, trunc(cntp(all_active, p))) ==> inst p, x
958  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv16i1 (SVEAllActive)), (nxv16i1 PPRAny:$pred))))),
959            (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _B) PPRAny:$pred,
960                                     (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
961                                 sub_32))>;
962  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv8i1 (SVEAllActive)), (nxv8i1 PPRAny:$pred))))),
963            (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _H) PPRAny:$pred,
964                                     (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
965                                 sub_32))>;
966  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv4i1 (SVEAllActive)), (nxv4i1 PPRAny:$pred))))),
967            (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _S) PPRAny:$pred,
968                                     (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
969                                 sub_32))>;
970  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv2i1 (SVEAllActive)), (nxv2i1 PPRAny:$pred))))),
971            (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _D) PPRAny:$pred,
972                                     (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
973                                 sub_32))>;
974
975  // combine_op(x, trunc(cntp(p, p))) ==> inst p, x
976  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv16i1 PPRAny:$pred), (nxv16i1 PPRAny:$pred))))),
977            (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _B) PPRAny:$pred,
978                                     (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
979                                 sub_32))>;
980  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv8i1 PPRAny:$pred), (nxv8i1 PPRAny:$pred))))),
981            (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _H) PPRAny:$pred,
982                                     (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
983                                 sub_32))>;
984  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv4i1 PPRAny:$pred), (nxv4i1 PPRAny:$pred))))),
985            (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _S) PPRAny:$pred,
986                                     (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
987                                 sub_32))>;
988  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv2i1 PPRAny:$pred), (nxv2i1 PPRAny:$pred))))),
989            (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _D) PPRAny:$pred,
990                                     (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
991                                 sub_32))>;
992}
993
994class sve_int_count_v<bits<2> sz8_64, bits<5> opc, string asm,
995                      ZPRRegOp zprty, PPRRegOp pprty>
996: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, pprty:$Pm),
997  asm, "\t$Zdn, $Pm",
998  "",
999  []>, Sched<[]> {
1000  bits<4> Pm;
1001  bits<5> Zdn;
1002  let Inst{31-24} = 0b00100101;
1003  let Inst{23-22} = sz8_64;
1004  let Inst{21-19} = 0b101;
1005  let Inst{18-16} = opc{4-2};
1006  let Inst{15-11} = 0b10000;
1007  let Inst{10-9}  = opc{1-0};
1008  let Inst{8-5}   = Pm;
1009  let Inst{4-0}   = Zdn;
1010
1011  let Constraints = "$Zdn = $_Zdn";
1012  let DestructiveInstType = DestructiveOther;
1013  let ElementSize = ElementSizeNone;
1014  let hasSideEffects = 0;
1015}
1016
1017multiclass sve_int_count_v<bits<5> opc, string asm,
1018                           SDPatternOperator op = null_frag> {
1019  def _H : sve_int_count_v<0b01, opc, asm, ZPR16, PPR16>;
1020  def _S : sve_int_count_v<0b10, opc, asm, ZPR32, PPR32>;
1021  def _D : sve_int_count_v<0b11, opc, asm, ZPR64, PPR64>;
1022
1023  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16,  nxv8i1, !cast<Instruction>(NAME # _H)>;
1024  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32,  nxv4i1, !cast<Instruction>(NAME # _S)>;
1025  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64,  nxv2i1, !cast<Instruction>(NAME # _D)>;
1026
1027  def : InstAlias<asm # "\t$Zdn, $Pm",
1028                 (!cast<Instruction>(NAME # "_H") ZPR16:$Zdn, PPRAny:$Pm), 0>;
1029  def : InstAlias<asm # "\t$Zdn, $Pm",
1030                 (!cast<Instruction>(NAME # "_S") ZPR32:$Zdn, PPRAny:$Pm), 0>;
1031  def : InstAlias<asm # "\t$Zdn, $Pm",
1032                  (!cast<Instruction>(NAME # "_D") ZPR64:$Zdn, PPRAny:$Pm), 0>;
1033}
1034
1035class sve_int_pcount_pred<bits<2> sz8_64, bits<4> opc, string asm,
1036                          PPRRegOp pprty>
1037: I<(outs GPR64:$Rd), (ins PPRAny:$Pg, pprty:$Pn),
1038  asm, "\t$Rd, $Pg, $Pn",
1039  "",
1040  []>, Sched<[]> {
1041  bits<4> Pg;
1042  bits<4> Pn;
1043  bits<5> Rd;
1044  let Inst{31-24} = 0b00100101;
1045  let Inst{23-22} = sz8_64;
1046  let Inst{21-19} = 0b100;
1047  let Inst{18-16} = opc{3-1};
1048  let Inst{15-14} = 0b10;
1049  let Inst{13-10} = Pg;
1050  let Inst{9}     = opc{0};
1051  let Inst{8-5}   = Pn;
1052  let Inst{4-0}   = Rd;
1053
1054  let hasSideEffects = 0;
1055}
1056
1057multiclass sve_int_pcount_pred<bits<4> opc, string asm,
1058                               SDPatternOperator int_op> {
1059  def _B : sve_int_pcount_pred<0b00, opc, asm, PPR8>;
1060  def _H : sve_int_pcount_pred<0b01, opc, asm, PPR16>;
1061  def _S : sve_int_pcount_pred<0b10, opc, asm, PPR32>;
1062  def _D : sve_int_pcount_pred<0b11, opc, asm, PPR64>;
1063
1064  def : SVE_2_Op_Pat<i64, int_op, nxv16i1, nxv16i1, !cast<Instruction>(NAME # _B)>;
1065  def : SVE_2_Op_Pat<i64, int_op, nxv8i1,  nxv8i1,  !cast<Instruction>(NAME # _H)>;
1066  def : SVE_2_Op_Pat<i64, int_op, nxv4i1,  nxv4i1,  !cast<Instruction>(NAME # _S)>;
1067  def : SVE_2_Op_Pat<i64, int_op, nxv2i1,  nxv2i1,  !cast<Instruction>(NAME # _D)>;
1068}
1069
1070//===----------------------------------------------------------------------===//
1071// SVE Element Count Group
1072//===----------------------------------------------------------------------===//
1073
1074class sve_int_count<bits<3> opc, string asm>
1075: I<(outs GPR64:$Rd), (ins sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1076  asm, "\t$Rd, $pattern, mul $imm4",
1077  "",
1078  []>, Sched<[]> {
1079  bits<5> Rd;
1080  bits<4> imm4;
1081  bits<5> pattern;
1082  let Inst{31-24} = 0b00000100;
1083  let Inst{23-22} = opc{2-1};
1084  let Inst{21-20} = 0b10;
1085  let Inst{19-16} = imm4;
1086  let Inst{15-11} = 0b11100;
1087  let Inst{10}    = opc{0};
1088  let Inst{9-5}   = pattern;
1089  let Inst{4-0}   = Rd;
1090
1091  let hasSideEffects = 0;
1092  let isReMaterializable = 1;
1093}
1094
1095multiclass sve_int_count<bits<3> opc, string asm, SDPatternOperator op> {
1096  def NAME : sve_int_count<opc, asm>;
1097
1098  def : InstAlias<asm # "\t$Rd, $pattern",
1099                  (!cast<Instruction>(NAME) GPR64:$Rd, sve_pred_enum:$pattern, 1), 1>;
1100  def : InstAlias<asm # "\t$Rd",
1101                  (!cast<Instruction>(NAME) GPR64:$Rd, 0b11111, 1), 2>;
1102
1103  def : Pat<(i64 (mul (op sve_pred_enum:$pattern), (sve_cnt_mul_imm_i64 i32:$imm))),
1104            (!cast<Instruction>(NAME) sve_pred_enum:$pattern, sve_incdec_imm:$imm)>;
1105
1106  def : Pat<(i64 (shl (op sve_pred_enum:$pattern), (sve_cnt_shl_imm i32:$imm))),
1107            (!cast<Instruction>(NAME) sve_pred_enum:$pattern, sve_incdec_imm:$imm)>;
1108
1109  def : Pat<(i64 (op sve_pred_enum:$pattern)),
1110            (!cast<Instruction>(NAME) sve_pred_enum:$pattern, 1)>;
1111}
1112
1113class sve_int_countvlv<bits<5> opc, string asm, ZPRRegOp zprty>
1114: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1115  asm, "\t$Zdn, $pattern, mul $imm4",
1116  "",
1117  []>, Sched<[]> {
1118  bits<5> Zdn;
1119  bits<5> pattern;
1120  bits<4> imm4;
1121  let Inst{31-24} = 0b00000100;
1122  let Inst{23-22} = opc{4-3};
1123  let Inst{21}    = 0b1;
1124  let Inst{20}    = opc{2};
1125  let Inst{19-16} = imm4;
1126  let Inst{15-12} = 0b1100;
1127  let Inst{11-10} = opc{1-0};
1128  let Inst{9-5}   = pattern;
1129  let Inst{4-0}   = Zdn;
1130
1131  let Constraints = "$Zdn = $_Zdn";
1132  let DestructiveInstType = DestructiveOther;
1133  let ElementSize = ElementSizeNone;
1134  let hasSideEffects = 0;
1135}
1136
1137multiclass sve_int_countvlv<bits<5> opc, string asm, ZPRRegOp zprty,
1138                            SDPatternOperator op = null_frag,
1139                            ValueType vt = OtherVT> {
1140  def NAME : sve_int_countvlv<opc, asm, zprty>;
1141
1142  def : InstAlias<asm # "\t$Zdn, $pattern",
1143                  (!cast<Instruction>(NAME) zprty:$Zdn, sve_pred_enum:$pattern, 1), 1>;
1144  def : InstAlias<asm # "\t$Zdn",
1145                  (!cast<Instruction>(NAME) zprty:$Zdn, 0b11111, 1), 2>;
1146
1147  def : Pat<(vt (op (vt zprty:$Zn), (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1148            (!cast<Instruction>(NAME) $Zn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1149}
1150
1151class sve_int_pred_pattern_a<bits<3> opc, string asm>
1152: I<(outs GPR64:$Rdn), (ins GPR64:$_Rdn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1153  asm, "\t$Rdn, $pattern, mul $imm4",
1154  "",
1155  []>, Sched<[]> {
1156  bits<5> Rdn;
1157  bits<5> pattern;
1158  bits<4> imm4;
1159  let Inst{31-24} = 0b00000100;
1160  let Inst{23-22} = opc{2-1};
1161  let Inst{21-20} = 0b11;
1162  let Inst{19-16} = imm4;
1163  let Inst{15-11} = 0b11100;
1164  let Inst{10}    = opc{0};
1165  let Inst{9-5}   = pattern;
1166  let Inst{4-0}   = Rdn;
1167
1168  let Constraints = "$Rdn = $_Rdn";
1169  let hasSideEffects = 0;
1170}
1171
1172multiclass sve_int_pred_pattern_a<bits<3> opc, string asm,
1173                                  SDPatternOperator op,
1174                                  SDPatternOperator opcnt> {
1175  let Predicates = [HasSVEorSME] in {
1176    def NAME : sve_int_pred_pattern_a<opc, asm>;
1177
1178    def : InstAlias<asm # "\t$Rdn, $pattern",
1179                    (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, 1), 1>;
1180    def : InstAlias<asm # "\t$Rdn",
1181                    (!cast<Instruction>(NAME) GPR64:$Rdn, 0b11111, 1), 2>;
1182  }
1183
1184  let Predicates = [HasSVEorSME, UseScalarIncVL] in {
1185    def : Pat<(i64 (op GPR64:$Rdn, (opcnt sve_pred_enum:$pattern))),
1186              (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, 1)>;
1187
1188    def : Pat<(i64 (op GPR64:$Rdn, (mul (opcnt sve_pred_enum:$pattern), (sve_cnt_mul_imm_i64 i32:$imm)))),
1189              (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, $imm)>;
1190
1191    def : Pat<(i64 (op GPR64:$Rdn, (shl (opcnt sve_pred_enum:$pattern), (sve_cnt_shl_imm i32:$imm)))),
1192              (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, $imm)>;
1193
1194    def : Pat<(i32 (op GPR32:$Rdn, (i32 (trunc (opcnt (sve_pred_enum:$pattern)))))),
1195              (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
1196                                               GPR32:$Rdn, sub_32), sve_pred_enum:$pattern, 1),
1197                                    sub_32))>;
1198
1199    def : Pat<(i32 (op GPR32:$Rdn, (mul (i32 (trunc (opcnt (sve_pred_enum:$pattern)))), (sve_cnt_mul_imm_i32 i32:$imm)))),
1200              (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
1201                                               GPR32:$Rdn, sub_32), sve_pred_enum:$pattern, $imm),
1202                                    sub_32))>;
1203
1204    def : Pat<(i32 (op GPR32:$Rdn, (shl (i32 (trunc (opcnt (sve_pred_enum:$pattern)))), (sve_cnt_shl_imm i32:$imm)))),
1205              (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
1206                                               GPR32:$Rdn, sub_32), sve_pred_enum:$pattern, $imm),
1207                                    sub_32))>;
1208  }
1209}
1210
1211class sve_int_pred_pattern_b<bits<5> opc, string asm, RegisterOperand dt,
1212                             RegisterOperand st>
1213: I<(outs dt:$Rdn), (ins st:$_Rdn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1214  asm, "\t$Rdn, $pattern, mul $imm4",
1215  "",
1216  []>, Sched<[]> {
1217  bits<5> Rdn;
1218  bits<5> pattern;
1219  bits<4> imm4;
1220  let Inst{31-24} = 0b00000100;
1221  let Inst{23-22} = opc{4-3};
1222  let Inst{21}    = 0b1;
1223  let Inst{20}    = opc{2};
1224  let Inst{19-16} = imm4;
1225  let Inst{15-12} = 0b1111;
1226  let Inst{11-10} = opc{1-0};
1227  let Inst{9-5}   = pattern;
1228  let Inst{4-0}   = Rdn;
1229
1230  // Signed 32bit forms require their GPR operand printed.
1231  let AsmString = !if(!eq(opc{2,0}, 0b00),
1232                      !strconcat(asm, "\t$Rdn, $_Rdn, $pattern, mul $imm4"),
1233                      !strconcat(asm, "\t$Rdn, $pattern, mul $imm4"));
1234
1235  let Constraints = "$Rdn = $_Rdn";
1236  let hasSideEffects = 0;
1237}
1238
1239multiclass sve_int_pred_pattern_b_s32<bits<5> opc, string asm,
1240                                      SDPatternOperator op> {
1241  def NAME : sve_int_pred_pattern_b<opc, asm, GPR64z, GPR64as32>;
1242
1243  def : InstAlias<asm # "\t$Rd, $Rn, $pattern",
1244                  (!cast<Instruction>(NAME) GPR64z:$Rd, GPR64as32:$Rn, sve_pred_enum:$pattern, 1), 1>;
1245  def : InstAlias<asm # "\t$Rd, $Rn",
1246                  (!cast<Instruction>(NAME) GPR64z:$Rd, GPR64as32:$Rn, 0b11111, 1), 2>;
1247
1248  // NOTE: Register allocation doesn't like tied operands of differing register
1249  //       class, hence the extra INSERT_SUBREG complication.
1250
1251  def : Pat<(i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1252            (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32), sve_pred_enum:$pattern, sve_incdec_imm:$imm4), sub_32)>;
1253  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))))),
1254            (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32), sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1255}
1256
1257multiclass sve_int_pred_pattern_b_u32<bits<5> opc, string asm,
1258                                      SDPatternOperator op> {
1259  def NAME : sve_int_pred_pattern_b<opc, asm, GPR32z, GPR32z>;
1260
1261  def : InstAlias<asm # "\t$Rdn, $pattern",
1262                  (!cast<Instruction>(NAME) GPR32z:$Rdn, sve_pred_enum:$pattern, 1), 1>;
1263  def : InstAlias<asm # "\t$Rdn",
1264                  (!cast<Instruction>(NAME) GPR32z:$Rdn, 0b11111, 1), 2>;
1265
1266  def : Pat<(i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1267            (!cast<Instruction>(NAME) $Rn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1268}
1269
1270multiclass sve_int_pred_pattern_b_x64<bits<5> opc, string asm,
1271                                      SDPatternOperator op> {
1272  def NAME : sve_int_pred_pattern_b<opc, asm, GPR64z, GPR64z>;
1273
1274  def : InstAlias<asm # "\t$Rdn, $pattern",
1275                  (!cast<Instruction>(NAME) GPR64z:$Rdn, sve_pred_enum:$pattern, 1), 1>;
1276  def : InstAlias<asm # "\t$Rdn",
1277                  (!cast<Instruction>(NAME) GPR64z:$Rdn, 0b11111, 1), 2>;
1278
1279  def : Pat<(i64 (op GPR64:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1280            (!cast<Instruction>(NAME) $Rn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1281}
1282
1283
1284//===----------------------------------------------------------------------===//
1285// SVE Permute - Cross Lane Group
1286//===----------------------------------------------------------------------===//
1287
1288class sve_int_perm_dup_r<bits<2> sz8_64, string asm, ZPRRegOp zprty,
1289                         ValueType vt, RegisterClass srcRegType,
1290                         SDPatternOperator op>
1291: I<(outs zprty:$Zd), (ins srcRegType:$Rn),
1292  asm, "\t$Zd, $Rn",
1293  "",
1294  [(set (vt zprty:$Zd), (op srcRegType:$Rn))]>, Sched<[]> {
1295  bits<5> Rn;
1296  bits<5> Zd;
1297  let Inst{31-24} = 0b00000101;
1298  let Inst{23-22} = sz8_64;
1299  let Inst{21-10} = 0b100000001110;
1300  let Inst{9-5}   = Rn;
1301  let Inst{4-0}   = Zd;
1302
1303  let hasSideEffects = 0;
1304}
1305
1306multiclass sve_int_perm_dup_r<string asm, SDPatternOperator op> {
1307  def _B : sve_int_perm_dup_r<0b00, asm, ZPR8, nxv16i8, GPR32sp, op>;
1308  def _H : sve_int_perm_dup_r<0b01, asm, ZPR16, nxv8i16, GPR32sp, op>;
1309  def _S : sve_int_perm_dup_r<0b10, asm, ZPR32, nxv4i32, GPR32sp, op>;
1310  def _D : sve_int_perm_dup_r<0b11, asm, ZPR64, nxv2i64, GPR64sp, op>;
1311
1312  def : InstAlias<"mov $Zd, $Rn",
1313                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, GPR32sp:$Rn), 1>;
1314  def : InstAlias<"mov $Zd, $Rn",
1315                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, GPR32sp:$Rn), 1>;
1316  def : InstAlias<"mov $Zd, $Rn",
1317                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, GPR32sp:$Rn), 1>;
1318  def : InstAlias<"mov $Zd, $Rn",
1319                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, GPR64sp:$Rn), 1>;
1320}
1321
1322class sve_int_perm_dup_i<bits<5> tsz, Operand immtype, string asm,
1323                         ZPRRegOp zprty>
1324: I<(outs zprty:$Zd), (ins zprty:$Zn, immtype:$idx),
1325  asm, "\t$Zd, $Zn$idx",
1326  "",
1327  []>, Sched<[]> {
1328  bits<5> Zd;
1329  bits<5> Zn;
1330  bits<7> idx;
1331  let Inst{31-24} = 0b00000101;
1332  let Inst{23-22} = {?,?}; // imm3h
1333  let Inst{21}    = 0b1;
1334  let Inst{20-16} = tsz;
1335  let Inst{15-10} = 0b001000;
1336  let Inst{9-5}   = Zn;
1337  let Inst{4-0}   = Zd;
1338
1339  let hasSideEffects = 0;
1340}
1341
1342multiclass sve_int_perm_dup_i<string asm> {
1343  def _B : sve_int_perm_dup_i<{?,?,?,?,1}, sve_elm_idx_extdup_b, asm, ZPR8> {
1344    let Inst{23-22} = idx{5-4};
1345    let Inst{20-17} = idx{3-0};
1346  }
1347  def _H : sve_int_perm_dup_i<{?,?,?,1,0}, sve_elm_idx_extdup_h, asm, ZPR16> {
1348    let Inst{23-22} = idx{4-3};
1349    let Inst{20-18} = idx{2-0};
1350  }
1351  def _S : sve_int_perm_dup_i<{?,?,1,0,0}, sve_elm_idx_extdup_s, asm, ZPR32> {
1352    let Inst{23-22} = idx{3-2};
1353    let Inst{20-19}    = idx{1-0};
1354  }
1355  def _D : sve_int_perm_dup_i<{?,1,0,0,0}, sve_elm_idx_extdup_d, asm, ZPR64> {
1356    let Inst{23-22} = idx{2-1};
1357    let Inst{20}    = idx{0};
1358  }
1359  def _Q : sve_int_perm_dup_i<{1,0,0,0,0}, sve_elm_idx_extdup_q, asm, ZPR128> {
1360    let Inst{23-22} = idx{1-0};
1361  }
1362
1363  def : InstAlias<"mov $Zd, $Zn$idx",
1364                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, ZPR8:$Zn, sve_elm_idx_extdup_b:$idx), 1>;
1365  def : InstAlias<"mov $Zd, $Zn$idx",
1366                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, ZPR16:$Zn, sve_elm_idx_extdup_h:$idx), 1>;
1367  def : InstAlias<"mov $Zd, $Zn$idx",
1368                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, ZPR32:$Zn, sve_elm_idx_extdup_s:$idx), 1>;
1369  def : InstAlias<"mov $Zd, $Zn$idx",
1370                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, ZPR64:$Zn, sve_elm_idx_extdup_d:$idx), 1>;
1371  def : InstAlias<"mov $Zd, $Zn$idx",
1372                  (!cast<Instruction>(NAME # _Q) ZPR128:$Zd, ZPR128:$Zn, sve_elm_idx_extdup_q:$idx), 1>;
1373  def : InstAlias<"mov $Zd, $Bn",
1374                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, FPR8asZPR:$Bn, 0), 2>;
1375  def : InstAlias<"mov $Zd, $Hn",
1376                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, FPR16asZPR:$Hn, 0), 2>;
1377  def : InstAlias<"mov $Zd, $Sn",
1378                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, FPR32asZPR:$Sn, 0), 2>;
1379  def : InstAlias<"mov $Zd, $Dn",
1380                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, FPR64asZPR:$Dn, 0), 2>;
1381  def : InstAlias<"mov $Zd, $Qn",
1382                  (!cast<Instruction>(NAME # _Q) ZPR128:$Zd, FPR128asZPR:$Qn, 0), 2>;
1383
1384  // Duplicate extracted element of vector into all vector elements
1385  def : Pat<(nxv16i8 (splat_vector (i32 (vector_extract (nxv16i8 ZPR:$vec), sve_elm_idx_extdup_b:$index)))),
1386            (!cast<Instruction>(NAME # _B) ZPR:$vec, sve_elm_idx_extdup_b:$index)>;
1387  def : Pat<(nxv8i16 (splat_vector (i32 (vector_extract (nxv8i16 ZPR:$vec), sve_elm_idx_extdup_h:$index)))),
1388            (!cast<Instruction>(NAME # _H) ZPR:$vec, sve_elm_idx_extdup_h:$index)>;
1389  def : Pat<(nxv4i32 (splat_vector (i32 (vector_extract (nxv4i32 ZPR:$vec), sve_elm_idx_extdup_s:$index)))),
1390            (!cast<Instruction>(NAME # _S) ZPR:$vec, sve_elm_idx_extdup_s:$index)>;
1391  def : Pat<(nxv2i64 (splat_vector (i64 (vector_extract (nxv2i64 ZPR:$vec), sve_elm_idx_extdup_d:$index)))),
1392            (!cast<Instruction>(NAME # _D) ZPR:$vec, sve_elm_idx_extdup_d:$index)>;
1393  def : Pat<(nxv8f16 (splat_vector (f16 (vector_extract (nxv8f16 ZPR:$vec), sve_elm_idx_extdup_h:$index)))),
1394            (!cast<Instruction>(NAME # _H) ZPR:$vec, sve_elm_idx_extdup_h:$index)>;
1395  def : Pat<(nxv8bf16 (splat_vector (bf16 (vector_extract (nxv8bf16 ZPR:$vec), sve_elm_idx_extdup_h:$index)))),
1396            (!cast<Instruction>(NAME # _H) ZPR:$vec, sve_elm_idx_extdup_h:$index)>;
1397  def : Pat<(nxv4f16 (splat_vector (f16 (vector_extract (nxv4f16 ZPR:$vec), sve_elm_idx_extdup_s:$index)))),
1398            (!cast<Instruction>(NAME # _S) ZPR:$vec, sve_elm_idx_extdup_s:$index)>;
1399  def : Pat<(nxv2f16 (splat_vector (f16 (vector_extract (nxv2f16 ZPR:$vec), sve_elm_idx_extdup_d:$index)))),
1400            (!cast<Instruction>(NAME # _D) ZPR:$vec, sve_elm_idx_extdup_d:$index)>;
1401  def : Pat<(nxv4f32 (splat_vector (f32 (vector_extract (nxv4f32 ZPR:$vec), sve_elm_idx_extdup_s:$index)))),
1402            (!cast<Instruction>(NAME # _S) ZPR:$vec, sve_elm_idx_extdup_s:$index)>;
1403  def : Pat<(nxv2f32 (splat_vector (f32 (vector_extract (nxv2f32 ZPR:$vec), sve_elm_idx_extdup_d:$index)))),
1404            (!cast<Instruction>(NAME # _D) ZPR:$vec, sve_elm_idx_extdup_d:$index)>;
1405  def : Pat<(nxv2f64 (splat_vector (f64 (vector_extract (nxv2f64 ZPR:$vec), sve_elm_idx_extdup_d:$index)))),
1406            (!cast<Instruction>(NAME # _D) ZPR:$vec, sve_elm_idx_extdup_d:$index)>;
1407
1408  def : Pat<(nxv16i8 (AArch64duplane128 nxv16i8:$Op1, i64:$imm)),
1409            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1410  def : Pat<(nxv8i16 (AArch64duplane128 nxv8i16:$Op1, i64:$imm)),
1411            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1412  def : Pat<(nxv4i32 (AArch64duplane128 nxv4i32:$Op1, i64:$imm)),
1413            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1414  def : Pat<(nxv2i64 (AArch64duplane128 nxv2i64:$Op1, i64:$imm)),
1415            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1416  def : Pat<(nxv8f16 (AArch64duplane128 nxv8f16:$Op1, i64:$imm)),
1417            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1418  def : Pat<(nxv4f32 (AArch64duplane128 nxv4f32:$Op1, i64:$imm)),
1419            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1420  def : Pat<(nxv2f64 (AArch64duplane128 nxv2f64:$Op1, i64:$imm)),
1421            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1422  def : Pat<(nxv8bf16 (AArch64duplane128 nxv8bf16:$Op1, i64:$imm)),
1423            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1424}
1425
1426class sve_int_perm_tbl<bits<2> sz8_64, bits<2> opc, string asm, ZPRRegOp zprty,
1427                       RegisterOperand VecList>
1428: I<(outs zprty:$Zd), (ins VecList:$Zn, zprty:$Zm),
1429  asm, "\t$Zd, $Zn, $Zm",
1430  "",
1431  []>, Sched<[]> {
1432  bits<5> Zd;
1433  bits<5> Zm;
1434  bits<5> Zn;
1435  let Inst{31-24} = 0b00000101;
1436  let Inst{23-22} = sz8_64;
1437  let Inst{21}    = 0b1;
1438  let Inst{20-16} = Zm;
1439  let Inst{15-13} = 0b001;
1440  let Inst{12-11} = opc;
1441  let Inst{10}    = 0b0;
1442  let Inst{9-5}   = Zn;
1443  let Inst{4-0}   = Zd;
1444
1445  let hasSideEffects = 0;
1446}
1447
1448multiclass sve_int_perm_tbl<string asm, SDPatternOperator op> {
1449  def _B : sve_int_perm_tbl<0b00, 0b10, asm, ZPR8,  Z_b>;
1450  def _H : sve_int_perm_tbl<0b01, 0b10, asm, ZPR16, Z_h>;
1451  def _S : sve_int_perm_tbl<0b10, 0b10, asm, ZPR32, Z_s>;
1452  def _D : sve_int_perm_tbl<0b11, 0b10, asm, ZPR64, Z_d>;
1453
1454  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1455                 (!cast<Instruction>(NAME # _B) ZPR8:$Zd, ZPR8:$Zn, ZPR8:$Zm), 0>;
1456  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1457                 (!cast<Instruction>(NAME # _H) ZPR16:$Zd, ZPR16:$Zn, ZPR16:$Zm), 0>;
1458  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1459                 (!cast<Instruction>(NAME # _S) ZPR32:$Zd, ZPR32:$Zn, ZPR32:$Zm), 0>;
1460  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1461                 (!cast<Instruction>(NAME # _D) ZPR64:$Zd, ZPR64:$Zn, ZPR64:$Zm), 0>;
1462
1463  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
1464  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1465  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1466  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1467
1468  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1469  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1470  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1471
1472  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1473}
1474
1475multiclass sve2_int_perm_tbl<string asm, SDPatternOperator op> {
1476  def _B : sve_int_perm_tbl<0b00, 0b01, asm, ZPR8,  ZZ_b>;
1477  def _H : sve_int_perm_tbl<0b01, 0b01, asm, ZPR16, ZZ_h>;
1478  def _S : sve_int_perm_tbl<0b10, 0b01, asm, ZPR32, ZZ_s>;
1479  def _D : sve_int_perm_tbl<0b11, 0b01, asm, ZPR64, ZZ_d>;
1480
1481  def : Pat<(nxv16i8 (op nxv16i8:$Op1, nxv16i8:$Op2, nxv16i8:$Op3)),
1482            (nxv16i8 (!cast<Instruction>(NAME # _B) (REG_SEQUENCE ZPR2, nxv16i8:$Op1, zsub0,
1483                                                                        nxv16i8:$Op2, zsub1),
1484                                                     nxv16i8:$Op3))>;
1485
1486  def : Pat<(nxv8i16 (op nxv8i16:$Op1, nxv8i16:$Op2, nxv8i16:$Op3)),
1487            (nxv8i16 (!cast<Instruction>(NAME # _H) (REG_SEQUENCE ZPR2, nxv8i16:$Op1, zsub0,
1488                                                                        nxv8i16:$Op2, zsub1),
1489                                                     nxv8i16:$Op3))>;
1490
1491  def : Pat<(nxv4i32 (op nxv4i32:$Op1, nxv4i32:$Op2, nxv4i32:$Op3)),
1492            (nxv4i32 (!cast<Instruction>(NAME # _S) (REG_SEQUENCE ZPR2, nxv4i32:$Op1, zsub0,
1493                                                                        nxv4i32:$Op2, zsub1),
1494                                                     nxv4i32:$Op3))>;
1495
1496  def : Pat<(nxv2i64 (op nxv2i64:$Op1, nxv2i64:$Op2, nxv2i64:$Op3)),
1497            (nxv2i64 (!cast<Instruction>(NAME # _D) (REG_SEQUENCE ZPR2, nxv2i64:$Op1, zsub0,
1498                                                                        nxv2i64:$Op2, zsub1),
1499                                                     nxv2i64:$Op3))>;
1500
1501  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8i16:$Op3)),
1502            (nxv8f16 (!cast<Instruction>(NAME # _H) (REG_SEQUENCE ZPR2, nxv8f16:$Op1, zsub0,
1503                                                                        nxv8f16:$Op2, zsub1),
1504                                                     nxv8i16:$Op3))>;
1505
1506  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4i32:$Op3)),
1507            (nxv4f32 (!cast<Instruction>(NAME # _S) (REG_SEQUENCE ZPR2, nxv4f32:$Op1, zsub0,
1508                                                                        nxv4f32:$Op2, zsub1),
1509                                                     nxv4i32:$Op3))>;
1510
1511  def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, nxv2i64:$Op3)),
1512            (nxv2f64 (!cast<Instruction>(NAME # _D) (REG_SEQUENCE ZPR2, nxv2f64:$Op1, zsub0,
1513                                                                        nxv2f64:$Op2, zsub1),
1514                                                     nxv2i64:$Op3))>;
1515
1516  def : Pat<(nxv8bf16 (op nxv8bf16:$Op1, nxv8bf16:$Op2, nxv8i16:$Op3)),
1517            (nxv8bf16 (!cast<Instruction>(NAME # _H) (REG_SEQUENCE ZPR2, nxv8bf16:$Op1, zsub0,
1518                                                                         nxv8bf16:$Op2, zsub1),
1519                                                      nxv8i16:$Op3))>;
1520}
1521
1522class sve2_int_perm_tbx<bits<2> sz8_64, bits<2> opc, string asm, ZPRRegOp zprty>
1523: I<(outs zprty:$Zd), (ins zprty:$_Zd, zprty:$Zn, zprty:$Zm),
1524  asm, "\t$Zd, $Zn, $Zm",
1525  "",
1526  []>, Sched<[]> {
1527  bits<5> Zd;
1528  bits<5> Zm;
1529  bits<5> Zn;
1530  let Inst{31-24} = 0b00000101;
1531  let Inst{23-22} = sz8_64;
1532  let Inst{21}    = 0b1;
1533  let Inst{20-16} = Zm;
1534  let Inst{15-13} = 0b001;
1535  let Inst{12-11} = opc;
1536  let Inst{10}    = 0b1;
1537  let Inst{9-5}   = Zn;
1538  let Inst{4-0}   = Zd;
1539
1540  let Constraints = "$Zd = $_Zd";
1541  let hasSideEffects = 0;
1542}
1543
1544multiclass sve2_int_perm_tbx<string asm, bits<2> opc, SDPatternOperator op> {
1545  def _B : sve2_int_perm_tbx<0b00, opc, asm, ZPR8>;
1546  def _H : sve2_int_perm_tbx<0b01, opc, asm, ZPR16>;
1547  def _S : sve2_int_perm_tbx<0b10, opc, asm, ZPR32>;
1548  def _D : sve2_int_perm_tbx<0b11, opc, asm, ZPR64>;
1549
1550  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
1551  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1552  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1553  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1554
1555  def : SVE_3_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1556  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1557  def : SVE_3_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1558
1559  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1560}
1561
1562class sve_int_perm_reverse_z<bits<2> sz8_64, string asm, ZPRRegOp zprty>
1563: I<(outs zprty:$Zd), (ins zprty:$Zn),
1564  asm, "\t$Zd, $Zn",
1565  "",
1566  []>, Sched<[]> {
1567  bits<5> Zd;
1568  bits<5> Zn;
1569  let Inst{31-24} = 0b00000101;
1570  let Inst{23-22} = sz8_64;
1571  let Inst{21-10} = 0b111000001110;
1572  let Inst{9-5}   = Zn;
1573  let Inst{4-0}   = Zd;
1574
1575  let hasSideEffects = 0;
1576}
1577
1578multiclass sve_int_perm_reverse_z<string asm, SDPatternOperator op> {
1579  def _B : sve_int_perm_reverse_z<0b00, asm, ZPR8>;
1580  def _H : sve_int_perm_reverse_z<0b01, asm, ZPR16>;
1581  def _S : sve_int_perm_reverse_z<0b10, asm, ZPR32>;
1582  def _D : sve_int_perm_reverse_z<0b11, asm, ZPR64>;
1583
1584  def : SVE_1_Op_Pat<nxv16i8, op, nxv16i8, !cast<Instruction>(NAME # _B)>;
1585  def : SVE_1_Op_Pat<nxv8i16, op, nxv8i16, !cast<Instruction>(NAME # _H)>;
1586  def : SVE_1_Op_Pat<nxv4i32, op, nxv4i32, !cast<Instruction>(NAME # _S)>;
1587  def : SVE_1_Op_Pat<nxv2i64, op, nxv2i64, !cast<Instruction>(NAME # _D)>;
1588
1589  def : SVE_1_Op_Pat<nxv2f16, op, nxv2f16, !cast<Instruction>(NAME # _D)>;
1590  def : SVE_1_Op_Pat<nxv4f16, op, nxv4f16, !cast<Instruction>(NAME # _S)>;
1591  def : SVE_1_Op_Pat<nxv8f16, op, nxv8f16, !cast<Instruction>(NAME # _H)>;
1592  def : SVE_1_Op_Pat<nxv2f32, op, nxv2f32, !cast<Instruction>(NAME # _D)>;
1593  def : SVE_1_Op_Pat<nxv4f32, op, nxv4f32, !cast<Instruction>(NAME # _S)>;
1594  def : SVE_1_Op_Pat<nxv2f64, op, nxv2f64, !cast<Instruction>(NAME # _D)>;
1595
1596  def : SVE_1_Op_Pat<nxv2bf16, op, nxv2bf16, !cast<Instruction>(NAME # _D)>;
1597  def : SVE_1_Op_Pat<nxv4bf16, op, nxv4bf16, !cast<Instruction>(NAME # _S)>;
1598  def : SVE_1_Op_Pat<nxv8bf16, op, nxv8bf16, !cast<Instruction>(NAME # _H)>;
1599}
1600
1601class sve_int_perm_reverse_p<bits<2> sz8_64, string asm, PPRRegOp pprty,
1602                             SDPatternOperator op>
1603: I<(outs pprty:$Pd), (ins pprty:$Pn),
1604  asm, "\t$Pd, $Pn",
1605  "",
1606  [(set nxv16i1:$Pd, (op nxv16i1:$Pn))]>, Sched<[]> {
1607  bits<4> Pd;
1608  bits<4> Pn;
1609  let Inst{31-24} = 0b00000101;
1610  let Inst{23-22} = sz8_64;
1611  let Inst{21-9}  = 0b1101000100000;
1612  let Inst{8-5}   = Pn;
1613  let Inst{4}     = 0b0;
1614  let Inst{3-0}   = Pd;
1615
1616  let hasSideEffects = 0;
1617}
1618
1619multiclass sve_int_perm_reverse_p<string asm, SDPatternOperator ir_op,
1620                                  SDPatternOperator op_b16,
1621                                  SDPatternOperator op_b32,
1622                                  SDPatternOperator op_b64> {
1623  def _B : sve_int_perm_reverse_p<0b00, asm, PPR8,  ir_op>;
1624  def _H : sve_int_perm_reverse_p<0b01, asm, PPR16, op_b16>;
1625  def _S : sve_int_perm_reverse_p<0b10, asm, PPR32, op_b32>;
1626  def _D : sve_int_perm_reverse_p<0b11, asm, PPR64, op_b64>;
1627
1628  def : SVE_1_Op_Pat<nxv8i1, ir_op, nxv8i1, !cast<Instruction>(NAME # _H)>;
1629  def : SVE_1_Op_Pat<nxv4i1, ir_op, nxv4i1, !cast<Instruction>(NAME # _S)>;
1630  def : SVE_1_Op_Pat<nxv2i1, ir_op, nxv2i1, !cast<Instruction>(NAME # _D)>;
1631}
1632
1633class sve_int_perm_unpk<bits<2> sz16_64, bits<2> opc, string asm,
1634                        ZPRRegOp zprty1, ZPRRegOp zprty2>
1635: I<(outs zprty1:$Zd), (ins zprty2:$Zn),
1636  asm, "\t$Zd, $Zn",
1637  "", []>, Sched<[]> {
1638  bits<5> Zd;
1639  bits<5> Zn;
1640  let Inst{31-24} = 0b00000101;
1641  let Inst{23-22} = sz16_64;
1642  let Inst{21-18} = 0b1100;
1643  let Inst{17-16} = opc;
1644  let Inst{15-10} = 0b001110;
1645  let Inst{9-5}   = Zn;
1646  let Inst{4-0}   = Zd;
1647
1648  let hasSideEffects = 0;
1649}
1650
1651multiclass sve_int_perm_unpk<bits<2> opc, string asm, SDPatternOperator op> {
1652  def _H : sve_int_perm_unpk<0b01, opc, asm, ZPR16, ZPR8>;
1653  def _S : sve_int_perm_unpk<0b10, opc, asm, ZPR32, ZPR16>;
1654  def _D : sve_int_perm_unpk<0b11, opc, asm, ZPR64, ZPR32>;
1655
1656  def : SVE_1_Op_Pat<nxv8i16, op, nxv16i8, !cast<Instruction>(NAME # _H)>;
1657  def : SVE_1_Op_Pat<nxv4i32, op, nxv8i16, !cast<Instruction>(NAME # _S)>;
1658  def : SVE_1_Op_Pat<nxv2i64, op, nxv4i32, !cast<Instruction>(NAME # _D)>;
1659}
1660
1661class sve_int_perm_insrs<bits<2> sz8_64, string asm, ZPRRegOp zprty,
1662                         RegisterClass srcRegType>
1663: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, srcRegType:$Rm),
1664  asm, "\t$Zdn, $Rm",
1665  "",
1666  []>, Sched<[]> {
1667  bits<5> Rm;
1668  bits<5> Zdn;
1669  let Inst{31-24} = 0b00000101;
1670  let Inst{23-22} = sz8_64;
1671  let Inst{21-10} = 0b100100001110;
1672  let Inst{9-5}   = Rm;
1673  let Inst{4-0}   = Zdn;
1674
1675  let Constraints = "$Zdn = $_Zdn";
1676  let DestructiveInstType = DestructiveOther;
1677  let hasSideEffects = 0;
1678}
1679
1680multiclass sve_int_perm_insrs<string asm, SDPatternOperator op> {
1681  def _B : sve_int_perm_insrs<0b00, asm, ZPR8, GPR32>;
1682  def _H : sve_int_perm_insrs<0b01, asm, ZPR16, GPR32>;
1683  def _S : sve_int_perm_insrs<0b10, asm, ZPR32, GPR32>;
1684  def _D : sve_int_perm_insrs<0b11, asm, ZPR64, GPR64>;
1685
1686  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, i32, !cast<Instruction>(NAME # _B)>;
1687  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, i32, !cast<Instruction>(NAME # _H)>;
1688  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, i32, !cast<Instruction>(NAME # _S)>;
1689  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, i64, !cast<Instruction>(NAME # _D)>;
1690}
1691
1692class sve_int_perm_insrv<bits<2> sz8_64, string asm, ZPRRegOp zprty,
1693                         FPRasZPROperand srcOpType>
1694: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, srcOpType:$Vm),
1695  asm, "\t$Zdn, $Vm",
1696  "",
1697  []>, Sched<[]> {
1698  bits<5> Vm;
1699  bits<5> Zdn;
1700  let Inst{31-24} = 0b00000101;
1701  let Inst{23-22} = sz8_64;
1702  let Inst{21-10} = 0b110100001110;
1703  let Inst{9-5}   = Vm;
1704  let Inst{4-0}   = Zdn;
1705
1706  let Constraints = "$Zdn = $_Zdn";
1707  let DestructiveInstType = DestructiveOther;
1708  let hasSideEffects = 0;
1709}
1710
1711multiclass sve_int_perm_insrv<string asm, SDPatternOperator op> {
1712  def _B : sve_int_perm_insrv<0b00, asm, ZPR8, FPR8asZPR>;
1713  def _H : sve_int_perm_insrv<0b01, asm, ZPR16, FPR16asZPR>;
1714  def _S : sve_int_perm_insrv<0b10, asm, ZPR32, FPR32asZPR>;
1715  def _D : sve_int_perm_insrv<0b11, asm, ZPR64, FPR64asZPR>;
1716
1717  def : Pat<(nxv8f16 (op nxv8f16:$Zn, f16:$Vm)),
1718            (!cast<Instruction>(NAME # _H) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, hsub))>;
1719  def : Pat<(nxv4f32 (op nxv4f32:$Zn, f32:$Vm)),
1720            (!cast<Instruction>(NAME # _S) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, ssub))>;
1721  def : Pat<(nxv2f64 (op nxv2f64:$Zn, f64:$Vm)),
1722            (!cast<Instruction>(NAME # _D) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, dsub))>;
1723
1724  def : Pat<(nxv8bf16 (op nxv8bf16:$Zn, bf16:$Vm)),
1725            (!cast<Instruction>(NAME # _H) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, hsub))>;
1726
1727  // Keep integer insertions within the vector unit.
1728  def : Pat<(nxv16i8 (op (nxv16i8 ZPR:$Zn), (i32 (vector_extract (nxv16i8 ZPR:$Vm), 0)))),
1729            (!cast<Instruction>(NAME # _B) $Zn, ZPR:$Vm)>;
1730  def : Pat<(nxv8i16 (op (nxv8i16 ZPR:$Zn), (i32 (vector_extract (nxv8i16 ZPR:$Vm), 0)))),
1731            (!cast<Instruction>(NAME # _H) $Zn, ZPR:$Vm)>;
1732  def : Pat<(nxv4i32 (op (nxv4i32 ZPR:$Zn), (i32 (vector_extract (nxv4i32 ZPR:$Vm), 0)))),
1733            (!cast<Instruction>(NAME # _S) $Zn, ZPR: $Vm)>;
1734  def : Pat<(nxv2i64 (op (nxv2i64 ZPR:$Zn), (i64 (vector_extract (nxv2i64 ZPR:$Vm), 0)))),
1735            (!cast<Instruction>(NAME # _D) $Zn, ZPR:$Vm)>;
1736
1737}
1738
1739//===----------------------------------------------------------------------===//
1740// SVE Permute - Extract Group
1741//===----------------------------------------------------------------------===//
1742
1743class sve_int_perm_extract_i<string asm>
1744: I<(outs ZPR8:$Zdn), (ins ZPR8:$_Zdn, ZPR8:$Zm, imm0_255:$imm8),
1745  asm, "\t$Zdn, $_Zdn, $Zm, $imm8",
1746  "", []>, Sched<[]> {
1747  bits<5> Zdn;
1748  bits<5> Zm;
1749  bits<8> imm8;
1750  let Inst{31-21} = 0b00000101001;
1751  let Inst{20-16} = imm8{7-3};
1752  let Inst{15-13} = 0b000;
1753  let Inst{12-10} = imm8{2-0};
1754  let Inst{9-5}   = Zm;
1755  let Inst{4-0}   = Zdn;
1756
1757  let Constraints = "$Zdn = $_Zdn";
1758  let DestructiveInstType = DestructiveOther;
1759  let ElementSize = ElementSizeNone;
1760  let hasSideEffects = 0;
1761}
1762
1763multiclass sve_int_perm_extract_i<string asm, SDPatternOperator op> {
1764  def NAME : sve_int_perm_extract_i<asm>;
1765
1766  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, imm0_255,
1767                         !cast<Instruction>(NAME)>;
1768}
1769
1770class sve2_int_perm_extract_i_cons<string asm>
1771: I<(outs ZPR8:$Zd), (ins ZZ_b:$Zn, imm0_255:$imm8),
1772  asm, "\t$Zd, $Zn, $imm8",
1773  "", []>, Sched<[]> {
1774  bits<5> Zd;
1775  bits<5> Zn;
1776  bits<8> imm8;
1777  let Inst{31-21} = 0b00000101011;
1778  let Inst{20-16} = imm8{7-3};
1779  let Inst{15-13} = 0b000;
1780  let Inst{12-10} = imm8{2-0};
1781  let Inst{9-5}   = Zn;
1782  let Inst{4-0}   = Zd;
1783
1784  let hasSideEffects = 0;
1785}
1786
1787//===----------------------------------------------------------------------===//
1788// SVE Vector Select Group
1789//===----------------------------------------------------------------------===//
1790
1791class sve_int_sel_vvv<bits<2> sz8_64, string asm, ZPRRegOp zprty>
1792: I<(outs zprty:$Zd), (ins PPRAny:$Pg, zprty:$Zn, zprty:$Zm),
1793  asm, "\t$Zd, $Pg, $Zn, $Zm",
1794  "",
1795  []>, Sched<[]> {
1796  bits<4> Pg;
1797  bits<5> Zd;
1798  bits<5> Zm;
1799  bits<5> Zn;
1800  let Inst{31-24} = 0b00000101;
1801  let Inst{23-22} = sz8_64;
1802  let Inst{21}    = 0b1;
1803  let Inst{20-16} = Zm;
1804  let Inst{15-14} = 0b11;
1805  let Inst{13-10} = Pg;
1806  let Inst{9-5}   = Zn;
1807  let Inst{4-0}   = Zd;
1808
1809  let hasSideEffects = 0;
1810}
1811
1812multiclass sve_int_sel_vvv<string asm, SDPatternOperator op> {
1813  def _B : sve_int_sel_vvv<0b00, asm, ZPR8>;
1814  def _H : sve_int_sel_vvv<0b01, asm, ZPR16>;
1815  def _S : sve_int_sel_vvv<0b10, asm, ZPR32>;
1816  def _D : sve_int_sel_vvv<0b11, asm, ZPR64>;
1817
1818  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
1819  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1820  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1821  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1822
1823  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1,  nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
1824  def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1,  nxv4f16, nxv4f16, !cast<Instruction>(NAME # _S)>;
1825  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1,  nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
1826  def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1,  nxv2f16, nxv2f16, !cast<Instruction>(NAME # _D)>;
1827  def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1,  nxv2f32, nxv2f32, !cast<Instruction>(NAME # _D)>;
1828  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1,  nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
1829
1830  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1,  nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
1831
1832  def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1833                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPRAny:$Pg, ZPR8:$Zn, ZPR8:$Zd), 1>;
1834  def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1835                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, ZPR16:$Zn, ZPR16:$Zd), 1>;
1836  def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1837                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, ZPR32:$Zn, ZPR32:$Zd), 1>;
1838  def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1839                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, ZPR64:$Zn, ZPR64:$Zd), 1>;
1840}
1841
1842
1843//===----------------------------------------------------------------------===//
1844// SVE Predicate Logical Operations Group
1845//===----------------------------------------------------------------------===//
1846
1847class sve_int_pred_log<bits<4> opc, string asm>
1848: I<(outs PPR8:$Pd), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$Pm),
1849  asm, "\t$Pd, $Pg/z, $Pn, $Pm",
1850  "",
1851  []>, Sched<[]> {
1852  bits<4> Pd;
1853  bits<4> Pg;
1854  bits<4> Pm;
1855  bits<4> Pn;
1856  let Inst{31-24} = 0b00100101;
1857  let Inst{23-22} = opc{3-2};
1858  let Inst{21-20} = 0b00;
1859  let Inst{19-16} = Pm;
1860  let Inst{15-14} = 0b01;
1861  let Inst{13-10} = Pg;
1862  let Inst{9}     = opc{1};
1863  let Inst{8-5}   = Pn;
1864  let Inst{4}     = opc{0};
1865  let Inst{3-0}   = Pd;
1866
1867  // SEL has no predication qualifier.
1868  let AsmString = !if(!eq(opc, 0b0011),
1869                      !strconcat(asm, "\t$Pd, $Pg, $Pn, $Pm"),
1870                      !strconcat(asm, "\t$Pd, $Pg/z, $Pn, $Pm"));
1871
1872  let Defs = !if(!eq (opc{2}, 1), [NZCV], []);
1873  let hasSideEffects = 0;
1874}
1875
1876multiclass sve_int_pred_log<bits<4> opc, string asm, SDPatternOperator op,
1877                            SDPatternOperator op_nopred = null_frag> {
1878  def NAME : sve_int_pred_log<opc, asm>;
1879
1880  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
1881  def : SVE_3_Op_Pat<nxv8i1, op, nxv8i1, nxv8i1, nxv8i1, !cast<Instruction>(NAME)>;
1882  def : SVE_3_Op_Pat<nxv4i1, op, nxv4i1, nxv4i1, nxv4i1, !cast<Instruction>(NAME)>;
1883  def : SVE_3_Op_Pat<nxv2i1, op, nxv2i1, nxv2i1, nxv2i1, !cast<Instruction>(NAME)>;
1884  def : SVE_3_Op_Pat<nxv1i1, op, nxv1i1, nxv1i1, nxv1i1, !cast<Instruction>(NAME)>;
1885  def : SVE_2_Op_AllActive_Pat<nxv16i1, op_nopred, nxv16i1, nxv16i1,
1886                               !cast<Instruction>(NAME), PTRUE_B>;
1887  def : SVE_2_Op_AllActive_Pat<nxv8i1, op_nopred, nxv8i1, nxv8i1,
1888                               !cast<Instruction>(NAME), PTRUE_H>;
1889  def : SVE_2_Op_AllActive_Pat<nxv4i1, op_nopred, nxv4i1, nxv4i1,
1890                               !cast<Instruction>(NAME), PTRUE_S>;
1891  def : SVE_2_Op_AllActive_Pat<nxv2i1, op_nopred, nxv2i1, nxv2i1,
1892                               !cast<Instruction>(NAME), PTRUE_D>;
1893  // Emulate .Q operation using a PTRUE_D when the other lanes don't matter.
1894  def : SVE_2_Op_AllActive_Pat<nxv1i1, op_nopred, nxv1i1, nxv1i1,
1895                               !cast<Instruction>(NAME), PTRUE_D>;
1896}
1897
1898// An instance of sve_int_pred_log_and but uses op_nopred's first operand as the
1899// general predicate.
1900multiclass sve_int_pred_log_v2<bits<4> opc, string asm, SDPatternOperator op,
1901                               SDPatternOperator op_nopred> :
1902  sve_int_pred_log<opc, asm, op> {
1903  def : Pat<(nxv16i1 (op_nopred nxv16i1:$Op1, nxv16i1:$Op2)),
1904            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1905  def : Pat<(nxv8i1 (op_nopred nxv8i1:$Op1, nxv8i1:$Op2)),
1906            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1907  def : Pat<(nxv4i1 (op_nopred nxv4i1:$Op1, nxv4i1:$Op2)),
1908            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1909  def : Pat<(nxv2i1 (op_nopred nxv2i1:$Op1, nxv2i1:$Op2)),
1910            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1911  // Emulate .Q operation using a PTRUE_D when the other lanes don't matter.
1912  def : Pat<(nxv1i1 (op_nopred nxv1i1:$Op1, nxv1i1:$Op2)),
1913            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1914}
1915
1916//===----------------------------------------------------------------------===//
1917// SVE Logical Mask Immediate Group
1918//===----------------------------------------------------------------------===//
1919
1920class sve_int_log_imm<bits<2> opc, string asm>
1921: I<(outs ZPR64:$Zdn), (ins ZPR64:$_Zdn, logical_imm64:$imms13),
1922  asm, "\t$Zdn, $_Zdn, $imms13",
1923  "", []>, Sched<[]> {
1924  bits<5> Zdn;
1925  bits<13> imms13;
1926  let Inst{31-24} = 0b00000101;
1927  let Inst{23-22} = opc;
1928  let Inst{21-18} = 0b0000;
1929  let Inst{17-5}  = imms13;
1930  let Inst{4-0}   = Zdn;
1931
1932  let Constraints = "$Zdn = $_Zdn";
1933  let DecoderMethod = "DecodeSVELogicalImmInstruction";
1934  let DestructiveInstType = DestructiveOther;
1935  let ElementSize = ElementSizeNone;
1936  let hasSideEffects = 0;
1937}
1938
1939multiclass sve_int_log_imm<bits<2> opc, string asm, string alias, SDPatternOperator op> {
1940  def NAME : sve_int_log_imm<opc, asm>;
1941
1942  def : SVE_1_Op_Imm_Log_Pat<nxv16i8, op, ZPR8,  i32, SVELogicalImm8Pat,  !cast<Instruction>(NAME)>;
1943  def : SVE_1_Op_Imm_Log_Pat<nxv8i16, op, ZPR16, i32, SVELogicalImm16Pat, !cast<Instruction>(NAME)>;
1944  def : SVE_1_Op_Imm_Log_Pat<nxv4i32, op, ZPR32, i32, SVELogicalImm32Pat, !cast<Instruction>(NAME)>;
1945  def : SVE_1_Op_Imm_Log_Pat<nxv2i64, op, ZPR64, i64, SVELogicalImm64Pat, !cast<Instruction>(NAME)>;
1946
1947  def : InstAlias<asm # "\t$Zdn, $Zdn, $imm",
1948                  (!cast<Instruction>(NAME) ZPR8:$Zdn, sve_logical_imm8:$imm), 4>;
1949  def : InstAlias<asm # "\t$Zdn, $Zdn, $imm",
1950                  (!cast<Instruction>(NAME) ZPR16:$Zdn, sve_logical_imm16:$imm), 3>;
1951  def : InstAlias<asm # "\t$Zdn, $Zdn, $imm",
1952                  (!cast<Instruction>(NAME) ZPR32:$Zdn, sve_logical_imm32:$imm), 2>;
1953
1954  def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
1955                  (!cast<Instruction>(NAME) ZPR8:$Zdn, sve_logical_imm8_not:$imm), 0>;
1956  def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
1957                  (!cast<Instruction>(NAME) ZPR16:$Zdn, sve_logical_imm16_not:$imm), 0>;
1958  def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
1959                  (!cast<Instruction>(NAME) ZPR32:$Zdn, sve_logical_imm32_not:$imm), 0>;
1960  def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
1961                  (!cast<Instruction>(NAME) ZPR64:$Zdn, logical_imm64_not:$imm), 0>;
1962}
1963
1964multiclass sve_int_log_imm_bic<SDPatternOperator op> {
1965  def : SVE_1_Op_Imm_Log_Pat<nxv16i8, op, ZPR8,  i32, SVELogicalImm8NotPat,  !cast<Instruction>("AND_ZI")>;
1966  def : SVE_1_Op_Imm_Log_Pat<nxv8i16, op, ZPR16, i32, SVELogicalImm16NotPat, !cast<Instruction>("AND_ZI")>;
1967  def : SVE_1_Op_Imm_Log_Pat<nxv4i32, op, ZPR32, i32, SVELogicalImm32NotPat, !cast<Instruction>("AND_ZI")>;
1968  def : SVE_1_Op_Imm_Log_Pat<nxv2i64, op, ZPR64, i64, SVELogicalImm64NotPat, !cast<Instruction>("AND_ZI")>;
1969}
1970
1971class sve_int_dup_mask_imm<string asm>
1972: I<(outs ZPR64:$Zd), (ins logical_imm64:$imms),
1973  asm, "\t$Zd, $imms",
1974  "",
1975  []>, Sched<[]> {
1976  bits<5> Zd;
1977  bits<13> imms;
1978  let Inst{31-18} = 0b00000101110000;
1979  let Inst{17-5} = imms;
1980  let Inst{4-0} = Zd;
1981
1982  let DecoderMethod = "DecodeSVELogicalImmInstruction";
1983  let hasSideEffects = 0;
1984  let isReMaterializable = 1;
1985}
1986
1987multiclass sve_int_dup_mask_imm<string asm> {
1988  def NAME : sve_int_dup_mask_imm<asm>;
1989
1990  def : InstAlias<"dupm $Zd, $imm",
1991                  (!cast<Instruction>(NAME) ZPR8:$Zd, sve_logical_imm8:$imm), 4>;
1992  def : InstAlias<"dupm $Zd, $imm",
1993                  (!cast<Instruction>(NAME) ZPR16:$Zd, sve_logical_imm16:$imm), 3>;
1994  def : InstAlias<"dupm $Zd, $imm",
1995                  (!cast<Instruction>(NAME) ZPR32:$Zd, sve_logical_imm32:$imm), 2>;
1996
1997  // All Zd.b forms have a CPY/DUP equivalent, hence no byte alias here.
1998  def : InstAlias<"mov $Zd, $imm",
1999                  (!cast<Instruction>(NAME) ZPR16:$Zd, sve_preferred_logical_imm16:$imm), 7>;
2000  def : InstAlias<"mov $Zd, $imm",
2001                  (!cast<Instruction>(NAME) ZPR32:$Zd, sve_preferred_logical_imm32:$imm), 6>;
2002  def : InstAlias<"mov $Zd, $imm",
2003                  (!cast<Instruction>(NAME) ZPR64:$Zd, sve_preferred_logical_imm64:$imm), 5>;
2004
2005  // NOTE: No pattern for nxv16i8 because DUP has full coverage.
2006  def : Pat<(nxv8i16 (splat_vector (i32 (SVELogicalImm16Pat i64:$imm)))),
2007            (!cast<Instruction>(NAME) i64:$imm)>;
2008  def : Pat<(nxv4i32 (splat_vector (i32 (SVELogicalImm32Pat i64:$imm)))),
2009            (!cast<Instruction>(NAME) i64:$imm)>;
2010  def : Pat<(nxv2i64 (splat_vector (i64 (SVELogicalImm64Pat i64:$imm)))),
2011            (!cast<Instruction>(NAME) i64:$imm)>;
2012}
2013
2014//===----------------------------------------------------------------------===//
2015// SVE Integer Arithmetic -  Unpredicated Group.
2016//===----------------------------------------------------------------------===//
2017
2018class sve_int_bin_cons_arit_0<bits<2> sz8_64, bits<3> opc, string asm,
2019                              ZPRRegOp zprty>
2020: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
2021  asm, "\t$Zd, $Zn, $Zm",
2022  "", []>, Sched<[]> {
2023  bits<5> Zd;
2024  bits<5> Zm;
2025  bits<5> Zn;
2026  let Inst{31-24} = 0b00000100;
2027  let Inst{23-22} = sz8_64;
2028  let Inst{21}    = 0b1;
2029  let Inst{20-16} = Zm;
2030  let Inst{15-13} = 0b000;
2031  let Inst{12-10} = opc;
2032  let Inst{9-5}   = Zn;
2033  let Inst{4-0}   = Zd;
2034
2035  let hasSideEffects = 0;
2036}
2037
2038multiclass sve_int_bin_cons_arit_0<bits<3> opc, string asm, SDPatternOperator op> {
2039  def _B : sve_int_bin_cons_arit_0<0b00, opc, asm, ZPR8>;
2040  def _H : sve_int_bin_cons_arit_0<0b01, opc, asm, ZPR16>;
2041  def _S : sve_int_bin_cons_arit_0<0b10, opc, asm, ZPR32>;
2042  def _D : sve_int_bin_cons_arit_0<0b11, opc, asm, ZPR64>;
2043
2044  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
2045  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2046  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2047  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2048}
2049
2050//===----------------------------------------------------------------------===//
2051// SVE Floating Point Arithmetic - Predicated Group
2052//===----------------------------------------------------------------------===//
2053
2054class sve_fp_2op_i_p_zds<bits<2> sz, bits<3> opc, string asm,
2055                         ZPRRegOp zprty,
2056                         Operand imm_ty>
2057: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, imm_ty:$i1),
2058  asm, "\t$Zdn, $Pg/m, $_Zdn, $i1",
2059  "",
2060  []>, Sched<[]> {
2061  bits<3> Pg;
2062  bits<5> Zdn;
2063  bit i1;
2064  let Inst{31-24} = 0b01100101;
2065  let Inst{23-22} = sz;
2066  let Inst{21-19} = 0b011;
2067  let Inst{18-16} = opc;
2068  let Inst{15-13} = 0b100;
2069  let Inst{12-10} = Pg;
2070  let Inst{9-6}   = 0b0000;
2071  let Inst{5}     = i1;
2072  let Inst{4-0}   = Zdn;
2073
2074  let Constraints = "$Zdn = $_Zdn";
2075  let DestructiveInstType = DestructiveOther;
2076  let ElementSize = zprty.ElementSize;
2077  let hasSideEffects = 0;
2078  let mayRaiseFPException = 1;
2079}
2080
2081multiclass sve_fp_2op_i_p_zds<bits<3> opc, string asm, string Ps, Operand imm_ty, FPImmLeaf A, FPImmLeaf B, SDPatternOperator op> {
2082  let DestructiveInstType = DestructiveBinaryImm in {
2083  def _H : SVEPseudo2Instr<Ps # _H, 1>, sve_fp_2op_i_p_zds<0b01, opc, asm, ZPR16, imm_ty>;
2084  def _S : SVEPseudo2Instr<Ps # _S, 1>, sve_fp_2op_i_p_zds<0b10, opc, asm, ZPR32, imm_ty>;
2085  def _D : SVEPseudo2Instr<Ps # _D, 1>, sve_fp_2op_i_p_zds<0b11, opc, asm, ZPR64, imm_ty>;
2086  }
2087
2088  def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, op, nxv8i1, f16, A, 0, !cast<Instruction>(NAME # "_H")>;
2089  def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, op, nxv8i1, f16, B, 1, !cast<Instruction>(NAME # "_H")>;
2090  def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, op, nxv4i1, f32, A, 0, !cast<Instruction>(NAME # "_S")>;
2091  def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, op, nxv4i1, f32, B, 1, !cast<Instruction>(NAME # "_S")>;
2092  def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, op, nxv2i1, f64, A, 0, !cast<Instruction>(NAME # "_D")>;
2093  def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, op, nxv2i1, f64, B, 1, !cast<Instruction>(NAME # "_D")>;
2094}
2095
2096class sve_fp_2op_p_zds<bits<2> sz, bits<4> opc, string asm,
2097                       ZPRRegOp zprty>
2098: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
2099  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
2100  "",
2101  []>, Sched<[]> {
2102  bits<3> Pg;
2103  bits<5> Zdn;
2104  bits<5> Zm;
2105  let Inst{31-24} = 0b01100101;
2106  let Inst{23-22} = sz;
2107  let Inst{21-20} = 0b00;
2108  let Inst{19-16} = opc;
2109  let Inst{15-13} = 0b100;
2110  let Inst{12-10} = Pg;
2111  let Inst{9-5}   = Zm;
2112  let Inst{4-0}   = Zdn;
2113
2114  let Constraints = "$Zdn = $_Zdn";
2115  let DestructiveInstType = DestructiveOther;
2116  let ElementSize = zprty.ElementSize;
2117  let hasSideEffects = 0;
2118  let mayRaiseFPException = 1;
2119}
2120
2121multiclass sve2p1_bf_2op_p_zds<bits<4> opc, string asm, string Ps,
2122                            SDPatternOperator op, DestructiveInstTypeEnum flags,
2123                            string revname="", bit isReverseInstr=0> {
2124let DestructiveInstType = flags in {
2125  def NAME : sve_fp_2op_p_zds<0b00, opc, asm, ZPR16>,
2126           SVEPseudo2Instr<Ps, 1>, SVEInstr2Rev<NAME , revname , isReverseInstr>;
2127  }
2128
2129  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
2130}
2131
2132multiclass sve2p1_bf_bin_pred_zds<SDPatternOperator op> {
2133  def _UNDEF : PredTwoOpPseudo<NAME, ZPR16, FalseLanesUndef>;
2134
2135  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1,  nxv8bf16, nxv8bf16, !cast<Pseudo>(NAME # _UNDEF)>;
2136}
2137
2138multiclass sve2p1_bf_2op_p_zds_zeroing<SDPatternOperator op> {
2139  def _ZERO : PredTwoOpPseudo<NAME, ZPR16, FalseLanesZero>;
2140
2141  def : SVE_3_Op_Pat_SelZero<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Pseudo>(NAME # _ZERO)>;
2142}
2143
2144multiclass sve_fp_2op_p_zds<bits<4> opc, string asm, string Ps,
2145                            SDPatternOperator op, DestructiveInstTypeEnum flags,
2146                            string revname="", bit isReverseInstr=0> {
2147  let DestructiveInstType = flags in {
2148  def _H : sve_fp_2op_p_zds<0b01, opc, asm, ZPR16>,
2149           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2150  def _S : sve_fp_2op_p_zds<0b10, opc, asm, ZPR32>,
2151           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2152  def _D : sve_fp_2op_p_zds<0b11, opc, asm, ZPR64>,
2153           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2154  }
2155
2156  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2157  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2158  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2159}
2160
2161multiclass sve_fp_2op_p_zds_fscale<bits<4> opc, string asm,
2162                                   SDPatternOperator op> {
2163  def _H : sve_fp_2op_p_zds<0b01, opc, asm, ZPR16>;
2164  def _S : sve_fp_2op_p_zds<0b10, opc, asm, ZPR32>;
2165  def _D : sve_fp_2op_p_zds<0b11, opc, asm, ZPR64>;
2166
2167  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2168  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2169  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2170}
2171
2172multiclass sve_fp_2op_p_zds_zeroing_hsd<SDPatternOperator op> {
2173  def _H_ZERO : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesZero>;
2174  def _S_ZERO : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesZero>;
2175  def _D_ZERO : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesZero>;
2176
2177  def : SVE_3_Op_Pat_SelZero<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Pseudo>(NAME # _H_ZERO)>;
2178  def : SVE_3_Op_Pat_SelZero<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Pseudo>(NAME # _S_ZERO)>;
2179  def : SVE_3_Op_Pat_SelZero<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Pseudo>(NAME # _D_ZERO)>;
2180}
2181
2182class sve_fp_ftmad<bits<2> sz, string asm, ZPRRegOp zprty>
2183: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, timm32_0_7:$imm3),
2184  asm, "\t$Zdn, $_Zdn, $Zm, $imm3",
2185  "",
2186  []>, Sched<[]> {
2187  bits<5> Zdn;
2188  bits<5> Zm;
2189  bits<3> imm3;
2190  let Inst{31-24} = 0b01100101;
2191  let Inst{23-22} = sz;
2192  let Inst{21-19} = 0b010;
2193  let Inst{18-16} = imm3;
2194  let Inst{15-10} = 0b100000;
2195  let Inst{9-5}   = Zm;
2196  let Inst{4-0}   = Zdn;
2197
2198  let Constraints = "$Zdn = $_Zdn";
2199  let DestructiveInstType = DestructiveOther;
2200  let ElementSize = ElementSizeNone;
2201  let hasSideEffects = 0;
2202  let mayRaiseFPException = 1;
2203}
2204
2205multiclass sve_fp_ftmad<string asm, SDPatternOperator op> {
2206  def _H : sve_fp_ftmad<0b01, asm, ZPR16>;
2207  def _S : sve_fp_ftmad<0b10, asm, ZPR32>;
2208  def _D : sve_fp_ftmad<0b11, asm, ZPR64>;
2209
2210  def : Pat<(nxv8f16 (op (nxv8f16 ZPR16:$Zn), (nxv8f16 ZPR16:$Zm), (i32 timm32_0_7:$imm))),
2211            (!cast<Instruction>(NAME # _H) ZPR16:$Zn, ZPR16:$Zm, timm32_0_7:$imm)>;
2212  def : Pat<(nxv4f32 (op (nxv4f32 ZPR32:$Zn), (nxv4f32 ZPR32:$Zm), (i32 timm32_0_7:$imm))),
2213            (!cast<Instruction>(NAME # _S) ZPR32:$Zn, ZPR32:$Zm, timm32_0_7:$imm)>;
2214  def : Pat<(nxv2f64 (op (nxv2f64 ZPR64:$Zn), (nxv2f64 ZPR64:$Zm), (i32 timm32_0_7:$imm))),
2215            (!cast<Instruction>(NAME # _D) ZPR64:$Zn, ZPR64:$Zm, timm32_0_7:$imm)>;
2216}
2217
2218multiclass sve_fp_2op_i_p_zds_hfd<Operand imm_ty, FPImmLeaf A, FPImmLeaf B, SDPatternOperator ir_op = null_frag> {
2219  def _H_UNDEF : PredTwoOpImmPseudo<NAME # _H, ZPR16, imm_ty, FalseLanesUndef>;
2220  def _S_UNDEF : PredTwoOpImmPseudo<NAME # _S, ZPR32, imm_ty, FalseLanesUndef>;
2221  def _D_UNDEF : PredTwoOpImmPseudo<NAME # _D, ZPR64, imm_ty, FalseLanesUndef>;
2222
2223  def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, ir_op, nxv8i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2224  def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, ir_op, nxv8i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2225  def : SVE_2_Op_Fp_Imm_Pat<nxv4f16, ir_op, nxv4i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2226  def : SVE_2_Op_Fp_Imm_Pat<nxv4f16, ir_op, nxv4i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2227  def : SVE_2_Op_Fp_Imm_Pat<nxv2f16, ir_op, nxv2i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2228  def : SVE_2_Op_Fp_Imm_Pat<nxv2f16, ir_op, nxv2i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2229  def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, ir_op, nxv4i1, f32, A, 0, !cast<Instruction>(NAME # "_S_UNDEF")>;
2230  def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, ir_op, nxv4i1, f32, B, 1, !cast<Instruction>(NAME # "_S_UNDEF")>;
2231  def : SVE_2_Op_Fp_Imm_Pat<nxv2f32, ir_op, nxv2i1, f32, A, 0, !cast<Instruction>(NAME # "_S_UNDEF")>;
2232  def : SVE_2_Op_Fp_Imm_Pat<nxv2f32, ir_op, nxv2i1, f32, B, 1, !cast<Instruction>(NAME # "_S_UNDEF")>;
2233  def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, ir_op, nxv2i1, f64, A, 0, !cast<Instruction>(NAME # "_D_UNDEF")>;
2234  def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, ir_op, nxv2i1, f64, B, 1, !cast<Instruction>(NAME # "_D_UNDEF")>;
2235}
2236
2237multiclass sve_fp_2op_i_p_zds_zeroing_hfd<Operand imm_ty, FPImmLeaf A, FPImmLeaf B, SDPatternOperator op> {
2238  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, imm_ty, FalseLanesZero>;
2239  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, imm_ty, FalseLanesZero>;
2240  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, imm_ty, FalseLanesZero>;
2241
2242  let AddedComplexity = 2 in {
2243    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv8f16, op, nxv8i1, f16, A, 0, !cast<Instruction>(NAME # "_H_ZERO")>;
2244    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv8f16, op, nxv8i1, f16, B, 1, !cast<Instruction>(NAME # "_H_ZERO")>;
2245    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv4f32, op, nxv4i1, f32, A, 0, !cast<Instruction>(NAME # "_S_ZERO")>;
2246    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv4f32, op, nxv4i1, f32, B, 1, !cast<Instruction>(NAME # "_S_ZERO")>;
2247    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv2f64, op, nxv2i1, f64, A, 0, !cast<Instruction>(NAME # "_D_ZERO")>;
2248    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv2f64, op, nxv2i1, f64, B, 1, !cast<Instruction>(NAME # "_D_ZERO")>;
2249  }
2250}
2251
2252//===----------------------------------------------------------------------===//
2253// SVE Floating Point Arithmetic - Unpredicated Group
2254//===----------------------------------------------------------------------===//
2255
2256class sve_fp_3op_u_zd<bits<2> sz, bits<3> opc, string asm, ZPRRegOp zprty>
2257: I<(outs zprty:$Zd), (ins  zprty:$Zn, zprty:$Zm),
2258  asm, "\t$Zd, $Zn, $Zm",
2259  "",
2260  []>, Sched<[]> {
2261  bits<5> Zd;
2262  bits<5> Zm;
2263  bits<5> Zn;
2264  let Inst{31-24} = 0b01100101;
2265  let Inst{23-22} = sz;
2266  let Inst{21}    = 0b0;
2267  let Inst{20-16} = Zm;
2268  let Inst{15-13} = 0b000;
2269  let Inst{12-10} = opc;
2270  let Inst{9-5}   = Zn;
2271  let Inst{4-0}   = Zd;
2272
2273  let hasSideEffects = 0;
2274  let mayRaiseFPException = 1;
2275}
2276
2277multiclass sve_fp_3op_u_zd<bits<3> opc, string asm, SDPatternOperator op,
2278                           SDPatternOperator predicated_op = null_frag> {
2279  def _H : sve_fp_3op_u_zd<0b01, opc, asm, ZPR16>;
2280  def _S : sve_fp_3op_u_zd<0b10, opc, asm, ZPR32>;
2281  def _D : sve_fp_3op_u_zd<0b11, opc, asm, ZPR64>;
2282
2283  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2284  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2285  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2286
2287  def : SVE_2_Op_Pred_All_Active<nxv8f16, predicated_op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2288  def : SVE_2_Op_Pred_All_Active<nxv4f32, predicated_op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2289  def : SVE_2_Op_Pred_All_Active<nxv2f64, predicated_op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2290}
2291
2292multiclass sve2p1_bf_3op_u_zd<bits<3> opc1, string asm, SDPatternOperator op,
2293                          SDPatternOperator predicated_op = null_frag> {
2294  def NAME : sve_fp_3op_u_zd<0b00, opc1, asm, ZPR16>;
2295  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
2296
2297  def : SVE_2_Op_Pred_All_Active<nxv8bf16, predicated_op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
2298}
2299
2300multiclass sve_fp_3op_u_zd_ftsmul<bits<3> opc, string asm, SDPatternOperator op> {
2301  def _H : sve_fp_3op_u_zd<0b01, opc, asm, ZPR16>;
2302  def _S : sve_fp_3op_u_zd<0b10, opc, asm, ZPR32>;
2303  def _D : sve_fp_3op_u_zd<0b11, opc, asm, ZPR64>;
2304
2305  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2306  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2307  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2308}
2309
2310//===----------------------------------------------------------------------===//
2311// SVE Floating Point Fused Multiply-Add Group
2312//===----------------------------------------------------------------------===//
2313
2314class sve_fp_3op_p_zds_a<bits<2> sz, bits<2> opc, string asm, ZPRRegOp zprty>
2315: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm),
2316  asm, "\t$Zda, $Pg/m, $Zn, $Zm",
2317  "",
2318  []>, Sched<[]> {
2319  bits<3> Pg;
2320  bits<5> Zda;
2321  bits<5> Zm;
2322  bits<5> Zn;
2323  let Inst{31-24} = 0b01100101;
2324  let Inst{23-22} = sz;
2325  let Inst{21}    = 0b1;
2326  let Inst{20-16} = Zm;
2327  let Inst{15}    = 0b0;
2328  let Inst{14-13} = opc;
2329  let Inst{12-10} = Pg;
2330  let Inst{9-5}   = Zn;
2331  let Inst{4-0}   = Zda;
2332
2333  let Constraints = "$Zda = $_Zda";
2334  let ElementSize = zprty.ElementSize;
2335  let DestructiveInstType = DestructiveTernaryCommWithRev;
2336  let hasSideEffects = 0;
2337  let mayRaiseFPException = 1;
2338}
2339
2340multiclass sve_fp_3op_p_zds_a<bits<2> opc, string asm, string Ps,
2341                              SDPatternOperator op, string revname,
2342                              bit isReverseInstr=0> {
2343  def _H : sve_fp_3op_p_zds_a<0b01, opc, asm, ZPR16>,
2344           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2345  def _S : sve_fp_3op_p_zds_a<0b10, opc, asm, ZPR32>,
2346           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2347  def _D : sve_fp_3op_p_zds_a<0b11, opc, asm, ZPR64>,
2348           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2349
2350  def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2351  def : SVE_4_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H)>;
2352  def : SVE_4_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H)>;
2353  def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2354  def : SVE_4_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S)>;
2355  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2356}
2357
2358multiclass sve_fp_3op_p_zds_a_bf<bits<2> opc, string asm, string Ps,
2359                              SDPatternOperator op> {
2360  def NAME : sve_fp_3op_p_zds_a<0b00, opc, asm, ZPR16>,
2361           SVEPseudo2Instr<Ps, 1>, SVEInstr2Rev<NAME, "", 0>;
2362
2363  def : SVE_4_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
2364}
2365
2366class sve_fp_3op_p_zds_b<bits<2> sz, bits<2> opc, string asm,
2367                         ZPRRegOp zprty>
2368: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm, zprty:$Za),
2369  asm, "\t$Zdn, $Pg/m, $Zm, $Za",
2370  "",
2371  []>, Sched<[]> {
2372  bits<3> Pg;
2373  bits<5> Za;
2374  bits<5> Zdn;
2375  bits<5> Zm;
2376  let Inst{31-24} = 0b01100101;
2377  let Inst{23-22} = sz;
2378  let Inst{21}    = 0b1;
2379  let Inst{20-16} = Za;
2380  let Inst{15}    = 0b1;
2381  let Inst{14-13} = opc;
2382  let Inst{12-10} = Pg;
2383  let Inst{9-5}   = Zm;
2384  let Inst{4-0}   = Zdn;
2385
2386  let Constraints = "$Zdn = $_Zdn";
2387  let DestructiveInstType = DestructiveOther;
2388  let ElementSize = zprty.ElementSize;
2389  let hasSideEffects = 0;
2390  let mayRaiseFPException = 1;
2391}
2392
2393multiclass sve_fp_3op_p_zds_b<bits<2> opc, string asm, SDPatternOperator op,
2394                              string revname, bit isReverseInstr> {
2395  def _H : sve_fp_3op_p_zds_b<0b01, opc, asm, ZPR16>,
2396           SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2397  def _S : sve_fp_3op_p_zds_b<0b10, opc, asm, ZPR32>,
2398           SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2399  def _D : sve_fp_3op_p_zds_b<0b11, opc, asm, ZPR64>,
2400           SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2401
2402  def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2403  def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2404  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2405}
2406
2407//===----------------------------------------------------------------------===//
2408// SVE Floating Point Multiply-Add - Indexed Group
2409//===----------------------------------------------------------------------===//
2410
2411class sve_fp_fma_by_indexed_elem<bits<2> sz, bits<2> opc, string asm,
2412                                 ZPRRegOp zprty1,
2413                                 ZPRRegOp zprty2, Operand itype>
2414: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty1:$Zn, zprty2:$Zm, itype:$iop),
2415  asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
2416  bits<5> Zda;
2417  bits<5> Zn;
2418  let Inst{31-24} = 0b01100100;
2419  let Inst{23-22} = sz;
2420  let Inst{21}    = 0b1;
2421  let Inst{15-12} = 0b0000;
2422  let Inst{11-10} = opc;
2423  let Inst{9-5}   = Zn;
2424  let Inst{4-0}   = Zda;
2425
2426  let Constraints = "$Zda = $_Zda";
2427  let DestructiveInstType = DestructiveOther;
2428  let ElementSize = ElementSizeNone;
2429  let hasSideEffects = 0;
2430  let mayRaiseFPException = 1;
2431}
2432
2433multiclass sve2p1_fp_bfma_by_indexed_elem<string asm, bits<2> opc, SDPatternOperator op> {
2434  def NAME : sve_fp_fma_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR3b16,
2435                                         VectorIndexH32b> {
2436    bits<3> Zm;
2437    bits<3> iop;
2438    let Inst{22} = iop{2};
2439    let Inst{20-19} = iop{1-0};
2440    let Inst{18-16} = Zm;
2441  }
2442  def : Pat<(nxv8bf16 (op nxv8bf16:$op1, nxv8bf16:$op2, nxv8bf16:$op3, (i32 VectorIndexH32b_timm:$idx))),
2443            (!cast<Instruction>(NAME) $op1, $op2, $op3, VectorIndexH32b_timm:$idx)>;
2444}
2445
2446multiclass sve_fp_fma_by_indexed_elem<bits<2> opc, string asm,
2447                                      SDPatternOperator op> {
2448  def _H : sve_fp_fma_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2449    bits<3> Zm;
2450    bits<3> iop;
2451    let Inst{22} = iop{2};
2452    let Inst{20-19} = iop{1-0};
2453    let Inst{18-16} = Zm;
2454  }
2455  def _S : sve_fp_fma_by_indexed_elem<0b10, opc, asm, ZPR32, ZPR3b32, VectorIndexS32b> {
2456    bits<3> Zm;
2457    bits<2> iop;
2458    let Inst{20-19} = iop;
2459    let Inst{18-16} = Zm;
2460  }
2461  def _D : sve_fp_fma_by_indexed_elem<0b11, opc, asm, ZPR64, ZPR4b64, VectorIndexD32b> {
2462    bits<4> Zm;
2463    bit iop;
2464    let Inst{20} = iop;
2465    let Inst{19-16} = Zm;
2466  }
2467
2468  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 VectorIndexH32b_timm:$idx))),
2469            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, VectorIndexH32b_timm:$idx)>;
2470  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 VectorIndexS32b_timm:$idx))),
2471            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, VectorIndexS32b_timm:$idx)>;
2472  def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, (i32 VectorIndexD32b_timm:$idx))),
2473            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, VectorIndexD32b_timm:$idx)>;
2474}
2475
2476
2477//===----------------------------------------------------------------------===//
2478// SVE Floating Point Multiply - Indexed Group
2479//===----------------------------------------------------------------------===//
2480
2481class sve_fp_fmul_by_indexed_elem<bits<2> sz, bit o2, string asm, ZPRRegOp zprty,
2482                                  ZPRRegOp zprty2, Operand itype>
2483: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty2:$Zm, itype:$iop),
2484  asm, "\t$Zd, $Zn, $Zm$iop", "", []>, Sched<[]> {
2485  bits<5> Zd;
2486  bits<5> Zn;
2487  let Inst{31-24} = 0b01100100;
2488  let Inst{23-22} = sz;
2489  let Inst{21}    = 0b1;
2490  let Inst{15-12} = 0b0010;
2491  let Inst{11}    = o2;
2492  let Inst{10}    = 0b0;
2493  let Inst{9-5}   = Zn;
2494  let Inst{4-0}   = Zd;
2495
2496  let hasSideEffects = 0;
2497  let mayRaiseFPException = 1;
2498}
2499
2500multiclass sve2p1_fp_bfmul_by_indexed_elem<string asm, SDPatternOperator ir_intrinsic> {
2501  def NAME : sve_fp_fmul_by_indexed_elem<{0, ?}, 0b1, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2502    bits<3> Zm;
2503    bits<3> iop;
2504    let Inst{22} = iop{2};
2505    let Inst{20-19} = iop{1-0};
2506    let Inst{18-16} = Zm;
2507  }
2508  def : Pat <(nxv8bf16 (ir_intrinsic nxv8bf16:$Op1, nxv8bf16:$Op2, (i32 VectorIndexH32b_timm:$idx))),
2509             (!cast<Instruction>(NAME) $Op1, $Op2, VectorIndexH32b_timm:$idx)>;
2510}
2511
2512multiclass sve_fp_fmul_by_indexed_elem<string asm, SDPatternOperator op> {
2513  def _H : sve_fp_fmul_by_indexed_elem<{0, ?}, 0b0, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2514    bits<3> Zm;
2515    bits<3> iop;
2516    let Inst{22} = iop{2};
2517    let Inst{20-19} = iop{1-0};
2518    let Inst{18-16} = Zm;
2519  }
2520  def _S : sve_fp_fmul_by_indexed_elem<0b10, 0b0, asm, ZPR32, ZPR3b32, VectorIndexS32b> {
2521    bits<3> Zm;
2522    bits<2> iop;
2523    let Inst{20-19} = iop;
2524    let Inst{18-16} = Zm;
2525  }
2526  def _D : sve_fp_fmul_by_indexed_elem<0b11, 0b0, asm, ZPR64, ZPR4b64, VectorIndexD32b> {
2527    bits<4> Zm;
2528    bit iop;
2529    let Inst{20} = iop;
2530    let Inst{19-16} = Zm;
2531  }
2532
2533  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, (i32 VectorIndexH32b_timm:$idx))),
2534            (!cast<Instruction>(NAME # _H) $Op1, $Op2, VectorIndexH32b_timm:$idx)>;
2535  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, (i32 VectorIndexS32b_timm:$idx))),
2536            (!cast<Instruction>(NAME # _S) $Op1, $Op2, VectorIndexS32b_timm:$idx)>;
2537  def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, (i32 VectorIndexD32b_timm:$idx))),
2538            (!cast<Instruction>(NAME # _D) $Op1, $Op2, VectorIndexD32b_timm:$idx)>;
2539}
2540
2541//===----------------------------------------------------------------------===//
2542// SVE Floating Point Complex Multiply-Add Group
2543//===----------------------------------------------------------------------===//
2544
2545class sve_fp_fcmla<bits<2> sz, string asm, ZPRRegOp zprty>
2546: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm,
2547                        complexrotateop:$imm),
2548  asm, "\t$Zda, $Pg/m, $Zn, $Zm, $imm",
2549  "", []>, Sched<[]> {
2550  bits<5> Zda;
2551  bits<3> Pg;
2552  bits<5> Zn;
2553  bits<5> Zm;
2554  bits<2> imm;
2555  let Inst{31-24} = 0b01100100;
2556  let Inst{23-22} = sz;
2557  let Inst{21}    = 0;
2558  let Inst{20-16} = Zm;
2559  let Inst{15}    = 0;
2560  let Inst{14-13} = imm;
2561  let Inst{12-10} = Pg;
2562  let Inst{9-5}   = Zn;
2563  let Inst{4-0}   = Zda;
2564
2565  let Constraints = "$Zda = $_Zda";
2566  let DestructiveInstType = DestructiveOther;
2567  let ElementSize = zprty.ElementSize;
2568  let hasSideEffects = 0;
2569  let mayRaiseFPException = 1;
2570}
2571
2572multiclass sve_fp_fcmla<string asm, SDPatternOperator op> {
2573  def _H : sve_fp_fcmla<0b01, asm, ZPR16>;
2574  def _S : sve_fp_fcmla<0b10, asm, ZPR32>;
2575  def _D : sve_fp_fcmla<0b11, asm, ZPR64>;
2576
2577  def : Pat<(nxv8f16 (op nxv8i1:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, nxv8f16:$Op4, (i32 complexrotateop:$imm))),
2578            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2579  def : Pat<(nxv4f32 (op nxv4i1:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, nxv4f32:$Op4, (i32 complexrotateop:$imm))),
2580            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2581  def : Pat<(nxv2f64 (op nxv2i1:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, nxv2f64:$Op4, (i32 complexrotateop:$imm))),
2582            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2583}
2584
2585//===----------------------------------------------------------------------===//
2586// SVE Floating Point Complex Multiply-Add - Indexed Group
2587//===----------------------------------------------------------------------===//
2588
2589class sve_fp_fcmla_by_indexed_elem<bits<2> sz, string asm,
2590                                   ZPRRegOp zprty,
2591                                   ZPRRegOp zprty2, Operand itype>
2592: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, zprty2:$Zm, itype:$iop,
2593                        complexrotateop:$imm),
2594  asm, "\t$Zda, $Zn, $Zm$iop, $imm",
2595  "", []>, Sched<[]> {
2596  bits<5> Zda;
2597  bits<5> Zn;
2598  bits<2> imm;
2599  let Inst{31-24} = 0b01100100;
2600  let Inst{23-22} = sz;
2601  let Inst{21}    = 0b1;
2602  let Inst{15-12} = 0b0001;
2603  let Inst{11-10} = imm;
2604  let Inst{9-5}   = Zn;
2605  let Inst{4-0}   = Zda;
2606
2607  let Constraints = "$Zda = $_Zda";
2608  let DestructiveInstType = DestructiveOther;
2609  let ElementSize = ElementSizeNone;
2610  let hasSideEffects = 0;
2611  let mayRaiseFPException = 1;
2612}
2613
2614multiclass sve_fp_fcmla_by_indexed_elem<string asm, SDPatternOperator op> {
2615  def _H : sve_fp_fcmla_by_indexed_elem<0b10, asm, ZPR16, ZPR3b16, VectorIndexS32b> {
2616    bits<3> Zm;
2617    bits<2> iop;
2618    let Inst{20-19} = iop;
2619    let Inst{18-16} = Zm;
2620  }
2621  def _S : sve_fp_fcmla_by_indexed_elem<0b11, asm, ZPR32, ZPR4b32, VectorIndexD32b> {
2622    bits<4> Zm;
2623    bits<1> iop;
2624    let Inst{20} = iop;
2625    let Inst{19-16} = Zm;
2626  }
2627
2628  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
2629            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
2630  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
2631            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
2632}
2633
2634//===----------------------------------------------------------------------===//
2635// SVE Floating Point Complex Addition Group
2636//===----------------------------------------------------------------------===//
2637
2638class sve_fp_fcadd<bits<2> sz, string asm, ZPRRegOp zprty>
2639: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm,
2640                        complexrotateopodd:$imm),
2641  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm, $imm",
2642  "",
2643  []>, Sched<[]> {
2644  bits<5> Zdn;
2645  bits<5> Zm;
2646  bits<3> Pg;
2647  bit imm;
2648  let Inst{31-24} = 0b01100100;
2649  let Inst{23-22} = sz;
2650  let Inst{21-17} = 0;
2651  let Inst{16}    = imm;
2652  let Inst{15-13} = 0b100;
2653  let Inst{12-10} = Pg;
2654  let Inst{9-5}   = Zm;
2655  let Inst{4-0}   = Zdn;
2656
2657  let Constraints = "$Zdn = $_Zdn";
2658  let DestructiveInstType = DestructiveOther;
2659  let ElementSize = zprty.ElementSize;
2660  let hasSideEffects = 0;
2661  let mayRaiseFPException = 1;
2662}
2663
2664multiclass sve_fp_fcadd<string asm, SDPatternOperator op> {
2665  def _H : sve_fp_fcadd<0b01, asm, ZPR16>;
2666  def _S : sve_fp_fcadd<0b10, asm, ZPR32>;
2667  def _D : sve_fp_fcadd<0b11, asm, ZPR64>;
2668
2669  def : Pat<(nxv8f16 (op nxv8i1:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 complexrotateopodd:$imm))),
2670            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2671  def : Pat<(nxv4f32 (op nxv4i1:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 complexrotateopodd:$imm))),
2672            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2673  def : Pat<(nxv2f64 (op nxv2i1:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, (i32 complexrotateopodd:$imm))),
2674            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2675}
2676
2677//===----------------------------------------------------------------------===//
2678// SVE2 Floating Point Convert Group
2679//===----------------------------------------------------------------------===//
2680
2681class sve2_fp_convert_precision<bits<4> opc, string asm,
2682                                ZPRRegOp zprty1, ZPRRegOp zprty2>
2683: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, PPR3bAny:$Pg, zprty2:$Zn),
2684  asm, "\t$Zd, $Pg/m, $Zn",
2685  "",
2686  []>, Sched<[]> {
2687  bits<5> Zd;
2688  bits<5> Zn;
2689  bits<3> Pg;
2690  let Inst{31-24} = 0b01100100;
2691  let Inst{23-22} = opc{3-2};
2692  let Inst{21-18} = 0b0010;
2693  let Inst{17-16} = opc{1-0};
2694  let Inst{15-13} = 0b101;
2695  let Inst{12-10} = Pg;
2696  let Inst{9-5}   = Zn;
2697  let Inst{4-0}   = Zd;
2698
2699  let Constraints = "$Zd = $_Zd";
2700  let hasSideEffects = 0;
2701  let mayRaiseFPException = 1;
2702}
2703
2704multiclass sve2_fp_convert_down_narrow<string asm, string op> {
2705  def _StoH : sve2_fp_convert_precision<0b1000, asm, ZPR16, ZPR32>;
2706  def _DtoS : sve2_fp_convert_precision<0b1110, asm, ZPR32, ZPR64>;
2707
2708  def : SVE_3_Op_Pat<nxv8f16, !cast<SDPatternOperator>(op # _f16f32), nxv8f16, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _StoH)>;
2709  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
2710}
2711
2712multiclass sve2_fp_convert_up_long<string asm, string op> {
2713  def _HtoS : sve2_fp_convert_precision<0b1001, asm, ZPR32, ZPR16>;
2714  def _StoD : sve2_fp_convert_precision<0b1111, asm, ZPR64, ZPR32>;
2715
2716  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f16), nxv4f32, nxv4i1, nxv8f16, !cast<Instruction>(NAME # _HtoS)>;
2717  def : SVE_3_Op_Pat<nxv2f64, !cast<SDPatternOperator>(op # _f64f32), nxv2f64, nxv2i1, nxv4f32, !cast<Instruction>(NAME # _StoD)>;
2718}
2719
2720multiclass sve2_fp_convert_down_odd_rounding_top<string asm, string op> {
2721  def _DtoS : sve2_fp_convert_precision<0b0010, asm, ZPR32, ZPR64>;
2722
2723  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
2724}
2725
2726//===----------------------------------------------------------------------===//
2727// SVE2 Floating Point Pairwise Group
2728//===----------------------------------------------------------------------===//
2729
2730class sve2_fp_pairwise_pred<bits<2> sz, bits<3> opc, string asm,
2731                            ZPRRegOp zprty>
2732: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
2733  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
2734  "",
2735  []>, Sched<[]> {
2736  bits<3> Pg;
2737  bits<5> Zm;
2738  bits<5> Zdn;
2739  let Inst{31-24} = 0b01100100;
2740  let Inst{23-22} = sz;
2741  let Inst{21-19} = 0b010;
2742  let Inst{18-16} = opc;
2743  let Inst{15-13} = 0b100;
2744  let Inst{12-10} = Pg;
2745  let Inst{9-5}   = Zm;
2746  let Inst{4-0}   = Zdn;
2747
2748  let Constraints = "$Zdn = $_Zdn";
2749  let DestructiveInstType = DestructiveOther;
2750  let ElementSize = zprty.ElementSize;
2751  let hasSideEffects = 0;
2752  let mayRaiseFPException = 1;
2753}
2754
2755multiclass sve2_fp_pairwise_pred<bits<3> opc, string asm,
2756                                 SDPatternOperator op> {
2757  def _H : sve2_fp_pairwise_pred<0b01, opc, asm, ZPR16>;
2758  def _S : sve2_fp_pairwise_pred<0b10, opc, asm, ZPR32>;
2759  def _D : sve2_fp_pairwise_pred<0b11, opc, asm, ZPR64>;
2760
2761  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2762  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2763  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2764}
2765
2766//===----------------------------------------------------------------------===//
2767// SVE2 Floating Point Widening Multiply-Add - Indexed Group
2768//===----------------------------------------------------------------------===//
2769
2770class sve2_fp_mla_long_by_indexed_elem<bits<3> opc, string asm>
2771: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR3b16:$Zm,
2772                        VectorIndexH32b:$iop),
2773  asm, "\t$Zda, $Zn, $Zm$iop",
2774  "",
2775  []>, Sched<[]> {
2776  bits<5> Zda;
2777  bits<5> Zn;
2778  bits<3> Zm;
2779  bits<3> iop;
2780  let Inst{31-23} = 0b011001001;
2781  let Inst{22}    = opc{2};
2782  let Inst{21}    = 0b1;
2783  let Inst{20-19} = iop{2-1};
2784  let Inst{18-16} = Zm;
2785  let Inst{15-14} = 0b01;
2786  let Inst{13}    = opc{1};
2787  let Inst{12}    = 0b0;
2788  let Inst{11}    = iop{0};
2789  let Inst{10}    = opc{0};
2790  let Inst{9-5}   = Zn;
2791  let Inst{4-0}   = Zda;
2792
2793  let Constraints = "$Zda = $_Zda";
2794  let DestructiveInstType = DestructiveOther;
2795  let ElementSize = ElementSizeNone;
2796  let hasSideEffects = 0;
2797  let mayRaiseFPException = 1;
2798}
2799
2800multiclass sve2_fp_mla_long_by_indexed_elem<bits<3> opc, string asm,
2801                                            ValueType OutVT, ValueType InVT,
2802                                            SDPatternOperator op> {
2803  def NAME : sve2_fp_mla_long_by_indexed_elem<opc, asm>;
2804  def : SVE_4_Op_Imm_Pat<OutVT, op, OutVT, InVT, InVT, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME)>;
2805}
2806
2807//===----------------------------------------------------------------------===//
2808// SVE2 Floating Point Widening Multiply-Add Group
2809//===----------------------------------------------------------------------===//
2810
2811class sve2_fp_mla_long<bits<3> opc, string asm>
2812: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
2813  asm, "\t$Zda, $Zn, $Zm",
2814  "",
2815  []>, Sched<[]> {
2816  bits<5> Zda;
2817  bits<5> Zn;
2818  bits<5> Zm;
2819  let Inst{31-23} = 0b011001001;
2820  let Inst{22}    = opc{2};
2821  let Inst{21}    = 0b1;
2822  let Inst{20-16} = Zm;
2823  let Inst{15-14} = 0b10;
2824  let Inst{13}    = opc{1};
2825  let Inst{12-11} = 0b00;
2826  let Inst{10}    = opc{0};
2827  let Inst{9-5}   = Zn;
2828  let Inst{4-0}   = Zda;
2829
2830  let Constraints = "$Zda = $_Zda";
2831  let DestructiveInstType = DestructiveOther;
2832  let ElementSize = ElementSizeNone;
2833  let hasSideEffects = 0;
2834  let mayRaiseFPException = 1;
2835}
2836
2837multiclass sve2_fp_mla_long<bits<3> opc, string asm, ValueType OutVT,
2838                            ValueType InVT, SDPatternOperator op> {
2839  def NAME : sve2_fp_mla_long<opc, asm>;
2840  def : SVE_3_Op_Pat<OutVT, op, OutVT, InVT, InVT, !cast<Instruction>(NAME)>;
2841}
2842
2843//===----------------------------------------------------------------------===//
2844// SVE Stack Allocation Group
2845//===----------------------------------------------------------------------===//
2846
2847class sve_int_arith_vl<bit opc, string asm, bit streaming_sve = 0b0>
2848: I<(outs GPR64sp:$Rd), (ins GPR64sp:$Rn, simm6_32b:$imm6),
2849  asm, "\t$Rd, $Rn, $imm6",
2850  "",
2851  []>, Sched<[]> {
2852  bits<5> Rd;
2853  bits<5> Rn;
2854  bits<6> imm6;
2855  let Inst{31-23} = 0b000001000;
2856  let Inst{22}    = opc;
2857  let Inst{21}    = 0b1;
2858  let Inst{20-16} = Rn;
2859  let Inst{15-12} = 0b0101;
2860  let Inst{11}    = streaming_sve;
2861  let Inst{10-5}  = imm6;
2862  let Inst{4-0}   = Rd;
2863
2864  let hasSideEffects = 0;
2865}
2866
2867class sve_int_read_vl_a<bit op, bits<5> opc2, string asm, bit streaming_sve = 0b0>
2868: I<(outs GPR64:$Rd), (ins simm6_32b:$imm6),
2869  asm, "\t$Rd, $imm6",
2870  "",
2871  []>, Sched<[]> {
2872  bits<5> Rd;
2873  bits<6> imm6;
2874  let Inst{31-23} = 0b000001001;
2875  let Inst{22}    = op;
2876  let Inst{21}    = 0b1;
2877  let Inst{20-16} = opc2{4-0};
2878  let Inst{15-12} = 0b0101;
2879  let Inst{11}    = streaming_sve;
2880  let Inst{10-5}  = imm6;
2881  let Inst{4-0}   = Rd;
2882
2883  let hasSideEffects = 0;
2884  let isReMaterializable = 1;
2885}
2886
2887//===----------------------------------------------------------------------===//
2888// SVE Permute - In Lane Group
2889//===----------------------------------------------------------------------===//
2890
2891class sve_int_perm_bin_perm_zz<bits<3> opc, bits<2> sz8_64, string asm,
2892                               ZPRRegOp zprty>
2893: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
2894  asm, "\t$Zd, $Zn, $Zm",
2895  "",
2896  []>, Sched<[]> {
2897  bits<5> Zd;
2898  bits<5> Zm;
2899  bits<5> Zn;
2900  let Inst{31-24} = 0b00000101;
2901  let Inst{23-22} = sz8_64;
2902  let Inst{21}    = 0b1;
2903  let Inst{20-16} = Zm;
2904  let Inst{15-13} = 0b011;
2905  let Inst{12-10} = opc;
2906  let Inst{9-5}   = Zn;
2907  let Inst{4-0}   = Zd;
2908
2909  let hasSideEffects = 0;
2910}
2911
2912multiclass sve_int_perm_bin_perm_zz<bits<3> opc, string asm,
2913                                    SDPatternOperator op> {
2914  def _B : sve_int_perm_bin_perm_zz<opc, 0b00, asm, ZPR8>;
2915  def _H : sve_int_perm_bin_perm_zz<opc, 0b01, asm, ZPR16>;
2916  def _S : sve_int_perm_bin_perm_zz<opc, 0b10, asm, ZPR32>;
2917  def _D : sve_int_perm_bin_perm_zz<opc, 0b11, asm, ZPR64>;
2918
2919  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
2920  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2921  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2922  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2923
2924  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2925  def : SVE_2_Op_Pat<nxv4f16, op, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _S)>;
2926  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2927  def : SVE_2_Op_Pat<nxv2f16, op, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _D)>;
2928  def : SVE_2_Op_Pat<nxv2f32, op, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _D)>;
2929  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2930
2931  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
2932}
2933
2934//===----------------------------------------------------------------------===//
2935// SVE Floating Point Unary Operations Group
2936//===----------------------------------------------------------------------===//
2937
2938class sve_fp_2op_p_zd<bits<7> opc, string asm, RegisterOperand i_zprtype,
2939                      RegisterOperand o_zprtype, ElementSizeEnum Sz>
2940: I<(outs o_zprtype:$Zd), (ins i_zprtype:$_Zd, PPR3bAny:$Pg, i_zprtype:$Zn),
2941  asm, "\t$Zd, $Pg/m, $Zn",
2942  "",
2943  []>, Sched<[]> {
2944  bits<3> Pg;
2945  bits<5> Zd;
2946  bits<5> Zn;
2947  let Inst{31-24} = 0b01100101;
2948  let Inst{23-22} = opc{6-5};
2949  let Inst{21}    = 0b0;
2950  let Inst{20-16} = opc{4-0};
2951  let Inst{15-13} = 0b101;
2952  let Inst{12-10} = Pg;
2953  let Inst{9-5}   = Zn;
2954  let Inst{4-0}   = Zd;
2955
2956  let Constraints = "$Zd = $_Zd";
2957  let DestructiveInstType = DestructiveUnaryPassthru;
2958  let ElementSize = Sz;
2959  let hasSideEffects = 0;
2960  let mayRaiseFPException = 1;
2961}
2962
2963multiclass sve_fp_2op_p_zd<bits<7> opc, string asm,
2964                           RegisterOperand i_zprtype,
2965                           RegisterOperand o_zprtype,
2966                           SDPatternOperator int_op,
2967                           SDPatternOperator ir_op, ValueType vt1,
2968                           ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
2969  def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>,
2970             SVEPseudo2Instr<NAME, 1>;
2971  // convert vt1 to a packed type for the intrinsic patterns
2972  defvar packedvt1 = SVEContainerVT<vt1>.Value;
2973
2974  // convert vt3 to a packed type for the intrinsic patterns
2975  defvar packedvt3 = SVEContainerVT<vt3>.Value;
2976
2977  def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, packedvt3, !cast<Instruction>(NAME)>;
2978  def : SVE_1_Op_Passthru_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
2979
2980  def _UNDEF : PredOneOpPassthruPseudo<NAME, !cast<ZPRRegOp>(i_zprtype)>;
2981
2982  defm : SVE_1_Op_PassthruUndef_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME # _UNDEF)>;
2983}
2984
2985multiclass sve_fp_2op_p_zdr<bits<7> opc, string asm,
2986                            RegisterOperand i_zprtype,
2987                            RegisterOperand o_zprtype,
2988                            SDPatternOperator int_op,
2989                            SDPatternOperator ir_op, ValueType vt1,
2990                            ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
2991  def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>,
2992             SVEPseudo2Instr<NAME, 1>;
2993
2994  // convert vt1 to a packed type for the intrinsic patterns
2995  defvar packedvt1 = SVEContainerVT<vt1>.Value;
2996
2997  def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, vt3, !cast<Instruction>(NAME)>;
2998  def : SVE_1_Op_Passthru_Round_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
2999
3000  def _UNDEF : PredOneOpPassthruPseudo<NAME, !cast<ZPRRegOp>(i_zprtype)>;
3001
3002  defm : SVE_1_Op_PassthruUndef_Round_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME # _UNDEF)>;
3003}
3004
3005multiclass sve_fp_2op_p_zd_HSD<bits<5> opc, string asm, SDPatternOperator op> {
3006  def _H : sve_fp_2op_p_zd<{ 0b01, opc }, asm, ZPR16, ZPR16, ElementSizeH>,
3007           SVEPseudo2Instr<NAME # _H, 1>;
3008  def _S : sve_fp_2op_p_zd<{ 0b10, opc }, asm, ZPR32, ZPR32, ElementSizeS>,
3009           SVEPseudo2Instr<NAME # _S, 1>;
3010  def _D : sve_fp_2op_p_zd<{ 0b11, opc }, asm, ZPR64, ZPR64, ElementSizeD>,
3011           SVEPseudo2Instr<NAME # _D, 1>;
3012
3013  def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
3014  def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
3015  def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
3016  def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
3017  def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
3018  def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
3019
3020  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
3021  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
3022  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
3023
3024  defm : SVE_1_Op_PassthruUndef_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H_UNDEF)>;
3025  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H_UNDEF)>;
3026  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H_UNDEF)>;
3027  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S_UNDEF)>;
3028  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S_UNDEF)>;
3029  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D_UNDEF)>;
3030}
3031
3032multiclass sve2_fp_flogb<string asm, string Ps, SDPatternOperator op> {
3033  def _H : sve_fp_2op_p_zd<0b0011010, asm, ZPR16, ZPR16, ElementSizeH>,
3034             SVEPseudo2Instr<Ps # _H, 1>;
3035  def _S : sve_fp_2op_p_zd<0b0011100, asm, ZPR32, ZPR32, ElementSizeS>,
3036             SVEPseudo2Instr<Ps # _S, 1>;
3037  def _D : sve_fp_2op_p_zd<0b0011110, asm, ZPR64, ZPR64, ElementSizeD>,
3038             SVEPseudo2Instr<Ps # _D, 1>;
3039
3040  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
3041  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
3042  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
3043}
3044
3045multiclass sve2_fp_un_pred_zeroing_hsd<SDPatternOperator op> {
3046  def _H_ZERO : PredOneOpPassthruPseudo<NAME # _H, ZPR16, FalseLanesZero>;
3047  def _S_ZERO : PredOneOpPassthruPseudo<NAME # _S, ZPR32, FalseLanesZero>;
3048  def _D_ZERO : PredOneOpPassthruPseudo<NAME # _D, ZPR64, FalseLanesZero>;
3049
3050  def : SVE_1_Op_PassthruZero_Pat<nxv8i16, op, nxv8i1, nxv8f16, !cast<Pseudo>(NAME # _H_ZERO)>;
3051  def : SVE_1_Op_PassthruZero_Pat<nxv4i32, op, nxv4i1, nxv4f32, !cast<Pseudo>(NAME # _S_ZERO)>;
3052  def : SVE_1_Op_PassthruZero_Pat<nxv2i64, op, nxv2i1, nxv2f64, !cast<Pseudo>(NAME # _D_ZERO)>;
3053}
3054
3055multiclass sve2_fp_convert_down_odd_rounding<string asm, string op> {
3056  def _DtoS : sve_fp_2op_p_zd<0b0001010, asm, ZPR64, ZPR32, ElementSizeD>;
3057  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
3058}
3059
3060//===----------------------------------------------------------------------===//
3061// SVE Floating Point Unary Operations - Unpredicated Group
3062//===----------------------------------------------------------------------===//
3063
3064class sve_fp_2op_u_zd<bits<2> sz, bits<3> opc, string asm,
3065                      ZPRRegOp zprty>
3066: I<(outs zprty:$Zd), (ins zprty:$Zn),
3067  asm, "\t$Zd, $Zn",
3068  "",
3069  []>, Sched<[]> {
3070  bits<5> Zd;
3071  bits<5> Zn;
3072  let Inst{31-24} = 0b01100101;
3073  let Inst{23-22} = sz;
3074  let Inst{21-19} = 0b001;
3075  let Inst{18-16} = opc;
3076  let Inst{15-10} = 0b001100;
3077  let Inst{9-5}   = Zn;
3078  let Inst{4-0}   = Zd;
3079
3080  let hasSideEffects = 0;
3081  let mayRaiseFPException = 1;
3082}
3083
3084multiclass sve_fp_2op_u_zd<bits<3> opc, string asm, SDPatternOperator op> {
3085  def _H : sve_fp_2op_u_zd<0b01, opc, asm, ZPR16>;
3086  def _S : sve_fp_2op_u_zd<0b10, opc, asm, ZPR32>;
3087  def _D : sve_fp_2op_u_zd<0b11, opc, asm, ZPR64>;
3088
3089  def : SVE_1_Op_Pat<nxv8f16, op, nxv8f16, !cast<Instruction>(NAME # _H)>;
3090  def : SVE_1_Op_Pat<nxv4f32, op, nxv4f32, !cast<Instruction>(NAME # _S)>;
3091  def : SVE_1_Op_Pat<nxv2f64, op, nxv2f64, !cast<Instruction>(NAME # _D)>;
3092}
3093
3094//===----------------------------------------------------------------------===//
3095// SVE Integer Arithmetic - Binary Predicated Group
3096//===----------------------------------------------------------------------===//
3097
3098class sve_int_bin_pred_arit_log<bits<2> sz8_64, bits<2> fmt, bits<3> opc,
3099                                string asm, ZPRRegOp zprty>
3100: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
3101  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm", "", []>, Sched<[]> {
3102  bits<3> Pg;
3103  bits<5> Zdn;
3104  bits<5> Zm;
3105  let Inst{31-24} = 0b00000100;
3106  let Inst{23-22} = sz8_64;
3107  let Inst{21}    = 0b0;
3108  let Inst{20-19} = fmt;
3109  let Inst{18-16} = opc;
3110  let Inst{15-13} = 0b000;
3111  let Inst{12-10} = Pg;
3112  let Inst{9-5}   = Zm;
3113  let Inst{4-0}   = Zdn;
3114
3115  let Constraints = "$Zdn = $_Zdn";
3116  let DestructiveInstType = DestructiveOther;
3117  let ElementSize = zprty.ElementSize;
3118  let hasSideEffects = 0;
3119}
3120
3121multiclass sve_int_bin_pred_log<bits<3> opc, string asm, string Ps,
3122                                SDPatternOperator op,
3123                                DestructiveInstTypeEnum flags> {
3124  let DestructiveInstType = flags in {
3125  def _B : sve_int_bin_pred_arit_log<0b00, 0b11, opc, asm, ZPR8>,
3126             SVEPseudo2Instr<Ps # _B, 1>;
3127  def _H : sve_int_bin_pred_arit_log<0b01, 0b11, opc, asm, ZPR16>,
3128             SVEPseudo2Instr<Ps # _H, 1>;
3129  def _S : sve_int_bin_pred_arit_log<0b10, 0b11, opc, asm, ZPR32>,
3130             SVEPseudo2Instr<Ps # _S, 1>;
3131  def _D : sve_int_bin_pred_arit_log<0b11, 0b11, opc, asm, ZPR64>,
3132             SVEPseudo2Instr<Ps # _D, 1>;
3133  }
3134
3135  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3136  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3137  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3138  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3139}
3140
3141multiclass sve_int_bin_pred_arit_0<bits<3> opc, string asm, string Ps,
3142                                   SDPatternOperator op,
3143                                   DestructiveInstTypeEnum flags,
3144                                   string revname="", bit isReverseInstr=0> {
3145  let DestructiveInstType = flags in {
3146  def _B : sve_int_bin_pred_arit_log<0b00, 0b00, opc, asm, ZPR8>,
3147           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3148  def _H : sve_int_bin_pred_arit_log<0b01, 0b00, opc, asm, ZPR16>,
3149           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3150  def _S : sve_int_bin_pred_arit_log<0b10, 0b00, opc, asm, ZPR32>,
3151           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3152  def _D : sve_int_bin_pred_arit_log<0b11, 0b00, opc, asm, ZPR64>,
3153           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3154  }
3155
3156  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3157  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3158  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3159  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3160}
3161
3162multiclass sve_int_bin_pred_arit_1<bits<3> opc, string asm, string Ps,
3163                                   SDPatternOperator op,
3164                                   DestructiveInstTypeEnum flags> {
3165  let DestructiveInstType = flags in {
3166  def _B : sve_int_bin_pred_arit_log<0b00, 0b01, opc, asm, ZPR8>,
3167           SVEPseudo2Instr<Ps # _B, 1>;
3168  def _H : sve_int_bin_pred_arit_log<0b01, 0b01, opc, asm, ZPR16>,
3169           SVEPseudo2Instr<Ps # _H, 1>;
3170  def _S : sve_int_bin_pred_arit_log<0b10, 0b01, opc, asm, ZPR32>,
3171           SVEPseudo2Instr<Ps # _S, 1>;
3172  def _D : sve_int_bin_pred_arit_log<0b11, 0b01, opc, asm, ZPR64>,
3173           SVEPseudo2Instr<Ps # _D, 1>;
3174  }
3175
3176  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3177  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3178  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3179  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3180}
3181
3182multiclass sve_int_bin_pred_arit_2<bits<3> opc, string asm, string Ps,
3183                                   SDPatternOperator op,
3184                                   DestructiveInstTypeEnum flags> {
3185  let DestructiveInstType = flags in {
3186  def _B : sve_int_bin_pred_arit_log<0b00, 0b10, opc, asm, ZPR8>,
3187           SVEPseudo2Instr<Ps # _B, 1>;
3188  def _H : sve_int_bin_pred_arit_log<0b01, 0b10, opc, asm, ZPR16>,
3189           SVEPseudo2Instr<Ps # _H, 1>;
3190  def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>,
3191           SVEPseudo2Instr<Ps # _S, 1>;
3192  def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>,
3193           SVEPseudo2Instr<Ps # _D, 1>;
3194  }
3195
3196  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3197  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3198  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3199  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3200}
3201
3202// Special case for divides which are not defined for 8b/16b elements.
3203multiclass sve_int_bin_pred_arit_2_div<bits<3> opc, string asm, string Ps,
3204                                       SDPatternOperator op,
3205                                       DestructiveInstTypeEnum flags,
3206                                       string revname="", bit isReverseInstr=0> {
3207  let DestructiveInstType = flags in {
3208  def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>,
3209           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3210  def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>,
3211           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3212  }
3213
3214  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3215  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3216}
3217
3218//===----------------------------------------------------------------------===//
3219// SVE Integer Multiply-Add Group
3220//===----------------------------------------------------------------------===//
3221
3222class sve_int_mladdsub_vvv_pred<bits<2> sz8_64, bits<1> opc, string asm,
3223                                ZPRRegOp zprty>
3224: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm, zprty:$Za),
3225  asm, "\t$Zdn, $Pg/m, $Zm, $Za",
3226  "",
3227  []>, Sched<[]> {
3228  bits<3> Pg;
3229  bits<5> Zdn;
3230  bits<5> Za;
3231  bits<5> Zm;
3232  let Inst{31-24} = 0b00000100;
3233  let Inst{23-22} = sz8_64;
3234  let Inst{21}    = 0b0;
3235  let Inst{20-16} = Zm;
3236  let Inst{15-14} = 0b11;
3237  let Inst{13}    = opc;
3238  let Inst{12-10} = Pg;
3239  let Inst{9-5}   = Za;
3240  let Inst{4-0}   = Zdn;
3241
3242  let Constraints = "$Zdn = $_Zdn";
3243  let DestructiveInstType = DestructiveOther;
3244  let ElementSize = zprty.ElementSize;
3245  let hasSideEffects = 0;
3246}
3247
3248multiclass sve_int_mladdsub_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
3249                                     string revname, bit isReverseInstr=0> {
3250  def _B : sve_int_mladdsub_vvv_pred<0b00, opc, asm, ZPR8>,
3251           SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3252  def _H : sve_int_mladdsub_vvv_pred<0b01, opc, asm, ZPR16>,
3253           SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3254  def _S : sve_int_mladdsub_vvv_pred<0b10, opc, asm, ZPR32>,
3255           SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3256  def _D : sve_int_mladdsub_vvv_pred<0b11, opc, asm, ZPR64>,
3257           SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3258
3259  def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3260  def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3261  def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3262  def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3263}
3264
3265class sve_int_mlas_vvv_pred<bits<2> sz8_64, bits<1> opc, string asm,
3266                            ZPRRegOp zprty>
3267: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm),
3268  asm, "\t$Zda, $Pg/m, $Zn, $Zm",
3269  "",
3270  []>, Sched<[]> {
3271  bits<3> Pg;
3272  bits<5> Zda;
3273  bits<5> Zm;
3274  bits<5> Zn;
3275  let Inst{31-24} = 0b00000100;
3276  let Inst{23-22} = sz8_64;
3277  let Inst{21}    = 0b0;
3278  let Inst{20-16} = Zm;
3279  let Inst{15-14} = 0b01;
3280  let Inst{13}    = opc;
3281  let Inst{12-10} = Pg;
3282  let Inst{9-5}   = Zn;
3283  let Inst{4-0}   = Zda;
3284
3285  let Constraints = "$Zda = $_Zda";
3286  let DestructiveInstType = DestructiveTernaryCommWithRev;
3287  let ElementSize = zprty.ElementSize;
3288  let hasSideEffects = 0;
3289}
3290
3291multiclass sve_int_mlas_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
3292                                 string Ps, string revname, bit isReverseInstr=0> {
3293  def _B : sve_int_mlas_vvv_pred<0b00, opc, asm, ZPR8>,
3294           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3295  def _H : sve_int_mlas_vvv_pred<0b01, opc, asm, ZPR16>,
3296           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3297  def _S : sve_int_mlas_vvv_pred<0b10, opc, asm, ZPR32>,
3298           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3299  def _D : sve_int_mlas_vvv_pred<0b11, opc, asm, ZPR64>,
3300           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3301
3302  def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3303  def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3304  def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3305  def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3306}
3307
3308//class for generating pseudo for SVE MLA/MAD/MLS/MSB
3309multiclass sve_int_3op_p_mladdsub<SDPatternOperator op> {
3310  def _B_UNDEF : PredThreeOpPseudo<NAME # _B, ZPR8,  FalseLanesUndef>;
3311  def _H_UNDEF : PredThreeOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
3312  def _S_UNDEF : PredThreeOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
3313  def _D_UNDEF : PredThreeOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
3314
3315  let  AddedComplexity = 9 in {
3316    def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B_UNDEF)>;
3317    def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H_UNDEF)>;
3318    def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S_UNDEF)>;
3319    def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D_UNDEF)>;
3320  }
3321}
3322
3323//===----------------------------------------------------------------------===//
3324// SVE2 Integer Multiply-Add - Unpredicated Group
3325//===----------------------------------------------------------------------===//
3326
3327class sve2_int_mla<bits<2> sz, bits<5> opc, string asm,
3328                   ZPRRegOp zprty1, ZPRRegOp zprty2>
3329: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm),
3330  asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
3331  bits<5> Zda;
3332  bits<5> Zn;
3333  bits<5> Zm;
3334  let Inst{31-24} = 0b01000100;
3335  let Inst{23-22} = sz;
3336  let Inst{21}    = 0b0;
3337  let Inst{20-16} = Zm;
3338  let Inst{15}    = 0b0;
3339  let Inst{14-10} = opc;
3340  let Inst{9-5}   = Zn;
3341  let Inst{4-0}   = Zda;
3342
3343  let Constraints = "$Zda = $_Zda";
3344  let DestructiveInstType = DestructiveOther;
3345  let ElementSize = ElementSizeNone;
3346  let hasSideEffects = 0;
3347}
3348
3349multiclass sve2_int_mla<bit S, string asm, SDPatternOperator op> {
3350  def _B : sve2_int_mla<0b00, { 0b1110, S }, asm, ZPR8, ZPR8>;
3351  def _H : sve2_int_mla<0b01, { 0b1110, S }, asm, ZPR16, ZPR16>;
3352  def _S : sve2_int_mla<0b10, { 0b1110, S }, asm, ZPR32, ZPR32>;
3353  def _D : sve2_int_mla<0b11, { 0b1110, S }, asm, ZPR64, ZPR64>;
3354
3355  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3356  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3357  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3358  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3359}
3360
3361multiclass sve2_int_mla_long<bits<5> opc, string asm, SDPatternOperator op> {
3362  def _H : sve2_int_mla<0b01, opc, asm, ZPR16, ZPR8>;
3363  def _S : sve2_int_mla<0b10, opc, asm, ZPR32, ZPR16>;
3364  def _D : sve2_int_mla<0b11, opc, asm, ZPR64, ZPR32>;
3365
3366  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3367  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
3368  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3369}
3370
3371//===----------------------------------------------------------------------===//
3372// SVE2 Integer Multiply-Add - Indexed Group
3373//===----------------------------------------------------------------------===//
3374
3375class sve2_int_mla_by_indexed_elem<bits<2> sz, bits<6> opc, string asm,
3376                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3377                                   ZPRRegOp zprty3, Operand itype>
3378: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop),
3379  asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
3380  bits<5> Zda;
3381  bits<5> Zn;
3382  let Inst{31-24} = 0b01000100;
3383  let Inst{23-22} = sz;
3384  let Inst{21}    = 0b1;
3385  let Inst{15-10} = opc;
3386  let Inst{9-5}   = Zn;
3387  let Inst{4-0}   = Zda;
3388
3389  let Constraints = "$Zda = $_Zda";
3390  let DestructiveInstType = DestructiveOther;
3391  let ElementSize = ElementSizeNone;
3392  let hasSideEffects = 0;
3393}
3394
3395multiclass sve2_int_mla_by_indexed_elem<bits<2> opc, bit S, string asm,
3396                                        SDPatternOperator op> {
3397  def _H : sve2_int_mla_by_indexed_elem<{0, ?}, { 0b000, opc, S }, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexH32b> {
3398    bits<3> Zm;
3399    bits<3> iop;
3400    let Inst{22} = iop{2};
3401    let Inst{20-19} = iop{1-0};
3402    let Inst{18-16} = Zm;
3403  }
3404  def _S : sve2_int_mla_by_indexed_elem<0b10, { 0b000, opc, S }, asm, ZPR32, ZPR32, ZPR3b32, VectorIndexS32b> {
3405    bits<3> Zm;
3406    bits<2> iop;
3407    let Inst{20-19} = iop;
3408    let Inst{18-16} = Zm;
3409  }
3410  def _D : sve2_int_mla_by_indexed_elem<0b11, { 0b000, opc, S }, asm, ZPR64, ZPR64, ZPR4b64, VectorIndexD32b> {
3411    bits<4> Zm;
3412    bit iop;
3413    let Inst{20} = iop;
3414    let Inst{19-16} = Zm;
3415  }
3416
3417  def : SVE_4_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
3418  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3419  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3420}
3421
3422//===----------------------------------------------------------------------===//
3423// SVE2 Integer Multiply-Add Long - Indexed Group
3424//===----------------------------------------------------------------------===//
3425
3426multiclass sve2_int_mla_long_by_indexed_elem<bits<4> opc, string asm,
3427                                             SDPatternOperator op> {
3428  def _S : sve2_int_mla_by_indexed_elem<0b10, { opc{3}, 0b0, opc{2-1}, ?, opc{0} },
3429                                        asm, ZPR32, ZPR16, ZPR3b16, VectorIndexH32b> {
3430    bits<3> Zm;
3431    bits<3> iop;
3432    let Inst{20-19} = iop{2-1};
3433    let Inst{18-16} = Zm;
3434    let Inst{11} = iop{0};
3435  }
3436  def _D : sve2_int_mla_by_indexed_elem<0b11, { opc{3}, 0b0, opc{2-1}, ?, opc{0} },
3437                                        asm, ZPR64, ZPR32, ZPR4b32, VectorIndexS32b> {
3438    bits<4> Zm;
3439    bits<2> iop;
3440    let Inst{20} = iop{1};
3441    let Inst{19-16} = Zm;
3442    let Inst{11} = iop{0};
3443  }
3444
3445  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _S)>;
3446  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
3447}
3448
3449//===----------------------------------------------------------------------===//
3450// SVE Integer Dot Product Group
3451//===----------------------------------------------------------------------===//
3452
3453class sve_intx_dot<bit sz, bit U, string asm, ZPRRegOp zprty1,
3454                   ZPRRegOp zprty2>
3455: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm), asm,
3456  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
3457  bits<5> Zda;
3458  bits<5> Zn;
3459  bits<5> Zm;
3460  let Inst{31-23} = 0b010001001;
3461  let Inst{22}    = sz;
3462  let Inst{21}    = 0;
3463  let Inst{20-16} = Zm;
3464  let Inst{15-11} = 0;
3465  let Inst{10}    = U;
3466  let Inst{9-5}   = Zn;
3467  let Inst{4-0}   = Zda;
3468
3469  let Constraints = "$Zda = $_Zda";
3470  let DestructiveInstType = DestructiveOther;
3471  let hasSideEffects = 0;
3472}
3473
3474multiclass sve_intx_dot<bit opc, string asm, SDPatternOperator op> {
3475  def _S : sve_intx_dot<0b0, opc, asm, ZPR32, ZPR8>;
3476  def _D : sve_intx_dot<0b1, opc, asm, ZPR64, ZPR16>;
3477
3478  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32,  nxv16i8, nxv16i8, !cast<Instruction>(NAME # _S)>;
3479  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _D)>;
3480}
3481
3482//===----------------------------------------------------------------------===//
3483// SVE Integer Dot Product Group - Indexed Group
3484//===----------------------------------------------------------------------===//
3485
3486class sve_intx_dot_by_indexed_elem<bit sz, bit U, string asm,
3487                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3488                                   ZPRRegOp zprty3, Operand itype>
3489: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop),
3490  asm, "\t$Zda, $Zn, $Zm$iop",
3491  "", []>, Sched<[]> {
3492  bits<5> Zda;
3493  bits<5> Zn;
3494  let Inst{31-23} = 0b010001001;
3495  let Inst{22}    = sz;
3496  let Inst{21}    = 0b1;
3497  let Inst{15-11} = 0;
3498  let Inst{10}    = U;
3499  let Inst{9-5}   = Zn;
3500  let Inst{4-0}   = Zda;
3501
3502  let Constraints = "$Zda = $_Zda";
3503  let DestructiveInstType = DestructiveOther;
3504  let hasSideEffects = 0;
3505}
3506
3507multiclass sve_intx_dot_by_indexed_elem<bit opc, string asm,
3508                                        SDPatternOperator op> {
3509  def _S : sve_intx_dot_by_indexed_elem<0b0, opc, asm, ZPR32, ZPR8, ZPR3b8, VectorIndexS32b_timm> {
3510    bits<2> iop;
3511    bits<3> Zm;
3512    let Inst{20-19} = iop;
3513    let Inst{18-16} = Zm;
3514  }
3515  def _D : sve_intx_dot_by_indexed_elem<0b1, opc, asm, ZPR64, ZPR16, ZPR4b16, VectorIndexD32b_timm> {
3516    bits<1> iop;
3517    bits<4> Zm;
3518    let Inst{20} = iop;
3519    let Inst{19-16} = Zm;
3520  }
3521
3522  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv16i8, nxv16i8, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3523  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv8i16, nxv8i16, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3524}
3525
3526//===----------------------------------------------------------------------===//
3527// SVE2 Complex Integer Dot Product Group
3528//===----------------------------------------------------------------------===//
3529
3530class sve2_complex_int_arith<bits<2> sz, bits<4> opc, string asm,
3531                             ZPRRegOp zprty1, ZPRRegOp zprty2>
3532: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm,
3533                         complexrotateop:$rot),
3534  asm, "\t$Zda, $Zn, $Zm, $rot", "", []>, Sched<[]> {
3535  bits<5> Zda;
3536  bits<5> Zn;
3537  bits<5> Zm;
3538  bits<2> rot;
3539  let Inst{31-24} = 0b01000100;
3540  let Inst{23-22} = sz;
3541  let Inst{21}    = 0b0;
3542  let Inst{20-16} = Zm;
3543  let Inst{15-12} = opc;
3544  let Inst{11-10} = rot;
3545  let Inst{9-5}   = Zn;
3546  let Inst{4-0}   = Zda;
3547
3548  let Constraints = "$Zda = $_Zda";
3549  let DestructiveInstType = DestructiveOther;
3550  let ElementSize = ElementSizeNone;
3551  let hasSideEffects = 0;
3552}
3553
3554multiclass sve2_cintx_dot<string asm, SDPatternOperator op> {
3555  def _S : sve2_complex_int_arith<0b10, 0b0001, asm, ZPR32, ZPR8>;
3556  def _D : sve2_complex_int_arith<0b11, 0b0001, asm, ZPR64, ZPR16>;
3557
3558  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv16i8 ZPR8:$Op2), (nxv16i8 ZPR8:$Op3),
3559                         (i32 complexrotateop:$imm))),
3560            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR8:$Op2, ZPR8:$Op3, complexrotateop:$imm)>;
3561  def : Pat<(nxv2i64 (op (nxv2i64 ZPR64:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3562                         (i32 complexrotateop:$imm))),
3563            (!cast<Instruction>(NAME # "_D") ZPR64:$Op1, ZPR16:$Op2, ZPR16:$Op3, complexrotateop:$imm)>;
3564}
3565
3566//===----------------------------------------------------------------------===//
3567// SVE2 Complex Multiply-Add Group
3568//===----------------------------------------------------------------------===//
3569
3570multiclass sve2_int_cmla<bit opc, string asm, SDPatternOperator op> {
3571  def _B : sve2_complex_int_arith<0b00, { 0b001, opc }, asm, ZPR8, ZPR8>;
3572  def _H : sve2_complex_int_arith<0b01, { 0b001, opc }, asm, ZPR16, ZPR16>;
3573  def _S : sve2_complex_int_arith<0b10, { 0b001, opc }, asm, ZPR32, ZPR32>;
3574  def _D : sve2_complex_int_arith<0b11, { 0b001, opc }, asm, ZPR64, ZPR64>;
3575
3576  def : SVE_4_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, i32, complexrotateop, !cast<Instruction>(NAME # _B)>;
3577  def : SVE_4_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, i32, complexrotateop, !cast<Instruction>(NAME # _H)>;
3578  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, i32, complexrotateop, !cast<Instruction>(NAME # _S)>;
3579  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, i32, complexrotateop, !cast<Instruction>(NAME # _D)>;
3580}
3581
3582//===----------------------------------------------------------------------===//
3583// SVE2 Complex Integer Dot Product - Indexed Group
3584//===----------------------------------------------------------------------===//
3585
3586class sve2_complex_int_arith_indexed<bits<2> sz, bits<4> opc, string asm,
3587                                     ZPRRegOp zprty1, ZPRRegOp zprty2,
3588                                     ZPRRegOp zprty3, Operand itype>
3589: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop,
3590                         complexrotateop:$rot),
3591  asm, "\t$Zda, $Zn, $Zm$iop, $rot", "", []>, Sched<[]> {
3592  bits<5> Zda;
3593  bits<5> Zn;
3594  bits<2> rot;
3595  let Inst{31-24} = 0b01000100;
3596  let Inst{23-22} = sz;
3597  let Inst{21}    = 0b1;
3598  let Inst{15-12} = opc;
3599  let Inst{11-10} = rot;
3600  let Inst{9-5}   = Zn;
3601  let Inst{4-0}   = Zda;
3602
3603  let Constraints = "$Zda = $_Zda";
3604  let DestructiveInstType = DestructiveOther;
3605  let ElementSize = ElementSizeNone;
3606  let hasSideEffects = 0;
3607}
3608
3609multiclass sve2_cintx_dot_by_indexed_elem<string asm, SDPatternOperator op> {
3610  def _S : sve2_complex_int_arith_indexed<0b10, 0b0100, asm, ZPR32, ZPR8, ZPR3b8, VectorIndexS32b> {
3611    bits<2> iop;
3612    bits<3> Zm;
3613    let Inst{20-19} = iop;
3614    let Inst{18-16} = Zm;
3615  }
3616  def _D : sve2_complex_int_arith_indexed<0b11, 0b0100, asm, ZPR64, ZPR16, ZPR4b16, VectorIndexD32b> {
3617    bit iop;
3618    bits<4> Zm;
3619    let Inst{20} = iop;
3620    let Inst{19-16} = Zm;
3621  }
3622
3623  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv16i8 ZPR8:$Op2), (nxv16i8 ZPR8:$Op3),
3624                         (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
3625            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR8:$Op2, ZPR8:$Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
3626  def : Pat<(nxv2i64 (op (nxv2i64 ZPR64:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3627                         (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
3628            (!cast<Instruction>(NAME # "_D") ZPR64:$Op1, ZPR16:$Op2, ZPR16:$Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
3629}
3630
3631//===----------------------------------------------------------------------===//
3632// SVE2 Complex Multiply-Add - Indexed Group
3633//===----------------------------------------------------------------------===//
3634
3635multiclass sve2_cmla_by_indexed_elem<bit opc, string asm,
3636                                     SDPatternOperator op> {
3637  def _H : sve2_complex_int_arith_indexed<0b10, { 0b011, opc }, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexS32b> {
3638    bits<2> iop;
3639    bits<3> Zm;
3640    let Inst{20-19} = iop;
3641    let Inst{18-16} = Zm;
3642  }
3643  def _S : sve2_complex_int_arith_indexed<0b11, { 0b011, opc }, asm, ZPR32, ZPR32, ZPR4b32, VectorIndexD32b> {
3644    bit iop;
3645    bits<4> Zm;
3646    let Inst{20} = iop;
3647    let Inst{19-16} = Zm;
3648  }
3649
3650  def : Pat<(nxv8i16 (op (nxv8i16 ZPR16:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3651                         (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
3652            (!cast<Instruction>(NAME # "_H") ZPR16:$Op1, ZPR16:$Op2, ZPR16:$Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
3653
3654  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv4i32 ZPR32:$Op2), (nxv4i32 ZPR32:$Op3),
3655                         (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
3656            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR32:$Op2, ZPR32:$Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
3657}
3658
3659//===----------------------------------------------------------------------===//
3660// SVE2 Integer Multiply - Unpredicated Group
3661//===----------------------------------------------------------------------===//
3662
3663class sve2_int_mul<bits<2> sz, bits<3> opc, string asm, ZPRRegOp zprty>
3664: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
3665  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3666  bits<5> Zd;
3667  bits<5> Zm;
3668  bits<5> Zn;
3669  let Inst{31-24} = 0b00000100;
3670  let Inst{23-22} = sz;
3671  let Inst{21}    = 0b1;
3672  let Inst{20-16} = Zm;
3673  let Inst{15-13} = 0b011;
3674  let Inst{12-10} = opc;
3675  let Inst{9-5}   = Zn;
3676  let Inst{4-0}   = Zd;
3677
3678  let hasSideEffects = 0;
3679}
3680
3681multiclass sve2_int_mul<bits<3> opc, string asm, SDPatternOperator op,
3682                        SDPatternOperator op_pred = null_frag> {
3683  def _B : sve2_int_mul<0b00, opc, asm, ZPR8>;
3684  def _H : sve2_int_mul<0b01, opc, asm, ZPR16>;
3685  def _S : sve2_int_mul<0b10, opc, asm, ZPR32>;
3686  def _D : sve2_int_mul<0b11, opc, asm, ZPR64>;
3687
3688  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3689  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3690  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3691  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3692
3693  def : SVE_2_Op_Pred_Any_Predicate<nxv16i8, op_pred, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3694  def : SVE_2_Op_Pred_Any_Predicate<nxv8i16, op_pred, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3695  def : SVE_2_Op_Pred_Any_Predicate<nxv4i32, op_pred, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3696  def : SVE_2_Op_Pred_Any_Predicate<nxv2i64, op_pred, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3697}
3698
3699multiclass sve2_int_mul_single<bits<3> opc, string asm, SDPatternOperator op> {
3700  def _B : sve2_int_mul<0b00, opc, asm, ZPR8>;
3701
3702  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3703}
3704
3705//===----------------------------------------------------------------------===//
3706// SVE2 Integer Multiply - Indexed Group
3707//===----------------------------------------------------------------------===//
3708
3709class sve2_int_mul_by_indexed_elem<bits<2> sz, bits<4> opc, string asm,
3710                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3711                                   ZPRRegOp zprty3, Operand itype>
3712: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty3:$Zm, itype:$iop),
3713  asm, "\t$Zd, $Zn, $Zm$iop", "", []>, Sched<[]> {
3714  bits<5> Zd;
3715  bits<5> Zn;
3716  let Inst{31-24} = 0b01000100;
3717  let Inst{23-22} = sz;
3718  let Inst{21}    = 0b1;
3719  let Inst{15-14} = 0b11;
3720  let Inst{13-10} = opc;
3721  let Inst{9-5}   = Zn;
3722  let Inst{4-0}   = Zd;
3723
3724  let hasSideEffects = 0;
3725}
3726
3727multiclass sve2_int_mul_by_indexed_elem<bits<4> opc, string asm,
3728                                        SDPatternOperator op> {
3729  def _H : sve2_int_mul_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexH32b> {
3730    bits<3> Zm;
3731    bits<3> iop;
3732    let Inst{22} = iop{2};
3733    let Inst{20-19} = iop{1-0};
3734    let Inst{18-16} = Zm;
3735  }
3736  def _S : sve2_int_mul_by_indexed_elem<0b10, opc, asm, ZPR32, ZPR32, ZPR3b32, VectorIndexS32b> {
3737    bits<3> Zm;
3738    bits<2> iop;
3739    let Inst{20-19} = iop;
3740    let Inst{18-16} = Zm;
3741  }
3742  def _D : sve2_int_mul_by_indexed_elem<0b11, opc, asm, ZPR64, ZPR64, ZPR4b64, VectorIndexD32b> {
3743    bits<4> Zm;
3744    bit iop;
3745    let Inst{20} = iop;
3746    let Inst{19-16} = Zm;
3747  }
3748
3749  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
3750  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3751  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3752}
3753
3754multiclass sve2_int_mul_long_by_indexed_elem<bits<3> opc, string asm,
3755                                             SDPatternOperator op> {
3756  def _S : sve2_int_mul_by_indexed_elem<0b10, { opc{2-1}, ?, opc{0} }, asm,
3757                                        ZPR32, ZPR16, ZPR3b16, VectorIndexH32b> {
3758    bits<3> Zm;
3759    bits<3> iop;
3760    let Inst{20-19} = iop{2-1};
3761    let Inst{18-16} = Zm;
3762    let Inst{11} = iop{0};
3763  }
3764  def _D : sve2_int_mul_by_indexed_elem<0b11, { opc{2-1}, ?, opc{0} }, asm,
3765                                        ZPR64, ZPR32, ZPR4b32, VectorIndexS32b> {
3766    bits<4> Zm;
3767    bits<2> iop;
3768    let Inst{20} = iop{1};
3769    let Inst{19-16} = Zm;
3770    let Inst{11} = iop{0};
3771  }
3772
3773  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _S)>;
3774  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
3775}
3776
3777//===----------------------------------------------------------------------===//
3778// SVE2 Integer - Predicated Group
3779//===----------------------------------------------------------------------===//
3780
3781class sve2_int_arith_pred<bits<2> sz, bits<6> opc, string asm,
3782                          ZPRRegOp zprty>
3783: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
3784  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm", "", []>, Sched<[]> {
3785  bits<3> Pg;
3786  bits<5> Zm;
3787  bits<5> Zdn;
3788  let Inst{31-24} = 0b01000100;
3789  let Inst{23-22} = sz;
3790  let Inst{21-20} = 0b01;
3791  let Inst{20-16} = opc{5-1};
3792  let Inst{15-14} = 0b10;
3793  let Inst{13}    = opc{0};
3794  let Inst{12-10} = Pg;
3795  let Inst{9-5}   = Zm;
3796  let Inst{4-0}   = Zdn;
3797
3798  let Constraints = "$Zdn = $_Zdn";
3799  let DestructiveInstType = DestructiveOther;
3800  let ElementSize = zprty.ElementSize;
3801  let hasSideEffects = 0;
3802}
3803
3804multiclass sve2_int_arith_pred<bits<6> opc, string asm, SDPatternOperator op,
3805                               string Ps = "",
3806                               DestructiveInstTypeEnum flags=DestructiveOther,
3807                               string revname="", bit isReverseInstr=0> {
3808  let DestructiveInstType = flags in {
3809  def _B : sve2_int_arith_pred<0b00, opc, asm, ZPR8>,
3810           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3811  def _H : sve2_int_arith_pred<0b01, opc, asm, ZPR16>,
3812           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3813  def _S : sve2_int_arith_pred<0b10, opc, asm, ZPR32>,
3814           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3815  def _D : sve2_int_arith_pred<0b11, opc, asm, ZPR64>,
3816           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3817  }
3818
3819  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3820  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3821  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3822  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3823}
3824
3825class sve2_int_sadd_long_accum_pairwise<bits<2> sz, bit U, string asm,
3826                                        ZPRRegOp zprty1, ZPRRegOp zprty2>
3827: I<(outs zprty1:$Zda), (ins PPR3bAny:$Pg, zprty1:$_Zda, zprty2:$Zn),
3828  asm, "\t$Zda, $Pg/m, $Zn", "", []>, Sched<[]> {
3829  bits<3> Pg;
3830  bits<5> Zn;
3831  bits<5> Zda;
3832  let Inst{31-24} = 0b01000100;
3833  let Inst{23-22} = sz;
3834  let Inst{21-17} = 0b00010;
3835  let Inst{16}    = U;
3836  let Inst{15-13} = 0b101;
3837  let Inst{12-10} = Pg;
3838  let Inst{9-5}   = Zn;
3839  let Inst{4-0}   = Zda;
3840
3841  let Constraints = "$Zda = $_Zda";
3842  let DestructiveInstType = DestructiveOther;
3843  let ElementSize = zprty1.ElementSize;
3844  let hasSideEffects = 0;
3845}
3846
3847multiclass sve2_int_sadd_long_accum_pairwise<bit U, string asm, SDPatternOperator op> {
3848  def _H : sve2_int_sadd_long_accum_pairwise<0b01, U, asm, ZPR16, ZPR8>;
3849  def _S : sve2_int_sadd_long_accum_pairwise<0b10, U, asm, ZPR32, ZPR16>;
3850  def _D : sve2_int_sadd_long_accum_pairwise<0b11, U, asm, ZPR64, ZPR32>;
3851
3852  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv16i8, !cast<Instruction>(NAME # _H)>;
3853  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv8i16, !cast<Instruction>(NAME # _S)>;
3854  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv4i32, !cast<Instruction>(NAME # _D)>;
3855}
3856
3857class sve2_int_un_pred_arit<bits<2> sz, bit Q, bits<2> opc,
3858                            string asm, ZPRRegOp zprty>
3859: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
3860  asm, "\t$Zd, $Pg/m, $Zn",
3861  "",
3862  []>, Sched<[]> {
3863  bits<3> Pg;
3864  bits<5> Zd;
3865  bits<5> Zn;
3866  let Inst{31-24} = 0b01000100;
3867  let Inst{23-22} = sz;
3868  let Inst{21-20} = 0b00;
3869  let Inst{19}    = Q;
3870  let Inst{18}    = 0b0;
3871  let Inst{17-16} = opc;
3872  let Inst{15-13} = 0b101;
3873  let Inst{12-10} = Pg;
3874  let Inst{9-5}   = Zn;
3875  let Inst{4-0}   = Zd;
3876
3877  let Constraints = "$Zd = $_Zd";
3878  let DestructiveInstType = DestructiveUnaryPassthru;
3879  let ElementSize = zprty.ElementSize;
3880  let hasSideEffects = 0;
3881}
3882
3883multiclass sve2_int_un_pred_arit_s<bits<3> opc, string asm,
3884                                   SDPatternOperator op> {
3885  def _S : sve2_int_un_pred_arit<0b10, opc{2}, opc{1-0}, asm, ZPR32>,
3886           SVEPseudo2Instr<NAME # _S, 1>;
3887
3888  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
3889
3890  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
3891
3892  defm : SVE_3_Op_Undef_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
3893}
3894
3895multiclass sve2_int_un_pred_arit<bits<3> opc, string asm, SDPatternOperator op> {
3896  def _B : sve2_int_un_pred_arit<0b00, opc{2}, opc{1-0}, asm, ZPR8>,
3897           SVEPseudo2Instr<NAME # _B, 1>;
3898  def _H : sve2_int_un_pred_arit<0b01, opc{2}, opc{1-0}, asm, ZPR16>,
3899           SVEPseudo2Instr<NAME # _H, 1>;
3900  def _S : sve2_int_un_pred_arit<0b10, opc{2}, opc{1-0}, asm, ZPR32>,
3901           SVEPseudo2Instr<NAME # _S, 1>;
3902  def _D : sve2_int_un_pred_arit<0b11, opc{2}, opc{1-0}, asm, ZPR64>,
3903           SVEPseudo2Instr<NAME # _D, 1>;
3904
3905  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
3906  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
3907  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
3908  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
3909
3910  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
3911  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
3912  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
3913  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
3914
3915  defm : SVE_3_Op_Undef_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
3916  defm : SVE_3_Op_Undef_Pat<nxv8i16, op, nxv8i16, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
3917  defm : SVE_3_Op_Undef_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
3918  defm : SVE_3_Op_Undef_Pat<nxv2i64, op, nxv2i64, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
3919}
3920
3921//===----------------------------------------------------------------------===//
3922// SVE2 Widening Integer Arithmetic Group
3923//===----------------------------------------------------------------------===//
3924
3925class sve2_wide_int_arith<bits<2> sz, bits<5> opc, string asm,
3926                          ZPRRegOp zprty1, ZPRRegOp zprty2, ZPRRegOp zprty3>
3927: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty3:$Zm),
3928  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3929  bits<5> Zd;
3930  bits<5> Zn;
3931  bits<5> Zm;
3932  let Inst{31-24} = 0b01000101;
3933  let Inst{23-22} = sz;
3934  let Inst{21}    = 0b0;
3935  let Inst{20-16} = Zm;
3936  let Inst{15}    = 0b0;
3937  let Inst{14-10} = opc;
3938  let Inst{9-5}   = Zn;
3939  let Inst{4-0}   = Zd;
3940
3941  let hasSideEffects = 0;
3942}
3943
3944multiclass sve2_wide_int_arith_long<bits<5> opc, string asm,
3945                                    SDPatternOperator op> {
3946  def _H : sve2_wide_int_arith<0b01, opc, asm, ZPR16, ZPR8, ZPR8>;
3947  def _S : sve2_wide_int_arith<0b10, opc, asm, ZPR32, ZPR16, ZPR16>;
3948  def _D : sve2_wide_int_arith<0b11, opc, asm, ZPR64, ZPR32, ZPR32>;
3949
3950  def : SVE_2_Op_Pat<nxv8i16, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3951  def : SVE_2_Op_Pat<nxv4i32, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
3952  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3953}
3954
3955multiclass sve2_wide_int_arith_wide<bits<3> opc, string asm,
3956                                    SDPatternOperator op> {
3957  def _H : sve2_wide_int_arith<0b01, { 0b10, opc }, asm, ZPR16, ZPR16, ZPR8>;
3958  def _S : sve2_wide_int_arith<0b10, { 0b10, opc }, asm, ZPR32, ZPR32, ZPR16>;
3959  def _D : sve2_wide_int_arith<0b11, { 0b10, opc }, asm, ZPR64, ZPR64, ZPR32>;
3960
3961  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, !cast<Instruction>(NAME # _H)>;
3962  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, !cast<Instruction>(NAME # _S)>;
3963  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, !cast<Instruction>(NAME # _D)>;
3964}
3965
3966multiclass sve2_wide_int_arith_pmul<bits<2> sz, bits<5> opc, string asm,
3967                                     SDPatternOperator op> {
3968  def NAME : sve2_wide_int_arith<sz, opc, asm, ZPR128, ZPR64, ZPR64>;
3969
3970  // To avoid using 128 bit elements in the IR, the pattern below works with
3971  // llvm intrinsics with the _pair suffix, to reflect that
3972  // _Q is implemented as a pair of _D.
3973  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
3974}
3975
3976multiclass sve2_pmul_long<bits<1> opc, string asm, SDPatternOperator op> {
3977  def _H : sve2_wide_int_arith<0b01, {0b1101, opc}, asm, ZPR16, ZPR8, ZPR8>;
3978  def _D : sve2_wide_int_arith<0b11, {0b1101, opc}, asm, ZPR64, ZPR32, ZPR32>;
3979
3980  // To avoid using 128 bit elements in the IR, the patterns below work with
3981  // llvm intrinsics with the _pair suffix, to reflect that
3982  // _H is implemented as a pair of _B and _D is implemented as a pair of _S.
3983  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3984  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3985}
3986
3987//===----------------------------------------------------------------------===//
3988// SVE2 Misc Group
3989//===----------------------------------------------------------------------===//
3990
3991class sve2_misc<bits<2> sz, bits<4> opc, string asm,
3992                ZPRRegOp zprty1, ZPRRegOp zprty2>
3993: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty2:$Zm),
3994  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3995  bits<5> Zd;
3996  bits<5> Zn;
3997  bits<5> Zm;
3998  let Inst{31-24} = 0b01000101;
3999  let Inst{23-22} = sz;
4000  let Inst{21}    = 0b0;
4001  let Inst{20-16} = Zm;
4002  let Inst{15-14} = 0b10;
4003  let Inst{13-10} = opc;
4004  let Inst{9-5}   = Zn;
4005  let Inst{4-0}   = Zd;
4006
4007  let hasSideEffects = 0;
4008}
4009
4010multiclass sve2_misc_bitwise<bits<4> opc, string asm, SDPatternOperator op> {
4011  def _B : sve2_misc<0b00, opc, asm, ZPR8, ZPR8>;
4012  def _H : sve2_misc<0b01, opc, asm, ZPR16, ZPR16>;
4013  def _S : sve2_misc<0b10, opc, asm, ZPR32, ZPR32>;
4014  def _D : sve2_misc<0b11, opc, asm, ZPR64, ZPR64>;
4015
4016  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4017  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4018  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4019  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4020}
4021
4022multiclass sve2_misc_int_addsub_long_interleaved<bits<2> opc, string asm,
4023                                                 SDPatternOperator op> {
4024  def _H : sve2_misc<0b01, { 0b00, opc }, asm, ZPR16, ZPR8>;
4025  def _S : sve2_misc<0b10, { 0b00, opc }, asm, ZPR32, ZPR16>;
4026  def _D : sve2_misc<0b11, { 0b00, opc }, asm, ZPR64, ZPR32>;
4027
4028  def : SVE_2_Op_Pat<nxv8i16, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
4029  def : SVE_2_Op_Pat<nxv4i32, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
4030  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
4031}
4032
4033class sve2_bitwise_xor_interleaved<bits<2> sz, bits<1> opc, string asm,
4034                                   ZPRRegOp zprty1, ZPRRegOp zprty2>
4035: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, zprty2:$Zm),
4036  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4037  bits<5> Zd;
4038  bits<5> Zn;
4039  bits<5> Zm;
4040  let Inst{31-24} = 0b01000101;
4041  let Inst{23-22} = sz;
4042  let Inst{21}    = 0b0;
4043  let Inst{20-16} = Zm;
4044  let Inst{15-11} = 0b10010;
4045  let Inst{10}    = opc;
4046  let Inst{9-5}   = Zn;
4047  let Inst{4-0}   = Zd;
4048
4049  let Constraints = "$Zd = $_Zd";
4050  let DestructiveInstType = DestructiveOther;
4051  let ElementSize = ElementSizeNone;
4052  let hasSideEffects = 0;
4053}
4054
4055multiclass sve2_bitwise_xor_interleaved<bit opc, string asm,
4056                                        SDPatternOperator op> {
4057  def _B : sve2_bitwise_xor_interleaved<0b00, opc, asm, ZPR8,  ZPR8>;
4058  def _H : sve2_bitwise_xor_interleaved<0b01, opc, asm, ZPR16, ZPR16>;
4059  def _S : sve2_bitwise_xor_interleaved<0b10, opc, asm, ZPR32, ZPR32>;
4060  def _D : sve2_bitwise_xor_interleaved<0b11, opc, asm, ZPR64, ZPR64>;
4061
4062  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4063  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4064  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4065  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4066}
4067
4068class sve2_bitwise_shift_left_long<bits<3> tsz8_64, bits<2> opc, string asm,
4069                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
4070                                   Operand immtype>
4071: I<(outs zprty1:$Zd), (ins zprty2:$Zn, immtype:$imm),
4072  asm, "\t$Zd, $Zn, $imm",
4073  "", []>, Sched<[]> {
4074  bits<5> Zd;
4075  bits<5> Zn;
4076  bits<5> imm;
4077  let Inst{31-23} = 0b010001010;
4078  let Inst{22}    = tsz8_64{2};
4079  let Inst{21}    = 0b0;
4080  let Inst{20-19} = tsz8_64{1-0};
4081  let Inst{18-16} = imm{2-0}; // imm3
4082  let Inst{15-12} = 0b1010;
4083  let Inst{11-10} = opc;
4084  let Inst{9-5}   = Zn;
4085  let Inst{4-0}   = Zd;
4086
4087  let hasSideEffects = 0;
4088}
4089
4090multiclass sve2_bitwise_shift_left_long<bits<2> opc, string asm,
4091                                        SDPatternOperator op> {
4092  def _H : sve2_bitwise_shift_left_long<{0,0,1}, opc, asm,
4093                                        ZPR16, ZPR8, vecshiftL8>;
4094  def _S : sve2_bitwise_shift_left_long<{0,1,?}, opc, asm,
4095                                        ZPR32, ZPR16, vecshiftL16> {
4096    let Inst{19} = imm{3};
4097  }
4098  def _D : sve2_bitwise_shift_left_long<{1,?,?}, opc, asm,
4099                                        ZPR64, ZPR32, vecshiftL32> {
4100    let Inst{20-19} = imm{4-3};
4101  }
4102  def : SVE_2_Op_Imm_Pat<nxv8i16, op, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _H)>;
4103  def : SVE_2_Op_Imm_Pat<nxv4i32, op, nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _S)>;
4104  def : SVE_2_Op_Imm_Pat<nxv2i64, op, nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _D)>;
4105}
4106
4107//===----------------------------------------------------------------------===//
4108// SVE2 Accumulate Group
4109//===----------------------------------------------------------------------===//
4110
4111class sve2_int_bin_shift_imm<bits<4> tsz8_64, bit opc, string asm,
4112                             ZPRRegOp zprty, Operand immtype>
4113: I<(outs zprty:$Zd), (ins zprty:$_Zd, zprty:$Zn, immtype:$imm),
4114  asm, "\t$Zd, $Zn, $imm",
4115  "", []>, Sched<[]> {
4116  bits<5> Zd;
4117  bits<5> Zn;
4118  bits<6> imm;
4119  let Inst{31-24} = 0b01000101;
4120  let Inst{23-22} = tsz8_64{3-2};
4121  let Inst{21}    = 0b0;
4122  let Inst{20-19} = tsz8_64{1-0};
4123  let Inst{18-16} = imm{2-0}; // imm3
4124  let Inst{15-11} = 0b11110;
4125  let Inst{10}    = opc;
4126  let Inst{9-5}   = Zn;
4127  let Inst{4-0}   = Zd;
4128
4129  let Constraints = "$Zd = $_Zd";
4130  let hasSideEffects = 0;
4131}
4132
4133multiclass sve2_int_bin_shift_imm_left<bit opc, string asm,
4134                                       SDPatternOperator op> {
4135  def _B : sve2_int_bin_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
4136  def _H : sve2_int_bin_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
4137    let Inst{19} = imm{3};
4138  }
4139  def _S : sve2_int_bin_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
4140    let Inst{20-19} = imm{4-3};
4141  }
4142  def _D : sve2_int_bin_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
4143    let Inst{22}    = imm{5};
4144    let Inst{20-19} = imm{4-3};
4145  }
4146
4147  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _B)>;
4148  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _H)>;
4149  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _S)>;
4150  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftL64, !cast<Instruction>(NAME # _D)>;
4151}
4152
4153multiclass sve2_int_bin_shift_imm_right<bit opc, string asm,
4154                                        SDPatternOperator op> {
4155  def _B : sve2_int_bin_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
4156  def _H : sve2_int_bin_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
4157    let Inst{19} = imm{3};
4158  }
4159  def _S : sve2_int_bin_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
4160    let Inst{20-19} = imm{4-3};
4161  }
4162  def _D : sve2_int_bin_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
4163    let Inst{22}    = imm{5};
4164    let Inst{20-19} = imm{4-3};
4165  }
4166
4167  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4168  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4169  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4170  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4171}
4172
4173class sve2_int_bin_accum_shift_imm<bits<4> tsz8_64, bits<2> opc, string asm,
4174                                   ZPRRegOp zprty, Operand immtype>
4175: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, immtype:$imm),
4176  asm, "\t$Zda, $Zn, $imm",
4177  "", []>, Sched<[]> {
4178  bits<5> Zda;
4179  bits<5> Zn;
4180  bits<6> imm;
4181  let Inst{31-24} = 0b01000101;
4182  let Inst{23-22} = tsz8_64{3-2};
4183  let Inst{21}    = 0b0;
4184  let Inst{20-19} = tsz8_64{1-0};
4185  let Inst{18-16} = imm{2-0}; // imm3
4186  let Inst{15-12} = 0b1110;
4187  let Inst{11-10} = opc;
4188  let Inst{9-5}   = Zn;
4189  let Inst{4-0}   = Zda;
4190
4191  let Constraints = "$Zda = $_Zda";
4192  let DestructiveInstType = DestructiveOther;
4193  let ElementSize = ElementSizeNone;
4194  let hasSideEffects = 0;
4195}
4196
4197multiclass sve2_int_bin_accum_shift_imm_right<bits<2> opc, string asm,
4198                                              SDPatternOperator op,
4199                                              SDPatternOperator shift_op = null_frag> {
4200  def _B : sve2_int_bin_accum_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
4201  def _H : sve2_int_bin_accum_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
4202    let Inst{19} = imm{3};
4203  }
4204  def _S : sve2_int_bin_accum_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
4205    let Inst{20-19} = imm{4-3};
4206  }
4207  def _D : sve2_int_bin_accum_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
4208    let Inst{22}    = imm{5};
4209    let Inst{20-19} = imm{4-3};
4210  }
4211
4212  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4213  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4214  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4215  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4216
4217  def : SVE_Shift_Add_All_Active_Pat<nxv16i8, shift_op, nxv16i1, nxv16i8, nxv16i8, i32, !cast<Instruction>(NAME # _B)>;
4218  def : SVE_Shift_Add_All_Active_Pat<nxv8i16, shift_op, nxv8i1, nxv8i16, nxv8i16, i32, !cast<Instruction>(NAME # _H)>;
4219  def : SVE_Shift_Add_All_Active_Pat<nxv4i32, shift_op, nxv4i1, nxv4i32, nxv4i32, i32, !cast<Instruction>(NAME # _S)>;
4220  def : SVE_Shift_Add_All_Active_Pat<nxv2i64, shift_op, nxv2i1, nxv2i64, nxv2i64, i32, !cast<Instruction>(NAME # _D)>;
4221}
4222
4223class sve2_int_cadd<bits<2> sz, bit opc, string asm, ZPRRegOp zprty>
4224: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, complexrotateopodd:$rot),
4225  asm, "\t$Zdn, $_Zdn, $Zm, $rot", "", []>, Sched<[]> {
4226  bits<5> Zdn;
4227  bits<5> Zm;
4228  bit rot;
4229  let Inst{31-24} = 0b01000101;
4230  let Inst{23-22} = sz;
4231  let Inst{21-17} = 0b00000;
4232  let Inst{16}    = opc;
4233  let Inst{15-11} = 0b11011;
4234  let Inst{10}    = rot;
4235  let Inst{9-5}   = Zm;
4236  let Inst{4-0}   = Zdn;
4237
4238  let Constraints = "$Zdn = $_Zdn";
4239  let DestructiveInstType = DestructiveOther;
4240  let ElementSize = ElementSizeNone;
4241  let hasSideEffects = 0;
4242}
4243
4244multiclass sve2_int_cadd<bit opc, string asm, SDPatternOperator op> {
4245  def _B : sve2_int_cadd<0b00, opc, asm, ZPR8>;
4246  def _H : sve2_int_cadd<0b01, opc, asm, ZPR16>;
4247  def _S : sve2_int_cadd<0b10, opc, asm, ZPR32>;
4248  def _D : sve2_int_cadd<0b11, opc, asm, ZPR64>;
4249
4250  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, complexrotateopodd, !cast<Instruction>(NAME # _B)>;
4251  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, complexrotateopodd, !cast<Instruction>(NAME # _H)>;
4252  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, complexrotateopodd, !cast<Instruction>(NAME # _S)>;
4253  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, complexrotateopodd, !cast<Instruction>(NAME # _D)>;
4254}
4255
4256class sve2_int_absdiff_accum<bits<2> sz, bits<4> opc, string asm,
4257                             ZPRRegOp zprty1, ZPRRegOp zprty2>
4258: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm),
4259  asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
4260  bits<5> Zda;
4261  bits<5> Zn;
4262  bits<5> Zm;
4263  let Inst{31-24} = 0b01000101;
4264  let Inst{23-22} = sz;
4265  let Inst{21}    = 0b0;
4266  let Inst{20-16} = Zm;
4267  let Inst{15-14} = 0b11;
4268  let Inst{13-10} = opc;
4269  let Inst{9-5}   = Zn;
4270  let Inst{4-0}   = Zda;
4271
4272  let Constraints = "$Zda = $_Zda";
4273  let DestructiveInstType = DestructiveOther;
4274  let ElementSize = ElementSizeNone;
4275  let hasSideEffects = 0;
4276}
4277
4278multiclass sve2_int_absdiff_accum<bit opc, string asm, SDPatternOperator op> {
4279  def _B : sve2_int_absdiff_accum<0b00, { 0b111, opc }, asm, ZPR8, ZPR8>;
4280  def _H : sve2_int_absdiff_accum<0b01, { 0b111, opc }, asm, ZPR16, ZPR16>;
4281  def _S : sve2_int_absdiff_accum<0b10, { 0b111, opc }, asm, ZPR32, ZPR32>;
4282  def _D : sve2_int_absdiff_accum<0b11, { 0b111, opc }, asm, ZPR64, ZPR64>;
4283
4284  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4285  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4286  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4287  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4288}
4289
4290multiclass sve2_int_absdiff_accum_long<bits<2> opc, string asm,
4291                                       SDPatternOperator op> {
4292  def _H : sve2_int_absdiff_accum<0b01, { 0b00, opc }, asm, ZPR16, ZPR8>;
4293  def _S : sve2_int_absdiff_accum<0b10, { 0b00, opc }, asm, ZPR32, ZPR16>;
4294  def _D : sve2_int_absdiff_accum<0b11, { 0b00, opc }, asm, ZPR64, ZPR32>;
4295
4296  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
4297  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
4298  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
4299}
4300
4301multiclass sve2_int_addsub_long_carry<bits<2> opc, string asm,
4302                                      SDPatternOperator op> {
4303  def _S : sve2_int_absdiff_accum<{ opc{1}, 0b0 }, { 0b010, opc{0} }, asm,
4304                                  ZPR32, ZPR32>;
4305  def _D : sve2_int_absdiff_accum<{ opc{1}, 0b1 }, { 0b010, opc{0} }, asm,
4306                                  ZPR64, ZPR64>;
4307
4308  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4309  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4310}
4311
4312//===----------------------------------------------------------------------===//
4313// SVE2 Narrowing Group
4314//===----------------------------------------------------------------------===//
4315
4316class sve2_int_bin_shift_imm_narrow_bottom<bits<3> tsz8_64, bits<3> opc,
4317                                           string asm, ZPRRegOp zprty1,
4318                                           ZPRRegOp zprty2, Operand immtype>
4319: I<(outs zprty1:$Zd), (ins zprty2:$Zn, immtype:$imm),
4320  asm, "\t$Zd, $Zn, $imm",
4321  "", []>, Sched<[]> {
4322  bits<5> Zd;
4323  bits<5> Zn;
4324  bits<5> imm;
4325  let Inst{31-23} = 0b010001010;
4326  let Inst{22}    = tsz8_64{2};
4327  let Inst{21}    = 0b1;
4328  let Inst{20-19} = tsz8_64{1-0};
4329  let Inst{18-16} = imm{2-0}; // imm3
4330  let Inst{15-14} = 0b00;
4331  let Inst{13-11} = opc;
4332  let Inst{10}    = 0b0;
4333  let Inst{9-5}   = Zn;
4334  let Inst{4-0}   = Zd;
4335
4336  let hasSideEffects = 0;
4337}
4338
4339multiclass sve2_int_bin_shift_imm_right_narrow_bottom<bits<3> opc, string asm,
4340                                                      SDPatternOperator op> {
4341  def _B : sve2_int_bin_shift_imm_narrow_bottom<{0,0,1}, opc, asm, ZPR8, ZPR16,
4342                                                tvecshiftR8>;
4343  def _H : sve2_int_bin_shift_imm_narrow_bottom<{0,1,?}, opc, asm, ZPR16, ZPR32,
4344                                                tvecshiftR16> {
4345    let Inst{19} = imm{3};
4346  }
4347  def _S : sve2_int_bin_shift_imm_narrow_bottom<{1,?,?}, opc, asm, ZPR32, ZPR64,
4348                                                tvecshiftR32> {
4349    let Inst{20-19} = imm{4-3};
4350  }
4351  def : SVE_2_Op_Imm_Pat<nxv16i8, op, nxv8i16, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4352  def : SVE_2_Op_Imm_Pat<nxv8i16, op, nxv4i32, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4353  def : SVE_2_Op_Imm_Pat<nxv4i32, op, nxv2i64, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4354}
4355
4356class sve2_int_bin_shift_imm_narrow_top<bits<3> tsz8_64, bits<3> opc,
4357                                        string asm, ZPRRegOp zprty1,
4358                                        ZPRRegOp zprty2, Operand immtype>
4359: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, immtype:$imm),
4360  asm, "\t$Zd, $Zn, $imm",
4361  "", []>, Sched<[]> {
4362  bits<5> Zd;
4363  bits<5> Zn;
4364  bits<5> imm;
4365  let Inst{31-23} = 0b010001010;
4366  let Inst{22}    = tsz8_64{2};
4367  let Inst{21}    = 0b1;
4368  let Inst{20-19} = tsz8_64{1-0};
4369  let Inst{18-16} = imm{2-0}; // imm3
4370  let Inst{15-14} = 0b00;
4371  let Inst{13-11} = opc;
4372  let Inst{10}    = 0b1;
4373  let Inst{9-5}   = Zn;
4374  let Inst{4-0}   = Zd;
4375
4376  let Constraints = "$Zd = $_Zd";
4377  let hasSideEffects = 0;
4378}
4379
4380multiclass sve2_int_bin_shift_imm_right_narrow_top<bits<3> opc, string asm,
4381                                                   SDPatternOperator op> {
4382  def _B : sve2_int_bin_shift_imm_narrow_top<{0,0,1}, opc, asm, ZPR8, ZPR16,
4383                                             tvecshiftR8>;
4384  def _H : sve2_int_bin_shift_imm_narrow_top<{0,1,?}, opc, asm, ZPR16, ZPR32,
4385                                             tvecshiftR16> {
4386    let Inst{19} = imm{3};
4387  }
4388  def _S : sve2_int_bin_shift_imm_narrow_top<{1,?,?}, opc, asm, ZPR32, ZPR64,
4389                                             tvecshiftR32> {
4390    let Inst{20-19} = imm{4-3};
4391  }
4392  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv8i16, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4393  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv4i32, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4394  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv2i64, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4395}
4396
4397class sve2_int_addsub_narrow_high_bottom<bits<2> sz, bits<2> opc, string asm,
4398                                         ZPRRegOp zprty1, ZPRRegOp zprty2>
4399: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty2:$Zm),
4400  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4401  bits<5> Zd;
4402  bits<5> Zn;
4403  bits<5> Zm;
4404  let Inst{31-24} = 0b01000101;
4405  let Inst{23-22} = sz;
4406  let Inst{21}    = 0b1;
4407  let Inst{20-16} = Zm;
4408  let Inst{15-13} = 0b011;
4409  let Inst{12-11} = opc; // S, R
4410  let Inst{10}    = 0b0; // Top
4411  let Inst{9-5}   = Zn;
4412  let Inst{4-0}   = Zd;
4413
4414  let hasSideEffects = 0;
4415}
4416
4417multiclass sve2_int_addsub_narrow_high_bottom<bits<2> opc, string asm,
4418                                              SDPatternOperator op> {
4419  def _B : sve2_int_addsub_narrow_high_bottom<0b01, opc, asm, ZPR8, ZPR16>;
4420  def _H : sve2_int_addsub_narrow_high_bottom<0b10, opc, asm, ZPR16, ZPR32>;
4421  def _S : sve2_int_addsub_narrow_high_bottom<0b11, opc, asm, ZPR32, ZPR64>;
4422
4423  def : SVE_2_Op_Pat<nxv16i8, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _B)>;
4424  def : SVE_2_Op_Pat<nxv8i16, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _H)>;
4425  def : SVE_2_Op_Pat<nxv4i32, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _S)>;
4426}
4427
4428class sve2_int_addsub_narrow_high_top<bits<2> sz, bits<2> opc, string asm,
4429                                      ZPRRegOp zprty1, ZPRRegOp zprty2>
4430: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, zprty2:$Zm),
4431  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4432  bits<5> Zd;
4433  bits<5> Zn;
4434  bits<5> Zm;
4435  let Inst{31-24} = 0b01000101;
4436  let Inst{23-22} = sz;
4437  let Inst{21}    = 0b1;
4438  let Inst{20-16} = Zm;
4439  let Inst{15-13} = 0b011;
4440  let Inst{12-11} = opc; // S, R
4441  let Inst{10}    = 0b1; // Top
4442  let Inst{9-5}   = Zn;
4443  let Inst{4-0}   = Zd;
4444
4445  let Constraints = "$Zd = $_Zd";
4446  let hasSideEffects = 0;
4447}
4448
4449multiclass sve2_int_addsub_narrow_high_top<bits<2> opc, string asm,
4450                                           SDPatternOperator op> {
4451  def _B : sve2_int_addsub_narrow_high_top<0b01, opc, asm, ZPR8, ZPR16>;
4452  def _H : sve2_int_addsub_narrow_high_top<0b10, opc, asm, ZPR16, ZPR32>;
4453  def _S : sve2_int_addsub_narrow_high_top<0b11, opc, asm, ZPR32, ZPR64>;
4454
4455  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _B)>;
4456  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _H)>;
4457  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _S)>;
4458}
4459
4460class sve2_int_sat_extract_narrow_bottom<bits<3> tsz8_64, bits<2> opc, string asm,
4461                                         ZPRRegOp zprty1, ZPRRegOp zprty2>
4462: I<(outs zprty1:$Zd), (ins zprty2:$Zn),
4463  asm, "\t$Zd, $Zn", "", []>, Sched<[]> {
4464  bits<5> Zd;
4465  bits<5> Zn;
4466  let Inst{31-23} = 0b010001010;
4467  let Inst{22}    = tsz8_64{2};
4468  let Inst{21}    = 0b1;
4469  let Inst{20-19} = tsz8_64{1-0};
4470  let Inst{18-13} = 0b000010;
4471  let Inst{12-11} = opc;
4472  let Inst{10}    = 0b0;
4473  let Inst{9-5}   = Zn;
4474  let Inst{4-0}   = Zd;
4475
4476  let hasSideEffects = 0;
4477}
4478
4479multiclass sve2_int_sat_extract_narrow_bottom<bits<2> opc, string asm,
4480                                              SDPatternOperator op> {
4481  def _B : sve2_int_sat_extract_narrow_bottom<0b001, opc, asm, ZPR8, ZPR16>;
4482  def _H : sve2_int_sat_extract_narrow_bottom<0b010, opc, asm, ZPR16, ZPR32>;
4483  def _S : sve2_int_sat_extract_narrow_bottom<0b100, opc, asm, ZPR32, ZPR64>;
4484
4485  def : SVE_1_Op_Pat<nxv16i8, op, nxv8i16, !cast<Instruction>(NAME # _B)>;
4486  def : SVE_1_Op_Pat<nxv8i16, op, nxv4i32, !cast<Instruction>(NAME # _H)>;
4487  def : SVE_1_Op_Pat<nxv4i32, op, nxv2i64, !cast<Instruction>(NAME # _S)>;
4488}
4489
4490class sve2_int_sat_extract_narrow_top<bits<3> tsz8_64, bits<2> opc, string asm,
4491                                      ZPRRegOp zprty1, ZPRRegOp zprty2>
4492: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn),
4493  asm, "\t$Zd, $Zn", "", []>, Sched<[]> {
4494  bits<5> Zd;
4495  bits<5> Zn;
4496  let Inst{31-23} = 0b010001010;
4497  let Inst{22}    = tsz8_64{2};
4498  let Inst{21}    = 0b1;
4499  let Inst{20-19} = tsz8_64{1-0};
4500  let Inst{18-13} = 0b000010;
4501  let Inst{12-11} = opc;
4502  let Inst{10}    = 0b1;
4503  let Inst{9-5}   = Zn;
4504  let Inst{4-0}   = Zd;
4505
4506  let Constraints = "$Zd = $_Zd";
4507  let hasSideEffects = 0;
4508}
4509
4510multiclass sve2_int_sat_extract_narrow_top<bits<2> opc, string asm,
4511                                           SDPatternOperator op> {
4512  def _B : sve2_int_sat_extract_narrow_top<0b001, opc, asm, ZPR8, ZPR16>;
4513  def _H : sve2_int_sat_extract_narrow_top<0b010, opc, asm, ZPR16, ZPR32>;
4514  def _S : sve2_int_sat_extract_narrow_top<0b100, opc, asm, ZPR32, ZPR64>;
4515
4516  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv8i16, !cast<Instruction>(NAME # _B)>;
4517  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv4i32, !cast<Instruction>(NAME # _H)>;
4518  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
4519}
4520
4521//===----------------------------------------------------------------------===//
4522// SVE Integer Arithmetic - Unary Predicated Group
4523//===----------------------------------------------------------------------===//
4524
4525class sve_int_un_pred_arit<bits<2> sz8_64, bits<4> opc,
4526                             string asm, ZPRRegOp zprty>
4527: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
4528  asm, "\t$Zd, $Pg/m, $Zn",
4529  "",
4530  []>, Sched<[]> {
4531  bits<3> Pg;
4532  bits<5> Zd;
4533  bits<5> Zn;
4534  let Inst{31-24} = 0b00000100;
4535  let Inst{23-22} = sz8_64;
4536  let Inst{21-20} = 0b01;
4537  let Inst{19}    = opc{0};
4538  let Inst{18-16} = opc{3-1};
4539  let Inst{15-13} = 0b101;
4540  let Inst{12-10} = Pg;
4541  let Inst{9-5}   = Zn;
4542  let Inst{4-0}   = Zd;
4543
4544  let Constraints = "$Zd = $_Zd";
4545  let DestructiveInstType = DestructiveUnaryPassthru;
4546  let ElementSize = zprty.ElementSize;
4547  let hasSideEffects = 0;
4548}
4549
4550multiclass sve_int_un_pred_arit_0<bits<3> opc, string asm,
4551                                  SDPatternOperator op> {
4552  def _B : sve_int_un_pred_arit<0b00, { opc, 0b0 }, asm, ZPR8>,
4553           SVEPseudo2Instr<NAME # _B, 1>;
4554  def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>,
4555           SVEPseudo2Instr<NAME # _H, 1>;
4556  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4557           SVEPseudo2Instr<NAME # _S, 1>;
4558  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4559           SVEPseudo2Instr<NAME # _D, 1>;
4560
4561  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
4562  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
4563  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
4564  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
4565
4566  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
4567  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4568  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4569  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4570
4571  defm : SVE_1_Op_PassthruUndef_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
4572  defm : SVE_1_Op_PassthruUndef_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4573  defm : SVE_1_Op_PassthruUndef_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4574  defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4575}
4576
4577multiclass sve_int_un_pred_arit_0_h<bits<3> opc, string asm,
4578                                    SDPatternOperator op> {
4579  def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>,
4580           SVEPseudo2Instr<NAME # _H, 1>;
4581  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4582           SVEPseudo2Instr<NAME # _S, 1>;
4583  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4584           SVEPseudo2Instr<NAME # _D, 1>;
4585
4586  def : SVE_InReg_Extend<nxv8i16, op, nxv8i1, nxv8i8, !cast<Instruction>(NAME # _H)>;
4587  def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i8, !cast<Instruction>(NAME # _S)>;
4588  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i8, !cast<Instruction>(NAME # _D)>;
4589
4590  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4591  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4592  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4593
4594  defm : SVE_InReg_Extend_PassthruUndef<nxv8i16, op, nxv8i1, nxv8i8, !cast<Pseudo>(NAME # _H_UNDEF)>;
4595  defm : SVE_InReg_Extend_PassthruUndef<nxv4i32, op, nxv4i1, nxv4i8, !cast<Pseudo>(NAME # _S_UNDEF)>;
4596  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i8, !cast<Pseudo>(NAME # _D_UNDEF)>;
4597}
4598
4599multiclass sve_int_un_pred_arit_0_w<bits<3> opc, string asm,
4600                                    SDPatternOperator op> {
4601  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4602           SVEPseudo2Instr<NAME # _S, 1>;
4603  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4604           SVEPseudo2Instr<NAME # _D, 1>;
4605
4606  def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i16, !cast<Instruction>(NAME # _S)>;
4607  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i16, !cast<Instruction>(NAME # _D)>;
4608
4609  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4610  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4611
4612  defm : SVE_InReg_Extend_PassthruUndef<nxv4i32, op, nxv4i1, nxv4i16, !cast<Pseudo>(NAME # _S_UNDEF)>;
4613  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i16, !cast<Pseudo>(NAME # _D_UNDEF)>;
4614}
4615
4616multiclass sve_int_un_pred_arit_0_d<bits<3> opc, string asm,
4617                                    SDPatternOperator op> {
4618  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4619           SVEPseudo2Instr<NAME # _D, 1>;
4620
4621  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i32, !cast<Instruction>(NAME # _D)>;
4622
4623  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4624
4625  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i32, !cast<Pseudo>(NAME # _D_UNDEF)>;
4626}
4627
4628multiclass sve_int_un_pred_arit_1<bits<3> opc, string asm,
4629                                  SDPatternOperator op> {
4630  def _B : sve_int_un_pred_arit<0b00, { opc, 0b1 }, asm, ZPR8>,
4631           SVEPseudo2Instr<NAME # _B, 1>;
4632  def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>,
4633           SVEPseudo2Instr<NAME # _H, 1>;
4634  def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>,
4635           SVEPseudo2Instr<NAME # _S, 1>;
4636  def _D : sve_int_un_pred_arit<0b11, { opc, 0b1 }, asm, ZPR64>,
4637           SVEPseudo2Instr<NAME # _D, 1>;
4638
4639  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
4640  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
4641  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
4642  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
4643
4644  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
4645  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4646  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4647  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4648
4649  defm : SVE_1_Op_PassthruUndef_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
4650  defm : SVE_1_Op_PassthruUndef_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4651  defm : SVE_1_Op_PassthruUndef_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4652  defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4653}
4654
4655multiclass sve_int_un_pred_arit_1_fp<bits<3> opc, string asm, SDPatternOperator op> {
4656  def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>,
4657           SVEPseudo2Instr<NAME # _H, 1>;
4658  def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>,
4659           SVEPseudo2Instr<NAME # _S, 1>;
4660  def _D : sve_int_un_pred_arit<0b11, { opc, 0b1 }, asm, ZPR64>,
4661           SVEPseudo2Instr<NAME # _D, 1>;
4662
4663  def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
4664  def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
4665  def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
4666  def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
4667  def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
4668  def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
4669
4670  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4671  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4672  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4673
4674  defm : SVE_1_Op_PassthruUndef_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4675  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4676  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4677  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4678  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4679  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4680}
4681
4682//===----------------------------------------------------------------------===//
4683// SVE Integer Wide Immediate - Unpredicated Group
4684//===----------------------------------------------------------------------===//
4685class sve_int_dup_imm<bits<2> sz8_64, string asm,
4686                      ZPRRegOp zprty, Operand immtype>
4687: I<(outs zprty:$Zd), (ins immtype:$imm),
4688  asm, "\t$Zd, $imm",
4689  "",
4690  []>, Sched<[]> {
4691  bits<5> Zd;
4692  bits<9> imm;
4693  let Inst{31-24} = 0b00100101;
4694  let Inst{23-22} = sz8_64;
4695  let Inst{21-14} = 0b11100011;
4696  let Inst{13}    = imm{8};   // sh
4697  let Inst{12-5}  = imm{7-0}; // imm8
4698  let Inst{4-0}   = Zd;
4699
4700  let hasSideEffects = 0;
4701  let isReMaterializable = 1;
4702}
4703
4704multiclass sve_int_dup_imm<string asm> {
4705  def _B : sve_int_dup_imm<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8>;
4706  def _H : sve_int_dup_imm<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16>;
4707  def _S : sve_int_dup_imm<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32>;
4708  def _D : sve_int_dup_imm<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64>;
4709
4710  def : InstAlias<"mov $Zd, $imm",
4711                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, cpy_imm8_opt_lsl_i8:$imm), 1>;
4712  def : InstAlias<"mov $Zd, $imm",
4713                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, cpy_imm8_opt_lsl_i16:$imm), 1>;
4714  def : InstAlias<"mov $Zd, $imm",
4715                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, cpy_imm8_opt_lsl_i32:$imm), 1>;
4716  def : InstAlias<"mov $Zd, $imm",
4717                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, cpy_imm8_opt_lsl_i64:$imm), 1>;
4718
4719  def : InstAlias<"fmov $Zd, #0.0",
4720                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, 0, 0), 1>;
4721  def : InstAlias<"fmov $Zd, #0.0",
4722                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, 0, 0), 1>;
4723  def : InstAlias<"fmov $Zd, #0.0",
4724                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, 0, 0), 1>;
4725}
4726
4727class sve_int_dup_fpimm<bits<2> sz8_64, Operand fpimmtype,
4728                        string asm, ZPRRegOp zprty>
4729: I<(outs zprty:$Zd), (ins fpimmtype:$imm8),
4730  asm, "\t$Zd, $imm8",
4731  "",
4732  []>, Sched<[]> {
4733  bits<5> Zd;
4734  bits<8> imm8;
4735  let Inst{31-24} = 0b00100101;
4736  let Inst{23-22} = sz8_64;
4737  let Inst{21-14} = 0b11100111;
4738  let Inst{13}    = 0b0;
4739  let Inst{12-5}  = imm8;
4740  let Inst{4-0}   = Zd;
4741
4742  let hasSideEffects = 0;
4743  let isReMaterializable = 1;
4744}
4745
4746multiclass sve_int_dup_fpimm<string asm> {
4747  def _H : sve_int_dup_fpimm<0b01, fpimm16, asm, ZPR16>;
4748  def _S : sve_int_dup_fpimm<0b10, fpimm32, asm, ZPR32>;
4749  def _D : sve_int_dup_fpimm<0b11, fpimm64, asm, ZPR64>;
4750
4751  def : InstAlias<"fmov $Zd, $imm8",
4752                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, fpimm16:$imm8), 1>;
4753  def : InstAlias<"fmov $Zd, $imm8",
4754                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, fpimm32:$imm8), 1>;
4755  def : InstAlias<"fmov $Zd, $imm8",
4756                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, fpimm64:$imm8), 1>;
4757}
4758
4759class sve_int_arith_imm0<bits<2> sz8_64, bits<3> opc, string asm,
4760                         ZPRRegOp zprty, Operand immtype>
4761: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, immtype:$imm),
4762  asm, "\t$Zdn, $_Zdn, $imm",
4763  "",
4764  []>, Sched<[]> {
4765  bits<5> Zdn;
4766  bits<9> imm;
4767  let Inst{31-24} = 0b00100101;
4768  let Inst{23-22} = sz8_64;
4769  let Inst{21-19} = 0b100;
4770  let Inst{18-16} = opc;
4771  let Inst{15-14} = 0b11;
4772  let Inst{13}    = imm{8};   // sh
4773  let Inst{12-5}  = imm{7-0}; // imm8
4774  let Inst{4-0}   = Zdn;
4775
4776  let Constraints = "$Zdn = $_Zdn";
4777  let DestructiveInstType = DestructiveOther;
4778  let ElementSize = ElementSizeNone;
4779  let hasSideEffects = 0;
4780}
4781
4782multiclass sve_int_arith_imm0<bits<3> opc, string asm, SDPatternOperator op> {
4783  def _B : sve_int_arith_imm0<0b00, opc, asm, ZPR8,  addsub_imm8_opt_lsl_i8>;
4784  def _H : sve_int_arith_imm0<0b01, opc, asm, ZPR16, addsub_imm8_opt_lsl_i16>;
4785  def _S : sve_int_arith_imm0<0b10, opc, asm, ZPR32, addsub_imm8_opt_lsl_i32>;
4786  def _D : sve_int_arith_imm0<0b11, opc, asm, ZPR64, addsub_imm8_opt_lsl_i64>;
4787
4788  def : SVE_1_Op_Imm_OptLsl_Pat<nxv16i8, op, ZPR8,  i32, SVEAddSubImm8Pat,  !cast<Instruction>(NAME # _B)>;
4789  def : SVE_1_Op_Imm_OptLsl_Pat<nxv8i16, op, ZPR16, i32, SVEAddSubImm16Pat, !cast<Instruction>(NAME # _H)>;
4790  def : SVE_1_Op_Imm_OptLsl_Pat<nxv4i32, op, ZPR32, i32, SVEAddSubImm32Pat, !cast<Instruction>(NAME # _S)>;
4791  def : SVE_1_Op_Imm_OptLsl_Pat<nxv2i64, op, ZPR64, i64, SVEAddSubImm64Pat, !cast<Instruction>(NAME # _D)>;
4792}
4793
4794class sve_int_arith_imm<bits<2> sz8_64, bits<6> opc, string asm,
4795                        ZPRRegOp zprty, Operand immtype>
4796: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, immtype:$imm),
4797  asm, "\t$Zdn, $_Zdn, $imm",
4798  "",
4799  []>, Sched<[]> {
4800  bits<5> Zdn;
4801  bits<8> imm;
4802  let Inst{31-24} = 0b00100101;
4803  let Inst{23-22} = sz8_64;
4804  let Inst{21-16} = opc;
4805  let Inst{15-13} = 0b110;
4806  let Inst{12-5} = imm;
4807  let Inst{4-0} = Zdn;
4808
4809  let Constraints = "$Zdn = $_Zdn";
4810  let DestructiveInstType = DestructiveOther;
4811  let ElementSize = ElementSizeNone;
4812  let hasSideEffects = 0;
4813}
4814
4815multiclass sve_int_arith_imm1<bits<2> opc, string asm, SDPatternOperator op> {
4816  def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, simm8_32b>;
4817  def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, simm8_32b>;
4818  def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, simm8_32b>;
4819  def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, simm8_32b>;
4820
4821  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B)>;
4822  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1,  op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H)>;
4823  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1,  op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S)>;
4824  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1,  op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D)>;
4825}
4826
4827multiclass sve_int_arith_imm1_unsigned<bits<2> opc, string asm, SDPatternOperator op> {
4828  def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, imm0_255>;
4829  def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, imm0_255>;
4830  def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, imm0_255>;
4831  def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, imm0_255>;
4832
4833  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithUImm8Pat, !cast<Instruction>(NAME # _B)>;
4834  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithUImm16Pat, !cast<Instruction>(NAME # _H)>;
4835  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithUImm32Pat, !cast<Instruction>(NAME # _S)>;
4836  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithUImm64Pat, !cast<Instruction>(NAME # _D)>;
4837}
4838
4839multiclass sve_int_arith_imm2<string asm, SDPatternOperator op> {
4840  def _B : sve_int_arith_imm<0b00, 0b110000, asm, ZPR8,  simm8_32b>;
4841  def _H : sve_int_arith_imm<0b01, 0b110000, asm, ZPR16, simm8_32b>;
4842  def _S : sve_int_arith_imm<0b10, 0b110000, asm, ZPR32, simm8_32b>;
4843  def _D : sve_int_arith_imm<0b11, 0b110000, asm, ZPR64, simm8_32b>;
4844
4845  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B)>;
4846  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H)>;
4847  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S)>;
4848  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D)>;
4849}
4850
4851//===----------------------------------------------------------------------===//
4852// SVE Bitwise Logical - Unpredicated Group
4853//===----------------------------------------------------------------------===//
4854
4855class sve_int_bin_cons_log<bits<2> opc, string asm>
4856: I<(outs ZPR64:$Zd), (ins ZPR64:$Zn, ZPR64:$Zm),
4857  asm, "\t$Zd, $Zn, $Zm",
4858  "",
4859  []>, Sched<[]> {
4860  bits<5> Zd;
4861  bits<5> Zm;
4862  bits<5> Zn;
4863  let Inst{31-24} = 0b00000100;
4864  let Inst{23-22} = opc{1-0};
4865  let Inst{21}    = 0b1;
4866  let Inst{20-16} = Zm;
4867  let Inst{15-10} = 0b001100;
4868  let Inst{9-5}   = Zn;
4869  let Inst{4-0}   = Zd;
4870
4871  let hasSideEffects = 0;
4872}
4873
4874multiclass sve_int_bin_cons_log<bits<2> opc, string asm, SDPatternOperator op> {
4875  def NAME : sve_int_bin_cons_log<opc, asm>;
4876
4877  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
4878  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
4879  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
4880  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4881
4882  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4883                  (!cast<Instruction>(NAME) ZPR8:$Zd,  ZPR8:$Zn,  ZPR8:$Zm),  1>;
4884  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4885                  (!cast<Instruction>(NAME) ZPR16:$Zd, ZPR16:$Zn, ZPR16:$Zm), 1>;
4886  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4887                  (!cast<Instruction>(NAME) ZPR32:$Zd, ZPR32:$Zn, ZPR32:$Zm), 1>;
4888}
4889
4890class sve2_int_bitwise_ternary_op_d<bits<3> opc, string asm>
4891: I<(outs ZPR64:$Zdn), (ins ZPR64:$_Zdn, ZPR64:$Zm, ZPR64:$Zk),
4892  asm, "\t$Zdn, $_Zdn, $Zm, $Zk",
4893  "",
4894  []>, Sched<[]> {
4895  bits<5> Zdn;
4896  bits<5> Zk;
4897  bits<5> Zm;
4898  let Inst{31-24} = 0b00000100;
4899  let Inst{23-22} = opc{2-1};
4900  let Inst{21}    = 0b1;
4901  let Inst{20-16} = Zm;
4902  let Inst{15-11} = 0b00111;
4903  let Inst{10}    = opc{0};
4904  let Inst{9-5}   = Zk;
4905  let Inst{4-0}   = Zdn;
4906
4907  let Constraints = "$Zdn = $_Zdn";
4908  let DestructiveInstType = DestructiveOther;
4909  let ElementSize = ElementSizeNone;
4910  let hasSideEffects = 0;
4911}
4912
4913multiclass sve2_int_bitwise_ternary_op<bits<3> opc, string asm, SDPatternOperator op,
4914                                       SDPatternOperator ir_op = null_frag> {
4915  def NAME : sve2_int_bitwise_ternary_op_d<opc, asm>;
4916
4917  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4918                  (!cast<Instruction>(NAME) ZPR8:$Zdn,  ZPR8:$Zm,  ZPR8:$Zk),  1>;
4919  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4920                  (!cast<Instruction>(NAME) ZPR16:$Zdn, ZPR16:$Zm, ZPR16:$Zk), 1>;
4921  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4922                  (!cast<Instruction>(NAME) ZPR32:$Zdn, ZPR32:$Zm, ZPR32:$Zk), 1>;
4923
4924  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
4925  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
4926  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
4927  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4928
4929
4930  def : SVE_3_Op_BSP_Pat<nxv16i8, ir_op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
4931  def : SVE_3_Op_BSP_Pat<nxv8i16, ir_op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
4932  def : SVE_3_Op_BSP_Pat<nxv4i32, ir_op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
4933  def : SVE_3_Op_BSP_Pat<nxv2i64, ir_op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4934}
4935
4936class sve2_int_rotate_right_imm<bits<4> tsz8_64, string asm,
4937                                ZPRRegOp zprty, Operand immtype>
4938: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, immtype:$imm),
4939  asm, "\t$Zdn, $_Zdn, $Zm, $imm",
4940  "",
4941  []>, Sched<[]> {
4942  bits<5> Zdn;
4943  bits<5> Zm;
4944  bits<6> imm;
4945  let Inst{31-24} = 0b00000100;
4946  let Inst{23-22} = tsz8_64{3-2};
4947  let Inst{21}    = 0b1;
4948  let Inst{20-19} = tsz8_64{1-0};
4949  let Inst{18-16} = imm{2-0}; // imm3
4950  let Inst{15-10} = 0b001101;
4951  let Inst{9-5}   = Zm;
4952  let Inst{4-0}   = Zdn;
4953
4954  let Constraints = "$Zdn = $_Zdn";
4955  let DestructiveInstType = DestructiveOther;
4956  let ElementSize = ElementSizeNone;
4957  let hasSideEffects = 0;
4958}
4959
4960multiclass sve2_int_rotate_right_imm<string asm, SDPatternOperator op> {
4961  def _B : sve2_int_rotate_right_imm<{0,0,0,1}, asm, ZPR8, vecshiftR8>;
4962  def _H : sve2_int_rotate_right_imm<{0,0,1,?}, asm, ZPR16, vecshiftR16> {
4963    let Inst{19} = imm{3};
4964  }
4965  def _S : sve2_int_rotate_right_imm<{0,1,?,?}, asm, ZPR32, vecshiftR32> {
4966    let Inst{20-19} = imm{4-3};
4967  }
4968  def _D : sve2_int_rotate_right_imm<{1,?,?,?}, asm, ZPR64, vecshiftR64> {
4969    let Inst{22}    = imm{5};
4970    let Inst{20-19} = imm{4-3};
4971  }
4972
4973  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4974  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4975  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4976  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4977}
4978
4979//===----------------------------------------------------------------------===//
4980// SVE Integer Wide Immediate - Predicated Group
4981//===----------------------------------------------------------------------===//
4982
4983class sve_int_dup_fpimm_pred<bits<2> sz, Operand fpimmtype,
4984                             string asm, ZPRRegOp zprty>
4985: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPRAny:$Pg, fpimmtype:$imm8),
4986  asm, "\t$Zd, $Pg/m, $imm8",
4987  "",
4988  []>, Sched<[]> {
4989  bits<4> Pg;
4990  bits<5> Zd;
4991  bits<8> imm8;
4992  let Inst{31-24} = 0b00000101;
4993  let Inst{23-22} = sz;
4994  let Inst{21-20} = 0b01;
4995  let Inst{19-16} = Pg;
4996  let Inst{15-13} = 0b110;
4997  let Inst{12-5}  = imm8;
4998  let Inst{4-0}   = Zd;
4999
5000  let Constraints = "$Zd = $_Zd";
5001  let DestructiveInstType = DestructiveOther;
5002  let ElementSize = zprty.ElementSize;
5003  let hasSideEffects = 0;
5004}
5005
5006multiclass sve_int_dup_fpimm_pred<string asm> {
5007  def _H : sve_int_dup_fpimm_pred<0b01, fpimm16, asm, ZPR16>;
5008  def _S : sve_int_dup_fpimm_pred<0b10, fpimm32, asm, ZPR32>;
5009  def _D : sve_int_dup_fpimm_pred<0b11, fpimm64, asm, ZPR64>;
5010
5011  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
5012                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, fpimm16:$imm8), 1>;
5013  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
5014                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, fpimm32:$imm8), 1>;
5015  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
5016                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, fpimm64:$imm8), 1>;
5017}
5018
5019class sve_int_dup_imm_pred<bits<2> sz8_64, bit m, string asm,
5020                           ZPRRegOp zprty, string pred_qual, dag iops>
5021: I<(outs zprty:$Zd), iops,
5022  asm, "\t$Zd, $Pg"#pred_qual#", $imm",
5023  "", []>, Sched<[]> {
5024  bits<5> Zd;
5025  bits<4> Pg;
5026  bits<9> imm;
5027  let Inst{31-24} = 0b00000101;
5028  let Inst{23-22} = sz8_64;
5029  let Inst{21-20} = 0b01;
5030  let Inst{19-16} = Pg;
5031  let Inst{15}    = 0b0;
5032  let Inst{14}    = m;
5033  let Inst{13}    = imm{8};   // sh
5034  let Inst{12-5}  = imm{7-0}; // imm8
5035  let Inst{4-0}   = Zd;
5036
5037  let DestructiveInstType = DestructiveOther;
5038  let ElementSize = zprty.ElementSize;
5039  let hasSideEffects = 0;
5040}
5041
5042multiclass sve_int_dup_imm_pred_merge_inst<
5043    bits<2> sz8_64, string asm, ZPRRegOp zprty, imm8_opt_lsl cpyimm,
5044    ValueType intty, ValueType predty, ValueType scalarty, ComplexPattern cpx> {
5045  let Constraints = "$Zd = $_Zd" in
5046  def NAME : sve_int_dup_imm_pred<sz8_64, 1, asm, zprty,  "/m",
5047                                  (ins zprty:$_Zd, PPRAny:$Pg, cpyimm:$imm)>;
5048  def : InstAlias<"mov $Zd, $Pg/m, $imm",
5049                  (!cast<Instruction>(NAME) zprty:$Zd, PPRAny:$Pg, cpyimm:$imm), 1>;
5050  def : Pat<(vselect predty:$Pg,
5051                (intty (splat_vector (scalarty (cpx i32:$imm, i32:$shift)))),
5052                ZPR:$Zd),
5053            (!cast<Instruction>(NAME) $Zd, $Pg, $imm, $shift)>;
5054}
5055
5056multiclass sve_int_dup_imm_pred_merge<string asm> {
5057  defm _B : sve_int_dup_imm_pred_merge_inst<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8,
5058                                            nxv16i8, nxv16i1, i32, SVECpyDupImm8Pat>;
5059  defm _H : sve_int_dup_imm_pred_merge_inst<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16,
5060                                            nxv8i16, nxv8i1, i32, SVECpyDupImm16Pat>;
5061  defm _S : sve_int_dup_imm_pred_merge_inst<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32,
5062                                            nxv4i32, nxv4i1, i32, SVECpyDupImm32Pat>;
5063  defm _D : sve_int_dup_imm_pred_merge_inst<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64,
5064                                            nxv2i64, nxv2i1, i64, SVECpyDupImm64Pat>;
5065
5066  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5067                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, 0, 0), 0>;
5068  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5069                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, 0, 0), 0>;
5070  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5071                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, 0, 0), 0>;
5072
5073  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv8f16 ZPR:$Zd)),
5074            (!cast<Instruction>(NAME # _H) $Zd, $Pg, 0, 0)>;
5075  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv4f16 ZPR:$Zd)),
5076            (!cast<Instruction>(NAME # _S) $Zd, $Pg, 0, 0)>;
5077  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f16 ZPR:$Zd)),
5078            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5079  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv4f32 ZPR:$Zd)),
5080            (!cast<Instruction>(NAME # _S) $Zd, $Pg, 0, 0)>;
5081  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f32 ZPR:$Zd)),
5082            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5083  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f64 ZPR:$Zd)),
5084            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5085}
5086
5087multiclass sve_int_dup_imm_pred_zero_inst<
5088    bits<2> sz8_64, string asm, ZPRRegOp zprty, imm8_opt_lsl cpyimm,
5089    ValueType intty, ValueType predty, ValueType scalarty, ComplexPattern cpx> {
5090  def NAME : sve_int_dup_imm_pred<sz8_64, 0, asm, zprty, "/z",
5091                                  (ins PPRAny:$Pg, cpyimm:$imm)>;
5092  def : InstAlias<"mov $Zd, $Pg/z, $imm",
5093                  (!cast<Instruction>(NAME) zprty:$Zd, PPRAny:$Pg, cpyimm:$imm), 1>;
5094  def : Pat<(intty (zext (predty PPRAny:$Ps1))),
5095            (!cast<Instruction>(NAME) PPRAny:$Ps1, 1, 0)>;
5096  def : Pat<(intty (sext (predty PPRAny:$Ps1))),
5097            (!cast<Instruction>(NAME) PPRAny:$Ps1, -1, 0)>;
5098  def : Pat<(intty (anyext (predty PPRAny:$Ps1))),
5099            (!cast<Instruction>(NAME) PPRAny:$Ps1, 1, 0)>;
5100  def : Pat<(vselect predty:$Pg,
5101                (intty (splat_vector (scalarty (cpx i32:$imm, i32:$shift)))),
5102                (intty (splat_vector (scalarty 0)))),
5103            (!cast<Instruction>(NAME) $Pg, $imm, $shift)>;
5104}
5105
5106multiclass sve_int_dup_imm_pred_zero<string asm> {
5107  defm _B : sve_int_dup_imm_pred_zero_inst<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8,
5108                                           nxv16i8, nxv16i1, i32, SVECpyDupImm8Pat>;
5109  defm _H : sve_int_dup_imm_pred_zero_inst<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16,
5110                                           nxv8i16, nxv8i1, i32, SVECpyDupImm16Pat>;
5111  defm _S : sve_int_dup_imm_pred_zero_inst<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32,
5112                                           nxv4i32, nxv4i1, i32, SVECpyDupImm32Pat>;
5113  defm _D : sve_int_dup_imm_pred_zero_inst<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64,
5114                                           nxv2i64, nxv2i1, i64, SVECpyDupImm64Pat>;
5115}
5116
5117//===----------------------------------------------------------------------===//
5118// SVE Integer Compare - Vectors Group
5119//===----------------------------------------------------------------------===//
5120
5121class sve_int_cmp<bit cmp_1, bits<2> sz8_64, bits<3> opc, string asm,
5122                  PPRRegOp pprty, ZPRRegOp zprty1, ZPRRegOp zprty2>
5123: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty1:$Zn, zprty2:$Zm),
5124  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
5125  "",
5126  []>, Sched<[]> {
5127  bits<4> Pd;
5128  bits<3> Pg;
5129  bits<5> Zm;
5130  bits<5> Zn;
5131  let Inst{31-24} = 0b00100100;
5132  let Inst{23-22} = sz8_64;
5133  let Inst{21}    = 0b0;
5134  let Inst{20-16} = Zm;
5135  let Inst{15}    = opc{2};
5136  let Inst{14}    = cmp_1;
5137  let Inst{13}    = opc{1};
5138  let Inst{12-10} = Pg;
5139  let Inst{9-5}   = Zn;
5140  let Inst{4}     = opc{0};
5141  let Inst{3-0}   = Pd;
5142
5143  let Defs = [NZCV];
5144  let ElementSize = pprty.ElementSize;
5145  let hasSideEffects = 0;
5146  let isPTestLike = 1;
5147}
5148
5149multiclass SVE_SETCC_Pat<CondCode cc, CondCode invcc, ValueType predvt,
5150                         ValueType intvt, Instruction cmp> {
5151  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, intvt:$Op3, cc)),
5152            (cmp $Op1, $Op2, $Op3)>;
5153  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, intvt:$Op3, invcc)),
5154            (cmp $Op1, $Op3, $Op2)>;
5155  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), intvt:$Op2, intvt:$Op3, cc))),
5156            (cmp $Pg, $Op2, $Op3)>;
5157  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), intvt:$Op2, intvt:$Op3, invcc))),
5158            (cmp $Pg, $Op3, $Op2)>;
5159}
5160
5161multiclass SVE_SETCC_Pat_With_Zero<CondCode cc, CondCode invcc, ValueType predvt,
5162                                   ValueType intvt, Instruction cmp> {
5163  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, (SVEDup0), cc)),
5164            (cmp $Op1, $Op2)>;
5165  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, (SVEDup0), intvt:$Op2, invcc)),
5166            (cmp $Op1, $Op2)>;
5167  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), intvt:$Op1, (SVEDup0), cc))),
5168            (cmp $Pg, $Op1)>;
5169  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), (SVEDup0), intvt:$Op1, invcc))),
5170            (cmp $Pg, $Op1)>;
5171}
5172
5173multiclass sve_int_cmp_0<bits<3> opc, string asm, CondCode cc, CondCode invcc> {
5174  def _B : sve_int_cmp<0b0, 0b00, opc, asm, PPR8, ZPR8, ZPR8>;
5175  def _H : sve_int_cmp<0b0, 0b01, opc, asm, PPR16, ZPR16, ZPR16>;
5176  def _S : sve_int_cmp<0b0, 0b10, opc, asm, PPR32, ZPR32, ZPR32>;
5177  def _D : sve_int_cmp<0b0, 0b11, opc, asm, PPR64, ZPR64, ZPR64>;
5178
5179  defm : SVE_SETCC_Pat<cc, invcc, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
5180  defm : SVE_SETCC_Pat<cc, invcc, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
5181  defm : SVE_SETCC_Pat<cc, invcc, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
5182  defm : SVE_SETCC_Pat<cc, invcc, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
5183}
5184
5185multiclass sve_int_cmp_0_wide<bits<3> opc, string asm, SDPatternOperator op> {
5186  def _B : sve_int_cmp<0b0, 0b00, opc, asm, PPR8, ZPR8, ZPR64>;
5187  def _H : sve_int_cmp<0b0, 0b01, opc, asm, PPR16, ZPR16, ZPR64>;
5188  def _S : sve_int_cmp<0b0, 0b10, opc, asm, PPR32, ZPR32, ZPR64>;
5189
5190  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
5191  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
5192  def : SVE_3_Op_Pat<nxv4i1,  op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
5193}
5194
5195multiclass sve_int_cmp_1_wide<bits<3> opc, string asm, SDPatternOperator op> {
5196  def _B : sve_int_cmp<0b1, 0b00, opc, asm, PPR8, ZPR8, ZPR64>;
5197  def _H : sve_int_cmp<0b1, 0b01, opc, asm, PPR16, ZPR16, ZPR64>;
5198  def _S : sve_int_cmp<0b1, 0b10, opc, asm, PPR32, ZPR32, ZPR64>;
5199
5200  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
5201  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
5202  def : SVE_3_Op_Pat<nxv4i1,  op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
5203}
5204
5205
5206//===----------------------------------------------------------------------===//
5207// SVE Integer Compare - Signed Immediate Group
5208//===----------------------------------------------------------------------===//
5209
5210class sve_int_scmp_vi<bits<2> sz8_64, bits<3> opc, string asm, PPRRegOp pprty,
5211                      ZPRRegOp zprty,
5212                      Operand immtype>
5213: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, immtype:$imm5),
5214  asm, "\t$Pd, $Pg/z, $Zn, $imm5",
5215  "",
5216  []>, Sched<[]> {
5217  bits<4> Pd;
5218  bits<3> Pg;
5219  bits<5> Zn;
5220  bits<5> imm5;
5221  let Inst{31-24} = 0b00100101;
5222  let Inst{23-22} = sz8_64;
5223  let Inst{21}    = 0b0;
5224  let Inst{20-16} = imm5;
5225  let Inst{15}    = opc{2};
5226  let Inst{14}    = 0b0;
5227  let Inst{13}    = opc{1};
5228  let Inst{12-10} = Pg;
5229  let Inst{9-5}   = Zn;
5230  let Inst{4}     = opc{0};
5231  let Inst{3-0}   = Pd;
5232
5233  let Defs = [NZCV];
5234  let ElementSize = pprty.ElementSize;
5235  let hasSideEffects = 0;
5236  let isPTestLike = 1;
5237}
5238
5239multiclass SVE_SETCC_Imm_Pat<CondCode cc, CondCode commuted_cc,
5240                             ValueType predvt, ValueType intvt,
5241                             Operand immtype, Instruction cmp> {
5242  def : Pat<(predvt (AArch64setcc_z (predvt PPR_3b:$Pg),
5243                                    (intvt ZPR:$Zs1),
5244                                    (intvt (splat_vector (immtype:$imm))),
5245                                    cc)),
5246            (cmp $Pg, $Zs1, immtype:$imm)>;
5247  def : Pat<(predvt (AArch64setcc_z (predvt PPR_3b:$Pg),
5248                                    (intvt (splat_vector (immtype:$imm))),
5249                                    (intvt ZPR:$Zs1),
5250                                    commuted_cc)),
5251            (cmp $Pg, $Zs1, immtype:$imm)>;
5252  def : Pat<(predvt (and predvt:$Pg,
5253                         (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)),
5254                                         (intvt ZPR:$Zs1),
5255                                         (intvt (splat_vector (immtype:$imm))),
5256                                         cc))),
5257            (cmp $Pg, $Zs1, immtype:$imm)>;
5258  def : Pat<(predvt (and predvt:$Pg,
5259                         (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)),
5260                                         (intvt (splat_vector (immtype:$imm))),
5261                                         (intvt ZPR:$Zs1),
5262                                         commuted_cc))),
5263            (cmp $Pg, $Zs1, immtype:$imm)>;
5264}
5265
5266multiclass sve_int_scmp_vi<bits<3> opc, string asm, CondCode cc, CondCode commuted_cc> {
5267  def _B : sve_int_scmp_vi<0b00, opc, asm, PPR8, ZPR8, simm5_32b>;
5268  def _H : sve_int_scmp_vi<0b01, opc, asm, PPR16, ZPR16, simm5_32b>;
5269  def _S : sve_int_scmp_vi<0b10, opc, asm, PPR32, ZPR32, simm5_32b>;
5270  def _D : sve_int_scmp_vi<0b11, opc, asm, PPR64, ZPR64, simm5_64b>;
5271
5272  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv16i1, nxv16i8, simm5_32b,
5273                           !cast<Instruction>(NAME # _B)>;
5274  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv8i1,  nxv8i16, simm5_32b,
5275                           !cast<Instruction>(NAME # _H)>;
5276  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv4i1,  nxv4i32, simm5_32b,
5277                           !cast<Instruction>(NAME # _S)>;
5278  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv2i1,  nxv2i64, simm5_64b,
5279                           !cast<Instruction>(NAME # _D)>;
5280}
5281
5282
5283//===----------------------------------------------------------------------===//
5284// SVE Integer Compare - Unsigned Immediate Group
5285//===----------------------------------------------------------------------===//
5286
5287class sve_int_ucmp_vi<bits<2> sz8_64, bits<2> opc, string asm, PPRRegOp pprty,
5288                      ZPRRegOp zprty, Operand immtype>
5289: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, immtype:$imm7),
5290  asm, "\t$Pd, $Pg/z, $Zn, $imm7",
5291  "",
5292  []>, Sched<[]> {
5293  bits<4> Pd;
5294  bits<3> Pg;
5295  bits<5> Zn;
5296  bits<7> imm7;
5297  let Inst{31-24} = 0b00100100;
5298  let Inst{23-22} = sz8_64;
5299  let Inst{21}    = 1;
5300  let Inst{20-14} = imm7;
5301  let Inst{13}    = opc{1};
5302  let Inst{12-10} = Pg;
5303  let Inst{9-5}   = Zn;
5304  let Inst{4}     = opc{0};
5305  let Inst{3-0}   = Pd;
5306
5307  let Defs = [NZCV];
5308  let ElementSize = pprty.ElementSize;
5309  let hasSideEffects = 0;
5310  let isPTestLike = 1;
5311}
5312
5313multiclass sve_int_ucmp_vi<bits<2> opc, string asm, CondCode cc,
5314                           CondCode commuted_cc> {
5315  def _B : sve_int_ucmp_vi<0b00, opc, asm, PPR8, ZPR8, imm0_127>;
5316  def _H : sve_int_ucmp_vi<0b01, opc, asm, PPR16, ZPR16, imm0_127>;
5317  def _S : sve_int_ucmp_vi<0b10, opc, asm, PPR32, ZPR32, imm0_127>;
5318  def _D : sve_int_ucmp_vi<0b11, opc, asm, PPR64, ZPR64, imm0_127_64b>;
5319
5320  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv16i1, nxv16i8, imm0_127,
5321                           !cast<Instruction>(NAME # _B)>;
5322  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv8i1,  nxv8i16, imm0_127,
5323                           !cast<Instruction>(NAME # _H)>;
5324  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv4i1,  nxv4i32, imm0_127,
5325                           !cast<Instruction>(NAME # _S)>;
5326  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv2i1,  nxv2i64, imm0_127_64b,
5327                           !cast<Instruction>(NAME # _D)>;
5328}
5329
5330
5331//===----------------------------------------------------------------------===//
5332// SVE Integer Compare - Scalars Group
5333//===----------------------------------------------------------------------===//
5334
5335class sve_int_cterm<bit sz, bit opc, string asm, RegisterClass rt>
5336: I<(outs), (ins rt:$Rn, rt:$Rm),
5337  asm, "\t$Rn, $Rm",
5338  "",
5339  []>, Sched<[]> {
5340  bits<5> Rm;
5341  bits<5> Rn;
5342  let Inst{31-23} = 0b001001011;
5343  let Inst{22}    = sz;
5344  let Inst{21}    = 0b1;
5345  let Inst{20-16} = Rm;
5346  let Inst{15-10} = 0b001000;
5347  let Inst{9-5}   = Rn;
5348  let Inst{4}     = opc;
5349  let Inst{3-0}   = 0b0000;
5350
5351  let Defs = [NZCV];
5352  let hasSideEffects = 0;
5353}
5354
5355class sve_int_while_rr<bits<2> sz8_64, bits<4> opc, string asm,
5356                       RegisterClass gprty, PPRRegOp pprty>
5357: I<(outs pprty:$Pd), (ins gprty:$Rn, gprty:$Rm),
5358  asm, "\t$Pd, $Rn, $Rm",
5359  "", []>, Sched<[]> {
5360  bits<4> Pd;
5361  bits<5> Rm;
5362  bits<5> Rn;
5363  let Inst{31-24} = 0b00100101;
5364  let Inst{23-22} = sz8_64;
5365  let Inst{21}    = 0b1;
5366  let Inst{20-16} = Rm;
5367  let Inst{15-13} = 0b000;
5368  let Inst{12-10} = opc{3-1};
5369  let Inst{9-5}   = Rn;
5370  let Inst{4}     = opc{0};
5371  let Inst{3-0}   = Pd;
5372
5373  let Defs = [NZCV];
5374  let ElementSize = pprty.ElementSize;
5375  let hasSideEffects = 0;
5376  let isWhile = 1;
5377}
5378
5379multiclass sve_int_while4_rr<bits<3> opc, string asm, SDPatternOperator op> {
5380  def _B : sve_int_while_rr<0b00, { 0, opc }, asm, GPR32, PPR8>;
5381  def _H : sve_int_while_rr<0b01, { 0, opc }, asm, GPR32, PPR16>;
5382  def _S : sve_int_while_rr<0b10, { 0, opc }, asm, GPR32, PPR32>;
5383  def _D : sve_int_while_rr<0b11, { 0, opc }, asm, GPR32, PPR64>;
5384
5385  def : SVE_2_Op_Pat<nxv16i1, op, i32, i32, !cast<Instruction>(NAME # _B)>;
5386  def : SVE_2_Op_Pat<nxv8i1,  op, i32, i32, !cast<Instruction>(NAME # _H)>;
5387  def : SVE_2_Op_Pat<nxv4i1,  op, i32, i32, !cast<Instruction>(NAME # _S)>;
5388  def : SVE_2_Op_Pat<nxv2i1,  op, i32, i32, !cast<Instruction>(NAME # _D)>;
5389}
5390
5391multiclass sve_int_while8_rr<bits<3> opc, string asm, SDPatternOperator op> {
5392  def _B : sve_int_while_rr<0b00, { 1, opc }, asm, GPR64, PPR8>;
5393  def _H : sve_int_while_rr<0b01, { 1, opc }, asm, GPR64, PPR16>;
5394  def _S : sve_int_while_rr<0b10, { 1, opc }, asm, GPR64, PPR32>;
5395  def _D : sve_int_while_rr<0b11, { 1, opc }, asm, GPR64, PPR64>;
5396
5397  def : SVE_2_Op_Pat<nxv16i1, op, i64, i64, !cast<Instruction>(NAME # _B)>;
5398  def : SVE_2_Op_Pat<nxv8i1,  op, i64, i64, !cast<Instruction>(NAME # _H)>;
5399  def : SVE_2_Op_Pat<nxv4i1,  op, i64, i64, !cast<Instruction>(NAME # _S)>;
5400  def : SVE_2_Op_Pat<nxv2i1,  op, i64, i64, !cast<Instruction>(NAME # _D)>;
5401}
5402
5403class sve2_int_while_rr<bits<2> sz8_64, bits<1> rw, string asm,
5404                        PPRRegOp pprty>
5405: I<(outs pprty:$Pd), (ins GPR64:$Rn, GPR64:$Rm),
5406  asm, "\t$Pd, $Rn, $Rm",
5407  "", []>, Sched<[]> {
5408  bits<4> Pd;
5409  bits<5> Rm;
5410  bits<5> Rn;
5411  let Inst{31-24} = 0b00100101;
5412  let Inst{23-22} = sz8_64;
5413  let Inst{21}    = 0b1;
5414  let Inst{20-16} = Rm;
5415  let Inst{15-10} = 0b001100;
5416  let Inst{9-5}   = Rn;
5417  let Inst{4}     = rw;
5418  let Inst{3-0}   = Pd;
5419
5420  let Defs = [NZCV];
5421  let ElementSize = pprty.ElementSize;
5422  let hasSideEffects = 0;
5423  let isWhile = 1;
5424}
5425
5426multiclass sve2_int_while_rr<bits<1> rw, string asm, string op> {
5427  def _B : sve2_int_while_rr<0b00, rw, asm, PPR8>;
5428  def _H : sve2_int_while_rr<0b01, rw, asm, PPR16>;
5429  def _S : sve2_int_while_rr<0b10, rw, asm, PPR32>;
5430  def _D : sve2_int_while_rr<0b11, rw, asm, PPR64>;
5431
5432  def : SVE_2_Op_Pat<nxv16i1, !cast<SDPatternOperator>(op # _b), i64, i64, !cast<Instruction>(NAME # _B)>;
5433  def : SVE_2_Op_Pat<nxv8i1,  !cast<SDPatternOperator>(op # _h), i64, i64, !cast<Instruction>(NAME # _H)>;
5434  def : SVE_2_Op_Pat<nxv4i1,  !cast<SDPatternOperator>(op # _s), i64, i64, !cast<Instruction>(NAME # _S)>;
5435  def : SVE_2_Op_Pat<nxv2i1,  !cast<SDPatternOperator>(op # _d), i64, i64, !cast<Instruction>(NAME # _D)>;
5436}
5437
5438//===----------------------------------------------------------------------===//
5439// SVE Floating Point Fast Reduction Group
5440//===----------------------------------------------------------------------===//
5441
5442class sve_fp_fast_red<bits<2> sz, bits<3> opc, string asm,
5443                      ZPRRegOp zprty, FPRasZPROperand dstOpType>
5444: I<(outs dstOpType:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
5445  asm, "\t$Vd, $Pg, $Zn",
5446  "",
5447  []>, Sched<[]> {
5448  bits<5> Zn;
5449  bits<5> Vd;
5450  bits<3> Pg;
5451  let Inst{31-24} = 0b01100101;
5452  let Inst{23-22} = sz;
5453  let Inst{21-19} = 0b000;
5454  let Inst{18-16} = opc;
5455  let Inst{15-13} = 0b001;
5456  let Inst{12-10} = Pg;
5457  let Inst{9-5}   = Zn;
5458  let Inst{4-0}   = Vd;
5459
5460  let hasSideEffects = 0;
5461  let mayRaiseFPException = 1;
5462}
5463
5464multiclass sve_fp_fast_red<bits<3> opc, string asm, SDPatternOperator op> {
5465  def _H : sve_fp_fast_red<0b01, opc, asm, ZPR16, FPR16asZPR>;
5466  def _S : sve_fp_fast_red<0b10, opc, asm, ZPR32, FPR32asZPR>;
5467  def _D : sve_fp_fast_red<0b11, opc, asm, ZPR64, FPR64asZPR>;
5468
5469  def : SVE_2_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
5470  def : SVE_2_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
5471  def : SVE_2_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
5472  def : SVE_2_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
5473  def : SVE_2_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
5474  def : SVE_2_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
5475}
5476
5477//===----------------------------------------------------------------------===//
5478// SVE Floating Point Accumulating Reduction Group
5479//===----------------------------------------------------------------------===//
5480
5481class sve_fp_2op_p_vd<bits<2> sz, bits<3> opc, string asm,
5482                      ZPRRegOp zprty, FPRasZPROperand dstOpType>
5483: I<(outs dstOpType:$Vdn), (ins PPR3bAny:$Pg, dstOpType:$_Vdn, zprty:$Zm),
5484  asm, "\t$Vdn, $Pg, $_Vdn, $Zm",
5485  "",
5486  []>,
5487  Sched<[]> {
5488  bits<3> Pg;
5489  bits<5> Vdn;
5490  bits<5> Zm;
5491  let Inst{31-24} = 0b01100101;
5492  let Inst{23-22} = sz;
5493  let Inst{21-19} = 0b011;
5494  let Inst{18-16} = opc;
5495  let Inst{15-13} = 0b001;
5496  let Inst{12-10} = Pg;
5497  let Inst{9-5}   = Zm;
5498  let Inst{4-0}   = Vdn;
5499
5500  let Constraints = "$Vdn = $_Vdn";
5501  let hasSideEffects = 0;
5502  let mayRaiseFPException = 1;
5503}
5504
5505multiclass sve_fp_2op_p_vd<bits<3> opc, string asm, SDPatternOperator op> {
5506  def _H : sve_fp_2op_p_vd<0b01, opc, asm, ZPR16, FPR16asZPR>;
5507  def _S : sve_fp_2op_p_vd<0b10, opc, asm, ZPR32, FPR32asZPR>;
5508  def _D : sve_fp_2op_p_vd<0b11, opc, asm, ZPR64, FPR64asZPR>;
5509
5510  def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H)>;
5511  def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H)>;
5512  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
5513  def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S)>;
5514  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
5515  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
5516}
5517
5518//===----------------------------------------------------------------------===//
5519// SVE Floating Point Compare - Vectors Group
5520//===----------------------------------------------------------------------===//
5521
5522class sve_fp_3op_p_pd<bits<2> sz, bits<3> opc, string asm, PPRRegOp pprty,
5523                      ZPRRegOp zprty>
5524: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
5525  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
5526  "",
5527  []>, Sched<[]> {
5528  bits<4> Pd;
5529  bits<3> Pg;
5530  bits<5> Zm;
5531  bits<5> Zn;
5532  let Inst{31-24} = 0b01100101;
5533  let Inst{23-22} = sz;
5534  let Inst{21}    = 0b0;
5535  let Inst{20-16} = Zm;
5536  let Inst{15}    = opc{2};
5537  let Inst{14}    = 0b1;
5538  let Inst{13}    = opc{1};
5539  let Inst{12-10} = Pg;
5540  let Inst{9-5}   = Zn;
5541  let Inst{4}     = opc{0};
5542  let Inst{3-0}   = Pd;
5543
5544  let hasSideEffects = 0;
5545  let mayRaiseFPException = 1;
5546}
5547
5548multiclass sve_fp_3op_p_pd<bits<3> opc, string asm, SDPatternOperator op> {
5549  def _H : sve_fp_3op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5550  def _S : sve_fp_3op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5551  def _D : sve_fp_3op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5552
5553  def : SVE_3_Op_Pat<nxv8i1, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
5554  def : SVE_3_Op_Pat<nxv4i1, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
5555  def : SVE_3_Op_Pat<nxv2i1, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
5556}
5557
5558multiclass sve_fp_3op_p_pd_cc<bits<3> opc, string asm,
5559                              CondCode cc1, CondCode cc2,
5560                              CondCode invcc1, CondCode invcc2> {
5561  def _H : sve_fp_3op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5562  def _S : sve_fp_3op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5563  def _D : sve_fp_3op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5564
5565  defm : SVE_SETCC_Pat<cc1, invcc1, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5566  defm : SVE_SETCC_Pat<cc1, invcc1, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5567  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5568  defm : SVE_SETCC_Pat<cc1, invcc1, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5569  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5570  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5571
5572  defm : SVE_SETCC_Pat<cc2, invcc2, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5573  defm : SVE_SETCC_Pat<cc2, invcc2, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5574  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5575  defm : SVE_SETCC_Pat<cc2, invcc2, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5576  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5577  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5578}
5579
5580//===----------------------------------------------------------------------===//
5581// SVE Floating Point Compare - with Zero Group
5582//===----------------------------------------------------------------------===//
5583
5584class sve_fp_2op_p_pd<bits<2> sz, bits<3> opc, string asm, PPRRegOp pprty,
5585                      ZPRRegOp zprty>
5586: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn),
5587  asm, "\t$Pd, $Pg/z, $Zn, #0.0",
5588  "",
5589  []>, Sched<[]> {
5590  bits<4> Pd;
5591  bits<3> Pg;
5592  bits<5> Zn;
5593  let Inst{31-24} = 0b01100101;
5594  let Inst{23-22} = sz;
5595  let Inst{21-18} = 0b0100;
5596  let Inst{17-16} = opc{2-1};
5597  let Inst{15-13} = 0b001;
5598  let Inst{12-10} = Pg;
5599  let Inst{9-5}   = Zn;
5600  let Inst{4}     = opc{0};
5601  let Inst{3-0}   = Pd;
5602
5603  let hasSideEffects = 0;
5604  let mayRaiseFPException = 1;
5605}
5606
5607multiclass sve_fp_2op_p_pd<bits<3> opc, string asm,
5608                           CondCode cc1, CondCode cc2,
5609                           CondCode invcc1, CondCode invcc2> {
5610  def _H : sve_fp_2op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5611  def _S : sve_fp_2op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5612  def _D : sve_fp_2op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5613
5614  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5615  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5616  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5617  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5618  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5619  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5620
5621  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5622  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5623  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5624  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5625  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5626  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5627}
5628
5629
5630//===----------------------------------------------------------------------===//
5631//SVE Index Generation Group
5632//===----------------------------------------------------------------------===//
5633
5634def simm5_8b_tgt : TImmLeaf<i8, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]>;
5635def simm5_16b_tgt : TImmLeaf<i16, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]>;
5636def simm5_32b_tgt : TImmLeaf<i32, [{ return (int32_t)Imm >= -16 && (int32_t)Imm < 16; }]>;
5637def simm5_64b_tgt : TImmLeaf<i64, [{ return (int64_t)Imm >= -16 && (int64_t)Imm < 16; }]>;
5638def i64imm_32bit_tgt : TImmLeaf<i64, [{
5639  return (Imm & 0xffffffffULL) == static_cast<uint64_t>(Imm);
5640}]>;
5641
5642class sve_int_index_ii<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5643                       Operand imm_ty>
5644: I<(outs zprty:$Zd), (ins imm_ty:$imm5, imm_ty:$imm5b),
5645  asm, "\t$Zd, $imm5, $imm5b",
5646  "", []>, Sched<[]> {
5647  bits<5> Zd;
5648  bits<5> imm5;
5649  bits<5> imm5b;
5650  let Inst{31-24} = 0b00000100;
5651  let Inst{23-22} = sz8_64;
5652  let Inst{21}    = 0b1;
5653  let Inst{20-16} = imm5b;
5654  let Inst{15-10} = 0b010000;
5655  let Inst{9-5}   = imm5;
5656  let Inst{4-0}   = Zd;
5657
5658  let hasSideEffects = 0;
5659  let isReMaterializable = 1;
5660}
5661
5662multiclass sve_int_index_ii<string asm> {
5663  def _B : sve_int_index_ii<0b00, asm, ZPR8, simm5_8b>;
5664  def _H : sve_int_index_ii<0b01, asm, ZPR16, simm5_16b>;
5665  def _S : sve_int_index_ii<0b10, asm, ZPR32, simm5_32b>;
5666  def _D : sve_int_index_ii<0b11, asm, ZPR64, simm5_64b>;
5667
5668  def : Pat<(nxv16i8 (step_vector simm5_8b_tgt:$imm5b)),
5669            (!cast<Instruction>(NAME # "_B") (i32 0), (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5670  def : Pat<(nxv8i16 (step_vector simm5_16b_tgt:$imm5b)),
5671            (!cast<Instruction>(NAME # "_H") (i32 0), (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5672  def : Pat<(nxv4i32 (step_vector simm5_32b_tgt:$imm5b)),
5673            (!cast<Instruction>(NAME # "_S") (i32 0), simm5_32b:$imm5b)>;
5674  def : Pat<(nxv2i64 (step_vector simm5_64b_tgt:$imm5b)),
5675            (!cast<Instruction>(NAME # "_D") (i64 0), simm5_64b:$imm5b)>;
5676
5677  // add(step_vector(step), dup(X)) -> index(X, step).
5678  def : Pat<(add (nxv16i8 (step_vector_oneuse simm5_8b_tgt:$imm5b)), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
5679            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5680  def : Pat<(add (nxv8i16 (step_vector_oneuse simm5_16b_tgt:$imm5b)), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
5681            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5682  def : Pat<(add (nxv4i32 (step_vector_oneuse simm5_32b_tgt:$imm5b)), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
5683            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, simm5_32b:$imm5b)>;
5684  def : Pat<(add (nxv2i64 (step_vector_oneuse simm5_64b_tgt:$imm5b)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5685            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, simm5_64b:$imm5b)>;
5686}
5687
5688class sve_int_index_ir<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5689                       RegisterClass srcRegType, Operand imm_ty>
5690: I<(outs zprty:$Zd), (ins imm_ty:$imm5, srcRegType:$Rm),
5691  asm, "\t$Zd, $imm5, $Rm",
5692  "", []>, Sched<[]> {
5693  bits<5> Rm;
5694  bits<5> Zd;
5695  bits<5> imm5;
5696  let Inst{31-24} = 0b00000100;
5697  let Inst{23-22} = sz8_64;
5698  let Inst{21}    = 0b1;
5699  let Inst{20-16} = Rm;
5700  let Inst{15-10} = 0b010010;
5701  let Inst{9-5}   = imm5;
5702  let Inst{4-0}   = Zd;
5703
5704  let hasSideEffects = 0;
5705}
5706
5707multiclass sve_int_index_ir<string asm, SDPatternOperator mulop, SDPatternOperator muloneuseop> {
5708  def _B : sve_int_index_ir<0b00, asm, ZPR8, GPR32, simm5_8b>;
5709  def _H : sve_int_index_ir<0b01, asm, ZPR16, GPR32, simm5_16b>;
5710  def _S : sve_int_index_ir<0b10, asm, ZPR32, GPR32, simm5_32b>;
5711  def _D : sve_int_index_ir<0b11, asm, ZPR64, GPR64, simm5_64b>;
5712
5713  def : Pat<(nxv16i8 (step_vector i8:$imm)),
5714            (!cast<Instruction>(NAME # "_B") (i32 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5715  def : Pat<(nxv8i16 (step_vector i16:$imm)),
5716            (!cast<Instruction>(NAME # "_H") (i32 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5717  def : Pat<(nxv4i32 (step_vector i32:$imm)),
5718            (!cast<Instruction>(NAME # "_S") (i32 0), (!cast<Instruction>("MOVi32imm") $imm))>;
5719  def : Pat<(nxv2i64 (step_vector i64:$imm)),
5720            (!cast<Instruction>(NAME # "_D") (i64 0), (!cast<Instruction>("MOVi64imm") $imm))>;
5721  def : Pat<(nxv2i64 (step_vector i64imm_32bit_tgt:$imm)),
5722            (!cast<Instruction>(NAME # "_D") (i64 0), (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5723
5724  // add(step_vector(step), dup(X)) -> index(X, step).
5725  def : Pat<(add (nxv16i8 (step_vector_oneuse i8:$imm)), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
5726            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5727  def : Pat<(add (nxv8i16 (step_vector_oneuse i16:$imm)), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
5728            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5729  def : Pat<(add (nxv4i32 (step_vector_oneuse i32:$imm)), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
5730            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, (!cast<Instruction>("MOVi32imm") $imm))>;
5731  def : Pat<(add (nxv2i64 (step_vector_oneuse i64:$imm)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5732            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, (!cast<Instruction>("MOVi64imm") $imm))>;
5733  def : Pat<(add (nxv2i64 (step_vector_oneuse i64imm_32bit_tgt:$imm)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5734            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5735
5736  // mul(step_vector(1), dup(Y)) -> index(0, Y).
5737  def : Pat<(mulop (nxv16i1 (AArch64ptrue 31)), (nxv16i8 (step_vector_oneuse (i8 1))), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))),
5738            (!cast<Instruction>(NAME # "_B") (i32 0), GPR32:$Rm)>;
5739  def : Pat<(mulop (nxv8i1 (AArch64ptrue 31)), (nxv8i16 (step_vector_oneuse (i16 1))), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),
5740            (!cast<Instruction>(NAME # "_H") (i32 0), GPR32:$Rm)>;
5741  def : Pat<(mulop (nxv4i1 (AArch64ptrue 31)), (nxv4i32 (step_vector_oneuse (i32 1))), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),
5742            (!cast<Instruction>(NAME # "_S") (i32 0), GPR32:$Rm)>;
5743  def : Pat<(mulop (nxv2i1 (AArch64ptrue 31)), (nxv2i64 (step_vector_oneuse (i64 1))), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),
5744            (!cast<Instruction>(NAME # "_D") (i64 0), GPR64:$Rm)>;
5745
5746  // add(mul(step_vector(1), dup(Y)), dup(X)) -> index(X, Y).
5747  def : Pat<(add (muloneuseop (nxv16i1 (AArch64ptrue 31)), (nxv16i8 (step_vector_oneuse (i8 1))), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
5748            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, GPR32:$Rm)>;
5749  def : Pat<(add (muloneuseop (nxv8i1 (AArch64ptrue 31)), (nxv8i16 (step_vector_oneuse (i16 1))), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
5750            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, GPR32:$Rm)>;
5751  def : Pat<(add (muloneuseop (nxv4i1 (AArch64ptrue 31)), (nxv4i32 (step_vector_oneuse (i32 1))), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
5752            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, GPR32:$Rm)>;
5753  def : Pat<(add (muloneuseop (nxv2i1 (AArch64ptrue 31)), (nxv2i64 (step_vector_oneuse (i64 1))), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5754            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, GPR64:$Rm)>;
5755}
5756
5757class sve_int_index_ri<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5758                       RegisterClass srcRegType, Operand imm_ty>
5759: I<(outs zprty:$Zd), (ins srcRegType:$Rn, imm_ty:$imm5),
5760  asm, "\t$Zd, $Rn, $imm5",
5761  "", []>, Sched<[]> {
5762  bits<5> Rn;
5763  bits<5> Zd;
5764  bits<5> imm5;
5765  let Inst{31-24} = 0b00000100;
5766  let Inst{23-22} = sz8_64;
5767  let Inst{21}    = 0b1;
5768  let Inst{20-16} = imm5;
5769  let Inst{15-10} = 0b010001;
5770  let Inst{9-5}   = Rn;
5771  let Inst{4-0}   = Zd;
5772
5773  let hasSideEffects = 0;
5774}
5775
5776multiclass sve_int_index_ri<string asm> {
5777  def _B : sve_int_index_ri<0b00, asm, ZPR8, GPR32, simm5_8b>;
5778  def _H : sve_int_index_ri<0b01, asm, ZPR16, GPR32, simm5_16b>;
5779  def _S : sve_int_index_ri<0b10, asm, ZPR32, GPR32, simm5_32b>;
5780  def _D : sve_int_index_ri<0b11, asm, ZPR64, GPR64, simm5_64b>;
5781
5782  // add(step_vector(step), dup(X)) -> index(X, step).
5783  def : Pat<(add (nxv16i8 (step_vector_oneuse simm5_8b_tgt:$imm5)), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))),
5784            (!cast<Instruction>(NAME # "_B") GPR32:$Rm, (!cast<SDNodeXForm>("trunc_imm") $imm5))>;
5785  def : Pat<(add (nxv8i16 (step_vector_oneuse simm5_16b_tgt:$imm5)), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),
5786            (!cast<Instruction>(NAME # "_H") GPR32:$Rm, (!cast<SDNodeXForm>("trunc_imm") $imm5))>;
5787  def : Pat<(add (nxv4i32 (step_vector_oneuse simm5_32b_tgt:$imm5)), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),
5788            (!cast<Instruction>(NAME # "_S") GPR32:$Rm, simm5_32b:$imm5)>;
5789  def : Pat<(add (nxv2i64 (step_vector_oneuse simm5_64b_tgt:$imm5)), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),
5790            (!cast<Instruction>(NAME # "_D") GPR64:$Rm, simm5_64b:$imm5)>;
5791}
5792
5793class sve_int_index_rr<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5794                       RegisterClass srcRegType>
5795: I<(outs zprty:$Zd), (ins srcRegType:$Rn, srcRegType:$Rm),
5796  asm, "\t$Zd, $Rn, $Rm",
5797  "", []>, Sched<[]> {
5798  bits<5> Zd;
5799  bits<5> Rm;
5800  bits<5> Rn;
5801  let Inst{31-24} = 0b00000100;
5802  let Inst{23-22} = sz8_64;
5803  let Inst{21}    = 0b1;
5804  let Inst{20-16} = Rm;
5805  let Inst{15-10} = 0b010011;
5806  let Inst{9-5}   = Rn;
5807  let Inst{4-0}   = Zd;
5808
5809  let hasSideEffects = 0;
5810}
5811
5812multiclass sve_int_index_rr<string asm, SDPatternOperator mulop> {
5813  def _B : sve_int_index_rr<0b00, asm, ZPR8, GPR32>;
5814  def _H : sve_int_index_rr<0b01, asm, ZPR16, GPR32>;
5815  def _S : sve_int_index_rr<0b10, asm, ZPR32, GPR32>;
5816  def _D : sve_int_index_rr<0b11, asm, ZPR64, GPR64>;
5817
5818  // add(step_vector(step), dup(X)) -> index(X, step).
5819  def : Pat<(add (nxv16i8 (step_vector_oneuse i8:$imm)), (nxv16i8 (splat_vector(i32 GPR32:$Rn)))),
5820            (!cast<Instruction>(NAME # "_B") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5821  def : Pat<(add (nxv8i16 (step_vector_oneuse i16:$imm)), (nxv8i16 (splat_vector(i32 GPR32:$Rn)))),
5822            (!cast<Instruction>(NAME # "_H") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5823  def : Pat<(add (nxv4i32 (step_vector_oneuse i32:$imm)), (nxv4i32 (splat_vector(i32 GPR32:$Rn)))),
5824            (!cast<Instruction>(NAME # "_S") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") $imm))>;
5825  def : Pat<(add (nxv2i64 (step_vector_oneuse i64:$imm)), (nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
5826            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, (!cast<Instruction>("MOVi64imm") $imm))>;
5827  def : Pat<(add (nxv2i64 (step_vector_oneuse i64imm_32bit_tgt:$imm)), (nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
5828            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5829
5830  // add(mul(step_vector(1), dup(Y)), dup(X)) -> index(X, Y).
5831  def : Pat<(add (mulop (nxv16i1 (AArch64ptrue 31)), (nxv16i8 (step_vector_oneuse (i8 1))), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))), (nxv16i8 (splat_vector(i32 GPR32:$Rn)))),
5832            (!cast<Instruction>(NAME # "_B") GPR32:$Rn, GPR32:$Rm)>;
5833  def : Pat<(add (mulop (nxv8i1 (AArch64ptrue 31)), (nxv8i16 (step_vector_oneuse (i16 1))), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),(nxv8i16 (splat_vector(i32 GPR32:$Rn)))),
5834            (!cast<Instruction>(NAME # "_H") GPR32:$Rn, GPR32:$Rm)>;
5835  def : Pat<(add (mulop (nxv4i1 (AArch64ptrue 31)), (nxv4i32 (step_vector_oneuse (i32 1))), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),(nxv4i32 (splat_vector(i32 GPR32:$Rn)))),
5836            (!cast<Instruction>(NAME # "_S") GPR32:$Rn, GPR32:$Rm)>;
5837  def : Pat<(add (mulop (nxv2i1 (AArch64ptrue 31)), (nxv2i64 (step_vector_oneuse (i64 1))), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),(nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
5838            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, GPR64:$Rm)>;
5839}
5840
5841//===----------------------------------------------------------------------===//
5842// SVE Bitwise Shift - Predicated Group
5843//===----------------------------------------------------------------------===//
5844
5845class sve_int_bin_pred_shift_imm<bits<4> tsz8_64, bits<4> opc, string asm,
5846                                 ZPRRegOp zprty, Operand immtype>
5847: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, immtype:$imm),
5848  asm, "\t$Zdn, $Pg/m, $_Zdn, $imm",
5849  "",
5850  []>, Sched<[]> {
5851  bits<3> Pg;
5852  bits<5> Zdn;
5853  bits<6> imm;
5854  let Inst{31-24} = 0b00000100;
5855  let Inst{23-22} = tsz8_64{3-2};
5856  let Inst{21-20} = 0b00;
5857  let Inst{19-16} = opc;
5858  let Inst{15-13} = 0b100;
5859  let Inst{12-10} = Pg;
5860  let Inst{9-8}   = tsz8_64{1-0};
5861  let Inst{7-5}   = imm{2-0}; // imm3
5862  let Inst{4-0}   = Zdn;
5863
5864  let Constraints = "$Zdn = $_Zdn";
5865  let DestructiveInstType = DestructiveBinaryImm;
5866  let ElementSize = zprty.ElementSize;
5867  let hasSideEffects = 0;
5868}
5869
5870multiclass sve_int_bin_pred_shift_imm_left<bits<4> opc, string asm, string Ps,
5871                                           SDPatternOperator op = null_frag> {
5872  def _B : SVEPseudo2Instr<Ps # _B, 1>,
5873           sve_int_bin_pred_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
5874  def _H : SVEPseudo2Instr<Ps # _H, 1>,
5875           sve_int_bin_pred_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
5876    let Inst{8} = imm{3};
5877  }
5878  def _S : SVEPseudo2Instr<Ps # _S, 1>,
5879           sve_int_bin_pred_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
5880    let Inst{9-8} = imm{4-3};
5881  }
5882  def _D : SVEPseudo2Instr<Ps # _D, 1>,
5883           sve_int_bin_pred_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
5884    let Inst{22}  = imm{5};
5885    let Inst{9-8} = imm{4-3};
5886  }
5887
5888  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i1, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _B)>;
5889  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i1,  nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _H)>;
5890  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i1,  nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _S)>;
5891  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i1,  nxv2i64, i32, tvecshiftL64, !cast<Instruction>(NAME # _D)>;
5892}
5893
5894// As above but shift amount takes the form of a "vector immediate".
5895multiclass sve_int_bin_pred_shift_imm_left_dup<bits<4> opc, string asm,
5896                                               string Ps, SDPatternOperator op>
5897: sve_int_bin_pred_shift_imm_left<opc, asm, Ps, null_frag> {
5898  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8,  !cast<Instruction>(NAME # _B)>;
5899  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
5900  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
5901  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
5902}
5903
5904multiclass sve_int_bin_pred_shift_imm_left_zeroing_bhsd<SDPatternOperator op> {
5905  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8,  tvecshiftL8,  FalseLanesZero>;
5906  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, tvecshiftL16, FalseLanesZero>;
5907  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, tvecshiftL32, FalseLanesZero>;
5908  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, tvecshiftL64, FalseLanesZero>;
5909
5910  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv16i8, op, nxv16i1, nxv16i8, tvecshiftL8,  !cast<Pseudo>(NAME # _B_ZERO)>;
5911  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv8i16, op, nxv8i1,  nxv8i16, tvecshiftL16, !cast<Pseudo>(NAME # _H_ZERO)>;
5912  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv4i32, op, nxv4i1,  nxv4i32, tvecshiftL32, !cast<Pseudo>(NAME # _S_ZERO)>;
5913  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv2i64, op, nxv2i1,  nxv2i64, tvecshiftL64, !cast<Pseudo>(NAME # _D_ZERO)>;
5914}
5915
5916multiclass sve_int_bin_pred_shift_imm_right<bits<4> opc, string asm, string Ps,
5917                                            SDPatternOperator op = null_frag> {
5918  def _B : SVEPseudo2Instr<Ps # _B, 1>,
5919           sve_int_bin_pred_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
5920  def _H : SVEPseudo2Instr<Ps # _H, 1>,
5921           sve_int_bin_pred_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
5922    let Inst{8} = imm{3};
5923  }
5924  def _S : SVEPseudo2Instr<Ps # _S, 1>,
5925           sve_int_bin_pred_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
5926    let Inst{9-8} = imm{4-3};
5927  }
5928  def _D : SVEPseudo2Instr<Ps # _D, 1>,
5929           sve_int_bin_pred_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
5930    let Inst{22}  = imm{5};
5931    let Inst{9-8} = imm{4-3};
5932  }
5933
5934  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i1, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
5935  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i1,  nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
5936  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i1,  nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
5937  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i1,  nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
5938}
5939
5940// As above but shift amount takes the form of a "vector immediate".
5941multiclass sve_int_bin_pred_shift_imm_right_dup<bits<4> opc, string asm,
5942                                            string Ps, SDPatternOperator op>
5943: sve_int_bin_pred_shift_imm_right<opc, asm, Ps, null_frag> {
5944  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8,  !cast<Instruction>(NAME # _B)>;
5945  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
5946  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
5947  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
5948}
5949
5950multiclass sve_int_bin_pred_shift_imm_right_zeroing_bhsd<SDPatternOperator op = null_frag> {
5951  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8, vecshiftR8, FalseLanesZero>;
5952  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, vecshiftR16, FalseLanesZero>;
5953  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, vecshiftR32, FalseLanesZero>;
5954  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, vecshiftR64, FalseLanesZero>;
5955
5956  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv16i8, op, nxv16i1, nxv16i8, tvecshiftR8, !cast<Pseudo>(NAME # _B_ZERO)>;
5957  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv8i16, op, nxv8i1, nxv8i16, tvecshiftR16, !cast<Pseudo>(NAME # _H_ZERO)>;
5958  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv4i32, op, nxv4i1, nxv4i32, tvecshiftR32, !cast<Pseudo>(NAME # _S_ZERO)>;
5959  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv2i64, op, nxv2i1, nxv2i64, tvecshiftR64, !cast<Pseudo>(NAME # _D_ZERO)>;
5960}
5961
5962class sve_int_bin_pred_shift<bits<2> sz8_64, bit wide, bits<3> opc,
5963                             string asm, ZPRRegOp zprty, ZPRRegOp zprty2>
5964: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty2:$Zm),
5965  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
5966  "",
5967  []>, Sched<[]> {
5968  bits<3> Pg;
5969  bits<5> Zdn;
5970  bits<5> Zm;
5971  let Inst{31-24} = 0b00000100;
5972  let Inst{23-22} = sz8_64;
5973  let Inst{21-20} = 0b01;
5974  let Inst{19}    = wide;
5975  let Inst{18-16} = opc;
5976  let Inst{15-13} = 0b100;
5977  let Inst{12-10} = Pg;
5978  let Inst{9-5}   = Zm;
5979  let Inst{4-0}   = Zdn;
5980
5981  let Constraints = "$Zdn = $_Zdn";
5982  let DestructiveInstType = DestructiveOther;
5983  let ElementSize = zprty.ElementSize;
5984  let hasSideEffects = 0;
5985}
5986
5987multiclass sve_int_bin_pred_shift<bits<3> opc, string asm, string Ps,
5988                                  SDPatternOperator op, string revname, bit isReverseInstr = 0> {
5989  let DestructiveInstType = DestructiveBinaryCommWithRev in {
5990  def _B : sve_int_bin_pred_shift<0b00, 0b0, opc, asm, ZPR8, ZPR8>,
5991           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
5992  def _H : sve_int_bin_pred_shift<0b01, 0b0, opc, asm, ZPR16, ZPR16>,
5993           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
5994  def _S : sve_int_bin_pred_shift<0b10, 0b0, opc, asm, ZPR32, ZPR32>,
5995           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
5996  def _D : sve_int_bin_pred_shift<0b11, 0b0, opc, asm, ZPR64, ZPR64>,
5997           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
5998  }
5999  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
6000  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
6001  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
6002  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
6003}
6004
6005multiclass sve_int_bin_pred_zeroing_bhsd<SDPatternOperator op> {
6006  def _B_ZERO : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesZero>;
6007  def _H_ZERO : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesZero>;
6008  def _S_ZERO : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesZero>;
6009  def _D_ZERO : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesZero>;
6010
6011  def : SVE_3_Op_Pat_SelZero<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_ZERO)>;
6012  def : SVE_3_Op_Pat_SelZero<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_ZERO)>;
6013  def : SVE_3_Op_Pat_SelZero<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_ZERO)>;
6014  def : SVE_3_Op_Pat_SelZero<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_ZERO)>;
6015}
6016
6017multiclass sve_int_bin_pred_imm_zeroing_bhsd<SDPatternOperator op,
6018                                   ComplexPattern imm_b, ComplexPattern imm_h,
6019                                   ComplexPattern imm_s, ComplexPattern imm_d> {
6020  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8,  Operand<i32>, FalseLanesZero>;
6021  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, Operand<i32>, FalseLanesZero>;
6022  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, Operand<i32>, FalseLanesZero>;
6023  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, Operand<i32>, FalseLanesZero>;
6024
6025  def : SVE_2_Op_Imm_Pat_Zero<nxv16i8, op, nxv16i1, i32, imm_b, !cast<Pseudo>(NAME # _B_ZERO)>;
6026  def : SVE_2_Op_Imm_Pat_Zero<nxv8i16, op, nxv8i1,  i32, imm_h, !cast<Pseudo>(NAME # _H_ZERO)>;
6027  def : SVE_2_Op_Imm_Pat_Zero<nxv4i32, op, nxv4i1,  i32, imm_s, !cast<Pseudo>(NAME # _S_ZERO)>;
6028  def : SVE_2_Op_Imm_Pat_Zero<nxv2i64, op, nxv2i1,  i64, imm_d, !cast<Pseudo>(NAME # _D_ZERO)>;
6029}
6030
6031multiclass sve_int_bin_pred_shift_wide<bits<3> opc, string asm,
6032                                  SDPatternOperator op> {
6033  def _B : sve_int_bin_pred_shift<0b00, 0b1, opc, asm, ZPR8, ZPR64>;
6034  def _H : sve_int_bin_pred_shift<0b01, 0b1, opc, asm, ZPR16, ZPR64>;
6035  def _S : sve_int_bin_pred_shift<0b10, 0b1, opc, asm, ZPR32, ZPR64>;
6036
6037  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
6038  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
6039  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
6040}
6041
6042//===----------------------------------------------------------------------===//
6043// SVE Shift - Unpredicated Group
6044//===----------------------------------------------------------------------===//
6045
6046class sve_int_bin_cons_shift_wide<bits<2> sz8_64, bits<2> opc, string asm,
6047                               ZPRRegOp zprty>
6048: I<(outs zprty:$Zd), (ins zprty:$Zn, ZPR64:$Zm),
6049  asm, "\t$Zd, $Zn, $Zm",
6050  "",
6051  []>, Sched<[]> {
6052  bits<5> Zd;
6053  bits<5> Zm;
6054  bits<5> Zn;
6055  let Inst{31-24} = 0b00000100;
6056  let Inst{23-22} = sz8_64;
6057  let Inst{21}    = 0b1;
6058  let Inst{20-16} = Zm;
6059  let Inst{15-12} = 0b1000;
6060  let Inst{11-10} = opc;
6061  let Inst{9-5}   = Zn;
6062  let Inst{4-0}   = Zd;
6063
6064  let hasSideEffects = 0;
6065}
6066
6067multiclass sve_int_bin_cons_shift_wide<bits<2> opc, string asm, SDPatternOperator op> {
6068  def _B : sve_int_bin_cons_shift_wide<0b00, opc, asm, ZPR8>;
6069  def _H : sve_int_bin_cons_shift_wide<0b01, opc, asm, ZPR16>;
6070  def _S : sve_int_bin_cons_shift_wide<0b10, opc, asm, ZPR32>;
6071
6072  def : SVE_2_Op_Pred_All_Active<nxv16i8, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
6073  def : SVE_2_Op_Pred_All_Active<nxv8i16, op, nxv8i1, nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
6074  def : SVE_2_Op_Pred_All_Active<nxv4i32, op, nxv4i1, nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
6075}
6076
6077class sve_int_bin_cons_shift_imm<bits<4> tsz8_64, bits<2> opc, string asm,
6078                               ZPRRegOp zprty, Operand immtype>
6079: I<(outs zprty:$Zd), (ins zprty:$Zn, immtype:$imm),
6080  asm, "\t$Zd, $Zn, $imm",
6081  "",
6082  []>, Sched<[]> {
6083  bits<5> Zd;
6084  bits<5> Zn;
6085  bits<6> imm;
6086  let Inst{31-24} = 0b00000100;
6087  let Inst{23-22} = tsz8_64{3-2};
6088  let Inst{21}    = 0b1;
6089  let Inst{20-19} = tsz8_64{1-0};
6090  let Inst{18-16} = imm{2-0}; // imm3
6091  let Inst{15-12} = 0b1001;
6092  let Inst{11-10} = opc;
6093  let Inst{9-5}   = Zn;
6094  let Inst{4-0}   = Zd;
6095
6096  let hasSideEffects = 0;
6097}
6098
6099multiclass sve_int_bin_cons_shift_imm_left<bits<2> opc, string asm,
6100                                           SDPatternOperator op> {
6101  def _B : sve_int_bin_cons_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
6102  def _H : sve_int_bin_cons_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
6103    let Inst{19} = imm{3};
6104  }
6105  def _S : sve_int_bin_cons_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
6106    let Inst{20-19} = imm{4-3};
6107  }
6108  def _D : sve_int_bin_cons_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
6109    let Inst{22}    = imm{5};
6110    let Inst{20-19} = imm{4-3};
6111  }
6112
6113  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8,  !cast<Instruction>(NAME # _B)>;
6114  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
6115  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
6116  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
6117}
6118
6119multiclass sve_int_bin_cons_shift_imm_right<bits<2> opc, string asm,
6120                                            SDPatternOperator op> {
6121  def _B : sve_int_bin_cons_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
6122  def _H : sve_int_bin_cons_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
6123    let Inst{19} = imm{3};
6124  }
6125  def _S : sve_int_bin_cons_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
6126    let Inst{20-19} = imm{4-3};
6127  }
6128  def _D : sve_int_bin_cons_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
6129    let Inst{22}    = imm{5};
6130    let Inst{20-19} = imm{4-3};
6131  }
6132
6133  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8,  !cast<Instruction>(NAME # _B)>;
6134  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
6135  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
6136  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
6137}
6138
6139//===----------------------------------------------------------------------===//
6140// SVE Memory - Store Group
6141//===----------------------------------------------------------------------===//
6142
6143class sve_mem_cst_si<bits<2> msz, bits<2> esz, string asm,
6144                     RegisterOperand VecList>
6145: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
6146  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6147  "",
6148  []>, Sched<[]> {
6149  bits<3> Pg;
6150  bits<5> Rn;
6151  bits<5> Zt;
6152  bits<4> imm4;
6153  let Inst{31-25} = 0b1110010;
6154  let Inst{24-23} = msz;
6155  let Inst{22-21} = esz;
6156  let Inst{20}    = 0;
6157  let Inst{19-16} = imm4;
6158  let Inst{15-13} = 0b111;
6159  let Inst{12-10} = Pg;
6160  let Inst{9-5}   = Rn;
6161  let Inst{4-0}   = Zt;
6162
6163  let hasSideEffects = 0;
6164  let mayStore = 1;
6165}
6166
6167multiclass sve_mem_cst_si<bits<2> msz, bits<2> esz, string asm,
6168                          RegisterOperand listty, ZPRRegOp zprty>
6169{
6170  def NAME : sve_mem_cst_si<msz, esz, asm, listty>;
6171
6172  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6173                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
6174  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6175                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
6176  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6177                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6178}
6179
6180class sve_mem_est_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6181                     string asm, Operand immtype>
6182: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
6183  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6184  "",
6185  []>, Sched<[]> {
6186  bits<3> Pg;
6187  bits<5> Rn;
6188  bits<5> Zt;
6189  bits<4> imm4;
6190  let Inst{31-25} = 0b1110010;
6191  let Inst{24-23} = sz;
6192  let Inst{22-21} = nregs;
6193  let Inst{20}    = 1;
6194  let Inst{19-16} = imm4;
6195  let Inst{15-13} = 0b111;
6196  let Inst{12-10} = Pg;
6197  let Inst{9-5}   = Rn;
6198  let Inst{4-0}   = Zt;
6199
6200  let hasSideEffects = 0;
6201  let mayStore = 1;
6202}
6203
6204multiclass sve_mem_est_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6205                          string asm, Operand immtype> {
6206  def NAME : sve_mem_est_si<sz, nregs, VecList, asm, immtype>;
6207
6208  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6209                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6210}
6211
6212
6213// SVE store multiple structures (quadwords, scalar plus immediate)
6214class sve_mem_128b_est_si<bits<2> nregs, RegisterOperand VecList,
6215                          string asm, Operand immtype>
6216    : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
6217        asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6218        "", []>, Sched<[]> {
6219  bits<5> Zt;
6220  bits<5> Rn;
6221  bits<3> Pg;
6222  bits<4> imm4;
6223  let Inst{31-24} = 0b11100100;
6224  let Inst{23-22} = nregs;
6225  let Inst{21-20} = 0b00;
6226  let Inst{19-16} = imm4;
6227  let Inst{15-13} = 0b000;
6228  let Inst{12-10} = Pg;
6229  let Inst{9-5}   = Rn;
6230  let Inst{4-0}   = Zt;
6231
6232  let hasSideEffects = 0;
6233  let mayStore = 1;
6234}
6235
6236multiclass sve_mem_128b_est_si<bits<2> nregs, RegisterOperand VecList,
6237                               string asm, Operand immtype> {
6238  def NAME : sve_mem_128b_est_si<nregs, VecList, asm, immtype>;
6239
6240  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6241                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6242}
6243
6244
6245class sve_mem_est_ss<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6246                     string asm, RegisterOperand gprty>
6247: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6248  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6249  "",
6250  []>, Sched<[]> {
6251  bits<3> Pg;
6252  bits<5> Rm;
6253  bits<5> Rn;
6254  bits<5> Zt;
6255  let Inst{31-25} = 0b1110010;
6256  let Inst{24-23} = sz;
6257  let Inst{22-21} = nregs;
6258  let Inst{20-16} = Rm;
6259  let Inst{15-13} = 0b011;
6260  let Inst{12-10} = Pg;
6261  let Inst{9-5}   = Rn;
6262  let Inst{4-0}   = Zt;
6263
6264  let hasSideEffects = 0;
6265  let mayStore = 1;
6266}
6267
6268
6269// SVE store multiple structures (quadwords, scalar plus scalar)
6270class sve_mem_128b_est_ss<bits<2> nregs, RegisterOperand VecList,
6271                          string asm, RegisterOperand gprty>
6272    : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6273        asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6274        "", []>, Sched<[]> {
6275  bits<5> Zt;
6276  bits<5> Rn;
6277  bits<3> Pg;
6278  bits<5> Rm;
6279  let Inst{31-24} = 0b11100100;
6280  let Inst{23-22} = nregs;
6281  let Inst{21}    = 0b1;
6282  let Inst{20-16} = Rm;
6283  let Inst{15-13} = 0b000;
6284  let Inst{12-10} = Pg;
6285  let Inst{9-5}   = Rn;
6286  let Inst{4-0}   = Zt;
6287
6288  let hasSideEffects = 0;
6289  let mayStore = 1;
6290}
6291
6292
6293class sve_mem_cst_ss_base<bits<4> dtype, string asm,
6294                          RegisterOperand listty, RegisterOperand gprty>
6295: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6296  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6297  "",
6298  []>, Sched<[]> {
6299  bits<3> Pg;
6300  bits<5> Rm;
6301  bits<5> Rn;
6302  bits<5> Zt;
6303  let Inst{31-25} = 0b1110010;
6304  let Inst{24-21} = dtype;
6305  let Inst{20-16} = Rm;
6306  let Inst{15-13} = 0b010;
6307  let Inst{12-10} = Pg;
6308  let Inst{9-5}   = Rn;
6309  let Inst{4-0}   = Zt;
6310
6311  let hasSideEffects = 0;
6312  let mayStore = 1;
6313}
6314
6315multiclass sve_mem_cst_ss<bits<4> dtype, string asm,
6316                          RegisterOperand listty, ZPRRegOp zprty,
6317                          RegisterOperand gprty> {
6318  def NAME : sve_mem_cst_ss_base<dtype, asm, listty, gprty>;
6319
6320  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Rm]",
6321                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
6322}
6323
6324class sve_mem_cstnt_si<bits<2> msz, string asm, RegisterOperand VecList>
6325: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
6326  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6327  "",
6328  []>, Sched<[]> {
6329  bits<3> Pg;
6330  bits<5> Rn;
6331  bits<5> Zt;
6332  bits<4> imm4;
6333  let Inst{31-25} = 0b1110010;
6334  let Inst{24-23} = msz;
6335  let Inst{22-20} = 0b001;
6336  let Inst{19-16} = imm4;
6337  let Inst{15-13} = 0b111;
6338  let Inst{12-10} = Pg;
6339  let Inst{9-5}   = Rn;
6340  let Inst{4-0}   = Zt;
6341
6342  let hasSideEffects = 0;
6343  let mayStore = 1;
6344}
6345
6346multiclass sve_mem_cstnt_si<bits<2> msz, string asm, RegisterOperand listty,
6347                            ZPRRegOp zprty> {
6348  def NAME : sve_mem_cstnt_si<msz, asm, listty>;
6349
6350  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6351                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
6352  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6353                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
6354  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6355                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6356}
6357
6358class sve_mem_cstnt_ss_base<bits<2> msz, string asm, RegisterOperand listty,
6359                            RegisterOperand gprty>
6360: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6361  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6362  "",
6363  []>, Sched<[]> {
6364  bits<3> Pg;
6365  bits<5> Rm;
6366  bits<5> Rn;
6367  bits<5> Zt;
6368  let Inst{31-25} = 0b1110010;
6369  let Inst{24-23} = msz;
6370  let Inst{22-21} = 0b00;
6371  let Inst{20-16} = Rm;
6372  let Inst{15-13} = 0b011;
6373  let Inst{12-10} = Pg;
6374  let Inst{9-5}   = Rn;
6375  let Inst{4-0}   = Zt;
6376
6377  let hasSideEffects = 0;
6378  let mayStore = 1;
6379}
6380
6381multiclass sve_mem_cstnt_ss<bits<2> msz, string asm, RegisterOperand listty,
6382                            ZPRRegOp zprty, RegisterOperand gprty> {
6383  def NAME : sve_mem_cstnt_ss_base<msz, asm, listty, gprty>;
6384
6385  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Rm]",
6386                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
6387}
6388
6389class sve2_mem_sstnt_vs_base<bits<3> opc, string asm,
6390                             RegisterOperand listty, ZPRRegOp zprty>
6391: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, zprty:$Zn, GPR64:$Rm),
6392  asm, "\t$Zt, $Pg, [$Zn, $Rm]",
6393  "",
6394  []>, Sched<[]> {
6395  bits<3> Pg;
6396  bits<5> Rm;
6397  bits<5> Zn;
6398  bits<5> Zt;
6399  let Inst{31-25} = 0b1110010;
6400  let Inst{24-22} = opc;
6401  let Inst{21}    = 0b0;
6402  let Inst{20-16} = Rm;
6403  let Inst{15-13} = 0b001;
6404  let Inst{12-10} = Pg;
6405  let Inst{9-5}   = Zn;
6406  let Inst{4-0}   = Zt;
6407
6408  let hasSideEffects = 0;
6409  let mayStore = 1;
6410}
6411
6412multiclass sve2_mem_sstnt_vs_32_ptrs<bits<3> opc, string asm,
6413                             SDPatternOperator op,
6414                             ValueType vt> {
6415  def _REAL : sve2_mem_sstnt_vs_base<opc, asm, Z_s, ZPR32>;
6416
6417  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $Rm]",
6418                 (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm), 0>;
6419  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6420                 (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 0>;
6421  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6422                 (!cast<Instruction>(NAME # _REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 1>;
6423
6424  def : Pat <(op (nxv4i32 ZPR32:$Zt), (nxv4i1 PPR3bAny:$Pg), (nxv4i32 ZPR32:$Zn), (i64 GPR64:$Rm), vt),
6425             (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm)>;
6426}
6427
6428multiclass sve2_mem_sstnt_vs_64_ptrs<bits<3> opc, string asm,
6429                             SDPatternOperator op,
6430                             ValueType vt> {
6431  def _REAL : sve2_mem_sstnt_vs_base<opc, asm, Z_d, ZPR64>;
6432
6433  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $Rm]",
6434                 (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm), 0>;
6435  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6436                 (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 0>;
6437  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6438                 (!cast<Instruction>(NAME # _REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
6439
6440  def : Pat <(op (nxv2i64 ZPR64:$Zt), (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64:$Rm), vt),
6441             (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
6442}
6443
6444class sve_mem_sst_sv<bits<3> opc, bit xs, bit scaled, string asm,
6445                     RegisterOperand VecList, RegisterOperand zprext>
6446: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
6447  asm, "\t$Zt, $Pg, [$Rn, $Zm]",
6448  "",
6449  []>, Sched<[]> {
6450  bits<3> Pg;
6451  bits<5> Rn;
6452  bits<5> Zm;
6453  bits<5> Zt;
6454  let Inst{31-25} = 0b1110010;
6455  let Inst{24-22} = opc;
6456  let Inst{21}    = scaled;
6457  let Inst{20-16} = Zm;
6458  let Inst{15}    = 0b1;
6459  let Inst{14}    = xs;
6460  let Inst{13}    = 0;
6461  let Inst{12-10} = Pg;
6462  let Inst{9-5}   = Rn;
6463  let Inst{4-0}   = Zt;
6464
6465  let hasSideEffects = 0;
6466  let mayStore = 1;
6467}
6468
6469multiclass sve_mem_32b_sst_sv_32_scaled<bits<3> opc, string asm,
6470                                    SDPatternOperator sxtw_op,
6471                                    SDPatternOperator uxtw_op,
6472                                    RegisterOperand sxtw_opnd,
6473                                    RegisterOperand uxtw_opnd,
6474                                    ValueType vt > {
6475  def _UXTW_SCALED : sve_mem_sst_sv<opc, 0, 1, asm, Z_s, uxtw_opnd>;
6476  def _SXTW_SCALED : sve_mem_sst_sv<opc, 1, 1, asm, Z_s, sxtw_opnd>;
6477
6478  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6479                 (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6480  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6481                 (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6482
6483  def : Pat<(uxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6484            (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6485  def : Pat<(sxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6486            (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6487}
6488
6489multiclass sve_mem_64b_sst_sv_32_scaled<bits<3> opc, string asm,
6490                                    SDPatternOperator sxtw_op,
6491                                    SDPatternOperator uxtw_op,
6492                                    RegisterOperand sxtw_opnd,
6493                                    RegisterOperand uxtw_opnd,
6494                                    ValueType vt > {
6495  def _UXTW_SCALED : sve_mem_sst_sv<opc, 0, 1, asm, Z_d, uxtw_opnd>;
6496  def _SXTW_SCALED : sve_mem_sst_sv<opc, 1, 1, asm, Z_d, sxtw_opnd>;
6497
6498  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6499                 (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6500  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6501                 (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6502
6503  def : Pat<(uxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6504            (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6505  def : Pat<(sxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6506            (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6507}
6508
6509multiclass sve_mem_64b_sst_sv_32_unscaled<bits<3> opc, string asm,
6510                                         SDPatternOperator sxtw_op,
6511                                         SDPatternOperator uxtw_op,
6512                                         RegisterOperand sxtw_opnd,
6513                                         RegisterOperand uxtw_opnd,
6514                                         ValueType vt> {
6515  def _UXTW : sve_mem_sst_sv<opc, 0, 0, asm, Z_d, uxtw_opnd>;
6516  def _SXTW : sve_mem_sst_sv<opc, 1, 0, asm, Z_d, sxtw_opnd>;
6517
6518  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6519                 (!cast<Instruction>(NAME # _UXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6520  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6521                 (!cast<Instruction>(NAME # _SXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6522
6523  def : Pat<(uxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6524            (!cast<Instruction>(NAME # _UXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6525  def : Pat<(sxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6526            (!cast<Instruction>(NAME # _SXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6527}
6528
6529multiclass sve_mem_32b_sst_sv_32_unscaled<bits<3> opc, string asm,
6530                                          SDPatternOperator sxtw_op,
6531                                          SDPatternOperator uxtw_op,
6532                                          RegisterOperand sxtw_opnd,
6533                                          RegisterOperand uxtw_opnd,
6534                                          ValueType vt> {
6535  def _UXTW : sve_mem_sst_sv<opc, 0, 0, asm, Z_s, uxtw_opnd>;
6536  def _SXTW : sve_mem_sst_sv<opc, 1, 0, asm, Z_s, sxtw_opnd>;
6537
6538  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6539                 (!cast<Instruction>(NAME # _UXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6540  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6541                 (!cast<Instruction>(NAME # _SXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6542
6543  def : Pat<(uxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6544            (!cast<Instruction>(NAME # _UXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6545  def : Pat<(sxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6546            (!cast<Instruction>(NAME # _SXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6547}
6548
6549class sve_mem_sst_sv2<bits<2> msz, bit scaled, string asm,
6550                      RegisterOperand zprext>
6551: I<(outs), (ins Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
6552  asm, "\t$Zt, $Pg, [$Rn, $Zm]",
6553  "",
6554  []>, Sched<[]> {
6555  bits<3> Pg;
6556  bits<5> Rn;
6557  bits<5> Zm;
6558  bits<5> Zt;
6559  let Inst{31-25} = 0b1110010;
6560  let Inst{24-23} = msz;
6561  let Inst{22}    = 0b0;
6562  let Inst{21}    = scaled;
6563  let Inst{20-16} = Zm;
6564  let Inst{15-13} = 0b101;
6565  let Inst{12-10} = Pg;
6566  let Inst{9-5}   = Rn;
6567  let Inst{4-0}   = Zt;
6568
6569  let hasSideEffects = 0;
6570  let mayStore = 1;
6571}
6572
6573multiclass sve_mem_sst_sv_64_scaled<bits<2> msz, string asm,
6574                                    SDPatternOperator op,
6575                                    RegisterOperand zprext,
6576                                    ValueType vt> {
6577  def _SCALED : sve_mem_sst_sv2<msz, 1, asm, zprext>;
6578
6579  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6580                 (!cast<Instruction>(NAME # _SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), 0>;
6581
6582  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt),
6583            (!cast<Instruction>(NAME # _SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
6584}
6585
6586multiclass sve_mem_sst_sv_64_unscaled<bits<2> msz, string asm,
6587                                      SDPatternOperator op,
6588                                      ValueType vt> {
6589  def NAME : sve_mem_sst_sv2<msz, 0, asm, ZPR64ExtLSL8>;
6590
6591  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6592                 (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), 0>;
6593
6594  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6595            (!cast<Instruction>(NAME) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6596}
6597
6598class sve_mem_sst_vi<bits<3> opc, string asm, ZPRRegOp zprty,
6599                     RegisterOperand VecList, Operand imm_ty>
6600: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, zprty:$Zn, imm_ty:$imm5),
6601  asm, "\t$Zt, $Pg, [$Zn, $imm5]",
6602  "",
6603  []>, Sched<[]> {
6604  bits<3> Pg;
6605  bits<5> imm5;
6606  bits<5> Zn;
6607  bits<5> Zt;
6608  let Inst{31-25} = 0b1110010;
6609  let Inst{24-23} = opc{2-1};
6610  let Inst{22}    = 0b1;
6611  let Inst{21}    = opc{0};
6612  let Inst{20-16} = imm5;
6613  let Inst{15-13} = 0b101;
6614  let Inst{12-10} = Pg;
6615  let Inst{9-5}   = Zn;
6616  let Inst{4-0}   = Zt;
6617
6618  let hasSideEffects = 0;
6619  let mayStore = 1;
6620}
6621
6622multiclass sve_mem_32b_sst_vi_ptrs<bits<3> opc, string asm,
6623                                   Operand imm_ty,
6624                                   SDPatternOperator op,
6625                                   ValueType vt> {
6626  def _IMM : sve_mem_sst_vi<opc, asm, ZPR32, Z_s, imm_ty>;
6627
6628  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6629                  (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 0>;
6630  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $imm5]",
6631                  (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), 0>;
6632  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6633                  (!cast<Instruction>(NAME # _IMM) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
6634
6635  def : Pat<(op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), (nxv4i32 ZPR:$ptrs), imm_ty:$index, vt),
6636            (!cast<Instruction>(NAME # _IMM) ZPR:$data, PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
6637}
6638
6639multiclass sve_mem_64b_sst_vi_ptrs<bits<3> opc, string asm,
6640                                   Operand imm_ty,
6641                                   SDPatternOperator op,
6642                                   ValueType vt> {
6643  def _IMM : sve_mem_sst_vi<opc, asm, ZPR64, Z_d, imm_ty>;
6644
6645  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6646                  (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 0>;
6647  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $imm5]",
6648                  (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), 0>;
6649  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6650                  (!cast<Instruction>(NAME # _IMM) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
6651
6652  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), (nxv2i64 ZPR:$ptrs), imm_ty:$index, vt),
6653            (!cast<Instruction>(NAME # _IMM) ZPR:$data, PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
6654}
6655
6656class sve_mem_z_spill<string asm>
6657: I<(outs), (ins ZPRAny:$Zt, GPR64sp:$Rn, simm9:$imm9),
6658  asm, "\t$Zt, [$Rn, $imm9, mul vl]",
6659  "",
6660  []>, Sched<[]> {
6661  bits<5> Rn;
6662  bits<5> Zt;
6663  bits<9> imm9;
6664  let Inst{31-22} = 0b1110010110;
6665  let Inst{21-16} = imm9{8-3};
6666  let Inst{15-13} = 0b010;
6667  let Inst{12-10} = imm9{2-0};
6668  let Inst{9-5}   = Rn;
6669  let Inst{4-0}   = Zt;
6670
6671  let hasSideEffects = 0;
6672  let mayStore = 1;
6673}
6674
6675multiclass sve_mem_z_spill<string asm> {
6676  def NAME : sve_mem_z_spill<asm>;
6677
6678  def : InstAlias<asm # "\t$Zt, [$Rn]",
6679                  (!cast<Instruction>(NAME) ZPRAny:$Zt, GPR64sp:$Rn, 0), 1>;
6680}
6681
6682class sve_mem_p_spill<string asm>
6683: I<(outs), (ins PPRAny:$Pt, GPR64sp:$Rn, simm9:$imm9),
6684  asm, "\t$Pt, [$Rn, $imm9, mul vl]",
6685  "",
6686  []>, Sched<[]> {
6687  bits<4> Pt;
6688  bits<5> Rn;
6689  bits<9> imm9;
6690  let Inst{31-22} = 0b1110010110;
6691  let Inst{21-16} = imm9{8-3};
6692  let Inst{15-13} = 0b000;
6693  let Inst{12-10} = imm9{2-0};
6694  let Inst{9-5}   = Rn;
6695  let Inst{4}     = 0b0;
6696  let Inst{3-0}   = Pt;
6697
6698  let hasSideEffects = 0;
6699  let mayStore = 1;
6700}
6701
6702multiclass sve_mem_p_spill<string asm> {
6703  def NAME : sve_mem_p_spill<asm>;
6704
6705  def : InstAlias<asm # "\t$Pt, [$Rn]",
6706                  (!cast<Instruction>(NAME) PPRAny:$Pt, GPR64sp:$Rn, 0), 1>;
6707}
6708
6709//===----------------------------------------------------------------------===//
6710// SVE Permute - Predicates Group
6711//===----------------------------------------------------------------------===//
6712
6713class sve_int_perm_bin_perm_pp<bits<3> opc, bits<2> sz8_64, string asm,
6714                               PPRRegOp pprty, SDPatternOperator op>
6715: I<(outs pprty:$Pd), (ins pprty:$Pn, pprty:$Pm),
6716  asm, "\t$Pd, $Pn, $Pm",
6717  "",
6718  [(set nxv16i1:$Pd, (op nxv16i1:$Pn, nxv16i1:$Pm))]>, Sched<[]> {
6719  bits<4> Pd;
6720  bits<4> Pm;
6721  bits<4> Pn;
6722  let Inst{31-24} = 0b00000101;
6723  let Inst{23-22} = sz8_64;
6724  let Inst{21-20} = 0b10;
6725  let Inst{19-16} = Pm;
6726  let Inst{15-13} = 0b010;
6727  let Inst{12-10} = opc;
6728  let Inst{9}     = 0b0;
6729  let Inst{8-5}   = Pn;
6730  let Inst{4}     = 0b0;
6731  let Inst{3-0}   = Pd;
6732
6733  let hasSideEffects = 0;
6734}
6735
6736multiclass sve_int_perm_bin_perm_pp<bits<3> opc, string asm,
6737                                    SDPatternOperator ir_op,
6738                                    SDPatternOperator op_b16,
6739                                    SDPatternOperator op_b32,
6740                                    SDPatternOperator op_b64> {
6741  def _B : sve_int_perm_bin_perm_pp<opc, 0b00, asm, PPR8,  ir_op>;
6742  def _H : sve_int_perm_bin_perm_pp<opc, 0b01, asm, PPR16, op_b16>;
6743  def _S : sve_int_perm_bin_perm_pp<opc, 0b10, asm, PPR32, op_b32>;
6744  def _D : sve_int_perm_bin_perm_pp<opc, 0b11, asm, PPR64, op_b64>;
6745
6746  def : SVE_2_Op_Pat<nxv8i1, ir_op, nxv8i1, nxv8i1, !cast<Instruction>(NAME # _H)>;
6747  def : SVE_2_Op_Pat<nxv4i1, ir_op, nxv4i1, nxv4i1, !cast<Instruction>(NAME # _S)>;
6748  def : SVE_2_Op_Pat<nxv2i1, ir_op, nxv2i1, nxv2i1, !cast<Instruction>(NAME # _D)>;
6749}
6750
6751class sve_int_perm_punpk<bit opc, string asm>
6752: I<(outs PPR16:$Pd), (ins PPR8:$Pn),
6753  asm, "\t$Pd, $Pn",
6754  "",
6755  []>, Sched<[]> {
6756  bits<4> Pd;
6757  bits<4> Pn;
6758  let Inst{31-17} = 0b000001010011000;
6759  let Inst{16}    = opc;
6760  let Inst{15-9}  = 0b0100000;
6761  let Inst{8-5}   = Pn;
6762  let Inst{4}     = 0b0;
6763  let Inst{3-0}   = Pd;
6764
6765  let hasSideEffects = 0;
6766}
6767
6768multiclass sve_int_perm_punpk<bit opc, string asm, SDPatternOperator op> {
6769  def NAME : sve_int_perm_punpk<opc, asm>;
6770
6771  def : SVE_1_Op_Pat<nxv8i1, op, nxv16i1, !cast<Instruction>(NAME)>;
6772  def : SVE_1_Op_Pat<nxv4i1, op, nxv8i1,  !cast<Instruction>(NAME)>;
6773  def : SVE_1_Op_Pat<nxv2i1, op, nxv4i1,  !cast<Instruction>(NAME)>;
6774}
6775
6776class sve_int_rdffr_pred<bit s, string asm>
6777: I<(outs PPR8:$Pd), (ins PPRAny:$Pg),
6778  asm, "\t$Pd, $Pg/z",
6779  "",
6780  []>, Sched<[]> {
6781  bits<4> Pd;
6782  bits<4> Pg;
6783  let Inst{31-23} = 0b001001010;
6784  let Inst{22}    = s;
6785  let Inst{21-9}  = 0b0110001111000;
6786  let Inst{8-5}   = Pg;
6787  let Inst{4}     = 0;
6788  let Inst{3-0}   = Pd;
6789
6790  let Defs = !if(s, [NZCV], []);
6791  let Uses = [FFR];
6792  let hasSideEffects = 1;
6793}
6794
6795multiclass sve_int_rdffr_pred<bit s, string asm, SDPatternOperator op> {
6796  def _REAL : sve_int_rdffr_pred<s, asm>;
6797
6798  // We need a layer of indirection because early machine code passes balk at
6799  // physical register (i.e. FFR) uses that have no previous definition.
6800  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
6801  def "" : Pseudo<(outs PPR8:$Pd), (ins PPRAny:$Pg), [(set (nxv16i1 PPR8:$Pd), (op (nxv16i1 PPRAny:$Pg)))]>,
6802           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) PPR8:$Pd, PPRAny:$Pg)>;
6803  }
6804}
6805
6806class sve_int_rdffr_unpred<string asm> : I<
6807  (outs PPR8:$Pd), (ins),
6808  asm, "\t$Pd",
6809  "",
6810  []>, Sched<[]> {
6811  bits<4> Pd;
6812  let Inst{31-4} = 0b0010010100011001111100000000;
6813  let Inst{3-0}   = Pd;
6814
6815  let Uses = [FFR];
6816  let hasSideEffects = 1;
6817}
6818
6819multiclass sve_int_rdffr_unpred<string asm, SDPatternOperator op> {
6820  def _REAL : sve_int_rdffr_unpred<asm>;
6821
6822  // We need a layer of indirection because early machine code passes balk at
6823  // physical register (i.e. FFR) uses that have no previous definition.
6824  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
6825  def "" : Pseudo<(outs PPR8:$Pd), (ins), [(set (nxv16i1 PPR8:$Pd), (op))]>,
6826           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) PPR8:$Pd)>;
6827  }
6828}
6829
6830class sve_int_wrffr<string asm, SDPatternOperator op>
6831: I<(outs), (ins PPR8:$Pn),
6832  asm, "\t$Pn",
6833  "",
6834  [(op (nxv16i1 PPR8:$Pn))]>, Sched<[]> {
6835  bits<4> Pn;
6836  let Inst{31-9} = 0b00100101001010001001000;
6837  let Inst{8-5}  = Pn;
6838  let Inst{4-0}  = 0b00000;
6839
6840  let Defs = [FFR];
6841  let hasSideEffects = 1;
6842}
6843
6844class sve_int_setffr<string asm, SDPatternOperator op>
6845: I<(outs), (ins),
6846  asm, "",
6847  "",
6848  [(op)]>, Sched<[]> {
6849  let Inst{31-0} = 0b00100101001011001001000000000000;
6850
6851  let Defs = [FFR];
6852  let hasSideEffects = 1;
6853}
6854
6855//===----------------------------------------------------------------------===//
6856// SVE Permute Vector - Predicated Group
6857//===----------------------------------------------------------------------===//
6858
6859class sve_int_perm_clast_rz<bits<2> sz8_64, bit ab, string asm,
6860                            ZPRRegOp zprty, RegisterClass rt>
6861: I<(outs rt:$Rdn), (ins PPR3bAny:$Pg, rt:$_Rdn, zprty:$Zm),
6862  asm, "\t$Rdn, $Pg, $_Rdn, $Zm",
6863  "",
6864  []>, Sched<[]> {
6865  bits<3> Pg;
6866  bits<5> Rdn;
6867  bits<5> Zm;
6868  let Inst{31-24} = 0b00000101;
6869  let Inst{23-22} = sz8_64;
6870  let Inst{21-17} = 0b11000;
6871  let Inst{16}    = ab;
6872  let Inst{15-13} = 0b101;
6873  let Inst{12-10} = Pg;
6874  let Inst{9-5}   = Zm;
6875  let Inst{4-0}   = Rdn;
6876
6877  let Constraints = "$Rdn = $_Rdn";
6878  let hasSideEffects = 0;
6879}
6880
6881multiclass sve_int_perm_clast_rz<bit ab, string asm, SDPatternOperator op> {
6882  def _B : sve_int_perm_clast_rz<0b00, ab, asm, ZPR8, GPR32>;
6883  def _H : sve_int_perm_clast_rz<0b01, ab, asm, ZPR16, GPR32>;
6884  def _S : sve_int_perm_clast_rz<0b10, ab, asm, ZPR32, GPR32>;
6885  def _D : sve_int_perm_clast_rz<0b11, ab, asm, ZPR64, GPR64>;
6886
6887  def : SVE_3_Op_Pat<i32, op, nxv16i1, i32, nxv16i8, !cast<Instruction>(NAME # _B)>;
6888  def : SVE_3_Op_Pat<i32, op, nxv8i1,  i32, nxv8i16, !cast<Instruction>(NAME # _H)>;
6889  def : SVE_3_Op_Pat<i32, op, nxv4i1,  i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
6890  def : SVE_3_Op_Pat<i64, op, nxv2i1,  i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
6891}
6892
6893class sve_int_perm_clast_vz<bits<2> sz8_64, bit ab, string asm,
6894                            ZPRRegOp zprty, RegisterClass rt>
6895: I<(outs rt:$Vdn), (ins PPR3bAny:$Pg, rt:$_Vdn, zprty:$Zm),
6896  asm, "\t$Vdn, $Pg, $_Vdn, $Zm",
6897  "",
6898  []>, Sched<[]> {
6899  bits<3> Pg;
6900  bits<5> Vdn;
6901  bits<5> Zm;
6902  let Inst{31-24} = 0b00000101;
6903  let Inst{23-22} = sz8_64;
6904  let Inst{21-17} = 0b10101;
6905  let Inst{16}    = ab;
6906  let Inst{15-13} = 0b100;
6907  let Inst{12-10} = Pg;
6908  let Inst{9-5}   = Zm;
6909  let Inst{4-0}   = Vdn;
6910
6911  let Constraints = "$Vdn = $_Vdn";
6912  let hasSideEffects = 0;
6913}
6914
6915multiclass sve_int_perm_clast_vz<bit ab, string asm, SDPatternOperator op> {
6916  def _B : sve_int_perm_clast_vz<0b00, ab, asm, ZPR8, FPR8>;
6917  def _H : sve_int_perm_clast_vz<0b01, ab, asm, ZPR16, FPR16>;
6918  def _S : sve_int_perm_clast_vz<0b10, ab, asm, ZPR32, FPR32>;
6919  def _D : sve_int_perm_clast_vz<0b11, ab, asm, ZPR64, FPR64>;
6920
6921  def : SVE_3_Op_Pat<f16, op, nxv8i1, f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
6922  def : SVE_3_Op_Pat<f32, op, nxv4i1, f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
6923  def : SVE_3_Op_Pat<f64, op, nxv2i1, f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
6924
6925  def : SVE_3_Op_Pat<bf16, op, nxv8i1, bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
6926}
6927
6928class sve_int_perm_clast_zz<bits<2> sz8_64, bit ab, string asm,
6929                            ZPRRegOp zprty>
6930: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
6931  asm, "\t$Zdn, $Pg, $_Zdn, $Zm",
6932  "",
6933  []>, Sched<[]> {
6934  bits<3> Pg;
6935  bits<5> Zdn;
6936  bits<5> Zm;
6937  let Inst{31-24} = 0b00000101;
6938  let Inst{23-22} = sz8_64;
6939  let Inst{21-17} = 0b10100;
6940  let Inst{16}    = ab;
6941  let Inst{15-13} = 0b100;
6942  let Inst{12-10} = Pg;
6943  let Inst{9-5}   = Zm;
6944  let Inst{4-0}   = Zdn;
6945
6946  let Constraints = "$Zdn = $_Zdn";
6947  let DestructiveInstType = DestructiveOther;
6948  let ElementSize = ElementSizeNone;
6949  let hasSideEffects = 0;
6950}
6951
6952multiclass sve_int_perm_clast_zz<bit ab, string asm, SDPatternOperator op> {
6953  def _B : sve_int_perm_clast_zz<0b00, ab, asm, ZPR8>;
6954  def _H : sve_int_perm_clast_zz<0b01, ab, asm, ZPR16>;
6955  def _S : sve_int_perm_clast_zz<0b10, ab, asm, ZPR32>;
6956  def _D : sve_int_perm_clast_zz<0b11, ab, asm, ZPR64>;
6957
6958  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
6959  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
6960  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
6961  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
6962
6963  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
6964  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
6965  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
6966
6967  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
6968}
6969
6970class sve_int_perm_last_r<bits<2> sz8_64, bit ab, string asm,
6971                          ZPRRegOp zprty, RegisterClass resultRegType>
6972: I<(outs resultRegType:$Rd), (ins PPR3bAny:$Pg, zprty:$Zn),
6973  asm, "\t$Rd, $Pg, $Zn",
6974  "",
6975  []>, Sched<[]> {
6976  bits<3> Pg;
6977  bits<5> Rd;
6978  bits<5> Zn;
6979  let Inst{31-24} = 0b00000101;
6980  let Inst{23-22} = sz8_64;
6981  let Inst{21-17} = 0b10000;
6982  let Inst{16}    = ab;
6983  let Inst{15-13} = 0b101;
6984  let Inst{12-10} = Pg;
6985  let Inst{9-5}   = Zn;
6986  let Inst{4-0}   = Rd;
6987
6988  let hasSideEffects = 0;
6989}
6990
6991multiclass sve_int_perm_last_r<bit ab, string asm, SDPatternOperator op> {
6992  def _B : sve_int_perm_last_r<0b00, ab, asm, ZPR8, GPR32>;
6993  def _H : sve_int_perm_last_r<0b01, ab, asm, ZPR16, GPR32>;
6994  def _S : sve_int_perm_last_r<0b10, ab, asm, ZPR32, GPR32>;
6995  def _D : sve_int_perm_last_r<0b11, ab, asm, ZPR64, GPR64>;
6996
6997  def : SVE_2_Op_Pat<i32, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
6998  def : SVE_2_Op_Pat<i32, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
6999  def : SVE_2_Op_Pat<i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7000  def : SVE_2_Op_Pat<i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7001}
7002
7003class sve_int_perm_last_v<bits<2> sz8_64, bit ab, string asm,
7004                          ZPRRegOp zprty, RegisterClass dstRegtype>
7005: I<(outs dstRegtype:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
7006  asm, "\t$Vd, $Pg, $Zn",
7007  "",
7008  []>, Sched<[]> {
7009  bits<3> Pg;
7010  bits<5> Vd;
7011  bits<5> Zn;
7012  let Inst{31-24} = 0b00000101;
7013  let Inst{23-22} = sz8_64;
7014  let Inst{21-17} = 0b10001;
7015  let Inst{16}    = ab;
7016  let Inst{15-13} = 0b100;
7017  let Inst{12-10} = Pg;
7018  let Inst{9-5}   = Zn;
7019  let Inst{4-0}   = Vd;
7020
7021  let hasSideEffects = 0;
7022}
7023
7024multiclass sve_int_perm_last_v<bit ab, string asm, SDPatternOperator op> {
7025  def _B : sve_int_perm_last_v<0b00, ab, asm, ZPR8, FPR8>;
7026  def _H : sve_int_perm_last_v<0b01, ab, asm, ZPR16, FPR16>;
7027  def _S : sve_int_perm_last_v<0b10, ab, asm, ZPR32, FPR32>;
7028  def _D : sve_int_perm_last_v<0b11, ab, asm, ZPR64, FPR64>;
7029
7030  def : SVE_2_Op_Pat<f16, op, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
7031  def : SVE_2_Op_Pat<f32, op, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
7032  def : SVE_2_Op_Pat<f32, op, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
7033  def : SVE_2_Op_Pat<f64, op, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
7034
7035  def : SVE_2_Op_Pat<bf16, op, nxv8i1,  nxv8bf16, !cast<Instruction>(NAME # _H)>;
7036}
7037
7038class sve_int_perm_splice<bits<2> sz8_64, string asm, ZPRRegOp zprty>
7039: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
7040  asm, "\t$Zdn, $Pg, $_Zdn, $Zm",
7041  "",
7042  []>, Sched<[]> {
7043  bits<3> Pg;
7044  bits<5> Zdn;
7045  bits<5> Zm;
7046  let Inst{31-24} = 0b00000101;
7047  let Inst{23-22} = sz8_64;
7048  let Inst{21-13} = 0b101100100;
7049  let Inst{12-10} = Pg;
7050  let Inst{9-5}   = Zm;
7051  let Inst{4-0}   = Zdn;
7052
7053  let Constraints = "$Zdn = $_Zdn";
7054  let DestructiveInstType = DestructiveOther;
7055  let ElementSize = ElementSizeNone;
7056  let hasSideEffects = 0;
7057}
7058
7059multiclass sve_int_perm_splice<string asm, SDPatternOperator op> {
7060  def _B : sve_int_perm_splice<0b00, asm, ZPR8>;
7061  def _H : sve_int_perm_splice<0b01, asm, ZPR16>;
7062  def _S : sve_int_perm_splice<0b10, asm, ZPR32>;
7063  def _D : sve_int_perm_splice<0b11, asm, ZPR64>;
7064
7065  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
7066  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
7067  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
7068  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
7069
7070  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1,  nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
7071  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1,  nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
7072  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1,  nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
7073
7074  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
7075}
7076
7077class sve2_int_perm_splice_cons<bits<2> sz8_64, string asm,
7078                               ZPRRegOp zprty, RegisterOperand VecList>
7079: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, VecList:$Zn),
7080  asm, "\t$Zd, $Pg, $Zn",
7081  "",
7082  []>, Sched<[]> {
7083  bits<3> Pg;
7084  bits<5> Zn;
7085  bits<5> Zd;
7086  let Inst{31-24} = 0b00000101;
7087  let Inst{23-22} = sz8_64;
7088  let Inst{21-13} = 0b101101100;
7089  let Inst{12-10} = Pg;
7090  let Inst{9-5}   = Zn;
7091  let Inst{4-0}   = Zd;
7092
7093  let hasSideEffects = 0;
7094}
7095
7096multiclass sve2_int_perm_splice_cons<string asm> {
7097  def _B : sve2_int_perm_splice_cons<0b00, asm, ZPR8,  ZZ_b>;
7098  def _H : sve2_int_perm_splice_cons<0b01, asm, ZPR16, ZZ_h>;
7099  def _S : sve2_int_perm_splice_cons<0b10, asm, ZPR32, ZZ_s>;
7100  def _D : sve2_int_perm_splice_cons<0b11, asm, ZPR64, ZZ_d>;
7101}
7102
7103class sve_int_perm_rev<bits<2> sz8_64, bits<2> opc, string asm,
7104                       ZPRRegOp zprty>
7105: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
7106  asm, "\t$Zd, $Pg/m, $Zn",
7107  "",
7108  []>, Sched<[]> {
7109  bits<5> Zd;
7110  bits<3> Pg;
7111  bits<5> Zn;
7112  let Inst{31-24} = 0b00000101;
7113  let Inst{23-22} = sz8_64;
7114  let Inst{21-18} = 0b1001;
7115  let Inst{17-16} = opc;
7116  let Inst{15-13} = 0b100;
7117  let Inst{12-10} = Pg;
7118  let Inst{9-5}   = Zn;
7119  let Inst{4-0}   = Zd;
7120
7121  let Constraints = "$Zd = $_Zd";
7122  let DestructiveInstType = DestructiveOther;
7123  let ElementSize = zprty.ElementSize;
7124  let hasSideEffects = 0;
7125}
7126
7127multiclass sve_int_perm_rev_rbit<string asm, SDPatternOperator op> {
7128  def _B : sve_int_perm_rev<0b00, 0b11, asm, ZPR8>;
7129  def _H : sve_int_perm_rev<0b01, 0b11, asm, ZPR16>;
7130  def _S : sve_int_perm_rev<0b10, 0b11, asm, ZPR32>;
7131  def _D : sve_int_perm_rev<0b11, 0b11, asm, ZPR64>;
7132
7133  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
7134  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
7135  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7136  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7137}
7138
7139multiclass sve_int_perm_rev_revb<string asm, SDPatternOperator op> {
7140  def _H : sve_int_perm_rev<0b01, 0b00, asm, ZPR16>;
7141  def _S : sve_int_perm_rev<0b10, 0b00, asm, ZPR32>;
7142  def _D : sve_int_perm_rev<0b11, 0b00, asm, ZPR64>;
7143
7144  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
7145  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7146  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7147}
7148
7149multiclass sve_int_perm_rev_revh<string asm, SDPatternOperator op> {
7150  def _S : sve_int_perm_rev<0b10, 0b01, asm, ZPR32>;
7151  def _D : sve_int_perm_rev<0b11, 0b01, asm, ZPR64>;
7152
7153  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7154  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7155}
7156
7157multiclass sve_int_perm_rev_revw<string asm, SDPatternOperator op> {
7158  def _D : sve_int_perm_rev<0b11, 0b10, asm, ZPR64>;
7159
7160  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7161}
7162
7163class sve_int_perm_cpy_r<bits<2> sz8_64, string asm, ZPRRegOp zprty,
7164                         RegisterClass srcRegType>
7165: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegType:$Rn),
7166  asm, "\t$Zd, $Pg/m, $Rn",
7167  "",
7168  []>, Sched<[]> {
7169  bits<3> Pg;
7170  bits<5> Rn;
7171  bits<5> Zd;
7172  let Inst{31-24} = 0b00000101;
7173  let Inst{23-22} = sz8_64;
7174  let Inst{21-13} = 0b101000101;
7175  let Inst{12-10} = Pg;
7176  let Inst{9-5}   = Rn;
7177  let Inst{4-0}   = Zd;
7178
7179  let Constraints = "$Zd = $_Zd";
7180  let DestructiveInstType = DestructiveOther;
7181  let ElementSize = zprty.ElementSize;
7182  let hasSideEffects = 0;
7183}
7184
7185multiclass sve_int_perm_cpy_r<string asm, SDPatternOperator op> {
7186  def _B : sve_int_perm_cpy_r<0b00, asm, ZPR8, GPR32sp>;
7187  def _H : sve_int_perm_cpy_r<0b01, asm, ZPR16, GPR32sp>;
7188  def _S : sve_int_perm_cpy_r<0b10, asm, ZPR32, GPR32sp>;
7189  def _D : sve_int_perm_cpy_r<0b11, asm, ZPR64, GPR64sp>;
7190
7191  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7192                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7193  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7194                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7195  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7196                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7197  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7198                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPR3bAny:$Pg, GPR64sp:$Rn), 1>;
7199
7200  def : Pat<(nxv16i8 (op nxv16i1:$pg, i32:$splat, nxv16i8:$passthru)),
7201            (!cast<Instruction>(NAME # _B) $passthru, $pg, $splat)>;
7202  def : Pat<(nxv8i16 (op nxv8i1:$pg, i32:$splat, nxv8i16:$passthru)),
7203            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7204  def : Pat<(nxv4i32 (op nxv4i1:$pg, i32:$splat, nxv4i32:$passthru)),
7205            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7206  def : Pat<(nxv2i64 (op nxv2i1:$pg, i64:$splat, nxv2i64:$passthru)),
7207            (!cast<Instruction>(NAME # _D) $passthru, $pg, $splat)>;
7208}
7209
7210class sve_int_perm_cpy_v<bits<2> sz8_64, string asm, ZPRRegOp zprty,
7211                         RegisterClass srcRegtype>
7212: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegtype:$Vn),
7213  asm, "\t$Zd, $Pg/m, $Vn",
7214  "",
7215  []>, Sched<[]> {
7216  bits<3> Pg;
7217  bits<5> Vn;
7218  bits<5> Zd;
7219  let Inst{31-24} = 0b00000101;
7220  let Inst{23-22} = sz8_64;
7221  let Inst{21-13} = 0b100000100;
7222  let Inst{12-10} = Pg;
7223  let Inst{9-5}   = Vn;
7224  let Inst{4-0}   = Zd;
7225
7226  let Constraints = "$Zd = $_Zd";
7227  let DestructiveInstType = DestructiveOther;
7228  let ElementSize = zprty.ElementSize;
7229  let hasSideEffects = 0;
7230}
7231
7232multiclass sve_int_perm_cpy_v<string asm, SDPatternOperator op> {
7233  def _B : sve_int_perm_cpy_v<0b00, asm, ZPR8, FPR8>;
7234  def _H : sve_int_perm_cpy_v<0b01, asm, ZPR16, FPR16>;
7235  def _S : sve_int_perm_cpy_v<0b10, asm, ZPR32, FPR32>;
7236  def _D : sve_int_perm_cpy_v<0b11, asm, ZPR64, FPR64>;
7237
7238  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7239                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPR3bAny:$Pg, FPR8:$Vn), 1>;
7240  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7241                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPR3bAny:$Pg, FPR16:$Vn), 1>;
7242  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7243                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPR3bAny:$Pg, FPR32:$Vn), 1>;
7244  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7245                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPR3bAny:$Pg, FPR64:$Vn), 1>;
7246
7247  def : Pat<(nxv8f16 (op nxv8i1:$pg, f16:$splat, nxv8f16:$passthru)),
7248            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7249  def : Pat<(nxv4f16 (op nxv4i1:$pg, f16:$splat, nxv4f16:$passthru)),
7250            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7251  def : Pat<(nxv2f16 (op nxv2i1:$pg, f16:$splat, nxv2f16:$passthru)),
7252            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7253  def : Pat<(nxv2f32 (op nxv2i1:$pg, f32:$splat, nxv2f32:$passthru)),
7254            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7255  def : Pat<(nxv4f32 (op nxv4i1:$pg, f32:$splat, nxv4f32:$passthru)),
7256            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7257  def : Pat<(nxv2f64 (op nxv2i1:$pg, f64:$splat, nxv2f64:$passthru)),
7258            (!cast<Instruction>(NAME # _D) $passthru, $pg, $splat)>;
7259
7260  def : Pat<(nxv8bf16 (op nxv8i1:$pg, bf16:$splat, nxv8bf16:$passthru)),
7261            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7262}
7263
7264class sve_int_perm_compact<bit sz, string asm, ZPRRegOp zprty>
7265: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
7266  asm, "\t$Zd, $Pg, $Zn",
7267  "",
7268  []>, Sched<[]> {
7269  bits<3> Pg;
7270  bits<5> Zd;
7271  bits<5> Zn;
7272  let Inst{31-23} = 0b000001011;
7273  let Inst{22}    = sz;
7274  let Inst{21-13} = 0b100001100;
7275  let Inst{12-10} = Pg;
7276  let Inst{9-5}   = Zn;
7277  let Inst{4-0}   = Zd;
7278
7279  let hasSideEffects = 0;
7280}
7281
7282multiclass sve_int_perm_compact<string asm, SDPatternOperator op> {
7283  def _S : sve_int_perm_compact<0b0, asm, ZPR32>;
7284  def _D : sve_int_perm_compact<0b1, asm, ZPR64>;
7285
7286  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
7287  def : SVE_2_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
7288  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
7289  def : SVE_2_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
7290}
7291
7292//===----------------------------------------------------------------------===//
7293// SVE Memory - Contiguous Load Group
7294//===----------------------------------------------------------------------===//
7295
7296class sve_mem_cld_si_base<bits<4> dtype, bit nf, string asm,
7297                          RegisterOperand VecList>
7298: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
7299  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7300  "",
7301  []>, Sched<[]> {
7302  bits<3> Pg;
7303  bits<5> Rn;
7304  bits<5> Zt;
7305  bits<4> imm4;
7306  let Inst{31-25} = 0b1010010;
7307  let Inst{24-21} = dtype;
7308  let Inst{20}    = nf;
7309  let Inst{19-16} = imm4;
7310  let Inst{15-13} = 0b101;
7311  let Inst{12-10} = Pg;
7312  let Inst{9-5}   = Rn;
7313  let Inst{4-0}   = Zt;
7314
7315  let Defs = !if(nf, [FFR], []);
7316  let Uses = !if(nf, [FFR], []);
7317  let hasSideEffects = nf;
7318  let mayLoad = 1;
7319}
7320
7321multiclass sve_mem_cld_si<bits<4> dtype, string asm, RegisterOperand listty,
7322                          ZPRRegOp zprty> {
7323  def "" : sve_mem_cld_si_base<dtype, 0, asm, listty>;
7324
7325  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7326                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7327  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7328                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
7329  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7330                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7331}
7332
7333class sve_mem_cldnt_si_base<bits<2> msz, string asm, RegisterOperand VecList>
7334: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
7335  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7336  "",
7337  []>, Sched<[]> {
7338  bits<5> Zt;
7339  bits<3> Pg;
7340  bits<5> Rn;
7341  bits<4> imm4;
7342  let Inst{31-25} = 0b1010010;
7343  let Inst{24-23} = msz;
7344  let Inst{22-20} = 0b000;
7345  let Inst{19-16} = imm4;
7346  let Inst{15-13} = 0b111;
7347  let Inst{12-10} = Pg;
7348  let Inst{9-5}   = Rn;
7349  let Inst{4-0}   = Zt;
7350
7351  let hasSideEffects = 0;
7352  let mayLoad = 1;
7353}
7354
7355multiclass sve_mem_cldnt_si<bits<2> msz, string asm, RegisterOperand listty,
7356                            ZPRRegOp zprty> {
7357  def NAME : sve_mem_cldnt_si_base<msz, asm, listty>;
7358
7359  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7360                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7361  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7362                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
7363  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7364                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7365}
7366
7367class sve_mem_cldnt_ss_base<bits<2> msz, string asm, RegisterOperand VecList,
7368                            RegisterOperand gprty>
7369: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7370  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7371  "",
7372  []>, Sched<[]> {
7373  bits<3> Pg;
7374  bits<5> Rm;
7375  bits<5> Rn;
7376  bits<5> Zt;
7377  let Inst{31-25} = 0b1010010;
7378  let Inst{24-23} = msz;
7379  let Inst{22-21} = 0b00;
7380  let Inst{20-16} = Rm;
7381  let Inst{15-13} = 0b110;
7382  let Inst{12-10} = Pg;
7383  let Inst{9-5}   = Rn;
7384  let Inst{4-0}   = Zt;
7385
7386  let hasSideEffects = 0;
7387  let mayLoad = 1;
7388}
7389
7390multiclass sve_mem_cldnt_ss<bits<2> msz, string asm, RegisterOperand listty,
7391                            ZPRRegOp zprty, RegisterOperand gprty> {
7392  def NAME : sve_mem_cldnt_ss_base<msz, asm, listty, gprty>;
7393
7394  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7395                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7396}
7397
7398class sve_mem_ldqr_si<bits<2> sz, string asm, RegisterOperand VecList>
7399: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4),
7400  asm, "\t$Zt, $Pg/z, [$Rn, $imm4]", "", []>, Sched<[]> {
7401  bits<5> Zt;
7402  bits<5> Rn;
7403  bits<3> Pg;
7404  bits<4> imm4;
7405  let Inst{31-25} = 0b1010010;
7406  let Inst{24-23} = sz;
7407  let Inst{22-20} = 0;
7408  let Inst{19-16} = imm4;
7409  let Inst{15-13} = 0b001;
7410  let Inst{12-10} = Pg;
7411  let Inst{9-5}   = Rn;
7412  let Inst{4-0}   = Zt;
7413
7414  let hasSideEffects = 0;
7415  let mayLoad = 1;
7416}
7417
7418multiclass sve_mem_ldqr_si<bits<2> sz, string asm, RegisterOperand listty,
7419                           ZPRRegOp zprty> {
7420  def NAME : sve_mem_ldqr_si<sz, asm, listty>;
7421  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7422                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7423  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7424                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7425  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4]",
7426                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4), 0>;
7427}
7428
7429class sve_mem_ldqr_ss<bits<2> sz, string asm, RegisterOperand VecList,
7430                      RegisterOperand gprty>
7431: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7432  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]", "", []>, Sched<[]> {
7433  bits<5> Zt;
7434  bits<3> Pg;
7435  bits<5> Rn;
7436  bits<5> Rm;
7437  let Inst{31-25} = 0b1010010;
7438  let Inst{24-23} = sz;
7439  let Inst{22-21} = 0;
7440  let Inst{20-16} = Rm;
7441  let Inst{15-13} = 0;
7442  let Inst{12-10} = Pg;
7443  let Inst{9-5}   = Rn;
7444  let Inst{4-0}   = Zt;
7445
7446  let hasSideEffects = 0;
7447  let mayLoad = 1;
7448}
7449
7450multiclass sve_mem_ldqr_ss<bits<2> sz, string asm, RegisterOperand listty,
7451                           ZPRRegOp zprty, RegisterOperand gprty> {
7452  def NAME : sve_mem_ldqr_ss<sz, asm, listty, gprty>;
7453
7454  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7455                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7456}
7457
7458class sve_mem_ld_dup<bits<2> dtypeh, bits<2> dtypel, string asm,
7459                     RegisterOperand VecList, Operand immtype>
7460: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm6),
7461  asm, "\t$Zt, $Pg/z, [$Rn, $imm6]",
7462  "",
7463  []>, Sched<[]> {
7464  bits<3> Pg;
7465  bits<5> Rn;
7466  bits<5> Zt;
7467  bits<6> imm6;
7468  let Inst{31-25} = 0b1000010;
7469  let Inst{24-23} = dtypeh;
7470  let Inst{22}    = 1;
7471  let Inst{21-16} = imm6;
7472  let Inst{15}    = 0b1;
7473  let Inst{14-13} = dtypel;
7474  let Inst{12-10} = Pg;
7475  let Inst{9-5}   = Rn;
7476  let Inst{4-0}   = Zt;
7477
7478  let hasSideEffects = 0;
7479  let mayLoad = 1;
7480}
7481
7482multiclass sve_mem_ld_dup<bits<2> dtypeh, bits<2> dtypel, string asm,
7483                          RegisterOperand zlistty, ZPRRegOp zprty, Operand immtype> {
7484  def NAME : sve_mem_ld_dup<dtypeh, dtypel, asm, zlistty, immtype>;
7485
7486  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7487                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7488  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm6]",
7489                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm6), 0>;
7490  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7491                  (!cast<Instruction>(NAME) zlistty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7492}
7493
7494class sve_mem_cld_ss_base<bits<4> dtype, bit ff, dag iops, string asm,
7495                          RegisterOperand VecList>
7496: I<(outs VecList:$Zt), iops,
7497  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7498  "",
7499  []>, Sched<[]> {
7500  bits<5> Zt;
7501  bits<3> Pg;
7502  bits<5> Rm;
7503  bits<5> Rn;
7504  let Inst{31-25} = 0b1010010;
7505  let Inst{24-21} = dtype;
7506  let Inst{20-16} = Rm;
7507  let Inst{15-14} = 0b01;
7508  let Inst{13}    = ff;
7509  let Inst{12-10} = Pg;
7510  let Inst{9-5}   = Rn;
7511  let Inst{4-0}   = Zt;
7512
7513  let Defs = !if(ff, [FFR], []);
7514  let Uses = !if(ff, [FFR], []);
7515  let hasSideEffects = ff;
7516  let mayLoad = 1;
7517}
7518
7519multiclass sve_mem_cld_ss<bits<4> dtype, string asm, RegisterOperand listty,
7520                          ZPRRegOp zprty, RegisterOperand gprty> {
7521  def "" : sve_mem_cld_ss_base<dtype, 0, (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7522                               asm, listty>;
7523
7524  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7525                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7526}
7527
7528multiclass sve_mem_cldff_ss<bits<4> dtype, string asm, RegisterOperand listty,
7529                            ZPRRegOp zprty, RegisterOperand gprty> {
7530  def _REAL : sve_mem_cld_ss_base<dtype, 1, (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7531                                  asm, listty>;
7532
7533  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7534                 (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7535
7536  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7537                 (!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 1>;
7538
7539  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7540                 (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 0>;
7541
7542  // We need a layer of indirection because early machine code passes balk at
7543  // physical register (i.e. FFR) uses that have no previous definition.
7544  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7545  def "" : Pseudo<(outs listty:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), []>,
7546           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm)>;
7547  }
7548}
7549
7550multiclass sve_mem_cldnf_si<bits<4> dtype, string asm, RegisterOperand listty,
7551                            ZPRRegOp zprty> {
7552  def _REAL : sve_mem_cld_si_base<dtype, 1, asm, listty>;
7553
7554  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7555                  (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7556  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7557                  (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
7558  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7559                  (!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7560
7561  // We need a layer of indirection because early machine code passes balk at
7562  // physical register (i.e. FFR) uses that have no previous definition.
7563  let hasSideEffects = 1, hasNoSchedulingInfo = 1, mayLoad = 1 in {
7564  def "" : Pseudo<(outs listty:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), []>,
7565           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4)>;
7566  }
7567}
7568
7569class sve_mem_eld_si<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7570                     string asm, Operand immtype>
7571: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
7572  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7573  "",
7574  []>, Sched<[]> {
7575  bits<5> Zt;
7576  bits<3> Pg;
7577  bits<5> Rn;
7578  bits<4> imm4;
7579  let Inst{31-25} = 0b1010010;
7580  let Inst{24-23} = sz;
7581  let Inst{22-21} = nregs{1-0};
7582  let Inst{20}    = nregs{2};
7583  let Inst{19-16} = imm4;
7584  let Inst{15-13} = 0b111;
7585  let Inst{12-10} = Pg;
7586  let Inst{9-5}   = Rn;
7587  let Inst{4-0}   = Zt;
7588
7589  let hasSideEffects = 0;
7590  let mayLoad = 1;
7591}
7592
7593multiclass sve_mem_eld_si<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7594                          string asm, Operand immtype> {
7595  def NAME : sve_mem_eld_si<sz, nregs, VecList, asm, immtype>;
7596
7597  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7598                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7599}
7600
7601
7602class sve_mem_eld_ss<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7603                     string asm, RegisterOperand gprty>
7604: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7605  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7606  "",
7607  []>, Sched<[]> {
7608  bits<3> Pg;
7609  bits<5> Rm;
7610  bits<5> Rn;
7611  bits<5> Zt;
7612  let Inst{31-25} = 0b1010010;
7613  let Inst{24-23} = sz;
7614  let Inst{22-21} = nregs{1-0};
7615  let Inst{20-16} = Rm;
7616  let Inst{15}    = 0b1;
7617  let Inst{14}    = nregs{2};
7618  let Inst{13}    = 0b0;
7619  let Inst{12-10} = Pg;
7620  let Inst{9-5}   = Rn;
7621  let Inst{4-0}   = Zt;
7622
7623  let hasSideEffects = 0;
7624  let mayLoad = 1;
7625}
7626
7627//===----------------------------------------------------------------------===//
7628// SVE Memory - 32-bit Gather and Unsized Contiguous Group
7629//===----------------------------------------------------------------------===//
7630
7631// bit xs      is '1' if offsets are signed
7632// bit scaled  is '1' if the offsets are scaled
7633class sve_mem_32b_gld_sv<bits<4> opc, bit xs, bit scaled, string asm,
7634                         RegisterOperand zprext>
7635: I<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
7636  asm, "\t$Zt, $Pg/z, [$Rn, $Zm]",
7637  "",
7638  []>, Sched<[]> {
7639  bits<3> Pg;
7640  bits<5> Rn;
7641  bits<5> Zm;
7642  bits<5> Zt;
7643  let Inst{31-25} = 0b1000010;
7644  let Inst{24-23} = opc{3-2};
7645  let Inst{22}    = xs;
7646  let Inst{21}    = scaled;
7647  let Inst{20-16} = Zm;
7648  let Inst{15}    = 0b0;
7649  let Inst{14-13} = opc{1-0};
7650  let Inst{12-10} = Pg;
7651  let Inst{9-5}   = Rn;
7652  let Inst{4-0}   = Zt;
7653
7654
7655  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
7656  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
7657  let hasSideEffects = opc{0};
7658  let mayLoad = 1;
7659}
7660
7661multiclass sve_mem_32b_gld_sv_32_scaled<bits<4> opc, string asm,
7662                                        SDPatternOperator sxtw_op,
7663                                        SDPatternOperator uxtw_op,
7664                                        RegisterOperand sxtw_opnd,
7665                                        RegisterOperand uxtw_opnd,
7666                                        ValueType vt> {
7667  def _UXTW_SCALED_REAL : sve_mem_32b_gld_sv<opc, 0, 1, asm, uxtw_opnd>;
7668  def _SXTW_SCALED_REAL : sve_mem_32b_gld_sv<opc, 1, 1, asm, sxtw_opnd>;
7669
7670  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7671                  (!cast<Instruction>(NAME # _UXTW_SCALED_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
7672  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7673                  (!cast<Instruction>(NAME # _SXTW_SCALED_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
7674
7675  // We need a layer of indirection because early machine code passes balk at
7676  // physical register (i.e. FFR) uses that have no previous definition.
7677  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7678  def _UXTW_SCALED : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
7679                     PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_SCALED_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
7680  def _SXTW_SCALED : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
7681                     PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_SCALED_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
7682  }
7683
7684  def : Pat<(nxv4i32 (uxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$indices), vt)),
7685            (!cast<Instruction>(NAME # _UXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
7686  def : Pat<(nxv4i32 (sxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$indices), vt)),
7687            (!cast<Instruction>(NAME # _SXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
7688}
7689
7690multiclass sve_mem_32b_gld_vs_32_unscaled<bits<4> opc, string asm,
7691                                          SDPatternOperator sxtw_op,
7692                                          SDPatternOperator uxtw_op,
7693                                          RegisterOperand sxtw_opnd,
7694                                          RegisterOperand uxtw_opnd,
7695                                          ValueType vt> {
7696  def _UXTW_REAL : sve_mem_32b_gld_sv<opc, 0, 0, asm, uxtw_opnd>;
7697  def _SXTW_REAL : sve_mem_32b_gld_sv<opc, 1, 0, asm, sxtw_opnd>;
7698
7699  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7700                  (!cast<Instruction>(NAME # _UXTW_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
7701  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7702                  (!cast<Instruction>(NAME # _SXTW_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
7703
7704  // We need a layer of indirection because early machine code passes balk at
7705  // physical register (i.e. FFR) uses that have no previous definition.
7706  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7707  def _UXTW : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
7708              PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
7709  def _SXTW : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
7710              PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
7711  }
7712
7713  def : Pat<(nxv4i32 (uxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt)),
7714            (!cast<Instruction>(NAME # _UXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
7715  def : Pat<(nxv4i32 (sxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt)),
7716            (!cast<Instruction>(NAME # _SXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
7717}
7718
7719
7720class sve_mem_32b_gld_vi<bits<4> opc, string asm, Operand imm_ty>
7721: I<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5),
7722  asm, "\t$Zt, $Pg/z, [$Zn, $imm5]",
7723  "",
7724  []>, Sched<[]> {
7725  bits<3> Pg;
7726  bits<5> Zn;
7727  bits<5> Zt;
7728  bits<5> imm5;
7729  let Inst{31-25} = 0b1000010;
7730  let Inst{24-23} = opc{3-2};
7731  let Inst{22-21} = 0b01;
7732  let Inst{20-16} = imm5;
7733  let Inst{15}    = 0b1;
7734  let Inst{14-13} = opc{1-0};
7735  let Inst{12-10} = Pg;
7736  let Inst{9-5}   = Zn;
7737  let Inst{4-0}   = Zt;
7738
7739
7740  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
7741  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
7742  let hasSideEffects = opc{0};
7743  let mayLoad = 1;
7744}
7745
7746multiclass sve_mem_32b_gld_vi_32_ptrs<bits<4> opc, string asm, Operand imm_ty,
7747                                      SDPatternOperator op, ValueType vt> {
7748  def _IMM_REAL : sve_mem_32b_gld_vi<opc, asm, imm_ty>;
7749
7750  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7751                  (!cast<Instruction>(NAME # _IMM_REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 0>;
7752  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $imm5]",
7753                  (!cast<Instruction>(NAME # _IMM_REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), 0>;
7754  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7755                  (!cast<Instruction>(NAME # _IMM_REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
7756
7757  // We need a layer of indirection because early machine code passes balk at
7758  // physical register (i.e. FFR) uses that have no previous definition.
7759  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7760  def _IMM : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), []>,
7761             PseudoInstExpansion<(!cast<Instruction>(NAME # _IMM_REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5)>;
7762  }
7763
7764  def : Pat<(nxv4i32 (op (nxv4i1 PPR:$gp), (nxv4i32 ZPR:$ptrs), imm_ty:$index, vt)),
7765            (!cast<Instruction>(NAME # _IMM) PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
7766}
7767
7768class sve_mem_prfm_si<bits<2> msz, string asm>
7769: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, simm6s1:$imm6),
7770  asm, "\t$prfop, $Pg, [$Rn, $imm6, mul vl]",
7771  "",
7772  []>, Sched<[]> {
7773  bits<5> Rn;
7774  bits<3> Pg;
7775  bits<6> imm6;
7776  bits<4> prfop;
7777  let Inst{31-22} = 0b1000010111;
7778  let Inst{21-16} = imm6;
7779  let Inst{15}    = 0b0;
7780  let Inst{14-13} = msz;
7781  let Inst{12-10} = Pg;
7782  let Inst{9-5}   = Rn;
7783  let Inst{4}     = 0b0;
7784  let Inst{3-0}   = prfop;
7785
7786  let hasSideEffects = 1;
7787}
7788
7789multiclass sve_mem_prfm_si<bits<2> msz, string asm> {
7790  def NAME : sve_mem_prfm_si<msz, asm>;
7791
7792  def : InstAlias<asm # "\t$prfop, $Pg, [$Rn]",
7793                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7794}
7795
7796class sve_mem_prfm_ss<bits<3> opc, string asm, RegisterOperand gprty>
7797: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7798  asm, "\t$prfop, $Pg, [$Rn, $Rm]",
7799  "",
7800  []>, Sched<[]> {
7801  bits<5> Rm;
7802  bits<5> Rn;
7803  bits<3> Pg;
7804  bits<4> prfop;
7805  let Inst{31-25} = 0b1000010;
7806  let Inst{24-23} = opc{2-1};
7807  let Inst{22-21} = 0b00;
7808  let Inst{20-16} = Rm;
7809  let Inst{15}    = 0b1;
7810  let Inst{14}    = opc{0};
7811  let Inst{13}    = 0b0;
7812  let Inst{12-10} = Pg;
7813  let Inst{9-5}   = Rn;
7814  let Inst{4}     = 0b0;
7815  let Inst{3-0}   = prfop;
7816
7817  let hasSideEffects = 1;
7818}
7819
7820class sve_mem_32b_prfm_sv<bits<2> msz, bit xs, string asm,
7821                          RegisterOperand zprext>
7822: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
7823  asm, "\t$prfop, $Pg, [$Rn, $Zm]",
7824  "",
7825  []>, Sched<[]> {
7826  bits<3> Pg;
7827  bits<5> Rn;
7828  bits<5> Zm;
7829  bits<4> prfop;
7830  let Inst{31-23} = 0b100001000;
7831  let Inst{22}    = xs;
7832  let Inst{21}    = 0b1;
7833  let Inst{20-16} = Zm;
7834  let Inst{15}    = 0b0;
7835  let Inst{14-13} = msz;
7836  let Inst{12-10} = Pg;
7837  let Inst{9-5}   = Rn;
7838  let Inst{4}     = 0b0;
7839  let Inst{3-0}   = prfop;
7840
7841  let hasSideEffects = 1;
7842}
7843
7844multiclass sve_mem_32b_prfm_sv_scaled<bits<2> msz, string asm,
7845                                      RegisterOperand sxtw_opnd,
7846                                      RegisterOperand uxtw_opnd,
7847                                      SDPatternOperator op_sxtw,
7848                                      SDPatternOperator op_uxtw> {
7849  def _UXTW_SCALED : sve_mem_32b_prfm_sv<msz, 0, asm, uxtw_opnd>;
7850  def _SXTW_SCALED : sve_mem_32b_prfm_sv<msz, 1, asm, sxtw_opnd>;
7851
7852  def : Pat<(op_uxtw (nxv4i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv4i32 uxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
7853            (!cast<Instruction>(NAME # _UXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
7854
7855  def : Pat<(op_sxtw (nxv4i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv4i32 sxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
7856            (!cast<Instruction>(NAME # _SXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
7857}
7858
7859class sve_mem_32b_prfm_vi<bits<2> msz, string asm, Operand imm_ty>
7860: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5),
7861  asm, "\t$prfop, $Pg, [$Zn, $imm5]",
7862  "",
7863  []>, Sched<[]> {
7864  bits<3> Pg;
7865  bits<5> Zn;
7866  bits<5> imm5;
7867  bits<4> prfop;
7868  let Inst{31-25} = 0b1000010;
7869  let Inst{24-23} = msz;
7870  let Inst{22-21} = 0b00;
7871  let Inst{20-16} = imm5;
7872  let Inst{15-13} = 0b111;
7873  let Inst{12-10} = Pg;
7874  let Inst{9-5}   = Zn;
7875  let Inst{4}     = 0b0;
7876  let Inst{3-0}   = prfop;
7877
7878  let hasSideEffects = 1;
7879}
7880
7881multiclass sve_mem_32b_prfm_vi<bits<2> msz, string asm, Operand imm_ty, SDPatternOperator op> {
7882  def NAME : sve_mem_32b_prfm_vi<msz, asm, imm_ty>;
7883
7884  def : InstAlias<asm # "\t$prfop, $Pg, [$Zn]",
7885                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
7886
7887  def : Pat<(op (nxv4i1 PPR_3b:$Pg), (nxv4i32 ZPR32:$Zn), (i64 imm_ty:$imm), (i32 sve_prfop:$prfop)),
7888            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR_3b:$Pg, ZPR32:$Zn, imm_ty:$imm)>;
7889}
7890
7891class sve_mem_z_fill<string asm>
7892: I<(outs ZPRAny:$Zt), (ins GPR64sp:$Rn, simm9:$imm9),
7893  asm, "\t$Zt, [$Rn, $imm9, mul vl]",
7894  "",
7895  []>, Sched<[]> {
7896  bits<5> Rn;
7897  bits<5> Zt;
7898  bits<9> imm9;
7899  let Inst{31-22} = 0b1000010110;
7900  let Inst{21-16} = imm9{8-3};
7901  let Inst{15-13} = 0b010;
7902  let Inst{12-10} = imm9{2-0};
7903  let Inst{9-5}   = Rn;
7904  let Inst{4-0}   = Zt;
7905
7906  let hasSideEffects = 0;
7907  let mayLoad = 1;
7908}
7909
7910multiclass sve_mem_z_fill<string asm> {
7911  def NAME : sve_mem_z_fill<asm>;
7912
7913  def : InstAlias<asm # "\t$Zt, [$Rn]",
7914                  (!cast<Instruction>(NAME) ZPRAny:$Zt, GPR64sp:$Rn, 0), 1>;
7915}
7916
7917class sve_mem_p_fill<string asm>
7918: I<(outs PPRAny:$Pt), (ins GPR64sp:$Rn, simm9:$imm9),
7919  asm, "\t$Pt, [$Rn, $imm9, mul vl]",
7920  "",
7921  []>, Sched<[]> {
7922  bits<4> Pt;
7923  bits<5> Rn;
7924  bits<9> imm9;
7925  let Inst{31-22} = 0b1000010110;
7926  let Inst{21-16} = imm9{8-3};
7927  let Inst{15-13} = 0b000;
7928  let Inst{12-10} = imm9{2-0};
7929  let Inst{9-5}   = Rn;
7930  let Inst{4}     = 0b0;
7931  let Inst{3-0}   = Pt;
7932
7933  let hasSideEffects = 0;
7934  let mayLoad = 1;
7935}
7936
7937multiclass sve_mem_p_fill<string asm> {
7938  def NAME : sve_mem_p_fill<asm>;
7939
7940  def : InstAlias<asm # "\t$Pt, [$Rn]",
7941                  (!cast<Instruction>(NAME) PPRAny:$Pt, GPR64sp:$Rn, 0), 1>;
7942}
7943
7944class sve2_mem_gldnt_vs_base<bits<5> opc, dag iops, string asm,
7945                             RegisterOperand VecList>
7946: I<(outs VecList:$Zt), iops,
7947  asm, "\t$Zt, $Pg/z, [$Zn, $Rm]",
7948  "",
7949  []>, Sched<[]> {
7950  bits<3> Pg;
7951  bits<5> Rm;
7952  bits<5> Zn;
7953  bits<5> Zt;
7954  let Inst{31}    = 0b1;
7955  let Inst{30}    = opc{4};
7956  let Inst{29-25} = 0b00010;
7957  let Inst{24-23} = opc{3-2};
7958  let Inst{22-21} = 0b00;
7959  let Inst{20-16} = Rm;
7960  let Inst{15}    = 0b1;
7961  let Inst{14-13} = opc{1-0};
7962  let Inst{12-10} = Pg;
7963  let Inst{9-5}   = Zn;
7964  let Inst{4-0}   = Zt;
7965
7966  let hasSideEffects = 0;
7967  let mayLoad = 1;
7968}
7969
7970multiclass sve2_mem_gldnt_vs_32_ptrs<bits<5> opc, string asm,
7971                                  SDPatternOperator op,
7972                                  ValueType vt> {
7973  def _REAL : sve2_mem_gldnt_vs_base<opc, (ins PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm),
7974                                     asm, Z_s>;
7975
7976  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $Rm]",
7977                 (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm), 0>;
7978  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7979                 (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 0>;
7980  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7981                 (!cast<Instruction>(NAME # _REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 1>;
7982
7983  def : Pat <(nxv4i32 (op (nxv4i1 PPR3bAny:$Pg), (nxv4i32 ZPR32:$Zd), (i64 GPR64:$Rm), vt)),
7984             (!cast<Instruction>(NAME # _REAL) PPR3bAny:$Pg, ZPR32:$Zd, GPR64:$Rm)>;
7985}
7986
7987multiclass sve2_mem_gldnt_vs_64_ptrs<bits<5> opc, string asm,
7988                                   SDPatternOperator op,
7989                                   ValueType vt> {
7990  def _REAL : sve2_mem_gldnt_vs_base<opc, (ins PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
7991                                     asm, Z_d>;
7992
7993  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $Rm]",
7994                 (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm), 0>;
7995  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7996                 (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 0>;
7997  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7998                 (!cast<Instruction>(NAME # _REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
7999
8000  def : Pat <(nxv2i64 (op (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zd), (i64 GPR64:$Rm), vt)),
8001             (!cast<Instruction>(NAME # _REAL) PPR3bAny:$Pg, ZPR64:$Zd, GPR64:$Rm)>;
8002}
8003
8004//===----------------------------------------------------------------------===//
8005// SVE Memory - 64-bit Gather Group
8006//===----------------------------------------------------------------------===//
8007
8008// bit xs      is '1' if offsets are signed
8009// bit scaled  is '1' if the offsets are scaled
8010// bit lsl     is '0' if the offsets are extended (uxtw/sxtw), '1' if shifted (lsl)
8011class sve_mem_64b_gld_sv<bits<4> opc, bit xs, bit scaled, bit lsl, string asm,
8012                         RegisterOperand zprext>
8013: I<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
8014  asm, "\t$Zt, $Pg/z, [$Rn, $Zm]",
8015  "",
8016  []>, Sched<[]> {
8017  bits<3> Pg;
8018  bits<5> Rn;
8019  bits<5> Zm;
8020  bits<5> Zt;
8021  let Inst{31-25} = 0b1100010;
8022  let Inst{24-23} = opc{3-2};
8023  let Inst{22}    = xs;
8024  let Inst{21}    = scaled;
8025  let Inst{20-16} = Zm;
8026  let Inst{15}    = lsl;
8027  let Inst{14-13} = opc{1-0};
8028  let Inst{12-10} = Pg;
8029  let Inst{9-5}   = Rn;
8030  let Inst{4-0}   = Zt;
8031
8032
8033  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
8034  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
8035  let hasSideEffects = opc{0};
8036  let mayLoad = 1;
8037}
8038
8039multiclass sve_mem_64b_gld_sv_32_scaled<bits<4> opc, string asm,
8040                                        SDPatternOperator sxtw_op,
8041                                        SDPatternOperator uxtw_op,
8042                                        RegisterOperand sxtw_opnd,
8043                                        RegisterOperand uxtw_opnd,
8044                                        ValueType vt> {
8045  def _UXTW_SCALED_REAL : sve_mem_64b_gld_sv<opc, 0, 1, 0, asm, uxtw_opnd>;
8046  def _SXTW_SCALED_REAL : sve_mem_64b_gld_sv<opc, 1, 1, 0, asm, sxtw_opnd>;
8047
8048  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8049                  (!cast<Instruction>(NAME # _UXTW_SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
8050  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8051                  (!cast<Instruction>(NAME # _SXTW_SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
8052
8053  // We need a layer of indirection because early machine code passes balk at
8054  // physical register (i.e. FFR) uses that have no previous definition.
8055  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8056  def _UXTW_SCALED : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
8057                     PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_SCALED_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8058  def _SXTW_SCALED : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
8059                     PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_SCALED_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8060  }
8061
8062  def : Pat<(nxv2i64 (uxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8063            (!cast<Instruction>(NAME # _UXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8064  def : Pat<(nxv2i64 (sxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8065            (!cast<Instruction>(NAME # _SXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8066}
8067
8068multiclass sve_mem_64b_gld_vs_32_unscaled<bits<4> opc, string asm,
8069                                          SDPatternOperator sxtw_op,
8070                                          SDPatternOperator uxtw_op,
8071                                          RegisterOperand sxtw_opnd,
8072                                          RegisterOperand uxtw_opnd,
8073                                          ValueType vt> {
8074  def _UXTW_REAL : sve_mem_64b_gld_sv<opc, 0, 0, 0, asm, uxtw_opnd>;
8075  def _SXTW_REAL : sve_mem_64b_gld_sv<opc, 1, 0, 0, asm, sxtw_opnd>;
8076
8077  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8078                  (!cast<Instruction>(NAME # _UXTW_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
8079  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8080                  (!cast<Instruction>(NAME # _SXTW_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
8081
8082  // We need a layer of indirection because early machine code passes balk at
8083  // physical register (i.e. FFR) uses that have no previous definition.
8084  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8085  def _UXTW : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
8086              PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8087  def _SXTW : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
8088              PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8089  }
8090
8091  def : Pat<(nxv2i64 (uxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8092            (!cast<Instruction>(NAME # _UXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8093  def : Pat<(nxv2i64 (sxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8094            (!cast<Instruction>(NAME # _SXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8095}
8096
8097multiclass sve_mem_64b_gld_sv2_64_scaled<bits<4> opc, string asm,
8098                                         SDPatternOperator op,
8099                                         RegisterOperand zprext, ValueType vt> {
8100  def _SCALED_REAL : sve_mem_64b_gld_sv<opc, 1, 1, 1, asm, zprext>;
8101
8102  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8103                  (!cast<Instruction>(NAME # _SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), 0>;
8104
8105  // We need a layer of indirection because early machine code passes balk at
8106  // physical register (i.e. FFR) uses that have no previous definition.
8107  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8108  def _SCALED : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), []>,
8109                PseudoInstExpansion<(!cast<Instruction>(NAME # _SCALED_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm)>;
8110  }
8111
8112  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8113                     (!cast<Instruction>(NAME # _SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8114}
8115
8116multiclass sve_mem_64b_gld_vs2_64_unscaled<bits<4> opc, string asm,
8117                                           SDPatternOperator op, ValueType vt> {
8118  def _REAL : sve_mem_64b_gld_sv<opc, 1, 0, 1, asm, ZPR64ExtLSL8>;
8119
8120  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8121                  (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), 0>;
8122
8123  // We need a layer of indirection because early machine code passes balk at
8124  // physical register (i.e. FFR) uses that have no previous definition.
8125  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8126  def "" : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), []>,
8127           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm)>;
8128  }
8129
8130  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8131            (!cast<Instruction>(NAME) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8132}
8133
8134class sve_mem_64b_gld_vi<bits<4> opc, string asm, Operand imm_ty>
8135: I<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5),
8136  asm, "\t$Zt, $Pg/z, [$Zn, $imm5]",
8137  "",
8138  []>, Sched<[]> {
8139  bits<3> Pg;
8140  bits<5> Zn;
8141  bits<5> Zt;
8142  bits<5> imm5;
8143  let Inst{31-25} = 0b1100010;
8144  let Inst{24-23} = opc{3-2};
8145  let Inst{22-21} = 0b01;
8146  let Inst{20-16} = imm5;
8147  let Inst{15}    = 0b1;
8148  let Inst{14-13} = opc{1-0};
8149  let Inst{12-10} = Pg;
8150  let Inst{9-5}   = Zn;
8151  let Inst{4-0}   = Zt;
8152
8153  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
8154  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
8155  let hasSideEffects = opc{0};
8156  let mayLoad = 1;
8157}
8158
8159multiclass sve_mem_64b_gld_vi_64_ptrs<bits<4> opc, string asm, Operand imm_ty,
8160                                      SDPatternOperator op, ValueType vt> {
8161  def _IMM_REAL : sve_mem_64b_gld_vi<opc, asm, imm_ty>;
8162
8163  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8164                  (!cast<Instruction>(NAME # _IMM_REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 0>;
8165  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $imm5]",
8166                 (!cast<Instruction>(NAME # _IMM_REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), 0>;
8167  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8168                  (!cast<Instruction>(NAME # _IMM_REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
8169
8170  // We need a layer of indirection because early machine code passes balk at
8171  // physical register (i.e. FFR) uses that have no previous definition.
8172  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8173  def _IMM : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), []>,
8174                  PseudoInstExpansion<(!cast<Instruction>(NAME # _IMM_REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5)>;
8175  }
8176
8177  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), (nxv2i64 ZPR:$ptrs), imm_ty:$index, vt)),
8178            (!cast<Instruction>(NAME # _IMM) PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
8179}
8180
8181// bit lsl is '0' if the offsets are extended (uxtw/sxtw), '1' if shifted (lsl)
8182class sve_mem_64b_prfm_sv<bits<2> msz, bit xs, bit lsl, string asm,
8183                          RegisterOperand zprext>
8184: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
8185  asm, "\t$prfop, $Pg, [$Rn, $Zm]",
8186  "",
8187  []>, Sched<[]> {
8188  bits<3> Pg;
8189  bits<5> Rn;
8190  bits<5> Zm;
8191  bits<4> prfop;
8192  let Inst{31-23} = 0b110001000;
8193  let Inst{22}    = xs;
8194  let Inst{21}    = 0b1;
8195  let Inst{20-16} = Zm;
8196  let Inst{15}    = lsl;
8197  let Inst{14-13} = msz;
8198  let Inst{12-10} = Pg;
8199  let Inst{9-5}   = Rn;
8200  let Inst{4}     = 0b0;
8201  let Inst{3-0}   = prfop;
8202
8203  let hasSideEffects = 1;
8204}
8205
8206multiclass sve_mem_64b_prfm_sv_ext_scaled<bits<2> msz, string asm,
8207                                          RegisterOperand sxtw_opnd,
8208                                          RegisterOperand uxtw_opnd,
8209                                          SDPatternOperator op_sxtw,
8210                                          SDPatternOperator op_uxtw> {
8211  def _UXTW_SCALED : sve_mem_64b_prfm_sv<msz, 0, 0, asm, uxtw_opnd>;
8212  def _SXTW_SCALED : sve_mem_64b_prfm_sv<msz, 1, 0, asm, sxtw_opnd>;
8213
8214  def : Pat<(op_uxtw (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 uxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
8215            (!cast<Instruction>(NAME # _UXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8216
8217  def : Pat<(op_sxtw (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 sxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
8218            (!cast<Instruction>(NAME # _SXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8219
8220}
8221
8222multiclass sve_mem_64b_prfm_sv_lsl_scaled<bits<2> msz, string asm,
8223                                          RegisterOperand zprext, SDPatternOperator frag> {
8224  def NAME : sve_mem_64b_prfm_sv<msz, 1, 1, asm, zprext>;
8225
8226  def : Pat<(frag (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 zprext:$Zm), (i32 sve_prfop:$prfop)),
8227            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm)>;
8228
8229}
8230
8231class sve_mem_64b_prfm_vi<bits<2> msz, string asm, Operand imm_ty>
8232: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5),
8233  asm, "\t$prfop, $Pg, [$Zn, $imm5]",
8234  "",
8235  []>, Sched<[]> {
8236  bits<3> Pg;
8237  bits<5> Zn;
8238  bits<5> imm5;
8239  bits<4> prfop;
8240  let Inst{31-25} = 0b1100010;
8241  let Inst{24-23} = msz;
8242  let Inst{22-21} = 0b00;
8243  let Inst{20-16} = imm5;
8244  let Inst{15-13} = 0b111;
8245  let Inst{12-10} = Pg;
8246  let Inst{9-5}   = Zn;
8247  let Inst{4}     = 0b0;
8248  let Inst{3-0}   = prfop;
8249
8250  let hasSideEffects = 1;
8251}
8252
8253multiclass sve_mem_64b_prfm_vi<bits<2> msz, string asm, Operand imm_ty, SDPatternOperator op> {
8254  def NAME : sve_mem_64b_prfm_vi<msz, asm, imm_ty>;
8255
8256  def : InstAlias<asm # "\t$prfop, $Pg, [$Zn]",
8257                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
8258
8259  def : Pat<(op (nxv2i1 PPR_3b:$Pg), (nxv2i64 ZPR32:$Zn), (i64 imm_ty:$imm), (i32 sve_prfop:$prfop)),
8260            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR_3b:$Pg, ZPR32:$Zn, imm_ty:$imm)>;
8261}
8262
8263//===----------------------------------------------------------------------===//
8264// SVE Compute Vector Address Group
8265//===----------------------------------------------------------------------===//
8266
8267class sve_int_bin_cons_misc_0_a<bits<2> opc, bits<2> msz, string asm,
8268                                ZPRRegOp zprty, RegisterOperand zprext>
8269: I<(outs zprty:$Zd), (ins zprty:$Zn, zprext:$Zm),
8270  asm, "\t$Zd, [$Zn, $Zm]",
8271  "",
8272  []>, Sched<[]> {
8273  bits<5> Zd;
8274  bits<5> Zn;
8275  bits<5> Zm;
8276  let Inst{31-24} = 0b00000100;
8277  let Inst{23-22} = opc;
8278  let Inst{21}    = 0b1;
8279  let Inst{20-16} = Zm;
8280  let Inst{15-12} = 0b1010;
8281  let Inst{11-10} = msz;
8282  let Inst{9-5}   = Zn;
8283  let Inst{4-0}   = Zd;
8284
8285  let hasSideEffects = 0;
8286}
8287
8288multiclass sve_int_bin_cons_misc_0_a_uxtw<bits<2> opc, string asm> {
8289  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtUXTW8>;
8290  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtUXTW16>;
8291  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtUXTW32>;
8292  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtUXTW64>;
8293}
8294
8295multiclass sve_int_bin_cons_misc_0_a_sxtw<bits<2> opc, string asm> {
8296  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtSXTW8>;
8297  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtSXTW16>;
8298  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtSXTW32>;
8299  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtSXTW64>;
8300}
8301
8302multiclass sve_int_bin_cons_misc_0_a_32_lsl<bits<2> opc, string asm> {
8303  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR32, ZPR32ExtLSL8>;
8304  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR32, ZPR32ExtLSL16>;
8305  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR32, ZPR32ExtLSL32>;
8306  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR32, ZPR32ExtLSL64>;
8307}
8308
8309multiclass sve_int_bin_cons_misc_0_a_64_lsl<bits<2> opc, string asm> {
8310  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtLSL8>;
8311  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtLSL16>;
8312  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtLSL32>;
8313  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtLSL64>;
8314}
8315
8316//===----------------------------------------------------------------------===//
8317// SVE Integer Misc - Unpredicated Group
8318//===----------------------------------------------------------------------===//
8319
8320class sve_int_bin_cons_misc_0_b<bits<2> sz, string asm, ZPRRegOp zprty>
8321: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
8322  asm, "\t$Zd, $Zn, $Zm",
8323  "",
8324  []>, Sched<[]> {
8325  bits<5> Zd;
8326  bits<5> Zm;
8327  bits<5> Zn;
8328  let Inst{31-24} = 0b00000100;
8329  let Inst{23-22} = sz;
8330  let Inst{21}    = 0b1;
8331  let Inst{20-16} = Zm;
8332  let Inst{15-10} = 0b101100;
8333  let Inst{9-5}   = Zn;
8334  let Inst{4-0}   = Zd;
8335
8336  let hasSideEffects = 0;
8337}
8338
8339multiclass sve_int_bin_cons_misc_0_b<string asm, SDPatternOperator op> {
8340  def _H : sve_int_bin_cons_misc_0_b<0b01, asm, ZPR16>;
8341  def _S : sve_int_bin_cons_misc_0_b<0b10, asm, ZPR32>;
8342  def _D : sve_int_bin_cons_misc_0_b<0b11, asm, ZPR64>;
8343
8344  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
8345  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
8346  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
8347}
8348
8349class sve_int_bin_cons_misc_0_c<bits<8> opc, string asm, ZPRRegOp zprty>
8350: I<(outs zprty:$Zd), (ins zprty:$Zn),
8351  asm, "\t$Zd, $Zn",
8352  "",
8353  []>, Sched<[]> {
8354  bits<5> Zd;
8355  bits<5> Zn;
8356  let Inst{31-24} = 0b00000100;
8357  let Inst{23-22} = opc{7-6};
8358  let Inst{21}    = 0b1;
8359  let Inst{20-16} = opc{5-1};
8360  let Inst{15-11} = 0b10111;
8361  let Inst{10}    = opc{0};
8362  let Inst{9-5}   = Zn;
8363  let Inst{4-0}   = Zd;
8364
8365  let hasSideEffects = 0;
8366}
8367
8368multiclass sve_int_bin_cons_misc_0_c_fexpa<string asm, SDPatternOperator op> {
8369  def _H : sve_int_bin_cons_misc_0_c<0b01000000, asm, ZPR16>;
8370  def _S : sve_int_bin_cons_misc_0_c<0b10000000, asm, ZPR32>;
8371  def _D : sve_int_bin_cons_misc_0_c<0b11000000, asm, ZPR64>;
8372
8373  def : SVE_1_Op_Pat<nxv8f16, op, nxv8i16, !cast<Instruction>(NAME # _H)>;
8374  def : SVE_1_Op_Pat<nxv4f32, op, nxv4i32, !cast<Instruction>(NAME # _S)>;
8375  def : SVE_1_Op_Pat<nxv2f64, op, nxv2i64, !cast<Instruction>(NAME # _D)>;
8376}
8377
8378//===----------------------------------------------------------------------===//
8379// SVE Integer Reduction Group
8380//===----------------------------------------------------------------------===//
8381
8382class sve_int_reduce<bits<2> sz8_32, bits<2> fmt, bits<3> opc, string asm,
8383                     ZPRRegOp zprty, FPRasZPROperand dstOpType>
8384: I<(outs dstOpType:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
8385  asm, "\t$Vd, $Pg, $Zn",
8386  "",
8387  []>, Sched<[]> {
8388  bits<3> Pg;
8389  bits<5> Vd;
8390  bits<5> Zn;
8391  let Inst{31-24} = 0b00000100;
8392  let Inst{23-22} = sz8_32;
8393  let Inst{21}    = 0b0;
8394  let Inst{20-19} = fmt;
8395  let Inst{18-16} = opc;
8396  let Inst{15-13} = 0b001;
8397  let Inst{12-10} = Pg;
8398  let Inst{9-5}   = Zn;
8399  let Inst{4-0}   = Vd;
8400
8401  let hasSideEffects = 0;
8402}
8403
8404multiclass sve_int_reduce_0_saddv<bits<3> opc, string asm,
8405                                  SDPatternOperator op> {
8406  def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
8407  def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
8408  def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
8409
8410  def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8411  def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8412  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8413}
8414
8415multiclass sve_int_reduce_0_uaddv<bits<3> opc, string asm,
8416                                  SDPatternOperator op> {
8417  def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
8418  def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
8419  def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
8420  def _D : sve_int_reduce<0b11, 0b00, opc, asm, ZPR64, FPR64asZPR>;
8421
8422  def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8423  def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8424  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8425  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8426}
8427
8428multiclass sve_int_reduce_1<bits<3> opc, string asm,
8429                            SDPatternOperator op> {
8430  def _B : sve_int_reduce<0b00, 0b01, opc, asm, ZPR8, FPR8asZPR>;
8431  def _H : sve_int_reduce<0b01, 0b01, opc, asm, ZPR16, FPR16asZPR>;
8432  def _S : sve_int_reduce<0b10, 0b01, opc, asm, ZPR32, FPR32asZPR>;
8433  def _D : sve_int_reduce<0b11, 0b01, opc, asm, ZPR64, FPR64asZPR>;
8434
8435  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8436  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8437  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8438  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8439}
8440
8441multiclass sve_int_reduce_2<bits<3> opc, string asm,
8442                            SDPatternOperator op> {
8443  def _B : sve_int_reduce<0b00, 0b11, opc, asm, ZPR8, FPR8asZPR>;
8444  def _H : sve_int_reduce<0b01, 0b11, opc, asm, ZPR16, FPR16asZPR>;
8445  def _S : sve_int_reduce<0b10, 0b11, opc, asm, ZPR32, FPR32asZPR>;
8446  def _D : sve_int_reduce<0b11, 0b11, opc, asm, ZPR64, FPR64asZPR>;
8447
8448  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8449  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8450  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8451  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8452}
8453
8454class sve_int_movprfx_pred<bits<2> sz8_32, bits<3> opc, string asm,
8455                           ZPRRegOp zprty, string pg_suffix, dag iops>
8456: I<(outs zprty:$Zd), iops,
8457  asm, "\t$Zd, $Pg"#pg_suffix#", $Zn",
8458  "",
8459  []>, Sched<[]> {
8460  bits<3> Pg;
8461  bits<5> Zd;
8462  bits<5> Zn;
8463  let Inst{31-24} = 0b00000100;
8464  let Inst{23-22} = sz8_32;
8465  let Inst{21-19} = 0b010;
8466  let Inst{18-16} = opc;
8467  let Inst{15-13} = 0b001;
8468  let Inst{12-10} = Pg;
8469  let Inst{9-5}   = Zn;
8470  let Inst{4-0}   = Zd;
8471
8472  let ElementSize = zprty.ElementSize;
8473  let hasSideEffects = 0;
8474}
8475
8476multiclass sve_int_movprfx_pred_merge<bits<3> opc, string asm> {
8477let Constraints = "$Zd = $_Zd" in {
8478  def _B : sve_int_movprfx_pred<0b00, opc, asm, ZPR8, "/m",
8479                                (ins ZPR8:$_Zd, PPR3bAny:$Pg, ZPR8:$Zn)>;
8480  def _H : sve_int_movprfx_pred<0b01, opc, asm, ZPR16, "/m",
8481                                (ins ZPR16:$_Zd, PPR3bAny:$Pg, ZPR16:$Zn)>;
8482  def _S : sve_int_movprfx_pred<0b10, opc, asm, ZPR32, "/m",
8483                                (ins ZPR32:$_Zd, PPR3bAny:$Pg, ZPR32:$Zn)>;
8484  def _D : sve_int_movprfx_pred<0b11, opc, asm, ZPR64, "/m",
8485                                (ins ZPR64:$_Zd, PPR3bAny:$Pg, ZPR64:$Zn)>;
8486}
8487}
8488
8489multiclass sve_int_movprfx_pred_zero<bits<3> opc, string asm> {
8490  def _B : sve_int_movprfx_pred<0b00, opc, asm, ZPR8, "/z",
8491                                (ins PPR3bAny:$Pg, ZPR8:$Zn)>;
8492  def _H : sve_int_movprfx_pred<0b01, opc, asm, ZPR16, "/z",
8493                                (ins PPR3bAny:$Pg, ZPR16:$Zn)>;
8494  def _S : sve_int_movprfx_pred<0b10, opc, asm, ZPR32, "/z",
8495                                (ins PPR3bAny:$Pg, ZPR32:$Zn)>;
8496  def _D : sve_int_movprfx_pred<0b11, opc, asm, ZPR64, "/z",
8497                                (ins PPR3bAny:$Pg, ZPR64:$Zn)>;
8498}
8499
8500//===----------------------------------------------------------------------===//
8501// SVE Propagate Break Group
8502//===----------------------------------------------------------------------===//
8503
8504class sve_int_brkp<bits<2> opc, string asm>
8505: I<(outs PPR8:$Pd), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$Pm),
8506  asm, "\t$Pd, $Pg/z, $Pn, $Pm",
8507  "",
8508  []>, Sched<[]> {
8509  bits<4> Pd;
8510  bits<4> Pg;
8511  bits<4> Pm;
8512  bits<4> Pn;
8513  let Inst{31-24} = 0b00100101;
8514  let Inst{23}    = 0b0;
8515  let Inst{22}    = opc{1};
8516  let Inst{21-20} = 0b00;
8517  let Inst{19-16} = Pm;
8518  let Inst{15-14} = 0b11;
8519  let Inst{13-10} = Pg;
8520  let Inst{9}     = 0b0;
8521  let Inst{8-5}   = Pn;
8522  let Inst{4}     = opc{0};
8523  let Inst{3-0}   = Pd;
8524
8525  let Defs = !if(!eq (opc{1}, 1), [NZCV], []);
8526  let hasSideEffects = 0;
8527}
8528
8529multiclass sve_int_brkp<bits<2> opc, string asm, SDPatternOperator op> {
8530  def NAME : sve_int_brkp<opc, asm>;
8531
8532  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8533}
8534
8535
8536//===----------------------------------------------------------------------===//
8537// SVE Partition Break Group
8538//===----------------------------------------------------------------------===//
8539
8540class sve_int_brkn<bit S, string asm>
8541: I<(outs PPR8:$Pdm), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$_Pdm),
8542  asm, "\t$Pdm, $Pg/z, $Pn, $_Pdm",
8543  "",
8544  []>, Sched<[]> {
8545  bits<4> Pdm;
8546  bits<4> Pg;
8547  bits<4> Pn;
8548  let Inst{31-23} = 0b001001010;
8549  let Inst{22}    = S;
8550  let Inst{21-14} = 0b01100001;
8551  let Inst{13-10} = Pg;
8552  let Inst{9}     = 0b0;
8553  let Inst{8-5}   = Pn;
8554  let Inst{4}     = 0b0;
8555  let Inst{3-0}   = Pdm;
8556
8557  let Constraints = "$Pdm = $_Pdm";
8558  let Defs = !if(S, [NZCV], []);
8559  let ElementSize = ElementSizeB;
8560  let hasSideEffects = 0;
8561}
8562
8563multiclass sve_int_brkn<bits<1> opc, string asm, SDPatternOperator op> {
8564  def NAME : sve_int_brkn<opc, asm>;
8565
8566  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8567}
8568
8569class sve_int_break<bits<3> opc, string asm, string suffix, dag iops>
8570: I<(outs PPR8:$Pd), iops,
8571  asm, "\t$Pd, $Pg"#suffix#", $Pn",
8572  "",
8573  []>, Sched<[]> {
8574  bits<4> Pd;
8575  bits<4> Pg;
8576  bits<4> Pn;
8577  let Inst{31-24} = 0b00100101;
8578  let Inst{23-22} = opc{2-1};
8579  let Inst{21-14} = 0b01000001;
8580  let Inst{13-10} = Pg;
8581  let Inst{9}     = 0b0;
8582  let Inst{8-5}   = Pn;
8583  let Inst{4}     = opc{0};
8584  let Inst{3-0}   = Pd;
8585
8586  let Constraints = !if(!eq (opc{0}, 1), "$Pd = $_Pd", "");
8587  let Defs = !if(!eq (opc{1}, 1), [NZCV], []);
8588  let hasSideEffects = 0;
8589}
8590
8591multiclass sve_int_break_m<bits<3> opc, string asm, SDPatternOperator op> {
8592  def NAME : sve_int_break<opc, asm, "/m", (ins PPR8:$_Pd, PPRAny:$Pg, PPR8:$Pn)>;
8593
8594  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8595}
8596
8597multiclass sve_int_break_z<bits<3> opc, string asm, SDPatternOperator op> {
8598  def NAME : sve_int_break<opc, asm, "/z", (ins PPRAny:$Pg, PPR8:$Pn)>;
8599
8600  def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8601}
8602
8603//===----------------------------------------------------------------------===//
8604// SVE2 String Processing Group
8605//===----------------------------------------------------------------------===//
8606
8607class sve2_char_match<bit sz, bit opc, string asm,
8608                      PPRRegOp pprty, ZPRRegOp zprty>
8609: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
8610  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
8611  "",
8612  []>, Sched<[]> {
8613  bits<4> Pd;
8614  bits<3> Pg;
8615  bits<5> Zm;
8616  bits<5> Zn;
8617  let Inst{31-23} = 0b010001010;
8618  let Inst{22}    = sz;
8619  let Inst{21}    = 0b1;
8620  let Inst{20-16} = Zm;
8621  let Inst{15-13} = 0b100;
8622  let Inst{12-10} = Pg;
8623  let Inst{9-5}   = Zn;
8624  let Inst{4}     = opc;
8625  let Inst{3-0}   = Pd;
8626
8627  let Defs = [NZCV];
8628  let ElementSize = pprty.ElementSize;
8629  let hasSideEffects = 0;
8630  let isPTestLike = 1;
8631}
8632
8633multiclass sve2_char_match<bit opc, string asm, SDPatternOperator op> {
8634  def _B : sve2_char_match<0b0, opc, asm, PPR8, ZPR8>;
8635  def _H : sve2_char_match<0b1, opc, asm, PPR16, ZPR16>;
8636
8637  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
8638  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
8639}
8640
8641//===----------------------------------------------------------------------===//
8642// SVE2 Histogram Computation - Segment Group
8643//===----------------------------------------------------------------------===//
8644
8645class sve2_hist_gen_segment<string asm, SDPatternOperator op>
8646: I<(outs ZPR8:$Zd), (ins ZPR8:$Zn, ZPR8:$Zm),
8647  asm, "\t$Zd, $Zn, $Zm",
8648  "",
8649  [(set nxv16i8:$Zd, (op nxv16i8:$Zn, nxv16i8:$Zm))]>, Sched<[]> {
8650  bits<5> Zd;
8651  bits<5> Zn;
8652  bits<5> Zm;
8653  let Inst{31-21} = 0b01000101001;
8654  let Inst{20-16} = Zm;
8655  let Inst{15-10} = 0b101000;
8656  let Inst{9-5}   = Zn;
8657  let Inst{4-0}   = Zd;
8658
8659  let hasSideEffects = 0;
8660}
8661
8662//===----------------------------------------------------------------------===//
8663// SVE2 Histogram Computation - Vector Group
8664//===----------------------------------------------------------------------===//
8665
8666class sve2_hist_gen_vector<bit sz, string asm, ZPRRegOp zprty>
8667: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
8668  asm, "\t$Zd, $Pg/z, $Zn, $Zm",
8669  "",
8670  []>, Sched<[]> {
8671  bits<5> Zd;
8672  bits<5> Zn;
8673  bits<3> Pg;
8674  bits<5> Zm;
8675  let Inst{31-23} = 0b010001011;
8676  let Inst{22}    = sz;
8677  let Inst{21}    = 0b1;
8678  let Inst{20-16} = Zm;
8679  let Inst{15-13} = 0b110;
8680  let Inst{12-10} = Pg;
8681  let Inst{9-5}   = Zn;
8682  let Inst{4-0}   = Zd;
8683
8684  let hasSideEffects = 0;
8685}
8686
8687multiclass sve2_hist_gen_vector<string asm, SDPatternOperator op> {
8688  def _S : sve2_hist_gen_vector<0b0, asm, ZPR32>;
8689  def _D : sve2_hist_gen_vector<0b1, asm, ZPR64>;
8690
8691  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
8692  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
8693}
8694
8695//===----------------------------------------------------------------------===//
8696// SVE2 Crypto Extensions Group
8697//===----------------------------------------------------------------------===//
8698
8699class sve2_crypto_cons_bin_op<bit opc, string asm, ZPRRegOp zprty>
8700: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
8701  asm, "\t$Zd, $Zn, $Zm",
8702  "",
8703  []>, Sched<[]> {
8704  bits<5> Zd;
8705  bits<5> Zn;
8706  bits<5> Zm;
8707  let Inst{31-21} = 0b01000101001;
8708  let Inst{20-16} = Zm;
8709  let Inst{15-11} = 0b11110;
8710  let Inst{10}    = opc;
8711  let Inst{9-5}   = Zn;
8712  let Inst{4-0}   = Zd;
8713
8714  let hasSideEffects = 0;
8715}
8716
8717multiclass sve2_crypto_cons_bin_op<bit opc, string asm, ZPRRegOp zprty,
8718                                   SDPatternOperator op, ValueType vt> {
8719  def NAME : sve2_crypto_cons_bin_op<opc, asm, zprty>;
8720  def : SVE_2_Op_Pat<vt, op, vt, vt, !cast<Instruction>(NAME)>;
8721}
8722
8723class sve2_crypto_des_bin_op<bits<2> opc, string asm, ZPRRegOp zprty>
8724: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm),
8725  asm, "\t$Zdn, $_Zdn, $Zm",
8726  "",
8727  []>, Sched<[]> {
8728  bits<5> Zdn;
8729  bits<5> Zm;
8730  let Inst{31-17} = 0b010001010010001;
8731  let Inst{16}    = opc{1};
8732  let Inst{15-11} = 0b11100;
8733  let Inst{10}    = opc{0};
8734  let Inst{9-5}   = Zm;
8735  let Inst{4-0}   = Zdn;
8736
8737  let Constraints = "$Zdn = $_Zdn";
8738  let hasSideEffects = 0;
8739}
8740
8741multiclass sve2_crypto_des_bin_op<bits<2> opc, string asm, ZPRRegOp zprty,
8742                                  SDPatternOperator op, ValueType vt> {
8743  def NAME : sve2_crypto_des_bin_op<opc, asm, zprty>;
8744  def : SVE_2_Op_Pat<vt, op, vt, vt, !cast<Instruction>(NAME)>;
8745}
8746
8747class sve2_crypto_unary_op<bit opc, string asm, ZPRRegOp zprty>
8748: I<(outs zprty:$Zdn), (ins zprty:$_Zdn),
8749  asm, "\t$Zdn, $_Zdn",
8750  "",
8751  []>, Sched<[]> {
8752  bits<5> Zdn;
8753  let Inst{31-11} = 0b010001010010000011100;
8754  let Inst{10}    = opc;
8755  let Inst{9-5}   = 0b00000;
8756  let Inst{4-0}   = Zdn;
8757
8758  let Constraints = "$Zdn = $_Zdn";
8759  let hasSideEffects = 0;
8760}
8761
8762multiclass sve2_crypto_unary_op<bit opc, string asm, SDPatternOperator op> {
8763  def NAME : sve2_crypto_unary_op<opc, asm, ZPR8>;
8764  def : SVE_1_Op_Pat<nxv16i8, op, nxv16i8, !cast<Instruction>(NAME)>;
8765}
8766
8767//===----------------------------------------------------------------------===//
8768// SVE BFloat16 Group
8769//===----------------------------------------------------------------------===//
8770
8771class sve_float_dot<bit bf, bit o2, ZPRRegOp dst_ty, ZPRRegOp src_ty, string asm>
8772: I<(outs dst_ty:$Zda), (ins dst_ty:$_Zda, src_ty:$Zn, src_ty:$Zm),
8773     asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8774  bits<5> Zda;
8775  bits<5> Zn;
8776  bits<5> Zm;
8777  let Inst{31-23} = 0b011001000;
8778  let Inst{22}    = bf;
8779  let Inst{21}    = 0b1;
8780  let Inst{20-16} = Zm;
8781  let Inst{15-11} = 0b10000;
8782  let Inst{10}    = o2;
8783  let Inst{9-5}   = Zn;
8784  let Inst{4-0}   = Zda;
8785
8786  let Constraints = "$Zda = $_Zda";
8787  let DestructiveInstType = DestructiveOther;
8788  let hasSideEffects = 0;
8789  let mayRaiseFPException = 1;
8790}
8791
8792multiclass sve_float_dot<bit bf, bit o2, ZPRRegOp dst_ty, ZPRRegOp src_ty,
8793                         string asm, ValueType InVT, SDPatternOperator op> {
8794  def NAME : sve_float_dot<bf, o2, dst_ty, src_ty, asm>;
8795  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, InVT, InVT, !cast<Instruction>(NAME)>;
8796}
8797
8798class sve_float_dot_indexed<bit bf, ZPRRegOp dst_ty, ZPRRegOp src1_ty,
8799                            ZPRRegOp src2_ty, Operand iop_ty, string asm>
8800: I<(outs dst_ty:$Zda), (ins dst_ty:$_Zda, src1_ty:$Zn, src2_ty:$Zm, iop_ty:$iop),
8801    asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
8802  bits<5> Zda;
8803  bits<5> Zn;
8804  bits<3> Zm;
8805  let Inst{31-23} = 0b011001000;
8806  let Inst{22}    = bf;
8807  let Inst{21}    = 0b1;
8808  let Inst{18-16} = Zm;
8809  let Inst{15-12} = 0b0100;
8810  let Inst{9-5}   = Zn;
8811  let Inst{4-0}   = Zda;
8812
8813  let Constraints = "$Zda = $_Zda";
8814  let DestructiveInstType = DestructiveOther;
8815  let hasSideEffects = 0;
8816  let mayRaiseFPException = 1;
8817}
8818
8819multiclass sve_float_dot_indexed<bit bf, bits<2> opc, ZPRRegOp src1_ty,
8820                                 ZPRRegOp src2_ty, string asm, ValueType InVT,
8821                                 SDPatternOperator op> {
8822  def NAME : sve_float_dot_indexed<bf, ZPR32, src1_ty, src2_ty, VectorIndexS32b, asm> {
8823    bits<2> iop;
8824    let Inst{20-19} = iop;
8825    let Inst{11-10} = opc;
8826  }
8827  def : SVE_4_Op_Imm_Pat<nxv4f32, op, nxv4f32, InVT, InVT, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
8828}
8829
8830class sve_bfloat_matmul<string asm>
8831: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
8832  asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8833  bits<5> Zm;
8834  bits<5> Zda;
8835  bits<5> Zn;
8836  let Inst{31-21} = 0b01100100011;
8837  let Inst{20-16} = Zm;
8838  let Inst{15-10} = 0b111001;
8839  let Inst{9-5}   = Zn;
8840  let Inst{4-0}   = Zda;
8841
8842  let Constraints = "$Zda = $_Zda";
8843  let DestructiveInstType = DestructiveOther;
8844  let ElementSize = ElementSizeH;
8845  let hasSideEffects = 0;
8846  let mayRaiseFPException = 1;
8847}
8848
8849multiclass sve_bfloat_matmul<string asm, SDPatternOperator op> {
8850  def NAME : sve_bfloat_matmul<asm>;
8851  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv8bf16, nxv8bf16 ,!cast<Instruction>(NAME)>;
8852}
8853
8854class sve_bfloat_convert<bit N, string asm>
8855: I<(outs ZPR16:$Zd), (ins ZPR16:$_Zd, PPR3bAny:$Pg, ZPR32:$Zn),
8856  asm, "\t$Zd, $Pg/m, $Zn", "", []>, Sched<[]> {
8857  bits<5> Zd;
8858  bits<3> Pg;
8859  bits<5> Zn;
8860  let Inst{31-25} = 0b0110010;
8861  let Inst{24}    = N;
8862  let Inst{23-13} = 0b10001010101;
8863  let Inst{12-10} = Pg;
8864  let Inst{9-5}   = Zn;
8865  let Inst{4-0}   = Zd;
8866
8867  let Constraints = "$Zd = $_Zd";
8868  let DestructiveInstType = DestructiveOther;
8869  let ElementSize = ElementSizeS;
8870  let hasSideEffects = 0;
8871  let mayRaiseFPException = 1;
8872}
8873
8874multiclass sve_bfloat_convert<bit N, string asm, SDPatternOperator op> {
8875  def NAME : sve_bfloat_convert<N, asm>;
8876  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i1, nxv4f32, !cast<Instruction>(NAME)>;
8877}
8878
8879//===----------------------------------------------------------------------===//
8880// SVE Integer Matrix Multiply Group
8881//===----------------------------------------------------------------------===//
8882
8883class sve_int_matmul<bits<2> uns, string asm>
8884: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR8:$Zm), asm,
8885  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8886  bits<5> Zda;
8887  bits<5> Zn;
8888  bits<5> Zm;
8889  let Inst{31-24} = 0b01000101;
8890  let Inst{23-22} = uns;
8891  let Inst{21}    = 0;
8892  let Inst{20-16} = Zm;
8893  let Inst{15-10} = 0b100110;
8894  let Inst{9-5}   = Zn;
8895  let Inst{4-0}   = Zda;
8896
8897  let Constraints = "$Zda = $_Zda";
8898  let DestructiveInstType = DestructiveOther;
8899  let ElementSize = ZPR32.ElementSize;
8900  let hasSideEffects = 0;
8901}
8902
8903multiclass sve_int_matmul<bits<2> uns, string asm, SDPatternOperator op> {
8904  def NAME : sve_int_matmul<uns, asm>;
8905
8906  def : SVE_3_Op_Pat<nxv4i32, op , nxv4i32, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
8907}
8908
8909//===----------------------------------------------------------------------===//
8910// SVE Integer Dot Product Mixed Sign Group
8911//===----------------------------------------------------------------------===//
8912
8913class sve_int_dot_mixed<string asm>
8914: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR8:$Zm), asm,
8915  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8916  bits<5> Zda;
8917  bits<5> Zn;
8918  bits<5> Zm;
8919  let Inst{31-21} = 0b01000100100;
8920  let Inst{20-16} = Zm;
8921  let Inst{15-10} = 0b011110;
8922  let Inst{9-5}   = Zn;
8923  let Inst{4-0}   = Zda;
8924
8925  let Constraints = "$Zda = $_Zda";
8926  let DestructiveInstType = DestructiveOther;
8927  let ElementSize = ZPR32.ElementSize;
8928  let hasSideEffects = 0;
8929}
8930
8931multiclass sve_int_dot_mixed<string asm, SDPatternOperator op> {
8932  def NAME : sve_int_dot_mixed<asm>;
8933
8934  def : SVE_3_Op_Pat<nxv4i32, op , nxv4i32, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
8935}
8936
8937//===----------------------------------------------------------------------===//
8938// SVE Integer Dot Product Mixed Sign - Indexed Group
8939//===----------------------------------------------------------------------===//
8940
8941class sve_int_dot_mixed_indexed<bit U, string asm>
8942: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexS32b:$idx),
8943    asm, "\t$Zda, $Zn, $Zm$idx", "", []>, Sched<[]> {
8944  bits<5> Zda;
8945  bits<5> Zn;
8946  bits<3> Zm;
8947  bits<2> idx;
8948  let Inst{31-21} = 0b01000100101;
8949  let Inst{20-19} = idx;
8950  let Inst{18-16} = Zm;
8951  let Inst{15-11} = 0b00011;
8952  let Inst{10}    = U;
8953  let Inst{9-5}   = Zn;
8954  let Inst{4-0}   = Zda;
8955
8956  let Constraints = "$Zda = $_Zda";
8957  let DestructiveInstType = DestructiveOther;
8958  let ElementSize = ZPR32.ElementSize;
8959  let hasSideEffects = 0;
8960}
8961
8962multiclass sve_int_dot_mixed_indexed<bit U, string asm, SDPatternOperator op> {
8963  def NAME : sve_int_dot_mixed_indexed<U, asm>;
8964
8965  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv16i8, nxv16i8, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
8966}
8967
8968//===----------------------------------------------------------------------===//
8969// SVE Floating Point Matrix Multiply Accumulate Group
8970//===----------------------------------------------------------------------===//
8971
8972class sve_fp_matrix_mla<bit sz, string asm, ZPRRegOp zprty>
8973: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, zprty:$Zm),
8974    asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8975  bits<5> Zda;
8976  bits<5> Zn;
8977  bits<5> Zm;
8978  let Inst{31-23} = 0b011001001;
8979  let Inst{22}    = sz;
8980  let Inst{21}    = 1;
8981  let Inst{20-16} = Zm;
8982  let Inst{15-10} = 0b111001;
8983  let Inst{9-5}   = Zn;
8984  let Inst{4-0}   = Zda;
8985
8986  let Constraints = "$Zda = $_Zda";
8987  let DestructiveInstType = DestructiveOther;
8988  let ElementSize = zprty.ElementSize;
8989  let hasSideEffects = 0;
8990  let mayRaiseFPException = 1;
8991}
8992
8993multiclass sve_fp_matrix_mla<bit sz, string asm, ZPRRegOp zprty, SDPatternOperator op, ValueType vt> {
8994  def NAME : sve_fp_matrix_mla<sz, asm, zprty>;
8995
8996  def : SVE_3_Op_Pat<vt, op , vt, vt, vt, !cast<Instruction>(NAME)>;
8997}
8998
8999//===----------------------------------------------------------------------===//
9000// SVE Memory - Contiguous Load And Replicate 256-bit Group
9001//===----------------------------------------------------------------------===//
9002
9003class sve_mem_ldor_si<bits<2> sz, string asm, RegisterOperand VecList>
9004: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s32:$imm4),
9005  asm, "\t$Zt, $Pg/z, [$Rn, $imm4]", "", []>, Sched<[]> {
9006  bits<5> Zt;
9007  bits<5> Rn;
9008  bits<3> Pg;
9009  bits<4> imm4;
9010  let Inst{31-25} = 0b1010010;
9011  let Inst{24-23} = sz;
9012  let Inst{22-20} = 0b010;
9013  let Inst{19-16} = imm4;
9014  let Inst{15-13} = 0b001;
9015  let Inst{12-10} = Pg;
9016  let Inst{9-5}   = Rn;
9017  let Inst{4-0}   = Zt;
9018
9019  let hasSideEffects = 0;
9020  let mayLoad = 1;
9021}
9022
9023multiclass sve_mem_ldor_si<bits<2> sz, string asm, RegisterOperand listty,
9024                           ZPRRegOp zprty, ValueType Ty, ValueType PredTy, SDNode Ld1ro> {
9025  def NAME : sve_mem_ldor_si<sz, asm, listty>;
9026  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
9027                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
9028  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
9029                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
9030  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4]",
9031                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s32:$imm4), 0>;
9032
9033  // Base addressing mode
9034  def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$Pg), GPR64sp:$base)),
9035            (!cast<Instruction>(NAME) PPR3bAny:$Pg, GPR64sp:$base, (i64 0))>;
9036  let AddedComplexity = 2 in {
9037    // Reg + Imm addressing mode
9038    def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$Pg), (add GPR64:$base, (i64 simm4s32:$imm)))),
9039              (!cast<Instruction>(NAME) $Pg, $base, simm4s32:$imm)>;
9040  }
9041}
9042
9043class sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand VecList,
9044                      RegisterOperand gprty>
9045: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
9046  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]", "", []>, Sched<[]> {
9047  bits<5> Zt;
9048  bits<3> Pg;
9049  bits<5> Rn;
9050  bits<5> Rm;
9051  let Inst{31-25} = 0b1010010;
9052  let Inst{24-23} = sz;
9053  let Inst{22-21} = 0b01;
9054  let Inst{20-16} = Rm;
9055  let Inst{15-13} = 0;
9056  let Inst{12-10} = Pg;
9057  let Inst{9-5}   = Rn;
9058  let Inst{4-0}   = Zt;
9059
9060  let hasSideEffects = 0;
9061  let mayLoad = 1;
9062}
9063
9064multiclass sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand listty,
9065                           ZPRRegOp zprty, RegisterOperand gprty, ValueType Ty,
9066                           ValueType PredTy, SDNode Ld1ro, ComplexPattern AddrCP> {
9067  def NAME : sve_mem_ldor_ss<sz, asm, listty, gprty>;
9068
9069  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
9070                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
9071
9072  def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$gp), (AddrCP GPR64sp:$base, gprty:$offset))),
9073            (!cast<Instruction>(NAME) PPR3bAny:$gp, GPR64sp:$base, gprty:$offset)>;
9074}
9075
9076//===----------------------------------------------------------------------===//
9077// SVE Interleave 128-bit Elements Group
9078//===----------------------------------------------------------------------===//
9079
9080class sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm>
9081: I<(outs ZPR128:$Zd), (ins ZPR128:$Zn, ZPR128:$Zm),
9082  asm, "\t$Zd, $Zn, $Zm",
9083  "",
9084  []>, Sched<[]> {
9085  bits<5> Zd;
9086  bits<5> Zm;
9087  bits<5> Zn;
9088  let Inst{31-21} = 0b00000101101;
9089  let Inst{20-16} = Zm;
9090  let Inst{15-13} = 0b000;
9091  let Inst{12-11} = opc;
9092  let Inst{10}    = P;
9093  let Inst{9-5}   = Zn;
9094  let Inst{4-0}   = Zd;
9095
9096  let hasSideEffects = 0;
9097}
9098
9099multiclass sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm, SDPatternOperator op> {
9100  def NAME : sve_int_perm_bin_perm_128_zz<opc, P, asm>;
9101
9102  def : SVE_2_Op_Pat<nxv16i8,  op, nxv16i8,  nxv16i8,  !cast<Instruction>(NAME)>;
9103  def : SVE_2_Op_Pat<nxv8i16,  op, nxv8i16,  nxv8i16,  !cast<Instruction>(NAME)>;
9104  def : SVE_2_Op_Pat<nxv8f16,  op, nxv8f16,  nxv8f16,  !cast<Instruction>(NAME)>;
9105  def : SVE_2_Op_Pat<nxv4i32,  op, nxv4i32,  nxv4i32,  !cast<Instruction>(NAME)>;
9106  def : SVE_2_Op_Pat<nxv4f32,  op, nxv4f32,  nxv4f32,  !cast<Instruction>(NAME)>;
9107  def : SVE_2_Op_Pat<nxv2i64,  op, nxv2i64,  nxv2i64,  !cast<Instruction>(NAME)>;
9108  def : SVE_2_Op_Pat<nxv2f64,  op, nxv2f64,  nxv2f64,  !cast<Instruction>(NAME)>;
9109  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
9110}
9111
9112/// Addressing modes
9113def am_sve_indexed_s4 :ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-8,7>", [], [SDNPWantRoot]>;
9114def am_sve_indexed_s6 :ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-32,31>", [], [SDNPWantRoot]>;
9115
9116def am_sve_regreg_lsl0 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<0>", []>;
9117def am_sve_regreg_lsl1 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<1>", []>;
9118def am_sve_regreg_lsl2 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<2>", []>;
9119def am_sve_regreg_lsl3 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<3>", []>;
9120def am_sve_regreg_lsl4 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<4>", []>;
9121
9122// Predicated pseudo floating point two operand instructions.
9123multiclass sve_fp_bin_pred_hfd<SDPatternOperator op> {
9124  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9125  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9126  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9127
9128  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9129  def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9130  def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9131  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9132  def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9133  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9134}
9135
9136// Predicated pseudo floating point three operand instructions.
9137multiclass sve_fp_3op_pred_hfd<SDPatternOperator op> {
9138  def _H_UNDEF : PredThreeOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9139  def _S_UNDEF : PredThreeOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9140  def _D_UNDEF : PredThreeOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9141
9142  def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9143  def : SVE_4_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9144  def : SVE_4_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9145  def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S_UNDEF)>;
9146  def : SVE_4_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S_UNDEF)>;
9147  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D_UNDEF)>;
9148}
9149
9150multiclass sve_fp_3op_pred_bf<SDPatternOperator op> {
9151  def _UNDEF : PredThreeOpPseudo<NAME, ZPR16, FalseLanesUndef>;
9152
9153  def : SVE_4_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _UNDEF)>;
9154}
9155
9156// Predicated pseudo integer two operand instructions.
9157multiclass sve_int_bin_pred_bhsd<SDPatternOperator op> {
9158  def _B_UNDEF : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesUndef>;
9159  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9160  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9161  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9162
9163  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
9164  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9165  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9166  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9167}
9168
9169// As sve_int_bin_pred but when only i32 and i64 vector types are required.
9170multiclass sve_int_bin_pred_sd<SDPatternOperator op> {
9171  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9172  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9173
9174  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9175  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9176}
9177
9178// Predicated pseudo integer two operand instructions. Second operand is an
9179// immediate specified by imm_[bhsd].
9180multiclass sve_int_shift_pred_bhsd<SDPatternOperator op,
9181                                   ComplexPattern imm_b, ComplexPattern imm_h,
9182                                   ComplexPattern imm_s, ComplexPattern imm_d> {
9183  def _B_UNDEF : PredTwoOpImmPseudo<NAME # _B, ZPR8,  Operand<i32>, FalseLanesUndef>;
9184  def _H_UNDEF : PredTwoOpImmPseudo<NAME # _H, ZPR16, Operand<i32>, FalseLanesUndef>;
9185  def _S_UNDEF : PredTwoOpImmPseudo<NAME # _S, ZPR32, Operand<i32>, FalseLanesUndef>;
9186  def _D_UNDEF : PredTwoOpImmPseudo<NAME # _D, ZPR64, Operand<i32>, FalseLanesUndef>;
9187
9188  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, imm_b, !cast<Instruction>(NAME # _B_UNDEF)>;
9189  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, imm_h, !cast<Instruction>(NAME # _H_UNDEF)>;
9190  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, imm_s, !cast<Instruction>(NAME # _S_UNDEF)>;
9191  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, imm_d, !cast<Instruction>(NAME # _D_UNDEF)>;
9192}
9193
9194multiclass sve_int_bin_pred_all_active_bhsd<SDPatternOperator op> {
9195  def _B_UNDEF : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesUndef>;
9196  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9197  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9198  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9199
9200  def : SVE_2_Op_Pred_All_Active_Pt<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
9201  def : SVE_2_Op_Pred_All_Active_Pt<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9202  def : SVE_2_Op_Pred_All_Active_Pt<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9203  def : SVE_2_Op_Pred_All_Active_Pt<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9204}
9205
9206//===----------------------------------------------------------------------===//
9207// SME2 or SVE2.1 Instructions
9208//===----------------------------------------------------------------------===//
9209
9210class sve2p1_fclamp<string asm, bits<2> sz, ZPRRegOp zpr_ty>
9211    : I<(outs zpr_ty:$Zd), (ins zpr_ty:$_Zd, zpr_ty:$Zn, zpr_ty:$Zm),
9212        asm, "\t$Zd, $Zn, $Zm", "", []>,
9213      Sched<[]> {
9214  bits<5> Zm;
9215  bits<5> Zn;
9216  bits<5> Zd;
9217  let Inst{31-24} = 0b01100100;
9218  let Inst{23-22} = sz;
9219  let Inst{21}    = 0b1;
9220  let Inst{20-16} = Zm;
9221  let Inst{15-10} = 0b001001;
9222  let Inst{9-5}   = Zn;
9223  let Inst{4-0}   = Zd;
9224
9225  let Constraints = "$Zd = $_Zd";
9226  let DestructiveInstType = DestructiveOther;
9227  let ElementSize = zpr_ty.ElementSize;
9228  let hasSideEffects = 0;
9229}
9230
9231multiclass sve2p1_fclamp<string asm, SDPatternOperator op> {
9232  def _H : sve2p1_fclamp<asm, 0b01, ZPR16>;
9233  def _S : sve2p1_fclamp<asm, 0b10, ZPR32>;
9234  def _D : sve2p1_fclamp<asm, 0b11, ZPR64>;
9235
9236  def : SVE_3_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
9237  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
9238  def : SVE_3_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
9239}
9240
9241multiclass sve2p1_bfclamp<string asm, SDPatternOperator op> {
9242  def NAME : sve2p1_fclamp<asm, 0b00, ZPR16>;
9243  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
9244}
9245
9246// SVE two-way dot product
9247class sve2p1_two_way_dot_vv<string mnemonic, bit u>
9248    : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
9249        mnemonic, "\t$Zda, $Zn, $Zm",
9250        "", []>, Sched<[]> {
9251  bits<5> Zda;
9252  bits<5> Zn;
9253  bits<5> Zm;
9254  let Inst{31-21} = 0b01000100000;
9255  let Inst{20-16} = Zm;
9256  let Inst{15-11} = 0b11001;
9257  let Inst{10}    = u;
9258  let Inst{9-5}   = Zn;
9259  let Inst{4-0}   = Zda;
9260
9261  let Constraints = "$Zda = $_Zda";
9262  let DestructiveInstType = DestructiveOther;
9263  let hasSideEffects = 0;
9264}
9265
9266multiclass sve2p1_two_way_dot_vv<string mnemonic, bit u, SDPatternOperator intrinsic> {
9267  def NAME : sve2p1_two_way_dot_vv<mnemonic, u>;
9268
9269  def : SVE_3_Op_Pat<nxv4i32, intrinsic, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
9270}
9271
9272// SVE two-way dot product (indexed)
9273class sve2p1_two_way_dot_vvi<string mnemonic, bit u>
9274    : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR3b16:$Zm, VectorIndexS32b:$i2),
9275        mnemonic, "\t$Zda, $Zn, $Zm$i2",
9276        "", []>, Sched<[]> {
9277  bits<5> Zda;
9278  bits<5> Zn;
9279  bits<3> Zm;
9280  bits<2> i2;
9281  let Inst{31-21} = 0b01000100100;
9282  let Inst{20-19} = i2;
9283  let Inst{18-16} = Zm;
9284  let Inst{15-11} = 0b11001;
9285  let Inst{10}    = u;
9286  let Inst{9-5}   = Zn;
9287  let Inst{4-0}   = Zda;
9288
9289  let Constraints = "$Zda = $_Zda";
9290  let DestructiveInstType = DestructiveOther;
9291  let hasSideEffects = 0;
9292}
9293
9294multiclass sve2p1_two_way_dot_vvi<string mnemonic, bit u, SDPatternOperator intrinsic> {
9295  def NAME : sve2p1_two_way_dot_vvi<mnemonic, u>;
9296
9297  def : SVE_4_Op_Imm_Pat<nxv4i32, intrinsic, nxv4i32, nxv8i16, nxv8i16, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
9298}
9299
9300class sve2p1_ptrue_pn<string mnemonic, bits<2> sz, PNRP8to15RegOp pnrty, SDPatternOperator op>
9301    : I<(outs pnrty:$PNd), (ins ), mnemonic, "\t$PNd",
9302        "", [(set pnrty:$PNd, (op))]>, Sched<[]> {
9303  bits<3> PNd;
9304  let Inst{31-24}  = 0b00100101;
9305  let Inst{23-22} = sz;
9306  let Inst{21-3}  = 0b1000000111100000010;
9307  let Inst{2-0}   = PNd;
9308
9309  let hasSideEffects = 0;
9310  let isReMaterializable = 1;
9311}
9312
9313
9314multiclass sve2p1_ptrue_pn<string mnemonic> {
9315 def _B : sve2p1_ptrue_pn<mnemonic, 0b00, PNR8_p8to15, int_aarch64_sve_ptrue_c8>;
9316 def _H : sve2p1_ptrue_pn<mnemonic, 0b01, PNR16_p8to15, int_aarch64_sve_ptrue_c16>;
9317 def _S : sve2p1_ptrue_pn<mnemonic, 0b10, PNR32_p8to15, int_aarch64_sve_ptrue_c32>;
9318 def _D : sve2p1_ptrue_pn<mnemonic, 0b11, PNR64_p8to15, int_aarch64_sve_ptrue_c64>;
9319}
9320
9321
9322// SVE extract mask predicate from predicate-as-counter
9323class sve2p1_pred_as_ctr_to_mask_base<string mnemonic, bits<2> sz, bits<3> opc,
9324                                      RegisterOperand pprty, Operand idxty>
9325    : I<(outs pprty:$Pd), (ins PNRAny_p8to15:$PNn, idxty:$index),
9326        mnemonic, "\t$Pd, $PNn$index",
9327        "", []>, Sched<[]> {
9328  bits<4> Pd;
9329  bits<3> PNn;
9330  bits<2> imm2;
9331  let Inst{31-24} = 0b00100101;
9332  let Inst{23-22} = sz;
9333  let Inst{21-11} = 0b10000001110;
9334  let Inst{10-8}  = opc;
9335  let Inst{7-5}   = PNn;
9336  let Inst{4}     = 0b1;
9337  let Inst{3-0}   = Pd;
9338
9339  let hasSideEffects = 0;
9340}
9341
9342class sve2p1_pred_as_ctr_to_mask<string mnemonic, bits<2> sz, PPRRegOp pprty>
9343    : sve2p1_pred_as_ctr_to_mask_base<mnemonic, sz, {0, ?, ?}, pprty, VectorIndexS32b_timm> {
9344  bits<2> index;
9345  let Inst{9-8} = index;
9346}
9347
9348multiclass sve2p1_pred_as_ctr_to_mask<string mnemonic, SDPatternOperator op> {
9349 def _B : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b00, PPR8>;
9350 def _H : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b01, PPR16>;
9351 def _S : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b10, PPR32>;
9352 def _D : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b11, PPR64>;
9353
9354 def : SVE_2_Op_Imm_Pat<nxv16i1, op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _B)>;
9355 def : SVE_2_Op_Imm_Pat<nxv8i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _H)>;
9356 def : SVE_2_Op_Imm_Pat<nxv4i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
9357 def : SVE_2_Op_Imm_Pat<nxv2i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
9358}
9359
9360
9361class sve2p1_pred_as_ctr_to_mask_pair<string mnemonic, bits<2> sz, RegisterOperand pprty>
9362    : sve2p1_pred_as_ctr_to_mask_base<mnemonic, sz, {1, 0, ?}, pprty, VectorIndexD> {
9363  bit index;
9364  let Inst{8}    = index;
9365}
9366
9367multiclass sve2p1_pred_as_ctr_to_mask_pair<string mnemonic> {
9368 def _B : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b00, PP_b>;
9369 def _H : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b01, PP_h>;
9370 def _S : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b10, PP_s>;
9371 def _D : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b11, PP_d>;
9372}
9373
9374
9375// SME2 multi-vec extract narrow
9376class sve2p1_multi_vec_extract_narrow<string mnemonic, bits<2> opc, bits<3> tsz>
9377    : I<(outs ZPR16:$Zd), (ins ZZ_s_mul_r:$Zn),
9378        mnemonic, "\t$Zd, $Zn",
9379        "", []>, Sched<[]> {
9380  bits<5> Zd;
9381  bits<4> Zn;
9382  let Inst{31-23} = 0b010001010;
9383  let Inst{22}    = tsz{2};
9384  let Inst{21}    = 0b1;
9385  let Inst{20-19} = tsz{1-0};
9386  let Inst{18-13} = 0b001010;
9387  let Inst{12-11} = opc;
9388  let Inst{10}    = 0b0;
9389  let Inst{9-6}   = Zn;
9390  let Inst{5}     = 0b0;
9391  let Inst{4-0}   = Zd;
9392
9393  let hasSideEffects = 0;
9394}
9395
9396multiclass sve2p1_multi_vec_extract_narrow<string mnemonic, bits<2> opc, SDPatternOperator intrinsic> {
9397  def NAME : sve2p1_multi_vec_extract_narrow<mnemonic, opc, 0b010>;
9398  def : SVE2p1_Cvt_VG2_Pat<NAME, intrinsic, nxv8i16, nxv4i32>;
9399}
9400
9401// SVE2 multi-vec shift narrow
9402class sve2p1_multi_vec_shift_narrow<string mnemonic, bits<3> opc, bits<2> tsz>
9403    : I<(outs ZPR16:$Zd), (ins ZZ_s_mul_r:$Zn, tvecshiftR16:$imm4),
9404        mnemonic, "\t$Zd, $Zn, $imm4",
9405        "", []>, Sched<[]> {
9406  bits<5> Zd;
9407  bits<4> Zn;
9408  bits<4> imm4;
9409  let Inst{31-23} = 0b010001011;
9410  let Inst{22}    = tsz{1};
9411  let Inst{21}    = 0b1;
9412  let Inst{20}    = tsz{0};
9413  let Inst{19-16} = imm4;
9414  let Inst{15-14} = 0b00;
9415  let Inst{13-11} = opc;
9416  let Inst{10}    = 0b0;
9417  let Inst{9-6}   = Zn;
9418  let Inst{5}     = 0b0;
9419  let Inst{4-0}   = Zd;
9420
9421  let hasSideEffects = 0;
9422}
9423
9424multiclass sve2p1_multi_vec_shift_narrow<string mnemonic, bits<3> opc, SDPatternOperator intrinsic> {
9425  def NAME : sve2p1_multi_vec_shift_narrow<mnemonic, opc, 0b01>;
9426
9427  def : SVE2p1_Sat_Shift_VG2_Pat<NAME, intrinsic, nxv8i16, nxv4i32, tvecshiftR16>;
9428}
9429
9430
9431// SME2 multi-vec contiguous load (scalar plus scalar, two registers)
9432class sve2p1_mem_cld_ss_2z<string mnemonic, bits<2> msz, bit n,
9433                         RegisterOperand vector_ty, RegisterOperand gpr_ty>
9434    : I<(outs vector_ty:$Zt),
9435        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9436        mnemonic, "\t$Zt, $PNg/z, [$Rn, $Rm]",
9437        "", []>, Sched<[]> {
9438  bits<4> Zt;
9439  bits<5> Rm;
9440  bits<5> Rn;
9441  bits<3> PNg;
9442  let Inst{31-21} = 0b10100000000;
9443  let Inst{20-16} = Rm;
9444  let Inst{15}    = 0b0;
9445  let Inst{14-13} = msz;
9446  let Inst{12-10} = PNg;
9447  let Inst{9-5} = Rn;
9448  let Inst{4-1} = Zt;
9449  let Inst{0}   = n;
9450
9451  let hasSideEffects = 0;
9452  let mayLoad = 1;
9453}
9454
9455multiclass sve2p1_mem_cld_ss_2z<string mnemonic, bits<2> msz, bit n,
9456                         RegisterOperand vector_ty, RegisterOperand gpr_ty, RegisterOperand vector_pseudo_ty> {
9457  def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm), []>;
9458  def NAME : sve2p1_mem_cld_ss_2z<mnemonic, msz, n, vector_ty, gpr_ty>;
9459}
9460
9461// SME2 multi-vec contiguous load (scalar plus immediate, two registers)
9462class sve2p1_mem_cld_si_2z<string mnemonic, bits<2> msz, bit n,
9463                         RegisterOperand vector_ty>
9464    : I<(outs vector_ty:$Zt),
9465        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4),
9466        mnemonic, "\t$Zt, $PNg/z, [$Rn, $imm4, mul vl]",
9467        "", []>, Sched<[]> {
9468  bits<4> Zt;
9469  bits<5> Rn;
9470  bits<3> PNg;
9471  bits<4> imm4;
9472  let Inst{31-20} = 0b101000000100;
9473  let Inst{19-16} = imm4;
9474  let Inst{15}    = 0b0;
9475  let Inst{14-13} = msz;
9476  let Inst{12-10} = PNg;
9477  let Inst{9-5}   = Rn;
9478  let Inst{4-1}   = Zt;
9479  let Inst{0}     = n;
9480
9481  let hasSideEffects = 0;
9482  let mayLoad = 1;
9483}
9484
9485multiclass sve2p1_mem_cld_si_2z<string mnemonic, bits<2> msz, bit n,
9486                              RegisterOperand vector_ty, RegisterOperand vector_pseudo_ty> {
9487  def NAME : sve2p1_mem_cld_si_2z<mnemonic, msz, n, vector_ty>;
9488  def : InstAlias<mnemonic # " $Zt, $PNg/z, [$Rn]",
9489                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9490  def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4), []>;
9491}
9492
9493// SME2 multi-vec contiguous load (scalar plus scalar, four registers)
9494class sve2p1_mem_cld_ss_4z<string mnemonic, bits<2> msz, bit n,
9495                         RegisterOperand vector_ty, RegisterOperand gpr_ty>
9496    : I<(outs vector_ty:$Zt),
9497        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9498        mnemonic, "\t$Zt, $PNg/z, [$Rn, $Rm]",
9499        "", []>, Sched<[]> {
9500  bits<3> Zt;
9501  bits<5> Rm;
9502  bits<5> Rn;
9503  bits<3> PNg;
9504  let Inst{31-21} = 0b10100000000;
9505  let Inst{20-16} = Rm;
9506  let Inst{15}    = 0b1;
9507  let Inst{14-13} = msz;
9508  let Inst{12-10} = PNg;
9509  let Inst{9-5} = Rn;
9510  let Inst{4-2} = Zt;
9511  let Inst{1}   = 0b0;
9512  let Inst{0}   = n;
9513
9514  let hasSideEffects = 0;
9515  let mayLoad = 1;
9516}
9517
9518multiclass sve2p1_mem_cld_ss_4z<string mnemonic, bits<2> msz, bit n,
9519                         RegisterOperand vector_ty, RegisterOperand gpr_ty, RegisterOperand vector_pseudo_ty> {
9520  def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm), []>;
9521  def NAME : sve2p1_mem_cld_ss_4z<mnemonic, msz, n, vector_ty, gpr_ty>;
9522}
9523
9524// SME2 multi-vec contiguous load (scalar plus immediate, four registers)
9525class sve2p1_mem_cld_si_4z<string mnemonic, bits<2> msz, bit n,
9526                         RegisterOperand vector_ty>
9527    : I<(outs vector_ty:$Zt),
9528        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4),
9529        mnemonic, "\t$Zt, $PNg/z, [$Rn, $imm4, mul vl]",
9530        "", []>, Sched<[]> {
9531  bits<3> Zt;
9532  bits<5> Rn;
9533  bits<3> PNg;
9534  bits<4> imm4;
9535  let Inst{31-20} = 0b101000000100;
9536  let Inst{19-16} = imm4;
9537  let Inst{15}    = 0b1;
9538  let Inst{14-13} = msz;
9539  let Inst{12-10} = PNg;
9540  let Inst{9-5}   = Rn;
9541  let Inst{4-2}   = Zt;
9542  let Inst{1}     = 0b0;
9543  let Inst{0}     = n;
9544
9545  let hasSideEffects = 0;
9546  let mayLoad = 1;
9547}
9548
9549multiclass sve2p1_mem_cld_si_4z<string mnemonic, bits<2> msz, bit n,
9550                              RegisterOperand vector_ty, RegisterOperand vector_pseudo_ty> {
9551  def NAME : sve2p1_mem_cld_si_4z<mnemonic, msz, n, vector_ty>;
9552  def : InstAlias<mnemonic # " $Zt, $PNg/z, [$Rn]",
9553                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9554  def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4), []>;
9555}
9556
9557// SME2 multi-vec contiguous store (scalar plus scalar, two registers)
9558class sve2p1_mem_cst_ss_2z<string mnemonic, bits<2> msz, bit n,
9559                           RegisterOperand vector_ty, RegisterOperand gpr_ty>
9560    : I<(outs ),
9561        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9562        mnemonic, "\t$Zt, $PNg, [$Rn, $Rm]",
9563        "", []>, Sched<[]> {
9564  bits<4> Zt;
9565  bits<5> Rm;
9566  bits<5> Rn;
9567  bits<3> PNg;
9568  let Inst{31-21} = 0b10100000001;
9569  let Inst{20-16} = Rm;
9570  let Inst{15}    = 0b0;
9571  let Inst{14-13} = msz;
9572  let Inst{12-10} = PNg;
9573  let Inst{9-5} = Rn;
9574  let Inst{4-1} = Zt;
9575  let Inst{0}   = n;
9576
9577  let hasSideEffects = 0;
9578  let mayStore = 1;
9579}
9580
9581
9582// SME2 multi-vec contiguous store (scalar plus immediate, two registers)
9583class sve2p1_mem_cst_si_2z<string mnemonic, bits<2> msz, bit n,
9584                           RegisterOperand vector_ty>
9585    : I<(outs ),
9586        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4),
9587        mnemonic, "\t$Zt, $PNg, [$Rn, $imm4, mul vl]",
9588        "", []>, Sched<[]> {
9589  bits<4> Zt;
9590  bits<5> Rn;
9591  bits<3> PNg;
9592  bits<4> imm4;
9593  let Inst{31-20} = 0b101000000110;
9594  let Inst{19-16} = imm4;
9595  let Inst{15}    = 0b0;
9596  let Inst{14-13} = msz;
9597  let Inst{12-10} = PNg;
9598  let Inst{9-5}   = Rn;
9599  let Inst{4-1}   = Zt;
9600  let Inst{0}     = n;
9601
9602  let hasSideEffects = 0;
9603  let mayStore = 1;
9604}
9605
9606
9607multiclass sve2p1_mem_cst_si_2z<string mnemonic, bits<2> msz, bit n,
9608                              RegisterOperand vector_ty> {
9609  def NAME : sve2p1_mem_cst_si_2z<mnemonic, msz, n, vector_ty>;
9610
9611  def : InstAlias<mnemonic # " $Zt, $PNg, [$Rn]",
9612                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9613}
9614
9615
9616// SME2 multi-vec contiguous store (scalar plus scalar, four registers)
9617class sve2p1_mem_cst_ss_4z<string mnemonic, bits<2> msz, bit n,
9618                           RegisterOperand vector_ty, RegisterOperand gpr_ty>
9619    : I<(outs ),
9620        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9621        mnemonic, "\t$Zt, $PNg, [$Rn, $Rm]",
9622        "", []>, Sched<[]> {
9623  bits<3> Zt;
9624  bits<5> Rm;
9625  bits<5> Rn;
9626  bits<3> PNg;
9627  let Inst{31-21} = 0b10100000001;
9628  let Inst{20-16} = Rm;
9629  let Inst{15}    = 0b1;
9630  let Inst{14-13} = msz;
9631  let Inst{12-10} = PNg;
9632  let Inst{9-5} = Rn;
9633  let Inst{4-2} = Zt;
9634  let Inst{1}   = 0b0;
9635  let Inst{0}   = n;
9636
9637  let mayStore = 1;
9638}
9639
9640
9641// SME2 multi-vec contiguous store (scalar plus immediate, four registers)
9642class sve2p1_mem_cst_si_4z<string mnemonic, bits<2> msz, bit n,
9643                           RegisterOperand vector_ty>
9644    : I<(outs ),
9645        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4),
9646        mnemonic, "\t$Zt, $PNg, [$Rn, $imm4, mul vl]",
9647        "", []>, Sched<[]> {
9648  bits<3> Zt;
9649  bits<5> Rn;
9650  bits<3> PNg;
9651  bits<4> imm4;
9652  let Inst{31-20} = 0b101000000110;
9653  let Inst{19-16} = imm4;
9654  let Inst{15}    = 0b1;
9655  let Inst{14-13} = msz;
9656  let Inst{12-10} = PNg;
9657  let Inst{9-5}   = Rn;
9658  let Inst{4-2}   = Zt;
9659  let Inst{1}     = 0b0;
9660  let Inst{0}     = n;
9661
9662  let hasSideEffects = 0;
9663  let mayStore = 1;
9664}
9665
9666
9667multiclass sve2p1_mem_cst_si_4z<string mnemonic, bits<2> msz, bit n,
9668                                RegisterOperand vector_ty> {
9669  def NAME : sve2p1_mem_cst_si_4z<mnemonic, msz, n, vector_ty>;
9670
9671  def : InstAlias<mnemonic # " $Zt, $PNg, [$Rn]",
9672                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn,0), 1>;
9673}
9674
9675// SVE predicate count (predicate-as-counter)
9676class sve2p1_pcount_pn<string mnemonic, bits<3> opc, bits<2> sz, PNRRegOp pnrty>
9677   : I<(outs GPR64:$Rd),
9678       (ins pnrty:$PNn, sve_vec_len_specifier_enum:$vl),
9679       mnemonic, "\t$Rd, $PNn, $vl",
9680       "", []>, Sched<[]> {
9681  bits<5> Rd;
9682  bits<4> PNn;
9683  bits<1> vl;
9684  let Inst{31-24} = 0b00100101;
9685  let Inst{23-22} = sz;
9686  let Inst{21-19} = 0b100;
9687  let Inst{18-16} = opc;
9688  let Inst{15-11} = 0b10000;
9689  let Inst{10}    = vl;
9690  let Inst{9}     = 0b1;
9691  let Inst{8-5}   = PNn;
9692  let Inst{4-0}   = Rd;
9693
9694  let hasSideEffects = 0;
9695}
9696
9697multiclass sve2p1_pcount_pn<string mnemonic, bits<3> opc> {
9698  def _B : sve2p1_pcount_pn<mnemonic, opc, 0b00, PNR8>;
9699  def _H : sve2p1_pcount_pn<mnemonic, opc, 0b01, PNR16>;
9700  def _S : sve2p1_pcount_pn<mnemonic, opc, 0b10, PNR32>;
9701  def _D : sve2p1_pcount_pn<mnemonic, opc, 0b11, PNR64>;
9702
9703  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c8,  aarch64svcount, !cast<Instruction>(NAME # _B)>;
9704  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c16, aarch64svcount, !cast<Instruction>(NAME # _H)>;
9705  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c32, aarch64svcount, !cast<Instruction>(NAME # _S)>;
9706  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c64, aarch64svcount, !cast<Instruction>(NAME # _D)>;
9707}
9708
9709
9710// SVE integer compare scalar count and limit (predicate-as-counter)
9711class sve2p1_int_while_rr_pn<string mnemonic, bits<2> sz, bits<3> opc,
9712                             PNRP8to15RegOp pnrty>
9713    : I<(outs pnrty:$PNd), (ins GPR64:$Rn, GPR64:$Rm, sve_vec_len_specifier_enum:$vl),
9714        mnemonic, "\t$PNd, $Rn, $Rm, $vl",
9715        "", []>, Sched<[]> {
9716  bits<3> PNd;
9717  bits<5> Rn;
9718  bits<1> vl;
9719  bits<5> Rm;
9720  let Inst{31-24} = 0b00100101;
9721  let Inst{23-22} = sz;
9722  let Inst{21}    = 0b1;
9723  let Inst{20-16} = Rm;
9724  let Inst{15-14} = 0b01;
9725  let Inst{13}    = vl;
9726  let Inst{12}    = 0b0;
9727  let Inst{11-10} = opc{2-1};
9728  let Inst{9-5}   = Rn;
9729  let Inst{4}     = 0b1;
9730  let Inst{3}     = opc{0};
9731  let Inst{2-0}   = PNd;
9732
9733  let Defs = [NZCV];
9734  let hasSideEffects = 0;
9735}
9736
9737
9738multiclass sve2p1_int_while_rr_pn<string mnemonic, bits<3> opc> {
9739 def _B : sve2p1_int_while_rr_pn<mnemonic, 0b00, opc, PNR8_p8to15>;
9740 def _H : sve2p1_int_while_rr_pn<mnemonic, 0b01, opc, PNR16_p8to15>;
9741 def _S : sve2p1_int_while_rr_pn<mnemonic, 0b10, opc, PNR32_p8to15>;
9742 def _D : sve2p1_int_while_rr_pn<mnemonic, 0b11, opc, PNR64_p8to15>;
9743
9744 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c8"),
9745                            i64, !cast<Instruction>(NAME # _B)>;
9746 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c16"),
9747                            i64, !cast<Instruction>(NAME # _H)>;
9748 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c32"),
9749                            i64, !cast<Instruction>(NAME # _S)>;
9750 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c64"),
9751                            i64, !cast<Instruction>(NAME # _D)>;
9752}
9753
9754
9755// SVE integer compare scalar count and limit (predicate pair)
9756class sve2p1_int_while_rr_pair<string mnemonic, bits<2> sz, bits<3> opc,
9757                             RegisterOperand ppr_ty>
9758    : I<(outs ppr_ty:$Pd), (ins GPR64:$Rn, GPR64:$Rm),
9759        mnemonic, "\t$Pd, $Rn, $Rm",
9760        "", []>, Sched<[]> {
9761  bits<3> Pd;
9762  bits<5> Rn;
9763  bits<5> Rm;
9764  let Inst{31-24} = 0b00100101;
9765  let Inst{23-22} = sz;
9766  let Inst{21}    = 0b1;
9767  let Inst{20-16} = Rm;
9768  let Inst{15-12} = 0b0101;
9769  let Inst{11-10} = opc{2-1};
9770  let Inst{9-5}   = Rn;
9771  let Inst{4}     = 0b1;
9772  let Inst{3-1}   = Pd;
9773  let Inst{0}     = opc{0};
9774
9775  let Defs = [NZCV];
9776  let hasSideEffects = 0;
9777}
9778
9779
9780multiclass sve2p1_int_while_rr_pair<string mnemonic, bits<3> opc> {
9781 def _B : sve2p1_int_while_rr_pair<mnemonic, 0b00, opc, PP_b_mul_r>;
9782 def _H : sve2p1_int_while_rr_pair<mnemonic, 0b01, opc, PP_h_mul_r>;
9783 def _S : sve2p1_int_while_rr_pair<mnemonic, 0b10, opc, PP_s_mul_r>;
9784 def _D : sve2p1_int_while_rr_pair<mnemonic, 0b11, opc, PP_d_mul_r>;
9785}
9786
9787
9788class sve_mem_128b_gld_64_unscaled<string mnemonic>
9789    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
9790        mnemonic, "\t$Zt, $Pg/z, [$Zn, $Rm]",
9791        "", []>, Sched<[]> {
9792  bits<5> Zt;
9793  bits<5> Zn;
9794  bits<3> Pg;
9795  bits<5> Rm;
9796  let Inst{31-21} = 0b11000100000;
9797  let Inst{20-16} = Rm;
9798  let Inst{15-13} = 0b101;
9799  let Inst{12-10} = Pg;
9800  let Inst{9-5}   = Zn;
9801  let Inst{4-0}   = Zt;
9802
9803  let hasSideEffects = 0;
9804  let mayLoad = 1;
9805}
9806
9807
9808multiclass sve_mem_128b_gld_64_unscaled<string mnemonic, SDPatternOperator op> {
9809  def NAME : sve_mem_128b_gld_64_unscaled<mnemonic>;
9810
9811  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Zn]",
9812                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
9813
9814
9815  def : Pat<(nxv2i64 (op (nxv2i1 PPR3bAny:$Pg),  (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2i64)),
9816            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9817  def : Pat<(nxv4i32 (op (nxv4i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn),  (i64 GPR64sp:$Rm), nxv4i32)),
9818            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9819  def : Pat<(nxv8i16 (op (nxv8i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8i16)),
9820            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9821  def : Pat<(nxv16i8 (op (nxv16i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv16i8)),
9822            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9823
9824  def : Pat<(nxv2f64 (op (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2f64)),
9825            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9826  def : Pat<(nxv4f32 (op (nxv4i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv4f32)),
9827            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9828  def : Pat<(nxv8f16 (op (nxv8i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8f16)),
9829            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9830  def : Pat<(nxv8bf16 (op (nxv8i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8bf16)),
9831            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9832}
9833
9834class sve_mem_sst_128b_64_unscaled<string mnemonic>
9835    : I<(outs ), (ins Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
9836        mnemonic, "\t$Zt, $Pg, [$Zn, $Rm]",
9837        "", []>, Sched<[]> {
9838  bits<5> Zt;
9839  bits<5> Zn;
9840  bits<3> Pg;
9841  bits<5> Rm;
9842  let Inst{31-21} = 0b11100100001;
9843  let Inst{20-16} = Rm;
9844  let Inst{15-13} = 0b001;
9845  let Inst{12-10} = Pg;
9846  let Inst{9-5}   = Zn;
9847  let Inst{4-0}   = Zt;
9848
9849  let hasSideEffects = 0;
9850  let mayStore = 1;
9851}
9852
9853
9854multiclass sve_mem_sst_128b_64_unscaled<string mnemonic, SDPatternOperator op> {
9855  def NAME : sve_mem_sst_128b_64_unscaled<mnemonic>;
9856
9857  def : InstAlias<mnemonic # " $Zt, $Pg, [$Zn]",
9858                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
9859
9860  def : Pat<(op (nxv2i64 Z_q:$Zt), (nxv2i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2i64),
9861            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9862  def : Pat<(op (nxv4i32 Z_q:$Zt), (nxv4i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv4i32),
9863            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9864  def : Pat<(op (nxv8i16 Z_q:$Zt), (nxv8i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8i16),
9865            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp,ZPR64:$Zn, GPR64:$Rm)>;
9866  def : Pat<(op (nxv16i8 Z_q:$Zt), (nxv16i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv16i8),
9867            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9868
9869  def : Pat<(op (nxv2f64 Z_q:$Zt), (nxv2i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2f64),
9870            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9871  def : Pat<(op (nxv4f32 Z_q:$Zt), (nxv4i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv4f32),
9872            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9873  def : Pat<(op (nxv8f16 Z_q:$Zt), (nxv8i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8f16),
9874            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9875  def : Pat<(op (nxv8bf16 Z_q:$Zt), (nxv8i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8bf16),
9876            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9877}
9878
9879
9880// SVE contiguous load (quadwords, scalar plus immediate)
9881class sve_mem_128b_cld_si<bits<2> dtype, string mnemonic>
9882    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
9883        mnemonic, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
9884        "", []>, Sched<[]> {
9885  bits<5> Zt;
9886  bits<5> Rn;
9887  bits<3> Pg;
9888  bits<4> imm4;
9889  let Inst{31-25} = 0b1010010;
9890  let Inst{24-23} = dtype;
9891  let Inst{22-20} = 0b001;
9892  let Inst{19-16} = imm4;
9893  let Inst{15-13} = 0b001;
9894  let Inst{12-10} = Pg;
9895  let Inst{9-5}   = Rn;
9896  let Inst{4-0}   = Zt;
9897
9898  let hasSideEffects = 0;
9899  let mayLoad = 1;
9900}
9901
9902multiclass sve_mem_128b_cld_si<bits<2> dtype, string mnemonic> {
9903  def NAME : sve_mem_128b_cld_si<dtype, mnemonic>;
9904
9905  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn]",
9906                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
9907  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn]",
9908                  (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
9909  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn, $imm4, mul vl]",
9910                  (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
9911}
9912
9913
9914// SVE contiguous load (quadwords, scalar plus scalar)
9915class sve_mem_128b_cld_ss<bits<2> dtype, string mnemonic, RegisterOperand gprsh_ty>
9916    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprsh_ty:$Rm),
9917        mnemonic, "\t$Zt, $Pg/z, [$Rn, $Rm]", "",
9918        []>, Sched<[]> {
9919  bits<5> Zt;
9920  bits<5> Rn;
9921  bits<3> Pg;
9922  bits<5> Rm;
9923  let Inst{31-25} = 0b1010010;
9924  let Inst{24-23} = dtype;
9925  let Inst{22-21} = 0b00;
9926  let Inst{20-16} = Rm;
9927  let Inst{15-13} = 0b100;
9928  let Inst{12-10} = Pg;
9929  let Inst{9-5}   = Rn;
9930  let Inst{4-0}   = Zt;
9931
9932  let hasSideEffects = 0;
9933  let mayLoad = 1;
9934}
9935
9936multiclass sve_mem_128b_cld_ss<bits<2> dtype, string mnemonic, RegisterOperand gprsh_ty> {
9937  def NAME : sve_mem_128b_cld_ss<dtype, mnemonic, gprsh_ty>;
9938
9939  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn, $Rm]",
9940                 (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprsh_ty:$Rm), 0>;
9941}
9942
9943
9944// SVE floating-point recursive reduction (quadwords)
9945class sve2p1_fp_reduction_q<bits<2> sz, bits<3> opc, string mnemonic,
9946                            RegisterOperand zpr_ty, string vec_sfx>
9947    : I<(outs V128:$Vd), (ins PPR3bAny:$Pg, zpr_ty:$Zn),
9948        mnemonic, "\t$Vd." # vec_sfx # ", $Pg, $Zn",
9949        "", []>, Sched<[]> {
9950  bits<5> Vd;
9951  bits<5> Zn;
9952  bits<3> Pg;
9953  let Inst{31-24} = 0b01100100;
9954  let Inst{23-22} = sz;
9955  let Inst{21-19} = 0b010;
9956  let Inst{18-16} = opc;
9957  let Inst{15-13} = 0b101;
9958  let Inst{12-10} = Pg;
9959  let Inst{9-5}   = Zn;
9960  let Inst{4-0}   = Vd;
9961
9962  let hasSideEffects = 0;
9963  let mayRaiseFPException = 1;
9964}
9965
9966multiclass sve2p1_fp_reduction_q<bits<3> opc, string mnemonic, SDPatternOperator op> {
9967  def _H : sve2p1_fp_reduction_q<0b01, opc, mnemonic, ZPR16, "8h">;
9968  def _S : sve2p1_fp_reduction_q<0b10, opc, mnemonic, ZPR32, "4s">;
9969  def _D : sve2p1_fp_reduction_q<0b11, opc, mnemonic, ZPR64, "2d">;
9970
9971  def : SVE_2_Op_Pat<v8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
9972  def : SVE_2_Op_Pat<v4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
9973  def : SVE_2_Op_Pat<v2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
9974}
9975
9976
9977// SVE Permute Vector - Quadwords (DUPQ)
9978class sve2p1_dupq<bits<5> ind_tsz, string mnemonic, ZPRRegOp zprty, Operand itype>
9979    : I<(outs zprty:$Zd), (ins zprty:$Zn, itype:$index),
9980        mnemonic, "\t$Zd, $Zn$index",
9981        "", []>, Sched<[]> {
9982  bits<5> Zd;
9983  bits<5> Zn;
9984  let Inst{31-21} = 0b00000101001;
9985  let Inst{20-16} = ind_tsz;
9986  let Inst{15-10} = 0b001001;
9987  let Inst{9-5} = Zn;
9988  let Inst{4-0} = Zd;
9989
9990  let hasSideEffects = 0;
9991}
9992
9993multiclass sve2p1_dupq<string mnemonic> {
9994  def _B : sve2p1_dupq<{?, ?, ?, ?, 1}, mnemonic, ZPR8, VectorIndexB32b> {
9995    bits<4> index;
9996    let Inst{20-17} = index;
9997  }
9998  def _H : sve2p1_dupq<{?, ?, ?, 1, 0}, mnemonic, ZPR16, VectorIndexH32b> {
9999    bits<3> index;
10000    let Inst{20-18} = index;
10001  }
10002  def _S : sve2p1_dupq<{?, ?, 1, 0, 0}, mnemonic, ZPR32, VectorIndexS32b> {
10003    bits<2> index;
10004    let Inst{20-19} = index;
10005  }
10006  def _D : sve2p1_dupq<{?, 1, 0, 0, 0}, mnemonic, ZPR64, VectorIndexD32b> {
10007    bits<1> index;
10008    let Inst{20} = index;
10009  }
10010}
10011
10012
10013// SVE Permute Vector - Quadwords (EXTQ)
10014class sve2p1_extq<string mnemonic>
10015    : I<(outs ZPR8:$Zdn), (ins ZPR8:$_Zdn, ZPR8:$Zm, timm32_0_15:$imm4),
10016        mnemonic, "\t$Zdn, $_Zdn, $Zm, $imm4",
10017        "", []>, Sched<[]> {
10018  bits<5> Zdn;
10019  bits<5> Zm;
10020  bits<4> imm4;
10021  let Inst{31-20} = 0b000001010110;
10022  let Inst{19-16} = imm4;
10023  let Inst{15-10} = 0b001001;
10024  let Inst{9-5} = Zm;
10025  let Inst{4-0} = Zdn;
10026
10027  let Constraints = "$Zdn = $_Zdn";
10028  let DestructiveInstType = DestructiveOther;
10029  let ElementSize = ZPR8.ElementSize;
10030  let hasSideEffects = 0;
10031}
10032
10033multiclass sve2p1_extq<string mnemonic, SDPatternOperator Op> {
10034  def NAME : sve2p1_extq<mnemonic>;
10035  def : SVE_3_Op_Imm_Pat<nxv16i8, Op, nxv16i8, nxv16i8, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10036  def : SVE_3_Op_Imm_Pat<nxv8i16, Op, nxv8i16, nxv8i16, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10037  def : SVE_3_Op_Imm_Pat<nxv4i32, Op, nxv4i32, nxv4i32, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10038  def : SVE_3_Op_Imm_Pat<nxv2i64, Op, nxv2i64, nxv2i64, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10039
10040  def : SVE_3_Op_Imm_Pat<nxv8f16, Op, nxv8f16, nxv8f16, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10041  def : SVE_3_Op_Imm_Pat<nxv4f32, Op, nxv4f32, nxv4f32, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10042  def : SVE_3_Op_Imm_Pat<nxv2f64, Op, nxv2f64, nxv2f64, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10043  def : SVE_3_Op_Imm_Pat<nxv8bf16, Op, nxv8bf16, nxv8bf16, i32, timm32_0_15, !cast<Instruction>(NAME
10044)>;
10045}
10046
10047// SVE move predicate from vector
10048class sve2p1_vector_to_pred<bits<4> opc, string mnemonic,
10049                            PPRRegOp ppr_ty, Operand itype>
10050    : I<(outs ppr_ty:$Pd), (ins ZPRAny:$Zn, itype:$index),
10051        mnemonic, "\t$Pd, $Zn$index",
10052        "", []>, Sched<[]> {
10053  bits<4> Pd;
10054  bits<5> Zn;
10055  let Inst{31-24} = 0b00000101;
10056  let Inst{23-22} = opc{3-2};
10057  let Inst{21-19} = 0b101;
10058  let Inst{18-17} = opc{1-0};
10059  let Inst{16-10} = 0b0001110;
10060  let Inst{9-5}   = Zn;
10061  let Inst{4}     = 0b0;
10062  let Inst{3-0}   = Pd;
10063
10064  let hasSideEffects = 0;
10065}
10066
10067multiclass sve2p1_vector_to_pred<string mnemonic, SDPatternOperator Op_lane, SDPatternOperator Op> {
10068  def _B : sve2p1_vector_to_pred<{0, 0, 0, 1}, mnemonic, PPR8,  VectorIndex032b>;
10069  def _H : sve2p1_vector_to_pred<{0, 0, 1, ?}, mnemonic, PPR16, VectorIndexD32b> {
10070    bits<1> index;
10071    let Inst{17} = index;
10072  }
10073  def _S : sve2p1_vector_to_pred<{0, 1, ?, ?}, mnemonic, PPR32, VectorIndexS32b> {
10074    bits<2> index;
10075    let Inst{18-17} = index;
10076  }
10077  def _D : sve2p1_vector_to_pred<{1, ?, ?, ?}, mnemonic, PPR64, VectorIndexH32b> {
10078    bits<3> index;
10079    let Inst{22}    = index{2};
10080    let Inst{18-17} = index{1-0};
10081  }
10082
10083  def : InstAlias<mnemonic # "\t$Pd, $Zn",
10084                 (!cast<Instruction>(NAME # _B) PPR8:$Pd, ZPRAny:$Zn, 0), 1>;
10085
10086  // any_lane
10087  def : Pat<(nxv16i1 (Op_lane (nxv16i8 ZPRAny:$Zn), (i32 timm32_0_0:$Idx))),
10088            (!cast<Instruction>(NAME # _B) ZPRAny:$Zn, timm32_0_0:$Idx)>;
10089  def : Pat<(nxv8i1 (Op_lane (nxv8i16 ZPRAny:$Zn), (i32 timm32_0_1:$Idx))),
10090            (!cast<Instruction>(NAME # _H) ZPRAny:$Zn, timm32_0_1:$Idx)>;
10091  def : Pat<(nxv4i1 (Op_lane (nxv4i32 ZPRAny:$Zn), (i32 timm32_0_3:$Idx))),
10092            (!cast<Instruction>(NAME # _S) ZPRAny:$Zn, timm32_0_3:$Idx)>;
10093  def : Pat<(nxv2i1 (Op_lane (nxv2i64 ZPRAny:$Zn), (i32 timm32_0_7:$Idx))),
10094            (!cast<Instruction>(NAME # _D) ZPRAny:$Zn, timm32_0_7:$Idx)>;
10095 // lane_0
10096 def : Pat<(nxv16i1 (Op (nxv16i8 ZPRAny:$Zn))),
10097            (!cast<Instruction>(NAME # _B) ZPRAny:$Zn, 0)>;
10098  def : Pat<(nxv8i1 (Op (nxv8i16 ZPRAny:$Zn))),
10099            (!cast<Instruction>(NAME # _H) ZPRAny:$Zn, 0)>;
10100  def : Pat<(nxv4i1 (Op (nxv4i32 ZPRAny:$Zn))),
10101            (!cast<Instruction>(NAME # _S) ZPRAny:$Zn, 0)>;
10102  def : Pat<(nxv2i1 (Op (nxv2i64 ZPRAny:$Zn))),
10103            (!cast<Instruction>(NAME # _D) ZPRAny:$Zn, 0)>;
10104}
10105
10106
10107// SVE move predicate into vector
10108class sve2p1_pred_to_vector<bits<4> opc, string mnemonic,
10109                            PPRRegOp ppr_ty, Operand itype>
10110    : I<(outs ZPRAny:$Zd), (ins ZPRAny:$_Zd, itype:$index, ppr_ty:$Pn),
10111        mnemonic, "\t$Zd$index, $Pn",
10112        "", []>, Sched<[]> {
10113  bits<5> Zd;
10114  bits<4> Pn;
10115  let Inst{31-24} = 0b00000101;
10116  let Inst{23-22} = opc{3-2};
10117  let Inst{21-19} = 0b101;
10118  let Inst{18-17} = opc{1-0};
10119  let Inst{16-9}  = 0b10011100;
10120  let Inst{8-5}   = Pn;
10121  let Inst{4-0}   = Zd;
10122
10123  let Constraints = "$Zd = $_Zd";
10124  let hasSideEffects = 0;
10125}
10126
10127multiclass sve2p1_pred_to_vector<string mnemonic, SDPatternOperator MergeOp,
10128                                 SDPatternOperator ZeroOp> {
10129  def _B : sve2p1_pred_to_vector<{0, 0, 0, 1}, mnemonic, PPR8,  VectorIndex0>;
10130  def _H : sve2p1_pred_to_vector<{0, 0, 1, ?}, mnemonic, PPR16, VectorIndexD32b> {
10131    bits<1> index;
10132    let Inst{17} = index;
10133  }
10134  def _S : sve2p1_pred_to_vector<{0, 1, ?, ?}, mnemonic, PPR32, VectorIndexS32b> {
10135    bits<2> index;
10136    let Inst{18-17} = index;
10137  }
10138  def _D : sve2p1_pred_to_vector<{1, ?, ?, ?}, mnemonic, PPR64, VectorIndexH32b> {
10139    bits<3> index;
10140    let Inst{22}    = index{2};
10141    let Inst{18-17} = index{1-0};
10142  }
10143
10144  def : InstAlias<mnemonic # "\t$Zd, $Pn",
10145                 (!cast<Instruction>(NAME # _B) ZPRAny:$Zd, 0, PPR8:$Pn), 1>;
10146
10147  // Merge
10148  def : Pat<(nxv8i16 (MergeOp (nxv8i16 ZPRAny:$Zd), (nxv8i1 PPR16:$Pn), (i32 timm32_1_1:$Idx))),
10149            (!cast<Instruction>(NAME # _H) ZPRAny:$Zd, timm32_1_1:$Idx, PPR16:$Pn)>;
10150  def : Pat<(nxv4i32 (MergeOp (nxv4i32 ZPRAny:$Zd), (nxv4i1 PPR32:$Pn), (i32 timm32_1_3:$Idx))),
10151            (!cast<Instruction>(NAME # _S) ZPRAny:$Zd, timm32_1_3:$Idx, PPR32:$Pn)>;
10152  def : Pat<(nxv2i64 (MergeOp (nxv2i64 ZPRAny:$Zd), (nxv2i1 PPR64:$Pn), (i32 timm32_1_7:$Idx))),
10153            (!cast<Instruction>(NAME # _D) ZPRAny:$Zd, timm32_1_7:$Idx, PPR64:$Pn)>;
10154
10155  // Zero
10156  def : Pat<(nxv16i8 (ZeroOp (nxv16i1 PPR8:$Pn))),
10157           (!cast<Instruction>(NAME # _B) (IMPLICIT_DEF), 0, PPR8:$Pn)>;
10158  def : Pat<(nxv8i16 (ZeroOp (nxv8i1 PPR16:$Pn))),
10159            (!cast<Instruction>(NAME # _H) (IMPLICIT_DEF), 0, PPR16:$Pn)>;
10160  def : Pat<(nxv4i32 (ZeroOp (nxv4i1 PPR32:$Pn))),
10161            (!cast<Instruction>(NAME # _S) (IMPLICIT_DEF), 0, PPR32:$Pn)>;
10162  def : Pat<(nxv2i64 (ZeroOp (nxv2i1 PPR64:$Pn))),
10163            (!cast<Instruction>(NAME # _D) (IMPLICIT_DEF), 0, PPR64:$Pn)>;
10164}
10165
10166
10167// SVE bitwise logical/add/min/max reductions (quadwords)
10168class sve2p1_int_reduce_q<bits<2> sz, bits<4> opc, string mnemonic,
10169                          RegisterOperand zpr_ty, string vec_sfx>
10170    : I<(outs V128:$Vd), (ins PPR3bAny:$Pg, zpr_ty:$Zn),
10171        mnemonic, "\t$Vd." # vec_sfx # ", $Pg, $Zn",
10172        "", []>, Sched<[]> {
10173  bits<5> Vd;
10174  bits<5> Zn;
10175  bits<3> Pg;
10176  let Inst{31-24} = 0b00000100;
10177  let Inst{23-22} = sz;
10178  let Inst{21}    = 0b0;
10179  let Inst{20-19} = opc{3-2};
10180  let Inst{18}    = 0b1;
10181  let Inst{17-16} = opc{1-0};
10182  let Inst{15-13} = 0b001;
10183  let Inst{12-10} = Pg;
10184  let Inst{9-5}   = Zn;
10185  let Inst{4-0}   = Vd;
10186
10187  let hasSideEffects = 0;
10188}
10189
10190multiclass sve2p1_int_reduce_q<bits<4> opc, string mnemonic, SDPatternOperator op> {
10191  def _B : sve2p1_int_reduce_q<0b00, opc, mnemonic, ZPR8,  "16b">;
10192  def _H : sve2p1_int_reduce_q<0b01, opc, mnemonic, ZPR16, "8h">;
10193  def _S : sve2p1_int_reduce_q<0b10, opc, mnemonic, ZPR32, "4s">;
10194  def _D : sve2p1_int_reduce_q<0b11, opc, mnemonic, ZPR64, "2d">;
10195
10196  def : SVE_2_Op_Pat<v16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
10197  def : SVE_2_Op_Pat<v8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
10198  def : SVE_2_Op_Pat<v4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
10199  def : SVE_2_Op_Pat<v2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
10200}
10201
10202
10203// SVE permute vector elements (quadwords)
10204class sve2p1_permute_vec_elems_q<bits<2> sz, bits<3> opc, string mnemonic,
10205                                 ZPRRegOp zpr_ty, RegisterOperand src1_ty>
10206    : I<(outs zpr_ty:$Zd), (ins src1_ty:$Zn, zpr_ty:$Zm),
10207        mnemonic, "\t$Zd, $Zn, $Zm",
10208        "", []>, Sched<[]> {
10209  bits<5> Zd;
10210  bits<5> Zn;
10211  bits<5> Zm;
10212  let Inst{31-24} = 0b01000100;
10213  let Inst{23-22} = sz;
10214  let Inst{21}    = 0b0;
10215  let Inst{20-16} = Zm;
10216  let Inst{15-13} = 0b111;
10217  let Inst{12-10} = opc;
10218  let Inst{9-5}   = Zn;
10219  let Inst{4-0}   = Zd;
10220
10221  let hasSideEffects = 0;
10222}
10223
10224multiclass sve2p1_permute_vec_elems_q<bits<3> opc, string mnemonic,
10225                                      SDPatternOperator op> {
10226  def _B : sve2p1_permute_vec_elems_q<0b00, opc, mnemonic, ZPR8,  ZPR8>;
10227  def _H : sve2p1_permute_vec_elems_q<0b01, opc, mnemonic, ZPR16, ZPR16>;
10228  def _S : sve2p1_permute_vec_elems_q<0b10, opc, mnemonic, ZPR32, ZPR32>;
10229  def _D : sve2p1_permute_vec_elems_q<0b11, opc, mnemonic, ZPR64, ZPR64>;
10230
10231  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
10232  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10233  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
10234  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
10235
10236  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
10237  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
10238  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
10239
10240  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
10241}
10242
10243multiclass sve2p1_tblq<string mnemonic, SDPatternOperator op> {
10244  def _B : sve2p1_permute_vec_elems_q<0b00, 0b110, mnemonic, ZPR8,  Z_b>;
10245  def _H : sve2p1_permute_vec_elems_q<0b01, 0b110, mnemonic, ZPR16, Z_h>;
10246  def _S : sve2p1_permute_vec_elems_q<0b10, 0b110, mnemonic, ZPR32, Z_s>;
10247  def _D : sve2p1_permute_vec_elems_q<0b11, 0b110, mnemonic, ZPR64, Z_d>;
10248
10249  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
10250  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10251  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
10252  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
10253
10254  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10255  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
10256  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
10257
10258  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10259}
10260
10261//===----------------------------------------------------------------------===//
10262// SVE2 FP8 Instructions
10263//===----------------------------------------------------------------------===//
10264
10265// FP8 upconvert
10266class sve2_fp8_cvt_single<bit L, bits<2> opc, string mnemonic,
10267                          ZPRRegOp dst_ty, ZPRRegOp src_ty>
10268    : I<(outs dst_ty:$Zd), (ins src_ty:$Zn),
10269      mnemonic, "\t$Zd, $Zn",
10270      "", []>, Sched<[]>{
10271  bits<5> Zd;
10272  bits<5> Zn;
10273  let Inst{31-17} = 0b011001010000100;
10274  let Inst{16}    = L;
10275  let Inst{15-12} = 0b0011;
10276  let Inst{11-10} = opc;
10277  let Inst{9-5}   = Zn;
10278  let Inst{4-0}   = Zd;
10279}
10280
10281multiclass sve2_fp8_cvt_single<bit L, bits<2> opc, string mnemonic> {
10282  def _BtoH : sve2_fp8_cvt_single<L, opc, mnemonic, ZPR16, ZPR8>;
10283}
10284
10285// FP8 downconvert
10286class sve2_fp8_down_cvt_single<bits<2> opc, string mnemonic,
10287                              ZPRRegOp dst_ty, RegisterOperand src_ty>
10288    : I<(outs dst_ty:$Zd), (ins src_ty:$Zn),
10289      mnemonic, "\t$Zd, $Zn",
10290      "", []>, Sched<[]>{
10291  bits<5> Zd;
10292  bits<4> Zn;
10293  let Inst{31-12} = 0b01100101000010100011;
10294  let Inst{11-10} = opc;
10295  let Inst{9-6} = Zn;
10296  let Inst{5} = 0b0;
10297  let Inst{4-0} = Zd;
10298}
10299
10300multiclass sve2_fp8_down_cvt_single<bits<2> opc, string mnemonic, RegisterOperand src> {
10301  def NAME : sve2_fp8_down_cvt_single<opc, mnemonic, ZPR8, src>;
10302}
10303
10304// FP8 Widening Multiply-Add Long - Indexed Group
10305class sve2_fp8_mla_long_by_indexed_elem<bit T, string mnemonic>
10306    : I<(outs ZPR16:$Zda),
10307      (ins ZPR16:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexB:$imm4),
10308      mnemonic, "\t$Zda, $Zn, $Zm$imm4",
10309      "", []>, Sched<[]>{
10310  bits<5> Zda;
10311  bits<5> Zn;
10312  bits<3> Zm;
10313  bits<4> imm4;
10314  let Inst{31-24} = 0b01100100;
10315  let Inst{23}    = T;
10316  let Inst{22-21} = 0b01;
10317  let Inst{20-19} = imm4{3-2};
10318  let Inst{18-16} = Zm;
10319  let Inst{15-12} = 0b0101;
10320  let Inst{11-10} = imm4{1-0};
10321  let Inst{9-5}   = Zn;
10322  let Inst{4-0}   = Zda;
10323  let Constraints = "$Zda = $_Zda";
10324  let DestructiveInstType = DestructiveOther;
10325  let ElementSize         = ZPR16.ElementSize;
10326}
10327
10328// FP8 Widening Multiply-Add (Long)/(Long Long) Group
10329class sve2_fp8_mla<bits<3>opc, ZPRRegOp dst_ty, string mnemonic>
10330    : I<(outs dst_ty:$Zda),
10331      (ins dst_ty:$_Zda, ZPR8:$Zn, ZPR8:$Zm),
10332      mnemonic, "\t$Zda, $Zn, $Zm",
10333      "", []>, Sched<[]>{
10334  bits<5> Zda;
10335  bits<5> Zn;
10336  bits<5> Zm;
10337  let Inst{31-24} = 0b01100100;
10338  let Inst{23}    = opc{2};
10339  let Inst{22-21} = 0b01;
10340  let Inst{20-16} = Zm;
10341  let Inst{15-14} = 0b10;
10342  let Inst{13-12} = opc{1-0};
10343  let Inst{11-10} = 0b10;
10344  let Inst{9-5}   = Zn;
10345  let Inst{4-0}   = Zda;
10346  let Constraints = "$Zda = $_Zda";
10347  let DestructiveInstType = DestructiveOther;
10348  let ElementSize         = dst_ty.ElementSize;
10349}
10350
10351// FP8 Widening Multiply-Add Long Long - Indexed Group
10352class sve2_fp8_mla_long_long_by_indexed_elem<bits<2> TT, string mnemonic>
10353    : I<(outs ZPR32:$Zda),
10354      (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexB:$imm4),
10355      mnemonic, "\t$Zda, $Zn, $Zm$imm4",
10356      "", []>, Sched<[]>{
10357  bits<5> Zda;
10358  bits<5> Zn;
10359  bits<3> Zm;
10360  bits<4> imm4;
10361  let Inst{31-24} = 0b01100100;
10362  let Inst{23-22} = TT;
10363  let Inst{21}    = 0b1;
10364  let Inst{20-19} = imm4{3-2};
10365  let Inst{18-16} = Zm;
10366  let Inst{15-12} = 0b1100;
10367  let Inst{11-10} = imm4{1-0};
10368  let Inst{9-5}   = Zn;
10369  let Inst{4-0}   = Zda;
10370  let Constraints = "$Zda = $_Zda";
10371  let DestructiveInstType = DestructiveOther;
10372  let ElementSize         = ZPR32.ElementSize;
10373}
10374
10375// FP8 Widening Dot-Product - Indexed Group
10376multiclass sve2_fp8_dot_indexed<string mnemonic>{
10377  def NAME : sve_float_dot_indexed<0b0, ZPR16, ZPR8, ZPR3b8, VectorIndexH, mnemonic> {
10378    bits<3> iop;
10379    let Inst{20-19} = iop{2-1};
10380    let Inst{11} = iop{0};
10381    let Inst{10} = 0b1;
10382  }
10383}
10384
10385// FP8 Look up table
10386class sve2_lut_vector_index<ZPRRegOp zd_ty, RegisterOperand zn_ty,
10387                            Operand idx_ty, bits<4>opc, string mnemonic>
10388    : I<(outs zd_ty:$Zd), (ins zn_ty:$Zn, ZPRAny:$Zm, idx_ty:$idx),
10389      mnemonic, "\t$Zd, $Zn, $Zm$idx",
10390      "", []>, Sched<[]> {
10391  bits<5> Zd;
10392  bits<5> Zn;
10393  bits<5> Zm;
10394  let Inst{31-24} = 0b01000101;
10395  let Inst{22}    = opc{3};
10396  let Inst{21}    = 0b1;
10397  let Inst{20-16} = Zm;
10398  let Inst{15-13} = 0b101;
10399  let Inst{12-10} = opc{2-0};
10400  let Inst{9-5}   = Zn;
10401  let Inst{4-0}   = Zd;
10402}
10403
10404// FP8 Look up table read with 2-bit indices
10405multiclass sve2_luti2_vector_index<string mnemonic> {
10406  def _B : sve2_lut_vector_index<ZPR8, Z_b, VectorIndexS32b, {?, 0b100}, mnemonic> {
10407    bits<2> idx;
10408    let Inst{23-22} = idx;
10409  }
10410  def _H : sve2_lut_vector_index<ZPR16, Z_h, VectorIndexH32b, {?,?,0b10}, mnemonic> {
10411    bits<3> idx;
10412    let Inst{23-22} = idx{2-1};
10413    let Inst{12}    = idx{0};
10414  }
10415}
10416
10417// FP8 Look up table read with 4-bit indices
10418multiclass sve2_luti4_vector_index<string mnemonic> {
10419  def _B : sve2_lut_vector_index<ZPR8, Z_b, VectorIndexD32b, 0b1001, mnemonic> {
10420    bit idx;
10421    let Inst{23} = idx;
10422  }
10423  def _H : sve2_lut_vector_index<ZPR16, Z_h, VectorIndexS32b, {?, 0b111}, mnemonic> {
10424    bits<2> idx;
10425    let Inst{23-22} = idx;
10426  }
10427}
10428
10429// FP8 Look up table read with 4-bit indices (two contiguous registers)
10430multiclass sve2_luti4_vector_vg2_index<string mnemonic> {
10431  def _H : sve2_lut_vector_index<ZPR16, ZZ_h, VectorIndexS32b, {?, 0b101}, mnemonic> {
10432    bits<2> idx;
10433    let Inst{23-22} = idx;
10434  }
10435}
10436