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 sve_fp_2op_p_zds<bits<4> opc, string asm, string Ps,
2122                            SDPatternOperator op, DestructiveInstTypeEnum flags,
2123                            string revname="", bit isReverseInstr=0> {
2124  let DestructiveInstType = flags in {
2125  def _H : sve_fp_2op_p_zds<0b01, opc, asm, ZPR16>,
2126           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2127  def _S : sve_fp_2op_p_zds<0b10, opc, asm, ZPR32>,
2128           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2129  def _D : sve_fp_2op_p_zds<0b11, opc, asm, ZPR64>,
2130           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2131  }
2132
2133  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2134  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2135  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2136}
2137
2138multiclass sve_fp_2op_p_zds_fscale<bits<4> opc, string asm,
2139                                   SDPatternOperator op> {
2140  def _H : sve_fp_2op_p_zds<0b01, opc, asm, ZPR16>;
2141  def _S : sve_fp_2op_p_zds<0b10, opc, asm, ZPR32>;
2142  def _D : sve_fp_2op_p_zds<0b11, opc, asm, ZPR64>;
2143
2144  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2145  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2146  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2147}
2148
2149multiclass sve_fp_2op_p_zds_zeroing_hsd<SDPatternOperator op> {
2150  def _H_ZERO : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesZero>;
2151  def _S_ZERO : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesZero>;
2152  def _D_ZERO : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesZero>;
2153
2154  def : SVE_3_Op_Pat_SelZero<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Pseudo>(NAME # _H_ZERO)>;
2155  def : SVE_3_Op_Pat_SelZero<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Pseudo>(NAME # _S_ZERO)>;
2156  def : SVE_3_Op_Pat_SelZero<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Pseudo>(NAME # _D_ZERO)>;
2157}
2158
2159class sve_fp_ftmad<bits<2> sz, string asm, ZPRRegOp zprty>
2160: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, timm32_0_7:$imm3),
2161  asm, "\t$Zdn, $_Zdn, $Zm, $imm3",
2162  "",
2163  []>, Sched<[]> {
2164  bits<5> Zdn;
2165  bits<5> Zm;
2166  bits<3> imm3;
2167  let Inst{31-24} = 0b01100101;
2168  let Inst{23-22} = sz;
2169  let Inst{21-19} = 0b010;
2170  let Inst{18-16} = imm3;
2171  let Inst{15-10} = 0b100000;
2172  let Inst{9-5}   = Zm;
2173  let Inst{4-0}   = Zdn;
2174
2175  let Constraints = "$Zdn = $_Zdn";
2176  let DestructiveInstType = DestructiveOther;
2177  let ElementSize = ElementSizeNone;
2178  let hasSideEffects = 0;
2179  let mayRaiseFPException = 1;
2180}
2181
2182multiclass sve_fp_ftmad<string asm, SDPatternOperator op> {
2183  def _H : sve_fp_ftmad<0b01, asm, ZPR16>;
2184  def _S : sve_fp_ftmad<0b10, asm, ZPR32>;
2185  def _D : sve_fp_ftmad<0b11, asm, ZPR64>;
2186
2187  def : Pat<(nxv8f16 (op (nxv8f16 ZPR16:$Zn), (nxv8f16 ZPR16:$Zm), (i32 timm32_0_7:$imm))),
2188            (!cast<Instruction>(NAME # _H) ZPR16:$Zn, ZPR16:$Zm, timm32_0_7:$imm)>;
2189  def : Pat<(nxv4f32 (op (nxv4f32 ZPR32:$Zn), (nxv4f32 ZPR32:$Zm), (i32 timm32_0_7:$imm))),
2190            (!cast<Instruction>(NAME # _S) ZPR32:$Zn, ZPR32:$Zm, timm32_0_7:$imm)>;
2191  def : Pat<(nxv2f64 (op (nxv2f64 ZPR64:$Zn), (nxv2f64 ZPR64:$Zm), (i32 timm32_0_7:$imm))),
2192            (!cast<Instruction>(NAME # _D) ZPR64:$Zn, ZPR64:$Zm, timm32_0_7:$imm)>;
2193}
2194
2195multiclass sve_fp_2op_i_p_zds_hfd<Operand imm_ty, FPImmLeaf A, FPImmLeaf B, SDPatternOperator ir_op = null_frag> {
2196  def _H_UNDEF : PredTwoOpImmPseudo<NAME # _H, ZPR16, imm_ty, FalseLanesUndef>;
2197  def _S_UNDEF : PredTwoOpImmPseudo<NAME # _S, ZPR32, imm_ty, FalseLanesUndef>;
2198  def _D_UNDEF : PredTwoOpImmPseudo<NAME # _D, ZPR64, imm_ty, FalseLanesUndef>;
2199
2200  def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, ir_op, nxv8i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2201  def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, ir_op, nxv8i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2202  def : SVE_2_Op_Fp_Imm_Pat<nxv4f16, ir_op, nxv4i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2203  def : SVE_2_Op_Fp_Imm_Pat<nxv4f16, ir_op, nxv4i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2204  def : SVE_2_Op_Fp_Imm_Pat<nxv2f16, ir_op, nxv2i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2205  def : SVE_2_Op_Fp_Imm_Pat<nxv2f16, ir_op, nxv2i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2206  def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, ir_op, nxv4i1, f32, A, 0, !cast<Instruction>(NAME # "_S_UNDEF")>;
2207  def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, ir_op, nxv4i1, f32, B, 1, !cast<Instruction>(NAME # "_S_UNDEF")>;
2208  def : SVE_2_Op_Fp_Imm_Pat<nxv2f32, ir_op, nxv2i1, f32, A, 0, !cast<Instruction>(NAME # "_S_UNDEF")>;
2209  def : SVE_2_Op_Fp_Imm_Pat<nxv2f32, ir_op, nxv2i1, f32, B, 1, !cast<Instruction>(NAME # "_S_UNDEF")>;
2210  def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, ir_op, nxv2i1, f64, A, 0, !cast<Instruction>(NAME # "_D_UNDEF")>;
2211  def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, ir_op, nxv2i1, f64, B, 1, !cast<Instruction>(NAME # "_D_UNDEF")>;
2212}
2213
2214multiclass sve_fp_2op_i_p_zds_zeroing_hfd<Operand imm_ty, FPImmLeaf A, FPImmLeaf B, SDPatternOperator op> {
2215  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, imm_ty, FalseLanesZero>;
2216  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, imm_ty, FalseLanesZero>;
2217  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, imm_ty, FalseLanesZero>;
2218
2219  let AddedComplexity = 2 in {
2220    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv8f16, op, nxv8i1, f16, A, 0, !cast<Instruction>(NAME # "_H_ZERO")>;
2221    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv8f16, op, nxv8i1, f16, B, 1, !cast<Instruction>(NAME # "_H_ZERO")>;
2222    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv4f32, op, nxv4i1, f32, A, 0, !cast<Instruction>(NAME # "_S_ZERO")>;
2223    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv4f32, op, nxv4i1, f32, B, 1, !cast<Instruction>(NAME # "_S_ZERO")>;
2224    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv2f64, op, nxv2i1, f64, A, 0, !cast<Instruction>(NAME # "_D_ZERO")>;
2225    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv2f64, op, nxv2i1, f64, B, 1, !cast<Instruction>(NAME # "_D_ZERO")>;
2226  }
2227}
2228
2229//===----------------------------------------------------------------------===//
2230// SVE Floating Point Arithmetic - Unpredicated Group
2231//===----------------------------------------------------------------------===//
2232
2233class sve_fp_3op_u_zd<bits<2> sz, bits<3> opc, string asm, ZPRRegOp zprty>
2234: I<(outs zprty:$Zd), (ins  zprty:$Zn, zprty:$Zm),
2235  asm, "\t$Zd, $Zn, $Zm",
2236  "",
2237  []>, Sched<[]> {
2238  bits<5> Zd;
2239  bits<5> Zm;
2240  bits<5> Zn;
2241  let Inst{31-24} = 0b01100101;
2242  let Inst{23-22} = sz;
2243  let Inst{21}    = 0b0;
2244  let Inst{20-16} = Zm;
2245  let Inst{15-13} = 0b000;
2246  let Inst{12-10} = opc;
2247  let Inst{9-5}   = Zn;
2248  let Inst{4-0}   = Zd;
2249
2250  let hasSideEffects = 0;
2251  let mayRaiseFPException = 1;
2252}
2253
2254multiclass sve_fp_3op_u_zd<bits<3> opc, string asm, SDPatternOperator op,
2255                           SDPatternOperator predicated_op = null_frag> {
2256  def _H : sve_fp_3op_u_zd<0b01, opc, asm, ZPR16>;
2257  def _S : sve_fp_3op_u_zd<0b10, opc, asm, ZPR32>;
2258  def _D : sve_fp_3op_u_zd<0b11, opc, asm, ZPR64>;
2259
2260  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2261  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2262  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2263
2264  def : SVE_2_Op_Pred_All_Active<nxv8f16, predicated_op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2265  def : SVE_2_Op_Pred_All_Active<nxv4f32, predicated_op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2266  def : SVE_2_Op_Pred_All_Active<nxv2f64, predicated_op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2267}
2268
2269multiclass sve_fp_3op_u_zd_ftsmul<bits<3> opc, string asm, SDPatternOperator op> {
2270  def _H : sve_fp_3op_u_zd<0b01, opc, asm, ZPR16>;
2271  def _S : sve_fp_3op_u_zd<0b10, opc, asm, ZPR32>;
2272  def _D : sve_fp_3op_u_zd<0b11, opc, asm, ZPR64>;
2273
2274  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2275  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2276  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2277}
2278
2279//===----------------------------------------------------------------------===//
2280// SVE Floating Point Fused Multiply-Add Group
2281//===----------------------------------------------------------------------===//
2282
2283class sve_fp_3op_p_zds_a<bits<2> sz, bits<2> opc, string asm, ZPRRegOp zprty>
2284: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm),
2285  asm, "\t$Zda, $Pg/m, $Zn, $Zm",
2286  "",
2287  []>, Sched<[]> {
2288  bits<3> Pg;
2289  bits<5> Zda;
2290  bits<5> Zm;
2291  bits<5> Zn;
2292  let Inst{31-24} = 0b01100101;
2293  let Inst{23-22} = sz;
2294  let Inst{21}    = 0b1;
2295  let Inst{20-16} = Zm;
2296  let Inst{15}    = 0b0;
2297  let Inst{14-13} = opc;
2298  let Inst{12-10} = Pg;
2299  let Inst{9-5}   = Zn;
2300  let Inst{4-0}   = Zda;
2301
2302  let Constraints = "$Zda = $_Zda";
2303  let ElementSize = zprty.ElementSize;
2304  let DestructiveInstType = DestructiveTernaryCommWithRev;
2305  let hasSideEffects = 0;
2306  let mayRaiseFPException = 1;
2307}
2308
2309multiclass sve_fp_3op_p_zds_a<bits<2> opc, string asm, string Ps,
2310                              SDPatternOperator op, string revname,
2311                              bit isReverseInstr=0> {
2312  def _H : sve_fp_3op_p_zds_a<0b01, opc, asm, ZPR16>,
2313           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2314  def _S : sve_fp_3op_p_zds_a<0b10, opc, asm, ZPR32>,
2315           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2316  def _D : sve_fp_3op_p_zds_a<0b11, opc, asm, ZPR64>,
2317           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2318
2319  def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2320  def : SVE_4_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H)>;
2321  def : SVE_4_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H)>;
2322  def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2323  def : SVE_4_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S)>;
2324  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2325}
2326
2327class sve_fp_3op_p_zds_b<bits<2> sz, bits<2> opc, string asm,
2328                         ZPRRegOp zprty>
2329: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm, zprty:$Za),
2330  asm, "\t$Zdn, $Pg/m, $Zm, $Za",
2331  "",
2332  []>, Sched<[]> {
2333  bits<3> Pg;
2334  bits<5> Za;
2335  bits<5> Zdn;
2336  bits<5> Zm;
2337  let Inst{31-24} = 0b01100101;
2338  let Inst{23-22} = sz;
2339  let Inst{21}    = 0b1;
2340  let Inst{20-16} = Za;
2341  let Inst{15}    = 0b1;
2342  let Inst{14-13} = opc;
2343  let Inst{12-10} = Pg;
2344  let Inst{9-5}   = Zm;
2345  let Inst{4-0}   = Zdn;
2346
2347  let Constraints = "$Zdn = $_Zdn";
2348  let DestructiveInstType = DestructiveOther;
2349  let ElementSize = zprty.ElementSize;
2350  let hasSideEffects = 0;
2351  let mayRaiseFPException = 1;
2352}
2353
2354multiclass sve_fp_3op_p_zds_b<bits<2> opc, string asm, SDPatternOperator op,
2355                              string revname, bit isReverseInstr> {
2356  def _H : sve_fp_3op_p_zds_b<0b01, opc, asm, ZPR16>,
2357           SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2358  def _S : sve_fp_3op_p_zds_b<0b10, opc, asm, ZPR32>,
2359           SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2360  def _D : sve_fp_3op_p_zds_b<0b11, opc, asm, ZPR64>,
2361           SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2362
2363  def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2364  def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2365  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2366}
2367
2368//===----------------------------------------------------------------------===//
2369// SVE Floating Point Multiply-Add - Indexed Group
2370//===----------------------------------------------------------------------===//
2371
2372class sve_fp_fma_by_indexed_elem<bits<2> sz, bits<2> opc, string asm,
2373                                 ZPRRegOp zprty1,
2374                                 ZPRRegOp zprty2, Operand itype>
2375: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty1:$Zn, zprty2:$Zm, itype:$iop),
2376  asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
2377  bits<5> Zda;
2378  bits<5> Zn;
2379  let Inst{31-24} = 0b01100100;
2380  let Inst{23-22} = sz;
2381  let Inst{21}    = 0b1;
2382  let Inst{15-12} = 0b0000;
2383  let Inst{11-10} = opc;
2384  let Inst{9-5}   = Zn;
2385  let Inst{4-0}   = Zda;
2386
2387  let Constraints = "$Zda = $_Zda";
2388  let DestructiveInstType = DestructiveOther;
2389  let ElementSize = ElementSizeNone;
2390  let hasSideEffects = 0;
2391  let mayRaiseFPException = 1;
2392}
2393
2394multiclass sve2p1_fp_bfma_by_indexed_elem<string asm, bits<2> opc> {
2395  def NAME : sve_fp_fma_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR3b16,
2396                                         VectorIndexH32b> {
2397    bits<3> Zm;
2398    bits<3> iop;
2399    let Inst{22} = iop{2};
2400    let Inst{20-19} = iop{1-0};
2401    let Inst{18-16} = Zm;
2402  }
2403}
2404
2405multiclass sve_fp_fma_by_indexed_elem<bits<2> opc, string asm,
2406                                      SDPatternOperator op> {
2407  def _H : sve_fp_fma_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2408    bits<3> Zm;
2409    bits<3> iop;
2410    let Inst{22} = iop{2};
2411    let Inst{20-19} = iop{1-0};
2412    let Inst{18-16} = Zm;
2413  }
2414  def _S : sve_fp_fma_by_indexed_elem<0b10, opc, asm, ZPR32, ZPR3b32, VectorIndexS32b> {
2415    bits<3> Zm;
2416    bits<2> iop;
2417    let Inst{20-19} = iop;
2418    let Inst{18-16} = Zm;
2419  }
2420  def _D : sve_fp_fma_by_indexed_elem<0b11, opc, asm, ZPR64, ZPR4b64, VectorIndexD32b> {
2421    bits<4> Zm;
2422    bit iop;
2423    let Inst{20} = iop;
2424    let Inst{19-16} = Zm;
2425  }
2426
2427  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 VectorIndexH32b_timm:$idx))),
2428            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, VectorIndexH32b_timm:$idx)>;
2429  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 VectorIndexS32b_timm:$idx))),
2430            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, VectorIndexS32b_timm:$idx)>;
2431  def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, (i32 VectorIndexD32b_timm:$idx))),
2432            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, VectorIndexD32b_timm:$idx)>;
2433}
2434
2435
2436//===----------------------------------------------------------------------===//
2437// SVE Floating Point Multiply - Indexed Group
2438//===----------------------------------------------------------------------===//
2439
2440class sve_fp_fmul_by_indexed_elem<bits<2> sz, bit o2, string asm, ZPRRegOp zprty,
2441                                  ZPRRegOp zprty2, Operand itype>
2442: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty2:$Zm, itype:$iop),
2443  asm, "\t$Zd, $Zn, $Zm$iop", "", []>, Sched<[]> {
2444  bits<5> Zd;
2445  bits<5> Zn;
2446  let Inst{31-24} = 0b01100100;
2447  let Inst{23-22} = sz;
2448  let Inst{21}    = 0b1;
2449  let Inst{15-12} = 0b0010;
2450  let Inst{11}    = o2;
2451  let Inst{10}    = 0b0;
2452  let Inst{9-5}   = Zn;
2453  let Inst{4-0}   = Zd;
2454
2455  let hasSideEffects = 0;
2456  let mayRaiseFPException = 1;
2457}
2458
2459multiclass sve2p1_fp_bfmul_by_indexed_elem<string asm> {
2460  def NAME : sve_fp_fmul_by_indexed_elem<{0, ?}, 0b1, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2461    bits<3> Zm;
2462    bits<3> iop;
2463    let Inst{22} = iop{2};
2464    let Inst{20-19} = iop{1-0};
2465    let Inst{18-16} = Zm;
2466  }
2467}
2468
2469multiclass sve_fp_fmul_by_indexed_elem<string asm, SDPatternOperator op> {
2470  def _H : sve_fp_fmul_by_indexed_elem<{0, ?}, 0b0, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2471    bits<3> Zm;
2472    bits<3> iop;
2473    let Inst{22} = iop{2};
2474    let Inst{20-19} = iop{1-0};
2475    let Inst{18-16} = Zm;
2476  }
2477  def _S : sve_fp_fmul_by_indexed_elem<0b10, 0b0, asm, ZPR32, ZPR3b32, VectorIndexS32b> {
2478    bits<3> Zm;
2479    bits<2> iop;
2480    let Inst{20-19} = iop;
2481    let Inst{18-16} = Zm;
2482  }
2483  def _D : sve_fp_fmul_by_indexed_elem<0b11, 0b0, asm, ZPR64, ZPR4b64, VectorIndexD32b> {
2484    bits<4> Zm;
2485    bit iop;
2486    let Inst{20} = iop;
2487    let Inst{19-16} = Zm;
2488  }
2489
2490  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, (i32 VectorIndexH32b_timm:$idx))),
2491            (!cast<Instruction>(NAME # _H) $Op1, $Op2, VectorIndexH32b_timm:$idx)>;
2492  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, (i32 VectorIndexS32b_timm:$idx))),
2493            (!cast<Instruction>(NAME # _S) $Op1, $Op2, VectorIndexS32b_timm:$idx)>;
2494  def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, (i32 VectorIndexD32b_timm:$idx))),
2495            (!cast<Instruction>(NAME # _D) $Op1, $Op2, VectorIndexD32b_timm:$idx)>;
2496}
2497
2498//===----------------------------------------------------------------------===//
2499// SVE Floating Point Complex Multiply-Add Group
2500//===----------------------------------------------------------------------===//
2501
2502class sve_fp_fcmla<bits<2> sz, string asm, ZPRRegOp zprty>
2503: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm,
2504                        complexrotateop:$imm),
2505  asm, "\t$Zda, $Pg/m, $Zn, $Zm, $imm",
2506  "", []>, Sched<[]> {
2507  bits<5> Zda;
2508  bits<3> Pg;
2509  bits<5> Zn;
2510  bits<5> Zm;
2511  bits<2> imm;
2512  let Inst{31-24} = 0b01100100;
2513  let Inst{23-22} = sz;
2514  let Inst{21}    = 0;
2515  let Inst{20-16} = Zm;
2516  let Inst{15}    = 0;
2517  let Inst{14-13} = imm;
2518  let Inst{12-10} = Pg;
2519  let Inst{9-5}   = Zn;
2520  let Inst{4-0}   = Zda;
2521
2522  let Constraints = "$Zda = $_Zda";
2523  let DestructiveInstType = DestructiveOther;
2524  let ElementSize = zprty.ElementSize;
2525  let hasSideEffects = 0;
2526  let mayRaiseFPException = 1;
2527}
2528
2529multiclass sve_fp_fcmla<string asm, SDPatternOperator op> {
2530  def _H : sve_fp_fcmla<0b01, asm, ZPR16>;
2531  def _S : sve_fp_fcmla<0b10, asm, ZPR32>;
2532  def _D : sve_fp_fcmla<0b11, asm, ZPR64>;
2533
2534  def : Pat<(nxv8f16 (op nxv8i1:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, nxv8f16:$Op4, (i32 complexrotateop:$imm))),
2535            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2536  def : Pat<(nxv4f32 (op nxv4i1:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, nxv4f32:$Op4, (i32 complexrotateop:$imm))),
2537            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2538  def : Pat<(nxv2f64 (op nxv2i1:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, nxv2f64:$Op4, (i32 complexrotateop:$imm))),
2539            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2540}
2541
2542//===----------------------------------------------------------------------===//
2543// SVE Floating Point Complex Multiply-Add - Indexed Group
2544//===----------------------------------------------------------------------===//
2545
2546class sve_fp_fcmla_by_indexed_elem<bits<2> sz, string asm,
2547                                   ZPRRegOp zprty,
2548                                   ZPRRegOp zprty2, Operand itype>
2549: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, zprty2:$Zm, itype:$iop,
2550                        complexrotateop:$imm),
2551  asm, "\t$Zda, $Zn, $Zm$iop, $imm",
2552  "", []>, Sched<[]> {
2553  bits<5> Zda;
2554  bits<5> Zn;
2555  bits<2> imm;
2556  let Inst{31-24} = 0b01100100;
2557  let Inst{23-22} = sz;
2558  let Inst{21}    = 0b1;
2559  let Inst{15-12} = 0b0001;
2560  let Inst{11-10} = imm;
2561  let Inst{9-5}   = Zn;
2562  let Inst{4-0}   = Zda;
2563
2564  let Constraints = "$Zda = $_Zda";
2565  let DestructiveInstType = DestructiveOther;
2566  let ElementSize = ElementSizeNone;
2567  let hasSideEffects = 0;
2568  let mayRaiseFPException = 1;
2569}
2570
2571multiclass sve_fp_fcmla_by_indexed_elem<string asm, SDPatternOperator op> {
2572  def _H : sve_fp_fcmla_by_indexed_elem<0b10, asm, ZPR16, ZPR3b16, VectorIndexS32b> {
2573    bits<3> Zm;
2574    bits<2> iop;
2575    let Inst{20-19} = iop;
2576    let Inst{18-16} = Zm;
2577  }
2578  def _S : sve_fp_fcmla_by_indexed_elem<0b11, asm, ZPR32, ZPR4b32, VectorIndexD32b> {
2579    bits<4> Zm;
2580    bits<1> iop;
2581    let Inst{20} = iop;
2582    let Inst{19-16} = Zm;
2583  }
2584
2585  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
2586            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
2587  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
2588            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
2589}
2590
2591//===----------------------------------------------------------------------===//
2592// SVE Floating Point Complex Addition Group
2593//===----------------------------------------------------------------------===//
2594
2595class sve_fp_fcadd<bits<2> sz, string asm, ZPRRegOp zprty>
2596: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm,
2597                        complexrotateopodd:$imm),
2598  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm, $imm",
2599  "",
2600  []>, Sched<[]> {
2601  bits<5> Zdn;
2602  bits<5> Zm;
2603  bits<3> Pg;
2604  bit imm;
2605  let Inst{31-24} = 0b01100100;
2606  let Inst{23-22} = sz;
2607  let Inst{21-17} = 0;
2608  let Inst{16}    = imm;
2609  let Inst{15-13} = 0b100;
2610  let Inst{12-10} = Pg;
2611  let Inst{9-5}   = Zm;
2612  let Inst{4-0}   = Zdn;
2613
2614  let Constraints = "$Zdn = $_Zdn";
2615  let DestructiveInstType = DestructiveOther;
2616  let ElementSize = zprty.ElementSize;
2617  let hasSideEffects = 0;
2618  let mayRaiseFPException = 1;
2619}
2620
2621multiclass sve_fp_fcadd<string asm, SDPatternOperator op> {
2622  def _H : sve_fp_fcadd<0b01, asm, ZPR16>;
2623  def _S : sve_fp_fcadd<0b10, asm, ZPR32>;
2624  def _D : sve_fp_fcadd<0b11, asm, ZPR64>;
2625
2626  def : Pat<(nxv8f16 (op nxv8i1:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 complexrotateopodd:$imm))),
2627            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2628  def : Pat<(nxv4f32 (op nxv4i1:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 complexrotateopodd:$imm))),
2629            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2630  def : Pat<(nxv2f64 (op nxv2i1:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, (i32 complexrotateopodd:$imm))),
2631            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2632}
2633
2634//===----------------------------------------------------------------------===//
2635// SVE2 Floating Point Convert Group
2636//===----------------------------------------------------------------------===//
2637
2638class sve2_fp_convert_precision<bits<4> opc, string asm,
2639                                ZPRRegOp zprty1, ZPRRegOp zprty2>
2640: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, PPR3bAny:$Pg, zprty2:$Zn),
2641  asm, "\t$Zd, $Pg/m, $Zn",
2642  "",
2643  []>, Sched<[]> {
2644  bits<5> Zd;
2645  bits<5> Zn;
2646  bits<3> Pg;
2647  let Inst{31-24} = 0b01100100;
2648  let Inst{23-22} = opc{3-2};
2649  let Inst{21-18} = 0b0010;
2650  let Inst{17-16} = opc{1-0};
2651  let Inst{15-13} = 0b101;
2652  let Inst{12-10} = Pg;
2653  let Inst{9-5}   = Zn;
2654  let Inst{4-0}   = Zd;
2655
2656  let Constraints = "$Zd = $_Zd";
2657  let hasSideEffects = 0;
2658  let mayRaiseFPException = 1;
2659}
2660
2661multiclass sve2_fp_convert_down_narrow<string asm, string op> {
2662  def _StoH : sve2_fp_convert_precision<0b1000, asm, ZPR16, ZPR32>;
2663  def _DtoS : sve2_fp_convert_precision<0b1110, asm, ZPR32, ZPR64>;
2664
2665  def : SVE_3_Op_Pat<nxv8f16, !cast<SDPatternOperator>(op # _f16f32), nxv8f16, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _StoH)>;
2666  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
2667}
2668
2669multiclass sve2_fp_convert_up_long<string asm, string op> {
2670  def _HtoS : sve2_fp_convert_precision<0b1001, asm, ZPR32, ZPR16>;
2671  def _StoD : sve2_fp_convert_precision<0b1111, asm, ZPR64, ZPR32>;
2672
2673  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f16), nxv4f32, nxv4i1, nxv8f16, !cast<Instruction>(NAME # _HtoS)>;
2674  def : SVE_3_Op_Pat<nxv2f64, !cast<SDPatternOperator>(op # _f64f32), nxv2f64, nxv2i1, nxv4f32, !cast<Instruction>(NAME # _StoD)>;
2675}
2676
2677multiclass sve2_fp_convert_down_odd_rounding_top<string asm, string op> {
2678  def _DtoS : sve2_fp_convert_precision<0b0010, asm, ZPR32, ZPR64>;
2679
2680  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
2681}
2682
2683//===----------------------------------------------------------------------===//
2684// SVE2 Floating Point Pairwise Group
2685//===----------------------------------------------------------------------===//
2686
2687class sve2_fp_pairwise_pred<bits<2> sz, bits<3> opc, string asm,
2688                            ZPRRegOp zprty>
2689: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
2690  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
2691  "",
2692  []>, Sched<[]> {
2693  bits<3> Pg;
2694  bits<5> Zm;
2695  bits<5> Zdn;
2696  let Inst{31-24} = 0b01100100;
2697  let Inst{23-22} = sz;
2698  let Inst{21-19} = 0b010;
2699  let Inst{18-16} = opc;
2700  let Inst{15-13} = 0b100;
2701  let Inst{12-10} = Pg;
2702  let Inst{9-5}   = Zm;
2703  let Inst{4-0}   = Zdn;
2704
2705  let Constraints = "$Zdn = $_Zdn";
2706  let DestructiveInstType = DestructiveOther;
2707  let ElementSize = zprty.ElementSize;
2708  let hasSideEffects = 0;
2709  let mayRaiseFPException = 1;
2710}
2711
2712multiclass sve2_fp_pairwise_pred<bits<3> opc, string asm,
2713                                 SDPatternOperator op> {
2714  def _H : sve2_fp_pairwise_pred<0b01, opc, asm, ZPR16>;
2715  def _S : sve2_fp_pairwise_pred<0b10, opc, asm, ZPR32>;
2716  def _D : sve2_fp_pairwise_pred<0b11, opc, asm, ZPR64>;
2717
2718  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2719  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2720  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2721}
2722
2723//===----------------------------------------------------------------------===//
2724// SVE2 Floating Point Widening Multiply-Add - Indexed Group
2725//===----------------------------------------------------------------------===//
2726
2727class sve2_fp_mla_long_by_indexed_elem<bits<3> opc, string asm>
2728: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR3b16:$Zm,
2729                        VectorIndexH32b:$iop),
2730  asm, "\t$Zda, $Zn, $Zm$iop",
2731  "",
2732  []>, Sched<[]> {
2733  bits<5> Zda;
2734  bits<5> Zn;
2735  bits<3> Zm;
2736  bits<3> iop;
2737  let Inst{31-23} = 0b011001001;
2738  let Inst{22}    = opc{2};
2739  let Inst{21}    = 0b1;
2740  let Inst{20-19} = iop{2-1};
2741  let Inst{18-16} = Zm;
2742  let Inst{15-14} = 0b01;
2743  let Inst{13}    = opc{1};
2744  let Inst{12}    = 0b0;
2745  let Inst{11}    = iop{0};
2746  let Inst{10}    = opc{0};
2747  let Inst{9-5}   = Zn;
2748  let Inst{4-0}   = Zda;
2749
2750  let Constraints = "$Zda = $_Zda";
2751  let DestructiveInstType = DestructiveOther;
2752  let ElementSize = ElementSizeNone;
2753  let hasSideEffects = 0;
2754  let mayRaiseFPException = 1;
2755}
2756
2757multiclass sve2_fp_mla_long_by_indexed_elem<bits<3> opc, string asm,
2758                                            ValueType OutVT, ValueType InVT,
2759                                            SDPatternOperator op> {
2760  def NAME : sve2_fp_mla_long_by_indexed_elem<opc, asm>;
2761  def : SVE_4_Op_Imm_Pat<OutVT, op, OutVT, InVT, InVT, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME)>;
2762}
2763
2764//===----------------------------------------------------------------------===//
2765// SVE2 Floating Point Widening Multiply-Add Group
2766//===----------------------------------------------------------------------===//
2767
2768class sve2_fp_mla_long<bits<3> opc, string asm>
2769: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
2770  asm, "\t$Zda, $Zn, $Zm",
2771  "",
2772  []>, Sched<[]> {
2773  bits<5> Zda;
2774  bits<5> Zn;
2775  bits<5> Zm;
2776  let Inst{31-23} = 0b011001001;
2777  let Inst{22}    = opc{2};
2778  let Inst{21}    = 0b1;
2779  let Inst{20-16} = Zm;
2780  let Inst{15-14} = 0b10;
2781  let Inst{13}    = opc{1};
2782  let Inst{12-11} = 0b00;
2783  let Inst{10}    = opc{0};
2784  let Inst{9-5}   = Zn;
2785  let Inst{4-0}   = Zda;
2786
2787  let Constraints = "$Zda = $_Zda";
2788  let DestructiveInstType = DestructiveOther;
2789  let ElementSize = ElementSizeNone;
2790  let hasSideEffects = 0;
2791  let mayRaiseFPException = 1;
2792}
2793
2794multiclass sve2_fp_mla_long<bits<3> opc, string asm, ValueType OutVT,
2795                            ValueType InVT, SDPatternOperator op> {
2796  def NAME : sve2_fp_mla_long<opc, asm>;
2797  def : SVE_3_Op_Pat<OutVT, op, OutVT, InVT, InVT, !cast<Instruction>(NAME)>;
2798}
2799
2800//===----------------------------------------------------------------------===//
2801// SVE Stack Allocation Group
2802//===----------------------------------------------------------------------===//
2803
2804class sve_int_arith_vl<bit opc, string asm, bit streaming_sve = 0b0>
2805: I<(outs GPR64sp:$Rd), (ins GPR64sp:$Rn, simm6_32b:$imm6),
2806  asm, "\t$Rd, $Rn, $imm6",
2807  "",
2808  []>, Sched<[]> {
2809  bits<5> Rd;
2810  bits<5> Rn;
2811  bits<6> imm6;
2812  let Inst{31-23} = 0b000001000;
2813  let Inst{22}    = opc;
2814  let Inst{21}    = 0b1;
2815  let Inst{20-16} = Rn;
2816  let Inst{15-12} = 0b0101;
2817  let Inst{11}    = streaming_sve;
2818  let Inst{10-5}  = imm6;
2819  let Inst{4-0}   = Rd;
2820
2821  let hasSideEffects = 0;
2822}
2823
2824class sve_int_read_vl_a<bit op, bits<5> opc2, string asm, bit streaming_sve = 0b0>
2825: I<(outs GPR64:$Rd), (ins simm6_32b:$imm6),
2826  asm, "\t$Rd, $imm6",
2827  "",
2828  []>, Sched<[]> {
2829  bits<5> Rd;
2830  bits<6> imm6;
2831  let Inst{31-23} = 0b000001001;
2832  let Inst{22}    = op;
2833  let Inst{21}    = 0b1;
2834  let Inst{20-16} = opc2{4-0};
2835  let Inst{15-12} = 0b0101;
2836  let Inst{11}    = streaming_sve;
2837  let Inst{10-5}  = imm6;
2838  let Inst{4-0}   = Rd;
2839
2840  let hasSideEffects = 0;
2841  let isReMaterializable = 1;
2842}
2843
2844//===----------------------------------------------------------------------===//
2845// SVE Permute - In Lane Group
2846//===----------------------------------------------------------------------===//
2847
2848class sve_int_perm_bin_perm_zz<bits<3> opc, bits<2> sz8_64, string asm,
2849                               ZPRRegOp zprty>
2850: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
2851  asm, "\t$Zd, $Zn, $Zm",
2852  "",
2853  []>, Sched<[]> {
2854  bits<5> Zd;
2855  bits<5> Zm;
2856  bits<5> Zn;
2857  let Inst{31-24} = 0b00000101;
2858  let Inst{23-22} = sz8_64;
2859  let Inst{21}    = 0b1;
2860  let Inst{20-16} = Zm;
2861  let Inst{15-13} = 0b011;
2862  let Inst{12-10} = opc;
2863  let Inst{9-5}   = Zn;
2864  let Inst{4-0}   = Zd;
2865
2866  let hasSideEffects = 0;
2867}
2868
2869multiclass sve_int_perm_bin_perm_zz<bits<3> opc, string asm,
2870                                    SDPatternOperator op> {
2871  def _B : sve_int_perm_bin_perm_zz<opc, 0b00, asm, ZPR8>;
2872  def _H : sve_int_perm_bin_perm_zz<opc, 0b01, asm, ZPR16>;
2873  def _S : sve_int_perm_bin_perm_zz<opc, 0b10, asm, ZPR32>;
2874  def _D : sve_int_perm_bin_perm_zz<opc, 0b11, asm, ZPR64>;
2875
2876  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
2877  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2878  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2879  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2880
2881  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2882  def : SVE_2_Op_Pat<nxv4f16, op, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _S)>;
2883  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2884  def : SVE_2_Op_Pat<nxv2f16, op, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _D)>;
2885  def : SVE_2_Op_Pat<nxv2f32, op, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _D)>;
2886  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2887
2888  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
2889}
2890
2891//===----------------------------------------------------------------------===//
2892// SVE Floating Point Unary Operations Group
2893//===----------------------------------------------------------------------===//
2894
2895class sve_fp_2op_p_zd<bits<7> opc, string asm, RegisterOperand i_zprtype,
2896                      RegisterOperand o_zprtype, ElementSizeEnum Sz>
2897: I<(outs o_zprtype:$Zd), (ins i_zprtype:$_Zd, PPR3bAny:$Pg, i_zprtype:$Zn),
2898  asm, "\t$Zd, $Pg/m, $Zn",
2899  "",
2900  []>, Sched<[]> {
2901  bits<3> Pg;
2902  bits<5> Zd;
2903  bits<5> Zn;
2904  let Inst{31-24} = 0b01100101;
2905  let Inst{23-22} = opc{6-5};
2906  let Inst{21}    = 0b0;
2907  let Inst{20-16} = opc{4-0};
2908  let Inst{15-13} = 0b101;
2909  let Inst{12-10} = Pg;
2910  let Inst{9-5}   = Zn;
2911  let Inst{4-0}   = Zd;
2912
2913  let Constraints = "$Zd = $_Zd";
2914  let DestructiveInstType = DestructiveUnaryPassthru;
2915  let ElementSize = Sz;
2916  let hasSideEffects = 0;
2917  let mayRaiseFPException = 1;
2918}
2919
2920multiclass sve_fp_2op_p_zd<bits<7> opc, string asm,
2921                           RegisterOperand i_zprtype,
2922                           RegisterOperand o_zprtype,
2923                           SDPatternOperator int_op,
2924                           SDPatternOperator ir_op, ValueType vt1,
2925                           ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
2926  def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>,
2927             SVEPseudo2Instr<NAME, 1>;
2928  // convert vt1 to a packed type for the intrinsic patterns
2929  defvar packedvt1 = SVEContainerVT<vt1>.Value;
2930
2931  // convert vt3 to a packed type for the intrinsic patterns
2932  defvar packedvt3 = SVEContainerVT<vt3>.Value;
2933
2934  def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, packedvt3, !cast<Instruction>(NAME)>;
2935  def : SVE_1_Op_Passthru_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
2936
2937  def _UNDEF : PredOneOpPassthruPseudo<NAME, !cast<ZPRRegOp>(i_zprtype)>;
2938
2939  defm : SVE_1_Op_PassthruUndef_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME # _UNDEF)>;
2940}
2941
2942multiclass sve_fp_2op_p_zdr<bits<7> opc, string asm,
2943                            RegisterOperand i_zprtype,
2944                            RegisterOperand o_zprtype,
2945                            SDPatternOperator int_op,
2946                            SDPatternOperator ir_op, ValueType vt1,
2947                            ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
2948  def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>,
2949             SVEPseudo2Instr<NAME, 1>;
2950
2951  // convert vt1 to a packed type for the intrinsic patterns
2952  defvar packedvt1 = SVEContainerVT<vt1>.Value;
2953
2954  def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, vt3, !cast<Instruction>(NAME)>;
2955  def : SVE_1_Op_Passthru_Round_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
2956
2957  def _UNDEF : PredOneOpPassthruPseudo<NAME, !cast<ZPRRegOp>(i_zprtype)>;
2958
2959  defm : SVE_1_Op_PassthruUndef_Round_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME # _UNDEF)>;
2960}
2961
2962multiclass sve_fp_2op_p_zd_HSD<bits<5> opc, string asm, SDPatternOperator op> {
2963  def _H : sve_fp_2op_p_zd<{ 0b01, opc }, asm, ZPR16, ZPR16, ElementSizeH>,
2964           SVEPseudo2Instr<NAME # _H, 1>;
2965  def _S : sve_fp_2op_p_zd<{ 0b10, opc }, asm, ZPR32, ZPR32, ElementSizeS>,
2966           SVEPseudo2Instr<NAME # _S, 1>;
2967  def _D : sve_fp_2op_p_zd<{ 0b11, opc }, asm, ZPR64, ZPR64, ElementSizeD>,
2968           SVEPseudo2Instr<NAME # _D, 1>;
2969
2970  def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
2971  def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
2972  def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
2973  def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
2974  def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
2975  def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
2976
2977  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
2978  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
2979  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
2980
2981  defm : SVE_1_Op_PassthruUndef_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H_UNDEF)>;
2982  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H_UNDEF)>;
2983  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H_UNDEF)>;
2984  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S_UNDEF)>;
2985  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S_UNDEF)>;
2986  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D_UNDEF)>;
2987}
2988
2989multiclass sve2_fp_flogb<string asm, string Ps, SDPatternOperator op> {
2990  def _H : sve_fp_2op_p_zd<0b0011010, asm, ZPR16, ZPR16, ElementSizeH>,
2991             SVEPseudo2Instr<Ps # _H, 1>;
2992  def _S : sve_fp_2op_p_zd<0b0011100, asm, ZPR32, ZPR32, ElementSizeS>,
2993             SVEPseudo2Instr<Ps # _S, 1>;
2994  def _D : sve_fp_2op_p_zd<0b0011110, asm, ZPR64, ZPR64, ElementSizeD>,
2995             SVEPseudo2Instr<Ps # _D, 1>;
2996
2997  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
2998  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
2999  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
3000}
3001
3002multiclass sve2_fp_un_pred_zeroing_hsd<SDPatternOperator op> {
3003  def _H_ZERO : PredOneOpPassthruPseudo<NAME # _H, ZPR16, FalseLanesZero>;
3004  def _S_ZERO : PredOneOpPassthruPseudo<NAME # _S, ZPR32, FalseLanesZero>;
3005  def _D_ZERO : PredOneOpPassthruPseudo<NAME # _D, ZPR64, FalseLanesZero>;
3006
3007  def : SVE_1_Op_PassthruZero_Pat<nxv8i16, op, nxv8i1, nxv8f16, !cast<Pseudo>(NAME # _H_ZERO)>;
3008  def : SVE_1_Op_PassthruZero_Pat<nxv4i32, op, nxv4i1, nxv4f32, !cast<Pseudo>(NAME # _S_ZERO)>;
3009  def : SVE_1_Op_PassthruZero_Pat<nxv2i64, op, nxv2i1, nxv2f64, !cast<Pseudo>(NAME # _D_ZERO)>;
3010}
3011
3012multiclass sve2_fp_convert_down_odd_rounding<string asm, string op> {
3013  def _DtoS : sve_fp_2op_p_zd<0b0001010, asm, ZPR64, ZPR32, ElementSizeD>;
3014  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
3015}
3016
3017//===----------------------------------------------------------------------===//
3018// SVE Floating Point Unary Operations - Unpredicated Group
3019//===----------------------------------------------------------------------===//
3020
3021class sve_fp_2op_u_zd<bits<2> sz, bits<3> opc, string asm,
3022                      ZPRRegOp zprty>
3023: I<(outs zprty:$Zd), (ins zprty:$Zn),
3024  asm, "\t$Zd, $Zn",
3025  "",
3026  []>, Sched<[]> {
3027  bits<5> Zd;
3028  bits<5> Zn;
3029  let Inst{31-24} = 0b01100101;
3030  let Inst{23-22} = sz;
3031  let Inst{21-19} = 0b001;
3032  let Inst{18-16} = opc;
3033  let Inst{15-10} = 0b001100;
3034  let Inst{9-5}   = Zn;
3035  let Inst{4-0}   = Zd;
3036
3037  let hasSideEffects = 0;
3038  let mayRaiseFPException = 1;
3039}
3040
3041multiclass sve_fp_2op_u_zd<bits<3> opc, string asm, SDPatternOperator op> {
3042  def _H : sve_fp_2op_u_zd<0b01, opc, asm, ZPR16>;
3043  def _S : sve_fp_2op_u_zd<0b10, opc, asm, ZPR32>;
3044  def _D : sve_fp_2op_u_zd<0b11, opc, asm, ZPR64>;
3045
3046  def : SVE_1_Op_Pat<nxv8f16, op, nxv8f16, !cast<Instruction>(NAME # _H)>;
3047  def : SVE_1_Op_Pat<nxv4f32, op, nxv4f32, !cast<Instruction>(NAME # _S)>;
3048  def : SVE_1_Op_Pat<nxv2f64, op, nxv2f64, !cast<Instruction>(NAME # _D)>;
3049}
3050
3051//===----------------------------------------------------------------------===//
3052// SVE Integer Arithmetic - Binary Predicated Group
3053//===----------------------------------------------------------------------===//
3054
3055class sve_int_bin_pred_arit_log<bits<2> sz8_64, bits<2> fmt, bits<3> opc,
3056                                string asm, ZPRRegOp zprty>
3057: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
3058  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm", "", []>, Sched<[]> {
3059  bits<3> Pg;
3060  bits<5> Zdn;
3061  bits<5> Zm;
3062  let Inst{31-24} = 0b00000100;
3063  let Inst{23-22} = sz8_64;
3064  let Inst{21}    = 0b0;
3065  let Inst{20-19} = fmt;
3066  let Inst{18-16} = opc;
3067  let Inst{15-13} = 0b000;
3068  let Inst{12-10} = Pg;
3069  let Inst{9-5}   = Zm;
3070  let Inst{4-0}   = Zdn;
3071
3072  let Constraints = "$Zdn = $_Zdn";
3073  let DestructiveInstType = DestructiveOther;
3074  let ElementSize = zprty.ElementSize;
3075  let hasSideEffects = 0;
3076}
3077
3078multiclass sve_int_bin_pred_log<bits<3> opc, string asm, string Ps,
3079                                SDPatternOperator op,
3080                                DestructiveInstTypeEnum flags> {
3081  let DestructiveInstType = flags in {
3082  def _B : sve_int_bin_pred_arit_log<0b00, 0b11, opc, asm, ZPR8>,
3083             SVEPseudo2Instr<Ps # _B, 1>;
3084  def _H : sve_int_bin_pred_arit_log<0b01, 0b11, opc, asm, ZPR16>,
3085             SVEPseudo2Instr<Ps # _H, 1>;
3086  def _S : sve_int_bin_pred_arit_log<0b10, 0b11, opc, asm, ZPR32>,
3087             SVEPseudo2Instr<Ps # _S, 1>;
3088  def _D : sve_int_bin_pred_arit_log<0b11, 0b11, opc, asm, ZPR64>,
3089             SVEPseudo2Instr<Ps # _D, 1>;
3090  }
3091
3092  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3093  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3094  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3095  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3096}
3097
3098multiclass sve_int_bin_pred_arit_0<bits<3> opc, string asm, string Ps,
3099                                   SDPatternOperator op,
3100                                   DestructiveInstTypeEnum flags,
3101                                   string revname="", bit isReverseInstr=0> {
3102  let DestructiveInstType = flags in {
3103  def _B : sve_int_bin_pred_arit_log<0b00, 0b00, opc, asm, ZPR8>,
3104           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3105  def _H : sve_int_bin_pred_arit_log<0b01, 0b00, opc, asm, ZPR16>,
3106           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3107  def _S : sve_int_bin_pred_arit_log<0b10, 0b00, opc, asm, ZPR32>,
3108           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3109  def _D : sve_int_bin_pred_arit_log<0b11, 0b00, opc, asm, ZPR64>,
3110           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3111  }
3112
3113  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3114  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3115  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3116  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3117}
3118
3119multiclass sve_int_bin_pred_arit_1<bits<3> opc, string asm, string Ps,
3120                                   SDPatternOperator op,
3121                                   DestructiveInstTypeEnum flags> {
3122  let DestructiveInstType = flags in {
3123  def _B : sve_int_bin_pred_arit_log<0b00, 0b01, opc, asm, ZPR8>,
3124           SVEPseudo2Instr<Ps # _B, 1>;
3125  def _H : sve_int_bin_pred_arit_log<0b01, 0b01, opc, asm, ZPR16>,
3126           SVEPseudo2Instr<Ps # _H, 1>;
3127  def _S : sve_int_bin_pred_arit_log<0b10, 0b01, opc, asm, ZPR32>,
3128           SVEPseudo2Instr<Ps # _S, 1>;
3129  def _D : sve_int_bin_pred_arit_log<0b11, 0b01, opc, asm, ZPR64>,
3130           SVEPseudo2Instr<Ps # _D, 1>;
3131  }
3132
3133  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3134  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3135  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3136  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3137}
3138
3139multiclass sve_int_bin_pred_arit_2<bits<3> opc, string asm, string Ps,
3140                                   SDPatternOperator op,
3141                                   DestructiveInstTypeEnum flags> {
3142  let DestructiveInstType = flags in {
3143  def _B : sve_int_bin_pred_arit_log<0b00, 0b10, opc, asm, ZPR8>,
3144           SVEPseudo2Instr<Ps # _B, 1>;
3145  def _H : sve_int_bin_pred_arit_log<0b01, 0b10, opc, asm, ZPR16>,
3146           SVEPseudo2Instr<Ps # _H, 1>;
3147  def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>,
3148           SVEPseudo2Instr<Ps # _S, 1>;
3149  def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>,
3150           SVEPseudo2Instr<Ps # _D, 1>;
3151  }
3152
3153  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3154  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3155  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3156  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3157}
3158
3159// Special case for divides which are not defined for 8b/16b elements.
3160multiclass sve_int_bin_pred_arit_2_div<bits<3> opc, string asm, string Ps,
3161                                       SDPatternOperator op,
3162                                       DestructiveInstTypeEnum flags,
3163                                       string revname="", bit isReverseInstr=0> {
3164  let DestructiveInstType = flags in {
3165  def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>,
3166           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3167  def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>,
3168           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3169  }
3170
3171  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3172  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3173}
3174
3175//===----------------------------------------------------------------------===//
3176// SVE Integer Multiply-Add Group
3177//===----------------------------------------------------------------------===//
3178
3179class sve_int_mladdsub_vvv_pred<bits<2> sz8_64, bits<1> opc, string asm,
3180                                ZPRRegOp zprty>
3181: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm, zprty:$Za),
3182  asm, "\t$Zdn, $Pg/m, $Zm, $Za",
3183  "",
3184  []>, Sched<[]> {
3185  bits<3> Pg;
3186  bits<5> Zdn;
3187  bits<5> Za;
3188  bits<5> Zm;
3189  let Inst{31-24} = 0b00000100;
3190  let Inst{23-22} = sz8_64;
3191  let Inst{21}    = 0b0;
3192  let Inst{20-16} = Zm;
3193  let Inst{15-14} = 0b11;
3194  let Inst{13}    = opc;
3195  let Inst{12-10} = Pg;
3196  let Inst{9-5}   = Za;
3197  let Inst{4-0}   = Zdn;
3198
3199  let Constraints = "$Zdn = $_Zdn";
3200  let DestructiveInstType = DestructiveOther;
3201  let ElementSize = zprty.ElementSize;
3202  let hasSideEffects = 0;
3203}
3204
3205multiclass sve_int_mladdsub_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
3206                                     string revname, bit isReverseInstr=0> {
3207  def _B : sve_int_mladdsub_vvv_pred<0b00, opc, asm, ZPR8>,
3208           SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3209  def _H : sve_int_mladdsub_vvv_pred<0b01, opc, asm, ZPR16>,
3210           SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3211  def _S : sve_int_mladdsub_vvv_pred<0b10, opc, asm, ZPR32>,
3212           SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3213  def _D : sve_int_mladdsub_vvv_pred<0b11, opc, asm, ZPR64>,
3214           SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3215
3216  def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3217  def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3218  def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3219  def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3220}
3221
3222class sve_int_mlas_vvv_pred<bits<2> sz8_64, bits<1> opc, string asm,
3223                            ZPRRegOp zprty>
3224: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm),
3225  asm, "\t$Zda, $Pg/m, $Zn, $Zm",
3226  "",
3227  []>, Sched<[]> {
3228  bits<3> Pg;
3229  bits<5> Zda;
3230  bits<5> Zm;
3231  bits<5> Zn;
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} = 0b01;
3237  let Inst{13}    = opc;
3238  let Inst{12-10} = Pg;
3239  let Inst{9-5}   = Zn;
3240  let Inst{4-0}   = Zda;
3241
3242  let Constraints = "$Zda = $_Zda";
3243  let DestructiveInstType = DestructiveTernaryCommWithRev;
3244  let ElementSize = zprty.ElementSize;
3245  let hasSideEffects = 0;
3246}
3247
3248multiclass sve_int_mlas_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
3249                                 string Ps, string revname, bit isReverseInstr=0> {
3250  def _B : sve_int_mlas_vvv_pred<0b00, opc, asm, ZPR8>,
3251           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3252  def _H : sve_int_mlas_vvv_pred<0b01, opc, asm, ZPR16>,
3253           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3254  def _S : sve_int_mlas_vvv_pred<0b10, opc, asm, ZPR32>,
3255           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3256  def _D : sve_int_mlas_vvv_pred<0b11, opc, asm, ZPR64>,
3257           SVEPseudo2Instr<Ps # _D, 1>, 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
3265//class for generating pseudo for SVE MLA/MAD/MLS/MSB
3266multiclass sve_int_3op_p_mladdsub<SDPatternOperator op> {
3267  def _B_UNDEF : PredThreeOpPseudo<NAME # _B, ZPR8,  FalseLanesUndef>;
3268  def _H_UNDEF : PredThreeOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
3269  def _S_UNDEF : PredThreeOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
3270  def _D_UNDEF : PredThreeOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
3271
3272  let  AddedComplexity = 9 in {
3273    def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B_UNDEF)>;
3274    def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H_UNDEF)>;
3275    def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S_UNDEF)>;
3276    def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D_UNDEF)>;
3277  }
3278}
3279
3280//===----------------------------------------------------------------------===//
3281// SVE2 Integer Multiply-Add - Unpredicated Group
3282//===----------------------------------------------------------------------===//
3283
3284class sve2_int_mla<bits<2> sz, bits<5> opc, string asm,
3285                   ZPRRegOp zprty1, ZPRRegOp zprty2>
3286: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm),
3287  asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
3288  bits<5> Zda;
3289  bits<5> Zn;
3290  bits<5> Zm;
3291  let Inst{31-24} = 0b01000100;
3292  let Inst{23-22} = sz;
3293  let Inst{21}    = 0b0;
3294  let Inst{20-16} = Zm;
3295  let Inst{15}    = 0b0;
3296  let Inst{14-10} = opc;
3297  let Inst{9-5}   = Zn;
3298  let Inst{4-0}   = Zda;
3299
3300  let Constraints = "$Zda = $_Zda";
3301  let DestructiveInstType = DestructiveOther;
3302  let ElementSize = ElementSizeNone;
3303  let hasSideEffects = 0;
3304}
3305
3306multiclass sve2_int_mla<bit S, string asm, SDPatternOperator op> {
3307  def _B : sve2_int_mla<0b00, { 0b1110, S }, asm, ZPR8, ZPR8>;
3308  def _H : sve2_int_mla<0b01, { 0b1110, S }, asm, ZPR16, ZPR16>;
3309  def _S : sve2_int_mla<0b10, { 0b1110, S }, asm, ZPR32, ZPR32>;
3310  def _D : sve2_int_mla<0b11, { 0b1110, S }, asm, ZPR64, ZPR64>;
3311
3312  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3313  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3314  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3315  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3316}
3317
3318multiclass sve2_int_mla_long<bits<5> opc, string asm, SDPatternOperator op> {
3319  def _H : sve2_int_mla<0b01, opc, asm, ZPR16, ZPR8>;
3320  def _S : sve2_int_mla<0b10, opc, asm, ZPR32, ZPR16>;
3321  def _D : sve2_int_mla<0b11, opc, asm, ZPR64, ZPR32>;
3322
3323  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3324  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
3325  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3326}
3327
3328//===----------------------------------------------------------------------===//
3329// SVE2 Integer Multiply-Add - Indexed Group
3330//===----------------------------------------------------------------------===//
3331
3332class sve2_int_mla_by_indexed_elem<bits<2> sz, bits<6> opc, string asm,
3333                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3334                                   ZPRRegOp zprty3, Operand itype>
3335: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop),
3336  asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
3337  bits<5> Zda;
3338  bits<5> Zn;
3339  let Inst{31-24} = 0b01000100;
3340  let Inst{23-22} = sz;
3341  let Inst{21}    = 0b1;
3342  let Inst{15-10} = opc;
3343  let Inst{9-5}   = Zn;
3344  let Inst{4-0}   = Zda;
3345
3346  let Constraints = "$Zda = $_Zda";
3347  let DestructiveInstType = DestructiveOther;
3348  let ElementSize = ElementSizeNone;
3349  let hasSideEffects = 0;
3350}
3351
3352multiclass sve2_int_mla_by_indexed_elem<bits<2> opc, bit S, string asm,
3353                                        SDPatternOperator op> {
3354  def _H : sve2_int_mla_by_indexed_elem<{0, ?}, { 0b000, opc, S }, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexH32b> {
3355    bits<3> Zm;
3356    bits<3> iop;
3357    let Inst{22} = iop{2};
3358    let Inst{20-19} = iop{1-0};
3359    let Inst{18-16} = Zm;
3360  }
3361  def _S : sve2_int_mla_by_indexed_elem<0b10, { 0b000, opc, S }, asm, ZPR32, ZPR32, ZPR3b32, VectorIndexS32b> {
3362    bits<3> Zm;
3363    bits<2> iop;
3364    let Inst{20-19} = iop;
3365    let Inst{18-16} = Zm;
3366  }
3367  def _D : sve2_int_mla_by_indexed_elem<0b11, { 0b000, opc, S }, asm, ZPR64, ZPR64, ZPR4b64, VectorIndexD32b> {
3368    bits<4> Zm;
3369    bit iop;
3370    let Inst{20} = iop;
3371    let Inst{19-16} = Zm;
3372  }
3373
3374  def : SVE_4_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
3375  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3376  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3377}
3378
3379//===----------------------------------------------------------------------===//
3380// SVE2 Integer Multiply-Add Long - Indexed Group
3381//===----------------------------------------------------------------------===//
3382
3383multiclass sve2_int_mla_long_by_indexed_elem<bits<4> opc, string asm,
3384                                             SDPatternOperator op> {
3385  def _S : sve2_int_mla_by_indexed_elem<0b10, { opc{3}, 0b0, opc{2-1}, ?, opc{0} },
3386                                        asm, ZPR32, ZPR16, ZPR3b16, VectorIndexH32b> {
3387    bits<3> Zm;
3388    bits<3> iop;
3389    let Inst{20-19} = iop{2-1};
3390    let Inst{18-16} = Zm;
3391    let Inst{11} = iop{0};
3392  }
3393  def _D : sve2_int_mla_by_indexed_elem<0b11, { opc{3}, 0b0, opc{2-1}, ?, opc{0} },
3394                                        asm, ZPR64, ZPR32, ZPR4b32, VectorIndexS32b> {
3395    bits<4> Zm;
3396    bits<2> iop;
3397    let Inst{20} = iop{1};
3398    let Inst{19-16} = Zm;
3399    let Inst{11} = iop{0};
3400  }
3401
3402  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _S)>;
3403  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
3404}
3405
3406//===----------------------------------------------------------------------===//
3407// SVE Integer Dot Product Group
3408//===----------------------------------------------------------------------===//
3409
3410class sve_intx_dot<bit sz, bit U, string asm, ZPRRegOp zprty1,
3411                   ZPRRegOp zprty2>
3412: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm), asm,
3413  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
3414  bits<5> Zda;
3415  bits<5> Zn;
3416  bits<5> Zm;
3417  let Inst{31-23} = 0b010001001;
3418  let Inst{22}    = sz;
3419  let Inst{21}    = 0;
3420  let Inst{20-16} = Zm;
3421  let Inst{15-11} = 0;
3422  let Inst{10}    = U;
3423  let Inst{9-5}   = Zn;
3424  let Inst{4-0}   = Zda;
3425
3426  let Constraints = "$Zda = $_Zda";
3427  let DestructiveInstType = DestructiveOther;
3428  let hasSideEffects = 0;
3429}
3430
3431multiclass sve_intx_dot<bit opc, string asm, SDPatternOperator op> {
3432  def _S : sve_intx_dot<0b0, opc, asm, ZPR32, ZPR8>;
3433  def _D : sve_intx_dot<0b1, opc, asm, ZPR64, ZPR16>;
3434
3435  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32,  nxv16i8, nxv16i8, !cast<Instruction>(NAME # _S)>;
3436  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _D)>;
3437}
3438
3439//===----------------------------------------------------------------------===//
3440// SVE Integer Dot Product Group - Indexed Group
3441//===----------------------------------------------------------------------===//
3442
3443class sve_intx_dot_by_indexed_elem<bit sz, bit U, string asm,
3444                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3445                                   ZPRRegOp zprty3, Operand itype>
3446: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop),
3447  asm, "\t$Zda, $Zn, $Zm$iop",
3448  "", []>, Sched<[]> {
3449  bits<5> Zda;
3450  bits<5> Zn;
3451  let Inst{31-23} = 0b010001001;
3452  let Inst{22}    = sz;
3453  let Inst{21}    = 0b1;
3454  let Inst{15-11} = 0;
3455  let Inst{10}    = U;
3456  let Inst{9-5}   = Zn;
3457  let Inst{4-0}   = Zda;
3458
3459  let Constraints = "$Zda = $_Zda";
3460  let DestructiveInstType = DestructiveOther;
3461  let hasSideEffects = 0;
3462}
3463
3464multiclass sve_intx_dot_by_indexed_elem<bit opc, string asm,
3465                                        SDPatternOperator op> {
3466  def _S : sve_intx_dot_by_indexed_elem<0b0, opc, asm, ZPR32, ZPR8, ZPR3b8, VectorIndexS32b_timm> {
3467    bits<2> iop;
3468    bits<3> Zm;
3469    let Inst{20-19} = iop;
3470    let Inst{18-16} = Zm;
3471  }
3472  def _D : sve_intx_dot_by_indexed_elem<0b1, opc, asm, ZPR64, ZPR16, ZPR4b16, VectorIndexD32b_timm> {
3473    bits<1> iop;
3474    bits<4> Zm;
3475    let Inst{20} = iop;
3476    let Inst{19-16} = Zm;
3477  }
3478
3479  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv16i8, nxv16i8, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3480  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv8i16, nxv8i16, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3481}
3482
3483//===----------------------------------------------------------------------===//
3484// SVE2 Complex Integer Dot Product Group
3485//===----------------------------------------------------------------------===//
3486
3487class sve2_complex_int_arith<bits<2> sz, bits<4> opc, string asm,
3488                             ZPRRegOp zprty1, ZPRRegOp zprty2>
3489: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm,
3490                         complexrotateop:$rot),
3491  asm, "\t$Zda, $Zn, $Zm, $rot", "", []>, Sched<[]> {
3492  bits<5> Zda;
3493  bits<5> Zn;
3494  bits<5> Zm;
3495  bits<2> rot;
3496  let Inst{31-24} = 0b01000100;
3497  let Inst{23-22} = sz;
3498  let Inst{21}    = 0b0;
3499  let Inst{20-16} = Zm;
3500  let Inst{15-12} = opc;
3501  let Inst{11-10} = rot;
3502  let Inst{9-5}   = Zn;
3503  let Inst{4-0}   = Zda;
3504
3505  let Constraints = "$Zda = $_Zda";
3506  let DestructiveInstType = DestructiveOther;
3507  let ElementSize = ElementSizeNone;
3508  let hasSideEffects = 0;
3509}
3510
3511multiclass sve2_cintx_dot<string asm, SDPatternOperator op> {
3512  def _S : sve2_complex_int_arith<0b10, 0b0001, asm, ZPR32, ZPR8>;
3513  def _D : sve2_complex_int_arith<0b11, 0b0001, asm, ZPR64, ZPR16>;
3514
3515  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv16i8 ZPR8:$Op2), (nxv16i8 ZPR8:$Op3),
3516                         (i32 complexrotateop:$imm))),
3517            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR8:$Op2, ZPR8:$Op3, complexrotateop:$imm)>;
3518  def : Pat<(nxv2i64 (op (nxv2i64 ZPR64:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3519                         (i32 complexrotateop:$imm))),
3520            (!cast<Instruction>(NAME # "_D") ZPR64:$Op1, ZPR16:$Op2, ZPR16:$Op3, complexrotateop:$imm)>;
3521}
3522
3523//===----------------------------------------------------------------------===//
3524// SVE2 Complex Multiply-Add Group
3525//===----------------------------------------------------------------------===//
3526
3527multiclass sve2_int_cmla<bit opc, string asm, SDPatternOperator op> {
3528  def _B : sve2_complex_int_arith<0b00, { 0b001, opc }, asm, ZPR8, ZPR8>;
3529  def _H : sve2_complex_int_arith<0b01, { 0b001, opc }, asm, ZPR16, ZPR16>;
3530  def _S : sve2_complex_int_arith<0b10, { 0b001, opc }, asm, ZPR32, ZPR32>;
3531  def _D : sve2_complex_int_arith<0b11, { 0b001, opc }, asm, ZPR64, ZPR64>;
3532
3533  def : SVE_4_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, i32, complexrotateop, !cast<Instruction>(NAME # _B)>;
3534  def : SVE_4_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, i32, complexrotateop, !cast<Instruction>(NAME # _H)>;
3535  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, i32, complexrotateop, !cast<Instruction>(NAME # _S)>;
3536  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, i32, complexrotateop, !cast<Instruction>(NAME # _D)>;
3537}
3538
3539//===----------------------------------------------------------------------===//
3540// SVE2 Complex Integer Dot Product - Indexed Group
3541//===----------------------------------------------------------------------===//
3542
3543class sve2_complex_int_arith_indexed<bits<2> sz, bits<4> opc, string asm,
3544                                     ZPRRegOp zprty1, ZPRRegOp zprty2,
3545                                     ZPRRegOp zprty3, Operand itype>
3546: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop,
3547                         complexrotateop:$rot),
3548  asm, "\t$Zda, $Zn, $Zm$iop, $rot", "", []>, Sched<[]> {
3549  bits<5> Zda;
3550  bits<5> Zn;
3551  bits<2> rot;
3552  let Inst{31-24} = 0b01000100;
3553  let Inst{23-22} = sz;
3554  let Inst{21}    = 0b1;
3555  let Inst{15-12} = opc;
3556  let Inst{11-10} = rot;
3557  let Inst{9-5}   = Zn;
3558  let Inst{4-0}   = Zda;
3559
3560  let Constraints = "$Zda = $_Zda";
3561  let DestructiveInstType = DestructiveOther;
3562  let ElementSize = ElementSizeNone;
3563  let hasSideEffects = 0;
3564}
3565
3566multiclass sve2_cintx_dot_by_indexed_elem<string asm, SDPatternOperator op> {
3567  def _S : sve2_complex_int_arith_indexed<0b10, 0b0100, asm, ZPR32, ZPR8, ZPR3b8, VectorIndexS32b> {
3568    bits<2> iop;
3569    bits<3> Zm;
3570    let Inst{20-19} = iop;
3571    let Inst{18-16} = Zm;
3572  }
3573  def _D : sve2_complex_int_arith_indexed<0b11, 0b0100, asm, ZPR64, ZPR16, ZPR4b16, VectorIndexD32b> {
3574    bit iop;
3575    bits<4> Zm;
3576    let Inst{20} = iop;
3577    let Inst{19-16} = Zm;
3578  }
3579
3580  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv16i8 ZPR8:$Op2), (nxv16i8 ZPR8:$Op3),
3581                         (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
3582            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR8:$Op2, ZPR8:$Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
3583  def : Pat<(nxv2i64 (op (nxv2i64 ZPR64:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3584                         (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
3585            (!cast<Instruction>(NAME # "_D") ZPR64:$Op1, ZPR16:$Op2, ZPR16:$Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
3586}
3587
3588//===----------------------------------------------------------------------===//
3589// SVE2 Complex Multiply-Add - Indexed Group
3590//===----------------------------------------------------------------------===//
3591
3592multiclass sve2_cmla_by_indexed_elem<bit opc, string asm,
3593                                     SDPatternOperator op> {
3594  def _H : sve2_complex_int_arith_indexed<0b10, { 0b011, opc }, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexS32b> {
3595    bits<2> iop;
3596    bits<3> Zm;
3597    let Inst{20-19} = iop;
3598    let Inst{18-16} = Zm;
3599  }
3600  def _S : sve2_complex_int_arith_indexed<0b11, { 0b011, opc }, asm, ZPR32, ZPR32, ZPR4b32, VectorIndexD32b> {
3601    bit iop;
3602    bits<4> Zm;
3603    let Inst{20} = iop;
3604    let Inst{19-16} = Zm;
3605  }
3606
3607  def : Pat<(nxv8i16 (op (nxv8i16 ZPR16:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3608                         (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
3609            (!cast<Instruction>(NAME # "_H") ZPR16:$Op1, ZPR16:$Op2, ZPR16:$Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
3610
3611  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv4i32 ZPR32:$Op2), (nxv4i32 ZPR32:$Op3),
3612                         (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
3613            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR32:$Op2, ZPR32:$Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
3614}
3615
3616//===----------------------------------------------------------------------===//
3617// SVE2 Integer Multiply - Unpredicated Group
3618//===----------------------------------------------------------------------===//
3619
3620class sve2_int_mul<bits<2> sz, bits<3> opc, string asm, ZPRRegOp zprty>
3621: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
3622  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3623  bits<5> Zd;
3624  bits<5> Zm;
3625  bits<5> Zn;
3626  let Inst{31-24} = 0b00000100;
3627  let Inst{23-22} = sz;
3628  let Inst{21}    = 0b1;
3629  let Inst{20-16} = Zm;
3630  let Inst{15-13} = 0b011;
3631  let Inst{12-10} = opc;
3632  let Inst{9-5}   = Zn;
3633  let Inst{4-0}   = Zd;
3634
3635  let hasSideEffects = 0;
3636}
3637
3638multiclass sve2_int_mul<bits<3> opc, string asm, SDPatternOperator op,
3639                        SDPatternOperator op_pred = null_frag> {
3640  def _B : sve2_int_mul<0b00, opc, asm, ZPR8>;
3641  def _H : sve2_int_mul<0b01, opc, asm, ZPR16>;
3642  def _S : sve2_int_mul<0b10, opc, asm, ZPR32>;
3643  def _D : sve2_int_mul<0b11, opc, asm, ZPR64>;
3644
3645  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3646  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3647  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3648  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3649
3650  def : SVE_2_Op_Pred_Any_Predicate<nxv16i8, op_pred, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3651  def : SVE_2_Op_Pred_Any_Predicate<nxv8i16, op_pred, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3652  def : SVE_2_Op_Pred_Any_Predicate<nxv4i32, op_pred, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3653  def : SVE_2_Op_Pred_Any_Predicate<nxv2i64, op_pred, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3654}
3655
3656multiclass sve2_int_mul_single<bits<3> opc, string asm, SDPatternOperator op> {
3657  def _B : sve2_int_mul<0b00, opc, asm, ZPR8>;
3658
3659  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3660}
3661
3662//===----------------------------------------------------------------------===//
3663// SVE2 Integer Multiply - Indexed Group
3664//===----------------------------------------------------------------------===//
3665
3666class sve2_int_mul_by_indexed_elem<bits<2> sz, bits<4> opc, string asm,
3667                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3668                                   ZPRRegOp zprty3, Operand itype>
3669: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty3:$Zm, itype:$iop),
3670  asm, "\t$Zd, $Zn, $Zm$iop", "", []>, Sched<[]> {
3671  bits<5> Zd;
3672  bits<5> Zn;
3673  let Inst{31-24} = 0b01000100;
3674  let Inst{23-22} = sz;
3675  let Inst{21}    = 0b1;
3676  let Inst{15-14} = 0b11;
3677  let Inst{13-10} = opc;
3678  let Inst{9-5}   = Zn;
3679  let Inst{4-0}   = Zd;
3680
3681  let hasSideEffects = 0;
3682}
3683
3684multiclass sve2_int_mul_by_indexed_elem<bits<4> opc, string asm,
3685                                        SDPatternOperator op> {
3686  def _H : sve2_int_mul_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexH32b> {
3687    bits<3> Zm;
3688    bits<3> iop;
3689    let Inst{22} = iop{2};
3690    let Inst{20-19} = iop{1-0};
3691    let Inst{18-16} = Zm;
3692  }
3693  def _S : sve2_int_mul_by_indexed_elem<0b10, opc, asm, ZPR32, ZPR32, ZPR3b32, VectorIndexS32b> {
3694    bits<3> Zm;
3695    bits<2> iop;
3696    let Inst{20-19} = iop;
3697    let Inst{18-16} = Zm;
3698  }
3699  def _D : sve2_int_mul_by_indexed_elem<0b11, opc, asm, ZPR64, ZPR64, ZPR4b64, VectorIndexD32b> {
3700    bits<4> Zm;
3701    bit iop;
3702    let Inst{20} = iop;
3703    let Inst{19-16} = Zm;
3704  }
3705
3706  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
3707  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3708  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3709}
3710
3711multiclass sve2_int_mul_long_by_indexed_elem<bits<3> opc, string asm,
3712                                             SDPatternOperator op> {
3713  def _S : sve2_int_mul_by_indexed_elem<0b10, { opc{2-1}, ?, opc{0} }, asm,
3714                                        ZPR32, ZPR16, ZPR3b16, VectorIndexH32b> {
3715    bits<3> Zm;
3716    bits<3> iop;
3717    let Inst{20-19} = iop{2-1};
3718    let Inst{18-16} = Zm;
3719    let Inst{11} = iop{0};
3720  }
3721  def _D : sve2_int_mul_by_indexed_elem<0b11, { opc{2-1}, ?, opc{0} }, asm,
3722                                        ZPR64, ZPR32, ZPR4b32, VectorIndexS32b> {
3723    bits<4> Zm;
3724    bits<2> iop;
3725    let Inst{20} = iop{1};
3726    let Inst{19-16} = Zm;
3727    let Inst{11} = iop{0};
3728  }
3729
3730  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _S)>;
3731  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
3732}
3733
3734//===----------------------------------------------------------------------===//
3735// SVE2 Integer - Predicated Group
3736//===----------------------------------------------------------------------===//
3737
3738class sve2_int_arith_pred<bits<2> sz, bits<6> opc, string asm,
3739                          ZPRRegOp zprty>
3740: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
3741  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm", "", []>, Sched<[]> {
3742  bits<3> Pg;
3743  bits<5> Zm;
3744  bits<5> Zdn;
3745  let Inst{31-24} = 0b01000100;
3746  let Inst{23-22} = sz;
3747  let Inst{21-20} = 0b01;
3748  let Inst{20-16} = opc{5-1};
3749  let Inst{15-14} = 0b10;
3750  let Inst{13}    = opc{0};
3751  let Inst{12-10} = Pg;
3752  let Inst{9-5}   = Zm;
3753  let Inst{4-0}   = Zdn;
3754
3755  let Constraints = "$Zdn = $_Zdn";
3756  let DestructiveInstType = DestructiveOther;
3757  let ElementSize = zprty.ElementSize;
3758  let hasSideEffects = 0;
3759}
3760
3761multiclass sve2_int_arith_pred<bits<6> opc, string asm, SDPatternOperator op,
3762                               string Ps = "",
3763                               DestructiveInstTypeEnum flags=DestructiveOther,
3764                               string revname="", bit isReverseInstr=0> {
3765  let DestructiveInstType = flags in {
3766  def _B : sve2_int_arith_pred<0b00, opc, asm, ZPR8>,
3767           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3768  def _H : sve2_int_arith_pred<0b01, opc, asm, ZPR16>,
3769           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3770  def _S : sve2_int_arith_pred<0b10, opc, asm, ZPR32>,
3771           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3772  def _D : sve2_int_arith_pred<0b11, opc, asm, ZPR64>,
3773           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3774  }
3775
3776  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3777  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3778  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3779  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3780}
3781
3782class sve2_int_sadd_long_accum_pairwise<bits<2> sz, bit U, string asm,
3783                                        ZPRRegOp zprty1, ZPRRegOp zprty2>
3784: I<(outs zprty1:$Zda), (ins PPR3bAny:$Pg, zprty1:$_Zda, zprty2:$Zn),
3785  asm, "\t$Zda, $Pg/m, $Zn", "", []>, Sched<[]> {
3786  bits<3> Pg;
3787  bits<5> Zn;
3788  bits<5> Zda;
3789  let Inst{31-24} = 0b01000100;
3790  let Inst{23-22} = sz;
3791  let Inst{21-17} = 0b00010;
3792  let Inst{16}    = U;
3793  let Inst{15-13} = 0b101;
3794  let Inst{12-10} = Pg;
3795  let Inst{9-5}   = Zn;
3796  let Inst{4-0}   = Zda;
3797
3798  let Constraints = "$Zda = $_Zda";
3799  let DestructiveInstType = DestructiveOther;
3800  let ElementSize = zprty1.ElementSize;
3801  let hasSideEffects = 0;
3802}
3803
3804multiclass sve2_int_sadd_long_accum_pairwise<bit U, string asm, SDPatternOperator op> {
3805  def _H : sve2_int_sadd_long_accum_pairwise<0b01, U, asm, ZPR16, ZPR8>;
3806  def _S : sve2_int_sadd_long_accum_pairwise<0b10, U, asm, ZPR32, ZPR16>;
3807  def _D : sve2_int_sadd_long_accum_pairwise<0b11, U, asm, ZPR64, ZPR32>;
3808
3809  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv16i8, !cast<Instruction>(NAME # _H)>;
3810  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv8i16, !cast<Instruction>(NAME # _S)>;
3811  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv4i32, !cast<Instruction>(NAME # _D)>;
3812}
3813
3814class sve2_int_un_pred_arit<bits<2> sz, bit Q, bits<2> opc,
3815                            string asm, ZPRRegOp zprty>
3816: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
3817  asm, "\t$Zd, $Pg/m, $Zn",
3818  "",
3819  []>, Sched<[]> {
3820  bits<3> Pg;
3821  bits<5> Zd;
3822  bits<5> Zn;
3823  let Inst{31-24} = 0b01000100;
3824  let Inst{23-22} = sz;
3825  let Inst{21-20} = 0b00;
3826  let Inst{19}    = Q;
3827  let Inst{18}    = 0b0;
3828  let Inst{17-16} = opc;
3829  let Inst{15-13} = 0b101;
3830  let Inst{12-10} = Pg;
3831  let Inst{9-5}   = Zn;
3832  let Inst{4-0}   = Zd;
3833
3834  let Constraints = "$Zd = $_Zd";
3835  let DestructiveInstType = DestructiveUnaryPassthru;
3836  let ElementSize = zprty.ElementSize;
3837  let hasSideEffects = 0;
3838}
3839
3840multiclass sve2_int_un_pred_arit_s<bits<3> opc, string asm,
3841                                   SDPatternOperator op> {
3842  def _S : sve2_int_un_pred_arit<0b10, opc{2}, opc{1-0}, asm, ZPR32>,
3843           SVEPseudo2Instr<NAME # _S, 1>;
3844
3845  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
3846
3847  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
3848
3849  defm : SVE_3_Op_Undef_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
3850}
3851
3852multiclass sve2_int_un_pred_arit<bits<3> opc, string asm, SDPatternOperator op> {
3853  def _B : sve2_int_un_pred_arit<0b00, opc{2}, opc{1-0}, asm, ZPR8>,
3854           SVEPseudo2Instr<NAME # _B, 1>;
3855  def _H : sve2_int_un_pred_arit<0b01, opc{2}, opc{1-0}, asm, ZPR16>,
3856           SVEPseudo2Instr<NAME # _H, 1>;
3857  def _S : sve2_int_un_pred_arit<0b10, opc{2}, opc{1-0}, asm, ZPR32>,
3858           SVEPseudo2Instr<NAME # _S, 1>;
3859  def _D : sve2_int_un_pred_arit<0b11, opc{2}, opc{1-0}, asm, ZPR64>,
3860           SVEPseudo2Instr<NAME # _D, 1>;
3861
3862  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
3863  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
3864  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
3865  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
3866
3867  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
3868  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
3869  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
3870  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
3871
3872  defm : SVE_3_Op_Undef_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
3873  defm : SVE_3_Op_Undef_Pat<nxv8i16, op, nxv8i16, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
3874  defm : SVE_3_Op_Undef_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
3875  defm : SVE_3_Op_Undef_Pat<nxv2i64, op, nxv2i64, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
3876}
3877
3878//===----------------------------------------------------------------------===//
3879// SVE2 Widening Integer Arithmetic Group
3880//===----------------------------------------------------------------------===//
3881
3882class sve2_wide_int_arith<bits<2> sz, bits<5> opc, string asm,
3883                          ZPRRegOp zprty1, ZPRRegOp zprty2, ZPRRegOp zprty3>
3884: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty3:$Zm),
3885  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3886  bits<5> Zd;
3887  bits<5> Zn;
3888  bits<5> Zm;
3889  let Inst{31-24} = 0b01000101;
3890  let Inst{23-22} = sz;
3891  let Inst{21}    = 0b0;
3892  let Inst{20-16} = Zm;
3893  let Inst{15}    = 0b0;
3894  let Inst{14-10} = opc;
3895  let Inst{9-5}   = Zn;
3896  let Inst{4-0}   = Zd;
3897
3898  let hasSideEffects = 0;
3899}
3900
3901multiclass sve2_wide_int_arith_long<bits<5> opc, string asm,
3902                                    SDPatternOperator op> {
3903  def _H : sve2_wide_int_arith<0b01, opc, asm, ZPR16, ZPR8, ZPR8>;
3904  def _S : sve2_wide_int_arith<0b10, opc, asm, ZPR32, ZPR16, ZPR16>;
3905  def _D : sve2_wide_int_arith<0b11, opc, asm, ZPR64, ZPR32, ZPR32>;
3906
3907  def : SVE_2_Op_Pat<nxv8i16, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3908  def : SVE_2_Op_Pat<nxv4i32, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
3909  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3910}
3911
3912multiclass sve2_wide_int_arith_wide<bits<3> opc, string asm,
3913                                    SDPatternOperator op> {
3914  def _H : sve2_wide_int_arith<0b01, { 0b10, opc }, asm, ZPR16, ZPR16, ZPR8>;
3915  def _S : sve2_wide_int_arith<0b10, { 0b10, opc }, asm, ZPR32, ZPR32, ZPR16>;
3916  def _D : sve2_wide_int_arith<0b11, { 0b10, opc }, asm, ZPR64, ZPR64, ZPR32>;
3917
3918  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, !cast<Instruction>(NAME # _H)>;
3919  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, !cast<Instruction>(NAME # _S)>;
3920  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, !cast<Instruction>(NAME # _D)>;
3921}
3922
3923multiclass sve2_wide_int_arith_pmul<bits<2> sz, bits<5> opc, string asm,
3924                                     SDPatternOperator op> {
3925  def NAME : sve2_wide_int_arith<sz, opc, asm, ZPR128, ZPR64, ZPR64>;
3926
3927  // To avoid using 128 bit elements in the IR, the pattern below works with
3928  // llvm intrinsics with the _pair suffix, to reflect that
3929  // _Q is implemented as a pair of _D.
3930  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
3931}
3932
3933multiclass sve2_pmul_long<bits<1> opc, string asm, SDPatternOperator op> {
3934  def _H : sve2_wide_int_arith<0b01, {0b1101, opc}, asm, ZPR16, ZPR8, ZPR8>;
3935  def _D : sve2_wide_int_arith<0b11, {0b1101, opc}, asm, ZPR64, ZPR32, ZPR32>;
3936
3937  // To avoid using 128 bit elements in the IR, the patterns below work with
3938  // llvm intrinsics with the _pair suffix, to reflect that
3939  // _H is implemented as a pair of _B and _D is implemented as a pair of _S.
3940  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3941  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3942}
3943
3944//===----------------------------------------------------------------------===//
3945// SVE2 Misc Group
3946//===----------------------------------------------------------------------===//
3947
3948class sve2_misc<bits<2> sz, bits<4> opc, string asm,
3949                ZPRRegOp zprty1, ZPRRegOp zprty2>
3950: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty2:$Zm),
3951  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3952  bits<5> Zd;
3953  bits<5> Zn;
3954  bits<5> Zm;
3955  let Inst{31-24} = 0b01000101;
3956  let Inst{23-22} = sz;
3957  let Inst{21}    = 0b0;
3958  let Inst{20-16} = Zm;
3959  let Inst{15-14} = 0b10;
3960  let Inst{13-10} = opc;
3961  let Inst{9-5}   = Zn;
3962  let Inst{4-0}   = Zd;
3963
3964  let hasSideEffects = 0;
3965}
3966
3967multiclass sve2_misc_bitwise<bits<4> opc, string asm, SDPatternOperator op> {
3968  def _B : sve2_misc<0b00, opc, asm, ZPR8, ZPR8>;
3969  def _H : sve2_misc<0b01, opc, asm, ZPR16, ZPR16>;
3970  def _S : sve2_misc<0b10, opc, asm, ZPR32, ZPR32>;
3971  def _D : sve2_misc<0b11, opc, asm, ZPR64, ZPR64>;
3972
3973  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3974  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3975  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3976  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3977}
3978
3979multiclass sve2_misc_int_addsub_long_interleaved<bits<2> opc, string asm,
3980                                                 SDPatternOperator op> {
3981  def _H : sve2_misc<0b01, { 0b00, opc }, asm, ZPR16, ZPR8>;
3982  def _S : sve2_misc<0b10, { 0b00, opc }, asm, ZPR32, ZPR16>;
3983  def _D : sve2_misc<0b11, { 0b00, opc }, asm, ZPR64, ZPR32>;
3984
3985  def : SVE_2_Op_Pat<nxv8i16, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3986  def : SVE_2_Op_Pat<nxv4i32, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
3987  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3988}
3989
3990class sve2_bitwise_xor_interleaved<bits<2> sz, bits<1> opc, string asm,
3991                                   ZPRRegOp zprty1, ZPRRegOp zprty2>
3992: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, zprty2:$Zm),
3993  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3994  bits<5> Zd;
3995  bits<5> Zn;
3996  bits<5> Zm;
3997  let Inst{31-24} = 0b01000101;
3998  let Inst{23-22} = sz;
3999  let Inst{21}    = 0b0;
4000  let Inst{20-16} = Zm;
4001  let Inst{15-11} = 0b10010;
4002  let Inst{10}    = opc;
4003  let Inst{9-5}   = Zn;
4004  let Inst{4-0}   = Zd;
4005
4006  let Constraints = "$Zd = $_Zd";
4007  let DestructiveInstType = DestructiveOther;
4008  let ElementSize = ElementSizeNone;
4009  let hasSideEffects = 0;
4010}
4011
4012multiclass sve2_bitwise_xor_interleaved<bit opc, string asm,
4013                                        SDPatternOperator op> {
4014  def _B : sve2_bitwise_xor_interleaved<0b00, opc, asm, ZPR8,  ZPR8>;
4015  def _H : sve2_bitwise_xor_interleaved<0b01, opc, asm, ZPR16, ZPR16>;
4016  def _S : sve2_bitwise_xor_interleaved<0b10, opc, asm, ZPR32, ZPR32>;
4017  def _D : sve2_bitwise_xor_interleaved<0b11, opc, asm, ZPR64, ZPR64>;
4018
4019  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4020  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4021  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4022  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4023}
4024
4025class sve2_bitwise_shift_left_long<bits<3> tsz8_64, bits<2> opc, string asm,
4026                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
4027                                   Operand immtype>
4028: I<(outs zprty1:$Zd), (ins zprty2:$Zn, immtype:$imm),
4029  asm, "\t$Zd, $Zn, $imm",
4030  "", []>, Sched<[]> {
4031  bits<5> Zd;
4032  bits<5> Zn;
4033  bits<5> imm;
4034  let Inst{31-23} = 0b010001010;
4035  let Inst{22}    = tsz8_64{2};
4036  let Inst{21}    = 0b0;
4037  let Inst{20-19} = tsz8_64{1-0};
4038  let Inst{18-16} = imm{2-0}; // imm3
4039  let Inst{15-12} = 0b1010;
4040  let Inst{11-10} = opc;
4041  let Inst{9-5}   = Zn;
4042  let Inst{4-0}   = Zd;
4043
4044  let hasSideEffects = 0;
4045}
4046
4047multiclass sve2_bitwise_shift_left_long<bits<2> opc, string asm,
4048                                        SDPatternOperator op> {
4049  def _H : sve2_bitwise_shift_left_long<{0,0,1}, opc, asm,
4050                                        ZPR16, ZPR8, vecshiftL8>;
4051  def _S : sve2_bitwise_shift_left_long<{0,1,?}, opc, asm,
4052                                        ZPR32, ZPR16, vecshiftL16> {
4053    let Inst{19} = imm{3};
4054  }
4055  def _D : sve2_bitwise_shift_left_long<{1,?,?}, opc, asm,
4056                                        ZPR64, ZPR32, vecshiftL32> {
4057    let Inst{20-19} = imm{4-3};
4058  }
4059  def : SVE_2_Op_Imm_Pat<nxv8i16, op, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _H)>;
4060  def : SVE_2_Op_Imm_Pat<nxv4i32, op, nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _S)>;
4061  def : SVE_2_Op_Imm_Pat<nxv2i64, op, nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _D)>;
4062}
4063
4064//===----------------------------------------------------------------------===//
4065// SVE2 Accumulate Group
4066//===----------------------------------------------------------------------===//
4067
4068class sve2_int_bin_shift_imm<bits<4> tsz8_64, bit opc, string asm,
4069                             ZPRRegOp zprty, Operand immtype>
4070: I<(outs zprty:$Zd), (ins zprty:$_Zd, zprty:$Zn, immtype:$imm),
4071  asm, "\t$Zd, $Zn, $imm",
4072  "", []>, Sched<[]> {
4073  bits<5> Zd;
4074  bits<5> Zn;
4075  bits<6> imm;
4076  let Inst{31-24} = 0b01000101;
4077  let Inst{23-22} = tsz8_64{3-2};
4078  let Inst{21}    = 0b0;
4079  let Inst{20-19} = tsz8_64{1-0};
4080  let Inst{18-16} = imm{2-0}; // imm3
4081  let Inst{15-11} = 0b11110;
4082  let Inst{10}    = opc;
4083  let Inst{9-5}   = Zn;
4084  let Inst{4-0}   = Zd;
4085
4086  let Constraints = "$Zd = $_Zd";
4087  let hasSideEffects = 0;
4088}
4089
4090multiclass sve2_int_bin_shift_imm_left<bit opc, string asm,
4091                                       SDPatternOperator op> {
4092  def _B : sve2_int_bin_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
4093  def _H : sve2_int_bin_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
4094    let Inst{19} = imm{3};
4095  }
4096  def _S : sve2_int_bin_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
4097    let Inst{20-19} = imm{4-3};
4098  }
4099  def _D : sve2_int_bin_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
4100    let Inst{22}    = imm{5};
4101    let Inst{20-19} = imm{4-3};
4102  }
4103
4104  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _B)>;
4105  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _H)>;
4106  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _S)>;
4107  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftL64, !cast<Instruction>(NAME # _D)>;
4108}
4109
4110multiclass sve2_int_bin_shift_imm_right<bit opc, string asm,
4111                                        SDPatternOperator op> {
4112  def _B : sve2_int_bin_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
4113  def _H : sve2_int_bin_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
4114    let Inst{19} = imm{3};
4115  }
4116  def _S : sve2_int_bin_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
4117    let Inst{20-19} = imm{4-3};
4118  }
4119  def _D : sve2_int_bin_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
4120    let Inst{22}    = imm{5};
4121    let Inst{20-19} = imm{4-3};
4122  }
4123
4124  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4125  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4126  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4127  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4128}
4129
4130class sve2_int_bin_accum_shift_imm<bits<4> tsz8_64, bits<2> opc, string asm,
4131                                   ZPRRegOp zprty, Operand immtype>
4132: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, immtype:$imm),
4133  asm, "\t$Zda, $Zn, $imm",
4134  "", []>, Sched<[]> {
4135  bits<5> Zda;
4136  bits<5> Zn;
4137  bits<6> imm;
4138  let Inst{31-24} = 0b01000101;
4139  let Inst{23-22} = tsz8_64{3-2};
4140  let Inst{21}    = 0b0;
4141  let Inst{20-19} = tsz8_64{1-0};
4142  let Inst{18-16} = imm{2-0}; // imm3
4143  let Inst{15-12} = 0b1110;
4144  let Inst{11-10} = opc;
4145  let Inst{9-5}   = Zn;
4146  let Inst{4-0}   = Zda;
4147
4148  let Constraints = "$Zda = $_Zda";
4149  let DestructiveInstType = DestructiveOther;
4150  let ElementSize = ElementSizeNone;
4151  let hasSideEffects = 0;
4152}
4153
4154multiclass sve2_int_bin_accum_shift_imm_right<bits<2> opc, string asm,
4155                                              SDPatternOperator op,
4156                                              SDPatternOperator shift_op = null_frag> {
4157  def _B : sve2_int_bin_accum_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
4158  def _H : sve2_int_bin_accum_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
4159    let Inst{19} = imm{3};
4160  }
4161  def _S : sve2_int_bin_accum_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
4162    let Inst{20-19} = imm{4-3};
4163  }
4164  def _D : sve2_int_bin_accum_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
4165    let Inst{22}    = imm{5};
4166    let Inst{20-19} = imm{4-3};
4167  }
4168
4169  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4170  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4171  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4172  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4173
4174  def : SVE_Shift_Add_All_Active_Pat<nxv16i8, shift_op, nxv16i1, nxv16i8, nxv16i8, i32, !cast<Instruction>(NAME # _B)>;
4175  def : SVE_Shift_Add_All_Active_Pat<nxv8i16, shift_op, nxv8i1, nxv8i16, nxv8i16, i32, !cast<Instruction>(NAME # _H)>;
4176  def : SVE_Shift_Add_All_Active_Pat<nxv4i32, shift_op, nxv4i1, nxv4i32, nxv4i32, i32, !cast<Instruction>(NAME # _S)>;
4177  def : SVE_Shift_Add_All_Active_Pat<nxv2i64, shift_op, nxv2i1, nxv2i64, nxv2i64, i32, !cast<Instruction>(NAME # _D)>;
4178}
4179
4180class sve2_int_cadd<bits<2> sz, bit opc, string asm, ZPRRegOp zprty>
4181: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, complexrotateopodd:$rot),
4182  asm, "\t$Zdn, $_Zdn, $Zm, $rot", "", []>, Sched<[]> {
4183  bits<5> Zdn;
4184  bits<5> Zm;
4185  bit rot;
4186  let Inst{31-24} = 0b01000101;
4187  let Inst{23-22} = sz;
4188  let Inst{21-17} = 0b00000;
4189  let Inst{16}    = opc;
4190  let Inst{15-11} = 0b11011;
4191  let Inst{10}    = rot;
4192  let Inst{9-5}   = Zm;
4193  let Inst{4-0}   = Zdn;
4194
4195  let Constraints = "$Zdn = $_Zdn";
4196  let DestructiveInstType = DestructiveOther;
4197  let ElementSize = ElementSizeNone;
4198  let hasSideEffects = 0;
4199}
4200
4201multiclass sve2_int_cadd<bit opc, string asm, SDPatternOperator op> {
4202  def _B : sve2_int_cadd<0b00, opc, asm, ZPR8>;
4203  def _H : sve2_int_cadd<0b01, opc, asm, ZPR16>;
4204  def _S : sve2_int_cadd<0b10, opc, asm, ZPR32>;
4205  def _D : sve2_int_cadd<0b11, opc, asm, ZPR64>;
4206
4207  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, complexrotateopodd, !cast<Instruction>(NAME # _B)>;
4208  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, complexrotateopodd, !cast<Instruction>(NAME # _H)>;
4209  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, complexrotateopodd, !cast<Instruction>(NAME # _S)>;
4210  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, complexrotateopodd, !cast<Instruction>(NAME # _D)>;
4211}
4212
4213class sve2_int_absdiff_accum<bits<2> sz, bits<4> opc, string asm,
4214                             ZPRRegOp zprty1, ZPRRegOp zprty2>
4215: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm),
4216  asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
4217  bits<5> Zda;
4218  bits<5> Zn;
4219  bits<5> Zm;
4220  let Inst{31-24} = 0b01000101;
4221  let Inst{23-22} = sz;
4222  let Inst{21}    = 0b0;
4223  let Inst{20-16} = Zm;
4224  let Inst{15-14} = 0b11;
4225  let Inst{13-10} = opc;
4226  let Inst{9-5}   = Zn;
4227  let Inst{4-0}   = Zda;
4228
4229  let Constraints = "$Zda = $_Zda";
4230  let DestructiveInstType = DestructiveOther;
4231  let ElementSize = ElementSizeNone;
4232  let hasSideEffects = 0;
4233}
4234
4235multiclass sve2_int_absdiff_accum<bit opc, string asm, SDPatternOperator op> {
4236  def _B : sve2_int_absdiff_accum<0b00, { 0b111, opc }, asm, ZPR8, ZPR8>;
4237  def _H : sve2_int_absdiff_accum<0b01, { 0b111, opc }, asm, ZPR16, ZPR16>;
4238  def _S : sve2_int_absdiff_accum<0b10, { 0b111, opc }, asm, ZPR32, ZPR32>;
4239  def _D : sve2_int_absdiff_accum<0b11, { 0b111, opc }, asm, ZPR64, ZPR64>;
4240
4241  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4242  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4243  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4244  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4245}
4246
4247multiclass sve2_int_absdiff_accum_long<bits<2> opc, string asm,
4248                                       SDPatternOperator op> {
4249  def _H : sve2_int_absdiff_accum<0b01, { 0b00, opc }, asm, ZPR16, ZPR8>;
4250  def _S : sve2_int_absdiff_accum<0b10, { 0b00, opc }, asm, ZPR32, ZPR16>;
4251  def _D : sve2_int_absdiff_accum<0b11, { 0b00, opc }, asm, ZPR64, ZPR32>;
4252
4253  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
4254  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
4255  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
4256}
4257
4258multiclass sve2_int_addsub_long_carry<bits<2> opc, string asm,
4259                                      SDPatternOperator op> {
4260  def _S : sve2_int_absdiff_accum<{ opc{1}, 0b0 }, { 0b010, opc{0} }, asm,
4261                                  ZPR32, ZPR32>;
4262  def _D : sve2_int_absdiff_accum<{ opc{1}, 0b1 }, { 0b010, opc{0} }, asm,
4263                                  ZPR64, ZPR64>;
4264
4265  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4266  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4267}
4268
4269//===----------------------------------------------------------------------===//
4270// SVE2 Narrowing Group
4271//===----------------------------------------------------------------------===//
4272
4273class sve2_int_bin_shift_imm_narrow_bottom<bits<3> tsz8_64, bits<3> opc,
4274                                           string asm, ZPRRegOp zprty1,
4275                                           ZPRRegOp zprty2, Operand immtype>
4276: I<(outs zprty1:$Zd), (ins zprty2:$Zn, immtype:$imm),
4277  asm, "\t$Zd, $Zn, $imm",
4278  "", []>, Sched<[]> {
4279  bits<5> Zd;
4280  bits<5> Zn;
4281  bits<5> imm;
4282  let Inst{31-23} = 0b010001010;
4283  let Inst{22}    = tsz8_64{2};
4284  let Inst{21}    = 0b1;
4285  let Inst{20-19} = tsz8_64{1-0};
4286  let Inst{18-16} = imm{2-0}; // imm3
4287  let Inst{15-14} = 0b00;
4288  let Inst{13-11} = opc;
4289  let Inst{10}    = 0b0;
4290  let Inst{9-5}   = Zn;
4291  let Inst{4-0}   = Zd;
4292
4293  let hasSideEffects = 0;
4294}
4295
4296multiclass sve2_int_bin_shift_imm_right_narrow_bottom<bits<3> opc, string asm,
4297                                                      SDPatternOperator op> {
4298  def _B : sve2_int_bin_shift_imm_narrow_bottom<{0,0,1}, opc, asm, ZPR8, ZPR16,
4299                                                tvecshiftR8>;
4300  def _H : sve2_int_bin_shift_imm_narrow_bottom<{0,1,?}, opc, asm, ZPR16, ZPR32,
4301                                                tvecshiftR16> {
4302    let Inst{19} = imm{3};
4303  }
4304  def _S : sve2_int_bin_shift_imm_narrow_bottom<{1,?,?}, opc, asm, ZPR32, ZPR64,
4305                                                tvecshiftR32> {
4306    let Inst{20-19} = imm{4-3};
4307  }
4308  def : SVE_2_Op_Imm_Pat<nxv16i8, op, nxv8i16, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4309  def : SVE_2_Op_Imm_Pat<nxv8i16, op, nxv4i32, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4310  def : SVE_2_Op_Imm_Pat<nxv4i32, op, nxv2i64, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4311}
4312
4313class sve2_int_bin_shift_imm_narrow_top<bits<3> tsz8_64, bits<3> opc,
4314                                        string asm, ZPRRegOp zprty1,
4315                                        ZPRRegOp zprty2, Operand immtype>
4316: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, immtype:$imm),
4317  asm, "\t$Zd, $Zn, $imm",
4318  "", []>, Sched<[]> {
4319  bits<5> Zd;
4320  bits<5> Zn;
4321  bits<5> imm;
4322  let Inst{31-23} = 0b010001010;
4323  let Inst{22}    = tsz8_64{2};
4324  let Inst{21}    = 0b1;
4325  let Inst{20-19} = tsz8_64{1-0};
4326  let Inst{18-16} = imm{2-0}; // imm3
4327  let Inst{15-14} = 0b00;
4328  let Inst{13-11} = opc;
4329  let Inst{10}    = 0b1;
4330  let Inst{9-5}   = Zn;
4331  let Inst{4-0}   = Zd;
4332
4333  let Constraints = "$Zd = $_Zd";
4334  let hasSideEffects = 0;
4335}
4336
4337multiclass sve2_int_bin_shift_imm_right_narrow_top<bits<3> opc, string asm,
4338                                                   SDPatternOperator op> {
4339  def _B : sve2_int_bin_shift_imm_narrow_top<{0,0,1}, opc, asm, ZPR8, ZPR16,
4340                                             tvecshiftR8>;
4341  def _H : sve2_int_bin_shift_imm_narrow_top<{0,1,?}, opc, asm, ZPR16, ZPR32,
4342                                             tvecshiftR16> {
4343    let Inst{19} = imm{3};
4344  }
4345  def _S : sve2_int_bin_shift_imm_narrow_top<{1,?,?}, opc, asm, ZPR32, ZPR64,
4346                                             tvecshiftR32> {
4347    let Inst{20-19} = imm{4-3};
4348  }
4349  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv8i16, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4350  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv4i32, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4351  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv2i64, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4352}
4353
4354class sve2_int_addsub_narrow_high_bottom<bits<2> sz, bits<2> opc, string asm,
4355                                         ZPRRegOp zprty1, ZPRRegOp zprty2>
4356: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty2:$Zm),
4357  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4358  bits<5> Zd;
4359  bits<5> Zn;
4360  bits<5> Zm;
4361  let Inst{31-24} = 0b01000101;
4362  let Inst{23-22} = sz;
4363  let Inst{21}    = 0b1;
4364  let Inst{20-16} = Zm;
4365  let Inst{15-13} = 0b011;
4366  let Inst{12-11} = opc; // S, R
4367  let Inst{10}    = 0b0; // Top
4368  let Inst{9-5}   = Zn;
4369  let Inst{4-0}   = Zd;
4370
4371  let hasSideEffects = 0;
4372}
4373
4374multiclass sve2_int_addsub_narrow_high_bottom<bits<2> opc, string asm,
4375                                              SDPatternOperator op> {
4376  def _B : sve2_int_addsub_narrow_high_bottom<0b01, opc, asm, ZPR8, ZPR16>;
4377  def _H : sve2_int_addsub_narrow_high_bottom<0b10, opc, asm, ZPR16, ZPR32>;
4378  def _S : sve2_int_addsub_narrow_high_bottom<0b11, opc, asm, ZPR32, ZPR64>;
4379
4380  def : SVE_2_Op_Pat<nxv16i8, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _B)>;
4381  def : SVE_2_Op_Pat<nxv8i16, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _H)>;
4382  def : SVE_2_Op_Pat<nxv4i32, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _S)>;
4383}
4384
4385class sve2_int_addsub_narrow_high_top<bits<2> sz, bits<2> opc, string asm,
4386                                      ZPRRegOp zprty1, ZPRRegOp zprty2>
4387: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, zprty2:$Zm),
4388  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4389  bits<5> Zd;
4390  bits<5> Zn;
4391  bits<5> Zm;
4392  let Inst{31-24} = 0b01000101;
4393  let Inst{23-22} = sz;
4394  let Inst{21}    = 0b1;
4395  let Inst{20-16} = Zm;
4396  let Inst{15-13} = 0b011;
4397  let Inst{12-11} = opc; // S, R
4398  let Inst{10}    = 0b1; // Top
4399  let Inst{9-5}   = Zn;
4400  let Inst{4-0}   = Zd;
4401
4402  let Constraints = "$Zd = $_Zd";
4403  let hasSideEffects = 0;
4404}
4405
4406multiclass sve2_int_addsub_narrow_high_top<bits<2> opc, string asm,
4407                                           SDPatternOperator op> {
4408  def _B : sve2_int_addsub_narrow_high_top<0b01, opc, asm, ZPR8, ZPR16>;
4409  def _H : sve2_int_addsub_narrow_high_top<0b10, opc, asm, ZPR16, ZPR32>;
4410  def _S : sve2_int_addsub_narrow_high_top<0b11, opc, asm, ZPR32, ZPR64>;
4411
4412  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _B)>;
4413  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _H)>;
4414  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _S)>;
4415}
4416
4417class sve2_int_sat_extract_narrow_bottom<bits<3> tsz8_64, bits<2> opc, string asm,
4418                                         ZPRRegOp zprty1, ZPRRegOp zprty2>
4419: I<(outs zprty1:$Zd), (ins zprty2:$Zn),
4420  asm, "\t$Zd, $Zn", "", []>, Sched<[]> {
4421  bits<5> Zd;
4422  bits<5> Zn;
4423  let Inst{31-23} = 0b010001010;
4424  let Inst{22}    = tsz8_64{2};
4425  let Inst{21}    = 0b1;
4426  let Inst{20-19} = tsz8_64{1-0};
4427  let Inst{18-13} = 0b000010;
4428  let Inst{12-11} = opc;
4429  let Inst{10}    = 0b0;
4430  let Inst{9-5}   = Zn;
4431  let Inst{4-0}   = Zd;
4432
4433  let hasSideEffects = 0;
4434}
4435
4436multiclass sve2_int_sat_extract_narrow_bottom<bits<2> opc, string asm,
4437                                              SDPatternOperator op> {
4438  def _B : sve2_int_sat_extract_narrow_bottom<0b001, opc, asm, ZPR8, ZPR16>;
4439  def _H : sve2_int_sat_extract_narrow_bottom<0b010, opc, asm, ZPR16, ZPR32>;
4440  def _S : sve2_int_sat_extract_narrow_bottom<0b100, opc, asm, ZPR32, ZPR64>;
4441
4442  def : SVE_1_Op_Pat<nxv16i8, op, nxv8i16, !cast<Instruction>(NAME # _B)>;
4443  def : SVE_1_Op_Pat<nxv8i16, op, nxv4i32, !cast<Instruction>(NAME # _H)>;
4444  def : SVE_1_Op_Pat<nxv4i32, op, nxv2i64, !cast<Instruction>(NAME # _S)>;
4445}
4446
4447class sve2_int_sat_extract_narrow_top<bits<3> tsz8_64, bits<2> opc, string asm,
4448                                      ZPRRegOp zprty1, ZPRRegOp zprty2>
4449: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn),
4450  asm, "\t$Zd, $Zn", "", []>, Sched<[]> {
4451  bits<5> Zd;
4452  bits<5> Zn;
4453  let Inst{31-23} = 0b010001010;
4454  let Inst{22}    = tsz8_64{2};
4455  let Inst{21}    = 0b1;
4456  let Inst{20-19} = tsz8_64{1-0};
4457  let Inst{18-13} = 0b000010;
4458  let Inst{12-11} = opc;
4459  let Inst{10}    = 0b1;
4460  let Inst{9-5}   = Zn;
4461  let Inst{4-0}   = Zd;
4462
4463  let Constraints = "$Zd = $_Zd";
4464  let hasSideEffects = 0;
4465}
4466
4467multiclass sve2_int_sat_extract_narrow_top<bits<2> opc, string asm,
4468                                           SDPatternOperator op> {
4469  def _B : sve2_int_sat_extract_narrow_top<0b001, opc, asm, ZPR8, ZPR16>;
4470  def _H : sve2_int_sat_extract_narrow_top<0b010, opc, asm, ZPR16, ZPR32>;
4471  def _S : sve2_int_sat_extract_narrow_top<0b100, opc, asm, ZPR32, ZPR64>;
4472
4473  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv8i16, !cast<Instruction>(NAME # _B)>;
4474  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv4i32, !cast<Instruction>(NAME # _H)>;
4475  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
4476}
4477
4478//===----------------------------------------------------------------------===//
4479// SVE Integer Arithmetic - Unary Predicated Group
4480//===----------------------------------------------------------------------===//
4481
4482class sve_int_un_pred_arit<bits<2> sz8_64, bits<4> opc,
4483                             string asm, ZPRRegOp zprty>
4484: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
4485  asm, "\t$Zd, $Pg/m, $Zn",
4486  "",
4487  []>, Sched<[]> {
4488  bits<3> Pg;
4489  bits<5> Zd;
4490  bits<5> Zn;
4491  let Inst{31-24} = 0b00000100;
4492  let Inst{23-22} = sz8_64;
4493  let Inst{21-20} = 0b01;
4494  let Inst{19}    = opc{0};
4495  let Inst{18-16} = opc{3-1};
4496  let Inst{15-13} = 0b101;
4497  let Inst{12-10} = Pg;
4498  let Inst{9-5}   = Zn;
4499  let Inst{4-0}   = Zd;
4500
4501  let Constraints = "$Zd = $_Zd";
4502  let DestructiveInstType = DestructiveUnaryPassthru;
4503  let ElementSize = zprty.ElementSize;
4504  let hasSideEffects = 0;
4505}
4506
4507multiclass sve_int_un_pred_arit_0<bits<3> opc, string asm,
4508                                  SDPatternOperator op> {
4509  def _B : sve_int_un_pred_arit<0b00, { opc, 0b0 }, asm, ZPR8>,
4510           SVEPseudo2Instr<NAME # _B, 1>;
4511  def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>,
4512           SVEPseudo2Instr<NAME # _H, 1>;
4513  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4514           SVEPseudo2Instr<NAME # _S, 1>;
4515  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4516           SVEPseudo2Instr<NAME # _D, 1>;
4517
4518  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
4519  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
4520  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
4521  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
4522
4523  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
4524  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4525  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4526  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4527
4528  defm : SVE_1_Op_PassthruUndef_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
4529  defm : SVE_1_Op_PassthruUndef_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4530  defm : SVE_1_Op_PassthruUndef_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4531  defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4532}
4533
4534multiclass sve_int_un_pred_arit_0_h<bits<3> opc, string asm,
4535                                    SDPatternOperator op> {
4536  def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>,
4537           SVEPseudo2Instr<NAME # _H, 1>;
4538  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4539           SVEPseudo2Instr<NAME # _S, 1>;
4540  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4541           SVEPseudo2Instr<NAME # _D, 1>;
4542
4543  def : SVE_InReg_Extend<nxv8i16, op, nxv8i1, nxv8i8, !cast<Instruction>(NAME # _H)>;
4544  def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i8, !cast<Instruction>(NAME # _S)>;
4545  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i8, !cast<Instruction>(NAME # _D)>;
4546
4547  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4548  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4549  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4550
4551  defm : SVE_InReg_Extend_PassthruUndef<nxv8i16, op, nxv8i1, nxv8i8, !cast<Pseudo>(NAME # _H_UNDEF)>;
4552  defm : SVE_InReg_Extend_PassthruUndef<nxv4i32, op, nxv4i1, nxv4i8, !cast<Pseudo>(NAME # _S_UNDEF)>;
4553  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i8, !cast<Pseudo>(NAME # _D_UNDEF)>;
4554}
4555
4556multiclass sve_int_un_pred_arit_0_w<bits<3> opc, string asm,
4557                                    SDPatternOperator op> {
4558  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4559           SVEPseudo2Instr<NAME # _S, 1>;
4560  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4561           SVEPseudo2Instr<NAME # _D, 1>;
4562
4563  def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i16, !cast<Instruction>(NAME # _S)>;
4564  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i16, !cast<Instruction>(NAME # _D)>;
4565
4566  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4567  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4568
4569  defm : SVE_InReg_Extend_PassthruUndef<nxv4i32, op, nxv4i1, nxv4i16, !cast<Pseudo>(NAME # _S_UNDEF)>;
4570  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i16, !cast<Pseudo>(NAME # _D_UNDEF)>;
4571}
4572
4573multiclass sve_int_un_pred_arit_0_d<bits<3> opc, string asm,
4574                                    SDPatternOperator op> {
4575  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4576           SVEPseudo2Instr<NAME # _D, 1>;
4577
4578  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i32, !cast<Instruction>(NAME # _D)>;
4579
4580  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4581
4582  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i32, !cast<Pseudo>(NAME # _D_UNDEF)>;
4583}
4584
4585multiclass sve_int_un_pred_arit_1<bits<3> opc, string asm,
4586                                  SDPatternOperator op> {
4587  def _B : sve_int_un_pred_arit<0b00, { opc, 0b1 }, asm, ZPR8>,
4588           SVEPseudo2Instr<NAME # _B, 1>;
4589  def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>,
4590           SVEPseudo2Instr<NAME # _H, 1>;
4591  def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>,
4592           SVEPseudo2Instr<NAME # _S, 1>;
4593  def _D : sve_int_un_pred_arit<0b11, { opc, 0b1 }, asm, ZPR64>,
4594           SVEPseudo2Instr<NAME # _D, 1>;
4595
4596  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
4597  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
4598  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
4599  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
4600
4601  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
4602  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4603  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4604  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4605
4606  defm : SVE_1_Op_PassthruUndef_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
4607  defm : SVE_1_Op_PassthruUndef_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4608  defm : SVE_1_Op_PassthruUndef_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4609  defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4610}
4611
4612multiclass sve_int_un_pred_arit_1_fp<bits<3> opc, string asm, SDPatternOperator op> {
4613  def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>,
4614           SVEPseudo2Instr<NAME # _H, 1>;
4615  def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>,
4616           SVEPseudo2Instr<NAME # _S, 1>;
4617  def _D : sve_int_un_pred_arit<0b11, { opc, 0b1 }, asm, ZPR64>,
4618           SVEPseudo2Instr<NAME # _D, 1>;
4619
4620  def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
4621  def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
4622  def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
4623  def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
4624  def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
4625  def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
4626
4627  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4628  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4629  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4630
4631  defm : SVE_1_Op_PassthruUndef_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4632  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4633  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4634  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4635  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4636  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4637}
4638
4639//===----------------------------------------------------------------------===//
4640// SVE Integer Wide Immediate - Unpredicated Group
4641//===----------------------------------------------------------------------===//
4642class sve_int_dup_imm<bits<2> sz8_64, string asm,
4643                      ZPRRegOp zprty, Operand immtype>
4644: I<(outs zprty:$Zd), (ins immtype:$imm),
4645  asm, "\t$Zd, $imm",
4646  "",
4647  []>, Sched<[]> {
4648  bits<5> Zd;
4649  bits<9> imm;
4650  let Inst{31-24} = 0b00100101;
4651  let Inst{23-22} = sz8_64;
4652  let Inst{21-14} = 0b11100011;
4653  let Inst{13}    = imm{8};   // sh
4654  let Inst{12-5}  = imm{7-0}; // imm8
4655  let Inst{4-0}   = Zd;
4656
4657  let hasSideEffects = 0;
4658  let isReMaterializable = 1;
4659}
4660
4661multiclass sve_int_dup_imm<string asm> {
4662  def _B : sve_int_dup_imm<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8>;
4663  def _H : sve_int_dup_imm<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16>;
4664  def _S : sve_int_dup_imm<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32>;
4665  def _D : sve_int_dup_imm<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64>;
4666
4667  def : InstAlias<"mov $Zd, $imm",
4668                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, cpy_imm8_opt_lsl_i8:$imm), 1>;
4669  def : InstAlias<"mov $Zd, $imm",
4670                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, cpy_imm8_opt_lsl_i16:$imm), 1>;
4671  def : InstAlias<"mov $Zd, $imm",
4672                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, cpy_imm8_opt_lsl_i32:$imm), 1>;
4673  def : InstAlias<"mov $Zd, $imm",
4674                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, cpy_imm8_opt_lsl_i64:$imm), 1>;
4675
4676  def : InstAlias<"fmov $Zd, #0.0",
4677                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, 0, 0), 1>;
4678  def : InstAlias<"fmov $Zd, #0.0",
4679                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, 0, 0), 1>;
4680  def : InstAlias<"fmov $Zd, #0.0",
4681                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, 0, 0), 1>;
4682}
4683
4684class sve_int_dup_fpimm<bits<2> sz8_64, Operand fpimmtype,
4685                        string asm, ZPRRegOp zprty>
4686: I<(outs zprty:$Zd), (ins fpimmtype:$imm8),
4687  asm, "\t$Zd, $imm8",
4688  "",
4689  []>, Sched<[]> {
4690  bits<5> Zd;
4691  bits<8> imm8;
4692  let Inst{31-24} = 0b00100101;
4693  let Inst{23-22} = sz8_64;
4694  let Inst{21-14} = 0b11100111;
4695  let Inst{13}    = 0b0;
4696  let Inst{12-5}  = imm8;
4697  let Inst{4-0}   = Zd;
4698
4699  let hasSideEffects = 0;
4700  let isReMaterializable = 1;
4701}
4702
4703multiclass sve_int_dup_fpimm<string asm> {
4704  def _H : sve_int_dup_fpimm<0b01, fpimm16, asm, ZPR16>;
4705  def _S : sve_int_dup_fpimm<0b10, fpimm32, asm, ZPR32>;
4706  def _D : sve_int_dup_fpimm<0b11, fpimm64, asm, ZPR64>;
4707
4708  def : InstAlias<"fmov $Zd, $imm8",
4709                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, fpimm16:$imm8), 1>;
4710  def : InstAlias<"fmov $Zd, $imm8",
4711                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, fpimm32:$imm8), 1>;
4712  def : InstAlias<"fmov $Zd, $imm8",
4713                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, fpimm64:$imm8), 1>;
4714}
4715
4716class sve_int_arith_imm0<bits<2> sz8_64, bits<3> opc, string asm,
4717                         ZPRRegOp zprty, Operand immtype>
4718: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, immtype:$imm),
4719  asm, "\t$Zdn, $_Zdn, $imm",
4720  "",
4721  []>, Sched<[]> {
4722  bits<5> Zdn;
4723  bits<9> imm;
4724  let Inst{31-24} = 0b00100101;
4725  let Inst{23-22} = sz8_64;
4726  let Inst{21-19} = 0b100;
4727  let Inst{18-16} = opc;
4728  let Inst{15-14} = 0b11;
4729  let Inst{13}    = imm{8};   // sh
4730  let Inst{12-5}  = imm{7-0}; // imm8
4731  let Inst{4-0}   = Zdn;
4732
4733  let Constraints = "$Zdn = $_Zdn";
4734  let DestructiveInstType = DestructiveOther;
4735  let ElementSize = ElementSizeNone;
4736  let hasSideEffects = 0;
4737}
4738
4739multiclass sve_int_arith_imm0<bits<3> opc, string asm, SDPatternOperator op> {
4740  def _B : sve_int_arith_imm0<0b00, opc, asm, ZPR8,  addsub_imm8_opt_lsl_i8>;
4741  def _H : sve_int_arith_imm0<0b01, opc, asm, ZPR16, addsub_imm8_opt_lsl_i16>;
4742  def _S : sve_int_arith_imm0<0b10, opc, asm, ZPR32, addsub_imm8_opt_lsl_i32>;
4743  def _D : sve_int_arith_imm0<0b11, opc, asm, ZPR64, addsub_imm8_opt_lsl_i64>;
4744
4745  def : SVE_1_Op_Imm_OptLsl_Pat<nxv16i8, op, ZPR8,  i32, SVEAddSubImm8Pat,  !cast<Instruction>(NAME # _B)>;
4746  def : SVE_1_Op_Imm_OptLsl_Pat<nxv8i16, op, ZPR16, i32, SVEAddSubImm16Pat, !cast<Instruction>(NAME # _H)>;
4747  def : SVE_1_Op_Imm_OptLsl_Pat<nxv4i32, op, ZPR32, i32, SVEAddSubImm32Pat, !cast<Instruction>(NAME # _S)>;
4748  def : SVE_1_Op_Imm_OptLsl_Pat<nxv2i64, op, ZPR64, i64, SVEAddSubImm64Pat, !cast<Instruction>(NAME # _D)>;
4749}
4750
4751class sve_int_arith_imm<bits<2> sz8_64, bits<6> opc, string asm,
4752                        ZPRRegOp zprty, Operand immtype>
4753: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, immtype:$imm),
4754  asm, "\t$Zdn, $_Zdn, $imm",
4755  "",
4756  []>, Sched<[]> {
4757  bits<5> Zdn;
4758  bits<8> imm;
4759  let Inst{31-24} = 0b00100101;
4760  let Inst{23-22} = sz8_64;
4761  let Inst{21-16} = opc;
4762  let Inst{15-13} = 0b110;
4763  let Inst{12-5} = imm;
4764  let Inst{4-0} = Zdn;
4765
4766  let Constraints = "$Zdn = $_Zdn";
4767  let DestructiveInstType = DestructiveOther;
4768  let ElementSize = ElementSizeNone;
4769  let hasSideEffects = 0;
4770}
4771
4772multiclass sve_int_arith_imm1<bits<2> opc, string asm, SDPatternOperator op> {
4773  def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, simm8_32b>;
4774  def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, simm8_32b>;
4775  def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, simm8_32b>;
4776  def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, simm8_32b>;
4777
4778  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B)>;
4779  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1,  op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H)>;
4780  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1,  op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S)>;
4781  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1,  op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D)>;
4782}
4783
4784multiclass sve_int_arith_imm1_unsigned<bits<2> opc, string asm, SDPatternOperator op> {
4785  def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, imm0_255>;
4786  def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, imm0_255>;
4787  def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, imm0_255>;
4788  def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, imm0_255>;
4789
4790  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithUImm8Pat, !cast<Instruction>(NAME # _B)>;
4791  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithUImm16Pat, !cast<Instruction>(NAME # _H)>;
4792  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithUImm32Pat, !cast<Instruction>(NAME # _S)>;
4793  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithUImm64Pat, !cast<Instruction>(NAME # _D)>;
4794}
4795
4796multiclass sve_int_arith_imm2<string asm, SDPatternOperator op> {
4797  def _B : sve_int_arith_imm<0b00, 0b110000, asm, ZPR8,  simm8_32b>;
4798  def _H : sve_int_arith_imm<0b01, 0b110000, asm, ZPR16, simm8_32b>;
4799  def _S : sve_int_arith_imm<0b10, 0b110000, asm, ZPR32, simm8_32b>;
4800  def _D : sve_int_arith_imm<0b11, 0b110000, asm, ZPR64, simm8_32b>;
4801
4802  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B)>;
4803  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H)>;
4804  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S)>;
4805  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D)>;
4806}
4807
4808//===----------------------------------------------------------------------===//
4809// SVE Bitwise Logical - Unpredicated Group
4810//===----------------------------------------------------------------------===//
4811
4812class sve_int_bin_cons_log<bits<2> opc, string asm>
4813: I<(outs ZPR64:$Zd), (ins ZPR64:$Zn, ZPR64:$Zm),
4814  asm, "\t$Zd, $Zn, $Zm",
4815  "",
4816  []>, Sched<[]> {
4817  bits<5> Zd;
4818  bits<5> Zm;
4819  bits<5> Zn;
4820  let Inst{31-24} = 0b00000100;
4821  let Inst{23-22} = opc{1-0};
4822  let Inst{21}    = 0b1;
4823  let Inst{20-16} = Zm;
4824  let Inst{15-10} = 0b001100;
4825  let Inst{9-5}   = Zn;
4826  let Inst{4-0}   = Zd;
4827
4828  let hasSideEffects = 0;
4829}
4830
4831multiclass sve_int_bin_cons_log<bits<2> opc, string asm, SDPatternOperator op> {
4832  def NAME : sve_int_bin_cons_log<opc, asm>;
4833
4834  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
4835  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
4836  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
4837  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4838
4839  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4840                  (!cast<Instruction>(NAME) ZPR8:$Zd,  ZPR8:$Zn,  ZPR8:$Zm),  1>;
4841  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4842                  (!cast<Instruction>(NAME) ZPR16:$Zd, ZPR16:$Zn, ZPR16:$Zm), 1>;
4843  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4844                  (!cast<Instruction>(NAME) ZPR32:$Zd, ZPR32:$Zn, ZPR32:$Zm), 1>;
4845}
4846
4847class sve2_int_bitwise_ternary_op_d<bits<3> opc, string asm>
4848: I<(outs ZPR64:$Zdn), (ins ZPR64:$_Zdn, ZPR64:$Zm, ZPR64:$Zk),
4849  asm, "\t$Zdn, $_Zdn, $Zm, $Zk",
4850  "",
4851  []>, Sched<[]> {
4852  bits<5> Zdn;
4853  bits<5> Zk;
4854  bits<5> Zm;
4855  let Inst{31-24} = 0b00000100;
4856  let Inst{23-22} = opc{2-1};
4857  let Inst{21}    = 0b1;
4858  let Inst{20-16} = Zm;
4859  let Inst{15-11} = 0b00111;
4860  let Inst{10}    = opc{0};
4861  let Inst{9-5}   = Zk;
4862  let Inst{4-0}   = Zdn;
4863
4864  let Constraints = "$Zdn = $_Zdn";
4865  let DestructiveInstType = DestructiveOther;
4866  let ElementSize = ElementSizeNone;
4867  let hasSideEffects = 0;
4868}
4869
4870multiclass sve2_int_bitwise_ternary_op<bits<3> opc, string asm, SDPatternOperator op,
4871                                       SDPatternOperator ir_op = null_frag> {
4872  def NAME : sve2_int_bitwise_ternary_op_d<opc, asm>;
4873
4874  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4875                  (!cast<Instruction>(NAME) ZPR8:$Zdn,  ZPR8:$Zm,  ZPR8:$Zk),  1>;
4876  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4877                  (!cast<Instruction>(NAME) ZPR16:$Zdn, ZPR16:$Zm, ZPR16:$Zk), 1>;
4878  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4879                  (!cast<Instruction>(NAME) ZPR32:$Zdn, ZPR32:$Zm, ZPR32:$Zk), 1>;
4880
4881  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
4882  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
4883  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
4884  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4885
4886
4887  def : SVE_3_Op_BSP_Pat<nxv16i8, ir_op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
4888  def : SVE_3_Op_BSP_Pat<nxv8i16, ir_op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
4889  def : SVE_3_Op_BSP_Pat<nxv4i32, ir_op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
4890  def : SVE_3_Op_BSP_Pat<nxv2i64, ir_op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4891}
4892
4893class sve2_int_rotate_right_imm<bits<4> tsz8_64, string asm,
4894                                ZPRRegOp zprty, Operand immtype>
4895: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, immtype:$imm),
4896  asm, "\t$Zdn, $_Zdn, $Zm, $imm",
4897  "",
4898  []>, Sched<[]> {
4899  bits<5> Zdn;
4900  bits<5> Zm;
4901  bits<6> imm;
4902  let Inst{31-24} = 0b00000100;
4903  let Inst{23-22} = tsz8_64{3-2};
4904  let Inst{21}    = 0b1;
4905  let Inst{20-19} = tsz8_64{1-0};
4906  let Inst{18-16} = imm{2-0}; // imm3
4907  let Inst{15-10} = 0b001101;
4908  let Inst{9-5}   = Zm;
4909  let Inst{4-0}   = Zdn;
4910
4911  let Constraints = "$Zdn = $_Zdn";
4912  let DestructiveInstType = DestructiveOther;
4913  let ElementSize = ElementSizeNone;
4914  let hasSideEffects = 0;
4915}
4916
4917multiclass sve2_int_rotate_right_imm<string asm, SDPatternOperator op> {
4918  def _B : sve2_int_rotate_right_imm<{0,0,0,1}, asm, ZPR8, vecshiftR8>;
4919  def _H : sve2_int_rotate_right_imm<{0,0,1,?}, asm, ZPR16, vecshiftR16> {
4920    let Inst{19} = imm{3};
4921  }
4922  def _S : sve2_int_rotate_right_imm<{0,1,?,?}, asm, ZPR32, vecshiftR32> {
4923    let Inst{20-19} = imm{4-3};
4924  }
4925  def _D : sve2_int_rotate_right_imm<{1,?,?,?}, asm, ZPR64, vecshiftR64> {
4926    let Inst{22}    = imm{5};
4927    let Inst{20-19} = imm{4-3};
4928  }
4929
4930  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4931  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4932  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4933  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4934}
4935
4936//===----------------------------------------------------------------------===//
4937// SVE Integer Wide Immediate - Predicated Group
4938//===----------------------------------------------------------------------===//
4939
4940class sve_int_dup_fpimm_pred<bits<2> sz, Operand fpimmtype,
4941                             string asm, ZPRRegOp zprty>
4942: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPRAny:$Pg, fpimmtype:$imm8),
4943  asm, "\t$Zd, $Pg/m, $imm8",
4944  "",
4945  []>, Sched<[]> {
4946  bits<4> Pg;
4947  bits<5> Zd;
4948  bits<8> imm8;
4949  let Inst{31-24} = 0b00000101;
4950  let Inst{23-22} = sz;
4951  let Inst{21-20} = 0b01;
4952  let Inst{19-16} = Pg;
4953  let Inst{15-13} = 0b110;
4954  let Inst{12-5}  = imm8;
4955  let Inst{4-0}   = Zd;
4956
4957  let Constraints = "$Zd = $_Zd";
4958  let DestructiveInstType = DestructiveOther;
4959  let ElementSize = zprty.ElementSize;
4960  let hasSideEffects = 0;
4961}
4962
4963multiclass sve_int_dup_fpimm_pred<string asm> {
4964  def _H : sve_int_dup_fpimm_pred<0b01, fpimm16, asm, ZPR16>;
4965  def _S : sve_int_dup_fpimm_pred<0b10, fpimm32, asm, ZPR32>;
4966  def _D : sve_int_dup_fpimm_pred<0b11, fpimm64, asm, ZPR64>;
4967
4968  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
4969                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, fpimm16:$imm8), 1>;
4970  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
4971                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, fpimm32:$imm8), 1>;
4972  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
4973                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, fpimm64:$imm8), 1>;
4974}
4975
4976class sve_int_dup_imm_pred<bits<2> sz8_64, bit m, string asm,
4977                           ZPRRegOp zprty, string pred_qual, dag iops>
4978: I<(outs zprty:$Zd), iops,
4979  asm, "\t$Zd, $Pg"#pred_qual#", $imm",
4980  "", []>, Sched<[]> {
4981  bits<5> Zd;
4982  bits<4> Pg;
4983  bits<9> imm;
4984  let Inst{31-24} = 0b00000101;
4985  let Inst{23-22} = sz8_64;
4986  let Inst{21-20} = 0b01;
4987  let Inst{19-16} = Pg;
4988  let Inst{15}    = 0b0;
4989  let Inst{14}    = m;
4990  let Inst{13}    = imm{8};   // sh
4991  let Inst{12-5}  = imm{7-0}; // imm8
4992  let Inst{4-0}   = Zd;
4993
4994  let DestructiveInstType = DestructiveOther;
4995  let ElementSize = zprty.ElementSize;
4996  let hasSideEffects = 0;
4997}
4998
4999multiclass sve_int_dup_imm_pred_merge_inst<
5000    bits<2> sz8_64, string asm, ZPRRegOp zprty, imm8_opt_lsl cpyimm,
5001    ValueType intty, ValueType predty, ValueType scalarty, ComplexPattern cpx> {
5002  let Constraints = "$Zd = $_Zd" in
5003  def NAME : sve_int_dup_imm_pred<sz8_64, 1, asm, zprty,  "/m",
5004                                  (ins zprty:$_Zd, PPRAny:$Pg, cpyimm:$imm)>;
5005  def : InstAlias<"mov $Zd, $Pg/m, $imm",
5006                  (!cast<Instruction>(NAME) zprty:$Zd, PPRAny:$Pg, cpyimm:$imm), 1>;
5007  def : Pat<(vselect predty:$Pg,
5008                (intty (splat_vector (scalarty (cpx i32:$imm, i32:$shift)))),
5009                ZPR:$Zd),
5010            (!cast<Instruction>(NAME) $Zd, $Pg, $imm, $shift)>;
5011}
5012
5013multiclass sve_int_dup_imm_pred_merge<string asm> {
5014  defm _B : sve_int_dup_imm_pred_merge_inst<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8,
5015                                            nxv16i8, nxv16i1, i32, SVECpyDupImm8Pat>;
5016  defm _H : sve_int_dup_imm_pred_merge_inst<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16,
5017                                            nxv8i16, nxv8i1, i32, SVECpyDupImm16Pat>;
5018  defm _S : sve_int_dup_imm_pred_merge_inst<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32,
5019                                            nxv4i32, nxv4i1, i32, SVECpyDupImm32Pat>;
5020  defm _D : sve_int_dup_imm_pred_merge_inst<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64,
5021                                            nxv2i64, nxv2i1, i64, SVECpyDupImm64Pat>;
5022
5023  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5024                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, 0, 0), 0>;
5025  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5026                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, 0, 0), 0>;
5027  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5028                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, 0, 0), 0>;
5029
5030  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv8f16 ZPR:$Zd)),
5031            (!cast<Instruction>(NAME # _H) $Zd, $Pg, 0, 0)>;
5032  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv4f16 ZPR:$Zd)),
5033            (!cast<Instruction>(NAME # _S) $Zd, $Pg, 0, 0)>;
5034  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f16 ZPR:$Zd)),
5035            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5036  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv4f32 ZPR:$Zd)),
5037            (!cast<Instruction>(NAME # _S) $Zd, $Pg, 0, 0)>;
5038  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f32 ZPR:$Zd)),
5039            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5040  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f64 ZPR:$Zd)),
5041            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5042}
5043
5044multiclass sve_int_dup_imm_pred_zero_inst<
5045    bits<2> sz8_64, string asm, ZPRRegOp zprty, imm8_opt_lsl cpyimm,
5046    ValueType intty, ValueType predty, ValueType scalarty, ComplexPattern cpx> {
5047  def NAME : sve_int_dup_imm_pred<sz8_64, 0, asm, zprty, "/z",
5048                                  (ins PPRAny:$Pg, cpyimm:$imm)>;
5049  def : InstAlias<"mov $Zd, $Pg/z, $imm",
5050                  (!cast<Instruction>(NAME) zprty:$Zd, PPRAny:$Pg, cpyimm:$imm), 1>;
5051  def : Pat<(intty (zext (predty PPRAny:$Ps1))),
5052            (!cast<Instruction>(NAME) PPRAny:$Ps1, 1, 0)>;
5053  def : Pat<(intty (sext (predty PPRAny:$Ps1))),
5054            (!cast<Instruction>(NAME) PPRAny:$Ps1, -1, 0)>;
5055  def : Pat<(intty (anyext (predty PPRAny:$Ps1))),
5056            (!cast<Instruction>(NAME) PPRAny:$Ps1, 1, 0)>;
5057  def : Pat<(vselect predty:$Pg,
5058                (intty (splat_vector (scalarty (cpx i32:$imm, i32:$shift)))),
5059                (intty (splat_vector (scalarty 0)))),
5060            (!cast<Instruction>(NAME) $Pg, $imm, $shift)>;
5061}
5062
5063multiclass sve_int_dup_imm_pred_zero<string asm> {
5064  defm _B : sve_int_dup_imm_pred_zero_inst<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8,
5065                                           nxv16i8, nxv16i1, i32, SVECpyDupImm8Pat>;
5066  defm _H : sve_int_dup_imm_pred_zero_inst<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16,
5067                                           nxv8i16, nxv8i1, i32, SVECpyDupImm16Pat>;
5068  defm _S : sve_int_dup_imm_pred_zero_inst<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32,
5069                                           nxv4i32, nxv4i1, i32, SVECpyDupImm32Pat>;
5070  defm _D : sve_int_dup_imm_pred_zero_inst<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64,
5071                                           nxv2i64, nxv2i1, i64, SVECpyDupImm64Pat>;
5072}
5073
5074//===----------------------------------------------------------------------===//
5075// SVE Integer Compare - Vectors Group
5076//===----------------------------------------------------------------------===//
5077
5078class sve_int_cmp<bit cmp_1, bits<2> sz8_64, bits<3> opc, string asm,
5079                  PPRRegOp pprty, ZPRRegOp zprty1, ZPRRegOp zprty2>
5080: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty1:$Zn, zprty2:$Zm),
5081  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
5082  "",
5083  []>, Sched<[]> {
5084  bits<4> Pd;
5085  bits<3> Pg;
5086  bits<5> Zm;
5087  bits<5> Zn;
5088  let Inst{31-24} = 0b00100100;
5089  let Inst{23-22} = sz8_64;
5090  let Inst{21}    = 0b0;
5091  let Inst{20-16} = Zm;
5092  let Inst{15}    = opc{2};
5093  let Inst{14}    = cmp_1;
5094  let Inst{13}    = opc{1};
5095  let Inst{12-10} = Pg;
5096  let Inst{9-5}   = Zn;
5097  let Inst{4}     = opc{0};
5098  let Inst{3-0}   = Pd;
5099
5100  let Defs = [NZCV];
5101  let ElementSize = pprty.ElementSize;
5102  let hasSideEffects = 0;
5103  let isPTestLike = 1;
5104}
5105
5106multiclass SVE_SETCC_Pat<CondCode cc, CondCode invcc, ValueType predvt,
5107                         ValueType intvt, Instruction cmp> {
5108  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, intvt:$Op3, cc)),
5109            (cmp $Op1, $Op2, $Op3)>;
5110  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, intvt:$Op3, invcc)),
5111            (cmp $Op1, $Op3, $Op2)>;
5112  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), intvt:$Op2, intvt:$Op3, cc))),
5113            (cmp $Pg, $Op2, $Op3)>;
5114  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), intvt:$Op2, intvt:$Op3, invcc))),
5115            (cmp $Pg, $Op3, $Op2)>;
5116}
5117
5118multiclass SVE_SETCC_Pat_With_Zero<CondCode cc, CondCode invcc, ValueType predvt,
5119                                   ValueType intvt, Instruction cmp> {
5120  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, (SVEDup0), cc)),
5121            (cmp $Op1, $Op2)>;
5122  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, (SVEDup0), intvt:$Op2, invcc)),
5123            (cmp $Op1, $Op2)>;
5124  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), intvt:$Op1, (SVEDup0), cc))),
5125            (cmp $Pg, $Op1)>;
5126  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), (SVEDup0), intvt:$Op1, invcc))),
5127            (cmp $Pg, $Op1)>;
5128}
5129
5130multiclass sve_int_cmp_0<bits<3> opc, string asm, CondCode cc, CondCode invcc> {
5131  def _B : sve_int_cmp<0b0, 0b00, opc, asm, PPR8, ZPR8, ZPR8>;
5132  def _H : sve_int_cmp<0b0, 0b01, opc, asm, PPR16, ZPR16, ZPR16>;
5133  def _S : sve_int_cmp<0b0, 0b10, opc, asm, PPR32, ZPR32, ZPR32>;
5134  def _D : sve_int_cmp<0b0, 0b11, opc, asm, PPR64, ZPR64, ZPR64>;
5135
5136  defm : SVE_SETCC_Pat<cc, invcc, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
5137  defm : SVE_SETCC_Pat<cc, invcc, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
5138  defm : SVE_SETCC_Pat<cc, invcc, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
5139  defm : SVE_SETCC_Pat<cc, invcc, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
5140}
5141
5142multiclass sve_int_cmp_0_wide<bits<3> opc, string asm, SDPatternOperator op> {
5143  def _B : sve_int_cmp<0b0, 0b00, opc, asm, PPR8, ZPR8, ZPR64>;
5144  def _H : sve_int_cmp<0b0, 0b01, opc, asm, PPR16, ZPR16, ZPR64>;
5145  def _S : sve_int_cmp<0b0, 0b10, opc, asm, PPR32, ZPR32, ZPR64>;
5146
5147  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
5148  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
5149  def : SVE_3_Op_Pat<nxv4i1,  op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
5150}
5151
5152multiclass sve_int_cmp_1_wide<bits<3> opc, string asm, SDPatternOperator op> {
5153  def _B : sve_int_cmp<0b1, 0b00, opc, asm, PPR8, ZPR8, ZPR64>;
5154  def _H : sve_int_cmp<0b1, 0b01, opc, asm, PPR16, ZPR16, ZPR64>;
5155  def _S : sve_int_cmp<0b1, 0b10, opc, asm, PPR32, ZPR32, ZPR64>;
5156
5157  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
5158  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
5159  def : SVE_3_Op_Pat<nxv4i1,  op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
5160}
5161
5162
5163//===----------------------------------------------------------------------===//
5164// SVE Integer Compare - Signed Immediate Group
5165//===----------------------------------------------------------------------===//
5166
5167class sve_int_scmp_vi<bits<2> sz8_64, bits<3> opc, string asm, PPRRegOp pprty,
5168                      ZPRRegOp zprty,
5169                      Operand immtype>
5170: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, immtype:$imm5),
5171  asm, "\t$Pd, $Pg/z, $Zn, $imm5",
5172  "",
5173  []>, Sched<[]> {
5174  bits<4> Pd;
5175  bits<3> Pg;
5176  bits<5> Zn;
5177  bits<5> imm5;
5178  let Inst{31-24} = 0b00100101;
5179  let Inst{23-22} = sz8_64;
5180  let Inst{21}    = 0b0;
5181  let Inst{20-16} = imm5;
5182  let Inst{15}    = opc{2};
5183  let Inst{14}    = 0b0;
5184  let Inst{13}    = opc{1};
5185  let Inst{12-10} = Pg;
5186  let Inst{9-5}   = Zn;
5187  let Inst{4}     = opc{0};
5188  let Inst{3-0}   = Pd;
5189
5190  let Defs = [NZCV];
5191  let ElementSize = pprty.ElementSize;
5192  let hasSideEffects = 0;
5193  let isPTestLike = 1;
5194}
5195
5196multiclass SVE_SETCC_Imm_Pat<CondCode cc, CondCode commuted_cc,
5197                             ValueType predvt, ValueType intvt,
5198                             Operand immtype, Instruction cmp> {
5199  def : Pat<(predvt (AArch64setcc_z (predvt PPR_3b:$Pg),
5200                                    (intvt ZPR:$Zs1),
5201                                    (intvt (splat_vector (immtype:$imm))),
5202                                    cc)),
5203            (cmp $Pg, $Zs1, immtype:$imm)>;
5204  def : Pat<(predvt (AArch64setcc_z (predvt PPR_3b:$Pg),
5205                                    (intvt (splat_vector (immtype:$imm))),
5206                                    (intvt ZPR:$Zs1),
5207                                    commuted_cc)),
5208            (cmp $Pg, $Zs1, immtype:$imm)>;
5209  def : Pat<(predvt (and predvt:$Pg,
5210                         (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)),
5211                                         (intvt ZPR:$Zs1),
5212                                         (intvt (splat_vector (immtype:$imm))),
5213                                         cc))),
5214            (cmp $Pg, $Zs1, immtype:$imm)>;
5215  def : Pat<(predvt (and predvt:$Pg,
5216                         (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)),
5217                                         (intvt (splat_vector (immtype:$imm))),
5218                                         (intvt ZPR:$Zs1),
5219                                         commuted_cc))),
5220            (cmp $Pg, $Zs1, immtype:$imm)>;
5221}
5222
5223multiclass sve_int_scmp_vi<bits<3> opc, string asm, CondCode cc, CondCode commuted_cc> {
5224  def _B : sve_int_scmp_vi<0b00, opc, asm, PPR8, ZPR8, simm5_32b>;
5225  def _H : sve_int_scmp_vi<0b01, opc, asm, PPR16, ZPR16, simm5_32b>;
5226  def _S : sve_int_scmp_vi<0b10, opc, asm, PPR32, ZPR32, simm5_32b>;
5227  def _D : sve_int_scmp_vi<0b11, opc, asm, PPR64, ZPR64, simm5_64b>;
5228
5229  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv16i1, nxv16i8, simm5_32b,
5230                           !cast<Instruction>(NAME # _B)>;
5231  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv8i1,  nxv8i16, simm5_32b,
5232                           !cast<Instruction>(NAME # _H)>;
5233  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv4i1,  nxv4i32, simm5_32b,
5234                           !cast<Instruction>(NAME # _S)>;
5235  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv2i1,  nxv2i64, simm5_64b,
5236                           !cast<Instruction>(NAME # _D)>;
5237}
5238
5239
5240//===----------------------------------------------------------------------===//
5241// SVE Integer Compare - Unsigned Immediate Group
5242//===----------------------------------------------------------------------===//
5243
5244class sve_int_ucmp_vi<bits<2> sz8_64, bits<2> opc, string asm, PPRRegOp pprty,
5245                      ZPRRegOp zprty, Operand immtype>
5246: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, immtype:$imm7),
5247  asm, "\t$Pd, $Pg/z, $Zn, $imm7",
5248  "",
5249  []>, Sched<[]> {
5250  bits<4> Pd;
5251  bits<3> Pg;
5252  bits<5> Zn;
5253  bits<7> imm7;
5254  let Inst{31-24} = 0b00100100;
5255  let Inst{23-22} = sz8_64;
5256  let Inst{21}    = 1;
5257  let Inst{20-14} = imm7;
5258  let Inst{13}    = opc{1};
5259  let Inst{12-10} = Pg;
5260  let Inst{9-5}   = Zn;
5261  let Inst{4}     = opc{0};
5262  let Inst{3-0}   = Pd;
5263
5264  let Defs = [NZCV];
5265  let ElementSize = pprty.ElementSize;
5266  let hasSideEffects = 0;
5267  let isPTestLike = 1;
5268}
5269
5270multiclass sve_int_ucmp_vi<bits<2> opc, string asm, CondCode cc,
5271                           CondCode commuted_cc> {
5272  def _B : sve_int_ucmp_vi<0b00, opc, asm, PPR8, ZPR8, imm0_127>;
5273  def _H : sve_int_ucmp_vi<0b01, opc, asm, PPR16, ZPR16, imm0_127>;
5274  def _S : sve_int_ucmp_vi<0b10, opc, asm, PPR32, ZPR32, imm0_127>;
5275  def _D : sve_int_ucmp_vi<0b11, opc, asm, PPR64, ZPR64, imm0_127_64b>;
5276
5277  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv16i1, nxv16i8, imm0_127,
5278                           !cast<Instruction>(NAME # _B)>;
5279  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv8i1,  nxv8i16, imm0_127,
5280                           !cast<Instruction>(NAME # _H)>;
5281  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv4i1,  nxv4i32, imm0_127,
5282                           !cast<Instruction>(NAME # _S)>;
5283  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv2i1,  nxv2i64, imm0_127_64b,
5284                           !cast<Instruction>(NAME # _D)>;
5285}
5286
5287
5288//===----------------------------------------------------------------------===//
5289// SVE Integer Compare - Scalars Group
5290//===----------------------------------------------------------------------===//
5291
5292class sve_int_cterm<bit sz, bit opc, string asm, RegisterClass rt>
5293: I<(outs), (ins rt:$Rn, rt:$Rm),
5294  asm, "\t$Rn, $Rm",
5295  "",
5296  []>, Sched<[]> {
5297  bits<5> Rm;
5298  bits<5> Rn;
5299  let Inst{31-23} = 0b001001011;
5300  let Inst{22}    = sz;
5301  let Inst{21}    = 0b1;
5302  let Inst{20-16} = Rm;
5303  let Inst{15-10} = 0b001000;
5304  let Inst{9-5}   = Rn;
5305  let Inst{4}     = opc;
5306  let Inst{3-0}   = 0b0000;
5307
5308  let Defs = [NZCV];
5309  let hasSideEffects = 0;
5310}
5311
5312class sve_int_while_rr<bits<2> sz8_64, bits<4> opc, string asm,
5313                       RegisterClass gprty, PPRRegOp pprty>
5314: I<(outs pprty:$Pd), (ins gprty:$Rn, gprty:$Rm),
5315  asm, "\t$Pd, $Rn, $Rm",
5316  "", []>, Sched<[]> {
5317  bits<4> Pd;
5318  bits<5> Rm;
5319  bits<5> Rn;
5320  let Inst{31-24} = 0b00100101;
5321  let Inst{23-22} = sz8_64;
5322  let Inst{21}    = 0b1;
5323  let Inst{20-16} = Rm;
5324  let Inst{15-13} = 0b000;
5325  let Inst{12-10} = opc{3-1};
5326  let Inst{9-5}   = Rn;
5327  let Inst{4}     = opc{0};
5328  let Inst{3-0}   = Pd;
5329
5330  let Defs = [NZCV];
5331  let ElementSize = pprty.ElementSize;
5332  let hasSideEffects = 0;
5333  let isWhile = 1;
5334}
5335
5336multiclass sve_int_while4_rr<bits<3> opc, string asm, SDPatternOperator op> {
5337  def _B : sve_int_while_rr<0b00, { 0, opc }, asm, GPR32, PPR8>;
5338  def _H : sve_int_while_rr<0b01, { 0, opc }, asm, GPR32, PPR16>;
5339  def _S : sve_int_while_rr<0b10, { 0, opc }, asm, GPR32, PPR32>;
5340  def _D : sve_int_while_rr<0b11, { 0, opc }, asm, GPR32, PPR64>;
5341
5342  def : SVE_2_Op_Pat<nxv16i1, op, i32, i32, !cast<Instruction>(NAME # _B)>;
5343  def : SVE_2_Op_Pat<nxv8i1,  op, i32, i32, !cast<Instruction>(NAME # _H)>;
5344  def : SVE_2_Op_Pat<nxv4i1,  op, i32, i32, !cast<Instruction>(NAME # _S)>;
5345  def : SVE_2_Op_Pat<nxv2i1,  op, i32, i32, !cast<Instruction>(NAME # _D)>;
5346}
5347
5348multiclass sve_int_while8_rr<bits<3> opc, string asm, SDPatternOperator op> {
5349  def _B : sve_int_while_rr<0b00, { 1, opc }, asm, GPR64, PPR8>;
5350  def _H : sve_int_while_rr<0b01, { 1, opc }, asm, GPR64, PPR16>;
5351  def _S : sve_int_while_rr<0b10, { 1, opc }, asm, GPR64, PPR32>;
5352  def _D : sve_int_while_rr<0b11, { 1, opc }, asm, GPR64, PPR64>;
5353
5354  def : SVE_2_Op_Pat<nxv16i1, op, i64, i64, !cast<Instruction>(NAME # _B)>;
5355  def : SVE_2_Op_Pat<nxv8i1,  op, i64, i64, !cast<Instruction>(NAME # _H)>;
5356  def : SVE_2_Op_Pat<nxv4i1,  op, i64, i64, !cast<Instruction>(NAME # _S)>;
5357  def : SVE_2_Op_Pat<nxv2i1,  op, i64, i64, !cast<Instruction>(NAME # _D)>;
5358}
5359
5360class sve2_int_while_rr<bits<2> sz8_64, bits<1> rw, string asm,
5361                        PPRRegOp pprty>
5362: I<(outs pprty:$Pd), (ins GPR64:$Rn, GPR64:$Rm),
5363  asm, "\t$Pd, $Rn, $Rm",
5364  "", []>, Sched<[]> {
5365  bits<4> Pd;
5366  bits<5> Rm;
5367  bits<5> Rn;
5368  let Inst{31-24} = 0b00100101;
5369  let Inst{23-22} = sz8_64;
5370  let Inst{21}    = 0b1;
5371  let Inst{20-16} = Rm;
5372  let Inst{15-10} = 0b001100;
5373  let Inst{9-5}   = Rn;
5374  let Inst{4}     = rw;
5375  let Inst{3-0}   = Pd;
5376
5377  let Defs = [NZCV];
5378  let ElementSize = pprty.ElementSize;
5379  let hasSideEffects = 0;
5380  let isWhile = 1;
5381}
5382
5383multiclass sve2_int_while_rr<bits<1> rw, string asm, string op> {
5384  def _B : sve2_int_while_rr<0b00, rw, asm, PPR8>;
5385  def _H : sve2_int_while_rr<0b01, rw, asm, PPR16>;
5386  def _S : sve2_int_while_rr<0b10, rw, asm, PPR32>;
5387  def _D : sve2_int_while_rr<0b11, rw, asm, PPR64>;
5388
5389  def : SVE_2_Op_Pat<nxv16i1, !cast<SDPatternOperator>(op # _b), i64, i64, !cast<Instruction>(NAME # _B)>;
5390  def : SVE_2_Op_Pat<nxv8i1,  !cast<SDPatternOperator>(op # _h), i64, i64, !cast<Instruction>(NAME # _H)>;
5391  def : SVE_2_Op_Pat<nxv4i1,  !cast<SDPatternOperator>(op # _s), i64, i64, !cast<Instruction>(NAME # _S)>;
5392  def : SVE_2_Op_Pat<nxv2i1,  !cast<SDPatternOperator>(op # _d), i64, i64, !cast<Instruction>(NAME # _D)>;
5393}
5394
5395//===----------------------------------------------------------------------===//
5396// SVE Floating Point Fast Reduction Group
5397//===----------------------------------------------------------------------===//
5398
5399class sve_fp_fast_red<bits<2> sz, bits<3> opc, string asm,
5400                      ZPRRegOp zprty, FPRasZPROperand dstOpType>
5401: I<(outs dstOpType:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
5402  asm, "\t$Vd, $Pg, $Zn",
5403  "",
5404  []>, Sched<[]> {
5405  bits<5> Zn;
5406  bits<5> Vd;
5407  bits<3> Pg;
5408  let Inst{31-24} = 0b01100101;
5409  let Inst{23-22} = sz;
5410  let Inst{21-19} = 0b000;
5411  let Inst{18-16} = opc;
5412  let Inst{15-13} = 0b001;
5413  let Inst{12-10} = Pg;
5414  let Inst{9-5}   = Zn;
5415  let Inst{4-0}   = Vd;
5416
5417  let hasSideEffects = 0;
5418  let mayRaiseFPException = 1;
5419}
5420
5421multiclass sve_fp_fast_red<bits<3> opc, string asm, SDPatternOperator op> {
5422  def _H : sve_fp_fast_red<0b01, opc, asm, ZPR16, FPR16asZPR>;
5423  def _S : sve_fp_fast_red<0b10, opc, asm, ZPR32, FPR32asZPR>;
5424  def _D : sve_fp_fast_red<0b11, opc, asm, ZPR64, FPR64asZPR>;
5425
5426  def : SVE_2_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
5427  def : SVE_2_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
5428  def : SVE_2_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
5429  def : SVE_2_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
5430  def : SVE_2_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
5431  def : SVE_2_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
5432}
5433
5434//===----------------------------------------------------------------------===//
5435// SVE Floating Point Accumulating Reduction Group
5436//===----------------------------------------------------------------------===//
5437
5438class sve_fp_2op_p_vd<bits<2> sz, bits<3> opc, string asm,
5439                      ZPRRegOp zprty, FPRasZPROperand dstOpType>
5440: I<(outs dstOpType:$Vdn), (ins PPR3bAny:$Pg, dstOpType:$_Vdn, zprty:$Zm),
5441  asm, "\t$Vdn, $Pg, $_Vdn, $Zm",
5442  "",
5443  []>,
5444  Sched<[]> {
5445  bits<3> Pg;
5446  bits<5> Vdn;
5447  bits<5> Zm;
5448  let Inst{31-24} = 0b01100101;
5449  let Inst{23-22} = sz;
5450  let Inst{21-19} = 0b011;
5451  let Inst{18-16} = opc;
5452  let Inst{15-13} = 0b001;
5453  let Inst{12-10} = Pg;
5454  let Inst{9-5}   = Zm;
5455  let Inst{4-0}   = Vdn;
5456
5457  let Constraints = "$Vdn = $_Vdn";
5458  let hasSideEffects = 0;
5459  let mayRaiseFPException = 1;
5460}
5461
5462multiclass sve_fp_2op_p_vd<bits<3> opc, string asm, SDPatternOperator op> {
5463  def _H : sve_fp_2op_p_vd<0b01, opc, asm, ZPR16, FPR16asZPR>;
5464  def _S : sve_fp_2op_p_vd<0b10, opc, asm, ZPR32, FPR32asZPR>;
5465  def _D : sve_fp_2op_p_vd<0b11, opc, asm, ZPR64, FPR64asZPR>;
5466
5467  def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H)>;
5468  def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H)>;
5469  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
5470  def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S)>;
5471  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
5472  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
5473}
5474
5475//===----------------------------------------------------------------------===//
5476// SVE Floating Point Compare - Vectors Group
5477//===----------------------------------------------------------------------===//
5478
5479class sve_fp_3op_p_pd<bits<2> sz, bits<3> opc, string asm, PPRRegOp pprty,
5480                      ZPRRegOp zprty>
5481: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
5482  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
5483  "",
5484  []>, Sched<[]> {
5485  bits<4> Pd;
5486  bits<3> Pg;
5487  bits<5> Zm;
5488  bits<5> Zn;
5489  let Inst{31-24} = 0b01100101;
5490  let Inst{23-22} = sz;
5491  let Inst{21}    = 0b0;
5492  let Inst{20-16} = Zm;
5493  let Inst{15}    = opc{2};
5494  let Inst{14}    = 0b1;
5495  let Inst{13}    = opc{1};
5496  let Inst{12-10} = Pg;
5497  let Inst{9-5}   = Zn;
5498  let Inst{4}     = opc{0};
5499  let Inst{3-0}   = Pd;
5500
5501  let hasSideEffects = 0;
5502  let mayRaiseFPException = 1;
5503}
5504
5505multiclass sve_fp_3op_p_pd<bits<3> opc, string asm, SDPatternOperator op> {
5506  def _H : sve_fp_3op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5507  def _S : sve_fp_3op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5508  def _D : sve_fp_3op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5509
5510  def : SVE_3_Op_Pat<nxv8i1, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
5511  def : SVE_3_Op_Pat<nxv4i1, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
5512  def : SVE_3_Op_Pat<nxv2i1, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
5513}
5514
5515multiclass sve_fp_3op_p_pd_cc<bits<3> opc, string asm,
5516                              CondCode cc1, CondCode cc2,
5517                              CondCode invcc1, CondCode invcc2> {
5518  def _H : sve_fp_3op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5519  def _S : sve_fp_3op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5520  def _D : sve_fp_3op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5521
5522  defm : SVE_SETCC_Pat<cc1, invcc1, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5523  defm : SVE_SETCC_Pat<cc1, invcc1, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5524  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5525  defm : SVE_SETCC_Pat<cc1, invcc1, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5526  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5527  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5528
5529  defm : SVE_SETCC_Pat<cc2, invcc2, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5530  defm : SVE_SETCC_Pat<cc2, invcc2, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5531  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5532  defm : SVE_SETCC_Pat<cc2, invcc2, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5533  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5534  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5535}
5536
5537//===----------------------------------------------------------------------===//
5538// SVE Floating Point Compare - with Zero Group
5539//===----------------------------------------------------------------------===//
5540
5541class sve_fp_2op_p_pd<bits<2> sz, bits<3> opc, string asm, PPRRegOp pprty,
5542                      ZPRRegOp zprty>
5543: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn),
5544  asm, "\t$Pd, $Pg/z, $Zn, #0.0",
5545  "",
5546  []>, Sched<[]> {
5547  bits<4> Pd;
5548  bits<3> Pg;
5549  bits<5> Zn;
5550  let Inst{31-24} = 0b01100101;
5551  let Inst{23-22} = sz;
5552  let Inst{21-18} = 0b0100;
5553  let Inst{17-16} = opc{2-1};
5554  let Inst{15-13} = 0b001;
5555  let Inst{12-10} = Pg;
5556  let Inst{9-5}   = Zn;
5557  let Inst{4}     = opc{0};
5558  let Inst{3-0}   = Pd;
5559
5560  let hasSideEffects = 0;
5561  let mayRaiseFPException = 1;
5562}
5563
5564multiclass sve_fp_2op_p_pd<bits<3> opc, string asm,
5565                           CondCode cc1, CondCode cc2,
5566                           CondCode invcc1, CondCode invcc2> {
5567  def _H : sve_fp_2op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5568  def _S : sve_fp_2op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5569  def _D : sve_fp_2op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5570
5571  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5572  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5573  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5574  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5575  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5576  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5577
5578  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5579  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5580  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5581  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5582  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5583  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5584}
5585
5586
5587//===----------------------------------------------------------------------===//
5588//SVE Index Generation Group
5589//===----------------------------------------------------------------------===//
5590
5591def simm5_8b_tgt : TImmLeaf<i8, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]>;
5592def simm5_16b_tgt : TImmLeaf<i16, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]>;
5593def simm5_32b_tgt : TImmLeaf<i32, [{ return (int32_t)Imm >= -16 && (int32_t)Imm < 16; }]>;
5594def simm5_64b_tgt : TImmLeaf<i64, [{ return (int64_t)Imm >= -16 && (int64_t)Imm < 16; }]>;
5595def i64imm_32bit_tgt : TImmLeaf<i64, [{
5596  return (Imm & 0xffffffffULL) == static_cast<uint64_t>(Imm);
5597}]>;
5598
5599class sve_int_index_ii<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5600                       Operand imm_ty>
5601: I<(outs zprty:$Zd), (ins imm_ty:$imm5, imm_ty:$imm5b),
5602  asm, "\t$Zd, $imm5, $imm5b",
5603  "", []>, Sched<[]> {
5604  bits<5> Zd;
5605  bits<5> imm5;
5606  bits<5> imm5b;
5607  let Inst{31-24} = 0b00000100;
5608  let Inst{23-22} = sz8_64;
5609  let Inst{21}    = 0b1;
5610  let Inst{20-16} = imm5b;
5611  let Inst{15-10} = 0b010000;
5612  let Inst{9-5}   = imm5;
5613  let Inst{4-0}   = Zd;
5614
5615  let hasSideEffects = 0;
5616  let isReMaterializable = 1;
5617}
5618
5619multiclass sve_int_index_ii<string asm> {
5620  def _B : sve_int_index_ii<0b00, asm, ZPR8, simm5_8b>;
5621  def _H : sve_int_index_ii<0b01, asm, ZPR16, simm5_16b>;
5622  def _S : sve_int_index_ii<0b10, asm, ZPR32, simm5_32b>;
5623  def _D : sve_int_index_ii<0b11, asm, ZPR64, simm5_64b>;
5624
5625  def : Pat<(nxv16i8 (step_vector simm5_8b_tgt:$imm5b)),
5626            (!cast<Instruction>(NAME # "_B") (i32 0), (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5627  def : Pat<(nxv8i16 (step_vector simm5_16b_tgt:$imm5b)),
5628            (!cast<Instruction>(NAME # "_H") (i32 0), (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5629  def : Pat<(nxv4i32 (step_vector simm5_32b_tgt:$imm5b)),
5630            (!cast<Instruction>(NAME # "_S") (i32 0), simm5_32b:$imm5b)>;
5631  def : Pat<(nxv2i64 (step_vector simm5_64b_tgt:$imm5b)),
5632            (!cast<Instruction>(NAME # "_D") (i64 0), simm5_64b:$imm5b)>;
5633
5634  // add(step_vector(step), dup(X)) -> index(X, step).
5635  def : Pat<(add (nxv16i8 (step_vector_oneuse simm5_8b_tgt:$imm5b)), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
5636            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5637  def : Pat<(add (nxv8i16 (step_vector_oneuse simm5_16b_tgt:$imm5b)), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
5638            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5639  def : Pat<(add (nxv4i32 (step_vector_oneuse simm5_32b_tgt:$imm5b)), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
5640            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, simm5_32b:$imm5b)>;
5641  def : Pat<(add (nxv2i64 (step_vector_oneuse simm5_64b_tgt:$imm5b)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5642            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, simm5_64b:$imm5b)>;
5643}
5644
5645class sve_int_index_ir<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5646                       RegisterClass srcRegType, Operand imm_ty>
5647: I<(outs zprty:$Zd), (ins imm_ty:$imm5, srcRegType:$Rm),
5648  asm, "\t$Zd, $imm5, $Rm",
5649  "", []>, Sched<[]> {
5650  bits<5> Rm;
5651  bits<5> Zd;
5652  bits<5> imm5;
5653  let Inst{31-24} = 0b00000100;
5654  let Inst{23-22} = sz8_64;
5655  let Inst{21}    = 0b1;
5656  let Inst{20-16} = Rm;
5657  let Inst{15-10} = 0b010010;
5658  let Inst{9-5}   = imm5;
5659  let Inst{4-0}   = Zd;
5660
5661  let hasSideEffects = 0;
5662}
5663
5664multiclass sve_int_index_ir<string asm, SDPatternOperator mulop, SDPatternOperator muloneuseop> {
5665  def _B : sve_int_index_ir<0b00, asm, ZPR8, GPR32, simm5_8b>;
5666  def _H : sve_int_index_ir<0b01, asm, ZPR16, GPR32, simm5_16b>;
5667  def _S : sve_int_index_ir<0b10, asm, ZPR32, GPR32, simm5_32b>;
5668  def _D : sve_int_index_ir<0b11, asm, ZPR64, GPR64, simm5_64b>;
5669
5670  def : Pat<(nxv16i8 (step_vector i8:$imm)),
5671            (!cast<Instruction>(NAME # "_B") (i32 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5672  def : Pat<(nxv8i16 (step_vector i16:$imm)),
5673            (!cast<Instruction>(NAME # "_H") (i32 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5674  def : Pat<(nxv4i32 (step_vector i32:$imm)),
5675            (!cast<Instruction>(NAME # "_S") (i32 0), (!cast<Instruction>("MOVi32imm") $imm))>;
5676  def : Pat<(nxv2i64 (step_vector i64:$imm)),
5677            (!cast<Instruction>(NAME # "_D") (i64 0), (!cast<Instruction>("MOVi64imm") $imm))>;
5678  def : Pat<(nxv2i64 (step_vector i64imm_32bit_tgt:$imm)),
5679            (!cast<Instruction>(NAME # "_D") (i64 0), (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5680
5681  // add(step_vector(step), dup(X)) -> index(X, step).
5682  def : Pat<(add (nxv16i8 (step_vector_oneuse i8:$imm)), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
5683            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5684  def : Pat<(add (nxv8i16 (step_vector_oneuse i16:$imm)), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
5685            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5686  def : Pat<(add (nxv4i32 (step_vector_oneuse i32:$imm)), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
5687            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, (!cast<Instruction>("MOVi32imm") $imm))>;
5688  def : Pat<(add (nxv2i64 (step_vector_oneuse i64:$imm)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5689            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, (!cast<Instruction>("MOVi64imm") $imm))>;
5690  def : Pat<(add (nxv2i64 (step_vector_oneuse i64imm_32bit_tgt:$imm)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5691            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5692
5693  // mul(step_vector(1), dup(Y)) -> index(0, Y).
5694  def : Pat<(mulop (nxv16i1 (AArch64ptrue 31)), (nxv16i8 (step_vector_oneuse (i8 1))), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))),
5695            (!cast<Instruction>(NAME # "_B") (i32 0), GPR32:$Rm)>;
5696  def : Pat<(mulop (nxv8i1 (AArch64ptrue 31)), (nxv8i16 (step_vector_oneuse (i16 1))), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),
5697            (!cast<Instruction>(NAME # "_H") (i32 0), GPR32:$Rm)>;
5698  def : Pat<(mulop (nxv4i1 (AArch64ptrue 31)), (nxv4i32 (step_vector_oneuse (i32 1))), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),
5699            (!cast<Instruction>(NAME # "_S") (i32 0), GPR32:$Rm)>;
5700  def : Pat<(mulop (nxv2i1 (AArch64ptrue 31)), (nxv2i64 (step_vector_oneuse (i64 1))), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),
5701            (!cast<Instruction>(NAME # "_D") (i64 0), GPR64:$Rm)>;
5702
5703  // add(mul(step_vector(1), dup(Y)), dup(X)) -> index(X, Y).
5704  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)))),
5705            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, GPR32:$Rm)>;
5706  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)))),
5707            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, GPR32:$Rm)>;
5708  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)))),
5709            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, GPR32:$Rm)>;
5710  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)))),
5711            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, GPR64:$Rm)>;
5712}
5713
5714class sve_int_index_ri<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5715                       RegisterClass srcRegType, Operand imm_ty>
5716: I<(outs zprty:$Zd), (ins srcRegType:$Rn, imm_ty:$imm5),
5717  asm, "\t$Zd, $Rn, $imm5",
5718  "", []>, Sched<[]> {
5719  bits<5> Rn;
5720  bits<5> Zd;
5721  bits<5> imm5;
5722  let Inst{31-24} = 0b00000100;
5723  let Inst{23-22} = sz8_64;
5724  let Inst{21}    = 0b1;
5725  let Inst{20-16} = imm5;
5726  let Inst{15-10} = 0b010001;
5727  let Inst{9-5}   = Rn;
5728  let Inst{4-0}   = Zd;
5729
5730  let hasSideEffects = 0;
5731}
5732
5733multiclass sve_int_index_ri<string asm> {
5734  def _B : sve_int_index_ri<0b00, asm, ZPR8, GPR32, simm5_8b>;
5735  def _H : sve_int_index_ri<0b01, asm, ZPR16, GPR32, simm5_16b>;
5736  def _S : sve_int_index_ri<0b10, asm, ZPR32, GPR32, simm5_32b>;
5737  def _D : sve_int_index_ri<0b11, asm, ZPR64, GPR64, simm5_64b>;
5738
5739  // add(step_vector(step), dup(X)) -> index(X, step).
5740  def : Pat<(add (nxv16i8 (step_vector_oneuse simm5_8b_tgt:$imm5)), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))),
5741            (!cast<Instruction>(NAME # "_B") GPR32:$Rm, (!cast<SDNodeXForm>("trunc_imm") $imm5))>;
5742  def : Pat<(add (nxv8i16 (step_vector_oneuse simm5_16b_tgt:$imm5)), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),
5743            (!cast<Instruction>(NAME # "_H") GPR32:$Rm, (!cast<SDNodeXForm>("trunc_imm") $imm5))>;
5744  def : Pat<(add (nxv4i32 (step_vector_oneuse simm5_32b_tgt:$imm5)), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),
5745            (!cast<Instruction>(NAME # "_S") GPR32:$Rm, simm5_32b:$imm5)>;
5746  def : Pat<(add (nxv2i64 (step_vector_oneuse simm5_64b_tgt:$imm5)), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),
5747            (!cast<Instruction>(NAME # "_D") GPR64:$Rm, simm5_64b:$imm5)>;
5748}
5749
5750class sve_int_index_rr<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5751                       RegisterClass srcRegType>
5752: I<(outs zprty:$Zd), (ins srcRegType:$Rn, srcRegType:$Rm),
5753  asm, "\t$Zd, $Rn, $Rm",
5754  "", []>, Sched<[]> {
5755  bits<5> Zd;
5756  bits<5> Rm;
5757  bits<5> Rn;
5758  let Inst{31-24} = 0b00000100;
5759  let Inst{23-22} = sz8_64;
5760  let Inst{21}    = 0b1;
5761  let Inst{20-16} = Rm;
5762  let Inst{15-10} = 0b010011;
5763  let Inst{9-5}   = Rn;
5764  let Inst{4-0}   = Zd;
5765
5766  let hasSideEffects = 0;
5767}
5768
5769multiclass sve_int_index_rr<string asm, SDPatternOperator mulop> {
5770  def _B : sve_int_index_rr<0b00, asm, ZPR8, GPR32>;
5771  def _H : sve_int_index_rr<0b01, asm, ZPR16, GPR32>;
5772  def _S : sve_int_index_rr<0b10, asm, ZPR32, GPR32>;
5773  def _D : sve_int_index_rr<0b11, asm, ZPR64, GPR64>;
5774
5775  // add(step_vector(step), dup(X)) -> index(X, step).
5776  def : Pat<(add (nxv16i8 (step_vector_oneuse i8:$imm)), (nxv16i8 (splat_vector(i32 GPR32:$Rn)))),
5777            (!cast<Instruction>(NAME # "_B") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5778  def : Pat<(add (nxv8i16 (step_vector_oneuse i16:$imm)), (nxv8i16 (splat_vector(i32 GPR32:$Rn)))),
5779            (!cast<Instruction>(NAME # "_H") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5780  def : Pat<(add (nxv4i32 (step_vector_oneuse i32:$imm)), (nxv4i32 (splat_vector(i32 GPR32:$Rn)))),
5781            (!cast<Instruction>(NAME # "_S") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") $imm))>;
5782  def : Pat<(add (nxv2i64 (step_vector_oneuse i64:$imm)), (nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
5783            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, (!cast<Instruction>("MOVi64imm") $imm))>;
5784  def : Pat<(add (nxv2i64 (step_vector_oneuse i64imm_32bit_tgt:$imm)), (nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
5785            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5786
5787  // add(mul(step_vector(1), dup(Y)), dup(X)) -> index(X, Y).
5788  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)))),
5789            (!cast<Instruction>(NAME # "_B") GPR32:$Rn, GPR32:$Rm)>;
5790  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)))),
5791            (!cast<Instruction>(NAME # "_H") GPR32:$Rn, GPR32:$Rm)>;
5792  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)))),
5793            (!cast<Instruction>(NAME # "_S") GPR32:$Rn, GPR32:$Rm)>;
5794  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)))),
5795            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, GPR64:$Rm)>;
5796}
5797
5798//===----------------------------------------------------------------------===//
5799// SVE Bitwise Shift - Predicated Group
5800//===----------------------------------------------------------------------===//
5801
5802class sve_int_bin_pred_shift_imm<bits<4> tsz8_64, bits<4> opc, string asm,
5803                                 ZPRRegOp zprty, Operand immtype>
5804: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, immtype:$imm),
5805  asm, "\t$Zdn, $Pg/m, $_Zdn, $imm",
5806  "",
5807  []>, Sched<[]> {
5808  bits<3> Pg;
5809  bits<5> Zdn;
5810  bits<6> imm;
5811  let Inst{31-24} = 0b00000100;
5812  let Inst{23-22} = tsz8_64{3-2};
5813  let Inst{21-20} = 0b00;
5814  let Inst{19-16} = opc;
5815  let Inst{15-13} = 0b100;
5816  let Inst{12-10} = Pg;
5817  let Inst{9-8}   = tsz8_64{1-0};
5818  let Inst{7-5}   = imm{2-0}; // imm3
5819  let Inst{4-0}   = Zdn;
5820
5821  let Constraints = "$Zdn = $_Zdn";
5822  let DestructiveInstType = DestructiveBinaryImm;
5823  let ElementSize = zprty.ElementSize;
5824  let hasSideEffects = 0;
5825}
5826
5827multiclass sve_int_bin_pred_shift_imm_left<bits<4> opc, string asm, string Ps,
5828                                           SDPatternOperator op = null_frag> {
5829  def _B : SVEPseudo2Instr<Ps # _B, 1>,
5830           sve_int_bin_pred_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
5831  def _H : SVEPseudo2Instr<Ps # _H, 1>,
5832           sve_int_bin_pred_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
5833    let Inst{8} = imm{3};
5834  }
5835  def _S : SVEPseudo2Instr<Ps # _S, 1>,
5836           sve_int_bin_pred_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
5837    let Inst{9-8} = imm{4-3};
5838  }
5839  def _D : SVEPseudo2Instr<Ps # _D, 1>,
5840           sve_int_bin_pred_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
5841    let Inst{22}  = imm{5};
5842    let Inst{9-8} = imm{4-3};
5843  }
5844
5845  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i1, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _B)>;
5846  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i1,  nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _H)>;
5847  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i1,  nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _S)>;
5848  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i1,  nxv2i64, i32, tvecshiftL64, !cast<Instruction>(NAME # _D)>;
5849}
5850
5851// As above but shift amount takes the form of a "vector immediate".
5852multiclass sve_int_bin_pred_shift_imm_left_dup<bits<4> opc, string asm,
5853                                               string Ps, SDPatternOperator op>
5854: sve_int_bin_pred_shift_imm_left<opc, asm, Ps, null_frag> {
5855  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8,  !cast<Instruction>(NAME # _B)>;
5856  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
5857  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
5858  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
5859}
5860
5861multiclass sve_int_bin_pred_shift_imm_left_zeroing_bhsd<SDPatternOperator op> {
5862  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8,  tvecshiftL8,  FalseLanesZero>;
5863  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, tvecshiftL16, FalseLanesZero>;
5864  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, tvecshiftL32, FalseLanesZero>;
5865  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, tvecshiftL64, FalseLanesZero>;
5866
5867  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv16i8, op, nxv16i1, nxv16i8, tvecshiftL8,  !cast<Pseudo>(NAME # _B_ZERO)>;
5868  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv8i16, op, nxv8i1,  nxv8i16, tvecshiftL16, !cast<Pseudo>(NAME # _H_ZERO)>;
5869  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv4i32, op, nxv4i1,  nxv4i32, tvecshiftL32, !cast<Pseudo>(NAME # _S_ZERO)>;
5870  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv2i64, op, nxv2i1,  nxv2i64, tvecshiftL64, !cast<Pseudo>(NAME # _D_ZERO)>;
5871}
5872
5873multiclass sve_int_bin_pred_shift_imm_right<bits<4> opc, string asm, string Ps,
5874                                            SDPatternOperator op = null_frag> {
5875  def _B : SVEPseudo2Instr<Ps # _B, 1>,
5876           sve_int_bin_pred_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
5877  def _H : SVEPseudo2Instr<Ps # _H, 1>,
5878           sve_int_bin_pred_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
5879    let Inst{8} = imm{3};
5880  }
5881  def _S : SVEPseudo2Instr<Ps # _S, 1>,
5882           sve_int_bin_pred_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
5883    let Inst{9-8} = imm{4-3};
5884  }
5885  def _D : SVEPseudo2Instr<Ps # _D, 1>,
5886           sve_int_bin_pred_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
5887    let Inst{22}  = imm{5};
5888    let Inst{9-8} = imm{4-3};
5889  }
5890
5891  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i1, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
5892  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i1,  nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
5893  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i1,  nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
5894  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i1,  nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
5895}
5896
5897// As above but shift amount takes the form of a "vector immediate".
5898multiclass sve_int_bin_pred_shift_imm_right_dup<bits<4> opc, string asm,
5899                                            string Ps, SDPatternOperator op>
5900: sve_int_bin_pred_shift_imm_right<opc, asm, Ps, null_frag> {
5901  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8,  !cast<Instruction>(NAME # _B)>;
5902  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
5903  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
5904  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
5905}
5906
5907multiclass sve_int_bin_pred_shift_imm_right_zeroing_bhsd<SDPatternOperator op = null_frag> {
5908  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8, vecshiftR8, FalseLanesZero>;
5909  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, vecshiftR16, FalseLanesZero>;
5910  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, vecshiftR32, FalseLanesZero>;
5911  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, vecshiftR64, FalseLanesZero>;
5912
5913  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv16i8, op, nxv16i1, nxv16i8, tvecshiftR8, !cast<Pseudo>(NAME # _B_ZERO)>;
5914  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv8i16, op, nxv8i1, nxv8i16, tvecshiftR16, !cast<Pseudo>(NAME # _H_ZERO)>;
5915  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv4i32, op, nxv4i1, nxv4i32, tvecshiftR32, !cast<Pseudo>(NAME # _S_ZERO)>;
5916  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv2i64, op, nxv2i1, nxv2i64, tvecshiftR64, !cast<Pseudo>(NAME # _D_ZERO)>;
5917}
5918
5919class sve_int_bin_pred_shift<bits<2> sz8_64, bit wide, bits<3> opc,
5920                             string asm, ZPRRegOp zprty, ZPRRegOp zprty2>
5921: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty2:$Zm),
5922  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
5923  "",
5924  []>, Sched<[]> {
5925  bits<3> Pg;
5926  bits<5> Zdn;
5927  bits<5> Zm;
5928  let Inst{31-24} = 0b00000100;
5929  let Inst{23-22} = sz8_64;
5930  let Inst{21-20} = 0b01;
5931  let Inst{19}    = wide;
5932  let Inst{18-16} = opc;
5933  let Inst{15-13} = 0b100;
5934  let Inst{12-10} = Pg;
5935  let Inst{9-5}   = Zm;
5936  let Inst{4-0}   = Zdn;
5937
5938  let Constraints = "$Zdn = $_Zdn";
5939  let DestructiveInstType = DestructiveOther;
5940  let ElementSize = zprty.ElementSize;
5941  let hasSideEffects = 0;
5942}
5943
5944multiclass sve_int_bin_pred_shift<bits<3> opc, string asm, string Ps,
5945                                  SDPatternOperator op, string revname, bit isReverseInstr = 0> {
5946  let DestructiveInstType = DestructiveBinaryCommWithRev in {
5947  def _B : sve_int_bin_pred_shift<0b00, 0b0, opc, asm, ZPR8, ZPR8>,
5948           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
5949  def _H : sve_int_bin_pred_shift<0b01, 0b0, opc, asm, ZPR16, ZPR16>,
5950           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
5951  def _S : sve_int_bin_pred_shift<0b10, 0b0, opc, asm, ZPR32, ZPR32>,
5952           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
5953  def _D : sve_int_bin_pred_shift<0b11, 0b0, opc, asm, ZPR64, ZPR64>,
5954           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
5955  }
5956  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
5957  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
5958  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
5959  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
5960}
5961
5962multiclass sve_int_bin_pred_zeroing_bhsd<SDPatternOperator op> {
5963  def _B_ZERO : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesZero>;
5964  def _H_ZERO : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesZero>;
5965  def _S_ZERO : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesZero>;
5966  def _D_ZERO : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesZero>;
5967
5968  def : SVE_3_Op_Pat_SelZero<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_ZERO)>;
5969  def : SVE_3_Op_Pat_SelZero<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_ZERO)>;
5970  def : SVE_3_Op_Pat_SelZero<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_ZERO)>;
5971  def : SVE_3_Op_Pat_SelZero<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_ZERO)>;
5972}
5973
5974multiclass sve_int_bin_pred_imm_zeroing_bhsd<SDPatternOperator op,
5975                                   ComplexPattern imm_b, ComplexPattern imm_h,
5976                                   ComplexPattern imm_s, ComplexPattern imm_d> {
5977  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8,  Operand<i32>, FalseLanesZero>;
5978  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, Operand<i32>, FalseLanesZero>;
5979  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, Operand<i32>, FalseLanesZero>;
5980  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, Operand<i32>, FalseLanesZero>;
5981
5982  def : SVE_2_Op_Imm_Pat_Zero<nxv16i8, op, nxv16i1, i32, imm_b, !cast<Pseudo>(NAME # _B_ZERO)>;
5983  def : SVE_2_Op_Imm_Pat_Zero<nxv8i16, op, nxv8i1,  i32, imm_h, !cast<Pseudo>(NAME # _H_ZERO)>;
5984  def : SVE_2_Op_Imm_Pat_Zero<nxv4i32, op, nxv4i1,  i32, imm_s, !cast<Pseudo>(NAME # _S_ZERO)>;
5985  def : SVE_2_Op_Imm_Pat_Zero<nxv2i64, op, nxv2i1,  i64, imm_d, !cast<Pseudo>(NAME # _D_ZERO)>;
5986}
5987
5988multiclass sve_int_bin_pred_shift_wide<bits<3> opc, string asm,
5989                                  SDPatternOperator op> {
5990  def _B : sve_int_bin_pred_shift<0b00, 0b1, opc, asm, ZPR8, ZPR64>;
5991  def _H : sve_int_bin_pred_shift<0b01, 0b1, opc, asm, ZPR16, ZPR64>;
5992  def _S : sve_int_bin_pred_shift<0b10, 0b1, opc, asm, ZPR32, ZPR64>;
5993
5994  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
5995  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
5996  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
5997}
5998
5999//===----------------------------------------------------------------------===//
6000// SVE Shift - Unpredicated Group
6001//===----------------------------------------------------------------------===//
6002
6003class sve_int_bin_cons_shift_wide<bits<2> sz8_64, bits<2> opc, string asm,
6004                               ZPRRegOp zprty>
6005: I<(outs zprty:$Zd), (ins zprty:$Zn, ZPR64:$Zm),
6006  asm, "\t$Zd, $Zn, $Zm",
6007  "",
6008  []>, Sched<[]> {
6009  bits<5> Zd;
6010  bits<5> Zm;
6011  bits<5> Zn;
6012  let Inst{31-24} = 0b00000100;
6013  let Inst{23-22} = sz8_64;
6014  let Inst{21}    = 0b1;
6015  let Inst{20-16} = Zm;
6016  let Inst{15-12} = 0b1000;
6017  let Inst{11-10} = opc;
6018  let Inst{9-5}   = Zn;
6019  let Inst{4-0}   = Zd;
6020
6021  let hasSideEffects = 0;
6022}
6023
6024multiclass sve_int_bin_cons_shift_wide<bits<2> opc, string asm, SDPatternOperator op> {
6025  def _B : sve_int_bin_cons_shift_wide<0b00, opc, asm, ZPR8>;
6026  def _H : sve_int_bin_cons_shift_wide<0b01, opc, asm, ZPR16>;
6027  def _S : sve_int_bin_cons_shift_wide<0b10, opc, asm, ZPR32>;
6028
6029  def : SVE_2_Op_Pred_All_Active<nxv16i8, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
6030  def : SVE_2_Op_Pred_All_Active<nxv8i16, op, nxv8i1, nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
6031  def : SVE_2_Op_Pred_All_Active<nxv4i32, op, nxv4i1, nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
6032}
6033
6034class sve_int_bin_cons_shift_imm<bits<4> tsz8_64, bits<2> opc, string asm,
6035                               ZPRRegOp zprty, Operand immtype>
6036: I<(outs zprty:$Zd), (ins zprty:$Zn, immtype:$imm),
6037  asm, "\t$Zd, $Zn, $imm",
6038  "",
6039  []>, Sched<[]> {
6040  bits<5> Zd;
6041  bits<5> Zn;
6042  bits<6> imm;
6043  let Inst{31-24} = 0b00000100;
6044  let Inst{23-22} = tsz8_64{3-2};
6045  let Inst{21}    = 0b1;
6046  let Inst{20-19} = tsz8_64{1-0};
6047  let Inst{18-16} = imm{2-0}; // imm3
6048  let Inst{15-12} = 0b1001;
6049  let Inst{11-10} = opc;
6050  let Inst{9-5}   = Zn;
6051  let Inst{4-0}   = Zd;
6052
6053  let hasSideEffects = 0;
6054}
6055
6056multiclass sve_int_bin_cons_shift_imm_left<bits<2> opc, string asm,
6057                                           SDPatternOperator op> {
6058  def _B : sve_int_bin_cons_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
6059  def _H : sve_int_bin_cons_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
6060    let Inst{19} = imm{3};
6061  }
6062  def _S : sve_int_bin_cons_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
6063    let Inst{20-19} = imm{4-3};
6064  }
6065  def _D : sve_int_bin_cons_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
6066    let Inst{22}    = imm{5};
6067    let Inst{20-19} = imm{4-3};
6068  }
6069
6070  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8,  !cast<Instruction>(NAME # _B)>;
6071  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
6072  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
6073  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
6074}
6075
6076multiclass sve_int_bin_cons_shift_imm_right<bits<2> opc, string asm,
6077                                            SDPatternOperator op> {
6078  def _B : sve_int_bin_cons_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
6079  def _H : sve_int_bin_cons_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
6080    let Inst{19} = imm{3};
6081  }
6082  def _S : sve_int_bin_cons_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
6083    let Inst{20-19} = imm{4-3};
6084  }
6085  def _D : sve_int_bin_cons_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
6086    let Inst{22}    = imm{5};
6087    let Inst{20-19} = imm{4-3};
6088  }
6089
6090  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8,  !cast<Instruction>(NAME # _B)>;
6091  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
6092  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
6093  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
6094}
6095
6096//===----------------------------------------------------------------------===//
6097// SVE Memory - Store Group
6098//===----------------------------------------------------------------------===//
6099
6100class sve_mem_cst_si<bits<2> msz, bits<2> esz, string asm,
6101                     RegisterOperand VecList>
6102: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
6103  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6104  "",
6105  []>, Sched<[]> {
6106  bits<3> Pg;
6107  bits<5> Rn;
6108  bits<5> Zt;
6109  bits<4> imm4;
6110  let Inst{31-25} = 0b1110010;
6111  let Inst{24-23} = msz;
6112  let Inst{22-21} = esz;
6113  let Inst{20}    = 0;
6114  let Inst{19-16} = imm4;
6115  let Inst{15-13} = 0b111;
6116  let Inst{12-10} = Pg;
6117  let Inst{9-5}   = Rn;
6118  let Inst{4-0}   = Zt;
6119
6120  let hasSideEffects = 0;
6121  let mayStore = 1;
6122}
6123
6124multiclass sve_mem_cst_si<bits<2> msz, bits<2> esz, string asm,
6125                          RegisterOperand listty, ZPRRegOp zprty>
6126{
6127  def NAME : sve_mem_cst_si<msz, esz, asm, listty>;
6128
6129  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6130                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
6131  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6132                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
6133  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6134                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6135}
6136
6137class sve_mem_est_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6138                     string asm, Operand immtype>
6139: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
6140  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6141  "",
6142  []>, Sched<[]> {
6143  bits<3> Pg;
6144  bits<5> Rn;
6145  bits<5> Zt;
6146  bits<4> imm4;
6147  let Inst{31-25} = 0b1110010;
6148  let Inst{24-23} = sz;
6149  let Inst{22-21} = nregs;
6150  let Inst{20}    = 1;
6151  let Inst{19-16} = imm4;
6152  let Inst{15-13} = 0b111;
6153  let Inst{12-10} = Pg;
6154  let Inst{9-5}   = Rn;
6155  let Inst{4-0}   = Zt;
6156
6157  let hasSideEffects = 0;
6158  let mayStore = 1;
6159}
6160
6161multiclass sve_mem_est_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6162                          string asm, Operand immtype> {
6163  def NAME : sve_mem_est_si<sz, nregs, VecList, asm, immtype>;
6164
6165  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6166                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6167}
6168
6169
6170// SVE store multiple structures (quadwords, scalar plus immediate)
6171class sve_mem_128b_est_si<bits<2> nregs, RegisterOperand VecList,
6172                          string asm, Operand immtype>
6173    : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
6174        asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6175        "", []>, Sched<[]> {
6176  bits<5> Zt;
6177  bits<5> Rn;
6178  bits<3> Pg;
6179  bits<4> imm4;
6180  let Inst{31-24} = 0b11100100;
6181  let Inst{23-22} = nregs;
6182  let Inst{21-20} = 0b00;
6183  let Inst{19-16} = imm4;
6184  let Inst{15-13} = 0b000;
6185  let Inst{12-10} = Pg;
6186  let Inst{9-5}   = Rn;
6187  let Inst{4-0}   = Zt;
6188
6189  let hasSideEffects = 0;
6190  let mayStore = 1;
6191}
6192
6193multiclass sve_mem_128b_est_si<bits<2> nregs, RegisterOperand VecList,
6194                               string asm, Operand immtype> {
6195  def NAME : sve_mem_128b_est_si<nregs, VecList, asm, immtype>;
6196
6197  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6198                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6199}
6200
6201
6202class sve_mem_est_ss<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6203                     string asm, RegisterOperand gprty>
6204: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6205  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6206  "",
6207  []>, Sched<[]> {
6208  bits<3> Pg;
6209  bits<5> Rm;
6210  bits<5> Rn;
6211  bits<5> Zt;
6212  let Inst{31-25} = 0b1110010;
6213  let Inst{24-23} = sz;
6214  let Inst{22-21} = nregs;
6215  let Inst{20-16} = Rm;
6216  let Inst{15-13} = 0b011;
6217  let Inst{12-10} = Pg;
6218  let Inst{9-5}   = Rn;
6219  let Inst{4-0}   = Zt;
6220
6221  let hasSideEffects = 0;
6222  let mayStore = 1;
6223}
6224
6225
6226// SVE store multiple structures (quadwords, scalar plus scalar)
6227class sve_mem_128b_est_ss<bits<2> nregs, RegisterOperand VecList,
6228                          string asm, RegisterOperand gprty>
6229    : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6230        asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6231        "", []>, Sched<[]> {
6232  bits<5> Zt;
6233  bits<5> Rn;
6234  bits<3> Pg;
6235  bits<5> Rm;
6236  let Inst{31-24} = 0b11100100;
6237  let Inst{23-22} = nregs;
6238  let Inst{21}    = 0b1;
6239  let Inst{20-16} = Rm;
6240  let Inst{15-13} = 0b000;
6241  let Inst{12-10} = Pg;
6242  let Inst{9-5}   = Rn;
6243  let Inst{4-0}   = Zt;
6244
6245  let hasSideEffects = 0;
6246  let mayStore = 1;
6247}
6248
6249
6250class sve_mem_cst_ss_base<bits<4> dtype, string asm,
6251                          RegisterOperand listty, RegisterOperand gprty>
6252: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6253  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6254  "",
6255  []>, Sched<[]> {
6256  bits<3> Pg;
6257  bits<5> Rm;
6258  bits<5> Rn;
6259  bits<5> Zt;
6260  let Inst{31-25} = 0b1110010;
6261  let Inst{24-21} = dtype;
6262  let Inst{20-16} = Rm;
6263  let Inst{15-13} = 0b010;
6264  let Inst{12-10} = Pg;
6265  let Inst{9-5}   = Rn;
6266  let Inst{4-0}   = Zt;
6267
6268  let hasSideEffects = 0;
6269  let mayStore = 1;
6270}
6271
6272multiclass sve_mem_cst_ss<bits<4> dtype, string asm,
6273                          RegisterOperand listty, ZPRRegOp zprty,
6274                          RegisterOperand gprty> {
6275  def NAME : sve_mem_cst_ss_base<dtype, asm, listty, gprty>;
6276
6277  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Rm]",
6278                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
6279}
6280
6281class sve_mem_cstnt_si<bits<2> msz, string asm, RegisterOperand VecList>
6282: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
6283  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6284  "",
6285  []>, Sched<[]> {
6286  bits<3> Pg;
6287  bits<5> Rn;
6288  bits<5> Zt;
6289  bits<4> imm4;
6290  let Inst{31-25} = 0b1110010;
6291  let Inst{24-23} = msz;
6292  let Inst{22-20} = 0b001;
6293  let Inst{19-16} = imm4;
6294  let Inst{15-13} = 0b111;
6295  let Inst{12-10} = Pg;
6296  let Inst{9-5}   = Rn;
6297  let Inst{4-0}   = Zt;
6298
6299  let hasSideEffects = 0;
6300  let mayStore = 1;
6301}
6302
6303multiclass sve_mem_cstnt_si<bits<2> msz, string asm, RegisterOperand listty,
6304                            ZPRRegOp zprty> {
6305  def NAME : sve_mem_cstnt_si<msz, asm, listty>;
6306
6307  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6308                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
6309  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6310                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
6311  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6312                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6313}
6314
6315class sve_mem_cstnt_ss_base<bits<2> msz, string asm, RegisterOperand listty,
6316                            RegisterOperand gprty>
6317: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6318  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6319  "",
6320  []>, Sched<[]> {
6321  bits<3> Pg;
6322  bits<5> Rm;
6323  bits<5> Rn;
6324  bits<5> Zt;
6325  let Inst{31-25} = 0b1110010;
6326  let Inst{24-23} = msz;
6327  let Inst{22-21} = 0b00;
6328  let Inst{20-16} = Rm;
6329  let Inst{15-13} = 0b011;
6330  let Inst{12-10} = Pg;
6331  let Inst{9-5}   = Rn;
6332  let Inst{4-0}   = Zt;
6333
6334  let hasSideEffects = 0;
6335  let mayStore = 1;
6336}
6337
6338multiclass sve_mem_cstnt_ss<bits<2> msz, string asm, RegisterOperand listty,
6339                            ZPRRegOp zprty, RegisterOperand gprty> {
6340  def NAME : sve_mem_cstnt_ss_base<msz, asm, listty, gprty>;
6341
6342  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Rm]",
6343                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
6344}
6345
6346class sve2_mem_sstnt_vs_base<bits<3> opc, string asm,
6347                             RegisterOperand listty, ZPRRegOp zprty>
6348: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, zprty:$Zn, GPR64:$Rm),
6349  asm, "\t$Zt, $Pg, [$Zn, $Rm]",
6350  "",
6351  []>, Sched<[]> {
6352  bits<3> Pg;
6353  bits<5> Rm;
6354  bits<5> Zn;
6355  bits<5> Zt;
6356  let Inst{31-25} = 0b1110010;
6357  let Inst{24-22} = opc;
6358  let Inst{21}    = 0b0;
6359  let Inst{20-16} = Rm;
6360  let Inst{15-13} = 0b001;
6361  let Inst{12-10} = Pg;
6362  let Inst{9-5}   = Zn;
6363  let Inst{4-0}   = Zt;
6364
6365  let hasSideEffects = 0;
6366  let mayStore = 1;
6367}
6368
6369multiclass sve2_mem_sstnt_vs_32_ptrs<bits<3> opc, string asm,
6370                             SDPatternOperator op,
6371                             ValueType vt> {
6372  def _REAL : sve2_mem_sstnt_vs_base<opc, asm, Z_s, ZPR32>;
6373
6374  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $Rm]",
6375                 (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm), 0>;
6376  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6377                 (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 0>;
6378  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6379                 (!cast<Instruction>(NAME # _REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 1>;
6380
6381  def : Pat <(op (nxv4i32 ZPR32:$Zt), (nxv4i1 PPR3bAny:$Pg), (nxv4i32 ZPR32:$Zn), (i64 GPR64:$Rm), vt),
6382             (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm)>;
6383}
6384
6385multiclass sve2_mem_sstnt_vs_64_ptrs<bits<3> opc, string asm,
6386                             SDPatternOperator op,
6387                             ValueType vt> {
6388  def _REAL : sve2_mem_sstnt_vs_base<opc, asm, Z_d, ZPR64>;
6389
6390  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $Rm]",
6391                 (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm), 0>;
6392  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6393                 (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 0>;
6394  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6395                 (!cast<Instruction>(NAME # _REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
6396
6397  def : Pat <(op (nxv2i64 ZPR64:$Zt), (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64:$Rm), vt),
6398             (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
6399}
6400
6401class sve_mem_sst_sv<bits<3> opc, bit xs, bit scaled, string asm,
6402                     RegisterOperand VecList, RegisterOperand zprext>
6403: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
6404  asm, "\t$Zt, $Pg, [$Rn, $Zm]",
6405  "",
6406  []>, Sched<[]> {
6407  bits<3> Pg;
6408  bits<5> Rn;
6409  bits<5> Zm;
6410  bits<5> Zt;
6411  let Inst{31-25} = 0b1110010;
6412  let Inst{24-22} = opc;
6413  let Inst{21}    = scaled;
6414  let Inst{20-16} = Zm;
6415  let Inst{15}    = 0b1;
6416  let Inst{14}    = xs;
6417  let Inst{13}    = 0;
6418  let Inst{12-10} = Pg;
6419  let Inst{9-5}   = Rn;
6420  let Inst{4-0}   = Zt;
6421
6422  let hasSideEffects = 0;
6423  let mayStore = 1;
6424}
6425
6426multiclass sve_mem_32b_sst_sv_32_scaled<bits<3> opc, string asm,
6427                                    SDPatternOperator sxtw_op,
6428                                    SDPatternOperator uxtw_op,
6429                                    RegisterOperand sxtw_opnd,
6430                                    RegisterOperand uxtw_opnd,
6431                                    ValueType vt > {
6432  def _UXTW_SCALED : sve_mem_sst_sv<opc, 0, 1, asm, Z_s, uxtw_opnd>;
6433  def _SXTW_SCALED : sve_mem_sst_sv<opc, 1, 1, asm, Z_s, sxtw_opnd>;
6434
6435  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6436                 (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6437  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6438                 (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6439
6440  def : Pat<(uxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6441            (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6442  def : Pat<(sxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6443            (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6444}
6445
6446multiclass sve_mem_64b_sst_sv_32_scaled<bits<3> opc, string asm,
6447                                    SDPatternOperator sxtw_op,
6448                                    SDPatternOperator uxtw_op,
6449                                    RegisterOperand sxtw_opnd,
6450                                    RegisterOperand uxtw_opnd,
6451                                    ValueType vt > {
6452  def _UXTW_SCALED : sve_mem_sst_sv<opc, 0, 1, asm, Z_d, uxtw_opnd>;
6453  def _SXTW_SCALED : sve_mem_sst_sv<opc, 1, 1, asm, Z_d, sxtw_opnd>;
6454
6455  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6456                 (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6457  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6458                 (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6459
6460  def : Pat<(uxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6461            (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6462  def : Pat<(sxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6463            (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6464}
6465
6466multiclass sve_mem_64b_sst_sv_32_unscaled<bits<3> opc, string asm,
6467                                         SDPatternOperator sxtw_op,
6468                                         SDPatternOperator uxtw_op,
6469                                         RegisterOperand sxtw_opnd,
6470                                         RegisterOperand uxtw_opnd,
6471                                         ValueType vt> {
6472  def _UXTW : sve_mem_sst_sv<opc, 0, 0, asm, Z_d, uxtw_opnd>;
6473  def _SXTW : sve_mem_sst_sv<opc, 1, 0, asm, Z_d, sxtw_opnd>;
6474
6475  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6476                 (!cast<Instruction>(NAME # _UXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6477  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6478                 (!cast<Instruction>(NAME # _SXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6479
6480  def : Pat<(uxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6481            (!cast<Instruction>(NAME # _UXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6482  def : Pat<(sxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6483            (!cast<Instruction>(NAME # _SXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6484}
6485
6486multiclass sve_mem_32b_sst_sv_32_unscaled<bits<3> opc, string asm,
6487                                          SDPatternOperator sxtw_op,
6488                                          SDPatternOperator uxtw_op,
6489                                          RegisterOperand sxtw_opnd,
6490                                          RegisterOperand uxtw_opnd,
6491                                          ValueType vt> {
6492  def _UXTW : sve_mem_sst_sv<opc, 0, 0, asm, Z_s, uxtw_opnd>;
6493  def _SXTW : sve_mem_sst_sv<opc, 1, 0, asm, Z_s, sxtw_opnd>;
6494
6495  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6496                 (!cast<Instruction>(NAME # _UXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6497  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6498                 (!cast<Instruction>(NAME # _SXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6499
6500  def : Pat<(uxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6501            (!cast<Instruction>(NAME # _UXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6502  def : Pat<(sxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6503            (!cast<Instruction>(NAME # _SXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6504}
6505
6506class sve_mem_sst_sv2<bits<2> msz, bit scaled, string asm,
6507                      RegisterOperand zprext>
6508: I<(outs), (ins Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
6509  asm, "\t$Zt, $Pg, [$Rn, $Zm]",
6510  "",
6511  []>, Sched<[]> {
6512  bits<3> Pg;
6513  bits<5> Rn;
6514  bits<5> Zm;
6515  bits<5> Zt;
6516  let Inst{31-25} = 0b1110010;
6517  let Inst{24-23} = msz;
6518  let Inst{22}    = 0b0;
6519  let Inst{21}    = scaled;
6520  let Inst{20-16} = Zm;
6521  let Inst{15-13} = 0b101;
6522  let Inst{12-10} = Pg;
6523  let Inst{9-5}   = Rn;
6524  let Inst{4-0}   = Zt;
6525
6526  let hasSideEffects = 0;
6527  let mayStore = 1;
6528}
6529
6530multiclass sve_mem_sst_sv_64_scaled<bits<2> msz, string asm,
6531                                    SDPatternOperator op,
6532                                    RegisterOperand zprext,
6533                                    ValueType vt> {
6534  def _SCALED : sve_mem_sst_sv2<msz, 1, asm, zprext>;
6535
6536  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6537                 (!cast<Instruction>(NAME # _SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), 0>;
6538
6539  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt),
6540            (!cast<Instruction>(NAME # _SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
6541}
6542
6543multiclass sve_mem_sst_sv_64_unscaled<bits<2> msz, string asm,
6544                                      SDPatternOperator op,
6545                                      ValueType vt> {
6546  def NAME : sve_mem_sst_sv2<msz, 0, asm, ZPR64ExtLSL8>;
6547
6548  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6549                 (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), 0>;
6550
6551  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6552            (!cast<Instruction>(NAME) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6553}
6554
6555class sve_mem_sst_vi<bits<3> opc, string asm, ZPRRegOp zprty,
6556                     RegisterOperand VecList, Operand imm_ty>
6557: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, zprty:$Zn, imm_ty:$imm5),
6558  asm, "\t$Zt, $Pg, [$Zn, $imm5]",
6559  "",
6560  []>, Sched<[]> {
6561  bits<3> Pg;
6562  bits<5> imm5;
6563  bits<5> Zn;
6564  bits<5> Zt;
6565  let Inst{31-25} = 0b1110010;
6566  let Inst{24-23} = opc{2-1};
6567  let Inst{22}    = 0b1;
6568  let Inst{21}    = opc{0};
6569  let Inst{20-16} = imm5;
6570  let Inst{15-13} = 0b101;
6571  let Inst{12-10} = Pg;
6572  let Inst{9-5}   = Zn;
6573  let Inst{4-0}   = Zt;
6574
6575  let hasSideEffects = 0;
6576  let mayStore = 1;
6577}
6578
6579multiclass sve_mem_32b_sst_vi_ptrs<bits<3> opc, string asm,
6580                                   Operand imm_ty,
6581                                   SDPatternOperator op,
6582                                   ValueType vt> {
6583  def _IMM : sve_mem_sst_vi<opc, asm, ZPR32, Z_s, imm_ty>;
6584
6585  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6586                  (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 0>;
6587  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $imm5]",
6588                  (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), 0>;
6589  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6590                  (!cast<Instruction>(NAME # _IMM) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
6591
6592  def : Pat<(op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), (nxv4i32 ZPR:$ptrs), imm_ty:$index, vt),
6593            (!cast<Instruction>(NAME # _IMM) ZPR:$data, PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
6594}
6595
6596multiclass sve_mem_64b_sst_vi_ptrs<bits<3> opc, string asm,
6597                                   Operand imm_ty,
6598                                   SDPatternOperator op,
6599                                   ValueType vt> {
6600  def _IMM : sve_mem_sst_vi<opc, asm, ZPR64, Z_d, imm_ty>;
6601
6602  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6603                  (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 0>;
6604  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $imm5]",
6605                  (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), 0>;
6606  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6607                  (!cast<Instruction>(NAME # _IMM) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
6608
6609  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), (nxv2i64 ZPR:$ptrs), imm_ty:$index, vt),
6610            (!cast<Instruction>(NAME # _IMM) ZPR:$data, PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
6611}
6612
6613class sve_mem_z_spill<string asm>
6614: I<(outs), (ins ZPRAny:$Zt, GPR64sp:$Rn, simm9:$imm9),
6615  asm, "\t$Zt, [$Rn, $imm9, mul vl]",
6616  "",
6617  []>, Sched<[]> {
6618  bits<5> Rn;
6619  bits<5> Zt;
6620  bits<9> imm9;
6621  let Inst{31-22} = 0b1110010110;
6622  let Inst{21-16} = imm9{8-3};
6623  let Inst{15-13} = 0b010;
6624  let Inst{12-10} = imm9{2-0};
6625  let Inst{9-5}   = Rn;
6626  let Inst{4-0}   = Zt;
6627
6628  let hasSideEffects = 0;
6629  let mayStore = 1;
6630}
6631
6632multiclass sve_mem_z_spill<string asm> {
6633  def NAME : sve_mem_z_spill<asm>;
6634
6635  def : InstAlias<asm # "\t$Zt, [$Rn]",
6636                  (!cast<Instruction>(NAME) ZPRAny:$Zt, GPR64sp:$Rn, 0), 1>;
6637}
6638
6639class sve_mem_p_spill<string asm>
6640: I<(outs), (ins PPRAny:$Pt, GPR64sp:$Rn, simm9:$imm9),
6641  asm, "\t$Pt, [$Rn, $imm9, mul vl]",
6642  "",
6643  []>, Sched<[]> {
6644  bits<4> Pt;
6645  bits<5> Rn;
6646  bits<9> imm9;
6647  let Inst{31-22} = 0b1110010110;
6648  let Inst{21-16} = imm9{8-3};
6649  let Inst{15-13} = 0b000;
6650  let Inst{12-10} = imm9{2-0};
6651  let Inst{9-5}   = Rn;
6652  let Inst{4}     = 0b0;
6653  let Inst{3-0}   = Pt;
6654
6655  let hasSideEffects = 0;
6656  let mayStore = 1;
6657}
6658
6659multiclass sve_mem_p_spill<string asm> {
6660  def NAME : sve_mem_p_spill<asm>;
6661
6662  def : InstAlias<asm # "\t$Pt, [$Rn]",
6663                  (!cast<Instruction>(NAME) PPRAny:$Pt, GPR64sp:$Rn, 0), 1>;
6664}
6665
6666//===----------------------------------------------------------------------===//
6667// SVE Permute - Predicates Group
6668//===----------------------------------------------------------------------===//
6669
6670class sve_int_perm_bin_perm_pp<bits<3> opc, bits<2> sz8_64, string asm,
6671                               PPRRegOp pprty, SDPatternOperator op>
6672: I<(outs pprty:$Pd), (ins pprty:$Pn, pprty:$Pm),
6673  asm, "\t$Pd, $Pn, $Pm",
6674  "",
6675  [(set nxv16i1:$Pd, (op nxv16i1:$Pn, nxv16i1:$Pm))]>, Sched<[]> {
6676  bits<4> Pd;
6677  bits<4> Pm;
6678  bits<4> Pn;
6679  let Inst{31-24} = 0b00000101;
6680  let Inst{23-22} = sz8_64;
6681  let Inst{21-20} = 0b10;
6682  let Inst{19-16} = Pm;
6683  let Inst{15-13} = 0b010;
6684  let Inst{12-10} = opc;
6685  let Inst{9}     = 0b0;
6686  let Inst{8-5}   = Pn;
6687  let Inst{4}     = 0b0;
6688  let Inst{3-0}   = Pd;
6689
6690  let hasSideEffects = 0;
6691}
6692
6693multiclass sve_int_perm_bin_perm_pp<bits<3> opc, string asm,
6694                                    SDPatternOperator ir_op,
6695                                    SDPatternOperator op_b16,
6696                                    SDPatternOperator op_b32,
6697                                    SDPatternOperator op_b64> {
6698  def _B : sve_int_perm_bin_perm_pp<opc, 0b00, asm, PPR8,  ir_op>;
6699  def _H : sve_int_perm_bin_perm_pp<opc, 0b01, asm, PPR16, op_b16>;
6700  def _S : sve_int_perm_bin_perm_pp<opc, 0b10, asm, PPR32, op_b32>;
6701  def _D : sve_int_perm_bin_perm_pp<opc, 0b11, asm, PPR64, op_b64>;
6702
6703  def : SVE_2_Op_Pat<nxv8i1, ir_op, nxv8i1, nxv8i1, !cast<Instruction>(NAME # _H)>;
6704  def : SVE_2_Op_Pat<nxv4i1, ir_op, nxv4i1, nxv4i1, !cast<Instruction>(NAME # _S)>;
6705  def : SVE_2_Op_Pat<nxv2i1, ir_op, nxv2i1, nxv2i1, !cast<Instruction>(NAME # _D)>;
6706}
6707
6708class sve_int_perm_punpk<bit opc, string asm>
6709: I<(outs PPR16:$Pd), (ins PPR8:$Pn),
6710  asm, "\t$Pd, $Pn",
6711  "",
6712  []>, Sched<[]> {
6713  bits<4> Pd;
6714  bits<4> Pn;
6715  let Inst{31-17} = 0b000001010011000;
6716  let Inst{16}    = opc;
6717  let Inst{15-9}  = 0b0100000;
6718  let Inst{8-5}   = Pn;
6719  let Inst{4}     = 0b0;
6720  let Inst{3-0}   = Pd;
6721
6722  let hasSideEffects = 0;
6723}
6724
6725multiclass sve_int_perm_punpk<bit opc, string asm, SDPatternOperator op> {
6726  def NAME : sve_int_perm_punpk<opc, asm>;
6727
6728  def : SVE_1_Op_Pat<nxv8i1, op, nxv16i1, !cast<Instruction>(NAME)>;
6729  def : SVE_1_Op_Pat<nxv4i1, op, nxv8i1,  !cast<Instruction>(NAME)>;
6730  def : SVE_1_Op_Pat<nxv2i1, op, nxv4i1,  !cast<Instruction>(NAME)>;
6731}
6732
6733class sve_int_rdffr_pred<bit s, string asm>
6734: I<(outs PPR8:$Pd), (ins PPRAny:$Pg),
6735  asm, "\t$Pd, $Pg/z",
6736  "",
6737  []>, Sched<[]> {
6738  bits<4> Pd;
6739  bits<4> Pg;
6740  let Inst{31-23} = 0b001001010;
6741  let Inst{22}    = s;
6742  let Inst{21-9}  = 0b0110001111000;
6743  let Inst{8-5}   = Pg;
6744  let Inst{4}     = 0;
6745  let Inst{3-0}   = Pd;
6746
6747  let Defs = !if(s, [NZCV], []);
6748  let Uses = [FFR];
6749  let hasSideEffects = 1;
6750}
6751
6752multiclass sve_int_rdffr_pred<bit s, string asm, SDPatternOperator op> {
6753  def _REAL : sve_int_rdffr_pred<s, asm>;
6754
6755  // We need a layer of indirection because early machine code passes balk at
6756  // physical register (i.e. FFR) uses that have no previous definition.
6757  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
6758  def "" : Pseudo<(outs PPR8:$Pd), (ins PPRAny:$Pg), [(set (nxv16i1 PPR8:$Pd), (op (nxv16i1 PPRAny:$Pg)))]>,
6759           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) PPR8:$Pd, PPRAny:$Pg)>;
6760  }
6761}
6762
6763class sve_int_rdffr_unpred<string asm> : I<
6764  (outs PPR8:$Pd), (ins),
6765  asm, "\t$Pd",
6766  "",
6767  []>, Sched<[]> {
6768  bits<4> Pd;
6769  let Inst{31-4} = 0b0010010100011001111100000000;
6770  let Inst{3-0}   = Pd;
6771
6772  let Uses = [FFR];
6773  let hasSideEffects = 1;
6774}
6775
6776multiclass sve_int_rdffr_unpred<string asm, SDPatternOperator op> {
6777  def _REAL : sve_int_rdffr_unpred<asm>;
6778
6779  // We need a layer of indirection because early machine code passes balk at
6780  // physical register (i.e. FFR) uses that have no previous definition.
6781  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
6782  def "" : Pseudo<(outs PPR8:$Pd), (ins), [(set (nxv16i1 PPR8:$Pd), (op))]>,
6783           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) PPR8:$Pd)>;
6784  }
6785}
6786
6787class sve_int_wrffr<string asm, SDPatternOperator op>
6788: I<(outs), (ins PPR8:$Pn),
6789  asm, "\t$Pn",
6790  "",
6791  [(op (nxv16i1 PPR8:$Pn))]>, Sched<[]> {
6792  bits<4> Pn;
6793  let Inst{31-9} = 0b00100101001010001001000;
6794  let Inst{8-5}  = Pn;
6795  let Inst{4-0}  = 0b00000;
6796
6797  let Defs = [FFR];
6798  let hasSideEffects = 1;
6799}
6800
6801class sve_int_setffr<string asm, SDPatternOperator op>
6802: I<(outs), (ins),
6803  asm, "",
6804  "",
6805  [(op)]>, Sched<[]> {
6806  let Inst{31-0} = 0b00100101001011001001000000000000;
6807
6808  let Defs = [FFR];
6809  let hasSideEffects = 1;
6810}
6811
6812//===----------------------------------------------------------------------===//
6813// SVE Permute Vector - Predicated Group
6814//===----------------------------------------------------------------------===//
6815
6816class sve_int_perm_clast_rz<bits<2> sz8_64, bit ab, string asm,
6817                            ZPRRegOp zprty, RegisterClass rt>
6818: I<(outs rt:$Rdn), (ins PPR3bAny:$Pg, rt:$_Rdn, zprty:$Zm),
6819  asm, "\t$Rdn, $Pg, $_Rdn, $Zm",
6820  "",
6821  []>, Sched<[]> {
6822  bits<3> Pg;
6823  bits<5> Rdn;
6824  bits<5> Zm;
6825  let Inst{31-24} = 0b00000101;
6826  let Inst{23-22} = sz8_64;
6827  let Inst{21-17} = 0b11000;
6828  let Inst{16}    = ab;
6829  let Inst{15-13} = 0b101;
6830  let Inst{12-10} = Pg;
6831  let Inst{9-5}   = Zm;
6832  let Inst{4-0}   = Rdn;
6833
6834  let Constraints = "$Rdn = $_Rdn";
6835  let hasSideEffects = 0;
6836}
6837
6838multiclass sve_int_perm_clast_rz<bit ab, string asm, SDPatternOperator op> {
6839  def _B : sve_int_perm_clast_rz<0b00, ab, asm, ZPR8, GPR32>;
6840  def _H : sve_int_perm_clast_rz<0b01, ab, asm, ZPR16, GPR32>;
6841  def _S : sve_int_perm_clast_rz<0b10, ab, asm, ZPR32, GPR32>;
6842  def _D : sve_int_perm_clast_rz<0b11, ab, asm, ZPR64, GPR64>;
6843
6844  def : SVE_3_Op_Pat<i32, op, nxv16i1, i32, nxv16i8, !cast<Instruction>(NAME # _B)>;
6845  def : SVE_3_Op_Pat<i32, op, nxv8i1,  i32, nxv8i16, !cast<Instruction>(NAME # _H)>;
6846  def : SVE_3_Op_Pat<i32, op, nxv4i1,  i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
6847  def : SVE_3_Op_Pat<i64, op, nxv2i1,  i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
6848}
6849
6850class sve_int_perm_clast_vz<bits<2> sz8_64, bit ab, string asm,
6851                            ZPRRegOp zprty, RegisterClass rt>
6852: I<(outs rt:$Vdn), (ins PPR3bAny:$Pg, rt:$_Vdn, zprty:$Zm),
6853  asm, "\t$Vdn, $Pg, $_Vdn, $Zm",
6854  "",
6855  []>, Sched<[]> {
6856  bits<3> Pg;
6857  bits<5> Vdn;
6858  bits<5> Zm;
6859  let Inst{31-24} = 0b00000101;
6860  let Inst{23-22} = sz8_64;
6861  let Inst{21-17} = 0b10101;
6862  let Inst{16}    = ab;
6863  let Inst{15-13} = 0b100;
6864  let Inst{12-10} = Pg;
6865  let Inst{9-5}   = Zm;
6866  let Inst{4-0}   = Vdn;
6867
6868  let Constraints = "$Vdn = $_Vdn";
6869  let hasSideEffects = 0;
6870}
6871
6872multiclass sve_int_perm_clast_vz<bit ab, string asm, SDPatternOperator op> {
6873  def _B : sve_int_perm_clast_vz<0b00, ab, asm, ZPR8, FPR8>;
6874  def _H : sve_int_perm_clast_vz<0b01, ab, asm, ZPR16, FPR16>;
6875  def _S : sve_int_perm_clast_vz<0b10, ab, asm, ZPR32, FPR32>;
6876  def _D : sve_int_perm_clast_vz<0b11, ab, asm, ZPR64, FPR64>;
6877
6878  def : SVE_3_Op_Pat<f16, op, nxv8i1, f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
6879  def : SVE_3_Op_Pat<f32, op, nxv4i1, f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
6880  def : SVE_3_Op_Pat<f64, op, nxv2i1, f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
6881
6882  def : SVE_3_Op_Pat<bf16, op, nxv8i1, bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
6883}
6884
6885class sve_int_perm_clast_zz<bits<2> sz8_64, bit ab, string asm,
6886                            ZPRRegOp zprty>
6887: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
6888  asm, "\t$Zdn, $Pg, $_Zdn, $Zm",
6889  "",
6890  []>, Sched<[]> {
6891  bits<3> Pg;
6892  bits<5> Zdn;
6893  bits<5> Zm;
6894  let Inst{31-24} = 0b00000101;
6895  let Inst{23-22} = sz8_64;
6896  let Inst{21-17} = 0b10100;
6897  let Inst{16}    = ab;
6898  let Inst{15-13} = 0b100;
6899  let Inst{12-10} = Pg;
6900  let Inst{9-5}   = Zm;
6901  let Inst{4-0}   = Zdn;
6902
6903  let Constraints = "$Zdn = $_Zdn";
6904  let DestructiveInstType = DestructiveOther;
6905  let ElementSize = ElementSizeNone;
6906  let hasSideEffects = 0;
6907}
6908
6909multiclass sve_int_perm_clast_zz<bit ab, string asm, SDPatternOperator op> {
6910  def _B : sve_int_perm_clast_zz<0b00, ab, asm, ZPR8>;
6911  def _H : sve_int_perm_clast_zz<0b01, ab, asm, ZPR16>;
6912  def _S : sve_int_perm_clast_zz<0b10, ab, asm, ZPR32>;
6913  def _D : sve_int_perm_clast_zz<0b11, ab, asm, ZPR64>;
6914
6915  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
6916  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
6917  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
6918  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
6919
6920  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
6921  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
6922  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
6923
6924  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
6925}
6926
6927class sve_int_perm_last_r<bits<2> sz8_64, bit ab, string asm,
6928                          ZPRRegOp zprty, RegisterClass resultRegType>
6929: I<(outs resultRegType:$Rd), (ins PPR3bAny:$Pg, zprty:$Zn),
6930  asm, "\t$Rd, $Pg, $Zn",
6931  "",
6932  []>, Sched<[]> {
6933  bits<3> Pg;
6934  bits<5> Rd;
6935  bits<5> Zn;
6936  let Inst{31-24} = 0b00000101;
6937  let Inst{23-22} = sz8_64;
6938  let Inst{21-17} = 0b10000;
6939  let Inst{16}    = ab;
6940  let Inst{15-13} = 0b101;
6941  let Inst{12-10} = Pg;
6942  let Inst{9-5}   = Zn;
6943  let Inst{4-0}   = Rd;
6944
6945  let hasSideEffects = 0;
6946}
6947
6948multiclass sve_int_perm_last_r<bit ab, string asm, SDPatternOperator op> {
6949  def _B : sve_int_perm_last_r<0b00, ab, asm, ZPR8, GPR32>;
6950  def _H : sve_int_perm_last_r<0b01, ab, asm, ZPR16, GPR32>;
6951  def _S : sve_int_perm_last_r<0b10, ab, asm, ZPR32, GPR32>;
6952  def _D : sve_int_perm_last_r<0b11, ab, asm, ZPR64, GPR64>;
6953
6954  def : SVE_2_Op_Pat<i32, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
6955  def : SVE_2_Op_Pat<i32, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
6956  def : SVE_2_Op_Pat<i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
6957  def : SVE_2_Op_Pat<i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
6958}
6959
6960class sve_int_perm_last_v<bits<2> sz8_64, bit ab, string asm,
6961                          ZPRRegOp zprty, RegisterClass dstRegtype>
6962: I<(outs dstRegtype:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
6963  asm, "\t$Vd, $Pg, $Zn",
6964  "",
6965  []>, Sched<[]> {
6966  bits<3> Pg;
6967  bits<5> Vd;
6968  bits<5> Zn;
6969  let Inst{31-24} = 0b00000101;
6970  let Inst{23-22} = sz8_64;
6971  let Inst{21-17} = 0b10001;
6972  let Inst{16}    = ab;
6973  let Inst{15-13} = 0b100;
6974  let Inst{12-10} = Pg;
6975  let Inst{9-5}   = Zn;
6976  let Inst{4-0}   = Vd;
6977
6978  let hasSideEffects = 0;
6979}
6980
6981multiclass sve_int_perm_last_v<bit ab, string asm, SDPatternOperator op> {
6982  def _B : sve_int_perm_last_v<0b00, ab, asm, ZPR8, FPR8>;
6983  def _H : sve_int_perm_last_v<0b01, ab, asm, ZPR16, FPR16>;
6984  def _S : sve_int_perm_last_v<0b10, ab, asm, ZPR32, FPR32>;
6985  def _D : sve_int_perm_last_v<0b11, ab, asm, ZPR64, FPR64>;
6986
6987  def : SVE_2_Op_Pat<f16, op, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
6988  def : SVE_2_Op_Pat<f32, op, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
6989  def : SVE_2_Op_Pat<f32, op, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
6990  def : SVE_2_Op_Pat<f64, op, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
6991
6992  def : SVE_2_Op_Pat<bf16, op, nxv8i1,  nxv8bf16, !cast<Instruction>(NAME # _H)>;
6993}
6994
6995class sve_int_perm_splice<bits<2> sz8_64, string asm, ZPRRegOp zprty>
6996: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
6997  asm, "\t$Zdn, $Pg, $_Zdn, $Zm",
6998  "",
6999  []>, Sched<[]> {
7000  bits<3> Pg;
7001  bits<5> Zdn;
7002  bits<5> Zm;
7003  let Inst{31-24} = 0b00000101;
7004  let Inst{23-22} = sz8_64;
7005  let Inst{21-13} = 0b101100100;
7006  let Inst{12-10} = Pg;
7007  let Inst{9-5}   = Zm;
7008  let Inst{4-0}   = Zdn;
7009
7010  let Constraints = "$Zdn = $_Zdn";
7011  let DestructiveInstType = DestructiveOther;
7012  let ElementSize = ElementSizeNone;
7013  let hasSideEffects = 0;
7014}
7015
7016multiclass sve_int_perm_splice<string asm, SDPatternOperator op> {
7017  def _B : sve_int_perm_splice<0b00, asm, ZPR8>;
7018  def _H : sve_int_perm_splice<0b01, asm, ZPR16>;
7019  def _S : sve_int_perm_splice<0b10, asm, ZPR32>;
7020  def _D : sve_int_perm_splice<0b11, asm, ZPR64>;
7021
7022  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
7023  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
7024  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
7025  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
7026
7027  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1,  nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
7028  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1,  nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
7029  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1,  nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
7030
7031  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
7032}
7033
7034class sve2_int_perm_splice_cons<bits<2> sz8_64, string asm,
7035                               ZPRRegOp zprty, RegisterOperand VecList>
7036: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, VecList:$Zn),
7037  asm, "\t$Zd, $Pg, $Zn",
7038  "",
7039  []>, Sched<[]> {
7040  bits<3> Pg;
7041  bits<5> Zn;
7042  bits<5> Zd;
7043  let Inst{31-24} = 0b00000101;
7044  let Inst{23-22} = sz8_64;
7045  let Inst{21-13} = 0b101101100;
7046  let Inst{12-10} = Pg;
7047  let Inst{9-5}   = Zn;
7048  let Inst{4-0}   = Zd;
7049
7050  let hasSideEffects = 0;
7051}
7052
7053multiclass sve2_int_perm_splice_cons<string asm> {
7054  def _B : sve2_int_perm_splice_cons<0b00, asm, ZPR8,  ZZ_b>;
7055  def _H : sve2_int_perm_splice_cons<0b01, asm, ZPR16, ZZ_h>;
7056  def _S : sve2_int_perm_splice_cons<0b10, asm, ZPR32, ZZ_s>;
7057  def _D : sve2_int_perm_splice_cons<0b11, asm, ZPR64, ZZ_d>;
7058}
7059
7060class sve_int_perm_rev<bits<2> sz8_64, bits<2> opc, string asm,
7061                       ZPRRegOp zprty>
7062: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
7063  asm, "\t$Zd, $Pg/m, $Zn",
7064  "",
7065  []>, Sched<[]> {
7066  bits<5> Zd;
7067  bits<3> Pg;
7068  bits<5> Zn;
7069  let Inst{31-24} = 0b00000101;
7070  let Inst{23-22} = sz8_64;
7071  let Inst{21-18} = 0b1001;
7072  let Inst{17-16} = opc;
7073  let Inst{15-13} = 0b100;
7074  let Inst{12-10} = Pg;
7075  let Inst{9-5}   = Zn;
7076  let Inst{4-0}   = Zd;
7077
7078  let Constraints = "$Zd = $_Zd";
7079  let DestructiveInstType = DestructiveOther;
7080  let ElementSize = zprty.ElementSize;
7081  let hasSideEffects = 0;
7082}
7083
7084multiclass sve_int_perm_rev_rbit<string asm, SDPatternOperator op> {
7085  def _B : sve_int_perm_rev<0b00, 0b11, asm, ZPR8>;
7086  def _H : sve_int_perm_rev<0b01, 0b11, asm, ZPR16>;
7087  def _S : sve_int_perm_rev<0b10, 0b11, asm, ZPR32>;
7088  def _D : sve_int_perm_rev<0b11, 0b11, asm, ZPR64>;
7089
7090  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
7091  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
7092  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7093  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7094}
7095
7096multiclass sve_int_perm_rev_revb<string asm, SDPatternOperator op> {
7097  def _H : sve_int_perm_rev<0b01, 0b00, asm, ZPR16>;
7098  def _S : sve_int_perm_rev<0b10, 0b00, asm, ZPR32>;
7099  def _D : sve_int_perm_rev<0b11, 0b00, asm, ZPR64>;
7100
7101  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
7102  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7103  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7104}
7105
7106multiclass sve_int_perm_rev_revh<string asm, SDPatternOperator op> {
7107  def _S : sve_int_perm_rev<0b10, 0b01, asm, ZPR32>;
7108  def _D : sve_int_perm_rev<0b11, 0b01, asm, ZPR64>;
7109
7110  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7111  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7112}
7113
7114multiclass sve_int_perm_rev_revw<string asm, SDPatternOperator op> {
7115  def _D : sve_int_perm_rev<0b11, 0b10, asm, ZPR64>;
7116
7117  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7118}
7119
7120class sve_int_perm_cpy_r<bits<2> sz8_64, string asm, ZPRRegOp zprty,
7121                         RegisterClass srcRegType>
7122: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegType:$Rn),
7123  asm, "\t$Zd, $Pg/m, $Rn",
7124  "",
7125  []>, Sched<[]> {
7126  bits<3> Pg;
7127  bits<5> Rn;
7128  bits<5> Zd;
7129  let Inst{31-24} = 0b00000101;
7130  let Inst{23-22} = sz8_64;
7131  let Inst{21-13} = 0b101000101;
7132  let Inst{12-10} = Pg;
7133  let Inst{9-5}   = Rn;
7134  let Inst{4-0}   = Zd;
7135
7136  let Constraints = "$Zd = $_Zd";
7137  let DestructiveInstType = DestructiveOther;
7138  let ElementSize = zprty.ElementSize;
7139  let hasSideEffects = 0;
7140}
7141
7142multiclass sve_int_perm_cpy_r<string asm, SDPatternOperator op> {
7143  def _B : sve_int_perm_cpy_r<0b00, asm, ZPR8, GPR32sp>;
7144  def _H : sve_int_perm_cpy_r<0b01, asm, ZPR16, GPR32sp>;
7145  def _S : sve_int_perm_cpy_r<0b10, asm, ZPR32, GPR32sp>;
7146  def _D : sve_int_perm_cpy_r<0b11, asm, ZPR64, GPR64sp>;
7147
7148  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7149                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7150  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7151                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7152  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7153                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7154  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7155                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPR3bAny:$Pg, GPR64sp:$Rn), 1>;
7156
7157  def : Pat<(nxv16i8 (op nxv16i1:$pg, i32:$splat, nxv16i8:$passthru)),
7158            (!cast<Instruction>(NAME # _B) $passthru, $pg, $splat)>;
7159  def : Pat<(nxv8i16 (op nxv8i1:$pg, i32:$splat, nxv8i16:$passthru)),
7160            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7161  def : Pat<(nxv4i32 (op nxv4i1:$pg, i32:$splat, nxv4i32:$passthru)),
7162            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7163  def : Pat<(nxv2i64 (op nxv2i1:$pg, i64:$splat, nxv2i64:$passthru)),
7164            (!cast<Instruction>(NAME # _D) $passthru, $pg, $splat)>;
7165}
7166
7167class sve_int_perm_cpy_v<bits<2> sz8_64, string asm, ZPRRegOp zprty,
7168                         RegisterClass srcRegtype>
7169: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegtype:$Vn),
7170  asm, "\t$Zd, $Pg/m, $Vn",
7171  "",
7172  []>, Sched<[]> {
7173  bits<3> Pg;
7174  bits<5> Vn;
7175  bits<5> Zd;
7176  let Inst{31-24} = 0b00000101;
7177  let Inst{23-22} = sz8_64;
7178  let Inst{21-13} = 0b100000100;
7179  let Inst{12-10} = Pg;
7180  let Inst{9-5}   = Vn;
7181  let Inst{4-0}   = Zd;
7182
7183  let Constraints = "$Zd = $_Zd";
7184  let DestructiveInstType = DestructiveOther;
7185  let ElementSize = zprty.ElementSize;
7186  let hasSideEffects = 0;
7187}
7188
7189multiclass sve_int_perm_cpy_v<string asm, SDPatternOperator op> {
7190  def _B : sve_int_perm_cpy_v<0b00, asm, ZPR8, FPR8>;
7191  def _H : sve_int_perm_cpy_v<0b01, asm, ZPR16, FPR16>;
7192  def _S : sve_int_perm_cpy_v<0b10, asm, ZPR32, FPR32>;
7193  def _D : sve_int_perm_cpy_v<0b11, asm, ZPR64, FPR64>;
7194
7195  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7196                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPR3bAny:$Pg, FPR8:$Vn), 1>;
7197  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7198                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPR3bAny:$Pg, FPR16:$Vn), 1>;
7199  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7200                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPR3bAny:$Pg, FPR32:$Vn), 1>;
7201  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7202                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPR3bAny:$Pg, FPR64:$Vn), 1>;
7203
7204  def : Pat<(nxv8f16 (op nxv8i1:$pg, f16:$splat, nxv8f16:$passthru)),
7205            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7206  def : Pat<(nxv4f16 (op nxv4i1:$pg, f16:$splat, nxv4f16:$passthru)),
7207            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7208  def : Pat<(nxv2f16 (op nxv2i1:$pg, f16:$splat, nxv2f16:$passthru)),
7209            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7210  def : Pat<(nxv2f32 (op nxv2i1:$pg, f32:$splat, nxv2f32:$passthru)),
7211            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7212  def : Pat<(nxv4f32 (op nxv4i1:$pg, f32:$splat, nxv4f32:$passthru)),
7213            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7214  def : Pat<(nxv2f64 (op nxv2i1:$pg, f64:$splat, nxv2f64:$passthru)),
7215            (!cast<Instruction>(NAME # _D) $passthru, $pg, $splat)>;
7216
7217  def : Pat<(nxv8bf16 (op nxv8i1:$pg, bf16:$splat, nxv8bf16:$passthru)),
7218            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7219}
7220
7221class sve_int_perm_compact<bit sz, string asm, ZPRRegOp zprty>
7222: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
7223  asm, "\t$Zd, $Pg, $Zn",
7224  "",
7225  []>, Sched<[]> {
7226  bits<3> Pg;
7227  bits<5> Zd;
7228  bits<5> Zn;
7229  let Inst{31-23} = 0b000001011;
7230  let Inst{22}    = sz;
7231  let Inst{21-13} = 0b100001100;
7232  let Inst{12-10} = Pg;
7233  let Inst{9-5}   = Zn;
7234  let Inst{4-0}   = Zd;
7235
7236  let hasSideEffects = 0;
7237}
7238
7239multiclass sve_int_perm_compact<string asm, SDPatternOperator op> {
7240  def _S : sve_int_perm_compact<0b0, asm, ZPR32>;
7241  def _D : sve_int_perm_compact<0b1, asm, ZPR64>;
7242
7243  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
7244  def : SVE_2_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
7245  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
7246  def : SVE_2_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
7247}
7248
7249//===----------------------------------------------------------------------===//
7250// SVE Memory - Contiguous Load Group
7251//===----------------------------------------------------------------------===//
7252
7253class sve_mem_cld_si_base<bits<4> dtype, bit nf, string asm,
7254                          RegisterOperand VecList>
7255: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
7256  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7257  "",
7258  []>, Sched<[]> {
7259  bits<3> Pg;
7260  bits<5> Rn;
7261  bits<5> Zt;
7262  bits<4> imm4;
7263  let Inst{31-25} = 0b1010010;
7264  let Inst{24-21} = dtype;
7265  let Inst{20}    = nf;
7266  let Inst{19-16} = imm4;
7267  let Inst{15-13} = 0b101;
7268  let Inst{12-10} = Pg;
7269  let Inst{9-5}   = Rn;
7270  let Inst{4-0}   = Zt;
7271
7272  let Defs = !if(nf, [FFR], []);
7273  let Uses = !if(nf, [FFR], []);
7274  let hasSideEffects = nf;
7275  let mayLoad = 1;
7276}
7277
7278multiclass sve_mem_cld_si_base<bits<4> dtype, bit nf, string asm,
7279                               RegisterOperand listty, ZPRRegOp zprty> {
7280  def _REAL : sve_mem_cld_si_base<dtype, nf, asm, listty>;
7281
7282  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7283                  (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7284  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7285                  (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
7286  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7287                  (!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7288
7289  // We need a layer of indirection because early machine code passes balk at
7290  // physical register (i.e. FFR) uses that have no previous definition.
7291  let hasSideEffects = 1, hasNoSchedulingInfo = 1, mayLoad = 1 in {
7292  def "" : Pseudo<(outs listty:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), []>,
7293           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4)>;
7294  }
7295}
7296
7297multiclass sve_mem_cld_si<bits<4> dtype, string asm, RegisterOperand listty,
7298                          ZPRRegOp zprty>
7299: sve_mem_cld_si_base<dtype, 0, asm, listty, zprty>;
7300
7301class sve_mem_cldnt_si_base<bits<2> msz, string asm, RegisterOperand VecList>
7302: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
7303  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7304  "",
7305  []>, Sched<[]> {
7306  bits<5> Zt;
7307  bits<3> Pg;
7308  bits<5> Rn;
7309  bits<4> imm4;
7310  let Inst{31-25} = 0b1010010;
7311  let Inst{24-23} = msz;
7312  let Inst{22-20} = 0b000;
7313  let Inst{19-16} = imm4;
7314  let Inst{15-13} = 0b111;
7315  let Inst{12-10} = Pg;
7316  let Inst{9-5}   = Rn;
7317  let Inst{4-0}   = Zt;
7318
7319  let hasSideEffects = 0;
7320  let mayLoad = 1;
7321}
7322
7323multiclass sve_mem_cldnt_si<bits<2> msz, string asm, RegisterOperand listty,
7324                            ZPRRegOp zprty> {
7325  def NAME : sve_mem_cldnt_si_base<msz, asm, listty>;
7326
7327  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7328                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7329  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7330                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
7331  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7332                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7333}
7334
7335class sve_mem_cldnt_ss_base<bits<2> msz, string asm, RegisterOperand VecList,
7336                            RegisterOperand gprty>
7337: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7338  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7339  "",
7340  []>, Sched<[]> {
7341  bits<3> Pg;
7342  bits<5> Rm;
7343  bits<5> Rn;
7344  bits<5> Zt;
7345  let Inst{31-25} = 0b1010010;
7346  let Inst{24-23} = msz;
7347  let Inst{22-21} = 0b00;
7348  let Inst{20-16} = Rm;
7349  let Inst{15-13} = 0b110;
7350  let Inst{12-10} = Pg;
7351  let Inst{9-5}   = Rn;
7352  let Inst{4-0}   = Zt;
7353
7354  let hasSideEffects = 0;
7355  let mayLoad = 1;
7356}
7357
7358multiclass sve_mem_cldnt_ss<bits<2> msz, string asm, RegisterOperand listty,
7359                            ZPRRegOp zprty, RegisterOperand gprty> {
7360  def NAME : sve_mem_cldnt_ss_base<msz, asm, listty, gprty>;
7361
7362  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7363                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7364}
7365
7366class sve_mem_ldqr_si<bits<2> sz, string asm, RegisterOperand VecList>
7367: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4),
7368  asm, "\t$Zt, $Pg/z, [$Rn, $imm4]", "", []>, Sched<[]> {
7369  bits<5> Zt;
7370  bits<5> Rn;
7371  bits<3> Pg;
7372  bits<4> imm4;
7373  let Inst{31-25} = 0b1010010;
7374  let Inst{24-23} = sz;
7375  let Inst{22-20} = 0;
7376  let Inst{19-16} = imm4;
7377  let Inst{15-13} = 0b001;
7378  let Inst{12-10} = Pg;
7379  let Inst{9-5}   = Rn;
7380  let Inst{4-0}   = Zt;
7381
7382  let hasSideEffects = 0;
7383  let mayLoad = 1;
7384}
7385
7386multiclass sve_mem_ldqr_si<bits<2> sz, string asm, RegisterOperand listty,
7387                           ZPRRegOp zprty> {
7388  def NAME : sve_mem_ldqr_si<sz, asm, listty>;
7389  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7390                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7391  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7392                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7393  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4]",
7394                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4), 0>;
7395}
7396
7397class sve_mem_ldqr_ss<bits<2> sz, string asm, RegisterOperand VecList,
7398                      RegisterOperand gprty>
7399: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7400  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]", "", []>, Sched<[]> {
7401  bits<5> Zt;
7402  bits<3> Pg;
7403  bits<5> Rn;
7404  bits<5> Rm;
7405  let Inst{31-25} = 0b1010010;
7406  let Inst{24-23} = sz;
7407  let Inst{22-21} = 0;
7408  let Inst{20-16} = Rm;
7409  let Inst{15-13} = 0;
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_ss<bits<2> sz, string asm, RegisterOperand listty,
7419                           ZPRRegOp zprty, RegisterOperand gprty> {
7420  def NAME : sve_mem_ldqr_ss<sz, asm, listty, gprty>;
7421
7422  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7423                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7424}
7425
7426class sve_mem_ld_dup<bits<2> dtypeh, bits<2> dtypel, string asm,
7427                     RegisterOperand VecList, Operand immtype>
7428: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm6),
7429  asm, "\t$Zt, $Pg/z, [$Rn, $imm6]",
7430  "",
7431  []>, Sched<[]> {
7432  bits<3> Pg;
7433  bits<5> Rn;
7434  bits<5> Zt;
7435  bits<6> imm6;
7436  let Inst{31-25} = 0b1000010;
7437  let Inst{24-23} = dtypeh;
7438  let Inst{22}    = 1;
7439  let Inst{21-16} = imm6;
7440  let Inst{15}    = 0b1;
7441  let Inst{14-13} = dtypel;
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_ld_dup<bits<2> dtypeh, bits<2> dtypel, string asm,
7451                          RegisterOperand zlistty, ZPRRegOp zprty, Operand immtype> {
7452  def NAME : sve_mem_ld_dup<dtypeh, dtypel, asm, zlistty, immtype>;
7453
7454  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7455                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7456  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm6]",
7457                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm6), 0>;
7458  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7459                  (!cast<Instruction>(NAME) zlistty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7460}
7461
7462class sve_mem_cld_ss_base<bits<4> dtype, bit ff, dag iops, string asm,
7463                          RegisterOperand VecList>
7464: I<(outs VecList:$Zt), iops,
7465  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7466  "",
7467  []>, Sched<[]> {
7468  bits<5> Zt;
7469  bits<3> Pg;
7470  bits<5> Rm;
7471  bits<5> Rn;
7472  let Inst{31-25} = 0b1010010;
7473  let Inst{24-21} = dtype;
7474  let Inst{20-16} = Rm;
7475  let Inst{15-14} = 0b01;
7476  let Inst{13}    = ff;
7477  let Inst{12-10} = Pg;
7478  let Inst{9-5}   = Rn;
7479  let Inst{4-0}   = Zt;
7480
7481  let Defs = !if(ff, [FFR], []);
7482  let Uses = !if(ff, [FFR], []);
7483  let hasSideEffects = ff;
7484  let mayLoad = 1;
7485}
7486
7487multiclass sve_mem_cld_ss<bits<4> dtype, string asm, RegisterOperand listty,
7488                          ZPRRegOp zprty, RegisterOperand gprty> {
7489  def "" : sve_mem_cld_ss_base<dtype, 0, (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7490                               asm, listty>;
7491
7492  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7493                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7494}
7495
7496multiclass sve_mem_cldff_ss<bits<4> dtype, string asm, RegisterOperand listty,
7497                            ZPRRegOp zprty, RegisterOperand gprty> {
7498  def _REAL : sve_mem_cld_ss_base<dtype, 1, (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7499                                  asm, listty>;
7500
7501  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7502                 (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7503
7504  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7505                 (!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 1>;
7506
7507  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7508                 (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 0>;
7509
7510  // We need a layer of indirection because early machine code passes balk at
7511  // physical register (i.e. FFR) uses that have no previous definition.
7512  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7513  def "" : Pseudo<(outs listty:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), []>,
7514           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm)>;
7515  }
7516}
7517
7518multiclass sve_mem_cldnf_si<bits<4> dtype, string asm, RegisterOperand listty,
7519                            ZPRRegOp zprty>
7520: sve_mem_cld_si_base<dtype, 1, asm, listty, zprty>;
7521
7522class sve_mem_eld_si<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7523                     string asm, Operand immtype>
7524: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
7525  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7526  "",
7527  []>, Sched<[]> {
7528  bits<5> Zt;
7529  bits<3> Pg;
7530  bits<5> Rn;
7531  bits<4> imm4;
7532  let Inst{31-25} = 0b1010010;
7533  let Inst{24-23} = sz;
7534  let Inst{22-21} = nregs{1-0};
7535  let Inst{20}    = nregs{2};
7536  let Inst{19-16} = imm4;
7537  let Inst{15-13} = 0b111;
7538  let Inst{12-10} = Pg;
7539  let Inst{9-5}   = Rn;
7540  let Inst{4-0}   = Zt;
7541
7542  let hasSideEffects = 0;
7543  let mayLoad = 1;
7544}
7545
7546multiclass sve_mem_eld_si<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7547                          string asm, Operand immtype> {
7548  def NAME : sve_mem_eld_si<sz, nregs, VecList, asm, immtype>;
7549
7550  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7551                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7552}
7553
7554
7555class sve_mem_eld_ss<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7556                     string asm, RegisterOperand gprty>
7557: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7558  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7559  "",
7560  []>, Sched<[]> {
7561  bits<3> Pg;
7562  bits<5> Rm;
7563  bits<5> Rn;
7564  bits<5> Zt;
7565  let Inst{31-25} = 0b1010010;
7566  let Inst{24-23} = sz;
7567  let Inst{22-21} = nregs{1-0};
7568  let Inst{20-16} = Rm;
7569  let Inst{15}    = 0b1;
7570  let Inst{14}    = nregs{2};
7571  let Inst{13}    = 0b0;
7572  let Inst{12-10} = Pg;
7573  let Inst{9-5}   = Rn;
7574  let Inst{4-0}   = Zt;
7575
7576  let hasSideEffects = 0;
7577  let mayLoad = 1;
7578}
7579
7580//===----------------------------------------------------------------------===//
7581// SVE Memory - 32-bit Gather and Unsized Contiguous Group
7582//===----------------------------------------------------------------------===//
7583
7584// bit xs      is '1' if offsets are signed
7585// bit scaled  is '1' if the offsets are scaled
7586class sve_mem_32b_gld_sv<bits<4> opc, bit xs, bit scaled, string asm,
7587                         RegisterOperand zprext>
7588: I<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
7589  asm, "\t$Zt, $Pg/z, [$Rn, $Zm]",
7590  "",
7591  []>, Sched<[]> {
7592  bits<3> Pg;
7593  bits<5> Rn;
7594  bits<5> Zm;
7595  bits<5> Zt;
7596  let Inst{31-25} = 0b1000010;
7597  let Inst{24-23} = opc{3-2};
7598  let Inst{22}    = xs;
7599  let Inst{21}    = scaled;
7600  let Inst{20-16} = Zm;
7601  let Inst{15}    = 0b0;
7602  let Inst{14-13} = opc{1-0};
7603  let Inst{12-10} = Pg;
7604  let Inst{9-5}   = Rn;
7605  let Inst{4-0}   = Zt;
7606
7607
7608  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
7609  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
7610  let hasSideEffects = opc{0};
7611  let mayLoad = 1;
7612}
7613
7614multiclass sve_mem_32b_gld_sv_32_scaled<bits<4> opc, string asm,
7615                                        SDPatternOperator sxtw_op,
7616                                        SDPatternOperator uxtw_op,
7617                                        RegisterOperand sxtw_opnd,
7618                                        RegisterOperand uxtw_opnd,
7619                                        ValueType vt> {
7620  def _UXTW_SCALED_REAL : sve_mem_32b_gld_sv<opc, 0, 1, asm, uxtw_opnd>;
7621  def _SXTW_SCALED_REAL : sve_mem_32b_gld_sv<opc, 1, 1, asm, sxtw_opnd>;
7622
7623  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7624                  (!cast<Instruction>(NAME # _UXTW_SCALED_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
7625  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7626                  (!cast<Instruction>(NAME # _SXTW_SCALED_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
7627
7628  // We need a layer of indirection because early machine code passes balk at
7629  // physical register (i.e. FFR) uses that have no previous definition.
7630  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7631  def _UXTW_SCALED : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
7632                     PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_SCALED_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
7633  def _SXTW_SCALED : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
7634                     PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_SCALED_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
7635  }
7636
7637  def : Pat<(nxv4i32 (uxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$indices), vt)),
7638            (!cast<Instruction>(NAME # _UXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
7639  def : Pat<(nxv4i32 (sxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$indices), vt)),
7640            (!cast<Instruction>(NAME # _SXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
7641}
7642
7643multiclass sve_mem_32b_gld_vs_32_unscaled<bits<4> opc, string asm,
7644                                          SDPatternOperator sxtw_op,
7645                                          SDPatternOperator uxtw_op,
7646                                          RegisterOperand sxtw_opnd,
7647                                          RegisterOperand uxtw_opnd,
7648                                          ValueType vt> {
7649  def _UXTW_REAL : sve_mem_32b_gld_sv<opc, 0, 0, asm, uxtw_opnd>;
7650  def _SXTW_REAL : sve_mem_32b_gld_sv<opc, 1, 0, asm, sxtw_opnd>;
7651
7652  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7653                  (!cast<Instruction>(NAME # _UXTW_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
7654  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7655                  (!cast<Instruction>(NAME # _SXTW_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
7656
7657  // We need a layer of indirection because early machine code passes balk at
7658  // physical register (i.e. FFR) uses that have no previous definition.
7659  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7660  def _UXTW : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
7661              PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
7662  def _SXTW : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
7663              PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
7664  }
7665
7666  def : Pat<(nxv4i32 (uxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt)),
7667            (!cast<Instruction>(NAME # _UXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
7668  def : Pat<(nxv4i32 (sxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt)),
7669            (!cast<Instruction>(NAME # _SXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
7670}
7671
7672
7673class sve_mem_32b_gld_vi<bits<4> opc, string asm, Operand imm_ty>
7674: I<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5),
7675  asm, "\t$Zt, $Pg/z, [$Zn, $imm5]",
7676  "",
7677  []>, Sched<[]> {
7678  bits<3> Pg;
7679  bits<5> Zn;
7680  bits<5> Zt;
7681  bits<5> imm5;
7682  let Inst{31-25} = 0b1000010;
7683  let Inst{24-23} = opc{3-2};
7684  let Inst{22-21} = 0b01;
7685  let Inst{20-16} = imm5;
7686  let Inst{15}    = 0b1;
7687  let Inst{14-13} = opc{1-0};
7688  let Inst{12-10} = Pg;
7689  let Inst{9-5}   = Zn;
7690  let Inst{4-0}   = Zt;
7691
7692
7693  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
7694  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
7695  let hasSideEffects = opc{0};
7696  let mayLoad = 1;
7697}
7698
7699multiclass sve_mem_32b_gld_vi_32_ptrs<bits<4> opc, string asm, Operand imm_ty,
7700                                      SDPatternOperator op, ValueType vt> {
7701  def _IMM_REAL : sve_mem_32b_gld_vi<opc, asm, imm_ty>;
7702
7703  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7704                  (!cast<Instruction>(NAME # _IMM_REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 0>;
7705  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $imm5]",
7706                  (!cast<Instruction>(NAME # _IMM_REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), 0>;
7707  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7708                  (!cast<Instruction>(NAME # _IMM_REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
7709
7710  // We need a layer of indirection because early machine code passes balk at
7711  // physical register (i.e. FFR) uses that have no previous definition.
7712  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7713  def _IMM : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), []>,
7714             PseudoInstExpansion<(!cast<Instruction>(NAME # _IMM_REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5)>;
7715  }
7716
7717  def : Pat<(nxv4i32 (op (nxv4i1 PPR:$gp), (nxv4i32 ZPR:$ptrs), imm_ty:$index, vt)),
7718            (!cast<Instruction>(NAME # _IMM) PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
7719}
7720
7721class sve_mem_prfm_si<bits<2> msz, string asm>
7722: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, simm6s1:$imm6),
7723  asm, "\t$prfop, $Pg, [$Rn, $imm6, mul vl]",
7724  "",
7725  []>, Sched<[]> {
7726  bits<5> Rn;
7727  bits<3> Pg;
7728  bits<6> imm6;
7729  bits<4> prfop;
7730  let Inst{31-22} = 0b1000010111;
7731  let Inst{21-16} = imm6;
7732  let Inst{15}    = 0b0;
7733  let Inst{14-13} = msz;
7734  let Inst{12-10} = Pg;
7735  let Inst{9-5}   = Rn;
7736  let Inst{4}     = 0b0;
7737  let Inst{3-0}   = prfop;
7738
7739  let hasSideEffects = 1;
7740}
7741
7742multiclass sve_mem_prfm_si<bits<2> msz, string asm> {
7743  def NAME : sve_mem_prfm_si<msz, asm>;
7744
7745  def : InstAlias<asm # "\t$prfop, $Pg, [$Rn]",
7746                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7747}
7748
7749class sve_mem_prfm_ss<bits<3> opc, string asm, RegisterOperand gprty>
7750: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7751  asm, "\t$prfop, $Pg, [$Rn, $Rm]",
7752  "",
7753  []>, Sched<[]> {
7754  bits<5> Rm;
7755  bits<5> Rn;
7756  bits<3> Pg;
7757  bits<4> prfop;
7758  let Inst{31-25} = 0b1000010;
7759  let Inst{24-23} = opc{2-1};
7760  let Inst{22-21} = 0b00;
7761  let Inst{20-16} = Rm;
7762  let Inst{15}    = 0b1;
7763  let Inst{14}    = opc{0};
7764  let Inst{13}    = 0b0;
7765  let Inst{12-10} = Pg;
7766  let Inst{9-5}   = Rn;
7767  let Inst{4}     = 0b0;
7768  let Inst{3-0}   = prfop;
7769
7770  let hasSideEffects = 1;
7771}
7772
7773class sve_mem_32b_prfm_sv<bits<2> msz, bit xs, string asm,
7774                          RegisterOperand zprext>
7775: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
7776  asm, "\t$prfop, $Pg, [$Rn, $Zm]",
7777  "",
7778  []>, Sched<[]> {
7779  bits<3> Pg;
7780  bits<5> Rn;
7781  bits<5> Zm;
7782  bits<4> prfop;
7783  let Inst{31-23} = 0b100001000;
7784  let Inst{22}    = xs;
7785  let Inst{21}    = 0b1;
7786  let Inst{20-16} = Zm;
7787  let Inst{15}    = 0b0;
7788  let Inst{14-13} = msz;
7789  let Inst{12-10} = Pg;
7790  let Inst{9-5}   = Rn;
7791  let Inst{4}     = 0b0;
7792  let Inst{3-0}   = prfop;
7793
7794  let hasSideEffects = 1;
7795}
7796
7797multiclass sve_mem_32b_prfm_sv_scaled<bits<2> msz, string asm,
7798                                      RegisterOperand sxtw_opnd,
7799                                      RegisterOperand uxtw_opnd,
7800                                      SDPatternOperator op_sxtw,
7801                                      SDPatternOperator op_uxtw> {
7802  def _UXTW_SCALED : sve_mem_32b_prfm_sv<msz, 0, asm, uxtw_opnd>;
7803  def _SXTW_SCALED : sve_mem_32b_prfm_sv<msz, 1, asm, sxtw_opnd>;
7804
7805  def : Pat<(op_uxtw (nxv4i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv4i32 uxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
7806            (!cast<Instruction>(NAME # _UXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
7807
7808  def : Pat<(op_sxtw (nxv4i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv4i32 sxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
7809            (!cast<Instruction>(NAME # _SXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
7810}
7811
7812class sve_mem_32b_prfm_vi<bits<2> msz, string asm, Operand imm_ty>
7813: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5),
7814  asm, "\t$prfop, $Pg, [$Zn, $imm5]",
7815  "",
7816  []>, Sched<[]> {
7817  bits<3> Pg;
7818  bits<5> Zn;
7819  bits<5> imm5;
7820  bits<4> prfop;
7821  let Inst{31-25} = 0b1000010;
7822  let Inst{24-23} = msz;
7823  let Inst{22-21} = 0b00;
7824  let Inst{20-16} = imm5;
7825  let Inst{15-13} = 0b111;
7826  let Inst{12-10} = Pg;
7827  let Inst{9-5}   = Zn;
7828  let Inst{4}     = 0b0;
7829  let Inst{3-0}   = prfop;
7830
7831  let hasSideEffects = 1;
7832}
7833
7834multiclass sve_mem_32b_prfm_vi<bits<2> msz, string asm, Operand imm_ty, SDPatternOperator op> {
7835  def NAME : sve_mem_32b_prfm_vi<msz, asm, imm_ty>;
7836
7837  def : InstAlias<asm # "\t$prfop, $Pg, [$Zn]",
7838                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
7839
7840  def : Pat<(op (nxv4i1 PPR_3b:$Pg), (nxv4i32 ZPR32:$Zn), (i64 imm_ty:$imm), (i32 sve_prfop:$prfop)),
7841            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR_3b:$Pg, ZPR32:$Zn, imm_ty:$imm)>;
7842}
7843
7844class sve_mem_z_fill<string asm>
7845: I<(outs ZPRAny:$Zt), (ins GPR64sp:$Rn, simm9:$imm9),
7846  asm, "\t$Zt, [$Rn, $imm9, mul vl]",
7847  "",
7848  []>, Sched<[]> {
7849  bits<5> Rn;
7850  bits<5> Zt;
7851  bits<9> imm9;
7852  let Inst{31-22} = 0b1000010110;
7853  let Inst{21-16} = imm9{8-3};
7854  let Inst{15-13} = 0b010;
7855  let Inst{12-10} = imm9{2-0};
7856  let Inst{9-5}   = Rn;
7857  let Inst{4-0}   = Zt;
7858
7859  let hasSideEffects = 0;
7860  let mayLoad = 1;
7861}
7862
7863multiclass sve_mem_z_fill<string asm> {
7864  def NAME : sve_mem_z_fill<asm>;
7865
7866  def : InstAlias<asm # "\t$Zt, [$Rn]",
7867                  (!cast<Instruction>(NAME) ZPRAny:$Zt, GPR64sp:$Rn, 0), 1>;
7868}
7869
7870class sve_mem_p_fill<string asm>
7871: I<(outs PPRAny:$Pt), (ins GPR64sp:$Rn, simm9:$imm9),
7872  asm, "\t$Pt, [$Rn, $imm9, mul vl]",
7873  "",
7874  []>, Sched<[]> {
7875  bits<4> Pt;
7876  bits<5> Rn;
7877  bits<9> imm9;
7878  let Inst{31-22} = 0b1000010110;
7879  let Inst{21-16} = imm9{8-3};
7880  let Inst{15-13} = 0b000;
7881  let Inst{12-10} = imm9{2-0};
7882  let Inst{9-5}   = Rn;
7883  let Inst{4}     = 0b0;
7884  let Inst{3-0}   = Pt;
7885
7886  let hasSideEffects = 0;
7887  let mayLoad = 1;
7888}
7889
7890multiclass sve_mem_p_fill<string asm> {
7891  def NAME : sve_mem_p_fill<asm>;
7892
7893  def : InstAlias<asm # "\t$Pt, [$Rn]",
7894                  (!cast<Instruction>(NAME) PPRAny:$Pt, GPR64sp:$Rn, 0), 1>;
7895}
7896
7897class sve2_mem_gldnt_vs_base<bits<5> opc, dag iops, string asm,
7898                             RegisterOperand VecList>
7899: I<(outs VecList:$Zt), iops,
7900  asm, "\t$Zt, $Pg/z, [$Zn, $Rm]",
7901  "",
7902  []>, Sched<[]> {
7903  bits<3> Pg;
7904  bits<5> Rm;
7905  bits<5> Zn;
7906  bits<5> Zt;
7907  let Inst{31}    = 0b1;
7908  let Inst{30}    = opc{4};
7909  let Inst{29-25} = 0b00010;
7910  let Inst{24-23} = opc{3-2};
7911  let Inst{22-21} = 0b00;
7912  let Inst{20-16} = Rm;
7913  let Inst{15}    = 0b1;
7914  let Inst{14-13} = opc{1-0};
7915  let Inst{12-10} = Pg;
7916  let Inst{9-5}   = Zn;
7917  let Inst{4-0}   = Zt;
7918
7919  let hasSideEffects = 0;
7920  let mayLoad = 1;
7921}
7922
7923multiclass sve2_mem_gldnt_vs_32_ptrs<bits<5> opc, string asm,
7924                                  SDPatternOperator op,
7925                                  ValueType vt> {
7926  def _REAL : sve2_mem_gldnt_vs_base<opc, (ins PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm),
7927                                     asm, Z_s>;
7928
7929  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $Rm]",
7930                 (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm), 0>;
7931  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7932                 (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 0>;
7933  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7934                 (!cast<Instruction>(NAME # _REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 1>;
7935
7936  def : Pat <(nxv4i32 (op (nxv4i1 PPR3bAny:$Pg), (nxv4i32 ZPR32:$Zd), (i64 GPR64:$Rm), vt)),
7937             (!cast<Instruction>(NAME # _REAL) PPR3bAny:$Pg, ZPR32:$Zd, GPR64:$Rm)>;
7938}
7939
7940multiclass sve2_mem_gldnt_vs_64_ptrs<bits<5> opc, string asm,
7941                                   SDPatternOperator op,
7942                                   ValueType vt> {
7943  def _REAL : sve2_mem_gldnt_vs_base<opc, (ins PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
7944                                     asm, Z_d>;
7945
7946  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $Rm]",
7947                 (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm), 0>;
7948  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7949                 (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 0>;
7950  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7951                 (!cast<Instruction>(NAME # _REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
7952
7953  def : Pat <(nxv2i64 (op (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zd), (i64 GPR64:$Rm), vt)),
7954             (!cast<Instruction>(NAME # _REAL) PPR3bAny:$Pg, ZPR64:$Zd, GPR64:$Rm)>;
7955}
7956
7957//===----------------------------------------------------------------------===//
7958// SVE Memory - 64-bit Gather Group
7959//===----------------------------------------------------------------------===//
7960
7961// bit xs      is '1' if offsets are signed
7962// bit scaled  is '1' if the offsets are scaled
7963// bit lsl     is '0' if the offsets are extended (uxtw/sxtw), '1' if shifted (lsl)
7964class sve_mem_64b_gld_sv<bits<4> opc, bit xs, bit scaled, bit lsl, string asm,
7965                         RegisterOperand zprext>
7966: I<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
7967  asm, "\t$Zt, $Pg/z, [$Rn, $Zm]",
7968  "",
7969  []>, Sched<[]> {
7970  bits<3> Pg;
7971  bits<5> Rn;
7972  bits<5> Zm;
7973  bits<5> Zt;
7974  let Inst{31-25} = 0b1100010;
7975  let Inst{24-23} = opc{3-2};
7976  let Inst{22}    = xs;
7977  let Inst{21}    = scaled;
7978  let Inst{20-16} = Zm;
7979  let Inst{15}    = lsl;
7980  let Inst{14-13} = opc{1-0};
7981  let Inst{12-10} = Pg;
7982  let Inst{9-5}   = Rn;
7983  let Inst{4-0}   = Zt;
7984
7985
7986  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
7987  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
7988  let hasSideEffects = opc{0};
7989  let mayLoad = 1;
7990}
7991
7992multiclass sve_mem_64b_gld_sv_32_scaled<bits<4> opc, string asm,
7993                                        SDPatternOperator sxtw_op,
7994                                        SDPatternOperator uxtw_op,
7995                                        RegisterOperand sxtw_opnd,
7996                                        RegisterOperand uxtw_opnd,
7997                                        ValueType vt> {
7998  def _UXTW_SCALED_REAL : sve_mem_64b_gld_sv<opc, 0, 1, 0, asm, uxtw_opnd>;
7999  def _SXTW_SCALED_REAL : sve_mem_64b_gld_sv<opc, 1, 1, 0, asm, sxtw_opnd>;
8000
8001  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8002                  (!cast<Instruction>(NAME # _UXTW_SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
8003  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8004                  (!cast<Instruction>(NAME # _SXTW_SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
8005
8006  // We need a layer of indirection because early machine code passes balk at
8007  // physical register (i.e. FFR) uses that have no previous definition.
8008  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8009  def _UXTW_SCALED : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
8010                     PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_SCALED_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8011  def _SXTW_SCALED : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
8012                     PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_SCALED_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8013  }
8014
8015  def : Pat<(nxv2i64 (uxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8016            (!cast<Instruction>(NAME # _UXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8017  def : Pat<(nxv2i64 (sxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8018            (!cast<Instruction>(NAME # _SXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8019}
8020
8021multiclass sve_mem_64b_gld_vs_32_unscaled<bits<4> opc, string asm,
8022                                          SDPatternOperator sxtw_op,
8023                                          SDPatternOperator uxtw_op,
8024                                          RegisterOperand sxtw_opnd,
8025                                          RegisterOperand uxtw_opnd,
8026                                          ValueType vt> {
8027  def _UXTW_REAL : sve_mem_64b_gld_sv<opc, 0, 0, 0, asm, uxtw_opnd>;
8028  def _SXTW_REAL : sve_mem_64b_gld_sv<opc, 1, 0, 0, asm, sxtw_opnd>;
8029
8030  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8031                  (!cast<Instruction>(NAME # _UXTW_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
8032  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8033                  (!cast<Instruction>(NAME # _SXTW_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
8034
8035  // We need a layer of indirection because early machine code passes balk at
8036  // physical register (i.e. FFR) uses that have no previous definition.
8037  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8038  def _UXTW : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
8039              PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8040  def _SXTW : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
8041              PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8042  }
8043
8044  def : Pat<(nxv2i64 (uxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8045            (!cast<Instruction>(NAME # _UXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8046  def : Pat<(nxv2i64 (sxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8047            (!cast<Instruction>(NAME # _SXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8048}
8049
8050multiclass sve_mem_64b_gld_sv2_64_scaled<bits<4> opc, string asm,
8051                                         SDPatternOperator op,
8052                                         RegisterOperand zprext, ValueType vt> {
8053  def _SCALED_REAL : sve_mem_64b_gld_sv<opc, 1, 1, 1, asm, zprext>;
8054
8055  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8056                  (!cast<Instruction>(NAME # _SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), 0>;
8057
8058  // We need a layer of indirection because early machine code passes balk at
8059  // physical register (i.e. FFR) uses that have no previous definition.
8060  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8061  def _SCALED : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), []>,
8062                PseudoInstExpansion<(!cast<Instruction>(NAME # _SCALED_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm)>;
8063  }
8064
8065  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8066                     (!cast<Instruction>(NAME # _SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8067}
8068
8069multiclass sve_mem_64b_gld_vs2_64_unscaled<bits<4> opc, string asm,
8070                                           SDPatternOperator op, ValueType vt> {
8071  def _REAL : sve_mem_64b_gld_sv<opc, 1, 0, 1, asm, ZPR64ExtLSL8>;
8072
8073  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8074                  (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), 0>;
8075
8076  // We need a layer of indirection because early machine code passes balk at
8077  // physical register (i.e. FFR) uses that have no previous definition.
8078  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8079  def "" : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), []>,
8080           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm)>;
8081  }
8082
8083  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8084            (!cast<Instruction>(NAME) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8085}
8086
8087class sve_mem_64b_gld_vi<bits<4> opc, string asm, Operand imm_ty>
8088: I<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5),
8089  asm, "\t$Zt, $Pg/z, [$Zn, $imm5]",
8090  "",
8091  []>, Sched<[]> {
8092  bits<3> Pg;
8093  bits<5> Zn;
8094  bits<5> Zt;
8095  bits<5> imm5;
8096  let Inst{31-25} = 0b1100010;
8097  let Inst{24-23} = opc{3-2};
8098  let Inst{22-21} = 0b01;
8099  let Inst{20-16} = imm5;
8100  let Inst{15}    = 0b1;
8101  let Inst{14-13} = opc{1-0};
8102  let Inst{12-10} = Pg;
8103  let Inst{9-5}   = Zn;
8104  let Inst{4-0}   = Zt;
8105
8106  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
8107  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
8108  let hasSideEffects = opc{0};
8109  let mayLoad = 1;
8110}
8111
8112multiclass sve_mem_64b_gld_vi_64_ptrs<bits<4> opc, string asm, Operand imm_ty,
8113                                      SDPatternOperator op, ValueType vt> {
8114  def _IMM_REAL : sve_mem_64b_gld_vi<opc, asm, imm_ty>;
8115
8116  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8117                  (!cast<Instruction>(NAME # _IMM_REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 0>;
8118  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $imm5]",
8119                 (!cast<Instruction>(NAME # _IMM_REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), 0>;
8120  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8121                  (!cast<Instruction>(NAME # _IMM_REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
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 _IMM : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), []>,
8127                  PseudoInstExpansion<(!cast<Instruction>(NAME # _IMM_REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5)>;
8128  }
8129
8130  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), (nxv2i64 ZPR:$ptrs), imm_ty:$index, vt)),
8131            (!cast<Instruction>(NAME # _IMM) PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
8132}
8133
8134// bit lsl is '0' if the offsets are extended (uxtw/sxtw), '1' if shifted (lsl)
8135class sve_mem_64b_prfm_sv<bits<2> msz, bit xs, bit lsl, string asm,
8136                          RegisterOperand zprext>
8137: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
8138  asm, "\t$prfop, $Pg, [$Rn, $Zm]",
8139  "",
8140  []>, Sched<[]> {
8141  bits<3> Pg;
8142  bits<5> Rn;
8143  bits<5> Zm;
8144  bits<4> prfop;
8145  let Inst{31-23} = 0b110001000;
8146  let Inst{22}    = xs;
8147  let Inst{21}    = 0b1;
8148  let Inst{20-16} = Zm;
8149  let Inst{15}    = lsl;
8150  let Inst{14-13} = msz;
8151  let Inst{12-10} = Pg;
8152  let Inst{9-5}   = Rn;
8153  let Inst{4}     = 0b0;
8154  let Inst{3-0}   = prfop;
8155
8156  let hasSideEffects = 1;
8157}
8158
8159multiclass sve_mem_64b_prfm_sv_ext_scaled<bits<2> msz, string asm,
8160                                          RegisterOperand sxtw_opnd,
8161                                          RegisterOperand uxtw_opnd,
8162                                          SDPatternOperator op_sxtw,
8163                                          SDPatternOperator op_uxtw> {
8164  def _UXTW_SCALED : sve_mem_64b_prfm_sv<msz, 0, 0, asm, uxtw_opnd>;
8165  def _SXTW_SCALED : sve_mem_64b_prfm_sv<msz, 1, 0, asm, sxtw_opnd>;
8166
8167  def : Pat<(op_uxtw (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 uxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
8168            (!cast<Instruction>(NAME # _UXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8169
8170  def : Pat<(op_sxtw (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 sxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
8171            (!cast<Instruction>(NAME # _SXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8172
8173}
8174
8175multiclass sve_mem_64b_prfm_sv_lsl_scaled<bits<2> msz, string asm,
8176                                          RegisterOperand zprext, SDPatternOperator frag> {
8177  def NAME : sve_mem_64b_prfm_sv<msz, 1, 1, asm, zprext>;
8178
8179  def : Pat<(frag (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 zprext:$Zm), (i32 sve_prfop:$prfop)),
8180            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm)>;
8181
8182}
8183
8184class sve_mem_64b_prfm_vi<bits<2> msz, string asm, Operand imm_ty>
8185: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5),
8186  asm, "\t$prfop, $Pg, [$Zn, $imm5]",
8187  "",
8188  []>, Sched<[]> {
8189  bits<3> Pg;
8190  bits<5> Zn;
8191  bits<5> imm5;
8192  bits<4> prfop;
8193  let Inst{31-25} = 0b1100010;
8194  let Inst{24-23} = msz;
8195  let Inst{22-21} = 0b00;
8196  let Inst{20-16} = imm5;
8197  let Inst{15-13} = 0b111;
8198  let Inst{12-10} = Pg;
8199  let Inst{9-5}   = Zn;
8200  let Inst{4}     = 0b0;
8201  let Inst{3-0}   = prfop;
8202
8203  let hasSideEffects = 1;
8204}
8205
8206multiclass sve_mem_64b_prfm_vi<bits<2> msz, string asm, Operand imm_ty, SDPatternOperator op> {
8207  def NAME : sve_mem_64b_prfm_vi<msz, asm, imm_ty>;
8208
8209  def : InstAlias<asm # "\t$prfop, $Pg, [$Zn]",
8210                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
8211
8212  def : Pat<(op (nxv2i1 PPR_3b:$Pg), (nxv2i64 ZPR32:$Zn), (i64 imm_ty:$imm), (i32 sve_prfop:$prfop)),
8213            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR_3b:$Pg, ZPR32:$Zn, imm_ty:$imm)>;
8214}
8215
8216//===----------------------------------------------------------------------===//
8217// SVE Compute Vector Address Group
8218//===----------------------------------------------------------------------===//
8219
8220class sve_int_bin_cons_misc_0_a<bits<2> opc, bits<2> msz, string asm,
8221                                ZPRRegOp zprty, RegisterOperand zprext>
8222: I<(outs zprty:$Zd), (ins zprty:$Zn, zprext:$Zm),
8223  asm, "\t$Zd, [$Zn, $Zm]",
8224  "",
8225  []>, Sched<[]> {
8226  bits<5> Zd;
8227  bits<5> Zn;
8228  bits<5> Zm;
8229  let Inst{31-24} = 0b00000100;
8230  let Inst{23-22} = opc;
8231  let Inst{21}    = 0b1;
8232  let Inst{20-16} = Zm;
8233  let Inst{15-12} = 0b1010;
8234  let Inst{11-10} = msz;
8235  let Inst{9-5}   = Zn;
8236  let Inst{4-0}   = Zd;
8237
8238  let hasSideEffects = 0;
8239}
8240
8241multiclass sve_int_bin_cons_misc_0_a_uxtw<bits<2> opc, string asm> {
8242  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtUXTW8>;
8243  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtUXTW16>;
8244  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtUXTW32>;
8245  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtUXTW64>;
8246}
8247
8248multiclass sve_int_bin_cons_misc_0_a_sxtw<bits<2> opc, string asm> {
8249  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtSXTW8>;
8250  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtSXTW16>;
8251  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtSXTW32>;
8252  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtSXTW64>;
8253}
8254
8255multiclass sve_int_bin_cons_misc_0_a_32_lsl<bits<2> opc, string asm> {
8256  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR32, ZPR32ExtLSL8>;
8257  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR32, ZPR32ExtLSL16>;
8258  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR32, ZPR32ExtLSL32>;
8259  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR32, ZPR32ExtLSL64>;
8260}
8261
8262multiclass sve_int_bin_cons_misc_0_a_64_lsl<bits<2> opc, string asm> {
8263  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtLSL8>;
8264  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtLSL16>;
8265  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtLSL32>;
8266  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtLSL64>;
8267}
8268
8269//===----------------------------------------------------------------------===//
8270// SVE Integer Misc - Unpredicated Group
8271//===----------------------------------------------------------------------===//
8272
8273class sve_int_bin_cons_misc_0_b<bits<2> sz, string asm, ZPRRegOp zprty>
8274: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
8275  asm, "\t$Zd, $Zn, $Zm",
8276  "",
8277  []>, Sched<[]> {
8278  bits<5> Zd;
8279  bits<5> Zm;
8280  bits<5> Zn;
8281  let Inst{31-24} = 0b00000100;
8282  let Inst{23-22} = sz;
8283  let Inst{21}    = 0b1;
8284  let Inst{20-16} = Zm;
8285  let Inst{15-10} = 0b101100;
8286  let Inst{9-5}   = Zn;
8287  let Inst{4-0}   = Zd;
8288
8289  let hasSideEffects = 0;
8290}
8291
8292multiclass sve_int_bin_cons_misc_0_b<string asm, SDPatternOperator op> {
8293  def _H : sve_int_bin_cons_misc_0_b<0b01, asm, ZPR16>;
8294  def _S : sve_int_bin_cons_misc_0_b<0b10, asm, ZPR32>;
8295  def _D : sve_int_bin_cons_misc_0_b<0b11, asm, ZPR64>;
8296
8297  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
8298  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
8299  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
8300}
8301
8302class sve_int_bin_cons_misc_0_c<bits<8> opc, string asm, ZPRRegOp zprty>
8303: I<(outs zprty:$Zd), (ins zprty:$Zn),
8304  asm, "\t$Zd, $Zn",
8305  "",
8306  []>, Sched<[]> {
8307  bits<5> Zd;
8308  bits<5> Zn;
8309  let Inst{31-24} = 0b00000100;
8310  let Inst{23-22} = opc{7-6};
8311  let Inst{21}    = 0b1;
8312  let Inst{20-16} = opc{5-1};
8313  let Inst{15-11} = 0b10111;
8314  let Inst{10}    = opc{0};
8315  let Inst{9-5}   = Zn;
8316  let Inst{4-0}   = Zd;
8317
8318  let hasSideEffects = 0;
8319}
8320
8321multiclass sve_int_bin_cons_misc_0_c_fexpa<string asm, SDPatternOperator op> {
8322  def _H : sve_int_bin_cons_misc_0_c<0b01000000, asm, ZPR16>;
8323  def _S : sve_int_bin_cons_misc_0_c<0b10000000, asm, ZPR32>;
8324  def _D : sve_int_bin_cons_misc_0_c<0b11000000, asm, ZPR64>;
8325
8326  def : SVE_1_Op_Pat<nxv8f16, op, nxv8i16, !cast<Instruction>(NAME # _H)>;
8327  def : SVE_1_Op_Pat<nxv4f32, op, nxv4i32, !cast<Instruction>(NAME # _S)>;
8328  def : SVE_1_Op_Pat<nxv2f64, op, nxv2i64, !cast<Instruction>(NAME # _D)>;
8329}
8330
8331//===----------------------------------------------------------------------===//
8332// SVE Integer Reduction Group
8333//===----------------------------------------------------------------------===//
8334
8335class sve_int_reduce<bits<2> sz8_32, bits<2> fmt, bits<3> opc, string asm,
8336                     ZPRRegOp zprty, FPRasZPROperand dstOpType>
8337: I<(outs dstOpType:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
8338  asm, "\t$Vd, $Pg, $Zn",
8339  "",
8340  []>, Sched<[]> {
8341  bits<3> Pg;
8342  bits<5> Vd;
8343  bits<5> Zn;
8344  let Inst{31-24} = 0b00000100;
8345  let Inst{23-22} = sz8_32;
8346  let Inst{21}    = 0b0;
8347  let Inst{20-19} = fmt;
8348  let Inst{18-16} = opc;
8349  let Inst{15-13} = 0b001;
8350  let Inst{12-10} = Pg;
8351  let Inst{9-5}   = Zn;
8352  let Inst{4-0}   = Vd;
8353
8354  let hasSideEffects = 0;
8355}
8356
8357multiclass sve_int_reduce_0_saddv<bits<3> opc, string asm,
8358                                  SDPatternOperator op> {
8359  def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
8360  def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
8361  def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
8362
8363  def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8364  def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8365  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8366}
8367
8368multiclass sve_int_reduce_0_uaddv<bits<3> opc, string asm,
8369                                  SDPatternOperator op> {
8370  def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
8371  def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
8372  def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
8373  def _D : sve_int_reduce<0b11, 0b00, opc, asm, ZPR64, FPR64asZPR>;
8374
8375  def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8376  def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8377  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8378  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8379}
8380
8381multiclass sve_int_reduce_1<bits<3> opc, string asm,
8382                            SDPatternOperator op> {
8383  def _B : sve_int_reduce<0b00, 0b01, opc, asm, ZPR8, FPR8asZPR>;
8384  def _H : sve_int_reduce<0b01, 0b01, opc, asm, ZPR16, FPR16asZPR>;
8385  def _S : sve_int_reduce<0b10, 0b01, opc, asm, ZPR32, FPR32asZPR>;
8386  def _D : sve_int_reduce<0b11, 0b01, opc, asm, ZPR64, FPR64asZPR>;
8387
8388  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8389  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8390  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8391  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8392}
8393
8394multiclass sve_int_reduce_2<bits<3> opc, string asm,
8395                            SDPatternOperator op> {
8396  def _B : sve_int_reduce<0b00, 0b11, opc, asm, ZPR8, FPR8asZPR>;
8397  def _H : sve_int_reduce<0b01, 0b11, opc, asm, ZPR16, FPR16asZPR>;
8398  def _S : sve_int_reduce<0b10, 0b11, opc, asm, ZPR32, FPR32asZPR>;
8399  def _D : sve_int_reduce<0b11, 0b11, opc, asm, ZPR64, FPR64asZPR>;
8400
8401  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8402  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8403  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8404  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8405}
8406
8407class sve_int_movprfx_pred<bits<2> sz8_32, bits<3> opc, string asm,
8408                           ZPRRegOp zprty, string pg_suffix, dag iops>
8409: I<(outs zprty:$Zd), iops,
8410  asm, "\t$Zd, $Pg"#pg_suffix#", $Zn",
8411  "",
8412  []>, Sched<[]> {
8413  bits<3> Pg;
8414  bits<5> Zd;
8415  bits<5> Zn;
8416  let Inst{31-24} = 0b00000100;
8417  let Inst{23-22} = sz8_32;
8418  let Inst{21-19} = 0b010;
8419  let Inst{18-16} = opc;
8420  let Inst{15-13} = 0b001;
8421  let Inst{12-10} = Pg;
8422  let Inst{9-5}   = Zn;
8423  let Inst{4-0}   = Zd;
8424
8425  let ElementSize = zprty.ElementSize;
8426  let hasSideEffects = 0;
8427}
8428
8429multiclass sve_int_movprfx_pred_merge<bits<3> opc, string asm> {
8430let Constraints = "$Zd = $_Zd" in {
8431  def _B : sve_int_movprfx_pred<0b00, opc, asm, ZPR8, "/m",
8432                                (ins ZPR8:$_Zd, PPR3bAny:$Pg, ZPR8:$Zn)>;
8433  def _H : sve_int_movprfx_pred<0b01, opc, asm, ZPR16, "/m",
8434                                (ins ZPR16:$_Zd, PPR3bAny:$Pg, ZPR16:$Zn)>;
8435  def _S : sve_int_movprfx_pred<0b10, opc, asm, ZPR32, "/m",
8436                                (ins ZPR32:$_Zd, PPR3bAny:$Pg, ZPR32:$Zn)>;
8437  def _D : sve_int_movprfx_pred<0b11, opc, asm, ZPR64, "/m",
8438                                (ins ZPR64:$_Zd, PPR3bAny:$Pg, ZPR64:$Zn)>;
8439}
8440}
8441
8442multiclass sve_int_movprfx_pred_zero<bits<3> opc, string asm> {
8443  def _B : sve_int_movprfx_pred<0b00, opc, asm, ZPR8, "/z",
8444                                (ins PPR3bAny:$Pg, ZPR8:$Zn)>;
8445  def _H : sve_int_movprfx_pred<0b01, opc, asm, ZPR16, "/z",
8446                                (ins PPR3bAny:$Pg, ZPR16:$Zn)>;
8447  def _S : sve_int_movprfx_pred<0b10, opc, asm, ZPR32, "/z",
8448                                (ins PPR3bAny:$Pg, ZPR32:$Zn)>;
8449  def _D : sve_int_movprfx_pred<0b11, opc, asm, ZPR64, "/z",
8450                                (ins PPR3bAny:$Pg, ZPR64:$Zn)>;
8451}
8452
8453//===----------------------------------------------------------------------===//
8454// SVE Propagate Break Group
8455//===----------------------------------------------------------------------===//
8456
8457class sve_int_brkp<bits<2> opc, string asm>
8458: I<(outs PPR8:$Pd), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$Pm),
8459  asm, "\t$Pd, $Pg/z, $Pn, $Pm",
8460  "",
8461  []>, Sched<[]> {
8462  bits<4> Pd;
8463  bits<4> Pg;
8464  bits<4> Pm;
8465  bits<4> Pn;
8466  let Inst{31-24} = 0b00100101;
8467  let Inst{23}    = 0b0;
8468  let Inst{22}    = opc{1};
8469  let Inst{21-20} = 0b00;
8470  let Inst{19-16} = Pm;
8471  let Inst{15-14} = 0b11;
8472  let Inst{13-10} = Pg;
8473  let Inst{9}     = 0b0;
8474  let Inst{8-5}   = Pn;
8475  let Inst{4}     = opc{0};
8476  let Inst{3-0}   = Pd;
8477
8478  let Defs = !if(!eq (opc{1}, 1), [NZCV], []);
8479  let hasSideEffects = 0;
8480}
8481
8482multiclass sve_int_brkp<bits<2> opc, string asm, SDPatternOperator op> {
8483  def NAME : sve_int_brkp<opc, asm>;
8484
8485  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8486}
8487
8488
8489//===----------------------------------------------------------------------===//
8490// SVE Partition Break Group
8491//===----------------------------------------------------------------------===//
8492
8493class sve_int_brkn<bit S, string asm>
8494: I<(outs PPR8:$Pdm), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$_Pdm),
8495  asm, "\t$Pdm, $Pg/z, $Pn, $_Pdm",
8496  "",
8497  []>, Sched<[]> {
8498  bits<4> Pdm;
8499  bits<4> Pg;
8500  bits<4> Pn;
8501  let Inst{31-23} = 0b001001010;
8502  let Inst{22}    = S;
8503  let Inst{21-14} = 0b01100001;
8504  let Inst{13-10} = Pg;
8505  let Inst{9}     = 0b0;
8506  let Inst{8-5}   = Pn;
8507  let Inst{4}     = 0b0;
8508  let Inst{3-0}   = Pdm;
8509
8510  let Constraints = "$Pdm = $_Pdm";
8511  let Defs = !if(S, [NZCV], []);
8512  let ElementSize = ElementSizeB;
8513  let hasSideEffects = 0;
8514}
8515
8516multiclass sve_int_brkn<bits<1> opc, string asm, SDPatternOperator op> {
8517  def NAME : sve_int_brkn<opc, asm>;
8518
8519  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8520}
8521
8522class sve_int_break<bits<3> opc, string asm, string suffix, dag iops>
8523: I<(outs PPR8:$Pd), iops,
8524  asm, "\t$Pd, $Pg"#suffix#", $Pn",
8525  "",
8526  []>, Sched<[]> {
8527  bits<4> Pd;
8528  bits<4> Pg;
8529  bits<4> Pn;
8530  let Inst{31-24} = 0b00100101;
8531  let Inst{23-22} = opc{2-1};
8532  let Inst{21-14} = 0b01000001;
8533  let Inst{13-10} = Pg;
8534  let Inst{9}     = 0b0;
8535  let Inst{8-5}   = Pn;
8536  let Inst{4}     = opc{0};
8537  let Inst{3-0}   = Pd;
8538
8539  let Constraints = !if(!eq (opc{0}, 1), "$Pd = $_Pd", "");
8540  let Defs = !if(!eq (opc{1}, 1), [NZCV], []);
8541  let hasSideEffects = 0;
8542}
8543
8544multiclass sve_int_break_m<bits<3> opc, string asm, SDPatternOperator op> {
8545  def NAME : sve_int_break<opc, asm, "/m", (ins PPR8:$_Pd, PPRAny:$Pg, PPR8:$Pn)>;
8546
8547  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8548}
8549
8550multiclass sve_int_break_z<bits<3> opc, string asm, SDPatternOperator op> {
8551  def NAME : sve_int_break<opc, asm, "/z", (ins PPRAny:$Pg, PPR8:$Pn)>;
8552
8553  def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8554}
8555
8556//===----------------------------------------------------------------------===//
8557// SVE2 String Processing Group
8558//===----------------------------------------------------------------------===//
8559
8560class sve2_char_match<bit sz, bit opc, string asm,
8561                      PPRRegOp pprty, ZPRRegOp zprty>
8562: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
8563  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
8564  "",
8565  []>, Sched<[]> {
8566  bits<4> Pd;
8567  bits<3> Pg;
8568  bits<5> Zm;
8569  bits<5> Zn;
8570  let Inst{31-23} = 0b010001010;
8571  let Inst{22}    = sz;
8572  let Inst{21}    = 0b1;
8573  let Inst{20-16} = Zm;
8574  let Inst{15-13} = 0b100;
8575  let Inst{12-10} = Pg;
8576  let Inst{9-5}   = Zn;
8577  let Inst{4}     = opc;
8578  let Inst{3-0}   = Pd;
8579
8580  let Defs = [NZCV];
8581  let ElementSize = pprty.ElementSize;
8582  let hasSideEffects = 0;
8583  let isPTestLike = 1;
8584}
8585
8586multiclass sve2_char_match<bit opc, string asm, SDPatternOperator op> {
8587  def _B : sve2_char_match<0b0, opc, asm, PPR8, ZPR8>;
8588  def _H : sve2_char_match<0b1, opc, asm, PPR16, ZPR16>;
8589
8590  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
8591  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
8592}
8593
8594//===----------------------------------------------------------------------===//
8595// SVE2 Histogram Computation - Segment Group
8596//===----------------------------------------------------------------------===//
8597
8598class sve2_hist_gen_segment<string asm, SDPatternOperator op>
8599: I<(outs ZPR8:$Zd), (ins ZPR8:$Zn, ZPR8:$Zm),
8600  asm, "\t$Zd, $Zn, $Zm",
8601  "",
8602  [(set nxv16i8:$Zd, (op nxv16i8:$Zn, nxv16i8:$Zm))]>, Sched<[]> {
8603  bits<5> Zd;
8604  bits<5> Zn;
8605  bits<5> Zm;
8606  let Inst{31-21} = 0b01000101001;
8607  let Inst{20-16} = Zm;
8608  let Inst{15-10} = 0b101000;
8609  let Inst{9-5}   = Zn;
8610  let Inst{4-0}   = Zd;
8611
8612  let hasSideEffects = 0;
8613}
8614
8615//===----------------------------------------------------------------------===//
8616// SVE2 Histogram Computation - Vector Group
8617//===----------------------------------------------------------------------===//
8618
8619class sve2_hist_gen_vector<bit sz, string asm, ZPRRegOp zprty>
8620: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
8621  asm, "\t$Zd, $Pg/z, $Zn, $Zm",
8622  "",
8623  []>, Sched<[]> {
8624  bits<5> Zd;
8625  bits<5> Zn;
8626  bits<3> Pg;
8627  bits<5> Zm;
8628  let Inst{31-23} = 0b010001011;
8629  let Inst{22}    = sz;
8630  let Inst{21}    = 0b1;
8631  let Inst{20-16} = Zm;
8632  let Inst{15-13} = 0b110;
8633  let Inst{12-10} = Pg;
8634  let Inst{9-5}   = Zn;
8635  let Inst{4-0}   = Zd;
8636
8637  let hasSideEffects = 0;
8638}
8639
8640multiclass sve2_hist_gen_vector<string asm, SDPatternOperator op> {
8641  def _S : sve2_hist_gen_vector<0b0, asm, ZPR32>;
8642  def _D : sve2_hist_gen_vector<0b1, asm, ZPR64>;
8643
8644  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
8645  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
8646}
8647
8648//===----------------------------------------------------------------------===//
8649// SVE2 Crypto Extensions Group
8650//===----------------------------------------------------------------------===//
8651
8652class sve2_crypto_cons_bin_op<bit opc, string asm, ZPRRegOp zprty>
8653: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
8654  asm, "\t$Zd, $Zn, $Zm",
8655  "",
8656  []>, Sched<[]> {
8657  bits<5> Zd;
8658  bits<5> Zn;
8659  bits<5> Zm;
8660  let Inst{31-21} = 0b01000101001;
8661  let Inst{20-16} = Zm;
8662  let Inst{15-11} = 0b11110;
8663  let Inst{10}    = opc;
8664  let Inst{9-5}   = Zn;
8665  let Inst{4-0}   = Zd;
8666
8667  let hasSideEffects = 0;
8668}
8669
8670multiclass sve2_crypto_cons_bin_op<bit opc, string asm, ZPRRegOp zprty,
8671                                   SDPatternOperator op, ValueType vt> {
8672  def NAME : sve2_crypto_cons_bin_op<opc, asm, zprty>;
8673  def : SVE_2_Op_Pat<vt, op, vt, vt, !cast<Instruction>(NAME)>;
8674}
8675
8676class sve2_crypto_des_bin_op<bits<2> opc, string asm, ZPRRegOp zprty>
8677: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm),
8678  asm, "\t$Zdn, $_Zdn, $Zm",
8679  "",
8680  []>, Sched<[]> {
8681  bits<5> Zdn;
8682  bits<5> Zm;
8683  let Inst{31-17} = 0b010001010010001;
8684  let Inst{16}    = opc{1};
8685  let Inst{15-11} = 0b11100;
8686  let Inst{10}    = opc{0};
8687  let Inst{9-5}   = Zm;
8688  let Inst{4-0}   = Zdn;
8689
8690  let Constraints = "$Zdn = $_Zdn";
8691  let hasSideEffects = 0;
8692}
8693
8694multiclass sve2_crypto_des_bin_op<bits<2> opc, string asm, ZPRRegOp zprty,
8695                                  SDPatternOperator op, ValueType vt> {
8696  def NAME : sve2_crypto_des_bin_op<opc, asm, zprty>;
8697  def : SVE_2_Op_Pat<vt, op, vt, vt, !cast<Instruction>(NAME)>;
8698}
8699
8700class sve2_crypto_unary_op<bit opc, string asm, ZPRRegOp zprty>
8701: I<(outs zprty:$Zdn), (ins zprty:$_Zdn),
8702  asm, "\t$Zdn, $_Zdn",
8703  "",
8704  []>, Sched<[]> {
8705  bits<5> Zdn;
8706  let Inst{31-11} = 0b010001010010000011100;
8707  let Inst{10}    = opc;
8708  let Inst{9-5}   = 0b00000;
8709  let Inst{4-0}   = Zdn;
8710
8711  let Constraints = "$Zdn = $_Zdn";
8712  let hasSideEffects = 0;
8713}
8714
8715multiclass sve2_crypto_unary_op<bit opc, string asm, SDPatternOperator op> {
8716  def NAME : sve2_crypto_unary_op<opc, asm, ZPR8>;
8717  def : SVE_1_Op_Pat<nxv16i8, op, nxv16i8, !cast<Instruction>(NAME)>;
8718}
8719
8720//===----------------------------------------------------------------------===//
8721// SVE BFloat16 Group
8722//===----------------------------------------------------------------------===//
8723
8724class sve_float_dot<bit bf, string asm>
8725: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
8726     asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8727  bits<5> Zda;
8728  bits<5> Zn;
8729  bits<5> Zm;
8730  let Inst{31-23} = 0b011001000;
8731  let Inst{22}    = bf;
8732  let Inst{21}    = 0b1;
8733  let Inst{20-16} = Zm;
8734  let Inst{15-10} = 0b100000;
8735  let Inst{9-5}   = Zn;
8736  let Inst{4-0}   = Zda;
8737
8738  let Constraints = "$Zda = $_Zda";
8739  let DestructiveInstType = DestructiveOther;
8740  let hasSideEffects = 0;
8741  let mayRaiseFPException = 1;
8742}
8743
8744multiclass sve_float_dot<bit bf, string asm, ValueType InVT, SDPatternOperator op> {
8745  def NAME : sve_float_dot<bf, asm>;
8746  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, InVT, InVT, !cast<Instruction>(NAME)>;
8747}
8748
8749class sve_float_dot_indexed<bit bf, string asm>
8750: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR3b16:$Zm, VectorIndexS32b:$iop),
8751    asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
8752  bits<5> Zda;
8753  bits<5> Zn;
8754  bits<3> Zm;
8755  bits<2> iop;
8756  let Inst{31-23} = 0b011001000;
8757  let Inst{22}    = bf;
8758  let Inst{21}    = 0b1;
8759  let Inst{20-19} = iop;
8760  let Inst{18-16} = Zm;
8761  let Inst{15-10} = 0b010000;
8762  let Inst{9-5}   = Zn;
8763  let Inst{4-0}   = Zda;
8764
8765  let Constraints = "$Zda = $_Zda";
8766  let DestructiveInstType = DestructiveOther;
8767  let hasSideEffects = 0;
8768  let mayRaiseFPException = 1;
8769}
8770
8771multiclass sve_float_dot_indexed<bit bf, string asm, ValueType InVT, SDPatternOperator op> {
8772  def NAME : sve_float_dot_indexed<bf, asm>;
8773  def : SVE_4_Op_Imm_Pat<nxv4f32, op, nxv4f32, InVT, InVT, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
8774}
8775
8776class sve_bfloat_matmul<string asm>
8777: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
8778  asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8779  bits<5> Zm;
8780  bits<5> Zda;
8781  bits<5> Zn;
8782  let Inst{31-21} = 0b01100100011;
8783  let Inst{20-16} = Zm;
8784  let Inst{15-10} = 0b111001;
8785  let Inst{9-5}   = Zn;
8786  let Inst{4-0}   = Zda;
8787
8788  let Constraints = "$Zda = $_Zda";
8789  let DestructiveInstType = DestructiveOther;
8790  let ElementSize = ElementSizeH;
8791  let hasSideEffects = 0;
8792  let mayRaiseFPException = 1;
8793}
8794
8795multiclass sve_bfloat_matmul<string asm, SDPatternOperator op> {
8796  def NAME : sve_bfloat_matmul<asm>;
8797  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv8bf16, nxv8bf16 ,!cast<Instruction>(NAME)>;
8798}
8799
8800class sve_bfloat_convert<bit N, string asm>
8801: I<(outs ZPR16:$Zd), (ins ZPR16:$_Zd, PPR3bAny:$Pg, ZPR32:$Zn),
8802  asm, "\t$Zd, $Pg/m, $Zn", "", []>, Sched<[]> {
8803  bits<5> Zd;
8804  bits<3> Pg;
8805  bits<5> Zn;
8806  let Inst{31-25} = 0b0110010;
8807  let Inst{24}    = N;
8808  let Inst{23-13} = 0b10001010101;
8809  let Inst{12-10} = Pg;
8810  let Inst{9-5}   = Zn;
8811  let Inst{4-0}   = Zd;
8812
8813  let Constraints = "$Zd = $_Zd";
8814  let DestructiveInstType = DestructiveOther;
8815  let ElementSize = ElementSizeS;
8816  let hasSideEffects = 0;
8817  let mayRaiseFPException = 1;
8818}
8819
8820multiclass sve_bfloat_convert<bit N, string asm, SDPatternOperator op> {
8821  def NAME : sve_bfloat_convert<N, asm>;
8822  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i1, nxv4f32, !cast<Instruction>(NAME)>;
8823}
8824
8825//===----------------------------------------------------------------------===//
8826// SVE Integer Matrix Multiply Group
8827//===----------------------------------------------------------------------===//
8828
8829class sve_int_matmul<bits<2> uns, string asm>
8830: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR8:$Zm), asm,
8831  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8832  bits<5> Zda;
8833  bits<5> Zn;
8834  bits<5> Zm;
8835  let Inst{31-24} = 0b01000101;
8836  let Inst{23-22} = uns;
8837  let Inst{21}    = 0;
8838  let Inst{20-16} = Zm;
8839  let Inst{15-10} = 0b100110;
8840  let Inst{9-5}   = Zn;
8841  let Inst{4-0}   = Zda;
8842
8843  let Constraints = "$Zda = $_Zda";
8844  let DestructiveInstType = DestructiveOther;
8845  let ElementSize = ZPR32.ElementSize;
8846  let hasSideEffects = 0;
8847}
8848
8849multiclass sve_int_matmul<bits<2> uns, string asm, SDPatternOperator op> {
8850  def NAME : sve_int_matmul<uns, asm>;
8851
8852  def : SVE_3_Op_Pat<nxv4i32, op , nxv4i32, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
8853}
8854
8855//===----------------------------------------------------------------------===//
8856// SVE Integer Dot Product Mixed Sign Group
8857//===----------------------------------------------------------------------===//
8858
8859class sve_int_dot_mixed<string asm>
8860: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR8:$Zm), asm,
8861  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8862  bits<5> Zda;
8863  bits<5> Zn;
8864  bits<5> Zm;
8865  let Inst{31-21} = 0b01000100100;
8866  let Inst{20-16} = Zm;
8867  let Inst{15-10} = 0b011110;
8868  let Inst{9-5}   = Zn;
8869  let Inst{4-0}   = Zda;
8870
8871  let Constraints = "$Zda = $_Zda";
8872  let DestructiveInstType = DestructiveOther;
8873  let ElementSize = ZPR32.ElementSize;
8874  let hasSideEffects = 0;
8875}
8876
8877multiclass sve_int_dot_mixed<string asm, SDPatternOperator op> {
8878  def NAME : sve_int_dot_mixed<asm>;
8879
8880  def : SVE_3_Op_Pat<nxv4i32, op , nxv4i32, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
8881}
8882
8883//===----------------------------------------------------------------------===//
8884// SVE Integer Dot Product Mixed Sign - Indexed Group
8885//===----------------------------------------------------------------------===//
8886
8887class sve_int_dot_mixed_indexed<bit U, string asm>
8888: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexS32b:$idx),
8889    asm, "\t$Zda, $Zn, $Zm$idx", "", []>, Sched<[]> {
8890  bits<5> Zda;
8891  bits<5> Zn;
8892  bits<3> Zm;
8893  bits<2> idx;
8894  let Inst{31-21} = 0b01000100101;
8895  let Inst{20-19} = idx;
8896  let Inst{18-16} = Zm;
8897  let Inst{15-11} = 0b00011;
8898  let Inst{10}    = U;
8899  let Inst{9-5}   = Zn;
8900  let Inst{4-0}   = Zda;
8901
8902  let Constraints = "$Zda = $_Zda";
8903  let DestructiveInstType = DestructiveOther;
8904  let ElementSize = ZPR32.ElementSize;
8905  let hasSideEffects = 0;
8906}
8907
8908multiclass sve_int_dot_mixed_indexed<bit U, string asm, SDPatternOperator op> {
8909  def NAME : sve_int_dot_mixed_indexed<U, asm>;
8910
8911  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv16i8, nxv16i8, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
8912}
8913
8914//===----------------------------------------------------------------------===//
8915// SVE Floating Point Matrix Multiply Accumulate Group
8916//===----------------------------------------------------------------------===//
8917
8918class sve_fp_matrix_mla<bit sz, string asm, ZPRRegOp zprty>
8919: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, zprty:$Zm),
8920    asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8921  bits<5> Zda;
8922  bits<5> Zn;
8923  bits<5> Zm;
8924  let Inst{31-23} = 0b011001001;
8925  let Inst{22}    = sz;
8926  let Inst{21}    = 1;
8927  let Inst{20-16} = Zm;
8928  let Inst{15-10} = 0b111001;
8929  let Inst{9-5}   = Zn;
8930  let Inst{4-0}   = Zda;
8931
8932  let Constraints = "$Zda = $_Zda";
8933  let DestructiveInstType = DestructiveOther;
8934  let ElementSize = zprty.ElementSize;
8935  let hasSideEffects = 0;
8936  let mayRaiseFPException = 1;
8937}
8938
8939multiclass sve_fp_matrix_mla<bit sz, string asm, ZPRRegOp zprty, SDPatternOperator op, ValueType vt> {
8940  def NAME : sve_fp_matrix_mla<sz, asm, zprty>;
8941
8942  def : SVE_3_Op_Pat<vt, op , vt, vt, vt, !cast<Instruction>(NAME)>;
8943}
8944
8945//===----------------------------------------------------------------------===//
8946// SVE Memory - Contiguous Load And Replicate 256-bit Group
8947//===----------------------------------------------------------------------===//
8948
8949class sve_mem_ldor_si<bits<2> sz, string asm, RegisterOperand VecList>
8950: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s32:$imm4),
8951  asm, "\t$Zt, $Pg/z, [$Rn, $imm4]", "", []>, Sched<[]> {
8952  bits<5> Zt;
8953  bits<5> Rn;
8954  bits<3> Pg;
8955  bits<4> imm4;
8956  let Inst{31-25} = 0b1010010;
8957  let Inst{24-23} = sz;
8958  let Inst{22-20} = 0b010;
8959  let Inst{19-16} = imm4;
8960  let Inst{15-13} = 0b001;
8961  let Inst{12-10} = Pg;
8962  let Inst{9-5}   = Rn;
8963  let Inst{4-0}   = Zt;
8964
8965  let hasSideEffects = 0;
8966  let mayLoad = 1;
8967}
8968
8969multiclass sve_mem_ldor_si<bits<2> sz, string asm, RegisterOperand listty,
8970                           ZPRRegOp zprty, ValueType Ty, ValueType PredTy, SDNode Ld1ro> {
8971  def NAME : sve_mem_ldor_si<sz, asm, listty>;
8972  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
8973                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
8974  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
8975                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
8976  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4]",
8977                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s32:$imm4), 0>;
8978
8979  // Base addressing mode
8980  def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$Pg), GPR64sp:$base)),
8981            (!cast<Instruction>(NAME) PPR3bAny:$Pg, GPR64sp:$base, (i64 0))>;
8982  let AddedComplexity = 2 in {
8983    // Reg + Imm addressing mode
8984    def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$Pg), (add GPR64:$base, (i64 simm4s32:$imm)))),
8985              (!cast<Instruction>(NAME) $Pg, $base, simm4s32:$imm)>;
8986  }
8987}
8988
8989class sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand VecList,
8990                      RegisterOperand gprty>
8991: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
8992  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]", "", []>, Sched<[]> {
8993  bits<5> Zt;
8994  bits<3> Pg;
8995  bits<5> Rn;
8996  bits<5> Rm;
8997  let Inst{31-25} = 0b1010010;
8998  let Inst{24-23} = sz;
8999  let Inst{22-21} = 0b01;
9000  let Inst{20-16} = Rm;
9001  let Inst{15-13} = 0;
9002  let Inst{12-10} = Pg;
9003  let Inst{9-5}   = Rn;
9004  let Inst{4-0}   = Zt;
9005
9006  let hasSideEffects = 0;
9007  let mayLoad = 1;
9008}
9009
9010multiclass sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand listty,
9011                           ZPRRegOp zprty, RegisterOperand gprty, ValueType Ty,
9012                           ValueType PredTy, SDNode Ld1ro, ComplexPattern AddrCP> {
9013  def NAME : sve_mem_ldor_ss<sz, asm, listty, gprty>;
9014
9015  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
9016                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
9017
9018  def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$gp), (AddrCP GPR64sp:$base, gprty:$offset))),
9019            (!cast<Instruction>(NAME) PPR3bAny:$gp, GPR64sp:$base, gprty:$offset)>;
9020}
9021
9022//===----------------------------------------------------------------------===//
9023// SVE Interleave 128-bit Elements Group
9024//===----------------------------------------------------------------------===//
9025
9026class sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm>
9027: I<(outs ZPR128:$Zd), (ins ZPR128:$Zn, ZPR128:$Zm),
9028  asm, "\t$Zd, $Zn, $Zm",
9029  "",
9030  []>, Sched<[]> {
9031  bits<5> Zd;
9032  bits<5> Zm;
9033  bits<5> Zn;
9034  let Inst{31-21} = 0b00000101101;
9035  let Inst{20-16} = Zm;
9036  let Inst{15-13} = 0b000;
9037  let Inst{12-11} = opc;
9038  let Inst{10}    = P;
9039  let Inst{9-5}   = Zn;
9040  let Inst{4-0}   = Zd;
9041
9042  let hasSideEffects = 0;
9043}
9044
9045multiclass sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm, SDPatternOperator op> {
9046  def NAME : sve_int_perm_bin_perm_128_zz<opc, P, asm>;
9047
9048  def : SVE_2_Op_Pat<nxv16i8,  op, nxv16i8,  nxv16i8,  !cast<Instruction>(NAME)>;
9049  def : SVE_2_Op_Pat<nxv8i16,  op, nxv8i16,  nxv8i16,  !cast<Instruction>(NAME)>;
9050  def : SVE_2_Op_Pat<nxv8f16,  op, nxv8f16,  nxv8f16,  !cast<Instruction>(NAME)>;
9051  def : SVE_2_Op_Pat<nxv4i32,  op, nxv4i32,  nxv4i32,  !cast<Instruction>(NAME)>;
9052  def : SVE_2_Op_Pat<nxv4f32,  op, nxv4f32,  nxv4f32,  !cast<Instruction>(NAME)>;
9053  def : SVE_2_Op_Pat<nxv2i64,  op, nxv2i64,  nxv2i64,  !cast<Instruction>(NAME)>;
9054  def : SVE_2_Op_Pat<nxv2f64,  op, nxv2f64,  nxv2f64,  !cast<Instruction>(NAME)>;
9055  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
9056}
9057
9058/// Addressing modes
9059def am_sve_indexed_s4 :ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-8,7>", [], [SDNPWantRoot]>;
9060def am_sve_indexed_s6 :ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-32,31>", [], [SDNPWantRoot]>;
9061
9062def am_sve_regreg_lsl0 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<0>", []>;
9063def am_sve_regreg_lsl1 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<1>", []>;
9064def am_sve_regreg_lsl2 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<2>", []>;
9065def am_sve_regreg_lsl3 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<3>", []>;
9066def am_sve_regreg_lsl4 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<4>", []>;
9067
9068// Predicated pseudo floating point two operand instructions.
9069multiclass sve_fp_bin_pred_hfd<SDPatternOperator op> {
9070  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9071  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9072  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9073
9074  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9075  def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9076  def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9077  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9078  def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9079  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9080}
9081
9082// Predicated pseudo floating point three operand instructions.
9083multiclass sve_fp_3op_pred_hfd<SDPatternOperator op> {
9084  def _H_UNDEF : PredThreeOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9085  def _S_UNDEF : PredThreeOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9086  def _D_UNDEF : PredThreeOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9087
9088  def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9089  def : SVE_4_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9090  def : SVE_4_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9091  def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S_UNDEF)>;
9092  def : SVE_4_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S_UNDEF)>;
9093  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D_UNDEF)>;
9094}
9095
9096// Predicated pseudo integer two operand instructions.
9097multiclass sve_int_bin_pred_bhsd<SDPatternOperator op> {
9098  def _B_UNDEF : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesUndef>;
9099  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9100  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9101  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9102
9103  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
9104  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9105  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9106  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9107}
9108
9109// As sve_int_bin_pred but when only i32 and i64 vector types are required.
9110multiclass sve_int_bin_pred_sd<SDPatternOperator op> {
9111  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9112  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9113
9114  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9115  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9116}
9117
9118// Predicated pseudo integer two operand instructions. Second operand is an
9119// immediate specified by imm_[bhsd].
9120multiclass sve_int_shift_pred_bhsd<SDPatternOperator op,
9121                                   ComplexPattern imm_b, ComplexPattern imm_h,
9122                                   ComplexPattern imm_s, ComplexPattern imm_d> {
9123  def _B_UNDEF : PredTwoOpImmPseudo<NAME # _B, ZPR8,  Operand<i32>, FalseLanesUndef>;
9124  def _H_UNDEF : PredTwoOpImmPseudo<NAME # _H, ZPR16, Operand<i32>, FalseLanesUndef>;
9125  def _S_UNDEF : PredTwoOpImmPseudo<NAME # _S, ZPR32, Operand<i32>, FalseLanesUndef>;
9126  def _D_UNDEF : PredTwoOpImmPseudo<NAME # _D, ZPR64, Operand<i32>, FalseLanesUndef>;
9127
9128  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, imm_b, !cast<Instruction>(NAME # _B_UNDEF)>;
9129  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, imm_h, !cast<Instruction>(NAME # _H_UNDEF)>;
9130  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, imm_s, !cast<Instruction>(NAME # _S_UNDEF)>;
9131  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, imm_d, !cast<Instruction>(NAME # _D_UNDEF)>;
9132}
9133
9134multiclass sve_int_bin_pred_all_active_bhsd<SDPatternOperator op> {
9135  def _B_UNDEF : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesUndef>;
9136  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9137  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9138  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9139
9140  def : SVE_2_Op_Pred_All_Active_Pt<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
9141  def : SVE_2_Op_Pred_All_Active_Pt<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9142  def : SVE_2_Op_Pred_All_Active_Pt<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9143  def : SVE_2_Op_Pred_All_Active_Pt<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9144}
9145
9146//===----------------------------------------------------------------------===//
9147// SME2 or SVE2.1 Instructions
9148//===----------------------------------------------------------------------===//
9149
9150class sve2p1_fclamp<string asm, bits<2> sz, ZPRRegOp zpr_ty>
9151    : I<(outs zpr_ty:$Zd), (ins zpr_ty:$_Zd, zpr_ty:$Zn, zpr_ty:$Zm),
9152        asm, "\t$Zd, $Zn, $Zm", "", []>,
9153      Sched<[]> {
9154  bits<5> Zm;
9155  bits<5> Zn;
9156  bits<5> Zd;
9157  let Inst{31-24} = 0b01100100;
9158  let Inst{23-22} = sz;
9159  let Inst{21}    = 0b1;
9160  let Inst{20-16} = Zm;
9161  let Inst{15-10} = 0b001001;
9162  let Inst{9-5}   = Zn;
9163  let Inst{4-0}   = Zd;
9164
9165  let Constraints = "$Zd = $_Zd";
9166  let DestructiveInstType = DestructiveOther;
9167  let ElementSize = zpr_ty.ElementSize;
9168  let hasSideEffects = 0;
9169}
9170
9171multiclass sve2p1_fclamp<string asm, SDPatternOperator op> {
9172  def _H : sve2p1_fclamp<asm, 0b01, ZPR16>;
9173  def _S : sve2p1_fclamp<asm, 0b10, ZPR32>;
9174  def _D : sve2p1_fclamp<asm, 0b11, ZPR64>;
9175
9176  def : SVE_3_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
9177  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
9178  def : SVE_3_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
9179}
9180
9181// SVE two-way dot product
9182class sve2p1_two_way_dot_vv<string mnemonic, bit u>
9183    : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
9184        mnemonic, "\t$Zda, $Zn, $Zm",
9185        "", []>, Sched<[]> {
9186  bits<5> Zda;
9187  bits<5> Zn;
9188  bits<5> Zm;
9189  let Inst{31-21} = 0b01000100000;
9190  let Inst{20-16} = Zm;
9191  let Inst{15-11} = 0b11001;
9192  let Inst{10}    = u;
9193  let Inst{9-5}   = Zn;
9194  let Inst{4-0}   = Zda;
9195
9196  let Constraints = "$Zda = $_Zda";
9197  let DestructiveInstType = DestructiveOther;
9198  let hasSideEffects = 0;
9199}
9200
9201multiclass sve2p1_two_way_dot_vv<string mnemonic, bit u, SDPatternOperator intrinsic> {
9202  def NAME : sve2p1_two_way_dot_vv<mnemonic, u>;
9203
9204  def : SVE_3_Op_Pat<nxv4i32, intrinsic, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
9205}
9206
9207// SVE two-way dot product (indexed)
9208class sve2p1_two_way_dot_vvi<string mnemonic, bit u>
9209    : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR3b16:$Zm, VectorIndexS32b:$i2),
9210        mnemonic, "\t$Zda, $Zn, $Zm$i2",
9211        "", []>, Sched<[]> {
9212  bits<5> Zda;
9213  bits<5> Zn;
9214  bits<3> Zm;
9215  bits<2> i2;
9216  let Inst{31-21} = 0b01000100100;
9217  let Inst{20-19} = i2;
9218  let Inst{18-16} = Zm;
9219  let Inst{15-11} = 0b11001;
9220  let Inst{10}    = u;
9221  let Inst{9-5}   = Zn;
9222  let Inst{4-0}   = Zda;
9223
9224  let Constraints = "$Zda = $_Zda";
9225  let DestructiveInstType = DestructiveOther;
9226  let hasSideEffects = 0;
9227}
9228
9229multiclass sve2p1_two_way_dot_vvi<string mnemonic, bit u, SDPatternOperator intrinsic> {
9230  def NAME : sve2p1_two_way_dot_vvi<mnemonic, u>;
9231
9232  def : SVE_4_Op_Imm_Pat<nxv4i32, intrinsic, nxv4i32, nxv8i16, nxv8i16, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
9233}
9234
9235class sve2p1_ptrue_pn<string mnemonic, bits<2> sz, PNRP8to15RegOp pnrty, SDPatternOperator op>
9236    : I<(outs pnrty:$PNd), (ins ), mnemonic, "\t$PNd",
9237        "", [(set pnrty:$PNd, (op))]>, Sched<[]> {
9238  bits<3> PNd;
9239  let Inst{31-24}  = 0b00100101;
9240  let Inst{23-22} = sz;
9241  let Inst{21-3}  = 0b1000000111100000010;
9242  let Inst{2-0}   = PNd;
9243
9244  let hasSideEffects = 0;
9245}
9246
9247
9248multiclass sve2p1_ptrue_pn<string mnemonic> {
9249 def _B : sve2p1_ptrue_pn<mnemonic, 0b00, PNR8_p8to15, int_aarch64_sve_ptrue_c8>;
9250 def _H : sve2p1_ptrue_pn<mnemonic, 0b01, PNR16_p8to15, int_aarch64_sve_ptrue_c16>;
9251 def _S : sve2p1_ptrue_pn<mnemonic, 0b10, PNR32_p8to15, int_aarch64_sve_ptrue_c32>;
9252 def _D : sve2p1_ptrue_pn<mnemonic, 0b11, PNR64_p8to15, int_aarch64_sve_ptrue_c64>;
9253}
9254
9255
9256// SVE extract mask predicate from predicate-as-counter
9257class sve2p1_pred_as_ctr_to_mask_base<string mnemonic, bits<2> sz, bits<3> opc,
9258                                      RegisterOperand pprty, Operand idxty>
9259    : I<(outs pprty:$Pd), (ins PNRAny_p8to15:$PNn, idxty:$index),
9260        mnemonic, "\t$Pd, $PNn$index",
9261        "", []>, Sched<[]> {
9262  bits<4> Pd;
9263  bits<3> PNn;
9264  bits<2> imm2;
9265  let Inst{31-24} = 0b00100101;
9266  let Inst{23-22} = sz;
9267  let Inst{21-11} = 0b10000001110;
9268  let Inst{10-8}  = opc;
9269  let Inst{7-5}   = PNn;
9270  let Inst{4}     = 0b1;
9271  let Inst{3-0}   = Pd;
9272
9273  let hasSideEffects = 0;
9274}
9275
9276class sve2p1_pred_as_ctr_to_mask<string mnemonic, bits<2> sz, PPRRegOp pprty>
9277    : sve2p1_pred_as_ctr_to_mask_base<mnemonic, sz, {0, ?, ?}, pprty, VectorIndexS32b_timm> {
9278  bits<2> index;
9279  let Inst{9-8} = index;
9280}
9281
9282multiclass sve2p1_pred_as_ctr_to_mask<string mnemonic, SDPatternOperator op> {
9283 def _B : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b00, PPR8>;
9284 def _H : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b01, PPR16>;
9285 def _S : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b10, PPR32>;
9286 def _D : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b11, PPR64>;
9287
9288 def : SVE_2_Op_Imm_Pat<nxv16i1, op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _B)>;
9289 def : SVE_2_Op_Imm_Pat<nxv8i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _H)>;
9290 def : SVE_2_Op_Imm_Pat<nxv4i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
9291 def : SVE_2_Op_Imm_Pat<nxv2i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
9292}
9293
9294
9295class sve2p1_pred_as_ctr_to_mask_pair<string mnemonic, bits<2> sz, RegisterOperand pprty>
9296    : sve2p1_pred_as_ctr_to_mask_base<mnemonic, sz, {1, 0, ?}, pprty, VectorIndexD> {
9297  bit index;
9298  let Inst{8}    = index;
9299}
9300
9301multiclass sve2p1_pred_as_ctr_to_mask_pair<string mnemonic> {
9302 def _B : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b00, PP_b>;
9303 def _H : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b01, PP_h>;
9304 def _S : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b10, PP_s>;
9305 def _D : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b11, PP_d>;
9306}
9307
9308
9309// SME2 multi-vec extract narrow
9310class sve2p1_multi_vec_extract_narrow<string mnemonic, bits<2> opc, bits<3> tsz>
9311    : I<(outs ZPR16:$Zd), (ins ZZ_s_mul_r:$Zn),
9312        mnemonic, "\t$Zd, $Zn",
9313        "", []>, Sched<[]> {
9314  bits<5> Zd;
9315  bits<4> Zn;
9316  let Inst{31-23} = 0b010001010;
9317  let Inst{22}    = tsz{2};
9318  let Inst{21}    = 0b1;
9319  let Inst{20-19} = tsz{1-0};
9320  let Inst{18-13} = 0b001010;
9321  let Inst{12-11} = opc;
9322  let Inst{10}    = 0b0;
9323  let Inst{9-6}   = Zn;
9324  let Inst{5}     = 0b0;
9325  let Inst{4-0}   = Zd;
9326
9327  let hasSideEffects = 0;
9328}
9329
9330multiclass sve2p1_multi_vec_extract_narrow<string mnemonic, bits<2> opc, SDPatternOperator intrinsic> {
9331  def NAME : sve2p1_multi_vec_extract_narrow<mnemonic, opc, 0b010>;
9332  def : SVE2p1_Cvt_VG2_Pat<NAME, intrinsic, nxv8i16, nxv4i32>;
9333}
9334
9335// SVE2 multi-vec shift narrow
9336class sve2p1_multi_vec_shift_narrow<string mnemonic, bits<3> opc, bits<2> tsz>
9337    : I<(outs ZPR16:$Zd), (ins ZZ_s_mul_r:$Zn, tvecshiftR16:$imm4),
9338        mnemonic, "\t$Zd, $Zn, $imm4",
9339        "", []>, Sched<[]> {
9340  bits<5> Zd;
9341  bits<4> Zn;
9342  bits<4> imm4;
9343  let Inst{31-23} = 0b010001011;
9344  let Inst{22}    = tsz{1};
9345  let Inst{21}    = 0b1;
9346  let Inst{20}    = tsz{0};
9347  let Inst{19-16} = imm4;
9348  let Inst{15-14} = 0b00;
9349  let Inst{13-11} = opc;
9350  let Inst{10}    = 0b0;
9351  let Inst{9-6}   = Zn;
9352  let Inst{5}     = 0b0;
9353  let Inst{4-0}   = Zd;
9354
9355  let hasSideEffects = 0;
9356}
9357
9358multiclass sve2p1_multi_vec_shift_narrow<string mnemonic, bits<3> opc, SDPatternOperator intrinsic> {
9359  def NAME : sve2p1_multi_vec_shift_narrow<mnemonic, opc, 0b01>;
9360
9361  def : SVE2p1_Sat_Shift_VG2_Pat<NAME, intrinsic, nxv8i16, nxv4i32, tvecshiftR16>;
9362}
9363
9364
9365// SME2 multi-vec contiguous load (scalar plus scalar, two registers)
9366class sve2p1_mem_cld_ss_2z<string mnemonic, bits<2> msz, bit n,
9367                         RegisterOperand vector_ty, RegisterOperand gpr_ty>
9368    : I<(outs vector_ty:$Zt),
9369        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9370        mnemonic, "\t$Zt, $PNg/z, [$Rn, $Rm]",
9371        "", []>, Sched<[]> {
9372  bits<4> Zt;
9373  bits<5> Rm;
9374  bits<5> Rn;
9375  bits<3> PNg;
9376  let Inst{31-21} = 0b10100000000;
9377  let Inst{20-16} = Rm;
9378  let Inst{15}    = 0b0;
9379  let Inst{14-13} = msz;
9380  let Inst{12-10} = PNg;
9381  let Inst{9-5} = Rn;
9382  let Inst{4-1} = Zt;
9383  let Inst{0}   = n;
9384
9385  let hasSideEffects = 0;
9386  let mayLoad = 1;
9387}
9388
9389// SME2 multi-vec contiguous load (scalar plus immediate, two registers)
9390class sve2p1_mem_cld_si_2z<string mnemonic, bits<2> msz, bit n,
9391                         RegisterOperand vector_ty>
9392    : I<(outs vector_ty:$Zt),
9393        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4),
9394        mnemonic, "\t$Zt, $PNg/z, [$Rn, $imm4, mul vl]",
9395        "", []>, Sched<[]> {
9396  bits<4> Zt;
9397  bits<5> Rn;
9398  bits<3> PNg;
9399  bits<4> imm4;
9400  let Inst{31-20} = 0b101000000100;
9401  let Inst{19-16} = imm4;
9402  let Inst{15}    = 0b0;
9403  let Inst{14-13} = msz;
9404  let Inst{12-10} = PNg;
9405  let Inst{9-5}   = Rn;
9406  let Inst{4-1}   = Zt;
9407  let Inst{0}     = n;
9408
9409  let hasSideEffects = 0;
9410  let mayLoad = 1;
9411}
9412
9413multiclass sve2p1_mem_cld_si_2z<string mnemonic, bits<2> msz, bit n,
9414                              RegisterOperand vector_ty> {
9415  def NAME : sve2p1_mem_cld_si_2z<mnemonic, msz, n, vector_ty>;
9416
9417  def : InstAlias<mnemonic # " $Zt, $PNg/z, [$Rn]",
9418                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9419}
9420
9421// SME2 multi-vec contiguous load (scalar plus scalar, four registers)
9422class sve2p1_mem_cld_ss_4z<string mnemonic, bits<2> msz, bit n,
9423                         RegisterOperand vector_ty, RegisterOperand gpr_ty>
9424    : I<(outs vector_ty:$Zt),
9425        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9426        mnemonic, "\t$Zt, $PNg/z, [$Rn, $Rm]",
9427        "", []>, Sched<[]> {
9428  bits<3> Zt;
9429  bits<5> Rm;
9430  bits<5> Rn;
9431  bits<3> PNg;
9432  let Inst{31-21} = 0b10100000000;
9433  let Inst{20-16} = Rm;
9434  let Inst{15}    = 0b1;
9435  let Inst{14-13} = msz;
9436  let Inst{12-10} = PNg;
9437  let Inst{9-5} = Rn;
9438  let Inst{4-2} = Zt;
9439  let Inst{1}   = 0b0;
9440  let Inst{0}   = n;
9441
9442  let hasSideEffects = 0;
9443  let mayLoad = 1;
9444}
9445
9446// SME2 multi-vec contiguous load (scalar plus immediate, four registers)
9447class sve2p1_mem_cld_si_4z<string mnemonic, bits<2> msz, bit n,
9448                         RegisterOperand vector_ty>
9449    : I<(outs vector_ty:$Zt),
9450        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4),
9451        mnemonic, "\t$Zt, $PNg/z, [$Rn, $imm4, mul vl]",
9452        "", []>, Sched<[]> {
9453  bits<3> Zt;
9454  bits<5> Rn;
9455  bits<3> PNg;
9456  bits<4> imm4;
9457  let Inst{31-20} = 0b101000000100;
9458  let Inst{19-16} = imm4;
9459  let Inst{15}    = 0b1;
9460  let Inst{14-13} = msz;
9461  let Inst{12-10} = PNg;
9462  let Inst{9-5}   = Rn;
9463  let Inst{4-2}   = Zt;
9464  let Inst{1}     = 0b0;
9465  let Inst{0}     = n;
9466
9467  let hasSideEffects = 0;
9468  let mayLoad = 1;
9469}
9470
9471multiclass sve2p1_mem_cld_si_4z<string mnemonic, bits<2> msz, bit n,
9472                              RegisterOperand vector_ty> {
9473  def NAME : sve2p1_mem_cld_si_4z<mnemonic, msz, n, vector_ty>;
9474
9475  def : InstAlias<mnemonic # " $Zt, $PNg/z, [$Rn]",
9476                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9477}
9478
9479
9480// SME2 multi-vec contiguous store (scalar plus scalar, two registers)
9481class sve2p1_mem_cst_ss_2z<string mnemonic, bits<2> msz, bit n,
9482                           RegisterOperand vector_ty, RegisterOperand gpr_ty>
9483    : I<(outs ),
9484        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9485        mnemonic, "\t$Zt, $PNg, [$Rn, $Rm]",
9486        "", []>, Sched<[]> {
9487  bits<4> Zt;
9488  bits<5> Rm;
9489  bits<5> Rn;
9490  bits<3> PNg;
9491  let Inst{31-21} = 0b10100000001;
9492  let Inst{20-16} = Rm;
9493  let Inst{15}    = 0b0;
9494  let Inst{14-13} = msz;
9495  let Inst{12-10} = PNg;
9496  let Inst{9-5} = Rn;
9497  let Inst{4-1} = Zt;
9498  let Inst{0}   = n;
9499
9500  let hasSideEffects = 0;
9501  let mayStore = 1;
9502}
9503
9504
9505// SME2 multi-vec contiguous store (scalar plus immediate, two registers)
9506class sve2p1_mem_cst_si_2z<string mnemonic, bits<2> msz, bit n,
9507                           RegisterOperand vector_ty>
9508    : I<(outs ),
9509        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4),
9510        mnemonic, "\t$Zt, $PNg, [$Rn, $imm4, mul vl]",
9511        "", []>, Sched<[]> {
9512  bits<4> Zt;
9513  bits<5> Rn;
9514  bits<3> PNg;
9515  bits<4> imm4;
9516  let Inst{31-20} = 0b101000000110;
9517  let Inst{19-16} = imm4;
9518  let Inst{15}    = 0b0;
9519  let Inst{14-13} = msz;
9520  let Inst{12-10} = PNg;
9521  let Inst{9-5}   = Rn;
9522  let Inst{4-1}   = Zt;
9523  let Inst{0}     = n;
9524
9525  let hasSideEffects = 0;
9526  let mayStore = 1;
9527}
9528
9529
9530multiclass sve2p1_mem_cst_si_2z<string mnemonic, bits<2> msz, bit n,
9531                              RegisterOperand vector_ty> {
9532  def NAME : sve2p1_mem_cst_si_2z<mnemonic, msz, n, vector_ty>;
9533
9534  def : InstAlias<mnemonic # " $Zt, $PNg, [$Rn]",
9535                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9536}
9537
9538
9539// SME2 multi-vec contiguous store (scalar plus scalar, four registers)
9540class sve2p1_mem_cst_ss_4z<string mnemonic, bits<2> msz, bit n,
9541                           RegisterOperand vector_ty, RegisterOperand gpr_ty>
9542    : I<(outs ),
9543        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9544        mnemonic, "\t$Zt, $PNg, [$Rn, $Rm]",
9545        "", []>, Sched<[]> {
9546  bits<3> Zt;
9547  bits<5> Rm;
9548  bits<5> Rn;
9549  bits<3> PNg;
9550  let Inst{31-21} = 0b10100000001;
9551  let Inst{20-16} = Rm;
9552  let Inst{15}    = 0b1;
9553  let Inst{14-13} = msz;
9554  let Inst{12-10} = PNg;
9555  let Inst{9-5} = Rn;
9556  let Inst{4-2} = Zt;
9557  let Inst{1}   = 0b0;
9558  let Inst{0}   = n;
9559
9560  let mayStore = 1;
9561}
9562
9563
9564// SME2 multi-vec contiguous store (scalar plus immediate, four registers)
9565class sve2p1_mem_cst_si_4z<string mnemonic, bits<2> msz, bit n,
9566                           RegisterOperand vector_ty>
9567    : I<(outs ),
9568        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4),
9569        mnemonic, "\t$Zt, $PNg, [$Rn, $imm4, mul vl]",
9570        "", []>, Sched<[]> {
9571  bits<3> Zt;
9572  bits<5> Rn;
9573  bits<3> PNg;
9574  bits<4> imm4;
9575  let Inst{31-20} = 0b101000000110;
9576  let Inst{19-16} = imm4;
9577  let Inst{15}    = 0b1;
9578  let Inst{14-13} = msz;
9579  let Inst{12-10} = PNg;
9580  let Inst{9-5}   = Rn;
9581  let Inst{4-2}   = Zt;
9582  let Inst{1}     = 0b0;
9583  let Inst{0}     = n;
9584
9585  let hasSideEffects = 0;
9586  let mayStore = 1;
9587}
9588
9589
9590multiclass sve2p1_mem_cst_si_4z<string mnemonic, bits<2> msz, bit n,
9591                                RegisterOperand vector_ty> {
9592  def NAME : sve2p1_mem_cst_si_4z<mnemonic, msz, n, vector_ty>;
9593
9594  def : InstAlias<mnemonic # " $Zt, $PNg, [$Rn]",
9595                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn,0), 1>;
9596}
9597
9598// SVE predicate count (predicate-as-counter)
9599class sve2p1_pcount_pn<string mnemonic, bits<3> opc, bits<2> sz, PNRRegOp pnrty>
9600   : I<(outs GPR64:$Rd),
9601       (ins pnrty:$PNn, sve_vec_len_specifier_enum:$vl),
9602       mnemonic, "\t$Rd, $PNn, $vl",
9603       "", []>, Sched<[]> {
9604  bits<5> Rd;
9605  bits<4> PNn;
9606  bits<1> vl;
9607  let Inst{31-24} = 0b00100101;
9608  let Inst{23-22} = sz;
9609  let Inst{21-19} = 0b100;
9610  let Inst{18-16} = opc;
9611  let Inst{15-11} = 0b10000;
9612  let Inst{10}    = vl;
9613  let Inst{9}     = 0b1;
9614  let Inst{8-5}   = PNn;
9615  let Inst{4-0}   = Rd;
9616
9617  let hasSideEffects = 0;
9618}
9619
9620multiclass sve2p1_pcount_pn<string mnemonic, bits<3> opc> {
9621  def _B : sve2p1_pcount_pn<mnemonic, opc, 0b00, PNR8>;
9622  def _H : sve2p1_pcount_pn<mnemonic, opc, 0b01, PNR16>;
9623  def _S : sve2p1_pcount_pn<mnemonic, opc, 0b10, PNR32>;
9624  def _D : sve2p1_pcount_pn<mnemonic, opc, 0b11, PNR64>;
9625
9626  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c8,  aarch64svcount, !cast<Instruction>(NAME # _B)>;
9627  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c16, aarch64svcount, !cast<Instruction>(NAME # _H)>;
9628  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c32, aarch64svcount, !cast<Instruction>(NAME # _S)>;
9629  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c64, aarch64svcount, !cast<Instruction>(NAME # _D)>;
9630}
9631
9632
9633// SVE integer compare scalar count and limit (predicate-as-counter)
9634class sve2p1_int_while_rr_pn<string mnemonic, bits<2> sz, bits<3> opc,
9635                             PNRP8to15RegOp pnrty>
9636    : I<(outs pnrty:$PNd), (ins GPR64:$Rn, GPR64:$Rm, sve_vec_len_specifier_enum:$vl),
9637        mnemonic, "\t$PNd, $Rn, $Rm, $vl",
9638        "", []>, Sched<[]> {
9639  bits<3> PNd;
9640  bits<5> Rn;
9641  bits<1> vl;
9642  bits<5> Rm;
9643  let Inst{31-24} = 0b00100101;
9644  let Inst{23-22} = sz;
9645  let Inst{21}    = 0b1;
9646  let Inst{20-16} = Rm;
9647  let Inst{15-14} = 0b01;
9648  let Inst{13}    = vl;
9649  let Inst{12}    = 0b0;
9650  let Inst{11-10} = opc{2-1};
9651  let Inst{9-5}   = Rn;
9652  let Inst{4}     = 0b1;
9653  let Inst{3}     = opc{0};
9654  let Inst{2-0}   = PNd;
9655
9656  let Defs = [NZCV];
9657  let hasSideEffects = 0;
9658}
9659
9660
9661multiclass sve2p1_int_while_rr_pn<string mnemonic, bits<3> opc> {
9662 def _B : sve2p1_int_while_rr_pn<mnemonic, 0b00, opc, PNR8_p8to15>;
9663 def _H : sve2p1_int_while_rr_pn<mnemonic, 0b01, opc, PNR16_p8to15>;
9664 def _S : sve2p1_int_while_rr_pn<mnemonic, 0b10, opc, PNR32_p8to15>;
9665 def _D : sve2p1_int_while_rr_pn<mnemonic, 0b11, opc, PNR64_p8to15>;
9666
9667 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c8"),
9668                            i64, !cast<Instruction>(NAME # _B)>;
9669 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c16"),
9670                            i64, !cast<Instruction>(NAME # _H)>;
9671 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c32"),
9672                            i64, !cast<Instruction>(NAME # _S)>;
9673 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c64"),
9674                            i64, !cast<Instruction>(NAME # _D)>;
9675}
9676
9677
9678// SVE integer compare scalar count and limit (predicate pair)
9679class sve2p1_int_while_rr_pair<string mnemonic, bits<2> sz, bits<3> opc,
9680                             RegisterOperand ppr_ty>
9681    : I<(outs ppr_ty:$Pd), (ins GPR64:$Rn, GPR64:$Rm),
9682        mnemonic, "\t$Pd, $Rn, $Rm",
9683        "", []>, Sched<[]> {
9684  bits<3> Pd;
9685  bits<5> Rn;
9686  bits<5> Rm;
9687  let Inst{31-24} = 0b00100101;
9688  let Inst{23-22} = sz;
9689  let Inst{21}    = 0b1;
9690  let Inst{20-16} = Rm;
9691  let Inst{15-12} = 0b0101;
9692  let Inst{11-10} = opc{2-1};
9693  let Inst{9-5}   = Rn;
9694  let Inst{4}     = 0b1;
9695  let Inst{3-1}   = Pd;
9696  let Inst{0}     = opc{0};
9697
9698  let Defs = [NZCV];
9699  let hasSideEffects = 0;
9700}
9701
9702
9703multiclass sve2p1_int_while_rr_pair<string mnemonic, bits<3> opc> {
9704 def _B : sve2p1_int_while_rr_pair<mnemonic, 0b00, opc, PP_b_mul_r>;
9705 def _H : sve2p1_int_while_rr_pair<mnemonic, 0b01, opc, PP_h_mul_r>;
9706 def _S : sve2p1_int_while_rr_pair<mnemonic, 0b10, opc, PP_s_mul_r>;
9707 def _D : sve2p1_int_while_rr_pair<mnemonic, 0b11, opc, PP_d_mul_r>;
9708}
9709
9710
9711class sve_mem_128b_gld_64_unscaled<string mnemonic>
9712    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
9713        mnemonic, "\t$Zt, $Pg/z, [$Zn, $Rm]",
9714        "", []>, Sched<[]> {
9715  bits<5> Zt;
9716  bits<5> Zn;
9717  bits<3> Pg;
9718  bits<5> Rm;
9719  let Inst{31-21} = 0b11000100000;
9720  let Inst{20-16} = Rm;
9721  let Inst{15-13} = 0b101;
9722  let Inst{12-10} = Pg;
9723  let Inst{9-5}   = Zn;
9724  let Inst{4-0}   = Zt;
9725
9726  let hasSideEffects = 0;
9727  let mayLoad = 1;
9728}
9729
9730
9731multiclass sve_mem_128b_gld_64_unscaled<string mnemonic> {
9732  def NAME : sve_mem_128b_gld_64_unscaled<mnemonic>;
9733
9734  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Zn]",
9735                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
9736}
9737
9738class sve_mem_sst_128b_64_unscaled<string mnemonic>
9739    : I<(outs ), (ins Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
9740        mnemonic, "\t$Zt, $Pg, [$Zn, $Rm]",
9741        "", []>, Sched<[]> {
9742  bits<5> Zt;
9743  bits<5> Zn;
9744  bits<3> Pg;
9745  bits<5> Rm;
9746  let Inst{31-21} = 0b11100100001;
9747  let Inst{20-16} = Rm;
9748  let Inst{15-13} = 0b001;
9749  let Inst{12-10} = Pg;
9750  let Inst{9-5}   = Zn;
9751  let Inst{4-0}   = Zt;
9752
9753  let hasSideEffects = 0;
9754  let mayStore = 1;
9755}
9756
9757
9758multiclass sve_mem_sst_128b_64_unscaled<string mnemonic> {
9759  def NAME : sve_mem_sst_128b_64_unscaled<mnemonic>;
9760
9761  def : InstAlias<mnemonic # " $Zt, $Pg, [$Zn]",
9762                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
9763}
9764
9765
9766// SVE contiguous load (quadwords, scalar plus immediate)
9767class sve_mem_128b_cld_si<bits<2> dtype, string mnemonic>
9768    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
9769        mnemonic, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
9770        "", []>, Sched<[]> {
9771  bits<5> Zt;
9772  bits<5> Rn;
9773  bits<3> Pg;
9774  bits<4> imm4;
9775  let Inst{31-25} = 0b1010010;
9776  let Inst{24-23} = dtype;
9777  let Inst{22-20} = 0b001;
9778  let Inst{19-16} = imm4;
9779  let Inst{15-13} = 0b001;
9780  let Inst{12-10} = Pg;
9781  let Inst{9-5}   = Rn;
9782  let Inst{4-0}   = Zt;
9783
9784  let hasSideEffects = 0;
9785  let mayLoad = 1;
9786}
9787
9788multiclass sve_mem_128b_cld_si<bits<2> dtype, string mnemonic> {
9789  def NAME : sve_mem_128b_cld_si<dtype, mnemonic>;
9790
9791  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn]",
9792                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
9793  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn]",
9794                  (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
9795  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn, $imm4, mul vl]",
9796                  (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
9797}
9798
9799
9800// SVE contiguous load (quadwords, scalar plus scalar)
9801class sve_mem_128b_cld_ss<bits<2> dtype, string mnemonic, RegisterOperand gprsh_ty>
9802    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprsh_ty:$Rm),
9803        mnemonic, "\t$Zt, $Pg/z, [$Rn, $Rm]", "",
9804        []>, Sched<[]> {
9805  bits<5> Zt;
9806  bits<5> Rn;
9807  bits<3> Pg;
9808  bits<5> Rm;
9809  let Inst{31-25} = 0b1010010;
9810  let Inst{24-23} = dtype;
9811  let Inst{22-21} = 0b00;
9812  let Inst{20-16} = Rm;
9813  let Inst{15-13} = 0b100;
9814  let Inst{12-10} = Pg;
9815  let Inst{9-5}   = Rn;
9816  let Inst{4-0}   = Zt;
9817
9818  let hasSideEffects = 0;
9819  let mayLoad = 1;
9820}
9821
9822multiclass sve_mem_128b_cld_ss<bits<2> dtype, string mnemonic, RegisterOperand gprsh_ty> {
9823  def NAME : sve_mem_128b_cld_ss<dtype, mnemonic, gprsh_ty>;
9824
9825  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn, $Rm]",
9826                 (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprsh_ty:$Rm), 0>;
9827}
9828
9829
9830// SVE floating-point recursive reduction (quadwords)
9831class sve2p1_fp_reduction_q<bits<2> sz, bits<3> opc, string mnemonic,
9832                            RegisterOperand zpr_ty, string vec_sfx>
9833    : I<(outs V128:$Vd), (ins PPR3bAny:$Pg, zpr_ty:$Zn),
9834        mnemonic, "\t$Vd." # vec_sfx # ", $Pg, $Zn",
9835        "", []>, Sched<[]> {
9836  bits<5> Vd;
9837  bits<5> Zn;
9838  bits<3> Pg;
9839  let Inst{31-24} = 0b01100100;
9840  let Inst{23-22} = sz;
9841  let Inst{21-19} = 0b010;
9842  let Inst{18-16} = opc;
9843  let Inst{15-13} = 0b101;
9844  let Inst{12-10} = Pg;
9845  let Inst{9-5}   = Zn;
9846  let Inst{4-0}   = Vd;
9847
9848  let hasSideEffects = 0;
9849  let mayRaiseFPException = 1;
9850}
9851
9852multiclass sve2p1_fp_reduction_q<bits<3> opc, string mnemonic> {
9853  def _H : sve2p1_fp_reduction_q<0b01, opc, mnemonic, ZPR16, "8h">;
9854  def _S : sve2p1_fp_reduction_q<0b10, opc, mnemonic, ZPR32, "4s">;
9855  def _D : sve2p1_fp_reduction_q<0b11, opc, mnemonic, ZPR64, "2d">;
9856}
9857
9858
9859// SVE Permute Vector - Quadwords (DUPQ)
9860class sve2p1_dupq<bits<5> ind_tsz, string mnemonic, ZPRRegOp zprty, Operand itype>
9861    : I<(outs zprty:$Zd), (ins zprty:$Zn, itype:$index),
9862        mnemonic, "\t$Zd, $Zn$index",
9863        "", []>, Sched<[]> {
9864  bits<5> Zd;
9865  bits<5> Zn;
9866  let Inst{31-21} = 0b00000101001;
9867  let Inst{20-16} = ind_tsz;
9868  let Inst{15-10} = 0b001001;
9869  let Inst{9-5} = Zn;
9870  let Inst{4-0} = Zd;
9871
9872  let hasSideEffects = 0;
9873}
9874
9875multiclass sve2p1_dupq<string mnemonic> {
9876  def _B : sve2p1_dupq<{?, ?, ?, ?, 1}, mnemonic, ZPR8, VectorIndexB32b> {
9877    bits<4> index;
9878    let Inst{20-17} = index;
9879  }
9880  def _H : sve2p1_dupq<{?, ?, ?, 1, 0}, mnemonic, ZPR16, VectorIndexH32b> {
9881    bits<3> index;
9882    let Inst{20-18} = index;
9883  }
9884  def _S : sve2p1_dupq<{?, ?, 1, 0, 0}, mnemonic, ZPR32, VectorIndexS32b> {
9885    bits<2> index;
9886    let Inst{20-19} = index;
9887  }
9888  def _D : sve2p1_dupq<{?, 1, 0, 0, 0}, mnemonic, ZPR64, VectorIndexD32b> {
9889    bits<1> index;
9890    let Inst{20} = index;
9891  }
9892}
9893
9894
9895// SVE Permute Vector - Quadwords (EXTQ)
9896class sve2p1_extq<string mnemonic>
9897    : I<(outs ZPR8:$Zdn), (ins ZPR8:$_Zdn, ZPR8:$Zm, imm0_15:$imm4),
9898        mnemonic, "\t$Zdn, $_Zdn, $Zm, $imm4",
9899        "", []>, Sched<[]> {
9900  bits<5> Zdn;
9901  bits<5> Zm;
9902  bits<4> imm4;
9903  let Inst{31-20} = 0b000001010110;
9904  let Inst{19-16} = imm4;
9905  let Inst{15-10} = 0b001001;
9906  let Inst{9-5} = Zm;
9907  let Inst{4-0} = Zdn;
9908
9909  let Constraints = "$Zdn = $_Zdn";
9910  let DestructiveInstType = DestructiveOther;
9911  let ElementSize = ZPR8.ElementSize;
9912  let hasSideEffects = 0;
9913}
9914
9915
9916// SVE move predicate from vector
9917class sve2p1_vector_to_pred<bits<4> opc, string mnemonic,
9918                            PPRRegOp ppr_ty, Operand itype>
9919    : I<(outs ppr_ty:$Pd), (ins ZPRAny:$Zn, itype:$index),
9920        mnemonic, "\t$Pd, $Zn$index",
9921        "", []>, Sched<[]> {
9922  bits<4> Pd;
9923  bits<5> Zn;
9924  let Inst{31-24} = 0b00000101;
9925  let Inst{23-22} = opc{3-2};
9926  let Inst{21-19} = 0b101;
9927  let Inst{18-17} = opc{1-0};
9928  let Inst{16-10} = 0b0001110;
9929  let Inst{9-5}   = Zn;
9930  let Inst{4}     = 0b0;
9931  let Inst{3-0}   = Pd;
9932
9933  let hasSideEffects = 0;
9934}
9935
9936multiclass sve2p1_vector_to_pred<string mnemonic> {
9937  def _B : sve2p1_vector_to_pred<{0, 0, 0, 1}, mnemonic, PPR8,  VectorIndex0>;
9938  def _H : sve2p1_vector_to_pred<{0, 0, 1, ?}, mnemonic, PPR16, VectorIndexD32b> {
9939    bits<1> index;
9940    let Inst{17} = index;
9941  }
9942  def _S : sve2p1_vector_to_pred<{0, 1, ?, ?}, mnemonic, PPR32, VectorIndexS32b> {
9943    bits<2> index;
9944    let Inst{18-17} = index;
9945  }
9946  def _D : sve2p1_vector_to_pred<{1, ?, ?, ?}, mnemonic, PPR64, VectorIndexH32b> {
9947    bits<3> index;
9948    let Inst{22}    = index{2};
9949    let Inst{18-17} = index{1-0};
9950  }
9951
9952  def : InstAlias<mnemonic # "\t$Pd, $Zn",
9953                 (!cast<Instruction>(NAME # _B) PPR8:$Pd, ZPRAny:$Zn, 0), 1>;
9954}
9955
9956
9957// SVE move predicate into vector
9958class sve2p1_pred_to_vector<bits<4> opc, string mnemonic,
9959                            PPRRegOp ppr_ty, Operand itype>
9960    : I<(outs ZPRAny:$Zd), (ins ZPRAny:$_Zd, itype:$index, ppr_ty:$Pn),
9961        mnemonic, "\t$Zd$index, $Pn",
9962        "", []>, Sched<[]> {
9963  bits<5> Zd;
9964  bits<4> Pn;
9965  let Inst{31-24} = 0b00000101;
9966  let Inst{23-22} = opc{3-2};
9967  let Inst{21-19} = 0b101;
9968  let Inst{18-17} = opc{1-0};
9969  let Inst{16-9}  = 0b10011100;
9970  let Inst{8-5}   = Pn;
9971  let Inst{4-0}   = Zd;
9972
9973  let Constraints = "$Zd = $_Zd";
9974  let hasSideEffects = 0;
9975}
9976
9977multiclass sve2p1_pred_to_vector<string mnemonic> {
9978  def _B : sve2p1_pred_to_vector<{0, 0, 0, 1}, mnemonic, PPR8,  VectorIndex0>;
9979  def _H : sve2p1_pred_to_vector<{0, 0, 1, ?}, mnemonic, PPR16, VectorIndexD32b> {
9980    bits<1> index;
9981    let Inst{17} = index;
9982  }
9983  def _S : sve2p1_pred_to_vector<{0, 1, ?, ?}, mnemonic, PPR32, VectorIndexS32b> {
9984    bits<2> index;
9985    let Inst{18-17} = index;
9986  }
9987  def _D : sve2p1_pred_to_vector<{1, ?, ?, ?}, mnemonic, PPR64, VectorIndexH32b> {
9988    bits<3> index;
9989    let Inst{22}    = index{2};
9990    let Inst{18-17} = index{1-0};
9991  }
9992
9993  def : InstAlias<mnemonic # "\t$Zd, $Pn",
9994                 (!cast<Instruction>(NAME # _B) ZPRAny:$Zd, 0, PPR8:$Pn), 1>;
9995}
9996
9997
9998// SVE bitwise logical/add/min/max reductions (quadwords)
9999class sve2p1_int_reduce_q<bits<2> sz, bits<4> opc, string mnemonic,
10000                          RegisterOperand zpr_ty, string vec_sfx>
10001    : I<(outs V128:$Vd), (ins PPR3bAny:$Pg, zpr_ty:$Zn),
10002        mnemonic, "\t$Vd." # vec_sfx # ", $Pg, $Zn",
10003        "", []>, Sched<[]> {
10004  bits<5> Vd;
10005  bits<5> Zn;
10006  bits<3> Pg;
10007  let Inst{31-24} = 0b00000100;
10008  let Inst{23-22} = sz;
10009  let Inst{21}    = 0b0;
10010  let Inst{20-19} = opc{3-2};
10011  let Inst{18}    = 0b1;
10012  let Inst{17-16} = opc{1-0};
10013  let Inst{15-13} = 0b001;
10014  let Inst{12-10} = Pg;
10015  let Inst{9-5}   = Zn;
10016  let Inst{4-0}   = Vd;
10017
10018  let hasSideEffects = 0;
10019}
10020
10021multiclass sve2p1_int_reduce_q<bits<4> opc, string mnemonic> {
10022  def _B : sve2p1_int_reduce_q<0b00, opc, mnemonic, ZPR8,  "16b">;
10023  def _H : sve2p1_int_reduce_q<0b01, opc, mnemonic, ZPR16, "8h">;
10024  def _S : sve2p1_int_reduce_q<0b10, opc, mnemonic, ZPR32, "4s">;
10025  def _D : sve2p1_int_reduce_q<0b11, opc, mnemonic, ZPR64, "2d">;
10026}
10027
10028
10029// SVE permute vector elements (quadwords)
10030class sve2p1_permute_vec_elems_q<bits<2> sz, bits<3> opc, string mnemonic,
10031                                 ZPRRegOp zpr_ty, RegisterOperand src1_ty>
10032    : I<(outs zpr_ty:$Zd), (ins src1_ty:$Zn, zpr_ty:$Zm),
10033        mnemonic, "\t$Zd, $Zn, $Zm",
10034        "", []>, Sched<[]> {
10035  bits<5> Zd;
10036  bits<5> Zn;
10037  bits<5> Zm;
10038  let Inst{31-24} = 0b01000100;
10039  let Inst{23-22} = sz;
10040  let Inst{21}    = 0b0;
10041  let Inst{20-16} = Zm;
10042  let Inst{15-13} = 0b111;
10043  let Inst{12-10} = opc;
10044  let Inst{9-5}   = Zn;
10045  let Inst{4-0}   = Zd;
10046
10047  let hasSideEffects = 0;
10048}
10049
10050multiclass sve2p1_permute_vec_elems_q<bits<3> opc, string mnemonic> {
10051  def _B : sve2p1_permute_vec_elems_q<0b00, opc, mnemonic, ZPR8,  ZPR8>;
10052  def _H : sve2p1_permute_vec_elems_q<0b01, opc, mnemonic, ZPR16, ZPR16>;
10053  def _S : sve2p1_permute_vec_elems_q<0b10, opc, mnemonic, ZPR32, ZPR32>;
10054  def _D : sve2p1_permute_vec_elems_q<0b11, opc, mnemonic, ZPR64, ZPR64>;
10055}
10056
10057multiclass sve2p1_tblq<string mnemonic> {
10058  def _B : sve2p1_permute_vec_elems_q<0b00, 0b110, mnemonic, ZPR8,  Z_b>;
10059  def _H : sve2p1_permute_vec_elems_q<0b01, 0b110, mnemonic, ZPR16, Z_h>;
10060  def _S : sve2p1_permute_vec_elems_q<0b10, 0b110, mnemonic, ZPR32, Z_s>;
10061  def _D : sve2p1_permute_vec_elems_q<0b11, 0b110, mnemonic, ZPR64, Z_d>;
10062}
10063