xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AArch64/SVEInstrFormats.td (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
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 SVEAddSubSSatNegImm8Pat  : ComplexPattern<i32, 2, "SelectSVEAddSubSSatImm<MVT::i8, true>", []>;
253def SVEAddSubSSatNegImm16Pat : ComplexPattern<i32, 2, "SelectSVEAddSubSSatImm<MVT::i16, true>", []>;
254def SVEAddSubSSatNegImm32Pat : ComplexPattern<i32, 2, "SelectSVEAddSubSSatImm<MVT::i32, true>", []>;
255def SVEAddSubSSatNegImm64Pat : ComplexPattern<i64, 2, "SelectSVEAddSubSSatImm<MVT::i64, true>", []>;
256
257def SVEAddSubSSatPosImm8Pat  : ComplexPattern<i32, 2, "SelectSVEAddSubSSatImm<MVT::i8, false>", []>;
258def SVEAddSubSSatPosImm16Pat : ComplexPattern<i32, 2, "SelectSVEAddSubSSatImm<MVT::i16, false>", []>;
259def SVEAddSubSSatPosImm32Pat : ComplexPattern<i32, 2, "SelectSVEAddSubSSatImm<MVT::i32, false>", []>;
260def SVEAddSubSSatPosImm64Pat : ComplexPattern<i64, 2, "SelectSVEAddSubSSatImm<MVT::i64, false>", []>;
261
262def SVECpyDupImm8Pat  : ComplexPattern<i32, 2, "SelectSVECpyDupImm<MVT::i8>", []>;
263def SVECpyDupImm16Pat : ComplexPattern<i32, 2, "SelectSVECpyDupImm<MVT::i16>", []>;
264def SVECpyDupImm32Pat : ComplexPattern<i32, 2, "SelectSVECpyDupImm<MVT::i32>", []>;
265def SVECpyDupImm64Pat : ComplexPattern<i64, 2, "SelectSVECpyDupImm<MVT::i64>", []>;
266
267def SVELogicalImm8Pat  : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i8>", []>;
268def SVELogicalImm16Pat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i16>", []>;
269def SVELogicalImm32Pat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i32>", []>;
270def SVELogicalImm64Pat : ComplexPattern<i64, 1, "SelectSVELogicalImm<MVT::i64>", []>;
271
272def SVELogicalImm8NotPat  : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i8, true>", []>;
273def SVELogicalImm16NotPat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i16, true>", []>;
274def SVELogicalImm32NotPat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i32, true>", []>;
275def SVELogicalImm64NotPat : ComplexPattern<i64, 1, "SelectSVELogicalImm<MVT::i64, true>", []>;
276
277def SVEArithUImm8Pat  : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i8>", []>;
278def SVEArithUImm16Pat  : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i16>", []>;
279def SVEArithUImm32Pat  : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i32>", []>;
280def SVEArithUImm64Pat  : ComplexPattern<i64, 1, "SelectSVEArithImm<MVT::i64>", []>;
281
282def SVEArithSImmPat32 : ComplexPattern<i32, 1, "SelectSVESignedArithImm", []>;
283def SVEArithSImmPat64 : ComplexPattern<i64, 1, "SelectSVESignedArithImm", []>;
284
285def SVEShiftImmL8  : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 7>",  []>;
286def SVEShiftImmL16 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 15>", []>;
287def SVEShiftImmL32 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 31>", []>;
288def SVEShiftImmL64 : ComplexPattern<i64, 1, "SelectSVEShiftImm<0, 63>", []>;
289def SVEShiftImmR8  : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 8,  true>", []>;
290def SVEShiftImmR16 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 16, true>", []>;
291def SVEShiftImmR32 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 32, true>", []>;
292def SVEShiftImmR64 : ComplexPattern<i64, 1, "SelectSVEShiftImm<1, 64, true>", []>;
293
294def SVEShiftSplatImmR : ComplexPattern<iAny, 1, "SelectSVEShiftSplatImmR", []>;
295
296def SVEAllActive : ComplexPattern<untyped, 0, "SelectAllActivePredicate", []>;
297def SVEAnyPredicate : ComplexPattern<untyped, 0, "SelectAnyPredicate", []>;
298
299class SVEExactFPImm<string Suffix, string ValA, string ValB> : AsmOperandClass {
300  let Name = "SVEExactFPImmOperand" # Suffix;
301  let DiagnosticType = "Invalid" # Name;
302  let ParserMethod = "tryParseFPImm<false>";
303  let PredicateMethod = "isExactFPImm<" # ValA # ", " # ValB # ">";
304  let RenderMethod = "addExactFPImmOperands<" # ValA # ", " # ValB # ">";
305}
306
307class SVEExactFPImmOperand<string Suffix, string ValA, string ValB> : Operand<i32> {
308  let PrintMethod = "printExactFPImm<" # ValA # ", " # ValB # ">";
309  let ParserMatchClass = SVEExactFPImm<Suffix, ValA, ValB>;
310}
311
312def sve_fpimm_half_one
313    : SVEExactFPImmOperand<"HalfOne", "AArch64ExactFPImm::half",
314                           "AArch64ExactFPImm::one">;
315def sve_fpimm_half_two
316    : SVEExactFPImmOperand<"HalfTwo", "AArch64ExactFPImm::half",
317                           "AArch64ExactFPImm::two">;
318def sve_fpimm_zero_one
319    : SVEExactFPImmOperand<"ZeroOne", "AArch64ExactFPImm::zero",
320                           "AArch64ExactFPImm::one">;
321
322def sve_incdec_imm : Operand<i32>, TImmLeaf<i32, [{
323  return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
324}]> {
325  let ParserMatchClass = Imm1_16Operand;
326  let EncoderMethod = "getSVEIncDecImm";
327  let DecoderMethod = "DecodeSVEIncDecImm";
328}
329
330// This allows i32 immediate extraction from i64 based arithmetic.
331def sve_cnt_mul_imm_i32 : ComplexPattern<i32, 1, "SelectCntImm<1, 16, 1, false>">;
332def sve_cnt_mul_imm_i64 : ComplexPattern<i64, 1, "SelectCntImm<1, 16, 1, false>">;
333def sve_cnt_shl_imm     : ComplexPattern<i64, 1, "SelectCntImm<1, 16, 1, true>">;
334
335def sve_ext_imm_0_31  : ComplexPattern<i64, 1, "SelectEXTImm<31, 8>">;
336def sve_ext_imm_0_63  : ComplexPattern<i64, 1, "SelectEXTImm<63, 4>">;
337def sve_ext_imm_0_127 : ComplexPattern<i64, 1, "SelectEXTImm<127, 2>">;
338def sve_ext_imm_0_255 : ComplexPattern<i64, 1, "SelectEXTImm<255, 1>">;
339
340def int_aarch64_sve_cntp_oneuse : PatFrag<(ops node:$pred, node:$src2),
341                                          (int_aarch64_sve_cntp node:$pred, node:$src2), [{
342  return N->hasOneUse();
343}]>;
344
345def step_vector_oneuse : PatFrag<(ops node:$idx),
346                                 (step_vector node:$idx), [{
347  return N->hasOneUse();
348}]>;
349
350
351//===----------------------------------------------------------------------===//
352// SVE PTrue - These are used extensively throughout the pattern matching so
353//             it's important we define them first.
354//===----------------------------------------------------------------------===//
355
356class sve_int_ptrue<bits<2> sz8_64, bits<3> opc, string asm, PPRRegOp pprty,
357                    ValueType vt, SDPatternOperator op>
358: I<(outs pprty:$Pd), (ins sve_pred_enum:$pattern),
359  asm, "\t$Pd, $pattern",
360  "",
361  [(set (vt pprty:$Pd), (op sve_pred_enum:$pattern))]>, Sched<[]> {
362  bits<4> Pd;
363  bits<5> pattern;
364  let Inst{31-24} = 0b00100101;
365  let Inst{23-22} = sz8_64;
366  let Inst{21-19} = 0b011;
367  let Inst{18-17} = opc{2-1};
368  let Inst{16}    = opc{0};
369  let Inst{15-10} = 0b111000;
370  let Inst{9-5}   = pattern;
371  let Inst{4}     = 0b0;
372  let Inst{3-0}   = Pd;
373
374  let Defs = !if(!eq (opc{0}, 1), [NZCV], []);
375  let ElementSize = pprty.ElementSize;
376  let hasSideEffects = 0;
377  let isReMaterializable = 1;
378  let Uses = [VG];
379}
380
381multiclass sve_int_ptrue<bits<3> opc, string asm, SDPatternOperator op> {
382  def _B : sve_int_ptrue<0b00, opc, asm, PPR8, nxv16i1, op>;
383  def _H : sve_int_ptrue<0b01, opc, asm, PPR16, nxv8i1, op>;
384  def _S : sve_int_ptrue<0b10, opc, asm, PPR32, nxv4i1, op>;
385  def _D : sve_int_ptrue<0b11, opc, asm, PPR64, nxv2i1, op>;
386
387  def : InstAlias<asm # "\t$Pd",
388                  (!cast<Instruction>(NAME # _B) PPR8:$Pd, 0b11111), 1>;
389  def : InstAlias<asm # "\t$Pd",
390                  (!cast<Instruction>(NAME # _H) PPR16:$Pd, 0b11111), 1>;
391  def : InstAlias<asm # "\t$Pd",
392                  (!cast<Instruction>(NAME # _S) PPR32:$Pd, 0b11111), 1>;
393  def : InstAlias<asm # "\t$Pd",
394                  (!cast<Instruction>(NAME # _D) PPR64:$Pd, 0b11111), 1>;
395}
396
397def SDT_AArch64PTrue : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVT<1, i32>]>;
398def AArch64ptrue : SDNode<"AArch64ISD::PTRUE", SDT_AArch64PTrue>;
399
400let Predicates = [HasSVEorSME] in {
401  defm PTRUE  : sve_int_ptrue<0b000, "ptrue", AArch64ptrue>;
402  defm PTRUES : sve_int_ptrue<0b001, "ptrues", null_frag>;
403
404  def : Pat<(nxv16i1 immAllOnesV), (PTRUE_B 31)>;
405  def : Pat<(nxv8i1 immAllOnesV), (PTRUE_H 31)>;
406  def : Pat<(nxv4i1 immAllOnesV), (PTRUE_S 31)>;
407  def : Pat<(nxv2i1 immAllOnesV), (PTRUE_D 31)>;
408}
409
410//===----------------------------------------------------------------------===//
411// SVE pattern match helpers.
412//===----------------------------------------------------------------------===//
413
414class SVE_1_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
415                   Instruction inst>
416: Pat<(vtd (op vt1:$Op1)),
417      (inst $Op1)>;
418
419class SVE_1_Op_Passthru_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
420                            ValueType vts, Instruction inst>
421: Pat<(vtd (op pg:$Op1, vts:$Op2, vtd:$Op3)),
422      (inst $Op3, $Op1, $Op2)>;
423
424
425multiclass SVE_1_Op_PassthruUndef_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
426                                 ValueType vts, Instruction inst> {
427  def : Pat<(vtd (op pg:$Op1, vts:$Op2, (vtd undef))),
428            (inst (IMPLICIT_DEF), $Op1, $Op2)>;
429  def : Pat<(vtd (op (pg (SVEAllActive:$Op1)), vts:$Op2, vtd:$Op3)),
430            (inst $Op3, $Op1, $Op2)>;
431}
432
433// Used to match FP_ROUND_MERGE_PASSTHRU, which has an additional flag for the
434// type of rounding. This is matched by timm0_1 in pattern below and ignored.
435class SVE_1_Op_Passthru_Round_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
436                                  ValueType vts, Instruction inst>
437: Pat<(vtd (op pg:$Op1, vts:$Op2, (i64 timm0_1), vtd:$Op3)),
438      (inst $Op3, $Op1, $Op2)>;
439
440multiclass SVE_1_Op_PassthruUndef_Round_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
441                                  ValueType vts, Instruction inst>{
442  def : Pat<(vtd (op pg:$Op1, vts:$Op2, (i64 timm0_1), (vtd undef))),
443            (inst (IMPLICIT_DEF), $Op1, $Op2)>;
444  def : Pat<(vtd (op (pg (SVEAllActive:$Op1)), vts:$Op2, (i64 timm0_1), vtd:$Op3)),
445            (inst $Op3, $Op1, $Op2)>;
446}
447
448def SVEDup0 : ComplexPattern<vAny, 0, "SelectDupZero", []>;
449def SVEDupNeg0 : ComplexPattern<vAny, 0, "SelectDupNegativeZero", []>;
450
451class SVE_1_Op_PassthruZero_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
452                   ValueType vt2, Instruction inst>
453   : Pat<(vtd (op (vtd (SVEDup0)), vt1:$Op1, vt2:$Op2)),
454        (inst (IMPLICIT_DEF), $Op1, $Op2)>;
455
456class SVE_1_Op_Imm_OptLsl_Pat<ValueType vt, SDPatternOperator op, ZPRRegOp zprty,
457                              ValueType it, ComplexPattern cpx, Instruction inst>
458  : Pat<(vt (op (vt zprty:$Op1), (vt (splat_vector (it (cpx i32:$imm, i32:$shift)))))),
459        (inst $Op1, i32:$imm, i32:$shift)>;
460
461class SVE_1_Op_Imm_Arith_Any_Predicate<ValueType vt, ValueType pt,
462                                       SDPatternOperator op, ZPRRegOp zprty,
463                                       ValueType it, ComplexPattern cpx,
464                                       Instruction inst>
465  : Pat<(vt (op (pt (SVEAnyPredicate)), (vt zprty:$Op1), (vt (splat_vector (it (cpx i32:$imm)))))),
466        (inst $Op1, i32:$imm)>;
467
468class SVE_1_Op_Imm_Log_Pat<ValueType vt, SDPatternOperator op, ZPRRegOp zprty,
469                           ValueType it, ComplexPattern cpx, Instruction inst>
470  : Pat<(vt (op (vt zprty:$Op1), (vt (splat_vector (it (cpx i64:$imm)))))),
471        (inst $Op1, i64:$imm)>;
472
473class SVE_2_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
474                   ValueType vt2, Instruction inst>
475: Pat<(vtd (op vt1:$Op1, vt2:$Op2)),
476      (inst $Op1, $Op2)>;
477
478class SVE_2_Op_Pred_All_Active<ValueType vtd, SDPatternOperator op,
479                               ValueType pt, ValueType vt1, ValueType vt2,
480                               Instruction inst>
481: Pat<(vtd (op (pt (SVEAllActive)), vt1:$Op1, vt2:$Op2)),
482      (inst $Op1, $Op2)>;
483
484class SVE_2_Op_Pred_All_Active_Pt<ValueType vtd, SDPatternOperator op,
485                                  ValueType pt, ValueType vt1, ValueType vt2,
486                                  Instruction inst>
487: Pat<(vtd (op (pt (SVEAllActive:$Op1)), vt1:$Op2, vt2:$Op3)),
488      (inst $Op1, $Op2, $Op3)>;
489
490class SVE_3_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
491                   ValueType vt2, ValueType vt3, Instruction inst>
492: Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3)),
493      (inst $Op1, $Op2, $Op3)>;
494
495multiclass SVE_3_Op_Undef_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
496                              ValueType vt2, ValueType vt3, Instruction inst> {
497  def : Pat<(vtd (op (vt1 undef), vt2:$Op1, vt3:$Op2)),
498            (inst (IMPLICIT_DEF), $Op1, $Op2)>;
499  def : Pat<(vtd (op vt1:$Op1, (vt2 (SVEAllActive:$Op2)), vt3:$Op3)),
500            (inst $Op1, $Op2, $Op3)>;
501}
502
503class SVE_4_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
504                   ValueType vt2, ValueType vt3, ValueType vt4,
505                   Instruction inst>
506: Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3, vt4:$Op4)),
507      (inst $Op1, $Op2, $Op3, $Op4)>;
508
509class SVE_2_Op_Imm_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
510                       ValueType vt2, Operand ImmTy, Instruction inst>
511: Pat<(vtd (op vt1:$Op1, (vt2 ImmTy:$Op2))),
512      (inst $Op1, ImmTy:$Op2)>;
513
514multiclass SVE2p1_Cntp_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
515                           Instruction inst> {
516  def : Pat<(vtd (op vt1:$Op1, (i32 2))), (inst $Op1, 0)>;
517  def : Pat<(vtd (op vt1:$Op1, (i32 4))), (inst $Op1, 1)>;
518}
519
520multiclass SVE2p1_While_PN_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
521                               Instruction inst> {
522  def : Pat<(vtd (op vt1:$Op1, vt1:$Op2, (i32 2))), (inst $Op1, $Op2, 0)>;
523  def : Pat<(vtd (op vt1:$Op1, vt1:$Op2, (i32 4))), (inst $Op1, $Op2, 1)>;
524}
525
526class SVE_3_Op_Imm_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
527                       ValueType vt2, ValueType vt3, Operand ImmTy,
528                       Instruction inst>
529: Pat<(vtd (op vt1:$Op1, vt2:$Op2, (vt3 ImmTy:$Op3))),
530      (inst $Op1, $Op2, ImmTy:$Op3)>;
531
532class SVE_4_Op_Imm_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
533                       ValueType vt2, ValueType vt3, ValueType vt4,
534                       Operand ImmTy, Instruction inst>
535: Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3, (vt4 ImmTy:$Op4))),
536      (inst $Op1, $Op2, $Op3, ImmTy:$Op4)>;
537
538def SVEDup0Undef : ComplexPattern<vAny, 0, "SelectDupZeroOrUndef", []>;
539
540let AddedComplexity = 1 in {
541class SVE_3_Op_Pat_SelZero<ValueType vtd, SDPatternOperator op, ValueType vt1,
542                   ValueType vt2, ValueType vt3, Instruction inst>
543: Pat<(vtd (vtd (op vt1:$Op1, (vselect vt1:$Op1, vt2:$Op2, (SVEDup0)), vt3:$Op3))),
544      (inst $Op1, $Op2, $Op3)>;
545
546class SVE_3_Op_Pat_Shift_Imm_SelZero<ValueType vtd, SDPatternOperator op,
547                                     ValueType vt1, ValueType vt2,
548                                     Operand vt3, Instruction inst>
549: Pat<(vtd (op vt1:$Op1, (vselect vt1:$Op1, vt2:$Op2, (SVEDup0)), (i32 (vt3:$Op3)))),
550      (inst $Op1, $Op2, vt3:$Op3)>;
551}
552
553//
554// Common but less generic patterns.
555//
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
608class SVE_Shift_Add_All_Active_Pat<ValueType vtd, SDPatternOperator op, ValueType pt,
609                                   ValueType vt1, ValueType vt2, ValueType vt3,
610                                   Instruction inst>
611: Pat<(vtd (add vt1:$Op1, (op (pt (SVEAllActive)), vt2:$Op2, vt3:$Op3))),
612      (inst $Op1, $Op2, $Op3)>;
613
614class SVE2p1_Sat_Shift_VG2_Pat<string name, SDPatternOperator intrinsic, ValueType out_vt, ValueType in_vt, Operand imm_ty>
615    : Pat<(out_vt (intrinsic in_vt:$Zn1, in_vt:$Zn2, (i32 imm_ty:$i))),
616                  (!cast<Instruction>(name) (REG_SEQUENCE ZPR2Mul2, in_vt:$Zn1, zsub0, in_vt:$Zn2, zsub1), imm_ty:$i)>;
617
618class SVE2p1_Cvt_VG2_Pat<string name, SDPatternOperator intrinsic, ValueType out_vt, ValueType in_vt>
619    : Pat<(out_vt (intrinsic in_vt:$Zn1, in_vt:$Zn2)),
620                  (!cast<Instruction>(name) (REG_SEQUENCE ZPR2Mul2, in_vt:$Zn1, zsub0, in_vt:$Zn2, zsub1))>;
621
622//===----------------------------------------------------------------------===//
623// SVE pattern match helpers.
624//===----------------------------------------------------------------------===//
625
626// Matches either an intrinsic, or a predicated operation with an all active predicate
627class VSelectPredOrPassthruPatFrags<SDPatternOperator intrinsic, SDPatternOperator sdnode>
628: PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [
629    (intrinsic node:$Pg, node:$Op1, node:$Op2),
630    (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op1, node:$Op2), node:$Op1),
631  ], [{
632    return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse();
633  }]>;
634// Same as above with a commutative operation
635class VSelectCommPredOrPassthruPatFrags<SDPatternOperator intrinsic, SDPatternOperator sdnode>
636: PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [
637    (intrinsic node:$Pg, node:$Op1, node:$Op2),
638    (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op1, node:$Op2), node:$Op1),
639    (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op2, node:$Op1), node:$Op1),
640  ], [{
641    return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse();
642  }]>;
643// Similarly matches either an intrinsic, or an unpredicated operation with a select
644class VSelectUnpredOrPassthruPatFrags<SDPatternOperator intrinsic, SDPatternOperator sdnode>
645: PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [
646    (intrinsic node:$Pg, node:$Op1, node:$Op2),
647    (vselect node:$Pg, (sdnode node:$Op1, node:$Op2), node:$Op1),
648  ], [{
649    return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse();
650  }]>;
651
652//
653// Pseudo -> Instruction mappings
654//
655def getSVEPseudoMap : InstrMapping {
656  let FilterClass = "SVEPseudo2Instr";
657  let RowFields = ["PseudoName"];
658  let ColFields = ["IsInstr"];
659  let KeyCol = ["0"];
660  let ValueCols = [["1"]];
661}
662
663class SVEPseudo2Instr<string name, bit instr> {
664  string PseudoName = name;
665  bit IsInstr = instr;
666}
667
668// Lookup e.g. DIV -> DIVR
669def getSVERevInstr : InstrMapping {
670  let FilterClass = "SVEInstr2Rev";
671  let RowFields = ["InstrName"];
672  let ColFields = ["isReverseInstr"];
673  let KeyCol = ["0"];
674  let ValueCols = [["1"]];
675}
676
677// Lookup e.g. DIVR -> DIV
678def getSVENonRevInstr : InstrMapping {
679  let FilterClass = "SVEInstr2Rev";
680  let RowFields = ["InstrName"];
681  let ColFields = ["isReverseInstr"];
682  let KeyCol = ["1"];
683  let ValueCols = [["0"]];
684}
685
686class SVEInstr2Rev<string name1, string name2, bit name1IsReverseInstr> {
687  string InstrName = !if(name1IsReverseInstr, name1, name2);
688  bit isReverseInstr = name1IsReverseInstr;
689}
690
691//
692// Pseudos for destructive operands
693//
694let hasNoSchedulingInfo = 1 in {
695  class PredTwoOpPseudo<string name, ZPRRegOp zprty,
696                        FalseLanesEnum flags = FalseLanesNone>
697  : SVEPseudo2Instr<name, 0>,
698    Pseudo<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zs1, zprty:$Zs2), []> {
699    let FalseLanes = flags;
700  }
701
702  class PredTwoOpImmPseudo<string name, ZPRRegOp zprty, Operand immty,
703                           FalseLanesEnum flags = FalseLanesNone>
704  : SVEPseudo2Instr<name, 0>,
705    Pseudo<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zs1, immty:$imm), []> {
706    let FalseLanes = flags;
707  }
708
709  class PredThreeOpPseudo<string name, ZPRRegOp zprty,
710                          FalseLanesEnum flags = FalseLanesNone>
711  : SVEPseudo2Instr<name, 0>,
712    Pseudo<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zs1, zprty:$Zs2, zprty:$Zs3), []> {
713    let FalseLanes = flags;
714  }
715}
716
717//
718// Pseudos for passthru operands
719//
720let hasNoSchedulingInfo = 1 in {
721  class PredOneOpPassthruPseudo<string name, ZPRRegOp zprty,
722                                FalseLanesEnum flags = FalseLanesNone>
723  : SVEPseudo2Instr<name, 0>,
724    Pseudo<(outs zprty:$Zd), (ins zprty:$Passthru, PPR3bAny:$Pg, zprty:$Zs), []> {
725    let FalseLanes = flags;
726    let Constraints = !if(!eq(flags, FalseLanesZero), "$Zd = $Passthru,@earlyclobber $Zd", "");
727  }
728}
729
730//===----------------------------------------------------------------------===//
731// SVE Predicate Misc Group
732//===----------------------------------------------------------------------===//
733
734class sve_int_pfalse<bits<6> opc, string asm>
735: I<(outs PPRorPNR8:$Pd), (ins),
736  asm, "\t$Pd",
737  "",
738  []>, Sched<[]> {
739  bits<4> Pd;
740  let Inst{31-24} = 0b00100101;
741  let Inst{23-22} = opc{5-4};
742  let Inst{21-19} = 0b011;
743  let Inst{18-16} = opc{3-1};
744  let Inst{15-10} = 0b111001;
745  let Inst{9}     = opc{0};
746  let Inst{8-4}   = 0b00000;
747  let Inst{3-0}   = Pd;
748
749  let hasSideEffects = 0;
750  let isReMaterializable = 1;
751  let Uses = [VG];
752}
753
754multiclass sve_int_pfalse<bits<6> opc, string asm> {
755  def NAME : sve_int_pfalse<opc, asm>;
756
757  def : Pat<(nxv16i1 immAllZerosV), (!cast<Instruction>(NAME))>;
758  def : Pat<(nxv8i1 immAllZerosV), (!cast<Instruction>(NAME))>;
759  def : Pat<(nxv4i1 immAllZerosV), (!cast<Instruction>(NAME))>;
760  def : Pat<(nxv2i1 immAllZerosV), (!cast<Instruction>(NAME))>;
761  def : Pat<(nxv1i1 immAllZerosV), (!cast<Instruction>(NAME))>;
762}
763
764class sve_int_ptest<bits<6> opc, string asm, SDPatternOperator op>
765: I<(outs), (ins PPRAny:$Pg, PPR8:$Pn),
766  asm, "\t$Pg, $Pn",
767  "",
768  [(op (nxv16i1 PPRAny:$Pg), (nxv16i1 PPR8:$Pn))]>, Sched<[]> {
769  bits<4> Pg;
770  bits<4> Pn;
771  let Inst{31-24} = 0b00100101;
772  let Inst{23-22} = opc{5-4};
773  let Inst{21-19} = 0b010;
774  let Inst{18-16} = opc{3-1};
775  let Inst{15-14} = 0b11;
776  let Inst{13-10} = Pg;
777  let Inst{9}     = opc{0};
778  let Inst{8-5}   = Pn;
779  let Inst{4-0}   = 0b00000;
780
781  let Defs = [NZCV];
782  let hasSideEffects = 0;
783  let isCompare = 1;
784}
785
786multiclass sve_int_ptest<bits<6> opc, string asm, SDPatternOperator op,
787                         SDPatternOperator op_any> {
788  def NAME : sve_int_ptest<opc, asm, op>;
789
790  let hasNoSchedulingInfo = 1, isCompare = 1, Defs = [NZCV] in {
791  def _ANY : Pseudo<(outs), (ins PPRAny:$Pg, PPR8:$Pn),
792                    [(op_any (nxv16i1 PPRAny:$Pg), (nxv16i1 PPR8:$Pn))]>,
793             PseudoInstExpansion<(!cast<Instruction>(NAME) PPRAny:$Pg, PPR8:$Pn)>;
794  }
795}
796
797class sve_int_pfirst_next<bits<2> sz8_64, bits<5> opc, string asm,
798                          PPRRegOp pprty>
799: I<(outs pprty:$Pdn), (ins PPRAny:$Pg, pprty:$_Pdn),
800  asm, "\t$Pdn, $Pg, $_Pdn",
801  "",
802  []>, Sched<[]> {
803  bits<4> Pdn;
804  bits<4> Pg;
805  let Inst{31-24} = 0b00100101;
806  let Inst{23-22} = sz8_64;
807  let Inst{21-19} = 0b011;
808  let Inst{18-16} = opc{4-2};
809  let Inst{15-11} = 0b11000;
810  let Inst{10-9}  = opc{1-0};
811  let Inst{8-5}   = Pg;
812  let Inst{4}     = 0;
813  let Inst{3-0}   = Pdn;
814
815  let Constraints = "$Pdn = $_Pdn";
816  let Defs = [NZCV];
817  let ElementSize = pprty.ElementSize;
818  let hasSideEffects = 0;
819  let isPTestLike = 1;
820}
821
822multiclass sve_int_pfirst<bits<5> opc, string asm, SDPatternOperator op> {
823  def _B : sve_int_pfirst_next<0b01, opc, asm, PPR8>;
824
825  def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME # _B)>;
826}
827
828multiclass sve_int_pnext<bits<5> opc, string asm, SDPatternOperator op> {
829  def _B : sve_int_pfirst_next<0b00, opc, asm, PPR8>;
830  def _H : sve_int_pfirst_next<0b01, opc, asm, PPR16>;
831  def _S : sve_int_pfirst_next<0b10, opc, asm, PPR32>;
832  def _D : sve_int_pfirst_next<0b11, opc, asm, PPR64>;
833
834  def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME # _B)>;
835  def : SVE_2_Op_Pat<nxv8i1, op, nxv8i1, nxv8i1, !cast<Instruction>(NAME # _H)>;
836  def : SVE_2_Op_Pat<nxv4i1, op, nxv4i1, nxv4i1, !cast<Instruction>(NAME # _S)>;
837  def : SVE_2_Op_Pat<nxv2i1, op, nxv2i1, nxv2i1, !cast<Instruction>(NAME # _D)>;
838}
839
840//===----------------------------------------------------------------------===//
841// SVE Predicate Count Group
842//===----------------------------------------------------------------------===//
843
844class sve_int_count_r<bits<2> sz8_64, bits<5> opc, string asm,
845                      RegisterOperand dty, PPRRegOp pprty, RegisterOperand sty>
846: I<(outs dty:$Rdn), (ins pprty:$Pg, sty:$_Rdn),
847  asm, "\t$Rdn, $Pg",
848  "",
849  []>, Sched<[]> {
850  bits<5> Rdn;
851  bits<4> Pg;
852  let Inst{31-24} = 0b00100101;
853  let Inst{23-22} = sz8_64;
854  let Inst{21-19} = 0b101;
855  let Inst{18-16} = opc{4-2};
856  let Inst{15-11} = 0b10001;
857  let Inst{10-9}  = opc{1-0};
858  let Inst{8-5}   = Pg;
859  let Inst{4-0}   = Rdn;
860
861  // Signed 32bit forms require their GPR operand printed.
862  let AsmString = !if(!eq(opc{4,2-0}, 0b0000),
863                      !strconcat(asm, "\t$Rdn, $Pg, $_Rdn"),
864                      !strconcat(asm, "\t$Rdn, $Pg"));
865  let Constraints = "$Rdn = $_Rdn";
866  let hasSideEffects = 0;
867}
868
869multiclass sve_int_count_r_s32<bits<5> opc, string asm,
870                               SDPatternOperator op> {
871  def _B : sve_int_count_r<0b00, opc, asm, GPR64z, PPR8, GPR64as32>;
872  def _H : sve_int_count_r<0b01, opc, asm, GPR64z, PPR16, GPR64as32>;
873  def _S : sve_int_count_r<0b10, opc, asm, GPR64z, PPR32, GPR64as32>;
874  def _D : sve_int_count_r<0b11, opc, asm, GPR64z, PPR64, GPR64as32>;
875
876  def : Pat<(i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))),
877            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _B) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
878  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))))),
879            (!cast<Instruction>(NAME # _B) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
880
881  def : Pat<(i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))),
882            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _H) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
883  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))))),
884            (!cast<Instruction>(NAME # _H) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
885
886  def : Pat<(i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))),
887            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _S) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
888  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))))),
889            (!cast<Instruction>(NAME # _S) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
890
891  def : Pat<(i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))),
892            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _D) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
893  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))))),
894            (!cast<Instruction>(NAME # _D) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
895}
896
897multiclass sve_int_count_r_u32<bits<5> opc, string asm,
898                               SDPatternOperator op> {
899  def _B : sve_int_count_r<0b00, opc, asm, GPR32z, PPR8, GPR32z>;
900  def _H : sve_int_count_r<0b01, opc, asm, GPR32z, PPR16, GPR32z>;
901  def _S : sve_int_count_r<0b10, opc, asm, GPR32z, PPR32, GPR32z>;
902  def _D : sve_int_count_r<0b11, opc, asm, GPR32z, PPR64, GPR32z>;
903
904  def : Pat<(i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))),
905            (!cast<Instruction>(NAME # _B) PPRAny:$Pg, $Rn)>;
906  def : Pat<(i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))),
907            (!cast<Instruction>(NAME # _H) PPRAny:$Pg, $Rn)>;
908  def : Pat<(i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))),
909            (!cast<Instruction>(NAME # _S) PPRAny:$Pg, $Rn)>;
910  def : Pat<(i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))),
911            (!cast<Instruction>(NAME # _D) PPRAny:$Pg, $Rn)>;
912}
913
914multiclass sve_int_count_r_x64<bits<5> opc, string asm,
915                               SDPatternOperator op,
916                               SDPatternOperator combine_op = null_frag> {
917  def _B : sve_int_count_r<0b00, opc, asm, GPR64z, PPR8, GPR64z>;
918  def _H : sve_int_count_r<0b01, opc, asm, GPR64z, PPR16, GPR64z>;
919  def _S : sve_int_count_r<0b10, opc, asm, GPR64z, PPR32, GPR64z>;
920  def _D : sve_int_count_r<0b11, opc, asm, GPR64z, PPR64, GPR64z>;
921
922  def : Pat<(i64 (op GPR64:$Rn, (nxv16i1 PPRAny:$Pg))),
923            (!cast<Instruction>(NAME # _B) PPRAny:$Pg, $Rn)>;
924  def : Pat<(i64 (op GPR64:$Rn, (nxv8i1 PPRAny:$Pg))),
925            (!cast<Instruction>(NAME # _H) PPRAny:$Pg, $Rn)>;
926  def : Pat<(i64 (op GPR64:$Rn, (nxv4i1 PPRAny:$Pg))),
927            (!cast<Instruction>(NAME # _S) PPRAny:$Pg, $Rn)>;
928  def : Pat<(i64 (op GPR64:$Rn, (nxv2i1 PPRAny:$Pg))),
929            (!cast<Instruction>(NAME # _D) PPRAny:$Pg, $Rn)>;
930
931  // combine_op(x, cntp(all_active, p)) ==> inst p, x
932  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv16i1 (SVEAllActive)), (nxv16i1 PPRAny:$pred)))),
933            (!cast<Instruction>(NAME # _B) PPRAny:$pred, $Rn)>;
934  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv8i1 (SVEAllActive)), (nxv8i1 PPRAny:$pred)))),
935            (!cast<Instruction>(NAME # _H) PPRAny:$pred, $Rn)>;
936  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv4i1 (SVEAllActive)), (nxv4i1 PPRAny:$pred)))),
937            (!cast<Instruction>(NAME # _S) PPRAny:$pred, $Rn)>;
938  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv2i1 (SVEAllActive)), (nxv2i1 PPRAny:$pred)))),
939            (!cast<Instruction>(NAME # _D) PPRAny:$pred, $Rn)>;
940
941  // combine_op(x, cntp(p, p)) ==> inst p, x
942  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv16i1 PPRAny:$pred), (nxv16i1 PPRAny:$pred)))),
943            (!cast<Instruction>(NAME # _B) PPRAny:$pred, $Rn)>;
944  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv8i1 PPRAny:$pred), (nxv8i1 PPRAny:$pred)))),
945            (!cast<Instruction>(NAME # _H) PPRAny:$pred, $Rn)>;
946  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv4i1 PPRAny:$pred), (nxv4i1 PPRAny:$pred)))),
947            (!cast<Instruction>(NAME # _S) PPRAny:$pred, $Rn)>;
948  def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv2i1 PPRAny:$pred), (nxv2i1 PPRAny:$pred)))),
949            (!cast<Instruction>(NAME # _D) PPRAny:$pred, $Rn)>;
950
951  // combine_op(x, trunc(cntp(all_active, p))) ==> inst p, x
952  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv16i1 (SVEAllActive)), (nxv16i1 PPRAny:$pred))))),
953            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _B) PPRAny:$pred,
954                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
955                                 sub_32)>;
956  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv8i1 (SVEAllActive)), (nxv8i1 PPRAny:$pred))))),
957            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _H) PPRAny:$pred,
958                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
959                                 sub_32)>;
960  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv4i1 (SVEAllActive)), (nxv4i1 PPRAny:$pred))))),
961            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _S) PPRAny:$pred,
962                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
963                                 sub_32)>;
964  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv2i1 (SVEAllActive)), (nxv2i1 PPRAny:$pred))))),
965            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _D) PPRAny:$pred,
966                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
967                                 sub_32)>;
968
969  // combine_op(x, trunc(cntp(p, p))) ==> inst p, x
970  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv16i1 PPRAny:$pred), (nxv16i1 PPRAny:$pred))))),
971            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _B) PPRAny:$pred,
972                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
973                                 sub_32)>;
974  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv8i1 PPRAny:$pred), (nxv8i1 PPRAny:$pred))))),
975            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _H) PPRAny:$pred,
976                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
977                                 sub_32)>;
978  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv4i1 PPRAny:$pred), (nxv4i1 PPRAny:$pred))))),
979            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _S) PPRAny:$pred,
980                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
981                                 sub_32)>;
982  def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv2i1 PPRAny:$pred), (nxv2i1 PPRAny:$pred))))),
983            (EXTRACT_SUBREG (!cast<Instruction>(NAME # _D) PPRAny:$pred,
984                                     (INSERT_SUBREG (IMPLICIT_DEF), GPR32:$Rn, sub_32)),
985                                 sub_32)>;
986}
987
988class sve_int_count_v<bits<2> sz8_64, bits<5> opc, string asm,
989                      ZPRRegOp zprty, PPRRegOp pprty>
990: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, pprty:$Pm),
991  asm, "\t$Zdn, $Pm",
992  "",
993  []>, Sched<[]> {
994  bits<4> Pm;
995  bits<5> Zdn;
996  let Inst{31-24} = 0b00100101;
997  let Inst{23-22} = sz8_64;
998  let Inst{21-19} = 0b101;
999  let Inst{18-16} = opc{4-2};
1000  let Inst{15-11} = 0b10000;
1001  let Inst{10-9}  = opc{1-0};
1002  let Inst{8-5}   = Pm;
1003  let Inst{4-0}   = Zdn;
1004
1005  let Constraints = "$Zdn = $_Zdn";
1006  let DestructiveInstType = DestructiveOther;
1007  let ElementSize = ElementSizeNone;
1008  let hasSideEffects = 0;
1009}
1010
1011multiclass sve_int_count_v<bits<5> opc, string asm,
1012                           SDPatternOperator op = null_frag> {
1013  def _H : sve_int_count_v<0b01, opc, asm, ZPR16, PPR16>;
1014  def _S : sve_int_count_v<0b10, opc, asm, ZPR32, PPR32>;
1015  def _D : sve_int_count_v<0b11, opc, asm, ZPR64, PPR64>;
1016
1017  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16,  nxv8i1, !cast<Instruction>(NAME # _H)>;
1018  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32,  nxv4i1, !cast<Instruction>(NAME # _S)>;
1019  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64,  nxv2i1, !cast<Instruction>(NAME # _D)>;
1020
1021  def : InstAlias<asm # "\t$Zdn, $Pm",
1022                 (!cast<Instruction>(NAME # "_H") ZPR16:$Zdn, PPRAny:$Pm), 0>;
1023  def : InstAlias<asm # "\t$Zdn, $Pm",
1024                 (!cast<Instruction>(NAME # "_S") ZPR32:$Zdn, PPRAny:$Pm), 0>;
1025  def : InstAlias<asm # "\t$Zdn, $Pm",
1026                  (!cast<Instruction>(NAME # "_D") ZPR64:$Zdn, PPRAny:$Pm), 0>;
1027}
1028
1029class sve_int_pcount_pred<bits<2> sz8_64, bits<4> opc, string asm,
1030                          PPRRegOp pprty>
1031: I<(outs GPR64:$Rd), (ins PPRAny:$Pg, pprty:$Pn),
1032  asm, "\t$Rd, $Pg, $Pn",
1033  "",
1034  []>, Sched<[]> {
1035  bits<4> Pg;
1036  bits<4> Pn;
1037  bits<5> Rd;
1038  let Inst{31-24} = 0b00100101;
1039  let Inst{23-22} = sz8_64;
1040  let Inst{21-19} = 0b100;
1041  let Inst{18-16} = opc{3-1};
1042  let Inst{15-14} = 0b10;
1043  let Inst{13-10} = Pg;
1044  let Inst{9}     = opc{0};
1045  let Inst{8-5}   = Pn;
1046  let Inst{4-0}   = Rd;
1047
1048  let hasSideEffects = 0;
1049}
1050
1051multiclass sve_int_pcount_pred<bits<4> opc, string asm,
1052                               SDPatternOperator int_op> {
1053  def _B : sve_int_pcount_pred<0b00, opc, asm, PPR8>;
1054  def _H : sve_int_pcount_pred<0b01, opc, asm, PPR16>;
1055  def _S : sve_int_pcount_pred<0b10, opc, asm, PPR32>;
1056  def _D : sve_int_pcount_pred<0b11, opc, asm, PPR64>;
1057
1058  def : SVE_2_Op_Pat<i64, int_op, nxv16i1, nxv16i1, !cast<Instruction>(NAME # _B)>;
1059  def : SVE_2_Op_Pat<i64, int_op, nxv8i1,  nxv8i1,  !cast<Instruction>(NAME # _H)>;
1060  def : SVE_2_Op_Pat<i64, int_op, nxv4i1,  nxv4i1,  !cast<Instruction>(NAME # _S)>;
1061  def : SVE_2_Op_Pat<i64, int_op, nxv2i1,  nxv2i1,  !cast<Instruction>(NAME # _D)>;
1062}
1063
1064//===----------------------------------------------------------------------===//
1065// SVE Element Count Group
1066//===----------------------------------------------------------------------===//
1067
1068class sve_int_count<bits<3> opc, string asm>
1069: I<(outs GPR64:$Rd), (ins sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1070  asm, "\t$Rd, $pattern, mul $imm4",
1071  "",
1072  []>, Sched<[]> {
1073  bits<5> Rd;
1074  bits<4> imm4;
1075  bits<5> pattern;
1076  let Inst{31-24} = 0b00000100;
1077  let Inst{23-22} = opc{2-1};
1078  let Inst{21-20} = 0b10;
1079  let Inst{19-16} = imm4;
1080  let Inst{15-11} = 0b11100;
1081  let Inst{10}    = opc{0};
1082  let Inst{9-5}   = pattern;
1083  let Inst{4-0}   = Rd;
1084
1085  let hasSideEffects = 0;
1086  let isReMaterializable = 1;
1087  let Uses = [VG];
1088}
1089
1090multiclass sve_int_count<bits<3> opc, string asm, SDPatternOperator op> {
1091  def NAME : sve_int_count<opc, asm>;
1092
1093  def : InstAlias<asm # "\t$Rd, $pattern",
1094                  (!cast<Instruction>(NAME) GPR64:$Rd, sve_pred_enum:$pattern, 1), 1>;
1095  def : InstAlias<asm # "\t$Rd",
1096                  (!cast<Instruction>(NAME) GPR64:$Rd, 0b11111, 1), 2>;
1097
1098  def : Pat<(i64 (mul (op sve_pred_enum:$pattern), (sve_cnt_mul_imm_i64 i32:$imm))),
1099            (!cast<Instruction>(NAME) sve_pred_enum:$pattern, sve_incdec_imm:$imm)>;
1100
1101  def : Pat<(i64 (shl (op sve_pred_enum:$pattern), (sve_cnt_shl_imm i32:$imm))),
1102            (!cast<Instruction>(NAME) sve_pred_enum:$pattern, sve_incdec_imm:$imm)>;
1103
1104  def : Pat<(i64 (op sve_pred_enum:$pattern)),
1105            (!cast<Instruction>(NAME) sve_pred_enum:$pattern, 1)>;
1106}
1107
1108class sve_int_countvlv<bits<5> opc, string asm, ZPRRegOp zprty>
1109: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1110  asm, "\t$Zdn, $pattern, mul $imm4",
1111  "",
1112  []>, Sched<[]> {
1113  bits<5> Zdn;
1114  bits<5> pattern;
1115  bits<4> imm4;
1116  let Inst{31-24} = 0b00000100;
1117  let Inst{23-22} = opc{4-3};
1118  let Inst{21}    = 0b1;
1119  let Inst{20}    = opc{2};
1120  let Inst{19-16} = imm4;
1121  let Inst{15-12} = 0b1100;
1122  let Inst{11-10} = opc{1-0};
1123  let Inst{9-5}   = pattern;
1124  let Inst{4-0}   = Zdn;
1125
1126  let Constraints = "$Zdn = $_Zdn";
1127  let DestructiveInstType = DestructiveOther;
1128  let ElementSize = ElementSizeNone;
1129  let hasSideEffects = 0;
1130}
1131
1132multiclass sve_int_countvlv<bits<5> opc, string asm, ZPRRegOp zprty,
1133                            SDPatternOperator op = null_frag,
1134                            ValueType vt = OtherVT> {
1135  def NAME : sve_int_countvlv<opc, asm, zprty>;
1136
1137  def : InstAlias<asm # "\t$Zdn, $pattern",
1138                  (!cast<Instruction>(NAME) zprty:$Zdn, sve_pred_enum:$pattern, 1), 1>;
1139  def : InstAlias<asm # "\t$Zdn",
1140                  (!cast<Instruction>(NAME) zprty:$Zdn, 0b11111, 1), 2>;
1141
1142  def : Pat<(vt (op (vt zprty:$Zn), (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1143            (!cast<Instruction>(NAME) $Zn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1144}
1145
1146class sve_int_pred_pattern_a<bits<3> opc, string asm>
1147: I<(outs GPR64:$Rdn), (ins GPR64:$_Rdn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1148  asm, "\t$Rdn, $pattern, mul $imm4",
1149  "",
1150  []>, Sched<[]> {
1151  bits<5> Rdn;
1152  bits<5> pattern;
1153  bits<4> imm4;
1154  let Inst{31-24} = 0b00000100;
1155  let Inst{23-22} = opc{2-1};
1156  let Inst{21-20} = 0b11;
1157  let Inst{19-16} = imm4;
1158  let Inst{15-11} = 0b11100;
1159  let Inst{10}    = opc{0};
1160  let Inst{9-5}   = pattern;
1161  let Inst{4-0}   = Rdn;
1162
1163  let Constraints = "$Rdn = $_Rdn";
1164  let hasSideEffects = 0;
1165}
1166
1167multiclass sve_int_pred_pattern_a<bits<3> opc, string asm,
1168                                  SDPatternOperator op,
1169                                  SDPatternOperator opcnt> {
1170  let Predicates = [HasSVEorSME] in {
1171    def NAME : sve_int_pred_pattern_a<opc, asm>;
1172
1173    def : InstAlias<asm # "\t$Rdn, $pattern",
1174                    (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, 1), 1>;
1175    def : InstAlias<asm # "\t$Rdn",
1176                    (!cast<Instruction>(NAME) GPR64:$Rdn, 0b11111, 1), 2>;
1177  }
1178
1179  let Predicates = [HasSVEorSME, UseScalarIncVL] in {
1180    def : Pat<(i64 (op GPR64:$Rdn, (opcnt sve_pred_enum:$pattern))),
1181              (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, 1)>;
1182
1183    def : Pat<(i64 (op GPR64:$Rdn, (mul (opcnt sve_pred_enum:$pattern), (sve_cnt_mul_imm_i64 i32:$imm)))),
1184              (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, $imm)>;
1185
1186    def : Pat<(i64 (op GPR64:$Rdn, (shl (opcnt sve_pred_enum:$pattern), (sve_cnt_shl_imm i32:$imm)))),
1187              (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, $imm)>;
1188
1189    def : Pat<(i32 (op GPR32:$Rdn, (i32 (trunc (opcnt (sve_pred_enum:$pattern)))))),
1190              (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF),
1191                                               GPR32:$Rdn, sub_32), sve_pred_enum:$pattern, 1),
1192                                    sub_32)>;
1193
1194    def : Pat<(i32 (op GPR32:$Rdn, (mul (i32 (trunc (opcnt (sve_pred_enum:$pattern)))), (sve_cnt_mul_imm_i32 i32:$imm)))),
1195              (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF),
1196                                               GPR32:$Rdn, sub_32), sve_pred_enum:$pattern, $imm),
1197                                    sub_32)>;
1198
1199    def : Pat<(i32 (op GPR32:$Rdn, (shl (i32 (trunc (opcnt (sve_pred_enum:$pattern)))), (sve_cnt_shl_imm i32:$imm)))),
1200              (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF),
1201                                               GPR32:$Rdn, sub_32), sve_pred_enum:$pattern, $imm),
1202                                    sub_32)>;
1203  }
1204}
1205
1206class sve_int_pred_pattern_b<bits<5> opc, string asm, RegisterOperand dt,
1207                             RegisterOperand st>
1208: I<(outs dt:$Rdn), (ins st:$_Rdn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1209  asm, "\t$Rdn, $pattern, mul $imm4",
1210  "",
1211  []>, Sched<[]> {
1212  bits<5> Rdn;
1213  bits<5> pattern;
1214  bits<4> imm4;
1215  let Inst{31-24} = 0b00000100;
1216  let Inst{23-22} = opc{4-3};
1217  let Inst{21}    = 0b1;
1218  let Inst{20}    = opc{2};
1219  let Inst{19-16} = imm4;
1220  let Inst{15-12} = 0b1111;
1221  let Inst{11-10} = opc{1-0};
1222  let Inst{9-5}   = pattern;
1223  let Inst{4-0}   = Rdn;
1224
1225  // Signed 32bit forms require their GPR operand printed.
1226  let AsmString = !if(!eq(opc{2,0}, 0b00),
1227                      !strconcat(asm, "\t$Rdn, $_Rdn, $pattern, mul $imm4"),
1228                      !strconcat(asm, "\t$Rdn, $pattern, mul $imm4"));
1229
1230  let Constraints = "$Rdn = $_Rdn";
1231  let hasSideEffects = 0;
1232}
1233
1234multiclass sve_int_pred_pattern_b_s32<bits<5> opc, string asm,
1235                                      SDPatternOperator op> {
1236  def NAME : sve_int_pred_pattern_b<opc, asm, GPR64z, GPR64as32>;
1237
1238  def : InstAlias<asm # "\t$Rd, $Rn, $pattern",
1239                  (!cast<Instruction>(NAME) GPR64z:$Rd, GPR64as32:$Rn, sve_pred_enum:$pattern, 1), 1>;
1240  def : InstAlias<asm # "\t$Rd, $Rn",
1241                  (!cast<Instruction>(NAME) GPR64z:$Rd, GPR64as32:$Rn, 0b11111, 1), 2>;
1242
1243  // NOTE: Register allocation doesn't like tied operands of differing register
1244  //       class, hence the extra INSERT_SUBREG complication.
1245
1246  def : Pat<(i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1247            (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32), sve_pred_enum:$pattern, sve_incdec_imm:$imm4), sub_32)>;
1248  def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))))),
1249            (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32), sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1250}
1251
1252multiclass sve_int_pred_pattern_b_u32<bits<5> opc, string asm,
1253                                      SDPatternOperator op> {
1254  def NAME : sve_int_pred_pattern_b<opc, asm, GPR32z, GPR32z>;
1255
1256  def : InstAlias<asm # "\t$Rdn, $pattern",
1257                  (!cast<Instruction>(NAME) GPR32z:$Rdn, sve_pred_enum:$pattern, 1), 1>;
1258  def : InstAlias<asm # "\t$Rdn",
1259                  (!cast<Instruction>(NAME) GPR32z:$Rdn, 0b11111, 1), 2>;
1260
1261  def : Pat<(i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1262            (!cast<Instruction>(NAME) $Rn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1263}
1264
1265multiclass sve_int_pred_pattern_b_x64<bits<5> opc, string asm,
1266                                      SDPatternOperator op> {
1267  def NAME : sve_int_pred_pattern_b<opc, asm, GPR64z, GPR64z>;
1268
1269  def : InstAlias<asm # "\t$Rdn, $pattern",
1270                  (!cast<Instruction>(NAME) GPR64z:$Rdn, sve_pred_enum:$pattern, 1), 1>;
1271  def : InstAlias<asm # "\t$Rdn",
1272                  (!cast<Instruction>(NAME) GPR64z:$Rdn, 0b11111, 1), 2>;
1273
1274  def : Pat<(i64 (op GPR64:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1275            (!cast<Instruction>(NAME) $Rn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1276}
1277
1278
1279//===----------------------------------------------------------------------===//
1280// SVE Permute - Cross Lane Group
1281//===----------------------------------------------------------------------===//
1282
1283class sve_int_perm_dup_r<bits<2> sz8_64, string asm, ZPRRegOp zprty,
1284                         ValueType vt, RegisterClass srcRegType,
1285                         SDPatternOperator op>
1286: I<(outs zprty:$Zd), (ins srcRegType:$Rn),
1287  asm, "\t$Zd, $Rn",
1288  "",
1289  [(set (vt zprty:$Zd), (op srcRegType:$Rn))]>, Sched<[]> {
1290  bits<5> Rn;
1291  bits<5> Zd;
1292  let Inst{31-24} = 0b00000101;
1293  let Inst{23-22} = sz8_64;
1294  let Inst{21-10} = 0b100000001110;
1295  let Inst{9-5}   = Rn;
1296  let Inst{4-0}   = Zd;
1297
1298  let hasSideEffects = 0;
1299}
1300
1301multiclass sve_int_perm_dup_r<string asm, SDPatternOperator op> {
1302  def _B : sve_int_perm_dup_r<0b00, asm, ZPR8, nxv16i8, GPR32sp, op>;
1303  def _H : sve_int_perm_dup_r<0b01, asm, ZPR16, nxv8i16, GPR32sp, op>;
1304  def _S : sve_int_perm_dup_r<0b10, asm, ZPR32, nxv4i32, GPR32sp, op>;
1305  def _D : sve_int_perm_dup_r<0b11, asm, ZPR64, nxv2i64, GPR64sp, op>;
1306
1307  def : InstAlias<"mov $Zd, $Rn",
1308                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, GPR32sp:$Rn), 1>;
1309  def : InstAlias<"mov $Zd, $Rn",
1310                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, GPR32sp:$Rn), 1>;
1311  def : InstAlias<"mov $Zd, $Rn",
1312                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, GPR32sp:$Rn), 1>;
1313  def : InstAlias<"mov $Zd, $Rn",
1314                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, GPR64sp:$Rn), 1>;
1315}
1316
1317class sve_int_perm_dup_i<bits<5> tsz, Operand immtype, string asm,
1318                         ZPRRegOp zprty>
1319: I<(outs zprty:$Zd), (ins zprty:$Zn, immtype:$idx),
1320  asm, "\t$Zd, $Zn$idx",
1321  "",
1322  []>, Sched<[]> {
1323  bits<5> Zd;
1324  bits<5> Zn;
1325  bits<7> idx;
1326  let Inst{31-24} = 0b00000101;
1327  let Inst{23-22} = {?,?}; // imm3h
1328  let Inst{21}    = 0b1;
1329  let Inst{20-16} = tsz;
1330  let Inst{15-10} = 0b001000;
1331  let Inst{9-5}   = Zn;
1332  let Inst{4-0}   = Zd;
1333
1334  let hasSideEffects = 0;
1335}
1336
1337multiclass sve_int_perm_dup_i<string asm> {
1338  def _B : sve_int_perm_dup_i<{?,?,?,?,1}, sve_elm_idx_extdup_b, asm, ZPR8> {
1339    let Inst{23-22} = idx{5-4};
1340    let Inst{20-17} = idx{3-0};
1341  }
1342  def _H : sve_int_perm_dup_i<{?,?,?,1,0}, sve_elm_idx_extdup_h, asm, ZPR16> {
1343    let Inst{23-22} = idx{4-3};
1344    let Inst{20-18} = idx{2-0};
1345  }
1346  def _S : sve_int_perm_dup_i<{?,?,1,0,0}, sve_elm_idx_extdup_s, asm, ZPR32> {
1347    let Inst{23-22} = idx{3-2};
1348    let Inst{20-19}    = idx{1-0};
1349  }
1350  def _D : sve_int_perm_dup_i<{?,1,0,0,0}, sve_elm_idx_extdup_d, asm, ZPR64> {
1351    let Inst{23-22} = idx{2-1};
1352    let Inst{20}    = idx{0};
1353  }
1354  def _Q : sve_int_perm_dup_i<{1,0,0,0,0}, sve_elm_idx_extdup_q, asm, ZPR128> {
1355    let Inst{23-22} = idx{1-0};
1356  }
1357
1358  def : InstAlias<"mov $Zd, $Zn$idx",
1359                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, ZPR8:$Zn, sve_elm_idx_extdup_b:$idx), 1>;
1360  def : InstAlias<"mov $Zd, $Zn$idx",
1361                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, ZPR16:$Zn, sve_elm_idx_extdup_h:$idx), 1>;
1362  def : InstAlias<"mov $Zd, $Zn$idx",
1363                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, ZPR32:$Zn, sve_elm_idx_extdup_s:$idx), 1>;
1364  def : InstAlias<"mov $Zd, $Zn$idx",
1365                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, ZPR64:$Zn, sve_elm_idx_extdup_d:$idx), 1>;
1366  def : InstAlias<"mov $Zd, $Zn$idx",
1367                  (!cast<Instruction>(NAME # _Q) ZPR128:$Zd, ZPR128:$Zn, sve_elm_idx_extdup_q:$idx), 1>;
1368  def : InstAlias<"mov $Zd, $Bn",
1369                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, FPR8asZPR:$Bn, 0), 2>;
1370  def : InstAlias<"mov $Zd, $Hn",
1371                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, FPR16asZPR:$Hn, 0), 2>;
1372  def : InstAlias<"mov $Zd, $Sn",
1373                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, FPR32asZPR:$Sn, 0), 2>;
1374  def : InstAlias<"mov $Zd, $Dn",
1375                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, FPR64asZPR:$Dn, 0), 2>;
1376  def : InstAlias<"mov $Zd, $Qn",
1377                  (!cast<Instruction>(NAME # _Q) ZPR128:$Zd, FPR128asZPR:$Qn, 0), 2>;
1378
1379  // Duplicate extracted element of vector into all vector elements
1380  def : Pat<(nxv16i8 (splat_vector (i32 (vector_extract (nxv16i8 ZPR:$vec), sve_elm_idx_extdup_b:$index)))),
1381            (!cast<Instruction>(NAME # _B) ZPR:$vec, sve_elm_idx_extdup_b:$index)>;
1382  def : Pat<(nxv8i16 (splat_vector (i32 (vector_extract (nxv8i16 ZPR:$vec), sve_elm_idx_extdup_h:$index)))),
1383            (!cast<Instruction>(NAME # _H) ZPR:$vec, sve_elm_idx_extdup_h:$index)>;
1384  def : Pat<(nxv4i32 (splat_vector (i32 (vector_extract (nxv4i32 ZPR:$vec), sve_elm_idx_extdup_s:$index)))),
1385            (!cast<Instruction>(NAME # _S) ZPR:$vec, sve_elm_idx_extdup_s:$index)>;
1386  def : Pat<(nxv2i64 (splat_vector (i64 (vector_extract (nxv2i64 ZPR:$vec), sve_elm_idx_extdup_d:$index)))),
1387            (!cast<Instruction>(NAME # _D) ZPR:$vec, sve_elm_idx_extdup_d:$index)>;
1388  def : Pat<(nxv8f16 (splat_vector (f16 (vector_extract (nxv8f16 ZPR:$vec), sve_elm_idx_extdup_h:$index)))),
1389            (!cast<Instruction>(NAME # _H) ZPR:$vec, sve_elm_idx_extdup_h:$index)>;
1390  def : Pat<(nxv8bf16 (splat_vector (bf16 (vector_extract (nxv8bf16 ZPR:$vec), sve_elm_idx_extdup_h:$index)))),
1391            (!cast<Instruction>(NAME # _H) ZPR:$vec, sve_elm_idx_extdup_h:$index)>;
1392  def : Pat<(nxv4f16 (splat_vector (f16 (vector_extract (nxv4f16 ZPR:$vec), sve_elm_idx_extdup_s:$index)))),
1393            (!cast<Instruction>(NAME # _S) ZPR:$vec, sve_elm_idx_extdup_s:$index)>;
1394  def : Pat<(nxv2f16 (splat_vector (f16 (vector_extract (nxv2f16 ZPR:$vec), sve_elm_idx_extdup_d:$index)))),
1395            (!cast<Instruction>(NAME # _D) ZPR:$vec, sve_elm_idx_extdup_d:$index)>;
1396  def : Pat<(nxv4f32 (splat_vector (f32 (vector_extract (nxv4f32 ZPR:$vec), sve_elm_idx_extdup_s:$index)))),
1397            (!cast<Instruction>(NAME # _S) ZPR:$vec, sve_elm_idx_extdup_s:$index)>;
1398  def : Pat<(nxv2f32 (splat_vector (f32 (vector_extract (nxv2f32 ZPR:$vec), sve_elm_idx_extdup_d:$index)))),
1399            (!cast<Instruction>(NAME # _D) ZPR:$vec, sve_elm_idx_extdup_d:$index)>;
1400  def : Pat<(nxv2f64 (splat_vector (f64 (vector_extract (nxv2f64 ZPR:$vec), sve_elm_idx_extdup_d:$index)))),
1401            (!cast<Instruction>(NAME # _D) ZPR:$vec, sve_elm_idx_extdup_d:$index)>;
1402
1403  def : Pat<(nxv16i8 (AArch64duplane128 nxv16i8:$Op1, i64:$imm)),
1404            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1405  def : Pat<(nxv8i16 (AArch64duplane128 nxv8i16:$Op1, i64:$imm)),
1406            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1407  def : Pat<(nxv4i32 (AArch64duplane128 nxv4i32:$Op1, i64:$imm)),
1408            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1409  def : Pat<(nxv2i64 (AArch64duplane128 nxv2i64:$Op1, i64:$imm)),
1410            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1411  def : Pat<(nxv8f16 (AArch64duplane128 nxv8f16:$Op1, i64:$imm)),
1412            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1413  def : Pat<(nxv4f32 (AArch64duplane128 nxv4f32:$Op1, i64:$imm)),
1414            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1415  def : Pat<(nxv2f64 (AArch64duplane128 nxv2f64:$Op1, i64:$imm)),
1416            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1417  def : Pat<(nxv8bf16 (AArch64duplane128 nxv8bf16:$Op1, i64:$imm)),
1418            (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1419}
1420
1421class sve_int_perm_tbl<bits<2> sz8_64, bits<2> opc, string asm, ZPRRegOp zprty,
1422                       RegisterOperand VecList>
1423: I<(outs zprty:$Zd), (ins VecList:$Zn, zprty:$Zm),
1424  asm, "\t$Zd, $Zn, $Zm",
1425  "",
1426  []>, Sched<[]> {
1427  bits<5> Zd;
1428  bits<5> Zm;
1429  bits<5> Zn;
1430  let Inst{31-24} = 0b00000101;
1431  let Inst{23-22} = sz8_64;
1432  let Inst{21}    = 0b1;
1433  let Inst{20-16} = Zm;
1434  let Inst{15-13} = 0b001;
1435  let Inst{12-11} = opc;
1436  let Inst{10}    = 0b0;
1437  let Inst{9-5}   = Zn;
1438  let Inst{4-0}   = Zd;
1439
1440  let hasSideEffects = 0;
1441}
1442
1443multiclass sve_int_perm_tbl<string asm, SDPatternOperator op> {
1444  def _B : sve_int_perm_tbl<0b00, 0b10, asm, ZPR8,  Z_b>;
1445  def _H : sve_int_perm_tbl<0b01, 0b10, asm, ZPR16, Z_h>;
1446  def _S : sve_int_perm_tbl<0b10, 0b10, asm, ZPR32, Z_s>;
1447  def _D : sve_int_perm_tbl<0b11, 0b10, asm, ZPR64, Z_d>;
1448
1449  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1450                 (!cast<Instruction>(NAME # _B) ZPR8:$Zd, ZPR8:$Zn, ZPR8:$Zm), 0>;
1451  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1452                 (!cast<Instruction>(NAME # _H) ZPR16:$Zd, ZPR16:$Zn, ZPR16:$Zm), 0>;
1453  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1454                 (!cast<Instruction>(NAME # _S) ZPR32:$Zd, ZPR32:$Zn, ZPR32:$Zm), 0>;
1455  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1456                 (!cast<Instruction>(NAME # _D) ZPR64:$Zd, ZPR64:$Zn, ZPR64:$Zm), 0>;
1457
1458  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
1459  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1460  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1461  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1462
1463  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1464  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1465  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1466
1467  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1468}
1469
1470multiclass sve2_int_perm_tbl<string asm, SDPatternOperator op> {
1471  def _B : sve_int_perm_tbl<0b00, 0b01, asm, ZPR8,  ZZ_b>;
1472  def _H : sve_int_perm_tbl<0b01, 0b01, asm, ZPR16, ZZ_h>;
1473  def _S : sve_int_perm_tbl<0b10, 0b01, asm, ZPR32, ZZ_s>;
1474  def _D : sve_int_perm_tbl<0b11, 0b01, asm, ZPR64, ZZ_d>;
1475
1476  def : Pat<(nxv16i8 (op nxv16i8:$Op1, nxv16i8:$Op2, nxv16i8:$Op3)),
1477            (nxv16i8 (!cast<Instruction>(NAME # _B) (REG_SEQUENCE ZPR2, nxv16i8:$Op1, zsub0,
1478                                                                        nxv16i8:$Op2, zsub1),
1479                                                     nxv16i8:$Op3))>;
1480
1481  def : Pat<(nxv8i16 (op nxv8i16:$Op1, nxv8i16:$Op2, nxv8i16:$Op3)),
1482            (nxv8i16 (!cast<Instruction>(NAME # _H) (REG_SEQUENCE ZPR2, nxv8i16:$Op1, zsub0,
1483                                                                        nxv8i16:$Op2, zsub1),
1484                                                     nxv8i16:$Op3))>;
1485
1486  def : Pat<(nxv4i32 (op nxv4i32:$Op1, nxv4i32:$Op2, nxv4i32:$Op3)),
1487            (nxv4i32 (!cast<Instruction>(NAME # _S) (REG_SEQUENCE ZPR2, nxv4i32:$Op1, zsub0,
1488                                                                        nxv4i32:$Op2, zsub1),
1489                                                     nxv4i32:$Op3))>;
1490
1491  def : Pat<(nxv2i64 (op nxv2i64:$Op1, nxv2i64:$Op2, nxv2i64:$Op3)),
1492            (nxv2i64 (!cast<Instruction>(NAME # _D) (REG_SEQUENCE ZPR2, nxv2i64:$Op1, zsub0,
1493                                                                        nxv2i64:$Op2, zsub1),
1494                                                     nxv2i64:$Op3))>;
1495
1496  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8i16:$Op3)),
1497            (nxv8f16 (!cast<Instruction>(NAME # _H) (REG_SEQUENCE ZPR2, nxv8f16:$Op1, zsub0,
1498                                                                        nxv8f16:$Op2, zsub1),
1499                                                     nxv8i16:$Op3))>;
1500
1501  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4i32:$Op3)),
1502            (nxv4f32 (!cast<Instruction>(NAME # _S) (REG_SEQUENCE ZPR2, nxv4f32:$Op1, zsub0,
1503                                                                        nxv4f32:$Op2, zsub1),
1504                                                     nxv4i32:$Op3))>;
1505
1506  def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, nxv2i64:$Op3)),
1507            (nxv2f64 (!cast<Instruction>(NAME # _D) (REG_SEQUENCE ZPR2, nxv2f64:$Op1, zsub0,
1508                                                                        nxv2f64:$Op2, zsub1),
1509                                                     nxv2i64:$Op3))>;
1510
1511  def : Pat<(nxv8bf16 (op nxv8bf16:$Op1, nxv8bf16:$Op2, nxv8i16:$Op3)),
1512            (nxv8bf16 (!cast<Instruction>(NAME # _H) (REG_SEQUENCE ZPR2, nxv8bf16:$Op1, zsub0,
1513                                                                         nxv8bf16:$Op2, zsub1),
1514                                                      nxv8i16:$Op3))>;
1515}
1516
1517class sve2_int_perm_tbx<bits<2> sz8_64, bits<2> opc, string asm, ZPRRegOp zprty>
1518: I<(outs zprty:$Zd), (ins zprty:$_Zd, zprty:$Zn, zprty:$Zm),
1519  asm, "\t$Zd, $Zn, $Zm",
1520  "",
1521  []>, Sched<[]> {
1522  bits<5> Zd;
1523  bits<5> Zm;
1524  bits<5> Zn;
1525  let Inst{31-24} = 0b00000101;
1526  let Inst{23-22} = sz8_64;
1527  let Inst{21}    = 0b1;
1528  let Inst{20-16} = Zm;
1529  let Inst{15-13} = 0b001;
1530  let Inst{12-11} = opc;
1531  let Inst{10}    = 0b1;
1532  let Inst{9-5}   = Zn;
1533  let Inst{4-0}   = Zd;
1534
1535  let Constraints = "$Zd = $_Zd";
1536  let hasSideEffects = 0;
1537}
1538
1539multiclass sve2_int_perm_tbx<string asm, bits<2> opc, SDPatternOperator op> {
1540  def _B : sve2_int_perm_tbx<0b00, opc, asm, ZPR8>;
1541  def _H : sve2_int_perm_tbx<0b01, opc, asm, ZPR16>;
1542  def _S : sve2_int_perm_tbx<0b10, opc, asm, ZPR32>;
1543  def _D : sve2_int_perm_tbx<0b11, opc, asm, ZPR64>;
1544
1545  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
1546  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1547  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1548  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1549
1550  def : SVE_3_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1551  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1552  def : SVE_3_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1553
1554  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1555}
1556
1557class sve_int_perm_reverse_z<bits<2> sz8_64, string asm, ZPRRegOp zprty>
1558: I<(outs zprty:$Zd), (ins zprty:$Zn),
1559  asm, "\t$Zd, $Zn",
1560  "",
1561  []>, Sched<[]> {
1562  bits<5> Zd;
1563  bits<5> Zn;
1564  let Inst{31-24} = 0b00000101;
1565  let Inst{23-22} = sz8_64;
1566  let Inst{21-10} = 0b111000001110;
1567  let Inst{9-5}   = Zn;
1568  let Inst{4-0}   = Zd;
1569
1570  let hasSideEffects = 0;
1571}
1572
1573multiclass sve_int_perm_reverse_z<string asm, SDPatternOperator op> {
1574  def _B : sve_int_perm_reverse_z<0b00, asm, ZPR8>;
1575  def _H : sve_int_perm_reverse_z<0b01, asm, ZPR16>;
1576  def _S : sve_int_perm_reverse_z<0b10, asm, ZPR32>;
1577  def _D : sve_int_perm_reverse_z<0b11, asm, ZPR64>;
1578
1579  def : SVE_1_Op_Pat<nxv16i8, op, nxv16i8, !cast<Instruction>(NAME # _B)>;
1580  def : SVE_1_Op_Pat<nxv8i16, op, nxv8i16, !cast<Instruction>(NAME # _H)>;
1581  def : SVE_1_Op_Pat<nxv4i32, op, nxv4i32, !cast<Instruction>(NAME # _S)>;
1582  def : SVE_1_Op_Pat<nxv2i64, op, nxv2i64, !cast<Instruction>(NAME # _D)>;
1583
1584  def : SVE_1_Op_Pat<nxv2f16, op, nxv2f16, !cast<Instruction>(NAME # _D)>;
1585  def : SVE_1_Op_Pat<nxv4f16, op, nxv4f16, !cast<Instruction>(NAME # _S)>;
1586  def : SVE_1_Op_Pat<nxv8f16, op, nxv8f16, !cast<Instruction>(NAME # _H)>;
1587  def : SVE_1_Op_Pat<nxv2f32, op, nxv2f32, !cast<Instruction>(NAME # _D)>;
1588  def : SVE_1_Op_Pat<nxv4f32, op, nxv4f32, !cast<Instruction>(NAME # _S)>;
1589  def : SVE_1_Op_Pat<nxv2f64, op, nxv2f64, !cast<Instruction>(NAME # _D)>;
1590
1591  def : SVE_1_Op_Pat<nxv2bf16, op, nxv2bf16, !cast<Instruction>(NAME # _D)>;
1592  def : SVE_1_Op_Pat<nxv4bf16, op, nxv4bf16, !cast<Instruction>(NAME # _S)>;
1593  def : SVE_1_Op_Pat<nxv8bf16, op, nxv8bf16, !cast<Instruction>(NAME # _H)>;
1594}
1595
1596class sve_int_perm_reverse_p<bits<2> sz8_64, string asm, PPRRegOp pprty,
1597                             SDPatternOperator op>
1598: I<(outs pprty:$Pd), (ins pprty:$Pn),
1599  asm, "\t$Pd, $Pn",
1600  "",
1601  [(set nxv16i1:$Pd, (op nxv16i1:$Pn))]>, Sched<[]> {
1602  bits<4> Pd;
1603  bits<4> Pn;
1604  let Inst{31-24} = 0b00000101;
1605  let Inst{23-22} = sz8_64;
1606  let Inst{21-9}  = 0b1101000100000;
1607  let Inst{8-5}   = Pn;
1608  let Inst{4}     = 0b0;
1609  let Inst{3-0}   = Pd;
1610
1611  let hasSideEffects = 0;
1612}
1613
1614multiclass sve_int_perm_reverse_p<string asm, SDPatternOperator ir_op,
1615                                  SDPatternOperator op_b16,
1616                                  SDPatternOperator op_b32,
1617                                  SDPatternOperator op_b64> {
1618  def _B : sve_int_perm_reverse_p<0b00, asm, PPR8,  ir_op>;
1619  def _H : sve_int_perm_reverse_p<0b01, asm, PPR16, op_b16>;
1620  def _S : sve_int_perm_reverse_p<0b10, asm, PPR32, op_b32>;
1621  def _D : sve_int_perm_reverse_p<0b11, asm, PPR64, op_b64>;
1622
1623  def : SVE_1_Op_Pat<nxv8i1, ir_op, nxv8i1, !cast<Instruction>(NAME # _H)>;
1624  def : SVE_1_Op_Pat<nxv4i1, ir_op, nxv4i1, !cast<Instruction>(NAME # _S)>;
1625  def : SVE_1_Op_Pat<nxv2i1, ir_op, nxv2i1, !cast<Instruction>(NAME # _D)>;
1626}
1627
1628class sve_int_perm_unpk<bits<2> sz16_64, bits<2> opc, string asm,
1629                        ZPRRegOp zprty1, ZPRRegOp zprty2>
1630: I<(outs zprty1:$Zd), (ins zprty2:$Zn),
1631  asm, "\t$Zd, $Zn",
1632  "", []>, Sched<[]> {
1633  bits<5> Zd;
1634  bits<5> Zn;
1635  let Inst{31-24} = 0b00000101;
1636  let Inst{23-22} = sz16_64;
1637  let Inst{21-18} = 0b1100;
1638  let Inst{17-16} = opc;
1639  let Inst{15-10} = 0b001110;
1640  let Inst{9-5}   = Zn;
1641  let Inst{4-0}   = Zd;
1642
1643  let hasSideEffects = 0;
1644}
1645
1646multiclass sve_int_perm_unpk<bits<2> opc, string asm, SDPatternOperator op> {
1647  def _H : sve_int_perm_unpk<0b01, opc, asm, ZPR16, ZPR8>;
1648  def _S : sve_int_perm_unpk<0b10, opc, asm, ZPR32, ZPR16>;
1649  def _D : sve_int_perm_unpk<0b11, opc, asm, ZPR64, ZPR32>;
1650
1651  def : SVE_1_Op_Pat<nxv8i16, op, nxv16i8, !cast<Instruction>(NAME # _H)>;
1652  def : SVE_1_Op_Pat<nxv4i32, op, nxv8i16, !cast<Instruction>(NAME # _S)>;
1653  def : SVE_1_Op_Pat<nxv2i64, op, nxv4i32, !cast<Instruction>(NAME # _D)>;
1654}
1655
1656class sve_int_perm_insrs<bits<2> sz8_64, string asm, ZPRRegOp zprty,
1657                         RegisterClass srcRegType>
1658: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, srcRegType:$Rm),
1659  asm, "\t$Zdn, $Rm",
1660  "",
1661  []>, Sched<[]> {
1662  bits<5> Rm;
1663  bits<5> Zdn;
1664  let Inst{31-24} = 0b00000101;
1665  let Inst{23-22} = sz8_64;
1666  let Inst{21-10} = 0b100100001110;
1667  let Inst{9-5}   = Rm;
1668  let Inst{4-0}   = Zdn;
1669
1670  let Constraints = "$Zdn = $_Zdn";
1671  let DestructiveInstType = DestructiveOther;
1672  let hasSideEffects = 0;
1673}
1674
1675multiclass sve_int_perm_insrs<string asm, SDPatternOperator op> {
1676  def _B : sve_int_perm_insrs<0b00, asm, ZPR8, GPR32>;
1677  def _H : sve_int_perm_insrs<0b01, asm, ZPR16, GPR32>;
1678  def _S : sve_int_perm_insrs<0b10, asm, ZPR32, GPR32>;
1679  def _D : sve_int_perm_insrs<0b11, asm, ZPR64, GPR64>;
1680
1681  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, i32, !cast<Instruction>(NAME # _B)>;
1682  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, i32, !cast<Instruction>(NAME # _H)>;
1683  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, i32, !cast<Instruction>(NAME # _S)>;
1684  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, i64, !cast<Instruction>(NAME # _D)>;
1685}
1686
1687class sve_int_perm_insrv<bits<2> sz8_64, string asm, ZPRRegOp zprty,
1688                         FPRasZPROperand srcOpType>
1689: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, srcOpType:$Vm),
1690  asm, "\t$Zdn, $Vm",
1691  "",
1692  []>, Sched<[]> {
1693  bits<5> Vm;
1694  bits<5> Zdn;
1695  let Inst{31-24} = 0b00000101;
1696  let Inst{23-22} = sz8_64;
1697  let Inst{21-10} = 0b110100001110;
1698  let Inst{9-5}   = Vm;
1699  let Inst{4-0}   = Zdn;
1700
1701  let Constraints = "$Zdn = $_Zdn";
1702  let DestructiveInstType = DestructiveOther;
1703  let hasSideEffects = 0;
1704}
1705
1706multiclass sve_int_perm_insrv<string asm, SDPatternOperator op> {
1707  def _B : sve_int_perm_insrv<0b00, asm, ZPR8, FPR8asZPR>;
1708  def _H : sve_int_perm_insrv<0b01, asm, ZPR16, FPR16asZPR>;
1709  def _S : sve_int_perm_insrv<0b10, asm, ZPR32, FPR32asZPR>;
1710  def _D : sve_int_perm_insrv<0b11, asm, ZPR64, FPR64asZPR>;
1711
1712  def : Pat<(nxv8f16 (op nxv8f16:$Zn, f16:$Vm)),
1713            (!cast<Instruction>(NAME # _H) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, hsub))>;
1714  def : Pat<(nxv4f32 (op nxv4f32:$Zn, f32:$Vm)),
1715            (!cast<Instruction>(NAME # _S) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, ssub))>;
1716  def : Pat<(nxv2f64 (op nxv2f64:$Zn, f64:$Vm)),
1717            (!cast<Instruction>(NAME # _D) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, dsub))>;
1718
1719  def : Pat<(nxv8bf16 (op nxv8bf16:$Zn, bf16:$Vm)),
1720            (!cast<Instruction>(NAME # _H) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, hsub))>;
1721
1722  // Keep integer insertions within the vector unit.
1723  def : Pat<(nxv16i8 (op (nxv16i8 ZPR:$Zn), (i32 (vector_extract (nxv16i8 ZPR:$Vm), 0)))),
1724            (!cast<Instruction>(NAME # _B) $Zn, ZPR:$Vm)>;
1725  def : Pat<(nxv8i16 (op (nxv8i16 ZPR:$Zn), (i32 (vector_extract (nxv8i16 ZPR:$Vm), 0)))),
1726            (!cast<Instruction>(NAME # _H) $Zn, ZPR:$Vm)>;
1727  def : Pat<(nxv4i32 (op (nxv4i32 ZPR:$Zn), (i32 (vector_extract (nxv4i32 ZPR:$Vm), 0)))),
1728            (!cast<Instruction>(NAME # _S) $Zn, ZPR: $Vm)>;
1729  def : Pat<(nxv2i64 (op (nxv2i64 ZPR:$Zn), (i64 (vector_extract (nxv2i64 ZPR:$Vm), 0)))),
1730            (!cast<Instruction>(NAME # _D) $Zn, ZPR:$Vm)>;
1731
1732}
1733
1734//===----------------------------------------------------------------------===//
1735// SVE Permute - Extract Group
1736//===----------------------------------------------------------------------===//
1737
1738class sve_int_perm_extract_i<string asm>
1739: I<(outs ZPR8:$Zdn), (ins ZPR8:$_Zdn, ZPR8:$Zm, imm0_255:$imm8),
1740  asm, "\t$Zdn, $_Zdn, $Zm, $imm8",
1741  "", []>, Sched<[]> {
1742  bits<5> Zdn;
1743  bits<5> Zm;
1744  bits<8> imm8;
1745  let Inst{31-21} = 0b00000101001;
1746  let Inst{20-16} = imm8{7-3};
1747  let Inst{15-13} = 0b000;
1748  let Inst{12-10} = imm8{2-0};
1749  let Inst{9-5}   = Zm;
1750  let Inst{4-0}   = Zdn;
1751
1752  let Constraints = "$Zdn = $_Zdn";
1753  let DestructiveInstType = DestructiveOther;
1754  let ElementSize = ElementSizeNone;
1755  let hasSideEffects = 0;
1756}
1757
1758multiclass sve_int_perm_extract_i<string asm, SDPatternOperator op> {
1759  def NAME : sve_int_perm_extract_i<asm>;
1760
1761  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, imm0_255,
1762                         !cast<Instruction>(NAME)>;
1763}
1764
1765class sve2_int_perm_extract_i_cons<string asm>
1766: I<(outs ZPR8:$Zd), (ins ZZ_b:$Zn, imm0_255:$imm8),
1767  asm, "\t$Zd, $Zn, $imm8",
1768  "", []>, Sched<[]> {
1769  bits<5> Zd;
1770  bits<5> Zn;
1771  bits<8> imm8;
1772  let Inst{31-21} = 0b00000101011;
1773  let Inst{20-16} = imm8{7-3};
1774  let Inst{15-13} = 0b000;
1775  let Inst{12-10} = imm8{2-0};
1776  let Inst{9-5}   = Zn;
1777  let Inst{4-0}   = Zd;
1778
1779  let hasSideEffects = 0;
1780}
1781
1782//===----------------------------------------------------------------------===//
1783// SVE Vector Select Group
1784//===----------------------------------------------------------------------===//
1785
1786class sve_int_sel_vvv<bits<2> sz8_64, string asm, ZPRRegOp zprty>
1787: I<(outs zprty:$Zd), (ins PPRAny:$Pg, zprty:$Zn, zprty:$Zm),
1788  asm, "\t$Zd, $Pg, $Zn, $Zm",
1789  "",
1790  []>, Sched<[]> {
1791  bits<4> Pg;
1792  bits<5> Zd;
1793  bits<5> Zm;
1794  bits<5> Zn;
1795  let Inst{31-24} = 0b00000101;
1796  let Inst{23-22} = sz8_64;
1797  let Inst{21}    = 0b1;
1798  let Inst{20-16} = Zm;
1799  let Inst{15-14} = 0b11;
1800  let Inst{13-10} = Pg;
1801  let Inst{9-5}   = Zn;
1802  let Inst{4-0}   = Zd;
1803
1804  let hasSideEffects = 0;
1805}
1806
1807multiclass sve_int_sel_vvv<string asm, SDPatternOperator op> {
1808  def _B : sve_int_sel_vvv<0b00, asm, ZPR8>;
1809  def _H : sve_int_sel_vvv<0b01, asm, ZPR16>;
1810  def _S : sve_int_sel_vvv<0b10, asm, ZPR32>;
1811  def _D : sve_int_sel_vvv<0b11, asm, ZPR64>;
1812
1813  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
1814  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1815  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1816  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1817
1818  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1,  nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
1819  def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1,  nxv4f16, nxv4f16, !cast<Instruction>(NAME # _S)>;
1820  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1,  nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
1821  def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1,  nxv2f16, nxv2f16, !cast<Instruction>(NAME # _D)>;
1822  def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1,  nxv2f32, nxv2f32, !cast<Instruction>(NAME # _D)>;
1823  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1,  nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
1824
1825  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1,  nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
1826
1827  def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1828                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPRAny:$Pg, ZPR8:$Zn, ZPR8:$Zd), 1>;
1829  def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1830                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, ZPR16:$Zn, ZPR16:$Zd), 1>;
1831  def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1832                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, ZPR32:$Zn, ZPR32:$Zd), 1>;
1833  def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1834                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, ZPR64:$Zn, ZPR64:$Zd), 1>;
1835}
1836
1837
1838//===----------------------------------------------------------------------===//
1839// SVE Predicate Logical Operations Group
1840//===----------------------------------------------------------------------===//
1841
1842class sve_int_pred_log<bits<4> opc, string asm>
1843: I<(outs PPRorPNR8:$Pd), (ins PPRorPNRAny:$Pg, PPRorPNR8:$Pn, PPRorPNR8:$Pm),
1844  asm, "\t$Pd, $Pg/z, $Pn, $Pm",
1845  "",
1846  []>, Sched<[]> {
1847  bits<4> Pd;
1848  bits<4> Pg;
1849  bits<4> Pm;
1850  bits<4> Pn;
1851  let Inst{31-24} = 0b00100101;
1852  let Inst{23-22} = opc{3-2};
1853  let Inst{21-20} = 0b00;
1854  let Inst{19-16} = Pm;
1855  let Inst{15-14} = 0b01;
1856  let Inst{13-10} = Pg;
1857  let Inst{9}     = opc{1};
1858  let Inst{8-5}   = Pn;
1859  let Inst{4}     = opc{0};
1860  let Inst{3-0}   = Pd;
1861
1862  // SEL has no predication qualifier.
1863  let AsmString = !if(!eq(opc, 0b0011),
1864                      !strconcat(asm, "\t$Pd, $Pg, $Pn, $Pm"),
1865                      !strconcat(asm, "\t$Pd, $Pg/z, $Pn, $Pm"));
1866
1867  let Defs = !if(!eq (opc{2}, 1), [NZCV], []);
1868  let hasSideEffects = 0;
1869}
1870
1871multiclass sve_int_pred_log<bits<4> opc, string asm, SDPatternOperator op,
1872                            SDPatternOperator op_nopred = null_frag> {
1873  def NAME : sve_int_pred_log<opc, asm>;
1874
1875  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
1876  def : SVE_3_Op_Pat<nxv8i1, op, nxv8i1, nxv8i1, nxv8i1, !cast<Instruction>(NAME)>;
1877  def : SVE_3_Op_Pat<nxv4i1, op, nxv4i1, nxv4i1, nxv4i1, !cast<Instruction>(NAME)>;
1878  def : SVE_3_Op_Pat<nxv2i1, op, nxv2i1, nxv2i1, nxv2i1, !cast<Instruction>(NAME)>;
1879  def : SVE_3_Op_Pat<nxv1i1, op, nxv1i1, nxv1i1, nxv1i1, !cast<Instruction>(NAME)>;
1880  def : SVE_2_Op_AllActive_Pat<nxv16i1, op_nopred, nxv16i1, nxv16i1,
1881                               !cast<Instruction>(NAME), PTRUE_B>;
1882  def : SVE_2_Op_AllActive_Pat<nxv8i1, op_nopred, nxv8i1, nxv8i1,
1883                               !cast<Instruction>(NAME), PTRUE_H>;
1884  def : SVE_2_Op_AllActive_Pat<nxv4i1, op_nopred, nxv4i1, nxv4i1,
1885                               !cast<Instruction>(NAME), PTRUE_S>;
1886  def : SVE_2_Op_AllActive_Pat<nxv2i1, op_nopred, nxv2i1, nxv2i1,
1887                               !cast<Instruction>(NAME), PTRUE_D>;
1888  // Emulate .Q operation using a PTRUE_D when the other lanes don't matter.
1889  def : SVE_2_Op_AllActive_Pat<nxv1i1, op_nopred, nxv1i1, nxv1i1,
1890                               !cast<Instruction>(NAME), PTRUE_D>;
1891}
1892
1893// An instance of sve_int_pred_log_and but uses op_nopred's first operand as the
1894// general predicate.
1895multiclass sve_int_pred_log_v2<bits<4> opc, string asm, SDPatternOperator op,
1896                               SDPatternOperator op_nopred> :
1897  sve_int_pred_log<opc, asm, op> {
1898  def : Pat<(nxv16i1 (op_nopred nxv16i1:$Op1, nxv16i1:$Op2)),
1899            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1900  def : Pat<(nxv8i1 (op_nopred nxv8i1:$Op1, nxv8i1:$Op2)),
1901            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1902  def : Pat<(nxv4i1 (op_nopred nxv4i1:$Op1, nxv4i1:$Op2)),
1903            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1904  def : Pat<(nxv2i1 (op_nopred nxv2i1:$Op1, nxv2i1:$Op2)),
1905            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1906  // Emulate .Q operation using a PTRUE_D when the other lanes don't matter.
1907  def : Pat<(nxv1i1 (op_nopred nxv1i1:$Op1, nxv1i1:$Op2)),
1908            (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1909}
1910
1911//===----------------------------------------------------------------------===//
1912// SVE Logical Mask Immediate Group
1913//===----------------------------------------------------------------------===//
1914
1915class sve_int_log_imm<bits<2> opc, string asm>
1916: I<(outs ZPR64:$Zdn), (ins ZPR64:$_Zdn, logical_imm64:$imms13),
1917  asm, "\t$Zdn, $_Zdn, $imms13",
1918  "", []>, Sched<[]> {
1919  bits<5> Zdn;
1920  bits<13> imms13;
1921  let Inst{31-24} = 0b00000101;
1922  let Inst{23-22} = opc;
1923  let Inst{21-18} = 0b0000;
1924  let Inst{17-5}  = imms13;
1925  let Inst{4-0}   = Zdn;
1926
1927  let Constraints = "$Zdn = $_Zdn";
1928  let DecoderMethod = "DecodeSVELogicalImmInstruction";
1929  let DestructiveInstType = DestructiveOther;
1930  let ElementSize = ElementSizeNone;
1931  let hasSideEffects = 0;
1932}
1933
1934multiclass sve_int_log_imm<bits<2> opc, string asm, string alias, SDPatternOperator op> {
1935  def NAME : sve_int_log_imm<opc, asm>;
1936
1937  def : SVE_1_Op_Imm_Log_Pat<nxv16i8, op, ZPR8,  i32, SVELogicalImm8Pat,  !cast<Instruction>(NAME)>;
1938  def : SVE_1_Op_Imm_Log_Pat<nxv8i16, op, ZPR16, i32, SVELogicalImm16Pat, !cast<Instruction>(NAME)>;
1939  def : SVE_1_Op_Imm_Log_Pat<nxv4i32, op, ZPR32, i32, SVELogicalImm32Pat, !cast<Instruction>(NAME)>;
1940  def : SVE_1_Op_Imm_Log_Pat<nxv2i64, op, ZPR64, i64, SVELogicalImm64Pat, !cast<Instruction>(NAME)>;
1941
1942  def : InstAlias<asm # "\t$Zdn, $Zdn, $imm",
1943                  (!cast<Instruction>(NAME) ZPR8:$Zdn, sve_logical_imm8:$imm), 4>;
1944  def : InstAlias<asm # "\t$Zdn, $Zdn, $imm",
1945                  (!cast<Instruction>(NAME) ZPR16:$Zdn, sve_logical_imm16:$imm), 3>;
1946  def : InstAlias<asm # "\t$Zdn, $Zdn, $imm",
1947                  (!cast<Instruction>(NAME) ZPR32:$Zdn, sve_logical_imm32:$imm), 2>;
1948
1949  def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
1950                  (!cast<Instruction>(NAME) ZPR8:$Zdn, sve_logical_imm8_not:$imm), 0>;
1951  def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
1952                  (!cast<Instruction>(NAME) ZPR16:$Zdn, sve_logical_imm16_not:$imm), 0>;
1953  def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
1954                  (!cast<Instruction>(NAME) ZPR32:$Zdn, sve_logical_imm32_not:$imm), 0>;
1955  def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
1956                  (!cast<Instruction>(NAME) ZPR64:$Zdn, logical_imm64_not:$imm), 0>;
1957}
1958
1959multiclass sve_int_log_imm_bic<SDPatternOperator op> {
1960  def : SVE_1_Op_Imm_Log_Pat<nxv16i8, op, ZPR8,  i32, SVELogicalImm8NotPat,  !cast<Instruction>("AND_ZI")>;
1961  def : SVE_1_Op_Imm_Log_Pat<nxv8i16, op, ZPR16, i32, SVELogicalImm16NotPat, !cast<Instruction>("AND_ZI")>;
1962  def : SVE_1_Op_Imm_Log_Pat<nxv4i32, op, ZPR32, i32, SVELogicalImm32NotPat, !cast<Instruction>("AND_ZI")>;
1963  def : SVE_1_Op_Imm_Log_Pat<nxv2i64, op, ZPR64, i64, SVELogicalImm64NotPat, !cast<Instruction>("AND_ZI")>;
1964}
1965
1966class sve_int_dup_mask_imm<string asm>
1967: I<(outs ZPR64:$Zd), (ins logical_imm64:$imms),
1968  asm, "\t$Zd, $imms",
1969  "",
1970  []>, Sched<[]> {
1971  bits<5> Zd;
1972  bits<13> imms;
1973  let Inst{31-18} = 0b00000101110000;
1974  let Inst{17-5} = imms;
1975  let Inst{4-0} = Zd;
1976
1977  let DecoderMethod = "DecodeSVELogicalImmInstruction";
1978  let hasSideEffects = 0;
1979  let isReMaterializable = 1;
1980  let Uses = [VG];
1981}
1982
1983multiclass sve_int_dup_mask_imm<string asm> {
1984  def NAME : sve_int_dup_mask_imm<asm>;
1985
1986  def : InstAlias<"dupm $Zd, $imm",
1987                  (!cast<Instruction>(NAME) ZPR8:$Zd, sve_logical_imm8:$imm), 4>;
1988  def : InstAlias<"dupm $Zd, $imm",
1989                  (!cast<Instruction>(NAME) ZPR16:$Zd, sve_logical_imm16:$imm), 3>;
1990  def : InstAlias<"dupm $Zd, $imm",
1991                  (!cast<Instruction>(NAME) ZPR32:$Zd, sve_logical_imm32:$imm), 2>;
1992
1993  // All Zd.b forms have a CPY/DUP equivalent, hence no byte alias here.
1994  def : InstAlias<"mov $Zd, $imm",
1995                  (!cast<Instruction>(NAME) ZPR16:$Zd, sve_preferred_logical_imm16:$imm), 7>;
1996  def : InstAlias<"mov $Zd, $imm",
1997                  (!cast<Instruction>(NAME) ZPR32:$Zd, sve_preferred_logical_imm32:$imm), 6>;
1998  def : InstAlias<"mov $Zd, $imm",
1999                  (!cast<Instruction>(NAME) ZPR64:$Zd, sve_preferred_logical_imm64:$imm), 5>;
2000
2001  // NOTE: No pattern for nxv16i8 because DUP has full coverage.
2002  def : Pat<(nxv8i16 (splat_vector (i32 (SVELogicalImm16Pat i64:$imm)))),
2003            (!cast<Instruction>(NAME) i64:$imm)>;
2004  def : Pat<(nxv4i32 (splat_vector (i32 (SVELogicalImm32Pat i64:$imm)))),
2005            (!cast<Instruction>(NAME) i64:$imm)>;
2006  def : Pat<(nxv2i64 (splat_vector (i64 (SVELogicalImm64Pat i64:$imm)))),
2007            (!cast<Instruction>(NAME) i64:$imm)>;
2008}
2009
2010//===----------------------------------------------------------------------===//
2011// SVE Integer Arithmetic -  Unpredicated Group.
2012//===----------------------------------------------------------------------===//
2013
2014class sve_int_bin_cons_arit_0<bits<2> sz8_64, bits<3> opc, string asm,
2015                              ZPRRegOp zprty>
2016: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
2017  asm, "\t$Zd, $Zn, $Zm",
2018  "", []>, Sched<[]> {
2019  bits<5> Zd;
2020  bits<5> Zm;
2021  bits<5> Zn;
2022  let Inst{31-24} = 0b00000100;
2023  let Inst{23-22} = sz8_64;
2024  let Inst{21}    = 0b1;
2025  let Inst{20-16} = Zm;
2026  let Inst{15-13} = 0b000;
2027  let Inst{12-10} = opc;
2028  let Inst{9-5}   = Zn;
2029  let Inst{4-0}   = Zd;
2030
2031  let hasSideEffects = 0;
2032}
2033
2034multiclass sve_int_bin_cons_arit_0<bits<3> opc, string asm, SDPatternOperator op> {
2035  def _B : sve_int_bin_cons_arit_0<0b00, opc, asm, ZPR8>;
2036  def _H : sve_int_bin_cons_arit_0<0b01, opc, asm, ZPR16>;
2037  def _S : sve_int_bin_cons_arit_0<0b10, opc, asm, ZPR32>;
2038  def _D : sve_int_bin_cons_arit_0<0b11, opc, asm, ZPR64>;
2039
2040  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
2041  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2042  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2043  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2044}
2045
2046//===----------------------------------------------------------------------===//
2047// SVE Floating Point Arithmetic - Predicated Group
2048//===----------------------------------------------------------------------===//
2049
2050class sve_fp_2op_i_p_zds<bits<2> sz, bits<3> opc, string asm,
2051                         ZPRRegOp zprty,
2052                         Operand imm_ty>
2053: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, imm_ty:$i1),
2054  asm, "\t$Zdn, $Pg/m, $_Zdn, $i1",
2055  "",
2056  []>, Sched<[]> {
2057  bits<3> Pg;
2058  bits<5> Zdn;
2059  bit i1;
2060  let Inst{31-24} = 0b01100101;
2061  let Inst{23-22} = sz;
2062  let Inst{21-19} = 0b011;
2063  let Inst{18-16} = opc;
2064  let Inst{15-13} = 0b100;
2065  let Inst{12-10} = Pg;
2066  let Inst{9-6}   = 0b0000;
2067  let Inst{5}     = i1;
2068  let Inst{4-0}   = Zdn;
2069
2070  let Constraints = "$Zdn = $_Zdn";
2071  let DestructiveInstType = DestructiveOther;
2072  let ElementSize = zprty.ElementSize;
2073  let hasSideEffects = 0;
2074  let mayRaiseFPException = 1;
2075}
2076
2077multiclass sve_fp_2op_i_p_zds<bits<3> opc, string asm, string Ps, Operand imm_ty, FPImmLeaf A, FPImmLeaf B, SDPatternOperator op> {
2078  let DestructiveInstType = DestructiveBinaryImm in {
2079  def _H : SVEPseudo2Instr<Ps # _H, 1>, sve_fp_2op_i_p_zds<0b01, opc, asm, ZPR16, imm_ty>;
2080  def _S : SVEPseudo2Instr<Ps # _S, 1>, sve_fp_2op_i_p_zds<0b10, opc, asm, ZPR32, imm_ty>;
2081  def _D : SVEPseudo2Instr<Ps # _D, 1>, sve_fp_2op_i_p_zds<0b11, opc, asm, ZPR64, imm_ty>;
2082  }
2083
2084  def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, op, nxv8i1, f16, A, 0, !cast<Instruction>(NAME # "_H")>;
2085  def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, op, nxv8i1, f16, B, 1, !cast<Instruction>(NAME # "_H")>;
2086  def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, op, nxv4i1, f32, A, 0, !cast<Instruction>(NAME # "_S")>;
2087  def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, op, nxv4i1, f32, B, 1, !cast<Instruction>(NAME # "_S")>;
2088  def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, op, nxv2i1, f64, A, 0, !cast<Instruction>(NAME # "_D")>;
2089  def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, op, nxv2i1, f64, B, 1, !cast<Instruction>(NAME # "_D")>;
2090}
2091
2092class sve_fp_2op_p_zds<bits<2> sz, bits<4> opc, string asm,
2093                       ZPRRegOp zprty>
2094: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
2095  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
2096  "",
2097  []>, Sched<[]> {
2098  bits<3> Pg;
2099  bits<5> Zdn;
2100  bits<5> Zm;
2101  let Inst{31-24} = 0b01100101;
2102  let Inst{23-22} = sz;
2103  let Inst{21-20} = 0b00;
2104  let Inst{19-16} = opc;
2105  let Inst{15-13} = 0b100;
2106  let Inst{12-10} = Pg;
2107  let Inst{9-5}   = Zm;
2108  let Inst{4-0}   = Zdn;
2109
2110  let Constraints = "$Zdn = $_Zdn";
2111  let DestructiveInstType = DestructiveOther;
2112  let ElementSize = zprty.ElementSize;
2113  let hasSideEffects = 0;
2114  let mayRaiseFPException = 1;
2115}
2116
2117multiclass sve2p1_bf_2op_p_zds<bits<4> opc, string asm, string Ps,
2118                            SDPatternOperator op, DestructiveInstTypeEnum flags,
2119                            string revname="", bit isReverseInstr=0> {
2120let DestructiveInstType = flags in {
2121  def NAME : sve_fp_2op_p_zds<0b00, opc, asm, ZPR16>,
2122           SVEPseudo2Instr<Ps, 1>, SVEInstr2Rev<NAME , revname , isReverseInstr>;
2123  }
2124
2125  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
2126}
2127
2128multiclass sve2p1_bf_bin_pred_zds<SDPatternOperator op> {
2129  def _UNDEF : PredTwoOpPseudo<NAME, ZPR16, FalseLanesUndef>;
2130
2131  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1,  nxv8bf16, nxv8bf16, !cast<Pseudo>(NAME # _UNDEF)>;
2132}
2133
2134multiclass sve2p1_bf_2op_p_zds_zeroing<SDPatternOperator op> {
2135  def _ZERO : PredTwoOpPseudo<NAME, ZPR16, FalseLanesZero>;
2136
2137  def : SVE_3_Op_Pat_SelZero<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Pseudo>(NAME # _ZERO)>;
2138}
2139
2140multiclass sve_fp_2op_p_zds<bits<4> opc, string asm, string Ps,
2141                            SDPatternOperator op, DestructiveInstTypeEnum flags,
2142                            string revname="", bit isReverseInstr=0> {
2143  let DestructiveInstType = flags in {
2144  def _H : sve_fp_2op_p_zds<0b01, opc, asm, ZPR16>,
2145           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2146  def _S : sve_fp_2op_p_zds<0b10, opc, asm, ZPR32>,
2147           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2148  def _D : sve_fp_2op_p_zds<0b11, opc, asm, ZPR64>,
2149           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2150  }
2151
2152  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2153  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2154  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2155}
2156
2157multiclass sve_fp_2op_p_zds_fscale<bits<4> opc, string asm,
2158                                   SDPatternOperator op> {
2159  def _H : sve_fp_2op_p_zds<0b01, opc, asm, ZPR16>;
2160  def _S : sve_fp_2op_p_zds<0b10, opc, asm, ZPR32>;
2161  def _D : sve_fp_2op_p_zds<0b11, opc, asm, ZPR64>;
2162
2163  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2164  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2165  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2166}
2167
2168multiclass sve_fp_2op_p_zds_zeroing_hsd<SDPatternOperator op> {
2169  def _H_ZERO : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesZero>;
2170  def _S_ZERO : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesZero>;
2171  def _D_ZERO : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesZero>;
2172
2173  def : SVE_3_Op_Pat_SelZero<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Pseudo>(NAME # _H_ZERO)>;
2174  def : SVE_3_Op_Pat_SelZero<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Pseudo>(NAME # _S_ZERO)>;
2175  def : SVE_3_Op_Pat_SelZero<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Pseudo>(NAME # _D_ZERO)>;
2176}
2177
2178class sve_fp_ftmad<bits<2> sz, string asm, ZPRRegOp zprty>
2179: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, timm32_0_7:$imm3),
2180  asm, "\t$Zdn, $_Zdn, $Zm, $imm3",
2181  "",
2182  []>, Sched<[]> {
2183  bits<5> Zdn;
2184  bits<5> Zm;
2185  bits<3> imm3;
2186  let Inst{31-24} = 0b01100101;
2187  let Inst{23-22} = sz;
2188  let Inst{21-19} = 0b010;
2189  let Inst{18-16} = imm3;
2190  let Inst{15-10} = 0b100000;
2191  let Inst{9-5}   = Zm;
2192  let Inst{4-0}   = Zdn;
2193
2194  let Constraints = "$Zdn = $_Zdn";
2195  let DestructiveInstType = DestructiveOther;
2196  let ElementSize = ElementSizeNone;
2197  let hasSideEffects = 0;
2198  let mayRaiseFPException = 1;
2199}
2200
2201multiclass sve_fp_ftmad<string asm, SDPatternOperator op> {
2202  def _H : sve_fp_ftmad<0b01, asm, ZPR16>;
2203  def _S : sve_fp_ftmad<0b10, asm, ZPR32>;
2204  def _D : sve_fp_ftmad<0b11, asm, ZPR64>;
2205
2206  def : Pat<(nxv8f16 (op (nxv8f16 ZPR16:$Zn), (nxv8f16 ZPR16:$Zm), (i32 timm32_0_7:$imm))),
2207            (!cast<Instruction>(NAME # _H) ZPR16:$Zn, ZPR16:$Zm, timm32_0_7:$imm)>;
2208  def : Pat<(nxv4f32 (op (nxv4f32 ZPR32:$Zn), (nxv4f32 ZPR32:$Zm), (i32 timm32_0_7:$imm))),
2209            (!cast<Instruction>(NAME # _S) ZPR32:$Zn, ZPR32:$Zm, timm32_0_7:$imm)>;
2210  def : Pat<(nxv2f64 (op (nxv2f64 ZPR64:$Zn), (nxv2f64 ZPR64:$Zm), (i32 timm32_0_7:$imm))),
2211            (!cast<Instruction>(NAME # _D) ZPR64:$Zn, ZPR64:$Zm, timm32_0_7:$imm)>;
2212}
2213
2214multiclass sve_fp_2op_i_p_zds_hfd<Operand imm_ty, FPImmLeaf A, FPImmLeaf B, SDPatternOperator ir_op = null_frag> {
2215  def _H_UNDEF : PredTwoOpImmPseudo<NAME # _H, ZPR16, imm_ty, FalseLanesUndef>;
2216  def _S_UNDEF : PredTwoOpImmPseudo<NAME # _S, ZPR32, imm_ty, FalseLanesUndef>;
2217  def _D_UNDEF : PredTwoOpImmPseudo<NAME # _D, ZPR64, imm_ty, FalseLanesUndef>;
2218
2219  def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, ir_op, nxv8i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2220  def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, ir_op, nxv8i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2221  def : SVE_2_Op_Fp_Imm_Pat<nxv4f16, ir_op, nxv4i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2222  def : SVE_2_Op_Fp_Imm_Pat<nxv4f16, ir_op, nxv4i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2223  def : SVE_2_Op_Fp_Imm_Pat<nxv2f16, ir_op, nxv2i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2224  def : SVE_2_Op_Fp_Imm_Pat<nxv2f16, ir_op, nxv2i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2225  def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, ir_op, nxv4i1, f32, A, 0, !cast<Instruction>(NAME # "_S_UNDEF")>;
2226  def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, ir_op, nxv4i1, f32, B, 1, !cast<Instruction>(NAME # "_S_UNDEF")>;
2227  def : SVE_2_Op_Fp_Imm_Pat<nxv2f32, ir_op, nxv2i1, f32, A, 0, !cast<Instruction>(NAME # "_S_UNDEF")>;
2228  def : SVE_2_Op_Fp_Imm_Pat<nxv2f32, ir_op, nxv2i1, f32, B, 1, !cast<Instruction>(NAME # "_S_UNDEF")>;
2229  def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, ir_op, nxv2i1, f64, A, 0, !cast<Instruction>(NAME # "_D_UNDEF")>;
2230  def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, ir_op, nxv2i1, f64, B, 1, !cast<Instruction>(NAME # "_D_UNDEF")>;
2231}
2232
2233multiclass sve_fp_2op_i_p_zds_zeroing_hfd<Operand imm_ty, FPImmLeaf A, FPImmLeaf B, SDPatternOperator op> {
2234  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, imm_ty, FalseLanesZero>;
2235  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, imm_ty, FalseLanesZero>;
2236  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, imm_ty, FalseLanesZero>;
2237
2238  let AddedComplexity = 2 in {
2239    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv8f16, op, nxv8i1, f16, A, 0, !cast<Instruction>(NAME # "_H_ZERO")>;
2240    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv8f16, op, nxv8i1, f16, B, 1, !cast<Instruction>(NAME # "_H_ZERO")>;
2241    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv4f32, op, nxv4i1, f32, A, 0, !cast<Instruction>(NAME # "_S_ZERO")>;
2242    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv4f32, op, nxv4i1, f32, B, 1, !cast<Instruction>(NAME # "_S_ZERO")>;
2243    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv2f64, op, nxv2i1, f64, A, 0, !cast<Instruction>(NAME # "_D_ZERO")>;
2244    def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv2f64, op, nxv2i1, f64, B, 1, !cast<Instruction>(NAME # "_D_ZERO")>;
2245  }
2246}
2247
2248//===----------------------------------------------------------------------===//
2249// SVE Floating Point Arithmetic - Unpredicated Group
2250//===----------------------------------------------------------------------===//
2251
2252class sve_fp_3op_u_zd<bits<2> sz, bits<3> opc, string asm, ZPRRegOp zprty>
2253: I<(outs zprty:$Zd), (ins  zprty:$Zn, zprty:$Zm),
2254  asm, "\t$Zd, $Zn, $Zm",
2255  "",
2256  []>, Sched<[]> {
2257  bits<5> Zd;
2258  bits<5> Zm;
2259  bits<5> Zn;
2260  let Inst{31-24} = 0b01100101;
2261  let Inst{23-22} = sz;
2262  let Inst{21}    = 0b0;
2263  let Inst{20-16} = Zm;
2264  let Inst{15-13} = 0b000;
2265  let Inst{12-10} = opc;
2266  let Inst{9-5}   = Zn;
2267  let Inst{4-0}   = Zd;
2268
2269  let hasSideEffects = 0;
2270  let mayRaiseFPException = 1;
2271}
2272
2273multiclass sve_fp_3op_u_zd<bits<3> opc, string asm, SDPatternOperator op> {
2274  def _H : sve_fp_3op_u_zd<0b01, opc, asm, ZPR16>;
2275  def _S : sve_fp_3op_u_zd<0b10, opc, asm, ZPR32>;
2276  def _D : sve_fp_3op_u_zd<0b11, opc, asm, ZPR64>;
2277
2278  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2279  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2280  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2281}
2282
2283multiclass sve2p1_bf_3op_u_zd<bits<3> opc, string asm, SDPatternOperator op> {
2284  def NAME : sve_fp_3op_u_zd<0b00, opc, asm, ZPR16>;
2285
2286  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
2287}
2288
2289multiclass sve_fp_3op_u_zd_ftsmul<bits<3> opc, string asm, SDPatternOperator op> {
2290  def _H : sve_fp_3op_u_zd<0b01, opc, asm, ZPR16>;
2291  def _S : sve_fp_3op_u_zd<0b10, opc, asm, ZPR32>;
2292  def _D : sve_fp_3op_u_zd<0b11, opc, asm, ZPR64>;
2293
2294  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2295  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2296  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2297}
2298
2299//===----------------------------------------------------------------------===//
2300// SVE Floating Point Fused Multiply-Add Group
2301//===----------------------------------------------------------------------===//
2302
2303class sve_fp_3op_p_zds_a<bits<2> sz, bits<2> opc, string asm, ZPRRegOp zprty>
2304: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm),
2305  asm, "\t$Zda, $Pg/m, $Zn, $Zm",
2306  "",
2307  []>, Sched<[]> {
2308  bits<3> Pg;
2309  bits<5> Zda;
2310  bits<5> Zm;
2311  bits<5> Zn;
2312  let Inst{31-24} = 0b01100101;
2313  let Inst{23-22} = sz;
2314  let Inst{21}    = 0b1;
2315  let Inst{20-16} = Zm;
2316  let Inst{15}    = 0b0;
2317  let Inst{14-13} = opc;
2318  let Inst{12-10} = Pg;
2319  let Inst{9-5}   = Zn;
2320  let Inst{4-0}   = Zda;
2321
2322  let Constraints = "$Zda = $_Zda";
2323  let ElementSize = zprty.ElementSize;
2324  let DestructiveInstType = DestructiveTernaryCommWithRev;
2325  let hasSideEffects = 0;
2326  let mayRaiseFPException = 1;
2327}
2328
2329multiclass sve_fp_3op_p_zds_a<bits<2> opc, string asm, string Ps,
2330                              SDPatternOperator op, string revname,
2331                              bit isReverseInstr=0> {
2332  def _H : sve_fp_3op_p_zds_a<0b01, opc, asm, ZPR16>,
2333           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2334  def _S : sve_fp_3op_p_zds_a<0b10, opc, asm, ZPR32>,
2335           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2336  def _D : sve_fp_3op_p_zds_a<0b11, opc, asm, ZPR64>,
2337           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2338
2339  def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2340  def : SVE_4_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H)>;
2341  def : SVE_4_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H)>;
2342  def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2343  def : SVE_4_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S)>;
2344  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2345}
2346
2347multiclass sve_fp_3op_p_zds_a_bf<bits<2> opc, string asm, string Ps,
2348                              SDPatternOperator op> {
2349  def NAME : sve_fp_3op_p_zds_a<0b00, opc, asm, ZPR16>,
2350           SVEPseudo2Instr<Ps, 1>, SVEInstr2Rev<NAME, "", 0>;
2351
2352  def : SVE_4_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
2353}
2354
2355class sve_fp_3op_p_zds_b<bits<2> sz, bits<2> opc, string asm,
2356                         ZPRRegOp zprty>
2357: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm, zprty:$Za),
2358  asm, "\t$Zdn, $Pg/m, $Zm, $Za",
2359  "",
2360  []>, Sched<[]> {
2361  bits<3> Pg;
2362  bits<5> Za;
2363  bits<5> Zdn;
2364  bits<5> Zm;
2365  let Inst{31-24} = 0b01100101;
2366  let Inst{23-22} = sz;
2367  let Inst{21}    = 0b1;
2368  let Inst{20-16} = Za;
2369  let Inst{15}    = 0b1;
2370  let Inst{14-13} = opc;
2371  let Inst{12-10} = Pg;
2372  let Inst{9-5}   = Zm;
2373  let Inst{4-0}   = Zdn;
2374
2375  let Constraints = "$Zdn = $_Zdn";
2376  let DestructiveInstType = DestructiveOther;
2377  let ElementSize = zprty.ElementSize;
2378  let hasSideEffects = 0;
2379  let mayRaiseFPException = 1;
2380}
2381
2382multiclass sve_fp_3op_p_zds_b<bits<2> opc, string asm, SDPatternOperator op,
2383                              string revname, bit isReverseInstr> {
2384  def _H : sve_fp_3op_p_zds_b<0b01, opc, asm, ZPR16>,
2385           SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2386  def _S : sve_fp_3op_p_zds_b<0b10, opc, asm, ZPR32>,
2387           SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2388  def _D : sve_fp_3op_p_zds_b<0b11, opc, asm, ZPR64>,
2389           SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2390
2391  def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2392  def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2393  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2394}
2395
2396//===----------------------------------------------------------------------===//
2397// SVE Floating Point Multiply-Add - Indexed Group
2398//===----------------------------------------------------------------------===//
2399
2400class sve_fp_fma_by_indexed_elem<bits<2> sz, bits<2> opc, string asm,
2401                                 ZPRRegOp zprty1,
2402                                 ZPRRegOp zprty2, Operand itype>
2403: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty1:$Zn, zprty2:$Zm, itype:$iop),
2404  asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
2405  bits<5> Zda;
2406  bits<5> Zn;
2407  let Inst{31-24} = 0b01100100;
2408  let Inst{23-22} = sz;
2409  let Inst{21}    = 0b1;
2410  let Inst{15-12} = 0b0000;
2411  let Inst{11-10} = opc;
2412  let Inst{9-5}   = Zn;
2413  let Inst{4-0}   = Zda;
2414
2415  let Constraints = "$Zda = $_Zda";
2416  let DestructiveInstType = DestructiveOther;
2417  let ElementSize = ElementSizeNone;
2418  let hasSideEffects = 0;
2419  let mayRaiseFPException = 1;
2420}
2421
2422multiclass sve2p1_fp_bfma_by_indexed_elem<string asm, bits<2> opc, SDPatternOperator op> {
2423  def NAME : sve_fp_fma_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR3b16,
2424                                         VectorIndexH32b> {
2425    bits<3> Zm;
2426    bits<3> iop;
2427    let Inst{22} = iop{2};
2428    let Inst{20-19} = iop{1-0};
2429    let Inst{18-16} = Zm;
2430  }
2431  def : Pat<(nxv8bf16 (op nxv8bf16:$op1, nxv8bf16:$op2, nxv8bf16:$op3, (i32 VectorIndexH32b_timm:$idx))),
2432            (!cast<Instruction>(NAME) $op1, $op2, $op3, VectorIndexH32b_timm:$idx)>;
2433}
2434
2435multiclass sve_fp_fma_by_indexed_elem<bits<2> opc, string asm,
2436                                      SDPatternOperator op> {
2437  def _H : sve_fp_fma_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2438    bits<3> Zm;
2439    bits<3> iop;
2440    let Inst{22} = iop{2};
2441    let Inst{20-19} = iop{1-0};
2442    let Inst{18-16} = Zm;
2443  }
2444  def _S : sve_fp_fma_by_indexed_elem<0b10, opc, asm, ZPR32, ZPR3b32, VectorIndexS32b> {
2445    bits<3> Zm;
2446    bits<2> iop;
2447    let Inst{20-19} = iop;
2448    let Inst{18-16} = Zm;
2449  }
2450  def _D : sve_fp_fma_by_indexed_elem<0b11, opc, asm, ZPR64, ZPR4b64, VectorIndexD32b> {
2451    bits<4> Zm;
2452    bit iop;
2453    let Inst{20} = iop;
2454    let Inst{19-16} = Zm;
2455  }
2456
2457  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 VectorIndexH32b_timm:$idx))),
2458            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, VectorIndexH32b_timm:$idx)>;
2459  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 VectorIndexS32b_timm:$idx))),
2460            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, VectorIndexS32b_timm:$idx)>;
2461  def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, (i32 VectorIndexD32b_timm:$idx))),
2462            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, VectorIndexD32b_timm:$idx)>;
2463}
2464
2465
2466//===----------------------------------------------------------------------===//
2467// SVE Floating Point Multiply - Indexed Group
2468//===----------------------------------------------------------------------===//
2469
2470class sve_fp_fmul_by_indexed_elem<bits<2> sz, bit o2, string asm, ZPRRegOp zprty,
2471                                  ZPRRegOp zprty2, Operand itype>
2472: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty2:$Zm, itype:$iop),
2473  asm, "\t$Zd, $Zn, $Zm$iop", "", []>, Sched<[]> {
2474  bits<5> Zd;
2475  bits<5> Zn;
2476  let Inst{31-24} = 0b01100100;
2477  let Inst{23-22} = sz;
2478  let Inst{21}    = 0b1;
2479  let Inst{15-12} = 0b0010;
2480  let Inst{11}    = o2;
2481  let Inst{10}    = 0b0;
2482  let Inst{9-5}   = Zn;
2483  let Inst{4-0}   = Zd;
2484
2485  let hasSideEffects = 0;
2486  let mayRaiseFPException = 1;
2487}
2488
2489multiclass sve2p1_fp_bfmul_by_indexed_elem<string asm, SDPatternOperator ir_intrinsic> {
2490  def NAME : sve_fp_fmul_by_indexed_elem<{0, ?}, 0b1, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2491    bits<3> Zm;
2492    bits<3> iop;
2493    let Inst{22} = iop{2};
2494    let Inst{20-19} = iop{1-0};
2495    let Inst{18-16} = Zm;
2496  }
2497  def : Pat <(nxv8bf16 (ir_intrinsic nxv8bf16:$Op1, nxv8bf16:$Op2, (i32 VectorIndexH32b_timm:$idx))),
2498             (!cast<Instruction>(NAME) $Op1, $Op2, VectorIndexH32b_timm:$idx)>;
2499}
2500
2501multiclass sve_fp_fmul_by_indexed_elem<string asm, SDPatternOperator op> {
2502  def _H : sve_fp_fmul_by_indexed_elem<{0, ?}, 0b0, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2503    bits<3> Zm;
2504    bits<3> iop;
2505    let Inst{22} = iop{2};
2506    let Inst{20-19} = iop{1-0};
2507    let Inst{18-16} = Zm;
2508  }
2509  def _S : sve_fp_fmul_by_indexed_elem<0b10, 0b0, asm, ZPR32, ZPR3b32, VectorIndexS32b> {
2510    bits<3> Zm;
2511    bits<2> iop;
2512    let Inst{20-19} = iop;
2513    let Inst{18-16} = Zm;
2514  }
2515  def _D : sve_fp_fmul_by_indexed_elem<0b11, 0b0, asm, ZPR64, ZPR4b64, VectorIndexD32b> {
2516    bits<4> Zm;
2517    bit iop;
2518    let Inst{20} = iop;
2519    let Inst{19-16} = Zm;
2520  }
2521
2522  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, (i32 VectorIndexH32b_timm:$idx))),
2523            (!cast<Instruction>(NAME # _H) $Op1, $Op2, VectorIndexH32b_timm:$idx)>;
2524  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, (i32 VectorIndexS32b_timm:$idx))),
2525            (!cast<Instruction>(NAME # _S) $Op1, $Op2, VectorIndexS32b_timm:$idx)>;
2526  def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, (i32 VectorIndexD32b_timm:$idx))),
2527            (!cast<Instruction>(NAME # _D) $Op1, $Op2, VectorIndexD32b_timm:$idx)>;
2528}
2529
2530//===----------------------------------------------------------------------===//
2531// SVE Floating Point Complex Multiply-Add Group
2532//===----------------------------------------------------------------------===//
2533
2534class sve_fp_fcmla<bits<2> sz, string asm, ZPRRegOp zprty>
2535: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm,
2536                        complexrotateop:$imm),
2537  asm, "\t$Zda, $Pg/m, $Zn, $Zm, $imm",
2538  "", []>, Sched<[]> {
2539  bits<5> Zda;
2540  bits<3> Pg;
2541  bits<5> Zn;
2542  bits<5> Zm;
2543  bits<2> imm;
2544  let Inst{31-24} = 0b01100100;
2545  let Inst{23-22} = sz;
2546  let Inst{21}    = 0;
2547  let Inst{20-16} = Zm;
2548  let Inst{15}    = 0;
2549  let Inst{14-13} = imm;
2550  let Inst{12-10} = Pg;
2551  let Inst{9-5}   = Zn;
2552  let Inst{4-0}   = Zda;
2553
2554  let Constraints = "$Zda = $_Zda";
2555  let DestructiveInstType = DestructiveOther;
2556  let ElementSize = zprty.ElementSize;
2557  let hasSideEffects = 0;
2558  let mayRaiseFPException = 1;
2559}
2560
2561multiclass sve_fp_fcmla<string asm, SDPatternOperator op> {
2562  def _H : sve_fp_fcmla<0b01, asm, ZPR16>;
2563  def _S : sve_fp_fcmla<0b10, asm, ZPR32>;
2564  def _D : sve_fp_fcmla<0b11, asm, ZPR64>;
2565
2566  def : Pat<(nxv8f16 (op nxv8i1:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, nxv8f16:$Op4, (i32 complexrotateop:$imm))),
2567            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2568  def : Pat<(nxv4f32 (op nxv4i1:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, nxv4f32:$Op4, (i32 complexrotateop:$imm))),
2569            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2570  def : Pat<(nxv2f64 (op nxv2i1:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, nxv2f64:$Op4, (i32 complexrotateop:$imm))),
2571            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2572}
2573
2574//===----------------------------------------------------------------------===//
2575// SVE Floating Point Complex Multiply-Add - Indexed Group
2576//===----------------------------------------------------------------------===//
2577
2578class sve_fp_fcmla_by_indexed_elem<bits<2> sz, string asm,
2579                                   ZPRRegOp zprty,
2580                                   ZPRRegOp zprty2, Operand itype>
2581: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, zprty2:$Zm, itype:$iop,
2582                        complexrotateop:$imm),
2583  asm, "\t$Zda, $Zn, $Zm$iop, $imm",
2584  "", []>, Sched<[]> {
2585  bits<5> Zda;
2586  bits<5> Zn;
2587  bits<2> imm;
2588  let Inst{31-24} = 0b01100100;
2589  let Inst{23-22} = sz;
2590  let Inst{21}    = 0b1;
2591  let Inst{15-12} = 0b0001;
2592  let Inst{11-10} = imm;
2593  let Inst{9-5}   = Zn;
2594  let Inst{4-0}   = Zda;
2595
2596  let Constraints = "$Zda = $_Zda";
2597  let DestructiveInstType = DestructiveOther;
2598  let ElementSize = ElementSizeNone;
2599  let hasSideEffects = 0;
2600  let mayRaiseFPException = 1;
2601}
2602
2603multiclass sve_fp_fcmla_by_indexed_elem<string asm, SDPatternOperator op> {
2604  def _H : sve_fp_fcmla_by_indexed_elem<0b10, asm, ZPR16, ZPR3b16, VectorIndexS32b> {
2605    bits<3> Zm;
2606    bits<2> iop;
2607    let Inst{20-19} = iop;
2608    let Inst{18-16} = Zm;
2609  }
2610  def _S : sve_fp_fcmla_by_indexed_elem<0b11, asm, ZPR32, ZPR4b32, VectorIndexD32b> {
2611    bits<4> Zm;
2612    bits<1> iop;
2613    let Inst{20} = iop;
2614    let Inst{19-16} = Zm;
2615  }
2616
2617  def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
2618            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
2619  def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
2620            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
2621}
2622
2623//===----------------------------------------------------------------------===//
2624// SVE Floating Point Complex Addition Group
2625//===----------------------------------------------------------------------===//
2626
2627class sve_fp_fcadd<bits<2> sz, string asm, ZPRRegOp zprty>
2628: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm,
2629                        complexrotateopodd:$imm),
2630  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm, $imm",
2631  "",
2632  []>, Sched<[]> {
2633  bits<5> Zdn;
2634  bits<5> Zm;
2635  bits<3> Pg;
2636  bit imm;
2637  let Inst{31-24} = 0b01100100;
2638  let Inst{23-22} = sz;
2639  let Inst{21-17} = 0;
2640  let Inst{16}    = imm;
2641  let Inst{15-13} = 0b100;
2642  let Inst{12-10} = Pg;
2643  let Inst{9-5}   = Zm;
2644  let Inst{4-0}   = Zdn;
2645
2646  let Constraints = "$Zdn = $_Zdn";
2647  let DestructiveInstType = DestructiveOther;
2648  let ElementSize = zprty.ElementSize;
2649  let hasSideEffects = 0;
2650  let mayRaiseFPException = 1;
2651}
2652
2653multiclass sve_fp_fcadd<string asm, SDPatternOperator op> {
2654  def _H : sve_fp_fcadd<0b01, asm, ZPR16>;
2655  def _S : sve_fp_fcadd<0b10, asm, ZPR32>;
2656  def _D : sve_fp_fcadd<0b11, asm, ZPR64>;
2657
2658  def : Pat<(nxv8f16 (op nxv8i1:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 complexrotateopodd:$imm))),
2659            (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2660  def : Pat<(nxv4f32 (op nxv4i1:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 complexrotateopodd:$imm))),
2661            (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2662  def : Pat<(nxv2f64 (op nxv2i1:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, (i32 complexrotateopodd:$imm))),
2663            (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2664}
2665
2666//===----------------------------------------------------------------------===//
2667// SVE2 Floating Point Convert Group
2668//===----------------------------------------------------------------------===//
2669
2670class sve2_fp_convert_precision<bits<4> opc, string asm,
2671                                ZPRRegOp zprty1, ZPRRegOp zprty2>
2672: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, PPR3bAny:$Pg, zprty2:$Zn),
2673  asm, "\t$Zd, $Pg/m, $Zn",
2674  "",
2675  []>, Sched<[]> {
2676  bits<5> Zd;
2677  bits<5> Zn;
2678  bits<3> Pg;
2679  let Inst{31-24} = 0b01100100;
2680  let Inst{23-22} = opc{3-2};
2681  let Inst{21-18} = 0b0010;
2682  let Inst{17-16} = opc{1-0};
2683  let Inst{15-13} = 0b101;
2684  let Inst{12-10} = Pg;
2685  let Inst{9-5}   = Zn;
2686  let Inst{4-0}   = Zd;
2687
2688  let Constraints = "$Zd = $_Zd";
2689  let hasSideEffects = 0;
2690  let mayRaiseFPException = 1;
2691}
2692
2693multiclass sve2_fp_convert_down_narrow<string asm, string op> {
2694  def _StoH : sve2_fp_convert_precision<0b1000, asm, ZPR16, ZPR32>;
2695  def _DtoS : sve2_fp_convert_precision<0b1110, asm, ZPR32, ZPR64>;
2696
2697  def : SVE_3_Op_Pat<nxv8f16, !cast<SDPatternOperator>(op # _f16f32), nxv8f16, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _StoH)>;
2698  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
2699}
2700
2701multiclass sve2_fp_convert_up_long<string asm, string op> {
2702  def _HtoS : sve2_fp_convert_precision<0b1001, asm, ZPR32, ZPR16>;
2703  def _StoD : sve2_fp_convert_precision<0b1111, asm, ZPR64, ZPR32>;
2704
2705  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f16), nxv4f32, nxv4i1, nxv8f16, !cast<Instruction>(NAME # _HtoS)>;
2706  def : SVE_3_Op_Pat<nxv2f64, !cast<SDPatternOperator>(op # _f64f32), nxv2f64, nxv2i1, nxv4f32, !cast<Instruction>(NAME # _StoD)>;
2707}
2708
2709multiclass sve2_fp_convert_down_odd_rounding_top<string asm, string op> {
2710  def _DtoS : sve2_fp_convert_precision<0b0010, asm, ZPR32, ZPR64>;
2711
2712  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
2713}
2714
2715//===----------------------------------------------------------------------===//
2716// SVE2 Floating Point Pairwise Group
2717//===----------------------------------------------------------------------===//
2718
2719class sve2_fp_pairwise_pred<bits<2> sz, bits<3> opc, string asm,
2720                            ZPRRegOp zprty>
2721: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
2722  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
2723  "",
2724  []>, Sched<[]> {
2725  bits<3> Pg;
2726  bits<5> Zm;
2727  bits<5> Zdn;
2728  let Inst{31-24} = 0b01100100;
2729  let Inst{23-22} = sz;
2730  let Inst{21-19} = 0b010;
2731  let Inst{18-16} = opc;
2732  let Inst{15-13} = 0b100;
2733  let Inst{12-10} = Pg;
2734  let Inst{9-5}   = Zm;
2735  let Inst{4-0}   = Zdn;
2736
2737  let Constraints = "$Zdn = $_Zdn";
2738  let DestructiveInstType = DestructiveOther;
2739  let ElementSize = zprty.ElementSize;
2740  let hasSideEffects = 0;
2741  let mayRaiseFPException = 1;
2742}
2743
2744multiclass sve2_fp_pairwise_pred<bits<3> opc, string asm,
2745                                 SDPatternOperator op> {
2746  def _H : sve2_fp_pairwise_pred<0b01, opc, asm, ZPR16>;
2747  def _S : sve2_fp_pairwise_pred<0b10, opc, asm, ZPR32>;
2748  def _D : sve2_fp_pairwise_pred<0b11, opc, asm, ZPR64>;
2749
2750  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2751  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2752  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2753}
2754
2755//===----------------------------------------------------------------------===//
2756// SVE2 Floating Point Widening Multiply-Add - Indexed Group
2757//===----------------------------------------------------------------------===//
2758
2759class sve2_fp_mla_long_by_indexed_elem<bits<3> opc, string asm>
2760: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR3b16:$Zm,
2761                        VectorIndexH32b:$iop),
2762  asm, "\t$Zda, $Zn, $Zm$iop",
2763  "",
2764  []>, Sched<[]> {
2765  bits<5> Zda;
2766  bits<5> Zn;
2767  bits<3> Zm;
2768  bits<3> iop;
2769  let Inst{31-23} = 0b011001001;
2770  let Inst{22}    = opc{2};
2771  let Inst{21}    = 0b1;
2772  let Inst{20-19} = iop{2-1};
2773  let Inst{18-16} = Zm;
2774  let Inst{15-14} = 0b01;
2775  let Inst{13}    = opc{1};
2776  let Inst{12}    = 0b0;
2777  let Inst{11}    = iop{0};
2778  let Inst{10}    = opc{0};
2779  let Inst{9-5}   = Zn;
2780  let Inst{4-0}   = Zda;
2781
2782  let Constraints = "$Zda = $_Zda";
2783  let DestructiveInstType = DestructiveOther;
2784  let ElementSize = ElementSizeNone;
2785  let hasSideEffects = 0;
2786  let mayRaiseFPException = 1;
2787}
2788
2789multiclass sve2_fp_mla_long_by_indexed_elem<bits<3> opc, string asm,
2790                                            ValueType OutVT, ValueType InVT,
2791                                            SDPatternOperator op> {
2792  def NAME : sve2_fp_mla_long_by_indexed_elem<opc, asm>;
2793  def : SVE_4_Op_Imm_Pat<OutVT, op, OutVT, InVT, InVT, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME)>;
2794}
2795
2796//===----------------------------------------------------------------------===//
2797// SVE2 Floating Point Widening Multiply-Add Group
2798//===----------------------------------------------------------------------===//
2799
2800class sve2_fp_mla_long<bits<3> opc, string asm>
2801: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
2802  asm, "\t$Zda, $Zn, $Zm",
2803  "",
2804  []>, Sched<[]> {
2805  bits<5> Zda;
2806  bits<5> Zn;
2807  bits<5> Zm;
2808  let Inst{31-23} = 0b011001001;
2809  let Inst{22}    = opc{2};
2810  let Inst{21}    = 0b1;
2811  let Inst{20-16} = Zm;
2812  let Inst{15-14} = 0b10;
2813  let Inst{13}    = opc{1};
2814  let Inst{12-11} = 0b00;
2815  let Inst{10}    = opc{0};
2816  let Inst{9-5}   = Zn;
2817  let Inst{4-0}   = Zda;
2818
2819  let Constraints = "$Zda = $_Zda";
2820  let DestructiveInstType = DestructiveOther;
2821  let ElementSize = ElementSizeNone;
2822  let hasSideEffects = 0;
2823  let mayRaiseFPException = 1;
2824}
2825
2826multiclass sve2_fp_mla_long<bits<3> opc, string asm, ValueType OutVT,
2827                            ValueType InVT, SDPatternOperator op> {
2828  def NAME : sve2_fp_mla_long<opc, asm>;
2829  def : SVE_3_Op_Pat<OutVT, op, OutVT, InVT, InVT, !cast<Instruction>(NAME)>;
2830}
2831
2832//===----------------------------------------------------------------------===//
2833// SVE Stack Allocation Group
2834//===----------------------------------------------------------------------===//
2835
2836class sve_int_arith_vl<bit opc, string asm, bit streaming_sve = 0b0>
2837: I<(outs GPR64sp:$Rd), (ins GPR64sp:$Rn, simm6_32b:$imm6),
2838  asm, "\t$Rd, $Rn, $imm6",
2839  "",
2840  []>, Sched<[]> {
2841  bits<5> Rd;
2842  bits<5> Rn;
2843  bits<6> imm6;
2844  let Inst{31-23} = 0b000001000;
2845  let Inst{22}    = opc;
2846  let Inst{21}    = 0b1;
2847  let Inst{20-16} = Rn;
2848  let Inst{15-12} = 0b0101;
2849  let Inst{11}    = streaming_sve;
2850  let Inst{10-5}  = imm6;
2851  let Inst{4-0}   = Rd;
2852
2853  let hasSideEffects = 0;
2854  let Uses = [VG];
2855}
2856
2857class sve_int_read_vl_a<bit op, bits<5> opc2, string asm, bit streaming_sve = 0b0>
2858: I<(outs GPR64:$Rd), (ins simm6_32b:$imm6),
2859  asm, "\t$Rd, $imm6",
2860  "",
2861  []>, Sched<[]> {
2862  bits<5> Rd;
2863  bits<6> imm6;
2864  let Inst{31-23} = 0b000001001;
2865  let Inst{22}    = op;
2866  let Inst{21}    = 0b1;
2867  let Inst{20-16} = opc2{4-0};
2868  let Inst{15-12} = 0b0101;
2869  let Inst{11}    = streaming_sve;
2870  let Inst{10-5}  = imm6;
2871  let Inst{4-0}   = Rd;
2872
2873  let hasSideEffects = 0;
2874  let isReMaterializable = 1;
2875  let Uses = [VG];
2876}
2877
2878//===----------------------------------------------------------------------===//
2879// SVE Permute - In Lane Group
2880//===----------------------------------------------------------------------===//
2881
2882class sve_int_perm_bin_perm_zz<bits<3> opc, bits<2> sz8_64, string asm,
2883                               ZPRRegOp zprty>
2884: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
2885  asm, "\t$Zd, $Zn, $Zm",
2886  "",
2887  []>, Sched<[]> {
2888  bits<5> Zd;
2889  bits<5> Zm;
2890  bits<5> Zn;
2891  let Inst{31-24} = 0b00000101;
2892  let Inst{23-22} = sz8_64;
2893  let Inst{21}    = 0b1;
2894  let Inst{20-16} = Zm;
2895  let Inst{15-13} = 0b011;
2896  let Inst{12-10} = opc;
2897  let Inst{9-5}   = Zn;
2898  let Inst{4-0}   = Zd;
2899
2900  let hasSideEffects = 0;
2901}
2902
2903multiclass sve_int_perm_bin_perm_zz<bits<3> opc, string asm,
2904                                    SDPatternOperator op> {
2905  def _B : sve_int_perm_bin_perm_zz<opc, 0b00, asm, ZPR8>;
2906  def _H : sve_int_perm_bin_perm_zz<opc, 0b01, asm, ZPR16>;
2907  def _S : sve_int_perm_bin_perm_zz<opc, 0b10, asm, ZPR32>;
2908  def _D : sve_int_perm_bin_perm_zz<opc, 0b11, asm, ZPR64>;
2909
2910  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
2911  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2912  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2913  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2914
2915  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2916  def : SVE_2_Op_Pat<nxv4f16, op, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _S)>;
2917  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2918  def : SVE_2_Op_Pat<nxv2f16, op, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _D)>;
2919  def : SVE_2_Op_Pat<nxv2f32, op, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _D)>;
2920  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2921
2922  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
2923}
2924
2925//===----------------------------------------------------------------------===//
2926// SVE Floating Point Unary Operations Group
2927//===----------------------------------------------------------------------===//
2928
2929class sve_fp_2op_p_zd<bits<7> opc, string asm, RegisterOperand i_zprtype,
2930                      RegisterOperand o_zprtype, ElementSizeEnum Sz>
2931: I<(outs o_zprtype:$Zd), (ins i_zprtype:$_Zd, PPR3bAny:$Pg, i_zprtype:$Zn),
2932  asm, "\t$Zd, $Pg/m, $Zn",
2933  "",
2934  []>, Sched<[]> {
2935  bits<3> Pg;
2936  bits<5> Zd;
2937  bits<5> Zn;
2938  let Inst{31-24} = 0b01100101;
2939  let Inst{23-22} = opc{6-5};
2940  let Inst{21}    = 0b0;
2941  let Inst{20-16} = opc{4-0};
2942  let Inst{15-13} = 0b101;
2943  let Inst{12-10} = Pg;
2944  let Inst{9-5}   = Zn;
2945  let Inst{4-0}   = Zd;
2946
2947  let Constraints = "$Zd = $_Zd";
2948  let DestructiveInstType = DestructiveUnaryPassthru;
2949  let ElementSize = Sz;
2950  let hasSideEffects = 0;
2951  let mayRaiseFPException = 1;
2952}
2953
2954multiclass sve_fp_2op_p_zd<bits<7> opc, string asm,
2955                           RegisterOperand i_zprtype,
2956                           RegisterOperand o_zprtype,
2957                           SDPatternOperator int_op,
2958                           SDPatternOperator ir_op, ValueType vt1,
2959                           ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
2960  def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>,
2961             SVEPseudo2Instr<NAME, 1>;
2962  // convert vt1 to a packed type for the intrinsic patterns
2963  defvar packedvt1 = SVEContainerVT<vt1>.Value;
2964
2965  // convert vt3 to a packed type for the intrinsic patterns
2966  defvar packedvt3 = SVEContainerVT<vt3>.Value;
2967
2968  def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, packedvt3, !cast<Instruction>(NAME)>;
2969  def : SVE_1_Op_Passthru_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
2970
2971  def _UNDEF : PredOneOpPassthruPseudo<NAME, !cast<ZPRRegOp>(i_zprtype)>;
2972
2973  defm : SVE_1_Op_PassthruUndef_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME # _UNDEF)>;
2974}
2975
2976multiclass sve_fp_2op_p_zdr<bits<7> opc, string asm,
2977                            RegisterOperand i_zprtype,
2978                            RegisterOperand o_zprtype,
2979                            SDPatternOperator int_op,
2980                            SDPatternOperator ir_op, ValueType vt1,
2981                            ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
2982  def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>,
2983             SVEPseudo2Instr<NAME, 1>;
2984
2985  // convert vt1 to a packed type for the intrinsic patterns
2986  defvar packedvt1 = SVEContainerVT<vt1>.Value;
2987
2988  def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, vt3, !cast<Instruction>(NAME)>;
2989  def : SVE_1_Op_Passthru_Round_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
2990
2991  def _UNDEF : PredOneOpPassthruPseudo<NAME, !cast<ZPRRegOp>(i_zprtype)>;
2992
2993  defm : SVE_1_Op_PassthruUndef_Round_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME # _UNDEF)>;
2994}
2995
2996multiclass sve_fp_2op_p_zd_HSD<bits<5> opc, string asm, SDPatternOperator op> {
2997  def _H : sve_fp_2op_p_zd<{ 0b01, opc }, asm, ZPR16, ZPR16, ElementSizeH>,
2998           SVEPseudo2Instr<NAME # _H, 1>;
2999  def _S : sve_fp_2op_p_zd<{ 0b10, opc }, asm, ZPR32, ZPR32, ElementSizeS>,
3000           SVEPseudo2Instr<NAME # _S, 1>;
3001  def _D : sve_fp_2op_p_zd<{ 0b11, opc }, asm, ZPR64, ZPR64, ElementSizeD>,
3002           SVEPseudo2Instr<NAME # _D, 1>;
3003
3004  def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
3005  def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
3006  def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
3007  def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
3008  def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
3009  def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
3010
3011  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
3012  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
3013  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
3014
3015  defm : SVE_1_Op_PassthruUndef_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H_UNDEF)>;
3016  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H_UNDEF)>;
3017  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H_UNDEF)>;
3018  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S_UNDEF)>;
3019  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S_UNDEF)>;
3020  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D_UNDEF)>;
3021}
3022
3023multiclass sve2_fp_flogb<string asm, string Ps, SDPatternOperator op> {
3024  def _H : sve_fp_2op_p_zd<0b0011010, asm, ZPR16, ZPR16, ElementSizeH>,
3025             SVEPseudo2Instr<Ps # _H, 1>;
3026  def _S : sve_fp_2op_p_zd<0b0011100, asm, ZPR32, ZPR32, ElementSizeS>,
3027             SVEPseudo2Instr<Ps # _S, 1>;
3028  def _D : sve_fp_2op_p_zd<0b0011110, asm, ZPR64, ZPR64, ElementSizeD>,
3029             SVEPseudo2Instr<Ps # _D, 1>;
3030
3031  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
3032  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
3033  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
3034}
3035
3036multiclass sve2_fp_un_pred_zeroing_hsd<SDPatternOperator op> {
3037  def _H_ZERO : PredOneOpPassthruPseudo<NAME # _H, ZPR16, FalseLanesZero>;
3038  def _S_ZERO : PredOneOpPassthruPseudo<NAME # _S, ZPR32, FalseLanesZero>;
3039  def _D_ZERO : PredOneOpPassthruPseudo<NAME # _D, ZPR64, FalseLanesZero>;
3040
3041  def : SVE_1_Op_PassthruZero_Pat<nxv8i16, op, nxv8i1, nxv8f16, !cast<Pseudo>(NAME # _H_ZERO)>;
3042  def : SVE_1_Op_PassthruZero_Pat<nxv4i32, op, nxv4i1, nxv4f32, !cast<Pseudo>(NAME # _S_ZERO)>;
3043  def : SVE_1_Op_PassthruZero_Pat<nxv2i64, op, nxv2i1, nxv2f64, !cast<Pseudo>(NAME # _D_ZERO)>;
3044}
3045
3046multiclass sve2_fp_convert_down_odd_rounding<string asm, string op> {
3047  def _DtoS : sve_fp_2op_p_zd<0b0001010, asm, ZPR64, ZPR32, ElementSizeD>;
3048  def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
3049}
3050
3051//===----------------------------------------------------------------------===//
3052// SVE Floating Point Unary Operations - Unpredicated Group
3053//===----------------------------------------------------------------------===//
3054
3055class sve_fp_2op_u_zd<bits<2> sz, bits<3> opc, string asm,
3056                      ZPRRegOp zprty>
3057: I<(outs zprty:$Zd), (ins zprty:$Zn),
3058  asm, "\t$Zd, $Zn",
3059  "",
3060  []>, Sched<[]> {
3061  bits<5> Zd;
3062  bits<5> Zn;
3063  let Inst{31-24} = 0b01100101;
3064  let Inst{23-22} = sz;
3065  let Inst{21-19} = 0b001;
3066  let Inst{18-16} = opc;
3067  let Inst{15-10} = 0b001100;
3068  let Inst{9-5}   = Zn;
3069  let Inst{4-0}   = Zd;
3070
3071  let hasSideEffects = 0;
3072  let mayRaiseFPException = 1;
3073}
3074
3075multiclass sve_fp_2op_u_zd<bits<3> opc, string asm, SDPatternOperator op> {
3076  def _H : sve_fp_2op_u_zd<0b01, opc, asm, ZPR16>;
3077  def _S : sve_fp_2op_u_zd<0b10, opc, asm, ZPR32>;
3078  def _D : sve_fp_2op_u_zd<0b11, opc, asm, ZPR64>;
3079
3080  def : SVE_1_Op_Pat<nxv8f16, op, nxv8f16, !cast<Instruction>(NAME # _H)>;
3081  def : SVE_1_Op_Pat<nxv4f32, op, nxv4f32, !cast<Instruction>(NAME # _S)>;
3082  def : SVE_1_Op_Pat<nxv2f64, op, nxv2f64, !cast<Instruction>(NAME # _D)>;
3083}
3084
3085//===----------------------------------------------------------------------===//
3086// SVE Integer Arithmetic - Binary Predicated Group
3087//===----------------------------------------------------------------------===//
3088
3089class sve_int_bin_pred_arit_log<bits<2> sz8_64, bits<2> fmt, bits<3> opc,
3090                                string asm, ZPRRegOp zprty>
3091: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
3092  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm", "", []>, Sched<[]> {
3093  bits<3> Pg;
3094  bits<5> Zdn;
3095  bits<5> Zm;
3096  let Inst{31-24} = 0b00000100;
3097  let Inst{23-22} = sz8_64;
3098  let Inst{21}    = 0b0;
3099  let Inst{20-19} = fmt;
3100  let Inst{18-16} = opc;
3101  let Inst{15-13} = 0b000;
3102  let Inst{12-10} = Pg;
3103  let Inst{9-5}   = Zm;
3104  let Inst{4-0}   = Zdn;
3105
3106  let Constraints = "$Zdn = $_Zdn";
3107  let DestructiveInstType = DestructiveOther;
3108  let ElementSize = zprty.ElementSize;
3109  let hasSideEffects = 0;
3110}
3111
3112multiclass sve_int_bin_pred_log<bits<3> opc, string asm, string Ps,
3113                                SDPatternOperator op,
3114                                DestructiveInstTypeEnum flags> {
3115  let DestructiveInstType = flags in {
3116  def _B : sve_int_bin_pred_arit_log<0b00, 0b11, opc, asm, ZPR8>,
3117             SVEPseudo2Instr<Ps # _B, 1>;
3118  def _H : sve_int_bin_pred_arit_log<0b01, 0b11, opc, asm, ZPR16>,
3119             SVEPseudo2Instr<Ps # _H, 1>;
3120  def _S : sve_int_bin_pred_arit_log<0b10, 0b11, opc, asm, ZPR32>,
3121             SVEPseudo2Instr<Ps # _S, 1>;
3122  def _D : sve_int_bin_pred_arit_log<0b11, 0b11, opc, asm, ZPR64>,
3123             SVEPseudo2Instr<Ps # _D, 1>;
3124  }
3125
3126  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3127  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3128  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3129  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3130}
3131
3132multiclass sve_int_bin_pred_arit_0<bits<3> opc, string asm, string Ps,
3133                                   SDPatternOperator op,
3134                                   DestructiveInstTypeEnum flags,
3135                                   string revname="", bit isReverseInstr=0> {
3136  let DestructiveInstType = flags in {
3137  def _B : sve_int_bin_pred_arit_log<0b00, 0b00, opc, asm, ZPR8>,
3138           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3139  def _H : sve_int_bin_pred_arit_log<0b01, 0b00, opc, asm, ZPR16>,
3140           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3141  def _S : sve_int_bin_pred_arit_log<0b10, 0b00, opc, asm, ZPR32>,
3142           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3143  def _D : sve_int_bin_pred_arit_log<0b11, 0b00, opc, asm, ZPR64>,
3144           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3145  }
3146
3147  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3148  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3149  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3150  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3151}
3152
3153multiclass sve_int_bin_pred_arit_1<bits<3> opc, string asm, string Ps,
3154                                   SDPatternOperator op,
3155                                   DestructiveInstTypeEnum flags> {
3156  let DestructiveInstType = flags in {
3157  def _B : sve_int_bin_pred_arit_log<0b00, 0b01, opc, asm, ZPR8>,
3158           SVEPseudo2Instr<Ps # _B, 1>;
3159  def _H : sve_int_bin_pred_arit_log<0b01, 0b01, opc, asm, ZPR16>,
3160           SVEPseudo2Instr<Ps # _H, 1>;
3161  def _S : sve_int_bin_pred_arit_log<0b10, 0b01, opc, asm, ZPR32>,
3162           SVEPseudo2Instr<Ps # _S, 1>;
3163  def _D : sve_int_bin_pred_arit_log<0b11, 0b01, opc, asm, ZPR64>,
3164           SVEPseudo2Instr<Ps # _D, 1>;
3165  }
3166
3167  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3168  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3169  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3170  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3171}
3172
3173multiclass sve_int_bin_pred_arit_2<bits<3> opc, string asm, string Ps,
3174                                   SDPatternOperator op,
3175                                   DestructiveInstTypeEnum flags> {
3176  let DestructiveInstType = flags in {
3177  def _B : sve_int_bin_pred_arit_log<0b00, 0b10, opc, asm, ZPR8>,
3178           SVEPseudo2Instr<Ps # _B, 1>;
3179  def _H : sve_int_bin_pred_arit_log<0b01, 0b10, opc, asm, ZPR16>,
3180           SVEPseudo2Instr<Ps # _H, 1>;
3181  def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>,
3182           SVEPseudo2Instr<Ps # _S, 1>;
3183  def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>,
3184           SVEPseudo2Instr<Ps # _D, 1>;
3185  }
3186
3187  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3188  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3189  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3190  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3191}
3192
3193// Special case for divides which are not defined for 8b/16b elements.
3194multiclass sve_int_bin_pred_arit_2_div<bits<3> opc, string asm, string Ps,
3195                                       SDPatternOperator op,
3196                                       DestructiveInstTypeEnum flags,
3197                                       string revname="", bit isReverseInstr=0> {
3198  let DestructiveInstType = flags in {
3199  def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>,
3200           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3201  def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>,
3202           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3203  }
3204
3205  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3206  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3207}
3208
3209//===----------------------------------------------------------------------===//
3210// SVE Integer Multiply-Add Group
3211//===----------------------------------------------------------------------===//
3212
3213class sve_int_mladdsub_vvv_pred<bits<2> sz8_64, bits<1> opc, string asm,
3214                                ZPRRegOp zprty>
3215: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm, zprty:$Za),
3216  asm, "\t$Zdn, $Pg/m, $Zm, $Za",
3217  "",
3218  []>, Sched<[]> {
3219  bits<3> Pg;
3220  bits<5> Zdn;
3221  bits<5> Za;
3222  bits<5> Zm;
3223  let Inst{31-24} = 0b00000100;
3224  let Inst{23-22} = sz8_64;
3225  let Inst{21}    = 0b0;
3226  let Inst{20-16} = Zm;
3227  let Inst{15-14} = 0b11;
3228  let Inst{13}    = opc;
3229  let Inst{12-10} = Pg;
3230  let Inst{9-5}   = Za;
3231  let Inst{4-0}   = Zdn;
3232
3233  let Constraints = "$Zdn = $_Zdn";
3234  let DestructiveInstType = DestructiveOther;
3235  let ElementSize = zprty.ElementSize;
3236  let hasSideEffects = 0;
3237}
3238
3239multiclass sve_int_mladdsub_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
3240                                     string revname, bit isReverseInstr=0> {
3241  def _B : sve_int_mladdsub_vvv_pred<0b00, opc, asm, ZPR8>,
3242           SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3243  def _H : sve_int_mladdsub_vvv_pred<0b01, opc, asm, ZPR16>,
3244           SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3245  def _S : sve_int_mladdsub_vvv_pred<0b10, opc, asm, ZPR32>,
3246           SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3247  def _D : sve_int_mladdsub_vvv_pred<0b11, opc, asm, ZPR64>,
3248           SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3249
3250  def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3251  def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3252  def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3253  def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3254}
3255
3256class sve_int_mlas_vvv_pred<bits<2> sz8_64, bits<1> opc, string asm,
3257                            ZPRRegOp zprty>
3258: I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm),
3259  asm, "\t$Zda, $Pg/m, $Zn, $Zm",
3260  "",
3261  []>, Sched<[]> {
3262  bits<3> Pg;
3263  bits<5> Zda;
3264  bits<5> Zm;
3265  bits<5> Zn;
3266  let Inst{31-24} = 0b00000100;
3267  let Inst{23-22} = sz8_64;
3268  let Inst{21}    = 0b0;
3269  let Inst{20-16} = Zm;
3270  let Inst{15-14} = 0b01;
3271  let Inst{13}    = opc;
3272  let Inst{12-10} = Pg;
3273  let Inst{9-5}   = Zn;
3274  let Inst{4-0}   = Zda;
3275
3276  let Constraints = "$Zda = $_Zda";
3277  let DestructiveInstType = DestructiveTernaryCommWithRev;
3278  let ElementSize = zprty.ElementSize;
3279  let hasSideEffects = 0;
3280}
3281
3282multiclass sve_int_mlas_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
3283                                 string Ps, string revname, bit isReverseInstr=0> {
3284  def _B : sve_int_mlas_vvv_pred<0b00, opc, asm, ZPR8>,
3285           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3286  def _H : sve_int_mlas_vvv_pred<0b01, opc, asm, ZPR16>,
3287           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3288  def _S : sve_int_mlas_vvv_pred<0b10, opc, asm, ZPR32>,
3289           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3290  def _D : sve_int_mlas_vvv_pred<0b11, opc, asm, ZPR64>,
3291           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3292
3293  def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3294  def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3295  def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3296  def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3297}
3298
3299//class for generating pseudo for SVE MLA/MAD/MLS/MSB
3300multiclass sve_int_3op_p_mladdsub<SDPatternOperator op> {
3301  def _B_UNDEF : PredThreeOpPseudo<NAME # _B, ZPR8,  FalseLanesUndef>;
3302  def _H_UNDEF : PredThreeOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
3303  def _S_UNDEF : PredThreeOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
3304  def _D_UNDEF : PredThreeOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
3305
3306  let  AddedComplexity = 9 in {
3307    def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B_UNDEF)>;
3308    def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H_UNDEF)>;
3309    def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S_UNDEF)>;
3310    def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D_UNDEF)>;
3311  }
3312}
3313
3314//===----------------------------------------------------------------------===//
3315// SVE2 Integer Multiply-Add - Unpredicated Group
3316//===----------------------------------------------------------------------===//
3317
3318class sve2_int_mla<bits<2> sz, bits<5> opc, string asm,
3319                   ZPRRegOp zprty1, ZPRRegOp zprty2>
3320: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm),
3321  asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
3322  bits<5> Zda;
3323  bits<5> Zn;
3324  bits<5> Zm;
3325  let Inst{31-24} = 0b01000100;
3326  let Inst{23-22} = sz;
3327  let Inst{21}    = 0b0;
3328  let Inst{20-16} = Zm;
3329  let Inst{15}    = 0b0;
3330  let Inst{14-10} = opc;
3331  let Inst{9-5}   = Zn;
3332  let Inst{4-0}   = Zda;
3333
3334  let Constraints = "$Zda = $_Zda";
3335  let DestructiveInstType = DestructiveOther;
3336  let ElementSize = ElementSizeNone;
3337  let hasSideEffects = 0;
3338}
3339
3340multiclass sve2_int_mla<bit S, string asm, SDPatternOperator op> {
3341  def _B : sve2_int_mla<0b00, { 0b1110, S }, asm, ZPR8, ZPR8>;
3342  def _H : sve2_int_mla<0b01, { 0b1110, S }, asm, ZPR16, ZPR16>;
3343  def _S : sve2_int_mla<0b10, { 0b1110, S }, asm, ZPR32, ZPR32>;
3344  def _D : sve2_int_mla<0b11, { 0b1110, S }, asm, ZPR64, ZPR64>;
3345
3346  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3347  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3348  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3349  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3350}
3351
3352multiclass sve2_int_mla_long<bits<5> opc, string asm, SDPatternOperator op> {
3353  def _H : sve2_int_mla<0b01, opc, asm, ZPR16, ZPR8>;
3354  def _S : sve2_int_mla<0b10, opc, asm, ZPR32, ZPR16>;
3355  def _D : sve2_int_mla<0b11, opc, asm, ZPR64, ZPR32>;
3356
3357  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3358  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
3359  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3360}
3361
3362//===----------------------------------------------------------------------===//
3363// SVE2 Integer Multiply-Add - Indexed Group
3364//===----------------------------------------------------------------------===//
3365
3366class sve2_int_mla_by_indexed_elem<bits<2> sz, bits<6> opc, string asm,
3367                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3368                                   ZPRRegOp zprty3, Operand itype>
3369: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop),
3370  asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
3371  bits<5> Zda;
3372  bits<5> Zn;
3373  let Inst{31-24} = 0b01000100;
3374  let Inst{23-22} = sz;
3375  let Inst{21}    = 0b1;
3376  let Inst{15-10} = opc;
3377  let Inst{9-5}   = Zn;
3378  let Inst{4-0}   = Zda;
3379
3380  let Constraints = "$Zda = $_Zda";
3381  let DestructiveInstType = DestructiveOther;
3382  let ElementSize = ElementSizeNone;
3383  let hasSideEffects = 0;
3384}
3385
3386multiclass sve2_int_mla_by_indexed_elem<bits<2> opc, bit S, string asm,
3387                                        SDPatternOperator op> {
3388  def _H : sve2_int_mla_by_indexed_elem<{0, ?}, { 0b000, opc, S }, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexH32b> {
3389    bits<3> Zm;
3390    bits<3> iop;
3391    let Inst{22} = iop{2};
3392    let Inst{20-19} = iop{1-0};
3393    let Inst{18-16} = Zm;
3394  }
3395  def _S : sve2_int_mla_by_indexed_elem<0b10, { 0b000, opc, S }, asm, ZPR32, ZPR32, ZPR3b32, VectorIndexS32b> {
3396    bits<3> Zm;
3397    bits<2> iop;
3398    let Inst{20-19} = iop;
3399    let Inst{18-16} = Zm;
3400  }
3401  def _D : sve2_int_mla_by_indexed_elem<0b11, { 0b000, opc, S }, asm, ZPR64, ZPR64, ZPR4b64, VectorIndexD32b> {
3402    bits<4> Zm;
3403    bit iop;
3404    let Inst{20} = iop;
3405    let Inst{19-16} = Zm;
3406  }
3407
3408  def : SVE_4_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
3409  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3410  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3411}
3412
3413//===----------------------------------------------------------------------===//
3414// SVE2 Integer Multiply-Add Long - Indexed Group
3415//===----------------------------------------------------------------------===//
3416
3417multiclass sve2_int_mla_long_by_indexed_elem<bits<4> opc, string asm,
3418                                             SDPatternOperator op> {
3419  def _S : sve2_int_mla_by_indexed_elem<0b10, { opc{3}, 0b0, opc{2-1}, ?, opc{0} },
3420                                        asm, ZPR32, ZPR16, ZPR3b16, VectorIndexH32b> {
3421    bits<3> Zm;
3422    bits<3> iop;
3423    let Inst{20-19} = iop{2-1};
3424    let Inst{18-16} = Zm;
3425    let Inst{11} = iop{0};
3426  }
3427  def _D : sve2_int_mla_by_indexed_elem<0b11, { opc{3}, 0b0, opc{2-1}, ?, opc{0} },
3428                                        asm, ZPR64, ZPR32, ZPR4b32, VectorIndexS32b> {
3429    bits<4> Zm;
3430    bits<2> iop;
3431    let Inst{20} = iop{1};
3432    let Inst{19-16} = Zm;
3433    let Inst{11} = iop{0};
3434  }
3435
3436  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _S)>;
3437  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
3438}
3439
3440//===----------------------------------------------------------------------===//
3441// SVE Integer Dot Product Group
3442//===----------------------------------------------------------------------===//
3443
3444class sve_intx_dot<bit sz, bit U, string asm, ZPRRegOp zprty1,
3445                   ZPRRegOp zprty2>
3446: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm), asm,
3447  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
3448  bits<5> Zda;
3449  bits<5> Zn;
3450  bits<5> Zm;
3451  let Inst{31-23} = 0b010001001;
3452  let Inst{22}    = sz;
3453  let Inst{21}    = 0;
3454  let Inst{20-16} = Zm;
3455  let Inst{15-11} = 0;
3456  let Inst{10}    = U;
3457  let Inst{9-5}   = Zn;
3458  let Inst{4-0}   = Zda;
3459
3460  let Constraints = "$Zda = $_Zda";
3461  let DestructiveInstType = DestructiveOther;
3462  let hasSideEffects = 0;
3463}
3464
3465multiclass sve_intx_dot<bit opc, string asm, SDPatternOperator op> {
3466  def _S : sve_intx_dot<0b0, opc, asm, ZPR32, ZPR8>;
3467  def _D : sve_intx_dot<0b1, opc, asm, ZPR64, ZPR16>;
3468
3469  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32,  nxv16i8, nxv16i8, !cast<Instruction>(NAME # _S)>;
3470  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _D)>;
3471}
3472
3473//===----------------------------------------------------------------------===//
3474// SVE Integer Dot Product Group - Indexed Group
3475//===----------------------------------------------------------------------===//
3476
3477class sve_intx_dot_by_indexed_elem<bit sz, bit U, string asm,
3478                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3479                                   ZPRRegOp zprty3, Operand itype>
3480: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop),
3481  asm, "\t$Zda, $Zn, $Zm$iop",
3482  "", []>, Sched<[]> {
3483  bits<5> Zda;
3484  bits<5> Zn;
3485  let Inst{31-23} = 0b010001001;
3486  let Inst{22}    = sz;
3487  let Inst{21}    = 0b1;
3488  let Inst{15-11} = 0;
3489  let Inst{10}    = U;
3490  let Inst{9-5}   = Zn;
3491  let Inst{4-0}   = Zda;
3492
3493  let Constraints = "$Zda = $_Zda";
3494  let DestructiveInstType = DestructiveOther;
3495  let hasSideEffects = 0;
3496}
3497
3498multiclass sve_intx_dot_by_indexed_elem<bit opc, string asm,
3499                                        SDPatternOperator op> {
3500  def _S : sve_intx_dot_by_indexed_elem<0b0, opc, asm, ZPR32, ZPR8, ZPR3b8, VectorIndexS32b_timm> {
3501    bits<2> iop;
3502    bits<3> Zm;
3503    let Inst{20-19} = iop;
3504    let Inst{18-16} = Zm;
3505  }
3506  def _D : sve_intx_dot_by_indexed_elem<0b1, opc, asm, ZPR64, ZPR16, ZPR4b16, VectorIndexD32b_timm> {
3507    bits<1> iop;
3508    bits<4> Zm;
3509    let Inst{20} = iop;
3510    let Inst{19-16} = Zm;
3511  }
3512
3513  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv16i8, nxv16i8, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3514  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv8i16, nxv8i16, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3515}
3516
3517//===----------------------------------------------------------------------===//
3518// SVE2 Complex Integer Dot Product Group
3519//===----------------------------------------------------------------------===//
3520
3521class sve2_complex_int_arith<bits<2> sz, bits<4> opc, string asm,
3522                             ZPRRegOp zprty1, ZPRRegOp zprty2>
3523: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm,
3524                         complexrotateop:$rot),
3525  asm, "\t$Zda, $Zn, $Zm, $rot", "", []>, Sched<[]> {
3526  bits<5> Zda;
3527  bits<5> Zn;
3528  bits<5> Zm;
3529  bits<2> rot;
3530  let Inst{31-24} = 0b01000100;
3531  let Inst{23-22} = sz;
3532  let Inst{21}    = 0b0;
3533  let Inst{20-16} = Zm;
3534  let Inst{15-12} = opc;
3535  let Inst{11-10} = rot;
3536  let Inst{9-5}   = Zn;
3537  let Inst{4-0}   = Zda;
3538
3539  let Constraints = "$Zda = $_Zda";
3540  let DestructiveInstType = DestructiveOther;
3541  let ElementSize = ElementSizeNone;
3542  let hasSideEffects = 0;
3543}
3544
3545multiclass sve2_cintx_dot<string asm, SDPatternOperator op> {
3546  def _S : sve2_complex_int_arith<0b10, 0b0001, asm, ZPR32, ZPR8>;
3547  def _D : sve2_complex_int_arith<0b11, 0b0001, asm, ZPR64, ZPR16>;
3548
3549  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv16i8 ZPR8:$Op2), (nxv16i8 ZPR8:$Op3),
3550                         (i32 complexrotateop:$imm))),
3551            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR8:$Op2, ZPR8:$Op3, complexrotateop:$imm)>;
3552  def : Pat<(nxv2i64 (op (nxv2i64 ZPR64:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3553                         (i32 complexrotateop:$imm))),
3554            (!cast<Instruction>(NAME # "_D") ZPR64:$Op1, ZPR16:$Op2, ZPR16:$Op3, complexrotateop:$imm)>;
3555}
3556
3557//===----------------------------------------------------------------------===//
3558// SVE2 Complex Multiply-Add Group
3559//===----------------------------------------------------------------------===//
3560
3561multiclass sve2_int_cmla<bit opc, string asm, SDPatternOperator op> {
3562  def _B : sve2_complex_int_arith<0b00, { 0b001, opc }, asm, ZPR8, ZPR8>;
3563  def _H : sve2_complex_int_arith<0b01, { 0b001, opc }, asm, ZPR16, ZPR16>;
3564  def _S : sve2_complex_int_arith<0b10, { 0b001, opc }, asm, ZPR32, ZPR32>;
3565  def _D : sve2_complex_int_arith<0b11, { 0b001, opc }, asm, ZPR64, ZPR64>;
3566
3567  def : SVE_4_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, i32, complexrotateop, !cast<Instruction>(NAME # _B)>;
3568  def : SVE_4_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, i32, complexrotateop, !cast<Instruction>(NAME # _H)>;
3569  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, i32, complexrotateop, !cast<Instruction>(NAME # _S)>;
3570  def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, i32, complexrotateop, !cast<Instruction>(NAME # _D)>;
3571}
3572
3573//===----------------------------------------------------------------------===//
3574// SVE2 Complex Integer Dot Product - Indexed Group
3575//===----------------------------------------------------------------------===//
3576
3577class sve2_complex_int_arith_indexed<bits<2> sz, bits<4> opc, string asm,
3578                                     ZPRRegOp zprty1, ZPRRegOp zprty2,
3579                                     ZPRRegOp zprty3, Operand itype>
3580: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop,
3581                         complexrotateop:$rot),
3582  asm, "\t$Zda, $Zn, $Zm$iop, $rot", "", []>, Sched<[]> {
3583  bits<5> Zda;
3584  bits<5> Zn;
3585  bits<2> rot;
3586  let Inst{31-24} = 0b01000100;
3587  let Inst{23-22} = sz;
3588  let Inst{21}    = 0b1;
3589  let Inst{15-12} = opc;
3590  let Inst{11-10} = rot;
3591  let Inst{9-5}   = Zn;
3592  let Inst{4-0}   = Zda;
3593
3594  let Constraints = "$Zda = $_Zda";
3595  let DestructiveInstType = DestructiveOther;
3596  let ElementSize = ElementSizeNone;
3597  let hasSideEffects = 0;
3598}
3599
3600multiclass sve2_cintx_dot_by_indexed_elem<string asm, SDPatternOperator op> {
3601  def _S : sve2_complex_int_arith_indexed<0b10, 0b0100, asm, ZPR32, ZPR8, ZPR3b8, VectorIndexS32b> {
3602    bits<2> iop;
3603    bits<3> Zm;
3604    let Inst{20-19} = iop;
3605    let Inst{18-16} = Zm;
3606  }
3607  def _D : sve2_complex_int_arith_indexed<0b11, 0b0100, asm, ZPR64, ZPR16, ZPR4b16, VectorIndexD32b> {
3608    bit iop;
3609    bits<4> Zm;
3610    let Inst{20} = iop;
3611    let Inst{19-16} = Zm;
3612  }
3613
3614  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv16i8 ZPR8:$Op2), (nxv16i8 ZPR8:$Op3),
3615                         (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
3616            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR8:$Op2, ZPR8:$Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
3617  def : Pat<(nxv2i64 (op (nxv2i64 ZPR64:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3618                         (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
3619            (!cast<Instruction>(NAME # "_D") ZPR64:$Op1, ZPR16:$Op2, ZPR16:$Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
3620}
3621
3622//===----------------------------------------------------------------------===//
3623// SVE2 Complex Multiply-Add - Indexed Group
3624//===----------------------------------------------------------------------===//
3625
3626multiclass sve2_cmla_by_indexed_elem<bit opc, string asm,
3627                                     SDPatternOperator op> {
3628  def _H : sve2_complex_int_arith_indexed<0b10, { 0b011, opc }, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexS32b> {
3629    bits<2> iop;
3630    bits<3> Zm;
3631    let Inst{20-19} = iop;
3632    let Inst{18-16} = Zm;
3633  }
3634  def _S : sve2_complex_int_arith_indexed<0b11, { 0b011, opc }, asm, ZPR32, ZPR32, ZPR4b32, VectorIndexD32b> {
3635    bit iop;
3636    bits<4> Zm;
3637    let Inst{20} = iop;
3638    let Inst{19-16} = Zm;
3639  }
3640
3641  def : Pat<(nxv8i16 (op (nxv8i16 ZPR16:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3642                         (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
3643            (!cast<Instruction>(NAME # "_H") ZPR16:$Op1, ZPR16:$Op2, ZPR16:$Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
3644
3645  def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv4i32 ZPR32:$Op2), (nxv4i32 ZPR32:$Op3),
3646                         (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
3647            (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR32:$Op2, ZPR32:$Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
3648}
3649
3650//===----------------------------------------------------------------------===//
3651// SVE2 Integer Multiply - Unpredicated Group
3652//===----------------------------------------------------------------------===//
3653
3654class sve2_int_mul<bits<2> sz, bits<3> opc, string asm, ZPRRegOp zprty>
3655: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
3656  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3657  bits<5> Zd;
3658  bits<5> Zm;
3659  bits<5> Zn;
3660  let Inst{31-24} = 0b00000100;
3661  let Inst{23-22} = sz;
3662  let Inst{21}    = 0b1;
3663  let Inst{20-16} = Zm;
3664  let Inst{15-13} = 0b011;
3665  let Inst{12-10} = opc;
3666  let Inst{9-5}   = Zn;
3667  let Inst{4-0}   = Zd;
3668
3669  let hasSideEffects = 0;
3670}
3671
3672multiclass sve2_int_mul<bits<3> opc, string asm, SDPatternOperator op> {
3673  def _B : sve2_int_mul<0b00, opc, asm, ZPR8>;
3674  def _H : sve2_int_mul<0b01, opc, asm, ZPR16>;
3675  def _S : sve2_int_mul<0b10, opc, asm, ZPR32>;
3676  def _D : sve2_int_mul<0b11, opc, asm, ZPR64>;
3677
3678  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3679  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3680  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3681  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3682}
3683
3684multiclass sve2_int_mul_single<bits<3> opc, string asm, SDPatternOperator op> {
3685  def _B : sve2_int_mul<0b00, opc, asm, ZPR8>;
3686
3687  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3688}
3689
3690//===----------------------------------------------------------------------===//
3691// SVE2 Integer Multiply - Indexed Group
3692//===----------------------------------------------------------------------===//
3693
3694class sve2_int_mul_by_indexed_elem<bits<2> sz, bits<4> opc, string asm,
3695                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
3696                                   ZPRRegOp zprty3, Operand itype>
3697: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty3:$Zm, itype:$iop),
3698  asm, "\t$Zd, $Zn, $Zm$iop", "", []>, Sched<[]> {
3699  bits<5> Zd;
3700  bits<5> Zn;
3701  let Inst{31-24} = 0b01000100;
3702  let Inst{23-22} = sz;
3703  let Inst{21}    = 0b1;
3704  let Inst{15-14} = 0b11;
3705  let Inst{13-10} = opc;
3706  let Inst{9-5}   = Zn;
3707  let Inst{4-0}   = Zd;
3708
3709  let hasSideEffects = 0;
3710}
3711
3712multiclass sve2_int_mul_by_indexed_elem<bits<4> opc, string asm,
3713                                        SDPatternOperator op> {
3714  def _H : sve2_int_mul_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexH32b> {
3715    bits<3> Zm;
3716    bits<3> iop;
3717    let Inst{22} = iop{2};
3718    let Inst{20-19} = iop{1-0};
3719    let Inst{18-16} = Zm;
3720  }
3721  def _S : sve2_int_mul_by_indexed_elem<0b10, opc, asm, ZPR32, ZPR32, ZPR3b32, VectorIndexS32b> {
3722    bits<3> Zm;
3723    bits<2> iop;
3724    let Inst{20-19} = iop;
3725    let Inst{18-16} = Zm;
3726  }
3727  def _D : sve2_int_mul_by_indexed_elem<0b11, opc, asm, ZPR64, ZPR64, ZPR4b64, VectorIndexD32b> {
3728    bits<4> Zm;
3729    bit iop;
3730    let Inst{20} = iop;
3731    let Inst{19-16} = Zm;
3732  }
3733
3734  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
3735  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3736  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3737}
3738
3739multiclass sve2_int_mul_long_by_indexed_elem<bits<3> opc, string asm,
3740                                             SDPatternOperator op> {
3741  def _S : sve2_int_mul_by_indexed_elem<0b10, { opc{2-1}, ?, opc{0} }, asm,
3742                                        ZPR32, ZPR16, ZPR3b16, VectorIndexH32b> {
3743    bits<3> Zm;
3744    bits<3> iop;
3745    let Inst{20-19} = iop{2-1};
3746    let Inst{18-16} = Zm;
3747    let Inst{11} = iop{0};
3748  }
3749  def _D : sve2_int_mul_by_indexed_elem<0b11, { opc{2-1}, ?, opc{0} }, asm,
3750                                        ZPR64, ZPR32, ZPR4b32, VectorIndexS32b> {
3751    bits<4> Zm;
3752    bits<2> iop;
3753    let Inst{20} = iop{1};
3754    let Inst{19-16} = Zm;
3755    let Inst{11} = iop{0};
3756  }
3757
3758  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _S)>;
3759  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
3760}
3761
3762//===----------------------------------------------------------------------===//
3763// SVE2 Integer - Predicated Group
3764//===----------------------------------------------------------------------===//
3765
3766class sve2_int_arith_pred<bits<2> sz, bits<6> opc, string asm,
3767                          ZPRRegOp zprty>
3768: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
3769  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm", "", []>, Sched<[]> {
3770  bits<3> Pg;
3771  bits<5> Zm;
3772  bits<5> Zdn;
3773  let Inst{31-24} = 0b01000100;
3774  let Inst{23-22} = sz;
3775  let Inst{21-20} = 0b01;
3776  let Inst{20-16} = opc{5-1};
3777  let Inst{15-14} = 0b10;
3778  let Inst{13}    = opc{0};
3779  let Inst{12-10} = Pg;
3780  let Inst{9-5}   = Zm;
3781  let Inst{4-0}   = Zdn;
3782
3783  let Constraints = "$Zdn = $_Zdn";
3784  let DestructiveInstType = DestructiveOther;
3785  let ElementSize = zprty.ElementSize;
3786  let hasSideEffects = 0;
3787}
3788
3789multiclass sve2_int_arith_pred<bits<6> opc, string asm, SDPatternOperator op,
3790                               string Ps = "",
3791                               DestructiveInstTypeEnum flags=DestructiveOther,
3792                               string revname="", bit isReverseInstr=0> {
3793  let DestructiveInstType = flags in {
3794  def _B : sve2_int_arith_pred<0b00, opc, asm, ZPR8>,
3795           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3796  def _H : sve2_int_arith_pred<0b01, opc, asm, ZPR16>,
3797           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3798  def _S : sve2_int_arith_pred<0b10, opc, asm, ZPR32>,
3799           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3800  def _D : sve2_int_arith_pred<0b11, opc, asm, ZPR64>,
3801           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3802  }
3803
3804  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3805  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3806  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3807  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3808}
3809
3810class sve2_int_sadd_long_accum_pairwise<bits<2> sz, bit U, string asm,
3811                                        ZPRRegOp zprty1, ZPRRegOp zprty2>
3812: I<(outs zprty1:$Zda), (ins PPR3bAny:$Pg, zprty1:$_Zda, zprty2:$Zn),
3813  asm, "\t$Zda, $Pg/m, $Zn", "", []>, Sched<[]> {
3814  bits<3> Pg;
3815  bits<5> Zn;
3816  bits<5> Zda;
3817  let Inst{31-24} = 0b01000100;
3818  let Inst{23-22} = sz;
3819  let Inst{21-17} = 0b00010;
3820  let Inst{16}    = U;
3821  let Inst{15-13} = 0b101;
3822  let Inst{12-10} = Pg;
3823  let Inst{9-5}   = Zn;
3824  let Inst{4-0}   = Zda;
3825
3826  let Constraints = "$Zda = $_Zda";
3827  let DestructiveInstType = DestructiveOther;
3828  let ElementSize = zprty1.ElementSize;
3829  let hasSideEffects = 0;
3830}
3831
3832multiclass sve2_int_sadd_long_accum_pairwise<bit U, string asm, SDPatternOperator op> {
3833  def _H : sve2_int_sadd_long_accum_pairwise<0b01, U, asm, ZPR16, ZPR8>;
3834  def _S : sve2_int_sadd_long_accum_pairwise<0b10, U, asm, ZPR32, ZPR16>;
3835  def _D : sve2_int_sadd_long_accum_pairwise<0b11, U, asm, ZPR64, ZPR32>;
3836
3837  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv16i8, !cast<Instruction>(NAME # _H)>;
3838  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv8i16, !cast<Instruction>(NAME # _S)>;
3839  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv4i32, !cast<Instruction>(NAME # _D)>;
3840}
3841
3842class sve2_int_un_pred_arit<bits<2> sz, bit Q, bits<2> opc,
3843                            string asm, ZPRRegOp zprty>
3844: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
3845  asm, "\t$Zd, $Pg/m, $Zn",
3846  "",
3847  []>, Sched<[]> {
3848  bits<3> Pg;
3849  bits<5> Zd;
3850  bits<5> Zn;
3851  let Inst{31-24} = 0b01000100;
3852  let Inst{23-22} = sz;
3853  let Inst{21-20} = 0b00;
3854  let Inst{19}    = Q;
3855  let Inst{18}    = 0b0;
3856  let Inst{17-16} = opc;
3857  let Inst{15-13} = 0b101;
3858  let Inst{12-10} = Pg;
3859  let Inst{9-5}   = Zn;
3860  let Inst{4-0}   = Zd;
3861
3862  let Constraints = "$Zd = $_Zd";
3863  let DestructiveInstType = DestructiveUnaryPassthru;
3864  let ElementSize = zprty.ElementSize;
3865  let hasSideEffects = 0;
3866}
3867
3868multiclass sve2_int_un_pred_arit_s<bits<3> opc, string asm,
3869                                   SDPatternOperator op> {
3870  def _S : sve2_int_un_pred_arit<0b10, opc{2}, opc{1-0}, asm, ZPR32>,
3871           SVEPseudo2Instr<NAME # _S, 1>;
3872
3873  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
3874
3875  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
3876
3877  defm : SVE_3_Op_Undef_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
3878}
3879
3880multiclass sve2_int_un_pred_arit<bits<3> opc, string asm, SDPatternOperator op> {
3881  def _B : sve2_int_un_pred_arit<0b00, opc{2}, opc{1-0}, asm, ZPR8>,
3882           SVEPseudo2Instr<NAME # _B, 1>;
3883  def _H : sve2_int_un_pred_arit<0b01, opc{2}, opc{1-0}, asm, ZPR16>,
3884           SVEPseudo2Instr<NAME # _H, 1>;
3885  def _S : sve2_int_un_pred_arit<0b10, opc{2}, opc{1-0}, asm, ZPR32>,
3886           SVEPseudo2Instr<NAME # _S, 1>;
3887  def _D : sve2_int_un_pred_arit<0b11, opc{2}, opc{1-0}, asm, ZPR64>,
3888           SVEPseudo2Instr<NAME # _D, 1>;
3889
3890  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
3891  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
3892  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
3893  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
3894
3895  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
3896  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
3897  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
3898  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
3899
3900  defm : SVE_3_Op_Undef_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
3901  defm : SVE_3_Op_Undef_Pat<nxv8i16, op, nxv8i16, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
3902  defm : SVE_3_Op_Undef_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
3903  defm : SVE_3_Op_Undef_Pat<nxv2i64, op, nxv2i64, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
3904}
3905
3906//===----------------------------------------------------------------------===//
3907// SVE2 Widening Integer Arithmetic Group
3908//===----------------------------------------------------------------------===//
3909
3910class sve2_wide_int_arith<bits<2> sz, bits<5> opc, string asm,
3911                          ZPRRegOp zprty1, ZPRRegOp zprty2, ZPRRegOp zprty3>
3912: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty3:$Zm),
3913  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3914  bits<5> Zd;
3915  bits<5> Zn;
3916  bits<5> Zm;
3917  let Inst{31-24} = 0b01000101;
3918  let Inst{23-22} = sz;
3919  let Inst{21}    = 0b0;
3920  let Inst{20-16} = Zm;
3921  let Inst{15}    = 0b0;
3922  let Inst{14-10} = opc;
3923  let Inst{9-5}   = Zn;
3924  let Inst{4-0}   = Zd;
3925
3926  let hasSideEffects = 0;
3927}
3928
3929multiclass sve2_wide_int_arith_long<bits<5> opc, string asm,
3930                                    SDPatternOperator op> {
3931  def _H : sve2_wide_int_arith<0b01, opc, asm, ZPR16, ZPR8, ZPR8>;
3932  def _S : sve2_wide_int_arith<0b10, opc, asm, ZPR32, ZPR16, ZPR16>;
3933  def _D : sve2_wide_int_arith<0b11, opc, asm, ZPR64, ZPR32, ZPR32>;
3934
3935  def : SVE_2_Op_Pat<nxv8i16, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3936  def : SVE_2_Op_Pat<nxv4i32, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
3937  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3938}
3939
3940multiclass sve2_wide_int_arith_wide<bits<3> opc, string asm,
3941                                    SDPatternOperator op> {
3942  def _H : sve2_wide_int_arith<0b01, { 0b10, opc }, asm, ZPR16, ZPR16, ZPR8>;
3943  def _S : sve2_wide_int_arith<0b10, { 0b10, opc }, asm, ZPR32, ZPR32, ZPR16>;
3944  def _D : sve2_wide_int_arith<0b11, { 0b10, opc }, asm, ZPR64, ZPR64, ZPR32>;
3945
3946  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, !cast<Instruction>(NAME # _H)>;
3947  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, !cast<Instruction>(NAME # _S)>;
3948  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, !cast<Instruction>(NAME # _D)>;
3949}
3950
3951multiclass sve2_wide_int_arith_pmul<bits<2> sz, bits<5> opc, string asm,
3952                                     SDPatternOperator op> {
3953  def NAME : sve2_wide_int_arith<sz, opc, asm, ZPR128, ZPR64, ZPR64>;
3954
3955  // To avoid using 128 bit elements in the IR, the pattern below works with
3956  // llvm intrinsics with the _pair suffix, to reflect that
3957  // _Q is implemented as a pair of _D.
3958  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
3959}
3960
3961multiclass sve2_pmul_long<bits<1> opc, string asm, SDPatternOperator op> {
3962  def _H : sve2_wide_int_arith<0b01, {0b1101, opc}, asm, ZPR16, ZPR8, ZPR8>;
3963  def _D : sve2_wide_int_arith<0b11, {0b1101, opc}, asm, ZPR64, ZPR32, ZPR32>;
3964
3965  // To avoid using 128 bit elements in the IR, the patterns below work with
3966  // llvm intrinsics with the _pair suffix, to reflect that
3967  // _H is implemented as a pair of _B and _D is implemented as a pair of _S.
3968  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3969  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3970}
3971
3972//===----------------------------------------------------------------------===//
3973// SVE2 Misc Group
3974//===----------------------------------------------------------------------===//
3975
3976class sve2_misc<bits<2> sz, bits<4> opc, string asm,
3977                ZPRRegOp zprty1, ZPRRegOp zprty2>
3978: I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty2:$Zm),
3979  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3980  bits<5> Zd;
3981  bits<5> Zn;
3982  bits<5> Zm;
3983  let Inst{31-24} = 0b01000101;
3984  let Inst{23-22} = sz;
3985  let Inst{21}    = 0b0;
3986  let Inst{20-16} = Zm;
3987  let Inst{15-14} = 0b10;
3988  let Inst{13-10} = opc;
3989  let Inst{9-5}   = Zn;
3990  let Inst{4-0}   = Zd;
3991
3992  let hasSideEffects = 0;
3993}
3994
3995multiclass sve2_misc_bitwise<bits<4> opc, string asm, SDPatternOperator op> {
3996  def _B : sve2_misc<0b00, opc, asm, ZPR8, ZPR8>;
3997  def _H : sve2_misc<0b01, opc, asm, ZPR16, ZPR16>;
3998  def _S : sve2_misc<0b10, opc, asm, ZPR32, ZPR32>;
3999  def _D : sve2_misc<0b11, opc, asm, ZPR64, ZPR64>;
4000
4001  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4002  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4003  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4004  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4005}
4006
4007multiclass sve2_misc_int_addsub_long_interleaved<bits<2> opc, string asm,
4008                                                 SDPatternOperator op> {
4009  def _H : sve2_misc<0b01, { 0b00, opc }, asm, ZPR16, ZPR8>;
4010  def _S : sve2_misc<0b10, { 0b00, opc }, asm, ZPR32, ZPR16>;
4011  def _D : sve2_misc<0b11, { 0b00, opc }, asm, ZPR64, ZPR32>;
4012
4013  def : SVE_2_Op_Pat<nxv8i16, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
4014  def : SVE_2_Op_Pat<nxv4i32, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
4015  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
4016}
4017
4018class sve2_bitwise_xor_interleaved<bits<2> sz, bits<1> opc, string asm,
4019                                   ZPRRegOp zprty1, ZPRRegOp zprty2>
4020: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, zprty2:$Zm),
4021  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4022  bits<5> Zd;
4023  bits<5> Zn;
4024  bits<5> Zm;
4025  let Inst{31-24} = 0b01000101;
4026  let Inst{23-22} = sz;
4027  let Inst{21}    = 0b0;
4028  let Inst{20-16} = Zm;
4029  let Inst{15-11} = 0b10010;
4030  let Inst{10}    = opc;
4031  let Inst{9-5}   = Zn;
4032  let Inst{4-0}   = Zd;
4033
4034  let Constraints = "$Zd = $_Zd";
4035  let DestructiveInstType = DestructiveOther;
4036  let ElementSize = ElementSizeNone;
4037  let hasSideEffects = 0;
4038}
4039
4040multiclass sve2_bitwise_xor_interleaved<bit opc, string asm,
4041                                        SDPatternOperator op> {
4042  def _B : sve2_bitwise_xor_interleaved<0b00, opc, asm, ZPR8,  ZPR8>;
4043  def _H : sve2_bitwise_xor_interleaved<0b01, opc, asm, ZPR16, ZPR16>;
4044  def _S : sve2_bitwise_xor_interleaved<0b10, opc, asm, ZPR32, ZPR32>;
4045  def _D : sve2_bitwise_xor_interleaved<0b11, opc, asm, ZPR64, ZPR64>;
4046
4047  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4048  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4049  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4050  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4051}
4052
4053class sve2_bitwise_shift_left_long<bits<3> tsz8_64, bits<2> opc, string asm,
4054                                   ZPRRegOp zprty1, ZPRRegOp zprty2,
4055                                   Operand immtype>
4056: I<(outs zprty1:$Zd), (ins zprty2:$Zn, immtype:$imm),
4057  asm, "\t$Zd, $Zn, $imm",
4058  "", []>, Sched<[]> {
4059  bits<5> Zd;
4060  bits<5> Zn;
4061  bits<5> imm;
4062  let Inst{31-23} = 0b010001010;
4063  let Inst{22}    = tsz8_64{2};
4064  let Inst{21}    = 0b0;
4065  let Inst{20-19} = tsz8_64{1-0};
4066  let Inst{18-16} = imm{2-0}; // imm3
4067  let Inst{15-12} = 0b1010;
4068  let Inst{11-10} = opc;
4069  let Inst{9-5}   = Zn;
4070  let Inst{4-0}   = Zd;
4071
4072  let hasSideEffects = 0;
4073}
4074
4075multiclass sve2_bitwise_shift_left_long<bits<2> opc, string asm,
4076                                        SDPatternOperator op> {
4077  def _H : sve2_bitwise_shift_left_long<{0,0,1}, opc, asm,
4078                                        ZPR16, ZPR8, vecshiftL8>;
4079  def _S : sve2_bitwise_shift_left_long<{0,1,?}, opc, asm,
4080                                        ZPR32, ZPR16, vecshiftL16> {
4081    let Inst{19} = imm{3};
4082  }
4083  def _D : sve2_bitwise_shift_left_long<{1,?,?}, opc, asm,
4084                                        ZPR64, ZPR32, vecshiftL32> {
4085    let Inst{20-19} = imm{4-3};
4086  }
4087  def : SVE_2_Op_Imm_Pat<nxv8i16, op, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _H)>;
4088  def : SVE_2_Op_Imm_Pat<nxv4i32, op, nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _S)>;
4089  def : SVE_2_Op_Imm_Pat<nxv2i64, op, nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _D)>;
4090}
4091
4092//===----------------------------------------------------------------------===//
4093// SVE2 Accumulate Group
4094//===----------------------------------------------------------------------===//
4095
4096class sve2_int_bin_shift_imm<bits<4> tsz8_64, bit opc, string asm,
4097                             ZPRRegOp zprty, Operand immtype>
4098: I<(outs zprty:$Zd), (ins zprty:$_Zd, zprty:$Zn, immtype:$imm),
4099  asm, "\t$Zd, $Zn, $imm",
4100  "", []>, Sched<[]> {
4101  bits<5> Zd;
4102  bits<5> Zn;
4103  bits<6> imm;
4104  let Inst{31-24} = 0b01000101;
4105  let Inst{23-22} = tsz8_64{3-2};
4106  let Inst{21}    = 0b0;
4107  let Inst{20-19} = tsz8_64{1-0};
4108  let Inst{18-16} = imm{2-0}; // imm3
4109  let Inst{15-11} = 0b11110;
4110  let Inst{10}    = opc;
4111  let Inst{9-5}   = Zn;
4112  let Inst{4-0}   = Zd;
4113
4114  let Constraints = "$Zd = $_Zd";
4115  let hasSideEffects = 0;
4116}
4117
4118multiclass sve2_int_bin_shift_imm_left<bit opc, string asm,
4119                                       SDPatternOperator op> {
4120  def _B : sve2_int_bin_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
4121  def _H : sve2_int_bin_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
4122    let Inst{19} = imm{3};
4123  }
4124  def _S : sve2_int_bin_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
4125    let Inst{20-19} = imm{4-3};
4126  }
4127  def _D : sve2_int_bin_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
4128    let Inst{22}    = imm{5};
4129    let Inst{20-19} = imm{4-3};
4130  }
4131
4132  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _B)>;
4133  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _H)>;
4134  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _S)>;
4135  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftL64, !cast<Instruction>(NAME # _D)>;
4136}
4137
4138multiclass sve2_int_bin_shift_imm_right<bit opc, string asm,
4139                                        SDPatternOperator op> {
4140  def _B : sve2_int_bin_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
4141  def _H : sve2_int_bin_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
4142    let Inst{19} = imm{3};
4143  }
4144  def _S : sve2_int_bin_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
4145    let Inst{20-19} = imm{4-3};
4146  }
4147  def _D : sve2_int_bin_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
4148    let Inst{22}    = imm{5};
4149    let Inst{20-19} = imm{4-3};
4150  }
4151
4152  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4153  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4154  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4155  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4156}
4157
4158class sve2_int_bin_accum_shift_imm<bits<4> tsz8_64, bits<2> opc, string asm,
4159                                   ZPRRegOp zprty, Operand immtype>
4160: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, immtype:$imm),
4161  asm, "\t$Zda, $Zn, $imm",
4162  "", []>, Sched<[]> {
4163  bits<5> Zda;
4164  bits<5> Zn;
4165  bits<6> imm;
4166  let Inst{31-24} = 0b01000101;
4167  let Inst{23-22} = tsz8_64{3-2};
4168  let Inst{21}    = 0b0;
4169  let Inst{20-19} = tsz8_64{1-0};
4170  let Inst{18-16} = imm{2-0}; // imm3
4171  let Inst{15-12} = 0b1110;
4172  let Inst{11-10} = opc;
4173  let Inst{9-5}   = Zn;
4174  let Inst{4-0}   = Zda;
4175
4176  let Constraints = "$Zda = $_Zda";
4177  let DestructiveInstType = DestructiveOther;
4178  let ElementSize = ElementSizeNone;
4179  let hasSideEffects = 0;
4180}
4181
4182multiclass sve2_int_bin_accum_shift_imm_right<bits<2> opc, string asm,
4183                                              SDPatternOperator op,
4184                                              SDPatternOperator shift_op = null_frag> {
4185  def _B : sve2_int_bin_accum_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
4186  def _H : sve2_int_bin_accum_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
4187    let Inst{19} = imm{3};
4188  }
4189  def _S : sve2_int_bin_accum_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
4190    let Inst{20-19} = imm{4-3};
4191  }
4192  def _D : sve2_int_bin_accum_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
4193    let Inst{22}    = imm{5};
4194    let Inst{20-19} = imm{4-3};
4195  }
4196
4197  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4198  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4199  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4200  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4201
4202  def : SVE_Shift_Add_All_Active_Pat<nxv16i8, shift_op, nxv16i1, nxv16i8, nxv16i8, i32, !cast<Instruction>(NAME # _B)>;
4203  def : SVE_Shift_Add_All_Active_Pat<nxv8i16, shift_op, nxv8i1, nxv8i16, nxv8i16, i32, !cast<Instruction>(NAME # _H)>;
4204  def : SVE_Shift_Add_All_Active_Pat<nxv4i32, shift_op, nxv4i1, nxv4i32, nxv4i32, i32, !cast<Instruction>(NAME # _S)>;
4205  def : SVE_Shift_Add_All_Active_Pat<nxv2i64, shift_op, nxv2i1, nxv2i64, nxv2i64, i32, !cast<Instruction>(NAME # _D)>;
4206}
4207
4208class sve2_int_cadd<bits<2> sz, bit opc, string asm, ZPRRegOp zprty>
4209: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, complexrotateopodd:$rot),
4210  asm, "\t$Zdn, $_Zdn, $Zm, $rot", "", []>, Sched<[]> {
4211  bits<5> Zdn;
4212  bits<5> Zm;
4213  bit rot;
4214  let Inst{31-24} = 0b01000101;
4215  let Inst{23-22} = sz;
4216  let Inst{21-17} = 0b00000;
4217  let Inst{16}    = opc;
4218  let Inst{15-11} = 0b11011;
4219  let Inst{10}    = rot;
4220  let Inst{9-5}   = Zm;
4221  let Inst{4-0}   = Zdn;
4222
4223  let Constraints = "$Zdn = $_Zdn";
4224  let DestructiveInstType = DestructiveOther;
4225  let ElementSize = ElementSizeNone;
4226  let hasSideEffects = 0;
4227}
4228
4229multiclass sve2_int_cadd<bit opc, string asm, SDPatternOperator op> {
4230  def _B : sve2_int_cadd<0b00, opc, asm, ZPR8>;
4231  def _H : sve2_int_cadd<0b01, opc, asm, ZPR16>;
4232  def _S : sve2_int_cadd<0b10, opc, asm, ZPR32>;
4233  def _D : sve2_int_cadd<0b11, opc, asm, ZPR64>;
4234
4235  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, complexrotateopodd, !cast<Instruction>(NAME # _B)>;
4236  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, complexrotateopodd, !cast<Instruction>(NAME # _H)>;
4237  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, complexrotateopodd, !cast<Instruction>(NAME # _S)>;
4238  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, complexrotateopodd, !cast<Instruction>(NAME # _D)>;
4239}
4240
4241class sve2_int_absdiff_accum<bits<2> sz, bits<4> opc, string asm,
4242                             ZPRRegOp zprty1, ZPRRegOp zprty2>
4243: I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm),
4244  asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
4245  bits<5> Zda;
4246  bits<5> Zn;
4247  bits<5> Zm;
4248  let Inst{31-24} = 0b01000101;
4249  let Inst{23-22} = sz;
4250  let Inst{21}    = 0b0;
4251  let Inst{20-16} = Zm;
4252  let Inst{15-14} = 0b11;
4253  let Inst{13-10} = opc;
4254  let Inst{9-5}   = Zn;
4255  let Inst{4-0}   = Zda;
4256
4257  let Constraints = "$Zda = $_Zda";
4258  let DestructiveInstType = DestructiveOther;
4259  let ElementSize = ElementSizeNone;
4260  let hasSideEffects = 0;
4261}
4262
4263multiclass sve2_int_absdiff_accum<bit opc, string asm, SDPatternOperator op> {
4264  def _B : sve2_int_absdiff_accum<0b00, { 0b111, opc }, asm, ZPR8, ZPR8>;
4265  def _H : sve2_int_absdiff_accum<0b01, { 0b111, opc }, asm, ZPR16, ZPR16>;
4266  def _S : sve2_int_absdiff_accum<0b10, { 0b111, opc }, asm, ZPR32, ZPR32>;
4267  def _D : sve2_int_absdiff_accum<0b11, { 0b111, opc }, asm, ZPR64, ZPR64>;
4268
4269  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4270  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4271  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4272  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4273}
4274
4275multiclass sve2_int_absdiff_accum_long<bits<2> opc, string asm,
4276                                       SDPatternOperator op> {
4277  def _H : sve2_int_absdiff_accum<0b01, { 0b00, opc }, asm, ZPR16, ZPR8>;
4278  def _S : sve2_int_absdiff_accum<0b10, { 0b00, opc }, asm, ZPR32, ZPR16>;
4279  def _D : sve2_int_absdiff_accum<0b11, { 0b00, opc }, asm, ZPR64, ZPR32>;
4280
4281  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
4282  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
4283  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
4284}
4285
4286multiclass sve2_int_addsub_long_carry<bits<2> opc, string asm,
4287                                      SDPatternOperator op> {
4288  def _S : sve2_int_absdiff_accum<{ opc{1}, 0b0 }, { 0b010, opc{0} }, asm,
4289                                  ZPR32, ZPR32>;
4290  def _D : sve2_int_absdiff_accum<{ opc{1}, 0b1 }, { 0b010, opc{0} }, asm,
4291                                  ZPR64, ZPR64>;
4292
4293  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4294  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4295}
4296
4297//===----------------------------------------------------------------------===//
4298// SVE2 Narrowing Group
4299//===----------------------------------------------------------------------===//
4300
4301class sve2_int_bin_shift_imm_narrow_bottom<bits<3> tsz8_64, bits<3> opc,
4302                                           string asm, ZPRRegOp zprty1,
4303                                           ZPRRegOp zprty2, Operand immtype>
4304: I<(outs zprty1:$Zd), (ins zprty2:$Zn, immtype:$imm),
4305  asm, "\t$Zd, $Zn, $imm",
4306  "", []>, Sched<[]> {
4307  bits<5> Zd;
4308  bits<5> Zn;
4309  bits<5> imm;
4310  let Inst{31-23} = 0b010001010;
4311  let Inst{22}    = tsz8_64{2};
4312  let Inst{21}    = 0b1;
4313  let Inst{20-19} = tsz8_64{1-0};
4314  let Inst{18-16} = imm{2-0}; // imm3
4315  let Inst{15-14} = 0b00;
4316  let Inst{13-11} = opc;
4317  let Inst{10}    = 0b0;
4318  let Inst{9-5}   = Zn;
4319  let Inst{4-0}   = Zd;
4320
4321  let hasSideEffects = 0;
4322}
4323
4324multiclass sve2_int_bin_shift_imm_right_narrow_bottom<bits<3> opc, string asm,
4325                                                      SDPatternOperator op> {
4326  def _B : sve2_int_bin_shift_imm_narrow_bottom<{0,0,1}, opc, asm, ZPR8, ZPR16,
4327                                                tvecshiftR8>;
4328  def _H : sve2_int_bin_shift_imm_narrow_bottom<{0,1,?}, opc, asm, ZPR16, ZPR32,
4329                                                tvecshiftR16> {
4330    let Inst{19} = imm{3};
4331  }
4332  def _S : sve2_int_bin_shift_imm_narrow_bottom<{1,?,?}, opc, asm, ZPR32, ZPR64,
4333                                                tvecshiftR32> {
4334    let Inst{20-19} = imm{4-3};
4335  }
4336  def : SVE_2_Op_Imm_Pat<nxv16i8, op, nxv8i16, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4337  def : SVE_2_Op_Imm_Pat<nxv8i16, op, nxv4i32, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4338  def : SVE_2_Op_Imm_Pat<nxv4i32, op, nxv2i64, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4339}
4340
4341class sve2_int_bin_shift_imm_narrow_top<bits<3> tsz8_64, bits<3> opc,
4342                                        string asm, ZPRRegOp zprty1,
4343                                        ZPRRegOp zprty2, Operand immtype>
4344: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, immtype:$imm),
4345  asm, "\t$Zd, $Zn, $imm",
4346  "", []>, Sched<[]> {
4347  bits<5> Zd;
4348  bits<5> Zn;
4349  bits<5> imm;
4350  let Inst{31-23} = 0b010001010;
4351  let Inst{22}    = tsz8_64{2};
4352  let Inst{21}    = 0b1;
4353  let Inst{20-19} = tsz8_64{1-0};
4354  let Inst{18-16} = imm{2-0}; // imm3
4355  let Inst{15-14} = 0b00;
4356  let Inst{13-11} = opc;
4357  let Inst{10}    = 0b1;
4358  let Inst{9-5}   = Zn;
4359  let Inst{4-0}   = Zd;
4360
4361  let Constraints = "$Zd = $_Zd";
4362  let hasSideEffects = 0;
4363}
4364
4365multiclass sve2_int_bin_shift_imm_right_narrow_top<bits<3> opc, string asm,
4366                                                   SDPatternOperator op> {
4367  def _B : sve2_int_bin_shift_imm_narrow_top<{0,0,1}, opc, asm, ZPR8, ZPR16,
4368                                             tvecshiftR8>;
4369  def _H : sve2_int_bin_shift_imm_narrow_top<{0,1,?}, opc, asm, ZPR16, ZPR32,
4370                                             tvecshiftR16> {
4371    let Inst{19} = imm{3};
4372  }
4373  def _S : sve2_int_bin_shift_imm_narrow_top<{1,?,?}, opc, asm, ZPR32, ZPR64,
4374                                             tvecshiftR32> {
4375    let Inst{20-19} = imm{4-3};
4376  }
4377  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv8i16, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4378  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv4i32, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4379  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv2i64, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4380}
4381
4382class sve2_int_addsub_narrow_high_bottom<bits<2> sz, bits<2> opc, string asm,
4383                                         ZPRRegOp zprty1, ZPRRegOp zprty2>
4384: I<(outs zprty1:$Zd), (ins 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}    = 0b0; // Top
4396  let Inst{9-5}   = Zn;
4397  let Inst{4-0}   = Zd;
4398
4399  let hasSideEffects = 0;
4400}
4401
4402multiclass sve2_int_addsub_narrow_high_bottom<bits<2> opc, string asm,
4403                                              SDPatternOperator op> {
4404  def _B : sve2_int_addsub_narrow_high_bottom<0b01, opc, asm, ZPR8, ZPR16>;
4405  def _H : sve2_int_addsub_narrow_high_bottom<0b10, opc, asm, ZPR16, ZPR32>;
4406  def _S : sve2_int_addsub_narrow_high_bottom<0b11, opc, asm, ZPR32, ZPR64>;
4407
4408  def : SVE_2_Op_Pat<nxv16i8, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _B)>;
4409  def : SVE_2_Op_Pat<nxv8i16, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _H)>;
4410  def : SVE_2_Op_Pat<nxv4i32, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _S)>;
4411}
4412
4413class sve2_int_addsub_narrow_high_top<bits<2> sz, bits<2> opc, string asm,
4414                                      ZPRRegOp zprty1, ZPRRegOp zprty2>
4415: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, zprty2:$Zm),
4416  asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4417  bits<5> Zd;
4418  bits<5> Zn;
4419  bits<5> Zm;
4420  let Inst{31-24} = 0b01000101;
4421  let Inst{23-22} = sz;
4422  let Inst{21}    = 0b1;
4423  let Inst{20-16} = Zm;
4424  let Inst{15-13} = 0b011;
4425  let Inst{12-11} = opc; // S, R
4426  let Inst{10}    = 0b1; // Top
4427  let Inst{9-5}   = Zn;
4428  let Inst{4-0}   = Zd;
4429
4430  let Constraints = "$Zd = $_Zd";
4431  let hasSideEffects = 0;
4432}
4433
4434multiclass sve2_int_addsub_narrow_high_top<bits<2> opc, string asm,
4435                                           SDPatternOperator op> {
4436  def _B : sve2_int_addsub_narrow_high_top<0b01, opc, asm, ZPR8, ZPR16>;
4437  def _H : sve2_int_addsub_narrow_high_top<0b10, opc, asm, ZPR16, ZPR32>;
4438  def _S : sve2_int_addsub_narrow_high_top<0b11, opc, asm, ZPR32, ZPR64>;
4439
4440  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _B)>;
4441  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _H)>;
4442  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _S)>;
4443}
4444
4445class sve2_int_sat_extract_narrow_bottom<bits<3> tsz8_64, bits<2> opc, string asm,
4446                                         ZPRRegOp zprty1, ZPRRegOp zprty2>
4447: I<(outs zprty1:$Zd), (ins zprty2:$Zn),
4448  asm, "\t$Zd, $Zn", "", []>, Sched<[]> {
4449  bits<5> Zd;
4450  bits<5> Zn;
4451  let Inst{31-23} = 0b010001010;
4452  let Inst{22}    = tsz8_64{2};
4453  let Inst{21}    = 0b1;
4454  let Inst{20-19} = tsz8_64{1-0};
4455  let Inst{18-13} = 0b000010;
4456  let Inst{12-11} = opc;
4457  let Inst{10}    = 0b0;
4458  let Inst{9-5}   = Zn;
4459  let Inst{4-0}   = Zd;
4460
4461  let hasSideEffects = 0;
4462}
4463
4464multiclass sve2_int_sat_extract_narrow_bottom<bits<2> opc, string asm,
4465                                              SDPatternOperator op> {
4466  def _B : sve2_int_sat_extract_narrow_bottom<0b001, opc, asm, ZPR8, ZPR16>;
4467  def _H : sve2_int_sat_extract_narrow_bottom<0b010, opc, asm, ZPR16, ZPR32>;
4468  def _S : sve2_int_sat_extract_narrow_bottom<0b100, opc, asm, ZPR32, ZPR64>;
4469
4470  def : SVE_1_Op_Pat<nxv16i8, op, nxv8i16, !cast<Instruction>(NAME # _B)>;
4471  def : SVE_1_Op_Pat<nxv8i16, op, nxv4i32, !cast<Instruction>(NAME # _H)>;
4472  def : SVE_1_Op_Pat<nxv4i32, op, nxv2i64, !cast<Instruction>(NAME # _S)>;
4473}
4474
4475class sve2_int_sat_extract_narrow_top<bits<3> tsz8_64, bits<2> opc, string asm,
4476                                      ZPRRegOp zprty1, ZPRRegOp zprty2>
4477: I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn),
4478  asm, "\t$Zd, $Zn", "", []>, Sched<[]> {
4479  bits<5> Zd;
4480  bits<5> Zn;
4481  let Inst{31-23} = 0b010001010;
4482  let Inst{22}    = tsz8_64{2};
4483  let Inst{21}    = 0b1;
4484  let Inst{20-19} = tsz8_64{1-0};
4485  let Inst{18-13} = 0b000010;
4486  let Inst{12-11} = opc;
4487  let Inst{10}    = 0b1;
4488  let Inst{9-5}   = Zn;
4489  let Inst{4-0}   = Zd;
4490
4491  let Constraints = "$Zd = $_Zd";
4492  let hasSideEffects = 0;
4493}
4494
4495multiclass sve2_int_sat_extract_narrow_top<bits<2> opc, string asm,
4496                                           SDPatternOperator op> {
4497  def _B : sve2_int_sat_extract_narrow_top<0b001, opc, asm, ZPR8, ZPR16>;
4498  def _H : sve2_int_sat_extract_narrow_top<0b010, opc, asm, ZPR16, ZPR32>;
4499  def _S : sve2_int_sat_extract_narrow_top<0b100, opc, asm, ZPR32, ZPR64>;
4500
4501  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv8i16, !cast<Instruction>(NAME # _B)>;
4502  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv4i32, !cast<Instruction>(NAME # _H)>;
4503  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
4504}
4505
4506//===----------------------------------------------------------------------===//
4507// SVE Integer Arithmetic - Unary Predicated Group
4508//===----------------------------------------------------------------------===//
4509
4510class sve_int_un_pred_arit<bits<2> sz8_64, bits<4> opc,
4511                             string asm, ZPRRegOp zprty>
4512: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
4513  asm, "\t$Zd, $Pg/m, $Zn",
4514  "",
4515  []>, Sched<[]> {
4516  bits<3> Pg;
4517  bits<5> Zd;
4518  bits<5> Zn;
4519  let Inst{31-24} = 0b00000100;
4520  let Inst{23-22} = sz8_64;
4521  let Inst{21-20} = 0b01;
4522  let Inst{19}    = opc{0};
4523  let Inst{18-16} = opc{3-1};
4524  let Inst{15-13} = 0b101;
4525  let Inst{12-10} = Pg;
4526  let Inst{9-5}   = Zn;
4527  let Inst{4-0}   = Zd;
4528
4529  let Constraints = "$Zd = $_Zd";
4530  let DestructiveInstType = DestructiveUnaryPassthru;
4531  let ElementSize = zprty.ElementSize;
4532  let hasSideEffects = 0;
4533}
4534
4535multiclass sve_int_un_pred_arit_0<bits<3> opc, string asm,
4536                                  SDPatternOperator op> {
4537  def _B : sve_int_un_pred_arit<0b00, { opc, 0b0 }, asm, ZPR8>,
4538           SVEPseudo2Instr<NAME # _B, 1>;
4539  def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>,
4540           SVEPseudo2Instr<NAME # _H, 1>;
4541  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4542           SVEPseudo2Instr<NAME # _S, 1>;
4543  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4544           SVEPseudo2Instr<NAME # _D, 1>;
4545
4546  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
4547  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
4548  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
4549  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
4550
4551  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
4552  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4553  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4554  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4555
4556  defm : SVE_1_Op_PassthruUndef_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
4557  defm : SVE_1_Op_PassthruUndef_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4558  defm : SVE_1_Op_PassthruUndef_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4559  defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4560}
4561
4562multiclass sve_int_un_pred_arit_0_h<bits<3> opc, string asm,
4563                                    SDPatternOperator op> {
4564  def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>,
4565           SVEPseudo2Instr<NAME # _H, 1>;
4566  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4567           SVEPseudo2Instr<NAME # _S, 1>;
4568  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4569           SVEPseudo2Instr<NAME # _D, 1>;
4570
4571  def : SVE_InReg_Extend<nxv8i16, op, nxv8i1, nxv8i8, !cast<Instruction>(NAME # _H)>;
4572  def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i8, !cast<Instruction>(NAME # _S)>;
4573  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i8, !cast<Instruction>(NAME # _D)>;
4574
4575  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4576  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4577  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4578
4579  defm : SVE_InReg_Extend_PassthruUndef<nxv8i16, op, nxv8i1, nxv8i8, !cast<Pseudo>(NAME # _H_UNDEF)>;
4580  defm : SVE_InReg_Extend_PassthruUndef<nxv4i32, op, nxv4i1, nxv4i8, !cast<Pseudo>(NAME # _S_UNDEF)>;
4581  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i8, !cast<Pseudo>(NAME # _D_UNDEF)>;
4582}
4583
4584multiclass sve_int_un_pred_arit_0_w<bits<3> opc, string asm,
4585                                    SDPatternOperator op> {
4586  def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4587           SVEPseudo2Instr<NAME # _S, 1>;
4588  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4589           SVEPseudo2Instr<NAME # _D, 1>;
4590
4591  def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i16, !cast<Instruction>(NAME # _S)>;
4592  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i16, !cast<Instruction>(NAME # _D)>;
4593
4594  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4595  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4596
4597  defm : SVE_InReg_Extend_PassthruUndef<nxv4i32, op, nxv4i1, nxv4i16, !cast<Pseudo>(NAME # _S_UNDEF)>;
4598  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i16, !cast<Pseudo>(NAME # _D_UNDEF)>;
4599}
4600
4601multiclass sve_int_un_pred_arit_0_d<bits<3> opc, string asm,
4602                                    SDPatternOperator op> {
4603  def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4604           SVEPseudo2Instr<NAME # _D, 1>;
4605
4606  def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i32, !cast<Instruction>(NAME # _D)>;
4607
4608  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4609
4610  defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i32, !cast<Pseudo>(NAME # _D_UNDEF)>;
4611}
4612
4613multiclass sve_int_un_pred_arit_1<bits<3> opc, string asm,
4614                                  SDPatternOperator op> {
4615  def _B : sve_int_un_pred_arit<0b00, { opc, 0b1 }, asm, ZPR8>,
4616           SVEPseudo2Instr<NAME # _B, 1>;
4617  def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>,
4618           SVEPseudo2Instr<NAME # _H, 1>;
4619  def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>,
4620           SVEPseudo2Instr<NAME # _S, 1>;
4621  def _D : sve_int_un_pred_arit<0b11, { opc, 0b1 }, asm, ZPR64>,
4622           SVEPseudo2Instr<NAME # _D, 1>;
4623
4624  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
4625  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
4626  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
4627  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
4628
4629  def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
4630  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4631  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4632  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4633
4634  defm : SVE_1_Op_PassthruUndef_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
4635  defm : SVE_1_Op_PassthruUndef_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4636  defm : SVE_1_Op_PassthruUndef_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4637  defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4638}
4639
4640multiclass sve_int_un_pred_arit_1_fp<bits<3> opc, string asm, SDPatternOperator op> {
4641  def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>,
4642           SVEPseudo2Instr<NAME # _H, 1>;
4643  def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>,
4644           SVEPseudo2Instr<NAME # _S, 1>;
4645  def _D : sve_int_un_pred_arit<0b11, { opc, 0b1 }, asm, ZPR64>,
4646           SVEPseudo2Instr<NAME # _D, 1>;
4647
4648  def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
4649  def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
4650  def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
4651  def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
4652  def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
4653  def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
4654
4655  def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4656  def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4657  def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4658
4659  defm : SVE_1_Op_PassthruUndef_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4660  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4661  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4662  defm : SVE_1_Op_PassthruUndef_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4663  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4664  defm : SVE_1_Op_PassthruUndef_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4665}
4666
4667//===----------------------------------------------------------------------===//
4668// SVE Integer Wide Immediate - Unpredicated Group
4669//===----------------------------------------------------------------------===//
4670class sve_int_dup_imm<bits<2> sz8_64, string asm,
4671                      ZPRRegOp zprty, Operand immtype>
4672: I<(outs zprty:$Zd), (ins immtype:$imm),
4673  asm, "\t$Zd, $imm",
4674  "",
4675  []>, Sched<[]> {
4676  bits<5> Zd;
4677  bits<9> imm;
4678  let Inst{31-24} = 0b00100101;
4679  let Inst{23-22} = sz8_64;
4680  let Inst{21-14} = 0b11100011;
4681  let Inst{13}    = imm{8};   // sh
4682  let Inst{12-5}  = imm{7-0}; // imm8
4683  let Inst{4-0}   = Zd;
4684
4685  let hasSideEffects = 0;
4686  let isReMaterializable = 1;
4687  let Uses = [VG];
4688}
4689
4690multiclass sve_int_dup_imm<string asm> {
4691  def _B : sve_int_dup_imm<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8>;
4692  def _H : sve_int_dup_imm<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16>;
4693  def _S : sve_int_dup_imm<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32>;
4694  def _D : sve_int_dup_imm<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64>;
4695
4696  def : InstAlias<"mov $Zd, $imm",
4697                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, cpy_imm8_opt_lsl_i8:$imm), 1>;
4698  def : InstAlias<"mov $Zd, $imm",
4699                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, cpy_imm8_opt_lsl_i16:$imm), 1>;
4700  def : InstAlias<"mov $Zd, $imm",
4701                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, cpy_imm8_opt_lsl_i32:$imm), 1>;
4702  def : InstAlias<"mov $Zd, $imm",
4703                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, cpy_imm8_opt_lsl_i64:$imm), 1>;
4704
4705  def : InstAlias<"fmov $Zd, #0.0",
4706                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, 0, 0), 1>;
4707  def : InstAlias<"fmov $Zd, #0.0",
4708                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, 0, 0), 1>;
4709  def : InstAlias<"fmov $Zd, #0.0",
4710                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, 0, 0), 1>;
4711}
4712
4713class sve_int_dup_fpimm<bits<2> sz8_64, Operand fpimmtype,
4714                        string asm, ZPRRegOp zprty>
4715: I<(outs zprty:$Zd), (ins fpimmtype:$imm8),
4716  asm, "\t$Zd, $imm8",
4717  "",
4718  []>, Sched<[]> {
4719  bits<5> Zd;
4720  bits<8> imm8;
4721  let Inst{31-24} = 0b00100101;
4722  let Inst{23-22} = sz8_64;
4723  let Inst{21-14} = 0b11100111;
4724  let Inst{13}    = 0b0;
4725  let Inst{12-5}  = imm8;
4726  let Inst{4-0}   = Zd;
4727
4728  let hasSideEffects = 0;
4729  let isReMaterializable = 1;
4730  let Uses = [VG];
4731}
4732
4733multiclass sve_int_dup_fpimm<string asm> {
4734  def _H : sve_int_dup_fpimm<0b01, fpimm16, asm, ZPR16>;
4735  def _S : sve_int_dup_fpimm<0b10, fpimm32, asm, ZPR32>;
4736  def _D : sve_int_dup_fpimm<0b11, fpimm64, asm, ZPR64>;
4737
4738  def : InstAlias<"fmov $Zd, $imm8",
4739                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, fpimm16:$imm8), 1>;
4740  def : InstAlias<"fmov $Zd, $imm8",
4741                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, fpimm32:$imm8), 1>;
4742  def : InstAlias<"fmov $Zd, $imm8",
4743                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, fpimm64:$imm8), 1>;
4744}
4745
4746class sve_int_arith_imm0<bits<2> sz8_64, bits<3> opc, string asm,
4747                         ZPRRegOp zprty, Operand immtype>
4748: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, immtype:$imm),
4749  asm, "\t$Zdn, $_Zdn, $imm",
4750  "",
4751  []>, Sched<[]> {
4752  bits<5> Zdn;
4753  bits<9> imm;
4754  let Inst{31-24} = 0b00100101;
4755  let Inst{23-22} = sz8_64;
4756  let Inst{21-19} = 0b100;
4757  let Inst{18-16} = opc;
4758  let Inst{15-14} = 0b11;
4759  let Inst{13}    = imm{8};   // sh
4760  let Inst{12-5}  = imm{7-0}; // imm8
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_imm0<bits<3> opc, string asm, SDPatternOperator op> {
4770  def _B : sve_int_arith_imm0<0b00, opc, asm, ZPR8,  addsub_imm8_opt_lsl_i8>;
4771  def _H : sve_int_arith_imm0<0b01, opc, asm, ZPR16, addsub_imm8_opt_lsl_i16>;
4772  def _S : sve_int_arith_imm0<0b10, opc, asm, ZPR32, addsub_imm8_opt_lsl_i32>;
4773  def _D : sve_int_arith_imm0<0b11, opc, asm, ZPR64, addsub_imm8_opt_lsl_i64>;
4774
4775  def : SVE_1_Op_Imm_OptLsl_Pat<nxv16i8, op, ZPR8,  i32, SVEAddSubImm8Pat,  !cast<Instruction>(NAME # _B)>;
4776  def : SVE_1_Op_Imm_OptLsl_Pat<nxv8i16, op, ZPR16, i32, SVEAddSubImm16Pat, !cast<Instruction>(NAME # _H)>;
4777  def : SVE_1_Op_Imm_OptLsl_Pat<nxv4i32, op, ZPR32, i32, SVEAddSubImm32Pat, !cast<Instruction>(NAME # _S)>;
4778  def : SVE_1_Op_Imm_OptLsl_Pat<nxv2i64, op, ZPR64, i64, SVEAddSubImm64Pat, !cast<Instruction>(NAME # _D)>;
4779}
4780
4781multiclass sve_int_arith_imm0_ssat<bits<3> opc, string asm, SDPatternOperator op,
4782                                   SDPatternOperator inv_op> {
4783  def _B : sve_int_arith_imm0<0b00, opc, asm, ZPR8,  addsub_imm8_opt_lsl_i8>;
4784  def _H : sve_int_arith_imm0<0b01, opc, asm, ZPR16, addsub_imm8_opt_lsl_i16>;
4785  def _S : sve_int_arith_imm0<0b10, opc, asm, ZPR32, addsub_imm8_opt_lsl_i32>;
4786  def _D : sve_int_arith_imm0<0b11, opc, asm, ZPR64, addsub_imm8_opt_lsl_i64>;
4787
4788  def : SVE_1_Op_Imm_OptLsl_Pat<nxv16i8, op, ZPR8,  i32, SVEAddSubSSatPosImm8Pat,  !cast<Instruction>(NAME # _B)>;
4789  def : SVE_1_Op_Imm_OptLsl_Pat<nxv8i16, op, ZPR16, i32, SVEAddSubSSatPosImm16Pat, !cast<Instruction>(NAME # _H)>;
4790  def : SVE_1_Op_Imm_OptLsl_Pat<nxv4i32, op, ZPR32, i32, SVEAddSubSSatPosImm32Pat, !cast<Instruction>(NAME # _S)>;
4791  def : SVE_1_Op_Imm_OptLsl_Pat<nxv2i64, op, ZPR64, i64, SVEAddSubSSatPosImm64Pat, !cast<Instruction>(NAME # _D)>;
4792
4793  def : SVE_1_Op_Imm_OptLsl_Pat<nxv16i8, inv_op, ZPR8,  i32, SVEAddSubSSatNegImm8Pat,  !cast<Instruction>(NAME # _B)>;
4794  def : SVE_1_Op_Imm_OptLsl_Pat<nxv8i16, inv_op, ZPR16, i32, SVEAddSubSSatNegImm16Pat, !cast<Instruction>(NAME # _H)>;
4795  def : SVE_1_Op_Imm_OptLsl_Pat<nxv4i32, inv_op, ZPR32, i32, SVEAddSubSSatNegImm32Pat, !cast<Instruction>(NAME # _S)>;
4796  def : SVE_1_Op_Imm_OptLsl_Pat<nxv2i64, inv_op, ZPR64, i64, SVEAddSubSSatNegImm64Pat, !cast<Instruction>(NAME # _D)>;
4797}
4798
4799class sve_int_arith_imm<bits<2> sz8_64, bits<6> opc, string asm,
4800                        ZPRRegOp zprty, Operand immtype>
4801: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, immtype:$imm),
4802  asm, "\t$Zdn, $_Zdn, $imm",
4803  "",
4804  []>, Sched<[]> {
4805  bits<5> Zdn;
4806  bits<8> imm;
4807  let Inst{31-24} = 0b00100101;
4808  let Inst{23-22} = sz8_64;
4809  let Inst{21-16} = opc;
4810  let Inst{15-13} = 0b110;
4811  let Inst{12-5} = imm;
4812  let Inst{4-0} = Zdn;
4813
4814  let Constraints = "$Zdn = $_Zdn";
4815  let DestructiveInstType = DestructiveOther;
4816  let ElementSize = ElementSizeNone;
4817  let hasSideEffects = 0;
4818}
4819
4820multiclass sve_int_arith_imm1<bits<2> opc, string asm, SDPatternOperator op> {
4821  def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, simm8_32b>;
4822  def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, simm8_32b>;
4823  def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, simm8_32b>;
4824  def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, simm8_32b>;
4825
4826  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B)>;
4827  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1,  op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H)>;
4828  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1,  op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S)>;
4829  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1,  op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D)>;
4830}
4831
4832multiclass sve_int_arith_imm1_unsigned<bits<2> opc, string asm, SDPatternOperator op> {
4833  def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, imm0_255>;
4834  def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, imm0_255>;
4835  def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, imm0_255>;
4836  def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, imm0_255>;
4837
4838  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithUImm8Pat, !cast<Instruction>(NAME # _B)>;
4839  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithUImm16Pat, !cast<Instruction>(NAME # _H)>;
4840  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithUImm32Pat, !cast<Instruction>(NAME # _S)>;
4841  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithUImm64Pat, !cast<Instruction>(NAME # _D)>;
4842}
4843
4844multiclass sve_int_arith_imm2<string asm, SDPatternOperator op> {
4845  def _B : sve_int_arith_imm<0b00, 0b110000, asm, ZPR8,  simm8_32b>;
4846  def _H : sve_int_arith_imm<0b01, 0b110000, asm, ZPR16, simm8_32b>;
4847  def _S : sve_int_arith_imm<0b10, 0b110000, asm, ZPR32, simm8_32b>;
4848  def _D : sve_int_arith_imm<0b11, 0b110000, asm, ZPR64, simm8_32b>;
4849
4850  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B)>;
4851  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H)>;
4852  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S)>;
4853  def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D)>;
4854}
4855
4856//===----------------------------------------------------------------------===//
4857// SVE Bitwise Logical - Unpredicated Group
4858//===----------------------------------------------------------------------===//
4859
4860class sve_int_bin_cons_log<bits<2> opc, string asm>
4861: I<(outs ZPR64:$Zd), (ins ZPR64:$Zn, ZPR64:$Zm),
4862  asm, "\t$Zd, $Zn, $Zm",
4863  "",
4864  []>, Sched<[]> {
4865  bits<5> Zd;
4866  bits<5> Zm;
4867  bits<5> Zn;
4868  let Inst{31-24} = 0b00000100;
4869  let Inst{23-22} = opc{1-0};
4870  let Inst{21}    = 0b1;
4871  let Inst{20-16} = Zm;
4872  let Inst{15-10} = 0b001100;
4873  let Inst{9-5}   = Zn;
4874  let Inst{4-0}   = Zd;
4875
4876  let hasSideEffects = 0;
4877}
4878
4879multiclass sve_int_bin_cons_log<bits<2> opc, string asm, SDPatternOperator op> {
4880  def NAME : sve_int_bin_cons_log<opc, asm>;
4881
4882  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
4883  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
4884  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
4885  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4886
4887  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4888                  (!cast<Instruction>(NAME) ZPR8:$Zd,  ZPR8:$Zn,  ZPR8:$Zm),  1>;
4889  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4890                  (!cast<Instruction>(NAME) ZPR16:$Zd, ZPR16:$Zn, ZPR16:$Zm), 1>;
4891  def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4892                  (!cast<Instruction>(NAME) ZPR32:$Zd, ZPR32:$Zn, ZPR32:$Zm), 1>;
4893}
4894
4895class sve2_int_bitwise_ternary_op_d<bits<3> opc, string asm>
4896: I<(outs ZPR64:$Zdn), (ins ZPR64:$_Zdn, ZPR64:$Zm, ZPR64:$Zk),
4897  asm, "\t$Zdn, $_Zdn, $Zm, $Zk",
4898  "",
4899  []>, Sched<[]> {
4900  bits<5> Zdn;
4901  bits<5> Zk;
4902  bits<5> Zm;
4903  let Inst{31-24} = 0b00000100;
4904  let Inst{23-22} = opc{2-1};
4905  let Inst{21}    = 0b1;
4906  let Inst{20-16} = Zm;
4907  let Inst{15-11} = 0b00111;
4908  let Inst{10}    = opc{0};
4909  let Inst{9-5}   = Zk;
4910  let Inst{4-0}   = Zdn;
4911
4912  let Constraints = "$Zdn = $_Zdn";
4913  let DestructiveInstType = DestructiveOther;
4914  let ElementSize = ElementSizeNone;
4915  let hasSideEffects = 0;
4916}
4917
4918multiclass sve2_int_bitwise_ternary_op<bits<3> opc, string asm,
4919                                       SDPatternOperator op> {
4920  def NAME : sve2_int_bitwise_ternary_op_d<opc, asm>;
4921
4922  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4923                  (!cast<Instruction>(NAME) ZPR8:$Zdn,  ZPR8:$Zm,  ZPR8:$Zk),  1>;
4924  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4925                  (!cast<Instruction>(NAME) ZPR16:$Zdn, ZPR16:$Zm, ZPR16:$Zk), 1>;
4926  def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4927                  (!cast<Instruction>(NAME) ZPR32:$Zdn, ZPR32:$Zm, ZPR32:$Zk), 1>;
4928
4929  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
4930  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
4931  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
4932  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4933}
4934
4935class sve2_int_rotate_right_imm<bits<4> tsz8_64, string asm,
4936                                ZPRRegOp zprty, Operand immtype>
4937: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, immtype:$imm),
4938  asm, "\t$Zdn, $_Zdn, $Zm, $imm",
4939  "",
4940  []>, Sched<[]> {
4941  bits<5> Zdn;
4942  bits<5> Zm;
4943  bits<6> imm;
4944  let Inst{31-24} = 0b00000100;
4945  let Inst{23-22} = tsz8_64{3-2};
4946  let Inst{21}    = 0b1;
4947  let Inst{20-19} = tsz8_64{1-0};
4948  let Inst{18-16} = imm{2-0}; // imm3
4949  let Inst{15-10} = 0b001101;
4950  let Inst{9-5}   = Zm;
4951  let Inst{4-0}   = Zdn;
4952
4953  let Constraints = "$Zdn = $_Zdn";
4954  let DestructiveInstType = DestructiveOther;
4955  let ElementSize = ElementSizeNone;
4956  let hasSideEffects = 0;
4957}
4958
4959multiclass sve2_int_rotate_right_imm<string asm, SDPatternOperator op> {
4960  def _B : sve2_int_rotate_right_imm<{0,0,0,1}, asm, ZPR8, vecshiftR8>;
4961  def _H : sve2_int_rotate_right_imm<{0,0,1,?}, asm, ZPR16, vecshiftR16> {
4962    let Inst{19} = imm{3};
4963  }
4964  def _S : sve2_int_rotate_right_imm<{0,1,?,?}, asm, ZPR32, vecshiftR32> {
4965    let Inst{20-19} = imm{4-3};
4966  }
4967  def _D : sve2_int_rotate_right_imm<{1,?,?,?}, asm, ZPR64, vecshiftR64> {
4968    let Inst{22}    = imm{5};
4969    let Inst{20-19} = imm{4-3};
4970  }
4971
4972  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4973  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4974  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4975  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4976}
4977
4978//===----------------------------------------------------------------------===//
4979// SVE Integer Wide Immediate - Predicated Group
4980//===----------------------------------------------------------------------===//
4981
4982class sve_int_dup_fpimm_pred<bits<2> sz, Operand fpimmtype,
4983                             string asm, ZPRRegOp zprty>
4984: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPRAny:$Pg, fpimmtype:$imm8),
4985  asm, "\t$Zd, $Pg/m, $imm8",
4986  "",
4987  []>, Sched<[]> {
4988  bits<4> Pg;
4989  bits<5> Zd;
4990  bits<8> imm8;
4991  let Inst{31-24} = 0b00000101;
4992  let Inst{23-22} = sz;
4993  let Inst{21-20} = 0b01;
4994  let Inst{19-16} = Pg;
4995  let Inst{15-13} = 0b110;
4996  let Inst{12-5}  = imm8;
4997  let Inst{4-0}   = Zd;
4998
4999  let Constraints = "$Zd = $_Zd";
5000  let DestructiveInstType = DestructiveOther;
5001  let ElementSize = zprty.ElementSize;
5002  let hasSideEffects = 0;
5003}
5004
5005multiclass sve_int_dup_fpimm_pred<string asm> {
5006  def _H : sve_int_dup_fpimm_pred<0b01, fpimm16, asm, ZPR16>;
5007  def _S : sve_int_dup_fpimm_pred<0b10, fpimm32, asm, ZPR32>;
5008  def _D : sve_int_dup_fpimm_pred<0b11, fpimm64, asm, ZPR64>;
5009
5010  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
5011                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, fpimm16:$imm8), 1>;
5012  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
5013                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, fpimm32:$imm8), 1>;
5014  def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
5015                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, fpimm64:$imm8), 1>;
5016}
5017
5018class sve_int_dup_imm_pred<bits<2> sz8_64, bit m, string asm,
5019                           ZPRRegOp zprty, string pred_qual, dag iops>
5020: I<(outs zprty:$Zd), iops,
5021  asm, "\t$Zd, $Pg"#pred_qual#", $imm",
5022  "", []>, Sched<[]> {
5023  bits<5> Zd;
5024  bits<4> Pg;
5025  bits<9> imm;
5026  let Inst{31-24} = 0b00000101;
5027  let Inst{23-22} = sz8_64;
5028  let Inst{21-20} = 0b01;
5029  let Inst{19-16} = Pg;
5030  let Inst{15}    = 0b0;
5031  let Inst{14}    = m;
5032  let Inst{13}    = imm{8};   // sh
5033  let Inst{12-5}  = imm{7-0}; // imm8
5034  let Inst{4-0}   = Zd;
5035
5036  let DestructiveInstType = DestructiveOther;
5037  let ElementSize = zprty.ElementSize;
5038  let hasSideEffects = 0;
5039}
5040
5041multiclass sve_int_dup_imm_pred_merge_inst<
5042    bits<2> sz8_64, string asm, ZPRRegOp zprty, imm8_opt_lsl cpyimm,
5043    ValueType intty, ValueType predty, ValueType scalarty, ComplexPattern cpx> {
5044  let Constraints = "$Zd = $_Zd" in
5045  def NAME : sve_int_dup_imm_pred<sz8_64, 1, asm, zprty,  "/m",
5046                                  (ins zprty:$_Zd, PPRAny:$Pg, cpyimm:$imm)>;
5047  def : InstAlias<"mov $Zd, $Pg/m, $imm",
5048                  (!cast<Instruction>(NAME) zprty:$Zd, PPRAny:$Pg, cpyimm:$imm), 1>;
5049  def : Pat<(vselect predty:$Pg,
5050                (intty (splat_vector (scalarty (cpx i32:$imm, i32:$shift)))),
5051                ZPR:$Zd),
5052            (!cast<Instruction>(NAME) $Zd, $Pg, $imm, $shift)>;
5053}
5054
5055multiclass sve_int_dup_imm_pred_merge<string asm> {
5056  defm _B : sve_int_dup_imm_pred_merge_inst<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8,
5057                                            nxv16i8, nxv16i1, i32, SVECpyDupImm8Pat>;
5058  defm _H : sve_int_dup_imm_pred_merge_inst<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16,
5059                                            nxv8i16, nxv8i1, i32, SVECpyDupImm16Pat>;
5060  defm _S : sve_int_dup_imm_pred_merge_inst<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32,
5061                                            nxv4i32, nxv4i1, i32, SVECpyDupImm32Pat>;
5062  defm _D : sve_int_dup_imm_pred_merge_inst<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64,
5063                                            nxv2i64, nxv2i1, i64, SVECpyDupImm64Pat>;
5064
5065  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5066                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, 0, 0), 0>;
5067  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5068                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, 0, 0), 0>;
5069  def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5070                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, 0, 0), 0>;
5071
5072  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv8f16 ZPR:$Zd)),
5073            (!cast<Instruction>(NAME # _H) $Zd, $Pg, 0, 0)>;
5074  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv4f16 ZPR:$Zd)),
5075            (!cast<Instruction>(NAME # _S) $Zd, $Pg, 0, 0)>;
5076  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f16 ZPR:$Zd)),
5077            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5078  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv4f32 ZPR:$Zd)),
5079            (!cast<Instruction>(NAME # _S) $Zd, $Pg, 0, 0)>;
5080  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f32 ZPR:$Zd)),
5081            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5082  def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f64 ZPR:$Zd)),
5083            (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5084}
5085
5086multiclass sve_int_dup_imm_pred_zero_inst<
5087    bits<2> sz8_64, string asm, ZPRRegOp zprty, imm8_opt_lsl cpyimm,
5088    ValueType intty, ValueType predty, ValueType scalarty, ComplexPattern cpx> {
5089  def NAME : sve_int_dup_imm_pred<sz8_64, 0, asm, zprty, "/z",
5090                                  (ins PPRAny:$Pg, cpyimm:$imm)>;
5091  def : InstAlias<"mov $Zd, $Pg/z, $imm",
5092                  (!cast<Instruction>(NAME) zprty:$Zd, PPRAny:$Pg, cpyimm:$imm), 1>;
5093  def : Pat<(intty (zext (predty PPRAny:$Ps1))),
5094            (!cast<Instruction>(NAME) PPRAny:$Ps1, 1, 0)>;
5095  def : Pat<(intty (sext (predty PPRAny:$Ps1))),
5096            (!cast<Instruction>(NAME) PPRAny:$Ps1, -1, 0)>;
5097  def : Pat<(intty (anyext (predty PPRAny:$Ps1))),
5098            (!cast<Instruction>(NAME) PPRAny:$Ps1, 1, 0)>;
5099  def : Pat<(vselect predty:$Pg,
5100                (intty (splat_vector (scalarty (cpx i32:$imm, i32:$shift)))),
5101                (intty (splat_vector (scalarty 0)))),
5102            (!cast<Instruction>(NAME) $Pg, $imm, $shift)>;
5103}
5104
5105multiclass sve_int_dup_imm_pred_zero<string asm> {
5106  defm _B : sve_int_dup_imm_pred_zero_inst<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8,
5107                                           nxv16i8, nxv16i1, i32, SVECpyDupImm8Pat>;
5108  defm _H : sve_int_dup_imm_pred_zero_inst<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16,
5109                                           nxv8i16, nxv8i1, i32, SVECpyDupImm16Pat>;
5110  defm _S : sve_int_dup_imm_pred_zero_inst<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32,
5111                                           nxv4i32, nxv4i1, i32, SVECpyDupImm32Pat>;
5112  defm _D : sve_int_dup_imm_pred_zero_inst<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64,
5113                                           nxv2i64, nxv2i1, i64, SVECpyDupImm64Pat>;
5114}
5115
5116//===----------------------------------------------------------------------===//
5117// SVE Integer Compare - Vectors Group
5118//===----------------------------------------------------------------------===//
5119
5120class sve_int_cmp<bit cmp_1, bits<2> sz8_64, bits<3> opc, string asm,
5121                  PPRRegOp pprty, ZPRRegOp zprty1, ZPRRegOp zprty2>
5122: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty1:$Zn, zprty2:$Zm),
5123  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
5124  "",
5125  []>, Sched<[]> {
5126  bits<4> Pd;
5127  bits<3> Pg;
5128  bits<5> Zm;
5129  bits<5> Zn;
5130  let Inst{31-24} = 0b00100100;
5131  let Inst{23-22} = sz8_64;
5132  let Inst{21}    = 0b0;
5133  let Inst{20-16} = Zm;
5134  let Inst{15}    = opc{2};
5135  let Inst{14}    = cmp_1;
5136  let Inst{13}    = opc{1};
5137  let Inst{12-10} = Pg;
5138  let Inst{9-5}   = Zn;
5139  let Inst{4}     = opc{0};
5140  let Inst{3-0}   = Pd;
5141
5142  let Defs = [NZCV];
5143  let ElementSize = pprty.ElementSize;
5144  let hasSideEffects = 0;
5145  let isPTestLike = 1;
5146}
5147
5148multiclass SVE_SETCC_Pat<CondCode cc, CondCode invcc, ValueType predvt,
5149                         ValueType intvt, Instruction cmp> {
5150  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, intvt:$Op3, cc)),
5151            (cmp $Op1, $Op2, $Op3)>;
5152  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, intvt:$Op3, invcc)),
5153            (cmp $Op1, $Op3, $Op2)>;
5154  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (SVEAllActive)), intvt:$Op2, intvt:$Op3, cc))),
5155            (cmp $Pg, $Op2, $Op3)>;
5156  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (SVEAllActive)), intvt:$Op2, intvt:$Op3, invcc))),
5157            (cmp $Pg, $Op3, $Op2)>;
5158}
5159
5160multiclass SVE_SETCC_Pat_With_Zero<CondCode cc, CondCode invcc, ValueType predvt,
5161                                   ValueType intvt, Instruction cmp> {
5162  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, (SVEDup0), cc)),
5163            (cmp $Op1, $Op2)>;
5164  def : Pat<(predvt (AArch64setcc_z predvt:$Op1, (SVEDup0), intvt:$Op2, invcc)),
5165            (cmp $Op1, $Op2)>;
5166  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (SVEAllActive)), intvt:$Op1, (SVEDup0), cc))),
5167            (cmp $Pg, $Op1)>;
5168  def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (SVEAllActive)), (SVEDup0), intvt:$Op1, invcc))),
5169            (cmp $Pg, $Op1)>;
5170}
5171
5172multiclass sve_int_cmp_0<bits<3> opc, string asm, CondCode cc, CondCode invcc> {
5173  def _B : sve_int_cmp<0b0, 0b00, opc, asm, PPR8, ZPR8, ZPR8>;
5174  def _H : sve_int_cmp<0b0, 0b01, opc, asm, PPR16, ZPR16, ZPR16>;
5175  def _S : sve_int_cmp<0b0, 0b10, opc, asm, PPR32, ZPR32, ZPR32>;
5176  def _D : sve_int_cmp<0b0, 0b11, opc, asm, PPR64, ZPR64, ZPR64>;
5177
5178  defm : SVE_SETCC_Pat<cc, invcc, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
5179  defm : SVE_SETCC_Pat<cc, invcc, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
5180  defm : SVE_SETCC_Pat<cc, invcc, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
5181  defm : SVE_SETCC_Pat<cc, invcc, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
5182}
5183
5184multiclass sve_int_cmp_0_wide<bits<3> opc, string asm, SDPatternOperator op> {
5185  def _B : sve_int_cmp<0b0, 0b00, opc, asm, PPR8, ZPR8, ZPR64>;
5186  def _H : sve_int_cmp<0b0, 0b01, opc, asm, PPR16, ZPR16, ZPR64>;
5187  def _S : sve_int_cmp<0b0, 0b10, opc, asm, PPR32, ZPR32, ZPR64>;
5188
5189  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
5190  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
5191  def : SVE_3_Op_Pat<nxv4i1,  op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
5192}
5193
5194multiclass sve_int_cmp_1_wide<bits<3> opc, string asm, SDPatternOperator op> {
5195  def _B : sve_int_cmp<0b1, 0b00, opc, asm, PPR8, ZPR8, ZPR64>;
5196  def _H : sve_int_cmp<0b1, 0b01, opc, asm, PPR16, ZPR16, ZPR64>;
5197  def _S : sve_int_cmp<0b1, 0b10, opc, asm, PPR32, ZPR32, ZPR64>;
5198
5199  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
5200  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
5201  def : SVE_3_Op_Pat<nxv4i1,  op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
5202}
5203
5204
5205//===----------------------------------------------------------------------===//
5206// SVE Integer Compare - Signed Immediate Group
5207//===----------------------------------------------------------------------===//
5208
5209class sve_int_scmp_vi<bits<2> sz8_64, bits<3> opc, string asm, PPRRegOp pprty,
5210                      ZPRRegOp zprty,
5211                      Operand immtype>
5212: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, immtype:$imm5),
5213  asm, "\t$Pd, $Pg/z, $Zn, $imm5",
5214  "",
5215  []>, Sched<[]> {
5216  bits<4> Pd;
5217  bits<3> Pg;
5218  bits<5> Zn;
5219  bits<5> imm5;
5220  let Inst{31-24} = 0b00100101;
5221  let Inst{23-22} = sz8_64;
5222  let Inst{21}    = 0b0;
5223  let Inst{20-16} = imm5;
5224  let Inst{15}    = opc{2};
5225  let Inst{14}    = 0b0;
5226  let Inst{13}    = opc{1};
5227  let Inst{12-10} = Pg;
5228  let Inst{9-5}   = Zn;
5229  let Inst{4}     = opc{0};
5230  let Inst{3-0}   = Pd;
5231
5232  let Defs = [NZCV];
5233  let ElementSize = pprty.ElementSize;
5234  let hasSideEffects = 0;
5235  let isPTestLike = 1;
5236}
5237
5238multiclass SVE_SETCC_Imm_Pat<CondCode cc, CondCode commuted_cc,
5239                             ValueType predvt, ValueType intvt,
5240                             Operand immtype, Instruction cmp> {
5241  def : Pat<(predvt (AArch64setcc_z (predvt PPR_3b:$Pg),
5242                                    (intvt ZPR:$Zs1),
5243                                    (intvt (splat_vector (immtype:$imm))),
5244                                    cc)),
5245            (cmp $Pg, $Zs1, immtype:$imm)>;
5246  def : Pat<(predvt (AArch64setcc_z (predvt PPR_3b:$Pg),
5247                                    (intvt (splat_vector (immtype:$imm))),
5248                                    (intvt ZPR:$Zs1),
5249                                    commuted_cc)),
5250            (cmp $Pg, $Zs1, immtype:$imm)>;
5251  def : Pat<(predvt (and predvt:$Pg,
5252                         (AArch64setcc_z_oneuse (predvt (SVEAllActive)),
5253                                         (intvt ZPR:$Zs1),
5254                                         (intvt (splat_vector (immtype:$imm))),
5255                                         cc))),
5256            (cmp $Pg, $Zs1, immtype:$imm)>;
5257  def : Pat<(predvt (and predvt:$Pg,
5258                         (AArch64setcc_z_oneuse (predvt (SVEAllActive)),
5259                                         (intvt (splat_vector (immtype:$imm))),
5260                                         (intvt ZPR:$Zs1),
5261                                         commuted_cc))),
5262            (cmp $Pg, $Zs1, immtype:$imm)>;
5263}
5264
5265multiclass sve_int_scmp_vi<bits<3> opc, string asm, CondCode cc, CondCode commuted_cc> {
5266  def _B : sve_int_scmp_vi<0b00, opc, asm, PPR8, ZPR8, simm5_32b>;
5267  def _H : sve_int_scmp_vi<0b01, opc, asm, PPR16, ZPR16, simm5_32b>;
5268  def _S : sve_int_scmp_vi<0b10, opc, asm, PPR32, ZPR32, simm5_32b>;
5269  def _D : sve_int_scmp_vi<0b11, opc, asm, PPR64, ZPR64, simm5_64b>;
5270
5271  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv16i1, nxv16i8, simm5_32b,
5272                           !cast<Instruction>(NAME # _B)>;
5273  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv8i1,  nxv8i16, simm5_32b,
5274                           !cast<Instruction>(NAME # _H)>;
5275  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv4i1,  nxv4i32, simm5_32b,
5276                           !cast<Instruction>(NAME # _S)>;
5277  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv2i1,  nxv2i64, simm5_64b,
5278                           !cast<Instruction>(NAME # _D)>;
5279}
5280
5281
5282//===----------------------------------------------------------------------===//
5283// SVE Integer Compare - Unsigned Immediate Group
5284//===----------------------------------------------------------------------===//
5285
5286class sve_int_ucmp_vi<bits<2> sz8_64, bits<2> opc, string asm, PPRRegOp pprty,
5287                      ZPRRegOp zprty, Operand immtype>
5288: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, immtype:$imm7),
5289  asm, "\t$Pd, $Pg/z, $Zn, $imm7",
5290  "",
5291  []>, Sched<[]> {
5292  bits<4> Pd;
5293  bits<3> Pg;
5294  bits<5> Zn;
5295  bits<7> imm7;
5296  let Inst{31-24} = 0b00100100;
5297  let Inst{23-22} = sz8_64;
5298  let Inst{21}    = 1;
5299  let Inst{20-14} = imm7;
5300  let Inst{13}    = opc{1};
5301  let Inst{12-10} = Pg;
5302  let Inst{9-5}   = Zn;
5303  let Inst{4}     = opc{0};
5304  let Inst{3-0}   = Pd;
5305
5306  let Defs = [NZCV];
5307  let ElementSize = pprty.ElementSize;
5308  let hasSideEffects = 0;
5309  let isPTestLike = 1;
5310}
5311
5312multiclass sve_int_ucmp_vi<bits<2> opc, string asm, CondCode cc,
5313                           CondCode commuted_cc> {
5314  def _B : sve_int_ucmp_vi<0b00, opc, asm, PPR8, ZPR8, imm0_127>;
5315  def _H : sve_int_ucmp_vi<0b01, opc, asm, PPR16, ZPR16, imm0_127>;
5316  def _S : sve_int_ucmp_vi<0b10, opc, asm, PPR32, ZPR32, imm0_127>;
5317  def _D : sve_int_ucmp_vi<0b11, opc, asm, PPR64, ZPR64, imm0_127_64b>;
5318
5319  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv16i1, nxv16i8, imm0_127,
5320                           !cast<Instruction>(NAME # _B)>;
5321  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv8i1,  nxv8i16, imm0_127,
5322                           !cast<Instruction>(NAME # _H)>;
5323  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv4i1,  nxv4i32, imm0_127,
5324                           !cast<Instruction>(NAME # _S)>;
5325  defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv2i1,  nxv2i64, imm0_127_64b,
5326                           !cast<Instruction>(NAME # _D)>;
5327}
5328
5329
5330//===----------------------------------------------------------------------===//
5331// SVE Integer Compare - Scalars Group
5332//===----------------------------------------------------------------------===//
5333
5334class sve_int_cterm<bit sz, bit opc, string asm, RegisterClass rt>
5335: I<(outs), (ins rt:$Rn, rt:$Rm),
5336  asm, "\t$Rn, $Rm",
5337  "",
5338  []>, Sched<[]> {
5339  bits<5> Rm;
5340  bits<5> Rn;
5341  let Inst{31-23} = 0b001001011;
5342  let Inst{22}    = sz;
5343  let Inst{21}    = 0b1;
5344  let Inst{20-16} = Rm;
5345  let Inst{15-10} = 0b001000;
5346  let Inst{9-5}   = Rn;
5347  let Inst{4}     = opc;
5348  let Inst{3-0}   = 0b0000;
5349
5350  let Defs = [NZCV];
5351  let hasSideEffects = 0;
5352}
5353
5354class sve_int_while_rr<bits<2> sz8_64, bits<4> opc, string asm,
5355                       RegisterClass gprty, PPRRegOp pprty>
5356: I<(outs pprty:$Pd), (ins gprty:$Rn, gprty:$Rm),
5357  asm, "\t$Pd, $Rn, $Rm",
5358  "", []>, Sched<[]> {
5359  bits<4> Pd;
5360  bits<5> Rm;
5361  bits<5> Rn;
5362  let Inst{31-24} = 0b00100101;
5363  let Inst{23-22} = sz8_64;
5364  let Inst{21}    = 0b1;
5365  let Inst{20-16} = Rm;
5366  let Inst{15-13} = 0b000;
5367  let Inst{12-10} = opc{3-1};
5368  let Inst{9-5}   = Rn;
5369  let Inst{4}     = opc{0};
5370  let Inst{3-0}   = Pd;
5371
5372  let Defs = [NZCV];
5373  let ElementSize = pprty.ElementSize;
5374  let hasSideEffects = 0;
5375  let isWhile = 1;
5376}
5377
5378multiclass sve_int_while4_rr<bits<3> opc, string asm, SDPatternOperator op,
5379                             SDPatternOperator rev_op> {
5380  def _B : sve_int_while_rr<0b00, { 0, opc }, asm, GPR32, PPR8>;
5381  def _H : sve_int_while_rr<0b01, { 0, opc }, asm, GPR32, PPR16>;
5382  def _S : sve_int_while_rr<0b10, { 0, opc }, asm, GPR32, PPR32>;
5383  def _D : sve_int_while_rr<0b11, { 0, opc }, asm, GPR32, PPR64>;
5384
5385  def : SVE_2_Op_Pat<nxv16i1, op, i32, i32, !cast<Instruction>(NAME # _B)>;
5386  def : SVE_2_Op_Pat<nxv8i1,  op, i32, i32, !cast<Instruction>(NAME # _H)>;
5387  def : SVE_2_Op_Pat<nxv4i1,  op, i32, i32, !cast<Instruction>(NAME # _S)>;
5388  def : SVE_2_Op_Pat<nxv2i1,  op, i32, i32, !cast<Instruction>(NAME # _D)>;
5389
5390  def : Pat<(nxv16i1 (vector_reverse (rev_op i32:$op2, i32:$op1))),
5391            (!cast<Instruction>(NAME # "_B") $op1, $op2)>;
5392  def : Pat<(nxv8i1 (vector_reverse (rev_op i32:$op2, i32:$op1))),
5393            (!cast<Instruction>(NAME # "_H") $op1, $op2)>;
5394  def : Pat<(nxv4i1 (vector_reverse (rev_op i32:$op2, i32:$op1))),
5395            (!cast<Instruction>(NAME # "_S") $op1, $op2)>;
5396  def : Pat<(nxv2i1 (vector_reverse (rev_op i32:$op2, i32:$op1))),
5397            (!cast<Instruction>(NAME # "_D") $op1, $op2)>;
5398}
5399
5400multiclass sve_int_while8_rr<bits<3> opc, string asm, SDPatternOperator op,
5401                             SDPatternOperator rev_op> {
5402  def _B : sve_int_while_rr<0b00, { 1, opc }, asm, GPR64, PPR8>;
5403  def _H : sve_int_while_rr<0b01, { 1, opc }, asm, GPR64, PPR16>;
5404  def _S : sve_int_while_rr<0b10, { 1, opc }, asm, GPR64, PPR32>;
5405  def _D : sve_int_while_rr<0b11, { 1, opc }, asm, GPR64, PPR64>;
5406
5407  def : SVE_2_Op_Pat<nxv16i1, op, i64, i64, !cast<Instruction>(NAME # _B)>;
5408  def : SVE_2_Op_Pat<nxv8i1,  op, i64, i64, !cast<Instruction>(NAME # _H)>;
5409  def : SVE_2_Op_Pat<nxv4i1,  op, i64, i64, !cast<Instruction>(NAME # _S)>;
5410  def : SVE_2_Op_Pat<nxv2i1,  op, i64, i64, !cast<Instruction>(NAME # _D)>;
5411
5412  def : Pat<(nxv16i1 (vector_reverse (rev_op i64:$op2, i64:$op1))),
5413            (!cast<Instruction>(NAME # "_B") $op1, $op2)>;
5414  def : Pat<(nxv8i1 (vector_reverse (rev_op i64:$op2, i64:$op1))),
5415            (!cast<Instruction>(NAME # "_H") $op1, $op2)>;
5416  def : Pat<(nxv4i1 (vector_reverse (rev_op i64:$op2, i64:$op1))),
5417            (!cast<Instruction>(NAME # "_S") $op1, $op2)>;
5418  def : Pat<(nxv2i1 (vector_reverse (rev_op i64:$op2, i64:$op1))),
5419            (!cast<Instruction>(NAME # "_D") $op1, $op2)>;
5420}
5421
5422class sve2_int_while_rr<bits<2> sz8_64, bits<1> rw, string asm,
5423                        PPRRegOp pprty>
5424: I<(outs pprty:$Pd), (ins GPR64:$Rn, GPR64:$Rm),
5425  asm, "\t$Pd, $Rn, $Rm",
5426  "", []>, Sched<[]> {
5427  bits<4> Pd;
5428  bits<5> Rm;
5429  bits<5> Rn;
5430  let Inst{31-24} = 0b00100101;
5431  let Inst{23-22} = sz8_64;
5432  let Inst{21}    = 0b1;
5433  let Inst{20-16} = Rm;
5434  let Inst{15-10} = 0b001100;
5435  let Inst{9-5}   = Rn;
5436  let Inst{4}     = rw;
5437  let Inst{3-0}   = Pd;
5438
5439  let Defs = [NZCV];
5440  let ElementSize = pprty.ElementSize;
5441  let hasSideEffects = 0;
5442  let isWhile = 1;
5443}
5444
5445multiclass sve2_int_while_rr<bits<1> rw, string asm, string op> {
5446  def _B : sve2_int_while_rr<0b00, rw, asm, PPR8>;
5447  def _H : sve2_int_while_rr<0b01, rw, asm, PPR16>;
5448  def _S : sve2_int_while_rr<0b10, rw, asm, PPR32>;
5449  def _D : sve2_int_while_rr<0b11, rw, asm, PPR64>;
5450
5451  def : SVE_2_Op_Pat<nxv16i1, !cast<SDPatternOperator>(op # _b), i64, i64, !cast<Instruction>(NAME # _B)>;
5452  def : SVE_2_Op_Pat<nxv8i1,  !cast<SDPatternOperator>(op # _h), i64, i64, !cast<Instruction>(NAME # _H)>;
5453  def : SVE_2_Op_Pat<nxv4i1,  !cast<SDPatternOperator>(op # _s), i64, i64, !cast<Instruction>(NAME # _S)>;
5454  def : SVE_2_Op_Pat<nxv2i1,  !cast<SDPatternOperator>(op # _d), i64, i64, !cast<Instruction>(NAME # _D)>;
5455}
5456
5457//===----------------------------------------------------------------------===//
5458// SVE Floating Point Fast Reduction Group
5459//===----------------------------------------------------------------------===//
5460
5461class sve_fp_fast_red<bits<2> sz, bits<3> opc, string asm,
5462                      ZPRRegOp zprty, FPRasZPROperand dstOpType>
5463: I<(outs dstOpType:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
5464  asm, "\t$Vd, $Pg, $Zn",
5465  "",
5466  []>, Sched<[]> {
5467  bits<5> Zn;
5468  bits<5> Vd;
5469  bits<3> Pg;
5470  let Inst{31-24} = 0b01100101;
5471  let Inst{23-22} = sz;
5472  let Inst{21-19} = 0b000;
5473  let Inst{18-16} = opc;
5474  let Inst{15-13} = 0b001;
5475  let Inst{12-10} = Pg;
5476  let Inst{9-5}   = Zn;
5477  let Inst{4-0}   = Vd;
5478
5479  let hasSideEffects = 0;
5480  let mayRaiseFPException = 1;
5481}
5482
5483multiclass sve_fp_fast_red<bits<3> opc, string asm, SDPatternOperator op> {
5484  def _H : sve_fp_fast_red<0b01, opc, asm, ZPR16, FPR16asZPR>;
5485  def _S : sve_fp_fast_red<0b10, opc, asm, ZPR32, FPR32asZPR>;
5486  def _D : sve_fp_fast_red<0b11, opc, asm, ZPR64, FPR64asZPR>;
5487
5488  def : SVE_2_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
5489  def : SVE_2_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
5490  def : SVE_2_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
5491  def : SVE_2_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
5492  def : SVE_2_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
5493  def : SVE_2_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
5494}
5495
5496//===----------------------------------------------------------------------===//
5497// SVE Floating Point Accumulating Reduction Group
5498//===----------------------------------------------------------------------===//
5499
5500class sve_fp_2op_p_vd<bits<2> sz, bits<3> opc, string asm,
5501                      ZPRRegOp zprty, FPRasZPROperand dstOpType>
5502: I<(outs dstOpType:$Vdn), (ins PPR3bAny:$Pg, dstOpType:$_Vdn, zprty:$Zm),
5503  asm, "\t$Vdn, $Pg, $_Vdn, $Zm",
5504  "",
5505  []>,
5506  Sched<[]> {
5507  bits<3> Pg;
5508  bits<5> Vdn;
5509  bits<5> Zm;
5510  let Inst{31-24} = 0b01100101;
5511  let Inst{23-22} = sz;
5512  let Inst{21-19} = 0b011;
5513  let Inst{18-16} = opc;
5514  let Inst{15-13} = 0b001;
5515  let Inst{12-10} = Pg;
5516  let Inst{9-5}   = Zm;
5517  let Inst{4-0}   = Vdn;
5518
5519  let Constraints = "$Vdn = $_Vdn";
5520  let hasSideEffects = 0;
5521  let mayRaiseFPException = 1;
5522}
5523
5524multiclass sve_fp_2op_p_vd<bits<3> opc, string asm, SDPatternOperator op> {
5525  def _H : sve_fp_2op_p_vd<0b01, opc, asm, ZPR16, FPR16asZPR>;
5526  def _S : sve_fp_2op_p_vd<0b10, opc, asm, ZPR32, FPR32asZPR>;
5527  def _D : sve_fp_2op_p_vd<0b11, opc, asm, ZPR64, FPR64asZPR>;
5528
5529  def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H)>;
5530  def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H)>;
5531  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
5532  def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S)>;
5533  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
5534  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
5535}
5536
5537//===----------------------------------------------------------------------===//
5538// SVE Floating Point Compare - Vectors Group
5539//===----------------------------------------------------------------------===//
5540
5541class sve_fp_3op_p_pd<bits<2> sz, bits<3> opc, string asm, PPRRegOp pprty,
5542                      ZPRRegOp zprty>
5543: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
5544  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
5545  "",
5546  []>, Sched<[]> {
5547  bits<4> Pd;
5548  bits<3> Pg;
5549  bits<5> Zm;
5550  bits<5> Zn;
5551  let Inst{31-24} = 0b01100101;
5552  let Inst{23-22} = sz;
5553  let Inst{21}    = 0b0;
5554  let Inst{20-16} = Zm;
5555  let Inst{15}    = opc{2};
5556  let Inst{14}    = 0b1;
5557  let Inst{13}    = opc{1};
5558  let Inst{12-10} = Pg;
5559  let Inst{9-5}   = Zn;
5560  let Inst{4}     = opc{0};
5561  let Inst{3-0}   = Pd;
5562
5563  let hasSideEffects = 0;
5564  let mayRaiseFPException = 1;
5565}
5566
5567multiclass sve_fp_3op_p_pd<bits<3> opc, string asm, SDPatternOperator op> {
5568  def _H : sve_fp_3op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5569  def _S : sve_fp_3op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5570  def _D : sve_fp_3op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5571
5572  def : SVE_3_Op_Pat<nxv8i1, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
5573  def : SVE_3_Op_Pat<nxv4i1, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
5574  def : SVE_3_Op_Pat<nxv2i1, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
5575}
5576
5577multiclass sve_fp_3op_p_pd_cc<bits<3> opc, string asm,
5578                              CondCode cc1, CondCode cc2,
5579                              CondCode invcc1, CondCode invcc2> {
5580  def _H : sve_fp_3op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5581  def _S : sve_fp_3op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5582  def _D : sve_fp_3op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5583
5584  defm : SVE_SETCC_Pat<cc1, invcc1, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5585  defm : SVE_SETCC_Pat<cc1, invcc1, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5586  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5587  defm : SVE_SETCC_Pat<cc1, invcc1, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5588  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5589  defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5590
5591  defm : SVE_SETCC_Pat<cc2, invcc2, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5592  defm : SVE_SETCC_Pat<cc2, invcc2, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5593  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5594  defm : SVE_SETCC_Pat<cc2, invcc2, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5595  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5596  defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5597}
5598
5599//===----------------------------------------------------------------------===//
5600// SVE Floating Point Compare - with Zero Group
5601//===----------------------------------------------------------------------===//
5602
5603class sve_fp_2op_p_pd<bits<2> sz, bits<3> opc, string asm, PPRRegOp pprty,
5604                      ZPRRegOp zprty>
5605: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn),
5606  asm, "\t$Pd, $Pg/z, $Zn, #0.0",
5607  "",
5608  []>, Sched<[]> {
5609  bits<4> Pd;
5610  bits<3> Pg;
5611  bits<5> Zn;
5612  let Inst{31-24} = 0b01100101;
5613  let Inst{23-22} = sz;
5614  let Inst{21-18} = 0b0100;
5615  let Inst{17-16} = opc{2-1};
5616  let Inst{15-13} = 0b001;
5617  let Inst{12-10} = Pg;
5618  let Inst{9-5}   = Zn;
5619  let Inst{4}     = opc{0};
5620  let Inst{3-0}   = Pd;
5621
5622  let hasSideEffects = 0;
5623  let mayRaiseFPException = 1;
5624}
5625
5626multiclass sve_fp_2op_p_pd<bits<3> opc, string asm,
5627                           CondCode cc1, CondCode cc2,
5628                           CondCode invcc1, CondCode invcc2> {
5629  def _H : sve_fp_2op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5630  def _S : sve_fp_2op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5631  def _D : sve_fp_2op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5632
5633  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5634  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5635  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5636  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5637  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5638  defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5639
5640  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5641  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5642  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5643  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5644  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5645  defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5646}
5647
5648
5649//===----------------------------------------------------------------------===//
5650//SVE Index Generation Group
5651//===----------------------------------------------------------------------===//
5652
5653def simm5_8b_tgt : TImmLeaf<i8, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]>;
5654def simm5_16b_tgt : TImmLeaf<i16, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]>;
5655def simm5_32b_tgt : TImmLeaf<i32, [{ return (int32_t)Imm >= -16 && (int32_t)Imm < 16; }]>;
5656def simm5_64b_tgt : TImmLeaf<i64, [{ return (int64_t)Imm >= -16 && (int64_t)Imm < 16; }]>;
5657def i64imm_32bit_tgt : TImmLeaf<i64, [{
5658  return (Imm & 0xffffffffULL) == static_cast<uint64_t>(Imm);
5659}]>;
5660
5661class sve_int_index_ii<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5662                       Operand imm_ty>
5663: I<(outs zprty:$Zd), (ins imm_ty:$imm5, imm_ty:$imm5b),
5664  asm, "\t$Zd, $imm5, $imm5b",
5665  "", []>, Sched<[]> {
5666  bits<5> Zd;
5667  bits<5> imm5;
5668  bits<5> imm5b;
5669  let Inst{31-24} = 0b00000100;
5670  let Inst{23-22} = sz8_64;
5671  let Inst{21}    = 0b1;
5672  let Inst{20-16} = imm5b;
5673  let Inst{15-10} = 0b010000;
5674  let Inst{9-5}   = imm5;
5675  let Inst{4-0}   = Zd;
5676
5677  let hasSideEffects = 0;
5678  let isReMaterializable = 1;
5679  let Uses = [VG];
5680}
5681
5682multiclass sve_int_index_ii<string asm> {
5683  def _B : sve_int_index_ii<0b00, asm, ZPR8, simm5_8b>;
5684  def _H : sve_int_index_ii<0b01, asm, ZPR16, simm5_16b>;
5685  def _S : sve_int_index_ii<0b10, asm, ZPR32, simm5_32b>;
5686  def _D : sve_int_index_ii<0b11, asm, ZPR64, simm5_64b>;
5687
5688  def : Pat<(nxv16i8 (step_vector simm5_8b_tgt:$imm5b)),
5689            (!cast<Instruction>(NAME # "_B") (i32 0), (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5690  def : Pat<(nxv8i16 (step_vector simm5_16b_tgt:$imm5b)),
5691            (!cast<Instruction>(NAME # "_H") (i32 0), (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5692  def : Pat<(nxv4i32 (step_vector simm5_32b_tgt:$imm5b)),
5693            (!cast<Instruction>(NAME # "_S") (i32 0), simm5_32b:$imm5b)>;
5694  def : Pat<(nxv2i64 (step_vector simm5_64b_tgt:$imm5b)),
5695            (!cast<Instruction>(NAME # "_D") (i64 0), simm5_64b:$imm5b)>;
5696
5697  // add(step_vector(step), dup(X)) -> index(X, step).
5698  def : Pat<(add (nxv16i8 (step_vector_oneuse simm5_8b_tgt:$imm5b)), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
5699            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5700  def : Pat<(add (nxv8i16 (step_vector_oneuse simm5_16b_tgt:$imm5b)), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
5701            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5702  def : Pat<(add (nxv4i32 (step_vector_oneuse simm5_32b_tgt:$imm5b)), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
5703            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, simm5_32b:$imm5b)>;
5704  def : Pat<(add (nxv2i64 (step_vector_oneuse simm5_64b_tgt:$imm5b)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5705            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, simm5_64b:$imm5b)>;
5706}
5707
5708class sve_int_index_ir<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5709                       RegisterClass srcRegType, Operand imm_ty>
5710: I<(outs zprty:$Zd), (ins imm_ty:$imm5, srcRegType:$Rm),
5711  asm, "\t$Zd, $imm5, $Rm",
5712  "", []>, Sched<[]> {
5713  bits<5> Rm;
5714  bits<5> Zd;
5715  bits<5> imm5;
5716  let Inst{31-24} = 0b00000100;
5717  let Inst{23-22} = sz8_64;
5718  let Inst{21}    = 0b1;
5719  let Inst{20-16} = Rm;
5720  let Inst{15-10} = 0b010010;
5721  let Inst{9-5}   = imm5;
5722  let Inst{4-0}   = Zd;
5723
5724  let hasSideEffects = 0;
5725}
5726
5727multiclass sve_int_index_ir<string asm, SDPatternOperator mulop, SDPatternOperator muloneuseop> {
5728  def _B : sve_int_index_ir<0b00, asm, ZPR8, GPR32, simm5_8b>;
5729  def _H : sve_int_index_ir<0b01, asm, ZPR16, GPR32, simm5_16b>;
5730  def _S : sve_int_index_ir<0b10, asm, ZPR32, GPR32, simm5_32b>;
5731  def _D : sve_int_index_ir<0b11, asm, ZPR64, GPR64, simm5_64b>;
5732
5733  def : Pat<(nxv16i8 (step_vector i8:$imm)),
5734            (!cast<Instruction>(NAME # "_B") (i32 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5735  def : Pat<(nxv8i16 (step_vector i16:$imm)),
5736            (!cast<Instruction>(NAME # "_H") (i32 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5737  def : Pat<(nxv4i32 (step_vector i32:$imm)),
5738            (!cast<Instruction>(NAME # "_S") (i32 0), (!cast<Instruction>("MOVi32imm") $imm))>;
5739  def : Pat<(nxv2i64 (step_vector i64:$imm)),
5740            (!cast<Instruction>(NAME # "_D") (i64 0), (!cast<Instruction>("MOVi64imm") $imm))>;
5741  def : Pat<(nxv2i64 (step_vector i64imm_32bit_tgt:$imm)),
5742            (!cast<Instruction>(NAME # "_D") (i64 0), (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5743
5744  // add(step_vector(step), dup(X)) -> index(X, step).
5745  def : Pat<(add (nxv16i8 (step_vector_oneuse i8:$imm)), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
5746            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5747  def : Pat<(add (nxv8i16 (step_vector_oneuse i16:$imm)), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
5748            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5749  def : Pat<(add (nxv4i32 (step_vector_oneuse i32:$imm)), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
5750            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, (!cast<Instruction>("MOVi32imm") $imm))>;
5751  def : Pat<(add (nxv2i64 (step_vector_oneuse i64:$imm)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5752            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, (!cast<Instruction>("MOVi64imm") $imm))>;
5753  def : Pat<(add (nxv2i64 (step_vector_oneuse i64imm_32bit_tgt:$imm)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5754            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5755
5756  // mul(step_vector(1), dup(Y)) -> index(0, Y).
5757  def : Pat<(mulop (nxv16i1 (SVEAllActive)), (nxv16i8 (step_vector_oneuse (i8 1))), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))),
5758            (!cast<Instruction>(NAME # "_B") (i32 0), GPR32:$Rm)>;
5759  def : Pat<(mulop (nxv8i1 (SVEAllActive)), (nxv8i16 (step_vector_oneuse (i16 1))), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),
5760            (!cast<Instruction>(NAME # "_H") (i32 0), GPR32:$Rm)>;
5761  def : Pat<(mulop (nxv4i1 (SVEAllActive)), (nxv4i32 (step_vector_oneuse (i32 1))), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),
5762            (!cast<Instruction>(NAME # "_S") (i32 0), GPR32:$Rm)>;
5763  def : Pat<(mulop (nxv2i1 (SVEAllActive)), (nxv2i64 (step_vector_oneuse (i64 1))), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),
5764            (!cast<Instruction>(NAME # "_D") (i64 0), GPR64:$Rm)>;
5765
5766  // add(mul(step_vector(1), dup(Y)), dup(X)) -> index(X, Y).
5767  def : Pat<(add (muloneuseop (nxv16i1 (SVEAllActive)), (nxv16i8 (step_vector_oneuse (i8 1))), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
5768            (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, GPR32:$Rm)>;
5769  def : Pat<(add (muloneuseop (nxv8i1 (SVEAllActive)), (nxv8i16 (step_vector_oneuse (i16 1))), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
5770            (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, GPR32:$Rm)>;
5771  def : Pat<(add (muloneuseop (nxv4i1 (SVEAllActive)), (nxv4i32 (step_vector_oneuse (i32 1))), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
5772            (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, GPR32:$Rm)>;
5773  def : Pat<(add (muloneuseop (nxv2i1 (SVEAllActive)), (nxv2i64 (step_vector_oneuse (i64 1))), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5774            (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, GPR64:$Rm)>;
5775}
5776
5777class sve_int_index_ri<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5778                       RegisterClass srcRegType, Operand imm_ty>
5779: I<(outs zprty:$Zd), (ins srcRegType:$Rn, imm_ty:$imm5),
5780  asm, "\t$Zd, $Rn, $imm5",
5781  "", []>, Sched<[]> {
5782  bits<5> Rn;
5783  bits<5> Zd;
5784  bits<5> imm5;
5785  let Inst{31-24} = 0b00000100;
5786  let Inst{23-22} = sz8_64;
5787  let Inst{21}    = 0b1;
5788  let Inst{20-16} = imm5;
5789  let Inst{15-10} = 0b010001;
5790  let Inst{9-5}   = Rn;
5791  let Inst{4-0}   = Zd;
5792
5793  let hasSideEffects = 0;
5794}
5795
5796multiclass sve_int_index_ri<string asm> {
5797  def _B : sve_int_index_ri<0b00, asm, ZPR8, GPR32, simm5_8b>;
5798  def _H : sve_int_index_ri<0b01, asm, ZPR16, GPR32, simm5_16b>;
5799  def _S : sve_int_index_ri<0b10, asm, ZPR32, GPR32, simm5_32b>;
5800  def _D : sve_int_index_ri<0b11, asm, ZPR64, GPR64, simm5_64b>;
5801
5802  // add(step_vector(step), dup(X)) -> index(X, step).
5803  def : Pat<(add (nxv16i8 (step_vector_oneuse simm5_8b_tgt:$imm5)), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))),
5804            (!cast<Instruction>(NAME # "_B") GPR32:$Rm, (!cast<SDNodeXForm>("trunc_imm") $imm5))>;
5805  def : Pat<(add (nxv8i16 (step_vector_oneuse simm5_16b_tgt:$imm5)), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),
5806            (!cast<Instruction>(NAME # "_H") GPR32:$Rm, (!cast<SDNodeXForm>("trunc_imm") $imm5))>;
5807  def : Pat<(add (nxv4i32 (step_vector_oneuse simm5_32b_tgt:$imm5)), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),
5808            (!cast<Instruction>(NAME # "_S") GPR32:$Rm, simm5_32b:$imm5)>;
5809  def : Pat<(add (nxv2i64 (step_vector_oneuse simm5_64b_tgt:$imm5)), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),
5810            (!cast<Instruction>(NAME # "_D") GPR64:$Rm, simm5_64b:$imm5)>;
5811}
5812
5813class sve_int_index_rr<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5814                       RegisterClass srcRegType>
5815: I<(outs zprty:$Zd), (ins srcRegType:$Rn, srcRegType:$Rm),
5816  asm, "\t$Zd, $Rn, $Rm",
5817  "", []>, Sched<[]> {
5818  bits<5> Zd;
5819  bits<5> Rm;
5820  bits<5> Rn;
5821  let Inst{31-24} = 0b00000100;
5822  let Inst{23-22} = sz8_64;
5823  let Inst{21}    = 0b1;
5824  let Inst{20-16} = Rm;
5825  let Inst{15-10} = 0b010011;
5826  let Inst{9-5}   = Rn;
5827  let Inst{4-0}   = Zd;
5828
5829  let hasSideEffects = 0;
5830}
5831
5832multiclass sve_int_index_rr<string asm, SDPatternOperator mulop> {
5833  def _B : sve_int_index_rr<0b00, asm, ZPR8, GPR32>;
5834  def _H : sve_int_index_rr<0b01, asm, ZPR16, GPR32>;
5835  def _S : sve_int_index_rr<0b10, asm, ZPR32, GPR32>;
5836  def _D : sve_int_index_rr<0b11, asm, ZPR64, GPR64>;
5837
5838  // add(step_vector(step), dup(X)) -> index(X, step).
5839  def : Pat<(add (nxv16i8 (step_vector_oneuse i8:$imm)), (nxv16i8 (splat_vector(i32 GPR32:$Rn)))),
5840            (!cast<Instruction>(NAME # "_B") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5841  def : Pat<(add (nxv8i16 (step_vector_oneuse i16:$imm)), (nxv8i16 (splat_vector(i32 GPR32:$Rn)))),
5842            (!cast<Instruction>(NAME # "_H") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5843  def : Pat<(add (nxv4i32 (step_vector_oneuse i32:$imm)), (nxv4i32 (splat_vector(i32 GPR32:$Rn)))),
5844            (!cast<Instruction>(NAME # "_S") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") $imm))>;
5845  def : Pat<(add (nxv2i64 (step_vector_oneuse i64:$imm)), (nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
5846            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, (!cast<Instruction>("MOVi64imm") $imm))>;
5847  def : Pat<(add (nxv2i64 (step_vector_oneuse i64imm_32bit_tgt:$imm)), (nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
5848            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5849
5850  // add(mul(step_vector(1), dup(Y)), dup(X)) -> index(X, Y).
5851  def : Pat<(add (mulop (nxv16i1 (SVEAllActive)), (nxv16i8 (step_vector_oneuse (i8 1))), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))), (nxv16i8 (splat_vector(i32 GPR32:$Rn)))),
5852            (!cast<Instruction>(NAME # "_B") GPR32:$Rn, GPR32:$Rm)>;
5853  def : Pat<(add (mulop (nxv8i1 (SVEAllActive)), (nxv8i16 (step_vector_oneuse (i16 1))), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),(nxv8i16 (splat_vector(i32 GPR32:$Rn)))),
5854            (!cast<Instruction>(NAME # "_H") GPR32:$Rn, GPR32:$Rm)>;
5855  def : Pat<(add (mulop (nxv4i1 (SVEAllActive)), (nxv4i32 (step_vector_oneuse (i32 1))), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),(nxv4i32 (splat_vector(i32 GPR32:$Rn)))),
5856            (!cast<Instruction>(NAME # "_S") GPR32:$Rn, GPR32:$Rm)>;
5857  def : Pat<(add (mulop (nxv2i1 (SVEAllActive)), (nxv2i64 (step_vector_oneuse (i64 1))), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),(nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
5858            (!cast<Instruction>(NAME # "_D") GPR64:$Rn, GPR64:$Rm)>;
5859}
5860
5861//===----------------------------------------------------------------------===//
5862// SVE Bitwise Shift - Predicated Group
5863//===----------------------------------------------------------------------===//
5864
5865class sve_int_bin_pred_shift_imm<bits<4> tsz8_64, bits<4> opc, string asm,
5866                                 ZPRRegOp zprty, Operand immtype>
5867: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, immtype:$imm),
5868  asm, "\t$Zdn, $Pg/m, $_Zdn, $imm",
5869  "",
5870  []>, Sched<[]> {
5871  bits<3> Pg;
5872  bits<5> Zdn;
5873  bits<6> imm;
5874  let Inst{31-24} = 0b00000100;
5875  let Inst{23-22} = tsz8_64{3-2};
5876  let Inst{21-20} = 0b00;
5877  let Inst{19-16} = opc;
5878  let Inst{15-13} = 0b100;
5879  let Inst{12-10} = Pg;
5880  let Inst{9-8}   = tsz8_64{1-0};
5881  let Inst{7-5}   = imm{2-0}; // imm3
5882  let Inst{4-0}   = Zdn;
5883
5884  let Constraints = "$Zdn = $_Zdn";
5885  let DestructiveInstType = DestructiveBinaryImm;
5886  let ElementSize = zprty.ElementSize;
5887  let hasSideEffects = 0;
5888}
5889
5890multiclass sve_int_bin_pred_shift_imm_left<bits<4> opc, string asm, string Ps,
5891                                           SDPatternOperator op = null_frag> {
5892  def _B : SVEPseudo2Instr<Ps # _B, 1>,
5893           sve_int_bin_pred_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
5894  def _H : SVEPseudo2Instr<Ps # _H, 1>,
5895           sve_int_bin_pred_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
5896    let Inst{8} = imm{3};
5897  }
5898  def _S : SVEPseudo2Instr<Ps # _S, 1>,
5899           sve_int_bin_pred_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
5900    let Inst{9-8} = imm{4-3};
5901  }
5902  def _D : SVEPseudo2Instr<Ps # _D, 1>,
5903           sve_int_bin_pred_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
5904    let Inst{22}  = imm{5};
5905    let Inst{9-8} = imm{4-3};
5906  }
5907
5908  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i1, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _B)>;
5909  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i1,  nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _H)>;
5910  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i1,  nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _S)>;
5911  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i1,  nxv2i64, i32, tvecshiftL64, !cast<Instruction>(NAME # _D)>;
5912}
5913
5914// As above but shift amount takes the form of a "vector immediate".
5915multiclass sve_int_bin_pred_shift_imm_left_dup<bits<4> opc, string asm,
5916                                               string Ps, SDPatternOperator op>
5917: sve_int_bin_pred_shift_imm_left<opc, asm, Ps, null_frag> {
5918  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8,  !cast<Instruction>(NAME # _B)>;
5919  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
5920  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
5921  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
5922}
5923
5924multiclass sve_int_bin_pred_shift_imm_left_zeroing_bhsd<SDPatternOperator op> {
5925  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8,  tvecshiftL8,  FalseLanesZero>;
5926  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, tvecshiftL16, FalseLanesZero>;
5927  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, tvecshiftL32, FalseLanesZero>;
5928  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, tvecshiftL64, FalseLanesZero>;
5929
5930  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv16i8, op, nxv16i1, nxv16i8, tvecshiftL8,  !cast<Pseudo>(NAME # _B_ZERO)>;
5931  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv8i16, op, nxv8i1,  nxv8i16, tvecshiftL16, !cast<Pseudo>(NAME # _H_ZERO)>;
5932  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv4i32, op, nxv4i1,  nxv4i32, tvecshiftL32, !cast<Pseudo>(NAME # _S_ZERO)>;
5933  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv2i64, op, nxv2i1,  nxv2i64, tvecshiftL64, !cast<Pseudo>(NAME # _D_ZERO)>;
5934}
5935
5936multiclass sve_int_bin_pred_shift_imm_right<bits<4> opc, string asm, string Ps,
5937                                            SDPatternOperator op = null_frag> {
5938  def _B : SVEPseudo2Instr<Ps # _B, 1>,
5939           sve_int_bin_pred_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
5940  def _H : SVEPseudo2Instr<Ps # _H, 1>,
5941           sve_int_bin_pred_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
5942    let Inst{8} = imm{3};
5943  }
5944  def _S : SVEPseudo2Instr<Ps # _S, 1>,
5945           sve_int_bin_pred_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
5946    let Inst{9-8} = imm{4-3};
5947  }
5948  def _D : SVEPseudo2Instr<Ps # _D, 1>,
5949           sve_int_bin_pred_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
5950    let Inst{22}  = imm{5};
5951    let Inst{9-8} = imm{4-3};
5952  }
5953
5954  def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i1, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
5955  def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i1,  nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
5956  def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i1,  nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
5957  def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i1,  nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
5958}
5959
5960// As above but shift amount takes the form of a "vector immediate".
5961multiclass sve_int_bin_pred_shift_imm_right_dup<bits<4> opc, string asm,
5962                                            string Ps, SDPatternOperator op>
5963: sve_int_bin_pred_shift_imm_right<opc, asm, Ps, null_frag> {
5964  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8,  !cast<Instruction>(NAME # _B)>;
5965  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
5966  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
5967  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
5968}
5969
5970multiclass sve_int_bin_pred_shift_imm_right_zeroing_bhsd<SDPatternOperator op = null_frag> {
5971  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8, vecshiftR8, FalseLanesZero>;
5972  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, vecshiftR16, FalseLanesZero>;
5973  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, vecshiftR32, FalseLanesZero>;
5974  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, vecshiftR64, FalseLanesZero>;
5975
5976  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv16i8, op, nxv16i1, nxv16i8, tvecshiftR8, !cast<Pseudo>(NAME # _B_ZERO)>;
5977  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv8i16, op, nxv8i1, nxv8i16, tvecshiftR16, !cast<Pseudo>(NAME # _H_ZERO)>;
5978  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv4i32, op, nxv4i1, nxv4i32, tvecshiftR32, !cast<Pseudo>(NAME # _S_ZERO)>;
5979  def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv2i64, op, nxv2i1, nxv2i64, tvecshiftR64, !cast<Pseudo>(NAME # _D_ZERO)>;
5980}
5981
5982class sve_int_bin_pred_shift<bits<2> sz8_64, bit wide, bits<3> opc,
5983                             string asm, ZPRRegOp zprty, ZPRRegOp zprty2>
5984: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty2:$Zm),
5985  asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
5986  "",
5987  []>, Sched<[]> {
5988  bits<3> Pg;
5989  bits<5> Zdn;
5990  bits<5> Zm;
5991  let Inst{31-24} = 0b00000100;
5992  let Inst{23-22} = sz8_64;
5993  let Inst{21-20} = 0b01;
5994  let Inst{19}    = wide;
5995  let Inst{18-16} = opc;
5996  let Inst{15-13} = 0b100;
5997  let Inst{12-10} = Pg;
5998  let Inst{9-5}   = Zm;
5999  let Inst{4-0}   = Zdn;
6000
6001  let Constraints = "$Zdn = $_Zdn";
6002  let DestructiveInstType = DestructiveOther;
6003  let ElementSize = zprty.ElementSize;
6004  let hasSideEffects = 0;
6005}
6006
6007multiclass sve_int_bin_pred_shift<bits<3> opc, string asm, string Ps,
6008                                  SDPatternOperator op, string revname, bit isReverseInstr = 0> {
6009  let DestructiveInstType = DestructiveBinaryCommWithRev in {
6010  def _B : sve_int_bin_pred_shift<0b00, 0b0, opc, asm, ZPR8, ZPR8>,
6011           SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
6012  def _H : sve_int_bin_pred_shift<0b01, 0b0, opc, asm, ZPR16, ZPR16>,
6013           SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
6014  def _S : sve_int_bin_pred_shift<0b10, 0b0, opc, asm, ZPR32, ZPR32>,
6015           SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
6016  def _D : sve_int_bin_pred_shift<0b11, 0b0, opc, asm, ZPR64, ZPR64>,
6017           SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
6018  }
6019  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
6020  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
6021  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
6022  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
6023}
6024
6025multiclass sve_int_bin_pred_zeroing_bhsd<SDPatternOperator op> {
6026  def _B_ZERO : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesZero>;
6027  def _H_ZERO : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesZero>;
6028  def _S_ZERO : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesZero>;
6029  def _D_ZERO : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesZero>;
6030
6031  def : SVE_3_Op_Pat_SelZero<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_ZERO)>;
6032  def : SVE_3_Op_Pat_SelZero<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_ZERO)>;
6033  def : SVE_3_Op_Pat_SelZero<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_ZERO)>;
6034  def : SVE_3_Op_Pat_SelZero<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_ZERO)>;
6035}
6036
6037multiclass sve_int_bin_pred_imm_zeroing_bhsd<SDPatternOperator op,
6038                                   ComplexPattern imm_b, ComplexPattern imm_h,
6039                                   ComplexPattern imm_s, ComplexPattern imm_d> {
6040  def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8,  Operand<i32>, FalseLanesZero>;
6041  def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, Operand<i32>, FalseLanesZero>;
6042  def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, Operand<i32>, FalseLanesZero>;
6043  def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, Operand<i32>, FalseLanesZero>;
6044
6045  def : SVE_2_Op_Imm_Pat_Zero<nxv16i8, op, nxv16i1, i32, imm_b, !cast<Pseudo>(NAME # _B_ZERO)>;
6046  def : SVE_2_Op_Imm_Pat_Zero<nxv8i16, op, nxv8i1,  i32, imm_h, !cast<Pseudo>(NAME # _H_ZERO)>;
6047  def : SVE_2_Op_Imm_Pat_Zero<nxv4i32, op, nxv4i1,  i32, imm_s, !cast<Pseudo>(NAME # _S_ZERO)>;
6048  def : SVE_2_Op_Imm_Pat_Zero<nxv2i64, op, nxv2i1,  i64, imm_d, !cast<Pseudo>(NAME # _D_ZERO)>;
6049}
6050
6051multiclass sve_int_bin_pred_shift_wide<bits<3> opc, string asm,
6052                                  SDPatternOperator op> {
6053  def _B : sve_int_bin_pred_shift<0b00, 0b1, opc, asm, ZPR8, ZPR64>;
6054  def _H : sve_int_bin_pred_shift<0b01, 0b1, opc, asm, ZPR16, ZPR64>;
6055  def _S : sve_int_bin_pred_shift<0b10, 0b1, opc, asm, ZPR32, ZPR64>;
6056
6057  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
6058  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
6059  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
6060}
6061
6062//===----------------------------------------------------------------------===//
6063// SVE Shift - Unpredicated Group
6064//===----------------------------------------------------------------------===//
6065
6066class sve_int_bin_cons_shift_wide<bits<2> sz8_64, bits<2> opc, string asm,
6067                               ZPRRegOp zprty>
6068: I<(outs zprty:$Zd), (ins zprty:$Zn, ZPR64:$Zm),
6069  asm, "\t$Zd, $Zn, $Zm",
6070  "",
6071  []>, Sched<[]> {
6072  bits<5> Zd;
6073  bits<5> Zm;
6074  bits<5> Zn;
6075  let Inst{31-24} = 0b00000100;
6076  let Inst{23-22} = sz8_64;
6077  let Inst{21}    = 0b1;
6078  let Inst{20-16} = Zm;
6079  let Inst{15-12} = 0b1000;
6080  let Inst{11-10} = opc;
6081  let Inst{9-5}   = Zn;
6082  let Inst{4-0}   = Zd;
6083
6084  let hasSideEffects = 0;
6085}
6086
6087multiclass sve_int_bin_cons_shift_wide<bits<2> opc, string asm, SDPatternOperator op> {
6088  def _B : sve_int_bin_cons_shift_wide<0b00, opc, asm, ZPR8>;
6089  def _H : sve_int_bin_cons_shift_wide<0b01, opc, asm, ZPR16>;
6090  def _S : sve_int_bin_cons_shift_wide<0b10, opc, asm, ZPR32>;
6091
6092  def : SVE_2_Op_Pred_All_Active<nxv16i8, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
6093  def : SVE_2_Op_Pred_All_Active<nxv8i16, op, nxv8i1, nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
6094  def : SVE_2_Op_Pred_All_Active<nxv4i32, op, nxv4i1, nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
6095}
6096
6097class sve_int_bin_cons_shift_imm<bits<4> tsz8_64, bits<2> opc, string asm,
6098                               ZPRRegOp zprty, Operand immtype>
6099: I<(outs zprty:$Zd), (ins zprty:$Zn, immtype:$imm),
6100  asm, "\t$Zd, $Zn, $imm",
6101  "",
6102  []>, Sched<[]> {
6103  bits<5> Zd;
6104  bits<5> Zn;
6105  bits<6> imm;
6106  let Inst{31-24} = 0b00000100;
6107  let Inst{23-22} = tsz8_64{3-2};
6108  let Inst{21}    = 0b1;
6109  let Inst{20-19} = tsz8_64{1-0};
6110  let Inst{18-16} = imm{2-0}; // imm3
6111  let Inst{15-12} = 0b1001;
6112  let Inst{11-10} = opc;
6113  let Inst{9-5}   = Zn;
6114  let Inst{4-0}   = Zd;
6115
6116  let hasSideEffects = 0;
6117}
6118
6119multiclass sve_int_bin_cons_shift_imm_left<bits<2> opc, string asm,
6120                                           SDPatternOperator op> {
6121  def _B : sve_int_bin_cons_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
6122  def _H : sve_int_bin_cons_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
6123    let Inst{19} = imm{3};
6124  }
6125  def _S : sve_int_bin_cons_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
6126    let Inst{20-19} = imm{4-3};
6127  }
6128  def _D : sve_int_bin_cons_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
6129    let Inst{22}    = imm{5};
6130    let Inst{20-19} = imm{4-3};
6131  }
6132
6133  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8,  !cast<Instruction>(NAME # _B)>;
6134  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
6135  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
6136  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
6137}
6138
6139multiclass sve_int_bin_cons_shift_imm_right<bits<2> opc, string asm,
6140                                            SDPatternOperator op> {
6141  def _B : sve_int_bin_cons_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
6142  def _H : sve_int_bin_cons_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
6143    let Inst{19} = imm{3};
6144  }
6145  def _S : sve_int_bin_cons_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
6146    let Inst{20-19} = imm{4-3};
6147  }
6148  def _D : sve_int_bin_cons_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
6149    let Inst{22}    = imm{5};
6150    let Inst{20-19} = imm{4-3};
6151  }
6152
6153  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8,  !cast<Instruction>(NAME # _B)>;
6154  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
6155  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
6156  def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
6157}
6158
6159//===----------------------------------------------------------------------===//
6160// SVE Memory - Store Group
6161//===----------------------------------------------------------------------===//
6162
6163class sve_mem_cst_si<bits<2> msz, bits<2> esz, string asm,
6164                     RegisterOperand VecList>
6165: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
6166  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6167  "",
6168  []>, Sched<[]> {
6169  bits<3> Pg;
6170  bits<5> Rn;
6171  bits<5> Zt;
6172  bits<4> imm4;
6173  let Inst{31-25} = 0b1110010;
6174  let Inst{24-23} = msz;
6175  let Inst{22-21} = esz;
6176  let Inst{20}    = 0;
6177  let Inst{19-16} = imm4;
6178  let Inst{15-13} = 0b111;
6179  let Inst{12-10} = Pg;
6180  let Inst{9-5}   = Rn;
6181  let Inst{4-0}   = Zt;
6182
6183  let hasSideEffects = 0;
6184  let mayStore = 1;
6185}
6186
6187multiclass sve_mem_cst_si<bits<2> msz, bits<2> esz, string asm,
6188                          RegisterOperand listty, ZPRRegOp zprty>
6189{
6190  def NAME : sve_mem_cst_si<msz, esz, asm, listty>;
6191
6192  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6193                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
6194  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6195                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
6196  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6197                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6198}
6199
6200class sve_mem_est_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6201                     string asm, Operand immtype>
6202: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
6203  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6204  "",
6205  []>, Sched<[]> {
6206  bits<3> Pg;
6207  bits<5> Rn;
6208  bits<5> Zt;
6209  bits<4> imm4;
6210  let Inst{31-25} = 0b1110010;
6211  let Inst{24-23} = sz;
6212  let Inst{22-21} = nregs;
6213  let Inst{20}    = 1;
6214  let Inst{19-16} = imm4;
6215  let Inst{15-13} = 0b111;
6216  let Inst{12-10} = Pg;
6217  let Inst{9-5}   = Rn;
6218  let Inst{4-0}   = Zt;
6219
6220  let hasSideEffects = 0;
6221  let mayStore = 1;
6222}
6223
6224multiclass sve_mem_est_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6225                          string asm, Operand immtype> {
6226  def NAME : sve_mem_est_si<sz, nregs, VecList, asm, immtype>;
6227
6228  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6229                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6230}
6231
6232
6233// SVE store multiple structures (quadwords, scalar plus immediate)
6234class sve_mem_128b_est_si<bits<2> nregs, RegisterOperand VecList,
6235                          string asm, Operand immtype>
6236    : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
6237        asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6238        "", []>, Sched<[]> {
6239  bits<5> Zt;
6240  bits<5> Rn;
6241  bits<3> Pg;
6242  bits<4> imm4;
6243  let Inst{31-24} = 0b11100100;
6244  let Inst{23-22} = nregs;
6245  let Inst{21-20} = 0b00;
6246  let Inst{19-16} = imm4;
6247  let Inst{15-13} = 0b000;
6248  let Inst{12-10} = Pg;
6249  let Inst{9-5}   = Rn;
6250  let Inst{4-0}   = Zt;
6251
6252  let hasSideEffects = 0;
6253  let mayStore = 1;
6254}
6255
6256multiclass sve_mem_128b_est_si<bits<2> nregs, RegisterOperand VecList,
6257                               string asm, Operand immtype> {
6258  def NAME : sve_mem_128b_est_si<nregs, VecList, asm, immtype>;
6259
6260  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6261                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6262}
6263
6264
6265class sve_mem_est_ss<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6266                     string asm, RegisterOperand gprty>
6267: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6268  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6269  "",
6270  []>, Sched<[]> {
6271  bits<3> Pg;
6272  bits<5> Rm;
6273  bits<5> Rn;
6274  bits<5> Zt;
6275  let Inst{31-25} = 0b1110010;
6276  let Inst{24-23} = sz;
6277  let Inst{22-21} = nregs;
6278  let Inst{20-16} = Rm;
6279  let Inst{15-13} = 0b011;
6280  let Inst{12-10} = Pg;
6281  let Inst{9-5}   = Rn;
6282  let Inst{4-0}   = Zt;
6283
6284  let hasSideEffects = 0;
6285  let mayStore = 1;
6286}
6287
6288
6289// SVE store multiple structures (quadwords, scalar plus scalar)
6290class sve_mem_128b_est_ss<bits<2> nregs, RegisterOperand VecList,
6291                          string asm, RegisterOperand gprty>
6292    : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6293        asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6294        "", []>, Sched<[]> {
6295  bits<5> Zt;
6296  bits<5> Rn;
6297  bits<3> Pg;
6298  bits<5> Rm;
6299  let Inst{31-24} = 0b11100100;
6300  let Inst{23-22} = nregs;
6301  let Inst{21}    = 0b1;
6302  let Inst{20-16} = Rm;
6303  let Inst{15-13} = 0b000;
6304  let Inst{12-10} = Pg;
6305  let Inst{9-5}   = Rn;
6306  let Inst{4-0}   = Zt;
6307
6308  let hasSideEffects = 0;
6309  let mayStore = 1;
6310}
6311
6312
6313class sve_mem_cst_ss_base<bits<4> dtype, string asm,
6314                          RegisterOperand listty, RegisterOperand gprty>
6315: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6316  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6317  "",
6318  []>, Sched<[]> {
6319  bits<3> Pg;
6320  bits<5> Rm;
6321  bits<5> Rn;
6322  bits<5> Zt;
6323  let Inst{31-25} = 0b1110010;
6324  let Inst{24-21} = dtype;
6325  let Inst{20-16} = Rm;
6326  let Inst{15-13} = 0b010;
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_cst_ss<bits<4> dtype, string asm,
6336                          RegisterOperand listty, ZPRRegOp zprty,
6337                          RegisterOperand gprty> {
6338  def NAME : sve_mem_cst_ss_base<dtype, asm, listty, gprty>;
6339
6340  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Rm]",
6341                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
6342}
6343
6344class sve_mem_cstnt_si<bits<2> msz, string asm, RegisterOperand VecList>
6345: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
6346  asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6347  "",
6348  []>, Sched<[]> {
6349  bits<3> Pg;
6350  bits<5> Rn;
6351  bits<5> Zt;
6352  bits<4> imm4;
6353  let Inst{31-25} = 0b1110010;
6354  let Inst{24-23} = msz;
6355  let Inst{22-20} = 0b001;
6356  let Inst{19-16} = imm4;
6357  let Inst{15-13} = 0b111;
6358  let Inst{12-10} = Pg;
6359  let Inst{9-5}   = Rn;
6360  let Inst{4-0}   = Zt;
6361
6362  let hasSideEffects = 0;
6363  let mayStore = 1;
6364}
6365
6366multiclass sve_mem_cstnt_si<bits<2> msz, string asm, RegisterOperand listty,
6367                            ZPRRegOp zprty> {
6368  def NAME : sve_mem_cstnt_si<msz, asm, listty>;
6369
6370  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6371                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
6372  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6373                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
6374  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6375                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6376}
6377
6378class sve_mem_cstnt_ss_base<bits<2> msz, string asm, RegisterOperand listty,
6379                            RegisterOperand gprty>
6380: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6381  asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6382  "",
6383  []>, Sched<[]> {
6384  bits<3> Pg;
6385  bits<5> Rm;
6386  bits<5> Rn;
6387  bits<5> Zt;
6388  let Inst{31-25} = 0b1110010;
6389  let Inst{24-23} = msz;
6390  let Inst{22-21} = 0b00;
6391  let Inst{20-16} = Rm;
6392  let Inst{15-13} = 0b011;
6393  let Inst{12-10} = Pg;
6394  let Inst{9-5}   = Rn;
6395  let Inst{4-0}   = Zt;
6396
6397  let hasSideEffects = 0;
6398  let mayStore = 1;
6399}
6400
6401multiclass sve_mem_cstnt_ss<bits<2> msz, string asm, RegisterOperand listty,
6402                            ZPRRegOp zprty, RegisterOperand gprty> {
6403  def NAME : sve_mem_cstnt_ss_base<msz, asm, listty, gprty>;
6404
6405  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Rm]",
6406                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
6407}
6408
6409class sve2_mem_sstnt_vs_base<bits<3> opc, string asm,
6410                             RegisterOperand listty, ZPRRegOp zprty>
6411: I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, zprty:$Zn, GPR64:$Rm),
6412  asm, "\t$Zt, $Pg, [$Zn, $Rm]",
6413  "",
6414  []>, Sched<[]> {
6415  bits<3> Pg;
6416  bits<5> Rm;
6417  bits<5> Zn;
6418  bits<5> Zt;
6419  let Inst{31-25} = 0b1110010;
6420  let Inst{24-22} = opc;
6421  let Inst{21}    = 0b0;
6422  let Inst{20-16} = Rm;
6423  let Inst{15-13} = 0b001;
6424  let Inst{12-10} = Pg;
6425  let Inst{9-5}   = Zn;
6426  let Inst{4-0}   = Zt;
6427
6428  let hasSideEffects = 0;
6429  let mayStore = 1;
6430}
6431
6432multiclass sve2_mem_sstnt_vs_32_ptrs<bits<3> opc, string asm,
6433                             SDPatternOperator op,
6434                             ValueType vt> {
6435  def NAME : sve2_mem_sstnt_vs_base<opc, asm, Z_s, ZPR32>;
6436
6437  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $Rm]",
6438                 (!cast<Instruction>(NAME) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm), 0>;
6439  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6440                 (!cast<Instruction>(NAME) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 0>;
6441  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6442                 (!cast<Instruction>(NAME) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 1>;
6443
6444  def : Pat <(op (nxv4i32 ZPR32:$Zt), (nxv4i1 PPR3bAny:$Pg), (nxv4i32 ZPR32:$Zn), (i64 GPR64:$Rm), vt),
6445             (!cast<Instruction>(NAME) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm)>;
6446}
6447
6448multiclass sve2_mem_sstnt_vs_64_ptrs<bits<3> opc, string asm,
6449                             SDPatternOperator op,
6450                             ValueType vt> {
6451  def NAME : sve2_mem_sstnt_vs_base<opc, asm, Z_d, ZPR64>;
6452
6453  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $Rm]",
6454                 (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm), 0>;
6455  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6456                 (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 0>;
6457  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6458                 (!cast<Instruction>(NAME) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
6459
6460  def : Pat <(op (nxv2i64 ZPR64:$Zt), (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64:$Rm), vt),
6461             (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
6462}
6463
6464class sve_mem_sst_sv<bits<3> opc, bit xs, bit scaled, string asm,
6465                     RegisterOperand VecList, RegisterOperand zprext>
6466: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
6467  asm, "\t$Zt, $Pg, [$Rn, $Zm]",
6468  "",
6469  []>, Sched<[]> {
6470  bits<3> Pg;
6471  bits<5> Rn;
6472  bits<5> Zm;
6473  bits<5> Zt;
6474  let Inst{31-25} = 0b1110010;
6475  let Inst{24-22} = opc;
6476  let Inst{21}    = scaled;
6477  let Inst{20-16} = Zm;
6478  let Inst{15}    = 0b1;
6479  let Inst{14}    = xs;
6480  let Inst{13}    = 0;
6481  let Inst{12-10} = Pg;
6482  let Inst{9-5}   = Rn;
6483  let Inst{4-0}   = Zt;
6484
6485  let hasSideEffects = 0;
6486  let mayStore = 1;
6487}
6488
6489multiclass sve_mem_32b_sst_sv_32_scaled<bits<3> opc, string asm,
6490                                    SDPatternOperator sxtw_op,
6491                                    SDPatternOperator uxtw_op,
6492                                    RegisterOperand sxtw_opnd,
6493                                    RegisterOperand uxtw_opnd,
6494                                    ValueType vt > {
6495  def _UXTW_SCALED : sve_mem_sst_sv<opc, 0, 1, asm, Z_s, uxtw_opnd>;
6496  def _SXTW_SCALED : sve_mem_sst_sv<opc, 1, 1, asm, Z_s, sxtw_opnd>;
6497
6498  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6499                 (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6500  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6501                 (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6502
6503  def : Pat<(uxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6504            (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6505  def : Pat<(sxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6506            (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6507}
6508
6509multiclass sve_mem_64b_sst_sv_32_scaled<bits<3> opc, string asm,
6510                                    SDPatternOperator sxtw_op,
6511                                    SDPatternOperator uxtw_op,
6512                                    RegisterOperand sxtw_opnd,
6513                                    RegisterOperand uxtw_opnd,
6514                                    ValueType vt > {
6515  def _UXTW_SCALED : sve_mem_sst_sv<opc, 0, 1, asm, Z_d, uxtw_opnd>;
6516  def _SXTW_SCALED : sve_mem_sst_sv<opc, 1, 1, asm, Z_d, sxtw_opnd>;
6517
6518  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6519                 (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6520  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6521                 (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6522
6523  def : Pat<(uxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6524            (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6525  def : Pat<(sxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6526            (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6527}
6528
6529multiclass sve_mem_64b_sst_sv_32_unscaled<bits<3> opc, string asm,
6530                                         SDPatternOperator sxtw_op,
6531                                         SDPatternOperator uxtw_op,
6532                                         RegisterOperand sxtw_opnd,
6533                                         RegisterOperand uxtw_opnd,
6534                                         ValueType vt> {
6535  def _UXTW : sve_mem_sst_sv<opc, 0, 0, asm, Z_d, uxtw_opnd>;
6536  def _SXTW : sve_mem_sst_sv<opc, 1, 0, asm, Z_d, sxtw_opnd>;
6537
6538  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6539                 (!cast<Instruction>(NAME # _UXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6540  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6541                 (!cast<Instruction>(NAME # _SXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6542
6543  def : Pat<(uxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6544            (!cast<Instruction>(NAME # _UXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6545  def : Pat<(sxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6546            (!cast<Instruction>(NAME # _SXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6547}
6548
6549multiclass sve_mem_32b_sst_sv_32_unscaled<bits<3> opc, string asm,
6550                                          SDPatternOperator sxtw_op,
6551                                          SDPatternOperator uxtw_op,
6552                                          RegisterOperand sxtw_opnd,
6553                                          RegisterOperand uxtw_opnd,
6554                                          ValueType vt> {
6555  def _UXTW : sve_mem_sst_sv<opc, 0, 0, asm, Z_s, uxtw_opnd>;
6556  def _SXTW : sve_mem_sst_sv<opc, 1, 0, asm, Z_s, sxtw_opnd>;
6557
6558  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6559                 (!cast<Instruction>(NAME # _UXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6560  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6561                 (!cast<Instruction>(NAME # _SXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6562
6563  def : Pat<(uxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6564            (!cast<Instruction>(NAME # _UXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6565  def : Pat<(sxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6566            (!cast<Instruction>(NAME # _SXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6567}
6568
6569class sve_mem_sst_sv2<bits<2> msz, bit scaled, string asm,
6570                      RegisterOperand zprext>
6571: I<(outs), (ins Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
6572  asm, "\t$Zt, $Pg, [$Rn, $Zm]",
6573  "",
6574  []>, Sched<[]> {
6575  bits<3> Pg;
6576  bits<5> Rn;
6577  bits<5> Zm;
6578  bits<5> Zt;
6579  let Inst{31-25} = 0b1110010;
6580  let Inst{24-23} = msz;
6581  let Inst{22}    = 0b0;
6582  let Inst{21}    = scaled;
6583  let Inst{20-16} = Zm;
6584  let Inst{15-13} = 0b101;
6585  let Inst{12-10} = Pg;
6586  let Inst{9-5}   = Rn;
6587  let Inst{4-0}   = Zt;
6588
6589  let hasSideEffects = 0;
6590  let mayStore = 1;
6591}
6592
6593multiclass sve_mem_sst_sv_64_scaled<bits<2> msz, string asm,
6594                                    SDPatternOperator op,
6595                                    RegisterOperand zprext,
6596                                    ValueType vt> {
6597  def _SCALED : sve_mem_sst_sv2<msz, 1, asm, zprext>;
6598
6599  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6600                 (!cast<Instruction>(NAME # _SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), 0>;
6601
6602  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt),
6603            (!cast<Instruction>(NAME # _SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
6604}
6605
6606multiclass sve_mem_sst_sv_64_unscaled<bits<2> msz, string asm,
6607                                      SDPatternOperator op,
6608                                      ValueType vt> {
6609  def NAME : sve_mem_sst_sv2<msz, 0, asm, ZPR64ExtLSL8>;
6610
6611  def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6612                 (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), 0>;
6613
6614  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6615            (!cast<Instruction>(NAME) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6616}
6617
6618class sve_mem_sst_vi<bits<3> opc, string asm, ZPRRegOp zprty,
6619                     RegisterOperand VecList, Operand imm_ty>
6620: I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, zprty:$Zn, imm_ty:$imm5),
6621  asm, "\t$Zt, $Pg, [$Zn, $imm5]",
6622  "",
6623  []>, Sched<[]> {
6624  bits<3> Pg;
6625  bits<5> imm5;
6626  bits<5> Zn;
6627  bits<5> Zt;
6628  let Inst{31-25} = 0b1110010;
6629  let Inst{24-23} = opc{2-1};
6630  let Inst{22}    = 0b1;
6631  let Inst{21}    = opc{0};
6632  let Inst{20-16} = imm5;
6633  let Inst{15-13} = 0b101;
6634  let Inst{12-10} = Pg;
6635  let Inst{9-5}   = Zn;
6636  let Inst{4-0}   = Zt;
6637
6638  let hasSideEffects = 0;
6639  let mayStore = 1;
6640}
6641
6642multiclass sve_mem_32b_sst_vi_ptrs<bits<3> opc, string asm,
6643                                   Operand imm_ty,
6644                                   SDPatternOperator op,
6645                                   ValueType vt> {
6646  def _IMM : sve_mem_sst_vi<opc, asm, ZPR32, Z_s, imm_ty>;
6647
6648  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6649                  (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 0>;
6650  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $imm5]",
6651                  (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), 0>;
6652  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6653                  (!cast<Instruction>(NAME # _IMM) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
6654
6655  def : Pat<(op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), (nxv4i32 ZPR:$ptrs), imm_ty:$index, vt),
6656            (!cast<Instruction>(NAME # _IMM) ZPR:$data, PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
6657}
6658
6659multiclass sve_mem_64b_sst_vi_ptrs<bits<3> opc, string asm,
6660                                   Operand imm_ty,
6661                                   SDPatternOperator op,
6662                                   ValueType vt> {
6663  def _IMM : sve_mem_sst_vi<opc, asm, ZPR64, Z_d, imm_ty>;
6664
6665  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6666                  (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 0>;
6667  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $imm5]",
6668                  (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), 0>;
6669  def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6670                  (!cast<Instruction>(NAME # _IMM) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
6671
6672  def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), (nxv2i64 ZPR:$ptrs), imm_ty:$index, vt),
6673            (!cast<Instruction>(NAME # _IMM) ZPR:$data, PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
6674}
6675
6676class sve_mem_z_spill<string asm>
6677: I<(outs), (ins ZPRAny:$Zt, GPR64sp:$Rn, simm9:$imm9),
6678  asm, "\t$Zt, [$Rn, $imm9, mul vl]",
6679  "",
6680  []>, Sched<[]> {
6681  bits<5> Rn;
6682  bits<5> Zt;
6683  bits<9> imm9;
6684  let Inst{31-22} = 0b1110010110;
6685  let Inst{21-16} = imm9{8-3};
6686  let Inst{15-13} = 0b010;
6687  let Inst{12-10} = imm9{2-0};
6688  let Inst{9-5}   = Rn;
6689  let Inst{4-0}   = Zt;
6690
6691  let hasSideEffects = 0;
6692  let mayStore = 1;
6693}
6694
6695multiclass sve_mem_z_spill<string asm> {
6696  def NAME : sve_mem_z_spill<asm>;
6697
6698  def : InstAlias<asm # "\t$Zt, [$Rn]",
6699                  (!cast<Instruction>(NAME) ZPRAny:$Zt, GPR64sp:$Rn, 0), 1>;
6700}
6701
6702class sve_mem_p_spill<string asm>
6703: I<(outs), (ins PPRorPNRAny:$Pt, GPR64sp:$Rn, simm9:$imm9),
6704  asm, "\t$Pt, [$Rn, $imm9, mul vl]",
6705  "",
6706  []>, Sched<[]> {
6707  bits<4> Pt;
6708  bits<5> Rn;
6709  bits<9> imm9;
6710  let Inst{31-22} = 0b1110010110;
6711  let Inst{21-16} = imm9{8-3};
6712  let Inst{15-13} = 0b000;
6713  let Inst{12-10} = imm9{2-0};
6714  let Inst{9-5}   = Rn;
6715  let Inst{4}     = 0b0;
6716  let Inst{3-0}   = Pt;
6717
6718  let hasSideEffects = 0;
6719  let mayStore = 1;
6720}
6721
6722multiclass sve_mem_p_spill<string asm> {
6723  def NAME : sve_mem_p_spill<asm>;
6724
6725  def : InstAlias<asm # "\t$Pt, [$Rn]",
6726                  (!cast<Instruction>(NAME) PPRorPNRAny:$Pt, GPR64sp:$Rn, 0), 1>;
6727}
6728
6729//===----------------------------------------------------------------------===//
6730// SVE Permute - Predicates Group
6731//===----------------------------------------------------------------------===//
6732
6733class sve_int_perm_bin_perm_pp<bits<3> opc, bits<2> sz8_64, string asm,
6734                               PPRRegOp pprty, SDPatternOperator op>
6735: I<(outs pprty:$Pd), (ins pprty:$Pn, pprty:$Pm),
6736  asm, "\t$Pd, $Pn, $Pm",
6737  "",
6738  [(set nxv16i1:$Pd, (op nxv16i1:$Pn, nxv16i1:$Pm))]>, Sched<[]> {
6739  bits<4> Pd;
6740  bits<4> Pm;
6741  bits<4> Pn;
6742  let Inst{31-24} = 0b00000101;
6743  let Inst{23-22} = sz8_64;
6744  let Inst{21-20} = 0b10;
6745  let Inst{19-16} = Pm;
6746  let Inst{15-13} = 0b010;
6747  let Inst{12-10} = opc;
6748  let Inst{9}     = 0b0;
6749  let Inst{8-5}   = Pn;
6750  let Inst{4}     = 0b0;
6751  let Inst{3-0}   = Pd;
6752
6753  let hasSideEffects = 0;
6754}
6755
6756multiclass sve_int_perm_bin_perm_pp<bits<3> opc, string asm,
6757                                    SDPatternOperator ir_op,
6758                                    SDPatternOperator op_b16,
6759                                    SDPatternOperator op_b32,
6760                                    SDPatternOperator op_b64> {
6761  def _B : sve_int_perm_bin_perm_pp<opc, 0b00, asm, PPR8,  ir_op>;
6762  def _H : sve_int_perm_bin_perm_pp<opc, 0b01, asm, PPR16, op_b16>;
6763  def _S : sve_int_perm_bin_perm_pp<opc, 0b10, asm, PPR32, op_b32>;
6764  def _D : sve_int_perm_bin_perm_pp<opc, 0b11, asm, PPR64, op_b64>;
6765
6766  def : SVE_2_Op_Pat<nxv8i1, ir_op, nxv8i1, nxv8i1, !cast<Instruction>(NAME # _H)>;
6767  def : SVE_2_Op_Pat<nxv4i1, ir_op, nxv4i1, nxv4i1, !cast<Instruction>(NAME # _S)>;
6768  def : SVE_2_Op_Pat<nxv2i1, ir_op, nxv2i1, nxv2i1, !cast<Instruction>(NAME # _D)>;
6769}
6770
6771class sve_int_perm_punpk<bit opc, string asm>
6772: I<(outs PPR16:$Pd), (ins PPR8:$Pn),
6773  asm, "\t$Pd, $Pn",
6774  "",
6775  []>, Sched<[]> {
6776  bits<4> Pd;
6777  bits<4> Pn;
6778  let Inst{31-17} = 0b000001010011000;
6779  let Inst{16}    = opc;
6780  let Inst{15-9}  = 0b0100000;
6781  let Inst{8-5}   = Pn;
6782  let Inst{4}     = 0b0;
6783  let Inst{3-0}   = Pd;
6784
6785  let hasSideEffects = 0;
6786}
6787
6788multiclass sve_int_perm_punpk<bit opc, string asm, SDPatternOperator op> {
6789  def NAME : sve_int_perm_punpk<opc, asm>;
6790
6791  def : SVE_1_Op_Pat<nxv8i1, op, nxv16i1, !cast<Instruction>(NAME)>;
6792  def : SVE_1_Op_Pat<nxv4i1, op, nxv8i1,  !cast<Instruction>(NAME)>;
6793  def : SVE_1_Op_Pat<nxv2i1, op, nxv4i1,  !cast<Instruction>(NAME)>;
6794}
6795
6796class sve_int_rdffr_pred<bit s, string asm, SDPatternOperator op = null_frag>
6797: I<(outs PPR8:$Pd), (ins PPRAny:$Pg),
6798  asm, "\t$Pd, $Pg/z",
6799  "",
6800  [(set (nxv16i1 PPR8:$Pd), (op (nxv16i1 PPRAny:$Pg)))]>, Sched<[]> {
6801  bits<4> Pd;
6802  bits<4> Pg;
6803  let Inst{31-23} = 0b001001010;
6804  let Inst{22}    = s;
6805  let Inst{21-9}  = 0b0110001111000;
6806  let Inst{8-5}   = Pg;
6807  let Inst{4}     = 0;
6808  let Inst{3-0}   = Pd;
6809
6810  let Defs = !if(s, [NZCV], []);
6811  let Uses = [FFR];
6812  let hasSideEffects = 1;
6813}
6814
6815class sve_int_rdffr_unpred<string asm, SDPatternOperator op> : I<
6816  (outs PPR8:$Pd), (ins),
6817  asm, "\t$Pd",
6818  "",
6819  [(set (nxv16i1 PPR8:$Pd), (op))]>, Sched<[]> {
6820  bits<4> Pd;
6821  let Inst{31-4} = 0b0010010100011001111100000000;
6822  let Inst{3-0}   = Pd;
6823
6824  let Uses = [FFR];
6825  let hasSideEffects = 1;
6826}
6827
6828class sve_int_wrffr<string asm, SDPatternOperator op>
6829: I<(outs), (ins PPR8:$Pn),
6830  asm, "\t$Pn",
6831  "",
6832  [(op (nxv16i1 PPR8:$Pn))]>, Sched<[]> {
6833  bits<4> Pn;
6834  let Inst{31-9} = 0b00100101001010001001000;
6835  let Inst{8-5}  = Pn;
6836  let Inst{4-0}  = 0b00000;
6837
6838  let Defs = [FFR];
6839  let hasSideEffects = 1;
6840}
6841
6842class sve_int_setffr<string asm, SDPatternOperator op>
6843: I<(outs), (ins),
6844  asm, "",
6845  "",
6846  [(op)]>, Sched<[]> {
6847  let Inst{31-0} = 0b00100101001011001001000000000000;
6848
6849  let Defs = [FFR];
6850  let hasSideEffects = 1;
6851}
6852
6853//===----------------------------------------------------------------------===//
6854// SVE Permute Vector - Predicated Group
6855//===----------------------------------------------------------------------===//
6856
6857class sve_int_perm_clast_rz<bits<2> sz8_64, bit ab, string asm,
6858                            ZPRRegOp zprty, RegisterClass rt>
6859: I<(outs rt:$Rdn), (ins PPR3bAny:$Pg, rt:$_Rdn, zprty:$Zm),
6860  asm, "\t$Rdn, $Pg, $_Rdn, $Zm",
6861  "",
6862  []>, Sched<[]> {
6863  bits<3> Pg;
6864  bits<5> Rdn;
6865  bits<5> Zm;
6866  let Inst{31-24} = 0b00000101;
6867  let Inst{23-22} = sz8_64;
6868  let Inst{21-17} = 0b11000;
6869  let Inst{16}    = ab;
6870  let Inst{15-13} = 0b101;
6871  let Inst{12-10} = Pg;
6872  let Inst{9-5}   = Zm;
6873  let Inst{4-0}   = Rdn;
6874
6875  let Constraints = "$Rdn = $_Rdn";
6876  let hasSideEffects = 0;
6877}
6878
6879multiclass sve_int_perm_clast_rz<bit ab, string asm, SDPatternOperator op> {
6880  def _B : sve_int_perm_clast_rz<0b00, ab, asm, ZPR8, GPR32>;
6881  def _H : sve_int_perm_clast_rz<0b01, ab, asm, ZPR16, GPR32>;
6882  def _S : sve_int_perm_clast_rz<0b10, ab, asm, ZPR32, GPR32>;
6883  def _D : sve_int_perm_clast_rz<0b11, ab, asm, ZPR64, GPR64>;
6884
6885  def : SVE_3_Op_Pat<i32, op, nxv16i1, i32, nxv16i8, !cast<Instruction>(NAME # _B)>;
6886  def : SVE_3_Op_Pat<i32, op, nxv8i1,  i32, nxv8i16, !cast<Instruction>(NAME # _H)>;
6887  def : SVE_3_Op_Pat<i32, op, nxv4i1,  i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
6888  def : SVE_3_Op_Pat<i64, op, nxv2i1,  i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
6889}
6890
6891class sve_int_perm_clast_vz<bits<2> sz8_64, bit ab, string asm,
6892                            ZPRRegOp zprty, RegisterClass rt>
6893: I<(outs rt:$Vdn), (ins PPR3bAny:$Pg, rt:$_Vdn, zprty:$Zm),
6894  asm, "\t$Vdn, $Pg, $_Vdn, $Zm",
6895  "",
6896  []>, Sched<[]> {
6897  bits<3> Pg;
6898  bits<5> Vdn;
6899  bits<5> Zm;
6900  let Inst{31-24} = 0b00000101;
6901  let Inst{23-22} = sz8_64;
6902  let Inst{21-17} = 0b10101;
6903  let Inst{16}    = ab;
6904  let Inst{15-13} = 0b100;
6905  let Inst{12-10} = Pg;
6906  let Inst{9-5}   = Zm;
6907  let Inst{4-0}   = Vdn;
6908
6909  let Constraints = "$Vdn = $_Vdn";
6910  let hasSideEffects = 0;
6911}
6912
6913multiclass sve_int_perm_clast_vz<bit ab, string asm, SDPatternOperator op> {
6914  def _B : sve_int_perm_clast_vz<0b00, ab, asm, ZPR8, FPR8>;
6915  def _H : sve_int_perm_clast_vz<0b01, ab, asm, ZPR16, FPR16>;
6916  def _S : sve_int_perm_clast_vz<0b10, ab, asm, ZPR32, FPR32>;
6917  def _D : sve_int_perm_clast_vz<0b11, ab, asm, ZPR64, FPR64>;
6918
6919  def : SVE_3_Op_Pat<f16, op, nxv8i1, f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
6920  def : SVE_3_Op_Pat<f32, op, nxv4i1, f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
6921  def : SVE_3_Op_Pat<f64, op, nxv2i1, f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
6922
6923  def : SVE_3_Op_Pat<bf16, op, nxv8i1, bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
6924}
6925
6926class sve_int_perm_clast_zz<bits<2> sz8_64, bit ab, string asm,
6927                            ZPRRegOp zprty>
6928: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
6929  asm, "\t$Zdn, $Pg, $_Zdn, $Zm",
6930  "",
6931  []>, Sched<[]> {
6932  bits<3> Pg;
6933  bits<5> Zdn;
6934  bits<5> Zm;
6935  let Inst{31-24} = 0b00000101;
6936  let Inst{23-22} = sz8_64;
6937  let Inst{21-17} = 0b10100;
6938  let Inst{16}    = ab;
6939  let Inst{15-13} = 0b100;
6940  let Inst{12-10} = Pg;
6941  let Inst{9-5}   = Zm;
6942  let Inst{4-0}   = Zdn;
6943
6944  let Constraints = "$Zdn = $_Zdn";
6945  let DestructiveInstType = DestructiveOther;
6946  let ElementSize = ElementSizeNone;
6947  let hasSideEffects = 0;
6948}
6949
6950multiclass sve_int_perm_clast_zz<bit ab, string asm, SDPatternOperator op> {
6951  def _B : sve_int_perm_clast_zz<0b00, ab, asm, ZPR8>;
6952  def _H : sve_int_perm_clast_zz<0b01, ab, asm, ZPR16>;
6953  def _S : sve_int_perm_clast_zz<0b10, ab, asm, ZPR32>;
6954  def _D : sve_int_perm_clast_zz<0b11, ab, asm, ZPR64>;
6955
6956  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
6957  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
6958  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
6959  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
6960
6961  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
6962  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
6963  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
6964
6965  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
6966}
6967
6968class sve_int_perm_last_r<bits<2> sz8_64, bit ab, string asm,
6969                          ZPRRegOp zprty, RegisterClass resultRegType>
6970: I<(outs resultRegType:$Rd), (ins PPR3bAny:$Pg, zprty:$Zn),
6971  asm, "\t$Rd, $Pg, $Zn",
6972  "",
6973  []>, Sched<[]> {
6974  bits<3> Pg;
6975  bits<5> Rd;
6976  bits<5> Zn;
6977  let Inst{31-24} = 0b00000101;
6978  let Inst{23-22} = sz8_64;
6979  let Inst{21-17} = 0b10000;
6980  let Inst{16}    = ab;
6981  let Inst{15-13} = 0b101;
6982  let Inst{12-10} = Pg;
6983  let Inst{9-5}   = Zn;
6984  let Inst{4-0}   = Rd;
6985
6986  let hasSideEffects = 0;
6987}
6988
6989multiclass sve_int_perm_last_r<bit ab, string asm, SDPatternOperator op> {
6990  def _B : sve_int_perm_last_r<0b00, ab, asm, ZPR8, GPR32>;
6991  def _H : sve_int_perm_last_r<0b01, ab, asm, ZPR16, GPR32>;
6992  def _S : sve_int_perm_last_r<0b10, ab, asm, ZPR32, GPR32>;
6993  def _D : sve_int_perm_last_r<0b11, ab, asm, ZPR64, GPR64>;
6994
6995  def : SVE_2_Op_Pat<i32, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
6996  def : SVE_2_Op_Pat<i32, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
6997  def : SVE_2_Op_Pat<i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
6998  def : SVE_2_Op_Pat<i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
6999}
7000
7001class sve_int_perm_last_v<bits<2> sz8_64, bit ab, string asm,
7002                          ZPRRegOp zprty, RegisterClass dstRegtype>
7003: I<(outs dstRegtype:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
7004  asm, "\t$Vd, $Pg, $Zn",
7005  "",
7006  []>, Sched<[]> {
7007  bits<3> Pg;
7008  bits<5> Vd;
7009  bits<5> Zn;
7010  let Inst{31-24} = 0b00000101;
7011  let Inst{23-22} = sz8_64;
7012  let Inst{21-17} = 0b10001;
7013  let Inst{16}    = ab;
7014  let Inst{15-13} = 0b100;
7015  let Inst{12-10} = Pg;
7016  let Inst{9-5}   = Zn;
7017  let Inst{4-0}   = Vd;
7018
7019  let hasSideEffects = 0;
7020}
7021
7022multiclass sve_int_perm_last_v<bit ab, string asm, SDPatternOperator op> {
7023  def _B : sve_int_perm_last_v<0b00, ab, asm, ZPR8, FPR8>;
7024  def _H : sve_int_perm_last_v<0b01, ab, asm, ZPR16, FPR16>;
7025  def _S : sve_int_perm_last_v<0b10, ab, asm, ZPR32, FPR32>;
7026  def _D : sve_int_perm_last_v<0b11, ab, asm, ZPR64, FPR64>;
7027
7028  def : SVE_2_Op_Pat<f16, op, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
7029  def : SVE_2_Op_Pat<f32, op, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
7030  def : SVE_2_Op_Pat<f32, op, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
7031  def : SVE_2_Op_Pat<f64, op, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
7032
7033  def : SVE_2_Op_Pat<bf16, op, nxv8i1,  nxv8bf16, !cast<Instruction>(NAME # _H)>;
7034}
7035
7036class sve_int_perm_splice<bits<2> sz8_64, string asm, ZPRRegOp zprty>
7037: I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
7038  asm, "\t$Zdn, $Pg, $_Zdn, $Zm",
7039  "",
7040  []>, Sched<[]> {
7041  bits<3> Pg;
7042  bits<5> Zdn;
7043  bits<5> Zm;
7044  let Inst{31-24} = 0b00000101;
7045  let Inst{23-22} = sz8_64;
7046  let Inst{21-13} = 0b101100100;
7047  let Inst{12-10} = Pg;
7048  let Inst{9-5}   = Zm;
7049  let Inst{4-0}   = Zdn;
7050
7051  let Constraints = "$Zdn = $_Zdn";
7052  let DestructiveInstType = DestructiveOther;
7053  let ElementSize = ElementSizeNone;
7054  let hasSideEffects = 0;
7055}
7056
7057multiclass sve_int_perm_splice<string asm, SDPatternOperator op> {
7058  def _B : sve_int_perm_splice<0b00, asm, ZPR8>;
7059  def _H : sve_int_perm_splice<0b01, asm, ZPR16>;
7060  def _S : sve_int_perm_splice<0b10, asm, ZPR32>;
7061  def _D : sve_int_perm_splice<0b11, asm, ZPR64>;
7062
7063 foreach VT = [nxv16i8] in
7064   def : SVE_3_Op_Pat<VT, op, nxv16i1, VT, VT, !cast<Instruction>(NAME # _B)>;
7065
7066 foreach VT = [nxv8i16, nxv8f16, nxv8bf16] in
7067   def : SVE_3_Op_Pat<VT, op, nxv8i1, VT, VT, !cast<Instruction>(NAME # _H)>;
7068
7069 foreach VT = [nxv4i32, nxv4f16, nxv4f32, nxv4bf16] in
7070   def : SVE_3_Op_Pat<VT, op, nxv4i1, VT, VT, !cast<Instruction>(NAME # _S)>;
7071
7072 foreach VT = [nxv2i64, nxv2f16, nxv2f32, nxv2f64, nxv2bf16] in
7073   def : SVE_3_Op_Pat<VT, op, nxv2i1, VT, VT, !cast<Instruction>(NAME # _D)>;
7074}
7075
7076class sve2_int_perm_splice_cons<bits<2> sz8_64, string asm,
7077                               ZPRRegOp zprty, RegisterOperand VecList>
7078: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, VecList:$Zn),
7079  asm, "\t$Zd, $Pg, $Zn",
7080  "",
7081  []>, Sched<[]> {
7082  bits<3> Pg;
7083  bits<5> Zn;
7084  bits<5> Zd;
7085  let Inst{31-24} = 0b00000101;
7086  let Inst{23-22} = sz8_64;
7087  let Inst{21-13} = 0b101101100;
7088  let Inst{12-10} = Pg;
7089  let Inst{9-5}   = Zn;
7090  let Inst{4-0}   = Zd;
7091
7092  let hasSideEffects = 0;
7093}
7094
7095multiclass sve2_int_perm_splice_cons<string asm> {
7096  def _B : sve2_int_perm_splice_cons<0b00, asm, ZPR8,  ZZ_b>;
7097  def _H : sve2_int_perm_splice_cons<0b01, asm, ZPR16, ZZ_h>;
7098  def _S : sve2_int_perm_splice_cons<0b10, asm, ZPR32, ZZ_s>;
7099  def _D : sve2_int_perm_splice_cons<0b11, asm, ZPR64, ZZ_d>;
7100}
7101
7102class sve_int_perm_rev<bits<2> sz8_64, bits<2> opc, string asm,
7103                       ZPRRegOp zprty>
7104: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
7105  asm, "\t$Zd, $Pg/m, $Zn",
7106  "",
7107  []>, Sched<[]> {
7108  bits<5> Zd;
7109  bits<3> Pg;
7110  bits<5> Zn;
7111  let Inst{31-24} = 0b00000101;
7112  let Inst{23-22} = sz8_64;
7113  let Inst{21-18} = 0b1001;
7114  let Inst{17-16} = opc;
7115  let Inst{15-13} = 0b100;
7116  let Inst{12-10} = Pg;
7117  let Inst{9-5}   = Zn;
7118  let Inst{4-0}   = Zd;
7119
7120  let Constraints = "$Zd = $_Zd";
7121  let DestructiveInstType = DestructiveOther;
7122  let ElementSize = zprty.ElementSize;
7123  let hasSideEffects = 0;
7124}
7125
7126multiclass sve_int_perm_rev_rbit<string asm, SDPatternOperator op> {
7127  def _B : sve_int_perm_rev<0b00, 0b11, asm, ZPR8>;
7128  def _H : sve_int_perm_rev<0b01, 0b11, asm, ZPR16>;
7129  def _S : sve_int_perm_rev<0b10, 0b11, asm, ZPR32>;
7130  def _D : sve_int_perm_rev<0b11, 0b11, asm, ZPR64>;
7131
7132  def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
7133  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
7134  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7135  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7136}
7137
7138multiclass sve_int_perm_rev_revb<string asm, SDPatternOperator op> {
7139  def _H : sve_int_perm_rev<0b01, 0b00, asm, ZPR16>;
7140  def _S : sve_int_perm_rev<0b10, 0b00, asm, ZPR32>;
7141  def _D : sve_int_perm_rev<0b11, 0b00, asm, ZPR64>;
7142
7143  def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
7144  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7145  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7146}
7147
7148multiclass sve_int_perm_rev_revh<string asm, SDPatternOperator op> {
7149  def _S : sve_int_perm_rev<0b10, 0b01, asm, ZPR32>;
7150  def _D : sve_int_perm_rev<0b11, 0b01, asm, ZPR64>;
7151
7152  def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7153  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7154}
7155
7156multiclass sve_int_perm_rev_revw<string asm, SDPatternOperator op> {
7157  def _D : sve_int_perm_rev<0b11, 0b10, asm, ZPR64>;
7158
7159  def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7160}
7161
7162class sve_int_perm_cpy_r<bits<2> sz8_64, string asm, ZPRRegOp zprty,
7163                         RegisterClass srcRegType>
7164: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegType:$Rn),
7165  asm, "\t$Zd, $Pg/m, $Rn",
7166  "",
7167  []>, Sched<[]> {
7168  bits<3> Pg;
7169  bits<5> Rn;
7170  bits<5> Zd;
7171  let Inst{31-24} = 0b00000101;
7172  let Inst{23-22} = sz8_64;
7173  let Inst{21-13} = 0b101000101;
7174  let Inst{12-10} = Pg;
7175  let Inst{9-5}   = Rn;
7176  let Inst{4-0}   = Zd;
7177
7178  let Constraints = "$Zd = $_Zd";
7179  let DestructiveInstType = DestructiveOther;
7180  let ElementSize = zprty.ElementSize;
7181  let hasSideEffects = 0;
7182}
7183
7184multiclass sve_int_perm_cpy_r<string asm, SDPatternOperator op> {
7185  def _B : sve_int_perm_cpy_r<0b00, asm, ZPR8, GPR32sp>;
7186  def _H : sve_int_perm_cpy_r<0b01, asm, ZPR16, GPR32sp>;
7187  def _S : sve_int_perm_cpy_r<0b10, asm, ZPR32, GPR32sp>;
7188  def _D : sve_int_perm_cpy_r<0b11, asm, ZPR64, GPR64sp>;
7189
7190  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7191                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7192  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7193                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7194  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7195                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7196  def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7197                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPR3bAny:$Pg, GPR64sp:$Rn), 1>;
7198
7199  def : Pat<(nxv16i8 (op nxv16i1:$pg, i32:$splat, nxv16i8:$passthru)),
7200            (!cast<Instruction>(NAME # _B) $passthru, $pg, $splat)>;
7201  def : Pat<(nxv8i16 (op nxv8i1:$pg, i32:$splat, nxv8i16:$passthru)),
7202            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7203  def : Pat<(nxv4i32 (op nxv4i1:$pg, i32:$splat, nxv4i32:$passthru)),
7204            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7205  def : Pat<(nxv2i64 (op nxv2i1:$pg, i64:$splat, nxv2i64:$passthru)),
7206            (!cast<Instruction>(NAME # _D) $passthru, $pg, $splat)>;
7207}
7208
7209class sve_int_perm_cpy_v<bits<2> sz8_64, string asm, ZPRRegOp zprty,
7210                         RegisterClass srcRegtype>
7211: I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegtype:$Vn),
7212  asm, "\t$Zd, $Pg/m, $Vn",
7213  "",
7214  []>, Sched<[]> {
7215  bits<3> Pg;
7216  bits<5> Vn;
7217  bits<5> Zd;
7218  let Inst{31-24} = 0b00000101;
7219  let Inst{23-22} = sz8_64;
7220  let Inst{21-13} = 0b100000100;
7221  let Inst{12-10} = Pg;
7222  let Inst{9-5}   = Vn;
7223  let Inst{4-0}   = Zd;
7224
7225  let Constraints = "$Zd = $_Zd";
7226  let DestructiveInstType = DestructiveOther;
7227  let ElementSize = zprty.ElementSize;
7228  let hasSideEffects = 0;
7229}
7230
7231multiclass sve_int_perm_cpy_v<string asm, SDPatternOperator op> {
7232  def _B : sve_int_perm_cpy_v<0b00, asm, ZPR8, FPR8>;
7233  def _H : sve_int_perm_cpy_v<0b01, asm, ZPR16, FPR16>;
7234  def _S : sve_int_perm_cpy_v<0b10, asm, ZPR32, FPR32>;
7235  def _D : sve_int_perm_cpy_v<0b11, asm, ZPR64, FPR64>;
7236
7237  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7238                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPR3bAny:$Pg, FPR8:$Vn), 1>;
7239  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7240                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPR3bAny:$Pg, FPR16:$Vn), 1>;
7241  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7242                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPR3bAny:$Pg, FPR32:$Vn), 1>;
7243  def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7244                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPR3bAny:$Pg, FPR64:$Vn), 1>;
7245
7246  def : Pat<(nxv8f16 (op nxv8i1:$pg, f16:$splat, nxv8f16:$passthru)),
7247            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7248  def : Pat<(nxv4f16 (op nxv4i1:$pg, f16:$splat, nxv4f16:$passthru)),
7249            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7250  def : Pat<(nxv2f16 (op nxv2i1:$pg, f16:$splat, nxv2f16:$passthru)),
7251            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7252  def : Pat<(nxv2f32 (op nxv2i1:$pg, f32:$splat, nxv2f32:$passthru)),
7253            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7254  def : Pat<(nxv4f32 (op nxv4i1:$pg, f32:$splat, nxv4f32:$passthru)),
7255            (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7256  def : Pat<(nxv2f64 (op nxv2i1:$pg, f64:$splat, nxv2f64:$passthru)),
7257            (!cast<Instruction>(NAME # _D) $passthru, $pg, $splat)>;
7258
7259  def : Pat<(nxv8bf16 (op nxv8i1:$pg, bf16:$splat, nxv8bf16:$passthru)),
7260            (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7261}
7262
7263class sve_int_perm_compact<bit sz, string asm, ZPRRegOp zprty>
7264: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
7265  asm, "\t$Zd, $Pg, $Zn",
7266  "",
7267  []>, Sched<[]> {
7268  bits<3> Pg;
7269  bits<5> Zd;
7270  bits<5> Zn;
7271  let Inst{31-23} = 0b000001011;
7272  let Inst{22}    = sz;
7273  let Inst{21-13} = 0b100001100;
7274  let Inst{12-10} = Pg;
7275  let Inst{9-5}   = Zn;
7276  let Inst{4-0}   = Zd;
7277
7278  let hasSideEffects = 0;
7279}
7280
7281multiclass sve_int_perm_compact<string asm, SDPatternOperator op> {
7282  def _S : sve_int_perm_compact<0b0, asm, ZPR32>;
7283  def _D : sve_int_perm_compact<0b1, asm, ZPR64>;
7284
7285  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
7286  def : SVE_2_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
7287  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
7288  def : SVE_2_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
7289}
7290
7291//===----------------------------------------------------------------------===//
7292// SVE Memory - Contiguous Load Group
7293//===----------------------------------------------------------------------===//
7294
7295class sve_mem_cld_si_base<bits<4> dtype, bit nf, string asm,
7296                          RegisterOperand VecList>
7297: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
7298  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7299  "",
7300  []>, Sched<[]> {
7301  bits<3> Pg;
7302  bits<5> Rn;
7303  bits<5> Zt;
7304  bits<4> imm4;
7305  let Inst{31-25} = 0b1010010;
7306  let Inst{24-21} = dtype;
7307  let Inst{20}    = nf;
7308  let Inst{19-16} = imm4;
7309  let Inst{15-13} = 0b101;
7310  let Inst{12-10} = Pg;
7311  let Inst{9-5}   = Rn;
7312  let Inst{4-0}   = Zt;
7313
7314  let Defs = !if(nf, [FFR], []);
7315  let Uses = !if(nf, [FFR], []);
7316  let hasSideEffects = nf;
7317  let mayLoad = 1;
7318}
7319
7320multiclass sve_mem_cld_si_base<bits<4> dtype, bit nf, string asm,
7321                               RegisterOperand listty, ZPRRegOp zprty> {
7322  def NAME : sve_mem_cld_si_base<dtype, nf, asm, listty>;
7323
7324  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7325                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7326  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7327                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
7328  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7329                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7330}
7331
7332multiclass sve_mem_cld_si<bits<4> dtype, string asm, RegisterOperand listty,
7333                          ZPRRegOp zprty>
7334: sve_mem_cld_si_base<dtype, 0, asm, listty, zprty>;
7335
7336multiclass sve_mem_cldnf_si<bits<4> dtype, string asm, RegisterOperand listty,
7337                            ZPRRegOp zprty>
7338: sve_mem_cld_si_base<dtype, 1, asm, listty, zprty>;
7339
7340class sve_mem_cldnt_si_base<bits<2> msz, string asm, RegisterOperand VecList>
7341: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
7342  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7343  "",
7344  []>, Sched<[]> {
7345  bits<5> Zt;
7346  bits<3> Pg;
7347  bits<5> Rn;
7348  bits<4> imm4;
7349  let Inst{31-25} = 0b1010010;
7350  let Inst{24-23} = msz;
7351  let Inst{22-20} = 0b000;
7352  let Inst{19-16} = imm4;
7353  let Inst{15-13} = 0b111;
7354  let Inst{12-10} = Pg;
7355  let Inst{9-5}   = Rn;
7356  let Inst{4-0}   = Zt;
7357
7358  let hasSideEffects = 0;
7359  let mayLoad = 1;
7360}
7361
7362multiclass sve_mem_cldnt_si<bits<2> msz, string asm, RegisterOperand listty,
7363                            ZPRRegOp zprty> {
7364  def NAME : sve_mem_cldnt_si_base<msz, asm, listty>;
7365
7366  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7367                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7368  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7369                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
7370  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7371                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7372}
7373
7374class sve_mem_cldnt_ss_base<bits<2> msz, string asm, RegisterOperand VecList,
7375                            RegisterOperand gprty>
7376: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7377  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7378  "",
7379  []>, Sched<[]> {
7380  bits<3> Pg;
7381  bits<5> Rm;
7382  bits<5> Rn;
7383  bits<5> Zt;
7384  let Inst{31-25} = 0b1010010;
7385  let Inst{24-23} = msz;
7386  let Inst{22-21} = 0b00;
7387  let Inst{20-16} = Rm;
7388  let Inst{15-13} = 0b110;
7389  let Inst{12-10} = Pg;
7390  let Inst{9-5}   = Rn;
7391  let Inst{4-0}   = Zt;
7392
7393  let hasSideEffects = 0;
7394  let mayLoad = 1;
7395}
7396
7397multiclass sve_mem_cldnt_ss<bits<2> msz, string asm, RegisterOperand listty,
7398                            ZPRRegOp zprty, RegisterOperand gprty> {
7399  def NAME : sve_mem_cldnt_ss_base<msz, asm, listty, gprty>;
7400
7401  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7402                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7403}
7404
7405class sve_mem_ldqr_si<bits<2> sz, string asm, RegisterOperand VecList>
7406: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4),
7407  asm, "\t$Zt, $Pg/z, [$Rn, $imm4]", "", []>, Sched<[]> {
7408  bits<5> Zt;
7409  bits<5> Rn;
7410  bits<3> Pg;
7411  bits<4> imm4;
7412  let Inst{31-25} = 0b1010010;
7413  let Inst{24-23} = sz;
7414  let Inst{22-20} = 0;
7415  let Inst{19-16} = imm4;
7416  let Inst{15-13} = 0b001;
7417  let Inst{12-10} = Pg;
7418  let Inst{9-5}   = Rn;
7419  let Inst{4-0}   = Zt;
7420
7421  let hasSideEffects = 0;
7422  let mayLoad = 1;
7423}
7424
7425multiclass sve_mem_ldqr_si<bits<2> sz, string asm, RegisterOperand listty,
7426                           ZPRRegOp zprty> {
7427  def NAME : sve_mem_ldqr_si<sz, asm, listty>;
7428  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7429                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7430  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7431                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7432  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4]",
7433                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4), 0>;
7434}
7435
7436class sve_mem_ldqr_ss<bits<2> sz, string asm, RegisterOperand VecList,
7437                      RegisterOperand gprty>
7438: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7439  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]", "", []>, Sched<[]> {
7440  bits<5> Zt;
7441  bits<3> Pg;
7442  bits<5> Rn;
7443  bits<5> Rm;
7444  let Inst{31-25} = 0b1010010;
7445  let Inst{24-23} = sz;
7446  let Inst{22-21} = 0;
7447  let Inst{20-16} = Rm;
7448  let Inst{15-13} = 0;
7449  let Inst{12-10} = Pg;
7450  let Inst{9-5}   = Rn;
7451  let Inst{4-0}   = Zt;
7452
7453  let hasSideEffects = 0;
7454  let mayLoad = 1;
7455}
7456
7457multiclass sve_mem_ldqr_ss<bits<2> sz, string asm, RegisterOperand listty,
7458                           ZPRRegOp zprty, RegisterOperand gprty> {
7459  def NAME : sve_mem_ldqr_ss<sz, asm, listty, gprty>;
7460
7461  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7462                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7463}
7464
7465class sve_mem_ld_dup<bits<2> dtypeh, bits<2> dtypel, string asm,
7466                     RegisterOperand VecList, Operand immtype>
7467: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm6),
7468  asm, "\t$Zt, $Pg/z, [$Rn, $imm6]",
7469  "",
7470  []>, Sched<[]> {
7471  bits<3> Pg;
7472  bits<5> Rn;
7473  bits<5> Zt;
7474  bits<6> imm6;
7475  let Inst{31-25} = 0b1000010;
7476  let Inst{24-23} = dtypeh;
7477  let Inst{22}    = 1;
7478  let Inst{21-16} = imm6;
7479  let Inst{15}    = 0b1;
7480  let Inst{14-13} = dtypel;
7481  let Inst{12-10} = Pg;
7482  let Inst{9-5}   = Rn;
7483  let Inst{4-0}   = Zt;
7484
7485  let hasSideEffects = 0;
7486  let mayLoad = 1;
7487}
7488
7489multiclass sve_mem_ld_dup<bits<2> dtypeh, bits<2> dtypel, string asm,
7490                          RegisterOperand zlistty, ZPRRegOp zprty, Operand immtype> {
7491  def NAME : sve_mem_ld_dup<dtypeh, dtypel, asm, zlistty, immtype>;
7492
7493  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7494                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7495  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm6]",
7496                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm6), 0>;
7497  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7498                  (!cast<Instruction>(NAME) zlistty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7499}
7500
7501class sve_mem_cld_ss_base<bits<4> dtype, bit ff, dag iops, string asm,
7502                          RegisterOperand VecList>
7503: I<(outs VecList:$Zt), iops,
7504  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7505  "",
7506  []>, Sched<[]> {
7507  bits<5> Zt;
7508  bits<3> Pg;
7509  bits<5> Rm;
7510  bits<5> Rn;
7511  let Inst{31-25} = 0b1010010;
7512  let Inst{24-21} = dtype;
7513  let Inst{20-16} = Rm;
7514  let Inst{15-14} = 0b01;
7515  let Inst{13}    = ff;
7516  let Inst{12-10} = Pg;
7517  let Inst{9-5}   = Rn;
7518  let Inst{4-0}   = Zt;
7519
7520  let Defs = !if(ff, [FFR], []);
7521  let Uses = !if(ff, [FFR], []);
7522  let hasSideEffects = ff;
7523  let mayLoad = 1;
7524}
7525
7526multiclass sve_mem_cld_ss<bits<4> dtype, string asm, RegisterOperand listty,
7527                          ZPRRegOp zprty, RegisterOperand gprty> {
7528  def NAME : sve_mem_cld_ss_base<dtype, 0, (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7529                               asm, listty>;
7530
7531  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7532                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7533}
7534
7535multiclass sve_mem_cldff_ss<bits<4> dtype, string asm, RegisterOperand listty,
7536                            ZPRRegOp zprty, RegisterOperand gprty> {
7537  def NAME : sve_mem_cld_ss_base<dtype, 1, (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), asm, listty>;
7538
7539  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7540                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7541
7542  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7543                 (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 1>;
7544
7545  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7546                 (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 0>;
7547}
7548
7549class sve_mem_eld_si<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7550                     string asm, Operand immtype>
7551: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
7552  asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7553  "",
7554  []>, Sched<[]> {
7555  bits<5> Zt;
7556  bits<3> Pg;
7557  bits<5> Rn;
7558  bits<4> imm4;
7559  let Inst{31-25} = 0b1010010;
7560  let Inst{24-23} = sz;
7561  let Inst{22-21} = nregs{1-0};
7562  let Inst{20}    = nregs{2};
7563  let Inst{19-16} = imm4;
7564  let Inst{15-13} = 0b111;
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
7573multiclass sve_mem_eld_si<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7574                          string asm, Operand immtype> {
7575  def NAME : sve_mem_eld_si<sz, nregs, VecList, asm, immtype>;
7576
7577  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7578                  (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7579}
7580
7581
7582class sve_mem_eld_ss<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7583                     string asm, RegisterOperand gprty>
7584: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7585  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7586  "",
7587  []>, Sched<[]> {
7588  bits<3> Pg;
7589  bits<5> Rm;
7590  bits<5> Rn;
7591  bits<5> Zt;
7592  let Inst{31-25} = 0b1010010;
7593  let Inst{24-23} = sz;
7594  let Inst{22-21} = nregs{1-0};
7595  let Inst{20-16} = Rm;
7596  let Inst{15}    = 0b1;
7597  let Inst{14}    = nregs{2};
7598  let Inst{13}    = 0b0;
7599  let Inst{12-10} = Pg;
7600  let Inst{9-5}   = Rn;
7601  let Inst{4-0}   = Zt;
7602
7603  let hasSideEffects = 0;
7604  let mayLoad = 1;
7605}
7606
7607//===----------------------------------------------------------------------===//
7608// SVE Memory - 32-bit Gather and Unsized Contiguous Group
7609//===----------------------------------------------------------------------===//
7610
7611// bit xs      is '1' if offsets are signed
7612// bit scaled  is '1' if the offsets are scaled
7613class sve_mem_32b_gld_sv<bits<4> opc, bit xs, bit scaled, string asm,
7614                         RegisterOperand zprext>
7615: I<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
7616  asm, "\t$Zt, $Pg/z, [$Rn, $Zm]",
7617  "",
7618  []>, Sched<[]> {
7619  bits<3> Pg;
7620  bits<5> Rn;
7621  bits<5> Zm;
7622  bits<5> Zt;
7623  let Inst{31-25} = 0b1000010;
7624  let Inst{24-23} = opc{3-2};
7625  let Inst{22}    = xs;
7626  let Inst{21}    = scaled;
7627  let Inst{20-16} = Zm;
7628  let Inst{15}    = 0b0;
7629  let Inst{14-13} = opc{1-0};
7630  let Inst{12-10} = Pg;
7631  let Inst{9-5}   = Rn;
7632  let Inst{4-0}   = Zt;
7633
7634
7635  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
7636  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
7637  let hasSideEffects = opc{0};
7638  let mayLoad = 1;
7639}
7640
7641multiclass sve_mem_32b_gld_sv_32_scaled<bits<4> opc, string asm,
7642                                        SDPatternOperator sxtw_op,
7643                                        SDPatternOperator uxtw_op,
7644                                        RegisterOperand sxtw_opnd,
7645                                        RegisterOperand uxtw_opnd,
7646                                        ValueType vt> {
7647  def _UXTW_SCALED : sve_mem_32b_gld_sv<opc, 0, 1, asm, uxtw_opnd>;
7648  def _SXTW_SCALED : sve_mem_32b_gld_sv<opc, 1, 1, asm, sxtw_opnd>;
7649
7650  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7651                  (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
7652  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7653                  (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
7654
7655  def : Pat<(nxv4i32 (uxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$indices), vt)),
7656            (!cast<Instruction>(NAME # _UXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
7657  def : Pat<(nxv4i32 (sxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$indices), vt)),
7658            (!cast<Instruction>(NAME # _SXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
7659}
7660
7661multiclass sve_mem_32b_gld_vs_32_unscaled<bits<4> opc, string asm,
7662                                          SDPatternOperator sxtw_op,
7663                                          SDPatternOperator uxtw_op,
7664                                          RegisterOperand sxtw_opnd,
7665                                          RegisterOperand uxtw_opnd,
7666                                          ValueType vt> {
7667  def _UXTW : sve_mem_32b_gld_sv<opc, 0, 0, asm, uxtw_opnd>;
7668  def _SXTW : sve_mem_32b_gld_sv<opc, 1, 0, asm, sxtw_opnd>;
7669
7670  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7671                  (!cast<Instruction>(NAME # _UXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
7672  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7673                  (!cast<Instruction>(NAME # _SXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
7674
7675  def : Pat<(nxv4i32 (uxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt)),
7676            (!cast<Instruction>(NAME # _UXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
7677  def : Pat<(nxv4i32 (sxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt)),
7678            (!cast<Instruction>(NAME # _SXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
7679}
7680
7681
7682class sve_mem_32b_gld_vi<bits<4> opc, string asm, Operand imm_ty>
7683: I<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5),
7684  asm, "\t$Zt, $Pg/z, [$Zn, $imm5]",
7685  "",
7686  []>, Sched<[]> {
7687  bits<3> Pg;
7688  bits<5> Zn;
7689  bits<5> Zt;
7690  bits<5> imm5;
7691  let Inst{31-25} = 0b1000010;
7692  let Inst{24-23} = opc{3-2};
7693  let Inst{22-21} = 0b01;
7694  let Inst{20-16} = imm5;
7695  let Inst{15}    = 0b1;
7696  let Inst{14-13} = opc{1-0};
7697  let Inst{12-10} = Pg;
7698  let Inst{9-5}   = Zn;
7699  let Inst{4-0}   = Zt;
7700
7701
7702  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
7703  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
7704  let hasSideEffects = opc{0};
7705  let mayLoad = 1;
7706}
7707
7708multiclass sve_mem_32b_gld_vi_32_ptrs<bits<4> opc, string asm, Operand imm_ty,
7709                                      SDPatternOperator op, ValueType vt> {
7710  def _IMM : sve_mem_32b_gld_vi<opc, asm, imm_ty>;
7711
7712  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7713                  (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 0>;
7714  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $imm5]",
7715                  (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), 0>;
7716  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7717                  (!cast<Instruction>(NAME # _IMM) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
7718
7719  def : Pat<(nxv4i32 (op (nxv4i1 PPR:$gp), (nxv4i32 ZPR:$ptrs), imm_ty:$index, vt)),
7720            (!cast<Instruction>(NAME # _IMM) PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
7721}
7722
7723class sve_mem_prfm_si<bits<2> msz, string asm>
7724: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, simm6s1:$imm6),
7725  asm, "\t$prfop, $Pg, [$Rn, $imm6, mul vl]",
7726  "",
7727  []>, Sched<[]> {
7728  bits<5> Rn;
7729  bits<3> Pg;
7730  bits<6> imm6;
7731  bits<4> prfop;
7732  let Inst{31-22} = 0b1000010111;
7733  let Inst{21-16} = imm6;
7734  let Inst{15}    = 0b0;
7735  let Inst{14-13} = msz;
7736  let Inst{12-10} = Pg;
7737  let Inst{9-5}   = Rn;
7738  let Inst{4}     = 0b0;
7739  let Inst{3-0}   = prfop;
7740
7741  let hasSideEffects = 1;
7742}
7743
7744multiclass sve_mem_prfm_si<bits<2> msz, string asm> {
7745  def NAME : sve_mem_prfm_si<msz, asm>;
7746
7747  def : InstAlias<asm # "\t$prfop, $Pg, [$Rn]",
7748                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7749}
7750
7751class sve_mem_prfm_ss<bits<3> opc, string asm, RegisterOperand gprty>
7752: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7753  asm, "\t$prfop, $Pg, [$Rn, $Rm]",
7754  "",
7755  []>, Sched<[]> {
7756  bits<5> Rm;
7757  bits<5> Rn;
7758  bits<3> Pg;
7759  bits<4> prfop;
7760  let Inst{31-25} = 0b1000010;
7761  let Inst{24-23} = opc{2-1};
7762  let Inst{22-21} = 0b00;
7763  let Inst{20-16} = Rm;
7764  let Inst{15}    = 0b1;
7765  let Inst{14}    = opc{0};
7766  let Inst{13}    = 0b0;
7767  let Inst{12-10} = Pg;
7768  let Inst{9-5}   = Rn;
7769  let Inst{4}     = 0b0;
7770  let Inst{3-0}   = prfop;
7771
7772  let hasSideEffects = 1;
7773}
7774
7775class sve_mem_32b_prfm_sv<bits<2> msz, bit xs, string asm,
7776                          RegisterOperand zprext>
7777: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
7778  asm, "\t$prfop, $Pg, [$Rn, $Zm]",
7779  "",
7780  []>, Sched<[]> {
7781  bits<3> Pg;
7782  bits<5> Rn;
7783  bits<5> Zm;
7784  bits<4> prfop;
7785  let Inst{31-23} = 0b100001000;
7786  let Inst{22}    = xs;
7787  let Inst{21}    = 0b1;
7788  let Inst{20-16} = Zm;
7789  let Inst{15}    = 0b0;
7790  let Inst{14-13} = msz;
7791  let Inst{12-10} = Pg;
7792  let Inst{9-5}   = Rn;
7793  let Inst{4}     = 0b0;
7794  let Inst{3-0}   = prfop;
7795
7796  let hasSideEffects = 1;
7797}
7798
7799multiclass sve_mem_32b_prfm_sv_scaled<bits<2> msz, string asm,
7800                                      RegisterOperand sxtw_opnd,
7801                                      RegisterOperand uxtw_opnd,
7802                                      SDPatternOperator op_sxtw,
7803                                      SDPatternOperator op_uxtw> {
7804  def _UXTW_SCALED : sve_mem_32b_prfm_sv<msz, 0, asm, uxtw_opnd>;
7805  def _SXTW_SCALED : sve_mem_32b_prfm_sv<msz, 1, asm, sxtw_opnd>;
7806
7807  def : Pat<(op_uxtw (nxv4i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv4i32 uxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
7808            (!cast<Instruction>(NAME # _UXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
7809
7810  def : Pat<(op_sxtw (nxv4i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv4i32 sxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
7811            (!cast<Instruction>(NAME # _SXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
7812}
7813
7814class sve_mem_32b_prfm_vi<bits<2> msz, string asm, Operand imm_ty>
7815: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5),
7816  asm, "\t$prfop, $Pg, [$Zn, $imm5]",
7817  "",
7818  []>, Sched<[]> {
7819  bits<3> Pg;
7820  bits<5> Zn;
7821  bits<5> imm5;
7822  bits<4> prfop;
7823  let Inst{31-25} = 0b1000010;
7824  let Inst{24-23} = msz;
7825  let Inst{22-21} = 0b00;
7826  let Inst{20-16} = imm5;
7827  let Inst{15-13} = 0b111;
7828  let Inst{12-10} = Pg;
7829  let Inst{9-5}   = Zn;
7830  let Inst{4}     = 0b0;
7831  let Inst{3-0}   = prfop;
7832
7833  let hasSideEffects = 1;
7834}
7835
7836multiclass sve_mem_32b_prfm_vi<bits<2> msz, string asm, Operand imm_ty, SDPatternOperator op> {
7837  def NAME : sve_mem_32b_prfm_vi<msz, asm, imm_ty>;
7838
7839  def : InstAlias<asm # "\t$prfop, $Pg, [$Zn]",
7840                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
7841
7842  def : Pat<(op (nxv4i1 PPR_3b:$Pg), (nxv4i32 ZPR32:$Zn), (i64 imm_ty:$imm), (i32 sve_prfop:$prfop)),
7843            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR_3b:$Pg, ZPR32:$Zn, imm_ty:$imm)>;
7844}
7845
7846class sve_mem_z_fill<string asm>
7847: I<(outs ZPRAny:$Zt), (ins GPR64sp:$Rn, simm9:$imm9),
7848  asm, "\t$Zt, [$Rn, $imm9, mul vl]",
7849  "",
7850  []>, Sched<[]> {
7851  bits<5> Rn;
7852  bits<5> Zt;
7853  bits<9> imm9;
7854  let Inst{31-22} = 0b1000010110;
7855  let Inst{21-16} = imm9{8-3};
7856  let Inst{15-13} = 0b010;
7857  let Inst{12-10} = imm9{2-0};
7858  let Inst{9-5}   = Rn;
7859  let Inst{4-0}   = Zt;
7860
7861  let hasSideEffects = 0;
7862  let mayLoad = 1;
7863}
7864
7865multiclass sve_mem_z_fill<string asm> {
7866  def NAME : sve_mem_z_fill<asm>;
7867
7868  def : InstAlias<asm # "\t$Zt, [$Rn]",
7869                  (!cast<Instruction>(NAME) ZPRAny:$Zt, GPR64sp:$Rn, 0), 1>;
7870}
7871
7872class sve_mem_p_fill<string asm>
7873: I<(outs PPRorPNRAny:$Pt), (ins GPR64sp:$Rn, simm9:$imm9),
7874  asm, "\t$Pt, [$Rn, $imm9, mul vl]",
7875  "",
7876  []>, Sched<[]> {
7877  bits<4> Pt;
7878  bits<5> Rn;
7879  bits<9> imm9;
7880  let Inst{31-22} = 0b1000010110;
7881  let Inst{21-16} = imm9{8-3};
7882  let Inst{15-13} = 0b000;
7883  let Inst{12-10} = imm9{2-0};
7884  let Inst{9-5}   = Rn;
7885  let Inst{4}     = 0b0;
7886  let Inst{3-0}   = Pt;
7887
7888  let hasSideEffects = 0;
7889  let mayLoad = 1;
7890}
7891
7892multiclass sve_mem_p_fill<string asm> {
7893  def NAME : sve_mem_p_fill<asm>;
7894
7895  def : InstAlias<asm # "\t$Pt, [$Rn]",
7896                  (!cast<Instruction>(NAME) PPRorPNRAny:$Pt, GPR64sp:$Rn, 0), 1>;
7897}
7898
7899class sve2_mem_gldnt_vs_base<bits<5> opc, dag iops, string asm,
7900                             RegisterOperand VecList>
7901: I<(outs VecList:$Zt), iops,
7902  asm, "\t$Zt, $Pg/z, [$Zn, $Rm]",
7903  "",
7904  []>, Sched<[]> {
7905  bits<3> Pg;
7906  bits<5> Rm;
7907  bits<5> Zn;
7908  bits<5> Zt;
7909  let Inst{31}    = 0b1;
7910  let Inst{30}    = opc{4};
7911  let Inst{29-25} = 0b00010;
7912  let Inst{24-23} = opc{3-2};
7913  let Inst{22-21} = 0b00;
7914  let Inst{20-16} = Rm;
7915  let Inst{15}    = 0b1;
7916  let Inst{14-13} = opc{1-0};
7917  let Inst{12-10} = Pg;
7918  let Inst{9-5}   = Zn;
7919  let Inst{4-0}   = Zt;
7920
7921  let hasSideEffects = 0;
7922  let mayLoad = 1;
7923}
7924
7925multiclass sve2_mem_gldnt_vs_32_ptrs<bits<5> opc, string asm,
7926                                  SDPatternOperator op,
7927                                  ValueType vt> {
7928  def NAME : sve2_mem_gldnt_vs_base<opc, (ins PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm), asm, Z_s>;
7929
7930  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $Rm]",
7931                 (!cast<Instruction>(NAME) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm), 0>;
7932  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7933                 (!cast<Instruction>(NAME) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 0>;
7934  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7935                 (!cast<Instruction>(NAME) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 1>;
7936
7937  def : Pat <(nxv4i32 (op (nxv4i1 PPR3bAny:$Pg), (nxv4i32 ZPR32:$Zd), (i64 GPR64:$Rm), vt)),
7938             (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR32:$Zd, GPR64:$Rm)>;
7939}
7940
7941multiclass sve2_mem_gldnt_vs_64_ptrs<bits<5> opc, string asm,
7942                                   SDPatternOperator op,
7943                                   ValueType vt> {
7944  def NAME : sve2_mem_gldnt_vs_base<opc, (ins PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm), asm, Z_d>;
7945
7946  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $Rm]",
7947                 (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm), 0>;
7948  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7949                 (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 0>;
7950  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7951                 (!cast<Instruction>(NAME) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
7952
7953  def : Pat <(nxv2i64 (op (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zd), (i64 GPR64:$Rm), vt)),
7954             (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zd, GPR64:$Rm)>;
7955}
7956
7957//===----------------------------------------------------------------------===//
7958// SVE Memory - 64-bit Gather Group
7959//===----------------------------------------------------------------------===//
7960
7961// bit xs      is '1' if offsets are signed
7962// bit scaled  is '1' if the offsets are scaled
7963// bit lsl     is '0' if the offsets are extended (uxtw/sxtw), '1' if shifted (lsl)
7964class sve_mem_64b_gld_sv<bits<4> opc, bit xs, bit scaled, bit lsl, string asm,
7965                         RegisterOperand zprext>
7966: I<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
7967  asm, "\t$Zt, $Pg/z, [$Rn, $Zm]",
7968  "",
7969  []>, Sched<[]> {
7970  bits<3> Pg;
7971  bits<5> Rn;
7972  bits<5> Zm;
7973  bits<5> Zt;
7974  let Inst{31-25} = 0b1100010;
7975  let Inst{24-23} = opc{3-2};
7976  let Inst{22}    = xs;
7977  let Inst{21}    = scaled;
7978  let Inst{20-16} = Zm;
7979  let Inst{15}    = lsl;
7980  let Inst{14-13} = opc{1-0};
7981  let Inst{12-10} = Pg;
7982  let Inst{9-5}   = Rn;
7983  let Inst{4-0}   = Zt;
7984
7985
7986  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
7987  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
7988  let hasSideEffects = opc{0};
7989  let mayLoad = 1;
7990}
7991
7992multiclass sve_mem_64b_gld_sv_32_scaled<bits<4> opc, string asm,
7993                                        SDPatternOperator sxtw_op,
7994                                        SDPatternOperator uxtw_op,
7995                                        RegisterOperand sxtw_opnd,
7996                                        RegisterOperand uxtw_opnd,
7997                                        ValueType vt> {
7998  def _UXTW_SCALED : sve_mem_64b_gld_sv<opc, 0, 1, 0, asm, uxtw_opnd>;
7999  def _SXTW_SCALED : sve_mem_64b_gld_sv<opc, 1, 1, 0, asm, sxtw_opnd>;
8000
8001  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8002                  (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
8003  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8004                  (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
8005
8006  def : Pat<(nxv2i64 (uxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8007            (!cast<Instruction>(NAME # _UXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8008  def : Pat<(nxv2i64 (sxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8009            (!cast<Instruction>(NAME # _SXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8010}
8011
8012multiclass sve_mem_64b_gld_vs_32_unscaled<bits<4> opc, string asm,
8013                                          SDPatternOperator sxtw_op,
8014                                          SDPatternOperator uxtw_op,
8015                                          RegisterOperand sxtw_opnd,
8016                                          RegisterOperand uxtw_opnd,
8017                                          ValueType vt> {
8018  def _UXTW : sve_mem_64b_gld_sv<opc, 0, 0, 0, asm, uxtw_opnd>;
8019  def _SXTW : sve_mem_64b_gld_sv<opc, 1, 0, 0, asm, sxtw_opnd>;
8020
8021  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8022                  (!cast<Instruction>(NAME # _UXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
8023  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8024                  (!cast<Instruction>(NAME # _SXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
8025
8026  def : Pat<(nxv2i64 (uxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8027            (!cast<Instruction>(NAME # _UXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8028  def : Pat<(nxv2i64 (sxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8029            (!cast<Instruction>(NAME # _SXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8030}
8031
8032multiclass sve_mem_64b_gld_sv2_64_scaled<bits<4> opc, string asm,
8033                                         SDPatternOperator op,
8034                                         RegisterOperand zprext, ValueType vt> {
8035  def _SCALED : sve_mem_64b_gld_sv<opc, 1, 1, 1, asm, zprext>;
8036
8037  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8038                  (!cast<Instruction>(NAME # _SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), 0>;
8039
8040  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8041                     (!cast<Instruction>(NAME # _SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8042}
8043
8044multiclass sve_mem_64b_gld_vs2_64_unscaled<bits<4> opc, string asm,
8045                                           SDPatternOperator op, ValueType vt> {
8046  def NAME : sve_mem_64b_gld_sv<opc, 1, 0, 1, asm, ZPR64ExtLSL8>;
8047
8048  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8049                  (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), 0>;
8050
8051  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8052            (!cast<Instruction>(NAME) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8053}
8054
8055class sve_mem_64b_gld_vi<bits<4> opc, string asm, Operand imm_ty>
8056: I<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5),
8057  asm, "\t$Zt, $Pg/z, [$Zn, $imm5]",
8058  "",
8059  []>, Sched<[]> {
8060  bits<3> Pg;
8061  bits<5> Zn;
8062  bits<5> Zt;
8063  bits<5> imm5;
8064  let Inst{31-25} = 0b1100010;
8065  let Inst{24-23} = opc{3-2};
8066  let Inst{22-21} = 0b01;
8067  let Inst{20-16} = imm5;
8068  let Inst{15}    = 0b1;
8069  let Inst{14-13} = opc{1-0};
8070  let Inst{12-10} = Pg;
8071  let Inst{9-5}   = Zn;
8072  let Inst{4-0}   = Zt;
8073
8074  let Defs = !if(!eq(opc{0}, 1), [FFR], []);
8075  let Uses = !if(!eq(opc{0}, 1), [FFR], []);
8076  let hasSideEffects = opc{0};
8077  let mayLoad = 1;
8078}
8079
8080multiclass sve_mem_64b_gld_vi_64_ptrs<bits<4> opc, string asm, Operand imm_ty,
8081                                      SDPatternOperator op, ValueType vt> {
8082  def _IMM : sve_mem_64b_gld_vi<opc, asm, imm_ty>;
8083
8084  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8085                  (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 0>;
8086  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $imm5]",
8087                  (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), 0>;
8088  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8089                  (!cast<Instruction>(NAME # _IMM) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
8090
8091  def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), (nxv2i64 ZPR:$ptrs), imm_ty:$index, vt)),
8092            (!cast<Instruction>(NAME # _IMM) PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
8093}
8094
8095// bit lsl is '0' if the offsets are extended (uxtw/sxtw), '1' if shifted (lsl)
8096class sve_mem_64b_prfm_sv<bits<2> msz, bit xs, bit lsl, string asm,
8097                          RegisterOperand zprext>
8098: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
8099  asm, "\t$prfop, $Pg, [$Rn, $Zm]",
8100  "",
8101  []>, Sched<[]> {
8102  bits<3> Pg;
8103  bits<5> Rn;
8104  bits<5> Zm;
8105  bits<4> prfop;
8106  let Inst{31-23} = 0b110001000;
8107  let Inst{22}    = xs;
8108  let Inst{21}    = 0b1;
8109  let Inst{20-16} = Zm;
8110  let Inst{15}    = lsl;
8111  let Inst{14-13} = msz;
8112  let Inst{12-10} = Pg;
8113  let Inst{9-5}   = Rn;
8114  let Inst{4}     = 0b0;
8115  let Inst{3-0}   = prfop;
8116
8117  let hasSideEffects = 1;
8118}
8119
8120multiclass sve_mem_64b_prfm_sv_ext_scaled<bits<2> msz, string asm,
8121                                          RegisterOperand sxtw_opnd,
8122                                          RegisterOperand uxtw_opnd,
8123                                          SDPatternOperator op_sxtw,
8124                                          SDPatternOperator op_uxtw> {
8125  def _UXTW_SCALED : sve_mem_64b_prfm_sv<msz, 0, 0, asm, uxtw_opnd>;
8126  def _SXTW_SCALED : sve_mem_64b_prfm_sv<msz, 1, 0, asm, sxtw_opnd>;
8127
8128  def : Pat<(op_uxtw (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 uxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
8129            (!cast<Instruction>(NAME # _UXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8130
8131  def : Pat<(op_sxtw (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 sxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
8132            (!cast<Instruction>(NAME # _SXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8133
8134}
8135
8136multiclass sve_mem_64b_prfm_sv_lsl_scaled<bits<2> msz, string asm,
8137                                          RegisterOperand zprext, SDPatternOperator frag> {
8138  def NAME : sve_mem_64b_prfm_sv<msz, 1, 1, asm, zprext>;
8139
8140  def : Pat<(frag (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 zprext:$Zm), (i32 sve_prfop:$prfop)),
8141            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm)>;
8142
8143}
8144
8145class sve_mem_64b_prfm_vi<bits<2> msz, string asm, Operand imm_ty>
8146: I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5),
8147  asm, "\t$prfop, $Pg, [$Zn, $imm5]",
8148  "",
8149  []>, Sched<[]> {
8150  bits<3> Pg;
8151  bits<5> Zn;
8152  bits<5> imm5;
8153  bits<4> prfop;
8154  let Inst{31-25} = 0b1100010;
8155  let Inst{24-23} = msz;
8156  let Inst{22-21} = 0b00;
8157  let Inst{20-16} = imm5;
8158  let Inst{15-13} = 0b111;
8159  let Inst{12-10} = Pg;
8160  let Inst{9-5}   = Zn;
8161  let Inst{4}     = 0b0;
8162  let Inst{3-0}   = prfop;
8163
8164  let hasSideEffects = 1;
8165}
8166
8167multiclass sve_mem_64b_prfm_vi<bits<2> msz, string asm, Operand imm_ty, SDPatternOperator op> {
8168  def NAME : sve_mem_64b_prfm_vi<msz, asm, imm_ty>;
8169
8170  def : InstAlias<asm # "\t$prfop, $Pg, [$Zn]",
8171                  (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
8172
8173  def : Pat<(op (nxv2i1 PPR_3b:$Pg), (nxv2i64 ZPR32:$Zn), (i64 imm_ty:$imm), (i32 sve_prfop:$prfop)),
8174            (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR_3b:$Pg, ZPR32:$Zn, imm_ty:$imm)>;
8175}
8176
8177//===----------------------------------------------------------------------===//
8178// SVE Compute Vector Address Group
8179//===----------------------------------------------------------------------===//
8180
8181class sve_int_bin_cons_misc_0_a<bits<2> opc, bits<2> msz, string asm,
8182                                ZPRRegOp zprty, RegisterOperand zprext>
8183: I<(outs zprty:$Zd), (ins zprty:$Zn, zprext:$Zm),
8184  asm, "\t$Zd, [$Zn, $Zm]",
8185  "",
8186  []>, Sched<[]> {
8187  bits<5> Zd;
8188  bits<5> Zn;
8189  bits<5> Zm;
8190  let Inst{31-24} = 0b00000100;
8191  let Inst{23-22} = opc;
8192  let Inst{21}    = 0b1;
8193  let Inst{20-16} = Zm;
8194  let Inst{15-12} = 0b1010;
8195  let Inst{11-10} = msz;
8196  let Inst{9-5}   = Zn;
8197  let Inst{4-0}   = Zd;
8198
8199  let hasSideEffects = 0;
8200}
8201
8202multiclass sve_int_bin_cons_misc_0_a_uxtw<bits<2> opc, string asm> {
8203  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtUXTW8>;
8204  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtUXTW16>;
8205  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtUXTW32>;
8206  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtUXTW64>;
8207}
8208
8209multiclass sve_int_bin_cons_misc_0_a_sxtw<bits<2> opc, string asm> {
8210  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtSXTW8>;
8211  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtSXTW16>;
8212  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtSXTW32>;
8213  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtSXTW64>;
8214}
8215
8216multiclass sve_int_bin_cons_misc_0_a_32_lsl<bits<2> opc, string asm> {
8217  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR32, ZPR32ExtLSL8>;
8218  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR32, ZPR32ExtLSL16>;
8219  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR32, ZPR32ExtLSL32>;
8220  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR32, ZPR32ExtLSL64>;
8221}
8222
8223multiclass sve_int_bin_cons_misc_0_a_64_lsl<bits<2> opc, string asm> {
8224  def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtLSL8>;
8225  def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtLSL16>;
8226  def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtLSL32>;
8227  def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtLSL64>;
8228}
8229
8230//===----------------------------------------------------------------------===//
8231// SVE Integer Misc - Unpredicated Group
8232//===----------------------------------------------------------------------===//
8233
8234class sve_int_bin_cons_misc_0_b<bits<2> sz, string asm, ZPRRegOp zprty>
8235: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
8236  asm, "\t$Zd, $Zn, $Zm",
8237  "",
8238  []>, Sched<[]> {
8239  bits<5> Zd;
8240  bits<5> Zm;
8241  bits<5> Zn;
8242  let Inst{31-24} = 0b00000100;
8243  let Inst{23-22} = sz;
8244  let Inst{21}    = 0b1;
8245  let Inst{20-16} = Zm;
8246  let Inst{15-10} = 0b101100;
8247  let Inst{9-5}   = Zn;
8248  let Inst{4-0}   = Zd;
8249
8250  let hasSideEffects = 0;
8251}
8252
8253multiclass sve_int_bin_cons_misc_0_b<string asm, SDPatternOperator op> {
8254  def _H : sve_int_bin_cons_misc_0_b<0b01, asm, ZPR16>;
8255  def _S : sve_int_bin_cons_misc_0_b<0b10, asm, ZPR32>;
8256  def _D : sve_int_bin_cons_misc_0_b<0b11, asm, ZPR64>;
8257
8258  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
8259  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
8260  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
8261}
8262
8263class sve_int_bin_cons_misc_0_c<bits<8> opc, string asm, ZPRRegOp zprty>
8264: I<(outs zprty:$Zd), (ins zprty:$Zn),
8265  asm, "\t$Zd, $Zn",
8266  "",
8267  []>, Sched<[]> {
8268  bits<5> Zd;
8269  bits<5> Zn;
8270  let Inst{31-24} = 0b00000100;
8271  let Inst{23-22} = opc{7-6};
8272  let Inst{21}    = 0b1;
8273  let Inst{20-16} = opc{5-1};
8274  let Inst{15-11} = 0b10111;
8275  let Inst{10}    = opc{0};
8276  let Inst{9-5}   = Zn;
8277  let Inst{4-0}   = Zd;
8278
8279  let hasSideEffects = 0;
8280}
8281
8282multiclass sve_int_bin_cons_misc_0_c_fexpa<string asm, SDPatternOperator op> {
8283  def _H : sve_int_bin_cons_misc_0_c<0b01000000, asm, ZPR16>;
8284  def _S : sve_int_bin_cons_misc_0_c<0b10000000, asm, ZPR32>;
8285  def _D : sve_int_bin_cons_misc_0_c<0b11000000, asm, ZPR64>;
8286
8287  def : SVE_1_Op_Pat<nxv8f16, op, nxv8i16, !cast<Instruction>(NAME # _H)>;
8288  def : SVE_1_Op_Pat<nxv4f32, op, nxv4i32, !cast<Instruction>(NAME # _S)>;
8289  def : SVE_1_Op_Pat<nxv2f64, op, nxv2i64, !cast<Instruction>(NAME # _D)>;
8290}
8291
8292//===----------------------------------------------------------------------===//
8293// SVE Integer Reduction Group
8294//===----------------------------------------------------------------------===//
8295
8296class sve_int_reduce<bits<2> sz8_32, bits<2> fmt, bits<3> opc, string asm,
8297                     ZPRRegOp zprty, FPRasZPROperand dstOpType>
8298: I<(outs dstOpType:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
8299  asm, "\t$Vd, $Pg, $Zn",
8300  "",
8301  []>, Sched<[]> {
8302  bits<3> Pg;
8303  bits<5> Vd;
8304  bits<5> Zn;
8305  let Inst{31-24} = 0b00000100;
8306  let Inst{23-22} = sz8_32;
8307  let Inst{21}    = 0b0;
8308  let Inst{20-19} = fmt;
8309  let Inst{18-16} = opc;
8310  let Inst{15-13} = 0b001;
8311  let Inst{12-10} = Pg;
8312  let Inst{9-5}   = Zn;
8313  let Inst{4-0}   = Vd;
8314
8315  let hasSideEffects = 0;
8316}
8317
8318multiclass sve_int_reduce_0_saddv<bits<3> opc, string asm,
8319                                  SDPatternOperator op> {
8320  def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
8321  def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
8322  def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
8323
8324  def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8325  def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8326  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8327}
8328
8329multiclass sve_int_reduce_0_uaddv<bits<3> opc, string asm,
8330                                  SDPatternOperator op> {
8331  def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
8332  def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
8333  def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
8334  def _D : sve_int_reduce<0b11, 0b00, opc, asm, ZPR64, FPR64asZPR>;
8335
8336  def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8337  def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8338  def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8339  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8340}
8341
8342multiclass sve_int_reduce_1<bits<3> opc, string asm,
8343                            SDPatternOperator op> {
8344  def _B : sve_int_reduce<0b00, 0b01, opc, asm, ZPR8, FPR8asZPR>;
8345  def _H : sve_int_reduce<0b01, 0b01, opc, asm, ZPR16, FPR16asZPR>;
8346  def _S : sve_int_reduce<0b10, 0b01, opc, asm, ZPR32, FPR32asZPR>;
8347  def _D : sve_int_reduce<0b11, 0b01, opc, asm, ZPR64, FPR64asZPR>;
8348
8349  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8350  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8351  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8352  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8353}
8354
8355multiclass sve_int_reduce_2<bits<3> opc, string asm,
8356                            SDPatternOperator op> {
8357  def _B : sve_int_reduce<0b00, 0b11, opc, asm, ZPR8, FPR8asZPR>;
8358  def _H : sve_int_reduce<0b01, 0b11, opc, asm, ZPR16, FPR16asZPR>;
8359  def _S : sve_int_reduce<0b10, 0b11, opc, asm, ZPR32, FPR32asZPR>;
8360  def _D : sve_int_reduce<0b11, 0b11, opc, asm, ZPR64, FPR64asZPR>;
8361
8362  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8363  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8364  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8365  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8366}
8367
8368class sve_int_movprfx_pred<bits<2> sz8_32, bits<3> opc, string asm,
8369                           ZPRRegOp zprty, string pg_suffix, dag iops>
8370: I<(outs zprty:$Zd), iops,
8371  asm, "\t$Zd, $Pg"#pg_suffix#", $Zn",
8372  "",
8373  []>, Sched<[]> {
8374  bits<3> Pg;
8375  bits<5> Zd;
8376  bits<5> Zn;
8377  let Inst{31-24} = 0b00000100;
8378  let Inst{23-22} = sz8_32;
8379  let Inst{21-19} = 0b010;
8380  let Inst{18-16} = opc;
8381  let Inst{15-13} = 0b001;
8382  let Inst{12-10} = Pg;
8383  let Inst{9-5}   = Zn;
8384  let Inst{4-0}   = Zd;
8385
8386  let ElementSize = zprty.ElementSize;
8387  let hasSideEffects = 0;
8388}
8389
8390multiclass sve_int_movprfx_pred_merge<bits<3> opc, string asm> {
8391let Constraints = "$Zd = $_Zd" in {
8392  def _B : sve_int_movprfx_pred<0b00, opc, asm, ZPR8, "/m",
8393                                (ins ZPR8:$_Zd, PPR3bAny:$Pg, ZPR8:$Zn)>;
8394  def _H : sve_int_movprfx_pred<0b01, opc, asm, ZPR16, "/m",
8395                                (ins ZPR16:$_Zd, PPR3bAny:$Pg, ZPR16:$Zn)>;
8396  def _S : sve_int_movprfx_pred<0b10, opc, asm, ZPR32, "/m",
8397                                (ins ZPR32:$_Zd, PPR3bAny:$Pg, ZPR32:$Zn)>;
8398  def _D : sve_int_movprfx_pred<0b11, opc, asm, ZPR64, "/m",
8399                                (ins ZPR64:$_Zd, PPR3bAny:$Pg, ZPR64:$Zn)>;
8400}
8401}
8402
8403multiclass sve_int_movprfx_pred_zero<bits<3> opc, string asm> {
8404  def _B : sve_int_movprfx_pred<0b00, opc, asm, ZPR8, "/z",
8405                                (ins PPR3bAny:$Pg, ZPR8:$Zn)>;
8406  def _H : sve_int_movprfx_pred<0b01, opc, asm, ZPR16, "/z",
8407                                (ins PPR3bAny:$Pg, ZPR16:$Zn)>;
8408  def _S : sve_int_movprfx_pred<0b10, opc, asm, ZPR32, "/z",
8409                                (ins PPR3bAny:$Pg, ZPR32:$Zn)>;
8410  def _D : sve_int_movprfx_pred<0b11, opc, asm, ZPR64, "/z",
8411                                (ins PPR3bAny:$Pg, ZPR64:$Zn)>;
8412}
8413
8414//===----------------------------------------------------------------------===//
8415// SVE Propagate Break Group
8416//===----------------------------------------------------------------------===//
8417
8418class sve_int_brkp<bits<2> opc, string asm>
8419: I<(outs PPR8:$Pd), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$Pm),
8420  asm, "\t$Pd, $Pg/z, $Pn, $Pm",
8421  "",
8422  []>, Sched<[]> {
8423  bits<4> Pd;
8424  bits<4> Pg;
8425  bits<4> Pm;
8426  bits<4> Pn;
8427  let Inst{31-24} = 0b00100101;
8428  let Inst{23}    = 0b0;
8429  let Inst{22}    = opc{1};
8430  let Inst{21-20} = 0b00;
8431  let Inst{19-16} = Pm;
8432  let Inst{15-14} = 0b11;
8433  let Inst{13-10} = Pg;
8434  let Inst{9}     = 0b0;
8435  let Inst{8-5}   = Pn;
8436  let Inst{4}     = opc{0};
8437  let Inst{3-0}   = Pd;
8438
8439  let Defs = !if(!eq (opc{1}, 1), [NZCV], []);
8440  let hasSideEffects = 0;
8441}
8442
8443multiclass sve_int_brkp<bits<2> opc, string asm, SDPatternOperator op> {
8444  def NAME : sve_int_brkp<opc, asm>;
8445
8446  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8447}
8448
8449
8450//===----------------------------------------------------------------------===//
8451// SVE Partition Break Group
8452//===----------------------------------------------------------------------===//
8453
8454class sve_int_brkn<bit S, string asm>
8455: I<(outs PPR8:$Pdm), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$_Pdm),
8456  asm, "\t$Pdm, $Pg/z, $Pn, $_Pdm",
8457  "",
8458  []>, Sched<[]> {
8459  bits<4> Pdm;
8460  bits<4> Pg;
8461  bits<4> Pn;
8462  let Inst{31-23} = 0b001001010;
8463  let Inst{22}    = S;
8464  let Inst{21-14} = 0b01100001;
8465  let Inst{13-10} = Pg;
8466  let Inst{9}     = 0b0;
8467  let Inst{8-5}   = Pn;
8468  let Inst{4}     = 0b0;
8469  let Inst{3-0}   = Pdm;
8470
8471  let Constraints = "$Pdm = $_Pdm";
8472  let Defs = !if(S, [NZCV], []);
8473  let ElementSize = ElementSizeB;
8474  let hasSideEffects = 0;
8475}
8476
8477multiclass sve_int_brkn<bits<1> opc, string asm, SDPatternOperator op> {
8478  def NAME : sve_int_brkn<opc, asm>;
8479
8480  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8481}
8482
8483class sve_int_break<bits<3> opc, string asm, string suffix, dag iops>
8484: I<(outs PPR8:$Pd), iops,
8485  asm, "\t$Pd, $Pg"#suffix#", $Pn",
8486  "",
8487  []>, Sched<[]> {
8488  bits<4> Pd;
8489  bits<4> Pg;
8490  bits<4> Pn;
8491  let Inst{31-24} = 0b00100101;
8492  let Inst{23-22} = opc{2-1};
8493  let Inst{21-14} = 0b01000001;
8494  let Inst{13-10} = Pg;
8495  let Inst{9}     = 0b0;
8496  let Inst{8-5}   = Pn;
8497  let Inst{4}     = opc{0};
8498  let Inst{3-0}   = Pd;
8499
8500  let Constraints = !if(!eq (opc{0}, 1), "$Pd = $_Pd", "");
8501  let Defs = !if(!eq (opc{1}, 1), [NZCV], []);
8502  let hasSideEffects = 0;
8503}
8504
8505multiclass sve_int_break_m<bits<3> opc, string asm, SDPatternOperator op> {
8506  def NAME : sve_int_break<opc, asm, "/m", (ins PPR8:$_Pd, PPRAny:$Pg, PPR8:$Pn)>;
8507
8508  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8509}
8510
8511multiclass sve_int_break_z<bits<3> opc, string asm, SDPatternOperator op> {
8512  def NAME : sve_int_break<opc, asm, "/z", (ins PPRAny:$Pg, PPR8:$Pn)>;
8513
8514  def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8515}
8516
8517//===----------------------------------------------------------------------===//
8518// SVE2 String Processing Group
8519//===----------------------------------------------------------------------===//
8520
8521class sve2_char_match<bit sz, bit opc, string asm,
8522                      PPRRegOp pprty, ZPRRegOp zprty>
8523: I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
8524  asm, "\t$Pd, $Pg/z, $Zn, $Zm",
8525  "",
8526  []>, Sched<[]> {
8527  bits<4> Pd;
8528  bits<3> Pg;
8529  bits<5> Zm;
8530  bits<5> Zn;
8531  let Inst{31-23} = 0b010001010;
8532  let Inst{22}    = sz;
8533  let Inst{21}    = 0b1;
8534  let Inst{20-16} = Zm;
8535  let Inst{15-13} = 0b100;
8536  let Inst{12-10} = Pg;
8537  let Inst{9-5}   = Zn;
8538  let Inst{4}     = opc;
8539  let Inst{3-0}   = Pd;
8540
8541  let Defs = [NZCV];
8542  let ElementSize = pprty.ElementSize;
8543  let hasSideEffects = 0;
8544  let isPTestLike = 1;
8545}
8546
8547multiclass sve2_char_match<bit opc, string asm, SDPatternOperator op> {
8548  def _B : sve2_char_match<0b0, opc, asm, PPR8, ZPR8>;
8549  def _H : sve2_char_match<0b1, opc, asm, PPR16, ZPR16>;
8550
8551  def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
8552  def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
8553}
8554
8555//===----------------------------------------------------------------------===//
8556// SVE2 Histogram Computation - Segment Group
8557//===----------------------------------------------------------------------===//
8558
8559class sve2_hist_gen_segment<string asm, SDPatternOperator op>
8560: I<(outs ZPR8:$Zd), (ins ZPR8:$Zn, ZPR8:$Zm),
8561  asm, "\t$Zd, $Zn, $Zm",
8562  "",
8563  [(set nxv16i8:$Zd, (op nxv16i8:$Zn, nxv16i8:$Zm))]>, Sched<[]> {
8564  bits<5> Zd;
8565  bits<5> Zn;
8566  bits<5> Zm;
8567  let Inst{31-21} = 0b01000101001;
8568  let Inst{20-16} = Zm;
8569  let Inst{15-10} = 0b101000;
8570  let Inst{9-5}   = Zn;
8571  let Inst{4-0}   = Zd;
8572
8573  let hasSideEffects = 0;
8574}
8575
8576//===----------------------------------------------------------------------===//
8577// SVE2 Histogram Computation - Vector Group
8578//===----------------------------------------------------------------------===//
8579
8580class sve2_hist_gen_vector<bit sz, string asm, ZPRRegOp zprty>
8581: I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
8582  asm, "\t$Zd, $Pg/z, $Zn, $Zm",
8583  "",
8584  []>, Sched<[]> {
8585  bits<5> Zd;
8586  bits<5> Zn;
8587  bits<3> Pg;
8588  bits<5> Zm;
8589  let Inst{31-23} = 0b010001011;
8590  let Inst{22}    = sz;
8591  let Inst{21}    = 0b1;
8592  let Inst{20-16} = Zm;
8593  let Inst{15-13} = 0b110;
8594  let Inst{12-10} = Pg;
8595  let Inst{9-5}   = Zn;
8596  let Inst{4-0}   = Zd;
8597
8598  let hasSideEffects = 0;
8599}
8600
8601multiclass sve2_hist_gen_vector<string asm, SDPatternOperator op> {
8602  def _S : sve2_hist_gen_vector<0b0, asm, ZPR32>;
8603  def _D : sve2_hist_gen_vector<0b1, asm, ZPR64>;
8604
8605  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
8606  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
8607}
8608
8609//===----------------------------------------------------------------------===//
8610// SVE2 Crypto Extensions Group
8611//===----------------------------------------------------------------------===//
8612
8613class sve2_crypto_cons_bin_op<bit opc, string asm, ZPRRegOp zprty>
8614: I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
8615  asm, "\t$Zd, $Zn, $Zm",
8616  "",
8617  []>, Sched<[]> {
8618  bits<5> Zd;
8619  bits<5> Zn;
8620  bits<5> Zm;
8621  let Inst{31-21} = 0b01000101001;
8622  let Inst{20-16} = Zm;
8623  let Inst{15-11} = 0b11110;
8624  let Inst{10}    = opc;
8625  let Inst{9-5}   = Zn;
8626  let Inst{4-0}   = Zd;
8627
8628  let hasSideEffects = 0;
8629}
8630
8631multiclass sve2_crypto_cons_bin_op<bit opc, string asm, ZPRRegOp zprty,
8632                                   SDPatternOperator op, ValueType vt> {
8633  def NAME : sve2_crypto_cons_bin_op<opc, asm, zprty>;
8634  def : SVE_2_Op_Pat<vt, op, vt, vt, !cast<Instruction>(NAME)>;
8635}
8636
8637class sve2_crypto_des_bin_op<bits<2> opc, string asm, ZPRRegOp zprty>
8638: I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm),
8639  asm, "\t$Zdn, $_Zdn, $Zm",
8640  "",
8641  []>, Sched<[]> {
8642  bits<5> Zdn;
8643  bits<5> Zm;
8644  let Inst{31-17} = 0b010001010010001;
8645  let Inst{16}    = opc{1};
8646  let Inst{15-11} = 0b11100;
8647  let Inst{10}    = opc{0};
8648  let Inst{9-5}   = Zm;
8649  let Inst{4-0}   = Zdn;
8650
8651  let Constraints = "$Zdn = $_Zdn";
8652  let hasSideEffects = 0;
8653}
8654
8655multiclass sve2_crypto_des_bin_op<bits<2> opc, string asm, ZPRRegOp zprty,
8656                                  SDPatternOperator op, ValueType vt> {
8657  def NAME : sve2_crypto_des_bin_op<opc, asm, zprty>;
8658  def : SVE_2_Op_Pat<vt, op, vt, vt, !cast<Instruction>(NAME)>;
8659}
8660
8661class sve2_crypto_unary_op<bit opc, string asm, ZPRRegOp zprty>
8662: I<(outs zprty:$Zdn), (ins zprty:$_Zdn),
8663  asm, "\t$Zdn, $_Zdn",
8664  "",
8665  []>, Sched<[]> {
8666  bits<5> Zdn;
8667  let Inst{31-11} = 0b010001010010000011100;
8668  let Inst{10}    = opc;
8669  let Inst{9-5}   = 0b00000;
8670  let Inst{4-0}   = Zdn;
8671
8672  let Constraints = "$Zdn = $_Zdn";
8673  let hasSideEffects = 0;
8674}
8675
8676multiclass sve2_crypto_unary_op<bit opc, string asm, SDPatternOperator op> {
8677  def NAME : sve2_crypto_unary_op<opc, asm, ZPR8>;
8678  def : SVE_1_Op_Pat<nxv16i8, op, nxv16i8, !cast<Instruction>(NAME)>;
8679}
8680
8681//===----------------------------------------------------------------------===//
8682// SVE BFloat16 Group
8683//===----------------------------------------------------------------------===//
8684
8685class sve_float_dot<bit bf, bit o2, ZPRRegOp dst_ty, ZPRRegOp src_ty, string asm>
8686: I<(outs dst_ty:$Zda), (ins dst_ty:$_Zda, src_ty:$Zn, src_ty:$Zm),
8687     asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8688  bits<5> Zda;
8689  bits<5> Zn;
8690  bits<5> Zm;
8691  let Inst{31-23} = 0b011001000;
8692  let Inst{22}    = bf;
8693  let Inst{21}    = 0b1;
8694  let Inst{20-16} = Zm;
8695  let Inst{15-11} = 0b10000;
8696  let Inst{10}    = o2;
8697  let Inst{9-5}   = Zn;
8698  let Inst{4-0}   = Zda;
8699
8700  let Constraints = "$Zda = $_Zda";
8701  let DestructiveInstType = DestructiveOther;
8702  let hasSideEffects = 0;
8703  let mayRaiseFPException = 1;
8704}
8705
8706multiclass sve_float_dot<bit bf, bit o2, ZPRRegOp dst_ty, ZPRRegOp src_ty,
8707                         string asm, ValueType InVT, SDPatternOperator op> {
8708  def NAME : sve_float_dot<bf, o2, dst_ty, src_ty, asm>;
8709  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, InVT, InVT, !cast<Instruction>(NAME)>;
8710}
8711
8712class sve_float_dot_indexed<bit bf, ZPRRegOp dst_ty, ZPRRegOp src1_ty,
8713                            ZPRRegOp src2_ty, Operand iop_ty, string asm>
8714: I<(outs dst_ty:$Zda), (ins dst_ty:$_Zda, src1_ty:$Zn, src2_ty:$Zm, iop_ty:$iop),
8715    asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
8716  bits<5> Zda;
8717  bits<5> Zn;
8718  bits<3> Zm;
8719  let Inst{31-23} = 0b011001000;
8720  let Inst{22}    = bf;
8721  let Inst{21}    = 0b1;
8722  let Inst{18-16} = Zm;
8723  let Inst{15-12} = 0b0100;
8724  let Inst{9-5}   = Zn;
8725  let Inst{4-0}   = Zda;
8726
8727  let Constraints = "$Zda = $_Zda";
8728  let DestructiveInstType = DestructiveOther;
8729  let hasSideEffects = 0;
8730  let mayRaiseFPException = 1;
8731}
8732
8733multiclass sve_float_dot_indexed<bit bf, bits<2> opc, ZPRRegOp src1_ty,
8734                                 ZPRRegOp src2_ty, string asm, ValueType InVT,
8735                                 SDPatternOperator op> {
8736  def NAME : sve_float_dot_indexed<bf, ZPR32, src1_ty, src2_ty, VectorIndexS32b, asm> {
8737    bits<2> iop;
8738    let Inst{20-19} = iop;
8739    let Inst{11-10} = opc;
8740  }
8741  def : SVE_4_Op_Imm_Pat<nxv4f32, op, nxv4f32, InVT, InVT, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
8742}
8743
8744class sve_bfloat_matmul<string asm>
8745: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
8746  asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8747  bits<5> Zm;
8748  bits<5> Zda;
8749  bits<5> Zn;
8750  let Inst{31-21} = 0b01100100011;
8751  let Inst{20-16} = Zm;
8752  let Inst{15-10} = 0b111001;
8753  let Inst{9-5}   = Zn;
8754  let Inst{4-0}   = Zda;
8755
8756  let Constraints = "$Zda = $_Zda";
8757  let DestructiveInstType = DestructiveOther;
8758  let ElementSize = ElementSizeH;
8759  let hasSideEffects = 0;
8760  let mayRaiseFPException = 1;
8761}
8762
8763multiclass sve_bfloat_matmul<string asm, SDPatternOperator op> {
8764  def NAME : sve_bfloat_matmul<asm>;
8765  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv8bf16, nxv8bf16 ,!cast<Instruction>(NAME)>;
8766}
8767
8768class sve_bfloat_convert<bit N, string asm>
8769: I<(outs ZPR16:$Zd), (ins ZPR16:$_Zd, PPR3bAny:$Pg, ZPR32:$Zn),
8770  asm, "\t$Zd, $Pg/m, $Zn", "", []>, Sched<[]> {
8771  bits<5> Zd;
8772  bits<3> Pg;
8773  bits<5> Zn;
8774  let Inst{31-25} = 0b0110010;
8775  let Inst{24}    = N;
8776  let Inst{23-13} = 0b10001010101;
8777  let Inst{12-10} = Pg;
8778  let Inst{9-5}   = Zn;
8779  let Inst{4-0}   = Zd;
8780
8781  let Constraints = "$Zd = $_Zd";
8782  let DestructiveInstType = DestructiveOther;
8783  let ElementSize = ElementSizeS;
8784  let hasSideEffects = 0;
8785  let mayRaiseFPException = 1;
8786}
8787
8788multiclass sve_bfloat_convert<bit N, string asm, SDPatternOperator op> {
8789  def NAME : sve_bfloat_convert<N, asm>;
8790  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i1, nxv4f32, !cast<Instruction>(NAME)>;
8791}
8792
8793//===----------------------------------------------------------------------===//
8794// SVE Integer Matrix Multiply Group
8795//===----------------------------------------------------------------------===//
8796
8797class sve_int_matmul<bits<2> uns, string asm>
8798: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR8:$Zm), asm,
8799  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8800  bits<5> Zda;
8801  bits<5> Zn;
8802  bits<5> Zm;
8803  let Inst{31-24} = 0b01000101;
8804  let Inst{23-22} = uns;
8805  let Inst{21}    = 0;
8806  let Inst{20-16} = Zm;
8807  let Inst{15-10} = 0b100110;
8808  let Inst{9-5}   = Zn;
8809  let Inst{4-0}   = Zda;
8810
8811  let Constraints = "$Zda = $_Zda";
8812  let DestructiveInstType = DestructiveOther;
8813  let ElementSize = ZPR32.ElementSize;
8814  let hasSideEffects = 0;
8815}
8816
8817multiclass sve_int_matmul<bits<2> uns, string asm, SDPatternOperator op> {
8818  def NAME : sve_int_matmul<uns, asm>;
8819
8820  def : SVE_3_Op_Pat<nxv4i32, op , nxv4i32, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
8821}
8822
8823//===----------------------------------------------------------------------===//
8824// SVE Integer Dot Product Mixed Sign Group
8825//===----------------------------------------------------------------------===//
8826
8827class sve_int_dot_mixed<string asm>
8828: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR8:$Zm), asm,
8829  "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8830  bits<5> Zda;
8831  bits<5> Zn;
8832  bits<5> Zm;
8833  let Inst{31-21} = 0b01000100100;
8834  let Inst{20-16} = Zm;
8835  let Inst{15-10} = 0b011110;
8836  let Inst{9-5}   = Zn;
8837  let Inst{4-0}   = Zda;
8838
8839  let Constraints = "$Zda = $_Zda";
8840  let DestructiveInstType = DestructiveOther;
8841  let ElementSize = ZPR32.ElementSize;
8842  let hasSideEffects = 0;
8843}
8844
8845multiclass sve_int_dot_mixed<string asm, SDPatternOperator op> {
8846  def NAME : sve_int_dot_mixed<asm>;
8847
8848  def : SVE_3_Op_Pat<nxv4i32, op , nxv4i32, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
8849}
8850
8851//===----------------------------------------------------------------------===//
8852// SVE Integer Dot Product Mixed Sign - Indexed Group
8853//===----------------------------------------------------------------------===//
8854
8855class sve_int_dot_mixed_indexed<bit U, string asm>
8856: I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexS32b:$idx),
8857    asm, "\t$Zda, $Zn, $Zm$idx", "", []>, Sched<[]> {
8858  bits<5> Zda;
8859  bits<5> Zn;
8860  bits<3> Zm;
8861  bits<2> idx;
8862  let Inst{31-21} = 0b01000100101;
8863  let Inst{20-19} = idx;
8864  let Inst{18-16} = Zm;
8865  let Inst{15-11} = 0b00011;
8866  let Inst{10}    = U;
8867  let Inst{9-5}   = Zn;
8868  let Inst{4-0}   = Zda;
8869
8870  let Constraints = "$Zda = $_Zda";
8871  let DestructiveInstType = DestructiveOther;
8872  let ElementSize = ZPR32.ElementSize;
8873  let hasSideEffects = 0;
8874}
8875
8876multiclass sve_int_dot_mixed_indexed<bit U, string asm, SDPatternOperator op> {
8877  def NAME : sve_int_dot_mixed_indexed<U, asm>;
8878
8879  def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv16i8, nxv16i8, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
8880}
8881
8882//===----------------------------------------------------------------------===//
8883// SVE Floating Point Matrix Multiply Accumulate Group
8884//===----------------------------------------------------------------------===//
8885
8886class sve_fp_matrix_mla<bit sz, string asm, ZPRRegOp zprty>
8887: I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, zprty:$Zm),
8888    asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8889  bits<5> Zda;
8890  bits<5> Zn;
8891  bits<5> Zm;
8892  let Inst{31-23} = 0b011001001;
8893  let Inst{22}    = sz;
8894  let Inst{21}    = 1;
8895  let Inst{20-16} = Zm;
8896  let Inst{15-10} = 0b111001;
8897  let Inst{9-5}   = Zn;
8898  let Inst{4-0}   = Zda;
8899
8900  let Constraints = "$Zda = $_Zda";
8901  let DestructiveInstType = DestructiveOther;
8902  let ElementSize = zprty.ElementSize;
8903  let hasSideEffects = 0;
8904  let mayRaiseFPException = 1;
8905}
8906
8907multiclass sve_fp_matrix_mla<bit sz, string asm, ZPRRegOp zprty, SDPatternOperator op, ValueType vt> {
8908  def NAME : sve_fp_matrix_mla<sz, asm, zprty>;
8909
8910  def : SVE_3_Op_Pat<vt, op , vt, vt, vt, !cast<Instruction>(NAME)>;
8911}
8912
8913//===----------------------------------------------------------------------===//
8914// SVE Memory - Contiguous Load And Replicate 256-bit Group
8915//===----------------------------------------------------------------------===//
8916
8917class sve_mem_ldor_si<bits<2> sz, string asm, RegisterOperand VecList>
8918: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s32:$imm4),
8919  asm, "\t$Zt, $Pg/z, [$Rn, $imm4]", "", []>, Sched<[]> {
8920  bits<5> Zt;
8921  bits<5> Rn;
8922  bits<3> Pg;
8923  bits<4> imm4;
8924  let Inst{31-25} = 0b1010010;
8925  let Inst{24-23} = sz;
8926  let Inst{22-20} = 0b010;
8927  let Inst{19-16} = imm4;
8928  let Inst{15-13} = 0b001;
8929  let Inst{12-10} = Pg;
8930  let Inst{9-5}   = Rn;
8931  let Inst{4-0}   = Zt;
8932
8933  let hasSideEffects = 0;
8934  let mayLoad = 1;
8935}
8936
8937multiclass sve_mem_ldor_si<bits<2> sz, string asm, RegisterOperand listty,
8938                           ZPRRegOp zprty, ValueType Ty, ValueType PredTy, SDNode Ld1ro> {
8939  def NAME : sve_mem_ldor_si<sz, asm, listty>;
8940  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
8941                  (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
8942  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
8943                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
8944  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4]",
8945                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s32:$imm4), 0>;
8946
8947  // Base addressing mode
8948  def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$Pg), GPR64sp:$base)),
8949            (!cast<Instruction>(NAME) PPR3bAny:$Pg, GPR64sp:$base, (i64 0))>;
8950  let AddedComplexity = 2 in {
8951    // Reg + Imm addressing mode
8952    def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$Pg), (add GPR64:$base, (i64 simm4s32:$imm)))),
8953              (!cast<Instruction>(NAME) $Pg, $base, simm4s32:$imm)>;
8954  }
8955}
8956
8957class sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand VecList,
8958                      RegisterOperand gprty>
8959: I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
8960  asm, "\t$Zt, $Pg/z, [$Rn, $Rm]", "", []>, Sched<[]> {
8961  bits<5> Zt;
8962  bits<3> Pg;
8963  bits<5> Rn;
8964  bits<5> Rm;
8965  let Inst{31-25} = 0b1010010;
8966  let Inst{24-23} = sz;
8967  let Inst{22-21} = 0b01;
8968  let Inst{20-16} = Rm;
8969  let Inst{15-13} = 0;
8970  let Inst{12-10} = Pg;
8971  let Inst{9-5}   = Rn;
8972  let Inst{4-0}   = Zt;
8973
8974  let hasSideEffects = 0;
8975  let mayLoad = 1;
8976}
8977
8978multiclass sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand listty,
8979                           ZPRRegOp zprty, RegisterOperand gprty, ValueType Ty,
8980                           ValueType PredTy, SDNode Ld1ro, ComplexPattern AddrCP> {
8981  def NAME : sve_mem_ldor_ss<sz, asm, listty, gprty>;
8982
8983  def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
8984                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
8985
8986  def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$gp), (AddrCP GPR64sp:$base, gprty:$offset))),
8987            (!cast<Instruction>(NAME) PPR3bAny:$gp, GPR64sp:$base, gprty:$offset)>;
8988}
8989
8990//===----------------------------------------------------------------------===//
8991// SVE Interleave 128-bit Elements Group
8992//===----------------------------------------------------------------------===//
8993
8994class sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm>
8995: I<(outs ZPR128:$Zd), (ins ZPR128:$Zn, ZPR128:$Zm),
8996  asm, "\t$Zd, $Zn, $Zm",
8997  "",
8998  []>, Sched<[]> {
8999  bits<5> Zd;
9000  bits<5> Zm;
9001  bits<5> Zn;
9002  let Inst{31-21} = 0b00000101101;
9003  let Inst{20-16} = Zm;
9004  let Inst{15-13} = 0b000;
9005  let Inst{12-11} = opc;
9006  let Inst{10}    = P;
9007  let Inst{9-5}   = Zn;
9008  let Inst{4-0}   = Zd;
9009
9010  let hasSideEffects = 0;
9011}
9012
9013multiclass sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm, SDPatternOperator op> {
9014  def NAME : sve_int_perm_bin_perm_128_zz<opc, P, asm>;
9015
9016  def : SVE_2_Op_Pat<nxv16i8,  op, nxv16i8,  nxv16i8,  !cast<Instruction>(NAME)>;
9017  def : SVE_2_Op_Pat<nxv8i16,  op, nxv8i16,  nxv8i16,  !cast<Instruction>(NAME)>;
9018  def : SVE_2_Op_Pat<nxv8f16,  op, nxv8f16,  nxv8f16,  !cast<Instruction>(NAME)>;
9019  def : SVE_2_Op_Pat<nxv4i32,  op, nxv4i32,  nxv4i32,  !cast<Instruction>(NAME)>;
9020  def : SVE_2_Op_Pat<nxv4f32,  op, nxv4f32,  nxv4f32,  !cast<Instruction>(NAME)>;
9021  def : SVE_2_Op_Pat<nxv2i64,  op, nxv2i64,  nxv2i64,  !cast<Instruction>(NAME)>;
9022  def : SVE_2_Op_Pat<nxv2f64,  op, nxv2f64,  nxv2f64,  !cast<Instruction>(NAME)>;
9023  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
9024}
9025
9026/// Addressing modes
9027def am_sve_indexed_s4 :ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-8,7>", [], [SDNPWantRoot]>;
9028def am_sve_indexed_s6 :ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-32,31>", [], [SDNPWantRoot]>;
9029
9030def am_sve_regreg_lsl0 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<0>", []>;
9031def am_sve_regreg_lsl1 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<1>", []>;
9032def am_sve_regreg_lsl2 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<2>", []>;
9033def am_sve_regreg_lsl3 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<3>", []>;
9034def am_sve_regreg_lsl4 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<4>", []>;
9035
9036// Predicated pseudo floating point two operand instructions.
9037multiclass sve_fp_bin_pred_hfd<SDPatternOperator op> {
9038  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9039  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9040  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9041
9042  def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9043  def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9044  def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9045  def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9046  def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9047  def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9048}
9049
9050// Predicated pseudo floating point three operand instructions.
9051multiclass sve_fp_3op_pred_hfd<SDPatternOperator op> {
9052  def _H_UNDEF : PredThreeOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9053  def _S_UNDEF : PredThreeOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9054  def _D_UNDEF : PredThreeOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9055
9056  def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9057  def : SVE_4_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9058  def : SVE_4_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9059  def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S_UNDEF)>;
9060  def : SVE_4_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S_UNDEF)>;
9061  def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D_UNDEF)>;
9062}
9063
9064multiclass sve_fp_3op_pred_bf<SDPatternOperator op> {
9065  def _UNDEF : PredThreeOpPseudo<NAME, ZPR16, FalseLanesUndef>;
9066
9067  def : SVE_4_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _UNDEF)>;
9068}
9069
9070// Predicated pseudo integer two operand instructions.
9071multiclass sve_int_bin_pred_bhsd<SDPatternOperator op> {
9072  def _B_UNDEF : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesUndef>;
9073  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9074  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9075  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9076
9077  def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
9078  def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9079  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9080  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9081}
9082
9083// As sve_int_bin_pred but when only i32 and i64 vector types are required.
9084multiclass sve_int_bin_pred_sd<SDPatternOperator op> {
9085  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9086  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9087
9088  def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9089  def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9090}
9091
9092// Predicated pseudo integer two operand instructions. Second operand is an
9093// immediate specified by imm_[bhsd].
9094multiclass sve_int_shift_pred_bhsd<SDPatternOperator op,
9095                                   ComplexPattern imm_b, ComplexPattern imm_h,
9096                                   ComplexPattern imm_s, ComplexPattern imm_d> {
9097  def _B_UNDEF : PredTwoOpImmPseudo<NAME # _B, ZPR8,  Operand<i32>, FalseLanesUndef>;
9098  def _H_UNDEF : PredTwoOpImmPseudo<NAME # _H, ZPR16, Operand<i32>, FalseLanesUndef>;
9099  def _S_UNDEF : PredTwoOpImmPseudo<NAME # _S, ZPR32, Operand<i32>, FalseLanesUndef>;
9100  def _D_UNDEF : PredTwoOpImmPseudo<NAME # _D, ZPR64, Operand<i32>, FalseLanesUndef>;
9101
9102  def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, imm_b, !cast<Instruction>(NAME # _B_UNDEF)>;
9103  def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, imm_h, !cast<Instruction>(NAME # _H_UNDEF)>;
9104  def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, imm_s, !cast<Instruction>(NAME # _S_UNDEF)>;
9105  def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, imm_d, !cast<Instruction>(NAME # _D_UNDEF)>;
9106}
9107
9108multiclass sve_int_bin_pred_all_active_bhsd<SDPatternOperator op> {
9109  def _B_UNDEF : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesUndef>;
9110  def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9111  def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9112  def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9113
9114  def : SVE_2_Op_Pred_All_Active_Pt<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
9115  def : SVE_2_Op_Pred_All_Active_Pt<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9116  def : SVE_2_Op_Pred_All_Active_Pt<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9117  def : SVE_2_Op_Pred_All_Active_Pt<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9118}
9119
9120//===----------------------------------------------------------------------===//
9121// SME2 or SVE2.1 Instructions
9122//===----------------------------------------------------------------------===//
9123
9124class sve2p1_fclamp<string asm, bits<2> sz, ZPRRegOp zpr_ty>
9125    : I<(outs zpr_ty:$Zd), (ins zpr_ty:$_Zd, zpr_ty:$Zn, zpr_ty:$Zm),
9126        asm, "\t$Zd, $Zn, $Zm", "", []>,
9127      Sched<[]> {
9128  bits<5> Zm;
9129  bits<5> Zn;
9130  bits<5> Zd;
9131  let Inst{31-24} = 0b01100100;
9132  let Inst{23-22} = sz;
9133  let Inst{21}    = 0b1;
9134  let Inst{20-16} = Zm;
9135  let Inst{15-10} = 0b001001;
9136  let Inst{9-5}   = Zn;
9137  let Inst{4-0}   = Zd;
9138
9139  let Constraints = "$Zd = $_Zd";
9140  let DestructiveInstType = DestructiveOther;
9141  let ElementSize = zpr_ty.ElementSize;
9142  let hasSideEffects = 0;
9143}
9144
9145multiclass sve2p1_fclamp<string asm, SDPatternOperator op> {
9146  def _H : sve2p1_fclamp<asm, 0b01, ZPR16>;
9147  def _S : sve2p1_fclamp<asm, 0b10, ZPR32>;
9148  def _D : sve2p1_fclamp<asm, 0b11, ZPR64>;
9149
9150  def : SVE_3_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
9151  def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
9152  def : SVE_3_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
9153}
9154
9155multiclass sve2p1_bfclamp<string asm, SDPatternOperator op> {
9156  def NAME : sve2p1_fclamp<asm, 0b00, ZPR16>;
9157  def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
9158}
9159
9160// SVE two-way dot product
9161class sve2p1_two_way_dot_vv<string mnemonic, bit u>
9162    : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
9163        mnemonic, "\t$Zda, $Zn, $Zm",
9164        "", []>, Sched<[]> {
9165  bits<5> Zda;
9166  bits<5> Zn;
9167  bits<5> Zm;
9168  let Inst{31-21} = 0b01000100000;
9169  let Inst{20-16} = Zm;
9170  let Inst{15-11} = 0b11001;
9171  let Inst{10}    = u;
9172  let Inst{9-5}   = Zn;
9173  let Inst{4-0}   = Zda;
9174
9175  let Constraints = "$Zda = $_Zda";
9176  let DestructiveInstType = DestructiveOther;
9177  let hasSideEffects = 0;
9178}
9179
9180multiclass sve2p1_two_way_dot_vv<string mnemonic, bit u, SDPatternOperator intrinsic> {
9181  def NAME : sve2p1_two_way_dot_vv<mnemonic, u>;
9182
9183  def : SVE_3_Op_Pat<nxv4i32, intrinsic, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
9184}
9185
9186// SVE two-way dot product (indexed)
9187class sve2p1_two_way_dot_vvi<string mnemonic, bit u>
9188    : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR3b16:$Zm, VectorIndexS32b:$i2),
9189        mnemonic, "\t$Zda, $Zn, $Zm$i2",
9190        "", []>, Sched<[]> {
9191  bits<5> Zda;
9192  bits<5> Zn;
9193  bits<3> Zm;
9194  bits<2> i2;
9195  let Inst{31-21} = 0b01000100100;
9196  let Inst{20-19} = i2;
9197  let Inst{18-16} = Zm;
9198  let Inst{15-11} = 0b11001;
9199  let Inst{10}    = u;
9200  let Inst{9-5}   = Zn;
9201  let Inst{4-0}   = Zda;
9202
9203  let Constraints = "$Zda = $_Zda";
9204  let DestructiveInstType = DestructiveOther;
9205  let hasSideEffects = 0;
9206}
9207
9208multiclass sve2p1_two_way_dot_vvi<string mnemonic, bit u, SDPatternOperator intrinsic> {
9209  def NAME : sve2p1_two_way_dot_vvi<mnemonic, u>;
9210
9211  def : SVE_4_Op_Imm_Pat<nxv4i32, intrinsic, nxv4i32, nxv8i16, nxv8i16, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
9212}
9213
9214class sve2p1_ptrue_pn<string mnemonic, bits<2> sz, PNRP8to15RegOp pnrty, SDPatternOperator op>
9215    : I<(outs pnrty:$PNd), (ins ), mnemonic, "\t$PNd",
9216        "", [(set pnrty:$PNd, (op))]>, Sched<[]> {
9217  bits<3> PNd;
9218  let Inst{31-24}  = 0b00100101;
9219  let Inst{23-22} = sz;
9220  let Inst{21-3}  = 0b1000000111100000010;
9221  let Inst{2-0}   = PNd;
9222
9223  let hasSideEffects = 0;
9224  let isReMaterializable = 1;
9225  let Uses = [VG];
9226}
9227
9228
9229multiclass sve2p1_ptrue_pn<string mnemonic> {
9230 def _B : sve2p1_ptrue_pn<mnemonic, 0b00, PNR8_p8to15, int_aarch64_sve_ptrue_c8>;
9231 def _H : sve2p1_ptrue_pn<mnemonic, 0b01, PNR16_p8to15, int_aarch64_sve_ptrue_c16>;
9232 def _S : sve2p1_ptrue_pn<mnemonic, 0b10, PNR32_p8to15, int_aarch64_sve_ptrue_c32>;
9233 def _D : sve2p1_ptrue_pn<mnemonic, 0b11, PNR64_p8to15, int_aarch64_sve_ptrue_c64>;
9234}
9235
9236
9237// SVE extract mask predicate from predicate-as-counter
9238class sve2p1_pred_as_ctr_to_mask_base<string mnemonic, bits<2> sz, bits<3> opc,
9239                                      RegisterOperand pprty, Operand idxty>
9240    : I<(outs pprty:$Pd), (ins PNRAny_p8to15:$PNn, idxty:$index),
9241        mnemonic, "\t$Pd, $PNn$index",
9242        "", []>, Sched<[]> {
9243  bits<4> Pd;
9244  bits<3> PNn;
9245  bits<2> imm2;
9246  let Inst{31-24} = 0b00100101;
9247  let Inst{23-22} = sz;
9248  let Inst{21-11} = 0b10000001110;
9249  let Inst{10-8}  = opc;
9250  let Inst{7-5}   = PNn;
9251  let Inst{4}     = 0b1;
9252  let Inst{3-0}   = Pd;
9253
9254  let hasSideEffects = 0;
9255}
9256
9257class sve2p1_pred_as_ctr_to_mask<string mnemonic, bits<2> sz, PPRRegOp pprty>
9258    : sve2p1_pred_as_ctr_to_mask_base<mnemonic, sz, {0, ?, ?}, pprty, VectorIndexS32b_timm> {
9259  bits<2> index;
9260  let Inst{9-8} = index;
9261}
9262
9263multiclass sve2p1_pred_as_ctr_to_mask<string mnemonic, SDPatternOperator op> {
9264 def _B : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b00, PPR8>;
9265 def _H : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b01, PPR16>;
9266 def _S : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b10, PPR32>;
9267 def _D : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b11, PPR64>;
9268
9269 def : SVE_2_Op_Imm_Pat<nxv16i1, op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _B)>;
9270 def : SVE_2_Op_Imm_Pat<nxv8i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _H)>;
9271 def : SVE_2_Op_Imm_Pat<nxv4i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
9272 def : SVE_2_Op_Imm_Pat<nxv2i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
9273}
9274
9275
9276class sve2p1_pred_as_ctr_to_mask_pair<string mnemonic, bits<2> sz, RegisterOperand pprty>
9277    : sve2p1_pred_as_ctr_to_mask_base<mnemonic, sz, {1, 0, ?}, pprty, VectorIndexD> {
9278  bit index;
9279  let Inst{8}    = index;
9280}
9281
9282multiclass sve2p1_pred_as_ctr_to_mask_pair<string mnemonic> {
9283 def _B : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b00, PP_b>;
9284 def _H : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b01, PP_h>;
9285 def _S : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b10, PP_s>;
9286 def _D : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b11, PP_d>;
9287}
9288
9289
9290// SME2 multi-vec extract narrow
9291class sve2p1_multi_vec_extract_narrow<string mnemonic, bits<2> opc, bits<3> tsz>
9292    : I<(outs ZPR16:$Zd), (ins ZZ_s_mul_r:$Zn),
9293        mnemonic, "\t$Zd, $Zn",
9294        "", []>, Sched<[]> {
9295  bits<5> Zd;
9296  bits<4> Zn;
9297  let Inst{31-23} = 0b010001010;
9298  let Inst{22}    = tsz{2};
9299  let Inst{21}    = 0b1;
9300  let Inst{20-19} = tsz{1-0};
9301  let Inst{18-13} = 0b001010;
9302  let Inst{12-11} = opc;
9303  let Inst{10}    = 0b0;
9304  let Inst{9-6}   = Zn;
9305  let Inst{5}     = 0b0;
9306  let Inst{4-0}   = Zd;
9307
9308  let hasSideEffects = 0;
9309}
9310
9311multiclass sve2p1_multi_vec_extract_narrow<string mnemonic, bits<2> opc, SDPatternOperator intrinsic> {
9312  def NAME : sve2p1_multi_vec_extract_narrow<mnemonic, opc, 0b010>;
9313  def : SVE2p1_Cvt_VG2_Pat<NAME, intrinsic, nxv8i16, nxv4i32>;
9314}
9315
9316// SVE2 multi-vec shift narrow
9317class sve2p1_multi_vec_shift_narrow<string mnemonic, bits<3> opc, bits<2> tsz>
9318    : I<(outs ZPR16:$Zd), (ins ZZ_s_mul_r:$Zn, tvecshiftR16:$imm4),
9319        mnemonic, "\t$Zd, $Zn, $imm4",
9320        "", []>, Sched<[]> {
9321  bits<5> Zd;
9322  bits<4> Zn;
9323  bits<4> imm4;
9324  let Inst{31-23} = 0b010001011;
9325  let Inst{22}    = tsz{1};
9326  let Inst{21}    = 0b1;
9327  let Inst{20}    = tsz{0};
9328  let Inst{19-16} = imm4;
9329  let Inst{15-14} = 0b00;
9330  let Inst{13-11} = opc;
9331  let Inst{10}    = 0b0;
9332  let Inst{9-6}   = Zn;
9333  let Inst{5}     = 0b0;
9334  let Inst{4-0}   = Zd;
9335
9336  let hasSideEffects = 0;
9337}
9338
9339multiclass sve2p1_multi_vec_shift_narrow<string mnemonic, bits<3> opc, SDPatternOperator intrinsic> {
9340  def NAME : sve2p1_multi_vec_shift_narrow<mnemonic, opc, 0b01>;
9341
9342  def : SVE2p1_Sat_Shift_VG2_Pat<NAME, intrinsic, nxv8i16, nxv4i32, tvecshiftR16>;
9343}
9344
9345
9346// SME2 multi-vec contiguous load (scalar plus scalar, two registers)
9347class sve2p1_mem_cld_ss_2z<string mnemonic, bits<2> msz, bit n,
9348                         RegisterOperand vector_ty, RegisterOperand gpr_ty>
9349    : I<(outs vector_ty:$Zt),
9350        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9351        mnemonic, "\t$Zt, $PNg/z, [$Rn, $Rm]",
9352        "", []>, Sched<[]> {
9353  bits<4> Zt;
9354  bits<5> Rm;
9355  bits<5> Rn;
9356  bits<3> PNg;
9357  let Inst{31-21} = 0b10100000000;
9358  let Inst{20-16} = Rm;
9359  let Inst{15}    = 0b0;
9360  let Inst{14-13} = msz;
9361  let Inst{12-10} = PNg;
9362  let Inst{9-5} = Rn;
9363  let Inst{4-1} = Zt;
9364  let Inst{0}   = n;
9365
9366  let hasSideEffects = 0;
9367  let mayLoad = 1;
9368}
9369
9370multiclass sve2p1_mem_cld_ss_2z<string mnemonic, bits<2> msz, bit n,
9371                         RegisterOperand vector_ty, RegisterOperand gpr_ty, RegisterOperand vector_pseudo_ty> {
9372  def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm), []>;
9373  def NAME : sve2p1_mem_cld_ss_2z<mnemonic, msz, n, vector_ty, gpr_ty>;
9374}
9375
9376// SME2 multi-vec contiguous load (scalar plus immediate, two registers)
9377class sve2p1_mem_cld_si_2z<string mnemonic, bits<2> msz, bit n,
9378                         RegisterOperand vector_ty>
9379    : I<(outs vector_ty:$Zt),
9380        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4),
9381        mnemonic, "\t$Zt, $PNg/z, [$Rn, $imm4, mul vl]",
9382        "", []>, Sched<[]> {
9383  bits<4> Zt;
9384  bits<5> Rn;
9385  bits<3> PNg;
9386  bits<4> imm4;
9387  let Inst{31-20} = 0b101000000100;
9388  let Inst{19-16} = imm4;
9389  let Inst{15}    = 0b0;
9390  let Inst{14-13} = msz;
9391  let Inst{12-10} = PNg;
9392  let Inst{9-5}   = Rn;
9393  let Inst{4-1}   = Zt;
9394  let Inst{0}     = n;
9395
9396  let hasSideEffects = 0;
9397  let mayLoad = 1;
9398}
9399
9400multiclass sve2p1_mem_cld_si_2z<string mnemonic, bits<2> msz, bit n,
9401                              RegisterOperand vector_ty, RegisterOperand vector_pseudo_ty> {
9402  def NAME : sve2p1_mem_cld_si_2z<mnemonic, msz, n, vector_ty>;
9403  def : InstAlias<mnemonic # " $Zt, $PNg/z, [$Rn]",
9404                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9405  def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4), []>;
9406}
9407
9408// SME2 multi-vec contiguous load (scalar plus scalar, four registers)
9409class sve2p1_mem_cld_ss_4z<string mnemonic, bits<2> msz, bit n,
9410                         RegisterOperand vector_ty, RegisterOperand gpr_ty>
9411    : I<(outs vector_ty:$Zt),
9412        (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9413        mnemonic, "\t$Zt, $PNg/z, [$Rn, $Rm]",
9414        "", []>, Sched<[]> {
9415  bits<3> Zt;
9416  bits<5> Rm;
9417  bits<5> Rn;
9418  bits<3> PNg;
9419  let Inst{31-21} = 0b10100000000;
9420  let Inst{20-16} = Rm;
9421  let Inst{15}    = 0b1;
9422  let Inst{14-13} = msz;
9423  let Inst{12-10} = PNg;
9424  let Inst{9-5} = Rn;
9425  let Inst{4-2} = Zt;
9426  let Inst{1}   = 0b0;
9427  let Inst{0}   = n;
9428
9429  let hasSideEffects = 0;
9430  let mayLoad = 1;
9431}
9432
9433multiclass sve2p1_mem_cld_ss_4z<string mnemonic, bits<2> msz, bit n,
9434                         RegisterOperand vector_ty, RegisterOperand gpr_ty, RegisterOperand vector_pseudo_ty> {
9435  def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm), []>;
9436  def NAME : sve2p1_mem_cld_ss_4z<mnemonic, msz, n, vector_ty, gpr_ty>;
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, RegisterOperand vector_pseudo_ty> {
9466  def NAME : sve2p1_mem_cld_si_4z<mnemonic, msz, n, vector_ty>;
9467  def : InstAlias<mnemonic # " $Zt, $PNg/z, [$Rn]",
9468                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9469  def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4), []>;
9470}
9471
9472// SME2 multi-vec contiguous store (scalar plus scalar, two registers)
9473class sve2p1_mem_cst_ss_2z<string mnemonic, bits<2> msz, bit n,
9474                           RegisterOperand vector_ty, RegisterOperand gpr_ty>
9475    : I<(outs ),
9476        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9477        mnemonic, "\t$Zt, $PNg, [$Rn, $Rm]",
9478        "", []>, Sched<[]> {
9479  bits<4> Zt;
9480  bits<5> Rm;
9481  bits<5> Rn;
9482  bits<3> PNg;
9483  let Inst{31-21} = 0b10100000001;
9484  let Inst{20-16} = Rm;
9485  let Inst{15}    = 0b0;
9486  let Inst{14-13} = msz;
9487  let Inst{12-10} = PNg;
9488  let Inst{9-5} = Rn;
9489  let Inst{4-1} = Zt;
9490  let Inst{0}   = n;
9491
9492  let hasSideEffects = 0;
9493  let mayStore = 1;
9494}
9495
9496
9497// SME2 multi-vec contiguous store (scalar plus immediate, two registers)
9498class sve2p1_mem_cst_si_2z<string mnemonic, bits<2> msz, bit n,
9499                           RegisterOperand vector_ty>
9500    : I<(outs ),
9501        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4),
9502        mnemonic, "\t$Zt, $PNg, [$Rn, $imm4, mul vl]",
9503        "", []>, Sched<[]> {
9504  bits<4> Zt;
9505  bits<5> Rn;
9506  bits<3> PNg;
9507  bits<4> imm4;
9508  let Inst{31-20} = 0b101000000110;
9509  let Inst{19-16} = imm4;
9510  let Inst{15}    = 0b0;
9511  let Inst{14-13} = msz;
9512  let Inst{12-10} = PNg;
9513  let Inst{9-5}   = Rn;
9514  let Inst{4-1}   = Zt;
9515  let Inst{0}     = n;
9516
9517  let hasSideEffects = 0;
9518  let mayStore = 1;
9519}
9520
9521
9522multiclass sve2p1_mem_cst_si_2z<string mnemonic, bits<2> msz, bit n,
9523                              RegisterOperand vector_ty> {
9524  def NAME : sve2p1_mem_cst_si_2z<mnemonic, msz, n, vector_ty>;
9525
9526  def : InstAlias<mnemonic # " $Zt, $PNg, [$Rn]",
9527                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9528}
9529
9530
9531// SME2 multi-vec contiguous store (scalar plus scalar, four registers)
9532class sve2p1_mem_cst_ss_4z<string mnemonic, bits<2> msz, bit n,
9533                           RegisterOperand vector_ty, RegisterOperand gpr_ty>
9534    : I<(outs ),
9535        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9536        mnemonic, "\t$Zt, $PNg, [$Rn, $Rm]",
9537        "", []>, Sched<[]> {
9538  bits<3> Zt;
9539  bits<5> Rm;
9540  bits<5> Rn;
9541  bits<3> PNg;
9542  let Inst{31-21} = 0b10100000001;
9543  let Inst{20-16} = Rm;
9544  let Inst{15}    = 0b1;
9545  let Inst{14-13} = msz;
9546  let Inst{12-10} = PNg;
9547  let Inst{9-5} = Rn;
9548  let Inst{4-2} = Zt;
9549  let Inst{1}   = 0b0;
9550  let Inst{0}   = n;
9551
9552  let mayStore = 1;
9553}
9554
9555
9556// SME2 multi-vec contiguous store (scalar plus immediate, four registers)
9557class sve2p1_mem_cst_si_4z<string mnemonic, bits<2> msz, bit n,
9558                           RegisterOperand vector_ty>
9559    : I<(outs ),
9560        (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4),
9561        mnemonic, "\t$Zt, $PNg, [$Rn, $imm4, mul vl]",
9562        "", []>, Sched<[]> {
9563  bits<3> Zt;
9564  bits<5> Rn;
9565  bits<3> PNg;
9566  bits<4> imm4;
9567  let Inst{31-20} = 0b101000000110;
9568  let Inst{19-16} = imm4;
9569  let Inst{15}    = 0b1;
9570  let Inst{14-13} = msz;
9571  let Inst{12-10} = PNg;
9572  let Inst{9-5}   = Rn;
9573  let Inst{4-2}   = Zt;
9574  let Inst{1}     = 0b0;
9575  let Inst{0}     = n;
9576
9577  let hasSideEffects = 0;
9578  let mayStore = 1;
9579}
9580
9581
9582multiclass sve2p1_mem_cst_si_4z<string mnemonic, bits<2> msz, bit n,
9583                                RegisterOperand vector_ty> {
9584  def NAME : sve2p1_mem_cst_si_4z<mnemonic, msz, n, vector_ty>;
9585
9586  def : InstAlias<mnemonic # " $Zt, $PNg, [$Rn]",
9587                  (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn,0), 1>;
9588}
9589
9590// SVE predicate count (predicate-as-counter)
9591class sve2p1_pcount_pn<string mnemonic, bits<3> opc, bits<2> sz, PNRRegOp pnrty>
9592   : I<(outs GPR64:$Rd),
9593       (ins pnrty:$PNn, sve_vec_len_specifier_enum:$vl),
9594       mnemonic, "\t$Rd, $PNn, $vl",
9595       "", []>, Sched<[]> {
9596  bits<5> Rd;
9597  bits<4> PNn;
9598  bits<1> vl;
9599  let Inst{31-24} = 0b00100101;
9600  let Inst{23-22} = sz;
9601  let Inst{21-19} = 0b100;
9602  let Inst{18-16} = opc;
9603  let Inst{15-11} = 0b10000;
9604  let Inst{10}    = vl;
9605  let Inst{9}     = 0b1;
9606  let Inst{8-5}   = PNn;
9607  let Inst{4-0}   = Rd;
9608
9609  let hasSideEffects = 0;
9610}
9611
9612multiclass sve2p1_pcount_pn<string mnemonic, bits<3> opc> {
9613  def _B : sve2p1_pcount_pn<mnemonic, opc, 0b00, PNR8>;
9614  def _H : sve2p1_pcount_pn<mnemonic, opc, 0b01, PNR16>;
9615  def _S : sve2p1_pcount_pn<mnemonic, opc, 0b10, PNR32>;
9616  def _D : sve2p1_pcount_pn<mnemonic, opc, 0b11, PNR64>;
9617
9618  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c8,  aarch64svcount, !cast<Instruction>(NAME # _B)>;
9619  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c16, aarch64svcount, !cast<Instruction>(NAME # _H)>;
9620  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c32, aarch64svcount, !cast<Instruction>(NAME # _S)>;
9621  defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c64, aarch64svcount, !cast<Instruction>(NAME # _D)>;
9622}
9623
9624
9625// SVE integer compare scalar count and limit (predicate-as-counter)
9626class sve2p1_int_while_rr_pn<string mnemonic, bits<2> sz, bits<3> opc,
9627                             PNRP8to15RegOp pnrty>
9628    : I<(outs pnrty:$PNd), (ins GPR64:$Rn, GPR64:$Rm, sve_vec_len_specifier_enum:$vl),
9629        mnemonic, "\t$PNd, $Rn, $Rm, $vl",
9630        "", []>, Sched<[]> {
9631  bits<3> PNd;
9632  bits<5> Rn;
9633  bits<1> vl;
9634  bits<5> Rm;
9635  let Inst{31-24} = 0b00100101;
9636  let Inst{23-22} = sz;
9637  let Inst{21}    = 0b1;
9638  let Inst{20-16} = Rm;
9639  let Inst{15-14} = 0b01;
9640  let Inst{13}    = vl;
9641  let Inst{12}    = 0b0;
9642  let Inst{11-10} = opc{2-1};
9643  let Inst{9-5}   = Rn;
9644  let Inst{4}     = 0b1;
9645  let Inst{3}     = opc{0};
9646  let Inst{2-0}   = PNd;
9647
9648  let Defs = [NZCV];
9649  let hasSideEffects = 0;
9650}
9651
9652
9653multiclass sve2p1_int_while_rr_pn<string mnemonic, bits<3> opc> {
9654 def _B : sve2p1_int_while_rr_pn<mnemonic, 0b00, opc, PNR8_p8to15>;
9655 def _H : sve2p1_int_while_rr_pn<mnemonic, 0b01, opc, PNR16_p8to15>;
9656 def _S : sve2p1_int_while_rr_pn<mnemonic, 0b10, opc, PNR32_p8to15>;
9657 def _D : sve2p1_int_while_rr_pn<mnemonic, 0b11, opc, PNR64_p8to15>;
9658
9659 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c8"),
9660                            i64, !cast<Instruction>(NAME # _B)>;
9661 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c16"),
9662                            i64, !cast<Instruction>(NAME # _H)>;
9663 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c32"),
9664                            i64, !cast<Instruction>(NAME # _S)>;
9665 defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c64"),
9666                            i64, !cast<Instruction>(NAME # _D)>;
9667}
9668
9669
9670// SVE integer compare scalar count and limit (predicate pair)
9671class sve2p1_int_while_rr_pair<string mnemonic, bits<2> sz, bits<3> opc,
9672                             RegisterOperand ppr_ty>
9673    : I<(outs ppr_ty:$Pd), (ins GPR64:$Rn, GPR64:$Rm),
9674        mnemonic, "\t$Pd, $Rn, $Rm",
9675        "", []>, Sched<[]> {
9676  bits<3> Pd;
9677  bits<5> Rn;
9678  bits<5> Rm;
9679  let Inst{31-24} = 0b00100101;
9680  let Inst{23-22} = sz;
9681  let Inst{21}    = 0b1;
9682  let Inst{20-16} = Rm;
9683  let Inst{15-12} = 0b0101;
9684  let Inst{11-10} = opc{2-1};
9685  let Inst{9-5}   = Rn;
9686  let Inst{4}     = 0b1;
9687  let Inst{3-1}   = Pd;
9688  let Inst{0}     = opc{0};
9689
9690  let Defs = [NZCV];
9691  let hasSideEffects = 0;
9692}
9693
9694
9695multiclass sve2p1_int_while_rr_pair<string mnemonic, bits<3> opc> {
9696 def _B : sve2p1_int_while_rr_pair<mnemonic, 0b00, opc, PP_b_mul_r>;
9697 def _H : sve2p1_int_while_rr_pair<mnemonic, 0b01, opc, PP_h_mul_r>;
9698 def _S : sve2p1_int_while_rr_pair<mnemonic, 0b10, opc, PP_s_mul_r>;
9699 def _D : sve2p1_int_while_rr_pair<mnemonic, 0b11, opc, PP_d_mul_r>;
9700}
9701
9702
9703class sve_mem_128b_gld_64_unscaled<string mnemonic>
9704    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
9705        mnemonic, "\t$Zt, $Pg/z, [$Zn, $Rm]",
9706        "", []>, Sched<[]> {
9707  bits<5> Zt;
9708  bits<5> Zn;
9709  bits<3> Pg;
9710  bits<5> Rm;
9711  let Inst{31-21} = 0b11000100000;
9712  let Inst{20-16} = Rm;
9713  let Inst{15-13} = 0b101;
9714  let Inst{12-10} = Pg;
9715  let Inst{9-5}   = Zn;
9716  let Inst{4-0}   = Zt;
9717
9718  let hasSideEffects = 0;
9719  let mayLoad = 1;
9720}
9721
9722
9723multiclass sve_mem_128b_gld_64_unscaled<string mnemonic, SDPatternOperator op> {
9724  def NAME : sve_mem_128b_gld_64_unscaled<mnemonic>;
9725
9726  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Zn]",
9727                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
9728
9729
9730  def : Pat<(nxv2i64 (op (nxv2i1 PPR3bAny:$Pg),  (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2i64)),
9731            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9732  def : Pat<(nxv4i32 (op (nxv4i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn),  (i64 GPR64sp:$Rm), nxv4i32)),
9733            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9734  def : Pat<(nxv8i16 (op (nxv8i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8i16)),
9735            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9736  def : Pat<(nxv16i8 (op (nxv16i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv16i8)),
9737            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9738
9739  def : Pat<(nxv2f64 (op (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2f64)),
9740            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9741  def : Pat<(nxv4f32 (op (nxv4i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv4f32)),
9742            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9743  def : Pat<(nxv8f16 (op (nxv8i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8f16)),
9744            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9745  def : Pat<(nxv8bf16 (op (nxv8i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8bf16)),
9746            (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9747}
9748
9749class sve_mem_sst_128b_64_unscaled<string mnemonic>
9750    : I<(outs ), (ins Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
9751        mnemonic, "\t$Zt, $Pg, [$Zn, $Rm]",
9752        "", []>, Sched<[]> {
9753  bits<5> Zt;
9754  bits<5> Zn;
9755  bits<3> Pg;
9756  bits<5> Rm;
9757  let Inst{31-21} = 0b11100100001;
9758  let Inst{20-16} = Rm;
9759  let Inst{15-13} = 0b001;
9760  let Inst{12-10} = Pg;
9761  let Inst{9-5}   = Zn;
9762  let Inst{4-0}   = Zt;
9763
9764  let hasSideEffects = 0;
9765  let mayStore = 1;
9766}
9767
9768
9769multiclass sve_mem_sst_128b_64_unscaled<string mnemonic, SDPatternOperator op> {
9770  def NAME : sve_mem_sst_128b_64_unscaled<mnemonic>;
9771
9772  def : InstAlias<mnemonic # " $Zt, $Pg, [$Zn]",
9773                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
9774
9775  def : Pat<(op (nxv2i64 Z_q:$Zt), (nxv2i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2i64),
9776            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9777  def : Pat<(op (nxv4i32 Z_q:$Zt), (nxv4i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv4i32),
9778            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9779  def : Pat<(op (nxv8i16 Z_q:$Zt), (nxv8i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8i16),
9780            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp,ZPR64:$Zn, GPR64:$Rm)>;
9781  def : Pat<(op (nxv16i8 Z_q:$Zt), (nxv16i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv16i8),
9782            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9783
9784  def : Pat<(op (nxv2f64 Z_q:$Zt), (nxv2i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2f64),
9785            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9786  def : Pat<(op (nxv4f32 Z_q:$Zt), (nxv4i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv4f32),
9787            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9788  def : Pat<(op (nxv8f16 Z_q:$Zt), (nxv8i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8f16),
9789            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9790  def : Pat<(op (nxv8bf16 Z_q:$Zt), (nxv8i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8bf16),
9791            (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9792}
9793
9794
9795// SVE contiguous load (quadwords, scalar plus immediate)
9796class sve_mem_128b_cld_si<bits<2> dtype, string mnemonic>
9797    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
9798        mnemonic, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
9799        "", []>, Sched<[]> {
9800  bits<5> Zt;
9801  bits<5> Rn;
9802  bits<3> Pg;
9803  bits<4> imm4;
9804  let Inst{31-25} = 0b1010010;
9805  let Inst{24-23} = dtype;
9806  let Inst{22-20} = 0b001;
9807  let Inst{19-16} = imm4;
9808  let Inst{15-13} = 0b001;
9809  let Inst{12-10} = Pg;
9810  let Inst{9-5}   = Rn;
9811  let Inst{4-0}   = Zt;
9812
9813  let hasSideEffects = 0;
9814  let mayLoad = 1;
9815}
9816
9817multiclass sve_mem_128b_cld_si<bits<2> dtype, string mnemonic> {
9818  def NAME : sve_mem_128b_cld_si<dtype, mnemonic>;
9819
9820  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn]",
9821                  (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
9822  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn]",
9823                  (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
9824  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn, $imm4, mul vl]",
9825                  (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
9826}
9827
9828
9829// SVE contiguous load (quadwords, scalar plus scalar)
9830class sve_mem_128b_cld_ss<bits<2> dtype, string mnemonic, RegisterOperand gprsh_ty>
9831    : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprsh_ty:$Rm),
9832        mnemonic, "\t$Zt, $Pg/z, [$Rn, $Rm]", "",
9833        []>, Sched<[]> {
9834  bits<5> Zt;
9835  bits<5> Rn;
9836  bits<3> Pg;
9837  bits<5> Rm;
9838  let Inst{31-25} = 0b1010010;
9839  let Inst{24-23} = dtype;
9840  let Inst{22-21} = 0b00;
9841  let Inst{20-16} = Rm;
9842  let Inst{15-13} = 0b100;
9843  let Inst{12-10} = Pg;
9844  let Inst{9-5}   = Rn;
9845  let Inst{4-0}   = Zt;
9846
9847  let hasSideEffects = 0;
9848  let mayLoad = 1;
9849}
9850
9851multiclass sve_mem_128b_cld_ss<bits<2> dtype, string mnemonic, RegisterOperand gprsh_ty> {
9852  def NAME : sve_mem_128b_cld_ss<dtype, mnemonic, gprsh_ty>;
9853
9854  def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn, $Rm]",
9855                 (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprsh_ty:$Rm), 0>;
9856}
9857
9858
9859// SVE floating-point recursive reduction (quadwords)
9860class sve2p1_fp_reduction_q<bits<2> sz, bits<3> opc, string mnemonic,
9861                            RegisterOperand zpr_ty, string vec_sfx>
9862    : I<(outs V128:$Vd), (ins PPR3bAny:$Pg, zpr_ty:$Zn),
9863        mnemonic, "\t$Vd." # vec_sfx # ", $Pg, $Zn",
9864        "", []>, Sched<[]> {
9865  bits<5> Vd;
9866  bits<5> Zn;
9867  bits<3> Pg;
9868  let Inst{31-24} = 0b01100100;
9869  let Inst{23-22} = sz;
9870  let Inst{21-19} = 0b010;
9871  let Inst{18-16} = opc;
9872  let Inst{15-13} = 0b101;
9873  let Inst{12-10} = Pg;
9874  let Inst{9-5}   = Zn;
9875  let Inst{4-0}   = Vd;
9876
9877  let hasSideEffects = 0;
9878  let mayRaiseFPException = 1;
9879}
9880
9881multiclass sve2p1_fp_reduction_q<bits<3> opc, string mnemonic, SDPatternOperator op> {
9882  def _H : sve2p1_fp_reduction_q<0b01, opc, mnemonic, ZPR16, "8h">;
9883  def _S : sve2p1_fp_reduction_q<0b10, opc, mnemonic, ZPR32, "4s">;
9884  def _D : sve2p1_fp_reduction_q<0b11, opc, mnemonic, ZPR64, "2d">;
9885
9886  def : SVE_2_Op_Pat<v8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
9887  def : SVE_2_Op_Pat<v4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
9888  def : SVE_2_Op_Pat<v2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
9889}
9890
9891
9892// SVE Permute Vector - Quadwords (DUPQ)
9893class sve2p1_dupq<bits<5> ind_tsz, string mnemonic, ZPRRegOp zprty, Operand itype>
9894    : I<(outs zprty:$Zd), (ins zprty:$Zn, itype:$index),
9895        mnemonic, "\t$Zd, $Zn$index",
9896        "", []>, Sched<[]> {
9897  bits<5> Zd;
9898  bits<5> Zn;
9899  let Inst{31-21} = 0b00000101001;
9900  let Inst{20-16} = ind_tsz;
9901  let Inst{15-10} = 0b001001;
9902  let Inst{9-5} = Zn;
9903  let Inst{4-0} = Zd;
9904
9905  let hasSideEffects = 0;
9906}
9907
9908multiclass sve2p1_dupq<string mnemonic, SDPatternOperator Op> {
9909  def _B : sve2p1_dupq<{?, ?, ?, ?, 1}, mnemonic, ZPR8, VectorIndexB32b_timm> {
9910    bits<4> index;
9911    let Inst{20-17} = index;
9912  }
9913  def _H : sve2p1_dupq<{?, ?, ?, 1, 0}, mnemonic, ZPR16, VectorIndexH32b_timm> {
9914    bits<3> index;
9915    let Inst{20-18} = index;
9916  }
9917  def _S : sve2p1_dupq<{?, ?, 1, 0, 0}, mnemonic, ZPR32, VectorIndexS32b_timm> {
9918    bits<2> index;
9919    let Inst{20-19} = index;
9920  }
9921  def _D : sve2p1_dupq<{?, 1, 0, 0, 0}, mnemonic, ZPR64, VectorIndexD32b_timm> {
9922    bits<1> index;
9923    let Inst{20} = index;
9924  }
9925
9926  def : SVE_2_Op_Imm_Pat<nxv16i8, Op, nxv16i8, i32, VectorIndexB32b_timm, !cast<Instruction>(NAME # _B)>;
9927  def : SVE_2_Op_Imm_Pat<nxv8i16, Op, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
9928  def : SVE_2_Op_Imm_Pat<nxv4i32, Op, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
9929  def : SVE_2_Op_Imm_Pat<nxv2i64, Op, nxv2i64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
9930
9931  def : SVE_2_Op_Imm_Pat<nxv8f16, Op, nxv8f16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
9932  def : SVE_2_Op_Imm_Pat<nxv4f32, Op, nxv4f32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
9933  def : SVE_2_Op_Imm_Pat<nxv2f64, Op, nxv2f64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
9934  def : SVE_2_Op_Imm_Pat<nxv8bf16, Op, nxv8bf16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
9935}
9936
9937
9938// SVE Permute Vector - Quadwords (EXTQ)
9939class sve2p1_extq<string mnemonic>
9940    : I<(outs ZPR8:$Zdn), (ins ZPR8:$_Zdn, ZPR8:$Zm, timm32_0_15:$imm4),
9941        mnemonic, "\t$Zdn, $_Zdn, $Zm, $imm4",
9942        "", []>, Sched<[]> {
9943  bits<5> Zdn;
9944  bits<5> Zm;
9945  bits<4> imm4;
9946  let Inst{31-20} = 0b000001010110;
9947  let Inst{19-16} = imm4;
9948  let Inst{15-10} = 0b001001;
9949  let Inst{9-5} = Zm;
9950  let Inst{4-0} = Zdn;
9951
9952  let Constraints = "$Zdn = $_Zdn";
9953  let DestructiveInstType = DestructiveOther;
9954  let ElementSize = ZPR8.ElementSize;
9955  let hasSideEffects = 0;
9956}
9957
9958multiclass sve2p1_extq<string mnemonic, SDPatternOperator Op> {
9959  def NAME : sve2p1_extq<mnemonic>;
9960  def : SVE_3_Op_Imm_Pat<nxv16i8, Op, nxv16i8, nxv16i8, i32, timm32_0_15, !cast<Instruction>(NAME)>;
9961  def : SVE_3_Op_Imm_Pat<nxv8i16, Op, nxv8i16, nxv8i16, i32, timm32_0_15, !cast<Instruction>(NAME)>;
9962  def : SVE_3_Op_Imm_Pat<nxv4i32, Op, nxv4i32, nxv4i32, i32, timm32_0_15, !cast<Instruction>(NAME)>;
9963  def : SVE_3_Op_Imm_Pat<nxv2i64, Op, nxv2i64, nxv2i64, i32, timm32_0_15, !cast<Instruction>(NAME)>;
9964
9965  def : SVE_3_Op_Imm_Pat<nxv8f16, Op, nxv8f16, nxv8f16, i32, timm32_0_15, !cast<Instruction>(NAME)>;
9966  def : SVE_3_Op_Imm_Pat<nxv4f32, Op, nxv4f32, nxv4f32, i32, timm32_0_15, !cast<Instruction>(NAME)>;
9967  def : SVE_3_Op_Imm_Pat<nxv2f64, Op, nxv2f64, nxv2f64, i32, timm32_0_15, !cast<Instruction>(NAME)>;
9968  def : SVE_3_Op_Imm_Pat<nxv8bf16, Op, nxv8bf16, nxv8bf16, i32, timm32_0_15, !cast<Instruction>(NAME
9969)>;
9970}
9971
9972// SVE move predicate from vector
9973class sve2p1_vector_to_pred<bits<4> opc, string mnemonic,
9974                            PPRRegOp ppr_ty, Operand itype>
9975    : I<(outs ppr_ty:$Pd), (ins ZPRAny:$Zn, itype:$index),
9976        mnemonic, "\t$Pd, $Zn$index",
9977        "", []>, Sched<[]> {
9978  bits<4> Pd;
9979  bits<5> Zn;
9980  let Inst{31-24} = 0b00000101;
9981  let Inst{23-22} = opc{3-2};
9982  let Inst{21-19} = 0b101;
9983  let Inst{18-17} = opc{1-0};
9984  let Inst{16-10} = 0b0001110;
9985  let Inst{9-5}   = Zn;
9986  let Inst{4}     = 0b0;
9987  let Inst{3-0}   = Pd;
9988
9989  let hasSideEffects = 0;
9990}
9991
9992multiclass sve2p1_vector_to_pred<string mnemonic, SDPatternOperator Op_lane, SDPatternOperator Op> {
9993  def _B : sve2p1_vector_to_pred<{0, 0, 0, 1}, mnemonic, PPR8,  VectorIndex032b>;
9994  def _H : sve2p1_vector_to_pred<{0, 0, 1, ?}, mnemonic, PPR16, VectorIndexD32b> {
9995    bits<1> index;
9996    let Inst{17} = index;
9997  }
9998  def _S : sve2p1_vector_to_pred<{0, 1, ?, ?}, mnemonic, PPR32, VectorIndexS32b> {
9999    bits<2> index;
10000    let Inst{18-17} = index;
10001  }
10002  def _D : sve2p1_vector_to_pred<{1, ?, ?, ?}, mnemonic, PPR64, VectorIndexH32b> {
10003    bits<3> index;
10004    let Inst{22}    = index{2};
10005    let Inst{18-17} = index{1-0};
10006  }
10007
10008  def : InstAlias<mnemonic # "\t$Pd, $Zn",
10009                 (!cast<Instruction>(NAME # _B) PPR8:$Pd, ZPRAny:$Zn, 0), 1>;
10010  def : InstAlias<mnemonic # "\t$Pd, $Zn",
10011                 (!cast<Instruction>(NAME # _H) PPR16:$Pd, ZPRAny:$Zn, 0), 0>;
10012  def : InstAlias<mnemonic # "\t$Pd, $Zn",
10013                 (!cast<Instruction>(NAME # _S) PPR32:$Pd, ZPRAny:$Zn, 0), 0>;
10014  def : InstAlias<mnemonic # "\t$Pd, $Zn",
10015                 (!cast<Instruction>(NAME # _D) PPR64:$Pd, ZPRAny:$Zn, 0), 0>;
10016
10017  // any_lane
10018  def : Pat<(nxv16i1 (Op_lane (nxv16i8 ZPRAny:$Zn), (i32 timm32_0_0:$Idx))),
10019            (!cast<Instruction>(NAME # _B) ZPRAny:$Zn, timm32_0_0:$Idx)>;
10020  def : Pat<(nxv8i1 (Op_lane (nxv8i16 ZPRAny:$Zn), (i32 timm32_0_1:$Idx))),
10021            (!cast<Instruction>(NAME # _H) ZPRAny:$Zn, timm32_0_1:$Idx)>;
10022  def : Pat<(nxv4i1 (Op_lane (nxv4i32 ZPRAny:$Zn), (i32 timm32_0_3:$Idx))),
10023            (!cast<Instruction>(NAME # _S) ZPRAny:$Zn, timm32_0_3:$Idx)>;
10024  def : Pat<(nxv2i1 (Op_lane (nxv2i64 ZPRAny:$Zn), (i32 timm32_0_7:$Idx))),
10025            (!cast<Instruction>(NAME # _D) ZPRAny:$Zn, timm32_0_7:$Idx)>;
10026 // lane_0
10027 def : Pat<(nxv16i1 (Op (nxv16i8 ZPRAny:$Zn))),
10028            (!cast<Instruction>(NAME # _B) ZPRAny:$Zn, 0)>;
10029  def : Pat<(nxv8i1 (Op (nxv8i16 ZPRAny:$Zn))),
10030            (!cast<Instruction>(NAME # _H) ZPRAny:$Zn, 0)>;
10031  def : Pat<(nxv4i1 (Op (nxv4i32 ZPRAny:$Zn))),
10032            (!cast<Instruction>(NAME # _S) ZPRAny:$Zn, 0)>;
10033  def : Pat<(nxv2i1 (Op (nxv2i64 ZPRAny:$Zn))),
10034            (!cast<Instruction>(NAME # _D) ZPRAny:$Zn, 0)>;
10035}
10036
10037
10038// SVE move predicate into vector
10039class sve2p1_pred_to_vector<bits<4> opc, string mnemonic,
10040                            PPRRegOp ppr_ty, Operand itype>
10041    : I<(outs ZPRAny:$Zd), (ins ZPRAny:$_Zd, itype:$index, ppr_ty:$Pn),
10042        mnemonic, "\t$Zd$index, $Pn",
10043        "", []>, Sched<[]> {
10044  bits<5> Zd;
10045  bits<4> Pn;
10046  let Inst{31-24} = 0b00000101;
10047  let Inst{23-22} = opc{3-2};
10048  let Inst{21-19} = 0b101;
10049  let Inst{18-17} = opc{1-0};
10050  let Inst{16-9}  = 0b10011100;
10051  let Inst{8-5}   = Pn;
10052  let Inst{4-0}   = Zd;
10053
10054  let Constraints = "$Zd = $_Zd";
10055  let hasSideEffects = 0;
10056}
10057
10058multiclass sve2p1_pred_to_vector<string mnemonic, SDPatternOperator MergeOp,
10059                                 SDPatternOperator ZeroOp> {
10060  def _B : sve2p1_pred_to_vector<{0, 0, 0, 1}, mnemonic, PPR8,  VectorIndex0>;
10061  def _H : sve2p1_pred_to_vector<{0, 0, 1, ?}, mnemonic, PPR16, VectorIndexD32b> {
10062    bits<1> index;
10063    let Inst{17} = index;
10064  }
10065  def _S : sve2p1_pred_to_vector<{0, 1, ?, ?}, mnemonic, PPR32, VectorIndexS32b> {
10066    bits<2> index;
10067    let Inst{18-17} = index;
10068  }
10069  def _D : sve2p1_pred_to_vector<{1, ?, ?, ?}, mnemonic, PPR64, VectorIndexH32b> {
10070    bits<3> index;
10071    let Inst{22}    = index{2};
10072    let Inst{18-17} = index{1-0};
10073  }
10074
10075  def : InstAlias<mnemonic # "\t$Zd, $Pn",
10076                 (!cast<Instruction>(NAME # _B) ZPRAny:$Zd, 0, PPR8:$Pn), 1>;
10077  def : InstAlias<mnemonic # "\t$Zd, $Pn",
10078                 (!cast<Instruction>(NAME # _H) ZPRAny:$Zd, 0, PPR16:$Pn), 0>;
10079  def : InstAlias<mnemonic # "\t$Zd, $Pn",
10080                 (!cast<Instruction>(NAME # _S) ZPRAny:$Zd, 0, PPR32:$Pn), 0>;
10081  def : InstAlias<mnemonic # "\t$Zd, $Pn",
10082                 (!cast<Instruction>(NAME # _D) ZPRAny:$Zd, 0, PPR64:$Pn), 0>;
10083
10084  // Merge
10085  def : Pat<(nxv8i16 (MergeOp (nxv8i16 ZPRAny:$Zd), (nxv8i1 PPR16:$Pn), (i32 timm32_1_1:$Idx))),
10086            (!cast<Instruction>(NAME # _H) ZPRAny:$Zd, timm32_1_1:$Idx, PPR16:$Pn)>;
10087  def : Pat<(nxv4i32 (MergeOp (nxv4i32 ZPRAny:$Zd), (nxv4i1 PPR32:$Pn), (i32 timm32_1_3:$Idx))),
10088            (!cast<Instruction>(NAME # _S) ZPRAny:$Zd, timm32_1_3:$Idx, PPR32:$Pn)>;
10089  def : Pat<(nxv2i64 (MergeOp (nxv2i64 ZPRAny:$Zd), (nxv2i1 PPR64:$Pn), (i32 timm32_1_7:$Idx))),
10090            (!cast<Instruction>(NAME # _D) ZPRAny:$Zd, timm32_1_7:$Idx, PPR64:$Pn)>;
10091
10092  // Zero
10093  def : Pat<(nxv16i8 (ZeroOp (nxv16i1 PPR8:$Pn))),
10094           (!cast<Instruction>(NAME # _B) (IMPLICIT_DEF), 0, PPR8:$Pn)>;
10095  def : Pat<(nxv8i16 (ZeroOp (nxv8i1 PPR16:$Pn))),
10096            (!cast<Instruction>(NAME # _H) (IMPLICIT_DEF), 0, PPR16:$Pn)>;
10097  def : Pat<(nxv4i32 (ZeroOp (nxv4i1 PPR32:$Pn))),
10098            (!cast<Instruction>(NAME # _S) (IMPLICIT_DEF), 0, PPR32:$Pn)>;
10099  def : Pat<(nxv2i64 (ZeroOp (nxv2i1 PPR64:$Pn))),
10100            (!cast<Instruction>(NAME # _D) (IMPLICIT_DEF), 0, PPR64:$Pn)>;
10101}
10102
10103
10104// SVE bitwise logical/add/min/max reductions (quadwords)
10105class sve2p1_int_reduce_q<bits<2> sz, bits<4> opc, string mnemonic,
10106                          RegisterOperand zpr_ty, string vec_sfx>
10107    : I<(outs V128:$Vd), (ins PPR3bAny:$Pg, zpr_ty:$Zn),
10108        mnemonic, "\t$Vd." # vec_sfx # ", $Pg, $Zn",
10109        "", []>, Sched<[]> {
10110  bits<5> Vd;
10111  bits<5> Zn;
10112  bits<3> Pg;
10113  let Inst{31-24} = 0b00000100;
10114  let Inst{23-22} = sz;
10115  let Inst{21}    = 0b0;
10116  let Inst{20-19} = opc{3-2};
10117  let Inst{18}    = 0b1;
10118  let Inst{17-16} = opc{1-0};
10119  let Inst{15-13} = 0b001;
10120  let Inst{12-10} = Pg;
10121  let Inst{9-5}   = Zn;
10122  let Inst{4-0}   = Vd;
10123
10124  let hasSideEffects = 0;
10125}
10126
10127multiclass sve2p1_int_reduce_q<bits<4> opc, string mnemonic, SDPatternOperator op> {
10128  def _B : sve2p1_int_reduce_q<0b00, opc, mnemonic, ZPR8,  "16b">;
10129  def _H : sve2p1_int_reduce_q<0b01, opc, mnemonic, ZPR16, "8h">;
10130  def _S : sve2p1_int_reduce_q<0b10, opc, mnemonic, ZPR32, "4s">;
10131  def _D : sve2p1_int_reduce_q<0b11, opc, mnemonic, ZPR64, "2d">;
10132
10133  def : SVE_2_Op_Pat<v16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
10134  def : SVE_2_Op_Pat<v8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
10135  def : SVE_2_Op_Pat<v4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
10136  def : SVE_2_Op_Pat<v2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
10137}
10138
10139
10140// SVE permute vector elements (quadwords)
10141class sve2p1_permute_vec_elems_q<bits<2> sz, bits<3> opc, string mnemonic,
10142                                 ZPRRegOp zpr_ty, RegisterOperand src1_ty>
10143    : I<(outs zpr_ty:$Zd), (ins src1_ty:$Zn, zpr_ty:$Zm),
10144        mnemonic, "\t$Zd, $Zn, $Zm",
10145        "", []>, Sched<[]> {
10146  bits<5> Zd;
10147  bits<5> Zn;
10148  bits<5> Zm;
10149  let Inst{31-24} = 0b01000100;
10150  let Inst{23-22} = sz;
10151  let Inst{21}    = 0b0;
10152  let Inst{20-16} = Zm;
10153  let Inst{15-13} = 0b111;
10154  let Inst{12-10} = opc;
10155  let Inst{9-5}   = Zn;
10156  let Inst{4-0}   = Zd;
10157
10158  let hasSideEffects = 0;
10159}
10160
10161multiclass sve2p1_permute_vec_elems_q<bits<3> opc, string mnemonic,
10162                                      SDPatternOperator op> {
10163  def _B : sve2p1_permute_vec_elems_q<0b00, opc, mnemonic, ZPR8,  ZPR8>;
10164  def _H : sve2p1_permute_vec_elems_q<0b01, opc, mnemonic, ZPR16, ZPR16>;
10165  def _S : sve2p1_permute_vec_elems_q<0b10, opc, mnemonic, ZPR32, ZPR32>;
10166  def _D : sve2p1_permute_vec_elems_q<0b11, opc, mnemonic, ZPR64, ZPR64>;
10167
10168  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
10169  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10170  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
10171  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
10172
10173  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
10174  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
10175  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
10176
10177  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
10178}
10179
10180multiclass sve2p1_tblq<string mnemonic, SDPatternOperator op> {
10181  def _B : sve2p1_permute_vec_elems_q<0b00, 0b110, mnemonic, ZPR8,  Z_b>;
10182  def _H : sve2p1_permute_vec_elems_q<0b01, 0b110, mnemonic, ZPR16, Z_h>;
10183  def _S : sve2p1_permute_vec_elems_q<0b10, 0b110, mnemonic, ZPR32, Z_s>;
10184  def _D : sve2p1_permute_vec_elems_q<0b11, 0b110, mnemonic, ZPR64, Z_d>;
10185
10186  def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
10187  def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10188  def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
10189  def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
10190
10191  def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10192  def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
10193  def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
10194
10195  def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10196}
10197
10198//===----------------------------------------------------------------------===//
10199// SVE2 FP8 Instructions
10200//===----------------------------------------------------------------------===//
10201
10202// FP8 upconvert
10203class sve2_fp8_cvt_single<bit L, bits<2> opc, string mnemonic,
10204                          ZPRRegOp dst_ty, ZPRRegOp src_ty>
10205    : I<(outs dst_ty:$Zd), (ins src_ty:$Zn),
10206      mnemonic, "\t$Zd, $Zn",
10207      "", []>, Sched<[]>{
10208  bits<5> Zd;
10209  bits<5> Zn;
10210  let Inst{31-17} = 0b011001010000100;
10211  let Inst{16}    = L;
10212  let Inst{15-12} = 0b0011;
10213  let Inst{11-10} = opc;
10214  let Inst{9-5}   = Zn;
10215  let Inst{4-0}   = Zd;
10216}
10217
10218multiclass sve2_fp8_cvt_single<bit L, bits<2> opc, string mnemonic> {
10219  def _BtoH : sve2_fp8_cvt_single<L, opc, mnemonic, ZPR16, ZPR8>;
10220}
10221
10222// FP8 downconvert
10223class sve2_fp8_down_cvt_single<bits<2> opc, string mnemonic,
10224                              ZPRRegOp dst_ty, RegisterOperand src_ty>
10225    : I<(outs dst_ty:$Zd), (ins src_ty:$Zn),
10226      mnemonic, "\t$Zd, $Zn",
10227      "", []>, Sched<[]>{
10228  bits<5> Zd;
10229  bits<4> Zn;
10230  let Inst{31-12} = 0b01100101000010100011;
10231  let Inst{11-10} = opc;
10232  let Inst{9-6} = Zn;
10233  let Inst{5} = 0b0;
10234  let Inst{4-0} = Zd;
10235}
10236
10237multiclass sve2_fp8_down_cvt_single<bits<2> opc, string mnemonic, RegisterOperand src> {
10238  def NAME : sve2_fp8_down_cvt_single<opc, mnemonic, ZPR8, src>;
10239}
10240
10241// FP8 Widening Multiply-Add Long - Indexed Group
10242class sve2_fp8_mla_long_by_indexed_elem<bit T, string mnemonic>
10243    : I<(outs ZPR16:$Zda),
10244      (ins ZPR16:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexB:$imm4),
10245      mnemonic, "\t$Zda, $Zn, $Zm$imm4",
10246      "", []>, Sched<[]>{
10247  bits<5> Zda;
10248  bits<5> Zn;
10249  bits<3> Zm;
10250  bits<4> imm4;
10251  let Inst{31-24} = 0b01100100;
10252  let Inst{23}    = T;
10253  let Inst{22-21} = 0b01;
10254  let Inst{20-19} = imm4{3-2};
10255  let Inst{18-16} = Zm;
10256  let Inst{15-12} = 0b0101;
10257  let Inst{11-10} = imm4{1-0};
10258  let Inst{9-5}   = Zn;
10259  let Inst{4-0}   = Zda;
10260  let Constraints = "$Zda = $_Zda";
10261  let DestructiveInstType = DestructiveOther;
10262  let ElementSize         = ZPR16.ElementSize;
10263}
10264
10265// FP8 Widening Multiply-Add (Long)/(Long Long) Group
10266class sve2_fp8_mla<bits<3>opc, ZPRRegOp dst_ty, string mnemonic>
10267    : I<(outs dst_ty:$Zda),
10268      (ins dst_ty:$_Zda, ZPR8:$Zn, ZPR8:$Zm),
10269      mnemonic, "\t$Zda, $Zn, $Zm",
10270      "", []>, Sched<[]>{
10271  bits<5> Zda;
10272  bits<5> Zn;
10273  bits<5> Zm;
10274  let Inst{31-24} = 0b01100100;
10275  let Inst{23}    = opc{2};
10276  let Inst{22-21} = 0b01;
10277  let Inst{20-16} = Zm;
10278  let Inst{15-14} = 0b10;
10279  let Inst{13-12} = opc{1-0};
10280  let Inst{11-10} = 0b10;
10281  let Inst{9-5}   = Zn;
10282  let Inst{4-0}   = Zda;
10283  let Constraints = "$Zda = $_Zda";
10284  let DestructiveInstType = DestructiveOther;
10285  let ElementSize         = dst_ty.ElementSize;
10286}
10287
10288// FP8 Widening Multiply-Add Long Long - Indexed Group
10289class sve2_fp8_mla_long_long_by_indexed_elem<bits<2> TT, string mnemonic>
10290    : I<(outs ZPR32:$Zda),
10291      (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexB:$imm4),
10292      mnemonic, "\t$Zda, $Zn, $Zm$imm4",
10293      "", []>, Sched<[]>{
10294  bits<5> Zda;
10295  bits<5> Zn;
10296  bits<3> Zm;
10297  bits<4> imm4;
10298  let Inst{31-24} = 0b01100100;
10299  let Inst{23-22} = TT;
10300  let Inst{21}    = 0b1;
10301  let Inst{20-19} = imm4{3-2};
10302  let Inst{18-16} = Zm;
10303  let Inst{15-12} = 0b1100;
10304  let Inst{11-10} = imm4{1-0};
10305  let Inst{9-5}   = Zn;
10306  let Inst{4-0}   = Zda;
10307  let Constraints = "$Zda = $_Zda";
10308  let DestructiveInstType = DestructiveOther;
10309  let ElementSize         = ZPR32.ElementSize;
10310}
10311
10312// FP8 Widening Dot-Product - Indexed Group
10313multiclass sve2_fp8_dot_indexed<string mnemonic>{
10314  def NAME : sve_float_dot_indexed<0b0, ZPR16, ZPR8, ZPR3b8, VectorIndexH, mnemonic> {
10315    bits<3> iop;
10316    let Inst{20-19} = iop{2-1};
10317    let Inst{11} = iop{0};
10318    let Inst{10} = 0b1;
10319  }
10320}
10321
10322// FP8 Look up table
10323class sve2_lut_vector_index<ZPRRegOp zd_ty, RegisterOperand zn_ty,
10324                            Operand idx_ty, bits<4>opc, string mnemonic>
10325    : I<(outs zd_ty:$Zd), (ins zn_ty:$Zn, ZPRAny:$Zm, idx_ty:$idx),
10326      mnemonic, "\t$Zd, $Zn, $Zm$idx",
10327      "", []>, Sched<[]> {
10328  bits<5> Zd;
10329  bits<5> Zn;
10330  bits<5> Zm;
10331  let Inst{31-24} = 0b01000101;
10332  let Inst{22}    = opc{3};
10333  let Inst{21}    = 0b1;
10334  let Inst{20-16} = Zm;
10335  let Inst{15-13} = 0b101;
10336  let Inst{12-10} = opc{2-0};
10337  let Inst{9-5}   = Zn;
10338  let Inst{4-0}   = Zd;
10339}
10340
10341// FP8 Look up table read with 2-bit indices
10342multiclass sve2_luti2_vector_index<string mnemonic> {
10343  def _B : sve2_lut_vector_index<ZPR8, Z_b, VectorIndexS32b, {?, 0b100}, mnemonic> {
10344    bits<2> idx;
10345    let Inst{23-22} = idx;
10346  }
10347  def _H : sve2_lut_vector_index<ZPR16, Z_h, VectorIndexH32b, {?,?,0b10}, mnemonic> {
10348    bits<3> idx;
10349    let Inst{23-22} = idx{2-1};
10350    let Inst{12}    = idx{0};
10351  }
10352}
10353
10354// FP8 Look up table read with 4-bit indices
10355multiclass sve2_luti4_vector_index<string mnemonic> {
10356  def _B : sve2_lut_vector_index<ZPR8, Z_b, VectorIndexD32b, 0b1001, mnemonic> {
10357    bit idx;
10358    let Inst{23} = idx;
10359  }
10360  def _H : sve2_lut_vector_index<ZPR16, Z_h, VectorIndexS32b, {?, 0b111}, mnemonic> {
10361    bits<2> idx;
10362    let Inst{23-22} = idx;
10363  }
10364}
10365
10366// FP8 Look up table read with 4-bit indices (two contiguous registers)
10367multiclass sve2_luti4_vector_vg2_index<string mnemonic> {
10368  def _H : sve2_lut_vector_index<ZPR16, ZZ_h, VectorIndexS32b, {?, 0b101}, mnemonic> {
10369    bits<2> idx;
10370    let Inst{23-22} = idx;
10371  }
10372}
10373
10374//===----------------------------------------------------------------------===//
10375// Checked Pointer Arithmetic (FEAT_CPA)
10376//===----------------------------------------------------------------------===//
10377class sve_int_mad_cpa<string asm>
10378    : I<(outs ZPR64:$Zdn), (ins ZPR64:$_Zdn, ZPR64:$Zm, ZPR64:$Za),
10379        asm, "\t$Zdn, $Zm, $Za", "", []>, Sched<[]> {
10380  bits<5> Zdn;
10381  bits<5> Zm;
10382  bits<5> Za;
10383  let Inst{31-24} = 0b01000100;
10384  let Inst{23-22} = 0b11; // sz
10385  let Inst{21}    = 0b0;
10386  let Inst{20-16} = Zm;
10387  let Inst{15}    = 0b1;
10388  let Inst{14-10} = 0b10110; // opc
10389  let Inst{9-5}   = Za;
10390  let Inst{4-0}   = Zdn;
10391
10392  let Constraints = "$Zdn = $_Zdn";
10393  let DestructiveInstType = DestructiveOther;
10394  let ElementSize = ZPR64.ElementSize;
10395  let hasSideEffects = 0;
10396}
10397
10398class sve_int_mla_cpa<string asm>
10399    : sve2_int_mla<0b11, 0b10100, asm, ZPR64, ZPR64> {
10400  let Inst{15} = 0b1;
10401
10402  let ElementSize = ZPR64.ElementSize;
10403}
10404