1 //===-- ARMInstrMVE.td - MVE support for ARM ---------------*- tablegen -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file describes the ARM MVE instruction set.
11 //===----------------------------------------------------------------------===//
13 class ExpandImmAsmOp<string shift> : AsmOperandClass {
14 let Name = !strconcat("ExpandImm", shift);
15 let PredicateMethod = !strconcat("isExpImm<", shift, ">");
16 let RenderMethod = "addImmOperands";
18 class InvertedExpandImmAsmOp<string shift, string size> : AsmOperandClass {
19 let Name = !strconcat("InvertedExpandImm", shift, "_", size);
20 let PredicateMethod = !strconcat("isInvertedExpImm<", shift, ",", size, ">");
21 let RenderMethod = "addImmOperands";
24 class ExpandImm<string shift> : Operand<i32> {
25 let ParserMatchClass = ExpandImmAsmOp<shift>;
26 let EncoderMethod = !strconcat("getExpandedImmOpValue<",shift,",false>");
27 let DecoderMethod = !strconcat("DecodeExpandedImmOperand<",shift,">");
28 let PrintMethod = "printExpandedImmOperand";
30 class InvertedExpandImm<string shift, string size> : Operand<i32> {
31 let ParserMatchClass = InvertedExpandImmAsmOp<shift, size>;
32 let EncoderMethod = !strconcat("getExpandedImmOpValue<",shift,",true>");
33 let PrintMethod = "printExpandedImmOperand";
34 // No decoder method needed, because this operand type is only used
35 // by aliases (VAND and VORN)
38 def expzero00 : ExpandImm<"0">;
39 def expzero08 : ExpandImm<"8">;
40 def expzero16 : ExpandImm<"16">;
41 def expzero24 : ExpandImm<"24">;
43 def expzero00inv16 : InvertedExpandImm<"0", "16">;
44 def expzero08inv16 : InvertedExpandImm<"8", "16">;
46 def expzero00inv32 : InvertedExpandImm<"0", "32">;
47 def expzero08inv32 : InvertedExpandImm<"8", "32">;
48 def expzero16inv32 : InvertedExpandImm<"16", "32">;
49 def expzero24inv32 : InvertedExpandImm<"24", "32">;
52 def vpt_mask : Operand<i32> {
53 let PrintMethod = "printVPTMask";
54 let ParserMatchClass = it_mask_asmoperand;
55 let EncoderMethod = "getVPTMaskOpValue";
56 let DecoderMethod = "DecodeVPTMaskOperand";
59 // VPT/VCMP restricted predicate for sign invariant types
60 def pred_restricted_i_asmoperand : AsmOperandClass {
61 let Name = "CondCodeRestrictedI";
62 let RenderMethod = "addITCondCodeOperands";
63 let PredicateMethod = "isITCondCodeRestrictedI";
64 let ParserMethod = "parseITCondCode";
67 // VPT/VCMP restricted predicate for signed types
68 def pred_restricted_s_asmoperand : AsmOperandClass {
69 let Name = "CondCodeRestrictedS";
70 let RenderMethod = "addITCondCodeOperands";
71 let PredicateMethod = "isITCondCodeRestrictedS";
72 let ParserMethod = "parseITCondCode";
75 // VPT/VCMP restricted predicate for unsigned types
76 def pred_restricted_u_asmoperand : AsmOperandClass {
77 let Name = "CondCodeRestrictedU";
78 let RenderMethod = "addITCondCodeOperands";
79 let PredicateMethod = "isITCondCodeRestrictedU";
80 let ParserMethod = "parseITCondCode";
83 // VPT/VCMP restricted predicate for floating point
84 def pred_restricted_fp_asmoperand : AsmOperandClass {
85 let Name = "CondCodeRestrictedFP";
86 let RenderMethod = "addITCondCodeOperands";
87 let PredicateMethod = "isITCondCodeRestrictedFP";
88 let ParserMethod = "parseITCondCode";
91 def pred_basic_i : Operand<i32> {
92 let PrintMethod = "printMandatoryRestrictedPredicateOperand";
93 let ParserMatchClass = pred_restricted_i_asmoperand;
94 let DecoderMethod = "DecodeRestrictedIPredicateOperand";
95 let EncoderMethod = "getRestrictedCondCodeOpValue";
98 def pred_basic_u : Operand<i32> {
99 let PrintMethod = "printMandatoryRestrictedPredicateOperand";
100 let ParserMatchClass = pred_restricted_u_asmoperand;
101 let DecoderMethod = "DecodeRestrictedUPredicateOperand";
102 let EncoderMethod = "getRestrictedCondCodeOpValue";
105 def pred_basic_s : Operand<i32> {
106 let PrintMethod = "printMandatoryRestrictedPredicateOperand";
107 let ParserMatchClass = pred_restricted_s_asmoperand;
108 let DecoderMethod = "DecodeRestrictedSPredicateOperand";
109 let EncoderMethod = "getRestrictedCondCodeOpValue";
112 def pred_basic_fp : Operand<i32> {
113 let PrintMethod = "printMandatoryRestrictedPredicateOperand";
114 let ParserMatchClass = pred_restricted_fp_asmoperand;
115 let DecoderMethod = "DecodeRestrictedFPPredicateOperand";
116 let EncoderMethod = "getRestrictedCondCodeOpValue";
119 class MVE_MI<dag oops, dag iops, InstrItinClass itin, string asm,
120 string ops, string cstr, list<dag> pattern>
121 : Thumb2XI<oops, iops, AddrModeNone, 4, itin, !strconcat(asm, "\t", ops), cstr,
123 Requires<[HasMVEInt]> {
125 let DecoderNamespace = "MVE";
128 // MVE_p is used for most predicated instructions, to add the cluster
129 // of input operands that provides the VPT suffix (none, T or E) and
130 // the input predicate register.
131 class MVE_p<dag oops, dag iops, InstrItinClass itin, string iname,
132 string suffix, string ops, vpred_ops vpred, string cstr,
133 list<dag> pattern=[]>
134 : MVE_MI<oops, !con(iops, (ins vpred:$vp)), itin,
135 // If the instruction has a suffix, like vadd.f32, then the
136 // VPT predication suffix goes before the dot, so the full
137 // name has to be "vadd${vp}.f32".
138 !strconcat(iname, "${vp}",
139 !if(!eq(suffix, ""), "", !strconcat(".", suffix))),
140 ops, !strconcat(cstr, vpred.vpred_constraint), pattern> {
141 let Inst{31-29} = 0b111;
142 let Inst{27-26} = 0b11;
145 class MVE_MI_with_pred<dag oops, dag iops, InstrItinClass itin, string asm,
146 string ops, string cstr, list<dag> pattern>
147 : Thumb2I<oops, iops, AddrModeNone, 4, itin, asm, !strconcat("\t", ops), cstr,
149 Requires<[HasV8_1MMainline, HasMVEInt]> {
151 let DecoderNamespace = "MVE";
154 class MVE_VMOV_lane_base<dag oops, dag iops, InstrItinClass itin, string asm,
155 string suffix, string ops, string cstr,
157 : Thumb2I<oops, iops, AddrModeNone, 4, itin, asm,
158 !if(!eq(suffix, ""), "", "." # suffix) # "\t" # ops,
160 Requires<[HasV8_1MMainline, HasMVEInt]> {
162 let DecoderNamespace = "MVE";
165 class MVE_ScalarShift<string iname, dag oops, dag iops, string asm, string cstr,
166 list<dag> pattern=[]>
167 : MVE_MI_with_pred<oops, iops, NoItinerary, iname, asm, cstr, pattern> {
168 let Inst{31-20} = 0b111010100101;
173 class MVE_ScalarShiftSingleReg<string iname, dag iops, string asm, string cstr,
174 list<dag> pattern=[]>
175 : MVE_ScalarShift<iname, (outs rGPR:$RdaDest), iops, asm, cstr, pattern> {
178 let Inst{19-16} = RdaDest{3-0};
181 class MVE_ScalarShiftSRegImm<string iname, bits<2> op5_4, list<dag> pattern=[]>
182 : MVE_ScalarShiftSingleReg<iname, (ins rGPR:$RdaSrc, long_shift:$imm),
183 "$RdaSrc, $imm", "$RdaDest = $RdaSrc", pattern> {
187 let Inst{14-12} = imm{4-2};
188 let Inst{11-8} = 0b1111;
189 let Inst{7-6} = imm{1-0};
190 let Inst{5-4} = op5_4{1-0};
191 let Inst{3-0} = 0b1111;
194 def MVE_SQSHL : MVE_ScalarShiftSRegImm<"sqshl", 0b11>;
195 def MVE_SRSHR : MVE_ScalarShiftSRegImm<"srshr", 0b10>;
196 def MVE_UQSHL : MVE_ScalarShiftSRegImm<"uqshl", 0b00>;
197 def MVE_URSHR : MVE_ScalarShiftSRegImm<"urshr", 0b01>;
199 class MVE_ScalarShiftSRegReg<string iname, bits<2> op5_4, list<dag> pattern=[]>
200 : MVE_ScalarShiftSingleReg<iname, (ins rGPR:$RdaSrc, rGPR:$Rm),
201 "$RdaSrc, $Rm", "$RdaDest = $RdaSrc", pattern> {
204 let Inst{15-12} = Rm{3-0};
205 let Inst{11-8} = 0b1111;
206 let Inst{7-6} = 0b00;
207 let Inst{5-4} = op5_4{1-0};
208 let Inst{3-0} = 0b1101;
211 def MVE_SQRSHR : MVE_ScalarShiftSRegReg<"sqrshr", 0b10>;
212 def MVE_UQRSHL : MVE_ScalarShiftSRegReg<"uqrshl", 0b00>;
214 class MVE_ScalarShiftDoubleReg<string iname, dag iops, string asm,
215 string cstr, list<dag> pattern=[]>
216 : MVE_ScalarShift<iname, (outs tGPREven:$RdaLo, tGPROdd:$RdaHi),
217 iops, asm, cstr, pattern> {
221 let Inst{19-17} = RdaLo{3-1};
222 let Inst{11-9} = RdaHi{3-1};
225 class MVE_ScalarShiftDRegImm<string iname, bits<2> op5_4, bit op16,
226 list<dag> pattern=[]>
227 : MVE_ScalarShiftDoubleReg<
228 iname, (ins tGPREven:$RdaLo_src, tGPROdd:$RdaHi_src, long_shift:$imm),
229 "$RdaLo, $RdaHi, $imm", "$RdaLo = $RdaLo_src,$RdaHi = $RdaHi_src",
235 let Inst{14-12} = imm{4-2};
236 let Inst{7-6} = imm{1-0};
237 let Inst{5-4} = op5_4{1-0};
238 let Inst{3-0} = 0b1111;
241 class MVE_ScalarShiftDRegReg<string iname, bit op5, bit op16,
242 list<dag> pattern=[]>
243 : MVE_ScalarShiftDoubleReg<
244 iname, (ins tGPREven:$RdaLo_src, tGPROdd:$RdaHi_src, rGPR:$Rm),
245 "$RdaLo, $RdaHi, $Rm", "@earlyclobber $RdaHi,@earlyclobber $RdaLo,"
246 "$RdaLo = $RdaLo_src,$RdaHi = $RdaHi_src",
251 let Inst{15-12} = Rm{3-0};
252 let Inst{7-6} = 0b00;
255 let Inst{3-0} = 0b1101;
257 // Custom decoder method because of the following overlapping encodings:
260 // SQRSHRL and SQRSHR
261 // UQRSHLL and UQRSHL
262 let DecoderMethod = "DecodeMVEOverlappingLongShift";
265 def MVE_ASRLr : MVE_ScalarShiftDRegReg<"asrl", 0b1, 0b0>;
266 def MVE_ASRLi : MVE_ScalarShiftDRegImm<"asrl", 0b10, ?>;
267 def MVE_LSLLr : MVE_ScalarShiftDRegReg<"lsll", 0b0, 0b0>;
268 def MVE_LSLLi : MVE_ScalarShiftDRegImm<"lsll", 0b00, ?>;
269 def MVE_LSRL : MVE_ScalarShiftDRegImm<"lsrl", 0b01, ?>;
271 def MVE_SQRSHRL : MVE_ScalarShiftDRegReg<"sqrshrl", 0b1, 0b1>;
272 def MVE_SQSHLL : MVE_ScalarShiftDRegImm<"sqshll", 0b11, 0b1>;
273 def MVE_SRSHRL : MVE_ScalarShiftDRegImm<"srshrl", 0b10, 0b1>;
275 def MVE_UQRSHLL : MVE_ScalarShiftDRegReg<"uqrshll", 0b0, 0b1>;
276 def MVE_UQSHLL : MVE_ScalarShiftDRegImm<"uqshll", 0b00, 0b1>;
277 def MVE_URSHRL : MVE_ScalarShiftDRegImm<"urshrl", 0b01, 0b1>;
279 // start of mve_rDest instructions
281 class MVE_rDest<dag oops, dag iops, InstrItinClass itin,
282 string iname, string suffix,
283 string ops, string cstr, list<dag> pattern=[]>
284 // Always use vpred_n and not vpred_r: with the output register being
285 // a GPR and not a vector register, there can't be any question of
286 // what to put in its inactive lanes.
287 : MVE_p<oops, iops, itin, iname, suffix, ops, vpred_n, cstr, pattern> {
289 let Inst{25-23} = 0b101;
290 let Inst{11-9} = 0b111;
294 class MVE_VABAV<string suffix, bit U, bits<2> size, list<dag> pattern=[]>
295 : MVE_rDest<(outs rGPR:$Rda), (ins rGPR:$Rda_src, MQPR:$Qn, MQPR:$Qm),
296 NoItinerary, "vabav", suffix, "$Rda, $Qn, $Qm", "$Rda = $Rda_src",
304 let Inst{21-20} = size{1-0};
305 let Inst{19-17} = Qn{2-0};
307 let Inst{15-12} = Rda{3-0};
312 let Inst{3-1} = Qm{2-0};
316 def MVE_VABAVs8 : MVE_VABAV<"s8", 0b0, 0b00>;
317 def MVE_VABAVs16 : MVE_VABAV<"s16", 0b0, 0b01>;
318 def MVE_VABAVs32 : MVE_VABAV<"s32", 0b0, 0b10>;
319 def MVE_VABAVu8 : MVE_VABAV<"u8", 0b1, 0b00>;
320 def MVE_VABAVu16 : MVE_VABAV<"u16", 0b1, 0b01>;
321 def MVE_VABAVu32 : MVE_VABAV<"u32", 0b1, 0b10>;
323 class MVE_VADDV<string iname, string suffix, dag iops, string cstr,
324 bit A, bit U, bits<2> size, list<dag> pattern=[]>
325 : MVE_rDest<(outs tGPREven:$Rda), iops, NoItinerary,
326 iname, suffix, "$Rda, $Qm", cstr, pattern> {
331 let Inst{22-20} = 0b111;
332 let Inst{19-18} = size{1-0};
333 let Inst{17-16} = 0b01;
334 let Inst{15-13} = Rda{3-1};
336 let Inst{8-6} = 0b100;
338 let Inst{3-1} = Qm{2-0};
342 multiclass MVE_VADDV_A<string suffix, bit U, bits<2> size,
343 list<dag> pattern=[]> {
344 def acc : MVE_VADDV<"vaddva", suffix,
345 (ins tGPREven:$Rda_src, MQPR:$Qm), "$Rda = $Rda_src",
346 0b1, U, size, pattern>;
347 def no_acc : MVE_VADDV<"vaddv", suffix,
349 0b0, U, size, pattern>;
352 defm MVE_VADDVs8 : MVE_VADDV_A<"s8", 0b0, 0b00>;
353 defm MVE_VADDVs16 : MVE_VADDV_A<"s16", 0b0, 0b01>;
354 defm MVE_VADDVs32 : MVE_VADDV_A<"s32", 0b0, 0b10>;
355 defm MVE_VADDVu8 : MVE_VADDV_A<"u8", 0b1, 0b00>;
356 defm MVE_VADDVu16 : MVE_VADDV_A<"u16", 0b1, 0b01>;
357 defm MVE_VADDVu32 : MVE_VADDV_A<"u32", 0b1, 0b10>;
359 class MVE_VADDLV<string iname, string suffix, dag iops, string cstr,
360 bit A, bit U, list<dag> pattern=[]>
361 : MVE_rDest<(outs tGPREven:$RdaLo, tGPROdd:$RdaHi), iops, NoItinerary, iname,
362 suffix, "$RdaLo, $RdaHi, $Qm", cstr, pattern> {
368 let Inst{22-20} = RdaHi{3-1};
369 let Inst{19-18} = 0b10;
370 let Inst{17-16} = 0b01;
371 let Inst{15-13} = RdaLo{3-1};
373 let Inst{8-6} = 0b100;
375 let Inst{3-1} = Qm{2-0};
379 multiclass MVE_VADDLV_A<string suffix, bit U, list<dag> pattern=[]> {
380 def acc : MVE_VADDLV<"vaddlva", suffix,
381 (ins tGPREven:$RdaLo_src, tGPROdd:$RdaHi_src, MQPR:$Qm),
382 "$RdaLo = $RdaLo_src,$RdaHi = $RdaHi_src",
384 def no_acc : MVE_VADDLV<"vaddlv", suffix,
390 defm MVE_VADDLVs32 : MVE_VADDLV_A<"s32", 0b0>;
391 defm MVE_VADDLVu32 : MVE_VADDLV_A<"u32", 0b1>;
393 class MVE_VMINMAXNMV<string iname, string suffix, bit sz,
394 bit bit_17, bit bit_7, list<dag> pattern=[]>
395 : MVE_rDest<(outs rGPR:$RdaDest), (ins rGPR:$RdaSrc, MQPR:$Qm),
396 NoItinerary, iname, suffix, "$RdaSrc, $Qm",
397 "$RdaDest = $RdaSrc", pattern> {
402 let Inst{22-20} = 0b110;
403 let Inst{19-18} = 0b11;
404 let Inst{17} = bit_17;
406 let Inst{15-12} = RdaDest{3-0};
409 let Inst{6-5} = 0b00;
410 let Inst{3-1} = Qm{2-0};
413 let Predicates = [HasMVEFloat];
416 multiclass MVE_VMINMAXNMV_fty<string iname, bit bit_7, list<dag> pattern=[]> {
417 def f32 : MVE_VMINMAXNMV<iname, "f32", 0b0, 0b1, bit_7, pattern>;
418 def f16 : MVE_VMINMAXNMV<iname, "f16", 0b1, 0b1, bit_7, pattern>;
421 defm MVE_VMINNMV : MVE_VMINMAXNMV_fty<"vminnmv", 0b1>;
422 defm MVE_VMAXNMV : MVE_VMINMAXNMV_fty<"vmaxnmv", 0b0>;
424 multiclass MVE_VMINMAXNMAV_fty<string iname, bit bit_7, list<dag> pattern=[]> {
425 def f32 : MVE_VMINMAXNMV<iname, "f32", 0b0, 0b0, bit_7, pattern>;
426 def f16 : MVE_VMINMAXNMV<iname, "f16", 0b1, 0b0, bit_7, pattern>;
429 defm MVE_VMINNMAV : MVE_VMINMAXNMAV_fty<"vminnmav", 0b1>;
430 defm MVE_VMAXNMAV : MVE_VMINMAXNMAV_fty<"vmaxnmav", 0b0>;
432 class MVE_VMINMAXV<string iname, string suffix, bit U, bits<2> size,
433 bit bit_17, bit bit_7, list<dag> pattern=[]>
434 : MVE_rDest<(outs rGPR:$RdaDest), (ins rGPR:$RdaSrc, MQPR:$Qm), NoItinerary,
435 iname, suffix, "$RdaSrc, $Qm", "$RdaDest = $RdaSrc", pattern> {
440 let Inst{22-20} = 0b110;
441 let Inst{19-18} = size{1-0};
442 let Inst{17} = bit_17;
444 let Inst{15-12} = RdaDest{3-0};
447 let Inst{6-5} = 0b00;
448 let Inst{3-1} = Qm{2-0};
452 multiclass MVE_VMINMAXV_ty<string iname, bit bit_7, list<dag> pattern=[]> {
453 def s8 : MVE_VMINMAXV<iname, "s8", 0b0, 0b00, 0b1, bit_7>;
454 def s16 : MVE_VMINMAXV<iname, "s16", 0b0, 0b01, 0b1, bit_7>;
455 def s32 : MVE_VMINMAXV<iname, "s32", 0b0, 0b10, 0b1, bit_7>;
456 def u8 : MVE_VMINMAXV<iname, "u8", 0b1, 0b00, 0b1, bit_7>;
457 def u16 : MVE_VMINMAXV<iname, "u16", 0b1, 0b01, 0b1, bit_7>;
458 def u32 : MVE_VMINMAXV<iname, "u32", 0b1, 0b10, 0b1, bit_7>;
461 defm MVE_VMINV : MVE_VMINMAXV_ty<"vminv", 0b1>;
462 defm MVE_VMAXV : MVE_VMINMAXV_ty<"vmaxv", 0b0>;
464 multiclass MVE_VMINMAXAV_ty<string iname, bit bit_7, list<dag> pattern=[]> {
465 def s8 : MVE_VMINMAXV<iname, "s8", 0b0, 0b00, 0b0, bit_7>;
466 def s16 : MVE_VMINMAXV<iname, "s16", 0b0, 0b01, 0b0, bit_7>;
467 def s32 : MVE_VMINMAXV<iname, "s32", 0b0, 0b10, 0b0, bit_7>;
470 defm MVE_VMINAV : MVE_VMINMAXAV_ty<"vminav", 0b1>;
471 defm MVE_VMAXAV : MVE_VMINMAXAV_ty<"vmaxav", 0b0>;
473 class MVE_VMLAMLSDAV<string iname, string suffix, dag iops, string cstr,
474 bit sz, bit bit_28, bit A, bit X, bit bit_8, bit bit_0,
475 list<dag> pattern=[]>
476 : MVE_rDest<(outs tGPREven:$RdaDest), iops, NoItinerary, iname, suffix,
477 "$RdaDest, $Qn, $Qm", cstr, pattern> {
482 let Inst{28} = bit_28;
483 let Inst{22-20} = 0b111;
484 let Inst{19-17} = Qn{2-0};
486 let Inst{15-13} = RdaDest{3-1};
489 let Inst{7-6} = 0b00;
491 let Inst{3-1} = Qm{2-0};
495 multiclass MVE_VMLAMLSDAV_X<string iname, string suffix, dag iops, string cstr,
496 bit sz, bit bit_28, bit A, bit bit_8, bit bit_0,
497 list<dag> pattern=[]> {
498 def _noexch : MVE_VMLAMLSDAV<iname, suffix, iops, cstr, sz,
499 bit_28, A, 0b0, bit_8, bit_0, pattern>;
500 def _exch : MVE_VMLAMLSDAV<iname # "x", suffix, iops, cstr, sz,
501 bit_28, A, 0b1, bit_8, bit_0, pattern>;
504 multiclass MVE_VMLAMLSDAV_XA<string iname, string suffix, bit sz, bit bit_28,
505 bit bit_8, bit bit_0, list<dag> pattern=[]> {
506 defm _noacc : MVE_VMLAMLSDAV_X<iname, suffix, (ins MQPR:$Qn, MQPR:$Qm), "",
507 sz, bit_28, 0b0, bit_8, bit_0, pattern>;
508 defm _acc : MVE_VMLAMLSDAV_X<iname # "a", suffix,
509 (ins tGPREven:$RdaSrc, MQPR:$Qn, MQPR:$Qm),
510 "$RdaDest = $RdaSrc",
511 sz, bit_28, 0b1, bit_8, bit_0, pattern>;
514 multiclass MVE_VMLADAV_multi<string suffix, bit sz, bit U, bit bit_8,
515 list<dag> pattern=[]> {
516 defm "" : MVE_VMLAMLSDAV_XA<"vmladav", suffix, sz, U, bit_8, 0b0, pattern>;
519 defm MVE_VMLADAVs16 : MVE_VMLADAV_multi<"s16", 0b0, 0b0, 0b0>;
520 defm MVE_VMLADAVs32 : MVE_VMLADAV_multi<"s32", 0b1, 0b0, 0b0>;
521 defm MVE_VMLADAVu16 : MVE_VMLADAV_multi<"u16", 0b0, 0b1, 0b0>;
522 defm MVE_VMLADAVu32 : MVE_VMLADAV_multi<"u32", 0b1, 0b1, 0b0>;
524 defm MVE_VMLADAVs8 : MVE_VMLADAV_multi<"s8", 0b0, 0b0, 0b1>;
525 defm MVE_VMLADAVu8 : MVE_VMLADAV_multi<"u8", 0b0, 0b1, 0b1>;
527 // vmlav aliases vmladav
528 foreach acc = ["_acc", "_noacc"] in {
529 foreach suffix = ["s8", "s16", "s32", "u8", "u16", "u32"] in {
530 def : MVEInstAlias<!strconcat("vmlav", !if(!eq(acc, "_acc"), "a", ""),
531 "${vp}.", suffix, "\t$RdaDest, $Qn, $Qm"),
532 (!cast<Instruction>("MVE_VMLADAV"#suffix#acc#"_noexch")
533 tGPREven:$RdaDest, MQPR:$Qn, MQPR:$Qm, vpred_n:$vp)>;
537 multiclass MVE_VMLSDAV_multi<string suffix, bit sz, bit bit_28,
538 list<dag> pattern=[]> {
539 defm "" : MVE_VMLAMLSDAV_XA<"vmlsdav", suffix, sz, bit_28, 0b0, 0b1, pattern>;
542 defm MVE_VMLSDAVs8 : MVE_VMLSDAV_multi<"s8", 0, 0b1>;
543 defm MVE_VMLSDAVs16 : MVE_VMLSDAV_multi<"s16", 0, 0b0>;
544 defm MVE_VMLSDAVs32 : MVE_VMLSDAV_multi<"s32", 1, 0b0>;
546 // Base class for VMLALDAV and VMLSLDAV, VRMLALDAVH, VRMLSLDAVH
547 class MVE_VMLALDAVBase<string iname, string suffix, dag iops, string cstr,
548 bit sz, bit bit_28, bit A, bit X, bit bit_8, bit bit_0,
549 list<dag> pattern=[]>
550 : MVE_rDest<(outs tGPREven:$RdaLoDest, tGPROdd:$RdaHiDest), iops, NoItinerary,
551 iname, suffix, "$RdaLoDest, $RdaHiDest, $Qn, $Qm", cstr, pattern> {
557 let Inst{28} = bit_28;
558 let Inst{22-20} = RdaHiDest{3-1};
559 let Inst{19-17} = Qn{2-0};
561 let Inst{15-13} = RdaLoDest{3-1};
564 let Inst{7-6} = 0b00;
566 let Inst{3-1} = Qm{2-0};
570 multiclass MVE_VMLALDAVBase_X<string iname, string suffix, dag iops,
571 string cstr, bit sz, bit bit_28, bit A,
572 bit bit_8, bit bit_0, list<dag> pattern=[]> {
573 def _noexch : MVE_VMLALDAVBase<iname, suffix, iops, cstr, sz,
574 bit_28, A, 0b0, bit_8, bit_0, pattern>;
575 def _exch : MVE_VMLALDAVBase<iname # "x", suffix, iops, cstr, sz,
576 bit_28, A, 0b1, bit_8, bit_0, pattern>;
579 multiclass MVE_VMLALDAVBase_XA<string iname, string suffix, bit sz, bit bit_28,
580 bit bit_8, bit bit_0, list<dag> pattern=[]> {
581 defm _noacc : MVE_VMLALDAVBase_X<
582 iname, suffix, (ins MQPR:$Qn, MQPR:$Qm), "",
583 sz, bit_28, 0b0, bit_8, bit_0, pattern>;
584 defm _acc : MVE_VMLALDAVBase_X<
585 iname # "a", suffix, (ins tGPREven:$RdaLoSrc, tGPROdd:$RdaHiSrc,
587 "$RdaLoDest = $RdaLoSrc,$RdaHiDest = $RdaHiSrc",
588 sz, bit_28, 0b1, bit_8, bit_0, pattern>;
591 multiclass MVE_VRMLALDAVH_multi<string suffix, bit U, list<dag> pattern=[]> {
592 defm "" : MVE_VMLALDAVBase_XA<
593 "vrmlaldavh", suffix, 0b0, U, 0b1, 0b0, pattern>;
596 defm MVE_VRMLALDAVHs32 : MVE_VRMLALDAVH_multi<"s32", 0>;
597 defm MVE_VRMLALDAVHu32 : MVE_VRMLALDAVH_multi<"u32", 1>;
599 // vrmlalvh aliases for vrmlaldavh
600 def : MVEInstAlias<"vrmlalvh${vp}.s32\t$RdaLo, $RdaHi, $Qn, $Qm",
601 (MVE_VRMLALDAVHs32_noacc_noexch
602 tGPREven:$RdaLo, tGPROdd:$RdaHi,
603 MQPR:$Qn, MQPR:$Qm, vpred_n:$vp)>;
604 def : MVEInstAlias<"vrmlalvha${vp}.s32\t$RdaLo, $RdaHi, $Qn, $Qm",
605 (MVE_VRMLALDAVHs32_acc_noexch
606 tGPREven:$RdaLo, tGPROdd:$RdaHi,
607 MQPR:$Qn, MQPR:$Qm, vpred_n:$vp)>;
608 def : MVEInstAlias<"vrmlalvh${vp}.u32\t$RdaLo, $RdaHi, $Qn, $Qm",
609 (MVE_VRMLALDAVHu32_noacc_noexch
610 tGPREven:$RdaLo, tGPROdd:$RdaHi,
611 MQPR:$Qn, MQPR:$Qm, vpred_n:$vp)>;
612 def : MVEInstAlias<"vrmlalvha${vp}.u32\t$RdaLo, $RdaHi, $Qn, $Qm",
613 (MVE_VRMLALDAVHu32_acc_noexch
614 tGPREven:$RdaLo, tGPROdd:$RdaHi,
615 MQPR:$Qn, MQPR:$Qm, vpred_n:$vp)>;
617 multiclass MVE_VMLALDAV_multi<string suffix, bit sz, bit U,
618 list<dag> pattern=[]> {
619 defm "" : MVE_VMLALDAVBase_XA<"vmlaldav", suffix, sz, U, 0b0, 0b0, pattern>;
622 defm MVE_VMLALDAVs16 : MVE_VMLALDAV_multi<"s16", 0b0, 0b0>;
623 defm MVE_VMLALDAVs32 : MVE_VMLALDAV_multi<"s32", 0b1, 0b0>;
624 defm MVE_VMLALDAVu16 : MVE_VMLALDAV_multi<"u16", 0b0, 0b1>;
625 defm MVE_VMLALDAVu32 : MVE_VMLALDAV_multi<"u32", 0b1, 0b1>;
627 // vmlalv aliases vmlaldav
628 foreach acc = ["_acc", "_noacc"] in {
629 foreach suffix = ["s16", "s32", "u16", "u32"] in {
630 def : MVEInstAlias<!strconcat("vmlalv", !if(!eq(acc, "_acc"), "a", ""),
631 "${vp}.", suffix, "\t$RdaLoDest, $RdaHiDest, $Qn, $Qm"),
632 (!cast<Instruction>("MVE_VMLALDAV"#suffix#acc#"_noexch")
633 tGPREven:$RdaLoDest, tGPROdd:$RdaHiDest,
634 MQPR:$Qn, MQPR:$Qm, vpred_n:$vp)>;
638 multiclass MVE_VMLSLDAV_multi<string iname, string suffix, bit sz,
639 bit bit_28, list<dag> pattern=[]> {
640 defm "" : MVE_VMLALDAVBase_XA<iname, suffix, sz, bit_28, 0b0, 0b1, pattern>;
643 defm MVE_VMLSLDAVs16 : MVE_VMLSLDAV_multi<"vmlsldav", "s16", 0b0, 0b0>;
644 defm MVE_VMLSLDAVs32 : MVE_VMLSLDAV_multi<"vmlsldav", "s32", 0b1, 0b0>;
645 defm MVE_VRMLSLDAVHs32 : MVE_VMLSLDAV_multi<"vrmlsldavh", "s32", 0b0, 0b1>;
647 // end of mve_rDest instructions
649 // start of mve_comp instructions
651 class MVE_comp<InstrItinClass itin, string iname, string suffix,
652 string cstr, list<dag> pattern=[]>
653 : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qn, MQPR:$Qm), itin, iname, suffix,
654 "$Qd, $Qn, $Qm", vpred_r, cstr, pattern> {
659 let Inst{22} = Qd{3};
660 let Inst{19-17} = Qn{2-0};
662 let Inst{15-13} = Qd{2-0};
664 let Inst{10-9} = 0b11;
667 let Inst{3-1} = Qm{2-0};
671 class MVE_VMINMAXNM<string iname, string suffix, bit sz, bit bit_21,
672 list<dag> pattern=[]>
673 : MVE_comp<NoItinerary, iname, suffix, "", pattern> {
676 let Inst{25-24} = 0b11;
678 let Inst{21} = bit_21;
685 let Predicates = [HasMVEFloat];
688 def MVE_VMAXNMf32 : MVE_VMINMAXNM<"vmaxnm", "f32", 0b0, 0b0>;
689 def MVE_VMAXNMf16 : MVE_VMINMAXNM<"vmaxnm", "f16", 0b1, 0b0>;
691 def MVE_VMINNMf32 : MVE_VMINMAXNM<"vminnm", "f32", 0b0, 0b1>;
692 def MVE_VMINNMf16 : MVE_VMINMAXNM<"vminnm", "f16", 0b1, 0b1>;
694 class MVE_VMINMAX<string iname, string suffix, bit U, bits<2> size,
695 bit bit_4, list<dag> pattern=[]>
696 : MVE_comp<NoItinerary, iname, suffix, "", pattern> {
699 let Inst{25-24} = 0b11;
701 let Inst{21-20} = size{1-0};
708 multiclass MVE_VMINMAX_all_sizes<string iname, bit bit_4> {
709 def s8 : MVE_VMINMAX<iname, "s8", 0b0, 0b00, bit_4>;
710 def s16 : MVE_VMINMAX<iname, "s16", 0b0, 0b01, bit_4>;
711 def s32 : MVE_VMINMAX<iname, "s32", 0b0, 0b10, bit_4>;
712 def u8 : MVE_VMINMAX<iname, "u8", 0b1, 0b00, bit_4>;
713 def u16 : MVE_VMINMAX<iname, "u16", 0b1, 0b01, bit_4>;
714 def u32 : MVE_VMINMAX<iname, "u32", 0b1, 0b10, bit_4>;
717 defm MVE_VMAX : MVE_VMINMAX_all_sizes<"vmax", 0b0>;
718 defm MVE_VMIN : MVE_VMINMAX_all_sizes<"vmin", 0b1>;
720 // end of mve_comp instructions
722 // start of mve_imm_shift instructions
724 def MVE_VSHLC : MVE_p<(outs rGPR:$RdmDest, MQPR:$Qd),
725 (ins MQPR:$QdSrc, rGPR:$RdmSrc, long_shift:$imm),
726 NoItinerary, "vshlc", "", "$QdSrc, $RdmSrc, $imm",
727 vpred_n, "$RdmDest = $RdmSrc,$Qd = $QdSrc"> {
733 let Inst{25-23} = 0b101;
734 let Inst{22} = Qd{3};
736 let Inst{20-16} = imm{4-0};
737 let Inst{15-13} = Qd{2-0};
738 let Inst{12-4} = 0b011111100;
739 let Inst{3-0} = RdmDest{3-0};
742 class MVE_shift_imm<dag oops, dag iops, string iname, string suffix,
743 string ops, vpred_ops vpred, string cstr,
744 list<dag> pattern=[]>
745 : MVE_p<oops, iops, NoItinerary, iname, suffix, ops, vpred, cstr, pattern> {
749 let Inst{22} = Qd{3};
750 let Inst{15-13} = Qd{2-0};
752 let Inst{3-1} = Qm{2-0};
755 class MVE_VMOVL<string iname, string suffix, bits<2> sz, bit U,
756 list<dag> pattern=[]>
757 : MVE_shift_imm<(outs MQPR:$Qd), (ins MQPR:$Qm),
758 iname, suffix, "$Qd, $Qm", vpred_r, "",
761 let Inst{25-23} = 0b101;
763 let Inst{20-19} = sz{1-0};
764 let Inst{18-16} = 0b000;
765 let Inst{11-6} = 0b111101;
770 multiclass MVE_VMOVL_shift_half<string iname, string suffix, bits<2> sz, bit U,
771 list<dag> pattern=[]> {
772 def bh : MVE_VMOVL<!strconcat(iname, "b"), suffix, sz, U, pattern> {
775 def th : MVE_VMOVL<!strconcat(iname, "t"), suffix, sz, U, pattern> {
780 defm MVE_VMOVLs8 : MVE_VMOVL_shift_half<"vmovl", "s8", 0b01, 0b0>;
781 defm MVE_VMOVLu8 : MVE_VMOVL_shift_half<"vmovl", "u8", 0b01, 0b1>;
782 defm MVE_VMOVLs16 : MVE_VMOVL_shift_half<"vmovl", "s16", 0b10, 0b0>;
783 defm MVE_VMOVLu16 : MVE_VMOVL_shift_half<"vmovl", "u16", 0b10, 0b1>;
785 class MVE_VSHLL_imm<string iname, string suffix, bit U, bit th,
786 dag immops, list<dag> pattern=[]>
787 : MVE_shift_imm<(outs MQPR:$Qd), !con((ins MQPR:$Qm), immops),
788 iname, suffix, "$Qd, $Qm, $imm", vpred_r, "", pattern> {
790 let Inst{25-23} = 0b101;
793 let Inst{11-6} = 0b111101;
798 // The immediate VSHLL instructions accept shift counts from 1 up to
799 // the lane width (8 or 16), but the full-width shifts have an
800 // entirely separate encoding, given below with 'lw' in the name.
802 class MVE_VSHLL_imm8<string iname, string suffix,
803 bit U, bit th, list<dag> pattern=[]>
804 : MVE_VSHLL_imm<iname, suffix, U, th, (ins mve_shift_imm1_7:$imm), pattern> {
806 let Inst{20-19} = 0b01;
807 let Inst{18-16} = imm;
810 class MVE_VSHLL_imm16<string iname, string suffix,
811 bit U, bit th, list<dag> pattern=[]>
812 : MVE_VSHLL_imm<iname, suffix, U, th, (ins mve_shift_imm1_15:$imm), pattern> {
815 let Inst{19-16} = imm;
818 def MVE_VSHLL_imms8bh : MVE_VSHLL_imm8 <"vshllb", "s8", 0b0, 0b0>;
819 def MVE_VSHLL_imms8th : MVE_VSHLL_imm8 <"vshllt", "s8", 0b0, 0b1>;
820 def MVE_VSHLL_immu8bh : MVE_VSHLL_imm8 <"vshllb", "u8", 0b1, 0b0>;
821 def MVE_VSHLL_immu8th : MVE_VSHLL_imm8 <"vshllt", "u8", 0b1, 0b1>;
822 def MVE_VSHLL_imms16bh : MVE_VSHLL_imm16<"vshllb", "s16", 0b0, 0b0>;
823 def MVE_VSHLL_imms16th : MVE_VSHLL_imm16<"vshllt", "s16", 0b0, 0b1>;
824 def MVE_VSHLL_immu16bh : MVE_VSHLL_imm16<"vshllb", "u16", 0b1, 0b0>;
825 def MVE_VSHLL_immu16th : MVE_VSHLL_imm16<"vshllt", "u16", 0b1, 0b1>;
827 class MVE_VSHLL_by_lane_width<string iname, string suffix, bits<2> size,
828 bit U, string ops, list<dag> pattern=[]>
829 : MVE_shift_imm<(outs MQPR:$Qd), (ins MQPR:$Qm),
830 iname, suffix, ops, vpred_r, "", pattern> {
832 let Inst{25-23} = 0b100;
833 let Inst{21-20} = 0b11;
834 let Inst{19-18} = size{1-0};
835 let Inst{17-16} = 0b01;
836 let Inst{11-6} = 0b111000;
841 multiclass MVE_VSHLL_lw<string iname, string suffix, bits<2> sz, bit U,
842 string ops, list<dag> pattern=[]> {
843 def bh : MVE_VSHLL_by_lane_width<iname#"b", suffix, sz, U, ops, pattern> {
846 def th : MVE_VSHLL_by_lane_width<iname#"t", suffix, sz, U, ops, pattern> {
851 defm MVE_VSHLL_lws8 : MVE_VSHLL_lw<"vshll", "s8", 0b00, 0b0, "$Qd, $Qm, #8">;
852 defm MVE_VSHLL_lws16 : MVE_VSHLL_lw<"vshll", "s16", 0b01, 0b0, "$Qd, $Qm, #16">;
853 defm MVE_VSHLL_lwu8 : MVE_VSHLL_lw<"vshll", "u8", 0b00, 0b1, "$Qd, $Qm, #8">;
854 defm MVE_VSHLL_lwu16 : MVE_VSHLL_lw<"vshll", "u16", 0b01, 0b1, "$Qd, $Qm, #16">;
856 class MVE_VxSHRN<string iname, string suffix, bit bit_12, bit bit_28,
857 dag immops, list<dag> pattern=[]>
858 : MVE_shift_imm<(outs MQPR:$Qd), !con((ins MQPR:$QdSrc, MQPR:$Qm), immops),
859 iname, suffix, "$Qd, $Qm, $imm", vpred_n, "$Qd = $QdSrc",
863 let Inst{28} = bit_28;
864 let Inst{25-23} = 0b101;
866 let Inst{20-16} = imm{4-0};
867 let Inst{12} = bit_12;
868 let Inst{11-6} = 0b111111;
873 def MVE_VRSHRNi16bh : MVE_VxSHRN<
874 "vrshrnb", "i16", 0b0, 0b1, (ins shr_imm8:$imm)> {
875 let Inst{20-19} = 0b01;
877 def MVE_VRSHRNi16th : MVE_VxSHRN<
878 "vrshrnt", "i16", 0b1, 0b1,(ins shr_imm8:$imm)> {
879 let Inst{20-19} = 0b01;
881 def MVE_VRSHRNi32bh : MVE_VxSHRN<
882 "vrshrnb", "i32", 0b0, 0b1, (ins shr_imm16:$imm)> {
885 def MVE_VRSHRNi32th : MVE_VxSHRN<
886 "vrshrnt", "i32", 0b1, 0b1, (ins shr_imm16:$imm)> {
890 def MVE_VSHRNi16bh : MVE_VxSHRN<
891 "vshrnb", "i16", 0b0, 0b0, (ins shr_imm8:$imm)> {
892 let Inst{20-19} = 0b01;
894 def MVE_VSHRNi16th : MVE_VxSHRN<
895 "vshrnt", "i16", 0b1, 0b0, (ins shr_imm8:$imm)> {
896 let Inst{20-19} = 0b01;
898 def MVE_VSHRNi32bh : MVE_VxSHRN<
899 "vshrnb", "i32", 0b0, 0b0, (ins shr_imm16:$imm)> {
902 def MVE_VSHRNi32th : MVE_VxSHRN<
903 "vshrnt", "i32", 0b1, 0b0, (ins shr_imm16:$imm)> {
907 class MVE_VxQRSHRUN<string iname, string suffix, bit bit_28, bit bit_12, dag immops,
908 list<dag> pattern=[]>
909 : MVE_shift_imm<(outs MQPR:$Qd), !con((ins MQPR:$QdSrc, MQPR:$Qm), immops),
910 iname, suffix, "$Qd, $Qm, $imm", vpred_n, "$Qd = $QdSrc",
914 let Inst{28} = bit_28;
915 let Inst{25-23} = 0b101;
917 let Inst{20-16} = imm{4-0};
918 let Inst{12} = bit_12;
919 let Inst{11-6} = 0b111111;
924 def MVE_VQRSHRUNs16bh : MVE_VxQRSHRUN<
925 "vqrshrunb", "s16", 0b1, 0b0, (ins shr_imm8:$imm)> {
926 let Inst{20-19} = 0b01;
928 def MVE_VQRSHRUNs16th : MVE_VxQRSHRUN<
929 "vqrshrunt", "s16", 0b1, 0b1, (ins shr_imm8:$imm)> {
930 let Inst{20-19} = 0b01;
932 def MVE_VQRSHRUNs32bh : MVE_VxQRSHRUN<
933 "vqrshrunb", "s32", 0b1, 0b0, (ins shr_imm16:$imm)> {
936 def MVE_VQRSHRUNs32th : MVE_VxQRSHRUN<
937 "vqrshrunt", "s32", 0b1, 0b1, (ins shr_imm16:$imm)> {
941 def MVE_VQSHRUNs16bh : MVE_VxQRSHRUN<
942 "vqshrunb", "s16", 0b0, 0b0, (ins shr_imm8:$imm)> {
943 let Inst{20-19} = 0b01;
945 def MVE_VQSHRUNs16th : MVE_VxQRSHRUN<
946 "vqshrunt", "s16", 0b0, 0b1, (ins shr_imm8:$imm)> {
947 let Inst{20-19} = 0b01;
949 def MVE_VQSHRUNs32bh : MVE_VxQRSHRUN<
950 "vqshrunb", "s32", 0b0, 0b0, (ins shr_imm16:$imm)> {
953 def MVE_VQSHRUNs32th : MVE_VxQRSHRUN<
954 "vqshrunt", "s32", 0b0, 0b1, (ins shr_imm16:$imm)> {
958 class MVE_VxQRSHRN<string iname, string suffix, bit bit_0, bit bit_12,
959 dag immops, list<dag> pattern=[]>
960 : MVE_shift_imm<(outs MQPR:$Qd), !con((ins MQPR:$QdSrc, MQPR:$Qm), immops),
961 iname, suffix, "$Qd, $Qm, $imm", vpred_n, "$Qd = $QdSrc",
965 let Inst{25-23} = 0b101;
967 let Inst{20-16} = imm{4-0};
968 let Inst{12} = bit_12;
969 let Inst{11-6} = 0b111101;
974 multiclass MVE_VxQRSHRN_types<string iname, bit bit_0, bit bit_12> {
975 def s16 : MVE_VxQRSHRN<iname, "s16", bit_0, bit_12, (ins shr_imm8:$imm)> {
977 let Inst{20-19} = 0b01;
979 def u16 : MVE_VxQRSHRN<iname, "u16", bit_0, bit_12, (ins shr_imm8:$imm)> {
981 let Inst{20-19} = 0b01;
983 def s32 : MVE_VxQRSHRN<iname, "s32", bit_0, bit_12, (ins shr_imm16:$imm)> {
987 def u32 : MVE_VxQRSHRN<iname, "u32", bit_0, bit_12, (ins shr_imm16:$imm)> {
993 defm MVE_VQRSHRNbh : MVE_VxQRSHRN_types<"vqrshrnb", 0b1, 0b0>;
994 defm MVE_VQRSHRNth : MVE_VxQRSHRN_types<"vqrshrnt", 0b1, 0b1>;
995 defm MVE_VQSHRNbh : MVE_VxQRSHRN_types<"vqshrnb", 0b0, 0b0>;
996 defm MVE_VQSHRNth : MVE_VxQRSHRN_types<"vqshrnt", 0b0, 0b1>;
998 // end of mve_imm_shift instructions
1000 // start of mve_shift instructions
1002 class MVE_shift_by_vec<string iname, string suffix, bit U,
1003 bits<2> size, bit bit_4, bit bit_8>
1004 : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qm, MQPR:$Qn), NoItinerary,
1005 iname, suffix, "$Qd, $Qm, $Qn", vpred_r, "", []> {
1006 // Shift instructions which take a vector of shift counts
1012 let Inst{25-24} = 0b11;
1014 let Inst{22} = Qd{3};
1015 let Inst{21-20} = size;
1016 let Inst{19-17} = Qn{2-0};
1018 let Inst{15-13} = Qd{2-0};
1019 let Inst{12-9} = 0b0010;
1020 let Inst{8} = bit_8;
1021 let Inst{7} = Qn{3};
1023 let Inst{5} = Qm{3};
1024 let Inst{4} = bit_4;
1025 let Inst{3-1} = Qm{2-0};
1029 multiclass mve_shift_by_vec_multi<string iname, bit bit_4, bit bit_8> {
1030 def s8 : MVE_shift_by_vec<iname, "s8", 0b0, 0b00, bit_4, bit_8>;
1031 def s16 : MVE_shift_by_vec<iname, "s16", 0b0, 0b01, bit_4, bit_8>;
1032 def s32 : MVE_shift_by_vec<iname, "s32", 0b0, 0b10, bit_4, bit_8>;
1033 def u8 : MVE_shift_by_vec<iname, "u8", 0b1, 0b00, bit_4, bit_8>;
1034 def u16 : MVE_shift_by_vec<iname, "u16", 0b1, 0b01, bit_4, bit_8>;
1035 def u32 : MVE_shift_by_vec<iname, "u32", 0b1, 0b10, bit_4, bit_8>;
1038 defm MVE_VSHL_by_vec : mve_shift_by_vec_multi<"vshl", 0b0, 0b0>;
1039 defm MVE_VQSHL_by_vec : mve_shift_by_vec_multi<"vqshl", 0b1, 0b0>;
1040 defm MVE_VQRSHL_by_vec : mve_shift_by_vec_multi<"vqrshl", 0b1, 0b1>;
1041 defm MVE_VRSHL_by_vec : mve_shift_by_vec_multi<"vrshl", 0b0, 0b1>;
1043 class MVE_shift_with_imm<string iname, string suffix, dag oops, dag iops,
1044 string ops, vpred_ops vpred, string cstr,
1045 list<dag> pattern=[]>
1046 : MVE_p<oops, iops, NoItinerary, iname, suffix, ops, vpred, cstr, pattern> {
1051 let Inst{22} = Qd{3};
1052 let Inst{15-13} = Qd{2-0};
1053 let Inst{12-11} = 0b00;
1054 let Inst{7-6} = 0b01;
1055 let Inst{5} = Qm{3};
1057 let Inst{3-1} = Qm{2-0};
1061 class MVE_VSxI_imm<string iname, string suffix, bit bit_8, dag imm>
1062 : MVE_shift_with_imm<iname, suffix, (outs MQPR:$Qd),
1063 !con((ins MQPR:$Qd_src, MQPR:$Qm), imm),
1064 "$Qd, $Qm, $imm", vpred_n, "$Qd = $Qd_src"> {
1067 let Inst{25-24} = 0b11;
1068 let Inst{21-16} = imm;
1069 let Inst{10-9} = 0b10;
1070 let Inst{8} = bit_8;
1073 def MVE_VSRIimm8 : MVE_VSxI_imm<"vsri", "8", 0b0, (ins shr_imm8:$imm)> {
1074 let Inst{21-19} = 0b001;
1077 def MVE_VSRIimm16 : MVE_VSxI_imm<"vsri", "16", 0b0, (ins shr_imm16:$imm)> {
1078 let Inst{21-20} = 0b01;
1081 def MVE_VSRIimm32 : MVE_VSxI_imm<"vsri", "32", 0b0, (ins shr_imm32:$imm)> {
1085 def MVE_VSLIimm8 : MVE_VSxI_imm<"vsli", "8", 0b1, (ins imm0_7:$imm)> {
1086 let Inst{21-19} = 0b001;
1089 def MVE_VSLIimm16 : MVE_VSxI_imm<"vsli", "16", 0b1, (ins imm0_15:$imm)> {
1090 let Inst{21-20} = 0b01;
1093 def MVE_VSLIimm32 : MVE_VSxI_imm<"vsli", "32", 0b1,(ins imm0_31:$imm)> {
1097 class MVE_VQSHL_imm<string suffix, dag imm>
1098 : MVE_shift_with_imm<"vqshl", suffix, (outs MQPR:$Qd),
1099 !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
1103 let Inst{25-24} = 0b11;
1104 let Inst{21-16} = imm;
1105 let Inst{10-8} = 0b111;
1108 def MVE_VSLIimms8 : MVE_VQSHL_imm<"s8", (ins imm0_7:$imm)> {
1110 let Inst{21-19} = 0b001;
1113 def MVE_VSLIimmu8 : MVE_VQSHL_imm<"u8", (ins imm0_7:$imm)> {
1115 let Inst{21-19} = 0b001;
1118 def MVE_VSLIimms16 : MVE_VQSHL_imm<"s16", (ins imm0_15:$imm)> {
1120 let Inst{21-20} = 0b01;
1123 def MVE_VSLIimmu16 : MVE_VQSHL_imm<"u16", (ins imm0_15:$imm)> {
1125 let Inst{21-20} = 0b01;
1128 def MVE_VSLIimms32 : MVE_VQSHL_imm<"s32", (ins imm0_31:$imm)> {
1133 def MVE_VSLIimmu32 : MVE_VQSHL_imm<"u32", (ins imm0_31:$imm)> {
1138 class MVE_VQSHLU_imm<string suffix, dag imm>
1139 : MVE_shift_with_imm<"vqshlu", suffix, (outs MQPR:$Qd),
1140 !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
1145 let Inst{25-24} = 0b11;
1146 let Inst{21-16} = imm;
1147 let Inst{10-8} = 0b110;
1150 def MVE_VQSHLU_imms8 : MVE_VQSHLU_imm<"s8", (ins imm0_7:$imm)> {
1151 let Inst{21-19} = 0b001;
1154 def MVE_VQSHLU_imms16 : MVE_VQSHLU_imm<"s16", (ins imm0_15:$imm)> {
1155 let Inst{21-20} = 0b01;
1158 def MVE_VQSHLU_imms32 : MVE_VQSHLU_imm<"s32", (ins imm0_31:$imm)> {
1162 class MVE_VRSHR_imm<string suffix, dag imm>
1163 : MVE_shift_with_imm<"vrshr", suffix, (outs MQPR:$Qd),
1164 !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
1168 let Inst{25-24} = 0b11;
1169 let Inst{21-16} = imm;
1170 let Inst{10-8} = 0b010;
1173 def MVE_VRSHR_imms8 : MVE_VRSHR_imm<"s8", (ins shr_imm8:$imm)> {
1175 let Inst{21-19} = 0b001;
1178 def MVE_VRSHR_immu8 : MVE_VRSHR_imm<"u8", (ins shr_imm8:$imm)> {
1180 let Inst{21-19} = 0b001;
1183 def MVE_VRSHR_imms16 : MVE_VRSHR_imm<"s16", (ins shr_imm16:$imm)> {
1185 let Inst{21-20} = 0b01;
1188 def MVE_VRSHR_immu16 : MVE_VRSHR_imm<"u16", (ins shr_imm16:$imm)> {
1190 let Inst{21-20} = 0b01;
1193 def MVE_VRSHR_imms32 : MVE_VRSHR_imm<"s32", (ins shr_imm32:$imm)> {
1198 def MVE_VRSHR_immu32 : MVE_VRSHR_imm<"u32", (ins shr_imm32:$imm)> {
1203 class MVE_VSHR_imm<string suffix, dag imm>
1204 : MVE_shift_with_imm<"vshr", suffix, (outs MQPR:$Qd),
1205 !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
1209 let Inst{25-24} = 0b11;
1210 let Inst{21-16} = imm;
1211 let Inst{10-8} = 0b000;
1214 def MVE_VSHR_imms8 : MVE_VSHR_imm<"s8", (ins shr_imm8:$imm)> {
1216 let Inst{21-19} = 0b001;
1219 def MVE_VSHR_immu8 : MVE_VSHR_imm<"u8", (ins shr_imm8:$imm)> {
1221 let Inst{21-19} = 0b001;
1224 def MVE_VSHR_imms16 : MVE_VSHR_imm<"s16", (ins shr_imm16:$imm)> {
1226 let Inst{21-20} = 0b01;
1229 def MVE_VSHR_immu16 : MVE_VSHR_imm<"u16", (ins shr_imm16:$imm)> {
1231 let Inst{21-20} = 0b01;
1234 def MVE_VSHR_imms32 : MVE_VSHR_imm<"s32", (ins shr_imm32:$imm)> {
1239 def MVE_VSHR_immu32 : MVE_VSHR_imm<"u32", (ins shr_imm32:$imm)> {
1244 class MVE_VSHL_imm<string suffix, dag imm>
1245 : MVE_shift_with_imm<"vshl", suffix, (outs MQPR:$Qd),
1246 !con((ins MQPR:$Qm), imm), "$Qd, $Qm, $imm",
1251 let Inst{25-24} = 0b11;
1252 let Inst{21-16} = imm;
1253 let Inst{10-8} = 0b101;
1256 def MVE_VSHL_immi8 : MVE_VSHL_imm<"i8", (ins imm0_7:$imm)> {
1257 let Inst{21-19} = 0b001;
1260 def MVE_VSHL_immi16 : MVE_VSHL_imm<"i16", (ins imm0_15:$imm)> {
1261 let Inst{21-20} = 0b01;
1264 def MVE_VSHL_immi32 : MVE_VSHL_imm<"i32", (ins imm0_31:$imm)> {
1267 // end of mve_shift instructions
1269 // start of mve_bit instructions
1271 class MVE_bit_arith<dag oops, dag iops, string iname, string suffix,
1272 string ops, string cstr, list<dag> pattern=[]>
1273 : MVE_p<oops, iops, NoItinerary, iname, suffix, ops, vpred_r, cstr, pattern> {
1277 let Inst{22} = Qd{3};
1278 let Inst{15-13} = Qd{2-0};
1279 let Inst{5} = Qm{3};
1280 let Inst{3-1} = Qm{2-0};
1283 def MVE_VBIC : MVE_bit_arith<(outs MQPR:$Qd), (ins MQPR:$Qn, MQPR:$Qm),
1284 "vbic", "", "$Qd, $Qn, $Qm", ""> {
1288 let Inst{25-23} = 0b110;
1289 let Inst{21-20} = 0b01;
1290 let Inst{19-17} = Qn{2-0};
1292 let Inst{12-8} = 0b00001;
1293 let Inst{7} = Qn{3};
1299 class MVE_VREV<string iname, string suffix, bits<2> size, bits<2> bit_8_7>
1300 : MVE_bit_arith<(outs MQPR:$Qd), (ins MQPR:$Qm), iname,
1301 suffix, "$Qd, $Qm", ""> {
1304 let Inst{25-23} = 0b111;
1305 let Inst{21-20} = 0b11;
1306 let Inst{19-18} = size;
1307 let Inst{17-16} = 0b00;
1308 let Inst{12-9} = 0b0000;
1309 let Inst{8-7} = bit_8_7;
1315 def MVE_VREV64_8 : MVE_VREV<"vrev64", "8", 0b00, 0b00>;
1316 def MVE_VREV64_16 : MVE_VREV<"vrev64", "16", 0b01, 0b00>;
1317 def MVE_VREV64_32 : MVE_VREV<"vrev64", "32", 0b10, 0b00>;
1319 def MVE_VREV32_8 : MVE_VREV<"vrev32", "8", 0b00, 0b01>;
1320 def MVE_VREV32_16 : MVE_VREV<"vrev32", "16", 0b01, 0b01>;
1322 def MVE_VREV16_8 : MVE_VREV<"vrev16", "8", 0b00, 0b10>;
1324 def MVE_VMVN : MVE_bit_arith<(outs MQPR:$Qd), (ins MQPR:$Qm),
1325 "vmvn", "", "$Qd, $Qm", ""> {
1327 let Inst{25-23} = 0b111;
1328 let Inst{21-16} = 0b110000;
1329 let Inst{12-6} = 0b0010111;
1334 class MVE_bit_ops<string iname, bits<2> bit_21_20, bit bit_28>
1335 : MVE_bit_arith<(outs MQPR:$Qd), (ins MQPR:$Qn, MQPR:$Qm),
1336 iname, "", "$Qd, $Qn, $Qm", ""> {
1339 let Inst{28} = bit_28;
1340 let Inst{25-23} = 0b110;
1341 let Inst{21-20} = bit_21_20;
1342 let Inst{19-17} = Qn{2-0};
1344 let Inst{12-8} = 0b00001;
1345 let Inst{7} = Qn{3};
1351 def MVE_VEOR : MVE_bit_ops<"veor", 0b00, 0b1>;
1352 def MVE_VORN : MVE_bit_ops<"vorn", 0b11, 0b0>;
1353 def MVE_VORR : MVE_bit_ops<"vorr", 0b10, 0b0>;
1354 def MVE_VAND : MVE_bit_ops<"vand", 0b00, 0b0>;
1356 // add ignored suffixes as aliases
1358 foreach s=["s8", "s16", "s32", "u8", "u16", "u32", "i8", "i16", "i32", "f16", "f32"] in {
1359 def : MVEInstAlias<"vbic${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
1360 (MVE_VBIC MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
1361 def : MVEInstAlias<"veor${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
1362 (MVE_VEOR MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
1363 def : MVEInstAlias<"vorn${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
1364 (MVE_VORN MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
1365 def : MVEInstAlias<"vorr${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
1366 (MVE_VORR MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
1367 def : MVEInstAlias<"vand${vp}." # s # "\t$QdSrc, $QnSrc, $QmSrc",
1368 (MVE_VAND MQPR:$QdSrc, MQPR:$QnSrc, MQPR:$QmSrc, vpred_r:$vp)>;
1371 class MVE_bit_cmode<string iname, string suffix, bits<4> cmode, dag inOps>
1372 : MVE_p<(outs MQPR:$Qd), inOps, NoItinerary,
1373 iname, suffix, "$Qd, $imm", vpred_n, "$Qd = $Qd_src"> {
1377 let Inst{28} = imm{7};
1378 let Inst{27-23} = 0b11111;
1379 let Inst{22} = Qd{3};
1380 let Inst{21-19} = 0b000;
1381 let Inst{18-16} = imm{6-4};
1382 let Inst{15-13} = Qd{2-0};
1384 let Inst{11-8} = cmode;
1385 let Inst{7-6} = 0b01;
1387 let Inst{3-0} = imm{3-0};
1390 class MVE_VORR<string suffix, bits<4> cmode, ExpandImm imm_type>
1391 : MVE_bit_cmode<"vorr", suffix, cmode, (ins MQPR:$Qd_src, imm_type:$imm)> {
1395 def MVE_VORRIZ0v4i32 : MVE_VORR<"i32", 0b0001, expzero00>;
1396 def MVE_VORRIZ0v8i16 : MVE_VORR<"i16", 0b1001, expzero00>;
1397 def MVE_VORRIZ8v4i32 : MVE_VORR<"i32", 0b0011, expzero08>;
1398 def MVE_VORRIZ8v8i16 : MVE_VORR<"i16", 0b1011, expzero08>;
1399 def MVE_VORRIZ16v4i32 : MVE_VORR<"i32", 0b0101, expzero16>;
1400 def MVE_VORRIZ24v4i32 : MVE_VORR<"i32", 0b0111, expzero24>;
1402 def MVE_VORNIZ0v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
1403 (ins MQPR:$Qd_src, expzero00inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
1404 def MVE_VORNIZ0v8i16 : MVEAsmPseudo<"vorn${vp}.i16\t$Qd, $imm",
1405 (ins MQPR:$Qd_src, expzero00inv16:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
1406 def MVE_VORNIZ8v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
1407 (ins MQPR:$Qd_src, expzero08inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
1408 def MVE_VORNIZ8v8i16 : MVEAsmPseudo<"vorn${vp}.i16\t$Qd, $imm",
1409 (ins MQPR:$Qd_src, expzero08inv16:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
1410 def MVE_VORNIZ16v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
1411 (ins MQPR:$Qd_src, expzero16inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
1412 def MVE_VORNIZ24v4i32 : MVEAsmPseudo<"vorn${vp}.i32\t$Qd, $imm",
1413 (ins MQPR:$Qd_src, expzero24inv32:$imm, vpred_n:$vp), (outs MQPR:$Qd)>;
1415 def MVE_VMOV : MVEInstAlias<"vmov${vp}\t$Qd, $Qm",
1416 (MVE_VORR MQPR:$Qd, MQPR:$Qm, MQPR:$Qm, vpred_r:$vp)>;
1418 class MVE_VBIC<string suffix, bits<4> cmode, ExpandImm imm_type>
1419 : MVE_bit_cmode<"vbic", suffix, cmode, (ins MQPR:$Qd_src, imm_type:$imm)> {
1423 def MVE_VBICIZ0v4i32 : MVE_VBIC<"i32", 0b0001, expzero00>;
1424 def MVE_VBICIZ0v8i16 : MVE_VBIC<"i16", 0b1001, expzero00>;
1425 def MVE_VBICIZ8v4i32 : MVE_VBIC<"i32", 0b0011, expzero08>;
1426 def MVE_VBICIZ8v8i16 : MVE_VBIC<"i16", 0b1011, expzero08>;
1427 def MVE_VBICIZ16v4i32 : MVE_VBIC<"i32", 0b0101, expzero16>;
1428 def MVE_VBICIZ24v4i32 : MVE_VBIC<"i32", 0b0111, expzero24>;
1430 def MVE_VANDIZ0v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
1431 (ins MQPR:$Qda_src, expzero00inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
1432 def MVE_VANDIZ0v8i16 : MVEAsmPseudo<"vand${vp}.i16\t$Qda, $imm",
1433 (ins MQPR:$Qda_src, expzero00inv16:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
1434 def MVE_VANDIZ8v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
1435 (ins MQPR:$Qda_src, expzero08inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
1436 def MVE_VANDIZ8v8i16 : MVEAsmPseudo<"vand${vp}.i16\t$Qda, $imm",
1437 (ins MQPR:$Qda_src, expzero08inv16:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
1438 def MVE_VANDIZ16v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
1439 (ins MQPR:$Qda_src, expzero16inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
1440 def MVE_VANDIZ24v4i32 : MVEAsmPseudo<"vand${vp}.i32\t$Qda, $imm",
1441 (ins MQPR:$Qda_src, expzero24inv32:$imm, vpred_n:$vp), (outs MQPR:$Qda)>;
1443 class MVE_VMOV_lane_direction {
1450 def MVE_VMOV_from_lane : MVE_VMOV_lane_direction {
1452 let oops = (outs rGPR:$Rt);
1453 let iops = (ins MQPR:$Qd);
1454 let ops = "$Rt, $Qd$Idx";
1457 def MVE_VMOV_to_lane : MVE_VMOV_lane_direction {
1459 let oops = (outs MQPR:$Qd);
1460 let iops = (ins MQPR:$Qd_src, rGPR:$Rt);
1461 let ops = "$Qd$Idx, $Rt";
1462 let cstr = "$Qd = $Qd_src";
1465 class MVE_VMOV_lane<string suffix, bit U, dag indexop,
1466 MVE_VMOV_lane_direction dir>
1467 : MVE_VMOV_lane_base<dir.oops, !con(dir.iops, indexop), NoItinerary,
1468 "vmov", suffix, dir.ops, dir.cstr, []> {
1472 let Inst{31-24} = 0b11101110;
1474 let Inst{20} = dir.bit_20;
1475 let Inst{19-17} = Qd{2-0};
1476 let Inst{15-12} = Rt{3-0};
1477 let Inst{11-8} = 0b1011;
1478 let Inst{7} = Qd{3};
1479 let Inst{4-0} = 0b10000;
1482 class MVE_VMOV_lane_32<MVE_VMOV_lane_direction dir>
1483 : MVE_VMOV_lane<"32", 0b0, (ins MVEVectorIndex<4>:$Idx), dir> {
1486 let Inst{6-5} = 0b00;
1487 let Inst{16} = Idx{1};
1488 let Inst{21} = Idx{0};
1490 let Predicates = [HasFPRegsV8_1M];
1493 class MVE_VMOV_lane_16<string suffix, bit U, MVE_VMOV_lane_direction dir>
1494 : MVE_VMOV_lane<suffix, U, (ins MVEVectorIndex<8>:$Idx), dir> {
1498 let Inst{16} = Idx{2};
1499 let Inst{21} = Idx{1};
1500 let Inst{6} = Idx{0};
1503 class MVE_VMOV_lane_8<string suffix, bit U, MVE_VMOV_lane_direction dir>
1504 : MVE_VMOV_lane<suffix, U, (ins MVEVectorIndex<16>:$Idx), dir> {
1507 let Inst{16} = Idx{3};
1508 let Inst{21} = Idx{2};
1509 let Inst{6} = Idx{1};
1510 let Inst{5} = Idx{0};
1513 def MVE_VMOV_from_lane_32 : MVE_VMOV_lane_32< MVE_VMOV_from_lane>;
1514 def MVE_VMOV_to_lane_32 : MVE_VMOV_lane_32< MVE_VMOV_to_lane>;
1515 def MVE_VMOV_from_lane_s16 : MVE_VMOV_lane_16<"s16", 0b0, MVE_VMOV_from_lane>;
1516 def MVE_VMOV_from_lane_u16 : MVE_VMOV_lane_16<"u16", 0b1, MVE_VMOV_from_lane>;
1517 def MVE_VMOV_to_lane_16 : MVE_VMOV_lane_16< "16", 0b0, MVE_VMOV_to_lane>;
1518 def MVE_VMOV_from_lane_s8 : MVE_VMOV_lane_8 < "s8", 0b0, MVE_VMOV_from_lane>;
1519 def MVE_VMOV_from_lane_u8 : MVE_VMOV_lane_8 < "u8", 0b1, MVE_VMOV_from_lane>;
1520 def MVE_VMOV_to_lane_8 : MVE_VMOV_lane_8 < "8", 0b0, MVE_VMOV_to_lane>;
1522 // end of mve_bit instructions
1524 // start of MVE Integer instructions
1526 class MVE_int<string iname, string suffix, bits<2> size, list<dag> pattern=[]>
1527 : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qn, MQPR:$Qm), NoItinerary,
1528 iname, suffix, "$Qd, $Qn, $Qm", vpred_r, "", pattern> {
1533 let Inst{22} = Qd{3};
1534 let Inst{21-20} = size;
1535 let Inst{19-17} = Qn{2-0};
1536 let Inst{15-13} = Qd{2-0};
1537 let Inst{7} = Qn{3};
1539 let Inst{5} = Qm{3};
1540 let Inst{3-1} = Qm{2-0};
1543 class MVE_VMULt1<string suffix, bits<2> size, list<dag> pattern=[]>
1544 : MVE_int<"vmul", suffix, size, pattern> {
1547 let Inst{25-23} = 0b110;
1549 let Inst{12-8} = 0b01001;
1554 def MVE_VMULt1i8 : MVE_VMULt1<"i8", 0b00>;
1555 def MVE_VMULt1i16 : MVE_VMULt1<"i16", 0b01>;
1556 def MVE_VMULt1i32 : MVE_VMULt1<"i32", 0b10>;
1558 class MVE_VQxDMULH<string iname, string suffix, bits<2> size, bit rounding,
1559 list<dag> pattern=[]>
1560 : MVE_int<iname, suffix, size, pattern> {
1562 let Inst{28} = rounding;
1563 let Inst{25-23} = 0b110;
1565 let Inst{12-8} = 0b01011;
1570 class MVE_VQDMULH<string suffix, bits<2> size, list<dag> pattern=[]>
1571 : MVE_VQxDMULH<"vqdmulh", suffix, size, 0b0, pattern>;
1572 class MVE_VQRDMULH<string suffix, bits<2> size, list<dag> pattern=[]>
1573 : MVE_VQxDMULH<"vqrdmulh", suffix, size, 0b1, pattern>;
1575 def MVE_VQDMULHi8 : MVE_VQDMULH<"s8", 0b00>;
1576 def MVE_VQDMULHi16 : MVE_VQDMULH<"s16", 0b01>;
1577 def MVE_VQDMULHi32 : MVE_VQDMULH<"s32", 0b10>;
1579 def MVE_VQRDMULHi8 : MVE_VQRDMULH<"s8", 0b00>;
1580 def MVE_VQRDMULHi16 : MVE_VQRDMULH<"s16", 0b01>;
1581 def MVE_VQRDMULHi32 : MVE_VQRDMULH<"s32", 0b10>;
1583 class MVE_VADDSUB<string iname, string suffix, bits<2> size, bit subtract,
1584 list<dag> pattern=[]>
1585 : MVE_int<iname, suffix, size, pattern> {
1587 let Inst{28} = subtract;
1588 let Inst{25-23} = 0b110;
1590 let Inst{12-8} = 0b01000;
1595 class MVE_VADD<string suffix, bits<2> size, list<dag> pattern=[]>
1596 : MVE_VADDSUB<"vadd", suffix, size, 0b0, pattern>;
1597 class MVE_VSUB<string suffix, bits<2> size, list<dag> pattern=[]>
1598 : MVE_VADDSUB<"vsub", suffix, size, 0b1, pattern>;
1600 def MVE_VADDi8 : MVE_VADD<"i8", 0b00>;
1601 def MVE_VADDi16 : MVE_VADD<"i16", 0b01>;
1602 def MVE_VADDi32 : MVE_VADD<"i32", 0b10>;
1604 def MVE_VSUBi8 : MVE_VSUB<"i8", 0b00>;
1605 def MVE_VSUBi16 : MVE_VSUB<"i16", 0b01>;
1606 def MVE_VSUBi32 : MVE_VSUB<"i32", 0b10>;
1608 class MVE_VQADDSUB<string iname, string suffix, bit U, bit subtract,
1609 bits<2> size, list<dag> pattern=[]>
1610 : MVE_int<iname, suffix, size, pattern> {
1613 let Inst{25-23} = 0b110;
1615 let Inst{12-10} = 0b000;
1616 let Inst{9} = subtract;
1622 class MVE_VQADD<string suffix, bit U, bits<2> size, list<dag> pattern=[]>
1623 : MVE_VQADDSUB<"vqadd", suffix, U, 0b0, size, pattern>;
1624 class MVE_VQSUB<string suffix, bit U, bits<2> size, list<dag> pattern=[]>
1625 : MVE_VQADDSUB<"vqsub", suffix, U, 0b1, size, pattern>;
1627 def MVE_VQADDs8 : MVE_VQADD<"s8", 0b0, 0b00>;
1628 def MVE_VQADDs16 : MVE_VQADD<"s16", 0b0, 0b01>;
1629 def MVE_VQADDs32 : MVE_VQADD<"s32", 0b0, 0b10>;
1630 def MVE_VQADDu8 : MVE_VQADD<"u8", 0b1, 0b00>;
1631 def MVE_VQADDu16 : MVE_VQADD<"u16", 0b1, 0b01>;
1632 def MVE_VQADDu32 : MVE_VQADD<"u32", 0b1, 0b10>;
1634 def MVE_VQSUBs8 : MVE_VQSUB<"s8", 0b0, 0b00>;
1635 def MVE_VQSUBs16 : MVE_VQSUB<"s16", 0b0, 0b01>;
1636 def MVE_VQSUBs32 : MVE_VQSUB<"s32", 0b0, 0b10>;
1637 def MVE_VQSUBu8 : MVE_VQSUB<"u8", 0b1, 0b00>;
1638 def MVE_VQSUBu16 : MVE_VQSUB<"u16", 0b1, 0b01>;
1639 def MVE_VQSUBu32 : MVE_VQSUB<"u32", 0b1, 0b10>;
1641 class MVE_VABD_int<string suffix, bit U, bits<2> size, list<dag> pattern=[]>
1642 : MVE_int<"vabd", suffix, size, pattern> {
1645 let Inst{25-23} = 0b110;
1647 let Inst{12-8} = 0b00111;
1652 def MVE_VABDs8 : MVE_VABD_int<"s8", 0b0, 0b00>;
1653 def MVE_VABDs16 : MVE_VABD_int<"s16", 0b0, 0b01>;
1654 def MVE_VABDs32 : MVE_VABD_int<"s32", 0b0, 0b10>;
1655 def MVE_VABDu8 : MVE_VABD_int<"u8", 0b1, 0b00>;
1656 def MVE_VABDu16 : MVE_VABD_int<"u16", 0b1, 0b01>;
1657 def MVE_VABDu32 : MVE_VABD_int<"u32", 0b1, 0b10>;
1659 class MVE_VRHADD<string suffix, bit U, bits<2> size, list<dag> pattern=[]>
1660 : MVE_int<"vrhadd", suffix, size, pattern> {
1663 let Inst{25-23} = 0b110;
1665 let Inst{12-8} = 0b00001;
1670 def MVE_VRHADDs8 : MVE_VRHADD<"s8", 0b0, 0b00>;
1671 def MVE_VRHADDs16 : MVE_VRHADD<"s16", 0b0, 0b01>;
1672 def MVE_VRHADDs32 : MVE_VRHADD<"s32", 0b0, 0b10>;
1673 def MVE_VRHADDu8 : MVE_VRHADD<"u8", 0b1, 0b00>;
1674 def MVE_VRHADDu16 : MVE_VRHADD<"u16", 0b1, 0b01>;
1675 def MVE_VRHADDu32 : MVE_VRHADD<"u32", 0b1, 0b10>;
1677 class MVE_VHADDSUB<string iname, string suffix, bit U, bit subtract,
1678 bits<2> size, list<dag> pattern=[]>
1679 : MVE_int<iname, suffix, size, pattern> {
1682 let Inst{25-23} = 0b110;
1684 let Inst{12-10} = 0b000;
1685 let Inst{9} = subtract;
1691 class MVE_VHADD<string suffix, bit U, bits<2> size,
1692 list<dag> pattern=[]>
1693 : MVE_VHADDSUB<"vhadd", suffix, U, 0b0, size, pattern>;
1694 class MVE_VHSUB<string suffix, bit U, bits<2> size,
1695 list<dag> pattern=[]>
1696 : MVE_VHADDSUB<"vhsub", suffix, U, 0b1, size, pattern>;
1698 def MVE_VHADDs8 : MVE_VHADD<"s8", 0b0, 0b00>;
1699 def MVE_VHADDs16 : MVE_VHADD<"s16", 0b0, 0b01>;
1700 def MVE_VHADDs32 : MVE_VHADD<"s32", 0b0, 0b10>;
1701 def MVE_VHADDu8 : MVE_VHADD<"u8", 0b1, 0b00>;
1702 def MVE_VHADDu16 : MVE_VHADD<"u16", 0b1, 0b01>;
1703 def MVE_VHADDu32 : MVE_VHADD<"u32", 0b1, 0b10>;
1705 def MVE_VHSUBs8 : MVE_VHSUB<"s8", 0b0, 0b00>;
1706 def MVE_VHSUBs16 : MVE_VHSUB<"s16", 0b0, 0b01>;
1707 def MVE_VHSUBs32 : MVE_VHSUB<"s32", 0b0, 0b10>;
1708 def MVE_VHSUBu8 : MVE_VHSUB<"u8", 0b1, 0b00>;
1709 def MVE_VHSUBu16 : MVE_VHSUB<"u16", 0b1, 0b01>;
1710 def MVE_VHSUBu32 : MVE_VHSUB<"u32", 0b1, 0b10>;
1712 class MVE_VDUP<string suffix, bit B, bit E, list<dag> pattern=[]>
1713 : MVE_p<(outs MQPR:$Qd), (ins rGPR:$Rt), NoItinerary,
1714 "vdup", suffix, "$Qd, $Rt", vpred_r, "", pattern> {
1719 let Inst{25-23} = 0b101;
1721 let Inst{21-20} = 0b10;
1722 let Inst{19-17} = Qd{2-0};
1724 let Inst{15-12} = Rt;
1725 let Inst{11-8} = 0b1011;
1726 let Inst{7} = Qd{3};
1729 let Inst{4-0} = 0b10000;
1732 def MVE_VDUP32 : MVE_VDUP<"32", 0b0, 0b0>;
1733 def MVE_VDUP16 : MVE_VDUP<"16", 0b0, 0b1>;
1734 def MVE_VDUP8 : MVE_VDUP<"8", 0b1, 0b0>;
1736 class MVEIntSingleSrc<string iname, string suffix, bits<2> size,
1737 list<dag> pattern=[]>
1738 : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qm), NoItinerary,
1739 iname, suffix, "$Qd, $Qm", vpred_r, "", pattern> {
1743 let Inst{22} = Qd{3};
1744 let Inst{19-18} = size{1-0};
1745 let Inst{15-13} = Qd{2-0};
1746 let Inst{5} = Qm{3};
1747 let Inst{3-1} = Qm{2-0};
1750 class MVE_VCLSCLZ<string iname, string suffix, bits<2> size,
1751 bit count_zeroes, list<dag> pattern=[]>
1752 : MVEIntSingleSrc<iname, suffix, size, pattern> {
1755 let Inst{25-23} = 0b111;
1756 let Inst{21-20} = 0b11;
1757 let Inst{17-16} = 0b00;
1758 let Inst{12-8} = 0b00100;
1759 let Inst{7} = count_zeroes;
1765 def MVE_VCLSs8 : MVE_VCLSCLZ<"vcls", "s8", 0b00, 0b0>;
1766 def MVE_VCLSs16 : MVE_VCLSCLZ<"vcls", "s16", 0b01, 0b0>;
1767 def MVE_VCLSs32 : MVE_VCLSCLZ<"vcls", "s32", 0b10, 0b0>;
1769 def MVE_VCLZs8 : MVE_VCLSCLZ<"vclz", "i8", 0b00, 0b1>;
1770 def MVE_VCLZs16 : MVE_VCLSCLZ<"vclz", "i16", 0b01, 0b1>;
1771 def MVE_VCLZs32 : MVE_VCLSCLZ<"vclz", "i32", 0b10, 0b1>;
1773 class MVE_VABSNEG_int<string iname, string suffix, bits<2> size, bit negate,
1774 list<dag> pattern=[]>
1775 : MVEIntSingleSrc<iname, suffix, size, pattern> {
1778 let Inst{25-23} = 0b111;
1779 let Inst{21-20} = 0b11;
1780 let Inst{17-16} = 0b01;
1781 let Inst{12-8} = 0b00011;
1782 let Inst{7} = negate;
1788 def MVE_VABSs8 : MVE_VABSNEG_int<"vabs", "s8", 0b00, 0b0>;
1789 def MVE_VABSs16 : MVE_VABSNEG_int<"vabs", "s16", 0b01, 0b0>;
1790 def MVE_VABSs32 : MVE_VABSNEG_int<"vabs", "s32", 0b10, 0b0>;
1792 def MVE_VNEGs8 : MVE_VABSNEG_int<"vneg", "s8", 0b00, 0b1>;
1793 def MVE_VNEGs16 : MVE_VABSNEG_int<"vneg", "s16", 0b01, 0b1>;
1794 def MVE_VNEGs32 : MVE_VABSNEG_int<"vneg", "s32", 0b10, 0b1>;
1796 class MVE_VQABSNEG<string iname, string suffix, bits<2> size,
1797 bit negate, list<dag> pattern=[]>
1798 : MVEIntSingleSrc<iname, suffix, size, pattern> {
1801 let Inst{25-23} = 0b111;
1802 let Inst{21-20} = 0b11;
1803 let Inst{17-16} = 0b00;
1804 let Inst{12-8} = 0b00111;
1805 let Inst{7} = negate;
1811 def MVE_VQABSs8 : MVE_VQABSNEG<"vqabs", "s8", 0b00, 0b0>;
1812 def MVE_VQABSs16 : MVE_VQABSNEG<"vqabs", "s16", 0b01, 0b0>;
1813 def MVE_VQABSs32 : MVE_VQABSNEG<"vqabs", "s32", 0b10, 0b0>;
1815 def MVE_VQNEGs8 : MVE_VQABSNEG<"vqneg", "s8", 0b00, 0b1>;
1816 def MVE_VQNEGs16 : MVE_VQABSNEG<"vqneg", "s16", 0b01, 0b1>;
1817 def MVE_VQNEGs32 : MVE_VQABSNEG<"vqneg", "s32", 0b10, 0b1>;
1819 class MVE_mod_imm<string iname, string suffix, bits<4> cmode, bit op,
1820 dag iops, list<dag> pattern=[]>
1821 : MVE_p<(outs MQPR:$Qd), iops, NoItinerary, iname, suffix, "$Qd, $imm",
1822 vpred_r, "", pattern> {
1826 let Inst{28} = imm{7};
1827 let Inst{25-23} = 0b111;
1828 let Inst{22} = Qd{3};
1829 let Inst{21-19} = 0b000;
1830 let Inst{18-16} = imm{6-4};
1831 let Inst{15-13} = Qd{2-0};
1833 let Inst{11-8} = cmode{3-0};
1834 let Inst{7-6} = 0b01;
1837 let Inst{3-0} = imm{3-0};
1839 let DecoderMethod = "DecodeMVEModImmInstruction";
1842 let isReMaterializable = 1 in {
1843 let isAsCheapAsAMove = 1 in {
1844 def MVE_VMOVimmi8 : MVE_mod_imm<"vmov", "i8", {1,1,1,0}, 0b0, (ins nImmSplatI8:$imm)>;
1845 def MVE_VMOVimmi16 : MVE_mod_imm<"vmov", "i16", {1,0,?,0}, 0b0, (ins nImmSplatI16:$imm)> {
1846 let Inst{9} = imm{9};
1848 def MVE_VMOVimmi32 : MVE_mod_imm<"vmov", "i32", {?,?,?,?}, 0b0, (ins nImmVMOVI32:$imm)> {
1849 let Inst{11-8} = imm{11-8};
1851 def MVE_VMOVimmi64 : MVE_mod_imm<"vmov", "i64", {1,1,1,0}, 0b1, (ins nImmSplatI64:$imm)>;
1852 def MVE_VMOVimmf32 : MVE_mod_imm<"vmov", "f32", {1,1,1,1}, 0b0, (ins nImmVMOVF32:$imm)>;
1853 } // let isAsCheapAsAMove = 1
1855 def MVE_VMVNimmi16 : MVE_mod_imm<"vmvn", "i16", {1,0,?,0}, 0b1, (ins nImmSplatI16:$imm)> {
1856 let Inst{9} = imm{9};
1858 def MVE_VMVNimmi32 : MVE_mod_imm<"vmvn", "i32", {?,?,?,?}, 0b1, (ins nImmVMOVI32:$imm)> {
1859 let Inst{11-8} = imm{11-8};
1861 } // let isReMaterializable = 1
1863 class MVE_VMINMAXA<string iname, string suffix, bits<2> size,
1864 bit bit_12, list<dag> pattern=[]>
1865 : MVE_p<(outs MQPR:$Qd), (ins MQPR:$Qd_src, MQPR:$Qm),
1866 NoItinerary, iname, suffix, "$Qd, $Qm", vpred_n, "$Qd = $Qd_src",
1872 let Inst{25-23} = 0b100;
1873 let Inst{22} = Qd{3};
1874 let Inst{21-20} = 0b11;
1875 let Inst{19-18} = size;
1876 let Inst{17-16} = 0b11;
1877 let Inst{15-13} = Qd{2-0};
1878 let Inst{12} = bit_12;
1879 let Inst{11-6} = 0b111010;
1880 let Inst{5} = Qm{3};
1882 let Inst{3-1} = Qm{2-0};
1886 def MVE_VMAXAs8 : MVE_VMINMAXA<"vmaxa", "s8", 0b00, 0b0>;
1887 def MVE_VMAXAs16 : MVE_VMINMAXA<"vmaxa", "s16", 0b01, 0b0>;
1888 def MVE_VMAXAs32 : MVE_VMINMAXA<"vmaxa", "s32", 0b10, 0b0>;
1890 def MVE_VMINAs8 : MVE_VMINMAXA<"vmina", "s8", 0b00, 0b1>;
1891 def MVE_VMINAs16 : MVE_VMINMAXA<"vmina", "s16", 0b01, 0b1>;
1892 def MVE_VMINAs32 : MVE_VMINMAXA<"vmina", "s32", 0b10, 0b1>;
1894 // end of MVE Integer instructions
1896 class MVE_VPT<string suffix, bits<2> size, dag iops, string asm, list<dag> pattern=[]>
1897 : MVE_MI<(outs ), iops, NoItinerary, !strconcat("vpt", "${Mk}", ".", suffix), asm, "", pattern> {
1902 let Inst{31-23} = 0b111111100;
1903 let Inst{22} = Mk{3};
1904 let Inst{21-20} = size;
1905 let Inst{19-17} = Qn{2-0};
1907 let Inst{15-13} = Mk{2-0};
1908 let Inst{12} = fc{2};
1909 let Inst{11-8} = 0b1111;
1910 let Inst{7} = fc{0};
1913 let Defs = [VPR, P0];
1916 class MVE_VPTt1<string suffix, bits<2> size, dag iops>
1917 : MVE_VPT<suffix, size, iops, "$fc, $Qn, $Qm"> {
1922 let Inst{5} = Qm{3};
1923 let Inst{3-1} = Qm{2-0};
1924 let Inst{0} = fc{1};
1927 class MVE_VPTt1i<string suffix, bits<2> size>
1928 : MVE_VPTt1<suffix, size,
1929 (ins vpt_mask:$Mk, pred_basic_i:$fc, MQPR:$Qn, MQPR:$Qm)> {
1934 def MVE_VPTv4i32 : MVE_VPTt1i<"i32", 0b10>;
1935 def MVE_VPTv8i16 : MVE_VPTt1i<"i16", 0b01>;
1936 def MVE_VPTv16i8 : MVE_VPTt1i<"i8", 0b00>;
1938 class MVE_VPTt1u<string suffix, bits<2> size>
1939 : MVE_VPTt1<suffix, size,
1940 (ins vpt_mask:$Mk, pred_basic_u:$fc, MQPR:$Qn, MQPR:$Qm)> {
1945 def MVE_VPTv4u32 : MVE_VPTt1u<"u32", 0b10>;
1946 def MVE_VPTv8u16 : MVE_VPTt1u<"u16", 0b01>;
1947 def MVE_VPTv16u8 : MVE_VPTt1u<"u8", 0b00>;
1949 class MVE_VPTt1s<string suffix, bits<2> size>
1950 : MVE_VPTt1<suffix, size,
1951 (ins vpt_mask:$Mk, pred_basic_s:$fc, MQPR:$Qn, MQPR:$Qm)> {
1955 def MVE_VPTv4s32 : MVE_VPTt1s<"s32", 0b10>;
1956 def MVE_VPTv8s16 : MVE_VPTt1s<"s16", 0b01>;
1957 def MVE_VPTv16s8 : MVE_VPTt1s<"s8", 0b00>;
1959 class MVE_VPTt2<string suffix, bits<2> size, dag iops>
1960 : MVE_VPT<suffix, size, iops,
1967 let Inst{5} = fc{1};
1968 let Inst{3-0} = Rm{3-0};
1971 class MVE_VPTt2i<string suffix, bits<2> size>
1972 : MVE_VPTt2<suffix, size,
1973 (ins vpt_mask:$Mk, pred_basic_i:$fc, MQPR:$Qn, GPRwithZR:$Rm)> {
1978 def MVE_VPTv4i32r : MVE_VPTt2i<"i32", 0b10>;
1979 def MVE_VPTv8i16r : MVE_VPTt2i<"i16", 0b01>;
1980 def MVE_VPTv16i8r : MVE_VPTt2i<"i8", 0b00>;
1982 class MVE_VPTt2u<string suffix, bits<2> size>
1983 : MVE_VPTt2<suffix, size,
1984 (ins vpt_mask:$Mk, pred_basic_u:$fc, MQPR:$Qn, GPRwithZR:$Rm)> {
1989 def MVE_VPTv4u32r : MVE_VPTt2u<"u32", 0b10>;
1990 def MVE_VPTv8u16r : MVE_VPTt2u<"u16", 0b01>;
1991 def MVE_VPTv16u8r : MVE_VPTt2u<"u8", 0b00>;
1993 class MVE_VPTt2s<string suffix, bits<2> size>
1994 : MVE_VPTt2<suffix, size,
1995 (ins vpt_mask:$Mk, pred_basic_s:$fc, MQPR:$Qn, GPRwithZR:$Rm)> {
1999 def MVE_VPTv4s32r : MVE_VPTt2s<"s32", 0b10>;
2000 def MVE_VPTv8s16r : MVE_VPTt2s<"s16", 0b01>;
2001 def MVE_VPTv16s8r : MVE_VPTt2s<"s8", 0b00>;
2004 class MVE_VPTf<string suffix, bit size, dag iops, string asm, list<dag> pattern=[]>
2005 : MVE_MI<(outs ), iops, NoItinerary, !strconcat("vpt", "${Mk}", ".", suffix), asm,
2011 let Inst{31-29} = 0b111;
2012 let Inst{28} = size;
2013 let Inst{27-23} = 0b11100;
2014 let Inst{22} = Mk{3};
2015 let Inst{21-20} = 0b11;
2016 let Inst{19-17} = Qn{2-0};
2018 let Inst{15-13} = Mk{2-0};
2019 let Inst{12} = fc{2};
2020 let Inst{11-8} = 0b1111;
2021 let Inst{7} = fc{0};
2025 let Predicates = [HasMVEFloat];
2028 class MVE_VPTft1<string suffix, bit size>
2029 : MVE_VPTf<suffix, size, (ins vpt_mask:$Mk, pred_basic_fp:$fc, MQPR:$Qn, MQPR:$Qm),
2035 let Inst{5} = Qm{3};
2036 let Inst{3-1} = Qm{2-0};
2037 let Inst{0} = fc{1};
2040 def MVE_VPTv4f32 : MVE_VPTft1<"f32", 0b0>;
2041 def MVE_VPTv8f16 : MVE_VPTft1<"f16", 0b1>;
2043 class MVE_VPTft2<string suffix, bit size>
2044 : MVE_VPTf<suffix, size, (ins vpt_mask:$Mk, pred_basic_fp:$fc, MQPR:$Qn, GPRwithZR:$Rm),
2050 let Inst{5} = fc{1};
2051 let Inst{3-0} = Rm{3-0};
2054 def MVE_VPTv4f32r : MVE_VPTft2<"f32", 0b0>;
2055 def MVE_VPTv8f16r : MVE_VPTft2<"f16", 0b1>;
2057 def MVE_VPST : MVE_MI<(outs ), (ins vpt_mask:$Mk), NoItinerary,
2058 !strconcat("vpst", "${Mk}"), "", "", []> {
2061 let Inst{31-23} = 0b111111100;
2062 let Inst{22} = Mk{3};
2063 let Inst{21-16} = 0b110001;
2064 let Inst{15-13} = Mk{2-0};
2065 let Inst{12-0} = 0b0111101001101;
2066 let Unpredictable{12} = 0b1;
2067 let Unpredictable{7} = 0b1;
2068 let Unpredictable{5} = 0b1;