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 // Normal instructions
61 class I<dag oops, dag iops, string asm, string operands, string cstr,
63 : EncodedI<cstr, pattern> {
64 dag OutOperandList = oops;
65 dag InOperandList = iops;
66 let AsmString = !strconcat(asm, operands);
69 class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>;
70 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
71 class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>;
73 // Helper fragment for an extract of the high portion of a 128-bit vector.
74 def extract_high_v16i8 :
75 UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>;
76 def extract_high_v8i16 :
77 UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>;
78 def extract_high_v4i32 :
79 UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>;
80 def extract_high_v2i64 :
81 UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>;
83 //===----------------------------------------------------------------------===//
84 // Asm Operand Classes.
87 // Shifter operand for arithmetic shifted encodings.
88 def ShifterOperand : AsmOperandClass {
92 // Shifter operand for mov immediate encodings.
93 def MovImm32ShifterOperand : AsmOperandClass {
94 let SuperClasses = [ShifterOperand];
95 let Name = "MovImm32Shifter";
96 let RenderMethod = "addShifterOperands";
97 let DiagnosticType = "InvalidMovImm32Shift";
99 def MovImm64ShifterOperand : AsmOperandClass {
100 let SuperClasses = [ShifterOperand];
101 let Name = "MovImm64Shifter";
102 let RenderMethod = "addShifterOperands";
103 let DiagnosticType = "InvalidMovImm64Shift";
106 // Shifter operand for arithmetic register shifted encodings.
107 class ArithmeticShifterOperand<int width> : AsmOperandClass {
108 let SuperClasses = [ShifterOperand];
109 let Name = "ArithmeticShifter" # width;
110 let PredicateMethod = "isArithmeticShifter<" # width # ">";
111 let RenderMethod = "addShifterOperands";
112 let DiagnosticType = "AddSubRegShift" # width;
115 def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
116 def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
118 // Shifter operand for logical register shifted encodings.
119 class LogicalShifterOperand<int width> : AsmOperandClass {
120 let SuperClasses = [ShifterOperand];
121 let Name = "LogicalShifter" # width;
122 let PredicateMethod = "isLogicalShifter<" # width # ">";
123 let RenderMethod = "addShifterOperands";
124 let DiagnosticType = "AddSubRegShift" # width;
127 def LogicalShifterOperand32 : LogicalShifterOperand<32>;
128 def LogicalShifterOperand64 : LogicalShifterOperand<64>;
130 // Shifter operand for logical vector 128/64-bit shifted encodings.
131 def LogicalVecShifterOperand : AsmOperandClass {
132 let SuperClasses = [ShifterOperand];
133 let Name = "LogicalVecShifter";
134 let RenderMethod = "addShifterOperands";
136 def LogicalVecHalfWordShifterOperand : AsmOperandClass {
137 let SuperClasses = [LogicalVecShifterOperand];
138 let Name = "LogicalVecHalfWordShifter";
139 let RenderMethod = "addShifterOperands";
142 // The "MSL" shifter on the vector MOVI instruction.
143 def MoveVecShifterOperand : AsmOperandClass {
144 let SuperClasses = [ShifterOperand];
145 let Name = "MoveVecShifter";
146 let RenderMethod = "addShifterOperands";
149 // Extend operand for arithmetic encodings.
150 def ExtendOperand : AsmOperandClass {
152 let DiagnosticType = "AddSubRegExtendLarge";
154 def ExtendOperand64 : AsmOperandClass {
155 let SuperClasses = [ExtendOperand];
156 let Name = "Extend64";
157 let DiagnosticType = "AddSubRegExtendSmall";
159 // 'extend' that's a lsl of a 64-bit register.
160 def ExtendOperandLSL64 : AsmOperandClass {
161 let SuperClasses = [ExtendOperand];
162 let Name = "ExtendLSL64";
163 let RenderMethod = "addExtend64Operands";
164 let DiagnosticType = "AddSubRegExtendLarge";
167 // 8-bit floating-point immediate encodings.
168 def FPImmOperand : AsmOperandClass {
170 let ParserMethod = "tryParseFPImm";
171 let DiagnosticType = "InvalidFPImm";
174 def CondCode : AsmOperandClass {
175 let Name = "CondCode";
176 let DiagnosticType = "InvalidCondCode";
179 // A 32-bit register pasrsed as 64-bit
180 def GPR32as64Operand : AsmOperandClass {
181 let Name = "GPR32as64";
183 def GPR32as64 : RegisterOperand<GPR32> {
184 let ParserMatchClass = GPR32as64Operand;
187 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
188 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
189 // are encoded as the eight bit value 'abcdefgh'.
190 def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
192 // Authenticated loads for v8.3 can have scaled 10-bit immediate offsets.
193 def SImm10s8Operand : AsmOperandClass {
194 let Name = "SImm10s8";
195 let DiagnosticType = "InvalidMemoryIndexedSImm10";
198 //===----------------------------------------------------------------------===//
199 // Operand Definitions.
202 // ADR[P] instruction labels.
203 def AdrpOperand : AsmOperandClass {
204 let Name = "AdrpLabel";
205 let ParserMethod = "tryParseAdrpLabel";
206 let DiagnosticType = "InvalidLabel";
208 def adrplabel : Operand<i64> {
209 let EncoderMethod = "getAdrLabelOpValue";
210 let PrintMethod = "printAdrpLabel";
211 let ParserMatchClass = AdrpOperand;
214 def AdrOperand : AsmOperandClass {
215 let Name = "AdrLabel";
216 let ParserMethod = "tryParseAdrLabel";
217 let DiagnosticType = "InvalidLabel";
219 def adrlabel : Operand<i64> {
220 let EncoderMethod = "getAdrLabelOpValue";
221 let ParserMatchClass = AdrOperand;
224 def simm10Scaled : Operand<i64> {
225 let ParserMatchClass = SImm10s8Operand;
226 let DecoderMethod = "DecodeSImm<10>";
227 let PrintMethod = "printImmScale<8>";
230 // simm9 predicate - True if the immediate is in the range [-256, 255].
231 def SImm9Operand : AsmOperandClass {
233 let DiagnosticType = "InvalidMemoryIndexedSImm9";
235 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
236 let ParserMatchClass = SImm9Operand;
239 // simm7sN predicate - True if the immediate is a multiple of N in the range
240 // [-64 * N, 63 * N].
241 class SImm7Scaled<int Scale> : AsmOperandClass {
242 let Name = "SImm7s" # Scale;
243 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm7";
246 def SImm7s4Operand : SImm7Scaled<4>;
247 def SImm7s8Operand : SImm7Scaled<8>;
248 def SImm7s16Operand : SImm7Scaled<16>;
250 def simm7s4 : Operand<i32> {
251 let ParserMatchClass = SImm7s4Operand;
252 let PrintMethod = "printImmScale<4>";
255 def simm7s8 : Operand<i32> {
256 let ParserMatchClass = SImm7s8Operand;
257 let PrintMethod = "printImmScale<8>";
260 def simm7s16 : Operand<i32> {
261 let ParserMatchClass = SImm7s16Operand;
262 let PrintMethod = "printImmScale<16>";
265 def am_indexed7s8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>;
266 def am_indexed7s16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>;
267 def am_indexed7s32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>;
268 def am_indexed7s64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>;
269 def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>;
271 class AsmImmRange<int Low, int High> : AsmOperandClass {
272 let Name = "Imm" # Low # "_" # High;
273 let DiagnosticType = "InvalidImm" # Low # "_" # High;
274 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">";
277 def Imm1_8Operand : AsmImmRange<1, 8>;
278 def Imm1_16Operand : AsmImmRange<1, 16>;
279 def Imm1_32Operand : AsmImmRange<1, 32>;
280 def Imm1_64Operand : AsmImmRange<1, 64>;
282 class BranchTarget<int N> : AsmOperandClass {
283 let Name = "BranchTarget" # N;
284 let DiagnosticType = "InvalidLabel";
285 let PredicateMethod = "isBranchTarget<" # N # ">";
288 class PCRelLabel<int N> : BranchTarget<N> {
289 let Name = "PCRelLabel" # N;
292 def BranchTarget14Operand : BranchTarget<14>;
293 def BranchTarget26Operand : BranchTarget<26>;
294 def PCRelLabel19Operand : PCRelLabel<19>;
296 def MovZSymbolG3AsmOperand : AsmOperandClass {
297 let Name = "MovZSymbolG3";
298 let RenderMethod = "addImmOperands";
301 def movz_symbol_g3 : Operand<i32> {
302 let ParserMatchClass = MovZSymbolG3AsmOperand;
305 def MovZSymbolG2AsmOperand : AsmOperandClass {
306 let Name = "MovZSymbolG2";
307 let RenderMethod = "addImmOperands";
310 def movz_symbol_g2 : Operand<i32> {
311 let ParserMatchClass = MovZSymbolG2AsmOperand;
314 def MovZSymbolG1AsmOperand : AsmOperandClass {
315 let Name = "MovZSymbolG1";
316 let RenderMethod = "addImmOperands";
319 def movz_symbol_g1 : Operand<i32> {
320 let ParserMatchClass = MovZSymbolG1AsmOperand;
323 def MovZSymbolG0AsmOperand : AsmOperandClass {
324 let Name = "MovZSymbolG0";
325 let RenderMethod = "addImmOperands";
328 def movz_symbol_g0 : Operand<i32> {
329 let ParserMatchClass = MovZSymbolG0AsmOperand;
332 def MovKSymbolG3AsmOperand : AsmOperandClass {
333 let Name = "MovKSymbolG3";
334 let RenderMethod = "addImmOperands";
337 def movk_symbol_g3 : Operand<i32> {
338 let ParserMatchClass = MovKSymbolG3AsmOperand;
341 def MovKSymbolG2AsmOperand : AsmOperandClass {
342 let Name = "MovKSymbolG2";
343 let RenderMethod = "addImmOperands";
346 def movk_symbol_g2 : Operand<i32> {
347 let ParserMatchClass = MovKSymbolG2AsmOperand;
350 def MovKSymbolG1AsmOperand : AsmOperandClass {
351 let Name = "MovKSymbolG1";
352 let RenderMethod = "addImmOperands";
355 def movk_symbol_g1 : Operand<i32> {
356 let ParserMatchClass = MovKSymbolG1AsmOperand;
359 def MovKSymbolG0AsmOperand : AsmOperandClass {
360 let Name = "MovKSymbolG0";
361 let RenderMethod = "addImmOperands";
364 def movk_symbol_g0 : Operand<i32> {
365 let ParserMatchClass = MovKSymbolG0AsmOperand;
368 class fixedpoint_i32<ValueType FloatVT>
370 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
371 let EncoderMethod = "getFixedPointScaleOpValue";
372 let DecoderMethod = "DecodeFixedPointScaleImm32";
373 let ParserMatchClass = Imm1_32Operand;
376 class fixedpoint_i64<ValueType FloatVT>
378 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
379 let EncoderMethod = "getFixedPointScaleOpValue";
380 let DecoderMethod = "DecodeFixedPointScaleImm64";
381 let ParserMatchClass = Imm1_64Operand;
384 def fixedpoint_f16_i32 : fixedpoint_i32<f16>;
385 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
386 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
388 def fixedpoint_f16_i64 : fixedpoint_i64<f16>;
389 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
390 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
392 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
393 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
395 let EncoderMethod = "getVecShiftR8OpValue";
396 let DecoderMethod = "DecodeVecShiftR8Imm";
397 let ParserMatchClass = Imm1_8Operand;
399 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
400 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
402 let EncoderMethod = "getVecShiftR16OpValue";
403 let DecoderMethod = "DecodeVecShiftR16Imm";
404 let ParserMatchClass = Imm1_16Operand;
406 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
407 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
409 let EncoderMethod = "getVecShiftR16OpValue";
410 let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
411 let ParserMatchClass = Imm1_8Operand;
413 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
414 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
416 let EncoderMethod = "getVecShiftR32OpValue";
417 let DecoderMethod = "DecodeVecShiftR32Imm";
418 let ParserMatchClass = Imm1_32Operand;
420 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
421 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
423 let EncoderMethod = "getVecShiftR32OpValue";
424 let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
425 let ParserMatchClass = Imm1_16Operand;
427 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
428 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
430 let EncoderMethod = "getVecShiftR64OpValue";
431 let DecoderMethod = "DecodeVecShiftR64Imm";
432 let ParserMatchClass = Imm1_64Operand;
434 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
435 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
437 let EncoderMethod = "getVecShiftR64OpValue";
438 let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
439 let ParserMatchClass = Imm1_32Operand;
442 def Imm0_1Operand : AsmImmRange<0, 1>;
443 def Imm0_7Operand : AsmImmRange<0, 7>;
444 def Imm0_15Operand : AsmImmRange<0, 15>;
445 def Imm0_31Operand : AsmImmRange<0, 31>;
446 def Imm0_63Operand : AsmImmRange<0, 63>;
448 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
449 return (((uint32_t)Imm) < 8);
451 let EncoderMethod = "getVecShiftL8OpValue";
452 let DecoderMethod = "DecodeVecShiftL8Imm";
453 let ParserMatchClass = Imm0_7Operand;
455 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
456 return (((uint32_t)Imm) < 16);
458 let EncoderMethod = "getVecShiftL16OpValue";
459 let DecoderMethod = "DecodeVecShiftL16Imm";
460 let ParserMatchClass = Imm0_15Operand;
462 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
463 return (((uint32_t)Imm) < 32);
465 let EncoderMethod = "getVecShiftL32OpValue";
466 let DecoderMethod = "DecodeVecShiftL32Imm";
467 let ParserMatchClass = Imm0_31Operand;
469 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
470 return (((uint32_t)Imm) < 64);
472 let EncoderMethod = "getVecShiftL64OpValue";
473 let DecoderMethod = "DecodeVecShiftL64Imm";
474 let ParserMatchClass = Imm0_63Operand;
478 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
479 // instructions for splatting repeating bit patterns across the immediate.
480 def logical_imm32_XFORM : SDNodeXForm<imm, [{
481 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
482 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
484 def logical_imm64_XFORM : SDNodeXForm<imm, [{
485 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
486 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
489 let DiagnosticType = "LogicalSecondSource" in {
490 def LogicalImm32Operand : AsmOperandClass {
491 let Name = "LogicalImm32";
493 def LogicalImm64Operand : AsmOperandClass {
494 let Name = "LogicalImm64";
496 def LogicalImm32NotOperand : AsmOperandClass {
497 let Name = "LogicalImm32Not";
499 def LogicalImm64NotOperand : AsmOperandClass {
500 let Name = "LogicalImm64Not";
503 def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{
504 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32);
505 }], logical_imm32_XFORM> {
506 let PrintMethod = "printLogicalImm32";
507 let ParserMatchClass = LogicalImm32Operand;
509 def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{
510 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64);
511 }], logical_imm64_XFORM> {
512 let PrintMethod = "printLogicalImm64";
513 let ParserMatchClass = LogicalImm64Operand;
515 def logical_imm32_not : Operand<i32> {
516 let ParserMatchClass = LogicalImm32NotOperand;
518 def logical_imm64_not : Operand<i64> {
519 let ParserMatchClass = LogicalImm64NotOperand;
522 // imm0_65535 predicate - True if the immediate is in the range [0,65535].
523 def Imm0_65535Operand : AsmImmRange<0, 65535>;
524 def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
525 return ((uint32_t)Imm) < 65536;
527 let ParserMatchClass = Imm0_65535Operand;
528 let PrintMethod = "printImmHex";
531 // imm0_255 predicate - True if the immediate is in the range [0,255].
532 def Imm0_255Operand : AsmImmRange<0,255>;
534 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
535 return ((uint32_t)Imm) < 256;
537 let ParserMatchClass = Imm0_255Operand;
538 let PrintMethod = "printImm";
541 // imm0_127 predicate - True if the immediate is in the range [0,127]
542 def Imm0_127Operand : AsmImmRange<0, 127>;
543 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
544 return ((uint32_t)Imm) < 128;
546 let ParserMatchClass = Imm0_127Operand;
547 let PrintMethod = "printImm";
550 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
551 // for all shift-amounts.
553 // imm0_63 predicate - True if the immediate is in the range [0,63]
554 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
555 return ((uint64_t)Imm) < 64;
557 let ParserMatchClass = Imm0_63Operand;
560 // imm0_31 predicate - True if the immediate is in the range [0,31]
561 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
562 return ((uint64_t)Imm) < 32;
564 let ParserMatchClass = Imm0_31Operand;
567 // True if the 32-bit immediate is in the range [0,31]
568 def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
569 return ((uint64_t)Imm) < 32;
571 let ParserMatchClass = Imm0_31Operand;
574 // imm0_1 predicate - True if the immediate is in the range [0,1]
575 def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
576 return ((uint64_t)Imm) < 2;
578 let ParserMatchClass = Imm0_1Operand;
581 // imm0_15 predicate - True if the immediate is in the range [0,15]
582 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
583 return ((uint64_t)Imm) < 16;
585 let ParserMatchClass = Imm0_15Operand;
588 // imm0_7 predicate - True if the immediate is in the range [0,7]
589 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
590 return ((uint64_t)Imm) < 8;
592 let ParserMatchClass = Imm0_7Operand;
595 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
596 def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
597 return ((uint32_t)Imm) < 16;
599 let ParserMatchClass = Imm0_15Operand;
602 // An arithmetic shifter operand:
603 // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
605 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
606 let PrintMethod = "printShifter";
607 let ParserMatchClass = !cast<AsmOperandClass>(
608 "ArithmeticShifterOperand" # width);
611 def arith_shift32 : arith_shift<i32, 32>;
612 def arith_shift64 : arith_shift<i64, 64>;
614 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
616 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
617 let PrintMethod = "printShiftedRegister";
618 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
621 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
622 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
624 // An arithmetic shifter operand:
625 // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
627 class logical_shift<int width> : Operand<i32> {
628 let PrintMethod = "printShifter";
629 let ParserMatchClass = !cast<AsmOperandClass>(
630 "LogicalShifterOperand" # width);
633 def logical_shift32 : logical_shift<32>;
634 def logical_shift64 : logical_shift<64>;
636 class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
638 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
639 let PrintMethod = "printShiftedRegister";
640 let MIOperandInfo = (ops regclass, shiftop);
643 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
644 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
646 // A logical vector shifter operand:
647 // {7-6} - shift type: 00 = lsl
648 // {5-0} - imm6: #0, #8, #16, or #24
649 def logical_vec_shift : Operand<i32> {
650 let PrintMethod = "printShifter";
651 let EncoderMethod = "getVecShifterOpValue";
652 let ParserMatchClass = LogicalVecShifterOperand;
655 // A logical vector half-word shifter operand:
656 // {7-6} - shift type: 00 = lsl
657 // {5-0} - imm6: #0 or #8
658 def logical_vec_hw_shift : Operand<i32> {
659 let PrintMethod = "printShifter";
660 let EncoderMethod = "getVecShifterOpValue";
661 let ParserMatchClass = LogicalVecHalfWordShifterOperand;
664 // A vector move shifter operand:
665 // {0} - imm1: #8 or #16
666 def move_vec_shift : Operand<i32> {
667 let PrintMethod = "printShifter";
668 let EncoderMethod = "getMoveVecShifterOpValue";
669 let ParserMatchClass = MoveVecShifterOperand;
672 let DiagnosticType = "AddSubSecondSource" in {
673 def AddSubImmOperand : AsmOperandClass {
674 let Name = "AddSubImm";
675 let ParserMethod = "tryParseAddSubImm";
677 def AddSubImmNegOperand : AsmOperandClass {
678 let Name = "AddSubImmNeg";
679 let ParserMethod = "tryParseAddSubImm";
682 // An ADD/SUB immediate shifter operand:
684 // {7-6} - shift type: 00 = lsl
685 // {5-0} - imm6: #0 or #12
686 class addsub_shifted_imm<ValueType Ty>
687 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
688 let PrintMethod = "printAddSubImm";
689 let EncoderMethod = "getAddSubImmOpValue";
690 let ParserMatchClass = AddSubImmOperand;
691 let MIOperandInfo = (ops i32imm, i32imm);
694 class addsub_shifted_imm_neg<ValueType Ty>
696 let EncoderMethod = "getAddSubImmOpValue";
697 let ParserMatchClass = AddSubImmNegOperand;
698 let MIOperandInfo = (ops i32imm, i32imm);
701 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
702 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
703 def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
704 def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
706 def gi_addsub_shifted_imm32 :
707 GIComplexOperandMatcher<s32, "selectArithImmed">,
708 GIComplexPatternEquiv<addsub_shifted_imm32>;
710 def gi_addsub_shifted_imm64 :
711 GIComplexOperandMatcher<s64, "selectArithImmed">,
712 GIComplexPatternEquiv<addsub_shifted_imm64>;
714 class neg_addsub_shifted_imm<ValueType Ty>
715 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
716 let PrintMethod = "printAddSubImm";
717 let EncoderMethod = "getAddSubImmOpValue";
718 let ParserMatchClass = AddSubImmOperand;
719 let MIOperandInfo = (ops i32imm, i32imm);
722 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
723 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
725 // An extend operand:
726 // {5-3} - extend type
728 def arith_extend : Operand<i32> {
729 let PrintMethod = "printArithExtend";
730 let ParserMatchClass = ExtendOperand;
732 def arith_extend64 : Operand<i32> {
733 let PrintMethod = "printArithExtend";
734 let ParserMatchClass = ExtendOperand64;
737 // 'extend' that's a lsl of a 64-bit register.
738 def arith_extendlsl64 : Operand<i32> {
739 let PrintMethod = "printArithExtend";
740 let ParserMatchClass = ExtendOperandLSL64;
743 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
744 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
745 let PrintMethod = "printExtendedRegister";
746 let MIOperandInfo = (ops GPR32, arith_extend);
749 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
750 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
751 let PrintMethod = "printExtendedRegister";
752 let MIOperandInfo = (ops GPR32, arith_extend64);
755 // Floating-point immediate.
756 def fpimm16 : Operand<f16>,
758 return AArch64_AM::getFP16Imm(Imm) != -1;
759 }], SDNodeXForm<fpimm, [{
760 APFloat InVal = N->getValueAPF();
761 uint32_t enc = AArch64_AM::getFP16Imm(InVal);
762 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
764 let ParserMatchClass = FPImmOperand;
765 let PrintMethod = "printFPImmOperand";
767 def fpimm32 : Operand<f32>,
769 return AArch64_AM::getFP32Imm(Imm) != -1;
770 }], SDNodeXForm<fpimm, [{
771 APFloat InVal = N->getValueAPF();
772 uint32_t enc = AArch64_AM::getFP32Imm(InVal);
773 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
775 let ParserMatchClass = FPImmOperand;
776 let PrintMethod = "printFPImmOperand";
778 def fpimm64 : Operand<f64>,
780 return AArch64_AM::getFP64Imm(Imm) != -1;
781 }], SDNodeXForm<fpimm, [{
782 APFloat InVal = N->getValueAPF();
783 uint32_t enc = AArch64_AM::getFP64Imm(InVal);
784 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
786 let ParserMatchClass = FPImmOperand;
787 let PrintMethod = "printFPImmOperand";
790 def fpimm8 : Operand<i32> {
791 let ParserMatchClass = FPImmOperand;
792 let PrintMethod = "printFPImmOperand";
795 def fpimm0 : FPImmLeaf<fAny, [{
796 return Imm.isExactlyValue(+0.0);
799 // Vector lane operands
800 class AsmVectorIndex<string Suffix> : AsmOperandClass {
801 let Name = "VectorIndex" # Suffix;
802 let DiagnosticType = "InvalidIndex" # Suffix;
804 def VectorIndex1Operand : AsmVectorIndex<"1">;
805 def VectorIndexBOperand : AsmVectorIndex<"B">;
806 def VectorIndexHOperand : AsmVectorIndex<"H">;
807 def VectorIndexSOperand : AsmVectorIndex<"S">;
808 def VectorIndexDOperand : AsmVectorIndex<"D">;
810 def VectorIndex1 : Operand<i64>, ImmLeaf<i64, [{
811 return ((uint64_t)Imm) == 1;
813 let ParserMatchClass = VectorIndex1Operand;
814 let PrintMethod = "printVectorIndex";
815 let MIOperandInfo = (ops i64imm);
817 def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
818 return ((uint64_t)Imm) < 16;
820 let ParserMatchClass = VectorIndexBOperand;
821 let PrintMethod = "printVectorIndex";
822 let MIOperandInfo = (ops i64imm);
824 def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
825 return ((uint64_t)Imm) < 8;
827 let ParserMatchClass = VectorIndexHOperand;
828 let PrintMethod = "printVectorIndex";
829 let MIOperandInfo = (ops i64imm);
831 def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
832 return ((uint64_t)Imm) < 4;
834 let ParserMatchClass = VectorIndexSOperand;
835 let PrintMethod = "printVectorIndex";
836 let MIOperandInfo = (ops i64imm);
838 def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
839 return ((uint64_t)Imm) < 2;
841 let ParserMatchClass = VectorIndexDOperand;
842 let PrintMethod = "printVectorIndex";
843 let MIOperandInfo = (ops i64imm);
846 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
847 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
848 // are encoded as the eight bit value 'abcdefgh'.
849 def simdimmtype10 : Operand<i32>,
851 return AArch64_AM::isAdvSIMDModImmType10(
852 Imm.bitcastToAPInt().getZExtValue());
853 }], SDNodeXForm<fpimm, [{
854 APFloat InVal = N->getValueAPF();
855 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
858 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
860 let ParserMatchClass = SIMDImmType10Operand;
861 let PrintMethod = "printSIMDType10Operand";
869 // Base encoding for system instruction operands.
870 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
871 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
872 list<dag> pattern = []>
873 : I<oops, iops, asm, operands, "", pattern> {
874 let Inst{31-22} = 0b1101010100;
878 // System instructions which do not have an Rt register.
879 class SimpleSystemI<bit L, dag iops, string asm, string operands,
880 list<dag> pattern = []>
881 : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
882 let Inst{4-0} = 0b11111;
885 // System instructions which have an Rt register.
886 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
887 : BaseSystemI<L, oops, iops, asm, operands>,
893 // Hint instructions that take both a CRm and a 3-bit immediate.
894 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
895 // model patterns with sufficiently fine granularity
896 let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
897 class HintI<string mnemonic>
898 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
899 [(int_aarch64_hint imm0_127:$imm)]>,
902 let Inst{20-12} = 0b000110010;
903 let Inst{11-5} = imm;
906 // System instructions taking a single literal operand which encodes into
907 // CRm. op2 differentiates the opcodes.
908 def BarrierAsmOperand : AsmOperandClass {
909 let Name = "Barrier";
910 let ParserMethod = "tryParseBarrierOperand";
912 def barrier_op : Operand<i32> {
913 let PrintMethod = "printBarrierOption";
914 let ParserMatchClass = BarrierAsmOperand;
916 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
917 list<dag> pattern = []>
918 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
919 Sched<[WriteBarrier]> {
921 let Inst{20-12} = 0b000110011;
922 let Inst{11-8} = CRm;
926 class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []>
927 : SimpleSystemI<0, (ins), asm, "", pattern>,
931 let Inst{31-12} = 0b11010101000000110010;
932 let Inst{11-8} = CRm;
934 let Inst{4-0} = 0b11111;
937 // MRS/MSR system instructions. These have different operand classes because
938 // a different subset of registers can be accessed through each instruction.
939 def MRSSystemRegisterOperand : AsmOperandClass {
940 let Name = "MRSSystemRegister";
941 let ParserMethod = "tryParseSysReg";
942 let DiagnosticType = "MRS";
944 // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
945 def mrs_sysreg_op : Operand<i32> {
946 let ParserMatchClass = MRSSystemRegisterOperand;
947 let DecoderMethod = "DecodeMRSSystemRegister";
948 let PrintMethod = "printMRSSystemRegister";
951 def MSRSystemRegisterOperand : AsmOperandClass {
952 let Name = "MSRSystemRegister";
953 let ParserMethod = "tryParseSysReg";
954 let DiagnosticType = "MSR";
956 def msr_sysreg_op : Operand<i32> {
957 let ParserMatchClass = MSRSystemRegisterOperand;
958 let DecoderMethod = "DecodeMSRSystemRegister";
959 let PrintMethod = "printMSRSystemRegister";
962 def PSBHintOperand : AsmOperandClass {
963 let Name = "PSBHint";
964 let ParserMethod = "tryParsePSBHint";
966 def psbhint_op : Operand<i32> {
967 let ParserMatchClass = PSBHintOperand;
968 let PrintMethod = "printPSBHintOp";
969 let MCOperandPredicate = [{
970 // Check, if operand is valid, to fix exhaustive aliasing in disassembly.
971 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.
974 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
978 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
979 "mrs", "\t$Rt, $systemreg"> {
981 let Inst{20-5} = systemreg;
984 // FIXME: Some of these def NZCV, others don't. Best way to model that?
985 // Explicitly modeling each of the system register as a register class
986 // would do it, but feels like overkill at this point.
987 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
988 "msr", "\t$systemreg, $Rt"> {
990 let Inst{20-5} = systemreg;
993 def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
994 let Name = "SystemPStateFieldWithImm0_15";
995 let ParserMethod = "tryParseSysReg";
997 def pstatefield4_op : Operand<i32> {
998 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
999 let PrintMethod = "printSystemPStateField";
1002 let Defs = [NZCV] in
1003 class MSRpstateImm0_15
1004 : SimpleSystemI<0, (ins pstatefield4_op:$pstatefield, imm0_15:$imm),
1005 "msr", "\t$pstatefield, $imm">,
1007 bits<6> pstatefield;
1009 let Inst{20-19} = 0b00;
1010 let Inst{18-16} = pstatefield{5-3};
1011 let Inst{15-12} = 0b0100;
1012 let Inst{11-8} = imm;
1013 let Inst{7-5} = pstatefield{2-0};
1015 let DecoderMethod = "DecodeSystemPStateInstruction";
1016 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1017 // Fail the decoder should attempt to decode the instruction as MSRI.
1018 let hasCompleteDecoder = 0;
1021 def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
1022 let Name = "SystemPStateFieldWithImm0_1";
1023 let ParserMethod = "tryParseSysReg";
1025 def pstatefield1_op : Operand<i32> {
1026 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
1027 let PrintMethod = "printSystemPStateField";
1030 let Defs = [NZCV] in
1031 class MSRpstateImm0_1
1032 : SimpleSystemI<0, (ins pstatefield1_op:$pstatefield, imm0_1:$imm),
1033 "msr", "\t$pstatefield, $imm">,
1035 bits<6> pstatefield;
1037 let Inst{20-19} = 0b00;
1038 let Inst{18-16} = pstatefield{5-3};
1039 let Inst{15-9} = 0b0100000;
1041 let Inst{7-5} = pstatefield{2-0};
1043 let DecoderMethod = "DecodeSystemPStateInstruction";
1044 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1045 // Fail the decoder should attempt to decode the instruction as MSRI.
1046 let hasCompleteDecoder = 0;
1049 // SYS and SYSL generic system instructions.
1050 def SysCRAsmOperand : AsmOperandClass {
1052 let ParserMethod = "tryParseSysCROperand";
1055 def sys_cr_op : Operand<i32> {
1056 let PrintMethod = "printSysCROperand";
1057 let ParserMatchClass = SysCRAsmOperand;
1060 class SystemXtI<bit L, string asm>
1061 : RtSystemI<L, (outs),
1062 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
1063 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
1068 let Inst{20-19} = 0b01;
1069 let Inst{18-16} = op1;
1070 let Inst{15-12} = Cn;
1071 let Inst{11-8} = Cm;
1072 let Inst{7-5} = op2;
1075 class SystemLXtI<bit L, string asm>
1076 : RtSystemI<L, (outs),
1077 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
1078 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
1083 let Inst{20-19} = 0b01;
1084 let Inst{18-16} = op1;
1085 let Inst{15-12} = Cn;
1086 let Inst{11-8} = Cm;
1087 let Inst{7-5} = op2;
1091 // Branch (register) instructions:
1099 // otherwise UNDEFINED
1100 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
1101 string operands, list<dag> pattern>
1102 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
1103 let Inst{31-25} = 0b1101011;
1104 let Inst{24-21} = opc;
1105 let Inst{20-16} = 0b11111;
1106 let Inst{15-10} = 0b000000;
1107 let Inst{4-0} = 0b00000;
1110 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
1111 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
1116 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
1117 class SpecialReturn<bits<4> opc, string asm>
1118 : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1119 let Inst{9-5} = 0b11111;
1123 class RCPCLoad<bits<2> sz, string asm, RegisterClass RC>
1124 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>,
1128 let Inst{31-30} = sz;
1129 let Inst{29-10} = 0b11100010111111110000;
1134 class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands,
1136 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> {
1137 let Inst{31-25} = 0b1101011;
1138 let Inst{20-11} = 0b1111100001;
1140 let Inst{4-0} = 0b11111;
1143 class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm>
1144 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> {
1147 let Inst{24-22} = 0b100;
1153 class AuthOneOperand<bits<3> opc, bits<1> M, string asm>
1154 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> {
1157 let Inst{23-21} = opc;
1161 class AuthReturn<bits<3> op, bits<1> M, string asm>
1162 : AuthBase<M, (outs), (ins), asm, "", []> {
1164 let Inst{23-21} = op;
1165 let Inst{9-0} = 0b1111111111;
1169 class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm,
1170 string operands, string cstr, Operand opr>
1171 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> {
1175 let Inst{31-24} = 0b11111000;
1177 let Inst{22} = offset{9};
1179 let Inst{20-12} = offset{8-0};
1186 multiclass AuthLoad<bit M, string asm, Operand opr> {
1187 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt),
1188 (ins GPR64sp:$Rn, opr:$offset),
1189 asm, "\t$Rt, [$Rn, $offset]", "", opr>;
1190 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt),
1191 (ins GPR64sp:$Rn, opr:$offset),
1192 asm, "\t$Rt, [$Rn, $offset]!",
1193 "$Rn = $wback,@earlyclobber $wback", opr>;
1195 def : InstAlias<asm # "\t$Rt, [$Rn]",
1196 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>;
1200 // Conditional branch instruction.
1204 // 4-bit immediate. Pretty-printed as <cc>
1205 def ccode : Operand<i32> {
1206 let PrintMethod = "printCondCode";
1207 let ParserMatchClass = CondCode;
1209 def inv_ccode : Operand<i32> {
1210 // AL and NV are invalid in the aliases which use inv_ccode
1211 let PrintMethod = "printInverseCondCode";
1212 let ParserMatchClass = CondCode;
1213 let MCOperandPredicate = [{
1214 return MCOp.isImm() &&
1215 MCOp.getImm() != AArch64CC::AL &&
1216 MCOp.getImm() != AArch64CC::NV;
1220 // Conditional branch target. 19-bit immediate. The low two bits of the target
1221 // offset are implied zero and so are not part of the immediate.
1222 def am_brcond : Operand<OtherVT> {
1223 let EncoderMethod = "getCondBranchTargetOpValue";
1224 let DecoderMethod = "DecodePCRelLabel19";
1225 let PrintMethod = "printAlignedLabel";
1226 let ParserMatchClass = PCRelLabel19Operand;
1229 class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1230 "b", ".$cond\t$target", "",
1231 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1234 let isTerminator = 1;
1239 let Inst{31-24} = 0b01010100;
1240 let Inst{23-5} = target;
1242 let Inst{3-0} = cond;
1246 // Compare-and-branch instructions.
1248 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1249 : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1250 asm, "\t$Rt, $target", "",
1251 [(node regtype:$Rt, bb:$target)]>,
1254 let isTerminator = 1;
1258 let Inst{30-25} = 0b011010;
1260 let Inst{23-5} = target;
1264 multiclass CmpBranch<bit op, string asm, SDNode node> {
1265 def W : BaseCmpBranch<GPR32, op, asm, node> {
1268 def X : BaseCmpBranch<GPR64, op, asm, node> {
1274 // Test-bit-and-branch instructions.
1276 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1277 // the target offset are implied zero and so are not part of the immediate.
1278 def am_tbrcond : Operand<OtherVT> {
1279 let EncoderMethod = "getTestBranchTargetOpValue";
1280 let PrintMethod = "printAlignedLabel";
1281 let ParserMatchClass = BranchTarget14Operand;
1284 // AsmOperand classes to emit (or not) special diagnostics
1285 def TBZImm0_31Operand : AsmOperandClass {
1286 let Name = "TBZImm0_31";
1287 let PredicateMethod = "isImmInRange<0,31>";
1288 let RenderMethod = "addImm0_31Operands";
1290 def TBZImm32_63Operand : AsmOperandClass {
1291 let Name = "Imm32_63";
1292 let PredicateMethod = "isImmInRange<32,63>";
1293 let DiagnosticType = "InvalidImm0_63";
1296 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1297 return (((uint32_t)Imm) < 32);
1299 let ParserMatchClass = matcher;
1302 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1303 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1305 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1306 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1308 let ParserMatchClass = TBZImm32_63Operand;
1311 class BaseTestBranch<RegisterClass regtype, Operand immtype,
1312 bit op, string asm, SDNode node>
1313 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1314 asm, "\t$Rt, $bit_off, $target", "",
1315 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1318 let isTerminator = 1;
1324 let Inst{30-25} = 0b011011;
1326 let Inst{23-19} = bit_off{4-0};
1327 let Inst{18-5} = target;
1330 let DecoderMethod = "DecodeTestAndBranch";
1333 multiclass TestBranch<bit op, string asm, SDNode node> {
1334 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1338 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1342 // Alias X-reg with 0-31 imm to W-Reg.
1343 def : InstAlias<asm # "\t$Rd, $imm, $target",
1344 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1345 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1346 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1347 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1348 tbz_imm0_31_diag:$imm, bb:$target)>;
1352 // Unconditional branch (immediate) instructions.
1354 def am_b_target : Operand<OtherVT> {
1355 let EncoderMethod = "getBranchTargetOpValue";
1356 let PrintMethod = "printAlignedLabel";
1357 let ParserMatchClass = BranchTarget26Operand;
1359 def am_bl_target : Operand<i64> {
1360 let EncoderMethod = "getBranchTargetOpValue";
1361 let PrintMethod = "printAlignedLabel";
1362 let ParserMatchClass = BranchTarget26Operand;
1365 class BImm<bit op, dag iops, string asm, list<dag> pattern>
1366 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1369 let Inst{30-26} = 0b00101;
1370 let Inst{25-0} = addr;
1372 let DecoderMethod = "DecodeUnconditionalBranch";
1375 class BranchImm<bit op, string asm, list<dag> pattern>
1376 : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1377 class CallImm<bit op, string asm, list<dag> pattern>
1378 : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1381 // Basic one-operand data processing instructions.
1384 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1385 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1386 SDPatternOperator node>
1387 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1388 [(set regtype:$Rd, (node regtype:$Rn))]>,
1389 Sched<[WriteI, ReadI]> {
1393 let Inst{30-13} = 0b101101011000000000;
1394 let Inst{12-10} = opc;
1399 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1400 multiclass OneOperandData<bits<3> opc, string asm,
1401 SDPatternOperator node = null_frag> {
1402 def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1406 def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1411 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1412 : BaseOneOperandData<opc, GPR32, asm, node> {
1416 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1417 : BaseOneOperandData<opc, GPR64, asm, node> {
1421 class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm>
1422 : I<(outs GPR64:$Rd), (ins GPR64sp:$Rn), asm, "\t$Rd, $Rn", "",
1424 Sched<[WriteI, ReadI]> {
1427 let Inst{31-15} = 0b11011010110000010;
1428 let Inst{14-12} = opcode_prefix;
1429 let Inst{11-10} = opcode;
1434 class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm>
1435 : I<(outs GPR64:$Rd), (ins), asm, "\t$Rd", "", []>, Sched<[]> {
1437 let Inst{31-15} = 0b11011010110000010;
1438 let Inst{14-12} = opcode_prefix;
1439 let Inst{11-10} = opcode;
1440 let Inst{9-5} = 0b11111;
1444 class SignAuthTwoOperand<bits<4> opc, string asm,
1445 SDPatternOperator OpNode>
1446 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm),
1447 asm, "\t$Rd, $Rn, $Rm", "",
1448 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>,
1449 Sched<[WriteI, ReadI, ReadI]> {
1453 let Inst{31-21} = 0b10011010110;
1454 let Inst{20-16} = Rm;
1455 let Inst{15-14} = 0b00;
1456 let Inst{13-10} = opc;
1462 // Basic two-operand data processing instructions.
1464 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1466 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1467 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1468 Sched<[WriteI, ReadI, ReadI]> {
1473 let Inst{30} = isSub;
1474 let Inst{28-21} = 0b11010000;
1475 let Inst{20-16} = Rm;
1476 let Inst{15-10} = 0;
1481 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1483 : BaseBaseAddSubCarry<isSub, regtype, asm,
1484 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1486 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1488 : BaseBaseAddSubCarry<isSub, regtype, asm,
1489 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1494 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1495 SDNode OpNode, SDNode OpNode_setflags> {
1496 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1500 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1506 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1511 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1518 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1519 SDPatternOperator OpNode>
1520 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1521 asm, "\t$Rd, $Rn, $Rm", "",
1522 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
1526 let Inst{30-21} = 0b0011010110;
1527 let Inst{20-16} = Rm;
1528 let Inst{15-14} = 0b00;
1529 let Inst{13-10} = opc;
1534 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1535 SDPatternOperator OpNode>
1536 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1537 let Inst{10} = isSigned;
1540 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1541 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1542 Sched<[WriteID32, ReadID, ReadID]> {
1545 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1546 Sched<[WriteID64, ReadID, ReadID]> {
1551 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1552 SDPatternOperator OpNode = null_frag>
1553 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1554 Sched<[WriteIS, ReadI]> {
1555 let Inst{11-10} = shift_type;
1558 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
1559 def Wr : BaseShift<shift_type, GPR32, asm> {
1563 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1567 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1568 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1569 (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1571 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1572 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1574 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1575 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1577 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1578 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1581 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
1582 : InstAlias<asm#"\t$dst, $src1, $src2",
1583 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
1585 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1586 RegisterClass addtype, string asm,
1588 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1589 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1594 let Inst{30-24} = 0b0011011;
1595 let Inst{23-21} = opc;
1596 let Inst{20-16} = Rm;
1597 let Inst{15} = isSub;
1598 let Inst{14-10} = Ra;
1603 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
1604 // MADD/MSUB generation is decided by MachineCombiner.cpp
1605 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
1606 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
1607 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1611 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
1612 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
1613 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
1618 class WideMulAccum<bit isSub, bits<3> opc, string asm,
1619 SDNode AccNode, SDNode ExtNode>
1620 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
1621 [(set GPR64:$Rd, (AccNode GPR64:$Ra,
1622 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
1623 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1627 class MulHi<bits<3> opc, string asm, SDNode OpNode>
1628 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
1629 asm, "\t$Rd, $Rn, $Rm", "",
1630 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
1631 Sched<[WriteIM64, ReadIM, ReadIM]> {
1635 let Inst{31-24} = 0b10011011;
1636 let Inst{23-21} = opc;
1637 let Inst{20-16} = Rm;
1642 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
1643 // (i.e. all bits 1) but is ignored by the processor.
1644 let PostEncoderMethod = "fixMulHigh";
1647 class MulAccumWAlias<string asm, Instruction inst>
1648 : InstAlias<asm#"\t$dst, $src1, $src2",
1649 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
1650 class MulAccumXAlias<string asm, Instruction inst>
1651 : InstAlias<asm#"\t$dst, $src1, $src2",
1652 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
1653 class WideMulAccumAlias<string asm, Instruction inst>
1654 : InstAlias<asm#"\t$dst, $src1, $src2",
1655 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
1657 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
1658 SDPatternOperator OpNode, string asm>
1659 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
1660 asm, "\t$Rd, $Rn, $Rm", "",
1661 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
1662 Sched<[WriteISReg, ReadI, ReadISReg]> {
1668 let Inst{30-21} = 0b0011010110;
1669 let Inst{20-16} = Rm;
1670 let Inst{15-13} = 0b010;
1672 let Inst{11-10} = sz;
1675 let Predicates = [HasCRC];
1679 // Address generation.
1682 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
1683 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
1688 let Inst{31} = page;
1689 let Inst{30-29} = label{1-0};
1690 let Inst{28-24} = 0b10000;
1691 let Inst{23-5} = label{20-2};
1694 let DecoderMethod = "DecodeAdrInstruction";
1701 def movimm32_imm : Operand<i32> {
1702 let ParserMatchClass = Imm0_65535Operand;
1703 let EncoderMethod = "getMoveWideImmOpValue";
1704 let PrintMethod = "printImm";
1706 def movimm32_shift : Operand<i32> {
1707 let PrintMethod = "printShifter";
1708 let ParserMatchClass = MovImm32ShifterOperand;
1710 def movimm64_shift : Operand<i32> {
1711 let PrintMethod = "printShifter";
1712 let ParserMatchClass = MovImm64ShifterOperand;
1715 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1716 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1718 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
1719 asm, "\t$Rd, $imm$shift", "", []>,
1724 let Inst{30-29} = opc;
1725 let Inst{28-23} = 0b100101;
1726 let Inst{22-21} = shift{5-4};
1727 let Inst{20-5} = imm;
1730 let DecoderMethod = "DecodeMoveImmInstruction";
1733 multiclass MoveImmediate<bits<2> opc, string asm> {
1734 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
1738 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
1743 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1744 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1746 : I<(outs regtype:$Rd),
1747 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
1748 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
1749 Sched<[WriteI, ReadI]> {
1753 let Inst{30-29} = opc;
1754 let Inst{28-23} = 0b100101;
1755 let Inst{22-21} = shift{5-4};
1756 let Inst{20-5} = imm;
1759 let DecoderMethod = "DecodeMoveImmInstruction";
1762 multiclass InsertImmediate<bits<2> opc, string asm> {
1763 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
1767 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
1776 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
1777 RegisterClass srcRegtype, addsub_shifted_imm immtype,
1778 string asm, SDPatternOperator OpNode>
1779 : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
1780 asm, "\t$Rd, $Rn, $imm", "",
1781 [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
1782 Sched<[WriteI, ReadI]> {
1786 let Inst{30} = isSub;
1787 let Inst{29} = setFlags;
1788 let Inst{28-24} = 0b10001;
1789 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
1790 let Inst{21-10} = imm{11-0};
1793 let DecoderMethod = "DecodeBaseAddSubImm";
1796 class BaseAddSubRegPseudo<RegisterClass regtype,
1797 SDPatternOperator OpNode>
1798 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1799 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1800 Sched<[WriteI, ReadI, ReadI]>;
1802 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
1803 arith_shifted_reg shifted_regtype, string asm,
1804 SDPatternOperator OpNode>
1805 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1806 asm, "\t$Rd, $Rn, $Rm", "",
1807 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
1808 Sched<[WriteISReg, ReadI, ReadISReg]> {
1809 // The operands are in order to match the 'addr' MI operands, so we
1810 // don't need an encoder method and by-name matching. Just use the default
1811 // in-order handling. Since we're using by-order, make sure the names
1817 let Inst{30} = isSub;
1818 let Inst{29} = setFlags;
1819 let Inst{28-24} = 0b01011;
1820 let Inst{23-22} = shift{7-6};
1822 let Inst{20-16} = src2;
1823 let Inst{15-10} = shift{5-0};
1824 let Inst{9-5} = src1;
1825 let Inst{4-0} = dst;
1827 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1830 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
1831 RegisterClass src1Regtype, Operand src2Regtype,
1832 string asm, SDPatternOperator OpNode>
1833 : I<(outs dstRegtype:$R1),
1834 (ins src1Regtype:$R2, src2Regtype:$R3),
1835 asm, "\t$R1, $R2, $R3", "",
1836 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
1837 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1842 let Inst{30} = isSub;
1843 let Inst{29} = setFlags;
1844 let Inst{28-24} = 0b01011;
1845 let Inst{23-21} = 0b001;
1846 let Inst{20-16} = Rm;
1847 let Inst{15-13} = ext{5-3};
1848 let Inst{12-10} = ext{2-0};
1852 let DecoderMethod = "DecodeAddSubERegInstruction";
1855 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1856 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
1857 RegisterClass src1Regtype, RegisterClass src2Regtype,
1858 Operand ext_op, string asm>
1859 : I<(outs dstRegtype:$Rd),
1860 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
1861 asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
1862 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1867 let Inst{30} = isSub;
1868 let Inst{29} = setFlags;
1869 let Inst{28-24} = 0b01011;
1870 let Inst{23-21} = 0b001;
1871 let Inst{20-16} = Rm;
1872 let Inst{15} = ext{5};
1873 let Inst{12-10} = ext{2-0};
1877 let DecoderMethod = "DecodeAddSubERegInstruction";
1880 // Aliases for register+register add/subtract.
1881 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
1882 RegisterClass src1Regtype, RegisterClass src2Regtype,
1884 : InstAlias<asm#"\t$dst, $src1, $src2",
1885 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
1888 multiclass AddSub<bit isSub, string mnemonic, string alias,
1889 SDPatternOperator OpNode = null_frag> {
1890 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1891 // Add/Subtract immediate
1892 // Increase the weight of the immediate variant to try to match it before
1893 // the extended register variant.
1894 // We used to match the register variant before the immediate when the
1895 // register argument could be implicitly zero-extended.
1896 let AddedComplexity = 6 in
1897 def Wri : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
1901 let AddedComplexity = 6 in
1902 def Xri : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
1907 // Add/Subtract register - Only used for CodeGen
1908 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1909 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1911 // Add/Subtract shifted register
1912 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
1916 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
1922 // Add/Subtract extended register
1923 let AddedComplexity = 1, hasSideEffects = 0 in {
1924 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
1925 arith_extended_reg32<i32>, mnemonic, OpNode> {
1928 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
1929 arith_extended_reg32to64<i64>, mnemonic, OpNode> {
1934 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
1935 arith_extendlsl64, mnemonic> {
1936 // UXTX and SXTX only.
1937 let Inst{14-13} = 0b11;
1941 // add Rd, Rb, -imm -> sub Rd, Rn, imm
1942 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
1943 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
1944 addsub_shifted_imm32_neg:$imm), 0>;
1945 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
1946 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
1947 addsub_shifted_imm64_neg:$imm), 0>;
1949 // Register/register aliases with no shift when SP is not used.
1950 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1951 GPR32, GPR32, GPR32, 0>;
1952 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1953 GPR64, GPR64, GPR64, 0>;
1955 // Register/register aliases with no shift when either the destination or
1956 // first source register is SP.
1957 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1958 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
1959 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1960 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
1961 def : AddSubRegAlias<mnemonic,
1962 !cast<Instruction>(NAME#"Xrx64"),
1963 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
1964 def : AddSubRegAlias<mnemonic,
1965 !cast<Instruction>(NAME#"Xrx64"),
1966 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
1969 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
1970 string alias, string cmpAlias> {
1971 let isCompare = 1, Defs = [NZCV] in {
1972 // Add/Subtract immediate
1973 def Wri : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
1977 def Xri : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
1982 // Add/Subtract register
1983 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1984 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1986 // Add/Subtract shifted register
1987 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
1991 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
1996 // Add/Subtract extended register
1997 let AddedComplexity = 1 in {
1998 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
1999 arith_extended_reg32<i32>, mnemonic, OpNode> {
2002 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
2003 arith_extended_reg32<i64>, mnemonic, OpNode> {
2008 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
2009 arith_extendlsl64, mnemonic> {
2010 // UXTX and SXTX only.
2011 let Inst{14-13} = 0b11;
2016 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
2017 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2018 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
2019 addsub_shifted_imm32_neg:$imm), 0>;
2020 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
2021 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
2022 addsub_shifted_imm64_neg:$imm), 0>;
2025 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
2026 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
2027 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
2028 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
2029 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
2030 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
2031 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
2032 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
2033 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
2034 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
2035 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
2036 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
2037 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
2038 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
2040 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
2041 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
2042 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
2043 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
2044 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
2046 // Compare shorthands
2047 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
2048 WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
2049 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
2050 XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
2051 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
2052 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
2053 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
2054 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
2056 // Register/register aliases with no shift when SP is not used.
2057 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
2058 GPR32, GPR32, GPR32, 0>;
2059 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
2060 GPR64, GPR64, GPR64, 0>;
2062 // Register/register aliases with no shift when the first source register
2064 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
2065 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
2066 def : AddSubRegAlias<mnemonic,
2067 !cast<Instruction>(NAME#"Xrx64"),
2068 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
2074 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
2076 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
2078 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
2080 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
2081 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
2082 Sched<[WriteExtr, ReadExtrHi]> {
2088 let Inst{30-23} = 0b00100111;
2090 let Inst{20-16} = Rm;
2091 let Inst{15-10} = imm;
2096 multiclass ExtractImm<string asm> {
2097 def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
2099 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
2102 // imm<5> must be zero.
2105 def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
2107 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
2118 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2119 class BaseBitfieldImm<bits<2> opc,
2120 RegisterClass regtype, Operand imm_type, string asm>
2121 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
2122 asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
2123 Sched<[WriteIS, ReadI]> {
2129 let Inst{30-29} = opc;
2130 let Inst{28-23} = 0b100110;
2131 let Inst{21-16} = immr;
2132 let Inst{15-10} = imms;
2137 multiclass BitfieldImm<bits<2> opc, string asm> {
2138 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
2141 // imms<5> and immr<5> must be zero, else ReservedValue().
2145 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
2151 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2152 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
2153 RegisterClass regtype, Operand imm_type, string asm>
2154 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
2156 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
2157 Sched<[WriteIS, ReadI]> {
2163 let Inst{30-29} = opc;
2164 let Inst{28-23} = 0b100110;
2165 let Inst{21-16} = immr;
2166 let Inst{15-10} = imms;
2171 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
2172 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
2175 // imms<5> and immr<5> must be zero, else ReservedValue().
2179 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
2189 // Logical (immediate)
2190 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
2191 RegisterClass sregtype, Operand imm_type, string asm,
2193 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
2194 asm, "\t$Rd, $Rn, $imm", "", pattern>,
2195 Sched<[WriteI, ReadI]> {
2199 let Inst{30-29} = opc;
2200 let Inst{28-23} = 0b100100;
2201 let Inst{22} = imm{12};
2202 let Inst{21-16} = imm{11-6};
2203 let Inst{15-10} = imm{5-0};
2207 let DecoderMethod = "DecodeLogicalImmInstruction";
2210 // Logical (shifted register)
2211 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
2212 logical_shifted_reg shifted_regtype, string asm,
2214 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2215 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2216 Sched<[WriteISReg, ReadI, ReadISReg]> {
2217 // The operands are in order to match the 'addr' MI operands, so we
2218 // don't need an encoder method and by-name matching. Just use the default
2219 // in-order handling. Since we're using by-order, make sure the names
2225 let Inst{30-29} = opc;
2226 let Inst{28-24} = 0b01010;
2227 let Inst{23-22} = shift{7-6};
2229 let Inst{20-16} = src2;
2230 let Inst{15-10} = shift{5-0};
2231 let Inst{9-5} = src1;
2232 let Inst{4-0} = dst;
2234 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2237 // Aliases for register+register logical instructions.
2238 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
2239 : InstAlias<asm#"\t$dst, $src1, $src2",
2240 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2242 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2244 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2245 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2246 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2247 logical_imm32:$imm))]> {
2249 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2251 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2252 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2253 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2254 logical_imm64:$imm))]> {
2258 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2259 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2260 logical_imm32_not:$imm), 0>;
2261 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2262 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2263 logical_imm64_not:$imm), 0>;
2266 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2268 let isCompare = 1, Defs = [NZCV] in {
2269 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2270 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2272 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2274 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2275 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2278 } // end Defs = [NZCV]
2280 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2281 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2282 logical_imm32_not:$imm), 0>;
2283 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2284 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2285 logical_imm64_not:$imm), 0>;
2288 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2289 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2290 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2291 Sched<[WriteI, ReadI, ReadI]>;
2293 // Split from LogicalImm as not all instructions have both.
2294 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2295 SDPatternOperator OpNode> {
2296 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2297 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2298 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2301 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2302 [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2303 logical_shifted_reg32:$Rm))]> {
2306 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2307 [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2308 logical_shifted_reg64:$Rm))]> {
2312 def : LogicalRegAlias<mnemonic,
2313 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2314 def : LogicalRegAlias<mnemonic,
2315 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2318 // Split from LogicalReg to allow setting NZCV Defs
2319 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2320 SDPatternOperator OpNode = null_frag> {
2321 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2322 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2323 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2325 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2326 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2329 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2330 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2335 def : LogicalRegAlias<mnemonic,
2336 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2337 def : LogicalRegAlias<mnemonic,
2338 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2342 // Conditionally set flags
2345 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2346 class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2347 string mnemonic, SDNode OpNode>
2348 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2349 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2350 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2351 (i32 imm:$cond), NZCV))]>,
2352 Sched<[WriteI, ReadI]> {
2362 let Inst{29-21} = 0b111010010;
2363 let Inst{20-16} = imm;
2364 let Inst{15-12} = cond;
2365 let Inst{11-10} = 0b10;
2368 let Inst{3-0} = nzcv;
2371 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2372 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2374 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2375 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2376 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2377 (i32 imm:$cond), NZCV))]>,
2378 Sched<[WriteI, ReadI, ReadI]> {
2388 let Inst{29-21} = 0b111010010;
2389 let Inst{20-16} = Rm;
2390 let Inst{15-12} = cond;
2391 let Inst{11-10} = 0b00;
2394 let Inst{3-0} = nzcv;
2397 multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
2398 // immediate operand variants
2399 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
2402 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
2405 // register operand variants
2406 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
2409 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
2415 // Conditional select
2418 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2419 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2420 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2422 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2423 Sched<[WriteI, ReadI, ReadI]> {
2432 let Inst{29-21} = 0b011010100;
2433 let Inst{20-16} = Rm;
2434 let Inst{15-12} = cond;
2435 let Inst{11-10} = op2;
2440 multiclass CondSelect<bit op, bits<2> op2, string asm> {
2441 def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2444 def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2449 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2451 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2452 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2454 (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2455 (i32 imm:$cond), NZCV))]>,
2456 Sched<[WriteI, ReadI, ReadI]> {
2465 let Inst{29-21} = 0b011010100;
2466 let Inst{20-16} = Rm;
2467 let Inst{15-12} = cond;
2468 let Inst{11-10} = op2;
2473 def inv_cond_XFORM : SDNodeXForm<imm, [{
2474 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
2475 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
2479 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
2480 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
2483 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
2487 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
2488 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
2489 (inv_cond_XFORM imm:$cond))>;
2491 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
2492 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
2493 (inv_cond_XFORM imm:$cond))>;
2497 // Special Mask Value
2499 def maski8_or_more : Operand<i32>,
2500 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
2502 def maski16_or_more : Operand<i32>,
2503 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
2511 // (unsigned immediate)
2512 // Indexed for 8-bit registers. offset is in range [0,4095].
2513 def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
2514 def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
2515 def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
2516 def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
2517 def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
2519 def gi_am_indexed8 :
2520 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">,
2521 GIComplexPatternEquiv<am_indexed8>;
2522 def gi_am_indexed16 :
2523 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">,
2524 GIComplexPatternEquiv<am_indexed16>;
2525 def gi_am_indexed32 :
2526 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">,
2527 GIComplexPatternEquiv<am_indexed32>;
2528 def gi_am_indexed64 :
2529 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">,
2530 GIComplexPatternEquiv<am_indexed64>;
2531 def gi_am_indexed128 :
2532 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">,
2533 GIComplexPatternEquiv<am_indexed128>;
2535 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
2536 let Name = "UImm12Offset" # Scale;
2537 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
2538 let PredicateMethod = "isUImm12Offset<" # Scale # ">";
2539 let DiagnosticType = "InvalidMemoryIndexed" # Scale;
2542 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
2543 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
2544 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
2545 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
2546 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
2548 class uimm12_scaled<int Scale> : Operand<i64> {
2549 let ParserMatchClass
2550 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
2552 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
2553 let PrintMethod = "printUImm12Offset<" # Scale # ">";
2556 def uimm12s1 : uimm12_scaled<1>;
2557 def uimm12s2 : uimm12_scaled<2>;
2558 def uimm12s4 : uimm12_scaled<4>;
2559 def uimm12s8 : uimm12_scaled<8>;
2560 def uimm12s16 : uimm12_scaled<16>;
2562 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2563 string asm, list<dag> pattern>
2564 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2570 let Inst{31-30} = sz;
2571 let Inst{29-27} = 0b111;
2573 let Inst{25-24} = 0b01;
2574 let Inst{23-22} = opc;
2575 let Inst{21-10} = offset;
2579 let DecoderMethod = "DecodeUnsignedLdStInstruction";
2582 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2583 Operand indextype, string asm, list<dag> pattern> {
2584 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2585 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
2586 (ins GPR64sp:$Rn, indextype:$offset),
2590 def : InstAlias<asm # "\t$Rt, [$Rn]",
2591 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2594 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2595 Operand indextype, string asm, list<dag> pattern> {
2596 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2597 def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2598 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2602 def : InstAlias<asm # "\t$Rt, [$Rn]",
2603 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2606 // Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to
2607 // substitute zero-registers automatically.
2609 // TODO: Roll out zero-register subtitution to GPR32/GPR64 and fold this back
2611 multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,
2612 Operand indextype, string asm, list<dag> pattern> {
2613 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2614 def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2615 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2619 def : InstAlias<asm # "\t$Rt, [$Rn]",
2620 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2623 def PrefetchOperand : AsmOperandClass {
2624 let Name = "Prefetch";
2625 let ParserMethod = "tryParsePrefetch";
2627 def prfop : Operand<i32> {
2628 let PrintMethod = "printPrefetchOp";
2629 let ParserMatchClass = PrefetchOperand;
2632 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2633 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2634 : BaseLoadStoreUI<sz, V, opc,
2635 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
2643 // Load literal address: 19-bit immediate. The low two bits of the target
2644 // offset are implied zero and so are not part of the immediate.
2645 def am_ldrlit : Operand<iPTR> {
2646 let EncoderMethod = "getLoadLiteralOpValue";
2647 let DecoderMethod = "DecodePCRelLabel19";
2648 let PrintMethod = "printAlignedLabel";
2649 let ParserMatchClass = PCRelLabel19Operand;
2652 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2653 class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
2654 : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
2655 asm, "\t$Rt, $label", "", []>,
2659 let Inst{31-30} = opc;
2660 let Inst{29-27} = 0b011;
2662 let Inst{25-24} = 0b00;
2663 let Inst{23-5} = label;
2667 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2668 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
2669 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
2670 asm, "\t$Rt, $label", "", pat>,
2674 let Inst{31-30} = opc;
2675 let Inst{29-27} = 0b011;
2677 let Inst{25-24} = 0b00;
2678 let Inst{23-5} = label;
2683 // Load/store register offset
2686 def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
2687 def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
2688 def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
2689 def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
2690 def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
2692 def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
2693 def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
2694 def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
2695 def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
2696 def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
2698 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
2699 let Name = "Mem" # Reg # "Extend" # Width;
2700 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
2701 let RenderMethod = "addMemExtendOperands";
2702 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
2705 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
2706 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2707 // the trivial shift.
2708 let RenderMethod = "addMemExtend8Operands";
2710 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
2711 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
2712 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
2713 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
2715 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
2716 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2717 // the trivial shift.
2718 let RenderMethod = "addMemExtend8Operands";
2720 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
2721 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
2722 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
2723 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
2725 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
2727 let ParserMatchClass = ParserClass;
2728 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
2729 let DecoderMethod = "DecodeMemExtend";
2730 let EncoderMethod = "getMemExtendOpValue";
2731 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
2734 def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>;
2735 def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>;
2736 def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>;
2737 def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>;
2738 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
2740 def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>;
2741 def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>;
2742 def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>;
2743 def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>;
2744 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
2746 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
2747 Operand wextend, Operand xextend> {
2748 // CodeGen-level pattern covering the entire addressing mode.
2749 ComplexPattern Wpat = windex;
2750 ComplexPattern Xpat = xindex;
2752 // Asm-level Operand covering the valid "uxtw #3" style syntax.
2753 Operand Wext = wextend;
2754 Operand Xext = xextend;
2757 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
2758 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
2759 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
2760 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
2761 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
2764 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2765 string asm, dag ins, dag outs, list<dag> pat>
2766 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2771 let Inst{31-30} = sz;
2772 let Inst{29-27} = 0b111;
2774 let Inst{25-24} = 0b00;
2775 let Inst{23-22} = opc;
2777 let Inst{20-16} = Rm;
2778 let Inst{15} = extend{1}; // sign extend Rm?
2780 let Inst{12} = extend{0}; // do shift?
2781 let Inst{11-10} = 0b10;
2786 class ROInstAlias<string asm, RegisterClass regtype, Instruction INST>
2787 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
2788 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2790 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2791 string asm, ValueType Ty, SDPatternOperator loadop> {
2792 let AddedComplexity = 10 in
2793 def roW : LoadStore8RO<sz, V, opc, regtype, asm,
2795 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2796 [(set (Ty regtype:$Rt),
2797 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2798 ro_Wextend8:$extend)))]>,
2799 Sched<[WriteLDIdx, ReadAdrBase]> {
2803 let AddedComplexity = 10 in
2804 def roX : LoadStore8RO<sz, V, opc, regtype, asm,
2806 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2807 [(set (Ty regtype:$Rt),
2808 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2809 ro_Xextend8:$extend)))]>,
2810 Sched<[WriteLDIdx, ReadAdrBase]> {
2814 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2817 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2818 string asm, ValueType Ty, SDPatternOperator storeop> {
2819 let AddedComplexity = 10 in
2820 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2821 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2822 [(storeop (Ty regtype:$Rt),
2823 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2824 ro_Wextend8:$extend))]>,
2825 Sched<[WriteSTIdx, ReadAdrBase]> {
2829 let AddedComplexity = 10 in
2830 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2831 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2832 [(storeop (Ty regtype:$Rt),
2833 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2834 ro_Xextend8:$extend))]>,
2835 Sched<[WriteSTIdx, ReadAdrBase]> {
2839 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2842 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2843 string asm, dag ins, dag outs, list<dag> pat>
2844 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2849 let Inst{31-30} = sz;
2850 let Inst{29-27} = 0b111;
2852 let Inst{25-24} = 0b00;
2853 let Inst{23-22} = opc;
2855 let Inst{20-16} = Rm;
2856 let Inst{15} = extend{1}; // sign extend Rm?
2858 let Inst{12} = extend{0}; // do shift?
2859 let Inst{11-10} = 0b10;
2864 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2865 string asm, ValueType Ty, SDPatternOperator loadop> {
2866 let AddedComplexity = 10 in
2867 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2868 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2869 [(set (Ty regtype:$Rt),
2870 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2871 ro_Wextend16:$extend)))]>,
2872 Sched<[WriteLDIdx, ReadAdrBase]> {
2876 let AddedComplexity = 10 in
2877 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2878 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2879 [(set (Ty regtype:$Rt),
2880 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2881 ro_Xextend16:$extend)))]>,
2882 Sched<[WriteLDIdx, ReadAdrBase]> {
2886 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2889 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2890 string asm, ValueType Ty, SDPatternOperator storeop> {
2891 let AddedComplexity = 10 in
2892 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2893 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2894 [(storeop (Ty regtype:$Rt),
2895 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2896 ro_Wextend16:$extend))]>,
2897 Sched<[WriteSTIdx, ReadAdrBase]> {
2901 let AddedComplexity = 10 in
2902 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2903 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2904 [(storeop (Ty regtype:$Rt),
2905 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2906 ro_Xextend16:$extend))]>,
2907 Sched<[WriteSTIdx, ReadAdrBase]> {
2911 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2914 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2915 string asm, dag ins, dag outs, list<dag> pat>
2916 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2921 let Inst{31-30} = sz;
2922 let Inst{29-27} = 0b111;
2924 let Inst{25-24} = 0b00;
2925 let Inst{23-22} = opc;
2927 let Inst{20-16} = Rm;
2928 let Inst{15} = extend{1}; // sign extend Rm?
2930 let Inst{12} = extend{0}; // do shift?
2931 let Inst{11-10} = 0b10;
2936 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2937 string asm, ValueType Ty, SDPatternOperator loadop> {
2938 let AddedComplexity = 10 in
2939 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2940 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2941 [(set (Ty regtype:$Rt),
2942 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2943 ro_Wextend32:$extend)))]>,
2944 Sched<[WriteLDIdx, ReadAdrBase]> {
2948 let AddedComplexity = 10 in
2949 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2950 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2951 [(set (Ty regtype:$Rt),
2952 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2953 ro_Xextend32:$extend)))]>,
2954 Sched<[WriteLDIdx, ReadAdrBase]> {
2958 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2961 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2962 string asm, ValueType Ty, SDPatternOperator storeop> {
2963 let AddedComplexity = 10 in
2964 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2965 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2966 [(storeop (Ty regtype:$Rt),
2967 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2968 ro_Wextend32:$extend))]>,
2969 Sched<[WriteSTIdx, ReadAdrBase]> {
2973 let AddedComplexity = 10 in
2974 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2975 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2976 [(storeop (Ty regtype:$Rt),
2977 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2978 ro_Xextend32:$extend))]>,
2979 Sched<[WriteSTIdx, ReadAdrBase]> {
2983 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2986 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2987 string asm, dag ins, dag outs, list<dag> pat>
2988 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2993 let Inst{31-30} = sz;
2994 let Inst{29-27} = 0b111;
2996 let Inst{25-24} = 0b00;
2997 let Inst{23-22} = opc;
2999 let Inst{20-16} = Rm;
3000 let Inst{15} = extend{1}; // sign extend Rm?
3002 let Inst{12} = extend{0}; // do shift?
3003 let Inst{11-10} = 0b10;
3008 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3009 string asm, ValueType Ty, SDPatternOperator loadop> {
3010 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3011 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3012 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3013 [(set (Ty regtype:$Rt),
3014 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3015 ro_Wextend64:$extend)))]>,
3016 Sched<[WriteLDIdx, ReadAdrBase]> {
3020 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3021 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3022 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3023 [(set (Ty regtype:$Rt),
3024 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3025 ro_Xextend64:$extend)))]>,
3026 Sched<[WriteLDIdx, ReadAdrBase]> {
3030 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3033 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3034 string asm, ValueType Ty, SDPatternOperator storeop> {
3035 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3036 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
3037 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3038 [(storeop (Ty regtype:$Rt),
3039 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3040 ro_Wextend64:$extend))]>,
3041 Sched<[WriteSTIdx, ReadAdrBase]> {
3045 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3046 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
3047 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3048 [(storeop (Ty regtype:$Rt),
3049 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3050 ro_Xextend64:$extend))]>,
3051 Sched<[WriteSTIdx, ReadAdrBase]> {
3055 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3058 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3059 string asm, dag ins, dag outs, list<dag> pat>
3060 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
3065 let Inst{31-30} = sz;
3066 let Inst{29-27} = 0b111;
3068 let Inst{25-24} = 0b00;
3069 let Inst{23-22} = opc;
3071 let Inst{20-16} = Rm;
3072 let Inst{15} = extend{1}; // sign extend Rm?
3074 let Inst{12} = extend{0}; // do shift?
3075 let Inst{11-10} = 0b10;
3080 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3081 string asm, ValueType Ty, SDPatternOperator loadop> {
3082 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3083 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3084 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
3085 [(set (Ty regtype:$Rt),
3086 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
3087 ro_Wextend128:$extend)))]>,
3088 Sched<[WriteLDIdx, ReadAdrBase]> {
3092 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
3093 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
3094 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
3095 [(set (Ty regtype:$Rt),
3096 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
3097 ro_Xextend128:$extend)))]>,
3098 Sched<[WriteLDIdx, ReadAdrBase]> {
3102 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3105 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3106 string asm, ValueType Ty, SDPatternOperator storeop> {
3107 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3108 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
3109 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
3111 Sched<[WriteSTIdx, ReadAdrBase]> {
3115 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
3116 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
3117 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
3119 Sched<[WriteSTIdx, ReadAdrBase]> {
3123 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
3126 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3127 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
3128 string asm, list<dag> pat>
3129 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
3135 let Inst{31-30} = sz;
3136 let Inst{29-27} = 0b111;
3138 let Inst{25-24} = 0b00;
3139 let Inst{23-22} = opc;
3141 let Inst{20-16} = Rm;
3142 let Inst{15} = extend{1}; // sign extend Rm?
3144 let Inst{12} = extend{0}; // do shift?
3145 let Inst{11-10} = 0b10;
3150 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
3151 def roW : BasePrefetchRO<sz, V, opc, (outs),
3152 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
3153 asm, [(AArch64Prefetch imm:$Rt,
3154 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
3155 ro_Wextend64:$extend))]> {
3159 def roX : BasePrefetchRO<sz, V, opc, (outs),
3160 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
3161 asm, [(AArch64Prefetch imm:$Rt,
3162 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
3163 ro_Xextend64:$extend))]> {
3167 def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
3168 (!cast<Instruction>(NAME # "roX") prfop:$Rt,
3169 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
3173 // Load/store unscaled immediate
3176 def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
3177 def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
3178 def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
3179 def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
3180 def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
3182 def gi_am_unscaled8 :
3183 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">,
3184 GIComplexPatternEquiv<am_unscaled8>;
3185 def gi_am_unscaled16 :
3186 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">,
3187 GIComplexPatternEquiv<am_unscaled16>;
3188 def gi_am_unscaled32 :
3189 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">,
3190 GIComplexPatternEquiv<am_unscaled32>;
3191 def gi_am_unscaled64 :
3192 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">,
3193 GIComplexPatternEquiv<am_unscaled64>;
3194 def gi_am_unscaled128 :
3195 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">,
3196 GIComplexPatternEquiv<am_unscaled128>;
3199 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3200 string asm, list<dag> pattern>
3201 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
3205 let Inst{31-30} = sz;
3206 let Inst{29-27} = 0b111;
3208 let Inst{25-24} = 0b00;
3209 let Inst{23-22} = opc;
3211 let Inst{20-12} = offset;
3212 let Inst{11-10} = 0b00;
3216 let DecoderMethod = "DecodeSignedLdStInstruction";
3219 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3220 string asm, list<dag> pattern> {
3221 let AddedComplexity = 1 in // try this before LoadUI
3222 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
3223 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
3226 def : InstAlias<asm # "\t$Rt, [$Rn]",
3227 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3230 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3231 string asm, list<dag> pattern> {
3232 let AddedComplexity = 1 in // try this before StoreUI
3233 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3234 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3238 def : InstAlias<asm # "\t$Rt, [$Rn]",
3239 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3242 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
3244 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3245 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3246 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
3250 def : InstAlias<asm # "\t$Rt, [$Rn]",
3251 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
3255 // Load/store unscaled immediate, unprivileged
3258 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3259 dag oops, dag iops, string asm>
3260 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
3264 let Inst{31-30} = sz;
3265 let Inst{29-27} = 0b111;
3267 let Inst{25-24} = 0b00;
3268 let Inst{23-22} = opc;
3270 let Inst{20-12} = offset;
3271 let Inst{11-10} = 0b10;
3275 let DecoderMethod = "DecodeSignedLdStInstruction";
3278 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3279 RegisterClass regtype, string asm> {
3280 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3281 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3282 (ins GPR64sp:$Rn, simm9:$offset), asm>,
3285 def : InstAlias<asm # "\t$Rt, [$Rn]",
3286 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3289 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3290 RegisterClass regtype, string asm> {
3291 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3292 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3293 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3297 def : InstAlias<asm # "\t$Rt, [$Rn]",
3298 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3302 // Load/store pre-indexed
3305 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3306 string asm, string cstr, list<dag> pat>
3307 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3311 let Inst{31-30} = sz;
3312 let Inst{29-27} = 0b111;
3314 let Inst{25-24} = 0;
3315 let Inst{23-22} = opc;
3317 let Inst{20-12} = offset;
3318 let Inst{11-10} = 0b11;
3322 let DecoderMethod = "DecodeSignedLdStInstruction";
3325 let hasSideEffects = 0 in {
3326 let mayStore = 0, mayLoad = 1 in
3327 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3329 : BaseLoadStorePreIdx<sz, V, opc,
3330 (outs GPR64sp:$wback, regtype:$Rt),
3331 (ins GPR64sp:$Rn, simm9:$offset), asm,
3332 "$Rn = $wback,@earlyclobber $wback", []>,
3333 Sched<[WriteLD, WriteAdr]>;
3335 let mayStore = 1, mayLoad = 0 in
3336 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3337 string asm, SDPatternOperator storeop, ValueType Ty>
3338 : BaseLoadStorePreIdx<sz, V, opc,
3339 (outs GPR64sp:$wback),
3340 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3341 asm, "$Rn = $wback,@earlyclobber $wback",
3342 [(set GPR64sp:$wback,
3343 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3344 Sched<[WriteAdr, WriteST]>;
3345 } // hasSideEffects = 0
3348 // Load/store post-indexed
3351 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3352 string asm, string cstr, list<dag> pat>
3353 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
3357 let Inst{31-30} = sz;
3358 let Inst{29-27} = 0b111;
3360 let Inst{25-24} = 0b00;
3361 let Inst{23-22} = opc;
3363 let Inst{20-12} = offset;
3364 let Inst{11-10} = 0b01;
3368 let DecoderMethod = "DecodeSignedLdStInstruction";
3371 let hasSideEffects = 0 in {
3372 let mayStore = 0, mayLoad = 1 in
3373 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3375 : BaseLoadStorePostIdx<sz, V, opc,
3376 (outs GPR64sp:$wback, regtype:$Rt),
3377 (ins GPR64sp:$Rn, simm9:$offset),
3378 asm, "$Rn = $wback,@earlyclobber $wback", []>,
3379 Sched<[WriteLD, WriteI]>;
3381 let mayStore = 1, mayLoad = 0 in
3382 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3383 string asm, SDPatternOperator storeop, ValueType Ty>
3384 : BaseLoadStorePostIdx<sz, V, opc,
3385 (outs GPR64sp:$wback),
3386 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3387 asm, "$Rn = $wback,@earlyclobber $wback",
3388 [(set GPR64sp:$wback,
3389 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3390 Sched<[WriteAdr, WriteST, ReadAdrBase]>;
3391 } // hasSideEffects = 0
3398 // (indexed, offset)
3400 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
3402 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3407 let Inst{31-30} = opc;
3408 let Inst{29-27} = 0b101;
3410 let Inst{25-23} = 0b010;
3412 let Inst{21-15} = offset;
3413 let Inst{14-10} = Rt2;
3417 let DecoderMethod = "DecodePairLdStInstruction";
3420 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
3421 Operand indextype, string asm> {
3422 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3423 def i : BaseLoadStorePairOffset<opc, V, 1,
3424 (outs regtype:$Rt, regtype:$Rt2),
3425 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3426 Sched<[WriteLD, WriteLDHi]>;
3428 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3429 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3434 multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
3435 Operand indextype, string asm> {
3436 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
3437 def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
3438 (ins regtype:$Rt, regtype:$Rt2,
3439 GPR64sp:$Rn, indextype:$offset),
3443 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3444 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3449 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3451 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
3456 let Inst{31-30} = opc;
3457 let Inst{29-27} = 0b101;
3459 let Inst{25-23} = 0b011;
3461 let Inst{21-15} = offset;
3462 let Inst{14-10} = Rt2;
3466 let DecoderMethod = "DecodePairLdStInstruction";
3469 let hasSideEffects = 0 in {
3470 let mayStore = 0, mayLoad = 1 in
3471 class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3472 Operand indextype, string asm>
3473 : BaseLoadStorePairPreIdx<opc, V, 1,
3474 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3475 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3476 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3478 let mayStore = 1, mayLoad = 0 in
3479 class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3480 Operand indextype, string asm>
3481 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
3482 (ins regtype:$Rt, regtype:$Rt2,
3483 GPR64sp:$Rn, indextype:$offset),
3485 Sched<[WriteAdr, WriteSTP]>;
3486 } // hasSideEffects = 0
3490 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3492 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
3497 let Inst{31-30} = opc;
3498 let Inst{29-27} = 0b101;
3500 let Inst{25-23} = 0b001;
3502 let Inst{21-15} = offset;
3503 let Inst{14-10} = Rt2;
3507 let DecoderMethod = "DecodePairLdStInstruction";
3510 let hasSideEffects = 0 in {
3511 let mayStore = 0, mayLoad = 1 in
3512 class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3513 Operand idxtype, string asm>
3514 : BaseLoadStorePairPostIdx<opc, V, 1,
3515 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3516 (ins GPR64sp:$Rn, idxtype:$offset), asm>,
3517 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3519 let mayStore = 1, mayLoad = 0 in
3520 class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3521 Operand idxtype, string asm>
3522 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
3523 (ins regtype:$Rt, regtype:$Rt2,
3524 GPR64sp:$Rn, idxtype:$offset),
3526 Sched<[WriteAdr, WriteSTP]>;
3527 } // hasSideEffects = 0
3531 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
3533 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3538 let Inst{31-30} = opc;
3539 let Inst{29-27} = 0b101;
3541 let Inst{25-23} = 0b000;
3543 let Inst{21-15} = offset;
3544 let Inst{14-10} = Rt2;
3548 let DecoderMethod = "DecodePairLdStInstruction";
3551 multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3552 Operand indextype, string asm> {
3553 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3554 def i : BaseLoadStorePairNoAlloc<opc, V, 1,
3555 (outs regtype:$Rt, regtype:$Rt2),
3556 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3557 Sched<[WriteLD, WriteLDHi]>;
3560 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3561 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3565 multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3566 Operand indextype, string asm> {
3567 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
3568 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
3569 (ins regtype:$Rt, regtype:$Rt2,
3570 GPR64sp:$Rn, indextype:$offset),
3574 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3575 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3580 // Load/store exclusive
3583 // True exclusive operations write to and/or read from the system's exclusive
3584 // monitors, which as far as a compiler is concerned can be modelled as a
3585 // random shared memory address. Hence LoadExclusive mayStore.
3587 // Since these instructions have the undefined register bits set to 1 in
3588 // their canonical form, we need a post encoder method to set those bits
3589 // to 1 when encoding these instructions. We do this using the
3590 // fixLoadStoreExclusive function. This function has template parameters:
3592 // fixLoadStoreExclusive<int hasRs, int hasRt2>
3594 // hasRs indicates that the instruction uses the Rs field, so we won't set
3595 // it to 1 (and the same for Rt2). We don't need template parameters for
3596 // the other register fields since Rt and Rn are always used.
3598 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
3599 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3600 dag oops, dag iops, string asm, string operands>
3601 : I<oops, iops, asm, operands, "", []> {
3602 let Inst{31-30} = sz;
3603 let Inst{29-24} = 0b001000;
3609 let DecoderMethod = "DecodeExclusiveLdStInstruction";
3612 // Neither Rs nor Rt2 operands.
3613 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3614 dag oops, dag iops, string asm, string operands>
3615 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
3618 let Inst{20-16} = 0b11111;
3619 let Unpredictable{20-16} = 0b11111;
3620 let Inst{14-10} = 0b11111;
3621 let Unpredictable{14-10} = 0b11111;
3625 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
3628 // Simple load acquires don't set the exclusive monitor
3629 let mayLoad = 1, mayStore = 0 in
3630 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3631 RegisterClass regtype, string asm>
3632 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3633 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3636 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3637 RegisterClass regtype, string asm>
3638 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3639 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3642 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3643 RegisterClass regtype, string asm>
3644 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3645 (outs regtype:$Rt, regtype:$Rt2),
3646 (ins GPR64sp0:$Rn), asm,
3647 "\t$Rt, $Rt2, [$Rn]">,
3648 Sched<[WriteLD, WriteLDHi]> {
3652 let Inst{14-10} = Rt2;
3656 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
3659 // Simple store release operations do not check the exclusive monitor.
3660 let mayLoad = 0, mayStore = 1 in
3661 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3662 RegisterClass regtype, string asm>
3663 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
3664 (ins regtype:$Rt, GPR64sp0:$Rn),
3665 asm, "\t$Rt, [$Rn]">,
3668 let mayLoad = 1, mayStore = 1 in
3669 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3670 RegisterClass regtype, string asm>
3671 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
3672 (ins regtype:$Rt, GPR64sp0:$Rn),
3673 asm, "\t$Ws, $Rt, [$Rn]">,
3678 let Inst{20-16} = Ws;
3682 let Constraints = "@earlyclobber $Ws";
3683 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
3686 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3687 RegisterClass regtype, string asm>
3688 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3690 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
3691 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
3697 let Inst{20-16} = Ws;
3698 let Inst{14-10} = Rt2;
3702 let Constraints = "@earlyclobber $Ws";
3706 // Exception generation
3709 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3710 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
3711 : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
3714 let Inst{31-24} = 0b11010100;
3715 let Inst{23-21} = op1;
3716 let Inst{20-5} = imm;
3717 let Inst{4-2} = 0b000;
3721 let Predicates = [HasFPARMv8] in {
3724 // Floating point to integer conversion
3727 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
3728 RegisterClass srcType, RegisterClass dstType,
3729 string asm, list<dag> pattern>
3730 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3731 asm, "\t$Rd, $Rn", "", pattern>,
3732 Sched<[WriteFCvt]> {
3735 let Inst{30-29} = 0b00;
3736 let Inst{28-24} = 0b11110;
3737 let Inst{23-22} = type;
3739 let Inst{20-19} = rmode;
3740 let Inst{18-16} = opcode;
3741 let Inst{15-10} = 0;
3746 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3747 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
3748 RegisterClass srcType, RegisterClass dstType,
3749 Operand immType, string asm, list<dag> pattern>
3750 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3751 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3752 Sched<[WriteFCvt]> {
3756 let Inst{30-29} = 0b00;
3757 let Inst{28-24} = 0b11110;
3758 let Inst{23-22} = type;
3760 let Inst{20-19} = rmode;
3761 let Inst{18-16} = opcode;
3762 let Inst{15-10} = scale;
3767 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
3768 SDPatternOperator OpN> {
3769 // Unscaled half-precision to 32-bit
3770 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
3771 [(set GPR32:$Rd, (OpN FPR16:$Rn))]> {
3772 let Inst{31} = 0; // 32-bit GPR flag
3773 let Predicates = [HasFullFP16];
3776 // Unscaled half-precision to 64-bit
3777 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
3778 [(set GPR64:$Rd, (OpN FPR16:$Rn))]> {
3779 let Inst{31} = 1; // 64-bit GPR flag
3780 let Predicates = [HasFullFP16];
3783 // Unscaled single-precision to 32-bit
3784 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
3785 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
3786 let Inst{31} = 0; // 32-bit GPR flag
3789 // Unscaled single-precision to 64-bit
3790 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
3791 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
3792 let Inst{31} = 1; // 64-bit GPR flag
3795 // Unscaled double-precision to 32-bit
3796 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
3797 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3798 let Inst{31} = 0; // 32-bit GPR flag
3801 // Unscaled double-precision to 64-bit
3802 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
3803 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3804 let Inst{31} = 1; // 64-bit GPR flag
3808 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
3809 SDPatternOperator OpN> {
3810 // Scaled half-precision to 32-bit
3811 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
3812 fixedpoint_f16_i32, asm,
3813 [(set GPR32:$Rd, (OpN (fmul FPR16:$Rn,
3814 fixedpoint_f16_i32:$scale)))]> {
3815 let Inst{31} = 0; // 32-bit GPR flag
3817 let Predicates = [HasFullFP16];
3820 // Scaled half-precision to 64-bit
3821 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
3822 fixedpoint_f16_i64, asm,
3823 [(set GPR64:$Rd, (OpN (fmul FPR16:$Rn,
3824 fixedpoint_f16_i64:$scale)))]> {
3825 let Inst{31} = 1; // 64-bit GPR flag
3826 let Predicates = [HasFullFP16];
3829 // Scaled single-precision to 32-bit
3830 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
3831 fixedpoint_f32_i32, asm,
3832 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
3833 fixedpoint_f32_i32:$scale)))]> {
3834 let Inst{31} = 0; // 32-bit GPR flag
3838 // Scaled single-precision to 64-bit
3839 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
3840 fixedpoint_f32_i64, asm,
3841 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
3842 fixedpoint_f32_i64:$scale)))]> {
3843 let Inst{31} = 1; // 64-bit GPR flag
3846 // Scaled double-precision to 32-bit
3847 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
3848 fixedpoint_f64_i32, asm,
3849 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
3850 fixedpoint_f64_i32:$scale)))]> {
3851 let Inst{31} = 0; // 32-bit GPR flag
3855 // Scaled double-precision to 64-bit
3856 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
3857 fixedpoint_f64_i64, asm,
3858 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
3859 fixedpoint_f64_i64:$scale)))]> {
3860 let Inst{31} = 1; // 64-bit GPR flag
3865 // Integer to floating point conversion
3868 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
3869 class BaseIntegerToFP<bit isUnsigned,
3870 RegisterClass srcType, RegisterClass dstType,
3871 Operand immType, string asm, list<dag> pattern>
3872 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3873 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3874 Sched<[WriteFCvt]> {
3878 let Inst{30-24} = 0b0011110;
3879 let Inst{21-17} = 0b00001;
3880 let Inst{16} = isUnsigned;
3881 let Inst{15-10} = scale;
3886 class BaseIntegerToFPUnscaled<bit isUnsigned,
3887 RegisterClass srcType, RegisterClass dstType,
3888 ValueType dvt, string asm, SDNode node>
3889 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3890 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
3891 Sched<[WriteFCvt]> {
3895 let Inst{30-24} = 0b0011110;
3896 let Inst{21-17} = 0b10001;
3897 let Inst{16} = isUnsigned;
3898 let Inst{15-10} = 0b000000;
3903 multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
3905 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
3906 let Inst{31} = 0; // 32-bit GPR flag
3907 let Inst{23-22} = 0b11; // 16-bit FPR flag
3908 let Predicates = [HasFullFP16];
3911 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
3912 let Inst{31} = 0; // 32-bit GPR flag
3913 let Inst{23-22} = 0b00; // 32-bit FPR flag
3916 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
3917 let Inst{31} = 0; // 32-bit GPR flag
3918 let Inst{23-22} = 0b01; // 64-bit FPR flag
3921 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
3922 let Inst{31} = 1; // 64-bit GPR flag
3923 let Inst{23-22} = 0b11; // 16-bit FPR flag
3924 let Predicates = [HasFullFP16];
3927 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
3928 let Inst{31} = 1; // 64-bit GPR flag
3929 let Inst{23-22} = 0b00; // 32-bit FPR flag
3932 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
3933 let Inst{31} = 1; // 64-bit GPR flag
3934 let Inst{23-22} = 0b01; // 64-bit FPR flag
3938 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm,
3940 (fdiv (node GPR32:$Rn),
3941 fixedpoint_f16_i32:$scale))]> {
3942 let Inst{31} = 0; // 32-bit GPR flag
3943 let Inst{23-22} = 0b11; // 16-bit FPR flag
3945 let Predicates = [HasFullFP16];
3948 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
3950 (fdiv (node GPR32:$Rn),
3951 fixedpoint_f32_i32:$scale))]> {
3952 let Inst{31} = 0; // 32-bit GPR flag
3953 let Inst{23-22} = 0b00; // 32-bit FPR flag
3957 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
3959 (fdiv (node GPR32:$Rn),
3960 fixedpoint_f64_i32:$scale))]> {
3961 let Inst{31} = 0; // 32-bit GPR flag
3962 let Inst{23-22} = 0b01; // 64-bit FPR flag
3966 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm,
3968 (fdiv (node GPR64:$Rn),
3969 fixedpoint_f16_i64:$scale))]> {
3970 let Inst{31} = 1; // 64-bit GPR flag
3971 let Inst{23-22} = 0b11; // 16-bit FPR flag
3972 let Predicates = [HasFullFP16];
3975 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
3977 (fdiv (node GPR64:$Rn),
3978 fixedpoint_f32_i64:$scale))]> {
3979 let Inst{31} = 1; // 64-bit GPR flag
3980 let Inst{23-22} = 0b00; // 32-bit FPR flag
3983 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
3985 (fdiv (node GPR64:$Rn),
3986 fixedpoint_f64_i64:$scale))]> {
3987 let Inst{31} = 1; // 64-bit GPR flag
3988 let Inst{23-22} = 0b01; // 64-bit FPR flag
3993 // Unscaled integer <-> floating point conversion (i.e. FMOV)
3996 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3997 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
3998 RegisterClass srcType, RegisterClass dstType,
4000 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
4001 // We use COPY_TO_REGCLASS for these bitconvert operations.
4002 // copyPhysReg() expands the resultant COPY instructions after
4003 // regalloc is done. This gives greater freedom for the allocator
4004 // and related passes (coalescing, copy propagation, et. al.) to
4005 // be more effective.
4006 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
4007 Sched<[WriteFCopy]> {
4010 let Inst{30-24} = 0b0011110;
4012 let Inst{20-19} = rmode;
4013 let Inst{18-16} = opcode;
4014 let Inst{15-10} = 0b000000;
4019 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4020 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
4021 RegisterClass srcType, RegisterOperand dstType, string asm,
4023 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
4024 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
4025 Sched<[WriteFCopy]> {
4028 let Inst{30-23} = 0b00111101;
4030 let Inst{20-19} = rmode;
4031 let Inst{18-16} = opcode;
4032 let Inst{15-10} = 0b000000;
4036 let DecoderMethod = "DecodeFMOVLaneInstruction";
4039 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4040 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
4041 RegisterOperand srcType, RegisterClass dstType, string asm,
4043 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
4044 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
4045 Sched<[WriteFCopy]> {
4048 let Inst{30-23} = 0b00111101;
4050 let Inst{20-19} = rmode;
4051 let Inst{18-16} = opcode;
4052 let Inst{15-10} = 0b000000;
4056 let DecoderMethod = "DecodeFMOVLaneInstruction";
4060 multiclass UnscaledConversion<string asm> {
4061 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
4062 let Inst{31} = 0; // 32-bit GPR flag
4063 let Inst{23-22} = 0b11; // 16-bit FPR flag
4064 let Predicates = [HasFullFP16];
4067 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
4068 let Inst{31} = 1; // 64-bit GPR flag
4069 let Inst{23-22} = 0b11; // 16-bit FPR flag
4070 let Predicates = [HasFullFP16];
4073 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
4074 let Inst{31} = 0; // 32-bit GPR flag
4075 let Inst{23-22} = 0b00; // 32-bit FPR flag
4078 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
4079 let Inst{31} = 1; // 64-bit GPR flag
4080 let Inst{23-22} = 0b01; // 64-bit FPR flag
4083 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
4084 let Inst{31} = 0; // 32-bit GPR flag
4085 let Inst{23-22} = 0b11; // 16-bit FPR flag
4086 let Predicates = [HasFullFP16];
4089 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
4090 let Inst{31} = 1; // 64-bit GPR flag
4091 let Inst{23-22} = 0b11; // 16-bit FPR flag
4092 let Predicates = [HasFullFP16];
4095 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
4096 let Inst{31} = 0; // 32-bit GPR flag
4097 let Inst{23-22} = 0b00; // 32-bit FPR flag
4100 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
4101 let Inst{31} = 1; // 64-bit GPR flag
4102 let Inst{23-22} = 0b01; // 64-bit FPR flag
4105 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
4111 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
4119 // Floating point conversion
4122 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
4123 RegisterClass srcType, string asm, list<dag> pattern>
4124 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
4125 Sched<[WriteFCvt]> {
4128 let Inst{31-24} = 0b00011110;
4129 let Inst{23-22} = type;
4130 let Inst{21-17} = 0b10001;
4131 let Inst{16-15} = opcode;
4132 let Inst{14-10} = 0b10000;
4137 multiclass FPConversion<string asm> {
4138 // Double-precision to Half-precision
4139 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
4140 [(set FPR16:$Rd, (fpround FPR64:$Rn))]>;
4142 // Double-precision to Single-precision
4143 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
4144 [(set FPR32:$Rd, (fpround FPR64:$Rn))]>;
4146 // Half-precision to Double-precision
4147 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
4148 [(set FPR64:$Rd, (fpextend FPR16:$Rn))]>;
4150 // Half-precision to Single-precision
4151 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
4152 [(set FPR32:$Rd, (fpextend FPR16:$Rn))]>;
4154 // Single-precision to Double-precision
4155 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
4156 [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>;
4158 // Single-precision to Half-precision
4159 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
4160 [(set FPR16:$Rd, (fpround FPR32:$Rn))]>;
4164 // Single operand floating point data processing
4167 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4168 class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
4169 ValueType vt, string asm, SDPatternOperator node>
4170 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
4171 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
4175 let Inst{31-24} = 0b00011110;
4176 let Inst{21-19} = 0b100;
4177 let Inst{18-15} = opcode;
4178 let Inst{14-10} = 0b10000;
4183 multiclass SingleOperandFPData<bits<4> opcode, string asm,
4184 SDPatternOperator node = null_frag> {
4185 def Hr : BaseSingleOperandFPData<opcode, FPR16, f16, asm, node> {
4186 let Inst{23-22} = 0b11; // 16-bit size flag
4187 let Predicates = [HasFullFP16];
4190 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
4191 let Inst{23-22} = 0b00; // 32-bit size flag
4194 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
4195 let Inst{23-22} = 0b01; // 64-bit size flag
4200 // Two operand floating point data processing
4203 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4204 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
4205 string asm, list<dag> pat>
4206 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
4207 asm, "\t$Rd, $Rn, $Rm", "", pat>,
4212 let Inst{31-24} = 0b00011110;
4214 let Inst{20-16} = Rm;
4215 let Inst{15-12} = opcode;
4216 let Inst{11-10} = 0b10;
4221 multiclass TwoOperandFPData<bits<4> opcode, string asm,
4222 SDPatternOperator node = null_frag> {
4223 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4224 [(set (f16 FPR16:$Rd),
4225 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
4226 let Inst{23-22} = 0b11; // 16-bit size flag
4227 let Predicates = [HasFullFP16];
4230 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4231 [(set (f32 FPR32:$Rd),
4232 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
4233 let Inst{23-22} = 0b00; // 32-bit size flag
4236 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4237 [(set (f64 FPR64:$Rd),
4238 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
4239 let Inst{23-22} = 0b01; // 64-bit size flag
4243 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
4244 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4245 [(set FPR16:$Rd, (fneg (node FPR16:$Rn, (f16 FPR16:$Rm))))]> {
4246 let Inst{23-22} = 0b11; // 16-bit size flag
4247 let Predicates = [HasFullFP16];
4250 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4251 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
4252 let Inst{23-22} = 0b00; // 32-bit size flag
4255 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4256 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
4257 let Inst{23-22} = 0b01; // 64-bit size flag
4263 // Three operand floating point data processing
4266 class BaseThreeOperandFPData<bit isNegated, bit isSub,
4267 RegisterClass regtype, string asm, list<dag> pat>
4268 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
4269 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
4270 Sched<[WriteFMul]> {
4275 let Inst{31-24} = 0b00011111;
4276 let Inst{21} = isNegated;
4277 let Inst{20-16} = Rm;
4278 let Inst{15} = isSub;
4279 let Inst{14-10} = Ra;
4284 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
4285 SDPatternOperator node> {
4286 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
4288 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
4289 let Inst{23-22} = 0b11; // 16-bit size flag
4290 let Predicates = [HasFullFP16];
4293 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
4295 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
4296 let Inst{23-22} = 0b00; // 32-bit size flag
4299 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
4301 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
4302 let Inst{23-22} = 0b01; // 64-bit size flag
4307 // Floating point data comparisons
4310 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4311 class BaseOneOperandFPComparison<bit signalAllNans,
4312 RegisterClass regtype, string asm,
4314 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
4315 Sched<[WriteFCmp]> {
4317 let Inst{31-24} = 0b00011110;
4320 let Inst{15-10} = 0b001000;
4322 let Inst{4} = signalAllNans;
4323 let Inst{3-0} = 0b1000;
4325 // Rm should be 0b00000 canonically, but we need to accept any value.
4326 let PostEncoderMethod = "fixOneOperandFPComparison";
4329 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4330 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
4331 string asm, list<dag> pat>
4332 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
4333 Sched<[WriteFCmp]> {
4336 let Inst{31-24} = 0b00011110;
4338 let Inst{20-16} = Rm;
4339 let Inst{15-10} = 0b001000;
4341 let Inst{4} = signalAllNans;
4342 let Inst{3-0} = 0b0000;
4345 multiclass FPComparison<bit signalAllNans, string asm,
4346 SDPatternOperator OpNode = null_frag> {
4347 let Defs = [NZCV] in {
4348 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
4349 [(OpNode FPR16:$Rn, (f16 FPR16:$Rm)), (implicit NZCV)]> {
4350 let Inst{23-22} = 0b11;
4351 let Predicates = [HasFullFP16];
4354 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
4355 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
4356 let Inst{23-22} = 0b11;
4357 let Predicates = [HasFullFP16];
4360 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
4361 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
4362 let Inst{23-22} = 0b00;
4365 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
4366 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
4367 let Inst{23-22} = 0b00;
4370 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
4371 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
4372 let Inst{23-22} = 0b01;
4375 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
4376 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
4377 let Inst{23-22} = 0b01;
4383 // Floating point conditional comparisons
4386 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4387 class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
4388 string mnemonic, list<dag> pat>
4389 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
4390 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
4391 Sched<[WriteFCmp]> {
4400 let Inst{31-24} = 0b00011110;
4402 let Inst{20-16} = Rm;
4403 let Inst{15-12} = cond;
4404 let Inst{11-10} = 0b01;
4406 let Inst{4} = signalAllNans;
4407 let Inst{3-0} = nzcv;
4410 multiclass FPCondComparison<bit signalAllNans, string mnemonic,
4411 SDPatternOperator OpNode = null_frag> {
4412 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, []> {
4413 let Inst{23-22} = 0b11;
4414 let Predicates = [HasFullFP16];
4417 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
4418 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
4419 (i32 imm:$cond), NZCV))]> {
4420 let Inst{23-22} = 0b00;
4423 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
4424 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
4425 (i32 imm:$cond), NZCV))]> {
4426 let Inst{23-22} = 0b01;
4431 // Floating point conditional select
4434 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
4435 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
4436 asm, "\t$Rd, $Rn, $Rm, $cond", "",
4438 (AArch64csel (vt regtype:$Rn), regtype:$Rm,
4439 (i32 imm:$cond), NZCV))]>,
4446 let Inst{31-24} = 0b00011110;
4448 let Inst{20-16} = Rm;
4449 let Inst{15-12} = cond;
4450 let Inst{11-10} = 0b11;
4455 multiclass FPCondSelect<string asm> {
4456 let Uses = [NZCV] in {
4457 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
4458 let Inst{23-22} = 0b11;
4459 let Predicates = [HasFullFP16];
4462 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
4463 let Inst{23-22} = 0b00;
4466 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
4467 let Inst{23-22} = 0b01;
4473 // Floating move immediate
4476 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
4477 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
4478 [(set regtype:$Rd, fpimmtype:$imm)]>,
4479 Sched<[WriteFImm]> {
4482 let Inst{31-24} = 0b00011110;
4484 let Inst{20-13} = imm;
4485 let Inst{12-5} = 0b10000000;
4489 multiclass FPMoveImmediate<string asm> {
4490 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
4491 let Inst{23-22} = 0b11;
4492 let Predicates = [HasFullFP16];
4495 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
4496 let Inst{23-22} = 0b00;
4499 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
4500 let Inst{23-22} = 0b01;
4503 } // end of 'let Predicates = [HasFPARMv8]'
4505 //----------------------------------------------------------------------------
4507 //----------------------------------------------------------------------------
4509 let Predicates = [HasNEON] in {
4511 //----------------------------------------------------------------------------
4512 // AdvSIMD three register vector instructions
4513 //----------------------------------------------------------------------------
4515 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4516 class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
4517 RegisterOperand regtype, string asm, string kind,
4519 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4520 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4521 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
4529 let Inst{28-24} = 0b01110;
4530 let Inst{23-21} = size;
4531 let Inst{20-16} = Rm;
4532 let Inst{15-11} = opcode;
4538 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4539 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
4540 RegisterOperand regtype, string asm, string kind,
4542 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
4543 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4544 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4552 let Inst{28-24} = 0b01110;
4553 let Inst{23-21} = size;
4554 let Inst{20-16} = Rm;
4555 let Inst{15-11} = opcode;
4561 class BaseSIMDThreeSameVectorDot<bit Q, bit U, string asm, string kind1,
4563 BaseSIMDThreeSameVector<Q, U, 0b100, 0b10010, V128, asm, kind1, [] > {
4564 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # "}");
4567 // All operand sizes distinguished in the encoding.
4568 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
4569 SDPatternOperator OpNode> {
4570 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4572 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4573 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4575 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4576 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4578 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4579 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4581 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4582 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4584 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4585 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4587 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4588 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
4590 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4593 // As above, but D sized elements unsupported.
4594 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
4595 SDPatternOperator OpNode> {
4596 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4598 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
4599 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4601 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
4602 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4604 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
4605 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4607 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
4608 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4610 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
4611 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4613 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
4616 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
4617 SDPatternOperator OpNode> {
4618 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
4620 [(set (v8i8 V64:$dst),
4621 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4622 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
4624 [(set (v16i8 V128:$dst),
4625 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4626 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
4628 [(set (v4i16 V64:$dst),
4629 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4630 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
4632 [(set (v8i16 V128:$dst),
4633 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4634 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
4636 [(set (v2i32 V64:$dst),
4637 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4638 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
4640 [(set (v4i32 V128:$dst),
4641 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4644 // As above, but only B sized elements supported.
4645 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
4646 SDPatternOperator OpNode> {
4647 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4649 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4650 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4652 [(set (v16i8 V128:$Rd),
4653 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4656 // As above, but only floating point elements supported.
4657 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
4658 string asm, SDPatternOperator OpNode> {
4659 let Predicates = [HasNEON, HasFullFP16] in {
4660 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
4662 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4663 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
4665 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4666 } // Predicates = [HasNEON, HasFullFP16]
4667 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
4669 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4670 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
4672 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4673 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
4675 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4678 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
4680 SDPatternOperator OpNode> {
4681 let Predicates = [HasNEON, HasFullFP16] in {
4682 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
4684 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4685 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
4687 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4688 } // Predicates = [HasNEON, HasFullFP16]
4689 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
4691 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4692 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
4694 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4695 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
4697 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4700 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
4701 string asm, SDPatternOperator OpNode> {
4702 let Predicates = [HasNEON, HasFullFP16] in {
4703 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
4705 [(set (v4f16 V64:$dst),
4706 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4707 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
4709 [(set (v8f16 V128:$dst),
4710 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4711 } // Predicates = [HasNEON, HasFullFP16]
4712 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
4714 [(set (v2f32 V64:$dst),
4715 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4716 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
4718 [(set (v4f32 V128:$dst),
4719 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4720 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
4722 [(set (v2f64 V128:$dst),
4723 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4726 // As above, but D and B sized elements unsupported.
4727 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
4728 SDPatternOperator OpNode> {
4729 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4731 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4732 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4734 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4735 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4737 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4738 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4740 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4743 // Logical three vector ops share opcode bits, and only use B sized elements.
4744 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
4745 SDPatternOperator OpNode = null_frag> {
4746 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
4748 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
4749 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
4751 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
4753 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
4754 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4755 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
4756 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4757 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
4758 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4760 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
4761 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4762 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
4763 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4764 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
4765 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4768 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
4769 string asm, SDPatternOperator OpNode> {
4770 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
4772 [(set (v8i8 V64:$dst),
4773 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4774 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
4776 [(set (v16i8 V128:$dst),
4777 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
4778 (v16i8 V128:$Rm)))]>;
4780 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
4782 (!cast<Instruction>(NAME#"v8i8")
4783 V64:$LHS, V64:$MHS, V64:$RHS)>;
4784 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
4786 (!cast<Instruction>(NAME#"v8i8")
4787 V64:$LHS, V64:$MHS, V64:$RHS)>;
4788 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
4790 (!cast<Instruction>(NAME#"v8i8")
4791 V64:$LHS, V64:$MHS, V64:$RHS)>;
4793 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
4794 (v8i16 V128:$RHS))),
4795 (!cast<Instruction>(NAME#"v16i8")
4796 V128:$LHS, V128:$MHS, V128:$RHS)>;
4797 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
4798 (v4i32 V128:$RHS))),
4799 (!cast<Instruction>(NAME#"v16i8")
4800 V128:$LHS, V128:$MHS, V128:$RHS)>;
4801 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
4802 (v2i64 V128:$RHS))),
4803 (!cast<Instruction>(NAME#"v16i8")
4804 V128:$LHS, V128:$MHS, V128:$RHS)>;
4808 //----------------------------------------------------------------------------
4809 // AdvSIMD two register vector instructions.
4810 //----------------------------------------------------------------------------
4812 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4813 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4814 bits<2> size2, RegisterOperand regtype, string asm,
4815 string dstkind, string srckind, list<dag> pattern>
4816 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4817 "{\t$Rd" # dstkind # ", $Rn" # srckind #
4818 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
4825 let Inst{28-24} = 0b01110;
4826 let Inst{23-22} = size;
4828 let Inst{20-19} = size2;
4829 let Inst{18-17} = 0b00;
4830 let Inst{16-12} = opcode;
4831 let Inst{11-10} = 0b10;
4836 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4837 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4838 bits<2> size2, RegisterOperand regtype,
4839 string asm, string dstkind, string srckind,
4841 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
4842 "{\t$Rd" # dstkind # ", $Rn" # srckind #
4843 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4850 let Inst{28-24} = 0b01110;
4851 let Inst{23-22} = size;
4853 let Inst{20-19} = size2;
4854 let Inst{18-17} = 0b00;
4855 let Inst{16-12} = opcode;
4856 let Inst{11-10} = 0b10;
4861 // Supports B, H, and S element sizes.
4862 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
4863 SDPatternOperator OpNode> {
4864 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
4866 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4867 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
4868 asm, ".16b", ".16b",
4869 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4870 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
4872 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4873 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
4875 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4876 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
4878 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4879 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
4881 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4884 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
4885 RegisterOperand regtype, string asm, string dstkind,
4886 string srckind, string amount>
4887 : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
4888 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
4889 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,
4895 let Inst{29-24} = 0b101110;
4896 let Inst{23-22} = size;
4897 let Inst{21-10} = 0b100001001110;
4902 multiclass SIMDVectorLShiftLongBySizeBHS {
4903 let hasSideEffects = 0 in {
4904 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
4905 "shll", ".8h", ".8b", "8">;
4906 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
4907 "shll2", ".8h", ".16b", "8">;
4908 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
4909 "shll", ".4s", ".4h", "16">;
4910 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
4911 "shll2", ".4s", ".8h", "16">;
4912 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
4913 "shll", ".2d", ".2s", "32">;
4914 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
4915 "shll2", ".2d", ".4s", "32">;
4919 // Supports all element sizes.
4920 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
4921 SDPatternOperator OpNode> {
4922 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
4924 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4925 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
4927 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4928 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
4930 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4931 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
4933 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4934 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
4936 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4937 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
4939 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4942 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
4943 SDPatternOperator OpNode> {
4944 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
4946 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
4948 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
4950 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
4951 (v16i8 V128:$Rn)))]>;
4952 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
4954 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
4955 (v4i16 V64:$Rn)))]>;
4956 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
4958 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
4959 (v8i16 V128:$Rn)))]>;
4960 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
4962 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
4963 (v2i32 V64:$Rn)))]>;
4964 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
4966 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
4967 (v4i32 V128:$Rn)))]>;
4970 // Supports all element sizes, except 1xD.
4971 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
4972 SDPatternOperator OpNode> {
4973 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
4975 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
4976 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
4977 asm, ".16b", ".16b",
4978 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
4979 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
4981 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
4982 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
4984 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
4985 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
4987 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
4988 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
4990 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
4991 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
4993 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
4996 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
4997 SDPatternOperator OpNode = null_frag> {
4998 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5000 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5001 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5002 asm, ".16b", ".16b",
5003 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5004 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5006 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5007 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5009 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5010 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
5012 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5013 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
5015 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5016 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
5018 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5022 // Supports only B element sizes.
5023 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
5024 SDPatternOperator OpNode> {
5025 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
5027 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
5028 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
5029 asm, ".16b", ".16b",
5030 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
5034 // Supports only B and H element sizes.
5035 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
5036 SDPatternOperator OpNode> {
5037 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
5039 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
5040 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
5041 asm, ".16b", ".16b",
5042 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
5043 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
5045 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
5046 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
5048 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
5051 // Supports only S and D element sizes, uses high bit of the size field
5052 // as an extra opcode bit.
5053 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
5054 SDPatternOperator OpNode> {
5055 let Predicates = [HasNEON, HasFullFP16] in {
5056 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5058 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5059 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5061 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5062 } // Predicates = [HasNEON, HasFullFP16]
5063 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5065 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5066 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5068 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5069 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5071 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5074 // Supports only S element size.
5075 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
5076 SDPatternOperator OpNode> {
5077 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5079 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5080 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5082 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5086 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
5087 SDPatternOperator OpNode> {
5088 let Predicates = [HasNEON, HasFullFP16] in {
5089 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5091 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
5092 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5094 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
5095 } // Predicates = [HasNEON, HasFullFP16]
5096 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5098 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
5099 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5101 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
5102 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5104 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5107 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
5108 SDPatternOperator OpNode> {
5109 let Predicates = [HasNEON, HasFullFP16] in {
5110 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
5112 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
5113 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
5115 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5116 } // Predicates = [HasNEON, HasFullFP16]
5117 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
5119 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
5120 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
5122 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5123 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
5125 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5129 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5130 RegisterOperand inreg, RegisterOperand outreg,
5131 string asm, string outkind, string inkind,
5133 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
5134 "{\t$Rd" # outkind # ", $Rn" # inkind #
5135 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
5142 let Inst{28-24} = 0b01110;
5143 let Inst{23-22} = size;
5144 let Inst{21-17} = 0b10000;
5145 let Inst{16-12} = opcode;
5146 let Inst{11-10} = 0b10;
5151 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5152 RegisterOperand inreg, RegisterOperand outreg,
5153 string asm, string outkind, string inkind,
5155 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
5156 "{\t$Rd" # outkind # ", $Rn" # inkind #
5157 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
5164 let Inst{28-24} = 0b01110;
5165 let Inst{23-22} = size;
5166 let Inst{21-17} = 0b10000;
5167 let Inst{16-12} = opcode;
5168 let Inst{11-10} = 0b10;
5173 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
5174 SDPatternOperator OpNode> {
5175 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
5177 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
5178 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
5179 asm#"2", ".16b", ".8h", []>;
5180 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
5182 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
5183 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
5184 asm#"2", ".8h", ".4s", []>;
5185 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
5187 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
5188 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
5189 asm#"2", ".4s", ".2d", []>;
5191 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
5192 (!cast<Instruction>(NAME # "v16i8")
5193 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5194 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
5195 (!cast<Instruction>(NAME # "v8i16")
5196 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5197 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
5198 (!cast<Instruction>(NAME # "v4i32")
5199 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5202 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
5203 bits<5> opcode, RegisterOperand regtype, string asm,
5204 string kind, string zero, ValueType dty,
5205 ValueType sty, SDNode OpNode>
5206 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5207 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
5208 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
5209 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
5216 let Inst{28-24} = 0b01110;
5217 let Inst{23-22} = size;
5219 let Inst{20-19} = size2;
5220 let Inst{18-17} = 0b00;
5221 let Inst{16-12} = opcode;
5222 let Inst{11-10} = 0b10;
5227 // Comparisons support all element sizes, except 1xD.
5228 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
5230 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
5232 v8i8, v8i8, OpNode>;
5233 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
5235 v16i8, v16i8, OpNode>;
5236 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
5238 v4i16, v4i16, OpNode>;
5239 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
5241 v8i16, v8i16, OpNode>;
5242 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
5244 v2i32, v2i32, OpNode>;
5245 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
5247 v4i32, v4i32, OpNode>;
5248 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
5250 v2i64, v2i64, OpNode>;
5253 // FP Comparisons support only S and D element sizes (and H for v8.2a).
5254 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
5255 string asm, SDNode OpNode> {
5257 let Predicates = [HasNEON, HasFullFP16] in {
5258 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
5260 v4i16, v4f16, OpNode>;
5261 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
5263 v8i16, v8f16, OpNode>;
5264 } // Predicates = [HasNEON, HasFullFP16]
5265 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
5267 v2i32, v2f32, OpNode>;
5268 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
5270 v4i32, v4f32, OpNode>;
5271 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
5273 v2i64, v2f64, OpNode>;
5275 let Predicates = [HasNEON, HasFullFP16] in {
5276 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
5277 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5278 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
5279 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5281 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
5282 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
5283 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
5284 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
5285 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
5286 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5287 let Predicates = [HasNEON, HasFullFP16] in {
5288 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
5289 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5290 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
5291 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5293 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
5294 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
5295 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
5296 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
5297 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
5298 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5301 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5302 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5303 RegisterOperand outtype, RegisterOperand intype,
5304 string asm, string VdTy, string VnTy,
5306 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
5307 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
5314 let Inst{28-24} = 0b01110;
5315 let Inst{23-22} = size;
5316 let Inst{21-17} = 0b10000;
5317 let Inst{16-12} = opcode;
5318 let Inst{11-10} = 0b10;
5323 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5324 RegisterOperand outtype, RegisterOperand intype,
5325 string asm, string VdTy, string VnTy,
5327 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
5328 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
5335 let Inst{28-24} = 0b01110;
5336 let Inst{23-22} = size;
5337 let Inst{21-17} = 0b10000;
5338 let Inst{16-12} = opcode;
5339 let Inst{11-10} = 0b10;
5344 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
5345 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
5346 asm, ".4s", ".4h", []>;
5347 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
5348 asm#"2", ".4s", ".8h", []>;
5349 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
5350 asm, ".2d", ".2s", []>;
5351 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
5352 asm#"2", ".2d", ".4s", []>;
5355 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
5356 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
5357 asm, ".4h", ".4s", []>;
5358 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
5359 asm#"2", ".8h", ".4s", []>;
5360 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5361 asm, ".2s", ".2d", []>;
5362 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5363 asm#"2", ".4s", ".2d", []>;
5366 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
5368 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5370 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5371 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5372 asm#"2", ".4s", ".2d", []>;
5374 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
5375 (!cast<Instruction>(NAME # "v4f32")
5376 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5379 //----------------------------------------------------------------------------
5380 // AdvSIMD three register different-size vector instructions.
5381 //----------------------------------------------------------------------------
5383 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5384 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
5385 RegisterOperand outtype, RegisterOperand intype1,
5386 RegisterOperand intype2, string asm,
5387 string outkind, string inkind1, string inkind2,
5389 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
5390 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5391 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
5397 let Inst{30} = size{0};
5399 let Inst{28-24} = 0b01110;
5400 let Inst{23-22} = size{2-1};
5402 let Inst{20-16} = Rm;
5403 let Inst{15-12} = opcode;
5404 let Inst{11-10} = 0b00;
5409 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5410 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
5411 RegisterOperand outtype, RegisterOperand intype1,
5412 RegisterOperand intype2, string asm,
5413 string outkind, string inkind1, string inkind2,
5415 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
5416 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5417 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
5423 let Inst{30} = size{0};
5425 let Inst{28-24} = 0b01110;
5426 let Inst{23-22} = size{2-1};
5428 let Inst{20-16} = Rm;
5429 let Inst{15-12} = opcode;
5430 let Inst{11-10} = 0b00;
5435 // FIXME: TableGen doesn't know how to deal with expanded types that also
5436 // change the element count (in this case, placing the results in
5437 // the high elements of the result register rather than the low
5438 // elements). Until that's fixed, we can't code-gen those.
5439 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
5441 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5443 asm, ".8b", ".8h", ".8h",
5444 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5445 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5447 asm#"2", ".16b", ".8h", ".8h",
5449 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5451 asm, ".4h", ".4s", ".4s",
5452 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5453 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5455 asm#"2", ".8h", ".4s", ".4s",
5457 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5459 asm, ".2s", ".2d", ".2d",
5460 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5461 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5463 asm#"2", ".4s", ".2d", ".2d",
5467 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
5468 // a version attached to an instruction.
5469 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
5471 (!cast<Instruction>(NAME # "v8i16_v16i8")
5472 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5473 V128:$Rn, V128:$Rm)>;
5474 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
5476 (!cast<Instruction>(NAME # "v4i32_v8i16")
5477 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5478 V128:$Rn, V128:$Rm)>;
5479 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
5481 (!cast<Instruction>(NAME # "v2i64_v4i32")
5482 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5483 V128:$Rn, V128:$Rm)>;
5486 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
5488 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5490 asm, ".8h", ".8b", ".8b",
5491 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5492 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5494 asm#"2", ".8h", ".16b", ".16b", []>;
5495 let Predicates = [HasCrypto] in {
5496 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
5498 asm, ".1q", ".1d", ".1d", []>;
5499 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
5501 asm#"2", ".1q", ".2d", ".2d", []>;
5504 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
5505 (v8i8 (extract_high_v16i8 V128:$Rm)))),
5506 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
5509 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
5510 SDPatternOperator OpNode> {
5511 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5513 asm, ".4s", ".4h", ".4h",
5514 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5515 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5517 asm#"2", ".4s", ".8h", ".8h",
5518 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5519 (extract_high_v8i16 V128:$Rm)))]>;
5520 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5522 asm, ".2d", ".2s", ".2s",
5523 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5524 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5526 asm#"2", ".2d", ".4s", ".4s",
5527 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5528 (extract_high_v4i32 V128:$Rm)))]>;
5531 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
5532 SDPatternOperator OpNode = null_frag> {
5533 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5535 asm, ".8h", ".8b", ".8b",
5536 [(set (v8i16 V128:$Rd),
5537 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
5538 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5540 asm#"2", ".8h", ".16b", ".16b",
5541 [(set (v8i16 V128:$Rd),
5542 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5543 (extract_high_v16i8 V128:$Rm)))))]>;
5544 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5546 asm, ".4s", ".4h", ".4h",
5547 [(set (v4i32 V128:$Rd),
5548 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
5549 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5551 asm#"2", ".4s", ".8h", ".8h",
5552 [(set (v4i32 V128:$Rd),
5553 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5554 (extract_high_v8i16 V128:$Rm)))))]>;
5555 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5557 asm, ".2d", ".2s", ".2s",
5558 [(set (v2i64 V128:$Rd),
5559 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
5560 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5562 asm#"2", ".2d", ".4s", ".4s",
5563 [(set (v2i64 V128:$Rd),
5564 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5565 (extract_high_v4i32 V128:$Rm)))))]>;
5568 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
5570 SDPatternOperator OpNode> {
5571 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5573 asm, ".8h", ".8b", ".8b",
5574 [(set (v8i16 V128:$dst),
5575 (add (v8i16 V128:$Rd),
5576 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
5577 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5579 asm#"2", ".8h", ".16b", ".16b",
5580 [(set (v8i16 V128:$dst),
5581 (add (v8i16 V128:$Rd),
5582 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5583 (extract_high_v16i8 V128:$Rm))))))]>;
5584 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5586 asm, ".4s", ".4h", ".4h",
5587 [(set (v4i32 V128:$dst),
5588 (add (v4i32 V128:$Rd),
5589 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
5590 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5592 asm#"2", ".4s", ".8h", ".8h",
5593 [(set (v4i32 V128:$dst),
5594 (add (v4i32 V128:$Rd),
5595 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5596 (extract_high_v8i16 V128:$Rm))))))]>;
5597 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5599 asm, ".2d", ".2s", ".2s",
5600 [(set (v2i64 V128:$dst),
5601 (add (v2i64 V128:$Rd),
5602 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
5603 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5605 asm#"2", ".2d", ".4s", ".4s",
5606 [(set (v2i64 V128:$dst),
5607 (add (v2i64 V128:$Rd),
5608 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5609 (extract_high_v4i32 V128:$Rm))))))]>;
5612 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
5613 SDPatternOperator OpNode = null_frag> {
5614 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5616 asm, ".8h", ".8b", ".8b",
5617 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5618 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5620 asm#"2", ".8h", ".16b", ".16b",
5621 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
5622 (extract_high_v16i8 V128:$Rm)))]>;
5623 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5625 asm, ".4s", ".4h", ".4h",
5626 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5627 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5629 asm#"2", ".4s", ".8h", ".8h",
5630 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5631 (extract_high_v8i16 V128:$Rm)))]>;
5632 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5634 asm, ".2d", ".2s", ".2s",
5635 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5636 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5638 asm#"2", ".2d", ".4s", ".4s",
5639 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5640 (extract_high_v4i32 V128:$Rm)))]>;
5643 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
5645 SDPatternOperator OpNode> {
5646 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5648 asm, ".8h", ".8b", ".8b",
5649 [(set (v8i16 V128:$dst),
5650 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5651 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5653 asm#"2", ".8h", ".16b", ".16b",
5654 [(set (v8i16 V128:$dst),
5655 (OpNode (v8i16 V128:$Rd),
5656 (extract_high_v16i8 V128:$Rn),
5657 (extract_high_v16i8 V128:$Rm)))]>;
5658 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5660 asm, ".4s", ".4h", ".4h",
5661 [(set (v4i32 V128:$dst),
5662 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5663 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5665 asm#"2", ".4s", ".8h", ".8h",
5666 [(set (v4i32 V128:$dst),
5667 (OpNode (v4i32 V128:$Rd),
5668 (extract_high_v8i16 V128:$Rn),
5669 (extract_high_v8i16 V128:$Rm)))]>;
5670 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5672 asm, ".2d", ".2s", ".2s",
5673 [(set (v2i64 V128:$dst),
5674 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5675 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5677 asm#"2", ".2d", ".4s", ".4s",
5678 [(set (v2i64 V128:$dst),
5679 (OpNode (v2i64 V128:$Rd),
5680 (extract_high_v4i32 V128:$Rn),
5681 (extract_high_v4i32 V128:$Rm)))]>;
5684 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
5685 SDPatternOperator Accum> {
5686 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5688 asm, ".4s", ".4h", ".4h",
5689 [(set (v4i32 V128:$dst),
5690 (Accum (v4i32 V128:$Rd),
5691 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
5692 (v4i16 V64:$Rm)))))]>;
5693 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5695 asm#"2", ".4s", ".8h", ".8h",
5696 [(set (v4i32 V128:$dst),
5697 (Accum (v4i32 V128:$Rd),
5698 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
5699 (extract_high_v8i16 V128:$Rm)))))]>;
5700 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5702 asm, ".2d", ".2s", ".2s",
5703 [(set (v2i64 V128:$dst),
5704 (Accum (v2i64 V128:$Rd),
5705 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
5706 (v2i32 V64:$Rm)))))]>;
5707 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5709 asm#"2", ".2d", ".4s", ".4s",
5710 [(set (v2i64 V128:$dst),
5711 (Accum (v2i64 V128:$Rd),
5712 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
5713 (extract_high_v4i32 V128:$Rm)))))]>;
5716 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
5717 SDPatternOperator OpNode> {
5718 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5720 asm, ".8h", ".8h", ".8b",
5721 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
5722 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5724 asm#"2", ".8h", ".8h", ".16b",
5725 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
5726 (extract_high_v16i8 V128:$Rm)))]>;
5727 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5729 asm, ".4s", ".4s", ".4h",
5730 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
5731 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5733 asm#"2", ".4s", ".4s", ".8h",
5734 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
5735 (extract_high_v8i16 V128:$Rm)))]>;
5736 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5738 asm, ".2d", ".2d", ".2s",
5739 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
5740 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5742 asm#"2", ".2d", ".2d", ".4s",
5743 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
5744 (extract_high_v4i32 V128:$Rm)))]>;
5747 //----------------------------------------------------------------------------
5748 // AdvSIMD bitwise extract from vector
5749 //----------------------------------------------------------------------------
5751 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
5752 string asm, string kind>
5753 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
5754 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
5755 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
5756 [(set (vty regtype:$Rd),
5757 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
5764 let Inst{30} = size;
5765 let Inst{29-21} = 0b101110000;
5766 let Inst{20-16} = Rm;
5768 let Inst{14-11} = imm;
5775 multiclass SIMDBitwiseExtract<string asm> {
5776 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
5779 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
5782 //----------------------------------------------------------------------------
5783 // AdvSIMD zip vector
5784 //----------------------------------------------------------------------------
5786 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
5787 string asm, string kind, SDNode OpNode, ValueType valty>
5788 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5789 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5790 "|" # kind # "\t$Rd, $Rn, $Rm}", "",
5791 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
5797 let Inst{30} = size{0};
5798 let Inst{29-24} = 0b001110;
5799 let Inst{23-22} = size{2-1};
5801 let Inst{20-16} = Rm;
5803 let Inst{14-12} = opc;
5804 let Inst{11-10} = 0b10;
5809 multiclass SIMDZipVector<bits<3>opc, string asm,
5811 def v8i8 : BaseSIMDZipVector<0b000, opc, V64,
5812 asm, ".8b", OpNode, v8i8>;
5813 def v16i8 : BaseSIMDZipVector<0b001, opc, V128,
5814 asm, ".16b", OpNode, v16i8>;
5815 def v4i16 : BaseSIMDZipVector<0b010, opc, V64,
5816 asm, ".4h", OpNode, v4i16>;
5817 def v8i16 : BaseSIMDZipVector<0b011, opc, V128,
5818 asm, ".8h", OpNode, v8i16>;
5819 def v2i32 : BaseSIMDZipVector<0b100, opc, V64,
5820 asm, ".2s", OpNode, v2i32>;
5821 def v4i32 : BaseSIMDZipVector<0b101, opc, V128,
5822 asm, ".4s", OpNode, v4i32>;
5823 def v2i64 : BaseSIMDZipVector<0b111, opc, V128,
5824 asm, ".2d", OpNode, v2i64>;
5826 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
5827 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
5828 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
5829 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
5830 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
5831 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
5832 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
5833 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
5834 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
5835 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
5838 //----------------------------------------------------------------------------
5839 // AdvSIMD three register scalar instructions
5840 //----------------------------------------------------------------------------
5842 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5843 class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
5844 RegisterClass regtype, string asm,
5846 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5847 "\t$Rd, $Rn, $Rm", "", pattern>,
5852 let Inst{31-30} = 0b01;
5854 let Inst{28-24} = 0b11110;
5855 let Inst{23-21} = size;
5856 let Inst{20-16} = Rm;
5857 let Inst{15-11} = opcode;
5863 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5864 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
5865 dag oops, dag iops, string asm,
5867 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
5872 let Inst{31-30} = 0b01;
5874 let Inst{28-24} = 0b11110;
5875 let Inst{23-22} = size;
5877 let Inst{20-16} = Rm;
5878 let Inst{15-11} = opcode;
5884 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
5885 SDPatternOperator OpNode> {
5886 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
5887 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5890 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
5891 SDPatternOperator OpNode> {
5892 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
5893 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5894 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
5895 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
5896 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
5898 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
5899 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
5900 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
5901 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
5904 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
5905 SDPatternOperator OpNode> {
5906 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
5907 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5908 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
5911 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
5912 SDPatternOperator OpNode = null_frag> {
5913 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
5914 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
5916 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
5917 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
5921 multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
5922 SDPatternOperator OpNode = null_frag> {
5923 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5924 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
5925 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5926 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
5927 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5928 let Predicates = [HasNEON, HasFullFP16] in {
5929 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
5930 [(set FPR16:$Rd, (OpNode FPR16:$Rn, FPR16:$Rm))]>;
5931 } // Predicates = [HasNEON, HasFullFP16]
5934 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5935 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5938 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
5939 SDPatternOperator OpNode = null_frag> {
5940 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5941 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
5942 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5943 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
5944 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
5945 let Predicates = [HasNEON, HasFullFP16] in {
5946 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
5948 } // Predicates = [HasNEON, HasFullFP16]
5951 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5952 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5955 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
5956 dag oops, dag iops, string asm, string cstr, list<dag> pat>
5957 : I<oops, iops, asm,
5958 "\t$Rd, $Rn, $Rm", cstr, pat>,
5963 let Inst{31-30} = 0b01;
5965 let Inst{28-24} = 0b11110;
5966 let Inst{23-22} = size;
5968 let Inst{20-16} = Rm;
5969 let Inst{15-11} = opcode;
5975 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5976 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
5977 SDPatternOperator OpNode = null_frag> {
5978 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5980 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
5981 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5983 (ins FPR32:$Rn, FPR32:$Rm), asm, "",
5984 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5987 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5988 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
5989 SDPatternOperator OpNode = null_frag> {
5990 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5992 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
5993 asm, "$Rd = $dst", []>;
5994 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5996 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
5998 [(set (i64 FPR64:$dst),
5999 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
6002 //----------------------------------------------------------------------------
6003 // AdvSIMD two register scalar instructions
6004 //----------------------------------------------------------------------------
6006 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6007 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6008 RegisterClass regtype, RegisterClass regtype2,
6009 string asm, list<dag> pat>
6010 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
6011 "\t$Rd, $Rn", "", pat>,
6015 let Inst{31-30} = 0b01;
6017 let Inst{28-24} = 0b11110;
6018 let Inst{23-22} = size;
6020 let Inst{20-19} = size2;
6021 let Inst{18-17} = 0b00;
6022 let Inst{16-12} = opcode;
6023 let Inst{11-10} = 0b10;
6028 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6029 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
6030 RegisterClass regtype, RegisterClass regtype2,
6031 string asm, list<dag> pat>
6032 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
6033 "\t$Rd, $Rn", "$Rd = $dst", pat>,
6037 let Inst{31-30} = 0b01;
6039 let Inst{28-24} = 0b11110;
6040 let Inst{23-22} = size;
6041 let Inst{21-17} = 0b10000;
6042 let Inst{16-12} = opcode;
6043 let Inst{11-10} = 0b10;
6049 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6050 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
6051 RegisterClass regtype, string asm, string zero>
6052 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
6053 "\t$Rd, $Rn, #" # zero, "", []>,
6057 let Inst{31-30} = 0b01;
6059 let Inst{28-24} = 0b11110;
6060 let Inst{23-22} = size;
6062 let Inst{20-19} = size2;
6063 let Inst{18-17} = 0b00;
6064 let Inst{16-12} = opcode;
6065 let Inst{11-10} = 0b10;
6070 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
6071 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
6072 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
6076 let Inst{31-17} = 0b011111100110000;
6077 let Inst{16-12} = opcode;
6078 let Inst{11-10} = 0b10;
6083 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
6084 SDPatternOperator OpNode> {
6085 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
6087 def : Pat<(v1i64 (OpNode FPR64:$Rn)),
6088 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6091 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
6092 SDPatternOperator OpNode> {
6093 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
6094 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
6095 let Predicates = [HasNEON, HasFullFP16] in {
6096 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
6099 def : InstAlias<asm # "\t$Rd, $Rn, #0",
6100 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
6101 def : InstAlias<asm # "\t$Rd, $Rn, #0",
6102 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
6103 let Predicates = [HasNEON, HasFullFP16] in {
6104 def : InstAlias<asm # "\t$Rd, $Rn, #0",
6105 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
6108 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
6109 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
6112 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
6113 SDPatternOperator OpNode = null_frag> {
6114 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
6115 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
6117 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
6118 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
6121 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
6122 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
6123 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
6124 let Predicates = [HasNEON, HasFullFP16] in {
6125 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
6129 multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
6130 SDPatternOperator OpNode> {
6131 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
6132 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
6133 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
6134 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
6135 let Predicates = [HasNEON, HasFullFP16] in {
6136 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
6137 [(set FPR16:$Rd, (OpNode (f16 FPR16:$Rn)))]>;
6141 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
6142 SDPatternOperator OpNode = null_frag> {
6143 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6144 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
6145 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
6146 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
6147 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
6148 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
6149 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
6152 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
6153 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
6156 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
6158 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6159 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
6160 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
6161 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
6162 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
6163 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
6164 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
6167 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
6168 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
6173 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6174 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
6175 SDPatternOperator OpNode = null_frag> {
6176 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
6177 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
6178 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
6179 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
6182 //----------------------------------------------------------------------------
6183 // AdvSIMD scalar pairwise instructions
6184 //----------------------------------------------------------------------------
6186 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6187 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
6188 RegisterOperand regtype, RegisterOperand vectype,
6189 string asm, string kind>
6190 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6191 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
6195 let Inst{31-30} = 0b01;
6197 let Inst{28-24} = 0b11110;
6198 let Inst{23-22} = size;
6199 let Inst{21-17} = 0b11000;
6200 let Inst{16-12} = opcode;
6201 let Inst{11-10} = 0b10;
6206 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
6207 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
6211 multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
6212 let Predicates = [HasNEON, HasFullFP16] in {
6213 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
6216 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
6218 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
6222 //----------------------------------------------------------------------------
6223 // AdvSIMD across lanes instructions
6224 //----------------------------------------------------------------------------
6226 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6227 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
6228 RegisterClass regtype, RegisterOperand vectype,
6229 string asm, string kind, list<dag> pattern>
6230 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6231 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
6238 let Inst{28-24} = 0b01110;
6239 let Inst{23-22} = size;
6240 let Inst{21-17} = 0b11000;
6241 let Inst{16-12} = opcode;
6242 let Inst{11-10} = 0b10;
6247 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
6249 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
6251 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
6253 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
6255 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
6257 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
6261 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
6262 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
6264 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
6266 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
6268 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
6270 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
6274 multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
6276 let Predicates = [HasNEON, HasFullFP16] in {
6277 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
6279 [(set FPR16:$Rd, (intOp (v4f16 V64:$Rn)))]>;
6280 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
6282 [(set FPR16:$Rd, (intOp (v8f16 V128:$Rn)))]>;
6283 } // Predicates = [HasNEON, HasFullFP16]
6284 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
6286 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
6289 //----------------------------------------------------------------------------
6290 // AdvSIMD INS/DUP instructions
6291 //----------------------------------------------------------------------------
6293 // FIXME: There has got to be a better way to factor these. ugh.
6295 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
6296 string operands, string constraints, list<dag> pattern>
6297 : I<outs, ins, asm, operands, constraints, pattern>,
6304 let Inst{28-21} = 0b01110000;
6311 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
6312 RegisterOperand vecreg, RegisterClass regtype>
6313 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
6314 "{\t$Rd" # size # ", $Rn" #
6315 "|" # size # "\t$Rd, $Rn}", "",
6316 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
6317 let Inst{20-16} = imm5;
6318 let Inst{14-11} = 0b0001;
6321 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
6322 ValueType vectype, ValueType insreg,
6323 RegisterOperand vecreg, Operand idxtype,
6324 ValueType elttype, SDNode OpNode>
6325 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
6326 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
6327 "|" # dstkind # "\t$Rd, $Rn$idx}", "",
6328 [(set (vectype vecreg:$Rd),
6329 (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
6330 let Inst{14-11} = 0b0000;
6333 class SIMDDup64FromElement
6334 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
6335 VectorIndexD, i64, AArch64duplane64> {
6338 let Inst{19-16} = 0b1000;
6341 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
6342 RegisterOperand vecreg>
6343 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
6344 VectorIndexS, i64, AArch64duplane32> {
6346 let Inst{20-19} = idx;
6347 let Inst{18-16} = 0b100;
6350 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
6351 RegisterOperand vecreg>
6352 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
6353 VectorIndexH, i64, AArch64duplane16> {
6355 let Inst{20-18} = idx;
6356 let Inst{17-16} = 0b10;
6359 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
6360 RegisterOperand vecreg>
6361 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
6362 VectorIndexB, i64, AArch64duplane8> {
6364 let Inst{20-17} = idx;
6368 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
6369 Operand idxtype, string asm, list<dag> pattern>
6370 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
6371 "{\t$Rd, $Rn" # size # "$idx" #
6372 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
6373 let Inst{14-11} = imm4;
6376 class SIMDSMov<bit Q, string size, RegisterClass regtype,
6378 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
6379 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
6381 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
6382 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
6384 class SIMDMovAlias<string asm, string size, Instruction inst,
6385 RegisterClass regtype, Operand idxtype>
6386 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
6387 "|" # size # "\t$dst, $src$idx}",
6388 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
6391 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
6393 let Inst{20-17} = idx;
6396 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
6398 let Inst{20-17} = idx;
6401 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
6403 let Inst{20-18} = idx;
6404 let Inst{17-16} = 0b10;
6406 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
6408 let Inst{20-18} = idx;
6409 let Inst{17-16} = 0b10;
6411 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
6413 let Inst{20-19} = idx;
6414 let Inst{18-16} = 0b100;
6419 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
6421 let Inst{20-17} = idx;
6424 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
6426 let Inst{20-18} = idx;
6427 let Inst{17-16} = 0b10;
6429 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
6431 let Inst{20-19} = idx;
6432 let Inst{18-16} = 0b100;
6434 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
6437 let Inst{19-16} = 0b1000;
6439 def : SIMDMovAlias<"mov", ".s",
6440 !cast<Instruction>(NAME#"vi32"),
6441 GPR32, VectorIndexS>;
6442 def : SIMDMovAlias<"mov", ".d",
6443 !cast<Instruction>(NAME#"vi64"),
6444 GPR64, VectorIndexD>;
6447 class SIMDInsFromMain<string size, ValueType vectype,
6448 RegisterClass regtype, Operand idxtype>
6449 : BaseSIMDInsDup<1, 0, (outs V128:$dst),
6450 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
6451 "{\t$Rd" # size # "$idx, $Rn" #
6452 "|" # size # "\t$Rd$idx, $Rn}",
6455 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
6456 let Inst{14-11} = 0b0011;
6459 class SIMDInsFromElement<string size, ValueType vectype,
6460 ValueType elttype, Operand idxtype>
6461 : BaseSIMDInsDup<1, 1, (outs V128:$dst),
6462 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
6463 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
6464 "|" # size # "\t$Rd$idx, $Rn$idx2}",
6469 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
6472 class SIMDInsMainMovAlias<string size, Instruction inst,
6473 RegisterClass regtype, Operand idxtype>
6474 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
6475 "|" # size #"\t$dst$idx, $src}",
6476 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
6477 class SIMDInsElementMovAlias<string size, Instruction inst,
6479 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
6480 # "|" # size #"\t$dst$idx, $src$idx2}",
6481 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
6484 multiclass SIMDIns {
6485 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
6487 let Inst{20-17} = idx;
6490 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
6492 let Inst{20-18} = idx;
6493 let Inst{17-16} = 0b10;
6495 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
6497 let Inst{20-19} = idx;
6498 let Inst{18-16} = 0b100;
6500 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
6503 let Inst{19-16} = 0b1000;
6506 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
6509 let Inst{20-17} = idx;
6511 let Inst{14-11} = idx2;
6513 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
6516 let Inst{20-18} = idx;
6517 let Inst{17-16} = 0b10;
6518 let Inst{14-12} = idx2;
6521 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
6524 let Inst{20-19} = idx;
6525 let Inst{18-16} = 0b100;
6526 let Inst{14-13} = idx2;
6527 let Inst{12-11} = {?,?};
6529 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
6533 let Inst{19-16} = 0b1000;
6534 let Inst{14} = idx2;
6535 let Inst{13-11} = {?,?,?};
6538 // For all forms of the INS instruction, the "mov" mnemonic is the
6539 // preferred alias. Why they didn't just call the instruction "mov" in
6540 // the first place is a very good question indeed...
6541 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
6542 GPR32, VectorIndexB>;
6543 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
6544 GPR32, VectorIndexH>;
6545 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
6546 GPR32, VectorIndexS>;
6547 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
6548 GPR64, VectorIndexD>;
6550 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
6552 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
6554 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
6556 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
6560 //----------------------------------------------------------------------------
6562 //----------------------------------------------------------------------------
6564 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6565 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6566 RegisterOperand listtype, string asm, string kind>
6567 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
6568 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
6575 let Inst{29-21} = 0b001110000;
6576 let Inst{20-16} = Vm;
6578 let Inst{14-13} = len;
6580 let Inst{11-10} = 0b00;
6585 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6586 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6587 RegisterOperand listtype, string asm, string kind>
6588 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
6589 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
6596 let Inst{29-21} = 0b001110000;
6597 let Inst{20-16} = Vm;
6599 let Inst{14-13} = len;
6601 let Inst{11-10} = 0b00;
6606 class SIMDTableLookupAlias<string asm, Instruction inst,
6607 RegisterOperand vectype, RegisterOperand listtype>
6608 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
6609 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
6611 multiclass SIMDTableLookup<bit op, string asm> {
6612 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
6614 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
6616 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
6618 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
6620 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
6622 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
6624 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
6626 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
6629 def : SIMDTableLookupAlias<asm # ".8b",
6630 !cast<Instruction>(NAME#"v8i8One"),
6631 V64, VecListOne128>;
6632 def : SIMDTableLookupAlias<asm # ".8b",
6633 !cast<Instruction>(NAME#"v8i8Two"),
6634 V64, VecListTwo128>;
6635 def : SIMDTableLookupAlias<asm # ".8b",
6636 !cast<Instruction>(NAME#"v8i8Three"),
6637 V64, VecListThree128>;
6638 def : SIMDTableLookupAlias<asm # ".8b",
6639 !cast<Instruction>(NAME#"v8i8Four"),
6640 V64, VecListFour128>;
6641 def : SIMDTableLookupAlias<asm # ".16b",
6642 !cast<Instruction>(NAME#"v16i8One"),
6643 V128, VecListOne128>;
6644 def : SIMDTableLookupAlias<asm # ".16b",
6645 !cast<Instruction>(NAME#"v16i8Two"),
6646 V128, VecListTwo128>;
6647 def : SIMDTableLookupAlias<asm # ".16b",
6648 !cast<Instruction>(NAME#"v16i8Three"),
6649 V128, VecListThree128>;
6650 def : SIMDTableLookupAlias<asm # ".16b",
6651 !cast<Instruction>(NAME#"v16i8Four"),
6652 V128, VecListFour128>;
6655 multiclass SIMDTableLookupTied<bit op, string asm> {
6656 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
6658 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
6660 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
6662 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
6664 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
6666 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
6668 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
6670 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
6673 def : SIMDTableLookupAlias<asm # ".8b",
6674 !cast<Instruction>(NAME#"v8i8One"),
6675 V64, VecListOne128>;
6676 def : SIMDTableLookupAlias<asm # ".8b",
6677 !cast<Instruction>(NAME#"v8i8Two"),
6678 V64, VecListTwo128>;
6679 def : SIMDTableLookupAlias<asm # ".8b",
6680 !cast<Instruction>(NAME#"v8i8Three"),
6681 V64, VecListThree128>;
6682 def : SIMDTableLookupAlias<asm # ".8b",
6683 !cast<Instruction>(NAME#"v8i8Four"),
6684 V64, VecListFour128>;
6685 def : SIMDTableLookupAlias<asm # ".16b",
6686 !cast<Instruction>(NAME#"v16i8One"),
6687 V128, VecListOne128>;
6688 def : SIMDTableLookupAlias<asm # ".16b",
6689 !cast<Instruction>(NAME#"v16i8Two"),
6690 V128, VecListTwo128>;
6691 def : SIMDTableLookupAlias<asm # ".16b",
6692 !cast<Instruction>(NAME#"v16i8Three"),
6693 V128, VecListThree128>;
6694 def : SIMDTableLookupAlias<asm # ".16b",
6695 !cast<Instruction>(NAME#"v16i8Four"),
6696 V128, VecListFour128>;
6700 //----------------------------------------------------------------------------
6701 // AdvSIMD scalar CPY
6702 //----------------------------------------------------------------------------
6703 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6704 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
6705 string kind, Operand idxtype>
6706 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
6707 "{\t$dst, $src" # kind # "$idx" #
6708 "|\t$dst, $src$idx}", "", []>,
6712 let Inst{31-21} = 0b01011110000;
6713 let Inst{15-10} = 0b000001;
6714 let Inst{9-5} = src;
6715 let Inst{4-0} = dst;
6718 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
6719 RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
6720 : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
6721 # "|\t$dst, $src$index}",
6722 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
6725 multiclass SIMDScalarCPY<string asm> {
6726 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> {
6728 let Inst{20-17} = idx;
6731 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
6733 let Inst{20-18} = idx;
6734 let Inst{17-16} = 0b10;
6736 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
6738 let Inst{20-19} = idx;
6739 let Inst{18-16} = 0b100;
6741 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
6744 let Inst{19-16} = 0b1000;
6747 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
6748 VectorIndexD:$idx)))),
6749 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
6751 // 'DUP' mnemonic aliases.
6752 def : SIMDScalarCPYAlias<"dup", ".b",
6753 !cast<Instruction>(NAME#"i8"),
6754 FPR8, V128, VectorIndexB>;
6755 def : SIMDScalarCPYAlias<"dup", ".h",
6756 !cast<Instruction>(NAME#"i16"),
6757 FPR16, V128, VectorIndexH>;
6758 def : SIMDScalarCPYAlias<"dup", ".s",
6759 !cast<Instruction>(NAME#"i32"),
6760 FPR32, V128, VectorIndexS>;
6761 def : SIMDScalarCPYAlias<"dup", ".d",
6762 !cast<Instruction>(NAME#"i64"),
6763 FPR64, V128, VectorIndexD>;
6766 //----------------------------------------------------------------------------
6767 // AdvSIMD modified immediate instructions
6768 //----------------------------------------------------------------------------
6770 class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
6771 string asm, string op_string,
6772 string cstr, list<dag> pattern>
6773 : I<oops, iops, asm, op_string, cstr, pattern>,
6780 let Inst{28-19} = 0b0111100000;
6781 let Inst{18-16} = imm8{7-5};
6784 let Inst{9-5} = imm8{4-0};
6788 class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
6789 Operand immtype, dag opt_shift_iop,
6790 string opt_shift, string asm, string kind,
6792 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
6793 !con((ins immtype:$imm8), opt_shift_iop), asm,
6794 "{\t$Rd" # kind # ", $imm8" # opt_shift #
6795 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6797 let DecoderMethod = "DecodeModImmInstruction";
6800 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
6801 Operand immtype, dag opt_shift_iop,
6802 string opt_shift, string asm, string kind,
6804 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
6805 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
6806 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
6807 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6808 "$Rd = $dst", pattern> {
6809 let DecoderMethod = "DecodeModImmTiedInstruction";
6812 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
6813 RegisterOperand vectype, string asm,
6814 string kind, list<dag> pattern>
6815 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
6816 (ins logical_vec_shift:$shift),
6817 "$shift", asm, kind, pattern> {
6819 let Inst{15} = b15_b12{1};
6820 let Inst{14-13} = shift;
6821 let Inst{12} = b15_b12{0};
6824 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
6825 RegisterOperand vectype, string asm,
6826 string kind, list<dag> pattern>
6827 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6828 (ins logical_vec_shift:$shift),
6829 "$shift", asm, kind, pattern> {
6831 let Inst{15} = b15_b12{1};
6832 let Inst{14-13} = shift;
6833 let Inst{12} = b15_b12{0};
6837 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
6838 RegisterOperand vectype, string asm,
6839 string kind, list<dag> pattern>
6840 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
6841 (ins logical_vec_hw_shift:$shift),
6842 "$shift", asm, kind, pattern> {
6844 let Inst{15} = b15_b12{1};
6846 let Inst{13} = shift{0};
6847 let Inst{12} = b15_b12{0};
6850 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
6851 RegisterOperand vectype, string asm,
6852 string kind, list<dag> pattern>
6853 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6854 (ins logical_vec_hw_shift:$shift),
6855 "$shift", asm, kind, pattern> {
6857 let Inst{15} = b15_b12{1};
6859 let Inst{13} = shift{0};
6860 let Inst{12} = b15_b12{0};
6863 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
6865 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
6867 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
6870 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
6872 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
6876 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
6877 bits<2> w_cmode, string asm,
6879 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
6881 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
6883 (i32 imm:$shift)))]>;
6884 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
6886 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
6888 (i32 imm:$shift)))]>;
6890 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
6892 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
6894 (i32 imm:$shift)))]>;
6895 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
6897 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
6899 (i32 imm:$shift)))]>;
6902 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
6903 RegisterOperand vectype, string asm,
6904 string kind, list<dag> pattern>
6905 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
6906 (ins move_vec_shift:$shift),
6907 "$shift", asm, kind, pattern> {
6909 let Inst{15-13} = cmode{3-1};
6910 let Inst{12} = shift;
6913 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
6914 RegisterOperand vectype,
6915 Operand imm_type, string asm,
6916 string kind, list<dag> pattern>
6917 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
6918 asm, kind, pattern> {
6919 let Inst{15-12} = cmode;
6922 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
6924 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
6925 "\t$Rd, $imm8", "", pattern> {
6926 let Inst{15-12} = cmode;
6927 let DecoderMethod = "DecodeModImmInstruction";
6930 //----------------------------------------------------------------------------
6931 // AdvSIMD indexed element
6932 //----------------------------------------------------------------------------
6934 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6935 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6936 RegisterOperand dst_reg, RegisterOperand lhs_reg,
6937 RegisterOperand rhs_reg, Operand vec_idx, string asm,
6938 string apple_kind, string dst_kind, string lhs_kind,
6939 string rhs_kind, list<dag> pattern>
6940 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
6942 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6943 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
6952 let Inst{28} = Scalar;
6953 let Inst{27-24} = 0b1111;
6954 let Inst{23-22} = size;
6955 // Bit 21 must be set by the derived class.
6956 let Inst{20-16} = Rm;
6957 let Inst{15-12} = opc;
6958 // Bit 11 must be set by the derived class.
6964 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6965 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6966 RegisterOperand dst_reg, RegisterOperand lhs_reg,
6967 RegisterOperand rhs_reg, Operand vec_idx, string asm,
6968 string apple_kind, string dst_kind, string lhs_kind,
6969 string rhs_kind, list<dag> pattern>
6970 : I<(outs dst_reg:$dst),
6971 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
6972 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6973 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
6982 let Inst{28} = Scalar;
6983 let Inst{27-24} = 0b1111;
6984 let Inst{23-22} = size;
6985 // Bit 21 must be set by the derived class.
6986 let Inst{20-16} = Rm;
6987 let Inst{15-12} = opc;
6988 // Bit 11 must be set by the derived class.
6994 // ARMv8.2 Index Dot product instructions
6995 class BaseSIMDThreeSameVectorDotIndex<bit Q, bit U, string asm, string dst_kind,
6996 string lhs_kind, string rhs_kind> :
6997 BaseSIMDIndexedTied<Q, U, 0b0, 0b10, 0b1110, V128, V128, V128, VectorIndexS,
6998 asm, "", dst_kind, lhs_kind, rhs_kind, []> {
7000 let Inst{21} = idx{0}; // L
7001 let Inst{11} = idx{1}; // H
7004 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
7005 SDPatternOperator OpNode> {
7006 let Predicates = [HasNEON, HasFullFP16] in {
7007 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
7009 V128_lo, VectorIndexH,
7010 asm, ".4h", ".4h", ".4h", ".h",
7011 [(set (v4f16 V64:$Rd),
7012 (OpNode (v4f16 V64:$Rn),
7013 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7015 let Inst{11} = idx{2};
7016 let Inst{21} = idx{1};
7017 let Inst{20} = idx{0};
7020 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
7022 V128_lo, VectorIndexH,
7023 asm, ".8h", ".8h", ".8h", ".h",
7024 [(set (v8f16 V128:$Rd),
7025 (OpNode (v8f16 V128:$Rn),
7026 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7028 let Inst{11} = idx{2};
7029 let Inst{21} = idx{1};
7030 let Inst{20} = idx{0};
7032 } // Predicates = [HasNEON, HasFullFP16]
7034 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7037 asm, ".2s", ".2s", ".2s", ".s",
7038 [(set (v2f32 V64:$Rd),
7039 (OpNode (v2f32 V64:$Rn),
7040 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
7042 let Inst{11} = idx{1};
7043 let Inst{21} = idx{0};
7046 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7049 asm, ".4s", ".4s", ".4s", ".s",
7050 [(set (v4f32 V128:$Rd),
7051 (OpNode (v4f32 V128:$Rn),
7052 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
7054 let Inst{11} = idx{1};
7055 let Inst{21} = idx{0};
7058 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
7061 asm, ".2d", ".2d", ".2d", ".d",
7062 [(set (v2f64 V128:$Rd),
7063 (OpNode (v2f64 V128:$Rn),
7064 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
7066 let Inst{11} = idx{0};
7070 let Predicates = [HasNEON, HasFullFP16] in {
7071 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
7072 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7073 asm, ".h", "", "", ".h",
7074 [(set (f16 FPR16Op:$Rd),
7075 (OpNode (f16 FPR16Op:$Rn),
7076 (f16 (vector_extract (v8f16 V128_lo:$Rm),
7077 VectorIndexH:$idx))))]> {
7079 let Inst{11} = idx{2};
7080 let Inst{21} = idx{1};
7081 let Inst{20} = idx{0};
7083 } // Predicates = [HasNEON, HasFullFP16]
7085 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7086 FPR32Op, FPR32Op, V128, VectorIndexS,
7087 asm, ".s", "", "", ".s",
7088 [(set (f32 FPR32Op:$Rd),
7089 (OpNode (f32 FPR32Op:$Rn),
7090 (f32 (vector_extract (v4f32 V128:$Rm),
7091 VectorIndexS:$idx))))]> {
7093 let Inst{11} = idx{1};
7094 let Inst{21} = idx{0};
7097 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
7098 FPR64Op, FPR64Op, V128, VectorIndexD,
7099 asm, ".d", "", "", ".d",
7100 [(set (f64 FPR64Op:$Rd),
7101 (OpNode (f64 FPR64Op:$Rn),
7102 (f64 (vector_extract (v2f64 V128:$Rm),
7103 VectorIndexD:$idx))))]> {
7105 let Inst{11} = idx{0};
7110 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
7111 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
7112 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
7113 (AArch64duplane32 (v4f32 V128:$Rm),
7114 VectorIndexS:$idx))),
7115 (!cast<Instruction>(INST # v2i32_indexed)
7116 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7117 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
7118 (AArch64dup (f32 FPR32Op:$Rm)))),
7119 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
7120 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
7123 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
7124 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
7125 (AArch64duplane32 (v4f32 V128:$Rm),
7126 VectorIndexS:$idx))),
7127 (!cast<Instruction>(INST # "v4i32_indexed")
7128 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7129 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
7130 (AArch64dup (f32 FPR32Op:$Rm)))),
7131 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
7132 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
7134 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
7135 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
7136 (AArch64duplane64 (v2f64 V128:$Rm),
7137 VectorIndexD:$idx))),
7138 (!cast<Instruction>(INST # "v2i64_indexed")
7139 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
7140 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
7141 (AArch64dup (f64 FPR64Op:$Rm)))),
7142 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
7143 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
7145 // 2 variants for 32-bit scalar version: extract from .2s or from .4s
7146 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
7147 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
7148 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
7149 V128:$Rm, VectorIndexS:$idx)>;
7150 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
7151 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
7152 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
7153 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
7155 // 1 variant for 64-bit scalar version: extract from .1d or from .2d
7156 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
7157 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
7158 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
7159 V128:$Rm, VectorIndexD:$idx)>;
7162 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
7163 let Predicates = [HasNEON, HasFullFP16] in {
7164 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
7165 V128_lo, VectorIndexH,
7166 asm, ".4h", ".4h", ".4h", ".h", []> {
7168 let Inst{11} = idx{2};
7169 let Inst{21} = idx{1};
7170 let Inst{20} = idx{0};
7173 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
7175 V128_lo, VectorIndexH,
7176 asm, ".8h", ".8h", ".8h", ".h", []> {
7178 let Inst{11} = idx{2};
7179 let Inst{21} = idx{1};
7180 let Inst{20} = idx{0};
7182 } // Predicates = [HasNEON, HasFullFP16]
7184 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
7186 asm, ".2s", ".2s", ".2s", ".s", []> {
7188 let Inst{11} = idx{1};
7189 let Inst{21} = idx{0};
7192 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7195 asm, ".4s", ".4s", ".4s", ".s", []> {
7197 let Inst{11} = idx{1};
7198 let Inst{21} = idx{0};
7201 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
7204 asm, ".2d", ".2d", ".2d", ".d", []> {
7206 let Inst{11} = idx{0};
7210 let Predicates = [HasNEON, HasFullFP16] in {
7211 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
7212 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7213 asm, ".h", "", "", ".h", []> {
7215 let Inst{11} = idx{2};
7216 let Inst{21} = idx{1};
7217 let Inst{20} = idx{0};
7219 } // Predicates = [HasNEON, HasFullFP16]
7221 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7222 FPR32Op, FPR32Op, V128, VectorIndexS,
7223 asm, ".s", "", "", ".s", []> {
7225 let Inst{11} = idx{1};
7226 let Inst{21} = idx{0};
7229 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
7230 FPR64Op, FPR64Op, V128, VectorIndexD,
7231 asm, ".d", "", "", ".d", []> {
7233 let Inst{11} = idx{0};
7238 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
7239 SDPatternOperator OpNode> {
7240 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
7241 V128_lo, VectorIndexH,
7242 asm, ".4h", ".4h", ".4h", ".h",
7243 [(set (v4i16 V64:$Rd),
7244 (OpNode (v4i16 V64:$Rn),
7245 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7247 let Inst{11} = idx{2};
7248 let Inst{21} = idx{1};
7249 let Inst{20} = idx{0};
7252 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7254 V128_lo, VectorIndexH,
7255 asm, ".8h", ".8h", ".8h", ".h",
7256 [(set (v8i16 V128:$Rd),
7257 (OpNode (v8i16 V128:$Rn),
7258 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7260 let Inst{11} = idx{2};
7261 let Inst{21} = idx{1};
7262 let Inst{20} = idx{0};
7265 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7268 asm, ".2s", ".2s", ".2s", ".s",
7269 [(set (v2i32 V64:$Rd),
7270 (OpNode (v2i32 V64:$Rn),
7271 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7273 let Inst{11} = idx{1};
7274 let Inst{21} = idx{0};
7277 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7280 asm, ".4s", ".4s", ".4s", ".s",
7281 [(set (v4i32 V128:$Rd),
7282 (OpNode (v4i32 V128:$Rn),
7283 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7285 let Inst{11} = idx{1};
7286 let Inst{21} = idx{0};
7289 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7290 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7291 asm, ".h", "", "", ".h", []> {
7293 let Inst{11} = idx{2};
7294 let Inst{21} = idx{1};
7295 let Inst{20} = idx{0};
7298 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7299 FPR32Op, FPR32Op, V128, VectorIndexS,
7300 asm, ".s", "", "", ".s",
7301 [(set (i32 FPR32Op:$Rd),
7302 (OpNode FPR32Op:$Rn,
7303 (i32 (vector_extract (v4i32 V128:$Rm),
7304 VectorIndexS:$idx))))]> {
7306 let Inst{11} = idx{1};
7307 let Inst{21} = idx{0};
7311 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
7312 SDPatternOperator OpNode> {
7313 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7315 V128_lo, VectorIndexH,
7316 asm, ".4h", ".4h", ".4h", ".h",
7317 [(set (v4i16 V64:$Rd),
7318 (OpNode (v4i16 V64:$Rn),
7319 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7321 let Inst{11} = idx{2};
7322 let Inst{21} = idx{1};
7323 let Inst{20} = idx{0};
7326 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7328 V128_lo, VectorIndexH,
7329 asm, ".8h", ".8h", ".8h", ".h",
7330 [(set (v8i16 V128:$Rd),
7331 (OpNode (v8i16 V128:$Rn),
7332 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7334 let Inst{11} = idx{2};
7335 let Inst{21} = idx{1};
7336 let Inst{20} = idx{0};
7339 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7342 asm, ".2s", ".2s", ".2s", ".s",
7343 [(set (v2i32 V64:$Rd),
7344 (OpNode (v2i32 V64:$Rn),
7345 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7347 let Inst{11} = idx{1};
7348 let Inst{21} = idx{0};
7351 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7354 asm, ".4s", ".4s", ".4s", ".s",
7355 [(set (v4i32 V128:$Rd),
7356 (OpNode (v4i32 V128:$Rn),
7357 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7359 let Inst{11} = idx{1};
7360 let Inst{21} = idx{0};
7364 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
7365 SDPatternOperator OpNode> {
7366 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
7367 V128_lo, VectorIndexH,
7368 asm, ".4h", ".4h", ".4h", ".h",
7369 [(set (v4i16 V64:$dst),
7370 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
7371 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7373 let Inst{11} = idx{2};
7374 let Inst{21} = idx{1};
7375 let Inst{20} = idx{0};
7378 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7380 V128_lo, VectorIndexH,
7381 asm, ".8h", ".8h", ".8h", ".h",
7382 [(set (v8i16 V128:$dst),
7383 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7384 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7386 let Inst{11} = idx{2};
7387 let Inst{21} = idx{1};
7388 let Inst{20} = idx{0};
7391 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7394 asm, ".2s", ".2s", ".2s", ".s",
7395 [(set (v2i32 V64:$dst),
7396 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7397 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7399 let Inst{11} = idx{1};
7400 let Inst{21} = idx{0};
7403 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7406 asm, ".4s", ".4s", ".4s", ".s",
7407 [(set (v4i32 V128:$dst),
7408 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7409 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7411 let Inst{11} = idx{1};
7412 let Inst{21} = idx{0};
7416 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
7417 SDPatternOperator OpNode> {
7418 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7420 V128_lo, VectorIndexH,
7421 asm, ".4s", ".4s", ".4h", ".h",
7422 [(set (v4i32 V128:$Rd),
7423 (OpNode (v4i16 V64:$Rn),
7424 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7426 let Inst{11} = idx{2};
7427 let Inst{21} = idx{1};
7428 let Inst{20} = idx{0};
7431 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7433 V128_lo, VectorIndexH,
7434 asm#"2", ".4s", ".4s", ".8h", ".h",
7435 [(set (v4i32 V128:$Rd),
7436 (OpNode (extract_high_v8i16 V128:$Rn),
7437 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7438 VectorIndexH:$idx))))]> {
7441 let Inst{11} = idx{2};
7442 let Inst{21} = idx{1};
7443 let Inst{20} = idx{0};
7446 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7449 asm, ".2d", ".2d", ".2s", ".s",
7450 [(set (v2i64 V128:$Rd),
7451 (OpNode (v2i32 V64:$Rn),
7452 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7454 let Inst{11} = idx{1};
7455 let Inst{21} = idx{0};
7458 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7461 asm#"2", ".2d", ".2d", ".4s", ".s",
7462 [(set (v2i64 V128:$Rd),
7463 (OpNode (extract_high_v4i32 V128:$Rn),
7464 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7465 VectorIndexS:$idx))))]> {
7467 let Inst{11} = idx{1};
7468 let Inst{21} = idx{0};
7471 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7472 FPR32Op, 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};
7480 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7481 FPR64Op, FPR32Op, V128, VectorIndexS,
7482 asm, ".s", "", "", ".s", []> {
7484 let Inst{11} = idx{1};
7485 let Inst{21} = idx{0};
7489 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
7490 SDPatternOperator Accum> {
7491 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7493 V128_lo, VectorIndexH,
7494 asm, ".4s", ".4s", ".4h", ".h",
7495 [(set (v4i32 V128:$dst),
7496 (Accum (v4i32 V128:$Rd),
7497 (v4i32 (int_aarch64_neon_sqdmull
7499 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7500 VectorIndexH:$idx))))))]> {
7502 let Inst{11} = idx{2};
7503 let Inst{21} = idx{1};
7504 let Inst{20} = idx{0};
7507 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
7508 // intermediate EXTRACT_SUBREG would be untyped.
7509 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
7510 (i32 (vector_extract (v4i32
7511 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
7512 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7513 VectorIndexH:$idx)))),
7516 (!cast<Instruction>(NAME # v4i16_indexed)
7517 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
7518 V128_lo:$Rm, VectorIndexH:$idx),
7521 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7523 V128_lo, VectorIndexH,
7524 asm#"2", ".4s", ".4s", ".8h", ".h",
7525 [(set (v4i32 V128:$dst),
7526 (Accum (v4i32 V128:$Rd),
7527 (v4i32 (int_aarch64_neon_sqdmull
7528 (extract_high_v8i16 V128:$Rn),
7530 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7531 VectorIndexH:$idx))))))]> {
7533 let Inst{11} = idx{2};
7534 let Inst{21} = idx{1};
7535 let Inst{20} = idx{0};
7538 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7541 asm, ".2d", ".2d", ".2s", ".s",
7542 [(set (v2i64 V128:$dst),
7543 (Accum (v2i64 V128:$Rd),
7544 (v2i64 (int_aarch64_neon_sqdmull
7546 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
7547 VectorIndexS:$idx))))))]> {
7549 let Inst{11} = idx{1};
7550 let Inst{21} = idx{0};
7553 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7556 asm#"2", ".2d", ".2d", ".4s", ".s",
7557 [(set (v2i64 V128:$dst),
7558 (Accum (v2i64 V128:$Rd),
7559 (v2i64 (int_aarch64_neon_sqdmull
7560 (extract_high_v4i32 V128:$Rn),
7562 (AArch64duplane32 (v4i32 V128:$Rm),
7563 VectorIndexS:$idx))))))]> {
7565 let Inst{11} = idx{1};
7566 let Inst{21} = idx{0};
7569 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
7570 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7571 asm, ".h", "", "", ".h", []> {
7573 let Inst{11} = idx{2};
7574 let Inst{21} = idx{1};
7575 let Inst{20} = idx{0};
7579 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7580 FPR64Op, FPR32Op, V128, VectorIndexS,
7581 asm, ".s", "", "", ".s",
7582 [(set (i64 FPR64Op:$dst),
7583 (Accum (i64 FPR64Op:$Rd),
7584 (i64 (int_aarch64_neon_sqdmulls_scalar
7586 (i32 (vector_extract (v4i32 V128:$Rm),
7587 VectorIndexS:$idx))))))]> {
7590 let Inst{11} = idx{1};
7591 let Inst{21} = idx{0};
7595 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
7596 SDPatternOperator OpNode> {
7597 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7598 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7600 V128_lo, VectorIndexH,
7601 asm, ".4s", ".4s", ".4h", ".h",
7602 [(set (v4i32 V128:$Rd),
7603 (OpNode (v4i16 V64:$Rn),
7604 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7606 let Inst{11} = idx{2};
7607 let Inst{21} = idx{1};
7608 let Inst{20} = idx{0};
7611 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7613 V128_lo, VectorIndexH,
7614 asm#"2", ".4s", ".4s", ".8h", ".h",
7615 [(set (v4i32 V128:$Rd),
7616 (OpNode (extract_high_v8i16 V128:$Rn),
7617 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7618 VectorIndexH:$idx))))]> {
7621 let Inst{11} = idx{2};
7622 let Inst{21} = idx{1};
7623 let Inst{20} = idx{0};
7626 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7629 asm, ".2d", ".2d", ".2s", ".s",
7630 [(set (v2i64 V128:$Rd),
7631 (OpNode (v2i32 V64:$Rn),
7632 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7634 let Inst{11} = idx{1};
7635 let Inst{21} = idx{0};
7638 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7641 asm#"2", ".2d", ".2d", ".4s", ".s",
7642 [(set (v2i64 V128:$Rd),
7643 (OpNode (extract_high_v4i32 V128:$Rn),
7644 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7645 VectorIndexS:$idx))))]> {
7647 let Inst{11} = idx{1};
7648 let Inst{21} = idx{0};
7653 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
7654 SDPatternOperator OpNode> {
7655 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7656 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7658 V128_lo, VectorIndexH,
7659 asm, ".4s", ".4s", ".4h", ".h",
7660 [(set (v4i32 V128:$dst),
7661 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
7662 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7664 let Inst{11} = idx{2};
7665 let Inst{21} = idx{1};
7666 let Inst{20} = idx{0};
7669 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7671 V128_lo, VectorIndexH,
7672 asm#"2", ".4s", ".4s", ".8h", ".h",
7673 [(set (v4i32 V128:$dst),
7674 (OpNode (v4i32 V128:$Rd),
7675 (extract_high_v8i16 V128:$Rn),
7676 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7677 VectorIndexH:$idx))))]> {
7679 let Inst{11} = idx{2};
7680 let Inst{21} = idx{1};
7681 let Inst{20} = idx{0};
7684 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7687 asm, ".2d", ".2d", ".2s", ".s",
7688 [(set (v2i64 V128:$dst),
7689 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
7690 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7692 let Inst{11} = idx{1};
7693 let Inst{21} = idx{0};
7696 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7699 asm#"2", ".2d", ".2d", ".4s", ".s",
7700 [(set (v2i64 V128:$dst),
7701 (OpNode (v2i64 V128:$Rd),
7702 (extract_high_v4i32 V128:$Rn),
7703 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7704 VectorIndexS:$idx))))]> {
7706 let Inst{11} = idx{1};
7707 let Inst{21} = idx{0};
7712 //----------------------------------------------------------------------------
7713 // AdvSIMD scalar shift by immediate
7714 //----------------------------------------------------------------------------
7716 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7717 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
7718 RegisterClass regtype1, RegisterClass regtype2,
7719 Operand immtype, string asm, list<dag> pattern>
7720 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
7721 asm, "\t$Rd, $Rn, $imm", "", pattern>,
7726 let Inst{31-30} = 0b01;
7728 let Inst{28-23} = 0b111110;
7729 let Inst{22-16} = fixed_imm;
7730 let Inst{15-11} = opc;
7736 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7737 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
7738 RegisterClass regtype1, RegisterClass regtype2,
7739 Operand immtype, string asm, list<dag> pattern>
7740 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
7741 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
7746 let Inst{31-30} = 0b01;
7748 let Inst{28-23} = 0b111110;
7749 let Inst{22-16} = fixed_imm;
7750 let Inst{15-11} = opc;
7757 multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
7758 let Predicates = [HasNEON, HasFullFP16] in {
7759 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7760 FPR16, FPR16, vecshiftR16, asm, []> {
7761 let Inst{19-16} = imm{3-0};
7763 } // Predicates = [HasNEON, HasFullFP16]
7764 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7765 FPR32, FPR32, vecshiftR32, asm, []> {
7766 let Inst{20-16} = imm{4-0};
7769 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7770 FPR64, FPR64, vecshiftR64, asm, []> {
7771 let Inst{21-16} = imm{5-0};
7775 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
7776 SDPatternOperator OpNode> {
7777 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7778 FPR64, FPR64, vecshiftR64, asm,
7779 [(set (i64 FPR64:$Rd),
7780 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
7781 let Inst{21-16} = imm{5-0};
7784 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
7785 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
7788 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
7789 SDPatternOperator OpNode = null_frag> {
7790 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7791 FPR64, FPR64, vecshiftR64, asm,
7792 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
7793 (i32 vecshiftR64:$imm)))]> {
7794 let Inst{21-16} = imm{5-0};
7797 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
7798 (i32 vecshiftR64:$imm))),
7799 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
7803 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
7804 SDPatternOperator OpNode> {
7805 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7806 FPR64, FPR64, vecshiftL64, asm,
7807 [(set (v1i64 FPR64:$Rd),
7808 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7809 let Inst{21-16} = imm{5-0};
7813 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7814 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
7815 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7816 FPR64, FPR64, vecshiftL64, asm, []> {
7817 let Inst{21-16} = imm{5-0};
7821 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7822 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
7823 SDPatternOperator OpNode = null_frag> {
7824 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7825 FPR8, FPR16, vecshiftR8, asm, []> {
7826 let Inst{18-16} = imm{2-0};
7829 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7830 FPR16, FPR32, vecshiftR16, asm, []> {
7831 let Inst{19-16} = imm{3-0};
7834 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7835 FPR32, FPR64, vecshiftR32, asm,
7836 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
7837 let Inst{20-16} = imm{4-0};
7841 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
7842 SDPatternOperator OpNode> {
7843 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7844 FPR8, FPR8, vecshiftL8, asm, []> {
7845 let Inst{18-16} = imm{2-0};
7848 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7849 FPR16, FPR16, vecshiftL16, asm, []> {
7850 let Inst{19-16} = imm{3-0};
7853 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7854 FPR32, FPR32, vecshiftL32, asm,
7855 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
7856 let Inst{20-16} = imm{4-0};
7859 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7860 FPR64, FPR64, vecshiftL64, asm,
7861 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7862 let Inst{21-16} = imm{5-0};
7865 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
7866 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
7869 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
7870 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7871 FPR8, FPR8, vecshiftR8, asm, []> {
7872 let Inst{18-16} = imm{2-0};
7875 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7876 FPR16, FPR16, vecshiftR16, asm, []> {
7877 let Inst{19-16} = imm{3-0};
7880 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7881 FPR32, FPR32, vecshiftR32, asm, []> {
7882 let Inst{20-16} = imm{4-0};
7885 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7886 FPR64, FPR64, vecshiftR64, asm, []> {
7887 let Inst{21-16} = imm{5-0};
7891 //----------------------------------------------------------------------------
7892 // AdvSIMD vector x indexed element
7893 //----------------------------------------------------------------------------
7895 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7896 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7897 RegisterOperand dst_reg, RegisterOperand src_reg,
7899 string asm, string dst_kind, string src_kind,
7901 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
7902 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7903 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
7910 let Inst{28-23} = 0b011110;
7911 let Inst{22-16} = fixed_imm;
7912 let Inst{15-11} = opc;
7918 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7919 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7920 RegisterOperand vectype1, RegisterOperand vectype2,
7922 string asm, string dst_kind, string src_kind,
7924 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
7925 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7926 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
7933 let Inst{28-23} = 0b011110;
7934 let Inst{22-16} = fixed_imm;
7935 let Inst{15-11} = opc;
7941 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
7943 let Predicates = [HasNEON, HasFullFP16] in {
7944 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7945 V64, V64, vecshiftR16,
7947 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
7949 let Inst{19-16} = imm;
7952 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7953 V128, V128, vecshiftR16,
7955 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
7957 let Inst{19-16} = imm;
7959 } // Predicates = [HasNEON, HasFullFP16]
7960 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7961 V64, V64, vecshiftR32,
7963 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
7965 let Inst{20-16} = imm;
7968 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7969 V128, V128, vecshiftR32,
7971 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
7973 let Inst{20-16} = imm;
7976 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7977 V128, V128, vecshiftR64,
7979 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
7981 let Inst{21-16} = imm;
7985 multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
7987 let Predicates = [HasNEON, HasFullFP16] in {
7988 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7989 V64, V64, vecshiftR16,
7991 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
7993 let Inst{19-16} = imm;
7996 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7997 V128, V128, vecshiftR16,
7999 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
8001 let Inst{19-16} = imm;
8003 } // Predicates = [HasNEON, HasFullFP16]
8005 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8006 V64, V64, vecshiftR32,
8008 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
8010 let Inst{20-16} = imm;
8013 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8014 V128, V128, vecshiftR32,
8016 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
8018 let Inst{20-16} = imm;
8021 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8022 V128, V128, vecshiftR64,
8024 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
8026 let Inst{21-16} = imm;
8030 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
8031 SDPatternOperator OpNode> {
8032 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8033 V64, V128, vecshiftR16Narrow,
8035 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
8037 let Inst{18-16} = imm;
8040 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8041 V128, V128, vecshiftR16Narrow,
8042 asm#"2", ".16b", ".8h", []> {
8044 let Inst{18-16} = imm;
8045 let hasSideEffects = 0;
8048 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8049 V64, V128, vecshiftR32Narrow,
8051 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
8053 let Inst{19-16} = imm;
8056 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8057 V128, V128, vecshiftR32Narrow,
8058 asm#"2", ".8h", ".4s", []> {
8060 let Inst{19-16} = imm;
8061 let hasSideEffects = 0;
8064 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8065 V64, V128, vecshiftR64Narrow,
8067 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
8069 let Inst{20-16} = imm;
8072 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8073 V128, V128, vecshiftR64Narrow,
8074 asm#"2", ".4s", ".2d", []> {
8076 let Inst{20-16} = imm;
8077 let hasSideEffects = 0;
8080 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
8081 // themselves, so put them here instead.
8083 // Patterns involving what's effectively an insert high and a normal
8084 // intrinsic, represented by CONCAT_VECTORS.
8085 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
8086 vecshiftR16Narrow:$imm)),
8087 (!cast<Instruction>(NAME # "v16i8_shift")
8088 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8089 V128:$Rn, vecshiftR16Narrow:$imm)>;
8090 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
8091 vecshiftR32Narrow:$imm)),
8092 (!cast<Instruction>(NAME # "v8i16_shift")
8093 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8094 V128:$Rn, vecshiftR32Narrow:$imm)>;
8095 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
8096 vecshiftR64Narrow:$imm)),
8097 (!cast<Instruction>(NAME # "v4i32_shift")
8098 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
8099 V128:$Rn, vecshiftR64Narrow:$imm)>;
8102 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
8103 SDPatternOperator OpNode> {
8104 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8105 V64, V64, vecshiftL8,
8107 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
8108 (i32 vecshiftL8:$imm)))]> {
8110 let Inst{18-16} = imm;
8113 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8114 V128, V128, vecshiftL8,
8115 asm, ".16b", ".16b",
8116 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
8117 (i32 vecshiftL8:$imm)))]> {
8119 let Inst{18-16} = imm;
8122 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8123 V64, V64, vecshiftL16,
8125 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
8126 (i32 vecshiftL16:$imm)))]> {
8128 let Inst{19-16} = imm;
8131 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8132 V128, V128, vecshiftL16,
8134 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
8135 (i32 vecshiftL16:$imm)))]> {
8137 let Inst{19-16} = imm;
8140 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8141 V64, V64, vecshiftL32,
8143 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
8144 (i32 vecshiftL32:$imm)))]> {
8146 let Inst{20-16} = imm;
8149 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8150 V128, V128, vecshiftL32,
8152 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
8153 (i32 vecshiftL32:$imm)))]> {
8155 let Inst{20-16} = imm;
8158 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8159 V128, V128, vecshiftL64,
8161 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
8162 (i32 vecshiftL64:$imm)))]> {
8164 let Inst{21-16} = imm;
8168 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
8169 SDPatternOperator OpNode> {
8170 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8171 V64, V64, vecshiftR8,
8173 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
8174 (i32 vecshiftR8:$imm)))]> {
8176 let Inst{18-16} = imm;
8179 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8180 V128, V128, vecshiftR8,
8181 asm, ".16b", ".16b",
8182 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
8183 (i32 vecshiftR8:$imm)))]> {
8185 let Inst{18-16} = imm;
8188 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8189 V64, V64, vecshiftR16,
8191 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
8192 (i32 vecshiftR16:$imm)))]> {
8194 let Inst{19-16} = imm;
8197 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8198 V128, V128, vecshiftR16,
8200 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
8201 (i32 vecshiftR16:$imm)))]> {
8203 let Inst{19-16} = imm;
8206 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8207 V64, V64, vecshiftR32,
8209 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
8210 (i32 vecshiftR32:$imm)))]> {
8212 let Inst{20-16} = imm;
8215 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8216 V128, V128, vecshiftR32,
8218 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
8219 (i32 vecshiftR32:$imm)))]> {
8221 let Inst{20-16} = imm;
8224 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8225 V128, V128, vecshiftR64,
8227 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
8228 (i32 vecshiftR64:$imm)))]> {
8230 let Inst{21-16} = imm;
8234 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8235 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
8236 SDPatternOperator OpNode = null_frag> {
8237 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8238 V64, V64, vecshiftR8, asm, ".8b", ".8b",
8239 [(set (v8i8 V64:$dst),
8240 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8241 (i32 vecshiftR8:$imm)))]> {
8243 let Inst{18-16} = imm;
8246 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8247 V128, V128, vecshiftR8, asm, ".16b", ".16b",
8248 [(set (v16i8 V128:$dst),
8249 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8250 (i32 vecshiftR8:$imm)))]> {
8252 let Inst{18-16} = imm;
8255 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8256 V64, V64, vecshiftR16, asm, ".4h", ".4h",
8257 [(set (v4i16 V64:$dst),
8258 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8259 (i32 vecshiftR16:$imm)))]> {
8261 let Inst{19-16} = imm;
8264 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8265 V128, V128, vecshiftR16, asm, ".8h", ".8h",
8266 [(set (v8i16 V128:$dst),
8267 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8268 (i32 vecshiftR16:$imm)))]> {
8270 let Inst{19-16} = imm;
8273 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8274 V64, V64, vecshiftR32, asm, ".2s", ".2s",
8275 [(set (v2i32 V64:$dst),
8276 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8277 (i32 vecshiftR32:$imm)))]> {
8279 let Inst{20-16} = imm;
8282 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8283 V128, V128, vecshiftR32, asm, ".4s", ".4s",
8284 [(set (v4i32 V128:$dst),
8285 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8286 (i32 vecshiftR32:$imm)))]> {
8288 let Inst{20-16} = imm;
8291 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8292 V128, V128, vecshiftR64,
8293 asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
8294 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8295 (i32 vecshiftR64:$imm)))]> {
8297 let Inst{21-16} = imm;
8301 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
8302 SDPatternOperator OpNode = null_frag> {
8303 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8304 V64, V64, vecshiftL8,
8306 [(set (v8i8 V64:$dst),
8307 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8308 (i32 vecshiftL8:$imm)))]> {
8310 let Inst{18-16} = imm;
8313 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8314 V128, V128, vecshiftL8,
8315 asm, ".16b", ".16b",
8316 [(set (v16i8 V128:$dst),
8317 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8318 (i32 vecshiftL8:$imm)))]> {
8320 let Inst{18-16} = imm;
8323 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8324 V64, V64, vecshiftL16,
8326 [(set (v4i16 V64:$dst),
8327 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8328 (i32 vecshiftL16:$imm)))]> {
8330 let Inst{19-16} = imm;
8333 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8334 V128, V128, vecshiftL16,
8336 [(set (v8i16 V128:$dst),
8337 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8338 (i32 vecshiftL16:$imm)))]> {
8340 let Inst{19-16} = imm;
8343 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8344 V64, V64, vecshiftL32,
8346 [(set (v2i32 V64:$dst),
8347 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8348 (i32 vecshiftL32:$imm)))]> {
8350 let Inst{20-16} = imm;
8353 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8354 V128, V128, vecshiftL32,
8356 [(set (v4i32 V128:$dst),
8357 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8358 (i32 vecshiftL32:$imm)))]> {
8360 let Inst{20-16} = imm;
8363 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8364 V128, V128, vecshiftL64,
8366 [(set (v2i64 V128:$dst),
8367 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8368 (i32 vecshiftL64:$imm)))]> {
8370 let Inst{21-16} = imm;
8374 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
8375 SDPatternOperator OpNode> {
8376 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8377 V128, V64, vecshiftL8, asm, ".8h", ".8b",
8378 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
8380 let Inst{18-16} = imm;
8383 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8384 V128, V128, vecshiftL8,
8385 asm#"2", ".8h", ".16b",
8386 [(set (v8i16 V128:$Rd),
8387 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
8389 let Inst{18-16} = imm;
8392 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8393 V128, V64, vecshiftL16, asm, ".4s", ".4h",
8394 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
8396 let Inst{19-16} = imm;
8399 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8400 V128, V128, vecshiftL16,
8401 asm#"2", ".4s", ".8h",
8402 [(set (v4i32 V128:$Rd),
8403 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
8406 let Inst{19-16} = imm;
8409 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8410 V128, V64, vecshiftL32, asm, ".2d", ".2s",
8411 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
8413 let Inst{20-16} = imm;
8416 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8417 V128, V128, vecshiftL32,
8418 asm#"2", ".2d", ".4s",
8419 [(set (v2i64 V128:$Rd),
8420 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
8422 let Inst{20-16} = imm;
8428 // Vector load/store
8430 // SIMD ldX/stX no-index memory references don't allow the optional
8431 // ", #0" constant and handle post-indexing explicitly, so we use
8432 // a more specialized parse method for them. Otherwise, it's the same as
8433 // the general GPR64sp handling.
8435 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
8436 string asm, dag oops, dag iops, list<dag> pattern>
8437 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
8442 let Inst{29-23} = 0b0011000;
8444 let Inst{21-16} = 0b000000;
8445 let Inst{15-12} = opcode;
8446 let Inst{11-10} = size;
8451 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
8452 string asm, dag oops, dag iops>
8453 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
8459 let Inst{29-23} = 0b0011001;
8462 let Inst{20-16} = Xm;
8463 let Inst{15-12} = opcode;
8464 let Inst{11-10} = size;
8469 // The immediate form of AdvSIMD post-indexed addressing is encoded with
8470 // register post-index addressing from the zero register.
8471 multiclass SIMDLdStAliases<string asm, string layout, string Count,
8472 int Offset, int Size> {
8473 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
8474 // "ld1\t$Vt, [$Rn], #16"
8475 // may get mapped to
8476 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
8477 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8478 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8480 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8483 // E.g. "ld1.8b { v0, v1 }, [x1], #16"
8484 // "ld1.8b\t$Vt, [$Rn], #16"
8485 // may get mapped to
8486 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
8487 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8488 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8490 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8493 // E.g. "ld1.8b { v0, v1 }, [x1]"
8494 // "ld1\t$Vt, [$Rn]"
8495 // may get mapped to
8496 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
8497 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8498 (!cast<Instruction>(NAME # Count # "v" # layout)
8499 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8502 // E.g. "ld1.8b { v0, v1 }, [x1], x2"
8503 // "ld1\t$Vt, [$Rn], $Xm"
8504 // may get mapped to
8505 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
8506 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8507 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8509 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8510 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8513 multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
8514 int Offset64, bits<4> opcode> {
8515 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8516 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
8517 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
8518 (ins GPR64sp:$Rn), []>;
8519 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
8520 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
8521 (ins GPR64sp:$Rn), []>;
8522 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
8523 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
8524 (ins GPR64sp:$Rn), []>;
8525 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
8526 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
8527 (ins GPR64sp:$Rn), []>;
8528 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
8529 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
8530 (ins GPR64sp:$Rn), []>;
8531 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
8532 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
8533 (ins GPR64sp:$Rn), []>;
8534 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
8535 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
8536 (ins GPR64sp:$Rn), []>;
8539 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
8540 (outs GPR64sp:$wback,
8541 !cast<RegisterOperand>(veclist # "16b"):$Vt),
8543 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8544 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
8545 (outs GPR64sp:$wback,
8546 !cast<RegisterOperand>(veclist # "8h"):$Vt),
8548 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8549 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
8550 (outs GPR64sp:$wback,
8551 !cast<RegisterOperand>(veclist # "4s"):$Vt),
8553 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8554 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
8555 (outs GPR64sp:$wback,
8556 !cast<RegisterOperand>(veclist # "2d"):$Vt),
8558 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8559 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
8560 (outs GPR64sp:$wback,
8561 !cast<RegisterOperand>(veclist # "8b"):$Vt),
8563 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8564 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
8565 (outs GPR64sp:$wback,
8566 !cast<RegisterOperand>(veclist # "4h"):$Vt),
8568 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8569 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
8570 (outs GPR64sp:$wback,
8571 !cast<RegisterOperand>(veclist # "2s"):$Vt),
8573 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8576 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
8577 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8578 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8579 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8580 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8581 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8582 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8585 // Only ld1/st1 has a v1d version.
8586 multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
8587 int Offset64, bits<4> opcode> {
8588 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
8589 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
8590 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8592 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
8593 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8595 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
8596 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8598 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
8599 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8601 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
8602 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8604 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
8605 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8607 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
8608 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8611 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
8612 (outs GPR64sp:$wback),
8613 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8615 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8616 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
8617 (outs GPR64sp:$wback),
8618 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8620 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8621 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
8622 (outs GPR64sp:$wback),
8623 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8625 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8626 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
8627 (outs GPR64sp:$wback),
8628 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8630 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8631 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
8632 (outs GPR64sp:$wback),
8633 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8635 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8636 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
8637 (outs GPR64sp:$wback),
8638 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8640 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8641 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
8642 (outs GPR64sp:$wback),
8643 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8645 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8648 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
8649 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8650 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8651 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8652 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8653 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8654 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8657 multiclass BaseSIMDLd1<string Count, string asm, string veclist,
8658 int Offset128, int Offset64, bits<4> opcode>
8659 : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
8661 // LD1 instructions have extra "1d" variants.
8662 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8663 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
8664 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
8665 (ins GPR64sp:$Rn), []>;
8667 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
8668 (outs GPR64sp:$wback,
8669 !cast<RegisterOperand>(veclist # "1d"):$Vt),
8671 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8674 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8677 multiclass BaseSIMDSt1<string Count, string asm, string veclist,
8678 int Offset128, int Offset64, bits<4> opcode>
8679 : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
8681 // ST1 instructions have extra "1d" variants.
8682 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
8683 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
8684 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8687 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
8688 (outs GPR64sp:$wback),
8689 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8691 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8694 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8697 multiclass SIMDLd1Multiple<string asm> {
8698 defm One : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8, 0b0111>;
8699 defm Two : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8700 defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8701 defm Four : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8704 multiclass SIMDSt1Multiple<string asm> {
8705 defm One : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8, 0b0111>;
8706 defm Two : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8707 defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8708 defm Four : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8711 multiclass SIMDLd2Multiple<string asm> {
8712 defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8715 multiclass SIMDSt2Multiple<string asm> {
8716 defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8719 multiclass SIMDLd3Multiple<string asm> {
8720 defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8723 multiclass SIMDSt3Multiple<string asm> {
8724 defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8727 multiclass SIMDLd4Multiple<string asm> {
8728 defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8731 multiclass SIMDSt4Multiple<string asm> {
8732 defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8736 // AdvSIMD Load/store single-element
8739 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
8740 string asm, string operands, string cst,
8741 dag oops, dag iops, list<dag> pattern>
8742 : I<oops, iops, asm, operands, cst, pattern> {
8746 let Inst{29-24} = 0b001101;
8749 let Inst{15-13} = opcode;
8754 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
8755 string asm, string operands, string cst,
8756 dag oops, dag iops, list<dag> pattern>
8757 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
8761 let Inst{29-24} = 0b001101;
8764 let Inst{15-13} = opcode;
8770 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8771 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
8773 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
8774 (outs listtype:$Vt), (ins GPR64sp:$Rn),
8778 let Inst{20-16} = 0b00000;
8780 let Inst{11-10} = size;
8782 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8783 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
8784 string asm, Operand listtype, Operand GPR64pi>
8785 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
8787 (outs GPR64sp:$wback, listtype:$Vt),
8788 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
8792 let Inst{20-16} = Xm;
8794 let Inst{11-10} = size;
8797 multiclass SIMDLdrAliases<string asm, string layout, string Count,
8798 int Offset, int Size> {
8799 // E.g. "ld1r { v0.8b }, [x1], #1"
8800 // "ld1r.8b\t$Vt, [$Rn], #1"
8801 // may get mapped to
8802 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8803 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8804 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8806 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8809 // E.g. "ld1r.8b { v0 }, [x1], #1"
8810 // "ld1r.8b\t$Vt, [$Rn], #1"
8811 // may get mapped to
8812 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8813 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8814 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8816 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8819 // E.g. "ld1r.8b { v0 }, [x1]"
8820 // "ld1r.8b\t$Vt, [$Rn]"
8821 // may get mapped to
8822 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8823 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8824 (!cast<Instruction>(NAME # "v" # layout)
8825 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8828 // E.g. "ld1r.8b { v0 }, [x1], x2"
8829 // "ld1r.8b\t$Vt, [$Rn], $Xm"
8830 // may get mapped to
8831 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8832 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8833 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8835 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8836 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8839 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
8840 int Offset1, int Offset2, int Offset4, int Offset8> {
8841 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
8842 !cast<Operand>("VecList" # Count # "8b")>;
8843 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
8844 !cast<Operand>("VecList" # Count #"16b")>;
8845 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
8846 !cast<Operand>("VecList" # Count #"4h")>;
8847 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
8848 !cast<Operand>("VecList" # Count #"8h")>;
8849 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
8850 !cast<Operand>("VecList" # Count #"2s")>;
8851 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
8852 !cast<Operand>("VecList" # Count #"4s")>;
8853 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
8854 !cast<Operand>("VecList" # Count #"1d")>;
8855 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
8856 !cast<Operand>("VecList" # Count #"2d")>;
8858 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
8859 !cast<Operand>("VecList" # Count # "8b"),
8860 !cast<Operand>("GPR64pi" # Offset1)>;
8861 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
8862 !cast<Operand>("VecList" # Count # "16b"),
8863 !cast<Operand>("GPR64pi" # Offset1)>;
8864 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
8865 !cast<Operand>("VecList" # Count # "4h"),
8866 !cast<Operand>("GPR64pi" # Offset2)>;
8867 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
8868 !cast<Operand>("VecList" # Count # "8h"),
8869 !cast<Operand>("GPR64pi" # Offset2)>;
8870 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
8871 !cast<Operand>("VecList" # Count # "2s"),
8872 !cast<Operand>("GPR64pi" # Offset4)>;
8873 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
8874 !cast<Operand>("VecList" # Count # "4s"),
8875 !cast<Operand>("GPR64pi" # Offset4)>;
8876 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
8877 !cast<Operand>("VecList" # Count # "1d"),
8878 !cast<Operand>("GPR64pi" # Offset8)>;
8879 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
8880 !cast<Operand>("VecList" # Count # "2d"),
8881 !cast<Operand>("GPR64pi" # Offset8)>;
8883 defm : SIMDLdrAliases<asm, "8b", Count, Offset1, 64>;
8884 defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
8885 defm : SIMDLdrAliases<asm, "4h", Count, Offset2, 64>;
8886 defm : SIMDLdrAliases<asm, "8h", Count, Offset2, 128>;
8887 defm : SIMDLdrAliases<asm, "2s", Count, Offset4, 64>;
8888 defm : SIMDLdrAliases<asm, "4s", Count, Offset4, 128>;
8889 defm : SIMDLdrAliases<asm, "1d", Count, Offset8, 64>;
8890 defm : SIMDLdrAliases<asm, "2d", Count, Offset8, 128>;
8893 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
8894 dag oops, dag iops, list<dag> pattern>
8895 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8897 // idx encoded in Q:S:size fields.
8899 let Inst{30} = idx{3};
8901 let Inst{20-16} = 0b00000;
8902 let Inst{12} = idx{2};
8903 let Inst{11-10} = idx{1-0};
8905 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
8906 dag oops, dag iops, list<dag> pattern>
8907 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8908 oops, iops, pattern> {
8909 // idx encoded in Q:S:size fields.
8911 let Inst{30} = idx{3};
8913 let Inst{20-16} = 0b00000;
8914 let Inst{12} = idx{2};
8915 let Inst{11-10} = idx{1-0};
8917 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
8919 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8920 "$Rn = $wback", oops, iops, []> {
8921 // idx encoded in Q:S:size fields.
8924 let Inst{30} = idx{3};
8926 let Inst{20-16} = Xm;
8927 let Inst{12} = idx{2};
8928 let Inst{11-10} = idx{1-0};
8930 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
8932 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8933 "$Rn = $wback", oops, iops, []> {
8934 // idx encoded in Q:S:size fields.
8937 let Inst{30} = idx{3};
8939 let Inst{20-16} = Xm;
8940 let Inst{12} = idx{2};
8941 let Inst{11-10} = idx{1-0};
8944 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
8945 dag oops, dag iops, list<dag> pattern>
8946 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8948 // idx encoded in Q:S:size<1> fields.
8950 let Inst{30} = idx{2};
8952 let Inst{20-16} = 0b00000;
8953 let Inst{12} = idx{1};
8954 let Inst{11} = idx{0};
8955 let Inst{10} = size;
8957 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
8958 dag oops, dag iops, list<dag> pattern>
8959 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8960 oops, iops, pattern> {
8961 // idx encoded in Q:S:size<1> fields.
8963 let Inst{30} = idx{2};
8965 let Inst{20-16} = 0b00000;
8966 let Inst{12} = idx{1};
8967 let Inst{11} = idx{0};
8968 let Inst{10} = size;
8971 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8973 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8974 "$Rn = $wback", oops, iops, []> {
8975 // idx encoded in Q:S:size<1> fields.
8978 let Inst{30} = idx{2};
8980 let Inst{20-16} = Xm;
8981 let Inst{12} = idx{1};
8982 let Inst{11} = idx{0};
8983 let Inst{10} = size;
8985 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8987 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8988 "$Rn = $wback", oops, iops, []> {
8989 // idx encoded in Q:S:size<1> fields.
8992 let Inst{30} = idx{2};
8994 let Inst{20-16} = Xm;
8995 let Inst{12} = idx{1};
8996 let Inst{11} = idx{0};
8997 let Inst{10} = size;
8999 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9000 dag oops, dag iops, list<dag> pattern>
9001 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9003 // idx encoded in Q:S fields.
9005 let Inst{30} = idx{1};
9007 let Inst{20-16} = 0b00000;
9008 let Inst{12} = idx{0};
9009 let Inst{11-10} = size;
9011 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9012 dag oops, dag iops, list<dag> pattern>
9013 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9014 oops, iops, pattern> {
9015 // idx encoded in Q:S fields.
9017 let Inst{30} = idx{1};
9019 let Inst{20-16} = 0b00000;
9020 let Inst{12} = idx{0};
9021 let Inst{11-10} = size;
9023 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
9024 string asm, dag oops, dag iops>
9025 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9026 "$Rn = $wback", oops, iops, []> {
9027 // idx encoded in Q:S fields.
9030 let Inst{30} = idx{1};
9032 let Inst{20-16} = Xm;
9033 let Inst{12} = idx{0};
9034 let Inst{11-10} = size;
9036 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
9037 string asm, dag oops, dag iops>
9038 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9039 "$Rn = $wback", oops, iops, []> {
9040 // idx encoded in Q:S fields.
9043 let Inst{30} = idx{1};
9045 let Inst{20-16} = Xm;
9046 let Inst{12} = idx{0};
9047 let Inst{11-10} = size;
9049 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9050 dag oops, dag iops, list<dag> pattern>
9051 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
9053 // idx encoded in Q field.
9057 let Inst{20-16} = 0b00000;
9059 let Inst{11-10} = size;
9061 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
9062 dag oops, dag iops, list<dag> pattern>
9063 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
9064 oops, iops, pattern> {
9065 // idx encoded in Q field.
9069 let Inst{20-16} = 0b00000;
9071 let Inst{11-10} = size;
9073 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
9074 string asm, dag oops, dag iops>
9075 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9076 "$Rn = $wback", oops, iops, []> {
9077 // idx encoded in Q field.
9082 let Inst{20-16} = Xm;
9084 let Inst{11-10} = size;
9086 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
9087 string asm, dag oops, dag iops>
9088 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
9089 "$Rn = $wback", oops, iops, []> {
9090 // idx encoded in Q field.
9095 let Inst{20-16} = Xm;
9097 let Inst{11-10} = size;
9100 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9101 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
9102 RegisterOperand listtype,
9103 RegisterOperand GPR64pi> {
9104 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
9105 (outs listtype:$dst),
9106 (ins listtype:$Vt, VectorIndexB:$idx,
9109 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
9110 (outs GPR64sp:$wback, listtype:$dst),
9111 (ins listtype:$Vt, VectorIndexB:$idx,
9112 GPR64sp:$Rn, GPR64pi:$Xm)>;
9114 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9115 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
9116 RegisterOperand listtype,
9117 RegisterOperand GPR64pi> {
9118 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
9119 (outs listtype:$dst),
9120 (ins listtype:$Vt, VectorIndexH:$idx,
9123 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
9124 (outs GPR64sp:$wback, listtype:$dst),
9125 (ins listtype:$Vt, VectorIndexH:$idx,
9126 GPR64sp:$Rn, GPR64pi:$Xm)>;
9128 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9129 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
9130 RegisterOperand listtype,
9131 RegisterOperand GPR64pi> {
9132 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
9133 (outs listtype:$dst),
9134 (ins listtype:$Vt, VectorIndexS:$idx,
9137 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
9138 (outs GPR64sp:$wback, listtype:$dst),
9139 (ins listtype:$Vt, VectorIndexS:$idx,
9140 GPR64sp:$Rn, GPR64pi:$Xm)>;
9142 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
9143 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
9144 RegisterOperand listtype, RegisterOperand GPR64pi> {
9145 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
9146 (outs listtype:$dst),
9147 (ins listtype:$Vt, VectorIndexD:$idx,
9150 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
9151 (outs GPR64sp:$wback, listtype:$dst),
9152 (ins listtype:$Vt, VectorIndexD:$idx,
9153 GPR64sp:$Rn, GPR64pi:$Xm)>;
9155 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9156 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
9157 RegisterOperand listtype, RegisterOperand GPR64pi> {
9158 def i8 : SIMDLdStSingleB<0, R, opcode, asm,
9159 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
9162 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
9163 (outs GPR64sp:$wback),
9164 (ins listtype:$Vt, VectorIndexB:$idx,
9165 GPR64sp:$Rn, GPR64pi:$Xm)>;
9167 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9168 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
9169 RegisterOperand listtype, RegisterOperand GPR64pi> {
9170 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
9171 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
9174 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
9175 (outs GPR64sp:$wback),
9176 (ins listtype:$Vt, VectorIndexH:$idx,
9177 GPR64sp:$Rn, GPR64pi:$Xm)>;
9179 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9180 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
9181 RegisterOperand listtype, RegisterOperand GPR64pi> {
9182 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
9183 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
9186 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
9187 (outs GPR64sp:$wback),
9188 (ins listtype:$Vt, VectorIndexS:$idx,
9189 GPR64sp:$Rn, GPR64pi:$Xm)>;
9191 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
9192 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
9193 RegisterOperand listtype, RegisterOperand GPR64pi> {
9194 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
9195 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
9198 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
9199 (outs GPR64sp:$wback),
9200 (ins listtype:$Vt, VectorIndexD:$idx,
9201 GPR64sp:$Rn, GPR64pi:$Xm)>;
9204 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
9205 string Count, int Offset, Operand idxtype> {
9206 // E.g. "ld1 { v0.8b }[0], [x1], #1"
9207 // "ld1\t$Vt, [$Rn], #1"
9208 // may get mapped to
9209 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
9210 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
9211 (!cast<Instruction>(NAME # Type # "_POST")
9213 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9214 idxtype:$idx, XZR), 1>;
9216 // E.g. "ld1.8b { v0 }[0], [x1], #1"
9217 // "ld1.8b\t$Vt, [$Rn], #1"
9218 // may get mapped to
9219 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
9220 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
9221 (!cast<Instruction>(NAME # Type # "_POST")
9223 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9224 idxtype:$idx, XZR), 0>;
9226 // E.g. "ld1.8b { v0 }[0], [x1]"
9227 // "ld1.8b\t$Vt, [$Rn]"
9228 // may get mapped to
9229 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
9230 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
9231 (!cast<Instruction>(NAME # Type)
9232 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9233 idxtype:$idx, GPR64sp:$Rn), 0>;
9235 // E.g. "ld1.8b { v0 }[0], [x1], x2"
9236 // "ld1.8b\t$Vt, [$Rn], $Xm"
9237 // may get mapped to
9238 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
9239 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
9240 (!cast<Instruction>(NAME # Type # "_POST")
9242 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9244 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9247 multiclass SIMDLdSt1SingleAliases<string asm> {
9248 defm : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;
9249 defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
9250 defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
9251 defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
9254 multiclass SIMDLdSt2SingleAliases<string asm> {
9255 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;
9256 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;
9257 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;
9258 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
9261 multiclass SIMDLdSt3SingleAliases<string asm> {
9262 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;
9263 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;
9264 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
9265 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
9268 multiclass SIMDLdSt4SingleAliases<string asm> {
9269 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;
9270 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;
9271 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
9272 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
9274 } // end of 'let Predicates = [HasNEON]'
9276 //----------------------------------------------------------------------------
9277 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
9278 //----------------------------------------------------------------------------
9280 let Predicates = [HasNEON, HasRDM] in {
9282 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
9283 RegisterOperand regtype, string asm,
9284 string kind, list<dag> pattern>
9285 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind,
9288 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
9289 SDPatternOperator Accum> {
9290 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
9291 [(set (v4i16 V64:$dst),
9292 (Accum (v4i16 V64:$Rd),
9293 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
9294 (v4i16 V64:$Rm)))))]>;
9295 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
9296 [(set (v8i16 V128:$dst),
9297 (Accum (v8i16 V128:$Rd),
9298 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
9299 (v8i16 V128:$Rm)))))]>;
9300 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
9301 [(set (v2i32 V64:$dst),
9302 (Accum (v2i32 V64:$Rd),
9303 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
9304 (v2i32 V64:$Rm)))))]>;
9305 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
9306 [(set (v4i32 V128:$dst),
9307 (Accum (v4i32 V128:$Rd),
9308 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
9309 (v4i32 V128:$Rm)))))]>;
9312 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
9313 SDPatternOperator Accum> {
9314 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
9315 V64, V64, V128_lo, VectorIndexH,
9316 asm, ".4h", ".4h", ".4h", ".h",
9317 [(set (v4i16 V64:$dst),
9318 (Accum (v4i16 V64:$Rd),
9319 (v4i16 (int_aarch64_neon_sqrdmulh
9321 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
9322 VectorIndexH:$idx))))))]> {
9324 let Inst{11} = idx{2};
9325 let Inst{21} = idx{1};
9326 let Inst{20} = idx{0};
9329 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
9330 V128, V128, V128_lo, VectorIndexH,
9331 asm, ".8h", ".8h", ".8h", ".h",
9332 [(set (v8i16 V128:$dst),
9333 (Accum (v8i16 V128:$Rd),
9334 (v8i16 (int_aarch64_neon_sqrdmulh
9336 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
9337 VectorIndexH:$idx))))))]> {
9339 let Inst{11} = idx{2};
9340 let Inst{21} = idx{1};
9341 let Inst{20} = idx{0};
9344 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
9345 V64, V64, V128, VectorIndexS,
9346 asm, ".2s", ".2s", ".2s", ".s",
9347 [(set (v2i32 V64:$dst),
9348 (Accum (v2i32 V64:$Rd),
9349 (v2i32 (int_aarch64_neon_sqrdmulh
9351 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
9352 VectorIndexS:$idx))))))]> {
9354 let Inst{11} = idx{1};
9355 let Inst{21} = idx{0};
9358 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
9359 // an intermediate EXTRACT_SUBREG would be untyped.
9360 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
9361 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
9362 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9363 (i32 (vector_extract
9364 (v4i32 (insert_subvector
9366 (v2i32 (int_aarch64_neon_sqrdmulh
9368 (v2i32 (AArch64duplane32
9370 VectorIndexS:$idx)))),
9374 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
9375 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
9380 VectorIndexS:$idx)),
9383 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
9384 V128, V128, V128, VectorIndexS,
9385 asm, ".4s", ".4s", ".4s", ".s",
9386 [(set (v4i32 V128:$dst),
9387 (Accum (v4i32 V128:$Rd),
9388 (v4i32 (int_aarch64_neon_sqrdmulh
9390 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
9391 VectorIndexS:$idx))))))]> {
9393 let Inst{11} = idx{1};
9394 let Inst{21} = idx{0};
9397 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
9398 // an intermediate EXTRACT_SUBREG would be untyped.
9399 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9400 (i32 (vector_extract
9401 (v4i32 (int_aarch64_neon_sqrdmulh
9403 (v4i32 (AArch64duplane32
9405 VectorIndexS:$idx)))),
9408 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
9409 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
9414 VectorIndexS:$idx)),
9417 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
9418 FPR16Op, FPR16Op, V128_lo,
9419 VectorIndexH, asm, ".h", "", "", ".h",
9422 let Inst{11} = idx{2};
9423 let Inst{21} = idx{1};
9424 let Inst{20} = idx{0};
9427 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
9428 FPR32Op, FPR32Op, V128, VectorIndexS,
9429 asm, ".s", "", "", ".s",
9430 [(set (i32 FPR32Op:$dst),
9431 (Accum (i32 FPR32Op:$Rd),
9432 (i32 (int_aarch64_neon_sqrdmulh
9434 (i32 (vector_extract (v4i32 V128:$Rm),
9435 VectorIndexS:$idx))))))]> {
9437 let Inst{11} = idx{1};
9438 let Inst{21} = idx{0};
9441 } // let Predicates = [HasNeon, HasRDM]
9443 //----------------------------------------------------------------------------
9444 // ARMv8.3 Complex ADD/MLA instructions
9445 //----------------------------------------------------------------------------
9447 class ComplexRotationOperand<int Angle, int Remainder, string Type>
9449 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">";
9450 let DiagnosticType = "InvalidComplexRotation" # Type;
9451 let Name = "ComplexRotation" # Type;
9453 def complexrotateop : Operand<i32> {
9454 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">;
9455 let PrintMethod = "printComplexRotationOp<90, 0>";
9457 def complexrotateopodd : Operand<i32> {
9458 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">;
9459 let PrintMethod = "printComplexRotationOp<180, 90>";
9462 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9463 class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode,
9464 RegisterOperand regtype, Operand rottype,
9465 string asm, string kind, list<dag> pattern>
9466 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
9467 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
9468 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>,
9477 let Inst{28-24} = 0b01110;
9478 let Inst{23-22} = size;
9480 let Inst{20-16} = Rm;
9481 let Inst{15-13} = opcode;
9482 // Non-tied version (FCADD) only has one rotation bit
9490 multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype,
9491 string asm, SDPatternOperator OpNode>{
9492 let Predicates = [HasV8_3a, HasNEON, HasFullFP16] in {
9493 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype,
9495 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
9498 (rottype i32:$rot)))]>;
9500 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype,
9502 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
9505 (rottype i32:$rot)))]>;
9508 let Predicates = [HasV8_3a, HasNEON] in {
9509 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype,
9511 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
9514 (rottype i32:$rot)))]>;
9516 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype,
9518 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
9521 (rottype i32:$rot)))]>;
9523 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype,
9525 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
9528 (rottype i32:$rot)))]>;
9532 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9533 class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size,
9535 RegisterOperand regtype,
9536 Operand rottype, string asm,
9537 string kind, list<dag> pattern>
9538 : I<(outs regtype:$dst),
9539 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm,
9540 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"
9541 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>,
9550 let Inst{28-24} = 0b01110;
9551 let Inst{23-22} = size;
9553 let Inst{20-16} = Rm;
9554 let Inst{15-13} = opcode;
9555 let Inst{12-11} = rot;
9561 multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode,
9562 Operand rottype, string asm,
9563 SDPatternOperator OpNode> {
9564 let Predicates = [HasV8_3a, HasNEON, HasFullFP16] in {
9565 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64,
9566 rottype, asm, ".4h",
9567 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),
9570 (rottype i32:$rot)))]>;
9572 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128,
9573 rottype, asm, ".8h",
9574 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),
9577 (rottype i32:$rot)))]>;
9580 let Predicates = [HasV8_3a, HasNEON] in {
9581 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64,
9582 rottype, asm, ".2s",
9583 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),
9586 (rottype i32:$rot)))]>;
9588 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128,
9589 rottype, asm, ".4s",
9590 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),
9593 (rottype i32:$rot)))]>;
9595 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128,
9596 rottype, asm, ".2d",
9597 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),
9600 (rottype i32:$rot)))]>;
9604 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9605 class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size,
9606 bit opc1, bit opc2, RegisterOperand dst_reg,
9607 RegisterOperand lhs_reg,
9608 RegisterOperand rhs_reg, Operand vec_idx,
9609 Operand rottype, string asm, string apple_kind,
9610 string dst_kind, string lhs_kind,
9611 string rhs_kind, list<dag> pattern>
9612 : I<(outs dst_reg:$dst),
9613 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot),
9615 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind #
9616 "$idx, $rot" # "|" # apple_kind #
9617 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>,
9627 let Inst{28} = Scalar;
9628 let Inst{27-24} = 0b1111;
9629 let Inst{23-22} = size;
9630 // Bit 21 must be set by the derived class.
9631 let Inst{20-16} = Rm;
9632 let Inst{15} = opc1;
9633 let Inst{14-13} = rot;
9634 let Inst{12} = opc2;
9635 // Bit 11 must be set by the derived class.
9641 // The complex instructions index by pairs of elements, so the VectorIndexes
9642 // don't match the lane types, and the index bits are different to the other
9644 multiclass SIMDIndexedTiedComplexHSD<bit U, bit opc1, bit opc2, Operand rottype,
9645 string asm, SDPatternOperator OpNode> {
9646 let Predicates = [HasV8_3a,HasNEON,HasFullFP16] in {
9647 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64,
9648 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h",
9652 let Inst{21} = idx{0};
9655 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2,
9656 V128, V128, V128, VectorIndexS, rottype, asm, ".8h",
9657 ".8h", ".8h", ".h", []> {
9659 let Inst{11} = idx{1};
9660 let Inst{21} = idx{0};
9662 } // Predicates = [HasV8_3a,HasNEON,HasFullFP16]
9664 let Predicates = [HasV8_3a,HasNEON] in {
9665 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2,
9666 V128, V128, V128, VectorIndexD, rottype, asm, ".4s",
9667 ".4s", ".4s", ".s", []> {
9669 let Inst{11} = idx{0};
9672 } // Predicates = [HasV8_3a,HasNEON]
9675 //----------------------------------------------------------------------------
9676 // Crypto extensions
9677 //----------------------------------------------------------------------------
9679 let Predicates = [HasCrypto] in {
9680 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9681 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
9683 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
9687 let Inst{31-16} = 0b0100111000101000;
9688 let Inst{15-12} = opc;
9689 let Inst{11-10} = 0b10;
9694 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
9695 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
9696 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
9698 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
9699 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
9701 [(set (v16i8 V128:$dst),
9702 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
9704 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9705 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
9706 dag oops, dag iops, list<dag> pat>
9707 : I<oops, iops, asm,
9708 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
9709 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
9714 let Inst{31-21} = 0b01011110000;
9715 let Inst{20-16} = Rm;
9717 let Inst{14-12} = opc;
9718 let Inst{11-10} = 0b00;
9723 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
9724 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9725 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
9726 [(set (v4i32 FPR128:$dst),
9727 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
9728 (v4i32 V128:$Rm)))]>;
9730 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
9731 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
9732 (ins V128:$Rd, V128:$Rn, V128:$Rm),
9733 [(set (v4i32 V128:$dst),
9734 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9735 (v4i32 V128:$Rm)))]>;
9737 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
9738 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9739 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
9740 [(set (v4i32 FPR128:$dst),
9741 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
9742 (v4i32 V128:$Rm)))]>;
9744 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9745 class SHA2OpInst<bits<4> opc, string asm, string kind,
9746 string cstr, dag oops, dag iops,
9748 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
9749 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
9753 let Inst{31-16} = 0b0101111000101000;
9754 let Inst{15-12} = opc;
9755 let Inst{11-10} = 0b10;
9760 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
9761 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
9762 (ins V128:$Rd, V128:$Rn),
9763 [(set (v4i32 V128:$dst),
9764 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
9766 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
9767 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
9768 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
9769 } // end of 'let Predicates = [HasCrypto]'
9771 //----------------------------------------------------------------------------
9772 // v8.1 atomic instructions extension:
9776 // * LDOPregister<OP>, and aliases STOPregister<OP>
9778 // Instruction encodings:
9780 // 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0
9781 // CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt
9782 // CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt
9783 // SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt
9784 // LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt
9785 // ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111
9787 // Instruction syntax:
9789 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9790 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
9791 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
9792 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
9793 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9794 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
9795 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9796 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
9797 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
9798 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
9800 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9801 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
9802 string cstr, list<dag> pattern>
9803 : I<oops, iops, asm, operands, cstr, pattern> {
9811 let Inst{31-30} = Sz;
9812 let Inst{29-24} = 0b001000;
9816 let Inst{20-16} = Rs;
9818 let Inst{14-10} = 0b11111;
9821 let Predicates = [HasLSE];
9824 class BaseCAS<string order, string size, RegisterClass RC>
9825 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
9826 "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
9828 Sched<[WriteAtomic]> {
9832 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
9833 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>;
9834 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>;
9835 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>;
9836 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>;
9839 class BaseCASP<string order, string size, RegisterOperand RC>
9840 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
9841 "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
9843 Sched<[WriteAtomic]> {
9847 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
9848 let Sz = 0b00, Acq = Acq, Rel = Rel in
9849 def W : BaseCASP<order, "", WSeqPairClassOperand>;
9850 let Sz = 0b01, Acq = Acq, Rel = Rel in
9851 def X : BaseCASP<order, "", XSeqPairClassOperand>;
9854 let Predicates = [HasLSE] in
9855 class BaseSWP<string order, string size, RegisterClass RC>
9856 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
9857 "\t$Rs, $Rt, [$Rn]","",[]>,
9858 Sched<[WriteAtomic]> {
9863 bits<3> opc = 0b000;
9866 let Inst{31-30} = Sz;
9867 let Inst{29-24} = 0b111000;
9871 let Inst{20-16} = Rs;
9873 let Inst{14-12} = opc;
9874 let Inst{11-10} = 0b00;
9877 let Predicates = [HasLSE];
9880 multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
9881 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>;
9882 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>;
9883 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>;
9884 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>;
9887 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9888 class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
9889 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
9890 "\t$Rs, $Rt, [$Rn]","",[]>,
9891 Sched<[WriteAtomic]> {
9899 let Inst{31-30} = Sz;
9900 let Inst{29-24} = 0b111000;
9904 let Inst{20-16} = Rs;
9906 let Inst{14-12} = opc;
9907 let Inst{11-10} = 0b00;
9910 let Predicates = [HasLSE];
9913 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
9915 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
9916 def B : BaseLDOPregister<op, order, "b", GPR32>;
9917 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
9918 def H : BaseLDOPregister<op, order, "h", GPR32>;
9919 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
9920 def W : BaseLDOPregister<op, order, "", GPR32>;
9921 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
9922 def X : BaseLDOPregister<op, order, "", GPR64>;
9925 // Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more
9926 // complex DAG for DstRHS.
9927 let Predicates = [HasLSE] in
9928 multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op,
9929 string size, dag SrcRHS, dag DstRHS> {
9930 def : Pat<(!cast<SDNode>(op#"_"#size#"_monotonic") GPR64sp:$Rn, SrcRHS),
9931 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>;
9932 def : Pat<(!cast<SDNode>(op#"_"#size#"_acquire") GPR64sp:$Rn, SrcRHS),
9933 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>;
9934 def : Pat<(!cast<SDNode>(op#"_"#size#"_release") GPR64sp:$Rn, SrcRHS),
9935 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>;
9936 def : Pat<(!cast<SDNode>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, SrcRHS),
9937 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
9938 def : Pat<(!cast<SDNode>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, SrcRHS),
9939 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;
9942 multiclass LDOPregister_patterns_ord<string inst, string suffix, string op,
9943 string size, dag RHS> {
9944 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, RHS, RHS>;
9947 multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op,
9948 string size, dag LHS, dag RHS> {
9949 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, size, LHS, RHS>;
9952 multiclass LDOPregister_patterns<string inst, string op> {
9953 defm : LDOPregister_patterns_ord<inst, "X", op, "64", (i64 GPR64:$Rm)>;
9954 defm : LDOPregister_patterns_ord<inst, "W", op, "32", (i32 GPR32:$Rm)>;
9955 defm : LDOPregister_patterns_ord<inst, "H", op, "16", (i32 GPR32:$Rm)>;
9956 defm : LDOPregister_patterns_ord<inst, "B", op, "8", (i32 GPR32:$Rm)>;
9959 multiclass LDOPregister_patterns_mod<string inst, string op, string mod> {
9960 defm : LDOPregister_patterns_ord_mod<inst, "X", op, "64",
9962 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>;
9963 defm : LDOPregister_patterns_ord_mod<inst, "W", op, "32",
9965 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
9966 defm : LDOPregister_patterns_ord_mod<inst, "H", op, "16",
9968 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
9969 defm : LDOPregister_patterns_ord_mod<inst, "B", op, "8",
9971 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;
9974 let Predicates = [HasLSE] in
9975 multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op,
9976 string size, dag OLD, dag NEW> {
9977 def : Pat<(!cast<SDNode>(op#"_"#size#"_monotonic") GPR64sp:$Rn, OLD, NEW),
9978 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>;
9979 def : Pat<(!cast<SDNode>(op#"_"#size#"_acquire") GPR64sp:$Rn, OLD, NEW),
9980 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>;
9981 def : Pat<(!cast<SDNode>(op#"_"#size#"_release") GPR64sp:$Rn, OLD, NEW),
9982 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>;
9983 def : Pat<(!cast<SDNode>(op#"_"#size#"_acq_rel") GPR64sp:$Rn, OLD, NEW),
9984 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
9985 def : Pat<(!cast<SDNode>(op#"_"#size#"_seq_cst") GPR64sp:$Rn, OLD, NEW),
9986 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;
9989 multiclass CASregister_patterns_ord<string inst, string suffix, string op,
9990 string size, dag OLD, dag NEW> {
9991 defm : CASregister_patterns_ord_dag<inst, suffix, op, size, OLD, NEW>;
9994 multiclass CASregister_patterns<string inst, string op> {
9995 defm : CASregister_patterns_ord<inst, "X", op, "64",
9996 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>;
9997 defm : CASregister_patterns_ord<inst, "W", op, "32",
9998 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
9999 defm : CASregister_patterns_ord<inst, "H", op, "16",
10000 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
10001 defm : CASregister_patterns_ord<inst, "B", op, "8",
10002 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;
10005 let Predicates = [HasLSE] in
10006 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
10007 Instruction inst> :
10008 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
10010 multiclass STOPregister<string asm, string instr> {
10011 def : BaseSTOPregister<asm # "lb", GPR32, WZR,
10012 !cast<Instruction>(instr # "LB")>;
10013 def : BaseSTOPregister<asm # "lh", GPR32, WZR,
10014 !cast<Instruction>(instr # "LH")>;
10015 def : BaseSTOPregister<asm # "l", GPR32, WZR,
10016 !cast<Instruction>(instr # "LW")>;
10017 def : BaseSTOPregister<asm # "l", GPR64, XZR,
10018 !cast<Instruction>(instr # "LX")>;
10019 def : BaseSTOPregister<asm # "b", GPR32, WZR,
10020 !cast<Instruction>(instr # "B")>;
10021 def : BaseSTOPregister<asm # "h", GPR32, WZR,
10022 !cast<Instruction>(instr # "H")>;
10023 def : BaseSTOPregister<asm, GPR32, WZR,
10024 !cast<Instruction>(instr # "W")>;
10025 def : BaseSTOPregister<asm, GPR64, XZR,
10026 !cast<Instruction>(instr # "X")>;
10029 //----------------------------------------------------------------------------
10030 // Allow the size specifier tokens to be upper case, not just lower.
10031 def : TokenAlias<".4B", ".4b">; // Add dot product
10032 def : TokenAlias<".8B", ".8b">;
10033 def : TokenAlias<".4H", ".4h">;
10034 def : TokenAlias<".2S", ".2s">;
10035 def : TokenAlias<".1D", ".1d">;
10036 def : TokenAlias<".16B", ".16b">;
10037 def : TokenAlias<".8H", ".8h">;
10038 def : TokenAlias<".4S", ".4s">;
10039 def : TokenAlias<".2D", ".2d">;
10040 def : TokenAlias<".1Q", ".1q">;
10041 def : TokenAlias<".2H", ".2h">;
10042 def : TokenAlias<".B", ".b">;
10043 def : TokenAlias<".H", ".h">;
10044 def : TokenAlias<".S", ".s">;
10045 def : TokenAlias<".D", ".d">;
10046 def : TokenAlias<".Q", ".q">;