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"; }
193 //===----------------------------------------------------------------------===//
194 // Operand Definitions.
197 // ADR[P] instruction labels.
198 def AdrpOperand : AsmOperandClass {
199 let Name = "AdrpLabel";
200 let ParserMethod = "tryParseAdrpLabel";
201 let DiagnosticType = "InvalidLabel";
203 def adrplabel : Operand<i64> {
204 let EncoderMethod = "getAdrLabelOpValue";
205 let PrintMethod = "printAdrpLabel";
206 let ParserMatchClass = AdrpOperand;
209 def AdrOperand : AsmOperandClass {
210 let Name = "AdrLabel";
211 let ParserMethod = "tryParseAdrLabel";
212 let DiagnosticType = "InvalidLabel";
214 def adrlabel : Operand<i64> {
215 let EncoderMethod = "getAdrLabelOpValue";
216 let ParserMatchClass = AdrOperand;
219 // simm9 predicate - True if the immediate is in the range [-256, 255].
220 def SImm9Operand : AsmOperandClass {
222 let DiagnosticType = "InvalidMemoryIndexedSImm9";
224 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
225 let ParserMatchClass = SImm9Operand;
228 // simm7sN predicate - True if the immediate is a multiple of N in the range
229 // [-64 * N, 63 * N].
230 class SImm7Scaled<int Scale> : AsmOperandClass {
231 let Name = "SImm7s" # Scale;
232 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm7";
235 def SImm7s4Operand : SImm7Scaled<4>;
236 def SImm7s8Operand : SImm7Scaled<8>;
237 def SImm7s16Operand : SImm7Scaled<16>;
239 def simm7s4 : Operand<i32> {
240 let ParserMatchClass = SImm7s4Operand;
241 let PrintMethod = "printImmScale<4>";
244 def simm7s8 : Operand<i32> {
245 let ParserMatchClass = SImm7s8Operand;
246 let PrintMethod = "printImmScale<8>";
249 def simm7s16 : Operand<i32> {
250 let ParserMatchClass = SImm7s16Operand;
251 let PrintMethod = "printImmScale<16>";
254 def am_indexed7s8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>;
255 def am_indexed7s16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>;
256 def am_indexed7s32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>;
257 def am_indexed7s64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>;
258 def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>;
260 class AsmImmRange<int Low, int High> : AsmOperandClass {
261 let Name = "Imm" # Low # "_" # High;
262 let DiagnosticType = "InvalidImm" # Low # "_" # High;
263 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">";
266 def Imm1_8Operand : AsmImmRange<1, 8>;
267 def Imm1_16Operand : AsmImmRange<1, 16>;
268 def Imm1_32Operand : AsmImmRange<1, 32>;
269 def Imm1_64Operand : AsmImmRange<1, 64>;
271 class BranchTarget<int N> : AsmOperandClass {
272 let Name = "BranchTarget" # N;
273 let DiagnosticType = "InvalidLabel";
274 let PredicateMethod = "isBranchTarget<" # N # ">";
277 class PCRelLabel<int N> : BranchTarget<N> {
278 let Name = "PCRelLabel" # N;
281 def BranchTarget14Operand : BranchTarget<14>;
282 def BranchTarget26Operand : BranchTarget<26>;
283 def PCRelLabel19Operand : PCRelLabel<19>;
285 def MovZSymbolG3AsmOperand : AsmOperandClass {
286 let Name = "MovZSymbolG3";
287 let RenderMethod = "addImmOperands";
290 def movz_symbol_g3 : Operand<i32> {
291 let ParserMatchClass = MovZSymbolG3AsmOperand;
294 def MovZSymbolG2AsmOperand : AsmOperandClass {
295 let Name = "MovZSymbolG2";
296 let RenderMethod = "addImmOperands";
299 def movz_symbol_g2 : Operand<i32> {
300 let ParserMatchClass = MovZSymbolG2AsmOperand;
303 def MovZSymbolG1AsmOperand : AsmOperandClass {
304 let Name = "MovZSymbolG1";
305 let RenderMethod = "addImmOperands";
308 def movz_symbol_g1 : Operand<i32> {
309 let ParserMatchClass = MovZSymbolG1AsmOperand;
312 def MovZSymbolG0AsmOperand : AsmOperandClass {
313 let Name = "MovZSymbolG0";
314 let RenderMethod = "addImmOperands";
317 def movz_symbol_g0 : Operand<i32> {
318 let ParserMatchClass = MovZSymbolG0AsmOperand;
321 def MovKSymbolG3AsmOperand : AsmOperandClass {
322 let Name = "MovKSymbolG3";
323 let RenderMethod = "addImmOperands";
326 def movk_symbol_g3 : Operand<i32> {
327 let ParserMatchClass = MovKSymbolG3AsmOperand;
330 def MovKSymbolG2AsmOperand : AsmOperandClass {
331 let Name = "MovKSymbolG2";
332 let RenderMethod = "addImmOperands";
335 def movk_symbol_g2 : Operand<i32> {
336 let ParserMatchClass = MovKSymbolG2AsmOperand;
339 def MovKSymbolG1AsmOperand : AsmOperandClass {
340 let Name = "MovKSymbolG1";
341 let RenderMethod = "addImmOperands";
344 def movk_symbol_g1 : Operand<i32> {
345 let ParserMatchClass = MovKSymbolG1AsmOperand;
348 def MovKSymbolG0AsmOperand : AsmOperandClass {
349 let Name = "MovKSymbolG0";
350 let RenderMethod = "addImmOperands";
353 def movk_symbol_g0 : Operand<i32> {
354 let ParserMatchClass = MovKSymbolG0AsmOperand;
357 class fixedpoint_i32<ValueType FloatVT>
359 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
360 let EncoderMethod = "getFixedPointScaleOpValue";
361 let DecoderMethod = "DecodeFixedPointScaleImm32";
362 let ParserMatchClass = Imm1_32Operand;
365 class fixedpoint_i64<ValueType FloatVT>
367 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
368 let EncoderMethod = "getFixedPointScaleOpValue";
369 let DecoderMethod = "DecodeFixedPointScaleImm64";
370 let ParserMatchClass = Imm1_64Operand;
373 def fixedpoint_f16_i32 : fixedpoint_i32<f16>;
374 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
375 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
377 def fixedpoint_f16_i64 : fixedpoint_i64<f16>;
378 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
379 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
381 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
382 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
384 let EncoderMethod = "getVecShiftR8OpValue";
385 let DecoderMethod = "DecodeVecShiftR8Imm";
386 let ParserMatchClass = Imm1_8Operand;
388 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
389 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
391 let EncoderMethod = "getVecShiftR16OpValue";
392 let DecoderMethod = "DecodeVecShiftR16Imm";
393 let ParserMatchClass = Imm1_16Operand;
395 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
396 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
398 let EncoderMethod = "getVecShiftR16OpValue";
399 let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
400 let ParserMatchClass = Imm1_8Operand;
402 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
403 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
405 let EncoderMethod = "getVecShiftR32OpValue";
406 let DecoderMethod = "DecodeVecShiftR32Imm";
407 let ParserMatchClass = Imm1_32Operand;
409 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
410 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
412 let EncoderMethod = "getVecShiftR32OpValue";
413 let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
414 let ParserMatchClass = Imm1_16Operand;
416 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
417 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
419 let EncoderMethod = "getVecShiftR64OpValue";
420 let DecoderMethod = "DecodeVecShiftR64Imm";
421 let ParserMatchClass = Imm1_64Operand;
423 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
424 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
426 let EncoderMethod = "getVecShiftR64OpValue";
427 let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
428 let ParserMatchClass = Imm1_32Operand;
431 def Imm0_1Operand : AsmImmRange<0, 1>;
432 def Imm0_7Operand : AsmImmRange<0, 7>;
433 def Imm0_15Operand : AsmImmRange<0, 15>;
434 def Imm0_31Operand : AsmImmRange<0, 31>;
435 def Imm0_63Operand : AsmImmRange<0, 63>;
437 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
438 return (((uint32_t)Imm) < 8);
440 let EncoderMethod = "getVecShiftL8OpValue";
441 let DecoderMethod = "DecodeVecShiftL8Imm";
442 let ParserMatchClass = Imm0_7Operand;
444 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
445 return (((uint32_t)Imm) < 16);
447 let EncoderMethod = "getVecShiftL16OpValue";
448 let DecoderMethod = "DecodeVecShiftL16Imm";
449 let ParserMatchClass = Imm0_15Operand;
451 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
452 return (((uint32_t)Imm) < 32);
454 let EncoderMethod = "getVecShiftL32OpValue";
455 let DecoderMethod = "DecodeVecShiftL32Imm";
456 let ParserMatchClass = Imm0_31Operand;
458 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
459 return (((uint32_t)Imm) < 64);
461 let EncoderMethod = "getVecShiftL64OpValue";
462 let DecoderMethod = "DecodeVecShiftL64Imm";
463 let ParserMatchClass = Imm0_63Operand;
467 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
468 // instructions for splatting repeating bit patterns across the immediate.
469 def logical_imm32_XFORM : SDNodeXForm<imm, [{
470 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
471 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
473 def logical_imm64_XFORM : SDNodeXForm<imm, [{
474 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
475 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
478 let DiagnosticType = "LogicalSecondSource" in {
479 def LogicalImm32Operand : AsmOperandClass {
480 let Name = "LogicalImm32";
482 def LogicalImm64Operand : AsmOperandClass {
483 let Name = "LogicalImm64";
485 def LogicalImm32NotOperand : AsmOperandClass {
486 let Name = "LogicalImm32Not";
488 def LogicalImm64NotOperand : AsmOperandClass {
489 let Name = "LogicalImm64Not";
492 def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{
493 return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 32);
494 }], logical_imm32_XFORM> {
495 let PrintMethod = "printLogicalImm32";
496 let ParserMatchClass = LogicalImm32Operand;
498 def logical_imm64 : Operand<i64>, PatLeaf<(imm), [{
499 return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 64);
500 }], logical_imm64_XFORM> {
501 let PrintMethod = "printLogicalImm64";
502 let ParserMatchClass = LogicalImm64Operand;
504 def logical_imm32_not : Operand<i32> {
505 let ParserMatchClass = LogicalImm32NotOperand;
507 def logical_imm64_not : Operand<i64> {
508 let ParserMatchClass = LogicalImm64NotOperand;
511 // imm0_65535 predicate - True if the immediate is in the range [0,65535].
512 def Imm0_65535Operand : AsmImmRange<0, 65535>;
513 def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
514 return ((uint32_t)Imm) < 65536;
516 let ParserMatchClass = Imm0_65535Operand;
517 let PrintMethod = "printImmHex";
520 // imm0_255 predicate - True if the immediate is in the range [0,255].
521 def Imm0_255Operand : AsmImmRange<0,255>;
523 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
524 return ((uint32_t)Imm) < 256;
526 let ParserMatchClass = Imm0_255Operand;
527 let PrintMethod = "printImm";
530 // imm0_127 predicate - True if the immediate is in the range [0,127]
531 def Imm0_127Operand : AsmImmRange<0, 127>;
532 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
533 return ((uint32_t)Imm) < 128;
535 let ParserMatchClass = Imm0_127Operand;
536 let PrintMethod = "printImm";
539 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
540 // for all shift-amounts.
542 // imm0_63 predicate - True if the immediate is in the range [0,63]
543 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
544 return ((uint64_t)Imm) < 64;
546 let ParserMatchClass = Imm0_63Operand;
549 // imm0_31 predicate - True if the immediate is in the range [0,31]
550 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
551 return ((uint64_t)Imm) < 32;
553 let ParserMatchClass = Imm0_31Operand;
556 // True if the 32-bit immediate is in the range [0,31]
557 def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
558 return ((uint64_t)Imm) < 32;
560 let ParserMatchClass = Imm0_31Operand;
563 // imm0_1 predicate - True if the immediate is in the range [0,1]
564 def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
565 return ((uint64_t)Imm) < 2;
567 let ParserMatchClass = Imm0_1Operand;
570 // imm0_15 predicate - True if the immediate is in the range [0,15]
571 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
572 return ((uint64_t)Imm) < 16;
574 let ParserMatchClass = Imm0_15Operand;
577 // imm0_7 predicate - True if the immediate is in the range [0,7]
578 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
579 return ((uint64_t)Imm) < 8;
581 let ParserMatchClass = Imm0_7Operand;
584 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
585 def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
586 return ((uint32_t)Imm) < 16;
588 let ParserMatchClass = Imm0_15Operand;
591 // An arithmetic shifter operand:
592 // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
594 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
595 let PrintMethod = "printShifter";
596 let ParserMatchClass = !cast<AsmOperandClass>(
597 "ArithmeticShifterOperand" # width);
600 def arith_shift32 : arith_shift<i32, 32>;
601 def arith_shift64 : arith_shift<i64, 64>;
603 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
605 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
606 let PrintMethod = "printShiftedRegister";
607 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
610 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
611 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
613 // An arithmetic shifter operand:
614 // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
616 class logical_shift<int width> : Operand<i32> {
617 let PrintMethod = "printShifter";
618 let ParserMatchClass = !cast<AsmOperandClass>(
619 "LogicalShifterOperand" # width);
622 def logical_shift32 : logical_shift<32>;
623 def logical_shift64 : logical_shift<64>;
625 class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
627 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
628 let PrintMethod = "printShiftedRegister";
629 let MIOperandInfo = (ops regclass, shiftop);
632 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
633 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
635 // A logical vector shifter operand:
636 // {7-6} - shift type: 00 = lsl
637 // {5-0} - imm6: #0, #8, #16, or #24
638 def logical_vec_shift : Operand<i32> {
639 let PrintMethod = "printShifter";
640 let EncoderMethod = "getVecShifterOpValue";
641 let ParserMatchClass = LogicalVecShifterOperand;
644 // A logical vector half-word shifter operand:
645 // {7-6} - shift type: 00 = lsl
646 // {5-0} - imm6: #0 or #8
647 def logical_vec_hw_shift : Operand<i32> {
648 let PrintMethod = "printShifter";
649 let EncoderMethod = "getVecShifterOpValue";
650 let ParserMatchClass = LogicalVecHalfWordShifterOperand;
653 // A vector move shifter operand:
654 // {0} - imm1: #8 or #16
655 def move_vec_shift : Operand<i32> {
656 let PrintMethod = "printShifter";
657 let EncoderMethod = "getMoveVecShifterOpValue";
658 let ParserMatchClass = MoveVecShifterOperand;
661 let DiagnosticType = "AddSubSecondSource" in {
662 def AddSubImmOperand : AsmOperandClass {
663 let Name = "AddSubImm";
664 let ParserMethod = "tryParseAddSubImm";
666 def AddSubImmNegOperand : AsmOperandClass {
667 let Name = "AddSubImmNeg";
668 let ParserMethod = "tryParseAddSubImm";
671 // An ADD/SUB immediate shifter operand:
673 // {7-6} - shift type: 00 = lsl
674 // {5-0} - imm6: #0 or #12
675 class addsub_shifted_imm<ValueType Ty>
676 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
677 let PrintMethod = "printAddSubImm";
678 let EncoderMethod = "getAddSubImmOpValue";
679 let ParserMatchClass = AddSubImmOperand;
680 let MIOperandInfo = (ops i32imm, i32imm);
683 class addsub_shifted_imm_neg<ValueType Ty>
685 let EncoderMethod = "getAddSubImmOpValue";
686 let ParserMatchClass = AddSubImmNegOperand;
687 let MIOperandInfo = (ops i32imm, i32imm);
690 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
691 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
692 def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
693 def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
695 def gi_addsub_shifted_imm32 :
696 GIComplexOperandMatcher<s32, "selectArithImmed">,
697 GIComplexPatternEquiv<addsub_shifted_imm32>;
699 def gi_addsub_shifted_imm64 :
700 GIComplexOperandMatcher<s64, "selectArithImmed">,
701 GIComplexPatternEquiv<addsub_shifted_imm64>;
703 class neg_addsub_shifted_imm<ValueType Ty>
704 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
705 let PrintMethod = "printAddSubImm";
706 let EncoderMethod = "getAddSubImmOpValue";
707 let ParserMatchClass = AddSubImmOperand;
708 let MIOperandInfo = (ops i32imm, i32imm);
711 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
712 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
714 // An extend operand:
715 // {5-3} - extend type
717 def arith_extend : Operand<i32> {
718 let PrintMethod = "printArithExtend";
719 let ParserMatchClass = ExtendOperand;
721 def arith_extend64 : Operand<i32> {
722 let PrintMethod = "printArithExtend";
723 let ParserMatchClass = ExtendOperand64;
726 // 'extend' that's a lsl of a 64-bit register.
727 def arith_extendlsl64 : Operand<i32> {
728 let PrintMethod = "printArithExtend";
729 let ParserMatchClass = ExtendOperandLSL64;
732 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
733 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
734 let PrintMethod = "printExtendedRegister";
735 let MIOperandInfo = (ops GPR32, arith_extend);
738 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
739 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
740 let PrintMethod = "printExtendedRegister";
741 let MIOperandInfo = (ops GPR32, arith_extend64);
744 // Floating-point immediate.
745 def fpimm16 : Operand<f16>,
746 PatLeaf<(f16 fpimm), [{
747 return AArch64_AM::getFP16Imm(N->getValueAPF()) != -1;
748 }], SDNodeXForm<fpimm, [{
749 APFloat InVal = N->getValueAPF();
750 uint32_t enc = AArch64_AM::getFP16Imm(InVal);
751 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
753 let ParserMatchClass = FPImmOperand;
754 let PrintMethod = "printFPImmOperand";
756 def fpimm32 : Operand<f32>,
757 PatLeaf<(f32 fpimm), [{
758 return AArch64_AM::getFP32Imm(N->getValueAPF()) != -1;
759 }], SDNodeXForm<fpimm, [{
760 APFloat InVal = N->getValueAPF();
761 uint32_t enc = AArch64_AM::getFP32Imm(InVal);
762 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
764 let ParserMatchClass = FPImmOperand;
765 let PrintMethod = "printFPImmOperand";
767 def fpimm64 : Operand<f64>,
768 PatLeaf<(f64 fpimm), [{
769 return AArch64_AM::getFP64Imm(N->getValueAPF()) != -1;
770 }], SDNodeXForm<fpimm, [{
771 APFloat InVal = N->getValueAPF();
772 uint32_t enc = AArch64_AM::getFP64Imm(InVal);
773 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
775 let ParserMatchClass = FPImmOperand;
776 let PrintMethod = "printFPImmOperand";
779 def fpimm8 : Operand<i32> {
780 let ParserMatchClass = FPImmOperand;
781 let PrintMethod = "printFPImmOperand";
784 def fpimm0 : PatLeaf<(fpimm), [{
785 return N->isExactlyValue(+0.0);
788 // Vector lane operands
789 class AsmVectorIndex<string Suffix> : AsmOperandClass {
790 let Name = "VectorIndex" # Suffix;
791 let DiagnosticType = "InvalidIndex" # Suffix;
793 def VectorIndex1Operand : AsmVectorIndex<"1">;
794 def VectorIndexBOperand : AsmVectorIndex<"B">;
795 def VectorIndexHOperand : AsmVectorIndex<"H">;
796 def VectorIndexSOperand : AsmVectorIndex<"S">;
797 def VectorIndexDOperand : AsmVectorIndex<"D">;
799 def VectorIndex1 : Operand<i64>, ImmLeaf<i64, [{
800 return ((uint64_t)Imm) == 1;
802 let ParserMatchClass = VectorIndex1Operand;
803 let PrintMethod = "printVectorIndex";
804 let MIOperandInfo = (ops i64imm);
806 def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
807 return ((uint64_t)Imm) < 16;
809 let ParserMatchClass = VectorIndexBOperand;
810 let PrintMethod = "printVectorIndex";
811 let MIOperandInfo = (ops i64imm);
813 def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
814 return ((uint64_t)Imm) < 8;
816 let ParserMatchClass = VectorIndexHOperand;
817 let PrintMethod = "printVectorIndex";
818 let MIOperandInfo = (ops i64imm);
820 def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
821 return ((uint64_t)Imm) < 4;
823 let ParserMatchClass = VectorIndexSOperand;
824 let PrintMethod = "printVectorIndex";
825 let MIOperandInfo = (ops i64imm);
827 def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
828 return ((uint64_t)Imm) < 2;
830 let ParserMatchClass = VectorIndexDOperand;
831 let PrintMethod = "printVectorIndex";
832 let MIOperandInfo = (ops i64imm);
835 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
836 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
837 // are encoded as the eight bit value 'abcdefgh'.
838 def simdimmtype10 : Operand<i32>,
839 PatLeaf<(f64 fpimm), [{
840 return AArch64_AM::isAdvSIMDModImmType10(N->getValueAPF()
843 }], SDNodeXForm<fpimm, [{
844 APFloat InVal = N->getValueAPF();
845 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
848 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
850 let ParserMatchClass = SIMDImmType10Operand;
851 let PrintMethod = "printSIMDType10Operand";
859 // Base encoding for system instruction operands.
860 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
861 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
862 list<dag> pattern = []>
863 : I<oops, iops, asm, operands, "", pattern> {
864 let Inst{31-22} = 0b1101010100;
868 // System instructions which do not have an Rt register.
869 class SimpleSystemI<bit L, dag iops, string asm, string operands,
870 list<dag> pattern = []>
871 : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
872 let Inst{4-0} = 0b11111;
875 // System instructions which have an Rt register.
876 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
877 : BaseSystemI<L, oops, iops, asm, operands>,
883 // Hint instructions that take both a CRm and a 3-bit immediate.
884 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
885 // model patterns with sufficiently fine granularity
886 let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
887 class HintI<string mnemonic>
888 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
889 [(int_aarch64_hint imm0_127:$imm)]>,
892 let Inst{20-12} = 0b000110010;
893 let Inst{11-5} = imm;
896 // System instructions taking a single literal operand which encodes into
897 // CRm. op2 differentiates the opcodes.
898 def BarrierAsmOperand : AsmOperandClass {
899 let Name = "Barrier";
900 let ParserMethod = "tryParseBarrierOperand";
902 def barrier_op : Operand<i32> {
903 let PrintMethod = "printBarrierOption";
904 let ParserMatchClass = BarrierAsmOperand;
906 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
907 list<dag> pattern = []>
908 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
909 Sched<[WriteBarrier]> {
911 let Inst{20-12} = 0b000110011;
912 let Inst{11-8} = CRm;
916 // MRS/MSR system instructions. These have different operand classes because
917 // a different subset of registers can be accessed through each instruction.
918 def MRSSystemRegisterOperand : AsmOperandClass {
919 let Name = "MRSSystemRegister";
920 let ParserMethod = "tryParseSysReg";
921 let DiagnosticType = "MRS";
923 // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
924 def mrs_sysreg_op : Operand<i32> {
925 let ParserMatchClass = MRSSystemRegisterOperand;
926 let DecoderMethod = "DecodeMRSSystemRegister";
927 let PrintMethod = "printMRSSystemRegister";
930 def MSRSystemRegisterOperand : AsmOperandClass {
931 let Name = "MSRSystemRegister";
932 let ParserMethod = "tryParseSysReg";
933 let DiagnosticType = "MSR";
935 def msr_sysreg_op : Operand<i32> {
936 let ParserMatchClass = MSRSystemRegisterOperand;
937 let DecoderMethod = "DecodeMSRSystemRegister";
938 let PrintMethod = "printMSRSystemRegister";
941 def PSBHintOperand : AsmOperandClass {
942 let Name = "PSBHint";
943 let ParserMethod = "tryParsePSBHint";
945 def psbhint_op : Operand<i32> {
946 let ParserMatchClass = PSBHintOperand;
947 let PrintMethod = "printPSBHintOp";
948 let MCOperandPredicate = [{
949 // Check, if operand is valid, to fix exhaustive aliasing in disassembly.
950 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.
953 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;
957 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
958 "mrs", "\t$Rt, $systemreg"> {
960 let Inst{20-5} = systemreg;
963 // FIXME: Some of these def NZCV, others don't. Best way to model that?
964 // Explicitly modeling each of the system register as a register class
965 // would do it, but feels like overkill at this point.
966 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
967 "msr", "\t$systemreg, $Rt"> {
969 let Inst{20-5} = systemreg;
972 def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
973 let Name = "SystemPStateFieldWithImm0_15";
974 let ParserMethod = "tryParseSysReg";
976 def pstatefield4_op : Operand<i32> {
977 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
978 let PrintMethod = "printSystemPStateField";
982 class MSRpstateImm0_15
983 : SimpleSystemI<0, (ins pstatefield4_op:$pstatefield, imm0_15:$imm),
984 "msr", "\t$pstatefield, $imm">,
988 let Inst{20-19} = 0b00;
989 let Inst{18-16} = pstatefield{5-3};
990 let Inst{15-12} = 0b0100;
991 let Inst{11-8} = imm;
992 let Inst{7-5} = pstatefield{2-0};
994 let DecoderMethod = "DecodeSystemPStateInstruction";
995 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
996 // Fail the decoder should attempt to decode the instruction as MSRI.
997 let hasCompleteDecoder = 0;
1000 def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
1001 let Name = "SystemPStateFieldWithImm0_1";
1002 let ParserMethod = "tryParseSysReg";
1004 def pstatefield1_op : Operand<i32> {
1005 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
1006 let PrintMethod = "printSystemPStateField";
1009 let Defs = [NZCV] in
1010 class MSRpstateImm0_1
1011 : SimpleSystemI<0, (ins pstatefield1_op:$pstatefield, imm0_1:$imm),
1012 "msr", "\t$pstatefield, $imm">,
1014 bits<6> pstatefield;
1016 let Inst{20-19} = 0b00;
1017 let Inst{18-16} = pstatefield{5-3};
1018 let Inst{15-9} = 0b0100000;
1020 let Inst{7-5} = pstatefield{2-0};
1022 let DecoderMethod = "DecodeSystemPStateInstruction";
1023 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
1024 // Fail the decoder should attempt to decode the instruction as MSRI.
1025 let hasCompleteDecoder = 0;
1028 // SYS and SYSL generic system instructions.
1029 def SysCRAsmOperand : AsmOperandClass {
1031 let ParserMethod = "tryParseSysCROperand";
1034 def sys_cr_op : Operand<i32> {
1035 let PrintMethod = "printSysCROperand";
1036 let ParserMatchClass = SysCRAsmOperand;
1039 class SystemXtI<bit L, string asm>
1040 : RtSystemI<L, (outs),
1041 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
1042 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
1047 let Inst{20-19} = 0b01;
1048 let Inst{18-16} = op1;
1049 let Inst{15-12} = Cn;
1050 let Inst{11-8} = Cm;
1051 let Inst{7-5} = op2;
1054 class SystemLXtI<bit L, string asm>
1055 : RtSystemI<L, (outs),
1056 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
1057 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
1062 let Inst{20-19} = 0b01;
1063 let Inst{18-16} = op1;
1064 let Inst{15-12} = Cn;
1065 let Inst{11-8} = Cm;
1066 let Inst{7-5} = op2;
1070 // Branch (register) instructions:
1078 // otherwise UNDEFINED
1079 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
1080 string operands, list<dag> pattern>
1081 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
1082 let Inst{31-25} = 0b1101011;
1083 let Inst{24-21} = opc;
1084 let Inst{20-16} = 0b11111;
1085 let Inst{15-10} = 0b000000;
1086 let Inst{4-0} = 0b00000;
1089 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
1090 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
1095 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
1096 class SpecialReturn<bits<4> opc, string asm>
1097 : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1098 let Inst{9-5} = 0b11111;
1102 // Conditional branch instruction.
1106 // 4-bit immediate. Pretty-printed as <cc>
1107 def ccode : Operand<i32> {
1108 let PrintMethod = "printCondCode";
1109 let ParserMatchClass = CondCode;
1111 def inv_ccode : Operand<i32> {
1112 // AL and NV are invalid in the aliases which use inv_ccode
1113 let PrintMethod = "printInverseCondCode";
1114 let ParserMatchClass = CondCode;
1115 let MCOperandPredicate = [{
1116 return MCOp.isImm() &&
1117 MCOp.getImm() != AArch64CC::AL &&
1118 MCOp.getImm() != AArch64CC::NV;
1122 // Conditional branch target. 19-bit immediate. The low two bits of the target
1123 // offset are implied zero and so are not part of the immediate.
1124 def am_brcond : Operand<OtherVT> {
1125 let EncoderMethod = "getCondBranchTargetOpValue";
1126 let DecoderMethod = "DecodePCRelLabel19";
1127 let PrintMethod = "printAlignedLabel";
1128 let ParserMatchClass = PCRelLabel19Operand;
1131 class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1132 "b", ".$cond\t$target", "",
1133 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1136 let isTerminator = 1;
1141 let Inst{31-24} = 0b01010100;
1142 let Inst{23-5} = target;
1144 let Inst{3-0} = cond;
1148 // Compare-and-branch instructions.
1150 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1151 : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1152 asm, "\t$Rt, $target", "",
1153 [(node regtype:$Rt, bb:$target)]>,
1156 let isTerminator = 1;
1160 let Inst{30-25} = 0b011010;
1162 let Inst{23-5} = target;
1166 multiclass CmpBranch<bit op, string asm, SDNode node> {
1167 def W : BaseCmpBranch<GPR32, op, asm, node> {
1170 def X : BaseCmpBranch<GPR64, op, asm, node> {
1176 // Test-bit-and-branch instructions.
1178 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1179 // the target offset are implied zero and so are not part of the immediate.
1180 def am_tbrcond : Operand<OtherVT> {
1181 let EncoderMethod = "getTestBranchTargetOpValue";
1182 let PrintMethod = "printAlignedLabel";
1183 let ParserMatchClass = BranchTarget14Operand;
1186 // AsmOperand classes to emit (or not) special diagnostics
1187 def TBZImm0_31Operand : AsmOperandClass {
1188 let Name = "TBZImm0_31";
1189 let PredicateMethod = "isImmInRange<0,31>";
1190 let RenderMethod = "addImm0_31Operands";
1192 def TBZImm32_63Operand : AsmOperandClass {
1193 let Name = "Imm32_63";
1194 let PredicateMethod = "isImmInRange<32,63>";
1195 let DiagnosticType = "InvalidImm0_63";
1198 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1199 return (((uint32_t)Imm) < 32);
1201 let ParserMatchClass = matcher;
1204 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1205 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1207 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1208 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1210 let ParserMatchClass = TBZImm32_63Operand;
1213 class BaseTestBranch<RegisterClass regtype, Operand immtype,
1214 bit op, string asm, SDNode node>
1215 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1216 asm, "\t$Rt, $bit_off, $target", "",
1217 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1220 let isTerminator = 1;
1226 let Inst{30-25} = 0b011011;
1228 let Inst{23-19} = bit_off{4-0};
1229 let Inst{18-5} = target;
1232 let DecoderMethod = "DecodeTestAndBranch";
1235 multiclass TestBranch<bit op, string asm, SDNode node> {
1236 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1240 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1244 // Alias X-reg with 0-31 imm to W-Reg.
1245 def : InstAlias<asm # "\t$Rd, $imm, $target",
1246 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1247 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1248 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1249 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1250 tbz_imm0_31_diag:$imm, bb:$target)>;
1254 // Unconditional branch (immediate) instructions.
1256 def am_b_target : Operand<OtherVT> {
1257 let EncoderMethod = "getBranchTargetOpValue";
1258 let PrintMethod = "printAlignedLabel";
1259 let ParserMatchClass = BranchTarget26Operand;
1261 def am_bl_target : Operand<i64> {
1262 let EncoderMethod = "getBranchTargetOpValue";
1263 let PrintMethod = "printAlignedLabel";
1264 let ParserMatchClass = BranchTarget26Operand;
1267 class BImm<bit op, dag iops, string asm, list<dag> pattern>
1268 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1271 let Inst{30-26} = 0b00101;
1272 let Inst{25-0} = addr;
1274 let DecoderMethod = "DecodeUnconditionalBranch";
1277 class BranchImm<bit op, string asm, list<dag> pattern>
1278 : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1279 class CallImm<bit op, string asm, list<dag> pattern>
1280 : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1283 // Basic one-operand data processing instructions.
1286 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1287 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1288 SDPatternOperator node>
1289 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1290 [(set regtype:$Rd, (node regtype:$Rn))]>,
1291 Sched<[WriteI, ReadI]> {
1295 let Inst{30-13} = 0b101101011000000000;
1296 let Inst{12-10} = opc;
1301 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1302 multiclass OneOperandData<bits<3> opc, string asm,
1303 SDPatternOperator node = null_frag> {
1304 def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1308 def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1313 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1314 : BaseOneOperandData<opc, GPR32, asm, node> {
1318 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1319 : BaseOneOperandData<opc, GPR64, asm, node> {
1324 // Basic two-operand data processing instructions.
1326 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1328 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1329 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1330 Sched<[WriteI, ReadI, ReadI]> {
1335 let Inst{30} = isSub;
1336 let Inst{28-21} = 0b11010000;
1337 let Inst{20-16} = Rm;
1338 let Inst{15-10} = 0;
1343 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1345 : BaseBaseAddSubCarry<isSub, regtype, asm,
1346 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1348 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1350 : BaseBaseAddSubCarry<isSub, regtype, asm,
1351 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1356 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1357 SDNode OpNode, SDNode OpNode_setflags> {
1358 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1362 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1368 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1373 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1380 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1381 SDPatternOperator OpNode>
1382 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1383 asm, "\t$Rd, $Rn, $Rm", "",
1384 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
1388 let Inst{30-21} = 0b0011010110;
1389 let Inst{20-16} = Rm;
1390 let Inst{15-14} = 0b00;
1391 let Inst{13-10} = opc;
1396 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1397 SDPatternOperator OpNode>
1398 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1399 let Inst{10} = isSigned;
1402 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1403 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1404 Sched<[WriteID32, ReadID, ReadID]> {
1407 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1408 Sched<[WriteID64, ReadID, ReadID]> {
1413 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1414 SDPatternOperator OpNode = null_frag>
1415 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1416 Sched<[WriteIS, ReadI]> {
1417 let Inst{11-10} = shift_type;
1420 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
1421 def Wr : BaseShift<shift_type, GPR32, asm> {
1425 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1429 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1430 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1431 (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1433 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1434 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1436 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1437 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1439 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1440 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1443 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
1444 : InstAlias<asm#"\t$dst, $src1, $src2",
1445 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
1447 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1448 RegisterClass addtype, string asm,
1450 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1451 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1456 let Inst{30-24} = 0b0011011;
1457 let Inst{23-21} = opc;
1458 let Inst{20-16} = Rm;
1459 let Inst{15} = isSub;
1460 let Inst{14-10} = Ra;
1465 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
1466 // MADD/MSUB generation is decided by MachineCombiner.cpp
1467 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
1468 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
1469 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1473 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
1474 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
1475 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
1480 class WideMulAccum<bit isSub, bits<3> opc, string asm,
1481 SDNode AccNode, SDNode ExtNode>
1482 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
1483 [(set GPR64:$Rd, (AccNode GPR64:$Ra,
1484 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
1485 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1489 class MulHi<bits<3> opc, string asm, SDNode OpNode>
1490 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
1491 asm, "\t$Rd, $Rn, $Rm", "",
1492 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
1493 Sched<[WriteIM64, ReadIM, ReadIM]> {
1497 let Inst{31-24} = 0b10011011;
1498 let Inst{23-21} = opc;
1499 let Inst{20-16} = Rm;
1504 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
1505 // (i.e. all bits 1) but is ignored by the processor.
1506 let PostEncoderMethod = "fixMulHigh";
1509 class MulAccumWAlias<string asm, Instruction inst>
1510 : InstAlias<asm#"\t$dst, $src1, $src2",
1511 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
1512 class MulAccumXAlias<string asm, Instruction inst>
1513 : InstAlias<asm#"\t$dst, $src1, $src2",
1514 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
1515 class WideMulAccumAlias<string asm, Instruction inst>
1516 : InstAlias<asm#"\t$dst, $src1, $src2",
1517 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
1519 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
1520 SDPatternOperator OpNode, string asm>
1521 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
1522 asm, "\t$Rd, $Rn, $Rm", "",
1523 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
1524 Sched<[WriteISReg, ReadI, ReadISReg]> {
1530 let Inst{30-21} = 0b0011010110;
1531 let Inst{20-16} = Rm;
1532 let Inst{15-13} = 0b010;
1534 let Inst{11-10} = sz;
1537 let Predicates = [HasCRC];
1541 // Address generation.
1544 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
1545 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
1550 let Inst{31} = page;
1551 let Inst{30-29} = label{1-0};
1552 let Inst{28-24} = 0b10000;
1553 let Inst{23-5} = label{20-2};
1556 let DecoderMethod = "DecodeAdrInstruction";
1563 def movimm32_imm : Operand<i32> {
1564 let ParserMatchClass = Imm0_65535Operand;
1565 let EncoderMethod = "getMoveWideImmOpValue";
1566 let PrintMethod = "printImm";
1568 def movimm32_shift : Operand<i32> {
1569 let PrintMethod = "printShifter";
1570 let ParserMatchClass = MovImm32ShifterOperand;
1572 def movimm64_shift : Operand<i32> {
1573 let PrintMethod = "printShifter";
1574 let ParserMatchClass = MovImm64ShifterOperand;
1577 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1578 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1580 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
1581 asm, "\t$Rd, $imm$shift", "", []>,
1586 let Inst{30-29} = opc;
1587 let Inst{28-23} = 0b100101;
1588 let Inst{22-21} = shift{5-4};
1589 let Inst{20-5} = imm;
1592 let DecoderMethod = "DecodeMoveImmInstruction";
1595 multiclass MoveImmediate<bits<2> opc, string asm> {
1596 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
1600 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
1605 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1606 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1608 : I<(outs regtype:$Rd),
1609 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
1610 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
1611 Sched<[WriteI, ReadI]> {
1615 let Inst{30-29} = opc;
1616 let Inst{28-23} = 0b100101;
1617 let Inst{22-21} = shift{5-4};
1618 let Inst{20-5} = imm;
1621 let DecoderMethod = "DecodeMoveImmInstruction";
1624 multiclass InsertImmediate<bits<2> opc, string asm> {
1625 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
1629 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
1638 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
1639 RegisterClass srcRegtype, addsub_shifted_imm immtype,
1640 string asm, SDPatternOperator OpNode>
1641 : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
1642 asm, "\t$Rd, $Rn, $imm", "",
1643 [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
1644 Sched<[WriteI, ReadI]> {
1648 let Inst{30} = isSub;
1649 let Inst{29} = setFlags;
1650 let Inst{28-24} = 0b10001;
1651 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
1652 let Inst{21-10} = imm{11-0};
1655 let DecoderMethod = "DecodeBaseAddSubImm";
1658 class BaseAddSubRegPseudo<RegisterClass regtype,
1659 SDPatternOperator OpNode>
1660 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1661 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1662 Sched<[WriteI, ReadI, ReadI]>;
1664 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
1665 arith_shifted_reg shifted_regtype, string asm,
1666 SDPatternOperator OpNode>
1667 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1668 asm, "\t$Rd, $Rn, $Rm", "",
1669 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
1670 Sched<[WriteISReg, ReadI, ReadISReg]> {
1671 // The operands are in order to match the 'addr' MI operands, so we
1672 // don't need an encoder method and by-name matching. Just use the default
1673 // in-order handling. Since we're using by-order, make sure the names
1679 let Inst{30} = isSub;
1680 let Inst{29} = setFlags;
1681 let Inst{28-24} = 0b01011;
1682 let Inst{23-22} = shift{7-6};
1684 let Inst{20-16} = src2;
1685 let Inst{15-10} = shift{5-0};
1686 let Inst{9-5} = src1;
1687 let Inst{4-0} = dst;
1689 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1692 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
1693 RegisterClass src1Regtype, Operand src2Regtype,
1694 string asm, SDPatternOperator OpNode>
1695 : I<(outs dstRegtype:$R1),
1696 (ins src1Regtype:$R2, src2Regtype:$R3),
1697 asm, "\t$R1, $R2, $R3", "",
1698 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
1699 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1704 let Inst{30} = isSub;
1705 let Inst{29} = setFlags;
1706 let Inst{28-24} = 0b01011;
1707 let Inst{23-21} = 0b001;
1708 let Inst{20-16} = Rm;
1709 let Inst{15-13} = ext{5-3};
1710 let Inst{12-10} = ext{2-0};
1714 let DecoderMethod = "DecodeAddSubERegInstruction";
1717 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1718 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
1719 RegisterClass src1Regtype, RegisterClass src2Regtype,
1720 Operand ext_op, string asm>
1721 : I<(outs dstRegtype:$Rd),
1722 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
1723 asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
1724 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1729 let Inst{30} = isSub;
1730 let Inst{29} = setFlags;
1731 let Inst{28-24} = 0b01011;
1732 let Inst{23-21} = 0b001;
1733 let Inst{20-16} = Rm;
1734 let Inst{15} = ext{5};
1735 let Inst{12-10} = ext{2-0};
1739 let DecoderMethod = "DecodeAddSubERegInstruction";
1742 // Aliases for register+register add/subtract.
1743 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
1744 RegisterClass src1Regtype, RegisterClass src2Regtype,
1746 : InstAlias<asm#"\t$dst, $src1, $src2",
1747 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
1750 multiclass AddSub<bit isSub, string mnemonic, string alias,
1751 SDPatternOperator OpNode = null_frag> {
1752 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1753 // Add/Subtract immediate
1754 // Increase the weight of the immediate variant to try to match it before
1755 // the extended register variant.
1756 // We used to match the register variant before the immediate when the
1757 // register argument could be implicitly zero-extended.
1758 let AddedComplexity = 6 in
1759 def Wri : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
1763 let AddedComplexity = 6 in
1764 def Xri : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
1769 // Add/Subtract register - Only used for CodeGen
1770 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1771 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1773 // Add/Subtract shifted register
1774 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
1778 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
1784 // Add/Subtract extended register
1785 let AddedComplexity = 1, hasSideEffects = 0 in {
1786 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
1787 arith_extended_reg32<i32>, mnemonic, OpNode> {
1790 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
1791 arith_extended_reg32to64<i64>, mnemonic, OpNode> {
1796 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
1797 arith_extendlsl64, mnemonic> {
1798 // UXTX and SXTX only.
1799 let Inst{14-13} = 0b11;
1803 // add Rd, Rb, -imm -> sub Rd, Rn, imm
1804 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
1805 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
1806 addsub_shifted_imm32_neg:$imm), 0>;
1807 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
1808 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
1809 addsub_shifted_imm64_neg:$imm), 0>;
1811 // Register/register aliases with no shift when SP is not used.
1812 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1813 GPR32, GPR32, GPR32, 0>;
1814 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1815 GPR64, GPR64, GPR64, 0>;
1817 // Register/register aliases with no shift when either the destination or
1818 // first source register is SP.
1819 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1820 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
1821 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1822 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
1823 def : AddSubRegAlias<mnemonic,
1824 !cast<Instruction>(NAME#"Xrx64"),
1825 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
1826 def : AddSubRegAlias<mnemonic,
1827 !cast<Instruction>(NAME#"Xrx64"),
1828 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
1831 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
1832 string alias, string cmpAlias> {
1833 let isCompare = 1, Defs = [NZCV] in {
1834 // Add/Subtract immediate
1835 def Wri : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
1839 def Xri : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
1844 // Add/Subtract register
1845 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1846 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1848 // Add/Subtract shifted register
1849 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
1853 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
1858 // Add/Subtract extended register
1859 let AddedComplexity = 1 in {
1860 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
1861 arith_extended_reg32<i32>, mnemonic, OpNode> {
1864 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
1865 arith_extended_reg32<i64>, mnemonic, OpNode> {
1870 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
1871 arith_extendlsl64, mnemonic> {
1872 // UXTX and SXTX only.
1873 let Inst{14-13} = 0b11;
1878 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
1879 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
1880 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
1881 addsub_shifted_imm32_neg:$imm), 0>;
1882 def : InstSubst<alias#"\t$Rd, $Rn, $imm",
1883 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
1884 addsub_shifted_imm64_neg:$imm), 0>;
1887 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
1888 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
1889 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
1890 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
1891 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
1892 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
1893 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
1894 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
1895 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
1896 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
1897 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
1898 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
1899 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
1900 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
1902 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
1903 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
1904 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
1905 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
1906 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
1908 // Compare shorthands
1909 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
1910 WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
1911 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
1912 XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
1913 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
1914 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
1915 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
1916 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
1918 // Register/register aliases with no shift when SP is not used.
1919 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1920 GPR32, GPR32, GPR32, 0>;
1921 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1922 GPR64, GPR64, GPR64, 0>;
1924 // Register/register aliases with no shift when the first source register
1926 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1927 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
1928 def : AddSubRegAlias<mnemonic,
1929 !cast<Instruction>(NAME#"Xrx64"),
1930 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
1936 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1938 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
1940 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
1942 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
1943 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
1944 Sched<[WriteExtr, ReadExtrHi]> {
1950 let Inst{30-23} = 0b00100111;
1952 let Inst{20-16} = Rm;
1953 let Inst{15-10} = imm;
1958 multiclass ExtractImm<string asm> {
1959 def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
1961 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
1964 // imm<5> must be zero.
1967 def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
1969 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
1980 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1981 class BaseBitfieldImm<bits<2> opc,
1982 RegisterClass regtype, Operand imm_type, string asm>
1983 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
1984 asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
1985 Sched<[WriteIS, ReadI]> {
1991 let Inst{30-29} = opc;
1992 let Inst{28-23} = 0b100110;
1993 let Inst{21-16} = immr;
1994 let Inst{15-10} = imms;
1999 multiclass BitfieldImm<bits<2> opc, string asm> {
2000 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
2003 // imms<5> and immr<5> must be zero, else ReservedValue().
2007 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
2013 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2014 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
2015 RegisterClass regtype, Operand imm_type, string asm>
2016 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
2018 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
2019 Sched<[WriteIS, ReadI]> {
2025 let Inst{30-29} = opc;
2026 let Inst{28-23} = 0b100110;
2027 let Inst{21-16} = immr;
2028 let Inst{15-10} = imms;
2033 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
2034 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
2037 // imms<5> and immr<5> must be zero, else ReservedValue().
2041 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
2051 // Logical (immediate)
2052 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
2053 RegisterClass sregtype, Operand imm_type, string asm,
2055 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
2056 asm, "\t$Rd, $Rn, $imm", "", pattern>,
2057 Sched<[WriteI, ReadI]> {
2061 let Inst{30-29} = opc;
2062 let Inst{28-23} = 0b100100;
2063 let Inst{22} = imm{12};
2064 let Inst{21-16} = imm{11-6};
2065 let Inst{15-10} = imm{5-0};
2069 let DecoderMethod = "DecodeLogicalImmInstruction";
2072 // Logical (shifted register)
2073 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
2074 logical_shifted_reg shifted_regtype, string asm,
2076 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2077 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2078 Sched<[WriteISReg, ReadI, ReadISReg]> {
2079 // The operands are in order to match the 'addr' MI operands, so we
2080 // don't need an encoder method and by-name matching. Just use the default
2081 // in-order handling. Since we're using by-order, make sure the names
2087 let Inst{30-29} = opc;
2088 let Inst{28-24} = 0b01010;
2089 let Inst{23-22} = shift{7-6};
2091 let Inst{20-16} = src2;
2092 let Inst{15-10} = shift{5-0};
2093 let Inst{9-5} = src1;
2094 let Inst{4-0} = dst;
2096 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2099 // Aliases for register+register logical instructions.
2100 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
2101 : InstAlias<asm#"\t$dst, $src1, $src2",
2102 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2104 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2106 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2107 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2108 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2109 logical_imm32:$imm))]> {
2111 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2113 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2114 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2115 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2116 logical_imm64:$imm))]> {
2120 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2121 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2122 logical_imm32_not:$imm), 0>;
2123 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2124 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2125 logical_imm64_not:$imm), 0>;
2128 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2130 let isCompare = 1, Defs = [NZCV] in {
2131 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2132 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2134 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2136 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2137 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2140 } // end Defs = [NZCV]
2142 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2143 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2144 logical_imm32_not:$imm), 0>;
2145 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",
2146 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2147 logical_imm64_not:$imm), 0>;
2150 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2151 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2152 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2153 Sched<[WriteI, ReadI, ReadI]>;
2155 // Split from LogicalImm as not all instructions have both.
2156 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2157 SDPatternOperator OpNode> {
2158 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2159 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2160 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2163 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2164 [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2165 logical_shifted_reg32:$Rm))]> {
2168 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2169 [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2170 logical_shifted_reg64:$Rm))]> {
2174 def : LogicalRegAlias<mnemonic,
2175 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2176 def : LogicalRegAlias<mnemonic,
2177 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2180 // Split from LogicalReg to allow setting NZCV Defs
2181 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2182 SDPatternOperator OpNode = null_frag> {
2183 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2184 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2185 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2187 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2188 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2191 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2192 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2197 def : LogicalRegAlias<mnemonic,
2198 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2199 def : LogicalRegAlias<mnemonic,
2200 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2204 // Conditionally set flags
2207 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2208 class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2209 string mnemonic, SDNode OpNode>
2210 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2211 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2212 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2213 (i32 imm:$cond), NZCV))]>,
2214 Sched<[WriteI, ReadI]> {
2224 let Inst{29-21} = 0b111010010;
2225 let Inst{20-16} = imm;
2226 let Inst{15-12} = cond;
2227 let Inst{11-10} = 0b10;
2230 let Inst{3-0} = nzcv;
2233 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2234 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2236 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2237 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2238 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2239 (i32 imm:$cond), NZCV))]>,
2240 Sched<[WriteI, ReadI, ReadI]> {
2250 let Inst{29-21} = 0b111010010;
2251 let Inst{20-16} = Rm;
2252 let Inst{15-12} = cond;
2253 let Inst{11-10} = 0b00;
2256 let Inst{3-0} = nzcv;
2259 multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
2260 // immediate operand variants
2261 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
2264 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
2267 // register operand variants
2268 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
2271 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
2277 // Conditional select
2280 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2281 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2282 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2284 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2285 Sched<[WriteI, ReadI, ReadI]> {
2294 let Inst{29-21} = 0b011010100;
2295 let Inst{20-16} = Rm;
2296 let Inst{15-12} = cond;
2297 let Inst{11-10} = op2;
2302 multiclass CondSelect<bit op, bits<2> op2, string asm> {
2303 def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2306 def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2311 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2313 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2314 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2316 (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2317 (i32 imm:$cond), NZCV))]>,
2318 Sched<[WriteI, ReadI, ReadI]> {
2327 let Inst{29-21} = 0b011010100;
2328 let Inst{20-16} = Rm;
2329 let Inst{15-12} = cond;
2330 let Inst{11-10} = op2;
2335 def inv_cond_XFORM : SDNodeXForm<imm, [{
2336 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
2337 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
2341 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
2342 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
2345 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
2349 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
2350 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
2351 (inv_cond_XFORM imm:$cond))>;
2353 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
2354 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
2355 (inv_cond_XFORM imm:$cond))>;
2359 // Special Mask Value
2361 def maski8_or_more : Operand<i32>,
2362 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
2364 def maski16_or_more : Operand<i32>,
2365 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
2373 // (unsigned immediate)
2374 // Indexed for 8-bit registers. offset is in range [0,4095].
2375 def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
2376 def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
2377 def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
2378 def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
2379 def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
2381 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
2382 let Name = "UImm12Offset" # Scale;
2383 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
2384 let PredicateMethod = "isUImm12Offset<" # Scale # ">";
2385 let DiagnosticType = "InvalidMemoryIndexed" # Scale;
2388 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
2389 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
2390 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
2391 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
2392 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
2394 class uimm12_scaled<int Scale> : Operand<i64> {
2395 let ParserMatchClass
2396 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
2398 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
2399 let PrintMethod = "printUImm12Offset<" # Scale # ">";
2402 def uimm12s1 : uimm12_scaled<1>;
2403 def uimm12s2 : uimm12_scaled<2>;
2404 def uimm12s4 : uimm12_scaled<4>;
2405 def uimm12s8 : uimm12_scaled<8>;
2406 def uimm12s16 : uimm12_scaled<16>;
2408 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2409 string asm, list<dag> pattern>
2410 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2416 let Inst{31-30} = sz;
2417 let Inst{29-27} = 0b111;
2419 let Inst{25-24} = 0b01;
2420 let Inst{23-22} = opc;
2421 let Inst{21-10} = offset;
2425 let DecoderMethod = "DecodeUnsignedLdStInstruction";
2428 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2429 Operand indextype, string asm, list<dag> pattern> {
2430 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2431 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
2432 (ins GPR64sp:$Rn, indextype:$offset),
2436 def : InstAlias<asm # "\t$Rt, [$Rn]",
2437 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2440 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2441 Operand indextype, string asm, list<dag> pattern> {
2442 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2443 def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2444 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2448 def : InstAlias<asm # "\t$Rt, [$Rn]",
2449 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2452 def PrefetchOperand : AsmOperandClass {
2453 let Name = "Prefetch";
2454 let ParserMethod = "tryParsePrefetch";
2456 def prfop : Operand<i32> {
2457 let PrintMethod = "printPrefetchOp";
2458 let ParserMatchClass = PrefetchOperand;
2461 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2462 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2463 : BaseLoadStoreUI<sz, V, opc,
2464 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
2472 // Load literal address: 19-bit immediate. The low two bits of the target
2473 // offset are implied zero and so are not part of the immediate.
2474 def am_ldrlit : Operand<iPTR> {
2475 let EncoderMethod = "getLoadLiteralOpValue";
2476 let DecoderMethod = "DecodePCRelLabel19";
2477 let PrintMethod = "printAlignedLabel";
2478 let ParserMatchClass = PCRelLabel19Operand;
2481 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2482 class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
2483 : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
2484 asm, "\t$Rt, $label", "", []>,
2488 let Inst{31-30} = opc;
2489 let Inst{29-27} = 0b011;
2491 let Inst{25-24} = 0b00;
2492 let Inst{23-5} = label;
2496 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2497 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
2498 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
2499 asm, "\t$Rt, $label", "", pat>,
2503 let Inst{31-30} = opc;
2504 let Inst{29-27} = 0b011;
2506 let Inst{25-24} = 0b00;
2507 let Inst{23-5} = label;
2512 // Load/store register offset
2515 def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
2516 def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
2517 def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
2518 def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
2519 def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
2521 def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
2522 def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
2523 def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
2524 def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
2525 def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
2527 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
2528 let Name = "Mem" # Reg # "Extend" # Width;
2529 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
2530 let RenderMethod = "addMemExtendOperands";
2531 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
2534 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
2535 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2536 // the trivial shift.
2537 let RenderMethod = "addMemExtend8Operands";
2539 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
2540 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
2541 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
2542 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
2544 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
2545 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2546 // the trivial shift.
2547 let RenderMethod = "addMemExtend8Operands";
2549 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
2550 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
2551 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
2552 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
2554 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
2556 let ParserMatchClass = ParserClass;
2557 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
2558 let DecoderMethod = "DecodeMemExtend";
2559 let EncoderMethod = "getMemExtendOpValue";
2560 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
2563 def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>;
2564 def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>;
2565 def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>;
2566 def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>;
2567 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
2569 def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>;
2570 def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>;
2571 def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>;
2572 def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>;
2573 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
2575 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
2576 Operand wextend, Operand xextend> {
2577 // CodeGen-level pattern covering the entire addressing mode.
2578 ComplexPattern Wpat = windex;
2579 ComplexPattern Xpat = xindex;
2581 // Asm-level Operand covering the valid "uxtw #3" style syntax.
2582 Operand Wext = wextend;
2583 Operand Xext = xextend;
2586 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
2587 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
2588 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
2589 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
2590 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
2593 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2594 string asm, dag ins, dag outs, list<dag> pat>
2595 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2600 let Inst{31-30} = sz;
2601 let Inst{29-27} = 0b111;
2603 let Inst{25-24} = 0b00;
2604 let Inst{23-22} = opc;
2606 let Inst{20-16} = Rm;
2607 let Inst{15} = extend{1}; // sign extend Rm?
2609 let Inst{12} = extend{0}; // do shift?
2610 let Inst{11-10} = 0b10;
2615 class ROInstAlias<string asm, RegisterClass regtype, Instruction INST>
2616 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
2617 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2619 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2620 string asm, ValueType Ty, SDPatternOperator loadop> {
2621 let AddedComplexity = 10 in
2622 def roW : LoadStore8RO<sz, V, opc, regtype, asm,
2624 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2625 [(set (Ty regtype:$Rt),
2626 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2627 ro_Wextend8:$extend)))]>,
2628 Sched<[WriteLDIdx, ReadAdrBase]> {
2632 let AddedComplexity = 10 in
2633 def roX : LoadStore8RO<sz, V, opc, regtype, asm,
2635 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2636 [(set (Ty regtype:$Rt),
2637 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2638 ro_Xextend8:$extend)))]>,
2639 Sched<[WriteLDIdx, ReadAdrBase]> {
2643 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2646 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2647 string asm, ValueType Ty, SDPatternOperator storeop> {
2648 let AddedComplexity = 10 in
2649 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2650 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2651 [(storeop (Ty regtype:$Rt),
2652 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2653 ro_Wextend8:$extend))]>,
2654 Sched<[WriteSTIdx, ReadAdrBase]> {
2658 let AddedComplexity = 10 in
2659 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2660 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2661 [(storeop (Ty regtype:$Rt),
2662 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2663 ro_Xextend8:$extend))]>,
2664 Sched<[WriteSTIdx, ReadAdrBase]> {
2668 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2671 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2672 string asm, dag ins, dag outs, list<dag> pat>
2673 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2678 let Inst{31-30} = sz;
2679 let Inst{29-27} = 0b111;
2681 let Inst{25-24} = 0b00;
2682 let Inst{23-22} = opc;
2684 let Inst{20-16} = Rm;
2685 let Inst{15} = extend{1}; // sign extend Rm?
2687 let Inst{12} = extend{0}; // do shift?
2688 let Inst{11-10} = 0b10;
2693 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2694 string asm, ValueType Ty, SDPatternOperator loadop> {
2695 let AddedComplexity = 10 in
2696 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2697 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2698 [(set (Ty regtype:$Rt),
2699 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2700 ro_Wextend16:$extend)))]>,
2701 Sched<[WriteLDIdx, ReadAdrBase]> {
2705 let AddedComplexity = 10 in
2706 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2707 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2708 [(set (Ty regtype:$Rt),
2709 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2710 ro_Xextend16:$extend)))]>,
2711 Sched<[WriteLDIdx, ReadAdrBase]> {
2715 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2718 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2719 string asm, ValueType Ty, SDPatternOperator storeop> {
2720 let AddedComplexity = 10 in
2721 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2722 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2723 [(storeop (Ty regtype:$Rt),
2724 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2725 ro_Wextend16:$extend))]>,
2726 Sched<[WriteSTIdx, ReadAdrBase]> {
2730 let AddedComplexity = 10 in
2731 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2732 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2733 [(storeop (Ty regtype:$Rt),
2734 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2735 ro_Xextend16:$extend))]>,
2736 Sched<[WriteSTIdx, ReadAdrBase]> {
2740 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2743 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2744 string asm, dag ins, dag outs, list<dag> pat>
2745 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2750 let Inst{31-30} = sz;
2751 let Inst{29-27} = 0b111;
2753 let Inst{25-24} = 0b00;
2754 let Inst{23-22} = opc;
2756 let Inst{20-16} = Rm;
2757 let Inst{15} = extend{1}; // sign extend Rm?
2759 let Inst{12} = extend{0}; // do shift?
2760 let Inst{11-10} = 0b10;
2765 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2766 string asm, ValueType Ty, SDPatternOperator loadop> {
2767 let AddedComplexity = 10 in
2768 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2769 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2770 [(set (Ty regtype:$Rt),
2771 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2772 ro_Wextend32:$extend)))]>,
2773 Sched<[WriteLDIdx, ReadAdrBase]> {
2777 let AddedComplexity = 10 in
2778 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2779 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2780 [(set (Ty regtype:$Rt),
2781 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2782 ro_Xextend32:$extend)))]>,
2783 Sched<[WriteLDIdx, ReadAdrBase]> {
2787 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2790 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2791 string asm, ValueType Ty, SDPatternOperator storeop> {
2792 let AddedComplexity = 10 in
2793 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2794 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2795 [(storeop (Ty regtype:$Rt),
2796 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2797 ro_Wextend32:$extend))]>,
2798 Sched<[WriteSTIdx, ReadAdrBase]> {
2802 let AddedComplexity = 10 in
2803 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2804 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2805 [(storeop (Ty regtype:$Rt),
2806 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2807 ro_Xextend32:$extend))]>,
2808 Sched<[WriteSTIdx, ReadAdrBase]> {
2812 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2815 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2816 string asm, dag ins, dag outs, list<dag> pat>
2817 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2822 let Inst{31-30} = sz;
2823 let Inst{29-27} = 0b111;
2825 let Inst{25-24} = 0b00;
2826 let Inst{23-22} = opc;
2828 let Inst{20-16} = Rm;
2829 let Inst{15} = extend{1}; // sign extend Rm?
2831 let Inst{12} = extend{0}; // do shift?
2832 let Inst{11-10} = 0b10;
2837 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2838 string asm, ValueType Ty, SDPatternOperator loadop> {
2839 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2840 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2841 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2842 [(set (Ty regtype:$Rt),
2843 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2844 ro_Wextend64:$extend)))]>,
2845 Sched<[WriteLDIdx, ReadAdrBase]> {
2849 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2850 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2851 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2852 [(set (Ty regtype:$Rt),
2853 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2854 ro_Xextend64:$extend)))]>,
2855 Sched<[WriteLDIdx, ReadAdrBase]> {
2859 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2862 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2863 string asm, ValueType Ty, SDPatternOperator storeop> {
2864 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2865 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2866 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2867 [(storeop (Ty regtype:$Rt),
2868 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2869 ro_Wextend64:$extend))]>,
2870 Sched<[WriteSTIdx, ReadAdrBase]> {
2874 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2875 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2876 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2877 [(storeop (Ty regtype:$Rt),
2878 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2879 ro_Xextend64:$extend))]>,
2880 Sched<[WriteSTIdx, ReadAdrBase]> {
2884 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2887 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2888 string asm, dag ins, dag outs, list<dag> pat>
2889 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2894 let Inst{31-30} = sz;
2895 let Inst{29-27} = 0b111;
2897 let Inst{25-24} = 0b00;
2898 let Inst{23-22} = opc;
2900 let Inst{20-16} = Rm;
2901 let Inst{15} = extend{1}; // sign extend Rm?
2903 let Inst{12} = extend{0}; // do shift?
2904 let Inst{11-10} = 0b10;
2909 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2910 string asm, ValueType Ty, SDPatternOperator loadop> {
2911 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2912 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2913 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2914 [(set (Ty regtype:$Rt),
2915 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2916 ro_Wextend128:$extend)))]>,
2917 Sched<[WriteLDIdx, ReadAdrBase]> {
2921 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2922 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2923 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2924 [(set (Ty regtype:$Rt),
2925 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2926 ro_Xextend128:$extend)))]>,
2927 Sched<[WriteLDIdx, ReadAdrBase]> {
2931 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2934 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2935 string asm, ValueType Ty, SDPatternOperator storeop> {
2936 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2937 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2938 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2939 [(storeop (Ty regtype:$Rt),
2940 (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2941 ro_Wextend128:$extend))]>,
2942 Sched<[WriteSTIdx, ReadAdrBase]> {
2946 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2947 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2948 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2949 [(storeop (Ty regtype:$Rt),
2950 (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2951 ro_Xextend128:$extend))]>,
2952 Sched<[WriteSTIdx, ReadAdrBase]> {
2956 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2959 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2960 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
2961 string asm, list<dag> pat>
2962 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
2968 let Inst{31-30} = sz;
2969 let Inst{29-27} = 0b111;
2971 let Inst{25-24} = 0b00;
2972 let Inst{23-22} = opc;
2974 let Inst{20-16} = Rm;
2975 let Inst{15} = extend{1}; // sign extend Rm?
2977 let Inst{12} = extend{0}; // do shift?
2978 let Inst{11-10} = 0b10;
2983 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
2984 def roW : BasePrefetchRO<sz, V, opc, (outs),
2985 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2986 asm, [(AArch64Prefetch imm:$Rt,
2987 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2988 ro_Wextend64:$extend))]> {
2992 def roX : BasePrefetchRO<sz, V, opc, (outs),
2993 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2994 asm, [(AArch64Prefetch imm:$Rt,
2995 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2996 ro_Xextend64:$extend))]> {
3000 def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
3001 (!cast<Instruction>(NAME # "roX") prfop:$Rt,
3002 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
3006 // Load/store unscaled immediate
3009 def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
3010 def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
3011 def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
3012 def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
3013 def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
3015 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3016 string asm, list<dag> pattern>
3017 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
3021 let Inst{31-30} = sz;
3022 let Inst{29-27} = 0b111;
3024 let Inst{25-24} = 0b00;
3025 let Inst{23-22} = opc;
3027 let Inst{20-12} = offset;
3028 let Inst{11-10} = 0b00;
3032 let DecoderMethod = "DecodeSignedLdStInstruction";
3035 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3036 string asm, list<dag> pattern> {
3037 let AddedComplexity = 1 in // try this before LoadUI
3038 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
3039 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
3042 def : InstAlias<asm # "\t$Rt, [$Rn]",
3043 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3046 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3047 string asm, list<dag> pattern> {
3048 let AddedComplexity = 1 in // try this before StoreUI
3049 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3050 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3054 def : InstAlias<asm # "\t$Rt, [$Rn]",
3055 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3058 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
3060 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3061 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3062 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
3066 def : InstAlias<asm # "\t$Rt, [$Rn]",
3067 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
3071 // Load/store unscaled immediate, unprivileged
3074 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3075 dag oops, dag iops, string asm>
3076 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
3080 let Inst{31-30} = sz;
3081 let Inst{29-27} = 0b111;
3083 let Inst{25-24} = 0b00;
3084 let Inst{23-22} = opc;
3086 let Inst{20-12} = offset;
3087 let Inst{11-10} = 0b10;
3091 let DecoderMethod = "DecodeSignedLdStInstruction";
3094 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3095 RegisterClass regtype, string asm> {
3096 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3097 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3098 (ins GPR64sp:$Rn, simm9:$offset), asm>,
3101 def : InstAlias<asm # "\t$Rt, [$Rn]",
3102 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3105 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3106 RegisterClass regtype, string asm> {
3107 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3108 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3109 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3113 def : InstAlias<asm # "\t$Rt, [$Rn]",
3114 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3118 // Load/store pre-indexed
3121 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3122 string asm, string cstr, list<dag> pat>
3123 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3127 let Inst{31-30} = sz;
3128 let Inst{29-27} = 0b111;
3130 let Inst{25-24} = 0;
3131 let Inst{23-22} = opc;
3133 let Inst{20-12} = offset;
3134 let Inst{11-10} = 0b11;
3138 let DecoderMethod = "DecodeSignedLdStInstruction";
3141 let hasSideEffects = 0 in {
3142 let mayStore = 0, mayLoad = 1 in
3143 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3145 : BaseLoadStorePreIdx<sz, V, opc,
3146 (outs GPR64sp:$wback, regtype:$Rt),
3147 (ins GPR64sp:$Rn, simm9:$offset), asm,
3148 "$Rn = $wback,@earlyclobber $wback", []>,
3149 Sched<[WriteLD, WriteAdr]>;
3151 let mayStore = 1, mayLoad = 0 in
3152 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3153 string asm, SDPatternOperator storeop, ValueType Ty>
3154 : BaseLoadStorePreIdx<sz, V, opc,
3155 (outs GPR64sp:$wback),
3156 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3157 asm, "$Rn = $wback,@earlyclobber $wback",
3158 [(set GPR64sp:$wback,
3159 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3160 Sched<[WriteAdr, WriteST]>;
3161 } // hasSideEffects = 0
3164 // Load/store post-indexed
3167 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3168 string asm, string cstr, list<dag> pat>
3169 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
3173 let Inst{31-30} = sz;
3174 let Inst{29-27} = 0b111;
3176 let Inst{25-24} = 0b00;
3177 let Inst{23-22} = opc;
3179 let Inst{20-12} = offset;
3180 let Inst{11-10} = 0b01;
3184 let DecoderMethod = "DecodeSignedLdStInstruction";
3187 let hasSideEffects = 0 in {
3188 let mayStore = 0, mayLoad = 1 in
3189 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3191 : BaseLoadStorePostIdx<sz, V, opc,
3192 (outs GPR64sp:$wback, regtype:$Rt),
3193 (ins GPR64sp:$Rn, simm9:$offset),
3194 asm, "$Rn = $wback,@earlyclobber $wback", []>,
3195 Sched<[WriteLD, WriteI]>;
3197 let mayStore = 1, mayLoad = 0 in
3198 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3199 string asm, SDPatternOperator storeop, ValueType Ty>
3200 : BaseLoadStorePostIdx<sz, V, opc,
3201 (outs GPR64sp:$wback),
3202 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3203 asm, "$Rn = $wback,@earlyclobber $wback",
3204 [(set GPR64sp:$wback,
3205 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3206 Sched<[WriteAdr, WriteST, ReadAdrBase]>;
3207 } // hasSideEffects = 0
3214 // (indexed, offset)
3216 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
3218 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3223 let Inst{31-30} = opc;
3224 let Inst{29-27} = 0b101;
3226 let Inst{25-23} = 0b010;
3228 let Inst{21-15} = offset;
3229 let Inst{14-10} = Rt2;
3233 let DecoderMethod = "DecodePairLdStInstruction";
3236 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
3237 Operand indextype, string asm> {
3238 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3239 def i : BaseLoadStorePairOffset<opc, V, 1,
3240 (outs regtype:$Rt, regtype:$Rt2),
3241 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3242 Sched<[WriteLD, WriteLDHi]>;
3244 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3245 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3250 multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
3251 Operand indextype, string asm> {
3252 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
3253 def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
3254 (ins regtype:$Rt, regtype:$Rt2,
3255 GPR64sp:$Rn, indextype:$offset),
3259 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3260 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3265 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3267 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
3272 let Inst{31-30} = opc;
3273 let Inst{29-27} = 0b101;
3275 let Inst{25-23} = 0b011;
3277 let Inst{21-15} = offset;
3278 let Inst{14-10} = Rt2;
3282 let DecoderMethod = "DecodePairLdStInstruction";
3285 let hasSideEffects = 0 in {
3286 let mayStore = 0, mayLoad = 1 in
3287 class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3288 Operand indextype, string asm>
3289 : BaseLoadStorePairPreIdx<opc, V, 1,
3290 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3291 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3292 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3294 let mayStore = 1, mayLoad = 0 in
3295 class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3296 Operand indextype, string asm>
3297 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
3298 (ins regtype:$Rt, regtype:$Rt2,
3299 GPR64sp:$Rn, indextype:$offset),
3301 Sched<[WriteAdr, WriteSTP]>;
3302 } // hasSideEffects = 0
3306 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3308 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
3313 let Inst{31-30} = opc;
3314 let Inst{29-27} = 0b101;
3316 let Inst{25-23} = 0b001;
3318 let Inst{21-15} = offset;
3319 let Inst{14-10} = Rt2;
3323 let DecoderMethod = "DecodePairLdStInstruction";
3326 let hasSideEffects = 0 in {
3327 let mayStore = 0, mayLoad = 1 in
3328 class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3329 Operand idxtype, string asm>
3330 : BaseLoadStorePairPostIdx<opc, V, 1,
3331 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3332 (ins GPR64sp:$Rn, idxtype:$offset), asm>,
3333 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3335 let mayStore = 1, mayLoad = 0 in
3336 class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3337 Operand idxtype, string asm>
3338 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
3339 (ins regtype:$Rt, regtype:$Rt2,
3340 GPR64sp:$Rn, idxtype:$offset),
3342 Sched<[WriteAdr, WriteSTP]>;
3343 } // hasSideEffects = 0
3347 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
3349 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3354 let Inst{31-30} = opc;
3355 let Inst{29-27} = 0b101;
3357 let Inst{25-23} = 0b000;
3359 let Inst{21-15} = offset;
3360 let Inst{14-10} = Rt2;
3364 let DecoderMethod = "DecodePairLdStInstruction";
3367 multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3368 Operand indextype, string asm> {
3369 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3370 def i : BaseLoadStorePairNoAlloc<opc, V, 1,
3371 (outs regtype:$Rt, regtype:$Rt2),
3372 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3373 Sched<[WriteLD, WriteLDHi]>;
3376 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3377 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3381 multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3382 Operand indextype, string asm> {
3383 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
3384 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
3385 (ins regtype:$Rt, regtype:$Rt2,
3386 GPR64sp:$Rn, indextype:$offset),
3390 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3391 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3396 // Load/store exclusive
3399 // True exclusive operations write to and/or read from the system's exclusive
3400 // monitors, which as far as a compiler is concerned can be modelled as a
3401 // random shared memory address. Hence LoadExclusive mayStore.
3403 // Since these instructions have the undefined register bits set to 1 in
3404 // their canonical form, we need a post encoder method to set those bits
3405 // to 1 when encoding these instructions. We do this using the
3406 // fixLoadStoreExclusive function. This function has template parameters:
3408 // fixLoadStoreExclusive<int hasRs, int hasRt2>
3410 // hasRs indicates that the instruction uses the Rs field, so we won't set
3411 // it to 1 (and the same for Rt2). We don't need template parameters for
3412 // the other register fields since Rt and Rn are always used.
3414 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
3415 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3416 dag oops, dag iops, string asm, string operands>
3417 : I<oops, iops, asm, operands, "", []> {
3418 let Inst{31-30} = sz;
3419 let Inst{29-24} = 0b001000;
3425 let DecoderMethod = "DecodeExclusiveLdStInstruction";
3428 // Neither Rs nor Rt2 operands.
3429 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3430 dag oops, dag iops, string asm, string operands>
3431 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
3434 let Inst{20-16} = 0b11111;
3435 let Unpredictable{20-16} = 0b11111;
3436 let Inst{14-10} = 0b11111;
3437 let Unpredictable{14-10} = 0b11111;
3441 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
3444 // Simple load acquires don't set the exclusive monitor
3445 let mayLoad = 1, mayStore = 0 in
3446 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3447 RegisterClass regtype, string asm>
3448 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3449 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3452 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3453 RegisterClass regtype, string asm>
3454 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3455 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3458 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3459 RegisterClass regtype, string asm>
3460 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3461 (outs regtype:$Rt, regtype:$Rt2),
3462 (ins GPR64sp0:$Rn), asm,
3463 "\t$Rt, $Rt2, [$Rn]">,
3464 Sched<[WriteLD, WriteLDHi]> {
3468 let Inst{14-10} = Rt2;
3472 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
3475 // Simple store release operations do not check the exclusive monitor.
3476 let mayLoad = 0, mayStore = 1 in
3477 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3478 RegisterClass regtype, string asm>
3479 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
3480 (ins regtype:$Rt, GPR64sp0:$Rn),
3481 asm, "\t$Rt, [$Rn]">,
3484 let mayLoad = 1, mayStore = 1 in
3485 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3486 RegisterClass regtype, string asm>
3487 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
3488 (ins regtype:$Rt, GPR64sp0:$Rn),
3489 asm, "\t$Ws, $Rt, [$Rn]">,
3494 let Inst{20-16} = Ws;
3498 let Constraints = "@earlyclobber $Ws";
3499 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
3502 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3503 RegisterClass regtype, string asm>
3504 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3506 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
3507 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
3513 let Inst{20-16} = Ws;
3514 let Inst{14-10} = Rt2;
3518 let Constraints = "@earlyclobber $Ws";
3522 // Exception generation
3525 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3526 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
3527 : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
3530 let Inst{31-24} = 0b11010100;
3531 let Inst{23-21} = op1;
3532 let Inst{20-5} = imm;
3533 let Inst{4-2} = 0b000;
3537 let Predicates = [HasFPARMv8] in {
3540 // Floating point to integer conversion
3543 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
3544 RegisterClass srcType, RegisterClass dstType,
3545 string asm, list<dag> pattern>
3546 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3547 asm, "\t$Rd, $Rn", "", pattern>,
3548 Sched<[WriteFCvt]> {
3551 let Inst{30-29} = 0b00;
3552 let Inst{28-24} = 0b11110;
3553 let Inst{23-22} = type;
3555 let Inst{20-19} = rmode;
3556 let Inst{18-16} = opcode;
3557 let Inst{15-10} = 0;
3562 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3563 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
3564 RegisterClass srcType, RegisterClass dstType,
3565 Operand immType, string asm, list<dag> pattern>
3566 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3567 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3568 Sched<[WriteFCvt]> {
3572 let Inst{30-29} = 0b00;
3573 let Inst{28-24} = 0b11110;
3574 let Inst{23-22} = type;
3576 let Inst{20-19} = rmode;
3577 let Inst{18-16} = opcode;
3578 let Inst{15-10} = scale;
3583 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
3584 SDPatternOperator OpN> {
3585 // Unscaled half-precision to 32-bit
3586 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,
3587 [(set GPR32:$Rd, (OpN FPR16:$Rn))]> {
3588 let Inst{31} = 0; // 32-bit GPR flag
3589 let Predicates = [HasFullFP16];
3592 // Unscaled half-precision to 64-bit
3593 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,
3594 [(set GPR64:$Rd, (OpN FPR16:$Rn))]> {
3595 let Inst{31} = 1; // 64-bit GPR flag
3596 let Predicates = [HasFullFP16];
3599 // Unscaled single-precision to 32-bit
3600 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
3601 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
3602 let Inst{31} = 0; // 32-bit GPR flag
3605 // Unscaled single-precision to 64-bit
3606 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
3607 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
3608 let Inst{31} = 1; // 64-bit GPR flag
3611 // Unscaled double-precision to 32-bit
3612 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
3613 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3614 let Inst{31} = 0; // 32-bit GPR flag
3617 // Unscaled double-precision to 64-bit
3618 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
3619 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3620 let Inst{31} = 1; // 64-bit GPR flag
3624 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
3625 SDPatternOperator OpN> {
3626 // Scaled half-precision to 32-bit
3627 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,
3628 fixedpoint_f16_i32, asm,
3629 [(set GPR32:$Rd, (OpN (fmul FPR16:$Rn,
3630 fixedpoint_f16_i32:$scale)))]> {
3631 let Inst{31} = 0; // 32-bit GPR flag
3633 let Predicates = [HasFullFP16];
3636 // Scaled half-precision to 64-bit
3637 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,
3638 fixedpoint_f16_i64, asm,
3639 [(set GPR64:$Rd, (OpN (fmul FPR16:$Rn,
3640 fixedpoint_f16_i64:$scale)))]> {
3641 let Inst{31} = 1; // 64-bit GPR flag
3642 let Predicates = [HasFullFP16];
3645 // Scaled single-precision to 32-bit
3646 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
3647 fixedpoint_f32_i32, asm,
3648 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
3649 fixedpoint_f32_i32:$scale)))]> {
3650 let Inst{31} = 0; // 32-bit GPR flag
3654 // Scaled single-precision to 64-bit
3655 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
3656 fixedpoint_f32_i64, asm,
3657 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
3658 fixedpoint_f32_i64:$scale)))]> {
3659 let Inst{31} = 1; // 64-bit GPR flag
3662 // Scaled double-precision to 32-bit
3663 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
3664 fixedpoint_f64_i32, asm,
3665 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
3666 fixedpoint_f64_i32:$scale)))]> {
3667 let Inst{31} = 0; // 32-bit GPR flag
3671 // Scaled double-precision to 64-bit
3672 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
3673 fixedpoint_f64_i64, asm,
3674 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
3675 fixedpoint_f64_i64:$scale)))]> {
3676 let Inst{31} = 1; // 64-bit GPR flag
3681 // Integer to floating point conversion
3684 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
3685 class BaseIntegerToFP<bit isUnsigned,
3686 RegisterClass srcType, RegisterClass dstType,
3687 Operand immType, string asm, list<dag> pattern>
3688 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3689 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3690 Sched<[WriteFCvt]> {
3694 let Inst{30-24} = 0b0011110;
3695 let Inst{21-17} = 0b00001;
3696 let Inst{16} = isUnsigned;
3697 let Inst{15-10} = scale;
3702 class BaseIntegerToFPUnscaled<bit isUnsigned,
3703 RegisterClass srcType, RegisterClass dstType,
3704 ValueType dvt, string asm, SDNode node>
3705 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3706 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
3707 Sched<[WriteFCvt]> {
3711 let Inst{30-24} = 0b0011110;
3712 let Inst{21-17} = 0b10001;
3713 let Inst{16} = isUnsigned;
3714 let Inst{15-10} = 0b000000;
3719 multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
3721 def UWHri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR16, f16, asm, node> {
3722 let Inst{31} = 0; // 32-bit GPR flag
3723 let Inst{23-22} = 0b11; // 16-bit FPR flag
3724 let Predicates = [HasFullFP16];
3727 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
3728 let Inst{31} = 0; // 32-bit GPR flag
3729 let Inst{23-22} = 0b00; // 32-bit FPR flag
3732 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
3733 let Inst{31} = 0; // 32-bit GPR flag
3734 let Inst{23-22} = 0b01; // 64-bit FPR flag
3737 def UXHri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR16, f16, asm, node> {
3738 let Inst{31} = 1; // 64-bit GPR flag
3739 let Inst{23-22} = 0b11; // 16-bit FPR flag
3740 let Predicates = [HasFullFP16];
3743 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
3744 let Inst{31} = 1; // 64-bit GPR flag
3745 let Inst{23-22} = 0b00; // 32-bit FPR flag
3748 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
3749 let Inst{31} = 1; // 64-bit GPR flag
3750 let Inst{23-22} = 0b01; // 64-bit FPR flag
3754 def SWHri: BaseIntegerToFP<isUnsigned, GPR32, FPR16, fixedpoint_f16_i32, asm,
3756 (fdiv (node GPR32:$Rn),
3757 fixedpoint_f16_i32:$scale))]> {
3758 let Inst{31} = 0; // 32-bit GPR flag
3759 let Inst{23-22} = 0b11; // 16-bit FPR flag
3761 let Predicates = [HasFullFP16];
3764 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
3766 (fdiv (node GPR32:$Rn),
3767 fixedpoint_f32_i32:$scale))]> {
3768 let Inst{31} = 0; // 32-bit GPR flag
3769 let Inst{23-22} = 0b00; // 32-bit FPR flag
3773 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
3775 (fdiv (node GPR32:$Rn),
3776 fixedpoint_f64_i32:$scale))]> {
3777 let Inst{31} = 0; // 32-bit GPR flag
3778 let Inst{23-22} = 0b01; // 64-bit FPR flag
3782 def SXHri: BaseIntegerToFP<isUnsigned, GPR64, FPR16, fixedpoint_f16_i64, asm,
3784 (fdiv (node GPR64:$Rn),
3785 fixedpoint_f16_i64:$scale))]> {
3786 let Inst{31} = 1; // 64-bit GPR flag
3787 let Inst{23-22} = 0b11; // 16-bit FPR flag
3788 let Predicates = [HasFullFP16];
3791 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
3793 (fdiv (node GPR64:$Rn),
3794 fixedpoint_f32_i64:$scale))]> {
3795 let Inst{31} = 1; // 64-bit GPR flag
3796 let Inst{23-22} = 0b00; // 32-bit FPR flag
3799 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
3801 (fdiv (node GPR64:$Rn),
3802 fixedpoint_f64_i64:$scale))]> {
3803 let Inst{31} = 1; // 64-bit GPR flag
3804 let Inst{23-22} = 0b01; // 64-bit FPR flag
3809 // Unscaled integer <-> floating point conversion (i.e. FMOV)
3812 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3813 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
3814 RegisterClass srcType, RegisterClass dstType,
3816 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
3817 // We use COPY_TO_REGCLASS for these bitconvert operations.
3818 // copyPhysReg() expands the resultant COPY instructions after
3819 // regalloc is done. This gives greater freedom for the allocator
3820 // and related passes (coalescing, copy propagation, et. al.) to
3821 // be more effective.
3822 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
3823 Sched<[WriteFCopy]> {
3826 let Inst{30-24} = 0b0011110;
3828 let Inst{20-19} = rmode;
3829 let Inst{18-16} = opcode;
3830 let Inst{15-10} = 0b000000;
3835 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3836 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
3837 RegisterClass srcType, RegisterOperand dstType, string asm,
3839 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3840 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
3841 Sched<[WriteFCopy]> {
3844 let Inst{30-23} = 0b00111101;
3846 let Inst{20-19} = rmode;
3847 let Inst{18-16} = opcode;
3848 let Inst{15-10} = 0b000000;
3852 let DecoderMethod = "DecodeFMOVLaneInstruction";
3855 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3856 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
3857 RegisterOperand srcType, RegisterClass dstType, string asm,
3859 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3860 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
3861 Sched<[WriteFCopy]> {
3864 let Inst{30-23} = 0b00111101;
3866 let Inst{20-19} = rmode;
3867 let Inst{18-16} = opcode;
3868 let Inst{15-10} = 0b000000;
3872 let DecoderMethod = "DecodeFMOVLaneInstruction";
3876 multiclass UnscaledConversion<string asm> {
3877 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {
3878 let Inst{31} = 0; // 32-bit GPR flag
3879 let Inst{23-22} = 0b11; // 16-bit FPR flag
3880 let Predicates = [HasFullFP16];
3883 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {
3884 let Inst{31} = 1; // 64-bit GPR flag
3885 let Inst{23-22} = 0b11; // 16-bit FPR flag
3886 let Predicates = [HasFullFP16];
3889 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
3890 let Inst{31} = 0; // 32-bit GPR flag
3891 let Inst{23-22} = 0b00; // 32-bit FPR flag
3894 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
3895 let Inst{31} = 1; // 64-bit GPR flag
3896 let Inst{23-22} = 0b01; // 64-bit FPR flag
3899 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {
3900 let Inst{31} = 0; // 32-bit GPR flag
3901 let Inst{23-22} = 0b11; // 16-bit FPR flag
3902 let Predicates = [HasFullFP16];
3905 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {
3906 let Inst{31} = 1; // 64-bit GPR flag
3907 let Inst{23-22} = 0b11; // 16-bit FPR flag
3908 let Predicates = [HasFullFP16];
3911 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
3912 let Inst{31} = 0; // 32-bit GPR flag
3913 let Inst{23-22} = 0b00; // 32-bit FPR flag
3916 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
3917 let Inst{31} = 1; // 64-bit GPR flag
3918 let Inst{23-22} = 0b01; // 64-bit FPR flag
3921 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
3927 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
3935 // Floating point conversion
3938 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
3939 RegisterClass srcType, string asm, list<dag> pattern>
3940 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
3941 Sched<[WriteFCvt]> {
3944 let Inst{31-24} = 0b00011110;
3945 let Inst{23-22} = type;
3946 let Inst{21-17} = 0b10001;
3947 let Inst{16-15} = opcode;
3948 let Inst{14-10} = 0b10000;
3953 multiclass FPConversion<string asm> {
3954 // Double-precision to Half-precision
3955 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
3956 [(set FPR16:$Rd, (fpround FPR64:$Rn))]>;
3958 // Double-precision to Single-precision
3959 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
3960 [(set FPR32:$Rd, (fpround FPR64:$Rn))]>;
3962 // Half-precision to Double-precision
3963 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
3964 [(set FPR64:$Rd, (fpextend FPR16:$Rn))]>;
3966 // Half-precision to Single-precision
3967 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
3968 [(set FPR32:$Rd, (fpextend FPR16:$Rn))]>;
3970 // Single-precision to Double-precision
3971 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
3972 [(set FPR64:$Rd, (fpextend FPR32:$Rn))]>;
3974 // Single-precision to Half-precision
3975 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
3976 [(set FPR16:$Rd, (fpround FPR32:$Rn))]>;
3980 // Single operand floating point data processing
3983 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3984 class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
3985 ValueType vt, string asm, SDPatternOperator node>
3986 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
3987 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
3991 let Inst{31-24} = 0b00011110;
3992 let Inst{21-19} = 0b100;
3993 let Inst{18-15} = opcode;
3994 let Inst{14-10} = 0b10000;
3999 multiclass SingleOperandFPData<bits<4> opcode, string asm,
4000 SDPatternOperator node = null_frag> {
4001 def Hr : BaseSingleOperandFPData<opcode, FPR16, f16, asm, node> {
4002 let Inst{23-22} = 0b11; // 16-bit size flag
4003 let Predicates = [HasFullFP16];
4006 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
4007 let Inst{23-22} = 0b00; // 32-bit size flag
4010 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
4011 let Inst{23-22} = 0b01; // 64-bit size flag
4016 // Two operand floating point data processing
4019 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4020 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
4021 string asm, list<dag> pat>
4022 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
4023 asm, "\t$Rd, $Rn, $Rm", "", pat>,
4028 let Inst{31-24} = 0b00011110;
4030 let Inst{20-16} = Rm;
4031 let Inst{15-12} = opcode;
4032 let Inst{11-10} = 0b10;
4037 multiclass TwoOperandFPData<bits<4> opcode, string asm,
4038 SDPatternOperator node = null_frag> {
4039 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4040 [(set (f16 FPR16:$Rd),
4041 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {
4042 let Inst{23-22} = 0b11; // 16-bit size flag
4043 let Predicates = [HasFullFP16];
4046 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4047 [(set (f32 FPR32:$Rd),
4048 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
4049 let Inst{23-22} = 0b00; // 32-bit size flag
4052 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4053 [(set (f64 FPR64:$Rd),
4054 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
4055 let Inst{23-22} = 0b01; // 64-bit size flag
4059 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
4060 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,
4061 [(set FPR16:$Rd, (fneg (node FPR16:$Rn, (f16 FPR16:$Rm))))]> {
4062 let Inst{23-22} = 0b11; // 16-bit size flag
4063 let Predicates = [HasFullFP16];
4066 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
4067 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
4068 let Inst{23-22} = 0b00; // 32-bit size flag
4071 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
4072 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
4073 let Inst{23-22} = 0b01; // 64-bit size flag
4079 // Three operand floating point data processing
4082 class BaseThreeOperandFPData<bit isNegated, bit isSub,
4083 RegisterClass regtype, string asm, list<dag> pat>
4084 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
4085 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
4086 Sched<[WriteFMul]> {
4091 let Inst{31-24} = 0b00011111;
4092 let Inst{21} = isNegated;
4093 let Inst{20-16} = Rm;
4094 let Inst{15} = isSub;
4095 let Inst{14-10} = Ra;
4100 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
4101 SDPatternOperator node> {
4102 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,
4104 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {
4105 let Inst{23-22} = 0b11; // 16-bit size flag
4106 let Predicates = [HasFullFP16];
4109 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
4111 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
4112 let Inst{23-22} = 0b00; // 32-bit size flag
4115 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
4117 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
4118 let Inst{23-22} = 0b01; // 64-bit size flag
4123 // Floating point data comparisons
4126 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4127 class BaseOneOperandFPComparison<bit signalAllNans,
4128 RegisterClass regtype, string asm,
4130 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
4131 Sched<[WriteFCmp]> {
4133 let Inst{31-24} = 0b00011110;
4136 let Inst{15-10} = 0b001000;
4138 let Inst{4} = signalAllNans;
4139 let Inst{3-0} = 0b1000;
4141 // Rm should be 0b00000 canonically, but we need to accept any value.
4142 let PostEncoderMethod = "fixOneOperandFPComparison";
4145 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4146 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
4147 string asm, list<dag> pat>
4148 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
4149 Sched<[WriteFCmp]> {
4152 let Inst{31-24} = 0b00011110;
4154 let Inst{20-16} = Rm;
4155 let Inst{15-10} = 0b001000;
4157 let Inst{4} = signalAllNans;
4158 let Inst{3-0} = 0b0000;
4161 multiclass FPComparison<bit signalAllNans, string asm,
4162 SDPatternOperator OpNode = null_frag> {
4163 let Defs = [NZCV] in {
4164 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,
4165 [(OpNode FPR16:$Rn, (f16 FPR16:$Rm)), (implicit NZCV)]> {
4166 let Inst{23-22} = 0b11;
4167 let Predicates = [HasFullFP16];
4170 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,
4171 [(OpNode (f16 FPR16:$Rn), fpimm0), (implicit NZCV)]> {
4172 let Inst{23-22} = 0b11;
4173 let Predicates = [HasFullFP16];
4176 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
4177 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
4178 let Inst{23-22} = 0b00;
4181 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
4182 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
4183 let Inst{23-22} = 0b00;
4186 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
4187 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
4188 let Inst{23-22} = 0b01;
4191 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
4192 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
4193 let Inst{23-22} = 0b01;
4199 // Floating point conditional comparisons
4202 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4203 class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
4204 string mnemonic, list<dag> pat>
4205 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
4206 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
4207 Sched<[WriteFCmp]> {
4216 let Inst{31-24} = 0b00011110;
4218 let Inst{20-16} = Rm;
4219 let Inst{15-12} = cond;
4220 let Inst{11-10} = 0b01;
4222 let Inst{4} = signalAllNans;
4223 let Inst{3-0} = nzcv;
4226 multiclass FPCondComparison<bit signalAllNans, string mnemonic,
4227 SDPatternOperator OpNode = null_frag> {
4228 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic, []> {
4229 let Inst{23-22} = 0b11;
4230 let Predicates = [HasFullFP16];
4233 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
4234 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
4235 (i32 imm:$cond), NZCV))]> {
4236 let Inst{23-22} = 0b00;
4239 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
4240 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
4241 (i32 imm:$cond), NZCV))]> {
4242 let Inst{23-22} = 0b01;
4247 // Floating point conditional select
4250 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
4251 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
4252 asm, "\t$Rd, $Rn, $Rm, $cond", "",
4254 (AArch64csel (vt regtype:$Rn), regtype:$Rm,
4255 (i32 imm:$cond), NZCV))]>,
4262 let Inst{31-24} = 0b00011110;
4264 let Inst{20-16} = Rm;
4265 let Inst{15-12} = cond;
4266 let Inst{11-10} = 0b11;
4271 multiclass FPCondSelect<string asm> {
4272 let Uses = [NZCV] in {
4273 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {
4274 let Inst{23-22} = 0b11;
4275 let Predicates = [HasFullFP16];
4278 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
4279 let Inst{23-22} = 0b00;
4282 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
4283 let Inst{23-22} = 0b01;
4289 // Floating move immediate
4292 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
4293 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
4294 [(set regtype:$Rd, fpimmtype:$imm)]>,
4295 Sched<[WriteFImm]> {
4298 let Inst{31-24} = 0b00011110;
4300 let Inst{20-13} = imm;
4301 let Inst{12-5} = 0b10000000;
4305 multiclass FPMoveImmediate<string asm> {
4306 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {
4307 let Inst{23-22} = 0b11;
4308 let Predicates = [HasFullFP16];
4311 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
4312 let Inst{23-22} = 0b00;
4315 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
4316 let Inst{23-22} = 0b01;
4319 } // end of 'let Predicates = [HasFPARMv8]'
4321 //----------------------------------------------------------------------------
4323 //----------------------------------------------------------------------------
4325 let Predicates = [HasNEON] in {
4327 //----------------------------------------------------------------------------
4328 // AdvSIMD three register vector instructions
4329 //----------------------------------------------------------------------------
4331 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4332 class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,
4333 RegisterOperand regtype, string asm, string kind,
4335 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4336 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4337 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
4345 let Inst{28-24} = 0b01110;
4346 let Inst{23-21} = size;
4347 let Inst{20-16} = Rm;
4348 let Inst{15-11} = opcode;
4354 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4355 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,
4356 RegisterOperand regtype, string asm, string kind,
4358 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
4359 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4360 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4368 let Inst{28-24} = 0b01110;
4369 let Inst{23-21} = size;
4370 let Inst{20-16} = Rm;
4371 let Inst{15-11} = opcode;
4377 // All operand sizes distinguished in the encoding.
4378 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
4379 SDPatternOperator OpNode> {
4380 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4382 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4383 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4385 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4386 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4388 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4389 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4391 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4392 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4394 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4395 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4397 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4398 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,
4400 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4403 // As above, but D sized elements unsupported.
4404 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
4405 SDPatternOperator OpNode> {
4406 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4408 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
4409 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4411 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
4412 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4414 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
4415 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4417 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
4418 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4420 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
4421 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4423 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
4426 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
4427 SDPatternOperator OpNode> {
4428 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,
4430 [(set (v8i8 V64:$dst),
4431 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4432 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,
4434 [(set (v16i8 V128:$dst),
4435 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4436 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,
4438 [(set (v4i16 V64:$dst),
4439 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4440 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,
4442 [(set (v8i16 V128:$dst),
4443 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4444 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,
4446 [(set (v2i32 V64:$dst),
4447 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4448 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,
4450 [(set (v4i32 V128:$dst),
4451 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4454 // As above, but only B sized elements supported.
4455 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
4456 SDPatternOperator OpNode> {
4457 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,
4459 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4460 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,
4462 [(set (v16i8 V128:$Rd),
4463 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4466 // As above, but only floating point elements supported.
4467 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,
4468 string asm, SDPatternOperator OpNode> {
4469 let Predicates = [HasNEON, HasFullFP16] in {
4470 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
4472 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4473 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
4475 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4476 } // Predicates = [HasNEON, HasFullFP16]
4477 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
4479 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4480 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
4482 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4483 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
4485 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4488 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,
4490 SDPatternOperator OpNode> {
4491 let Predicates = [HasNEON, HasFullFP16] in {
4492 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,
4494 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4495 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,
4497 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4498 } // Predicates = [HasNEON, HasFullFP16]
4499 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,
4501 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4502 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,
4504 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4505 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,
4507 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4510 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,
4511 string asm, SDPatternOperator OpNode> {
4512 let Predicates = [HasNEON, HasFullFP16] in {
4513 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,
4515 [(set (v4f16 V64:$dst),
4516 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;
4517 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,
4519 [(set (v8f16 V128:$dst),
4520 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;
4521 } // Predicates = [HasNEON, HasFullFP16]
4522 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,
4524 [(set (v2f32 V64:$dst),
4525 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4526 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,
4528 [(set (v4f32 V128:$dst),
4529 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4530 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,
4532 [(set (v2f64 V128:$dst),
4533 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4536 // As above, but D and B sized elements unsupported.
4537 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
4538 SDPatternOperator OpNode> {
4539 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,
4541 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4542 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,
4544 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4545 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,
4547 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4548 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,
4550 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4553 // Logical three vector ops share opcode bits, and only use B sized elements.
4554 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
4555 SDPatternOperator OpNode = null_frag> {
4556 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,
4558 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
4559 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,
4561 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
4563 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
4564 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4565 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
4566 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4567 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
4568 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4570 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
4571 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4572 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
4573 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4574 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
4575 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4578 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
4579 string asm, SDPatternOperator OpNode> {
4580 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,
4582 [(set (v8i8 V64:$dst),
4583 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4584 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,
4586 [(set (v16i8 V128:$dst),
4587 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
4588 (v16i8 V128:$Rm)))]>;
4590 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
4592 (!cast<Instruction>(NAME#"v8i8")
4593 V64:$LHS, V64:$MHS, V64:$RHS)>;
4594 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
4596 (!cast<Instruction>(NAME#"v8i8")
4597 V64:$LHS, V64:$MHS, V64:$RHS)>;
4598 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
4600 (!cast<Instruction>(NAME#"v8i8")
4601 V64:$LHS, V64:$MHS, V64:$RHS)>;
4603 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
4604 (v8i16 V128:$RHS))),
4605 (!cast<Instruction>(NAME#"v16i8")
4606 V128:$LHS, V128:$MHS, V128:$RHS)>;
4607 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
4608 (v4i32 V128:$RHS))),
4609 (!cast<Instruction>(NAME#"v16i8")
4610 V128:$LHS, V128:$MHS, V128:$RHS)>;
4611 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
4612 (v2i64 V128:$RHS))),
4613 (!cast<Instruction>(NAME#"v16i8")
4614 V128:$LHS, V128:$MHS, V128:$RHS)>;
4618 //----------------------------------------------------------------------------
4619 // AdvSIMD two register vector instructions.
4620 //----------------------------------------------------------------------------
4622 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4623 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4624 bits<2> size2, RegisterOperand regtype, string asm,
4625 string dstkind, string srckind, list<dag> pattern>
4626 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4627 "{\t$Rd" # dstkind # ", $Rn" # srckind #
4628 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
4635 let Inst{28-24} = 0b01110;
4636 let Inst{23-22} = size;
4638 let Inst{20-19} = size2;
4639 let Inst{18-17} = 0b00;
4640 let Inst{16-12} = opcode;
4641 let Inst{11-10} = 0b10;
4646 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4647 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4648 bits<2> size2, RegisterOperand regtype,
4649 string asm, string dstkind, string srckind,
4651 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
4652 "{\t$Rd" # dstkind # ", $Rn" # srckind #
4653 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4660 let Inst{28-24} = 0b01110;
4661 let Inst{23-22} = size;
4663 let Inst{20-19} = size2;
4664 let Inst{18-17} = 0b00;
4665 let Inst{16-12} = opcode;
4666 let Inst{11-10} = 0b10;
4671 // Supports B, H, and S element sizes.
4672 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
4673 SDPatternOperator OpNode> {
4674 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
4676 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4677 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
4678 asm, ".16b", ".16b",
4679 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4680 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
4682 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4683 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
4685 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4686 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
4688 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4689 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
4691 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4694 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
4695 RegisterOperand regtype, string asm, string dstkind,
4696 string srckind, string amount>
4697 : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
4698 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
4699 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,
4705 let Inst{29-24} = 0b101110;
4706 let Inst{23-22} = size;
4707 let Inst{21-10} = 0b100001001110;
4712 multiclass SIMDVectorLShiftLongBySizeBHS {
4713 let hasSideEffects = 0 in {
4714 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
4715 "shll", ".8h", ".8b", "8">;
4716 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
4717 "shll2", ".8h", ".16b", "8">;
4718 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
4719 "shll", ".4s", ".4h", "16">;
4720 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
4721 "shll2", ".4s", ".8h", "16">;
4722 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
4723 "shll", ".2d", ".2s", "32">;
4724 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
4725 "shll2", ".2d", ".4s", "32">;
4729 // Supports all element sizes.
4730 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
4731 SDPatternOperator OpNode> {
4732 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
4734 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4735 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
4737 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4738 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
4740 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4741 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
4743 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4744 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
4746 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4747 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
4749 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4752 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
4753 SDPatternOperator OpNode> {
4754 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
4756 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
4758 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
4760 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
4761 (v16i8 V128:$Rn)))]>;
4762 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
4764 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
4765 (v4i16 V64:$Rn)))]>;
4766 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
4768 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
4769 (v8i16 V128:$Rn)))]>;
4770 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
4772 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
4773 (v2i32 V64:$Rn)))]>;
4774 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
4776 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
4777 (v4i32 V128:$Rn)))]>;
4780 // Supports all element sizes, except 1xD.
4781 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
4782 SDPatternOperator OpNode> {
4783 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,
4785 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
4786 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,
4787 asm, ".16b", ".16b",
4788 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
4789 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,
4791 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
4792 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,
4794 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
4795 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,
4797 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
4798 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,
4800 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
4801 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,
4803 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
4806 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
4807 SDPatternOperator OpNode = null_frag> {
4808 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
4810 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4811 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
4812 asm, ".16b", ".16b",
4813 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4814 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
4816 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4817 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
4819 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4820 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,
4822 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4823 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,
4825 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4826 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,
4828 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4832 // Supports only B element sizes.
4833 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
4834 SDPatternOperator OpNode> {
4835 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,
4837 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4838 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,
4839 asm, ".16b", ".16b",
4840 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4844 // Supports only B and H element sizes.
4845 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
4846 SDPatternOperator OpNode> {
4847 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,
4849 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
4850 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,
4851 asm, ".16b", ".16b",
4852 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
4853 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,
4855 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
4856 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,
4858 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
4861 // Supports only S and D element sizes, uses high bit of the size field
4862 // as an extra opcode bit.
4863 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
4864 SDPatternOperator OpNode> {
4865 let Predicates = [HasNEON, HasFullFP16] in {
4866 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
4868 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
4869 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
4871 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
4872 } // Predicates = [HasNEON, HasFullFP16]
4873 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
4875 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4876 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
4878 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4879 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
4881 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4884 // Supports only S element size.
4885 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
4886 SDPatternOperator OpNode> {
4887 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
4889 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4890 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
4892 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4896 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
4897 SDPatternOperator OpNode> {
4898 let Predicates = [HasNEON, HasFullFP16] in {
4899 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
4901 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;
4902 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
4904 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;
4905 } // Predicates = [HasNEON, HasFullFP16]
4906 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
4908 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4909 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
4911 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4912 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
4914 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4917 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
4918 SDPatternOperator OpNode> {
4919 let Predicates = [HasNEON, HasFullFP16] in {
4920 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,
4922 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4923 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,
4925 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4926 } // Predicates = [HasNEON, HasFullFP16]
4927 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,
4929 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4930 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,
4932 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4933 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,
4935 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4939 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4940 RegisterOperand inreg, RegisterOperand outreg,
4941 string asm, string outkind, string inkind,
4943 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
4944 "{\t$Rd" # outkind # ", $Rn" # inkind #
4945 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
4952 let Inst{28-24} = 0b01110;
4953 let Inst{23-22} = size;
4954 let Inst{21-17} = 0b10000;
4955 let Inst{16-12} = opcode;
4956 let Inst{11-10} = 0b10;
4961 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4962 RegisterOperand inreg, RegisterOperand outreg,
4963 string asm, string outkind, string inkind,
4965 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
4966 "{\t$Rd" # outkind # ", $Rn" # inkind #
4967 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4974 let Inst{28-24} = 0b01110;
4975 let Inst{23-22} = size;
4976 let Inst{21-17} = 0b10000;
4977 let Inst{16-12} = opcode;
4978 let Inst{11-10} = 0b10;
4983 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
4984 SDPatternOperator OpNode> {
4985 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
4987 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4988 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
4989 asm#"2", ".16b", ".8h", []>;
4990 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
4992 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4993 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
4994 asm#"2", ".8h", ".4s", []>;
4995 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
4997 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4998 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
4999 asm#"2", ".4s", ".2d", []>;
5001 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
5002 (!cast<Instruction>(NAME # "v16i8")
5003 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5004 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
5005 (!cast<Instruction>(NAME # "v8i16")
5006 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5007 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
5008 (!cast<Instruction>(NAME # "v4i32")
5009 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5012 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,
5013 bits<5> opcode, RegisterOperand regtype, string asm,
5014 string kind, string zero, ValueType dty,
5015 ValueType sty, SDNode OpNode>
5016 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5017 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
5018 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
5019 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
5026 let Inst{28-24} = 0b01110;
5027 let Inst{23-22} = size;
5029 let Inst{20-19} = size2;
5030 let Inst{18-17} = 0b00;
5031 let Inst{16-12} = opcode;
5032 let Inst{11-10} = 0b10;
5037 // Comparisons support all element sizes, except 1xD.
5038 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
5040 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,
5042 v8i8, v8i8, OpNode>;
5043 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,
5045 v16i8, v16i8, OpNode>;
5046 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,
5048 v4i16, v4i16, OpNode>;
5049 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,
5051 v8i16, v8i16, OpNode>;
5052 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,
5054 v2i32, v2i32, OpNode>;
5055 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,
5057 v4i32, v4i32, OpNode>;
5058 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,
5060 v2i64, v2i64, OpNode>;
5063 // FP Comparisons support only S and D element sizes (and H for v8.2a).
5064 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
5065 string asm, SDNode OpNode> {
5067 let Predicates = [HasNEON, HasFullFP16] in {
5068 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,
5070 v4i16, v4f16, OpNode>;
5071 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,
5073 v8i16, v8f16, OpNode>;
5074 } // Predicates = [HasNEON, HasFullFP16]
5075 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,
5077 v2i32, v2f32, OpNode>;
5078 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,
5080 v4i32, v4f32, OpNode>;
5081 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,
5083 v2i64, v2f64, OpNode>;
5085 let Predicates = [HasNEON, HasFullFP16] in {
5086 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",
5087 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5088 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",
5089 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5091 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
5092 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
5093 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
5094 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
5095 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
5096 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5097 let Predicates = [HasNEON, HasFullFP16] in {
5098 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",
5099 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;
5100 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",
5101 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;
5103 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
5104 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
5105 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
5106 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
5107 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
5108 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
5111 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5112 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
5113 RegisterOperand outtype, RegisterOperand intype,
5114 string asm, string VdTy, string VnTy,
5116 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
5117 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
5124 let Inst{28-24} = 0b01110;
5125 let Inst{23-22} = size;
5126 let Inst{21-17} = 0b10000;
5127 let Inst{16-12} = opcode;
5128 let Inst{11-10} = 0b10;
5133 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
5134 RegisterOperand outtype, RegisterOperand intype,
5135 string asm, string VdTy, string VnTy,
5137 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
5138 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
5145 let Inst{28-24} = 0b01110;
5146 let Inst{23-22} = size;
5147 let Inst{21-17} = 0b10000;
5148 let Inst{16-12} = opcode;
5149 let Inst{11-10} = 0b10;
5154 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
5155 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
5156 asm, ".4s", ".4h", []>;
5157 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
5158 asm#"2", ".4s", ".8h", []>;
5159 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
5160 asm, ".2d", ".2s", []>;
5161 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
5162 asm#"2", ".2d", ".4s", []>;
5165 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
5166 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
5167 asm, ".4h", ".4s", []>;
5168 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
5169 asm#"2", ".8h", ".4s", []>;
5170 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5171 asm, ".2s", ".2d", []>;
5172 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5173 asm#"2", ".4s", ".2d", []>;
5176 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
5178 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
5180 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
5181 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
5182 asm#"2", ".4s", ".2d", []>;
5184 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
5185 (!cast<Instruction>(NAME # "v4f32")
5186 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
5189 //----------------------------------------------------------------------------
5190 // AdvSIMD three register different-size vector instructions.
5191 //----------------------------------------------------------------------------
5193 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5194 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
5195 RegisterOperand outtype, RegisterOperand intype1,
5196 RegisterOperand intype2, string asm,
5197 string outkind, string inkind1, string inkind2,
5199 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
5200 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5201 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
5207 let Inst{30} = size{0};
5209 let Inst{28-24} = 0b01110;
5210 let Inst{23-22} = size{2-1};
5212 let Inst{20-16} = Rm;
5213 let Inst{15-12} = opcode;
5214 let Inst{11-10} = 0b00;
5219 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5220 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
5221 RegisterOperand outtype, RegisterOperand intype1,
5222 RegisterOperand intype2, string asm,
5223 string outkind, string inkind1, string inkind2,
5225 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
5226 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
5227 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
5233 let Inst{30} = size{0};
5235 let Inst{28-24} = 0b01110;
5236 let Inst{23-22} = size{2-1};
5238 let Inst{20-16} = Rm;
5239 let Inst{15-12} = opcode;
5240 let Inst{11-10} = 0b00;
5245 // FIXME: TableGen doesn't know how to deal with expanded types that also
5246 // change the element count (in this case, placing the results in
5247 // the high elements of the result register rather than the low
5248 // elements). Until that's fixed, we can't code-gen those.
5249 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
5251 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5253 asm, ".8b", ".8h", ".8h",
5254 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
5255 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5257 asm#"2", ".16b", ".8h", ".8h",
5259 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5261 asm, ".4h", ".4s", ".4s",
5262 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5263 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5265 asm#"2", ".8h", ".4s", ".4s",
5267 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5269 asm, ".2s", ".2d", ".2d",
5270 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5271 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5273 asm#"2", ".4s", ".2d", ".2d",
5277 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
5278 // a version attached to an instruction.
5279 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
5281 (!cast<Instruction>(NAME # "v8i16_v16i8")
5282 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5283 V128:$Rn, V128:$Rm)>;
5284 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
5286 (!cast<Instruction>(NAME # "v4i32_v8i16")
5287 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5288 V128:$Rn, V128:$Rm)>;
5289 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
5291 (!cast<Instruction>(NAME # "v2i64_v4i32")
5292 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5293 V128:$Rn, V128:$Rm)>;
5296 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
5298 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5300 asm, ".8h", ".8b", ".8b",
5301 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5302 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5304 asm#"2", ".8h", ".16b", ".16b", []>;
5305 let Predicates = [HasCrypto] in {
5306 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
5308 asm, ".1q", ".1d", ".1d", []>;
5309 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
5311 asm#"2", ".1q", ".2d", ".2d", []>;
5314 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
5315 (v8i8 (extract_high_v16i8 V128:$Rm)))),
5316 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
5319 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
5320 SDPatternOperator OpNode> {
5321 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5323 asm, ".4s", ".4h", ".4h",
5324 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5325 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5327 asm#"2", ".4s", ".8h", ".8h",
5328 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5329 (extract_high_v8i16 V128:$Rm)))]>;
5330 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5332 asm, ".2d", ".2s", ".2s",
5333 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5334 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5336 asm#"2", ".2d", ".4s", ".4s",
5337 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5338 (extract_high_v4i32 V128:$Rm)))]>;
5341 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
5342 SDPatternOperator OpNode = null_frag> {
5343 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5345 asm, ".8h", ".8b", ".8b",
5346 [(set (v8i16 V128:$Rd),
5347 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
5348 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5350 asm#"2", ".8h", ".16b", ".16b",
5351 [(set (v8i16 V128:$Rd),
5352 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5353 (extract_high_v16i8 V128:$Rm)))))]>;
5354 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5356 asm, ".4s", ".4h", ".4h",
5357 [(set (v4i32 V128:$Rd),
5358 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
5359 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5361 asm#"2", ".4s", ".8h", ".8h",
5362 [(set (v4i32 V128:$Rd),
5363 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5364 (extract_high_v8i16 V128:$Rm)))))]>;
5365 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5367 asm, ".2d", ".2s", ".2s",
5368 [(set (v2i64 V128:$Rd),
5369 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
5370 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5372 asm#"2", ".2d", ".4s", ".4s",
5373 [(set (v2i64 V128:$Rd),
5374 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5375 (extract_high_v4i32 V128:$Rm)))))]>;
5378 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
5380 SDPatternOperator OpNode> {
5381 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5383 asm, ".8h", ".8b", ".8b",
5384 [(set (v8i16 V128:$dst),
5385 (add (v8i16 V128:$Rd),
5386 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
5387 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5389 asm#"2", ".8h", ".16b", ".16b",
5390 [(set (v8i16 V128:$dst),
5391 (add (v8i16 V128:$Rd),
5392 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5393 (extract_high_v16i8 V128:$Rm))))))]>;
5394 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5396 asm, ".4s", ".4h", ".4h",
5397 [(set (v4i32 V128:$dst),
5398 (add (v4i32 V128:$Rd),
5399 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
5400 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5402 asm#"2", ".4s", ".8h", ".8h",
5403 [(set (v4i32 V128:$dst),
5404 (add (v4i32 V128:$Rd),
5405 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5406 (extract_high_v8i16 V128:$Rm))))))]>;
5407 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5409 asm, ".2d", ".2s", ".2s",
5410 [(set (v2i64 V128:$dst),
5411 (add (v2i64 V128:$Rd),
5412 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
5413 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5415 asm#"2", ".2d", ".4s", ".4s",
5416 [(set (v2i64 V128:$dst),
5417 (add (v2i64 V128:$Rd),
5418 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5419 (extract_high_v4i32 V128:$Rm))))))]>;
5422 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
5423 SDPatternOperator OpNode = null_frag> {
5424 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5426 asm, ".8h", ".8b", ".8b",
5427 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5428 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5430 asm#"2", ".8h", ".16b", ".16b",
5431 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
5432 (extract_high_v16i8 V128:$Rm)))]>;
5433 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5435 asm, ".4s", ".4h", ".4h",
5436 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5437 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5439 asm#"2", ".4s", ".8h", ".8h",
5440 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5441 (extract_high_v8i16 V128:$Rm)))]>;
5442 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5444 asm, ".2d", ".2s", ".2s",
5445 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5446 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5448 asm#"2", ".2d", ".4s", ".4s",
5449 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5450 (extract_high_v4i32 V128:$Rm)))]>;
5453 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
5455 SDPatternOperator OpNode> {
5456 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5458 asm, ".8h", ".8b", ".8b",
5459 [(set (v8i16 V128:$dst),
5460 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5461 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5463 asm#"2", ".8h", ".16b", ".16b",
5464 [(set (v8i16 V128:$dst),
5465 (OpNode (v8i16 V128:$Rd),
5466 (extract_high_v16i8 V128:$Rn),
5467 (extract_high_v16i8 V128:$Rm)))]>;
5468 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5470 asm, ".4s", ".4h", ".4h",
5471 [(set (v4i32 V128:$dst),
5472 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5473 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5475 asm#"2", ".4s", ".8h", ".8h",
5476 [(set (v4i32 V128:$dst),
5477 (OpNode (v4i32 V128:$Rd),
5478 (extract_high_v8i16 V128:$Rn),
5479 (extract_high_v8i16 V128:$Rm)))]>;
5480 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5482 asm, ".2d", ".2s", ".2s",
5483 [(set (v2i64 V128:$dst),
5484 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5485 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5487 asm#"2", ".2d", ".4s", ".4s",
5488 [(set (v2i64 V128:$dst),
5489 (OpNode (v2i64 V128:$Rd),
5490 (extract_high_v4i32 V128:$Rn),
5491 (extract_high_v4i32 V128:$Rm)))]>;
5494 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
5495 SDPatternOperator Accum> {
5496 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5498 asm, ".4s", ".4h", ".4h",
5499 [(set (v4i32 V128:$dst),
5500 (Accum (v4i32 V128:$Rd),
5501 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
5502 (v4i16 V64:$Rm)))))]>;
5503 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5505 asm#"2", ".4s", ".8h", ".8h",
5506 [(set (v4i32 V128:$dst),
5507 (Accum (v4i32 V128:$Rd),
5508 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
5509 (extract_high_v8i16 V128:$Rm)))))]>;
5510 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5512 asm, ".2d", ".2s", ".2s",
5513 [(set (v2i64 V128:$dst),
5514 (Accum (v2i64 V128:$Rd),
5515 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
5516 (v2i32 V64:$Rm)))))]>;
5517 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5519 asm#"2", ".2d", ".4s", ".4s",
5520 [(set (v2i64 V128:$dst),
5521 (Accum (v2i64 V128:$Rd),
5522 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
5523 (extract_high_v4i32 V128:$Rm)))))]>;
5526 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
5527 SDPatternOperator OpNode> {
5528 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5530 asm, ".8h", ".8h", ".8b",
5531 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
5532 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5534 asm#"2", ".8h", ".8h", ".16b",
5535 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
5536 (extract_high_v16i8 V128:$Rm)))]>;
5537 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5539 asm, ".4s", ".4s", ".4h",
5540 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
5541 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5543 asm#"2", ".4s", ".4s", ".8h",
5544 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
5545 (extract_high_v8i16 V128:$Rm)))]>;
5546 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5548 asm, ".2d", ".2d", ".2s",
5549 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
5550 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5552 asm#"2", ".2d", ".2d", ".4s",
5553 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
5554 (extract_high_v4i32 V128:$Rm)))]>;
5557 //----------------------------------------------------------------------------
5558 // AdvSIMD bitwise extract from vector
5559 //----------------------------------------------------------------------------
5561 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
5562 string asm, string kind>
5563 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
5564 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
5565 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
5566 [(set (vty regtype:$Rd),
5567 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
5574 let Inst{30} = size;
5575 let Inst{29-21} = 0b101110000;
5576 let Inst{20-16} = Rm;
5578 let Inst{14-11} = imm;
5585 multiclass SIMDBitwiseExtract<string asm> {
5586 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
5589 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
5592 //----------------------------------------------------------------------------
5593 // AdvSIMD zip vector
5594 //----------------------------------------------------------------------------
5596 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
5597 string asm, string kind, SDNode OpNode, ValueType valty>
5598 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5599 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5600 "|" # kind # "\t$Rd, $Rn, $Rm}", "",
5601 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
5607 let Inst{30} = size{0};
5608 let Inst{29-24} = 0b001110;
5609 let Inst{23-22} = size{2-1};
5611 let Inst{20-16} = Rm;
5613 let Inst{14-12} = opc;
5614 let Inst{11-10} = 0b10;
5619 multiclass SIMDZipVector<bits<3>opc, string asm,
5621 def v8i8 : BaseSIMDZipVector<0b000, opc, V64,
5622 asm, ".8b", OpNode, v8i8>;
5623 def v16i8 : BaseSIMDZipVector<0b001, opc, V128,
5624 asm, ".16b", OpNode, v16i8>;
5625 def v4i16 : BaseSIMDZipVector<0b010, opc, V64,
5626 asm, ".4h", OpNode, v4i16>;
5627 def v8i16 : BaseSIMDZipVector<0b011, opc, V128,
5628 asm, ".8h", OpNode, v8i16>;
5629 def v2i32 : BaseSIMDZipVector<0b100, opc, V64,
5630 asm, ".2s", OpNode, v2i32>;
5631 def v4i32 : BaseSIMDZipVector<0b101, opc, V128,
5632 asm, ".4s", OpNode, v4i32>;
5633 def v2i64 : BaseSIMDZipVector<0b111, opc, V128,
5634 asm, ".2d", OpNode, v2i64>;
5636 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
5637 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
5638 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
5639 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
5640 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
5641 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
5642 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
5643 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
5644 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
5645 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
5648 //----------------------------------------------------------------------------
5649 // AdvSIMD three register scalar instructions
5650 //----------------------------------------------------------------------------
5652 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5653 class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,
5654 RegisterClass regtype, string asm,
5656 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5657 "\t$Rd, $Rn, $Rm", "", pattern>,
5662 let Inst{31-30} = 0b01;
5664 let Inst{28-24} = 0b11110;
5665 let Inst{23-21} = size;
5666 let Inst{20-16} = Rm;
5667 let Inst{15-11} = opcode;
5673 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5674 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
5675 dag oops, dag iops, string asm,
5677 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
5682 let Inst{31-30} = 0b01;
5684 let Inst{28-24} = 0b11110;
5685 let Inst{23-22} = size;
5687 let Inst{20-16} = Rm;
5688 let Inst{15-11} = opcode;
5694 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
5695 SDPatternOperator OpNode> {
5696 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
5697 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5700 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
5701 SDPatternOperator OpNode> {
5702 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,
5703 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5704 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;
5705 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
5706 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;
5708 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
5709 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
5710 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
5711 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
5714 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
5715 SDPatternOperator OpNode> {
5716 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,
5717 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5718 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;
5721 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
5722 SDPatternOperator OpNode = null_frag> {
5723 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
5724 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
5726 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
5727 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
5731 multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,
5732 SDPatternOperator OpNode = null_frag> {
5733 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5734 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
5735 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5736 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
5737 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5738 let Predicates = [HasNEON, HasFullFP16] in {
5739 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
5740 [(set FPR16:$Rd, (OpNode FPR16:$Rn, FPR16:$Rm))]>;
5741 } // Predicates = [HasNEON, HasFullFP16]
5744 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5745 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5748 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,
5749 SDPatternOperator OpNode = null_frag> {
5750 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5751 def #NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,
5752 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5753 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,
5754 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
5755 let Predicates = [HasNEON, HasFullFP16] in {
5756 def #NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,
5758 } // Predicates = [HasNEON, HasFullFP16]
5761 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5762 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5765 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
5766 dag oops, dag iops, string asm, string cstr, list<dag> pat>
5767 : I<oops, iops, asm,
5768 "\t$Rd, $Rn, $Rm", cstr, pat>,
5773 let Inst{31-30} = 0b01;
5775 let Inst{28-24} = 0b11110;
5776 let Inst{23-22} = size;
5778 let Inst{20-16} = Rm;
5779 let Inst{15-11} = opcode;
5785 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5786 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
5787 SDPatternOperator OpNode = null_frag> {
5788 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5790 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
5791 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5793 (ins FPR32:$Rn, FPR32:$Rm), asm, "",
5794 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5797 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5798 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
5799 SDPatternOperator OpNode = null_frag> {
5800 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5802 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
5803 asm, "$Rd = $dst", []>;
5804 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5806 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
5808 [(set (i64 FPR64:$dst),
5809 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5812 //----------------------------------------------------------------------------
5813 // AdvSIMD two register scalar instructions
5814 //----------------------------------------------------------------------------
5816 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5817 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
5818 RegisterClass regtype, RegisterClass regtype2,
5819 string asm, list<dag> pat>
5820 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
5821 "\t$Rd, $Rn", "", pat>,
5825 let Inst{31-30} = 0b01;
5827 let Inst{28-24} = 0b11110;
5828 let Inst{23-22} = size;
5830 let Inst{20-19} = size2;
5831 let Inst{18-17} = 0b00;
5832 let Inst{16-12} = opcode;
5833 let Inst{11-10} = 0b10;
5838 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5839 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
5840 RegisterClass regtype, RegisterClass regtype2,
5841 string asm, list<dag> pat>
5842 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
5843 "\t$Rd, $Rn", "$Rd = $dst", pat>,
5847 let Inst{31-30} = 0b01;
5849 let Inst{28-24} = 0b11110;
5850 let Inst{23-22} = size;
5851 let Inst{21-17} = 0b10000;
5852 let Inst{16-12} = opcode;
5853 let Inst{11-10} = 0b10;
5859 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5860 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,
5861 RegisterClass regtype, string asm, string zero>
5862 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5863 "\t$Rd, $Rn, #" # zero, "", []>,
5867 let Inst{31-30} = 0b01;
5869 let Inst{28-24} = 0b11110;
5870 let Inst{23-22} = size;
5872 let Inst{20-19} = size2;
5873 let Inst{18-17} = 0b00;
5874 let Inst{16-12} = opcode;
5875 let Inst{11-10} = 0b10;
5880 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
5881 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
5882 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
5886 let Inst{31-17} = 0b011111100110000;
5887 let Inst{16-12} = opcode;
5888 let Inst{11-10} = 0b10;
5893 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
5894 SDPatternOperator OpNode> {
5895 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;
5897 def : Pat<(v1i64 (OpNode FPR64:$Rn)),
5898 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5901 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
5902 SDPatternOperator OpNode> {
5903 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;
5904 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;
5905 let Predicates = [HasNEON, HasFullFP16] in {
5906 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;
5909 def : InstAlias<asm # "\t$Rd, $Rn, #0",
5910 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
5911 def : InstAlias<asm # "\t$Rd, $Rn, #0",
5912 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
5913 let Predicates = [HasNEON, HasFullFP16] in {
5914 def : InstAlias<asm # "\t$Rd, $Rn, #0",
5915 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;
5918 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
5919 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5922 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
5923 SDPatternOperator OpNode = null_frag> {
5924 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
5925 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
5927 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
5928 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
5931 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
5932 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,[]>;
5933 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,[]>;
5934 let Predicates = [HasNEON, HasFullFP16] in {
5935 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,[]>;
5939 multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,
5940 SDPatternOperator OpNode> {
5941 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,
5942 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
5943 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,
5944 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
5945 let Predicates = [HasNEON, HasFullFP16] in {
5946 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,
5947 [(set FPR16:$Rd, (OpNode (f16 FPR16:$Rn)))]>;
5951 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
5952 SDPatternOperator OpNode = null_frag> {
5953 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5954 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,
5955 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5956 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,
5957 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
5958 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;
5959 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;
5962 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
5963 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
5966 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
5968 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5969 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
5970 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
5971 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
5972 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
5973 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
5974 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5977 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
5978 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
5983 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5984 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
5985 SDPatternOperator OpNode = null_frag> {
5986 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,
5987 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5988 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;
5989 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;
5992 //----------------------------------------------------------------------------
5993 // AdvSIMD scalar pairwise instructions
5994 //----------------------------------------------------------------------------
5996 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5997 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
5998 RegisterOperand regtype, RegisterOperand vectype,
5999 string asm, string kind>
6000 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6001 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
6005 let Inst{31-30} = 0b01;
6007 let Inst{28-24} = 0b11110;
6008 let Inst{23-22} = size;
6009 let Inst{21-17} = 0b11000;
6010 let Inst{16-12} = opcode;
6011 let Inst{11-10} = 0b10;
6016 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
6017 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
6021 multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {
6022 let Predicates = [HasNEON, HasFullFP16] in {
6023 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,
6026 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,
6028 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,
6032 //----------------------------------------------------------------------------
6033 // AdvSIMD across lanes instructions
6034 //----------------------------------------------------------------------------
6036 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6037 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
6038 RegisterClass regtype, RegisterOperand vectype,
6039 string asm, string kind, list<dag> pattern>
6040 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
6041 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
6048 let Inst{28-24} = 0b01110;
6049 let Inst{23-22} = size;
6050 let Inst{21-17} = 0b11000;
6051 let Inst{16-12} = opcode;
6052 let Inst{11-10} = 0b10;
6057 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
6059 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
6061 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
6063 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
6065 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
6067 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
6071 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
6072 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
6074 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
6076 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
6078 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
6080 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
6084 multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,
6086 let Predicates = [HasNEON, HasFullFP16] in {
6087 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,
6089 [(set FPR16:$Rd, (intOp (v4f16 V64:$Rn)))]>;
6090 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,
6092 [(set FPR16:$Rd, (intOp (v8f16 V128:$Rn)))]>;
6093 } // Predicates = [HasNEON, HasFullFP16]
6094 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
6096 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
6099 //----------------------------------------------------------------------------
6100 // AdvSIMD INS/DUP instructions
6101 //----------------------------------------------------------------------------
6103 // FIXME: There has got to be a better way to factor these. ugh.
6105 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
6106 string operands, string constraints, list<dag> pattern>
6107 : I<outs, ins, asm, operands, constraints, pattern>,
6114 let Inst{28-21} = 0b01110000;
6121 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
6122 RegisterOperand vecreg, RegisterClass regtype>
6123 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
6124 "{\t$Rd" # size # ", $Rn" #
6125 "|" # size # "\t$Rd, $Rn}", "",
6126 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
6127 let Inst{20-16} = imm5;
6128 let Inst{14-11} = 0b0001;
6131 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
6132 ValueType vectype, ValueType insreg,
6133 RegisterOperand vecreg, Operand idxtype,
6134 ValueType elttype, SDNode OpNode>
6135 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
6136 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
6137 "|" # dstkind # "\t$Rd, $Rn$idx}", "",
6138 [(set (vectype vecreg:$Rd),
6139 (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
6140 let Inst{14-11} = 0b0000;
6143 class SIMDDup64FromElement
6144 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
6145 VectorIndexD, i64, AArch64duplane64> {
6148 let Inst{19-16} = 0b1000;
6151 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
6152 RegisterOperand vecreg>
6153 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
6154 VectorIndexS, i64, AArch64duplane32> {
6156 let Inst{20-19} = idx;
6157 let Inst{18-16} = 0b100;
6160 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
6161 RegisterOperand vecreg>
6162 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
6163 VectorIndexH, i64, AArch64duplane16> {
6165 let Inst{20-18} = idx;
6166 let Inst{17-16} = 0b10;
6169 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
6170 RegisterOperand vecreg>
6171 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
6172 VectorIndexB, i64, AArch64duplane8> {
6174 let Inst{20-17} = idx;
6178 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
6179 Operand idxtype, string asm, list<dag> pattern>
6180 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
6181 "{\t$Rd, $Rn" # size # "$idx" #
6182 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
6183 let Inst{14-11} = imm4;
6186 class SIMDSMov<bit Q, string size, RegisterClass regtype,
6188 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
6189 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
6191 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
6192 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
6194 class SIMDMovAlias<string asm, string size, Instruction inst,
6195 RegisterClass regtype, Operand idxtype>
6196 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
6197 "|" # size # "\t$dst, $src$idx}",
6198 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
6201 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
6203 let Inst{20-17} = idx;
6206 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
6208 let Inst{20-17} = idx;
6211 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
6213 let Inst{20-18} = idx;
6214 let Inst{17-16} = 0b10;
6216 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
6218 let Inst{20-18} = idx;
6219 let Inst{17-16} = 0b10;
6221 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
6223 let Inst{20-19} = idx;
6224 let Inst{18-16} = 0b100;
6229 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
6231 let Inst{20-17} = idx;
6234 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
6236 let Inst{20-18} = idx;
6237 let Inst{17-16} = 0b10;
6239 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
6241 let Inst{20-19} = idx;
6242 let Inst{18-16} = 0b100;
6244 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
6247 let Inst{19-16} = 0b1000;
6249 def : SIMDMovAlias<"mov", ".s",
6250 !cast<Instruction>(NAME#"vi32"),
6251 GPR32, VectorIndexS>;
6252 def : SIMDMovAlias<"mov", ".d",
6253 !cast<Instruction>(NAME#"vi64"),
6254 GPR64, VectorIndexD>;
6257 class SIMDInsFromMain<string size, ValueType vectype,
6258 RegisterClass regtype, Operand idxtype>
6259 : BaseSIMDInsDup<1, 0, (outs V128:$dst),
6260 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
6261 "{\t$Rd" # size # "$idx, $Rn" #
6262 "|" # size # "\t$Rd$idx, $Rn}",
6265 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
6266 let Inst{14-11} = 0b0011;
6269 class SIMDInsFromElement<string size, ValueType vectype,
6270 ValueType elttype, Operand idxtype>
6271 : BaseSIMDInsDup<1, 1, (outs V128:$dst),
6272 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
6273 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
6274 "|" # size # "\t$Rd$idx, $Rn$idx2}",
6279 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
6282 class SIMDInsMainMovAlias<string size, Instruction inst,
6283 RegisterClass regtype, Operand idxtype>
6284 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
6285 "|" # size #"\t$dst$idx, $src}",
6286 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
6287 class SIMDInsElementMovAlias<string size, Instruction inst,
6289 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
6290 # "|" # size #"\t$dst$idx, $src$idx2}",
6291 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
6294 multiclass SIMDIns {
6295 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
6297 let Inst{20-17} = idx;
6300 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
6302 let Inst{20-18} = idx;
6303 let Inst{17-16} = 0b10;
6305 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
6307 let Inst{20-19} = idx;
6308 let Inst{18-16} = 0b100;
6310 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
6313 let Inst{19-16} = 0b1000;
6316 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
6319 let Inst{20-17} = idx;
6321 let Inst{14-11} = idx2;
6323 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
6326 let Inst{20-18} = idx;
6327 let Inst{17-16} = 0b10;
6328 let Inst{14-12} = idx2;
6331 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
6334 let Inst{20-19} = idx;
6335 let Inst{18-16} = 0b100;
6336 let Inst{14-13} = idx2;
6337 let Inst{12-11} = {?,?};
6339 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
6343 let Inst{19-16} = 0b1000;
6344 let Inst{14} = idx2;
6345 let Inst{13-11} = {?,?,?};
6348 // For all forms of the INS instruction, the "mov" mnemonic is the
6349 // preferred alias. Why they didn't just call the instruction "mov" in
6350 // the first place is a very good question indeed...
6351 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
6352 GPR32, VectorIndexB>;
6353 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
6354 GPR32, VectorIndexH>;
6355 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
6356 GPR32, VectorIndexS>;
6357 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
6358 GPR64, VectorIndexD>;
6360 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
6362 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
6364 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
6366 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
6370 //----------------------------------------------------------------------------
6372 //----------------------------------------------------------------------------
6374 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6375 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6376 RegisterOperand listtype, string asm, string kind>
6377 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
6378 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
6385 let Inst{29-21} = 0b001110000;
6386 let Inst{20-16} = Vm;
6388 let Inst{14-13} = len;
6390 let Inst{11-10} = 0b00;
6395 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6396 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6397 RegisterOperand listtype, string asm, string kind>
6398 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
6399 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
6406 let Inst{29-21} = 0b001110000;
6407 let Inst{20-16} = Vm;
6409 let Inst{14-13} = len;
6411 let Inst{11-10} = 0b00;
6416 class SIMDTableLookupAlias<string asm, Instruction inst,
6417 RegisterOperand vectype, RegisterOperand listtype>
6418 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
6419 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
6421 multiclass SIMDTableLookup<bit op, string asm> {
6422 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
6424 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
6426 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
6428 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
6430 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
6432 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
6434 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
6436 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
6439 def : SIMDTableLookupAlias<asm # ".8b",
6440 !cast<Instruction>(NAME#"v8i8One"),
6441 V64, VecListOne128>;
6442 def : SIMDTableLookupAlias<asm # ".8b",
6443 !cast<Instruction>(NAME#"v8i8Two"),
6444 V64, VecListTwo128>;
6445 def : SIMDTableLookupAlias<asm # ".8b",
6446 !cast<Instruction>(NAME#"v8i8Three"),
6447 V64, VecListThree128>;
6448 def : SIMDTableLookupAlias<asm # ".8b",
6449 !cast<Instruction>(NAME#"v8i8Four"),
6450 V64, VecListFour128>;
6451 def : SIMDTableLookupAlias<asm # ".16b",
6452 !cast<Instruction>(NAME#"v16i8One"),
6453 V128, VecListOne128>;
6454 def : SIMDTableLookupAlias<asm # ".16b",
6455 !cast<Instruction>(NAME#"v16i8Two"),
6456 V128, VecListTwo128>;
6457 def : SIMDTableLookupAlias<asm # ".16b",
6458 !cast<Instruction>(NAME#"v16i8Three"),
6459 V128, VecListThree128>;
6460 def : SIMDTableLookupAlias<asm # ".16b",
6461 !cast<Instruction>(NAME#"v16i8Four"),
6462 V128, VecListFour128>;
6465 multiclass SIMDTableLookupTied<bit op, string asm> {
6466 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
6468 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
6470 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
6472 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
6474 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
6476 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
6478 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
6480 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
6483 def : SIMDTableLookupAlias<asm # ".8b",
6484 !cast<Instruction>(NAME#"v8i8One"),
6485 V64, VecListOne128>;
6486 def : SIMDTableLookupAlias<asm # ".8b",
6487 !cast<Instruction>(NAME#"v8i8Two"),
6488 V64, VecListTwo128>;
6489 def : SIMDTableLookupAlias<asm # ".8b",
6490 !cast<Instruction>(NAME#"v8i8Three"),
6491 V64, VecListThree128>;
6492 def : SIMDTableLookupAlias<asm # ".8b",
6493 !cast<Instruction>(NAME#"v8i8Four"),
6494 V64, VecListFour128>;
6495 def : SIMDTableLookupAlias<asm # ".16b",
6496 !cast<Instruction>(NAME#"v16i8One"),
6497 V128, VecListOne128>;
6498 def : SIMDTableLookupAlias<asm # ".16b",
6499 !cast<Instruction>(NAME#"v16i8Two"),
6500 V128, VecListTwo128>;
6501 def : SIMDTableLookupAlias<asm # ".16b",
6502 !cast<Instruction>(NAME#"v16i8Three"),
6503 V128, VecListThree128>;
6504 def : SIMDTableLookupAlias<asm # ".16b",
6505 !cast<Instruction>(NAME#"v16i8Four"),
6506 V128, VecListFour128>;
6510 //----------------------------------------------------------------------------
6511 // AdvSIMD scalar CPY
6512 //----------------------------------------------------------------------------
6513 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6514 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
6515 string kind, Operand idxtype>
6516 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
6517 "{\t$dst, $src" # kind # "$idx" #
6518 "|\t$dst, $src$idx}", "", []>,
6522 let Inst{31-21} = 0b01011110000;
6523 let Inst{15-10} = 0b000001;
6524 let Inst{9-5} = src;
6525 let Inst{4-0} = dst;
6528 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
6529 RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
6530 : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
6531 # "|\t$dst, $src$index}",
6532 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
6535 multiclass SIMDScalarCPY<string asm> {
6536 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> {
6538 let Inst{20-17} = idx;
6541 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
6543 let Inst{20-18} = idx;
6544 let Inst{17-16} = 0b10;
6546 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
6548 let Inst{20-19} = idx;
6549 let Inst{18-16} = 0b100;
6551 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
6554 let Inst{19-16} = 0b1000;
6557 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
6558 VectorIndexD:$idx)))),
6559 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
6561 // 'DUP' mnemonic aliases.
6562 def : SIMDScalarCPYAlias<"dup", ".b",
6563 !cast<Instruction>(NAME#"i8"),
6564 FPR8, V128, VectorIndexB>;
6565 def : SIMDScalarCPYAlias<"dup", ".h",
6566 !cast<Instruction>(NAME#"i16"),
6567 FPR16, V128, VectorIndexH>;
6568 def : SIMDScalarCPYAlias<"dup", ".s",
6569 !cast<Instruction>(NAME#"i32"),
6570 FPR32, V128, VectorIndexS>;
6571 def : SIMDScalarCPYAlias<"dup", ".d",
6572 !cast<Instruction>(NAME#"i64"),
6573 FPR64, V128, VectorIndexD>;
6576 //----------------------------------------------------------------------------
6577 // AdvSIMD modified immediate instructions
6578 //----------------------------------------------------------------------------
6580 class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,
6581 string asm, string op_string,
6582 string cstr, list<dag> pattern>
6583 : I<oops, iops, asm, op_string, cstr, pattern>,
6590 let Inst{28-19} = 0b0111100000;
6591 let Inst{18-16} = imm8{7-5};
6594 let Inst{9-5} = imm8{4-0};
6598 class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,
6599 Operand immtype, dag opt_shift_iop,
6600 string opt_shift, string asm, string kind,
6602 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),
6603 !con((ins immtype:$imm8), opt_shift_iop), asm,
6604 "{\t$Rd" # kind # ", $imm8" # opt_shift #
6605 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6607 let DecoderMethod = "DecodeModImmInstruction";
6610 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
6611 Operand immtype, dag opt_shift_iop,
6612 string opt_shift, string asm, string kind,
6614 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),
6615 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
6616 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
6617 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6618 "$Rd = $dst", pattern> {
6619 let DecoderMethod = "DecodeModImmTiedInstruction";
6622 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
6623 RegisterOperand vectype, string asm,
6624 string kind, list<dag> pattern>
6625 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
6626 (ins logical_vec_shift:$shift),
6627 "$shift", asm, kind, pattern> {
6629 let Inst{15} = b15_b12{1};
6630 let Inst{14-13} = shift;
6631 let Inst{12} = b15_b12{0};
6634 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
6635 RegisterOperand vectype, string asm,
6636 string kind, list<dag> pattern>
6637 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6638 (ins logical_vec_shift:$shift),
6639 "$shift", asm, kind, pattern> {
6641 let Inst{15} = b15_b12{1};
6642 let Inst{14-13} = shift;
6643 let Inst{12} = b15_b12{0};
6647 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
6648 RegisterOperand vectype, string asm,
6649 string kind, list<dag> pattern>
6650 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
6651 (ins logical_vec_hw_shift:$shift),
6652 "$shift", asm, kind, pattern> {
6654 let Inst{15} = b15_b12{1};
6656 let Inst{13} = shift{0};
6657 let Inst{12} = b15_b12{0};
6660 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
6661 RegisterOperand vectype, string asm,
6662 string kind, list<dag> pattern>
6663 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6664 (ins logical_vec_hw_shift:$shift),
6665 "$shift", asm, kind, pattern> {
6667 let Inst{15} = b15_b12{1};
6669 let Inst{13} = shift{0};
6670 let Inst{12} = b15_b12{0};
6673 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
6675 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
6677 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
6680 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
6682 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
6686 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
6687 bits<2> w_cmode, string asm,
6689 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
6691 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
6693 (i32 imm:$shift)))]>;
6694 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
6696 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
6698 (i32 imm:$shift)))]>;
6700 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
6702 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
6704 (i32 imm:$shift)))]>;
6705 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
6707 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
6709 (i32 imm:$shift)))]>;
6712 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
6713 RegisterOperand vectype, string asm,
6714 string kind, list<dag> pattern>
6715 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,
6716 (ins move_vec_shift:$shift),
6717 "$shift", asm, kind, pattern> {
6719 let Inst{15-13} = cmode{3-1};
6720 let Inst{12} = shift;
6723 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,
6724 RegisterOperand vectype,
6725 Operand imm_type, string asm,
6726 string kind, list<dag> pattern>
6727 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",
6728 asm, kind, pattern> {
6729 let Inst{15-12} = cmode;
6732 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
6734 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
6735 "\t$Rd, $imm8", "", pattern> {
6736 let Inst{15-12} = cmode;
6737 let DecoderMethod = "DecodeModImmInstruction";
6740 //----------------------------------------------------------------------------
6741 // AdvSIMD indexed element
6742 //----------------------------------------------------------------------------
6744 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6745 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6746 RegisterOperand dst_reg, RegisterOperand lhs_reg,
6747 RegisterOperand rhs_reg, Operand vec_idx, string asm,
6748 string apple_kind, string dst_kind, string lhs_kind,
6749 string rhs_kind, list<dag> pattern>
6750 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
6752 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6753 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
6762 let Inst{28} = Scalar;
6763 let Inst{27-24} = 0b1111;
6764 let Inst{23-22} = size;
6765 // Bit 21 must be set by the derived class.
6766 let Inst{20-16} = Rm;
6767 let Inst{15-12} = opc;
6768 // Bit 11 must be set by the derived class.
6774 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6775 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6776 RegisterOperand dst_reg, RegisterOperand lhs_reg,
6777 RegisterOperand rhs_reg, Operand vec_idx, string asm,
6778 string apple_kind, string dst_kind, string lhs_kind,
6779 string rhs_kind, list<dag> pattern>
6780 : I<(outs dst_reg:$dst),
6781 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
6782 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6783 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
6792 let Inst{28} = Scalar;
6793 let Inst{27-24} = 0b1111;
6794 let Inst{23-22} = size;
6795 // Bit 21 must be set by the derived class.
6796 let Inst{20-16} = Rm;
6797 let Inst{15-12} = opc;
6798 // Bit 11 must be set by the derived class.
6804 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
6805 SDPatternOperator OpNode> {
6806 let Predicates = [HasNEON, HasFullFP16] in {
6807 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,
6809 V128_lo, VectorIndexH,
6810 asm, ".4h", ".4h", ".4h", ".h",
6811 [(set (v4f16 V64:$Rd),
6812 (OpNode (v4f16 V64:$Rn),
6813 (v4f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6815 let Inst{11} = idx{2};
6816 let Inst{21} = idx{1};
6817 let Inst{20} = idx{0};
6820 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,
6822 V128_lo, VectorIndexH,
6823 asm, ".8h", ".8h", ".8h", ".h",
6824 [(set (v8f16 V128:$Rd),
6825 (OpNode (v8f16 V128:$Rn),
6826 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6828 let Inst{11} = idx{2};
6829 let Inst{21} = idx{1};
6830 let Inst{20} = idx{0};
6832 } // Predicates = [HasNEON, HasFullFP16]
6834 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6837 asm, ".2s", ".2s", ".2s", ".s",
6838 [(set (v2f32 V64:$Rd),
6839 (OpNode (v2f32 V64:$Rn),
6840 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6842 let Inst{11} = idx{1};
6843 let Inst{21} = idx{0};
6846 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6849 asm, ".4s", ".4s", ".4s", ".s",
6850 [(set (v4f32 V128:$Rd),
6851 (OpNode (v4f32 V128:$Rn),
6852 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6854 let Inst{11} = idx{1};
6855 let Inst{21} = idx{0};
6858 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
6861 asm, ".2d", ".2d", ".2d", ".d",
6862 [(set (v2f64 V128:$Rd),
6863 (OpNode (v2f64 V128:$Rn),
6864 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
6866 let Inst{11} = idx{0};
6870 let Predicates = [HasNEON, HasFullFP16] in {
6871 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,
6872 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
6873 asm, ".h", "", "", ".h",
6874 [(set (f16 FPR16Op:$Rd),
6875 (OpNode (f16 FPR16Op:$Rn),
6876 (f16 (vector_extract (v8f16 V128_lo:$Rm),
6877 VectorIndexH:$idx))))]> {
6879 let Inst{11} = idx{2};
6880 let Inst{21} = idx{1};
6881 let Inst{20} = idx{0};
6883 } // Predicates = [HasNEON, HasFullFP16]
6885 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6886 FPR32Op, FPR32Op, V128, VectorIndexS,
6887 asm, ".s", "", "", ".s",
6888 [(set (f32 FPR32Op:$Rd),
6889 (OpNode (f32 FPR32Op:$Rn),
6890 (f32 (vector_extract (v4f32 V128:$Rm),
6891 VectorIndexS:$idx))))]> {
6893 let Inst{11} = idx{1};
6894 let Inst{21} = idx{0};
6897 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
6898 FPR64Op, FPR64Op, V128, VectorIndexD,
6899 asm, ".d", "", "", ".d",
6900 [(set (f64 FPR64Op:$Rd),
6901 (OpNode (f64 FPR64Op:$Rn),
6902 (f64 (vector_extract (v2f64 V128:$Rm),
6903 VectorIndexD:$idx))))]> {
6905 let Inst{11} = idx{0};
6910 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
6911 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
6912 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6913 (AArch64duplane32 (v4f32 V128:$Rm),
6914 VectorIndexS:$idx))),
6915 (!cast<Instruction>(INST # v2i32_indexed)
6916 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6917 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6918 (AArch64dup (f32 FPR32Op:$Rm)))),
6919 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
6920 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6923 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
6924 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6925 (AArch64duplane32 (v4f32 V128:$Rm),
6926 VectorIndexS:$idx))),
6927 (!cast<Instruction>(INST # "v4i32_indexed")
6928 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6929 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6930 (AArch64dup (f32 FPR32Op:$Rm)))),
6931 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
6932 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6934 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
6935 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6936 (AArch64duplane64 (v2f64 V128:$Rm),
6937 VectorIndexD:$idx))),
6938 (!cast<Instruction>(INST # "v2i64_indexed")
6939 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6940 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6941 (AArch64dup (f64 FPR64Op:$Rm)))),
6942 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
6943 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
6945 // 2 variants for 32-bit scalar version: extract from .2s or from .4s
6946 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6947 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
6948 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6949 V128:$Rm, VectorIndexS:$idx)>;
6950 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6951 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
6952 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6953 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
6955 // 1 variant for 64-bit scalar version: extract from .1d or from .2d
6956 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
6957 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
6958 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
6959 V128:$Rm, VectorIndexD:$idx)>;
6962 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
6963 let Predicates = [HasNEON, HasFullFP16] in {
6964 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,
6965 V128_lo, VectorIndexH,
6966 asm, ".4h", ".4h", ".4h", ".h", []> {
6968 let Inst{11} = idx{2};
6969 let Inst{21} = idx{1};
6970 let Inst{20} = idx{0};
6973 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,
6975 V128_lo, VectorIndexH,
6976 asm, ".8h", ".8h", ".8h", ".h", []> {
6978 let Inst{11} = idx{2};
6979 let Inst{21} = idx{1};
6980 let Inst{20} = idx{0};
6982 } // Predicates = [HasNEON, HasFullFP16]
6984 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
6986 asm, ".2s", ".2s", ".2s", ".s", []> {
6988 let Inst{11} = idx{1};
6989 let Inst{21} = idx{0};
6992 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6995 asm, ".4s", ".4s", ".4s", ".s", []> {
6997 let Inst{11} = idx{1};
6998 let Inst{21} = idx{0};
7001 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
7004 asm, ".2d", ".2d", ".2d", ".d", []> {
7006 let Inst{11} = idx{0};
7010 let Predicates = [HasNEON, HasFullFP16] in {
7011 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,
7012 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7013 asm, ".h", "", "", ".h", []> {
7015 let Inst{11} = idx{2};
7016 let Inst{21} = idx{1};
7017 let Inst{20} = idx{0};
7019 } // Predicates = [HasNEON, HasFullFP16]
7021 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7022 FPR32Op, FPR32Op, V128, VectorIndexS,
7023 asm, ".s", "", "", ".s", []> {
7025 let Inst{11} = idx{1};
7026 let Inst{21} = idx{0};
7029 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
7030 FPR64Op, FPR64Op, V128, VectorIndexD,
7031 asm, ".d", "", "", ".d", []> {
7033 let Inst{11} = idx{0};
7038 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
7039 SDPatternOperator OpNode> {
7040 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
7041 V128_lo, VectorIndexH,
7042 asm, ".4h", ".4h", ".4h", ".h",
7043 [(set (v4i16 V64:$Rd),
7044 (OpNode (v4i16 V64:$Rn),
7045 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7047 let Inst{11} = idx{2};
7048 let Inst{21} = idx{1};
7049 let Inst{20} = idx{0};
7052 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7054 V128_lo, VectorIndexH,
7055 asm, ".8h", ".8h", ".8h", ".h",
7056 [(set (v8i16 V128:$Rd),
7057 (OpNode (v8i16 V128:$Rn),
7058 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7060 let Inst{11} = idx{2};
7061 let Inst{21} = idx{1};
7062 let Inst{20} = idx{0};
7065 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7068 asm, ".2s", ".2s", ".2s", ".s",
7069 [(set (v2i32 V64:$Rd),
7070 (OpNode (v2i32 V64:$Rn),
7071 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7073 let Inst{11} = idx{1};
7074 let Inst{21} = idx{0};
7077 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7080 asm, ".4s", ".4s", ".4s", ".s",
7081 [(set (v4i32 V128:$Rd),
7082 (OpNode (v4i32 V128:$Rn),
7083 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7085 let Inst{11} = idx{1};
7086 let Inst{21} = idx{0};
7089 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7090 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
7091 asm, ".h", "", "", ".h", []> {
7093 let Inst{11} = idx{2};
7094 let Inst{21} = idx{1};
7095 let Inst{20} = idx{0};
7098 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7099 FPR32Op, FPR32Op, V128, VectorIndexS,
7100 asm, ".s", "", "", ".s",
7101 [(set (i32 FPR32Op:$Rd),
7102 (OpNode FPR32Op:$Rn,
7103 (i32 (vector_extract (v4i32 V128:$Rm),
7104 VectorIndexS:$idx))))]> {
7106 let Inst{11} = idx{1};
7107 let Inst{21} = idx{0};
7111 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
7112 SDPatternOperator OpNode> {
7113 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7115 V128_lo, VectorIndexH,
7116 asm, ".4h", ".4h", ".4h", ".h",
7117 [(set (v4i16 V64:$Rd),
7118 (OpNode (v4i16 V64:$Rn),
7119 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7121 let Inst{11} = idx{2};
7122 let Inst{21} = idx{1};
7123 let Inst{20} = idx{0};
7126 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7128 V128_lo, VectorIndexH,
7129 asm, ".8h", ".8h", ".8h", ".h",
7130 [(set (v8i16 V128:$Rd),
7131 (OpNode (v8i16 V128:$Rn),
7132 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7134 let Inst{11} = idx{2};
7135 let Inst{21} = idx{1};
7136 let Inst{20} = idx{0};
7139 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7142 asm, ".2s", ".2s", ".2s", ".s",
7143 [(set (v2i32 V64:$Rd),
7144 (OpNode (v2i32 V64:$Rn),
7145 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7147 let Inst{11} = idx{1};
7148 let Inst{21} = idx{0};
7151 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7154 asm, ".4s", ".4s", ".4s", ".s",
7155 [(set (v4i32 V128:$Rd),
7156 (OpNode (v4i32 V128:$Rn),
7157 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7159 let Inst{11} = idx{1};
7160 let Inst{21} = idx{0};
7164 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
7165 SDPatternOperator OpNode> {
7166 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
7167 V128_lo, VectorIndexH,
7168 asm, ".4h", ".4h", ".4h", ".h",
7169 [(set (v4i16 V64:$dst),
7170 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
7171 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7173 let Inst{11} = idx{2};
7174 let Inst{21} = idx{1};
7175 let Inst{20} = idx{0};
7178 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7180 V128_lo, VectorIndexH,
7181 asm, ".8h", ".8h", ".8h", ".h",
7182 [(set (v8i16 V128:$dst),
7183 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7184 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7186 let Inst{11} = idx{2};
7187 let Inst{21} = idx{1};
7188 let Inst{20} = idx{0};
7191 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7194 asm, ".2s", ".2s", ".2s", ".s",
7195 [(set (v2i32 V64:$dst),
7196 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7197 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7199 let Inst{11} = idx{1};
7200 let Inst{21} = idx{0};
7203 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7206 asm, ".4s", ".4s", ".4s", ".s",
7207 [(set (v4i32 V128:$dst),
7208 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7209 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7211 let Inst{11} = idx{1};
7212 let Inst{21} = idx{0};
7216 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
7217 SDPatternOperator OpNode> {
7218 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7220 V128_lo, VectorIndexH,
7221 asm, ".4s", ".4s", ".4h", ".h",
7222 [(set (v4i32 V128:$Rd),
7223 (OpNode (v4i16 V64:$Rn),
7224 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7226 let Inst{11} = idx{2};
7227 let Inst{21} = idx{1};
7228 let Inst{20} = idx{0};
7231 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7233 V128_lo, VectorIndexH,
7234 asm#"2", ".4s", ".4s", ".8h", ".h",
7235 [(set (v4i32 V128:$Rd),
7236 (OpNode (extract_high_v8i16 V128:$Rn),
7237 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7238 VectorIndexH:$idx))))]> {
7241 let Inst{11} = idx{2};
7242 let Inst{21} = idx{1};
7243 let Inst{20} = idx{0};
7246 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7249 asm, ".2d", ".2d", ".2s", ".s",
7250 [(set (v2i64 V128:$Rd),
7251 (OpNode (v2i32 V64:$Rn),
7252 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7254 let Inst{11} = idx{1};
7255 let Inst{21} = idx{0};
7258 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7261 asm#"2", ".2d", ".2d", ".4s", ".s",
7262 [(set (v2i64 V128:$Rd),
7263 (OpNode (extract_high_v4i32 V128:$Rn),
7264 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7265 VectorIndexS:$idx))))]> {
7267 let Inst{11} = idx{1};
7268 let Inst{21} = idx{0};
7271 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
7272 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7273 asm, ".h", "", "", ".h", []> {
7275 let Inst{11} = idx{2};
7276 let Inst{21} = idx{1};
7277 let Inst{20} = idx{0};
7280 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
7281 FPR64Op, FPR32Op, V128, VectorIndexS,
7282 asm, ".s", "", "", ".s", []> {
7284 let Inst{11} = idx{1};
7285 let Inst{21} = idx{0};
7289 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
7290 SDPatternOperator Accum> {
7291 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7293 V128_lo, VectorIndexH,
7294 asm, ".4s", ".4s", ".4h", ".h",
7295 [(set (v4i32 V128:$dst),
7296 (Accum (v4i32 V128:$Rd),
7297 (v4i32 (int_aarch64_neon_sqdmull
7299 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7300 VectorIndexH:$idx))))))]> {
7302 let Inst{11} = idx{2};
7303 let Inst{21} = idx{1};
7304 let Inst{20} = idx{0};
7307 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
7308 // intermediate EXTRACT_SUBREG would be untyped.
7309 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
7310 (i32 (vector_extract (v4i32
7311 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
7312 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7313 VectorIndexH:$idx)))),
7316 (!cast<Instruction>(NAME # v4i16_indexed)
7317 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
7318 V128_lo:$Rm, VectorIndexH:$idx),
7321 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7323 V128_lo, VectorIndexH,
7324 asm#"2", ".4s", ".4s", ".8h", ".h",
7325 [(set (v4i32 V128:$dst),
7326 (Accum (v4i32 V128:$Rd),
7327 (v4i32 (int_aarch64_neon_sqdmull
7328 (extract_high_v8i16 V128:$Rn),
7330 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7331 VectorIndexH:$idx))))))]> {
7333 let Inst{11} = idx{2};
7334 let Inst{21} = idx{1};
7335 let Inst{20} = idx{0};
7338 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7341 asm, ".2d", ".2d", ".2s", ".s",
7342 [(set (v2i64 V128:$dst),
7343 (Accum (v2i64 V128:$Rd),
7344 (v2i64 (int_aarch64_neon_sqdmull
7346 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
7347 VectorIndexS:$idx))))))]> {
7349 let Inst{11} = idx{1};
7350 let Inst{21} = idx{0};
7353 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7356 asm#"2", ".2d", ".2d", ".4s", ".s",
7357 [(set (v2i64 V128:$dst),
7358 (Accum (v2i64 V128:$Rd),
7359 (v2i64 (int_aarch64_neon_sqdmull
7360 (extract_high_v4i32 V128:$Rn),
7362 (AArch64duplane32 (v4i32 V128:$Rm),
7363 VectorIndexS:$idx))))))]> {
7365 let Inst{11} = idx{1};
7366 let Inst{21} = idx{0};
7369 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
7370 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
7371 asm, ".h", "", "", ".h", []> {
7373 let Inst{11} = idx{2};
7374 let Inst{21} = idx{1};
7375 let Inst{20} = idx{0};
7379 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7380 FPR64Op, FPR32Op, V128, VectorIndexS,
7381 asm, ".s", "", "", ".s",
7382 [(set (i64 FPR64Op:$dst),
7383 (Accum (i64 FPR64Op:$Rd),
7384 (i64 (int_aarch64_neon_sqdmulls_scalar
7386 (i32 (vector_extract (v4i32 V128:$Rm),
7387 VectorIndexS:$idx))))))]> {
7390 let Inst{11} = idx{1};
7391 let Inst{21} = idx{0};
7395 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
7396 SDPatternOperator OpNode> {
7397 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7398 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7400 V128_lo, VectorIndexH,
7401 asm, ".4s", ".4s", ".4h", ".h",
7402 [(set (v4i32 V128:$Rd),
7403 (OpNode (v4i16 V64:$Rn),
7404 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7406 let Inst{11} = idx{2};
7407 let Inst{21} = idx{1};
7408 let Inst{20} = idx{0};
7411 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7413 V128_lo, VectorIndexH,
7414 asm#"2", ".4s", ".4s", ".8h", ".h",
7415 [(set (v4i32 V128:$Rd),
7416 (OpNode (extract_high_v8i16 V128:$Rn),
7417 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7418 VectorIndexH:$idx))))]> {
7421 let Inst{11} = idx{2};
7422 let Inst{21} = idx{1};
7423 let Inst{20} = idx{0};
7426 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7429 asm, ".2d", ".2d", ".2s", ".s",
7430 [(set (v2i64 V128:$Rd),
7431 (OpNode (v2i32 V64:$Rn),
7432 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7434 let Inst{11} = idx{1};
7435 let Inst{21} = idx{0};
7438 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7441 asm#"2", ".2d", ".2d", ".4s", ".s",
7442 [(set (v2i64 V128:$Rd),
7443 (OpNode (extract_high_v4i32 V128:$Rn),
7444 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7445 VectorIndexS:$idx))))]> {
7447 let Inst{11} = idx{1};
7448 let Inst{21} = idx{0};
7453 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
7454 SDPatternOperator OpNode> {
7455 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7456 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7458 V128_lo, VectorIndexH,
7459 asm, ".4s", ".4s", ".4h", ".h",
7460 [(set (v4i32 V128:$dst),
7461 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
7462 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7464 let Inst{11} = idx{2};
7465 let Inst{21} = idx{1};
7466 let Inst{20} = idx{0};
7469 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7471 V128_lo, VectorIndexH,
7472 asm#"2", ".4s", ".4s", ".8h", ".h",
7473 [(set (v4i32 V128:$dst),
7474 (OpNode (v4i32 V128:$Rd),
7475 (extract_high_v8i16 V128:$Rn),
7476 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7477 VectorIndexH:$idx))))]> {
7479 let Inst{11} = idx{2};
7480 let Inst{21} = idx{1};
7481 let Inst{20} = idx{0};
7484 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7487 asm, ".2d", ".2d", ".2s", ".s",
7488 [(set (v2i64 V128:$dst),
7489 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
7490 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7492 let Inst{11} = idx{1};
7493 let Inst{21} = idx{0};
7496 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7499 asm#"2", ".2d", ".2d", ".4s", ".s",
7500 [(set (v2i64 V128:$dst),
7501 (OpNode (v2i64 V128:$Rd),
7502 (extract_high_v4i32 V128:$Rn),
7503 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7504 VectorIndexS:$idx))))]> {
7506 let Inst{11} = idx{1};
7507 let Inst{21} = idx{0};
7512 //----------------------------------------------------------------------------
7513 // AdvSIMD scalar shift by immediate
7514 //----------------------------------------------------------------------------
7516 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7517 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
7518 RegisterClass regtype1, RegisterClass regtype2,
7519 Operand immtype, string asm, list<dag> pattern>
7520 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
7521 asm, "\t$Rd, $Rn, $imm", "", pattern>,
7526 let Inst{31-30} = 0b01;
7528 let Inst{28-23} = 0b111110;
7529 let Inst{22-16} = fixed_imm;
7530 let Inst{15-11} = opc;
7536 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7537 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
7538 RegisterClass regtype1, RegisterClass regtype2,
7539 Operand immtype, string asm, list<dag> pattern>
7540 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
7541 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
7546 let Inst{31-30} = 0b01;
7548 let Inst{28-23} = 0b111110;
7549 let Inst{22-16} = fixed_imm;
7550 let Inst{15-11} = opc;
7557 multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {
7558 let Predicates = [HasNEON, HasFullFP16] in {
7559 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7560 FPR16, FPR16, vecshiftR16, asm, []> {
7561 let Inst{19-16} = imm{3-0};
7563 } // Predicates = [HasNEON, HasFullFP16]
7564 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7565 FPR32, FPR32, vecshiftR32, asm, []> {
7566 let Inst{20-16} = imm{4-0};
7569 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7570 FPR64, FPR64, vecshiftR64, asm, []> {
7571 let Inst{21-16} = imm{5-0};
7575 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
7576 SDPatternOperator OpNode> {
7577 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7578 FPR64, FPR64, vecshiftR64, asm,
7579 [(set (i64 FPR64:$Rd),
7580 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
7581 let Inst{21-16} = imm{5-0};
7584 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
7585 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
7588 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
7589 SDPatternOperator OpNode = null_frag> {
7590 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7591 FPR64, FPR64, vecshiftR64, asm,
7592 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
7593 (i32 vecshiftR64:$imm)))]> {
7594 let Inst{21-16} = imm{5-0};
7597 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
7598 (i32 vecshiftR64:$imm))),
7599 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
7603 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
7604 SDPatternOperator OpNode> {
7605 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7606 FPR64, FPR64, vecshiftL64, asm,
7607 [(set (v1i64 FPR64:$Rd),
7608 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7609 let Inst{21-16} = imm{5-0};
7613 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7614 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
7615 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7616 FPR64, FPR64, vecshiftL64, asm, []> {
7617 let Inst{21-16} = imm{5-0};
7621 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7622 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
7623 SDPatternOperator OpNode = null_frag> {
7624 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7625 FPR8, FPR16, vecshiftR8, asm, []> {
7626 let Inst{18-16} = imm{2-0};
7629 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7630 FPR16, FPR32, vecshiftR16, asm, []> {
7631 let Inst{19-16} = imm{3-0};
7634 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7635 FPR32, FPR64, vecshiftR32, asm,
7636 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
7637 let Inst{20-16} = imm{4-0};
7641 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
7642 SDPatternOperator OpNode> {
7643 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7644 FPR8, FPR8, vecshiftL8, asm, []> {
7645 let Inst{18-16} = imm{2-0};
7648 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7649 FPR16, FPR16, vecshiftL16, asm, []> {
7650 let Inst{19-16} = imm{3-0};
7653 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7654 FPR32, FPR32, vecshiftL32, asm,
7655 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
7656 let Inst{20-16} = imm{4-0};
7659 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7660 FPR64, FPR64, vecshiftL64, asm,
7661 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7662 let Inst{21-16} = imm{5-0};
7665 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
7666 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
7669 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
7670 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7671 FPR8, FPR8, vecshiftR8, asm, []> {
7672 let Inst{18-16} = imm{2-0};
7675 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7676 FPR16, FPR16, vecshiftR16, asm, []> {
7677 let Inst{19-16} = imm{3-0};
7680 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7681 FPR32, FPR32, vecshiftR32, asm, []> {
7682 let Inst{20-16} = imm{4-0};
7685 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7686 FPR64, FPR64, vecshiftR64, asm, []> {
7687 let Inst{21-16} = imm{5-0};
7691 //----------------------------------------------------------------------------
7692 // AdvSIMD vector x indexed element
7693 //----------------------------------------------------------------------------
7695 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7696 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7697 RegisterOperand dst_reg, RegisterOperand src_reg,
7699 string asm, string dst_kind, string src_kind,
7701 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
7702 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7703 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
7710 let Inst{28-23} = 0b011110;
7711 let Inst{22-16} = fixed_imm;
7712 let Inst{15-11} = opc;
7718 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7719 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7720 RegisterOperand vectype1, RegisterOperand vectype2,
7722 string asm, string dst_kind, string src_kind,
7724 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
7725 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7726 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
7733 let Inst{28-23} = 0b011110;
7734 let Inst{22-16} = fixed_imm;
7735 let Inst{15-11} = opc;
7741 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
7743 let Predicates = [HasNEON, HasFullFP16] in {
7744 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7745 V64, V64, vecshiftR16,
7747 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 imm:$imm)))]> {
7749 let Inst{19-16} = imm;
7752 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7753 V128, V128, vecshiftR16,
7755 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 imm:$imm)))]> {
7757 let Inst{19-16} = imm;
7759 } // Predicates = [HasNEON, HasFullFP16]
7760 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7761 V64, V64, vecshiftR32,
7763 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
7765 let Inst{20-16} = imm;
7768 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7769 V128, V128, vecshiftR32,
7771 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
7773 let Inst{20-16} = imm;
7776 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7777 V128, V128, vecshiftR64,
7779 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
7781 let Inst{21-16} = imm;
7785 multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,
7787 let Predicates = [HasNEON, HasFullFP16] in {
7788 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7789 V64, V64, vecshiftR16,
7791 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 imm:$imm)))]> {
7793 let Inst{19-16} = imm;
7796 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7797 V128, V128, vecshiftR16,
7799 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 imm:$imm)))]> {
7801 let Inst{19-16} = imm;
7803 } // Predicates = [HasNEON, HasFullFP16]
7805 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7806 V64, V64, vecshiftR32,
7808 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
7810 let Inst{20-16} = imm;
7813 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7814 V128, V128, vecshiftR32,
7816 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
7818 let Inst{20-16} = imm;
7821 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7822 V128, V128, vecshiftR64,
7824 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
7826 let Inst{21-16} = imm;
7830 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
7831 SDPatternOperator OpNode> {
7832 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7833 V64, V128, vecshiftR16Narrow,
7835 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
7837 let Inst{18-16} = imm;
7840 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7841 V128, V128, vecshiftR16Narrow,
7842 asm#"2", ".16b", ".8h", []> {
7844 let Inst{18-16} = imm;
7845 let hasSideEffects = 0;
7848 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7849 V64, V128, vecshiftR32Narrow,
7851 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
7853 let Inst{19-16} = imm;
7856 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7857 V128, V128, vecshiftR32Narrow,
7858 asm#"2", ".8h", ".4s", []> {
7860 let Inst{19-16} = imm;
7861 let hasSideEffects = 0;
7864 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7865 V64, V128, vecshiftR64Narrow,
7867 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
7869 let Inst{20-16} = imm;
7872 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7873 V128, V128, vecshiftR64Narrow,
7874 asm#"2", ".4s", ".2d", []> {
7876 let Inst{20-16} = imm;
7877 let hasSideEffects = 0;
7880 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
7881 // themselves, so put them here instead.
7883 // Patterns involving what's effectively an insert high and a normal
7884 // intrinsic, represented by CONCAT_VECTORS.
7885 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
7886 vecshiftR16Narrow:$imm)),
7887 (!cast<Instruction>(NAME # "v16i8_shift")
7888 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7889 V128:$Rn, vecshiftR16Narrow:$imm)>;
7890 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
7891 vecshiftR32Narrow:$imm)),
7892 (!cast<Instruction>(NAME # "v8i16_shift")
7893 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7894 V128:$Rn, vecshiftR32Narrow:$imm)>;
7895 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
7896 vecshiftR64Narrow:$imm)),
7897 (!cast<Instruction>(NAME # "v4i32_shift")
7898 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7899 V128:$Rn, vecshiftR64Narrow:$imm)>;
7902 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
7903 SDPatternOperator OpNode> {
7904 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7905 V64, V64, vecshiftL8,
7907 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7908 (i32 vecshiftL8:$imm)))]> {
7910 let Inst{18-16} = imm;
7913 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7914 V128, V128, vecshiftL8,
7915 asm, ".16b", ".16b",
7916 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7917 (i32 vecshiftL8:$imm)))]> {
7919 let Inst{18-16} = imm;
7922 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7923 V64, V64, vecshiftL16,
7925 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7926 (i32 vecshiftL16:$imm)))]> {
7928 let Inst{19-16} = imm;
7931 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7932 V128, V128, vecshiftL16,
7934 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7935 (i32 vecshiftL16:$imm)))]> {
7937 let Inst{19-16} = imm;
7940 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7941 V64, V64, vecshiftL32,
7943 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7944 (i32 vecshiftL32:$imm)))]> {
7946 let Inst{20-16} = imm;
7949 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7950 V128, V128, vecshiftL32,
7952 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7953 (i32 vecshiftL32:$imm)))]> {
7955 let Inst{20-16} = imm;
7958 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7959 V128, V128, vecshiftL64,
7961 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7962 (i32 vecshiftL64:$imm)))]> {
7964 let Inst{21-16} = imm;
7968 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
7969 SDPatternOperator OpNode> {
7970 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7971 V64, V64, vecshiftR8,
7973 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7974 (i32 vecshiftR8:$imm)))]> {
7976 let Inst{18-16} = imm;
7979 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7980 V128, V128, vecshiftR8,
7981 asm, ".16b", ".16b",
7982 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7983 (i32 vecshiftR8:$imm)))]> {
7985 let Inst{18-16} = imm;
7988 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7989 V64, V64, vecshiftR16,
7991 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7992 (i32 vecshiftR16:$imm)))]> {
7994 let Inst{19-16} = imm;
7997 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7998 V128, V128, vecshiftR16,
8000 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
8001 (i32 vecshiftR16:$imm)))]> {
8003 let Inst{19-16} = imm;
8006 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8007 V64, V64, vecshiftR32,
8009 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
8010 (i32 vecshiftR32:$imm)))]> {
8012 let Inst{20-16} = imm;
8015 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8016 V128, V128, vecshiftR32,
8018 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
8019 (i32 vecshiftR32:$imm)))]> {
8021 let Inst{20-16} = imm;
8024 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
8025 V128, V128, vecshiftR64,
8027 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
8028 (i32 vecshiftR64:$imm)))]> {
8030 let Inst{21-16} = imm;
8034 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8035 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
8036 SDPatternOperator OpNode = null_frag> {
8037 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8038 V64, V64, vecshiftR8, asm, ".8b", ".8b",
8039 [(set (v8i8 V64:$dst),
8040 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8041 (i32 vecshiftR8:$imm)))]> {
8043 let Inst{18-16} = imm;
8046 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8047 V128, V128, vecshiftR8, asm, ".16b", ".16b",
8048 [(set (v16i8 V128:$dst),
8049 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8050 (i32 vecshiftR8:$imm)))]> {
8052 let Inst{18-16} = imm;
8055 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8056 V64, V64, vecshiftR16, asm, ".4h", ".4h",
8057 [(set (v4i16 V64:$dst),
8058 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8059 (i32 vecshiftR16:$imm)))]> {
8061 let Inst{19-16} = imm;
8064 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8065 V128, V128, vecshiftR16, asm, ".8h", ".8h",
8066 [(set (v8i16 V128:$dst),
8067 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8068 (i32 vecshiftR16:$imm)))]> {
8070 let Inst{19-16} = imm;
8073 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8074 V64, V64, vecshiftR32, asm, ".2s", ".2s",
8075 [(set (v2i32 V64:$dst),
8076 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8077 (i32 vecshiftR32:$imm)))]> {
8079 let Inst{20-16} = imm;
8082 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8083 V128, V128, vecshiftR32, asm, ".4s", ".4s",
8084 [(set (v4i32 V128:$dst),
8085 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8086 (i32 vecshiftR32:$imm)))]> {
8088 let Inst{20-16} = imm;
8091 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8092 V128, V128, vecshiftR64,
8093 asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
8094 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8095 (i32 vecshiftR64:$imm)))]> {
8097 let Inst{21-16} = imm;
8101 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
8102 SDPatternOperator OpNode = null_frag> {
8103 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
8104 V64, V64, vecshiftL8,
8106 [(set (v8i8 V64:$dst),
8107 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
8108 (i32 vecshiftL8:$imm)))]> {
8110 let Inst{18-16} = imm;
8113 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
8114 V128, V128, vecshiftL8,
8115 asm, ".16b", ".16b",
8116 [(set (v16i8 V128:$dst),
8117 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
8118 (i32 vecshiftL8:$imm)))]> {
8120 let Inst{18-16} = imm;
8123 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
8124 V64, V64, vecshiftL16,
8126 [(set (v4i16 V64:$dst),
8127 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
8128 (i32 vecshiftL16:$imm)))]> {
8130 let Inst{19-16} = imm;
8133 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
8134 V128, V128, vecshiftL16,
8136 [(set (v8i16 V128:$dst),
8137 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
8138 (i32 vecshiftL16:$imm)))]> {
8140 let Inst{19-16} = imm;
8143 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
8144 V64, V64, vecshiftL32,
8146 [(set (v2i32 V64:$dst),
8147 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
8148 (i32 vecshiftL32:$imm)))]> {
8150 let Inst{20-16} = imm;
8153 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
8154 V128, V128, vecshiftL32,
8156 [(set (v4i32 V128:$dst),
8157 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8158 (i32 vecshiftL32:$imm)))]> {
8160 let Inst{20-16} = imm;
8163 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
8164 V128, V128, vecshiftL64,
8166 [(set (v2i64 V128:$dst),
8167 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
8168 (i32 vecshiftL64:$imm)))]> {
8170 let Inst{21-16} = imm;
8174 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
8175 SDPatternOperator OpNode> {
8176 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
8177 V128, V64, vecshiftL8, asm, ".8h", ".8b",
8178 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
8180 let Inst{18-16} = imm;
8183 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
8184 V128, V128, vecshiftL8,
8185 asm#"2", ".8h", ".16b",
8186 [(set (v8i16 V128:$Rd),
8187 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
8189 let Inst{18-16} = imm;
8192 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
8193 V128, V64, vecshiftL16, asm, ".4s", ".4h",
8194 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
8196 let Inst{19-16} = imm;
8199 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
8200 V128, V128, vecshiftL16,
8201 asm#"2", ".4s", ".8h",
8202 [(set (v4i32 V128:$Rd),
8203 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
8206 let Inst{19-16} = imm;
8209 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
8210 V128, V64, vecshiftL32, asm, ".2d", ".2s",
8211 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
8213 let Inst{20-16} = imm;
8216 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
8217 V128, V128, vecshiftL32,
8218 asm#"2", ".2d", ".4s",
8219 [(set (v2i64 V128:$Rd),
8220 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
8222 let Inst{20-16} = imm;
8228 // Vector load/store
8230 // SIMD ldX/stX no-index memory references don't allow the optional
8231 // ", #0" constant and handle post-indexing explicitly, so we use
8232 // a more specialized parse method for them. Otherwise, it's the same as
8233 // the general GPR64sp handling.
8235 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
8236 string asm, dag oops, dag iops, list<dag> pattern>
8237 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
8242 let Inst{29-23} = 0b0011000;
8244 let Inst{21-16} = 0b000000;
8245 let Inst{15-12} = opcode;
8246 let Inst{11-10} = size;
8251 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
8252 string asm, dag oops, dag iops>
8253 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
8259 let Inst{29-23} = 0b0011001;
8262 let Inst{20-16} = Xm;
8263 let Inst{15-12} = opcode;
8264 let Inst{11-10} = size;
8269 // The immediate form of AdvSIMD post-indexed addressing is encoded with
8270 // register post-index addressing from the zero register.
8271 multiclass SIMDLdStAliases<string asm, string layout, string Count,
8272 int Offset, int Size> {
8273 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
8274 // "ld1\t$Vt, [$Rn], #16"
8275 // may get mapped to
8276 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
8277 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8278 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8280 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8283 // E.g. "ld1.8b { v0, v1 }, [x1], #16"
8284 // "ld1.8b\t$Vt, [$Rn], #16"
8285 // may get mapped to
8286 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
8287 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8288 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8290 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8293 // E.g. "ld1.8b { v0, v1 }, [x1]"
8294 // "ld1\t$Vt, [$Rn]"
8295 // may get mapped to
8296 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
8297 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8298 (!cast<Instruction>(NAME # Count # "v" # layout)
8299 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8302 // E.g. "ld1.8b { v0, v1 }, [x1], x2"
8303 // "ld1\t$Vt, [$Rn], $Xm"
8304 // may get mapped to
8305 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
8306 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8307 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
8309 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8310 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8313 multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
8314 int Offset64, bits<4> opcode> {
8315 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8316 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
8317 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
8318 (ins GPR64sp:$Rn), []>;
8319 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
8320 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
8321 (ins GPR64sp:$Rn), []>;
8322 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
8323 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
8324 (ins GPR64sp:$Rn), []>;
8325 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
8326 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
8327 (ins GPR64sp:$Rn), []>;
8328 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
8329 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
8330 (ins GPR64sp:$Rn), []>;
8331 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
8332 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
8333 (ins GPR64sp:$Rn), []>;
8334 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
8335 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
8336 (ins GPR64sp:$Rn), []>;
8339 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
8340 (outs GPR64sp:$wback,
8341 !cast<RegisterOperand>(veclist # "16b"):$Vt),
8343 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8344 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
8345 (outs GPR64sp:$wback,
8346 !cast<RegisterOperand>(veclist # "8h"):$Vt),
8348 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8349 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
8350 (outs GPR64sp:$wback,
8351 !cast<RegisterOperand>(veclist # "4s"):$Vt),
8353 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8354 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
8355 (outs GPR64sp:$wback,
8356 !cast<RegisterOperand>(veclist # "2d"):$Vt),
8358 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8359 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
8360 (outs GPR64sp:$wback,
8361 !cast<RegisterOperand>(veclist # "8b"):$Vt),
8363 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8364 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
8365 (outs GPR64sp:$wback,
8366 !cast<RegisterOperand>(veclist # "4h"):$Vt),
8368 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8369 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
8370 (outs GPR64sp:$wback,
8371 !cast<RegisterOperand>(veclist # "2s"):$Vt),
8373 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8376 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
8377 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8378 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8379 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8380 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8381 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8382 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8385 // Only ld1/st1 has a v1d version.
8386 multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
8387 int Offset64, bits<4> opcode> {
8388 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
8389 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
8390 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8392 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
8393 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8395 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
8396 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8398 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
8399 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8401 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
8402 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8404 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
8405 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8407 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
8408 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8411 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
8412 (outs GPR64sp:$wback),
8413 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8415 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8416 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
8417 (outs GPR64sp:$wback),
8418 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8420 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8421 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
8422 (outs GPR64sp:$wback),
8423 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8425 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8426 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
8427 (outs GPR64sp:$wback),
8428 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8430 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8431 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
8432 (outs GPR64sp:$wback),
8433 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8435 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8436 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
8437 (outs GPR64sp:$wback),
8438 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8440 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8441 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
8442 (outs GPR64sp:$wback),
8443 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8445 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8448 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
8449 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8450 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8451 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8452 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8453 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8454 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8457 multiclass BaseSIMDLd1<string Count, string asm, string veclist,
8458 int Offset128, int Offset64, bits<4> opcode>
8459 : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
8461 // LD1 instructions have extra "1d" variants.
8462 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8463 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
8464 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
8465 (ins GPR64sp:$Rn), []>;
8467 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
8468 (outs GPR64sp:$wback,
8469 !cast<RegisterOperand>(veclist # "1d"):$Vt),
8471 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8474 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8477 multiclass BaseSIMDSt1<string Count, string asm, string veclist,
8478 int Offset128, int Offset64, bits<4> opcode>
8479 : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
8481 // ST1 instructions have extra "1d" variants.
8482 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
8483 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
8484 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8487 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
8488 (outs GPR64sp:$wback),
8489 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8491 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8494 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8497 multiclass SIMDLd1Multiple<string asm> {
8498 defm One : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8, 0b0111>;
8499 defm Two : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8500 defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8501 defm Four : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8504 multiclass SIMDSt1Multiple<string asm> {
8505 defm One : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8, 0b0111>;
8506 defm Two : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8507 defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8508 defm Four : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8511 multiclass SIMDLd2Multiple<string asm> {
8512 defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8515 multiclass SIMDSt2Multiple<string asm> {
8516 defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8519 multiclass SIMDLd3Multiple<string asm> {
8520 defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8523 multiclass SIMDSt3Multiple<string asm> {
8524 defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8527 multiclass SIMDLd4Multiple<string asm> {
8528 defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8531 multiclass SIMDSt4Multiple<string asm> {
8532 defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8536 // AdvSIMD Load/store single-element
8539 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
8540 string asm, string operands, string cst,
8541 dag oops, dag iops, list<dag> pattern>
8542 : I<oops, iops, asm, operands, cst, pattern> {
8546 let Inst{29-24} = 0b001101;
8549 let Inst{15-13} = opcode;
8554 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
8555 string asm, string operands, string cst,
8556 dag oops, dag iops, list<dag> pattern>
8557 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
8561 let Inst{29-24} = 0b001101;
8564 let Inst{15-13} = opcode;
8570 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8571 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
8573 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
8574 (outs listtype:$Vt), (ins GPR64sp:$Rn),
8578 let Inst{20-16} = 0b00000;
8580 let Inst{11-10} = size;
8582 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8583 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
8584 string asm, Operand listtype, Operand GPR64pi>
8585 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
8587 (outs GPR64sp:$wback, listtype:$Vt),
8588 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
8592 let Inst{20-16} = Xm;
8594 let Inst{11-10} = size;
8597 multiclass SIMDLdrAliases<string asm, string layout, string Count,
8598 int Offset, int Size> {
8599 // E.g. "ld1r { v0.8b }, [x1], #1"
8600 // "ld1r.8b\t$Vt, [$Rn], #1"
8601 // may get mapped to
8602 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8603 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8604 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8606 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8609 // E.g. "ld1r.8b { v0 }, [x1], #1"
8610 // "ld1r.8b\t$Vt, [$Rn], #1"
8611 // may get mapped to
8612 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8613 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8614 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8616 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8619 // E.g. "ld1r.8b { v0 }, [x1]"
8620 // "ld1r.8b\t$Vt, [$Rn]"
8621 // may get mapped to
8622 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8623 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8624 (!cast<Instruction>(NAME # "v" # layout)
8625 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8628 // E.g. "ld1r.8b { v0 }, [x1], x2"
8629 // "ld1r.8b\t$Vt, [$Rn], $Xm"
8630 // may get mapped to
8631 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8632 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8633 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8635 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8636 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8639 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
8640 int Offset1, int Offset2, int Offset4, int Offset8> {
8641 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
8642 !cast<Operand>("VecList" # Count # "8b")>;
8643 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
8644 !cast<Operand>("VecList" # Count #"16b")>;
8645 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
8646 !cast<Operand>("VecList" # Count #"4h")>;
8647 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
8648 !cast<Operand>("VecList" # Count #"8h")>;
8649 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
8650 !cast<Operand>("VecList" # Count #"2s")>;
8651 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
8652 !cast<Operand>("VecList" # Count #"4s")>;
8653 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
8654 !cast<Operand>("VecList" # Count #"1d")>;
8655 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
8656 !cast<Operand>("VecList" # Count #"2d")>;
8658 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
8659 !cast<Operand>("VecList" # Count # "8b"),
8660 !cast<Operand>("GPR64pi" # Offset1)>;
8661 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
8662 !cast<Operand>("VecList" # Count # "16b"),
8663 !cast<Operand>("GPR64pi" # Offset1)>;
8664 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
8665 !cast<Operand>("VecList" # Count # "4h"),
8666 !cast<Operand>("GPR64pi" # Offset2)>;
8667 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
8668 !cast<Operand>("VecList" # Count # "8h"),
8669 !cast<Operand>("GPR64pi" # Offset2)>;
8670 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
8671 !cast<Operand>("VecList" # Count # "2s"),
8672 !cast<Operand>("GPR64pi" # Offset4)>;
8673 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
8674 !cast<Operand>("VecList" # Count # "4s"),
8675 !cast<Operand>("GPR64pi" # Offset4)>;
8676 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
8677 !cast<Operand>("VecList" # Count # "1d"),
8678 !cast<Operand>("GPR64pi" # Offset8)>;
8679 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
8680 !cast<Operand>("VecList" # Count # "2d"),
8681 !cast<Operand>("GPR64pi" # Offset8)>;
8683 defm : SIMDLdrAliases<asm, "8b", Count, Offset1, 64>;
8684 defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
8685 defm : SIMDLdrAliases<asm, "4h", Count, Offset2, 64>;
8686 defm : SIMDLdrAliases<asm, "8h", Count, Offset2, 128>;
8687 defm : SIMDLdrAliases<asm, "2s", Count, Offset4, 64>;
8688 defm : SIMDLdrAliases<asm, "4s", Count, Offset4, 128>;
8689 defm : SIMDLdrAliases<asm, "1d", Count, Offset8, 64>;
8690 defm : SIMDLdrAliases<asm, "2d", Count, Offset8, 128>;
8693 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
8694 dag oops, dag iops, list<dag> pattern>
8695 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8697 // idx encoded in Q:S:size fields.
8699 let Inst{30} = idx{3};
8701 let Inst{20-16} = 0b00000;
8702 let Inst{12} = idx{2};
8703 let Inst{11-10} = idx{1-0};
8705 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
8706 dag oops, dag iops, list<dag> pattern>
8707 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8708 oops, iops, pattern> {
8709 // idx encoded in Q:S:size fields.
8711 let Inst{30} = idx{3};
8713 let Inst{20-16} = 0b00000;
8714 let Inst{12} = idx{2};
8715 let Inst{11-10} = idx{1-0};
8717 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
8719 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8720 "$Rn = $wback", oops, iops, []> {
8721 // idx encoded in Q:S:size fields.
8724 let Inst{30} = idx{3};
8726 let Inst{20-16} = Xm;
8727 let Inst{12} = idx{2};
8728 let Inst{11-10} = idx{1-0};
8730 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
8732 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8733 "$Rn = $wback", oops, iops, []> {
8734 // idx encoded in Q:S:size fields.
8737 let Inst{30} = idx{3};
8739 let Inst{20-16} = Xm;
8740 let Inst{12} = idx{2};
8741 let Inst{11-10} = idx{1-0};
8744 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
8745 dag oops, dag iops, list<dag> pattern>
8746 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8748 // idx encoded in Q:S:size<1> fields.
8750 let Inst{30} = idx{2};
8752 let Inst{20-16} = 0b00000;
8753 let Inst{12} = idx{1};
8754 let Inst{11} = idx{0};
8755 let Inst{10} = size;
8757 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
8758 dag oops, dag iops, list<dag> pattern>
8759 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8760 oops, iops, pattern> {
8761 // idx encoded in Q:S:size<1> fields.
8763 let Inst{30} = idx{2};
8765 let Inst{20-16} = 0b00000;
8766 let Inst{12} = idx{1};
8767 let Inst{11} = idx{0};
8768 let Inst{10} = size;
8771 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8773 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8774 "$Rn = $wback", oops, iops, []> {
8775 // idx encoded in Q:S:size<1> fields.
8778 let Inst{30} = idx{2};
8780 let Inst{20-16} = Xm;
8781 let Inst{12} = idx{1};
8782 let Inst{11} = idx{0};
8783 let Inst{10} = size;
8785 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8787 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8788 "$Rn = $wback", oops, iops, []> {
8789 // idx encoded in Q:S:size<1> fields.
8792 let Inst{30} = idx{2};
8794 let Inst{20-16} = Xm;
8795 let Inst{12} = idx{1};
8796 let Inst{11} = idx{0};
8797 let Inst{10} = size;
8799 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8800 dag oops, dag iops, list<dag> pattern>
8801 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8803 // idx encoded in Q:S fields.
8805 let Inst{30} = idx{1};
8807 let Inst{20-16} = 0b00000;
8808 let Inst{12} = idx{0};
8809 let Inst{11-10} = size;
8811 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8812 dag oops, dag iops, list<dag> pattern>
8813 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8814 oops, iops, pattern> {
8815 // idx encoded in Q:S fields.
8817 let Inst{30} = idx{1};
8819 let Inst{20-16} = 0b00000;
8820 let Inst{12} = idx{0};
8821 let Inst{11-10} = size;
8823 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
8824 string asm, dag oops, dag iops>
8825 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8826 "$Rn = $wback", oops, iops, []> {
8827 // idx encoded in Q:S fields.
8830 let Inst{30} = idx{1};
8832 let Inst{20-16} = Xm;
8833 let Inst{12} = idx{0};
8834 let Inst{11-10} = size;
8836 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8837 string asm, dag oops, dag iops>
8838 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8839 "$Rn = $wback", oops, iops, []> {
8840 // idx encoded in Q:S fields.
8843 let Inst{30} = idx{1};
8845 let Inst{20-16} = Xm;
8846 let Inst{12} = idx{0};
8847 let Inst{11-10} = size;
8849 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8850 dag oops, dag iops, list<dag> pattern>
8851 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8853 // idx encoded in Q field.
8857 let Inst{20-16} = 0b00000;
8859 let Inst{11-10} = size;
8861 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8862 dag oops, dag iops, list<dag> pattern>
8863 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8864 oops, iops, pattern> {
8865 // idx encoded in Q field.
8869 let Inst{20-16} = 0b00000;
8871 let Inst{11-10} = size;
8873 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
8874 string asm, dag oops, dag iops>
8875 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8876 "$Rn = $wback", oops, iops, []> {
8877 // idx encoded in Q field.
8882 let Inst{20-16} = Xm;
8884 let Inst{11-10} = size;
8886 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8887 string asm, dag oops, dag iops>
8888 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8889 "$Rn = $wback", oops, iops, []> {
8890 // idx encoded in Q field.
8895 let Inst{20-16} = Xm;
8897 let Inst{11-10} = size;
8900 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8901 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
8902 RegisterOperand listtype,
8903 RegisterOperand GPR64pi> {
8904 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
8905 (outs listtype:$dst),
8906 (ins listtype:$Vt, VectorIndexB:$idx,
8909 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
8910 (outs GPR64sp:$wback, listtype:$dst),
8911 (ins listtype:$Vt, VectorIndexB:$idx,
8912 GPR64sp:$Rn, GPR64pi:$Xm)>;
8914 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8915 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
8916 RegisterOperand listtype,
8917 RegisterOperand GPR64pi> {
8918 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
8919 (outs listtype:$dst),
8920 (ins listtype:$Vt, VectorIndexH:$idx,
8923 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
8924 (outs GPR64sp:$wback, listtype:$dst),
8925 (ins listtype:$Vt, VectorIndexH:$idx,
8926 GPR64sp:$Rn, GPR64pi:$Xm)>;
8928 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8929 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
8930 RegisterOperand listtype,
8931 RegisterOperand GPR64pi> {
8932 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
8933 (outs listtype:$dst),
8934 (ins listtype:$Vt, VectorIndexS:$idx,
8937 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
8938 (outs GPR64sp:$wback, listtype:$dst),
8939 (ins listtype:$Vt, VectorIndexS:$idx,
8940 GPR64sp:$Rn, GPR64pi:$Xm)>;
8942 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8943 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
8944 RegisterOperand listtype, RegisterOperand GPR64pi> {
8945 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
8946 (outs listtype:$dst),
8947 (ins listtype:$Vt, VectorIndexD:$idx,
8950 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
8951 (outs GPR64sp:$wback, listtype:$dst),
8952 (ins listtype:$Vt, VectorIndexD:$idx,
8953 GPR64sp:$Rn, GPR64pi:$Xm)>;
8955 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8956 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
8957 RegisterOperand listtype, RegisterOperand GPR64pi> {
8958 def i8 : SIMDLdStSingleB<0, R, opcode, asm,
8959 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
8962 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
8963 (outs GPR64sp:$wback),
8964 (ins listtype:$Vt, VectorIndexB:$idx,
8965 GPR64sp:$Rn, GPR64pi:$Xm)>;
8967 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8968 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
8969 RegisterOperand listtype, RegisterOperand GPR64pi> {
8970 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
8971 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
8974 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
8975 (outs GPR64sp:$wback),
8976 (ins listtype:$Vt, VectorIndexH:$idx,
8977 GPR64sp:$Rn, GPR64pi:$Xm)>;
8979 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8980 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
8981 RegisterOperand listtype, RegisterOperand GPR64pi> {
8982 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
8983 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
8986 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
8987 (outs GPR64sp:$wback),
8988 (ins listtype:$Vt, VectorIndexS:$idx,
8989 GPR64sp:$Rn, GPR64pi:$Xm)>;
8991 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8992 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
8993 RegisterOperand listtype, RegisterOperand GPR64pi> {
8994 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
8995 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
8998 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
8999 (outs GPR64sp:$wback),
9000 (ins listtype:$Vt, VectorIndexD:$idx,
9001 GPR64sp:$Rn, GPR64pi:$Xm)>;
9004 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
9005 string Count, int Offset, Operand idxtype> {
9006 // E.g. "ld1 { v0.8b }[0], [x1], #1"
9007 // "ld1\t$Vt, [$Rn], #1"
9008 // may get mapped to
9009 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
9010 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
9011 (!cast<Instruction>(NAME # Type # "_POST")
9013 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
9014 idxtype:$idx, XZR), 1>;
9016 // E.g. "ld1.8b { v0 }[0], [x1], #1"
9017 // "ld1.8b\t$Vt, [$Rn], #1"
9018 // may get mapped to
9019 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
9020 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
9021 (!cast<Instruction>(NAME # Type # "_POST")
9023 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9024 idxtype:$idx, XZR), 0>;
9026 // E.g. "ld1.8b { v0 }[0], [x1]"
9027 // "ld1.8b\t$Vt, [$Rn]"
9028 // may get mapped to
9029 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
9030 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
9031 (!cast<Instruction>(NAME # Type)
9032 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9033 idxtype:$idx, GPR64sp:$Rn), 0>;
9035 // E.g. "ld1.8b { v0 }[0], [x1], x2"
9036 // "ld1.8b\t$Vt, [$Rn], $Xm"
9037 // may get mapped to
9038 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
9039 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
9040 (!cast<Instruction>(NAME # Type # "_POST")
9042 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
9044 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
9047 multiclass SIMDLdSt1SingleAliases<string asm> {
9048 defm : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;
9049 defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
9050 defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
9051 defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
9054 multiclass SIMDLdSt2SingleAliases<string asm> {
9055 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;
9056 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;
9057 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;
9058 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
9061 multiclass SIMDLdSt3SingleAliases<string asm> {
9062 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;
9063 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;
9064 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
9065 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
9068 multiclass SIMDLdSt4SingleAliases<string asm> {
9069 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;
9070 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;
9071 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
9072 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
9074 } // end of 'let Predicates = [HasNEON]'
9076 //----------------------------------------------------------------------------
9077 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
9078 //----------------------------------------------------------------------------
9080 let Predicates = [HasNEON, HasRDM] in {
9082 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
9083 RegisterOperand regtype, string asm,
9084 string kind, list<dag> pattern>
9085 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind,
9088 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
9089 SDPatternOperator Accum> {
9090 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
9091 [(set (v4i16 V64:$dst),
9092 (Accum (v4i16 V64:$Rd),
9093 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
9094 (v4i16 V64:$Rm)))))]>;
9095 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
9096 [(set (v8i16 V128:$dst),
9097 (Accum (v8i16 V128:$Rd),
9098 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
9099 (v8i16 V128:$Rm)))))]>;
9100 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
9101 [(set (v2i32 V64:$dst),
9102 (Accum (v2i32 V64:$Rd),
9103 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
9104 (v2i32 V64:$Rm)))))]>;
9105 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
9106 [(set (v4i32 V128:$dst),
9107 (Accum (v4i32 V128:$Rd),
9108 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
9109 (v4i32 V128:$Rm)))))]>;
9112 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
9113 SDPatternOperator Accum> {
9114 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
9115 V64, V64, V128_lo, VectorIndexH,
9116 asm, ".4h", ".4h", ".4h", ".h",
9117 [(set (v4i16 V64:$dst),
9118 (Accum (v4i16 V64:$Rd),
9119 (v4i16 (int_aarch64_neon_sqrdmulh
9121 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
9122 VectorIndexH:$idx))))))]> {
9124 let Inst{11} = idx{2};
9125 let Inst{21} = idx{1};
9126 let Inst{20} = idx{0};
9129 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
9130 V128, V128, V128_lo, VectorIndexH,
9131 asm, ".8h", ".8h", ".8h", ".h",
9132 [(set (v8i16 V128:$dst),
9133 (Accum (v8i16 V128:$Rd),
9134 (v8i16 (int_aarch64_neon_sqrdmulh
9136 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
9137 VectorIndexH:$idx))))))]> {
9139 let Inst{11} = idx{2};
9140 let Inst{21} = idx{1};
9141 let Inst{20} = idx{0};
9144 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
9145 V64, V64, V128, VectorIndexS,
9146 asm, ".2s", ".2s", ".2s", ".s",
9147 [(set (v2i32 V64:$dst),
9148 (Accum (v2i32 V64:$Rd),
9149 (v2i32 (int_aarch64_neon_sqrdmulh
9151 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
9152 VectorIndexS:$idx))))))]> {
9154 let Inst{11} = idx{1};
9155 let Inst{21} = idx{0};
9158 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
9159 // an intermediate EXTRACT_SUBREG would be untyped.
9160 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
9161 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
9162 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9163 (i32 (vector_extract
9164 (v4i32 (insert_subvector
9166 (v2i32 (int_aarch64_neon_sqrdmulh
9168 (v2i32 (AArch64duplane32
9170 VectorIndexS:$idx)))),
9174 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
9175 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
9180 VectorIndexS:$idx)),
9183 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
9184 V128, V128, V128, VectorIndexS,
9185 asm, ".4s", ".4s", ".4s", ".s",
9186 [(set (v4i32 V128:$dst),
9187 (Accum (v4i32 V128:$Rd),
9188 (v4i32 (int_aarch64_neon_sqrdmulh
9190 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
9191 VectorIndexS:$idx))))))]> {
9193 let Inst{11} = idx{1};
9194 let Inst{21} = idx{0};
9197 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
9198 // an intermediate EXTRACT_SUBREG would be untyped.
9199 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
9200 (i32 (vector_extract
9201 (v4i32 (int_aarch64_neon_sqrdmulh
9203 (v4i32 (AArch64duplane32
9205 VectorIndexS:$idx)))),
9208 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
9209 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
9214 VectorIndexS:$idx)),
9217 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
9218 FPR16Op, FPR16Op, V128_lo,
9219 VectorIndexH, asm, ".h", "", "", ".h",
9222 let Inst{11} = idx{2};
9223 let Inst{21} = idx{1};
9224 let Inst{20} = idx{0};
9227 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
9228 FPR32Op, FPR32Op, V128, VectorIndexS,
9229 asm, ".s", "", "", ".s",
9230 [(set (i32 FPR32Op:$dst),
9231 (Accum (i32 FPR32Op:$Rd),
9232 (i32 (int_aarch64_neon_sqrdmulh
9234 (i32 (vector_extract (v4i32 V128:$Rm),
9235 VectorIndexS:$idx))))))]> {
9237 let Inst{11} = idx{1};
9238 let Inst{21} = idx{0};
9241 } // let Predicates = [HasNeon, HasRDM]
9243 //----------------------------------------------------------------------------
9244 // Crypto extensions
9245 //----------------------------------------------------------------------------
9247 let Predicates = [HasCrypto] in {
9248 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9249 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
9251 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
9255 let Inst{31-16} = 0b0100111000101000;
9256 let Inst{15-12} = opc;
9257 let Inst{11-10} = 0b10;
9262 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
9263 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
9264 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
9266 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
9267 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
9269 [(set (v16i8 V128:$dst),
9270 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
9272 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9273 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
9274 dag oops, dag iops, list<dag> pat>
9275 : I<oops, iops, asm,
9276 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
9277 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
9282 let Inst{31-21} = 0b01011110000;
9283 let Inst{20-16} = Rm;
9285 let Inst{14-12} = opc;
9286 let Inst{11-10} = 0b00;
9291 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
9292 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9293 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
9294 [(set (v4i32 FPR128:$dst),
9295 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
9296 (v4i32 V128:$Rm)))]>;
9298 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
9299 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
9300 (ins V128:$Rd, V128:$Rn, V128:$Rm),
9301 [(set (v4i32 V128:$dst),
9302 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
9303 (v4i32 V128:$Rm)))]>;
9305 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
9306 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
9307 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
9308 [(set (v4i32 FPR128:$dst),
9309 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
9310 (v4i32 V128:$Rm)))]>;
9312 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
9313 class SHA2OpInst<bits<4> opc, string asm, string kind,
9314 string cstr, dag oops, dag iops,
9316 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
9317 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
9321 let Inst{31-16} = 0b0101111000101000;
9322 let Inst{15-12} = opc;
9323 let Inst{11-10} = 0b10;
9328 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
9329 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
9330 (ins V128:$Rd, V128:$Rn),
9331 [(set (v4i32 V128:$dst),
9332 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
9334 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
9335 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
9336 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
9337 } // end of 'let Predicates = [HasCrypto]'
9339 //----------------------------------------------------------------------------
9340 // v8.1 atomic instructions extension:
9344 // * LDOPregister<OP>, and aliases STOPregister<OP>
9346 // Instruction encodings:
9348 // 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0
9349 // CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt
9350 // CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt
9351 // SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt
9352 // LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt
9353 // ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111
9355 // Instruction syntax:
9357 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9358 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
9359 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
9360 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
9361 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9362 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
9363 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
9364 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
9365 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
9366 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
9368 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9369 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
9370 string cstr, list<dag> pattern>
9371 : I<oops, iops, asm, operands, cstr, pattern> {
9379 let Inst{31-30} = Sz;
9380 let Inst{29-24} = 0b001000;
9384 let Inst{20-16} = Rs;
9386 let Inst{14-10} = 0b11111;
9389 let Predicates = [HasLSE];
9392 class BaseCAS<string order, string size, RegisterClass RC>
9393 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
9394 "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
9396 Sched<[WriteAtomic]> {
9400 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
9401 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseCAS<order, "b", GPR32>;
9402 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseCAS<order, "h", GPR32>;
9403 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseCAS<order, "", GPR32>;
9404 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseCAS<order, "", GPR64>;
9407 class BaseCASP<string order, string size, RegisterOperand RC>
9408 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
9409 "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
9411 Sched<[WriteAtomic]> {
9415 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
9416 let Sz = 0b00, Acq = Acq, Rel = Rel in
9417 def s : BaseCASP<order, "", WSeqPairClassOperand>;
9418 let Sz = 0b01, Acq = Acq, Rel = Rel in
9419 def d : BaseCASP<order, "", XSeqPairClassOperand>;
9422 let Predicates = [HasLSE] in
9423 class BaseSWP<string order, string size, RegisterClass RC>
9424 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
9425 "\t$Rs, $Rt, [$Rn]","",[]>,
9426 Sched<[WriteAtomic]> {
9431 bits<3> opc = 0b000;
9434 let Inst{31-30} = Sz;
9435 let Inst{29-24} = 0b111000;
9439 let Inst{20-16} = Rs;
9441 let Inst{14-12} = opc;
9442 let Inst{11-10} = 0b00;
9445 let Predicates = [HasLSE];
9448 multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
9449 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseSWP<order, "b", GPR32>;
9450 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseSWP<order, "h", GPR32>;
9451 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseSWP<order, "", GPR32>;
9452 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseSWP<order, "", GPR64>;
9455 let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9456 class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
9457 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
9458 "\t$Rs, $Rt, [$Rn]","",[]>,
9459 Sched<[WriteAtomic]> {
9467 let Inst{31-30} = Sz;
9468 let Inst{29-24} = 0b111000;
9472 let Inst{20-16} = Rs;
9474 let Inst{14-12} = opc;
9475 let Inst{11-10} = 0b00;
9478 let Predicates = [HasLSE];
9481 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
9483 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
9484 def b : BaseLDOPregister<op, order, "b", GPR32>;
9485 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
9486 def h : BaseLDOPregister<op, order, "h", GPR32>;
9487 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
9488 def s : BaseLDOPregister<op, order, "", GPR32>;
9489 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
9490 def d : BaseLDOPregister<op, order, "", GPR64>;
9493 let Predicates = [HasLSE] in
9494 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
9496 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
9498 multiclass STOPregister<string asm, string instr> {
9499 def : BaseSTOPregister<asm # "lb", GPR32, WZR,
9500 !cast<Instruction>(instr # "Lb")>;
9501 def : BaseSTOPregister<asm # "lh", GPR32, WZR,
9502 !cast<Instruction>(instr # "Lh")>;
9503 def : BaseSTOPregister<asm # "l", GPR32, WZR,
9504 !cast<Instruction>(instr # "Ls")>;
9505 def : BaseSTOPregister<asm # "l", GPR64, XZR,
9506 !cast<Instruction>(instr # "Ld")>;
9507 def : BaseSTOPregister<asm # "b", GPR32, WZR,
9508 !cast<Instruction>(instr # "b")>;
9509 def : BaseSTOPregister<asm # "h", GPR32, WZR,
9510 !cast<Instruction>(instr # "h")>;
9511 def : BaseSTOPregister<asm, GPR32, WZR,
9512 !cast<Instruction>(instr # "s")>;
9513 def : BaseSTOPregister<asm, GPR64, XZR,
9514 !cast<Instruction>(instr # "d")>;
9517 //----------------------------------------------------------------------------
9518 // Allow the size specifier tokens to be upper case, not just lower.
9519 def : TokenAlias<".8B", ".8b">;
9520 def : TokenAlias<".4H", ".4h">;
9521 def : TokenAlias<".2S", ".2s">;
9522 def : TokenAlias<".1D", ".1d">;
9523 def : TokenAlias<".16B", ".16b">;
9524 def : TokenAlias<".8H", ".8h">;
9525 def : TokenAlias<".4S", ".4s">;
9526 def : TokenAlias<".2D", ".2d">;
9527 def : TokenAlias<".1Q", ".1q">;
9528 def : TokenAlias<".2H", ".2h">;
9529 def : TokenAlias<".B", ".b">;
9530 def : TokenAlias<".H", ".h">;
9531 def : TokenAlias<".S", ".s">;
9532 def : TokenAlias<".D", ".d">;
9533 def : TokenAlias<".Q", ".q">;