[llvm-shlib] Fix the version naming style of libLLVM for Windows (#85710)
[llvm-project.git] / llvm / lib / Target / AArch64 / SVEInstrFormats.td
blob789ec817d3d8b890fab363ffe88bd984714df610
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.
11 //===----------------------------------------------------------------------===//
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.
15 class 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);
43 def 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 ]>;
49 def AArch64setcc_z : SDNode<"AArch64ISD::SETCC_MERGE_ZERO", SDT_AArch64Setcc>;
50 def 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 }]>;
55 def SVEPatternOperand : AsmOperandClass {
56   let Name = "SVEPattern";
57   let ParserMethod = "tryParseSVEPattern";
58   let PredicateMethod = "isSVEPattern";
59   let RenderMethod = "addImmOperands";
60   let DiagnosticType = "InvalidSVEPattern";
63 def sve_pred_enum : Operand<i32>, TImmLeaf<i32, [{
64   return (((uint32_t)Imm) < 32);
65   }]> {
67   let PrintMethod = "printSVEPattern";
68   let ParserMatchClass = SVEPatternOperand;
71 def SVEVecLenSpecifierOperand : AsmOperandClass {
72   let Name = "SVEVecLenSpecifier";
73   let ParserMethod = "tryParseSVEVecLenSpecifier";
74   let PredicateMethod = "isSVEVecLenSpecifier";
75   let RenderMethod = "addImmOperands";
76   let DiagnosticType = "InvalidSVEVecLenSpecifier";
79 def sve_vec_len_specifier_enum : Operand<i32>, TImmLeaf<i32, [{
80   return (((uint32_t)Imm) < 2);
81   }]> {
83   let PrintMethod = "printSVEVecLenSpecifier";
84   let ParserMatchClass = SVEVecLenSpecifierOperand;
87 def SVEPrefetchOperand : AsmOperandClass {
88   let Name = "SVEPrefetch";
89   let ParserMethod = "tryParsePrefetch<true>";
90   let PredicateMethod = "isPrefetch";
91   let RenderMethod = "addPrefetchOperands";
94 def sve_prfop : Operand<i32>, TImmLeaf<i32, [{
95     return (((uint32_t)Imm) <= 15);
96   }]> {
97   let PrintMethod = "printPrefetchOp<true>";
98   let ParserMatchClass = SVEPrefetchOperand;
101 class 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>";
108 def sve_logical_imm8 : Operand<i64> {
109   let ParserMatchClass = SVELogicalImmOperand<8>;
110   let PrintMethod = "printLogicalImm<int8_t>";
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   }];
120 def sve_logical_imm16 : Operand<i64> {
121   let ParserMatchClass = SVELogicalImmOperand<16>;
122   let PrintMethod = "printLogicalImm<int16_t>";
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   }];
132 def sve_logical_imm32 : Operand<i64> {
133   let ParserMatchClass = SVELogicalImmOperand<32>;
134   let PrintMethod = "printLogicalImm<int32_t>";
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   }];
144 class SVEPreferredLogicalImmOperand<int Width> : AsmOperandClass {
145   let Name = "SVEPreferredLogicalImm" # Width;
146   let PredicateMethod = "isSVEPreferredLogicalImm<int" # Width # "_t>";
147   let RenderMethod = "addLogicalImmOperands<int" # Width # "_t>";
150 def sve_preferred_logical_imm16 : Operand<i64> {
151   let ParserMatchClass = SVEPreferredLogicalImmOperand<16>;
152   let PrintMethod = "printSVELogicalImm<int16_t>";
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   }];
163 def sve_preferred_logical_imm32 : Operand<i64> {
164   let ParserMatchClass =  SVEPreferredLogicalImmOperand<32>;
165   let PrintMethod = "printSVELogicalImm<int32_t>";
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   }];
176 def sve_preferred_logical_imm64 : Operand<i64> {
177   let ParserMatchClass = SVEPreferredLogicalImmOperand<64>;
178   let PrintMethod = "printSVELogicalImm<int64_t>";
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   }];
189 class 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>";
196 def sve_logical_imm8_not : Operand<i64> {
197   let ParserMatchClass = SVELogicalImmNotOperand<8>;
200 def sve_logical_imm16_not : Operand<i64> {
201   let ParserMatchClass = SVELogicalImmNotOperand<16>;
204 def sve_logical_imm32_not : Operand<i64> {
205   let ParserMatchClass = SVELogicalImmNotOperand<32>;
208 class 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;
217 def SVECpyImmOperand8  : SVEShiftedImmOperand<8,  "Cpy", "isSVECpyImm<int8_t>">;
218 def SVECpyImmOperand16 : SVEShiftedImmOperand<16, "Cpy", "isSVECpyImm<int16_t>">;
219 def SVECpyImmOperand32 : SVEShiftedImmOperand<32, "Cpy", "isSVECpyImm<int32_t>">;
220 def SVECpyImmOperand64 : SVEShiftedImmOperand<64, "Cpy", "isSVECpyImm<int64_t>">;
222 def SVEAddSubImmOperand8  : SVEShiftedImmOperand<8,  "AddSub", "isSVEAddSubImm<int8_t>">;
223 def SVEAddSubImmOperand16 : SVEShiftedImmOperand<16, "AddSub", "isSVEAddSubImm<int16_t>">;
224 def SVEAddSubImmOperand32 : SVEShiftedImmOperand<32, "AddSub", "isSVEAddSubImm<int32_t>">;
225 def SVEAddSubImmOperand64 : SVEShiftedImmOperand<64, "AddSub", "isSVEAddSubImm<int64_t>">;
227 class 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);
237 def cpy_imm8_opt_lsl_i8  : imm8_opt_lsl<8,  "int8_t",  SVECpyImmOperand8>;
238 def cpy_imm8_opt_lsl_i16 : imm8_opt_lsl<16, "int16_t", SVECpyImmOperand16>;
239 def cpy_imm8_opt_lsl_i32 : imm8_opt_lsl<32, "int32_t", SVECpyImmOperand32>;
240 def cpy_imm8_opt_lsl_i64 : imm8_opt_lsl<64, "int64_t", SVECpyImmOperand64>;
242 def addsub_imm8_opt_lsl_i8  : imm8_opt_lsl<8,  "uint8_t",  SVEAddSubImmOperand8>;
243 def addsub_imm8_opt_lsl_i16 : imm8_opt_lsl<16, "uint16_t", SVEAddSubImmOperand16>;
244 def addsub_imm8_opt_lsl_i32 : imm8_opt_lsl<32, "uint32_t", SVEAddSubImmOperand32>;
245 def addsub_imm8_opt_lsl_i64 : imm8_opt_lsl<64, "uint64_t", SVEAddSubImmOperand64>;
247 def SVEAddSubImm8Pat  : ComplexPattern<i32, 2, "SelectSVEAddSubImm<MVT::i8>", []>;
248 def SVEAddSubImm16Pat : ComplexPattern<i32, 2, "SelectSVEAddSubImm<MVT::i16>", []>;
249 def SVEAddSubImm32Pat : ComplexPattern<i32, 2, "SelectSVEAddSubImm<MVT::i32>", []>;
250 def SVEAddSubImm64Pat : ComplexPattern<i64, 2, "SelectSVEAddSubImm<MVT::i64>", []>;
252 def SVECpyDupImm8Pat  : ComplexPattern<i32, 2, "SelectSVECpyDupImm<MVT::i8>", []>;
253 def SVECpyDupImm16Pat : ComplexPattern<i32, 2, "SelectSVECpyDupImm<MVT::i16>", []>;
254 def SVECpyDupImm32Pat : ComplexPattern<i32, 2, "SelectSVECpyDupImm<MVT::i32>", []>;
255 def SVECpyDupImm64Pat : ComplexPattern<i64, 2, "SelectSVECpyDupImm<MVT::i64>", []>;
257 def SVELogicalImm8Pat  : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i8>", []>;
258 def SVELogicalImm16Pat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i16>", []>;
259 def SVELogicalImm32Pat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i32>", []>;
260 def SVELogicalImm64Pat : ComplexPattern<i64, 1, "SelectSVELogicalImm<MVT::i64>", []>;
262 def SVELogicalImm8NotPat  : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i8, true>", []>;
263 def SVELogicalImm16NotPat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i16, true>", []>;
264 def SVELogicalImm32NotPat : ComplexPattern<i32, 1, "SelectSVELogicalImm<MVT::i32, true>", []>;
265 def SVELogicalImm64NotPat : ComplexPattern<i64, 1, "SelectSVELogicalImm<MVT::i64, true>", []>;
267 def SVEArithUImm8Pat  : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i8>", []>;
268 def SVEArithUImm16Pat  : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i16>", []>;
269 def SVEArithUImm32Pat  : ComplexPattern<i32, 1, "SelectSVEArithImm<MVT::i32>", []>;
270 def SVEArithUImm64Pat  : ComplexPattern<i64, 1, "SelectSVEArithImm<MVT::i64>", []>;
272 def SVEArithSImmPat32 : ComplexPattern<i32, 1, "SelectSVESignedArithImm", []>;
273 def SVEArithSImmPat64 : ComplexPattern<i64, 1, "SelectSVESignedArithImm", []>;
275 def SVEShiftImmL8  : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 7>",  []>;
276 def SVEShiftImmL16 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 15>", []>;
277 def SVEShiftImmL32 : ComplexPattern<i32, 1, "SelectSVEShiftImm<0, 31>", []>;
278 def SVEShiftImmL64 : ComplexPattern<i64, 1, "SelectSVEShiftImm<0, 63>", []>;
279 def SVEShiftImmR8  : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 8,  true>", []>;
280 def SVEShiftImmR16 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 16, true>", []>;
281 def SVEShiftImmR32 : ComplexPattern<i32, 1, "SelectSVEShiftImm<1, 32, true>", []>;
282 def SVEShiftImmR64 : ComplexPattern<i64, 1, "SelectSVEShiftImm<1, 64, true>", []>;
284 def SVEShiftSplatImmR : ComplexPattern<iAny, 1, "SelectSVEShiftSplatImmR", []>;
286 def SVEAllActive : ComplexPattern<untyped, 0, "SelectAllActivePredicate", []>;
287 def SVEAnyPredicate : ComplexPattern<untyped, 0, "SelectAnyPredicate", []>;
289 class SVEExactFPImm<string Suffix, string ValA, string ValB> : AsmOperandClass {
290   let Name = "SVEExactFPImmOperand" # Suffix;
291   let DiagnosticType = "Invalid" # Name;
292   let ParserMethod = "tryParseFPImm<false>";
293   let PredicateMethod = "isExactFPImm<" # ValA # ", " # ValB # ">";
294   let RenderMethod = "addExactFPImmOperands<" # ValA # ", " # ValB # ">";
297 class SVEExactFPImmOperand<string Suffix, string ValA, string ValB> : Operand<i32> {
298   let PrintMethod = "printExactFPImm<" # ValA # ", " # ValB # ">";
299   let ParserMatchClass = SVEExactFPImm<Suffix, ValA, ValB>;
302 def sve_fpimm_half_one
303     : SVEExactFPImmOperand<"HalfOne", "AArch64ExactFPImm::half",
304                            "AArch64ExactFPImm::one">;
305 def sve_fpimm_half_two
306     : SVEExactFPImmOperand<"HalfTwo", "AArch64ExactFPImm::half",
307                            "AArch64ExactFPImm::two">;
308 def sve_fpimm_zero_one
309     : SVEExactFPImmOperand<"ZeroOne", "AArch64ExactFPImm::zero",
310                            "AArch64ExactFPImm::one">;
312 def sve_incdec_imm : Operand<i32>, TImmLeaf<i32, [{
313   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
314 }]> {
315   let ParserMatchClass = Imm1_16Operand;
316   let EncoderMethod = "getSVEIncDecImm";
317   let DecoderMethod = "DecodeSVEIncDecImm";
320 // This allows i32 immediate extraction from i64 based arithmetic.
321 def sve_cnt_mul_imm_i32 : ComplexPattern<i32, 1, "SelectCntImm<1, 16, 1, false>">;
322 def sve_cnt_mul_imm_i64 : ComplexPattern<i64, 1, "SelectCntImm<1, 16, 1, false>">;
323 def sve_cnt_shl_imm     : ComplexPattern<i64, 1, "SelectCntImm<1, 16, 1, true>">;
325 def sve_ext_imm_0_31  : ComplexPattern<i64, 1, "SelectEXTImm<31, 8>">;
326 def sve_ext_imm_0_63  : ComplexPattern<i64, 1, "SelectEXTImm<63, 4>">;
327 def sve_ext_imm_0_127 : ComplexPattern<i64, 1, "SelectEXTImm<127, 2>">;
328 def sve_ext_imm_0_255 : ComplexPattern<i64, 1, "SelectEXTImm<255, 1>">;
330 def int_aarch64_sve_cntp_oneuse : PatFrag<(ops node:$pred, node:$src2),
331                                           (int_aarch64_sve_cntp node:$pred, node:$src2), [{
332   return N->hasOneUse();
333 }]>;
335 def step_vector_oneuse : PatFrag<(ops node:$idx),
336                                  (step_vector node:$idx), [{
337   return N->hasOneUse();
338 }]>;
341 //===----------------------------------------------------------------------===//
342 // SVE PTrue - These are used extensively throughout the pattern matching so
343 //             it's important we define them first.
344 //===----------------------------------------------------------------------===//
346 class sve_int_ptrue<bits<2> sz8_64, bits<3> opc, string asm, PPRRegOp pprty,
347                     ValueType vt, SDPatternOperator op>
348 : I<(outs pprty:$Pd), (ins sve_pred_enum:$pattern),
349   asm, "\t$Pd, $pattern",
350   "",
351   [(set (vt pprty:$Pd), (op sve_pred_enum:$pattern))]>, Sched<[]> {
352   bits<4> Pd;
353   bits<5> pattern;
354   let Inst{31-24} = 0b00100101;
355   let Inst{23-22} = sz8_64;
356   let Inst{21-19} = 0b011;
357   let Inst{18-17} = opc{2-1};
358   let Inst{16}    = opc{0};
359   let Inst{15-10} = 0b111000;
360   let Inst{9-5}   = pattern;
361   let Inst{4}     = 0b0;
362   let Inst{3-0}   = Pd;
364   let Defs = !if(!eq (opc{0}, 1), [NZCV], []);
365   let ElementSize = pprty.ElementSize;
366   let hasSideEffects = 0;
367   let isReMaterializable = 1;
370 multiclass sve_int_ptrue<bits<3> opc, string asm, SDPatternOperator op> {
371   def _B : sve_int_ptrue<0b00, opc, asm, PPR8, nxv16i1, op>;
372   def _H : sve_int_ptrue<0b01, opc, asm, PPR16, nxv8i1, op>;
373   def _S : sve_int_ptrue<0b10, opc, asm, PPR32, nxv4i1, op>;
374   def _D : sve_int_ptrue<0b11, opc, asm, PPR64, nxv2i1, op>;
376   def : InstAlias<asm # "\t$Pd",
377                   (!cast<Instruction>(NAME # _B) PPR8:$Pd, 0b11111), 1>;
378   def : InstAlias<asm # "\t$Pd",
379                   (!cast<Instruction>(NAME # _H) PPR16:$Pd, 0b11111), 1>;
380   def : InstAlias<asm # "\t$Pd",
381                   (!cast<Instruction>(NAME # _S) PPR32:$Pd, 0b11111), 1>;
382   def : InstAlias<asm # "\t$Pd",
383                   (!cast<Instruction>(NAME # _D) PPR64:$Pd, 0b11111), 1>;
386 def SDT_AArch64PTrue : SDTypeProfile<1, 1, [SDTCisVec<0>, SDTCisVT<1, i32>]>;
387 def AArch64ptrue : SDNode<"AArch64ISD::PTRUE", SDT_AArch64PTrue>;
389 let Predicates = [HasSVEorSME] in {
390   defm PTRUE  : sve_int_ptrue<0b000, "ptrue", AArch64ptrue>;
391   defm PTRUES : sve_int_ptrue<0b001, "ptrues", null_frag>;
393   def : Pat<(nxv16i1 immAllOnesV), (PTRUE_B 31)>;
394   def : Pat<(nxv8i1 immAllOnesV), (PTRUE_H 31)>;
395   def : Pat<(nxv4i1 immAllOnesV), (PTRUE_S 31)>;
396   def : Pat<(nxv2i1 immAllOnesV), (PTRUE_D 31)>;
399 //===----------------------------------------------------------------------===//
400 // SVE pattern match helpers.
401 //===----------------------------------------------------------------------===//
403 class SVE_1_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
404                    Instruction inst>
405 : Pat<(vtd (op vt1:$Op1)),
406       (inst $Op1)>;
408 class SVE_1_Op_Passthru_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
409                             ValueType vts, Instruction inst>
410 : Pat<(vtd (op pg:$Op1, vts:$Op2, vtd:$Op3)),
411       (inst $Op3, $Op1, $Op2)>;
414 multiclass SVE_1_Op_PassthruUndef_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
415                                  ValueType vts, Instruction inst> {
416   def : Pat<(vtd (op pg:$Op1, vts:$Op2, (vtd undef))),
417             (inst (IMPLICIT_DEF), $Op1, $Op2)>;
418   def : Pat<(vtd (op (pg (SVEAllActive:$Op1)), vts:$Op2, vtd:$Op3)),
419             (inst $Op3, $Op1, $Op2)>;
422 // Used to match FP_ROUND_MERGE_PASSTHRU, which has an additional flag for the
423 // type of rounding. This is matched by timm0_1 in pattern below and ignored.
424 class SVE_1_Op_Passthru_Round_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
425                                   ValueType vts, Instruction inst>
426 : Pat<(vtd (op pg:$Op1, vts:$Op2, (i64 timm0_1), vtd:$Op3)),
427       (inst $Op3, $Op1, $Op2)>;
429 multiclass SVE_1_Op_PassthruUndef_Round_Pat<ValueType vtd, SDPatternOperator op, ValueType pg,
430                                   ValueType vts, Instruction inst>{
431   def : Pat<(vtd (op pg:$Op1, vts:$Op2, (i64 timm0_1), (vtd undef))),
432             (inst (IMPLICIT_DEF), $Op1, $Op2)>;
433   def : Pat<(vtd (op (pg (SVEAllActive:$Op1)), vts:$Op2, (i64 timm0_1), vtd:$Op3)),
434             (inst $Op3, $Op1, $Op2)>;
437 def SVEDup0 : ComplexPattern<vAny, 0, "SelectDupZero", []>;
438 def SVEDupNeg0 : ComplexPattern<vAny, 0, "SelectDupNegativeZero", []>;
440 class SVE_1_Op_PassthruZero_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
441                    ValueType vt2, Instruction inst>
442    : Pat<(vtd (op (vtd (SVEDup0)), vt1:$Op1, vt2:$Op2)),
443         (inst (IMPLICIT_DEF), $Op1, $Op2)>;
445 class SVE_1_Op_Imm_OptLsl_Pat<ValueType vt, SDPatternOperator op, ZPRRegOp zprty,
446                               ValueType it, ComplexPattern cpx, Instruction inst>
447   : Pat<(vt (op (vt zprty:$Op1), (vt (splat_vector (it (cpx i32:$imm, i32:$shift)))))),
448         (inst $Op1, i32:$imm, i32:$shift)>;
450 class SVE_1_Op_Imm_Arith_Any_Predicate<ValueType vt, ValueType pt,
451                                        SDPatternOperator op, ZPRRegOp zprty,
452                                        ValueType it, ComplexPattern cpx,
453                                        Instruction inst>
454   : Pat<(vt (op (pt (SVEAnyPredicate)), (vt zprty:$Op1), (vt (splat_vector (it (cpx i32:$imm)))))),
455         (inst $Op1, i32:$imm)>;
457 class SVE_1_Op_Imm_Log_Pat<ValueType vt, SDPatternOperator op, ZPRRegOp zprty,
458                            ValueType it, ComplexPattern cpx, Instruction inst>
459   : Pat<(vt (op (vt zprty:$Op1), (vt (splat_vector (it (cpx i64:$imm)))))),
460         (inst $Op1, i64:$imm)>;
462 class SVE_2_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
463                    ValueType vt2, Instruction inst>
464 : Pat<(vtd (op vt1:$Op1, vt2:$Op2)),
465       (inst $Op1, $Op2)>;
467 class SVE_2_Op_Pred_All_Active<ValueType vtd, SDPatternOperator op,
468                                ValueType pt, ValueType vt1, ValueType vt2,
469                                Instruction inst>
470 : Pat<(vtd (op (pt (SVEAllActive)), vt1:$Op1, vt2:$Op2)),
471       (inst $Op1, $Op2)>;
473 class SVE_2_Op_Pred_All_Active_Pt<ValueType vtd, SDPatternOperator op,
474                                   ValueType pt, ValueType vt1, ValueType vt2,
475                                   Instruction inst>
476 : Pat<(vtd (op (pt (SVEAllActive:$Op1)), vt1:$Op2, vt2:$Op3)),
477       (inst $Op1, $Op2, $Op3)>;
479 class SVE_2_Op_Pred_Any_Predicate<ValueType vtd, SDPatternOperator op,
480                                   ValueType pt, ValueType vt1, ValueType vt2,
481                                   Instruction inst>
482 : Pat<(vtd (op (pt (SVEAnyPredicate)), vt1:$Op1, vt2:$Op2)),
483       (inst $Op1, $Op2)>;
485 class SVE_3_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
486                    ValueType vt2, ValueType vt3, Instruction inst>
487 : Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3)),
488       (inst $Op1, $Op2, $Op3)>;
490 multiclass SVE_3_Op_Undef_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
491                               ValueType vt2, ValueType vt3, Instruction inst> {
492   def : Pat<(vtd (op (vt1 undef), vt2:$Op1, vt3:$Op2)),
493             (inst (IMPLICIT_DEF), $Op1, $Op2)>;
494   def : Pat<(vtd (op vt1:$Op1, (vt2 (SVEAllActive:$Op2)), vt3:$Op3)),
495             (inst $Op1, $Op2, $Op3)>;
498 class SVE_4_Op_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
499                    ValueType vt2, ValueType vt3, ValueType vt4,
500                    Instruction inst>
501 : Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3, vt4:$Op4)),
502       (inst $Op1, $Op2, $Op3, $Op4)>;
504 class SVE_2_Op_Imm_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
505                        ValueType vt2, Operand ImmTy, Instruction inst>
506 : Pat<(vtd (op vt1:$Op1, (vt2 ImmTy:$Op2))),
507       (inst $Op1, ImmTy:$Op2)>;
509 multiclass SVE2p1_Cntp_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
510                            Instruction inst> {
511   def : Pat<(vtd (op vt1:$Op1, (i32 2))), (inst $Op1, 0)>;
512   def : Pat<(vtd (op vt1:$Op1, (i32 4))), (inst $Op1, 1)>;
515 multiclass SVE2p1_While_PN_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
516                                Instruction inst> {
517   def : Pat<(vtd (op vt1:$Op1, vt1:$Op2, (i32 2))), (inst $Op1, $Op2, 0)>;
518   def : Pat<(vtd (op vt1:$Op1, vt1:$Op2, (i32 4))), (inst $Op1, $Op2, 1)>;
521 class SVE_3_Op_Imm_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
522                        ValueType vt2, ValueType vt3, Operand ImmTy,
523                        Instruction inst>
524 : Pat<(vtd (op vt1:$Op1, vt2:$Op2, (vt3 ImmTy:$Op3))),
525       (inst $Op1, $Op2, ImmTy:$Op3)>;
527 class SVE_4_Op_Imm_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
528                        ValueType vt2, ValueType vt3, ValueType vt4,
529                        Operand ImmTy, Instruction inst>
530 : Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3, (vt4 ImmTy:$Op4))),
531       (inst $Op1, $Op2, $Op3, ImmTy:$Op4)>;
533 def SVEDup0Undef : ComplexPattern<vAny, 0, "SelectDupZeroOrUndef", []>;
535 let AddedComplexity = 1 in {
536 class SVE_3_Op_Pat_SelZero<ValueType vtd, SDPatternOperator op, ValueType vt1,
537                    ValueType vt2, ValueType vt3, Instruction inst>
538 : Pat<(vtd (vtd (op vt1:$Op1, (vselect vt1:$Op1, vt2:$Op2, (SVEDup0)), vt3:$Op3))),
539       (inst $Op1, $Op2, $Op3)>;
541 class SVE_3_Op_Pat_Shift_Imm_SelZero<ValueType vtd, SDPatternOperator op,
542                                      ValueType vt1, ValueType vt2,
543                                      Operand vt3, Instruction inst>
544 : Pat<(vtd (op vt1:$Op1, (vselect vt1:$Op1, vt2:$Op2, (SVEDup0)), (i32 (vt3:$Op3)))),
545       (inst $Op1, $Op2, vt3:$Op3)>;
549 // Common but less generic patterns.
552 class SVE_1_Op_AllActive_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
553                              Instruction inst, Instruction ptrue>
554 : Pat<(vtd (op vt1:$Op1)),
555       (inst (IMPLICIT_DEF), (ptrue 31), $Op1)>;
557 class 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)>;
562 class 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)>;
567 multiclass 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)>;
575 class 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)>;
581 class 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)>;
587 class 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)>;
593 class 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)>;
600 class 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)>;
608 // Used to re-order the operands of BSP when lowering to BSL. BSP has the order:
609 // mask, in1, in2 whereas BSL for SVE2 has them ordered in1, in2, mask
610 class SVE_3_Op_BSP_Pat<ValueType vtd, SDPatternOperator op, ValueType vt1,
611                    ValueType vt2, ValueType vt3, Instruction inst>
612 : Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3)),
613       (inst $Op2, $Op3, $Op1)>;
615 class SVE_Shift_Add_All_Active_Pat<ValueType vtd, SDPatternOperator op, ValueType pt,
616                                    ValueType vt1, ValueType vt2, ValueType vt3,
617                                    Instruction inst>
618 : Pat<(vtd (add vt1:$Op1, (op (pt (SVEAllActive)), vt2:$Op2, vt3:$Op3))),
619       (inst $Op1, $Op2, $Op3)>;
621 class SVE2p1_Sat_Shift_VG2_Pat<string name, SDPatternOperator intrinsic, ValueType out_vt, ValueType in_vt, Operand imm_ty>
622     : Pat<(out_vt (intrinsic in_vt:$Zn1, in_vt:$Zn2, (i32 imm_ty:$i))),
623                   (!cast<Instruction>(name) (REG_SEQUENCE ZPR2Mul2, in_vt:$Zn1, zsub0, in_vt:$Zn2, zsub1), imm_ty:$i)>;
625 class SVE2p1_Cvt_VG2_Pat<string name, SDPatternOperator intrinsic, ValueType out_vt, ValueType in_vt>
626     : Pat<(out_vt (intrinsic in_vt:$Zn1, in_vt:$Zn2)),
627                   (!cast<Instruction>(name) (REG_SEQUENCE ZPR2Mul2, in_vt:$Zn1, zsub0, in_vt:$Zn2, zsub1))>;
629 //===----------------------------------------------------------------------===//
630 // SVE pattern match helpers.
631 //===----------------------------------------------------------------------===//
633 // Matches either an intrinsic, or a predicated operation with an all active predicate
634 class VSelectPredOrPassthruPatFrags<SDPatternOperator intrinsic, SDPatternOperator sdnode>
635 : PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [
636     (intrinsic node:$Pg, node:$Op1, node:$Op2),
637     (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op1, node:$Op2), node:$Op1),
638   ], [{
639     return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse();
640   }]>;
641 // Same as above with a commutative operation
642 class VSelectCommPredOrPassthruPatFrags<SDPatternOperator intrinsic, SDPatternOperator sdnode>
643 : PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [
644     (intrinsic node:$Pg, node:$Op1, node:$Op2),
645     (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op1, node:$Op2), node:$Op1),
646     (vselect node:$Pg, (sdnode (SVEAllActive), node:$Op2, node:$Op1), node:$Op1),
647   ], [{
648     return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse();
649   }]>;
650 // Similarly matches either an intrinsic, or an unpredicated operation with a select
651 class VSelectUnpredOrPassthruPatFrags<SDPatternOperator intrinsic, SDPatternOperator sdnode>
652 : PatFrags<(ops node:$Pg, node:$Op1, node:$Op2), [
653     (intrinsic node:$Pg, node:$Op1, node:$Op2),
654     (vselect node:$Pg, (sdnode node:$Op1, node:$Op2), node:$Op1),
655   ], [{
656     return N->getOpcode() != ISD::VSELECT || N->getOperand(1).hasOneUse();
657   }]>;
660 // Pseudo -> Instruction mappings
662 def getSVEPseudoMap : InstrMapping {
663   let FilterClass = "SVEPseudo2Instr";
664   let RowFields = ["PseudoName"];
665   let ColFields = ["IsInstr"];
666   let KeyCol = ["0"];
667   let ValueCols = [["1"]];
670 class SVEPseudo2Instr<string name, bit instr> {
671   string PseudoName = name;
672   bit IsInstr = instr;
675 // Lookup e.g. DIV -> DIVR
676 def getSVERevInstr : InstrMapping {
677   let FilterClass = "SVEInstr2Rev";
678   let RowFields = ["InstrName"];
679   let ColFields = ["isReverseInstr"];
680   let KeyCol = ["0"];
681   let ValueCols = [["1"]];
684 // Lookup e.g. DIVR -> DIV
685 def getSVENonRevInstr : InstrMapping {
686   let FilterClass = "SVEInstr2Rev";
687   let RowFields = ["InstrName"];
688   let ColFields = ["isReverseInstr"];
689   let KeyCol = ["1"];
690   let ValueCols = [["0"]];
693 class SVEInstr2Rev<string name1, string name2, bit name1IsReverseInstr> {
694   string InstrName = !if(name1IsReverseInstr, name1, name2);
695   bit isReverseInstr = name1IsReverseInstr;
699 // Pseudos for destructive operands
701 let hasNoSchedulingInfo = 1 in {
702   class PredTwoOpPseudo<string name, ZPRRegOp zprty,
703                         FalseLanesEnum flags = FalseLanesNone>
704   : SVEPseudo2Instr<name, 0>,
705     Pseudo<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zs1, zprty:$Zs2), []> {
706     let FalseLanes = flags;
707   }
709   class PredTwoOpImmPseudo<string name, ZPRRegOp zprty, Operand immty,
710                            FalseLanesEnum flags = FalseLanesNone>
711   : SVEPseudo2Instr<name, 0>,
712     Pseudo<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zs1, immty:$imm), []> {
713     let FalseLanes = flags;
714   }
716   class PredThreeOpPseudo<string name, ZPRRegOp zprty,
717                           FalseLanesEnum flags = FalseLanesNone>
718   : SVEPseudo2Instr<name, 0>,
719     Pseudo<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zs1, zprty:$Zs2, zprty:$Zs3), []> {
720     let FalseLanes = flags;
721   }
725 // Pseudos for passthru operands
727 let hasNoSchedulingInfo = 1 in {
728   class PredOneOpPassthruPseudo<string name, ZPRRegOp zprty,
729                                 FalseLanesEnum flags = FalseLanesNone>
730   : SVEPseudo2Instr<name, 0>,
731     Pseudo<(outs zprty:$Zd), (ins zprty:$Passthru, PPR3bAny:$Pg, zprty:$Zs), []> {
732     let FalseLanes = flags;
733     let Constraints = !if(!eq(flags, FalseLanesZero), "$Zd = $Passthru,@earlyclobber $Zd", "");
734   }
737 //===----------------------------------------------------------------------===//
738 // SVE Predicate Misc Group
739 //===----------------------------------------------------------------------===//
741 class sve_int_pfalse<bits<6> opc, string asm>
742 : I<(outs PPR8:$Pd), (ins),
743   asm, "\t$Pd",
744   "",
745   []>, Sched<[]> {
746   bits<4> Pd;
747   let Inst{31-24} = 0b00100101;
748   let Inst{23-22} = opc{5-4};
749   let Inst{21-19} = 0b011;
750   let Inst{18-16} = opc{3-1};
751   let Inst{15-10} = 0b111001;
752   let Inst{9}     = opc{0};
753   let Inst{8-4}   = 0b00000;
754   let Inst{3-0}   = Pd;
756   let hasSideEffects = 0;
757   let isReMaterializable = 1;
760 multiclass sve_int_pfalse<bits<6> opc, string asm> {
761   def NAME : sve_int_pfalse<opc, asm>;
763   def : Pat<(nxv16i1 immAllZerosV), (!cast<Instruction>(NAME))>;
764   def : Pat<(nxv8i1 immAllZerosV), (!cast<Instruction>(NAME))>;
765   def : Pat<(nxv4i1 immAllZerosV), (!cast<Instruction>(NAME))>;
766   def : Pat<(nxv2i1 immAllZerosV), (!cast<Instruction>(NAME))>;
767   def : Pat<(nxv1i1 immAllZerosV), (!cast<Instruction>(NAME))>;
770 class sve_int_ptest<bits<6> opc, string asm, SDPatternOperator op>
771 : I<(outs), (ins PPRAny:$Pg, PPR8:$Pn),
772   asm, "\t$Pg, $Pn",
773   "",
774   [(op (nxv16i1 PPRAny:$Pg), (nxv16i1 PPR8:$Pn))]>, Sched<[]> {
775   bits<4> Pg;
776   bits<4> Pn;
777   let Inst{31-24} = 0b00100101;
778   let Inst{23-22} = opc{5-4};
779   let Inst{21-19} = 0b010;
780   let Inst{18-16} = opc{3-1};
781   let Inst{15-14} = 0b11;
782   let Inst{13-10} = Pg;
783   let Inst{9}     = opc{0};
784   let Inst{8-5}   = Pn;
785   let Inst{4-0}   = 0b00000;
787   let Defs = [NZCV];
788   let hasSideEffects = 0;
789   let isCompare = 1;
792 multiclass sve_int_ptest<bits<6> opc, string asm, SDPatternOperator op,
793                          SDPatternOperator op_any> {
794   def NAME : sve_int_ptest<opc, asm, op>;
796   let hasNoSchedulingInfo = 1, isCompare = 1, Defs = [NZCV] in {
797   def _ANY : Pseudo<(outs), (ins PPRAny:$Pg, PPR8:$Pn),
798                     [(op_any (nxv16i1 PPRAny:$Pg), (nxv16i1 PPR8:$Pn))]>,
799              PseudoInstExpansion<(!cast<Instruction>(NAME) PPRAny:$Pg, PPR8:$Pn)>;
800   }
803 class sve_int_pfirst_next<bits<2> sz8_64, bits<5> opc, string asm,
804                           PPRRegOp pprty>
805 : I<(outs pprty:$Pdn), (ins PPRAny:$Pg, pprty:$_Pdn),
806   asm, "\t$Pdn, $Pg, $_Pdn",
807   "",
808   []>, Sched<[]> {
809   bits<4> Pdn;
810   bits<4> Pg;
811   let Inst{31-24} = 0b00100101;
812   let Inst{23-22} = sz8_64;
813   let Inst{21-19} = 0b011;
814   let Inst{18-16} = opc{4-2};
815   let Inst{15-11} = 0b11000;
816   let Inst{10-9}  = opc{1-0};
817   let Inst{8-5}   = Pg;
818   let Inst{4}     = 0;
819   let Inst{3-0}   = Pdn;
821   let Constraints = "$Pdn = $_Pdn";
822   let Defs = [NZCV];
823   let ElementSize = pprty.ElementSize;
824   let hasSideEffects = 0;
825   let isPTestLike = 1;
828 multiclass sve_int_pfirst<bits<5> opc, string asm, SDPatternOperator op> {
829   def _B : sve_int_pfirst_next<0b01, opc, asm, PPR8>;
831   def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME # _B)>;
834 multiclass sve_int_pnext<bits<5> opc, string asm, SDPatternOperator op> {
835   def _B : sve_int_pfirst_next<0b00, opc, asm, PPR8>;
836   def _H : sve_int_pfirst_next<0b01, opc, asm, PPR16>;
837   def _S : sve_int_pfirst_next<0b10, opc, asm, PPR32>;
838   def _D : sve_int_pfirst_next<0b11, opc, asm, PPR64>;
840   def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME # _B)>;
841   def : SVE_2_Op_Pat<nxv8i1, op, nxv8i1, nxv8i1, !cast<Instruction>(NAME # _H)>;
842   def : SVE_2_Op_Pat<nxv4i1, op, nxv4i1, nxv4i1, !cast<Instruction>(NAME # _S)>;
843   def : SVE_2_Op_Pat<nxv2i1, op, nxv2i1, nxv2i1, !cast<Instruction>(NAME # _D)>;
846 //===----------------------------------------------------------------------===//
847 // SVE Predicate Count Group
848 //===----------------------------------------------------------------------===//
850 class sve_int_count_r<bits<2> sz8_64, bits<5> opc, string asm,
851                       RegisterOperand dty, PPRRegOp pprty, RegisterOperand sty>
852 : I<(outs dty:$Rdn), (ins pprty:$Pg, sty:$_Rdn),
853   asm, "\t$Rdn, $Pg",
854   "",
855   []>, Sched<[]> {
856   bits<5> Rdn;
857   bits<4> Pg;
858   let Inst{31-24} = 0b00100101;
859   let Inst{23-22} = sz8_64;
860   let Inst{21-19} = 0b101;
861   let Inst{18-16} = opc{4-2};
862   let Inst{15-11} = 0b10001;
863   let Inst{10-9}  = opc{1-0};
864   let Inst{8-5}   = Pg;
865   let Inst{4-0}   = Rdn;
867   // Signed 32bit forms require their GPR operand printed.
868   let AsmString = !if(!eq(opc{4,2-0}, 0b0000),
869                       !strconcat(asm, "\t$Rdn, $Pg, $_Rdn"),
870                       !strconcat(asm, "\t$Rdn, $Pg"));
871   let Constraints = "$Rdn = $_Rdn";
872   let hasSideEffects = 0;
875 multiclass sve_int_count_r_s32<bits<5> opc, string asm,
876                                SDPatternOperator op> {
877   def _B : sve_int_count_r<0b00, opc, asm, GPR64z, PPR8, GPR64as32>;
878   def _H : sve_int_count_r<0b01, opc, asm, GPR64z, PPR16, GPR64as32>;
879   def _S : sve_int_count_r<0b10, opc, asm, GPR64z, PPR32, GPR64as32>;
880   def _D : sve_int_count_r<0b11, opc, asm, GPR64z, PPR64, GPR64as32>;
882   def : Pat<(i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))),
883             (EXTRACT_SUBREG (!cast<Instruction>(NAME # _B) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
884   def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))))),
885             (!cast<Instruction>(NAME # _B) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
887   def : Pat<(i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))),
888             (EXTRACT_SUBREG (!cast<Instruction>(NAME # _H) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
889   def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))))),
890             (!cast<Instruction>(NAME # _H) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
892   def : Pat<(i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))),
893             (EXTRACT_SUBREG (!cast<Instruction>(NAME # _S) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
894   def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))))),
895             (!cast<Instruction>(NAME # _S) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
897   def : Pat<(i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))),
898             (EXTRACT_SUBREG (!cast<Instruction>(NAME # _D) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32)), sub_32)>;
899   def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))))),
900             (!cast<Instruction>(NAME # _D) PPRAny:$Pg, (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32))>;
903 multiclass sve_int_count_r_u32<bits<5> opc, string asm,
904                                SDPatternOperator op> {
905   def _B : sve_int_count_r<0b00, opc, asm, GPR32z, PPR8, GPR32z>;
906   def _H : sve_int_count_r<0b01, opc, asm, GPR32z, PPR16, GPR32z>;
907   def _S : sve_int_count_r<0b10, opc, asm, GPR32z, PPR32, GPR32z>;
908   def _D : sve_int_count_r<0b11, opc, asm, GPR32z, PPR64, GPR32z>;
910   def : Pat<(i32 (op GPR32:$Rn, (nxv16i1 PPRAny:$Pg))),
911             (!cast<Instruction>(NAME # _B) PPRAny:$Pg, $Rn)>;
912   def : Pat<(i32 (op GPR32:$Rn, (nxv8i1 PPRAny:$Pg))),
913             (!cast<Instruction>(NAME # _H) PPRAny:$Pg, $Rn)>;
914   def : Pat<(i32 (op GPR32:$Rn, (nxv4i1 PPRAny:$Pg))),
915             (!cast<Instruction>(NAME # _S) PPRAny:$Pg, $Rn)>;
916   def : Pat<(i32 (op GPR32:$Rn, (nxv2i1 PPRAny:$Pg))),
917             (!cast<Instruction>(NAME # _D) PPRAny:$Pg, $Rn)>;
920 multiclass sve_int_count_r_x64<bits<5> opc, string asm,
921                                SDPatternOperator op,
922                                SDPatternOperator combine_op = null_frag> {
923   def _B : sve_int_count_r<0b00, opc, asm, GPR64z, PPR8, GPR64z>;
924   def _H : sve_int_count_r<0b01, opc, asm, GPR64z, PPR16, GPR64z>;
925   def _S : sve_int_count_r<0b10, opc, asm, GPR64z, PPR32, GPR64z>;
926   def _D : sve_int_count_r<0b11, opc, asm, GPR64z, PPR64, GPR64z>;
928   def : Pat<(i64 (op GPR64:$Rn, (nxv16i1 PPRAny:$Pg))),
929             (!cast<Instruction>(NAME # _B) PPRAny:$Pg, $Rn)>;
930   def : Pat<(i64 (op GPR64:$Rn, (nxv8i1 PPRAny:$Pg))),
931             (!cast<Instruction>(NAME # _H) PPRAny:$Pg, $Rn)>;
932   def : Pat<(i64 (op GPR64:$Rn, (nxv4i1 PPRAny:$Pg))),
933             (!cast<Instruction>(NAME # _S) PPRAny:$Pg, $Rn)>;
934   def : Pat<(i64 (op GPR64:$Rn, (nxv2i1 PPRAny:$Pg))),
935             (!cast<Instruction>(NAME # _D) PPRAny:$Pg, $Rn)>;
937   // combine_op(x, cntp(all_active, p)) ==> inst p, x
938   def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv16i1 (SVEAllActive)), (nxv16i1 PPRAny:$pred)))),
939             (!cast<Instruction>(NAME # _B) PPRAny:$pred, $Rn)>;
940   def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv8i1 (SVEAllActive)), (nxv8i1 PPRAny:$pred)))),
941             (!cast<Instruction>(NAME # _H) PPRAny:$pred, $Rn)>;
942   def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv4i1 (SVEAllActive)), (nxv4i1 PPRAny:$pred)))),
943             (!cast<Instruction>(NAME # _S) PPRAny:$pred, $Rn)>;
944   def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv2i1 (SVEAllActive)), (nxv2i1 PPRAny:$pred)))),
945             (!cast<Instruction>(NAME # _D) PPRAny:$pred, $Rn)>;
947   // combine_op(x, cntp(p, p)) ==> inst p, x
948   def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv16i1 PPRAny:$pred), (nxv16i1 PPRAny:$pred)))),
949             (!cast<Instruction>(NAME # _B) PPRAny:$pred, $Rn)>;
950   def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv8i1 PPRAny:$pred), (nxv8i1 PPRAny:$pred)))),
951             (!cast<Instruction>(NAME # _H) PPRAny:$pred, $Rn)>;
952   def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv4i1 PPRAny:$pred), (nxv4i1 PPRAny:$pred)))),
953             (!cast<Instruction>(NAME # _S) PPRAny:$pred, $Rn)>;
954   def : Pat<(i64 (combine_op GPR64:$Rn, (int_aarch64_sve_cntp_oneuse (nxv2i1 PPRAny:$pred), (nxv2i1 PPRAny:$pred)))),
955             (!cast<Instruction>(NAME # _D) PPRAny:$pred, $Rn)>;
957   // combine_op(x, trunc(cntp(all_active, p))) ==> inst p, x
958   def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv16i1 (SVEAllActive)), (nxv16i1 PPRAny:$pred))))),
959             (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _B) PPRAny:$pred,
960                                      (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
961                                  sub_32))>;
962   def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv8i1 (SVEAllActive)), (nxv8i1 PPRAny:$pred))))),
963             (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _H) PPRAny:$pred,
964                                      (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
965                                  sub_32))>;
966   def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv4i1 (SVEAllActive)), (nxv4i1 PPRAny:$pred))))),
967             (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _S) PPRAny:$pred,
968                                      (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
969                                  sub_32))>;
970   def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv2i1 (SVEAllActive)), (nxv2i1 PPRAny:$pred))))),
971             (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _D) PPRAny:$pred,
972                                      (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
973                                  sub_32))>;
975   // combine_op(x, trunc(cntp(p, p))) ==> inst p, x
976   def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv16i1 PPRAny:$pred), (nxv16i1 PPRAny:$pred))))),
977             (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _B) PPRAny:$pred,
978                                      (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
979                                  sub_32))>;
980   def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv8i1 PPRAny:$pred), (nxv8i1 PPRAny:$pred))))),
981             (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _H) PPRAny:$pred,
982                                      (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
983                                  sub_32))>;
984   def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv4i1 PPRAny:$pred), (nxv4i1 PPRAny:$pred))))),
985             (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _S) PPRAny:$pred,
986                                      (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
987                                  sub_32))>;
988   def : Pat<(i32 (combine_op GPR32:$Rn, (trunc (int_aarch64_sve_cntp_oneuse (nxv2i1 PPRAny:$pred), (nxv2i1 PPRAny:$pred))))),
989             (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME # _D) PPRAny:$pred,
990                                      (INSERT_SUBREG (i64 (IMPLICIT_DEF)), GPR32:$Rn, sub_32)),
991                                  sub_32))>;
994 class sve_int_count_v<bits<2> sz8_64, bits<5> opc, string asm,
995                       ZPRRegOp zprty, PPRRegOp pprty>
996 : I<(outs zprty:$Zdn), (ins zprty:$_Zdn, pprty:$Pm),
997   asm, "\t$Zdn, $Pm",
998   "",
999   []>, Sched<[]> {
1000   bits<4> Pm;
1001   bits<5> Zdn;
1002   let Inst{31-24} = 0b00100101;
1003   let Inst{23-22} = sz8_64;
1004   let Inst{21-19} = 0b101;
1005   let Inst{18-16} = opc{4-2};
1006   let Inst{15-11} = 0b10000;
1007   let Inst{10-9}  = opc{1-0};
1008   let Inst{8-5}   = Pm;
1009   let Inst{4-0}   = Zdn;
1011   let Constraints = "$Zdn = $_Zdn";
1012   let DestructiveInstType = DestructiveOther;
1013   let ElementSize = ElementSizeNone;
1014   let hasSideEffects = 0;
1017 multiclass sve_int_count_v<bits<5> opc, string asm,
1018                            SDPatternOperator op = null_frag> {
1019   def _H : sve_int_count_v<0b01, opc, asm, ZPR16, PPR16>;
1020   def _S : sve_int_count_v<0b10, opc, asm, ZPR32, PPR32>;
1021   def _D : sve_int_count_v<0b11, opc, asm, ZPR64, PPR64>;
1023   def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16,  nxv8i1, !cast<Instruction>(NAME # _H)>;
1024   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32,  nxv4i1, !cast<Instruction>(NAME # _S)>;
1025   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64,  nxv2i1, !cast<Instruction>(NAME # _D)>;
1027   def : InstAlias<asm # "\t$Zdn, $Pm",
1028                  (!cast<Instruction>(NAME # "_H") ZPR16:$Zdn, PPRAny:$Pm), 0>;
1029   def : InstAlias<asm # "\t$Zdn, $Pm",
1030                  (!cast<Instruction>(NAME # "_S") ZPR32:$Zdn, PPRAny:$Pm), 0>;
1031   def : InstAlias<asm # "\t$Zdn, $Pm",
1032                   (!cast<Instruction>(NAME # "_D") ZPR64:$Zdn, PPRAny:$Pm), 0>;
1035 class sve_int_pcount_pred<bits<2> sz8_64, bits<4> opc, string asm,
1036                           PPRRegOp pprty>
1037 : I<(outs GPR64:$Rd), (ins PPRAny:$Pg, pprty:$Pn),
1038   asm, "\t$Rd, $Pg, $Pn",
1039   "",
1040   []>, Sched<[]> {
1041   bits<4> Pg;
1042   bits<4> Pn;
1043   bits<5> Rd;
1044   let Inst{31-24} = 0b00100101;
1045   let Inst{23-22} = sz8_64;
1046   let Inst{21-19} = 0b100;
1047   let Inst{18-16} = opc{3-1};
1048   let Inst{15-14} = 0b10;
1049   let Inst{13-10} = Pg;
1050   let Inst{9}     = opc{0};
1051   let Inst{8-5}   = Pn;
1052   let Inst{4-0}   = Rd;
1054   let hasSideEffects = 0;
1057 multiclass sve_int_pcount_pred<bits<4> opc, string asm,
1058                                SDPatternOperator int_op> {
1059   def _B : sve_int_pcount_pred<0b00, opc, asm, PPR8>;
1060   def _H : sve_int_pcount_pred<0b01, opc, asm, PPR16>;
1061   def _S : sve_int_pcount_pred<0b10, opc, asm, PPR32>;
1062   def _D : sve_int_pcount_pred<0b11, opc, asm, PPR64>;
1064   def : SVE_2_Op_Pat<i64, int_op, nxv16i1, nxv16i1, !cast<Instruction>(NAME # _B)>;
1065   def : SVE_2_Op_Pat<i64, int_op, nxv8i1,  nxv8i1,  !cast<Instruction>(NAME # _H)>;
1066   def : SVE_2_Op_Pat<i64, int_op, nxv4i1,  nxv4i1,  !cast<Instruction>(NAME # _S)>;
1067   def : SVE_2_Op_Pat<i64, int_op, nxv2i1,  nxv2i1,  !cast<Instruction>(NAME # _D)>;
1070 //===----------------------------------------------------------------------===//
1071 // SVE Element Count Group
1072 //===----------------------------------------------------------------------===//
1074 class sve_int_count<bits<3> opc, string asm>
1075 : I<(outs GPR64:$Rd), (ins sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1076   asm, "\t$Rd, $pattern, mul $imm4",
1077   "",
1078   []>, Sched<[]> {
1079   bits<5> Rd;
1080   bits<4> imm4;
1081   bits<5> pattern;
1082   let Inst{31-24} = 0b00000100;
1083   let Inst{23-22} = opc{2-1};
1084   let Inst{21-20} = 0b10;
1085   let Inst{19-16} = imm4;
1086   let Inst{15-11} = 0b11100;
1087   let Inst{10}    = opc{0};
1088   let Inst{9-5}   = pattern;
1089   let Inst{4-0}   = Rd;
1091   let hasSideEffects = 0;
1092   let isReMaterializable = 1;
1095 multiclass sve_int_count<bits<3> opc, string asm, SDPatternOperator op> {
1096   def NAME : sve_int_count<opc, asm>;
1098   def : InstAlias<asm # "\t$Rd, $pattern",
1099                   (!cast<Instruction>(NAME) GPR64:$Rd, sve_pred_enum:$pattern, 1), 1>;
1100   def : InstAlias<asm # "\t$Rd",
1101                   (!cast<Instruction>(NAME) GPR64:$Rd, 0b11111, 1), 2>;
1103   def : Pat<(i64 (mul (op sve_pred_enum:$pattern), (sve_cnt_mul_imm_i64 i32:$imm))),
1104             (!cast<Instruction>(NAME) sve_pred_enum:$pattern, sve_incdec_imm:$imm)>;
1106   def : Pat<(i64 (shl (op sve_pred_enum:$pattern), (sve_cnt_shl_imm i32:$imm))),
1107             (!cast<Instruction>(NAME) sve_pred_enum:$pattern, sve_incdec_imm:$imm)>;
1109   def : Pat<(i64 (op sve_pred_enum:$pattern)),
1110             (!cast<Instruction>(NAME) sve_pred_enum:$pattern, 1)>;
1113 class sve_int_countvlv<bits<5> opc, string asm, ZPRRegOp zprty>
1114 : I<(outs zprty:$Zdn), (ins zprty:$_Zdn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1115   asm, "\t$Zdn, $pattern, mul $imm4",
1116   "",
1117   []>, Sched<[]> {
1118   bits<5> Zdn;
1119   bits<5> pattern;
1120   bits<4> imm4;
1121   let Inst{31-24} = 0b00000100;
1122   let Inst{23-22} = opc{4-3};
1123   let Inst{21}    = 0b1;
1124   let Inst{20}    = opc{2};
1125   let Inst{19-16} = imm4;
1126   let Inst{15-12} = 0b1100;
1127   let Inst{11-10} = opc{1-0};
1128   let Inst{9-5}   = pattern;
1129   let Inst{4-0}   = Zdn;
1131   let Constraints = "$Zdn = $_Zdn";
1132   let DestructiveInstType = DestructiveOther;
1133   let ElementSize = ElementSizeNone;
1134   let hasSideEffects = 0;
1137 multiclass sve_int_countvlv<bits<5> opc, string asm, ZPRRegOp zprty,
1138                             SDPatternOperator op = null_frag,
1139                             ValueType vt = OtherVT> {
1140   def NAME : sve_int_countvlv<opc, asm, zprty>;
1142   def : InstAlias<asm # "\t$Zdn, $pattern",
1143                   (!cast<Instruction>(NAME) zprty:$Zdn, sve_pred_enum:$pattern, 1), 1>;
1144   def : InstAlias<asm # "\t$Zdn",
1145                   (!cast<Instruction>(NAME) zprty:$Zdn, 0b11111, 1), 2>;
1147   def : Pat<(vt (op (vt zprty:$Zn), (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1148             (!cast<Instruction>(NAME) $Zn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1151 class sve_int_pred_pattern_a<bits<3> opc, string asm>
1152 : I<(outs GPR64:$Rdn), (ins GPR64:$_Rdn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1153   asm, "\t$Rdn, $pattern, mul $imm4",
1154   "",
1155   []>, Sched<[]> {
1156   bits<5> Rdn;
1157   bits<5> pattern;
1158   bits<4> imm4;
1159   let Inst{31-24} = 0b00000100;
1160   let Inst{23-22} = opc{2-1};
1161   let Inst{21-20} = 0b11;
1162   let Inst{19-16} = imm4;
1163   let Inst{15-11} = 0b11100;
1164   let Inst{10}    = opc{0};
1165   let Inst{9-5}   = pattern;
1166   let Inst{4-0}   = Rdn;
1168   let Constraints = "$Rdn = $_Rdn";
1169   let hasSideEffects = 0;
1172 multiclass sve_int_pred_pattern_a<bits<3> opc, string asm,
1173                                   SDPatternOperator op,
1174                                   SDPatternOperator opcnt> {
1175   let Predicates = [HasSVEorSME] in {
1176     def NAME : sve_int_pred_pattern_a<opc, asm>;
1178     def : InstAlias<asm # "\t$Rdn, $pattern",
1179                     (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, 1), 1>;
1180     def : InstAlias<asm # "\t$Rdn",
1181                     (!cast<Instruction>(NAME) GPR64:$Rdn, 0b11111, 1), 2>;
1182   }
1184   let Predicates = [HasSVEorSME, UseScalarIncVL] in {
1185     def : Pat<(i64 (op GPR64:$Rdn, (opcnt sve_pred_enum:$pattern))),
1186               (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, 1)>;
1188     def : Pat<(i64 (op GPR64:$Rdn, (mul (opcnt sve_pred_enum:$pattern), (sve_cnt_mul_imm_i64 i32:$imm)))),
1189               (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, $imm)>;
1191     def : Pat<(i64 (op GPR64:$Rdn, (shl (opcnt sve_pred_enum:$pattern), (sve_cnt_shl_imm i32:$imm)))),
1192               (!cast<Instruction>(NAME) GPR64:$Rdn, sve_pred_enum:$pattern, $imm)>;
1194     def : Pat<(i32 (op GPR32:$Rdn, (i32 (trunc (opcnt (sve_pred_enum:$pattern)))))),
1195               (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
1196                                                GPR32:$Rdn, sub_32), sve_pred_enum:$pattern, 1),
1197                                     sub_32))>;
1199     def : Pat<(i32 (op GPR32:$Rdn, (mul (i32 (trunc (opcnt (sve_pred_enum:$pattern)))), (sve_cnt_mul_imm_i32 i32:$imm)))),
1200               (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
1201                                                GPR32:$Rdn, sub_32), sve_pred_enum:$pattern, $imm),
1202                                     sub_32))>;
1204     def : Pat<(i32 (op GPR32:$Rdn, (shl (i32 (trunc (opcnt (sve_pred_enum:$pattern)))), (sve_cnt_shl_imm i32:$imm)))),
1205               (i32 (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (i64 (IMPLICIT_DEF)),
1206                                                GPR32:$Rdn, sub_32), sve_pred_enum:$pattern, $imm),
1207                                     sub_32))>;
1208   }
1211 class sve_int_pred_pattern_b<bits<5> opc, string asm, RegisterOperand dt,
1212                              RegisterOperand st>
1213 : I<(outs dt:$Rdn), (ins st:$_Rdn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4),
1214   asm, "\t$Rdn, $pattern, mul $imm4",
1215   "",
1216   []>, Sched<[]> {
1217   bits<5> Rdn;
1218   bits<5> pattern;
1219   bits<4> imm4;
1220   let Inst{31-24} = 0b00000100;
1221   let Inst{23-22} = opc{4-3};
1222   let Inst{21}    = 0b1;
1223   let Inst{20}    = opc{2};
1224   let Inst{19-16} = imm4;
1225   let Inst{15-12} = 0b1111;
1226   let Inst{11-10} = opc{1-0};
1227   let Inst{9-5}   = pattern;
1228   let Inst{4-0}   = Rdn;
1230   // Signed 32bit forms require their GPR operand printed.
1231   let AsmString = !if(!eq(opc{2,0}, 0b00),
1232                       !strconcat(asm, "\t$Rdn, $_Rdn, $pattern, mul $imm4"),
1233                       !strconcat(asm, "\t$Rdn, $pattern, mul $imm4"));
1235   let Constraints = "$Rdn = $_Rdn";
1236   let hasSideEffects = 0;
1239 multiclass sve_int_pred_pattern_b_s32<bits<5> opc, string asm,
1240                                       SDPatternOperator op> {
1241   def NAME : sve_int_pred_pattern_b<opc, asm, GPR64z, GPR64as32>;
1243   def : InstAlias<asm # "\t$Rd, $Rn, $pattern",
1244                   (!cast<Instruction>(NAME) GPR64z:$Rd, GPR64as32:$Rn, sve_pred_enum:$pattern, 1), 1>;
1245   def : InstAlias<asm # "\t$Rd, $Rn",
1246                   (!cast<Instruction>(NAME) GPR64z:$Rd, GPR64as32:$Rn, 0b11111, 1), 2>;
1248   // NOTE: Register allocation doesn't like tied operands of differing register
1249   //       class, hence the extra INSERT_SUBREG complication.
1251   def : Pat<(i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1252             (EXTRACT_SUBREG (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32), sve_pred_enum:$pattern, sve_incdec_imm:$imm4), sub_32)>;
1253   def : Pat<(i64 (sext (i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))))),
1254             (!cast<Instruction>(NAME) (INSERT_SUBREG (IMPLICIT_DEF), $Rn, sub_32), sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1257 multiclass sve_int_pred_pattern_b_u32<bits<5> opc, string asm,
1258                                       SDPatternOperator op> {
1259   def NAME : sve_int_pred_pattern_b<opc, asm, GPR32z, GPR32z>;
1261   def : InstAlias<asm # "\t$Rdn, $pattern",
1262                   (!cast<Instruction>(NAME) GPR32z:$Rdn, sve_pred_enum:$pattern, 1), 1>;
1263   def : InstAlias<asm # "\t$Rdn",
1264                   (!cast<Instruction>(NAME) GPR32z:$Rdn, 0b11111, 1), 2>;
1266   def : Pat<(i32 (op GPR32:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1267             (!cast<Instruction>(NAME) $Rn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1270 multiclass sve_int_pred_pattern_b_x64<bits<5> opc, string asm,
1271                                       SDPatternOperator op> {
1272   def NAME : sve_int_pred_pattern_b<opc, asm, GPR64z, GPR64z>;
1274   def : InstAlias<asm # "\t$Rdn, $pattern",
1275                   (!cast<Instruction>(NAME) GPR64z:$Rdn, sve_pred_enum:$pattern, 1), 1>;
1276   def : InstAlias<asm # "\t$Rdn",
1277                   (!cast<Instruction>(NAME) GPR64z:$Rdn, 0b11111, 1), 2>;
1279   def : Pat<(i64 (op GPR64:$Rn, (sve_pred_enum:$pattern), (sve_incdec_imm:$imm4))),
1280             (!cast<Instruction>(NAME) $Rn, sve_pred_enum:$pattern, sve_incdec_imm:$imm4)>;
1284 //===----------------------------------------------------------------------===//
1285 // SVE Permute - Cross Lane Group
1286 //===----------------------------------------------------------------------===//
1288 class sve_int_perm_dup_r<bits<2> sz8_64, string asm, ZPRRegOp zprty,
1289                          ValueType vt, RegisterClass srcRegType,
1290                          SDPatternOperator op>
1291 : I<(outs zprty:$Zd), (ins srcRegType:$Rn),
1292   asm, "\t$Zd, $Rn",
1293   "",
1294   [(set (vt zprty:$Zd), (op srcRegType:$Rn))]>, Sched<[]> {
1295   bits<5> Rn;
1296   bits<5> Zd;
1297   let Inst{31-24} = 0b00000101;
1298   let Inst{23-22} = sz8_64;
1299   let Inst{21-10} = 0b100000001110;
1300   let Inst{9-5}   = Rn;
1301   let Inst{4-0}   = Zd;
1303   let hasSideEffects = 0;
1306 multiclass sve_int_perm_dup_r<string asm, SDPatternOperator op> {
1307   def _B : sve_int_perm_dup_r<0b00, asm, ZPR8, nxv16i8, GPR32sp, op>;
1308   def _H : sve_int_perm_dup_r<0b01, asm, ZPR16, nxv8i16, GPR32sp, op>;
1309   def _S : sve_int_perm_dup_r<0b10, asm, ZPR32, nxv4i32, GPR32sp, op>;
1310   def _D : sve_int_perm_dup_r<0b11, asm, ZPR64, nxv2i64, GPR64sp, op>;
1312   def : InstAlias<"mov $Zd, $Rn",
1313                   (!cast<Instruction>(NAME # _B) ZPR8:$Zd, GPR32sp:$Rn), 1>;
1314   def : InstAlias<"mov $Zd, $Rn",
1315                   (!cast<Instruction>(NAME # _H) ZPR16:$Zd, GPR32sp:$Rn), 1>;
1316   def : InstAlias<"mov $Zd, $Rn",
1317                   (!cast<Instruction>(NAME # _S) ZPR32:$Zd, GPR32sp:$Rn), 1>;
1318   def : InstAlias<"mov $Zd, $Rn",
1319                   (!cast<Instruction>(NAME # _D) ZPR64:$Zd, GPR64sp:$Rn), 1>;
1322 class sve_int_perm_dup_i<bits<5> tsz, Operand immtype, string asm,
1323                          ZPRRegOp zprty>
1324 : I<(outs zprty:$Zd), (ins zprty:$Zn, immtype:$idx),
1325   asm, "\t$Zd, $Zn$idx",
1326   "",
1327   []>, Sched<[]> {
1328   bits<5> Zd;
1329   bits<5> Zn;
1330   bits<7> idx;
1331   let Inst{31-24} = 0b00000101;
1332   let Inst{23-22} = {?,?}; // imm3h
1333   let Inst{21}    = 0b1;
1334   let Inst{20-16} = tsz;
1335   let Inst{15-10} = 0b001000;
1336   let Inst{9-5}   = Zn;
1337   let Inst{4-0}   = Zd;
1339   let hasSideEffects = 0;
1342 multiclass sve_int_perm_dup_i<string asm> {
1343   def _B : sve_int_perm_dup_i<{?,?,?,?,1}, sve_elm_idx_extdup_b, asm, ZPR8> {
1344     let Inst{23-22} = idx{5-4};
1345     let Inst{20-17} = idx{3-0};
1346   }
1347   def _H : sve_int_perm_dup_i<{?,?,?,1,0}, sve_elm_idx_extdup_h, asm, ZPR16> {
1348     let Inst{23-22} = idx{4-3};
1349     let Inst{20-18} = idx{2-0};
1350   }
1351   def _S : sve_int_perm_dup_i<{?,?,1,0,0}, sve_elm_idx_extdup_s, asm, ZPR32> {
1352     let Inst{23-22} = idx{3-2};
1353     let Inst{20-19}    = idx{1-0};
1354   }
1355   def _D : sve_int_perm_dup_i<{?,1,0,0,0}, sve_elm_idx_extdup_d, asm, ZPR64> {
1356     let Inst{23-22} = idx{2-1};
1357     let Inst{20}    = idx{0};
1358   }
1359   def _Q : sve_int_perm_dup_i<{1,0,0,0,0}, sve_elm_idx_extdup_q, asm, ZPR128> {
1360     let Inst{23-22} = idx{1-0};
1361   }
1363   def : InstAlias<"mov $Zd, $Zn$idx",
1364                   (!cast<Instruction>(NAME # _B) ZPR8:$Zd, ZPR8:$Zn, sve_elm_idx_extdup_b:$idx), 1>;
1365   def : InstAlias<"mov $Zd, $Zn$idx",
1366                   (!cast<Instruction>(NAME # _H) ZPR16:$Zd, ZPR16:$Zn, sve_elm_idx_extdup_h:$idx), 1>;
1367   def : InstAlias<"mov $Zd, $Zn$idx",
1368                   (!cast<Instruction>(NAME # _S) ZPR32:$Zd, ZPR32:$Zn, sve_elm_idx_extdup_s:$idx), 1>;
1369   def : InstAlias<"mov $Zd, $Zn$idx",
1370                   (!cast<Instruction>(NAME # _D) ZPR64:$Zd, ZPR64:$Zn, sve_elm_idx_extdup_d:$idx), 1>;
1371   def : InstAlias<"mov $Zd, $Zn$idx",
1372                   (!cast<Instruction>(NAME # _Q) ZPR128:$Zd, ZPR128:$Zn, sve_elm_idx_extdup_q:$idx), 1>;
1373   def : InstAlias<"mov $Zd, $Bn",
1374                   (!cast<Instruction>(NAME # _B) ZPR8:$Zd, FPR8asZPR:$Bn, 0), 2>;
1375   def : InstAlias<"mov $Zd, $Hn",
1376                   (!cast<Instruction>(NAME # _H) ZPR16:$Zd, FPR16asZPR:$Hn, 0), 2>;
1377   def : InstAlias<"mov $Zd, $Sn",
1378                   (!cast<Instruction>(NAME # _S) ZPR32:$Zd, FPR32asZPR:$Sn, 0), 2>;
1379   def : InstAlias<"mov $Zd, $Dn",
1380                   (!cast<Instruction>(NAME # _D) ZPR64:$Zd, FPR64asZPR:$Dn, 0), 2>;
1381   def : InstAlias<"mov $Zd, $Qn",
1382                   (!cast<Instruction>(NAME # _Q) ZPR128:$Zd, FPR128asZPR:$Qn, 0), 2>;
1384   // Duplicate extracted element of vector into all vector elements
1385   def : Pat<(nxv16i8 (splat_vector (i32 (vector_extract (nxv16i8 ZPR:$vec), sve_elm_idx_extdup_b:$index)))),
1386             (!cast<Instruction>(NAME # _B) ZPR:$vec, sve_elm_idx_extdup_b:$index)>;
1387   def : Pat<(nxv8i16 (splat_vector (i32 (vector_extract (nxv8i16 ZPR:$vec), sve_elm_idx_extdup_h:$index)))),
1388             (!cast<Instruction>(NAME # _H) ZPR:$vec, sve_elm_idx_extdup_h:$index)>;
1389   def : Pat<(nxv4i32 (splat_vector (i32 (vector_extract (nxv4i32 ZPR:$vec), sve_elm_idx_extdup_s:$index)))),
1390             (!cast<Instruction>(NAME # _S) ZPR:$vec, sve_elm_idx_extdup_s:$index)>;
1391   def : Pat<(nxv2i64 (splat_vector (i64 (vector_extract (nxv2i64 ZPR:$vec), sve_elm_idx_extdup_d:$index)))),
1392             (!cast<Instruction>(NAME # _D) ZPR:$vec, sve_elm_idx_extdup_d:$index)>;
1393   def : Pat<(nxv8f16 (splat_vector (f16 (vector_extract (nxv8f16 ZPR:$vec), sve_elm_idx_extdup_h:$index)))),
1394             (!cast<Instruction>(NAME # _H) ZPR:$vec, sve_elm_idx_extdup_h:$index)>;
1395   def : Pat<(nxv8bf16 (splat_vector (bf16 (vector_extract (nxv8bf16 ZPR:$vec), sve_elm_idx_extdup_h:$index)))),
1396             (!cast<Instruction>(NAME # _H) ZPR:$vec, sve_elm_idx_extdup_h:$index)>;
1397   def : Pat<(nxv4f16 (splat_vector (f16 (vector_extract (nxv4f16 ZPR:$vec), sve_elm_idx_extdup_s:$index)))),
1398             (!cast<Instruction>(NAME # _S) ZPR:$vec, sve_elm_idx_extdup_s:$index)>;
1399   def : Pat<(nxv2f16 (splat_vector (f16 (vector_extract (nxv2f16 ZPR:$vec), sve_elm_idx_extdup_d:$index)))),
1400             (!cast<Instruction>(NAME # _D) ZPR:$vec, sve_elm_idx_extdup_d:$index)>;
1401   def : Pat<(nxv4f32 (splat_vector (f32 (vector_extract (nxv4f32 ZPR:$vec), sve_elm_idx_extdup_s:$index)))),
1402             (!cast<Instruction>(NAME # _S) ZPR:$vec, sve_elm_idx_extdup_s:$index)>;
1403   def : Pat<(nxv2f32 (splat_vector (f32 (vector_extract (nxv2f32 ZPR:$vec), sve_elm_idx_extdup_d:$index)))),
1404             (!cast<Instruction>(NAME # _D) ZPR:$vec, sve_elm_idx_extdup_d:$index)>;
1405   def : Pat<(nxv2f64 (splat_vector (f64 (vector_extract (nxv2f64 ZPR:$vec), sve_elm_idx_extdup_d:$index)))),
1406             (!cast<Instruction>(NAME # _D) ZPR:$vec, sve_elm_idx_extdup_d:$index)>;
1408   def : Pat<(nxv16i8 (AArch64duplane128 nxv16i8:$Op1, i64:$imm)),
1409             (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1410   def : Pat<(nxv8i16 (AArch64duplane128 nxv8i16:$Op1, i64:$imm)),
1411             (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1412   def : Pat<(nxv4i32 (AArch64duplane128 nxv4i32:$Op1, i64:$imm)),
1413             (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1414   def : Pat<(nxv2i64 (AArch64duplane128 nxv2i64:$Op1, i64:$imm)),
1415             (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1416   def : Pat<(nxv8f16 (AArch64duplane128 nxv8f16:$Op1, i64:$imm)),
1417             (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1418   def : Pat<(nxv4f32 (AArch64duplane128 nxv4f32:$Op1, i64:$imm)),
1419             (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1420   def : Pat<(nxv2f64 (AArch64duplane128 nxv2f64:$Op1, i64:$imm)),
1421             (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1422   def : Pat<(nxv8bf16 (AArch64duplane128 nxv8bf16:$Op1, i64:$imm)),
1423             (!cast<Instruction>(NAME # _Q) $Op1, $imm)>;
1426 class sve_int_perm_tbl<bits<2> sz8_64, bits<2> opc, string asm, ZPRRegOp zprty,
1427                        RegisterOperand VecList>
1428 : I<(outs zprty:$Zd), (ins VecList:$Zn, zprty:$Zm),
1429   asm, "\t$Zd, $Zn, $Zm",
1430   "",
1431   []>, Sched<[]> {
1432   bits<5> Zd;
1433   bits<5> Zm;
1434   bits<5> Zn;
1435   let Inst{31-24} = 0b00000101;
1436   let Inst{23-22} = sz8_64;
1437   let Inst{21}    = 0b1;
1438   let Inst{20-16} = Zm;
1439   let Inst{15-13} = 0b001;
1440   let Inst{12-11} = opc;
1441   let Inst{10}    = 0b0;
1442   let Inst{9-5}   = Zn;
1443   let Inst{4-0}   = Zd;
1445   let hasSideEffects = 0;
1448 multiclass sve_int_perm_tbl<string asm, SDPatternOperator op> {
1449   def _B : sve_int_perm_tbl<0b00, 0b10, asm, ZPR8,  Z_b>;
1450   def _H : sve_int_perm_tbl<0b01, 0b10, asm, ZPR16, Z_h>;
1451   def _S : sve_int_perm_tbl<0b10, 0b10, asm, ZPR32, Z_s>;
1452   def _D : sve_int_perm_tbl<0b11, 0b10, asm, ZPR64, Z_d>;
1454   def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1455                  (!cast<Instruction>(NAME # _B) ZPR8:$Zd, ZPR8:$Zn, ZPR8:$Zm), 0>;
1456   def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1457                  (!cast<Instruction>(NAME # _H) ZPR16:$Zd, ZPR16:$Zn, ZPR16:$Zm), 0>;
1458   def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1459                  (!cast<Instruction>(NAME # _S) ZPR32:$Zd, ZPR32:$Zn, ZPR32:$Zm), 0>;
1460   def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
1461                  (!cast<Instruction>(NAME # _D) ZPR64:$Zd, ZPR64:$Zn, ZPR64:$Zm), 0>;
1463   def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
1464   def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1465   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1466   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1468   def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1469   def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1470   def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1472   def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1475 multiclass sve2_int_perm_tbl<string asm, SDPatternOperator op> {
1476   def _B : sve_int_perm_tbl<0b00, 0b01, asm, ZPR8,  ZZ_b>;
1477   def _H : sve_int_perm_tbl<0b01, 0b01, asm, ZPR16, ZZ_h>;
1478   def _S : sve_int_perm_tbl<0b10, 0b01, asm, ZPR32, ZZ_s>;
1479   def _D : sve_int_perm_tbl<0b11, 0b01, asm, ZPR64, ZZ_d>;
1481   def : Pat<(nxv16i8 (op nxv16i8:$Op1, nxv16i8:$Op2, nxv16i8:$Op3)),
1482             (nxv16i8 (!cast<Instruction>(NAME # _B) (REG_SEQUENCE ZPR2, nxv16i8:$Op1, zsub0,
1483                                                                         nxv16i8:$Op2, zsub1),
1484                                                      nxv16i8:$Op3))>;
1486   def : Pat<(nxv8i16 (op nxv8i16:$Op1, nxv8i16:$Op2, nxv8i16:$Op3)),
1487             (nxv8i16 (!cast<Instruction>(NAME # _H) (REG_SEQUENCE ZPR2, nxv8i16:$Op1, zsub0,
1488                                                                         nxv8i16:$Op2, zsub1),
1489                                                      nxv8i16:$Op3))>;
1491   def : Pat<(nxv4i32 (op nxv4i32:$Op1, nxv4i32:$Op2, nxv4i32:$Op3)),
1492             (nxv4i32 (!cast<Instruction>(NAME # _S) (REG_SEQUENCE ZPR2, nxv4i32:$Op1, zsub0,
1493                                                                         nxv4i32:$Op2, zsub1),
1494                                                      nxv4i32:$Op3))>;
1496   def : Pat<(nxv2i64 (op nxv2i64:$Op1, nxv2i64:$Op2, nxv2i64:$Op3)),
1497             (nxv2i64 (!cast<Instruction>(NAME # _D) (REG_SEQUENCE ZPR2, nxv2i64:$Op1, zsub0,
1498                                                                         nxv2i64:$Op2, zsub1),
1499                                                      nxv2i64:$Op3))>;
1501   def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8i16:$Op3)),
1502             (nxv8f16 (!cast<Instruction>(NAME # _H) (REG_SEQUENCE ZPR2, nxv8f16:$Op1, zsub0,
1503                                                                         nxv8f16:$Op2, zsub1),
1504                                                      nxv8i16:$Op3))>;
1506   def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4i32:$Op3)),
1507             (nxv4f32 (!cast<Instruction>(NAME # _S) (REG_SEQUENCE ZPR2, nxv4f32:$Op1, zsub0,
1508                                                                         nxv4f32:$Op2, zsub1),
1509                                                      nxv4i32:$Op3))>;
1511   def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, nxv2i64:$Op3)),
1512             (nxv2f64 (!cast<Instruction>(NAME # _D) (REG_SEQUENCE ZPR2, nxv2f64:$Op1, zsub0,
1513                                                                         nxv2f64:$Op2, zsub1),
1514                                                      nxv2i64:$Op3))>;
1516   def : Pat<(nxv8bf16 (op nxv8bf16:$Op1, nxv8bf16:$Op2, nxv8i16:$Op3)),
1517             (nxv8bf16 (!cast<Instruction>(NAME # _H) (REG_SEQUENCE ZPR2, nxv8bf16:$Op1, zsub0,
1518                                                                          nxv8bf16:$Op2, zsub1),
1519                                                       nxv8i16:$Op3))>;
1522 class sve2_int_perm_tbx<bits<2> sz8_64, bits<2> opc, string asm, ZPRRegOp zprty>
1523 : I<(outs zprty:$Zd), (ins zprty:$_Zd, zprty:$Zn, zprty:$Zm),
1524   asm, "\t$Zd, $Zn, $Zm",
1525   "",
1526   []>, Sched<[]> {
1527   bits<5> Zd;
1528   bits<5> Zm;
1529   bits<5> Zn;
1530   let Inst{31-24} = 0b00000101;
1531   let Inst{23-22} = sz8_64;
1532   let Inst{21}    = 0b1;
1533   let Inst{20-16} = Zm;
1534   let Inst{15-13} = 0b001;
1535   let Inst{12-11} = opc;
1536   let Inst{10}    = 0b1;
1537   let Inst{9-5}   = Zn;
1538   let Inst{4-0}   = Zd;
1540   let Constraints = "$Zd = $_Zd";
1541   let hasSideEffects = 0;
1544 multiclass sve2_int_perm_tbx<string asm, bits<2> opc, SDPatternOperator op> {
1545   def _B : sve2_int_perm_tbx<0b00, opc, asm, ZPR8>;
1546   def _H : sve2_int_perm_tbx<0b01, opc, asm, ZPR16>;
1547   def _S : sve2_int_perm_tbx<0b10, opc, asm, ZPR32>;
1548   def _D : sve2_int_perm_tbx<0b11, opc, asm, ZPR64>;
1550   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
1551   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1552   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1553   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1555   def : SVE_3_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1556   def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1557   def : SVE_3_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1559   def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1562 class sve_int_perm_reverse_z<bits<2> sz8_64, string asm, ZPRRegOp zprty>
1563 : I<(outs zprty:$Zd), (ins zprty:$Zn),
1564   asm, "\t$Zd, $Zn",
1565   "",
1566   []>, Sched<[]> {
1567   bits<5> Zd;
1568   bits<5> Zn;
1569   let Inst{31-24} = 0b00000101;
1570   let Inst{23-22} = sz8_64;
1571   let Inst{21-10} = 0b111000001110;
1572   let Inst{9-5}   = Zn;
1573   let Inst{4-0}   = Zd;
1575   let hasSideEffects = 0;
1578 multiclass sve_int_perm_reverse_z<string asm, SDPatternOperator op> {
1579   def _B : sve_int_perm_reverse_z<0b00, asm, ZPR8>;
1580   def _H : sve_int_perm_reverse_z<0b01, asm, ZPR16>;
1581   def _S : sve_int_perm_reverse_z<0b10, asm, ZPR32>;
1582   def _D : sve_int_perm_reverse_z<0b11, asm, ZPR64>;
1584   def : SVE_1_Op_Pat<nxv16i8, op, nxv16i8, !cast<Instruction>(NAME # _B)>;
1585   def : SVE_1_Op_Pat<nxv8i16, op, nxv8i16, !cast<Instruction>(NAME # _H)>;
1586   def : SVE_1_Op_Pat<nxv4i32, op, nxv4i32, !cast<Instruction>(NAME # _S)>;
1587   def : SVE_1_Op_Pat<nxv2i64, op, nxv2i64, !cast<Instruction>(NAME # _D)>;
1589   def : SVE_1_Op_Pat<nxv2f16, op, nxv2f16, !cast<Instruction>(NAME # _D)>;
1590   def : SVE_1_Op_Pat<nxv4f16, op, nxv4f16, !cast<Instruction>(NAME # _S)>;
1591   def : SVE_1_Op_Pat<nxv8f16, op, nxv8f16, !cast<Instruction>(NAME # _H)>;
1592   def : SVE_1_Op_Pat<nxv2f32, op, nxv2f32, !cast<Instruction>(NAME # _D)>;
1593   def : SVE_1_Op_Pat<nxv4f32, op, nxv4f32, !cast<Instruction>(NAME # _S)>;
1594   def : SVE_1_Op_Pat<nxv2f64, op, nxv2f64, !cast<Instruction>(NAME # _D)>;
1596   def : SVE_1_Op_Pat<nxv2bf16, op, nxv2bf16, !cast<Instruction>(NAME # _D)>;
1597   def : SVE_1_Op_Pat<nxv4bf16, op, nxv4bf16, !cast<Instruction>(NAME # _S)>;
1598   def : SVE_1_Op_Pat<nxv8bf16, op, nxv8bf16, !cast<Instruction>(NAME # _H)>;
1601 class sve_int_perm_reverse_p<bits<2> sz8_64, string asm, PPRRegOp pprty,
1602                              SDPatternOperator op>
1603 : I<(outs pprty:$Pd), (ins pprty:$Pn),
1604   asm, "\t$Pd, $Pn",
1605   "",
1606   [(set nxv16i1:$Pd, (op nxv16i1:$Pn))]>, Sched<[]> {
1607   bits<4> Pd;
1608   bits<4> Pn;
1609   let Inst{31-24} = 0b00000101;
1610   let Inst{23-22} = sz8_64;
1611   let Inst{21-9}  = 0b1101000100000;
1612   let Inst{8-5}   = Pn;
1613   let Inst{4}     = 0b0;
1614   let Inst{3-0}   = Pd;
1616   let hasSideEffects = 0;
1619 multiclass sve_int_perm_reverse_p<string asm, SDPatternOperator ir_op,
1620                                   SDPatternOperator op_b16,
1621                                   SDPatternOperator op_b32,
1622                                   SDPatternOperator op_b64> {
1623   def _B : sve_int_perm_reverse_p<0b00, asm, PPR8,  ir_op>;
1624   def _H : sve_int_perm_reverse_p<0b01, asm, PPR16, op_b16>;
1625   def _S : sve_int_perm_reverse_p<0b10, asm, PPR32, op_b32>;
1626   def _D : sve_int_perm_reverse_p<0b11, asm, PPR64, op_b64>;
1628   def : SVE_1_Op_Pat<nxv8i1, ir_op, nxv8i1, !cast<Instruction>(NAME # _H)>;
1629   def : SVE_1_Op_Pat<nxv4i1, ir_op, nxv4i1, !cast<Instruction>(NAME # _S)>;
1630   def : SVE_1_Op_Pat<nxv2i1, ir_op, nxv2i1, !cast<Instruction>(NAME # _D)>;
1633 class sve_int_perm_unpk<bits<2> sz16_64, bits<2> opc, string asm,
1634                         ZPRRegOp zprty1, ZPRRegOp zprty2>
1635 : I<(outs zprty1:$Zd), (ins zprty2:$Zn),
1636   asm, "\t$Zd, $Zn",
1637   "", []>, Sched<[]> {
1638   bits<5> Zd;
1639   bits<5> Zn;
1640   let Inst{31-24} = 0b00000101;
1641   let Inst{23-22} = sz16_64;
1642   let Inst{21-18} = 0b1100;
1643   let Inst{17-16} = opc;
1644   let Inst{15-10} = 0b001110;
1645   let Inst{9-5}   = Zn;
1646   let Inst{4-0}   = Zd;
1648   let hasSideEffects = 0;
1651 multiclass sve_int_perm_unpk<bits<2> opc, string asm, SDPatternOperator op> {
1652   def _H : sve_int_perm_unpk<0b01, opc, asm, ZPR16, ZPR8>;
1653   def _S : sve_int_perm_unpk<0b10, opc, asm, ZPR32, ZPR16>;
1654   def _D : sve_int_perm_unpk<0b11, opc, asm, ZPR64, ZPR32>;
1656   def : SVE_1_Op_Pat<nxv8i16, op, nxv16i8, !cast<Instruction>(NAME # _H)>;
1657   def : SVE_1_Op_Pat<nxv4i32, op, nxv8i16, !cast<Instruction>(NAME # _S)>;
1658   def : SVE_1_Op_Pat<nxv2i64, op, nxv4i32, !cast<Instruction>(NAME # _D)>;
1661 class sve_int_perm_insrs<bits<2> sz8_64, string asm, ZPRRegOp zprty,
1662                          RegisterClass srcRegType>
1663 : I<(outs zprty:$Zdn), (ins zprty:$_Zdn, srcRegType:$Rm),
1664   asm, "\t$Zdn, $Rm",
1665   "",
1666   []>, Sched<[]> {
1667   bits<5> Rm;
1668   bits<5> Zdn;
1669   let Inst{31-24} = 0b00000101;
1670   let Inst{23-22} = sz8_64;
1671   let Inst{21-10} = 0b100100001110;
1672   let Inst{9-5}   = Rm;
1673   let Inst{4-0}   = Zdn;
1675   let Constraints = "$Zdn = $_Zdn";
1676   let DestructiveInstType = DestructiveOther;
1677   let hasSideEffects = 0;
1680 multiclass sve_int_perm_insrs<string asm, SDPatternOperator op> {
1681   def _B : sve_int_perm_insrs<0b00, asm, ZPR8, GPR32>;
1682   def _H : sve_int_perm_insrs<0b01, asm, ZPR16, GPR32>;
1683   def _S : sve_int_perm_insrs<0b10, asm, ZPR32, GPR32>;
1684   def _D : sve_int_perm_insrs<0b11, asm, ZPR64, GPR64>;
1686   def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, i32, !cast<Instruction>(NAME # _B)>;
1687   def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, i32, !cast<Instruction>(NAME # _H)>;
1688   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, i32, !cast<Instruction>(NAME # _S)>;
1689   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, i64, !cast<Instruction>(NAME # _D)>;
1692 class sve_int_perm_insrv<bits<2> sz8_64, string asm, ZPRRegOp zprty,
1693                          FPRasZPROperand srcOpType>
1694 : I<(outs zprty:$Zdn), (ins zprty:$_Zdn, srcOpType:$Vm),
1695   asm, "\t$Zdn, $Vm",
1696   "",
1697   []>, Sched<[]> {
1698   bits<5> Vm;
1699   bits<5> Zdn;
1700   let Inst{31-24} = 0b00000101;
1701   let Inst{23-22} = sz8_64;
1702   let Inst{21-10} = 0b110100001110;
1703   let Inst{9-5}   = Vm;
1704   let Inst{4-0}   = Zdn;
1706   let Constraints = "$Zdn = $_Zdn";
1707   let DestructiveInstType = DestructiveOther;
1708   let hasSideEffects = 0;
1711 multiclass sve_int_perm_insrv<string asm, SDPatternOperator op> {
1712   def _B : sve_int_perm_insrv<0b00, asm, ZPR8, FPR8asZPR>;
1713   def _H : sve_int_perm_insrv<0b01, asm, ZPR16, FPR16asZPR>;
1714   def _S : sve_int_perm_insrv<0b10, asm, ZPR32, FPR32asZPR>;
1715   def _D : sve_int_perm_insrv<0b11, asm, ZPR64, FPR64asZPR>;
1717   def : Pat<(nxv8f16 (op nxv8f16:$Zn, f16:$Vm)),
1718             (!cast<Instruction>(NAME # _H) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, hsub))>;
1719   def : Pat<(nxv4f32 (op nxv4f32:$Zn, f32:$Vm)),
1720             (!cast<Instruction>(NAME # _S) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, ssub))>;
1721   def : Pat<(nxv2f64 (op nxv2f64:$Zn, f64:$Vm)),
1722             (!cast<Instruction>(NAME # _D) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, dsub))>;
1724   def : Pat<(nxv8bf16 (op nxv8bf16:$Zn, bf16:$Vm)),
1725             (!cast<Instruction>(NAME # _H) $Zn, (INSERT_SUBREG (IMPLICIT_DEF), $Vm, hsub))>;
1727   // Keep integer insertions within the vector unit.
1728   def : Pat<(nxv16i8 (op (nxv16i8 ZPR:$Zn), (i32 (vector_extract (nxv16i8 ZPR:$Vm), 0)))),
1729             (!cast<Instruction>(NAME # _B) $Zn, ZPR:$Vm)>;
1730   def : Pat<(nxv8i16 (op (nxv8i16 ZPR:$Zn), (i32 (vector_extract (nxv8i16 ZPR:$Vm), 0)))),
1731             (!cast<Instruction>(NAME # _H) $Zn, ZPR:$Vm)>;
1732   def : Pat<(nxv4i32 (op (nxv4i32 ZPR:$Zn), (i32 (vector_extract (nxv4i32 ZPR:$Vm), 0)))),
1733             (!cast<Instruction>(NAME # _S) $Zn, ZPR: $Vm)>;
1734   def : Pat<(nxv2i64 (op (nxv2i64 ZPR:$Zn), (i64 (vector_extract (nxv2i64 ZPR:$Vm), 0)))),
1735             (!cast<Instruction>(NAME # _D) $Zn, ZPR:$Vm)>;
1739 //===----------------------------------------------------------------------===//
1740 // SVE Permute - Extract Group
1741 //===----------------------------------------------------------------------===//
1743 class sve_int_perm_extract_i<string asm>
1744 : I<(outs ZPR8:$Zdn), (ins ZPR8:$_Zdn, ZPR8:$Zm, imm0_255:$imm8),
1745   asm, "\t$Zdn, $_Zdn, $Zm, $imm8",
1746   "", []>, Sched<[]> {
1747   bits<5> Zdn;
1748   bits<5> Zm;
1749   bits<8> imm8;
1750   let Inst{31-21} = 0b00000101001;
1751   let Inst{20-16} = imm8{7-3};
1752   let Inst{15-13} = 0b000;
1753   let Inst{12-10} = imm8{2-0};
1754   let Inst{9-5}   = Zm;
1755   let Inst{4-0}   = Zdn;
1757   let Constraints = "$Zdn = $_Zdn";
1758   let DestructiveInstType = DestructiveOther;
1759   let ElementSize = ElementSizeNone;
1760   let hasSideEffects = 0;
1763 multiclass sve_int_perm_extract_i<string asm, SDPatternOperator op> {
1764   def NAME : sve_int_perm_extract_i<asm>;
1766   def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, imm0_255,
1767                          !cast<Instruction>(NAME)>;
1770 class sve2_int_perm_extract_i_cons<string asm>
1771 : I<(outs ZPR8:$Zd), (ins ZZ_b:$Zn, imm0_255:$imm8),
1772   asm, "\t$Zd, $Zn, $imm8",
1773   "", []>, Sched<[]> {
1774   bits<5> Zd;
1775   bits<5> Zn;
1776   bits<8> imm8;
1777   let Inst{31-21} = 0b00000101011;
1778   let Inst{20-16} = imm8{7-3};
1779   let Inst{15-13} = 0b000;
1780   let Inst{12-10} = imm8{2-0};
1781   let Inst{9-5}   = Zn;
1782   let Inst{4-0}   = Zd;
1784   let hasSideEffects = 0;
1787 //===----------------------------------------------------------------------===//
1788 // SVE Vector Select Group
1789 //===----------------------------------------------------------------------===//
1791 class sve_int_sel_vvv<bits<2> sz8_64, string asm, ZPRRegOp zprty>
1792 : I<(outs zprty:$Zd), (ins PPRAny:$Pg, zprty:$Zn, zprty:$Zm),
1793   asm, "\t$Zd, $Pg, $Zn, $Zm",
1794   "",
1795   []>, Sched<[]> {
1796   bits<4> Pg;
1797   bits<5> Zd;
1798   bits<5> Zm;
1799   bits<5> Zn;
1800   let Inst{31-24} = 0b00000101;
1801   let Inst{23-22} = sz8_64;
1802   let Inst{21}    = 0b1;
1803   let Inst{20-16} = Zm;
1804   let Inst{15-14} = 0b11;
1805   let Inst{13-10} = Pg;
1806   let Inst{9-5}   = Zn;
1807   let Inst{4-0}   = Zd;
1809   let hasSideEffects = 0;
1812 multiclass sve_int_sel_vvv<string asm, SDPatternOperator op> {
1813   def _B : sve_int_sel_vvv<0b00, asm, ZPR8>;
1814   def _H : sve_int_sel_vvv<0b01, asm, ZPR16>;
1815   def _S : sve_int_sel_vvv<0b10, asm, ZPR32>;
1816   def _D : sve_int_sel_vvv<0b11, asm, ZPR64>;
1818   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
1819   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
1820   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
1821   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
1823   def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1,  nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
1824   def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1,  nxv4f16, nxv4f16, !cast<Instruction>(NAME # _S)>;
1825   def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1,  nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
1826   def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1,  nxv2f16, nxv2f16, !cast<Instruction>(NAME # _D)>;
1827   def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1,  nxv2f32, nxv2f32, !cast<Instruction>(NAME # _D)>;
1828   def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1,  nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
1830   def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1,  nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
1832   def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1833                   (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPRAny:$Pg, ZPR8:$Zn, ZPR8:$Zd), 1>;
1834   def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1835                   (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, ZPR16:$Zn, ZPR16:$Zd), 1>;
1836   def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1837                   (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, ZPR32:$Zn, ZPR32:$Zd), 1>;
1838   def : InstAlias<"mov $Zd, $Pg/m, $Zn",
1839                   (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, ZPR64:$Zn, ZPR64:$Zd), 1>;
1843 //===----------------------------------------------------------------------===//
1844 // SVE Predicate Logical Operations Group
1845 //===----------------------------------------------------------------------===//
1847 class sve_int_pred_log<bits<4> opc, string asm>
1848 : I<(outs PPR8:$Pd), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$Pm),
1849   asm, "\t$Pd, $Pg/z, $Pn, $Pm",
1850   "",
1851   []>, Sched<[]> {
1852   bits<4> Pd;
1853   bits<4> Pg;
1854   bits<4> Pm;
1855   bits<4> Pn;
1856   let Inst{31-24} = 0b00100101;
1857   let Inst{23-22} = opc{3-2};
1858   let Inst{21-20} = 0b00;
1859   let Inst{19-16} = Pm;
1860   let Inst{15-14} = 0b01;
1861   let Inst{13-10} = Pg;
1862   let Inst{9}     = opc{1};
1863   let Inst{8-5}   = Pn;
1864   let Inst{4}     = opc{0};
1865   let Inst{3-0}   = Pd;
1867   // SEL has no predication qualifier.
1868   let AsmString = !if(!eq(opc, 0b0011),
1869                       !strconcat(asm, "\t$Pd, $Pg, $Pn, $Pm"),
1870                       !strconcat(asm, "\t$Pd, $Pg/z, $Pn, $Pm"));
1872   let Defs = !if(!eq (opc{2}, 1), [NZCV], []);
1873   let hasSideEffects = 0;
1876 multiclass sve_int_pred_log<bits<4> opc, string asm, SDPatternOperator op,
1877                             SDPatternOperator op_nopred = null_frag> {
1878   def NAME : sve_int_pred_log<opc, asm>;
1880   def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
1881   def : SVE_3_Op_Pat<nxv8i1, op, nxv8i1, nxv8i1, nxv8i1, !cast<Instruction>(NAME)>;
1882   def : SVE_3_Op_Pat<nxv4i1, op, nxv4i1, nxv4i1, nxv4i1, !cast<Instruction>(NAME)>;
1883   def : SVE_3_Op_Pat<nxv2i1, op, nxv2i1, nxv2i1, nxv2i1, !cast<Instruction>(NAME)>;
1884   def : SVE_3_Op_Pat<nxv1i1, op, nxv1i1, nxv1i1, nxv1i1, !cast<Instruction>(NAME)>;
1885   def : SVE_2_Op_AllActive_Pat<nxv16i1, op_nopred, nxv16i1, nxv16i1,
1886                                !cast<Instruction>(NAME), PTRUE_B>;
1887   def : SVE_2_Op_AllActive_Pat<nxv8i1, op_nopred, nxv8i1, nxv8i1,
1888                                !cast<Instruction>(NAME), PTRUE_H>;
1889   def : SVE_2_Op_AllActive_Pat<nxv4i1, op_nopred, nxv4i1, nxv4i1,
1890                                !cast<Instruction>(NAME), PTRUE_S>;
1891   def : SVE_2_Op_AllActive_Pat<nxv2i1, op_nopred, nxv2i1, nxv2i1,
1892                                !cast<Instruction>(NAME), PTRUE_D>;
1893   // Emulate .Q operation using a PTRUE_D when the other lanes don't matter.
1894   def : SVE_2_Op_AllActive_Pat<nxv1i1, op_nopred, nxv1i1, nxv1i1,
1895                                !cast<Instruction>(NAME), PTRUE_D>;
1898 // An instance of sve_int_pred_log_and but uses op_nopred's first operand as the
1899 // general predicate.
1900 multiclass sve_int_pred_log_v2<bits<4> opc, string asm, SDPatternOperator op,
1901                                SDPatternOperator op_nopred> :
1902   sve_int_pred_log<opc, asm, op> {
1903   def : Pat<(nxv16i1 (op_nopred nxv16i1:$Op1, nxv16i1:$Op2)),
1904             (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1905   def : Pat<(nxv8i1 (op_nopred nxv8i1:$Op1, nxv8i1:$Op2)),
1906             (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1907   def : Pat<(nxv4i1 (op_nopred nxv4i1:$Op1, nxv4i1:$Op2)),
1908             (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1909   def : Pat<(nxv2i1 (op_nopred nxv2i1:$Op1, nxv2i1:$Op2)),
1910             (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1911   // Emulate .Q operation using a PTRUE_D when the other lanes don't matter.
1912   def : Pat<(nxv1i1 (op_nopred nxv1i1:$Op1, nxv1i1:$Op2)),
1913             (!cast<Instruction>(NAME) $Op1, $Op1, $Op2)>;
1916 //===----------------------------------------------------------------------===//
1917 // SVE Logical Mask Immediate Group
1918 //===----------------------------------------------------------------------===//
1920 class sve_int_log_imm<bits<2> opc, string asm>
1921 : I<(outs ZPR64:$Zdn), (ins ZPR64:$_Zdn, logical_imm64:$imms13),
1922   asm, "\t$Zdn, $_Zdn, $imms13",
1923   "", []>, Sched<[]> {
1924   bits<5> Zdn;
1925   bits<13> imms13;
1926   let Inst{31-24} = 0b00000101;
1927   let Inst{23-22} = opc;
1928   let Inst{21-18} = 0b0000;
1929   let Inst{17-5}  = imms13;
1930   let Inst{4-0}   = Zdn;
1932   let Constraints = "$Zdn = $_Zdn";
1933   let DecoderMethod = "DecodeSVELogicalImmInstruction";
1934   let DestructiveInstType = DestructiveOther;
1935   let ElementSize = ElementSizeNone;
1936   let hasSideEffects = 0;
1939 multiclass sve_int_log_imm<bits<2> opc, string asm, string alias, SDPatternOperator op> {
1940   def NAME : sve_int_log_imm<opc, asm>;
1942   def : SVE_1_Op_Imm_Log_Pat<nxv16i8, op, ZPR8,  i32, SVELogicalImm8Pat,  !cast<Instruction>(NAME)>;
1943   def : SVE_1_Op_Imm_Log_Pat<nxv8i16, op, ZPR16, i32, SVELogicalImm16Pat, !cast<Instruction>(NAME)>;
1944   def : SVE_1_Op_Imm_Log_Pat<nxv4i32, op, ZPR32, i32, SVELogicalImm32Pat, !cast<Instruction>(NAME)>;
1945   def : SVE_1_Op_Imm_Log_Pat<nxv2i64, op, ZPR64, i64, SVELogicalImm64Pat, !cast<Instruction>(NAME)>;
1947   def : InstAlias<asm # "\t$Zdn, $Zdn, $imm",
1948                   (!cast<Instruction>(NAME) ZPR8:$Zdn, sve_logical_imm8:$imm), 4>;
1949   def : InstAlias<asm # "\t$Zdn, $Zdn, $imm",
1950                   (!cast<Instruction>(NAME) ZPR16:$Zdn, sve_logical_imm16:$imm), 3>;
1951   def : InstAlias<asm # "\t$Zdn, $Zdn, $imm",
1952                   (!cast<Instruction>(NAME) ZPR32:$Zdn, sve_logical_imm32:$imm), 2>;
1954   def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
1955                   (!cast<Instruction>(NAME) ZPR8:$Zdn, sve_logical_imm8_not:$imm), 0>;
1956   def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
1957                   (!cast<Instruction>(NAME) ZPR16:$Zdn, sve_logical_imm16_not:$imm), 0>;
1958   def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
1959                   (!cast<Instruction>(NAME) ZPR32:$Zdn, sve_logical_imm32_not:$imm), 0>;
1960   def : InstAlias<alias # "\t$Zdn, $Zdn, $imm",
1961                   (!cast<Instruction>(NAME) ZPR64:$Zdn, logical_imm64_not:$imm), 0>;
1964 multiclass sve_int_log_imm_bic<SDPatternOperator op> {
1965   def : SVE_1_Op_Imm_Log_Pat<nxv16i8, op, ZPR8,  i32, SVELogicalImm8NotPat,  !cast<Instruction>("AND_ZI")>;
1966   def : SVE_1_Op_Imm_Log_Pat<nxv8i16, op, ZPR16, i32, SVELogicalImm16NotPat, !cast<Instruction>("AND_ZI")>;
1967   def : SVE_1_Op_Imm_Log_Pat<nxv4i32, op, ZPR32, i32, SVELogicalImm32NotPat, !cast<Instruction>("AND_ZI")>;
1968   def : SVE_1_Op_Imm_Log_Pat<nxv2i64, op, ZPR64, i64, SVELogicalImm64NotPat, !cast<Instruction>("AND_ZI")>;
1971 class sve_int_dup_mask_imm<string asm>
1972 : I<(outs ZPR64:$Zd), (ins logical_imm64:$imms),
1973   asm, "\t$Zd, $imms",
1974   "",
1975   []>, Sched<[]> {
1976   bits<5> Zd;
1977   bits<13> imms;
1978   let Inst{31-18} = 0b00000101110000;
1979   let Inst{17-5} = imms;
1980   let Inst{4-0} = Zd;
1982   let DecoderMethod = "DecodeSVELogicalImmInstruction";
1983   let hasSideEffects = 0;
1984   let isReMaterializable = 1;
1987 multiclass sve_int_dup_mask_imm<string asm> {
1988   def NAME : sve_int_dup_mask_imm<asm>;
1990   def : InstAlias<"dupm $Zd, $imm",
1991                   (!cast<Instruction>(NAME) ZPR8:$Zd, sve_logical_imm8:$imm), 4>;
1992   def : InstAlias<"dupm $Zd, $imm",
1993                   (!cast<Instruction>(NAME) ZPR16:$Zd, sve_logical_imm16:$imm), 3>;
1994   def : InstAlias<"dupm $Zd, $imm",
1995                   (!cast<Instruction>(NAME) ZPR32:$Zd, sve_logical_imm32:$imm), 2>;
1997   // All Zd.b forms have a CPY/DUP equivalent, hence no byte alias here.
1998   def : InstAlias<"mov $Zd, $imm",
1999                   (!cast<Instruction>(NAME) ZPR16:$Zd, sve_preferred_logical_imm16:$imm), 7>;
2000   def : InstAlias<"mov $Zd, $imm",
2001                   (!cast<Instruction>(NAME) ZPR32:$Zd, sve_preferred_logical_imm32:$imm), 6>;
2002   def : InstAlias<"mov $Zd, $imm",
2003                   (!cast<Instruction>(NAME) ZPR64:$Zd, sve_preferred_logical_imm64:$imm), 5>;
2005   // NOTE: No pattern for nxv16i8 because DUP has full coverage.
2006   def : Pat<(nxv8i16 (splat_vector (i32 (SVELogicalImm16Pat i64:$imm)))),
2007             (!cast<Instruction>(NAME) i64:$imm)>;
2008   def : Pat<(nxv4i32 (splat_vector (i32 (SVELogicalImm32Pat i64:$imm)))),
2009             (!cast<Instruction>(NAME) i64:$imm)>;
2010   def : Pat<(nxv2i64 (splat_vector (i64 (SVELogicalImm64Pat i64:$imm)))),
2011             (!cast<Instruction>(NAME) i64:$imm)>;
2014 //===----------------------------------------------------------------------===//
2015 // SVE Integer Arithmetic -  Unpredicated Group.
2016 //===----------------------------------------------------------------------===//
2018 class sve_int_bin_cons_arit_0<bits<2> sz8_64, bits<3> opc, string asm,
2019                               ZPRRegOp zprty>
2020 : I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
2021   asm, "\t$Zd, $Zn, $Zm",
2022   "", []>, Sched<[]> {
2023   bits<5> Zd;
2024   bits<5> Zm;
2025   bits<5> Zn;
2026   let Inst{31-24} = 0b00000100;
2027   let Inst{23-22} = sz8_64;
2028   let Inst{21}    = 0b1;
2029   let Inst{20-16} = Zm;
2030   let Inst{15-13} = 0b000;
2031   let Inst{12-10} = opc;
2032   let Inst{9-5}   = Zn;
2033   let Inst{4-0}   = Zd;
2035   let hasSideEffects = 0;
2038 multiclass sve_int_bin_cons_arit_0<bits<3> opc, string asm, SDPatternOperator op> {
2039   def _B : sve_int_bin_cons_arit_0<0b00, opc, asm, ZPR8>;
2040   def _H : sve_int_bin_cons_arit_0<0b01, opc, asm, ZPR16>;
2041   def _S : sve_int_bin_cons_arit_0<0b10, opc, asm, ZPR32>;
2042   def _D : sve_int_bin_cons_arit_0<0b11, opc, asm, ZPR64>;
2044   def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
2045   def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2046   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2047   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2050 //===----------------------------------------------------------------------===//
2051 // SVE Floating Point Arithmetic - Predicated Group
2052 //===----------------------------------------------------------------------===//
2054 class sve_fp_2op_i_p_zds<bits<2> sz, bits<3> opc, string asm,
2055                          ZPRRegOp zprty,
2056                          Operand imm_ty>
2057 : I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, imm_ty:$i1),
2058   asm, "\t$Zdn, $Pg/m, $_Zdn, $i1",
2059   "",
2060   []>, Sched<[]> {
2061   bits<3> Pg;
2062   bits<5> Zdn;
2063   bit i1;
2064   let Inst{31-24} = 0b01100101;
2065   let Inst{23-22} = sz;
2066   let Inst{21-19} = 0b011;
2067   let Inst{18-16} = opc;
2068   let Inst{15-13} = 0b100;
2069   let Inst{12-10} = Pg;
2070   let Inst{9-6}   = 0b0000;
2071   let Inst{5}     = i1;
2072   let Inst{4-0}   = Zdn;
2074   let Constraints = "$Zdn = $_Zdn";
2075   let DestructiveInstType = DestructiveOther;
2076   let ElementSize = zprty.ElementSize;
2077   let hasSideEffects = 0;
2078   let mayRaiseFPException = 1;
2081 multiclass sve_fp_2op_i_p_zds<bits<3> opc, string asm, string Ps, Operand imm_ty, FPImmLeaf A, FPImmLeaf B, SDPatternOperator op> {
2082   let DestructiveInstType = DestructiveBinaryImm in {
2083   def _H : SVEPseudo2Instr<Ps # _H, 1>, sve_fp_2op_i_p_zds<0b01, opc, asm, ZPR16, imm_ty>;
2084   def _S : SVEPseudo2Instr<Ps # _S, 1>, sve_fp_2op_i_p_zds<0b10, opc, asm, ZPR32, imm_ty>;
2085   def _D : SVEPseudo2Instr<Ps # _D, 1>, sve_fp_2op_i_p_zds<0b11, opc, asm, ZPR64, imm_ty>;
2086   }
2088   def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, op, nxv8i1, f16, A, 0, !cast<Instruction>(NAME # "_H")>;
2089   def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, op, nxv8i1, f16, B, 1, !cast<Instruction>(NAME # "_H")>;
2090   def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, op, nxv4i1, f32, A, 0, !cast<Instruction>(NAME # "_S")>;
2091   def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, op, nxv4i1, f32, B, 1, !cast<Instruction>(NAME # "_S")>;
2092   def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, op, nxv2i1, f64, A, 0, !cast<Instruction>(NAME # "_D")>;
2093   def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, op, nxv2i1, f64, B, 1, !cast<Instruction>(NAME # "_D")>;
2096 class sve_fp_2op_p_zds<bits<2> sz, bits<4> opc, string asm,
2097                        ZPRRegOp zprty>
2098 : I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
2099   asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
2100   "",
2101   []>, Sched<[]> {
2102   bits<3> Pg;
2103   bits<5> Zdn;
2104   bits<5> Zm;
2105   let Inst{31-24} = 0b01100101;
2106   let Inst{23-22} = sz;
2107   let Inst{21-20} = 0b00;
2108   let Inst{19-16} = opc;
2109   let Inst{15-13} = 0b100;
2110   let Inst{12-10} = Pg;
2111   let Inst{9-5}   = Zm;
2112   let Inst{4-0}   = Zdn;
2114   let Constraints = "$Zdn = $_Zdn";
2115   let DestructiveInstType = DestructiveOther;
2116   let ElementSize = zprty.ElementSize;
2117   let hasSideEffects = 0;
2118   let mayRaiseFPException = 1;
2121 multiclass sve2p1_bf_2op_p_zds<bits<4> opc, string asm, string Ps,
2122                             SDPatternOperator op, DestructiveInstTypeEnum flags,
2123                             string revname="", bit isReverseInstr=0> {
2124 let DestructiveInstType = flags in {
2125   def NAME : sve_fp_2op_p_zds<0b00, opc, asm, ZPR16>,
2126            SVEPseudo2Instr<Ps, 1>, SVEInstr2Rev<NAME , revname , isReverseInstr>;
2127   }
2129   def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
2132 multiclass sve2p1_bf_bin_pred_zds<SDPatternOperator op> {
2133   def _UNDEF : PredTwoOpPseudo<NAME, ZPR16, FalseLanesUndef>;
2135   def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1,  nxv8bf16, nxv8bf16, !cast<Pseudo>(NAME # _UNDEF)>;
2138 multiclass sve2p1_bf_2op_p_zds_zeroing<SDPatternOperator op> {
2139   def _ZERO : PredTwoOpPseudo<NAME, ZPR16, FalseLanesZero>;
2141   def : SVE_3_Op_Pat_SelZero<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Pseudo>(NAME # _ZERO)>;
2144 multiclass sve_fp_2op_p_zds<bits<4> opc, string asm, string Ps,
2145                             SDPatternOperator op, DestructiveInstTypeEnum flags,
2146                             string revname="", bit isReverseInstr=0> {
2147   let DestructiveInstType = flags in {
2148   def _H : sve_fp_2op_p_zds<0b01, opc, asm, ZPR16>,
2149            SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2150   def _S : sve_fp_2op_p_zds<0b10, opc, asm, ZPR32>,
2151            SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2152   def _D : sve_fp_2op_p_zds<0b11, opc, asm, ZPR64>,
2153            SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2154   }
2156   def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2157   def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2158   def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2161 multiclass sve_fp_2op_p_zds_fscale<bits<4> opc, string asm,
2162                                    SDPatternOperator op> {
2163   def _H : sve_fp_2op_p_zds<0b01, opc, asm, ZPR16>;
2164   def _S : sve_fp_2op_p_zds<0b10, opc, asm, ZPR32>;
2165   def _D : sve_fp_2op_p_zds<0b11, opc, asm, ZPR64>;
2167   def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2168   def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2169   def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2172 multiclass sve_fp_2op_p_zds_zeroing_hsd<SDPatternOperator op> {
2173   def _H_ZERO : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesZero>;
2174   def _S_ZERO : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesZero>;
2175   def _D_ZERO : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesZero>;
2177   def : SVE_3_Op_Pat_SelZero<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Pseudo>(NAME # _H_ZERO)>;
2178   def : SVE_3_Op_Pat_SelZero<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Pseudo>(NAME # _S_ZERO)>;
2179   def : SVE_3_Op_Pat_SelZero<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Pseudo>(NAME # _D_ZERO)>;
2182 class sve_fp_ftmad<bits<2> sz, string asm, ZPRRegOp zprty>
2183 : I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, timm32_0_7:$imm3),
2184   asm, "\t$Zdn, $_Zdn, $Zm, $imm3",
2185   "",
2186   []>, Sched<[]> {
2187   bits<5> Zdn;
2188   bits<5> Zm;
2189   bits<3> imm3;
2190   let Inst{31-24} = 0b01100101;
2191   let Inst{23-22} = sz;
2192   let Inst{21-19} = 0b010;
2193   let Inst{18-16} = imm3;
2194   let Inst{15-10} = 0b100000;
2195   let Inst{9-5}   = Zm;
2196   let Inst{4-0}   = Zdn;
2198   let Constraints = "$Zdn = $_Zdn";
2199   let DestructiveInstType = DestructiveOther;
2200   let ElementSize = ElementSizeNone;
2201   let hasSideEffects = 0;
2202   let mayRaiseFPException = 1;
2205 multiclass sve_fp_ftmad<string asm, SDPatternOperator op> {
2206   def _H : sve_fp_ftmad<0b01, asm, ZPR16>;
2207   def _S : sve_fp_ftmad<0b10, asm, ZPR32>;
2208   def _D : sve_fp_ftmad<0b11, asm, ZPR64>;
2210   def : Pat<(nxv8f16 (op (nxv8f16 ZPR16:$Zn), (nxv8f16 ZPR16:$Zm), (i32 timm32_0_7:$imm))),
2211             (!cast<Instruction>(NAME # _H) ZPR16:$Zn, ZPR16:$Zm, timm32_0_7:$imm)>;
2212   def : Pat<(nxv4f32 (op (nxv4f32 ZPR32:$Zn), (nxv4f32 ZPR32:$Zm), (i32 timm32_0_7:$imm))),
2213             (!cast<Instruction>(NAME # _S) ZPR32:$Zn, ZPR32:$Zm, timm32_0_7:$imm)>;
2214   def : Pat<(nxv2f64 (op (nxv2f64 ZPR64:$Zn), (nxv2f64 ZPR64:$Zm), (i32 timm32_0_7:$imm))),
2215             (!cast<Instruction>(NAME # _D) ZPR64:$Zn, ZPR64:$Zm, timm32_0_7:$imm)>;
2218 multiclass sve_fp_2op_i_p_zds_hfd<Operand imm_ty, FPImmLeaf A, FPImmLeaf B, SDPatternOperator ir_op = null_frag> {
2219   def _H_UNDEF : PredTwoOpImmPseudo<NAME # _H, ZPR16, imm_ty, FalseLanesUndef>;
2220   def _S_UNDEF : PredTwoOpImmPseudo<NAME # _S, ZPR32, imm_ty, FalseLanesUndef>;
2221   def _D_UNDEF : PredTwoOpImmPseudo<NAME # _D, ZPR64, imm_ty, FalseLanesUndef>;
2223   def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, ir_op, nxv8i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2224   def : SVE_2_Op_Fp_Imm_Pat<nxv8f16, ir_op, nxv8i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2225   def : SVE_2_Op_Fp_Imm_Pat<nxv4f16, ir_op, nxv4i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2226   def : SVE_2_Op_Fp_Imm_Pat<nxv4f16, ir_op, nxv4i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2227   def : SVE_2_Op_Fp_Imm_Pat<nxv2f16, ir_op, nxv2i1, f16, A, 0, !cast<Instruction>(NAME # "_H_UNDEF")>;
2228   def : SVE_2_Op_Fp_Imm_Pat<nxv2f16, ir_op, nxv2i1, f16, B, 1, !cast<Instruction>(NAME # "_H_UNDEF")>;
2229   def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, ir_op, nxv4i1, f32, A, 0, !cast<Instruction>(NAME # "_S_UNDEF")>;
2230   def : SVE_2_Op_Fp_Imm_Pat<nxv4f32, ir_op, nxv4i1, f32, B, 1, !cast<Instruction>(NAME # "_S_UNDEF")>;
2231   def : SVE_2_Op_Fp_Imm_Pat<nxv2f32, ir_op, nxv2i1, f32, A, 0, !cast<Instruction>(NAME # "_S_UNDEF")>;
2232   def : SVE_2_Op_Fp_Imm_Pat<nxv2f32, ir_op, nxv2i1, f32, B, 1, !cast<Instruction>(NAME # "_S_UNDEF")>;
2233   def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, ir_op, nxv2i1, f64, A, 0, !cast<Instruction>(NAME # "_D_UNDEF")>;
2234   def : SVE_2_Op_Fp_Imm_Pat<nxv2f64, ir_op, nxv2i1, f64, B, 1, !cast<Instruction>(NAME # "_D_UNDEF")>;
2237 multiclass sve_fp_2op_i_p_zds_zeroing_hfd<Operand imm_ty, FPImmLeaf A, FPImmLeaf B, SDPatternOperator op> {
2238   def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, imm_ty, FalseLanesZero>;
2239   def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, imm_ty, FalseLanesZero>;
2240   def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, imm_ty, FalseLanesZero>;
2242   let AddedComplexity = 2 in {
2243     def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv8f16, op, nxv8i1, f16, A, 0, !cast<Instruction>(NAME # "_H_ZERO")>;
2244     def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv8f16, op, nxv8i1, f16, B, 1, !cast<Instruction>(NAME # "_H_ZERO")>;
2245     def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv4f32, op, nxv4i1, f32, A, 0, !cast<Instruction>(NAME # "_S_ZERO")>;
2246     def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv4f32, op, nxv4i1, f32, B, 1, !cast<Instruction>(NAME # "_S_ZERO")>;
2247     def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv2f64, op, nxv2i1, f64, A, 0, !cast<Instruction>(NAME # "_D_ZERO")>;
2248     def : SVE_2_Op_Fp_Imm_Pat_Zero<nxv2f64, op, nxv2i1, f64, B, 1, !cast<Instruction>(NAME # "_D_ZERO")>;
2249   }
2252 //===----------------------------------------------------------------------===//
2253 // SVE Floating Point Arithmetic - Unpredicated Group
2254 //===----------------------------------------------------------------------===//
2256 class sve_fp_3op_u_zd<bits<2> sz, bits<3> opc, string asm, ZPRRegOp zprty>
2257 : I<(outs zprty:$Zd), (ins  zprty:$Zn, zprty:$Zm),
2258   asm, "\t$Zd, $Zn, $Zm",
2259   "",
2260   []>, Sched<[]> {
2261   bits<5> Zd;
2262   bits<5> Zm;
2263   bits<5> Zn;
2264   let Inst{31-24} = 0b01100101;
2265   let Inst{23-22} = sz;
2266   let Inst{21}    = 0b0;
2267   let Inst{20-16} = Zm;
2268   let Inst{15-13} = 0b000;
2269   let Inst{12-10} = opc;
2270   let Inst{9-5}   = Zn;
2271   let Inst{4-0}   = Zd;
2273   let hasSideEffects = 0;
2274   let mayRaiseFPException = 1;
2277 multiclass sve_fp_3op_u_zd<bits<3> opc, string asm, SDPatternOperator op,
2278                            SDPatternOperator predicated_op = null_frag> {
2279   def _H : sve_fp_3op_u_zd<0b01, opc, asm, ZPR16>;
2280   def _S : sve_fp_3op_u_zd<0b10, opc, asm, ZPR32>;
2281   def _D : sve_fp_3op_u_zd<0b11, opc, asm, ZPR64>;
2283   def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2284   def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2285   def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2287   def : SVE_2_Op_Pred_All_Active<nxv8f16, predicated_op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2288   def : SVE_2_Op_Pred_All_Active<nxv4f32, predicated_op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2289   def : SVE_2_Op_Pred_All_Active<nxv2f64, predicated_op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2292 multiclass sve2p1_bf_3op_u_zd<bits<3> opc1, string asm, SDPatternOperator op,
2293                           SDPatternOperator predicated_op = null_frag> {
2294   def NAME : sve_fp_3op_u_zd<0b00, opc1, asm, ZPR16>;
2295   def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
2297   def : SVE_2_Op_Pred_All_Active<nxv8bf16, predicated_op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
2300 multiclass sve_fp_3op_u_zd_ftsmul<bits<3> opc, string asm, SDPatternOperator op> {
2301   def _H : sve_fp_3op_u_zd<0b01, opc, asm, ZPR16>;
2302   def _S : sve_fp_3op_u_zd<0b10, opc, asm, ZPR32>;
2303   def _D : sve_fp_3op_u_zd<0b11, opc, asm, ZPR64>;
2305   def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2306   def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2307   def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2310 //===----------------------------------------------------------------------===//
2311 // SVE Floating Point Fused Multiply-Add Group
2312 //===----------------------------------------------------------------------===//
2314 class sve_fp_3op_p_zds_a<bits<2> sz, bits<2> opc, string asm, ZPRRegOp zprty>
2315 : I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm),
2316   asm, "\t$Zda, $Pg/m, $Zn, $Zm",
2317   "",
2318   []>, Sched<[]> {
2319   bits<3> Pg;
2320   bits<5> Zda;
2321   bits<5> Zm;
2322   bits<5> Zn;
2323   let Inst{31-24} = 0b01100101;
2324   let Inst{23-22} = sz;
2325   let Inst{21}    = 0b1;
2326   let Inst{20-16} = Zm;
2327   let Inst{15}    = 0b0;
2328   let Inst{14-13} = opc;
2329   let Inst{12-10} = Pg;
2330   let Inst{9-5}   = Zn;
2331   let Inst{4-0}   = Zda;
2333   let Constraints = "$Zda = $_Zda";
2334   let ElementSize = zprty.ElementSize;
2335   let DestructiveInstType = DestructiveTernaryCommWithRev;
2336   let hasSideEffects = 0;
2337   let mayRaiseFPException = 1;
2340 multiclass sve_fp_3op_p_zds_a<bits<2> opc, string asm, string Ps,
2341                               SDPatternOperator op, string revname,
2342                               bit isReverseInstr=0> {
2343   def _H : sve_fp_3op_p_zds_a<0b01, opc, asm, ZPR16>,
2344            SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2345   def _S : sve_fp_3op_p_zds_a<0b10, opc, asm, ZPR32>,
2346            SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2347   def _D : sve_fp_3op_p_zds_a<0b11, opc, asm, ZPR64>,
2348            SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2350   def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2351   def : SVE_4_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H)>;
2352   def : SVE_4_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H)>;
2353   def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2354   def : SVE_4_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S)>;
2355   def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2358 multiclass sve_fp_3op_p_zds_a_bf<bits<2> opc, string asm, string Ps,
2359                               SDPatternOperator op> {
2360   def NAME : sve_fp_3op_p_zds_a<0b00, opc, asm, ZPR16>,
2361            SVEPseudo2Instr<Ps, 1>, SVEInstr2Rev<NAME, "", 0>;
2363   def : SVE_4_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
2366 class sve_fp_3op_p_zds_b<bits<2> sz, bits<2> opc, string asm,
2367                          ZPRRegOp zprty>
2368 : I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm, zprty:$Za),
2369   asm, "\t$Zdn, $Pg/m, $Zm, $Za",
2370   "",
2371   []>, Sched<[]> {
2372   bits<3> Pg;
2373   bits<5> Za;
2374   bits<5> Zdn;
2375   bits<5> Zm;
2376   let Inst{31-24} = 0b01100101;
2377   let Inst{23-22} = sz;
2378   let Inst{21}    = 0b1;
2379   let Inst{20-16} = Za;
2380   let Inst{15}    = 0b1;
2381   let Inst{14-13} = opc;
2382   let Inst{12-10} = Pg;
2383   let Inst{9-5}   = Zm;
2384   let Inst{4-0}   = Zdn;
2386   let Constraints = "$Zdn = $_Zdn";
2387   let DestructiveInstType = DestructiveOther;
2388   let ElementSize = zprty.ElementSize;
2389   let hasSideEffects = 0;
2390   let mayRaiseFPException = 1;
2393 multiclass sve_fp_3op_p_zds_b<bits<2> opc, string asm, SDPatternOperator op,
2394                               string revname, bit isReverseInstr> {
2395   def _H : sve_fp_3op_p_zds_b<0b01, opc, asm, ZPR16>,
2396            SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
2397   def _S : sve_fp_3op_p_zds_b<0b10, opc, asm, ZPR32>,
2398            SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
2399   def _D : sve_fp_3op_p_zds_b<0b11, opc, asm, ZPR64>,
2400            SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
2402   def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2403   def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2404   def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2407 //===----------------------------------------------------------------------===//
2408 // SVE Floating Point Multiply-Add - Indexed Group
2409 //===----------------------------------------------------------------------===//
2411 class sve_fp_fma_by_indexed_elem<bits<2> sz, bits<2> opc, string asm,
2412                                  ZPRRegOp zprty1,
2413                                  ZPRRegOp zprty2, Operand itype>
2414 : I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty1:$Zn, zprty2:$Zm, itype:$iop),
2415   asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
2416   bits<5> Zda;
2417   bits<5> Zn;
2418   let Inst{31-24} = 0b01100100;
2419   let Inst{23-22} = sz;
2420   let Inst{21}    = 0b1;
2421   let Inst{15-12} = 0b0000;
2422   let Inst{11-10} = opc;
2423   let Inst{9-5}   = Zn;
2424   let Inst{4-0}   = Zda;
2426   let Constraints = "$Zda = $_Zda";
2427   let DestructiveInstType = DestructiveOther;
2428   let ElementSize = ElementSizeNone;
2429   let hasSideEffects = 0;
2430   let mayRaiseFPException = 1;
2433 multiclass sve2p1_fp_bfma_by_indexed_elem<string asm, bits<2> opc, SDPatternOperator op> {
2434   def NAME : sve_fp_fma_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR3b16,
2435                                          VectorIndexH32b> {
2436     bits<3> Zm;
2437     bits<3> iop;
2438     let Inst{22} = iop{2};
2439     let Inst{20-19} = iop{1-0};
2440     let Inst{18-16} = Zm;
2441   }
2442   def : Pat<(nxv8bf16 (op nxv8bf16:$op1, nxv8bf16:$op2, nxv8bf16:$op3, (i32 VectorIndexH32b_timm:$idx))),
2443             (!cast<Instruction>(NAME) $op1, $op2, $op3, VectorIndexH32b_timm:$idx)>;
2446 multiclass sve_fp_fma_by_indexed_elem<bits<2> opc, string asm,
2447                                       SDPatternOperator op> {
2448   def _H : sve_fp_fma_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2449     bits<3> Zm;
2450     bits<3> iop;
2451     let Inst{22} = iop{2};
2452     let Inst{20-19} = iop{1-0};
2453     let Inst{18-16} = Zm;
2454   }
2455   def _S : sve_fp_fma_by_indexed_elem<0b10, opc, asm, ZPR32, ZPR3b32, VectorIndexS32b> {
2456     bits<3> Zm;
2457     bits<2> iop;
2458     let Inst{20-19} = iop;
2459     let Inst{18-16} = Zm;
2460   }
2461   def _D : sve_fp_fma_by_indexed_elem<0b11, opc, asm, ZPR64, ZPR4b64, VectorIndexD32b> {
2462     bits<4> Zm;
2463     bit iop;
2464     let Inst{20} = iop;
2465     let Inst{19-16} = Zm;
2466   }
2468   def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 VectorIndexH32b_timm:$idx))),
2469             (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, VectorIndexH32b_timm:$idx)>;
2470   def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 VectorIndexS32b_timm:$idx))),
2471             (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, VectorIndexS32b_timm:$idx)>;
2472   def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, (i32 VectorIndexD32b_timm:$idx))),
2473             (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, VectorIndexD32b_timm:$idx)>;
2477 //===----------------------------------------------------------------------===//
2478 // SVE Floating Point Multiply - Indexed Group
2479 //===----------------------------------------------------------------------===//
2481 class sve_fp_fmul_by_indexed_elem<bits<2> sz, bit o2, string asm, ZPRRegOp zprty,
2482                                   ZPRRegOp zprty2, Operand itype>
2483 : I<(outs zprty:$Zd), (ins zprty:$Zn, zprty2:$Zm, itype:$iop),
2484   asm, "\t$Zd, $Zn, $Zm$iop", "", []>, Sched<[]> {
2485   bits<5> Zd;
2486   bits<5> Zn;
2487   let Inst{31-24} = 0b01100100;
2488   let Inst{23-22} = sz;
2489   let Inst{21}    = 0b1;
2490   let Inst{15-12} = 0b0010;
2491   let Inst{11}    = o2;
2492   let Inst{10}    = 0b0;
2493   let Inst{9-5}   = Zn;
2494   let Inst{4-0}   = Zd;
2496   let hasSideEffects = 0;
2497   let mayRaiseFPException = 1;
2500 multiclass sve2p1_fp_bfmul_by_indexed_elem<string asm, SDPatternOperator ir_intrinsic> {
2501   def NAME : sve_fp_fmul_by_indexed_elem<{0, ?}, 0b1, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2502     bits<3> Zm;
2503     bits<3> iop;
2504     let Inst{22} = iop{2};
2505     let Inst{20-19} = iop{1-0};
2506     let Inst{18-16} = Zm;
2507   }
2508   def : Pat <(nxv8bf16 (ir_intrinsic nxv8bf16:$Op1, nxv8bf16:$Op2, (i32 VectorIndexH32b_timm:$idx))),
2509              (!cast<Instruction>(NAME) $Op1, $Op2, VectorIndexH32b_timm:$idx)>;
2512 multiclass sve_fp_fmul_by_indexed_elem<string asm, SDPatternOperator op> {
2513   def _H : sve_fp_fmul_by_indexed_elem<{0, ?}, 0b0, asm, ZPR16, ZPR3b16, VectorIndexH32b> {
2514     bits<3> Zm;
2515     bits<3> iop;
2516     let Inst{22} = iop{2};
2517     let Inst{20-19} = iop{1-0};
2518     let Inst{18-16} = Zm;
2519   }
2520   def _S : sve_fp_fmul_by_indexed_elem<0b10, 0b0, asm, ZPR32, ZPR3b32, VectorIndexS32b> {
2521     bits<3> Zm;
2522     bits<2> iop;
2523     let Inst{20-19} = iop;
2524     let Inst{18-16} = Zm;
2525   }
2526   def _D : sve_fp_fmul_by_indexed_elem<0b11, 0b0, asm, ZPR64, ZPR4b64, VectorIndexD32b> {
2527     bits<4> Zm;
2528     bit iop;
2529     let Inst{20} = iop;
2530     let Inst{19-16} = Zm;
2531   }
2533   def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, (i32 VectorIndexH32b_timm:$idx))),
2534             (!cast<Instruction>(NAME # _H) $Op1, $Op2, VectorIndexH32b_timm:$idx)>;
2535   def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, (i32 VectorIndexS32b_timm:$idx))),
2536             (!cast<Instruction>(NAME # _S) $Op1, $Op2, VectorIndexS32b_timm:$idx)>;
2537   def : Pat<(nxv2f64 (op nxv2f64:$Op1, nxv2f64:$Op2, (i32 VectorIndexD32b_timm:$idx))),
2538             (!cast<Instruction>(NAME # _D) $Op1, $Op2, VectorIndexD32b_timm:$idx)>;
2541 //===----------------------------------------------------------------------===//
2542 // SVE Floating Point Complex Multiply-Add Group
2543 //===----------------------------------------------------------------------===//
2545 class sve_fp_fcmla<bits<2> sz, string asm, ZPRRegOp zprty>
2546 : I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm,
2547                         complexrotateop:$imm),
2548   asm, "\t$Zda, $Pg/m, $Zn, $Zm, $imm",
2549   "", []>, Sched<[]> {
2550   bits<5> Zda;
2551   bits<3> Pg;
2552   bits<5> Zn;
2553   bits<5> Zm;
2554   bits<2> imm;
2555   let Inst{31-24} = 0b01100100;
2556   let Inst{23-22} = sz;
2557   let Inst{21}    = 0;
2558   let Inst{20-16} = Zm;
2559   let Inst{15}    = 0;
2560   let Inst{14-13} = imm;
2561   let Inst{12-10} = Pg;
2562   let Inst{9-5}   = Zn;
2563   let Inst{4-0}   = Zda;
2565   let Constraints = "$Zda = $_Zda";
2566   let DestructiveInstType = DestructiveOther;
2567   let ElementSize = zprty.ElementSize;
2568   let hasSideEffects = 0;
2569   let mayRaiseFPException = 1;
2572 multiclass sve_fp_fcmla<string asm, SDPatternOperator op> {
2573   def _H : sve_fp_fcmla<0b01, asm, ZPR16>;
2574   def _S : sve_fp_fcmla<0b10, asm, ZPR32>;
2575   def _D : sve_fp_fcmla<0b11, asm, ZPR64>;
2577   def : Pat<(nxv8f16 (op nxv8i1:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, nxv8f16:$Op4, (i32 complexrotateop:$imm))),
2578             (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2579   def : Pat<(nxv4f32 (op nxv4i1:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, nxv4f32:$Op4, (i32 complexrotateop:$imm))),
2580             (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2581   def : Pat<(nxv2f64 (op nxv2i1:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, nxv2f64:$Op4, (i32 complexrotateop:$imm))),
2582             (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, $Op4, complexrotateop:$imm)>;
2585 //===----------------------------------------------------------------------===//
2586 // SVE Floating Point Complex Multiply-Add - Indexed Group
2587 //===----------------------------------------------------------------------===//
2589 class sve_fp_fcmla_by_indexed_elem<bits<2> sz, string asm,
2590                                    ZPRRegOp zprty,
2591                                    ZPRRegOp zprty2, Operand itype>
2592 : I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, zprty2:$Zm, itype:$iop,
2593                         complexrotateop:$imm),
2594   asm, "\t$Zda, $Zn, $Zm$iop, $imm",
2595   "", []>, Sched<[]> {
2596   bits<5> Zda;
2597   bits<5> Zn;
2598   bits<2> imm;
2599   let Inst{31-24} = 0b01100100;
2600   let Inst{23-22} = sz;
2601   let Inst{21}    = 0b1;
2602   let Inst{15-12} = 0b0001;
2603   let Inst{11-10} = imm;
2604   let Inst{9-5}   = Zn;
2605   let Inst{4-0}   = Zda;
2607   let Constraints = "$Zda = $_Zda";
2608   let DestructiveInstType = DestructiveOther;
2609   let ElementSize = ElementSizeNone;
2610   let hasSideEffects = 0;
2611   let mayRaiseFPException = 1;
2614 multiclass sve_fp_fcmla_by_indexed_elem<string asm, SDPatternOperator op> {
2615   def _H : sve_fp_fcmla_by_indexed_elem<0b10, asm, ZPR16, ZPR3b16, VectorIndexS32b> {
2616     bits<3> Zm;
2617     bits<2> iop;
2618     let Inst{20-19} = iop;
2619     let Inst{18-16} = Zm;
2620   }
2621   def _S : sve_fp_fcmla_by_indexed_elem<0b11, asm, ZPR32, ZPR4b32, VectorIndexD32b> {
2622     bits<4> Zm;
2623     bits<1> iop;
2624     let Inst{20} = iop;
2625     let Inst{19-16} = Zm;
2626   }
2628   def : Pat<(nxv8f16 (op nxv8f16:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
2629             (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
2630   def : Pat<(nxv4f32 (op nxv4f32:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
2631             (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
2634 //===----------------------------------------------------------------------===//
2635 // SVE Floating Point Complex Addition Group
2636 //===----------------------------------------------------------------------===//
2638 class sve_fp_fcadd<bits<2> sz, string asm, ZPRRegOp zprty>
2639 : I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm,
2640                         complexrotateopodd:$imm),
2641   asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm, $imm",
2642   "",
2643   []>, Sched<[]> {
2644   bits<5> Zdn;
2645   bits<5> Zm;
2646   bits<3> Pg;
2647   bit imm;
2648   let Inst{31-24} = 0b01100100;
2649   let Inst{23-22} = sz;
2650   let Inst{21-17} = 0;
2651   let Inst{16}    = imm;
2652   let Inst{15-13} = 0b100;
2653   let Inst{12-10} = Pg;
2654   let Inst{9-5}   = Zm;
2655   let Inst{4-0}   = Zdn;
2657   let Constraints = "$Zdn = $_Zdn";
2658   let DestructiveInstType = DestructiveOther;
2659   let ElementSize = zprty.ElementSize;
2660   let hasSideEffects = 0;
2661   let mayRaiseFPException = 1;
2664 multiclass sve_fp_fcadd<string asm, SDPatternOperator op> {
2665   def _H : sve_fp_fcadd<0b01, asm, ZPR16>;
2666   def _S : sve_fp_fcadd<0b10, asm, ZPR32>;
2667   def _D : sve_fp_fcadd<0b11, asm, ZPR64>;
2669   def : Pat<(nxv8f16 (op nxv8i1:$Op1, nxv8f16:$Op2, nxv8f16:$Op3, (i32 complexrotateopodd:$imm))),
2670             (!cast<Instruction>(NAME # _H) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2671   def : Pat<(nxv4f32 (op nxv4i1:$Op1, nxv4f32:$Op2, nxv4f32:$Op3, (i32 complexrotateopodd:$imm))),
2672             (!cast<Instruction>(NAME # _S) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2673   def : Pat<(nxv2f64 (op nxv2i1:$Op1, nxv2f64:$Op2, nxv2f64:$Op3, (i32 complexrotateopodd:$imm))),
2674             (!cast<Instruction>(NAME # _D) $Op1, $Op2, $Op3, complexrotateopodd:$imm)>;
2677 //===----------------------------------------------------------------------===//
2678 // SVE2 Floating Point Convert Group
2679 //===----------------------------------------------------------------------===//
2681 class sve2_fp_convert_precision<bits<4> opc, string asm,
2682                                 ZPRRegOp zprty1, ZPRRegOp zprty2>
2683 : I<(outs zprty1:$Zd), (ins zprty1:$_Zd, PPR3bAny:$Pg, zprty2:$Zn),
2684   asm, "\t$Zd, $Pg/m, $Zn",
2685   "",
2686   []>, Sched<[]> {
2687   bits<5> Zd;
2688   bits<5> Zn;
2689   bits<3> Pg;
2690   let Inst{31-24} = 0b01100100;
2691   let Inst{23-22} = opc{3-2};
2692   let Inst{21-18} = 0b0010;
2693   let Inst{17-16} = opc{1-0};
2694   let Inst{15-13} = 0b101;
2695   let Inst{12-10} = Pg;
2696   let Inst{9-5}   = Zn;
2697   let Inst{4-0}   = Zd;
2699   let Constraints = "$Zd = $_Zd";
2700   let hasSideEffects = 0;
2701   let mayRaiseFPException = 1;
2704 multiclass sve2_fp_convert_down_narrow<string asm, string op> {
2705   def _StoH : sve2_fp_convert_precision<0b1000, asm, ZPR16, ZPR32>;
2706   def _DtoS : sve2_fp_convert_precision<0b1110, asm, ZPR32, ZPR64>;
2708   def : SVE_3_Op_Pat<nxv8f16, !cast<SDPatternOperator>(op # _f16f32), nxv8f16, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _StoH)>;
2709   def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
2712 multiclass sve2_fp_convert_up_long<string asm, string op> {
2713   def _HtoS : sve2_fp_convert_precision<0b1001, asm, ZPR32, ZPR16>;
2714   def _StoD : sve2_fp_convert_precision<0b1111, asm, ZPR64, ZPR32>;
2716   def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f16), nxv4f32, nxv4i1, nxv8f16, !cast<Instruction>(NAME # _HtoS)>;
2717   def : SVE_3_Op_Pat<nxv2f64, !cast<SDPatternOperator>(op # _f64f32), nxv2f64, nxv2i1, nxv4f32, !cast<Instruction>(NAME # _StoD)>;
2720 multiclass sve2_fp_convert_down_odd_rounding_top<string asm, string op> {
2721   def _DtoS : sve2_fp_convert_precision<0b0010, asm, ZPR32, ZPR64>;
2723   def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
2726 //===----------------------------------------------------------------------===//
2727 // SVE2 Floating Point Pairwise Group
2728 //===----------------------------------------------------------------------===//
2730 class sve2_fp_pairwise_pred<bits<2> sz, bits<3> opc, string asm,
2731                             ZPRRegOp zprty>
2732 : I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
2733   asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
2734   "",
2735   []>, Sched<[]> {
2736   bits<3> Pg;
2737   bits<5> Zm;
2738   bits<5> Zdn;
2739   let Inst{31-24} = 0b01100100;
2740   let Inst{23-22} = sz;
2741   let Inst{21-19} = 0b010;
2742   let Inst{18-16} = opc;
2743   let Inst{15-13} = 0b100;
2744   let Inst{12-10} = Pg;
2745   let Inst{9-5}   = Zm;
2746   let Inst{4-0}   = Zdn;
2748   let Constraints = "$Zdn = $_Zdn";
2749   let DestructiveInstType = DestructiveOther;
2750   let ElementSize = zprty.ElementSize;
2751   let hasSideEffects = 0;
2752   let mayRaiseFPException = 1;
2755 multiclass sve2_fp_pairwise_pred<bits<3> opc, string asm,
2756                                  SDPatternOperator op> {
2757   def _H : sve2_fp_pairwise_pred<0b01, opc, asm, ZPR16>;
2758   def _S : sve2_fp_pairwise_pred<0b10, opc, asm, ZPR32>;
2759   def _D : sve2_fp_pairwise_pred<0b11, opc, asm, ZPR64>;
2761   def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2762   def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2763   def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2766 //===----------------------------------------------------------------------===//
2767 // SVE2 Floating Point Widening Multiply-Add - Indexed Group
2768 //===----------------------------------------------------------------------===//
2770 class sve2_fp_mla_long_by_indexed_elem<bits<3> opc, string asm>
2771 : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR3b16:$Zm,
2772                         VectorIndexH32b:$iop),
2773   asm, "\t$Zda, $Zn, $Zm$iop",
2774   "",
2775   []>, Sched<[]> {
2776   bits<5> Zda;
2777   bits<5> Zn;
2778   bits<3> Zm;
2779   bits<3> iop;
2780   let Inst{31-23} = 0b011001001;
2781   let Inst{22}    = opc{2};
2782   let Inst{21}    = 0b1;
2783   let Inst{20-19} = iop{2-1};
2784   let Inst{18-16} = Zm;
2785   let Inst{15-14} = 0b01;
2786   let Inst{13}    = opc{1};
2787   let Inst{12}    = 0b0;
2788   let Inst{11}    = iop{0};
2789   let Inst{10}    = opc{0};
2790   let Inst{9-5}   = Zn;
2791   let Inst{4-0}   = Zda;
2793   let Constraints = "$Zda = $_Zda";
2794   let DestructiveInstType = DestructiveOther;
2795   let ElementSize = ElementSizeNone;
2796   let hasSideEffects = 0;
2797   let mayRaiseFPException = 1;
2800 multiclass sve2_fp_mla_long_by_indexed_elem<bits<3> opc, string asm,
2801                                             ValueType OutVT, ValueType InVT,
2802                                             SDPatternOperator op> {
2803   def NAME : sve2_fp_mla_long_by_indexed_elem<opc, asm>;
2804   def : SVE_4_Op_Imm_Pat<OutVT, op, OutVT, InVT, InVT, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME)>;
2807 //===----------------------------------------------------------------------===//
2808 // SVE2 Floating Point Widening Multiply-Add Group
2809 //===----------------------------------------------------------------------===//
2811 class sve2_fp_mla_long<bits<3> opc, string asm>
2812 : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
2813   asm, "\t$Zda, $Zn, $Zm",
2814   "",
2815   []>, Sched<[]> {
2816   bits<5> Zda;
2817   bits<5> Zn;
2818   bits<5> Zm;
2819   let Inst{31-23} = 0b011001001;
2820   let Inst{22}    = opc{2};
2821   let Inst{21}    = 0b1;
2822   let Inst{20-16} = Zm;
2823   let Inst{15-14} = 0b10;
2824   let Inst{13}    = opc{1};
2825   let Inst{12-11} = 0b00;
2826   let Inst{10}    = opc{0};
2827   let Inst{9-5}   = Zn;
2828   let Inst{4-0}   = Zda;
2830   let Constraints = "$Zda = $_Zda";
2831   let DestructiveInstType = DestructiveOther;
2832   let ElementSize = ElementSizeNone;
2833   let hasSideEffects = 0;
2834   let mayRaiseFPException = 1;
2837 multiclass sve2_fp_mla_long<bits<3> opc, string asm, ValueType OutVT,
2838                             ValueType InVT, SDPatternOperator op> {
2839   def NAME : sve2_fp_mla_long<opc, asm>;
2840   def : SVE_3_Op_Pat<OutVT, op, OutVT, InVT, InVT, !cast<Instruction>(NAME)>;
2843 //===----------------------------------------------------------------------===//
2844 // SVE Stack Allocation Group
2845 //===----------------------------------------------------------------------===//
2847 class sve_int_arith_vl<bit opc, string asm, bit streaming_sve = 0b0>
2848 : I<(outs GPR64sp:$Rd), (ins GPR64sp:$Rn, simm6_32b:$imm6),
2849   asm, "\t$Rd, $Rn, $imm6",
2850   "",
2851   []>, Sched<[]> {
2852   bits<5> Rd;
2853   bits<5> Rn;
2854   bits<6> imm6;
2855   let Inst{31-23} = 0b000001000;
2856   let Inst{22}    = opc;
2857   let Inst{21}    = 0b1;
2858   let Inst{20-16} = Rn;
2859   let Inst{15-12} = 0b0101;
2860   let Inst{11}    = streaming_sve;
2861   let Inst{10-5}  = imm6;
2862   let Inst{4-0}   = Rd;
2864   let hasSideEffects = 0;
2867 class sve_int_read_vl_a<bit op, bits<5> opc2, string asm, bit streaming_sve = 0b0>
2868 : I<(outs GPR64:$Rd), (ins simm6_32b:$imm6),
2869   asm, "\t$Rd, $imm6",
2870   "",
2871   []>, Sched<[]> {
2872   bits<5> Rd;
2873   bits<6> imm6;
2874   let Inst{31-23} = 0b000001001;
2875   let Inst{22}    = op;
2876   let Inst{21}    = 0b1;
2877   let Inst{20-16} = opc2{4-0};
2878   let Inst{15-12} = 0b0101;
2879   let Inst{11}    = streaming_sve;
2880   let Inst{10-5}  = imm6;
2881   let Inst{4-0}   = Rd;
2883   let hasSideEffects = 0;
2884   let isReMaterializable = 1;
2887 //===----------------------------------------------------------------------===//
2888 // SVE Permute - In Lane Group
2889 //===----------------------------------------------------------------------===//
2891 class sve_int_perm_bin_perm_zz<bits<3> opc, bits<2> sz8_64, string asm,
2892                                ZPRRegOp zprty>
2893 : I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
2894   asm, "\t$Zd, $Zn, $Zm",
2895   "",
2896   []>, Sched<[]> {
2897   bits<5> Zd;
2898   bits<5> Zm;
2899   bits<5> Zn;
2900   let Inst{31-24} = 0b00000101;
2901   let Inst{23-22} = sz8_64;
2902   let Inst{21}    = 0b1;
2903   let Inst{20-16} = Zm;
2904   let Inst{15-13} = 0b011;
2905   let Inst{12-10} = opc;
2906   let Inst{9-5}   = Zn;
2907   let Inst{4-0}   = Zd;
2909   let hasSideEffects = 0;
2912 multiclass sve_int_perm_bin_perm_zz<bits<3> opc, string asm,
2913                                     SDPatternOperator op> {
2914   def _B : sve_int_perm_bin_perm_zz<opc, 0b00, asm, ZPR8>;
2915   def _H : sve_int_perm_bin_perm_zz<opc, 0b01, asm, ZPR16>;
2916   def _S : sve_int_perm_bin_perm_zz<opc, 0b10, asm, ZPR32>;
2917   def _D : sve_int_perm_bin_perm_zz<opc, 0b11, asm, ZPR64>;
2919   def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
2920   def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
2921   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
2922   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
2924   def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
2925   def : SVE_2_Op_Pat<nxv4f16, op, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _S)>;
2926   def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
2927   def : SVE_2_Op_Pat<nxv2f16, op, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _D)>;
2928   def : SVE_2_Op_Pat<nxv2f32, op, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _D)>;
2929   def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
2931   def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
2934 //===----------------------------------------------------------------------===//
2935 // SVE Floating Point Unary Operations Group
2936 //===----------------------------------------------------------------------===//
2938 class sve_fp_2op_p_zd<bits<7> opc, string asm, RegisterOperand i_zprtype,
2939                       RegisterOperand o_zprtype, ElementSizeEnum Sz>
2940 : I<(outs o_zprtype:$Zd), (ins i_zprtype:$_Zd, PPR3bAny:$Pg, i_zprtype:$Zn),
2941   asm, "\t$Zd, $Pg/m, $Zn",
2942   "",
2943   []>, Sched<[]> {
2944   bits<3> Pg;
2945   bits<5> Zd;
2946   bits<5> Zn;
2947   let Inst{31-24} = 0b01100101;
2948   let Inst{23-22} = opc{6-5};
2949   let Inst{21}    = 0b0;
2950   let Inst{20-16} = opc{4-0};
2951   let Inst{15-13} = 0b101;
2952   let Inst{12-10} = Pg;
2953   let Inst{9-5}   = Zn;
2954   let Inst{4-0}   = Zd;
2956   let Constraints = "$Zd = $_Zd";
2957   let DestructiveInstType = DestructiveUnaryPassthru;
2958   let ElementSize = Sz;
2959   let hasSideEffects = 0;
2960   let mayRaiseFPException = 1;
2963 multiclass sve_fp_2op_p_zd<bits<7> opc, string asm,
2964                            RegisterOperand i_zprtype,
2965                            RegisterOperand o_zprtype,
2966                            SDPatternOperator int_op,
2967                            SDPatternOperator ir_op, ValueType vt1,
2968                            ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
2969   def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>,
2970              SVEPseudo2Instr<NAME, 1>;
2971   // convert vt1 to a packed type for the intrinsic patterns
2972   defvar packedvt1 = SVEContainerVT<vt1>.Value;
2974   // convert vt3 to a packed type for the intrinsic patterns
2975   defvar packedvt3 = SVEContainerVT<vt3>.Value;
2977   def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, packedvt3, !cast<Instruction>(NAME)>;
2978   def : SVE_1_Op_Passthru_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
2980   def _UNDEF : PredOneOpPassthruPseudo<NAME, !cast<ZPRRegOp>(i_zprtype)>;
2982   defm : SVE_1_Op_PassthruUndef_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME # _UNDEF)>;
2985 multiclass sve_fp_2op_p_zdr<bits<7> opc, string asm,
2986                             RegisterOperand i_zprtype,
2987                             RegisterOperand o_zprtype,
2988                             SDPatternOperator int_op,
2989                             SDPatternOperator ir_op, ValueType vt1,
2990                             ValueType vt2, ValueType vt3, ElementSizeEnum Sz> {
2991   def NAME : sve_fp_2op_p_zd<opc, asm, i_zprtype, o_zprtype, Sz>,
2992              SVEPseudo2Instr<NAME, 1>;
2994   // convert vt1 to a packed type for the intrinsic patterns
2995   defvar packedvt1 = SVEContainerVT<vt1>.Value;
2997   def : SVE_3_Op_Pat<packedvt1, int_op, packedvt1, vt2, vt3, !cast<Instruction>(NAME)>;
2998   def : SVE_1_Op_Passthru_Round_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME)>;
3000   def _UNDEF : PredOneOpPassthruPseudo<NAME, !cast<ZPRRegOp>(i_zprtype)>;
3002   defm : SVE_1_Op_PassthruUndef_Round_Pat<vt1, ir_op, vt2, vt3, !cast<Instruction>(NAME # _UNDEF)>;
3005 multiclass sve_fp_2op_p_zd_HSD<bits<5> opc, string asm, SDPatternOperator op> {
3006   def _H : sve_fp_2op_p_zd<{ 0b01, opc }, asm, ZPR16, ZPR16, ElementSizeH>,
3007            SVEPseudo2Instr<NAME # _H, 1>;
3008   def _S : sve_fp_2op_p_zd<{ 0b10, opc }, asm, ZPR32, ZPR32, ElementSizeS>,
3009            SVEPseudo2Instr<NAME # _S, 1>;
3010   def _D : sve_fp_2op_p_zd<{ 0b11, opc }, asm, ZPR64, ZPR64, ElementSizeD>,
3011            SVEPseudo2Instr<NAME # _D, 1>;
3013   def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
3014   def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
3015   def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
3016   def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
3017   def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
3018   def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
3020   def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
3021   def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
3022   def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
3024   defm : SVE_1_Op_PassthruUndef_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H_UNDEF)>;
3025   defm : SVE_1_Op_PassthruUndef_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H_UNDEF)>;
3026   defm : SVE_1_Op_PassthruUndef_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H_UNDEF)>;
3027   defm : SVE_1_Op_PassthruUndef_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S_UNDEF)>;
3028   defm : SVE_1_Op_PassthruUndef_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S_UNDEF)>;
3029   defm : SVE_1_Op_PassthruUndef_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D_UNDEF)>;
3032 multiclass sve2_fp_flogb<string asm, string Ps, SDPatternOperator op> {
3033   def _H : sve_fp_2op_p_zd<0b0011010, asm, ZPR16, ZPR16, ElementSizeH>,
3034              SVEPseudo2Instr<Ps # _H, 1>;
3035   def _S : sve_fp_2op_p_zd<0b0011100, asm, ZPR32, ZPR32, ElementSizeS>,
3036              SVEPseudo2Instr<Ps # _S, 1>;
3037   def _D : sve_fp_2op_p_zd<0b0011110, asm, ZPR64, ZPR64, ElementSizeD>,
3038              SVEPseudo2Instr<Ps # _D, 1>;
3040   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
3041   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
3042   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
3045 multiclass sve2_fp_un_pred_zeroing_hsd<SDPatternOperator op> {
3046   def _H_ZERO : PredOneOpPassthruPseudo<NAME # _H, ZPR16, FalseLanesZero>;
3047   def _S_ZERO : PredOneOpPassthruPseudo<NAME # _S, ZPR32, FalseLanesZero>;
3048   def _D_ZERO : PredOneOpPassthruPseudo<NAME # _D, ZPR64, FalseLanesZero>;
3050   def : SVE_1_Op_PassthruZero_Pat<nxv8i16, op, nxv8i1, nxv8f16, !cast<Pseudo>(NAME # _H_ZERO)>;
3051   def : SVE_1_Op_PassthruZero_Pat<nxv4i32, op, nxv4i1, nxv4f32, !cast<Pseudo>(NAME # _S_ZERO)>;
3052   def : SVE_1_Op_PassthruZero_Pat<nxv2i64, op, nxv2i1, nxv2f64, !cast<Pseudo>(NAME # _D_ZERO)>;
3055 multiclass sve2_fp_convert_down_odd_rounding<string asm, string op> {
3056   def _DtoS : sve_fp_2op_p_zd<0b0001010, asm, ZPR64, ZPR32, ElementSizeD>;
3057   def : SVE_3_Op_Pat<nxv4f32, !cast<SDPatternOperator>(op # _f32f64), nxv4f32, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _DtoS)>;
3060 //===----------------------------------------------------------------------===//
3061 // SVE Floating Point Unary Operations - Unpredicated Group
3062 //===----------------------------------------------------------------------===//
3064 class sve_fp_2op_u_zd<bits<2> sz, bits<3> opc, string asm,
3065                       ZPRRegOp zprty>
3066 : I<(outs zprty:$Zd), (ins zprty:$Zn),
3067   asm, "\t$Zd, $Zn",
3068   "",
3069   []>, Sched<[]> {
3070   bits<5> Zd;
3071   bits<5> Zn;
3072   let Inst{31-24} = 0b01100101;
3073   let Inst{23-22} = sz;
3074   let Inst{21-19} = 0b001;
3075   let Inst{18-16} = opc;
3076   let Inst{15-10} = 0b001100;
3077   let Inst{9-5}   = Zn;
3078   let Inst{4-0}   = Zd;
3080   let hasSideEffects = 0;
3081   let mayRaiseFPException = 1;
3084 multiclass sve_fp_2op_u_zd<bits<3> opc, string asm, SDPatternOperator op> {
3085   def _H : sve_fp_2op_u_zd<0b01, opc, asm, ZPR16>;
3086   def _S : sve_fp_2op_u_zd<0b10, opc, asm, ZPR32>;
3087   def _D : sve_fp_2op_u_zd<0b11, opc, asm, ZPR64>;
3089   def : SVE_1_Op_Pat<nxv8f16, op, nxv8f16, !cast<Instruction>(NAME # _H)>;
3090   def : SVE_1_Op_Pat<nxv4f32, op, nxv4f32, !cast<Instruction>(NAME # _S)>;
3091   def : SVE_1_Op_Pat<nxv2f64, op, nxv2f64, !cast<Instruction>(NAME # _D)>;
3094 //===----------------------------------------------------------------------===//
3095 // SVE Integer Arithmetic - Binary Predicated Group
3096 //===----------------------------------------------------------------------===//
3098 class sve_int_bin_pred_arit_log<bits<2> sz8_64, bits<2> fmt, bits<3> opc,
3099                                 string asm, ZPRRegOp zprty>
3100 : I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
3101   asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm", "", []>, Sched<[]> {
3102   bits<3> Pg;
3103   bits<5> Zdn;
3104   bits<5> Zm;
3105   let Inst{31-24} = 0b00000100;
3106   let Inst{23-22} = sz8_64;
3107   let Inst{21}    = 0b0;
3108   let Inst{20-19} = fmt;
3109   let Inst{18-16} = opc;
3110   let Inst{15-13} = 0b000;
3111   let Inst{12-10} = Pg;
3112   let Inst{9-5}   = Zm;
3113   let Inst{4-0}   = Zdn;
3115   let Constraints = "$Zdn = $_Zdn";
3116   let DestructiveInstType = DestructiveOther;
3117   let ElementSize = zprty.ElementSize;
3118   let hasSideEffects = 0;
3121 multiclass sve_int_bin_pred_log<bits<3> opc, string asm, string Ps,
3122                                 SDPatternOperator op,
3123                                 DestructiveInstTypeEnum flags> {
3124   let DestructiveInstType = flags in {
3125   def _B : sve_int_bin_pred_arit_log<0b00, 0b11, opc, asm, ZPR8>,
3126              SVEPseudo2Instr<Ps # _B, 1>;
3127   def _H : sve_int_bin_pred_arit_log<0b01, 0b11, opc, asm, ZPR16>,
3128              SVEPseudo2Instr<Ps # _H, 1>;
3129   def _S : sve_int_bin_pred_arit_log<0b10, 0b11, opc, asm, ZPR32>,
3130              SVEPseudo2Instr<Ps # _S, 1>;
3131   def _D : sve_int_bin_pred_arit_log<0b11, 0b11, opc, asm, ZPR64>,
3132              SVEPseudo2Instr<Ps # _D, 1>;
3133   }
3135   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3136   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3137   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3138   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3141 multiclass sve_int_bin_pred_arit_0<bits<3> opc, string asm, string Ps,
3142                                    SDPatternOperator op,
3143                                    DestructiveInstTypeEnum flags,
3144                                    string revname="", bit isReverseInstr=0> {
3145   let DestructiveInstType = flags in {
3146   def _B : sve_int_bin_pred_arit_log<0b00, 0b00, opc, asm, ZPR8>,
3147            SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3148   def _H : sve_int_bin_pred_arit_log<0b01, 0b00, opc, asm, ZPR16>,
3149            SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3150   def _S : sve_int_bin_pred_arit_log<0b10, 0b00, opc, asm, ZPR32>,
3151            SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3152   def _D : sve_int_bin_pred_arit_log<0b11, 0b00, opc, asm, ZPR64>,
3153            SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3154   }
3156   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3157   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3158   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3159   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3162 multiclass sve_int_bin_pred_arit_1<bits<3> opc, string asm, string Ps,
3163                                    SDPatternOperator op,
3164                                    DestructiveInstTypeEnum flags> {
3165   let DestructiveInstType = flags in {
3166   def _B : sve_int_bin_pred_arit_log<0b00, 0b01, opc, asm, ZPR8>,
3167            SVEPseudo2Instr<Ps # _B, 1>;
3168   def _H : sve_int_bin_pred_arit_log<0b01, 0b01, opc, asm, ZPR16>,
3169            SVEPseudo2Instr<Ps # _H, 1>;
3170   def _S : sve_int_bin_pred_arit_log<0b10, 0b01, opc, asm, ZPR32>,
3171            SVEPseudo2Instr<Ps # _S, 1>;
3172   def _D : sve_int_bin_pred_arit_log<0b11, 0b01, opc, asm, ZPR64>,
3173            SVEPseudo2Instr<Ps # _D, 1>;
3174   }
3176   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3177   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3178   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3179   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3182 multiclass sve_int_bin_pred_arit_2<bits<3> opc, string asm, string Ps,
3183                                    SDPatternOperator op,
3184                                    DestructiveInstTypeEnum flags> {
3185   let DestructiveInstType = flags in {
3186   def _B : sve_int_bin_pred_arit_log<0b00, 0b10, opc, asm, ZPR8>,
3187            SVEPseudo2Instr<Ps # _B, 1>;
3188   def _H : sve_int_bin_pred_arit_log<0b01, 0b10, opc, asm, ZPR16>,
3189            SVEPseudo2Instr<Ps # _H, 1>;
3190   def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>,
3191            SVEPseudo2Instr<Ps # _S, 1>;
3192   def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>,
3193            SVEPseudo2Instr<Ps # _D, 1>;
3194   }
3196   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3197   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3198   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3199   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3202 // Special case for divides which are not defined for 8b/16b elements.
3203 multiclass sve_int_bin_pred_arit_2_div<bits<3> opc, string asm, string Ps,
3204                                        SDPatternOperator op,
3205                                        DestructiveInstTypeEnum flags,
3206                                        string revname="", bit isReverseInstr=0> {
3207   let DestructiveInstType = flags in {
3208   def _S : sve_int_bin_pred_arit_log<0b10, 0b10, opc, asm, ZPR32>,
3209            SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3210   def _D : sve_int_bin_pred_arit_log<0b11, 0b10, opc, asm, ZPR64>,
3211            SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3212   }
3214   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3215   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3218 //===----------------------------------------------------------------------===//
3219 // SVE Integer Multiply-Add Group
3220 //===----------------------------------------------------------------------===//
3222 class sve_int_mladdsub_vvv_pred<bits<2> sz8_64, bits<1> opc, string asm,
3223                                 ZPRRegOp zprty>
3224 : I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm, zprty:$Za),
3225   asm, "\t$Zdn, $Pg/m, $Zm, $Za",
3226   "",
3227   []>, Sched<[]> {
3228   bits<3> Pg;
3229   bits<5> Zdn;
3230   bits<5> Za;
3231   bits<5> Zm;
3232   let Inst{31-24} = 0b00000100;
3233   let Inst{23-22} = sz8_64;
3234   let Inst{21}    = 0b0;
3235   let Inst{20-16} = Zm;
3236   let Inst{15-14} = 0b11;
3237   let Inst{13}    = opc;
3238   let Inst{12-10} = Pg;
3239   let Inst{9-5}   = Za;
3240   let Inst{4-0}   = Zdn;
3242   let Constraints = "$Zdn = $_Zdn";
3243   let DestructiveInstType = DestructiveOther;
3244   let ElementSize = zprty.ElementSize;
3245   let hasSideEffects = 0;
3248 multiclass sve_int_mladdsub_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
3249                                      string revname, bit isReverseInstr=0> {
3250   def _B : sve_int_mladdsub_vvv_pred<0b00, opc, asm, ZPR8>,
3251            SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3252   def _H : sve_int_mladdsub_vvv_pred<0b01, opc, asm, ZPR16>,
3253            SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3254   def _S : sve_int_mladdsub_vvv_pred<0b10, opc, asm, ZPR32>,
3255            SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3256   def _D : sve_int_mladdsub_vvv_pred<0b11, opc, asm, ZPR64>,
3257            SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3259   def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3260   def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3261   def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3262   def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3265 class sve_int_mlas_vvv_pred<bits<2> sz8_64, bits<1> opc, string asm,
3266                             ZPRRegOp zprty>
3267 : I<(outs zprty:$Zda), (ins PPR3bAny:$Pg, zprty:$_Zda, zprty:$Zn, zprty:$Zm),
3268   asm, "\t$Zda, $Pg/m, $Zn, $Zm",
3269   "",
3270   []>, Sched<[]> {
3271   bits<3> Pg;
3272   bits<5> Zda;
3273   bits<5> Zm;
3274   bits<5> Zn;
3275   let Inst{31-24} = 0b00000100;
3276   let Inst{23-22} = sz8_64;
3277   let Inst{21}    = 0b0;
3278   let Inst{20-16} = Zm;
3279   let Inst{15-14} = 0b01;
3280   let Inst{13}    = opc;
3281   let Inst{12-10} = Pg;
3282   let Inst{9-5}   = Zn;
3283   let Inst{4-0}   = Zda;
3285   let Constraints = "$Zda = $_Zda";
3286   let DestructiveInstType = DestructiveTernaryCommWithRev;
3287   let ElementSize = zprty.ElementSize;
3288   let hasSideEffects = 0;
3291 multiclass sve_int_mlas_vvv_pred<bits<1> opc, string asm, SDPatternOperator op,
3292                                  string Ps, string revname, bit isReverseInstr=0> {
3293   def _B : sve_int_mlas_vvv_pred<0b00, opc, asm, ZPR8>,
3294            SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3295   def _H : sve_int_mlas_vvv_pred<0b01, opc, asm, ZPR16>,
3296            SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3297   def _S : sve_int_mlas_vvv_pred<0b10, opc, asm, ZPR32>,
3298            SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3299   def _D : sve_int_mlas_vvv_pred<0b11, opc, asm, ZPR64>,
3300            SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3302   def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3303   def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3304   def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3305   def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3308 //class for generating pseudo for SVE MLA/MAD/MLS/MSB
3309 multiclass sve_int_3op_p_mladdsub<SDPatternOperator op> {
3310   def _B_UNDEF : PredThreeOpPseudo<NAME # _B, ZPR8,  FalseLanesUndef>;
3311   def _H_UNDEF : PredThreeOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
3312   def _S_UNDEF : PredThreeOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
3313   def _D_UNDEF : PredThreeOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
3315   let  AddedComplexity = 9 in {
3316     def : SVE_4_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B_UNDEF)>;
3317     def : SVE_4_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H_UNDEF)>;
3318     def : SVE_4_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S_UNDEF)>;
3319     def : SVE_4_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D_UNDEF)>;
3320   }
3323 //===----------------------------------------------------------------------===//
3324 // SVE2 Integer Multiply-Add - Unpredicated Group
3325 //===----------------------------------------------------------------------===//
3327 class sve2_int_mla<bits<2> sz, bits<5> opc, string asm,
3328                    ZPRRegOp zprty1, ZPRRegOp zprty2>
3329 : I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm),
3330   asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
3331   bits<5> Zda;
3332   bits<5> Zn;
3333   bits<5> Zm;
3334   let Inst{31-24} = 0b01000100;
3335   let Inst{23-22} = sz;
3336   let Inst{21}    = 0b0;
3337   let Inst{20-16} = Zm;
3338   let Inst{15}    = 0b0;
3339   let Inst{14-10} = opc;
3340   let Inst{9-5}   = Zn;
3341   let Inst{4-0}   = Zda;
3343   let Constraints = "$Zda = $_Zda";
3344   let DestructiveInstType = DestructiveOther;
3345   let ElementSize = ElementSizeNone;
3346   let hasSideEffects = 0;
3349 multiclass sve2_int_mla<bit S, string asm, SDPatternOperator op> {
3350   def _B : sve2_int_mla<0b00, { 0b1110, S }, asm, ZPR8, ZPR8>;
3351   def _H : sve2_int_mla<0b01, { 0b1110, S }, asm, ZPR16, ZPR16>;
3352   def _S : sve2_int_mla<0b10, { 0b1110, S }, asm, ZPR32, ZPR32>;
3353   def _D : sve2_int_mla<0b11, { 0b1110, S }, asm, ZPR64, ZPR64>;
3355   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3356   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3357   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3358   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3361 multiclass sve2_int_mla_long<bits<5> opc, string asm, SDPatternOperator op> {
3362   def _H : sve2_int_mla<0b01, opc, asm, ZPR16, ZPR8>;
3363   def _S : sve2_int_mla<0b10, opc, asm, ZPR32, ZPR16>;
3364   def _D : sve2_int_mla<0b11, opc, asm, ZPR64, ZPR32>;
3366   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3367   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
3368   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3371 //===----------------------------------------------------------------------===//
3372 // SVE2 Integer Multiply-Add - Indexed Group
3373 //===----------------------------------------------------------------------===//
3375 class sve2_int_mla_by_indexed_elem<bits<2> sz, bits<6> opc, string asm,
3376                                    ZPRRegOp zprty1, ZPRRegOp zprty2,
3377                                    ZPRRegOp zprty3, Operand itype>
3378 : I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop),
3379   asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
3380   bits<5> Zda;
3381   bits<5> Zn;
3382   let Inst{31-24} = 0b01000100;
3383   let Inst{23-22} = sz;
3384   let Inst{21}    = 0b1;
3385   let Inst{15-10} = opc;
3386   let Inst{9-5}   = Zn;
3387   let Inst{4-0}   = Zda;
3389   let Constraints = "$Zda = $_Zda";
3390   let DestructiveInstType = DestructiveOther;
3391   let ElementSize = ElementSizeNone;
3392   let hasSideEffects = 0;
3395 multiclass sve2_int_mla_by_indexed_elem<bits<2> opc, bit S, string asm,
3396                                         SDPatternOperator op> {
3397   def _H : sve2_int_mla_by_indexed_elem<{0, ?}, { 0b000, opc, S }, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexH32b> {
3398     bits<3> Zm;
3399     bits<3> iop;
3400     let Inst{22} = iop{2};
3401     let Inst{20-19} = iop{1-0};
3402     let Inst{18-16} = Zm;
3403   }
3404   def _S : sve2_int_mla_by_indexed_elem<0b10, { 0b000, opc, S }, asm, ZPR32, ZPR32, ZPR3b32, VectorIndexS32b> {
3405     bits<3> Zm;
3406     bits<2> iop;
3407     let Inst{20-19} = iop;
3408     let Inst{18-16} = Zm;
3409   }
3410   def _D : sve2_int_mla_by_indexed_elem<0b11, { 0b000, opc, S }, asm, ZPR64, ZPR64, ZPR4b64, VectorIndexD32b> {
3411     bits<4> Zm;
3412     bit iop;
3413     let Inst{20} = iop;
3414     let Inst{19-16} = Zm;
3415   }
3417   def : SVE_4_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
3418   def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3419   def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3422 //===----------------------------------------------------------------------===//
3423 // SVE2 Integer Multiply-Add Long - Indexed Group
3424 //===----------------------------------------------------------------------===//
3426 multiclass sve2_int_mla_long_by_indexed_elem<bits<4> opc, string asm,
3427                                              SDPatternOperator op> {
3428   def _S : sve2_int_mla_by_indexed_elem<0b10, { opc{3}, 0b0, opc{2-1}, ?, opc{0} },
3429                                         asm, ZPR32, ZPR16, ZPR3b16, VectorIndexH32b> {
3430     bits<3> Zm;
3431     bits<3> iop;
3432     let Inst{20-19} = iop{2-1};
3433     let Inst{18-16} = Zm;
3434     let Inst{11} = iop{0};
3435   }
3436   def _D : sve2_int_mla_by_indexed_elem<0b11, { opc{3}, 0b0, opc{2-1}, ?, opc{0} },
3437                                         asm, ZPR64, ZPR32, ZPR4b32, VectorIndexS32b> {
3438     bits<4> Zm;
3439     bits<2> iop;
3440     let Inst{20} = iop{1};
3441     let Inst{19-16} = Zm;
3442     let Inst{11} = iop{0};
3443   }
3445   def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _S)>;
3446   def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
3449 //===----------------------------------------------------------------------===//
3450 // SVE Integer Dot Product Group
3451 //===----------------------------------------------------------------------===//
3453 class sve_intx_dot<bit sz, bit U, string asm, ZPRRegOp zprty1,
3454                    ZPRRegOp zprty2>
3455 : I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm), asm,
3456   "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
3457   bits<5> Zda;
3458   bits<5> Zn;
3459   bits<5> Zm;
3460   let Inst{31-23} = 0b010001001;
3461   let Inst{22}    = sz;
3462   let Inst{21}    = 0;
3463   let Inst{20-16} = Zm;
3464   let Inst{15-11} = 0;
3465   let Inst{10}    = U;
3466   let Inst{9-5}   = Zn;
3467   let Inst{4-0}   = Zda;
3469   let Constraints = "$Zda = $_Zda";
3470   let DestructiveInstType = DestructiveOther;
3471   let hasSideEffects = 0;
3474 multiclass sve_intx_dot<bit opc, string asm, SDPatternOperator op> {
3475   def _S : sve_intx_dot<0b0, opc, asm, ZPR32, ZPR8>;
3476   def _D : sve_intx_dot<0b1, opc, asm, ZPR64, ZPR16>;
3478   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32,  nxv16i8, nxv16i8, !cast<Instruction>(NAME # _S)>;
3479   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _D)>;
3482 //===----------------------------------------------------------------------===//
3483 // SVE Integer Dot Product Group - Indexed Group
3484 //===----------------------------------------------------------------------===//
3486 class sve_intx_dot_by_indexed_elem<bit sz, bit U, string asm,
3487                                    ZPRRegOp zprty1, ZPRRegOp zprty2,
3488                                    ZPRRegOp zprty3, Operand itype>
3489 : I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop),
3490   asm, "\t$Zda, $Zn, $Zm$iop",
3491   "", []>, Sched<[]> {
3492   bits<5> Zda;
3493   bits<5> Zn;
3494   let Inst{31-23} = 0b010001001;
3495   let Inst{22}    = sz;
3496   let Inst{21}    = 0b1;
3497   let Inst{15-11} = 0;
3498   let Inst{10}    = U;
3499   let Inst{9-5}   = Zn;
3500   let Inst{4-0}   = Zda;
3502   let Constraints = "$Zda = $_Zda";
3503   let DestructiveInstType = DestructiveOther;
3504   let hasSideEffects = 0;
3507 multiclass sve_intx_dot_by_indexed_elem<bit opc, string asm,
3508                                         SDPatternOperator op> {
3509   def _S : sve_intx_dot_by_indexed_elem<0b0, opc, asm, ZPR32, ZPR8, ZPR3b8, VectorIndexS32b_timm> {
3510     bits<2> iop;
3511     bits<3> Zm;
3512     let Inst{20-19} = iop;
3513     let Inst{18-16} = Zm;
3514   }
3515   def _D : sve_intx_dot_by_indexed_elem<0b1, opc, asm, ZPR64, ZPR16, ZPR4b16, VectorIndexD32b_timm> {
3516     bits<1> iop;
3517     bits<4> Zm;
3518     let Inst{20} = iop;
3519     let Inst{19-16} = Zm;
3520   }
3522   def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv16i8, nxv16i8, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3523   def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv8i16, nxv8i16, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3526 //===----------------------------------------------------------------------===//
3527 // SVE2 Complex Integer Dot Product Group
3528 //===----------------------------------------------------------------------===//
3530 class sve2_complex_int_arith<bits<2> sz, bits<4> opc, string asm,
3531                              ZPRRegOp zprty1, ZPRRegOp zprty2>
3532 : I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm,
3533                          complexrotateop:$rot),
3534   asm, "\t$Zda, $Zn, $Zm, $rot", "", []>, Sched<[]> {
3535   bits<5> Zda;
3536   bits<5> Zn;
3537   bits<5> Zm;
3538   bits<2> rot;
3539   let Inst{31-24} = 0b01000100;
3540   let Inst{23-22} = sz;
3541   let Inst{21}    = 0b0;
3542   let Inst{20-16} = Zm;
3543   let Inst{15-12} = opc;
3544   let Inst{11-10} = rot;
3545   let Inst{9-5}   = Zn;
3546   let Inst{4-0}   = Zda;
3548   let Constraints = "$Zda = $_Zda";
3549   let DestructiveInstType = DestructiveOther;
3550   let ElementSize = ElementSizeNone;
3551   let hasSideEffects = 0;
3554 multiclass sve2_cintx_dot<string asm, SDPatternOperator op> {
3555   def _S : sve2_complex_int_arith<0b10, 0b0001, asm, ZPR32, ZPR8>;
3556   def _D : sve2_complex_int_arith<0b11, 0b0001, asm, ZPR64, ZPR16>;
3558   def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv16i8 ZPR8:$Op2), (nxv16i8 ZPR8:$Op3),
3559                          (i32 complexrotateop:$imm))),
3560             (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR8:$Op2, ZPR8:$Op3, complexrotateop:$imm)>;
3561   def : Pat<(nxv2i64 (op (nxv2i64 ZPR64:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3562                          (i32 complexrotateop:$imm))),
3563             (!cast<Instruction>(NAME # "_D") ZPR64:$Op1, ZPR16:$Op2, ZPR16:$Op3, complexrotateop:$imm)>;
3566 //===----------------------------------------------------------------------===//
3567 // SVE2 Complex Multiply-Add Group
3568 //===----------------------------------------------------------------------===//
3570 multiclass sve2_int_cmla<bit opc, string asm, SDPatternOperator op> {
3571   def _B : sve2_complex_int_arith<0b00, { 0b001, opc }, asm, ZPR8, ZPR8>;
3572   def _H : sve2_complex_int_arith<0b01, { 0b001, opc }, asm, ZPR16, ZPR16>;
3573   def _S : sve2_complex_int_arith<0b10, { 0b001, opc }, asm, ZPR32, ZPR32>;
3574   def _D : sve2_complex_int_arith<0b11, { 0b001, opc }, asm, ZPR64, ZPR64>;
3576   def : SVE_4_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, i32, complexrotateop, !cast<Instruction>(NAME # _B)>;
3577   def : SVE_4_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, i32, complexrotateop, !cast<Instruction>(NAME # _H)>;
3578   def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, i32, complexrotateop, !cast<Instruction>(NAME # _S)>;
3579   def : SVE_4_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, i32, complexrotateop, !cast<Instruction>(NAME # _D)>;
3582 //===----------------------------------------------------------------------===//
3583 // SVE2 Complex Integer Dot Product - Indexed Group
3584 //===----------------------------------------------------------------------===//
3586 class sve2_complex_int_arith_indexed<bits<2> sz, bits<4> opc, string asm,
3587                                      ZPRRegOp zprty1, ZPRRegOp zprty2,
3588                                      ZPRRegOp zprty3, Operand itype>
3589 : I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty3:$Zm, itype:$iop,
3590                          complexrotateop:$rot),
3591   asm, "\t$Zda, $Zn, $Zm$iop, $rot", "", []>, Sched<[]> {
3592   bits<5> Zda;
3593   bits<5> Zn;
3594   bits<2> rot;
3595   let Inst{31-24} = 0b01000100;
3596   let Inst{23-22} = sz;
3597   let Inst{21}    = 0b1;
3598   let Inst{15-12} = opc;
3599   let Inst{11-10} = rot;
3600   let Inst{9-5}   = Zn;
3601   let Inst{4-0}   = Zda;
3603   let Constraints = "$Zda = $_Zda";
3604   let DestructiveInstType = DestructiveOther;
3605   let ElementSize = ElementSizeNone;
3606   let hasSideEffects = 0;
3609 multiclass sve2_cintx_dot_by_indexed_elem<string asm, SDPatternOperator op> {
3610   def _S : sve2_complex_int_arith_indexed<0b10, 0b0100, asm, ZPR32, ZPR8, ZPR3b8, VectorIndexS32b> {
3611     bits<2> iop;
3612     bits<3> Zm;
3613     let Inst{20-19} = iop;
3614     let Inst{18-16} = Zm;
3615   }
3616   def _D : sve2_complex_int_arith_indexed<0b11, 0b0100, asm, ZPR64, ZPR16, ZPR4b16, VectorIndexD32b> {
3617     bit iop;
3618     bits<4> Zm;
3619     let Inst{20} = iop;
3620     let Inst{19-16} = Zm;
3621   }
3623   def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv16i8 ZPR8:$Op2), (nxv16i8 ZPR8:$Op3),
3624                          (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
3625             (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR8:$Op2, ZPR8:$Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
3626   def : Pat<(nxv2i64 (op (nxv2i64 ZPR64:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3627                          (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
3628             (!cast<Instruction>(NAME # "_D") ZPR64:$Op1, ZPR16:$Op2, ZPR16:$Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
3631 //===----------------------------------------------------------------------===//
3632 // SVE2 Complex Multiply-Add - Indexed Group
3633 //===----------------------------------------------------------------------===//
3635 multiclass sve2_cmla_by_indexed_elem<bit opc, string asm,
3636                                      SDPatternOperator op> {
3637   def _H : sve2_complex_int_arith_indexed<0b10, { 0b011, opc }, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexS32b> {
3638     bits<2> iop;
3639     bits<3> Zm;
3640     let Inst{20-19} = iop;
3641     let Inst{18-16} = Zm;
3642   }
3643   def _S : sve2_complex_int_arith_indexed<0b11, { 0b011, opc }, asm, ZPR32, ZPR32, ZPR4b32, VectorIndexD32b> {
3644     bit iop;
3645     bits<4> Zm;
3646     let Inst{20} = iop;
3647     let Inst{19-16} = Zm;
3648   }
3650   def : Pat<(nxv8i16 (op (nxv8i16 ZPR16:$Op1), (nxv8i16 ZPR16:$Op2), (nxv8i16 ZPR16:$Op3),
3651                          (i32 VectorIndexS32b_timm:$idx), (i32 complexrotateop:$imm))),
3652             (!cast<Instruction>(NAME # "_H") ZPR16:$Op1, ZPR16:$Op2, ZPR16:$Op3, VectorIndexS32b_timm:$idx, complexrotateop:$imm)>;
3654   def : Pat<(nxv4i32 (op (nxv4i32 ZPR32:$Op1), (nxv4i32 ZPR32:$Op2), (nxv4i32 ZPR32:$Op3),
3655                          (i32 VectorIndexD32b_timm:$idx), (i32 complexrotateop:$imm))),
3656             (!cast<Instruction>(NAME # "_S") ZPR32:$Op1, ZPR32:$Op2, ZPR32:$Op3, VectorIndexD32b_timm:$idx, complexrotateop:$imm)>;
3659 //===----------------------------------------------------------------------===//
3660 // SVE2 Integer Multiply - Unpredicated Group
3661 //===----------------------------------------------------------------------===//
3663 class sve2_int_mul<bits<2> sz, bits<3> opc, string asm, ZPRRegOp zprty>
3664 : I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
3665   asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3666   bits<5> Zd;
3667   bits<5> Zm;
3668   bits<5> Zn;
3669   let Inst{31-24} = 0b00000100;
3670   let Inst{23-22} = sz;
3671   let Inst{21}    = 0b1;
3672   let Inst{20-16} = Zm;
3673   let Inst{15-13} = 0b011;
3674   let Inst{12-10} = opc;
3675   let Inst{9-5}   = Zn;
3676   let Inst{4-0}   = Zd;
3678   let hasSideEffects = 0;
3681 multiclass sve2_int_mul<bits<3> opc, string asm, SDPatternOperator op,
3682                         SDPatternOperator op_pred = null_frag> {
3683   def _B : sve2_int_mul<0b00, opc, asm, ZPR8>;
3684   def _H : sve2_int_mul<0b01, opc, asm, ZPR16>;
3685   def _S : sve2_int_mul<0b10, opc, asm, ZPR32>;
3686   def _D : sve2_int_mul<0b11, opc, asm, ZPR64>;
3688   def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3689   def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3690   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3691   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3693   def : SVE_2_Op_Pred_Any_Predicate<nxv16i8, op_pred, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3694   def : SVE_2_Op_Pred_Any_Predicate<nxv8i16, op_pred, nxv8i1, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3695   def : SVE_2_Op_Pred_Any_Predicate<nxv4i32, op_pred, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3696   def : SVE_2_Op_Pred_Any_Predicate<nxv2i64, op_pred, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3699 multiclass sve2_int_mul_single<bits<3> opc, string asm, SDPatternOperator op> {
3700   def _B : sve2_int_mul<0b00, opc, asm, ZPR8>;
3702   def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3705 //===----------------------------------------------------------------------===//
3706 // SVE2 Integer Multiply - Indexed Group
3707 //===----------------------------------------------------------------------===//
3709 class sve2_int_mul_by_indexed_elem<bits<2> sz, bits<4> opc, string asm,
3710                                    ZPRRegOp zprty1, ZPRRegOp zprty2,
3711                                    ZPRRegOp zprty3, Operand itype>
3712 : I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty3:$Zm, itype:$iop),
3713   asm, "\t$Zd, $Zn, $Zm$iop", "", []>, Sched<[]> {
3714   bits<5> Zd;
3715   bits<5> Zn;
3716   let Inst{31-24} = 0b01000100;
3717   let Inst{23-22} = sz;
3718   let Inst{21}    = 0b1;
3719   let Inst{15-14} = 0b11;
3720   let Inst{13-10} = opc;
3721   let Inst{9-5}   = Zn;
3722   let Inst{4-0}   = Zd;
3724   let hasSideEffects = 0;
3727 multiclass sve2_int_mul_by_indexed_elem<bits<4> opc, string asm,
3728                                         SDPatternOperator op> {
3729   def _H : sve2_int_mul_by_indexed_elem<{0, ?}, opc, asm, ZPR16, ZPR16, ZPR3b16, VectorIndexH32b> {
3730     bits<3> Zm;
3731     bits<3> iop;
3732     let Inst{22} = iop{2};
3733     let Inst{20-19} = iop{1-0};
3734     let Inst{18-16} = Zm;
3735   }
3736   def _S : sve2_int_mul_by_indexed_elem<0b10, opc, asm, ZPR32, ZPR32, ZPR3b32, VectorIndexS32b> {
3737     bits<3> Zm;
3738     bits<2> iop;
3739     let Inst{20-19} = iop;
3740     let Inst{18-16} = Zm;
3741   }
3742   def _D : sve2_int_mul_by_indexed_elem<0b11, opc, asm, ZPR64, ZPR64, ZPR4b64, VectorIndexD32b> {
3743     bits<4> Zm;
3744     bit iop;
3745     let Inst{20} = iop;
3746     let Inst{19-16} = Zm;
3747   }
3749   def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _H)>;
3750   def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
3751   def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, VectorIndexD32b_timm, !cast<Instruction>(NAME # _D)>;
3754 multiclass sve2_int_mul_long_by_indexed_elem<bits<3> opc, string asm,
3755                                              SDPatternOperator op> {
3756   def _S : sve2_int_mul_by_indexed_elem<0b10, { opc{2-1}, ?, opc{0} }, asm,
3757                                         ZPR32, ZPR16, ZPR3b16, VectorIndexH32b> {
3758     bits<3> Zm;
3759     bits<3> iop;
3760     let Inst{20-19} = iop{2-1};
3761     let Inst{18-16} = Zm;
3762     let Inst{11} = iop{0};
3763   }
3764   def _D : sve2_int_mul_by_indexed_elem<0b11, { opc{2-1}, ?, opc{0} }, asm,
3765                                         ZPR64, ZPR32, ZPR4b32, VectorIndexS32b> {
3766     bits<4> Zm;
3767     bits<2> iop;
3768     let Inst{20} = iop{1};
3769     let Inst{19-16} = Zm;
3770     let Inst{11} = iop{0};
3771   }
3773   def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv8i16, nxv8i16, i32, VectorIndexH32b_timm, !cast<Instruction>(NAME # _S)>;
3774   def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv4i32, nxv4i32, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
3777 //===----------------------------------------------------------------------===//
3778 // SVE2 Integer - Predicated Group
3779 //===----------------------------------------------------------------------===//
3781 class sve2_int_arith_pred<bits<2> sz, bits<6> opc, string asm,
3782                           ZPRRegOp zprty>
3783 : I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
3784   asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm", "", []>, Sched<[]> {
3785   bits<3> Pg;
3786   bits<5> Zm;
3787   bits<5> Zdn;
3788   let Inst{31-24} = 0b01000100;
3789   let Inst{23-22} = sz;
3790   let Inst{21-20} = 0b01;
3791   let Inst{20-16} = opc{5-1};
3792   let Inst{15-14} = 0b10;
3793   let Inst{13}    = opc{0};
3794   let Inst{12-10} = Pg;
3795   let Inst{9-5}   = Zm;
3796   let Inst{4-0}   = Zdn;
3798   let Constraints = "$Zdn = $_Zdn";
3799   let DestructiveInstType = DestructiveOther;
3800   let ElementSize = zprty.ElementSize;
3801   let hasSideEffects = 0;
3804 multiclass sve2_int_arith_pred<bits<6> opc, string asm, SDPatternOperator op,
3805                                string Ps = "",
3806                                DestructiveInstTypeEnum flags=DestructiveOther,
3807                                string revname="", bit isReverseInstr=0> {
3808   let DestructiveInstType = flags in {
3809   def _B : sve2_int_arith_pred<0b00, opc, asm, ZPR8>,
3810            SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
3811   def _H : sve2_int_arith_pred<0b01, opc, asm, ZPR16>,
3812            SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
3813   def _S : sve2_int_arith_pred<0b10, opc, asm, ZPR32>,
3814            SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
3815   def _D : sve2_int_arith_pred<0b11, opc, asm, ZPR64>,
3816            SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
3817   }
3819   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
3820   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
3821   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
3822   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
3825 class sve2_int_sadd_long_accum_pairwise<bits<2> sz, bit U, string asm,
3826                                         ZPRRegOp zprty1, ZPRRegOp zprty2>
3827 : I<(outs zprty1:$Zda), (ins PPR3bAny:$Pg, zprty1:$_Zda, zprty2:$Zn),
3828   asm, "\t$Zda, $Pg/m, $Zn", "", []>, Sched<[]> {
3829   bits<3> Pg;
3830   bits<5> Zn;
3831   bits<5> Zda;
3832   let Inst{31-24} = 0b01000100;
3833   let Inst{23-22} = sz;
3834   let Inst{21-17} = 0b00010;
3835   let Inst{16}    = U;
3836   let Inst{15-13} = 0b101;
3837   let Inst{12-10} = Pg;
3838   let Inst{9-5}   = Zn;
3839   let Inst{4-0}   = Zda;
3841   let Constraints = "$Zda = $_Zda";
3842   let DestructiveInstType = DestructiveOther;
3843   let ElementSize = zprty1.ElementSize;
3844   let hasSideEffects = 0;
3847 multiclass sve2_int_sadd_long_accum_pairwise<bit U, string asm, SDPatternOperator op> {
3848   def _H : sve2_int_sadd_long_accum_pairwise<0b01, U, asm, ZPR16, ZPR8>;
3849   def _S : sve2_int_sadd_long_accum_pairwise<0b10, U, asm, ZPR32, ZPR16>;
3850   def _D : sve2_int_sadd_long_accum_pairwise<0b11, U, asm, ZPR64, ZPR32>;
3852   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1, nxv8i16, nxv16i8, !cast<Instruction>(NAME # _H)>;
3853   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv8i16, !cast<Instruction>(NAME # _S)>;
3854   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv4i32, !cast<Instruction>(NAME # _D)>;
3857 class sve2_int_un_pred_arit<bits<2> sz, bit Q, bits<2> opc,
3858                             string asm, ZPRRegOp zprty>
3859 : I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
3860   asm, "\t$Zd, $Pg/m, $Zn",
3861   "",
3862   []>, Sched<[]> {
3863   bits<3> Pg;
3864   bits<5> Zd;
3865   bits<5> Zn;
3866   let Inst{31-24} = 0b01000100;
3867   let Inst{23-22} = sz;
3868   let Inst{21-20} = 0b00;
3869   let Inst{19}    = Q;
3870   let Inst{18}    = 0b0;
3871   let Inst{17-16} = opc;
3872   let Inst{15-13} = 0b101;
3873   let Inst{12-10} = Pg;
3874   let Inst{9-5}   = Zn;
3875   let Inst{4-0}   = Zd;
3877   let Constraints = "$Zd = $_Zd";
3878   let DestructiveInstType = DestructiveUnaryPassthru;
3879   let ElementSize = zprty.ElementSize;
3880   let hasSideEffects = 0;
3883 multiclass sve2_int_un_pred_arit_s<bits<3> opc, string asm,
3884                                    SDPatternOperator op> {
3885   def _S : sve2_int_un_pred_arit<0b10, opc{2}, opc{1-0}, asm, ZPR32>,
3886            SVEPseudo2Instr<NAME # _S, 1>;
3888   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
3890   def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
3892   defm : SVE_3_Op_Undef_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
3895 multiclass sve2_int_un_pred_arit<bits<3> opc, string asm, SDPatternOperator op> {
3896   def _B : sve2_int_un_pred_arit<0b00, opc{2}, opc{1-0}, asm, ZPR8>,
3897            SVEPseudo2Instr<NAME # _B, 1>;
3898   def _H : sve2_int_un_pred_arit<0b01, opc{2}, opc{1-0}, asm, ZPR16>,
3899            SVEPseudo2Instr<NAME # _H, 1>;
3900   def _S : sve2_int_un_pred_arit<0b10, opc{2}, opc{1-0}, asm, ZPR32>,
3901            SVEPseudo2Instr<NAME # _S, 1>;
3902   def _D : sve2_int_un_pred_arit<0b11, opc{2}, opc{1-0}, asm, ZPR64>,
3903            SVEPseudo2Instr<NAME # _D, 1>;
3905   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
3906   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
3907   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
3908   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
3910   def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
3911   def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
3912   def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
3913   def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
3915   defm : SVE_3_Op_Undef_Pat<nxv16i8, op, nxv16i8, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
3916   defm : SVE_3_Op_Undef_Pat<nxv8i16, op, nxv8i16, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
3917   defm : SVE_3_Op_Undef_Pat<nxv4i32, op, nxv4i32, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
3918   defm : SVE_3_Op_Undef_Pat<nxv2i64, op, nxv2i64, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
3921 //===----------------------------------------------------------------------===//
3922 // SVE2 Widening Integer Arithmetic Group
3923 //===----------------------------------------------------------------------===//
3925 class sve2_wide_int_arith<bits<2> sz, bits<5> opc, string asm,
3926                           ZPRRegOp zprty1, ZPRRegOp zprty2, ZPRRegOp zprty3>
3927 : I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty3:$Zm),
3928   asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3929   bits<5> Zd;
3930   bits<5> Zn;
3931   bits<5> Zm;
3932   let Inst{31-24} = 0b01000101;
3933   let Inst{23-22} = sz;
3934   let Inst{21}    = 0b0;
3935   let Inst{20-16} = Zm;
3936   let Inst{15}    = 0b0;
3937   let Inst{14-10} = opc;
3938   let Inst{9-5}   = Zn;
3939   let Inst{4-0}   = Zd;
3941   let hasSideEffects = 0;
3944 multiclass sve2_wide_int_arith_long<bits<5> opc, string asm,
3945                                     SDPatternOperator op> {
3946   def _H : sve2_wide_int_arith<0b01, opc, asm, ZPR16, ZPR8, ZPR8>;
3947   def _S : sve2_wide_int_arith<0b10, opc, asm, ZPR32, ZPR16, ZPR16>;
3948   def _D : sve2_wide_int_arith<0b11, opc, asm, ZPR64, ZPR32, ZPR32>;
3950   def : SVE_2_Op_Pat<nxv8i16, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3951   def : SVE_2_Op_Pat<nxv4i32, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
3952   def : SVE_2_Op_Pat<nxv2i64, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3955 multiclass sve2_wide_int_arith_wide<bits<3> opc, string asm,
3956                                     SDPatternOperator op> {
3957   def _H : sve2_wide_int_arith<0b01, { 0b10, opc }, asm, ZPR16, ZPR16, ZPR8>;
3958   def _S : sve2_wide_int_arith<0b10, { 0b10, opc }, asm, ZPR32, ZPR32, ZPR16>;
3959   def _D : sve2_wide_int_arith<0b11, { 0b10, opc }, asm, ZPR64, ZPR64, ZPR32>;
3961   def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, !cast<Instruction>(NAME # _H)>;
3962   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, !cast<Instruction>(NAME # _S)>;
3963   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, !cast<Instruction>(NAME # _D)>;
3966 multiclass sve2_wide_int_arith_pmul<bits<2> sz, bits<5> opc, string asm,
3967                                      SDPatternOperator op> {
3968   def NAME : sve2_wide_int_arith<sz, opc, asm, ZPR128, ZPR64, ZPR64>;
3970   // To avoid using 128 bit elements in the IR, the pattern below works with
3971   // llvm intrinsics with the _pair suffix, to reflect that
3972   // _Q is implemented as a pair of _D.
3973   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
3976 multiclass sve2_pmul_long<bits<1> opc, string asm, SDPatternOperator op> {
3977   def _H : sve2_wide_int_arith<0b01, {0b1101, opc}, asm, ZPR16, ZPR8, ZPR8>;
3978   def _D : sve2_wide_int_arith<0b11, {0b1101, opc}, asm, ZPR64, ZPR32, ZPR32>;
3980   // To avoid using 128 bit elements in the IR, the patterns below work with
3981   // llvm intrinsics with the _pair suffix, to reflect that
3982   // _H is implemented as a pair of _B and _D is implemented as a pair of _S.
3983   def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
3984   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
3987 //===----------------------------------------------------------------------===//
3988 // SVE2 Misc Group
3989 //===----------------------------------------------------------------------===//
3991 class sve2_misc<bits<2> sz, bits<4> opc, string asm,
3992                 ZPRRegOp zprty1, ZPRRegOp zprty2>
3993 : I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty2:$Zm),
3994   asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
3995   bits<5> Zd;
3996   bits<5> Zn;
3997   bits<5> Zm;
3998   let Inst{31-24} = 0b01000101;
3999   let Inst{23-22} = sz;
4000   let Inst{21}    = 0b0;
4001   let Inst{20-16} = Zm;
4002   let Inst{15-14} = 0b10;
4003   let Inst{13-10} = opc;
4004   let Inst{9-5}   = Zn;
4005   let Inst{4-0}   = Zd;
4007   let hasSideEffects = 0;
4010 multiclass sve2_misc_bitwise<bits<4> opc, string asm, SDPatternOperator op> {
4011   def _B : sve2_misc<0b00, opc, asm, ZPR8, ZPR8>;
4012   def _H : sve2_misc<0b01, opc, asm, ZPR16, ZPR16>;
4013   def _S : sve2_misc<0b10, opc, asm, ZPR32, ZPR32>;
4014   def _D : sve2_misc<0b11, opc, asm, ZPR64, ZPR64>;
4016   def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4017   def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4018   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4019   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4022 multiclass sve2_misc_int_addsub_long_interleaved<bits<2> opc, string asm,
4023                                                  SDPatternOperator op> {
4024   def _H : sve2_misc<0b01, { 0b00, opc }, asm, ZPR16, ZPR8>;
4025   def _S : sve2_misc<0b10, { 0b00, opc }, asm, ZPR32, ZPR16>;
4026   def _D : sve2_misc<0b11, { 0b00, opc }, asm, ZPR64, ZPR32>;
4028   def : SVE_2_Op_Pat<nxv8i16, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
4029   def : SVE_2_Op_Pat<nxv4i32, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
4030   def : SVE_2_Op_Pat<nxv2i64, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
4033 class sve2_bitwise_xor_interleaved<bits<2> sz, bits<1> opc, string asm,
4034                                    ZPRRegOp zprty1, ZPRRegOp zprty2>
4035 : I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, zprty2:$Zm),
4036   asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4037   bits<5> Zd;
4038   bits<5> Zn;
4039   bits<5> Zm;
4040   let Inst{31-24} = 0b01000101;
4041   let Inst{23-22} = sz;
4042   let Inst{21}    = 0b0;
4043   let Inst{20-16} = Zm;
4044   let Inst{15-11} = 0b10010;
4045   let Inst{10}    = opc;
4046   let Inst{9-5}   = Zn;
4047   let Inst{4-0}   = Zd;
4049   let Constraints = "$Zd = $_Zd";
4050   let DestructiveInstType = DestructiveOther;
4051   let ElementSize = ElementSizeNone;
4052   let hasSideEffects = 0;
4055 multiclass sve2_bitwise_xor_interleaved<bit opc, string asm,
4056                                         SDPatternOperator op> {
4057   def _B : sve2_bitwise_xor_interleaved<0b00, opc, asm, ZPR8,  ZPR8>;
4058   def _H : sve2_bitwise_xor_interleaved<0b01, opc, asm, ZPR16, ZPR16>;
4059   def _S : sve2_bitwise_xor_interleaved<0b10, opc, asm, ZPR32, ZPR32>;
4060   def _D : sve2_bitwise_xor_interleaved<0b11, opc, asm, ZPR64, ZPR64>;
4062   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4063   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4064   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4065   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4068 class sve2_bitwise_shift_left_long<bits<3> tsz8_64, bits<2> opc, string asm,
4069                                    ZPRRegOp zprty1, ZPRRegOp zprty2,
4070                                    Operand immtype>
4071 : I<(outs zprty1:$Zd), (ins zprty2:$Zn, immtype:$imm),
4072   asm, "\t$Zd, $Zn, $imm",
4073   "", []>, Sched<[]> {
4074   bits<5> Zd;
4075   bits<5> Zn;
4076   bits<5> imm;
4077   let Inst{31-23} = 0b010001010;
4078   let Inst{22}    = tsz8_64{2};
4079   let Inst{21}    = 0b0;
4080   let Inst{20-19} = tsz8_64{1-0};
4081   let Inst{18-16} = imm{2-0}; // imm3
4082   let Inst{15-12} = 0b1010;
4083   let Inst{11-10} = opc;
4084   let Inst{9-5}   = Zn;
4085   let Inst{4-0}   = Zd;
4087   let hasSideEffects = 0;
4090 multiclass sve2_bitwise_shift_left_long<bits<2> opc, string asm,
4091                                         SDPatternOperator op> {
4092   def _H : sve2_bitwise_shift_left_long<{0,0,1}, opc, asm,
4093                                         ZPR16, ZPR8, vecshiftL8>;
4094   def _S : sve2_bitwise_shift_left_long<{0,1,?}, opc, asm,
4095                                         ZPR32, ZPR16, vecshiftL16> {
4096     let Inst{19} = imm{3};
4097   }
4098   def _D : sve2_bitwise_shift_left_long<{1,?,?}, opc, asm,
4099                                         ZPR64, ZPR32, vecshiftL32> {
4100     let Inst{20-19} = imm{4-3};
4101   }
4102   def : SVE_2_Op_Imm_Pat<nxv8i16, op, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _H)>;
4103   def : SVE_2_Op_Imm_Pat<nxv4i32, op, nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _S)>;
4104   def : SVE_2_Op_Imm_Pat<nxv2i64, op, nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _D)>;
4107 //===----------------------------------------------------------------------===//
4108 // SVE2 Accumulate Group
4109 //===----------------------------------------------------------------------===//
4111 class sve2_int_bin_shift_imm<bits<4> tsz8_64, bit opc, string asm,
4112                              ZPRRegOp zprty, Operand immtype>
4113 : I<(outs zprty:$Zd), (ins zprty:$_Zd, zprty:$Zn, immtype:$imm),
4114   asm, "\t$Zd, $Zn, $imm",
4115   "", []>, Sched<[]> {
4116   bits<5> Zd;
4117   bits<5> Zn;
4118   bits<6> imm;
4119   let Inst{31-24} = 0b01000101;
4120   let Inst{23-22} = tsz8_64{3-2};
4121   let Inst{21}    = 0b0;
4122   let Inst{20-19} = tsz8_64{1-0};
4123   let Inst{18-16} = imm{2-0}; // imm3
4124   let Inst{15-11} = 0b11110;
4125   let Inst{10}    = opc;
4126   let Inst{9-5}   = Zn;
4127   let Inst{4-0}   = Zd;
4129   let Constraints = "$Zd = $_Zd";
4130   let hasSideEffects = 0;
4133 multiclass sve2_int_bin_shift_imm_left<bit opc, string asm,
4134                                        SDPatternOperator op> {
4135   def _B : sve2_int_bin_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
4136   def _H : sve2_int_bin_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
4137     let Inst{19} = imm{3};
4138   }
4139   def _S : sve2_int_bin_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
4140     let Inst{20-19} = imm{4-3};
4141   }
4142   def _D : sve2_int_bin_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
4143     let Inst{22}    = imm{5};
4144     let Inst{20-19} = imm{4-3};
4145   }
4147   def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _B)>;
4148   def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _H)>;
4149   def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _S)>;
4150   def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftL64, !cast<Instruction>(NAME # _D)>;
4153 multiclass sve2_int_bin_shift_imm_right<bit opc, string asm,
4154                                         SDPatternOperator op> {
4155   def _B : sve2_int_bin_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
4156   def _H : sve2_int_bin_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
4157     let Inst{19} = imm{3};
4158   }
4159   def _S : sve2_int_bin_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
4160     let Inst{20-19} = imm{4-3};
4161   }
4162   def _D : sve2_int_bin_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
4163     let Inst{22}    = imm{5};
4164     let Inst{20-19} = imm{4-3};
4165   }
4167   def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4168   def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4169   def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4170   def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4173 class sve2_int_bin_accum_shift_imm<bits<4> tsz8_64, bits<2> opc, string asm,
4174                                    ZPRRegOp zprty, Operand immtype>
4175 : I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, immtype:$imm),
4176   asm, "\t$Zda, $Zn, $imm",
4177   "", []>, Sched<[]> {
4178   bits<5> Zda;
4179   bits<5> Zn;
4180   bits<6> imm;
4181   let Inst{31-24} = 0b01000101;
4182   let Inst{23-22} = tsz8_64{3-2};
4183   let Inst{21}    = 0b0;
4184   let Inst{20-19} = tsz8_64{1-0};
4185   let Inst{18-16} = imm{2-0}; // imm3
4186   let Inst{15-12} = 0b1110;
4187   let Inst{11-10} = opc;
4188   let Inst{9-5}   = Zn;
4189   let Inst{4-0}   = Zda;
4191   let Constraints = "$Zda = $_Zda";
4192   let DestructiveInstType = DestructiveOther;
4193   let ElementSize = ElementSizeNone;
4194   let hasSideEffects = 0;
4197 multiclass sve2_int_bin_accum_shift_imm_right<bits<2> opc, string asm,
4198                                               SDPatternOperator op,
4199                                               SDPatternOperator shift_op = null_frag> {
4200   def _B : sve2_int_bin_accum_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
4201   def _H : sve2_int_bin_accum_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
4202     let Inst{19} = imm{3};
4203   }
4204   def _S : sve2_int_bin_accum_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
4205     let Inst{20-19} = imm{4-3};
4206   }
4207   def _D : sve2_int_bin_accum_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
4208     let Inst{22}    = imm{5};
4209     let Inst{20-19} = imm{4-3};
4210   }
4212   def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4213   def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4214   def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4215   def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4217   def : SVE_Shift_Add_All_Active_Pat<nxv16i8, shift_op, nxv16i1, nxv16i8, nxv16i8, i32, !cast<Instruction>(NAME # _B)>;
4218   def : SVE_Shift_Add_All_Active_Pat<nxv8i16, shift_op, nxv8i1, nxv8i16, nxv8i16, i32, !cast<Instruction>(NAME # _H)>;
4219   def : SVE_Shift_Add_All_Active_Pat<nxv4i32, shift_op, nxv4i1, nxv4i32, nxv4i32, i32, !cast<Instruction>(NAME # _S)>;
4220   def : SVE_Shift_Add_All_Active_Pat<nxv2i64, shift_op, nxv2i1, nxv2i64, nxv2i64, i32, !cast<Instruction>(NAME # _D)>;
4223 class sve2_int_cadd<bits<2> sz, bit opc, string asm, ZPRRegOp zprty>
4224 : I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, complexrotateopodd:$rot),
4225   asm, "\t$Zdn, $_Zdn, $Zm, $rot", "", []>, Sched<[]> {
4226   bits<5> Zdn;
4227   bits<5> Zm;
4228   bit rot;
4229   let Inst{31-24} = 0b01000101;
4230   let Inst{23-22} = sz;
4231   let Inst{21-17} = 0b00000;
4232   let Inst{16}    = opc;
4233   let Inst{15-11} = 0b11011;
4234   let Inst{10}    = rot;
4235   let Inst{9-5}   = Zm;
4236   let Inst{4-0}   = Zdn;
4238   let Constraints = "$Zdn = $_Zdn";
4239   let DestructiveInstType = DestructiveOther;
4240   let ElementSize = ElementSizeNone;
4241   let hasSideEffects = 0;
4244 multiclass sve2_int_cadd<bit opc, string asm, SDPatternOperator op> {
4245   def _B : sve2_int_cadd<0b00, opc, asm, ZPR8>;
4246   def _H : sve2_int_cadd<0b01, opc, asm, ZPR16>;
4247   def _S : sve2_int_cadd<0b10, opc, asm, ZPR32>;
4248   def _D : sve2_int_cadd<0b11, opc, asm, ZPR64>;
4250   def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, complexrotateopodd, !cast<Instruction>(NAME # _B)>;
4251   def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, complexrotateopodd, !cast<Instruction>(NAME # _H)>;
4252   def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, complexrotateopodd, !cast<Instruction>(NAME # _S)>;
4253   def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, complexrotateopodd, !cast<Instruction>(NAME # _D)>;
4256 class sve2_int_absdiff_accum<bits<2> sz, bits<4> opc, string asm,
4257                              ZPRRegOp zprty1, ZPRRegOp zprty2>
4258 : I<(outs zprty1:$Zda), (ins zprty1:$_Zda, zprty2:$Zn, zprty2:$Zm),
4259   asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
4260   bits<5> Zda;
4261   bits<5> Zn;
4262   bits<5> Zm;
4263   let Inst{31-24} = 0b01000101;
4264   let Inst{23-22} = sz;
4265   let Inst{21}    = 0b0;
4266   let Inst{20-16} = Zm;
4267   let Inst{15-14} = 0b11;
4268   let Inst{13-10} = opc;
4269   let Inst{9-5}   = Zn;
4270   let Inst{4-0}   = Zda;
4272   let Constraints = "$Zda = $_Zda";
4273   let DestructiveInstType = DestructiveOther;
4274   let ElementSize = ElementSizeNone;
4275   let hasSideEffects = 0;
4278 multiclass sve2_int_absdiff_accum<bit opc, string asm, SDPatternOperator op> {
4279   def _B : sve2_int_absdiff_accum<0b00, { 0b111, opc }, asm, ZPR8, ZPR8>;
4280   def _H : sve2_int_absdiff_accum<0b01, { 0b111, opc }, asm, ZPR16, ZPR16>;
4281   def _S : sve2_int_absdiff_accum<0b10, { 0b111, opc }, asm, ZPR32, ZPR32>;
4282   def _D : sve2_int_absdiff_accum<0b11, { 0b111, opc }, asm, ZPR64, ZPR64>;
4284   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
4285   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
4286   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4287   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4290 multiclass sve2_int_absdiff_accum_long<bits<2> opc, string asm,
4291                                        SDPatternOperator op> {
4292   def _H : sve2_int_absdiff_accum<0b01, { 0b00, opc }, asm, ZPR16, ZPR8>;
4293   def _S : sve2_int_absdiff_accum<0b10, { 0b00, opc }, asm, ZPR32, ZPR16>;
4294   def _D : sve2_int_absdiff_accum<0b11, { 0b00, opc }, asm, ZPR64, ZPR32>;
4296   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _H)>;
4297   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _S)>;
4298   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _D)>;
4301 multiclass sve2_int_addsub_long_carry<bits<2> opc, string asm,
4302                                       SDPatternOperator op> {
4303   def _S : sve2_int_absdiff_accum<{ opc{1}, 0b0 }, { 0b010, opc{0} }, asm,
4304                                   ZPR32, ZPR32>;
4305   def _D : sve2_int_absdiff_accum<{ opc{1}, 0b1 }, { 0b010, opc{0} }, asm,
4306                                   ZPR64, ZPR64>;
4308   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
4309   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
4312 //===----------------------------------------------------------------------===//
4313 // SVE2 Narrowing Group
4314 //===----------------------------------------------------------------------===//
4316 class sve2_int_bin_shift_imm_narrow_bottom<bits<3> tsz8_64, bits<3> opc,
4317                                            string asm, ZPRRegOp zprty1,
4318                                            ZPRRegOp zprty2, Operand immtype>
4319 : I<(outs zprty1:$Zd), (ins zprty2:$Zn, immtype:$imm),
4320   asm, "\t$Zd, $Zn, $imm",
4321   "", []>, Sched<[]> {
4322   bits<5> Zd;
4323   bits<5> Zn;
4324   bits<5> imm;
4325   let Inst{31-23} = 0b010001010;
4326   let Inst{22}    = tsz8_64{2};
4327   let Inst{21}    = 0b1;
4328   let Inst{20-19} = tsz8_64{1-0};
4329   let Inst{18-16} = imm{2-0}; // imm3
4330   let Inst{15-14} = 0b00;
4331   let Inst{13-11} = opc;
4332   let Inst{10}    = 0b0;
4333   let Inst{9-5}   = Zn;
4334   let Inst{4-0}   = Zd;
4336   let hasSideEffects = 0;
4339 multiclass sve2_int_bin_shift_imm_right_narrow_bottom<bits<3> opc, string asm,
4340                                                       SDPatternOperator op> {
4341   def _B : sve2_int_bin_shift_imm_narrow_bottom<{0,0,1}, opc, asm, ZPR8, ZPR16,
4342                                                 tvecshiftR8>;
4343   def _H : sve2_int_bin_shift_imm_narrow_bottom<{0,1,?}, opc, asm, ZPR16, ZPR32,
4344                                                 tvecshiftR16> {
4345     let Inst{19} = imm{3};
4346   }
4347   def _S : sve2_int_bin_shift_imm_narrow_bottom<{1,?,?}, opc, asm, ZPR32, ZPR64,
4348                                                 tvecshiftR32> {
4349     let Inst{20-19} = imm{4-3};
4350   }
4351   def : SVE_2_Op_Imm_Pat<nxv16i8, op, nxv8i16, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4352   def : SVE_2_Op_Imm_Pat<nxv8i16, op, nxv4i32, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4353   def : SVE_2_Op_Imm_Pat<nxv4i32, op, nxv2i64, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4356 class sve2_int_bin_shift_imm_narrow_top<bits<3> tsz8_64, bits<3> opc,
4357                                         string asm, ZPRRegOp zprty1,
4358                                         ZPRRegOp zprty2, Operand immtype>
4359 : I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, immtype:$imm),
4360   asm, "\t$Zd, $Zn, $imm",
4361   "", []>, Sched<[]> {
4362   bits<5> Zd;
4363   bits<5> Zn;
4364   bits<5> imm;
4365   let Inst{31-23} = 0b010001010;
4366   let Inst{22}    = tsz8_64{2};
4367   let Inst{21}    = 0b1;
4368   let Inst{20-19} = tsz8_64{1-0};
4369   let Inst{18-16} = imm{2-0}; // imm3
4370   let Inst{15-14} = 0b00;
4371   let Inst{13-11} = opc;
4372   let Inst{10}    = 0b1;
4373   let Inst{9-5}   = Zn;
4374   let Inst{4-0}   = Zd;
4376   let Constraints = "$Zd = $_Zd";
4377   let hasSideEffects = 0;
4380 multiclass sve2_int_bin_shift_imm_right_narrow_top<bits<3> opc, string asm,
4381                                                    SDPatternOperator op> {
4382   def _B : sve2_int_bin_shift_imm_narrow_top<{0,0,1}, opc, asm, ZPR8, ZPR16,
4383                                              tvecshiftR8>;
4384   def _H : sve2_int_bin_shift_imm_narrow_top<{0,1,?}, opc, asm, ZPR16, ZPR32,
4385                                              tvecshiftR16> {
4386     let Inst{19} = imm{3};
4387   }
4388   def _S : sve2_int_bin_shift_imm_narrow_top<{1,?,?}, opc, asm, ZPR32, ZPR64,
4389                                              tvecshiftR32> {
4390     let Inst{20-19} = imm{4-3};
4391   }
4392   def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv8i16, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4393   def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv4i32, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4394   def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv2i64, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4397 class sve2_int_addsub_narrow_high_bottom<bits<2> sz, bits<2> opc, string asm,
4398                                          ZPRRegOp zprty1, ZPRRegOp zprty2>
4399 : I<(outs zprty1:$Zd), (ins zprty2:$Zn, zprty2:$Zm),
4400   asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4401   bits<5> Zd;
4402   bits<5> Zn;
4403   bits<5> Zm;
4404   let Inst{31-24} = 0b01000101;
4405   let Inst{23-22} = sz;
4406   let Inst{21}    = 0b1;
4407   let Inst{20-16} = Zm;
4408   let Inst{15-13} = 0b011;
4409   let Inst{12-11} = opc; // S, R
4410   let Inst{10}    = 0b0; // Top
4411   let Inst{9-5}   = Zn;
4412   let Inst{4-0}   = Zd;
4414   let hasSideEffects = 0;
4417 multiclass sve2_int_addsub_narrow_high_bottom<bits<2> opc, string asm,
4418                                               SDPatternOperator op> {
4419   def _B : sve2_int_addsub_narrow_high_bottom<0b01, opc, asm, ZPR8, ZPR16>;
4420   def _H : sve2_int_addsub_narrow_high_bottom<0b10, opc, asm, ZPR16, ZPR32>;
4421   def _S : sve2_int_addsub_narrow_high_bottom<0b11, opc, asm, ZPR32, ZPR64>;
4423   def : SVE_2_Op_Pat<nxv16i8, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _B)>;
4424   def : SVE_2_Op_Pat<nxv8i16, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _H)>;
4425   def : SVE_2_Op_Pat<nxv4i32, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _S)>;
4428 class sve2_int_addsub_narrow_high_top<bits<2> sz, bits<2> opc, string asm,
4429                                       ZPRRegOp zprty1, ZPRRegOp zprty2>
4430 : I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn, zprty2:$Zm),
4431   asm, "\t$Zd, $Zn, $Zm", "", []>, Sched<[]> {
4432   bits<5> Zd;
4433   bits<5> Zn;
4434   bits<5> Zm;
4435   let Inst{31-24} = 0b01000101;
4436   let Inst{23-22} = sz;
4437   let Inst{21}    = 0b1;
4438   let Inst{20-16} = Zm;
4439   let Inst{15-13} = 0b011;
4440   let Inst{12-11} = opc; // S, R
4441   let Inst{10}    = 0b1; // Top
4442   let Inst{9-5}   = Zn;
4443   let Inst{4-0}   = Zd;
4445   let Constraints = "$Zd = $_Zd";
4446   let hasSideEffects = 0;
4449 multiclass sve2_int_addsub_narrow_high_top<bits<2> opc, string asm,
4450                                            SDPatternOperator op> {
4451   def _B : sve2_int_addsub_narrow_high_top<0b01, opc, asm, ZPR8, ZPR16>;
4452   def _H : sve2_int_addsub_narrow_high_top<0b10, opc, asm, ZPR16, ZPR32>;
4453   def _S : sve2_int_addsub_narrow_high_top<0b11, opc, asm, ZPR32, ZPR64>;
4455   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _B)>;
4456   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _H)>;
4457   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _S)>;
4460 class sve2_int_sat_extract_narrow_bottom<bits<3> tsz8_64, bits<2> opc, string asm,
4461                                          ZPRRegOp zprty1, ZPRRegOp zprty2>
4462 : I<(outs zprty1:$Zd), (ins zprty2:$Zn),
4463   asm, "\t$Zd, $Zn", "", []>, Sched<[]> {
4464   bits<5> Zd;
4465   bits<5> Zn;
4466   let Inst{31-23} = 0b010001010;
4467   let Inst{22}    = tsz8_64{2};
4468   let Inst{21}    = 0b1;
4469   let Inst{20-19} = tsz8_64{1-0};
4470   let Inst{18-13} = 0b000010;
4471   let Inst{12-11} = opc;
4472   let Inst{10}    = 0b0;
4473   let Inst{9-5}   = Zn;
4474   let Inst{4-0}   = Zd;
4476   let hasSideEffects = 0;
4479 multiclass sve2_int_sat_extract_narrow_bottom<bits<2> opc, string asm,
4480                                               SDPatternOperator op> {
4481   def _B : sve2_int_sat_extract_narrow_bottom<0b001, opc, asm, ZPR8, ZPR16>;
4482   def _H : sve2_int_sat_extract_narrow_bottom<0b010, opc, asm, ZPR16, ZPR32>;
4483   def _S : sve2_int_sat_extract_narrow_bottom<0b100, opc, asm, ZPR32, ZPR64>;
4485   def : SVE_1_Op_Pat<nxv16i8, op, nxv8i16, !cast<Instruction>(NAME # _B)>;
4486   def : SVE_1_Op_Pat<nxv8i16, op, nxv4i32, !cast<Instruction>(NAME # _H)>;
4487   def : SVE_1_Op_Pat<nxv4i32, op, nxv2i64, !cast<Instruction>(NAME # _S)>;
4490 class sve2_int_sat_extract_narrow_top<bits<3> tsz8_64, bits<2> opc, string asm,
4491                                       ZPRRegOp zprty1, ZPRRegOp zprty2>
4492 : I<(outs zprty1:$Zd), (ins zprty1:$_Zd, zprty2:$Zn),
4493   asm, "\t$Zd, $Zn", "", []>, Sched<[]> {
4494   bits<5> Zd;
4495   bits<5> Zn;
4496   let Inst{31-23} = 0b010001010;
4497   let Inst{22}    = tsz8_64{2};
4498   let Inst{21}    = 0b1;
4499   let Inst{20-19} = tsz8_64{1-0};
4500   let Inst{18-13} = 0b000010;
4501   let Inst{12-11} = opc;
4502   let Inst{10}    = 0b1;
4503   let Inst{9-5}   = Zn;
4504   let Inst{4-0}   = Zd;
4506   let Constraints = "$Zd = $_Zd";
4507   let hasSideEffects = 0;
4510 multiclass sve2_int_sat_extract_narrow_top<bits<2> opc, string asm,
4511                                            SDPatternOperator op> {
4512   def _B : sve2_int_sat_extract_narrow_top<0b001, opc, asm, ZPR8, ZPR16>;
4513   def _H : sve2_int_sat_extract_narrow_top<0b010, opc, asm, ZPR16, ZPR32>;
4514   def _S : sve2_int_sat_extract_narrow_top<0b100, opc, asm, ZPR32, ZPR64>;
4516   def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv8i16, !cast<Instruction>(NAME # _B)>;
4517   def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv4i32, !cast<Instruction>(NAME # _H)>;
4518   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
4521 //===----------------------------------------------------------------------===//
4522 // SVE Integer Arithmetic - Unary Predicated Group
4523 //===----------------------------------------------------------------------===//
4525 class sve_int_un_pred_arit<bits<2> sz8_64, bits<4> opc,
4526                              string asm, ZPRRegOp zprty>
4527 : I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
4528   asm, "\t$Zd, $Pg/m, $Zn",
4529   "",
4530   []>, Sched<[]> {
4531   bits<3> Pg;
4532   bits<5> Zd;
4533   bits<5> Zn;
4534   let Inst{31-24} = 0b00000100;
4535   let Inst{23-22} = sz8_64;
4536   let Inst{21-20} = 0b01;
4537   let Inst{19}    = opc{0};
4538   let Inst{18-16} = opc{3-1};
4539   let Inst{15-13} = 0b101;
4540   let Inst{12-10} = Pg;
4541   let Inst{9-5}   = Zn;
4542   let Inst{4-0}   = Zd;
4544   let Constraints = "$Zd = $_Zd";
4545   let DestructiveInstType = DestructiveUnaryPassthru;
4546   let ElementSize = zprty.ElementSize;
4547   let hasSideEffects = 0;
4550 multiclass sve_int_un_pred_arit_0<bits<3> opc, string asm,
4551                                   SDPatternOperator op> {
4552   def _B : sve_int_un_pred_arit<0b00, { opc, 0b0 }, asm, ZPR8>,
4553            SVEPseudo2Instr<NAME # _B, 1>;
4554   def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>,
4555            SVEPseudo2Instr<NAME # _H, 1>;
4556   def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4557            SVEPseudo2Instr<NAME # _S, 1>;
4558   def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4559            SVEPseudo2Instr<NAME # _D, 1>;
4561   def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
4562   def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
4563   def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
4564   def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
4566   def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
4567   def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4568   def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4569   def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4571   defm : SVE_1_Op_PassthruUndef_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
4572   defm : SVE_1_Op_PassthruUndef_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4573   defm : SVE_1_Op_PassthruUndef_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4574   defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4577 multiclass sve_int_un_pred_arit_0_h<bits<3> opc, string asm,
4578                                     SDPatternOperator op> {
4579   def _H : sve_int_un_pred_arit<0b01, { opc, 0b0 }, asm, ZPR16>,
4580            SVEPseudo2Instr<NAME # _H, 1>;
4581   def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4582            SVEPseudo2Instr<NAME # _S, 1>;
4583   def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4584            SVEPseudo2Instr<NAME # _D, 1>;
4586   def : SVE_InReg_Extend<nxv8i16, op, nxv8i1, nxv8i8, !cast<Instruction>(NAME # _H)>;
4587   def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i8, !cast<Instruction>(NAME # _S)>;
4588   def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i8, !cast<Instruction>(NAME # _D)>;
4590   def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4591   def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4592   def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4594   defm : SVE_InReg_Extend_PassthruUndef<nxv8i16, op, nxv8i1, nxv8i8, !cast<Pseudo>(NAME # _H_UNDEF)>;
4595   defm : SVE_InReg_Extend_PassthruUndef<nxv4i32, op, nxv4i1, nxv4i8, !cast<Pseudo>(NAME # _S_UNDEF)>;
4596   defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i8, !cast<Pseudo>(NAME # _D_UNDEF)>;
4599 multiclass sve_int_un_pred_arit_0_w<bits<3> opc, string asm,
4600                                     SDPatternOperator op> {
4601   def _S : sve_int_un_pred_arit<0b10, { opc, 0b0 }, asm, ZPR32>,
4602            SVEPseudo2Instr<NAME # _S, 1>;
4603   def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4604            SVEPseudo2Instr<NAME # _D, 1>;
4606   def : SVE_InReg_Extend<nxv4i32, op, nxv4i1, nxv4i16, !cast<Instruction>(NAME # _S)>;
4607   def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i16, !cast<Instruction>(NAME # _D)>;
4609   def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4610   def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4612   defm : SVE_InReg_Extend_PassthruUndef<nxv4i32, op, nxv4i1, nxv4i16, !cast<Pseudo>(NAME # _S_UNDEF)>;
4613   defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i16, !cast<Pseudo>(NAME # _D_UNDEF)>;
4616 multiclass sve_int_un_pred_arit_0_d<bits<3> opc, string asm,
4617                                     SDPatternOperator op> {
4618   def _D : sve_int_un_pred_arit<0b11, { opc, 0b0 }, asm, ZPR64>,
4619            SVEPseudo2Instr<NAME # _D, 1>;
4621   def : SVE_InReg_Extend<nxv2i64, op, nxv2i1, nxv2i32, !cast<Instruction>(NAME # _D)>;
4623   def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4625   defm : SVE_InReg_Extend_PassthruUndef<nxv2i64, op, nxv2i1, nxv2i32, !cast<Pseudo>(NAME # _D_UNDEF)>;
4628 multiclass sve_int_un_pred_arit_1<bits<3> opc, string asm,
4629                                   SDPatternOperator op> {
4630   def _B : sve_int_un_pred_arit<0b00, { opc, 0b1 }, asm, ZPR8>,
4631            SVEPseudo2Instr<NAME # _B, 1>;
4632   def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>,
4633            SVEPseudo2Instr<NAME # _H, 1>;
4634   def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>,
4635            SVEPseudo2Instr<NAME # _S, 1>;
4636   def _D : sve_int_un_pred_arit<0b11, { opc, 0b1 }, asm, ZPR64>,
4637            SVEPseudo2Instr<NAME # _D, 1>;
4639   def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
4640   def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
4641   def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
4642   def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
4644   def _B_UNDEF : PredOneOpPassthruPseudo<NAME # _B, ZPR8>;
4645   def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4646   def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4647   def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4649   defm : SVE_1_Op_PassthruUndef_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
4650   defm : SVE_1_Op_PassthruUndef_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4651   defm : SVE_1_Op_PassthruUndef_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4652   defm : SVE_1_Op_PassthruUndef_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4655 multiclass sve_int_un_pred_arit_1_fp<bits<3> opc, string asm, SDPatternOperator op> {
4656   def _H : sve_int_un_pred_arit<0b01, { opc, 0b1 }, asm, ZPR16>,
4657            SVEPseudo2Instr<NAME # _H, 1>;
4658   def _S : sve_int_un_pred_arit<0b10, { opc, 0b1 }, asm, ZPR32>,
4659            SVEPseudo2Instr<NAME # _S, 1>;
4660   def _D : sve_int_un_pred_arit<0b11, { opc, 0b1 }, asm, ZPR64>,
4661            SVEPseudo2Instr<NAME # _D, 1>;
4663   def : SVE_1_Op_Passthru_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
4664   def : SVE_1_Op_Passthru_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
4665   def : SVE_1_Op_Passthru_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
4666   def : SVE_1_Op_Passthru_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
4667   def : SVE_1_Op_Passthru_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
4668   def : SVE_1_Op_Passthru_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
4670   def _H_UNDEF : PredOneOpPassthruPseudo<NAME # _H, ZPR16>;
4671   def _S_UNDEF : PredOneOpPassthruPseudo<NAME # _S, ZPR32>;
4672   def _D_UNDEF : PredOneOpPassthruPseudo<NAME # _D, ZPR64>;
4674   defm : SVE_1_Op_PassthruUndef_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4675   defm : SVE_1_Op_PassthruUndef_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4676   defm : SVE_1_Op_PassthruUndef_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
4677   defm : SVE_1_Op_PassthruUndef_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4678   defm : SVE_1_Op_PassthruUndef_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
4679   defm : SVE_1_Op_PassthruUndef_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Pseudo>(NAME # _D_UNDEF)>;
4682 //===----------------------------------------------------------------------===//
4683 // SVE Integer Wide Immediate - Unpredicated Group
4684 //===----------------------------------------------------------------------===//
4685 class sve_int_dup_imm<bits<2> sz8_64, string asm,
4686                       ZPRRegOp zprty, Operand immtype>
4687 : I<(outs zprty:$Zd), (ins immtype:$imm),
4688   asm, "\t$Zd, $imm",
4689   "",
4690   []>, Sched<[]> {
4691   bits<5> Zd;
4692   bits<9> imm;
4693   let Inst{31-24} = 0b00100101;
4694   let Inst{23-22} = sz8_64;
4695   let Inst{21-14} = 0b11100011;
4696   let Inst{13}    = imm{8};   // sh
4697   let Inst{12-5}  = imm{7-0}; // imm8
4698   let Inst{4-0}   = Zd;
4700   let hasSideEffects = 0;
4701   let isReMaterializable = 1;
4704 multiclass sve_int_dup_imm<string asm> {
4705   def _B : sve_int_dup_imm<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8>;
4706   def _H : sve_int_dup_imm<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16>;
4707   def _S : sve_int_dup_imm<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32>;
4708   def _D : sve_int_dup_imm<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64>;
4710   def : InstAlias<"mov $Zd, $imm",
4711                   (!cast<Instruction>(NAME # _B) ZPR8:$Zd, cpy_imm8_opt_lsl_i8:$imm), 1>;
4712   def : InstAlias<"mov $Zd, $imm",
4713                   (!cast<Instruction>(NAME # _H) ZPR16:$Zd, cpy_imm8_opt_lsl_i16:$imm), 1>;
4714   def : InstAlias<"mov $Zd, $imm",
4715                   (!cast<Instruction>(NAME # _S) ZPR32:$Zd, cpy_imm8_opt_lsl_i32:$imm), 1>;
4716   def : InstAlias<"mov $Zd, $imm",
4717                   (!cast<Instruction>(NAME # _D) ZPR64:$Zd, cpy_imm8_opt_lsl_i64:$imm), 1>;
4719   def : InstAlias<"fmov $Zd, #0.0",
4720                   (!cast<Instruction>(NAME # _H) ZPR16:$Zd, 0, 0), 1>;
4721   def : InstAlias<"fmov $Zd, #0.0",
4722                   (!cast<Instruction>(NAME # _S) ZPR32:$Zd, 0, 0), 1>;
4723   def : InstAlias<"fmov $Zd, #0.0",
4724                   (!cast<Instruction>(NAME # _D) ZPR64:$Zd, 0, 0), 1>;
4727 class sve_int_dup_fpimm<bits<2> sz8_64, Operand fpimmtype,
4728                         string asm, ZPRRegOp zprty>
4729 : I<(outs zprty:$Zd), (ins fpimmtype:$imm8),
4730   asm, "\t$Zd, $imm8",
4731   "",
4732   []>, Sched<[]> {
4733   bits<5> Zd;
4734   bits<8> imm8;
4735   let Inst{31-24} = 0b00100101;
4736   let Inst{23-22} = sz8_64;
4737   let Inst{21-14} = 0b11100111;
4738   let Inst{13}    = 0b0;
4739   let Inst{12-5}  = imm8;
4740   let Inst{4-0}   = Zd;
4742   let hasSideEffects = 0;
4743   let isReMaterializable = 1;
4746 multiclass sve_int_dup_fpimm<string asm> {
4747   def _H : sve_int_dup_fpimm<0b01, fpimm16, asm, ZPR16>;
4748   def _S : sve_int_dup_fpimm<0b10, fpimm32, asm, ZPR32>;
4749   def _D : sve_int_dup_fpimm<0b11, fpimm64, asm, ZPR64>;
4751   def : InstAlias<"fmov $Zd, $imm8",
4752                   (!cast<Instruction>(NAME # _H) ZPR16:$Zd, fpimm16:$imm8), 1>;
4753   def : InstAlias<"fmov $Zd, $imm8",
4754                   (!cast<Instruction>(NAME # _S) ZPR32:$Zd, fpimm32:$imm8), 1>;
4755   def : InstAlias<"fmov $Zd, $imm8",
4756                   (!cast<Instruction>(NAME # _D) ZPR64:$Zd, fpimm64:$imm8), 1>;
4759 class sve_int_arith_imm0<bits<2> sz8_64, bits<3> opc, string asm,
4760                          ZPRRegOp zprty, Operand immtype>
4761 : I<(outs zprty:$Zdn), (ins zprty:$_Zdn, immtype:$imm),
4762   asm, "\t$Zdn, $_Zdn, $imm",
4763   "",
4764   []>, Sched<[]> {
4765   bits<5> Zdn;
4766   bits<9> imm;
4767   let Inst{31-24} = 0b00100101;
4768   let Inst{23-22} = sz8_64;
4769   let Inst{21-19} = 0b100;
4770   let Inst{18-16} = opc;
4771   let Inst{15-14} = 0b11;
4772   let Inst{13}    = imm{8};   // sh
4773   let Inst{12-5}  = imm{7-0}; // imm8
4774   let Inst{4-0}   = Zdn;
4776   let Constraints = "$Zdn = $_Zdn";
4777   let DestructiveInstType = DestructiveOther;
4778   let ElementSize = ElementSizeNone;
4779   let hasSideEffects = 0;
4782 multiclass sve_int_arith_imm0<bits<3> opc, string asm, SDPatternOperator op> {
4783   def _B : sve_int_arith_imm0<0b00, opc, asm, ZPR8,  addsub_imm8_opt_lsl_i8>;
4784   def _H : sve_int_arith_imm0<0b01, opc, asm, ZPR16, addsub_imm8_opt_lsl_i16>;
4785   def _S : sve_int_arith_imm0<0b10, opc, asm, ZPR32, addsub_imm8_opt_lsl_i32>;
4786   def _D : sve_int_arith_imm0<0b11, opc, asm, ZPR64, addsub_imm8_opt_lsl_i64>;
4788   def : SVE_1_Op_Imm_OptLsl_Pat<nxv16i8, op, ZPR8,  i32, SVEAddSubImm8Pat,  !cast<Instruction>(NAME # _B)>;
4789   def : SVE_1_Op_Imm_OptLsl_Pat<nxv8i16, op, ZPR16, i32, SVEAddSubImm16Pat, !cast<Instruction>(NAME # _H)>;
4790   def : SVE_1_Op_Imm_OptLsl_Pat<nxv4i32, op, ZPR32, i32, SVEAddSubImm32Pat, !cast<Instruction>(NAME # _S)>;
4791   def : SVE_1_Op_Imm_OptLsl_Pat<nxv2i64, op, ZPR64, i64, SVEAddSubImm64Pat, !cast<Instruction>(NAME # _D)>;
4794 class sve_int_arith_imm<bits<2> sz8_64, bits<6> opc, string asm,
4795                         ZPRRegOp zprty, Operand immtype>
4796 : I<(outs zprty:$Zdn), (ins zprty:$_Zdn, immtype:$imm),
4797   asm, "\t$Zdn, $_Zdn, $imm",
4798   "",
4799   []>, Sched<[]> {
4800   bits<5> Zdn;
4801   bits<8> imm;
4802   let Inst{31-24} = 0b00100101;
4803   let Inst{23-22} = sz8_64;
4804   let Inst{21-16} = opc;
4805   let Inst{15-13} = 0b110;
4806   let Inst{12-5} = imm;
4807   let Inst{4-0} = Zdn;
4809   let Constraints = "$Zdn = $_Zdn";
4810   let DestructiveInstType = DestructiveOther;
4811   let ElementSize = ElementSizeNone;
4812   let hasSideEffects = 0;
4815 multiclass sve_int_arith_imm1<bits<2> opc, string asm, SDPatternOperator op> {
4816   def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, simm8_32b>;
4817   def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, simm8_32b>;
4818   def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, simm8_32b>;
4819   def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, simm8_32b>;
4821   def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B)>;
4822   def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1,  op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H)>;
4823   def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1,  op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S)>;
4824   def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1,  op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D)>;
4827 multiclass sve_int_arith_imm1_unsigned<bits<2> opc, string asm, SDPatternOperator op> {
4828   def _B : sve_int_arith_imm<0b00, { 0b1010, opc }, asm, ZPR8, imm0_255>;
4829   def _H : sve_int_arith_imm<0b01, { 0b1010, opc }, asm, ZPR16, imm0_255>;
4830   def _S : sve_int_arith_imm<0b10, { 0b1010, opc }, asm, ZPR32, imm0_255>;
4831   def _D : sve_int_arith_imm<0b11, { 0b1010, opc }, asm, ZPR64, imm0_255>;
4833   def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithUImm8Pat, !cast<Instruction>(NAME # _B)>;
4834   def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithUImm16Pat, !cast<Instruction>(NAME # _H)>;
4835   def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithUImm32Pat, !cast<Instruction>(NAME # _S)>;
4836   def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithUImm64Pat, !cast<Instruction>(NAME # _D)>;
4839 multiclass sve_int_arith_imm2<string asm, SDPatternOperator op> {
4840   def _B : sve_int_arith_imm<0b00, 0b110000, asm, ZPR8,  simm8_32b>;
4841   def _H : sve_int_arith_imm<0b01, 0b110000, asm, ZPR16, simm8_32b>;
4842   def _S : sve_int_arith_imm<0b10, 0b110000, asm, ZPR32, simm8_32b>;
4843   def _D : sve_int_arith_imm<0b11, 0b110000, asm, ZPR64, simm8_32b>;
4845   def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv16i8, nxv16i1, op, ZPR8, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _B)>;
4846   def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv8i16, nxv8i1, op, ZPR16, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _H)>;
4847   def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv4i32, nxv4i1, op, ZPR32, i32, SVEArithSImmPat32, !cast<Instruction>(NAME # _S)>;
4848   def : SVE_1_Op_Imm_Arith_Any_Predicate<nxv2i64, nxv2i1, op, ZPR64, i64, SVEArithSImmPat64, !cast<Instruction>(NAME # _D)>;
4851 //===----------------------------------------------------------------------===//
4852 // SVE Bitwise Logical - Unpredicated Group
4853 //===----------------------------------------------------------------------===//
4855 class sve_int_bin_cons_log<bits<2> opc, string asm>
4856 : I<(outs ZPR64:$Zd), (ins ZPR64:$Zn, ZPR64:$Zm),
4857   asm, "\t$Zd, $Zn, $Zm",
4858   "",
4859   []>, Sched<[]> {
4860   bits<5> Zd;
4861   bits<5> Zm;
4862   bits<5> Zn;
4863   let Inst{31-24} = 0b00000100;
4864   let Inst{23-22} = opc{1-0};
4865   let Inst{21}    = 0b1;
4866   let Inst{20-16} = Zm;
4867   let Inst{15-10} = 0b001100;
4868   let Inst{9-5}   = Zn;
4869   let Inst{4-0}   = Zd;
4871   let hasSideEffects = 0;
4874 multiclass sve_int_bin_cons_log<bits<2> opc, string asm, SDPatternOperator op> {
4875   def NAME : sve_int_bin_cons_log<opc, asm>;
4877   def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
4878   def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
4879   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
4880   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4882   def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4883                   (!cast<Instruction>(NAME) ZPR8:$Zd,  ZPR8:$Zn,  ZPR8:$Zm),  1>;
4884   def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4885                   (!cast<Instruction>(NAME) ZPR16:$Zd, ZPR16:$Zn, ZPR16:$Zm), 1>;
4886   def : InstAlias<asm # "\t$Zd, $Zn, $Zm",
4887                   (!cast<Instruction>(NAME) ZPR32:$Zd, ZPR32:$Zn, ZPR32:$Zm), 1>;
4890 class sve2_int_bitwise_ternary_op_d<bits<3> opc, string asm>
4891 : I<(outs ZPR64:$Zdn), (ins ZPR64:$_Zdn, ZPR64:$Zm, ZPR64:$Zk),
4892   asm, "\t$Zdn, $_Zdn, $Zm, $Zk",
4893   "",
4894   []>, Sched<[]> {
4895   bits<5> Zdn;
4896   bits<5> Zk;
4897   bits<5> Zm;
4898   let Inst{31-24} = 0b00000100;
4899   let Inst{23-22} = opc{2-1};
4900   let Inst{21}    = 0b1;
4901   let Inst{20-16} = Zm;
4902   let Inst{15-11} = 0b00111;
4903   let Inst{10}    = opc{0};
4904   let Inst{9-5}   = Zk;
4905   let Inst{4-0}   = Zdn;
4907   let Constraints = "$Zdn = $_Zdn";
4908   let DestructiveInstType = DestructiveOther;
4909   let ElementSize = ElementSizeNone;
4910   let hasSideEffects = 0;
4913 multiclass sve2_int_bitwise_ternary_op<bits<3> opc, string asm, SDPatternOperator op,
4914                                        SDPatternOperator ir_op = null_frag> {
4915   def NAME : sve2_int_bitwise_ternary_op_d<opc, asm>;
4917   def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4918                   (!cast<Instruction>(NAME) ZPR8:$Zdn,  ZPR8:$Zm,  ZPR8:$Zk),  1>;
4919   def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4920                   (!cast<Instruction>(NAME) ZPR16:$Zdn, ZPR16:$Zm, ZPR16:$Zk), 1>;
4921   def : InstAlias<asm # "\t$Zdn, $Zdn, $Zm, $Zk",
4922                   (!cast<Instruction>(NAME) ZPR32:$Zdn, ZPR32:$Zm, ZPR32:$Zk), 1>;
4924   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
4925   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
4926   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
4927   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4930   def : SVE_3_Op_BSP_Pat<nxv16i8, ir_op, nxv16i8, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
4931   def : SVE_3_Op_BSP_Pat<nxv8i16, ir_op, nxv8i16, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
4932   def : SVE_3_Op_BSP_Pat<nxv4i32, ir_op, nxv4i32, nxv4i32, nxv4i32, !cast<Instruction>(NAME)>;
4933   def : SVE_3_Op_BSP_Pat<nxv2i64, ir_op, nxv2i64, nxv2i64, nxv2i64, !cast<Instruction>(NAME)>;
4936 class sve2_int_rotate_right_imm<bits<4> tsz8_64, string asm,
4937                                 ZPRRegOp zprty, Operand immtype>
4938 : I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm, immtype:$imm),
4939   asm, "\t$Zdn, $_Zdn, $Zm, $imm",
4940   "",
4941   []>, Sched<[]> {
4942   bits<5> Zdn;
4943   bits<5> Zm;
4944   bits<6> imm;
4945   let Inst{31-24} = 0b00000100;
4946   let Inst{23-22} = tsz8_64{3-2};
4947   let Inst{21}    = 0b1;
4948   let Inst{20-19} = tsz8_64{1-0};
4949   let Inst{18-16} = imm{2-0}; // imm3
4950   let Inst{15-10} = 0b001101;
4951   let Inst{9-5}   = Zm;
4952   let Inst{4-0}   = Zdn;
4954   let Constraints = "$Zdn = $_Zdn";
4955   let DestructiveInstType = DestructiveOther;
4956   let ElementSize = ElementSizeNone;
4957   let hasSideEffects = 0;
4960 multiclass sve2_int_rotate_right_imm<string asm, SDPatternOperator op> {
4961   def _B : sve2_int_rotate_right_imm<{0,0,0,1}, asm, ZPR8, vecshiftR8>;
4962   def _H : sve2_int_rotate_right_imm<{0,0,1,?}, asm, ZPR16, vecshiftR16> {
4963     let Inst{19} = imm{3};
4964   }
4965   def _S : sve2_int_rotate_right_imm<{0,1,?,?}, asm, ZPR32, vecshiftR32> {
4966     let Inst{20-19} = imm{4-3};
4967   }
4968   def _D : sve2_int_rotate_right_imm<{1,?,?,?}, asm, ZPR64, vecshiftR64> {
4969     let Inst{22}    = imm{5};
4970     let Inst{20-19} = imm{4-3};
4971   }
4973   def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i8, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
4974   def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i16, nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
4975   def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
4976   def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i64, nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
4979 //===----------------------------------------------------------------------===//
4980 // SVE Integer Wide Immediate - Predicated Group
4981 //===----------------------------------------------------------------------===//
4983 class sve_int_dup_fpimm_pred<bits<2> sz, Operand fpimmtype,
4984                              string asm, ZPRRegOp zprty>
4985 : I<(outs zprty:$Zd), (ins zprty:$_Zd, PPRAny:$Pg, fpimmtype:$imm8),
4986   asm, "\t$Zd, $Pg/m, $imm8",
4987   "",
4988   []>, Sched<[]> {
4989   bits<4> Pg;
4990   bits<5> Zd;
4991   bits<8> imm8;
4992   let Inst{31-24} = 0b00000101;
4993   let Inst{23-22} = sz;
4994   let Inst{21-20} = 0b01;
4995   let Inst{19-16} = Pg;
4996   let Inst{15-13} = 0b110;
4997   let Inst{12-5}  = imm8;
4998   let Inst{4-0}   = Zd;
5000   let Constraints = "$Zd = $_Zd";
5001   let DestructiveInstType = DestructiveOther;
5002   let ElementSize = zprty.ElementSize;
5003   let hasSideEffects = 0;
5006 multiclass sve_int_dup_fpimm_pred<string asm> {
5007   def _H : sve_int_dup_fpimm_pred<0b01, fpimm16, asm, ZPR16>;
5008   def _S : sve_int_dup_fpimm_pred<0b10, fpimm32, asm, ZPR32>;
5009   def _D : sve_int_dup_fpimm_pred<0b11, fpimm64, asm, ZPR64>;
5011   def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
5012                   (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, fpimm16:$imm8), 1>;
5013   def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
5014                   (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, fpimm32:$imm8), 1>;
5015   def : InstAlias<"fmov $Zd, $Pg/m, $imm8",
5016                   (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, fpimm64:$imm8), 1>;
5019 class sve_int_dup_imm_pred<bits<2> sz8_64, bit m, string asm,
5020                            ZPRRegOp zprty, string pred_qual, dag iops>
5021 : I<(outs zprty:$Zd), iops,
5022   asm, "\t$Zd, $Pg"#pred_qual#", $imm",
5023   "", []>, Sched<[]> {
5024   bits<5> Zd;
5025   bits<4> Pg;
5026   bits<9> imm;
5027   let Inst{31-24} = 0b00000101;
5028   let Inst{23-22} = sz8_64;
5029   let Inst{21-20} = 0b01;
5030   let Inst{19-16} = Pg;
5031   let Inst{15}    = 0b0;
5032   let Inst{14}    = m;
5033   let Inst{13}    = imm{8};   // sh
5034   let Inst{12-5}  = imm{7-0}; // imm8
5035   let Inst{4-0}   = Zd;
5037   let DestructiveInstType = DestructiveOther;
5038   let ElementSize = zprty.ElementSize;
5039   let hasSideEffects = 0;
5042 multiclass sve_int_dup_imm_pred_merge_inst<
5043     bits<2> sz8_64, string asm, ZPRRegOp zprty, imm8_opt_lsl cpyimm,
5044     ValueType intty, ValueType predty, ValueType scalarty, ComplexPattern cpx> {
5045   let Constraints = "$Zd = $_Zd" in
5046   def NAME : sve_int_dup_imm_pred<sz8_64, 1, asm, zprty,  "/m",
5047                                   (ins zprty:$_Zd, PPRAny:$Pg, cpyimm:$imm)>;
5048   def : InstAlias<"mov $Zd, $Pg/m, $imm",
5049                   (!cast<Instruction>(NAME) zprty:$Zd, PPRAny:$Pg, cpyimm:$imm), 1>;
5050   def : Pat<(vselect predty:$Pg,
5051                 (intty (splat_vector (scalarty (cpx i32:$imm, i32:$shift)))),
5052                 ZPR:$Zd),
5053             (!cast<Instruction>(NAME) $Zd, $Pg, $imm, $shift)>;
5056 multiclass sve_int_dup_imm_pred_merge<string asm> {
5057   defm _B : sve_int_dup_imm_pred_merge_inst<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8,
5058                                             nxv16i8, nxv16i1, i32, SVECpyDupImm8Pat>;
5059   defm _H : sve_int_dup_imm_pred_merge_inst<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16,
5060                                             nxv8i16, nxv8i1, i32, SVECpyDupImm16Pat>;
5061   defm _S : sve_int_dup_imm_pred_merge_inst<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32,
5062                                             nxv4i32, nxv4i1, i32, SVECpyDupImm32Pat>;
5063   defm _D : sve_int_dup_imm_pred_merge_inst<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64,
5064                                             nxv2i64, nxv2i1, i64, SVECpyDupImm64Pat>;
5066   def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5067                   (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPRAny:$Pg, 0, 0), 0>;
5068   def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5069                   (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPRAny:$Pg, 0, 0), 0>;
5070   def : InstAlias<"fmov $Zd, $Pg/m, #0.0",
5071                   (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPRAny:$Pg, 0, 0), 0>;
5073   def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv8f16 ZPR:$Zd)),
5074             (!cast<Instruction>(NAME # _H) $Zd, $Pg, 0, 0)>;
5075   def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv4f16 ZPR:$Zd)),
5076             (!cast<Instruction>(NAME # _S) $Zd, $Pg, 0, 0)>;
5077   def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f16 ZPR:$Zd)),
5078             (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5079   def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv4f32 ZPR:$Zd)),
5080             (!cast<Instruction>(NAME # _S) $Zd, $Pg, 0, 0)>;
5081   def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f32 ZPR:$Zd)),
5082             (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5083   def : Pat<(vselect PPRAny:$Pg, (SVEDup0), (nxv2f64 ZPR:$Zd)),
5084             (!cast<Instruction>(NAME # _D) $Zd, $Pg, 0, 0)>;
5087 multiclass sve_int_dup_imm_pred_zero_inst<
5088     bits<2> sz8_64, string asm, ZPRRegOp zprty, imm8_opt_lsl cpyimm,
5089     ValueType intty, ValueType predty, ValueType scalarty, ComplexPattern cpx> {
5090   def NAME : sve_int_dup_imm_pred<sz8_64, 0, asm, zprty, "/z",
5091                                   (ins PPRAny:$Pg, cpyimm:$imm)>;
5092   def : InstAlias<"mov $Zd, $Pg/z, $imm",
5093                   (!cast<Instruction>(NAME) zprty:$Zd, PPRAny:$Pg, cpyimm:$imm), 1>;
5094   def : Pat<(intty (zext (predty PPRAny:$Ps1))),
5095             (!cast<Instruction>(NAME) PPRAny:$Ps1, 1, 0)>;
5096   def : Pat<(intty (sext (predty PPRAny:$Ps1))),
5097             (!cast<Instruction>(NAME) PPRAny:$Ps1, -1, 0)>;
5098   def : Pat<(intty (anyext (predty PPRAny:$Ps1))),
5099             (!cast<Instruction>(NAME) PPRAny:$Ps1, 1, 0)>;
5100   def : Pat<(vselect predty:$Pg,
5101                 (intty (splat_vector (scalarty (cpx i32:$imm, i32:$shift)))),
5102                 (intty (splat_vector (scalarty 0)))),
5103             (!cast<Instruction>(NAME) $Pg, $imm, $shift)>;
5106 multiclass sve_int_dup_imm_pred_zero<string asm> {
5107   defm _B : sve_int_dup_imm_pred_zero_inst<0b00, asm, ZPR8, cpy_imm8_opt_lsl_i8,
5108                                            nxv16i8, nxv16i1, i32, SVECpyDupImm8Pat>;
5109   defm _H : sve_int_dup_imm_pred_zero_inst<0b01, asm, ZPR16, cpy_imm8_opt_lsl_i16,
5110                                            nxv8i16, nxv8i1, i32, SVECpyDupImm16Pat>;
5111   defm _S : sve_int_dup_imm_pred_zero_inst<0b10, asm, ZPR32, cpy_imm8_opt_lsl_i32,
5112                                            nxv4i32, nxv4i1, i32, SVECpyDupImm32Pat>;
5113   defm _D : sve_int_dup_imm_pred_zero_inst<0b11, asm, ZPR64, cpy_imm8_opt_lsl_i64,
5114                                            nxv2i64, nxv2i1, i64, SVECpyDupImm64Pat>;
5117 //===----------------------------------------------------------------------===//
5118 // SVE Integer Compare - Vectors Group
5119 //===----------------------------------------------------------------------===//
5121 class sve_int_cmp<bit cmp_1, bits<2> sz8_64, bits<3> opc, string asm,
5122                   PPRRegOp pprty, ZPRRegOp zprty1, ZPRRegOp zprty2>
5123 : I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty1:$Zn, zprty2:$Zm),
5124   asm, "\t$Pd, $Pg/z, $Zn, $Zm",
5125   "",
5126   []>, Sched<[]> {
5127   bits<4> Pd;
5128   bits<3> Pg;
5129   bits<5> Zm;
5130   bits<5> Zn;
5131   let Inst{31-24} = 0b00100100;
5132   let Inst{23-22} = sz8_64;
5133   let Inst{21}    = 0b0;
5134   let Inst{20-16} = Zm;
5135   let Inst{15}    = opc{2};
5136   let Inst{14}    = cmp_1;
5137   let Inst{13}    = opc{1};
5138   let Inst{12-10} = Pg;
5139   let Inst{9-5}   = Zn;
5140   let Inst{4}     = opc{0};
5141   let Inst{3-0}   = Pd;
5143   let Defs = [NZCV];
5144   let ElementSize = pprty.ElementSize;
5145   let hasSideEffects = 0;
5146   let isPTestLike = 1;
5149 multiclass SVE_SETCC_Pat<CondCode cc, CondCode invcc, ValueType predvt,
5150                          ValueType intvt, Instruction cmp> {
5151   def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, intvt:$Op3, cc)),
5152             (cmp $Op1, $Op2, $Op3)>;
5153   def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, intvt:$Op3, invcc)),
5154             (cmp $Op1, $Op3, $Op2)>;
5155   def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), intvt:$Op2, intvt:$Op3, cc))),
5156             (cmp $Pg, $Op2, $Op3)>;
5157   def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), intvt:$Op2, intvt:$Op3, invcc))),
5158             (cmp $Pg, $Op3, $Op2)>;
5161 multiclass SVE_SETCC_Pat_With_Zero<CondCode cc, CondCode invcc, ValueType predvt,
5162                                    ValueType intvt, Instruction cmp> {
5163   def : Pat<(predvt (AArch64setcc_z predvt:$Op1, intvt:$Op2, (SVEDup0), cc)),
5164             (cmp $Op1, $Op2)>;
5165   def : Pat<(predvt (AArch64setcc_z predvt:$Op1, (SVEDup0), intvt:$Op2, invcc)),
5166             (cmp $Op1, $Op2)>;
5167   def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), intvt:$Op1, (SVEDup0), cc))),
5168             (cmp $Pg, $Op1)>;
5169   def : Pat<(predvt (and predvt:$Pg, (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)), (SVEDup0), intvt:$Op1, invcc))),
5170             (cmp $Pg, $Op1)>;
5173 multiclass sve_int_cmp_0<bits<3> opc, string asm, CondCode cc, CondCode invcc> {
5174   def _B : sve_int_cmp<0b0, 0b00, opc, asm, PPR8, ZPR8, ZPR8>;
5175   def _H : sve_int_cmp<0b0, 0b01, opc, asm, PPR16, ZPR16, ZPR16>;
5176   def _S : sve_int_cmp<0b0, 0b10, opc, asm, PPR32, ZPR32, ZPR32>;
5177   def _D : sve_int_cmp<0b0, 0b11, opc, asm, PPR64, ZPR64, ZPR64>;
5179   defm : SVE_SETCC_Pat<cc, invcc, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
5180   defm : SVE_SETCC_Pat<cc, invcc, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
5181   defm : SVE_SETCC_Pat<cc, invcc, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
5182   defm : SVE_SETCC_Pat<cc, invcc, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
5185 multiclass sve_int_cmp_0_wide<bits<3> opc, string asm, SDPatternOperator op> {
5186   def _B : sve_int_cmp<0b0, 0b00, opc, asm, PPR8, ZPR8, ZPR64>;
5187   def _H : sve_int_cmp<0b0, 0b01, opc, asm, PPR16, ZPR16, ZPR64>;
5188   def _S : sve_int_cmp<0b0, 0b10, opc, asm, PPR32, ZPR32, ZPR64>;
5190   def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
5191   def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
5192   def : SVE_3_Op_Pat<nxv4i1,  op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
5195 multiclass sve_int_cmp_1_wide<bits<3> opc, string asm, SDPatternOperator op> {
5196   def _B : sve_int_cmp<0b1, 0b00, opc, asm, PPR8, ZPR8, ZPR64>;
5197   def _H : sve_int_cmp<0b1, 0b01, opc, asm, PPR16, ZPR16, ZPR64>;
5198   def _S : sve_int_cmp<0b1, 0b10, opc, asm, PPR32, ZPR32, ZPR64>;
5200   def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
5201   def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
5202   def : SVE_3_Op_Pat<nxv4i1,  op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
5206 //===----------------------------------------------------------------------===//
5207 // SVE Integer Compare - Signed Immediate Group
5208 //===----------------------------------------------------------------------===//
5210 class sve_int_scmp_vi<bits<2> sz8_64, bits<3> opc, string asm, PPRRegOp pprty,
5211                       ZPRRegOp zprty,
5212                       Operand immtype>
5213 : I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, immtype:$imm5),
5214   asm, "\t$Pd, $Pg/z, $Zn, $imm5",
5215   "",
5216   []>, Sched<[]> {
5217   bits<4> Pd;
5218   bits<3> Pg;
5219   bits<5> Zn;
5220   bits<5> imm5;
5221   let Inst{31-24} = 0b00100101;
5222   let Inst{23-22} = sz8_64;
5223   let Inst{21}    = 0b0;
5224   let Inst{20-16} = imm5;
5225   let Inst{15}    = opc{2};
5226   let Inst{14}    = 0b0;
5227   let Inst{13}    = opc{1};
5228   let Inst{12-10} = Pg;
5229   let Inst{9-5}   = Zn;
5230   let Inst{4}     = opc{0};
5231   let Inst{3-0}   = Pd;
5233   let Defs = [NZCV];
5234   let ElementSize = pprty.ElementSize;
5235   let hasSideEffects = 0;
5236   let isPTestLike = 1;
5239 multiclass SVE_SETCC_Imm_Pat<CondCode cc, CondCode commuted_cc,
5240                              ValueType predvt, ValueType intvt,
5241                              Operand immtype, Instruction cmp> {
5242   def : Pat<(predvt (AArch64setcc_z (predvt PPR_3b:$Pg),
5243                                     (intvt ZPR:$Zs1),
5244                                     (intvt (splat_vector (immtype:$imm))),
5245                                     cc)),
5246             (cmp $Pg, $Zs1, immtype:$imm)>;
5247   def : Pat<(predvt (AArch64setcc_z (predvt PPR_3b:$Pg),
5248                                     (intvt (splat_vector (immtype:$imm))),
5249                                     (intvt ZPR:$Zs1),
5250                                     commuted_cc)),
5251             (cmp $Pg, $Zs1, immtype:$imm)>;
5252   def : Pat<(predvt (and predvt:$Pg,
5253                          (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)),
5254                                          (intvt ZPR:$Zs1),
5255                                          (intvt (splat_vector (immtype:$imm))),
5256                                          cc))),
5257             (cmp $Pg, $Zs1, immtype:$imm)>;
5258   def : Pat<(predvt (and predvt:$Pg,
5259                          (AArch64setcc_z_oneuse (predvt (AArch64ptrue 31)),
5260                                          (intvt (splat_vector (immtype:$imm))),
5261                                          (intvt ZPR:$Zs1),
5262                                          commuted_cc))),
5263             (cmp $Pg, $Zs1, immtype:$imm)>;
5266 multiclass sve_int_scmp_vi<bits<3> opc, string asm, CondCode cc, CondCode commuted_cc> {
5267   def _B : sve_int_scmp_vi<0b00, opc, asm, PPR8, ZPR8, simm5_32b>;
5268   def _H : sve_int_scmp_vi<0b01, opc, asm, PPR16, ZPR16, simm5_32b>;
5269   def _S : sve_int_scmp_vi<0b10, opc, asm, PPR32, ZPR32, simm5_32b>;
5270   def _D : sve_int_scmp_vi<0b11, opc, asm, PPR64, ZPR64, simm5_64b>;
5272   defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv16i1, nxv16i8, simm5_32b,
5273                            !cast<Instruction>(NAME # _B)>;
5274   defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv8i1,  nxv8i16, simm5_32b,
5275                            !cast<Instruction>(NAME # _H)>;
5276   defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv4i1,  nxv4i32, simm5_32b,
5277                            !cast<Instruction>(NAME # _S)>;
5278   defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv2i1,  nxv2i64, simm5_64b,
5279                            !cast<Instruction>(NAME # _D)>;
5283 //===----------------------------------------------------------------------===//
5284 // SVE Integer Compare - Unsigned Immediate Group
5285 //===----------------------------------------------------------------------===//
5287 class sve_int_ucmp_vi<bits<2> sz8_64, bits<2> opc, string asm, PPRRegOp pprty,
5288                       ZPRRegOp zprty, Operand immtype>
5289 : I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, immtype:$imm7),
5290   asm, "\t$Pd, $Pg/z, $Zn, $imm7",
5291   "",
5292   []>, Sched<[]> {
5293   bits<4> Pd;
5294   bits<3> Pg;
5295   bits<5> Zn;
5296   bits<7> imm7;
5297   let Inst{31-24} = 0b00100100;
5298   let Inst{23-22} = sz8_64;
5299   let Inst{21}    = 1;
5300   let Inst{20-14} = imm7;
5301   let Inst{13}    = opc{1};
5302   let Inst{12-10} = Pg;
5303   let Inst{9-5}   = Zn;
5304   let Inst{4}     = opc{0};
5305   let Inst{3-0}   = Pd;
5307   let Defs = [NZCV];
5308   let ElementSize = pprty.ElementSize;
5309   let hasSideEffects = 0;
5310   let isPTestLike = 1;
5313 multiclass sve_int_ucmp_vi<bits<2> opc, string asm, CondCode cc,
5314                            CondCode commuted_cc> {
5315   def _B : sve_int_ucmp_vi<0b00, opc, asm, PPR8, ZPR8, imm0_127>;
5316   def _H : sve_int_ucmp_vi<0b01, opc, asm, PPR16, ZPR16, imm0_127>;
5317   def _S : sve_int_ucmp_vi<0b10, opc, asm, PPR32, ZPR32, imm0_127>;
5318   def _D : sve_int_ucmp_vi<0b11, opc, asm, PPR64, ZPR64, imm0_127_64b>;
5320   defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv16i1, nxv16i8, imm0_127,
5321                            !cast<Instruction>(NAME # _B)>;
5322   defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv8i1,  nxv8i16, imm0_127,
5323                            !cast<Instruction>(NAME # _H)>;
5324   defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv4i1,  nxv4i32, imm0_127,
5325                            !cast<Instruction>(NAME # _S)>;
5326   defm : SVE_SETCC_Imm_Pat<cc, commuted_cc, nxv2i1,  nxv2i64, imm0_127_64b,
5327                            !cast<Instruction>(NAME # _D)>;
5331 //===----------------------------------------------------------------------===//
5332 // SVE Integer Compare - Scalars Group
5333 //===----------------------------------------------------------------------===//
5335 class sve_int_cterm<bit sz, bit opc, string asm, RegisterClass rt>
5336 : I<(outs), (ins rt:$Rn, rt:$Rm),
5337   asm, "\t$Rn, $Rm",
5338   "",
5339   []>, Sched<[]> {
5340   bits<5> Rm;
5341   bits<5> Rn;
5342   let Inst{31-23} = 0b001001011;
5343   let Inst{22}    = sz;
5344   let Inst{21}    = 0b1;
5345   let Inst{20-16} = Rm;
5346   let Inst{15-10} = 0b001000;
5347   let Inst{9-5}   = Rn;
5348   let Inst{4}     = opc;
5349   let Inst{3-0}   = 0b0000;
5351   let Defs = [NZCV];
5352   let hasSideEffects = 0;
5355 class sve_int_while_rr<bits<2> sz8_64, bits<4> opc, string asm,
5356                        RegisterClass gprty, PPRRegOp pprty>
5357 : I<(outs pprty:$Pd), (ins gprty:$Rn, gprty:$Rm),
5358   asm, "\t$Pd, $Rn, $Rm",
5359   "", []>, Sched<[]> {
5360   bits<4> Pd;
5361   bits<5> Rm;
5362   bits<5> Rn;
5363   let Inst{31-24} = 0b00100101;
5364   let Inst{23-22} = sz8_64;
5365   let Inst{21}    = 0b1;
5366   let Inst{20-16} = Rm;
5367   let Inst{15-13} = 0b000;
5368   let Inst{12-10} = opc{3-1};
5369   let Inst{9-5}   = Rn;
5370   let Inst{4}     = opc{0};
5371   let Inst{3-0}   = Pd;
5373   let Defs = [NZCV];
5374   let ElementSize = pprty.ElementSize;
5375   let hasSideEffects = 0;
5376   let isWhile = 1;
5379 multiclass sve_int_while4_rr<bits<3> opc, string asm, SDPatternOperator op> {
5380   def _B : sve_int_while_rr<0b00, { 0, opc }, asm, GPR32, PPR8>;
5381   def _H : sve_int_while_rr<0b01, { 0, opc }, asm, GPR32, PPR16>;
5382   def _S : sve_int_while_rr<0b10, { 0, opc }, asm, GPR32, PPR32>;
5383   def _D : sve_int_while_rr<0b11, { 0, opc }, asm, GPR32, PPR64>;
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)>;
5391 multiclass sve_int_while8_rr<bits<3> opc, string asm, SDPatternOperator op> {
5392   def _B : sve_int_while_rr<0b00, { 1, opc }, asm, GPR64, PPR8>;
5393   def _H : sve_int_while_rr<0b01, { 1, opc }, asm, GPR64, PPR16>;
5394   def _S : sve_int_while_rr<0b10, { 1, opc }, asm, GPR64, PPR32>;
5395   def _D : sve_int_while_rr<0b11, { 1, opc }, asm, GPR64, PPR64>;
5397   def : SVE_2_Op_Pat<nxv16i1, op, i64, i64, !cast<Instruction>(NAME # _B)>;
5398   def : SVE_2_Op_Pat<nxv8i1,  op, i64, i64, !cast<Instruction>(NAME # _H)>;
5399   def : SVE_2_Op_Pat<nxv4i1,  op, i64, i64, !cast<Instruction>(NAME # _S)>;
5400   def : SVE_2_Op_Pat<nxv2i1,  op, i64, i64, !cast<Instruction>(NAME # _D)>;
5403 class sve2_int_while_rr<bits<2> sz8_64, bits<1> rw, string asm,
5404                         PPRRegOp pprty>
5405 : I<(outs pprty:$Pd), (ins GPR64:$Rn, GPR64:$Rm),
5406   asm, "\t$Pd, $Rn, $Rm",
5407   "", []>, Sched<[]> {
5408   bits<4> Pd;
5409   bits<5> Rm;
5410   bits<5> Rn;
5411   let Inst{31-24} = 0b00100101;
5412   let Inst{23-22} = sz8_64;
5413   let Inst{21}    = 0b1;
5414   let Inst{20-16} = Rm;
5415   let Inst{15-10} = 0b001100;
5416   let Inst{9-5}   = Rn;
5417   let Inst{4}     = rw;
5418   let Inst{3-0}   = Pd;
5420   let Defs = [NZCV];
5421   let ElementSize = pprty.ElementSize;
5422   let hasSideEffects = 0;
5423   let isWhile = 1;
5426 multiclass sve2_int_while_rr<bits<1> rw, string asm, string op> {
5427   def _B : sve2_int_while_rr<0b00, rw, asm, PPR8>;
5428   def _H : sve2_int_while_rr<0b01, rw, asm, PPR16>;
5429   def _S : sve2_int_while_rr<0b10, rw, asm, PPR32>;
5430   def _D : sve2_int_while_rr<0b11, rw, asm, PPR64>;
5432   def : SVE_2_Op_Pat<nxv16i1, !cast<SDPatternOperator>(op # _b), i64, i64, !cast<Instruction>(NAME # _B)>;
5433   def : SVE_2_Op_Pat<nxv8i1,  !cast<SDPatternOperator>(op # _h), i64, i64, !cast<Instruction>(NAME # _H)>;
5434   def : SVE_2_Op_Pat<nxv4i1,  !cast<SDPatternOperator>(op # _s), i64, i64, !cast<Instruction>(NAME # _S)>;
5435   def : SVE_2_Op_Pat<nxv2i1,  !cast<SDPatternOperator>(op # _d), i64, i64, !cast<Instruction>(NAME # _D)>;
5438 //===----------------------------------------------------------------------===//
5439 // SVE Floating Point Fast Reduction Group
5440 //===----------------------------------------------------------------------===//
5442 class sve_fp_fast_red<bits<2> sz, bits<3> opc, string asm,
5443                       ZPRRegOp zprty, FPRasZPROperand dstOpType>
5444 : I<(outs dstOpType:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
5445   asm, "\t$Vd, $Pg, $Zn",
5446   "",
5447   []>, Sched<[]> {
5448   bits<5> Zn;
5449   bits<5> Vd;
5450   bits<3> Pg;
5451   let Inst{31-24} = 0b01100101;
5452   let Inst{23-22} = sz;
5453   let Inst{21-19} = 0b000;
5454   let Inst{18-16} = opc;
5455   let Inst{15-13} = 0b001;
5456   let Inst{12-10} = Pg;
5457   let Inst{9-5}   = Zn;
5458   let Inst{4-0}   = Vd;
5460   let hasSideEffects = 0;
5461   let mayRaiseFPException = 1;
5464 multiclass sve_fp_fast_red<bits<3> opc, string asm, SDPatternOperator op> {
5465   def _H : sve_fp_fast_red<0b01, opc, asm, ZPR16, FPR16asZPR>;
5466   def _S : sve_fp_fast_red<0b10, opc, asm, ZPR32, FPR32asZPR>;
5467   def _D : sve_fp_fast_red<0b11, opc, asm, ZPR64, FPR64asZPR>;
5469   def : SVE_2_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, !cast<Instruction>(NAME # _H)>;
5470   def : SVE_2_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, !cast<Instruction>(NAME # _H)>;
5471   def : SVE_2_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
5472   def : SVE_2_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, !cast<Instruction>(NAME # _S)>;
5473   def : SVE_2_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
5474   def : SVE_2_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
5477 //===----------------------------------------------------------------------===//
5478 // SVE Floating Point Accumulating Reduction Group
5479 //===----------------------------------------------------------------------===//
5481 class sve_fp_2op_p_vd<bits<2> sz, bits<3> opc, string asm,
5482                       ZPRRegOp zprty, FPRasZPROperand dstOpType>
5483 : I<(outs dstOpType:$Vdn), (ins PPR3bAny:$Pg, dstOpType:$_Vdn, zprty:$Zm),
5484   asm, "\t$Vdn, $Pg, $_Vdn, $Zm",
5485   "",
5486   []>,
5487   Sched<[]> {
5488   bits<3> Pg;
5489   bits<5> Vdn;
5490   bits<5> Zm;
5491   let Inst{31-24} = 0b01100101;
5492   let Inst{23-22} = sz;
5493   let Inst{21-19} = 0b011;
5494   let Inst{18-16} = opc;
5495   let Inst{15-13} = 0b001;
5496   let Inst{12-10} = Pg;
5497   let Inst{9-5}   = Zm;
5498   let Inst{4-0}   = Vdn;
5500   let Constraints = "$Vdn = $_Vdn";
5501   let hasSideEffects = 0;
5502   let mayRaiseFPException = 1;
5505 multiclass sve_fp_2op_p_vd<bits<3> opc, string asm, SDPatternOperator op> {
5506   def _H : sve_fp_2op_p_vd<0b01, opc, asm, ZPR16, FPR16asZPR>;
5507   def _S : sve_fp_2op_p_vd<0b10, opc, asm, ZPR32, FPR32asZPR>;
5508   def _D : sve_fp_2op_p_vd<0b11, opc, asm, ZPR64, FPR64asZPR>;
5510   def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H)>;
5511   def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H)>;
5512   def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
5513   def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S)>;
5514   def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
5515   def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
5518 //===----------------------------------------------------------------------===//
5519 // SVE Floating Point Compare - Vectors Group
5520 //===----------------------------------------------------------------------===//
5522 class sve_fp_3op_p_pd<bits<2> sz, bits<3> opc, string asm, PPRRegOp pprty,
5523                       ZPRRegOp zprty>
5524 : I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
5525   asm, "\t$Pd, $Pg/z, $Zn, $Zm",
5526   "",
5527   []>, Sched<[]> {
5528   bits<4> Pd;
5529   bits<3> Pg;
5530   bits<5> Zm;
5531   bits<5> Zn;
5532   let Inst{31-24} = 0b01100101;
5533   let Inst{23-22} = sz;
5534   let Inst{21}    = 0b0;
5535   let Inst{20-16} = Zm;
5536   let Inst{15}    = opc{2};
5537   let Inst{14}    = 0b1;
5538   let Inst{13}    = opc{1};
5539   let Inst{12-10} = Pg;
5540   let Inst{9-5}   = Zn;
5541   let Inst{4}     = opc{0};
5542   let Inst{3-0}   = Pd;
5544   let hasSideEffects = 0;
5545   let mayRaiseFPException = 1;
5548 multiclass sve_fp_3op_p_pd<bits<3> opc, string asm, SDPatternOperator op> {
5549   def _H : sve_fp_3op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5550   def _S : sve_fp_3op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5551   def _D : sve_fp_3op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5553   def : SVE_3_Op_Pat<nxv8i1, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
5554   def : SVE_3_Op_Pat<nxv4i1, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
5555   def : SVE_3_Op_Pat<nxv2i1, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
5558 multiclass sve_fp_3op_p_pd_cc<bits<3> opc, string asm,
5559                               CondCode cc1, CondCode cc2,
5560                               CondCode invcc1, CondCode invcc2> {
5561   def _H : sve_fp_3op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5562   def _S : sve_fp_3op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5563   def _D : sve_fp_3op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5565   defm : SVE_SETCC_Pat<cc1, invcc1, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5566   defm : SVE_SETCC_Pat<cc1, invcc1, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5567   defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5568   defm : SVE_SETCC_Pat<cc1, invcc1, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5569   defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5570   defm : SVE_SETCC_Pat<cc1, invcc1, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5572   defm : SVE_SETCC_Pat<cc2, invcc2, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5573   defm : SVE_SETCC_Pat<cc2, invcc2, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5574   defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5575   defm : SVE_SETCC_Pat<cc2, invcc2, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5576   defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5577   defm : SVE_SETCC_Pat<cc2, invcc2, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5580 //===----------------------------------------------------------------------===//
5581 // SVE Floating Point Compare - with Zero Group
5582 //===----------------------------------------------------------------------===//
5584 class sve_fp_2op_p_pd<bits<2> sz, bits<3> opc, string asm, PPRRegOp pprty,
5585                       ZPRRegOp zprty>
5586 : I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn),
5587   asm, "\t$Pd, $Pg/z, $Zn, #0.0",
5588   "",
5589   []>, Sched<[]> {
5590   bits<4> Pd;
5591   bits<3> Pg;
5592   bits<5> Zn;
5593   let Inst{31-24} = 0b01100101;
5594   let Inst{23-22} = sz;
5595   let Inst{21-18} = 0b0100;
5596   let Inst{17-16} = opc{2-1};
5597   let Inst{15-13} = 0b001;
5598   let Inst{12-10} = Pg;
5599   let Inst{9-5}   = Zn;
5600   let Inst{4}     = opc{0};
5601   let Inst{3-0}   = Pd;
5603   let hasSideEffects = 0;
5604   let mayRaiseFPException = 1;
5607 multiclass sve_fp_2op_p_pd<bits<3> opc, string asm,
5608                            CondCode cc1, CondCode cc2,
5609                            CondCode invcc1, CondCode invcc2> {
5610   def _H : sve_fp_2op_p_pd<0b01, opc, asm, PPR16, ZPR16>;
5611   def _S : sve_fp_2op_p_pd<0b10, opc, asm, PPR32, ZPR32>;
5612   def _D : sve_fp_2op_p_pd<0b11, opc, asm, PPR64, ZPR64>;
5614   defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5615   defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5616   defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5617   defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5618   defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5619   defm : SVE_SETCC_Pat_With_Zero<cc1, invcc1, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5621   defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
5622   defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv4i1,  nxv4f16, !cast<Instruction>(NAME # _H)>;
5623   defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f16, !cast<Instruction>(NAME # _H)>;
5624   defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
5625   defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
5626   defm : SVE_SETCC_Pat_With_Zero<cc2, invcc2, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
5630 //===----------------------------------------------------------------------===//
5631 //SVE Index Generation Group
5632 //===----------------------------------------------------------------------===//
5634 def simm5_8b_tgt : TImmLeaf<i8, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]>;
5635 def simm5_16b_tgt : TImmLeaf<i16, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]>;
5636 def simm5_32b_tgt : TImmLeaf<i32, [{ return (int32_t)Imm >= -16 && (int32_t)Imm < 16; }]>;
5637 def simm5_64b_tgt : TImmLeaf<i64, [{ return (int64_t)Imm >= -16 && (int64_t)Imm < 16; }]>;
5638 def i64imm_32bit_tgt : TImmLeaf<i64, [{
5639   return (Imm & 0xffffffffULL) == static_cast<uint64_t>(Imm);
5640 }]>;
5642 class sve_int_index_ii<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5643                        Operand imm_ty>
5644 : I<(outs zprty:$Zd), (ins imm_ty:$imm5, imm_ty:$imm5b),
5645   asm, "\t$Zd, $imm5, $imm5b",
5646   "", []>, Sched<[]> {
5647   bits<5> Zd;
5648   bits<5> imm5;
5649   bits<5> imm5b;
5650   let Inst{31-24} = 0b00000100;
5651   let Inst{23-22} = sz8_64;
5652   let Inst{21}    = 0b1;
5653   let Inst{20-16} = imm5b;
5654   let Inst{15-10} = 0b010000;
5655   let Inst{9-5}   = imm5;
5656   let Inst{4-0}   = Zd;
5658   let hasSideEffects = 0;
5659   let isReMaterializable = 1;
5662 multiclass sve_int_index_ii<string asm> {
5663   def _B : sve_int_index_ii<0b00, asm, ZPR8, simm5_8b>;
5664   def _H : sve_int_index_ii<0b01, asm, ZPR16, simm5_16b>;
5665   def _S : sve_int_index_ii<0b10, asm, ZPR32, simm5_32b>;
5666   def _D : sve_int_index_ii<0b11, asm, ZPR64, simm5_64b>;
5668   def : Pat<(nxv16i8 (step_vector simm5_8b_tgt:$imm5b)),
5669             (!cast<Instruction>(NAME # "_B") (i32 0), (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5670   def : Pat<(nxv8i16 (step_vector simm5_16b_tgt:$imm5b)),
5671             (!cast<Instruction>(NAME # "_H") (i32 0), (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5672   def : Pat<(nxv4i32 (step_vector simm5_32b_tgt:$imm5b)),
5673             (!cast<Instruction>(NAME # "_S") (i32 0), simm5_32b:$imm5b)>;
5674   def : Pat<(nxv2i64 (step_vector simm5_64b_tgt:$imm5b)),
5675             (!cast<Instruction>(NAME # "_D") (i64 0), simm5_64b:$imm5b)>;
5677   // add(step_vector(step), dup(X)) -> index(X, step).
5678   def : Pat<(add (nxv16i8 (step_vector_oneuse simm5_8b_tgt:$imm5b)), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
5679             (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5680   def : Pat<(add (nxv8i16 (step_vector_oneuse simm5_16b_tgt:$imm5b)), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
5681             (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, (!cast<SDNodeXForm>("trunc_imm") $imm5b))>;
5682   def : Pat<(add (nxv4i32 (step_vector_oneuse simm5_32b_tgt:$imm5b)), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
5683             (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, simm5_32b:$imm5b)>;
5684   def : Pat<(add (nxv2i64 (step_vector_oneuse simm5_64b_tgt:$imm5b)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5685             (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, simm5_64b:$imm5b)>;
5688 class sve_int_index_ir<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5689                        RegisterClass srcRegType, Operand imm_ty>
5690 : I<(outs zprty:$Zd), (ins imm_ty:$imm5, srcRegType:$Rm),
5691   asm, "\t$Zd, $imm5, $Rm",
5692   "", []>, Sched<[]> {
5693   bits<5> Rm;
5694   bits<5> Zd;
5695   bits<5> imm5;
5696   let Inst{31-24} = 0b00000100;
5697   let Inst{23-22} = sz8_64;
5698   let Inst{21}    = 0b1;
5699   let Inst{20-16} = Rm;
5700   let Inst{15-10} = 0b010010;
5701   let Inst{9-5}   = imm5;
5702   let Inst{4-0}   = Zd;
5704   let hasSideEffects = 0;
5707 multiclass sve_int_index_ir<string asm, SDPatternOperator mulop, SDPatternOperator muloneuseop> {
5708   def _B : sve_int_index_ir<0b00, asm, ZPR8, GPR32, simm5_8b>;
5709   def _H : sve_int_index_ir<0b01, asm, ZPR16, GPR32, simm5_16b>;
5710   def _S : sve_int_index_ir<0b10, asm, ZPR32, GPR32, simm5_32b>;
5711   def _D : sve_int_index_ir<0b11, asm, ZPR64, GPR64, simm5_64b>;
5713   def : Pat<(nxv16i8 (step_vector i8:$imm)),
5714             (!cast<Instruction>(NAME # "_B") (i32 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5715   def : Pat<(nxv8i16 (step_vector i16:$imm)),
5716             (!cast<Instruction>(NAME # "_H") (i32 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5717   def : Pat<(nxv4i32 (step_vector i32:$imm)),
5718             (!cast<Instruction>(NAME # "_S") (i32 0), (!cast<Instruction>("MOVi32imm") $imm))>;
5719   def : Pat<(nxv2i64 (step_vector i64:$imm)),
5720             (!cast<Instruction>(NAME # "_D") (i64 0), (!cast<Instruction>("MOVi64imm") $imm))>;
5721   def : Pat<(nxv2i64 (step_vector i64imm_32bit_tgt:$imm)),
5722             (!cast<Instruction>(NAME # "_D") (i64 0), (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5724   // add(step_vector(step), dup(X)) -> index(X, step).
5725   def : Pat<(add (nxv16i8 (step_vector_oneuse i8:$imm)), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
5726             (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5727   def : Pat<(add (nxv8i16 (step_vector_oneuse i16:$imm)), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
5728             (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5729   def : Pat<(add (nxv4i32 (step_vector_oneuse i32:$imm)), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
5730             (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, (!cast<Instruction>("MOVi32imm") $imm))>;
5731   def : Pat<(add (nxv2i64 (step_vector_oneuse i64:$imm)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5732             (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, (!cast<Instruction>("MOVi64imm") $imm))>;
5733   def : Pat<(add (nxv2i64 (step_vector_oneuse i64imm_32bit_tgt:$imm)), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5734             (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5736   // mul(step_vector(1), dup(Y)) -> index(0, Y).
5737   def : Pat<(mulop (nxv16i1 (AArch64ptrue 31)), (nxv16i8 (step_vector_oneuse (i8 1))), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))),
5738             (!cast<Instruction>(NAME # "_B") (i32 0), GPR32:$Rm)>;
5739   def : Pat<(mulop (nxv8i1 (AArch64ptrue 31)), (nxv8i16 (step_vector_oneuse (i16 1))), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),
5740             (!cast<Instruction>(NAME # "_H") (i32 0), GPR32:$Rm)>;
5741   def : Pat<(mulop (nxv4i1 (AArch64ptrue 31)), (nxv4i32 (step_vector_oneuse (i32 1))), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),
5742             (!cast<Instruction>(NAME # "_S") (i32 0), GPR32:$Rm)>;
5743   def : Pat<(mulop (nxv2i1 (AArch64ptrue 31)), (nxv2i64 (step_vector_oneuse (i64 1))), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),
5744             (!cast<Instruction>(NAME # "_D") (i64 0), GPR64:$Rm)>;
5746   // add(mul(step_vector(1), dup(Y)), dup(X)) -> index(X, Y).
5747   def : Pat<(add (muloneuseop (nxv16i1 (AArch64ptrue 31)), (nxv16i8 (step_vector_oneuse (i8 1))), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))), (nxv16i8 (splat_vector(simm5_8b:$imm5)))),
5748             (!cast<Instruction>(NAME # "_B") simm5_8b:$imm5, GPR32:$Rm)>;
5749   def : Pat<(add (muloneuseop (nxv8i1 (AArch64ptrue 31)), (nxv8i16 (step_vector_oneuse (i16 1))), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))), (nxv8i16 (splat_vector(simm5_16b:$imm5)))),
5750             (!cast<Instruction>(NAME # "_H") simm5_16b:$imm5, GPR32:$Rm)>;
5751   def : Pat<(add (muloneuseop (nxv4i1 (AArch64ptrue 31)), (nxv4i32 (step_vector_oneuse (i32 1))), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))), (nxv4i32 (splat_vector(simm5_32b:$imm5)))),
5752             (!cast<Instruction>(NAME # "_S") simm5_32b:$imm5, GPR32:$Rm)>;
5753   def : Pat<(add (muloneuseop (nxv2i1 (AArch64ptrue 31)), (nxv2i64 (step_vector_oneuse (i64 1))), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))), (nxv2i64 (splat_vector(simm5_64b:$imm5)))),
5754             (!cast<Instruction>(NAME # "_D") simm5_64b:$imm5, GPR64:$Rm)>;
5757 class sve_int_index_ri<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5758                        RegisterClass srcRegType, Operand imm_ty>
5759 : I<(outs zprty:$Zd), (ins srcRegType:$Rn, imm_ty:$imm5),
5760   asm, "\t$Zd, $Rn, $imm5",
5761   "", []>, Sched<[]> {
5762   bits<5> Rn;
5763   bits<5> Zd;
5764   bits<5> imm5;
5765   let Inst{31-24} = 0b00000100;
5766   let Inst{23-22} = sz8_64;
5767   let Inst{21}    = 0b1;
5768   let Inst{20-16} = imm5;
5769   let Inst{15-10} = 0b010001;
5770   let Inst{9-5}   = Rn;
5771   let Inst{4-0}   = Zd;
5773   let hasSideEffects = 0;
5776 multiclass sve_int_index_ri<string asm> {
5777   def _B : sve_int_index_ri<0b00, asm, ZPR8, GPR32, simm5_8b>;
5778   def _H : sve_int_index_ri<0b01, asm, ZPR16, GPR32, simm5_16b>;
5779   def _S : sve_int_index_ri<0b10, asm, ZPR32, GPR32, simm5_32b>;
5780   def _D : sve_int_index_ri<0b11, asm, ZPR64, GPR64, simm5_64b>;
5782   // add(step_vector(step), dup(X)) -> index(X, step).
5783   def : Pat<(add (nxv16i8 (step_vector_oneuse simm5_8b_tgt:$imm5)), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))),
5784             (!cast<Instruction>(NAME # "_B") GPR32:$Rm, (!cast<SDNodeXForm>("trunc_imm") $imm5))>;
5785   def : Pat<(add (nxv8i16 (step_vector_oneuse simm5_16b_tgt:$imm5)), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),
5786             (!cast<Instruction>(NAME # "_H") GPR32:$Rm, (!cast<SDNodeXForm>("trunc_imm") $imm5))>;
5787   def : Pat<(add (nxv4i32 (step_vector_oneuse simm5_32b_tgt:$imm5)), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),
5788             (!cast<Instruction>(NAME # "_S") GPR32:$Rm, simm5_32b:$imm5)>;
5789   def : Pat<(add (nxv2i64 (step_vector_oneuse simm5_64b_tgt:$imm5)), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),
5790             (!cast<Instruction>(NAME # "_D") GPR64:$Rm, simm5_64b:$imm5)>;
5793 class sve_int_index_rr<bits<2> sz8_64, string asm, ZPRRegOp zprty,
5794                        RegisterClass srcRegType>
5795 : I<(outs zprty:$Zd), (ins srcRegType:$Rn, srcRegType:$Rm),
5796   asm, "\t$Zd, $Rn, $Rm",
5797   "", []>, Sched<[]> {
5798   bits<5> Zd;
5799   bits<5> Rm;
5800   bits<5> Rn;
5801   let Inst{31-24} = 0b00000100;
5802   let Inst{23-22} = sz8_64;
5803   let Inst{21}    = 0b1;
5804   let Inst{20-16} = Rm;
5805   let Inst{15-10} = 0b010011;
5806   let Inst{9-5}   = Rn;
5807   let Inst{4-0}   = Zd;
5809   let hasSideEffects = 0;
5812 multiclass sve_int_index_rr<string asm, SDPatternOperator mulop> {
5813   def _B : sve_int_index_rr<0b00, asm, ZPR8, GPR32>;
5814   def _H : sve_int_index_rr<0b01, asm, ZPR16, GPR32>;
5815   def _S : sve_int_index_rr<0b10, asm, ZPR32, GPR32>;
5816   def _D : sve_int_index_rr<0b11, asm, ZPR64, GPR64>;
5818   // add(step_vector(step), dup(X)) -> index(X, step).
5819   def : Pat<(add (nxv16i8 (step_vector_oneuse i8:$imm)), (nxv16i8 (splat_vector(i32 GPR32:$Rn)))),
5820             (!cast<Instruction>(NAME # "_B") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5821   def : Pat<(add (nxv8i16 (step_vector_oneuse i16:$imm)), (nxv8i16 (splat_vector(i32 GPR32:$Rn)))),
5822             (!cast<Instruction>(NAME # "_H") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)))>;
5823   def : Pat<(add (nxv4i32 (step_vector_oneuse i32:$imm)), (nxv4i32 (splat_vector(i32 GPR32:$Rn)))),
5824             (!cast<Instruction>(NAME # "_S") GPR32:$Rn, (!cast<Instruction>("MOVi32imm") $imm))>;
5825   def : Pat<(add (nxv2i64 (step_vector_oneuse i64:$imm)), (nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
5826             (!cast<Instruction>(NAME # "_D") GPR64:$Rn, (!cast<Instruction>("MOVi64imm") $imm))>;
5827   def : Pat<(add (nxv2i64 (step_vector_oneuse i64imm_32bit_tgt:$imm)), (nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
5828             (!cast<Instruction>(NAME # "_D") GPR64:$Rn, (SUBREG_TO_REG (i64 0), (!cast<Instruction>("MOVi32imm") (!cast<SDNodeXForm>("trunc_imm") $imm)), sub_32))>;
5830   // add(mul(step_vector(1), dup(Y)), dup(X)) -> index(X, Y).
5831   def : Pat<(add (mulop (nxv16i1 (AArch64ptrue 31)), (nxv16i8 (step_vector_oneuse (i8 1))), (nxv16i8 (splat_vector(i32 GPR32:$Rm)))), (nxv16i8 (splat_vector(i32 GPR32:$Rn)))),
5832             (!cast<Instruction>(NAME # "_B") GPR32:$Rn, GPR32:$Rm)>;
5833   def : Pat<(add (mulop (nxv8i1 (AArch64ptrue 31)), (nxv8i16 (step_vector_oneuse (i16 1))), (nxv8i16 (splat_vector(i32 GPR32:$Rm)))),(nxv8i16 (splat_vector(i32 GPR32:$Rn)))),
5834             (!cast<Instruction>(NAME # "_H") GPR32:$Rn, GPR32:$Rm)>;
5835   def : Pat<(add (mulop (nxv4i1 (AArch64ptrue 31)), (nxv4i32 (step_vector_oneuse (i32 1))), (nxv4i32 (splat_vector(i32 GPR32:$Rm)))),(nxv4i32 (splat_vector(i32 GPR32:$Rn)))),
5836             (!cast<Instruction>(NAME # "_S") GPR32:$Rn, GPR32:$Rm)>;
5837   def : Pat<(add (mulop (nxv2i1 (AArch64ptrue 31)), (nxv2i64 (step_vector_oneuse (i64 1))), (nxv2i64 (splat_vector(i64 GPR64:$Rm)))),(nxv2i64 (splat_vector(i64 GPR64:$Rn)))),
5838             (!cast<Instruction>(NAME # "_D") GPR64:$Rn, GPR64:$Rm)>;
5841 //===----------------------------------------------------------------------===//
5842 // SVE Bitwise Shift - Predicated Group
5843 //===----------------------------------------------------------------------===//
5845 class sve_int_bin_pred_shift_imm<bits<4> tsz8_64, bits<4> opc, string asm,
5846                                  ZPRRegOp zprty, Operand immtype>
5847 : I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, immtype:$imm),
5848   asm, "\t$Zdn, $Pg/m, $_Zdn, $imm",
5849   "",
5850   []>, Sched<[]> {
5851   bits<3> Pg;
5852   bits<5> Zdn;
5853   bits<6> imm;
5854   let Inst{31-24} = 0b00000100;
5855   let Inst{23-22} = tsz8_64{3-2};
5856   let Inst{21-20} = 0b00;
5857   let Inst{19-16} = opc;
5858   let Inst{15-13} = 0b100;
5859   let Inst{12-10} = Pg;
5860   let Inst{9-8}   = tsz8_64{1-0};
5861   let Inst{7-5}   = imm{2-0}; // imm3
5862   let Inst{4-0}   = Zdn;
5864   let Constraints = "$Zdn = $_Zdn";
5865   let DestructiveInstType = DestructiveBinaryImm;
5866   let ElementSize = zprty.ElementSize;
5867   let hasSideEffects = 0;
5870 multiclass sve_int_bin_pred_shift_imm_left<bits<4> opc, string asm, string Ps,
5871                                            SDPatternOperator op = null_frag> {
5872   def _B : SVEPseudo2Instr<Ps # _B, 1>,
5873            sve_int_bin_pred_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
5874   def _H : SVEPseudo2Instr<Ps # _H, 1>,
5875            sve_int_bin_pred_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
5876     let Inst{8} = imm{3};
5877   }
5878   def _S : SVEPseudo2Instr<Ps # _S, 1>,
5879            sve_int_bin_pred_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
5880     let Inst{9-8} = imm{4-3};
5881   }
5882   def _D : SVEPseudo2Instr<Ps # _D, 1>,
5883            sve_int_bin_pred_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
5884     let Inst{22}  = imm{5};
5885     let Inst{9-8} = imm{4-3};
5886   }
5888   def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i1, nxv16i8, i32, tvecshiftL8,  !cast<Instruction>(NAME # _B)>;
5889   def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i1,  nxv8i16, i32, tvecshiftL16, !cast<Instruction>(NAME # _H)>;
5890   def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i1,  nxv4i32, i32, tvecshiftL32, !cast<Instruction>(NAME # _S)>;
5891   def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i1,  nxv2i64, i32, tvecshiftL64, !cast<Instruction>(NAME # _D)>;
5894 // As above but shift amount takes the form of a "vector immediate".
5895 multiclass sve_int_bin_pred_shift_imm_left_dup<bits<4> opc, string asm,
5896                                                string Ps, SDPatternOperator op>
5897 : sve_int_bin_pred_shift_imm_left<opc, asm, Ps, null_frag> {
5898   def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8,  !cast<Instruction>(NAME # _B)>;
5899   def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
5900   def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
5901   def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
5904 multiclass sve_int_bin_pred_shift_imm_left_zeroing_bhsd<SDPatternOperator op> {
5905   def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8,  tvecshiftL8,  FalseLanesZero>;
5906   def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, tvecshiftL16, FalseLanesZero>;
5907   def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, tvecshiftL32, FalseLanesZero>;
5908   def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, tvecshiftL64, FalseLanesZero>;
5910   def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv16i8, op, nxv16i1, nxv16i8, tvecshiftL8,  !cast<Pseudo>(NAME # _B_ZERO)>;
5911   def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv8i16, op, nxv8i1,  nxv8i16, tvecshiftL16, !cast<Pseudo>(NAME # _H_ZERO)>;
5912   def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv4i32, op, nxv4i1,  nxv4i32, tvecshiftL32, !cast<Pseudo>(NAME # _S_ZERO)>;
5913   def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv2i64, op, nxv2i1,  nxv2i64, tvecshiftL64, !cast<Pseudo>(NAME # _D_ZERO)>;
5916 multiclass sve_int_bin_pred_shift_imm_right<bits<4> opc, string asm, string Ps,
5917                                             SDPatternOperator op = null_frag> {
5918   def _B : SVEPseudo2Instr<Ps # _B, 1>,
5919            sve_int_bin_pred_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
5920   def _H : SVEPseudo2Instr<Ps # _H, 1>,
5921            sve_int_bin_pred_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
5922     let Inst{8} = imm{3};
5923   }
5924   def _S : SVEPseudo2Instr<Ps # _S, 1>,
5925            sve_int_bin_pred_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
5926     let Inst{9-8} = imm{4-3};
5927   }
5928   def _D : SVEPseudo2Instr<Ps # _D, 1>,
5929            sve_int_bin_pred_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
5930     let Inst{22}  = imm{5};
5931     let Inst{9-8} = imm{4-3};
5932   }
5934   def : SVE_3_Op_Imm_Pat<nxv16i8, op, nxv16i1, nxv16i8, i32, tvecshiftR8,  !cast<Instruction>(NAME # _B)>;
5935   def : SVE_3_Op_Imm_Pat<nxv8i16, op, nxv8i1,  nxv8i16, i32, tvecshiftR16, !cast<Instruction>(NAME # _H)>;
5936   def : SVE_3_Op_Imm_Pat<nxv4i32, op, nxv4i1,  nxv4i32, i32, tvecshiftR32, !cast<Instruction>(NAME # _S)>;
5937   def : SVE_3_Op_Imm_Pat<nxv2i64, op, nxv2i1,  nxv2i64, i32, tvecshiftR64, !cast<Instruction>(NAME # _D)>;
5940 // As above but shift amount takes the form of a "vector immediate".
5941 multiclass sve_int_bin_pred_shift_imm_right_dup<bits<4> opc, string asm,
5942                                             string Ps, SDPatternOperator op>
5943 : sve_int_bin_pred_shift_imm_right<opc, asm, Ps, null_frag> {
5944   def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8,  !cast<Instruction>(NAME # _B)>;
5945   def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
5946   def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
5947   def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
5950 multiclass sve_int_bin_pred_shift_imm_right_zeroing_bhsd<SDPatternOperator op = null_frag> {
5951   def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8, vecshiftR8, FalseLanesZero>;
5952   def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, vecshiftR16, FalseLanesZero>;
5953   def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, vecshiftR32, FalseLanesZero>;
5954   def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, vecshiftR64, FalseLanesZero>;
5956   def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv16i8, op, nxv16i1, nxv16i8, tvecshiftR8, !cast<Pseudo>(NAME # _B_ZERO)>;
5957   def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv8i16, op, nxv8i1, nxv8i16, tvecshiftR16, !cast<Pseudo>(NAME # _H_ZERO)>;
5958   def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv4i32, op, nxv4i1, nxv4i32, tvecshiftR32, !cast<Pseudo>(NAME # _S_ZERO)>;
5959   def : SVE_3_Op_Pat_Shift_Imm_SelZero<nxv2i64, op, nxv2i1, nxv2i64, tvecshiftR64, !cast<Pseudo>(NAME # _D_ZERO)>;
5962 class sve_int_bin_pred_shift<bits<2> sz8_64, bit wide, bits<3> opc,
5963                              string asm, ZPRRegOp zprty, ZPRRegOp zprty2>
5964 : I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty2:$Zm),
5965   asm, "\t$Zdn, $Pg/m, $_Zdn, $Zm",
5966   "",
5967   []>, Sched<[]> {
5968   bits<3> Pg;
5969   bits<5> Zdn;
5970   bits<5> Zm;
5971   let Inst{31-24} = 0b00000100;
5972   let Inst{23-22} = sz8_64;
5973   let Inst{21-20} = 0b01;
5974   let Inst{19}    = wide;
5975   let Inst{18-16} = opc;
5976   let Inst{15-13} = 0b100;
5977   let Inst{12-10} = Pg;
5978   let Inst{9-5}   = Zm;
5979   let Inst{4-0}   = Zdn;
5981   let Constraints = "$Zdn = $_Zdn";
5982   let DestructiveInstType = DestructiveOther;
5983   let ElementSize = zprty.ElementSize;
5984   let hasSideEffects = 0;
5987 multiclass sve_int_bin_pred_shift<bits<3> opc, string asm, string Ps,
5988                                   SDPatternOperator op, string revname, bit isReverseInstr = 0> {
5989   let DestructiveInstType = DestructiveBinaryCommWithRev in {
5990   def _B : sve_int_bin_pred_shift<0b00, 0b0, opc, asm, ZPR8, ZPR8>,
5991            SVEPseudo2Instr<Ps # _B, 1>, SVEInstr2Rev<NAME # _B, revname # _B, isReverseInstr>;
5992   def _H : sve_int_bin_pred_shift<0b01, 0b0, opc, asm, ZPR16, ZPR16>,
5993            SVEPseudo2Instr<Ps # _H, 1>, SVEInstr2Rev<NAME # _H, revname # _H, isReverseInstr>;
5994   def _S : sve_int_bin_pred_shift<0b10, 0b0, opc, asm, ZPR32, ZPR32>,
5995            SVEPseudo2Instr<Ps # _S, 1>, SVEInstr2Rev<NAME # _S, revname # _S, isReverseInstr>;
5996   def _D : sve_int_bin_pred_shift<0b11, 0b0, opc, asm, ZPR64, ZPR64>,
5997            SVEPseudo2Instr<Ps # _D, 1>, SVEInstr2Rev<NAME # _D, revname # _D, isReverseInstr>;
5998   }
5999   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
6000   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
6001   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
6002   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
6005 multiclass sve_int_bin_pred_zeroing_bhsd<SDPatternOperator op> {
6006   def _B_ZERO : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesZero>;
6007   def _H_ZERO : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesZero>;
6008   def _S_ZERO : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesZero>;
6009   def _D_ZERO : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesZero>;
6011   def : SVE_3_Op_Pat_SelZero<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_ZERO)>;
6012   def : SVE_3_Op_Pat_SelZero<nxv8i16, op, nxv8i1, nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_ZERO)>;
6013   def : SVE_3_Op_Pat_SelZero<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_ZERO)>;
6014   def : SVE_3_Op_Pat_SelZero<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_ZERO)>;
6017 multiclass sve_int_bin_pred_imm_zeroing_bhsd<SDPatternOperator op,
6018                                    ComplexPattern imm_b, ComplexPattern imm_h,
6019                                    ComplexPattern imm_s, ComplexPattern imm_d> {
6020   def _B_ZERO : PredTwoOpImmPseudo<NAME # _B, ZPR8,  Operand<i32>, FalseLanesZero>;
6021   def _H_ZERO : PredTwoOpImmPseudo<NAME # _H, ZPR16, Operand<i32>, FalseLanesZero>;
6022   def _S_ZERO : PredTwoOpImmPseudo<NAME # _S, ZPR32, Operand<i32>, FalseLanesZero>;
6023   def _D_ZERO : PredTwoOpImmPseudo<NAME # _D, ZPR64, Operand<i32>, FalseLanesZero>;
6025   def : SVE_2_Op_Imm_Pat_Zero<nxv16i8, op, nxv16i1, i32, imm_b, !cast<Pseudo>(NAME # _B_ZERO)>;
6026   def : SVE_2_Op_Imm_Pat_Zero<nxv8i16, op, nxv8i1,  i32, imm_h, !cast<Pseudo>(NAME # _H_ZERO)>;
6027   def : SVE_2_Op_Imm_Pat_Zero<nxv4i32, op, nxv4i1,  i32, imm_s, !cast<Pseudo>(NAME # _S_ZERO)>;
6028   def : SVE_2_Op_Imm_Pat_Zero<nxv2i64, op, nxv2i1,  i64, imm_d, !cast<Pseudo>(NAME # _D_ZERO)>;
6031 multiclass sve_int_bin_pred_shift_wide<bits<3> opc, string asm,
6032                                   SDPatternOperator op> {
6033   def _B : sve_int_bin_pred_shift<0b00, 0b1, opc, asm, ZPR8, ZPR64>;
6034   def _H : sve_int_bin_pred_shift<0b01, 0b1, opc, asm, ZPR16, ZPR64>;
6035   def _S : sve_int_bin_pred_shift<0b10, 0b1, opc, asm, ZPR32, ZPR64>;
6037   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
6038   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
6039   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
6042 //===----------------------------------------------------------------------===//
6043 // SVE Shift - Unpredicated Group
6044 //===----------------------------------------------------------------------===//
6046 class sve_int_bin_cons_shift_wide<bits<2> sz8_64, bits<2> opc, string asm,
6047                                ZPRRegOp zprty>
6048 : I<(outs zprty:$Zd), (ins zprty:$Zn, ZPR64:$Zm),
6049   asm, "\t$Zd, $Zn, $Zm",
6050   "",
6051   []>, Sched<[]> {
6052   bits<5> Zd;
6053   bits<5> Zm;
6054   bits<5> Zn;
6055   let Inst{31-24} = 0b00000100;
6056   let Inst{23-22} = sz8_64;
6057   let Inst{21}    = 0b1;
6058   let Inst{20-16} = Zm;
6059   let Inst{15-12} = 0b1000;
6060   let Inst{11-10} = opc;
6061   let Inst{9-5}   = Zn;
6062   let Inst{4-0}   = Zd;
6064   let hasSideEffects = 0;
6067 multiclass sve_int_bin_cons_shift_wide<bits<2> opc, string asm, SDPatternOperator op> {
6068   def _B : sve_int_bin_cons_shift_wide<0b00, opc, asm, ZPR8>;
6069   def _H : sve_int_bin_cons_shift_wide<0b01, opc, asm, ZPR16>;
6070   def _S : sve_int_bin_cons_shift_wide<0b10, opc, asm, ZPR32>;
6072   def : SVE_2_Op_Pred_All_Active<nxv16i8, op, nxv16i1, nxv16i8, nxv2i64, !cast<Instruction>(NAME # _B)>;
6073   def : SVE_2_Op_Pred_All_Active<nxv8i16, op, nxv8i1, nxv8i16, nxv2i64, !cast<Instruction>(NAME # _H)>;
6074   def : SVE_2_Op_Pred_All_Active<nxv4i32, op, nxv4i1, nxv4i32, nxv2i64, !cast<Instruction>(NAME # _S)>;
6077 class sve_int_bin_cons_shift_imm<bits<4> tsz8_64, bits<2> opc, string asm,
6078                                ZPRRegOp zprty, Operand immtype>
6079 : I<(outs zprty:$Zd), (ins zprty:$Zn, immtype:$imm),
6080   asm, "\t$Zd, $Zn, $imm",
6081   "",
6082   []>, Sched<[]> {
6083   bits<5> Zd;
6084   bits<5> Zn;
6085   bits<6> imm;
6086   let Inst{31-24} = 0b00000100;
6087   let Inst{23-22} = tsz8_64{3-2};
6088   let Inst{21}    = 0b1;
6089   let Inst{20-19} = tsz8_64{1-0};
6090   let Inst{18-16} = imm{2-0}; // imm3
6091   let Inst{15-12} = 0b1001;
6092   let Inst{11-10} = opc;
6093   let Inst{9-5}   = Zn;
6094   let Inst{4-0}   = Zd;
6096   let hasSideEffects = 0;
6099 multiclass sve_int_bin_cons_shift_imm_left<bits<2> opc, string asm,
6100                                            SDPatternOperator op> {
6101   def _B : sve_int_bin_cons_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftL8>;
6102   def _H : sve_int_bin_cons_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftL16> {
6103     let Inst{19} = imm{3};
6104   }
6105   def _S : sve_int_bin_cons_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftL32> {
6106     let Inst{20-19} = imm{4-3};
6107   }
6108   def _D : sve_int_bin_cons_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftL64> {
6109     let Inst{22}    = imm{5};
6110     let Inst{20-19} = imm{4-3};
6111   }
6113   def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmL8,  !cast<Instruction>(NAME # _B)>;
6114   def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmL16, !cast<Instruction>(NAME # _H)>;
6115   def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmL32, !cast<Instruction>(NAME # _S)>;
6116   def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmL64, !cast<Instruction>(NAME # _D)>;
6119 multiclass sve_int_bin_cons_shift_imm_right<bits<2> opc, string asm,
6120                                             SDPatternOperator op> {
6121   def _B : sve_int_bin_cons_shift_imm<{0,0,0,1}, opc, asm, ZPR8, vecshiftR8>;
6122   def _H : sve_int_bin_cons_shift_imm<{0,0,1,?}, opc, asm, ZPR16, vecshiftR16> {
6123     let Inst{19} = imm{3};
6124   }
6125   def _S : sve_int_bin_cons_shift_imm<{0,1,?,?}, opc, asm, ZPR32, vecshiftR32> {
6126     let Inst{20-19} = imm{4-3};
6127   }
6128   def _D : sve_int_bin_cons_shift_imm<{1,?,?,?}, opc, asm, ZPR64, vecshiftR64> {
6129     let Inst{22}    = imm{5};
6130     let Inst{20-19} = imm{4-3};
6131   }
6133   def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv16i8, op, nxv16i1, i32, SVEShiftImmR8,  !cast<Instruction>(NAME # _B)>;
6134   def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv8i16, op, nxv8i1,  i32, SVEShiftImmR16, !cast<Instruction>(NAME # _H)>;
6135   def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv4i32, op, nxv4i1,  i32, SVEShiftImmR32, !cast<Instruction>(NAME # _S)>;
6136   def : SVE_Shift_DupImm_Any_Predicate_Pat<nxv2i64, op, nxv2i1,  i64, SVEShiftImmR64, !cast<Instruction>(NAME # _D)>;
6139 //===----------------------------------------------------------------------===//
6140 // SVE Memory - Store Group
6141 //===----------------------------------------------------------------------===//
6143 class sve_mem_cst_si<bits<2> msz, bits<2> esz, string asm,
6144                      RegisterOperand VecList>
6145 : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
6146   asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6147   "",
6148   []>, Sched<[]> {
6149   bits<3> Pg;
6150   bits<5> Rn;
6151   bits<5> Zt;
6152   bits<4> imm4;
6153   let Inst{31-25} = 0b1110010;
6154   let Inst{24-23} = msz;
6155   let Inst{22-21} = esz;
6156   let Inst{20}    = 0;
6157   let Inst{19-16} = imm4;
6158   let Inst{15-13} = 0b111;
6159   let Inst{12-10} = Pg;
6160   let Inst{9-5}   = Rn;
6161   let Inst{4-0}   = Zt;
6163   let hasSideEffects = 0;
6164   let mayStore = 1;
6167 multiclass sve_mem_cst_si<bits<2> msz, bits<2> esz, string asm,
6168                           RegisterOperand listty, ZPRRegOp zprty>
6170   def NAME : sve_mem_cst_si<msz, esz, asm, listty>;
6172   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6173                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
6174   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6175                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
6176   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6177                   (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6180 class sve_mem_est_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6181                      string asm, Operand immtype>
6182 : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
6183   asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6184   "",
6185   []>, Sched<[]> {
6186   bits<3> Pg;
6187   bits<5> Rn;
6188   bits<5> Zt;
6189   bits<4> imm4;
6190   let Inst{31-25} = 0b1110010;
6191   let Inst{24-23} = sz;
6192   let Inst{22-21} = nregs;
6193   let Inst{20}    = 1;
6194   let Inst{19-16} = imm4;
6195   let Inst{15-13} = 0b111;
6196   let Inst{12-10} = Pg;
6197   let Inst{9-5}   = Rn;
6198   let Inst{4-0}   = Zt;
6200   let hasSideEffects = 0;
6201   let mayStore = 1;
6204 multiclass sve_mem_est_si<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6205                           string asm, Operand immtype> {
6206   def NAME : sve_mem_est_si<sz, nregs, VecList, asm, immtype>;
6208   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6209                   (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6213 // SVE store multiple structures (quadwords, scalar plus immediate)
6214 class sve_mem_128b_est_si<bits<2> nregs, RegisterOperand VecList,
6215                           string asm, Operand immtype>
6216     : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
6217         asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6218         "", []>, Sched<[]> {
6219   bits<5> Zt;
6220   bits<5> Rn;
6221   bits<3> Pg;
6222   bits<4> imm4;
6223   let Inst{31-24} = 0b11100100;
6224   let Inst{23-22} = nregs;
6225   let Inst{21-20} = 0b00;
6226   let Inst{19-16} = imm4;
6227   let Inst{15-13} = 0b000;
6228   let Inst{12-10} = Pg;
6229   let Inst{9-5}   = Rn;
6230   let Inst{4-0}   = Zt;
6232   let hasSideEffects = 0;
6233   let mayStore = 1;
6236 multiclass sve_mem_128b_est_si<bits<2> nregs, RegisterOperand VecList,
6237                                string asm, Operand immtype> {
6238   def NAME : sve_mem_128b_est_si<nregs, VecList, asm, immtype>;
6240   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6241                   (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6245 class sve_mem_est_ss<bits<2> sz, bits<2> nregs, RegisterOperand VecList,
6246                      string asm, RegisterOperand gprty>
6247 : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6248   asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6249   "",
6250   []>, Sched<[]> {
6251   bits<3> Pg;
6252   bits<5> Rm;
6253   bits<5> Rn;
6254   bits<5> Zt;
6255   let Inst{31-25} = 0b1110010;
6256   let Inst{24-23} = sz;
6257   let Inst{22-21} = nregs;
6258   let Inst{20-16} = Rm;
6259   let Inst{15-13} = 0b011;
6260   let Inst{12-10} = Pg;
6261   let Inst{9-5}   = Rn;
6262   let Inst{4-0}   = Zt;
6264   let hasSideEffects = 0;
6265   let mayStore = 1;
6269 // SVE store multiple structures (quadwords, scalar plus scalar)
6270 class sve_mem_128b_est_ss<bits<2> nregs, RegisterOperand VecList,
6271                           string asm, RegisterOperand gprty>
6272     : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6273         asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6274         "", []>, Sched<[]> {
6275   bits<5> Zt;
6276   bits<5> Rn;
6277   bits<3> Pg;
6278   bits<5> Rm;
6279   let Inst{31-24} = 0b11100100;
6280   let Inst{23-22} = nregs;
6281   let Inst{21}    = 0b1;
6282   let Inst{20-16} = Rm;
6283   let Inst{15-13} = 0b000;
6284   let Inst{12-10} = Pg;
6285   let Inst{9-5}   = Rn;
6286   let Inst{4-0}   = Zt;
6288   let hasSideEffects = 0;
6289   let mayStore = 1;
6293 class sve_mem_cst_ss_base<bits<4> dtype, string asm,
6294                           RegisterOperand listty, RegisterOperand gprty>
6295 : I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6296   asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6297   "",
6298   []>, Sched<[]> {
6299   bits<3> Pg;
6300   bits<5> Rm;
6301   bits<5> Rn;
6302   bits<5> Zt;
6303   let Inst{31-25} = 0b1110010;
6304   let Inst{24-21} = dtype;
6305   let Inst{20-16} = Rm;
6306   let Inst{15-13} = 0b010;
6307   let Inst{12-10} = Pg;
6308   let Inst{9-5}   = Rn;
6309   let Inst{4-0}   = Zt;
6311   let hasSideEffects = 0;
6312   let mayStore = 1;
6315 multiclass sve_mem_cst_ss<bits<4> dtype, string asm,
6316                           RegisterOperand listty, ZPRRegOp zprty,
6317                           RegisterOperand gprty> {
6318   def NAME : sve_mem_cst_ss_base<dtype, asm, listty, gprty>;
6320   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Rm]",
6321                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
6324 class sve_mem_cstnt_si<bits<2> msz, string asm, RegisterOperand VecList>
6325 : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
6326   asm, "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6327   "",
6328   []>, Sched<[]> {
6329   bits<3> Pg;
6330   bits<5> Rn;
6331   bits<5> Zt;
6332   bits<4> imm4;
6333   let Inst{31-25} = 0b1110010;
6334   let Inst{24-23} = msz;
6335   let Inst{22-20} = 0b001;
6336   let Inst{19-16} = imm4;
6337   let Inst{15-13} = 0b111;
6338   let Inst{12-10} = Pg;
6339   let Inst{9-5}   = Rn;
6340   let Inst{4-0}   = Zt;
6342   let hasSideEffects = 0;
6343   let mayStore = 1;
6346 multiclass sve_mem_cstnt_si<bits<2> msz, string asm, RegisterOperand listty,
6347                             ZPRRegOp zprty> {
6348   def NAME : sve_mem_cstnt_si<msz, asm, listty>;
6350   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6351                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
6352   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $imm4, mul vl]",
6353                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
6354   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn]",
6355                   (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
6358 class sve_mem_cstnt_ss_base<bits<2> msz, string asm, RegisterOperand listty,
6359                             RegisterOperand gprty>
6360 : I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
6361   asm, "\t$Zt, $Pg, [$Rn, $Rm]",
6362   "",
6363   []>, Sched<[]> {
6364   bits<3> Pg;
6365   bits<5> Rm;
6366   bits<5> Rn;
6367   bits<5> Zt;
6368   let Inst{31-25} = 0b1110010;
6369   let Inst{24-23} = msz;
6370   let Inst{22-21} = 0b00;
6371   let Inst{20-16} = Rm;
6372   let Inst{15-13} = 0b011;
6373   let Inst{12-10} = Pg;
6374   let Inst{9-5}   = Rn;
6375   let Inst{4-0}   = Zt;
6377   let hasSideEffects = 0;
6378   let mayStore = 1;
6381 multiclass sve_mem_cstnt_ss<bits<2> msz, string asm, RegisterOperand listty,
6382                             ZPRRegOp zprty, RegisterOperand gprty> {
6383   def NAME : sve_mem_cstnt_ss_base<msz, asm, listty, gprty>;
6385   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Rm]",
6386                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
6389 class sve2_mem_sstnt_vs_base<bits<3> opc, string asm,
6390                              RegisterOperand listty, ZPRRegOp zprty>
6391 : I<(outs), (ins listty:$Zt, PPR3bAny:$Pg, zprty:$Zn, GPR64:$Rm),
6392   asm, "\t$Zt, $Pg, [$Zn, $Rm]",
6393   "",
6394   []>, Sched<[]> {
6395   bits<3> Pg;
6396   bits<5> Rm;
6397   bits<5> Zn;
6398   bits<5> Zt;
6399   let Inst{31-25} = 0b1110010;
6400   let Inst{24-22} = opc;
6401   let Inst{21}    = 0b0;
6402   let Inst{20-16} = Rm;
6403   let Inst{15-13} = 0b001;
6404   let Inst{12-10} = Pg;
6405   let Inst{9-5}   = Zn;
6406   let Inst{4-0}   = Zt;
6408   let hasSideEffects = 0;
6409   let mayStore = 1;
6412 multiclass sve2_mem_sstnt_vs_32_ptrs<bits<3> opc, string asm,
6413                              SDPatternOperator op,
6414                              ValueType vt> {
6415   def _REAL : sve2_mem_sstnt_vs_base<opc, asm, Z_s, ZPR32>;
6417   def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $Rm]",
6418                  (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm), 0>;
6419   def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6420                  (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 0>;
6421   def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6422                  (!cast<Instruction>(NAME # _REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 1>;
6424   def : Pat <(op (nxv4i32 ZPR32:$Zt), (nxv4i1 PPR3bAny:$Pg), (nxv4i32 ZPR32:$Zn), (i64 GPR64:$Rm), vt),
6425              (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm)>;
6428 multiclass sve2_mem_sstnt_vs_64_ptrs<bits<3> opc, string asm,
6429                              SDPatternOperator op,
6430                              ValueType vt> {
6431   def _REAL : sve2_mem_sstnt_vs_base<opc, asm, Z_d, ZPR64>;
6433   def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $Rm]",
6434                  (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm), 0>;
6435   def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6436                  (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 0>;
6437   def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6438                  (!cast<Instruction>(NAME # _REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
6440   def : Pat <(op (nxv2i64 ZPR64:$Zt), (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64:$Rm), vt),
6441              (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
6444 class sve_mem_sst_sv<bits<3> opc, bit xs, bit scaled, string asm,
6445                      RegisterOperand VecList, RegisterOperand zprext>
6446 : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
6447   asm, "\t$Zt, $Pg, [$Rn, $Zm]",
6448   "",
6449   []>, Sched<[]> {
6450   bits<3> Pg;
6451   bits<5> Rn;
6452   bits<5> Zm;
6453   bits<5> Zt;
6454   let Inst{31-25} = 0b1110010;
6455   let Inst{24-22} = opc;
6456   let Inst{21}    = scaled;
6457   let Inst{20-16} = Zm;
6458   let Inst{15}    = 0b1;
6459   let Inst{14}    = xs;
6460   let Inst{13}    = 0;
6461   let Inst{12-10} = Pg;
6462   let Inst{9-5}   = Rn;
6463   let Inst{4-0}   = Zt;
6465   let hasSideEffects = 0;
6466   let mayStore = 1;
6469 multiclass sve_mem_32b_sst_sv_32_scaled<bits<3> opc, string asm,
6470                                     SDPatternOperator sxtw_op,
6471                                     SDPatternOperator uxtw_op,
6472                                     RegisterOperand sxtw_opnd,
6473                                     RegisterOperand uxtw_opnd,
6474                                     ValueType vt > {
6475   def _UXTW_SCALED : sve_mem_sst_sv<opc, 0, 1, asm, Z_s, uxtw_opnd>;
6476   def _SXTW_SCALED : sve_mem_sst_sv<opc, 1, 1, asm, Z_s, sxtw_opnd>;
6478   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6479                  (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6480   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6481                  (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6483   def : Pat<(uxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6484             (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6485   def : Pat<(sxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6486             (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6489 multiclass sve_mem_64b_sst_sv_32_scaled<bits<3> opc, string asm,
6490                                     SDPatternOperator sxtw_op,
6491                                     SDPatternOperator uxtw_op,
6492                                     RegisterOperand sxtw_opnd,
6493                                     RegisterOperand uxtw_opnd,
6494                                     ValueType vt > {
6495   def _UXTW_SCALED : sve_mem_sst_sv<opc, 0, 1, asm, Z_d, uxtw_opnd>;
6496   def _SXTW_SCALED : sve_mem_sst_sv<opc, 1, 1, asm, Z_d, sxtw_opnd>;
6498   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6499                  (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6500   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6501                  (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6503   def : Pat<(uxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6504             (!cast<Instruction>(NAME # _UXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6505   def : Pat<(sxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6506             (!cast<Instruction>(NAME # _SXTW_SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6509 multiclass sve_mem_64b_sst_sv_32_unscaled<bits<3> opc, string asm,
6510                                          SDPatternOperator sxtw_op,
6511                                          SDPatternOperator uxtw_op,
6512                                          RegisterOperand sxtw_opnd,
6513                                          RegisterOperand uxtw_opnd,
6514                                          ValueType vt> {
6515   def _UXTW : sve_mem_sst_sv<opc, 0, 0, asm, Z_d, uxtw_opnd>;
6516   def _SXTW : sve_mem_sst_sv<opc, 1, 0, asm, Z_d, sxtw_opnd>;
6518   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6519                  (!cast<Instruction>(NAME # _UXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6520   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6521                  (!cast<Instruction>(NAME # _SXTW) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6523   def : Pat<(uxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6524             (!cast<Instruction>(NAME # _UXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6525   def : Pat<(sxtw_op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6526             (!cast<Instruction>(NAME # _SXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6529 multiclass sve_mem_32b_sst_sv_32_unscaled<bits<3> opc, string asm,
6530                                           SDPatternOperator sxtw_op,
6531                                           SDPatternOperator uxtw_op,
6532                                           RegisterOperand sxtw_opnd,
6533                                           RegisterOperand uxtw_opnd,
6534                                           ValueType vt> {
6535   def _UXTW : sve_mem_sst_sv<opc, 0, 0, asm, Z_s, uxtw_opnd>;
6536   def _SXTW : sve_mem_sst_sv<opc, 1, 0, asm, Z_s, sxtw_opnd>;
6538   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6539                  (!cast<Instruction>(NAME # _UXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
6540   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6541                  (!cast<Instruction>(NAME # _SXTW) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
6543   def : Pat<(uxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6544             (!cast<Instruction>(NAME # _UXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6545   def : Pat<(sxtw_op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt),
6546             (!cast<Instruction>(NAME # _SXTW) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6549 class sve_mem_sst_sv2<bits<2> msz, bit scaled, string asm,
6550                       RegisterOperand zprext>
6551 : I<(outs), (ins Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
6552   asm, "\t$Zt, $Pg, [$Rn, $Zm]",
6553   "",
6554   []>, Sched<[]> {
6555   bits<3> Pg;
6556   bits<5> Rn;
6557   bits<5> Zm;
6558   bits<5> Zt;
6559   let Inst{31-25} = 0b1110010;
6560   let Inst{24-23} = msz;
6561   let Inst{22}    = 0b0;
6562   let Inst{21}    = scaled;
6563   let Inst{20-16} = Zm;
6564   let Inst{15-13} = 0b101;
6565   let Inst{12-10} = Pg;
6566   let Inst{9-5}   = Rn;
6567   let Inst{4-0}   = Zt;
6569   let hasSideEffects = 0;
6570   let mayStore = 1;
6573 multiclass sve_mem_sst_sv_64_scaled<bits<2> msz, string asm,
6574                                     SDPatternOperator op,
6575                                     RegisterOperand zprext,
6576                                     ValueType vt> {
6577   def _SCALED : sve_mem_sst_sv2<msz, 1, asm, zprext>;
6579   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6580                  (!cast<Instruction>(NAME # _SCALED) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), 0>;
6582   def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt),
6583             (!cast<Instruction>(NAME # _SCALED) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
6586 multiclass sve_mem_sst_sv_64_unscaled<bits<2> msz, string asm,
6587                                       SDPatternOperator op,
6588                                       ValueType vt> {
6589   def NAME : sve_mem_sst_sv2<msz, 0, asm, ZPR64ExtLSL8>;
6591   def : InstAlias<asm # "\t$Zt, $Pg, [$Rn, $Zm]",
6592                  (!cast<Instruction>(NAME) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), 0>;
6594   def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt),
6595             (!cast<Instruction>(NAME) ZPR:$data, PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
6598 class sve_mem_sst_vi<bits<3> opc, string asm, ZPRRegOp zprty,
6599                      RegisterOperand VecList, Operand imm_ty>
6600 : I<(outs), (ins VecList:$Zt, PPR3bAny:$Pg, zprty:$Zn, imm_ty:$imm5),
6601   asm, "\t$Zt, $Pg, [$Zn, $imm5]",
6602   "",
6603   []>, Sched<[]> {
6604   bits<3> Pg;
6605   bits<5> imm5;
6606   bits<5> Zn;
6607   bits<5> Zt;
6608   let Inst{31-25} = 0b1110010;
6609   let Inst{24-23} = opc{2-1};
6610   let Inst{22}    = 0b1;
6611   let Inst{21}    = opc{0};
6612   let Inst{20-16} = imm5;
6613   let Inst{15-13} = 0b101;
6614   let Inst{12-10} = Pg;
6615   let Inst{9-5}   = Zn;
6616   let Inst{4-0}   = Zt;
6618   let hasSideEffects = 0;
6619   let mayStore = 1;
6622 multiclass sve_mem_32b_sst_vi_ptrs<bits<3> opc, string asm,
6623                                    Operand imm_ty,
6624                                    SDPatternOperator op,
6625                                    ValueType vt> {
6626   def _IMM : sve_mem_sst_vi<opc, asm, ZPR32, Z_s, imm_ty>;
6628   def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6629                   (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 0>;
6630   def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $imm5]",
6631                   (!cast<Instruction>(NAME # _IMM) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), 0>;
6632   def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6633                   (!cast<Instruction>(NAME # _IMM) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
6635   def : Pat<(op (nxv4i32 ZPR:$data), (nxv4i1 PPR:$gp), (nxv4i32 ZPR:$ptrs), imm_ty:$index, vt),
6636             (!cast<Instruction>(NAME # _IMM) ZPR:$data, PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
6639 multiclass sve_mem_64b_sst_vi_ptrs<bits<3> opc, string asm,
6640                                    Operand imm_ty,
6641                                    SDPatternOperator op,
6642                                    ValueType vt> {
6643   def _IMM : sve_mem_sst_vi<opc, asm, ZPR64, Z_d, imm_ty>;
6645   def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6646                   (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 0>;
6647   def : InstAlias<asm # "\t$Zt, $Pg, [$Zn, $imm5]",
6648                   (!cast<Instruction>(NAME # _IMM) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), 0>;
6649   def : InstAlias<asm # "\t$Zt, $Pg, [$Zn]",
6650                   (!cast<Instruction>(NAME # _IMM) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
6652   def : Pat<(op (nxv2i64 ZPR:$data), (nxv2i1 PPR:$gp), (nxv2i64 ZPR:$ptrs), imm_ty:$index, vt),
6653             (!cast<Instruction>(NAME # _IMM) ZPR:$data, PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
6656 class sve_mem_z_spill<string asm>
6657 : I<(outs), (ins ZPRAny:$Zt, GPR64sp:$Rn, simm9:$imm9),
6658   asm, "\t$Zt, [$Rn, $imm9, mul vl]",
6659   "",
6660   []>, Sched<[]> {
6661   bits<5> Rn;
6662   bits<5> Zt;
6663   bits<9> imm9;
6664   let Inst{31-22} = 0b1110010110;
6665   let Inst{21-16} = imm9{8-3};
6666   let Inst{15-13} = 0b010;
6667   let Inst{12-10} = imm9{2-0};
6668   let Inst{9-5}   = Rn;
6669   let Inst{4-0}   = Zt;
6671   let hasSideEffects = 0;
6672   let mayStore = 1;
6675 multiclass sve_mem_z_spill<string asm> {
6676   def NAME : sve_mem_z_spill<asm>;
6678   def : InstAlias<asm # "\t$Zt, [$Rn]",
6679                   (!cast<Instruction>(NAME) ZPRAny:$Zt, GPR64sp:$Rn, 0), 1>;
6682 class sve_mem_p_spill<string asm>
6683 : I<(outs), (ins PPRAny:$Pt, GPR64sp:$Rn, simm9:$imm9),
6684   asm, "\t$Pt, [$Rn, $imm9, mul vl]",
6685   "",
6686   []>, Sched<[]> {
6687   bits<4> Pt;
6688   bits<5> Rn;
6689   bits<9> imm9;
6690   let Inst{31-22} = 0b1110010110;
6691   let Inst{21-16} = imm9{8-3};
6692   let Inst{15-13} = 0b000;
6693   let Inst{12-10} = imm9{2-0};
6694   let Inst{9-5}   = Rn;
6695   let Inst{4}     = 0b0;
6696   let Inst{3-0}   = Pt;
6698   let hasSideEffects = 0;
6699   let mayStore = 1;
6702 multiclass sve_mem_p_spill<string asm> {
6703   def NAME : sve_mem_p_spill<asm>;
6705   def : InstAlias<asm # "\t$Pt, [$Rn]",
6706                   (!cast<Instruction>(NAME) PPRAny:$Pt, GPR64sp:$Rn, 0), 1>;
6709 //===----------------------------------------------------------------------===//
6710 // SVE Permute - Predicates Group
6711 //===----------------------------------------------------------------------===//
6713 class sve_int_perm_bin_perm_pp<bits<3> opc, bits<2> sz8_64, string asm,
6714                                PPRRegOp pprty, SDPatternOperator op>
6715 : I<(outs pprty:$Pd), (ins pprty:$Pn, pprty:$Pm),
6716   asm, "\t$Pd, $Pn, $Pm",
6717   "",
6718   [(set nxv16i1:$Pd, (op nxv16i1:$Pn, nxv16i1:$Pm))]>, Sched<[]> {
6719   bits<4> Pd;
6720   bits<4> Pm;
6721   bits<4> Pn;
6722   let Inst{31-24} = 0b00000101;
6723   let Inst{23-22} = sz8_64;
6724   let Inst{21-20} = 0b10;
6725   let Inst{19-16} = Pm;
6726   let Inst{15-13} = 0b010;
6727   let Inst{12-10} = opc;
6728   let Inst{9}     = 0b0;
6729   let Inst{8-5}   = Pn;
6730   let Inst{4}     = 0b0;
6731   let Inst{3-0}   = Pd;
6733   let hasSideEffects = 0;
6736 multiclass sve_int_perm_bin_perm_pp<bits<3> opc, string asm,
6737                                     SDPatternOperator ir_op,
6738                                     SDPatternOperator op_b16,
6739                                     SDPatternOperator op_b32,
6740                                     SDPatternOperator op_b64> {
6741   def _B : sve_int_perm_bin_perm_pp<opc, 0b00, asm, PPR8,  ir_op>;
6742   def _H : sve_int_perm_bin_perm_pp<opc, 0b01, asm, PPR16, op_b16>;
6743   def _S : sve_int_perm_bin_perm_pp<opc, 0b10, asm, PPR32, op_b32>;
6744   def _D : sve_int_perm_bin_perm_pp<opc, 0b11, asm, PPR64, op_b64>;
6746   def : SVE_2_Op_Pat<nxv8i1, ir_op, nxv8i1, nxv8i1, !cast<Instruction>(NAME # _H)>;
6747   def : SVE_2_Op_Pat<nxv4i1, ir_op, nxv4i1, nxv4i1, !cast<Instruction>(NAME # _S)>;
6748   def : SVE_2_Op_Pat<nxv2i1, ir_op, nxv2i1, nxv2i1, !cast<Instruction>(NAME # _D)>;
6751 class sve_int_perm_punpk<bit opc, string asm>
6752 : I<(outs PPR16:$Pd), (ins PPR8:$Pn),
6753   asm, "\t$Pd, $Pn",
6754   "",
6755   []>, Sched<[]> {
6756   bits<4> Pd;
6757   bits<4> Pn;
6758   let Inst{31-17} = 0b000001010011000;
6759   let Inst{16}    = opc;
6760   let Inst{15-9}  = 0b0100000;
6761   let Inst{8-5}   = Pn;
6762   let Inst{4}     = 0b0;
6763   let Inst{3-0}   = Pd;
6765   let hasSideEffects = 0;
6768 multiclass sve_int_perm_punpk<bit opc, string asm, SDPatternOperator op> {
6769   def NAME : sve_int_perm_punpk<opc, asm>;
6771   def : SVE_1_Op_Pat<nxv8i1, op, nxv16i1, !cast<Instruction>(NAME)>;
6772   def : SVE_1_Op_Pat<nxv4i1, op, nxv8i1,  !cast<Instruction>(NAME)>;
6773   def : SVE_1_Op_Pat<nxv2i1, op, nxv4i1,  !cast<Instruction>(NAME)>;
6776 class sve_int_rdffr_pred<bit s, string asm>
6777 : I<(outs PPR8:$Pd), (ins PPRAny:$Pg),
6778   asm, "\t$Pd, $Pg/z",
6779   "",
6780   []>, Sched<[]> {
6781   bits<4> Pd;
6782   bits<4> Pg;
6783   let Inst{31-23} = 0b001001010;
6784   let Inst{22}    = s;
6785   let Inst{21-9}  = 0b0110001111000;
6786   let Inst{8-5}   = Pg;
6787   let Inst{4}     = 0;
6788   let Inst{3-0}   = Pd;
6790   let Defs = !if(s, [NZCV], []);
6791   let Uses = [FFR];
6792   let hasSideEffects = 1;
6795 multiclass sve_int_rdffr_pred<bit s, string asm, SDPatternOperator op> {
6796   def _REAL : sve_int_rdffr_pred<s, asm>;
6798   // We need a layer of indirection because early machine code passes balk at
6799   // physical register (i.e. FFR) uses that have no previous definition.
6800   let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
6801   def "" : Pseudo<(outs PPR8:$Pd), (ins PPRAny:$Pg), [(set (nxv16i1 PPR8:$Pd), (op (nxv16i1 PPRAny:$Pg)))]>,
6802            PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) PPR8:$Pd, PPRAny:$Pg)>;
6803   }
6806 class sve_int_rdffr_unpred<string asm> : I<
6807   (outs PPR8:$Pd), (ins),
6808   asm, "\t$Pd",
6809   "",
6810   []>, Sched<[]> {
6811   bits<4> Pd;
6812   let Inst{31-4} = 0b0010010100011001111100000000;
6813   let Inst{3-0}   = Pd;
6815   let Uses = [FFR];
6816   let hasSideEffects = 1;
6819 multiclass sve_int_rdffr_unpred<string asm, SDPatternOperator op> {
6820   def _REAL : sve_int_rdffr_unpred<asm>;
6822   // We need a layer of indirection because early machine code passes balk at
6823   // physical register (i.e. FFR) uses that have no previous definition.
6824   let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
6825   def "" : Pseudo<(outs PPR8:$Pd), (ins), [(set (nxv16i1 PPR8:$Pd), (op))]>,
6826            PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) PPR8:$Pd)>;
6827   }
6830 class sve_int_wrffr<string asm, SDPatternOperator op>
6831 : I<(outs), (ins PPR8:$Pn),
6832   asm, "\t$Pn",
6833   "",
6834   [(op (nxv16i1 PPR8:$Pn))]>, Sched<[]> {
6835   bits<4> Pn;
6836   let Inst{31-9} = 0b00100101001010001001000;
6837   let Inst{8-5}  = Pn;
6838   let Inst{4-0}  = 0b00000;
6840   let Defs = [FFR];
6841   let hasSideEffects = 1;
6844 class sve_int_setffr<string asm, SDPatternOperator op>
6845 : I<(outs), (ins),
6846   asm, "",
6847   "",
6848   [(op)]>, Sched<[]> {
6849   let Inst{31-0} = 0b00100101001011001001000000000000;
6851   let Defs = [FFR];
6852   let hasSideEffects = 1;
6855 //===----------------------------------------------------------------------===//
6856 // SVE Permute Vector - Predicated Group
6857 //===----------------------------------------------------------------------===//
6859 class sve_int_perm_clast_rz<bits<2> sz8_64, bit ab, string asm,
6860                             ZPRRegOp zprty, RegisterClass rt>
6861 : I<(outs rt:$Rdn), (ins PPR3bAny:$Pg, rt:$_Rdn, zprty:$Zm),
6862   asm, "\t$Rdn, $Pg, $_Rdn, $Zm",
6863   "",
6864   []>, Sched<[]> {
6865   bits<3> Pg;
6866   bits<5> Rdn;
6867   bits<5> Zm;
6868   let Inst{31-24} = 0b00000101;
6869   let Inst{23-22} = sz8_64;
6870   let Inst{21-17} = 0b11000;
6871   let Inst{16}    = ab;
6872   let Inst{15-13} = 0b101;
6873   let Inst{12-10} = Pg;
6874   let Inst{9-5}   = Zm;
6875   let Inst{4-0}   = Rdn;
6877   let Constraints = "$Rdn = $_Rdn";
6878   let hasSideEffects = 0;
6881 multiclass sve_int_perm_clast_rz<bit ab, string asm, SDPatternOperator op> {
6882   def _B : sve_int_perm_clast_rz<0b00, ab, asm, ZPR8, GPR32>;
6883   def _H : sve_int_perm_clast_rz<0b01, ab, asm, ZPR16, GPR32>;
6884   def _S : sve_int_perm_clast_rz<0b10, ab, asm, ZPR32, GPR32>;
6885   def _D : sve_int_perm_clast_rz<0b11, ab, asm, ZPR64, GPR64>;
6887   def : SVE_3_Op_Pat<i32, op, nxv16i1, i32, nxv16i8, !cast<Instruction>(NAME # _B)>;
6888   def : SVE_3_Op_Pat<i32, op, nxv8i1,  i32, nxv8i16, !cast<Instruction>(NAME # _H)>;
6889   def : SVE_3_Op_Pat<i32, op, nxv4i1,  i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
6890   def : SVE_3_Op_Pat<i64, op, nxv2i1,  i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
6893 class sve_int_perm_clast_vz<bits<2> sz8_64, bit ab, string asm,
6894                             ZPRRegOp zprty, RegisterClass rt>
6895 : I<(outs rt:$Vdn), (ins PPR3bAny:$Pg, rt:$_Vdn, zprty:$Zm),
6896   asm, "\t$Vdn, $Pg, $_Vdn, $Zm",
6897   "",
6898   []>, Sched<[]> {
6899   bits<3> Pg;
6900   bits<5> Vdn;
6901   bits<5> Zm;
6902   let Inst{31-24} = 0b00000101;
6903   let Inst{23-22} = sz8_64;
6904   let Inst{21-17} = 0b10101;
6905   let Inst{16}    = ab;
6906   let Inst{15-13} = 0b100;
6907   let Inst{12-10} = Pg;
6908   let Inst{9-5}   = Zm;
6909   let Inst{4-0}   = Vdn;
6911   let Constraints = "$Vdn = $_Vdn";
6912   let hasSideEffects = 0;
6915 multiclass sve_int_perm_clast_vz<bit ab, string asm, SDPatternOperator op> {
6916   def _B : sve_int_perm_clast_vz<0b00, ab, asm, ZPR8, FPR8>;
6917   def _H : sve_int_perm_clast_vz<0b01, ab, asm, ZPR16, FPR16>;
6918   def _S : sve_int_perm_clast_vz<0b10, ab, asm, ZPR32, FPR32>;
6919   def _D : sve_int_perm_clast_vz<0b11, ab, asm, ZPR64, FPR64>;
6921   def : SVE_3_Op_Pat<f16, op, nxv8i1, f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
6922   def : SVE_3_Op_Pat<f32, op, nxv4i1, f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
6923   def : SVE_3_Op_Pat<f64, op, nxv2i1, f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
6925   def : SVE_3_Op_Pat<bf16, op, nxv8i1, bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
6928 class sve_int_perm_clast_zz<bits<2> sz8_64, bit ab, string asm,
6929                             ZPRRegOp zprty>
6930 : I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
6931   asm, "\t$Zdn, $Pg, $_Zdn, $Zm",
6932   "",
6933   []>, Sched<[]> {
6934   bits<3> Pg;
6935   bits<5> Zdn;
6936   bits<5> Zm;
6937   let Inst{31-24} = 0b00000101;
6938   let Inst{23-22} = sz8_64;
6939   let Inst{21-17} = 0b10100;
6940   let Inst{16}    = ab;
6941   let Inst{15-13} = 0b100;
6942   let Inst{12-10} = Pg;
6943   let Inst{9-5}   = Zm;
6944   let Inst{4-0}   = Zdn;
6946   let Constraints = "$Zdn = $_Zdn";
6947   let DestructiveInstType = DestructiveOther;
6948   let ElementSize = ElementSizeNone;
6949   let hasSideEffects = 0;
6952 multiclass sve_int_perm_clast_zz<bit ab, string asm, SDPatternOperator op> {
6953   def _B : sve_int_perm_clast_zz<0b00, ab, asm, ZPR8>;
6954   def _H : sve_int_perm_clast_zz<0b01, ab, asm, ZPR16>;
6955   def _S : sve_int_perm_clast_zz<0b10, ab, asm, ZPR32>;
6956   def _D : sve_int_perm_clast_zz<0b11, ab, asm, ZPR64>;
6958   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
6959   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
6960   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
6961   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
6963   def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
6964   def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
6965   def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
6967   def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
6970 class sve_int_perm_last_r<bits<2> sz8_64, bit ab, string asm,
6971                           ZPRRegOp zprty, RegisterClass resultRegType>
6972 : I<(outs resultRegType:$Rd), (ins PPR3bAny:$Pg, zprty:$Zn),
6973   asm, "\t$Rd, $Pg, $Zn",
6974   "",
6975   []>, Sched<[]> {
6976   bits<3> Pg;
6977   bits<5> Rd;
6978   bits<5> Zn;
6979   let Inst{31-24} = 0b00000101;
6980   let Inst{23-22} = sz8_64;
6981   let Inst{21-17} = 0b10000;
6982   let Inst{16}    = ab;
6983   let Inst{15-13} = 0b101;
6984   let Inst{12-10} = Pg;
6985   let Inst{9-5}   = Zn;
6986   let Inst{4-0}   = Rd;
6988   let hasSideEffects = 0;
6991 multiclass sve_int_perm_last_r<bit ab, string asm, SDPatternOperator op> {
6992   def _B : sve_int_perm_last_r<0b00, ab, asm, ZPR8, GPR32>;
6993   def _H : sve_int_perm_last_r<0b01, ab, asm, ZPR16, GPR32>;
6994   def _S : sve_int_perm_last_r<0b10, ab, asm, ZPR32, GPR32>;
6995   def _D : sve_int_perm_last_r<0b11, ab, asm, ZPR64, GPR64>;
6997   def : SVE_2_Op_Pat<i32, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
6998   def : SVE_2_Op_Pat<i32, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
6999   def : SVE_2_Op_Pat<i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7000   def : SVE_2_Op_Pat<i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7003 class sve_int_perm_last_v<bits<2> sz8_64, bit ab, string asm,
7004                           ZPRRegOp zprty, RegisterClass dstRegtype>
7005 : I<(outs dstRegtype:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
7006   asm, "\t$Vd, $Pg, $Zn",
7007   "",
7008   []>, Sched<[]> {
7009   bits<3> Pg;
7010   bits<5> Vd;
7011   bits<5> Zn;
7012   let Inst{31-24} = 0b00000101;
7013   let Inst{23-22} = sz8_64;
7014   let Inst{21-17} = 0b10001;
7015   let Inst{16}    = ab;
7016   let Inst{15-13} = 0b100;
7017   let Inst{12-10} = Pg;
7018   let Inst{9-5}   = Zn;
7019   let Inst{4-0}   = Vd;
7021   let hasSideEffects = 0;
7024 multiclass sve_int_perm_last_v<bit ab, string asm, SDPatternOperator op> {
7025   def _B : sve_int_perm_last_v<0b00, ab, asm, ZPR8, FPR8>;
7026   def _H : sve_int_perm_last_v<0b01, ab, asm, ZPR16, FPR16>;
7027   def _S : sve_int_perm_last_v<0b10, ab, asm, ZPR32, FPR32>;
7028   def _D : sve_int_perm_last_v<0b11, ab, asm, ZPR64, FPR64>;
7030   def : SVE_2_Op_Pat<f16, op, nxv8i1,  nxv8f16, !cast<Instruction>(NAME # _H)>;
7031   def : SVE_2_Op_Pat<f32, op, nxv4i1,  nxv4f32, !cast<Instruction>(NAME # _S)>;
7032   def : SVE_2_Op_Pat<f32, op, nxv2i1,  nxv2f32, !cast<Instruction>(NAME # _S)>;
7033   def : SVE_2_Op_Pat<f64, op, nxv2i1,  nxv2f64, !cast<Instruction>(NAME # _D)>;
7035   def : SVE_2_Op_Pat<bf16, op, nxv8i1,  nxv8bf16, !cast<Instruction>(NAME # _H)>;
7038 class sve_int_perm_splice<bits<2> sz8_64, string asm, ZPRRegOp zprty>
7039 : I<(outs zprty:$Zdn), (ins PPR3bAny:$Pg, zprty:$_Zdn, zprty:$Zm),
7040   asm, "\t$Zdn, $Pg, $_Zdn, $Zm",
7041   "",
7042   []>, Sched<[]> {
7043   bits<3> Pg;
7044   bits<5> Zdn;
7045   bits<5> Zm;
7046   let Inst{31-24} = 0b00000101;
7047   let Inst{23-22} = sz8_64;
7048   let Inst{21-13} = 0b101100100;
7049   let Inst{12-10} = Pg;
7050   let Inst{9-5}   = Zm;
7051   let Inst{4-0}   = Zdn;
7053   let Constraints = "$Zdn = $_Zdn";
7054   let DestructiveInstType = DestructiveOther;
7055   let ElementSize = ElementSizeNone;
7056   let hasSideEffects = 0;
7059 multiclass sve_int_perm_splice<string asm, SDPatternOperator op> {
7060   def _B : sve_int_perm_splice<0b00, asm, ZPR8>;
7061   def _H : sve_int_perm_splice<0b01, asm, ZPR16>;
7062   def _S : sve_int_perm_splice<0b10, asm, ZPR32>;
7063   def _D : sve_int_perm_splice<0b11, asm, ZPR64>;
7065   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
7066   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
7067   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
7068   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
7070   def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1,  nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
7071   def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1,  nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
7072   def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1,  nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
7074   def : SVE_3_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
7077 class sve2_int_perm_splice_cons<bits<2> sz8_64, string asm,
7078                                ZPRRegOp zprty, RegisterOperand VecList>
7079 : I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, VecList:$Zn),
7080   asm, "\t$Zd, $Pg, $Zn",
7081   "",
7082   []>, Sched<[]> {
7083   bits<3> Pg;
7084   bits<5> Zn;
7085   bits<5> Zd;
7086   let Inst{31-24} = 0b00000101;
7087   let Inst{23-22} = sz8_64;
7088   let Inst{21-13} = 0b101101100;
7089   let Inst{12-10} = Pg;
7090   let Inst{9-5}   = Zn;
7091   let Inst{4-0}   = Zd;
7093   let hasSideEffects = 0;
7096 multiclass sve2_int_perm_splice_cons<string asm> {
7097   def _B : sve2_int_perm_splice_cons<0b00, asm, ZPR8,  ZZ_b>;
7098   def _H : sve2_int_perm_splice_cons<0b01, asm, ZPR16, ZZ_h>;
7099   def _S : sve2_int_perm_splice_cons<0b10, asm, ZPR32, ZZ_s>;
7100   def _D : sve2_int_perm_splice_cons<0b11, asm, ZPR64, ZZ_d>;
7103 class sve_int_perm_rev<bits<2> sz8_64, bits<2> opc, string asm,
7104                        ZPRRegOp zprty>
7105 : I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, zprty:$Zn),
7106   asm, "\t$Zd, $Pg/m, $Zn",
7107   "",
7108   []>, Sched<[]> {
7109   bits<5> Zd;
7110   bits<3> Pg;
7111   bits<5> Zn;
7112   let Inst{31-24} = 0b00000101;
7113   let Inst{23-22} = sz8_64;
7114   let Inst{21-18} = 0b1001;
7115   let Inst{17-16} = opc;
7116   let Inst{15-13} = 0b100;
7117   let Inst{12-10} = Pg;
7118   let Inst{9-5}   = Zn;
7119   let Inst{4-0}   = Zd;
7121   let Constraints = "$Zd = $_Zd";
7122   let DestructiveInstType = DestructiveOther;
7123   let ElementSize = zprty.ElementSize;
7124   let hasSideEffects = 0;
7127 multiclass sve_int_perm_rev_rbit<string asm, SDPatternOperator op> {
7128   def _B : sve_int_perm_rev<0b00, 0b11, asm, ZPR8>;
7129   def _H : sve_int_perm_rev<0b01, 0b11, asm, ZPR16>;
7130   def _S : sve_int_perm_rev<0b10, 0b11, asm, ZPR32>;
7131   def _D : sve_int_perm_rev<0b11, 0b11, asm, ZPR64>;
7133   def : SVE_1_Op_Passthru_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
7134   def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
7135   def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7136   def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7139 multiclass sve_int_perm_rev_revb<string asm, SDPatternOperator op> {
7140   def _H : sve_int_perm_rev<0b01, 0b00, asm, ZPR16>;
7141   def _S : sve_int_perm_rev<0b10, 0b00, asm, ZPR32>;
7142   def _D : sve_int_perm_rev<0b11, 0b00, asm, ZPR64>;
7144   def : SVE_1_Op_Passthru_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
7145   def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7146   def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7149 multiclass sve_int_perm_rev_revh<string asm, SDPatternOperator op> {
7150   def _S : sve_int_perm_rev<0b10, 0b01, asm, ZPR32>;
7151   def _D : sve_int_perm_rev<0b11, 0b01, asm, ZPR64>;
7153   def : SVE_1_Op_Passthru_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
7154   def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7157 multiclass sve_int_perm_rev_revw<string asm, SDPatternOperator op> {
7158   def _D : sve_int_perm_rev<0b11, 0b10, asm, ZPR64>;
7160   def : SVE_1_Op_Passthru_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
7163 class sve_int_perm_cpy_r<bits<2> sz8_64, string asm, ZPRRegOp zprty,
7164                          RegisterClass srcRegType>
7165 : I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegType:$Rn),
7166   asm, "\t$Zd, $Pg/m, $Rn",
7167   "",
7168   []>, Sched<[]> {
7169   bits<3> Pg;
7170   bits<5> Rn;
7171   bits<5> Zd;
7172   let Inst{31-24} = 0b00000101;
7173   let Inst{23-22} = sz8_64;
7174   let Inst{21-13} = 0b101000101;
7175   let Inst{12-10} = Pg;
7176   let Inst{9-5}   = Rn;
7177   let Inst{4-0}   = Zd;
7179   let Constraints = "$Zd = $_Zd";
7180   let DestructiveInstType = DestructiveOther;
7181   let ElementSize = zprty.ElementSize;
7182   let hasSideEffects = 0;
7185 multiclass sve_int_perm_cpy_r<string asm, SDPatternOperator op> {
7186   def _B : sve_int_perm_cpy_r<0b00, asm, ZPR8, GPR32sp>;
7187   def _H : sve_int_perm_cpy_r<0b01, asm, ZPR16, GPR32sp>;
7188   def _S : sve_int_perm_cpy_r<0b10, asm, ZPR32, GPR32sp>;
7189   def _D : sve_int_perm_cpy_r<0b11, asm, ZPR64, GPR64sp>;
7191   def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7192                   (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7193   def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7194                   (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7195   def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7196                   (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPR3bAny:$Pg, GPR32sp:$Rn), 1>;
7197   def : InstAlias<"mov $Zd, $Pg/m, $Rn",
7198                   (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPR3bAny:$Pg, GPR64sp:$Rn), 1>;
7200   def : Pat<(nxv16i8 (op nxv16i1:$pg, i32:$splat, nxv16i8:$passthru)),
7201             (!cast<Instruction>(NAME # _B) $passthru, $pg, $splat)>;
7202   def : Pat<(nxv8i16 (op nxv8i1:$pg, i32:$splat, nxv8i16:$passthru)),
7203             (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7204   def : Pat<(nxv4i32 (op nxv4i1:$pg, i32:$splat, nxv4i32:$passthru)),
7205             (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7206   def : Pat<(nxv2i64 (op nxv2i1:$pg, i64:$splat, nxv2i64:$passthru)),
7207             (!cast<Instruction>(NAME # _D) $passthru, $pg, $splat)>;
7210 class sve_int_perm_cpy_v<bits<2> sz8_64, string asm, ZPRRegOp zprty,
7211                          RegisterClass srcRegtype>
7212 : I<(outs zprty:$Zd), (ins zprty:$_Zd, PPR3bAny:$Pg, srcRegtype:$Vn),
7213   asm, "\t$Zd, $Pg/m, $Vn",
7214   "",
7215   []>, Sched<[]> {
7216   bits<3> Pg;
7217   bits<5> Vn;
7218   bits<5> Zd;
7219   let Inst{31-24} = 0b00000101;
7220   let Inst{23-22} = sz8_64;
7221   let Inst{21-13} = 0b100000100;
7222   let Inst{12-10} = Pg;
7223   let Inst{9-5}   = Vn;
7224   let Inst{4-0}   = Zd;
7226   let Constraints = "$Zd = $_Zd";
7227   let DestructiveInstType = DestructiveOther;
7228   let ElementSize = zprty.ElementSize;
7229   let hasSideEffects = 0;
7232 multiclass sve_int_perm_cpy_v<string asm, SDPatternOperator op> {
7233   def _B : sve_int_perm_cpy_v<0b00, asm, ZPR8, FPR8>;
7234   def _H : sve_int_perm_cpy_v<0b01, asm, ZPR16, FPR16>;
7235   def _S : sve_int_perm_cpy_v<0b10, asm, ZPR32, FPR32>;
7236   def _D : sve_int_perm_cpy_v<0b11, asm, ZPR64, FPR64>;
7238   def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7239                   (!cast<Instruction>(NAME # _B) ZPR8:$Zd, PPR3bAny:$Pg, FPR8:$Vn), 1>;
7240   def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7241                   (!cast<Instruction>(NAME # _H) ZPR16:$Zd, PPR3bAny:$Pg, FPR16:$Vn), 1>;
7242   def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7243                   (!cast<Instruction>(NAME # _S) ZPR32:$Zd, PPR3bAny:$Pg, FPR32:$Vn), 1>;
7244   def : InstAlias<"mov $Zd, $Pg/m, $Vn",
7245                   (!cast<Instruction>(NAME # _D) ZPR64:$Zd, PPR3bAny:$Pg, FPR64:$Vn), 1>;
7247   def : Pat<(nxv8f16 (op nxv8i1:$pg, f16:$splat, nxv8f16:$passthru)),
7248             (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7249   def : Pat<(nxv4f16 (op nxv4i1:$pg, f16:$splat, nxv4f16:$passthru)),
7250             (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7251   def : Pat<(nxv2f16 (op nxv2i1:$pg, f16:$splat, nxv2f16:$passthru)),
7252             (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7253   def : Pat<(nxv2f32 (op nxv2i1:$pg, f32:$splat, nxv2f32:$passthru)),
7254             (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7255   def : Pat<(nxv4f32 (op nxv4i1:$pg, f32:$splat, nxv4f32:$passthru)),
7256             (!cast<Instruction>(NAME # _S) $passthru, $pg, $splat)>;
7257   def : Pat<(nxv2f64 (op nxv2i1:$pg, f64:$splat, nxv2f64:$passthru)),
7258             (!cast<Instruction>(NAME # _D) $passthru, $pg, $splat)>;
7260   def : Pat<(nxv8bf16 (op nxv8i1:$pg, bf16:$splat, nxv8bf16:$passthru)),
7261             (!cast<Instruction>(NAME # _H) $passthru, $pg, $splat)>;
7264 class sve_int_perm_compact<bit sz, string asm, ZPRRegOp zprty>
7265 : I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn),
7266   asm, "\t$Zd, $Pg, $Zn",
7267   "",
7268   []>, Sched<[]> {
7269   bits<3> Pg;
7270   bits<5> Zd;
7271   bits<5> Zn;
7272   let Inst{31-23} = 0b000001011;
7273   let Inst{22}    = sz;
7274   let Inst{21-13} = 0b100001100;
7275   let Inst{12-10} = Pg;
7276   let Inst{9-5}   = Zn;
7277   let Inst{4-0}   = Zd;
7279   let hasSideEffects = 0;
7282 multiclass sve_int_perm_compact<string asm, SDPatternOperator op> {
7283   def _S : sve_int_perm_compact<0b0, asm, ZPR32>;
7284   def _D : sve_int_perm_compact<0b1, asm, ZPR64>;
7286   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
7287   def : SVE_2_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
7288   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
7289   def : SVE_2_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
7292 //===----------------------------------------------------------------------===//
7293 // SVE Memory - Contiguous Load Group
7294 //===----------------------------------------------------------------------===//
7296 class sve_mem_cld_si_base<bits<4> dtype, bit nf, string asm,
7297                           RegisterOperand VecList>
7298 : I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
7299   asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7300   "",
7301   []>, Sched<[]> {
7302   bits<3> Pg;
7303   bits<5> Rn;
7304   bits<5> Zt;
7305   bits<4> imm4;
7306   let Inst{31-25} = 0b1010010;
7307   let Inst{24-21} = dtype;
7308   let Inst{20}    = nf;
7309   let Inst{19-16} = imm4;
7310   let Inst{15-13} = 0b101;
7311   let Inst{12-10} = Pg;
7312   let Inst{9-5}   = Rn;
7313   let Inst{4-0}   = Zt;
7315   let Defs = !if(nf, [FFR], []);
7316   let Uses = !if(nf, [FFR], []);
7317   let hasSideEffects = nf;
7318   let mayLoad = 1;
7321 multiclass sve_mem_cld_si<bits<4> dtype, string asm, RegisterOperand listty,
7322                           ZPRRegOp zprty> {
7323   def "" : sve_mem_cld_si_base<dtype, 0, asm, listty>;
7325   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7326                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7327   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7328                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
7329   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7330                   (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7333 class sve_mem_cldnt_si_base<bits<2> msz, string asm, RegisterOperand VecList>
7334 : I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
7335   asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7336   "",
7337   []>, Sched<[]> {
7338   bits<5> Zt;
7339   bits<3> Pg;
7340   bits<5> Rn;
7341   bits<4> imm4;
7342   let Inst{31-25} = 0b1010010;
7343   let Inst{24-23} = msz;
7344   let Inst{22-20} = 0b000;
7345   let Inst{19-16} = imm4;
7346   let Inst{15-13} = 0b111;
7347   let Inst{12-10} = Pg;
7348   let Inst{9-5}   = Rn;
7349   let Inst{4-0}   = Zt;
7351   let hasSideEffects = 0;
7352   let mayLoad = 1;
7355 multiclass sve_mem_cldnt_si<bits<2> msz, string asm, RegisterOperand listty,
7356                             ZPRRegOp zprty> {
7357   def NAME : sve_mem_cldnt_si_base<msz, asm, listty>;
7359   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7360                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7361   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7362                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
7363   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7364                   (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7367 class sve_mem_cldnt_ss_base<bits<2> msz, string asm, RegisterOperand VecList,
7368                             RegisterOperand gprty>
7369 : I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7370   asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7371   "",
7372   []>, Sched<[]> {
7373   bits<3> Pg;
7374   bits<5> Rm;
7375   bits<5> Rn;
7376   bits<5> Zt;
7377   let Inst{31-25} = 0b1010010;
7378   let Inst{24-23} = msz;
7379   let Inst{22-21} = 0b00;
7380   let Inst{20-16} = Rm;
7381   let Inst{15-13} = 0b110;
7382   let Inst{12-10} = Pg;
7383   let Inst{9-5}   = Rn;
7384   let Inst{4-0}   = Zt;
7386   let hasSideEffects = 0;
7387   let mayLoad = 1;
7390 multiclass sve_mem_cldnt_ss<bits<2> msz, string asm, RegisterOperand listty,
7391                             ZPRRegOp zprty, RegisterOperand gprty> {
7392   def NAME : sve_mem_cldnt_ss_base<msz, asm, listty, gprty>;
7394   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7395                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7398 class sve_mem_ldqr_si<bits<2> sz, string asm, RegisterOperand VecList>
7399 : I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4),
7400   asm, "\t$Zt, $Pg/z, [$Rn, $imm4]", "", []>, Sched<[]> {
7401   bits<5> Zt;
7402   bits<5> Rn;
7403   bits<3> Pg;
7404   bits<4> imm4;
7405   let Inst{31-25} = 0b1010010;
7406   let Inst{24-23} = sz;
7407   let Inst{22-20} = 0;
7408   let Inst{19-16} = imm4;
7409   let Inst{15-13} = 0b001;
7410   let Inst{12-10} = Pg;
7411   let Inst{9-5}   = Rn;
7412   let Inst{4-0}   = Zt;
7414   let hasSideEffects = 0;
7415   let mayLoad = 1;
7418 multiclass sve_mem_ldqr_si<bits<2> sz, string asm, RegisterOperand listty,
7419                            ZPRRegOp zprty> {
7420   def NAME : sve_mem_ldqr_si<sz, asm, listty>;
7421   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7422                   (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7423   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7424                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7425   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4]",
7426                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s16:$imm4), 0>;
7429 class sve_mem_ldqr_ss<bits<2> sz, string asm, RegisterOperand VecList,
7430                       RegisterOperand gprty>
7431 : I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7432   asm, "\t$Zt, $Pg/z, [$Rn, $Rm]", "", []>, Sched<[]> {
7433   bits<5> Zt;
7434   bits<3> Pg;
7435   bits<5> Rn;
7436   bits<5> Rm;
7437   let Inst{31-25} = 0b1010010;
7438   let Inst{24-23} = sz;
7439   let Inst{22-21} = 0;
7440   let Inst{20-16} = Rm;
7441   let Inst{15-13} = 0;
7442   let Inst{12-10} = Pg;
7443   let Inst{9-5}   = Rn;
7444   let Inst{4-0}   = Zt;
7446   let hasSideEffects = 0;
7447   let mayLoad = 1;
7450 multiclass sve_mem_ldqr_ss<bits<2> sz, string asm, RegisterOperand listty,
7451                            ZPRRegOp zprty, RegisterOperand gprty> {
7452   def NAME : sve_mem_ldqr_ss<sz, asm, listty, gprty>;
7454   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7455                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7458 class sve_mem_ld_dup<bits<2> dtypeh, bits<2> dtypel, string asm,
7459                      RegisterOperand VecList, Operand immtype>
7460 : I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm6),
7461   asm, "\t$Zt, $Pg/z, [$Rn, $imm6]",
7462   "",
7463   []>, Sched<[]> {
7464   bits<3> Pg;
7465   bits<5> Rn;
7466   bits<5> Zt;
7467   bits<6> imm6;
7468   let Inst{31-25} = 0b1000010;
7469   let Inst{24-23} = dtypeh;
7470   let Inst{22}    = 1;
7471   let Inst{21-16} = imm6;
7472   let Inst{15}    = 0b1;
7473   let Inst{14-13} = dtypel;
7474   let Inst{12-10} = Pg;
7475   let Inst{9-5}   = Rn;
7476   let Inst{4-0}   = Zt;
7478   let hasSideEffects = 0;
7479   let mayLoad = 1;
7482 multiclass sve_mem_ld_dup<bits<2> dtypeh, bits<2> dtypel, string asm,
7483                           RegisterOperand zlistty, ZPRRegOp zprty, Operand immtype> {
7484   def NAME : sve_mem_ld_dup<dtypeh, dtypel, asm, zlistty, immtype>;
7486   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7487                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7488   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm6]",
7489                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm6), 0>;
7490   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7491                   (!cast<Instruction>(NAME) zlistty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7494 class sve_mem_cld_ss_base<bits<4> dtype, bit ff, dag iops, string asm,
7495                           RegisterOperand VecList>
7496 : I<(outs VecList:$Zt), iops,
7497   asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7498   "",
7499   []>, Sched<[]> {
7500   bits<5> Zt;
7501   bits<3> Pg;
7502   bits<5> Rm;
7503   bits<5> Rn;
7504   let Inst{31-25} = 0b1010010;
7505   let Inst{24-21} = dtype;
7506   let Inst{20-16} = Rm;
7507   let Inst{15-14} = 0b01;
7508   let Inst{13}    = ff;
7509   let Inst{12-10} = Pg;
7510   let Inst{9-5}   = Rn;
7511   let Inst{4-0}   = Zt;
7513   let Defs = !if(ff, [FFR], []);
7514   let Uses = !if(ff, [FFR], []);
7515   let hasSideEffects = ff;
7516   let mayLoad = 1;
7519 multiclass sve_mem_cld_ss<bits<4> dtype, string asm, RegisterOperand listty,
7520                           ZPRRegOp zprty, RegisterOperand gprty> {
7521   def "" : sve_mem_cld_ss_base<dtype, 0, (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7522                                asm, listty>;
7524   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7525                  (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7528 multiclass sve_mem_cldff_ss<bits<4> dtype, string asm, RegisterOperand listty,
7529                             ZPRRegOp zprty, RegisterOperand gprty> {
7530   def _REAL : sve_mem_cld_ss_base<dtype, 1, (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7531                                   asm, listty>;
7533   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
7534                  (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
7536   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7537                  (!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 1>;
7539   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7540                  (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, XZR), 0>;
7542   // We need a layer of indirection because early machine code passes balk at
7543   // physical register (i.e. FFR) uses that have no previous definition.
7544   let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7545   def "" : Pseudo<(outs listty:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), []>,
7546            PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm)>;
7547   }
7550 multiclass sve_mem_cldnf_si<bits<4> dtype, string asm, RegisterOperand listty,
7551                             ZPRRegOp zprty> {
7552   def _REAL : sve_mem_cld_si_base<dtype, 1, asm, listty>;
7554   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7555                   (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
7556   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7557                   (!cast<Instruction>(NAME # _REAL) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
7558   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7559                   (!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7561   // We need a layer of indirection because early machine code passes balk at
7562   // physical register (i.e. FFR) uses that have no previous definition.
7563   let hasSideEffects = 1, hasNoSchedulingInfo = 1, mayLoad = 1 in {
7564   def "" : Pseudo<(outs listty:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), []>,
7565            PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4)>;
7566   }
7569 class sve_mem_eld_si<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7570                      string asm, Operand immtype>
7571 : I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, immtype:$imm4),
7572   asm, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
7573   "",
7574   []>, Sched<[]> {
7575   bits<5> Zt;
7576   bits<3> Pg;
7577   bits<5> Rn;
7578   bits<4> imm4;
7579   let Inst{31-25} = 0b1010010;
7580   let Inst{24-23} = sz;
7581   let Inst{22-21} = nregs{1-0};
7582   let Inst{20}    = nregs{2};
7583   let Inst{19-16} = imm4;
7584   let Inst{15-13} = 0b111;
7585   let Inst{12-10} = Pg;
7586   let Inst{9-5}   = Rn;
7587   let Inst{4-0}   = Zt;
7589   let hasSideEffects = 0;
7590   let mayLoad = 1;
7593 multiclass sve_mem_eld_si<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7594                           string asm, Operand immtype> {
7595   def NAME : sve_mem_eld_si<sz, nregs, VecList, asm, immtype>;
7597   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
7598                   (!cast<Instruction>(NAME) VecList:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7602 class sve_mem_eld_ss<bits<2> sz, bits<3> nregs, RegisterOperand VecList,
7603                      string asm, RegisterOperand gprty>
7604 : I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7605   asm, "\t$Zt, $Pg/z, [$Rn, $Rm]",
7606   "",
7607   []>, Sched<[]> {
7608   bits<3> Pg;
7609   bits<5> Rm;
7610   bits<5> Rn;
7611   bits<5> Zt;
7612   let Inst{31-25} = 0b1010010;
7613   let Inst{24-23} = sz;
7614   let Inst{22-21} = nregs{1-0};
7615   let Inst{20-16} = Rm;
7616   let Inst{15}    = 0b1;
7617   let Inst{14}    = nregs{2};
7618   let Inst{13}    = 0b0;
7619   let Inst{12-10} = Pg;
7620   let Inst{9-5}   = Rn;
7621   let Inst{4-0}   = Zt;
7623   let hasSideEffects = 0;
7624   let mayLoad = 1;
7627 //===----------------------------------------------------------------------===//
7628 // SVE Memory - 32-bit Gather and Unsized Contiguous Group
7629 //===----------------------------------------------------------------------===//
7631 // bit xs      is '1' if offsets are signed
7632 // bit scaled  is '1' if the offsets are scaled
7633 class sve_mem_32b_gld_sv<bits<4> opc, bit xs, bit scaled, string asm,
7634                          RegisterOperand zprext>
7635 : I<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
7636   asm, "\t$Zt, $Pg/z, [$Rn, $Zm]",
7637   "",
7638   []>, Sched<[]> {
7639   bits<3> Pg;
7640   bits<5> Rn;
7641   bits<5> Zm;
7642   bits<5> Zt;
7643   let Inst{31-25} = 0b1000010;
7644   let Inst{24-23} = opc{3-2};
7645   let Inst{22}    = xs;
7646   let Inst{21}    = scaled;
7647   let Inst{20-16} = Zm;
7648   let Inst{15}    = 0b0;
7649   let Inst{14-13} = opc{1-0};
7650   let Inst{12-10} = Pg;
7651   let Inst{9-5}   = Rn;
7652   let Inst{4-0}   = Zt;
7655   let Defs = !if(!eq(opc{0}, 1), [FFR], []);
7656   let Uses = !if(!eq(opc{0}, 1), [FFR], []);
7657   let hasSideEffects = opc{0};
7658   let mayLoad = 1;
7661 multiclass sve_mem_32b_gld_sv_32_scaled<bits<4> opc, string asm,
7662                                         SDPatternOperator sxtw_op,
7663                                         SDPatternOperator uxtw_op,
7664                                         RegisterOperand sxtw_opnd,
7665                                         RegisterOperand uxtw_opnd,
7666                                         ValueType vt> {
7667   def _UXTW_SCALED_REAL : sve_mem_32b_gld_sv<opc, 0, 1, asm, uxtw_opnd>;
7668   def _SXTW_SCALED_REAL : sve_mem_32b_gld_sv<opc, 1, 1, asm, sxtw_opnd>;
7670   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7671                   (!cast<Instruction>(NAME # _UXTW_SCALED_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
7672   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7673                   (!cast<Instruction>(NAME # _SXTW_SCALED_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
7675   // We need a layer of indirection because early machine code passes balk at
7676   // physical register (i.e. FFR) uses that have no previous definition.
7677   let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7678   def _UXTW_SCALED : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
7679                      PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_SCALED_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
7680   def _SXTW_SCALED : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
7681                      PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_SCALED_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
7682   }
7684   def : Pat<(nxv4i32 (uxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$indices), vt)),
7685             (!cast<Instruction>(NAME # _UXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
7686   def : Pat<(nxv4i32 (sxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$indices), vt)),
7687             (!cast<Instruction>(NAME # _SXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
7690 multiclass sve_mem_32b_gld_vs_32_unscaled<bits<4> opc, string asm,
7691                                           SDPatternOperator sxtw_op,
7692                                           SDPatternOperator uxtw_op,
7693                                           RegisterOperand sxtw_opnd,
7694                                           RegisterOperand uxtw_opnd,
7695                                           ValueType vt> {
7696   def _UXTW_REAL : sve_mem_32b_gld_sv<opc, 0, 0, asm, uxtw_opnd>;
7697   def _SXTW_REAL : sve_mem_32b_gld_sv<opc, 1, 0, asm, sxtw_opnd>;
7699   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7700                   (!cast<Instruction>(NAME # _UXTW_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
7701   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
7702                   (!cast<Instruction>(NAME # _SXTW_REAL) ZPR32:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
7704   // We need a layer of indirection because early machine code passes balk at
7705   // physical register (i.e. FFR) uses that have no previous definition.
7706   let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7707   def _UXTW : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
7708               PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
7709   def _SXTW : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
7710               PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_REAL) Z_s:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
7711   }
7713   def : Pat<(nxv4i32 (uxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt)),
7714             (!cast<Instruction>(NAME # _UXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
7715   def : Pat<(nxv4i32 (sxtw_op (nxv4i1 PPR:$gp), GPR64sp:$base, (nxv4i32 ZPR:$offsets), vt)),
7716             (!cast<Instruction>(NAME # _SXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
7720 class sve_mem_32b_gld_vi<bits<4> opc, string asm, Operand imm_ty>
7721 : I<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5),
7722   asm, "\t$Zt, $Pg/z, [$Zn, $imm5]",
7723   "",
7724   []>, Sched<[]> {
7725   bits<3> Pg;
7726   bits<5> Zn;
7727   bits<5> Zt;
7728   bits<5> imm5;
7729   let Inst{31-25} = 0b1000010;
7730   let Inst{24-23} = opc{3-2};
7731   let Inst{22-21} = 0b01;
7732   let Inst{20-16} = imm5;
7733   let Inst{15}    = 0b1;
7734   let Inst{14-13} = opc{1-0};
7735   let Inst{12-10} = Pg;
7736   let Inst{9-5}   = Zn;
7737   let Inst{4-0}   = Zt;
7740   let Defs = !if(!eq(opc{0}, 1), [FFR], []);
7741   let Uses = !if(!eq(opc{0}, 1), [FFR], []);
7742   let hasSideEffects = opc{0};
7743   let mayLoad = 1;
7746 multiclass sve_mem_32b_gld_vi_32_ptrs<bits<4> opc, string asm, Operand imm_ty,
7747                                       SDPatternOperator op, ValueType vt> {
7748   def _IMM_REAL : sve_mem_32b_gld_vi<opc, asm, imm_ty>;
7750   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7751                   (!cast<Instruction>(NAME # _IMM_REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 0>;
7752   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $imm5]",
7753                   (!cast<Instruction>(NAME # _IMM_REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), 0>;
7754   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7755                   (!cast<Instruction>(NAME # _IMM_REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
7757   // We need a layer of indirection because early machine code passes balk at
7758   // physical register (i.e. FFR) uses that have no previous definition.
7759   let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
7760   def _IMM : Pseudo<(outs Z_s:$Zt), (ins PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5), []>,
7761              PseudoInstExpansion<(!cast<Instruction>(NAME # _IMM_REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5)>;
7762   }
7764   def : Pat<(nxv4i32 (op (nxv4i1 PPR:$gp), (nxv4i32 ZPR:$ptrs), imm_ty:$index, vt)),
7765             (!cast<Instruction>(NAME # _IMM) PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
7768 class sve_mem_prfm_si<bits<2> msz, string asm>
7769 : I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, simm6s1:$imm6),
7770   asm, "\t$prfop, $Pg, [$Rn, $imm6, mul vl]",
7771   "",
7772   []>, Sched<[]> {
7773   bits<5> Rn;
7774   bits<3> Pg;
7775   bits<6> imm6;
7776   bits<4> prfop;
7777   let Inst{31-22} = 0b1000010111;
7778   let Inst{21-16} = imm6;
7779   let Inst{15}    = 0b0;
7780   let Inst{14-13} = msz;
7781   let Inst{12-10} = Pg;
7782   let Inst{9-5}   = Rn;
7783   let Inst{4}     = 0b0;
7784   let Inst{3-0}   = prfop;
7786   let hasSideEffects = 1;
7789 multiclass sve_mem_prfm_si<bits<2> msz, string asm> {
7790   def NAME : sve_mem_prfm_si<msz, asm>;
7792   def : InstAlias<asm # "\t$prfop, $Pg, [$Rn]",
7793                   (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
7796 class sve_mem_prfm_ss<bits<3> opc, string asm, RegisterOperand gprty>
7797 : I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
7798   asm, "\t$prfop, $Pg, [$Rn, $Rm]",
7799   "",
7800   []>, Sched<[]> {
7801   bits<5> Rm;
7802   bits<5> Rn;
7803   bits<3> Pg;
7804   bits<4> prfop;
7805   let Inst{31-25} = 0b1000010;
7806   let Inst{24-23} = opc{2-1};
7807   let Inst{22-21} = 0b00;
7808   let Inst{20-16} = Rm;
7809   let Inst{15}    = 0b1;
7810   let Inst{14}    = opc{0};
7811   let Inst{13}    = 0b0;
7812   let Inst{12-10} = Pg;
7813   let Inst{9-5}   = Rn;
7814   let Inst{4}     = 0b0;
7815   let Inst{3-0}   = prfop;
7817   let hasSideEffects = 1;
7820 class sve_mem_32b_prfm_sv<bits<2> msz, bit xs, string asm,
7821                           RegisterOperand zprext>
7822 : I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
7823   asm, "\t$prfop, $Pg, [$Rn, $Zm]",
7824   "",
7825   []>, Sched<[]> {
7826   bits<3> Pg;
7827   bits<5> Rn;
7828   bits<5> Zm;
7829   bits<4> prfop;
7830   let Inst{31-23} = 0b100001000;
7831   let Inst{22}    = xs;
7832   let Inst{21}    = 0b1;
7833   let Inst{20-16} = Zm;
7834   let Inst{15}    = 0b0;
7835   let Inst{14-13} = msz;
7836   let Inst{12-10} = Pg;
7837   let Inst{9-5}   = Rn;
7838   let Inst{4}     = 0b0;
7839   let Inst{3-0}   = prfop;
7841   let hasSideEffects = 1;
7844 multiclass sve_mem_32b_prfm_sv_scaled<bits<2> msz, string asm,
7845                                       RegisterOperand sxtw_opnd,
7846                                       RegisterOperand uxtw_opnd,
7847                                       SDPatternOperator op_sxtw,
7848                                       SDPatternOperator op_uxtw> {
7849   def _UXTW_SCALED : sve_mem_32b_prfm_sv<msz, 0, asm, uxtw_opnd>;
7850   def _SXTW_SCALED : sve_mem_32b_prfm_sv<msz, 1, asm, sxtw_opnd>;
7852   def : Pat<(op_uxtw (nxv4i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv4i32 uxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
7853             (!cast<Instruction>(NAME # _UXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
7855   def : Pat<(op_sxtw (nxv4i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv4i32 sxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
7856             (!cast<Instruction>(NAME # _SXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
7859 class sve_mem_32b_prfm_vi<bits<2> msz, string asm, Operand imm_ty>
7860 : I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, ZPR32:$Zn, imm_ty:$imm5),
7861   asm, "\t$prfop, $Pg, [$Zn, $imm5]",
7862   "",
7863   []>, Sched<[]> {
7864   bits<3> Pg;
7865   bits<5> Zn;
7866   bits<5> imm5;
7867   bits<4> prfop;
7868   let Inst{31-25} = 0b1000010;
7869   let Inst{24-23} = msz;
7870   let Inst{22-21} = 0b00;
7871   let Inst{20-16} = imm5;
7872   let Inst{15-13} = 0b111;
7873   let Inst{12-10} = Pg;
7874   let Inst{9-5}   = Zn;
7875   let Inst{4}     = 0b0;
7876   let Inst{3-0}   = prfop;
7878   let hasSideEffects = 1;
7881 multiclass sve_mem_32b_prfm_vi<bits<2> msz, string asm, Operand imm_ty, SDPatternOperator op> {
7882   def NAME : sve_mem_32b_prfm_vi<msz, asm, imm_ty>;
7884   def : InstAlias<asm # "\t$prfop, $Pg, [$Zn]",
7885                   (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, ZPR32:$Zn, 0), 1>;
7887   def : Pat<(op (nxv4i1 PPR_3b:$Pg), (nxv4i32 ZPR32:$Zn), (i64 imm_ty:$imm), (i32 sve_prfop:$prfop)),
7888             (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR_3b:$Pg, ZPR32:$Zn, imm_ty:$imm)>;
7891 class sve_mem_z_fill<string asm>
7892 : I<(outs ZPRAny:$Zt), (ins GPR64sp:$Rn, simm9:$imm9),
7893   asm, "\t$Zt, [$Rn, $imm9, mul vl]",
7894   "",
7895   []>, Sched<[]> {
7896   bits<5> Rn;
7897   bits<5> Zt;
7898   bits<9> imm9;
7899   let Inst{31-22} = 0b1000010110;
7900   let Inst{21-16} = imm9{8-3};
7901   let Inst{15-13} = 0b010;
7902   let Inst{12-10} = imm9{2-0};
7903   let Inst{9-5}   = Rn;
7904   let Inst{4-0}   = Zt;
7906   let hasSideEffects = 0;
7907   let mayLoad = 1;
7910 multiclass sve_mem_z_fill<string asm> {
7911   def NAME : sve_mem_z_fill<asm>;
7913   def : InstAlias<asm # "\t$Zt, [$Rn]",
7914                   (!cast<Instruction>(NAME) ZPRAny:$Zt, GPR64sp:$Rn, 0), 1>;
7917 class sve_mem_p_fill<string asm>
7918 : I<(outs PPRAny:$Pt), (ins GPR64sp:$Rn, simm9:$imm9),
7919   asm, "\t$Pt, [$Rn, $imm9, mul vl]",
7920   "",
7921   []>, Sched<[]> {
7922   bits<4> Pt;
7923   bits<5> Rn;
7924   bits<9> imm9;
7925   let Inst{31-22} = 0b1000010110;
7926   let Inst{21-16} = imm9{8-3};
7927   let Inst{15-13} = 0b000;
7928   let Inst{12-10} = imm9{2-0};
7929   let Inst{9-5}   = Rn;
7930   let Inst{4}     = 0b0;
7931   let Inst{3-0}   = Pt;
7933   let hasSideEffects = 0;
7934   let mayLoad = 1;
7937 multiclass sve_mem_p_fill<string asm> {
7938   def NAME : sve_mem_p_fill<asm>;
7940   def : InstAlias<asm # "\t$Pt, [$Rn]",
7941                   (!cast<Instruction>(NAME) PPRAny:$Pt, GPR64sp:$Rn, 0), 1>;
7944 class sve2_mem_gldnt_vs_base<bits<5> opc, dag iops, string asm,
7945                              RegisterOperand VecList>
7946 : I<(outs VecList:$Zt), iops,
7947   asm, "\t$Zt, $Pg/z, [$Zn, $Rm]",
7948   "",
7949   []>, Sched<[]> {
7950   bits<3> Pg;
7951   bits<5> Rm;
7952   bits<5> Zn;
7953   bits<5> Zt;
7954   let Inst{31}    = 0b1;
7955   let Inst{30}    = opc{4};
7956   let Inst{29-25} = 0b00010;
7957   let Inst{24-23} = opc{3-2};
7958   let Inst{22-21} = 0b00;
7959   let Inst{20-16} = Rm;
7960   let Inst{15}    = 0b1;
7961   let Inst{14-13} = opc{1-0};
7962   let Inst{12-10} = Pg;
7963   let Inst{9-5}   = Zn;
7964   let Inst{4-0}   = Zt;
7966   let hasSideEffects = 0;
7967   let mayLoad = 1;
7970 multiclass sve2_mem_gldnt_vs_32_ptrs<bits<5> opc, string asm,
7971                                   SDPatternOperator op,
7972                                   ValueType vt> {
7973   def _REAL : sve2_mem_gldnt_vs_base<opc, (ins PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm),
7974                                      asm, Z_s>;
7976   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $Rm]",
7977                  (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, GPR64:$Rm), 0>;
7978   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7979                  (!cast<Instruction>(NAME # _REAL) ZPR32:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 0>;
7980   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7981                  (!cast<Instruction>(NAME # _REAL) Z_s:$Zt, PPR3bAny:$Pg, ZPR32:$Zn, XZR), 1>;
7983   def : Pat <(nxv4i32 (op (nxv4i1 PPR3bAny:$Pg), (nxv4i32 ZPR32:$Zd), (i64 GPR64:$Rm), vt)),
7984              (!cast<Instruction>(NAME # _REAL) PPR3bAny:$Pg, ZPR32:$Zd, GPR64:$Rm)>;
7987 multiclass sve2_mem_gldnt_vs_64_ptrs<bits<5> opc, string asm,
7988                                    SDPatternOperator op,
7989                                    ValueType vt> {
7990   def _REAL : sve2_mem_gldnt_vs_base<opc, (ins PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
7991                                      asm, Z_d>;
7993   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $Rm]",
7994                  (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm), 0>;
7995   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7996                  (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 0>;
7997   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
7998                  (!cast<Instruction>(NAME # _REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
8000   def : Pat <(nxv2i64 (op (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zd), (i64 GPR64:$Rm), vt)),
8001              (!cast<Instruction>(NAME # _REAL) PPR3bAny:$Pg, ZPR64:$Zd, GPR64:$Rm)>;
8004 //===----------------------------------------------------------------------===//
8005 // SVE Memory - 64-bit Gather Group
8006 //===----------------------------------------------------------------------===//
8008 // bit xs      is '1' if offsets are signed
8009 // bit scaled  is '1' if the offsets are scaled
8010 // bit lsl     is '0' if the offsets are extended (uxtw/sxtw), '1' if shifted (lsl)
8011 class sve_mem_64b_gld_sv<bits<4> opc, bit xs, bit scaled, bit lsl, string asm,
8012                          RegisterOperand zprext>
8013 : I<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
8014   asm, "\t$Zt, $Pg/z, [$Rn, $Zm]",
8015   "",
8016   []>, Sched<[]> {
8017   bits<3> Pg;
8018   bits<5> Rn;
8019   bits<5> Zm;
8020   bits<5> Zt;
8021   let Inst{31-25} = 0b1100010;
8022   let Inst{24-23} = opc{3-2};
8023   let Inst{22}    = xs;
8024   let Inst{21}    = scaled;
8025   let Inst{20-16} = Zm;
8026   let Inst{15}    = lsl;
8027   let Inst{14-13} = opc{1-0};
8028   let Inst{12-10} = Pg;
8029   let Inst{9-5}   = Rn;
8030   let Inst{4-0}   = Zt;
8033   let Defs = !if(!eq(opc{0}, 1), [FFR], []);
8034   let Uses = !if(!eq(opc{0}, 1), [FFR], []);
8035   let hasSideEffects = opc{0};
8036   let mayLoad = 1;
8039 multiclass sve_mem_64b_gld_sv_32_scaled<bits<4> opc, string asm,
8040                                         SDPatternOperator sxtw_op,
8041                                         SDPatternOperator uxtw_op,
8042                                         RegisterOperand sxtw_opnd,
8043                                         RegisterOperand uxtw_opnd,
8044                                         ValueType vt> {
8045   def _UXTW_SCALED_REAL : sve_mem_64b_gld_sv<opc, 0, 1, 0, asm, uxtw_opnd>;
8046   def _SXTW_SCALED_REAL : sve_mem_64b_gld_sv<opc, 1, 1, 0, asm, sxtw_opnd>;
8048   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8049                   (!cast<Instruction>(NAME # _UXTW_SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
8050   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8051                   (!cast<Instruction>(NAME # _SXTW_SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
8053   // We need a layer of indirection because early machine code passes balk at
8054   // physical register (i.e. FFR) uses that have no previous definition.
8055   let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8056   def _UXTW_SCALED : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
8057                      PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_SCALED_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8058   def _SXTW_SCALED : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
8059                      PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_SCALED_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8060   }
8062   def : Pat<(nxv2i64 (uxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8063             (!cast<Instruction>(NAME # _UXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8064   def : Pat<(nxv2i64 (sxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8065             (!cast<Instruction>(NAME # _SXTW_SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8068 multiclass sve_mem_64b_gld_vs_32_unscaled<bits<4> opc, string asm,
8069                                           SDPatternOperator sxtw_op,
8070                                           SDPatternOperator uxtw_op,
8071                                           RegisterOperand sxtw_opnd,
8072                                           RegisterOperand uxtw_opnd,
8073                                           ValueType vt> {
8074   def _UXTW_REAL : sve_mem_64b_gld_sv<opc, 0, 0, 0, asm, uxtw_opnd>;
8075   def _SXTW_REAL : sve_mem_64b_gld_sv<opc, 1, 0, 0, asm, sxtw_opnd>;
8077   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8078                   (!cast<Instruction>(NAME # _UXTW_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), 0>;
8079   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8080                   (!cast<Instruction>(NAME # _SXTW_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), 0>;
8082   // We need a layer of indirection because early machine code passes balk at
8083   // physical register (i.e. FFR) uses that have no previous definition.
8084   let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8085   def _UXTW : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm), []>,
8086               PseudoInstExpansion<(!cast<Instruction>(NAME # _UXTW_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8087   def _SXTW : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm), []>,
8088               PseudoInstExpansion<(!cast<Instruction>(NAME # _SXTW_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8089   }
8091   def : Pat<(nxv2i64 (uxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8092             (!cast<Instruction>(NAME # _UXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8093   def : Pat<(nxv2i64 (sxtw_op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8094             (!cast<Instruction>(NAME # _SXTW) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8097 multiclass sve_mem_64b_gld_sv2_64_scaled<bits<4> opc, string asm,
8098                                          SDPatternOperator op,
8099                                          RegisterOperand zprext, ValueType vt> {
8100   def _SCALED_REAL : sve_mem_64b_gld_sv<opc, 1, 1, 1, asm, zprext>;
8102   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8103                   (!cast<Instruction>(NAME # _SCALED_REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), 0>;
8105   // We need a layer of indirection because early machine code passes balk at
8106   // physical register (i.e. FFR) uses that have no previous definition.
8107   let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8108   def _SCALED : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm), []>,
8109                 PseudoInstExpansion<(!cast<Instruction>(NAME # _SCALED_REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm)>;
8110   }
8112   def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$indices), vt)),
8113                      (!cast<Instruction>(NAME # _SCALED) PPR:$gp, GPR64sp:$base, ZPR:$indices)>;
8116 multiclass sve_mem_64b_gld_vs2_64_unscaled<bits<4> opc, string asm,
8117                                            SDPatternOperator op, ValueType vt> {
8118   def _REAL : sve_mem_64b_gld_sv<opc, 1, 0, 1, asm, ZPR64ExtLSL8>;
8120   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Zm]",
8121                   (!cast<Instruction>(NAME # _REAL) ZPR64:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), 0>;
8123   // We need a layer of indirection because early machine code passes balk at
8124   // physical register (i.e. FFR) uses that have no previous definition.
8125   let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8126   def "" : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm), []>,
8127            PseudoInstExpansion<(!cast<Instruction>(NAME # _REAL) Z_d:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, ZPR64ExtLSL8:$Zm)>;
8128   }
8130   def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), GPR64sp:$base, (nxv2i64 ZPR:$offsets), vt)),
8131             (!cast<Instruction>(NAME) PPR:$gp, GPR64sp:$base, ZPR:$offsets)>;
8134 class sve_mem_64b_gld_vi<bits<4> opc, string asm, Operand imm_ty>
8135 : I<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5),
8136   asm, "\t$Zt, $Pg/z, [$Zn, $imm5]",
8137   "",
8138   []>, Sched<[]> {
8139   bits<3> Pg;
8140   bits<5> Zn;
8141   bits<5> Zt;
8142   bits<5> imm5;
8143   let Inst{31-25} = 0b1100010;
8144   let Inst{24-23} = opc{3-2};
8145   let Inst{22-21} = 0b01;
8146   let Inst{20-16} = imm5;
8147   let Inst{15}    = 0b1;
8148   let Inst{14-13} = opc{1-0};
8149   let Inst{12-10} = Pg;
8150   let Inst{9-5}   = Zn;
8151   let Inst{4-0}   = Zt;
8153   let Defs = !if(!eq(opc{0}, 1), [FFR], []);
8154   let Uses = !if(!eq(opc{0}, 1), [FFR], []);
8155   let hasSideEffects = opc{0};
8156   let mayLoad = 1;
8159 multiclass sve_mem_64b_gld_vi_64_ptrs<bits<4> opc, string asm, Operand imm_ty,
8160                                       SDPatternOperator op, ValueType vt> {
8161   def _IMM_REAL : sve_mem_64b_gld_vi<opc, asm, imm_ty>;
8163   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8164                   (!cast<Instruction>(NAME # _IMM_REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 0>;
8165   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn, $imm5]",
8166                  (!cast<Instruction>(NAME # _IMM_REAL) ZPR64:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), 0>;
8167   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Zn]",
8168                   (!cast<Instruction>(NAME # _IMM_REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
8170   // We need a layer of indirection because early machine code passes balk at
8171   // physical register (i.e. FFR) uses that have no previous definition.
8172   let hasSideEffects = 1, hasNoSchedulingInfo = 1 in {
8173   def _IMM : Pseudo<(outs Z_d:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5), []>,
8174                   PseudoInstExpansion<(!cast<Instruction>(NAME # _IMM_REAL) Z_d:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5)>;
8175   }
8177   def : Pat<(nxv2i64 (op (nxv2i1 PPR:$gp), (nxv2i64 ZPR:$ptrs), imm_ty:$index, vt)),
8178             (!cast<Instruction>(NAME # _IMM) PPR:$gp, ZPR:$ptrs, imm_ty:$index)>;
8181 // bit lsl is '0' if the offsets are extended (uxtw/sxtw), '1' if shifted (lsl)
8182 class sve_mem_64b_prfm_sv<bits<2> msz, bit xs, bit lsl, string asm,
8183                           RegisterOperand zprext>
8184 : I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm),
8185   asm, "\t$prfop, $Pg, [$Rn, $Zm]",
8186   "",
8187   []>, Sched<[]> {
8188   bits<3> Pg;
8189   bits<5> Rn;
8190   bits<5> Zm;
8191   bits<4> prfop;
8192   let Inst{31-23} = 0b110001000;
8193   let Inst{22}    = xs;
8194   let Inst{21}    = 0b1;
8195   let Inst{20-16} = Zm;
8196   let Inst{15}    = lsl;
8197   let Inst{14-13} = msz;
8198   let Inst{12-10} = Pg;
8199   let Inst{9-5}   = Rn;
8200   let Inst{4}     = 0b0;
8201   let Inst{3-0}   = prfop;
8203   let hasSideEffects = 1;
8206 multiclass sve_mem_64b_prfm_sv_ext_scaled<bits<2> msz, string asm,
8207                                           RegisterOperand sxtw_opnd,
8208                                           RegisterOperand uxtw_opnd,
8209                                           SDPatternOperator op_sxtw,
8210                                           SDPatternOperator op_uxtw> {
8211   def _UXTW_SCALED : sve_mem_64b_prfm_sv<msz, 0, 0, asm, uxtw_opnd>;
8212   def _SXTW_SCALED : sve_mem_64b_prfm_sv<msz, 1, 0, asm, sxtw_opnd>;
8214   def : Pat<(op_uxtw (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 uxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
8215             (!cast<Instruction>(NAME # _UXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, uxtw_opnd:$Zm)>;
8217   def : Pat<(op_sxtw (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 sxtw_opnd:$Zm), (i32 sve_prfop:$prfop)),
8218             (!cast<Instruction>(NAME # _SXTW_SCALED) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, sxtw_opnd:$Zm)>;
8222 multiclass sve_mem_64b_prfm_sv_lsl_scaled<bits<2> msz, string asm,
8223                                           RegisterOperand zprext, SDPatternOperator frag> {
8224   def NAME : sve_mem_64b_prfm_sv<msz, 1, 1, asm, zprext>;
8226   def : Pat<(frag (nxv2i1 PPR3bAny:$Pg), (i64 GPR64sp:$Rn), (nxv2i64 zprext:$Zm), (i32 sve_prfop:$prfop)),
8227             (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, GPR64sp:$Rn, zprext:$Zm)>;
8231 class sve_mem_64b_prfm_vi<bits<2> msz, string asm, Operand imm_ty>
8232 : I<(outs), (ins sve_prfop:$prfop, PPR3bAny:$Pg, ZPR64:$Zn, imm_ty:$imm5),
8233   asm, "\t$prfop, $Pg, [$Zn, $imm5]",
8234   "",
8235   []>, Sched<[]> {
8236   bits<3> Pg;
8237   bits<5> Zn;
8238   bits<5> imm5;
8239   bits<4> prfop;
8240   let Inst{31-25} = 0b1100010;
8241   let Inst{24-23} = msz;
8242   let Inst{22-21} = 0b00;
8243   let Inst{20-16} = imm5;
8244   let Inst{15-13} = 0b111;
8245   let Inst{12-10} = Pg;
8246   let Inst{9-5}   = Zn;
8247   let Inst{4}     = 0b0;
8248   let Inst{3-0}   = prfop;
8250   let hasSideEffects = 1;
8253 multiclass sve_mem_64b_prfm_vi<bits<2> msz, string asm, Operand imm_ty, SDPatternOperator op> {
8254   def NAME : sve_mem_64b_prfm_vi<msz, asm, imm_ty>;
8256   def : InstAlias<asm # "\t$prfop, $Pg, [$Zn]",
8257                   (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR3bAny:$Pg, ZPR64:$Zn, 0), 1>;
8259   def : Pat<(op (nxv2i1 PPR_3b:$Pg), (nxv2i64 ZPR32:$Zn), (i64 imm_ty:$imm), (i32 sve_prfop:$prfop)),
8260             (!cast<Instruction>(NAME) sve_prfop:$prfop, PPR_3b:$Pg, ZPR32:$Zn, imm_ty:$imm)>;
8263 //===----------------------------------------------------------------------===//
8264 // SVE Compute Vector Address Group
8265 //===----------------------------------------------------------------------===//
8267 class sve_int_bin_cons_misc_0_a<bits<2> opc, bits<2> msz, string asm,
8268                                 ZPRRegOp zprty, RegisterOperand zprext>
8269 : I<(outs zprty:$Zd), (ins zprty:$Zn, zprext:$Zm),
8270   asm, "\t$Zd, [$Zn, $Zm]",
8271   "",
8272   []>, Sched<[]> {
8273   bits<5> Zd;
8274   bits<5> Zn;
8275   bits<5> Zm;
8276   let Inst{31-24} = 0b00000100;
8277   let Inst{23-22} = opc;
8278   let Inst{21}    = 0b1;
8279   let Inst{20-16} = Zm;
8280   let Inst{15-12} = 0b1010;
8281   let Inst{11-10} = msz;
8282   let Inst{9-5}   = Zn;
8283   let Inst{4-0}   = Zd;
8285   let hasSideEffects = 0;
8288 multiclass sve_int_bin_cons_misc_0_a_uxtw<bits<2> opc, string asm> {
8289   def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtUXTW8>;
8290   def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtUXTW16>;
8291   def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtUXTW32>;
8292   def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtUXTW64>;
8295 multiclass sve_int_bin_cons_misc_0_a_sxtw<bits<2> opc, string asm> {
8296   def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtSXTW8>;
8297   def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtSXTW16>;
8298   def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtSXTW32>;
8299   def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtSXTW64>;
8302 multiclass sve_int_bin_cons_misc_0_a_32_lsl<bits<2> opc, string asm> {
8303   def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR32, ZPR32ExtLSL8>;
8304   def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR32, ZPR32ExtLSL16>;
8305   def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR32, ZPR32ExtLSL32>;
8306   def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR32, ZPR32ExtLSL64>;
8309 multiclass sve_int_bin_cons_misc_0_a_64_lsl<bits<2> opc, string asm> {
8310   def _0 : sve_int_bin_cons_misc_0_a<opc, 0b00, asm, ZPR64, ZPR64ExtLSL8>;
8311   def _1 : sve_int_bin_cons_misc_0_a<opc, 0b01, asm, ZPR64, ZPR64ExtLSL16>;
8312   def _2 : sve_int_bin_cons_misc_0_a<opc, 0b10, asm, ZPR64, ZPR64ExtLSL32>;
8313   def _3 : sve_int_bin_cons_misc_0_a<opc, 0b11, asm, ZPR64, ZPR64ExtLSL64>;
8316 //===----------------------------------------------------------------------===//
8317 // SVE Integer Misc - Unpredicated Group
8318 //===----------------------------------------------------------------------===//
8320 class sve_int_bin_cons_misc_0_b<bits<2> sz, string asm, ZPRRegOp zprty>
8321 : I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
8322   asm, "\t$Zd, $Zn, $Zm",
8323   "",
8324   []>, Sched<[]> {
8325   bits<5> Zd;
8326   bits<5> Zm;
8327   bits<5> Zn;
8328   let Inst{31-24} = 0b00000100;
8329   let Inst{23-22} = sz;
8330   let Inst{21}    = 0b1;
8331   let Inst{20-16} = Zm;
8332   let Inst{15-10} = 0b101100;
8333   let Inst{9-5}   = Zn;
8334   let Inst{4-0}   = Zd;
8336   let hasSideEffects = 0;
8339 multiclass sve_int_bin_cons_misc_0_b<string asm, SDPatternOperator op> {
8340   def _H : sve_int_bin_cons_misc_0_b<0b01, asm, ZPR16>;
8341   def _S : sve_int_bin_cons_misc_0_b<0b10, asm, ZPR32>;
8342   def _D : sve_int_bin_cons_misc_0_b<0b11, asm, ZPR64>;
8344   def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
8345   def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
8346   def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
8349 class sve_int_bin_cons_misc_0_c<bits<8> opc, string asm, ZPRRegOp zprty>
8350 : I<(outs zprty:$Zd), (ins zprty:$Zn),
8351   asm, "\t$Zd, $Zn",
8352   "",
8353   []>, Sched<[]> {
8354   bits<5> Zd;
8355   bits<5> Zn;
8356   let Inst{31-24} = 0b00000100;
8357   let Inst{23-22} = opc{7-6};
8358   let Inst{21}    = 0b1;
8359   let Inst{20-16} = opc{5-1};
8360   let Inst{15-11} = 0b10111;
8361   let Inst{10}    = opc{0};
8362   let Inst{9-5}   = Zn;
8363   let Inst{4-0}   = Zd;
8365   let hasSideEffects = 0;
8368 multiclass sve_int_bin_cons_misc_0_c_fexpa<string asm, SDPatternOperator op> {
8369   def _H : sve_int_bin_cons_misc_0_c<0b01000000, asm, ZPR16>;
8370   def _S : sve_int_bin_cons_misc_0_c<0b10000000, asm, ZPR32>;
8371   def _D : sve_int_bin_cons_misc_0_c<0b11000000, asm, ZPR64>;
8373   def : SVE_1_Op_Pat<nxv8f16, op, nxv8i16, !cast<Instruction>(NAME # _H)>;
8374   def : SVE_1_Op_Pat<nxv4f32, op, nxv4i32, !cast<Instruction>(NAME # _S)>;
8375   def : SVE_1_Op_Pat<nxv2f64, op, nxv2i64, !cast<Instruction>(NAME # _D)>;
8378 //===----------------------------------------------------------------------===//
8379 // SVE Integer Reduction Group
8380 //===----------------------------------------------------------------------===//
8382 class sve_int_reduce<bits<2> sz8_32, bits<2> fmt, bits<3> opc, string asm,
8383                      ZPRRegOp zprty, FPRasZPROperand dstOpType>
8384 : I<(outs dstOpType:$Vd), (ins PPR3bAny:$Pg, zprty:$Zn),
8385   asm, "\t$Vd, $Pg, $Zn",
8386   "",
8387   []>, Sched<[]> {
8388   bits<3> Pg;
8389   bits<5> Vd;
8390   bits<5> Zn;
8391   let Inst{31-24} = 0b00000100;
8392   let Inst{23-22} = sz8_32;
8393   let Inst{21}    = 0b0;
8394   let Inst{20-19} = fmt;
8395   let Inst{18-16} = opc;
8396   let Inst{15-13} = 0b001;
8397   let Inst{12-10} = Pg;
8398   let Inst{9-5}   = Zn;
8399   let Inst{4-0}   = Vd;
8401   let hasSideEffects = 0;
8404 multiclass sve_int_reduce_0_saddv<bits<3> opc, string asm,
8405                                   SDPatternOperator op> {
8406   def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
8407   def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
8408   def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
8410   def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8411   def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8412   def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8415 multiclass sve_int_reduce_0_uaddv<bits<3> opc, string asm,
8416                                   SDPatternOperator op> {
8417   def _B : sve_int_reduce<0b00, 0b00, opc, asm, ZPR8, FPR64asZPR>;
8418   def _H : sve_int_reduce<0b01, 0b00, opc, asm, ZPR16, FPR64asZPR>;
8419   def _S : sve_int_reduce<0b10, 0b00, opc, asm, ZPR32, FPR64asZPR>;
8420   def _D : sve_int_reduce<0b11, 0b00, opc, asm, ZPR64, FPR64asZPR>;
8422   def : SVE_2_Op_Pat<nxv2i64, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8423   def : SVE_2_Op_Pat<nxv2i64, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8424   def : SVE_2_Op_Pat<nxv2i64, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8425   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8428 multiclass sve_int_reduce_1<bits<3> opc, string asm,
8429                             SDPatternOperator op> {
8430   def _B : sve_int_reduce<0b00, 0b01, opc, asm, ZPR8, FPR8asZPR>;
8431   def _H : sve_int_reduce<0b01, 0b01, opc, asm, ZPR16, FPR16asZPR>;
8432   def _S : sve_int_reduce<0b10, 0b01, opc, asm, ZPR32, FPR32asZPR>;
8433   def _D : sve_int_reduce<0b11, 0b01, opc, asm, ZPR64, FPR64asZPR>;
8435   def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8436   def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8437   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8438   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8441 multiclass sve_int_reduce_2<bits<3> opc, string asm,
8442                             SDPatternOperator op> {
8443   def _B : sve_int_reduce<0b00, 0b11, opc, asm, ZPR8, FPR8asZPR>;
8444   def _H : sve_int_reduce<0b01, 0b11, opc, asm, ZPR16, FPR16asZPR>;
8445   def _S : sve_int_reduce<0b10, 0b11, opc, asm, ZPR32, FPR32asZPR>;
8446   def _D : sve_int_reduce<0b11, 0b11, opc, asm, ZPR64, FPR64asZPR>;
8448   def : SVE_2_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
8449   def : SVE_2_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, !cast<Instruction>(NAME # _H)>;
8450   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, !cast<Instruction>(NAME # _S)>;
8451   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, !cast<Instruction>(NAME # _D)>;
8454 class sve_int_movprfx_pred<bits<2> sz8_32, bits<3> opc, string asm,
8455                            ZPRRegOp zprty, string pg_suffix, dag iops>
8456 : I<(outs zprty:$Zd), iops,
8457   asm, "\t$Zd, $Pg"#pg_suffix#", $Zn",
8458   "",
8459   []>, Sched<[]> {
8460   bits<3> Pg;
8461   bits<5> Zd;
8462   bits<5> Zn;
8463   let Inst{31-24} = 0b00000100;
8464   let Inst{23-22} = sz8_32;
8465   let Inst{21-19} = 0b010;
8466   let Inst{18-16} = opc;
8467   let Inst{15-13} = 0b001;
8468   let Inst{12-10} = Pg;
8469   let Inst{9-5}   = Zn;
8470   let Inst{4-0}   = Zd;
8472   let ElementSize = zprty.ElementSize;
8473   let hasSideEffects = 0;
8476 multiclass sve_int_movprfx_pred_merge<bits<3> opc, string asm> {
8477 let Constraints = "$Zd = $_Zd" in {
8478   def _B : sve_int_movprfx_pred<0b00, opc, asm, ZPR8, "/m",
8479                                 (ins ZPR8:$_Zd, PPR3bAny:$Pg, ZPR8:$Zn)>;
8480   def _H : sve_int_movprfx_pred<0b01, opc, asm, ZPR16, "/m",
8481                                 (ins ZPR16:$_Zd, PPR3bAny:$Pg, ZPR16:$Zn)>;
8482   def _S : sve_int_movprfx_pred<0b10, opc, asm, ZPR32, "/m",
8483                                 (ins ZPR32:$_Zd, PPR3bAny:$Pg, ZPR32:$Zn)>;
8484   def _D : sve_int_movprfx_pred<0b11, opc, asm, ZPR64, "/m",
8485                                 (ins ZPR64:$_Zd, PPR3bAny:$Pg, ZPR64:$Zn)>;
8489 multiclass sve_int_movprfx_pred_zero<bits<3> opc, string asm> {
8490   def _B : sve_int_movprfx_pred<0b00, opc, asm, ZPR8, "/z",
8491                                 (ins PPR3bAny:$Pg, ZPR8:$Zn)>;
8492   def _H : sve_int_movprfx_pred<0b01, opc, asm, ZPR16, "/z",
8493                                 (ins PPR3bAny:$Pg, ZPR16:$Zn)>;
8494   def _S : sve_int_movprfx_pred<0b10, opc, asm, ZPR32, "/z",
8495                                 (ins PPR3bAny:$Pg, ZPR32:$Zn)>;
8496   def _D : sve_int_movprfx_pred<0b11, opc, asm, ZPR64, "/z",
8497                                 (ins PPR3bAny:$Pg, ZPR64:$Zn)>;
8500 //===----------------------------------------------------------------------===//
8501 // SVE Propagate Break Group
8502 //===----------------------------------------------------------------------===//
8504 class sve_int_brkp<bits<2> opc, string asm>
8505 : I<(outs PPR8:$Pd), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$Pm),
8506   asm, "\t$Pd, $Pg/z, $Pn, $Pm",
8507   "",
8508   []>, Sched<[]> {
8509   bits<4> Pd;
8510   bits<4> Pg;
8511   bits<4> Pm;
8512   bits<4> Pn;
8513   let Inst{31-24} = 0b00100101;
8514   let Inst{23}    = 0b0;
8515   let Inst{22}    = opc{1};
8516   let Inst{21-20} = 0b00;
8517   let Inst{19-16} = Pm;
8518   let Inst{15-14} = 0b11;
8519   let Inst{13-10} = Pg;
8520   let Inst{9}     = 0b0;
8521   let Inst{8-5}   = Pn;
8522   let Inst{4}     = opc{0};
8523   let Inst{3-0}   = Pd;
8525   let Defs = !if(!eq (opc{1}, 1), [NZCV], []);
8526   let hasSideEffects = 0;
8529 multiclass sve_int_brkp<bits<2> opc, string asm, SDPatternOperator op> {
8530   def NAME : sve_int_brkp<opc, asm>;
8532   def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8536 //===----------------------------------------------------------------------===//
8537 // SVE Partition Break Group
8538 //===----------------------------------------------------------------------===//
8540 class sve_int_brkn<bit S, string asm>
8541 : I<(outs PPR8:$Pdm), (ins PPRAny:$Pg, PPR8:$Pn, PPR8:$_Pdm),
8542   asm, "\t$Pdm, $Pg/z, $Pn, $_Pdm",
8543   "",
8544   []>, Sched<[]> {
8545   bits<4> Pdm;
8546   bits<4> Pg;
8547   bits<4> Pn;
8548   let Inst{31-23} = 0b001001010;
8549   let Inst{22}    = S;
8550   let Inst{21-14} = 0b01100001;
8551   let Inst{13-10} = Pg;
8552   let Inst{9}     = 0b0;
8553   let Inst{8-5}   = Pn;
8554   let Inst{4}     = 0b0;
8555   let Inst{3-0}   = Pdm;
8557   let Constraints = "$Pdm = $_Pdm";
8558   let Defs = !if(S, [NZCV], []);
8559   let ElementSize = ElementSizeB;
8560   let hasSideEffects = 0;
8563 multiclass sve_int_brkn<bits<1> opc, string asm, SDPatternOperator op> {
8564   def NAME : sve_int_brkn<opc, asm>;
8566   def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8569 class sve_int_break<bits<3> opc, string asm, string suffix, dag iops>
8570 : I<(outs PPR8:$Pd), iops,
8571   asm, "\t$Pd, $Pg"#suffix#", $Pn",
8572   "",
8573   []>, Sched<[]> {
8574   bits<4> Pd;
8575   bits<4> Pg;
8576   bits<4> Pn;
8577   let Inst{31-24} = 0b00100101;
8578   let Inst{23-22} = opc{2-1};
8579   let Inst{21-14} = 0b01000001;
8580   let Inst{13-10} = Pg;
8581   let Inst{9}     = 0b0;
8582   let Inst{8-5}   = Pn;
8583   let Inst{4}     = opc{0};
8584   let Inst{3-0}   = Pd;
8586   let Constraints = !if(!eq (opc{0}, 1), "$Pd = $_Pd", "");
8587   let Defs = !if(!eq (opc{1}, 1), [NZCV], []);
8588   let hasSideEffects = 0;
8591 multiclass sve_int_break_m<bits<3> opc, string asm, SDPatternOperator op> {
8592   def NAME : sve_int_break<opc, asm, "/m", (ins PPR8:$_Pd, PPRAny:$Pg, PPR8:$Pn)>;
8594   def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8597 multiclass sve_int_break_z<bits<3> opc, string asm, SDPatternOperator op> {
8598   def NAME : sve_int_break<opc, asm, "/z", (ins PPRAny:$Pg, PPR8:$Pn)>;
8600   def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME)>;
8603 //===----------------------------------------------------------------------===//
8604 // SVE2 String Processing Group
8605 //===----------------------------------------------------------------------===//
8607 class sve2_char_match<bit sz, bit opc, string asm,
8608                       PPRRegOp pprty, ZPRRegOp zprty>
8609 : I<(outs pprty:$Pd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
8610   asm, "\t$Pd, $Pg/z, $Zn, $Zm",
8611   "",
8612   []>, Sched<[]> {
8613   bits<4> Pd;
8614   bits<3> Pg;
8615   bits<5> Zm;
8616   bits<5> Zn;
8617   let Inst{31-23} = 0b010001010;
8618   let Inst{22}    = sz;
8619   let Inst{21}    = 0b1;
8620   let Inst{20-16} = Zm;
8621   let Inst{15-13} = 0b100;
8622   let Inst{12-10} = Pg;
8623   let Inst{9-5}   = Zn;
8624   let Inst{4}     = opc;
8625   let Inst{3-0}   = Pd;
8627   let Defs = [NZCV];
8628   let ElementSize = pprty.ElementSize;
8629   let hasSideEffects = 0;
8630   let isPTestLike = 1;
8633 multiclass sve2_char_match<bit opc, string asm, SDPatternOperator op> {
8634   def _B : sve2_char_match<0b0, opc, asm, PPR8, ZPR8>;
8635   def _H : sve2_char_match<0b1, opc, asm, PPR16, ZPR16>;
8637   def : SVE_3_Op_Pat<nxv16i1, op, nxv16i1, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
8638   def : SVE_3_Op_Pat<nxv8i1,  op, nxv8i1,  nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
8641 //===----------------------------------------------------------------------===//
8642 // SVE2 Histogram Computation - Segment Group
8643 //===----------------------------------------------------------------------===//
8645 class sve2_hist_gen_segment<string asm, SDPatternOperator op>
8646 : I<(outs ZPR8:$Zd), (ins ZPR8:$Zn, ZPR8:$Zm),
8647   asm, "\t$Zd, $Zn, $Zm",
8648   "",
8649   [(set nxv16i8:$Zd, (op nxv16i8:$Zn, nxv16i8:$Zm))]>, Sched<[]> {
8650   bits<5> Zd;
8651   bits<5> Zn;
8652   bits<5> Zm;
8653   let Inst{31-21} = 0b01000101001;
8654   let Inst{20-16} = Zm;
8655   let Inst{15-10} = 0b101000;
8656   let Inst{9-5}   = Zn;
8657   let Inst{4-0}   = Zd;
8659   let hasSideEffects = 0;
8662 //===----------------------------------------------------------------------===//
8663 // SVE2 Histogram Computation - Vector Group
8664 //===----------------------------------------------------------------------===//
8666 class sve2_hist_gen_vector<bit sz, string asm, ZPRRegOp zprty>
8667 : I<(outs zprty:$Zd), (ins PPR3bAny:$Pg, zprty:$Zn, zprty:$Zm),
8668   asm, "\t$Zd, $Pg/z, $Zn, $Zm",
8669   "",
8670   []>, Sched<[]> {
8671   bits<5> Zd;
8672   bits<5> Zn;
8673   bits<3> Pg;
8674   bits<5> Zm;
8675   let Inst{31-23} = 0b010001011;
8676   let Inst{22}    = sz;
8677   let Inst{21}    = 0b1;
8678   let Inst{20-16} = Zm;
8679   let Inst{15-13} = 0b110;
8680   let Inst{12-10} = Pg;
8681   let Inst{9-5}   = Zn;
8682   let Inst{4-0}   = Zd;
8684   let hasSideEffects = 0;
8687 multiclass sve2_hist_gen_vector<string asm, SDPatternOperator op> {
8688   def _S : sve2_hist_gen_vector<0b0, asm, ZPR32>;
8689   def _D : sve2_hist_gen_vector<0b1, asm, ZPR64>;
8691   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
8692   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
8695 //===----------------------------------------------------------------------===//
8696 // SVE2 Crypto Extensions Group
8697 //===----------------------------------------------------------------------===//
8699 class sve2_crypto_cons_bin_op<bit opc, string asm, ZPRRegOp zprty>
8700 : I<(outs zprty:$Zd), (ins zprty:$Zn, zprty:$Zm),
8701   asm, "\t$Zd, $Zn, $Zm",
8702   "",
8703   []>, Sched<[]> {
8704   bits<5> Zd;
8705   bits<5> Zn;
8706   bits<5> Zm;
8707   let Inst{31-21} = 0b01000101001;
8708   let Inst{20-16} = Zm;
8709   let Inst{15-11} = 0b11110;
8710   let Inst{10}    = opc;
8711   let Inst{9-5}   = Zn;
8712   let Inst{4-0}   = Zd;
8714   let hasSideEffects = 0;
8717 multiclass sve2_crypto_cons_bin_op<bit opc, string asm, ZPRRegOp zprty,
8718                                    SDPatternOperator op, ValueType vt> {
8719   def NAME : sve2_crypto_cons_bin_op<opc, asm, zprty>;
8720   def : SVE_2_Op_Pat<vt, op, vt, vt, !cast<Instruction>(NAME)>;
8723 class sve2_crypto_des_bin_op<bits<2> opc, string asm, ZPRRegOp zprty>
8724 : I<(outs zprty:$Zdn), (ins zprty:$_Zdn, zprty:$Zm),
8725   asm, "\t$Zdn, $_Zdn, $Zm",
8726   "",
8727   []>, Sched<[]> {
8728   bits<5> Zdn;
8729   bits<5> Zm;
8730   let Inst{31-17} = 0b010001010010001;
8731   let Inst{16}    = opc{1};
8732   let Inst{15-11} = 0b11100;
8733   let Inst{10}    = opc{0};
8734   let Inst{9-5}   = Zm;
8735   let Inst{4-0}   = Zdn;
8737   let Constraints = "$Zdn = $_Zdn";
8738   let hasSideEffects = 0;
8741 multiclass sve2_crypto_des_bin_op<bits<2> opc, string asm, ZPRRegOp zprty,
8742                                   SDPatternOperator op, ValueType vt> {
8743   def NAME : sve2_crypto_des_bin_op<opc, asm, zprty>;
8744   def : SVE_2_Op_Pat<vt, op, vt, vt, !cast<Instruction>(NAME)>;
8747 class sve2_crypto_unary_op<bit opc, string asm, ZPRRegOp zprty>
8748 : I<(outs zprty:$Zdn), (ins zprty:$_Zdn),
8749   asm, "\t$Zdn, $_Zdn",
8750   "",
8751   []>, Sched<[]> {
8752   bits<5> Zdn;
8753   let Inst{31-11} = 0b010001010010000011100;
8754   let Inst{10}    = opc;
8755   let Inst{9-5}   = 0b00000;
8756   let Inst{4-0}   = Zdn;
8758   let Constraints = "$Zdn = $_Zdn";
8759   let hasSideEffects = 0;
8762 multiclass sve2_crypto_unary_op<bit opc, string asm, SDPatternOperator op> {
8763   def NAME : sve2_crypto_unary_op<opc, asm, ZPR8>;
8764   def : SVE_1_Op_Pat<nxv16i8, op, nxv16i8, !cast<Instruction>(NAME)>;
8767 //===----------------------------------------------------------------------===//
8768 // SVE BFloat16 Group
8769 //===----------------------------------------------------------------------===//
8771 class sve_float_dot<bit bf, bit o2, ZPRRegOp dst_ty, ZPRRegOp src_ty, string asm>
8772 : I<(outs dst_ty:$Zda), (ins dst_ty:$_Zda, src_ty:$Zn, src_ty:$Zm),
8773      asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8774   bits<5> Zda;
8775   bits<5> Zn;
8776   bits<5> Zm;
8777   let Inst{31-23} = 0b011001000;
8778   let Inst{22}    = bf;
8779   let Inst{21}    = 0b1;
8780   let Inst{20-16} = Zm;
8781   let Inst{15-11} = 0b10000;
8782   let Inst{10}    = o2;
8783   let Inst{9-5}   = Zn;
8784   let Inst{4-0}   = Zda;
8786   let Constraints = "$Zda = $_Zda";
8787   let DestructiveInstType = DestructiveOther;
8788   let hasSideEffects = 0;
8789   let mayRaiseFPException = 1;
8792 multiclass sve_float_dot<bit bf, bit o2, ZPRRegOp dst_ty, ZPRRegOp src_ty,
8793                          string asm, ValueType InVT, SDPatternOperator op> {
8794   def NAME : sve_float_dot<bf, o2, dst_ty, src_ty, asm>;
8795   def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, InVT, InVT, !cast<Instruction>(NAME)>;
8798 class sve_float_dot_indexed<bit bf, ZPRRegOp dst_ty, ZPRRegOp src1_ty,
8799                             ZPRRegOp src2_ty, Operand iop_ty, string asm>
8800 : I<(outs dst_ty:$Zda), (ins dst_ty:$_Zda, src1_ty:$Zn, src2_ty:$Zm, iop_ty:$iop),
8801     asm, "\t$Zda, $Zn, $Zm$iop", "", []>, Sched<[]> {
8802   bits<5> Zda;
8803   bits<5> Zn;
8804   bits<3> Zm;
8805   let Inst{31-23} = 0b011001000;
8806   let Inst{22}    = bf;
8807   let Inst{21}    = 0b1;
8808   let Inst{18-16} = Zm;
8809   let Inst{15-12} = 0b0100;
8810   let Inst{9-5}   = Zn;
8811   let Inst{4-0}   = Zda;
8813   let Constraints = "$Zda = $_Zda";
8814   let DestructiveInstType = DestructiveOther;
8815   let hasSideEffects = 0;
8816   let mayRaiseFPException = 1;
8819 multiclass sve_float_dot_indexed<bit bf, bits<2> opc, ZPRRegOp src1_ty,
8820                                  ZPRRegOp src2_ty, string asm, ValueType InVT,
8821                                  SDPatternOperator op> {
8822   def NAME : sve_float_dot_indexed<bf, ZPR32, src1_ty, src2_ty, VectorIndexS32b, asm> {
8823     bits<2> iop;
8824     let Inst{20-19} = iop;
8825     let Inst{11-10} = opc;
8826   }
8827   def : SVE_4_Op_Imm_Pat<nxv4f32, op, nxv4f32, InVT, InVT, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
8830 class sve_bfloat_matmul<string asm>
8831 : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
8832   asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8833   bits<5> Zm;
8834   bits<5> Zda;
8835   bits<5> Zn;
8836   let Inst{31-21} = 0b01100100011;
8837   let Inst{20-16} = Zm;
8838   let Inst{15-10} = 0b111001;
8839   let Inst{9-5}   = Zn;
8840   let Inst{4-0}   = Zda;
8842   let Constraints = "$Zda = $_Zda";
8843   let DestructiveInstType = DestructiveOther;
8844   let ElementSize = ElementSizeH;
8845   let hasSideEffects = 0;
8846   let mayRaiseFPException = 1;
8849 multiclass sve_bfloat_matmul<string asm, SDPatternOperator op> {
8850   def NAME : sve_bfloat_matmul<asm>;
8851   def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv8bf16, nxv8bf16 ,!cast<Instruction>(NAME)>;
8854 class sve_bfloat_convert<bit N, string asm>
8855 : I<(outs ZPR16:$Zd), (ins ZPR16:$_Zd, PPR3bAny:$Pg, ZPR32:$Zn),
8856   asm, "\t$Zd, $Pg/m, $Zn", "", []>, Sched<[]> {
8857   bits<5> Zd;
8858   bits<3> Pg;
8859   bits<5> Zn;
8860   let Inst{31-25} = 0b0110010;
8861   let Inst{24}    = N;
8862   let Inst{23-13} = 0b10001010101;
8863   let Inst{12-10} = Pg;
8864   let Inst{9-5}   = Zn;
8865   let Inst{4-0}   = Zd;
8867   let Constraints = "$Zd = $_Zd";
8868   let DestructiveInstType = DestructiveOther;
8869   let ElementSize = ElementSizeS;
8870   let hasSideEffects = 0;
8871   let mayRaiseFPException = 1;
8874 multiclass sve_bfloat_convert<bit N, string asm, SDPatternOperator op> {
8875   def NAME : sve_bfloat_convert<N, asm>;
8876   def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i1, nxv4f32, !cast<Instruction>(NAME)>;
8879 //===----------------------------------------------------------------------===//
8880 // SVE Integer Matrix Multiply Group
8881 //===----------------------------------------------------------------------===//
8883 class sve_int_matmul<bits<2> uns, string asm>
8884 : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR8:$Zm), asm,
8885   "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8886   bits<5> Zda;
8887   bits<5> Zn;
8888   bits<5> Zm;
8889   let Inst{31-24} = 0b01000101;
8890   let Inst{23-22} = uns;
8891   let Inst{21}    = 0;
8892   let Inst{20-16} = Zm;
8893   let Inst{15-10} = 0b100110;
8894   let Inst{9-5}   = Zn;
8895   let Inst{4-0}   = Zda;
8897   let Constraints = "$Zda = $_Zda";
8898   let DestructiveInstType = DestructiveOther;
8899   let ElementSize = ZPR32.ElementSize;
8900   let hasSideEffects = 0;
8903 multiclass sve_int_matmul<bits<2> uns, string asm, SDPatternOperator op> {
8904   def NAME : sve_int_matmul<uns, asm>;
8906   def : SVE_3_Op_Pat<nxv4i32, op , nxv4i32, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
8909 //===----------------------------------------------------------------------===//
8910 // SVE Integer Dot Product Mixed Sign Group
8911 //===----------------------------------------------------------------------===//
8913 class sve_int_dot_mixed<string asm>
8914 : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR8:$Zm), asm,
8915   "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8916   bits<5> Zda;
8917   bits<5> Zn;
8918   bits<5> Zm;
8919   let Inst{31-21} = 0b01000100100;
8920   let Inst{20-16} = Zm;
8921   let Inst{15-10} = 0b011110;
8922   let Inst{9-5}   = Zn;
8923   let Inst{4-0}   = Zda;
8925   let Constraints = "$Zda = $_Zda";
8926   let DestructiveInstType = DestructiveOther;
8927   let ElementSize = ZPR32.ElementSize;
8928   let hasSideEffects = 0;
8931 multiclass sve_int_dot_mixed<string asm, SDPatternOperator op> {
8932   def NAME : sve_int_dot_mixed<asm>;
8934   def : SVE_3_Op_Pat<nxv4i32, op , nxv4i32, nxv16i8, nxv16i8, !cast<Instruction>(NAME)>;
8937 //===----------------------------------------------------------------------===//
8938 // SVE Integer Dot Product Mixed Sign - Indexed Group
8939 //===----------------------------------------------------------------------===//
8941 class sve_int_dot_mixed_indexed<bit U, string asm>
8942 : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexS32b:$idx),
8943     asm, "\t$Zda, $Zn, $Zm$idx", "", []>, Sched<[]> {
8944   bits<5> Zda;
8945   bits<5> Zn;
8946   bits<3> Zm;
8947   bits<2> idx;
8948   let Inst{31-21} = 0b01000100101;
8949   let Inst{20-19} = idx;
8950   let Inst{18-16} = Zm;
8951   let Inst{15-11} = 0b00011;
8952   let Inst{10}    = U;
8953   let Inst{9-5}   = Zn;
8954   let Inst{4-0}   = Zda;
8956   let Constraints = "$Zda = $_Zda";
8957   let DestructiveInstType = DestructiveOther;
8958   let ElementSize = ZPR32.ElementSize;
8959   let hasSideEffects = 0;
8962 multiclass sve_int_dot_mixed_indexed<bit U, string asm, SDPatternOperator op> {
8963   def NAME : sve_int_dot_mixed_indexed<U, asm>;
8965   def : SVE_4_Op_Imm_Pat<nxv4i32, op, nxv4i32, nxv16i8, nxv16i8, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
8968 //===----------------------------------------------------------------------===//
8969 // SVE Floating Point Matrix Multiply Accumulate Group
8970 //===----------------------------------------------------------------------===//
8972 class sve_fp_matrix_mla<bit sz, string asm, ZPRRegOp zprty>
8973 : I<(outs zprty:$Zda), (ins zprty:$_Zda, zprty:$Zn, zprty:$Zm),
8974     asm, "\t$Zda, $Zn, $Zm", "", []>, Sched<[]> {
8975   bits<5> Zda;
8976   bits<5> Zn;
8977   bits<5> Zm;
8978   let Inst{31-23} = 0b011001001;
8979   let Inst{22}    = sz;
8980   let Inst{21}    = 1;
8981   let Inst{20-16} = Zm;
8982   let Inst{15-10} = 0b111001;
8983   let Inst{9-5}   = Zn;
8984   let Inst{4-0}   = Zda;
8986   let Constraints = "$Zda = $_Zda";
8987   let DestructiveInstType = DestructiveOther;
8988   let ElementSize = zprty.ElementSize;
8989   let hasSideEffects = 0;
8990   let mayRaiseFPException = 1;
8993 multiclass sve_fp_matrix_mla<bit sz, string asm, ZPRRegOp zprty, SDPatternOperator op, ValueType vt> {
8994   def NAME : sve_fp_matrix_mla<sz, asm, zprty>;
8996   def : SVE_3_Op_Pat<vt, op , vt, vt, vt, !cast<Instruction>(NAME)>;
8999 //===----------------------------------------------------------------------===//
9000 // SVE Memory - Contiguous Load And Replicate 256-bit Group
9001 //===----------------------------------------------------------------------===//
9003 class sve_mem_ldor_si<bits<2> sz, string asm, RegisterOperand VecList>
9004 : I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s32:$imm4),
9005   asm, "\t$Zt, $Pg/z, [$Rn, $imm4]", "", []>, Sched<[]> {
9006   bits<5> Zt;
9007   bits<5> Rn;
9008   bits<3> Pg;
9009   bits<4> imm4;
9010   let Inst{31-25} = 0b1010010;
9011   let Inst{24-23} = sz;
9012   let Inst{22-20} = 0b010;
9013   let Inst{19-16} = imm4;
9014   let Inst{15-13} = 0b001;
9015   let Inst{12-10} = Pg;
9016   let Inst{9-5}   = Rn;
9017   let Inst{4-0}   = Zt;
9019   let hasSideEffects = 0;
9020   let mayLoad = 1;
9023 multiclass sve_mem_ldor_si<bits<2> sz, string asm, RegisterOperand listty,
9024                            ZPRRegOp zprty, ValueType Ty, ValueType PredTy, SDNode Ld1ro> {
9025   def NAME : sve_mem_ldor_si<sz, asm, listty>;
9026   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
9027                   (!cast<Instruction>(NAME) listty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
9028   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn]",
9029                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
9030   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $imm4]",
9031                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s32:$imm4), 0>;
9033   // Base addressing mode
9034   def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$Pg), GPR64sp:$base)),
9035             (!cast<Instruction>(NAME) PPR3bAny:$Pg, GPR64sp:$base, (i64 0))>;
9036   let AddedComplexity = 2 in {
9037     // Reg + Imm addressing mode
9038     def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$Pg), (add GPR64:$base, (i64 simm4s32:$imm)))),
9039               (!cast<Instruction>(NAME) $Pg, $base, simm4s32:$imm)>;
9040   }
9043 class sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand VecList,
9044                       RegisterOperand gprty>
9045 : I<(outs VecList:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm),
9046   asm, "\t$Zt, $Pg/z, [$Rn, $Rm]", "", []>, Sched<[]> {
9047   bits<5> Zt;
9048   bits<3> Pg;
9049   bits<5> Rn;
9050   bits<5> Rm;
9051   let Inst{31-25} = 0b1010010;
9052   let Inst{24-23} = sz;
9053   let Inst{22-21} = 0b01;
9054   let Inst{20-16} = Rm;
9055   let Inst{15-13} = 0;
9056   let Inst{12-10} = Pg;
9057   let Inst{9-5}   = Rn;
9058   let Inst{4-0}   = Zt;
9060   let hasSideEffects = 0;
9061   let mayLoad = 1;
9064 multiclass sve_mem_ldor_ss<bits<2> sz, string asm, RegisterOperand listty,
9065                            ZPRRegOp zprty, RegisterOperand gprty, ValueType Ty,
9066                            ValueType PredTy, SDNode Ld1ro, ComplexPattern AddrCP> {
9067   def NAME : sve_mem_ldor_ss<sz, asm, listty, gprty>;
9069   def : InstAlias<asm # "\t$Zt, $Pg/z, [$Rn, $Rm]",
9070                   (!cast<Instruction>(NAME) zprty:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprty:$Rm), 0>;
9072   def : Pat<(Ty (Ld1ro (PredTy PPR3bAny:$gp), (AddrCP GPR64sp:$base, gprty:$offset))),
9073             (!cast<Instruction>(NAME) PPR3bAny:$gp, GPR64sp:$base, gprty:$offset)>;
9076 //===----------------------------------------------------------------------===//
9077 // SVE Interleave 128-bit Elements Group
9078 //===----------------------------------------------------------------------===//
9080 class sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm>
9081 : I<(outs ZPR128:$Zd), (ins ZPR128:$Zn, ZPR128:$Zm),
9082   asm, "\t$Zd, $Zn, $Zm",
9083   "",
9084   []>, Sched<[]> {
9085   bits<5> Zd;
9086   bits<5> Zm;
9087   bits<5> Zn;
9088   let Inst{31-21} = 0b00000101101;
9089   let Inst{20-16} = Zm;
9090   let Inst{15-13} = 0b000;
9091   let Inst{12-11} = opc;
9092   let Inst{10}    = P;
9093   let Inst{9-5}   = Zn;
9094   let Inst{4-0}   = Zd;
9096   let hasSideEffects = 0;
9099 multiclass sve_int_perm_bin_perm_128_zz<bits<2> opc, bit P, string asm, SDPatternOperator op> {
9100   def NAME : sve_int_perm_bin_perm_128_zz<opc, P, asm>;
9102   def : SVE_2_Op_Pat<nxv16i8,  op, nxv16i8,  nxv16i8,  !cast<Instruction>(NAME)>;
9103   def : SVE_2_Op_Pat<nxv8i16,  op, nxv8i16,  nxv8i16,  !cast<Instruction>(NAME)>;
9104   def : SVE_2_Op_Pat<nxv8f16,  op, nxv8f16,  nxv8f16,  !cast<Instruction>(NAME)>;
9105   def : SVE_2_Op_Pat<nxv4i32,  op, nxv4i32,  nxv4i32,  !cast<Instruction>(NAME)>;
9106   def : SVE_2_Op_Pat<nxv4f32,  op, nxv4f32,  nxv4f32,  !cast<Instruction>(NAME)>;
9107   def : SVE_2_Op_Pat<nxv2i64,  op, nxv2i64,  nxv2i64,  !cast<Instruction>(NAME)>;
9108   def : SVE_2_Op_Pat<nxv2f64,  op, nxv2f64,  nxv2f64,  !cast<Instruction>(NAME)>;
9109   def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
9112 /// Addressing modes
9113 def am_sve_indexed_s4 :ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-8,7>", [], [SDNPWantRoot]>;
9114 def am_sve_indexed_s6 :ComplexPattern<iPTR, 2, "SelectAddrModeIndexedSVE<-32,31>", [], [SDNPWantRoot]>;
9116 def am_sve_regreg_lsl0 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<0>", []>;
9117 def am_sve_regreg_lsl1 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<1>", []>;
9118 def am_sve_regreg_lsl2 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<2>", []>;
9119 def am_sve_regreg_lsl3 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<3>", []>;
9120 def am_sve_regreg_lsl4 : ComplexPattern<iPTR, 2, "SelectSVERegRegAddrMode<4>", []>;
9122 // Predicated pseudo floating point two operand instructions.
9123 multiclass sve_fp_bin_pred_hfd<SDPatternOperator op> {
9124   def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9125   def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9126   def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9128   def : SVE_3_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9129   def : SVE_3_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9130   def : SVE_3_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9131   def : SVE_3_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9132   def : SVE_3_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9133   def : SVE_3_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9136 // Predicated pseudo floating point three operand instructions.
9137 multiclass sve_fp_3op_pred_hfd<SDPatternOperator op> {
9138   def _H_UNDEF : PredThreeOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9139   def _S_UNDEF : PredThreeOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9140   def _D_UNDEF : PredThreeOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9142   def : SVE_4_Op_Pat<nxv8f16, op, nxv8i1, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9143   def : SVE_4_Op_Pat<nxv4f16, op, nxv4i1, nxv4f16, nxv4f16, nxv4f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9144   def : SVE_4_Op_Pat<nxv2f16, op, nxv2i1, nxv2f16, nxv2f16, nxv2f16, !cast<Instruction>(NAME # _H_UNDEF)>;
9145   def : SVE_4_Op_Pat<nxv4f32, op, nxv4i1, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S_UNDEF)>;
9146   def : SVE_4_Op_Pat<nxv2f32, op, nxv2i1, nxv2f32, nxv2f32, nxv2f32, !cast<Instruction>(NAME # _S_UNDEF)>;
9147   def : SVE_4_Op_Pat<nxv2f64, op, nxv2i1, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D_UNDEF)>;
9150 multiclass sve_fp_3op_pred_bf<SDPatternOperator op> {
9151   def _UNDEF : PredThreeOpPseudo<NAME, ZPR16, FalseLanesUndef>;
9153   def : SVE_4_Op_Pat<nxv8bf16, op, nxv8i1, nxv8bf16, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _UNDEF)>;
9156 // Predicated pseudo integer two operand instructions.
9157 multiclass sve_int_bin_pred_bhsd<SDPatternOperator op> {
9158   def _B_UNDEF : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesUndef>;
9159   def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9160   def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9161   def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9163   def : SVE_3_Op_Pat<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
9164   def : SVE_3_Op_Pat<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9165   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9166   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9169 // As sve_int_bin_pred but when only i32 and i64 vector types are required.
9170 multiclass sve_int_bin_pred_sd<SDPatternOperator op> {
9171   def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9172   def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9174   def : SVE_3_Op_Pat<nxv4i32, op, nxv4i1, nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9175   def : SVE_3_Op_Pat<nxv2i64, op, nxv2i1, nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9178 // Predicated pseudo integer two operand instructions. Second operand is an
9179 // immediate specified by imm_[bhsd].
9180 multiclass sve_int_shift_pred_bhsd<SDPatternOperator op,
9181                                    ComplexPattern imm_b, ComplexPattern imm_h,
9182                                    ComplexPattern imm_s, ComplexPattern imm_d> {
9183   def _B_UNDEF : PredTwoOpImmPseudo<NAME # _B, ZPR8,  Operand<i32>, FalseLanesUndef>;
9184   def _H_UNDEF : PredTwoOpImmPseudo<NAME # _H, ZPR16, Operand<i32>, FalseLanesUndef>;
9185   def _S_UNDEF : PredTwoOpImmPseudo<NAME # _S, ZPR32, Operand<i32>, FalseLanesUndef>;
9186   def _D_UNDEF : PredTwoOpImmPseudo<NAME # _D, ZPR64, Operand<i32>, FalseLanesUndef>;
9188   def : SVE_Shift_DupImm_Pred_Pat<nxv16i8, op, nxv16i1, i32, imm_b, !cast<Instruction>(NAME # _B_UNDEF)>;
9189   def : SVE_Shift_DupImm_Pred_Pat<nxv8i16, op, nxv8i1,  i32, imm_h, !cast<Instruction>(NAME # _H_UNDEF)>;
9190   def : SVE_Shift_DupImm_Pred_Pat<nxv4i32, op, nxv4i1,  i32, imm_s, !cast<Instruction>(NAME # _S_UNDEF)>;
9191   def : SVE_Shift_DupImm_Pred_Pat<nxv2i64, op, nxv2i1,  i64, imm_d, !cast<Instruction>(NAME # _D_UNDEF)>;
9194 multiclass sve_int_bin_pred_all_active_bhsd<SDPatternOperator op> {
9195   def _B_UNDEF : PredTwoOpPseudo<NAME # _B, ZPR8, FalseLanesUndef>;
9196   def _H_UNDEF : PredTwoOpPseudo<NAME # _H, ZPR16, FalseLanesUndef>;
9197   def _S_UNDEF : PredTwoOpPseudo<NAME # _S, ZPR32, FalseLanesUndef>;
9198   def _D_UNDEF : PredTwoOpPseudo<NAME # _D, ZPR64, FalseLanesUndef>;
9200   def : SVE_2_Op_Pred_All_Active_Pt<nxv16i8, op, nxv16i1, nxv16i8, nxv16i8, !cast<Pseudo>(NAME # _B_UNDEF)>;
9201   def : SVE_2_Op_Pred_All_Active_Pt<nxv8i16, op, nxv8i1,  nxv8i16, nxv8i16, !cast<Pseudo>(NAME # _H_UNDEF)>;
9202   def : SVE_2_Op_Pred_All_Active_Pt<nxv4i32, op, nxv4i1,  nxv4i32, nxv4i32, !cast<Pseudo>(NAME # _S_UNDEF)>;
9203   def : SVE_2_Op_Pred_All_Active_Pt<nxv2i64, op, nxv2i1,  nxv2i64, nxv2i64, !cast<Pseudo>(NAME # _D_UNDEF)>;
9206 //===----------------------------------------------------------------------===//
9207 // SME2 or SVE2.1 Instructions
9208 //===----------------------------------------------------------------------===//
9210 class sve2p1_fclamp<string asm, bits<2> sz, ZPRRegOp zpr_ty>
9211     : I<(outs zpr_ty:$Zd), (ins zpr_ty:$_Zd, zpr_ty:$Zn, zpr_ty:$Zm),
9212         asm, "\t$Zd, $Zn, $Zm", "", []>,
9213       Sched<[]> {
9214   bits<5> Zm;
9215   bits<5> Zn;
9216   bits<5> Zd;
9217   let Inst{31-24} = 0b01100100;
9218   let Inst{23-22} = sz;
9219   let Inst{21}    = 0b1;
9220   let Inst{20-16} = Zm;
9221   let Inst{15-10} = 0b001001;
9222   let Inst{9-5}   = Zn;
9223   let Inst{4-0}   = Zd;
9225   let Constraints = "$Zd = $_Zd";
9226   let DestructiveInstType = DestructiveOther;
9227   let ElementSize = zpr_ty.ElementSize;
9228   let hasSideEffects = 0;
9231 multiclass sve2p1_fclamp<string asm, SDPatternOperator op> {
9232   def _H : sve2p1_fclamp<asm, 0b01, ZPR16>;
9233   def _S : sve2p1_fclamp<asm, 0b10, ZPR32>;
9234   def _D : sve2p1_fclamp<asm, 0b11, ZPR64>;
9236   def : SVE_3_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
9237   def : SVE_3_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
9238   def : SVE_3_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
9241 multiclass sve2p1_bfclamp<string asm, SDPatternOperator op> {
9242   def NAME : sve2p1_fclamp<asm, 0b00, ZPR16>;
9243   def : SVE_3_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME)>;
9246 // SVE two-way dot product
9247 class sve2p1_two_way_dot_vv<string mnemonic, bit u>
9248     : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR16:$Zm),
9249         mnemonic, "\t$Zda, $Zn, $Zm",
9250         "", []>, Sched<[]> {
9251   bits<5> Zda;
9252   bits<5> Zn;
9253   bits<5> Zm;
9254   let Inst{31-21} = 0b01000100000;
9255   let Inst{20-16} = Zm;
9256   let Inst{15-11} = 0b11001;
9257   let Inst{10}    = u;
9258   let Inst{9-5}   = Zn;
9259   let Inst{4-0}   = Zda;
9261   let Constraints = "$Zda = $_Zda";
9262   let DestructiveInstType = DestructiveOther;
9263   let hasSideEffects = 0;
9266 multiclass sve2p1_two_way_dot_vv<string mnemonic, bit u, SDPatternOperator intrinsic> {
9267   def NAME : sve2p1_two_way_dot_vv<mnemonic, u>;
9269   def : SVE_3_Op_Pat<nxv4i32, intrinsic, nxv4i32, nxv8i16, nxv8i16, !cast<Instruction>(NAME)>;
9272 // SVE two-way dot product (indexed)
9273 class sve2p1_two_way_dot_vvi<string mnemonic, bit u>
9274     : I<(outs ZPR32:$Zda), (ins ZPR32:$_Zda, ZPR16:$Zn, ZPR3b16:$Zm, VectorIndexS32b:$i2),
9275         mnemonic, "\t$Zda, $Zn, $Zm$i2",
9276         "", []>, Sched<[]> {
9277   bits<5> Zda;
9278   bits<5> Zn;
9279   bits<3> Zm;
9280   bits<2> i2;
9281   let Inst{31-21} = 0b01000100100;
9282   let Inst{20-19} = i2;
9283   let Inst{18-16} = Zm;
9284   let Inst{15-11} = 0b11001;
9285   let Inst{10}    = u;
9286   let Inst{9-5}   = Zn;
9287   let Inst{4-0}   = Zda;
9289   let Constraints = "$Zda = $_Zda";
9290   let DestructiveInstType = DestructiveOther;
9291   let hasSideEffects = 0;
9294 multiclass sve2p1_two_way_dot_vvi<string mnemonic, bit u, SDPatternOperator intrinsic> {
9295   def NAME : sve2p1_two_way_dot_vvi<mnemonic, u>;
9297   def : SVE_4_Op_Imm_Pat<nxv4i32, intrinsic, nxv4i32, nxv8i16, nxv8i16, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME)>;
9300 class sve2p1_ptrue_pn<string mnemonic, bits<2> sz, PNRP8to15RegOp pnrty, SDPatternOperator op>
9301     : I<(outs pnrty:$PNd), (ins ), mnemonic, "\t$PNd",
9302         "", [(set pnrty:$PNd, (op))]>, Sched<[]> {
9303   bits<3> PNd;
9304   let Inst{31-24}  = 0b00100101;
9305   let Inst{23-22} = sz;
9306   let Inst{21-3}  = 0b1000000111100000010;
9307   let Inst{2-0}   = PNd;
9309   let hasSideEffects = 0;
9310   let isReMaterializable = 1;
9314 multiclass sve2p1_ptrue_pn<string mnemonic> {
9315  def _B : sve2p1_ptrue_pn<mnemonic, 0b00, PNR8_p8to15, int_aarch64_sve_ptrue_c8>;
9316  def _H : sve2p1_ptrue_pn<mnemonic, 0b01, PNR16_p8to15, int_aarch64_sve_ptrue_c16>;
9317  def _S : sve2p1_ptrue_pn<mnemonic, 0b10, PNR32_p8to15, int_aarch64_sve_ptrue_c32>;
9318  def _D : sve2p1_ptrue_pn<mnemonic, 0b11, PNR64_p8to15, int_aarch64_sve_ptrue_c64>;
9322 // SVE extract mask predicate from predicate-as-counter
9323 class sve2p1_pred_as_ctr_to_mask_base<string mnemonic, bits<2> sz, bits<3> opc,
9324                                       RegisterOperand pprty, Operand idxty>
9325     : I<(outs pprty:$Pd), (ins PNRAny_p8to15:$PNn, idxty:$index),
9326         mnemonic, "\t$Pd, $PNn$index",
9327         "", []>, Sched<[]> {
9328   bits<4> Pd;
9329   bits<3> PNn;
9330   bits<2> imm2;
9331   let Inst{31-24} = 0b00100101;
9332   let Inst{23-22} = sz;
9333   let Inst{21-11} = 0b10000001110;
9334   let Inst{10-8}  = opc;
9335   let Inst{7-5}   = PNn;
9336   let Inst{4}     = 0b1;
9337   let Inst{3-0}   = Pd;
9339   let hasSideEffects = 0;
9342 class sve2p1_pred_as_ctr_to_mask<string mnemonic, bits<2> sz, PPRRegOp pprty>
9343     : sve2p1_pred_as_ctr_to_mask_base<mnemonic, sz, {0, ?, ?}, pprty, VectorIndexS32b_timm> {
9344   bits<2> index;
9345   let Inst{9-8} = index;
9348 multiclass sve2p1_pred_as_ctr_to_mask<string mnemonic, SDPatternOperator op> {
9349  def _B : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b00, PPR8>;
9350  def _H : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b01, PPR16>;
9351  def _S : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b10, PPR32>;
9352  def _D : sve2p1_pred_as_ctr_to_mask<mnemonic, 0b11, PPR64>;
9354  def : SVE_2_Op_Imm_Pat<nxv16i1, op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _B)>;
9355  def : SVE_2_Op_Imm_Pat<nxv8i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _H)>;
9356  def : SVE_2_Op_Imm_Pat<nxv4i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _S)>;
9357  def : SVE_2_Op_Imm_Pat<nxv2i1,  op, aarch64svcount, i32, VectorIndexS32b_timm, !cast<Instruction>(NAME # _D)>;
9361 class sve2p1_pred_as_ctr_to_mask_pair<string mnemonic, bits<2> sz, RegisterOperand pprty>
9362     : sve2p1_pred_as_ctr_to_mask_base<mnemonic, sz, {1, 0, ?}, pprty, VectorIndexD> {
9363   bit index;
9364   let Inst{8}    = index;
9367 multiclass sve2p1_pred_as_ctr_to_mask_pair<string mnemonic> {
9368  def _B : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b00, PP_b>;
9369  def _H : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b01, PP_h>;
9370  def _S : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b10, PP_s>;
9371  def _D : sve2p1_pred_as_ctr_to_mask_pair<mnemonic, 0b11, PP_d>;
9375 // SME2 multi-vec extract narrow
9376 class sve2p1_multi_vec_extract_narrow<string mnemonic, bits<2> opc, bits<3> tsz>
9377     : I<(outs ZPR16:$Zd), (ins ZZ_s_mul_r:$Zn),
9378         mnemonic, "\t$Zd, $Zn",
9379         "", []>, Sched<[]> {
9380   bits<5> Zd;
9381   bits<4> Zn;
9382   let Inst{31-23} = 0b010001010;
9383   let Inst{22}    = tsz{2};
9384   let Inst{21}    = 0b1;
9385   let Inst{20-19} = tsz{1-0};
9386   let Inst{18-13} = 0b001010;
9387   let Inst{12-11} = opc;
9388   let Inst{10}    = 0b0;
9389   let Inst{9-6}   = Zn;
9390   let Inst{5}     = 0b0;
9391   let Inst{4-0}   = Zd;
9393   let hasSideEffects = 0;
9396 multiclass sve2p1_multi_vec_extract_narrow<string mnemonic, bits<2> opc, SDPatternOperator intrinsic> {
9397   def NAME : sve2p1_multi_vec_extract_narrow<mnemonic, opc, 0b010>;
9398   def : SVE2p1_Cvt_VG2_Pat<NAME, intrinsic, nxv8i16, nxv4i32>;
9401 // SVE2 multi-vec shift narrow
9402 class sve2p1_multi_vec_shift_narrow<string mnemonic, bits<3> opc, bits<2> tsz>
9403     : I<(outs ZPR16:$Zd), (ins ZZ_s_mul_r:$Zn, tvecshiftR16:$imm4),
9404         mnemonic, "\t$Zd, $Zn, $imm4",
9405         "", []>, Sched<[]> {
9406   bits<5> Zd;
9407   bits<4> Zn;
9408   bits<4> imm4;
9409   let Inst{31-23} = 0b010001011;
9410   let Inst{22}    = tsz{1};
9411   let Inst{21}    = 0b1;
9412   let Inst{20}    = tsz{0};
9413   let Inst{19-16} = imm4;
9414   let Inst{15-14} = 0b00;
9415   let Inst{13-11} = opc;
9416   let Inst{10}    = 0b0;
9417   let Inst{9-6}   = Zn;
9418   let Inst{5}     = 0b0;
9419   let Inst{4-0}   = Zd;
9421   let hasSideEffects = 0;
9424 multiclass sve2p1_multi_vec_shift_narrow<string mnemonic, bits<3> opc, SDPatternOperator intrinsic> {
9425   def NAME : sve2p1_multi_vec_shift_narrow<mnemonic, opc, 0b01>;
9427   def : SVE2p1_Sat_Shift_VG2_Pat<NAME, intrinsic, nxv8i16, nxv4i32, tvecshiftR16>;
9431 // SME2 multi-vec contiguous load (scalar plus scalar, two registers)
9432 class sve2p1_mem_cld_ss_2z<string mnemonic, bits<2> msz, bit n,
9433                          RegisterOperand vector_ty, RegisterOperand gpr_ty>
9434     : I<(outs vector_ty:$Zt),
9435         (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9436         mnemonic, "\t$Zt, $PNg/z, [$Rn, $Rm]",
9437         "", []>, Sched<[]> {
9438   bits<4> Zt;
9439   bits<5> Rm;
9440   bits<5> Rn;
9441   bits<3> PNg;
9442   let Inst{31-21} = 0b10100000000;
9443   let Inst{20-16} = Rm;
9444   let Inst{15}    = 0b0;
9445   let Inst{14-13} = msz;
9446   let Inst{12-10} = PNg;
9447   let Inst{9-5} = Rn;
9448   let Inst{4-1} = Zt;
9449   let Inst{0}   = n;
9451   let hasSideEffects = 0;
9452   let mayLoad = 1;
9455 multiclass sve2p1_mem_cld_ss_2z<string mnemonic, bits<2> msz, bit n,
9456                          RegisterOperand vector_ty, RegisterOperand gpr_ty, RegisterOperand vector_pseudo_ty> {
9457   def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm), []>;
9458   def NAME : sve2p1_mem_cld_ss_2z<mnemonic, msz, n, vector_ty, gpr_ty>;
9461 // SME2 multi-vec contiguous load (scalar plus immediate, two registers)
9462 class sve2p1_mem_cld_si_2z<string mnemonic, bits<2> msz, bit n,
9463                          RegisterOperand vector_ty>
9464     : I<(outs vector_ty:$Zt),
9465         (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4),
9466         mnemonic, "\t$Zt, $PNg/z, [$Rn, $imm4, mul vl]",
9467         "", []>, Sched<[]> {
9468   bits<4> Zt;
9469   bits<5> Rn;
9470   bits<3> PNg;
9471   bits<4> imm4;
9472   let Inst{31-20} = 0b101000000100;
9473   let Inst{19-16} = imm4;
9474   let Inst{15}    = 0b0;
9475   let Inst{14-13} = msz;
9476   let Inst{12-10} = PNg;
9477   let Inst{9-5}   = Rn;
9478   let Inst{4-1}   = Zt;
9479   let Inst{0}     = n;
9481   let hasSideEffects = 0;
9482   let mayLoad = 1;
9485 multiclass sve2p1_mem_cld_si_2z<string mnemonic, bits<2> msz, bit n,
9486                               RegisterOperand vector_ty, RegisterOperand vector_pseudo_ty> {
9487   def NAME : sve2p1_mem_cld_si_2z<mnemonic, msz, n, vector_ty>;
9488   def : InstAlias<mnemonic # " $Zt, $PNg/z, [$Rn]",
9489                   (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9490   def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4), []>;
9493 // SME2 multi-vec contiguous load (scalar plus scalar, four registers)
9494 class sve2p1_mem_cld_ss_4z<string mnemonic, bits<2> msz, bit n,
9495                          RegisterOperand vector_ty, RegisterOperand gpr_ty>
9496     : I<(outs vector_ty:$Zt),
9497         (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9498         mnemonic, "\t$Zt, $PNg/z, [$Rn, $Rm]",
9499         "", []>, Sched<[]> {
9500   bits<3> Zt;
9501   bits<5> Rm;
9502   bits<5> Rn;
9503   bits<3> PNg;
9504   let Inst{31-21} = 0b10100000000;
9505   let Inst{20-16} = Rm;
9506   let Inst{15}    = 0b1;
9507   let Inst{14-13} = msz;
9508   let Inst{12-10} = PNg;
9509   let Inst{9-5} = Rn;
9510   let Inst{4-2} = Zt;
9511   let Inst{1}   = 0b0;
9512   let Inst{0}   = n;
9514   let hasSideEffects = 0;
9515   let mayLoad = 1;
9518 multiclass sve2p1_mem_cld_ss_4z<string mnemonic, bits<2> msz, bit n,
9519                          RegisterOperand vector_ty, RegisterOperand gpr_ty, RegisterOperand vector_pseudo_ty> {
9520   def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm), []>;
9521   def NAME : sve2p1_mem_cld_ss_4z<mnemonic, msz, n, vector_ty, gpr_ty>;
9524 // SME2 multi-vec contiguous load (scalar plus immediate, four registers)
9525 class sve2p1_mem_cld_si_4z<string mnemonic, bits<2> msz, bit n,
9526                          RegisterOperand vector_ty>
9527     : I<(outs vector_ty:$Zt),
9528         (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4),
9529         mnemonic, "\t$Zt, $PNg/z, [$Rn, $imm4, mul vl]",
9530         "", []>, Sched<[]> {
9531   bits<3> Zt;
9532   bits<5> Rn;
9533   bits<3> PNg;
9534   bits<4> imm4;
9535   let Inst{31-20} = 0b101000000100;
9536   let Inst{19-16} = imm4;
9537   let Inst{15}    = 0b1;
9538   let Inst{14-13} = msz;
9539   let Inst{12-10} = PNg;
9540   let Inst{9-5}   = Rn;
9541   let Inst{4-2}   = Zt;
9542   let Inst{1}     = 0b0;
9543   let Inst{0}     = n;
9545   let hasSideEffects = 0;
9546   let mayLoad = 1;
9549 multiclass sve2p1_mem_cld_si_4z<string mnemonic, bits<2> msz, bit n,
9550                               RegisterOperand vector_ty, RegisterOperand vector_pseudo_ty> {
9551   def NAME : sve2p1_mem_cld_si_4z<mnemonic, msz, n, vector_ty>;
9552   def : InstAlias<mnemonic # " $Zt, $PNg/z, [$Rn]",
9553                   (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9554   def NAME # _PSEUDO : Pseudo<(outs vector_pseudo_ty:$Zt), (ins PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4), []>;
9557 // SME2 multi-vec contiguous store (scalar plus scalar, two registers)
9558 class sve2p1_mem_cst_ss_2z<string mnemonic, bits<2> msz, bit n,
9559                            RegisterOperand vector_ty, RegisterOperand gpr_ty>
9560     : I<(outs ),
9561         (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9562         mnemonic, "\t$Zt, $PNg, [$Rn, $Rm]",
9563         "", []>, Sched<[]> {
9564   bits<4> Zt;
9565   bits<5> Rm;
9566   bits<5> Rn;
9567   bits<3> PNg;
9568   let Inst{31-21} = 0b10100000001;
9569   let Inst{20-16} = Rm;
9570   let Inst{15}    = 0b0;
9571   let Inst{14-13} = msz;
9572   let Inst{12-10} = PNg;
9573   let Inst{9-5} = Rn;
9574   let Inst{4-1} = Zt;
9575   let Inst{0}   = n;
9577   let hasSideEffects = 0;
9578   let mayStore = 1;
9582 // SME2 multi-vec contiguous store (scalar plus immediate, two registers)
9583 class sve2p1_mem_cst_si_2z<string mnemonic, bits<2> msz, bit n,
9584                            RegisterOperand vector_ty>
9585     : I<(outs ),
9586         (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s2:$imm4),
9587         mnemonic, "\t$Zt, $PNg, [$Rn, $imm4, mul vl]",
9588         "", []>, Sched<[]> {
9589   bits<4> Zt;
9590   bits<5> Rn;
9591   bits<3> PNg;
9592   bits<4> imm4;
9593   let Inst{31-20} = 0b101000000110;
9594   let Inst{19-16} = imm4;
9595   let Inst{15}    = 0b0;
9596   let Inst{14-13} = msz;
9597   let Inst{12-10} = PNg;
9598   let Inst{9-5}   = Rn;
9599   let Inst{4-1}   = Zt;
9600   let Inst{0}     = n;
9602   let hasSideEffects = 0;
9603   let mayStore = 1;
9607 multiclass sve2p1_mem_cst_si_2z<string mnemonic, bits<2> msz, bit n,
9608                               RegisterOperand vector_ty> {
9609   def NAME : sve2p1_mem_cst_si_2z<mnemonic, msz, n, vector_ty>;
9611   def : InstAlias<mnemonic # " $Zt, $PNg, [$Rn]",
9612                   (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, 0), 1>;
9616 // SME2 multi-vec contiguous store (scalar plus scalar, four registers)
9617 class sve2p1_mem_cst_ss_4z<string mnemonic, bits<2> msz, bit n,
9618                            RegisterOperand vector_ty, RegisterOperand gpr_ty>
9619     : I<(outs ),
9620         (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, gpr_ty:$Rm),
9621         mnemonic, "\t$Zt, $PNg, [$Rn, $Rm]",
9622         "", []>, Sched<[]> {
9623   bits<3> Zt;
9624   bits<5> Rm;
9625   bits<5> Rn;
9626   bits<3> PNg;
9627   let Inst{31-21} = 0b10100000001;
9628   let Inst{20-16} = Rm;
9629   let Inst{15}    = 0b1;
9630   let Inst{14-13} = msz;
9631   let Inst{12-10} = PNg;
9632   let Inst{9-5} = Rn;
9633   let Inst{4-2} = Zt;
9634   let Inst{1}   = 0b0;
9635   let Inst{0}   = n;
9637   let mayStore = 1;
9641 // SME2 multi-vec contiguous store (scalar plus immediate, four registers)
9642 class sve2p1_mem_cst_si_4z<string mnemonic, bits<2> msz, bit n,
9643                            RegisterOperand vector_ty>
9644     : I<(outs ),
9645         (ins vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn, simm4s4:$imm4),
9646         mnemonic, "\t$Zt, $PNg, [$Rn, $imm4, mul vl]",
9647         "", []>, Sched<[]> {
9648   bits<3> Zt;
9649   bits<5> Rn;
9650   bits<3> PNg;
9651   bits<4> imm4;
9652   let Inst{31-20} = 0b101000000110;
9653   let Inst{19-16} = imm4;
9654   let Inst{15}    = 0b1;
9655   let Inst{14-13} = msz;
9656   let Inst{12-10} = PNg;
9657   let Inst{9-5}   = Rn;
9658   let Inst{4-2}   = Zt;
9659   let Inst{1}     = 0b0;
9660   let Inst{0}     = n;
9662   let hasSideEffects = 0;
9663   let mayStore = 1;
9667 multiclass sve2p1_mem_cst_si_4z<string mnemonic, bits<2> msz, bit n,
9668                                 RegisterOperand vector_ty> {
9669   def NAME : sve2p1_mem_cst_si_4z<mnemonic, msz, n, vector_ty>;
9671   def : InstAlias<mnemonic # " $Zt, $PNg, [$Rn]",
9672                   (!cast<Instruction>(NAME) vector_ty:$Zt, PNRAny_p8to15:$PNg, GPR64sp:$Rn,0), 1>;
9675 // SVE predicate count (predicate-as-counter)
9676 class sve2p1_pcount_pn<string mnemonic, bits<3> opc, bits<2> sz, PNRRegOp pnrty>
9677    : I<(outs GPR64:$Rd),
9678        (ins pnrty:$PNn, sve_vec_len_specifier_enum:$vl),
9679        mnemonic, "\t$Rd, $PNn, $vl",
9680        "", []>, Sched<[]> {
9681   bits<5> Rd;
9682   bits<4> PNn;
9683   bits<1> vl;
9684   let Inst{31-24} = 0b00100101;
9685   let Inst{23-22} = sz;
9686   let Inst{21-19} = 0b100;
9687   let Inst{18-16} = opc;
9688   let Inst{15-11} = 0b10000;
9689   let Inst{10}    = vl;
9690   let Inst{9}     = 0b1;
9691   let Inst{8-5}   = PNn;
9692   let Inst{4-0}   = Rd;
9694   let hasSideEffects = 0;
9697 multiclass sve2p1_pcount_pn<string mnemonic, bits<3> opc> {
9698   def _B : sve2p1_pcount_pn<mnemonic, opc, 0b00, PNR8>;
9699   def _H : sve2p1_pcount_pn<mnemonic, opc, 0b01, PNR16>;
9700   def _S : sve2p1_pcount_pn<mnemonic, opc, 0b10, PNR32>;
9701   def _D : sve2p1_pcount_pn<mnemonic, opc, 0b11, PNR64>;
9703   defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c8,  aarch64svcount, !cast<Instruction>(NAME # _B)>;
9704   defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c16, aarch64svcount, !cast<Instruction>(NAME # _H)>;
9705   defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c32, aarch64svcount, !cast<Instruction>(NAME # _S)>;
9706   defm : SVE2p1_Cntp_Pat<i64, int_aarch64_sve_cntp_c64, aarch64svcount, !cast<Instruction>(NAME # _D)>;
9710 // SVE integer compare scalar count and limit (predicate-as-counter)
9711 class sve2p1_int_while_rr_pn<string mnemonic, bits<2> sz, bits<3> opc,
9712                              PNRP8to15RegOp pnrty>
9713     : I<(outs pnrty:$PNd), (ins GPR64:$Rn, GPR64:$Rm, sve_vec_len_specifier_enum:$vl),
9714         mnemonic, "\t$PNd, $Rn, $Rm, $vl",
9715         "", []>, Sched<[]> {
9716   bits<3> PNd;
9717   bits<5> Rn;
9718   bits<1> vl;
9719   bits<5> Rm;
9720   let Inst{31-24} = 0b00100101;
9721   let Inst{23-22} = sz;
9722   let Inst{21}    = 0b1;
9723   let Inst{20-16} = Rm;
9724   let Inst{15-14} = 0b01;
9725   let Inst{13}    = vl;
9726   let Inst{12}    = 0b0;
9727   let Inst{11-10} = opc{2-1};
9728   let Inst{9-5}   = Rn;
9729   let Inst{4}     = 0b1;
9730   let Inst{3}     = opc{0};
9731   let Inst{2-0}   = PNd;
9733   let Defs = [NZCV];
9734   let hasSideEffects = 0;
9738 multiclass sve2p1_int_while_rr_pn<string mnemonic, bits<3> opc> {
9739  def _B : sve2p1_int_while_rr_pn<mnemonic, 0b00, opc, PNR8_p8to15>;
9740  def _H : sve2p1_int_while_rr_pn<mnemonic, 0b01, opc, PNR16_p8to15>;
9741  def _S : sve2p1_int_while_rr_pn<mnemonic, 0b10, opc, PNR32_p8to15>;
9742  def _D : sve2p1_int_while_rr_pn<mnemonic, 0b11, opc, PNR64_p8to15>;
9744  defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c8"),
9745                             i64, !cast<Instruction>(NAME # _B)>;
9746  defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c16"),
9747                             i64, !cast<Instruction>(NAME # _H)>;
9748  defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c32"),
9749                             i64, !cast<Instruction>(NAME # _S)>;
9750  defm : SVE2p1_While_PN_Pat<aarch64svcount, !cast<SDPatternOperator>("int_aarch64_sve_" # mnemonic # "_c64"),
9751                             i64, !cast<Instruction>(NAME # _D)>;
9755 // SVE integer compare scalar count and limit (predicate pair)
9756 class sve2p1_int_while_rr_pair<string mnemonic, bits<2> sz, bits<3> opc,
9757                              RegisterOperand ppr_ty>
9758     : I<(outs ppr_ty:$Pd), (ins GPR64:$Rn, GPR64:$Rm),
9759         mnemonic, "\t$Pd, $Rn, $Rm",
9760         "", []>, Sched<[]> {
9761   bits<3> Pd;
9762   bits<5> Rn;
9763   bits<5> Rm;
9764   let Inst{31-24} = 0b00100101;
9765   let Inst{23-22} = sz;
9766   let Inst{21}    = 0b1;
9767   let Inst{20-16} = Rm;
9768   let Inst{15-12} = 0b0101;
9769   let Inst{11-10} = opc{2-1};
9770   let Inst{9-5}   = Rn;
9771   let Inst{4}     = 0b1;
9772   let Inst{3-1}   = Pd;
9773   let Inst{0}     = opc{0};
9775   let Defs = [NZCV];
9776   let hasSideEffects = 0;
9780 multiclass sve2p1_int_while_rr_pair<string mnemonic, bits<3> opc> {
9781  def _B : sve2p1_int_while_rr_pair<mnemonic, 0b00, opc, PP_b_mul_r>;
9782  def _H : sve2p1_int_while_rr_pair<mnemonic, 0b01, opc, PP_h_mul_r>;
9783  def _S : sve2p1_int_while_rr_pair<mnemonic, 0b10, opc, PP_s_mul_r>;
9784  def _D : sve2p1_int_while_rr_pair<mnemonic, 0b11, opc, PP_d_mul_r>;
9788 class sve_mem_128b_gld_64_unscaled<string mnemonic>
9789     : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
9790         mnemonic, "\t$Zt, $Pg/z, [$Zn, $Rm]",
9791         "", []>, Sched<[]> {
9792   bits<5> Zt;
9793   bits<5> Zn;
9794   bits<3> Pg;
9795   bits<5> Rm;
9796   let Inst{31-21} = 0b11000100000;
9797   let Inst{20-16} = Rm;
9798   let Inst{15-13} = 0b101;
9799   let Inst{12-10} = Pg;
9800   let Inst{9-5}   = Zn;
9801   let Inst{4-0}   = Zt;
9803   let hasSideEffects = 0;
9804   let mayLoad = 1;
9808 multiclass sve_mem_128b_gld_64_unscaled<string mnemonic, SDPatternOperator op> {
9809   def NAME : sve_mem_128b_gld_64_unscaled<mnemonic>;
9811   def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Zn]",
9812                   (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
9815   def : Pat<(nxv2i64 (op (nxv2i1 PPR3bAny:$Pg),  (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2i64)),
9816             (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9817   def : Pat<(nxv4i32 (op (nxv4i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn),  (i64 GPR64sp:$Rm), nxv4i32)),
9818             (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9819   def : Pat<(nxv8i16 (op (nxv8i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8i16)),
9820             (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9821   def : Pat<(nxv16i8 (op (nxv16i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv16i8)),
9822             (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9824   def : Pat<(nxv2f64 (op (nxv2i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2f64)),
9825             (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9826   def : Pat<(nxv4f32 (op (nxv4i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv4f32)),
9827             (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9828   def : Pat<(nxv8f16 (op (nxv8i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8f16)),
9829             (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9830   def : Pat<(nxv8bf16 (op (nxv8i1 PPR3bAny:$Pg), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8bf16)),
9831             (!cast<Instruction>(NAME) PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm)>;
9834 class sve_mem_sst_128b_64_unscaled<string mnemonic>
9835     : I<(outs ), (ins Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, GPR64:$Rm),
9836         mnemonic, "\t$Zt, $Pg, [$Zn, $Rm]",
9837         "", []>, Sched<[]> {
9838   bits<5> Zt;
9839   bits<5> Zn;
9840   bits<3> Pg;
9841   bits<5> Rm;
9842   let Inst{31-21} = 0b11100100001;
9843   let Inst{20-16} = Rm;
9844   let Inst{15-13} = 0b001;
9845   let Inst{12-10} = Pg;
9846   let Inst{9-5}   = Zn;
9847   let Inst{4-0}   = Zt;
9849   let hasSideEffects = 0;
9850   let mayStore = 1;
9854 multiclass sve_mem_sst_128b_64_unscaled<string mnemonic, SDPatternOperator op> {
9855   def NAME : sve_mem_sst_128b_64_unscaled<mnemonic>;
9857   def : InstAlias<mnemonic # " $Zt, $Pg, [$Zn]",
9858                   (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, ZPR64:$Zn, XZR), 1>;
9860   def : Pat<(op (nxv2i64 Z_q:$Zt), (nxv2i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2i64),
9861             (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9862   def : Pat<(op (nxv4i32 Z_q:$Zt), (nxv4i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv4i32),
9863             (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9864   def : Pat<(op (nxv8i16 Z_q:$Zt), (nxv8i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8i16),
9865             (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp,ZPR64:$Zn, GPR64:$Rm)>;
9866   def : Pat<(op (nxv16i8 Z_q:$Zt), (nxv16i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv16i8),
9867             (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9869   def : Pat<(op (nxv2f64 Z_q:$Zt), (nxv2i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv2f64),
9870             (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9871   def : Pat<(op (nxv4f32 Z_q:$Zt), (nxv4i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv4f32),
9872             (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9873   def : Pat<(op (nxv8f16 Z_q:$Zt), (nxv8i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8f16),
9874             (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9875   def : Pat<(op (nxv8bf16 Z_q:$Zt), (nxv8i1 PPR3bAny:$gp), (nxv2i64 ZPR64:$Zn), (i64 GPR64sp:$Rm), nxv8bf16),
9876             (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$gp, ZPR64:$Zn, GPR64:$Rm)>;
9880 // SVE contiguous load (quadwords, scalar plus immediate)
9881 class sve_mem_128b_cld_si<bits<2> dtype, string mnemonic>
9882     : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4),
9883         mnemonic, "\t$Zt, $Pg/z, [$Rn, $imm4, mul vl]",
9884         "", []>, Sched<[]> {
9885   bits<5> Zt;
9886   bits<5> Rn;
9887   bits<3> Pg;
9888   bits<4> imm4;
9889   let Inst{31-25} = 0b1010010;
9890   let Inst{24-23} = dtype;
9891   let Inst{22-20} = 0b001;
9892   let Inst{19-16} = imm4;
9893   let Inst{15-13} = 0b001;
9894   let Inst{12-10} = Pg;
9895   let Inst{9-5}   = Rn;
9896   let Inst{4-0}   = Zt;
9898   let hasSideEffects = 0;
9899   let mayLoad = 1;
9902 multiclass sve_mem_128b_cld_si<bits<2> dtype, string mnemonic> {
9903   def NAME : sve_mem_128b_cld_si<dtype, mnemonic>;
9905   def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn]",
9906                   (!cast<Instruction>(NAME) Z_q:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 1>;
9907   def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn]",
9908                   (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, 0), 0>;
9909   def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn, $imm4, mul vl]",
9910                   (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, simm4s1:$imm4), 0>;
9914 // SVE contiguous load (quadwords, scalar plus scalar)
9915 class sve_mem_128b_cld_ss<bits<2> dtype, string mnemonic, RegisterOperand gprsh_ty>
9916     : I<(outs Z_q:$Zt), (ins PPR3bAny:$Pg, GPR64sp:$Rn, gprsh_ty:$Rm),
9917         mnemonic, "\t$Zt, $Pg/z, [$Rn, $Rm]", "",
9918         []>, Sched<[]> {
9919   bits<5> Zt;
9920   bits<5> Rn;
9921   bits<3> Pg;
9922   bits<5> Rm;
9923   let Inst{31-25} = 0b1010010;
9924   let Inst{24-23} = dtype;
9925   let Inst{22-21} = 0b00;
9926   let Inst{20-16} = Rm;
9927   let Inst{15-13} = 0b100;
9928   let Inst{12-10} = Pg;
9929   let Inst{9-5}   = Rn;
9930   let Inst{4-0}   = Zt;
9932   let hasSideEffects = 0;
9933   let mayLoad = 1;
9936 multiclass sve_mem_128b_cld_ss<bits<2> dtype, string mnemonic, RegisterOperand gprsh_ty> {
9937   def NAME : sve_mem_128b_cld_ss<dtype, mnemonic, gprsh_ty>;
9939   def : InstAlias<mnemonic # " $Zt, $Pg/z, [$Rn, $Rm]",
9940                  (!cast<Instruction>(NAME) ZPR128:$Zt, PPR3bAny:$Pg, GPR64sp:$Rn, gprsh_ty:$Rm), 0>;
9944 // SVE floating-point recursive reduction (quadwords)
9945 class sve2p1_fp_reduction_q<bits<2> sz, bits<3> opc, string mnemonic,
9946                             RegisterOperand zpr_ty, string vec_sfx>
9947     : I<(outs V128:$Vd), (ins PPR3bAny:$Pg, zpr_ty:$Zn),
9948         mnemonic, "\t$Vd." # vec_sfx # ", $Pg, $Zn",
9949         "", []>, Sched<[]> {
9950   bits<5> Vd;
9951   bits<5> Zn;
9952   bits<3> Pg;
9953   let Inst{31-24} = 0b01100100;
9954   let Inst{23-22} = sz;
9955   let Inst{21-19} = 0b010;
9956   let Inst{18-16} = opc;
9957   let Inst{15-13} = 0b101;
9958   let Inst{12-10} = Pg;
9959   let Inst{9-5}   = Zn;
9960   let Inst{4-0}   = Vd;
9962   let hasSideEffects = 0;
9963   let mayRaiseFPException = 1;
9966 multiclass sve2p1_fp_reduction_q<bits<3> opc, string mnemonic, SDPatternOperator op> {
9967   def _H : sve2p1_fp_reduction_q<0b01, opc, mnemonic, ZPR16, "8h">;
9968   def _S : sve2p1_fp_reduction_q<0b10, opc, mnemonic, ZPR32, "4s">;
9969   def _D : sve2p1_fp_reduction_q<0b11, opc, mnemonic, ZPR64, "2d">;
9971   def : SVE_2_Op_Pat<v8f16, op, nxv8i1, nxv8f16, !cast<Instruction>(NAME # _H)>;
9972   def : SVE_2_Op_Pat<v4f32, op, nxv4i1, nxv4f32, !cast<Instruction>(NAME # _S)>;
9973   def : SVE_2_Op_Pat<v2f64, op, nxv2i1, nxv2f64, !cast<Instruction>(NAME # _D)>;
9977 // SVE Permute Vector - Quadwords (DUPQ)
9978 class sve2p1_dupq<bits<5> ind_tsz, string mnemonic, ZPRRegOp zprty, Operand itype>
9979     : I<(outs zprty:$Zd), (ins zprty:$Zn, itype:$index),
9980         mnemonic, "\t$Zd, $Zn$index",
9981         "", []>, Sched<[]> {
9982   bits<5> Zd;
9983   bits<5> Zn;
9984   let Inst{31-21} = 0b00000101001;
9985   let Inst{20-16} = ind_tsz;
9986   let Inst{15-10} = 0b001001;
9987   let Inst{9-5} = Zn;
9988   let Inst{4-0} = Zd;
9990   let hasSideEffects = 0;
9993 multiclass sve2p1_dupq<string mnemonic> {
9994   def _B : sve2p1_dupq<{?, ?, ?, ?, 1}, mnemonic, ZPR8, VectorIndexB32b> {
9995     bits<4> index;
9996     let Inst{20-17} = index;
9997   }
9998   def _H : sve2p1_dupq<{?, ?, ?, 1, 0}, mnemonic, ZPR16, VectorIndexH32b> {
9999     bits<3> index;
10000     let Inst{20-18} = index;
10001   }
10002   def _S : sve2p1_dupq<{?, ?, 1, 0, 0}, mnemonic, ZPR32, VectorIndexS32b> {
10003     bits<2> index;
10004     let Inst{20-19} = index;
10005   }
10006   def _D : sve2p1_dupq<{?, 1, 0, 0, 0}, mnemonic, ZPR64, VectorIndexD32b> {
10007     bits<1> index;
10008     let Inst{20} = index;
10009   }
10013 // SVE Permute Vector - Quadwords (EXTQ)
10014 class sve2p1_extq<string mnemonic>
10015     : I<(outs ZPR8:$Zdn), (ins ZPR8:$_Zdn, ZPR8:$Zm, timm32_0_15:$imm4),
10016         mnemonic, "\t$Zdn, $_Zdn, $Zm, $imm4",
10017         "", []>, Sched<[]> {
10018   bits<5> Zdn;
10019   bits<5> Zm;
10020   bits<4> imm4;
10021   let Inst{31-20} = 0b000001010110;
10022   let Inst{19-16} = imm4;
10023   let Inst{15-10} = 0b001001;
10024   let Inst{9-5} = Zm;
10025   let Inst{4-0} = Zdn;
10027   let Constraints = "$Zdn = $_Zdn";
10028   let DestructiveInstType = DestructiveOther;
10029   let ElementSize = ZPR8.ElementSize;
10030   let hasSideEffects = 0;
10033 multiclass sve2p1_extq<string mnemonic, SDPatternOperator Op> {
10034   def NAME : sve2p1_extq<mnemonic>;
10035   def : SVE_3_Op_Imm_Pat<nxv16i8, Op, nxv16i8, nxv16i8, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10036   def : SVE_3_Op_Imm_Pat<nxv8i16, Op, nxv8i16, nxv8i16, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10037   def : SVE_3_Op_Imm_Pat<nxv4i32, Op, nxv4i32, nxv4i32, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10038   def : SVE_3_Op_Imm_Pat<nxv2i64, Op, nxv2i64, nxv2i64, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10040   def : SVE_3_Op_Imm_Pat<nxv8f16, Op, nxv8f16, nxv8f16, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10041   def : SVE_3_Op_Imm_Pat<nxv4f32, Op, nxv4f32, nxv4f32, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10042   def : SVE_3_Op_Imm_Pat<nxv2f64, Op, nxv2f64, nxv2f64, i32, timm32_0_15, !cast<Instruction>(NAME)>;
10043   def : SVE_3_Op_Imm_Pat<nxv8bf16, Op, nxv8bf16, nxv8bf16, i32, timm32_0_15, !cast<Instruction>(NAME
10047 // SVE move predicate from vector
10048 class sve2p1_vector_to_pred<bits<4> opc, string mnemonic,
10049                             PPRRegOp ppr_ty, Operand itype>
10050     : I<(outs ppr_ty:$Pd), (ins ZPRAny:$Zn, itype:$index),
10051         mnemonic, "\t$Pd, $Zn$index",
10052         "", []>, Sched<[]> {
10053   bits<4> Pd;
10054   bits<5> Zn;
10055   let Inst{31-24} = 0b00000101;
10056   let Inst{23-22} = opc{3-2};
10057   let Inst{21-19} = 0b101;
10058   let Inst{18-17} = opc{1-0};
10059   let Inst{16-10} = 0b0001110;
10060   let Inst{9-5}   = Zn;
10061   let Inst{4}     = 0b0;
10062   let Inst{3-0}   = Pd;
10064   let hasSideEffects = 0;
10067 multiclass sve2p1_vector_to_pred<string mnemonic, SDPatternOperator Op_lane, SDPatternOperator Op> {
10068   def _B : sve2p1_vector_to_pred<{0, 0, 0, 1}, mnemonic, PPR8,  VectorIndex032b>;
10069   def _H : sve2p1_vector_to_pred<{0, 0, 1, ?}, mnemonic, PPR16, VectorIndexD32b> {
10070     bits<1> index;
10071     let Inst{17} = index;
10072   }
10073   def _S : sve2p1_vector_to_pred<{0, 1, ?, ?}, mnemonic, PPR32, VectorIndexS32b> {
10074     bits<2> index;
10075     let Inst{18-17} = index;
10076   }
10077   def _D : sve2p1_vector_to_pred<{1, ?, ?, ?}, mnemonic, PPR64, VectorIndexH32b> {
10078     bits<3> index;
10079     let Inst{22}    = index{2};
10080     let Inst{18-17} = index{1-0};
10081   }
10083   def : InstAlias<mnemonic # "\t$Pd, $Zn",
10084                  (!cast<Instruction>(NAME # _B) PPR8:$Pd, ZPRAny:$Zn, 0), 1>;
10085   def : InstAlias<mnemonic # "\t$Pd, $Zn",
10086                  (!cast<Instruction>(NAME # _H) PPR16:$Pd, ZPRAny:$Zn, 0), 0>;
10087   def : InstAlias<mnemonic # "\t$Pd, $Zn",
10088                  (!cast<Instruction>(NAME # _S) PPR32:$Pd, ZPRAny:$Zn, 0), 0>;
10089   def : InstAlias<mnemonic # "\t$Pd, $Zn",
10090                  (!cast<Instruction>(NAME # _D) PPR64:$Pd, ZPRAny:$Zn, 0), 0>;
10092   // any_lane
10093   def : Pat<(nxv16i1 (Op_lane (nxv16i8 ZPRAny:$Zn), (i32 timm32_0_0:$Idx))),
10094             (!cast<Instruction>(NAME # _B) ZPRAny:$Zn, timm32_0_0:$Idx)>;
10095   def : Pat<(nxv8i1 (Op_lane (nxv8i16 ZPRAny:$Zn), (i32 timm32_0_1:$Idx))),
10096             (!cast<Instruction>(NAME # _H) ZPRAny:$Zn, timm32_0_1:$Idx)>;
10097   def : Pat<(nxv4i1 (Op_lane (nxv4i32 ZPRAny:$Zn), (i32 timm32_0_3:$Idx))),
10098             (!cast<Instruction>(NAME # _S) ZPRAny:$Zn, timm32_0_3:$Idx)>;
10099   def : Pat<(nxv2i1 (Op_lane (nxv2i64 ZPRAny:$Zn), (i32 timm32_0_7:$Idx))),
10100             (!cast<Instruction>(NAME # _D) ZPRAny:$Zn, timm32_0_7:$Idx)>;
10101  // lane_0
10102  def : Pat<(nxv16i1 (Op (nxv16i8 ZPRAny:$Zn))),
10103             (!cast<Instruction>(NAME # _B) ZPRAny:$Zn, 0)>;
10104   def : Pat<(nxv8i1 (Op (nxv8i16 ZPRAny:$Zn))),
10105             (!cast<Instruction>(NAME # _H) ZPRAny:$Zn, 0)>;
10106   def : Pat<(nxv4i1 (Op (nxv4i32 ZPRAny:$Zn))),
10107             (!cast<Instruction>(NAME # _S) ZPRAny:$Zn, 0)>;
10108   def : Pat<(nxv2i1 (Op (nxv2i64 ZPRAny:$Zn))),
10109             (!cast<Instruction>(NAME # _D) ZPRAny:$Zn, 0)>;
10113 // SVE move predicate into vector
10114 class sve2p1_pred_to_vector<bits<4> opc, string mnemonic,
10115                             PPRRegOp ppr_ty, Operand itype>
10116     : I<(outs ZPRAny:$Zd), (ins ZPRAny:$_Zd, itype:$index, ppr_ty:$Pn),
10117         mnemonic, "\t$Zd$index, $Pn",
10118         "", []>, Sched<[]> {
10119   bits<5> Zd;
10120   bits<4> Pn;
10121   let Inst{31-24} = 0b00000101;
10122   let Inst{23-22} = opc{3-2};
10123   let Inst{21-19} = 0b101;
10124   let Inst{18-17} = opc{1-0};
10125   let Inst{16-9}  = 0b10011100;
10126   let Inst{8-5}   = Pn;
10127   let Inst{4-0}   = Zd;
10129   let Constraints = "$Zd = $_Zd";
10130   let hasSideEffects = 0;
10133 multiclass sve2p1_pred_to_vector<string mnemonic, SDPatternOperator MergeOp,
10134                                  SDPatternOperator ZeroOp> {
10135   def _B : sve2p1_pred_to_vector<{0, 0, 0, 1}, mnemonic, PPR8,  VectorIndex0>;
10136   def _H : sve2p1_pred_to_vector<{0, 0, 1, ?}, mnemonic, PPR16, VectorIndexD32b> {
10137     bits<1> index;
10138     let Inst{17} = index;
10139   }
10140   def _S : sve2p1_pred_to_vector<{0, 1, ?, ?}, mnemonic, PPR32, VectorIndexS32b> {
10141     bits<2> index;
10142     let Inst{18-17} = index;
10143   }
10144   def _D : sve2p1_pred_to_vector<{1, ?, ?, ?}, mnemonic, PPR64, VectorIndexH32b> {
10145     bits<3> index;
10146     let Inst{22}    = index{2};
10147     let Inst{18-17} = index{1-0};
10148   }
10150   def : InstAlias<mnemonic # "\t$Zd, $Pn",
10151                  (!cast<Instruction>(NAME # _B) ZPRAny:$Zd, 0, PPR8:$Pn), 1>;
10152   def : InstAlias<mnemonic # "\t$Zd, $Pn",
10153                  (!cast<Instruction>(NAME # _H) ZPRAny:$Zd, 0, PPR16:$Pn), 0>;
10154   def : InstAlias<mnemonic # "\t$Zd, $Pn",
10155                  (!cast<Instruction>(NAME # _S) ZPRAny:$Zd, 0, PPR32:$Pn), 0>;
10156   def : InstAlias<mnemonic # "\t$Zd, $Pn",
10157                  (!cast<Instruction>(NAME # _D) ZPRAny:$Zd, 0, PPR64:$Pn), 0>;
10159   // Merge
10160   def : Pat<(nxv8i16 (MergeOp (nxv8i16 ZPRAny:$Zd), (nxv8i1 PPR16:$Pn), (i32 timm32_1_1:$Idx))),
10161             (!cast<Instruction>(NAME # _H) ZPRAny:$Zd, timm32_1_1:$Idx, PPR16:$Pn)>;
10162   def : Pat<(nxv4i32 (MergeOp (nxv4i32 ZPRAny:$Zd), (nxv4i1 PPR32:$Pn), (i32 timm32_1_3:$Idx))),
10163             (!cast<Instruction>(NAME # _S) ZPRAny:$Zd, timm32_1_3:$Idx, PPR32:$Pn)>;
10164   def : Pat<(nxv2i64 (MergeOp (nxv2i64 ZPRAny:$Zd), (nxv2i1 PPR64:$Pn), (i32 timm32_1_7:$Idx))),
10165             (!cast<Instruction>(NAME # _D) ZPRAny:$Zd, timm32_1_7:$Idx, PPR64:$Pn)>;
10167   // Zero
10168   def : Pat<(nxv16i8 (ZeroOp (nxv16i1 PPR8:$Pn))),
10169            (!cast<Instruction>(NAME # _B) (IMPLICIT_DEF), 0, PPR8:$Pn)>;
10170   def : Pat<(nxv8i16 (ZeroOp (nxv8i1 PPR16:$Pn))),
10171             (!cast<Instruction>(NAME # _H) (IMPLICIT_DEF), 0, PPR16:$Pn)>;
10172   def : Pat<(nxv4i32 (ZeroOp (nxv4i1 PPR32:$Pn))),
10173             (!cast<Instruction>(NAME # _S) (IMPLICIT_DEF), 0, PPR32:$Pn)>;
10174   def : Pat<(nxv2i64 (ZeroOp (nxv2i1 PPR64:$Pn))),
10175             (!cast<Instruction>(NAME # _D) (IMPLICIT_DEF), 0, PPR64:$Pn)>;
10179 // SVE bitwise logical/add/min/max reductions (quadwords)
10180 class sve2p1_int_reduce_q<bits<2> sz, bits<4> opc, string mnemonic,
10181                           RegisterOperand zpr_ty, string vec_sfx>
10182     : I<(outs V128:$Vd), (ins PPR3bAny:$Pg, zpr_ty:$Zn),
10183         mnemonic, "\t$Vd." # vec_sfx # ", $Pg, $Zn",
10184         "", []>, Sched<[]> {
10185   bits<5> Vd;
10186   bits<5> Zn;
10187   bits<3> Pg;
10188   let Inst{31-24} = 0b00000100;
10189   let Inst{23-22} = sz;
10190   let Inst{21}    = 0b0;
10191   let Inst{20-19} = opc{3-2};
10192   let Inst{18}    = 0b1;
10193   let Inst{17-16} = opc{1-0};
10194   let Inst{15-13} = 0b001;
10195   let Inst{12-10} = Pg;
10196   let Inst{9-5}   = Zn;
10197   let Inst{4-0}   = Vd;
10199   let hasSideEffects = 0;
10202 multiclass sve2p1_int_reduce_q<bits<4> opc, string mnemonic, SDPatternOperator op> {
10203   def _B : sve2p1_int_reduce_q<0b00, opc, mnemonic, ZPR8,  "16b">;
10204   def _H : sve2p1_int_reduce_q<0b01, opc, mnemonic, ZPR16, "8h">;
10205   def _S : sve2p1_int_reduce_q<0b10, opc, mnemonic, ZPR32, "4s">;
10206   def _D : sve2p1_int_reduce_q<0b11, opc, mnemonic, ZPR64, "2d">;
10208   def : SVE_2_Op_Pat<v16i8, op, nxv16i1, nxv16i8, !cast<Instruction>(NAME # _B)>;
10209   def : SVE_2_Op_Pat<v8i16, op, nxv8i1, nxv8i16, !cast<Instruction>(NAME # _H)>;
10210   def : SVE_2_Op_Pat<v4i32, op, nxv4i1, nxv4i32, !cast<Instruction>(NAME # _S)>;
10211   def : SVE_2_Op_Pat<v2i64, op, nxv2i1, nxv2i64, !cast<Instruction>(NAME # _D)>;
10215 // SVE permute vector elements (quadwords)
10216 class sve2p1_permute_vec_elems_q<bits<2> sz, bits<3> opc, string mnemonic,
10217                                  ZPRRegOp zpr_ty, RegisterOperand src1_ty>
10218     : I<(outs zpr_ty:$Zd), (ins src1_ty:$Zn, zpr_ty:$Zm),
10219         mnemonic, "\t$Zd, $Zn, $Zm",
10220         "", []>, Sched<[]> {
10221   bits<5> Zd;
10222   bits<5> Zn;
10223   bits<5> Zm;
10224   let Inst{31-24} = 0b01000100;
10225   let Inst{23-22} = sz;
10226   let Inst{21}    = 0b0;
10227   let Inst{20-16} = Zm;
10228   let Inst{15-13} = 0b111;
10229   let Inst{12-10} = opc;
10230   let Inst{9-5}   = Zn;
10231   let Inst{4-0}   = Zd;
10233   let hasSideEffects = 0;
10236 multiclass sve2p1_permute_vec_elems_q<bits<3> opc, string mnemonic,
10237                                       SDPatternOperator op> {
10238   def _B : sve2p1_permute_vec_elems_q<0b00, opc, mnemonic, ZPR8,  ZPR8>;
10239   def _H : sve2p1_permute_vec_elems_q<0b01, opc, mnemonic, ZPR16, ZPR16>;
10240   def _S : sve2p1_permute_vec_elems_q<0b10, opc, mnemonic, ZPR32, ZPR32>;
10241   def _D : sve2p1_permute_vec_elems_q<0b11, opc, mnemonic, ZPR64, ZPR64>;
10243   def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
10244   def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10245   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
10246   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
10248   def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8f16, !cast<Instruction>(NAME # _H)>;
10249   def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4f32, !cast<Instruction>(NAME # _S)>;
10250   def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2f64, !cast<Instruction>(NAME # _D)>;
10252   def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8bf16, !cast<Instruction>(NAME # _H)>;
10255 multiclass sve2p1_tblq<string mnemonic, SDPatternOperator op> {
10256   def _B : sve2p1_permute_vec_elems_q<0b00, 0b110, mnemonic, ZPR8,  Z_b>;
10257   def _H : sve2p1_permute_vec_elems_q<0b01, 0b110, mnemonic, ZPR16, Z_h>;
10258   def _S : sve2p1_permute_vec_elems_q<0b10, 0b110, mnemonic, ZPR32, Z_s>;
10259   def _D : sve2p1_permute_vec_elems_q<0b11, 0b110, mnemonic, ZPR64, Z_d>;
10261   def : SVE_2_Op_Pat<nxv16i8, op, nxv16i8, nxv16i8, !cast<Instruction>(NAME # _B)>;
10262   def : SVE_2_Op_Pat<nxv8i16, op, nxv8i16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10263   def : SVE_2_Op_Pat<nxv4i32, op, nxv4i32, nxv4i32, !cast<Instruction>(NAME # _S)>;
10264   def : SVE_2_Op_Pat<nxv2i64, op, nxv2i64, nxv2i64, !cast<Instruction>(NAME # _D)>;
10266   def : SVE_2_Op_Pat<nxv8f16, op, nxv8f16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10267   def : SVE_2_Op_Pat<nxv4f32, op, nxv4f32, nxv4i32, !cast<Instruction>(NAME # _S)>;
10268   def : SVE_2_Op_Pat<nxv2f64, op, nxv2f64, nxv2i64, !cast<Instruction>(NAME # _D)>;
10270   def : SVE_2_Op_Pat<nxv8bf16, op, nxv8bf16, nxv8i16, !cast<Instruction>(NAME # _H)>;
10273 //===----------------------------------------------------------------------===//
10274 // SVE2 FP8 Instructions
10275 //===----------------------------------------------------------------------===//
10277 // FP8 upconvert
10278 class sve2_fp8_cvt_single<bit L, bits<2> opc, string mnemonic,
10279                           ZPRRegOp dst_ty, ZPRRegOp src_ty>
10280     : I<(outs dst_ty:$Zd), (ins src_ty:$Zn),
10281       mnemonic, "\t$Zd, $Zn",
10282       "", []>, Sched<[]>{
10283   bits<5> Zd;
10284   bits<5> Zn;
10285   let Inst{31-17} = 0b011001010000100;
10286   let Inst{16}    = L;
10287   let Inst{15-12} = 0b0011;
10288   let Inst{11-10} = opc;
10289   let Inst{9-5}   = Zn;
10290   let Inst{4-0}   = Zd;
10293 multiclass sve2_fp8_cvt_single<bit L, bits<2> opc, string mnemonic> {
10294   def _BtoH : sve2_fp8_cvt_single<L, opc, mnemonic, ZPR16, ZPR8>;
10297 // FP8 downconvert
10298 class sve2_fp8_down_cvt_single<bits<2> opc, string mnemonic,
10299                               ZPRRegOp dst_ty, RegisterOperand src_ty>
10300     : I<(outs dst_ty:$Zd), (ins src_ty:$Zn),
10301       mnemonic, "\t$Zd, $Zn",
10302       "", []>, Sched<[]>{
10303   bits<5> Zd;
10304   bits<4> Zn;
10305   let Inst{31-12} = 0b01100101000010100011;
10306   let Inst{11-10} = opc;
10307   let Inst{9-6} = Zn;
10308   let Inst{5} = 0b0;
10309   let Inst{4-0} = Zd;
10312 multiclass sve2_fp8_down_cvt_single<bits<2> opc, string mnemonic, RegisterOperand src> {
10313   def NAME : sve2_fp8_down_cvt_single<opc, mnemonic, ZPR8, src>;
10316 // FP8 Widening Multiply-Add Long - Indexed Group
10317 class sve2_fp8_mla_long_by_indexed_elem<bit T, string mnemonic>
10318     : I<(outs ZPR16:$Zda),
10319       (ins ZPR16:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexB:$imm4),
10320       mnemonic, "\t$Zda, $Zn, $Zm$imm4",
10321       "", []>, Sched<[]>{
10322   bits<5> Zda;
10323   bits<5> Zn;
10324   bits<3> Zm;
10325   bits<4> imm4;
10326   let Inst{31-24} = 0b01100100;
10327   let Inst{23}    = T;
10328   let Inst{22-21} = 0b01;
10329   let Inst{20-19} = imm4{3-2};
10330   let Inst{18-16} = Zm;
10331   let Inst{15-12} = 0b0101;
10332   let Inst{11-10} = imm4{1-0};
10333   let Inst{9-5}   = Zn;
10334   let Inst{4-0}   = Zda;
10335   let Constraints = "$Zda = $_Zda";
10336   let DestructiveInstType = DestructiveOther;
10337   let ElementSize         = ZPR16.ElementSize;
10340 // FP8 Widening Multiply-Add (Long)/(Long Long) Group
10341 class sve2_fp8_mla<bits<3>opc, ZPRRegOp dst_ty, string mnemonic>
10342     : I<(outs dst_ty:$Zda),
10343       (ins dst_ty:$_Zda, ZPR8:$Zn, ZPR8:$Zm),
10344       mnemonic, "\t$Zda, $Zn, $Zm",
10345       "", []>, Sched<[]>{
10346   bits<5> Zda;
10347   bits<5> Zn;
10348   bits<5> Zm;
10349   let Inst{31-24} = 0b01100100;
10350   let Inst{23}    = opc{2};
10351   let Inst{22-21} = 0b01;
10352   let Inst{20-16} = Zm;
10353   let Inst{15-14} = 0b10;
10354   let Inst{13-12} = opc{1-0};
10355   let Inst{11-10} = 0b10;
10356   let Inst{9-5}   = Zn;
10357   let Inst{4-0}   = Zda;
10358   let Constraints = "$Zda = $_Zda";
10359   let DestructiveInstType = DestructiveOther;
10360   let ElementSize         = dst_ty.ElementSize;
10363 // FP8 Widening Multiply-Add Long Long - Indexed Group
10364 class sve2_fp8_mla_long_long_by_indexed_elem<bits<2> TT, string mnemonic>
10365     : I<(outs ZPR32:$Zda),
10366       (ins ZPR32:$_Zda, ZPR8:$Zn, ZPR3b8:$Zm, VectorIndexB:$imm4),
10367       mnemonic, "\t$Zda, $Zn, $Zm$imm4",
10368       "", []>, Sched<[]>{
10369   bits<5> Zda;
10370   bits<5> Zn;
10371   bits<3> Zm;
10372   bits<4> imm4;
10373   let Inst{31-24} = 0b01100100;
10374   let Inst{23-22} = TT;
10375   let Inst{21}    = 0b1;
10376   let Inst{20-19} = imm4{3-2};
10377   let Inst{18-16} = Zm;
10378   let Inst{15-12} = 0b1100;
10379   let Inst{11-10} = imm4{1-0};
10380   let Inst{9-5}   = Zn;
10381   let Inst{4-0}   = Zda;
10382   let Constraints = "$Zda = $_Zda";
10383   let DestructiveInstType = DestructiveOther;
10384   let ElementSize         = ZPR32.ElementSize;
10387 // FP8 Widening Dot-Product - Indexed Group
10388 multiclass sve2_fp8_dot_indexed<string mnemonic>{
10389   def NAME : sve_float_dot_indexed<0b0, ZPR16, ZPR8, ZPR3b8, VectorIndexH, mnemonic> {
10390     bits<3> iop;
10391     let Inst{20-19} = iop{2-1};
10392     let Inst{11} = iop{0};
10393     let Inst{10} = 0b1;
10394   }
10397 // FP8 Look up table
10398 class sve2_lut_vector_index<ZPRRegOp zd_ty, RegisterOperand zn_ty,
10399                             Operand idx_ty, bits<4>opc, string mnemonic>
10400     : I<(outs zd_ty:$Zd), (ins zn_ty:$Zn, ZPRAny:$Zm, idx_ty:$idx),
10401       mnemonic, "\t$Zd, $Zn, $Zm$idx",
10402       "", []>, Sched<[]> {
10403   bits<5> Zd;
10404   bits<5> Zn;
10405   bits<5> Zm;
10406   let Inst{31-24} = 0b01000101;
10407   let Inst{22}    = opc{3};
10408   let Inst{21}    = 0b1;
10409   let Inst{20-16} = Zm;
10410   let Inst{15-13} = 0b101;
10411   let Inst{12-10} = opc{2-0};
10412   let Inst{9-5}   = Zn;
10413   let Inst{4-0}   = Zd;
10416 // FP8 Look up table read with 2-bit indices
10417 multiclass sve2_luti2_vector_index<string mnemonic> {
10418   def _B : sve2_lut_vector_index<ZPR8, Z_b, VectorIndexS32b, {?, 0b100}, mnemonic> {
10419     bits<2> idx;
10420     let Inst{23-22} = idx;
10421   }
10422   def _H : sve2_lut_vector_index<ZPR16, Z_h, VectorIndexH32b, {?,?,0b10}, mnemonic> {
10423     bits<3> idx;
10424     let Inst{23-22} = idx{2-1};
10425     let Inst{12}    = idx{0};
10426   }
10429 // FP8 Look up table read with 4-bit indices
10430 multiclass sve2_luti4_vector_index<string mnemonic> {
10431   def _B : sve2_lut_vector_index<ZPR8, Z_b, VectorIndexD32b, 0b1001, mnemonic> {
10432     bit idx;
10433     let Inst{23} = idx;
10434   }
10435   def _H : sve2_lut_vector_index<ZPR16, Z_h, VectorIndexS32b, {?, 0b111}, mnemonic> {
10436     bits<2> idx;
10437     let Inst{23-22} = idx;
10438   }
10441 // FP8 Look up table read with 4-bit indices (two contiguous registers)
10442 multiclass sve2_luti4_vector_vg2_index<string mnemonic> {
10443   def _H : sve2_lut_vector_index<ZPR16, ZZ_h, VectorIndexS32b, {?, 0b101}, mnemonic> {
10444     bits<2> idx;
10445     let Inst{23-22} = idx;
10446   }
10449 //===----------------------------------------------------------------------===//
10450 // Checked Pointer Arithmetic (FEAT_CPA)
10451 //===----------------------------------------------------------------------===//
10452 class sve_int_mad_cpa<string asm>
10453     : I<(outs ZPR64:$Zdn), (ins ZPR64:$_Zdn, ZPR64:$Zm, ZPR64:$Za),
10454         asm, "\t$Zdn, $Zm, $Za", "", []>, Sched<[]> {
10455   bits<5> Zdn;
10456   bits<5> Zm;
10457   bits<5> Za;
10458   let Inst{31-24} = 0b01000100;
10459   let Inst{23-22} = 0b11; // sz
10460   let Inst{21}    = 0b0;
10461   let Inst{20-16} = Zm;
10462   let Inst{15}    = 0b1;
10463   let Inst{14-10} = 0b10110; // opc
10464   let Inst{9-5}   = Za;
10465   let Inst{4-0}   = Zdn;
10467   let Constraints = "$Zdn = $_Zdn";
10468   let DestructiveInstType = DestructiveOther;
10469   let ElementSize = ZPR64.ElementSize;
10470   let hasSideEffects = 0;
10473 class sve_int_mla_cpa<string asm>
10474     : sve2_int_mla<0b11, 0b10100, asm, ZPR64, ZPR64> {
10475   let Inst{15} = 0b1;
10477   let ElementSize = ZPR64.ElementSize;