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 let Inst{23-22} = 0b11;
4644 let Predicates = [HasFullFP16];
4647 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
4648 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
4649 (i32 imm:$cond), NZCV))]> {
4650 let Inst{23-22} = 0b00;
4653 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
4654 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
4655 (i32 imm:$cond), NZCV))]> {
4656 let Inst{23-22} = 0b01;
4661 // Floating point conditional select
4664 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
4665 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
4666 asm, "\t$Rd, $Rn, $Rm, $cond", "",
4668 (AArch64csel (vt regtype:$Rn), regtype:$Rm,
4669 (i32 imm:$cond), NZCV))]>,
4676 let Inst{31-24} = 0b00011110;
4678 let Inst{20-16} = Rm;
4679 let Inst{15-12} = cond;
4680 let Inst{11-10} = 0b11;
4685 multiclass FPCondSelect<string asm> {
4686 let Uses = [NZCV] in {
4687 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
4688 let Inst{23-22} = 0b11;
4689 let Predicates = [HasFullFP16];
4692 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
4693 let Inst{23-22} = 0b00;
4696 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
4697 let Inst{23-22} = 0b01;
4703 // Floating move immediate
4706 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
4707 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
4708 [(set regtype:$Rd, fpimmtype:$imm)]>,
4709 Sched<[WriteFImm]> {
4712 let Inst{31-24} = 0b00011110;
4714 let Inst{20-13} = imm;
4715 let Inst{12-5} = 0b10000000;
4719 multiclass FPMoveImmediate<string asm> {
4720 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
4721 let Inst{23-22} = 0b11;
4722 let Predicates = [HasFullFP16];
4725 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
4726 let Inst{23-22} = 0b00;
4729 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
4730 let Inst{23-22} = 0b01;
4733 } // end of 'let Predicates = [HasFPARMv8]'
4735 //----------------------------------------------------------------------------
4737 //----------------------------------------------------------------------------
4739 let Predicates = [HasNEON] in {
4741 //----------------------------------------------------------------------------
4742 // AdvSIMD three register vector instructions
4743 //----------------------------------------------------------------------------
4745 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4746 class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
4747 RegisterOperand regtype, string asm, string kind,
4749 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4750 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4751 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
4759 let Inst{28-24} = 0b01110;
4760 let Inst{23-21} = size;
4761 let Inst{20-16} = Rm;
4762 let Inst{15-11} = opcode;
4768 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4769 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
4770 RegisterOperand regtype, string asm, string kind,
4772 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
4773 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4774 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4782 let Inst{28-24} = 0b01110;
4783 let Inst{23-21} = size;
4784 let Inst{20-16} = Rm;
4785 let Inst{15-11} = opcode;
4791 class BaseSIMDThreeSameVectorDot<bit Q, bit U, string asm, string kind1,
4792 string kind2, RegisterOperand RegType,
4793 ValueType AccumType, ValueType InputType,
4794 SDPatternOperator OpNode> :
4795 BaseSIMDThreeSameVectorTied<Q, U, 0b100, 0b10010, RegType, asm, kind1,
4796 [(set (AccumType RegType:$dst),
4797 (OpNode (AccumType RegType:$Rd),
4798 (InputType RegType:$Rn),
4799 (InputType RegType:$Rm)))]> {
4800 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
4803 multiclass SIMDThreeSameVectorDot<bit U, string asm, SDPatternOperator OpNode> {
4804 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, asm, ".2s", ".8b", V64,
4805 v2i32, v8i8, OpNode>;
4806 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, asm, ".4s", ".16b", V128,
4807 v4i32, v16i8, OpNode>;
4810 // All operand sizes distinguished in the encoding.
4811 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
4812 SDPatternOperator OpNode> {
4813 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4815 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4816 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4818 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4819 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4821 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4822 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4824 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4825 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4827 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4828 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4830 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4831 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
4833 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4836 // As above, but D sized elements unsupported.
4837 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
4838 SDPatternOperator OpNode> {
4839 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4841 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
4842 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4844 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
4845 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4847 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
4848 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4850 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
4851 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4853 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
4854 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4856 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
4859 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
4860 SDPatternOperator OpNode> {
4861 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
4863 [(set (v8i8 V64:$dst),
4864 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4865 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
4867 [(set (v16i8 V128:$dst),
4868 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4869 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
4871 [(set (v4i16 V64:$dst),
4872 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4873 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
4875 [(set (v8i16 V128:$dst),
4876 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4877 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
4879 [(set (v2i32 V64:$dst),
4880 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4881 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
4883 [(set (v4i32 V128:$dst),
4884 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4887 // As above, but only B sized elements supported.
4888 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
4889 SDPatternOperator OpNode> {
4890 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4892 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4893 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4895 [(set (v16i8 V128:$Rd),
4896 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4899 // As above, but only floating point elements supported.
4900 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
4901 string asm, SDPatternOperator OpNode> {
4902 let Predicates = [HasNEON, HasFullFP16] in {
4903 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
4905 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4906 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
4908 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4909 } // Predicates = [HasNEON, HasFullFP16]
4910 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
4912 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4913 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
4915 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4916 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
4918 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4921 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
4923 SDPatternOperator OpNode> {
4924 let Predicates = [HasNEON, HasFullFP16] in {
4925 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
4927 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4928 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
4930 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4931 } // Predicates = [HasNEON, HasFullFP16]
4932 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
4934 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4935 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
4937 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4938 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
4940 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4943 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
4944 string asm, SDPatternOperator OpNode> {
4945 let Predicates = [HasNEON, HasFullFP16] in {
4946 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
4948 [(set (v4f16 V64:$dst),
4949 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4950 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
4952 [(set (v8f16 V128:$dst),
4953 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4954 } // Predicates = [HasNEON, HasFullFP16]
4955 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
4957 [(set (v2f32 V64:$dst),
4958 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4959 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
4961 [(set (v4f32 V128:$dst),
4962 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4963 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
4965 [(set (v2f64 V128:$dst),
4966 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4969 // As above, but D and B sized elements unsupported.
4970 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
4971 SDPatternOperator OpNode> {
4972 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4974 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4975 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4977 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4978 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4980 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4981 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4983 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4986 // Logical three vector ops share opcode bits, and only use B sized elements.
4987 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
4988 SDPatternOperator OpNode = null_frag> {
4989 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
4991 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
4992 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
4994 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
4996 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
4997 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4998 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
4999 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5000 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
5001 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
5003 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
5004 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5005 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
5006 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5007 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
5008 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
5011 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
5012 string asm, SDPatternOperator OpNode> {
5013 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
5015 [(set (v8i8 V64:$dst),
5016 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5017 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
5019 [(set (v16i8 V128:$dst),
5020 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
5021 (v16i8 V128:$Rm)))]>;
5023 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
5025 (!cast<Instruction>(NAME#"v8i8")
5026 V64:$LHS, V64:$MHS, V64:$RHS)>;
5027 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
5029 (!cast<Instruction>(NAME#"v8i8")
5030 V64:$LHS, V64:$MHS, V64:$RHS)>;
5031 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
5033 (!cast<Instruction>(NAME#"v8i8")
5034 V64:$LHS, V64:$MHS, V64:$RHS)>;
5036 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
5037 (v8i16 V128:$RHS))),
5038 (!cast<Instruction>(NAME#"v16i8")
5039 V128:$LHS, V128:$MHS, V128:$RHS)>;
5040 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
5041 (v4i32 V128:$RHS))),
5042 (!cast<Instruction>(NAME#"v16i8")
5043 V128:$LHS, V128:$MHS, V128:$RHS)>;
5044 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
5045 (v2i64 V128:$RHS))),
5046 (!cast<Instruction>(NAME#"v16i8")
5047 V128:$LHS, V128:$MHS, V128:$RHS)>;
5051 //----------------------------------------------------------------------------
5052 // AdvSIMD two register vector instructions.
5053 //----------------------------------------------------------------------------
5055 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5056 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5057 bits<2> size2, RegisterOperand regtype, string asm,
5058 string dstkind, string srckind, list<dag> pattern>
5059 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5060 "{\t$Rd" # dstkind # ", $Rn" # srckind #
5061 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
5068 let Inst{28-24} = 0b01110;
5069 let Inst{23-22} = size;
5071 let Inst{20-19} = size2;
5072 let Inst{18-17} = 0b00;
5073 let Inst{16-12} = opcode;
5074 let Inst{11-10} = 0b10;
5079 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5080 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5081 bits<2> size2, RegisterOperand regtype,
5082 string asm, string dstkind, string srckind,
5084 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
5085 "{\t$Rd" # dstkind # ", $Rn" # srckind #
5086 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
5093 let Inst{28-24} = 0b01110;
5094 let Inst{23-22} = size;
5096 let Inst{20-19} = size2;
5097 let Inst{18-17} = 0b00;
5098 let Inst{16-12} = opcode;
5099 let Inst{11-10} = 0b10;
5104 // Supports B, H, and S element sizes.
5105 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
5106 SDPatternOperator OpNode> {
5107 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5109 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5110 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5111 asm, ".16b", ".16b",
5112 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5113 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5115 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5116 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5118 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5119 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5121 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5122 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5124 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5127 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
5128 RegisterOperand regtype, string asm, string dstkind,
5129 string srckind, string amount>
5130 : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
5131 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
5132 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,
5138 let Inst{29-24} = 0b101110;
5139 let Inst{23-22} = size;
5140 let Inst{21-10} = 0b100001001110;
5145 multiclass SIMDVectorLShiftLongBySizeBHS {
5146 let hasSideEffects = 0 in {
5147 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
5148 "shll", ".8h", ".8b", "8">;
5149 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
5150 "shll2", ".8h", ".16b", "8">;
5151 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
5152 "shll", ".4s", ".4h", "16">;
5153 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
5154 "shll2", ".4s", ".8h", "16">;
5155 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
5156 "shll", ".2d", ".2s", "32">;
5157 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
5158 "shll2", ".2d", ".4s", "32">;
5162 // Supports all element sizes.
5163 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
5164 SDPatternOperator OpNode> {
5165 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5167 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5168 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5170 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5171 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5173 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5174 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5176 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5177 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5179 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5180 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5182 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5185 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
5186 SDPatternOperator OpNode> {
5187 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
5189 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
5191 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
5193 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
5194 (v16i8 V128:$Rn)))]>;
5195 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
5197 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
5198 (v4i16 V64:$Rn)))]>;
5199 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
5201 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
5202 (v8i16 V128:$Rn)))]>;
5203 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
5205 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
5206 (v2i32 V64:$Rn)))]>;
5207 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
5209 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
5210 (v4i32 V128:$Rn)))]>;
5213 // Supports all element sizes, except 1xD.
5214 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
5215 SDPatternOperator OpNode> {
5216 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
5218 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
5219 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
5220 asm, ".16b", ".16b",
5221 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
5222 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
5224 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
5225 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
5227 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
5228 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
5230 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
5231 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
5233 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
5234 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
5236 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
5239 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
5240 SDPatternOperator OpNode = null_frag> {
5241 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5243 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5244 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5245 asm, ".16b", ".16b",
5246 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5247 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5249 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5250 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5252 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5253 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5255 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5256 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5258 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5259 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
5261 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5265 // Supports only B element sizes.
5266 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
5267 SDPatternOperator OpNode> {
5268 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
5270 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5271 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
5272 asm, ".16b", ".16b",
5273 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5277 // Supports only B and H element sizes.
5278 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
5279 SDPatternOperator OpNode> {
5280 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5282 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
5283 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5284 asm, ".16b", ".16b",
5285 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
5286 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5288 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
5289 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5291 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
5294 // Supports only S and D element sizes, uses high bit of the size field
5295 // as an extra opcode bit.
5296 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
5297 SDPatternOperator OpNode> {
5298 let Predicates = [HasNEON, HasFullFP16] in {
5299 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5301 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5302 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5304 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5305 } // Predicates = [HasNEON, HasFullFP16]
5306 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5308 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5309 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5311 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5312 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5314 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5317 // Supports only S element size.
5318 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
5319 SDPatternOperator OpNode> {
5320 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5322 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5323 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5325 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5329 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
5330 SDPatternOperator OpNode> {
5331 let Predicates = [HasNEON, HasFullFP16] in {
5332 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5334 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5335 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5337 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5338 } // Predicates = [HasNEON, HasFullFP16]
5339 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5341 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5342 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5344 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5345 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5347 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5350 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
5351 SDPatternOperator OpNode> {
5352 let Predicates = [HasNEON, HasFullFP16] in {
5353 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5355 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5356 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5358 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5359 } // Predicates = [HasNEON, HasFullFP16]
5360 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5362 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5363 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5365 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5366 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5368 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5372 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5373 RegisterOperand inreg, RegisterOperand outreg,
5374 string asm, string outkind, string inkind,
5376 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
5377 "{\t$Rd" # outkind # ", $Rn" # inkind #
5378 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
5385 let Inst{28-24} = 0b01110;
5386 let Inst{23-22} = size;
5387 let Inst{21-17} = 0b10000;
5388 let Inst{16-12} = opcode;
5389 let Inst{11-10} = 0b10;
5394 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5395 RegisterOperand inreg, RegisterOperand outreg,
5396 string asm, string outkind, string inkind,
5398 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
5399 "{\t$Rd" # outkind # ", $Rn" # inkind #
5400 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
5407 let Inst{28-24} = 0b01110;
5408 let Inst{23-22} = size;
5409 let Inst{21-17} = 0b10000;
5410 let Inst{16-12} = opcode;
5411 let Inst{11-10} = 0b10;
5416 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
5417 SDPatternOperator OpNode> {
5418 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
5420 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5421 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
5422 asm#"2", ".16b", ".8h", []>;
5423 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
5425 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5426 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
5427 asm#"2", ".8h", ".4s", []>;
5428 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
5430 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5431 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
5432 asm#"2", ".4s", ".2d", []>;
5434 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
5435 (!cast<Instruction>(NAME # "v16i8")
5436 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5437 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
5438 (!cast<Instruction>(NAME # "v8i16")
5439 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5440 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
5441 (!cast<Instruction>(NAME # "v4i32")
5442 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5445 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
5446 bits<5> opcode, RegisterOperand regtype, string asm,
5447 string kind, string zero, ValueType dty,
5448 ValueType sty, SDNode OpNode>
5449 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5450 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
5451 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
5452 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
5459 let Inst{28-24} = 0b01110;
5460 let Inst{23-22} = size;
5462 let Inst{20-19} = size2;
5463 let Inst{18-17} = 0b00;
5464 let Inst{16-12} = opcode;
5465 let Inst{11-10} = 0b10;
5470 // Comparisons support all element sizes, except 1xD.
5471 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
5473 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
5475 v8i8, v8i8, OpNode>;
5476 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
5478 v16i8, v16i8, OpNode>;
5479 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
5481 v4i16, v4i16, OpNode>;
5482 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
5484 v8i16, v8i16, OpNode>;
5485 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
5487 v2i32, v2i32, OpNode>;
5488 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
5490 v4i32, v4i32, OpNode>;
5491 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
5493 v2i64, v2i64, OpNode>;
5496 // FP Comparisons support only S and D element sizes (and H for v8.2a).
5497 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
5498 string asm, SDNode OpNode> {
5500 let Predicates = [HasNEON, HasFullFP16] in {
5501 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
5503 v4i16, v4f16, OpNode>;
5504 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
5506 v8i16, v8f16, OpNode>;
5507 } // Predicates = [HasNEON, HasFullFP16]
5508 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
5510 v2i32, v2f32, OpNode>;
5511 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
5513 v4i32, v4f32, OpNode>;
5514 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
5516 v2i64, v2f64, OpNode>;
5518 let Predicates = [HasNEON, HasFullFP16] in {
5519 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
5520 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5521 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
5522 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5524 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
5525 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
5526 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
5527 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
5528 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
5529 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5530 let Predicates = [HasNEON, HasFullFP16] in {
5531 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
5532 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5533 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
5534 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5536 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
5537 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
5538 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
5539 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
5540 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
5541 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5544 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5545 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5546 RegisterOperand outtype, RegisterOperand intype,
5547 string asm, string VdTy, string VnTy,
5549 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
5550 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
5557 let Inst{28-24} = 0b01110;
5558 let Inst{23-22} = size;
5559 let Inst{21-17} = 0b10000;
5560 let Inst{16-12} = opcode;
5561 let Inst{11-10} = 0b10;
5566 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5567 RegisterOperand outtype, RegisterOperand intype,
5568 string asm, string VdTy, string VnTy,
5570 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
5571 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
5578 let Inst{28-24} = 0b01110;
5579 let Inst{23-22} = size;
5580 let Inst{21-17} = 0b10000;
5581 let Inst{16-12} = opcode;
5582 let Inst{11-10} = 0b10;
5587 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
5588 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
5589 asm, ".4s", ".4h", []>;
5590 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
5591 asm#"2", ".4s", ".8h", []>;
5592 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
5593 asm, ".2d", ".2s", []>;
5594 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
5595 asm#"2", ".2d", ".4s", []>;
5598 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
5599 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
5600 asm, ".4h", ".4s", []>;
5601 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
5602 asm#"2", ".8h", ".4s", []>;
5603 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5604 asm, ".2s", ".2d", []>;
5605 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5606 asm#"2", ".4s", ".2d", []>;
5609 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
5611 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5613 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5614 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5615 asm#"2", ".4s", ".2d", []>;
5617 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
5618 (!cast<Instruction>(NAME # "v4f32")
5619 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5622 //----------------------------------------------------------------------------
5623 // AdvSIMD three register different-size vector instructions.
5624 //----------------------------------------------------------------------------
5626 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5627 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
5628 RegisterOperand outtype, RegisterOperand intype1,
5629 RegisterOperand intype2, string asm,
5630 string outkind, string inkind1, string inkind2,
5632 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
5633 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5634 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
5640 let Inst{30} = size{0};
5642 let Inst{28-24} = 0b01110;
5643 let Inst{23-22} = size{2-1};
5645 let Inst{20-16} = Rm;
5646 let Inst{15-12} = opcode;
5647 let Inst{11-10} = 0b00;
5652 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5653 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
5654 RegisterOperand outtype, RegisterOperand intype1,
5655 RegisterOperand intype2, string asm,
5656 string outkind, string inkind1, string inkind2,
5658 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
5659 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5660 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
5666 let Inst{30} = size{0};
5668 let Inst{28-24} = 0b01110;
5669 let Inst{23-22} = size{2-1};
5671 let Inst{20-16} = Rm;
5672 let Inst{15-12} = opcode;
5673 let Inst{11-10} = 0b00;
5678 // FIXME: TableGen doesn't know how to deal with expanded types that also
5679 // change the element count (in this case, placing the results in
5680 // the high elements of the result register rather than the low
5681 // elements). Until that's fixed, we can't code-gen those.
5682 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
5684 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5686 asm, ".8b", ".8h", ".8h",
5687 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5688 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5690 asm#"2", ".16b", ".8h", ".8h",
5692 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5694 asm, ".4h", ".4s", ".4s",
5695 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5696 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5698 asm#"2", ".8h", ".4s", ".4s",
5700 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5702 asm, ".2s", ".2d", ".2d",
5703 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5704 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5706 asm#"2", ".4s", ".2d", ".2d",
5710 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
5711 // a version attached to an instruction.
5712 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
5714 (!cast<Instruction>(NAME # "v8i16_v16i8")
5715 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5716 V128:$Rn, V128:$Rm)>;
5717 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
5719 (!cast<Instruction>(NAME # "v4i32_v8i16")
5720 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5721 V128:$Rn, V128:$Rm)>;
5722 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
5724 (!cast<Instruction>(NAME # "v2i64_v4i32")
5725 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5726 V128:$Rn, V128:$Rm)>;
5729 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
5731 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5733 asm, ".8h", ".8b", ".8b",
5734 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5735 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5737 asm#"2", ".8h", ".16b", ".16b", []>;
5738 let Predicates = [HasAES] in {
5739 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
5741 asm, ".1q", ".1d", ".1d", []>;
5742 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
5744 asm#"2", ".1q", ".2d", ".2d", []>;
5747 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
5748 (v8i8 (extract_high_v16i8 V128:$Rm)))),
5749 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
5752 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
5753 SDPatternOperator OpNode> {
5754 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5756 asm, ".4s", ".4h", ".4h",
5757 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5758 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5760 asm#"2", ".4s", ".8h", ".8h",
5761 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5762 (extract_high_v8i16 V128:$Rm)))]>;
5763 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5765 asm, ".2d", ".2s", ".2s",
5766 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5767 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5769 asm#"2", ".2d", ".4s", ".4s",
5770 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5771 (extract_high_v4i32 V128:$Rm)))]>;
5774 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
5775 SDPatternOperator OpNode = null_frag> {
5776 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5778 asm, ".8h", ".8b", ".8b",
5779 [(set (v8i16 V128:$Rd),
5780 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
5781 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5783 asm#"2", ".8h", ".16b", ".16b",
5784 [(set (v8i16 V128:$Rd),
5785 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5786 (extract_high_v16i8 V128:$Rm)))))]>;
5787 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5789 asm, ".4s", ".4h", ".4h",
5790 [(set (v4i32 V128:$Rd),
5791 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
5792 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5794 asm#"2", ".4s", ".8h", ".8h",
5795 [(set (v4i32 V128:$Rd),
5796 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5797 (extract_high_v8i16 V128:$Rm)))))]>;
5798 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5800 asm, ".2d", ".2s", ".2s",
5801 [(set (v2i64 V128:$Rd),
5802 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
5803 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5805 asm#"2", ".2d", ".4s", ".4s",
5806 [(set (v2i64 V128:$Rd),
5807 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5808 (extract_high_v4i32 V128:$Rm)))))]>;
5811 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
5813 SDPatternOperator OpNode> {
5814 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5816 asm, ".8h", ".8b", ".8b",
5817 [(set (v8i16 V128:$dst),
5818 (add (v8i16 V128:$Rd),
5819 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
5820 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5822 asm#"2", ".8h", ".16b", ".16b",
5823 [(set (v8i16 V128:$dst),
5824 (add (v8i16 V128:$Rd),
5825 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5826 (extract_high_v16i8 V128:$Rm))))))]>;
5827 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5829 asm, ".4s", ".4h", ".4h",
5830 [(set (v4i32 V128:$dst),
5831 (add (v4i32 V128:$Rd),
5832 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
5833 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5835 asm#"2", ".4s", ".8h", ".8h",
5836 [(set (v4i32 V128:$dst),
5837 (add (v4i32 V128:$Rd),
5838 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5839 (extract_high_v8i16 V128:$Rm))))))]>;
5840 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5842 asm, ".2d", ".2s", ".2s",
5843 [(set (v2i64 V128:$dst),
5844 (add (v2i64 V128:$Rd),
5845 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
5846 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5848 asm#"2", ".2d", ".4s", ".4s",
5849 [(set (v2i64 V128:$dst),
5850 (add (v2i64 V128:$Rd),
5851 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5852 (extract_high_v4i32 V128:$Rm))))))]>;
5855 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
5856 SDPatternOperator OpNode = null_frag> {
5857 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5859 asm, ".8h", ".8b", ".8b",
5860 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5861 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5863 asm#"2", ".8h", ".16b", ".16b",
5864 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
5865 (extract_high_v16i8 V128:$Rm)))]>;
5866 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5868 asm, ".4s", ".4h", ".4h",
5869 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5870 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5872 asm#"2", ".4s", ".8h", ".8h",
5873 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5874 (extract_high_v8i16 V128:$Rm)))]>;
5875 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5877 asm, ".2d", ".2s", ".2s",
5878 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5879 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5881 asm#"2", ".2d", ".4s", ".4s",
5882 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5883 (extract_high_v4i32 V128:$Rm)))]>;
5886 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
5888 SDPatternOperator OpNode> {
5889 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5891 asm, ".8h", ".8b", ".8b",
5892 [(set (v8i16 V128:$dst),
5893 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5894 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5896 asm#"2", ".8h", ".16b", ".16b",
5897 [(set (v8i16 V128:$dst),
5898 (OpNode (v8i16 V128:$Rd),
5899 (extract_high_v16i8 V128:$Rn),
5900 (extract_high_v16i8 V128:$Rm)))]>;
5901 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5903 asm, ".4s", ".4h", ".4h",
5904 [(set (v4i32 V128:$dst),
5905 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5906 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5908 asm#"2", ".4s", ".8h", ".8h",
5909 [(set (v4i32 V128:$dst),
5910 (OpNode (v4i32 V128:$Rd),
5911 (extract_high_v8i16 V128:$Rn),
5912 (extract_high_v8i16 V128:$Rm)))]>;
5913 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5915 asm, ".2d", ".2s", ".2s",
5916 [(set (v2i64 V128:$dst),
5917 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5918 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5920 asm#"2", ".2d", ".4s", ".4s",
5921 [(set (v2i64 V128:$dst),
5922 (OpNode (v2i64 V128:$Rd),
5923 (extract_high_v4i32 V128:$Rn),
5924 (extract_high_v4i32 V128:$Rm)))]>;
5927 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
5928 SDPatternOperator Accum> {
5929 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5931 asm, ".4s", ".4h", ".4h",
5932 [(set (v4i32 V128:$dst),
5933 (Accum (v4i32 V128:$Rd),
5934 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
5935 (v4i16 V64:$Rm)))))]>;
5936 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5938 asm#"2", ".4s", ".8h", ".8h",
5939 [(set (v4i32 V128:$dst),
5940 (Accum (v4i32 V128:$Rd),
5941 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
5942 (extract_high_v8i16 V128:$Rm)))))]>;
5943 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5945 asm, ".2d", ".2s", ".2s",
5946 [(set (v2i64 V128:$dst),
5947 (Accum (v2i64 V128:$Rd),
5948 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
5949 (v2i32 V64:$Rm)))))]>;
5950 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5952 asm#"2", ".2d", ".4s", ".4s",
5953 [(set (v2i64 V128:$dst),
5954 (Accum (v2i64 V128:$Rd),
5955 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
5956 (extract_high_v4i32 V128:$Rm)))))]>;
5959 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
5960 SDPatternOperator OpNode> {
5961 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5963 asm, ".8h", ".8h", ".8b",
5964 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
5965 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5967 asm#"2", ".8h", ".8h", ".16b",
5968 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
5969 (extract_high_v16i8 V128:$Rm)))]>;
5970 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5972 asm, ".4s", ".4s", ".4h",
5973 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
5974 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5976 asm#"2", ".4s", ".4s", ".8h",
5977 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
5978 (extract_high_v8i16 V128:$Rm)))]>;
5979 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5981 asm, ".2d", ".2d", ".2s",
5982 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
5983 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5985 asm#"2", ".2d", ".2d", ".4s",
5986 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
5987 (extract_high_v4i32 V128:$Rm)))]>;
5990 //----------------------------------------------------------------------------
5991 // AdvSIMD bitwise extract from vector
5992 //----------------------------------------------------------------------------
5994 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
5995 string asm, string kind>
5996 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
5997 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
5998 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
5999 [(set (vty regtype:$Rd),
6000 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
6007 let Inst{30} = size;
6008 let Inst{29-21} = 0b101110000;
6009 let Inst{20-16} = Rm;
6011 let Inst{14-11} = imm;
6018 multiclass SIMDBitwiseExtract<string asm> {
6019 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
6022 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
6025 //----------------------------------------------------------------------------
6026 // AdvSIMD zip vector
6027 //----------------------------------------------------------------------------
6029 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
6030 string asm, string kind, SDNode OpNode, ValueType valty>
6031 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
6032 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
6033 "|" # kind # "\t$Rd, $Rn, $Rm}", "",
6034 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
6040 let Inst{30} = size{0};
6041 let Inst{29-24} = 0b001110;
6042 let Inst{23-22} = size{2-1};
6044 let Inst{20-16} = Rm;
6046 let Inst{14-12} = opc;
6047 let Inst{11-10} = 0b10;
6052 multiclass SIMDZipVector<bits<3>opc, string asm,
6054 def v8i8 : BaseSIMDZipVector<0b000, opc, V64,
6055 asm, ".8b", OpNode, v8i8>;
6056 def v16i8 : BaseSIMDZipVector<0b001, opc, V128,
6057 asm, ".16b", OpNode, v16i8>;
6058 def v4i16 : BaseSIMDZipVector<0b010, opc, V64,
6059 asm, ".4h", OpNode, v4i16>;
6060 def v8i16 : BaseSIMDZipVector<0b011, opc, V128,
6061 asm, ".8h", OpNode, v8i16>;
6062 def v2i32 : BaseSIMDZipVector<0b100, opc, V64,
6063 asm, ".2s", OpNode, v2i32>;
6064 def v4i32 : BaseSIMDZipVector<0b101, opc, V128,
6065 asm, ".4s", OpNode, v4i32>;
6066 def v2i64 : BaseSIMDZipVector<0b111, opc, V128,
6067 asm, ".2d", OpNode, v2i64>;
6069 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
6070 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
6071 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
6072 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
6073 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
6074 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
6075 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
6076 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
6077 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
6078 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
6081 //----------------------------------------------------------------------------
6082 // AdvSIMD three register scalar instructions
6083 //----------------------------------------------------------------------------
6085 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6086 class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
6087 RegisterClass regtype, string asm,
6089 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
6090 "\t$Rd, $Rn, $Rm", "", pattern>,
6095 let Inst{31-30} = 0b01;
6097 let Inst{28-24} = 0b11110;
6098 let Inst{23-21} = size;
6099 let Inst{20-16} = Rm;
6100 let Inst{15-11} = opcode;
6106 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6107 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
6108 dag oops, dag iops, string asm,
6110 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
6115 let Inst{31-30} = 0b01;
6117 let Inst{28-24} = 0b11110;
6118 let Inst{23-22} = size;
6120 let Inst{20-16} = Rm;
6121 let Inst{15-11} = opcode;
6127 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
6128 SDPatternOperator OpNode> {
6129 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
6130 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
6133 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
6134 SDPatternOperator OpNode> {
6135 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
6136 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
6137 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
6138 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
6139 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
6141 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
6142 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
6143 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
6144 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
6147 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
6148 SDPatternOperator OpNode> {
6149 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
6150 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
6151 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
6154 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
6155 SDPatternOperator OpNode = null_frag> {
6156 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
6157 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
6159 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
6160 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
6164 multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
6165 SDPatternOperator OpNode = null_frag> {
6166 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6167 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
6168 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
6169 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
6170 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
6171 let Predicates = [HasNEON, HasFullFP16] in {
6172 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
6173 [(set FPR16:$Rd, (OpNode FPR16:$Rn, FPR16:$Rm))]>;
6174 } // Predicates = [HasNEON, HasFullFP16]
6177 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
6178 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
6181 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
6182 SDPatternOperator OpNode = null_frag> {
6183 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6184 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
6185 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
6186 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
6187 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
6188 let Predicates = [HasNEON, HasFullFP16] in {
6189 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
6191 } // Predicates = [HasNEON, HasFullFP16]
6194 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
6195 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
6198 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
6199 dag oops, dag iops, string asm, string cstr, list<dag> pat>
6200 : I<oops, iops, asm,
6201 "\t$Rd, $Rn, $Rm", cstr, pat>,
6206 let Inst{31-30} = 0b01;
6208 let Inst{28-24} = 0b11110;
6209 let Inst{23-22} = size;
6211 let Inst{20-16} = Rm;
6212 let Inst{15-11} = opcode;
6218 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6219 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
6220 SDPatternOperator OpNode = null_frag> {
6221 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
6223 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
6224 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
6226 (ins FPR32:$Rn, FPR32:$Rm), asm, "",
6227 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
6230 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6231 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
6232 SDPatternOperator OpNode = null_frag> {
6233 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
6235 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
6236 asm, "$Rd = $dst", []>;
6237 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
6239 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
6241 [(set (i64 FPR64:$dst),
6242 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
6245 //----------------------------------------------------------------------------
6246 // AdvSIMD two register scalar instructions
6247 //----------------------------------------------------------------------------
6249 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6250 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6251 RegisterClass regtype, RegisterClass regtype2,
6252 string asm, list<dag> pat>
6253 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
6254 "\t$Rd, $Rn", "", pat>,
6258 let Inst{31-30} = 0b01;
6260 let Inst{28-24} = 0b11110;
6261 let Inst{23-22} = size;
6263 let Inst{20-19} = size2;
6264 let Inst{18-17} = 0b00;
6265 let Inst{16-12} = opcode;
6266 let Inst{11-10} = 0b10;
6271 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6272 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
6273 RegisterClass regtype, RegisterClass regtype2,
6274 string asm, list<dag> pat>
6275 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
6276 "\t$Rd, $Rn", "$Rd = $dst", pat>,
6280 let Inst{31-30} = 0b01;
6282 let Inst{28-24} = 0b11110;
6283 let Inst{23-22} = size;
6284 let Inst{21-17} = 0b10000;
6285 let Inst{16-12} = opcode;
6286 let Inst{11-10} = 0b10;
6292 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6293 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6294 RegisterClass regtype, string asm, string zero>
6295 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
6296 "\t$Rd, $Rn, #" # zero, "", []>,
6300 let Inst{31-30} = 0b01;
6302 let Inst{28-24} = 0b11110;
6303 let Inst{23-22} = size;
6305 let Inst{20-19} = size2;
6306 let Inst{18-17} = 0b00;
6307 let Inst{16-12} = opcode;
6308 let Inst{11-10} = 0b10;
6313 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
6314 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
6315 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
6319 let Inst{31-17} = 0b011111100110000;
6320 let Inst{16-12} = opcode;
6321 let Inst{11-10} = 0b10;
6326 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
6327 SDPatternOperator OpNode> {
6328 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
6330 def : Pat<(v1i64 (OpNode FPR64:$Rn)),
6331 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6334 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
6335 SDPatternOperator OpNode> {
6336 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
6337 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
6338 let Predicates = [HasNEON, HasFullFP16] in {
6339 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
6342 def : InstAlias<asm # "\t$Rd, $Rn, #0",
6343 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
6344 def : InstAlias<asm # "\t$Rd, $Rn, #0",
6345 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
6346 let Predicates = [HasNEON, HasFullFP16] in {
6347 def : InstAlias<asm # "\t$Rd, $Rn, #0",
6348 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
6351 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
6352 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6355 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
6356 SDPatternOperator OpNode = null_frag> {
6357 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
6358 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
6360 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
6361 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
6364 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
6365 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
6366 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
6367 let Predicates = [HasNEON, HasFullFP16] in {
6368 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
6372 multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
6373 SDPatternOperator OpNode> {
6374 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
6375 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
6376 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
6377 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
6378 let Predicates = [HasNEON, HasFullFP16] in {
6379 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
6380 [(set FPR16:$Rd, (OpNode (f16 FPR16:$Rn)))]>;
6384 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
6385 SDPatternOperator OpNode = null_frag> {
6386 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6387 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
6388 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
6389 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
6390 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
6391 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
6392 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
6395 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
6396 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
6399 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
6401 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6402 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
6403 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
6404 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
6405 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
6406 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
6407 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
6410 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
6411 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
6416 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6417 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
6418 SDPatternOperator OpNode = null_frag> {
6419 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
6420 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
6421 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
6422 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
6425 //----------------------------------------------------------------------------
6426 // AdvSIMD scalar pairwise instructions
6427 //----------------------------------------------------------------------------
6429 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6430 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
6431 RegisterOperand regtype, RegisterOperand vectype,
6432 string asm, string kind>
6433 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6434 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
6438 let Inst{31-30} = 0b01;
6440 let Inst{28-24} = 0b11110;
6441 let Inst{23-22} = size;
6442 let Inst{21-17} = 0b11000;
6443 let Inst{16-12} = opcode;
6444 let Inst{11-10} = 0b10;
6449 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
6450 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
6454 multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
6455 let Predicates = [HasNEON, HasFullFP16] in {
6456 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
6459 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
6461 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
6465 //----------------------------------------------------------------------------
6466 // AdvSIMD across lanes instructions
6467 //----------------------------------------------------------------------------
6469 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6470 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
6471 RegisterClass regtype, RegisterOperand vectype,
6472 string asm, string kind, list<dag> pattern>
6473 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6474 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
6481 let Inst{28-24} = 0b01110;
6482 let Inst{23-22} = size;
6483 let Inst{21-17} = 0b11000;
6484 let Inst{16-12} = opcode;
6485 let Inst{11-10} = 0b10;
6490 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
6492 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
6494 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
6496 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
6498 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
6500 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
6504 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
6505 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
6507 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
6509 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
6511 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
6513 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
6517 multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
6519 let Predicates = [HasNEON, HasFullFP16] in {
6520 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
6522 [(set FPR16:$Rd, (intOp (v4f16 V64:$Rn)))]>;
6523 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
6525 [(set FPR16:$Rd, (intOp (v8f16 V128:$Rn)))]>;
6526 } // Predicates = [HasNEON, HasFullFP16]
6527 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
6529 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
6532 //----------------------------------------------------------------------------
6533 // AdvSIMD INS/DUP instructions
6534 //----------------------------------------------------------------------------
6536 // FIXME: There has got to be a better way to factor these. ugh.
6538 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
6539 string operands, string constraints, list<dag> pattern>
6540 : I<outs, ins, asm, operands, constraints, pattern>,
6547 let Inst{28-21} = 0b01110000;
6554 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
6555 RegisterOperand vecreg, RegisterClass regtype>
6556 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
6557 "{\t$Rd" # size # ", $Rn" #
6558 "|" # size # "\t$Rd, $Rn}", "",
6559 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
6560 let Inst{20-16} = imm5;
6561 let Inst{14-11} = 0b0001;
6564 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
6565 ValueType vectype, ValueType insreg,
6566 RegisterOperand vecreg, Operand idxtype,
6567 ValueType elttype, SDNode OpNode>
6568 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
6569 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
6570 "|" # dstkind # "\t$Rd, $Rn$idx}", "",
6571 [(set (vectype vecreg:$Rd),
6572 (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
6573 let Inst{14-11} = 0b0000;
6576 class SIMDDup64FromElement
6577 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
6578 VectorIndexD, i64, AArch64duplane64> {
6581 let Inst{19-16} = 0b1000;
6584 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
6585 RegisterOperand vecreg>
6586 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
6587 VectorIndexS, i64, AArch64duplane32> {
6589 let Inst{20-19} = idx;
6590 let Inst{18-16} = 0b100;
6593 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
6594 RegisterOperand vecreg>
6595 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
6596 VectorIndexH, i64, AArch64duplane16> {
6598 let Inst{20-18} = idx;
6599 let Inst{17-16} = 0b10;
6602 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
6603 RegisterOperand vecreg>
6604 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
6605 VectorIndexB, i64, AArch64duplane8> {
6607 let Inst{20-17} = idx;
6611 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
6612 Operand idxtype, string asm, list<dag> pattern>
6613 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
6614 "{\t$Rd, $Rn" # size # "$idx" #
6615 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
6616 let Inst{14-11} = imm4;
6619 class SIMDSMov<bit Q, string size, RegisterClass regtype,
6621 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
6622 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
6624 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
6625 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
6627 class SIMDMovAlias<string asm, string size, Instruction inst,
6628 RegisterClass regtype, Operand idxtype>
6629 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
6630 "|" # size # "\t$dst, $src$idx}",
6631 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
6634 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
6636 let Inst{20-17} = idx;
6639 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
6641 let Inst{20-17} = idx;
6644 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
6646 let Inst{20-18} = idx;
6647 let Inst{17-16} = 0b10;
6649 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
6651 let Inst{20-18} = idx;
6652 let Inst{17-16} = 0b10;
6654 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
6656 let Inst{20-19} = idx;
6657 let Inst{18-16} = 0b100;
6662 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
6664 let Inst{20-17} = idx;
6667 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
6669 let Inst{20-18} = idx;
6670 let Inst{17-16} = 0b10;
6672 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
6674 let Inst{20-19} = idx;
6675 let Inst{18-16} = 0b100;
6677 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
6680 let Inst{19-16} = 0b1000;
6682 def : SIMDMovAlias<"mov", ".s",
6683 !cast<Instruction>(NAME#"vi32"),
6684 GPR32, VectorIndexS>;
6685 def : SIMDMovAlias<"mov", ".d",
6686 !cast<Instruction>(NAME#"vi64"),
6687 GPR64, VectorIndexD>;
6690 class SIMDInsFromMain<string size, ValueType vectype,
6691 RegisterClass regtype, Operand idxtype>
6692 : BaseSIMDInsDup<1, 0, (outs V128:$dst),
6693 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
6694 "{\t$Rd" # size # "$idx, $Rn" #
6695 "|" # size # "\t$Rd$idx, $Rn}",
6698 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
6699 let Inst{14-11} = 0b0011;
6702 class SIMDInsFromElement<string size, ValueType vectype,
6703 ValueType elttype, Operand idxtype>
6704 : BaseSIMDInsDup<1, 1, (outs V128:$dst),
6705 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
6706 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
6707 "|" # size # "\t$Rd$idx, $Rn$idx2}",
6712 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
6715 class SIMDInsMainMovAlias<string size, Instruction inst,
6716 RegisterClass regtype, Operand idxtype>
6717 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
6718 "|" # size #"\t$dst$idx, $src}",
6719 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
6720 class SIMDInsElementMovAlias<string size, Instruction inst,
6722 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
6723 # "|" # size #"\t$dst$idx, $src$idx2}",
6724 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
6727 multiclass SIMDIns {
6728 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
6730 let Inst{20-17} = idx;
6733 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
6735 let Inst{20-18} = idx;
6736 let Inst{17-16} = 0b10;
6738 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
6740 let Inst{20-19} = idx;
6741 let Inst{18-16} = 0b100;
6743 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
6746 let Inst{19-16} = 0b1000;
6749 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
6752 let Inst{20-17} = idx;
6754 let Inst{14-11} = idx2;
6756 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
6759 let Inst{20-18} = idx;
6760 let Inst{17-16} = 0b10;
6761 let Inst{14-12} = idx2;
6764 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
6767 let Inst{20-19} = idx;
6768 let Inst{18-16} = 0b100;
6769 let Inst{14-13} = idx2;
6770 let Inst{12-11} = {?,?};
6772 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
6776 let Inst{19-16} = 0b1000;
6777 let Inst{14} = idx2;
6778 let Inst{13-11} = {?,?,?};
6781 // For all forms of the INS instruction, the "mov" mnemonic is the
6782 // preferred alias. Why they didn't just call the instruction "mov" in
6783 // the first place is a very good question indeed...
6784 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
6785 GPR32, VectorIndexB>;
6786 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
6787 GPR32, VectorIndexH>;
6788 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
6789 GPR32, VectorIndexS>;
6790 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
6791 GPR64, VectorIndexD>;
6793 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
6795 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
6797 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
6799 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
6803 //----------------------------------------------------------------------------
6805 //----------------------------------------------------------------------------
6807 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6808 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6809 RegisterOperand listtype, string asm, string kind>
6810 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
6811 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
6818 let Inst{29-21} = 0b001110000;
6819 let Inst{20-16} = Vm;
6821 let Inst{14-13} = len;
6823 let Inst{11-10} = 0b00;
6828 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6829 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6830 RegisterOperand listtype, string asm, string kind>
6831 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
6832 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
6839 let Inst{29-21} = 0b001110000;
6840 let Inst{20-16} = Vm;
6842 let Inst{14-13} = len;
6844 let Inst{11-10} = 0b00;
6849 class SIMDTableLookupAlias<string asm, Instruction inst,
6850 RegisterOperand vectype, RegisterOperand listtype>
6851 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
6852 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
6854 multiclass SIMDTableLookup<bit op, string asm> {
6855 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
6857 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
6859 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
6861 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
6863 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
6865 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
6867 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
6869 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
6872 def : SIMDTableLookupAlias<asm # ".8b",
6873 !cast<Instruction>(NAME#"v8i8One"),
6874 V64, VecListOne128>;
6875 def : SIMDTableLookupAlias<asm # ".8b",
6876 !cast<Instruction>(NAME#"v8i8Two"),
6877 V64, VecListTwo128>;
6878 def : SIMDTableLookupAlias<asm # ".8b",
6879 !cast<Instruction>(NAME#"v8i8Three"),
6880 V64, VecListThree128>;
6881 def : SIMDTableLookupAlias<asm # ".8b",
6882 !cast<Instruction>(NAME#"v8i8Four"),
6883 V64, VecListFour128>;
6884 def : SIMDTableLookupAlias<asm # ".16b",
6885 !cast<Instruction>(NAME#"v16i8One"),
6886 V128, VecListOne128>;
6887 def : SIMDTableLookupAlias<asm # ".16b",
6888 !cast<Instruction>(NAME#"v16i8Two"),
6889 V128, VecListTwo128>;
6890 def : SIMDTableLookupAlias<asm # ".16b",
6891 !cast<Instruction>(NAME#"v16i8Three"),
6892 V128, VecListThree128>;
6893 def : SIMDTableLookupAlias<asm # ".16b",
6894 !cast<Instruction>(NAME#"v16i8Four"),
6895 V128, VecListFour128>;
6898 multiclass SIMDTableLookupTied<bit op, string asm> {
6899 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
6901 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
6903 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
6905 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
6907 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
6909 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
6911 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
6913 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
6916 def : SIMDTableLookupAlias<asm # ".8b",
6917 !cast<Instruction>(NAME#"v8i8One"),
6918 V64, VecListOne128>;
6919 def : SIMDTableLookupAlias<asm # ".8b",
6920 !cast<Instruction>(NAME#"v8i8Two"),
6921 V64, VecListTwo128>;
6922 def : SIMDTableLookupAlias<asm # ".8b",
6923 !cast<Instruction>(NAME#"v8i8Three"),
6924 V64, VecListThree128>;
6925 def : SIMDTableLookupAlias<asm # ".8b",
6926 !cast<Instruction>(NAME#"v8i8Four"),
6927 V64, VecListFour128>;
6928 def : SIMDTableLookupAlias<asm # ".16b",
6929 !cast<Instruction>(NAME#"v16i8One"),
6930 V128, VecListOne128>;
6931 def : SIMDTableLookupAlias<asm # ".16b",
6932 !cast<Instruction>(NAME#"v16i8Two"),
6933 V128, VecListTwo128>;
6934 def : SIMDTableLookupAlias<asm # ".16b",
6935 !cast<Instruction>(NAME#"v16i8Three"),
6936 V128, VecListThree128>;
6937 def : SIMDTableLookupAlias<asm # ".16b",
6938 !cast<Instruction>(NAME#"v16i8Four"),
6939 V128, VecListFour128>;
6943 //----------------------------------------------------------------------------
6944 // AdvSIMD scalar CPY
6945 //----------------------------------------------------------------------------
6946 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6947 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
6948 string kind, Operand idxtype>
6949 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
6950 "{\t$dst, $src" # kind # "$idx" #
6951 "|\t$dst, $src$idx}", "", []>,
6955 let Inst{31-21} = 0b01011110000;
6956 let Inst{15-10} = 0b000001;
6957 let Inst{9-5} = src;
6958 let Inst{4-0} = dst;
6961 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
6962 RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
6963 : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
6964 # "|\t$dst, $src$index}",
6965 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
6968 multiclass SIMDScalarCPY<string asm> {
6969 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> {
6971 let Inst{20-17} = idx;
6974 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
6976 let Inst{20-18} = idx;
6977 let Inst{17-16} = 0b10;
6979 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
6981 let Inst{20-19} = idx;
6982 let Inst{18-16} = 0b100;
6984 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
6987 let Inst{19-16} = 0b1000;
6990 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
6991 VectorIndexD:$idx)))),
6992 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
6994 // 'DUP' mnemonic aliases.
6995 def : SIMDScalarCPYAlias<"dup", ".b",
6996 !cast<Instruction>(NAME#"i8"),
6997 FPR8, V128, VectorIndexB>;
6998 def : SIMDScalarCPYAlias<"dup", ".h",
6999 !cast<Instruction>(NAME#"i16"),
7000 FPR16, V128, VectorIndexH>;
7001 def : SIMDScalarCPYAlias<"dup", ".s",
7002 !cast<Instruction>(NAME#"i32"),
7003 FPR32, V128, VectorIndexS>;
7004 def : SIMDScalarCPYAlias<"dup", ".d",
7005 !cast<Instruction>(NAME#"i64"),
7006 FPR64, V128, VectorIndexD>;
7009 //----------------------------------------------------------------------------
7010 // AdvSIMD modified immediate instructions
7011 //----------------------------------------------------------------------------
7013 class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
7014 string asm, string op_string,
7015 string cstr, list<dag> pattern>
7016 : I<oops, iops, asm, op_string, cstr, pattern>,
7023 let Inst{28-19} = 0b0111100000;
7024 let Inst{18-16} = imm8{7-5};
7027 let Inst{9-5} = imm8{4-0};
7031 class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
7032 Operand immtype, dag opt_shift_iop,
7033 string opt_shift, string asm, string kind,
7035 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
7036 !con((ins immtype:$imm8), opt_shift_iop), asm,
7037 "{\t$Rd" # kind # ", $imm8" # opt_shift #
7038 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
7040 let DecoderMethod = "DecodeModImmInstruction";
7043 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
7044 Operand immtype, dag opt_shift_iop,
7045 string opt_shift, string asm, string kind,
7047 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
7048 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
7049 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
7050 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
7051 "$Rd = $dst", pattern> {
7052 let DecoderMethod = "DecodeModImmTiedInstruction";
7055 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
7056 RegisterOperand vectype, string asm,
7057 string kind, list<dag> pattern>
7058 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7059 (ins logical_vec_shift:$shift),
7060 "$shift", asm, kind, pattern> {
7062 let Inst{15} = b15_b12{1};
7063 let Inst{14-13} = shift;
7064 let Inst{12} = b15_b12{0};
7067 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
7068 RegisterOperand vectype, string asm,
7069 string kind, list<dag> pattern>
7070 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
7071 (ins logical_vec_shift:$shift),
7072 "$shift", asm, kind, pattern> {
7074 let Inst{15} = b15_b12{1};
7075 let Inst{14-13} = shift;
7076 let Inst{12} = b15_b12{0};
7080 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
7081 RegisterOperand vectype, string asm,
7082 string kind, list<dag> pattern>
7083 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7084 (ins logical_vec_hw_shift:$shift),
7085 "$shift", asm, kind, pattern> {
7087 let Inst{15} = b15_b12{1};
7089 let Inst{13} = shift{0};
7090 let Inst{12} = b15_b12{0};
7093 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
7094 RegisterOperand vectype, string asm,
7095 string kind, list<dag> pattern>
7096 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
7097 (ins logical_vec_hw_shift:$shift),
7098 "$shift", asm, kind, pattern> {
7100 let Inst{15} = b15_b12{1};
7102 let Inst{13} = shift{0};
7103 let Inst{12} = b15_b12{0};
7106 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
7108 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
7110 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
7113 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
7115 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
7119 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
7120 bits<2> w_cmode, string asm,
7122 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
7124 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
7126 (i32 imm:$shift)))]>;
7127 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
7129 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
7131 (i32 imm:$shift)))]>;
7133 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
7135 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
7137 (i32 imm:$shift)))]>;
7138 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
7140 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
7142 (i32 imm:$shift)))]>;
7145 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
7146 RegisterOperand vectype, string asm,
7147 string kind, list<dag> pattern>
7148 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
7149 (ins move_vec_shift:$shift),
7150 "$shift", asm, kind, pattern> {
7152 let Inst{15-13} = cmode{3-1};
7153 let Inst{12} = shift;
7156 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
7157 RegisterOperand vectype,
7158 Operand imm_type, string asm,
7159 string kind, list<dag> pattern>
7160 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
7161 asm, kind, pattern> {
7162 let Inst{15-12} = cmode;
7165 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
7167 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
7168 "\t$Rd, $imm8", "", pattern> {
7169 let Inst{15-12} = cmode;
7170 let DecoderMethod = "DecodeModImmInstruction";
7173 //----------------------------------------------------------------------------
7174 // AdvSIMD indexed element
7175 //----------------------------------------------------------------------------
7177 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7178 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
7179 RegisterOperand dst_reg, RegisterOperand lhs_reg,
7180 RegisterOperand rhs_reg, Operand vec_idx, string asm,
7181 string apple_kind, string dst_kind, string lhs_kind,
7182 string rhs_kind, list<dag> pattern>
7183 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
7185 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
7186 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
7195 let Inst{28} = Scalar;
7196 let Inst{27-24} = 0b1111;
7197 let Inst{23-22} = size;
7198 // Bit 21 must be set by the derived class.
7199 let Inst{20-16} = Rm;
7200 let Inst{15-12} = opc;
7201 // Bit 11 must be set by the derived class.
7207 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7208 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
7209 RegisterOperand dst_reg, RegisterOperand lhs_reg,
7210 RegisterOperand rhs_reg, Operand vec_idx, string asm,
7211 string apple_kind, string dst_kind, string lhs_kind,
7212 string rhs_kind, list<dag> pattern>
7213 : I<(outs dst_reg:$dst),
7214 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
7215 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
7216 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
7225 let Inst{28} = Scalar;
7226 let Inst{27-24} = 0b1111;
7227 let Inst{23-22} = size;
7228 // Bit 21 must be set by the derived class.
7229 let Inst{20-16} = Rm;
7230 let Inst{15-12} = opc;
7231 // Bit 11 must be set by the derived class.
7237 // ARMv8.2 Index Dot product instructions
7238 class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, string asm, string dst_kind,
7239 string lhs_kind, string rhs_kind,
7240 RegisterOperand RegType,
7241 ValueType AccumType, ValueType InputType,
7242 SDPatternOperator OpNode> :
7243 BaseSIMDIndexedTied<Q, U, 0b0, 0b10, 0b1110, RegType, RegType, V128,
7244 VectorIndexS, asm, "", dst_kind, lhs_kind, rhs_kind,
7245 [(set (AccumType RegType:$dst),
7246 (AccumType (OpNode (AccumType RegType:$Rd),
7247 (InputType RegType:$Rn),
7248 (InputType (bitconvert (AccumType
7249 (AArch64duplane32 (v4i32 V128:$Rm),
7250 VectorIndexS:$idx)))))))]> {
7252 let Inst{21} = idx{0}; // L
7253 let Inst{11} = idx{1}; // H
7256 multiclass SIMDThreeSameVectorDotIndex<bit U, string asm,
7257 SDPatternOperator OpNode> {
7258 def v8i8 : BaseSIMDThreeSameVectorDotIndex<0, U, asm, ".2s", ".8b", ".4b", V64,
7259 v2i32, v8i8, OpNode>;
7260 def v16i8 : BaseSIMDThreeSameVectorDotIndex<1, U, asm, ".4s", ".16b", ".4b", V128,
7261 v4i32, v16i8, OpNode>;
7264 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
7265 SDPatternOperator OpNode> {
7266 let Predicates = [HasNEON, HasFullFP16] in {
7267 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
7269 V128_lo, VectorIndexH,
7270 asm, ".4h", ".4h", ".4h", ".h",
7271 [(set (v4f16 V64:$Rd),
7272 (OpNode (v4f16 V64:$Rn),
7273 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7275 let Inst{11} = idx{2};
7276 let Inst{21} = idx{1};
7277 let Inst{20} = idx{0};
7280 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
7282 V128_lo, VectorIndexH,
7283 asm, ".8h", ".8h", ".8h", ".h",
7284 [(set (v8f16 V128:$Rd),
7285 (OpNode (v8f16 V128:$Rn),
7286 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7288 let Inst{11} = idx{2};
7289 let Inst{21} = idx{1};
7290 let Inst{20} = idx{0};
7292 } // Predicates = [HasNEON, HasFullFP16]
7294 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7297 asm, ".2s", ".2s", ".2s", ".s",
7298 [(set (v2f32 V64:$Rd),
7299 (OpNode (v2f32 V64:$Rn),
7300 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
7302 let Inst{11} = idx{1};
7303 let Inst{21} = idx{0};
7306 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7309 asm, ".4s", ".4s", ".4s", ".s",
7310 [(set (v4f32 V128:$Rd),
7311 (OpNode (v4f32 V128:$Rn),
7312 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
7314 let Inst{11} = idx{1};
7315 let Inst{21} = idx{0};
7318 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
7321 asm, ".2d", ".2d", ".2d", ".d",
7322 [(set (v2f64 V128:$Rd),
7323 (OpNode (v2f64 V128:$Rn),
7324 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
7326 let Inst{11} = idx{0};
7330 let Predicates = [HasNEON, HasFullFP16] in {
7331 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
7332 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7333 asm, ".h", "", "", ".h",
7334 [(set (f16 FPR16Op:$Rd),
7335 (OpNode (f16 FPR16Op:$Rn),
7336 (f16 (vector_extract (v8f16 V128_lo:$Rm),
7337 VectorIndexH:$idx))))]> {
7339 let Inst{11} = idx{2};
7340 let Inst{21} = idx{1};
7341 let Inst{20} = idx{0};
7343 } // Predicates = [HasNEON, HasFullFP16]
7345 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7346 FPR32Op, FPR32Op, V128, VectorIndexS,
7347 asm, ".s", "", "", ".s",
7348 [(set (f32 FPR32Op:$Rd),
7349 (OpNode (f32 FPR32Op:$Rn),
7350 (f32 (vector_extract (v4f32 V128:$Rm),
7351 VectorIndexS:$idx))))]> {
7353 let Inst{11} = idx{1};
7354 let Inst{21} = idx{0};
7357 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
7358 FPR64Op, FPR64Op, V128, VectorIndexD,
7359 asm, ".d", "", "", ".d",
7360 [(set (f64 FPR64Op:$Rd),
7361 (OpNode (f64 FPR64Op:$Rn),
7362 (f64 (vector_extract (v2f64 V128:$Rm),
7363 VectorIndexD:$idx))))]> {
7365 let Inst{11} = idx{0};
7370 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
7371 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
7372 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
7373 (AArch64duplane32 (v4f32 V128:$Rm),
7374 VectorIndexS:$idx))),
7375 (!cast<Instruction>(INST # v2i32_indexed)
7376 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7377 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
7378 (AArch64dup (f32 FPR32Op:$Rm)))),
7379 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
7380 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
7383 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
7384 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
7385 (AArch64duplane32 (v4f32 V128:$Rm),
7386 VectorIndexS:$idx))),
7387 (!cast<Instruction>(INST # "v4i32_indexed")
7388 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7389 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
7390 (AArch64dup (f32 FPR32Op:$Rm)))),
7391 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
7392 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
7394 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
7395 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
7396 (AArch64duplane64 (v2f64 V128:$Rm),
7397 VectorIndexD:$idx))),
7398 (!cast<Instruction>(INST # "v2i64_indexed")
7399 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7400 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
7401 (AArch64dup (f64 FPR64Op:$Rm)))),
7402 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
7403 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
7405 // 2 variants for 32-bit scalar version: extract from .2s or from .4s
7406 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
7407 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
7408 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
7409 V128:$Rm, VectorIndexS:$idx)>;
7410 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
7411 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
7412 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
7413 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
7415 // 1 variant for 64-bit scalar version: extract from .1d or from .2d
7416 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
7417 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
7418 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
7419 V128:$Rm, VectorIndexD:$idx)>;
7422 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
7423 let Predicates = [HasNEON, HasFullFP16] in {
7424 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
7425 V128_lo, VectorIndexH,
7426 asm, ".4h", ".4h", ".4h", ".h", []> {
7428 let Inst{11} = idx{2};
7429 let Inst{21} = idx{1};
7430 let Inst{20} = idx{0};
7433 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
7435 V128_lo, VectorIndexH,
7436 asm, ".8h", ".8h", ".8h", ".h", []> {
7438 let Inst{11} = idx{2};
7439 let Inst{21} = idx{1};
7440 let Inst{20} = idx{0};
7442 } // Predicates = [HasNEON, HasFullFP16]
7444 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
7446 asm, ".2s", ".2s", ".2s", ".s", []> {
7448 let Inst{11} = idx{1};
7449 let Inst{21} = idx{0};
7452 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7455 asm, ".4s", ".4s", ".4s", ".s", []> {
7457 let Inst{11} = idx{1};
7458 let Inst{21} = idx{0};
7461 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
7464 asm, ".2d", ".2d", ".2d", ".d", []> {
7466 let Inst{11} = idx{0};
7470 let Predicates = [HasNEON, HasFullFP16] in {
7471 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
7472 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7473 asm, ".h", "", "", ".h", []> {
7475 let Inst{11} = idx{2};
7476 let Inst{21} = idx{1};
7477 let Inst{20} = idx{0};
7479 } // Predicates = [HasNEON, HasFullFP16]
7481 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7482 FPR32Op, FPR32Op, V128, VectorIndexS,
7483 asm, ".s", "", "", ".s", []> {
7485 let Inst{11} = idx{1};
7486 let Inst{21} = idx{0};
7489 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
7490 FPR64Op, FPR64Op, V128, VectorIndexD,
7491 asm, ".d", "", "", ".d", []> {
7493 let Inst{11} = idx{0};
7498 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
7499 SDPatternOperator OpNode> {
7500 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
7501 V128_lo, VectorIndexH,
7502 asm, ".4h", ".4h", ".4h", ".h",
7503 [(set (v4i16 V64:$Rd),
7504 (OpNode (v4i16 V64:$Rn),
7505 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7507 let Inst{11} = idx{2};
7508 let Inst{21} = idx{1};
7509 let Inst{20} = idx{0};
7512 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7514 V128_lo, VectorIndexH,
7515 asm, ".8h", ".8h", ".8h", ".h",
7516 [(set (v8i16 V128:$Rd),
7517 (OpNode (v8i16 V128:$Rn),
7518 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7520 let Inst{11} = idx{2};
7521 let Inst{21} = idx{1};
7522 let Inst{20} = idx{0};
7525 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7528 asm, ".2s", ".2s", ".2s", ".s",
7529 [(set (v2i32 V64:$Rd),
7530 (OpNode (v2i32 V64:$Rn),
7531 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7533 let Inst{11} = idx{1};
7534 let Inst{21} = idx{0};
7537 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7540 asm, ".4s", ".4s", ".4s", ".s",
7541 [(set (v4i32 V128:$Rd),
7542 (OpNode (v4i32 V128:$Rn),
7543 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7545 let Inst{11} = idx{1};
7546 let Inst{21} = idx{0};
7549 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7550 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7551 asm, ".h", "", "", ".h", []> {
7553 let Inst{11} = idx{2};
7554 let Inst{21} = idx{1};
7555 let Inst{20} = idx{0};
7558 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7559 FPR32Op, FPR32Op, V128, VectorIndexS,
7560 asm, ".s", "", "", ".s",
7561 [(set (i32 FPR32Op:$Rd),
7562 (OpNode FPR32Op:$Rn,
7563 (i32 (vector_extract (v4i32 V128:$Rm),
7564 VectorIndexS:$idx))))]> {
7566 let Inst{11} = idx{1};
7567 let Inst{21} = idx{0};
7571 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
7572 SDPatternOperator OpNode> {
7573 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7575 V128_lo, VectorIndexH,
7576 asm, ".4h", ".4h", ".4h", ".h",
7577 [(set (v4i16 V64:$Rd),
7578 (OpNode (v4i16 V64:$Rn),
7579 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7581 let Inst{11} = idx{2};
7582 let Inst{21} = idx{1};
7583 let Inst{20} = idx{0};
7586 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7588 V128_lo, VectorIndexH,
7589 asm, ".8h", ".8h", ".8h", ".h",
7590 [(set (v8i16 V128:$Rd),
7591 (OpNode (v8i16 V128:$Rn),
7592 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7594 let Inst{11} = idx{2};
7595 let Inst{21} = idx{1};
7596 let Inst{20} = idx{0};
7599 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7602 asm, ".2s", ".2s", ".2s", ".s",
7603 [(set (v2i32 V64:$Rd),
7604 (OpNode (v2i32 V64:$Rn),
7605 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7607 let Inst{11} = idx{1};
7608 let Inst{21} = idx{0};
7611 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7614 asm, ".4s", ".4s", ".4s", ".s",
7615 [(set (v4i32 V128:$Rd),
7616 (OpNode (v4i32 V128:$Rn),
7617 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7619 let Inst{11} = idx{1};
7620 let Inst{21} = idx{0};
7624 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
7625 SDPatternOperator OpNode> {
7626 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
7627 V128_lo, VectorIndexH,
7628 asm, ".4h", ".4h", ".4h", ".h",
7629 [(set (v4i16 V64:$dst),
7630 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
7631 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7633 let Inst{11} = idx{2};
7634 let Inst{21} = idx{1};
7635 let Inst{20} = idx{0};
7638 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7640 V128_lo, VectorIndexH,
7641 asm, ".8h", ".8h", ".8h", ".h",
7642 [(set (v8i16 V128:$dst),
7643 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7644 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7646 let Inst{11} = idx{2};
7647 let Inst{21} = idx{1};
7648 let Inst{20} = idx{0};
7651 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7654 asm, ".2s", ".2s", ".2s", ".s",
7655 [(set (v2i32 V64:$dst),
7656 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7657 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7659 let Inst{11} = idx{1};
7660 let Inst{21} = idx{0};
7663 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7666 asm, ".4s", ".4s", ".4s", ".s",
7667 [(set (v4i32 V128:$dst),
7668 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7669 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7671 let Inst{11} = idx{1};
7672 let Inst{21} = idx{0};
7676 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
7677 SDPatternOperator OpNode> {
7678 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7680 V128_lo, VectorIndexH,
7681 asm, ".4s", ".4s", ".4h", ".h",
7682 [(set (v4i32 V128:$Rd),
7683 (OpNode (v4i16 V64:$Rn),
7684 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7686 let Inst{11} = idx{2};
7687 let Inst{21} = idx{1};
7688 let Inst{20} = idx{0};
7691 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7693 V128_lo, VectorIndexH,
7694 asm#"2", ".4s", ".4s", ".8h", ".h",
7695 [(set (v4i32 V128:$Rd),
7696 (OpNode (extract_high_v8i16 V128:$Rn),
7697 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7698 VectorIndexH:$idx))))]> {
7701 let Inst{11} = idx{2};
7702 let Inst{21} = idx{1};
7703 let Inst{20} = idx{0};
7706 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7709 asm, ".2d", ".2d", ".2s", ".s",
7710 [(set (v2i64 V128:$Rd),
7711 (OpNode (v2i32 V64:$Rn),
7712 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7714 let Inst{11} = idx{1};
7715 let Inst{21} = idx{0};
7718 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7721 asm#"2", ".2d", ".2d", ".4s", ".s",
7722 [(set (v2i64 V128:$Rd),
7723 (OpNode (extract_high_v4i32 V128:$Rn),
7724 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7725 VectorIndexS:$idx))))]> {
7727 let Inst{11} = idx{1};
7728 let Inst{21} = idx{0};
7731 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7732 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7733 asm, ".h", "", "", ".h", []> {
7735 let Inst{11} = idx{2};
7736 let Inst{21} = idx{1};
7737 let Inst{20} = idx{0};
7740 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7741 FPR64Op, FPR32Op, V128, VectorIndexS,
7742 asm, ".s", "", "", ".s", []> {
7744 let Inst{11} = idx{1};
7745 let Inst{21} = idx{0};
7749 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
7750 SDPatternOperator Accum> {
7751 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7753 V128_lo, VectorIndexH,
7754 asm, ".4s", ".4s", ".4h", ".h",
7755 [(set (v4i32 V128:$dst),
7756 (Accum (v4i32 V128:$Rd),
7757 (v4i32 (int_aarch64_neon_sqdmull
7759 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7760 VectorIndexH:$idx))))))]> {
7762 let Inst{11} = idx{2};
7763 let Inst{21} = idx{1};
7764 let Inst{20} = idx{0};
7767 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
7768 // intermediate EXTRACT_SUBREG would be untyped.
7769 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
7770 (i32 (vector_extract (v4i32
7771 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
7772 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7773 VectorIndexH:$idx)))),
7776 (!cast<Instruction>(NAME # v4i16_indexed)
7777 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
7778 V128_lo:$Rm, VectorIndexH:$idx),
7781 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7783 V128_lo, VectorIndexH,
7784 asm#"2", ".4s", ".4s", ".8h", ".h",
7785 [(set (v4i32 V128:$dst),
7786 (Accum (v4i32 V128:$Rd),
7787 (v4i32 (int_aarch64_neon_sqdmull
7788 (extract_high_v8i16 V128:$Rn),
7790 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7791 VectorIndexH:$idx))))))]> {
7793 let Inst{11} = idx{2};
7794 let Inst{21} = idx{1};
7795 let Inst{20} = idx{0};
7798 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7801 asm, ".2d", ".2d", ".2s", ".s",
7802 [(set (v2i64 V128:$dst),
7803 (Accum (v2i64 V128:$Rd),
7804 (v2i64 (int_aarch64_neon_sqdmull
7806 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
7807 VectorIndexS:$idx))))))]> {
7809 let Inst{11} = idx{1};
7810 let Inst{21} = idx{0};
7813 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7816 asm#"2", ".2d", ".2d", ".4s", ".s",
7817 [(set (v2i64 V128:$dst),
7818 (Accum (v2i64 V128:$Rd),
7819 (v2i64 (int_aarch64_neon_sqdmull
7820 (extract_high_v4i32 V128:$Rn),
7822 (AArch64duplane32 (v4i32 V128:$Rm),
7823 VectorIndexS:$idx))))))]> {
7825 let Inst{11} = idx{1};
7826 let Inst{21} = idx{0};
7829 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
7830 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7831 asm, ".h", "", "", ".h", []> {
7833 let Inst{11} = idx{2};
7834 let Inst{21} = idx{1};
7835 let Inst{20} = idx{0};
7839 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7840 FPR64Op, FPR32Op, V128, VectorIndexS,
7841 asm, ".s", "", "", ".s",
7842 [(set (i64 FPR64Op:$dst),
7843 (Accum (i64 FPR64Op:$Rd),
7844 (i64 (int_aarch64_neon_sqdmulls_scalar
7846 (i32 (vector_extract (v4i32 V128:$Rm),
7847 VectorIndexS:$idx))))))]> {
7850 let Inst{11} = idx{1};
7851 let Inst{21} = idx{0};
7855 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
7856 SDPatternOperator OpNode> {
7857 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7858 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7860 V128_lo, VectorIndexH,
7861 asm, ".4s", ".4s", ".4h", ".h",
7862 [(set (v4i32 V128:$Rd),
7863 (OpNode (v4i16 V64:$Rn),
7864 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7866 let Inst{11} = idx{2};
7867 let Inst{21} = idx{1};
7868 let Inst{20} = idx{0};
7871 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7873 V128_lo, VectorIndexH,
7874 asm#"2", ".4s", ".4s", ".8h", ".h",
7875 [(set (v4i32 V128:$Rd),
7876 (OpNode (extract_high_v8i16 V128:$Rn),
7877 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7878 VectorIndexH:$idx))))]> {
7881 let Inst{11} = idx{2};
7882 let Inst{21} = idx{1};
7883 let Inst{20} = idx{0};
7886 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7889 asm, ".2d", ".2d", ".2s", ".s",
7890 [(set (v2i64 V128:$Rd),
7891 (OpNode (v2i32 V64:$Rn),
7892 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7894 let Inst{11} = idx{1};
7895 let Inst{21} = idx{0};
7898 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7901 asm#"2", ".2d", ".2d", ".4s", ".s",
7902 [(set (v2i64 V128:$Rd),
7903 (OpNode (extract_high_v4i32 V128:$Rn),
7904 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7905 VectorIndexS:$idx))))]> {
7907 let Inst{11} = idx{1};
7908 let Inst{21} = idx{0};
7913 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
7914 SDPatternOperator OpNode> {
7915 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7916 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7918 V128_lo, VectorIndexH,
7919 asm, ".4s", ".4s", ".4h", ".h",
7920 [(set (v4i32 V128:$dst),
7921 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
7922 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7924 let Inst{11} = idx{2};
7925 let Inst{21} = idx{1};
7926 let Inst{20} = idx{0};
7929 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7931 V128_lo, VectorIndexH,
7932 asm#"2", ".4s", ".4s", ".8h", ".h",
7933 [(set (v4i32 V128:$dst),
7934 (OpNode (v4i32 V128:$Rd),
7935 (extract_high_v8i16 V128:$Rn),
7936 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7937 VectorIndexH:$idx))))]> {
7939 let Inst{11} = idx{2};
7940 let Inst{21} = idx{1};
7941 let Inst{20} = idx{0};
7944 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7947 asm, ".2d", ".2d", ".2s", ".s",
7948 [(set (v2i64 V128:$dst),
7949 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
7950 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7952 let Inst{11} = idx{1};
7953 let Inst{21} = idx{0};
7956 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7959 asm#"2", ".2d", ".2d", ".4s", ".s",
7960 [(set (v2i64 V128:$dst),
7961 (OpNode (v2i64 V128:$Rd),
7962 (extract_high_v4i32 V128:$Rn),
7963 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7964 VectorIndexS:$idx))))]> {
7966 let Inst{11} = idx{1};
7967 let Inst{21} = idx{0};
7972 //----------------------------------------------------------------------------
7973 // AdvSIMD scalar shift by immediate
7974 //----------------------------------------------------------------------------
7976 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7977 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
7978 RegisterClass regtype1, RegisterClass regtype2,
7979 Operand immtype, string asm, list<dag> pattern>
7980 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
7981 asm, "\t$Rd, $Rn, $imm", "", pattern>,
7986 let Inst{31-30} = 0b01;
7988 let Inst{28-23} = 0b111110;
7989 let Inst{22-16} = fixed_imm;
7990 let Inst{15-11} = opc;
7996 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7997 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
7998 RegisterClass regtype1, RegisterClass regtype2,
7999 Operand immtype, string asm, list<dag> pattern>
8000 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
8001 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
8006 let Inst{31-30} = 0b01;
8008 let Inst{28-23} = 0b111110;
8009 let Inst{22-16} = fixed_imm;
8010 let Inst{15-11} = opc;
8017 multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
8018 let Predicates = [HasNEON, HasFullFP16] in {
8019 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8020 FPR16, FPR16, vecshiftR16, asm, []> {
8021 let Inst{19-16} = imm{3-0};
8023 } // Predicates = [HasNEON, HasFullFP16]
8024 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8025 FPR32, FPR32, vecshiftR32, asm, []> {
8026 let Inst{20-16} = imm{4-0};
8028 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8029 FPR64, FPR64, vecshiftR64, asm, []> {
8030 let Inst{21-16} = imm{5-0};
8034 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
8035 SDPatternOperator OpNode> {
8036 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8037 FPR64, FPR64, vecshiftR64, asm,
8038 [(set (i64 FPR64:$Rd),
8039 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
8040 let Inst{21-16} = imm{5-0};
8043 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
8044 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
8047 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
8048 SDPatternOperator OpNode = null_frag> {
8049 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
8050 FPR64, FPR64, vecshiftR64, asm,
8051 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
8052 (i32 vecshiftR64:$imm)))]> {
8053 let Inst{21-16} = imm{5-0};
8056 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
8057 (i32 vecshiftR64:$imm))),
8058 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
8062 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
8063 SDPatternOperator OpNode> {
8064 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8065 FPR64, FPR64, vecshiftL64, asm,
8066 [(set (v1i64 FPR64:$Rd),
8067 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
8068 let Inst{21-16} = imm{5-0};
8072 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8073 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
8074 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
8075 FPR64, FPR64, vecshiftL64, asm, []> {
8076 let Inst{21-16} = imm{5-0};
8080 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8081 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
8082 SDPatternOperator OpNode = null_frag> {
8083 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8084 FPR8, FPR16, vecshiftR8, asm, []> {
8085 let Inst{18-16} = imm{2-0};
8088 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8089 FPR16, FPR32, vecshiftR16, asm, []> {
8090 let Inst{19-16} = imm{3-0};
8093 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8094 FPR32, FPR64, vecshiftR32, asm,
8095 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
8096 let Inst{20-16} = imm{4-0};
8100 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
8101 SDPatternOperator OpNode> {
8102 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8103 FPR8, FPR8, vecshiftL8, asm, []> {
8104 let Inst{18-16} = imm{2-0};
8107 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8108 FPR16, FPR16, vecshiftL16, asm, []> {
8109 let Inst{19-16} = imm{3-0};
8112 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8113 FPR32, FPR32, vecshiftL32, asm,
8114 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
8115 let Inst{20-16} = imm{4-0};
8118 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8119 FPR64, FPR64, vecshiftL64, asm,
8120 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
8121 let Inst{21-16} = imm{5-0};
8124 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
8125 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
8128 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
8129 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
8130 FPR8, FPR8, vecshiftR8, asm, []> {
8131 let Inst{18-16} = imm{2-0};
8134 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
8135 FPR16, FPR16, vecshiftR16, asm, []> {
8136 let Inst{19-16} = imm{3-0};
8139 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
8140 FPR32, FPR32, vecshiftR32, asm, []> {
8141 let Inst{20-16} = imm{4-0};
8144 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
8145 FPR64, FPR64, vecshiftR64, asm, []> {
8146 let Inst{21-16} = imm{5-0};
8150 //----------------------------------------------------------------------------
8151 // AdvSIMD vector x indexed element
8152 //----------------------------------------------------------------------------
8154 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8155 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
8156 RegisterOperand dst_reg, RegisterOperand src_reg,
8158 string asm, string dst_kind, string src_kind,
8160 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
8161 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
8162 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
8169 let Inst{28-23} = 0b011110;
8170 let Inst{22-16} = fixed_imm;
8171 let Inst{15-11} = opc;
8177 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
8178 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
8179 RegisterOperand vectype1, RegisterOperand vectype2,
8181 string asm, string dst_kind, string src_kind,
8183 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
8184 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
8185 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
8192 let Inst{28-23} = 0b011110;
8193 let Inst{22-16} = fixed_imm;
8194 let Inst{15-11} = opc;
8200 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
8202 let Predicates = [HasNEON, HasFullFP16] in {
8203 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8204 V64, V64, vecshiftR16,
8206 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
8208 let Inst{19-16} = imm;
8211 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8212 V128, V128, vecshiftR16,
8214 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
8216 let Inst{19-16} = imm;
8218 } // Predicates = [HasNEON, HasFullFP16]
8219 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8220 V64, V64, vecshiftR32,
8222 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
8224 let Inst{20-16} = imm;
8227 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8228 V128, V128, vecshiftR32,
8230 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
8232 let Inst{20-16} = imm;
8235 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8236 V128, V128, vecshiftR64,
8238 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
8240 let Inst{21-16} = imm;
8244 multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
8246 let Predicates = [HasNEON, HasFullFP16] in {
8247 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8248 V64, V64, vecshiftR16,
8250 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
8252 let Inst{19-16} = imm;
8255 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8256 V128, V128, vecshiftR16,
8258 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
8260 let Inst{19-16} = imm;
8262 } // Predicates = [HasNEON, HasFullFP16]
8264 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8265 V64, V64, vecshiftR32,
8267 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
8269 let Inst{20-16} = imm;
8272 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8273 V128, V128, vecshiftR32,
8275 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
8277 let Inst{20-16} = imm;
8280 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8281 V128, V128, vecshiftR64,
8283 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
8285 let Inst{21-16} = imm;
8289 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
8290 SDPatternOperator OpNode> {
8291 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8292 V64, V128, vecshiftR16Narrow,
8294 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
8296 let Inst{18-16} = imm;
8299 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8300 V128, V128, vecshiftR16Narrow,
8301 asm#"2", ".16b", ".8h", []> {
8303 let Inst{18-16} = imm;
8304 let hasSideEffects = 0;
8307 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8308 V64, V128, vecshiftR32Narrow,
8310 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
8312 let Inst{19-16} = imm;
8315 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8316 V128, V128, vecshiftR32Narrow,
8317 asm#"2", ".8h", ".4s", []> {
8319 let Inst{19-16} = imm;
8320 let hasSideEffects = 0;
8323 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8324 V64, V128, vecshiftR64Narrow,
8326 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
8328 let Inst{20-16} = imm;
8331 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8332 V128, V128, vecshiftR64Narrow,
8333 asm#"2", ".4s", ".2d", []> {
8335 let Inst{20-16} = imm;
8336 let hasSideEffects = 0;
8339 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
8340 // themselves, so put them here instead.
8342 // Patterns involving what's effectively an insert high and a normal
8343 // intrinsic, represented by CONCAT_VECTORS.
8344 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
8345 vecshiftR16Narrow:$imm)),
8346 (!cast<Instruction>(NAME # "v16i8_shift")
8347 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8348 V128:$Rn, vecshiftR16Narrow:$imm)>;
8349 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
8350 vecshiftR32Narrow:$imm)),
8351 (!cast<Instruction>(NAME # "v8i16_shift")
8352 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8353 V128:$Rn, vecshiftR32Narrow:$imm)>;
8354 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
8355 vecshiftR64Narrow:$imm)),
8356 (!cast<Instruction>(NAME # "v4i32_shift")
8357 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8358 V128:$Rn, vecshiftR64Narrow:$imm)>;
8361 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
8362 SDPatternOperator OpNode> {
8363 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8364 V64, V64, vecshiftL8,
8366 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
8367 (i32 vecshiftL8:$imm)))]> {
8369 let Inst{18-16} = imm;
8372 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8373 V128, V128, vecshiftL8,
8374 asm, ".16b", ".16b",
8375 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
8376 (i32 vecshiftL8:$imm)))]> {
8378 let Inst{18-16} = imm;
8381 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8382 V64, V64, vecshiftL16,
8384 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
8385 (i32 vecshiftL16:$imm)))]> {
8387 let Inst{19-16} = imm;
8390 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8391 V128, V128, vecshiftL16,
8393 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
8394 (i32 vecshiftL16:$imm)))]> {
8396 let Inst{19-16} = imm;
8399 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8400 V64, V64, vecshiftL32,
8402 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
8403 (i32 vecshiftL32:$imm)))]> {
8405 let Inst{20-16} = imm;
8408 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8409 V128, V128, vecshiftL32,
8411 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
8412 (i32 vecshiftL32:$imm)))]> {
8414 let Inst{20-16} = imm;
8417 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8418 V128, V128, vecshiftL64,
8420 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
8421 (i32 vecshiftL64:$imm)))]> {
8423 let Inst{21-16} = imm;
8427 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
8428 SDPatternOperator OpNode> {
8429 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8430 V64, V64, vecshiftR8,
8432 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
8433 (i32 vecshiftR8:$imm)))]> {
8435 let Inst{18-16} = imm;
8438 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8439 V128, V128, vecshiftR8,
8440 asm, ".16b", ".16b",
8441 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
8442 (i32 vecshiftR8:$imm)))]> {
8444 let Inst{18-16} = imm;
8447 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8448 V64, V64, vecshiftR16,
8450 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
8451 (i32 vecshiftR16:$imm)))]> {
8453 let Inst{19-16} = imm;
8456 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8457 V128, V128, vecshiftR16,
8459 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
8460 (i32 vecshiftR16:$imm)))]> {
8462 let Inst{19-16} = imm;
8465 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8466 V64, V64, vecshiftR32,
8468 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
8469 (i32 vecshiftR32:$imm)))]> {
8471 let Inst{20-16} = imm;
8474 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8475 V128, V128, vecshiftR32,
8477 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
8478 (i32 vecshiftR32:$imm)))]> {
8480 let Inst{20-16} = imm;
8483 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8484 V128, V128, vecshiftR64,
8486 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
8487 (i32 vecshiftR64:$imm)))]> {
8489 let Inst{21-16} = imm;
8493 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8494 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
8495 SDPatternOperator OpNode = null_frag> {
8496 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8497 V64, V64, vecshiftR8, asm, ".8b", ".8b",
8498 [(set (v8i8 V64:$dst),
8499 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8500 (i32 vecshiftR8:$imm)))]> {
8502 let Inst{18-16} = imm;
8505 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8506 V128, V128, vecshiftR8, asm, ".16b", ".16b",
8507 [(set (v16i8 V128:$dst),
8508 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8509 (i32 vecshiftR8:$imm)))]> {
8511 let Inst{18-16} = imm;
8514 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8515 V64, V64, vecshiftR16, asm, ".4h", ".4h",
8516 [(set (v4i16 V64:$dst),
8517 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8518 (i32 vecshiftR16:$imm)))]> {
8520 let Inst{19-16} = imm;
8523 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8524 V128, V128, vecshiftR16, asm, ".8h", ".8h",
8525 [(set (v8i16 V128:$dst),
8526 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8527 (i32 vecshiftR16:$imm)))]> {
8529 let Inst{19-16} = imm;
8532 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8533 V64, V64, vecshiftR32, asm, ".2s", ".2s",
8534 [(set (v2i32 V64:$dst),
8535 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8536 (i32 vecshiftR32:$imm)))]> {
8538 let Inst{20-16} = imm;
8541 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8542 V128, V128, vecshiftR32, asm, ".4s", ".4s",
8543 [(set (v4i32 V128:$dst),
8544 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8545 (i32 vecshiftR32:$imm)))]> {
8547 let Inst{20-16} = imm;
8550 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8551 V128, V128, vecshiftR64,
8552 asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
8553 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8554 (i32 vecshiftR64:$imm)))]> {
8556 let Inst{21-16} = imm;
8560 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
8561 SDPatternOperator OpNode = null_frag> {
8562 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8563 V64, V64, vecshiftL8,
8565 [(set (v8i8 V64:$dst),
8566 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8567 (i32 vecshiftL8:$imm)))]> {
8569 let Inst{18-16} = imm;
8572 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8573 V128, V128, vecshiftL8,
8574 asm, ".16b", ".16b",
8575 [(set (v16i8 V128:$dst),
8576 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8577 (i32 vecshiftL8:$imm)))]> {
8579 let Inst{18-16} = imm;
8582 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8583 V64, V64, vecshiftL16,
8585 [(set (v4i16 V64:$dst),
8586 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8587 (i32 vecshiftL16:$imm)))]> {
8589 let Inst{19-16} = imm;
8592 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8593 V128, V128, vecshiftL16,
8595 [(set (v8i16 V128:$dst),
8596 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8597 (i32 vecshiftL16:$imm)))]> {
8599 let Inst{19-16} = imm;
8602 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8603 V64, V64, vecshiftL32,
8605 [(set (v2i32 V64:$dst),
8606 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8607 (i32 vecshiftL32:$imm)))]> {
8609 let Inst{20-16} = imm;
8612 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8613 V128, V128, vecshiftL32,
8615 [(set (v4i32 V128:$dst),
8616 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8617 (i32 vecshiftL32:$imm)))]> {
8619 let Inst{20-16} = imm;
8622 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8623 V128, V128, vecshiftL64,
8625 [(set (v2i64 V128:$dst),
8626 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8627 (i32 vecshiftL64:$imm)))]> {
8629 let Inst{21-16} = imm;
8633 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
8634 SDPatternOperator OpNode> {
8635 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8636 V128, V64, vecshiftL8, asm, ".8h", ".8b",
8637 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
8639 let Inst{18-16} = imm;
8642 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8643 V128, V128, vecshiftL8,
8644 asm#"2", ".8h", ".16b",
8645 [(set (v8i16 V128:$Rd),
8646 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
8648 let Inst{18-16} = imm;
8651 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8652 V128, V64, vecshiftL16, asm, ".4s", ".4h",
8653 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
8655 let Inst{19-16} = imm;
8658 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8659 V128, V128, vecshiftL16,
8660 asm#"2", ".4s", ".8h",
8661 [(set (v4i32 V128:$Rd),
8662 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
8665 let Inst{19-16} = imm;
8668 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8669 V128, V64, vecshiftL32, asm, ".2d", ".2s",
8670 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
8672 let Inst{20-16} = imm;
8675 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8676 V128, V128, vecshiftL32,
8677 asm#"2", ".2d", ".4s",
8678 [(set (v2i64 V128:$Rd),
8679 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
8681 let Inst{20-16} = imm;
8687 // Vector load/store
8689 // SIMD ldX/stX no-index memory references don't allow the optional
8690 // ", #0" constant and handle post-indexing explicitly, so we use
8691 // a more specialized parse method for them. Otherwise, it's the same as
8692 // the general GPR64sp handling.
8694 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
8695 string asm, dag oops, dag iops, list<dag> pattern>
8696 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
8701 let Inst{29-23} = 0b0011000;
8703 let Inst{21-16} = 0b000000;
8704 let Inst{15-12} = opcode;
8705 let Inst{11-10} = size;
8710 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
8711 string asm, dag oops, dag iops>
8712 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
8718 let Inst{29-23} = 0b0011001;
8721 let Inst{20-16} = Xm;
8722 let Inst{15-12} = opcode;
8723 let Inst{11-10} = size;
8728 // The immediate form of AdvSIMD post-indexed addressing is encoded with
8729 // register post-index addressing from the zero register.
8730 multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count,
8731 int Offset, int Size> {
8732 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
8733 // "ld1\t$Vt, [$Rn], #16"
8734 // may get mapped to
8735 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
8736 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8737 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
8739 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8742 // E.g. "ld1.8b { v0, v1 }, [x1], #16"
8743 // "ld1.8b\t$Vt, [$Rn], #16"
8744 // may get mapped to
8745 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
8746 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8747 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
8749 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8752 // E.g. "ld1.8b { v0, v1 }, [x1]"
8753 // "ld1\t$Vt, [$Rn]"
8754 // may get mapped to
8755 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
8756 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8757 (!cast<Instruction>(BaseName # Count # "v" # layout)
8758 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8761 // E.g. "ld1.8b { v0, v1 }, [x1], x2"
8762 // "ld1\t$Vt, [$Rn], $Xm"
8763 // may get mapped to
8764 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
8765 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8766 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")
8768 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8769 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8772 multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist,
8773 int Offset128, int Offset64, bits<4> opcode> {
8774 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8775 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
8776 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
8777 (ins GPR64sp:$Rn), []>;
8778 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
8779 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
8780 (ins GPR64sp:$Rn), []>;
8781 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
8782 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
8783 (ins GPR64sp:$Rn), []>;
8784 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
8785 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
8786 (ins GPR64sp:$Rn), []>;
8787 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
8788 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
8789 (ins GPR64sp:$Rn), []>;
8790 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
8791 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
8792 (ins GPR64sp:$Rn), []>;
8793 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
8794 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
8795 (ins GPR64sp:$Rn), []>;
8798 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
8799 (outs GPR64sp:$wback,
8800 !cast<RegisterOperand>(veclist # "16b"):$Vt),
8802 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8803 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
8804 (outs GPR64sp:$wback,
8805 !cast<RegisterOperand>(veclist # "8h"):$Vt),
8807 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8808 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
8809 (outs GPR64sp:$wback,
8810 !cast<RegisterOperand>(veclist # "4s"):$Vt),
8812 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8813 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
8814 (outs GPR64sp:$wback,
8815 !cast<RegisterOperand>(veclist # "2d"):$Vt),
8817 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8818 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
8819 (outs GPR64sp:$wback,
8820 !cast<RegisterOperand>(veclist # "8b"):$Vt),
8822 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8823 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
8824 (outs GPR64sp:$wback,
8825 !cast<RegisterOperand>(veclist # "4h"):$Vt),
8827 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8828 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
8829 (outs GPR64sp:$wback,
8830 !cast<RegisterOperand>(veclist # "2s"):$Vt),
8832 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8835 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
8836 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
8837 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
8838 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
8839 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
8840 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
8841 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
8844 // Only ld1/st1 has a v1d version.
8845 multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist,
8846 int Offset128, int Offset64, bits<4> opcode> {
8847 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
8848 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
8849 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8851 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
8852 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8854 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
8855 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8857 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
8858 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8860 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
8861 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8863 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
8864 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8866 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
8867 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8870 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
8871 (outs GPR64sp:$wback),
8872 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8874 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8875 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
8876 (outs GPR64sp:$wback),
8877 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8879 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8880 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
8881 (outs GPR64sp:$wback),
8882 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8884 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8885 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
8886 (outs GPR64sp:$wback),
8887 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8889 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8890 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
8891 (outs GPR64sp:$wback),
8892 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8894 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8895 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
8896 (outs GPR64sp:$wback),
8897 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8899 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8900 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
8901 (outs GPR64sp:$wback),
8902 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8904 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8907 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;
8908 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;
8909 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;
8910 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;
8911 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;
8912 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;
8913 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;
8916 multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist,
8917 int Offset128, int Offset64, bits<4> opcode>
8918 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
8920 // LD1 instructions have extra "1d" variants.
8921 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8922 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
8923 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
8924 (ins GPR64sp:$Rn), []>;
8926 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
8927 (outs GPR64sp:$wback,
8928 !cast<RegisterOperand>(veclist # "1d"):$Vt),
8930 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8933 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
8936 multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist,
8937 int Offset128, int Offset64, bits<4> opcode>
8938 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {
8940 // ST1 instructions have extra "1d" variants.
8941 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
8942 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
8943 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8946 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
8947 (outs GPR64sp:$wback),
8948 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8950 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8953 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;
8956 multiclass SIMDLd1Multiple<string asm> {
8957 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>;
8958 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
8959 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
8960 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
8963 multiclass SIMDSt1Multiple<string asm> {
8964 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>;
8965 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;
8966 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;
8967 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;
8970 multiclass SIMDLd2Multiple<string asm> {
8971 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
8974 multiclass SIMDSt2Multiple<string asm> {
8975 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;
8978 multiclass SIMDLd3Multiple<string asm> {
8979 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
8982 multiclass SIMDSt3Multiple<string asm> {
8983 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;
8986 multiclass SIMDLd4Multiple<string asm> {
8987 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
8990 multiclass SIMDSt4Multiple<string asm> {
8991 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;
8995 // AdvSIMD Load/store single-element
8998 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
8999 string asm, string operands, string cst,
9000 dag oops, dag iops, list<dag> pattern>
9001 : I<oops, iops, asm, operands, cst, pattern> {
9005 let Inst{29-24} = 0b001101;
9008 let Inst{15-13} = opcode;
9013 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
9014 string asm, string operands, string cst,
9015 dag oops, dag iops, list<dag> pattern>
9016 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
9020 let Inst{29-24} = 0b001101;
9023 let Inst{15-13} = opcode;
9029 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9030 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
9031 DAGOperand listtype>
9032 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
9033 (outs listtype:$Vt), (ins GPR64sp:$Rn),
9037 let Inst{20-16} = 0b00000;
9039 let Inst{11-10} = size;
9041 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9042 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
9043 string asm, DAGOperand listtype, DAGOperand GPR64pi>
9044 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
9046 (outs GPR64sp:$wback, listtype:$Vt),
9047 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
9051 let Inst{20-16} = Xm;
9053 let Inst{11-10} = size;
9056 multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count,
9057 int Offset, int Size> {
9058 // E.g. "ld1r { v0.8b }, [x1], #1"
9059 // "ld1r.8b\t$Vt, [$Rn], #1"
9060 // may get mapped to
9061 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
9062 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
9063 (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9065 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9068 // E.g. "ld1r.8b { v0 }, [x1], #1"
9069 // "ld1r.8b\t$Vt, [$Rn], #1"
9070 // may get mapped to
9071 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
9072 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
9073 (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9075 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9078 // E.g. "ld1r.8b { v0 }, [x1]"
9079 // "ld1r.8b\t$Vt, [$Rn]"
9080 // may get mapped to
9081 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
9082 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
9083 (!cast<Instruction>(BaseName # "v" # layout)
9084 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9087 // E.g. "ld1r.8b { v0 }, [x1], x2"
9088 // "ld1r.8b\t$Vt, [$Rn], $Xm"
9089 // may get mapped to
9090 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
9091 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
9092 (!cast<Instruction>(BaseName # "v" # layout # "_POST")
9094 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
9095 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9098 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
9099 int Offset1, int Offset2, int Offset4, int Offset8> {
9100 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
9101 !cast<DAGOperand>("VecList" # Count # "8b")>;
9102 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
9103 !cast<DAGOperand>("VecList" # Count #"16b")>;
9104 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
9105 !cast<DAGOperand>("VecList" # Count #"4h")>;
9106 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
9107 !cast<DAGOperand>("VecList" # Count #"8h")>;
9108 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
9109 !cast<DAGOperand>("VecList" # Count #"2s")>;
9110 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
9111 !cast<DAGOperand>("VecList" # Count #"4s")>;
9112 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
9113 !cast<DAGOperand>("VecList" # Count #"1d")>;
9114 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
9115 !cast<DAGOperand>("VecList" # Count #"2d")>;
9117 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
9118 !cast<DAGOperand>("VecList" # Count # "8b"),
9119 !cast<DAGOperand>("GPR64pi" # Offset1)>;
9120 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
9121 !cast<DAGOperand>("VecList" # Count # "16b"),
9122 !cast<DAGOperand>("GPR64pi" # Offset1)>;
9123 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
9124 !cast<DAGOperand>("VecList" # Count # "4h"),
9125 !cast<DAGOperand>("GPR64pi" # Offset2)>;
9126 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
9127 !cast<DAGOperand>("VecList" # Count # "8h"),
9128 !cast<DAGOperand>("GPR64pi" # Offset2)>;
9129 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
9130 !cast<DAGOperand>("VecList" # Count # "2s"),
9131 !cast<DAGOperand>("GPR64pi" # Offset4)>;
9132 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
9133 !cast<DAGOperand>("VecList" # Count # "4s"),
9134 !cast<DAGOperand>("GPR64pi" # Offset4)>;
9135 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
9136 !cast<DAGOperand>("VecList" # Count # "1d"),
9137 !cast<DAGOperand>("GPR64pi" # Offset8)>;
9138 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
9139 !cast<DAGOperand>("VecList" # Count # "2d"),
9140 !cast<DAGOperand>("GPR64pi" # Offset8)>;
9142 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>;
9143 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>;
9144 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>;
9145 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>;
9146 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>;
9147 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>;
9148 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>;
9149 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>;
9152 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
9153 dag oops, dag iops, list<dag> pattern>
9154 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9156 // idx encoded in Q:S:size fields.
9158 let Inst{30} = idx{3};
9160 let Inst{20-16} = 0b00000;
9161 let Inst{12} = idx{2};
9162 let Inst{11-10} = idx{1-0};
9164 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
9165 dag oops, dag iops, list<dag> pattern>
9166 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9167 oops, iops, pattern> {
9168 // idx encoded in Q:S:size fields.
9170 let Inst{30} = idx{3};
9172 let Inst{20-16} = 0b00000;
9173 let Inst{12} = idx{2};
9174 let Inst{11-10} = idx{1-0};
9176 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
9178 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9179 "$Rn = $wback", oops, iops, []> {
9180 // idx encoded in Q:S:size fields.
9183 let Inst{30} = idx{3};
9185 let Inst{20-16} = Xm;
9186 let Inst{12} = idx{2};
9187 let Inst{11-10} = idx{1-0};
9189 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
9191 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9192 "$Rn = $wback", oops, iops, []> {
9193 // idx encoded in Q:S:size fields.
9196 let Inst{30} = idx{3};
9198 let Inst{20-16} = Xm;
9199 let Inst{12} = idx{2};
9200 let Inst{11-10} = idx{1-0};
9203 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
9204 dag oops, dag iops, list<dag> pattern>
9205 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9207 // idx encoded in Q:S:size<1> fields.
9209 let Inst{30} = idx{2};
9211 let Inst{20-16} = 0b00000;
9212 let Inst{12} = idx{1};
9213 let Inst{11} = idx{0};
9214 let Inst{10} = size;
9216 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
9217 dag oops, dag iops, list<dag> pattern>
9218 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9219 oops, iops, pattern> {
9220 // idx encoded in Q:S:size<1> fields.
9222 let Inst{30} = idx{2};
9224 let Inst{20-16} = 0b00000;
9225 let Inst{12} = idx{1};
9226 let Inst{11} = idx{0};
9227 let Inst{10} = size;
9230 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
9232 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9233 "$Rn = $wback", oops, iops, []> {
9234 // idx encoded in Q:S:size<1> fields.
9237 let Inst{30} = idx{2};
9239 let Inst{20-16} = Xm;
9240 let Inst{12} = idx{1};
9241 let Inst{11} = idx{0};
9242 let Inst{10} = size;
9244 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
9246 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9247 "$Rn = $wback", oops, iops, []> {
9248 // idx encoded in Q:S:size<1> fields.
9251 let Inst{30} = idx{2};
9253 let Inst{20-16} = Xm;
9254 let Inst{12} = idx{1};
9255 let Inst{11} = idx{0};
9256 let Inst{10} = size;
9258 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9259 dag oops, dag iops, list<dag> pattern>
9260 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9262 // idx encoded in Q:S fields.
9264 let Inst{30} = idx{1};
9266 let Inst{20-16} = 0b00000;
9267 let Inst{12} = idx{0};
9268 let Inst{11-10} = size;
9270 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9271 dag oops, dag iops, list<dag> pattern>
9272 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9273 oops, iops, pattern> {
9274 // idx encoded in Q:S fields.
9276 let Inst{30} = idx{1};
9278 let Inst{20-16} = 0b00000;
9279 let Inst{12} = idx{0};
9280 let Inst{11-10} = size;
9282 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
9283 string asm, dag oops, dag iops>
9284 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9285 "$Rn = $wback", oops, iops, []> {
9286 // idx encoded in Q:S fields.
9289 let Inst{30} = idx{1};
9291 let Inst{20-16} = Xm;
9292 let Inst{12} = idx{0};
9293 let Inst{11-10} = size;
9295 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
9296 string asm, dag oops, dag iops>
9297 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9298 "$Rn = $wback", oops, iops, []> {
9299 // idx encoded in Q:S fields.
9302 let Inst{30} = idx{1};
9304 let Inst{20-16} = Xm;
9305 let Inst{12} = idx{0};
9306 let Inst{11-10} = size;
9308 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9309 dag oops, dag iops, list<dag> pattern>
9310 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9312 // idx encoded in Q field.
9316 let Inst{20-16} = 0b00000;
9318 let Inst{11-10} = size;
9320 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9321 dag oops, dag iops, list<dag> pattern>
9322 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9323 oops, iops, pattern> {
9324 // idx encoded in Q field.
9328 let Inst{20-16} = 0b00000;
9330 let Inst{11-10} = size;
9332 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
9333 string asm, dag oops, dag iops>
9334 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9335 "$Rn = $wback", oops, iops, []> {
9336 // idx encoded in Q field.
9341 let Inst{20-16} = Xm;
9343 let Inst{11-10} = size;
9345 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
9346 string asm, dag oops, dag iops>
9347 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9348 "$Rn = $wback", oops, iops, []> {
9349 // idx encoded in Q field.
9354 let Inst{20-16} = Xm;
9356 let Inst{11-10} = size;
9359 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9360 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
9361 RegisterOperand listtype,
9362 RegisterOperand GPR64pi> {
9363 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
9364 (outs listtype:$dst),
9365 (ins listtype:$Vt, VectorIndexB:$idx,
9368 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
9369 (outs GPR64sp:$wback, listtype:$dst),
9370 (ins listtype:$Vt, VectorIndexB:$idx,
9371 GPR64sp:$Rn, GPR64pi:$Xm)>;
9373 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9374 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
9375 RegisterOperand listtype,
9376 RegisterOperand GPR64pi> {
9377 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
9378 (outs listtype:$dst),
9379 (ins listtype:$Vt, VectorIndexH:$idx,
9382 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
9383 (outs GPR64sp:$wback, listtype:$dst),
9384 (ins listtype:$Vt, VectorIndexH:$idx,
9385 GPR64sp:$Rn, GPR64pi:$Xm)>;
9387 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9388 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
9389 RegisterOperand listtype,
9390 RegisterOperand GPR64pi> {
9391 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
9392 (outs listtype:$dst),
9393 (ins listtype:$Vt, VectorIndexS:$idx,
9396 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
9397 (outs GPR64sp:$wback, listtype:$dst),
9398 (ins listtype:$Vt, VectorIndexS:$idx,
9399 GPR64sp:$Rn, GPR64pi:$Xm)>;
9401 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9402 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
9403 RegisterOperand listtype, RegisterOperand GPR64pi> {
9404 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
9405 (outs listtype:$dst),
9406 (ins listtype:$Vt, VectorIndexD:$idx,
9409 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
9410 (outs GPR64sp:$wback, listtype:$dst),
9411 (ins listtype:$Vt, VectorIndexD:$idx,
9412 GPR64sp:$Rn, GPR64pi:$Xm)>;
9414 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9415 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
9416 RegisterOperand listtype, RegisterOperand GPR64pi> {
9417 def i8 : SIMDLdStSingleB<0, R, opcode, asm,
9418 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
9421 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
9422 (outs GPR64sp:$wback),
9423 (ins listtype:$Vt, VectorIndexB:$idx,
9424 GPR64sp:$Rn, GPR64pi:$Xm)>;
9426 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9427 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
9428 RegisterOperand listtype, RegisterOperand GPR64pi> {
9429 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
9430 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
9433 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
9434 (outs GPR64sp:$wback),
9435 (ins listtype:$Vt, VectorIndexH:$idx,
9436 GPR64sp:$Rn, GPR64pi:$Xm)>;
9438 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9439 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
9440 RegisterOperand listtype, RegisterOperand GPR64pi> {
9441 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
9442 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
9445 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
9446 (outs GPR64sp:$wback),
9447 (ins listtype:$Vt, VectorIndexS:$idx,
9448 GPR64sp:$Rn, GPR64pi:$Xm)>;
9450 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9451 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
9452 RegisterOperand listtype, RegisterOperand GPR64pi> {
9453 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
9454 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
9457 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
9458 (outs GPR64sp:$wback),
9459 (ins listtype:$Vt, VectorIndexD:$idx,
9460 GPR64sp:$Rn, GPR64pi:$Xm)>;
9463 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
9464 string Count, int Offset, Operand idxtype> {
9465 // E.g. "ld1 { v0.8b }[0], [x1], #1"
9466 // "ld1\t$Vt, [$Rn], #1"
9467 // may get mapped to
9468 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
9469 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
9470 (!cast<Instruction>(NAME # Type # "_POST")
9472 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9473 idxtype:$idx, XZR), 1>;
9475 // E.g. "ld1.8b { v0 }[0], [x1], #1"
9476 // "ld1.8b\t$Vt, [$Rn], #1"
9477 // may get mapped to
9478 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
9479 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
9480 (!cast<Instruction>(NAME # Type # "_POST")
9482 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9483 idxtype:$idx, XZR), 0>;
9485 // E.g. "ld1.8b { v0 }[0], [x1]"
9486 // "ld1.8b\t$Vt, [$Rn]"
9487 // may get mapped to
9488 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
9489 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
9490 (!cast<Instruction>(NAME # Type)
9491 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9492 idxtype:$idx, GPR64sp:$Rn), 0>;
9494 // E.g. "ld1.8b { v0 }[0], [x1], x2"
9495 // "ld1.8b\t$Vt, [$Rn], $Xm"
9496 // may get mapped to
9497 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
9498 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
9499 (!cast<Instruction>(NAME # Type # "_POST")
9501 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9503 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9506 multiclass SIMDLdSt1SingleAliases<string asm> {
9507 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;
9508 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
9509 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
9510 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
9513 multiclass SIMDLdSt2SingleAliases<string asm> {
9514 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;
9515 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;
9516 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;
9517 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
9520 multiclass SIMDLdSt3SingleAliases<string asm> {
9521 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;
9522 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;
9523 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
9524 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
9527 multiclass SIMDLdSt4SingleAliases<string asm> {
9528 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;
9529 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;
9530 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
9531 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
9533 } // end of 'let Predicates = [HasNEON]'
9535 //----------------------------------------------------------------------------
9536 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
9537 //----------------------------------------------------------------------------
9539 let Predicates = [HasNEON, HasRDM] in {
9541 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
9542 RegisterOperand regtype, string asm,
9543 string kind, list<dag> pattern>
9544 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind,
9547 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
9548 SDPatternOperator Accum> {
9549 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
9550 [(set (v4i16 V64:$dst),
9551 (Accum (v4i16 V64:$Rd),
9552 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
9553 (v4i16 V64:$Rm)))))]>;
9554 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
9555 [(set (v8i16 V128:$dst),
9556 (Accum (v8i16 V128:$Rd),
9557 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
9558 (v8i16 V128:$Rm)))))]>;
9559 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
9560 [(set (v2i32 V64:$dst),
9561 (Accum (v2i32 V64:$Rd),
9562 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
9563 (v2i32 V64:$Rm)))))]>;
9564 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
9565 [(set (v4i32 V128:$dst),
9566 (Accum (v4i32 V128:$Rd),
9567 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
9568 (v4i32 V128:$Rm)))))]>;
9571 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
9572 SDPatternOperator Accum> {
9573 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
9574 V64, V64, V128_lo, VectorIndexH,
9575 asm, ".4h", ".4h", ".4h", ".h",
9576 [(set (v4i16 V64:$dst),
9577 (Accum (v4i16 V64:$Rd),
9578 (v4i16 (int_aarch64_neon_sqrdmulh
9580 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
9581 VectorIndexH:$idx))))))]> {
9583 let Inst{11} = idx{2};
9584 let Inst{21} = idx{1};
9585 let Inst{20} = idx{0};
9588 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
9589 V128, V128, V128_lo, VectorIndexH,
9590 asm, ".8h", ".8h", ".8h", ".h",
9591 [(set (v8i16 V128:$dst),
9592 (Accum (v8i16 V128:$Rd),
9593 (v8i16 (int_aarch64_neon_sqrdmulh
9595 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
9596 VectorIndexH:$idx))))))]> {
9598 let Inst{11} = idx{2};
9599 let Inst{21} = idx{1};
9600 let Inst{20} = idx{0};
9603 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
9604 V64, V64, V128, VectorIndexS,
9605 asm, ".2s", ".2s", ".2s", ".s",
9606 [(set (v2i32 V64:$dst),
9607 (Accum (v2i32 V64:$Rd),
9608 (v2i32 (int_aarch64_neon_sqrdmulh
9610 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
9611 VectorIndexS:$idx))))))]> {
9613 let Inst{11} = idx{1};
9614 let Inst{21} = idx{0};
9617 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
9618 // an intermediate EXTRACT_SUBREG would be untyped.
9619 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
9620 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
9621 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9622 (i32 (vector_extract
9623 (v4i32 (insert_subvector
9625 (v2i32 (int_aarch64_neon_sqrdmulh
9627 (v2i32 (AArch64duplane32
9629 VectorIndexS:$idx)))),
9633 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
9634 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
9639 VectorIndexS:$idx)),
9642 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
9643 V128, V128, V128, VectorIndexS,
9644 asm, ".4s", ".4s", ".4s", ".s",
9645 [(set (v4i32 V128:$dst),
9646 (Accum (v4i32 V128:$Rd),
9647 (v4i32 (int_aarch64_neon_sqrdmulh
9649 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
9650 VectorIndexS:$idx))))))]> {
9652 let Inst{11} = idx{1};
9653 let Inst{21} = idx{0};
9656 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
9657 // an intermediate EXTRACT_SUBREG would be untyped.
9658 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9659 (i32 (vector_extract
9660 (v4i32 (int_aarch64_neon_sqrdmulh
9662 (v4i32 (AArch64duplane32
9664 VectorIndexS:$idx)))),
9667 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
9668 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
9673 VectorIndexS:$idx)),
9676 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
9677 FPR16Op, FPR16Op, V128_lo,
9678 VectorIndexH, asm, ".h", "", "", ".h",
9681 let Inst{11} = idx{2};
9682 let Inst{21} = idx{1};
9683 let Inst{20} = idx{0};
9686 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
9687 FPR32Op, FPR32Op, V128, VectorIndexS,
9688 asm, ".s", "", "", ".s",
9689 [(set (i32 FPR32Op:$dst),
9690 (Accum (i32 FPR32Op:$Rd),
9691 (i32 (int_aarch64_neon_sqrdmulh
9693 (i32 (vector_extract (v4i32 V128:$Rm),
9694 VectorIndexS:$idx))))))]> {
9696 let Inst{11} = idx{1};
9697 let Inst{21} = idx{0};
9700 } // let Predicates = [HasNeon, HasRDM]
9702 //----------------------------------------------------------------------------
9703 // ARMv8.3 Complex ADD/MLA instructions
9704 //----------------------------------------------------------------------------
9706 class ComplexRotationOperand<int Angle, int Remainder, string Type>
9708 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">";
9709 let DiagnosticType = "InvalidComplexRotation" # Type;
9710 let Name = "ComplexRotation" # Type;
9712 def complexrotateop : Operand<i32> {
9713 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">;
9714 let PrintMethod = "printComplexRotationOp<90, 0>";
9716 def complexrotateopodd : Operand<i32> {
9717 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">;
9718 let PrintMethod = "printComplexRotationOp<180, 90>";
9721 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9722 class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode,
9723 RegisterOperand regtype, Operand rottype,
9724 string asm, string kind, list<dag> pattern>
9725 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
9726 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
9727 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>,
9736 let Inst{28-24} = 0b01110;
9737 let Inst{23-22} = size;
9739 let Inst{20-16} = Rm;
9740 let Inst{15-13} = opcode;
9741 // Non-tied version (FCADD) only has one rotation bit
9749 multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype,
9750 string asm, SDPatternOperator OpNode>{
9751 let Predicates = [HasV8_3a, HasNEON, HasFullFP16] in {
9752 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype,
9754 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
9757 (rottype i32:$rot)))]>;
9759 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype,
9761 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
9764 (rottype i32:$rot)))]>;
9767 let Predicates = [HasV8_3a, HasNEON] in {
9768 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype,
9770 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
9773 (rottype i32:$rot)))]>;
9775 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype,
9777 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
9780 (rottype i32:$rot)))]>;
9782 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype,
9784 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
9787 (rottype i32:$rot)))]>;
9791 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9792 class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size,
9794 RegisterOperand regtype,
9795 Operand rottype, string asm,
9796 string kind, list<dag> pattern>
9797 : I<(outs regtype:$dst),
9798 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
9799 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
9800 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>,
9809 let Inst{28-24} = 0b01110;
9810 let Inst{23-22} = size;
9812 let Inst{20-16} = Rm;
9813 let Inst{15-13} = opcode;
9814 let Inst{12-11} = rot;
9820 multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode,
9821 Operand rottype, string asm,
9822 SDPatternOperator OpNode> {
9823 let Predicates = [HasV8_3a, HasNEON, HasFullFP16] in {
9824 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64,
9825 rottype, asm, ".4h",
9826 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
9829 (rottype i32:$rot)))]>;
9831 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128,
9832 rottype, asm, ".8h",
9833 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
9836 (rottype i32:$rot)))]>;
9839 let Predicates = [HasV8_3a, HasNEON] in {
9840 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64,
9841 rottype, asm, ".2s",
9842 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
9845 (rottype i32:$rot)))]>;
9847 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128,
9848 rottype, asm, ".4s",
9849 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
9852 (rottype i32:$rot)))]>;
9854 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128,
9855 rottype, asm, ".2d",
9856 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
9859 (rottype i32:$rot)))]>;
9863 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9864 class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size,
9865 bit opc1, bit opc2, RegisterOperand dst_reg,
9866 RegisterOperand lhs_reg,
9867 RegisterOperand rhs_reg, Operand vec_idx,
9868 Operand rottype, string asm, string apple_kind,
9869 string dst_kind, string lhs_kind,
9870 string rhs_kind, list<dag> pattern>
9871 : I<(outs dst_reg:$dst),
9872 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot),
9874 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind #
9875 "$idx, $rot" # "|" # apple_kind #
9876 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>,
9886 let Inst{28} = Scalar;
9887 let Inst{27-24} = 0b1111;
9888 let Inst{23-22} = size;
9889 // Bit 21 must be set by the derived class.
9890 let Inst{20-16} = Rm;
9891 let Inst{15} = opc1;
9892 let Inst{14-13} = rot;
9893 let Inst{12} = opc2;
9894 // Bit 11 must be set by the derived class.
9900 // The complex instructions index by pairs of elements, so the VectorIndexes
9901 // don't match the lane types, and the index bits are different to the other
9903 multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype,
9904 string asm, SDPatternOperator OpNode> {
9905 let Predicates = [HasV8_3a,HasNEON,HasFullFP16] in {
9906 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64,
9907 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h",
9911 let Inst{21} = idx{0};
9914 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2,
9915 V128, V128, V128, VectorIndexS, rottype, asm, ".8h",
9916 ".8h", ".8h", ".h", []> {
9918 let Inst{11} = idx{1};
9919 let Inst{21} = idx{0};
9921 } // Predicates = [HasV8_3a,HasNEON,HasFullFP16]
9923 let Predicates = [HasV8_3a,HasNEON] in {
9924 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2,
9925 V128, V128, V128, VectorIndexD, rottype, asm, ".4s",
9926 ".4s", ".4s", ".s", []> {
9928 let Inst{11} = idx{0};
9931 } // Predicates = [HasV8_3a,HasNEON]
9934 //----------------------------------------------------------------------------
9935 // Crypto extensions
9936 //----------------------------------------------------------------------------
9938 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9939 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
9941 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
9945 let Inst{31-16} = 0b0100111000101000;
9946 let Inst{15-12} = opc;
9947 let Inst{11-10} = 0b10;
9952 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
9953 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
9954 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
9956 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
9957 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
9959 [(set (v16i8 V128:$dst),
9960 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
9962 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9963 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
9964 dag oops, dag iops, list<dag> pat>
9965 : I<oops, iops, asm,
9966 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
9967 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
9972 let Inst{31-21} = 0b01011110000;
9973 let Inst{20-16} = Rm;
9975 let Inst{14-12} = opc;
9976 let Inst{11-10} = 0b00;
9981 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
9982 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9983 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
9984 [(set (v4i32 FPR128:$dst),
9985 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
9986 (v4i32 V128:$Rm)))]>;
9988 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
9989 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
9990 (ins V128:$Rd, V128:$Rn, V128:$Rm),
9991 [(set (v4i32 V128:$dst),
9992 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9993 (v4i32 V128:$Rm)))]>;
9995 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
9996 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9997 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
9998 [(set (v4i32 FPR128:$dst),
9999 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
10000 (v4i32 V128:$Rm)))]>;
10002 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
10003 class SHA2OpInst<bits<4> opc, string asm, string kind,
10004 string cstr, dag oops, dag iops,
10006 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
10007 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
10011 let Inst{31-16} = 0b0101111000101000;
10012 let Inst{15-12} = opc;
10013 let Inst{11-10} = 0b10;
10014 let Inst{9-5} = Rn;
10015 let Inst{4-0} = Rd;
10018 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
10019 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
10020 (ins V128:$Rd, V128:$Rn),
10021 [(set (v4i32 V128:$dst),
10022 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
10024 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
10025 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
10026 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
10028 // Armv8.2-A Crypto extensions
10029 class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst,
10031 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteV]> {
10034 let Inst{31-25} = 0b1100111;
10035 let Inst{9-5} = Vn;
10036 let Inst{4-0} = Vd;
10039 class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops>
10040 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm, asmops,
10042 let Inst{31-25} = 0b1100111;
10043 let Inst{24-21} = 0b0110;
10044 let Inst{20-15} = 0b000001;
10045 let Inst{14} = op0;
10046 let Inst{13-12} = 0b00;
10047 let Inst{11-10} = op1;
10049 class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm>
10050 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d}">;
10051 class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm>
10052 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s}">;
10054 class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm,
10055 string asmops, string cst>
10056 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> {
10058 let Inst{24-21} = 0b0011;
10059 let Inst{20-16} = Vm;
10060 let Inst{15} = 0b1;
10061 let Inst{14} = op0;
10062 let Inst{13-12} = 0b00;
10063 let Inst{11-10} = op1;
10065 class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm>
10066 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
10067 "{\t$Vd.2d, $Vn.2d, $Vm.2d}", "">;
10068 class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm>
10069 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
10070 "{\t$Vd.2d, $Vn.2d, $Vm.2d}", "$Vd = $Vdst">;
10071 class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm>
10072 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,
10073 "{\t$Vd.4s, $Vn.4s, $Vm.4s}", "">;
10074 class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm>
10075 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,
10076 "{\t$Vd.4s, $Vn.4s, $Vm.4s}", "$Vd = $Vdst">;
10077 class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm>
10078 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm),
10079 asm, "{\t$Vd, $Vn, $Vm.2d}", "$Vd = $Vdst">;
10081 class CryptoRRRR<bits<2>op0, string asm, string asmops>
10082 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm,
10086 let Inst{24-23} = 0b00;
10087 let Inst{22-21} = op0;
10088 let Inst{20-16} = Vm;
10089 let Inst{15} = 0b0;
10090 let Inst{14-10} = Va;
10092 class CryptoRRRR_16B<bits<2>op0, string asm>
10093 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b}"> {
10095 class CryptoRRRR_4S<bits<2>op0, string asm>
10096 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s}"> {
10099 class CryptoRRRi6<string asm>
10100 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm,
10101 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm}", "", []> {
10104 let Inst{24-21} = 0b0100;
10105 let Inst{20-16} = Vm;
10106 let Inst{15-10} = imm;
10107 let Inst{9-5} = Vn;
10108 let Inst{4-0} = Vd;
10111 class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm>
10112 : BaseCryptoV82<(outs V128:$Vdst),
10113 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm),
10114 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm}", "$Vd = $Vdst", []> {
10117 let Inst{24-21} = 0b0010;
10118 let Inst{20-16} = Vm;
10119 let Inst{15} = 0b1;
10120 let Inst{14} = op0;
10121 let Inst{13-12} = imm;
10122 let Inst{11-10} = op1;
10125 //----------------------------------------------------------------------------
10126 // v8.1 atomic instructions extension:
10130 // * LDOPregister<OP>, and aliases STOPregister<OP>
10132 // Instruction encodings:
10134 // 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0
10135 // CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt
10136 // CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt
10137 // SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt
10138 // LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt
10139 // ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111
10141 // Instruction syntax:
10143 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10144 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
10145 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
10146 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
10147 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10148 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
10149 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
10150 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
10151 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
10152 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
10154 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
10155 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
10156 string cstr, list<dag> pattern>
10157 : I<oops, iops, asm, operands, cstr, pattern> {
10165 let Inst{31-30} = Sz;
10166 let Inst{29-24} = 0b001000;
10168 let Inst{22} = Acq;
10169 let Inst{21} = 0b1;
10170 let Inst{20-16} = Rs;
10171 let Inst{15} = Rel;
10172 let Inst{14-10} = 0b11111;
10173 let Inst{9-5} = Rn;
10174 let Inst{4-0} = Rt;
10175 let Predicates = [HasLSE];
10178 class BaseCAS<string order, string size, RegisterClass RC>
10179 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
10180 "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
10182 Sched<[WriteAtomic]> {
10186 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
10187 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>;
10188 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>;
10189 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>;
10190 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>;
10193 class BaseCASP<string order, string size, RegisterOperand RC>
10194 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
10195 "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
10197 Sched<[WriteAtomic]> {
10201 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
10202 let Sz = 0b00, Acq = Acq, Rel = Rel in
10203 def W : BaseCASP<order, "", WSeqPairClassOperand>;
10204 let Sz = 0b01, Acq = Acq, Rel = Rel in
10205 def X : BaseCASP<order, "", XSeqPairClassOperand>;
10208 let Predicates = [HasLSE] in
10209 class BaseSWP<string order, string size, RegisterClass RC>
10210 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
10211 "\t$Rs, $Rt, [$Rn]","",[]>,
10212 Sched<[WriteAtomic]> {
10217 bits<3> opc = 0b000;
10220 let Inst{31-30} = Sz;
10221 let Inst{29-24} = 0b111000;
10222 let Inst{23} = Acq;
10223 let Inst{22} = Rel;
10224 let Inst{21} = 0b1;
10225 let Inst{20-16} = Rs;
10226 let Inst{15} = 0b1;
10227 let Inst{14-12} = opc;
10228 let Inst{11-10} = 0b00;
10229 let Inst{9-5} = Rn;
10230 let Inst{4-0} = Rt;
10231 let Predicates = [HasLSE];
10234 multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
10235 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>;
10236 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>;
10237 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>;
10238 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>;
10241 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
10242 class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
10243 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
10244 "\t$Rs, $Rt, [$Rn]","",[]>,
10245 Sched<[WriteAtomic]> {
10253 let Inst{31-30} = Sz;
10254 let Inst{29-24} = 0b111000;
10255 let Inst{23} = Acq;
10256 let Inst{22} = Rel;
10257 let Inst{21} = 0b1;
10258 let Inst{20-16} = Rs;
10259 let Inst{15} = 0b0;
10260 let Inst{14-12} = opc;
10261 let Inst{11-10} = 0b00;
10262 let Inst{9-5} = Rn;
10263 let Inst{4-0} = Rt;
10264 let Predicates = [HasLSE];
10267 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
10269 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
10270 def B : BaseLDOPregister<op, order, "b", GPR32>;
10271 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
10272 def H : BaseLDOPregister<op, order, "h", GPR32>;
10273 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
10274 def W : BaseLDOPregister<op, order, "", GPR32>;
10275 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
10276 def X : BaseLDOPregister<op, order, "", GPR64>;
10279 // Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more
10280 // complex DAG for DstRHS.
10281 let Predicates = [HasLSE] in
10282 multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op,
10283 string size, dag SrcRHS, dag DstRHS> {
10284 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS),
10285 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>;
10286 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS),
10287 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>;
10288 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS),
10289 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>;
10290 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS),
10291 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
10292 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS),
10293 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
10296 multiclass LDOPregister_patterns_ord<string inst, string suffix, string op,
10297 string size, dag RHS> {
10298 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>;
10301 multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op,
10302 string size, dag LHS, dag RHS> {
10303 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>;
10306 multiclass LDOPregister_patterns<string inst, string op> {
10307 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>;
10308 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>;
10309 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>;
10310 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>;
10313 multiclass LDOPregister_patterns_mod<string inst, string op, string mod> {
10314 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64",
10316 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>;
10317 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32",
10319 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
10320 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16",
10322 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
10323 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8",
10325 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
10328 let Predicates = [HasLSE] in
10329 multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op,
10330 string size, dag OLD, dag NEW> {
10331 def : Pat<(!cast<PatFrag>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW),
10332 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>;
10333 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW),
10334 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10335 def : Pat<(!cast<PatFrag>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW),
10336 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10337 def : Pat<(!cast<PatFrag>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW),
10338 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10339 def : Pat<(!cast<PatFrag>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW),
10340 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
10343 multiclass CASregister_patterns_ord<string inst, string suffix, string op,
10344 string size, dag OLD, dag NEW> {
10345 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>;
10348 multiclass CASregister_patterns<string inst, string op> {
10349 defm : CASregister_patterns_ord<inst, "X", op, "64",
10350 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>;
10351 defm : CASregister_patterns_ord<inst, "W", op, "32",
10352 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
10353 defm : CASregister_patterns_ord<inst, "H", op, "16",
10354 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
10355 defm : CASregister_patterns_ord<inst, "B", op, "8",
10356 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
10359 let Predicates = [HasLSE] in
10360 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
10361 Instruction inst> :
10362 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
10364 multiclass STOPregister<string asm, string instr> {
10365 def : BaseSTOPregister<asm # "lb", GPR32, WZR,
10366 !cast<Instruction>(instr # "LB")>;
10367 def : BaseSTOPregister<asm # "lh", GPR32, WZR,
10368 !cast<Instruction>(instr # "LH")>;
10369 def : BaseSTOPregister<asm # "l", GPR32, WZR,
10370 !cast<Instruction>(instr # "LW")>;
10371 def : BaseSTOPregister<asm # "l", GPR64, XZR,
10372 !cast<Instruction>(instr # "LX")>;
10373 def : BaseSTOPregister<asm # "b", GPR32, WZR,
10374 !cast<Instruction>(instr # "B")>;
10375 def : BaseSTOPregister<asm # "h", GPR32, WZR,
10376 !cast<Instruction>(instr # "H")>;
10377 def : BaseSTOPregister<asm, GPR32, WZR,
10378 !cast<Instruction>(instr # "W")>;
10379 def : BaseSTOPregister<asm, GPR64, XZR,
10380 !cast<Instruction>(instr # "X")>;
10383 //----------------------------------------------------------------------------
10384 // Allow the size specifier tokens to be upper case, not just lower.
10385 def : TokenAlias<".4B", ".4b">; // Add dot product
10386 def : TokenAlias<".8B", ".8b">;
10387 def : TokenAlias<".4H", ".4h">;
10388 def : TokenAlias<".2S", ".2s">;
10389 def : TokenAlias<".1D", ".1d">;
10390 def : TokenAlias<".16B", ".16b">;
10391 def : TokenAlias<".8H", ".8h">;
10392 def : TokenAlias<".4S", ".4s">;
10393 def : TokenAlias<".2D", ".2d">;
10394 def : TokenAlias<".1Q", ".1q">;
10395 def : TokenAlias<".2H", ".2h">;
10396 def : TokenAlias<".B", ".b">;
10397 def : TokenAlias<".H", ".h">;
10398 def : TokenAlias<".S", ".s">;
10399 def : TokenAlias<".D", ".d">;
10400 def : TokenAlias<".Q", ".q">;