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 // Pseudo instructions (don't have encoding information)
43 class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">
44 : AArch64Inst<PseudoFrm, cstr> {
45 dag OutOperandList = oops;
46 dag InOperandList = iops;
47 let Pattern = pattern;
48 let isCodeGenOnly = 1;
51 // Real instructions (have encoding information)
52 class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> {
53 let Pattern = pattern;
57 // Normal instructions
58 class I<dag oops, dag iops, string asm, string operands, string cstr,
60 : EncodedI<cstr, pattern> {
61 dag OutOperandList = oops;
62 dag InOperandList = iops;
63 let AsmString = !strconcat(asm, operands);
66 class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>;
67 class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;
68 class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>;
70 // Helper fragment for an extract of the high portion of a 128-bit vector.
71 def extract_high_v16i8 :
72 UnOpFrag<(extract_subvector (v16i8 node:$LHS), (i64 8))>;
73 def extract_high_v8i16 :
74 UnOpFrag<(extract_subvector (v8i16 node:$LHS), (i64 4))>;
75 def extract_high_v4i32 :
76 UnOpFrag<(extract_subvector (v4i32 node:$LHS), (i64 2))>;
77 def extract_high_v2i64 :
78 UnOpFrag<(extract_subvector (v2i64 node:$LHS), (i64 1))>;
80 //===----------------------------------------------------------------------===//
81 // Asm Operand Classes.
84 // Shifter operand for arithmetic shifted encodings.
85 def ShifterOperand : AsmOperandClass {
89 // Shifter operand for mov immediate encodings.
90 def MovImm32ShifterOperand : AsmOperandClass {
91 let SuperClasses = [ShifterOperand];
92 let Name = "MovImm32Shifter";
93 let RenderMethod = "addShifterOperands";
94 let DiagnosticType = "InvalidMovImm32Shift";
96 def MovImm64ShifterOperand : AsmOperandClass {
97 let SuperClasses = [ShifterOperand];
98 let Name = "MovImm64Shifter";
99 let RenderMethod = "addShifterOperands";
100 let DiagnosticType = "InvalidMovImm64Shift";
103 // Shifter operand for arithmetic register shifted encodings.
104 class ArithmeticShifterOperand<int width> : AsmOperandClass {
105 let SuperClasses = [ShifterOperand];
106 let Name = "ArithmeticShifter" # width;
107 let PredicateMethod = "isArithmeticShifter<" # width # ">";
108 let RenderMethod = "addShifterOperands";
109 let DiagnosticType = "AddSubRegShift" # width;
112 def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
113 def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
115 // Shifter operand for logical register shifted encodings.
116 class LogicalShifterOperand<int width> : AsmOperandClass {
117 let SuperClasses = [ShifterOperand];
118 let Name = "LogicalShifter" # width;
119 let PredicateMethod = "isLogicalShifter<" # width # ">";
120 let RenderMethod = "addShifterOperands";
121 let DiagnosticType = "AddSubRegShift" # width;
124 def LogicalShifterOperand32 : LogicalShifterOperand<32>;
125 def LogicalShifterOperand64 : LogicalShifterOperand<64>;
127 // Shifter operand for logical vector 128/64-bit shifted encodings.
128 def LogicalVecShifterOperand : AsmOperandClass {
129 let SuperClasses = [ShifterOperand];
130 let Name = "LogicalVecShifter";
131 let RenderMethod = "addShifterOperands";
133 def LogicalVecHalfWordShifterOperand : AsmOperandClass {
134 let SuperClasses = [LogicalVecShifterOperand];
135 let Name = "LogicalVecHalfWordShifter";
136 let RenderMethod = "addShifterOperands";
139 // The "MSL" shifter on the vector MOVI instruction.
140 def MoveVecShifterOperand : AsmOperandClass {
141 let SuperClasses = [ShifterOperand];
142 let Name = "MoveVecShifter";
143 let RenderMethod = "addShifterOperands";
146 // Extend operand for arithmetic encodings.
147 def ExtendOperand : AsmOperandClass {
149 let DiagnosticType = "AddSubRegExtendLarge";
151 def ExtendOperand64 : AsmOperandClass {
152 let SuperClasses = [ExtendOperand];
153 let Name = "Extend64";
154 let DiagnosticType = "AddSubRegExtendSmall";
156 // 'extend' that's a lsl of a 64-bit register.
157 def ExtendOperandLSL64 : AsmOperandClass {
158 let SuperClasses = [ExtendOperand];
159 let Name = "ExtendLSL64";
160 let RenderMethod = "addExtend64Operands";
161 let DiagnosticType = "AddSubRegExtendLarge";
164 // 8-bit floating-point immediate encodings.
165 def FPImmOperand : AsmOperandClass {
167 let ParserMethod = "tryParseFPImm";
168 let DiagnosticType = "InvalidFPImm";
171 def CondCode : AsmOperandClass {
172 let Name = "CondCode";
173 let DiagnosticType = "InvalidCondCode";
176 // A 32-bit register pasrsed as 64-bit
177 def GPR32as64Operand : AsmOperandClass {
178 let Name = "GPR32as64";
180 def GPR32as64 : RegisterOperand<GPR32> {
181 let ParserMatchClass = GPR32as64Operand;
184 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
185 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
186 // are encoded as the eight bit value 'abcdefgh'.
187 def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
190 //===----------------------------------------------------------------------===//
191 // Operand Definitions.
194 // ADR[P] instruction labels.
195 def AdrpOperand : AsmOperandClass {
196 let Name = "AdrpLabel";
197 let ParserMethod = "tryParseAdrpLabel";
198 let DiagnosticType = "InvalidLabel";
200 def adrplabel : Operand<i64> {
201 let EncoderMethod = "getAdrLabelOpValue";
202 let PrintMethod = "printAdrpLabel";
203 let ParserMatchClass = AdrpOperand;
206 def AdrOperand : AsmOperandClass {
207 let Name = "AdrLabel";
208 let ParserMethod = "tryParseAdrLabel";
209 let DiagnosticType = "InvalidLabel";
211 def adrlabel : Operand<i64> {
212 let EncoderMethod = "getAdrLabelOpValue";
213 let ParserMatchClass = AdrOperand;
216 // simm9 predicate - True if the immediate is in the range [-256, 255].
217 def SImm9Operand : AsmOperandClass {
219 let DiagnosticType = "InvalidMemoryIndexedSImm9";
221 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
222 let ParserMatchClass = SImm9Operand;
225 // simm7sN predicate - True if the immediate is a multiple of N in the range
226 // [-64 * N, 63 * N].
227 class SImm7Scaled<int Scale> : AsmOperandClass {
228 let Name = "SImm7s" # Scale;
229 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm7";
232 def SImm7s4Operand : SImm7Scaled<4>;
233 def SImm7s8Operand : SImm7Scaled<8>;
234 def SImm7s16Operand : SImm7Scaled<16>;
236 def simm7s4 : Operand<i32> {
237 let ParserMatchClass = SImm7s4Operand;
238 let PrintMethod = "printImmScale<4>";
241 def simm7s8 : Operand<i32> {
242 let ParserMatchClass = SImm7s8Operand;
243 let PrintMethod = "printImmScale<8>";
246 def simm7s16 : Operand<i32> {
247 let ParserMatchClass = SImm7s16Operand;
248 let PrintMethod = "printImmScale<16>";
251 def am_indexed7s8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>;
252 def am_indexed7s16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>;
253 def am_indexed7s32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>;
254 def am_indexed7s64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>;
255 def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>;
257 class AsmImmRange<int Low, int High> : AsmOperandClass {
258 let Name = "Imm" # Low # "_" # High;
259 let DiagnosticType = "InvalidImm" # Low # "_" # High;
262 def Imm1_8Operand : AsmImmRange<1, 8>;
263 def Imm1_16Operand : AsmImmRange<1, 16>;
264 def Imm1_32Operand : AsmImmRange<1, 32>;
265 def Imm1_64Operand : AsmImmRange<1, 64>;
267 def MovZSymbolG3AsmOperand : AsmOperandClass {
268 let Name = "MovZSymbolG3";
269 let RenderMethod = "addImmOperands";
272 def movz_symbol_g3 : Operand<i32> {
273 let ParserMatchClass = MovZSymbolG3AsmOperand;
276 def MovZSymbolG2AsmOperand : AsmOperandClass {
277 let Name = "MovZSymbolG2";
278 let RenderMethod = "addImmOperands";
281 def movz_symbol_g2 : Operand<i32> {
282 let ParserMatchClass = MovZSymbolG2AsmOperand;
285 def MovZSymbolG1AsmOperand : AsmOperandClass {
286 let Name = "MovZSymbolG1";
287 let RenderMethod = "addImmOperands";
290 def movz_symbol_g1 : Operand<i32> {
291 let ParserMatchClass = MovZSymbolG1AsmOperand;
294 def MovZSymbolG0AsmOperand : AsmOperandClass {
295 let Name = "MovZSymbolG0";
296 let RenderMethod = "addImmOperands";
299 def movz_symbol_g0 : Operand<i32> {
300 let ParserMatchClass = MovZSymbolG0AsmOperand;
303 def MovKSymbolG3AsmOperand : AsmOperandClass {
304 let Name = "MovKSymbolG3";
305 let RenderMethod = "addImmOperands";
308 def movk_symbol_g3 : Operand<i32> {
309 let ParserMatchClass = MovKSymbolG3AsmOperand;
312 def MovKSymbolG2AsmOperand : AsmOperandClass {
313 let Name = "MovKSymbolG2";
314 let RenderMethod = "addImmOperands";
317 def movk_symbol_g2 : Operand<i32> {
318 let ParserMatchClass = MovKSymbolG2AsmOperand;
321 def MovKSymbolG1AsmOperand : AsmOperandClass {
322 let Name = "MovKSymbolG1";
323 let RenderMethod = "addImmOperands";
326 def movk_symbol_g1 : Operand<i32> {
327 let ParserMatchClass = MovKSymbolG1AsmOperand;
330 def MovKSymbolG0AsmOperand : AsmOperandClass {
331 let Name = "MovKSymbolG0";
332 let RenderMethod = "addImmOperands";
335 def movk_symbol_g0 : Operand<i32> {
336 let ParserMatchClass = MovKSymbolG0AsmOperand;
339 class fixedpoint_i32<ValueType FloatVT>
341 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
342 let EncoderMethod = "getFixedPointScaleOpValue";
343 let DecoderMethod = "DecodeFixedPointScaleImm32";
344 let ParserMatchClass = Imm1_32Operand;
347 class fixedpoint_i64<ValueType FloatVT>
349 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
350 let EncoderMethod = "getFixedPointScaleOpValue";
351 let DecoderMethod = "DecodeFixedPointScaleImm64";
352 let ParserMatchClass = Imm1_64Operand;
355 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
356 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
358 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
359 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
361 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
362 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
364 let EncoderMethod = "getVecShiftR8OpValue";
365 let DecoderMethod = "DecodeVecShiftR8Imm";
366 let ParserMatchClass = Imm1_8Operand;
368 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
369 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
371 let EncoderMethod = "getVecShiftR16OpValue";
372 let DecoderMethod = "DecodeVecShiftR16Imm";
373 let ParserMatchClass = Imm1_16Operand;
375 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
376 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
378 let EncoderMethod = "getVecShiftR16OpValue";
379 let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
380 let ParserMatchClass = Imm1_8Operand;
382 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
383 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
385 let EncoderMethod = "getVecShiftR32OpValue";
386 let DecoderMethod = "DecodeVecShiftR32Imm";
387 let ParserMatchClass = Imm1_32Operand;
389 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
390 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
392 let EncoderMethod = "getVecShiftR32OpValue";
393 let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
394 let ParserMatchClass = Imm1_16Operand;
396 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
397 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
399 let EncoderMethod = "getVecShiftR64OpValue";
400 let DecoderMethod = "DecodeVecShiftR64Imm";
401 let ParserMatchClass = Imm1_64Operand;
403 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
404 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
406 let EncoderMethod = "getVecShiftR64OpValue";
407 let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
408 let ParserMatchClass = Imm1_32Operand;
411 def Imm0_1Operand : AsmImmRange<0, 1>;
412 def Imm0_7Operand : AsmImmRange<0, 7>;
413 def Imm0_15Operand : AsmImmRange<0, 15>;
414 def Imm0_31Operand : AsmImmRange<0, 31>;
415 def Imm0_63Operand : AsmImmRange<0, 63>;
417 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
418 return (((uint32_t)Imm) < 8);
420 let EncoderMethod = "getVecShiftL8OpValue";
421 let DecoderMethod = "DecodeVecShiftL8Imm";
422 let ParserMatchClass = Imm0_7Operand;
424 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
425 return (((uint32_t)Imm) < 16);
427 let EncoderMethod = "getVecShiftL16OpValue";
428 let DecoderMethod = "DecodeVecShiftL16Imm";
429 let ParserMatchClass = Imm0_15Operand;
431 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
432 return (((uint32_t)Imm) < 32);
434 let EncoderMethod = "getVecShiftL32OpValue";
435 let DecoderMethod = "DecodeVecShiftL32Imm";
436 let ParserMatchClass = Imm0_31Operand;
438 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
439 return (((uint32_t)Imm) < 64);
441 let EncoderMethod = "getVecShiftL64OpValue";
442 let DecoderMethod = "DecodeVecShiftL64Imm";
443 let ParserMatchClass = Imm0_63Operand;
447 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
448 // instructions for splatting repeating bit patterns across the immediate.
449 def logical_imm32_XFORM : SDNodeXForm<imm, [{
450 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
451 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
453 def logical_imm64_XFORM : SDNodeXForm<imm, [{
454 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
455 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
458 let DiagnosticType = "LogicalSecondSource" in {
459 def LogicalImm32Operand : AsmOperandClass {
460 let Name = "LogicalImm32";
462 def LogicalImm64Operand : AsmOperandClass {
463 let Name = "LogicalImm64";
465 def LogicalImm32NotOperand : AsmOperandClass {
466 let Name = "LogicalImm32Not";
468 def LogicalImm64NotOperand : AsmOperandClass {
469 let Name = "LogicalImm64Not";
472 def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{
473 return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 32);
474 }], logical_imm32_XFORM> {
475 let PrintMethod = "printLogicalImm32";
476 let ParserMatchClass = LogicalImm32Operand;
478 def logical_imm64 : Operand<i64>, PatLeaf<(imm), [{
479 return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 64);
480 }], logical_imm64_XFORM> {
481 let PrintMethod = "printLogicalImm64";
482 let ParserMatchClass = LogicalImm64Operand;
484 def logical_imm32_not : Operand<i32> {
485 let ParserMatchClass = LogicalImm32NotOperand;
487 def logical_imm64_not : Operand<i64> {
488 let ParserMatchClass = LogicalImm64NotOperand;
491 // imm0_65535 predicate - True if the immediate is in the range [0,65535].
492 def Imm0_65535Operand : AsmImmRange<0, 65535>;
493 def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
494 return ((uint32_t)Imm) < 65536;
496 let ParserMatchClass = Imm0_65535Operand;
497 let PrintMethod = "printHexImm";
500 // imm0_255 predicate - True if the immediate is in the range [0,255].
501 def Imm0_255Operand : AsmOperandClass { let Name = "Imm0_255"; }
502 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
503 return ((uint32_t)Imm) < 256;
505 let ParserMatchClass = Imm0_255Operand;
506 let PrintMethod = "printHexImm";
509 // imm0_127 predicate - True if the immediate is in the range [0,127]
510 def Imm0_127Operand : AsmImmRange<0, 127>;
511 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
512 return ((uint32_t)Imm) < 128;
514 let ParserMatchClass = Imm0_127Operand;
515 let PrintMethod = "printHexImm";
518 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
519 // for all shift-amounts.
521 // imm0_63 predicate - True if the immediate is in the range [0,63]
522 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
523 return ((uint64_t)Imm) < 64;
525 let ParserMatchClass = Imm0_63Operand;
528 // imm0_31 predicate - True if the immediate is in the range [0,31]
529 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
530 return ((uint64_t)Imm) < 32;
532 let ParserMatchClass = Imm0_31Operand;
535 // True if the 32-bit immediate is in the range [0,31]
536 def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
537 return ((uint64_t)Imm) < 32;
539 let ParserMatchClass = Imm0_31Operand;
542 // imm0_1 predicate - True if the immediate is in the range [0,1]
543 def imm0_1 : Operand<i64>, ImmLeaf<i64, [{
544 return ((uint64_t)Imm) < 2;
546 let ParserMatchClass = Imm0_1Operand;
549 // imm0_15 predicate - True if the immediate is in the range [0,15]
550 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
551 return ((uint64_t)Imm) < 16;
553 let ParserMatchClass = Imm0_15Operand;
556 // imm0_7 predicate - True if the immediate is in the range [0,7]
557 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
558 return ((uint64_t)Imm) < 8;
560 let ParserMatchClass = Imm0_7Operand;
563 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
564 def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
565 return ((uint32_t)Imm) < 16;
567 let ParserMatchClass = Imm0_15Operand;
570 // An arithmetic shifter operand:
571 // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
573 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
574 let PrintMethod = "printShifter";
575 let ParserMatchClass = !cast<AsmOperandClass>(
576 "ArithmeticShifterOperand" # width);
579 def arith_shift32 : arith_shift<i32, 32>;
580 def arith_shift64 : arith_shift<i64, 64>;
582 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
584 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
585 let PrintMethod = "printShiftedRegister";
586 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
589 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
590 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
592 // An arithmetic shifter operand:
593 // {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
595 class logical_shift<int width> : Operand<i32> {
596 let PrintMethod = "printShifter";
597 let ParserMatchClass = !cast<AsmOperandClass>(
598 "LogicalShifterOperand" # width);
601 def logical_shift32 : logical_shift<32>;
602 def logical_shift64 : logical_shift<64>;
604 class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
606 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
607 let PrintMethod = "printShiftedRegister";
608 let MIOperandInfo = (ops regclass, shiftop);
611 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
612 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
614 // A logical vector shifter operand:
615 // {7-6} - shift type: 00 = lsl
616 // {5-0} - imm6: #0, #8, #16, or #24
617 def logical_vec_shift : Operand<i32> {
618 let PrintMethod = "printShifter";
619 let EncoderMethod = "getVecShifterOpValue";
620 let ParserMatchClass = LogicalVecShifterOperand;
623 // A logical vector half-word shifter operand:
624 // {7-6} - shift type: 00 = lsl
625 // {5-0} - imm6: #0 or #8
626 def logical_vec_hw_shift : Operand<i32> {
627 let PrintMethod = "printShifter";
628 let EncoderMethod = "getVecShifterOpValue";
629 let ParserMatchClass = LogicalVecHalfWordShifterOperand;
632 // A vector move shifter operand:
633 // {0} - imm1: #8 or #16
634 def move_vec_shift : Operand<i32> {
635 let PrintMethod = "printShifter";
636 let EncoderMethod = "getMoveVecShifterOpValue";
637 let ParserMatchClass = MoveVecShifterOperand;
640 let DiagnosticType = "AddSubSecondSource" in {
641 def AddSubImmOperand : AsmOperandClass {
642 let Name = "AddSubImm";
643 let ParserMethod = "tryParseAddSubImm";
645 def AddSubImmNegOperand : AsmOperandClass {
646 let Name = "AddSubImmNeg";
647 let ParserMethod = "tryParseAddSubImm";
650 // An ADD/SUB immediate shifter operand:
652 // {7-6} - shift type: 00 = lsl
653 // {5-0} - imm6: #0 or #12
654 class addsub_shifted_imm<ValueType Ty>
655 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
656 let PrintMethod = "printAddSubImm";
657 let EncoderMethod = "getAddSubImmOpValue";
658 let ParserMatchClass = AddSubImmOperand;
659 let MIOperandInfo = (ops i32imm, i32imm);
662 class addsub_shifted_imm_neg<ValueType Ty>
664 let EncoderMethod = "getAddSubImmOpValue";
665 let ParserMatchClass = AddSubImmNegOperand;
666 let MIOperandInfo = (ops i32imm, i32imm);
669 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
670 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
671 def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
672 def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
674 class neg_addsub_shifted_imm<ValueType Ty>
675 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
676 let PrintMethod = "printAddSubImm";
677 let EncoderMethod = "getAddSubImmOpValue";
678 let ParserMatchClass = AddSubImmOperand;
679 let MIOperandInfo = (ops i32imm, i32imm);
682 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
683 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
685 // An extend operand:
686 // {5-3} - extend type
688 def arith_extend : Operand<i32> {
689 let PrintMethod = "printArithExtend";
690 let ParserMatchClass = ExtendOperand;
692 def arith_extend64 : Operand<i32> {
693 let PrintMethod = "printArithExtend";
694 let ParserMatchClass = ExtendOperand64;
697 // 'extend' that's a lsl of a 64-bit register.
698 def arith_extendlsl64 : Operand<i32> {
699 let PrintMethod = "printArithExtend";
700 let ParserMatchClass = ExtendOperandLSL64;
703 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
704 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
705 let PrintMethod = "printExtendedRegister";
706 let MIOperandInfo = (ops GPR32, arith_extend);
709 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
710 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
711 let PrintMethod = "printExtendedRegister";
712 let MIOperandInfo = (ops GPR32, arith_extend64);
715 // Floating-point immediate.
716 def fpimm32 : Operand<f32>,
717 PatLeaf<(f32 fpimm), [{
718 return AArch64_AM::getFP32Imm(N->getValueAPF()) != -1;
719 }], SDNodeXForm<fpimm, [{
720 APFloat InVal = N->getValueAPF();
721 uint32_t enc = AArch64_AM::getFP32Imm(InVal);
722 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
724 let ParserMatchClass = FPImmOperand;
725 let PrintMethod = "printFPImmOperand";
727 def fpimm64 : Operand<f64>,
728 PatLeaf<(f64 fpimm), [{
729 return AArch64_AM::getFP64Imm(N->getValueAPF()) != -1;
730 }], SDNodeXForm<fpimm, [{
731 APFloat InVal = N->getValueAPF();
732 uint32_t enc = AArch64_AM::getFP64Imm(InVal);
733 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
735 let ParserMatchClass = FPImmOperand;
736 let PrintMethod = "printFPImmOperand";
739 def fpimm8 : Operand<i32> {
740 let ParserMatchClass = FPImmOperand;
741 let PrintMethod = "printFPImmOperand";
744 def fpimm0 : PatLeaf<(fpimm), [{
745 return N->isExactlyValue(+0.0);
748 // Vector lane operands
749 class AsmVectorIndex<string Suffix> : AsmOperandClass {
750 let Name = "VectorIndex" # Suffix;
751 let DiagnosticType = "InvalidIndex" # Suffix;
753 def VectorIndex1Operand : AsmVectorIndex<"1">;
754 def VectorIndexBOperand : AsmVectorIndex<"B">;
755 def VectorIndexHOperand : AsmVectorIndex<"H">;
756 def VectorIndexSOperand : AsmVectorIndex<"S">;
757 def VectorIndexDOperand : AsmVectorIndex<"D">;
759 def VectorIndex1 : Operand<i64>, ImmLeaf<i64, [{
760 return ((uint64_t)Imm) == 1;
762 let ParserMatchClass = VectorIndex1Operand;
763 let PrintMethod = "printVectorIndex";
764 let MIOperandInfo = (ops i64imm);
766 def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
767 return ((uint64_t)Imm) < 16;
769 let ParserMatchClass = VectorIndexBOperand;
770 let PrintMethod = "printVectorIndex";
771 let MIOperandInfo = (ops i64imm);
773 def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
774 return ((uint64_t)Imm) < 8;
776 let ParserMatchClass = VectorIndexHOperand;
777 let PrintMethod = "printVectorIndex";
778 let MIOperandInfo = (ops i64imm);
780 def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
781 return ((uint64_t)Imm) < 4;
783 let ParserMatchClass = VectorIndexSOperand;
784 let PrintMethod = "printVectorIndex";
785 let MIOperandInfo = (ops i64imm);
787 def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
788 return ((uint64_t)Imm) < 2;
790 let ParserMatchClass = VectorIndexDOperand;
791 let PrintMethod = "printVectorIndex";
792 let MIOperandInfo = (ops i64imm);
795 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
796 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
797 // are encoded as the eight bit value 'abcdefgh'.
798 def simdimmtype10 : Operand<i32>,
799 PatLeaf<(f64 fpimm), [{
800 return AArch64_AM::isAdvSIMDModImmType10(N->getValueAPF()
803 }], SDNodeXForm<fpimm, [{
804 APFloat InVal = N->getValueAPF();
805 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
808 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
810 let ParserMatchClass = SIMDImmType10Operand;
811 let PrintMethod = "printSIMDType10Operand";
819 // Base encoding for system instruction operands.
820 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
821 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
822 list<dag> pattern = []>
823 : I<oops, iops, asm, operands, "", pattern> {
824 let Inst{31-22} = 0b1101010100;
828 // System instructions which do not have an Rt register.
829 class SimpleSystemI<bit L, dag iops, string asm, string operands,
830 list<dag> pattern = []>
831 : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
832 let Inst{4-0} = 0b11111;
835 // System instructions which have an Rt register.
836 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
837 : BaseSystemI<L, oops, iops, asm, operands>,
843 // Hint instructions that take both a CRm and a 3-bit immediate.
844 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
845 // model patterns with sufficiently fine granularity
846 let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
847 class HintI<string mnemonic>
848 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
849 [(int_aarch64_hint imm0_127:$imm)]>,
852 let Inst{20-12} = 0b000110010;
853 let Inst{11-5} = imm;
856 // System instructions taking a single literal operand which encodes into
857 // CRm. op2 differentiates the opcodes.
858 def BarrierAsmOperand : AsmOperandClass {
859 let Name = "Barrier";
860 let ParserMethod = "tryParseBarrierOperand";
862 def barrier_op : Operand<i32> {
863 let PrintMethod = "printBarrierOption";
864 let ParserMatchClass = BarrierAsmOperand;
866 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
867 list<dag> pattern = []>
868 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
869 Sched<[WriteBarrier]> {
871 let Inst{20-12} = 0b000110011;
872 let Inst{11-8} = CRm;
876 // MRS/MSR system instructions. These have different operand classes because
877 // a different subset of registers can be accessed through each instruction.
878 def MRSSystemRegisterOperand : AsmOperandClass {
879 let Name = "MRSSystemRegister";
880 let ParserMethod = "tryParseSysReg";
881 let DiagnosticType = "MRS";
883 // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
884 def mrs_sysreg_op : Operand<i32> {
885 let ParserMatchClass = MRSSystemRegisterOperand;
886 let DecoderMethod = "DecodeMRSSystemRegister";
887 let PrintMethod = "printMRSSystemRegister";
890 def MSRSystemRegisterOperand : AsmOperandClass {
891 let Name = "MSRSystemRegister";
892 let ParserMethod = "tryParseSysReg";
893 let DiagnosticType = "MSR";
895 def msr_sysreg_op : Operand<i32> {
896 let ParserMatchClass = MSRSystemRegisterOperand;
897 let DecoderMethod = "DecodeMSRSystemRegister";
898 let PrintMethod = "printMSRSystemRegister";
901 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
902 "mrs", "\t$Rt, $systemreg"> {
904 let Inst{20-5} = systemreg;
907 // FIXME: Some of these def NZCV, others don't. Best way to model that?
908 // Explicitly modeling each of the system register as a register class
909 // would do it, but feels like overkill at this point.
910 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
911 "msr", "\t$systemreg, $Rt"> {
913 let Inst{20-5} = systemreg;
916 def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {
917 let Name = "SystemPStateFieldWithImm0_15";
918 let ParserMethod = "tryParseSysReg";
920 def pstatefield4_op : Operand<i32> {
921 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;
922 let PrintMethod = "printSystemPStateField";
926 class MSRpstateImm0_15
927 : SimpleSystemI<0, (ins pstatefield4_op:$pstatefield, imm0_15:$imm),
928 "msr", "\t$pstatefield, $imm">,
932 let Inst{20-19} = 0b00;
933 let Inst{18-16} = pstatefield{5-3};
934 let Inst{15-12} = 0b0100;
935 let Inst{11-8} = imm;
936 let Inst{7-5} = pstatefield{2-0};
938 let DecoderMethod = "DecodeSystemPStateInstruction";
939 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
940 // Fail the decoder should attempt to decode the instruction as MSRI.
941 let hasCompleteDecoder = 0;
944 def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {
945 let Name = "SystemPStateFieldWithImm0_1";
946 let ParserMethod = "tryParseSysReg";
948 def pstatefield1_op : Operand<i32> {
949 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;
950 let PrintMethod = "printSystemPStateField";
954 class MSRpstateImm0_1
955 : SimpleSystemI<0, (ins pstatefield1_op:$pstatefield, imm0_1:$imm),
956 "msr", "\t$pstatefield, $imm">,
960 let Inst{20-19} = 0b00;
961 let Inst{18-16} = pstatefield{5-3};
962 let Inst{15-9} = 0b0100000;
964 let Inst{7-5} = pstatefield{2-0};
966 let DecoderMethod = "DecodeSystemPStateInstruction";
967 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
968 // Fail the decoder should attempt to decode the instruction as MSRI.
969 let hasCompleteDecoder = 0;
972 // SYS and SYSL generic system instructions.
973 def SysCRAsmOperand : AsmOperandClass {
975 let ParserMethod = "tryParseSysCROperand";
978 def sys_cr_op : Operand<i32> {
979 let PrintMethod = "printSysCROperand";
980 let ParserMatchClass = SysCRAsmOperand;
983 class SystemXtI<bit L, string asm>
984 : RtSystemI<L, (outs),
985 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
986 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
991 let Inst{20-19} = 0b01;
992 let Inst{18-16} = op1;
993 let Inst{15-12} = Cn;
998 class SystemLXtI<bit L, string asm>
999 : RtSystemI<L, (outs),
1000 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
1001 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
1006 let Inst{20-19} = 0b01;
1007 let Inst{18-16} = op1;
1008 let Inst{15-12} = Cn;
1009 let Inst{11-8} = Cm;
1010 let Inst{7-5} = op2;
1014 // Branch (register) instructions:
1022 // otherwise UNDEFINED
1023 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
1024 string operands, list<dag> pattern>
1025 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
1026 let Inst{31-25} = 0b1101011;
1027 let Inst{24-21} = opc;
1028 let Inst{20-16} = 0b11111;
1029 let Inst{15-10} = 0b000000;
1030 let Inst{4-0} = 0b00000;
1033 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
1034 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
1039 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
1040 class SpecialReturn<bits<4> opc, string asm>
1041 : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1042 let Inst{9-5} = 0b11111;
1046 // Conditional branch instruction.
1050 // 4-bit immediate. Pretty-printed as <cc>
1051 def ccode : Operand<i32> {
1052 let PrintMethod = "printCondCode";
1053 let ParserMatchClass = CondCode;
1055 def inv_ccode : Operand<i32> {
1056 // AL and NV are invalid in the aliases which use inv_ccode
1057 let PrintMethod = "printInverseCondCode";
1058 let ParserMatchClass = CondCode;
1059 let MCOperandPredicate = [{
1060 return MCOp.isImm() &&
1061 MCOp.getImm() != AArch64CC::AL &&
1062 MCOp.getImm() != AArch64CC::NV;
1066 // Conditional branch target. 19-bit immediate. The low two bits of the target
1067 // offset are implied zero and so are not part of the immediate.
1068 def PCRelLabel19Operand : AsmOperandClass {
1069 let Name = "PCRelLabel19";
1070 let DiagnosticType = "InvalidLabel";
1072 def am_brcond : Operand<OtherVT> {
1073 let EncoderMethod = "getCondBranchTargetOpValue";
1074 let DecoderMethod = "DecodePCRelLabel19";
1075 let PrintMethod = "printAlignedLabel";
1076 let ParserMatchClass = PCRelLabel19Operand;
1079 class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1080 "b", ".$cond\t$target", "",
1081 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1084 let isTerminator = 1;
1089 let Inst{31-24} = 0b01010100;
1090 let Inst{23-5} = target;
1092 let Inst{3-0} = cond;
1096 // Compare-and-branch instructions.
1098 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1099 : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1100 asm, "\t$Rt, $target", "",
1101 [(node regtype:$Rt, bb:$target)]>,
1104 let isTerminator = 1;
1108 let Inst{30-25} = 0b011010;
1110 let Inst{23-5} = target;
1114 multiclass CmpBranch<bit op, string asm, SDNode node> {
1115 def W : BaseCmpBranch<GPR32, op, asm, node> {
1118 def X : BaseCmpBranch<GPR64, op, asm, node> {
1124 // Test-bit-and-branch instructions.
1126 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1127 // the target offset are implied zero and so are not part of the immediate.
1128 def BranchTarget14Operand : AsmOperandClass {
1129 let Name = "BranchTarget14";
1131 def am_tbrcond : Operand<OtherVT> {
1132 let EncoderMethod = "getTestBranchTargetOpValue";
1133 let PrintMethod = "printAlignedLabel";
1134 let ParserMatchClass = BranchTarget14Operand;
1137 // AsmOperand classes to emit (or not) special diagnostics
1138 def TBZImm0_31Operand : AsmOperandClass {
1139 let Name = "TBZImm0_31";
1140 let PredicateMethod = "isImm0_31";
1141 let RenderMethod = "addImm0_31Operands";
1143 def TBZImm32_63Operand : AsmOperandClass {
1144 let Name = "Imm32_63";
1145 let DiagnosticType = "InvalidImm0_63";
1148 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1149 return (((uint32_t)Imm) < 32);
1151 let ParserMatchClass = matcher;
1154 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1155 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1157 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1158 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1160 let ParserMatchClass = TBZImm32_63Operand;
1163 class BaseTestBranch<RegisterClass regtype, Operand immtype,
1164 bit op, string asm, SDNode node>
1165 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1166 asm, "\t$Rt, $bit_off, $target", "",
1167 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1170 let isTerminator = 1;
1176 let Inst{30-25} = 0b011011;
1178 let Inst{23-19} = bit_off{4-0};
1179 let Inst{18-5} = target;
1182 let DecoderMethod = "DecodeTestAndBranch";
1185 multiclass TestBranch<bit op, string asm, SDNode node> {
1186 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1190 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1194 // Alias X-reg with 0-31 imm to W-Reg.
1195 def : InstAlias<asm # "\t$Rd, $imm, $target",
1196 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1197 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1198 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1199 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1200 tbz_imm0_31_diag:$imm, bb:$target)>;
1204 // Unconditional branch (immediate) instructions.
1206 def BranchTarget26Operand : AsmOperandClass {
1207 let Name = "BranchTarget26";
1208 let DiagnosticType = "InvalidLabel";
1210 def am_b_target : Operand<OtherVT> {
1211 let EncoderMethod = "getBranchTargetOpValue";
1212 let PrintMethod = "printAlignedLabel";
1213 let ParserMatchClass = BranchTarget26Operand;
1215 def am_bl_target : Operand<i64> {
1216 let EncoderMethod = "getBranchTargetOpValue";
1217 let PrintMethod = "printAlignedLabel";
1218 let ParserMatchClass = BranchTarget26Operand;
1221 class BImm<bit op, dag iops, string asm, list<dag> pattern>
1222 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1225 let Inst{30-26} = 0b00101;
1226 let Inst{25-0} = addr;
1228 let DecoderMethod = "DecodeUnconditionalBranch";
1231 class BranchImm<bit op, string asm, list<dag> pattern>
1232 : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1233 class CallImm<bit op, string asm, list<dag> pattern>
1234 : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1237 // Basic one-operand data processing instructions.
1240 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1241 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1242 SDPatternOperator node>
1243 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1244 [(set regtype:$Rd, (node regtype:$Rn))]>,
1245 Sched<[WriteI, ReadI]> {
1249 let Inst{30-13} = 0b101101011000000000;
1250 let Inst{12-10} = opc;
1255 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1256 multiclass OneOperandData<bits<3> opc, string asm,
1257 SDPatternOperator node = null_frag> {
1258 def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1262 def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1267 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1268 : BaseOneOperandData<opc, GPR32, asm, node> {
1272 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1273 : BaseOneOperandData<opc, GPR64, asm, node> {
1278 // Basic two-operand data processing instructions.
1280 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1282 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1283 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1284 Sched<[WriteI, ReadI, ReadI]> {
1289 let Inst{30} = isSub;
1290 let Inst{28-21} = 0b11010000;
1291 let Inst{20-16} = Rm;
1292 let Inst{15-10} = 0;
1297 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1299 : BaseBaseAddSubCarry<isSub, regtype, asm,
1300 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1302 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1304 : BaseBaseAddSubCarry<isSub, regtype, asm,
1305 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1310 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1311 SDNode OpNode, SDNode OpNode_setflags> {
1312 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1316 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1322 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1327 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1334 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1335 SDPatternOperator OpNode>
1336 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1337 asm, "\t$Rd, $Rn, $Rm", "",
1338 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
1342 let Inst{30-21} = 0b0011010110;
1343 let Inst{20-16} = Rm;
1344 let Inst{15-14} = 0b00;
1345 let Inst{13-10} = opc;
1350 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1351 SDPatternOperator OpNode>
1352 : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1353 let Inst{10} = isSigned;
1356 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1357 def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1358 Sched<[WriteID32, ReadID, ReadID]> {
1361 def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1362 Sched<[WriteID64, ReadID, ReadID]> {
1367 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1368 SDPatternOperator OpNode = null_frag>
1369 : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1370 Sched<[WriteIS, ReadI]> {
1371 let Inst{11-10} = shift_type;
1374 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
1375 def Wr : BaseShift<shift_type, GPR32, asm> {
1379 def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1383 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1384 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1385 (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1387 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1388 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1390 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1391 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1393 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1394 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1397 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
1398 : InstAlias<asm#"\t$dst, $src1, $src2",
1399 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
1401 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1402 RegisterClass addtype, string asm,
1404 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1405 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1410 let Inst{30-24} = 0b0011011;
1411 let Inst{23-21} = opc;
1412 let Inst{20-16} = Rm;
1413 let Inst{15} = isSub;
1414 let Inst{14-10} = Ra;
1419 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
1420 // MADD/MSUB generation is decided by MachineCombiner.cpp
1421 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
1422 [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
1423 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1427 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
1428 [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
1429 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
1434 class WideMulAccum<bit isSub, bits<3> opc, string asm,
1435 SDNode AccNode, SDNode ExtNode>
1436 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
1437 [(set GPR64:$Rd, (AccNode GPR64:$Ra,
1438 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
1439 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1443 class MulHi<bits<3> opc, string asm, SDNode OpNode>
1444 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
1445 asm, "\t$Rd, $Rn, $Rm", "",
1446 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
1447 Sched<[WriteIM64, ReadIM, ReadIM]> {
1451 let Inst{31-24} = 0b10011011;
1452 let Inst{23-21} = opc;
1453 let Inst{20-16} = Rm;
1458 // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
1459 // (i.e. all bits 1) but is ignored by the processor.
1460 let PostEncoderMethod = "fixMulHigh";
1463 class MulAccumWAlias<string asm, Instruction inst>
1464 : InstAlias<asm#"\t$dst, $src1, $src2",
1465 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
1466 class MulAccumXAlias<string asm, Instruction inst>
1467 : InstAlias<asm#"\t$dst, $src1, $src2",
1468 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
1469 class WideMulAccumAlias<string asm, Instruction inst>
1470 : InstAlias<asm#"\t$dst, $src1, $src2",
1471 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
1473 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
1474 SDPatternOperator OpNode, string asm>
1475 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
1476 asm, "\t$Rd, $Rn, $Rm", "",
1477 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
1478 Sched<[WriteISReg, ReadI, ReadISReg]> {
1484 let Inst{30-21} = 0b0011010110;
1485 let Inst{20-16} = Rm;
1486 let Inst{15-13} = 0b010;
1488 let Inst{11-10} = sz;
1491 let Predicates = [HasCRC];
1495 // Address generation.
1498 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
1499 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
1504 let Inst{31} = page;
1505 let Inst{30-29} = label{1-0};
1506 let Inst{28-24} = 0b10000;
1507 let Inst{23-5} = label{20-2};
1510 let DecoderMethod = "DecodeAdrInstruction";
1517 def movimm32_imm : Operand<i32> {
1518 let ParserMatchClass = Imm0_65535Operand;
1519 let EncoderMethod = "getMoveWideImmOpValue";
1520 let PrintMethod = "printHexImm";
1522 def movimm32_shift : Operand<i32> {
1523 let PrintMethod = "printShifter";
1524 let ParserMatchClass = MovImm32ShifterOperand;
1526 def movimm64_shift : Operand<i32> {
1527 let PrintMethod = "printShifter";
1528 let ParserMatchClass = MovImm64ShifterOperand;
1531 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1532 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1534 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
1535 asm, "\t$Rd, $imm$shift", "", []>,
1540 let Inst{30-29} = opc;
1541 let Inst{28-23} = 0b100101;
1542 let Inst{22-21} = shift{5-4};
1543 let Inst{20-5} = imm;
1546 let DecoderMethod = "DecodeMoveImmInstruction";
1549 multiclass MoveImmediate<bits<2> opc, string asm> {
1550 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
1554 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
1559 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1560 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1562 : I<(outs regtype:$Rd),
1563 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
1564 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
1565 Sched<[WriteI, ReadI]> {
1569 let Inst{30-29} = opc;
1570 let Inst{28-23} = 0b100101;
1571 let Inst{22-21} = shift{5-4};
1572 let Inst{20-5} = imm;
1575 let DecoderMethod = "DecodeMoveImmInstruction";
1578 multiclass InsertImmediate<bits<2> opc, string asm> {
1579 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
1583 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
1592 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
1593 RegisterClass srcRegtype, addsub_shifted_imm immtype,
1594 string asm, SDPatternOperator OpNode>
1595 : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
1596 asm, "\t$Rd, $Rn, $imm", "",
1597 [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
1598 Sched<[WriteI, ReadI]> {
1602 let Inst{30} = isSub;
1603 let Inst{29} = setFlags;
1604 let Inst{28-24} = 0b10001;
1605 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
1606 let Inst{21-10} = imm{11-0};
1609 let DecoderMethod = "DecodeBaseAddSubImm";
1612 class BaseAddSubRegPseudo<RegisterClass regtype,
1613 SDPatternOperator OpNode>
1614 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1615 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1616 Sched<[WriteI, ReadI, ReadI]>;
1618 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
1619 arith_shifted_reg shifted_regtype, string asm,
1620 SDPatternOperator OpNode>
1621 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1622 asm, "\t$Rd, $Rn, $Rm", "",
1623 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
1624 Sched<[WriteISReg, ReadI, ReadISReg]> {
1625 // The operands are in order to match the 'addr' MI operands, so we
1626 // don't need an encoder method and by-name matching. Just use the default
1627 // in-order handling. Since we're using by-order, make sure the names
1633 let Inst{30} = isSub;
1634 let Inst{29} = setFlags;
1635 let Inst{28-24} = 0b01011;
1636 let Inst{23-22} = shift{7-6};
1638 let Inst{20-16} = src2;
1639 let Inst{15-10} = shift{5-0};
1640 let Inst{9-5} = src1;
1641 let Inst{4-0} = dst;
1643 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1646 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
1647 RegisterClass src1Regtype, Operand src2Regtype,
1648 string asm, SDPatternOperator OpNode>
1649 : I<(outs dstRegtype:$R1),
1650 (ins src1Regtype:$R2, src2Regtype:$R3),
1651 asm, "\t$R1, $R2, $R3", "",
1652 [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
1653 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1658 let Inst{30} = isSub;
1659 let Inst{29} = setFlags;
1660 let Inst{28-24} = 0b01011;
1661 let Inst{23-21} = 0b001;
1662 let Inst{20-16} = Rm;
1663 let Inst{15-13} = ext{5-3};
1664 let Inst{12-10} = ext{2-0};
1668 let DecoderMethod = "DecodeAddSubERegInstruction";
1671 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1672 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
1673 RegisterClass src1Regtype, RegisterClass src2Regtype,
1674 Operand ext_op, string asm>
1675 : I<(outs dstRegtype:$Rd),
1676 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
1677 asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
1678 Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1683 let Inst{30} = isSub;
1684 let Inst{29} = setFlags;
1685 let Inst{28-24} = 0b01011;
1686 let Inst{23-21} = 0b001;
1687 let Inst{20-16} = Rm;
1688 let Inst{15} = ext{5};
1689 let Inst{12-10} = ext{2-0};
1693 let DecoderMethod = "DecodeAddSubERegInstruction";
1696 // Aliases for register+register add/subtract.
1697 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
1698 RegisterClass src1Regtype, RegisterClass src2Regtype,
1700 : InstAlias<asm#"\t$dst, $src1, $src2",
1701 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
1704 multiclass AddSub<bit isSub, string mnemonic, string alias,
1705 SDPatternOperator OpNode = null_frag> {
1706 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1707 // Add/Subtract immediate
1708 // Increase the weight of the immediate variant to try to match it before
1709 // the extended register variant.
1710 // We used to match the register variant before the immediate when the
1711 // register argument could be implicitly zero-extended.
1712 let AddedComplexity = 6 in
1713 def Wri : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
1717 let AddedComplexity = 6 in
1718 def Xri : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
1723 // Add/Subtract register - Only used for CodeGen
1724 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1725 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1727 // Add/Subtract shifted register
1728 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
1732 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
1738 // Add/Subtract extended register
1739 let AddedComplexity = 1, hasSideEffects = 0 in {
1740 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
1741 arith_extended_reg32<i32>, mnemonic, OpNode> {
1744 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
1745 arith_extended_reg32to64<i64>, mnemonic, OpNode> {
1750 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
1751 arith_extendlsl64, mnemonic> {
1752 // UXTX and SXTX only.
1753 let Inst{14-13} = 0b11;
1757 // add Rd, Rb, -imm -> sub Rd, Rn, imm
1758 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
1759 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
1760 addsub_shifted_imm32_neg:$imm), 0>;
1761 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
1762 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
1763 addsub_shifted_imm64_neg:$imm), 0>;
1765 // Register/register aliases with no shift when SP is not used.
1766 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1767 GPR32, GPR32, GPR32, 0>;
1768 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1769 GPR64, GPR64, GPR64, 0>;
1771 // Register/register aliases with no shift when either the destination or
1772 // first source register is SP.
1773 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1774 GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
1775 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1776 GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
1777 def : AddSubRegAlias<mnemonic,
1778 !cast<Instruction>(NAME#"Xrx64"),
1779 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
1780 def : AddSubRegAlias<mnemonic,
1781 !cast<Instruction>(NAME#"Xrx64"),
1782 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
1785 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
1786 string alias, string cmpAlias> {
1787 let isCompare = 1, Defs = [NZCV] in {
1788 // Add/Subtract immediate
1789 def Wri : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
1793 def Xri : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
1798 // Add/Subtract register
1799 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1800 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1802 // Add/Subtract shifted register
1803 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
1807 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
1812 // Add/Subtract extended register
1813 let AddedComplexity = 1 in {
1814 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
1815 arith_extended_reg32<i32>, mnemonic, OpNode> {
1818 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
1819 arith_extended_reg32<i64>, mnemonic, OpNode> {
1824 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
1825 arith_extendlsl64, mnemonic> {
1826 // UXTX and SXTX only.
1827 let Inst{14-13} = 0b11;
1832 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
1833 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
1834 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
1835 addsub_shifted_imm32_neg:$imm), 0>;
1836 def : InstAlias<alias#"\t$Rd, $Rn, $imm",
1837 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
1838 addsub_shifted_imm64_neg:$imm), 0>;
1841 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
1842 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
1843 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
1844 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
1845 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
1846 WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
1847 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
1848 XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
1849 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
1850 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
1851 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
1852 WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
1853 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
1854 XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
1856 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
1857 def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
1858 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
1859 def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
1860 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
1862 // Compare shorthands
1863 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
1864 WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
1865 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
1866 XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
1867 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
1868 WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
1869 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
1870 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
1872 // Register/register aliases with no shift when SP is not used.
1873 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1874 GPR32, GPR32, GPR32, 0>;
1875 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1876 GPR64, GPR64, GPR64, 0>;
1878 // Register/register aliases with no shift when the first source register
1880 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1881 GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
1882 def : AddSubRegAlias<mnemonic,
1883 !cast<Instruction>(NAME#"Xrx64"),
1884 GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
1890 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1892 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
1894 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
1896 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
1897 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
1898 Sched<[WriteExtr, ReadExtrHi]> {
1904 let Inst{30-23} = 0b00100111;
1906 let Inst{20-16} = Rm;
1907 let Inst{15-10} = imm;
1912 multiclass ExtractImm<string asm> {
1913 def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
1915 (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
1918 // imm<5> must be zero.
1921 def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
1923 (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
1934 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1935 class BaseBitfieldImm<bits<2> opc,
1936 RegisterClass regtype, Operand imm_type, string asm>
1937 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
1938 asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
1939 Sched<[WriteIS, ReadI]> {
1945 let Inst{30-29} = opc;
1946 let Inst{28-23} = 0b100110;
1947 let Inst{21-16} = immr;
1948 let Inst{15-10} = imms;
1953 multiclass BitfieldImm<bits<2> opc, string asm> {
1954 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
1957 // imms<5> and immr<5> must be zero, else ReservedValue().
1961 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
1967 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1968 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
1969 RegisterClass regtype, Operand imm_type, string asm>
1970 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
1972 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
1973 Sched<[WriteIS, ReadI]> {
1979 let Inst{30-29} = opc;
1980 let Inst{28-23} = 0b100110;
1981 let Inst{21-16} = immr;
1982 let Inst{15-10} = imms;
1987 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
1988 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
1991 // imms<5> and immr<5> must be zero, else ReservedValue().
1995 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
2005 // Logical (immediate)
2006 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
2007 RegisterClass sregtype, Operand imm_type, string asm,
2009 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
2010 asm, "\t$Rd, $Rn, $imm", "", pattern>,
2011 Sched<[WriteI, ReadI]> {
2015 let Inst{30-29} = opc;
2016 let Inst{28-23} = 0b100100;
2017 let Inst{22} = imm{12};
2018 let Inst{21-16} = imm{11-6};
2019 let Inst{15-10} = imm{5-0};
2023 let DecoderMethod = "DecodeLogicalImmInstruction";
2026 // Logical (shifted register)
2027 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
2028 logical_shifted_reg shifted_regtype, string asm,
2030 : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
2031 asm, "\t$Rd, $Rn, $Rm", "", pattern>,
2032 Sched<[WriteISReg, ReadI, ReadISReg]> {
2033 // The operands are in order to match the 'addr' MI operands, so we
2034 // don't need an encoder method and by-name matching. Just use the default
2035 // in-order handling. Since we're using by-order, make sure the names
2041 let Inst{30-29} = opc;
2042 let Inst{28-24} = 0b01010;
2043 let Inst{23-22} = shift{7-6};
2045 let Inst{20-16} = src2;
2046 let Inst{15-10} = shift{5-0};
2047 let Inst{9-5} = src1;
2048 let Inst{4-0} = dst;
2050 let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2053 // Aliases for register+register logical instructions.
2054 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
2055 : InstAlias<asm#"\t$dst, $src1, $src2",
2056 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2058 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2060 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2061 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2062 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2063 logical_imm32:$imm))]> {
2065 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2067 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2068 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2069 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2070 logical_imm64:$imm))]> {
2074 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
2075 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2076 logical_imm32_not:$imm), 0>;
2077 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
2078 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2079 logical_imm64_not:$imm), 0>;
2082 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2084 let isCompare = 1, Defs = [NZCV] in {
2085 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2086 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2088 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2090 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2091 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2094 } // end Defs = [NZCV]
2096 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
2097 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2098 logical_imm32_not:$imm), 0>;
2099 def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
2100 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2101 logical_imm64_not:$imm), 0>;
2104 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2105 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2106 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2107 Sched<[WriteI, ReadI, ReadI]>;
2109 // Split from LogicalImm as not all instructions have both.
2110 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2111 SDPatternOperator OpNode> {
2112 let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2113 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2114 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2117 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2118 [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2119 logical_shifted_reg32:$Rm))]> {
2122 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2123 [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2124 logical_shifted_reg64:$Rm))]> {
2128 def : LogicalRegAlias<mnemonic,
2129 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2130 def : LogicalRegAlias<mnemonic,
2131 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2134 // Split from LogicalReg to allow setting NZCV Defs
2135 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2136 SDPatternOperator OpNode = null_frag> {
2137 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2138 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2139 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2141 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2142 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2145 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2146 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2151 def : LogicalRegAlias<mnemonic,
2152 !cast<Instruction>(NAME#"Wrs"), GPR32>;
2153 def : LogicalRegAlias<mnemonic,
2154 !cast<Instruction>(NAME#"Xrs"), GPR64>;
2158 // Conditionally set flags
2161 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2162 class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2163 string mnemonic, SDNode OpNode>
2164 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2165 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2166 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2167 (i32 imm:$cond), NZCV))]>,
2168 Sched<[WriteI, ReadI]> {
2178 let Inst{29-21} = 0b111010010;
2179 let Inst{20-16} = imm;
2180 let Inst{15-12} = cond;
2181 let Inst{11-10} = 0b10;
2184 let Inst{3-0} = nzcv;
2187 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2188 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2190 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2191 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2192 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2193 (i32 imm:$cond), NZCV))]>,
2194 Sched<[WriteI, ReadI, ReadI]> {
2204 let Inst{29-21} = 0b111010010;
2205 let Inst{20-16} = Rm;
2206 let Inst{15-12} = cond;
2207 let Inst{11-10} = 0b00;
2210 let Inst{3-0} = nzcv;
2213 multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
2214 // immediate operand variants
2215 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
2218 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
2221 // register operand variants
2222 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
2225 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
2231 // Conditional select
2234 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2235 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2236 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2238 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2239 Sched<[WriteI, ReadI, ReadI]> {
2248 let Inst{29-21} = 0b011010100;
2249 let Inst{20-16} = Rm;
2250 let Inst{15-12} = cond;
2251 let Inst{11-10} = op2;
2256 multiclass CondSelect<bit op, bits<2> op2, string asm> {
2257 def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2260 def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2265 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2267 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2268 asm, "\t$Rd, $Rn, $Rm, $cond", "",
2270 (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2271 (i32 imm:$cond), NZCV))]>,
2272 Sched<[WriteI, ReadI, ReadI]> {
2281 let Inst{29-21} = 0b011010100;
2282 let Inst{20-16} = Rm;
2283 let Inst{15-12} = cond;
2284 let Inst{11-10} = op2;
2289 def inv_cond_XFORM : SDNodeXForm<imm, [{
2290 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
2291 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
2295 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
2296 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
2299 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
2303 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
2304 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
2305 (inv_cond_XFORM imm:$cond))>;
2307 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
2308 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
2309 (inv_cond_XFORM imm:$cond))>;
2313 // Special Mask Value
2315 def maski8_or_more : Operand<i32>,
2316 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
2318 def maski16_or_more : Operand<i32>,
2319 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
2327 // (unsigned immediate)
2328 // Indexed for 8-bit registers. offset is in range [0,4095].
2329 def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
2330 def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
2331 def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
2332 def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
2333 def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
2335 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
2336 let Name = "UImm12Offset" # Scale;
2337 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
2338 let PredicateMethod = "isUImm12Offset<" # Scale # ">";
2339 let DiagnosticType = "InvalidMemoryIndexed" # Scale;
2342 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
2343 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
2344 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
2345 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
2346 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
2348 class uimm12_scaled<int Scale> : Operand<i64> {
2349 let ParserMatchClass
2350 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
2352 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
2353 let PrintMethod = "printUImm12Offset<" # Scale # ">";
2356 def uimm12s1 : uimm12_scaled<1>;
2357 def uimm12s2 : uimm12_scaled<2>;
2358 def uimm12s4 : uimm12_scaled<4>;
2359 def uimm12s8 : uimm12_scaled<8>;
2360 def uimm12s16 : uimm12_scaled<16>;
2362 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2363 string asm, list<dag> pattern>
2364 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2370 let Inst{31-30} = sz;
2371 let Inst{29-27} = 0b111;
2373 let Inst{25-24} = 0b01;
2374 let Inst{23-22} = opc;
2375 let Inst{21-10} = offset;
2379 let DecoderMethod = "DecodeUnsignedLdStInstruction";
2382 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2383 Operand indextype, string asm, list<dag> pattern> {
2384 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2385 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
2386 (ins GPR64sp:$Rn, indextype:$offset),
2390 def : InstAlias<asm # "\t$Rt, [$Rn]",
2391 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2394 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2395 Operand indextype, string asm, list<dag> pattern> {
2396 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2397 def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2398 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2402 def : InstAlias<asm # "\t$Rt, [$Rn]",
2403 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2406 def PrefetchOperand : AsmOperandClass {
2407 let Name = "Prefetch";
2408 let ParserMethod = "tryParsePrefetch";
2410 def prfop : Operand<i32> {
2411 let PrintMethod = "printPrefetchOp";
2412 let ParserMatchClass = PrefetchOperand;
2415 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2416 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2417 : BaseLoadStoreUI<sz, V, opc,
2418 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
2426 // Load literal address: 19-bit immediate. The low two bits of the target
2427 // offset are implied zero and so are not part of the immediate.
2428 def am_ldrlit : Operand<OtherVT> {
2429 let EncoderMethod = "getLoadLiteralOpValue";
2430 let DecoderMethod = "DecodePCRelLabel19";
2431 let PrintMethod = "printAlignedLabel";
2432 let ParserMatchClass = PCRelLabel19Operand;
2435 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2436 class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
2437 : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
2438 asm, "\t$Rt, $label", "", []>,
2442 let Inst{31-30} = opc;
2443 let Inst{29-27} = 0b011;
2445 let Inst{25-24} = 0b00;
2446 let Inst{23-5} = label;
2450 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2451 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
2452 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
2453 asm, "\t$Rt, $label", "", pat>,
2457 let Inst{31-30} = opc;
2458 let Inst{29-27} = 0b011;
2460 let Inst{25-24} = 0b00;
2461 let Inst{23-5} = label;
2466 // Load/store register offset
2469 def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
2470 def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
2471 def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
2472 def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
2473 def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
2475 def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
2476 def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
2477 def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
2478 def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
2479 def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
2481 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
2482 let Name = "Mem" # Reg # "Extend" # Width;
2483 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
2484 let RenderMethod = "addMemExtendOperands";
2485 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
2488 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
2489 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2490 // the trivial shift.
2491 let RenderMethod = "addMemExtend8Operands";
2493 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
2494 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
2495 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
2496 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
2498 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
2499 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2500 // the trivial shift.
2501 let RenderMethod = "addMemExtend8Operands";
2503 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
2504 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
2505 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
2506 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
2508 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
2510 let ParserMatchClass = ParserClass;
2511 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
2512 let DecoderMethod = "DecodeMemExtend";
2513 let EncoderMethod = "getMemExtendOpValue";
2514 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
2517 def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>;
2518 def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>;
2519 def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>;
2520 def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>;
2521 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
2523 def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>;
2524 def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>;
2525 def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>;
2526 def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>;
2527 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
2529 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
2530 Operand wextend, Operand xextend> {
2531 // CodeGen-level pattern covering the entire addressing mode.
2532 ComplexPattern Wpat = windex;
2533 ComplexPattern Xpat = xindex;
2535 // Asm-level Operand covering the valid "uxtw #3" style syntax.
2536 Operand Wext = wextend;
2537 Operand Xext = xextend;
2540 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
2541 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
2542 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
2543 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
2544 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
2547 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2548 string asm, dag ins, dag outs, list<dag> pat>
2549 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2554 let Inst{31-30} = sz;
2555 let Inst{29-27} = 0b111;
2557 let Inst{25-24} = 0b00;
2558 let Inst{23-22} = opc;
2560 let Inst{20-16} = Rm;
2561 let Inst{15} = extend{1}; // sign extend Rm?
2563 let Inst{12} = extend{0}; // do shift?
2564 let Inst{11-10} = 0b10;
2569 class ROInstAlias<string asm, RegisterClass regtype, Instruction INST>
2570 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
2571 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2573 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2574 string asm, ValueType Ty, SDPatternOperator loadop> {
2575 let AddedComplexity = 10 in
2576 def roW : LoadStore8RO<sz, V, opc, regtype, asm,
2578 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2579 [(set (Ty regtype:$Rt),
2580 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2581 ro_Wextend8:$extend)))]>,
2582 Sched<[WriteLDIdx, ReadAdrBase]> {
2586 let AddedComplexity = 10 in
2587 def roX : LoadStore8RO<sz, V, opc, regtype, asm,
2589 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2590 [(set (Ty regtype:$Rt),
2591 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2592 ro_Xextend8:$extend)))]>,
2593 Sched<[WriteLDIdx, ReadAdrBase]> {
2597 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2600 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2601 string asm, ValueType Ty, SDPatternOperator storeop> {
2602 let AddedComplexity = 10 in
2603 def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2604 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2605 [(storeop (Ty regtype:$Rt),
2606 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2607 ro_Wextend8:$extend))]>,
2608 Sched<[WriteSTIdx, ReadAdrBase]> {
2612 let AddedComplexity = 10 in
2613 def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2614 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2615 [(storeop (Ty regtype:$Rt),
2616 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2617 ro_Xextend8:$extend))]>,
2618 Sched<[WriteSTIdx, ReadAdrBase]> {
2622 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2625 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2626 string asm, dag ins, dag outs, list<dag> pat>
2627 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2632 let Inst{31-30} = sz;
2633 let Inst{29-27} = 0b111;
2635 let Inst{25-24} = 0b00;
2636 let Inst{23-22} = opc;
2638 let Inst{20-16} = Rm;
2639 let Inst{15} = extend{1}; // sign extend Rm?
2641 let Inst{12} = extend{0}; // do shift?
2642 let Inst{11-10} = 0b10;
2647 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2648 string asm, ValueType Ty, SDPatternOperator loadop> {
2649 let AddedComplexity = 10 in
2650 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2651 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2652 [(set (Ty regtype:$Rt),
2653 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2654 ro_Wextend16:$extend)))]>,
2655 Sched<[WriteLDIdx, ReadAdrBase]> {
2659 let AddedComplexity = 10 in
2660 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2661 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2662 [(set (Ty regtype:$Rt),
2663 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2664 ro_Xextend16:$extend)))]>,
2665 Sched<[WriteLDIdx, ReadAdrBase]> {
2669 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2672 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2673 string asm, ValueType Ty, SDPatternOperator storeop> {
2674 let AddedComplexity = 10 in
2675 def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2676 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2677 [(storeop (Ty regtype:$Rt),
2678 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2679 ro_Wextend16:$extend))]>,
2680 Sched<[WriteSTIdx, ReadAdrBase]> {
2684 let AddedComplexity = 10 in
2685 def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2686 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2687 [(storeop (Ty regtype:$Rt),
2688 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2689 ro_Xextend16:$extend))]>,
2690 Sched<[WriteSTIdx, ReadAdrBase]> {
2694 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2697 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2698 string asm, dag ins, dag outs, list<dag> pat>
2699 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2704 let Inst{31-30} = sz;
2705 let Inst{29-27} = 0b111;
2707 let Inst{25-24} = 0b00;
2708 let Inst{23-22} = opc;
2710 let Inst{20-16} = Rm;
2711 let Inst{15} = extend{1}; // sign extend Rm?
2713 let Inst{12} = extend{0}; // do shift?
2714 let Inst{11-10} = 0b10;
2719 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2720 string asm, ValueType Ty, SDPatternOperator loadop> {
2721 let AddedComplexity = 10 in
2722 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2723 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2724 [(set (Ty regtype:$Rt),
2725 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2726 ro_Wextend32:$extend)))]>,
2727 Sched<[WriteLDIdx, ReadAdrBase]> {
2731 let AddedComplexity = 10 in
2732 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2733 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2734 [(set (Ty regtype:$Rt),
2735 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2736 ro_Xextend32:$extend)))]>,
2737 Sched<[WriteLDIdx, ReadAdrBase]> {
2741 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2744 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2745 string asm, ValueType Ty, SDPatternOperator storeop> {
2746 let AddedComplexity = 10 in
2747 def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2748 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2749 [(storeop (Ty regtype:$Rt),
2750 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2751 ro_Wextend32:$extend))]>,
2752 Sched<[WriteSTIdx, ReadAdrBase]> {
2756 let AddedComplexity = 10 in
2757 def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2758 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2759 [(storeop (Ty regtype:$Rt),
2760 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2761 ro_Xextend32:$extend))]>,
2762 Sched<[WriteSTIdx, ReadAdrBase]> {
2766 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2769 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2770 string asm, dag ins, dag outs, list<dag> pat>
2771 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2776 let Inst{31-30} = sz;
2777 let Inst{29-27} = 0b111;
2779 let Inst{25-24} = 0b00;
2780 let Inst{23-22} = opc;
2782 let Inst{20-16} = Rm;
2783 let Inst{15} = extend{1}; // sign extend Rm?
2785 let Inst{12} = extend{0}; // do shift?
2786 let Inst{11-10} = 0b10;
2791 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2792 string asm, ValueType Ty, SDPatternOperator loadop> {
2793 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2794 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2795 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2796 [(set (Ty regtype:$Rt),
2797 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2798 ro_Wextend64:$extend)))]>,
2799 Sched<[WriteLDIdx, ReadAdrBase]> {
2803 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2804 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2805 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2806 [(set (Ty regtype:$Rt),
2807 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2808 ro_Xextend64:$extend)))]>,
2809 Sched<[WriteLDIdx, ReadAdrBase]> {
2813 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2816 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2817 string asm, ValueType Ty, SDPatternOperator storeop> {
2818 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2819 def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2820 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2821 [(storeop (Ty regtype:$Rt),
2822 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2823 ro_Wextend64:$extend))]>,
2824 Sched<[WriteSTIdx, ReadAdrBase]> {
2828 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2829 def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2830 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2831 [(storeop (Ty regtype:$Rt),
2832 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2833 ro_Xextend64:$extend))]>,
2834 Sched<[WriteSTIdx, ReadAdrBase]> {
2838 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2841 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2842 string asm, dag ins, dag outs, list<dag> pat>
2843 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2848 let Inst{31-30} = sz;
2849 let Inst{29-27} = 0b111;
2851 let Inst{25-24} = 0b00;
2852 let Inst{23-22} = opc;
2854 let Inst{20-16} = Rm;
2855 let Inst{15} = extend{1}; // sign extend Rm?
2857 let Inst{12} = extend{0}; // do shift?
2858 let Inst{11-10} = 0b10;
2863 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2864 string asm, ValueType Ty, SDPatternOperator loadop> {
2865 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2866 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2867 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2868 [(set (Ty regtype:$Rt),
2869 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2870 ro_Wextend128:$extend)))]>,
2871 Sched<[WriteLDIdx, ReadAdrBase]> {
2875 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2876 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2877 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2878 [(set (Ty regtype:$Rt),
2879 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2880 ro_Xextend128:$extend)))]>,
2881 Sched<[WriteLDIdx, ReadAdrBase]> {
2885 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2888 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2889 string asm, ValueType Ty, SDPatternOperator storeop> {
2890 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2891 def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2892 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2893 [(storeop (Ty regtype:$Rt),
2894 (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2895 ro_Wextend128:$extend))]>,
2896 Sched<[WriteSTIdx, ReadAdrBase]> {
2900 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2901 def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2902 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2903 [(storeop (Ty regtype:$Rt),
2904 (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2905 ro_Xextend128:$extend))]>,
2906 Sched<[WriteSTIdx, ReadAdrBase]> {
2910 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2913 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2914 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
2915 string asm, list<dag> pat>
2916 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
2922 let Inst{31-30} = sz;
2923 let Inst{29-27} = 0b111;
2925 let Inst{25-24} = 0b00;
2926 let Inst{23-22} = opc;
2928 let Inst{20-16} = Rm;
2929 let Inst{15} = extend{1}; // sign extend Rm?
2931 let Inst{12} = extend{0}; // do shift?
2932 let Inst{11-10} = 0b10;
2937 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
2938 def roW : BasePrefetchRO<sz, V, opc, (outs),
2939 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2940 asm, [(AArch64Prefetch imm:$Rt,
2941 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2942 ro_Wextend64:$extend))]> {
2946 def roX : BasePrefetchRO<sz, V, opc, (outs),
2947 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2948 asm, [(AArch64Prefetch imm:$Rt,
2949 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2950 ro_Xextend64:$extend))]> {
2954 def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
2955 (!cast<Instruction>(NAME # "roX") prfop:$Rt,
2956 GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2960 // Load/store unscaled immediate
2963 def am_unscaled8 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
2964 def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
2965 def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
2966 def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
2967 def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
2969 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2970 string asm, list<dag> pattern>
2971 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2975 let Inst{31-30} = sz;
2976 let Inst{29-27} = 0b111;
2978 let Inst{25-24} = 0b00;
2979 let Inst{23-22} = opc;
2981 let Inst{20-12} = offset;
2982 let Inst{11-10} = 0b00;
2986 let DecoderMethod = "DecodeSignedLdStInstruction";
2989 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2990 string asm, list<dag> pattern> {
2991 let AddedComplexity = 1 in // try this before LoadUI
2992 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
2993 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
2996 def : InstAlias<asm # "\t$Rt, [$Rn]",
2997 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3000 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3001 string asm, list<dag> pattern> {
3002 let AddedComplexity = 1 in // try this before StoreUI
3003 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3004 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3008 def : InstAlias<asm # "\t$Rt, [$Rn]",
3009 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3012 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
3014 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3015 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
3016 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
3020 def : InstAlias<asm # "\t$Rt, [$Rn]",
3021 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
3025 // Load/store unscaled immediate, unprivileged
3028 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3029 dag oops, dag iops, string asm>
3030 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
3034 let Inst{31-30} = sz;
3035 let Inst{29-27} = 0b111;
3037 let Inst{25-24} = 0b00;
3038 let Inst{23-22} = opc;
3040 let Inst{20-12} = offset;
3041 let Inst{11-10} = 0b10;
3045 let DecoderMethod = "DecodeSignedLdStInstruction";
3048 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3049 RegisterClass regtype, string asm> {
3050 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3051 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3052 (ins GPR64sp:$Rn, simm9:$offset), asm>,
3055 def : InstAlias<asm # "\t$Rt, [$Rn]",
3056 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3059 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3060 RegisterClass regtype, string asm> {
3061 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3062 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3063 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3067 def : InstAlias<asm # "\t$Rt, [$Rn]",
3068 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3072 // Load/store pre-indexed
3075 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3076 string asm, string cstr, list<dag> pat>
3077 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3081 let Inst{31-30} = sz;
3082 let Inst{29-27} = 0b111;
3084 let Inst{25-24} = 0;
3085 let Inst{23-22} = opc;
3087 let Inst{20-12} = offset;
3088 let Inst{11-10} = 0b11;
3092 let DecoderMethod = "DecodeSignedLdStInstruction";
3095 let hasSideEffects = 0 in {
3096 let mayStore = 0, mayLoad = 1 in
3097 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3099 : BaseLoadStorePreIdx<sz, V, opc,
3100 (outs GPR64sp:$wback, regtype:$Rt),
3101 (ins GPR64sp:$Rn, simm9:$offset), asm,
3102 "$Rn = $wback,@earlyclobber $wback", []>,
3103 Sched<[WriteLD, WriteAdr]>;
3105 let mayStore = 1, mayLoad = 0 in
3106 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3107 string asm, SDPatternOperator storeop, ValueType Ty>
3108 : BaseLoadStorePreIdx<sz, V, opc,
3109 (outs GPR64sp:$wback),
3110 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3111 asm, "$Rn = $wback,@earlyclobber $wback",
3112 [(set GPR64sp:$wback,
3113 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3114 Sched<[WriteAdr, WriteST]>;
3115 } // hasSideEffects = 0
3118 // Load/store post-indexed
3121 class BaseLoadStorePostIdx<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} = 0b00;
3131 let Inst{23-22} = opc;
3133 let Inst{20-12} = offset;
3134 let Inst{11-10} = 0b01;
3138 let DecoderMethod = "DecodeSignedLdStInstruction";
3141 let hasSideEffects = 0 in {
3142 let mayStore = 0, mayLoad = 1 in
3143 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3145 : BaseLoadStorePostIdx<sz, V, opc,
3146 (outs GPR64sp:$wback, regtype:$Rt),
3147 (ins GPR64sp:$Rn, simm9:$offset),
3148 asm, "$Rn = $wback,@earlyclobber $wback", []>,
3149 Sched<[WriteLD, WriteI]>;
3151 let mayStore = 1, mayLoad = 0 in
3152 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3153 string asm, SDPatternOperator storeop, ValueType Ty>
3154 : BaseLoadStorePostIdx<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, ReadAdrBase]>;
3161 } // hasSideEffects = 0
3168 // (indexed, offset)
3170 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
3172 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3177 let Inst{31-30} = opc;
3178 let Inst{29-27} = 0b101;
3180 let Inst{25-23} = 0b010;
3182 let Inst{21-15} = offset;
3183 let Inst{14-10} = Rt2;
3187 let DecoderMethod = "DecodePairLdStInstruction";
3190 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
3191 Operand indextype, string asm> {
3192 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3193 def i : BaseLoadStorePairOffset<opc, V, 1,
3194 (outs regtype:$Rt, regtype:$Rt2),
3195 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3196 Sched<[WriteLD, WriteLDHi]>;
3198 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3199 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3204 multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
3205 Operand indextype, string asm> {
3206 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
3207 def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
3208 (ins regtype:$Rt, regtype:$Rt2,
3209 GPR64sp:$Rn, indextype:$offset),
3213 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3214 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3219 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3221 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
3226 let Inst{31-30} = opc;
3227 let Inst{29-27} = 0b101;
3229 let Inst{25-23} = 0b011;
3231 let Inst{21-15} = offset;
3232 let Inst{14-10} = Rt2;
3236 let DecoderMethod = "DecodePairLdStInstruction";
3239 let hasSideEffects = 0 in {
3240 let mayStore = 0, mayLoad = 1 in
3241 class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3242 Operand indextype, string asm>
3243 : BaseLoadStorePairPreIdx<opc, V, 1,
3244 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3245 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3246 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3248 let mayStore = 1, mayLoad = 0 in
3249 class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3250 Operand indextype, string asm>
3251 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
3252 (ins regtype:$Rt, regtype:$Rt2,
3253 GPR64sp:$Rn, indextype:$offset),
3255 Sched<[WriteAdr, WriteSTP]>;
3256 } // hasSideEffects = 0
3260 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3262 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
3267 let Inst{31-30} = opc;
3268 let Inst{29-27} = 0b101;
3270 let Inst{25-23} = 0b001;
3272 let Inst{21-15} = offset;
3273 let Inst{14-10} = Rt2;
3277 let DecoderMethod = "DecodePairLdStInstruction";
3280 let hasSideEffects = 0 in {
3281 let mayStore = 0, mayLoad = 1 in
3282 class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3283 Operand idxtype, string asm>
3284 : BaseLoadStorePairPostIdx<opc, V, 1,
3285 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3286 (ins GPR64sp:$Rn, idxtype:$offset), asm>,
3287 Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3289 let mayStore = 1, mayLoad = 0 in
3290 class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3291 Operand idxtype, string asm>
3292 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
3293 (ins regtype:$Rt, regtype:$Rt2,
3294 GPR64sp:$Rn, idxtype:$offset),
3296 Sched<[WriteAdr, WriteSTP]>;
3297 } // hasSideEffects = 0
3301 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
3303 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3308 let Inst{31-30} = opc;
3309 let Inst{29-27} = 0b101;
3311 let Inst{25-23} = 0b000;
3313 let Inst{21-15} = offset;
3314 let Inst{14-10} = Rt2;
3318 let DecoderMethod = "DecodePairLdStInstruction";
3321 multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3322 Operand indextype, string asm> {
3323 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3324 def i : BaseLoadStorePairNoAlloc<opc, V, 1,
3325 (outs regtype:$Rt, regtype:$Rt2),
3326 (ins GPR64sp:$Rn, indextype:$offset), asm>,
3327 Sched<[WriteLD, WriteLDHi]>;
3330 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3331 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3335 multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3336 Operand indextype, string asm> {
3337 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
3338 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
3339 (ins regtype:$Rt, regtype:$Rt2,
3340 GPR64sp:$Rn, indextype:$offset),
3344 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3345 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3350 // Load/store exclusive
3353 // True exclusive operations write to and/or read from the system's exclusive
3354 // monitors, which as far as a compiler is concerned can be modelled as a
3355 // random shared memory address. Hence LoadExclusive mayStore.
3357 // Since these instructions have the undefined register bits set to 1 in
3358 // their canonical form, we need a post encoder method to set those bits
3359 // to 1 when encoding these instructions. We do this using the
3360 // fixLoadStoreExclusive function. This function has template parameters:
3362 // fixLoadStoreExclusive<int hasRs, int hasRt2>
3364 // hasRs indicates that the instruction uses the Rs field, so we won't set
3365 // it to 1 (and the same for Rt2). We don't need template parameters for
3366 // the other register fields since Rt and Rn are always used.
3368 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
3369 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3370 dag oops, dag iops, string asm, string operands>
3371 : I<oops, iops, asm, operands, "", []> {
3372 let Inst{31-30} = sz;
3373 let Inst{29-24} = 0b001000;
3379 let DecoderMethod = "DecodeExclusiveLdStInstruction";
3382 // Neither Rs nor Rt2 operands.
3383 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3384 dag oops, dag iops, string asm, string operands>
3385 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
3388 let Inst{20-16} = 0b11111;
3389 let Unpredictable{20-16} = 0b11111;
3390 let Inst{14-10} = 0b11111;
3391 let Unpredictable{14-10} = 0b11111;
3395 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
3398 // Simple load acquires don't set the exclusive monitor
3399 let mayLoad = 1, mayStore = 0 in
3400 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3401 RegisterClass regtype, string asm>
3402 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3403 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3406 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3407 RegisterClass regtype, string asm>
3408 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3409 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3412 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3413 RegisterClass regtype, string asm>
3414 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3415 (outs regtype:$Rt, regtype:$Rt2),
3416 (ins GPR64sp0:$Rn), asm,
3417 "\t$Rt, $Rt2, [$Rn]">,
3418 Sched<[WriteLD, WriteLDHi]> {
3422 let Inst{14-10} = Rt2;
3426 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
3429 // Simple store release operations do not check the exclusive monitor.
3430 let mayLoad = 0, mayStore = 1 in
3431 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3432 RegisterClass regtype, string asm>
3433 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
3434 (ins regtype:$Rt, GPR64sp0:$Rn),
3435 asm, "\t$Rt, [$Rn]">,
3438 let mayLoad = 1, mayStore = 1 in
3439 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3440 RegisterClass regtype, string asm>
3441 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
3442 (ins regtype:$Rt, GPR64sp0:$Rn),
3443 asm, "\t$Ws, $Rt, [$Rn]">,
3448 let Inst{20-16} = Ws;
3452 let Constraints = "@earlyclobber $Ws";
3453 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
3456 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3457 RegisterClass regtype, string asm>
3458 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3460 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
3461 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
3467 let Inst{20-16} = Ws;
3468 let Inst{14-10} = Rt2;
3472 let Constraints = "@earlyclobber $Ws";
3476 // Exception generation
3479 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3480 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
3481 : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
3484 let Inst{31-24} = 0b11010100;
3485 let Inst{23-21} = op1;
3486 let Inst{20-5} = imm;
3487 let Inst{4-2} = 0b000;
3491 let Predicates = [HasFPARMv8] in {
3494 // Floating point to integer conversion
3497 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
3498 RegisterClass srcType, RegisterClass dstType,
3499 string asm, list<dag> pattern>
3500 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3501 asm, "\t$Rd, $Rn", "", pattern>,
3502 Sched<[WriteFCvt]> {
3505 let Inst{30-29} = 0b00;
3506 let Inst{28-24} = 0b11110;
3507 let Inst{23-22} = type;
3509 let Inst{20-19} = rmode;
3510 let Inst{18-16} = opcode;
3511 let Inst{15-10} = 0;
3516 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3517 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
3518 RegisterClass srcType, RegisterClass dstType,
3519 Operand immType, string asm, list<dag> pattern>
3520 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3521 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3522 Sched<[WriteFCvt]> {
3526 let Inst{30-29} = 0b00;
3527 let Inst{28-24} = 0b11110;
3528 let Inst{23-22} = type;
3530 let Inst{20-19} = rmode;
3531 let Inst{18-16} = opcode;
3532 let Inst{15-10} = scale;
3537 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
3538 SDPatternOperator OpN> {
3539 // Unscaled single-precision to 32-bit
3540 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
3541 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
3542 let Inst{31} = 0; // 32-bit GPR flag
3545 // Unscaled single-precision to 64-bit
3546 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
3547 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
3548 let Inst{31} = 1; // 64-bit GPR flag
3551 // Unscaled double-precision to 32-bit
3552 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
3553 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3554 let Inst{31} = 0; // 32-bit GPR flag
3557 // Unscaled double-precision to 64-bit
3558 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
3559 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3560 let Inst{31} = 1; // 64-bit GPR flag
3564 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
3565 SDPatternOperator OpN> {
3566 // Scaled single-precision to 32-bit
3567 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
3568 fixedpoint_f32_i32, asm,
3569 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
3570 fixedpoint_f32_i32:$scale)))]> {
3571 let Inst{31} = 0; // 32-bit GPR flag
3575 // Scaled single-precision to 64-bit
3576 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
3577 fixedpoint_f32_i64, asm,
3578 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
3579 fixedpoint_f32_i64:$scale)))]> {
3580 let Inst{31} = 1; // 64-bit GPR flag
3583 // Scaled double-precision to 32-bit
3584 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
3585 fixedpoint_f64_i32, asm,
3586 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
3587 fixedpoint_f64_i32:$scale)))]> {
3588 let Inst{31} = 0; // 32-bit GPR flag
3592 // Scaled double-precision to 64-bit
3593 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
3594 fixedpoint_f64_i64, asm,
3595 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
3596 fixedpoint_f64_i64:$scale)))]> {
3597 let Inst{31} = 1; // 64-bit GPR flag
3602 // Integer to floating point conversion
3605 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
3606 class BaseIntegerToFP<bit isUnsigned,
3607 RegisterClass srcType, RegisterClass dstType,
3608 Operand immType, string asm, list<dag> pattern>
3609 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3610 asm, "\t$Rd, $Rn, $scale", "", pattern>,
3611 Sched<[WriteFCvt]> {
3615 let Inst{30-23} = 0b00111100;
3616 let Inst{21-17} = 0b00001;
3617 let Inst{16} = isUnsigned;
3618 let Inst{15-10} = scale;
3623 class BaseIntegerToFPUnscaled<bit isUnsigned,
3624 RegisterClass srcType, RegisterClass dstType,
3625 ValueType dvt, string asm, SDNode node>
3626 : I<(outs dstType:$Rd), (ins srcType:$Rn),
3627 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
3628 Sched<[WriteFCvt]> {
3632 let Inst{30-23} = 0b00111100;
3633 let Inst{21-17} = 0b10001;
3634 let Inst{16} = isUnsigned;
3635 let Inst{15-10} = 0b000000;
3640 multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
3642 def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
3643 let Inst{31} = 0; // 32-bit GPR flag
3644 let Inst{22} = 0; // 32-bit FPR flag
3647 def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
3648 let Inst{31} = 0; // 32-bit GPR flag
3649 let Inst{22} = 1; // 64-bit FPR flag
3652 def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
3653 let Inst{31} = 1; // 64-bit GPR flag
3654 let Inst{22} = 0; // 32-bit FPR flag
3657 def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
3658 let Inst{31} = 1; // 64-bit GPR flag
3659 let Inst{22} = 1; // 64-bit FPR flag
3663 def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
3665 (fdiv (node GPR32:$Rn),
3666 fixedpoint_f32_i32:$scale))]> {
3667 let Inst{31} = 0; // 32-bit GPR flag
3668 let Inst{22} = 0; // 32-bit FPR flag
3672 def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
3674 (fdiv (node GPR32:$Rn),
3675 fixedpoint_f64_i32:$scale))]> {
3676 let Inst{31} = 0; // 32-bit GPR flag
3677 let Inst{22} = 1; // 64-bit FPR flag
3681 def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
3683 (fdiv (node GPR64:$Rn),
3684 fixedpoint_f32_i64:$scale))]> {
3685 let Inst{31} = 1; // 64-bit GPR flag
3686 let Inst{22} = 0; // 32-bit FPR flag
3689 def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
3691 (fdiv (node GPR64:$Rn),
3692 fixedpoint_f64_i64:$scale))]> {
3693 let Inst{31} = 1; // 64-bit GPR flag
3694 let Inst{22} = 1; // 64-bit FPR flag
3699 // Unscaled integer <-> floating point conversion (i.e. FMOV)
3702 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3703 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
3704 RegisterClass srcType, RegisterClass dstType,
3706 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
3707 // We use COPY_TO_REGCLASS for these bitconvert operations.
3708 // copyPhysReg() expands the resultant COPY instructions after
3709 // regalloc is done. This gives greater freedom for the allocator
3710 // and related passes (coalescing, copy propagation, et. al.) to
3711 // be more effective.
3712 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
3713 Sched<[WriteFCopy]> {
3716 let Inst{30-23} = 0b00111100;
3718 let Inst{20-19} = rmode;
3719 let Inst{18-16} = opcode;
3720 let Inst{15-10} = 0b000000;
3725 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3726 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
3727 RegisterClass srcType, RegisterOperand dstType, string asm,
3729 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3730 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
3731 Sched<[WriteFCopy]> {
3734 let Inst{30-23} = 0b00111101;
3736 let Inst{20-19} = rmode;
3737 let Inst{18-16} = opcode;
3738 let Inst{15-10} = 0b000000;
3742 let DecoderMethod = "DecodeFMOVLaneInstruction";
3745 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3746 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
3747 RegisterOperand srcType, RegisterClass dstType, string asm,
3749 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3750 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
3751 Sched<[WriteFCopy]> {
3754 let Inst{30-23} = 0b00111101;
3756 let Inst{20-19} = rmode;
3757 let Inst{18-16} = opcode;
3758 let Inst{15-10} = 0b000000;
3762 let DecoderMethod = "DecodeFMOVLaneInstruction";
3767 multiclass UnscaledConversion<string asm> {
3768 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
3769 let Inst{31} = 0; // 32-bit GPR flag
3770 let Inst{22} = 0; // 32-bit FPR flag
3773 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
3774 let Inst{31} = 1; // 64-bit GPR flag
3775 let Inst{22} = 1; // 64-bit FPR flag
3778 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
3779 let Inst{31} = 0; // 32-bit GPR flag
3780 let Inst{22} = 0; // 32-bit FPR flag
3783 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
3784 let Inst{31} = 1; // 64-bit GPR flag
3785 let Inst{22} = 1; // 64-bit FPR flag
3788 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
3794 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
3802 // Floating point conversion
3805 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
3806 RegisterClass srcType, string asm, list<dag> pattern>
3807 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
3808 Sched<[WriteFCvt]> {
3811 let Inst{31-24} = 0b00011110;
3812 let Inst{23-22} = type;
3813 let Inst{21-17} = 0b10001;
3814 let Inst{16-15} = opcode;
3815 let Inst{14-10} = 0b10000;
3820 multiclass FPConversion<string asm> {
3821 // Double-precision to Half-precision
3822 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
3823 [(set FPR16:$Rd, (fround FPR64:$Rn))]>;
3825 // Double-precision to Single-precision
3826 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
3827 [(set FPR32:$Rd, (fround FPR64:$Rn))]>;
3829 // Half-precision to Double-precision
3830 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
3831 [(set FPR64:$Rd, (fextend FPR16:$Rn))]>;
3833 // Half-precision to Single-precision
3834 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
3835 [(set FPR32:$Rd, (fextend FPR16:$Rn))]>;
3837 // Single-precision to Double-precision
3838 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
3839 [(set FPR64:$Rd, (fextend FPR32:$Rn))]>;
3841 // Single-precision to Half-precision
3842 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
3843 [(set FPR16:$Rd, (fround FPR32:$Rn))]>;
3847 // Single operand floating point data processing
3850 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3851 class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
3852 ValueType vt, string asm, SDPatternOperator node>
3853 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
3854 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
3858 let Inst{31-23} = 0b000111100;
3859 let Inst{21-19} = 0b100;
3860 let Inst{18-15} = opcode;
3861 let Inst{14-10} = 0b10000;
3866 multiclass SingleOperandFPData<bits<4> opcode, string asm,
3867 SDPatternOperator node = null_frag> {
3868 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
3869 let Inst{22} = 0; // 32-bit size flag
3872 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
3873 let Inst{22} = 1; // 64-bit size flag
3878 // Two operand floating point data processing
3881 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3882 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
3883 string asm, list<dag> pat>
3884 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
3885 asm, "\t$Rd, $Rn, $Rm", "", pat>,
3890 let Inst{31-23} = 0b000111100;
3892 let Inst{20-16} = Rm;
3893 let Inst{15-12} = opcode;
3894 let Inst{11-10} = 0b10;
3899 multiclass TwoOperandFPData<bits<4> opcode, string asm,
3900 SDPatternOperator node = null_frag> {
3901 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3902 [(set (f32 FPR32:$Rd),
3903 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
3904 let Inst{22} = 0; // 32-bit size flag
3907 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3908 [(set (f64 FPR64:$Rd),
3909 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
3910 let Inst{22} = 1; // 64-bit size flag
3914 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
3915 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3916 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
3917 let Inst{22} = 0; // 32-bit size flag
3920 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3921 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
3922 let Inst{22} = 1; // 64-bit size flag
3928 // Three operand floating point data processing
3931 class BaseThreeOperandFPData<bit isNegated, bit isSub,
3932 RegisterClass regtype, string asm, list<dag> pat>
3933 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
3934 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
3935 Sched<[WriteFMul]> {
3940 let Inst{31-23} = 0b000111110;
3941 let Inst{21} = isNegated;
3942 let Inst{20-16} = Rm;
3943 let Inst{15} = isSub;
3944 let Inst{14-10} = Ra;
3949 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
3950 SDPatternOperator node> {
3951 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
3953 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
3954 let Inst{22} = 0; // 32-bit size flag
3957 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
3959 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
3960 let Inst{22} = 1; // 64-bit size flag
3965 // Floating point data comparisons
3968 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3969 class BaseOneOperandFPComparison<bit signalAllNans,
3970 RegisterClass regtype, string asm,
3972 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
3973 Sched<[WriteFCmp]> {
3975 let Inst{31-23} = 0b000111100;
3978 let Inst{15-10} = 0b001000;
3980 let Inst{4} = signalAllNans;
3981 let Inst{3-0} = 0b1000;
3983 // Rm should be 0b00000 canonically, but we need to accept any value.
3984 let PostEncoderMethod = "fixOneOperandFPComparison";
3987 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3988 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
3989 string asm, list<dag> pat>
3990 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
3991 Sched<[WriteFCmp]> {
3994 let Inst{31-23} = 0b000111100;
3996 let Inst{20-16} = Rm;
3997 let Inst{15-10} = 0b001000;
3999 let Inst{4} = signalAllNans;
4000 let Inst{3-0} = 0b0000;
4003 multiclass FPComparison<bit signalAllNans, string asm,
4004 SDPatternOperator OpNode = null_frag> {
4005 let Defs = [NZCV] in {
4006 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
4007 [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
4011 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
4012 [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
4016 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
4017 [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
4021 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
4022 [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
4029 // Floating point conditional comparisons
4032 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4033 class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
4034 string mnemonic, list<dag> pat>
4035 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
4036 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
4037 Sched<[WriteFCmp]> {
4046 let Inst{31-23} = 0b000111100;
4048 let Inst{20-16} = Rm;
4049 let Inst{15-12} = cond;
4050 let Inst{11-10} = 0b01;
4052 let Inst{4} = signalAllNans;
4053 let Inst{3-0} = nzcv;
4056 multiclass FPCondComparison<bit signalAllNans, string mnemonic,
4057 SDPatternOperator OpNode = null_frag> {
4058 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
4059 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
4060 (i32 imm:$cond), NZCV))]> {
4063 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
4064 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
4065 (i32 imm:$cond), NZCV))]> {
4071 // Floating point conditional select
4074 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
4075 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
4076 asm, "\t$Rd, $Rn, $Rm, $cond", "",
4078 (AArch64csel (vt regtype:$Rn), regtype:$Rm,
4079 (i32 imm:$cond), NZCV))]>,
4086 let Inst{31-23} = 0b000111100;
4088 let Inst{20-16} = Rm;
4089 let Inst{15-12} = cond;
4090 let Inst{11-10} = 0b11;
4095 multiclass FPCondSelect<string asm> {
4096 let Uses = [NZCV] in {
4097 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
4101 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
4108 // Floating move immediate
4111 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
4112 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
4113 [(set regtype:$Rd, fpimmtype:$imm)]>,
4114 Sched<[WriteFImm]> {
4117 let Inst{31-23} = 0b000111100;
4119 let Inst{20-13} = imm;
4120 let Inst{12-5} = 0b10000000;
4124 multiclass FPMoveImmediate<string asm> {
4125 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
4129 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
4133 } // end of 'let Predicates = [HasFPARMv8]'
4135 //----------------------------------------------------------------------------
4137 //----------------------------------------------------------------------------
4139 let Predicates = [HasNEON] in {
4141 //----------------------------------------------------------------------------
4142 // AdvSIMD three register vector instructions
4143 //----------------------------------------------------------------------------
4145 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4146 class BaseSIMDThreeSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4147 RegisterOperand regtype, string asm, string kind,
4149 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4150 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4151 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
4159 let Inst{28-24} = 0b01110;
4160 let Inst{23-22} = size;
4162 let Inst{20-16} = Rm;
4163 let Inst{15-11} = opcode;
4169 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4170 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4171 RegisterOperand regtype, string asm, string kind,
4173 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
4174 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4175 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4183 let Inst{28-24} = 0b01110;
4184 let Inst{23-22} = size;
4186 let Inst{20-16} = Rm;
4187 let Inst{15-11} = opcode;
4193 // All operand sizes distinguished in the encoding.
4194 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
4195 SDPatternOperator OpNode> {
4196 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4198 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4199 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4201 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4202 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4204 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4205 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4207 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4208 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4210 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4211 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4213 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4214 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b11, opc, V128,
4216 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4219 // As above, but D sized elements unsupported.
4220 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
4221 SDPatternOperator OpNode> {
4222 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4224 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
4225 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4227 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
4228 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4230 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
4231 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4233 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
4234 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4236 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
4237 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4239 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
4242 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
4243 SDPatternOperator OpNode> {
4244 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b00, opc, V64,
4246 [(set (v8i8 V64:$dst),
4247 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4248 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b00, opc, V128,
4250 [(set (v16i8 V128:$dst),
4251 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4252 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b01, opc, V64,
4254 [(set (v4i16 V64:$dst),
4255 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4256 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b01, opc, V128,
4258 [(set (v8i16 V128:$dst),
4259 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4260 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b10, opc, V64,
4262 [(set (v2i32 V64:$dst),
4263 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4264 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b10, opc, V128,
4266 [(set (v4i32 V128:$dst),
4267 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4270 // As above, but only B sized elements supported.
4271 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
4272 SDPatternOperator OpNode> {
4273 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4275 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4276 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4278 [(set (v16i8 V128:$Rd),
4279 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4282 // As above, but only S and D sized floating point elements supported.
4283 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<5> opc,
4284 string asm, SDPatternOperator OpNode> {
4285 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
4287 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4288 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
4290 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4291 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
4293 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4296 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<5> opc,
4298 SDPatternOperator OpNode> {
4299 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
4301 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4302 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
4304 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4305 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
4307 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4310 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<5> opc,
4311 string asm, SDPatternOperator OpNode> {
4312 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0}, opc, V64,
4314 [(set (v2f32 V64:$dst),
4315 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4316 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0}, opc, V128,
4318 [(set (v4f32 V128:$dst),
4319 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4320 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,1}, opc, V128,
4322 [(set (v2f64 V128:$dst),
4323 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4326 // As above, but D and B sized elements unsupported.
4327 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
4328 SDPatternOperator OpNode> {
4329 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4331 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4332 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4334 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4335 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4337 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4338 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4340 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4343 // Logical three vector ops share opcode bits, and only use B sized elements.
4344 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
4345 SDPatternOperator OpNode = null_frag> {
4346 def v8i8 : BaseSIMDThreeSameVector<0, U, size, 0b00011, V64,
4348 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
4349 def v16i8 : BaseSIMDThreeSameVector<1, U, size, 0b00011, V128,
4351 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
4353 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
4354 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4355 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
4356 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4357 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
4358 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4360 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
4361 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4362 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
4363 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4364 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
4365 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4368 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
4369 string asm, SDPatternOperator OpNode> {
4370 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, size, 0b00011, V64,
4372 [(set (v8i8 V64:$dst),
4373 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4374 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, size, 0b00011, V128,
4376 [(set (v16i8 V128:$dst),
4377 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
4378 (v16i8 V128:$Rm)))]>;
4380 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
4382 (!cast<Instruction>(NAME#"v8i8")
4383 V64:$LHS, V64:$MHS, V64:$RHS)>;
4384 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
4386 (!cast<Instruction>(NAME#"v8i8")
4387 V64:$LHS, V64:$MHS, V64:$RHS)>;
4388 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
4390 (!cast<Instruction>(NAME#"v8i8")
4391 V64:$LHS, V64:$MHS, V64:$RHS)>;
4393 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
4394 (v8i16 V128:$RHS))),
4395 (!cast<Instruction>(NAME#"v16i8")
4396 V128:$LHS, V128:$MHS, V128:$RHS)>;
4397 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
4398 (v4i32 V128:$RHS))),
4399 (!cast<Instruction>(NAME#"v16i8")
4400 V128:$LHS, V128:$MHS, V128:$RHS)>;
4401 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
4402 (v2i64 V128:$RHS))),
4403 (!cast<Instruction>(NAME#"v16i8")
4404 V128:$LHS, V128:$MHS, V128:$RHS)>;
4408 //----------------------------------------------------------------------------
4409 // AdvSIMD two register vector instructions.
4410 //----------------------------------------------------------------------------
4412 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4413 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4414 RegisterOperand regtype, string asm, string dstkind,
4415 string srckind, list<dag> pattern>
4416 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4417 "{\t$Rd" # dstkind # ", $Rn" # srckind #
4418 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
4425 let Inst{28-24} = 0b01110;
4426 let Inst{23-22} = size;
4427 let Inst{21-17} = 0b10000;
4428 let Inst{16-12} = opcode;
4429 let Inst{11-10} = 0b10;
4434 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4435 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4436 RegisterOperand regtype, string asm, string dstkind,
4437 string srckind, list<dag> pattern>
4438 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
4439 "{\t$Rd" # dstkind # ", $Rn" # srckind #
4440 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4447 let Inst{28-24} = 0b01110;
4448 let Inst{23-22} = size;
4449 let Inst{21-17} = 0b10000;
4450 let Inst{16-12} = opcode;
4451 let Inst{11-10} = 0b10;
4456 // Supports B, H, and S element sizes.
4457 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
4458 SDPatternOperator OpNode> {
4459 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4461 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4462 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4463 asm, ".16b", ".16b",
4464 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4465 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4467 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4468 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4470 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4471 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4473 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4474 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4476 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4479 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
4480 RegisterOperand regtype, string asm, string dstkind,
4481 string srckind, string amount>
4482 : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
4483 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
4484 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,
4490 let Inst{29-24} = 0b101110;
4491 let Inst{23-22} = size;
4492 let Inst{21-10} = 0b100001001110;
4497 multiclass SIMDVectorLShiftLongBySizeBHS {
4498 let hasSideEffects = 0 in {
4499 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
4500 "shll", ".8h", ".8b", "8">;
4501 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
4502 "shll2", ".8h", ".16b", "8">;
4503 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
4504 "shll", ".4s", ".4h", "16">;
4505 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
4506 "shll2", ".4s", ".8h", "16">;
4507 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
4508 "shll", ".2d", ".2s", "32">;
4509 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
4510 "shll2", ".2d", ".4s", "32">;
4514 // Supports all element sizes.
4515 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
4516 SDPatternOperator OpNode> {
4517 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4519 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4520 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4522 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4523 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4525 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4526 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4528 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4529 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4531 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4532 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4534 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4537 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
4538 SDPatternOperator OpNode> {
4539 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4541 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
4543 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4545 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
4546 (v16i8 V128:$Rn)))]>;
4547 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4549 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
4550 (v4i16 V64:$Rn)))]>;
4551 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4553 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
4554 (v8i16 V128:$Rn)))]>;
4555 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4557 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
4558 (v2i32 V64:$Rn)))]>;
4559 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4561 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
4562 (v4i32 V128:$Rn)))]>;
4565 // Supports all element sizes, except 1xD.
4566 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
4567 SDPatternOperator OpNode> {
4568 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4570 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
4571 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4572 asm, ".16b", ".16b",
4573 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
4574 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4576 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
4577 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4579 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
4580 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4582 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
4583 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4585 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
4586 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, V128,
4588 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
4591 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
4592 SDPatternOperator OpNode = null_frag> {
4593 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4595 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4596 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4597 asm, ".16b", ".16b",
4598 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4599 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4601 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4602 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4604 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4605 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4607 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4608 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4610 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4611 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, V128,
4613 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4617 // Supports only B element sizes.
4618 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
4619 SDPatternOperator OpNode> {
4620 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, V64,
4622 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4623 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, V128,
4624 asm, ".16b", ".16b",
4625 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4629 // Supports only B and H element sizes.
4630 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
4631 SDPatternOperator OpNode> {
4632 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4634 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
4635 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4636 asm, ".16b", ".16b",
4637 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
4638 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4640 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
4641 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4643 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
4646 // Supports only S and D element sizes, uses high bit of the size field
4647 // as an extra opcode bit.
4648 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
4649 SDPatternOperator OpNode> {
4650 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4652 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4653 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4655 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4656 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4658 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4661 // Supports only S element size.
4662 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
4663 SDPatternOperator OpNode> {
4664 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4666 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4667 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4669 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4673 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
4674 SDPatternOperator OpNode> {
4675 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4677 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4678 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4680 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4681 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4683 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4686 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
4687 SDPatternOperator OpNode> {
4688 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4690 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4691 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4693 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4694 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4696 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4700 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4701 RegisterOperand inreg, RegisterOperand outreg,
4702 string asm, string outkind, string inkind,
4704 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
4705 "{\t$Rd" # outkind # ", $Rn" # inkind #
4706 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
4713 let Inst{28-24} = 0b01110;
4714 let Inst{23-22} = size;
4715 let Inst{21-17} = 0b10000;
4716 let Inst{16-12} = opcode;
4717 let Inst{11-10} = 0b10;
4722 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4723 RegisterOperand inreg, RegisterOperand outreg,
4724 string asm, string outkind, string inkind,
4726 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
4727 "{\t$Rd" # outkind # ", $Rn" # inkind #
4728 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4735 let Inst{28-24} = 0b01110;
4736 let Inst{23-22} = size;
4737 let Inst{21-17} = 0b10000;
4738 let Inst{16-12} = opcode;
4739 let Inst{11-10} = 0b10;
4744 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
4745 SDPatternOperator OpNode> {
4746 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
4748 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4749 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
4750 asm#"2", ".16b", ".8h", []>;
4751 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
4753 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4754 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
4755 asm#"2", ".8h", ".4s", []>;
4756 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
4758 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4759 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
4760 asm#"2", ".4s", ".2d", []>;
4762 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
4763 (!cast<Instruction>(NAME # "v16i8")
4764 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4765 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
4766 (!cast<Instruction>(NAME # "v8i16")
4767 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4768 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
4769 (!cast<Instruction>(NAME # "v4i32")
4770 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4773 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4774 RegisterOperand regtype,
4775 string asm, string kind, string zero,
4776 ValueType dty, ValueType sty, SDNode OpNode>
4777 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4778 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
4779 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
4780 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
4787 let Inst{28-24} = 0b01110;
4788 let Inst{23-22} = size;
4789 let Inst{21-17} = 0b10000;
4790 let Inst{16-12} = opcode;
4791 let Inst{11-10} = 0b10;
4796 // Comparisons support all element sizes, except 1xD.
4797 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
4799 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, opc, V64,
4801 v8i8, v8i8, OpNode>;
4802 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, opc, V128,
4804 v16i8, v16i8, OpNode>;
4805 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, opc, V64,
4807 v4i16, v4i16, OpNode>;
4808 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, opc, V128,
4810 v8i16, v8i16, OpNode>;
4811 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, opc, V64,
4813 v2i32, v2i32, OpNode>;
4814 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, opc, V128,
4816 v4i32, v4i32, OpNode>;
4817 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, opc, V128,
4819 v2i64, v2i64, OpNode>;
4822 // FP Comparisons support only S and D element sizes.
4823 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
4824 string asm, SDNode OpNode> {
4826 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, opc, V64,
4828 v2i32, v2f32, OpNode>;
4829 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, opc, V128,
4831 v4i32, v4f32, OpNode>;
4832 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, opc, V128,
4834 v2i64, v2f64, OpNode>;
4836 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
4837 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
4838 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
4839 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
4840 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
4841 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
4842 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
4843 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
4844 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
4845 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
4846 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
4847 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
4850 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4851 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4852 RegisterOperand outtype, RegisterOperand intype,
4853 string asm, string VdTy, string VnTy,
4855 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
4856 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
4863 let Inst{28-24} = 0b01110;
4864 let Inst{23-22} = size;
4865 let Inst{21-17} = 0b10000;
4866 let Inst{16-12} = opcode;
4867 let Inst{11-10} = 0b10;
4872 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4873 RegisterOperand outtype, RegisterOperand intype,
4874 string asm, string VdTy, string VnTy,
4876 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
4877 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
4884 let Inst{28-24} = 0b01110;
4885 let Inst{23-22} = size;
4886 let Inst{21-17} = 0b10000;
4887 let Inst{16-12} = opcode;
4888 let Inst{11-10} = 0b10;
4893 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
4894 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
4895 asm, ".4s", ".4h", []>;
4896 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
4897 asm#"2", ".4s", ".8h", []>;
4898 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
4899 asm, ".2d", ".2s", []>;
4900 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
4901 asm#"2", ".2d", ".4s", []>;
4904 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
4905 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
4906 asm, ".4h", ".4s", []>;
4907 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
4908 asm#"2", ".8h", ".4s", []>;
4909 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4910 asm, ".2s", ".2d", []>;
4911 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4912 asm#"2", ".4s", ".2d", []>;
4915 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
4917 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4919 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4920 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4921 asm#"2", ".4s", ".2d", []>;
4923 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
4924 (!cast<Instruction>(NAME # "v4f32")
4925 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4928 //----------------------------------------------------------------------------
4929 // AdvSIMD three register different-size vector instructions.
4930 //----------------------------------------------------------------------------
4932 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4933 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
4934 RegisterOperand outtype, RegisterOperand intype1,
4935 RegisterOperand intype2, string asm,
4936 string outkind, string inkind1, string inkind2,
4938 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
4939 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4940 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
4946 let Inst{30} = size{0};
4948 let Inst{28-24} = 0b01110;
4949 let Inst{23-22} = size{2-1};
4951 let Inst{20-16} = Rm;
4952 let Inst{15-12} = opcode;
4953 let Inst{11-10} = 0b00;
4958 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4959 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
4960 RegisterOperand outtype, RegisterOperand intype1,
4961 RegisterOperand intype2, string asm,
4962 string outkind, string inkind1, string inkind2,
4964 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
4965 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4966 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4972 let Inst{30} = size{0};
4974 let Inst{28-24} = 0b01110;
4975 let Inst{23-22} = size{2-1};
4977 let Inst{20-16} = Rm;
4978 let Inst{15-12} = opcode;
4979 let Inst{11-10} = 0b00;
4984 // FIXME: TableGen doesn't know how to deal with expanded types that also
4985 // change the element count (in this case, placing the results in
4986 // the high elements of the result register rather than the low
4987 // elements). Until that's fixed, we can't code-gen those.
4988 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
4990 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4992 asm, ".8b", ".8h", ".8h",
4993 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4994 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
4996 asm#"2", ".16b", ".8h", ".8h",
4998 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5000 asm, ".4h", ".4s", ".4s",
5001 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
5002 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5004 asm#"2", ".8h", ".4s", ".4s",
5006 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5008 asm, ".2s", ".2d", ".2d",
5009 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
5010 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5012 asm#"2", ".4s", ".2d", ".2d",
5016 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
5017 // a version attached to an instruction.
5018 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
5020 (!cast<Instruction>(NAME # "v8i16_v16i8")
5021 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5022 V128:$Rn, V128:$Rm)>;
5023 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
5025 (!cast<Instruction>(NAME # "v4i32_v8i16")
5026 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5027 V128:$Rn, V128:$Rm)>;
5028 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
5030 (!cast<Instruction>(NAME # "v2i64_v4i32")
5031 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
5032 V128:$Rn, V128:$Rm)>;
5035 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
5037 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5039 asm, ".8h", ".8b", ".8b",
5040 [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5041 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5043 asm#"2", ".8h", ".16b", ".16b", []>;
5044 let Predicates = [HasCrypto] in {
5045 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,
5047 asm, ".1q", ".1d", ".1d", []>;
5048 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,
5050 asm#"2", ".1q", ".2d", ".2d", []>;
5053 def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
5054 (v8i8 (extract_high_v16i8 V128:$Rm)))),
5055 (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
5058 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
5059 SDPatternOperator OpNode> {
5060 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5062 asm, ".4s", ".4h", ".4h",
5063 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5064 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5066 asm#"2", ".4s", ".8h", ".8h",
5067 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5068 (extract_high_v8i16 V128:$Rm)))]>;
5069 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5071 asm, ".2d", ".2s", ".2s",
5072 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5073 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5075 asm#"2", ".2d", ".4s", ".4s",
5076 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5077 (extract_high_v4i32 V128:$Rm)))]>;
5080 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
5081 SDPatternOperator OpNode = null_frag> {
5082 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5084 asm, ".8h", ".8b", ".8b",
5085 [(set (v8i16 V128:$Rd),
5086 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
5087 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5089 asm#"2", ".8h", ".16b", ".16b",
5090 [(set (v8i16 V128:$Rd),
5091 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5092 (extract_high_v16i8 V128:$Rm)))))]>;
5093 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5095 asm, ".4s", ".4h", ".4h",
5096 [(set (v4i32 V128:$Rd),
5097 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
5098 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5100 asm#"2", ".4s", ".8h", ".8h",
5101 [(set (v4i32 V128:$Rd),
5102 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5103 (extract_high_v8i16 V128:$Rm)))))]>;
5104 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5106 asm, ".2d", ".2s", ".2s",
5107 [(set (v2i64 V128:$Rd),
5108 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
5109 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5111 asm#"2", ".2d", ".4s", ".4s",
5112 [(set (v2i64 V128:$Rd),
5113 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5114 (extract_high_v4i32 V128:$Rm)))))]>;
5117 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
5119 SDPatternOperator OpNode> {
5120 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5122 asm, ".8h", ".8b", ".8b",
5123 [(set (v8i16 V128:$dst),
5124 (add (v8i16 V128:$Rd),
5125 (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
5126 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5128 asm#"2", ".8h", ".16b", ".16b",
5129 [(set (v8i16 V128:$dst),
5130 (add (v8i16 V128:$Rd),
5131 (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5132 (extract_high_v16i8 V128:$Rm))))))]>;
5133 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5135 asm, ".4s", ".4h", ".4h",
5136 [(set (v4i32 V128:$dst),
5137 (add (v4i32 V128:$Rd),
5138 (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
5139 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5141 asm#"2", ".4s", ".8h", ".8h",
5142 [(set (v4i32 V128:$dst),
5143 (add (v4i32 V128:$Rd),
5144 (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5145 (extract_high_v8i16 V128:$Rm))))))]>;
5146 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5148 asm, ".2d", ".2s", ".2s",
5149 [(set (v2i64 V128:$dst),
5150 (add (v2i64 V128:$Rd),
5151 (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
5152 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5154 asm#"2", ".2d", ".4s", ".4s",
5155 [(set (v2i64 V128:$dst),
5156 (add (v2i64 V128:$Rd),
5157 (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5158 (extract_high_v4i32 V128:$Rm))))))]>;
5161 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
5162 SDPatternOperator OpNode = null_frag> {
5163 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5165 asm, ".8h", ".8b", ".8b",
5166 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5167 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5169 asm#"2", ".8h", ".16b", ".16b",
5170 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
5171 (extract_high_v16i8 V128:$Rm)))]>;
5172 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5174 asm, ".4s", ".4h", ".4h",
5175 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5176 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5178 asm#"2", ".4s", ".8h", ".8h",
5179 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5180 (extract_high_v8i16 V128:$Rm)))]>;
5181 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5183 asm, ".2d", ".2s", ".2s",
5184 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5185 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5187 asm#"2", ".2d", ".4s", ".4s",
5188 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5189 (extract_high_v4i32 V128:$Rm)))]>;
5192 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
5194 SDPatternOperator OpNode> {
5195 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5197 asm, ".8h", ".8b", ".8b",
5198 [(set (v8i16 V128:$dst),
5199 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5200 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5202 asm#"2", ".8h", ".16b", ".16b",
5203 [(set (v8i16 V128:$dst),
5204 (OpNode (v8i16 V128:$Rd),
5205 (extract_high_v16i8 V128:$Rn),
5206 (extract_high_v16i8 V128:$Rm)))]>;
5207 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5209 asm, ".4s", ".4h", ".4h",
5210 [(set (v4i32 V128:$dst),
5211 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5212 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5214 asm#"2", ".4s", ".8h", ".8h",
5215 [(set (v4i32 V128:$dst),
5216 (OpNode (v4i32 V128:$Rd),
5217 (extract_high_v8i16 V128:$Rn),
5218 (extract_high_v8i16 V128:$Rm)))]>;
5219 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5221 asm, ".2d", ".2s", ".2s",
5222 [(set (v2i64 V128:$dst),
5223 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5224 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5226 asm#"2", ".2d", ".4s", ".4s",
5227 [(set (v2i64 V128:$dst),
5228 (OpNode (v2i64 V128:$Rd),
5229 (extract_high_v4i32 V128:$Rn),
5230 (extract_high_v4i32 V128:$Rm)))]>;
5233 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
5234 SDPatternOperator Accum> {
5235 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5237 asm, ".4s", ".4h", ".4h",
5238 [(set (v4i32 V128:$dst),
5239 (Accum (v4i32 V128:$Rd),
5240 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
5241 (v4i16 V64:$Rm)))))]>;
5242 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5244 asm#"2", ".4s", ".8h", ".8h",
5245 [(set (v4i32 V128:$dst),
5246 (Accum (v4i32 V128:$Rd),
5247 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
5248 (extract_high_v8i16 V128:$Rm)))))]>;
5249 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5251 asm, ".2d", ".2s", ".2s",
5252 [(set (v2i64 V128:$dst),
5253 (Accum (v2i64 V128:$Rd),
5254 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
5255 (v2i32 V64:$Rm)))))]>;
5256 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5258 asm#"2", ".2d", ".4s", ".4s",
5259 [(set (v2i64 V128:$dst),
5260 (Accum (v2i64 V128:$Rd),
5261 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
5262 (extract_high_v4i32 V128:$Rm)))))]>;
5265 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
5266 SDPatternOperator OpNode> {
5267 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5269 asm, ".8h", ".8h", ".8b",
5270 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
5271 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5273 asm#"2", ".8h", ".8h", ".16b",
5274 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
5275 (extract_high_v16i8 V128:$Rm)))]>;
5276 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5278 asm, ".4s", ".4s", ".4h",
5279 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
5280 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5282 asm#"2", ".4s", ".4s", ".8h",
5283 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
5284 (extract_high_v8i16 V128:$Rm)))]>;
5285 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5287 asm, ".2d", ".2d", ".2s",
5288 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
5289 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5291 asm#"2", ".2d", ".2d", ".4s",
5292 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
5293 (extract_high_v4i32 V128:$Rm)))]>;
5296 //----------------------------------------------------------------------------
5297 // AdvSIMD bitwise extract from vector
5298 //----------------------------------------------------------------------------
5300 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
5301 string asm, string kind>
5302 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
5303 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
5304 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
5305 [(set (vty regtype:$Rd),
5306 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
5313 let Inst{30} = size;
5314 let Inst{29-21} = 0b101110000;
5315 let Inst{20-16} = Rm;
5317 let Inst{14-11} = imm;
5324 multiclass SIMDBitwiseExtract<string asm> {
5325 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
5328 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
5331 //----------------------------------------------------------------------------
5332 // AdvSIMD zip vector
5333 //----------------------------------------------------------------------------
5335 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
5336 string asm, string kind, SDNode OpNode, ValueType valty>
5337 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5338 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5339 "|" # kind # "\t$Rd, $Rn, $Rm}", "",
5340 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
5346 let Inst{30} = size{0};
5347 let Inst{29-24} = 0b001110;
5348 let Inst{23-22} = size{2-1};
5350 let Inst{20-16} = Rm;
5352 let Inst{14-12} = opc;
5353 let Inst{11-10} = 0b10;
5358 multiclass SIMDZipVector<bits<3>opc, string asm,
5360 def v8i8 : BaseSIMDZipVector<0b000, opc, V64,
5361 asm, ".8b", OpNode, v8i8>;
5362 def v16i8 : BaseSIMDZipVector<0b001, opc, V128,
5363 asm, ".16b", OpNode, v16i8>;
5364 def v4i16 : BaseSIMDZipVector<0b010, opc, V64,
5365 asm, ".4h", OpNode, v4i16>;
5366 def v8i16 : BaseSIMDZipVector<0b011, opc, V128,
5367 asm, ".8h", OpNode, v8i16>;
5368 def v2i32 : BaseSIMDZipVector<0b100, opc, V64,
5369 asm, ".2s", OpNode, v2i32>;
5370 def v4i32 : BaseSIMDZipVector<0b101, opc, V128,
5371 asm, ".4s", OpNode, v4i32>;
5372 def v2i64 : BaseSIMDZipVector<0b111, opc, V128,
5373 asm, ".2d", OpNode, v2i64>;
5375 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
5376 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
5377 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
5378 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
5379 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
5380 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
5381 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
5382 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
5383 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
5384 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
5387 //----------------------------------------------------------------------------
5388 // AdvSIMD three register scalar instructions
5389 //----------------------------------------------------------------------------
5391 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5392 class BaseSIMDThreeScalar<bit U, bits<2> size, bits<5> opcode,
5393 RegisterClass regtype, string asm,
5395 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5396 "\t$Rd, $Rn, $Rm", "", pattern>,
5401 let Inst{31-30} = 0b01;
5403 let Inst{28-24} = 0b11110;
5404 let Inst{23-22} = size;
5406 let Inst{20-16} = Rm;
5407 let Inst{15-11} = opcode;
5413 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5414 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
5415 dag oops, dag iops, string asm,
5417 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
5422 let Inst{31-30} = 0b01;
5424 let Inst{28-24} = 0b11110;
5425 let Inst{23-22} = size;
5427 let Inst{20-16} = Rm;
5428 let Inst{15-11} = opcode;
5434 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
5435 SDPatternOperator OpNode> {
5436 def v1i64 : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
5437 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5440 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
5441 SDPatternOperator OpNode> {
5442 def v1i64 : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
5443 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5444 def v1i32 : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm, []>;
5445 def v1i16 : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
5446 def v1i8 : BaseSIMDThreeScalar<U, 0b00, opc, FPR8 , asm, []>;
5448 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
5449 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
5450 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
5451 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
5454 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
5455 SDPatternOperator OpNode> {
5456 def v1i32 : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm,
5457 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5458 def v1i16 : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
5461 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
5462 SDPatternOperator OpNode = null_frag> {
5463 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
5464 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),
5466 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
5467 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),
5471 multiclass SIMDThreeScalarSD<bit U, bit S, bits<5> opc, string asm,
5472 SDPatternOperator OpNode = null_frag> {
5473 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5474 def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
5475 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5476 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
5477 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5480 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5481 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5484 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<5> opc, string asm,
5485 SDPatternOperator OpNode = null_frag> {
5486 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5487 def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
5488 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5489 def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
5490 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
5493 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5494 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5497 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
5498 dag oops, dag iops, string asm, string cstr, list<dag> pat>
5499 : I<oops, iops, asm,
5500 "\t$Rd, $Rn, $Rm", cstr, pat>,
5505 let Inst{31-30} = 0b01;
5507 let Inst{28-24} = 0b11110;
5508 let Inst{23-22} = size;
5510 let Inst{20-16} = Rm;
5511 let Inst{15-11} = opcode;
5517 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5518 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
5519 SDPatternOperator OpNode = null_frag> {
5520 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5522 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
5523 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5525 (ins FPR32:$Rn, FPR32:$Rm), asm, "",
5526 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5529 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5530 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
5531 SDPatternOperator OpNode = null_frag> {
5532 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5534 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
5535 asm, "$Rd = $dst", []>;
5536 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5538 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
5540 [(set (i64 FPR64:$dst),
5541 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5544 //----------------------------------------------------------------------------
5545 // AdvSIMD two register scalar instructions
5546 //----------------------------------------------------------------------------
5548 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5549 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<5> opcode,
5550 RegisterClass regtype, RegisterClass regtype2,
5551 string asm, list<dag> pat>
5552 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
5553 "\t$Rd, $Rn", "", pat>,
5557 let Inst{31-30} = 0b01;
5559 let Inst{28-24} = 0b11110;
5560 let Inst{23-22} = size;
5561 let Inst{21-17} = 0b10000;
5562 let Inst{16-12} = opcode;
5563 let Inst{11-10} = 0b10;
5568 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5569 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
5570 RegisterClass regtype, RegisterClass regtype2,
5571 string asm, list<dag> pat>
5572 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
5573 "\t$Rd, $Rn", "$Rd = $dst", pat>,
5577 let Inst{31-30} = 0b01;
5579 let Inst{28-24} = 0b11110;
5580 let Inst{23-22} = size;
5581 let Inst{21-17} = 0b10000;
5582 let Inst{16-12} = opcode;
5583 let Inst{11-10} = 0b10;
5589 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5590 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<5> opcode,
5591 RegisterClass regtype, string asm, string zero>
5592 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5593 "\t$Rd, $Rn, #" # zero, "", []>,
5597 let Inst{31-30} = 0b01;
5599 let Inst{28-24} = 0b11110;
5600 let Inst{23-22} = size;
5601 let Inst{21-17} = 0b10000;
5602 let Inst{16-12} = opcode;
5603 let Inst{11-10} = 0b10;
5608 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
5609 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
5610 [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
5614 let Inst{31-17} = 0b011111100110000;
5615 let Inst{16-12} = opcode;
5616 let Inst{11-10} = 0b10;
5621 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
5622 SDPatternOperator OpNode> {
5623 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, opc, FPR64, asm, "0">;
5625 def : Pat<(v1i64 (OpNode FPR64:$Rn)),
5626 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5629 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
5630 SDPatternOperator OpNode> {
5631 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, opc, FPR64, asm, "0.0">;
5632 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, opc, FPR32, asm, "0.0">;
5634 def : InstAlias<asm # "\t$Rd, $Rn, #0",
5635 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
5636 def : InstAlias<asm # "\t$Rd, $Rn, #0",
5637 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
5639 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
5640 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5643 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
5644 SDPatternOperator OpNode = null_frag> {
5645 def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5646 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
5648 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
5649 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
5652 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
5653 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,[]>;
5654 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,[]>;
5657 multiclass SIMDTwoScalarCVTSD<bit U, bit S, bits<5> opc, string asm,
5658 SDPatternOperator OpNode> {
5659 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,
5660 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
5661 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,
5662 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
5665 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
5666 SDPatternOperator OpNode = null_frag> {
5667 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5668 def v1i64 : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5669 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5670 def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR32, asm,
5671 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
5672 def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR16, asm, []>;
5673 def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5676 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
5677 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
5680 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
5682 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5683 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
5684 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
5685 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
5686 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
5687 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
5688 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5691 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
5692 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
5697 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5698 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
5699 SDPatternOperator OpNode = null_frag> {
5700 def v1i32 : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR64, asm,
5701 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5702 def v1i16 : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR32, asm, []>;
5703 def v1i8 : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR16, asm, []>;
5706 //----------------------------------------------------------------------------
5707 // AdvSIMD scalar pairwise instructions
5708 //----------------------------------------------------------------------------
5710 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5711 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
5712 RegisterOperand regtype, RegisterOperand vectype,
5713 string asm, string kind>
5714 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5715 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
5719 let Inst{31-30} = 0b01;
5721 let Inst{28-24} = 0b11110;
5722 let Inst{23-22} = size;
5723 let Inst{21-17} = 0b11000;
5724 let Inst{16-12} = opcode;
5725 let Inst{11-10} = 0b10;
5730 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
5731 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
5735 multiclass SIMDFPPairwiseScalar<bit U, bit S, bits<5> opc, string asm> {
5736 def v2i32p : BaseSIMDPairwiseScalar<U, {S,0}, opc, FPR32Op, V64,
5738 def v2i64p : BaseSIMDPairwiseScalar<U, {S,1}, opc, FPR64Op, V128,
5742 //----------------------------------------------------------------------------
5743 // AdvSIMD across lanes instructions
5744 //----------------------------------------------------------------------------
5746 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5747 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
5748 RegisterClass regtype, RegisterOperand vectype,
5749 string asm, string kind, list<dag> pattern>
5750 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5751 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
5758 let Inst{28-24} = 0b01110;
5759 let Inst{23-22} = size;
5760 let Inst{21-17} = 0b11000;
5761 let Inst{16-12} = opcode;
5762 let Inst{11-10} = 0b10;
5767 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
5769 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,
5771 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,
5773 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
5775 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
5777 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
5781 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
5782 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
5784 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
5786 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
5788 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
5790 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
5794 multiclass SIMDAcrossLanesS<bits<5> opcode, bit sz1, string asm,
5796 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
5798 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
5801 //----------------------------------------------------------------------------
5802 // AdvSIMD INS/DUP instructions
5803 //----------------------------------------------------------------------------
5805 // FIXME: There has got to be a better way to factor these. ugh.
5807 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
5808 string operands, string constraints, list<dag> pattern>
5809 : I<outs, ins, asm, operands, constraints, pattern>,
5816 let Inst{28-21} = 0b01110000;
5823 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
5824 RegisterOperand vecreg, RegisterClass regtype>
5825 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
5826 "{\t$Rd" # size # ", $Rn" #
5827 "|" # size # "\t$Rd, $Rn}", "",
5828 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
5829 let Inst{20-16} = imm5;
5830 let Inst{14-11} = 0b0001;
5833 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
5834 ValueType vectype, ValueType insreg,
5835 RegisterOperand vecreg, Operand idxtype,
5836 ValueType elttype, SDNode OpNode>
5837 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
5838 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
5839 "|" # dstkind # "\t$Rd, $Rn$idx}", "",
5840 [(set (vectype vecreg:$Rd),
5841 (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
5842 let Inst{14-11} = 0b0000;
5845 class SIMDDup64FromElement
5846 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
5847 VectorIndexD, i64, AArch64duplane64> {
5850 let Inst{19-16} = 0b1000;
5853 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
5854 RegisterOperand vecreg>
5855 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
5856 VectorIndexS, i64, AArch64duplane32> {
5858 let Inst{20-19} = idx;
5859 let Inst{18-16} = 0b100;
5862 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
5863 RegisterOperand vecreg>
5864 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
5865 VectorIndexH, i64, AArch64duplane16> {
5867 let Inst{20-18} = idx;
5868 let Inst{17-16} = 0b10;
5871 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
5872 RegisterOperand vecreg>
5873 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
5874 VectorIndexB, i64, AArch64duplane8> {
5876 let Inst{20-17} = idx;
5880 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
5881 Operand idxtype, string asm, list<dag> pattern>
5882 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
5883 "{\t$Rd, $Rn" # size # "$idx" #
5884 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
5885 let Inst{14-11} = imm4;
5888 class SIMDSMov<bit Q, string size, RegisterClass regtype,
5890 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
5891 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
5893 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
5894 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
5896 class SIMDMovAlias<string asm, string size, Instruction inst,
5897 RegisterClass regtype, Operand idxtype>
5898 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
5899 "|" # size # "\t$dst, $src$idx}",
5900 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
5903 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
5905 let Inst{20-17} = idx;
5908 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
5910 let Inst{20-17} = idx;
5913 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
5915 let Inst{20-18} = idx;
5916 let Inst{17-16} = 0b10;
5918 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
5920 let Inst{20-18} = idx;
5921 let Inst{17-16} = 0b10;
5923 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
5925 let Inst{20-19} = idx;
5926 let Inst{18-16} = 0b100;
5931 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
5933 let Inst{20-17} = idx;
5936 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
5938 let Inst{20-18} = idx;
5939 let Inst{17-16} = 0b10;
5941 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
5943 let Inst{20-19} = idx;
5944 let Inst{18-16} = 0b100;
5946 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
5949 let Inst{19-16} = 0b1000;
5951 def : SIMDMovAlias<"mov", ".s",
5952 !cast<Instruction>(NAME#"vi32"),
5953 GPR32, VectorIndexS>;
5954 def : SIMDMovAlias<"mov", ".d",
5955 !cast<Instruction>(NAME#"vi64"),
5956 GPR64, VectorIndexD>;
5959 class SIMDInsFromMain<string size, ValueType vectype,
5960 RegisterClass regtype, Operand idxtype>
5961 : BaseSIMDInsDup<1, 0, (outs V128:$dst),
5962 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
5963 "{\t$Rd" # size # "$idx, $Rn" #
5964 "|" # size # "\t$Rd$idx, $Rn}",
5967 (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
5968 let Inst{14-11} = 0b0011;
5971 class SIMDInsFromElement<string size, ValueType vectype,
5972 ValueType elttype, Operand idxtype>
5973 : BaseSIMDInsDup<1, 1, (outs V128:$dst),
5974 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
5975 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
5976 "|" # size # "\t$Rd$idx, $Rn$idx2}",
5981 (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
5984 class SIMDInsMainMovAlias<string size, Instruction inst,
5985 RegisterClass regtype, Operand idxtype>
5986 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
5987 "|" # size #"\t$dst$idx, $src}",
5988 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
5989 class SIMDInsElementMovAlias<string size, Instruction inst,
5991 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
5992 # "|" # size #"\t$dst$idx, $src$idx2}",
5993 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
5996 multiclass SIMDIns {
5997 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
5999 let Inst{20-17} = idx;
6002 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
6004 let Inst{20-18} = idx;
6005 let Inst{17-16} = 0b10;
6007 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
6009 let Inst{20-19} = idx;
6010 let Inst{18-16} = 0b100;
6012 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
6015 let Inst{19-16} = 0b1000;
6018 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
6021 let Inst{20-17} = idx;
6023 let Inst{14-11} = idx2;
6025 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
6028 let Inst{20-18} = idx;
6029 let Inst{17-16} = 0b10;
6030 let Inst{14-12} = idx2;
6033 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
6036 let Inst{20-19} = idx;
6037 let Inst{18-16} = 0b100;
6038 let Inst{14-13} = idx2;
6039 let Inst{12-11} = {?,?};
6041 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
6045 let Inst{19-16} = 0b1000;
6046 let Inst{14} = idx2;
6047 let Inst{13-11} = {?,?,?};
6050 // For all forms of the INS instruction, the "mov" mnemonic is the
6051 // preferred alias. Why they didn't just call the instruction "mov" in
6052 // the first place is a very good question indeed...
6053 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
6054 GPR32, VectorIndexB>;
6055 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
6056 GPR32, VectorIndexH>;
6057 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
6058 GPR32, VectorIndexS>;
6059 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
6060 GPR64, VectorIndexD>;
6062 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
6064 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
6066 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
6068 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
6072 //----------------------------------------------------------------------------
6074 //----------------------------------------------------------------------------
6076 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6077 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6078 RegisterOperand listtype, string asm, string kind>
6079 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
6080 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
6087 let Inst{29-21} = 0b001110000;
6088 let Inst{20-16} = Vm;
6090 let Inst{14-13} = len;
6092 let Inst{11-10} = 0b00;
6097 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6098 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6099 RegisterOperand listtype, string asm, string kind>
6100 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
6101 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
6108 let Inst{29-21} = 0b001110000;
6109 let Inst{20-16} = Vm;
6111 let Inst{14-13} = len;
6113 let Inst{11-10} = 0b00;
6118 class SIMDTableLookupAlias<string asm, Instruction inst,
6119 RegisterOperand vectype, RegisterOperand listtype>
6120 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
6121 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
6123 multiclass SIMDTableLookup<bit op, string asm> {
6124 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
6126 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
6128 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
6130 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
6132 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
6134 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
6136 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
6138 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
6141 def : SIMDTableLookupAlias<asm # ".8b",
6142 !cast<Instruction>(NAME#"v8i8One"),
6143 V64, VecListOne128>;
6144 def : SIMDTableLookupAlias<asm # ".8b",
6145 !cast<Instruction>(NAME#"v8i8Two"),
6146 V64, VecListTwo128>;
6147 def : SIMDTableLookupAlias<asm # ".8b",
6148 !cast<Instruction>(NAME#"v8i8Three"),
6149 V64, VecListThree128>;
6150 def : SIMDTableLookupAlias<asm # ".8b",
6151 !cast<Instruction>(NAME#"v8i8Four"),
6152 V64, VecListFour128>;
6153 def : SIMDTableLookupAlias<asm # ".16b",
6154 !cast<Instruction>(NAME#"v16i8One"),
6155 V128, VecListOne128>;
6156 def : SIMDTableLookupAlias<asm # ".16b",
6157 !cast<Instruction>(NAME#"v16i8Two"),
6158 V128, VecListTwo128>;
6159 def : SIMDTableLookupAlias<asm # ".16b",
6160 !cast<Instruction>(NAME#"v16i8Three"),
6161 V128, VecListThree128>;
6162 def : SIMDTableLookupAlias<asm # ".16b",
6163 !cast<Instruction>(NAME#"v16i8Four"),
6164 V128, VecListFour128>;
6167 multiclass SIMDTableLookupTied<bit op, string asm> {
6168 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
6170 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
6172 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
6174 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
6176 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
6178 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
6180 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
6182 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
6185 def : SIMDTableLookupAlias<asm # ".8b",
6186 !cast<Instruction>(NAME#"v8i8One"),
6187 V64, VecListOne128>;
6188 def : SIMDTableLookupAlias<asm # ".8b",
6189 !cast<Instruction>(NAME#"v8i8Two"),
6190 V64, VecListTwo128>;
6191 def : SIMDTableLookupAlias<asm # ".8b",
6192 !cast<Instruction>(NAME#"v8i8Three"),
6193 V64, VecListThree128>;
6194 def : SIMDTableLookupAlias<asm # ".8b",
6195 !cast<Instruction>(NAME#"v8i8Four"),
6196 V64, VecListFour128>;
6197 def : SIMDTableLookupAlias<asm # ".16b",
6198 !cast<Instruction>(NAME#"v16i8One"),
6199 V128, VecListOne128>;
6200 def : SIMDTableLookupAlias<asm # ".16b",
6201 !cast<Instruction>(NAME#"v16i8Two"),
6202 V128, VecListTwo128>;
6203 def : SIMDTableLookupAlias<asm # ".16b",
6204 !cast<Instruction>(NAME#"v16i8Three"),
6205 V128, VecListThree128>;
6206 def : SIMDTableLookupAlias<asm # ".16b",
6207 !cast<Instruction>(NAME#"v16i8Four"),
6208 V128, VecListFour128>;
6212 //----------------------------------------------------------------------------
6213 // AdvSIMD scalar CPY
6214 //----------------------------------------------------------------------------
6215 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6216 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
6217 string kind, Operand idxtype>
6218 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
6219 "{\t$dst, $src" # kind # "$idx" #
6220 "|\t$dst, $src$idx}", "", []>,
6224 let Inst{31-21} = 0b01011110000;
6225 let Inst{15-10} = 0b000001;
6226 let Inst{9-5} = src;
6227 let Inst{4-0} = dst;
6230 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
6231 RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
6232 : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
6233 # "|\t$dst, $src$index}",
6234 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
6237 multiclass SIMDScalarCPY<string asm> {
6238 def i8 : BaseSIMDScalarCPY<FPR8, V128, ".b", VectorIndexB> {
6240 let Inst{20-17} = idx;
6243 def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
6245 let Inst{20-18} = idx;
6246 let Inst{17-16} = 0b10;
6248 def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
6250 let Inst{20-19} = idx;
6251 let Inst{18-16} = 0b100;
6253 def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
6256 let Inst{19-16} = 0b1000;
6259 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
6260 VectorIndexD:$idx)))),
6261 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
6263 // 'DUP' mnemonic aliases.
6264 def : SIMDScalarCPYAlias<"dup", ".b",
6265 !cast<Instruction>(NAME#"i8"),
6266 FPR8, V128, VectorIndexB>;
6267 def : SIMDScalarCPYAlias<"dup", ".h",
6268 !cast<Instruction>(NAME#"i16"),
6269 FPR16, V128, VectorIndexH>;
6270 def : SIMDScalarCPYAlias<"dup", ".s",
6271 !cast<Instruction>(NAME#"i32"),
6272 FPR32, V128, VectorIndexS>;
6273 def : SIMDScalarCPYAlias<"dup", ".d",
6274 !cast<Instruction>(NAME#"i64"),
6275 FPR64, V128, VectorIndexD>;
6278 //----------------------------------------------------------------------------
6279 // AdvSIMD modified immediate instructions
6280 //----------------------------------------------------------------------------
6282 class BaseSIMDModifiedImm<bit Q, bit op, dag oops, dag iops,
6283 string asm, string op_string,
6284 string cstr, list<dag> pattern>
6285 : I<oops, iops, asm, op_string, cstr, pattern>,
6292 let Inst{28-19} = 0b0111100000;
6293 let Inst{18-16} = imm8{7-5};
6294 let Inst{11-10} = 0b01;
6295 let Inst{9-5} = imm8{4-0};
6299 class BaseSIMDModifiedImmVector<bit Q, bit op, RegisterOperand vectype,
6300 Operand immtype, dag opt_shift_iop,
6301 string opt_shift, string asm, string kind,
6303 : BaseSIMDModifiedImm<Q, op, (outs vectype:$Rd),
6304 !con((ins immtype:$imm8), opt_shift_iop), asm,
6305 "{\t$Rd" # kind # ", $imm8" # opt_shift #
6306 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6308 let DecoderMethod = "DecodeModImmInstruction";
6311 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
6312 Operand immtype, dag opt_shift_iop,
6313 string opt_shift, string asm, string kind,
6315 : BaseSIMDModifiedImm<Q, op, (outs vectype:$dst),
6316 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
6317 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
6318 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6319 "$Rd = $dst", pattern> {
6320 let DecoderMethod = "DecodeModImmTiedInstruction";
6323 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
6324 RegisterOperand vectype, string asm,
6325 string kind, list<dag> pattern>
6326 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6327 (ins logical_vec_shift:$shift),
6328 "$shift", asm, kind, pattern> {
6330 let Inst{15} = b15_b12{1};
6331 let Inst{14-13} = shift;
6332 let Inst{12} = b15_b12{0};
6335 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
6336 RegisterOperand vectype, string asm,
6337 string kind, list<dag> pattern>
6338 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6339 (ins logical_vec_shift:$shift),
6340 "$shift", asm, kind, pattern> {
6342 let Inst{15} = b15_b12{1};
6343 let Inst{14-13} = shift;
6344 let Inst{12} = b15_b12{0};
6348 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
6349 RegisterOperand vectype, string asm,
6350 string kind, list<dag> pattern>
6351 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6352 (ins logical_vec_hw_shift:$shift),
6353 "$shift", asm, kind, pattern> {
6355 let Inst{15} = b15_b12{1};
6357 let Inst{13} = shift{0};
6358 let Inst{12} = b15_b12{0};
6361 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
6362 RegisterOperand vectype, string asm,
6363 string kind, list<dag> pattern>
6364 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6365 (ins logical_vec_hw_shift:$shift),
6366 "$shift", asm, kind, pattern> {
6368 let Inst{15} = b15_b12{1};
6370 let Inst{13} = shift{0};
6371 let Inst{12} = b15_b12{0};
6374 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
6376 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
6378 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
6381 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
6383 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
6387 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
6388 bits<2> w_cmode, string asm,
6390 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
6392 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
6394 (i32 imm:$shift)))]>;
6395 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
6397 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
6399 (i32 imm:$shift)))]>;
6401 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
6403 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
6405 (i32 imm:$shift)))]>;
6406 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
6408 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
6410 (i32 imm:$shift)))]>;
6413 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
6414 RegisterOperand vectype, string asm,
6415 string kind, list<dag> pattern>
6416 : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6417 (ins move_vec_shift:$shift),
6418 "$shift", asm, kind, pattern> {
6420 let Inst{15-13} = cmode{3-1};
6421 let Inst{12} = shift;
6424 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bits<4> cmode,
6425 RegisterOperand vectype,
6426 Operand imm_type, string asm,
6427 string kind, list<dag> pattern>
6428 : BaseSIMDModifiedImmVector<Q, op, vectype, imm_type, (ins), "",
6429 asm, kind, pattern> {
6430 let Inst{15-12} = cmode;
6433 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
6435 : BaseSIMDModifiedImm<Q, op, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
6436 "\t$Rd, $imm8", "", pattern> {
6437 let Inst{15-12} = cmode;
6438 let DecoderMethod = "DecodeModImmInstruction";
6441 //----------------------------------------------------------------------------
6442 // AdvSIMD indexed element
6443 //----------------------------------------------------------------------------
6445 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6446 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6447 RegisterOperand dst_reg, RegisterOperand lhs_reg,
6448 RegisterOperand rhs_reg, Operand vec_idx, string asm,
6449 string apple_kind, string dst_kind, string lhs_kind,
6450 string rhs_kind, list<dag> pattern>
6451 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
6453 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6454 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
6463 let Inst{28} = Scalar;
6464 let Inst{27-24} = 0b1111;
6465 let Inst{23-22} = size;
6466 // Bit 21 must be set by the derived class.
6467 let Inst{20-16} = Rm;
6468 let Inst{15-12} = opc;
6469 // Bit 11 must be set by the derived class.
6475 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6476 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6477 RegisterOperand dst_reg, RegisterOperand lhs_reg,
6478 RegisterOperand rhs_reg, Operand vec_idx, string asm,
6479 string apple_kind, string dst_kind, string lhs_kind,
6480 string rhs_kind, list<dag> pattern>
6481 : I<(outs dst_reg:$dst),
6482 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
6483 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6484 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
6493 let Inst{28} = Scalar;
6494 let Inst{27-24} = 0b1111;
6495 let Inst{23-22} = size;
6496 // Bit 21 must be set by the derived class.
6497 let Inst{20-16} = Rm;
6498 let Inst{15-12} = opc;
6499 // Bit 11 must be set by the derived class.
6505 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
6506 SDPatternOperator OpNode> {
6507 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6510 asm, ".2s", ".2s", ".2s", ".s",
6511 [(set (v2f32 V64:$Rd),
6512 (OpNode (v2f32 V64:$Rn),
6513 (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6515 let Inst{11} = idx{1};
6516 let Inst{21} = idx{0};
6519 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6522 asm, ".4s", ".4s", ".4s", ".s",
6523 [(set (v4f32 V128:$Rd),
6524 (OpNode (v4f32 V128:$Rn),
6525 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6527 let Inst{11} = idx{1};
6528 let Inst{21} = idx{0};
6531 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
6534 asm, ".2d", ".2d", ".2d", ".d",
6535 [(set (v2f64 V128:$Rd),
6536 (OpNode (v2f64 V128:$Rn),
6537 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
6539 let Inst{11} = idx{0};
6543 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6544 FPR32Op, FPR32Op, V128, VectorIndexS,
6545 asm, ".s", "", "", ".s",
6546 [(set (f32 FPR32Op:$Rd),
6547 (OpNode (f32 FPR32Op:$Rn),
6548 (f32 (vector_extract (v4f32 V128:$Rm),
6549 VectorIndexS:$idx))))]> {
6551 let Inst{11} = idx{1};
6552 let Inst{21} = idx{0};
6555 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
6556 FPR64Op, FPR64Op, V128, VectorIndexD,
6557 asm, ".d", "", "", ".d",
6558 [(set (f64 FPR64Op:$Rd),
6559 (OpNode (f64 FPR64Op:$Rn),
6560 (f64 (vector_extract (v2f64 V128:$Rm),
6561 VectorIndexD:$idx))))]> {
6563 let Inst{11} = idx{0};
6568 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
6569 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
6570 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6571 (AArch64duplane32 (v4f32 V128:$Rm),
6572 VectorIndexS:$idx))),
6573 (!cast<Instruction>(INST # v2i32_indexed)
6574 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6575 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6576 (AArch64dup (f32 FPR32Op:$Rm)))),
6577 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
6578 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6581 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
6582 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6583 (AArch64duplane32 (v4f32 V128:$Rm),
6584 VectorIndexS:$idx))),
6585 (!cast<Instruction>(INST # "v4i32_indexed")
6586 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6587 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6588 (AArch64dup (f32 FPR32Op:$Rm)))),
6589 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
6590 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6592 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
6593 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6594 (AArch64duplane64 (v2f64 V128:$Rm),
6595 VectorIndexD:$idx))),
6596 (!cast<Instruction>(INST # "v2i64_indexed")
6597 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6598 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6599 (AArch64dup (f64 FPR64Op:$Rm)))),
6600 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
6601 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
6603 // 2 variants for 32-bit scalar version: extract from .2s or from .4s
6604 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6605 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
6606 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6607 V128:$Rm, VectorIndexS:$idx)>;
6608 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6609 (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
6610 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6611 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
6613 // 1 variant for 64-bit scalar version: extract from .1d or from .2d
6614 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
6615 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
6616 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
6617 V128:$Rm, VectorIndexD:$idx)>;
6620 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
6621 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
6623 asm, ".2s", ".2s", ".2s", ".s", []> {
6625 let Inst{11} = idx{1};
6626 let Inst{21} = idx{0};
6629 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6632 asm, ".4s", ".4s", ".4s", ".s", []> {
6634 let Inst{11} = idx{1};
6635 let Inst{21} = idx{0};
6638 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
6641 asm, ".2d", ".2d", ".2d", ".d", []> {
6643 let Inst{11} = idx{0};
6648 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6649 FPR32Op, FPR32Op, V128, VectorIndexS,
6650 asm, ".s", "", "", ".s", []> {
6652 let Inst{11} = idx{1};
6653 let Inst{21} = idx{0};
6656 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
6657 FPR64Op, FPR64Op, V128, VectorIndexD,
6658 asm, ".d", "", "", ".d", []> {
6660 let Inst{11} = idx{0};
6665 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
6666 SDPatternOperator OpNode> {
6667 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
6668 V128_lo, VectorIndexH,
6669 asm, ".4h", ".4h", ".4h", ".h",
6670 [(set (v4i16 V64:$Rd),
6671 (OpNode (v4i16 V64:$Rn),
6672 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6674 let Inst{11} = idx{2};
6675 let Inst{21} = idx{1};
6676 let Inst{20} = idx{0};
6679 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6681 V128_lo, VectorIndexH,
6682 asm, ".8h", ".8h", ".8h", ".h",
6683 [(set (v8i16 V128:$Rd),
6684 (OpNode (v8i16 V128:$Rn),
6685 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6687 let Inst{11} = idx{2};
6688 let Inst{21} = idx{1};
6689 let Inst{20} = idx{0};
6692 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6695 asm, ".2s", ".2s", ".2s", ".s",
6696 [(set (v2i32 V64:$Rd),
6697 (OpNode (v2i32 V64:$Rn),
6698 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6700 let Inst{11} = idx{1};
6701 let Inst{21} = idx{0};
6704 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6707 asm, ".4s", ".4s", ".4s", ".s",
6708 [(set (v4i32 V128:$Rd),
6709 (OpNode (v4i32 V128:$Rn),
6710 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6712 let Inst{11} = idx{1};
6713 let Inst{21} = idx{0};
6716 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6717 FPR16Op, FPR16Op, V128_lo, VectorIndexH,
6718 asm, ".h", "", "", ".h", []> {
6720 let Inst{11} = idx{2};
6721 let Inst{21} = idx{1};
6722 let Inst{20} = idx{0};
6725 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6726 FPR32Op, FPR32Op, V128, VectorIndexS,
6727 asm, ".s", "", "", ".s",
6728 [(set (i32 FPR32Op:$Rd),
6729 (OpNode FPR32Op:$Rn,
6730 (i32 (vector_extract (v4i32 V128:$Rm),
6731 VectorIndexS:$idx))))]> {
6733 let Inst{11} = idx{1};
6734 let Inst{21} = idx{0};
6738 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
6739 SDPatternOperator OpNode> {
6740 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6742 V128_lo, VectorIndexH,
6743 asm, ".4h", ".4h", ".4h", ".h",
6744 [(set (v4i16 V64:$Rd),
6745 (OpNode (v4i16 V64:$Rn),
6746 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6748 let Inst{11} = idx{2};
6749 let Inst{21} = idx{1};
6750 let Inst{20} = idx{0};
6753 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6755 V128_lo, VectorIndexH,
6756 asm, ".8h", ".8h", ".8h", ".h",
6757 [(set (v8i16 V128:$Rd),
6758 (OpNode (v8i16 V128:$Rn),
6759 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6761 let Inst{11} = idx{2};
6762 let Inst{21} = idx{1};
6763 let Inst{20} = idx{0};
6766 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6769 asm, ".2s", ".2s", ".2s", ".s",
6770 [(set (v2i32 V64:$Rd),
6771 (OpNode (v2i32 V64:$Rn),
6772 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6774 let Inst{11} = idx{1};
6775 let Inst{21} = idx{0};
6778 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6781 asm, ".4s", ".4s", ".4s", ".s",
6782 [(set (v4i32 V128:$Rd),
6783 (OpNode (v4i32 V128:$Rn),
6784 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6786 let Inst{11} = idx{1};
6787 let Inst{21} = idx{0};
6791 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
6792 SDPatternOperator OpNode> {
6793 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
6794 V128_lo, VectorIndexH,
6795 asm, ".4h", ".4h", ".4h", ".h",
6796 [(set (v4i16 V64:$dst),
6797 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
6798 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6800 let Inst{11} = idx{2};
6801 let Inst{21} = idx{1};
6802 let Inst{20} = idx{0};
6805 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6807 V128_lo, VectorIndexH,
6808 asm, ".8h", ".8h", ".8h", ".h",
6809 [(set (v8i16 V128:$dst),
6810 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
6811 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6813 let Inst{11} = idx{2};
6814 let Inst{21} = idx{1};
6815 let Inst{20} = idx{0};
6818 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6821 asm, ".2s", ".2s", ".2s", ".s",
6822 [(set (v2i32 V64:$dst),
6823 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
6824 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6826 let Inst{11} = idx{1};
6827 let Inst{21} = idx{0};
6830 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6833 asm, ".4s", ".4s", ".4s", ".s",
6834 [(set (v4i32 V128:$dst),
6835 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
6836 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6838 let Inst{11} = idx{1};
6839 let Inst{21} = idx{0};
6843 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
6844 SDPatternOperator OpNode> {
6845 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6847 V128_lo, VectorIndexH,
6848 asm, ".4s", ".4s", ".4h", ".h",
6849 [(set (v4i32 V128:$Rd),
6850 (OpNode (v4i16 V64:$Rn),
6851 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6853 let Inst{11} = idx{2};
6854 let Inst{21} = idx{1};
6855 let Inst{20} = idx{0};
6858 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6860 V128_lo, VectorIndexH,
6861 asm#"2", ".4s", ".4s", ".8h", ".h",
6862 [(set (v4i32 V128:$Rd),
6863 (OpNode (extract_high_v8i16 V128:$Rn),
6864 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6865 VectorIndexH:$idx))))]> {
6868 let Inst{11} = idx{2};
6869 let Inst{21} = idx{1};
6870 let Inst{20} = idx{0};
6873 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6876 asm, ".2d", ".2d", ".2s", ".s",
6877 [(set (v2i64 V128:$Rd),
6878 (OpNode (v2i32 V64:$Rn),
6879 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6881 let Inst{11} = idx{1};
6882 let Inst{21} = idx{0};
6885 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6888 asm#"2", ".2d", ".2d", ".4s", ".s",
6889 [(set (v2i64 V128:$Rd),
6890 (OpNode (extract_high_v4i32 V128:$Rn),
6891 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
6892 VectorIndexS:$idx))))]> {
6894 let Inst{11} = idx{1};
6895 let Inst{21} = idx{0};
6898 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6899 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6900 asm, ".h", "", "", ".h", []> {
6902 let Inst{11} = idx{2};
6903 let Inst{21} = idx{1};
6904 let Inst{20} = idx{0};
6907 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6908 FPR64Op, FPR32Op, V128, VectorIndexS,
6909 asm, ".s", "", "", ".s", []> {
6911 let Inst{11} = idx{1};
6912 let Inst{21} = idx{0};
6916 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
6917 SDPatternOperator Accum> {
6918 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
6920 V128_lo, VectorIndexH,
6921 asm, ".4s", ".4s", ".4h", ".h",
6922 [(set (v4i32 V128:$dst),
6923 (Accum (v4i32 V128:$Rd),
6924 (v4i32 (int_aarch64_neon_sqdmull
6926 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6927 VectorIndexH:$idx))))))]> {
6929 let Inst{11} = idx{2};
6930 let Inst{21} = idx{1};
6931 let Inst{20} = idx{0};
6934 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
6935 // intermediate EXTRACT_SUBREG would be untyped.
6936 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
6937 (i32 (vector_extract (v4i32
6938 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
6939 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6940 VectorIndexH:$idx)))),
6943 (!cast<Instruction>(NAME # v4i16_indexed)
6944 (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
6945 V128_lo:$Rm, VectorIndexH:$idx),
6948 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6950 V128_lo, VectorIndexH,
6951 asm#"2", ".4s", ".4s", ".8h", ".h",
6952 [(set (v4i32 V128:$dst),
6953 (Accum (v4i32 V128:$Rd),
6954 (v4i32 (int_aarch64_neon_sqdmull
6955 (extract_high_v8i16 V128:$Rn),
6957 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6958 VectorIndexH:$idx))))))]> {
6960 let Inst{11} = idx{2};
6961 let Inst{21} = idx{1};
6962 let Inst{20} = idx{0};
6965 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6968 asm, ".2d", ".2d", ".2s", ".s",
6969 [(set (v2i64 V128:$dst),
6970 (Accum (v2i64 V128:$Rd),
6971 (v2i64 (int_aarch64_neon_sqdmull
6973 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
6974 VectorIndexS:$idx))))))]> {
6976 let Inst{11} = idx{1};
6977 let Inst{21} = idx{0};
6980 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6983 asm#"2", ".2d", ".2d", ".4s", ".s",
6984 [(set (v2i64 V128:$dst),
6985 (Accum (v2i64 V128:$Rd),
6986 (v2i64 (int_aarch64_neon_sqdmull
6987 (extract_high_v4i32 V128:$Rn),
6989 (AArch64duplane32 (v4i32 V128:$Rm),
6990 VectorIndexS:$idx))))))]> {
6992 let Inst{11} = idx{1};
6993 let Inst{21} = idx{0};
6996 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
6997 FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6998 asm, ".h", "", "", ".h", []> {
7000 let Inst{11} = idx{2};
7001 let Inst{21} = idx{1};
7002 let Inst{20} = idx{0};
7006 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
7007 FPR64Op, FPR32Op, V128, VectorIndexS,
7008 asm, ".s", "", "", ".s",
7009 [(set (i64 FPR64Op:$dst),
7010 (Accum (i64 FPR64Op:$Rd),
7011 (i64 (int_aarch64_neon_sqdmulls_scalar
7013 (i32 (vector_extract (v4i32 V128:$Rm),
7014 VectorIndexS:$idx))))))]> {
7017 let Inst{11} = idx{1};
7018 let Inst{21} = idx{0};
7022 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
7023 SDPatternOperator OpNode> {
7024 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7025 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
7027 V128_lo, VectorIndexH,
7028 asm, ".4s", ".4s", ".4h", ".h",
7029 [(set (v4i32 V128:$Rd),
7030 (OpNode (v4i16 V64:$Rn),
7031 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7033 let Inst{11} = idx{2};
7034 let Inst{21} = idx{1};
7035 let Inst{20} = idx{0};
7038 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7040 V128_lo, VectorIndexH,
7041 asm#"2", ".4s", ".4s", ".8h", ".h",
7042 [(set (v4i32 V128:$Rd),
7043 (OpNode (extract_high_v8i16 V128:$Rn),
7044 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7045 VectorIndexH:$idx))))]> {
7048 let Inst{11} = idx{2};
7049 let Inst{21} = idx{1};
7050 let Inst{20} = idx{0};
7053 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7056 asm, ".2d", ".2d", ".2s", ".s",
7057 [(set (v2i64 V128:$Rd),
7058 (OpNode (v2i32 V64:$Rn),
7059 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7061 let Inst{11} = idx{1};
7062 let Inst{21} = idx{0};
7065 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7068 asm#"2", ".2d", ".2d", ".4s", ".s",
7069 [(set (v2i64 V128:$Rd),
7070 (OpNode (extract_high_v4i32 V128:$Rn),
7071 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7072 VectorIndexS:$idx))))]> {
7074 let Inst{11} = idx{1};
7075 let Inst{21} = idx{0};
7080 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
7081 SDPatternOperator OpNode> {
7082 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7083 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7085 V128_lo, VectorIndexH,
7086 asm, ".4s", ".4s", ".4h", ".h",
7087 [(set (v4i32 V128:$dst),
7088 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
7089 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7091 let Inst{11} = idx{2};
7092 let Inst{21} = idx{1};
7093 let Inst{20} = idx{0};
7096 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7098 V128_lo, VectorIndexH,
7099 asm#"2", ".4s", ".4s", ".8h", ".h",
7100 [(set (v4i32 V128:$dst),
7101 (OpNode (v4i32 V128:$Rd),
7102 (extract_high_v8i16 V128:$Rn),
7103 (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7104 VectorIndexH:$idx))))]> {
7106 let Inst{11} = idx{2};
7107 let Inst{21} = idx{1};
7108 let Inst{20} = idx{0};
7111 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7114 asm, ".2d", ".2d", ".2s", ".s",
7115 [(set (v2i64 V128:$dst),
7116 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
7117 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7119 let Inst{11} = idx{1};
7120 let Inst{21} = idx{0};
7123 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7126 asm#"2", ".2d", ".2d", ".4s", ".s",
7127 [(set (v2i64 V128:$dst),
7128 (OpNode (v2i64 V128:$Rd),
7129 (extract_high_v4i32 V128:$Rn),
7130 (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7131 VectorIndexS:$idx))))]> {
7133 let Inst{11} = idx{1};
7134 let Inst{21} = idx{0};
7139 //----------------------------------------------------------------------------
7140 // AdvSIMD scalar shift by immediate
7141 //----------------------------------------------------------------------------
7143 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7144 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
7145 RegisterClass regtype1, RegisterClass regtype2,
7146 Operand immtype, string asm, list<dag> pattern>
7147 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
7148 asm, "\t$Rd, $Rn, $imm", "", pattern>,
7153 let Inst{31-30} = 0b01;
7155 let Inst{28-23} = 0b111110;
7156 let Inst{22-16} = fixed_imm;
7157 let Inst{15-11} = opc;
7163 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7164 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
7165 RegisterClass regtype1, RegisterClass regtype2,
7166 Operand immtype, string asm, list<dag> pattern>
7167 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
7168 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
7173 let Inst{31-30} = 0b01;
7175 let Inst{28-23} = 0b111110;
7176 let Inst{22-16} = fixed_imm;
7177 let Inst{15-11} = opc;
7184 multiclass SIMDScalarRShiftSD<bit U, bits<5> opc, string asm> {
7185 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7186 FPR32, FPR32, vecshiftR32, asm, []> {
7187 let Inst{20-16} = imm{4-0};
7190 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7191 FPR64, FPR64, vecshiftR64, asm, []> {
7192 let Inst{21-16} = imm{5-0};
7196 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
7197 SDPatternOperator OpNode> {
7198 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7199 FPR64, FPR64, vecshiftR64, asm,
7200 [(set (i64 FPR64:$Rd),
7201 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
7202 let Inst{21-16} = imm{5-0};
7205 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
7206 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
7209 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
7210 SDPatternOperator OpNode = null_frag> {
7211 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7212 FPR64, FPR64, vecshiftR64, asm,
7213 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
7214 (i32 vecshiftR64:$imm)))]> {
7215 let Inst{21-16} = imm{5-0};
7218 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
7219 (i32 vecshiftR64:$imm))),
7220 (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
7224 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
7225 SDPatternOperator OpNode> {
7226 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7227 FPR64, FPR64, vecshiftL64, asm,
7228 [(set (v1i64 FPR64:$Rd),
7229 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7230 let Inst{21-16} = imm{5-0};
7234 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7235 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
7236 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7237 FPR64, FPR64, vecshiftL64, asm, []> {
7238 let Inst{21-16} = imm{5-0};
7242 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7243 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
7244 SDPatternOperator OpNode = null_frag> {
7245 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7246 FPR8, FPR16, vecshiftR8, asm, []> {
7247 let Inst{18-16} = imm{2-0};
7250 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7251 FPR16, FPR32, vecshiftR16, asm, []> {
7252 let Inst{19-16} = imm{3-0};
7255 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7256 FPR32, FPR64, vecshiftR32, asm,
7257 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
7258 let Inst{20-16} = imm{4-0};
7262 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
7263 SDPatternOperator OpNode> {
7264 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7265 FPR8, FPR8, vecshiftL8, asm, []> {
7266 let Inst{18-16} = imm{2-0};
7269 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7270 FPR16, FPR16, vecshiftL16, asm, []> {
7271 let Inst{19-16} = imm{3-0};
7274 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7275 FPR32, FPR32, vecshiftL32, asm,
7276 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
7277 let Inst{20-16} = imm{4-0};
7280 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7281 FPR64, FPR64, vecshiftL64, asm,
7282 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7283 let Inst{21-16} = imm{5-0};
7286 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
7287 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
7290 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
7291 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7292 FPR8, FPR8, vecshiftR8, asm, []> {
7293 let Inst{18-16} = imm{2-0};
7296 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7297 FPR16, FPR16, vecshiftR16, asm, []> {
7298 let Inst{19-16} = imm{3-0};
7301 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7302 FPR32, FPR32, vecshiftR32, asm, []> {
7303 let Inst{20-16} = imm{4-0};
7306 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7307 FPR64, FPR64, vecshiftR64, asm, []> {
7308 let Inst{21-16} = imm{5-0};
7312 //----------------------------------------------------------------------------
7313 // AdvSIMD vector x indexed element
7314 //----------------------------------------------------------------------------
7316 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7317 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7318 RegisterOperand dst_reg, RegisterOperand src_reg,
7320 string asm, string dst_kind, string src_kind,
7322 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
7323 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7324 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
7331 let Inst{28-23} = 0b011110;
7332 let Inst{22-16} = fixed_imm;
7333 let Inst{15-11} = opc;
7339 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7340 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7341 RegisterOperand vectype1, RegisterOperand vectype2,
7343 string asm, string dst_kind, string src_kind,
7345 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
7346 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7347 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
7354 let Inst{28-23} = 0b011110;
7355 let Inst{22-16} = fixed_imm;
7356 let Inst{15-11} = opc;
7362 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
7364 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7365 V64, V64, vecshiftR32,
7367 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
7369 let Inst{20-16} = imm;
7372 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7373 V128, V128, vecshiftR32,
7375 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
7377 let Inst{20-16} = imm;
7380 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7381 V128, V128, vecshiftR64,
7383 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
7385 let Inst{21-16} = imm;
7389 multiclass SIMDVectorRShiftSDToFP<bit U, bits<5> opc, string asm,
7391 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7392 V64, V64, vecshiftR32,
7394 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
7396 let Inst{20-16} = imm;
7399 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7400 V128, V128, vecshiftR32,
7402 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
7404 let Inst{20-16} = imm;
7407 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7408 V128, V128, vecshiftR64,
7410 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
7412 let Inst{21-16} = imm;
7416 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
7417 SDPatternOperator OpNode> {
7418 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7419 V64, V128, vecshiftR16Narrow,
7421 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
7423 let Inst{18-16} = imm;
7426 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7427 V128, V128, vecshiftR16Narrow,
7428 asm#"2", ".16b", ".8h", []> {
7430 let Inst{18-16} = imm;
7431 let hasSideEffects = 0;
7434 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7435 V64, V128, vecshiftR32Narrow,
7437 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
7439 let Inst{19-16} = imm;
7442 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7443 V128, V128, vecshiftR32Narrow,
7444 asm#"2", ".8h", ".4s", []> {
7446 let Inst{19-16} = imm;
7447 let hasSideEffects = 0;
7450 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7451 V64, V128, vecshiftR64Narrow,
7453 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
7455 let Inst{20-16} = imm;
7458 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7459 V128, V128, vecshiftR64Narrow,
7460 asm#"2", ".4s", ".2d", []> {
7462 let Inst{20-16} = imm;
7463 let hasSideEffects = 0;
7466 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
7467 // themselves, so put them here instead.
7469 // Patterns involving what's effectively an insert high and a normal
7470 // intrinsic, represented by CONCAT_VECTORS.
7471 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
7472 vecshiftR16Narrow:$imm)),
7473 (!cast<Instruction>(NAME # "v16i8_shift")
7474 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7475 V128:$Rn, vecshiftR16Narrow:$imm)>;
7476 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
7477 vecshiftR32Narrow:$imm)),
7478 (!cast<Instruction>(NAME # "v8i16_shift")
7479 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7480 V128:$Rn, vecshiftR32Narrow:$imm)>;
7481 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
7482 vecshiftR64Narrow:$imm)),
7483 (!cast<Instruction>(NAME # "v4i32_shift")
7484 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7485 V128:$Rn, vecshiftR64Narrow:$imm)>;
7488 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
7489 SDPatternOperator OpNode> {
7490 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7491 V64, V64, vecshiftL8,
7493 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7494 (i32 vecshiftL8:$imm)))]> {
7496 let Inst{18-16} = imm;
7499 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7500 V128, V128, vecshiftL8,
7501 asm, ".16b", ".16b",
7502 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7503 (i32 vecshiftL8:$imm)))]> {
7505 let Inst{18-16} = imm;
7508 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7509 V64, V64, vecshiftL16,
7511 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7512 (i32 vecshiftL16:$imm)))]> {
7514 let Inst{19-16} = imm;
7517 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7518 V128, V128, vecshiftL16,
7520 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7521 (i32 vecshiftL16:$imm)))]> {
7523 let Inst{19-16} = imm;
7526 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7527 V64, V64, vecshiftL32,
7529 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7530 (i32 vecshiftL32:$imm)))]> {
7532 let Inst{20-16} = imm;
7535 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7536 V128, V128, vecshiftL32,
7538 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7539 (i32 vecshiftL32:$imm)))]> {
7541 let Inst{20-16} = imm;
7544 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7545 V128, V128, vecshiftL64,
7547 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7548 (i32 vecshiftL64:$imm)))]> {
7550 let Inst{21-16} = imm;
7554 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
7555 SDPatternOperator OpNode> {
7556 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7557 V64, V64, vecshiftR8,
7559 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7560 (i32 vecshiftR8:$imm)))]> {
7562 let Inst{18-16} = imm;
7565 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7566 V128, V128, vecshiftR8,
7567 asm, ".16b", ".16b",
7568 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7569 (i32 vecshiftR8:$imm)))]> {
7571 let Inst{18-16} = imm;
7574 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7575 V64, V64, vecshiftR16,
7577 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7578 (i32 vecshiftR16:$imm)))]> {
7580 let Inst{19-16} = imm;
7583 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7584 V128, V128, vecshiftR16,
7586 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7587 (i32 vecshiftR16:$imm)))]> {
7589 let Inst{19-16} = imm;
7592 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7593 V64, V64, vecshiftR32,
7595 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7596 (i32 vecshiftR32:$imm)))]> {
7598 let Inst{20-16} = imm;
7601 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7602 V128, V128, vecshiftR32,
7604 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7605 (i32 vecshiftR32:$imm)))]> {
7607 let Inst{20-16} = imm;
7610 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7611 V128, V128, vecshiftR64,
7613 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7614 (i32 vecshiftR64:$imm)))]> {
7616 let Inst{21-16} = imm;
7620 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7621 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
7622 SDPatternOperator OpNode = null_frag> {
7623 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7624 V64, V64, vecshiftR8, asm, ".8b", ".8b",
7625 [(set (v8i8 V64:$dst),
7626 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7627 (i32 vecshiftR8:$imm)))]> {
7629 let Inst{18-16} = imm;
7632 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7633 V128, V128, vecshiftR8, asm, ".16b", ".16b",
7634 [(set (v16i8 V128:$dst),
7635 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7636 (i32 vecshiftR8:$imm)))]> {
7638 let Inst{18-16} = imm;
7641 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7642 V64, V64, vecshiftR16, asm, ".4h", ".4h",
7643 [(set (v4i16 V64:$dst),
7644 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7645 (i32 vecshiftR16:$imm)))]> {
7647 let Inst{19-16} = imm;
7650 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7651 V128, V128, vecshiftR16, asm, ".8h", ".8h",
7652 [(set (v8i16 V128:$dst),
7653 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7654 (i32 vecshiftR16:$imm)))]> {
7656 let Inst{19-16} = imm;
7659 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7660 V64, V64, vecshiftR32, asm, ".2s", ".2s",
7661 [(set (v2i32 V64:$dst),
7662 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7663 (i32 vecshiftR32:$imm)))]> {
7665 let Inst{20-16} = imm;
7668 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7669 V128, V128, vecshiftR32, asm, ".4s", ".4s",
7670 [(set (v4i32 V128:$dst),
7671 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7672 (i32 vecshiftR32:$imm)))]> {
7674 let Inst{20-16} = imm;
7677 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7678 V128, V128, vecshiftR64,
7679 asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
7680 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7681 (i32 vecshiftR64:$imm)))]> {
7683 let Inst{21-16} = imm;
7687 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
7688 SDPatternOperator OpNode = null_frag> {
7689 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7690 V64, V64, vecshiftL8,
7692 [(set (v8i8 V64:$dst),
7693 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7694 (i32 vecshiftL8:$imm)))]> {
7696 let Inst{18-16} = imm;
7699 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7700 V128, V128, vecshiftL8,
7701 asm, ".16b", ".16b",
7702 [(set (v16i8 V128:$dst),
7703 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7704 (i32 vecshiftL8:$imm)))]> {
7706 let Inst{18-16} = imm;
7709 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7710 V64, V64, vecshiftL16,
7712 [(set (v4i16 V64:$dst),
7713 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7714 (i32 vecshiftL16:$imm)))]> {
7716 let Inst{19-16} = imm;
7719 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7720 V128, V128, vecshiftL16,
7722 [(set (v8i16 V128:$dst),
7723 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7724 (i32 vecshiftL16:$imm)))]> {
7726 let Inst{19-16} = imm;
7729 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7730 V64, V64, vecshiftL32,
7732 [(set (v2i32 V64:$dst),
7733 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7734 (i32 vecshiftL32:$imm)))]> {
7736 let Inst{20-16} = imm;
7739 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7740 V128, V128, vecshiftL32,
7742 [(set (v4i32 V128:$dst),
7743 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7744 (i32 vecshiftL32:$imm)))]> {
7746 let Inst{20-16} = imm;
7749 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7750 V128, V128, vecshiftL64,
7752 [(set (v2i64 V128:$dst),
7753 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7754 (i32 vecshiftL64:$imm)))]> {
7756 let Inst{21-16} = imm;
7760 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
7761 SDPatternOperator OpNode> {
7762 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7763 V128, V64, vecshiftL8, asm, ".8h", ".8b",
7764 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
7766 let Inst{18-16} = imm;
7769 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7770 V128, V128, vecshiftL8,
7771 asm#"2", ".8h", ".16b",
7772 [(set (v8i16 V128:$Rd),
7773 (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
7775 let Inst{18-16} = imm;
7778 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7779 V128, V64, vecshiftL16, asm, ".4s", ".4h",
7780 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
7782 let Inst{19-16} = imm;
7785 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7786 V128, V128, vecshiftL16,
7787 asm#"2", ".4s", ".8h",
7788 [(set (v4i32 V128:$Rd),
7789 (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
7792 let Inst{19-16} = imm;
7795 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7796 V128, V64, vecshiftL32, asm, ".2d", ".2s",
7797 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
7799 let Inst{20-16} = imm;
7802 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7803 V128, V128, vecshiftL32,
7804 asm#"2", ".2d", ".4s",
7805 [(set (v2i64 V128:$Rd),
7806 (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
7808 let Inst{20-16} = imm;
7814 // Vector load/store
7816 // SIMD ldX/stX no-index memory references don't allow the optional
7817 // ", #0" constant and handle post-indexing explicitly, so we use
7818 // a more specialized parse method for them. Otherwise, it's the same as
7819 // the general GPR64sp handling.
7821 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
7822 string asm, dag oops, dag iops, list<dag> pattern>
7823 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
7828 let Inst{29-23} = 0b0011000;
7830 let Inst{21-16} = 0b000000;
7831 let Inst{15-12} = opcode;
7832 let Inst{11-10} = size;
7837 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
7838 string asm, dag oops, dag iops>
7839 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
7845 let Inst{29-23} = 0b0011001;
7848 let Inst{20-16} = Xm;
7849 let Inst{15-12} = opcode;
7850 let Inst{11-10} = size;
7855 // The immediate form of AdvSIMD post-indexed addressing is encoded with
7856 // register post-index addressing from the zero register.
7857 multiclass SIMDLdStAliases<string asm, string layout, string Count,
7858 int Offset, int Size> {
7859 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
7860 // "ld1\t$Vt, [$Rn], #16"
7861 // may get mapped to
7862 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
7863 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
7864 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7866 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
7869 // E.g. "ld1.8b { v0, v1 }, [x1], #16"
7870 // "ld1.8b\t$Vt, [$Rn], #16"
7871 // may get mapped to
7872 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
7873 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
7874 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7876 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7879 // E.g. "ld1.8b { v0, v1 }, [x1]"
7880 // "ld1\t$Vt, [$Rn]"
7881 // may get mapped to
7882 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
7883 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
7884 (!cast<Instruction>(NAME # Count # "v" # layout)
7885 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7888 // E.g. "ld1.8b { v0, v1 }, [x1], x2"
7889 // "ld1\t$Vt, [$Rn], $Xm"
7890 // may get mapped to
7891 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
7892 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
7893 (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7895 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7896 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
7899 multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
7900 int Offset64, bits<4> opcode> {
7901 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
7902 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
7903 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
7904 (ins GPR64sp:$Rn), []>;
7905 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
7906 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
7907 (ins GPR64sp:$Rn), []>;
7908 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
7909 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
7910 (ins GPR64sp:$Rn), []>;
7911 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
7912 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
7913 (ins GPR64sp:$Rn), []>;
7914 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
7915 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
7916 (ins GPR64sp:$Rn), []>;
7917 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
7918 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
7919 (ins GPR64sp:$Rn), []>;
7920 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
7921 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
7922 (ins GPR64sp:$Rn), []>;
7925 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
7926 (outs GPR64sp:$wback,
7927 !cast<RegisterOperand>(veclist # "16b"):$Vt),
7929 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7930 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
7931 (outs GPR64sp:$wback,
7932 !cast<RegisterOperand>(veclist # "8h"):$Vt),
7934 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7935 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
7936 (outs GPR64sp:$wback,
7937 !cast<RegisterOperand>(veclist # "4s"):$Vt),
7939 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7940 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
7941 (outs GPR64sp:$wback,
7942 !cast<RegisterOperand>(veclist # "2d"):$Vt),
7944 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7945 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
7946 (outs GPR64sp:$wback,
7947 !cast<RegisterOperand>(veclist # "8b"):$Vt),
7949 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7950 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
7951 (outs GPR64sp:$wback,
7952 !cast<RegisterOperand>(veclist # "4h"):$Vt),
7954 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7955 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
7956 (outs GPR64sp:$wback,
7957 !cast<RegisterOperand>(veclist # "2s"):$Vt),
7959 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7962 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
7963 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
7964 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
7965 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
7966 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
7967 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
7968 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
7971 // Only ld1/st1 has a v1d version.
7972 multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
7973 int Offset64, bits<4> opcode> {
7974 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
7975 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
7976 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
7978 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
7979 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
7981 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
7982 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
7984 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
7985 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
7987 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
7988 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
7990 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
7991 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
7993 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
7994 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
7997 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
7998 (outs GPR64sp:$wback),
7999 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
8001 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8002 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
8003 (outs GPR64sp:$wback),
8004 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
8006 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8007 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
8008 (outs GPR64sp:$wback),
8009 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
8011 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8012 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
8013 (outs GPR64sp:$wback),
8014 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
8016 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
8017 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
8018 (outs GPR64sp:$wback),
8019 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
8021 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8022 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
8023 (outs GPR64sp:$wback),
8024 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
8026 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8027 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
8028 (outs GPR64sp:$wback),
8029 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
8031 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8034 defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
8035 defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8036 defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8037 defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8038 defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8039 defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8040 defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8043 multiclass BaseSIMDLd1<string Count, string asm, string veclist,
8044 int Offset128, int Offset64, bits<4> opcode>
8045 : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
8047 // LD1 instructions have extra "1d" variants.
8048 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8049 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
8050 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
8051 (ins GPR64sp:$Rn), []>;
8053 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
8054 (outs GPR64sp:$wback,
8055 !cast<RegisterOperand>(veclist # "1d"):$Vt),
8057 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8060 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8063 multiclass BaseSIMDSt1<string Count, string asm, string veclist,
8064 int Offset128, int Offset64, bits<4> opcode>
8065 : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
8067 // ST1 instructions have extra "1d" variants.
8068 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
8069 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
8070 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8073 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
8074 (outs GPR64sp:$wback),
8075 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8077 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8080 defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8083 multiclass SIMDLd1Multiple<string asm> {
8084 defm One : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8, 0b0111>;
8085 defm Two : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8086 defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8087 defm Four : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8090 multiclass SIMDSt1Multiple<string asm> {
8091 defm One : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8, 0b0111>;
8092 defm Two : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8093 defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8094 defm Four : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8097 multiclass SIMDLd2Multiple<string asm> {
8098 defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8101 multiclass SIMDSt2Multiple<string asm> {
8102 defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8105 multiclass SIMDLd3Multiple<string asm> {
8106 defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8109 multiclass SIMDSt3Multiple<string asm> {
8110 defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8113 multiclass SIMDLd4Multiple<string asm> {
8114 defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8117 multiclass SIMDSt4Multiple<string asm> {
8118 defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8122 // AdvSIMD Load/store single-element
8125 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
8126 string asm, string operands, string cst,
8127 dag oops, dag iops, list<dag> pattern>
8128 : I<oops, iops, asm, operands, cst, pattern> {
8132 let Inst{29-24} = 0b001101;
8135 let Inst{15-13} = opcode;
8140 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
8141 string asm, string operands, string cst,
8142 dag oops, dag iops, list<dag> pattern>
8143 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
8147 let Inst{29-24} = 0b001101;
8150 let Inst{15-13} = opcode;
8156 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8157 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
8159 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
8160 (outs listtype:$Vt), (ins GPR64sp:$Rn),
8164 let Inst{20-16} = 0b00000;
8166 let Inst{11-10} = size;
8168 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8169 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
8170 string asm, Operand listtype, Operand GPR64pi>
8171 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
8173 (outs GPR64sp:$wback, listtype:$Vt),
8174 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
8178 let Inst{20-16} = Xm;
8180 let Inst{11-10} = size;
8183 multiclass SIMDLdrAliases<string asm, string layout, string Count,
8184 int Offset, int Size> {
8185 // E.g. "ld1r { v0.8b }, [x1], #1"
8186 // "ld1r.8b\t$Vt, [$Rn], #1"
8187 // may get mapped to
8188 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8189 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8190 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8192 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8195 // E.g. "ld1r.8b { v0 }, [x1], #1"
8196 // "ld1r.8b\t$Vt, [$Rn], #1"
8197 // may get mapped to
8198 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8199 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8200 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8202 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8205 // E.g. "ld1r.8b { v0 }, [x1]"
8206 // "ld1r.8b\t$Vt, [$Rn]"
8207 // may get mapped to
8208 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8209 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8210 (!cast<Instruction>(NAME # "v" # layout)
8211 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8214 // E.g. "ld1r.8b { v0 }, [x1], x2"
8215 // "ld1r.8b\t$Vt, [$Rn], $Xm"
8216 // may get mapped to
8217 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8218 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8219 (!cast<Instruction>(NAME # "v" # layout # "_POST")
8221 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8222 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8225 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
8226 int Offset1, int Offset2, int Offset4, int Offset8> {
8227 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
8228 !cast<Operand>("VecList" # Count # "8b")>;
8229 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
8230 !cast<Operand>("VecList" # Count #"16b")>;
8231 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
8232 !cast<Operand>("VecList" # Count #"4h")>;
8233 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
8234 !cast<Operand>("VecList" # Count #"8h")>;
8235 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
8236 !cast<Operand>("VecList" # Count #"2s")>;
8237 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
8238 !cast<Operand>("VecList" # Count #"4s")>;
8239 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
8240 !cast<Operand>("VecList" # Count #"1d")>;
8241 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
8242 !cast<Operand>("VecList" # Count #"2d")>;
8244 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
8245 !cast<Operand>("VecList" # Count # "8b"),
8246 !cast<Operand>("GPR64pi" # Offset1)>;
8247 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
8248 !cast<Operand>("VecList" # Count # "16b"),
8249 !cast<Operand>("GPR64pi" # Offset1)>;
8250 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
8251 !cast<Operand>("VecList" # Count # "4h"),
8252 !cast<Operand>("GPR64pi" # Offset2)>;
8253 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
8254 !cast<Operand>("VecList" # Count # "8h"),
8255 !cast<Operand>("GPR64pi" # Offset2)>;
8256 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
8257 !cast<Operand>("VecList" # Count # "2s"),
8258 !cast<Operand>("GPR64pi" # Offset4)>;
8259 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
8260 !cast<Operand>("VecList" # Count # "4s"),
8261 !cast<Operand>("GPR64pi" # Offset4)>;
8262 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
8263 !cast<Operand>("VecList" # Count # "1d"),
8264 !cast<Operand>("GPR64pi" # Offset8)>;
8265 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
8266 !cast<Operand>("VecList" # Count # "2d"),
8267 !cast<Operand>("GPR64pi" # Offset8)>;
8269 defm : SIMDLdrAliases<asm, "8b", Count, Offset1, 64>;
8270 defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
8271 defm : SIMDLdrAliases<asm, "4h", Count, Offset2, 64>;
8272 defm : SIMDLdrAliases<asm, "8h", Count, Offset2, 128>;
8273 defm : SIMDLdrAliases<asm, "2s", Count, Offset4, 64>;
8274 defm : SIMDLdrAliases<asm, "4s", Count, Offset4, 128>;
8275 defm : SIMDLdrAliases<asm, "1d", Count, Offset8, 64>;
8276 defm : SIMDLdrAliases<asm, "2d", Count, Offset8, 128>;
8279 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
8280 dag oops, dag iops, list<dag> pattern>
8281 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8283 // idx encoded in Q:S:size fields.
8285 let Inst{30} = idx{3};
8287 let Inst{20-16} = 0b00000;
8288 let Inst{12} = idx{2};
8289 let Inst{11-10} = idx{1-0};
8291 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
8292 dag oops, dag iops, list<dag> pattern>
8293 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8294 oops, iops, pattern> {
8295 // idx encoded in Q:S:size fields.
8297 let Inst{30} = idx{3};
8299 let Inst{20-16} = 0b00000;
8300 let Inst{12} = idx{2};
8301 let Inst{11-10} = idx{1-0};
8303 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
8305 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8306 "$Rn = $wback", oops, iops, []> {
8307 // idx encoded in Q:S:size fields.
8310 let Inst{30} = idx{3};
8312 let Inst{20-16} = Xm;
8313 let Inst{12} = idx{2};
8314 let Inst{11-10} = idx{1-0};
8316 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
8318 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8319 "$Rn = $wback", oops, iops, []> {
8320 // idx encoded in Q:S:size fields.
8323 let Inst{30} = idx{3};
8325 let Inst{20-16} = Xm;
8326 let Inst{12} = idx{2};
8327 let Inst{11-10} = idx{1-0};
8330 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
8331 dag oops, dag iops, list<dag> pattern>
8332 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8334 // idx encoded in Q:S:size<1> fields.
8336 let Inst{30} = idx{2};
8338 let Inst{20-16} = 0b00000;
8339 let Inst{12} = idx{1};
8340 let Inst{11} = idx{0};
8341 let Inst{10} = size;
8343 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
8344 dag oops, dag iops, list<dag> pattern>
8345 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8346 oops, iops, pattern> {
8347 // idx encoded in Q:S:size<1> fields.
8349 let Inst{30} = idx{2};
8351 let Inst{20-16} = 0b00000;
8352 let Inst{12} = idx{1};
8353 let Inst{11} = idx{0};
8354 let Inst{10} = size;
8357 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8359 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8360 "$Rn = $wback", oops, iops, []> {
8361 // idx encoded in Q:S:size<1> fields.
8364 let Inst{30} = idx{2};
8366 let Inst{20-16} = Xm;
8367 let Inst{12} = idx{1};
8368 let Inst{11} = idx{0};
8369 let Inst{10} = size;
8371 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8373 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8374 "$Rn = $wback", oops, iops, []> {
8375 // idx encoded in Q:S:size<1> fields.
8378 let Inst{30} = idx{2};
8380 let Inst{20-16} = Xm;
8381 let Inst{12} = idx{1};
8382 let Inst{11} = idx{0};
8383 let Inst{10} = size;
8385 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8386 dag oops, dag iops, list<dag> pattern>
8387 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8389 // idx encoded in Q:S fields.
8391 let Inst{30} = idx{1};
8393 let Inst{20-16} = 0b00000;
8394 let Inst{12} = idx{0};
8395 let Inst{11-10} = size;
8397 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8398 dag oops, dag iops, list<dag> pattern>
8399 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8400 oops, iops, pattern> {
8401 // idx encoded in Q:S fields.
8403 let Inst{30} = idx{1};
8405 let Inst{20-16} = 0b00000;
8406 let Inst{12} = idx{0};
8407 let Inst{11-10} = size;
8409 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
8410 string asm, dag oops, dag iops>
8411 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8412 "$Rn = $wback", oops, iops, []> {
8413 // idx encoded in Q:S fields.
8416 let Inst{30} = idx{1};
8418 let Inst{20-16} = Xm;
8419 let Inst{12} = idx{0};
8420 let Inst{11-10} = size;
8422 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8423 string asm, dag oops, dag iops>
8424 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8425 "$Rn = $wback", oops, iops, []> {
8426 // idx encoded in Q:S fields.
8429 let Inst{30} = idx{1};
8431 let Inst{20-16} = Xm;
8432 let Inst{12} = idx{0};
8433 let Inst{11-10} = size;
8435 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8436 dag oops, dag iops, list<dag> pattern>
8437 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8439 // idx encoded in Q field.
8443 let Inst{20-16} = 0b00000;
8445 let Inst{11-10} = size;
8447 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8448 dag oops, dag iops, list<dag> pattern>
8449 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8450 oops, iops, pattern> {
8451 // idx encoded in Q field.
8455 let Inst{20-16} = 0b00000;
8457 let Inst{11-10} = size;
8459 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
8460 string asm, dag oops, dag iops>
8461 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8462 "$Rn = $wback", oops, iops, []> {
8463 // idx encoded in Q field.
8468 let Inst{20-16} = Xm;
8470 let Inst{11-10} = size;
8472 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8473 string asm, dag oops, dag iops>
8474 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8475 "$Rn = $wback", oops, iops, []> {
8476 // idx encoded in Q field.
8481 let Inst{20-16} = Xm;
8483 let Inst{11-10} = size;
8486 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8487 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
8488 RegisterOperand listtype,
8489 RegisterOperand GPR64pi> {
8490 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
8491 (outs listtype:$dst),
8492 (ins listtype:$Vt, VectorIndexB:$idx,
8495 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
8496 (outs GPR64sp:$wback, listtype:$dst),
8497 (ins listtype:$Vt, VectorIndexB:$idx,
8498 GPR64sp:$Rn, GPR64pi:$Xm)>;
8500 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8501 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
8502 RegisterOperand listtype,
8503 RegisterOperand GPR64pi> {
8504 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
8505 (outs listtype:$dst),
8506 (ins listtype:$Vt, VectorIndexH:$idx,
8509 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
8510 (outs GPR64sp:$wback, listtype:$dst),
8511 (ins listtype:$Vt, VectorIndexH:$idx,
8512 GPR64sp:$Rn, GPR64pi:$Xm)>;
8514 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8515 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
8516 RegisterOperand listtype,
8517 RegisterOperand GPR64pi> {
8518 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
8519 (outs listtype:$dst),
8520 (ins listtype:$Vt, VectorIndexS:$idx,
8523 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
8524 (outs GPR64sp:$wback, listtype:$dst),
8525 (ins listtype:$Vt, VectorIndexS:$idx,
8526 GPR64sp:$Rn, GPR64pi:$Xm)>;
8528 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8529 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
8530 RegisterOperand listtype, RegisterOperand GPR64pi> {
8531 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
8532 (outs listtype:$dst),
8533 (ins listtype:$Vt, VectorIndexD:$idx,
8536 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
8537 (outs GPR64sp:$wback, listtype:$dst),
8538 (ins listtype:$Vt, VectorIndexD:$idx,
8539 GPR64sp:$Rn, GPR64pi:$Xm)>;
8541 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8542 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
8543 RegisterOperand listtype, RegisterOperand GPR64pi> {
8544 def i8 : SIMDLdStSingleB<0, R, opcode, asm,
8545 (outs), (ins listtype:$Vt, VectorIndexB:$idx,
8548 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
8549 (outs GPR64sp:$wback),
8550 (ins listtype:$Vt, VectorIndexB:$idx,
8551 GPR64sp:$Rn, GPR64pi:$Xm)>;
8553 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8554 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
8555 RegisterOperand listtype, RegisterOperand GPR64pi> {
8556 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
8557 (outs), (ins listtype:$Vt, VectorIndexH:$idx,
8560 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
8561 (outs GPR64sp:$wback),
8562 (ins listtype:$Vt, VectorIndexH:$idx,
8563 GPR64sp:$Rn, GPR64pi:$Xm)>;
8565 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8566 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
8567 RegisterOperand listtype, RegisterOperand GPR64pi> {
8568 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
8569 (outs), (ins listtype:$Vt, VectorIndexS:$idx,
8572 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
8573 (outs GPR64sp:$wback),
8574 (ins listtype:$Vt, VectorIndexS:$idx,
8575 GPR64sp:$Rn, GPR64pi:$Xm)>;
8577 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8578 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
8579 RegisterOperand listtype, RegisterOperand GPR64pi> {
8580 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
8581 (outs), (ins listtype:$Vt, VectorIndexD:$idx,
8584 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
8585 (outs GPR64sp:$wback),
8586 (ins listtype:$Vt, VectorIndexD:$idx,
8587 GPR64sp:$Rn, GPR64pi:$Xm)>;
8590 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
8591 string Count, int Offset, Operand idxtype> {
8592 // E.g. "ld1 { v0.8b }[0], [x1], #1"
8593 // "ld1\t$Vt, [$Rn], #1"
8594 // may get mapped to
8595 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8596 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
8597 (!cast<Instruction>(NAME # Type # "_POST")
8599 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8600 idxtype:$idx, XZR), 1>;
8602 // E.g. "ld1.8b { v0 }[0], [x1], #1"
8603 // "ld1.8b\t$Vt, [$Rn], #1"
8604 // may get mapped to
8605 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8606 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
8607 (!cast<Instruction>(NAME # Type # "_POST")
8609 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8610 idxtype:$idx, XZR), 0>;
8612 // E.g. "ld1.8b { v0 }[0], [x1]"
8613 // "ld1.8b\t$Vt, [$Rn]"
8614 // may get mapped to
8615 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8616 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
8617 (!cast<Instruction>(NAME # Type)
8618 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8619 idxtype:$idx, GPR64sp:$Rn), 0>;
8621 // E.g. "ld1.8b { v0 }[0], [x1], x2"
8622 // "ld1.8b\t$Vt, [$Rn], $Xm"
8623 // may get mapped to
8624 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8625 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
8626 (!cast<Instruction>(NAME # Type # "_POST")
8628 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8630 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8633 multiclass SIMDLdSt1SingleAliases<string asm> {
8634 defm : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;
8635 defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
8636 defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
8637 defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
8640 multiclass SIMDLdSt2SingleAliases<string asm> {
8641 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;
8642 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;
8643 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;
8644 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
8647 multiclass SIMDLdSt3SingleAliases<string asm> {
8648 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;
8649 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;
8650 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
8651 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
8654 multiclass SIMDLdSt4SingleAliases<string asm> {
8655 defm : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;
8656 defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;
8657 defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
8658 defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
8660 } // end of 'let Predicates = [HasNEON]'
8662 //----------------------------------------------------------------------------
8663 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
8664 //----------------------------------------------------------------------------
8666 let Predicates = [HasNEON, HasV8_1a] in {
8668 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
8669 RegisterOperand regtype, string asm,
8670 string kind, list<dag> pattern>
8671 : BaseSIMDThreeSameVectorTied<Q, U, size, opcode, regtype, asm, kind,
8675 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
8676 SDPatternOperator Accum> {
8677 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
8678 [(set (v4i16 V64:$dst),
8679 (Accum (v4i16 V64:$Rd),
8680 (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
8681 (v4i16 V64:$Rm)))))]>;
8682 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
8683 [(set (v8i16 V128:$dst),
8684 (Accum (v8i16 V128:$Rd),
8685 (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
8686 (v8i16 V128:$Rm)))))]>;
8687 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
8688 [(set (v2i32 V64:$dst),
8689 (Accum (v2i32 V64:$Rd),
8690 (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
8691 (v2i32 V64:$Rm)))))]>;
8692 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
8693 [(set (v4i32 V128:$dst),
8694 (Accum (v4i32 V128:$Rd),
8695 (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
8696 (v4i32 V128:$Rm)))))]>;
8699 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
8700 SDPatternOperator Accum> {
8701 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
8702 V64, V64, V128_lo, VectorIndexH,
8703 asm, ".4h", ".4h", ".4h", ".h",
8704 [(set (v4i16 V64:$dst),
8705 (Accum (v4i16 V64:$Rd),
8706 (v4i16 (int_aarch64_neon_sqrdmulh
8708 (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8709 VectorIndexH:$idx))))))]> {
8711 let Inst{11} = idx{2};
8712 let Inst{21} = idx{1};
8713 let Inst{20} = idx{0};
8716 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8717 V128, V128, V128_lo, VectorIndexH,
8718 asm, ".8h", ".8h", ".8h", ".h",
8719 [(set (v8i16 V128:$dst),
8720 (Accum (v8i16 V128:$Rd),
8721 (v8i16 (int_aarch64_neon_sqrdmulh
8723 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8724 VectorIndexH:$idx))))))]> {
8726 let Inst{11} = idx{2};
8727 let Inst{21} = idx{1};
8728 let Inst{20} = idx{0};
8731 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8732 V64, V64, V128, VectorIndexS,
8733 asm, ".2s", ".2s", ".2s", ".s",
8734 [(set (v2i32 V64:$dst),
8735 (Accum (v2i32 V64:$Rd),
8736 (v2i32 (int_aarch64_neon_sqrdmulh
8738 (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
8739 VectorIndexS:$idx))))))]> {
8741 let Inst{11} = idx{1};
8742 let Inst{21} = idx{0};
8745 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
8746 // an intermediate EXTRACT_SUBREG would be untyped.
8747 // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we
8748 // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
8749 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8750 (i32 (vector_extract
8751 (v4i32 (insert_subvector
8753 (v2i32 (int_aarch64_neon_sqrdmulh
8755 (v2i32 (AArch64duplane32
8757 VectorIndexS:$idx)))),
8761 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
8762 (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)),
8767 VectorIndexS:$idx)),
8770 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8771 V128, V128, V128, VectorIndexS,
8772 asm, ".4s", ".4s", ".4s", ".s",
8773 [(set (v4i32 V128:$dst),
8774 (Accum (v4i32 V128:$Rd),
8775 (v4i32 (int_aarch64_neon_sqrdmulh
8777 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8778 VectorIndexS:$idx))))))]> {
8780 let Inst{11} = idx{1};
8781 let Inst{21} = idx{0};
8784 // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
8785 // an intermediate EXTRACT_SUBREG would be untyped.
8786 def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8787 (i32 (vector_extract
8788 (v4i32 (int_aarch64_neon_sqrdmulh
8790 (v4i32 (AArch64duplane32
8792 VectorIndexS:$idx)))),
8795 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
8796 (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)),
8801 VectorIndexS:$idx)),
8804 def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
8805 FPR16Op, FPR16Op, V128_lo,
8806 VectorIndexH, asm, ".h", "", "", ".h",
8809 let Inst{11} = idx{2};
8810 let Inst{21} = idx{1};
8811 let Inst{20} = idx{0};
8814 def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
8815 FPR32Op, FPR32Op, V128, VectorIndexS,
8816 asm, ".s", "", "", ".s",
8817 [(set (i32 FPR32Op:$dst),
8818 (Accum (i32 FPR32Op:$Rd),
8819 (i32 (int_aarch64_neon_sqrdmulh
8821 (i32 (vector_extract (v4i32 V128:$Rm),
8822 VectorIndexS:$idx))))))]> {
8824 let Inst{11} = idx{1};
8825 let Inst{21} = idx{0};
8828 } // let Predicates = [HasNeon, HasV8_1a]
8830 //----------------------------------------------------------------------------
8831 // Crypto extensions
8832 //----------------------------------------------------------------------------
8834 let Predicates = [HasCrypto] in {
8835 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8836 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
8838 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
8842 let Inst{31-16} = 0b0100111000101000;
8843 let Inst{15-12} = opc;
8844 let Inst{11-10} = 0b10;
8849 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
8850 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
8851 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
8853 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
8854 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
8856 [(set (v16i8 V128:$dst),
8857 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
8859 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8860 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
8861 dag oops, dag iops, list<dag> pat>
8862 : I<oops, iops, asm,
8863 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
8864 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
8869 let Inst{31-21} = 0b01011110000;
8870 let Inst{20-16} = Rm;
8872 let Inst{14-12} = opc;
8873 let Inst{11-10} = 0b00;
8878 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
8879 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8880 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
8881 [(set (v4i32 FPR128:$dst),
8882 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
8883 (v4i32 V128:$Rm)))]>;
8885 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
8886 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
8887 (ins V128:$Rd, V128:$Rn, V128:$Rm),
8888 [(set (v4i32 V128:$dst),
8889 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8890 (v4i32 V128:$Rm)))]>;
8892 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
8893 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8894 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
8895 [(set (v4i32 FPR128:$dst),
8896 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
8897 (v4i32 V128:$Rm)))]>;
8899 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8900 class SHA2OpInst<bits<4> opc, string asm, string kind,
8901 string cstr, dag oops, dag iops,
8903 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
8904 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
8908 let Inst{31-16} = 0b0101111000101000;
8909 let Inst{15-12} = opc;
8910 let Inst{11-10} = 0b10;
8915 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
8916 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
8917 (ins V128:$Rd, V128:$Rn),
8918 [(set (v4i32 V128:$dst),
8919 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
8921 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
8922 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
8923 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
8924 } // end of 'let Predicates = [HasCrypto]'
8926 //----------------------------------------------------------------------------
8927 // v8.1 atomic instructions extension:
8931 // * LDOPregister<OP>, and aliases STOPregister<OP>
8933 // Instruction encodings:
8935 // 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 0
8936 // CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt
8937 // CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt
8938 // SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt
8939 // LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt
8940 // ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |11111
8942 // Instruction syntax:
8944 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
8945 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
8946 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
8947 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
8948 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
8949 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
8950 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
8951 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
8952 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
8953 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
8955 let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
8956 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
8957 string cstr, list<dag> pattern>
8958 : I<oops, iops, asm, operands, cstr, pattern> {
8966 let Inst{31-30} = Sz;
8967 let Inst{29-24} = 0b001000;
8971 let Inst{20-16} = Rs;
8973 let Inst{14-10} = 0b11111;
8978 class BaseCAS<string order, string size, RegisterClass RC>
8979 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
8980 "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
8985 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
8986 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseCAS<order, "b", GPR32>;
8987 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseCAS<order, "h", GPR32>;
8988 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseCAS<order, "", GPR32>;
8989 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseCAS<order, "", GPR64>;
8992 class BaseCASP<string order, string size, RegisterOperand RC>
8993 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
8994 "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
8999 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
9000 let Sz = 0b00, Acq = Acq, Rel = Rel in
9001 def s : BaseCASP<order, "", WSeqPairClassOperand>;
9002 let Sz = 0b01, Acq = Acq, Rel = Rel in
9003 def d : BaseCASP<order, "", XSeqPairClassOperand>;
9006 let Predicates = [HasV8_1a] in
9007 class BaseSWP<string order, string size, RegisterClass RC>
9008 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
9009 "\t$Rs, $Rt, [$Rn]","",[]> {
9014 bits<3> opc = 0b000;
9017 let Inst{31-30} = Sz;
9018 let Inst{29-24} = 0b111000;
9022 let Inst{20-16} = Rs;
9024 let Inst{14-12} = opc;
9025 let Inst{11-10} = 0b00;
9030 multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
9031 let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseSWP<order, "b", GPR32>;
9032 let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseSWP<order, "h", GPR32>;
9033 let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseSWP<order, "", GPR32>;
9034 let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseSWP<order, "", GPR64>;
9037 let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9038 class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
9039 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
9040 "\t$Rs, $Rt, [$Rn]","",[]> {
9048 let Inst{31-30} = Sz;
9049 let Inst{29-24} = 0b111000;
9053 let Inst{20-16} = Rs;
9055 let Inst{14-12} = opc;
9056 let Inst{11-10} = 0b00;
9061 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,
9063 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in
9064 def b : BaseLDOPregister<op, order, "b", GPR32>;
9065 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in
9066 def h : BaseLDOPregister<op, order, "h", GPR32>;
9067 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in
9068 def s : BaseLDOPregister<op, order, "", GPR32>;
9069 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in
9070 def d : BaseLDOPregister<op, order, "", GPR64>;
9073 let Predicates = [HasV8_1a] in
9074 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
9076 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
9078 multiclass STOPregister<string asm, string instr> {
9079 def : BaseSTOPregister<asm # "lb", GPR32, WZR,
9080 !cast<Instruction>(instr # "Lb")>;
9081 def : BaseSTOPregister<asm # "lh", GPR32, WZR,
9082 !cast<Instruction>(instr # "Lh")>;
9083 def : BaseSTOPregister<asm # "l", GPR32, WZR,
9084 !cast<Instruction>(instr # "Ls")>;
9085 def : BaseSTOPregister<asm # "l", GPR64, XZR,
9086 !cast<Instruction>(instr # "Ld")>;
9087 def : BaseSTOPregister<asm # "b", GPR32, WZR,
9088 !cast<Instruction>(instr # "b")>;
9089 def : BaseSTOPregister<asm # "h", GPR32, WZR,
9090 !cast<Instruction>(instr # "h")>;
9091 def : BaseSTOPregister<asm, GPR32, WZR,
9092 !cast<Instruction>(instr # "s")>;
9093 def : BaseSTOPregister<asm, GPR64, XZR,
9094 !cast<Instruction>(instr # "d")>;
9097 //----------------------------------------------------------------------------
9098 // Allow the size specifier tokens to be upper case, not just lower.
9099 def : TokenAlias<".8B", ".8b">;
9100 def : TokenAlias<".4H", ".4h">;
9101 def : TokenAlias<".2S", ".2s">;
9102 def : TokenAlias<".1D", ".1d">;
9103 def : TokenAlias<".16B", ".16b">;
9104 def : TokenAlias<".8H", ".8h">;
9105 def : TokenAlias<".4S", ".4s">;
9106 def : TokenAlias<".2D", ".2d">;
9107 def : TokenAlias<".1Q", ".1q">;
9108 def : TokenAlias<".B", ".b">;
9109 def : TokenAlias<".H", ".h">;
9110 def : TokenAlias<".S", ".s">;
9111 def : TokenAlias<".D", ".d">;
9112 def : TokenAlias<".Q", ".q">;