xref: /src/contrib/llvm-project/llvm/lib/Target/AArch64/SVEInstrFormats.td (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
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<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2321  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2322}
2323
2324class sve_fp_3op_p_zds_b<bits<2> sz, bits<2> opc, string asm,
2325                         ZPRRegOp zprty>
2326: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm, zprty:$Za),
2327  asm, "\t$Zdn, $Pg/m, $Zm, $Za",
2328  "",
2329  []>, Sched<[]> {
2330  bits<3> Pg;
2331  bits<5> Za;
2332  bits<5> Zdn;
2333  bits<5> Zm;
2334  let Inst{31-24} = 0b01100101;
2335  let Inst{23-22} = sz;
2336  let Inst{21}    = 0b1;
2337  let Inst{20-16} = Za;
2338  let Inst{15}    = 0b1;
2339  let Inst{14-13} = opc;
2340  let Inst{12-10} = Pg;
2341  let Inst{9-5}   = Zm;
2342  let Inst{4-0}   = Zdn;
2343
2344  let Constraints = "$Zdn = $_Zdn";
2345  let DestructiveInstType = DestructiveOther;
2346  let ElementSize = zprty.ElementSize;
2347  let hasSideEffects = 0;
2348  let mayRaiseFPException = 1;
2349}
2350
2351multiclass sve_fp_3op_p_zds_b<bits<2> opc, string asm, SDPatternOperator op,
2352                              string revname, bit isReverseInstr> {
2353  def _H : sve_fp_3op_p_zds_b<0b01, opc, asm, ZPR16>,
2354           SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2355  def _S : sve_fp_3op_p_zds_b<0b10, opc, asm, ZPR32>,
2356           SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2357  def _D : sve_fp_3op_p_zds_b<0b11, opc, asm, ZPR64>,
2358           SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2359
2360  def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2361  def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2362  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2363}
2364
2365//===----------------------------------------------------------------------===//
2366// SVE Floating Point Multiply-Add - Indexed Group
2367//===----------------------------------------------------------------------===//
2368
2369class sve_fp_fma_by_indexed_elem<bits<2> sz, bits<2> opc, string asm,
2370                                 ZPRRegOp zprty1,
2371                                 ZPRRegOp zprty2, Operand itype>
2372: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty1:$Zn, zprty2:$Zm, itype:$iop),
2373  asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
2374  bits<5> Zda;
2375  bits<5> Zn;
2376  let Inst{31-24} = 0b01100100;
2377  let Inst{23-22} = sz;
2378  let Inst{21}    = 0b1;
2379  let Inst{15-12} = 0b0000;
2380  let Inst{11-10} = opc;
2381  let Inst{9-5}   = Zn;
2382  let Inst{4-0}   = Zda;
2383
2384  let Constraints = "$Zda = $_Zda";
2385  let DestructiveInstType = DestructiveOther;
2386  let ElementSize = ElementSizeNone;
2387  let hasSideEffects = 0;
2388  let mayRaiseFPException = 1;
2389}
2390
2391multiclass sve2p1_fp_bfma_by_indexed_elem<string asm, bits<2> opc> {
2392  def NAME : sve_fp_fma_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR3b16,
2393                                         VectorIndexH32b> {
2394    bits<3> Zm;
2395    bits<3> iop;
2396    let Inst{22} = iop{2};
2397    let Inst{20-19} = iop{1-0};
2398    let Inst{18-16} = Zm;
2399  }
2400}
2401
2402multiclass sve_fp_fma_by_indexed_elem<bits<2> opc, string asm,
2403                                      SDPatternOperator op> {
2404  def _H : sve_fp_fma_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2405    bits<3> Zm;
2406    bits<3> iop;
2407    let Inst{22} = iop{2};
2408    let Inst{20-19} = iop{1-0};
2409    let Inst{18-16} = Zm;
2410  }
2411  def _S : sve_fp_fma_by_indexed_elem<0b10, opc, asm, ZPR32, ZPR3b32, VectorIndexS32b> {
2412    bits<3> Zm;
2413    bits<2> iop;
2414    let Inst{20-19} = iop;
2415    let Inst{18-16} = Zm;
2416  }
2417  def _D : sve_fp_fma_by_indexed_elem<0b11, opc, asm, ZPR64, ZPR4b64, VectorIndexD32b> {
2418    bits<4> Zm;
2419    bit iop;
2420    let Inst{20} = iop;
2421    let Inst{19-16} = Zm;
2422  }
2423
2424  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 VectorIndexH32b_timm:$idx))),
2425            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, VectorIndexH32b_timm:$idx)>;
2426  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 VectorIndexS32b_timm:$idx))),
2427            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, VectorIndexS32b_timm:$idx)>;
2428  def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, (i32 VectorIndexD32b_timm:$idx))),
2429            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, VectorIndexD32b_timm:$idx)>;
2430}
2431
2432
2433//===----------------------------------------------------------------------===//
2434// SVE Floating Point Multiply - Indexed Group
2435//===----------------------------------------------------------------------===//
2436
2437class sve_fp_fmul_by_indexed_elem<bits<2> sz, bit o2, string asm, ZPRRegOp zprty,
2438                                  ZPRRegOp zprty2, Operand itype>
2439: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty2:$Zm, itype:$iop),
2440  asm, "\t$Zd, $Zn, $Zm$iop", "", []>, Sched<[]> {
2441  bits<5> Zd;
2442  bits<5> Zn;
2443  let Inst{31-24} = 0b01100100;
2444  let Inst{23-22} = sz;
2445  let Inst{21}    = 0b1;
2446  let Inst{15-12} = 0b0010;
2447  let Inst{11}    = o2;
2448  let Inst{10}    = 0b0;
2449  let Inst{9-5}   = Zn;
2450  let Inst{4-0}   = Zd;
2451
2452  let hasSideEffects = 0;
2453  let mayRaiseFPException = 1;
2454}
2455
2456multiclass sve2p1_fp_bfmul_by_indexed_elem<string asm> {
2457  def NAME : sve_fp_fmul_by_indexed_elem<{0, ?}, 0b1, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2458    bits<3> Zm;
2459    bits<3> iop;
2460    let Inst{22} = iop{2};
2461    let Inst{20-19} = iop{1-0};
2462    let Inst{18-16} = Zm;
2463  }
2464}
2465
2466multiclass sve_fp_fmul_by_indexed_elem<string asm, SDPatternOperator op> {
2467  def _H : sve_fp_fmul_by_indexed_elem<{0, ?}, 0b0, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2468    bits<3> Zm;
2469    bits<3> iop;
2470    let Inst{22} = iop{2};
2471    let Inst{20-19} = iop{1-0};
2472    let Inst{18-16} = Zm;
2473  }
2474  def _S : sve_fp_fmul_by_indexed_elem<0b10, 0b0, asm, ZPR32, ZPR3b32, VectorIndexS32b> {
2475    bits<3> Zm;
2476    bits<2> iop;
2477    let Inst{20-19} = iop;
2478    let Inst{18-16} = Zm;
2479  }
2480  def _D : sve_fp_fmul_by_indexed_elem<0b11, 0b0, asm, ZPR64, ZPR4b64, VectorIndexD32b> {
2481    bits<4> Zm;
2482    bit iop;
2483    let Inst{20} = iop;
2484    let Inst{19-16} = Zm;
2485  }
2486
2487  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, (i32 VectorIndexH32b_timm:$idx))),
2488            (!cast<Instruction>(NAME # _H) $Op1, $Op2, VectorIndexH32b_timm:$idx)>;
2489  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, (i32 VectorIndexS32b_timm:$idx))),
2490            (!cast<Instruction>(NAME # _S) $Op1, $Op2, VectorIndexS32b_timm:$idx)>;
2491  def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, (i32 VectorIndexD32b_timm:$idx))),
2492            (!cast<Instruction>(NAME # _D) $Op1, $Op2, VectorIndexD32b_timm:$idx)>;
2493}
2494
2495//===----------------------------------------------------------------------===//
2496// SVE Floating Point Complex Multiply-Add Group
2497//===----------------------------------------------------------------------===//
2498
2499class sve_fp_fcmla<bits<2> sz, string asm, ZPRRegOp zprty>
2500: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm,
2501                        complexrotateop:$imm),
2502  asm, "\t$Zda, $Pg/m, $Zn, $Zm, $imm",
2503  "", []>, Sched<[]> {
2504  bits<5> Zda;
2505  bits<3> Pg;
2506  bits<5> Zn;
2507  bits<5> Zm;
2508  bits<2> imm;
2509  let Inst{31-24} = 0b01100100;
2510  let Inst{23-22} = sz;
2511  let Inst{21}    = 0;
2512  let Inst{20-16} = Zm;
2513  let Inst{15}    = 0;
2514  let Inst{14-13} = imm;
2515  let Inst{12-10} = Pg;
2516  let Inst{9-5}   = Zn;
2517  let Inst{4-0}   = Zda;
2518
2519  let Constraints = "$Zda = $_Zda";
2520  let DestructiveInstType = DestructiveOther;
2521  let ElementSize = zprty.ElementSize;
2522  let hasSideEffects = 0;
2523  let mayRaiseFPException = 1;
2524}
2525
2526multiclass sve_fp_fcmla<string asm, SDPatternOperator op> {
2527  def _H : sve_fp_fcmla<0b01, asm, ZPR16>;
2528  def _S : sve_fp_fcmla<0b10, asm, ZPR32>;
2529  def _D : sve_fp_fcmla<0b11, asm, ZPR64>;
2530
2531  def : Pat<(nxv8f16 (op nxv8i1:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, nxv8f16:$Op4, (i32 complexrotateop:$imm))),
2532            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2533  def : Pat<(nxv4f32 (op nxv4i1:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, nxv4f32:$Op4, (i32 complexrotateop:$imm))),
2534            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2535  def : Pat<(nxv2f64 (op nxv2i1:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, nxv2f64:$Op4, (i32 complexrotateop:$imm))),
2536            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2537}
2538
2539//===----------------------------------------------------------------------===//
2540// SVE Floating Point Complex Multiply-Add - Indexed Group
2541//===----------------------------------------------------------------------===//
2542
2543class sve_fp_fcmla_by_indexed_elem<bits<2> sz, string asm,
2544                                   ZPRRegOp zprty,
2545                                   ZPRRegOp zprty2, Operand itype>
2546: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, zprty2:$Zm, itype:$iop,
2547                        complexrotateop:$imm),
2548  asm, "\t$Zda, $Zn, $Zm$iop, $imm",
2549  "", []>, Sched<[]> {
2550  bits<5> Zda;
2551  bits<5> Zn;
2552  bits<2> imm;
2553  let Inst{31-24} = 0b01100100;
2554  let Inst{23-22} = sz;
2555  let Inst{21}    = 0b1;
2556  let Inst{15-12} = 0b0001;
2557  let Inst{11-10} = imm;
2558  let Inst{9-5}   = Zn;
2559  let Inst{4-0}   = Zda;
2560
2561  let Constraints = "$Zda = $_Zda";
2562  let DestructiveInstType = DestructiveOther;
2563  let ElementSize = ElementSizeNone;
2564  let hasSideEffects = 0;
2565  let mayRaiseFPException = 1;
2566}
2567
2568multiclass sve_fp_fcmla_by_indexed_elem<string asm, SDPatternOperator op> {
2569  def _H : sve_fp_fcmla_by_indexed_elem<0b10, asm, ZPR16, ZPR3b16, VectorIndexS32b> {
2570    bits<3> Zm;
2571    bits<2> iop;
2572    let Inst{20-19} = iop;
2573    let Inst{18-16} = Zm;
2574  }
2575  def _S : sve_fp_fcmla_by_indexed_elem<0b11, asm, ZPR32, ZPR4b32, VectorIndexD32b> {
2576    bits<4> Zm;
2577    bits<1> iop;
2578    let Inst{20} = iop;
2579    let Inst{19-16} = Zm;
2580  }
2581
2582  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
2583            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
2584  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
2585            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
2586}
2587
2588//===----------------------------------------------------------------------===//
2589// SVE Floating Point Complex Addition Group
2590//===----------------------------------------------------------------------===//
2591
2592class sve_fp_fcadd<bits<2> sz, string asm, ZPRRegOp zprty>
2593: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm,
2594                        complexrotateopodd:$imm),
2595  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm, $imm",
2596  "",
2597  []>, Sched<[]> {
2598  bits<5> Zdn;
2599  bits<5> Zm;
2600  bits<3> Pg;
2601  bit imm;
2602  let Inst{31-24} = 0b01100100;
2603  let Inst{23-22} = sz;
2604  let Inst{21-17} = 0;
2605  let Inst{16}    = imm;
2606  let Inst{15-13} = 0b100;
2607  let Inst{12-10} = Pg;
2608  let Inst{9-5}   = Zm;
2609  let Inst{4-0}   = Zdn;
2610
2611  let Constraints = "$Zdn = $_Zdn";
2612  let DestructiveInstType = DestructiveOther;
2613  let ElementSize = zprty.ElementSize;
2614  let hasSideEffects = 0;
2615  let mayRaiseFPException = 1;
2616}
2617
2618multiclass sve_fp_fcadd<string asm, SDPatternOperator op> {
2619  def _H : sve_fp_fcadd<0b01, asm, ZPR16>;
2620  def _S : sve_fp_fcadd<0b10, asm, ZPR32>;
2621  def _D : sve_fp_fcadd<0b11, asm, ZPR64>;
2622
2623  def : Pat<(nxv8f16 (op nxv8i1:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 complexrotateopodd:$imm))),
2624            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2625  def : Pat<(nxv4f32 (op nxv4i1:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 complexrotateopodd:$imm))),
2626            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2627  def : Pat<(nxv2f64 (op nxv2i1:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, (i32 complexrotateopodd:$imm))),
2628            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2629}
2630
2631//===----------------------------------------------------------------------===//
2632// SVE2 Floating Point Convert Group
2633//===----------------------------------------------------------------------===//
2634
2635class sve2_fp_convert_precision<bits<4> opc, string asm,
2636                                ZPRRegOp zprty1, ZPRRegOp zprty2>
2637: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, PPR3bAny:$Pg, zprty2:$Zn),
2638  asm, "\t$Zd, $Pg/m, $Zn",
2639  "",
2640  []>, Sched<[]> {
2641  bits<5> Zd;
2642  bits<5> Zn;
2643  bits<3> Pg;
2644  let Inst{31-24} = 0b01100100;
2645  let Inst{23-22} = opc{3-2};
2646  let Inst{21-18} = 0b0010;
2647  let Inst{17-16} = opc{1-0};
2648  let Inst{15-13} = 0b101;
2649  let Inst{12-10} = Pg;
2650  let Inst{9-5}   = Zn;
2651  let Inst{4-0}   = Zd;
2652
2653  let Constraints = "$Zd = $_Zd";
2654  let hasSideEffects = 0;
2655  let mayRaiseFPException = 1;
2656}
2657
2658multiclass sve2_fp_convert_down_narrow<string asm, string op> {
2659  def _StoH : sve2_fp_convert_precision<0b1000, asm, ZPR16, ZPR32>;
2660  def _DtoS : sve2_fp_convert_precision<0b1110, asm, ZPR32, ZPR64>;
2661
2662  def : SVE_3_Op_Pat<nxv8f16, !cast<SDPatternOperator>(op # _f16f32), nxv8f16, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _StoH)>;
2663  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
2664}
2665
2666multiclass sve2_fp_convert_up_long<string asm, string op> {
2667  def _HtoS : sve2_fp_convert_precision<0b1001, asm, ZPR32, ZPR16>;
2668  def _StoD : sve2_fp_convert_precision<0b1111, asm, ZPR64, ZPR32>;
2669
2670  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f16), nxv4f32, nxv4i1, nxv8f16, !cast<Instruction>(NAME # _HtoS)>;
2671  def : SVE_3_Op_Pat<nxv2f64, !cast<SDPatternOperator>(op # _f64f32), nxv2f64, nxv2i1, nxv4f32, !cast<Instruction>(NAME # _StoD)>;
2672}
2673
2674multiclass sve2_fp_convert_down_odd_rounding_top<string asm, string op> {
2675  def _DtoS : sve2_fp_convert_precision<0b0010, asm, ZPR32, ZPR64>;
2676
2677  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
2678}
2679
2680//===----------------------------------------------------------------------===//
2681// SVE2 Floating Point Pairwise Group
2682//===----------------------------------------------------------------------===//
2683
2684class sve2_fp_pairwise_pred<bits<2> sz, bits<3> opc, string asm,
2685                            ZPRRegOp zprty>
2686: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
2687  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
2688  "",
2689  []>, Sched<[]> {
2690  bits<3> Pg;
2691  bits<5> Zm;
2692  bits<5> Zdn;
2693  let Inst{31-24} = 0b01100100;
2694  let Inst{23-22} = sz;
2695  let Inst{21-19} = 0b010;
2696  let Inst{18-16} = opc;
2697  let Inst{15-13} = 0b100;
2698  let Inst{12-10} = Pg;
2699  let Inst{9-5}   = Zm;
2700  let Inst{4-0}   = Zdn;
2701
2702  let Constraints = "$Zdn = $_Zdn";
2703  let DestructiveInstType = DestructiveOther;
2704  let ElementSize = zprty.ElementSize;
2705  let hasSideEffects = 0;
2706  let mayRaiseFPException = 1;
2707}
2708
2709multiclass sve2_fp_pairwise_pred<bits<3> opc, string asm,
2710                                 SDPatternOperator op> {
2711  def _H : sve2_fp_pairwise_pred<0b01, opc, asm, ZPR16>;
2712  def _S : sve2_fp_pairwise_pred<0b10, opc, asm, ZPR32>;
2713  def _D : sve2_fp_pairwise_pred<0b11, opc, asm, ZPR64>;
2714
2715  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2716  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2717  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2718}
2719
2720//===----------------------------------------------------------------------===//
2721// SVE2 Floating Point Widening Multiply-Add - Indexed Group
2722//===----------------------------------------------------------------------===//
2723
2724class sve2_fp_mla_long_by_indexed_elem<bits<3> opc, string asm>
2725: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR3b16:$Zm,
2726                        VectorIndexH32b:$iop),
2727  asm, "\t$Zda, $Zn, $Zm$iop",
2728  "",
2729  []>, Sched<[]> {
2730  bits<5> Zda;
2731  bits<5> Zn;
2732  bits<3> Zm;
2733  bits<3> iop;
2734  let Inst{31-23} = 0b011001001;
2735  let Inst{22}    = opc{2};
2736  let Inst{21}    = 0b1;
2737  let Inst{20-19} = iop{2-1};
2738  let Inst{18-16} = Zm;
2739  let Inst{15-14} = 0b01;
2740  let Inst{13}    = opc{1};
2741  let Inst{12}    = 0b0;
2742  let Inst{11}    = iop{0};
2743  let Inst{10}    = opc{0};
2744  let Inst{9-5}   = Zn;
2745  let Inst{4-0}   = Zda;
2746
2747  let Constraints = "$Zda = $_Zda";
2748  let DestructiveInstType = DestructiveOther;
2749  let ElementSize = ElementSizeNone;
2750  let hasSideEffects = 0;
2751  let mayRaiseFPException = 1;
2752}
2753
2754multiclass sve2_fp_mla_long_by_indexed_elem<bits<3> opc, string asm,
2755                                            ValueType OutVT, ValueType InVT,
2756                                            SDPatternOperator op> {
2757  def NAME : sve2_fp_mla_long_by_indexed_elem<opc, asm>;
2758  def : SVE_4_Op_Imm_Pat<OutVT, op, OutVT, InVT, InVT, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME)>;
2759}
2760
2761//===----------------------------------------------------------------------===//
2762// SVE2 Floating Point Widening Multiply-Add Group
2763//===----------------------------------------------------------------------===//
2764
2765class sve2_fp_mla_long<bits<3> opc, string asm>
2766: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
2767  asm, "\t$Zda, $Zn, $Zm",
2768  "",
2769  []>, Sched<[]> {
2770  bits<5> Zda;
2771  bits<5> Zn;
2772  bits<5> Zm;
2773  let Inst{31-23} = 0b011001001;
2774  let Inst{22}    = opc{2};
2775  let Inst{21}    = 0b1;
2776  let Inst{20-16} = Zm;
2777  let Inst{15-14} = 0b10;
2778  let Inst{13}    = opc{1};
2779  let Inst{12-11} = 0b00;
2780  let Inst{10}    = opc{0};
2781  let Inst{9-5}   = Zn;
2782  let Inst{4-0}   = Zda;
2783
2784  let Constraints = "$Zda = $_Zda";
2785  let DestructiveInstType = DestructiveOther;
2786  let ElementSize = ElementSizeNone;
2787  let hasSideEffects = 0;
2788  let mayRaiseFPException = 1;
2789}
2790
2791multiclass sve2_fp_mla_long<bits<3> opc, string asm, ValueType OutVT,
2792                            ValueType InVT, SDPatternOperator op> {
2793  def NAME : sve2_fp_mla_long<opc, asm>;
2794  def : SVE_3_Op_Pat<OutVT, op, OutVT, InVT, InVT, !cast<Instruction>(NAME)>;
2795}
2796
2797//===----------------------------------------------------------------------===//
2798// SVE Stack Allocation Group
2799//===----------------------------------------------------------------------===//
2800
2801class sve_int_arith_vl<bit opc, string asm, bit streaming_sve = 0b0>
2802: I<(outs GPR64sp:$Rd), (ins GPR64sp:$Rn, simm6_32b:$imm6),
2803  asm, "\t$Rd, $Rn, $imm6",
2804  "",
2805  []>, Sched<[]> {
2806  bits<5> Rd;
2807  bits<5> Rn;
2808  bits<6> imm6;
2809  let Inst{31-23} = 0b000001000;
2810  let Inst{22}    = opc;
2811  let Inst{21}    = 0b1;
2812  let Inst{20-16} = Rn;
2813  let Inst{15-12} = 0b0101;
2814  let Inst{11}    = streaming_sve;
2815  let Inst{10-5}  = imm6;
2816  let Inst{4-0}   = Rd;
2817
2818  let hasSideEffects = 0;
2819}
2820
2821class sve_int_read_vl_a<bit op, bits<5> opc2, string asm, bit streaming_sve = 0b0>
2822: I<(outs GPR64:$Rd), (ins simm6_32b:$imm6),
2823  asm, "\t$Rd, $imm6",
2824  "",
2825  []>, Sched<[]> {
2826  bits<5> Rd;
2827  bits<6> imm6;
2828  let Inst{31-23} = 0b000001001;
2829  let Inst{22}    = op;
2830  let Inst{21}    = 0b1;
2831  let Inst{20-16} = opc2{4-0};
2832  let Inst{15-12} = 0b0101;
2833  let Inst{11}    = streaming_sve;
2834  let Inst{10-5}  = imm6;
2835  let Inst{4-0}   = Rd;
2836
2837  let hasSideEffects = 0;
2838  let isReMaterializable = 1;
2839}
2840
2841//===----------------------------------------------------------------------===//
2842// SVE Permute - In Lane Group
2843//===----------------------------------------------------------------------===//
2844
2845class sve_int_perm_bin_perm_zz<bits<3> opc, bits<2> sz8_64, string asm,
2846                               ZPRRegOp zprty>
2847: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
2848  asm, "\t$Zd, $Zn, $Zm",
2849  "",
2850  []>, Sched<[]> {
2851  bits<5> Zd;
2852  bits<5> Zm;
2853  bits<5> Zn;
2854  let Inst{31-24} = 0b00000101;
2855  let Inst{23-22} = sz8_64;
2856  let Inst{21}    = 0b1;
2857  let Inst{20-16} = Zm;
2858  let Inst{15-13} = 0b011;
2859  let Inst{12-10} = opc;
2860  let Inst{9-5}   = Zn;
2861  let Inst{4-0}   = Zd;
2862
2863  let hasSideEffects = 0;
2864}
2865
2866multiclass sve_int_perm_bin_perm_zz<bits<3> opc, string asm,
2867                                    SDPatternOperator op> {
2868  def _B : sve_int_perm_bin_perm_zz<opc, 0b00, asm, ZPR8>;
2869  def _H : sve_int_perm_bin_perm_zz<opc, 0b01, asm, ZPR16>;
2870  def _S : sve_int_perm_bin_perm_zz<opc, 0b10, asm, ZPR32>;
2871  def _D : sve_int_perm_bin_perm_zz<opc, 0b11, asm, ZPR64>;
2872
2873  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
2874  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2875  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2876  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2877
2878  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2879  def : SVE_2_Op_Pat<nxv4f16, op, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _S)>;
2880  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2881  def : SVE_2_Op_Pat<nxv2f16, op, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _D)>;
2882  def : SVE_2_Op_Pat<nxv2f32, op, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _D)>;
2883  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2884
2885  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
2886}
2887
2888//===----------------------------------------------------------------------===//
2889// SVE Floating Point Unary Operations Group
2890//===----------------------------------------------------------------------===//
2891
2892class sve_fp_2op_p_zd<bits<7> opc, string asm, RegisterOperand i_zprtype,
2893                      RegisterOperand o_zprtype, ElementSizeEnum Sz>
2894: I<(outs o_zprtype:$Zd), (ins i_zprtype:$_Zd, PPR3bAny:$Pg, i_zprtype:$Zn),
2895  asm, "\t$Zd, $Pg/m, $Zn",
2896  "",
2897  []>, Sched<[]> {
2898  bits<3> Pg;
2899  bits<5> Zd;
2900  bits<5> Zn;
2901  let Inst{31-24} = 0b01100101;
2902  let Inst{23-22} = opc{6-5};
2903  let Inst{21}    = 0b0;
2904  let Inst{20-16} = opc{4-0};
2905  let Inst{15-13} = 0b101;
2906  let Inst{12-10} = Pg;
2907  let Inst{9-5}   = Zn;
2908  let Inst{4-0}   = Zd;
2909
2910  let Constraints = "$Zd = $_Zd";
2911  let DestructiveInstType = DestructiveUnaryPassthru;
2912  let ElementSize = Sz;
2913  let hasSideEffects = 0;
2914  let mayRaiseFPException = 1;
2915}
2916
2917multiclass sve_fp_2op_p_zd<bits<7> opc, string asm,
2918                           RegisterOperand i_zprtype,
2919                           RegisterOperand o_zprtype,
2920                           SDPatternOperator int_op,
2921                           SDPatternOperator ir_op, ValueType vt1,
2922                           ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
2923  def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>,
2924             SVEPseudo2Instr<NAME, 1>;
2925  // convert vt1 to a packed type for the intrinsic patterns
2926  defvar packedvt1 = SVEContainerVT<vt1>.Value;
2927
2928  // convert vt3 to a packed type for the intrinsic patterns
2929  defvar packedvt3 = SVEContainerVT<vt3>.Value;
2930
2931  def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, packedvt3, !cast<Instruction>(NAME)>;
2932  def : SVE_1_Op_Passthru_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
2933
2934  def _UNDEF : PredOneOpPassthruPseudo<NAME, !cast<ZPRRegOp>(i_zprtype)>;
2935
2936  defm : SVE_1_Op_PassthruUndef_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME # _UNDEF)>;
2937}
2938
2939multiclass sve_fp_2op_p_zdr<bits<7> opc, string asm,
2940                            RegisterOperand i_zprtype,
2941                            RegisterOperand o_zprtype,
2942                            SDPatternOperator int_op,
2943                            SDPatternOperator ir_op, ValueType vt1,
2944                            ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
2945  def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>,
2946             SVEPseudo2Instr<NAME, 1>;
2947
2948  // convert vt1 to a packed type for the intrinsic patterns
2949  defvar packedvt1 = SVEContainerVT<vt1>.Value;
2950
2951  def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, vt3, !cast<Instruction>(NAME)>;
2952  def : SVE_1_Op_Passthru_Round_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
2953
2954  def _UNDEF : PredOneOpPassthruPseudo<NAME, !cast<ZPRRegOp>(i_zprtype)>;
2955
2956  defm : SVE_1_Op_PassthruUndef_Round_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME # _UNDEF)>;
2957}
2958
2959multiclass sve_fp_2op_p_zd_HSD<bits<5> opc, string asm, SDPatternOperator op> {
2960  def _H : sve_fp_2op_p_zd<{ 0b01, opc }, asm, ZPR16, ZPR16, ElementSizeH>,
2961           SVEPseudo2Instr<NAME # _H, 1>;
2962  def _S : sve_fp_2op_p_zd<{ 0b10, opc }, asm, ZPR32, ZPR32, ElementSizeS>,
2963           SVEPseudo2Instr<NAME # _S, 1>;
2964  def _D : sve_fp_2op_p_zd<{ 0b11, opc }, asm, ZPR64, ZPR64, ElementSizeD>,
2965           SVEPseudo2Instr<NAME # _D, 1>;
2966
2967  def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
2968  def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
2969  def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
2970  def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
2971  def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
2972  def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
2973
2974  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
2975  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
2976  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
2977
2978  defm : SVE_1_Op_PassthruUndef_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H_UNDEF)>;
2979  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H_UNDEF)>;
2980  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H_UNDEF)>;
2981  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S_UNDEF)>;
2982  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S_UNDEF)>;
2983  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D_UNDEF)>;
2984}
2985
2986multiclass sve2_fp_flogb<string asm, string Ps, SDPatternOperator op> {
2987  def _H : sve_fp_2op_p_zd<0b0011010, asm, ZPR16, ZPR16, ElementSizeH>,
2988             SVEPseudo2Instr<Ps # _H, 1>;
2989  def _S : sve_fp_2op_p_zd<0b0011100, asm, ZPR32, ZPR32, ElementSizeS>,
2990             SVEPseudo2Instr<Ps # _S, 1>;
2991  def _D : sve_fp_2op_p_zd<0b0011110, asm, ZPR64, ZPR64, ElementSizeD>,
2992             SVEPseudo2Instr<Ps # _D, 1>;
2993
2994  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
2995  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
2996  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
2997}
2998
2999multiclass sve2_fp_un_pred_zeroing_hsd<SDPatternOperator op> {
3000  def _H_ZERO : PredOneOpPassthruPseudo<NAME # _H, ZPR16, FalseLanesZero>;
3001  def _S_ZERO : PredOneOpPassthruPseudo<NAME # _S, ZPR32, FalseLanesZero>;
3002  def _D_ZERO : PredOneOpPassthruPseudo<NAME # _D, ZPR64, FalseLanesZero>;
3003
3004  def : SVE_1_Op_PassthruZero_Pat<nxv8i16, op, nxv8i1, nxv8f16, !cast<Pseudo>(NAME # _H_ZERO)>;
3005  def : SVE_1_Op_PassthruZero_Pat<nxv4i32, op, nxv4i1, nxv4f32, !cast<Pseudo>(NAME # _S_ZERO)>;
3006  def : SVE_1_Op_PassthruZero_Pat<nxv2i64, op, nxv2i1, nxv2f64, !cast<Pseudo>(NAME # _D_ZERO)>;
3007}
3008
3009multiclass sve2_fp_convert_down_odd_rounding<string asm, string op> {
3010  def _DtoS : sve_fp_2op_p_zd<0b0001010, asm, ZPR64, ZPR32, ElementSizeD>;
3011  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
3012}
3013
3014//===----------------------------------------------------------------------===//
3015// SVE Floating Point Unary Operations - Unpredicated Group
3016//===----------------------------------------------------------------------===//
3017
3018class sve_fp_2op_u_zd<bits<2> sz, bits<3> opc, string asm,
3019                      ZPRRegOp zprty>
3020: I<(outs zprty:$Zd), (ins zprty:$Zn),
3021  asm, "\t$Zd, $Zn",
3022  "",
3023  []>, Sched<[]> {
3024  bits<5> Zd;
3025  bits<5> Zn;
3026  let Inst{31-24} = 0b01100101;
3027  let Inst{23-22} = sz;
3028  let Inst{21-19} = 0b001;
3029  let Inst{18-16} = opc;
3030  let Inst{15-10} = 0b001100;
3031  let Inst{9-5}   = Zn;
3032  let Inst{4-0}   = Zd;
3033
3034  let hasSideEffects = 0;
3035  let mayRaiseFPException = 1;
3036}
3037
3038multiclass sve_fp_2op_u_zd<bits<3> opc, string asm, SDPatternOperator op> {
3039  def _H : sve_fp_2op_u_zd<0b01, opc, asm, ZPR16>;
3040  def _S : sve_fp_2op_u_zd<0b10, opc, asm, ZPR32>;
3041  def _D : sve_fp_2op_u_zd<0b11, opc, asm, ZPR64>;
3042
3043  def : SVE_1_Op_Pat<nxv8f16, op, nxv8f16, !cast<Instruction>(NAME # _H)>;
3044  def : SVE_1_Op_Pat<nxv4f32, op, nxv4f32, !cast<Instruction>(NAME # _S)>;
3045  def : SVE_1_Op_Pat<nxv2f64, op, nxv2f64, !cast<Instruction>(NAME # _D)>;
3046}
3047
3048//===----------------------------------------------------------------------===//
3049// SVE Integer Arithmetic - Binary Predicated Group
3050//===----------------------------------------------------------------------===//
3051
3052class sve_int_bin_pred_arit_log<bits<2> sz8_64, bits<2> fmt, bits<3> opc,
3053                                string asm, ZPRRegOp zprty>
3054: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
3055  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm", "", []>, Sched<[]> {
3056  bits<3> Pg;
3057  bits<5> Zdn;
3058  bits<5> Zm;
3059  let Inst{31-24} = 0b00000100;
3060  let Inst{23-22} = sz8_64;
3061  let Inst{21}    = 0b0;
3062  let Inst{20-19} = fmt;
3063  let Inst{18-16} = opc;
3064  let Inst{15-13} = 0b000;
3065  let Inst{12-10} = Pg;
3066  let Inst{9-5}   = Zm;
3067  let Inst{4-0}   = Zdn;
3068
3069  let Constraints = "$Zdn = $_Zdn";
3070  let DestructiveInstType = DestructiveOther;
3071  let ElementSize = zprty.ElementSize;
3072  let hasSideEffects = 0;
3073}
3074
3075multiclass sve_int_bin_pred_log<bits<3> opc, string asm, string Ps,
3076                                SDPatternOperator op,
3077                                DestructiveInstTypeEnum flags> {
3078  let DestructiveInstType = flags in {
3079  def _B : sve_int_bin_pred_arit_log<0b00, 0b11, opc, asm, ZPR8>,
3080             SVEPseudo2Instr<Ps # _B, 1>;
3081  def _H : sve_int_bin_pred_arit_log<0b01, 0b11, opc, asm, ZPR16>,
3082             SVEPseudo2Instr<Ps # _H, 1>;
3083  def _S : sve_int_bin_pred_arit_log<0b10, 0b11, opc, asm, ZPR32>,
3084             SVEPseudo2Instr<Ps # _S, 1>;
3085  def _D : sve_int_bin_pred_arit_log<0b11, 0b11, opc, asm, ZPR64>,
3086             SVEPseudo2Instr<Ps # _D, 1>;
3087  }
3088
3089  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3090  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3091  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3092  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3093}
3094
3095multiclass sve_int_bin_pred_arit_0<bits<3> opc, string asm, string Ps,
3096                                   SDPatternOperator op,
3097                                   DestructiveInstTypeEnum flags,
3098                                   string revname="", bit isReverseInstr=0> {
3099  let DestructiveInstType = flags in {
3100  def _B : sve_int_bin_pred_arit_log<0b00, 0b00, opc, asm, ZPR8>,
3101           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3102  def _H : sve_int_bin_pred_arit_log<0b01, 0b00, opc, asm, ZPR16>,
3103           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3104  def _S : sve_int_bin_pred_arit_log<0b10, 0b00, opc, asm, ZPR32>,
3105           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3106  def _D : sve_int_bin_pred_arit_log<0b11, 0b00, opc, asm, ZPR64>,
3107           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3108  }
3109
3110  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3111  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3112  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3113  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3114}
3115
3116multiclass sve_int_bin_pred_arit_1<bits<3> opc, string asm, string Ps,
3117                                   SDPatternOperator op,
3118                                   DestructiveInstTypeEnum flags> {
3119  let DestructiveInstType = flags in {
3120  def _B : sve_int_bin_pred_arit_log<0b00, 0b01, opc, asm, ZPR8>,
3121           SVEPseudo2Instr<Ps # _B, 1>;
3122  def _H : sve_int_bin_pred_arit_log<0b01, 0b01, opc, asm, ZPR16>,
3123           SVEPseudo2Instr<Ps # _H, 1>;
3124  def _S : sve_int_bin_pred_arit_log<0b10, 0b01, opc, asm, ZPR32>,
3125           SVEPseudo2Instr<Ps # _S, 1>;
3126  def _D : sve_int_bin_pred_arit_log<0b11, 0b01, opc, asm, ZPR64>,
3127           SVEPseudo2Instr<Ps # _D, 1>;
3128  }
3129
3130  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3131  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3132  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3133  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3134}
3135
3136multiclass sve_int_bin_pred_arit_2<bits<3> opc, string asm, string Ps,
3137                                   SDPatternOperator op,
3138                                   DestructiveInstTypeEnum flags> {
3139  let DestructiveInstType = flags in {
3140  def _B : sve_int_bin_pred_arit_log<0b00, 0b10, opc, asm, ZPR8>,
3141           SVEPseudo2Instr<Ps # _B, 1>;
3142  def _H : sve_int_bin_pred_arit_log<0b01, 0b10, opc, asm, ZPR16>,
3143           SVEPseudo2Instr<Ps # _H, 1>;
3144  def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>,
3145           SVEPseudo2Instr<Ps # _S, 1>;
3146  def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>,
3147           SVEPseudo2Instr<Ps # _D, 1>;
3148  }
3149
3150  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3151  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3152  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3153  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3154}
3155
3156// Special case for divides which are not defined for 8b/16b elements.
3157multiclass sve_int_bin_pred_arit_2_div<bits<3> opc, string asm, string Ps,
3158                                       SDPatternOperator op,
3159                                       DestructiveInstTypeEnum flags,
3160                                       string revname="", bit isReverseInstr=0> {
3161  let DestructiveInstType = flags in {
3162  def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>,
3163           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3164  def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>,
3165           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3166  }
3167
3168  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3169  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3170}
3171
3172//===----------------------------------------------------------------------===//
3173// SVE Integer Multiply-Add Group
3174//===----------------------------------------------------------------------===//
3175
3176class sve_int_mladdsub_vvv_pred<bits<2> sz8_64, bits<1> opc, string asm,
3177                                ZPRRegOp zprty>
3178: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm, zprty:$Za),
3179  asm, "\t$Zdn, $Pg/m, $Zm, $Za",
3180  "",
3181  []>, Sched<[]> {
3182  bits<3> Pg;
3183  bits<5> Zdn;
3184  bits<5> Za;
3185  bits<5> Zm;
3186  let Inst{31-24} = 0b00000100;
3187  let Inst{23-22} = sz8_64;
3188  let Inst{21}    = 0b0;
3189  let Inst{20-16} = Zm;
3190  let Inst{15-14} = 0b11;
3191  let Inst{13}    = opc;
3192  let Inst{12-10} = Pg;
3193  let Inst{9-5}   = Za;
3194  let Inst{4-0}   = Zdn;
3195
3196  let Constraints = "$Zdn = $_Zdn";
3197  let DestructiveInstType = DestructiveOther;
3198  let ElementSize = zprty.ElementSize;
3199  let hasSideEffects = 0;
3200}
3201
3202multiclass sve_int_mladdsub_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
3203                                     string revname, bit isReverseInstr=0> {
3204  def _B : sve_int_mladdsub_vvv_pred<0b00, opc, asm, ZPR8>,
3205           SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3206  def _H : sve_int_mladdsub_vvv_pred<0b01, opc, asm, ZPR16>,
3207           SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3208  def _S : sve_int_mladdsub_vvv_pred<0b10, opc, asm, ZPR32>,
3209           SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3210  def _D : sve_int_mladdsub_vvv_pred<0b11, opc, asm, ZPR64>,
3211           SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3212
3213  def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3214  def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3215  def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3216  def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3217}
3218
3219class sve_int_mlas_vvv_pred<bits<2> sz8_64, bits<1> opc, string asm,
3220                            ZPRRegOp zprty>
3221: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm),
3222  asm, "\t$Zda, $Pg/m, $Zn, $Zm",
3223  "",
3224  []>, Sched<[]> {
3225  bits<3> Pg;
3226  bits<5> Zda;
3227  bits<5> Zm;
3228  bits<5> Zn;
3229  let Inst{31-24} = 0b00000100;
3230  let Inst{23-22} = sz8_64;
3231  let Inst{21}    = 0b0;
3232  let Inst{20-16} = Zm;
3233  let Inst{15-14} = 0b01;
3234  let Inst{13}    = opc;
3235  let Inst{12-10} = Pg;
3236  let Inst{9-5}   = Zn;
3237  let Inst{4-0}   = Zda;
3238
3239  let Constraints = "$Zda = $_Zda";
3240  let DestructiveInstType = DestructiveTernaryCommWithRev;
3241  let ElementSize = zprty.ElementSize;
3242  let hasSideEffects = 0;
3243}
3244
3245multiclass sve_int_mlas_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
3246                                 string Ps, string revname, bit isReverseInstr=0> {
3247  def _B : sve_int_mlas_vvv_pred<0b00, opc, asm, ZPR8>,
3248           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3249  def _H : sve_int_mlas_vvv_pred<0b01, opc, asm, ZPR16>,
3250           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3251  def _S : sve_int_mlas_vvv_pred<0b10, opc, asm, ZPR32>,
3252           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3253  def _D : sve_int_mlas_vvv_pred<0b11, opc, asm, ZPR64>,
3254           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3255
3256  def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3257  def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3258  def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3259  def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3260}
3261
3262//class for generating pseudo for SVE MLA/MAD/MLS/MSB
3263multiclass sve_int_3op_p_mladdsub<SDPatternOperator op> {
3264  def _B_UNDEF : PredThreeOpPseudo<NAME # _B, ZPR8,  FalseLanesUndef>;
3265  def _H_UNDEF : PredThreeOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
3266  def _S_UNDEF : PredThreeOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
3267  def _D_UNDEF : PredThreeOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
3268
3269  let  AddedComplexity = 9 in {
3270    def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B_UNDEF)>;
3271    def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H_UNDEF)>;
3272    def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S_UNDEF)>;
3273    def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D_UNDEF)>;
3274  }
3275}
3276
3277//===----------------------------------------------------------------------===//
3278// SVE2 Integer Multiply-Add - Unpredicated Group
3279//===----------------------------------------------------------------------===//
3280
3281class sve2_int_mla<bits<2> sz, bits<5> opc, string asm,
3282                   ZPRRegOp zprty1, ZPRRegOp zprty2>
3283: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm),
3284  asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
3285  bits<5> Zda;
3286  bits<5> Zn;
3287  bits<5> Zm;
3288  let Inst{31-24} = 0b01000100;
3289  let Inst{23-22} = sz;
3290  let Inst{21}    = 0b0;
3291  let Inst{20-16} = Zm;
3292  let Inst{15}    = 0b0;
3293  let Inst{14-10} = opc;
3294  let Inst{9-5}   = Zn;
3295  let Inst{4-0}   = Zda;
3296
3297  let Constraints = "$Zda = $_Zda";
3298  let DestructiveInstType = DestructiveOther;
3299  let ElementSize = ElementSizeNone;
3300  let hasSideEffects = 0;
3301}
3302
3303multiclass sve2_int_mla<bit S, string asm, SDPatternOperator op> {
3304  def _B : sve2_int_mla<0b00, { 0b1110, S }, asm, ZPR8, ZPR8>;
3305  def _H : sve2_int_mla<0b01, { 0b1110, S }, asm, ZPR16, ZPR16>;
3306  def _S : sve2_int_mla<0b10, { 0b1110, S }, asm, ZPR32, ZPR32>;
3307  def _D : sve2_int_mla<0b11, { 0b1110, S }, asm, ZPR64, ZPR64>;
3308
3309  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3310  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3311  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3312  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3313}
3314
3315multiclass sve2_int_mla_long<bits<5> opc, string asm, SDPatternOperator op> {
3316  def _H : sve2_int_mla<0b01, opc, asm, ZPR16, ZPR8>;
3317  def _S : sve2_int_mla<0b10, opc, asm, ZPR32, ZPR16>;
3318  def _D : sve2_int_mla<0b11, opc, asm, ZPR64, ZPR32>;
3319
3320  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3321  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
3322  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3323}
3324
3325//===----------------------------------------------------------------------===//
3326// SVE2 Integer Multiply-Add - Indexed Group
3327//===----------------------------------------------------------------------===//
3328
3329class sve2_int_mla_by_indexed_elem<bits<2> sz, bits<6> opc, string asm,
3330                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3331                                   ZPRRegOp zprty3, Operand itype>
3332: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop),
3333  asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
3334  bits<5> Zda;
3335  bits<5> Zn;
3336  let Inst{31-24} = 0b01000100;
3337  let Inst{23-22} = sz;
3338  let Inst{21}    = 0b1;
3339  let Inst{15-10} = opc;
3340  let Inst{9-5}   = Zn;
3341  let Inst{4-0}   = Zda;
3342
3343  let Constraints = "$Zda = $_Zda";
3344  let DestructiveInstType = DestructiveOther;
3345  let ElementSize = ElementSizeNone;
3346  let hasSideEffects = 0;
3347}
3348
3349multiclass sve2_int_mla_by_indexed_elem<bits<2> opc, bit S, string asm,
3350                                        SDPatternOperator op> {
3351  def _H : sve2_int_mla_by_indexed_elem<{0, ?}, { 0b000, opc, S }, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexH32b> {
3352    bits<3> Zm;
3353    bits<3> iop;
3354    let Inst{22} = iop{2};
3355    let Inst{20-19} = iop{1-0};
3356    let Inst{18-16} = Zm;
3357  }
3358  def _S : sve2_int_mla_by_indexed_elem<0b10, { 0b000, opc, S }, asm, ZPR32, ZPR32, ZPR3b32, VectorIndexS32b> {
3359    bits<3> Zm;
3360    bits<2> iop;
3361    let Inst{20-19} = iop;
3362    let Inst{18-16} = Zm;
3363  }
3364  def _D : sve2_int_mla_by_indexed_elem<0b11, { 0b000, opc, S }, asm, ZPR64, ZPR64, ZPR4b64, VectorIndexD32b> {
3365    bits<4> Zm;
3366    bit iop;
3367    let Inst{20} = iop;
3368    let Inst{19-16} = Zm;
3369  }
3370
3371  def : SVE_4_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
3372  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3373  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3374}
3375
3376//===----------------------------------------------------------------------===//
3377// SVE2 Integer Multiply-Add Long - Indexed Group
3378//===----------------------------------------------------------------------===//
3379
3380multiclass sve2_int_mla_long_by_indexed_elem<bits<4> opc, string asm,
3381                                             SDPatternOperator op> {
3382  def _S : sve2_int_mla_by_indexed_elem<0b10, { opc{3}, 0b0, opc{2-1}, ?, opc{0} },
3383                                        asm, ZPR32, ZPR16, ZPR3b16, VectorIndexH32b> {
3384    bits<3> Zm;
3385    bits<3> iop;
3386    let Inst{20-19} = iop{2-1};
3387    let Inst{18-16} = Zm;
3388    let Inst{11} = iop{0};
3389  }
3390  def _D : sve2_int_mla_by_indexed_elem<0b11, { opc{3}, 0b0, opc{2-1}, ?, opc{0} },
3391                                        asm, ZPR64, ZPR32, ZPR4b32, VectorIndexS32b> {
3392    bits<4> Zm;
3393    bits<2> iop;
3394    let Inst{20} = iop{1};
3395    let Inst{19-16} = Zm;
3396    let Inst{11} = iop{0};
3397  }
3398
3399  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _S)>;
3400  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
3401}
3402
3403//===----------------------------------------------------------------------===//
3404// SVE Integer Dot Product Group
3405//===----------------------------------------------------------------------===//
3406
3407class sve_intx_dot<bit sz, bit U, string asm, ZPRRegOp zprty1,
3408                   ZPRRegOp zprty2>
3409: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm), asm,
3410  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
3411  bits<5> Zda;
3412  bits<5> Zn;
3413  bits<5> Zm;
3414  let Inst{31-23} = 0b010001001;
3415  let Inst{22}    = sz;
3416  let Inst{21}    = 0;
3417  let Inst{20-16} = Zm;
3418  let Inst{15-11} = 0;
3419  let Inst{10}    = U;
3420  let Inst{9-5}   = Zn;
3421  let Inst{4-0}   = Zda;
3422
3423  let Constraints = "$Zda = $_Zda";
3424  let DestructiveInstType = DestructiveOther;
3425  let hasSideEffects = 0;
3426}
3427
3428multiclass sve_intx_dot<bit opc, string asm, SDPatternOperator op> {
3429  def _S : sve_intx_dot<0b0, opc, asm, ZPR32, ZPR8>;
3430  def _D : sve_intx_dot<0b1, opc, asm, ZPR64, ZPR16>;
3431
3432  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32,  nxv16i8, nxv16i8, !cast<Instruction>(NAME # _S)>;
3433  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _D)>;
3434}
3435
3436//===----------------------------------------------------------------------===//
3437// SVE Integer Dot Product Group - Indexed Group
3438//===----------------------------------------------------------------------===//
3439
3440class sve_intx_dot_by_indexed_elem<bit sz, bit U, string asm,
3441                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3442                                   ZPRRegOp zprty3, Operand itype>
3443: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop),
3444  asm, "\t$Zda, $Zn, $Zm$iop",
3445  "", []>, Sched<[]> {
3446  bits<5> Zda;
3447  bits<5> Zn;
3448  let Inst{31-23} = 0b010001001;
3449  let Inst{22}    = sz;
3450  let Inst{21}    = 0b1;
3451  let Inst{15-11} = 0;
3452  let Inst{10}    = U;
3453  let Inst{9-5}   = Zn;
3454  let Inst{4-0}   = Zda;
3455
3456  let Constraints = "$Zda = $_Zda";
3457  let DestructiveInstType = DestructiveOther;
3458  let hasSideEffects = 0;
3459}
3460
3461multiclass sve_intx_dot_by_indexed_elem<bit opc, string asm,
3462                                        SDPatternOperator op> {
3463  def _S : sve_intx_dot_by_indexed_elem<0b0, opc, asm, ZPR32, ZPR8, ZPR3b8, VectorIndexS32b_timm> {
3464    bits<2> iop;
3465    bits<3> Zm;
3466    let Inst{20-19} = iop;
3467    let Inst{18-16} = Zm;
3468  }
3469  def _D : sve_intx_dot_by_indexed_elem<0b1, opc, asm, ZPR64, ZPR16, ZPR4b16, VectorIndexD32b_timm> {
3470    bits<1> iop;
3471    bits<4> Zm;
3472    let Inst{20} = iop;
3473    let Inst{19-16} = Zm;
3474  }
3475
3476  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv16i8, nxv16i8, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3477  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv8i16, nxv8i16, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3478}
3479
3480//===----------------------------------------------------------------------===//
3481// SVE2 Complex Integer Dot Product Group
3482//===----------------------------------------------------------------------===//
3483
3484class sve2_complex_int_arith<bits<2> sz, bits<4> opc, string asm,
3485                             ZPRRegOp zprty1, ZPRRegOp zprty2>
3486: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm,
3487                         complexrotateop:$rot),
3488  asm, "\t$Zda, $Zn, $Zm, $rot", "", []>, Sched<[]> {
3489  bits<5> Zda;
3490  bits<5> Zn;
3491  bits<5> Zm;
3492  bits<2> rot;
3493  let Inst{31-24} = 0b01000100;
3494  let Inst{23-22} = sz;
3495  let Inst{21}    = 0b0;
3496  let Inst{20-16} = Zm;
3497  let Inst{15-12} = opc;
3498  let Inst{11-10} = rot;
3499  let Inst{9-5}   = Zn;
3500  let Inst{4-0}   = Zda;
3501
3502  let Constraints = "$Zda = $_Zda";
3503  let DestructiveInstType = DestructiveOther;
3504  let ElementSize = ElementSizeNone;
3505  let hasSideEffects = 0;
3506}
3507
3508multiclass sve2_cintx_dot<string asm, SDPatternOperator op> {
3509  def _S : sve2_complex_int_arith<0b10, 0b0001, asm, ZPR32, ZPR8>;
3510  def _D : sve2_complex_int_arith<0b11, 0b0001, asm, ZPR64, ZPR16>;
3511
3512  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv16i8 ZPR8:$Op2), (nxv16i8 ZPR8:$Op3),
3513                         (i32 complexrotateop:$imm))),
3514            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR8:$Op2, ZPR8:$Op3, complexrotateop:$imm)>;
3515  def : Pat<(nxv2i64 (op (nxv2i64 ZPR64:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3516                         (i32 complexrotateop:$imm))),
3517            (!cast<Instruction>(NAME # "_D") ZPR64:$Op1, ZPR16:$Op2, ZPR16:$Op3, complexrotateop:$imm)>;
3518}
3519
3520//===----------------------------------------------------------------------===//
3521// SVE2 Complex Multiply-Add Group
3522//===----------------------------------------------------------------------===//
3523
3524multiclass sve2_int_cmla<bit opc, string asm, SDPatternOperator op> {
3525  def _B : sve2_complex_int_arith<0b00, { 0b001, opc }, asm, ZPR8, ZPR8>;
3526  def _H : sve2_complex_int_arith<0b01, { 0b001, opc }, asm, ZPR16, ZPR16>;
3527  def _S : sve2_complex_int_arith<0b10, { 0b001, opc }, asm, ZPR32, ZPR32>;
3528  def _D : sve2_complex_int_arith<0b11, { 0b001, opc }, asm, ZPR64, ZPR64>;
3529
3530  def : SVE_4_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, i32, complexrotateop, !cast<Instruction>(NAME # _B)>;
3531  def : SVE_4_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, i32, complexrotateop, !cast<Instruction>(NAME # _H)>;
3532  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, i32, complexrotateop, !cast<Instruction>(NAME # _S)>;
3533  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, i32, complexrotateop, !cast<Instruction>(NAME # _D)>;
3534}
3535
3536//===----------------------------------------------------------------------===//
3537// SVE2 Complex Integer Dot Product - Indexed Group
3538//===----------------------------------------------------------------------===//
3539
3540class sve2_complex_int_arith_indexed<bits<2> sz, bits<4> opc, string asm,
3541                                     ZPRRegOp zprty1, ZPRRegOp zprty2,
3542                                     ZPRRegOp zprty3, Operand itype>
3543: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop,
3544                         complexrotateop:$rot),
3545  asm, "\t$Zda, $Zn, $Zm$iop, $rot", "", []>, Sched<[]> {
3546  bits<5> Zda;
3547  bits<5> Zn;
3548  bits<2> rot;
3549  let Inst{31-24} = 0b01000100;
3550  let Inst{23-22} = sz;
3551  let Inst{21}    = 0b1;
3552  let Inst{15-12} = opc;
3553  let Inst{11-10} = rot;
3554  let Inst{9-5}   = Zn;
3555  let Inst{4-0}   = Zda;
3556
3557  let Constraints = "$Zda = $_Zda";
3558  let DestructiveInstType = DestructiveOther;
3559  let ElementSize = ElementSizeNone;
3560  let hasSideEffects = 0;
3561}
3562
3563multiclass sve2_cintx_dot_by_indexed_elem<string asm, SDPatternOperator op> {
3564  def _S : sve2_complex_int_arith_indexed<0b10, 0b0100, asm, ZPR32, ZPR8, ZPR3b8, VectorIndexS32b> {
3565    bits<2> iop;
3566    bits<3> Zm;
3567    let Inst{20-19} = iop;
3568    let Inst{18-16} = Zm;
3569  }
3570  def _D : sve2_complex_int_arith_indexed<0b11, 0b0100, asm, ZPR64, ZPR16, ZPR4b16, VectorIndexD32b> {
3571    bit iop;
3572    bits<4> Zm;
3573    let Inst{20} = iop;
3574    let Inst{19-16} = Zm;
3575  }
3576
3577  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv16i8 ZPR8:$Op2), (nxv16i8 ZPR8:$Op3),
3578                         (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
3579            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR8:$Op2, ZPR8:$Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
3580  def : Pat<(nxv2i64 (op (nxv2i64 ZPR64:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3581                         (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
3582            (!cast<Instruction>(NAME # "_D") ZPR64:$Op1, ZPR16:$Op2, ZPR16:$Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
3583}
3584
3585//===----------------------------------------------------------------------===//
3586// SVE2 Complex Multiply-Add - Indexed Group
3587//===----------------------------------------------------------------------===//
3588
3589multiclass sve2_cmla_by_indexed_elem<bit opc, string asm,
3590                                     SDPatternOperator op> {
3591  def _H : sve2_complex_int_arith_indexed<0b10, { 0b011, opc }, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexS32b> {
3592    bits<2> iop;
3593    bits<3> Zm;
3594    let Inst{20-19} = iop;
3595    let Inst{18-16} = Zm;
3596  }
3597  def _S : sve2_complex_int_arith_indexed<0b11, { 0b011, opc }, asm, ZPR32, ZPR32, ZPR4b32, VectorIndexD32b> {
3598    bit iop;
3599    bits<4> Zm;
3600    let Inst{20} = iop;
3601    let Inst{19-16} = Zm;
3602  }
3603
3604  def : Pat<(nxv8i16 (op (nxv8i16 ZPR16:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3605                         (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
3606            (!cast<Instruction>(NAME # "_H") ZPR16:$Op1, ZPR16:$Op2, ZPR16:$Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
3607
3608  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv4i32 ZPR32:$Op2), (nxv4i32 ZPR32:$Op3),
3609                         (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
3610            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR32:$Op2, ZPR32:$Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
3611}
3612
3613//===----------------------------------------------------------------------===//
3614// SVE2 Integer Multiply - Unpredicated Group
3615//===----------------------------------------------------------------------===//
3616
3617class sve2_int_mul<bits<2> sz, bits<3> opc, string asm, ZPRRegOp zprty>
3618: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
3619  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3620  bits<5> Zd;
3621  bits<5> Zm;
3622  bits<5> Zn;
3623  let Inst{31-24} = 0b00000100;
3624  let Inst{23-22} = sz;
3625  let Inst{21}    = 0b1;
3626  let Inst{20-16} = Zm;
3627  let Inst{15-13} = 0b011;
3628  let Inst{12-10} = opc;
3629  let Inst{9-5}   = Zn;
3630  let Inst{4-0}   = Zd;
3631
3632  let hasSideEffects = 0;
3633}
3634
3635multiclass sve2_int_mul<bits<3> opc, string asm, SDPatternOperator op,
3636                        SDPatternOperator op_pred = null_frag> {
3637  def _B : sve2_int_mul<0b00, opc, asm, ZPR8>;
3638  def _H : sve2_int_mul<0b01, opc, asm, ZPR16>;
3639  def _S : sve2_int_mul<0b10, opc, asm, ZPR32>;
3640  def _D : sve2_int_mul<0b11, opc, asm, ZPR64>;
3641
3642  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3643  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3644  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3645  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3646
3647  def : SVE_2_Op_Pred_Any_Predicate<nxv16i8, op_pred, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3648  def : SVE_2_Op_Pred_Any_Predicate<nxv8i16, op_pred, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3649  def : SVE_2_Op_Pred_Any_Predicate<nxv4i32, op_pred, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3650  def : SVE_2_Op_Pred_Any_Predicate<nxv2i64, op_pred, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3651}
3652
3653multiclass sve2_int_mul_single<bits<3> opc, string asm, SDPatternOperator op> {
3654  def _B : sve2_int_mul<0b00, opc, asm, ZPR8>;
3655
3656  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3657}
3658
3659//===----------------------------------------------------------------------===//
3660// SVE2 Integer Multiply - Indexed Group
3661//===----------------------------------------------------------------------===//
3662
3663class sve2_int_mul_by_indexed_elem<bits<2> sz, bits<4> opc, string asm,
3664                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3665                                   ZPRRegOp zprty3, Operand itype>
3666: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty3:$Zm, itype:$iop),
3667  asm, "\t$Zd, $Zn, $Zm$iop", "", []>, Sched<[]> {
3668  bits<5> Zd;
3669  bits<5> Zn;
3670  let Inst{31-24} = 0b01000100;
3671  let Inst{23-22} = sz;
3672  let Inst{21}    = 0b1;
3673  let Inst{15-14} = 0b11;
3674  let Inst{13-10} = opc;
3675  let Inst{9-5}   = Zn;
3676  let Inst{4-0}   = Zd;
3677
3678  let hasSideEffects = 0;
3679}
3680
3681multiclass sve2_int_mul_by_indexed_elem<bits<4> opc, string asm,
3682                                        SDPatternOperator op> {
3683  def _H : sve2_int_mul_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexH32b> {
3684    bits<3> Zm;
3685    bits<3> iop;
3686    let Inst{22} = iop{2};
3687    let Inst{20-19} = iop{1-0};
3688    let Inst{18-16} = Zm;
3689  }
3690  def _S : sve2_int_mul_by_indexed_elem<0b10, opc, asm, ZPR32, ZPR32, ZPR3b32, VectorIndexS32b> {
3691    bits<3> Zm;
3692    bits<2> iop;
3693    let Inst{20-19} = iop;
3694    let Inst{18-16} = Zm;
3695  }
3696  def _D : sve2_int_mul_by_indexed_elem<0b11, opc, asm, ZPR64, ZPR64, ZPR4b64, VectorIndexD32b> {
3697    bits<4> Zm;
3698    bit iop;
3699    let Inst{20} = iop;
3700    let Inst{19-16} = Zm;
3701  }
3702
3703  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
3704  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3705  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3706}
3707
3708multiclass sve2_int_mul_long_by_indexed_elem<bits<3> opc, string asm,
3709                                             SDPatternOperator op> {
3710  def _S : sve2_int_mul_by_indexed_elem<0b10, { opc{2-1}, ?, opc{0} }, asm,
3711                                        ZPR32, ZPR16, ZPR3b16, VectorIndexH32b> {
3712    bits<3> Zm;
3713    bits<3> iop;
3714    let Inst{20-19} = iop{2-1};
3715    let Inst{18-16} = Zm;
3716    let Inst{11} = iop{0};
3717  }
3718  def _D : sve2_int_mul_by_indexed_elem<0b11, { opc{2-1}, ?, opc{0} }, asm,
3719                                        ZPR64, ZPR32, ZPR4b32, VectorIndexS32b> {
3720    bits<4> Zm;
3721    bits<2> iop;
3722    let Inst{20} = iop{1};
3723    let Inst{19-16} = Zm;
3724    let Inst{11} = iop{0};
3725  }
3726
3727  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _S)>;
3728  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
3729}
3730
3731//===----------------------------------------------------------------------===//
3732// SVE2 Integer - Predicated Group
3733//===----------------------------------------------------------------------===//
3734
3735class sve2_int_arith_pred<bits<2> sz, bits<6> opc, string asm,
3736                          ZPRRegOp zprty>
3737: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
3738  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm", "", []>, Sched<[]> {
3739  bits<3> Pg;
3740  bits<5> Zm;
3741  bits<5> Zdn;
3742  let Inst{31-24} = 0b01000100;
3743  let Inst{23-22} = sz;
3744  let Inst{21-20} = 0b01;
3745  let Inst{20-16} = opc{5-1};
3746  let Inst{15-14} = 0b10;
3747  let Inst{13}    = opc{0};
3748  let Inst{12-10} = Pg;
3749  let Inst{9-5}   = Zm;
3750  let Inst{4-0}   = Zdn;
3751
3752  let Constraints = "$Zdn = $_Zdn";
3753  let DestructiveInstType = DestructiveOther;
3754  let ElementSize = zprty.ElementSize;
3755  let hasSideEffects = 0;
3756}
3757
3758multiclass sve2_int_arith_pred<bits<6> opc, string asm, SDPatternOperator op,
3759                               string Ps = "",
3760                               DestructiveInstTypeEnum flags=DestructiveOther,
3761                               string revname="", bit isReverseInstr=0> {
3762  let DestructiveInstType = flags in {
3763  def _B : sve2_int_arith_pred<0b00, opc, asm, ZPR8>,
3764           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3765  def _H : sve2_int_arith_pred<0b01, opc, asm, ZPR16>,
3766           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3767  def _S : sve2_int_arith_pred<0b10, opc, asm, ZPR32>,
3768           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3769  def _D : sve2_int_arith_pred<0b11, opc, asm, ZPR64>,
3770           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3771  }
3772
3773  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3774  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3775  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3776  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3777}
3778
3779class sve2_int_sadd_long_accum_pairwise<bits<2> sz, bit U, string asm,
3780                                        ZPRRegOp zprty1, ZPRRegOp zprty2>
3781: I<(outs zprty1:$Zda), (ins PPR3bAny:$Pg, zprty1:$_Zda, zprty2:$Zn),
3782  asm, "\t$Zda, $Pg/m, $Zn", "", []>, Sched<[]> {
3783  bits<3> Pg;
3784  bits<5> Zn;
3785  bits<5> Zda;
3786  let Inst{31-24} = 0b01000100;
3787  let Inst{23-22} = sz;
3788  let Inst{21-17} = 0b00010;
3789  let Inst{16}    = U;
3790  let Inst{15-13} = 0b101;
3791  let Inst{12-10} = Pg;
3792  let Inst{9-5}   = Zn;
3793  let Inst{4-0}   = Zda;
3794
3795  let Constraints = "$Zda = $_Zda";
3796  let DestructiveInstType = DestructiveOther;
3797  let ElementSize = zprty1.ElementSize;
3798  let hasSideEffects = 0;
3799}
3800
3801multiclass sve2_int_sadd_long_accum_pairwise<bit U, string asm, SDPatternOperator op> {
3802  def _H : sve2_int_sadd_long_accum_pairwise<0b01, U, asm, ZPR16, ZPR8>;
3803  def _S : sve2_int_sadd_long_accum_pairwise<0b10, U, asm, ZPR32, ZPR16>;
3804  def _D : sve2_int_sadd_long_accum_pairwise<0b11, U, asm, ZPR64, ZPR32>;
3805
3806  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv16i8, !cast<Instruction>(NAME # _H)>;
3807  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv8i16, !cast<Instruction>(NAME # _S)>;
3808  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv4i32, !cast<Instruction>(NAME # _D)>;
3809}
3810
3811class sve2_int_un_pred_arit<bits<2> sz, bit Q, bits<2> opc,
3812                            string asm, ZPRRegOp zprty>
3813: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
3814  asm, "\t$Zd, $Pg/m, $Zn",
3815  "",
3816  []>, Sched<[]> {
3817  bits<3> Pg;
3818  bits<5> Zd;
3819  bits<5> Zn;
3820  let Inst{31-24} = 0b01000100;
3821  let Inst{23-22} = sz;
3822  let Inst{21-20} = 0b00;
3823  let Inst{19}    = Q;
3824  let Inst{18}    = 0b0;
3825  let Inst{17-16} = opc;
3826  let Inst{15-13} = 0b101;
3827  let Inst{12-10} = Pg;
3828  let Inst{9-5}   = Zn;
3829  let Inst{4-0}   = Zd;
3830
3831  let Constraints = "$Zd = $_Zd";
3832  let DestructiveInstType = DestructiveUnaryPassthru;
3833  let ElementSize = zprty.ElementSize;
3834  let hasSideEffects = 0;
3835}
3836
3837multiclass sve2_int_un_pred_arit_s<bits<3> opc, string asm,
3838                                   SDPatternOperator op> {
3839  def _S : sve2_int_un_pred_arit<0b10, opc{2}, opc{1-0}, asm, ZPR32>,
3840           SVEPseudo2Instr<NAME # _S, 1>;
3841
3842  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
3843
3844  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
3845
3846  defm : SVE_3_Op_Undef_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
3847}
3848
3849multiclass sve2_int_un_pred_arit<bits<3> opc, string asm, SDPatternOperator op> {
3850  def _B : sve2_int_un_pred_arit<0b00, opc{2}, opc{1-0}, asm, ZPR8>,
3851           SVEPseudo2Instr<NAME # _B, 1>;
3852  def _H : sve2_int_un_pred_arit<0b01, opc{2}, opc{1-0}, asm, ZPR16>,
3853           SVEPseudo2Instr<NAME # _H, 1>;
3854  def _S : sve2_int_un_pred_arit<0b10, opc{2}, opc{1-0}, asm, ZPR32>,
3855           SVEPseudo2Instr<NAME # _S, 1>;
3856  def _D : sve2_int_un_pred_arit<0b11, opc{2}, opc{1-0}, asm, ZPR64>,
3857           SVEPseudo2Instr<NAME # _D, 1>;
3858
3859  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
3860  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
3861  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
3862  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
3863
3864  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
3865  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
3866  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
3867  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
3868
3869  defm : SVE_3_Op_Undef_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
3870  defm : SVE_3_Op_Undef_Pat<nxv8i16, op, nxv8i16, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
3871  defm : SVE_3_Op_Undef_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
3872  defm : SVE_3_Op_Undef_Pat<nxv2i64, op, nxv2i64, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
3873}
3874
3875//===----------------------------------------------------------------------===//
3876// SVE2 Widening Integer Arithmetic Group
3877//===----------------------------------------------------------------------===//
3878
3879class sve2_wide_int_arith<bits<2> sz, bits<5> opc, string asm,
3880                          ZPRRegOp zprty1, ZPRRegOp zprty2, ZPRRegOp zprty3>
3881: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty3:$Zm),
3882  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3883  bits<5> Zd;
3884  bits<5> Zn;
3885  bits<5> Zm;
3886  let Inst{31-24} = 0b01000101;
3887  let Inst{23-22} = sz;
3888  let Inst{21}    = 0b0;
3889  let Inst{20-16} = Zm;
3890  let Inst{15}    = 0b0;
3891  let Inst{14-10} = opc;
3892  let Inst{9-5}   = Zn;
3893  let Inst{4-0}   = Zd;
3894
3895  let hasSideEffects = 0;
3896}
3897
3898multiclass sve2_wide_int_arith_long<bits<5> opc, string asm,
3899                                    SDPatternOperator op> {
3900  def _H : sve2_wide_int_arith<0b01, opc, asm, ZPR16, ZPR8, ZPR8>;
3901  def _S : sve2_wide_int_arith<0b10, opc, asm, ZPR32, ZPR16, ZPR16>;
3902  def _D : sve2_wide_int_arith<0b11, opc, asm, ZPR64, ZPR32, ZPR32>;
3903
3904  def : SVE_2_Op_Pat<nxv8i16, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3905  def : SVE_2_Op_Pat<nxv4i32, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
3906  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3907}
3908
3909multiclass sve2_wide_int_arith_wide<bits<3> opc, string asm,
3910                                    SDPatternOperator op> {
3911  def _H : sve2_wide_int_arith<0b01, { 0b10, opc }, asm, ZPR16, ZPR16, ZPR8>;
3912  def _S : sve2_wide_int_arith<0b10, { 0b10, opc }, asm, ZPR32, ZPR32, ZPR16>;
3913  def _D : sve2_wide_int_arith<0b11, { 0b10, opc }, asm, ZPR64, ZPR64, ZPR32>;
3914
3915  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, !cast<Instruction>(NAME # _H)>;
3916  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, !cast<Instruction>(NAME # _S)>;
3917  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, !cast<Instruction>(NAME # _D)>;
3918}
3919
3920multiclass sve2_wide_int_arith_pmul<bits<2> sz, bits<5> opc, string asm,
3921                                     SDPatternOperator op> {
3922  def NAME : sve2_wide_int_arith<sz, opc, asm, ZPR128, ZPR64, ZPR64>;
3923
3924  // To avoid using 128 bit elements in the IR, the pattern below works with
3925  // llvm intrinsics with the _pair suffix, to reflect that
3926  // _Q is implemented as a pair of _D.
3927  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
3928}
3929
3930multiclass sve2_pmul_long<bits<1> opc, string asm, SDPatternOperator op> {
3931  def _H : sve2_wide_int_arith<0b01, {0b1101, opc}, asm, ZPR16, ZPR8, ZPR8>;
3932  def _D : sve2_wide_int_arith<0b11, {0b1101, opc}, asm, ZPR64, ZPR32, ZPR32>;
3933
3934  // To avoid using 128 bit elements in the IR, the patterns below work with
3935  // llvm intrinsics with the _pair suffix, to reflect that
3936  // _H is implemented as a pair of _B and _D is implemented as a pair of _S.
3937  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3938  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3939}
3940
3941//===----------------------------------------------------------------------===//
3942// SVE2 Misc Group
3943//===----------------------------------------------------------------------===//
3944
3945class sve2_misc<bits<2> sz, bits<4> opc, string asm,
3946                ZPRRegOp zprty1, ZPRRegOp zprty2>
3947: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty2:$Zm),
3948  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3949  bits<5> Zd;
3950  bits<5> Zn;
3951  bits<5> Zm;
3952  let Inst{31-24} = 0b01000101;
3953  let Inst{23-22} = sz;
3954  let Inst{21}    = 0b0;
3955  let Inst{20-16} = Zm;
3956  let Inst{15-14} = 0b10;
3957  let Inst{13-10} = opc;
3958  let Inst{9-5}   = Zn;
3959  let Inst{4-0}   = Zd;
3960
3961  let hasSideEffects = 0;
3962}
3963
3964multiclass sve2_misc_bitwise<bits<4> opc, string asm, SDPatternOperator op> {
3965  def _B : sve2_misc<0b00, opc, asm, ZPR8, ZPR8>;
3966  def _H : sve2_misc<0b01, opc, asm, ZPR16, ZPR16>;
3967  def _S : sve2_misc<0b10, opc, asm, ZPR32, ZPR32>;
3968  def _D : sve2_misc<0b11, opc, asm, ZPR64, ZPR64>;
3969
3970  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3971  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3972  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3973  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3974}
3975
3976multiclass sve2_misc_int_addsub_long_interleaved<bits<2> opc, string asm,
3977                                                 SDPatternOperator op> {
3978  def _H : sve2_misc<0b01, { 0b00, opc }, asm, ZPR16, ZPR8>;
3979  def _S : sve2_misc<0b10, { 0b00, opc }, asm, ZPR32, ZPR16>;
3980  def _D : sve2_misc<0b11, { 0b00, opc }, asm, ZPR64, ZPR32>;
3981
3982  def : SVE_2_Op_Pat<nxv8i16, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3983  def : SVE_2_Op_Pat<nxv4i32, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
3984  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3985}
3986
3987class sve2_bitwise_xor_interleaved<bits<2> sz, bits<1> opc, string asm,
3988                                   ZPRRegOp zprty1, ZPRRegOp zprty2>
3989: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, zprty2:$Zm),
3990  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3991  bits<5> Zd;
3992  bits<5> Zn;
3993  bits<5> Zm;
3994  let Inst{31-24} = 0b01000101;
3995  let Inst{23-22} = sz;
3996  let Inst{21}    = 0b0;
3997  let Inst{20-16} = Zm;
3998  let Inst{15-11} = 0b10010;
3999  let Inst{10}    = opc;
4000  let Inst{9-5}   = Zn;
4001  let Inst{4-0}   = Zd;
4002
4003  let Constraints = "$Zd = $_Zd";
4004  let DestructiveInstType = DestructiveOther;
4005  let ElementSize = ElementSizeNone;
4006  let hasSideEffects = 0;
4007}
4008
4009multiclass sve2_bitwise_xor_interleaved<bit opc, string asm,
4010                                        SDPatternOperator op> {
4011  def _B : sve2_bitwise_xor_interleaved<0b00, opc, asm, ZPR8,  ZPR8>;
4012  def _H : sve2_bitwise_xor_interleaved<0b01, opc, asm, ZPR16, ZPR16>;
4013  def _S : sve2_bitwise_xor_interleaved<0b10, opc, asm, ZPR32, ZPR32>;
4014  def _D : sve2_bitwise_xor_interleaved<0b11, opc, asm, ZPR64, ZPR64>;
4015
4016  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4017  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4018  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4019  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4020}
4021
4022class sve2_bitwise_shift_left_long<bits<3> tsz8_64, bits<2> opc, string asm,
4023                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
4024                                   Operand immtype>
4025: I<(outs zprty1:$Zd), (ins zprty2:$Zn, immtype:$imm),
4026  asm, "\t$Zd, $Zn, $imm",
4027  "", []>, Sched<[]> {
4028  bits<5> Zd;
4029  bits<5> Zn;
4030  bits<5> imm;
4031  let Inst{31-23} = 0b010001010;
4032  let Inst{22}    = tsz8_64{2};
4033  let Inst{21}    = 0b0;
4034  let Inst{20-19} = tsz8_64{1-0};
4035  let Inst{18-16} = imm{2-0}; // imm3
4036  let Inst{15-12} = 0b1010;
4037  let Inst{11-10} = opc;
4038  let Inst{9-5}   = Zn;
4039  let Inst{4-0}   = Zd;
4040
4041  let hasSideEffects = 0;
4042}
4043
4044multiclass sve2_bitwise_shift_left_long<bits<2> opc, string asm,
4045                                        SDPatternOperator op> {
4046  def _H : sve2_bitwise_shift_left_long<{0,0,1}, opc, asm,
4047                                        ZPR16, ZPR8, vecshiftL8>;
4048  def _S : sve2_bitwise_shift_left_long<{0,1,?}, opc, asm,
4049                                        ZPR32, ZPR16, vecshiftL16> {
4050    let Inst{19} = imm{3};
4051  }
4052  def _D : sve2_bitwise_shift_left_long<{1,?,?}, opc, asm,
4053                                        ZPR64, ZPR32, vecshiftL32> {
4054    let Inst{20-19} = imm{4-3};
4055  }
4056  def : SVE_2_Op_Imm_Pat<nxv8i16, op, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _H)>;
4057  def : SVE_2_Op_Imm_Pat<nxv4i32, op, nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _S)>;
4058  def : SVE_2_Op_Imm_Pat<nxv2i64, op, nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _D)>;
4059}
4060
4061//===----------------------------------------------------------------------===//
4062// SVE2 Accumulate Group
4063//===----------------------------------------------------------------------===//
4064
4065class sve2_int_bin_shift_imm<bits<4> tsz8_64, bit opc, string asm,
4066                             ZPRRegOp zprty, Operand immtype>
4067: I<(outs zprty:$Zd), (ins zprty:$_Zd, zprty:$Zn, immtype:$imm),
4068  asm, "\t$Zd, $Zn, $imm",
4069  "", []>, Sched<[]> {
4070  bits<5> Zd;
4071  bits<5> Zn;
4072  bits<6> imm;
4073  let Inst{31-24} = 0b01000101;
4074  let Inst{23-22} = tsz8_64{3-2};
4075  let Inst{21}    = 0b0;
4076  let Inst{20-19} = tsz8_64{1-0};
4077  let Inst{18-16} = imm{2-0}; // imm3
4078  let Inst{15-11} = 0b11110;
4079  let Inst{10}    = opc;
4080  let Inst{9-5}   = Zn;
4081  let Inst{4-0}   = Zd;
4082
4083  let Constraints = "$Zd = $_Zd";
4084  let hasSideEffects = 0;
4085}
4086
4087multiclass sve2_int_bin_shift_imm_left<bit opc, string asm,
4088                                       SDPatternOperator op> {
4089  def _B : sve2_int_bin_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
4090  def _H : sve2_int_bin_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
4091    let Inst{19} = imm{3};
4092  }
4093  def _S : sve2_int_bin_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
4094    let Inst{20-19} = imm{4-3};
4095  }
4096  def _D : sve2_int_bin_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
4097    let Inst{22}    = imm{5};
4098    let Inst{20-19} = imm{4-3};
4099  }
4100
4101  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _B)>;
4102  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _H)>;
4103  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _S)>;
4104  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftL64, !cast<Instruction>(NAME # _D)>;
4105}
4106
4107multiclass sve2_int_bin_shift_imm_right<bit opc, string asm,
4108                                        SDPatternOperator op> {
4109  def _B : sve2_int_bin_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
4110  def _H : sve2_int_bin_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
4111    let Inst{19} = imm{3};
4112  }
4113  def _S : sve2_int_bin_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
4114    let Inst{20-19} = imm{4-3};
4115  }
4116  def _D : sve2_int_bin_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
4117    let Inst{22}    = imm{5};
4118    let Inst{20-19} = imm{4-3};
4119  }
4120
4121  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4122  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4123  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4124  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4125}
4126
4127class sve2_int_bin_accum_shift_imm<bits<4> tsz8_64, bits<2> opc, string asm,
4128                                   ZPRRegOp zprty, Operand immtype>
4129: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, immtype:$imm),
4130  asm, "\t$Zda, $Zn, $imm",
4131  "", []>, Sched<[]> {
4132  bits<5> Zda;
4133  bits<5> Zn;
4134  bits<6> imm;
4135  let Inst{31-24} = 0b01000101;
4136  let Inst{23-22} = tsz8_64{3-2};
4137  let Inst{21}    = 0b0;
4138  let Inst{20-19} = tsz8_64{1-0};
4139  let Inst{18-16} = imm{2-0}; // imm3
4140  let Inst{15-12} = 0b1110;
4141  let Inst{11-10} = opc;
4142  let Inst{9-5}   = Zn;
4143  let Inst{4-0}   = Zda;
4144
4145  let Constraints = "$Zda = $_Zda";
4146  let DestructiveInstType = DestructiveOther;
4147  let ElementSize = ElementSizeNone;
4148  let hasSideEffects = 0;
4149}
4150
4151multiclass sve2_int_bin_accum_shift_imm_right<bits<2> opc, string asm,
4152                                              SDPatternOperator op,
4153                                              SDPatternOperator shift_op = null_frag> {
4154  def _B : sve2_int_bin_accum_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
4155  def _H : sve2_int_bin_accum_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
4156    let Inst{19} = imm{3};
4157  }
4158  def _S : sve2_int_bin_accum_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
4159    let Inst{20-19} = imm{4-3};
4160  }
4161  def _D : sve2_int_bin_accum_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
4162    let Inst{22}    = imm{5};
4163    let Inst{20-19} = imm{4-3};
4164  }
4165
4166  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4167  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4168  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4169  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4170
4171  def : SVE_Shift_Add_All_Active_Pat<nxv16i8, shift_op, nxv16i1, nxv16i8, nxv16i8, i32, !cast<Instruction>(NAME # _B)>;
4172  def : SVE_Shift_Add_All_Active_Pat<nxv8i16, shift_op, nxv8i1, nxv8i16, nxv8i16, i32, !cast<Instruction>(NAME # _H)>;
4173  def : SVE_Shift_Add_All_Active_Pat<nxv4i32, shift_op, nxv4i1, nxv4i32, nxv4i32, i32, !cast<Instruction>(NAME # _S)>;
4174  def : SVE_Shift_Add_All_Active_Pat<nxv2i64, shift_op, nxv2i1, nxv2i64, nxv2i64, i32, !cast<Instruction>(NAME # _D)>;
4175}
4176
4177class sve2_int_cadd<bits<2> sz, bit opc, string asm, ZPRRegOp zprty>
4178: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, complexrotateopodd:$rot),
4179  asm, "\t$Zdn, $_Zdn, $Zm, $rot", "", []>, Sched<[]> {
4180  bits<5> Zdn;
4181  bits<5> Zm;
4182  bit rot;
4183  let Inst{31-24} = 0b01000101;
4184  let Inst{23-22} = sz;
4185  let Inst{21-17} = 0b00000;
4186  let Inst{16}    = opc;
4187  let Inst{15-11} = 0b11011;
4188  let Inst{10}    = rot;
4189  let Inst{9-5}   = Zm;
4190  let Inst{4-0}   = Zdn;
4191
4192  let Constraints = "$Zdn = $_Zdn";
4193  let DestructiveInstType = DestructiveOther;
4194  let ElementSize = ElementSizeNone;
4195  let hasSideEffects = 0;
4196}
4197
4198multiclass sve2_int_cadd<bit opc, string asm, SDPatternOperator op> {
4199  def _B : sve2_int_cadd<0b00, opc, asm, ZPR8>;
4200  def _H : sve2_int_cadd<0b01, opc, asm, ZPR16>;
4201  def _S : sve2_int_cadd<0b10, opc, asm, ZPR32>;
4202  def _D : sve2_int_cadd<0b11, opc, asm, ZPR64>;
4203
4204  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, complexrotateopodd, !cast<Instruction>(NAME # _B)>;
4205  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, complexrotateopodd, !cast<Instruction>(NAME # _H)>;
4206  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, complexrotateopodd, !cast<Instruction>(NAME # _S)>;
4207  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, complexrotateopodd, !cast<Instruction>(NAME # _D)>;
4208}
4209
4210class sve2_int_absdiff_accum<bits<2> sz, bits<4> opc, string asm,
4211                             ZPRRegOp zprty1, ZPRRegOp zprty2>
4212: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm),
4213  asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
4214  bits<5> Zda;
4215  bits<5> Zn;
4216  bits<5> Zm;
4217  let Inst{31-24} = 0b01000101;
4218  let Inst{23-22} = sz;
4219  let Inst{21}    = 0b0;
4220  let Inst{20-16} = Zm;
4221  let Inst{15-14} = 0b11;
4222  let Inst{13-10} = opc;
4223  let Inst{9-5}   = Zn;
4224  let Inst{4-0}   = Zda;
4225
4226  let Constraints = "$Zda = $_Zda";
4227  let DestructiveInstType = DestructiveOther;
4228  let ElementSize = ElementSizeNone;
4229  let hasSideEffects = 0;
4230}
4231
4232multiclass sve2_int_absdiff_accum<bit opc, string asm, SDPatternOperator op> {
4233  def _B : sve2_int_absdiff_accum<0b00, { 0b111, opc }, asm, ZPR8, ZPR8>;
4234  def _H : sve2_int_absdiff_accum<0b01, { 0b111, opc }, asm, ZPR16, ZPR16>;
4235  def _S : sve2_int_absdiff_accum<0b10, { 0b111, opc }, asm, ZPR32, ZPR32>;
4236  def _D : sve2_int_absdiff_accum<0b11, { 0b111, opc }, asm, ZPR64, ZPR64>;
4237
4238  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4239  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4240  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4241  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4242}
4243
4244multiclass sve2_int_absdiff_accum_long<bits<2> opc, string asm,
4245                                       SDPatternOperator op> {
4246  def _H : sve2_int_absdiff_accum<0b01, { 0b00, opc }, asm, ZPR16, ZPR8>;
4247  def _S : sve2_int_absdiff_accum<0b10, { 0b00, opc }, asm, ZPR32, ZPR16>;
4248  def _D : sve2_int_absdiff_accum<0b11, { 0b00, opc }, asm, ZPR64, ZPR32>;
4249
4250  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
4251  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
4252  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
4253}
4254
4255multiclass sve2_int_addsub_long_carry<bits<2> opc, string asm,
4256                                      SDPatternOperator op> {
4257  def _S : sve2_int_absdiff_accum<{ opc{1}, 0b0 }, { 0b010, opc{0} }, asm,
4258                                  ZPR32, ZPR32>;
4259  def _D : sve2_int_absdiff_accum<{ opc{1}, 0b1 }, { 0b010, opc{0} }, asm,
4260                                  ZPR64, ZPR64>;
4261
4262  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4263  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4264}
4265
4266//===----------------------------------------------------------------------===//
4267// SVE2 Narrowing Group
4268//===----------------------------------------------------------------------===//
4269
4270class sve2_int_bin_shift_imm_narrow_bottom<bits<3> tsz8_64, bits<3> opc,
4271                                           string asm, ZPRRegOp zprty1,
4272                                           ZPRRegOp zprty2, Operand immtype>
4273: I<(outs zprty1:$Zd), (ins zprty2:$Zn, immtype:$imm),
4274  asm, "\t$Zd, $Zn, $imm",
4275  "", []>, Sched<[]> {
4276  bits<5> Zd;
4277  bits<5> Zn;
4278  bits<5> imm;
4279  let Inst{31-23} = 0b010001010;
4280  let Inst{22}    = tsz8_64{2};
4281  let Inst{21}    = 0b1;
4282  let Inst{20-19} = tsz8_64{1-0};
4283  let Inst{18-16} = imm{2-0}; // imm3
4284  let Inst{15-14} = 0b00;
4285  let Inst{13-11} = opc;
4286  let Inst{10}    = 0b0;
4287  let Inst{9-5}   = Zn;
4288  let Inst{4-0}   = Zd;
4289
4290  let hasSideEffects = 0;
4291}
4292
4293multiclass sve2_int_bin_shift_imm_right_narrow_bottom<bits<3> opc, string asm,
4294                                                      SDPatternOperator op> {
4295  def _B : sve2_int_bin_shift_imm_narrow_bottom<{0,0,1}, opc, asm, ZPR8, ZPR16,
4296                                                tvecshiftR8>;
4297  def _H : sve2_int_bin_shift_imm_narrow_bottom<{0,1,?}, opc, asm, ZPR16, ZPR32,
4298                                                tvecshiftR16> {
4299    let Inst{19} = imm{3};
4300  }
4301  def _S : sve2_int_bin_shift_imm_narrow_bottom<{1,?,?}, opc, asm, ZPR32, ZPR64,
4302                                                tvecshiftR32> {
4303    let Inst{20-19} = imm{4-3};
4304  }
4305  def : SVE_2_Op_Imm_Pat<nxv16i8, op, nxv8i16, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4306  def : SVE_2_Op_Imm_Pat<nxv8i16, op, nxv4i32, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4307  def : SVE_2_Op_Imm_Pat<nxv4i32, op, nxv2i64, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4308}
4309
4310class sve2_int_bin_shift_imm_narrow_top<bits<3> tsz8_64, bits<3> opc,
4311                                        string asm, ZPRRegOp zprty1,
4312                                        ZPRRegOp zprty2, Operand immtype>
4313: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, immtype:$imm),
4314  asm, "\t$Zd, $Zn, $imm",
4315  "", []>, Sched<[]> {
4316  bits<5> Zd;
4317  bits<5> Zn;
4318  bits<5> imm;
4319  let Inst{31-23} = 0b010001010;
4320  let Inst{22}    = tsz8_64{2};
4321  let Inst{21}    = 0b1;
4322  let Inst{20-19} = tsz8_64{1-0};
4323  let Inst{18-16} = imm{2-0}; // imm3
4324  let Inst{15-14} = 0b00;
4325  let Inst{13-11} = opc;
4326  let Inst{10}    = 0b1;
4327  let Inst{9-5}   = Zn;
4328  let Inst{4-0}   = Zd;
4329
4330  let Constraints = "$Zd = $_Zd";
4331  let hasSideEffects = 0;
4332}
4333
4334multiclass sve2_int_bin_shift_imm_right_narrow_top<bits<3> opc, string asm,
4335                                                   SDPatternOperator op> {
4336  def _B : sve2_int_bin_shift_imm_narrow_top<{0,0,1}, opc, asm, ZPR8, ZPR16,
4337                                             tvecshiftR8>;
4338  def _H : sve2_int_bin_shift_imm_narrow_top<{0,1,?}, opc, asm, ZPR16, ZPR32,
4339                                             tvecshiftR16> {
4340    let Inst{19} = imm{3};
4341  }
4342  def _S : sve2_int_bin_shift_imm_narrow_top<{1,?,?}, opc, asm, ZPR32, ZPR64,
4343                                             tvecshiftR32> {
4344    let Inst{20-19} = imm{4-3};
4345  }
4346  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv8i16, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4347  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv4i32, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4348  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv2i64, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4349}
4350
4351class sve2_int_addsub_narrow_high_bottom<bits<2> sz, bits<2> opc, string asm,
4352                                         ZPRRegOp zprty1, ZPRRegOp zprty2>
4353: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty2:$Zm),
4354  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4355  bits<5> Zd;
4356  bits<5> Zn;
4357  bits<5> Zm;
4358  let Inst{31-24} = 0b01000101;
4359  let Inst{23-22} = sz;
4360  let Inst{21}    = 0b1;
4361  let Inst{20-16} = Zm;
4362  let Inst{15-13} = 0b011;
4363  let Inst{12-11} = opc; // S, R
4364  let Inst{10}    = 0b0; // Top
4365  let Inst{9-5}   = Zn;
4366  let Inst{4-0}   = Zd;
4367
4368  let hasSideEffects = 0;
4369}
4370
4371multiclass sve2_int_addsub_narrow_high_bottom<bits<2> opc, string asm,
4372                                              SDPatternOperator op> {
4373  def _B : sve2_int_addsub_narrow_high_bottom<0b01, opc, asm, ZPR8, ZPR16>;
4374  def _H : sve2_int_addsub_narrow_high_bottom<0b10, opc, asm, ZPR16, ZPR32>;
4375  def _S : sve2_int_addsub_narrow_high_bottom<0b11, opc, asm, ZPR32, ZPR64>;
4376
4377  def : SVE_2_Op_Pat<nxv16i8, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _B)>;
4378  def : SVE_2_Op_Pat<nxv8i16, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _H)>;
4379  def : SVE_2_Op_Pat<nxv4i32, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _S)>;
4380}
4381
4382class sve2_int_addsub_narrow_high_top<bits<2> sz, bits<2> opc, string asm,
4383                                      ZPRRegOp zprty1, ZPRRegOp zprty2>
4384: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, zprty2:$Zm),
4385  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4386  bits<5> Zd;
4387  bits<5> Zn;
4388  bits<5> Zm;
4389  let Inst{31-24} = 0b01000101;
4390  let Inst{23-22} = sz;
4391  let Inst{21}    = 0b1;
4392  let Inst{20-16} = Zm;
4393  let Inst{15-13} = 0b011;
4394  let Inst{12-11} = opc; // S, R
4395  let Inst{10}    = 0b1; // Top
4396  let Inst{9-5}   = Zn;
4397  let Inst{4-0}   = Zd;
4398
4399  let Constraints = "$Zd = $_Zd";
4400  let hasSideEffects = 0;
4401}
4402
4403multiclass sve2_int_addsub_narrow_high_top<bits<2> opc, string asm,
4404                                           SDPatternOperator op> {
4405  def _B : sve2_int_addsub_narrow_high_top<0b01, opc, asm, ZPR8, ZPR16>;
4406  def _H : sve2_int_addsub_narrow_high_top<0b10, opc, asm, ZPR16, ZPR32>;
4407  def _S : sve2_int_addsub_narrow_high_top<0b11, opc, asm, ZPR32, ZPR64>;
4408
4409  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _B)>;
4410  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _H)>;
4411  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _S)>;
4412}
4413
4414class sve2_int_sat_extract_narrow_bottom<bits<3> tsz8_64, bits<2> opc, string asm,
4415                                         ZPRRegOp zprty1, ZPRRegOp zprty2>
4416: I<(outs zprty1:$Zd), (ins zprty2:$Zn),
4417  asm, "\t$Zd, $Zn", "", []>, Sched<[]> {
4418  bits<5> Zd;
4419  bits<5> Zn;
4420  let Inst{31-23} = 0b010001010;
4421  let Inst{22}    = tsz8_64{2};
4422  let Inst{21}    = 0b1;
4423  let Inst{20-19} = tsz8_64{1-0};
4424  let Inst{18-13} = 0b000010;
4425  let Inst{12-11} = opc;
4426  let Inst{10}    = 0b0;
4427  let Inst{9-5}   = Zn;
4428  let Inst{4-0}   = Zd;
4429
4430  let hasSideEffects = 0;
4431}
4432
4433multiclass sve2_int_sat_extract_narrow_bottom<bits<2> opc, string asm,
4434                                              SDPatternOperator op> {
4435  def _B : sve2_int_sat_extract_narrow_bottom<0b001, opc, asm, ZPR8, ZPR16>;
4436  def _H : sve2_int_sat_extract_narrow_bottom<0b010, opc, asm, ZPR16, ZPR32>;
4437  def _S : sve2_int_sat_extract_narrow_bottom<0b100, opc, asm, ZPR32, ZPR64>;
4438
4439  def : SVE_1_Op_Pat<nxv16i8, op, nxv8i16, !cast<Instruction>(NAME # _B)>;
4440  def : SVE_1_Op_Pat<nxv8i16, op, nxv4i32, !cast<Instruction>(NAME # _H)>;
4441  def : SVE_1_Op_Pat<nxv4i32, op, nxv2i64, !cast<Instruction>(NAME # _S)>;
4442}
4443
4444class sve2_int_sat_extract_narrow_top<bits<3> tsz8_64, bits<2> opc, string asm,
4445                                      ZPRRegOp zprty1, ZPRRegOp zprty2>
4446: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn),
4447  asm, "\t$Zd, $Zn", "", []>, Sched<[]> {
4448  bits<5> Zd;
4449  bits<5> Zn;
4450  let Inst{31-23} = 0b010001010;
4451  let Inst{22}    = tsz8_64{2};
4452  let Inst{21}    = 0b1;
4453  let Inst{20-19} = tsz8_64{1-0};
4454  let Inst{18-13} = 0b000010;
4455  let Inst{12-11} = opc;
4456  let Inst{10}    = 0b1;
4457  let Inst{9-5}   = Zn;
4458  let Inst{4-0}   = Zd;
4459
4460  let Constraints = "$Zd = $_Zd";
4461  let hasSideEffects = 0;
4462}
4463
4464multiclass sve2_int_sat_extract_narrow_top<bits<2> opc, string asm,
4465                                           SDPatternOperator op> {
4466  def _B : sve2_int_sat_extract_narrow_top<0b001, opc, asm, ZPR8, ZPR16>;
4467  def _H : sve2_int_sat_extract_narrow_top<0b010, opc, asm, ZPR16, ZPR32>;
4468  def _S : sve2_int_sat_extract_narrow_top<0b100, opc, asm, ZPR32, ZPR64>;
4469
4470  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv8i16, !cast<Instruction>(NAME # _B)>;
4471  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv4i32, !cast<Instruction>(NAME # _H)>;
4472  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
4473}
4474
4475//===----------------------------------------------------------------------===//
4476// SVE Integer Arithmetic - Unary Predicated Group
4477//===----------------------------------------------------------------------===//
4478
4479class sve_int_un_pred_arit<bits<2> sz8_64, bits<4> opc,
4480                             string asm, ZPRRegOp zprty>
4481: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
4482  asm, "\t$Zd, $Pg/m, $Zn",
4483  "",
4484  []>, Sched<[]> {
4485  bits<3> Pg;
4486  bits<5> Zd;
4487  bits<5> Zn;
4488  let Inst{31-24} = 0b00000100;
4489  let Inst{23-22} = sz8_64;
4490  let Inst{21-20} = 0b01;
4491  let Inst{19}    = opc{0};
4492  let Inst{18-16} = opc{3-1};
4493  let Inst{15-13} = 0b101;
4494  let Inst{12-10} = Pg;
4495  let Inst{9-5}   = Zn;
4496  let Inst{4-0}   = Zd;
4497
4498  let Constraints = "$Zd = $_Zd";
4499  let DestructiveInstType = DestructiveUnaryPassthru;
4500  let ElementSize = zprty.ElementSize;
4501  let hasSideEffects = 0;
4502}
4503
4504multiclass sve_int_un_pred_arit_0<bits<3> opc, string asm,
4505                                  SDPatternOperator op> {
4506  def _B : sve_int_un_pred_arit<0b00, { opc, 0b0 }, asm, ZPR8>,
4507           SVEPseudo2Instr<NAME # _B, 1>;
4508  def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>,
4509           SVEPseudo2Instr<NAME # _H, 1>;
4510  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4511           SVEPseudo2Instr<NAME # _S, 1>;
4512  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4513           SVEPseudo2Instr<NAME # _D, 1>;
4514
4515  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
4516  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
4517  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
4518  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
4519
4520  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
4521  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4522  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4523  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4524
4525  defm : SVE_1_Op_PassthruUndef_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
4526  defm : SVE_1_Op_PassthruUndef_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4527  defm : SVE_1_Op_PassthruUndef_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4528  defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4529}
4530
4531multiclass sve_int_un_pred_arit_0_h<bits<3> opc, string asm,
4532                                    SDPatternOperator op> {
4533  def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>,
4534           SVEPseudo2Instr<NAME # _H, 1>;
4535  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4536           SVEPseudo2Instr<NAME # _S, 1>;
4537  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4538           SVEPseudo2Instr<NAME # _D, 1>;
4539
4540  def : SVE_InReg_Extend<nxv8i16, op, nxv8i1, nxv8i8, !cast<Instruction>(NAME # _H)>;
4541  def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i8, !cast<Instruction>(NAME # _S)>;
4542  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i8, !cast<Instruction>(NAME # _D)>;
4543
4544  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4545  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4546  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4547
4548  defm : SVE_InReg_Extend_PassthruUndef<nxv8i16, op, nxv8i1, nxv8i8, !cast<Pseudo>(NAME # _H_UNDEF)>;
4549  defm : SVE_InReg_Extend_PassthruUndef<nxv4i32, op, nxv4i1, nxv4i8, !cast<Pseudo>(NAME # _S_UNDEF)>;
4550  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i8, !cast<Pseudo>(NAME # _D_UNDEF)>;
4551}
4552
4553multiclass sve_int_un_pred_arit_0_w<bits<3> opc, string asm,
4554                                    SDPatternOperator op> {
4555  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4556           SVEPseudo2Instr<NAME # _S, 1>;
4557  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4558           SVEPseudo2Instr<NAME # _D, 1>;
4559
4560  def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i16, !cast<Instruction>(NAME # _S)>;
4561  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i16, !cast<Instruction>(NAME # _D)>;
4562
4563  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4564  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4565
4566  defm : SVE_InReg_Extend_PassthruUndef<nxv4i32, op, nxv4i1, nxv4i16, !cast<Pseudo>(NAME # _S_UNDEF)>;
4567  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i16, !cast<Pseudo>(NAME # _D_UNDEF)>;
4568}
4569
4570multiclass sve_int_un_pred_arit_0_d<bits<3> opc, string asm,
4571                                    SDPatternOperator op> {
4572  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4573           SVEPseudo2Instr<NAME # _D, 1>;
4574
4575  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i32, !cast<Instruction>(NAME # _D)>;
4576
4577  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4578
4579  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i32, !cast<Pseudo>(NAME # _D_UNDEF)>;
4580}
4581
4582multiclass sve_int_un_pred_arit_1<bits<3> opc, string asm,
4583                                  SDPatternOperator op> {
4584  def _B : sve_int_un_pred_arit<0b00, { opc, 0b1 }, asm, ZPR8>,
4585           SVEPseudo2Instr<NAME # _B, 1>;
4586  def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>,
4587           SVEPseudo2Instr<NAME # _H, 1>;
4588  def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>,
4589           SVEPseudo2Instr<NAME # _S, 1>;
4590  def _D : sve_int_un_pred_arit<0b11, { opc, 0b1 }, asm, ZPR64>,
4591           SVEPseudo2Instr<NAME # _D, 1>;
4592
4593  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
4594  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
4595  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
4596  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
4597
4598  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
4599  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4600  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4601  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4602
4603  defm : SVE_1_Op_PassthruUndef_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
4604  defm : SVE_1_Op_PassthruUndef_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4605  defm : SVE_1_Op_PassthruUndef_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4606  defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4607}
4608
4609multiclass sve_int_un_pred_arit_1_fp<bits<3> opc, string asm, SDPatternOperator op> {
4610  def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>,
4611           SVEPseudo2Instr<NAME # _H, 1>;
4612  def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>,
4613           SVEPseudo2Instr<NAME # _S, 1>;
4614  def _D : sve_int_un_pred_arit<0b11, { opc, 0b1 }, asm, ZPR64>,
4615           SVEPseudo2Instr<NAME # _D, 1>;
4616
4617  def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
4618  def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
4619  def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
4620  def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
4621  def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
4622  def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
4623
4624  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4625  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4626  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4627
4628  defm : SVE_1_Op_PassthruUndef_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4629  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4630  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4631  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4632  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4633  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4634}
4635
4636//===----------------------------------------------------------------------===//
4637// SVE Integer Wide Immediate - Unpredicated Group
4638//===----------------------------------------------------------------------===//
4639class sve_int_dup_imm<bits<2> sz8_64, string asm,
4640                      ZPRRegOp zprty, Operand immtype>
4641: I<(outs zprty:$Zd), (ins immtype:$imm),
4642  asm, "\t$Zd, $imm",
4643  "",
4644  []>, Sched<[]> {
4645  bits<5> Zd;
4646  bits<9> imm;
4647  let Inst{31-24} = 0b00100101;
4648  let Inst{23-22} = sz8_64;
4649  let Inst{21-14} = 0b11100011;
4650  let Inst{13}    = imm{8};   // sh
4651  let Inst{12-5}  = imm{7-0}; // imm8
4652  let Inst{4-0}   = Zd;
4653
4654  let hasSideEffects = 0;
4655  let isReMaterializable = 1;
4656}
4657
4658multiclass sve_int_dup_imm<string asm> {
4659  def _B : sve_int_dup_imm<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8>;
4660  def _H : sve_int_dup_imm<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16>;
4661  def _S : sve_int_dup_imm<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32>;
4662  def _D : sve_int_dup_imm<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64>;
4663
4664  def : InstAlias<"mov $Zd, $imm",
4665                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, cpy_imm8_opt_lsl_i8:$imm), 1>;
4666  def : InstAlias<"mov $Zd, $imm",
4667                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, cpy_imm8_opt_lsl_i16:$imm), 1>;
4668  def : InstAlias<"mov $Zd, $imm",
4669                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, cpy_imm8_opt_lsl_i32:$imm), 1>;
4670  def : InstAlias<"mov $Zd, $imm",
4671                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, cpy_imm8_opt_lsl_i64:$imm), 1>;
4672
4673  def : InstAlias<"fmov $Zd, #0.0",
4674                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, 0, 0), 1>;
4675  def : InstAlias<"fmov $Zd, #0.0",
4676                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, 0, 0), 1>;
4677  def : InstAlias<"fmov $Zd, #0.0",
4678                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, 0, 0), 1>;
4679}
4680
4681class sve_int_dup_fpimm<bits<2> sz8_64, Operand fpimmtype,
4682                        string asm, ZPRRegOp zprty>
4683: I<(outs zprty:$Zd), (ins fpimmtype:$imm8),
4684  asm, "\t$Zd, $imm8",
4685  "",
4686  []>, Sched<[]> {
4687  bits<5> Zd;
4688  bits<8> imm8;
4689  let Inst{31-24} = 0b00100101;
4690  let Inst{23-22} = sz8_64;
4691  let Inst{21-14} = 0b11100111;
4692  let Inst{13}    = 0b0;
4693  let Inst{12-5}  = imm8;
4694  let Inst{4-0}   = Zd;
4695
4696  let hasSideEffects = 0;
4697  let isReMaterializable = 1;
4698}
4699
4700multiclass sve_int_dup_fpimm<string asm> {
4701  def _H : sve_int_dup_fpimm<0b01, fpimm16, asm, ZPR16>;
4702  def _S : sve_int_dup_fpimm<0b10, fpimm32, asm, ZPR32>;
4703  def _D : sve_int_dup_fpimm<0b11, fpimm64, asm, ZPR64>;
4704
4705  def : InstAlias<"fmov $Zd, $imm8",
4706                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, fpimm16:$imm8), 1>;
4707  def : InstAlias<"fmov $Zd, $imm8",
4708                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, fpimm32:$imm8), 1>;
4709  def : InstAlias<"fmov $Zd, $imm8",
4710                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, fpimm64:$imm8), 1>;
4711}
4712
4713class sve_int_arith_imm0<bits<2> sz8_64, bits<3> opc, string asm,
4714                         ZPRRegOp zprty, Operand immtype>
4715: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, immtype:$imm),
4716  asm, "\t$Zdn, $_Zdn, $imm",
4717  "",
4718  []>, Sched<[]> {
4719  bits<5> Zdn;
4720  bits<9> imm;
4721  let Inst{31-24} = 0b00100101;
4722  let Inst{23-22} = sz8_64;
4723  let Inst{21-19} = 0b100;
4724  let Inst{18-16} = opc;
4725  let Inst{15-14} = 0b11;
4726  let Inst{13}    = imm{8};   // sh
4727  let Inst{12-5}  = imm{7-0}; // imm8
4728  let Inst{4-0}   = Zdn;
4729
4730  let Constraints = "$Zdn = $_Zdn";
4731  let DestructiveInstType = DestructiveOther;
4732  let ElementSize = ElementSizeNone;
4733  let hasSideEffects = 0;
4734}
4735
4736multiclass sve_int_arith_imm0<bits<3> opc, string asm, SDPatternOperator op> {
4737  def _B : sve_int_arith_imm0<0b00, opc, asm, ZPR8,  addsub_imm8_opt_lsl_i8>;
4738  def _H : sve_int_arith_imm0<0b01, opc, asm, ZPR16, addsub_imm8_opt_lsl_i16>;
4739  def _S : sve_int_arith_imm0<0b10, opc, asm, ZPR32, addsub_imm8_opt_lsl_i32>;
4740  def _D : sve_int_arith_imm0<0b11, opc, asm, ZPR64, addsub_imm8_opt_lsl_i64>;
4741
4742  def : SVE_1_Op_Imm_OptLsl_Pat<nxv16i8, op, ZPR8,  i32, SVEAddSubImm8Pat,  !cast<Instruction>(NAME # _B)>;
4743  def : SVE_1_Op_Imm_OptLsl_Pat<nxv8i16, op, ZPR16, i32, SVEAddSubImm16Pat, !cast<Instruction>(NAME # _H)>;
4744  def : SVE_1_Op_Imm_OptLsl_Pat<nxv4i32, op, ZPR32, i32, SVEAddSubImm32Pat, !cast<Instruction>(NAME # _S)>;
4745  def : SVE_1_Op_Imm_OptLsl_Pat<nxv2i64, op, ZPR64, i64, SVEAddSubImm64Pat, !cast<Instruction>(NAME # _D)>;
4746}
4747
4748class sve_int_arith_imm<bits<2> sz8_64, bits<6> opc, string asm,
4749                        ZPRRegOp zprty, Operand immtype>
4750: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, immtype:$imm),
4751  asm, "\t$Zdn, $_Zdn, $imm",
4752  "",
4753  []>, Sched<[]> {
4754  bits<5> Zdn;
4755  bits<8> imm;
4756  let Inst{31-24} = 0b00100101;
4757  let Inst{23-22} = sz8_64;
4758  let Inst{21-16} = opc;
4759  let Inst{15-13} = 0b110;
4760  let Inst{12-5} = imm;
4761  let Inst{4-0} = Zdn;
4762
4763  let Constraints = "$Zdn = $_Zdn";
4764  let DestructiveInstType = DestructiveOther;
4765  let ElementSize = ElementSizeNone;
4766  let hasSideEffects = 0;
4767}
4768
4769multiclass sve_int_arith_imm1<bits<2> opc, string asm, SDPatternOperator op> {
4770  def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, simm8_32b>;
4771  def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, simm8_32b>;
4772  def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, simm8_32b>;
4773  def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, simm8_32b>;
4774
4775  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B)>;
4776  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1,  op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H)>;
4777  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1,  op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S)>;
4778  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1,  op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D)>;
4779}
4780
4781multiclass sve_int_arith_imm1_unsigned<bits<2> opc, string asm, SDPatternOperator op> {
4782  def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, imm0_255>;
4783  def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, imm0_255>;
4784  def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, imm0_255>;
4785  def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, imm0_255>;
4786
4787  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithUImm8Pat, !cast<Instruction>(NAME # _B)>;
4788  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithUImm16Pat, !cast<Instruction>(NAME # _H)>;
4789  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithUImm32Pat, !cast<Instruction>(NAME # _S)>;
4790  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithUImm64Pat, !cast<Instruction>(NAME # _D)>;
4791}
4792
4793multiclass sve_int_arith_imm2<string asm, SDPatternOperator op> {
4794  def _B : sve_int_arith_imm<0b00, 0b110000, asm, ZPR8,  simm8_32b>;
4795  def _H : sve_int_arith_imm<0b01, 0b110000, asm, ZPR16, simm8_32b>;
4796  def _S : sve_int_arith_imm<0b10, 0b110000, asm, ZPR32, simm8_32b>;
4797  def _D : sve_int_arith_imm<0b11, 0b110000, asm, ZPR64, simm8_32b>;
4798
4799  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B)>;
4800  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H)>;
4801  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S)>;
4802  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D)>;
4803}
4804
4805//===----------------------------------------------------------------------===//
4806// SVE Bitwise Logical - Unpredicated Group
4807//===----------------------------------------------------------------------===//
4808
4809class sve_int_bin_cons_log<bits<2> opc, string asm>
4810: I<(outs ZPR64:$Zd), (ins ZPR64:$Zn, ZPR64:$Zm),
4811  asm, "\t$Zd, $Zn, $Zm",
4812  "",
4813  []>, Sched<[]> {
4814  bits<5> Zd;
4815  bits<5> Zm;
4816  bits<5> Zn;
4817  let Inst{31-24} = 0b00000100;
4818  let Inst{23-22} = opc{1-0};
4819  let Inst{21}    = 0b1;
4820  let Inst{20-16} = Zm;
4821  let Inst{15-10} = 0b001100;
4822  let Inst{9-5}   = Zn;
4823  let Inst{4-0}   = Zd;
4824
4825  let hasSideEffects = 0;
4826}
4827
4828multiclass sve_int_bin_cons_log<bits<2> opc, string asm, SDPatternOperator op> {
4829  def NAME : sve_int_bin_cons_log<opc, asm>;
4830
4831  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
4832  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
4833  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
4834  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4835
4836  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4837                  (!cast<Instruction>(NAME) ZPR8:$Zd,  ZPR8:$Zn,  ZPR8:$Zm),  1>;
4838  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4839                  (!cast<Instruction>(NAME) ZPR16:$Zd, ZPR16:$Zn, ZPR16:$Zm), 1>;
4840  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4841                  (!cast<Instruction>(NAME) ZPR32:$Zd, ZPR32:$Zn, ZPR32:$Zm), 1>;
4842}
4843
4844class sve2_int_bitwise_ternary_op_d<bits<3> opc, string asm>
4845: I<(outs ZPR64:$Zdn), (ins ZPR64:$_Zdn, ZPR64:$Zm, ZPR64:$Zk),
4846  asm, "\t$Zdn, $_Zdn, $Zm, $Zk",
4847  "",
4848  []>, Sched<[]> {
4849  bits<5> Zdn;
4850  bits<5> Zk;
4851  bits<5> Zm;
4852  let Inst{31-24} = 0b00000100;
4853  let Inst{23-22} = opc{2-1};
4854  let Inst{21}    = 0b1;
4855  let Inst{20-16} = Zm;
4856  let Inst{15-11} = 0b00111;
4857  let Inst{10}    = opc{0};
4858  let Inst{9-5}   = Zk;
4859  let Inst{4-0}   = Zdn;
4860
4861  let Constraints = "$Zdn = $_Zdn";
4862  let DestructiveInstType = DestructiveOther;
4863  let ElementSize = ElementSizeNone;
4864  let hasSideEffects = 0;
4865}
4866
4867multiclass sve2_int_bitwise_ternary_op<bits<3> opc, string asm, SDPatternOperator op,
4868                                       SDPatternOperator ir_op = null_frag> {
4869  def NAME : sve2_int_bitwise_ternary_op_d<opc, asm>;
4870
4871  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4872                  (!cast<Instruction>(NAME) ZPR8:$Zdn,  ZPR8:$Zm,  ZPR8:$Zk),  1>;
4873  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4874                  (!cast<Instruction>(NAME) ZPR16:$Zdn, ZPR16:$Zm, ZPR16:$Zk), 1>;
4875  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4876                  (!cast<Instruction>(NAME) ZPR32:$Zdn, ZPR32:$Zm, ZPR32:$Zk), 1>;
4877
4878  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
4879  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
4880  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
4881  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4882
4883
4884  def : SVE_3_Op_BSP_Pat<nxv16i8, ir_op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
4885  def : SVE_3_Op_BSP_Pat<nxv8i16, ir_op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
4886  def : SVE_3_Op_BSP_Pat<nxv4i32, ir_op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
4887  def : SVE_3_Op_BSP_Pat<nxv2i64, ir_op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4888}
4889
4890class sve2_int_rotate_right_imm<bits<4> tsz8_64, string asm,
4891                                ZPRRegOp zprty, Operand immtype>
4892: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, immtype:$imm),
4893  asm, "\t$Zdn, $_Zdn, $Zm, $imm",
4894  "",
4895  []>, Sched<[]> {
4896  bits<5> Zdn;
4897  bits<5> Zm;
4898  bits<6> imm;
4899  let Inst{31-24} = 0b00000100;
4900  let Inst{23-22} = tsz8_64{3-2};
4901  let Inst{21}    = 0b1;
4902  let Inst{20-19} = tsz8_64{1-0};
4903  let Inst{18-16} = imm{2-0}; // imm3
4904  let Inst{15-10} = 0b001101;
4905  let Inst{9-5}   = Zm;
4906  let Inst{4-0}   = Zdn;
4907
4908  let Constraints = "$Zdn = $_Zdn";
4909  let DestructiveInstType = DestructiveOther;
4910  let ElementSize = ElementSizeNone;
4911  let hasSideEffects = 0;
4912}
4913
4914multiclass sve2_int_rotate_right_imm<string asm, SDPatternOperator op> {
4915  def _B : sve2_int_rotate_right_imm<{0,0,0,1}, asm, ZPR8, vecshiftR8>;
4916  def _H : sve2_int_rotate_right_imm<{0,0,1,?}, asm, ZPR16, vecshiftR16> {
4917    let Inst{19} = imm{3};
4918  }
4919  def _S : sve2_int_rotate_right_imm<{0,1,?,?}, asm, ZPR32, vecshiftR32> {
4920    let Inst{20-19} = imm{4-3};
4921  }
4922  def _D : sve2_int_rotate_right_imm<{1,?,?,?}, asm, ZPR64, vecshiftR64> {
4923    let Inst{22}    = imm{5};
4924    let Inst{20-19} = imm{4-3};
4925  }
4926
4927  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4928  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4929  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4930  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4931}
4932
4933//===----------------------------------------------------------------------===//
4934// SVE Integer Wide Immediate - Predicated Group
4935//===----------------------------------------------------------------------===//
4936
4937class sve_int_dup_fpimm_pred<bits<2> sz, Operand fpimmtype,
4938                             string asm, ZPRRegOp zprty>
4939: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPRAny:$Pg, fpimmtype:$imm8),
4940  asm, "\t$Zd, $Pg/m, $imm8",
4941  "",
4942  []>, Sched<[]> {
4943  bits<4> Pg;
4944  bits<5> Zd;
4945  bits<8> imm8;
4946  let Inst{31-24} = 0b00000101;
4947  let Inst{23-22} = sz;
4948  let Inst{21-20} = 0b01;
4949  let Inst{19-16} = Pg;
4950  let Inst{15-13} = 0b110;
4951  let Inst{12-5}  = imm8;
4952  let Inst{4-0}   = Zd;
4953
4954  let Constraints = "$Zd = $_Zd";
4955  let DestructiveInstType = DestructiveOther;
4956  let ElementSize = zprty.ElementSize;
4957  let hasSideEffects = 0;
4958}
4959
4960multiclass sve_int_dup_fpimm_pred<string asm> {
4961  def _H : sve_int_dup_fpimm_pred<0b01, fpimm16, asm, ZPR16>;
4962  def _S : sve_int_dup_fpimm_pred<0b10, fpimm32, asm, ZPR32>;
4963  def _D : sve_int_dup_fpimm_pred<0b11, fpimm64, asm, ZPR64>;
4964
4965  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
4966                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, fpimm16:$imm8), 1>;
4967  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
4968                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, fpimm32:$imm8), 1>;
4969  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
4970                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, fpimm64:$imm8), 1>;
4971}
4972
4973class sve_int_dup_imm_pred<bits<2> sz8_64, bit m, string asm,
4974                           ZPRRegOp zprty, string pred_qual, dag iops>
4975: I<(outs zprty:$Zd), iops,
4976  asm, "\t$Zd, $Pg"#pred_qual#", $imm",
4977  "", []>, Sched<[]> {
4978  bits<5> Zd;
4979  bits<4> Pg;
4980  bits<9> imm;
4981  let Inst{31-24} = 0b00000101;
4982  let Inst{23-22} = sz8_64;
4983  let Inst{21-20} = 0b01;
4984  let Inst{19-16} = Pg;
4985  let Inst{15}    = 0b0;
4986  let Inst{14}    = m;
4987  let Inst{13}    = imm{8};   // sh
4988  let Inst{12-5}  = imm{7-0}; // imm8
4989  let Inst{4-0}   = Zd;
4990
4991  let DestructiveInstType = DestructiveOther;
4992  let ElementSize = zprty.ElementSize;
4993  let hasSideEffects = 0;
4994}
4995
4996multiclass sve_int_dup_imm_pred_merge_inst<
4997    bits<2> sz8_64, string asm, ZPRRegOp zprty, imm8_opt_lsl cpyimm,
4998    ValueType intty, ValueType predty, ValueType scalarty, ComplexPattern cpx> {
4999  let Constraints = "$Zd = $_Zd" in
5000  def NAME : sve_int_dup_imm_pred<sz8_64, 1, asm, zprty,  "/m",
5001                                  (ins zprty:$_Zd, PPRAny:$Pg, cpyimm:$imm)>;
5002  def : InstAlias<"mov $Zd, $Pg/m, $imm",
5003                  (!cast<Instruction>(NAME) zprty:$Zd, PPRAny:$Pg, cpyimm:$imm), 1>;
5004  def : Pat<(vselect predty:$Pg,
5005                (intty (splat_vector (scalarty (cpx i32:$imm, i32:$shift)))),
5006                ZPR:$Zd),
5007            (!cast<Instruction>(NAME) $Zd, $Pg, $imm, $shift)>;
5008}
5009
5010multiclass sve_int_dup_imm_pred_merge<string asm> {
5011  defm _B : sve_int_dup_imm_pred_merge_inst<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8,
5012                                            nxv16i8, nxv16i1, i32, SVECpyDupImm8Pat>;
5013  defm _H : sve_int_dup_imm_pred_merge_inst<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16,
5014                                            nxv8i16, nxv8i1, i32, SVECpyDupImm16Pat>;
5015  defm _S : sve_int_dup_imm_pred_merge_inst<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32,
5016                                            nxv4i32, nxv4i1, i32, SVECpyDupImm32Pat>;
5017  defm _D : sve_int_dup_imm_pred_merge_inst<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64,
5018                                            nxv2i64, nxv2i1, i64, SVECpyDupImm64Pat>;
5019
5020  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5021                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, 0, 0), 0>;
5022  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5023                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, 0, 0), 0>;
5024  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5025                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, 0, 0), 0>;
5026
5027  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv8f16 ZPR:$Zd)),
5028            (!cast<Instruction>(NAME # _H) $Zd, $Pg, 0, 0)>;
5029  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv4f16 ZPR:$Zd)),
5030            (!cast<Instruction>(NAME # _S) $Zd, $Pg, 0, 0)>;
5031  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f16 ZPR:$Zd)),
5032            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5033  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv4f32 ZPR:$Zd)),
5034            (!cast<Instruction>(NAME # _S) $Zd, $Pg, 0, 0)>;
5035  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f32 ZPR:$Zd)),
5036            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5037  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f64 ZPR:$Zd)),
5038            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5039}
5040
5041multiclass sve_int_dup_imm_pred_zero_inst<
5042    bits<2> sz8_64, string asm, ZPRRegOp zprty, imm8_opt_lsl cpyimm,
5043    ValueType intty, ValueType predty, ValueType scalarty, ComplexPattern cpx> {
5044  def NAME : sve_int_dup_imm_pred<sz8_64, 0, asm, zprty, "/z",
5045                                  (ins PPRAny:$Pg, cpyimm:$imm)>;
5046  def : InstAlias<"mov $Zd, $Pg/z, $imm",
5047                  (!cast<Instruction>(NAME) zprty:$Zd, PPRAny:$Pg, cpyimm:$imm), 1>;
5048  def : Pat<(intty (zext (predty PPRAny:$Ps1))),
5049            (!cast<Instruction>(NAME) PPRAny:$Ps1, 1, 0)>;
5050  def : Pat<(intty (sext (predty PPRAny:$Ps1))),
5051            (!cast<Instruction>(NAME) PPRAny:$Ps1, -1, 0)>;
5052  def : Pat<(intty (anyext (predty PPRAny:$Ps1))),
5053            (!cast<Instruction>(NAME) PPRAny:$Ps1, 1, 0)>;
5054  def : Pat<(vselect predty:$Pg,
5055                (intty (splat_vector (scalarty (cpx i32:$imm, i32:$shift)))),
5056                (intty (splat_vector (scalarty 0)))),
5057            (!cast<Instruction>(NAME) $Pg, $imm, $shift)>;
5058}
5059
5060multiclass sve_int_dup_imm_pred_zero<string asm> {
5061  defm _B : sve_int_dup_imm_pred_zero_inst<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8,
5062                                           nxv16i8, nxv16i1, i32, SVECpyDupImm8Pat>;
5063  defm _H : sve_int_dup_imm_pred_zero_inst<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16,
5064                                           nxv8i16, nxv8i1, i32, SVECpyDupImm16Pat>;
5065  defm _S : sve_int_dup_imm_pred_zero_inst<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32,
5066                                           nxv4i32, nxv4i1, i32, SVECpyDupImm32Pat>;
5067  defm _D : sve_int_dup_imm_pred_zero_inst<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64,
5068                                           nxv2i64, nxv2i1, i64, SVECpyDupImm64Pat>;
5069}
5070
5071//===----------------------------------------------------------------------===//
5072// SVE Integer Compare - Vectors Group
5073//===----------------------------------------------------------------------===//
5074
5075class sve_int_cmp<bit cmp_1, bits<2> sz8_64, bits<3> opc, string asm,
5076                  PPRRegOp pprty, ZPRRegOp zprty1, ZPRRegOp zprty2>
5077: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty1:$Zn, zprty2:$Zm),
5078  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
5079  "",
5080  []>, Sched<[]> {
5081  bits<4> Pd;
5082  bits<3> Pg;
5083  bits<5> Zm;
5084  bits<5> Zn;
5085  let Inst{31-24} = 0b00100100;
5086  let Inst{23-22} = sz8_64;
5087  let Inst{21}    = 0b0;
5088  let Inst{20-16} = Zm;
5089  let Inst{15}    = opc{2};
5090  let Inst{14}    = cmp_1;
5091  let Inst{13}    = opc{1};
5092  let Inst{12-10} = Pg;
5093  let Inst{9-5}   = Zn;
5094  let Inst{4}     = opc{0};
5095  let Inst{3-0}   = Pd;
5096
5097  let Defs = [NZCV];
5098  let ElementSize = pprty.ElementSize;
5099  let hasSideEffects = 0;
5100  let isPTestLike = 1;
5101}
5102
5103multiclass SVE_SETCC_Pat<CondCode cc, CondCode invcc, ValueType predvt,
5104                         ValueType intvt, Instruction cmp> {
5105  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, intvt:$Op3, cc)),
5106            (cmp $Op1, $Op2, $Op3)>;
5107  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, intvt:$Op3, invcc)),
5108            (cmp $Op1, $Op3, $Op2)>;
5109  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), intvt:$Op2, intvt:$Op3, cc))),
5110            (cmp $Pg, $Op2, $Op3)>;
5111  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), intvt:$Op2, intvt:$Op3, invcc))),
5112            (cmp $Pg, $Op3, $Op2)>;
5113}
5114
5115multiclass SVE_SETCC_Pat_With_Zero<CondCode cc, CondCode invcc, ValueType predvt,
5116                                   ValueType intvt, Instruction cmp> {
5117  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, (SVEDup0), cc)),
5118            (cmp $Op1, $Op2)>;
5119  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, (SVEDup0), intvt:$Op2, invcc)),
5120            (cmp $Op1, $Op2)>;
5121  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), intvt:$Op1, (SVEDup0), cc))),
5122            (cmp $Pg, $Op1)>;
5123  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), (SVEDup0), intvt:$Op1, invcc))),
5124            (cmp $Pg, $Op1)>;
5125}
5126
5127multiclass sve_int_cmp_0<bits<3> opc, string asm, CondCode cc, CondCode invcc> {
5128  def _B : sve_int_cmp<0b0, 0b00, opc, asm, PPR8, ZPR8, ZPR8>;
5129  def _H : sve_int_cmp<0b0, 0b01, opc, asm, PPR16, ZPR16, ZPR16>;
5130  def _S : sve_int_cmp<0b0, 0b10, opc, asm, PPR32, ZPR32, ZPR32>;
5131  def _D : sve_int_cmp<0b0, 0b11, opc, asm, PPR64, ZPR64, ZPR64>;
5132
5133  defm : SVE_SETCC_Pat<cc, invcc, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
5134  defm : SVE_SETCC_Pat<cc, invcc, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
5135  defm : SVE_SETCC_Pat<cc, invcc, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
5136  defm : SVE_SETCC_Pat<cc, invcc, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
5137}
5138
5139multiclass sve_int_cmp_0_wide<bits<3> opc, string asm, SDPatternOperator op> {
5140  def _B : sve_int_cmp<0b0, 0b00, opc, asm, PPR8, ZPR8, ZPR64>;
5141  def _H : sve_int_cmp<0b0, 0b01, opc, asm, PPR16, ZPR16, ZPR64>;
5142  def _S : sve_int_cmp<0b0, 0b10, opc, asm, PPR32, ZPR32, ZPR64>;
5143
5144  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
5145  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
5146  def : SVE_3_Op_Pat<nxv4i1,  op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
5147}
5148
5149multiclass sve_int_cmp_1_wide<bits<3> opc, string asm, SDPatternOperator op> {
5150  def _B : sve_int_cmp<0b1, 0b00, opc, asm, PPR8, ZPR8, ZPR64>;
5151  def _H : sve_int_cmp<0b1, 0b01, opc, asm, PPR16, ZPR16, ZPR64>;
5152  def _S : sve_int_cmp<0b1, 0b10, opc, asm, PPR32, ZPR32, ZPR64>;
5153
5154  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
5155  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
5156  def : SVE_3_Op_Pat<nxv4i1,  op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
5157}
5158
5159
5160//===----------------------------------------------------------------------===//
5161// SVE Integer Compare - Signed Immediate Group
5162//===----------------------------------------------------------------------===//
5163
5164class sve_int_scmp_vi<bits<2> sz8_64, bits<3> opc, string asm, PPRRegOp pprty,
5165                      ZPRRegOp zprty,
5166                      Operand immtype>
5167: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, immtype:$imm5),
5168  asm, "\t$Pd, $Pg/z, $Zn, $imm5",
5169  "",
5170  []>, Sched<[]> {
5171  bits<4> Pd;
5172  bits<3> Pg;
5173  bits<5> Zn;
5174  bits<5> imm5;
5175  let Inst{31-24} = 0b00100101;
5176  let Inst{23-22} = sz8_64;
5177  let Inst{21}    = 0b0;
5178  let Inst{20-16} = imm5;
5179  let Inst{15}    = opc{2};
5180  let Inst{14}    = 0b0;
5181  let Inst{13}    = opc{1};
5182  let Inst{12-10} = Pg;
5183  let Inst{9-5}   = Zn;
5184  let Inst{4}     = opc{0};
5185  let Inst{3-0}   = Pd;
5186
5187  let Defs = [NZCV];
5188  let ElementSize = pprty.ElementSize;
5189  let hasSideEffects = 0;
5190  let isPTestLike = 1;
5191}
5192
5193multiclass SVE_SETCC_Imm_Pat<CondCode cc, CondCode commuted_cc,
5194                             ValueType predvt, ValueType intvt,
5195                             Operand immtype, Instruction cmp> {
5196  def : Pat<(predvt (AArch64setcc_z (predvt PPR_3b:$Pg),
5197                                    (intvt ZPR:$Zs1),
5198                                    (intvt (splat_vector (immtype:$imm))),
5199                                    cc)),
5200            (cmp $Pg, $Zs1, immtype:$imm)>;
5201  def : Pat<(predvt (AArch64setcc_z (predvt PPR_3b:$Pg),
5202                                    (intvt (splat_vector (immtype:$imm))),
5203                                    (intvt ZPR:$Zs1),
5204                                    commuted_cc)),
5205            (cmp $Pg, $Zs1, immtype:$imm)>;
5206  def : Pat<(predvt (and predvt:$Pg,
5207                         (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)),
5208                                         (intvt ZPR:$Zs1),
5209                                         (intvt (splat_vector (immtype:$imm))),
5210                                         cc))),
5211            (cmp $Pg, $Zs1, immtype:$imm)>;
5212  def : Pat<(predvt (and predvt:$Pg,
5213                         (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)),
5214                                         (intvt (splat_vector (immtype:$imm))),
5215                                         (intvt ZPR:$Zs1),
5216                                         commuted_cc))),
5217            (cmp $Pg, $Zs1, immtype:$imm)>;
5218}
5219
5220multiclass sve_int_scmp_vi<bits<3> opc, string asm, CondCode cc, CondCode commuted_cc> {
5221  def _B : sve_int_scmp_vi<0b00, opc, asm, PPR8, ZPR8, simm5_32b>;
5222  def _H : sve_int_scmp_vi<0b01, opc, asm, PPR16, ZPR16, simm5_32b>;
5223  def _S : sve_int_scmp_vi<0b10, opc, asm, PPR32, ZPR32, simm5_32b>;
5224  def _D : sve_int_scmp_vi<0b11, opc, asm, PPR64, ZPR64, simm5_64b>;
5225
5226  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv16i1, nxv16i8, simm5_32b,
5227                           !cast<Instruction>(NAME # _B)>;
5228  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv8i1,  nxv8i16, simm5_32b,
5229                           !cast<Instruction>(NAME # _H)>;
5230  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv4i1,  nxv4i32, simm5_32b,
5231                           !cast<Instruction>(NAME # _S)>;
5232  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv2i1,  nxv2i64, simm5_64b,
5233                           !cast<Instruction>(NAME # _D)>;
5234}
5235
5236
5237//===----------------------------------------------------------------------===//
5238// SVE Integer Compare - Unsigned Immediate Group
5239//===----------------------------------------------------------------------===//
5240
5241class sve_int_ucmp_vi<bits<2> sz8_64, bits<2> opc, string asm, PPRRegOp pprty,
5242                      ZPRRegOp zprty, Operand immtype>
5243: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, immtype:$imm7),
5244  asm, "\t$Pd, $Pg/z, $Zn, $imm7",
5245  "",
5246  []>, Sched<[]> {
5247  bits<4> Pd;
5248  bits<3> Pg;
5249  bits<5> Zn;
5250  bits<7> imm7;
5251  let Inst{31-24} = 0b00100100;
5252  let Inst{23-22} = sz8_64;
5253  let Inst{21}    = 1;
5254  let Inst{20-14} = imm7;
5255  let Inst{13}    = opc{1};
5256  let Inst{12-10} = Pg;
5257  let Inst{9-5}   = Zn;
5258  let Inst{4}     = opc{0};
5259  let Inst{3-0}   = Pd;
5260
5261  let Defs = [NZCV];
5262  let ElementSize = pprty.ElementSize;
5263  let hasSideEffects = 0;
5264  let isPTestLike = 1;
5265}
5266
5267multiclass sve_int_ucmp_vi<bits<2> opc, string asm, CondCode cc,
5268                           CondCode commuted_cc> {
5269  def _B : sve_int_ucmp_vi<0b00, opc, asm, PPR8, ZPR8, imm0_127>;
5270  def _H : sve_int_ucmp_vi<0b01, opc, asm, PPR16, ZPR16, imm0_127>;
5271  def _S : sve_int_ucmp_vi<0b10, opc, asm, PPR32, ZPR32, imm0_127>;
5272  def _D : sve_int_ucmp_vi<0b11, opc, asm, PPR64, ZPR64, imm0_127_64b>;
5273
5274  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv16i1, nxv16i8, imm0_127,
5275                           !cast<Instruction>(NAME # _B)>;
5276  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv8i1,  nxv8i16, imm0_127,
5277                           !cast<Instruction>(NAME # _H)>;
5278  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv4i1,  nxv4i32, imm0_127,
5279                           !cast<Instruction>(NAME # _S)>;
5280  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv2i1,  nxv2i64, imm0_127_64b,
5281                           !cast<Instruction>(NAME # _D)>;
5282}
5283
5284
5285//===----------------------------------------------------------------------===//
5286// SVE Integer Compare - Scalars Group
5287//===----------------------------------------------------------------------===//
5288
5289class sve_int_cterm<bit sz, bit opc, string asm, RegisterClass rt>
5290: I<(outs), (ins rt:$Rn, rt:$Rm),
5291  asm, "\t$Rn, $Rm",
5292  "",
5293  []>, Sched<[]> {
5294  bits<5> Rm;
5295  bits<5> Rn;
5296  let Inst{31-23} = 0b001001011;
5297  let Inst{22}    = sz;
5298  let Inst{21}    = 0b1;
5299  let Inst{20-16} = Rm;
5300  let Inst{15-10} = 0b001000;
5301  let Inst{9-5}   = Rn;
5302  let Inst{4}     = opc;
5303  let Inst{3-0}   = 0b0000;
5304
5305  let Defs = [NZCV];
5306  let hasSideEffects = 0;
5307}
5308
5309class sve_int_while_rr<bits<2> sz8_64, bits<4> opc, string asm,
5310                       RegisterClass gprty, PPRRegOp pprty>
5311: I<(outs pprty:$Pd), (ins gprty:$Rn, gprty:$Rm),
5312  asm, "\t$Pd, $Rn, $Rm",
5313  "", []>, Sched<[]> {
5314  bits<4> Pd;
5315  bits<5> Rm;
5316  bits<5> Rn;
5317  let Inst{31-24} = 0b00100101;
5318  let Inst{23-22} = sz8_64;
5319  let Inst{21}    = 0b1;
5320  let Inst{20-16} = Rm;
5321  let Inst{15-13} = 0b000;
5322  let Inst{12-10} = opc{3-1};
5323  let Inst{9-5}   = Rn;
5324  let Inst{4}     = opc{0};
5325  let Inst{3-0}   = Pd;
5326
5327  let Defs = [NZCV];
5328  let ElementSize = pprty.ElementSize;
5329  let hasSideEffects = 0;
5330  let isWhile = 1;
5331}
5332
5333multiclass sve_int_while4_rr<bits<3> opc, string asm, SDPatternOperator op> {
5334  def _B : sve_int_while_rr<0b00, { 0, opc }, asm, GPR32, PPR8>;
5335  def _H : sve_int_while_rr<0b01, { 0, opc }, asm, GPR32, PPR16>;
5336  def _S : sve_int_while_rr<0b10, { 0, opc }, asm, GPR32, PPR32>;
5337  def _D : sve_int_while_rr<0b11, { 0, opc }, asm, GPR32, PPR64>;
5338
5339  def : SVE_2_Op_Pat<nxv16i1, op, i32, i32, !cast<Instruction>(NAME # _B)>;
5340  def : SVE_2_Op_Pat<nxv8i1,  op, i32, i32, !cast<Instruction>(NAME # _H)>;
5341  def : SVE_2_Op_Pat<nxv4i1,  op, i32, i32, !cast<Instruction>(NAME # _S)>;
5342  def : SVE_2_Op_Pat<nxv2i1,  op, i32, i32, !cast<Instruction>(NAME # _D)>;
5343}
5344
5345multiclass sve_int_while8_rr<bits<3> opc, string asm, SDPatternOperator op> {
5346  def _B : sve_int_while_rr<0b00, { 1, opc }, asm, GPR64, PPR8>;
5347  def _H : sve_int_while_rr<0b01, { 1, opc }, asm, GPR64, PPR16>;
5348  def _S : sve_int_while_rr<0b10, { 1, opc }, asm, GPR64, PPR32>;
5349  def _D : sve_int_while_rr<0b11, { 1, opc }, asm, GPR64, PPR64>;
5350
5351  def : SVE_2_Op_Pat<nxv16i1, op, i64, i64, !cast<Instruction>(NAME # _B)>;
5352  def : SVE_2_Op_Pat<nxv8i1,  op, i64, i64, !cast<Instruction>(NAME # _H)>;
5353  def : SVE_2_Op_Pat<nxv4i1,  op, i64, i64, !cast<Instruction>(NAME # _S)>;
5354  def : SVE_2_Op_Pat<nxv2i1,  op, i64, i64, !cast<Instruction>(NAME # _D)>;
5355}
5356
5357class sve2_int_while_rr<bits<2> sz8_64, bits<1> rw, string asm,
5358                        PPRRegOp pprty>
5359: I<(outs pprty:$Pd), (ins GPR64:$Rn, GPR64:$Rm),
5360  asm, "\t$Pd, $Rn, $Rm",
5361  "", []>, Sched<[]> {
5362  bits<4> Pd;
5363  bits<5> Rm;
5364  bits<5> Rn;
5365  let Inst{31-24} = 0b00100101;
5366  let Inst{23-22} = sz8_64;
5367  let Inst{21}    = 0b1;
5368  let Inst{20-16} = Rm;
5369  let Inst{15-10} = 0b001100;
5370  let Inst{9-5}   = Rn;
5371  let Inst{4}     = rw;
5372  let Inst{3-0}   = Pd;
5373
5374  let Defs = [NZCV];
5375  let ElementSize = pprty.ElementSize;
5376  let hasSideEffects = 0;
5377  let isWhile = 1;
5378}
5379
5380multiclass sve2_int_while_rr<bits<1> rw, string asm, string op> {
5381  def _B : sve2_int_while_rr<0b00, rw, asm, PPR8>;
5382  def _H : sve2_int_while_rr<0b01, rw, asm, PPR16>;
5383  def _S : sve2_int_while_rr<0b10, rw, asm, PPR32>;
5384  def _D : sve2_int_while_rr<0b11, rw, asm, PPR64>;
5385
5386  def : SVE_2_Op_Pat<nxv16i1, !cast<SDPatternOperator>(op # _b), i64, i64, !cast<Instruction>(NAME # _B)>;
5387  def : SVE_2_Op_Pat<nxv8i1,  !cast<SDPatternOperator>(op # _h), i64, i64, !cast<Instruction>(NAME # _H)>;
5388  def : SVE_2_Op_Pat<nxv4i1,  !cast<SDPatternOperator>(op # _s), i64, i64, !cast<Instruction>(NAME # _S)>;
5389  def : SVE_2_Op_Pat<nxv2i1,  !cast<SDPatternOperator>(op # _d), i64, i64, !cast<Instruction>(NAME # _D)>;
5390}
5391
5392//===----------------------------------------------------------------------===//
5393// SVE Floating Point Fast Reduction Group
5394//===----------------------------------------------------------------------===//
5395
5396class sve_fp_fast_red<bits<2> sz, bits<3> opc, string asm,
5397                      ZPRRegOp zprty, FPRasZPROperand dstOpType>
5398: I<(outs dstOpType:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
5399  asm, "\t$Vd, $Pg, $Zn",
5400  "",
5401  []>, Sched<[]> {
5402  bits<5> Zn;
5403  bits<5> Vd;
5404  bits<3> Pg;
5405  let Inst{31-24} = 0b01100101;
5406  let Inst{23-22} = sz;
5407  let Inst{21-19} = 0b000;
5408  let Inst{18-16} = opc;
5409  let Inst{15-13} = 0b001;
5410  let Inst{12-10} = Pg;
5411  let Inst{9-5}   = Zn;
5412  let Inst{4-0}   = Vd;
5413
5414  let hasSideEffects = 0;
5415  let mayRaiseFPException = 1;
5416}
5417
5418multiclass sve_fp_fast_red<bits<3> opc, string asm, SDPatternOperator op> {
5419  def _H : sve_fp_fast_red<0b01, opc, asm, ZPR16, FPR16asZPR>;
5420  def _S : sve_fp_fast_red<0b10, opc, asm, ZPR32, FPR32asZPR>;
5421  def _D : sve_fp_fast_red<0b11, opc, asm, ZPR64, FPR64asZPR>;
5422
5423  def : SVE_2_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
5424  def : SVE_2_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
5425  def : SVE_2_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
5426  def : SVE_2_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
5427  def : SVE_2_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
5428  def : SVE_2_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
5429}
5430
5431//===----------------------------------------------------------------------===//
5432// SVE Floating Point Accumulating Reduction Group
5433//===----------------------------------------------------------------------===//
5434
5435class sve_fp_2op_p_vd<bits<2> sz, bits<3> opc, string asm,
5436                      ZPRRegOp zprty, FPRasZPROperand dstOpType>
5437: I<(outs dstOpType:$Vdn), (ins PPR3bAny:$Pg, dstOpType:$_Vdn, zprty:$Zm),
5438  asm, "\t$Vdn, $Pg, $_Vdn, $Zm",
5439  "",
5440  []>,
5441  Sched<[]> {
5442  bits<3> Pg;
5443  bits<5> Vdn;
5444  bits<5> Zm;
5445  let Inst{31-24} = 0b01100101;
5446  let Inst{23-22} = sz;
5447  let Inst{21-19} = 0b011;
5448  let Inst{18-16} = opc;
5449  let Inst{15-13} = 0b001;
5450  let Inst{12-10} = Pg;
5451  let Inst{9-5}   = Zm;
5452  let Inst{4-0}   = Vdn;
5453
5454  let Constraints = "$Vdn = $_Vdn";
5455  let hasSideEffects = 0;
5456  let mayRaiseFPException = 1;
5457}
5458
5459multiclass sve_fp_2op_p_vd<bits<3> opc, string asm, SDPatternOperator op> {
5460  def _H : sve_fp_2op_p_vd<0b01, opc, asm, ZPR16, FPR16asZPR>;
5461  def _S : sve_fp_2op_p_vd<0b10, opc, asm, ZPR32, FPR32asZPR>;
5462  def _D : sve_fp_2op_p_vd<0b11, opc, asm, ZPR64, FPR64asZPR>;
5463
5464  def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H)>;
5465  def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H)>;
5466  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
5467  def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S)>;
5468  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
5469  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
5470}
5471
5472//===----------------------------------------------------------------------===//
5473// SVE Floating Point Compare - Vectors Group
5474//===----------------------------------------------------------------------===//
5475
5476class sve_fp_3op_p_pd<bits<2> sz, bits<3> opc, string asm, PPRRegOp pprty,
5477                      ZPRRegOp zprty>
5478: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
5479  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
5480  "",
5481  []>, Sched<[]> {
5482  bits<4> Pd;
5483  bits<3> Pg;
5484  bits<5> Zm;
5485  bits<5> Zn;
5486  let Inst{31-24} = 0b01100101;
5487  let Inst{23-22} = sz;
5488  let Inst{21}    = 0b0;
5489  let Inst{20-16} = Zm;
5490  let Inst{15}    = opc{2};
5491  let Inst{14}    = 0b1;
5492  let Inst{13}    = opc{1};
5493  let Inst{12-10} = Pg;
5494  let Inst{9-5}   = Zn;
5495  let Inst{4}     = opc{0};
5496  let Inst{3-0}   = Pd;
5497
5498  let hasSideEffects = 0;
5499  let mayRaiseFPException = 1;
5500}
5501
5502multiclass sve_fp_3op_p_pd<bits<3> opc, string asm, SDPatternOperator op> {
5503  def _H : sve_fp_3op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5504  def _S : sve_fp_3op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5505  def _D : sve_fp_3op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5506
5507  def : SVE_3_Op_Pat<nxv8i1, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
5508  def : SVE_3_Op_Pat<nxv4i1, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
5509  def : SVE_3_Op_Pat<nxv2i1, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
5510}
5511
5512multiclass sve_fp_3op_p_pd_cc<bits<3> opc, string asm,
5513                              CondCode cc1, CondCode cc2,
5514                              CondCode invcc1, CondCode invcc2> {
5515  def _H : sve_fp_3op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5516  def _S : sve_fp_3op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5517  def _D : sve_fp_3op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5518
5519  defm : SVE_SETCC_Pat<cc1, invcc1, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5520  defm : SVE_SETCC_Pat<cc1, invcc1, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5521  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5522  defm : SVE_SETCC_Pat<cc1, invcc1, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5523  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5524  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5525
5526  defm : SVE_SETCC_Pat<cc2, invcc2, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5527  defm : SVE_SETCC_Pat<cc2, invcc2, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5528  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5529  defm : SVE_SETCC_Pat<cc2, invcc2, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5530  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5531  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5532}
5533
5534//===----------------------------------------------------------------------===//
5535// SVE Floating Point Compare - with Zero Group
5536//===----------------------------------------------------------------------===//
5537
5538class sve_fp_2op_p_pd<bits<2> sz, bits<3> opc, string asm, PPRRegOp pprty,
5539                      ZPRRegOp zprty>
5540: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn),
5541  asm, "\t$Pd, $Pg/z, $Zn, #0.0",
5542  "",
5543  []>, Sched<[]> {
5544  bits<4> Pd;
5545  bits<3> Pg;
5546  bits<5> Zn;
5547  let Inst{31-24} = 0b01100101;
5548  let Inst{23-22} = sz;
5549  let Inst{21-18} = 0b0100;
5550  let Inst{17-16} = opc{2-1};
5551  let Inst{15-13} = 0b001;
5552  let Inst{12-10} = Pg;
5553  let Inst{9-5}   = Zn;
5554  let Inst{4}     = opc{0};
5555  let Inst{3-0}   = Pd;
5556
5557  let hasSideEffects = 0;
5558  let mayRaiseFPException = 1;
5559}
5560
5561multiclass sve_fp_2op_p_pd<bits<3> opc, string asm,
5562                           CondCode cc1, CondCode cc2,
5563                           CondCode invcc1, CondCode invcc2> {
5564  def _H : sve_fp_2op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5565  def _S : sve_fp_2op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5566  def _D : sve_fp_2op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5567
5568  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5569  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5570  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5571  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5572  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5573  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5574
5575  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5576  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5577  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5578  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5579  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5580  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5581}
5582
5583
5584//===----------------------------------------------------------------------===//
5585//SVE Index Generation Group
5586//===----------------------------------------------------------------------===//
5587
5588def simm5_8b_tgt : TImmLeaf<i8, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]>;
5589def simm5_16b_tgt : TImmLeaf<i16, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]>;
5590def simm5_32b_tgt : TImmLeaf<i32, [{ return (int32_t)Imm >= -16 && (int32_t)Imm < 16; }]>;
5591def simm5_64b_tgt : TImmLeaf<i64, [{ return (int64_t)Imm >= -16 && (int64_t)Imm < 16; }]>;
5592def i64imm_32bit_tgt : TImmLeaf<i64, [{
5593  return (Imm & 0xffffffffULL) == static_cast<uint64_t>(Imm);
5594}]>;
5595
5596class sve_int_index_ii<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5597                       Operand imm_ty>
5598: I<(outs zprty:$Zd), (ins imm_ty:$imm5, imm_ty:$imm5b),
5599  asm, "\t$Zd, $imm5, $imm5b",
5600  "", []>, Sched<[]> {
5601  bits<5> Zd;
5602  bits<5> imm5;
5603  bits<5> imm5b;
5604  let Inst{31-24} = 0b00000100;
5605  let Inst{23-22} = sz8_64;
5606  let Inst{21}    = 0b1;
5607  let Inst{20-16} = imm5b;
5608  let Inst{15-10} = 0b010000;
5609  let Inst{9-5}   = imm5;
5610  let Inst{4-0}   = Zd;
5611
5612  let hasSideEffects = 0;
5613  let isReMaterializable = 1;
5614}
5615
5616multiclass sve_int_index_ii<string asm> {
5617  def _B : sve_int_index_ii<0b00, asm, ZPR8, simm5_8b>;
5618  def _H : sve_int_index_ii<0b01, asm, ZPR16, simm5_16b>;
5619  def _S : sve_int_index_ii<0b10, asm, ZPR32, simm5_32b>;
5620  def _D : sve_int_index_ii<0b11, asm, ZPR64, simm5_64b>;
5621
5622  def : Pat<(nxv16i8 (step_vector simm5_8b_tgt:$imm5b)),
5623            (!cast<Instruction>(NAME # "_B") (i32 0), (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5624  def : Pat<(nxv8i16 (step_vector simm5_16b_tgt:$imm5b)),
5625            (!cast<Instruction>(NAME # "_H") (i32 0), (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5626  def : Pat<(nxv4i32 (step_vector simm5_32b_tgt:$imm5b)),
5627            (!cast<Instruction>(NAME # "_S") (i32 0), simm5_32b:$imm5b)>;
5628  def : Pat<(nxv2i64 (step_vector simm5_64b_tgt:$imm5b)),
5629            (!cast<Instruction>(NAME # "_D") (i64 0), simm5_64b:$imm5b)>;
5630
5631  // add(step_vector(step), dup(X)) -> index(X, step).
5632  def : Pat<(add (nxv16i8 (step_vector_oneuse simm5_8b_tgt:$imm5b)), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
5633            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5634  def : Pat<(add (nxv8i16 (step_vector_oneuse simm5_16b_tgt:$imm5b)), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
5635            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5636  def : Pat<(add (nxv4i32 (step_vector_oneuse simm5_32b_tgt:$imm5b)), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
5637            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, simm5_32b:$imm5b)>;
5638  def : Pat<(add (nxv2i64 (step_vector_oneuse simm5_64b_tgt:$imm5b)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5639            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, simm5_64b:$imm5b)>;
5640}
5641
5642class sve_int_index_ir<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5643                       RegisterClass srcRegType, Operand imm_ty>
5644: I<(outs zprty:$Zd), (ins imm_ty:$imm5, srcRegType:$Rm),
5645  asm, "\t$Zd, $imm5, $Rm",
5646  "", []>, Sched<[]> {
5647  bits<5> Rm;
5648  bits<5> Zd;
5649  bits<5> imm5;
5650  let Inst{31-24} = 0b00000100;
5651  let Inst{23-22} = sz8_64;
5652  let Inst{21}    = 0b1;
5653  let Inst{20-16} = Rm;
5654  let Inst{15-10} = 0b010010;
5655  let Inst{9-5}   = imm5;
5656  let Inst{4-0}   = Zd;
5657
5658  let hasSideEffects = 0;
5659}
5660
5661multiclass sve_int_index_ir<string asm, SDPatternOperator mulop, SDPatternOperator muloneuseop> {
5662  def _B : sve_int_index_ir<0b00, asm, ZPR8, GPR32, simm5_8b>;
5663  def _H : sve_int_index_ir<0b01, asm, ZPR16, GPR32, simm5_16b>;
5664  def _S : sve_int_index_ir<0b10, asm, ZPR32, GPR32, simm5_32b>;
5665  def _D : sve_int_index_ir<0b11, asm, ZPR64, GPR64, simm5_64b>;
5666
5667  def : Pat<(nxv16i8 (step_vector i8:$imm)),
5668            (!cast<Instruction>(NAME # "_B") (i32 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5669  def : Pat<(nxv8i16 (step_vector i16:$imm)),
5670            (!cast<Instruction>(NAME # "_H") (i32 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5671  def : Pat<(nxv4i32 (step_vector i32:$imm)),
5672            (!cast<Instruction>(NAME # "_S") (i32 0), (!cast<Instruction>("MOVi32imm") $imm))>;
5673  def : Pat<(nxv2i64 (step_vector i64:$imm)),
5674            (!cast<Instruction>(NAME # "_D") (i64 0), (!cast<Instruction>("MOVi64imm") $imm))>;
5675  def : Pat<(nxv2i64 (step_vector i64imm_32bit_tgt:$imm)),
5676            (!cast<Instruction>(NAME # "_D") (i64 0), (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5677
5678  // add(step_vector(step), dup(X)) -> index(X, step).
5679  def : Pat<(add (nxv16i8 (step_vector_oneuse i8:$imm)), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
5680            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5681  def : Pat<(add (nxv8i16 (step_vector_oneuse i16:$imm)), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
5682            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5683  def : Pat<(add (nxv4i32 (step_vector_oneuse i32:$imm)), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
5684            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, (!cast<Instruction>("MOVi32imm") $imm))>;
5685  def : Pat<(add (nxv2i64 (step_vector_oneuse i64:$imm)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5686            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, (!cast<Instruction>("MOVi64imm") $imm))>;
5687  def : Pat<(add (nxv2i64 (step_vector_oneuse i64imm_32bit_tgt:$imm)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5688            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5689
5690  // mul(step_vector(1), dup(Y)) -> index(0, Y).
5691  def : Pat<(mulop (nxv16i1 (AArch64ptrue 31)), (nxv16i8 (step_vector_oneuse (i8 1))), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))),
5692            (!cast<Instruction>(NAME # "_B") (i32 0), GPR32:$Rm)>;
5693  def : Pat<(mulop (nxv8i1 (AArch64ptrue 31)), (nxv8i16 (step_vector_oneuse (i16 1))), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),
5694            (!cast<Instruction>(NAME # "_H") (i32 0), GPR32:$Rm)>;
5695  def : Pat<(mulop (nxv4i1 (AArch64ptrue 31)), (nxv4i32 (step_vector_oneuse (i32 1))), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),
5696            (!cast<Instruction>(NAME # "_S") (i32 0), GPR32:$Rm)>;
5697  def : Pat<(mulop (nxv2i1 (AArch64ptrue 31)), (nxv2i64 (step_vector_oneuse (i64 1))), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),
5698            (!cast<Instruction>(NAME # "_D") (i64 0), GPR64:$Rm)>;
5699
5700  // add(mul(step_vector(1), dup(Y)), dup(X)) -> index(X, Y).
5701  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)))),
5702            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, GPR32:$Rm)>;
5703  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)))),
5704            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, GPR32:$Rm)>;
5705  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)))),
5706            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, GPR32:$Rm)>;
5707  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)))),
5708            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, GPR64:$Rm)>;
5709}
5710
5711class sve_int_index_ri<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5712                       RegisterClass srcRegType, Operand imm_ty>
5713: I<(outs zprty:$Zd), (ins srcRegType:$Rn, imm_ty:$imm5),
5714  asm, "\t$Zd, $Rn, $imm5",
5715  "", []>, Sched<[]> {
5716  bits<5> Rn;
5717  bits<5> Zd;
5718  bits<5> imm5;
5719  let Inst{31-24} = 0b00000100;
5720  let Inst{23-22} = sz8_64;
5721  let Inst{21}    = 0b1;
5722  let Inst{20-16} = imm5;
5723  let Inst{15-10} = 0b010001;
5724  let Inst{9-5}   = Rn;
5725  let Inst{4-0}   = Zd;
5726
5727  let hasSideEffects = 0;
5728}
5729
5730multiclass sve_int_index_ri<string asm> {
5731  def _B : sve_int_index_ri<0b00, asm, ZPR8, GPR32, simm5_8b>;
5732  def _H : sve_int_index_ri<0b01, asm, ZPR16, GPR32, simm5_16b>;
5733  def _S : sve_int_index_ri<0b10, asm, ZPR32, GPR32, simm5_32b>;
5734  def _D : sve_int_index_ri<0b11, asm, ZPR64, GPR64, simm5_64b>;
5735
5736  // add(step_vector(step), dup(X)) -> index(X, step).
5737  def : Pat<(add (nxv16i8 (step_vector_oneuse simm5_8b_tgt:$imm5)), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))),
5738            (!cast<Instruction>(NAME # "_B") GPR32:$Rm, (!cast<SDNodeXForm>("trunc_imm") $imm5))>;
5739  def : Pat<(add (nxv8i16 (step_vector_oneuse simm5_16b_tgt:$imm5)), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),
5740            (!cast<Instruction>(NAME # "_H") GPR32:$Rm, (!cast<SDNodeXForm>("trunc_imm") $imm5))>;
5741  def : Pat<(add (nxv4i32 (step_vector_oneuse simm5_32b_tgt:$imm5)), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),
5742            (!cast<Instruction>(NAME # "_S") GPR32:$Rm, simm5_32b:$imm5)>;
5743  def : Pat<(add (nxv2i64 (step_vector_oneuse simm5_64b_tgt:$imm5)), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),
5744            (!cast<Instruction>(NAME # "_D") GPR64:$Rm, simm5_64b:$imm5)>;
5745}
5746
5747class sve_int_index_rr<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5748                       RegisterClass srcRegType>
5749: I<(outs zprty:$Zd), (ins srcRegType:$Rn, srcRegType:$Rm),
5750  asm, "\t$Zd, $Rn, $Rm",
5751  "", []>, Sched<[]> {
5752  bits<5> Zd;
5753  bits<5> Rm;
5754  bits<5> Rn;
5755  let Inst{31-24} = 0b00000100;
5756  let Inst{23-22} = sz8_64;
5757  let Inst{21}    = 0b1;
5758  let Inst{20-16} = Rm;
5759  let Inst{15-10} = 0b010011;
5760  let Inst{9-5}   = Rn;
5761  let Inst{4-0}   = Zd;
5762
5763  let hasSideEffects = 0;
5764}
5765
5766multiclass sve_int_index_rr<string asm, SDPatternOperator mulop> {
5767  def _B : sve_int_index_rr<0b00, asm, ZPR8, GPR32>;
5768  def _H : sve_int_index_rr<0b01, asm, ZPR16, GPR32>;
5769  def _S : sve_int_index_rr<0b10, asm, ZPR32, GPR32>;
5770  def _D : sve_int_index_rr<0b11, asm, ZPR64, GPR64>;
5771
5772  // add(step_vector(step), dup(X)) -> index(X, step).
5773  def : Pat<(add (nxv16i8 (step_vector_oneuse i8:$imm)), (nxv16i8 (splat_vector(i32 GPR32:$Rn)))),
5774            (!cast<Instruction>(NAME # "_B") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5775  def : Pat<(add (nxv8i16 (step_vector_oneuse i16:$imm)), (nxv8i16 (splat_vector(i32 GPR32:$Rn)))),
5776            (!cast<Instruction>(NAME # "_H") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5777  def : Pat<(add (nxv4i32 (step_vector_oneuse i32:$imm)), (nxv4i32 (splat_vector(i32 GPR32:$Rn)))),
5778            (!cast<Instruction>(NAME # "_S") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") $imm))>;
5779  def : Pat<(add (nxv2i64 (step_vector_oneuse i64:$imm)), (nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
5780            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, (!cast<Instruction>("MOVi64imm") $imm))>;
5781  def : Pat<(add (nxv2i64 (step_vector_oneuse i64imm_32bit_tgt:$imm)), (nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
5782            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5783
5784  // add(mul(step_vector(1), dup(Y)), dup(X)) -> index(X, Y).
5785  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)))),
5786            (!cast<Instruction>(NAME # "_B") GPR32:$Rn, GPR32:$Rm)>;
5787  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)))),
5788            (!cast<Instruction>(NAME # "_H") GPR32:$Rn, GPR32:$Rm)>;
5789  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)))),
5790            (!cast<Instruction>(NAME # "_S") GPR32:$Rn, GPR32:$Rm)>;
5791  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)))),
5792            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, GPR64:$Rm)>;
5793}
5794
5795//===----------------------------------------------------------------------===//
5796// SVE Bitwise Shift - Predicated Group
5797//===----------------------------------------------------------------------===//
5798
5799class sve_int_bin_pred_shift_imm<bits<4> tsz8_64, bits<4> opc, string asm,
5800                                 ZPRRegOp zprty, Operand immtype>
5801: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, immtype:$imm),
5802  asm, "\t$Zdn, $Pg/m, $_Zdn, $imm",
5803  "",
5804  []>, Sched<[]> {
5805  bits<3> Pg;
5806  bits<5> Zdn;
5807  bits<6> imm;
5808  let Inst{31-24} = 0b00000100;
5809  let Inst{23-22} = tsz8_64{3-2};
5810  let Inst{21-20} = 0b00;
5811  let Inst{19-16} = opc;
5812  let Inst{15-13} = 0b100;
5813  let Inst{12-10} = Pg;
5814  let Inst{9-8}   = tsz8_64{1-0};
5815  let Inst{7-5}   = imm{2-0}; // imm3
5816  let Inst{4-0}   = Zdn;
5817
5818  let Constraints = "$Zdn = $_Zdn";
5819  let DestructiveInstType = DestructiveBinaryImm;
5820  let ElementSize = zprty.ElementSize;
5821  let hasSideEffects = 0;
5822}
5823
5824multiclass sve_int_bin_pred_shift_imm_left<bits<4> opc, string asm, string Ps,
5825                                           SDPatternOperator op = null_frag> {
5826  def _B : SVEPseudo2Instr<Ps # _B, 1>,
5827           sve_int_bin_pred_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
5828  def _H : SVEPseudo2Instr<Ps # _H, 1>,
5829           sve_int_bin_pred_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
5830    let Inst{8} = imm{3};
5831  }
5832  def _S : SVEPseudo2Instr<Ps # _S, 1>,
5833           sve_int_bin_pred_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
5834    let Inst{9-8} = imm{4-3};
5835  }
5836  def _D : SVEPseudo2Instr<Ps # _D, 1>,
5837           sve_int_bin_pred_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
5838    let Inst{22}  = imm{5};
5839    let Inst{9-8} = imm{4-3};
5840  }
5841
5842  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i1, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _B)>;
5843  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i1,  nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _H)>;
5844  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i1,  nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _S)>;
5845  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i1,  nxv2i64, i32, tvecshiftL64, !cast<Instruction>(NAME # _D)>;
5846}
5847
5848// As above but shift amount takes the form of a "vector immediate".
5849multiclass sve_int_bin_pred_shift_imm_left_dup<bits<4> opc, string asm,
5850                                               string Ps, SDPatternOperator op>
5851: sve_int_bin_pred_shift_imm_left<opc, asm, Ps, null_frag> {
5852  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8,  !cast<Instruction>(NAME # _B)>;
5853  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
5854  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
5855  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
5856}
5857
5858multiclass sve_int_bin_pred_shift_imm_left_zeroing_bhsd<SDPatternOperator op> {
5859  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8,  tvecshiftL8,  FalseLanesZero>;
5860  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, tvecshiftL16, FalseLanesZero>;
5861  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, tvecshiftL32, FalseLanesZero>;
5862  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, tvecshiftL64, FalseLanesZero>;
5863
5864  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv16i8, op, nxv16i1, nxv16i8, tvecshiftL8,  !cast<Pseudo>(NAME # _B_ZERO)>;
5865  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv8i16, op, nxv8i1,  nxv8i16, tvecshiftL16, !cast<Pseudo>(NAME # _H_ZERO)>;
5866  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv4i32, op, nxv4i1,  nxv4i32, tvecshiftL32, !cast<Pseudo>(NAME # _S_ZERO)>;
5867  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv2i64, op, nxv2i1,  nxv2i64, tvecshiftL64, !cast<Pseudo>(NAME # _D_ZERO)>;
5868}
5869
5870multiclass sve_int_bin_pred_shift_imm_right<bits<4> opc, string asm, string Ps,
5871                                            SDPatternOperator op = null_frag> {
5872  def _B : SVEPseudo2Instr<Ps # _B, 1>,
5873           sve_int_bin_pred_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
5874  def _H : SVEPseudo2Instr<Ps # _H, 1>,
5875           sve_int_bin_pred_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
5876    let Inst{8} = imm{3};
5877  }
5878  def _S : SVEPseudo2Instr<Ps # _S, 1>,
5879           sve_int_bin_pred_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
5880    let Inst{9-8} = imm{4-3};
5881  }
5882  def _D : SVEPseudo2Instr<Ps # _D, 1>,
5883           sve_int_bin_pred_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
5884    let Inst{22}  = imm{5};
5885    let Inst{9-8} = imm{4-3};
5886  }
5887
5888  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i1, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
5889  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i1,  nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
5890  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i1,  nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
5891  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i1,  nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
5892}
5893
5894// As above but shift amount takes the form of a "vector immediate".
5895multiclass sve_int_bin_pred_shift_imm_right_dup<bits<4> opc, string asm,
5896                                            string Ps, SDPatternOperator op>
5897: sve_int_bin_pred_shift_imm_right<opc, asm, Ps, null_frag> {
5898  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8,  !cast<Instruction>(NAME # _B)>;
5899  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
5900  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
5901  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
5902}
5903
5904multiclass sve_int_bin_pred_shift_imm_right_zeroing_bhsd<SDPatternOperator op = null_frag> {
5905  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8, vecshiftR8, FalseLanesZero>;
5906  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, vecshiftR16, FalseLanesZero>;
5907  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, vecshiftR32, FalseLanesZero>;
5908  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, vecshiftR64, FalseLanesZero>;
5909
5910  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv16i8, op, nxv16i1, nxv16i8, tvecshiftR8, !cast<Pseudo>(NAME # _B_ZERO)>;
5911  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv8i16, op, nxv8i1, nxv8i16, tvecshiftR16, !cast<Pseudo>(NAME # _H_ZERO)>;
5912  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv4i32, op, nxv4i1, nxv4i32, tvecshiftR32, !cast<Pseudo>(NAME # _S_ZERO)>;
5913  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv2i64, op, nxv2i1, nxv2i64, tvecshiftR64, !cast<Pseudo>(NAME # _D_ZERO)>;
5914}
5915
5916class sve_int_bin_pred_shift<bits<2> sz8_64, bit wide, bits<3> opc,
5917                             string asm, ZPRRegOp zprty, ZPRRegOp zprty2>
5918: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty2:$Zm),
5919  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
5920  "",
5921  []>, Sched<[]> {
5922  bits<3> Pg;
5923  bits<5> Zdn;
5924  bits<5> Zm;
5925  let Inst{31-24} = 0b00000100;
5926  let Inst{23-22} = sz8_64;
5927  let Inst{21-20} = 0b01;
5928  let Inst{19}    = wide;
5929  let Inst{18-16} = opc;
5930  let Inst{15-13} = 0b100;
5931  let Inst{12-10} = Pg;
5932  let Inst{9-5}   = Zm;
5933  let Inst{4-0}   = Zdn;
5934
5935  let Constraints = "$Zdn = $_Zdn";
5936  let DestructiveInstType = DestructiveOther;
5937  let ElementSize = zprty.ElementSize;
5938  let hasSideEffects = 0;
5939}
5940
5941multiclass sve_int_bin_pred_shift<bits<3> opc, string asm, string Ps,
5942                                  SDPatternOperator op, string revname, bit isReverseInstr = 0> {
5943  let DestructiveInstType = DestructiveBinaryCommWithRev in {
5944  def _B : sve_int_bin_pred_shift<0b00, 0b0, opc, asm, ZPR8, ZPR8>,
5945           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
5946  def _H : sve_int_bin_pred_shift<0b01, 0b0, opc, asm, ZPR16, ZPR16>,
5947           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
5948  def _S : sve_int_bin_pred_shift<0b10, 0b0, opc, asm, ZPR32, ZPR32>,
5949           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
5950  def _D : sve_int_bin_pred_shift<0b11, 0b0, opc, asm, ZPR64, ZPR64>,
5951           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
5952  }
5953  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
5954  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
5955  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
5956  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
5957}
5958
5959multiclass sve_int_bin_pred_zeroing_bhsd<SDPatternOperator op> {
5960  def _B_ZERO : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesZero>;
5961  def _H_ZERO : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesZero>;
5962  def _S_ZERO : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesZero>;
5963  def _D_ZERO : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesZero>;
5964
5965  def : SVE_3_Op_Pat_SelZero<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_ZERO)>;
5966  def : SVE_3_Op_Pat_SelZero<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_ZERO)>;
5967  def : SVE_3_Op_Pat_SelZero<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_ZERO)>;
5968  def : SVE_3_Op_Pat_SelZero<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_ZERO)>;
5969}
5970
5971multiclass sve_int_bin_pred_imm_zeroing_bhsd<SDPatternOperator op,
5972                                   ComplexPattern imm_b, ComplexPattern imm_h,
5973                                   ComplexPattern imm_s, ComplexPattern imm_d> {
5974  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8,  Operand<i32>, FalseLanesZero>;
5975  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, Operand<i32>, FalseLanesZero>;
5976  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, Operand<i32>, FalseLanesZero>;
5977  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, Operand<i32>, FalseLanesZero>;
5978
5979  def : SVE_2_Op_Imm_Pat_Zero<nxv16i8, op, nxv16i1, i32, imm_b, !cast<Pseudo>(NAME # _B_ZERO)>;
5980  def : SVE_2_Op_Imm_Pat_Zero<nxv8i16, op, nxv8i1,  i32, imm_h, !cast<Pseudo>(NAME # _H_ZERO)>;
5981  def : SVE_2_Op_Imm_Pat_Zero<nxv4i32, op, nxv4i1,  i32, imm_s, !cast<Pseudo>(NAME # _S_ZERO)>;
5982  def : SVE_2_Op_Imm_Pat_Zero<nxv2i64, op, nxv2i1,  i64, imm_d, !cast<Pseudo>(NAME # _D_ZERO)>;
5983}
5984
5985multiclass sve_int_bin_pred_shift_wide<bits<3> opc, string asm,
5986                                  SDPatternOperator op> {
5987  def _B : sve_int_bin_pred_shift<0b00, 0b1, opc, asm, ZPR8, ZPR64>;
5988  def _H : sve_int_bin_pred_shift<0b01, 0b1, opc, asm, ZPR16, ZPR64>;
5989  def _S : sve_int_bin_pred_shift<0b10, 0b1, opc, asm, ZPR32, ZPR64>;
5990
5991  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
5992  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
5993  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
5994}
5995
5996//===----------------------------------------------------------------------===//
5997// SVE Shift - Unpredicated Group
5998//===----------------------------------------------------------------------===//
5999
6000class sve_int_bin_cons_shift_wide<bits<2> sz8_64, bits<2> opc, string asm,
6001                               ZPRRegOp zprty>
6002: I<(outs zprty:$Zd), (ins zprty:$Zn, ZPR64:$Zm),
6003  asm, "\t$Zd, $Zn, $Zm",
6004  "",
6005  []>, Sched<[]> {
6006  bits<5> Zd;
6007  bits<5> Zm;
6008  bits<5> Zn;
6009  let Inst{31-24} = 0b00000100;
6010  let Inst{23-22} = sz8_64;
6011  let Inst{21}    = 0b1;
6012  let Inst{20-16} = Zm;
6013  let Inst{15-12} = 0b1000;
6014  let Inst{11-10} = opc;
6015  let Inst{9-5}   = Zn;
6016  let Inst{4-0}   = Zd;
6017
6018  let hasSideEffects = 0;
6019}
6020
6021multiclass sve_int_bin_cons_shift_wide<bits<2> opc, string asm, SDPatternOperator op> {
6022  def _B : sve_int_bin_cons_shift_wide<0b00, opc, asm, ZPR8>;
6023  def _H : sve_int_bin_cons_shift_wide<0b01, opc, asm, ZPR16>;
6024  def _S : sve_int_bin_cons_shift_wide<0b10, opc, asm, ZPR32>;
6025
6026  def : SVE_2_Op_Pred_All_Active<nxv16i8, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
6027  def : SVE_2_Op_Pred_All_Active<nxv8i16, op, nxv8i1, nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
6028  def : SVE_2_Op_Pred_All_Active<nxv4i32, op, nxv4i1, nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
6029}
6030
6031class sve_int_bin_cons_shift_imm<bits<4> tsz8_64, bits<2> opc, string asm,
6032                               ZPRRegOp zprty, Operand immtype>
6033: I<(outs zprty:$Zd), (ins zprty:$Zn, immtype:$imm),
6034  asm, "\t$Zd, $Zn, $imm",
6035  "",
6036  []>, Sched<[]> {
6037  bits<5> Zd;
6038  bits<5> Zn;
6039  bits<6> imm;
6040  let Inst{31-24} = 0b00000100;
6041  let Inst{23-22} = tsz8_64{3-2};
6042  let Inst{21}    = 0b1;
6043  let Inst{20-19} = tsz8_64{1-0};
6044  let Inst{18-16} = imm{2-0}; // imm3
6045  let Inst{15-12} = 0b1001;
6046  let Inst{11-10} = opc;
6047  let Inst{9-5}   = Zn;
6048  let Inst{4-0}   = Zd;
6049
6050  let hasSideEffects = 0;
6051}
6052
6053multiclass sve_int_bin_cons_shift_imm_left<bits<2> opc, string asm,
6054                                           SDPatternOperator op> {
6055  def _B : sve_int_bin_cons_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
6056  def _H : sve_int_bin_cons_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
6057    let Inst{19} = imm{3};
6058  }
6059  def _S : sve_int_bin_cons_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
6060    let Inst{20-19} = imm{4-3};
6061  }
6062  def _D : sve_int_bin_cons_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
6063    let Inst{22}    = imm{5};
6064    let Inst{20-19} = imm{4-3};
6065  }
6066
6067  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8,  !cast<Instruction>(NAME # _B)>;
6068  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
6069  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
6070  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
6071}
6072
6073multiclass sve_int_bin_cons_shift_imm_right<bits<2> opc, string asm,
6074                                            SDPatternOperator op> {
6075  def _B : sve_int_bin_cons_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
6076  def _H : sve_int_bin_cons_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
6077    let Inst{19} = imm{3};
6078  }
6079  def _S : sve_int_bin_cons_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
6080    let Inst{20-19} = imm{4-3};
6081  }
6082  def _D : sve_int_bin_cons_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
6083    let Inst{22}    = imm{5};
6084    let Inst{20-19} = imm{4-3};
6085  }
6086
6087  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8,  !cast<Instruction>(NAME # _B)>;
6088  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
6089  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
6090  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
6091}
6092
6093//===----------------------------------------------------------------------===//
6094// SVE Memory - Store Group
6095//===----------------------------------------------------------------------===//
6096
6097class sve_mem_cst_si<bits<2> msz, bits<2> esz, string asm,
6098                     RegisterOperand VecList>
6099: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
6100  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6101  "",
6102  []>, Sched<[]> {
6103  bits<3> Pg;
6104  bits<5> Rn;
6105  bits<5> Zt;
6106  bits<4> imm4;
6107  let Inst{31-25} = 0b1110010;
6108  let Inst{24-23} = msz;
6109  let Inst{22-21} = esz;
6110  let Inst{20}    = 0;
6111  let Inst{19-16} = imm4;
6112  let Inst{15-13} = 0b111;
6113  let Inst{12-10} = Pg;
6114  let Inst{9-5}   = Rn;
6115  let Inst{4-0}   = Zt;
6116
6117  let hasSideEffects = 0;
6118  let mayStore = 1;
6119}
6120
6121multiclass sve_mem_cst_si<bits<2> msz, bits<2> esz, string asm,
6122                          RegisterOperand listty, ZPRRegOp zprty>
6123{
6124  def NAME : sve_mem_cst_si<msz, esz, asm, listty>;
6125
6126  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6127                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
6128  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6129                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
6130  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6131                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6132}
6133
6134class sve_mem_est_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6135                     string asm, Operand immtype>
6136: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
6137  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6138  "",
6139  []>, Sched<[]> {
6140  bits<3> Pg;
6141  bits<5> Rn;
6142  bits<5> Zt;
6143  bits<4> imm4;
6144  let Inst{31-25} = 0b1110010;
6145  let Inst{24-23} = sz;
6146  let Inst{22-21} = nregs;
6147  let Inst{20}    = 1;
6148  let Inst{19-16} = imm4;
6149  let Inst{15-13} = 0b111;
6150  let Inst{12-10} = Pg;
6151  let Inst{9-5}   = Rn;
6152  let Inst{4-0}   = Zt;
6153
6154  let hasSideEffects = 0;
6155  let mayStore = 1;
6156}
6157
6158multiclass sve_mem_est_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6159                          string asm, Operand immtype> {
6160  def NAME : sve_mem_est_si<sz, nregs, VecList, asm, immtype>;
6161
6162  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6163                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6164}
6165
6166
6167// SVE store multiple structures (quadwords, scalar plus immediate)
6168class sve_mem_128b_est_si<bits<2> nregs, RegisterOperand VecList,
6169                          string asm, Operand immtype>
6170    : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
6171        asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6172        "", []>, Sched<[]> {
6173  bits<5> Zt;
6174  bits<5> Rn;
6175  bits<3> Pg;
6176  bits<4> imm4;
6177  let Inst{31-24} = 0b11100100;
6178  let Inst{23-22} = nregs;
6179  let Inst{21-20} = 0b00;
6180  let Inst{19-16} = imm4;
6181  let Inst{15-13} = 0b000;
6182  let Inst{12-10} = Pg;
6183  let Inst{9-5}   = Rn;
6184  let Inst{4-0}   = Zt;
6185
6186  let hasSideEffects = 0;
6187  let mayStore = 1;
6188}
6189
6190multiclass sve_mem_128b_est_si<bits<2> nregs, RegisterOperand VecList,
6191                               string asm, Operand immtype> {
6192  def NAME : sve_mem_128b_est_si<nregs, VecList, asm, immtype>;
6193
6194  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6195                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6196}
6197
6198
6199class sve_mem_est_ss<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6200                     string asm, RegisterOperand gprty>
6201: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6202  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6203  "",
6204  []>, Sched<[]> {
6205  bits<3> Pg;
6206  bits<5> Rm;
6207  bits<5> Rn;
6208  bits<5> Zt;
6209  let Inst{31-25} = 0b1110010;
6210  let Inst{24-23} = sz;
6211  let Inst{22-21} = nregs;
6212  let Inst{20-16} = Rm;
6213  let Inst{15-13} = 0b011;
6214  let Inst{12-10} = Pg;
6215  let Inst{9-5}   = Rn;
6216  let Inst{4-0}   = Zt;
6217
6218  let hasSideEffects = 0;
6219  let mayStore = 1;
6220}
6221
6222
6223// SVE store multiple structures (quadwords, scalar plus scalar)
6224class sve_mem_128b_est_ss<bits<2> nregs, RegisterOperand VecList,
6225                          string asm, RegisterOperand gprty>
6226    : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6227        asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6228        "", []>, Sched<[]> {
6229  bits<5> Zt;
6230  bits<5> Rn;
6231  bits<3> Pg;
6232  bits<5> Rm;
6233  let Inst{31-24} = 0b11100100;
6234  let Inst{23-22} = nregs;
6235  let Inst{21}    = 0b1;
6236  let Inst{20-16} = Rm;
6237  let Inst{15-13} = 0b000;
6238  let Inst{12-10} = Pg;
6239  let Inst{9-5}   = Rn;
6240  let Inst{4-0}   = Zt;
6241
6242  let hasSideEffects = 0;
6243  let mayStore = 1;
6244}
6245
6246
6247class sve_mem_cst_ss_base<bits<4> dtype, string asm,
6248                          RegisterOperand listty, RegisterOperand gprty>
6249: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6250  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6251  "",
6252  []>, Sched<[]> {
6253  bits<3> Pg;
6254  bits<5> Rm;
6255  bits<5> Rn;
6256  bits<5> Zt;
6257  let Inst{31-25} = 0b1110010;
6258  let Inst{24-21} = dtype;
6259  let Inst{20-16} = Rm;
6260  let Inst{15-13} = 0b010;
6261  let Inst{12-10} = Pg;
6262  let Inst{9-5}   = Rn;
6263  let Inst{4-0}   = Zt;
6264
6265  let hasSideEffects = 0;
6266  let mayStore = 1;
6267}
6268
6269multiclass sve_mem_cst_ss<bits<4> dtype, string asm,
6270                          RegisterOperand listty, ZPRRegOp zprty,
6271                          RegisterOperand gprty> {
6272  def NAME : sve_mem_cst_ss_base<dtype, asm, listty, gprty>;
6273
6274  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Rm]",
6275                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
6276}
6277
6278class sve_mem_cstnt_si<bits<2> msz, string asm, RegisterOperand VecList>
6279: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
6280  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6281  "",
6282  []>, Sched<[]> {
6283  bits<3> Pg;
6284  bits<5> Rn;
6285  bits<5> Zt;
6286  bits<4> imm4;
6287  let Inst{31-25} = 0b1110010;
6288  let Inst{24-23} = msz;
6289  let Inst{22-20} = 0b001;
6290  let Inst{19-16} = imm4;
6291  let Inst{15-13} = 0b111;
6292  let Inst{12-10} = Pg;
6293  let Inst{9-5}   = Rn;
6294  let Inst{4-0}   = Zt;
6295
6296  let hasSideEffects = 0;
6297  let mayStore = 1;
6298}
6299
6300multiclass sve_mem_cstnt_si<bits<2> msz, string asm, RegisterOperand listty,
6301                            ZPRRegOp zprty> {
6302  def NAME : sve_mem_cstnt_si<msz, asm, listty>;
6303
6304  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6305                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
6306  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6307                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
6308  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6309                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6310}
6311
6312class sve_mem_cstnt_ss_base<bits<2> msz, string asm, RegisterOperand listty,
6313                            RegisterOperand gprty>
6314: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6315  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6316  "",
6317  []>, Sched<[]> {
6318  bits<3> Pg;
6319  bits<5> Rm;
6320  bits<5> Rn;
6321  bits<5> Zt;
6322  let Inst{31-25} = 0b1110010;
6323  let Inst{24-23} = msz;
6324  let Inst{22-21} = 0b00;
6325  let Inst{20-16} = Rm;
6326  let Inst{15-13} = 0b011;
6327  let Inst{12-10} = Pg;
6328  let Inst{9-5}   = Rn;
6329  let Inst{4-0}   = Zt;
6330
6331  let hasSideEffects = 0;
6332  let mayStore = 1;
6333}
6334
6335multiclass sve_mem_cstnt_ss<bits<2> msz, string asm, RegisterOperand listty,
6336                            ZPRRegOp zprty, RegisterOperand gprty> {
6337  def NAME : sve_mem_cstnt_ss_base<msz, asm, listty, gprty>;
6338
6339  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Rm]",
6340                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
6341}
6342
6343class sve2_mem_sstnt_vs_base<bits<3> opc, string asm,
6344                             RegisterOperand listty, ZPRRegOp zprty>
6345: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, zprty:$Zn, GPR64:$Rm),
6346  asm, "\t$Zt, $Pg, [$Zn, $Rm]",
6347  "",
6348  []>, Sched<[]> {
6349  bits<3> Pg;
6350  bits<5> Rm;
6351  bits<5> Zn;
6352  bits<5> Zt;
6353  let Inst{31-25} = 0b1110010;
6354  let Inst{24-22} = opc;
6355  let Inst{21}    = 0b0;
6356  let Inst{20-16} = Rm;
6357  let Inst{15-13} = 0b001;
6358  let Inst{12-10} = Pg;
6359  let Inst{9-5}   = Zn;
6360  let Inst{4-0}   = Zt;
6361
6362  let hasSideEffects = 0;
6363  let mayStore = 1;
6364}
6365
6366multiclass sve2_mem_sstnt_vs_32_ptrs<bits<3> opc, string asm,
6367                             SDPatternOperator op,
6368                             ValueType vt> {
6369  def _REAL : sve2_mem_sstnt_vs_base<opc, asm, Z_s, ZPR32>;
6370
6371  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $Rm]",
6372                 (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm), 0>;
6373  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6374                 (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 0>;
6375  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6376                 (!cast<Instruction>(NAME # _REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 1>;
6377
6378  def : Pat <(op (nxv4i32 ZPR32:$Zt), (nxv4i1 PPR3bAny:$Pg), (nxv4i32 ZPR32:$Zn), (i64 GPR64:$Rm), vt),
6379             (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm)>;
6380}
6381
6382multiclass sve2_mem_sstnt_vs_64_ptrs<bits<3> opc, string asm,
6383                             SDPatternOperator op,
6384                             ValueType vt> {
6385  def _REAL : sve2_mem_sstnt_vs_base<opc, asm, Z_d, ZPR64>;
6386
6387  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $Rm]",
6388                 (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm), 0>;
6389  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6390                 (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 0>;
6391  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6392                 (!cast<Instruction>(NAME # _REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
6393
6394  def : Pat <(op (nxv2i64 ZPR64:$Zt), (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64:$Rm), vt),
6395             (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
6396}
6397
6398class sve_mem_sst_sv<bits<3> opc, bit xs, bit scaled, string asm,
6399                     RegisterOperand VecList, RegisterOperand zprext>
6400: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
6401  asm, "\t$Zt, $Pg, [$Rn, $Zm]",
6402  "",
6403  []>, Sched<[]> {
6404  bits<3> Pg;
6405  bits<5> Rn;
6406  bits<5> Zm;
6407  bits<5> Zt;
6408  let Inst{31-25} = 0b1110010;
6409  let Inst{24-22} = opc;
6410  let Inst{21}    = scaled;
6411  let Inst{20-16} = Zm;
6412  let Inst{15}    = 0b1;
6413  let Inst{14}    = xs;
6414  let Inst{13}    = 0;
6415  let Inst{12-10} = Pg;
6416  let Inst{9-5}   = Rn;
6417  let Inst{4-0}   = Zt;
6418
6419  let hasSideEffects = 0;
6420  let mayStore = 1;
6421}
6422
6423multiclass sve_mem_32b_sst_sv_32_scaled<bits<3> opc, string asm,
6424                                    SDPatternOperator sxtw_op,
6425                                    SDPatternOperator uxtw_op,
6426                                    RegisterOperand sxtw_opnd,
6427                                    RegisterOperand uxtw_opnd,
6428                                    ValueType vt > {
6429  def _UXTW_SCALED : sve_mem_sst_sv<opc, 0, 1, asm, Z_s, uxtw_opnd>;
6430  def _SXTW_SCALED : sve_mem_sst_sv<opc, 1, 1, asm, Z_s, sxtw_opnd>;
6431
6432  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6433                 (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6434  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6435                 (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6436
6437  def : Pat<(uxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6438            (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6439  def : Pat<(sxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6440            (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6441}
6442
6443multiclass sve_mem_64b_sst_sv_32_scaled<bits<3> opc, string asm,
6444                                    SDPatternOperator sxtw_op,
6445                                    SDPatternOperator uxtw_op,
6446                                    RegisterOperand sxtw_opnd,
6447                                    RegisterOperand uxtw_opnd,
6448                                    ValueType vt > {
6449  def _UXTW_SCALED : sve_mem_sst_sv<opc, 0, 1, asm, Z_d, uxtw_opnd>;
6450  def _SXTW_SCALED : sve_mem_sst_sv<opc, 1, 1, asm, Z_d, sxtw_opnd>;
6451
6452  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6453                 (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6454  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6455                 (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6456
6457  def : Pat<(uxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6458            (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6459  def : Pat<(sxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6460            (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6461}
6462
6463multiclass sve_mem_64b_sst_sv_32_unscaled<bits<3> opc, string asm,
6464                                         SDPatternOperator sxtw_op,
6465                                         SDPatternOperator uxtw_op,
6466                                         RegisterOperand sxtw_opnd,
6467                                         RegisterOperand uxtw_opnd,
6468                                         ValueType vt> {
6469  def _UXTW : sve_mem_sst_sv<opc, 0, 0, asm, Z_d, uxtw_opnd>;
6470  def _SXTW : sve_mem_sst_sv<opc, 1, 0, asm, Z_d, sxtw_opnd>;
6471
6472  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6473                 (!cast<Instruction>(NAME # _UXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6474  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6475                 (!cast<Instruction>(NAME # _SXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6476
6477  def : Pat<(uxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6478            (!cast<Instruction>(NAME # _UXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6479  def : Pat<(sxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6480            (!cast<Instruction>(NAME # _SXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6481}
6482
6483multiclass sve_mem_32b_sst_sv_32_unscaled<bits<3> opc, string asm,
6484                                          SDPatternOperator sxtw_op,
6485                                          SDPatternOperator uxtw_op,
6486                                          RegisterOperand sxtw_opnd,
6487                                          RegisterOperand uxtw_opnd,
6488                                          ValueType vt> {
6489  def _UXTW : sve_mem_sst_sv<opc, 0, 0, asm, Z_s, uxtw_opnd>;
6490  def _SXTW : sve_mem_sst_sv<opc, 1, 0, asm, Z_s, sxtw_opnd>;
6491
6492  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6493                 (!cast<Instruction>(NAME # _UXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6494  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6495                 (!cast<Instruction>(NAME # _SXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6496
6497  def : Pat<(uxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6498            (!cast<Instruction>(NAME # _UXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6499  def : Pat<(sxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6500            (!cast<Instruction>(NAME # _SXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6501}
6502
6503class sve_mem_sst_sv2<bits<2> msz, bit scaled, string asm,
6504                      RegisterOperand zprext>
6505: I<(outs), (ins Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
6506  asm, "\t$Zt, $Pg, [$Rn, $Zm]",
6507  "",
6508  []>, Sched<[]> {
6509  bits<3> Pg;
6510  bits<5> Rn;
6511  bits<5> Zm;
6512  bits<5> Zt;
6513  let Inst{31-25} = 0b1110010;
6514  let Inst{24-23} = msz;
6515  let Inst{22}    = 0b0;
6516  let Inst{21}    = scaled;
6517  let Inst{20-16} = Zm;
6518  let Inst{15-13} = 0b101;
6519  let Inst{12-10} = Pg;
6520  let Inst{9-5}   = Rn;
6521  let Inst{4-0}   = Zt;
6522
6523  let hasSideEffects = 0;
6524  let mayStore = 1;
6525}
6526
6527multiclass sve_mem_sst_sv_64_scaled<bits<2> msz, string asm,
6528                                    SDPatternOperator op,
6529                                    RegisterOperand zprext,
6530                                    ValueType vt> {
6531  def _SCALED : sve_mem_sst_sv2<msz, 1, asm, zprext>;
6532
6533  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6534                 (!cast<Instruction>(NAME # _SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), 0>;
6535
6536  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt),
6537            (!cast<Instruction>(NAME # _SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
6538}
6539
6540multiclass sve_mem_sst_sv_64_unscaled<bits<2> msz, string asm,
6541                                      SDPatternOperator op,
6542                                      ValueType vt> {
6543  def NAME : sve_mem_sst_sv2<msz, 0, asm, ZPR64ExtLSL8>;
6544
6545  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6546                 (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), 0>;
6547
6548  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6549            (!cast<Instruction>(NAME) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6550}
6551
6552class sve_mem_sst_vi<bits<3> opc, string asm, ZPRRegOp zprty,
6553                     RegisterOperand VecList, Operand imm_ty>
6554: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, zprty:$Zn, imm_ty:$imm5),
6555  asm, "\t$Zt, $Pg, [$Zn, $imm5]",
6556  "",
6557  []>, Sched<[]> {
6558  bits<3> Pg;
6559  bits<5> imm5;
6560  bits<5> Zn;
6561  bits<5> Zt;
6562  let Inst{31-25} = 0b1110010;
6563  let Inst{24-23} = opc{2-1};
6564  let Inst{22}    = 0b1;
6565  let Inst{21}    = opc{0};
6566  let Inst{20-16} = imm5;
6567  let Inst{15-13} = 0b101;
6568  let Inst{12-10} = Pg;
6569  let Inst{9-5}   = Zn;
6570  let Inst{4-0}   = Zt;
6571
6572  let hasSideEffects = 0;
6573  let mayStore = 1;
6574}
6575
6576multiclass sve_mem_32b_sst_vi_ptrs<bits<3> opc, string asm,
6577                                   Operand imm_ty,
6578                                   SDPatternOperator op,
6579                                   ValueType vt> {
6580  def _IMM : sve_mem_sst_vi<opc, asm, ZPR32, Z_s, imm_ty>;
6581
6582  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6583                  (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 0>;
6584  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $imm5]",
6585                  (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), 0>;
6586  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6587                  (!cast<Instruction>(NAME # _IMM) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
6588
6589  def : Pat<(op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), (nxv4i32 ZPR:$ptrs), imm_ty:$index, vt),
6590            (!cast<Instruction>(NAME # _IMM) ZPR:$data, PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
6591}
6592
6593multiclass sve_mem_64b_sst_vi_ptrs<bits<3> opc, string asm,
6594                                   Operand imm_ty,
6595                                   SDPatternOperator op,
6596                                   ValueType vt> {
6597  def _IMM : sve_mem_sst_vi<opc, asm, ZPR64, Z_d, imm_ty>;
6598
6599  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6600                  (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 0>;
6601  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $imm5]",
6602                  (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), 0>;
6603  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6604                  (!cast<Instruction>(NAME # _IMM) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
6605
6606  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), (nxv2i64 ZPR:$ptrs), imm_ty:$index, vt),
6607            (!cast<Instruction>(NAME # _IMM) ZPR:$data, PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
6608}
6609
6610class sve_mem_z_spill<string asm>
6611: I<(outs), (ins ZPRAny:$Zt, GPR64sp:$Rn, simm9:$imm9),
6612  asm, "\t$Zt, [$Rn, $imm9, mul vl]",
6613  "",
6614  []>, Sched<[]> {
6615  bits<5> Rn;
6616  bits<5> Zt;
6617  bits<9> imm9;
6618  let Inst{31-22} = 0b1110010110;
6619  let Inst{21-16} = imm9{8-3};
6620  let Inst{15-13} = 0b010;
6621  let Inst{12-10} = imm9{2-0};
6622  let Inst{9-5}   = Rn;
6623  let Inst{4-0}   = Zt;
6624
6625  let hasSideEffects = 0;
6626  let mayStore = 1;
6627}
6628
6629multiclass sve_mem_z_spill<string asm> {
6630  def NAME : sve_mem_z_spill<asm>;
6631
6632  def : InstAlias<asm # "\t$Zt, [$Rn]",
6633                  (!cast<Instruction>(NAME) ZPRAny:$Zt, GPR64sp:$Rn, 0), 1>;
6634}
6635
6636class sve_mem_p_spill<string asm>
6637: I<(outs), (ins PPRAny:$Pt, GPR64sp:$Rn, simm9:$imm9),
6638  asm, "\t$Pt, [$Rn, $imm9, mul vl]",
6639  "",
6640  []>, Sched<[]> {
6641  bits<4> Pt;
6642  bits<5> Rn;
6643  bits<9> imm9;
6644  let Inst{31-22} = 0b1110010110;
6645  let Inst{21-16} = imm9{8-3};
6646  let Inst{15-13} = 0b000;
6647  let Inst{12-10} = imm9{2-0};
6648  let Inst{9-5}   = Rn;
6649  let Inst{4}     = 0b0;
6650  let Inst{3-0}   = Pt;
6651
6652  let hasSideEffects = 0;
6653  let mayStore = 1;
6654}
6655
6656multiclass sve_mem_p_spill<string asm> {
6657  def NAME : sve_mem_p_spill<asm>;
6658
6659  def : InstAlias<asm # "\t$Pt, [$Rn]",
6660                  (!cast<Instruction>(NAME) PPRAny:$Pt, GPR64sp:$Rn, 0), 1>;
6661}
6662
6663//===----------------------------------------------------------------------===//
6664// SVE Permute - Predicates Group
6665//===----------------------------------------------------------------------===//
6666
6667class sve_int_perm_bin_perm_pp<bits<3> opc, bits<2> sz8_64, string asm,
6668                               PPRRegOp pprty, SDPatternOperator op>
6669: I<(outs pprty:$Pd), (ins pprty:$Pn, pprty:$Pm),
6670  asm, "\t$Pd, $Pn, $Pm",
6671  "",
6672  [(set nxv16i1:$Pd, (op nxv16i1:$Pn, nxv16i1:$Pm))]>, Sched<[]> {
6673  bits<4> Pd;
6674  bits<4> Pm;
6675  bits<4> Pn;
6676  let Inst{31-24} = 0b00000101;
6677  let Inst{23-22} = sz8_64;
6678  let Inst{21-20} = 0b10;
6679  let Inst{19-16} = Pm;
6680  let Inst{15-13} = 0b010;
6681  let Inst{12-10} = opc;
6682  let Inst{9}     = 0b0;
6683  let Inst{8-5}   = Pn;
6684  let Inst{4}     = 0b0;
6685  let Inst{3-0}   = Pd;
6686
6687  let hasSideEffects = 0;
6688}
6689
6690multiclass sve_int_perm_bin_perm_pp<bits<3> opc, string asm,
6691                                    SDPatternOperator ir_op,
6692                                    SDPatternOperator op_b16,
6693                                    SDPatternOperator op_b32,
6694                                    SDPatternOperator op_b64> {
6695  def _B : sve_int_perm_bin_perm_pp<opc, 0b00, asm, PPR8,  ir_op>;
6696  def _H : sve_int_perm_bin_perm_pp<opc, 0b01, asm, PPR16, op_b16>;
6697  def _S : sve_int_perm_bin_perm_pp<opc, 0b10, asm, PPR32, op_b32>;
6698  def _D : sve_int_perm_bin_perm_pp<opc, 0b11, asm, PPR64, op_b64>;
6699
6700  def : SVE_2_Op_Pat<nxv8i1, ir_op, nxv8i1, nxv8i1, !cast<Instruction>(NAME # _H)>;
6701  def : SVE_2_Op_Pat<nxv4i1, ir_op, nxv4i1, nxv4i1, !cast<Instruction>(NAME # _S)>;
6702  def : SVE_2_Op_Pat<nxv2i1, ir_op, nxv2i1, nxv2i1, !cast<Instruction>(NAME # _D)>;
6703}
6704
6705class sve_int_perm_punpk<bit opc, string asm>
6706: I<(outs PPR16:$Pd), (ins PPR8:$Pn),
6707  asm, "\t$Pd, $Pn",
6708  "",
6709  []>, Sched<[]> {
6710  bits<4> Pd;
6711  bits<4> Pn;
6712  let Inst{31-17} = 0b000001010011000;
6713  let Inst{16}    = opc;
6714  let Inst{15-9}  = 0b0100000;
6715  let Inst{8-5}   = Pn;
6716  let Inst{4}     = 0b0;
6717  let Inst{3-0}   = Pd;
6718
6719  let hasSideEffects = 0;
6720}
6721
6722multiclass sve_int_perm_punpk<bit opc, string asm, SDPatternOperator op> {
6723  def NAME : sve_int_perm_punpk<opc, asm>;
6724
6725  def : SVE_1_Op_Pat<nxv8i1, op, nxv16i1, !cast<Instruction>(NAME)>;
6726  def : SVE_1_Op_Pat<nxv4i1, op, nxv8i1,  !cast<Instruction>(NAME)>;
6727  def : SVE_1_Op_Pat<nxv2i1, op, nxv4i1,  !cast<Instruction>(NAME)>;
6728}
6729
6730class sve_int_rdffr_pred<bit s, string asm>
6731: I<(outs PPR8:$Pd), (ins PPRAny:$Pg),
6732  asm, "\t$Pd, $Pg/z",
6733  "",
6734  []>, Sched<[]> {
6735  bits<4> Pd;
6736  bits<4> Pg;
6737  let Inst{31-23} = 0b001001010;
6738  let Inst{22}    = s;
6739  let Inst{21-9}  = 0b0110001111000;
6740  let Inst{8-5}   = Pg;
6741  let Inst{4}     = 0;
6742  let Inst{3-0}   = Pd;
6743
6744  let Defs = !if(s, [NZCV], []);
6745  let Uses = [FFR];
6746  let hasSideEffects = 1;
6747}
6748
6749multiclass sve_int_rdffr_pred<bit s, string asm, SDPatternOperator op> {
6750  def _REAL : sve_int_rdffr_pred<s, asm>;
6751
6752  // We need a layer of indirection because early machine code passes balk at
6753  // physical register (i.e. FFR) uses that have no previous definition.
6754  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
6755  def "" : Pseudo<(outs PPR8:$Pd), (ins PPRAny:$Pg), [(set (nxv16i1 PPR8:$Pd), (op (nxv16i1 PPRAny:$Pg)))]>,
6756           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) PPR8:$Pd, PPRAny:$Pg)>;
6757  }
6758}
6759
6760class sve_int_rdffr_unpred<string asm> : I<
6761  (outs PPR8:$Pd), (ins),
6762  asm, "\t$Pd",
6763  "",
6764  []>, Sched<[]> {
6765  bits<4> Pd;
6766  let Inst{31-4} = 0b0010010100011001111100000000;
6767  let Inst{3-0}   = Pd;
6768
6769  let Uses = [FFR];
6770  let hasSideEffects = 1;
6771}
6772
6773multiclass sve_int_rdffr_unpred<string asm, SDPatternOperator op> {
6774  def _REAL : sve_int_rdffr_unpred<asm>;
6775
6776  // We need a layer of indirection because early machine code passes balk at
6777  // physical register (i.e. FFR) uses that have no previous definition.
6778  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
6779  def "" : Pseudo<(outs PPR8:$Pd), (ins), [(set (nxv16i1 PPR8:$Pd), (op))]>,
6780           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) PPR8:$Pd)>;
6781  }
6782}
6783
6784class sve_int_wrffr<string asm, SDPatternOperator op>
6785: I<(outs), (ins PPR8:$Pn),
6786  asm, "\t$Pn",
6787  "",
6788  [(op (nxv16i1 PPR8:$Pn))]>, Sched<[]> {
6789  bits<4> Pn;
6790  let Inst{31-9} = 0b00100101001010001001000;
6791  let Inst{8-5}  = Pn;
6792  let Inst{4-0}  = 0b00000;
6793
6794  let Defs = [FFR];
6795  let hasSideEffects = 1;
6796}
6797
6798class sve_int_setffr<string asm, SDPatternOperator op>
6799: I<(outs), (ins),
6800  asm, "",
6801  "",
6802  [(op)]>, Sched<[]> {
6803  let Inst{31-0} = 0b00100101001011001001000000000000;
6804
6805  let Defs = [FFR];
6806  let hasSideEffects = 1;
6807}
6808
6809//===----------------------------------------------------------------------===//
6810// SVE Permute Vector - Predicated Group
6811//===----------------------------------------------------------------------===//
6812
6813class sve_int_perm_clast_rz<bits<2> sz8_64, bit ab, string asm,
6814                            ZPRRegOp zprty, RegisterClass rt>
6815: I<(outs rt:$Rdn), (ins PPR3bAny:$Pg, rt:$_Rdn, zprty:$Zm),
6816  asm, "\t$Rdn, $Pg, $_Rdn, $Zm",
6817  "",
6818  []>, Sched<[]> {
6819  bits<3> Pg;
6820  bits<5> Rdn;
6821  bits<5> Zm;
6822  let Inst{31-24} = 0b00000101;
6823  let Inst{23-22} = sz8_64;
6824  let Inst{21-17} = 0b11000;
6825  let Inst{16}    = ab;
6826  let Inst{15-13} = 0b101;
6827  let Inst{12-10} = Pg;
6828  let Inst{9-5}   = Zm;
6829  let Inst{4-0}   = Rdn;
6830
6831  let Constraints = "$Rdn = $_Rdn";
6832  let hasSideEffects = 0;
6833}
6834
6835multiclass sve_int_perm_clast_rz<bit ab, string asm, SDPatternOperator op> {
6836  def _B : sve_int_perm_clast_rz<0b00, ab, asm, ZPR8, GPR32>;
6837  def _H : sve_int_perm_clast_rz<0b01, ab, asm, ZPR16, GPR32>;
6838  def _S : sve_int_perm_clast_rz<0b10, ab, asm, ZPR32, GPR32>;
6839  def _D : sve_int_perm_clast_rz<0b11, ab, asm, ZPR64, GPR64>;
6840
6841  def : SVE_3_Op_Pat<i32, op, nxv16i1, i32, nxv16i8, !cast<Instruction>(NAME # _B)>;
6842  def : SVE_3_Op_Pat<i32, op, nxv8i1,  i32, nxv8i16, !cast<Instruction>(NAME # _H)>;
6843  def : SVE_3_Op_Pat<i32, op, nxv4i1,  i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
6844  def : SVE_3_Op_Pat<i64, op, nxv2i1,  i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
6845}
6846
6847class sve_int_perm_clast_vz<bits<2> sz8_64, bit ab, string asm,
6848                            ZPRRegOp zprty, RegisterClass rt>
6849: I<(outs rt:$Vdn), (ins PPR3bAny:$Pg, rt:$_Vdn, zprty:$Zm),
6850  asm, "\t$Vdn, $Pg, $_Vdn, $Zm",
6851  "",
6852  []>, Sched<[]> {
6853  bits<3> Pg;
6854  bits<5> Vdn;
6855  bits<5> Zm;
6856  let Inst{31-24} = 0b00000101;
6857  let Inst{23-22} = sz8_64;
6858  let Inst{21-17} = 0b10101;
6859  let Inst{16}    = ab;
6860  let Inst{15-13} = 0b100;
6861  let Inst{12-10} = Pg;
6862  let Inst{9-5}   = Zm;
6863  let Inst{4-0}   = Vdn;
6864
6865  let Constraints = "$Vdn = $_Vdn";
6866  let hasSideEffects = 0;
6867}
6868
6869multiclass sve_int_perm_clast_vz<bit ab, string asm, SDPatternOperator op> {
6870  def _B : sve_int_perm_clast_vz<0b00, ab, asm, ZPR8, FPR8>;
6871  def _H : sve_int_perm_clast_vz<0b01, ab, asm, ZPR16, FPR16>;
6872  def _S : sve_int_perm_clast_vz<0b10, ab, asm, ZPR32, FPR32>;
6873  def _D : sve_int_perm_clast_vz<0b11, ab, asm, ZPR64, FPR64>;
6874
6875  def : SVE_3_Op_Pat<f16, op, nxv8i1, f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
6876  def : SVE_3_Op_Pat<f32, op, nxv4i1, f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
6877  def : SVE_3_Op_Pat<f64, op, nxv2i1, f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
6878
6879  def : SVE_3_Op_Pat<bf16, op, nxv8i1, bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
6880}
6881
6882class sve_int_perm_clast_zz<bits<2> sz8_64, bit ab, string asm,
6883                            ZPRRegOp zprty>
6884: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
6885  asm, "\t$Zdn, $Pg, $_Zdn, $Zm",
6886  "",
6887  []>, Sched<[]> {
6888  bits<3> Pg;
6889  bits<5> Zdn;
6890  bits<5> Zm;
6891  let Inst{31-24} = 0b00000101;
6892  let Inst{23-22} = sz8_64;
6893  let Inst{21-17} = 0b10100;
6894  let Inst{16}    = ab;
6895  let Inst{15-13} = 0b100;
6896  let Inst{12-10} = Pg;
6897  let Inst{9-5}   = Zm;
6898  let Inst{4-0}   = Zdn;
6899
6900  let Constraints = "$Zdn = $_Zdn";
6901  let DestructiveInstType = DestructiveOther;
6902  let ElementSize = ElementSizeNone;
6903  let hasSideEffects = 0;
6904}
6905
6906multiclass sve_int_perm_clast_zz<bit ab, string asm, SDPatternOperator op> {
6907  def _B : sve_int_perm_clast_zz<0b00, ab, asm, ZPR8>;
6908  def _H : sve_int_perm_clast_zz<0b01, ab, asm, ZPR16>;
6909  def _S : sve_int_perm_clast_zz<0b10, ab, asm, ZPR32>;
6910  def _D : sve_int_perm_clast_zz<0b11, ab, asm, ZPR64>;
6911
6912  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
6913  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
6914  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
6915  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
6916
6917  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
6918  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
6919  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
6920
6921  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
6922}
6923
6924class sve_int_perm_last_r<bits<2> sz8_64, bit ab, string asm,
6925                          ZPRRegOp zprty, RegisterClass resultRegType>
6926: I<(outs resultRegType:$Rd), (ins PPR3bAny:$Pg, zprty:$Zn),
6927  asm, "\t$Rd, $Pg, $Zn",
6928  "",
6929  []>, Sched<[]> {
6930  bits<3> Pg;
6931  bits<5> Rd;
6932  bits<5> Zn;
6933  let Inst{31-24} = 0b00000101;
6934  let Inst{23-22} = sz8_64;
6935  let Inst{21-17} = 0b10000;
6936  let Inst{16}    = ab;
6937  let Inst{15-13} = 0b101;
6938  let Inst{12-10} = Pg;
6939  let Inst{9-5}   = Zn;
6940  let Inst{4-0}   = Rd;
6941
6942  let hasSideEffects = 0;
6943}
6944
6945multiclass sve_int_perm_last_r<bit ab, string asm, SDPatternOperator op> {
6946  def _B : sve_int_perm_last_r<0b00, ab, asm, ZPR8, GPR32>;
6947  def _H : sve_int_perm_last_r<0b01, ab, asm, ZPR16, GPR32>;
6948  def _S : sve_int_perm_last_r<0b10, ab, asm, ZPR32, GPR32>;
6949  def _D : sve_int_perm_last_r<0b11, ab, asm, ZPR64, GPR64>;
6950
6951  def : SVE_2_Op_Pat<i32, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
6952  def : SVE_2_Op_Pat<i32, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
6953  def : SVE_2_Op_Pat<i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
6954  def : SVE_2_Op_Pat<i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
6955}
6956
6957class sve_int_perm_last_v<bits<2> sz8_64, bit ab, string asm,
6958                          ZPRRegOp zprty, RegisterClass dstRegtype>
6959: I<(outs dstRegtype:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
6960  asm, "\t$Vd, $Pg, $Zn",
6961  "",
6962  []>, Sched<[]> {
6963  bits<3> Pg;
6964  bits<5> Vd;
6965  bits<5> Zn;
6966  let Inst{31-24} = 0b00000101;
6967  let Inst{23-22} = sz8_64;
6968  let Inst{21-17} = 0b10001;
6969  let Inst{16}    = ab;
6970  let Inst{15-13} = 0b100;
6971  let Inst{12-10} = Pg;
6972  let Inst{9-5}   = Zn;
6973  let Inst{4-0}   = Vd;
6974
6975  let hasSideEffects = 0;
6976}
6977
6978multiclass sve_int_perm_last_v<bit ab, string asm, SDPatternOperator op> {
6979  def _B : sve_int_perm_last_v<0b00, ab, asm, ZPR8, FPR8>;
6980  def _H : sve_int_perm_last_v<0b01, ab, asm, ZPR16, FPR16>;
6981  def _S : sve_int_perm_last_v<0b10, ab, asm, ZPR32, FPR32>;
6982  def _D : sve_int_perm_last_v<0b11, ab, asm, ZPR64, FPR64>;
6983
6984  def : SVE_2_Op_Pat<f16, op, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
6985  def : SVE_2_Op_Pat<f32, op, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
6986  def : SVE_2_Op_Pat<f32, op, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
6987  def : SVE_2_Op_Pat<f64, op, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
6988
6989  def : SVE_2_Op_Pat<bf16, op, nxv8i1,  nxv8bf16, !cast<Instruction>(NAME # _H)>;
6990}
6991
6992class sve_int_perm_splice<bits<2> sz8_64, string asm, ZPRRegOp zprty>
6993: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
6994  asm, "\t$Zdn, $Pg, $_Zdn, $Zm",
6995  "",
6996  []>, Sched<[]> {
6997  bits<3> Pg;
6998  bits<5> Zdn;
6999  bits<5> Zm;
7000  let Inst{31-24} = 0b00000101;
7001  let Inst{23-22} = sz8_64;
7002  let Inst{21-13} = 0b101100100;
7003  let Inst{12-10} = Pg;
7004  let Inst{9-5}   = Zm;
7005  let Inst{4-0}   = Zdn;
7006
7007  let Constraints = "$Zdn = $_Zdn";
7008  let DestructiveInstType = DestructiveOther;
7009  let ElementSize = ElementSizeNone;
7010  let hasSideEffects = 0;
7011}
7012
7013multiclass sve_int_perm_splice<string asm, SDPatternOperator op> {
7014  def _B : sve_int_perm_splice<0b00, asm, ZPR8>;
7015  def _H : sve_int_perm_splice<0b01, asm, ZPR16>;
7016  def _S : sve_int_perm_splice<0b10, asm, ZPR32>;
7017  def _D : sve_int_perm_splice<0b11, asm, ZPR64>;
7018
7019  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
7020  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
7021  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
7022  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
7023
7024  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1,  nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
7025  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1,  nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
7026  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1,  nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
7027
7028  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
7029}
7030
7031class sve2_int_perm_splice_cons<bits<2> sz8_64, string asm,
7032                               ZPRRegOp zprty, RegisterOperand VecList>
7033: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, VecList:$Zn),
7034  asm, "\t$Zd, $Pg, $Zn",
7035  "",
7036  []>, Sched<[]> {
7037  bits<3> Pg;
7038  bits<5> Zn;
7039  bits<5> Zd;
7040  let Inst{31-24} = 0b00000101;
7041  let Inst{23-22} = sz8_64;
7042  let Inst{21-13} = 0b101101100;
7043  let Inst{12-10} = Pg;
7044  let Inst{9-5}   = Zn;
7045  let Inst{4-0}   = Zd;
7046
7047  let hasSideEffects = 0;
7048}
7049
7050multiclass sve2_int_perm_splice_cons<string asm> {
7051  def _B : sve2_int_perm_splice_cons<0b00, asm, ZPR8,  ZZ_b>;
7052  def _H : sve2_int_perm_splice_cons<0b01, asm, ZPR16, ZZ_h>;
7053  def _S : sve2_int_perm_splice_cons<0b10, asm, ZPR32, ZZ_s>;
7054  def _D : sve2_int_perm_splice_cons<0b11, asm, ZPR64, ZZ_d>;
7055}
7056
7057class sve_int_perm_rev<bits<2> sz8_64, bits<2> opc, string asm,
7058                       ZPRRegOp zprty>
7059: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
7060  asm, "\t$Zd, $Pg/m, $Zn",
7061  "",
7062  []>, Sched<[]> {
7063  bits<5> Zd;
7064  bits<3> Pg;
7065  bits<5> Zn;
7066  let Inst{31-24} = 0b00000101;
7067  let Inst{23-22} = sz8_64;
7068  let Inst{21-18} = 0b1001;
7069  let Inst{17-16} = opc;
7070  let Inst{15-13} = 0b100;
7071  let Inst{12-10} = Pg;
7072  let Inst{9-5}   = Zn;
7073  let Inst{4-0}   = Zd;
7074
7075  let Constraints = "$Zd = $_Zd";
7076  let DestructiveInstType = DestructiveOther;
7077  let ElementSize = zprty.ElementSize;
7078  let hasSideEffects = 0;
7079}
7080
7081multiclass sve_int_perm_rev_rbit<string asm, SDPatternOperator op> {
7082  def _B : sve_int_perm_rev<0b00, 0b11, asm, ZPR8>;
7083  def _H : sve_int_perm_rev<0b01, 0b11, asm, ZPR16>;
7084  def _S : sve_int_perm_rev<0b10, 0b11, asm, ZPR32>;
7085  def _D : sve_int_perm_rev<0b11, 0b11, asm, ZPR64>;
7086
7087  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
7088  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
7089  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7090  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7091}
7092
7093multiclass sve_int_perm_rev_revb<string asm, SDPatternOperator op> {
7094  def _H : sve_int_perm_rev<0b01, 0b00, asm, ZPR16>;
7095  def _S : sve_int_perm_rev<0b10, 0b00, asm, ZPR32>;
7096  def _D : sve_int_perm_rev<0b11, 0b00, asm, ZPR64>;
7097
7098  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
7099  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7100  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7101}
7102
7103multiclass sve_int_perm_rev_revh<string asm, SDPatternOperator op> {
7104  def _S : sve_int_perm_rev<0b10, 0b01, asm, ZPR32>;
7105  def _D : sve_int_perm_rev<0b11, 0b01, asm, ZPR64>;
7106
7107  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7108  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7109}
7110
7111multiclass sve_int_perm_rev_revw<string asm, SDPatternOperator op> {
7112  def _D : sve_int_perm_rev<0b11, 0b10, asm, ZPR64>;
7113
7114  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7115}
7116
7117class sve_int_perm_cpy_r<bits<2> sz8_64, string asm, ZPRRegOp zprty,
7118                         RegisterClass srcRegType>
7119: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegType:$Rn),
7120  asm, "\t$Zd, $Pg/m, $Rn",
7121  "",
7122  []>, Sched<[]> {
7123  bits<3> Pg;
7124  bits<5> Rn;
7125  bits<5> Zd;
7126  let Inst{31-24} = 0b00000101;
7127  let Inst{23-22} = sz8_64;
7128  let Inst{21-13} = 0b101000101;
7129  let Inst{12-10} = Pg;
7130  let Inst{9-5}   = Rn;
7131  let Inst{4-0}   = Zd;
7132
7133  let Constraints = "$Zd = $_Zd";
7134  let DestructiveInstType = DestructiveOther;
7135  let ElementSize = zprty.ElementSize;
7136  let hasSideEffects = 0;
7137}
7138
7139multiclass sve_int_perm_cpy_r<string asm, SDPatternOperator op> {
7140  def _B : sve_int_perm_cpy_r<0b00, asm, ZPR8, GPR32sp>;
7141  def _H : sve_int_perm_cpy_r<0b01, asm, ZPR16, GPR32sp>;
7142  def _S : sve_int_perm_cpy_r<0b10, asm, ZPR32, GPR32sp>;
7143  def _D : sve_int_perm_cpy_r<0b11, asm, ZPR64, GPR64sp>;
7144
7145  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7146                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7147  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7148                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7149  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7150                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7151  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7152                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPR3bAny:$Pg, GPR64sp:$Rn), 1>;
7153
7154  def : Pat<(nxv16i8 (op nxv16i1:$pg, i32:$splat, nxv16i8:$passthru)),
7155            (!cast<Instruction>(NAME # _B) $passthru, $pg, $splat)>;
7156  def : Pat<(nxv8i16 (op nxv8i1:$pg, i32:$splat, nxv8i16:$passthru)),
7157            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7158  def : Pat<(nxv4i32 (op nxv4i1:$pg, i32:$splat, nxv4i32:$passthru)),
7159            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7160  def : Pat<(nxv2i64 (op nxv2i1:$pg, i64:$splat, nxv2i64:$passthru)),
7161            (!cast<Instruction>(NAME # _D) $passthru, $pg, $splat)>;
7162}
7163
7164class sve_int_perm_cpy_v<bits<2> sz8_64, string asm, ZPRRegOp zprty,
7165                         RegisterClass srcRegtype>
7166: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegtype:$Vn),
7167  asm, "\t$Zd, $Pg/m, $Vn",
7168  "",
7169  []>, Sched<[]> {
7170  bits<3> Pg;
7171  bits<5> Vn;
7172  bits<5> Zd;
7173  let Inst{31-24} = 0b00000101;
7174  let Inst{23-22} = sz8_64;
7175  let Inst{21-13} = 0b100000100;
7176  let Inst{12-10} = Pg;
7177  let Inst{9-5}   = Vn;
7178  let Inst{4-0}   = Zd;
7179
7180  let Constraints = "$Zd = $_Zd";
7181  let DestructiveInstType = DestructiveOther;
7182  let ElementSize = zprty.ElementSize;
7183  let hasSideEffects = 0;
7184}
7185
7186multiclass sve_int_perm_cpy_v<string asm, SDPatternOperator op> {
7187  def _B : sve_int_perm_cpy_v<0b00, asm, ZPR8, FPR8>;
7188  def _H : sve_int_perm_cpy_v<0b01, asm, ZPR16, FPR16>;
7189  def _S : sve_int_perm_cpy_v<0b10, asm, ZPR32, FPR32>;
7190  def _D : sve_int_perm_cpy_v<0b11, asm, ZPR64, FPR64>;
7191
7192  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7193                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPR3bAny:$Pg, FPR8:$Vn), 1>;
7194  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7195                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPR3bAny:$Pg, FPR16:$Vn), 1>;
7196  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7197                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPR3bAny:$Pg, FPR32:$Vn), 1>;
7198  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7199                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPR3bAny:$Pg, FPR64:$Vn), 1>;
7200
7201  def : Pat<(nxv8f16 (op nxv8i1:$pg, f16:$splat, nxv8f16:$passthru)),
7202            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7203  def : Pat<(nxv2f32 (op nxv2i1:$pg, f32:$splat, nxv2f32:$passthru)),
7204            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7205  def : Pat<(nxv4f32 (op nxv4i1:$pg, f32:$splat, nxv4f32:$passthru)),
7206            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7207  def : Pat<(nxv2f64 (op nxv2i1:$pg, f64:$splat, nxv2f64:$passthru)),
7208            (!cast<Instruction>(NAME # _D) $passthru, $pg, $splat)>;
7209
7210  def : Pat<(nxv8bf16 (op nxv8i1:$pg, bf16:$splat, nxv8bf16:$passthru)),
7211            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7212}
7213
7214class sve_int_perm_compact<bit sz, string asm, ZPRRegOp zprty>
7215: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
7216  asm, "\t$Zd, $Pg, $Zn",
7217  "",
7218  []>, Sched<[]> {
7219  bits<3> Pg;
7220  bits<5> Zd;
7221  bits<5> Zn;
7222  let Inst{31-23} = 0b000001011;
7223  let Inst{22}    = sz;
7224  let Inst{21-13} = 0b100001100;
7225  let Inst{12-10} = Pg;
7226  let Inst{9-5}   = Zn;
7227  let Inst{4-0}   = Zd;
7228
7229  let hasSideEffects = 0;
7230}
7231
7232multiclass sve_int_perm_compact<string asm, SDPatternOperator op> {
7233  def _S : sve_int_perm_compact<0b0, asm, ZPR32>;
7234  def _D : sve_int_perm_compact<0b1, asm, ZPR64>;
7235
7236  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
7237  def : SVE_2_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
7238  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
7239  def : SVE_2_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
7240}
7241
7242//===----------------------------------------------------------------------===//
7243// SVE Memory - Contiguous Load Group
7244//===----------------------------------------------------------------------===//
7245
7246class sve_mem_cld_si_base<bits<4> dtype, bit nf, string asm,
7247                          RegisterOperand VecList>
7248: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
7249  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7250  "",
7251  []>, Sched<[]> {
7252  bits<3> Pg;
7253  bits<5> Rn;
7254  bits<5> Zt;
7255  bits<4> imm4;
7256  let Inst{31-25} = 0b1010010;
7257  let Inst{24-21} = dtype;
7258  let Inst{20}    = nf;
7259  let Inst{19-16} = imm4;
7260  let Inst{15-13} = 0b101;
7261  let Inst{12-10} = Pg;
7262  let Inst{9-5}   = Rn;
7263  let Inst{4-0}   = Zt;
7264
7265  let Defs = !if(nf, [FFR], []);
7266  let Uses = !if(nf, [FFR], []);
7267  let hasSideEffects = nf;
7268  let mayLoad = 1;
7269}
7270
7271multiclass sve_mem_cld_si_base<bits<4> dtype, bit nf, string asm,
7272                               RegisterOperand listty, ZPRRegOp zprty> {
7273  def _REAL : sve_mem_cld_si_base<dtype, nf, asm, listty>;
7274
7275  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7276                  (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7277  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7278                  (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
7279  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7280                  (!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7281
7282  // We need a layer of indirection because early machine code passes balk at
7283  // physical register (i.e. FFR) uses that have no previous definition.
7284  let hasSideEffects = 1, hasNoSchedulingInfo = 1, mayLoad = 1 in {
7285  def "" : Pseudo<(outs listty:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), []>,
7286           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4)>;
7287  }
7288}
7289
7290multiclass sve_mem_cld_si<bits<4> dtype, string asm, RegisterOperand listty,
7291                          ZPRRegOp zprty>
7292: sve_mem_cld_si_base<dtype, 0, asm, listty, zprty>;
7293
7294class sve_mem_cldnt_si_base<bits<2> msz, string asm, RegisterOperand VecList>
7295: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
7296  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7297  "",
7298  []>, Sched<[]> {
7299  bits<5> Zt;
7300  bits<3> Pg;
7301  bits<5> Rn;
7302  bits<4> imm4;
7303  let Inst{31-25} = 0b1010010;
7304  let Inst{24-23} = msz;
7305  let Inst{22-20} = 0b000;
7306  let Inst{19-16} = imm4;
7307  let Inst{15-13} = 0b111;
7308  let Inst{12-10} = Pg;
7309  let Inst{9-5}   = Rn;
7310  let Inst{4-0}   = Zt;
7311
7312  let hasSideEffects = 0;
7313  let mayLoad = 1;
7314}
7315
7316multiclass sve_mem_cldnt_si<bits<2> msz, string asm, RegisterOperand listty,
7317                            ZPRRegOp zprty> {
7318  def NAME : sve_mem_cldnt_si_base<msz, asm, listty>;
7319
7320  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7321                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7322  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7323                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
7324  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7325                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7326}
7327
7328class sve_mem_cldnt_ss_base<bits<2> msz, string asm, RegisterOperand VecList,
7329                            RegisterOperand gprty>
7330: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7331  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7332  "",
7333  []>, Sched<[]> {
7334  bits<3> Pg;
7335  bits<5> Rm;
7336  bits<5> Rn;
7337  bits<5> Zt;
7338  let Inst{31-25} = 0b1010010;
7339  let Inst{24-23} = msz;
7340  let Inst{22-21} = 0b00;
7341  let Inst{20-16} = Rm;
7342  let Inst{15-13} = 0b110;
7343  let Inst{12-10} = Pg;
7344  let Inst{9-5}   = Rn;
7345  let Inst{4-0}   = Zt;
7346
7347  let hasSideEffects = 0;
7348  let mayLoad = 1;
7349}
7350
7351multiclass sve_mem_cldnt_ss<bits<2> msz, string asm, RegisterOperand listty,
7352                            ZPRRegOp zprty, RegisterOperand gprty> {
7353  def NAME : sve_mem_cldnt_ss_base<msz, asm, listty, gprty>;
7354
7355  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7356                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7357}
7358
7359class sve_mem_ldqr_si<bits<2> sz, string asm, RegisterOperand VecList>
7360: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4),
7361  asm, "\t$Zt, $Pg/z, [$Rn, $imm4]", "", []>, Sched<[]> {
7362  bits<5> Zt;
7363  bits<5> Rn;
7364  bits<3> Pg;
7365  bits<4> imm4;
7366  let Inst{31-25} = 0b1010010;
7367  let Inst{24-23} = sz;
7368  let Inst{22-20} = 0;
7369  let Inst{19-16} = imm4;
7370  let Inst{15-13} = 0b001;
7371  let Inst{12-10} = Pg;
7372  let Inst{9-5}   = Rn;
7373  let Inst{4-0}   = Zt;
7374
7375  let hasSideEffects = 0;
7376  let mayLoad = 1;
7377}
7378
7379multiclass sve_mem_ldqr_si<bits<2> sz, string asm, RegisterOperand listty,
7380                           ZPRRegOp zprty> {
7381  def NAME : sve_mem_ldqr_si<sz, asm, listty>;
7382  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7383                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7384  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7385                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7386  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4]",
7387                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4), 0>;
7388}
7389
7390class sve_mem_ldqr_ss<bits<2> sz, string asm, RegisterOperand VecList,
7391                      RegisterOperand gprty>
7392: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7393  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]", "", []>, Sched<[]> {
7394  bits<5> Zt;
7395  bits<3> Pg;
7396  bits<5> Rn;
7397  bits<5> Rm;
7398  let Inst{31-25} = 0b1010010;
7399  let Inst{24-23} = sz;
7400  let Inst{22-21} = 0;
7401  let Inst{20-16} = Rm;
7402  let Inst{15-13} = 0;
7403  let Inst{12-10} = Pg;
7404  let Inst{9-5}   = Rn;
7405  let Inst{4-0}   = Zt;
7406
7407  let hasSideEffects = 0;
7408  let mayLoad = 1;
7409}
7410
7411multiclass sve_mem_ldqr_ss<bits<2> sz, string asm, RegisterOperand listty,
7412                           ZPRRegOp zprty, RegisterOperand gprty> {
7413  def NAME : sve_mem_ldqr_ss<sz, asm, listty, gprty>;
7414
7415  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7416                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7417}
7418
7419class sve_mem_ld_dup<bits<2> dtypeh, bits<2> dtypel, string asm,
7420                     RegisterOperand VecList, Operand immtype>
7421: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm6),
7422  asm, "\t$Zt, $Pg/z, [$Rn, $imm6]",
7423  "",
7424  []>, Sched<[]> {
7425  bits<3> Pg;
7426  bits<5> Rn;
7427  bits<5> Zt;
7428  bits<6> imm6;
7429  let Inst{31-25} = 0b1000010;
7430  let Inst{24-23} = dtypeh;
7431  let Inst{22}    = 1;
7432  let Inst{21-16} = imm6;
7433  let Inst{15}    = 0b1;
7434  let Inst{14-13} = dtypel;
7435  let Inst{12-10} = Pg;
7436  let Inst{9-5}   = Rn;
7437  let Inst{4-0}   = Zt;
7438
7439  let hasSideEffects = 0;
7440  let mayLoad = 1;
7441}
7442
7443multiclass sve_mem_ld_dup<bits<2> dtypeh, bits<2> dtypel, string asm,
7444                          RegisterOperand zlistty, ZPRRegOp zprty, Operand immtype> {
7445  def NAME : sve_mem_ld_dup<dtypeh, dtypel, asm, zlistty, immtype>;
7446
7447  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7448                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7449  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm6]",
7450                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm6), 0>;
7451  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7452                  (!cast<Instruction>(NAME) zlistty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7453}
7454
7455class sve_mem_cld_ss_base<bits<4> dtype, bit ff, dag iops, string asm,
7456                          RegisterOperand VecList>
7457: I<(outs VecList:$Zt), iops,
7458  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7459  "",
7460  []>, Sched<[]> {
7461  bits<5> Zt;
7462  bits<3> Pg;
7463  bits<5> Rm;
7464  bits<5> Rn;
7465  let Inst{31-25} = 0b1010010;
7466  let Inst{24-21} = dtype;
7467  let Inst{20-16} = Rm;
7468  let Inst{15-14} = 0b01;
7469  let Inst{13}    = ff;
7470  let Inst{12-10} = Pg;
7471  let Inst{9-5}   = Rn;
7472  let Inst{4-0}   = Zt;
7473
7474  let Defs = !if(ff, [FFR], []);
7475  let Uses = !if(ff, [FFR], []);
7476  let hasSideEffects = ff;
7477  let mayLoad = 1;
7478}
7479
7480multiclass sve_mem_cld_ss<bits<4> dtype, string asm, RegisterOperand listty,
7481                          ZPRRegOp zprty, RegisterOperand gprty> {
7482  def "" : sve_mem_cld_ss_base<dtype, 0, (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7483                               asm, listty>;
7484
7485  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7486                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7487}
7488
7489multiclass sve_mem_cldff_ss<bits<4> dtype, string asm, RegisterOperand listty,
7490                            ZPRRegOp zprty, RegisterOperand gprty> {
7491  def _REAL : sve_mem_cld_ss_base<dtype, 1, (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7492                                  asm, listty>;
7493
7494  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7495                 (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7496
7497  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7498                 (!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 1>;
7499
7500  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7501                 (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 0>;
7502
7503  // We need a layer of indirection because early machine code passes balk at
7504  // physical register (i.e. FFR) uses that have no previous definition.
7505  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7506  def "" : Pseudo<(outs listty:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), []>,
7507           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm)>;
7508  }
7509}
7510
7511multiclass sve_mem_cldnf_si<bits<4> dtype, string asm, RegisterOperand listty,
7512                            ZPRRegOp zprty>
7513: sve_mem_cld_si_base<dtype, 1, asm, listty, zprty>;
7514
7515class sve_mem_eld_si<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7516                     string asm, Operand immtype>
7517: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
7518  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7519  "",
7520  []>, Sched<[]> {
7521  bits<5> Zt;
7522  bits<3> Pg;
7523  bits<5> Rn;
7524  bits<4> imm4;
7525  let Inst{31-25} = 0b1010010;
7526  let Inst{24-23} = sz;
7527  let Inst{22-21} = nregs{1-0};
7528  let Inst{20}    = nregs{2};
7529  let Inst{19-16} = imm4;
7530  let Inst{15-13} = 0b111;
7531  let Inst{12-10} = Pg;
7532  let Inst{9-5}   = Rn;
7533  let Inst{4-0}   = Zt;
7534
7535  let hasSideEffects = 0;
7536  let mayLoad = 1;
7537}
7538
7539multiclass sve_mem_eld_si<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7540                          string asm, Operand immtype> {
7541  def NAME : sve_mem_eld_si<sz, nregs, VecList, asm, immtype>;
7542
7543  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7544                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7545}
7546
7547
7548class sve_mem_eld_ss<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7549                     string asm, RegisterOperand gprty>
7550: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7551  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7552  "",
7553  []>, Sched<[]> {
7554  bits<3> Pg;
7555  bits<5> Rm;
7556  bits<5> Rn;
7557  bits<5> Zt;
7558  let Inst{31-25} = 0b1010010;
7559  let Inst{24-23} = sz;
7560  let Inst{22-21} = nregs{1-0};
7561  let Inst{20-16} = Rm;
7562  let Inst{15}    = 0b1;
7563  let Inst{14}    = nregs{2};
7564  let Inst{13}    = 0b0;
7565  let Inst{12-10} = Pg;
7566  let Inst{9-5}   = Rn;
7567  let Inst{4-0}   = Zt;
7568
7569  let hasSideEffects = 0;
7570  let mayLoad = 1;
7571}
7572
7573//===----------------------------------------------------------------------===//
7574// SVE Memory - 32-bit Gather and Unsized Contiguous Group
7575//===----------------------------------------------------------------------===//
7576
7577// bit xs      is '1' if offsets are signed
7578// bit scaled  is '1' if the offsets are scaled
7579class sve_mem_32b_gld_sv<bits<4> opc, bit xs, bit scaled, string asm,
7580                         RegisterOperand zprext>
7581: I<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
7582  asm, "\t$Zt, $Pg/z, [$Rn, $Zm]",
7583  "",
7584  []>, Sched<[]> {
7585  bits<3> Pg;
7586  bits<5> Rn;
7587  bits<5> Zm;
7588  bits<5> Zt;
7589  let Inst{31-25} = 0b1000010;
7590  let Inst{24-23} = opc{3-2};
7591  let Inst{22}    = xs;
7592  let Inst{21}    = scaled;
7593  let Inst{20-16} = Zm;
7594  let Inst{15}    = 0b0;
7595  let Inst{14-13} = opc{1-0};
7596  let Inst{12-10} = Pg;
7597  let Inst{9-5}   = Rn;
7598  let Inst{4-0}   = Zt;
7599
7600
7601  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
7602  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
7603  let hasSideEffects = opc{0};
7604  let mayLoad = 1;
7605}
7606
7607multiclass sve_mem_32b_gld_sv_32_scaled<bits<4> opc, string asm,
7608                                        SDPatternOperator sxtw_op,
7609                                        SDPatternOperator uxtw_op,
7610                                        RegisterOperand sxtw_opnd,
7611                                        RegisterOperand uxtw_opnd,
7612                                        ValueType vt> {
7613  def _UXTW_SCALED_REAL : sve_mem_32b_gld_sv<opc, 0, 1, asm, uxtw_opnd>;
7614  def _SXTW_SCALED_REAL : sve_mem_32b_gld_sv<opc, 1, 1, asm, sxtw_opnd>;
7615
7616  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7617                  (!cast<Instruction>(NAME # _UXTW_SCALED_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
7618  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7619                  (!cast<Instruction>(NAME # _SXTW_SCALED_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
7620
7621  // We need a layer of indirection because early machine code passes balk at
7622  // physical register (i.e. FFR) uses that have no previous definition.
7623  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7624  def _UXTW_SCALED : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
7625                     PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_SCALED_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
7626  def _SXTW_SCALED : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
7627                     PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_SCALED_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
7628  }
7629
7630  def : Pat<(nxv4i32 (uxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$indices), vt)),
7631            (!cast<Instruction>(NAME # _UXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
7632  def : Pat<(nxv4i32 (sxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$indices), vt)),
7633            (!cast<Instruction>(NAME # _SXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
7634}
7635
7636multiclass sve_mem_32b_gld_vs_32_unscaled<bits<4> opc, string asm,
7637                                          SDPatternOperator sxtw_op,
7638                                          SDPatternOperator uxtw_op,
7639                                          RegisterOperand sxtw_opnd,
7640                                          RegisterOperand uxtw_opnd,
7641                                          ValueType vt> {
7642  def _UXTW_REAL : sve_mem_32b_gld_sv<opc, 0, 0, asm, uxtw_opnd>;
7643  def _SXTW_REAL : sve_mem_32b_gld_sv<opc, 1, 0, asm, sxtw_opnd>;
7644
7645  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7646                  (!cast<Instruction>(NAME # _UXTW_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
7647  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7648                  (!cast<Instruction>(NAME # _SXTW_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
7649
7650  // We need a layer of indirection because early machine code passes balk at
7651  // physical register (i.e. FFR) uses that have no previous definition.
7652  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7653  def _UXTW : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
7654              PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
7655  def _SXTW : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
7656              PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
7657  }
7658
7659  def : Pat<(nxv4i32 (uxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt)),
7660            (!cast<Instruction>(NAME # _UXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
7661  def : Pat<(nxv4i32 (sxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt)),
7662            (!cast<Instruction>(NAME # _SXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
7663}
7664
7665
7666class sve_mem_32b_gld_vi<bits<4> opc, string asm, Operand imm_ty>
7667: I<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5),
7668  asm, "\t$Zt, $Pg/z, [$Zn, $imm5]",
7669  "",
7670  []>, Sched<[]> {
7671  bits<3> Pg;
7672  bits<5> Zn;
7673  bits<5> Zt;
7674  bits<5> imm5;
7675  let Inst{31-25} = 0b1000010;
7676  let Inst{24-23} = opc{3-2};
7677  let Inst{22-21} = 0b01;
7678  let Inst{20-16} = imm5;
7679  let Inst{15}    = 0b1;
7680  let Inst{14-13} = opc{1-0};
7681  let Inst{12-10} = Pg;
7682  let Inst{9-5}   = Zn;
7683  let Inst{4-0}   = Zt;
7684
7685
7686  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
7687  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
7688  let hasSideEffects = opc{0};
7689  let mayLoad = 1;
7690}
7691
7692multiclass sve_mem_32b_gld_vi_32_ptrs<bits<4> opc, string asm, Operand imm_ty,
7693                                      SDPatternOperator op, ValueType vt> {
7694  def _IMM_REAL : sve_mem_32b_gld_vi<opc, asm, imm_ty>;
7695
7696  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7697                  (!cast<Instruction>(NAME # _IMM_REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 0>;
7698  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $imm5]",
7699                  (!cast<Instruction>(NAME # _IMM_REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), 0>;
7700  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7701                  (!cast<Instruction>(NAME # _IMM_REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
7702
7703  // We need a layer of indirection because early machine code passes balk at
7704  // physical register (i.e. FFR) uses that have no previous definition.
7705  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7706  def _IMM : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), []>,
7707             PseudoInstExpansion<(!cast<Instruction>(NAME # _IMM_REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5)>;
7708  }
7709
7710  def : Pat<(nxv4i32 (op (nxv4i1 PPR:$gp), (nxv4i32 ZPR:$ptrs), imm_ty:$index, vt)),
7711            (!cast<Instruction>(NAME # _IMM) PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
7712}
7713
7714class sve_mem_prfm_si<bits<2> msz, string asm>
7715: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, simm6s1:$imm6),
7716  asm, "\t$prfop, $Pg, [$Rn, $imm6, mul vl]",
7717  "",
7718  []>, Sched<[]> {
7719  bits<5> Rn;
7720  bits<3> Pg;
7721  bits<6> imm6;
7722  bits<4> prfop;
7723  let Inst{31-22} = 0b1000010111;
7724  let Inst{21-16} = imm6;
7725  let Inst{15}    = 0b0;
7726  let Inst{14-13} = msz;
7727  let Inst{12-10} = Pg;
7728  let Inst{9-5}   = Rn;
7729  let Inst{4}     = 0b0;
7730  let Inst{3-0}   = prfop;
7731
7732  let hasSideEffects = 1;
7733}
7734
7735multiclass sve_mem_prfm_si<bits<2> msz, string asm> {
7736  def NAME : sve_mem_prfm_si<msz, asm>;
7737
7738  def : InstAlias<asm # "\t$prfop, $Pg, [$Rn]",
7739                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7740}
7741
7742class sve_mem_prfm_ss<bits<3> opc, string asm, RegisterOperand gprty>
7743: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7744  asm, "\t$prfop, $Pg, [$Rn, $Rm]",
7745  "",
7746  []>, Sched<[]> {
7747  bits<5> Rm;
7748  bits<5> Rn;
7749  bits<3> Pg;
7750  bits<4> prfop;
7751  let Inst{31-25} = 0b1000010;
7752  let Inst{24-23} = opc{2-1};
7753  let Inst{22-21} = 0b00;
7754  let Inst{20-16} = Rm;
7755  let Inst{15}    = 0b1;
7756  let Inst{14}    = opc{0};
7757  let Inst{13}    = 0b0;
7758  let Inst{12-10} = Pg;
7759  let Inst{9-5}   = Rn;
7760  let Inst{4}     = 0b0;
7761  let Inst{3-0}   = prfop;
7762
7763  let hasSideEffects = 1;
7764}
7765
7766class sve_mem_32b_prfm_sv<bits<2> msz, bit xs, string asm,
7767                          RegisterOperand zprext>
7768: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
7769  asm, "\t$prfop, $Pg, [$Rn, $Zm]",
7770  "",
7771  []>, Sched<[]> {
7772  bits<3> Pg;
7773  bits<5> Rn;
7774  bits<5> Zm;
7775  bits<4> prfop;
7776  let Inst{31-23} = 0b100001000;
7777  let Inst{22}    = xs;
7778  let Inst{21}    = 0b1;
7779  let Inst{20-16} = Zm;
7780  let Inst{15}    = 0b0;
7781  let Inst{14-13} = msz;
7782  let Inst{12-10} = Pg;
7783  let Inst{9-5}   = Rn;
7784  let Inst{4}     = 0b0;
7785  let Inst{3-0}   = prfop;
7786
7787  let hasSideEffects = 1;
7788}
7789
7790multiclass sve_mem_32b_prfm_sv_scaled<bits<2> msz, string asm,
7791                                      RegisterOperand sxtw_opnd,
7792                                      RegisterOperand uxtw_opnd,
7793                                      SDPatternOperator op_sxtw,
7794                                      SDPatternOperator op_uxtw> {
7795  def _UXTW_SCALED : sve_mem_32b_prfm_sv<msz, 0, asm, uxtw_opnd>;
7796  def _SXTW_SCALED : sve_mem_32b_prfm_sv<msz, 1, asm, sxtw_opnd>;
7797
7798  def : Pat<(op_uxtw (nxv4i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv4i32 uxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
7799            (!cast<Instruction>(NAME # _UXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
7800
7801  def : Pat<(op_sxtw (nxv4i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv4i32 sxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
7802            (!cast<Instruction>(NAME # _SXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
7803}
7804
7805class sve_mem_32b_prfm_vi<bits<2> msz, string asm, Operand imm_ty>
7806: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5),
7807  asm, "\t$prfop, $Pg, [$Zn, $imm5]",
7808  "",
7809  []>, Sched<[]> {
7810  bits<3> Pg;
7811  bits<5> Zn;
7812  bits<5> imm5;
7813  bits<4> prfop;
7814  let Inst{31-25} = 0b1000010;
7815  let Inst{24-23} = msz;
7816  let Inst{22-21} = 0b00;
7817  let Inst{20-16} = imm5;
7818  let Inst{15-13} = 0b111;
7819  let Inst{12-10} = Pg;
7820  let Inst{9-5}   = Zn;
7821  let Inst{4}     = 0b0;
7822  let Inst{3-0}   = prfop;
7823
7824  let hasSideEffects = 1;
7825}
7826
7827multiclass sve_mem_32b_prfm_vi<bits<2> msz, string asm, Operand imm_ty, SDPatternOperator op> {
7828  def NAME : sve_mem_32b_prfm_vi<msz, asm, imm_ty>;
7829
7830  def : InstAlias<asm # "\t$prfop, $Pg, [$Zn]",
7831                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
7832
7833  def : Pat<(op (nxv4i1 PPR_3b:$Pg), (nxv4i32 ZPR32:$Zn), (i64 imm_ty:$imm), (i32 sve_prfop:$prfop)),
7834            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR_3b:$Pg, ZPR32:$Zn, imm_ty:$imm)>;
7835}
7836
7837class sve_mem_z_fill<string asm>
7838: I<(outs ZPRAny:$Zt), (ins GPR64sp:$Rn, simm9:$imm9),
7839  asm, "\t$Zt, [$Rn, $imm9, mul vl]",
7840  "",
7841  []>, Sched<[]> {
7842  bits<5> Rn;
7843  bits<5> Zt;
7844  bits<9> imm9;
7845  let Inst{31-22} = 0b1000010110;
7846  let Inst{21-16} = imm9{8-3};
7847  let Inst{15-13} = 0b010;
7848  let Inst{12-10} = imm9{2-0};
7849  let Inst{9-5}   = Rn;
7850  let Inst{4-0}   = Zt;
7851
7852  let hasSideEffects = 0;
7853  let mayLoad = 1;
7854}
7855
7856multiclass sve_mem_z_fill<string asm> {
7857  def NAME : sve_mem_z_fill<asm>;
7858
7859  def : InstAlias<asm # "\t$Zt, [$Rn]",
7860                  (!cast<Instruction>(NAME) ZPRAny:$Zt, GPR64sp:$Rn, 0), 1>;
7861}
7862
7863class sve_mem_p_fill<string asm>
7864: I<(outs PPRAny:$Pt), (ins GPR64sp:$Rn, simm9:$imm9),
7865  asm, "\t$Pt, [$Rn, $imm9, mul vl]",
7866  "",
7867  []>, Sched<[]> {
7868  bits<4> Pt;
7869  bits<5> Rn;
7870  bits<9> imm9;
7871  let Inst{31-22} = 0b1000010110;
7872  let Inst{21-16} = imm9{8-3};
7873  let Inst{15-13} = 0b000;
7874  let Inst{12-10} = imm9{2-0};
7875  let Inst{9-5}   = Rn;
7876  let Inst{4}     = 0b0;
7877  let Inst{3-0}   = Pt;
7878
7879  let hasSideEffects = 0;
7880  let mayLoad = 1;
7881}
7882
7883multiclass sve_mem_p_fill<string asm> {
7884  def NAME : sve_mem_p_fill<asm>;
7885
7886  def : InstAlias<asm # "\t$Pt, [$Rn]",
7887                  (!cast<Instruction>(NAME) PPRAny:$Pt, GPR64sp:$Rn, 0), 1>;
7888}
7889
7890class sve2_mem_gldnt_vs_base<bits<5> opc, dag iops, string asm,
7891                             RegisterOperand VecList>
7892: I<(outs VecList:$Zt), iops,
7893  asm, "\t$Zt, $Pg/z, [$Zn, $Rm]",
7894  "",
7895  []>, Sched<[]> {
7896  bits<3> Pg;
7897  bits<5> Rm;
7898  bits<5> Zn;
7899  bits<5> Zt;
7900  let Inst{31}    = 0b1;
7901  let Inst{30}    = opc{4};
7902  let Inst{29-25} = 0b00010;
7903  let Inst{24-23} = opc{3-2};
7904  let Inst{22-21} = 0b00;
7905  let Inst{20-16} = Rm;
7906  let Inst{15}    = 0b1;
7907  let Inst{14-13} = opc{1-0};
7908  let Inst{12-10} = Pg;
7909  let Inst{9-5}   = Zn;
7910  let Inst{4-0}   = Zt;
7911
7912  let hasSideEffects = 0;
7913  let mayLoad = 1;
7914}
7915
7916multiclass sve2_mem_gldnt_vs_32_ptrs<bits<5> opc, string asm,
7917                                  SDPatternOperator op,
7918                                  ValueType vt> {
7919  def _REAL : sve2_mem_gldnt_vs_base<opc, (ins PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm),
7920                                     asm, Z_s>;
7921
7922  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $Rm]",
7923                 (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm), 0>;
7924  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7925                 (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 0>;
7926  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7927                 (!cast<Instruction>(NAME # _REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 1>;
7928
7929  def : Pat <(nxv4i32 (op (nxv4i1 PPR3bAny:$Pg), (nxv4i32 ZPR32:$Zd), (i64 GPR64:$Rm), vt)),
7930             (!cast<Instruction>(NAME # _REAL) PPR3bAny:$Pg, ZPR32:$Zd, GPR64:$Rm)>;
7931}
7932
7933multiclass sve2_mem_gldnt_vs_64_ptrs<bits<5> opc, string asm,
7934                                   SDPatternOperator op,
7935                                   ValueType vt> {
7936  def _REAL : sve2_mem_gldnt_vs_base<opc, (ins PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
7937                                     asm, Z_d>;
7938
7939  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $Rm]",
7940                 (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm), 0>;
7941  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7942                 (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 0>;
7943  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7944                 (!cast<Instruction>(NAME # _REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
7945
7946  def : Pat <(nxv2i64 (op (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zd), (i64 GPR64:$Rm), vt)),
7947             (!cast<Instruction>(NAME # _REAL) PPR3bAny:$Pg, ZPR64:$Zd, GPR64:$Rm)>;
7948}
7949
7950//===----------------------------------------------------------------------===//
7951// SVE Memory - 64-bit Gather Group
7952//===----------------------------------------------------------------------===//
7953
7954// bit xs      is '1' if offsets are signed
7955// bit scaled  is '1' if the offsets are scaled
7956// bit lsl     is '0' if the offsets are extended (uxtw/sxtw), '1' if shifted (lsl)
7957class sve_mem_64b_gld_sv<bits<4> opc, bit xs, bit scaled, bit lsl, string asm,
7958                         RegisterOperand zprext>
7959: I<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
7960  asm, "\t$Zt, $Pg/z, [$Rn, $Zm]",
7961  "",
7962  []>, Sched<[]> {
7963  bits<3> Pg;
7964  bits<5> Rn;
7965  bits<5> Zm;
7966  bits<5> Zt;
7967  let Inst{31-25} = 0b1100010;
7968  let Inst{24-23} = opc{3-2};
7969  let Inst{22}    = xs;
7970  let Inst{21}    = scaled;
7971  let Inst{20-16} = Zm;
7972  let Inst{15}    = lsl;
7973  let Inst{14-13} = opc{1-0};
7974  let Inst{12-10} = Pg;
7975  let Inst{9-5}   = Rn;
7976  let Inst{4-0}   = Zt;
7977
7978
7979  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
7980  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
7981  let hasSideEffects = opc{0};
7982  let mayLoad = 1;
7983}
7984
7985multiclass sve_mem_64b_gld_sv_32_scaled<bits<4> opc, string asm,
7986                                        SDPatternOperator sxtw_op,
7987                                        SDPatternOperator uxtw_op,
7988                                        RegisterOperand sxtw_opnd,
7989                                        RegisterOperand uxtw_opnd,
7990                                        ValueType vt> {
7991  def _UXTW_SCALED_REAL : sve_mem_64b_gld_sv<opc, 0, 1, 0, asm, uxtw_opnd>;
7992  def _SXTW_SCALED_REAL : sve_mem_64b_gld_sv<opc, 1, 1, 0, asm, sxtw_opnd>;
7993
7994  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7995                  (!cast<Instruction>(NAME # _UXTW_SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
7996  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7997                  (!cast<Instruction>(NAME # _SXTW_SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
7998
7999  // We need a layer of indirection because early machine code passes balk at
8000  // physical register (i.e. FFR) uses that have no previous definition.
8001  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8002  def _UXTW_SCALED : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
8003                     PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_SCALED_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8004  def _SXTW_SCALED : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
8005                     PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_SCALED_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8006  }
8007
8008  def : Pat<(nxv2i64 (uxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8009            (!cast<Instruction>(NAME # _UXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8010  def : Pat<(nxv2i64 (sxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8011            (!cast<Instruction>(NAME # _SXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8012}
8013
8014multiclass sve_mem_64b_gld_vs_32_unscaled<bits<4> opc, string asm,
8015                                          SDPatternOperator sxtw_op,
8016                                          SDPatternOperator uxtw_op,
8017                                          RegisterOperand sxtw_opnd,
8018                                          RegisterOperand uxtw_opnd,
8019                                          ValueType vt> {
8020  def _UXTW_REAL : sve_mem_64b_gld_sv<opc, 0, 0, 0, asm, uxtw_opnd>;
8021  def _SXTW_REAL : sve_mem_64b_gld_sv<opc, 1, 0, 0, asm, sxtw_opnd>;
8022
8023  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8024                  (!cast<Instruction>(NAME # _UXTW_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
8025  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8026                  (!cast<Instruction>(NAME # _SXTW_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
8027
8028  // We need a layer of indirection because early machine code passes balk at
8029  // physical register (i.e. FFR) uses that have no previous definition.
8030  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8031  def _UXTW : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
8032              PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8033  def _SXTW : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
8034              PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8035  }
8036
8037  def : Pat<(nxv2i64 (uxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8038            (!cast<Instruction>(NAME # _UXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8039  def : Pat<(nxv2i64 (sxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8040            (!cast<Instruction>(NAME # _SXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8041}
8042
8043multiclass sve_mem_64b_gld_sv2_64_scaled<bits<4> opc, string asm,
8044                                         SDPatternOperator op,
8045                                         RegisterOperand zprext, ValueType vt> {
8046  def _SCALED_REAL : sve_mem_64b_gld_sv<opc, 1, 1, 1, asm, zprext>;
8047
8048  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8049                  (!cast<Instruction>(NAME # _SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), 0>;
8050
8051  // We need a layer of indirection because early machine code passes balk at
8052  // physical register (i.e. FFR) uses that have no previous definition.
8053  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8054  def _SCALED : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), []>,
8055                PseudoInstExpansion<(!cast<Instruction>(NAME # _SCALED_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm)>;
8056  }
8057
8058  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8059                     (!cast<Instruction>(NAME # _SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8060}
8061
8062multiclass sve_mem_64b_gld_vs2_64_unscaled<bits<4> opc, string asm,
8063                                           SDPatternOperator op, ValueType vt> {
8064  def _REAL : sve_mem_64b_gld_sv<opc, 1, 0, 1, asm, ZPR64ExtLSL8>;
8065
8066  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8067                  (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), 0>;
8068
8069  // We need a layer of indirection because early machine code passes balk at
8070  // physical register (i.e. FFR) uses that have no previous definition.
8071  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8072  def "" : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), []>,
8073           PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm)>;
8074  }
8075
8076  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8077            (!cast<Instruction>(NAME) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8078}
8079
8080class sve_mem_64b_gld_vi<bits<4> opc, string asm, Operand imm_ty>
8081: I<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5),
8082  asm, "\t$Zt, $Pg/z, [$Zn, $imm5]",
8083  "",
8084  []>, Sched<[]> {
8085  bits<3> Pg;
8086  bits<5> Zn;
8087  bits<5> Zt;
8088  bits<5> imm5;
8089  let Inst{31-25} = 0b1100010;
8090  let Inst{24-23} = opc{3-2};
8091  let Inst{22-21} = 0b01;
8092  let Inst{20-16} = imm5;
8093  let Inst{15}    = 0b1;
8094  let Inst{14-13} = opc{1-0};
8095  let Inst{12-10} = Pg;
8096  let Inst{9-5}   = Zn;
8097  let Inst{4-0}   = Zt;
8098
8099  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
8100  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
8101  let hasSideEffects = opc{0};
8102  let mayLoad = 1;
8103}
8104
8105multiclass sve_mem_64b_gld_vi_64_ptrs<bits<4> opc, string asm, Operand imm_ty,
8106                                      SDPatternOperator op, ValueType vt> {
8107  def _IMM_REAL : sve_mem_64b_gld_vi<opc, asm, imm_ty>;
8108
8109  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8110                  (!cast<Instruction>(NAME # _IMM_REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 0>;
8111  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $imm5]",
8112                 (!cast<Instruction>(NAME # _IMM_REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), 0>;
8113  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8114                  (!cast<Instruction>(NAME # _IMM_REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
8115
8116  // We need a layer of indirection because early machine code passes balk at
8117  // physical register (i.e. FFR) uses that have no previous definition.
8118  let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8119  def _IMM : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), []>,
8120                  PseudoInstExpansion<(!cast<Instruction>(NAME # _IMM_REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5)>;
8121  }
8122
8123  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), (nxv2i64 ZPR:$ptrs), imm_ty:$index, vt)),
8124            (!cast<Instruction>(NAME # _IMM) PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
8125}
8126
8127// bit lsl is '0' if the offsets are extended (uxtw/sxtw), '1' if shifted (lsl)
8128class sve_mem_64b_prfm_sv<bits<2> msz, bit xs, bit lsl, string asm,
8129                          RegisterOperand zprext>
8130: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
8131  asm, "\t$prfop, $Pg, [$Rn, $Zm]",
8132  "",
8133  []>, Sched<[]> {
8134  bits<3> Pg;
8135  bits<5> Rn;
8136  bits<5> Zm;
8137  bits<4> prfop;
8138  let Inst{31-23} = 0b110001000;
8139  let Inst{22}    = xs;
8140  let Inst{21}    = 0b1;
8141  let Inst{20-16} = Zm;
8142  let Inst{15}    = lsl;
8143  let Inst{14-13} = msz;
8144  let Inst{12-10} = Pg;
8145  let Inst{9-5}   = Rn;
8146  let Inst{4}     = 0b0;
8147  let Inst{3-0}   = prfop;
8148
8149  let hasSideEffects = 1;
8150}
8151
8152multiclass sve_mem_64b_prfm_sv_ext_scaled<bits<2> msz, string asm,
8153                                          RegisterOperand sxtw_opnd,
8154                                          RegisterOperand uxtw_opnd,
8155                                          SDPatternOperator op_sxtw,
8156                                          SDPatternOperator op_uxtw> {
8157  def _UXTW_SCALED : sve_mem_64b_prfm_sv<msz, 0, 0, asm, uxtw_opnd>;
8158  def _SXTW_SCALED : sve_mem_64b_prfm_sv<msz, 1, 0, asm, sxtw_opnd>;
8159
8160  def : Pat<(op_uxtw (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 uxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
8161            (!cast<Instruction>(NAME # _UXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8162
8163  def : Pat<(op_sxtw (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 sxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
8164            (!cast<Instruction>(NAME # _SXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8165
8166}
8167
8168multiclass sve_mem_64b_prfm_sv_lsl_scaled<bits<2> msz, string asm,
8169                                          RegisterOperand zprext, SDPatternOperator frag> {
8170  def NAME : sve_mem_64b_prfm_sv<msz, 1, 1, asm, zprext>;
8171
8172  def : Pat<(frag (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 zprext:$Zm), (i32 sve_prfop:$prfop)),
8173            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm)>;
8174
8175}
8176
8177class sve_mem_64b_prfm_vi<bits<2> msz, string asm, Operand imm_ty>
8178: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5),
8179  asm, "\t$prfop, $Pg, [$Zn, $imm5]",
8180  "",
8181  []>, Sched<[]> {
8182  bits<3> Pg;
8183  bits<5> Zn;
8184  bits<5> imm5;
8185  bits<4> prfop;
8186  let Inst{31-25} = 0b1100010;
8187  let Inst{24-23} = msz;
8188  let Inst{22-21} = 0b00;
8189  let Inst{20-16} = imm5;
8190  let Inst{15-13} = 0b111;
8191  let Inst{12-10} = Pg;
8192  let Inst{9-5}   = Zn;
8193  let Inst{4}     = 0b0;
8194  let Inst{3-0}   = prfop;
8195
8196  let hasSideEffects = 1;
8197}
8198
8199multiclass sve_mem_64b_prfm_vi<bits<2> msz, string asm, Operand imm_ty, SDPatternOperator op> {
8200  def NAME : sve_mem_64b_prfm_vi<msz, asm, imm_ty>;
8201
8202  def : InstAlias<asm # "\t$prfop, $Pg, [$Zn]",
8203                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
8204
8205  def : Pat<(op (nxv2i1 PPR_3b:$Pg), (nxv2i64 ZPR32:$Zn), (i64 imm_ty:$imm), (i32 sve_prfop:$prfop)),
8206            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR_3b:$Pg, ZPR32:$Zn, imm_ty:$imm)>;
8207}
8208
8209//===----------------------------------------------------------------------===//
8210// SVE Compute Vector Address Group
8211//===----------------------------------------------------------------------===//
8212
8213class sve_int_bin_cons_misc_0_a<bits<2> opc, bits<2> msz, string asm,
8214                                ZPRRegOp zprty, RegisterOperand zprext>
8215: I<(outs zprty:$Zd), (ins zprty:$Zn, zprext:$Zm),
8216  asm, "\t$Zd, [$Zn, $Zm]",
8217  "",
8218  []>, Sched<[]> {
8219  bits<5> Zd;
8220  bits<5> Zn;
8221  bits<5> Zm;
8222  let Inst{31-24} = 0b00000100;
8223  let Inst{23-22} = opc;
8224  let Inst{21}    = 0b1;
8225  let Inst{20-16} = Zm;
8226  let Inst{15-12} = 0b1010;
8227  let Inst{11-10} = msz;
8228  let Inst{9-5}   = Zn;
8229  let Inst{4-0}   = Zd;
8230
8231  let hasSideEffects = 0;
8232}
8233
8234multiclass sve_int_bin_cons_misc_0_a_uxtw<bits<2> opc, string asm> {
8235  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtUXTW8>;
8236  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtUXTW16>;
8237  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtUXTW32>;
8238  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtUXTW64>;
8239}
8240
8241multiclass sve_int_bin_cons_misc_0_a_sxtw<bits<2> opc, string asm> {
8242  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtSXTW8>;
8243  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtSXTW16>;
8244  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtSXTW32>;
8245  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtSXTW64>;
8246}
8247
8248multiclass sve_int_bin_cons_misc_0_a_32_lsl<bits<2> opc, string asm> {
8249  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR32, ZPR32ExtLSL8>;
8250  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR32, ZPR32ExtLSL16>;
8251  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR32, ZPR32ExtLSL32>;
8252  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR32, ZPR32ExtLSL64>;
8253}
8254
8255multiclass sve_int_bin_cons_misc_0_a_64_lsl<bits<2> opc, string asm> {
8256  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtLSL8>;
8257  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtLSL16>;
8258  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtLSL32>;
8259  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtLSL64>;
8260}
8261
8262//===----------------------------------------------------------------------===//
8263// SVE Integer Misc - Unpredicated Group
8264//===----------------------------------------------------------------------===//
8265
8266class sve_int_bin_cons_misc_0_b<bits<2> sz, string asm, ZPRRegOp zprty>
8267: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
8268  asm, "\t$Zd, $Zn, $Zm",
8269  "",
8270  []>, Sched<[]> {
8271  bits<5> Zd;
8272  bits<5> Zm;
8273  bits<5> Zn;
8274  let Inst{31-24} = 0b00000100;
8275  let Inst{23-22} = sz;
8276  let Inst{21}    = 0b1;
8277  let Inst{20-16} = Zm;
8278  let Inst{15-10} = 0b101100;
8279  let Inst{9-5}   = Zn;
8280  let Inst{4-0}   = Zd;
8281
8282  let hasSideEffects = 0;
8283}
8284
8285multiclass sve_int_bin_cons_misc_0_b<string asm, SDPatternOperator op> {
8286  def _H : sve_int_bin_cons_misc_0_b<0b01, asm, ZPR16>;
8287  def _S : sve_int_bin_cons_misc_0_b<0b10, asm, ZPR32>;
8288  def _D : sve_int_bin_cons_misc_0_b<0b11, asm, ZPR64>;
8289
8290  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
8291  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
8292  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
8293}
8294
8295class sve_int_bin_cons_misc_0_c<bits<8> opc, string asm, ZPRRegOp zprty>
8296: I<(outs zprty:$Zd), (ins zprty:$Zn),
8297  asm, "\t$Zd, $Zn",
8298  "",
8299  []>, Sched<[]> {
8300  bits<5> Zd;
8301  bits<5> Zn;
8302  let Inst{31-24} = 0b00000100;
8303  let Inst{23-22} = opc{7-6};
8304  let Inst{21}    = 0b1;
8305  let Inst{20-16} = opc{5-1};
8306  let Inst{15-11} = 0b10111;
8307  let Inst{10}    = opc{0};
8308  let Inst{9-5}   = Zn;
8309  let Inst{4-0}   = Zd;
8310
8311  let hasSideEffects = 0;
8312}
8313
8314multiclass sve_int_bin_cons_misc_0_c_fexpa<string asm, SDPatternOperator op> {
8315  def _H : sve_int_bin_cons_misc_0_c<0b01000000, asm, ZPR16>;
8316  def _S : sve_int_bin_cons_misc_0_c<0b10000000, asm, ZPR32>;
8317  def _D : sve_int_bin_cons_misc_0_c<0b11000000, asm, ZPR64>;
8318
8319  def : SVE_1_Op_Pat<nxv8f16, op, nxv8i16, !cast<Instruction>(NAME # _H)>;
8320  def : SVE_1_Op_Pat<nxv4f32, op, nxv4i32, !cast<Instruction>(NAME # _S)>;
8321  def : SVE_1_Op_Pat<nxv2f64, op, nxv2i64, !cast<Instruction>(NAME # _D)>;
8322}
8323
8324//===----------------------------------------------------------------------===//
8325// SVE Integer Reduction Group
8326//===----------------------------------------------------------------------===//
8327
8328class sve_int_reduce<bits<2> sz8_32, bits<2> fmt, bits<3> opc, string asm,
8329                     ZPRRegOp zprty, FPRasZPROperand dstOpType>
8330: I<(outs dstOpType:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
8331  asm, "\t$Vd, $Pg, $Zn",
8332  "",
8333  []>, Sched<[]> {
8334  bits<3> Pg;
8335  bits<5> Vd;
8336  bits<5> Zn;
8337  let Inst{31-24} = 0b00000100;
8338  let Inst{23-22} = sz8_32;
8339  let Inst{21}    = 0b0;
8340  let Inst{20-19} = fmt;
8341  let Inst{18-16} = opc;
8342  let Inst{15-13} = 0b001;
8343  let Inst{12-10} = Pg;
8344  let Inst{9-5}   = Zn;
8345  let Inst{4-0}   = Vd;
8346
8347  let hasSideEffects = 0;
8348}
8349
8350multiclass sve_int_reduce_0_saddv<bits<3> opc, string asm,
8351                                  SDPatternOperator op> {
8352  def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
8353  def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
8354  def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
8355
8356  def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8357  def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8358  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8359}
8360
8361multiclass sve_int_reduce_0_uaddv<bits<3> opc, string asm,
8362                                  SDPatternOperator op> {
8363  def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
8364  def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
8365  def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
8366  def _D : sve_int_reduce<0b11, 0b00, opc, asm, ZPR64, FPR64asZPR>;
8367
8368  def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8369  def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8370  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8371  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8372}
8373
8374multiclass sve_int_reduce_1<bits<3> opc, string asm,
8375                            SDPatternOperator op> {
8376  def _B : sve_int_reduce<0b00, 0b01, opc, asm, ZPR8, FPR8asZPR>;
8377  def _H : sve_int_reduce<0b01, 0b01, opc, asm, ZPR16, FPR16asZPR>;
8378  def _S : sve_int_reduce<0b10, 0b01, opc, asm, ZPR32, FPR32asZPR>;
8379  def _D : sve_int_reduce<0b11, 0b01, opc, asm, ZPR64, FPR64asZPR>;
8380
8381  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8382  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8383  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8384  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8385}
8386
8387multiclass sve_int_reduce_2<bits<3> opc, string asm,
8388                            SDPatternOperator op> {
8389  def _B : sve_int_reduce<0b00, 0b11, opc, asm, ZPR8, FPR8asZPR>;
8390  def _H : sve_int_reduce<0b01, 0b11, opc, asm, ZPR16, FPR16asZPR>;
8391  def _S : sve_int_reduce<0b10, 0b11, opc, asm, ZPR32, FPR32asZPR>;
8392  def _D : sve_int_reduce<0b11, 0b11, opc, asm, ZPR64, FPR64asZPR>;
8393
8394  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8395  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8396  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8397  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8398}
8399
8400class sve_int_movprfx_pred<bits<2> sz8_32, bits<3> opc, string asm,
8401                           ZPRRegOp zprty, string pg_suffix, dag iops>
8402: I<(outs zprty:$Zd), iops,
8403  asm, "\t$Zd, $Pg"#pg_suffix#", $Zn",
8404  "",
8405  []>, Sched<[]> {
8406  bits<3> Pg;
8407  bits<5> Zd;
8408  bits<5> Zn;
8409  let Inst{31-24} = 0b00000100;
8410  let Inst{23-22} = sz8_32;
8411  let Inst{21-19} = 0b010;
8412  let Inst{18-16} = opc;
8413  let Inst{15-13} = 0b001;
8414  let Inst{12-10} = Pg;
8415  let Inst{9-5}   = Zn;
8416  let Inst{4-0}   = Zd;
8417
8418  let ElementSize = zprty.ElementSize;
8419  let hasSideEffects = 0;
8420}
8421
8422multiclass sve_int_movprfx_pred_merge<bits<3> opc, string asm> {
8423let Constraints = "$Zd = $_Zd" in {
8424  def _B : sve_int_movprfx_pred<0b00, opc, asm, ZPR8, "/m",
8425                                (ins ZPR8:$_Zd, PPR3bAny:$Pg, ZPR8:$Zn)>;
8426  def _H : sve_int_movprfx_pred<0b01, opc, asm, ZPR16, "/m",
8427                                (ins ZPR16:$_Zd, PPR3bAny:$Pg, ZPR16:$Zn)>;
8428  def _S : sve_int_movprfx_pred<0b10, opc, asm, ZPR32, "/m",
8429                                (ins ZPR32:$_Zd, PPR3bAny:$Pg, ZPR32:$Zn)>;
8430  def _D : sve_int_movprfx_pred<0b11, opc, asm, ZPR64, "/m",
8431                                (ins ZPR64:$_Zd, PPR3bAny:$Pg, ZPR64:$Zn)>;
8432}
8433}
8434
8435multiclass sve_int_movprfx_pred_zero<bits<3> opc, string asm> {
8436  def _B : sve_int_movprfx_pred<0b00, opc, asm, ZPR8, "/z",
8437                                (ins PPR3bAny:$Pg, ZPR8:$Zn)>;
8438  def _H : sve_int_movprfx_pred<0b01, opc, asm, ZPR16, "/z",
8439                                (ins PPR3bAny:$Pg, ZPR16:$Zn)>;
8440  def _S : sve_int_movprfx_pred<0b10, opc, asm, ZPR32, "/z",
8441                                (ins PPR3bAny:$Pg, ZPR32:$Zn)>;
8442  def _D : sve_int_movprfx_pred<0b11, opc, asm, ZPR64, "/z",
8443                                (ins PPR3bAny:$Pg, ZPR64:$Zn)>;
8444}
8445
8446//===----------------------------------------------------------------------===//
8447// SVE Propagate Break Group
8448//===----------------------------------------------------------------------===//
8449
8450class sve_int_brkp<bits<2> opc, string asm>
8451: I<(outs PPR8:$Pd), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$Pm),
8452  asm, "\t$Pd, $Pg/z, $Pn, $Pm",
8453  "",
8454  []>, Sched<[]> {
8455  bits<4> Pd;
8456  bits<4> Pg;
8457  bits<4> Pm;
8458  bits<4> Pn;
8459  let Inst{31-24} = 0b00100101;
8460  let Inst{23}    = 0b0;
8461  let Inst{22}    = opc{1};
8462  let Inst{21-20} = 0b00;
8463  let Inst{19-16} = Pm;
8464  let Inst{15-14} = 0b11;
8465  let Inst{13-10} = Pg;
8466  let Inst{9}     = 0b0;
8467  let Inst{8-5}   = Pn;
8468  let Inst{4}     = opc{0};
8469  let Inst{3-0}   = Pd;
8470
8471  let Defs = !if(!eq (opc{1}, 1), [NZCV], []);
8472  let hasSideEffects = 0;
8473}
8474
8475multiclass sve_int_brkp<bits<2> opc, string asm, SDPatternOperator op> {
8476  def NAME : sve_int_brkp<opc, asm>;
8477
8478  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8479}
8480
8481
8482//===----------------------------------------------------------------------===//
8483// SVE Partition Break Group
8484//===----------------------------------------------------------------------===//
8485
8486class sve_int_brkn<bit S, string asm>
8487: I<(outs PPR8:$Pdm), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$_Pdm),
8488  asm, "\t$Pdm, $Pg/z, $Pn, $_Pdm",
8489  "",
8490  []>, Sched<[]> {
8491  bits<4> Pdm;
8492  bits<4> Pg;
8493  bits<4> Pn;
8494  let Inst{31-23} = 0b001001010;
8495  let Inst{22}    = S;
8496  let Inst{21-14} = 0b01100001;
8497  let Inst{13-10} = Pg;
8498  let Inst{9}     = 0b0;
8499  let Inst{8-5}   = Pn;
8500  let Inst{4}     = 0b0;
8501  let Inst{3-0}   = Pdm;
8502
8503  let Constraints = "$Pdm = $_Pdm";
8504  let Defs = !if(S, [NZCV], []);
8505  let ElementSize = ElementSizeB;
8506  let hasSideEffects = 0;
8507}
8508
8509multiclass sve_int_brkn<bits<1> opc, string asm, SDPatternOperator op> {
8510  def NAME : sve_int_brkn<opc, asm>;
8511
8512  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8513}
8514
8515class sve_int_break<bits<3> opc, string asm, string suffix, dag iops>
8516: I<(outs PPR8:$Pd), iops,
8517  asm, "\t$Pd, $Pg"#suffix#", $Pn",
8518  "",
8519  []>, Sched<[]> {
8520  bits<4> Pd;
8521  bits<4> Pg;
8522  bits<4> Pn;
8523  let Inst{31-24} = 0b00100101;
8524  let Inst{23-22} = opc{2-1};
8525  let Inst{21-14} = 0b01000001;
8526  let Inst{13-10} = Pg;
8527  let Inst{9}     = 0b0;
8528  let Inst{8-5}   = Pn;
8529  let Inst{4}     = opc{0};
8530  let Inst{3-0}   = Pd;
8531
8532  let Constraints = !if(!eq (opc{0}, 1), "$Pd = $_Pd", "");
8533  let Defs = !if(!eq (opc{1}, 1), [NZCV], []);
8534  let hasSideEffects = 0;
8535}
8536
8537multiclass sve_int_break_m<bits<3> opc, string asm, SDPatternOperator op> {
8538  def NAME : sve_int_break<opc, asm, "/m", (ins PPR8:$_Pd, PPRAny:$Pg, PPR8:$Pn)>;
8539
8540  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8541}
8542
8543multiclass sve_int_break_z<bits<3> opc, string asm, SDPatternOperator op> {
8544  def NAME : sve_int_break<opc, asm, "/z", (ins PPRAny:$Pg, PPR8:$Pn)>;
8545
8546  def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8547}
8548
8549//===----------------------------------------------------------------------===//
8550// SVE2 String Processing Group
8551//===----------------------------------------------------------------------===//
8552
8553class sve2_char_match<bit sz, bit opc, string asm,
8554                      PPRRegOp pprty, ZPRRegOp zprty>
8555: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
8556  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
8557  "",
8558  []>, Sched<[]> {
8559  bits<4> Pd;
8560  bits<3> Pg;
8561  bits<5> Zm;
8562  bits<5> Zn;
8563  let Inst{31-23} = 0b010001010;
8564  let Inst{22}    = sz;
8565  let Inst{21}    = 0b1;
8566  let Inst{20-16} = Zm;
8567  let Inst{15-13} = 0b100;
8568  let Inst{12-10} = Pg;
8569  let Inst{9-5}   = Zn;
8570  let Inst{4}     = opc;
8571  let Inst{3-0}   = Pd;
8572
8573  let Defs = [NZCV];
8574  let ElementSize = pprty.ElementSize;
8575  let hasSideEffects = 0;
8576  let isPTestLike = 1;
8577}
8578
8579multiclass sve2_char_match<bit opc, string asm, SDPatternOperator op> {
8580  def _B : sve2_char_match<0b0, opc, asm, PPR8, ZPR8>;
8581  def _H : sve2_char_match<0b1, opc, asm, PPR16, ZPR16>;
8582
8583  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
8584  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
8585}
8586
8587//===----------------------------------------------------------------------===//
8588// SVE2 Histogram Computation - Segment Group
8589//===----------------------------------------------------------------------===//
8590
8591class sve2_hist_gen_segment<string asm, SDPatternOperator op>
8592: I<(outs ZPR8:$Zd), (ins ZPR8:$Zn, ZPR8:$Zm),
8593  asm, "\t$Zd, $Zn, $Zm",
8594  "",
8595  [(set nxv16i8:$Zd, (op nxv16i8:$Zn, nxv16i8:$Zm))]>, Sched<[]> {
8596  bits<5> Zd;
8597  bits<5> Zn;
8598  bits<5> Zm;
8599  let Inst{31-21} = 0b01000101001;
8600  let Inst{20-16} = Zm;
8601  let Inst{15-10} = 0b101000;
8602  let Inst{9-5}   = Zn;
8603  let Inst{4-0}   = Zd;
8604
8605  let hasSideEffects = 0;
8606}
8607
8608//===----------------------------------------------------------------------===//
8609// SVE2 Histogram Computation - Vector Group
8610//===----------------------------------------------------------------------===//
8611
8612class sve2_hist_gen_vector<bit sz, string asm, ZPRRegOp zprty>
8613: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
8614  asm, "\t$Zd, $Pg/z, $Zn, $Zm",
8615  "",
8616  []>, Sched<[]> {
8617  bits<5> Zd;
8618  bits<5> Zn;
8619  bits<3> Pg;
8620  bits<5> Zm;
8621  let Inst{31-23} = 0b010001011;
8622  let Inst{22}    = sz;
8623  let Inst{21}    = 0b1;
8624  let Inst{20-16} = Zm;
8625  let Inst{15-13} = 0b110;
8626  let Inst{12-10} = Pg;
8627  let Inst{9-5}   = Zn;
8628  let Inst{4-0}   = Zd;
8629
8630  let hasSideEffects = 0;
8631}
8632
8633multiclass sve2_hist_gen_vector<string asm, SDPatternOperator op> {
8634  def _S : sve2_hist_gen_vector<0b0, asm, ZPR32>;
8635  def _D : sve2_hist_gen_vector<0b1, asm, ZPR64>;
8636
8637  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
8638  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
8639}
8640
8641//===----------------------------------------------------------------------===//
8642// SVE2 Crypto Extensions Group
8643//===----------------------------------------------------------------------===//
8644
8645class sve2_crypto_cons_bin_op<bit opc, string asm, ZPRRegOp zprty>
8646: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
8647  asm, "\t$Zd, $Zn, $Zm",
8648  "",
8649  []>, Sched<[]> {
8650  bits<5> Zd;
8651  bits<5> Zn;
8652  bits<5> Zm;
8653  let Inst{31-21} = 0b01000101001;
8654  let Inst{20-16} = Zm;
8655  let Inst{15-11} = 0b11110;
8656  let Inst{10}    = opc;
8657  let Inst{9-5}   = Zn;
8658  let Inst{4-0}   = Zd;
8659
8660  let hasSideEffects = 0;
8661}
8662
8663multiclass sve2_crypto_cons_bin_op<bit opc, string asm, ZPRRegOp zprty,
8664                                   SDPatternOperator op, ValueType vt> {
8665  def NAME : sve2_crypto_cons_bin_op<opc, asm, zprty>;
8666  def : SVE_2_Op_Pat<vt, op, vt, vt, !cast<Instruction>(NAME)>;
8667}
8668
8669class sve2_crypto_des_bin_op<bits<2> opc, string asm, ZPRRegOp zprty>
8670: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm),
8671  asm, "\t$Zdn, $_Zdn, $Zm",
8672  "",
8673  []>, Sched<[]> {
8674  bits<5> Zdn;
8675  bits<5> Zm;
8676  let Inst{31-17} = 0b010001010010001;
8677  let Inst{16}    = opc{1};
8678  let Inst{15-11} = 0b11100;
8679  let Inst{10}    = opc{0};
8680  let Inst{9-5}   = Zm;
8681  let Inst{4-0}   = Zdn;
8682
8683  let Constraints = "$Zdn = $_Zdn";
8684  let hasSideEffects = 0;
8685}
8686
8687multiclass sve2_crypto_des_bin_op<bits<2> opc, string asm, ZPRRegOp zprty,
8688                                  SDPatternOperator op, ValueType vt> {
8689  def NAME : sve2_crypto_des_bin_op<opc, asm, zprty>;
8690  def : SVE_2_Op_Pat<vt, op, vt, vt, !cast<Instruction>(NAME)>;
8691}
8692
8693class sve2_crypto_unary_op<bit opc, string asm, ZPRRegOp zprty>
8694: I<(outs zprty:$Zdn), (ins zprty:$_Zdn),
8695  asm, "\t$Zdn, $_Zdn",
8696  "",
8697  []>, Sched<[]> {
8698  bits<5> Zdn;
8699  let Inst{31-11} = 0b010001010010000011100;
8700  let Inst{10}    = opc;
8701  let Inst{9-5}   = 0b00000;
8702  let Inst{4-0}   = Zdn;
8703
8704  let Constraints = "$Zdn = $_Zdn";
8705  let hasSideEffects = 0;
8706}
8707
8708multiclass sve2_crypto_unary_op<bit opc, string asm, SDPatternOperator op> {
8709  def NAME : sve2_crypto_unary_op<opc, asm, ZPR8>;
8710  def : SVE_1_Op_Pat<nxv16i8, op, nxv16i8, !cast<Instruction>(NAME)>;
8711}
8712
8713//===----------------------------------------------------------------------===//
8714// SVE BFloat16 Group
8715//===----------------------------------------------------------------------===//
8716
8717class sve_float_dot<bit bf, string asm>
8718: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
8719     asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8720  bits<5> Zda;
8721  bits<5> Zn;
8722  bits<5> Zm;
8723  let Inst{31-23} = 0b011001000;
8724  let Inst{22}    = bf;
8725  let Inst{21}    = 0b1;
8726  let Inst{20-16} = Zm;
8727  let Inst{15-10} = 0b100000;
8728  let Inst{9-5}   = Zn;
8729  let Inst{4-0}   = Zda;
8730
8731  let Constraints = "$Zda = $_Zda";
8732  let DestructiveInstType = DestructiveOther;
8733  let hasSideEffects = 0;
8734  let mayRaiseFPException = 1;
8735}
8736
8737multiclass sve_float_dot<bit bf, string asm, ValueType InVT, SDPatternOperator op> {
8738  def NAME : sve_float_dot<bf, asm>;
8739  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, InVT, InVT, !cast<Instruction>(NAME)>;
8740}
8741
8742class sve_float_dot_indexed<bit bf, string asm>
8743: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR3b16:$Zm, VectorIndexS32b:$iop),
8744    asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
8745  bits<5> Zda;
8746  bits<5> Zn;
8747  bits<3> Zm;
8748  bits<2> iop;
8749  let Inst{31-23} = 0b011001000;
8750  let Inst{22}    = bf;
8751  let Inst{21}    = 0b1;
8752  let Inst{20-19} = iop;
8753  let Inst{18-16} = Zm;
8754  let Inst{15-10} = 0b010000;
8755  let Inst{9-5}   = Zn;
8756  let Inst{4-0}   = Zda;
8757
8758  let Constraints = "$Zda = $_Zda";
8759  let DestructiveInstType = DestructiveOther;
8760  let hasSideEffects = 0;
8761  let mayRaiseFPException = 1;
8762}
8763
8764multiclass sve_float_dot_indexed<bit bf, string asm, ValueType InVT, SDPatternOperator op> {
8765  def NAME : sve_float_dot_indexed<bf, asm>;
8766  def : SVE_4_Op_Imm_Pat<nxv4f32, op, nxv4f32, InVT, InVT, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
8767}
8768
8769class sve_bfloat_matmul<string asm>
8770: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
8771  asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8772  bits<5> Zm;
8773  bits<5> Zda;
8774  bits<5> Zn;
8775  let Inst{31-21} = 0b01100100011;
8776  let Inst{20-16} = Zm;
8777  let Inst{15-10} = 0b111001;
8778  let Inst{9-5}   = Zn;
8779  let Inst{4-0}   = Zda;
8780
8781  let Constraints = "$Zda = $_Zda";
8782  let DestructiveInstType = DestructiveOther;
8783  let ElementSize = ElementSizeH;
8784  let hasSideEffects = 0;
8785  let mayRaiseFPException = 1;
8786}
8787
8788multiclass sve_bfloat_matmul<string asm, SDPatternOperator op> {
8789  def NAME : sve_bfloat_matmul<asm>;
8790  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv8bf16, nxv8bf16 ,!cast<Instruction>(NAME)>;
8791}
8792
8793class sve_bfloat_convert<bit N, string asm>
8794: I<(outs ZPR16:$Zd), (ins ZPR16:$_Zd, PPR3bAny:$Pg, ZPR32:$Zn),
8795  asm, "\t$Zd, $Pg/m, $Zn", "", []>, Sched<[]> {
8796  bits<5> Zd;
8797  bits<3> Pg;
8798  bits<5> Zn;
8799  let Inst{31-25} = 0b0110010;
8800  let Inst{24}    = N;
8801  let Inst{23-13} = 0b10001010101;
8802  let Inst{12-10} = Pg;
8803  let Inst{9-5}   = Zn;
8804  let Inst{4-0}   = Zd;
8805
8806  let Constraints = "$Zd = $_Zd";
8807  let DestructiveInstType = DestructiveOther;
8808  let ElementSize = ElementSizeS;
8809  let hasSideEffects = 0;
8810  let mayRaiseFPException = 1;
8811}
8812
8813multiclass sve_bfloat_convert<bit N, string asm, SDPatternOperator op> {
8814  def NAME : sve_bfloat_convert<N, asm>;
8815  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i1, nxv4f32, !cast<Instruction>(NAME)>;
8816}
8817
8818//===----------------------------------------------------------------------===//
8819// SVE Integer Matrix Multiply Group
8820//===----------------------------------------------------------------------===//
8821
8822class sve_int_matmul<bits<2> uns, string asm>
8823: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR8:$Zm), asm,
8824  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8825  bits<5> Zda;
8826  bits<5> Zn;
8827  bits<5> Zm;
8828  let Inst{31-24} = 0b01000101;
8829  let Inst{23-22} = uns;
8830  let Inst{21}    = 0;
8831  let Inst{20-16} = Zm;
8832  let Inst{15-10} = 0b100110;
8833  let Inst{9-5}   = Zn;
8834  let Inst{4-0}   = Zda;
8835
8836  let Constraints = "$Zda = $_Zda";
8837  let DestructiveInstType = DestructiveOther;
8838  let ElementSize = ZPR32.ElementSize;
8839  let hasSideEffects = 0;
8840}
8841
8842multiclass sve_int_matmul<bits<2> uns, string asm, SDPatternOperator op> {
8843  def NAME : sve_int_matmul<uns, asm>;
8844
8845  def : SVE_3_Op_Pat<nxv4i32, op , nxv4i32, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
8846}
8847
8848//===----------------------------------------------------------------------===//
8849// SVE Integer Dot Product Mixed Sign Group
8850//===----------------------------------------------------------------------===//
8851
8852class sve_int_dot_mixed<string asm>
8853: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR8:$Zm), asm,
8854  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8855  bits<5> Zda;
8856  bits<5> Zn;
8857  bits<5> Zm;
8858  let Inst{31-21} = 0b01000100100;
8859  let Inst{20-16} = Zm;
8860  let Inst{15-10} = 0b011110;
8861  let Inst{9-5}   = Zn;
8862  let Inst{4-0}   = Zda;
8863
8864  let Constraints = "$Zda = $_Zda";
8865  let DestructiveInstType = DestructiveOther;
8866  let ElementSize = ZPR32.ElementSize;
8867  let hasSideEffects = 0;
8868}
8869
8870multiclass sve_int_dot_mixed<string asm, SDPatternOperator op> {
8871  def NAME : sve_int_dot_mixed<asm>;
8872
8873  def : SVE_3_Op_Pat<nxv4i32, op , nxv4i32, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
8874}
8875
8876//===----------------------------------------------------------------------===//
8877// SVE Integer Dot Product Mixed Sign - Indexed Group
8878//===----------------------------------------------------------------------===//
8879
8880class sve_int_dot_mixed_indexed<bit U, string asm>
8881: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexS32b:$idx),
8882    asm, "\t$Zda, $Zn, $Zm$idx", "", []>, Sched<[]> {
8883  bits<5> Zda;
8884  bits<5> Zn;
8885  bits<3> Zm;
8886  bits<2> idx;
8887  let Inst{31-21} = 0b01000100101;
8888  let Inst{20-19} = idx;
8889  let Inst{18-16} = Zm;
8890  let Inst{15-11} = 0b00011;
8891  let Inst{10}    = U;
8892  let Inst{9-5}   = Zn;
8893  let Inst{4-0}   = Zda;
8894
8895  let Constraints = "$Zda = $_Zda";
8896  let DestructiveInstType = DestructiveOther;
8897  let ElementSize = ZPR32.ElementSize;
8898  let hasSideEffects = 0;
8899}
8900
8901multiclass sve_int_dot_mixed_indexed<bit U, string asm, SDPatternOperator op> {
8902  def NAME : sve_int_dot_mixed_indexed<U, asm>;
8903
8904  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv16i8, nxv16i8, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
8905}
8906
8907//===----------------------------------------------------------------------===//
8908// SVE Floating Point Matrix Multiply Accumulate Group
8909//===----------------------------------------------------------------------===//
8910
8911class sve_fp_matrix_mla<bit sz, string asm, ZPRRegOp zprty>
8912: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, zprty:$Zm),
8913    asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8914  bits<5> Zda;
8915  bits<5> Zn;
8916  bits<5> Zm;
8917  let Inst{31-23} = 0b011001001;
8918  let Inst{22}    = sz;
8919  let Inst{21}    = 1;
8920  let Inst{20-16} = Zm;
8921  let Inst{15-10} = 0b111001;
8922  let Inst{9-5}   = Zn;
8923  let Inst{4-0}   = Zda;
8924
8925  let Constraints = "$Zda = $_Zda";
8926  let DestructiveInstType = DestructiveOther;
8927  let ElementSize = zprty.ElementSize;
8928  let hasSideEffects = 0;
8929  let mayRaiseFPException = 1;
8930}
8931
8932multiclass sve_fp_matrix_mla<bit sz, string asm, ZPRRegOp zprty, SDPatternOperator op, ValueType vt> {
8933  def NAME : sve_fp_matrix_mla<sz, asm, zprty>;
8934
8935  def : SVE_3_Op_Pat<vt, op , vt, vt, vt, !cast<Instruction>(NAME)>;
8936}
8937
8938//===----------------------------------------------------------------------===//
8939// SVE Memory - Contiguous Load And Replicate 256-bit Group
8940//===----------------------------------------------------------------------===//
8941
8942class sve_mem_ldor_si<bits<2> sz, string asm, RegisterOperand VecList>
8943: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s32:$imm4),
8944  asm, "\t$Zt, $Pg/z, [$Rn, $imm4]", "", []>, Sched<[]> {
8945  bits<5> Zt;
8946  bits<5> Rn;
8947  bits<3> Pg;
8948  bits<4> imm4;
8949  let Inst{31-25} = 0b1010010;
8950  let Inst{24-23} = sz;
8951  let Inst{22-20} = 0b010;
8952  let Inst{19-16} = imm4;
8953  let Inst{15-13} = 0b001;
8954  let Inst{12-10} = Pg;
8955  let Inst{9-5}   = Rn;
8956  let Inst{4-0}   = Zt;
8957
8958  let hasSideEffects = 0;
8959  let mayLoad = 1;
8960}
8961
8962multiclass sve_mem_ldor_si<bits<2> sz, string asm, RegisterOperand listty,
8963                           ZPRRegOp zprty, ValueType Ty, ValueType PredTy, SDNode Ld1ro> {
8964  def NAME : sve_mem_ldor_si<sz, asm, listty>;
8965  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
8966                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
8967  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
8968                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
8969  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4]",
8970                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s32:$imm4), 0>;
8971
8972  // Base addressing mode
8973  def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$Pg), GPR64sp:$base)),
8974            (!cast<Instruction>(NAME) PPR3bAny:$Pg, GPR64sp:$base, (i64 0))>;
8975  let AddedComplexity = 2 in {
8976    // Reg + Imm addressing mode
8977    def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$Pg), (add GPR64:$base, (i64 simm4s32:$imm)))),
8978              (!cast<Instruction>(NAME) $Pg, $base, simm4s32:$imm)>;
8979  }
8980}
8981
8982class sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand VecList,
8983                      RegisterOperand gprty>
8984: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
8985  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]", "", []>, Sched<[]> {
8986  bits<5> Zt;
8987  bits<3> Pg;
8988  bits<5> Rn;
8989  bits<5> Rm;
8990  let Inst{31-25} = 0b1010010;
8991  let Inst{24-23} = sz;
8992  let Inst{22-21} = 0b01;
8993  let Inst{20-16} = Rm;
8994  let Inst{15-13} = 0;
8995  let Inst{12-10} = Pg;
8996  let Inst{9-5}   = Rn;
8997  let Inst{4-0}   = Zt;
8998
8999  let hasSideEffects = 0;
9000  let mayLoad = 1;
9001}
9002
9003multiclass sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand listty,
9004                           ZPRRegOp zprty, RegisterOperand gprty, ValueType Ty,
9005                           ValueType PredTy, SDNode Ld1ro, ComplexPattern AddrCP> {
9006  def NAME : sve_mem_ldor_ss<sz, asm, listty, gprty>;
9007
9008  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
9009                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
9010
9011  def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$gp), (AddrCP GPR64sp:$base, gprty:$offset))),
9012            (!cast<Instruction>(NAME) PPR3bAny:$gp, GPR64sp:$base, gprty:$offset)>;
9013}
9014
9015//===----------------------------------------------------------------------===//
9016// SVE Interleave 128-bit Elements Group
9017//===----------------------------------------------------------------------===//
9018
9019class sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm>
9020: I<(outs ZPR128:$Zd), (ins ZPR128:$Zn, ZPR128:$Zm),
9021  asm, "\t$Zd, $Zn, $Zm",
9022  "",
9023  []>, Sched<[]> {
9024  bits<5> Zd;
9025  bits<5> Zm;
9026  bits<5> Zn;
9027  let Inst{31-21} = 0b00000101101;
9028  let Inst{20-16} = Zm;
9029  let Inst{15-13} = 0b000;
9030  let Inst{12-11} = opc;
9031  let Inst{10}    = P;
9032  let Inst{9-5}   = Zn;
9033  let Inst{4-0}   = Zd;
9034
9035  let hasSideEffects = 0;
9036}
9037
9038multiclass sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm, SDPatternOperator op> {
9039  def NAME : sve_int_perm_bin_perm_128_zz<opc, P, asm>;
9040
9041  def : SVE_2_Op_Pat<nxv16i8,  op, nxv16i8,  nxv16i8,  !cast<Instruction>(NAME)>;
9042  def : SVE_2_Op_Pat<nxv8i16,  op, nxv8i16,  nxv8i16,  !cast<Instruction>(NAME)>;
9043  def : SVE_2_Op_Pat<nxv8f16,  op, nxv8f16,  nxv8f16,  !cast<Instruction>(NAME)>;
9044  def : SVE_2_Op_Pat<nxv4i32,  op, nxv4i32,  nxv4i32,  !cast<Instruction>(NAME)>;
9045  def : SVE_2_Op_Pat<nxv4f32,  op, nxv4f32,  nxv4f32,  !cast<Instruction>(NAME)>;
9046  def : SVE_2_Op_Pat<nxv2i64,  op, nxv2i64,  nxv2i64,  !cast<Instruction>(NAME)>;
9047  def : SVE_2_Op_Pat<nxv2f64,  op, nxv2f64,  nxv2f64,  !cast<Instruction>(NAME)>;
9048  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
9049}
9050
9051/// Addressing modes
9052def am_sve_indexed_s4 :ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-8,7>", [], [SDNPWantRoot]>;
9053def am_sve_indexed_s6 :ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-32,31>", [], [SDNPWantRoot]>;
9054
9055def am_sve_regreg_lsl0 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<0>", []>;
9056def am_sve_regreg_lsl1 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<1>", []>;
9057def am_sve_regreg_lsl2 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<2>", []>;
9058def am_sve_regreg_lsl3 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<3>", []>;
9059def am_sve_regreg_lsl4 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<4>", []>;
9060
9061// Predicated pseudo floating point two operand instructions.
9062multiclass sve_fp_bin_pred_hfd<SDPatternOperator op> {
9063  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9064  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9065  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9066
9067  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9068  def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9069  def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9070  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9071  def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9072  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9073}
9074
9075// Predicated pseudo floating point three operand instructions.
9076multiclass sve_fp_3op_pred_hfd<SDPatternOperator op> {
9077  def _H_UNDEF : PredThreeOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9078  def _S_UNDEF : PredThreeOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9079  def _D_UNDEF : PredThreeOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9080
9081  def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9082  def : SVE_4_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9083  def : SVE_4_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9084  def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S_UNDEF)>;
9085  def : SVE_4_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S_UNDEF)>;
9086  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D_UNDEF)>;
9087}
9088
9089// Predicated pseudo integer two operand instructions.
9090multiclass sve_int_bin_pred_bhsd<SDPatternOperator op> {
9091  def _B_UNDEF : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesUndef>;
9092  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9093  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9094  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9095
9096  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
9097  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9098  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9099  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9100}
9101
9102// As sve_int_bin_pred but when only i32 and i64 vector types are required.
9103multiclass sve_int_bin_pred_sd<SDPatternOperator op> {
9104  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9105  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9106
9107  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9108  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9109}
9110
9111// Predicated pseudo integer two operand instructions. Second operand is an
9112// immediate specified by imm_[bhsd].
9113multiclass sve_int_shift_pred_bhsd<SDPatternOperator op,
9114                                   ComplexPattern imm_b, ComplexPattern imm_h,
9115                                   ComplexPattern imm_s, ComplexPattern imm_d> {
9116  def _B_UNDEF : PredTwoOpImmPseudo<NAME # _B, ZPR8,  Operand<i32>, FalseLanesUndef>;
9117  def _H_UNDEF : PredTwoOpImmPseudo<NAME # _H, ZPR16, Operand<i32>, FalseLanesUndef>;
9118  def _S_UNDEF : PredTwoOpImmPseudo<NAME # _S, ZPR32, Operand<i32>, FalseLanesUndef>;
9119  def _D_UNDEF : PredTwoOpImmPseudo<NAME # _D, ZPR64, Operand<i32>, FalseLanesUndef>;
9120
9121  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, imm_b, !cast<Instruction>(NAME # _B_UNDEF)>;
9122  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, imm_h, !cast<Instruction>(NAME # _H_UNDEF)>;
9123  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, imm_s, !cast<Instruction>(NAME # _S_UNDEF)>;
9124  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, imm_d, !cast<Instruction>(NAME # _D_UNDEF)>;
9125}
9126
9127multiclass sve_int_bin_pred_all_active_bhsd<SDPatternOperator op> {
9128  def _B_UNDEF : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesUndef>;
9129  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9130  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9131  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9132
9133  def : SVE_2_Op_Pred_All_Active_Pt<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
9134  def : SVE_2_Op_Pred_All_Active_Pt<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9135  def : SVE_2_Op_Pred_All_Active_Pt<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9136  def : SVE_2_Op_Pred_All_Active_Pt<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9137}
9138
9139//===----------------------------------------------------------------------===//
9140// SME2 or SVE2.1 Instructions
9141//===----------------------------------------------------------------------===//
9142
9143class sve2p1_fclamp<string asm, bits<2> sz, ZPRRegOp zpr_ty>
9144    : I<(outs zpr_ty:$Zd), (ins zpr_ty:$_Zd, zpr_ty:$Zn, zpr_ty:$Zm),
9145        asm, "\t$Zd, $Zn, $Zm", "", []>,
9146      Sched<[]> {
9147  bits<5> Zm;
9148  bits<5> Zn;
9149  bits<5> Zd;
9150  let Inst{31-24} = 0b01100100;
9151  let Inst{23-22} = sz;
9152  let Inst{21}    = 0b1;
9153  let Inst{20-16} = Zm;
9154  let Inst{15-10} = 0b001001;
9155  let Inst{9-5}   = Zn;
9156  let Inst{4-0}   = Zd;
9157
9158  let Constraints = "$Zd = $_Zd";
9159  let DestructiveInstType = DestructiveOther;
9160  let ElementSize = zpr_ty.ElementSize;
9161  let hasSideEffects = 0;
9162}
9163
9164multiclass sve2p1_fclamp<string asm, SDPatternOperator op> {
9165  def _H : sve2p1_fclamp<asm, 0b01, ZPR16>;
9166  def _S : sve2p1_fclamp<asm, 0b10, ZPR32>;
9167  def _D : sve2p1_fclamp<asm, 0b11, ZPR64>;
9168
9169  def : SVE_3_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
9170  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
9171  def : SVE_3_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
9172}
9173
9174// SVE two-way dot product
9175class sve2p1_two_way_dot_vv<string mnemonic, bit u>
9176    : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
9177        mnemonic, "\t$Zda, $Zn, $Zm",
9178        "", []>, Sched<[]> {
9179  bits<5> Zda;
9180  bits<5> Zn;
9181  bits<5> Zm;
9182  let Inst{31-21} = 0b01000100000;
9183  let Inst{20-16} = Zm;
9184  let Inst{15-11} = 0b11001;
9185  let Inst{10}    = u;
9186  let Inst{9-5}   = Zn;
9187  let Inst{4-0}   = Zda;
9188
9189  let Constraints = "$Zda = $_Zda";
9190  let DestructiveInstType = DestructiveOther;
9191  let hasSideEffects = 0;
9192}
9193
9194multiclass sve2p1_two_way_dot_vv<string mnemonic, bit u, SDPatternOperator intrinsic> {
9195  def NAME : sve2p1_two_way_dot_vv<mnemonic, u>;
9196
9197  def : SVE_3_Op_Pat<nxv4i32, intrinsic, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
9198}
9199
9200// SVE two-way dot product (indexed)
9201class sve2p1_two_way_dot_vvi<string mnemonic, bit u>
9202    : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR3b16:$Zm, VectorIndexS32b:$i2),
9203        mnemonic, "\t$Zda, $Zn, $Zm$i2",
9204        "", []>, Sched<[]> {
9205  bits<5> Zda;
9206  bits<5> Zn;
9207  bits<3> Zm;
9208  bits<2> i2;
9209  let Inst{31-21} = 0b01000100100;
9210  let Inst{20-19} = i2;
9211  let Inst{18-16} = Zm;
9212  let Inst{15-11} = 0b11001;
9213  let Inst{10}    = u;
9214  let Inst{9-5}   = Zn;
9215  let Inst{4-0}   = Zda;
9216
9217  let Constraints = "$Zda = $_Zda";
9218  let DestructiveInstType = DestructiveOther;
9219  let hasSideEffects = 0;
9220}
9221
9222multiclass sve2p1_two_way_dot_vvi<string mnemonic, bit u, SDPatternOperator intrinsic> {
9223  def NAME : sve2p1_two_way_dot_vvi<mnemonic, u>;
9224
9225  def : SVE_4_Op_Imm_Pat<nxv4i32, intrinsic, nxv4i32, nxv8i16, nxv8i16, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
9226}
9227
9228class sve2p1_ptrue_pn<string mnemonic, bits<2> sz, PNRP8to15RegOp pnrty, SDPatternOperator op>
9229    : I<(outs pnrty:$PNd), (ins ), mnemonic, "\t$PNd",
9230        "", [(set pnrty:$PNd, (op))]>, Sched<[]> {
9231  bits<3> PNd;
9232  let Inst{31-24}  = 0b00100101;
9233  let Inst{23-22} = sz;
9234  let Inst{21-3}  = 0b1000000111100000010;
9235  let Inst{2-0}   = PNd;
9236
9237  let hasSideEffects = 0;
9238}
9239
9240
9241multiclass sve2p1_ptrue_pn<string mnemonic> {
9242 def _B : sve2p1_ptrue_pn<mnemonic, 0b00, PNR8_p8to15, int_aarch64_sve_ptrue_c8>;
9243 def _H : sve2p1_ptrue_pn<mnemonic, 0b01, PNR16_p8to15, int_aarch64_sve_ptrue_c16>;
9244 def _S : sve2p1_ptrue_pn<mnemonic, 0b10, PNR32_p8to15, int_aarch64_sve_ptrue_c32>;
9245 def _D : sve2p1_ptrue_pn<mnemonic, 0b11, PNR64_p8to15, int_aarch64_sve_ptrue_c64>;
9246}
9247
9248
9249// SVE extract mask predicate from predicate-as-counter
9250class sve2p1_pred_as_ctr_to_mask_base<string mnemonic, bits<2> sz, bits<3> opc,
9251                                      RegisterOperand pprty, Operand idxty>
9252    : I<(outs pprty:$Pd), (ins PNRAny_p8to15:$PNn, idxty:$index),
9253        mnemonic, "\t$Pd, $PNn$index",
9254        "", []>, Sched<[]> {
9255  bits<4> Pd;
9256  bits<3> PNn;
9257  bits<2> imm2;
9258  let Inst{31-24} = 0b00100101;
9259  let Inst{23-22} = sz;
9260  let Inst{21-11} = 0b10000001110;
9261  let Inst{10-8}  = opc;
9262  let Inst{7-5}   = PNn;
9263  let Inst{4}     = 0b1;
9264  let Inst{3-0}   = Pd;
9265
9266  let hasSideEffects = 0;
9267}
9268
9269class sve2p1_pred_as_ctr_to_mask<string mnemonic, bits<2> sz, PPRRegOp pprty>
9270    : sve2p1_pred_as_ctr_to_mask_base<mnemonic, sz, {0, ?, ?}, pprty, VectorIndexS32b_timm> {
9271  bits<2> index;
9272  let Inst{9-8} = index;
9273}
9274
9275multiclass sve2p1_pred_as_ctr_to_mask<string mnemonic, SDPatternOperator op> {
9276 def _B : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b00, PPR8>;
9277 def _H : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b01, PPR16>;
9278 def _S : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b10, PPR32>;
9279 def _D : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b11, PPR64>;
9280
9281 def : SVE_2_Op_Imm_Pat<nxv16i1, op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _B)>;
9282 def : SVE_2_Op_Imm_Pat<nxv8i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _H)>;
9283 def : SVE_2_Op_Imm_Pat<nxv4i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
9284 def : SVE_2_Op_Imm_Pat<nxv2i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
9285}
9286
9287
9288class sve2p1_pred_as_ctr_to_mask_pair<string mnemonic, bits<2> sz, RegisterOperand pprty>
9289    : sve2p1_pred_as_ctr_to_mask_base<mnemonic, sz, {1, 0, ?}, pprty, VectorIndexD> {
9290  bit index;
9291  let Inst{8}    = index;
9292}
9293
9294multiclass sve2p1_pred_as_ctr_to_mask_pair<string mnemonic> {
9295 def _B : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b00, PP_b>;
9296 def _H : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b01, PP_h>;
9297 def _S : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b10, PP_s>;
9298 def _D : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b11, PP_d>;
9299}
9300
9301
9302// SME2 multi-vec extract narrow
9303class sve2p1_multi_vec_extract_narrow<string mnemonic, bits<2> opc, bits<3> tsz>
9304    : I<(outs ZPR16:$Zd), (ins ZZ_s_mul_r:$Zn),
9305        mnemonic, "\t$Zd, $Zn",
9306        "", []>, Sched<[]> {
9307  bits<5> Zd;
9308  bits<4> Zn;
9309  let Inst{31-23} = 0b010001010;
9310  let Inst{22}    = tsz{2};
9311  let Inst{21}    = 0b1;
9312  let Inst{20-19} = tsz{1-0};
9313  let Inst{18-13} = 0b001010;
9314  let Inst{12-11} = opc;
9315  let Inst{10}    = 0b0;
9316  let Inst{9-6}   = Zn;
9317  let Inst{5}     = 0b0;
9318  let Inst{4-0}   = Zd;
9319
9320  let hasSideEffects = 0;
9321}
9322
9323multiclass sve2p1_multi_vec_extract_narrow<string mnemonic, bits<2> opc, SDPatternOperator intrinsic> {
9324  def NAME : sve2p1_multi_vec_extract_narrow<mnemonic, opc, 0b010>;
9325  def : SVE2p1_Cvt_VG2_Pat<NAME, intrinsic, nxv8i16, nxv4i32>;
9326}
9327
9328// SVE2 multi-vec shift narrow
9329class sve2p1_multi_vec_shift_narrow<string mnemonic, bits<3> opc, bits<2> tsz>
9330    : I<(outs ZPR16:$Zd), (ins ZZ_s_mul_r:$Zn, tvecshiftR16:$imm4),
9331        mnemonic, "\t$Zd, $Zn, $imm4",
9332        "", []>, Sched<[]> {
9333  bits<5> Zd;
9334  bits<4> Zn;
9335  bits<4> imm4;
9336  let Inst{31-23} = 0b010001011;
9337  let Inst{22}    = tsz{1};
9338  let Inst{21}    = 0b1;
9339  let Inst{20}    = tsz{0};
9340  let Inst{19-16} = imm4;
9341  let Inst{15-14} = 0b00;
9342  let Inst{13-11} = opc;
9343  let Inst{10}    = 0b0;
9344  let Inst{9-6}   = Zn;
9345  let Inst{5}     = 0b0;
9346  let Inst{4-0}   = Zd;
9347
9348  let hasSideEffects = 0;
9349}
9350
9351multiclass sve2p1_multi_vec_shift_narrow<string mnemonic, bits<3> opc, SDPatternOperator intrinsic> {
9352  def NAME : sve2p1_multi_vec_shift_narrow<mnemonic, opc, 0b01>;
9353
9354  def : SVE2p1_Sat_Shift_VG2_Pat<NAME, intrinsic, nxv8i16, nxv4i32, tvecshiftR16>;
9355}
9356
9357
9358// SME2 multi-vec contiguous load (scalar plus scalar, two registers)
9359class sve2p1_mem_cld_ss_2z<string mnemonic, bits<2> msz, bit n,
9360                         RegisterOperand vector_ty, RegisterOperand gpr_ty>
9361    : I<(outs vector_ty:$Zt),
9362        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9363        mnemonic, "\t$Zt, $PNg/z, [$Rn, $Rm]",
9364        "", []>, Sched<[]> {
9365  bits<4> Zt;
9366  bits<5> Rm;
9367  bits<5> Rn;
9368  bits<3> PNg;
9369  let Inst{31-21} = 0b10100000000;
9370  let Inst{20-16} = Rm;
9371  let Inst{15}    = 0b0;
9372  let Inst{14-13} = msz;
9373  let Inst{12-10} = PNg;
9374  let Inst{9-5} = Rn;
9375  let Inst{4-1} = Zt;
9376  let Inst{0}   = n;
9377
9378  let hasSideEffects = 0;
9379  let mayLoad = 1;
9380}
9381
9382// SME2 multi-vec contiguous load (scalar plus immediate, two registers)
9383class sve2p1_mem_cld_si_2z<string mnemonic, bits<2> msz, bit n,
9384                         RegisterOperand vector_ty>
9385    : I<(outs vector_ty:$Zt),
9386        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4),
9387        mnemonic, "\t$Zt, $PNg/z, [$Rn, $imm4, mul vl]",
9388        "", []>, Sched<[]> {
9389  bits<4> Zt;
9390  bits<5> Rn;
9391  bits<3> PNg;
9392  bits<4> imm4;
9393  let Inst{31-20} = 0b101000000100;
9394  let Inst{19-16} = imm4;
9395  let Inst{15}    = 0b0;
9396  let Inst{14-13} = msz;
9397  let Inst{12-10} = PNg;
9398  let Inst{9-5}   = Rn;
9399  let Inst{4-1}   = Zt;
9400  let Inst{0}     = n;
9401
9402  let hasSideEffects = 0;
9403  let mayLoad = 1;
9404}
9405
9406multiclass sve2p1_mem_cld_si_2z<string mnemonic, bits<2> msz, bit n,
9407                              RegisterOperand vector_ty> {
9408  def NAME : sve2p1_mem_cld_si_2z<mnemonic, msz, n, vector_ty>;
9409
9410  def : InstAlias<mnemonic # " $Zt, $PNg/z, [$Rn]",
9411                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9412}
9413
9414// SME2 multi-vec contiguous load (scalar plus scalar, four registers)
9415class sve2p1_mem_cld_ss_4z<string mnemonic, bits<2> msz, bit n,
9416                         RegisterOperand vector_ty, RegisterOperand gpr_ty>
9417    : I<(outs vector_ty:$Zt),
9418        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9419        mnemonic, "\t$Zt, $PNg/z, [$Rn, $Rm]",
9420        "", []>, Sched<[]> {
9421  bits<3> Zt;
9422  bits<5> Rm;
9423  bits<5> Rn;
9424  bits<3> PNg;
9425  let Inst{31-21} = 0b10100000000;
9426  let Inst{20-16} = Rm;
9427  let Inst{15}    = 0b1;
9428  let Inst{14-13} = msz;
9429  let Inst{12-10} = PNg;
9430  let Inst{9-5} = Rn;
9431  let Inst{4-2} = Zt;
9432  let Inst{1}   = 0b0;
9433  let Inst{0}   = n;
9434
9435  let hasSideEffects = 0;
9436  let mayLoad = 1;
9437}
9438
9439// SME2 multi-vec contiguous load (scalar plus immediate, four registers)
9440class sve2p1_mem_cld_si_4z<string mnemonic, bits<2> msz, bit n,
9441                         RegisterOperand vector_ty>
9442    : I<(outs vector_ty:$Zt),
9443        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4),
9444        mnemonic, "\t$Zt, $PNg/z, [$Rn, $imm4, mul vl]",
9445        "", []>, Sched<[]> {
9446  bits<3> Zt;
9447  bits<5> Rn;
9448  bits<3> PNg;
9449  bits<4> imm4;
9450  let Inst{31-20} = 0b101000000100;
9451  let Inst{19-16} = imm4;
9452  let Inst{15}    = 0b1;
9453  let Inst{14-13} = msz;
9454  let Inst{12-10} = PNg;
9455  let Inst{9-5}   = Rn;
9456  let Inst{4-2}   = Zt;
9457  let Inst{1}     = 0b0;
9458  let Inst{0}     = n;
9459
9460  let hasSideEffects = 0;
9461  let mayLoad = 1;
9462}
9463
9464multiclass sve2p1_mem_cld_si_4z<string mnemonic, bits<2> msz, bit n,
9465                              RegisterOperand vector_ty> {
9466  def NAME : sve2p1_mem_cld_si_4z<mnemonic, msz, n, vector_ty>;
9467
9468  def : InstAlias<mnemonic # " $Zt, $PNg/z, [$Rn]",
9469                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9470}
9471
9472
9473// SME2 multi-vec contiguous store (scalar plus scalar, two registers)
9474class sve2p1_mem_cst_ss_2z<string mnemonic, bits<2> msz, bit n,
9475                           RegisterOperand vector_ty, RegisterOperand gpr_ty>
9476    : I<(outs ),
9477        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9478        mnemonic, "\t$Zt, $PNg, [$Rn, $Rm]",
9479        "", []>, Sched<[]> {
9480  bits<4> Zt;
9481  bits<5> Rm;
9482  bits<5> Rn;
9483  bits<3> PNg;
9484  let Inst{31-21} = 0b10100000001;
9485  let Inst{20-16} = Rm;
9486  let Inst{15}    = 0b0;
9487  let Inst{14-13} = msz;
9488  let Inst{12-10} = PNg;
9489  let Inst{9-5} = Rn;
9490  let Inst{4-1} = Zt;
9491  let Inst{0}   = n;
9492
9493  let hasSideEffects = 0;
9494  let mayStore = 1;
9495}
9496
9497
9498// SME2 multi-vec contiguous store (scalar plus immediate, two registers)
9499class sve2p1_mem_cst_si_2z<string mnemonic, bits<2> msz, bit n,
9500                           RegisterOperand vector_ty>
9501    : I<(outs ),
9502        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4),
9503        mnemonic, "\t$Zt, $PNg, [$Rn, $imm4, mul vl]",
9504        "", []>, Sched<[]> {
9505  bits<4> Zt;
9506  bits<5> Rn;
9507  bits<3> PNg;
9508  bits<4> imm4;
9509  let Inst{31-20} = 0b101000000110;
9510  let Inst{19-16} = imm4;
9511  let Inst{15}    = 0b0;
9512  let Inst{14-13} = msz;
9513  let Inst{12-10} = PNg;
9514  let Inst{9-5}   = Rn;
9515  let Inst{4-1}   = Zt;
9516  let Inst{0}     = n;
9517
9518  let hasSideEffects = 0;
9519  let mayStore = 1;
9520}
9521
9522
9523multiclass sve2p1_mem_cst_si_2z<string mnemonic, bits<2> msz, bit n,
9524                              RegisterOperand vector_ty> {
9525  def NAME : sve2p1_mem_cst_si_2z<mnemonic, msz, n, vector_ty>;
9526
9527  def : InstAlias<mnemonic # " $Zt, $PNg, [$Rn]",
9528                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9529}
9530
9531
9532// SME2 multi-vec contiguous store (scalar plus scalar, four registers)
9533class sve2p1_mem_cst_ss_4z<string mnemonic, bits<2> msz, bit n,
9534                           RegisterOperand vector_ty, RegisterOperand gpr_ty>
9535    : I<(outs ),
9536        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9537        mnemonic, "\t$Zt, $PNg, [$Rn, $Rm]",
9538        "", []>, Sched<[]> {
9539  bits<3> Zt;
9540  bits<5> Rm;
9541  bits<5> Rn;
9542  bits<3> PNg;
9543  let Inst{31-21} = 0b10100000001;
9544  let Inst{20-16} = Rm;
9545  let Inst{15}    = 0b1;
9546  let Inst{14-13} = msz;
9547  let Inst{12-10} = PNg;
9548  let Inst{9-5} = Rn;
9549  let Inst{4-2} = Zt;
9550  let Inst{1}   = 0b0;
9551  let Inst{0}   = n;
9552
9553  let mayStore = 1;
9554}
9555
9556
9557// SME2 multi-vec contiguous store (scalar plus immediate, four registers)
9558class sve2p1_mem_cst_si_4z<string mnemonic, bits<2> msz, bit n,
9559                           RegisterOperand vector_ty>
9560    : I<(outs ),
9561        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4),
9562        mnemonic, "\t$Zt, $PNg, [$Rn, $imm4, mul vl]",
9563        "", []>, Sched<[]> {
9564  bits<3> Zt;
9565  bits<5> Rn;
9566  bits<3> PNg;
9567  bits<4> imm4;
9568  let Inst{31-20} = 0b101000000110;
9569  let Inst{19-16} = imm4;
9570  let Inst{15}    = 0b1;
9571  let Inst{14-13} = msz;
9572  let Inst{12-10} = PNg;
9573  let Inst{9-5}   = Rn;
9574  let Inst{4-2}   = Zt;
9575  let Inst{1}     = 0b0;
9576  let Inst{0}     = n;
9577
9578  let hasSideEffects = 0;
9579  let mayStore = 1;
9580}
9581
9582
9583multiclass sve2p1_mem_cst_si_4z<string mnemonic, bits<2> msz, bit n,
9584                                RegisterOperand vector_ty> {
9585  def NAME : sve2p1_mem_cst_si_4z<mnemonic, msz, n, vector_ty>;
9586
9587  def : InstAlias<mnemonic # " $Zt, $PNg, [$Rn]",
9588                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn,0), 1>;
9589}
9590
9591// SVE predicate count (predicate-as-counter)
9592class sve2p1_pcount_pn<string mnemonic, bits<3> opc, bits<2> sz, PNRRegOp pnrty>
9593   : I<(outs GPR64:$Rd),
9594       (ins pnrty:$PNn, sve_vec_len_specifier_enum:$vl),
9595       mnemonic, "\t$Rd, $PNn, $vl",
9596       "", []>, Sched<[]> {
9597  bits<5> Rd;
9598  bits<4> PNn;
9599  bits<1> vl;
9600  let Inst{31-24} = 0b00100101;
9601  let Inst{23-22} = sz;
9602  let Inst{21-19} = 0b100;
9603  let Inst{18-16} = opc;
9604  let Inst{15-11} = 0b10000;
9605  let Inst{10}    = vl;
9606  let Inst{9}     = 0b1;
9607  let Inst{8-5}   = PNn;
9608  let Inst{4-0}   = Rd;
9609
9610  let hasSideEffects = 0;
9611}
9612
9613multiclass sve2p1_pcount_pn<string mnemonic, bits<3> opc> {
9614  def _B : sve2p1_pcount_pn<mnemonic, opc, 0b00, PNR8>;
9615  def _H : sve2p1_pcount_pn<mnemonic, opc, 0b01, PNR16>;
9616  def _S : sve2p1_pcount_pn<mnemonic, opc, 0b10, PNR32>;
9617  def _D : sve2p1_pcount_pn<mnemonic, opc, 0b11, PNR64>;
9618
9619  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c8,  aarch64svcount, !cast<Instruction>(NAME # _B)>;
9620  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c16, aarch64svcount, !cast<Instruction>(NAME # _H)>;
9621  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c32, aarch64svcount, !cast<Instruction>(NAME # _S)>;
9622  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c64, aarch64svcount, !cast<Instruction>(NAME # _D)>;
9623}
9624
9625
9626// SVE integer compare scalar count and limit (predicate-as-counter)
9627class sve2p1_int_while_rr_pn<string mnemonic, bits<2> sz, bits<3> opc,
9628                             PNRP8to15RegOp pnrty>
9629    : I<(outs pnrty:$PNd), (ins GPR64:$Rn, GPR64:$Rm, sve_vec_len_specifier_enum:$vl),
9630        mnemonic, "\t$PNd, $Rn, $Rm, $vl",
9631        "", []>, Sched<[]> {
9632  bits<3> PNd;
9633  bits<5> Rn;
9634  bits<1> vl;
9635  bits<5> Rm;
9636  let Inst{31-24} = 0b00100101;
9637  let Inst{23-22} = sz;
9638  let Inst{21}    = 0b1;
9639  let Inst{20-16} = Rm;
9640  let Inst{15-14} = 0b01;
9641  let Inst{13}    = vl;
9642  let Inst{12}    = 0b0;
9643  let Inst{11-10} = opc{2-1};
9644  let Inst{9-5}   = Rn;
9645  let Inst{4}     = 0b1;
9646  let Inst{3}     = opc{0};
9647  let Inst{2-0}   = PNd;
9648
9649  let Defs = [NZCV];
9650  let hasSideEffects = 0;
9651}
9652
9653
9654multiclass sve2p1_int_while_rr_pn<string mnemonic, bits<3> opc> {
9655 def _B : sve2p1_int_while_rr_pn<mnemonic, 0b00, opc, PNR8_p8to15>;
9656 def _H : sve2p1_int_while_rr_pn<mnemonic, 0b01, opc, PNR16_p8to15>;
9657 def _S : sve2p1_int_while_rr_pn<mnemonic, 0b10, opc, PNR32_p8to15>;
9658 def _D : sve2p1_int_while_rr_pn<mnemonic, 0b11, opc, PNR64_p8to15>;
9659
9660 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c8"),
9661                            i64, !cast<Instruction>(NAME # _B)>;
9662 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c16"),
9663                            i64, !cast<Instruction>(NAME # _H)>;
9664 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c32"),
9665                            i64, !cast<Instruction>(NAME # _S)>;
9666 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c64"),
9667                            i64, !cast<Instruction>(NAME # _D)>;
9668}
9669
9670
9671// SVE integer compare scalar count and limit (predicate pair)
9672class sve2p1_int_while_rr_pair<string mnemonic, bits<2> sz, bits<3> opc,
9673                             RegisterOperand ppr_ty>
9674    : I<(outs ppr_ty:$Pd), (ins GPR64:$Rn, GPR64:$Rm),
9675        mnemonic, "\t$Pd, $Rn, $Rm",
9676        "", []>, Sched<[]> {
9677  bits<3> Pd;
9678  bits<5> Rn;
9679  bits<5> Rm;
9680  let Inst{31-24} = 0b00100101;
9681  let Inst{23-22} = sz;
9682  let Inst{21}    = 0b1;
9683  let Inst{20-16} = Rm;
9684  let Inst{15-12} = 0b0101;
9685  let Inst{11-10} = opc{2-1};
9686  let Inst{9-5}   = Rn;
9687  let Inst{4}     = 0b1;
9688  let Inst{3-1}   = Pd;
9689  let Inst{0}     = opc{0};
9690
9691  let Defs = [NZCV];
9692  let hasSideEffects = 0;
9693}
9694
9695
9696multiclass sve2p1_int_while_rr_pair<string mnemonic, bits<3> opc> {
9697 def _B : sve2p1_int_while_rr_pair<mnemonic, 0b00, opc, PP_b_mul_r>;
9698 def _H : sve2p1_int_while_rr_pair<mnemonic, 0b01, opc, PP_h_mul_r>;
9699 def _S : sve2p1_int_while_rr_pair<mnemonic, 0b10, opc, PP_s_mul_r>;
9700 def _D : sve2p1_int_while_rr_pair<mnemonic, 0b11, opc, PP_d_mul_r>;
9701}
9702
9703
9704class sve_mem_128b_gld_64_unscaled<string mnemonic>
9705    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
9706        mnemonic, "\t$Zt, $Pg/z, [$Zn, $Rm]",
9707        "", []>, Sched<[]> {
9708  bits<5> Zt;
9709  bits<5> Zn;
9710  bits<3> Pg;
9711  bits<5> Rm;
9712  let Inst{31-21} = 0b11000100000;
9713  let Inst{20-16} = Rm;
9714  let Inst{15-13} = 0b101;
9715  let Inst{12-10} = Pg;
9716  let Inst{9-5}   = Zn;
9717  let Inst{4-0}   = Zt;
9718
9719  let hasSideEffects = 0;
9720  let mayLoad = 1;
9721}
9722
9723
9724multiclass sve_mem_128b_gld_64_unscaled<string mnemonic> {
9725  def NAME : sve_mem_128b_gld_64_unscaled<mnemonic>;
9726
9727  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Zn]",
9728                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
9729}
9730
9731class sve_mem_sst_128b_64_unscaled<string mnemonic>
9732    : I<(outs ), (ins Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
9733        mnemonic, "\t$Zt, $Pg, [$Zn, $Rm]",
9734        "", []>, Sched<[]> {
9735  bits<5> Zt;
9736  bits<5> Zn;
9737  bits<3> Pg;
9738  bits<5> Rm;
9739  let Inst{31-21} = 0b11100100001;
9740  let Inst{20-16} = Rm;
9741  let Inst{15-13} = 0b001;
9742  let Inst{12-10} = Pg;
9743  let Inst{9-5}   = Zn;
9744  let Inst{4-0}   = Zt;
9745
9746  let hasSideEffects = 0;
9747  let mayStore = 1;
9748}
9749
9750
9751multiclass sve_mem_sst_128b_64_unscaled<string mnemonic> {
9752  def NAME : sve_mem_sst_128b_64_unscaled<mnemonic>;
9753
9754  def : InstAlias<mnemonic # " $Zt, $Pg, [$Zn]",
9755                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
9756}
9757
9758
9759// SVE contiguous load (quadwords, scalar plus immediate)
9760class sve_mem_128b_cld_si<bits<2> dtype, string mnemonic>
9761    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
9762        mnemonic, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
9763        "", []>, Sched<[]> {
9764  bits<5> Zt;
9765  bits<5> Rn;
9766  bits<3> Pg;
9767  bits<4> imm4;
9768  let Inst{31-25} = 0b1010010;
9769  let Inst{24-23} = dtype;
9770  let Inst{22-20} = 0b001;
9771  let Inst{19-16} = imm4;
9772  let Inst{15-13} = 0b001;
9773  let Inst{12-10} = Pg;
9774  let Inst{9-5}   = Rn;
9775  let Inst{4-0}   = Zt;
9776
9777  let hasSideEffects = 0;
9778  let mayLoad = 1;
9779}
9780
9781multiclass sve_mem_128b_cld_si<bits<2> dtype, string mnemonic> {
9782  def NAME : sve_mem_128b_cld_si<dtype, mnemonic>;
9783
9784  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn]",
9785                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
9786  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn]",
9787                  (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
9788  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn, $imm4, mul vl]",
9789                  (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
9790}
9791
9792
9793// SVE contiguous load (quadwords, scalar plus scalar)
9794class sve_mem_128b_cld_ss<bits<2> dtype, string mnemonic, RegisterOperand gprsh_ty>
9795    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprsh_ty:$Rm),
9796        mnemonic, "\t$Zt, $Pg/z, [$Rn, $Rm]", "",
9797        []>, Sched<[]> {
9798  bits<5> Zt;
9799  bits<5> Rn;
9800  bits<3> Pg;
9801  bits<5> Rm;
9802  let Inst{31-25} = 0b1010010;
9803  let Inst{24-23} = dtype;
9804  let Inst{22-21} = 0b00;
9805  let Inst{20-16} = Rm;
9806  let Inst{15-13} = 0b100;
9807  let Inst{12-10} = Pg;
9808  let Inst{9-5}   = Rn;
9809  let Inst{4-0}   = Zt;
9810
9811  let hasSideEffects = 0;
9812  let mayLoad = 1;
9813}
9814
9815multiclass sve_mem_128b_cld_ss<bits<2> dtype, string mnemonic, RegisterOperand gprsh_ty> {
9816  def NAME : sve_mem_128b_cld_ss<dtype, mnemonic, gprsh_ty>;
9817
9818  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn, $Rm]",
9819                 (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprsh_ty:$Rm), 0>;
9820}
9821
9822
9823// SVE floating-point recursive reduction (quadwords)
9824class sve2p1_fp_reduction_q<bits<2> sz, bits<3> opc, string mnemonic,
9825                            RegisterOperand zpr_ty, string vec_sfx>
9826    : I<(outs V128:$Vd), (ins PPR3bAny:$Pg, zpr_ty:$Zn),
9827        mnemonic, "\t$Vd." # vec_sfx # ", $Pg, $Zn",
9828        "", []>, Sched<[]> {
9829  bits<5> Vd;
9830  bits<5> Zn;
9831  bits<3> Pg;
9832  let Inst{31-24} = 0b01100100;
9833  let Inst{23-22} = sz;
9834  let Inst{21-19} = 0b010;
9835  let Inst{18-16} = opc;
9836  let Inst{15-13} = 0b101;
9837  let Inst{12-10} = Pg;
9838  let Inst{9-5}   = Zn;
9839  let Inst{4-0}   = Vd;
9840
9841  let hasSideEffects = 0;
9842  let mayRaiseFPException = 1;
9843}
9844
9845multiclass sve2p1_fp_reduction_q<bits<3> opc, string mnemonic> {
9846  def _H : sve2p1_fp_reduction_q<0b01, opc, mnemonic, ZPR16, "8h">;
9847  def _S : sve2p1_fp_reduction_q<0b10, opc, mnemonic, ZPR32, "4s">;
9848  def _D : sve2p1_fp_reduction_q<0b11, opc, mnemonic, ZPR64, "2d">;
9849}
9850
9851
9852// SVE Permute Vector - Quadwords (DUPQ)
9853class sve2p1_dupq<bits<5> ind_tsz, string mnemonic, ZPRRegOp zprty, Operand itype>
9854    : I<(outs zprty:$Zd), (ins zprty:$Zn, itype:$index),
9855        mnemonic, "\t$Zd, $Zn$index",
9856        "", []>, Sched<[]> {
9857  bits<5> Zd;
9858  bits<5> Zn;
9859  let Inst{31-21} = 0b00000101001;
9860  let Inst{20-16} = ind_tsz;
9861  let Inst{15-10} = 0b001001;
9862  let Inst{9-5} = Zn;
9863  let Inst{4-0} = Zd;
9864
9865  let hasSideEffects = 0;
9866}
9867
9868multiclass sve2p1_dupq<string mnemonic> {
9869  def _B : sve2p1_dupq<{?, ?, ?, ?, 1}, mnemonic, ZPR8, VectorIndexB32b> {
9870    bits<4> index;
9871    let Inst{20-17} = index;
9872  }
9873  def _H : sve2p1_dupq<{?, ?, ?, 1, 0}, mnemonic, ZPR16, VectorIndexH32b> {
9874    bits<3> index;
9875    let Inst{20-18} = index;
9876  }
9877  def _S : sve2p1_dupq<{?, ?, 1, 0, 0}, mnemonic, ZPR32, VectorIndexS32b> {
9878    bits<2> index;
9879    let Inst{20-19} = index;
9880  }
9881  def _D : sve2p1_dupq<{?, 1, 0, 0, 0}, mnemonic, ZPR64, VectorIndexD32b> {
9882    bits<1> index;
9883    let Inst{20} = index;
9884  }
9885}
9886
9887
9888// SVE Permute Vector - Quadwords (EXTQ)
9889class sve2p1_extq<string mnemonic>
9890    : I<(outs ZPR8:$Zdn), (ins ZPR8:$_Zdn, ZPR8:$Zm, imm0_15:$imm4),
9891        mnemonic, "\t$Zdn, $_Zdn, $Zm, $imm4",
9892        "", []>, Sched<[]> {
9893  bits<5> Zdn;
9894  bits<5> Zm;
9895  bits<4> imm4;
9896  let Inst{31-20} = 0b000001010110;
9897  let Inst{19-16} = imm4;
9898  let Inst{15-10} = 0b001001;
9899  let Inst{9-5} = Zm;
9900  let Inst{4-0} = Zdn;
9901
9902  let Constraints = "$Zdn = $_Zdn";
9903  let DestructiveInstType = DestructiveOther;
9904  let ElementSize = ZPR8.ElementSize;
9905  let hasSideEffects = 0;
9906}
9907
9908
9909// SVE move predicate from vector
9910class sve2p1_vector_to_pred<bits<4> opc, string mnemonic,
9911                            PPRRegOp ppr_ty, Operand itype>
9912    : I<(outs ppr_ty:$Pd), (ins ZPRAny:$Zn, itype:$index),
9913        mnemonic, "\t$Pd, $Zn$index",
9914        "", []>, Sched<[]> {
9915  bits<4> Pd;
9916  bits<5> Zn;
9917  let Inst{31-24} = 0b00000101;
9918  let Inst{23-22} = opc{3-2};
9919  let Inst{21-19} = 0b101;
9920  let Inst{18-17} = opc{1-0};
9921  let Inst{16-10} = 0b0001110;
9922  let Inst{9-5}   = Zn;
9923  let Inst{4}     = 0b0;
9924  let Inst{3-0}   = Pd;
9925
9926  let hasSideEffects = 0;
9927}
9928
9929multiclass sve2p1_vector_to_pred<string mnemonic> {
9930  def _B : sve2p1_vector_to_pred<{0, 0, 0, 1}, mnemonic, PPR8,  VectorIndex0>;
9931  def _H : sve2p1_vector_to_pred<{0, 0, 1, ?}, mnemonic, PPR16, VectorIndexD32b> {
9932    bits<1> index;
9933    let Inst{17} = index;
9934  }
9935  def _S : sve2p1_vector_to_pred<{0, 1, ?, ?}, mnemonic, PPR32, VectorIndexS32b> {
9936    bits<2> index;
9937    let Inst{18-17} = index;
9938  }
9939  def _D : sve2p1_vector_to_pred<{1, ?, ?, ?}, mnemonic, PPR64, VectorIndexH32b> {
9940    bits<3> index;
9941    let Inst{22}    = index{2};
9942    let Inst{18-17} = index{1-0};
9943  }
9944
9945  def : InstAlias<mnemonic # "\t$Pd, $Zn",
9946                 (!cast<Instruction>(NAME # _B) PPR8:$Pd, ZPRAny:$Zn, 0), 1>;
9947}
9948
9949
9950// SVE move predicate into vector
9951class sve2p1_pred_to_vector<bits<4> opc, string mnemonic,
9952                            PPRRegOp ppr_ty, Operand itype>
9953    : I<(outs ZPRAny:$Zd), (ins ZPRAny:$_Zd, itype:$index, ppr_ty:$Pn),
9954        mnemonic, "\t$Zd$index, $Pn",
9955        "", []>, Sched<[]> {
9956  bits<5> Zd;
9957  bits<4> Pn;
9958  let Inst{31-24} = 0b00000101;
9959  let Inst{23-22} = opc{3-2};
9960  let Inst{21-19} = 0b101;
9961  let Inst{18-17} = opc{1-0};
9962  let Inst{16-9}  = 0b10011100;
9963  let Inst{8-5}   = Pn;
9964  let Inst{4-0}   = Zd;
9965
9966  let Constraints = "$Zd = $_Zd";
9967  let hasSideEffects = 0;
9968}
9969
9970multiclass sve2p1_pred_to_vector<string mnemonic> {
9971  def _B : sve2p1_pred_to_vector<{0, 0, 0, 1}, mnemonic, PPR8,  VectorIndex0>;
9972  def _H : sve2p1_pred_to_vector<{0, 0, 1, ?}, mnemonic, PPR16, VectorIndexD32b> {
9973    bits<1> index;
9974    let Inst{17} = index;
9975  }
9976  def _S : sve2p1_pred_to_vector<{0, 1, ?, ?}, mnemonic, PPR32, VectorIndexS32b> {
9977    bits<2> index;
9978    let Inst{18-17} = index;
9979  }
9980  def _D : sve2p1_pred_to_vector<{1, ?, ?, ?}, mnemonic, PPR64, VectorIndexH32b> {
9981    bits<3> index;
9982    let Inst{22}    = index{2};
9983    let Inst{18-17} = index{1-0};
9984  }
9985
9986  def : InstAlias<mnemonic # "\t$Zd, $Pn",
9987                 (!cast<Instruction>(NAME # _B) ZPRAny:$Zd, 0, PPR8:$Pn), 1>;
9988}
9989
9990
9991// SVE bitwise logical/add/min/max reductions (quadwords)
9992class sve2p1_int_reduce_q<bits<2> sz, bits<4> opc, string mnemonic,
9993                          RegisterOperand zpr_ty, string vec_sfx>
9994    : I<(outs V128:$Vd), (ins PPR3bAny:$Pg, zpr_ty:$Zn),
9995        mnemonic, "\t$Vd." # vec_sfx # ", $Pg, $Zn",
9996        "", []>, Sched<[]> {
9997  bits<5> Vd;
9998  bits<5> Zn;
9999  bits<3> Pg;
10000  let Inst{31-24} = 0b00000100;
10001  let Inst{23-22} = sz;
10002  let Inst{21}    = 0b0;
10003  let Inst{20-19} = opc{3-2};
10004  let Inst{18}    = 0b1;
10005  let Inst{17-16} = opc{1-0};
10006  let Inst{15-13} = 0b001;
10007  let Inst{12-10} = Pg;
10008  let Inst{9-5}   = Zn;
10009  let Inst{4-0}   = Vd;
10010
10011  let hasSideEffects = 0;
10012}
10013
10014multiclass sve2p1_int_reduce_q<bits<4> opc, string mnemonic> {
10015  def _B : sve2p1_int_reduce_q<0b00, opc, mnemonic, ZPR8,  "16b">;
10016  def _H : sve2p1_int_reduce_q<0b01, opc, mnemonic, ZPR16, "8h">;
10017  def _S : sve2p1_int_reduce_q<0b10, opc, mnemonic, ZPR32, "4s">;
10018  def _D : sve2p1_int_reduce_q<0b11, opc, mnemonic, ZPR64, "2d">;
10019}
10020
10021
10022// SVE permute vector elements (quadwords)
10023class sve2p1_permute_vec_elems_q<bits<2> sz, bits<3> opc, string mnemonic,
10024                                 ZPRRegOp zpr_ty, RegisterOperand src1_ty>
10025    : I<(outs zpr_ty:$Zd), (ins src1_ty:$Zn, zpr_ty:$Zm),
10026        mnemonic, "\t$Zd, $Zn, $Zm",
10027        "", []>, Sched<[]> {
10028  bits<5> Zd;
10029  bits<5> Zn;
10030  bits<5> Zm;
10031  let Inst{31-24} = 0b01000100;
10032  let Inst{23-22} = sz;
10033  let Inst{21}    = 0b0;
10034  let Inst{20-16} = Zm;
10035  let Inst{15-13} = 0b111;
10036  let Inst{12-10} = opc;
10037  let Inst{9-5}   = Zn;
10038  let Inst{4-0}   = Zd;
10039
10040  let hasSideEffects = 0;
10041}
10042
10043multiclass sve2p1_permute_vec_elems_q<bits<3> opc, string mnemonic> {
10044  def _B : sve2p1_permute_vec_elems_q<0b00, opc, mnemonic, ZPR8,  ZPR8>;
10045  def _H : sve2p1_permute_vec_elems_q<0b01, opc, mnemonic, ZPR16, ZPR16>;
10046  def _S : sve2p1_permute_vec_elems_q<0b10, opc, mnemonic, ZPR32, ZPR32>;
10047  def _D : sve2p1_permute_vec_elems_q<0b11, opc, mnemonic, ZPR64, ZPR64>;
10048}
10049
10050multiclass sve2p1_tblq<string mnemonic> {
10051  def _B : sve2p1_permute_vec_elems_q<0b00, 0b110, mnemonic, ZPR8,  Z_b>;
10052  def _H : sve2p1_permute_vec_elems_q<0b01, 0b110, mnemonic, ZPR16, Z_h>;
10053  def _S : sve2p1_permute_vec_elems_q<0b10, 0b110, mnemonic, ZPR32, Z_s>;
10054  def _D : sve2p1_permute_vec_elems_q<0b11, 0b110, mnemonic, ZPR64, Z_d>;
10055}
10056