1 //===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tblgen -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 //===----------------------------------------------------------------------===//
11 // Describe AArch64 instructions format here
14 // Format specifies the encoding used by the instruction. This is part of the
15 // ad-hoc solution used to emit machine instruction encodings by our machine
17 class Format<bits<2> val> {
21 def PseudoFrm : Format<0>;
22 def NormalFrm : Format<1>; // Do we need any others?
24 // AArch64 Instruction Format
25 class AArch64Inst<Format f, string cstr> : Instruction {
26 field bits<32> Inst; // Instruction encoding.
27 // Mask of bits that cause an encoding to be UNPREDICTABLE.
28 // If a bit is set, then if the corresponding bit in the
29 // target encoding differs from its value in the "Inst" field,
30 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
31 field bits<32> Unpredictable = 0;
32 // SoftFail is the generic name for this field, but we alias it so
33 // as to make it more obvious what it means in ARM-land.
34 field bits<32> SoftFail = Unpredictable;
35 let Namespace = "AArch64";
37 bits<2> Form = F.Value;
39 let Constraints = cstr;
42 class InstSubst<string Asm, dag Result, bit EmitPriority = 0>
43 : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>;
45 // Pseudo instructions (don't have encoding information)
46 class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">
47 : AArch64Inst<PseudoFrm, cstr> {
48 dag OutOperandList = oops;
49 dag InOperandList = iops;
50 let Pattern = pattern;
51 let isCodeGenOnly = 1;
54 // Real instructions (have encoding information)
55 class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> {
56 let Pattern = pattern;
60 // Enum describing whether an instruction is
61 // destructive in its first source operand.
62 class DestructiveInstTypeEnum<bits<1> val> {
65 def NotDestructive : DestructiveInstTypeEnum<0>;
66 def Destructive : DestructiveInstTypeEnum<1>;
68 // Normal instructions
69 class I<dag oops, dag iops, string asm, string operands, string cstr,
71 : EncodedI<cstr, pattern> {
72 dag OutOperandList = oops;
73 dag InOperandList = iops;
74 let AsmString = !strconcat(asm, operands);
76 // Destructive operations (SVE)
77 DestructiveInstTypeEnum DestructiveInstType = NotDestructive;
78 ElementSizeEnum ElementSize = ElementSizeB;
80 let TSFlags{3} = DestructiveInstType.Value;
81 let TSFlags{2-0} = ElementSize.Value;
84 class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>;
85 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
86 class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>;
88 // Helper fragment for an extract of the high portion of a 128-bit vector.
89 def extract_high_v16i8 :
90 UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>;
91 def extract_high_v8i16 :
92 UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>;
93 def extract_high_v4i32 :
94 UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>;
95 def extract_high_v2i64 :
96 UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>;
98 //===----------------------------------------------------------------------===//
99 // Asm Operand Classes.
102 // Shifter operand for arithmetic shifted encodings.
103 def ShifterOperand : AsmOperandClass {
104 let Name = "Shifter";
107 // Shifter operand for mov immediate encodings.
108 def MovImm32ShifterOperand : AsmOperandClass {
109 let SuperClasses = [ShifterOperand];
110 let Name = "MovImm32Shifter";
111 let RenderMethod = "addShifterOperands";
112 let DiagnosticType = "InvalidMovImm32Shift";
114 def MovImm64ShifterOperand : AsmOperandClass {
115 let SuperClasses = [ShifterOperand];
116 let Name = "MovImm64Shifter";
117 let RenderMethod = "addShifterOperands";
118 let DiagnosticType = "InvalidMovImm64Shift";
121 // Shifter operand for arithmetic register shifted encodings.
122 class ArithmeticShifterOperand<int width> : AsmOperandClass {
123 let SuperClasses = [ShifterOperand];
124 let Name = "ArithmeticShifter" # width;
125 let PredicateMethod = "isArithmeticShifter<" # width # ">";
126 let RenderMethod = "addShifterOperands";
127 let DiagnosticType = "AddSubRegShift" # width;
130 def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
131 def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
133 // Shifter operand for logical register shifted encodings.
134 class LogicalShifterOperand<int width> : AsmOperandClass {
135 let SuperClasses = [ShifterOperand];
136 let Name = "LogicalShifter" # width;
137 let PredicateMethod = "isLogicalShifter<" # width # ">";
138 let RenderMethod = "addShifterOperands";
139 let DiagnosticType = "AddSubRegShift" # width;
142 def LogicalShifterOperand32 : LogicalShifterOperand<32>;
143 def LogicalShifterOperand64 : LogicalShifterOperand<64>;
145 // Shifter operand for logical vector 128/64-bit shifted encodings.
146 def LogicalVecShifterOperand : AsmOperandClass {
147 let SuperClasses = [ShifterOperand];
148 let Name = "LogicalVecShifter";
149 let RenderMethod = "addShifterOperands";
151 def LogicalVecHalfWordShifterOperand : AsmOperandClass {
152 let SuperClasses = [LogicalVecShifterOperand];
153 let Name = "LogicalVecHalfWordShifter";
154 let RenderMethod = "addShifterOperands";
157 // The "MSL" shifter on the vector MOVI instruction.
158 def MoveVecShifterOperand : AsmOperandClass {
159 let SuperClasses = [ShifterOperand];
160 let Name = "MoveVecShifter";
161 let RenderMethod = "addShifterOperands";
164 // Extend operand for arithmetic encodings.
165 def ExtendOperand : AsmOperandClass {
167 let DiagnosticType = "AddSubRegExtendLarge";
169 def ExtendOperand64 : AsmOperandClass {
170 let SuperClasses = [ExtendOperand];
171 let Name = "Extend64";
172 let DiagnosticType = "AddSubRegExtendSmall";
174 // 'extend' that's a lsl of a 64-bit register.
175 def ExtendOperandLSL64 : AsmOperandClass {
176 let SuperClasses = [ExtendOperand];
177 let Name = "ExtendLSL64";
178 let RenderMethod = "addExtend64Operands";
179 let DiagnosticType = "AddSubRegExtendLarge";
182 // 8-bit floating-point immediate encodings.
183 def FPImmOperand : AsmOperandClass {
185 let ParserMethod = "tryParseFPImm<true>";
186 let DiagnosticType = "InvalidFPImm";
189 def CondCode : AsmOperandClass {
190 let Name = "CondCode";
191 let DiagnosticType = "InvalidCondCode";
194 // A 32-bit register pasrsed as 64-bit
195 def GPR32as64Operand : AsmOperandClass {
196 let Name = "GPR32as64";
198 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>";
200 def GPR32as64 : RegisterOperand<GPR32> {
201 let ParserMatchClass = GPR32as64Operand;
204 // A 64-bit register pasrsed as 32-bit
205 def GPR64as32Operand : AsmOperandClass {
206 let Name = "GPR64as32";
208 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>";
210 def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> {
211 let ParserMatchClass = GPR64as32Operand;
214 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
215 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
216 // are encoded as the eight bit value 'abcdefgh'.
217 def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
219 class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {
220 let Name = "UImm" # Width # "s" # Scale;
221 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width;
222 let RenderMethod = "addImmScaledOperands<" # Scale # ">";
223 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">";
226 class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {
227 let Name = "SImm" # Width # "s" # Scale;
228 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width;
229 let RenderMethod = "addImmScaledOperands<" # Scale # ">";
230 let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">";
233 //===----------------------------------------------------------------------===//
234 // Operand Definitions.
237 // ADR[P] instruction labels.
238 def AdrpOperand : AsmOperandClass {
239 let Name = "AdrpLabel";
240 let ParserMethod = "tryParseAdrpLabel";
241 let DiagnosticType = "InvalidLabel";
243 def adrplabel : Operand<i64> {
244 let EncoderMethod = "getAdrLabelOpValue";
245 let PrintMethod = "printAdrpLabel";
246 let ParserMatchClass = AdrpOperand;
249 def AdrOperand : AsmOperandClass {
250 let Name = "AdrLabel";
251 let ParserMethod = "tryParseAdrLabel";
252 let DiagnosticType = "InvalidLabel";
254 def adrlabel : Operand<i64> {
255 let EncoderMethod = "getAdrLabelOpValue";
256 let ParserMatchClass = AdrOperand;
259 class SImmOperand<int width> : AsmOperandClass {
260 let Name = "SImm" # width;
261 let DiagnosticType = "InvalidMemoryIndexedSImm" # width;
262 let RenderMethod = "addImmOperands";
263 let PredicateMethod = "isSImm<" # width # ">";
266 // Authenticated loads for v8.3 can have scaled 10-bit immediate offsets.
267 def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>;
268 def simm10Scaled : Operand<i64> {
269 let ParserMatchClass = SImm10s8Operand;
270 let DecoderMethod = "DecodeSImm<10>";
271 let PrintMethod = "printImmScale<8>";
274 // uimm6 predicate - True if the immediate is in the range [0, 63].
275 def UImm6Operand : AsmOperandClass {
277 let DiagnosticType = "InvalidImm0_63";
280 def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
281 let ParserMatchClass = UImm6Operand;
284 def SImm9Operand : SImmOperand<9>;
285 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
286 let ParserMatchClass = SImm9Operand;
287 let DecoderMethod = "DecodeSImm<9>";
290 def SImm8Operand : SImmOperand<8>;
291 def simm8 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -128 && Imm < 127; }]> {
292 let ParserMatchClass = SImm8Operand;
293 let DecoderMethod = "DecodeSImm<8>";
296 def SImm6Operand : SImmOperand<6>;
297 def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> {
298 let ParserMatchClass = SImm6Operand;
299 let DecoderMethod = "DecodeSImm<6>";
302 def SImm5Operand : SImmOperand<5>;
303 def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> {
304 let ParserMatchClass = SImm5Operand;
305 let DecoderMethod = "DecodeSImm<5>";
308 def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> {
309 let ParserMatchClass = SImm5Operand;
310 let DecoderMethod = "DecodeSImm<5>";
313 // simm7sN predicate - True if the immediate is a multiple of N in the range
314 // [-64 * N, 63 * N].
316 def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>;
317 def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>;
318 def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>;
320 def simm7s4 : Operand<i32> {
321 let ParserMatchClass = SImm7s4Operand;
322 let PrintMethod = "printImmScale<4>";
325 def simm7s8 : Operand<i32> {
326 let ParserMatchClass = SImm7s8Operand;
327 let PrintMethod = "printImmScale<8>";
330 def simm7s16 : Operand<i32> {
331 let ParserMatchClass = SImm7s16Operand;
332 let PrintMethod = "printImmScale<16>";
335 def am_indexed7s8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>;
336 def am_indexed7s16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>;
337 def am_indexed7s32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>;
338 def am_indexed7s64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>;
339 def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>;
341 // uimm5sN predicate - True if the immediate is a multiple of N in the range
343 def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>;
344 def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>;
345 def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>;
347 def uimm5s2 : Operand<i64>, ImmLeaf<i64,
348 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }]> {
349 let ParserMatchClass = UImm5s2Operand;
350 let PrintMethod = "printImmScale<2>";
352 def uimm5s4 : Operand<i64>, ImmLeaf<i64,
353 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }]> {
354 let ParserMatchClass = UImm5s4Operand;
355 let PrintMethod = "printImmScale<4>";
357 def uimm5s8 : Operand<i64>, ImmLeaf<i64,
358 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }]> {
359 let ParserMatchClass = UImm5s8Operand;
360 let PrintMethod = "printImmScale<8>";
363 // uimm6sN predicate - True if the immediate is a multiple of N in the range
365 def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>;
366 def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>;
367 def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>;
368 def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>;
370 def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {
371 let ParserMatchClass = UImm6s1Operand;
373 def uimm6s2 : Operand<i64>, ImmLeaf<i64,
374 [{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> {
375 let PrintMethod = "printImmScale<2>";
376 let ParserMatchClass = UImm6s2Operand;
378 def uimm6s4 : Operand<i64>, ImmLeaf<i64,
379 [{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> {
380 let PrintMethod = "printImmScale<4>";
381 let ParserMatchClass = UImm6s4Operand;
383 def uimm6s8 : Operand<i64>, ImmLeaf<i64,
384 [{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> {
385 let PrintMethod = "printImmScale<8>";
386 let ParserMatchClass = UImm6s8Operand;
389 // simm6sN predicate - True if the immediate is a multiple of N in the range
390 // [-32 * N, 31 * N].
391 def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>;
392 def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> {
393 let ParserMatchClass = SImm6s1Operand;
394 let DecoderMethod = "DecodeSImm<6>";
397 // simm4sN predicate - True if the immediate is a multiple of N in the range
399 def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>;
400 def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>;
401 def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>;
402 def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>;
403 def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>;
405 def simm4s1 : Operand<i64>, ImmLeaf<i64,
406 [{ return Imm >=-8 && Imm <= 7; }]> {
407 let ParserMatchClass = SImm4s1Operand;
408 let DecoderMethod = "DecodeSImm<4>";
411 def simm4s2 : Operand<i64>, ImmLeaf<i64,
412 [{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }]> {
413 let PrintMethod = "printImmScale<2>";
414 let ParserMatchClass = SImm4s2Operand;
415 let DecoderMethod = "DecodeSImm<4>";
418 def simm4s3 : Operand<i64>, ImmLeaf<i64,
419 [{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }]> {
420 let PrintMethod = "printImmScale<3>";
421 let ParserMatchClass = SImm4s3Operand;
422 let DecoderMethod = "DecodeSImm<4>";
425 def simm4s4 : Operand<i64>, ImmLeaf<i64,
426 [{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }]> {
427 let PrintMethod = "printImmScale<4>";
428 let ParserMatchClass = SImm4s4Operand;
429 let DecoderMethod = "DecodeSImm<4>";
431 def simm4s16 : Operand<i64>, ImmLeaf<i64,
432 [{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }]> {
433 let PrintMethod = "printImmScale<16>";
434 let ParserMatchClass = SImm4s16Operand;
435 let DecoderMethod = "DecodeSImm<4>";
438 class AsmImmRange<int Low, int High> : AsmOperandClass {
439 let Name = "Imm" # Low # "_" # High;
440 let DiagnosticType = "InvalidImm" # Low # "_" # High;
441 let RenderMethod = "addImmOperands";
442 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">";
445 def Imm1_8Operand : AsmImmRange<1, 8>;
446 def Imm1_16Operand : AsmImmRange<1, 16>;
447 def Imm1_32Operand : AsmImmRange<1, 32>;
448 def Imm1_64Operand : AsmImmRange<1, 64>;
450 class BranchTarget<int N> : AsmOperandClass {
451 let Name = "BranchTarget" # N;
452 let DiagnosticType = "InvalidLabel";
453 let PredicateMethod = "isBranchTarget<" # N # ">";
456 class PCRelLabel<int N> : BranchTarget<N> {
457 let Name = "PCRelLabel" # N;
460 def BranchTarget14Operand : BranchTarget<14>;
461 def BranchTarget26Operand : BranchTarget<26>;
462 def PCRelLabel19Operand : PCRelLabel<19>;
464 def MovZSymbolG3AsmOperand : AsmOperandClass {
465 let Name = "MovZSymbolG3";
466 let RenderMethod = "addImmOperands";
469 def movz_symbol_g3 : Operand<i32> {
470 let ParserMatchClass = MovZSymbolG3AsmOperand;
473 def MovZSymbolG2AsmOperand : AsmOperandClass {
474 let Name = "MovZSymbolG2";
475 let RenderMethod = "addImmOperands";
478 def movz_symbol_g2 : Operand<i32> {
479 let ParserMatchClass = MovZSymbolG2AsmOperand;
482 def MovZSymbolG1AsmOperand : AsmOperandClass {
483 let Name = "MovZSymbolG1";
484 let RenderMethod = "addImmOperands";
487 def movz_symbol_g1 : Operand<i32> {
488 let ParserMatchClass = MovZSymbolG1AsmOperand;
491 def MovZSymbolG0AsmOperand : AsmOperandClass {
492 let Name = "MovZSymbolG0";
493 let RenderMethod = "addImmOperands";
496 def movz_symbol_g0 : Operand<i32> {
497 let ParserMatchClass = MovZSymbolG0AsmOperand;
500 def MovKSymbolG3AsmOperand : AsmOperandClass {
501 let Name = "MovKSymbolG3";
502 let RenderMethod = "addImmOperands";
505 def movk_symbol_g3 : Operand<i32> {
506 let ParserMatchClass = MovKSymbolG3AsmOperand;
509 def MovKSymbolG2AsmOperand : AsmOperandClass {
510 let Name = "MovKSymbolG2";
511 let RenderMethod = "addImmOperands";
514 def movk_symbol_g2 : Operand<i32> {
515 let ParserMatchClass = MovKSymbolG2AsmOperand;
518 def MovKSymbolG1AsmOperand : AsmOperandClass {
519 let Name = "MovKSymbolG1";
520 let RenderMethod = "addImmOperands";
523 def movk_symbol_g1 : Operand<i32> {
524 let ParserMatchClass = MovKSymbolG1AsmOperand;
527 def MovKSymbolG0AsmOperand : AsmOperandClass {
528 let Name = "MovKSymbolG0";
529 let RenderMethod = "addImmOperands";
532 def movk_symbol_g0 : Operand<i32> {
533 let ParserMatchClass = MovKSymbolG0AsmOperand;
536 class fixedpoint_i32<ValueType FloatVT>
538 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
539 let EncoderMethod = "getFixedPointScaleOpValue";
540 let DecoderMethod = "DecodeFixedPointScaleImm32";
541 let ParserMatchClass = Imm1_32Operand;
544 class fixedpoint_i64<ValueType FloatVT>
546 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
547 let EncoderMethod = "getFixedPointScaleOpValue";
548 let DecoderMethod = "DecodeFixedPointScaleImm64";
549 let ParserMatchClass = Imm1_64Operand;
552 def fixedpoint_f16_i32 : fixedpoint_i32<f16>;
553 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
554 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
556 def fixedpoint_f16_i64 : fixedpoint_i64<f16>;
557 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
558 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
560 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
561 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
563 let EncoderMethod = "getVecShiftR8OpValue";
564 let DecoderMethod = "DecodeVecShiftR8Imm";
565 let ParserMatchClass = Imm1_8Operand;
567 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
568 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
570 let EncoderMethod = "getVecShiftR16OpValue";
571 let DecoderMethod = "DecodeVecShiftR16Imm";
572 let ParserMatchClass = Imm1_16Operand;
574 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
575 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
577 let EncoderMethod = "getVecShiftR16OpValue";
578 let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
579 let ParserMatchClass = Imm1_8Operand;
581 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
582 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
584 let EncoderMethod = "getVecShiftR32OpValue";
585 let DecoderMethod = "DecodeVecShiftR32Imm";
586 let ParserMatchClass = Imm1_32Operand;
588 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
589 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
591 let EncoderMethod = "getVecShiftR32OpValue";
592 let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
593 let ParserMatchClass = Imm1_16Operand;
595 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
596 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
598 let EncoderMethod = "getVecShiftR64OpValue";
599 let DecoderMethod = "DecodeVecShiftR64Imm";
600 let ParserMatchClass = Imm1_64Operand;
602 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
603 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
605 let EncoderMethod = "getVecShiftR64OpValue";
606 let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
607 let ParserMatchClass = Imm1_32Operand;
610 def Imm0_1Operand : AsmImmRange<0, 1>;
611 def Imm0_7Operand : AsmImmRange<0, 7>;
612 def Imm0_15Operand : AsmImmRange<0, 15>;
613 def Imm0_31Operand : AsmImmRange<0, 31>;
614 def Imm0_63Operand : AsmImmRange<0, 63>;
616 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
617 return (((uint32_t)Imm) < 8);
619 let EncoderMethod = "getVecShiftL8OpValue";
620 let DecoderMethod = "DecodeVecShiftL8Imm";
621 let ParserMatchClass = Imm0_7Operand;
623 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
624 return (((uint32_t)Imm) < 16);
626 let EncoderMethod = "getVecShiftL16OpValue";
627 let DecoderMethod = "DecodeVecShiftL16Imm";
628 let ParserMatchClass = Imm0_15Operand;
630 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
631 return (((uint32_t)Imm) < 32);
633 let EncoderMethod = "getVecShiftL32OpValue";
634 let DecoderMethod = "DecodeVecShiftL32Imm";
635 let ParserMatchClass = Imm0_31Operand;
637 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
638 return (((uint32_t)Imm) < 64);
640 let EncoderMethod = "getVecShiftL64OpValue";
641 let DecoderMethod = "DecodeVecShiftL64Imm";
642 let ParserMatchClass = Imm0_63Operand;
646 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
647 // instructions for splatting repeating bit patterns across the immediate.
648 def logical_imm32_XFORM : SDNodeXForm<imm, [{
649 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
650 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
652 def logical_imm64_XFORM : SDNodeXForm<imm, [{
653 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
654 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
657 let DiagnosticType = "LogicalSecondSource" in {
658 def LogicalImm32Operand : AsmOperandClass {
659 let Name = "LogicalImm32";
660 let PredicateMethod = "isLogicalImm<int32_t>";
661 let RenderMethod = "addLogicalImmOperands<int32_t>";
663 def LogicalImm64Operand : AsmOperandClass {
664 let Name = "LogicalImm64";
665 let PredicateMethod = "isLogicalImm<int64_t>";
666 let RenderMethod = "addLogicalImmOperands<int64_t>";
668 def LogicalImm32NotOperand : AsmOperandClass {
669 let Name = "LogicalImm32Not";
670 let PredicateMethod = "isLogicalImm<int32_t>";
671 let RenderMethod = "addLogicalImmNotOperands<int32_t>";
673 def LogicalImm64NotOperand : AsmOperandClass {
674 let Name = "LogicalImm64Not";
675 let PredicateMethod = "isLogicalImm<int64_t>";
676 let RenderMethod = "addLogicalImmNotOperands<int64_t>";
679 def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{
680 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32);
681 }], logical_imm32_XFORM> {
682 let PrintMethod = "printLogicalImm<int32_t>";
683 let ParserMatchClass = LogicalImm32Operand;
685 def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{
686 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64);
687 }], logical_imm64_XFORM> {
688 let PrintMethod = "printLogicalImm<int64_t>";
689 let ParserMatchClass = LogicalImm64Operand;
691 def logical_imm32_not : Operand<i32> {
692 let ParserMatchClass = LogicalImm32NotOperand;
694 def logical_imm64_not : Operand<i64> {
695 let ParserMatchClass = LogicalImm64NotOperand;
698 // imm0_65535 predicate - True if the immediate is in the range [0,65535].
699 def Imm0_65535Operand : AsmImmRange<0, 65535>;
700 def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
701 return ((uint32_t)Imm) < 65536;
703 let ParserMatchClass = Imm0_65535Operand;
704 let PrintMethod = "printImmHex";
707 // imm0_255 predicate - True if the immediate is in the range [0,255].
708 def Imm0_255Operand : AsmImmRange<0,255>;
710 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
711 return ((uint32_t)Imm) < 256;
713 let ParserMatchClass = Imm0_255Operand;
714 let PrintMethod = "printImm";
717 // imm0_127 predicate - True if the immediate is in the range [0,127]
718 def Imm0_127Operand : AsmImmRange<0, 127>;
719 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
720 return ((uint32_t)Imm) < 128;
722 let ParserMatchClass = Imm0_127Operand;
723 let PrintMethod = "printImm";
726 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
727 // for all shift-amounts.
729 // imm0_63 predicate - True if the immediate is in the range [0,63]
730 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
731 return ((uint64_t)Imm) < 64;
733 let ParserMatchClass = Imm0_63Operand;
736 // imm0_31 predicate - True if the immediate is in the range [0,31]
737 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
738 return ((uint64_t)Imm) < 32;
740 let ParserMatchClass = Imm0_31Operand;
743 // True if the 32-bit immediate is in the range [0,31]
744 def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
745 return ((uint64_t)Imm) < 32;
747 let ParserMatchClass = Imm0_31Operand;
750 // imm0_1 predicate - True if the immediate is in the range [0,1]
751 def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
752 return ((uint64_t)Imm) < 2;
754 let ParserMatchClass = Imm0_1Operand;
757 // imm0_15 predicate - True if the immediate is in the range [0,15]
758 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
759 return ((uint64_t)Imm) < 16;
761 let ParserMatchClass = Imm0_15Operand;
764 // imm0_7 predicate - True if the immediate is in the range [0,7]
765 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
766 return ((uint64_t)Imm) < 8;
768 let ParserMatchClass = Imm0_7Operand;
771 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
772 def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
773 return ((uint32_t)Imm) < 16;
775 let ParserMatchClass = Imm0_15Operand;
778 // An arithmetic shifter operand:
779 // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
781 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
782 let PrintMethod = "printShifter";
783 let ParserMatchClass = !cast<AsmOperandClass>(
784 "ArithmeticShifterOperand" # width);
787 def arith_shift32 : arith_shift<i32, 32>;
788 def arith_shift64 : arith_shift<i64, 64>;
790 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
792 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
793 let PrintMethod = "printShiftedRegister";
794 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
797 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
798 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
800 // An arithmetic shifter operand:
801 // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
803 class logical_shift<int width> : Operand<i32> {
804 let PrintMethod = "printShifter";
805 let ParserMatchClass = !cast<AsmOperandClass>(
806 "LogicalShifterOperand" # width);
809 def logical_shift32 : logical_shift<32>;
810 def logical_shift64 : logical_shift<64>;
812 class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
814 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
815 let PrintMethod = "printShiftedRegister";
816 let MIOperandInfo = (ops regclass, shiftop);
819 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
820 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
822 // A logical vector shifter operand:
823 // {7-6} - shift type: 00 = lsl
824 // {5-0} - imm6: #0, #8, #16, or #24
825 def logical_vec_shift : Operand<i32> {
826 let PrintMethod = "printShifter";
827 let EncoderMethod = "getVecShifterOpValue";
828 let ParserMatchClass = LogicalVecShifterOperand;
831 // A logical vector half-word shifter operand:
832 // {7-6} - shift type: 00 = lsl
833 // {5-0} - imm6: #0 or #8
834 def logical_vec_hw_shift : Operand<i32> {
835 let PrintMethod = "printShifter";
836 let EncoderMethod = "getVecShifterOpValue";
837 let ParserMatchClass = LogicalVecHalfWordShifterOperand;
840 // A vector move shifter operand:
841 // {0} - imm1: #8 or #16
842 def move_vec_shift : Operand<i32> {
843 let PrintMethod = "printShifter";
844 let EncoderMethod = "getMoveVecShifterOpValue";
845 let ParserMatchClass = MoveVecShifterOperand;
848 let DiagnosticType = "AddSubSecondSource" in {
849 def AddSubImmOperand : AsmOperandClass {
850 let Name = "AddSubImm";
851 let ParserMethod = "tryParseImmWithOptionalShift";
852 let RenderMethod = "addImmWithOptionalShiftOperands<12>";
854 def AddSubImmNegOperand : AsmOperandClass {
855 let Name = "AddSubImmNeg";
856 let ParserMethod = "tryParseImmWithOptionalShift";
857 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>";
860 // An ADD/SUB immediate shifter operand:
862 // {7-6} - shift type: 00 = lsl
863 // {5-0} - imm6: #0 or #12
864 class addsub_shifted_imm<ValueType Ty>
865 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
866 let PrintMethod = "printAddSubImm";
867 let EncoderMethod = "getAddSubImmOpValue";
868 let ParserMatchClass = AddSubImmOperand;
869 let MIOperandInfo = (ops i32imm, i32imm);
872 class addsub_shifted_imm_neg<ValueType Ty>
874 let EncoderMethod = "getAddSubImmOpValue";
875 let ParserMatchClass = AddSubImmNegOperand;
876 let MIOperandInfo = (ops i32imm, i32imm);
879 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
880 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
881 def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
882 def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
884 def gi_addsub_shifted_imm32 :
885 GIComplexOperandMatcher<s32, "selectArithImmed">,
886 GIComplexPatternEquiv<addsub_shifted_imm32>;
888 def gi_addsub_shifted_imm64 :
889 GIComplexOperandMatcher<s64, "selectArithImmed">,
890 GIComplexPatternEquiv<addsub_shifted_imm64>;
892 class neg_addsub_shifted_imm<ValueType Ty>
893 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
894 let PrintMethod = "printAddSubImm";
895 let EncoderMethod = "getAddSubImmOpValue";
896 let ParserMatchClass = AddSubImmOperand;
897 let MIOperandInfo = (ops i32imm, i32imm);
900 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
901 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
903 // An extend operand:
904 // {5-3} - extend type
906 def arith_extend : Operand<i32> {
907 let PrintMethod = "printArithExtend";
908 let ParserMatchClass = ExtendOperand;
910 def arith_extend64 : Operand<i32> {
911 let PrintMethod = "printArithExtend";
912 let ParserMatchClass = ExtendOperand64;
915 // 'extend' that's a lsl of a 64-bit register.
916 def arith_extendlsl64 : Operand<i32> {
917 let PrintMethod = "printArithExtend";
918 let ParserMatchClass = ExtendOperandLSL64;
921 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
922 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
923 let PrintMethod = "printExtendedRegister";
924 let MIOperandInfo = (ops GPR32, arith_extend);
927 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
928 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
929 let PrintMethod = "printExtendedRegister";
930 let MIOperandInfo = (ops GPR32, arith_extend64);
933 // Floating-point immediate.
934 def fpimm16 : Operand<f16>,
936 return AArch64_AM::getFP16Imm(Imm) != -1;
937 }], SDNodeXForm<fpimm, [{
938 APFloat InVal = N->getValueAPF();
939 uint32_t enc = AArch64_AM::getFP16Imm(InVal);
940 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
942 let ParserMatchClass = FPImmOperand;
943 let PrintMethod = "printFPImmOperand";
945 def fpimm32 : Operand<f32>,
947 return AArch64_AM::getFP32Imm(Imm) != -1;
948 }], SDNodeXForm<fpimm, [{
949 APFloat InVal = N->getValueAPF();
950 uint32_t enc = AArch64_AM::getFP32Imm(InVal);
951 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
953 let ParserMatchClass = FPImmOperand;
954 let PrintMethod = "printFPImmOperand";
956 def fpimm64 : Operand<f64>,
958 return AArch64_AM::getFP64Imm(Imm) != -1;
959 }], SDNodeXForm<fpimm, [{
960 APFloat InVal = N->getValueAPF();
961 uint32_t enc = AArch64_AM::getFP64Imm(InVal);
962 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
964 let ParserMatchClass = FPImmOperand;
965 let PrintMethod = "printFPImmOperand";
968 def fpimm8 : Operand<i32> {
969 let ParserMatchClass = FPImmOperand;
970 let PrintMethod = "printFPImmOperand";
973 def fpimm0 : FPImmLeaf<fAny, [{
974 return Imm.isExactlyValue(+0.0);
977 // Vector lane operands
978 class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass {
979 let Name = NamePrefix # "IndexRange" # Min # "_" # Max;
980 let DiagnosticType = "Invalid" # Name;
981 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">";
982 let RenderMethod = "addVectorIndexOperands";
985 class AsmVectorIndexOpnd<AsmOperandClass mc, code pred>
986 : Operand<i64>, ImmLeaf<i64, pred> {
987 let ParserMatchClass = mc;
988 let PrintMethod = "printVectorIndex";
991 def VectorIndex1Operand : AsmVectorIndex<1, 1>;
992 def VectorIndexBOperand : AsmVectorIndex<0, 15>;
993 def VectorIndexHOperand : AsmVectorIndex<0, 7>;
994 def VectorIndexSOperand : AsmVectorIndex<0, 3>;
995 def VectorIndexDOperand : AsmVectorIndex<0, 1>;
997 def VectorIndex1 : AsmVectorIndexOpnd<VectorIndex1Operand, [{ return ((uint64_t)Imm) == 1; }]>;
998 def VectorIndexB : AsmVectorIndexOpnd<VectorIndexBOperand, [{ return ((uint64_t)Imm) < 16; }]>;
999 def VectorIndexH : AsmVectorIndexOpnd<VectorIndexHOperand, [{ return ((uint64_t)Imm) < 8; }]>;
1000 def VectorIndexS : AsmVectorIndexOpnd<VectorIndexSOperand, [{ return ((uint64_t)Imm) < 4; }]>;
1001 def VectorIndexD : AsmVectorIndexOpnd<VectorIndexDOperand, [{ return ((uint64_t)Imm) < 2; }]>;
1003 def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">;
1004 def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">;
1005 def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">;
1006 def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">;
1007 def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">;
1009 def sve_elm_idx_extdup_b
1010 : AsmVectorIndexOpnd<SVEVectorIndexExtDupBOperand, [{ return ((uint64_t)Imm) < 64; }]>;
1011 def sve_elm_idx_extdup_h
1012 : AsmVectorIndexOpnd<SVEVectorIndexExtDupHOperand, [{ return ((uint64_t)Imm) < 32; }]>;
1013 def sve_elm_idx_extdup_s
1014 : AsmVectorIndexOpnd<SVEVectorIndexExtDupSOperand, [{ return ((uint64_t)Imm) < 16; }]>;
1015 def sve_elm_idx_extdup_d
1016 : AsmVectorIndexOpnd<SVEVectorIndexExtDupDOperand, [{ return ((uint64_t)Imm) < 8; }]>;
1017 def sve_elm_idx_extdup_q
1018 : AsmVectorIndexOpnd<SVEVectorIndexExtDupQOperand, [{ return ((uint64_t)Imm) < 4; }]>;
1020 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
1021 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
1022 // are encoded as the eight bit value 'abcdefgh'.
1023 def simdimmtype10 : Operand<i32>,
1025 return AArch64_AM::isAdvSIMDModImmType10(
1026 Imm.bitcastToAPInt().getZExtValue());
1027 }], SDNodeXForm<fpimm, [{
1028 APFloat InVal = N->getValueAPF();
1029 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
1032 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
1034 let ParserMatchClass = SIMDImmType10Operand;
1035 let PrintMethod = "printSIMDType10Operand";
1040 // System management
1043 // Base encoding for system instruction operands.
1044 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
1045 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
1046 list<dag> pattern = []>
1047 : I<oops, iops, asm, operands, "", pattern> {
1048 let Inst{31-22} = 0b1101010100;
1052 // System instructions which do not have an Rt register.
1053 class SimpleSystemI<bit L, dag iops, string asm, string operands,
1054 list<dag> pattern = []>
1055 : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
1056 let Inst{4-0} = 0b11111;
1059 // System instructions which have an Rt register.
1060 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
1061 : BaseSystemI<L, oops, iops, asm, operands>,
1067 // Hint instructions that take both a CRm and a 3-bit immediate.
1068 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
1069 // model patterns with sufficiently fine granularity
1070 let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
1071 class HintI<string mnemonic>
1072 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
1073 [(int_aarch64_hint imm0_127:$imm)]>,
1074 Sched<[WriteHint]> {
1076 let Inst{20-12} = 0b000110010;
1077 let Inst{11-5} = imm;
1080 // System instructions taking a single literal operand which encodes into
1081 // CRm. op2 differentiates the opcodes.
1082 def BarrierAsmOperand : AsmOperandClass {
1083 let Name = "Barrier";
1084 let ParserMethod = "tryParseBarrierOperand";
1086 def barrier_op : Operand<i32> {
1087 let PrintMethod = "printBarrierOption";
1088 let ParserMatchClass = BarrierAsmOperand;
1090 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
1091 list<dag> pattern = []>
1092 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
1093 Sched<[WriteBarrier]> {
1095 let Inst{20-12} = 0b000110011;
1096 let Inst{11-8} = CRm;
1097 let Inst{7-5} = opc;
1100 class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []>
1101 : SimpleSystemI<0, (ins), asm, "", pattern>,
1105 let Inst{31-12} = 0b11010101000000110010;
1106 let Inst{11-8} = CRm;
1107 let Inst{7-5} = op2;
1108 let Inst{4-0} = 0b11111;
1111 // MRS/MSR system instructions. These have different operand classes because
1112 // a different subset of registers can be accessed through each instruction.
1113 def MRSSystemRegisterOperand : AsmOperandClass {
1114 let Name = "MRSSystemRegister";
1115 let ParserMethod = "tryParseSysReg";
1116 let DiagnosticType = "MRS";
1118 // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
1119 def mrs_sysreg_op : Operand<i32> {
1120 let ParserMatchClass = MRSSystemRegisterOperand;
1121 let DecoderMethod = "DecodeMRSSystemRegister";
1122 let PrintMethod = "printMRSSystemRegister";
1125 def MSRSystemRegisterOperand : AsmOperandClass {
1126 let Name = "MSRSystemRegister";
1127 let ParserMethod = "tryParseSysReg";
1128 let DiagnosticType = "MSR";
1130 def msr_sysreg_op : Operand<i32> {
1131 let ParserMatchClass = MSRSystemRegisterOperand;
1132 let DecoderMethod = "DecodeMSRSystemRegister";
1133 let PrintMethod = "printMSRSystemRegister";
1136 def PSBHintOperand : AsmOperandClass {
1137 let Name = "PSBHint";
1138 let ParserMethod = "tryParsePSBHint";
1140 def psbhint_op : Operand<i32> {
1141 let ParserMatchClass = PSBHintOperand;
1142 let PrintMethod = "printPSBHintOp";
1143 let MCOperandPredicate = [{
1144 // Check, if operand is valid, to fix exhaustive aliasing in disassembly.
1145 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.
1148 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
1152 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
1153 "mrs", "\t$Rt, $systemreg"> {
1155 let Inst{20-5} = systemreg;
1158 // FIXME: Some of these def NZCV, others don't. Best way to model that?
1159 // Explicitly modeling each of the system register as a register class
1160 // would do it, but feels like overkill at this point.
1161 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
1162 "msr", "\t$systemreg, $Rt"> {
1164 let Inst{20-5} = systemreg;
1167 def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
1168 let Name = "SystemPStateFieldWithImm0_15";
1169 let ParserMethod = "tryParseSysReg";
1171 def pstatefield4_op : Operand<i32> {
1172 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
1173 let PrintMethod = "printSystemPStateField";
1176 let Defs = [NZCV] in
1177 class MSRpstateImm0_15
1178 : SimpleSystemI<0, (ins pstatefield4_op:$pstatefield, imm0_15:$imm),
1179 "msr", "\t$pstatefield, $imm">,
1181 bits<6> pstatefield;
1183 let Inst{20-19} = 0b00;
1184 let Inst{18-16} = pstatefield{5-3};
1185 let Inst{15-12} = 0b0100;
1186 let Inst{11-8} = imm;
1187 let Inst{7-5} = pstatefield{2-0};
1189 let DecoderMethod = "DecodeSystemPStateInstruction";
1190 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1191 // Fail the decoder should attempt to decode the instruction as MSRI.
1192 let hasCompleteDecoder = 0;
1195 def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
1196 let Name = "SystemPStateFieldWithImm0_1";
1197 let ParserMethod = "tryParseSysReg";
1199 def pstatefield1_op : Operand<i32> {
1200 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
1201 let PrintMethod = "printSystemPStateField";
1204 let Defs = [NZCV] in
1205 class MSRpstateImm0_1
1206 : SimpleSystemI<0, (ins pstatefield1_op:$pstatefield, imm0_1:$imm),
1207 "msr", "\t$pstatefield, $imm">,
1209 bits<6> pstatefield;
1211 let Inst{20-19} = 0b00;
1212 let Inst{18-16} = pstatefield{5-3};
1213 let Inst{15-9} = 0b0100000;
1215 let Inst{7-5} = pstatefield{2-0};
1217 let DecoderMethod = "DecodeSystemPStateInstruction";
1218 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1219 // Fail the decoder should attempt to decode the instruction as MSRI.
1220 let hasCompleteDecoder = 0;
1223 // SYS and SYSL generic system instructions.
1224 def SysCRAsmOperand : AsmOperandClass {
1226 let ParserMethod = "tryParseSysCROperand";
1229 def sys_cr_op : Operand<i32> {
1230 let PrintMethod = "printSysCROperand";
1231 let ParserMatchClass = SysCRAsmOperand;
1234 class SystemXtI<bit L, string asm>
1235 : RtSystemI<L, (outs),
1236 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
1237 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
1242 let Inst{20-19} = 0b01;
1243 let Inst{18-16} = op1;
1244 let Inst{15-12} = Cn;
1245 let Inst{11-8} = Cm;
1246 let Inst{7-5} = op2;
1249 class SystemLXtI<bit L, string asm>
1250 : RtSystemI<L, (outs),
1251 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
1252 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
1257 let Inst{20-19} = 0b01;
1258 let Inst{18-16} = op1;
1259 let Inst{15-12} = Cn;
1260 let Inst{11-8} = Cm;
1261 let Inst{7-5} = op2;
1265 // Branch (register) instructions:
1273 // otherwise UNDEFINED
1274 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
1275 string operands, list<dag> pattern>
1276 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
1277 let Inst{31-25} = 0b1101011;
1278 let Inst{24-21} = opc;
1279 let Inst{20-16} = 0b11111;
1280 let Inst{15-10} = 0b000000;
1281 let Inst{4-0} = 0b00000;
1284 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
1285 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
1290 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
1291 class SpecialReturn<bits<4> opc, string asm>
1292 : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1293 let Inst{9-5} = 0b11111;
1297 class RCPCLoad<bits<2> sz, string asm, RegisterClass RC>
1298 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>,
1302 let Inst{31-30} = sz;
1303 let Inst{29-10} = 0b11100010111111110000;
1308 class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands,
1310 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> {
1311 let Inst{31-25} = 0b1101011;
1312 let Inst{20-11} = 0b1111100001;
1314 let Inst{4-0} = 0b11111;
1317 class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm>
1318 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> {
1321 let Inst{24-22} = 0b100;
1327 class AuthOneOperand<bits<3> opc, bits<1> M, string asm>
1328 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> {
1331 let Inst{23-21} = opc;
1335 class AuthReturn<bits<3> op, bits<1> M, string asm>
1336 : AuthBase<M, (outs), (ins), asm, "", []> {
1338 let Inst{23-21} = op;
1339 let Inst{9-0} = 0b1111111111;
1343 class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm,
1344 string operands, string cstr, Operand opr>
1345 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> {
1349 let Inst{31-24} = 0b11111000;
1351 let Inst{22} = offset{9};
1353 let Inst{20-12} = offset{8-0};
1360 multiclass AuthLoad<bit M, string asm, Operand opr> {
1361 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt),
1362 (ins GPR64sp:$Rn, opr:$offset),
1363 asm, "\t$Rt, [$Rn, $offset]", "", opr>;
1364 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt),
1365 (ins GPR64sp:$Rn, opr:$offset),
1366 asm, "\t$Rt, [$Rn, $offset]!",
1367 "$Rn = $wback,@earlyclobber $wback", opr>;
1369 def : InstAlias<asm # "\t$Rt, [$Rn]",
1370 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>;
1374 // Conditional branch instruction.
1378 // 4-bit immediate. Pretty-printed as <cc>
1379 def ccode : Operand<i32> {
1380 let PrintMethod = "printCondCode";
1381 let ParserMatchClass = CondCode;
1383 def inv_ccode : Operand<i32> {
1384 // AL and NV are invalid in the aliases which use inv_ccode
1385 let PrintMethod = "printInverseCondCode";
1386 let ParserMatchClass = CondCode;
1387 let MCOperandPredicate = [{
1388 return MCOp.isImm() &&
1389 MCOp.getImm() != AArch64CC::AL &&
1390 MCOp.getImm() != AArch64CC::NV;
1394 // Conditional branch target. 19-bit immediate. The low two bits of the target
1395 // offset are implied zero and so are not part of the immediate.
1396 def am_brcond : Operand<OtherVT> {
1397 let EncoderMethod = "getCondBranchTargetOpValue";
1398 let DecoderMethod = "DecodePCRelLabel19";
1399 let PrintMethod = "printAlignedLabel";
1400 let ParserMatchClass = PCRelLabel19Operand;
1401 let OperandType = "OPERAND_PCREL";
1404 class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1405 "b", ".$cond\t$target", "",
1406 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1409 let isTerminator = 1;
1414 let Inst{31-24} = 0b01010100;
1415 let Inst{23-5} = target;
1417 let Inst{3-0} = cond;
1421 // Compare-and-branch instructions.
1423 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1424 : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1425 asm, "\t$Rt, $target", "",
1426 [(node regtype:$Rt, bb:$target)]>,
1429 let isTerminator = 1;
1433 let Inst{30-25} = 0b011010;
1435 let Inst{23-5} = target;
1439 multiclass CmpBranch<bit op, string asm, SDNode node> {
1440 def W : BaseCmpBranch<GPR32, op, asm, node> {
1443 def X : BaseCmpBranch<GPR64, op, asm, node> {
1449 // Test-bit-and-branch instructions.
1451 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1452 // the target offset are implied zero and so are not part of the immediate.
1453 def am_tbrcond : Operand<OtherVT> {
1454 let EncoderMethod = "getTestBranchTargetOpValue";
1455 let PrintMethod = "printAlignedLabel";
1456 let ParserMatchClass = BranchTarget14Operand;
1457 let OperandType = "OPERAND_PCREL";
1460 // AsmOperand classes to emit (or not) special diagnostics
1461 def TBZImm0_31Operand : AsmOperandClass {
1462 let Name = "TBZImm0_31";
1463 let PredicateMethod = "isImmInRange<0,31>";
1464 let RenderMethod = "addImmOperands";
1466 def TBZImm32_63Operand : AsmOperandClass {
1467 let Name = "Imm32_63";
1468 let PredicateMethod = "isImmInRange<32,63>";
1469 let DiagnosticType = "InvalidImm0_63";
1470 let RenderMethod = "addImmOperands";
1473 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1474 return (((uint32_t)Imm) < 32);
1476 let ParserMatchClass = matcher;
1479 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1480 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1482 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1483 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1485 let ParserMatchClass = TBZImm32_63Operand;
1488 class BaseTestBranch<RegisterClass regtype, Operand immtype,
1489 bit op, string asm, SDNode node>
1490 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1491 asm, "\t$Rt, $bit_off, $target", "",
1492 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1495 let isTerminator = 1;
1501 let Inst{30-25} = 0b011011;
1503 let Inst{23-19} = bit_off{4-0};
1504 let Inst{18-5} = target;
1507 let DecoderMethod = "DecodeTestAndBranch";
1510 multiclass TestBranch<bit op, string asm, SDNode node> {
1511 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1515 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1519 // Alias X-reg with 0-31 imm to W-Reg.
1520 def : InstAlias<asm # "\t$Rd, $imm, $target",
1521 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1522 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1523 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1524 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1525 tbz_imm0_31_diag:$imm, bb:$target)>;
1529 // Unconditional branch (immediate) instructions.
1531 def am_b_target : Operand<OtherVT> {
1532 let EncoderMethod = "getBranchTargetOpValue";
1533 let PrintMethod = "printAlignedLabel";
1534 let ParserMatchClass = BranchTarget26Operand;
1535 let OperandType = "OPERAND_PCREL";
1537 def am_bl_target : Operand<i64> {
1538 let EncoderMethod = "getBranchTargetOpValue";
1539 let PrintMethod = "printAlignedLabel";
1540 let ParserMatchClass = BranchTarget26Operand;
1541 let OperandType = "OPERAND_PCREL";
1544 class BImm<bit op, dag iops, string asm, list<dag> pattern>
1545 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1548 let Inst{30-26} = 0b00101;
1549 let Inst{25-0} = addr;
1551 let DecoderMethod = "DecodeUnconditionalBranch";
1554 class BranchImm<bit op, string asm, list<dag> pattern>
1555 : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1556 class CallImm<bit op, string asm, list<dag> pattern>
1557 : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1560 // Basic one-operand data processing instructions.
1563 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1564 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1565 SDPatternOperator node>
1566 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1567 [(set regtype:$Rd, (node regtype:$Rn))]>,
1568 Sched<[WriteI, ReadI]> {
1572 let Inst{30-13} = 0b101101011000000000;
1573 let Inst{12-10} = opc;
1578 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1579 multiclass OneOperandData<bits<3> opc, string asm,
1580 SDPatternOperator node = null_frag> {
1581 def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1585 def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1590 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1591 : BaseOneOperandData<opc, GPR32, asm, node> {
1595 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1596 : BaseOneOperandData<opc, GPR64, asm, node> {
1600 class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm>
1601 : I<(outs GPR64:$Rd), (ins GPR64sp:$Rn), asm, "\t$Rd, $Rn", "",
1603 Sched<[WriteI, ReadI]> {
1606 let Inst{31-15} = 0b11011010110000010;
1607 let Inst{14-12} = opcode_prefix;
1608 let Inst{11-10} = opcode;
1613 class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm>
1614 : I<(outs GPR64:$Rd), (ins), asm, "\t$Rd", "", []>, Sched<[]> {
1616 let Inst{31-15} = 0b11011010110000010;
1617 let Inst{14-12} = opcode_prefix;
1618 let Inst{11-10} = opcode;
1619 let Inst{9-5} = 0b11111;
1623 class SignAuthTwoOperand<bits<4> opc, string asm,
1624 SDPatternOperator OpNode>
1625 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm),
1626 asm, "\t$Rd, $Rn, $Rm", "",
1627 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>,
1628 Sched<[WriteI, ReadI, ReadI]> {
1632 let Inst{31-21} = 0b10011010110;
1633 let Inst{20-16} = Rm;
1634 let Inst{15-14} = 0b00;
1635 let Inst{13-10} = opc;
1640 // Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions
1641 class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops>
1642 : I<(outs), iops, asm, ops, "", []>,
1643 Sched<[WriteI, ReadI, ReadI]> {
1647 let Inst{30-15} = 0b0111010000000000;
1649 let Inst{13-10} = 0b0010;
1651 let Inst{4-0} = 0b01101;
1654 class FlagRotate<dag iops, string asm, string ops>
1655 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> {
1658 let Inst{20-15} = imm;
1659 let Inst{13-10} = 0b0001;
1661 let Inst{3-0} = mask;
1665 // Basic two-operand data processing instructions.
1667 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1669 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1670 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1671 Sched<[WriteI, ReadI, ReadI]> {
1676 let Inst{30} = isSub;
1677 let Inst{28-21} = 0b11010000;
1678 let Inst{20-16} = Rm;
1679 let Inst{15-10} = 0;
1684 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1686 : BaseBaseAddSubCarry<isSub, regtype, asm,
1687 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1689 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1691 : BaseBaseAddSubCarry<isSub, regtype, asm,
1692 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1697 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1698 SDNode OpNode, SDNode OpNode_setflags> {
1699 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1703 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1709 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1714 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1721 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1722 SDPatternOperator OpNode>
1723 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1724 asm, "\t$Rd, $Rn, $Rm", "",
1725 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
1729 let Inst{30-21} = 0b0011010110;
1730 let Inst{20-16} = Rm;
1731 let Inst{15-14} = 0b00;
1732 let Inst{13-10} = opc;
1737 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1738 SDPatternOperator OpNode>
1739 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1740 let Inst{10} = isSigned;
1743 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1744 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1745 Sched<[WriteID32, ReadID, ReadID]> {
1748 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1749 Sched<[WriteID64, ReadID, ReadID]> {
1754 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1755 SDPatternOperator OpNode = null_frag>
1756 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1757 Sched<[WriteIS, ReadI]> {
1758 let Inst{11-10} = shift_type;
1761 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
1762 def Wr : BaseShift<shift_type, GPR32, asm> {
1766 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1770 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1771 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1772 (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1774 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1775 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1777 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1778 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1780 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1781 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1784 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
1785 : InstAlias<asm#"\t$dst, $src1, $src2",
1786 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
1788 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1789 RegisterClass addtype, string asm,
1791 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1792 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1797 let Inst{30-24} = 0b0011011;
1798 let Inst{23-21} = opc;
1799 let Inst{20-16} = Rm;
1800 let Inst{15} = isSub;
1801 let Inst{14-10} = Ra;
1806 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
1807 // MADD/MSUB generation is decided by MachineCombiner.cpp
1808 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
1809 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
1810 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1814 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
1815 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
1816 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
1821 class WideMulAccum<bit isSub, bits<3> opc, string asm,
1822 SDNode AccNode, SDNode ExtNode>
1823 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
1824 [(set GPR64:$Rd, (AccNode GPR64:$Ra,
1825 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
1826 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1830 class MulHi<bits<3> opc, string asm, SDNode OpNode>
1831 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
1832 asm, "\t$Rd, $Rn, $Rm", "",
1833 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
1834 Sched<[WriteIM64, ReadIM, ReadIM]> {
1838 let Inst{31-24} = 0b10011011;
1839 let Inst{23-21} = opc;
1840 let Inst{20-16} = Rm;
1845 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
1846 // (i.e. all bits 1) but is ignored by the processor.
1847 let PostEncoderMethod = "fixMulHigh";
1850 class MulAccumWAlias<string asm, Instruction inst>
1851 : InstAlias<asm#"\t$dst, $src1, $src2",
1852 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
1853 class MulAccumXAlias<string asm, Instruction inst>
1854 : InstAlias<asm#"\t$dst, $src1, $src2",
1855 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
1856 class WideMulAccumAlias<string asm, Instruction inst>
1857 : InstAlias<asm#"\t$dst, $src1, $src2",
1858 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
1860 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
1861 SDPatternOperator OpNode, string asm>
1862 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
1863 asm, "\t$Rd, $Rn, $Rm", "",
1864 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
1865 Sched<[WriteISReg, ReadI, ReadISReg]> {
1871 let Inst{30-21} = 0b0011010110;
1872 let Inst{20-16} = Rm;
1873 let Inst{15-13} = 0b010;
1875 let Inst{11-10} = sz;
1878 let Predicates = [HasCRC];
1882 // Address generation.
1885 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
1886 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
1891 let Inst{31} = page;
1892 let Inst{30-29} = label{1-0};
1893 let Inst{28-24} = 0b10000;
1894 let Inst{23-5} = label{20-2};
1897 let DecoderMethod = "DecodeAdrInstruction";
1904 def movimm32_imm : Operand<i32> {
1905 let ParserMatchClass = Imm0_65535Operand;
1906 let EncoderMethod = "getMoveWideImmOpValue";
1907 let PrintMethod = "printImm";
1909 def movimm32_shift : Operand<i32> {
1910 let PrintMethod = "printShifter";
1911 let ParserMatchClass = MovImm32ShifterOperand;
1913 def movimm64_shift : Operand<i32> {
1914 let PrintMethod = "printShifter";
1915 let ParserMatchClass = MovImm64ShifterOperand;
1918 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1919 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1921 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
1922 asm, "\t$Rd, $imm$shift", "", []>,
1927 let Inst{30-29} = opc;
1928 let Inst{28-23} = 0b100101;
1929 let Inst{22-21} = shift{5-4};
1930 let Inst{20-5} = imm;
1933 let DecoderMethod = "DecodeMoveImmInstruction";
1936 multiclass MoveImmediate<bits<2> opc, string asm> {
1937 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
1941 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
1946 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1947 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1949 : I<(outs regtype:$Rd),
1950 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
1951 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
1952 Sched<[WriteI, ReadI]> {
1956 let Inst{30-29} = opc;
1957 let Inst{28-23} = 0b100101;
1958 let Inst{22-21} = shift{5-4};
1959 let Inst{20-5} = imm;
1962 let DecoderMethod = "DecodeMoveImmInstruction";
1965 multiclass InsertImmediate<bits<2> opc, string asm> {
1966 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
1970 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
1979 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
1980 RegisterClass srcRegtype, addsub_shifted_imm immtype,
1981 string asm, SDPatternOperator OpNode>
1982 : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
1983 asm, "\t$Rd, $Rn, $imm", "",
1984 [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
1985 Sched<[WriteI, ReadI]> {
1989 let Inst{30} = isSub;
1990 let Inst{29} = setFlags;
1991 let Inst{28-24} = 0b10001;
1992 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
1993 let Inst{21-10} = imm{11-0};
1996 let DecoderMethod = "DecodeBaseAddSubImm";
1999 class BaseAddSubRegPseudo<RegisterClass regtype,
2000 SDPatternOperator OpNode>
2001 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2002 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2003 Sched<[WriteI, ReadI, ReadI]>;
2005 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
2006 arith_shifted_reg shifted_regtype, string asm,
2007 SDPatternOperator OpNode>
2008 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2009 asm, "\t$Rd, $Rn, $Rm", "",
2010 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
2011 Sched<[WriteISReg, ReadI, ReadISReg]> {
2012 // The operands are in order to match the 'addr' MI operands, so we
2013 // don't need an encoder method and by-name matching. Just use the default
2014 // in-order handling. Since we're using by-order, make sure the names
2020 let Inst{30} = isSub;
2021 let Inst{29} = setFlags;
2022 let Inst{28-24} = 0b01011;
2023 let Inst{23-22} = shift{7-6};
2025 let Inst{20-16} = src2;
2026 let Inst{15-10} = shift{5-0};
2027 let Inst{9-5} = src1;
2028 let Inst{4-0} = dst;
2030 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2033 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
2034 RegisterClass src1Regtype, Operand src2Regtype,
2035 string asm, SDPatternOperator OpNode>
2036 : I<(outs dstRegtype:$R1),
2037 (ins src1Regtype:$R2, src2Regtype:$R3),
2038 asm, "\t$R1, $R2, $R3", "",
2039 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
2040 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
2045 let Inst{30} = isSub;
2046 let Inst{29} = setFlags;
2047 let Inst{28-24} = 0b01011;
2048 let Inst{23-21} = 0b001;
2049 let Inst{20-16} = Rm;
2050 let Inst{15-13} = ext{5-3};
2051 let Inst{12-10} = ext{2-0};
2055 let DecoderMethod = "DecodeAddSubERegInstruction";
2058 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2059 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
2060 RegisterClass src1Regtype, RegisterClass src2Regtype,
2061 Operand ext_op, string asm>
2062 : I<(outs dstRegtype:$Rd),
2063 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
2064 asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
2065 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
2070 let Inst{30} = isSub;
2071 let Inst{29} = setFlags;
2072 let Inst{28-24} = 0b01011;
2073 let Inst{23-21} = 0b001;
2074 let Inst{20-16} = Rm;
2075 let Inst{15} = ext{5};
2076 let Inst{12-10} = ext{2-0};
2080 let DecoderMethod = "DecodeAddSubERegInstruction";
2083 // Aliases for register+register add/subtract.
2084 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
2085 RegisterClass src1Regtype, RegisterClass src2Regtype,
2087 : InstAlias<asm#"\t$dst, $src1, $src2",
2088 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
2091 multiclass AddSub<bit isSub, string mnemonic, string alias,
2092 SDPatternOperator OpNode = null_frag> {
2093 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2094 // Add/Subtract immediate
2095 // Increase the weight of the immediate variant to try to match it before
2096 // the extended register variant.
2097 // We used to match the register variant before the immediate when the
2098 // register argument could be implicitly zero-extended.
2099 let AddedComplexity = 6 in
2100 def Wri : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
2104 let AddedComplexity = 6 in
2105 def Xri : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
2110 // Add/Subtract register - Only used for CodeGen
2111 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
2112 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
2114 // Add/Subtract shifted register
2115 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
2119 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
2125 // Add/Subtract extended register
2126 let AddedComplexity = 1, hasSideEffects = 0 in {
2127 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
2128 arith_extended_reg32<i32>, mnemonic, OpNode> {
2131 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
2132 arith_extended_reg32to64<i64>, mnemonic, OpNode> {
2137 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
2138 arith_extendlsl64, mnemonic> {
2139 // UXTX and SXTX only.
2140 let Inst{14-13} = 0b11;
2144 // add Rd, Rb, -imm -> sub Rd, Rn, imm
2145 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2146 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
2147 addsub_shifted_imm32_neg:$imm), 0>;
2148 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2149 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
2150 addsub_shifted_imm64_neg:$imm), 0>;
2152 // Register/register aliases with no shift when SP is not used.
2153 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
2154 GPR32, GPR32, GPR32, 0>;
2155 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
2156 GPR64, GPR64, GPR64, 0>;
2158 // Register/register aliases with no shift when either the destination or
2159 // first source register is SP.
2160 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2161 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
2162 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2163 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
2164 def : AddSubRegAlias<mnemonic,
2165 !cast<Instruction>(NAME#"Xrx64"),
2166 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
2167 def : AddSubRegAlias<mnemonic,
2168 !cast<Instruction>(NAME#"Xrx64"),
2169 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
2172 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
2173 string alias, string cmpAlias> {
2174 let isCompare = 1, Defs = [NZCV] in {
2175 // Add/Subtract immediate
2176 def Wri : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
2180 def Xri : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
2185 // Add/Subtract register
2186 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
2187 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
2189 // Add/Subtract shifted register
2190 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
2194 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
2199 // Add/Subtract extended register
2200 let AddedComplexity = 1 in {
2201 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
2202 arith_extended_reg32<i32>, mnemonic, OpNode> {
2205 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
2206 arith_extended_reg32<i64>, mnemonic, OpNode> {
2211 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
2212 arith_extendlsl64, mnemonic> {
2213 // UXTX and SXTX only.
2214 let Inst{14-13} = 0b11;
2219 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
2220 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2221 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
2222 addsub_shifted_imm32_neg:$imm), 0>;
2223 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2224 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
2225 addsub_shifted_imm64_neg:$imm), 0>;
2228 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
2229 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
2230 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
2231 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
2232 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
2233 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
2234 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
2235 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
2236 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
2237 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
2238 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
2239 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
2240 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
2241 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
2243 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
2244 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
2245 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
2246 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
2247 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
2249 // Compare shorthands
2250 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
2251 WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
2252 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
2253 XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
2254 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
2255 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
2256 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
2257 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
2259 // Register/register aliases with no shift when SP is not used.
2260 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
2261 GPR32, GPR32, GPR32, 0>;
2262 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
2263 GPR64, GPR64, GPR64, 0>;
2265 // Register/register aliases with no shift when the first source register
2267 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2268 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
2269 def : AddSubRegAlias<mnemonic,
2270 !cast<Instruction>(NAME#"Xrx64"),
2271 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
2277 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
2279 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
2281 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
2283 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
2284 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
2285 Sched<[WriteExtr, ReadExtrHi]> {
2291 let Inst{30-23} = 0b00100111;
2293 let Inst{20-16} = Rm;
2294 let Inst{15-10} = imm;
2299 multiclass ExtractImm<string asm> {
2300 def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
2302 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
2305 // imm<5> must be zero.
2308 def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
2310 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
2321 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2322 class BaseBitfieldImm<bits<2> opc,
2323 RegisterClass regtype, Operand imm_type, string asm>
2324 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
2325 asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
2326 Sched<[WriteIS, ReadI]> {
2332 let Inst{30-29} = opc;
2333 let Inst{28-23} = 0b100110;
2334 let Inst{21-16} = immr;
2335 let Inst{15-10} = imms;
2340 multiclass BitfieldImm<bits<2> opc, string asm> {
2341 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
2344 // imms<5> and immr<5> must be zero, else ReservedValue().
2348 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
2354 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2355 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
2356 RegisterClass regtype, Operand imm_type, string asm>
2357 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
2359 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
2360 Sched<[WriteIS, ReadI]> {
2366 let Inst{30-29} = opc;
2367 let Inst{28-23} = 0b100110;
2368 let Inst{21-16} = immr;
2369 let Inst{15-10} = imms;
2374 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
2375 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
2378 // imms<5> and immr<5> must be zero, else ReservedValue().
2382 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
2392 // Logical (immediate)
2393 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
2394 RegisterClass sregtype, Operand imm_type, string asm,
2396 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
2397 asm, "\t$Rd, $Rn, $imm", "", pattern>,
2398 Sched<[WriteI, ReadI]> {
2402 let Inst{30-29} = opc;
2403 let Inst{28-23} = 0b100100;
2404 let Inst{22} = imm{12};
2405 let Inst{21-16} = imm{11-6};
2406 let Inst{15-10} = imm{5-0};
2410 let DecoderMethod = "DecodeLogicalImmInstruction";
2413 // Logical (shifted register)
2414 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
2415 logical_shifted_reg shifted_regtype, string asm,
2417 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2418 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2419 Sched<[WriteISReg, ReadI, ReadISReg]> {
2420 // The operands are in order to match the 'addr' MI operands, so we
2421 // don't need an encoder method and by-name matching. Just use the default
2422 // in-order handling. Since we're using by-order, make sure the names
2428 let Inst{30-29} = opc;
2429 let Inst{28-24} = 0b01010;
2430 let Inst{23-22} = shift{7-6};
2432 let Inst{20-16} = src2;
2433 let Inst{15-10} = shift{5-0};
2434 let Inst{9-5} = src1;
2435 let Inst{4-0} = dst;
2437 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2440 // Aliases for register+register logical instructions.
2441 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
2442 : InstAlias<asm#"\t$dst, $src1, $src2",
2443 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2445 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2447 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2448 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2449 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2450 logical_imm32:$imm))]> {
2452 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2454 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2455 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2456 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2457 logical_imm64:$imm))]> {
2461 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2462 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2463 logical_imm32_not:$imm), 0>;
2464 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2465 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2466 logical_imm64_not:$imm), 0>;
2469 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2471 let isCompare = 1, Defs = [NZCV] in {
2472 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2473 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2475 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2477 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2478 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2481 } // end Defs = [NZCV]
2483 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2484 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2485 logical_imm32_not:$imm), 0>;
2486 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2487 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2488 logical_imm64_not:$imm), 0>;
2491 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2492 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2493 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2494 Sched<[WriteI, ReadI, ReadI]>;
2496 // Split from LogicalImm as not all instructions have both.
2497 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2498 SDPatternOperator OpNode> {
2499 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2500 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2501 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2504 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2505 [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2506 logical_shifted_reg32:$Rm))]> {
2509 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2510 [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2511 logical_shifted_reg64:$Rm))]> {
2515 def : LogicalRegAlias<mnemonic,
2516 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2517 def : LogicalRegAlias<mnemonic,
2518 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2521 // Split from LogicalReg to allow setting NZCV Defs
2522 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2523 SDPatternOperator OpNode = null_frag> {
2524 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2525 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2526 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2528 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2529 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2532 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2533 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2538 def : LogicalRegAlias<mnemonic,
2539 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2540 def : LogicalRegAlias<mnemonic,
2541 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2545 // Conditionally set flags
2548 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2549 class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2550 string mnemonic, SDNode OpNode>
2551 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2552 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2553 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2554 (i32 imm:$cond), NZCV))]>,
2555 Sched<[WriteI, ReadI]> {
2565 let Inst{29-21} = 0b111010010;
2566 let Inst{20-16} = imm;
2567 let Inst{15-12} = cond;
2568 let Inst{11-10} = 0b10;
2571 let Inst{3-0} = nzcv;
2574 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2575 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2577 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2578 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2579 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2580 (i32 imm:$cond), NZCV))]>,
2581 Sched<[WriteI, ReadI, ReadI]> {
2591 let Inst{29-21} = 0b111010010;
2592 let Inst{20-16} = Rm;
2593 let Inst{15-12} = cond;
2594 let Inst{11-10} = 0b00;
2597 let Inst{3-0} = nzcv;
2600 multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
2601 // immediate operand variants
2602 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
2605 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
2608 // register operand variants
2609 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
2612 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
2618 // Conditional select
2621 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2622 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2623 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2625 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2626 Sched<[WriteI, ReadI, ReadI]> {
2635 let Inst{29-21} = 0b011010100;
2636 let Inst{20-16} = Rm;
2637 let Inst{15-12} = cond;
2638 let Inst{11-10} = op2;
2643 multiclass CondSelect<bit op, bits<2> op2, string asm> {
2644 def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2647 def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2652 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2654 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2655 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2657 (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2658 (i32 imm:$cond), NZCV))]>,
2659 Sched<[WriteI, ReadI, ReadI]> {
2668 let Inst{29-21} = 0b011010100;
2669 let Inst{20-16} = Rm;
2670 let Inst{15-12} = cond;
2671 let Inst{11-10} = op2;
2676 def inv_cond_XFORM : SDNodeXForm<imm, [{
2677 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
2678 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
2682 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
2683 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
2686 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
2690 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
2691 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
2692 (inv_cond_XFORM imm:$cond))>;
2694 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
2695 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
2696 (inv_cond_XFORM imm:$cond))>;
2700 // Special Mask Value
2702 def maski8_or_more : Operand<i32>,
2703 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
2705 def maski16_or_more : Operand<i32>,
2706 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
2714 // (unsigned immediate)
2715 // Indexed for 8-bit registers. offset is in range [0,4095].
2716 def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
2717 def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
2718 def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
2719 def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
2720 def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
2722 def gi_am_indexed8 :
2723 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">,
2724 GIComplexPatternEquiv<am_indexed8>;
2725 def gi_am_indexed16 :
2726 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">,
2727 GIComplexPatternEquiv<am_indexed16>;
2728 def gi_am_indexed32 :
2729 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">,
2730 GIComplexPatternEquiv<am_indexed32>;
2731 def gi_am_indexed64 :
2732 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">,
2733 GIComplexPatternEquiv<am_indexed64>;
2734 def gi_am_indexed128 :
2735 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">,
2736 GIComplexPatternEquiv<am_indexed128>;
2738 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
2739 let Name = "UImm12Offset" # Scale;
2740 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
2741 let PredicateMethod = "isUImm12Offset<" # Scale # ">";
2742 let DiagnosticType = "InvalidMemoryIndexed" # Scale;
2745 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
2746 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
2747 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
2748 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
2749 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
2751 class uimm12_scaled<int Scale> : Operand<i64> {
2752 let ParserMatchClass
2753 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
2755 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
2756 let PrintMethod = "printUImm12Offset<" # Scale # ">";
2759 def uimm12s1 : uimm12_scaled<1>;
2760 def uimm12s2 : uimm12_scaled<2>;
2761 def uimm12s4 : uimm12_scaled<4>;
2762 def uimm12s8 : uimm12_scaled<8>;
2763 def uimm12s16 : uimm12_scaled<16>;
2765 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2766 string asm, list<dag> pattern>
2767 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2773 let Inst{31-30} = sz;
2774 let Inst{29-27} = 0b111;
2776 let Inst{25-24} = 0b01;
2777 let Inst{23-22} = opc;
2778 let Inst{21-10} = offset;
2782 let DecoderMethod = "DecodeUnsignedLdStInstruction";
2785 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
2786 Operand indextype, string asm, list<dag> pattern> {
2787 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2788 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
2789 (ins GPR64sp:$Rn, indextype:$offset),
2793 def : InstAlias<asm # "\t$Rt, [$Rn]",
2794 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2797 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
2798 Operand indextype, string asm, list<dag> pattern> {
2799 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2800 def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2801 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2805 def : InstAlias<asm # "\t$Rt, [$Rn]",
2806 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2809 // Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to
2810 // substitute zero-registers automatically.
2812 // TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back
2814 multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
2815 Operand indextype, string asm, list<dag> pattern> {
2816 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2817 def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2818 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2822 def : InstAlias<asm # "\t$Rt, [$Rn]",
2823 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2826 def PrefetchOperand : AsmOperandClass {
2827 let Name = "Prefetch";
2828 let ParserMethod = "tryParsePrefetch";
2830 def prfop : Operand<i32> {
2831 let PrintMethod = "printPrefetchOp";
2832 let ParserMatchClass = PrefetchOperand;
2835 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2836 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2837 : BaseLoadStoreUI<sz, V, opc,
2838 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
2846 // Load literal address: 19-bit immediate. The low two bits of the target
2847 // offset are implied zero and so are not part of the immediate.
2848 def am_ldrlit : Operand<iPTR> {
2849 let EncoderMethod = "getLoadLiteralOpValue";
2850 let DecoderMethod = "DecodePCRelLabel19";
2851 let PrintMethod = "printAlignedLabel";
2852 let ParserMatchClass = PCRelLabel19Operand;
2853 let OperandType = "OPERAND_PCREL";
2856 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2857 class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm>
2858 : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
2859 asm, "\t$Rt, $label", "", []>,
2863 let Inst{31-30} = opc;
2864 let Inst{29-27} = 0b011;
2866 let Inst{25-24} = 0b00;
2867 let Inst{23-5} = label;
2871 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2872 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
2873 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
2874 asm, "\t$Rt, $label", "", pat>,
2878 let Inst{31-30} = opc;
2879 let Inst{29-27} = 0b011;
2881 let Inst{25-24} = 0b00;
2882 let Inst{23-5} = label;
2887 // Load/store register offset
2890 def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
2891 def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
2892 def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
2893 def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
2894 def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
2896 def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
2897 def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
2898 def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
2899 def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
2900 def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
2902 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
2903 let Name = "Mem" # Reg # "Extend" # Width;
2904 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
2905 let RenderMethod = "addMemExtendOperands";
2906 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
2909 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
2910 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2911 // the trivial shift.
2912 let RenderMethod = "addMemExtend8Operands";
2914 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
2915 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
2916 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
2917 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
2919 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
2920 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2921 // the trivial shift.
2922 let RenderMethod = "addMemExtend8Operands";
2924 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
2925 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
2926 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
2927 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
2929 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
2931 let ParserMatchClass = ParserClass;
2932 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
2933 let DecoderMethod = "DecodeMemExtend";
2934 let EncoderMethod = "getMemExtendOpValue";
2935 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
2938 def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>;
2939 def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>;
2940 def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>;
2941 def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>;
2942 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
2944 def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>;
2945 def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>;
2946 def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>;
2947 def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>;
2948 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
2950 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
2951 Operand wextend, Operand xextend> {
2952 // CodeGen-level pattern covering the entire addressing mode.
2953 ComplexPattern Wpat = windex;
2954 ComplexPattern Xpat = xindex;
2956 // Asm-level Operand covering the valid "uxtw #3" style syntax.
2957 Operand Wext = wextend;
2958 Operand Xext = xextend;
2961 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
2962 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
2963 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
2964 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
2965 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
2968 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
2969 string asm, dag ins, dag outs, list<dag> pat>
2970 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2975 let Inst{31-30} = sz;
2976 let Inst{29-27} = 0b111;
2978 let Inst{25-24} = 0b00;
2979 let Inst{23-22} = opc;
2981 let Inst{20-16} = Rm;
2982 let Inst{15} = extend{1}; // sign extend Rm?
2984 let Inst{12} = extend{0}; // do shift?
2985 let Inst{11-10} = 0b10;
2990 class ROInstAlias<string asm, RegisterOperand regtype, Instruction INST>
2991 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
2992 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2994 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
2995 string asm, ValueType Ty, SDPatternOperator loadop> {
2996 let AddedComplexity = 10 in
2997 def roW : LoadStore8RO<sz, V, opc, regtype, asm,
2999 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
3000 [(set (Ty regtype:$Rt),
3001 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
3002 ro_Wextend8:$extend)))]>,
3003 Sched<[WriteLDIdx, ReadAdrBase]> {
3007 let AddedComplexity = 10 in
3008 def roX : LoadStore8RO<sz, V, opc, regtype, asm,
3010 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
3011 [(set (Ty regtype:$Rt),
3012 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
3013 ro_Xextend8:$extend)))]>,
3014 Sched<[WriteLDIdx, ReadAdrBase]> {
3018 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3021 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3022 string asm, ValueType Ty, SDPatternOperator storeop> {
3023 let AddedComplexity = 10 in
3024 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
3025 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
3026 [(storeop (Ty regtype:$Rt),
3027 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
3028 ro_Wextend8:$extend))]>,
3029 Sched<[WriteSTIdx, ReadAdrBase]> {
3033 let AddedComplexity = 10 in
3034 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
3035 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
3036 [(storeop (Ty regtype:$Rt),
3037 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
3038 ro_Xextend8:$extend))]>,
3039 Sched<[WriteSTIdx, ReadAdrBase]> {
3043 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3046 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3047 string asm, dag ins, dag outs, list<dag> pat>
3048 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3053 let Inst{31-30} = sz;
3054 let Inst{29-27} = 0b111;
3056 let Inst{25-24} = 0b00;
3057 let Inst{23-22} = opc;
3059 let Inst{20-16} = Rm;
3060 let Inst{15} = extend{1}; // sign extend Rm?
3062 let Inst{12} = extend{0}; // do shift?
3063 let Inst{11-10} = 0b10;
3068 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3069 string asm, ValueType Ty, SDPatternOperator loadop> {
3070 let AddedComplexity = 10 in
3071 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3072 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
3073 [(set (Ty regtype:$Rt),
3074 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
3075 ro_Wextend16:$extend)))]>,
3076 Sched<[WriteLDIdx, ReadAdrBase]> {
3080 let AddedComplexity = 10 in
3081 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3082 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
3083 [(set (Ty regtype:$Rt),
3084 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
3085 ro_Xextend16:$extend)))]>,
3086 Sched<[WriteLDIdx, ReadAdrBase]> {
3090 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3093 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3094 string asm, ValueType Ty, SDPatternOperator storeop> {
3095 let AddedComplexity = 10 in
3096 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
3097 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
3098 [(storeop (Ty regtype:$Rt),
3099 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
3100 ro_Wextend16:$extend))]>,
3101 Sched<[WriteSTIdx, ReadAdrBase]> {
3105 let AddedComplexity = 10 in
3106 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
3107 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
3108 [(storeop (Ty regtype:$Rt),
3109 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
3110 ro_Xextend16:$extend))]>,
3111 Sched<[WriteSTIdx, ReadAdrBase]> {
3115 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3118 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3119 string asm, dag ins, dag outs, list<dag> pat>
3120 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3125 let Inst{31-30} = sz;
3126 let Inst{29-27} = 0b111;
3128 let Inst{25-24} = 0b00;
3129 let Inst{23-22} = opc;
3131 let Inst{20-16} = Rm;
3132 let Inst{15} = extend{1}; // sign extend Rm?
3134 let Inst{12} = extend{0}; // do shift?
3135 let Inst{11-10} = 0b10;
3140 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3141 string asm, ValueType Ty, SDPatternOperator loadop> {
3142 let AddedComplexity = 10 in
3143 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3144 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
3145 [(set (Ty regtype:$Rt),
3146 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
3147 ro_Wextend32:$extend)))]>,
3148 Sched<[WriteLDIdx, ReadAdrBase]> {
3152 let AddedComplexity = 10 in
3153 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3154 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
3155 [(set (Ty regtype:$Rt),
3156 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
3157 ro_Xextend32:$extend)))]>,
3158 Sched<[WriteLDIdx, ReadAdrBase]> {
3162 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3165 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3166 string asm, ValueType Ty, SDPatternOperator storeop> {
3167 let AddedComplexity = 10 in
3168 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
3169 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
3170 [(storeop (Ty regtype:$Rt),
3171 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
3172 ro_Wextend32:$extend))]>,
3173 Sched<[WriteSTIdx, ReadAdrBase]> {
3177 let AddedComplexity = 10 in
3178 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
3179 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
3180 [(storeop (Ty regtype:$Rt),
3181 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
3182 ro_Xextend32:$extend))]>,
3183 Sched<[WriteSTIdx, ReadAdrBase]> {
3187 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3190 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3191 string asm, dag ins, dag outs, list<dag> pat>
3192 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3197 let Inst{31-30} = sz;
3198 let Inst{29-27} = 0b111;
3200 let Inst{25-24} = 0b00;
3201 let Inst{23-22} = opc;
3203 let Inst{20-16} = Rm;
3204 let Inst{15} = extend{1}; // sign extend Rm?
3206 let Inst{12} = extend{0}; // do shift?
3207 let Inst{11-10} = 0b10;
3212 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3213 string asm, ValueType Ty, SDPatternOperator loadop> {
3214 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3215 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3216 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3217 [(set (Ty regtype:$Rt),
3218 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3219 ro_Wextend64:$extend)))]>,
3220 Sched<[WriteLDIdx, ReadAdrBase]> {
3224 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3225 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3226 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3227 [(set (Ty regtype:$Rt),
3228 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3229 ro_Xextend64:$extend)))]>,
3230 Sched<[WriteLDIdx, ReadAdrBase]> {
3234 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3237 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3238 string asm, ValueType Ty, SDPatternOperator storeop> {
3239 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3240 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
3241 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3242 [(storeop (Ty regtype:$Rt),
3243 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3244 ro_Wextend64:$extend))]>,
3245 Sched<[WriteSTIdx, ReadAdrBase]> {
3249 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3250 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
3251 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3252 [(storeop (Ty regtype:$Rt),
3253 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3254 ro_Xextend64:$extend))]>,
3255 Sched<[WriteSTIdx, ReadAdrBase]> {
3259 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3262 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3263 string asm, dag ins, dag outs, list<dag> pat>
3264 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3269 let Inst{31-30} = sz;
3270 let Inst{29-27} = 0b111;
3272 let Inst{25-24} = 0b00;
3273 let Inst{23-22} = opc;
3275 let Inst{20-16} = Rm;
3276 let Inst{15} = extend{1}; // sign extend Rm?
3278 let Inst{12} = extend{0}; // do shift?
3279 let Inst{11-10} = 0b10;
3284 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3285 string asm, ValueType Ty, SDPatternOperator loadop> {
3286 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3287 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3288 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
3289 [(set (Ty regtype:$Rt),
3290 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
3291 ro_Wextend128:$extend)))]>,
3292 Sched<[WriteLDIdx, ReadAdrBase]> {
3296 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3297 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3298 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
3299 [(set (Ty regtype:$Rt),
3300 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
3301 ro_Xextend128:$extend)))]>,
3302 Sched<[WriteLDIdx, ReadAdrBase]> {
3306 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3309 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3310 string asm, ValueType Ty, SDPatternOperator storeop> {
3311 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3312 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
3313 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
3315 Sched<[WriteSTIdx, ReadAdrBase]> {
3319 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3320 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
3321 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
3323 Sched<[WriteSTIdx, ReadAdrBase]> {
3327 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3330 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3331 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
3332 string asm, list<dag> pat>
3333 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
3339 let Inst{31-30} = sz;
3340 let Inst{29-27} = 0b111;
3342 let Inst{25-24} = 0b00;
3343 let Inst{23-22} = opc;
3345 let Inst{20-16} = Rm;
3346 let Inst{15} = extend{1}; // sign extend Rm?
3348 let Inst{12} = extend{0}; // do shift?
3349 let Inst{11-10} = 0b10;
3354 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
3355 def roW : BasePrefetchRO<sz, V, opc, (outs),
3356 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3357 asm, [(AArch64Prefetch imm:$Rt,
3358 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3359 ro_Wextend64:$extend))]> {
3363 def roX : BasePrefetchRO<sz, V, opc, (outs),
3364 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3365 asm, [(AArch64Prefetch imm:$Rt,
3366 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3367 ro_Xextend64:$extend))]> {
3371 def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
3372 (!cast<Instruction>(NAME # "roX") prfop:$Rt,
3373 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
3377 // Load/store unscaled immediate
3380 def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
3381 def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
3382 def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
3383 def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
3384 def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
3386 def gi_am_unscaled8 :
3387 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">,
3388 GIComplexPatternEquiv<am_unscaled8>;
3389 def gi_am_unscaled16 :
3390 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">,
3391 GIComplexPatternEquiv<am_unscaled16>;
3392 def gi_am_unscaled32 :
3393 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">,
3394 GIComplexPatternEquiv<am_unscaled32>;
3395 def gi_am_unscaled64 :
3396 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">,
3397 GIComplexPatternEquiv<am_unscaled64>;
3398 def gi_am_unscaled128 :
3399 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">,
3400 GIComplexPatternEquiv<am_unscaled128>;
3403 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3404 string asm, list<dag> pattern>
3405 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
3409 let Inst{31-30} = sz;
3410 let Inst{29-27} = 0b111;
3412 let Inst{25-24} = 0b00;
3413 let Inst{23-22} = opc;
3415 let Inst{20-12} = offset;
3416 let Inst{11-10} = 0b00;
3420 let DecoderMethod = "DecodeSignedLdStInstruction";
3423 // Armv8.4 LDAPR & STLR with Immediate Offset instruction
3424 multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc,
3425 RegisterOperand regtype > {
3426 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt),
3427 (ins GPR64sp:$Rn, simm9:$offset), asm, []>,
3432 def : InstAlias<asm # "\t$Rt, [$Rn]",
3433 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3436 multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc,
3437 RegisterOperand regtype > {
3438 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs),
3439 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3445 def : InstAlias<asm # "\t$Rt, [$Rn]",
3446 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3449 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3450 string asm, list<dag> pattern> {
3451 let AddedComplexity = 1 in // try this before LoadUI
3452 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
3453 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
3456 def : InstAlias<asm # "\t$Rt, [$Rn]",
3457 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3460 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3461 string asm, list<dag> pattern> {
3462 let AddedComplexity = 1 in // try this before StoreUI
3463 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3464 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3468 def : InstAlias<asm # "\t$Rt, [$Rn]",
3469 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3472 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
3474 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3475 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3476 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
3480 def : InstAlias<asm # "\t$Rt, [$Rn]",
3481 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
3485 // Load/store unscaled immediate, unprivileged
3488 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3489 dag oops, dag iops, string asm>
3490 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
3494 let Inst{31-30} = sz;
3495 let Inst{29-27} = 0b111;
3497 let Inst{25-24} = 0b00;
3498 let Inst{23-22} = opc;
3500 let Inst{20-12} = offset;
3501 let Inst{11-10} = 0b10;
3505 let DecoderMethod = "DecodeSignedLdStInstruction";
3508 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3509 RegisterClass regtype, string asm> {
3510 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3511 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3512 (ins GPR64sp:$Rn, simm9:$offset), asm>,
3515 def : InstAlias<asm # "\t$Rt, [$Rn]",
3516 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3519 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3520 RegisterClass regtype, string asm> {
3521 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3522 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3523 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3527 def : InstAlias<asm # "\t$Rt, [$Rn]",
3528 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3532 // Load/store pre-indexed
3535 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3536 string asm, string cstr, list<dag> pat>
3537 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3541 let Inst{31-30} = sz;
3542 let Inst{29-27} = 0b111;
3544 let Inst{25-24} = 0;
3545 let Inst{23-22} = opc;
3547 let Inst{20-12} = offset;
3548 let Inst{11-10} = 0b11;
3552 let DecoderMethod = "DecodeSignedLdStInstruction";
3555 let hasSideEffects = 0 in {
3556 let mayStore = 0, mayLoad = 1 in
3557 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3559 : BaseLoadStorePreIdx<sz, V, opc,
3560 (outs GPR64sp:$wback, regtype:$Rt),
3561 (ins GPR64sp:$Rn, simm9:$offset), asm,
3562 "$Rn = $wback,@earlyclobber $wback", []>,
3563 Sched<[WriteLD, WriteAdr]>;
3565 let mayStore = 1, mayLoad = 0 in
3566 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3567 string asm, SDPatternOperator storeop, ValueType Ty>
3568 : BaseLoadStorePreIdx<sz, V, opc,
3569 (outs GPR64sp:$wback),
3570 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3571 asm, "$Rn = $wback,@earlyclobber $wback",
3572 [(set GPR64sp:$wback,
3573 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3574 Sched<[WriteAdr, WriteST]>;
3575 } // hasSideEffects = 0
3578 // Load/store post-indexed
3581 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3582 string asm, string cstr, list<dag> pat>
3583 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
3587 let Inst{31-30} = sz;
3588 let Inst{29-27} = 0b111;
3590 let Inst{25-24} = 0b00;
3591 let Inst{23-22} = opc;
3593 let Inst{20-12} = offset;
3594 let Inst{11-10} = 0b01;
3598 let DecoderMethod = "DecodeSignedLdStInstruction";
3601 let hasSideEffects = 0 in {
3602 let mayStore = 0, mayLoad = 1 in
3603 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3605 : BaseLoadStorePostIdx<sz, V, opc,
3606 (outs GPR64sp:$wback, regtype:$Rt),
3607 (ins GPR64sp:$Rn, simm9:$offset),
3608 asm, "$Rn = $wback,@earlyclobber $wback", []>,
3609 Sched<[WriteLD, WriteAdr]>;
3611 let mayStore = 1, mayLoad = 0 in
3612 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
3613 string asm, SDPatternOperator storeop, ValueType Ty>
3614 : BaseLoadStorePostIdx<sz, V, opc,
3615 (outs GPR64sp:$wback),
3616 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3617 asm, "$Rn = $wback,@earlyclobber $wback",
3618 [(set GPR64sp:$wback,
3619 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3620 Sched<[WriteAdr, WriteST]>;
3621 } // hasSideEffects = 0
3628 // (indexed, offset)
3630 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
3632 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3637 let Inst{31-30} = opc;
3638 let Inst{29-27} = 0b101;
3640 let Inst{25-23} = 0b010;
3642 let Inst{21-15} = offset;
3643 let Inst{14-10} = Rt2;
3647 let DecoderMethod = "DecodePairLdStInstruction";
3650 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype,
3651 Operand indextype, string asm> {
3652 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3653 def i : BaseLoadStorePairOffset<opc, V, 1,
3654 (outs regtype:$Rt, regtype:$Rt2),
3655 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3656 Sched<[WriteLD, WriteLDHi]>;
3658 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3659 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3664 multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype,
3665 Operand indextype, string asm> {
3666 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
3667 def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
3668 (ins regtype:$Rt, regtype:$Rt2,
3669 GPR64sp:$Rn, indextype:$offset),
3673 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3674 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3679 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3681 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
3686 let Inst{31-30} = opc;
3687 let Inst{29-27} = 0b101;
3689 let Inst{25-23} = 0b011;
3691 let Inst{21-15} = offset;
3692 let Inst{14-10} = Rt2;
3696 let DecoderMethod = "DecodePairLdStInstruction";
3699 let hasSideEffects = 0 in {
3700 let mayStore = 0, mayLoad = 1 in
3701 class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
3702 Operand indextype, string asm>
3703 : BaseLoadStorePairPreIdx<opc, V, 1,
3704 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3705 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3706 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3708 let mayStore = 1, mayLoad = 0 in
3709 class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,
3710 Operand indextype, string asm>
3711 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
3712 (ins regtype:$Rt, regtype:$Rt2,
3713 GPR64sp:$Rn, indextype:$offset),
3715 Sched<[WriteAdr, WriteSTP]>;
3716 } // hasSideEffects = 0
3720 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3722 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
3727 let Inst{31-30} = opc;
3728 let Inst{29-27} = 0b101;
3730 let Inst{25-23} = 0b001;
3732 let Inst{21-15} = offset;
3733 let Inst{14-10} = Rt2;
3737 let DecoderMethod = "DecodePairLdStInstruction";
3740 let hasSideEffects = 0 in {
3741 let mayStore = 0, mayLoad = 1 in
3742 class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
3743 Operand idxtype, string asm>
3744 : BaseLoadStorePairPostIdx<opc, V, 1,
3745 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3746 (ins GPR64sp:$Rn, idxtype:$offset), asm>,
3747 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3749 let mayStore = 1, mayLoad = 0 in
3750 class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,
3751 Operand idxtype, string asm>
3752 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
3753 (ins regtype:$Rt, regtype:$Rt2,
3754 GPR64sp:$Rn, idxtype:$offset),
3756 Sched<[WriteAdr, WriteSTP]>;
3757 } // hasSideEffects = 0
3761 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
3763 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3768 let Inst{31-30} = opc;
3769 let Inst{29-27} = 0b101;
3771 let Inst{25-23} = 0b000;
3773 let Inst{21-15} = offset;
3774 let Inst{14-10} = Rt2;
3778 let DecoderMethod = "DecodePairLdStInstruction";
3781 multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3782 Operand indextype, string asm> {
3783 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3784 def i : BaseLoadStorePairNoAlloc<opc, V, 1,
3785 (outs regtype:$Rt, regtype:$Rt2),
3786 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3787 Sched<[WriteLD, WriteLDHi]>;
3790 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3791 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3795 multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3796 Operand indextype, string asm> {
3797 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
3798 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
3799 (ins regtype:$Rt, regtype:$Rt2,
3800 GPR64sp:$Rn, indextype:$offset),
3804 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3805 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3810 // Load/store exclusive
3813 // True exclusive operations write to and/or read from the system's exclusive
3814 // monitors, which as far as a compiler is concerned can be modelled as a
3815 // random shared memory address. Hence LoadExclusive mayStore.
3817 // Since these instructions have the undefined register bits set to 1 in
3818 // their canonical form, we need a post encoder method to set those bits
3819 // to 1 when encoding these instructions. We do this using the
3820 // fixLoadStoreExclusive function. This function has template parameters:
3822 // fixLoadStoreExclusive<int hasRs, int hasRt2>
3824 // hasRs indicates that the instruction uses the Rs field, so we won't set
3825 // it to 1 (and the same for Rt2). We don't need template parameters for
3826 // the other register fields since Rt and Rn are always used.
3828 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
3829 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3830 dag oops, dag iops, string asm, string operands>
3831 : I<oops, iops, asm, operands, "", []> {
3832 let Inst{31-30} = sz;
3833 let Inst{29-24} = 0b001000;
3839 let DecoderMethod = "DecodeExclusiveLdStInstruction";
3842 // Neither Rs nor Rt2 operands.
3843 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3844 dag oops, dag iops, string asm, string operands>
3845 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
3848 let Inst{20-16} = 0b11111;
3849 let Unpredictable{20-16} = 0b11111;
3850 let Inst{14-10} = 0b11111;
3851 let Unpredictable{14-10} = 0b11111;
3855 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
3858 // Simple load acquires don't set the exclusive monitor
3859 let mayLoad = 1, mayStore = 0 in
3860 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3861 RegisterClass regtype, string asm>
3862 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3863 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3866 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3867 RegisterClass regtype, string asm>
3868 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3869 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3872 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3873 RegisterClass regtype, string asm>
3874 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3875 (outs regtype:$Rt, regtype:$Rt2),
3876 (ins GPR64sp0:$Rn), asm,
3877 "\t$Rt, $Rt2, [$Rn]">,
3878 Sched<[WriteLD, WriteLDHi]> {
3882 let Inst{14-10} = Rt2;
3886 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
3889 // Simple store release operations do not check the exclusive monitor.
3890 let mayLoad = 0, mayStore = 1 in
3891 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3892 RegisterClass regtype, string asm>
3893 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
3894 (ins regtype:$Rt, GPR64sp0:$Rn),
3895 asm, "\t$Rt, [$Rn]">,
3898 let mayLoad = 1, mayStore = 1 in
3899 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3900 RegisterClass regtype, string asm>
3901 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
3902 (ins regtype:$Rt, GPR64sp0:$Rn),
3903 asm, "\t$Ws, $Rt, [$Rn]">,
3908 let Inst{20-16} = Ws;
3912 let Constraints = "@earlyclobber $Ws";
3913 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
3916 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3917 RegisterClass regtype, string asm>
3918 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3920 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
3921 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
3927 let Inst{20-16} = Ws;
3928 let Inst{14-10} = Rt2;
3932 let Constraints = "@earlyclobber $Ws";
3936 // Exception generation
3939 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3940 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
3941 : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
3944 let Inst{31-24} = 0b11010100;
3945 let Inst{23-21} = op1;
3946 let Inst{20-5} = imm;
3947 let Inst{4-2} = 0b000;
3951 let Predicates = [HasFPARMv8] in {
3954 // Floating point to integer conversion
3957 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
3958 RegisterClass srcType, RegisterClass dstType,
3959 string asm, list<dag> pattern>
3960 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3961 asm, "\t$Rd, $Rn", "", pattern>,
3962 Sched<[WriteFCvt]> {
3965 let Inst{30-29} = 0b00;
3966 let Inst{28-24} = 0b11110;
3967 let Inst{23-22} = type;
3969 let Inst{20-19} = rmode;
3970 let Inst{18-16} = opcode;
3971 let Inst{15-10} = 0;
3976 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3977 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
3978 RegisterClass srcType, RegisterClass dstType,
3979 Operand immType, string asm, list<dag> pattern>
3980 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3981 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3982 Sched<[WriteFCvt]> {
3986 let Inst{30-29} = 0b00;
3987 let Inst{28-24} = 0b11110;
3988 let Inst{23-22} = type;
3990 let Inst{20-19} = rmode;
3991 let Inst{18-16} = opcode;
3992 let Inst{15-10} = scale;
3997 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
3998 SDPatternOperator OpN> {
3999 // Unscaled half-precision to 32-bit
4000 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
4001 [(set GPR32:$Rd, (OpN FPR16:$Rn))]> {
4002 let Inst{31} = 0; // 32-bit GPR flag
4003 let Predicates = [HasFullFP16];
4006 // Unscaled half-precision to 64-bit
4007 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
4008 [(set GPR64:$Rd, (OpN FPR16:$Rn))]> {
4009 let Inst{31} = 1; // 64-bit GPR flag
4010 let Predicates = [HasFullFP16];
4013 // Unscaled single-precision to 32-bit
4014 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
4015 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
4016 let Inst{31} = 0; // 32-bit GPR flag
4019 // Unscaled single-precision to 64-bit
4020 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
4021 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
4022 let Inst{31} = 1; // 64-bit GPR flag
4025 // Unscaled double-precision to 32-bit
4026 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
4027 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
4028 let Inst{31} = 0; // 32-bit GPR flag
4031 // Unscaled double-precision to 64-bit
4032 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
4033 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
4034 let Inst{31} = 1; // 64-bit GPR flag
4038 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
4039 SDPatternOperator OpN> {
4040 // Scaled half-precision to 32-bit
4041 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
4042 fixedpoint_f16_i32, asm,
4043 [(set GPR32:$Rd, (OpN (fmul FPR16:$Rn,
4044 fixedpoint_f16_i32:$scale)))]> {
4045 let Inst{31} = 0; // 32-bit GPR flag
4047 let Predicates = [HasFullFP16];
4050 // Scaled half-precision to 64-bit
4051 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
4052 fixedpoint_f16_i64, asm,
4053 [(set GPR64:$Rd, (OpN (fmul FPR16:$Rn,
4054 fixedpoint_f16_i64:$scale)))]> {
4055 let Inst{31} = 1; // 64-bit GPR flag
4056 let Predicates = [HasFullFP16];
4059 // Scaled single-precision to 32-bit
4060 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
4061 fixedpoint_f32_i32, asm,
4062 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
4063 fixedpoint_f32_i32:$scale)))]> {
4064 let Inst{31} = 0; // 32-bit GPR flag
4068 // Scaled single-precision to 64-bit
4069 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
4070 fixedpoint_f32_i64, asm,
4071 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
4072 fixedpoint_f32_i64:$scale)))]> {
4073 let Inst{31} = 1; // 64-bit GPR flag
4076 // Scaled double-precision to 32-bit
4077 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
4078 fixedpoint_f64_i32, asm,
4079 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
4080 fixedpoint_f64_i32:$scale)))]> {
4081 let Inst{31} = 0; // 32-bit GPR flag
4085 // Scaled double-precision to 64-bit
4086 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
4087 fixedpoint_f64_i64, asm,
4088 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
4089 fixedpoint_f64_i64:$scale)))]> {
4090 let Inst{31} = 1; // 64-bit GPR flag
4095 // Integer to floating point conversion
4098 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
4099 class BaseIntegerToFP<bit isUnsigned,
4100 RegisterClass srcType, RegisterClass dstType,
4101 Operand immType, string asm, list<dag> pattern>
4102 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
4103 asm, "\t$Rd, $Rn, $scale", "", pattern>,
4104 Sched<[WriteFCvt]> {
4108 let Inst{30-24} = 0b0011110;
4109 let Inst{21-17} = 0b00001;
4110 let Inst{16} = isUnsigned;
4111 let Inst{15-10} = scale;
4116 class BaseIntegerToFPUnscaled<bit isUnsigned,
4117 RegisterClass srcType, RegisterClass dstType,
4118 ValueType dvt, string asm, SDNode node>
4119 : I<(outs dstType:$Rd), (ins srcType:$Rn),
4120 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
4121 Sched<[WriteFCvt]> {
4125 let Inst{30-24} = 0b0011110;
4126 let Inst{21-17} = 0b10001;
4127 let Inst{16} = isUnsigned;
4128 let Inst{15-10} = 0b000000;
4133 multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
4135 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
4136 let Inst{31} = 0; // 32-bit GPR flag
4137 let Inst{23-22} = 0b11; // 16-bit FPR flag
4138 let Predicates = [HasFullFP16];
4141 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
4142 let Inst{31} = 0; // 32-bit GPR flag
4143 let Inst{23-22} = 0b00; // 32-bit FPR flag
4146 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
4147 let Inst{31} = 0; // 32-bit GPR flag
4148 let Inst{23-22} = 0b01; // 64-bit FPR flag
4151 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
4152 let Inst{31} = 1; // 64-bit GPR flag
4153 let Inst{23-22} = 0b11; // 16-bit FPR flag
4154 let Predicates = [HasFullFP16];
4157 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
4158 let Inst{31} = 1; // 64-bit GPR flag
4159 let Inst{23-22} = 0b00; // 32-bit FPR flag
4162 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
4163 let Inst{31} = 1; // 64-bit GPR flag
4164 let Inst{23-22} = 0b01; // 64-bit FPR flag
4168 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm,
4170 (fdiv (node GPR32:$Rn),
4171 fixedpoint_f16_i32:$scale))]> {
4172 let Inst{31} = 0; // 32-bit GPR flag
4173 let Inst{23-22} = 0b11; // 16-bit FPR flag
4175 let Predicates = [HasFullFP16];
4178 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
4180 (fdiv (node GPR32:$Rn),
4181 fixedpoint_f32_i32:$scale))]> {
4182 let Inst{31} = 0; // 32-bit GPR flag
4183 let Inst{23-22} = 0b00; // 32-bit FPR flag
4187 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
4189 (fdiv (node GPR32:$Rn),
4190 fixedpoint_f64_i32:$scale))]> {
4191 let Inst{31} = 0; // 32-bit GPR flag
4192 let Inst{23-22} = 0b01; // 64-bit FPR flag
4196 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm,
4198 (fdiv (node GPR64:$Rn),
4199 fixedpoint_f16_i64:$scale))]> {
4200 let Inst{31} = 1; // 64-bit GPR flag
4201 let Inst{23-22} = 0b11; // 16-bit FPR flag
4202 let Predicates = [HasFullFP16];
4205 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
4207 (fdiv (node GPR64:$Rn),
4208 fixedpoint_f32_i64:$scale))]> {
4209 let Inst{31} = 1; // 64-bit GPR flag
4210 let Inst{23-22} = 0b00; // 32-bit FPR flag
4213 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
4215 (fdiv (node GPR64:$Rn),
4216 fixedpoint_f64_i64:$scale))]> {
4217 let Inst{31} = 1; // 64-bit GPR flag
4218 let Inst{23-22} = 0b01; // 64-bit FPR flag
4223 // Unscaled integer <-> floating point conversion (i.e. FMOV)
4226 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4227 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
4228 RegisterClass srcType, RegisterClass dstType,
4230 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
4231 // We use COPY_TO_REGCLASS for these bitconvert operations.
4232 // copyPhysReg() expands the resultant COPY instructions after
4233 // regalloc is done. This gives greater freedom for the allocator
4234 // and related passes (coalescing, copy propagation, et. al.) to
4235 // be more effective.
4236 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
4237 Sched<[WriteFCopy]> {
4240 let Inst{30-24} = 0b0011110;
4242 let Inst{20-19} = rmode;
4243 let Inst{18-16} = opcode;
4244 let Inst{15-10} = 0b000000;
4249 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4250 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
4251 RegisterClass srcType, RegisterOperand dstType, string asm,
4253 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
4254 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
4255 Sched<[WriteFCopy]> {
4258 let Inst{30-23} = 0b00111101;
4260 let Inst{20-19} = rmode;
4261 let Inst{18-16} = opcode;
4262 let Inst{15-10} = 0b000000;
4266 let DecoderMethod = "DecodeFMOVLaneInstruction";
4269 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4270 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
4271 RegisterOperand srcType, RegisterClass dstType, string asm,
4273 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
4274 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
4275 Sched<[WriteFCopy]> {
4278 let Inst{30-23} = 0b00111101;
4280 let Inst{20-19} = rmode;
4281 let Inst{18-16} = opcode;
4282 let Inst{15-10} = 0b000000;
4286 let DecoderMethod = "DecodeFMOVLaneInstruction";
4290 multiclass UnscaledConversion<string asm> {
4291 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
4292 let Inst{31} = 0; // 32-bit GPR flag
4293 let Inst{23-22} = 0b11; // 16-bit FPR flag
4294 let Predicates = [HasFullFP16];
4297 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
4298 let Inst{31} = 1; // 64-bit GPR flag
4299 let Inst{23-22} = 0b11; // 16-bit FPR flag
4300 let Predicates = [HasFullFP16];
4303 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
4304 let Inst{31} = 0; // 32-bit GPR flag
4305 let Inst{23-22} = 0b00; // 32-bit FPR flag
4308 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
4309 let Inst{31} = 1; // 64-bit GPR flag
4310 let Inst{23-22} = 0b01; // 64-bit FPR flag
4313 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
4314 let Inst{31} = 0; // 32-bit GPR flag
4315 let Inst{23-22} = 0b11; // 16-bit FPR flag
4316 let Predicates = [HasFullFP16];
4319 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
4320 let Inst{31} = 1; // 64-bit GPR flag
4321 let Inst{23-22} = 0b11; // 16-bit FPR flag
4322 let Predicates = [HasFullFP16];
4325 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
4326 let Inst{31} = 0; // 32-bit GPR flag
4327 let Inst{23-22} = 0b00; // 32-bit FPR flag
4330 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
4331 let Inst{31} = 1; // 64-bit GPR flag
4332 let Inst{23-22} = 0b01; // 64-bit FPR flag
4335 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
4341 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
4349 // Floating point conversion
4352 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
4353 RegisterClass srcType, string asm, list<dag> pattern>
4354 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
4355 Sched<[WriteFCvt]> {
4358 let Inst{31-24} = 0b00011110;
4359 let Inst{23-22} = type;
4360 let Inst{21-17} = 0b10001;
4361 let Inst{16-15} = opcode;
4362 let Inst{14-10} = 0b10000;
4367 multiclass FPConversion<string asm> {
4368 // Double-precision to Half-precision
4369 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
4370 [(set FPR16:$Rd, (fpround FPR64:$Rn))]>;
4372 // Double-precision to Single-precision
4373 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
4374 [(set FPR32:$Rd, (fpround FPR64:$Rn))]>;
4376 // Half-precision to Double-precision
4377 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
4378 [(set FPR64:$Rd, (fpextend FPR16:$Rn))]>;
4380 // Half-precision to Single-precision
4381 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
4382 [(set FPR32:$Rd, (fpextend FPR16:$Rn))]>;
4384 // Single-precision to Double-precision
4385 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
4386 [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>;
4388 // Single-precision to Half-precision
4389 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
4390 [(set FPR16:$Rd, (fpround FPR32:$Rn))]>;
4394 // Single operand floating point data processing
4397 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4398 class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
4399 ValueType vt, string asm, SDPatternOperator node>
4400 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
4401 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
4405 let Inst{31-24} = 0b00011110;
4406 let Inst{21-19} = 0b100;
4407 let Inst{18-15} = opcode;
4408 let Inst{14-10} = 0b10000;
4413 multiclass SingleOperandFPData<bits<4> opcode, string asm,
4414 SDPatternOperator node = null_frag> {
4415 def Hr : BaseSingleOperandFPData<opcode, FPR16, f16, asm, node> {
4416 let Inst{23-22} = 0b11; // 16-bit size flag
4417 let Predicates = [HasFullFP16];
4420 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
4421 let Inst{23-22} = 0b00; // 32-bit size flag
4424 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
4425 let Inst{23-22} = 0b01; // 64-bit size flag
4430 // Two operand floating point data processing
4433 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4434 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
4435 string asm, list<dag> pat>
4436 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
4437 asm, "\t$Rd, $Rn, $Rm", "", pat>,
4442 let Inst{31-24} = 0b00011110;
4444 let Inst{20-16} = Rm;
4445 let Inst{15-12} = opcode;
4446 let Inst{11-10} = 0b10;
4451 multiclass TwoOperandFPData<bits<4> opcode, string asm,
4452 SDPatternOperator node = null_frag> {
4453 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4454 [(set (f16 FPR16:$Rd),
4455 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
4456 let Inst{23-22} = 0b11; // 16-bit size flag
4457 let Predicates = [HasFullFP16];
4460 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4461 [(set (f32 FPR32:$Rd),
4462 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
4463 let Inst{23-22} = 0b00; // 32-bit size flag
4466 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4467 [(set (f64 FPR64:$Rd),
4468 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
4469 let Inst{23-22} = 0b01; // 64-bit size flag
4473 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
4474 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4475 [(set FPR16:$Rd, (fneg (node FPR16:$Rn, (f16 FPR16:$Rm))))]> {
4476 let Inst{23-22} = 0b11; // 16-bit size flag
4477 let Predicates = [HasFullFP16];
4480 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4481 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
4482 let Inst{23-22} = 0b00; // 32-bit size flag
4485 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4486 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
4487 let Inst{23-22} = 0b01; // 64-bit size flag
4493 // Three operand floating point data processing
4496 class BaseThreeOperandFPData<bit isNegated, bit isSub,
4497 RegisterClass regtype, string asm, list<dag> pat>
4498 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
4499 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
4500 Sched<[WriteFMul]> {
4505 let Inst{31-24} = 0b00011111;
4506 let Inst{21} = isNegated;
4507 let Inst{20-16} = Rm;
4508 let Inst{15} = isSub;
4509 let Inst{14-10} = Ra;
4514 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
4515 SDPatternOperator node> {
4516 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
4518 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
4519 let Inst{23-22} = 0b11; // 16-bit size flag
4520 let Predicates = [HasFullFP16];
4523 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
4525 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
4526 let Inst{23-22} = 0b00; // 32-bit size flag
4529 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
4531 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
4532 let Inst{23-22} = 0b01; // 64-bit size flag
4537 // Floating point data comparisons
4540 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4541 class BaseOneOperandFPComparison<bit signalAllNans,
4542 RegisterClass regtype, string asm,
4544 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
4545 Sched<[WriteFCmp]> {
4547 let Inst{31-24} = 0b00011110;
4550 let Inst{15-10} = 0b001000;
4552 let Inst{4} = signalAllNans;
4553 let Inst{3-0} = 0b1000;
4555 // Rm should be 0b00000 canonically, but we need to accept any value.
4556 let PostEncoderMethod = "fixOneOperandFPComparison";
4559 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4560 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
4561 string asm, list<dag> pat>
4562 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
4563 Sched<[WriteFCmp]> {
4566 let Inst{31-24} = 0b00011110;
4568 let Inst{20-16} = Rm;
4569 let Inst{15-10} = 0b001000;
4571 let Inst{4} = signalAllNans;
4572 let Inst{3-0} = 0b0000;
4575 multiclass FPComparison<bit signalAllNans, string asm,
4576 SDPatternOperator OpNode = null_frag> {
4577 let Defs = [NZCV] in {
4578 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
4579 [(OpNode FPR16:$Rn, (f16 FPR16:$Rm)), (implicit NZCV)]> {
4580 let Inst{23-22} = 0b11;
4581 let Predicates = [HasFullFP16];
4584 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
4585 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
4586 let Inst{23-22} = 0b11;
4587 let Predicates = [HasFullFP16];
4590 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
4591 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
4592 let Inst{23-22} = 0b00;
4595 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
4596 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
4597 let Inst{23-22} = 0b00;
4600 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
4601 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
4602 let Inst{23-22} = 0b01;
4605 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
4606 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
4607 let Inst{23-22} = 0b01;
4613 // Floating point conditional comparisons
4616 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4617 class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
4618 string mnemonic, list<dag> pat>
4619 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
4620 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
4621 Sched<[WriteFCmp]> {
4630 let Inst{31-24} = 0b00011110;
4632 let Inst{20-16} = Rm;
4633 let Inst{15-12} = cond;
4634 let Inst{11-10} = 0b01;
4636 let Inst{4} = signalAllNans;
4637 let Inst{3-0} = nzcv;
4640 multiclass FPCondComparison<bit signalAllNans, string mnemonic,
4641 SDPatternOperator OpNode = null_frag> {
4642 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic,
4643 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv),
4644 (i32 imm:$cond), NZCV))]> {
4645 let Inst{23-22} = 0b11;
4646 let Predicates = [HasFullFP16];
4649 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
4650 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
4651 (i32 imm:$cond), NZCV))]> {
4652 let Inst{23-22} = 0b00;
4655 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
4656 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
4657 (i32 imm:$cond), NZCV))]> {
4658 let Inst{23-22} = 0b01;
4663 // Floating point conditional select
4666 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
4667 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
4668 asm, "\t$Rd, $Rn, $Rm, $cond", "",
4670 (AArch64csel (vt regtype:$Rn), regtype:$Rm,
4671 (i32 imm:$cond), NZCV))]>,
4678 let Inst{31-24} = 0b00011110;
4680 let Inst{20-16} = Rm;
4681 let Inst{15-12} = cond;
4682 let Inst{11-10} = 0b11;
4687 multiclass FPCondSelect<string asm> {
4688 let Uses = [NZCV] in {
4689 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
4690 let Inst{23-22} = 0b11;
4691 let Predicates = [HasFullFP16];
4694 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
4695 let Inst{23-22} = 0b00;
4698 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
4699 let Inst{23-22} = 0b01;
4705 // Floating move immediate
4708 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
4709 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
4710 [(set regtype:$Rd, fpimmtype:$imm)]>,
4711 Sched<[WriteFImm]> {
4714 let Inst{31-24} = 0b00011110;
4716 let Inst{20-13} = imm;
4717 let Inst{12-5} = 0b10000000;
4721 multiclass FPMoveImmediate<string asm> {
4722 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
4723 let Inst{23-22} = 0b11;
4724 let Predicates = [HasFullFP16];
4727 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
4728 let Inst{23-22} = 0b00;
4731 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
4732 let Inst{23-22} = 0b01;
4735 } // end of 'let Predicates = [HasFPARMv8]'
4737 //----------------------------------------------------------------------------
4739 //----------------------------------------------------------------------------
4741 let Predicates = [HasNEON] in {
4743 //----------------------------------------------------------------------------
4744 // AdvSIMD three register vector instructions
4745 //----------------------------------------------------------------------------
4747 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4748 class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
4749 RegisterOperand regtype, string asm, string kind,
4751 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4752 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4753 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
4761 let Inst{28-24} = 0b01110;
4762 let Inst{23-21} = size;
4763 let Inst{20-16} = Rm;
4764 let Inst{15-11} = opcode;
4770 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4771 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
4772 RegisterOperand regtype, string asm, string kind,
4774 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
4775 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4776 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4784 let Inst{28-24} = 0b01110;
4785 let Inst{23-21} = size;
4786 let Inst{20-16} = Rm;
4787 let Inst{15-11} = opcode;
4793 class BaseSIMDThreeSameVectorDot<bit Q, bit U, string asm, string kind1,
4794 string kind2, RegisterOperand RegType,
4795 ValueType AccumType, ValueType InputType,
4796 SDPatternOperator OpNode> :
4797 BaseSIMDThreeSameVectorTied<Q, U, 0b100, 0b10010, RegType, asm, kind1,
4798 [(set (AccumType RegType:$dst),
4799 (OpNode (AccumType RegType:$Rd),
4800 (InputType RegType:$Rn),
4801 (InputType RegType:$Rm)))]> {
4802 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
4805 multiclass SIMDThreeSameVectorDot<bit U, string asm, SDPatternOperator OpNode> {
4806 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, asm, ".2s", ".8b", V64,
4807 v2i32, v8i8, OpNode>;
4808 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, asm, ".4s", ".16b", V128,
4809 v4i32, v16i8, OpNode>;
4812 // All operand sizes distinguished in the encoding.
4813 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
4814 SDPatternOperator OpNode> {
4815 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4817 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4818 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4820 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4821 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4823 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4824 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4826 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4827 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4829 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4830 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4832 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4833 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
4835 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4838 // As above, but D sized elements unsupported.
4839 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
4840 SDPatternOperator OpNode> {
4841 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4843 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
4844 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4846 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
4847 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4849 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
4850 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4852 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
4853 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4855 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
4856 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4858 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
4861 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
4862 SDPatternOperator OpNode> {
4863 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
4865 [(set (v8i8 V64:$dst),
4866 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4867 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
4869 [(set (v16i8 V128:$dst),
4870 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4871 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
4873 [(set (v4i16 V64:$dst),
4874 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4875 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
4877 [(set (v8i16 V128:$dst),
4878 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4879 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
4881 [(set (v2i32 V64:$dst),
4882 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4883 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
4885 [(set (v4i32 V128:$dst),
4886 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4889 // As above, but only B sized elements supported.
4890 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
4891 SDPatternOperator OpNode> {
4892 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4894 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4895 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4897 [(set (v16i8 V128:$Rd),
4898 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4901 // As above, but only floating point elements supported.
4902 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
4903 string asm, SDPatternOperator OpNode> {
4904 let Predicates = [HasNEON, HasFullFP16] in {
4905 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
4907 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4908 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
4910 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4911 } // Predicates = [HasNEON, HasFullFP16]
4912 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
4914 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4915 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
4917 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4918 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
4920 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4923 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
4925 SDPatternOperator OpNode> {
4926 let Predicates = [HasNEON, HasFullFP16] in {
4927 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
4929 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4930 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
4932 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4933 } // Predicates = [HasNEON, HasFullFP16]
4934 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
4936 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4937 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
4939 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4940 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
4942 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4945 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
4946 string asm, SDPatternOperator OpNode> {
4947 let Predicates = [HasNEON, HasFullFP16] in {
4948 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
4950 [(set (v4f16 V64:$dst),
4951 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4952 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
4954 [(set (v8f16 V128:$dst),
4955 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4956 } // Predicates = [HasNEON, HasFullFP16]
4957 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
4959 [(set (v2f32 V64:$dst),
4960 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4961 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
4963 [(set (v4f32 V128:$dst),
4964 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4965 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
4967 [(set (v2f64 V128:$dst),
4968 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4971 // As above, but D and B sized elements unsupported.
4972 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
4973 SDPatternOperator OpNode> {
4974 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4976 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4977 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4979 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4980 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4982 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4983 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4985 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4988 // Logical three vector ops share opcode bits, and only use B sized elements.
4989 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
4990 SDPatternOperator OpNode = null_frag> {
4991 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
4993 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
4994 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
4996 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
4998 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
4999 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5000 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
5001 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5002 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
5003 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5005 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
5006 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5007 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
5008 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5009 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
5010 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5013 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
5014 string asm, SDPatternOperator OpNode> {
5015 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
5017 [(set (v8i8 V64:$dst),
5018 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5019 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
5021 [(set (v16i8 V128:$dst),
5022 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
5023 (v16i8 V128:$Rm)))]>;
5025 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
5027 (!cast<Instruction>(NAME#"v8i8")
5028 V64:$LHS, V64:$MHS, V64:$RHS)>;
5029 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
5031 (!cast<Instruction>(NAME#"v8i8")
5032 V64:$LHS, V64:$MHS, V64:$RHS)>;
5033 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
5035 (!cast<Instruction>(NAME#"v8i8")
5036 V64:$LHS, V64:$MHS, V64:$RHS)>;
5038 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
5039 (v8i16 V128:$RHS))),
5040 (!cast<Instruction>(NAME#"v16i8")
5041 V128:$LHS, V128:$MHS, V128:$RHS)>;
5042 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
5043 (v4i32 V128:$RHS))),
5044 (!cast<Instruction>(NAME#"v16i8")
5045 V128:$LHS, V128:$MHS, V128:$RHS)>;
5046 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
5047 (v2i64 V128:$RHS))),
5048 (!cast<Instruction>(NAME#"v16i8")
5049 V128:$LHS, V128:$MHS, V128:$RHS)>;
5053 //----------------------------------------------------------------------------
5054 // AdvSIMD two register vector instructions.
5055 //----------------------------------------------------------------------------
5057 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5058 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5059 bits<2> size2, RegisterOperand regtype, string asm,
5060 string dstkind, string srckind, list<dag> pattern>
5061 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5062 "{\t$Rd" # dstkind # ", $Rn" # srckind #
5063 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
5070 let Inst{28-24} = 0b01110;
5071 let Inst{23-22} = size;
5073 let Inst{20-19} = size2;
5074 let Inst{18-17} = 0b00;
5075 let Inst{16-12} = opcode;
5076 let Inst{11-10} = 0b10;
5081 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5082 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5083 bits<2> size2, RegisterOperand regtype,
5084 string asm, string dstkind, string srckind,
5086 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
5087 "{\t$Rd" # dstkind # ", $Rn" # srckind #
5088 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
5095 let Inst{28-24} = 0b01110;
5096 let Inst{23-22} = size;
5098 let Inst{20-19} = size2;
5099 let Inst{18-17} = 0b00;
5100 let Inst{16-12} = opcode;
5101 let Inst{11-10} = 0b10;
5106 // Supports B, H, and S element sizes.
5107 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
5108 SDPatternOperator OpNode> {
5109 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5111 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5112 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5113 asm, ".16b", ".16b",
5114 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5115 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5117 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5118 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5120 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5121 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5123 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5124 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5126 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5129 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
5130 RegisterOperand regtype, string asm, string dstkind,
5131 string srckind, string amount>
5132 : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
5133 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
5134 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,
5140 let Inst{29-24} = 0b101110;
5141 let Inst{23-22} = size;
5142 let Inst{21-10} = 0b100001001110;
5147 multiclass SIMDVectorLShiftLongBySizeBHS {
5148 let hasSideEffects = 0 in {
5149 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
5150 "shll", ".8h", ".8b", "8">;
5151 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
5152 "shll2", ".8h", ".16b", "8">;
5153 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
5154 "shll", ".4s", ".4h", "16">;
5155 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
5156 "shll2", ".4s", ".8h", "16">;
5157 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
5158 "shll", ".2d", ".2s", "32">;
5159 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
5160 "shll2", ".2d", ".4s", "32">;
5164 // Supports all element sizes.
5165 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
5166 SDPatternOperator OpNode> {
5167 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5169 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5170 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5172 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5173 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5175 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5176 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5178 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5179 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5181 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5182 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5184 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5187 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
5188 SDPatternOperator OpNode> {
5189 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
5191 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
5193 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
5195 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
5196 (v16i8 V128:$Rn)))]>;
5197 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
5199 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
5200 (v4i16 V64:$Rn)))]>;
5201 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
5203 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
5204 (v8i16 V128:$Rn)))]>;
5205 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
5207 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
5208 (v2i32 V64:$Rn)))]>;
5209 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
5211 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
5212 (v4i32 V128:$Rn)))]>;
5215 // Supports all element sizes, except 1xD.
5216 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
5217 SDPatternOperator OpNode> {
5218 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
5220 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
5221 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
5222 asm, ".16b", ".16b",
5223 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
5224 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
5226 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
5227 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
5229 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
5230 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
5232 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
5233 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
5235 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
5236 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
5238 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
5241 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
5242 SDPatternOperator OpNode = null_frag> {
5243 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5245 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5246 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5247 asm, ".16b", ".16b",
5248 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5249 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5251 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5252 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5254 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5255 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5257 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5258 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5260 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5261 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
5263 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5267 // Supports only B element sizes.
5268 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
5269 SDPatternOperator OpNode> {
5270 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
5272 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5273 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
5274 asm, ".16b", ".16b",
5275 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5279 // Supports only B and H element sizes.
5280 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
5281 SDPatternOperator OpNode> {
5282 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5284 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
5285 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5286 asm, ".16b", ".16b",
5287 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
5288 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5290 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
5291 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5293 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
5296 // Supports only S and D element sizes, uses high bit of the size field
5297 // as an extra opcode bit.
5298 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
5299 SDPatternOperator OpNode> {
5300 let Predicates = [HasNEON, HasFullFP16] in {
5301 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5303 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5304 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5306 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5307 } // Predicates = [HasNEON, HasFullFP16]
5308 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5310 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5311 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5313 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5314 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5316 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5319 // Supports only S element size.
5320 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
5321 SDPatternOperator OpNode> {
5322 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5324 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5325 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5327 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5331 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
5332 SDPatternOperator OpNode> {
5333 let Predicates = [HasNEON, HasFullFP16] in {
5334 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5336 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5337 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5339 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5340 } // Predicates = [HasNEON, HasFullFP16]
5341 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5343 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5344 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5346 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5347 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5349 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5352 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
5353 SDPatternOperator OpNode> {
5354 let Predicates = [HasNEON, HasFullFP16] in {
5355 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5357 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5358 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5360 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5361 } // Predicates = [HasNEON, HasFullFP16]
5362 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5364 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5365 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5367 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5368 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5370 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5374 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5375 RegisterOperand inreg, RegisterOperand outreg,
5376 string asm, string outkind, string inkind,
5378 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
5379 "{\t$Rd" # outkind # ", $Rn" # inkind #
5380 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
5387 let Inst{28-24} = 0b01110;
5388 let Inst{23-22} = size;
5389 let Inst{21-17} = 0b10000;
5390 let Inst{16-12} = opcode;
5391 let Inst{11-10} = 0b10;
5396 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5397 RegisterOperand inreg, RegisterOperand outreg,
5398 string asm, string outkind, string inkind,
5400 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
5401 "{\t$Rd" # outkind # ", $Rn" # inkind #
5402 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
5409 let Inst{28-24} = 0b01110;
5410 let Inst{23-22} = size;
5411 let Inst{21-17} = 0b10000;
5412 let Inst{16-12} = opcode;
5413 let Inst{11-10} = 0b10;
5418 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
5419 SDPatternOperator OpNode> {
5420 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
5422 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5423 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
5424 asm#"2", ".16b", ".8h", []>;
5425 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
5427 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5428 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
5429 asm#"2", ".8h", ".4s", []>;
5430 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
5432 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5433 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
5434 asm#"2", ".4s", ".2d", []>;
5436 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
5437 (!cast<Instruction>(NAME # "v16i8")
5438 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5439 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
5440 (!cast<Instruction>(NAME # "v8i16")
5441 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5442 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
5443 (!cast<Instruction>(NAME # "v4i32")
5444 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5447 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
5448 bits<5> opcode, RegisterOperand regtype, string asm,
5449 string kind, string zero, ValueType dty,
5450 ValueType sty, SDNode OpNode>
5451 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5452 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
5453 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
5454 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
5461 let Inst{28-24} = 0b01110;
5462 let Inst{23-22} = size;
5464 let Inst{20-19} = size2;
5465 let Inst{18-17} = 0b00;
5466 let Inst{16-12} = opcode;
5467 let Inst{11-10} = 0b10;
5472 // Comparisons support all element sizes, except 1xD.
5473 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
5475 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
5477 v8i8, v8i8, OpNode>;
5478 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
5480 v16i8, v16i8, OpNode>;
5481 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
5483 v4i16, v4i16, OpNode>;
5484 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
5486 v8i16, v8i16, OpNode>;
5487 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
5489 v2i32, v2i32, OpNode>;
5490 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
5492 v4i32, v4i32, OpNode>;
5493 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
5495 v2i64, v2i64, OpNode>;
5498 // FP Comparisons support only S and D element sizes (and H for v8.2a).
5499 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
5500 string asm, SDNode OpNode> {
5502 let Predicates = [HasNEON, HasFullFP16] in {
5503 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
5505 v4i16, v4f16, OpNode>;
5506 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
5508 v8i16, v8f16, OpNode>;
5509 } // Predicates = [HasNEON, HasFullFP16]
5510 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
5512 v2i32, v2f32, OpNode>;
5513 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
5515 v4i32, v4f32, OpNode>;
5516 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
5518 v2i64, v2f64, OpNode>;
5520 let Predicates = [HasNEON, HasFullFP16] in {
5521 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
5522 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5523 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
5524 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5526 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
5527 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
5528 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
5529 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
5530 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
5531 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5532 let Predicates = [HasNEON, HasFullFP16] in {
5533 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
5534 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5535 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
5536 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5538 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
5539 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
5540 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
5541 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
5542 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
5543 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5546 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5547 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5548 RegisterOperand outtype, RegisterOperand intype,
5549 string asm, string VdTy, string VnTy,
5551 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
5552 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
5559 let Inst{28-24} = 0b01110;
5560 let Inst{23-22} = size;
5561 let Inst{21-17} = 0b10000;
5562 let Inst{16-12} = opcode;
5563 let Inst{11-10} = 0b10;
5568 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5569 RegisterOperand outtype, RegisterOperand intype,
5570 string asm, string VdTy, string VnTy,
5572 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
5573 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
5580 let Inst{28-24} = 0b01110;
5581 let Inst{23-22} = size;
5582 let Inst{21-17} = 0b10000;
5583 let Inst{16-12} = opcode;
5584 let Inst{11-10} = 0b10;
5589 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
5590 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
5591 asm, ".4s", ".4h", []>;
5592 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
5593 asm#"2", ".4s", ".8h", []>;
5594 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
5595 asm, ".2d", ".2s", []>;
5596 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
5597 asm#"2", ".2d", ".4s", []>;
5600 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
5601 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
5602 asm, ".4h", ".4s", []>;
5603 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
5604 asm#"2", ".8h", ".4s", []>;
5605 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5606 asm, ".2s", ".2d", []>;
5607 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5608 asm#"2", ".4s", ".2d", []>;
5611 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
5613 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5615 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5616 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5617 asm#"2", ".4s", ".2d", []>;
5619 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
5620 (!cast<Instruction>(NAME # "v4f32")
5621 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5624 //----------------------------------------------------------------------------
5625 // AdvSIMD three register different-size vector instructions.
5626 //----------------------------------------------------------------------------
5628 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5629 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
5630 RegisterOperand outtype, RegisterOperand intype1,
5631 RegisterOperand intype2, string asm,
5632 string outkind, string inkind1, string inkind2,
5634 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
5635 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5636 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
5642 let Inst{30} = size{0};
5644 let Inst{28-24} = 0b01110;
5645 let Inst{23-22} = size{2-1};
5647 let Inst{20-16} = Rm;
5648 let Inst{15-12} = opcode;
5649 let Inst{11-10} = 0b00;
5654 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5655 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
5656 RegisterOperand outtype, RegisterOperand intype1,
5657 RegisterOperand intype2, string asm,
5658 string outkind, string inkind1, string inkind2,
5660 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
5661 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5662 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
5668 let Inst{30} = size{0};
5670 let Inst{28-24} = 0b01110;
5671 let Inst{23-22} = size{2-1};
5673 let Inst{20-16} = Rm;
5674 let Inst{15-12} = opcode;
5675 let Inst{11-10} = 0b00;
5680 // FIXME: TableGen doesn't know how to deal with expanded types that also
5681 // change the element count (in this case, placing the results in
5682 // the high elements of the result register rather than the low
5683 // elements). Until that's fixed, we can't code-gen those.
5684 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
5686 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5688 asm, ".8b", ".8h", ".8h",
5689 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5690 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5692 asm#"2", ".16b", ".8h", ".8h",
5694 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5696 asm, ".4h", ".4s", ".4s",
5697 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5698 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5700 asm#"2", ".8h", ".4s", ".4s",
5702 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5704 asm, ".2s", ".2d", ".2d",
5705 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5706 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5708 asm#"2", ".4s", ".2d", ".2d",
5712 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
5713 // a version attached to an instruction.
5714 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
5716 (!cast<Instruction>(NAME # "v8i16_v16i8")
5717 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5718 V128:$Rn, V128:$Rm)>;
5719 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
5721 (!cast<Instruction>(NAME # "v4i32_v8i16")
5722 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5723 V128:$Rn, V128:$Rm)>;
5724 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
5726 (!cast<Instruction>(NAME # "v2i64_v4i32")
5727 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5728 V128:$Rn, V128:$Rm)>;
5731 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
5733 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5735 asm, ".8h", ".8b", ".8b",
5736 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5737 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5739 asm#"2", ".8h", ".16b", ".16b", []>;
5740 let Predicates = [HasAES] in {
5741 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
5743 asm, ".1q", ".1d", ".1d", []>;
5744 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
5746 asm#"2", ".1q", ".2d", ".2d", []>;
5749 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
5750 (v8i8 (extract_high_v16i8 V128:$Rm)))),
5751 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
5754 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
5755 SDPatternOperator OpNode> {
5756 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5758 asm, ".4s", ".4h", ".4h",
5759 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5760 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5762 asm#"2", ".4s", ".8h", ".8h",
5763 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5764 (extract_high_v8i16 V128:$Rm)))]>;
5765 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5767 asm, ".2d", ".2s", ".2s",
5768 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5769 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5771 asm#"2", ".2d", ".4s", ".4s",
5772 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5773 (extract_high_v4i32 V128:$Rm)))]>;
5776 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
5777 SDPatternOperator OpNode = null_frag> {
5778 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5780 asm, ".8h", ".8b", ".8b",
5781 [(set (v8i16 V128:$Rd),
5782 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
5783 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5785 asm#"2", ".8h", ".16b", ".16b",
5786 [(set (v8i16 V128:$Rd),
5787 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5788 (extract_high_v16i8 V128:$Rm)))))]>;
5789 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5791 asm, ".4s", ".4h", ".4h",
5792 [(set (v4i32 V128:$Rd),
5793 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
5794 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5796 asm#"2", ".4s", ".8h", ".8h",
5797 [(set (v4i32 V128:$Rd),
5798 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5799 (extract_high_v8i16 V128:$Rm)))))]>;
5800 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5802 asm, ".2d", ".2s", ".2s",
5803 [(set (v2i64 V128:$Rd),
5804 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
5805 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5807 asm#"2", ".2d", ".4s", ".4s",
5808 [(set (v2i64 V128:$Rd),
5809 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5810 (extract_high_v4i32 V128:$Rm)))))]>;
5813 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
5815 SDPatternOperator OpNode> {
5816 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5818 asm, ".8h", ".8b", ".8b",
5819 [(set (v8i16 V128:$dst),
5820 (add (v8i16 V128:$Rd),
5821 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
5822 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5824 asm#"2", ".8h", ".16b", ".16b",
5825 [(set (v8i16 V128:$dst),
5826 (add (v8i16 V128:$Rd),
5827 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5828 (extract_high_v16i8 V128:$Rm))))))]>;
5829 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5831 asm, ".4s", ".4h", ".4h",
5832 [(set (v4i32 V128:$dst),
5833 (add (v4i32 V128:$Rd),
5834 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
5835 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5837 asm#"2", ".4s", ".8h", ".8h",
5838 [(set (v4i32 V128:$dst),
5839 (add (v4i32 V128:$Rd),
5840 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5841 (extract_high_v8i16 V128:$Rm))))))]>;
5842 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5844 asm, ".2d", ".2s", ".2s",
5845 [(set (v2i64 V128:$dst),
5846 (add (v2i64 V128:$Rd),
5847 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
5848 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5850 asm#"2", ".2d", ".4s", ".4s",
5851 [(set (v2i64 V128:$dst),
5852 (add (v2i64 V128:$Rd),
5853 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5854 (extract_high_v4i32 V128:$Rm))))))]>;
5857 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
5858 SDPatternOperator OpNode = null_frag> {
5859 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5861 asm, ".8h", ".8b", ".8b",
5862 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5863 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5865 asm#"2", ".8h", ".16b", ".16b",
5866 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
5867 (extract_high_v16i8 V128:$Rm)))]>;
5868 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5870 asm, ".4s", ".4h", ".4h",
5871 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5872 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5874 asm#"2", ".4s", ".8h", ".8h",
5875 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5876 (extract_high_v8i16 V128:$Rm)))]>;
5877 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5879 asm, ".2d", ".2s", ".2s",
5880 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5881 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5883 asm#"2", ".2d", ".4s", ".4s",
5884 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5885 (extract_high_v4i32 V128:$Rm)))]>;
5888 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
5890 SDPatternOperator OpNode> {
5891 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5893 asm, ".8h", ".8b", ".8b",
5894 [(set (v8i16 V128:$dst),
5895 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5896 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5898 asm#"2", ".8h", ".16b", ".16b",
5899 [(set (v8i16 V128:$dst),
5900 (OpNode (v8i16 V128:$Rd),
5901 (extract_high_v16i8 V128:$Rn),
5902 (extract_high_v16i8 V128:$Rm)))]>;
5903 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5905 asm, ".4s", ".4h", ".4h",
5906 [(set (v4i32 V128:$dst),
5907 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5908 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5910 asm#"2", ".4s", ".8h", ".8h",
5911 [(set (v4i32 V128:$dst),
5912 (OpNode (v4i32 V128:$Rd),
5913 (extract_high_v8i16 V128:$Rn),
5914 (extract_high_v8i16 V128:$Rm)))]>;
5915 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5917 asm, ".2d", ".2s", ".2s",
5918 [(set (v2i64 V128:$dst),
5919 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5920 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5922 asm#"2", ".2d", ".4s", ".4s",
5923 [(set (v2i64 V128:$dst),
5924 (OpNode (v2i64 V128:$Rd),
5925 (extract_high_v4i32 V128:$Rn),
5926 (extract_high_v4i32 V128:$Rm)))]>;
5929 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
5930 SDPatternOperator Accum> {
5931 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5933 asm, ".4s", ".4h", ".4h",
5934 [(set (v4i32 V128:$dst),
5935 (Accum (v4i32 V128:$Rd),
5936 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
5937 (v4i16 V64:$Rm)))))]>;
5938 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5940 asm#"2", ".4s", ".8h", ".8h",
5941 [(set (v4i32 V128:$dst),
5942 (Accum (v4i32 V128:$Rd),
5943 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
5944 (extract_high_v8i16 V128:$Rm)))))]>;
5945 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5947 asm, ".2d", ".2s", ".2s",
5948 [(set (v2i64 V128:$dst),
5949 (Accum (v2i64 V128:$Rd),
5950 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
5951 (v2i32 V64:$Rm)))))]>;
5952 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5954 asm#"2", ".2d", ".4s", ".4s",
5955 [(set (v2i64 V128:$dst),
5956 (Accum (v2i64 V128:$Rd),
5957 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
5958 (extract_high_v4i32 V128:$Rm)))))]>;
5961 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
5962 SDPatternOperator OpNode> {
5963 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5965 asm, ".8h", ".8h", ".8b",
5966 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
5967 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5969 asm#"2", ".8h", ".8h", ".16b",
5970 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
5971 (extract_high_v16i8 V128:$Rm)))]>;
5972 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5974 asm, ".4s", ".4s", ".4h",
5975 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
5976 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5978 asm#"2", ".4s", ".4s", ".8h",
5979 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
5980 (extract_high_v8i16 V128:$Rm)))]>;
5981 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5983 asm, ".2d", ".2d", ".2s",
5984 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
5985 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5987 asm#"2", ".2d", ".2d", ".4s",
5988 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
5989 (extract_high_v4i32 V128:$Rm)))]>;
5992 //----------------------------------------------------------------------------
5993 // AdvSIMD bitwise extract from vector
5994 //----------------------------------------------------------------------------
5996 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
5997 string asm, string kind>
5998 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
5999 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
6000 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
6001 [(set (vty regtype:$Rd),
6002 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
6009 let Inst{30} = size;
6010 let Inst{29-21} = 0b101110000;
6011 let Inst{20-16} = Rm;
6013 let Inst{14-11} = imm;
6020 multiclass SIMDBitwiseExtract<string asm> {
6021 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
6024 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
6027 //----------------------------------------------------------------------------
6028 // AdvSIMD zip vector
6029 //----------------------------------------------------------------------------
6031 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
6032 string asm, string kind, SDNode OpNode, ValueType valty>
6033 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
6034 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
6035 "|" # kind # "\t$Rd, $Rn, $Rm}", "",
6036 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
6042 let Inst{30} = size{0};
6043 let Inst{29-24} = 0b001110;
6044 let Inst{23-22} = size{2-1};
6046 let Inst{20-16} = Rm;
6048 let Inst{14-12} = opc;
6049 let Inst{11-10} = 0b10;
6054 multiclass SIMDZipVector<bits<3>opc, string asm,
6056 def v8i8 : BaseSIMDZipVector<0b000, opc, V64,
6057 asm, ".8b", OpNode, v8i8>;
6058 def v16i8 : BaseSIMDZipVector<0b001, opc, V128,
6059 asm, ".16b", OpNode, v16i8>;
6060 def v4i16 : BaseSIMDZipVector<0b010, opc, V64,
6061 asm, ".4h", OpNode, v4i16>;
6062 def v8i16 : BaseSIMDZipVector<0b011, opc, V128,
6063 asm, ".8h", OpNode, v8i16>;
6064 def v2i32 : BaseSIMDZipVector<0b100, opc, V64,
6065 asm, ".2s", OpNode, v2i32>;
6066 def v4i32 : BaseSIMDZipVector<0b101, opc, V128,
6067 asm, ".4s", OpNode, v4i32>;
6068 def v2i64 : BaseSIMDZipVector<0b111, opc, V128,
6069 asm, ".2d", OpNode, v2i64>;
6071 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
6072 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
6073 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
6074 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
6075 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
6076 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
6077 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
6078 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
6079 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
6080 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
6083 //----------------------------------------------------------------------------
6084 // AdvSIMD three register scalar instructions
6085 //----------------------------------------------------------------------------
6087 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6088 class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
6089 RegisterClass regtype, string asm,
6091 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
6092 "\t$Rd, $Rn, $Rm", "", pattern>,
6097 let Inst{31-30} = 0b01;
6099 let Inst{28-24} = 0b11110;
6100 let Inst{23-21} = size;
6101 let Inst{20-16} = Rm;
6102 let Inst{15-11} = opcode;
6108 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6109 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
6110 dag oops, dag iops, string asm,
6112 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
6117 let Inst{31-30} = 0b01;
6119 let Inst{28-24} = 0b11110;
6120 let Inst{23-22} = size;
6122 let Inst{20-16} = Rm;
6123 let Inst{15-11} = opcode;
6129 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
6130 SDPatternOperator OpNode> {
6131 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
6132 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
6135 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
6136 SDPatternOperator OpNode> {
6137 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
6138 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
6139 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
6140 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
6141 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
6143 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
6144 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
6145 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
6146 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
6149 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
6150 SDPatternOperator OpNode> {
6151 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
6152 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
6153 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
6156 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
6157 SDPatternOperator OpNode = null_frag> {
6158 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
6159 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
6161 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
6162 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
6166 multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
6167 SDPatternOperator OpNode = null_frag> {
6168 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6169 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
6170 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
6171 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
6172 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
6173 let Predicates = [HasNEON, HasFullFP16] in {
6174 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
6175 [(set FPR16:$Rd, (OpNode FPR16:$Rn, FPR16:$Rm))]>;
6176 } // Predicates = [HasNEON, HasFullFP16]
6179 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
6180 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
6183 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
6184 SDPatternOperator OpNode = null_frag> {
6185 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6186 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
6187 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
6188 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
6189 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
6190 let Predicates = [HasNEON, HasFullFP16] in {
6191 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
6193 } // Predicates = [HasNEON, HasFullFP16]
6196 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
6197 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
6200 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
6201 dag oops, dag iops, string asm, string cstr, list<dag> pat>
6202 : I<oops, iops, asm,
6203 "\t$Rd, $Rn, $Rm", cstr, pat>,
6208 let Inst{31-30} = 0b01;
6210 let Inst{28-24} = 0b11110;
6211 let Inst{23-22} = size;
6213 let Inst{20-16} = Rm;
6214 let Inst{15-11} = opcode;
6220 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6221 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
6222 SDPatternOperator OpNode = null_frag> {
6223 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
6225 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
6226 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
6228 (ins FPR32:$Rn, FPR32:$Rm), asm, "",
6229 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
6232 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6233 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
6234 SDPatternOperator OpNode = null_frag> {
6235 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
6237 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
6238 asm, "$Rd = $dst", []>;
6239 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
6241 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
6243 [(set (i64 FPR64:$dst),
6244 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
6247 //----------------------------------------------------------------------------
6248 // AdvSIMD two register scalar instructions
6249 //----------------------------------------------------------------------------
6251 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6252 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6253 RegisterClass regtype, RegisterClass regtype2,
6254 string asm, list<dag> pat>
6255 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
6256 "\t$Rd, $Rn", "", pat>,
6260 let Inst{31-30} = 0b01;
6262 let Inst{28-24} = 0b11110;
6263 let Inst{23-22} = size;
6265 let Inst{20-19} = size2;
6266 let Inst{18-17} = 0b00;
6267 let Inst{16-12} = opcode;
6268 let Inst{11-10} = 0b10;
6273 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6274 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
6275 RegisterClass regtype, RegisterClass regtype2,
6276 string asm, list<dag> pat>
6277 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
6278 "\t$Rd, $Rn", "$Rd = $dst", pat>,
6282 let Inst{31-30} = 0b01;
6284 let Inst{28-24} = 0b11110;
6285 let Inst{23-22} = size;
6286 let Inst{21-17} = 0b10000;
6287 let Inst{16-12} = opcode;
6288 let Inst{11-10} = 0b10;
6294 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6295 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6296 RegisterClass regtype, string asm, string zero>
6297 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
6298 "\t$Rd, $Rn, #" # zero, "", []>,
6302 let Inst{31-30} = 0b01;
6304 let Inst{28-24} = 0b11110;
6305 let Inst{23-22} = size;
6307 let Inst{20-19} = size2;
6308 let Inst{18-17} = 0b00;
6309 let Inst{16-12} = opcode;
6310 let Inst{11-10} = 0b10;
6315 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
6316 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
6317 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
6321 let Inst{31-17} = 0b011111100110000;
6322 let Inst{16-12} = opcode;
6323 let Inst{11-10} = 0b10;
6328 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
6329 SDPatternOperator OpNode> {
6330 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
6332 def : Pat<(v1i64 (OpNode FPR64:$Rn)),
6333 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6336 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
6337 SDPatternOperator OpNode> {
6338 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
6339 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
6340 let Predicates = [HasNEON, HasFullFP16] in {
6341 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
6344 def : InstAlias<asm # "\t$Rd, $Rn, #0",
6345 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
6346 def : InstAlias<asm # "\t$Rd, $Rn, #0",
6347 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
6348 let Predicates = [HasNEON, HasFullFP16] in {
6349 def : InstAlias<asm # "\t$Rd, $Rn, #0",
6350 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
6353 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
6354 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6357 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
6358 SDPatternOperator OpNode = null_frag> {
6359 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
6360 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
6362 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
6363 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
6366 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
6367 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
6368 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
6369 let Predicates = [HasNEON, HasFullFP16] in {
6370 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
6374 multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
6375 SDPatternOperator OpNode> {
6376 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
6377 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
6378 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
6379 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
6380 let Predicates = [HasNEON, HasFullFP16] in {
6381 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
6382 [(set FPR16:$Rd, (OpNode (f16 FPR16:$Rn)))]>;
6386 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
6387 SDPatternOperator OpNode = null_frag> {
6388 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6389 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
6390 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
6391 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
6392 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
6393 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
6394 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
6397 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
6398 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
6401 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
6403 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6404 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
6405 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
6406 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
6407 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
6408 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
6409 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
6412 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
6413 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
6418 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6419 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
6420 SDPatternOperator OpNode = null_frag> {
6421 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
6422 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
6423 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
6424 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
6427 //----------------------------------------------------------------------------
6428 // AdvSIMD scalar pairwise instructions
6429 //----------------------------------------------------------------------------
6431 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6432 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
6433 RegisterOperand regtype, RegisterOperand vectype,
6434 string asm, string kind>
6435 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6436 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
6440 let Inst{31-30} = 0b01;
6442 let Inst{28-24} = 0b11110;
6443 let Inst{23-22} = size;
6444 let Inst{21-17} = 0b11000;
6445 let Inst{16-12} = opcode;
6446 let Inst{11-10} = 0b10;
6451 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
6452 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
6456 multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
6457 let Predicates = [HasNEON, HasFullFP16] in {
6458 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
6461 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
6463 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
6467 //----------------------------------------------------------------------------
6468 // AdvSIMD across lanes instructions
6469 //----------------------------------------------------------------------------
6471 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6472 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
6473 RegisterClass regtype, RegisterOperand vectype,
6474 string asm, string kind, list<dag> pattern>
6475 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6476 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
6483 let Inst{28-24} = 0b01110;
6484 let Inst{23-22} = size;
6485 let Inst{21-17} = 0b11000;
6486 let Inst{16-12} = opcode;
6487 let Inst{11-10} = 0b10;
6492 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
6494 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
6496 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
6498 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
6500 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
6502 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
6506 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
6507 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
6509 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
6511 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
6513 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
6515 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
6519 multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
6521 let Predicates = [HasNEON, HasFullFP16] in {
6522 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
6524 [(set FPR16:$Rd, (intOp (v4f16 V64:$Rn)))]>;
6525 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
6527 [(set FPR16:$Rd, (intOp (v8f16 V128:$Rn)))]>;
6528 } // Predicates = [HasNEON, HasFullFP16]
6529 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
6531 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
6534 //----------------------------------------------------------------------------
6535 // AdvSIMD INS/DUP instructions
6536 //----------------------------------------------------------------------------
6538 // FIXME: There has got to be a better way to factor these. ugh.
6540 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
6541 string operands, string constraints, list<dag> pattern>
6542 : I<outs, ins, asm, operands, constraints, pattern>,
6549 let Inst{28-21} = 0b01110000;
6556 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
6557 RegisterOperand vecreg, RegisterClass regtype>
6558 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
6559 "{\t$Rd" # size # ", $Rn" #
6560 "|" # size # "\t$Rd, $Rn}", "",
6561 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
6562 let Inst{20-16} = imm5;
6563 let Inst{14-11} = 0b0001;
6566 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
6567 ValueType vectype, ValueType insreg,
6568 RegisterOperand vecreg, Operand idxtype,
6569 ValueType elttype, SDNode OpNode>
6570 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
6571 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
6572 "|" # dstkind # "\t$Rd, $Rn$idx}", "",
6573 [(set (vectype vecreg:$Rd),
6574 (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
6575 let Inst{14-11} = 0b0000;
6578 class SIMDDup64FromElement
6579 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
6580 VectorIndexD, i64, AArch64duplane64> {
6583 let Inst{19-16} = 0b1000;
6586 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
6587 RegisterOperand vecreg>
6588 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
6589 VectorIndexS, i64, AArch64duplane32> {
6591 let Inst{20-19} = idx;
6592 let Inst{18-16} = 0b100;
6595 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
6596 RegisterOperand vecreg>
6597 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
6598 VectorIndexH, i64, AArch64duplane16> {
6600 let Inst{20-18} = idx;
6601 let Inst{17-16} = 0b10;
6604 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
6605 RegisterOperand vecreg>
6606 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
6607 VectorIndexB, i64, AArch64duplane8> {
6609 let Inst{20-17} = idx;
6613 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
6614 Operand idxtype, string asm, list<dag> pattern>
6615 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
6616 "{\t$Rd, $Rn" # size # "$idx" #
6617 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
6618 let Inst{14-11} = imm4;
6621 class SIMDSMov<bit Q, string size, RegisterClass regtype,
6623 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
6624 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
6626 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
6627 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
6629 class SIMDMovAlias<string asm, string size, Instruction inst,
6630 RegisterClass regtype, Operand idxtype>
6631 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
6632 "|" # size # "\t$dst, $src$idx}",
6633 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
6636 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
6638 let Inst{20-17} = idx;
6641 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
6643 let Inst{20-17} = idx;
6646 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
6648 let Inst{20-18} = idx;
6649 let Inst{17-16} = 0b10;
6651 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
6653 let Inst{20-18} = idx;
6654 let Inst{17-16} = 0b10;
6656 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
6658 let Inst{20-19} = idx;
6659 let Inst{18-16} = 0b100;
6664 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
6666 let Inst{20-17} = idx;
6669 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
6671 let Inst{20-18} = idx;
6672 let Inst{17-16} = 0b10;
6674 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
6676 let Inst{20-19} = idx;
6677 let Inst{18-16} = 0b100;
6679 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
6682 let Inst{19-16} = 0b1000;
6684 def : SIMDMovAlias<"mov", ".s",
6685 !cast<Instruction>(NAME#"vi32"),
6686 GPR32, VectorIndexS>;
6687 def : SIMDMovAlias<"mov", ".d",
6688 !cast<Instruction>(NAME#"vi64"),
6689 GPR64, VectorIndexD>;
6692 class SIMDInsFromMain<string size, ValueType vectype,
6693 RegisterClass regtype, Operand idxtype>
6694 : BaseSIMDInsDup<1, 0, (outs V128:$dst),
6695 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
6696 "{\t$Rd" # size # "$idx, $Rn" #
6697 "|" # size # "\t$Rd$idx, $Rn}",
6700 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
6701 let Inst{14-11} = 0b0011;
6704 class SIMDInsFromElement<string size, ValueType vectype,
6705 ValueType elttype, Operand idxtype>
6706 : BaseSIMDInsDup<1, 1, (outs V128:$dst),
6707 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
6708 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
6709 "|" # size # "\t$Rd$idx, $Rn$idx2}",
6714 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
6717 class SIMDInsMainMovAlias<string size, Instruction inst,
6718 RegisterClass regtype, Operand idxtype>
6719 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
6720 "|" # size #"\t$dst$idx, $src}",
6721 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
6722 class SIMDInsElementMovAlias<string size, Instruction inst,
6724 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
6725 # "|" # size #"\t$dst$idx, $src$idx2}",
6726 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
6729 multiclass SIMDIns {
6730 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
6732 let Inst{20-17} = idx;
6735 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
6737 let Inst{20-18} = idx;
6738 let Inst{17-16} = 0b10;
6740 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
6742 let Inst{20-19} = idx;
6743 let Inst{18-16} = 0b100;
6745 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
6748 let Inst{19-16} = 0b1000;
6751 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
6754 let Inst{20-17} = idx;
6756 let Inst{14-11} = idx2;
6758 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
6761 let Inst{20-18} = idx;
6762 let Inst{17-16} = 0b10;
6763 let Inst{14-12} = idx2;
6766 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
6769 let Inst{20-19} = idx;
6770 let Inst{18-16} = 0b100;
6771 let Inst{14-13} = idx2;
6772 let Inst{12-11} = {?,?};
6774 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
6778 let Inst{19-16} = 0b1000;
6779 let Inst{14} = idx2;
6780 let Inst{13-11} = {?,?,?};
6783 // For all forms of the INS instruction, the "mov" mnemonic is the
6784 // preferred alias. Why they didn't just call the instruction "mov" in
6785 // the first place is a very good question indeed...
6786 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
6787 GPR32, VectorIndexB>;
6788 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
6789 GPR32, VectorIndexH>;
6790 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
6791 GPR32, VectorIndexS>;
6792 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
6793 GPR64, VectorIndexD>;
6795 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
6797 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
6799 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
6801 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
6805 //----------------------------------------------------------------------------
6807 //----------------------------------------------------------------------------
6809 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6810 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6811 RegisterOperand listtype, string asm, string kind>
6812 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
6813 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
6820 let Inst{29-21} = 0b001110000;
6821 let Inst{20-16} = Vm;
6823 let Inst{14-13} = len;
6825 let Inst{11-10} = 0b00;
6830 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6831 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6832 RegisterOperand listtype, string asm, string kind>
6833 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
6834 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
6841 let Inst{29-21} = 0b001110000;
6842 let Inst{20-16} = Vm;
6844 let Inst{14-13} = len;
6846 let Inst{11-10} = 0b00;
6851 class SIMDTableLookupAlias<string asm, Instruction inst,
6852 RegisterOperand vectype, RegisterOperand listtype>
6853 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
6854 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
6856 multiclass SIMDTableLookup<bit op, string asm> {
6857 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
6859 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
6861 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
6863 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
6865 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
6867 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
6869 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
6871 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
6874 def : SIMDTableLookupAlias<asm # ".8b",
6875 !cast<Instruction>(NAME#"v8i8One"),
6876 V64, VecListOne128>;
6877 def : SIMDTableLookupAlias<asm # ".8b",
6878 !cast<Instruction>(NAME#"v8i8Two"),
6879 V64, VecListTwo128>;
6880 def : SIMDTableLookupAlias<asm # ".8b",
6881 !cast<Instruction>(NAME#"v8i8Three"),
6882 V64, VecListThree128>;
6883 def : SIMDTableLookupAlias<asm # ".8b",
6884 !cast<Instruction>(NAME#"v8i8Four"),
6885 V64, VecListFour128>;
6886 def : SIMDTableLookupAlias<asm # ".16b",
6887 !cast<Instruction>(NAME#"v16i8One"),
6888 V128, VecListOne128>;
6889 def : SIMDTableLookupAlias<asm # ".16b",
6890 !cast<Instruction>(NAME#"v16i8Two"),
6891 V128, VecListTwo128>;
6892 def : SIMDTableLookupAlias<asm # ".16b",
6893 !cast<Instruction>(NAME#"v16i8Three"),
6894 V128, VecListThree128>;
6895 def : SIMDTableLookupAlias<asm # ".16b",
6896 !cast<Instruction>(NAME#"v16i8Four"),
6897 V128, VecListFour128>;
6900 multiclass SIMDTableLookupTied<bit op, string asm> {
6901 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
6903 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
6905 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
6907 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
6909 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
6911 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
6913 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
6915 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
6918 def : SIMDTableLookupAlias<asm # ".8b",
6919 !cast<Instruction>(NAME#"v8i8One"),
6920 V64, VecListOne128>;
6921 def : SIMDTableLookupAlias<asm # ".8b",
6922 !cast<Instruction>(NAME#"v8i8Two"),
6923 V64, VecListTwo128>;
6924 def : SIMDTableLookupAlias<asm # ".8b",
6925 !cast<Instruction>(NAME#"v8i8Three"),
6926 V64, VecListThree128>;
6927 def : SIMDTableLookupAlias<asm # ".8b",
6928 !cast<Instruction>(NAME#"v8i8Four"),
6929 V64, VecListFour128>;
6930 def : SIMDTableLookupAlias<asm # ".16b",
6931 !cast<Instruction>(NAME#"v16i8One"),
6932 V128, VecListOne128>;
6933 def : SIMDTableLookupAlias<asm # ".16b",
6934 !cast<Instruction>(NAME#"v16i8Two"),
6935 V128, VecListTwo128>;
6936 def : SIMDTableLookupAlias<asm # ".16b",
6937 !cast<Instruction>(NAME#"v16i8Three"),
6938 V128, VecListThree128>;
6939 def : SIMDTableLookupAlias<asm # ".16b",
6940 !cast<Instruction>(NAME#"v16i8Four"),
6941 V128, VecListFour128>;
6945 //----------------------------------------------------------------------------
6946 // AdvSIMD scalar CPY
6947 //----------------------------------------------------------------------------
6948 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6949 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
6950 string kind, Operand idxtype>
6951 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
6952 "{\t$dst, $src" # kind # "$idx" #
6953 "|\t$dst, $src$idx}", "", []>,
6957 let Inst{31-21} = 0b01011110000;
6958 let Inst{15-10} = 0b000001;
6959 let Inst{9-5} = src;
6960 let Inst{4-0} = dst;
6963 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
6964 RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
6965 : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
6966 # "|\t$dst, $src$index}",
6967 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
6970 multiclass SIMDScalarCPY<string asm> {
6971 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> {
6973 let Inst{20-17} = idx;
6976 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
6978 let Inst{20-18} = idx;
6979 let Inst{17-16} = 0b10;
6981 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
6983 let Inst{20-19} = idx;
6984 let Inst{18-16} = 0b100;
6986 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
6989 let Inst{19-16} = 0b1000;
6992 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
6993 VectorIndexD:$idx)))),
6994 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
6996 // 'DUP' mnemonic aliases.
6997 def : SIMDScalarCPYAlias<"dup", ".b",
6998 !cast<Instruction>(NAME#"i8"),
6999 FPR8, V128, VectorIndexB>;
7000 def : SIMDScalarCPYAlias<"dup", ".h",
7001 !cast<Instruction>(NAME#"i16"),
7002 FPR16, V128, VectorIndexH>;
7003 def : SIMDScalarCPYAlias<"dup", ".s",
7004 !cast<Instruction>(NAME#"i32"),
7005 FPR32, V128, VectorIndexS>;
7006 def : SIMDScalarCPYAlias<"dup", ".d",
7007 !cast<Instruction>(NAME#"i64"),
7008 FPR64, V128, VectorIndexD>;
7011 //----------------------------------------------------------------------------
7012 // AdvSIMD modified immediate instructions
7013 //----------------------------------------------------------------------------
7015 class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
7016 string asm, string op_string,
7017 string cstr, list<dag> pattern>
7018 : I<oops, iops, asm, op_string, cstr, pattern>,
7025 let Inst{28-19} = 0b0111100000;
7026 let Inst{18-16} = imm8{7-5};
7029 let Inst{9-5} = imm8{4-0};
7033 class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
7034 Operand immtype, dag opt_shift_iop,
7035 string opt_shift, string asm, string kind,
7037 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
7038 !con((ins immtype:$imm8), opt_shift_iop), asm,
7039 "{\t$Rd" # kind # ", $imm8" # opt_shift #
7040 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
7042 let DecoderMethod = "DecodeModImmInstruction";
7045 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
7046 Operand immtype, dag opt_shift_iop,
7047 string opt_shift, string asm, string kind,
7049 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
7050 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
7051 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
7052 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
7053 "$Rd = $dst", pattern> {
7054 let DecoderMethod = "DecodeModImmTiedInstruction";
7057 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
7058 RegisterOperand vectype, string asm,
7059 string kind, list<dag> pattern>
7060 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7061 (ins logical_vec_shift:$shift),
7062 "$shift", asm, kind, pattern> {
7064 let Inst{15} = b15_b12{1};
7065 let Inst{14-13} = shift;
7066 let Inst{12} = b15_b12{0};
7069 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
7070 RegisterOperand vectype, string asm,
7071 string kind, list<dag> pattern>
7072 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
7073 (ins logical_vec_shift:$shift),
7074 "$shift", asm, kind, pattern> {
7076 let Inst{15} = b15_b12{1};
7077 let Inst{14-13} = shift;
7078 let Inst{12} = b15_b12{0};
7082 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
7083 RegisterOperand vectype, string asm,
7084 string kind, list<dag> pattern>
7085 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7086 (ins logical_vec_hw_shift:$shift),
7087 "$shift", asm, kind, pattern> {
7089 let Inst{15} = b15_b12{1};
7091 let Inst{13} = shift{0};
7092 let Inst{12} = b15_b12{0};
7095 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
7096 RegisterOperand vectype, string asm,
7097 string kind, list<dag> pattern>
7098 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
7099 (ins logical_vec_hw_shift:$shift),
7100 "$shift", asm, kind, pattern> {
7102 let Inst{15} = b15_b12{1};
7104 let Inst{13} = shift{0};
7105 let Inst{12} = b15_b12{0};
7108 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
7110 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
7112 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
7115 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
7117 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
7121 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
7122 bits<2> w_cmode, string asm,
7124 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
7126 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
7128 (i32 imm:$shift)))]>;
7129 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
7131 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
7133 (i32 imm:$shift)))]>;
7135 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
7137 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
7139 (i32 imm:$shift)))]>;
7140 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
7142 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
7144 (i32 imm:$shift)))]>;
7147 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
7148 RegisterOperand vectype, string asm,
7149 string kind, list<dag> pattern>
7150 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7151 (ins move_vec_shift:$shift),
7152 "$shift", asm, kind, pattern> {
7154 let Inst{15-13} = cmode{3-1};
7155 let Inst{12} = shift;
7158 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
7159 RegisterOperand vectype,
7160 Operand imm_type, string asm,
7161 string kind, list<dag> pattern>
7162 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
7163 asm, kind, pattern> {
7164 let Inst{15-12} = cmode;
7167 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
7169 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
7170 "\t$Rd, $imm8", "", pattern> {
7171 let Inst{15-12} = cmode;
7172 let DecoderMethod = "DecodeModImmInstruction";
7175 //----------------------------------------------------------------------------
7176 // AdvSIMD indexed element
7177 //----------------------------------------------------------------------------
7179 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7180 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
7181 RegisterOperand dst_reg, RegisterOperand lhs_reg,
7182 RegisterOperand rhs_reg, Operand vec_idx, string asm,
7183 string apple_kind, string dst_kind, string lhs_kind,
7184 string rhs_kind, list<dag> pattern>
7185 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
7187 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
7188 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
7197 let Inst{28} = Scalar;
7198 let Inst{27-24} = 0b1111;
7199 let Inst{23-22} = size;
7200 // Bit 21 must be set by the derived class.
7201 let Inst{20-16} = Rm;
7202 let Inst{15-12} = opc;
7203 // Bit 11 must be set by the derived class.
7209 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7210 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
7211 RegisterOperand dst_reg, RegisterOperand lhs_reg,
7212 RegisterOperand rhs_reg, Operand vec_idx, string asm,
7213 string apple_kind, string dst_kind, string lhs_kind,
7214 string rhs_kind, list<dag> pattern>
7215 : I<(outs dst_reg:$dst),
7216 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
7217 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
7218 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
7227 let Inst{28} = Scalar;
7228 let Inst{27-24} = 0b1111;
7229 let Inst{23-22} = size;
7230 // Bit 21 must be set by the derived class.
7231 let Inst{20-16} = Rm;
7232 let Inst{15-12} = opc;
7233 // Bit 11 must be set by the derived class.
7239 // ARMv8.2 Index Dot product instructions
7240 class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, string asm, string dst_kind,
7241 string lhs_kind, string rhs_kind,
7242 RegisterOperand RegType,
7243 ValueType AccumType, ValueType InputType,
7244 SDPatternOperator OpNode> :
7245 BaseSIMDIndexedTied<Q, U, 0b0, 0b10, 0b1110, RegType, RegType, V128,
7246 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind,
7247 [(set (AccumType RegType:$dst),
7248 (AccumType (OpNode (AccumType RegType:$Rd),
7249 (InputType RegType:$Rn),
7250 (InputType (bitconvert (AccumType
7251 (AArch64duplane32 (v4i32 V128:$Rm),
7252 VectorIndexS:$idx)))))))]> {
7254 let Inst{21} = idx{0}; // L
7255 let Inst{11} = idx{1}; // H
7258 multiclass SIMDThreeSameVectorDotIndex<bit U, string asm,
7259 SDPatternOperator OpNode> {
7260 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, asm, ".2s", ".8b", ".4b", V64,
7261 v2i32, v8i8, OpNode>;
7262 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, asm, ".4s", ".16b", ".4b", V128,
7263 v4i32, v16i8, OpNode>;
7266 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
7267 SDPatternOperator OpNode> {
7268 let Predicates = [HasNEON, HasFullFP16] in {
7269 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
7271 V128_lo, VectorIndexH,
7272 asm, ".4h", ".4h", ".4h", ".h",
7273 [(set (v4f16 V64:$Rd),
7274 (OpNode (v4f16 V64:$Rn),
7275 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7277 let Inst{11} = idx{2};
7278 let Inst{21} = idx{1};
7279 let Inst{20} = idx{0};
7282 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
7284 V128_lo, VectorIndexH,
7285 asm, ".8h", ".8h", ".8h", ".h",
7286 [(set (v8f16 V128:$Rd),
7287 (OpNode (v8f16 V128:$Rn),
7288 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7290 let Inst{11} = idx{2};
7291 let Inst{21} = idx{1};
7292 let Inst{20} = idx{0};
7294 } // Predicates = [HasNEON, HasFullFP16]
7296 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7299 asm, ".2s", ".2s", ".2s", ".s",
7300 [(set (v2f32 V64:$Rd),
7301 (OpNode (v2f32 V64:$Rn),
7302 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
7304 let Inst{11} = idx{1};
7305 let Inst{21} = idx{0};
7308 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7311 asm, ".4s", ".4s", ".4s", ".s",
7312 [(set (v4f32 V128:$Rd),
7313 (OpNode (v4f32 V128:$Rn),
7314 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
7316 let Inst{11} = idx{1};
7317 let Inst{21} = idx{0};
7320 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
7323 asm, ".2d", ".2d", ".2d", ".d",
7324 [(set (v2f64 V128:$Rd),
7325 (OpNode (v2f64 V128:$Rn),
7326 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
7328 let Inst{11} = idx{0};
7332 let Predicates = [HasNEON, HasFullFP16] in {
7333 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
7334 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7335 asm, ".h", "", "", ".h",
7336 [(set (f16 FPR16Op:$Rd),
7337 (OpNode (f16 FPR16Op:$Rn),
7338 (f16 (vector_extract (v8f16 V128_lo:$Rm),
7339 VectorIndexH:$idx))))]> {
7341 let Inst{11} = idx{2};
7342 let Inst{21} = idx{1};
7343 let Inst{20} = idx{0};
7345 } // Predicates = [HasNEON, HasFullFP16]
7347 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7348 FPR32Op, FPR32Op, V128, VectorIndexS,
7349 asm, ".s", "", "", ".s",
7350 [(set (f32 FPR32Op:$Rd),
7351 (OpNode (f32 FPR32Op:$Rn),
7352 (f32 (vector_extract (v4f32 V128:$Rm),
7353 VectorIndexS:$idx))))]> {
7355 let Inst{11} = idx{1};
7356 let Inst{21} = idx{0};
7359 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
7360 FPR64Op, FPR64Op, V128, VectorIndexD,
7361 asm, ".d", "", "", ".d",
7362 [(set (f64 FPR64Op:$Rd),
7363 (OpNode (f64 FPR64Op:$Rn),
7364 (f64 (vector_extract (v2f64 V128:$Rm),
7365 VectorIndexD:$idx))))]> {
7367 let Inst{11} = idx{0};
7372 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
7373 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
7374 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
7375 (AArch64duplane32 (v4f32 V128:$Rm),
7376 VectorIndexS:$idx))),
7377 (!cast<Instruction>(INST # v2i32_indexed)
7378 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7379 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
7380 (AArch64dup (f32 FPR32Op:$Rm)))),
7381 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
7382 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
7385 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
7386 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
7387 (AArch64duplane32 (v4f32 V128:$Rm),
7388 VectorIndexS:$idx))),
7389 (!cast<Instruction>(INST # "v4i32_indexed")
7390 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7391 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
7392 (AArch64dup (f32 FPR32Op:$Rm)))),
7393 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
7394 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
7396 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
7397 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
7398 (AArch64duplane64 (v2f64 V128:$Rm),
7399 VectorIndexD:$idx))),
7400 (!cast<Instruction>(INST # "v2i64_indexed")
7401 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7402 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
7403 (AArch64dup (f64 FPR64Op:$Rm)))),
7404 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
7405 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
7407 // 2 variants for 32-bit scalar version: extract from .2s or from .4s
7408 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
7409 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
7410 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
7411 V128:$Rm, VectorIndexS:$idx)>;
7412 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
7413 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
7414 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
7415 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
7417 // 1 variant for 64-bit scalar version: extract from .1d or from .2d
7418 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
7419 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
7420 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
7421 V128:$Rm, VectorIndexD:$idx)>;
7424 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
7425 let Predicates = [HasNEON, HasFullFP16] in {
7426 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
7427 V128_lo, VectorIndexH,
7428 asm, ".4h", ".4h", ".4h", ".h", []> {
7430 let Inst{11} = idx{2};
7431 let Inst{21} = idx{1};
7432 let Inst{20} = idx{0};
7435 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
7437 V128_lo, VectorIndexH,
7438 asm, ".8h", ".8h", ".8h", ".h", []> {
7440 let Inst{11} = idx{2};
7441 let Inst{21} = idx{1};
7442 let Inst{20} = idx{0};
7444 } // Predicates = [HasNEON, HasFullFP16]
7446 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
7448 asm, ".2s", ".2s", ".2s", ".s", []> {
7450 let Inst{11} = idx{1};
7451 let Inst{21} = idx{0};
7454 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7457 asm, ".4s", ".4s", ".4s", ".s", []> {
7459 let Inst{11} = idx{1};
7460 let Inst{21} = idx{0};
7463 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
7466 asm, ".2d", ".2d", ".2d", ".d", []> {
7468 let Inst{11} = idx{0};
7472 let Predicates = [HasNEON, HasFullFP16] in {
7473 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
7474 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7475 asm, ".h", "", "", ".h", []> {
7477 let Inst{11} = idx{2};
7478 let Inst{21} = idx{1};
7479 let Inst{20} = idx{0};
7481 } // Predicates = [HasNEON, HasFullFP16]
7483 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7484 FPR32Op, FPR32Op, V128, VectorIndexS,
7485 asm, ".s", "", "", ".s", []> {
7487 let Inst{11} = idx{1};
7488 let Inst{21} = idx{0};
7491 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
7492 FPR64Op, FPR64Op, V128, VectorIndexD,
7493 asm, ".d", "", "", ".d", []> {
7495 let Inst{11} = idx{0};
7500 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
7501 SDPatternOperator OpNode> {
7502 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
7503 V128_lo, VectorIndexH,
7504 asm, ".4h", ".4h", ".4h", ".h",
7505 [(set (v4i16 V64:$Rd),
7506 (OpNode (v4i16 V64:$Rn),
7507 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7509 let Inst{11} = idx{2};
7510 let Inst{21} = idx{1};
7511 let Inst{20} = idx{0};
7514 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7516 V128_lo, VectorIndexH,
7517 asm, ".8h", ".8h", ".8h", ".h",
7518 [(set (v8i16 V128:$Rd),
7519 (OpNode (v8i16 V128:$Rn),
7520 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7522 let Inst{11} = idx{2};
7523 let Inst{21} = idx{1};
7524 let Inst{20} = idx{0};
7527 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7530 asm, ".2s", ".2s", ".2s", ".s",
7531 [(set (v2i32 V64:$Rd),
7532 (OpNode (v2i32 V64:$Rn),
7533 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7535 let Inst{11} = idx{1};
7536 let Inst{21} = idx{0};
7539 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7542 asm, ".4s", ".4s", ".4s", ".s",
7543 [(set (v4i32 V128:$Rd),
7544 (OpNode (v4i32 V128:$Rn),
7545 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7547 let Inst{11} = idx{1};
7548 let Inst{21} = idx{0};
7551 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7552 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7553 asm, ".h", "", "", ".h", []> {
7555 let Inst{11} = idx{2};
7556 let Inst{21} = idx{1};
7557 let Inst{20} = idx{0};
7560 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7561 FPR32Op, FPR32Op, V128, VectorIndexS,
7562 asm, ".s", "", "", ".s",
7563 [(set (i32 FPR32Op:$Rd),
7564 (OpNode FPR32Op:$Rn,
7565 (i32 (vector_extract (v4i32 V128:$Rm),
7566 VectorIndexS:$idx))))]> {
7568 let Inst{11} = idx{1};
7569 let Inst{21} = idx{0};
7573 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
7574 SDPatternOperator OpNode> {
7575 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7577 V128_lo, VectorIndexH,
7578 asm, ".4h", ".4h", ".4h", ".h",
7579 [(set (v4i16 V64:$Rd),
7580 (OpNode (v4i16 V64:$Rn),
7581 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7583 let Inst{11} = idx{2};
7584 let Inst{21} = idx{1};
7585 let Inst{20} = idx{0};
7588 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7590 V128_lo, VectorIndexH,
7591 asm, ".8h", ".8h", ".8h", ".h",
7592 [(set (v8i16 V128:$Rd),
7593 (OpNode (v8i16 V128:$Rn),
7594 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7596 let Inst{11} = idx{2};
7597 let Inst{21} = idx{1};
7598 let Inst{20} = idx{0};
7601 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7604 asm, ".2s", ".2s", ".2s", ".s",
7605 [(set (v2i32 V64:$Rd),
7606 (OpNode (v2i32 V64:$Rn),
7607 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7609 let Inst{11} = idx{1};
7610 let Inst{21} = idx{0};
7613 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7616 asm, ".4s", ".4s", ".4s", ".s",
7617 [(set (v4i32 V128:$Rd),
7618 (OpNode (v4i32 V128:$Rn),
7619 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7621 let Inst{11} = idx{1};
7622 let Inst{21} = idx{0};
7626 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
7627 SDPatternOperator OpNode> {
7628 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
7629 V128_lo, VectorIndexH,
7630 asm, ".4h", ".4h", ".4h", ".h",
7631 [(set (v4i16 V64:$dst),
7632 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
7633 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7635 let Inst{11} = idx{2};
7636 let Inst{21} = idx{1};
7637 let Inst{20} = idx{0};
7640 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7642 V128_lo, VectorIndexH,
7643 asm, ".8h", ".8h", ".8h", ".h",
7644 [(set (v8i16 V128:$dst),
7645 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7646 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7648 let Inst{11} = idx{2};
7649 let Inst{21} = idx{1};
7650 let Inst{20} = idx{0};
7653 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7656 asm, ".2s", ".2s", ".2s", ".s",
7657 [(set (v2i32 V64:$dst),
7658 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7659 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7661 let Inst{11} = idx{1};
7662 let Inst{21} = idx{0};
7665 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7668 asm, ".4s", ".4s", ".4s", ".s",
7669 [(set (v4i32 V128:$dst),
7670 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7671 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7673 let Inst{11} = idx{1};
7674 let Inst{21} = idx{0};
7678 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
7679 SDPatternOperator OpNode> {
7680 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7682 V128_lo, VectorIndexH,
7683 asm, ".4s", ".4s", ".4h", ".h",
7684 [(set (v4i32 V128:$Rd),
7685 (OpNode (v4i16 V64:$Rn),
7686 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7688 let Inst{11} = idx{2};
7689 let Inst{21} = idx{1};
7690 let Inst{20} = idx{0};
7693 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7695 V128_lo, VectorIndexH,
7696 asm#"2", ".4s", ".4s", ".8h", ".h",
7697 [(set (v4i32 V128:$Rd),
7698 (OpNode (extract_high_v8i16 V128:$Rn),
7699 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7700 VectorIndexH:$idx))))]> {
7703 let Inst{11} = idx{2};
7704 let Inst{21} = idx{1};
7705 let Inst{20} = idx{0};
7708 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7711 asm, ".2d", ".2d", ".2s", ".s",
7712 [(set (v2i64 V128:$Rd),
7713 (OpNode (v2i32 V64:$Rn),
7714 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7716 let Inst{11} = idx{1};
7717 let Inst{21} = idx{0};
7720 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7723 asm#"2", ".2d", ".2d", ".4s", ".s",
7724 [(set (v2i64 V128:$Rd),
7725 (OpNode (extract_high_v4i32 V128:$Rn),
7726 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7727 VectorIndexS:$idx))))]> {
7729 let Inst{11} = idx{1};
7730 let Inst{21} = idx{0};
7733 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7734 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7735 asm, ".h", "", "", ".h", []> {
7737 let Inst{11} = idx{2};
7738 let Inst{21} = idx{1};
7739 let Inst{20} = idx{0};
7742 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7743 FPR64Op, FPR32Op, V128, VectorIndexS,
7744 asm, ".s", "", "", ".s", []> {
7746 let Inst{11} = idx{1};
7747 let Inst{21} = idx{0};
7751 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
7752 SDPatternOperator Accum> {
7753 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7755 V128_lo, VectorIndexH,
7756 asm, ".4s", ".4s", ".4h", ".h",
7757 [(set (v4i32 V128:$dst),
7758 (Accum (v4i32 V128:$Rd),
7759 (v4i32 (int_aarch64_neon_sqdmull
7761 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7762 VectorIndexH:$idx))))))]> {
7764 let Inst{11} = idx{2};
7765 let Inst{21} = idx{1};
7766 let Inst{20} = idx{0};
7769 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
7770 // intermediate EXTRACT_SUBREG would be untyped.
7771 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
7772 (i32 (vector_extract (v4i32
7773 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
7774 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7775 VectorIndexH:$idx)))),
7778 (!cast<Instruction>(NAME # v4i16_indexed)
7779 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
7780 V128_lo:$Rm, VectorIndexH:$idx),
7783 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7785 V128_lo, VectorIndexH,
7786 asm#"2", ".4s", ".4s", ".8h", ".h",
7787 [(set (v4i32 V128:$dst),
7788 (Accum (v4i32 V128:$Rd),
7789 (v4i32 (int_aarch64_neon_sqdmull
7790 (extract_high_v8i16 V128:$Rn),
7792 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7793 VectorIndexH:$idx))))))]> {
7795 let Inst{11} = idx{2};
7796 let Inst{21} = idx{1};
7797 let Inst{20} = idx{0};
7800 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7803 asm, ".2d", ".2d", ".2s", ".s",
7804 [(set (v2i64 V128:$dst),
7805 (Accum (v2i64 V128:$Rd),
7806 (v2i64 (int_aarch64_neon_sqdmull
7808 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
7809 VectorIndexS:$idx))))))]> {
7811 let Inst{11} = idx{1};
7812 let Inst{21} = idx{0};
7815 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7818 asm#"2", ".2d", ".2d", ".4s", ".s",
7819 [(set (v2i64 V128:$dst),
7820 (Accum (v2i64 V128:$Rd),
7821 (v2i64 (int_aarch64_neon_sqdmull
7822 (extract_high_v4i32 V128:$Rn),
7824 (AArch64duplane32 (v4i32 V128:$Rm),
7825 VectorIndexS:$idx))))))]> {
7827 let Inst{11} = idx{1};
7828 let Inst{21} = idx{0};
7831 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
7832 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7833 asm, ".h", "", "", ".h", []> {
7835 let Inst{11} = idx{2};
7836 let Inst{21} = idx{1};
7837 let Inst{20} = idx{0};
7841 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7842 FPR64Op, FPR32Op, V128, VectorIndexS,
7843 asm, ".s", "", "", ".s",
7844 [(set (i64 FPR64Op:$dst),
7845 (Accum (i64 FPR64Op:$Rd),
7846 (i64 (int_aarch64_neon_sqdmulls_scalar
7848 (i32 (vector_extract (v4i32 V128:$Rm),
7849 VectorIndexS:$idx))))))]> {
7852 let Inst{11} = idx{1};
7853 let Inst{21} = idx{0};
7857 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
7858 SDPatternOperator OpNode> {
7859 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7860 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7862 V128_lo, VectorIndexH,
7863 asm, ".4s", ".4s", ".4h", ".h",
7864 [(set (v4i32 V128:$Rd),
7865 (OpNode (v4i16 V64:$Rn),
7866 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7868 let Inst{11} = idx{2};
7869 let Inst{21} = idx{1};
7870 let Inst{20} = idx{0};
7873 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7875 V128_lo, VectorIndexH,
7876 asm#"2", ".4s", ".4s", ".8h", ".h",
7877 [(set (v4i32 V128:$Rd),
7878 (OpNode (extract_high_v8i16 V128:$Rn),
7879 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7880 VectorIndexH:$idx))))]> {
7883 let Inst{11} = idx{2};
7884 let Inst{21} = idx{1};
7885 let Inst{20} = idx{0};
7888 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7891 asm, ".2d", ".2d", ".2s", ".s",
7892 [(set (v2i64 V128:$Rd),
7893 (OpNode (v2i32 V64:$Rn),
7894 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7896 let Inst{11} = idx{1};
7897 let Inst{21} = idx{0};
7900 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7903 asm#"2", ".2d", ".2d", ".4s", ".s",
7904 [(set (v2i64 V128:$Rd),
7905 (OpNode (extract_high_v4i32 V128:$Rn),
7906 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7907 VectorIndexS:$idx))))]> {
7909 let Inst{11} = idx{1};
7910 let Inst{21} = idx{0};
7915 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
7916 SDPatternOperator OpNode> {
7917 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7918 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7920 V128_lo, VectorIndexH,
7921 asm, ".4s", ".4s", ".4h", ".h",
7922 [(set (v4i32 V128:$dst),
7923 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
7924 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7926 let Inst{11} = idx{2};
7927 let Inst{21} = idx{1};
7928 let Inst{20} = idx{0};
7931 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7933 V128_lo, VectorIndexH,
7934 asm#"2", ".4s", ".4s", ".8h", ".h",
7935 [(set (v4i32 V128:$dst),
7936 (OpNode (v4i32 V128:$Rd),
7937 (extract_high_v8i16 V128:$Rn),
7938 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7939 VectorIndexH:$idx))))]> {
7941 let Inst{11} = idx{2};
7942 let Inst{21} = idx{1};
7943 let Inst{20} = idx{0};
7946 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7949 asm, ".2d", ".2d", ".2s", ".s",
7950 [(set (v2i64 V128:$dst),
7951 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
7952 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7954 let Inst{11} = idx{1};
7955 let Inst{21} = idx{0};
7958 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7961 asm#"2", ".2d", ".2d", ".4s", ".s",
7962 [(set (v2i64 V128:$dst),
7963 (OpNode (v2i64 V128:$Rd),
7964 (extract_high_v4i32 V128:$Rn),
7965 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7966 VectorIndexS:$idx))))]> {
7968 let Inst{11} = idx{1};
7969 let Inst{21} = idx{0};
7974 //----------------------------------------------------------------------------
7975 // AdvSIMD scalar shift by immediate
7976 //----------------------------------------------------------------------------
7978 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7979 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
7980 RegisterClass regtype1, RegisterClass regtype2,
7981 Operand immtype, string asm, list<dag> pattern>
7982 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
7983 asm, "\t$Rd, $Rn, $imm", "", pattern>,
7988 let Inst{31-30} = 0b01;
7990 let Inst{28-23} = 0b111110;
7991 let Inst{22-16} = fixed_imm;
7992 let Inst{15-11} = opc;
7998 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7999 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
8000 RegisterClass regtype1, RegisterClass regtype2,
8001 Operand immtype, string asm, list<dag> pattern>
8002 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
8003 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
8008 let Inst{31-30} = 0b01;
8010 let Inst{28-23} = 0b111110;
8011 let Inst{22-16} = fixed_imm;
8012 let Inst{15-11} = opc;
8019 multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
8020 let Predicates = [HasNEON, HasFullFP16] in {
8021 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8022 FPR16, FPR16, vecshiftR16, asm, []> {
8023 let Inst{19-16} = imm{3-0};
8025 } // Predicates = [HasNEON, HasFullFP16]
8026 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8027 FPR32, FPR32, vecshiftR32, asm, []> {
8028 let Inst{20-16} = imm{4-0};
8030 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8031 FPR64, FPR64, vecshiftR64, asm, []> {
8032 let Inst{21-16} = imm{5-0};
8036 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
8037 SDPatternOperator OpNode> {
8038 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8039 FPR64, FPR64, vecshiftR64, asm,
8040 [(set (i64 FPR64:$Rd),
8041 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
8042 let Inst{21-16} = imm{5-0};
8045 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
8046 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
8049 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
8050 SDPatternOperator OpNode = null_frag> {
8051 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
8052 FPR64, FPR64, vecshiftR64, asm,
8053 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
8054 (i32 vecshiftR64:$imm)))]> {
8055 let Inst{21-16} = imm{5-0};
8058 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
8059 (i32 vecshiftR64:$imm))),
8060 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
8064 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
8065 SDPatternOperator OpNode> {
8066 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8067 FPR64, FPR64, vecshiftL64, asm,
8068 [(set (v1i64 FPR64:$Rd),
8069 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
8070 let Inst{21-16} = imm{5-0};
8074 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8075 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
8076 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
8077 FPR64, FPR64, vecshiftL64, asm, []> {
8078 let Inst{21-16} = imm{5-0};
8082 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8083 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
8084 SDPatternOperator OpNode = null_frag> {
8085 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8086 FPR8, FPR16, vecshiftR8, asm, []> {
8087 let Inst{18-16} = imm{2-0};
8090 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8091 FPR16, FPR32, vecshiftR16, asm, []> {
8092 let Inst{19-16} = imm{3-0};
8095 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8096 FPR32, FPR64, vecshiftR32, asm,
8097 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
8098 let Inst{20-16} = imm{4-0};
8102 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
8103 SDPatternOperator OpNode> {
8104 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8105 FPR8, FPR8, vecshiftL8, asm, []> {
8106 let Inst{18-16} = imm{2-0};
8109 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8110 FPR16, FPR16, vecshiftL16, asm, []> {
8111 let Inst{19-16} = imm{3-0};
8114 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8115 FPR32, FPR32, vecshiftL32, asm,
8116 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
8117 let Inst{20-16} = imm{4-0};
8120 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8121 FPR64, FPR64, vecshiftL64, asm,
8122 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
8123 let Inst{21-16} = imm{5-0};
8126 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
8127 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
8130 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
8131 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8132 FPR8, FPR8, vecshiftR8, asm, []> {
8133 let Inst{18-16} = imm{2-0};
8136 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8137 FPR16, FPR16, vecshiftR16, asm, []> {
8138 let Inst{19-16} = imm{3-0};
8141 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8142 FPR32, FPR32, vecshiftR32, asm, []> {
8143 let Inst{20-16} = imm{4-0};
8146 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8147 FPR64, FPR64, vecshiftR64, asm, []> {
8148 let Inst{21-16} = imm{5-0};
8152 //----------------------------------------------------------------------------
8153 // AdvSIMD vector x indexed element
8154 //----------------------------------------------------------------------------
8156 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8157 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
8158 RegisterOperand dst_reg, RegisterOperand src_reg,
8160 string asm, string dst_kind, string src_kind,
8162 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
8163 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
8164 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
8171 let Inst{28-23} = 0b011110;
8172 let Inst{22-16} = fixed_imm;
8173 let Inst{15-11} = opc;
8179 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8180 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
8181 RegisterOperand vectype1, RegisterOperand vectype2,
8183 string asm, string dst_kind, string src_kind,
8185 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
8186 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
8187 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
8194 let Inst{28-23} = 0b011110;
8195 let Inst{22-16} = fixed_imm;
8196 let Inst{15-11} = opc;
8202 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
8204 let Predicates = [HasNEON, HasFullFP16] in {
8205 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8206 V64, V64, vecshiftR16,
8208 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
8210 let Inst{19-16} = imm;
8213 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8214 V128, V128, vecshiftR16,
8216 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
8218 let Inst{19-16} = imm;
8220 } // Predicates = [HasNEON, HasFullFP16]
8221 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8222 V64, V64, vecshiftR32,
8224 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
8226 let Inst{20-16} = imm;
8229 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8230 V128, V128, vecshiftR32,
8232 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
8234 let Inst{20-16} = imm;
8237 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8238 V128, V128, vecshiftR64,
8240 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
8242 let Inst{21-16} = imm;
8246 multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
8248 let Predicates = [HasNEON, HasFullFP16] in {
8249 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8250 V64, V64, vecshiftR16,
8252 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
8254 let Inst{19-16} = imm;
8257 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8258 V128, V128, vecshiftR16,
8260 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
8262 let Inst{19-16} = imm;
8264 } // Predicates = [HasNEON, HasFullFP16]
8266 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8267 V64, V64, vecshiftR32,
8269 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
8271 let Inst{20-16} = imm;
8274 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8275 V128, V128, vecshiftR32,
8277 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
8279 let Inst{20-16} = imm;
8282 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8283 V128, V128, vecshiftR64,
8285 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
8287 let Inst{21-16} = imm;
8291 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
8292 SDPatternOperator OpNode> {
8293 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8294 V64, V128, vecshiftR16Narrow,
8296 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
8298 let Inst{18-16} = imm;
8301 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8302 V128, V128, vecshiftR16Narrow,
8303 asm#"2", ".16b", ".8h", []> {
8305 let Inst{18-16} = imm;
8306 let hasSideEffects = 0;
8309 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8310 V64, V128, vecshiftR32Narrow,
8312 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
8314 let Inst{19-16} = imm;
8317 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8318 V128, V128, vecshiftR32Narrow,
8319 asm#"2", ".8h", ".4s", []> {
8321 let Inst{19-16} = imm;
8322 let hasSideEffects = 0;
8325 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8326 V64, V128, vecshiftR64Narrow,
8328 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
8330 let Inst{20-16} = imm;
8333 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8334 V128, V128, vecshiftR64Narrow,
8335 asm#"2", ".4s", ".2d", []> {
8337 let Inst{20-16} = imm;
8338 let hasSideEffects = 0;
8341 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
8342 // themselves, so put them here instead.
8344 // Patterns involving what's effectively an insert high and a normal
8345 // intrinsic, represented by CONCAT_VECTORS.
8346 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
8347 vecshiftR16Narrow:$imm)),
8348 (!cast<Instruction>(NAME # "v16i8_shift")
8349 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8350 V128:$Rn, vecshiftR16Narrow:$imm)>;
8351 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
8352 vecshiftR32Narrow:$imm)),
8353 (!cast<Instruction>(NAME # "v8i16_shift")
8354 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8355 V128:$Rn, vecshiftR32Narrow:$imm)>;
8356 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
8357 vecshiftR64Narrow:$imm)),
8358 (!cast<Instruction>(NAME # "v4i32_shift")
8359 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8360 V128:$Rn, vecshiftR64Narrow:$imm)>;
8363 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
8364 SDPatternOperator OpNode> {
8365 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8366 V64, V64, vecshiftL8,
8368 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
8369 (i32 vecshiftL8:$imm)))]> {
8371 let Inst{18-16} = imm;
8374 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8375 V128, V128, vecshiftL8,
8376 asm, ".16b", ".16b",
8377 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
8378 (i32 vecshiftL8:$imm)))]> {
8380 let Inst{18-16} = imm;
8383 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8384 V64, V64, vecshiftL16,
8386 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
8387 (i32 vecshiftL16:$imm)))]> {
8389 let Inst{19-16} = imm;
8392 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8393 V128, V128, vecshiftL16,
8395 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
8396 (i32 vecshiftL16:$imm)))]> {
8398 let Inst{19-16} = imm;
8401 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8402 V64, V64, vecshiftL32,
8404 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
8405 (i32 vecshiftL32:$imm)))]> {
8407 let Inst{20-16} = imm;
8410 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8411 V128, V128, vecshiftL32,
8413 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
8414 (i32 vecshiftL32:$imm)))]> {
8416 let Inst{20-16} = imm;
8419 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8420 V128, V128, vecshiftL64,
8422 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
8423 (i32 vecshiftL64:$imm)))]> {
8425 let Inst{21-16} = imm;
8429 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
8430 SDPatternOperator OpNode> {
8431 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8432 V64, V64, vecshiftR8,
8434 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
8435 (i32 vecshiftR8:$imm)))]> {
8437 let Inst{18-16} = imm;
8440 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8441 V128, V128, vecshiftR8,
8442 asm, ".16b", ".16b",
8443 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
8444 (i32 vecshiftR8:$imm)))]> {
8446 let Inst{18-16} = imm;
8449 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8450 V64, V64, vecshiftR16,
8452 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
8453 (i32 vecshiftR16:$imm)))]> {
8455 let Inst{19-16} = imm;
8458 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8459 V128, V128, vecshiftR16,
8461 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
8462 (i32 vecshiftR16:$imm)))]> {
8464 let Inst{19-16} = imm;
8467 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8468 V64, V64, vecshiftR32,
8470 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
8471 (i32 vecshiftR32:$imm)))]> {
8473 let Inst{20-16} = imm;
8476 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8477 V128, V128, vecshiftR32,
8479 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
8480 (i32 vecshiftR32:$imm)))]> {
8482 let Inst{20-16} = imm;
8485 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8486 V128, V128, vecshiftR64,
8488 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
8489 (i32 vecshiftR64:$imm)))]> {
8491 let Inst{21-16} = imm;
8495 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8496 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
8497 SDPatternOperator OpNode = null_frag> {
8498 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8499 V64, V64, vecshiftR8, asm, ".8b", ".8b",
8500 [(set (v8i8 V64:$dst),
8501 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8502 (i32 vecshiftR8:$imm)))]> {
8504 let Inst{18-16} = imm;
8507 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8508 V128, V128, vecshiftR8, asm, ".16b", ".16b",
8509 [(set (v16i8 V128:$dst),
8510 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8511 (i32 vecshiftR8:$imm)))]> {
8513 let Inst{18-16} = imm;
8516 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8517 V64, V64, vecshiftR16, asm, ".4h", ".4h",
8518 [(set (v4i16 V64:$dst),
8519 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8520 (i32 vecshiftR16:$imm)))]> {
8522 let Inst{19-16} = imm;
8525 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8526 V128, V128, vecshiftR16, asm, ".8h", ".8h",
8527 [(set (v8i16 V128:$dst),
8528 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8529 (i32 vecshiftR16:$imm)))]> {
8531 let Inst{19-16} = imm;
8534 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8535 V64, V64, vecshiftR32, asm, ".2s", ".2s",
8536 [(set (v2i32 V64:$dst),
8537 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8538 (i32 vecshiftR32:$imm)))]> {
8540 let Inst{20-16} = imm;
8543 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8544 V128, V128, vecshiftR32, asm, ".4s", ".4s",
8545 [(set (v4i32 V128:$dst),
8546 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8547 (i32 vecshiftR32:$imm)))]> {
8549 let Inst{20-16} = imm;
8552 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8553 V128, V128, vecshiftR64,
8554 asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
8555 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8556 (i32 vecshiftR64:$imm)))]> {
8558 let Inst{21-16} = imm;
8562 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
8563 SDPatternOperator OpNode = null_frag> {
8564 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8565 V64, V64, vecshiftL8,
8567 [(set (v8i8 V64:$dst),
8568 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8569 (i32 vecshiftL8:$imm)))]> {
8571 let Inst{18-16} = imm;
8574 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8575 V128, V128, vecshiftL8,
8576 asm, ".16b", ".16b",
8577 [(set (v16i8 V128:$dst),
8578 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8579 (i32 vecshiftL8:$imm)))]> {
8581 let Inst{18-16} = imm;
8584 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8585 V64, V64, vecshiftL16,
8587 [(set (v4i16 V64:$dst),
8588 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8589 (i32 vecshiftL16:$imm)))]> {
8591 let Inst{19-16} = imm;
8594 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8595 V128, V128, vecshiftL16,
8597 [(set (v8i16 V128:$dst),
8598 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8599 (i32 vecshiftL16:$imm)))]> {
8601 let Inst{19-16} = imm;
8604 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8605 V64, V64, vecshiftL32,
8607 [(set (v2i32 V64:$dst),
8608 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8609 (i32 vecshiftL32:$imm)))]> {
8611 let Inst{20-16} = imm;
8614 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8615 V128, V128, vecshiftL32,
8617 [(set (v4i32 V128:$dst),
8618 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8619 (i32 vecshiftL32:$imm)))]> {
8621 let Inst{20-16} = imm;
8624 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8625 V128, V128, vecshiftL64,
8627 [(set (v2i64 V128:$dst),
8628 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8629 (i32 vecshiftL64:$imm)))]> {
8631 let Inst{21-16} = imm;
8635 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
8636 SDPatternOperator OpNode> {
8637 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8638 V128, V64, vecshiftL8, asm, ".8h", ".8b",
8639 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
8641 let Inst{18-16} = imm;
8644 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8645 V128, V128, vecshiftL8,
8646 asm#"2", ".8h", ".16b",
8647 [(set (v8i16 V128:$Rd),
8648 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
8650 let Inst{18-16} = imm;
8653 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8654 V128, V64, vecshiftL16, asm, ".4s", ".4h",
8655 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
8657 let Inst{19-16} = imm;
8660 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8661 V128, V128, vecshiftL16,
8662 asm#"2", ".4s", ".8h",
8663 [(set (v4i32 V128:$Rd),
8664 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
8667 let Inst{19-16} = imm;
8670 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8671 V128, V64, vecshiftL32, asm, ".2d", ".2s",
8672 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
8674 let Inst{20-16} = imm;
8677 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8678 V128, V128, vecshiftL32,
8679 asm#"2", ".2d", ".4s",
8680 [(set (v2i64 V128:$Rd),
8681 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
8683 let Inst{20-16} = imm;
8689 // Vector load/store
8691 // SIMD ldX/stX no-index memory references don't allow the optional
8692 // ", #0" constant and handle post-indexing explicitly, so we use
8693 // a more specialized parse method for them. Otherwise, it's the same as
8694 // the general GPR64sp handling.
8696 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
8697 string asm, dag oops, dag iops, list<dag> pattern>
8698 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
8703 let Inst{29-23} = 0b0011000;
8705 let Inst{21-16} = 0b000000;
8706 let Inst{15-12} = opcode;
8707 let Inst{11-10} = size;
8712 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
8713 string asm, dag oops, dag iops>
8714 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
8720 let Inst{29-23} = 0b0011001;
8723 let Inst{20-16} = Xm;
8724 let Inst{15-12} = opcode;
8725 let Inst{11-10} = size;
8730 // The immediate form of AdvSIMD post-indexed addressing is encoded with
8731 // register post-index addressing from the zero register.
8732 multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count,
8733 int Offset, int Size> {
8734 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
8735 // "ld1\t$Vt, [$Rn], #16"
8736 // may get mapped to
8737 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
8738 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8739 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
8741 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8744 // E.g. "ld1.8b { v0, v1 }, [x1], #16"
8745 // "ld1.8b\t$Vt, [$Rn], #16"
8746 // may get mapped to
8747 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
8748 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8749 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
8751 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8754 // E.g. "ld1.8b { v0, v1 }, [x1]"
8755 // "ld1\t$Vt, [$Rn]"
8756 // may get mapped to
8757 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
8758 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8759 (!cast<Instruction>(BaseName # Count # "v" # layout)
8760 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8763 // E.g. "ld1.8b { v0, v1 }, [x1], x2"
8764 // "ld1\t$Vt, [$Rn], $Xm"
8765 // may get mapped to
8766 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
8767 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8768 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
8770 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8771 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8774 multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist,
8775 int Offset128, int Offset64, bits<4> opcode> {
8776 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8777 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
8778 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
8779 (ins GPR64sp:$Rn), []>;
8780 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
8781 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
8782 (ins GPR64sp:$Rn), []>;
8783 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
8784 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
8785 (ins GPR64sp:$Rn), []>;
8786 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
8787 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
8788 (ins GPR64sp:$Rn), []>;
8789 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
8790 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
8791 (ins GPR64sp:$Rn), []>;
8792 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
8793 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
8794 (ins GPR64sp:$Rn), []>;
8795 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
8796 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
8797 (ins GPR64sp:$Rn), []>;
8800 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
8801 (outs GPR64sp:$wback,
8802 !cast<RegisterOperand>(veclist # "16b"):$Vt),
8804 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8805 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
8806 (outs GPR64sp:$wback,
8807 !cast<RegisterOperand>(veclist # "8h"):$Vt),
8809 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8810 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
8811 (outs GPR64sp:$wback,
8812 !cast<RegisterOperand>(veclist # "4s"):$Vt),
8814 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8815 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
8816 (outs GPR64sp:$wback,
8817 !cast<RegisterOperand>(veclist # "2d"):$Vt),
8819 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8820 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
8821 (outs GPR64sp:$wback,
8822 !cast<RegisterOperand>(veclist # "8b"):$Vt),
8824 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8825 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
8826 (outs GPR64sp:$wback,
8827 !cast<RegisterOperand>(veclist # "4h"):$Vt),
8829 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8830 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
8831 (outs GPR64sp:$wback,
8832 !cast<RegisterOperand>(veclist # "2s"):$Vt),
8834 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8837 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
8838 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
8839 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
8840 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
8841 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
8842 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
8843 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
8846 // Only ld1/st1 has a v1d version.
8847 multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist,
8848 int Offset128, int Offset64, bits<4> opcode> {
8849 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
8850 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
8851 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8853 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
8854 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8856 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
8857 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8859 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
8860 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8862 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
8863 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8865 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
8866 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8868 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
8869 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8872 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
8873 (outs GPR64sp:$wback),
8874 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8876 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8877 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
8878 (outs GPR64sp:$wback),
8879 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8881 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8882 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
8883 (outs GPR64sp:$wback),
8884 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8886 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8887 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
8888 (outs GPR64sp:$wback),
8889 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8891 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8892 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
8893 (outs GPR64sp:$wback),
8894 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8896 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8897 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
8898 (outs GPR64sp:$wback),
8899 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8901 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8902 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
8903 (outs GPR64sp:$wback),
8904 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8906 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8909 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
8910 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
8911 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
8912 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
8913 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
8914 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
8915 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
8918 multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist,
8919 int Offset128, int Offset64, bits<4> opcode>
8920 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
8922 // LD1 instructions have extra "1d" variants.
8923 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8924 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
8925 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
8926 (ins GPR64sp:$Rn), []>;
8928 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
8929 (outs GPR64sp:$wback,
8930 !cast<RegisterOperand>(veclist # "1d"):$Vt),
8932 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8935 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
8938 multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist,
8939 int Offset128, int Offset64, bits<4> opcode>
8940 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
8942 // ST1 instructions have extra "1d" variants.
8943 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
8944 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
8945 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8948 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
8949 (outs GPR64sp:$wback),
8950 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8952 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8955 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
8958 multiclass SIMDLd1Multiple<string asm> {
8959 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>;
8960 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
8961 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
8962 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
8965 multiclass SIMDSt1Multiple<string asm> {
8966 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>;
8967 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
8968 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
8969 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
8972 multiclass SIMDLd2Multiple<string asm> {
8973 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
8976 multiclass SIMDSt2Multiple<string asm> {
8977 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
8980 multiclass SIMDLd3Multiple<string asm> {
8981 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
8984 multiclass SIMDSt3Multiple<string asm> {
8985 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
8988 multiclass SIMDLd4Multiple<string asm> {
8989 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
8992 multiclass SIMDSt4Multiple<string asm> {
8993 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
8997 // AdvSIMD Load/store single-element
9000 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
9001 string asm, string operands, string cst,
9002 dag oops, dag iops, list<dag> pattern>
9003 : I<oops, iops, asm, operands, cst, pattern> {
9007 let Inst{29-24} = 0b001101;
9010 let Inst{15-13} = opcode;
9015 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
9016 string asm, string operands, string cst,
9017 dag oops, dag iops, list<dag> pattern>
9018 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
9022 let Inst{29-24} = 0b001101;
9025 let Inst{15-13} = opcode;
9031 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9032 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
9033 DAGOperand listtype>
9034 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
9035 (outs listtype:$Vt), (ins GPR64sp:$Rn),
9039 let Inst{20-16} = 0b00000;
9041 let Inst{11-10} = size;
9043 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9044 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
9045 string asm, DAGOperand listtype, DAGOperand GPR64pi>
9046 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
9048 (outs GPR64sp:$wback, listtype:$Vt),
9049 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
9053 let Inst{20-16} = Xm;
9055 let Inst{11-10} = size;
9058 multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count,
9059 int Offset, int Size> {
9060 // E.g. "ld1r { v0.8b }, [x1], #1"
9061 // "ld1r.8b\t$Vt, [$Rn], #1"
9062 // may get mapped to
9063 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
9064 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
9065 (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9067 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9070 // E.g. "ld1r.8b { v0 }, [x1], #1"
9071 // "ld1r.8b\t$Vt, [$Rn], #1"
9072 // may get mapped to
9073 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
9074 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
9075 (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9077 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9080 // E.g. "ld1r.8b { v0 }, [x1]"
9081 // "ld1r.8b\t$Vt, [$Rn]"
9082 // may get mapped to
9083 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
9084 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
9085 (!cast<Instruction>(BaseName # "v" # layout)
9086 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9089 // E.g. "ld1r.8b { v0 }, [x1], x2"
9090 // "ld1r.8b\t$Vt, [$Rn], $Xm"
9091 // may get mapped to
9092 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
9093 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
9094 (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9096 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9097 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9100 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
9101 int Offset1, int Offset2, int Offset4, int Offset8> {
9102 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
9103 !cast<DAGOperand>("VecList" # Count # "8b")>;
9104 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
9105 !cast<DAGOperand>("VecList" # Count #"16b")>;
9106 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
9107 !cast<DAGOperand>("VecList" # Count #"4h")>;
9108 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
9109 !cast<DAGOperand>("VecList" # Count #"8h")>;
9110 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
9111 !cast<DAGOperand>("VecList" # Count #"2s")>;
9112 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
9113 !cast<DAGOperand>("VecList" # Count #"4s")>;
9114 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
9115 !cast<DAGOperand>("VecList" # Count #"1d")>;
9116 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
9117 !cast<DAGOperand>("VecList" # Count #"2d")>;
9119 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
9120 !cast<DAGOperand>("VecList" # Count # "8b"),
9121 !cast<DAGOperand>("GPR64pi" # Offset1)>;
9122 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
9123 !cast<DAGOperand>("VecList" # Count # "16b"),
9124 !cast<DAGOperand>("GPR64pi" # Offset1)>;
9125 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
9126 !cast<DAGOperand>("VecList" # Count # "4h"),
9127 !cast<DAGOperand>("GPR64pi" # Offset2)>;
9128 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
9129 !cast<DAGOperand>("VecList" # Count # "8h"),
9130 !cast<DAGOperand>("GPR64pi" # Offset2)>;
9131 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
9132 !cast<DAGOperand>("VecList" # Count # "2s"),
9133 !cast<DAGOperand>("GPR64pi" # Offset4)>;
9134 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
9135 !cast<DAGOperand>("VecList" # Count # "4s"),
9136 !cast<DAGOperand>("GPR64pi" # Offset4)>;
9137 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
9138 !cast<DAGOperand>("VecList" # Count # "1d"),
9139 !cast<DAGOperand>("GPR64pi" # Offset8)>;
9140 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
9141 !cast<DAGOperand>("VecList" # Count # "2d"),
9142 !cast<DAGOperand>("GPR64pi" # Offset8)>;
9144 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>;
9145 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>;
9146 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>;
9147 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>;
9148 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>;
9149 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>;
9150 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>;
9151 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>;
9154 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
9155 dag oops, dag iops, list<dag> pattern>
9156 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9158 // idx encoded in Q:S:size fields.
9160 let Inst{30} = idx{3};
9162 let Inst{20-16} = 0b00000;
9163 let Inst{12} = idx{2};
9164 let Inst{11-10} = idx{1-0};
9166 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
9167 dag oops, dag iops, list<dag> pattern>
9168 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9169 oops, iops, pattern> {
9170 // idx encoded in Q:S:size fields.
9172 let Inst{30} = idx{3};
9174 let Inst{20-16} = 0b00000;
9175 let Inst{12} = idx{2};
9176 let Inst{11-10} = idx{1-0};
9178 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
9180 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9181 "$Rn = $wback", oops, iops, []> {
9182 // idx encoded in Q:S:size fields.
9185 let Inst{30} = idx{3};
9187 let Inst{20-16} = Xm;
9188 let Inst{12} = idx{2};
9189 let Inst{11-10} = idx{1-0};
9191 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
9193 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9194 "$Rn = $wback", oops, iops, []> {
9195 // idx encoded in Q:S:size fields.
9198 let Inst{30} = idx{3};
9200 let Inst{20-16} = Xm;
9201 let Inst{12} = idx{2};
9202 let Inst{11-10} = idx{1-0};
9205 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
9206 dag oops, dag iops, list<dag> pattern>
9207 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9209 // idx encoded in Q:S:size<1> fields.
9211 let Inst{30} = idx{2};
9213 let Inst{20-16} = 0b00000;
9214 let Inst{12} = idx{1};
9215 let Inst{11} = idx{0};
9216 let Inst{10} = size;
9218 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
9219 dag oops, dag iops, list<dag> pattern>
9220 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9221 oops, iops, pattern> {
9222 // idx encoded in Q:S:size<1> fields.
9224 let Inst{30} = idx{2};
9226 let Inst{20-16} = 0b00000;
9227 let Inst{12} = idx{1};
9228 let Inst{11} = idx{0};
9229 let Inst{10} = size;
9232 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
9234 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9235 "$Rn = $wback", oops, iops, []> {
9236 // idx encoded in Q:S:size<1> fields.
9239 let Inst{30} = idx{2};
9241 let Inst{20-16} = Xm;
9242 let Inst{12} = idx{1};
9243 let Inst{11} = idx{0};
9244 let Inst{10} = size;
9246 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
9248 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9249 "$Rn = $wback", oops, iops, []> {
9250 // idx encoded in Q:S:size<1> fields.
9253 let Inst{30} = idx{2};
9255 let Inst{20-16} = Xm;
9256 let Inst{12} = idx{1};
9257 let Inst{11} = idx{0};
9258 let Inst{10} = size;
9260 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9261 dag oops, dag iops, list<dag> pattern>
9262 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9264 // idx encoded in Q:S fields.
9266 let Inst{30} = idx{1};
9268 let Inst{20-16} = 0b00000;
9269 let Inst{12} = idx{0};
9270 let Inst{11-10} = size;
9272 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9273 dag oops, dag iops, list<dag> pattern>
9274 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9275 oops, iops, pattern> {
9276 // idx encoded in Q:S fields.
9278 let Inst{30} = idx{1};
9280 let Inst{20-16} = 0b00000;
9281 let Inst{12} = idx{0};
9282 let Inst{11-10} = size;
9284 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
9285 string asm, dag oops, dag iops>
9286 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9287 "$Rn = $wback", oops, iops, []> {
9288 // idx encoded in Q:S fields.
9291 let Inst{30} = idx{1};
9293 let Inst{20-16} = Xm;
9294 let Inst{12} = idx{0};
9295 let Inst{11-10} = size;
9297 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
9298 string asm, dag oops, dag iops>
9299 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9300 "$Rn = $wback", oops, iops, []> {
9301 // idx encoded in Q:S fields.
9304 let Inst{30} = idx{1};
9306 let Inst{20-16} = Xm;
9307 let Inst{12} = idx{0};
9308 let Inst{11-10} = size;
9310 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9311 dag oops, dag iops, list<dag> pattern>
9312 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9314 // idx encoded in Q field.
9318 let Inst{20-16} = 0b00000;
9320 let Inst{11-10} = size;
9322 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9323 dag oops, dag iops, list<dag> pattern>
9324 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9325 oops, iops, pattern> {
9326 // idx encoded in Q field.
9330 let Inst{20-16} = 0b00000;
9332 let Inst{11-10} = size;
9334 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
9335 string asm, dag oops, dag iops>
9336 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9337 "$Rn = $wback", oops, iops, []> {
9338 // idx encoded in Q field.
9343 let Inst{20-16} = Xm;
9345 let Inst{11-10} = size;
9347 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
9348 string asm, dag oops, dag iops>
9349 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9350 "$Rn = $wback", oops, iops, []> {
9351 // idx encoded in Q field.
9356 let Inst{20-16} = Xm;
9358 let Inst{11-10} = size;
9361 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9362 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
9363 RegisterOperand listtype,
9364 RegisterOperand GPR64pi> {
9365 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
9366 (outs listtype:$dst),
9367 (ins listtype:$Vt, VectorIndexB:$idx,
9370 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
9371 (outs GPR64sp:$wback, listtype:$dst),
9372 (ins listtype:$Vt, VectorIndexB:$idx,
9373 GPR64sp:$Rn, GPR64pi:$Xm)>;
9375 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9376 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
9377 RegisterOperand listtype,
9378 RegisterOperand GPR64pi> {
9379 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
9380 (outs listtype:$dst),
9381 (ins listtype:$Vt, VectorIndexH:$idx,
9384 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
9385 (outs GPR64sp:$wback, listtype:$dst),
9386 (ins listtype:$Vt, VectorIndexH:$idx,
9387 GPR64sp:$Rn, GPR64pi:$Xm)>;
9389 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9390 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
9391 RegisterOperand listtype,
9392 RegisterOperand GPR64pi> {
9393 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
9394 (outs listtype:$dst),
9395 (ins listtype:$Vt, VectorIndexS:$idx,
9398 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
9399 (outs GPR64sp:$wback, listtype:$dst),
9400 (ins listtype:$Vt, VectorIndexS:$idx,
9401 GPR64sp:$Rn, GPR64pi:$Xm)>;
9403 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9404 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
9405 RegisterOperand listtype, RegisterOperand GPR64pi> {
9406 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
9407 (outs listtype:$dst),
9408 (ins listtype:$Vt, VectorIndexD:$idx,
9411 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
9412 (outs GPR64sp:$wback, listtype:$dst),
9413 (ins listtype:$Vt, VectorIndexD:$idx,
9414 GPR64sp:$Rn, GPR64pi:$Xm)>;
9416 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9417 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
9418 RegisterOperand listtype, RegisterOperand GPR64pi> {
9419 def i8 : SIMDLdStSingleB<0, R, opcode, asm,
9420 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
9423 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
9424 (outs GPR64sp:$wback),
9425 (ins listtype:$Vt, VectorIndexB:$idx,
9426 GPR64sp:$Rn, GPR64pi:$Xm)>;
9428 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9429 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
9430 RegisterOperand listtype, RegisterOperand GPR64pi> {
9431 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
9432 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
9435 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
9436 (outs GPR64sp:$wback),
9437 (ins listtype:$Vt, VectorIndexH:$idx,
9438 GPR64sp:$Rn, GPR64pi:$Xm)>;
9440 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9441 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
9442 RegisterOperand listtype, RegisterOperand GPR64pi> {
9443 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
9444 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
9447 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
9448 (outs GPR64sp:$wback),
9449 (ins listtype:$Vt, VectorIndexS:$idx,
9450 GPR64sp:$Rn, GPR64pi:$Xm)>;
9452 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9453 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
9454 RegisterOperand listtype, RegisterOperand GPR64pi> {
9455 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
9456 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
9459 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
9460 (outs GPR64sp:$wback),
9461 (ins listtype:$Vt, VectorIndexD:$idx,
9462 GPR64sp:$Rn, GPR64pi:$Xm)>;
9465 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
9466 string Count, int Offset, Operand idxtype> {
9467 // E.g. "ld1 { v0.8b }[0], [x1], #1"
9468 // "ld1\t$Vt, [$Rn], #1"
9469 // may get mapped to
9470 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
9471 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
9472 (!cast<Instruction>(NAME # Type # "_POST")
9474 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9475 idxtype:$idx, XZR), 1>;
9477 // E.g. "ld1.8b { v0 }[0], [x1], #1"
9478 // "ld1.8b\t$Vt, [$Rn], #1"
9479 // may get mapped to
9480 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
9481 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
9482 (!cast<Instruction>(NAME # Type # "_POST")
9484 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9485 idxtype:$idx, XZR), 0>;
9487 // E.g. "ld1.8b { v0 }[0], [x1]"
9488 // "ld1.8b\t$Vt, [$Rn]"
9489 // may get mapped to
9490 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
9491 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
9492 (!cast<Instruction>(NAME # Type)
9493 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9494 idxtype:$idx, GPR64sp:$Rn), 0>;
9496 // E.g. "ld1.8b { v0 }[0], [x1], x2"
9497 // "ld1.8b\t$Vt, [$Rn], $Xm"
9498 // may get mapped to
9499 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
9500 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
9501 (!cast<Instruction>(NAME # Type # "_POST")
9503 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9505 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9508 multiclass SIMDLdSt1SingleAliases<string asm> {
9509 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;
9510 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
9511 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
9512 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
9515 multiclass SIMDLdSt2SingleAliases<string asm> {
9516 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;
9517 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;
9518 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;
9519 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
9522 multiclass SIMDLdSt3SingleAliases<string asm> {
9523 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;
9524 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;
9525 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
9526 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
9529 multiclass SIMDLdSt4SingleAliases<string asm> {
9530 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;
9531 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;
9532 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
9533 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
9535 } // end of 'let Predicates = [HasNEON]'
9537 //----------------------------------------------------------------------------
9538 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
9539 //----------------------------------------------------------------------------
9541 let Predicates = [HasNEON, HasRDM] in {
9543 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
9544 RegisterOperand regtype, string asm,
9545 string kind, list<dag> pattern>
9546 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind,
9549 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
9550 SDPatternOperator Accum> {
9551 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
9552 [(set (v4i16 V64:$dst),
9553 (Accum (v4i16 V64:$Rd),
9554 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
9555 (v4i16 V64:$Rm)))))]>;
9556 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
9557 [(set (v8i16 V128:$dst),
9558 (Accum (v8i16 V128:$Rd),
9559 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
9560 (v8i16 V128:$Rm)))))]>;
9561 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
9562 [(set (v2i32 V64:$dst),
9563 (Accum (v2i32 V64:$Rd),
9564 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
9565 (v2i32 V64:$Rm)))))]>;
9566 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
9567 [(set (v4i32 V128:$dst),
9568 (Accum (v4i32 V128:$Rd),
9569 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
9570 (v4i32 V128:$Rm)))))]>;
9573 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
9574 SDPatternOperator Accum> {
9575 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
9576 V64, V64, V128_lo, VectorIndexH,
9577 asm, ".4h", ".4h", ".4h", ".h",
9578 [(set (v4i16 V64:$dst),
9579 (Accum (v4i16 V64:$Rd),
9580 (v4i16 (int_aarch64_neon_sqrdmulh
9582 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
9583 VectorIndexH:$idx))))))]> {
9585 let Inst{11} = idx{2};
9586 let Inst{21} = idx{1};
9587 let Inst{20} = idx{0};
9590 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
9591 V128, V128, V128_lo, VectorIndexH,
9592 asm, ".8h", ".8h", ".8h", ".h",
9593 [(set (v8i16 V128:$dst),
9594 (Accum (v8i16 V128:$Rd),
9595 (v8i16 (int_aarch64_neon_sqrdmulh
9597 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
9598 VectorIndexH:$idx))))))]> {
9600 let Inst{11} = idx{2};
9601 let Inst{21} = idx{1};
9602 let Inst{20} = idx{0};
9605 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
9606 V64, V64, V128, VectorIndexS,
9607 asm, ".2s", ".2s", ".2s", ".s",
9608 [(set (v2i32 V64:$dst),
9609 (Accum (v2i32 V64:$Rd),
9610 (v2i32 (int_aarch64_neon_sqrdmulh
9612 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
9613 VectorIndexS:$idx))))))]> {
9615 let Inst{11} = idx{1};
9616 let Inst{21} = idx{0};
9619 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
9620 // an intermediate EXTRACT_SUBREG would be untyped.
9621 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
9622 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
9623 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9624 (i32 (vector_extract
9625 (v4i32 (insert_subvector
9627 (v2i32 (int_aarch64_neon_sqrdmulh
9629 (v2i32 (AArch64duplane32
9631 VectorIndexS:$idx)))),
9635 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
9636 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
9641 VectorIndexS:$idx)),
9644 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
9645 V128, V128, V128, VectorIndexS,
9646 asm, ".4s", ".4s", ".4s", ".s",
9647 [(set (v4i32 V128:$dst),
9648 (Accum (v4i32 V128:$Rd),
9649 (v4i32 (int_aarch64_neon_sqrdmulh
9651 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
9652 VectorIndexS:$idx))))))]> {
9654 let Inst{11} = idx{1};
9655 let Inst{21} = idx{0};
9658 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
9659 // an intermediate EXTRACT_SUBREG would be untyped.
9660 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9661 (i32 (vector_extract
9662 (v4i32 (int_aarch64_neon_sqrdmulh
9664 (v4i32 (AArch64duplane32
9666 VectorIndexS:$idx)))),
9669 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
9670 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
9675 VectorIndexS:$idx)),
9678 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
9679 FPR16Op, FPR16Op, V128_lo,
9680 VectorIndexH, asm, ".h", "", "", ".h",
9683 let Inst{11} = idx{2};
9684 let Inst{21} = idx{1};
9685 let Inst{20} = idx{0};
9688 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
9689 FPR32Op, FPR32Op, V128, VectorIndexS,
9690 asm, ".s", "", "", ".s",
9691 [(set (i32 FPR32Op:$dst),
9692 (Accum (i32 FPR32Op:$Rd),
9693 (i32 (int_aarch64_neon_sqrdmulh
9695 (i32 (vector_extract (v4i32 V128:$Rm),
9696 VectorIndexS:$idx))))))]> {
9698 let Inst{11} = idx{1};
9699 let Inst{21} = idx{0};
9702 } // let Predicates = [HasNeon, HasRDM]
9704 //----------------------------------------------------------------------------
9705 // ARMv8.3 Complex ADD/MLA instructions
9706 //----------------------------------------------------------------------------
9708 class ComplexRotationOperand<int Angle, int Remainder, string Type>
9710 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">";
9711 let DiagnosticType = "InvalidComplexRotation" # Type;
9712 let Name = "ComplexRotation" # Type;
9714 def complexrotateop : Operand<i32> {
9715 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">;
9716 let PrintMethod = "printComplexRotationOp<90, 0>";
9718 def complexrotateopodd : Operand<i32> {
9719 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">;
9720 let PrintMethod = "printComplexRotationOp<180, 90>";
9723 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9724 class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode,
9725 RegisterOperand regtype, Operand rottype,
9726 string asm, string kind, list<dag> pattern>
9727 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
9728 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
9729 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>,
9738 let Inst{28-24} = 0b01110;
9739 let Inst{23-22} = size;
9741 let Inst{20-16} = Rm;
9742 let Inst{15-13} = opcode;
9743 // Non-tied version (FCADD) only has one rotation bit
9751 multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype,
9752 string asm, SDPatternOperator OpNode>{
9753 let Predicates = [HasV8_3a, HasNEON, HasFullFP16] in {
9754 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype,
9756 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
9759 (rottype i32:$rot)))]>;
9761 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype,
9763 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
9766 (rottype i32:$rot)))]>;
9769 let Predicates = [HasV8_3a, HasNEON] in {
9770 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype,
9772 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
9775 (rottype i32:$rot)))]>;
9777 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype,
9779 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
9782 (rottype i32:$rot)))]>;
9784 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype,
9786 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
9789 (rottype i32:$rot)))]>;
9793 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9794 class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size,
9796 RegisterOperand regtype,
9797 Operand rottype, string asm,
9798 string kind, list<dag> pattern>
9799 : I<(outs regtype:$dst),
9800 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
9801 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
9802 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>,
9811 let Inst{28-24} = 0b01110;
9812 let Inst{23-22} = size;
9814 let Inst{20-16} = Rm;
9815 let Inst{15-13} = opcode;
9816 let Inst{12-11} = rot;
9822 multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode,
9823 Operand rottype, string asm,
9824 SDPatternOperator OpNode> {
9825 let Predicates = [HasV8_3a, HasNEON, HasFullFP16] in {
9826 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64,
9827 rottype, asm, ".4h",
9828 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
9831 (rottype i32:$rot)))]>;
9833 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128,
9834 rottype, asm, ".8h",
9835 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
9838 (rottype i32:$rot)))]>;
9841 let Predicates = [HasV8_3a, HasNEON] in {
9842 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64,
9843 rottype, asm, ".2s",
9844 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
9847 (rottype i32:$rot)))]>;
9849 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128,
9850 rottype, asm, ".4s",
9851 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
9854 (rottype i32:$rot)))]>;
9856 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128,
9857 rottype, asm, ".2d",
9858 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
9861 (rottype i32:$rot)))]>;
9865 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9866 class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size,
9867 bit opc1, bit opc2, RegisterOperand dst_reg,
9868 RegisterOperand lhs_reg,
9869 RegisterOperand rhs_reg, Operand vec_idx,
9870 Operand rottype, string asm, string apple_kind,
9871 string dst_kind, string lhs_kind,
9872 string rhs_kind, list<dag> pattern>
9873 : I<(outs dst_reg:$dst),
9874 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot),
9876 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind #
9877 "$idx, $rot" # "|" # apple_kind #
9878 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>,
9888 let Inst{28} = Scalar;
9889 let Inst{27-24} = 0b1111;
9890 let Inst{23-22} = size;
9891 // Bit 21 must be set by the derived class.
9892 let Inst{20-16} = Rm;
9893 let Inst{15} = opc1;
9894 let Inst{14-13} = rot;
9895 let Inst{12} = opc2;
9896 // Bit 11 must be set by the derived class.
9902 // The complex instructions index by pairs of elements, so the VectorIndexes
9903 // don't match the lane types, and the index bits are different to the other
9905 multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype,
9906 string asm, SDPatternOperator OpNode> {
9907 let Predicates = [HasV8_3a,HasNEON,HasFullFP16] in {
9908 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64,
9909 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h",
9913 let Inst{21} = idx{0};
9916 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2,
9917 V128, V128, V128, VectorIndexS, rottype, asm, ".8h",
9918 ".8h", ".8h", ".h", []> {
9920 let Inst{11} = idx{1};
9921 let Inst{21} = idx{0};
9923 } // Predicates = [HasV8_3a,HasNEON,HasFullFP16]
9925 let Predicates = [HasV8_3a,HasNEON] in {
9926 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2,
9927 V128, V128, V128, VectorIndexD, rottype, asm, ".4s",
9928 ".4s", ".4s", ".s", []> {
9930 let Inst{11} = idx{0};
9933 } // Predicates = [HasV8_3a,HasNEON]
9936 //----------------------------------------------------------------------------
9937 // Crypto extensions
9938 //----------------------------------------------------------------------------
9940 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9941 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
9943 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
9947 let Inst{31-16} = 0b0100111000101000;
9948 let Inst{15-12} = opc;
9949 let Inst{11-10} = 0b10;
9954 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
9955 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
9956 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
9958 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
9959 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
9961 [(set (v16i8 V128:$dst),
9962 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
9964 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9965 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
9966 dag oops, dag iops, list<dag> pat>
9967 : I<oops, iops, asm,
9968 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
9969 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
9974 let Inst{31-21} = 0b01011110000;
9975 let Inst{20-16} = Rm;
9977 let Inst{14-12} = opc;
9978 let Inst{11-10} = 0b00;
9983 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
9984 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9985 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
9986 [(set (v4i32 FPR128:$dst),
9987 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
9988 (v4i32 V128:$Rm)))]>;
9990 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
9991 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
9992 (ins V128:$Rd, V128:$Rn, V128:$Rm),
9993 [(set (v4i32 V128:$dst),
9994 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9995 (v4i32 V128:$Rm)))]>;
9997 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
9998 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9999 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
10000 [(set (v4i32 FPR128:$dst),
10001 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
10002 (v4i32 V128:$Rm)))]>;
10004 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10005 class SHA2OpInst<bits<4> opc, string asm, string kind,
10006 string cstr, dag oops, dag iops,
10008 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
10009 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
10013 let Inst{31-16} = 0b0101111000101000;
10014 let Inst{15-12} = opc;
10015 let Inst{11-10} = 0b10;
10016 let Inst{9-5} = Rn;
10017 let Inst{4-0} = Rd;
10020 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
10021 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
10022 (ins V128:$Rd, V128:$Rn),
10023 [(set (v4i32 V128:$dst),
10024 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
10026 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
10027 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
10028 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
10030 // Armv8.2-A Crypto extensions
10031 class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst,
10033 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteV]> {
10036 let Inst{31-25} = 0b1100111;
10037 let Inst{9-5} = Vn;
10038 let Inst{4-0} = Vd;
10041 class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops>
10042 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, asmops,
10044 let Inst{31-25} = 0b1100111;
10045 let Inst{24-21} = 0b0110;
10046 let Inst{20-15} = 0b000001;
10047 let Inst{14} = op0;
10048 let Inst{13-12} = 0b00;
10049 let Inst{11-10} = op1;
10051 class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm>
10052 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d}">;
10053 class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm>
10054 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s}">;
10056 class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm,
10057 string asmops, string cst>
10058 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> {
10060 let Inst{24-21} = 0b0011;
10061 let Inst{20-16} = Vm;
10062 let Inst{15} = 0b1;
10063 let Inst{14} = op0;
10064 let Inst{13-12} = 0b00;
10065 let Inst{11-10} = op1;
10067 class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm>
10068 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
10069 "{\t$Vd.2d, $Vn.2d, $Vm.2d}", "">;
10070 class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm>
10071 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
10072 "{\t$Vd.2d, $Vn.2d, $Vm.2d}", "$Vd = $Vdst">;
10073 class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm>
10074 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
10075 "{\t$Vd.4s, $Vn.4s, $Vm.4s}", "">;
10076 class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm>
10077 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
10078 "{\t$Vd.4s, $Vn.4s, $Vm.4s}", "$Vd = $Vdst">;
10079 class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm>
10080 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm),
10081 asm, "{\t$Vd, $Vn, $Vm.2d}", "$Vd = $Vdst">;
10083 class CryptoRRRR<bits<2>op0, string asm, string asmops>
10084 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm,
10088 let Inst{24-23} = 0b00;
10089 let Inst{22-21} = op0;
10090 let Inst{20-16} = Vm;
10091 let Inst{15} = 0b0;
10092 let Inst{14-10} = Va;
10094 class CryptoRRRR_16B<bits<2>op0, string asm>
10095 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b}"> {
10097 class CryptoRRRR_4S<bits<2>op0, string asm>
10098 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s}"> {
10101 class CryptoRRRi6<string asm>
10102 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm,
10103 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm}", "", []> {
10106 let Inst{24-21} = 0b0100;
10107 let Inst{20-16} = Vm;
10108 let Inst{15-10} = imm;
10109 let Inst{9-5} = Vn;
10110 let Inst{4-0} = Vd;
10113 class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm>
10114 : BaseCryptoV82<(outs V128:$Vdst),
10115 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm),
10116 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm}", "$Vd = $Vdst", []> {
10119 let Inst{24-21} = 0b0010;
10120 let Inst{20-16} = Vm;
10121 let Inst{15} = 0b1;
10122 let Inst{14} = op0;
10123 let Inst{13-12} = imm;
10124 let Inst{11-10} = op1;
10127 //----------------------------------------------------------------------------
10128 // v8.1 atomic instructions extension:
10132 // * LDOPregister<OP>, and aliases STOPregister<OP>
10134 // Instruction encodings:
10136 // 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0
10137 // CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt
10138 // CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt
10139 // SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt
10140 // LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt
10141 // ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111
10143 // Instruction syntax:
10145 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10146 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
10147 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
10148 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
10149 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10150 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
10151 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10152 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
10153 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
10154 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
10156 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
10157 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
10158 string cstr, list<dag> pattern>
10159 : I<oops, iops, asm, operands, cstr, pattern> {
10167 let Inst{31-30} = Sz;
10168 let Inst{29-24} = 0b001000;
10170 let Inst{22} = Acq;
10171 let Inst{21} = 0b1;
10172 let Inst{20-16} = Rs;
10173 let Inst{15} = Rel;
10174 let Inst{14-10} = 0b11111;
10175 let Inst{9-5} = Rn;
10176 let Inst{4-0} = Rt;
10177 let Predicates = [HasLSE];
10180 class BaseCAS<string order, string size, RegisterClass RC>
10181 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
10182 "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
10184 Sched<[WriteAtomic]> {
10188 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
10189 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>;
10190 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>;
10191 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>;
10192 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>;
10195 class BaseCASP<string order, string size, RegisterOperand RC>
10196 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
10197 "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
10199 Sched<[WriteAtomic]> {
10203 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
10204 let Sz = 0b00, Acq = Acq, Rel = Rel in
10205 def W : BaseCASP<order, "", WSeqPairClassOperand>;
10206 let Sz = 0b01, Acq = Acq, Rel = Rel in
10207 def X : BaseCASP<order, "", XSeqPairClassOperand>;
10210 let Predicates = [HasLSE] in
10211 class BaseSWP<string order, string size, RegisterClass RC>
10212 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
10213 "\t$Rs, $Rt, [$Rn]","",[]>,
10214 Sched<[WriteAtomic]> {
10219 bits<3> opc = 0b000;
10222 let Inst{31-30} = Sz;
10223 let Inst{29-24} = 0b111000;
10224 let Inst{23} = Acq;
10225 let Inst{22} = Rel;
10226 let Inst{21} = 0b1;
10227 let Inst{20-16} = Rs;
10228 let Inst{15} = 0b1;
10229 let Inst{14-12} = opc;
10230 let Inst{11-10} = 0b00;
10231 let Inst{9-5} = Rn;
10232 let Inst{4-0} = Rt;
10233 let Predicates = [HasLSE];
10236 multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
10237 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>;
10238 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>;
10239 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>;
10240 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>;
10243 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
10244 class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
10245 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
10246 "\t$Rs, $Rt, [$Rn]","",[]>,
10247 Sched<[WriteAtomic]> {
10255 let Inst{31-30} = Sz;
10256 let Inst{29-24} = 0b111000;
10257 let Inst{23} = Acq;
10258 let Inst{22} = Rel;
10259 let Inst{21} = 0b1;
10260 let Inst{20-16} = Rs;
10261 let Inst{15} = 0b0;
10262 let Inst{14-12} = opc;
10263 let Inst{11-10} = 0b00;
10264 let Inst{9-5} = Rn;
10265 let Inst{4-0} = Rt;
10266 let Predicates = [HasLSE];
10269 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
10271 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
10272 def B : BaseLDOPregister<op, order, "b", GPR32>;
10273 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
10274 def H : BaseLDOPregister<op, order, "h", GPR32>;
10275 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
10276 def W : BaseLDOPregister<op, order, "", GPR32>;
10277 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
10278 def X : BaseLDOPregister<op, order, "", GPR64>;
10281 // Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more
10282 // complex DAG for DstRHS.
10283 let Predicates = [HasLSE] in
10284 multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op,
10285 string size, dag SrcRHS, dag DstRHS> {
10286 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS),
10287 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>;
10288 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS),
10289 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>;
10290 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS),
10291 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>;
10292 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS),
10293 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
10294 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS),
10295 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
10298 multiclass LDOPregister_patterns_ord<string inst, string suffix, string op,
10299 string size, dag RHS> {
10300 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>;
10303 multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op,
10304 string size, dag LHS, dag RHS> {
10305 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>;
10308 multiclass LDOPregister_patterns<string inst, string op> {
10309 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>;
10310 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>;
10311 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>;
10312 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>;
10315 multiclass LDOPregister_patterns_mod<string inst, string op, string mod> {
10316 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64",
10318 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>;
10319 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32",
10321 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
10322 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16",
10324 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
10325 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8",
10327 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
10330 let Predicates = [HasLSE] in
10331 multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op,
10332 string size, dag OLD, dag NEW> {
10333 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW),
10334 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>;
10335 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW),
10336 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10337 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW),
10338 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10339 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW),
10340 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10341 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW),
10342 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10345 multiclass CASregister_patterns_ord<string inst, string suffix, string op,
10346 string size, dag OLD, dag NEW> {
10347 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>;
10350 multiclass CASregister_patterns<string inst, string op> {
10351 defm : CASregister_patterns_ord<inst, "X", op, "64",
10352 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>;
10353 defm : CASregister_patterns_ord<inst, "W", op, "32",
10354 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
10355 defm : CASregister_patterns_ord<inst, "H", op, "16",
10356 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
10357 defm : CASregister_patterns_ord<inst, "B", op, "8",
10358 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
10361 let Predicates = [HasLSE] in
10362 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
10363 Instruction inst> :
10364 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
10366 multiclass STOPregister<string asm, string instr> {
10367 def : BaseSTOPregister<asm # "lb", GPR32, WZR,
10368 !cast<Instruction>(instr # "LB")>;
10369 def : BaseSTOPregister<asm # "lh", GPR32, WZR,
10370 !cast<Instruction>(instr # "LH")>;
10371 def : BaseSTOPregister<asm # "l", GPR32, WZR,
10372 !cast<Instruction>(instr # "LW")>;
10373 def : BaseSTOPregister<asm # "l", GPR64, XZR,
10374 !cast<Instruction>(instr # "LX")>;
10375 def : BaseSTOPregister<asm # "b", GPR32, WZR,
10376 !cast<Instruction>(instr # "B")>;
10377 def : BaseSTOPregister<asm # "h", GPR32, WZR,
10378 !cast<Instruction>(instr # "H")>;
10379 def : BaseSTOPregister<asm, GPR32, WZR,
10380 !cast<Instruction>(instr # "W")>;
10381 def : BaseSTOPregister<asm, GPR64, XZR,
10382 !cast<Instruction>(instr # "X")>;
10385 //----------------------------------------------------------------------------
10386 // Allow the size specifier tokens to be upper case, not just lower.
10387 def : TokenAlias<".4B", ".4b">; // Add dot product
10388 def : TokenAlias<".8B", ".8b">;
10389 def : TokenAlias<".4H", ".4h">;
10390 def : TokenAlias<".2S", ".2s">;
10391 def : TokenAlias<".1D", ".1d">;
10392 def : TokenAlias<".16B", ".16b">;
10393 def : TokenAlias<".8H", ".8h">;
10394 def : TokenAlias<".4S", ".4s">;
10395 def : TokenAlias<".2D", ".2d">;
10396 def : TokenAlias<".1Q", ".1q">;
10397 def : TokenAlias<".2H", ".2h">;
10398 def : TokenAlias<".B", ".b">;
10399 def : TokenAlias<".H", ".h">;
10400 def : TokenAlias<".S", ".s">;
10401 def : TokenAlias<".D", ".d">;
10402 def : TokenAlias<".Q", ".q">;