Fix broken build
[oota-llvm.git] / lib / Target / ARM64 / ARM64InstrFormats.td
1 //===- ARM64InstrFormats.td - ARM64 Instruction Formats ------*- tblgen -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 //===----------------------------------------------------------------------===//
11 //  Describe ARM64 instructions format here
12 //
13
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
16 // code emitter.
17 class Format<bits<2> val> {
18   bits<2> Value = val;
19 }
20
21 def PseudoFrm   : Format<0>;
22 def NormalFrm   : Format<1>; // Do we need any others?
23
24 // ARM64 Instruction Format
25 class ARM64Inst<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   = "ARM64";
36   Format F        = f;
37   bits<2> Form    = F.Value;
38   let Pattern     = [];
39   let Constraints = cstr;
40 }
41
42 // Pseudo instructions (don't have encoding information)
43 class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">
44     : ARM64Inst<PseudoFrm, cstr> {
45   dag OutOperandList = oops;
46   dag InOperandList  = iops;
47   let Pattern        = pattern;
48   let isCodeGenOnly  = 1;
49 }
50
51 // Real instructions (have encoding information)
52 class EncodedI<string cstr, list<dag> pattern> : ARM64Inst<NormalFrm, cstr> {
53   let Pattern = pattern;
54   let Size = 4;
55 }
56
57 // Normal instructions
58 class I<dag oops, dag iops, string asm, string operands, string cstr,
59         list<dag> pattern>
60     : EncodedI<cstr, pattern> {
61   dag OutOperandList = oops;
62   dag InOperandList  = iops;
63   let AsmString      = !strconcat(asm, operands);
64 }
65
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>;
69
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))>;
79
80 //===----------------------------------------------------------------------===//
81 // Asm Operand Classes.
82 //
83
84 // Shifter operand for arithmetic shifted encodings.
85 def ShifterOperand : AsmOperandClass {
86   let Name = "Shifter";
87 }
88
89 // Shifter operand for mov immediate encodings.
90 def MovImm32ShifterOperand : AsmOperandClass {
91   let SuperClasses = [ShifterOperand];
92   let Name = "MovImm32Shifter";
93 }
94 def MovImm64ShifterOperand : AsmOperandClass {
95   let SuperClasses = [ShifterOperand];
96   let Name = "MovImm64Shifter";
97 }
98
99 // Shifter operand for arithmetic register shifted encodings.
100 class ArithmeticShifterOperand<int width> : AsmOperandClass {
101   let SuperClasses = [ShifterOperand];
102   let Name = "ArithmeticShifter" # width;
103   let PredicateMethod = "isArithmeticShifter";
104   let RenderMethod = "addArithmeticShifterOperands";
105   let DiagnosticType = "AddSubRegShift" # width;
106 }
107
108 def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
109 def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
110
111 // Shifter operand for logical vector 128/64-bit shifted encodings.
112 def LogicalVecShifterOperand : AsmOperandClass {
113   let SuperClasses = [ShifterOperand];
114   let Name = "LogicalVecShifter";
115 }
116 def LogicalVecHalfWordShifterOperand : AsmOperandClass {
117   let SuperClasses = [LogicalVecShifterOperand];
118   let Name = "LogicalVecHalfWordShifter";
119 }
120
121 // The "MSL" shifter on the vector MOVI instruction.
122 def MoveVecShifterOperand : AsmOperandClass {
123   let SuperClasses = [ShifterOperand];
124   let Name = "MoveVecShifter";
125 }
126
127 // Extend operand for arithmetic encodings.
128 def ExtendOperand : AsmOperandClass {
129   let Name = "Extend";
130   let DiagnosticType = "AddSubRegExtendLarge";
131 }
132 def ExtendOperand64 : AsmOperandClass {
133   let SuperClasses = [ExtendOperand];
134   let Name = "Extend64";
135   let DiagnosticType = "AddSubRegExtendSmall";
136 }
137 // 'extend' that's a lsl of a 64-bit register.
138 def ExtendOperandLSL64 : AsmOperandClass {
139   let SuperClasses = [ExtendOperand];
140   let Name = "ExtendLSL64";
141   let DiagnosticType = "AddSubRegExtendLarge";
142 }
143
144 // 8-bit floating-point immediate encodings.
145 def FPImmOperand : AsmOperandClass {
146   let Name = "FPImm";
147   let ParserMethod = "tryParseFPImm";
148 }
149
150 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
151 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
152 // are encoded as the eight bit value 'abcdefgh'.
153 def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
154
155
156 //===----------------------------------------------------------------------===//
157 // Operand Definitions.
158 //
159
160 // ADR[P] instruction labels.
161 def AdrpOperand : AsmOperandClass {
162   let Name = "AdrpLabel";
163   let ParserMethod = "tryParseAdrpLabel";
164   let DiagnosticType = "InvalidLabel";
165 }
166 def adrplabel : Operand<i64> {
167   let EncoderMethod = "getAdrLabelOpValue";
168   let PrintMethod = "printAdrpLabel";
169   let ParserMatchClass = AdrpOperand;
170 }
171
172 def AdrOperand : AsmOperandClass {
173   let Name = "AdrLabel";
174   let ParserMethod = "tryParseAdrLabel";
175   let DiagnosticType = "InvalidLabel";
176 }
177 def adrlabel : Operand<i64> {
178   let EncoderMethod = "getAdrLabelOpValue";
179   let ParserMatchClass = AdrOperand;
180 }
181
182 // simm9 predicate - True if the immediate is in the range [-256, 255].
183 def SImm9Operand : AsmOperandClass {
184   let Name = "SImm9";
185   let DiagnosticType = "InvalidMemoryIndexedSImm9";
186 }
187 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
188   let ParserMatchClass = SImm9Operand;
189 }
190
191 // simm7s4 predicate - True if the immediate is a multiple of 4 in the range
192 // [-256, 252].
193 def SImm7s4Operand : AsmOperandClass {
194   let Name = "SImm7s4";
195   let DiagnosticType = "InvalidMemoryIndexed32SImm7";
196 }
197 def simm7s4 : Operand<i32> {
198   let ParserMatchClass = SImm7s4Operand;
199   let PrintMethod = "printImmScale<4>";
200 }
201
202 // simm7s8 predicate - True if the immediate is a multiple of 8 in the range
203 // [-512, 504].
204 def SImm7s8Operand : AsmOperandClass {
205   let Name = "SImm7s8";
206   let DiagnosticType = "InvalidMemoryIndexed64SImm7";
207 }
208 def simm7s8 : Operand<i32> {
209   let ParserMatchClass = SImm7s8Operand;
210   let PrintMethod = "printImmScale<8>";
211 }
212
213 // simm7s16 predicate - True if the immediate is a multiple of 16 in the range
214 // [-1024, 1008].
215 def SImm7s16Operand : AsmOperandClass {
216   let Name = "SImm7s16";
217   let DiagnosticType = "InvalidMemoryIndexed64SImm7";
218 }
219 def simm7s16 : Operand<i32> {
220   let ParserMatchClass = SImm7s16Operand;
221   let PrintMethod = "printImmScale<16>";
222 }
223
224 // imm0_65535 predicate - True if the immediate is in the range [0,65535].
225 def Imm0_65535Operand : AsmOperandClass { let Name = "Imm0_65535"; }
226 def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
227   return ((uint32_t)Imm) < 65536;
228 }]> {
229   let ParserMatchClass = Imm0_65535Operand;
230   let PrintMethod = "printHexImm";
231 }
232
233 class AsmImmRange<int Low, int High> : AsmOperandClass {
234   let Name = "Imm" # Low # "_" # High;
235   let DiagnosticType = "InvalidImm" # Low # "_" # High;
236 }
237
238 def Imm1_8Operand : AsmImmRange<1, 8>;
239 def Imm1_16Operand : AsmImmRange<1, 16>;
240 def Imm1_32Operand : AsmImmRange<1, 32>;
241 def Imm1_64Operand : AsmImmRange<1, 64>;
242
243 def MovZSymbolG3AsmOperand : AsmOperandClass {
244   let Name = "MovZSymbolG3";
245   let RenderMethod = "addImmOperands";
246 }
247
248 def movz_symbol_g3 : Operand<i32> {
249   let ParserMatchClass = MovZSymbolG3AsmOperand;
250 }
251
252 def MovZSymbolG2AsmOperand : AsmOperandClass {
253   let Name = "MovZSymbolG2";
254   let RenderMethod = "addImmOperands";
255 }
256
257 def movz_symbol_g2 : Operand<i32> {
258   let ParserMatchClass = MovZSymbolG2AsmOperand;
259 }
260
261 def MovZSymbolG1AsmOperand : AsmOperandClass {
262   let Name = "MovZSymbolG1";
263   let RenderMethod = "addImmOperands";
264 }
265
266 def movz_symbol_g1 : Operand<i32> {
267   let ParserMatchClass = MovZSymbolG1AsmOperand;
268 }
269
270 def MovZSymbolG0AsmOperand : AsmOperandClass {
271   let Name = "MovZSymbolG0";
272   let RenderMethod = "addImmOperands";
273 }
274
275 def movz_symbol_g0 : Operand<i32> {
276   let ParserMatchClass = MovZSymbolG0AsmOperand;
277 }
278
279 def MovKSymbolG3AsmOperand : AsmOperandClass {
280   let Name = "MovKSymbolG3";
281   let RenderMethod = "addImmOperands";
282 }
283
284 def movk_symbol_g3 : Operand<i32> {
285   let ParserMatchClass = MovKSymbolG3AsmOperand;
286 }
287
288 def MovKSymbolG2AsmOperand : AsmOperandClass {
289   let Name = "MovKSymbolG2";
290   let RenderMethod = "addImmOperands";
291 }
292
293 def movk_symbol_g2 : Operand<i32> {
294   let ParserMatchClass = MovKSymbolG2AsmOperand;
295 }
296
297 def MovKSymbolG1AsmOperand : AsmOperandClass {
298   let Name = "MovKSymbolG1";
299   let RenderMethod = "addImmOperands";
300 }
301
302 def movk_symbol_g1 : Operand<i32> {
303   let ParserMatchClass = MovKSymbolG1AsmOperand;
304 }
305
306 def MovKSymbolG0AsmOperand : AsmOperandClass {
307   let Name = "MovKSymbolG0";
308   let RenderMethod = "addImmOperands";
309 }
310
311 def movk_symbol_g0 : Operand<i32> {
312   let ParserMatchClass = MovKSymbolG0AsmOperand;
313 }
314
315 class fixedpoint_i32<ValueType FloatVT>
316   : Operand<FloatVT>,
317     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
318   let EncoderMethod = "getFixedPointScaleOpValue";
319   let DecoderMethod = "DecodeFixedPointScaleImm32";
320   let ParserMatchClass = Imm1_32Operand;
321 }
322
323 class fixedpoint_i64<ValueType FloatVT>
324   : Operand<FloatVT>,
325     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
326   let EncoderMethod = "getFixedPointScaleOpValue";
327   let DecoderMethod = "DecodeFixedPointScaleImm64";
328   let ParserMatchClass = Imm1_64Operand;
329 }
330
331 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
332 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
333
334 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
335 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
336
337 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
338   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
339 }]> {
340   let EncoderMethod = "getVecShiftR8OpValue";
341   let DecoderMethod = "DecodeVecShiftR8Imm";
342   let ParserMatchClass = Imm1_8Operand;
343 }
344 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
345   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
346 }]> {
347   let EncoderMethod = "getVecShiftR16OpValue";
348   let DecoderMethod = "DecodeVecShiftR16Imm";
349   let ParserMatchClass = Imm1_16Operand;
350 }
351 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
352   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
353 }]> {
354   let EncoderMethod = "getVecShiftR16OpValue";
355   let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
356   let ParserMatchClass = Imm1_8Operand;
357 }
358 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
359   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
360 }]> {
361   let EncoderMethod = "getVecShiftR32OpValue";
362   let DecoderMethod = "DecodeVecShiftR32Imm";
363   let ParserMatchClass = Imm1_32Operand;
364 }
365 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
366   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
367 }]> {
368   let EncoderMethod = "getVecShiftR32OpValue";
369   let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
370   let ParserMatchClass = Imm1_16Operand;
371 }
372 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
373   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
374 }]> {
375   let EncoderMethod = "getVecShiftR64OpValue";
376   let DecoderMethod = "DecodeVecShiftR64Imm";
377   let ParserMatchClass = Imm1_64Operand;
378 }
379 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
380   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
381 }]> {
382   let EncoderMethod = "getVecShiftR64OpValue";
383   let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
384   let ParserMatchClass = Imm1_32Operand;
385 }
386
387 def Imm0_7Operand : AsmImmRange<0, 7>;
388 def Imm0_15Operand : AsmImmRange<0, 15>;
389 def Imm0_31Operand : AsmImmRange<0, 31>;
390 def Imm0_63Operand : AsmImmRange<0, 63>;
391
392 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
393   return (((uint32_t)Imm) < 8);
394 }]> {
395   let EncoderMethod = "getVecShiftL8OpValue";
396   let DecoderMethod = "DecodeVecShiftL8Imm";
397   let ParserMatchClass = Imm0_7Operand;
398 }
399 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
400   return (((uint32_t)Imm) < 16);
401 }]> {
402   let EncoderMethod = "getVecShiftL16OpValue";
403   let DecoderMethod = "DecodeVecShiftL16Imm";
404   let ParserMatchClass = Imm0_15Operand;
405 }
406 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
407   return (((uint32_t)Imm) < 32);
408 }]> {
409   let EncoderMethod = "getVecShiftL32OpValue";
410   let DecoderMethod = "DecodeVecShiftL32Imm";
411   let ParserMatchClass = Imm0_31Operand;
412 }
413 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
414   return (((uint32_t)Imm) < 64);
415 }]> {
416   let EncoderMethod = "getVecShiftL64OpValue";
417   let DecoderMethod = "DecodeVecShiftL64Imm";
418   let ParserMatchClass = Imm0_63Operand;
419 }
420
421
422 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
423 // instructions for splatting repeating bit patterns across the immediate.
424 def logical_imm32_XFORM : SDNodeXForm<imm, [{
425   uint64_t enc = ARM64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
426   return CurDAG->getTargetConstant(enc, MVT::i32);
427 }]>;
428 def logical_imm64_XFORM : SDNodeXForm<imm, [{
429   uint64_t enc = ARM64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
430   return CurDAG->getTargetConstant(enc, MVT::i32);
431 }]>;
432
433 def LogicalImm32Operand : AsmOperandClass { let Name = "LogicalImm32"; }
434 def LogicalImm64Operand : AsmOperandClass { let Name = "LogicalImm64"; }
435 def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{
436   return ARM64_AM::isLogicalImmediate(N->getZExtValue(), 32);
437 }], logical_imm32_XFORM> {
438   let PrintMethod = "printLogicalImm32";
439   let ParserMatchClass = LogicalImm32Operand;
440 }
441 def logical_imm64 : Operand<i64>, PatLeaf<(imm), [{
442   return ARM64_AM::isLogicalImmediate(N->getZExtValue(), 64);
443 }], logical_imm64_XFORM> {
444   let PrintMethod = "printLogicalImm64";
445   let ParserMatchClass = LogicalImm64Operand;
446 }
447
448 // imm0_255 predicate - True if the immediate is in the range [0,255].
449 def Imm0_255Operand : AsmOperandClass { let Name = "Imm0_255"; }
450 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
451   return ((uint32_t)Imm) < 256;
452 }]> {
453   let ParserMatchClass = Imm0_255Operand;
454   let PrintMethod = "printHexImm";
455 }
456
457 // imm0_127 predicate - True if the immediate is in the range [0,127]
458 def Imm0_127Operand : AsmOperandClass { let Name = "Imm0_127"; }
459 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
460   return ((uint32_t)Imm) < 128;
461 }]> {
462   let ParserMatchClass = Imm0_127Operand;
463   let PrintMethod = "printHexImm";
464 }
465
466 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
467 // for all shift-amounts.
468
469 // imm0_63 predicate - True if the immediate is in the range [0,63]
470 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
471   return ((uint64_t)Imm) < 64;
472 }]> {
473   let ParserMatchClass = Imm0_63Operand;
474 }
475
476 // imm0_31 predicate - True if the immediate is in the range [0,31]
477 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
478   return ((uint64_t)Imm) < 32;
479 }]> {
480   let ParserMatchClass = Imm0_31Operand;
481 }
482
483 // imm0_15 predicate - True if the immediate is in the range [0,15]
484 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
485   return ((uint64_t)Imm) < 16;
486 }]> {
487   let ParserMatchClass = Imm0_15Operand;
488 }
489
490 // imm0_7 predicate - True if the immediate is in the range [0,7]
491 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
492   return ((uint64_t)Imm) < 8;
493 }]> {
494   let ParserMatchClass = Imm0_7Operand;
495 }
496
497 // An arithmetic shifter operand:
498 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
499 //  {5-0} - imm6
500 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
501   let PrintMethod = "printShifter";
502   let ParserMatchClass = !cast<AsmOperandClass>(
503                          "ArithmeticShifterOperand" # width);
504 }
505
506 def arith_shift32 : arith_shift<i32, 32>;
507 def arith_shift64 : arith_shift<i64, 64>;
508
509 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
510     : Operand<Ty>,
511       ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
512   let PrintMethod = "printShiftedRegister";
513   let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
514 }
515
516 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
517 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
518
519 // An arithmetic shifter operand:
520 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
521 //  {5-0} - imm6
522 def logical_shift : Operand<i32> {
523   let PrintMethod = "printShifter";
524   let ParserMatchClass = ShifterOperand;
525 }
526
527 class logical_shifted_reg<ValueType Ty, RegisterClass regclass>
528     : Operand<Ty>,
529       ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
530   let PrintMethod = "printShiftedRegister";
531   let MIOperandInfo = (ops regclass, logical_shift);
532 }
533
534 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32>;
535 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64>;
536
537 // A logical vector shifter operand:
538 //  {7-6} - shift type: 00 = lsl
539 //  {5-0} - imm6: #0, #8, #16, or #24
540 def logical_vec_shift : Operand<i32> {
541   let PrintMethod = "printShifter";
542   let EncoderMethod = "getVecShifterOpValue";
543   let ParserMatchClass = LogicalVecShifterOperand;
544 }
545
546 // A logical vector half-word shifter operand:
547 //  {7-6} - shift type: 00 = lsl
548 //  {5-0} - imm6: #0 or #8
549 def logical_vec_hw_shift : Operand<i32> {
550   let PrintMethod = "printShifter";
551   let EncoderMethod = "getVecShifterOpValue";
552   let ParserMatchClass = LogicalVecHalfWordShifterOperand;
553 }
554
555 // A vector move shifter operand:
556 //  {0} - imm1: #8 or #16
557 def move_vec_shift : Operand<i32> {
558   let PrintMethod = "printShifter";
559   let EncoderMethod = "getMoveVecShifterOpValue";
560   let ParserMatchClass = MoveVecShifterOperand;
561 }
562
563 def AddSubImmOperand : AsmOperandClass {
564   let Name = "AddSubImm";
565   let ParserMethod = "tryParseAddSubImm";
566   let DiagnosticType = "AddSubSecondSource";
567 }
568 // An ADD/SUB immediate shifter operand:
569 //  second operand:
570 //  {7-6} - shift type: 00 = lsl
571 //  {5-0} - imm6: #0 or #12
572 class addsub_shifted_imm<ValueType Ty>
573     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
574   let PrintMethod = "printAddSubImm";
575   let EncoderMethod = "getAddSubImmOpValue";
576   let ParserMatchClass = AddSubImmOperand;
577   let MIOperandInfo = (ops i32imm, i32imm);
578 }
579
580 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
581 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
582
583 class neg_addsub_shifted_imm<ValueType Ty>
584     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
585   let PrintMethod = "printAddSubImm";
586   let EncoderMethod = "getAddSubImmOpValue";
587   let ParserMatchClass = AddSubImmOperand;
588   let MIOperandInfo = (ops i32imm, i32imm);
589 }
590
591 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
592 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
593
594 // An extend operand:
595 //  {5-3} - extend type
596 //  {2-0} - imm3
597 def arith_extend : Operand<i32> {
598   let PrintMethod = "printExtend";
599   let ParserMatchClass = ExtendOperand;
600 }
601 def arith_extend64 : Operand<i32> {
602   let PrintMethod = "printExtend";
603   let ParserMatchClass = ExtendOperand64;
604 }
605
606 // 'extend' that's a lsl of a 64-bit register.
607 def arith_extendlsl64 : Operand<i32> {
608   let PrintMethod = "printExtend";
609   let ParserMatchClass = ExtendOperandLSL64;
610 }
611
612 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
613                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
614   let PrintMethod = "printExtendedRegister";
615   let MIOperandInfo = (ops GPR32, arith_extend);
616 }
617
618 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
619                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
620   let PrintMethod = "printExtendedRegister";
621   let MIOperandInfo = (ops GPR32, arith_extend64);
622 }
623
624 // Floating-point immediate.
625 def fpimm32 : Operand<f32>,
626               PatLeaf<(f32 fpimm), [{
627       return ARM64_AM::getFP32Imm(N->getValueAPF()) != -1;
628     }], SDNodeXForm<fpimm, [{
629       APFloat InVal = N->getValueAPF();
630       uint32_t enc = ARM64_AM::getFP32Imm(InVal);
631       return CurDAG->getTargetConstant(enc, MVT::i32);
632     }]>> {
633   let ParserMatchClass = FPImmOperand;
634   let PrintMethod = "printFPImmOperand";
635 }
636 def fpimm64 : Operand<f64>,
637               PatLeaf<(f64 fpimm), [{
638       return ARM64_AM::getFP64Imm(N->getValueAPF()) != -1;
639     }], SDNodeXForm<fpimm, [{
640       APFloat InVal = N->getValueAPF();
641       uint32_t enc = ARM64_AM::getFP64Imm(InVal);
642       return CurDAG->getTargetConstant(enc, MVT::i32);
643     }]>> {
644   let ParserMatchClass = FPImmOperand;
645   let PrintMethod = "printFPImmOperand";
646 }
647
648 def fpimm8 : Operand<i32> {
649   let ParserMatchClass = FPImmOperand;
650   let PrintMethod = "printFPImmOperand";
651 }
652
653 def fpimm0 : PatLeaf<(fpimm), [{
654   return N->isExactlyValue(+0.0);
655 }]>;
656
657 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
658 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
659 // are encoded as the eight bit value 'abcdefgh'.
660 def simdimmtype10 : Operand<i32>,
661                     PatLeaf<(f64 fpimm), [{
662       return ARM64_AM::isAdvSIMDModImmType10(N->getValueAPF()
663                                                .bitcastToAPInt()
664                                                .getZExtValue());
665     }], SDNodeXForm<fpimm, [{
666       APFloat InVal = N->getValueAPF();
667       uint32_t enc = ARM64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
668                                                            .bitcastToAPInt()
669                                                            .getZExtValue());
670       return CurDAG->getTargetConstant(enc, MVT::i32);
671     }]>> {
672   let ParserMatchClass = SIMDImmType10Operand;
673   let PrintMethod = "printSIMDType10Operand";
674 }
675
676
677 //---
678 // System management
679 //---
680
681 // Base encoding for system instruction operands.
682 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
683 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands>
684     : I<oops, iops, asm, operands, "", []> {
685   let Inst{31-22} = 0b1101010100;
686   let Inst{21}    = L;
687 }
688
689 // System instructions which do not have an Rt register.
690 class SimpleSystemI<bit L, dag iops, string asm, string operands>
691     : BaseSystemI<L, (outs), iops, asm, operands> {
692   let Inst{4-0} = 0b11111;
693 }
694
695 // System instructions which have an Rt register.
696 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
697     : BaseSystemI<L, oops, iops, asm, operands>,
698       Sched<[WriteSys]> {
699   bits<5> Rt;
700   let Inst{4-0} = Rt;
701 }
702
703 // Hint instructions that take both a CRm and a 3-bit immediate.
704 class HintI<string mnemonic>
705     : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#" $imm", "">,
706       Sched<[WriteHint]> {
707   bits <7> imm;
708   let Inst{20-12} = 0b000110010;
709   let Inst{11-5} = imm;
710 }
711
712 // System instructions taking a single literal operand which encodes into
713 // CRm. op2 differentiates the opcodes.
714 def BarrierAsmOperand : AsmOperandClass {
715   let Name = "Barrier";
716   let ParserMethod = "tryParseBarrierOperand";
717 }
718 def barrier_op : Operand<i32> {
719   let PrintMethod = "printBarrierOption";
720   let ParserMatchClass = BarrierAsmOperand;
721 }
722 class CRmSystemI<Operand crmtype, bits<3> opc, string asm>
723     : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm">,
724       Sched<[WriteBarrier]> {
725   bits<4> CRm;
726   let Inst{20-12} = 0b000110011;
727   let Inst{11-8} = CRm;
728   let Inst{7-5} = opc;
729 }
730
731 // MRS/MSR system instructions. These have different operand classes because
732 // a different subset of registers can be accessed through each instruction.
733 def MRSSystemRegisterOperand : AsmOperandClass {
734   let Name = "MRSSystemRegister";
735   let ParserMethod = "tryParseSysReg";
736   let DiagnosticType = "MRS";
737 }
738 // concatenation of 1, op0, op1, CRn, CRm, op2. 16-bit immediate.
739 def mrs_sysreg_op : Operand<i32> {
740   let ParserMatchClass = MRSSystemRegisterOperand;
741   let DecoderMethod = "DecodeMRSSystemRegister";
742   let PrintMethod = "printMRSSystemRegister";
743 }
744
745 def MSRSystemRegisterOperand : AsmOperandClass {
746   let Name = "MSRSystemRegister";
747   let ParserMethod = "tryParseSysReg";
748   let DiagnosticType = "MSR";
749 }
750 def msr_sysreg_op : Operand<i32> {
751   let ParserMatchClass = MSRSystemRegisterOperand;
752   let DecoderMethod = "DecodeMSRSystemRegister";
753   let PrintMethod = "printMSRSystemRegister";
754 }
755
756 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
757                        "mrs", "\t$Rt, $systemreg"> {
758   bits<15> systemreg;
759   let Inst{20} = 1;
760   let Inst{19-5} = systemreg;
761 }
762
763 // FIXME: Some of these def NZCV, others don't. Best way to model that?
764 // Explicitly modeling each of the system register as a register class
765 // would do it, but feels like overkill at this point.
766 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
767                        "msr", "\t$systemreg, $Rt"> {
768   bits<15> systemreg;
769   let Inst{20} = 1;
770   let Inst{19-5} = systemreg;
771 }
772
773 def SystemPStateFieldOperand : AsmOperandClass {
774   let Name = "SystemPStateField";
775   let ParserMethod = "tryParseSysReg";
776 }
777 def pstatefield_op : Operand<i32> {
778   let ParserMatchClass = SystemPStateFieldOperand;
779   let PrintMethod = "printSystemPStateField";
780 }
781
782 let Defs = [NZCV] in
783 class MSRpstateI
784   : SimpleSystemI<0, (ins pstatefield_op:$pstate_field, imm0_15:$imm),
785                   "msr", "\t$pstate_field, $imm">,
786     Sched<[WriteSys]> {
787   bits<6> pstatefield;
788   bits<4> imm;
789   let Inst{20-19} = 0b00;
790   let Inst{18-16} = pstatefield{5-3};
791   let Inst{15-12} = 0b0100;
792   let Inst{11-8} = imm;
793   let Inst{7-5} = pstatefield{2-0};
794
795   let DecoderMethod = "DecodeSystemPStateInstruction";
796 }
797
798 // SYS and SYSL generic system instructions.
799 def SysCRAsmOperand : AsmOperandClass {
800   let Name = "SysCR";
801   let ParserMethod = "tryParseSysCROperand";
802 }
803
804 def sys_cr_op : Operand<i32> {
805   let PrintMethod = "printSysCROperand";
806   let ParserMatchClass = SysCRAsmOperand;
807 }
808
809 class SystemXtI<bit L, string asm>
810   : RtSystemI<L, (outs),
811        (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
812        asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
813   bits<3> op1;
814   bits<4> Cn;
815   bits<4> Cm;
816   bits<3> op2;
817   let Inst{20-19} = 0b01;
818   let Inst{18-16} = op1;
819   let Inst{15-12} = Cn;
820   let Inst{11-8}  = Cm;
821   let Inst{7-5}   = op2;
822 }
823
824 class SystemLXtI<bit L, string asm>
825   : RtSystemI<L, (outs),
826        (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
827        asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
828   bits<3> op1;
829   bits<4> Cn;
830   bits<4> Cm;
831   bits<3> op2;
832   let Inst{20-19} = 0b01;
833   let Inst{18-16} = op1;
834   let Inst{15-12} = Cn;
835   let Inst{11-8}  = Cm;
836   let Inst{7-5}   = op2;
837 }
838
839
840 // Branch (register) instructions:
841 //
842 //  case opc of
843 //    0001 blr
844 //    0000 br
845 //    0101 dret
846 //    0100 eret
847 //    0010 ret
848 //    otherwise UNDEFINED
849 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
850                     string operands, list<dag> pattern>
851     : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
852   let Inst{31-25} = 0b1101011;
853   let Inst{24-21} = opc;
854   let Inst{20-16} = 0b11111;
855   let Inst{15-10} = 0b000000;
856   let Inst{4-0}   = 0b00000;
857 }
858
859 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
860     : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
861   bits<5> Rn;
862   let Inst{9-5} = Rn;
863 }
864
865 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
866 class SpecialReturn<bits<4> opc, string asm>
867     : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
868   let Inst{9-5} = 0b11111;
869 }
870
871 //---
872 // Conditional branch instruction.
873 //---
874 // Branch condition code.
875 // 4-bit immediate. Pretty-printed as .<cc>
876 def dotCcode : Operand<i32> {
877   let PrintMethod = "printDotCondCode";
878 }
879
880 // Conditional branch target. 19-bit immediate. The low two bits of the target
881 // offset are implied zero and so are not part of the immediate.
882 def PCRelLabel19Operand : AsmOperandClass {
883   let Name = "PCRelLabel19";
884 }
885 def am_brcond : Operand<OtherVT> {
886   let EncoderMethod = "getCondBranchTargetOpValue";
887   let DecoderMethod = "DecodePCRelLabel19";
888   let PrintMethod = "printAlignedLabel";
889   let ParserMatchClass = PCRelLabel19Operand;
890 }
891
892 class BranchCond : I<(outs), (ins dotCcode:$cond, am_brcond:$target),
893                      "b", "$cond\t$target", "",
894                      [(ARM64brcond bb:$target, imm:$cond, NZCV)]>,
895                    Sched<[WriteBr]> {
896   let isBranch = 1;
897   let isTerminator = 1;
898   let Uses = [NZCV];
899
900   bits<4> cond;
901   bits<19> target;
902   let Inst{31-24} = 0b01010100;
903   let Inst{23-5} = target;
904   let Inst{4} = 0;
905   let Inst{3-0} = cond;
906 }
907
908 //---
909 // Compare-and-branch instructions.
910 //---
911 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
912     : I<(outs), (ins regtype:$Rt, am_brcond:$target),
913          asm, "\t$Rt, $target", "",
914          [(node regtype:$Rt, bb:$target)]>,
915       Sched<[WriteBr]> {
916   let isBranch = 1;
917   let isTerminator = 1;
918
919   bits<5> Rt;
920   bits<19> target;
921   let Inst{30-25} = 0b011010;
922   let Inst{24}    = op;
923   let Inst{23-5}  = target;
924   let Inst{4-0}   = Rt;
925 }
926
927 multiclass CmpBranch<bit op, string asm, SDNode node> {
928   def W : BaseCmpBranch<GPR32, op, asm, node> {
929     let Inst{31} = 0;
930   }
931   def X : BaseCmpBranch<GPR64, op, asm, node> {
932     let Inst{31} = 1;
933   }
934 }
935
936 //---
937 // Test-bit-and-branch instructions.
938 //---
939 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
940 // the target offset are implied zero and so are not part of the immediate.
941 def BranchTarget14Operand : AsmOperandClass {
942   let Name = "BranchTarget14";
943 }
944 def am_tbrcond : Operand<OtherVT> {
945   let EncoderMethod = "getTestBranchTargetOpValue";
946   let PrintMethod = "printAlignedLabel";
947   let ParserMatchClass = BranchTarget14Operand;
948 }
949
950 class TestBranch<bit op, string asm, SDNode node>
951     : I<(outs), (ins GPR64:$Rt, imm0_63:$bit_off, am_tbrcond:$target),
952        asm, "\t$Rt, $bit_off, $target", "",
953        [(node GPR64:$Rt, imm0_63:$bit_off, bb:$target)]>,
954       Sched<[WriteBr]> {
955   let isBranch = 1;
956   let isTerminator = 1;
957
958   bits<5> Rt;
959   bits<6> bit_off;
960   bits<14> target;
961
962   let Inst{31}    = bit_off{5};
963   let Inst{30-25} = 0b011011;
964   let Inst{24}    = op;
965   let Inst{23-19} = bit_off{4-0};
966   let Inst{18-5}  = target;
967   let Inst{4-0}   = Rt;
968
969   let DecoderMethod = "DecodeTestAndBranch";
970 }
971
972 //---
973 // Unconditional branch (immediate) instructions.
974 //---
975 def BranchTarget26Operand : AsmOperandClass {
976   let Name = "BranchTarget26";
977 }
978 def am_b_target : Operand<OtherVT> {
979   let EncoderMethod = "getBranchTargetOpValue";
980   let PrintMethod = "printAlignedLabel";
981   let ParserMatchClass = BranchTarget26Operand;
982 }
983 def am_bl_target : Operand<i64> {
984   let EncoderMethod = "getBranchTargetOpValue";
985   let PrintMethod = "printAlignedLabel";
986   let ParserMatchClass = BranchTarget26Operand;
987 }
988
989 class BImm<bit op, dag iops, string asm, list<dag> pattern>
990     : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
991   bits<26> addr;
992   let Inst{31}    = op;
993   let Inst{30-26} = 0b00101;
994   let Inst{25-0}  = addr;
995
996   let DecoderMethod = "DecodeUnconditionalBranch";
997 }
998
999 class BranchImm<bit op, string asm, list<dag> pattern>
1000     : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1001 class CallImm<bit op, string asm, list<dag> pattern>
1002     : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1003
1004 //---
1005 // Basic one-operand data processing instructions.
1006 //---
1007
1008 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1009 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1010                          SDPatternOperator node>
1011   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1012       [(set regtype:$Rd, (node regtype:$Rn))]>,
1013     Sched<[WriteI]> {
1014   bits<5> Rd;
1015   bits<5> Rn;
1016
1017   let Inst{30-13} = 0b101101011000000000;
1018   let Inst{12-10} = opc;
1019   let Inst{9-5}   = Rn;
1020   let Inst{4-0}   = Rd;
1021 }
1022
1023 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1024 multiclass OneOperandData<bits<3> opc, string asm,
1025                           SDPatternOperator node = null_frag> {
1026   def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1027     let Inst{31} = 0;
1028   }
1029
1030   def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1031     let Inst{31} = 1;
1032   }
1033 }
1034
1035 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1036     : BaseOneOperandData<opc, GPR32, asm, node> {
1037   let Inst{31} = 0;
1038 }
1039
1040 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1041     : BaseOneOperandData<opc, GPR64, asm, node> {
1042   let Inst{31} = 1;
1043 }
1044
1045 //---
1046 // Basic two-operand data processing instructions.
1047 //---
1048 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1049                           list<dag> pattern>
1050     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1051         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1052       Sched<[WriteI]> {
1053   let Uses = [NZCV];
1054   bits<5> Rd;
1055   bits<5> Rn;
1056   bits<5> Rm;
1057   let Inst{30}    = isSub;
1058   let Inst{28-21} = 0b11010000;
1059   let Inst{20-16} = Rm;
1060   let Inst{15-10} = 0;
1061   let Inst{9-5}   = Rn;
1062   let Inst{4-0}   = Rd;
1063 }
1064
1065 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1066                       SDNode OpNode>
1067     : BaseBaseAddSubCarry<isSub, regtype, asm,
1068         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1069
1070 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1071                               SDNode OpNode>
1072     : BaseBaseAddSubCarry<isSub, regtype, asm,
1073         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1074          (implicit NZCV)]> {
1075   let Defs = [NZCV];
1076 }
1077
1078 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1079                        SDNode OpNode, SDNode OpNode_setflags> {
1080   def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1081     let Inst{31} = 0;
1082     let Inst{29} = 0;
1083   }
1084   def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1085     let Inst{31} = 1;
1086     let Inst{29} = 0;
1087   }
1088
1089   // Sets flags.
1090   def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1091                                     OpNode_setflags> {
1092     let Inst{31} = 0;
1093     let Inst{29} = 1;
1094   }
1095   def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1096                                     OpNode_setflags> {
1097     let Inst{31} = 1;
1098     let Inst{29} = 1;
1099   }
1100 }
1101
1102 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1103                      SDPatternOperator OpNode>
1104   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1105       asm, "\t$Rd, $Rn, $Rm", "",
1106       [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
1107   bits<5> Rd;
1108   bits<5> Rn;
1109   bits<5> Rm;
1110   let Inst{30-21} = 0b0011010110;
1111   let Inst{20-16} = Rm;
1112   let Inst{15-14} = 0b00;
1113   let Inst{13-10} = opc;
1114   let Inst{9-5}   = Rn;
1115   let Inst{4-0}   = Rd;
1116 }
1117
1118 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1119               SDPatternOperator OpNode>
1120     : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1121   let Inst{10}    = isSigned;
1122 }
1123
1124 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1125   def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1126            Sched<[WriteID32]> {
1127     let Inst{31} = 0;
1128   }
1129   def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1130            Sched<[WriteID64]> {
1131     let Inst{31} = 1;
1132   }
1133 }
1134
1135 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1136                 SDPatternOperator OpNode = null_frag>
1137   : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1138     Sched<[WriteIS]> {
1139   let Inst{11-10} = shift_type;
1140 }
1141
1142 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
1143   def Wr : BaseShift<shift_type, GPR32, asm> {
1144     let Inst{31} = 0;
1145   }
1146
1147   def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1148     let Inst{31} = 1;
1149   }
1150
1151   def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1152             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1153                                              (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1154
1155   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1156             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1157
1158   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1159             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1160
1161   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1162             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1163 }
1164
1165 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
1166     : InstAlias<asm#" $dst, $src1, $src2",
1167                 (inst regtype:$dst, regtype:$src1, regtype:$src2)>;
1168
1169 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1170                        RegisterClass addtype, string asm,
1171                        list<dag> pattern>
1172   : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1173       asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1174   bits<5> Rd;
1175   bits<5> Rn;
1176   bits<5> Rm;
1177   bits<5> Ra;
1178   let Inst{30-24} = 0b0011011;
1179   let Inst{23-21} = opc;
1180   let Inst{20-16} = Rm;
1181   let Inst{15}    = isSub;
1182   let Inst{14-10} = Ra;
1183   let Inst{9-5}   = Rn;
1184   let Inst{4-0}   = Rd;
1185 }
1186
1187 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
1188   def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
1189       [(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))]>,
1190       Sched<[WriteIM32]> {
1191     let Inst{31} = 0;
1192   }
1193
1194   def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
1195       [(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))]>,
1196       Sched<[WriteIM64]> {
1197     let Inst{31} = 1;
1198   }
1199 }
1200
1201 class WideMulAccum<bit isSub, bits<3> opc, string asm,
1202                    SDNode AccNode, SDNode ExtNode>
1203   : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
1204     [(set GPR64:$Rd, (AccNode GPR64:$Ra,
1205                             (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
1206     Sched<[WriteIM32]> {
1207   let Inst{31} = 1;
1208 }
1209
1210 class MulHi<bits<3> opc, string asm, SDNode OpNode>
1211   : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
1212       asm, "\t$Rd, $Rn, $Rm", "",
1213       [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
1214     Sched<[WriteIM64]> {
1215   bits<5> Rd;
1216   bits<5> Rn;
1217   bits<5> Rm;
1218   let Inst{31-24} = 0b10011011;
1219   let Inst{23-21} = opc;
1220   let Inst{20-16} = Rm;
1221   let Inst{15}    = 0;
1222   let Inst{9-5}   = Rn;
1223   let Inst{4-0}   = Rd;
1224
1225   // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
1226   // (i.e. all bits 1) but is ignored by the processor.
1227   let PostEncoderMethod = "fixMulHigh";
1228 }
1229
1230 class MulAccumWAlias<string asm, Instruction inst>
1231     : InstAlias<asm#" $dst, $src1, $src2",
1232                 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
1233 class MulAccumXAlias<string asm, Instruction inst>
1234     : InstAlias<asm#" $dst, $src1, $src2",
1235                 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
1236 class WideMulAccumAlias<string asm, Instruction inst>
1237     : InstAlias<asm#" $dst, $src1, $src2",
1238                 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
1239
1240 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
1241               SDPatternOperator OpNode, string asm>
1242   : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
1243       asm, "\t$Rd, $Rn, $Rm", "",
1244       [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
1245     Sched<[WriteISReg]> {
1246   bits<5> Rd;
1247   bits<5> Rn;
1248   bits<5> Rm;
1249
1250   let Inst{31} = sf;
1251   let Inst{30-21} = 0b0011010110;
1252   let Inst{20-16} = Rm;
1253   let Inst{15-13} = 0b010;
1254   let Inst{12} = C;
1255   let Inst{11-10} = sz;
1256   let Inst{9-5} = Rn;
1257   let Inst{4-0} = Rd;
1258   let Predicates = [HasCRC];
1259 }
1260
1261 //---
1262 // Address generation.
1263 //---
1264
1265 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
1266     : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
1267         pattern>,
1268       Sched<[WriteI]> {
1269   bits<5>  Xd;
1270   bits<21> label;
1271   let Inst{31}    = page;
1272   let Inst{30-29} = label{1-0};
1273   let Inst{28-24} = 0b10000;
1274   let Inst{23-5}  = label{20-2};
1275   let Inst{4-0}   = Xd;
1276
1277   let DecoderMethod = "DecodeAdrInstruction";
1278 }
1279
1280 //---
1281 // Move immediate.
1282 //---
1283
1284 def movimm32_imm : Operand<i32> {
1285   let ParserMatchClass = Imm0_65535Operand;
1286   let EncoderMethod = "getMoveWideImmOpValue";
1287   let PrintMethod = "printHexImm";
1288 }
1289 def movimm32_shift : Operand<i32> {
1290   let PrintMethod = "printShifter";
1291   let ParserMatchClass = MovImm32ShifterOperand;
1292 }
1293 def movimm64_shift : Operand<i32> {
1294   let PrintMethod = "printShifter";
1295   let ParserMatchClass = MovImm64ShifterOperand;
1296 }
1297 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1298 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1299                         string asm>
1300   : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
1301        asm, "\t$Rd, $imm$shift", "", []>,
1302     Sched<[WriteImm]> {
1303   bits<5> Rd;
1304   bits<16> imm;
1305   bits<6> shift;
1306   let Inst{30-29} = opc;
1307   let Inst{28-23} = 0b100101;
1308   let Inst{22-21} = shift{5-4};
1309   let Inst{20-5}  = imm;
1310   let Inst{4-0}   = Rd;
1311
1312   let DecoderMethod = "DecodeMoveImmInstruction";
1313 }
1314
1315 multiclass MoveImmediate<bits<2> opc, string asm> {
1316   def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
1317     let Inst{31} = 0;
1318   }
1319
1320   def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
1321     let Inst{31} = 1;
1322   }
1323 }
1324
1325 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1326 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1327                           string asm>
1328   : I<(outs regtype:$Rd),
1329       (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
1330        asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
1331     Sched<[WriteI]> {
1332   bits<5> Rd;
1333   bits<16> imm;
1334   bits<6> shift;
1335   let Inst{30-29} = opc;
1336   let Inst{28-23} = 0b100101;
1337   let Inst{22-21} = shift{5-4};
1338   let Inst{20-5}  = imm;
1339   let Inst{4-0}   = Rd;
1340
1341   let DecoderMethod = "DecodeMoveImmInstruction";
1342 }
1343
1344 multiclass InsertImmediate<bits<2> opc, string asm> {
1345   def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
1346     let Inst{31} = 0;
1347   }
1348
1349   def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
1350     let Inst{31} = 1;
1351   }
1352 }
1353
1354 //---
1355 // Add/Subtract
1356 //---
1357
1358 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
1359                     RegisterClass srcRegtype, addsub_shifted_imm immtype,
1360                     string asm, SDPatternOperator OpNode>
1361     : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
1362         asm, "\t$Rd, $Rn, $imm", "",
1363         [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
1364       Sched<[WriteI]>  {
1365   bits<5>  Rd;
1366   bits<5>  Rn;
1367   bits<14> imm;
1368   let Inst{30}    = isSub;
1369   let Inst{29}    = setFlags;
1370   let Inst{28-24} = 0b10001;
1371   let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
1372   let Inst{21-10} = imm{11-0};
1373   let Inst{9-5}   = Rn;
1374   let Inst{4-0}   = Rd;
1375   let DecoderMethod = "DecodeBaseAddSubImm";
1376 }
1377
1378 class BaseAddSubRegPseudo<RegisterClass regtype,
1379                           SDPatternOperator OpNode>
1380     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1381              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1382       Sched<[WriteI]>;
1383
1384 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
1385                      arith_shifted_reg shifted_regtype, string asm,
1386                      SDPatternOperator OpNode>
1387     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1388         asm, "\t$Rd, $Rn, $Rm", "",
1389         [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
1390       Sched<[WriteISReg]> {
1391   // The operands are in order to match the 'addr' MI operands, so we
1392   // don't need an encoder method and by-name matching. Just use the default
1393   // in-order handling. Since we're using by-order, make sure the names
1394   // do not match.
1395   bits<5> dst;
1396   bits<5> src1;
1397   bits<5> src2;
1398   bits<8> shift;
1399   let Inst{30}    = isSub;
1400   let Inst{29}    = setFlags;
1401   let Inst{28-24} = 0b01011;
1402   let Inst{23-22} = shift{7-6};
1403   let Inst{21}    = 0;
1404   let Inst{20-16} = src2;
1405   let Inst{15-10} = shift{5-0};
1406   let Inst{9-5}   = src1;
1407   let Inst{4-0}   = dst;
1408
1409   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1410 }
1411
1412 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
1413                      RegisterClass src1Regtype, Operand src2Regtype,
1414                      string asm, SDPatternOperator OpNode>
1415     : I<(outs dstRegtype:$R1),
1416         (ins src1Regtype:$R2, src2Regtype:$R3),
1417         asm, "\t$R1, $R2, $R3", "",
1418         [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
1419       Sched<[WriteIEReg]> {
1420   bits<5> Rd;
1421   bits<5> Rn;
1422   bits<5> Rm;
1423   bits<6> ext;
1424   let Inst{30}    = isSub;
1425   let Inst{29}    = setFlags;
1426   let Inst{28-24} = 0b01011;
1427   let Inst{23-21} = 0b001;
1428   let Inst{20-16} = Rm;
1429   let Inst{15-13} = ext{5-3};
1430   let Inst{12-10} = ext{2-0};
1431   let Inst{9-5}   = Rn;
1432   let Inst{4-0}   = Rd;
1433
1434   let DecoderMethod = "DecodeAddSubERegInstruction";
1435 }
1436
1437 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1438 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
1439                        RegisterClass src1Regtype, RegisterClass src2Regtype,
1440                        Operand ext_op, string asm>
1441     : I<(outs dstRegtype:$Rd),
1442         (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
1443         asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
1444       Sched<[WriteIEReg]> {
1445   bits<5> Rd;
1446   bits<5> Rn;
1447   bits<5> Rm;
1448   bits<6> ext;
1449   let Inst{30}    = isSub;
1450   let Inst{29}    = setFlags;
1451   let Inst{28-24} = 0b01011;
1452   let Inst{23-21} = 0b001;
1453   let Inst{20-16} = Rm;
1454   let Inst{15}    = ext{5};
1455   let Inst{12-10} = ext{2-0};
1456   let Inst{9-5}   = Rn;
1457   let Inst{4-0}   = Rd;
1458
1459   let DecoderMethod = "DecodeAddSubERegInstruction";
1460 }
1461
1462 // Aliases for register+register add/subtract.
1463 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
1464                      RegisterClass src1Regtype, RegisterClass src2Regtype,
1465                      int shiftExt>
1466     : InstAlias<asm#" $dst, $src1, $src2",
1467                 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
1468                       shiftExt)>;
1469
1470 multiclass AddSub<bit isSub, string mnemonic,
1471                   SDPatternOperator OpNode = null_frag> {
1472   let hasSideEffects = 0 in {
1473   // Add/Subtract immediate
1474   def Wri  : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
1475                            mnemonic, OpNode> {
1476     let Inst{31} = 0;
1477   }
1478   def Xri  : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
1479                            mnemonic, OpNode> {
1480     let Inst{31} = 1;
1481   }
1482
1483   // Add/Subtract register - Only used for CodeGen
1484   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1485   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1486
1487   // Add/Subtract shifted register
1488   def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
1489                            OpNode> {
1490     let Inst{31} = 0;
1491   }
1492   def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
1493                            OpNode> {
1494     let Inst{31} = 1;
1495   }
1496   }
1497
1498   // Add/Subtract extended register
1499   let AddedComplexity = 1, hasSideEffects = 0 in {
1500   def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
1501                            arith_extended_reg32<i32>, mnemonic, OpNode> {
1502     let Inst{31} = 0;
1503   }
1504   def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
1505                            arith_extended_reg32to64<i64>, mnemonic, OpNode> {
1506     let Inst{31} = 1;
1507   }
1508   }
1509
1510   def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
1511                                arith_extendlsl64, mnemonic> {
1512     // UXTX and SXTX only.
1513     let Inst{14-13} = 0b11;
1514     let Inst{31} = 1;
1515   }
1516
1517   // Register/register aliases with no shift when SP is not used.
1518   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1519                        GPR32, GPR32, GPR32, 0>;
1520   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1521                        GPR64, GPR64, GPR64, 0>;
1522
1523   // Register/register aliases with no shift when either the destination or
1524   // first source register is SP.  This relies on the shifted register aliases
1525   // above matching first in the case when SP is not used.
1526   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1527                        GPR32sp, GPR32sp, GPR32, 16>; // UXTW #0
1528   def : AddSubRegAlias<mnemonic,
1529                        !cast<Instruction>(NAME#"Xrx64"),
1530                        GPR64sp, GPR64sp, GPR64, 24>; // UXTX #0
1531 }
1532
1533 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp> {
1534   let isCompare = 1, Defs = [NZCV] in {
1535   // Add/Subtract immediate
1536   def Wri  : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
1537                            mnemonic, OpNode> {
1538     let Inst{31} = 0;
1539   }
1540   def Xri  : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
1541                            mnemonic, OpNode> {
1542     let Inst{31} = 1;
1543   }
1544
1545   // Add/Subtract register
1546   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1547   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1548
1549   // Add/Subtract shifted register
1550   def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
1551                            OpNode> {
1552     let Inst{31} = 0;
1553   }
1554   def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
1555                            OpNode> {
1556     let Inst{31} = 1;
1557   }
1558
1559   // Add/Subtract extended register
1560   let AddedComplexity = 1 in {
1561   def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
1562                            arith_extended_reg32<i32>, mnemonic, OpNode> {
1563     let Inst{31} = 0;
1564   }
1565   def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
1566                            arith_extended_reg32<i64>, mnemonic, OpNode> {
1567     let Inst{31} = 1;
1568   }
1569   }
1570
1571   def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
1572                                arith_extendlsl64, mnemonic> {
1573     // UXTX and SXTX only.
1574     let Inst{14-13} = 0b11;
1575     let Inst{31} = 1;
1576   }
1577   } // Defs = [NZCV]
1578
1579   // Compare aliases
1580   def : InstAlias<cmp#" $src, $imm", (!cast<Instruction>(NAME#"Wri")
1581                   WZR, GPR32sp:$src, addsub_shifted_imm32:$imm)>;
1582   def : InstAlias<cmp#" $src, $imm", (!cast<Instruction>(NAME#"Xri")
1583                   XZR, GPR64sp:$src, addsub_shifted_imm64:$imm)>;
1584   def : InstAlias<cmp#" $src1, $src2, $sh", (!cast<Instruction>(NAME#"Wrx")
1585                   WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh)>;
1586   def : InstAlias<cmp#" $src1, $src2, $sh", (!cast<Instruction>(NAME#"Xrx")
1587                   XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh)>;
1588   def : InstAlias<cmp#" $src1, $src2, $sh", (!cast<Instruction>(NAME#"Xrx64")
1589                   XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh)>;
1590   def : InstAlias<cmp#" $src1, $src2, $sh", (!cast<Instruction>(NAME#"Wrs")
1591                   WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh)>;
1592   def : InstAlias<cmp#" $src1, $src2, $sh", (!cast<Instruction>(NAME#"Xrs")
1593                   XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh)>;
1594
1595   // Compare shorthands
1596   def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Wrs")
1597                   WZR, GPR32:$src1, GPR32:$src2, 0)>;
1598   def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Xrs")
1599                   XZR, GPR64:$src1, GPR64:$src2, 0)>;
1600
1601   // Register/register aliases with no shift when SP is not used.
1602   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1603                        GPR32, GPR32, GPR32, 0>;
1604   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1605                        GPR64, GPR64, GPR64, 0>;
1606
1607   // Register/register aliases with no shift when the first source register
1608   // is SP.  This relies on the shifted register aliases above matching first
1609   // in the case when SP is not used.
1610   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1611                        GPR32, GPR32sp, GPR32, 16>; // UXTW #0
1612   def : AddSubRegAlias<mnemonic,
1613                        !cast<Instruction>(NAME#"Xrx64"),
1614                        GPR64, GPR64sp, GPR64, 24>; // UXTX #0
1615 }
1616
1617 //---
1618 // Extract
1619 //---
1620 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1621                                       SDTCisPtrTy<3>]>;
1622 def ARM64Extr : SDNode<"ARM64ISD::EXTR", SDTA64EXTR>;
1623
1624 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
1625                      list<dag> patterns>
1626     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
1627          asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
1628       Sched<[WriteExtr, ReadExtrHi]> {
1629   bits<5> Rd;
1630   bits<5> Rn;
1631   bits<5> Rm;
1632   bits<6> imm;
1633
1634   let Inst{30-23} = 0b00100111;
1635   let Inst{21}    = 0;
1636   let Inst{20-16} = Rm;
1637   let Inst{15-10} = imm;
1638   let Inst{9-5}   = Rn;
1639   let Inst{4-0}   = Rd;
1640 }
1641
1642 multiclass ExtractImm<string asm> {
1643   def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
1644                       [(set GPR32:$Rd,
1645                         (ARM64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
1646     let Inst{31} = 0;
1647     let Inst{22} = 0;
1648     // imm<5> must be zero.
1649     let imm{5}   = 0;
1650   }
1651   def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
1652                       [(set GPR64:$Rd,
1653                         (ARM64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
1654
1655     let Inst{31} = 1;
1656     let Inst{22} = 1;
1657   }
1658 }
1659
1660 //---
1661 // Bitfield
1662 //---
1663
1664 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1665 class BaseBitfieldImm<bits<2> opc,
1666                       RegisterClass regtype, Operand imm_type, string asm>
1667     : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
1668          asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
1669       Sched<[WriteIS]> {
1670   bits<5> Rd;
1671   bits<5> Rn;
1672   bits<6> immr;
1673   bits<6> imms;
1674
1675   let Inst{30-29} = opc;
1676   let Inst{28-23} = 0b100110;
1677   let Inst{21-16} = immr;
1678   let Inst{15-10} = imms;
1679   let Inst{9-5}   = Rn;
1680   let Inst{4-0}   = Rd;
1681 }
1682
1683 multiclass BitfieldImm<bits<2> opc, string asm> {
1684   def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
1685     let Inst{31} = 0;
1686     let Inst{22} = 0;
1687     // imms<5> and immr<5> must be zero, else ReservedValue().
1688     let Inst{21} = 0;
1689     let Inst{15} = 0;
1690   }
1691   def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
1692     let Inst{31} = 1;
1693     let Inst{22} = 1;
1694   }
1695 }
1696
1697 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1698 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
1699                       RegisterClass regtype, Operand imm_type, string asm>
1700     : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
1701                              imm_type:$imms),
1702          asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
1703       Sched<[WriteIS]> {
1704   bits<5> Rd;
1705   bits<5> Rn;
1706   bits<6> immr;
1707   bits<6> imms;
1708
1709   let Inst{30-29} = opc;
1710   let Inst{28-23} = 0b100110;
1711   let Inst{21-16} = immr;
1712   let Inst{15-10} = imms;
1713   let Inst{9-5}   = Rn;
1714   let Inst{4-0}   = Rd;
1715 }
1716
1717 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
1718   def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
1719     let Inst{31} = 0;
1720     let Inst{22} = 0;
1721     // imms<5> and immr<5> must be zero, else ReservedValue().
1722     let Inst{21} = 0;
1723     let Inst{15} = 0;
1724   }
1725   def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
1726     let Inst{31} = 1;
1727     let Inst{22} = 1;
1728   }
1729 }
1730
1731 //---
1732 // Logical
1733 //---
1734
1735 // Logical (immediate)
1736 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
1737                      RegisterClass sregtype, Operand imm_type, string asm,
1738                      list<dag> pattern>
1739     : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
1740          asm, "\t$Rd, $Rn, $imm", "", pattern>,
1741       Sched<[WriteI]> {
1742   bits<5>  Rd;
1743   bits<5>  Rn;
1744   bits<13> imm;
1745   let Inst{30-29} = opc;
1746   let Inst{28-23} = 0b100100;
1747   let Inst{22}    = imm{12};
1748   let Inst{21-16} = imm{11-6};
1749   let Inst{15-10} = imm{5-0};
1750   let Inst{9-5}   = Rn;
1751   let Inst{4-0}   = Rd;
1752
1753   let DecoderMethod = "DecodeLogicalImmInstruction";
1754 }
1755
1756 // Logical (shifted register)
1757 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
1758                       logical_shifted_reg shifted_regtype, string asm,
1759                       list<dag> pattern>
1760     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1761         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1762       Sched<[WriteISReg]> {
1763   // The operands are in order to match the 'addr' MI operands, so we
1764   // don't need an encoder method and by-name matching. Just use the default
1765   // in-order handling. Since we're using by-order, make sure the names
1766   // do not match.
1767   bits<5> dst;
1768   bits<5> src1;
1769   bits<5> src2;
1770   bits<8> shift;
1771   let Inst{30-29} = opc;
1772   let Inst{28-24} = 0b01010;
1773   let Inst{23-22} = shift{7-6};
1774   let Inst{21}    = N;
1775   let Inst{20-16} = src2;
1776   let Inst{15-10} = shift{5-0};
1777   let Inst{9-5}   = src1;
1778   let Inst{4-0}   = dst;
1779
1780   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1781 }
1782
1783 // Aliases for register+register logical instructions.
1784 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
1785     : InstAlias<asm#" $dst, $src1, $src2",
1786                 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
1787
1788 let AddedComplexity = 6 in
1789 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode> {
1790   def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
1791                            [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
1792                                                logical_imm32:$imm))]> {
1793     let Inst{31} = 0;
1794     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
1795   }
1796   def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
1797                            [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
1798                                                logical_imm64:$imm))]> {
1799     let Inst{31} = 1;
1800   }
1801 }
1802
1803 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode> {
1804   let isCompare = 1, Defs = [NZCV] in {
1805   def Wri  : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
1806       [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
1807     let Inst{31} = 0;
1808     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
1809   }
1810   def Xri  : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
1811       [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
1812     let Inst{31} = 1;
1813   }
1814   } // end Defs = [NZCV]
1815 }
1816
1817 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
1818     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1819              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1820       Sched<[WriteI]>;
1821
1822 // Split from LogicalImm as not all instructions have both.
1823 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
1824                       SDPatternOperator OpNode> {
1825   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
1826   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
1827
1828   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
1829                             [(set GPR32:$Rd, (OpNode GPR32:$Rn,
1830                                                  logical_shifted_reg32:$Rm))]> {
1831     let Inst{31} = 0;
1832   }
1833   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
1834                             [(set GPR64:$Rd, (OpNode GPR64:$Rn,
1835                                                  logical_shifted_reg64:$Rm))]> {
1836     let Inst{31} = 1;
1837   }
1838
1839   def : LogicalRegAlias<mnemonic,
1840                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
1841   def : LogicalRegAlias<mnemonic,
1842                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
1843 }
1844
1845 // Split from LogicalReg to allow setting NZCV Defs
1846 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
1847                        SDPatternOperator OpNode = null_frag> {
1848   let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
1849   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
1850   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
1851
1852   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
1853             [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
1854     let Inst{31} = 0;
1855   }
1856   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
1857             [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
1858     let Inst{31} = 1;
1859   }
1860   } // Defs = [NZCV]
1861
1862   def : LogicalRegAlias<mnemonic,
1863                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
1864   def : LogicalRegAlias<mnemonic,
1865                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
1866 }
1867
1868 //---
1869 // Conditionally set flags
1870 //---
1871
1872 // Condition code.
1873 // 4-bit immediate. Pretty-printed as <cc>
1874 def ccode : Operand<i32> {
1875   let PrintMethod = "printCondCode";
1876 }
1877
1878 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1879 class BaseCondSetFlagsImm<bit op, RegisterClass regtype, string asm>
1880     : I<(outs), (ins regtype:$Rn, imm0_31:$imm, imm0_15:$nzcv, ccode:$cond),
1881          asm, "\t$Rn, $imm, $nzcv, $cond", "", []>,
1882       Sched<[WriteI]> {
1883   let Uses = [NZCV];
1884   let Defs = [NZCV];
1885
1886   bits<5> Rn;
1887   bits<5> imm;
1888   bits<4> nzcv;
1889   bits<4> cond;
1890
1891   let Inst{30}    = op;
1892   let Inst{29-21} = 0b111010010;
1893   let Inst{20-16} = imm;
1894   let Inst{15-12} = cond;
1895   let Inst{11-10} = 0b10;
1896   let Inst{9-5}   = Rn;
1897   let Inst{4}     = 0b0;
1898   let Inst{3-0}   = nzcv;
1899 }
1900
1901 multiclass CondSetFlagsImm<bit op, string asm> {
1902   def Wi : BaseCondSetFlagsImm<op, GPR32, asm> {
1903     let Inst{31} = 0;
1904   }
1905   def Xi : BaseCondSetFlagsImm<op, GPR64, asm> {
1906     let Inst{31} = 1;
1907   }
1908 }
1909
1910 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1911 class BaseCondSetFlagsReg<bit op, RegisterClass regtype, string asm>
1912     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm0_15:$nzcv, ccode:$cond),
1913          asm, "\t$Rn, $Rm, $nzcv, $cond", "", []>,
1914       Sched<[WriteI]> {
1915   let Uses = [NZCV];
1916   let Defs = [NZCV];
1917
1918   bits<5> Rn;
1919   bits<5> Rm;
1920   bits<4> nzcv;
1921   bits<4> cond;
1922
1923   let Inst{30}    = op;
1924   let Inst{29-21} = 0b111010010;
1925   let Inst{20-16} = Rm;
1926   let Inst{15-12} = cond;
1927   let Inst{11-10} = 0b00;
1928   let Inst{9-5}   = Rn;
1929   let Inst{4}     = 0b0;
1930   let Inst{3-0}   = nzcv;
1931 }
1932
1933 multiclass CondSetFlagsReg<bit op, string asm> {
1934   def Wr : BaseCondSetFlagsReg<op, GPR32, asm> {
1935     let Inst{31} = 0;
1936   }
1937   def Xr : BaseCondSetFlagsReg<op, GPR64, asm> {
1938     let Inst{31} = 1;
1939   }
1940 }
1941
1942 //---
1943 // Conditional select
1944 //---
1945
1946 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
1947     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
1948          asm, "\t$Rd, $Rn, $Rm, $cond", "",
1949          [(set regtype:$Rd,
1950                (ARM64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
1951       Sched<[WriteI]> {
1952   let Uses = [NZCV];
1953
1954   bits<5> Rd;
1955   bits<5> Rn;
1956   bits<5> Rm;
1957   bits<4> cond;
1958
1959   let Inst{30}    = op;
1960   let Inst{29-21} = 0b011010100;
1961   let Inst{20-16} = Rm;
1962   let Inst{15-12} = cond;
1963   let Inst{11-10} = op2;
1964   let Inst{9-5}   = Rn;
1965   let Inst{4-0}   = Rd;
1966 }
1967
1968 multiclass CondSelect<bit op, bits<2> op2, string asm> {
1969   def Wr : BaseCondSelect<op, op2, GPR32, asm> {
1970     let Inst{31} = 0;
1971   }
1972   def Xr : BaseCondSelect<op, op2, GPR64, asm> {
1973     let Inst{31} = 1;
1974   }
1975 }
1976
1977 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
1978                        PatFrag frag>
1979     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
1980          asm, "\t$Rd, $Rn, $Rm, $cond", "",
1981          [(set regtype:$Rd,
1982                (ARM64csel regtype:$Rn, (frag regtype:$Rm),
1983                (i32 imm:$cond), NZCV))]>,
1984       Sched<[WriteI]> {
1985   let Uses = [NZCV];
1986
1987   bits<5> Rd;
1988   bits<5> Rn;
1989   bits<5> Rm;
1990   bits<4> cond;
1991
1992   let Inst{30}    = op;
1993   let Inst{29-21} = 0b011010100;
1994   let Inst{20-16} = Rm;
1995   let Inst{15-12} = cond;
1996   let Inst{11-10} = op2;
1997   let Inst{9-5}   = Rn;
1998   let Inst{4-0}   = Rd;
1999 }
2000
2001 def inv_cond_XFORM : SDNodeXForm<imm, [{
2002   ARM64CC::CondCode CC = static_cast<ARM64CC::CondCode>(N->getZExtValue());
2003   return CurDAG->getTargetConstant(ARM64CC::getInvertedCondCode(CC), MVT::i32);
2004 }]>;
2005
2006 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
2007   def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
2008     let Inst{31} = 0;
2009   }
2010   def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
2011     let Inst{31} = 1;
2012   }
2013
2014   def : Pat<(ARM64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
2015             (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
2016                                            (inv_cond_XFORM imm:$cond))>;
2017
2018   def : Pat<(ARM64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
2019             (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
2020                                            (inv_cond_XFORM imm:$cond))>;
2021 }
2022
2023 //---
2024 // Special Mask Value
2025 //---
2026 def maski8_or_more : Operand<i32>,
2027   ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
2028 }
2029 def maski16_or_more : Operand<i32>,
2030   ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
2031 }
2032
2033
2034 //---
2035 // Load/store
2036 //---
2037
2038 // (unsigned immediate)
2039 // Indexed for 8-bit registers. offset is in range [0,4095].
2040 def MemoryIndexed8Operand : AsmOperandClass {
2041   let Name = "MemoryIndexed8";
2042   let DiagnosticType = "InvalidMemoryIndexed8";
2043 }
2044 def am_indexed8 : Operand<i64>,
2045                   ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []> {
2046   let PrintMethod = "printAMIndexed<8>";
2047   let EncoderMethod
2048       = "getAMIndexed8OpValue<ARM64::fixup_arm64_ldst_imm12_scale1>";
2049   let ParserMatchClass = MemoryIndexed8Operand;
2050   let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2051 }
2052
2053 // Indexed for 16-bit registers. offset is multiple of 2 in range [0,8190],
2054 // stored as immval/2 (the 12-bit literal that encodes directly into the insn).
2055 def MemoryIndexed16Operand : AsmOperandClass {
2056   let Name = "MemoryIndexed16";
2057   let DiagnosticType = "InvalidMemoryIndexed16";
2058 }
2059 def am_indexed16 : Operand<i64>,
2060                    ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []> {
2061   let PrintMethod = "printAMIndexed<16>";
2062   let EncoderMethod
2063       = "getAMIndexed8OpValue<ARM64::fixup_arm64_ldst_imm12_scale2>";
2064   let ParserMatchClass = MemoryIndexed16Operand;
2065   let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2066 }
2067
2068 // Indexed for 32-bit registers. offset is multiple of 4 in range [0,16380],
2069 // stored as immval/4 (the 12-bit literal that encodes directly into the insn).
2070 def MemoryIndexed32Operand : AsmOperandClass {
2071   let Name = "MemoryIndexed32";
2072   let DiagnosticType = "InvalidMemoryIndexed32";
2073 }
2074 def am_indexed32 : Operand<i64>,
2075                    ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []> {
2076   let PrintMethod = "printAMIndexed<32>";
2077   let EncoderMethod
2078       = "getAMIndexed8OpValue<ARM64::fixup_arm64_ldst_imm12_scale4>";
2079   let ParserMatchClass = MemoryIndexed32Operand;
2080   let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2081 }
2082
2083 // Indexed for 64-bit registers. offset is multiple of 8 in range [0,32760],
2084 // stored as immval/8 (the 12-bit literal that encodes directly into the insn).
2085 def MemoryIndexed64Operand : AsmOperandClass {
2086   let Name = "MemoryIndexed64";
2087   let DiagnosticType = "InvalidMemoryIndexed64";
2088 }
2089 def am_indexed64 : Operand<i64>,
2090                    ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []> {
2091   let PrintMethod = "printAMIndexed<64>";
2092   let EncoderMethod
2093       = "getAMIndexed8OpValue<ARM64::fixup_arm64_ldst_imm12_scale8>";
2094   let ParserMatchClass = MemoryIndexed64Operand;
2095   let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2096 }
2097
2098 // Indexed for 128-bit registers. offset is multiple of 16 in range [0,65520],
2099 // stored as immval/16 (the 12-bit literal that encodes directly into the insn).
2100 def MemoryIndexed128Operand : AsmOperandClass {
2101   let Name = "MemoryIndexed128";
2102   let DiagnosticType = "InvalidMemoryIndexed128";
2103 }
2104 def am_indexed128 : Operand<i64>,
2105                    ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []> {
2106   let PrintMethod = "printAMIndexed<128>";
2107   let EncoderMethod
2108       = "getAMIndexed8OpValue<ARM64::fixup_arm64_ldst_imm12_scale16>";
2109   let ParserMatchClass = MemoryIndexed128Operand;
2110   let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2111 }
2112
2113 // No offset.
2114 def MemoryNoIndexOperand : AsmOperandClass { let Name = "MemoryNoIndex"; }
2115 def am_noindex : Operand<i64>,
2116                  ComplexPattern<i64, 1, "SelectAddrModeNoIndex", []> {
2117   let PrintMethod = "printAMNoIndex";
2118   let ParserMatchClass = MemoryNoIndexOperand;
2119   let MIOperandInfo = (ops GPR64sp:$base);
2120 }
2121
2122 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2123                       string asm, list<dag> pattern>
2124     : I<oops, iops, asm, "\t$Rt, $addr", "", pattern> {
2125   bits<5> dst;
2126
2127   bits<17> addr;
2128   bits<5> base = addr{4-0};
2129   bits<12> offset = addr{16-5};
2130
2131   let Inst{31-30} = sz;
2132   let Inst{29-27} = 0b111;
2133   let Inst{26}    = V;
2134   let Inst{25-24} = 0b01;
2135   let Inst{23-22} = opc;
2136   let Inst{21-10} = offset;
2137   let Inst{9-5}   = base;
2138   let Inst{4-0}   = dst;
2139
2140   let DecoderMethod = "DecodeUnsignedLdStInstruction";
2141 }
2142
2143 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2144 class LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2145              Operand indextype, string asm, list<dag> pattern>
2146     : BaseLoadStoreUI<sz, V, opc,
2147                       (outs regtype:$Rt), (ins indextype:$addr), asm, pattern>,
2148       Sched<[WriteLD]>;
2149
2150 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2151 class StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2152              Operand indextype, string asm, list<dag> pattern>
2153     : BaseLoadStoreUI<sz, V, opc,
2154                       (outs), (ins regtype:$Rt, indextype:$addr), asm, pattern>,
2155       Sched<[WriteST]>;
2156
2157 def PrefetchOperand : AsmOperandClass {
2158   let Name = "Prefetch";
2159   let ParserMethod = "tryParsePrefetch";
2160 }
2161 def prfop : Operand<i32> {
2162   let PrintMethod = "printPrefetchOp";
2163   let ParserMatchClass = PrefetchOperand;
2164 }
2165
2166 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2167 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2168     : BaseLoadStoreUI<sz, V, opc,
2169                       (outs), (ins prfop:$Rt, am_indexed64:$addr), asm, pat>,
2170       Sched<[WriteLD]>;
2171
2172 //---
2173 // Load literal
2174 //---
2175
2176 // Load literal address: 19-bit immediate. The low two bits of the target
2177 // offset are implied zero and so are not part of the immediate.
2178 def am_ldrlit : Operand<OtherVT> {
2179   let EncoderMethod = "getLoadLiteralOpValue";
2180   let DecoderMethod = "DecodePCRelLabel19";
2181   let PrintMethod = "printAlignedLabel";
2182   let ParserMatchClass = PCRelLabel19Operand;
2183 }
2184
2185 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2186 class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
2187     : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
2188         asm, "\t$Rt, $label", "", []>,
2189       Sched<[WriteLD]> {
2190   bits<5> Rt;
2191   bits<19> label;
2192   let Inst{31-30} = opc;
2193   let Inst{29-27} = 0b011;
2194   let Inst{26}    = V;
2195   let Inst{25-24} = 0b00;
2196   let Inst{23-5}  = label;
2197   let Inst{4-0}   = Rt;
2198 }
2199
2200 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2201 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
2202     : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
2203         asm, "\t$Rt, $label", "", pat>,
2204       Sched<[WriteLD]> {
2205   bits<5> Rt;
2206   bits<19> label;
2207   let Inst{31-30} = opc;
2208   let Inst{29-27} = 0b011;
2209   let Inst{26}    = V;
2210   let Inst{25-24} = 0b00;
2211   let Inst{23-5}  = label;
2212   let Inst{4-0}   = Rt;
2213 }
2214
2215 //---
2216 // Load/store register offset
2217 //---
2218
2219 class MemROAsmOperand<int sz> : AsmOperandClass {
2220   let Name = "MemoryRegisterOffset"#sz;
2221 }
2222
2223 def MemROAsmOperand8 : MemROAsmOperand<8>;
2224 def MemROAsmOperand16 : MemROAsmOperand<16>;
2225 def MemROAsmOperand32 : MemROAsmOperand<32>;
2226 def MemROAsmOperand64 : MemROAsmOperand<64>;
2227 def MemROAsmOperand128 : MemROAsmOperand<128>;
2228
2229 class ro_indexed<int sz> : Operand<i64> { // ComplexPattern<...>
2230   let PrintMethod = "printMemoryRegOffset<" # sz # ">";
2231   let MIOperandInfo = (ops GPR64sp:$base, GPR64:$offset, i32imm:$extend);
2232 }
2233
2234 def ro_indexed8 : ro_indexed<8>, ComplexPattern<i64, 3, "SelectAddrModeRO8", []> {
2235   let ParserMatchClass = MemROAsmOperand8;
2236 }
2237
2238 def ro_indexed16 : ro_indexed<16>, ComplexPattern<i64, 3, "SelectAddrModeRO16", []> {
2239   let ParserMatchClass = MemROAsmOperand16;
2240 }
2241
2242 def ro_indexed32 : ro_indexed<32>, ComplexPattern<i64, 3, "SelectAddrModeRO32", []> {
2243   let ParserMatchClass = MemROAsmOperand32;
2244 }
2245
2246 def ro_indexed64 : ro_indexed<64>, ComplexPattern<i64, 3, "SelectAddrModeRO64", []> {
2247   let ParserMatchClass = MemROAsmOperand64;
2248 }
2249
2250 def ro_indexed128 : ro_indexed<128>, ComplexPattern<i64, 3, "SelectAddrModeRO128", []> {
2251   let ParserMatchClass = MemROAsmOperand128;
2252 }
2253
2254 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2255                       string asm, dag ins, dag outs, list<dag> pat>
2256     : I<ins, outs, asm, "\t$Rt, $addr", "", pat> {
2257   // The operands are in order to match the 'addr' MI operands, so we
2258   // don't need an encoder method and by-name matching. Just use the default
2259   // in-order handling. Since we're using by-order, make sure the names
2260   // do not match.
2261   bits<5> dst;
2262   bits<5> base;
2263   bits<5> offset;
2264   bits<4> extend;
2265   let Inst{31-30} = sz;
2266   let Inst{29-27} = 0b111;
2267   let Inst{26}    = V;
2268   let Inst{25-24} = 0b00;
2269   let Inst{23-22} = opc;
2270   let Inst{21}    = 1;
2271   let Inst{20-16} = offset;
2272   let Inst{15-13} = extend{3-1};
2273
2274   let Inst{12}    = extend{0};
2275   let Inst{11-10} = 0b10;
2276   let Inst{9-5}   = base;
2277   let Inst{4-0}   = dst;
2278
2279   let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2280 }
2281
2282 class Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2283              string asm, list<dag> pat>
2284   : LoadStore8RO<sz, V, opc, regtype, asm,
2285                  (outs regtype:$Rt), (ins ro_indexed8:$addr), pat>,
2286     Sched<[WriteLDIdx, ReadAdrBase]>;
2287
2288 class Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2289              string asm, list<dag> pat>
2290   : LoadStore8RO<sz, V, opc, regtype, asm,
2291                  (outs), (ins regtype:$Rt, ro_indexed8:$addr), pat>,
2292     Sched<[WriteSTIdx, ReadAdrBase]>;
2293
2294 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2295                       string asm, dag ins, dag outs, list<dag> pat>
2296     : I<ins, outs, asm, "\t$Rt, $addr", "", pat> {
2297   // The operands are in order to match the 'addr' MI operands, so we
2298   // don't need an encoder method and by-name matching. Just use the default
2299   // in-order handling. Since we're using by-order, make sure the names
2300   // do not match.
2301   bits<5> dst;
2302   bits<5> base;
2303   bits<5> offset;
2304   bits<4> extend;
2305   let Inst{31-30} = sz;
2306   let Inst{29-27} = 0b111;
2307   let Inst{26}    = V;
2308   let Inst{25-24} = 0b00;
2309   let Inst{23-22} = opc;
2310   let Inst{21}    = 1;
2311   let Inst{20-16} = offset;
2312   let Inst{15-13} = extend{3-1};
2313
2314   let Inst{12}    = extend{0};
2315   let Inst{11-10} = 0b10;
2316   let Inst{9-5}   = base;
2317   let Inst{4-0}   = dst;
2318
2319   let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2320 }
2321
2322 class Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2323              string asm, list<dag> pat>
2324   : LoadStore16RO<sz, V, opc, regtype, asm,
2325                  (outs regtype:$Rt), (ins ro_indexed16:$addr), pat>,
2326     Sched<[WriteLDIdx, ReadAdrBase]>;
2327
2328 class Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2329              string asm, list<dag> pat>
2330   : LoadStore16RO<sz, V, opc, regtype, asm,
2331                  (outs), (ins regtype:$Rt, ro_indexed16:$addr), pat>,
2332     Sched<[WriteSTIdx, ReadAdrBase]>;
2333
2334 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2335                       string asm, dag ins, dag outs, list<dag> pat>
2336     : I<ins, outs, asm, "\t$Rt, $addr", "", pat> {
2337   // The operands are in order to match the 'addr' MI operands, so we
2338   // don't need an encoder method and by-name matching. Just use the default
2339   // in-order handling. Since we're using by-order, make sure the names
2340   // do not match.
2341   bits<5> dst;
2342   bits<5> base;
2343   bits<5> offset;
2344   bits<4> extend;
2345   let Inst{31-30} = sz;
2346   let Inst{29-27} = 0b111;
2347   let Inst{26}    = V;
2348   let Inst{25-24} = 0b00;
2349   let Inst{23-22} = opc;
2350   let Inst{21}    = 1;
2351   let Inst{20-16} = offset;
2352   let Inst{15-13} = extend{3-1};
2353
2354   let Inst{12}    = extend{0};
2355   let Inst{11-10} = 0b10;
2356   let Inst{9-5}   = base;
2357   let Inst{4-0}   = dst;
2358
2359   let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2360 }
2361
2362 class Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2363              string asm, list<dag> pat>
2364   : LoadStore32RO<sz, V, opc, regtype, asm,
2365                  (outs regtype:$Rt), (ins ro_indexed32:$addr), pat>,
2366     Sched<[WriteLDIdx, ReadAdrBase]>;
2367
2368 class Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2369              string asm, list<dag> pat>
2370   : LoadStore32RO<sz, V, opc, regtype, asm,
2371                  (outs), (ins regtype:$Rt, ro_indexed32:$addr), pat>,
2372     Sched<[WriteSTIdx, ReadAdrBase]>;
2373
2374 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2375                       string asm, dag ins, dag outs, list<dag> pat>
2376     : I<ins, outs, asm, "\t$Rt, $addr", "", pat> {
2377   // The operands are in order to match the 'addr' MI operands, so we
2378   // don't need an encoder method and by-name matching. Just use the default
2379   // in-order handling. Since we're using by-order, make sure the names
2380   // do not match.
2381   bits<5> dst;
2382   bits<5> base;
2383   bits<5> offset;
2384   bits<4> extend;
2385   let Inst{31-30} = sz;
2386   let Inst{29-27} = 0b111;
2387   let Inst{26}    = V;
2388   let Inst{25-24} = 0b00;
2389   let Inst{23-22} = opc;
2390   let Inst{21}    = 1;
2391   let Inst{20-16} = offset;
2392   let Inst{15-13} = extend{3-1};
2393
2394   let Inst{12}    = extend{0};
2395   let Inst{11-10} = 0b10;
2396   let Inst{9-5}   = base;
2397   let Inst{4-0}   = dst;
2398
2399   let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2400 }
2401
2402 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2403 class Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2404              string asm, list<dag> pat>
2405   : LoadStore64RO<sz, V, opc, regtype, asm,
2406                  (outs regtype:$Rt), (ins ro_indexed64:$addr), pat>,
2407     Sched<[WriteLDIdx, ReadAdrBase]>;
2408
2409 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2410 class Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2411              string asm, list<dag> pat>
2412   : LoadStore64RO<sz, V, opc, regtype, asm,
2413                  (outs), (ins regtype:$Rt, ro_indexed64:$addr), pat>,
2414     Sched<[WriteSTIdx, ReadAdrBase]>;
2415
2416
2417 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2418                       string asm, dag ins, dag outs, list<dag> pat>
2419     : I<ins, outs, asm, "\t$Rt, $addr", "", pat> {
2420   // The operands are in order to match the 'addr' MI operands, so we
2421   // don't need an encoder method and by-name matching. Just use the default
2422   // in-order handling. Since we're using by-order, make sure the names
2423   // do not match.
2424   bits<5> dst;
2425   bits<5> base;
2426   bits<5> offset;
2427   bits<4> extend;
2428   let Inst{31-30} = sz;
2429   let Inst{29-27} = 0b111;
2430   let Inst{26}    = V;
2431   let Inst{25-24} = 0b00;
2432   let Inst{23-22} = opc;
2433   let Inst{21}    = 1;
2434   let Inst{20-16} = offset;
2435   let Inst{15-13} = extend{3-1};
2436
2437   let Inst{12}    = extend{0};
2438   let Inst{11-10} = 0b10;
2439   let Inst{9-5}   = base;
2440   let Inst{4-0}   = dst;
2441
2442   let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2443 }
2444
2445 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2446 class Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2447              string asm, list<dag> pat>
2448   : LoadStore128RO<sz, V, opc, regtype, asm,
2449                  (outs regtype:$Rt), (ins ro_indexed128:$addr), pat>,
2450     Sched<[WriteLDIdx, ReadAdrBase]>;
2451
2452 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2453 class Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2454              string asm, list<dag> pat>
2455   : LoadStore128RO<sz, V, opc, regtype, asm,
2456                  (outs), (ins regtype:$Rt, ro_indexed128:$addr), pat>,
2457     Sched<[WriteSTIdx, ReadAdrBase]>;
2458
2459 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2460 class PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2461     : I<(outs), (ins prfop:$Rt, ro_indexed64:$addr), asm,
2462          "\t$Rt, $addr", "", pat>,
2463       Sched<[WriteLD]> {
2464   // The operands are in order to match the 'addr' MI operands, so we
2465   // don't need an encoder method and by-name matching. Just use the default
2466   // in-order handling. Since we're using by-order, make sure the names
2467   // do not match.
2468   bits<5> dst;
2469   bits<5> base;
2470   bits<5> offset;
2471   bits<4> extend;
2472   let Inst{31-30} = sz;
2473   let Inst{29-27} = 0b111;
2474   let Inst{26}    = V;
2475   let Inst{25-24} = 0b00;
2476   let Inst{23-22} = opc;
2477   let Inst{21}    = 1;
2478   let Inst{20-16} = offset;
2479   let Inst{15-13} = extend{3-1};
2480
2481   let Inst{12}    = extend{0};
2482   let Inst{11-10} = 0b10;
2483   let Inst{9-5}   = base;
2484   let Inst{4-0}   = dst;
2485
2486   let DecoderMethod = "DecodeRegOffsetLdStInstruction";
2487 }
2488
2489 //---
2490 // Load/store unscaled immediate
2491 //---
2492
2493 def MemoryUnscaledOperand : AsmOperandClass {
2494   let Name = "MemoryUnscaled";
2495   let DiagnosticType = "InvalidMemoryIndexedSImm9";
2496 }
2497 class am_unscaled_operand : Operand<i64> {
2498   let PrintMethod = "printAMIndexed<8>";
2499   let ParserMatchClass = MemoryUnscaledOperand;
2500   let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2501 }
2502 class am_unscaled_wb_operand : Operand<i64> {
2503   let PrintMethod = "printAMIndexedWB<8>";
2504   let ParserMatchClass = MemoryUnscaledOperand;
2505   let MIOperandInfo = (ops GPR64sp:$base, i64imm:$offset);
2506 }
2507 def am_unscaled   : am_unscaled_operand;
2508 def am_unscaled_wb: am_unscaled_wb_operand;
2509 def am_unscaled8  : am_unscaled_operand,
2510                     ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
2511 def am_unscaled16 : am_unscaled_operand,
2512                     ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
2513 def am_unscaled32 : am_unscaled_operand,
2514                     ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
2515 def am_unscaled64 : am_unscaled_operand,
2516                     ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
2517 def am_unscaled128 : am_unscaled_operand,
2518                     ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
2519
2520 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2521                            string asm, list<dag> pattern>
2522     : I<oops, iops, asm, "\t$Rt, $addr", "", pattern> {
2523   // The operands are in order to match the 'addr' MI operands, so we
2524   // don't need an encoder method and by-name matching. Just use the default
2525   // in-order handling. Since we're using by-order, make sure the names
2526   // do not match.
2527   bits<5> dst;
2528   bits<5> base;
2529   bits<9> offset;
2530   let Inst{31-30} = sz;
2531   let Inst{29-27} = 0b111;
2532   let Inst{26}    = V;
2533   let Inst{25-24} = 0b00;
2534   let Inst{23-22} = opc;
2535   let Inst{21}    = 0;
2536   let Inst{20-12} = offset;
2537   let Inst{11-10} = 0b00;
2538   let Inst{9-5}   = base;
2539   let Inst{4-0}   = dst;
2540
2541   let DecoderMethod = "DecodeSignedLdStInstruction";
2542 }
2543
2544 let AddedComplexity = 1 in // try this before LoadUI
2545 class LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2546                    Operand amtype, string asm, list<dag> pattern>
2547     : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
2548                            (ins amtype:$addr), asm, pattern>,
2549       Sched<[WriteLD]>;
2550
2551 let AddedComplexity = 1 in // try this before StoreUI
2552 class StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2553                     Operand amtype, string asm, list<dag> pattern>
2554     : BaseLoadStoreUnscale<sz, V, opc, (outs),
2555                            (ins regtype:$Rt, amtype:$addr), asm, pattern>,
2556       Sched<[WriteST]>;
2557
2558 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2559 class PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2560     : BaseLoadStoreUnscale<sz, V, opc, (outs),
2561                            (ins prfop:$Rt, am_unscaled:$addr), asm, pat>,
2562       Sched<[WriteLD]>;
2563
2564 //---
2565 // Load/store unscaled immediate, unprivileged
2566 //---
2567
2568 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
2569                                 dag oops, dag iops, string asm>
2570     : I<oops, iops, asm, "\t$Rt, $addr", "", []> {
2571   // The operands are in order to match the 'addr' MI operands, so we
2572   // don't need an encoder method and by-name matching. Just use the default
2573   // in-order handling. Since we're using by-order, make sure the names
2574   // do not match.
2575   bits<5> dst;
2576   bits<5> base;
2577   bits<9> offset;
2578   let Inst{31-30} = sz;
2579   let Inst{29-27} = 0b111;
2580   let Inst{26}    = V;
2581   let Inst{25-24} = 0b00;
2582   let Inst{23-22} = opc;
2583   let Inst{21}    = 0;
2584   let Inst{20-12} = offset;
2585   let Inst{11-10} = 0b10;
2586   let Inst{9-5}   = base;
2587   let Inst{4-0}   = dst;
2588
2589   let DecoderMethod = "DecodeSignedLdStInstruction";
2590 }
2591
2592 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in {
2593 class LoadUnprivileged<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2594                    string asm>
2595     : BaseLoadStoreUnprivileged<sz, V, opc,
2596                       (outs regtype:$Rt), (ins am_unscaled:$addr), asm>,
2597       Sched<[WriteLD]>;
2598 }
2599
2600 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in {
2601 class StoreUnprivileged<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2602                     string asm>
2603     : BaseLoadStoreUnprivileged<sz, V, opc,
2604                       (outs), (ins regtype:$Rt, am_unscaled:$addr), asm>,
2605       Sched<[WriteST]>;
2606 }
2607
2608 //---
2609 // Load/store pre-indexed
2610 //---
2611
2612 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2613                           string asm, string cstr>
2614     : I<oops, iops, asm, "\t$Rt, $addr!", cstr, []> {
2615   // The operands are in order to match the 'addr' MI operands, so we
2616   // don't need an encoder method and by-name matching. Just use the default
2617   // in-order handling.
2618   bits<5> dst;
2619   bits<5> base;
2620   bits<9> offset;
2621   let Inst{31-30} = sz;
2622   let Inst{29-27} = 0b111;
2623   let Inst{26}    = V;
2624   let Inst{25-24} = 0;
2625   let Inst{23-22} = opc;
2626   let Inst{21}    = 0;
2627   let Inst{20-12} = offset;
2628   let Inst{11-10} = 0b11;
2629   let Inst{9-5}   = base;
2630   let Inst{4-0}   = dst;
2631
2632   let DecoderMethod = "DecodeSignedLdStInstruction";
2633 }
2634
2635 let hasSideEffects = 0 in {
2636 let mayStore = 0, mayLoad = 1 in
2637 // FIXME: Modeling the write-back of these instructions for isel is tricky.
2638 //        we need the complex addressing mode for the memory reference, but
2639 //        we also need the write-back specified as a tied operand to the
2640 //        base register. That combination does not play nicely with
2641 //        the asm matcher and friends.
2642 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2643              string asm>
2644     : BaseLoadStorePreIdx<sz, V, opc,
2645                      (outs regtype:$Rt/*, GPR64sp:$wback*/),
2646                      (ins am_unscaled_wb:$addr), asm, ""/*"$addr.base = $wback"*/>,
2647       Sched<[WriteLD, WriteAdr]>;
2648
2649 let mayStore = 1, mayLoad = 0 in
2650 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2651              string asm>
2652     : BaseLoadStorePreIdx<sz, V, opc,
2653                       (outs/* GPR64sp:$wback*/),
2654                       (ins regtype:$Rt, am_unscaled_wb:$addr),
2655                        asm, ""/*"$addr.base = $wback"*/>,
2656       Sched<[WriteAdr, WriteST]>;
2657 } // hasSideEffects = 0
2658
2659 // ISel pseudo-instructions which have the tied operands. When the MC lowering
2660 // logic finally gets smart enough to strip off tied operands that are just
2661 // for isel convenience, we can get rid of these pseudos and just reference
2662 // the real instructions directly.
2663 //
2664 // Ironically, also because of the writeback operands, we can't put the
2665 // matcher pattern directly on the instruction, but need to define it
2666 // separately.
2667 //
2668 // Loads aren't matched with patterns here at all, but rather in C++
2669 // custom lowering.
2670 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in {
2671 class LoadPreIdxPseudo<RegisterClass regtype>
2672     : Pseudo<(outs regtype:$Rt, GPR64sp:$wback),
2673              (ins am_noindex:$addr, simm9:$offset), [],
2674               "$addr.base = $wback,@earlyclobber $wback">,
2675       Sched<[WriteLD, WriteAdr]>;
2676 class LoadPostIdxPseudo<RegisterClass regtype>
2677     : Pseudo<(outs regtype:$Rt, GPR64sp:$wback),
2678              (ins am_noindex:$addr, simm9:$offset), [],
2679               "$addr.base = $wback,@earlyclobber $wback">,
2680       Sched<[WriteLD, WriteI]>;
2681 }
2682 multiclass StorePreIdxPseudo<RegisterClass regtype, ValueType Ty,
2683                              SDPatternOperator OpNode> {
2684   let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
2685   def _isel: Pseudo<(outs GPR64sp:$wback),
2686                     (ins regtype:$Rt, am_noindex:$addr, simm9:$offset), [],
2687                     "$addr.base = $wback,@earlyclobber $wback">,
2688       Sched<[WriteAdr, WriteST]>;
2689
2690   def : Pat<(OpNode (Ty regtype:$Rt), am_noindex:$addr, simm9:$offset),
2691             (!cast<Instruction>(NAME#_isel) regtype:$Rt, am_noindex:$addr,
2692                                             simm9:$offset)>;
2693 }
2694
2695 //---
2696 // Load/store post-indexed
2697 //---
2698
2699 // (pre-index) load/stores.
2700 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2701                           string asm, string cstr>
2702     : I<oops, iops, asm, "\t$Rt, $addr, $idx", cstr, []> {
2703   // The operands are in order to match the 'addr' MI operands, so we
2704   // don't need an encoder method and by-name matching. Just use the default
2705   // in-order handling.
2706   bits<5> dst;
2707   bits<5> base;
2708   bits<9> offset;
2709   let Inst{31-30} = sz;
2710   let Inst{29-27} = 0b111;
2711   let Inst{26}    = V;
2712   let Inst{25-24} = 0b00;
2713   let Inst{23-22} = opc;
2714   let Inst{21}    = 0b0;
2715   let Inst{20-12} = offset;
2716   let Inst{11-10} = 0b01;
2717   let Inst{9-5}   = base;
2718   let Inst{4-0}   = dst;
2719
2720   let DecoderMethod = "DecodeSignedLdStInstruction";
2721 }
2722
2723 let hasSideEffects = 0 in {
2724 let mayStore = 0, mayLoad = 1 in
2725 // FIXME: Modeling the write-back of these instructions for isel is tricky.
2726 //        we need the complex addressing mode for the memory reference, but
2727 //        we also need the write-back specified as a tied operand to the
2728 //        base register. That combination does not play nicely with
2729 //        the asm matcher and friends.
2730 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2731              string asm>
2732     : BaseLoadStorePostIdx<sz, V, opc,
2733                       (outs regtype:$Rt/*, GPR64sp:$wback*/),
2734                       (ins am_noindex:$addr, simm9:$idx),
2735                       asm, ""/*"$addr.base = $wback"*/>,
2736       Sched<[WriteLD, WriteI]>;
2737
2738 let mayStore = 1, mayLoad = 0 in
2739 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2740              string asm>
2741     : BaseLoadStorePostIdx<sz, V, opc,
2742                       (outs/* GPR64sp:$wback*/),
2743                       (ins regtype:$Rt, am_noindex:$addr, simm9:$idx),
2744                        asm, ""/*"$addr.base = $wback"*/>,
2745     Sched<[WriteAdr, WriteST, ReadAdrBase]>;
2746 } // hasSideEffects = 0
2747
2748 // ISel pseudo-instructions which have the tied operands. When the MC lowering
2749 // logic finally gets smart enough to strip off tied operands that are just
2750 // for isel convenience, we can get rid of these pseudos and just reference
2751 // the real instructions directly.
2752 //
2753 // Ironically, also because of the writeback operands, we can't put the
2754 // matcher pattern directly on the instruction, but need to define it
2755 // separately.
2756 multiclass StorePostIdxPseudo<RegisterClass regtype, ValueType Ty,
2757                               SDPatternOperator OpNode, Instruction Insn> {
2758   let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
2759   def _isel: Pseudo<(outs GPR64sp:$wback),
2760                     (ins regtype:$Rt, am_noindex:$addr, simm9:$idx), [],
2761                     "$addr.base = $wback,@earlyclobber $wback">,
2762       PseudoInstExpansion<(Insn regtype:$Rt, am_noindex:$addr, simm9:$idx)>,
2763       Sched<[WriteAdr, WriteST, ReadAdrBase]>;
2764
2765   def : Pat<(OpNode (Ty regtype:$Rt), am_noindex:$addr, simm9:$idx),
2766             (!cast<Instruction>(NAME#_isel) regtype:$Rt, am_noindex:$addr,
2767                                             simm9:$idx)>;
2768 }
2769
2770 //---
2771 // Load/store pair
2772 //---
2773
2774 // (indexed, offset)
2775
2776 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
2777                               string asm>
2778     : I<oops, iops, asm, "\t$Rt, $Rt2, $addr", "", []> {
2779   // The operands are in order to match the 'addr' MI operands, so we
2780   // don't need an encoder method and by-name matching. Just use the default
2781   // in-order handling. Since we're using by-order, make sure the names
2782   // do not match.
2783   bits<5> dst;
2784   bits<5> dst2;
2785   bits<5> base;
2786   bits<7> offset;
2787   let Inst{31-30} = opc;
2788   let Inst{29-27} = 0b101;
2789   let Inst{26}    = V;
2790   let Inst{25-23} = 0b010;
2791   let Inst{22}    = L;
2792   let Inst{21-15} = offset;
2793   let Inst{14-10} = dst2;
2794   let Inst{9-5}   = base;
2795   let Inst{4-0}   = dst;
2796
2797   let DecoderMethod = "DecodePairLdStInstruction";
2798 }
2799
2800 let hasSideEffects = 0 in {
2801 let mayStore = 0, mayLoad = 1 in
2802 class LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
2803                      Operand indextype, string asm>
2804     : BaseLoadStorePairOffset<opc, V, 1,
2805                               (outs regtype:$Rt, regtype:$Rt2),
2806                               (ins indextype:$addr), asm>,
2807       Sched<[WriteLD, WriteLDHi]>;
2808
2809 let mayLoad = 0, mayStore = 1 in
2810 class StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
2811                       Operand indextype, string asm>
2812     : BaseLoadStorePairOffset<opc, V, 0, (outs),
2813                              (ins regtype:$Rt, regtype:$Rt2, indextype:$addr),
2814                              asm>,
2815       Sched<[WriteSTP]>;
2816 } // hasSideEffects = 0
2817
2818 // (pre-indexed)
2819
2820 def MemoryIndexed32SImm7 : AsmOperandClass {
2821   let Name = "MemoryIndexed32SImm7";
2822   let DiagnosticType = "InvalidMemoryIndexed32SImm7";
2823 }
2824 def am_indexed32simm7 : Operand<i32> { // ComplexPattern<...>
2825   let PrintMethod = "printAMIndexed<32>";
2826   let ParserMatchClass = MemoryIndexed32SImm7;
2827   let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
2828 }
2829 def am_indexed32simm7_wb : Operand<i32> { // ComplexPattern<...>
2830   let PrintMethod = "printAMIndexedWB<32>";
2831   let ParserMatchClass = MemoryIndexed32SImm7;
2832   let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
2833 }
2834
2835 def MemoryIndexed64SImm7 : AsmOperandClass {
2836   let Name = "MemoryIndexed64SImm7";
2837   let DiagnosticType = "InvalidMemoryIndexed64SImm7";
2838 }
2839 def am_indexed64simm7 : Operand<i32> { // ComplexPattern<...>
2840   let PrintMethod = "printAMIndexed<64>";
2841   let ParserMatchClass = MemoryIndexed64SImm7;
2842   let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
2843 }
2844 def am_indexed64simm7_wb : Operand<i32> { // ComplexPattern<...>
2845   let PrintMethod = "printAMIndexedWB<64>";
2846   let ParserMatchClass = MemoryIndexed64SImm7;
2847   let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
2848 }
2849
2850 def MemoryIndexed128SImm7 : AsmOperandClass {
2851   let Name = "MemoryIndexed128SImm7";
2852   let DiagnosticType = "InvalidMemoryIndexed128SImm7";
2853 }
2854 def am_indexed128simm7 : Operand<i32> { // ComplexPattern<...>
2855   let PrintMethod = "printAMIndexed<128>";
2856   let ParserMatchClass = MemoryIndexed128SImm7;
2857   let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
2858 }
2859 def am_indexed128simm7_wb : Operand<i32> { // ComplexPattern<...>
2860   let PrintMethod = "printAMIndexedWB<128>";
2861   let ParserMatchClass = MemoryIndexed128SImm7;
2862   let MIOperandInfo = (ops GPR64sp:$base, i32imm:$offset);
2863 }
2864
2865 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
2866                               string asm>
2867     : I<oops, iops, asm, "\t$Rt, $Rt2, $addr!", "", []> {
2868   // The operands are in order to match the 'addr' MI operands, so we
2869   // don't need an encoder method and by-name matching. Just use the default
2870   // in-order handling. Since we're using by-order, make sure the names
2871   // do not match.
2872   bits<5> dst;
2873   bits<5> dst2;
2874   bits<5> base;
2875   bits<7> offset;
2876   let Inst{31-30} = opc;
2877   let Inst{29-27} = 0b101;
2878   let Inst{26}    = V;
2879   let Inst{25-23} = 0b011;
2880   let Inst{22}    = L;
2881   let Inst{21-15} = offset;
2882   let Inst{14-10} = dst2;
2883   let Inst{9-5}   = base;
2884   let Inst{4-0}   = dst;
2885
2886   let DecoderMethod = "DecodePairLdStInstruction";
2887 }
2888
2889 let hasSideEffects = 0 in {
2890 let mayStore = 0, mayLoad = 1 in
2891 class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
2892                      Operand addrmode, string asm>
2893     : BaseLoadStorePairPreIdx<opc, V, 1,
2894                               (outs regtype:$Rt, regtype:$Rt2),
2895                               (ins addrmode:$addr), asm>,
2896       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
2897
2898 let mayStore = 1, mayLoad = 0 in
2899 class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
2900                       Operand addrmode, string asm>
2901     : BaseLoadStorePairPreIdx<opc, V, 0, (outs),
2902                              (ins regtype:$Rt, regtype:$Rt2, addrmode:$addr),
2903                              asm>,
2904       Sched<[WriteAdr, WriteSTP]>;
2905 } // hasSideEffects = 0
2906
2907 // (post-indexed)
2908
2909 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
2910                               string asm>
2911     : I<oops, iops, asm, "\t$Rt, $Rt2, $addr, $idx", "", []> {
2912   // The operands are in order to match the 'addr' MI operands, so we
2913   // don't need an encoder method and by-name matching. Just use the default
2914   // in-order handling. Since we're using by-order, make sure the names
2915   // do not match.
2916   bits<5> dst;
2917   bits<5> dst2;
2918   bits<5> base;
2919   bits<7> offset;
2920   let Inst{31-30} = opc;
2921   let Inst{29-27} = 0b101;
2922   let Inst{26}    = V;
2923   let Inst{25-23} = 0b001;
2924   let Inst{22}    = L;
2925   let Inst{21-15} = offset;
2926   let Inst{14-10} = dst2;
2927   let Inst{9-5}   = base;
2928   let Inst{4-0}   = dst;
2929
2930   let DecoderMethod = "DecodePairLdStInstruction";
2931 }
2932
2933 let hasSideEffects = 0 in {
2934 let mayStore = 0, mayLoad = 1 in
2935 class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
2936                       Operand idxtype, string asm>
2937     : BaseLoadStorePairPostIdx<opc, V, 1,
2938                               (outs regtype:$Rt, regtype:$Rt2),
2939                               (ins am_noindex:$addr, idxtype:$idx), asm>,
2940       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
2941
2942 let mayStore = 1, mayLoad = 0 in
2943 class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
2944                        Operand idxtype, string asm>
2945     : BaseLoadStorePairPostIdx<opc, V, 0, (outs),
2946                              (ins regtype:$Rt, regtype:$Rt2,
2947                                   am_noindex:$addr, idxtype:$idx),
2948                              asm>,
2949       Sched<[WriteAdr, WriteSTP]>;
2950 } // hasSideEffects = 0
2951
2952 //  (no-allocate)
2953
2954 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
2955                               string asm>
2956     : I<oops, iops, asm, "\t$Rt, $Rt2, $addr", "", []> {
2957   // The operands are in order to match the 'addr' MI operands, so we
2958   // don't need an encoder method and by-name matching. Just use the default
2959   // in-order handling. Since we're using by-order, make sure the names
2960   // do not match.
2961   bits<5> dst;
2962   bits<5> dst2;
2963   bits<5> base;
2964   bits<7> offset;
2965   let Inst{31-30} = opc;
2966   let Inst{29-27} = 0b101;
2967   let Inst{26}    = V;
2968   let Inst{25-23} = 0b000;
2969   let Inst{22}    = L;
2970   let Inst{21-15} = offset;
2971   let Inst{14-10} = dst2;
2972   let Inst{9-5}   = base;
2973   let Inst{4-0}   = dst;
2974
2975   let DecoderMethod = "DecodePairLdStInstruction";
2976 }
2977
2978 let hasSideEffects = 0 in {
2979 let mayStore = 0, mayLoad = 1 in
2980 class LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
2981                      Operand indextype, string asm>
2982     : BaseLoadStorePairNoAlloc<opc, V, 1,
2983                               (outs regtype:$Rt, regtype:$Rt2),
2984                               (ins indextype:$addr), asm>,
2985       Sched<[WriteLD, WriteLDHi]>;
2986
2987 let mayStore = 1, mayLoad = 0 in
2988 class StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
2989                       Operand indextype, string asm>
2990     : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
2991                              (ins regtype:$Rt, regtype:$Rt2, indextype:$addr),
2992                              asm>,
2993       Sched<[WriteSTP]>;
2994 } // hasSideEffects = 0
2995
2996 //---
2997 // Load/store exclusive
2998 //---
2999
3000 // True exclusive operations write to and/or read from the system's exclusive
3001 // monitors, which as far as a compiler is concerned can be modelled as a
3002 // random shared memory address. Hence LoadExclusive mayStore.
3003 //
3004 // Since these instructions have the undefined register bits set to 1 in
3005 // their canonical form, we need a post encoder method to set those bits
3006 // to 1 when encoding these instructions. We do this using the
3007 // fixLoadStoreExclusive function. This function has template parameters:
3008 //
3009 // fixLoadStoreExclusive<int hasRs, int hasRt2>
3010 //
3011 // hasRs indicates that the instruction uses the Rs field, so we won't set
3012 // it to 1 (and the same for Rt2). We don't need template parameters for
3013 // the other register fields since Rt and Rn are always used.
3014 //
3015 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
3016 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3017                              dag oops, dag iops, string asm, string operands>
3018     : I<oops, iops, asm, operands, "", []> {
3019   let Inst{31-30} = sz;
3020   let Inst{29-24} = 0b001000;
3021   let Inst{23}    = o2;
3022   let Inst{22}    = L;
3023   let Inst{21}    = o1;
3024   let Inst{15}    = o0;
3025
3026   let DecoderMethod = "DecodeExclusiveLdStInstruction";
3027 }
3028
3029 // Neither Rs nor Rt2 operands.
3030 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3031                                dag oops, dag iops, string asm, string operands>
3032     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
3033   bits<5> reg;
3034   bits<5> base;
3035   let Inst{9-5} = base;
3036   let Inst{4-0} = reg;
3037
3038   let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
3039 }
3040
3041 // Simple load acquires don't set the exclusive monitor
3042 let mayLoad = 1, mayStore = 0 in
3043 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3044                   RegisterClass regtype, string asm>
3045     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3046                                (ins am_noindex:$addr), asm, "\t$Rt, $addr">,
3047       Sched<[WriteLD]>;
3048
3049 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3050                     RegisterClass regtype, string asm>
3051     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3052                                (ins am_noindex:$addr), asm, "\t$Rt, $addr">,
3053       Sched<[WriteLD]>;
3054
3055 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3056                        RegisterClass regtype, string asm>
3057     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3058                              (outs regtype:$Rt, regtype:$Rt2),
3059                              (ins am_noindex:$addr), asm,
3060                              "\t$Rt, $Rt2, $addr">,
3061       Sched<[WriteLD, WriteLDHi]> {
3062   bits<5> dst1;
3063   bits<5> dst2;
3064   bits<5> base;
3065   let Inst{14-10} = dst2;
3066   let Inst{9-5} = base;
3067   let Inst{4-0} = dst1;
3068
3069   let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
3070 }
3071
3072 // Simple store release operations do not check the exclusive monitor.
3073 let mayLoad = 0, mayStore = 1 in
3074 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3075                    RegisterClass regtype, string asm>
3076     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
3077                                (ins regtype:$Rt, am_noindex:$addr),
3078                                asm, "\t$Rt, $addr">,
3079       Sched<[WriteST]>;
3080
3081 let mayLoad = 1, mayStore = 1 in
3082 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3083                      RegisterClass regtype, string asm>
3084     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
3085                              (ins regtype:$Rt, am_noindex:$addr),
3086                              asm, "\t$Ws, $Rt, $addr">,
3087       Sched<[WriteSTX]> {
3088   bits<5> status;
3089   bits<5> reg;
3090   bits<5> base;
3091   let Inst{20-16} = status;
3092   let Inst{9-5} = base;
3093   let Inst{4-0} = reg;
3094
3095   let Constraints = "@earlyclobber $Ws";
3096   let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
3097 }
3098
3099 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3100                          RegisterClass regtype, string asm>
3101     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3102                              (outs GPR32:$Ws),
3103                              (ins regtype:$Rt, regtype:$Rt2, am_noindex:$addr),
3104                               asm, "\t$Ws, $Rt, $Rt2, $addr">,
3105       Sched<[WriteSTX]> {
3106   bits<5> status;
3107   bits<5> dst1;
3108   bits<5> dst2;
3109   bits<5> base;
3110   let Inst{20-16} = status;
3111   let Inst{14-10} = dst2;
3112   let Inst{9-5} = base;
3113   let Inst{4-0} = dst1;
3114
3115   let Constraints = "@earlyclobber $Ws";
3116 }
3117
3118 //---
3119 // Exception generation
3120 //---
3121
3122 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3123 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
3124     : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
3125       Sched<[WriteSys]> {
3126   bits<16> imm;
3127   let Inst{31-24} = 0b11010100;
3128   let Inst{23-21} = op1;
3129   let Inst{20-5}  = imm;
3130   let Inst{4-2}   = 0b000;
3131   let Inst{1-0}   = ll;
3132 }
3133
3134 let Predicates = [HasFPARMv8] in {
3135
3136 //---
3137 // Floating point to integer conversion
3138 //---
3139
3140 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
3141                       RegisterClass srcType, RegisterClass dstType,
3142                       string asm, list<dag> pattern>
3143     : I<(outs dstType:$Rd), (ins srcType:$Rn),
3144          asm, "\t$Rd, $Rn", "", pattern>,
3145       Sched<[WriteFCvt]> {
3146   bits<5> Rd;
3147   bits<5> Rn;
3148   let Inst{30-29} = 0b00;
3149   let Inst{28-24} = 0b11110;
3150   let Inst{23-22} = type;
3151   let Inst{21}    = 1;
3152   let Inst{20-19} = rmode;
3153   let Inst{18-16} = opcode;
3154   let Inst{15-10} = 0;
3155   let Inst{9-5}   = Rn;
3156   let Inst{4-0}   = Rd;
3157 }
3158
3159 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3160 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
3161                       RegisterClass srcType, RegisterClass dstType,
3162                       Operand immType, string asm, list<dag> pattern>
3163     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3164          asm, "\t$Rd, $Rn, $scale", "", pattern>,
3165       Sched<[WriteFCvt]> {
3166   bits<5> Rd;
3167   bits<5> Rn;
3168   bits<6> scale;
3169   let Inst{30-29} = 0b00;
3170   let Inst{28-24} = 0b11110;
3171   let Inst{23-22} = type;
3172   let Inst{21}    = 0;
3173   let Inst{20-19} = rmode;
3174   let Inst{18-16} = opcode;
3175   let Inst{15-10} = scale;
3176   let Inst{9-5}   = Rn;
3177   let Inst{4-0}   = Rd;
3178 }
3179
3180 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
3181            SDPatternOperator OpN> {
3182   // Unscaled single-precision to 32-bit
3183   def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
3184                                      [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
3185     let Inst{31} = 0; // 32-bit GPR flag
3186   }
3187
3188   // Unscaled single-precision to 64-bit
3189   def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
3190                                      [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
3191     let Inst{31} = 1; // 64-bit GPR flag
3192   }
3193
3194   // Unscaled double-precision to 32-bit
3195   def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
3196                                      [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3197     let Inst{31} = 0; // 32-bit GPR flag
3198   }
3199
3200   // Unscaled double-precision to 64-bit
3201   def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
3202                                      [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3203     let Inst{31} = 1; // 64-bit GPR flag
3204   }
3205 }
3206
3207 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
3208                              SDPatternOperator OpN> {
3209   // Scaled single-precision to 32-bit
3210   def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
3211                               fixedpoint_f32_i32, asm,
3212               [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
3213                                           fixedpoint_f32_i32:$scale)))]> {
3214     let Inst{31} = 0; // 32-bit GPR flag
3215     let scale{5} = 1;
3216   }
3217
3218   // Scaled single-precision to 64-bit
3219   def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
3220                               fixedpoint_f32_i64, asm,
3221               [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
3222                                           fixedpoint_f32_i64:$scale)))]> {
3223     let Inst{31} = 1; // 64-bit GPR flag
3224   }
3225
3226   // Scaled double-precision to 32-bit
3227   def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
3228                               fixedpoint_f64_i32, asm,
3229               [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
3230                                           fixedpoint_f64_i32:$scale)))]> {
3231     let Inst{31} = 0; // 32-bit GPR flag
3232     let scale{5} = 1;
3233   }
3234
3235   // Scaled double-precision to 64-bit
3236   def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
3237                               fixedpoint_f64_i64, asm,
3238               [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
3239                                           fixedpoint_f64_i64:$scale)))]> {
3240     let Inst{31} = 1; // 64-bit GPR flag
3241   }
3242 }
3243
3244 //---
3245 // Integer to floating point conversion
3246 //---
3247
3248 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
3249 class BaseIntegerToFP<bit isUnsigned,
3250                       RegisterClass srcType, RegisterClass dstType,
3251                       Operand immType, string asm, list<dag> pattern>
3252     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3253          asm, "\t$Rd, $Rn, $scale", "", pattern>,
3254       Sched<[WriteFCvt]> {
3255   bits<5> Rd;
3256   bits<5> Rn;
3257   bits<6> scale;
3258   let Inst{30-23} = 0b00111100;
3259   let Inst{21-17} = 0b00001;
3260   let Inst{16}    = isUnsigned;
3261   let Inst{15-10} = scale;
3262   let Inst{9-5}   = Rn;
3263   let Inst{4-0}   = Rd;
3264 }
3265
3266 class BaseIntegerToFPUnscaled<bit isUnsigned,
3267                       RegisterClass srcType, RegisterClass dstType,
3268                       ValueType dvt, string asm, SDNode node>
3269     : I<(outs dstType:$Rd), (ins srcType:$Rn),
3270          asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
3271       Sched<[WriteFCvt]> {
3272   bits<5> Rd;
3273   bits<5> Rn;
3274   bits<6> scale;
3275   let Inst{30-23} = 0b00111100;
3276   let Inst{21-17} = 0b10001;
3277   let Inst{16}    = isUnsigned;
3278   let Inst{15-10} = 0b000000;
3279   let Inst{9-5}   = Rn;
3280   let Inst{4-0}   = Rd;
3281 }
3282
3283 multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
3284   // Unscaled
3285   def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
3286     let Inst{31} = 0; // 32-bit GPR flag
3287     let Inst{22} = 0; // 32-bit FPR flag
3288   }
3289
3290   def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
3291     let Inst{31} = 0; // 32-bit GPR flag
3292     let Inst{22} = 1; // 64-bit FPR flag
3293   }
3294
3295   def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
3296     let Inst{31} = 1; // 64-bit GPR flag
3297     let Inst{22} = 0; // 32-bit FPR flag
3298   }
3299
3300   def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
3301     let Inst{31} = 1; // 64-bit GPR flag
3302     let Inst{22} = 1; // 64-bit FPR flag
3303   }
3304
3305   // Scaled
3306   def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
3307                              [(set FPR32:$Rd,
3308                                    (fdiv (node GPR32:$Rn),
3309                                          fixedpoint_f32_i32:$scale))]> {
3310     let Inst{31} = 0; // 32-bit GPR flag
3311     let Inst{22} = 0; // 32-bit FPR flag
3312     let scale{5} = 1;
3313   }
3314
3315   def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
3316                              [(set FPR64:$Rd,
3317                                    (fdiv (node GPR32:$Rn),
3318                                          fixedpoint_f64_i32:$scale))]> {
3319     let Inst{31} = 0; // 32-bit GPR flag
3320     let Inst{22} = 1; // 64-bit FPR flag
3321     let scale{5} = 1;
3322   }
3323
3324   def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
3325                              [(set FPR32:$Rd,
3326                                    (fdiv (node GPR64:$Rn),
3327                                          fixedpoint_f32_i64:$scale))]> {
3328     let Inst{31} = 1; // 64-bit GPR flag
3329     let Inst{22} = 0; // 32-bit FPR flag
3330   }
3331
3332   def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
3333                              [(set FPR64:$Rd,
3334                                    (fdiv (node GPR64:$Rn),
3335                                          fixedpoint_f64_i64:$scale))]> {
3336     let Inst{31} = 1; // 64-bit GPR flag
3337     let Inst{22} = 1; // 64-bit FPR flag
3338   }
3339 }
3340
3341 //---
3342 // Unscaled integer <-> floating point conversion (i.e. FMOV)
3343 //---
3344
3345 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3346 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
3347                       RegisterClass srcType, RegisterClass dstType,
3348                       string asm>
3349     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
3350         // We use COPY_TO_REGCLASS for these bitconvert operations.
3351         // copyPhysReg() expands the resultant COPY instructions after
3352         // regalloc is done. This gives greater freedom for the allocator
3353         // and related passes (coalescing, copy propagation, et. al.) to
3354         // be more effective.
3355         [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
3356       Sched<[WriteFCopy]> {
3357   bits<5> Rd;
3358   bits<5> Rn;
3359   let Inst{30-23} = 0b00111100;
3360   let Inst{21}    = 1;
3361   let Inst{20-19} = rmode;
3362   let Inst{18-16} = opcode;
3363   let Inst{15-10} = 0b000000;
3364   let Inst{9-5}   = Rn;
3365   let Inst{4-0}   = Rd;
3366 }
3367
3368 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3369 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
3370                      RegisterClass srcType, RegisterOperand dstType, string asm,
3371                      string kind>
3372     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm,
3373         "{\t$Rd"#kind#"[1], $Rn|"#kind#"\t$Rd[1], $Rn}", "", []>,
3374       Sched<[WriteFCopy]> {
3375   bits<5> Rd;
3376   bits<5> Rn;
3377   let Inst{30-23} = 0b00111101;
3378   let Inst{21}    = 1;
3379   let Inst{20-19} = rmode;
3380   let Inst{18-16} = opcode;
3381   let Inst{15-10} = 0b000000;
3382   let Inst{9-5}   = Rn;
3383   let Inst{4-0}   = Rd;
3384 }
3385
3386 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3387 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
3388                      RegisterOperand srcType, RegisterClass dstType, string asm,
3389                      string kind>
3390     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm,
3391         "{\t$Rd, $Rn"#kind#"[1]|"#kind#"\t$Rd, $Rn[1]}", "", []>,
3392       Sched<[WriteFCopy]> {
3393   bits<5> Rd;
3394   bits<5> Rn;
3395   let Inst{30-23} = 0b00111101;
3396   let Inst{21}    = 1;
3397   let Inst{20-19} = rmode;
3398   let Inst{18-16} = opcode;
3399   let Inst{15-10} = 0b000000;
3400   let Inst{9-5}   = Rn;
3401   let Inst{4-0}   = Rd;
3402 }
3403
3404
3405
3406 multiclass UnscaledConversion<string asm> {
3407   def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
3408     let Inst{31} = 0; // 32-bit GPR flag
3409     let Inst{22} = 0; // 32-bit FPR flag
3410   }
3411
3412   def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
3413     let Inst{31} = 1; // 64-bit GPR flag
3414     let Inst{22} = 1; // 64-bit FPR flag
3415   }
3416
3417   def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
3418     let Inst{31} = 0; // 32-bit GPR flag
3419     let Inst{22} = 0; // 32-bit FPR flag
3420   }
3421
3422   def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
3423     let Inst{31} = 1; // 64-bit GPR flag
3424     let Inst{22} = 1; // 64-bit FPR flag
3425   }
3426
3427   def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
3428                                              asm, ".d"> {
3429     let Inst{31} = 1;
3430     let Inst{22} = 0;
3431   }
3432
3433   def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
3434                                                asm, ".d"> {
3435     let Inst{31} = 1;
3436     let Inst{22} = 0;
3437   }
3438 }
3439
3440 //---
3441 // Floating point conversion
3442 //---
3443
3444 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
3445                        RegisterClass srcType, string asm, list<dag> pattern>
3446     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
3447       Sched<[WriteFCvt]> {
3448   bits<5> Rd;
3449   bits<5> Rn;
3450   let Inst{31-24} = 0b00011110;
3451   let Inst{23-22} = type;
3452   let Inst{21-17} = 0b10001;
3453   let Inst{16-15} = opcode;
3454   let Inst{14-10} = 0b10000;
3455   let Inst{9-5}   = Rn;
3456   let Inst{4-0}   = Rd;
3457 }
3458
3459 multiclass FPConversion<string asm> {
3460   // Double-precision to Half-precision
3461   def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
3462                              [(set FPR16:$Rd, (fround FPR64:$Rn))]>;
3463
3464   // Double-precision to Single-precision
3465   def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
3466                              [(set FPR32:$Rd, (fround FPR64:$Rn))]>;
3467
3468   // Half-precision to Double-precision
3469   def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
3470                              [(set FPR64:$Rd, (fextend FPR16:$Rn))]>;
3471
3472   // Half-precision to Single-precision
3473   def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
3474                              [(set FPR32:$Rd, (fextend FPR16:$Rn))]>;
3475
3476   // Single-precision to Double-precision
3477   def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
3478                              [(set FPR64:$Rd, (fextend FPR32:$Rn))]>;
3479
3480   // Single-precision to Half-precision
3481   def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
3482                              [(set FPR16:$Rd, (fround FPR32:$Rn))]>;
3483 }
3484
3485 //---
3486 // Single operand floating point data processing
3487 //---
3488
3489 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3490 class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
3491                               ValueType vt, string asm, SDPatternOperator node>
3492     : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
3493          [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
3494       Sched<[WriteF]> {
3495   bits<5> Rd;
3496   bits<5> Rn;
3497   let Inst{31-23} = 0b000111100;
3498   let Inst{21-19} = 0b100;
3499   let Inst{18-15} = opcode;
3500   let Inst{14-10} = 0b10000;
3501   let Inst{9-5}   = Rn;
3502   let Inst{4-0}   = Rd;
3503 }
3504
3505 multiclass SingleOperandFPData<bits<4> opcode, string asm,
3506                                SDPatternOperator node = null_frag> {
3507   def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
3508     let Inst{22} = 0; // 32-bit size flag
3509   }
3510
3511   def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
3512     let Inst{22} = 1; // 64-bit size flag
3513   }
3514 }
3515
3516 //---
3517 // Two operand floating point data processing
3518 //---
3519
3520 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3521 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
3522                            string asm, list<dag> pat>
3523     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
3524          asm, "\t$Rd, $Rn, $Rm", "", pat>,
3525       Sched<[WriteF]> {
3526   bits<5> Rd;
3527   bits<5> Rn;
3528   bits<5> Rm;
3529   let Inst{31-23} = 0b000111100;
3530   let Inst{21}    = 1;
3531   let Inst{20-16} = Rm;
3532   let Inst{15-12} = opcode;
3533   let Inst{11-10} = 0b10;
3534   let Inst{9-5}   = Rn;
3535   let Inst{4-0}   = Rd;
3536 }
3537
3538 multiclass TwoOperandFPData<bits<4> opcode, string asm,
3539                             SDPatternOperator node = null_frag> {
3540   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3541                          [(set (f32 FPR32:$Rd),
3542                                (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
3543     let Inst{22} = 0; // 32-bit size flag
3544   }
3545
3546   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3547                          [(set (f64 FPR64:$Rd),
3548                                (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
3549     let Inst{22} = 1; // 64-bit size flag
3550   }
3551 }
3552
3553 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
3554   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3555                   [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
3556     let Inst{22} = 0; // 32-bit size flag
3557   }
3558
3559   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3560                   [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
3561     let Inst{22} = 1; // 64-bit size flag
3562   }
3563 }
3564
3565
3566 //---
3567 // Three operand floating point data processing
3568 //---
3569
3570 class BaseThreeOperandFPData<bit isNegated, bit isSub,
3571                              RegisterClass regtype, string asm, list<dag> pat>
3572     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
3573          asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
3574       Sched<[WriteFMul]> {
3575   bits<5> Rd;
3576   bits<5> Rn;
3577   bits<5> Rm;
3578   bits<5> Ra;
3579   let Inst{31-23} = 0b000111110;
3580   let Inst{21}    = isNegated;
3581   let Inst{20-16} = Rm;
3582   let Inst{15}    = isSub;
3583   let Inst{14-10} = Ra;
3584   let Inst{9-5}   = Rn;
3585   let Inst{4-0}   = Rd;
3586 }
3587
3588 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
3589                               SDPatternOperator node> {
3590   def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
3591             [(set FPR32:$Rd,
3592                   (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
3593     let Inst{22} = 0; // 32-bit size flag
3594   }
3595
3596   def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
3597             [(set FPR64:$Rd,
3598                   (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
3599     let Inst{22} = 1; // 64-bit size flag
3600   }
3601 }
3602
3603 //---
3604 // Floating point data comparisons
3605 //---
3606
3607 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3608 class BaseOneOperandFPComparison<bit signalAllNans,
3609                                  RegisterClass regtype, string asm,
3610                                  list<dag> pat>
3611     : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
3612       Sched<[WriteFCmp]> {
3613   bits<5> Rn;
3614   let Inst{31-23} = 0b000111100;
3615   let Inst{21}    = 1;
3616
3617   let Inst{15-10} = 0b001000;
3618   let Inst{9-5}   = Rn;
3619   let Inst{4}     = signalAllNans;
3620   let Inst{3-0}   = 0b1000;
3621
3622   // Rm should be 0b00000 canonically, but we need to accept any value.
3623   let PostEncoderMethod = "fixOneOperandFPComparison";
3624 }
3625
3626 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3627 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
3628                                 string asm, list<dag> pat>
3629     : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
3630       Sched<[WriteFCmp]> {
3631   bits<5> Rm;
3632   bits<5> Rn;
3633   let Inst{31-23} = 0b000111100;
3634   let Inst{21}    = 1;
3635   let Inst{20-16} = Rm;
3636   let Inst{15-10} = 0b001000;
3637   let Inst{9-5}   = Rn;
3638   let Inst{4}     = signalAllNans;
3639   let Inst{3-0}   = 0b0000;
3640 }
3641
3642 multiclass FPComparison<bit signalAllNans, string asm,
3643                         SDPatternOperator OpNode = null_frag> {
3644   let Defs = [NZCV] in {
3645   def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
3646       [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
3647     let Inst{22} = 0;
3648   }
3649
3650   def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
3651       [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
3652     let Inst{22} = 0;
3653   }
3654
3655   def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
3656       [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
3657     let Inst{22} = 1;
3658   }
3659
3660   def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
3661       [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
3662     let Inst{22} = 1;
3663   }
3664   } // Defs = [NZCV]
3665 }
3666
3667 //---
3668 // Floating point conditional comparisons
3669 //---
3670
3671 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3672 class BaseFPCondComparison<bit signalAllNans,
3673                               RegisterClass regtype, string asm>
3674     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm0_15:$nzcv, ccode:$cond),
3675          asm, "\t$Rn, $Rm, $nzcv, $cond", "", []>,
3676       Sched<[WriteFCmp]> {
3677   bits<5> Rn;
3678   bits<5> Rm;
3679   bits<4> nzcv;
3680   bits<4> cond;
3681
3682   let Inst{31-23} = 0b000111100;
3683   let Inst{21}    = 1;
3684   let Inst{20-16} = Rm;
3685   let Inst{15-12} = cond;
3686   let Inst{11-10} = 0b01;
3687   let Inst{9-5}   = Rn;
3688   let Inst{4}     = signalAllNans;
3689   let Inst{3-0}   = nzcv;
3690 }
3691
3692 multiclass FPCondComparison<bit signalAllNans, string asm> {
3693   let Defs = [NZCV], Uses = [NZCV] in {
3694   def Srr : BaseFPCondComparison<signalAllNans, FPR32, asm> {
3695     let Inst{22} = 0;
3696   }
3697
3698   def Drr : BaseFPCondComparison<signalAllNans, FPR64, asm> {
3699     let Inst{22} = 1;
3700   }
3701   } // Defs = [NZCV], Uses = [NZCV]
3702 }
3703
3704 //---
3705 // Floating point conditional select
3706 //---
3707
3708 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
3709     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
3710          asm, "\t$Rd, $Rn, $Rm, $cond", "",
3711          [(set regtype:$Rd,
3712                (ARM64csel (vt regtype:$Rn), regtype:$Rm,
3713                           (i32 imm:$cond), NZCV))]>,
3714       Sched<[WriteF]> {
3715   bits<5> Rd;
3716   bits<5> Rn;
3717   bits<5> Rm;
3718   bits<4> cond;
3719
3720   let Inst{31-23} = 0b000111100;
3721   let Inst{21}    = 1;
3722   let Inst{20-16} = Rm;
3723   let Inst{15-12} = cond;
3724   let Inst{11-10} = 0b11;
3725   let Inst{9-5}   = Rn;
3726   let Inst{4-0}   = Rd;
3727 }
3728
3729 multiclass FPCondSelect<string asm> {
3730   let Uses = [NZCV] in {
3731   def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
3732     let Inst{22} = 0;
3733   }
3734
3735   def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
3736     let Inst{22} = 1;
3737   }
3738   } // Uses = [NZCV]
3739 }
3740
3741 //---
3742 // Floating move immediate
3743 //---
3744
3745 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
3746   : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
3747       [(set regtype:$Rd, fpimmtype:$imm)]>,
3748     Sched<[WriteFImm]> {
3749   bits<5> Rd;
3750   bits<8> imm;
3751   let Inst{31-23} = 0b000111100;
3752   let Inst{21}    = 1;
3753   let Inst{20-13} = imm;
3754   let Inst{12-5}  = 0b10000000;
3755   let Inst{4-0}   = Rd;
3756 }
3757
3758 multiclass FPMoveImmediate<string asm> {
3759   def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
3760     let Inst{22} = 0;
3761   }
3762
3763   def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
3764     let Inst{22} = 1;
3765   }
3766 }
3767 } // end of 'let Predicates = [HasFPARMv8]'
3768
3769 //----------------------------------------------------------------------------
3770 // AdvSIMD
3771 //----------------------------------------------------------------------------
3772
3773 class AsmVectorIndex<string Suffix> : AsmOperandClass {
3774   let Name = "VectorIndex" # Suffix;
3775   let DiagnosticType = "InvalidIndex" # Suffix;
3776 }
3777 def VectorIndexBOperand : AsmVectorIndex<"B">;
3778 def VectorIndexHOperand : AsmVectorIndex<"H">;
3779 def VectorIndexSOperand : AsmVectorIndex<"S">;
3780 def VectorIndexDOperand : AsmVectorIndex<"D">;
3781
3782 def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
3783   return ((uint64_t)Imm) < 16;
3784 }]> {
3785   let ParserMatchClass = VectorIndexBOperand;
3786   let PrintMethod = "printVectorIndex";
3787   let MIOperandInfo = (ops i64imm);
3788 }
3789 def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
3790   return ((uint64_t)Imm) < 8;
3791 }]> {
3792   let ParserMatchClass = VectorIndexHOperand;
3793   let PrintMethod = "printVectorIndex";
3794   let MIOperandInfo = (ops i64imm);
3795 }
3796 def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
3797   return ((uint64_t)Imm) < 4;
3798 }]> {
3799   let ParserMatchClass = VectorIndexSOperand;
3800   let PrintMethod = "printVectorIndex";
3801   let MIOperandInfo = (ops i64imm);
3802 }
3803 def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
3804   return ((uint64_t)Imm) < 2;
3805 }]> {
3806   let ParserMatchClass = VectorIndexDOperand;
3807   let PrintMethod = "printVectorIndex";
3808   let MIOperandInfo = (ops i64imm);
3809 }
3810
3811 def MemorySIMDNoIndexOperand : AsmOperandClass {
3812   let Name = "MemorySIMDNoIndex";
3813   let ParserMethod = "tryParseNoIndexMemory";
3814 }
3815 def am_simdnoindex : Operand<i64>,
3816                      ComplexPattern<i64, 1, "SelectAddrModeNoIndex", []> {
3817   let PrintMethod = "printAMNoIndex";
3818   let ParserMatchClass = MemorySIMDNoIndexOperand;
3819   let MIOperandInfo = (ops GPR64sp:$base);
3820   let DecoderMethod = "DecodeGPR64spRegisterClass";
3821 }
3822
3823 let Predicates = [HasNEON] in {
3824
3825 //----------------------------------------------------------------------------
3826 // AdvSIMD three register vector instructions
3827 //----------------------------------------------------------------------------
3828
3829 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3830 class BaseSIMDThreeSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
3831                         RegisterOperand regtype, string asm, string kind,
3832                         list<dag> pattern>
3833   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
3834       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
3835       "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
3836     Sched<[WriteV]> {
3837   bits<5> Rd;
3838   bits<5> Rn;
3839   bits<5> Rm;
3840   let Inst{31}    = 0;
3841   let Inst{30}    = Q;
3842   let Inst{29}    = U;
3843   let Inst{28-24} = 0b01110;
3844   let Inst{23-22} = size;
3845   let Inst{21}    = 1;
3846   let Inst{20-16} = Rm;
3847   let Inst{15-11} = opcode;
3848   let Inst{10}    = 1;
3849   let Inst{9-5}   = Rn;
3850   let Inst{4-0}   = Rd;
3851 }
3852
3853 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3854 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
3855                         RegisterOperand regtype, string asm, string kind,
3856                         list<dag> pattern>
3857   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
3858       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
3859       "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
3860     Sched<[WriteV]> {
3861   bits<5> Rd;
3862   bits<5> Rn;
3863   bits<5> Rm;
3864   let Inst{31}    = 0;
3865   let Inst{30}    = Q;
3866   let Inst{29}    = U;
3867   let Inst{28-24} = 0b01110;
3868   let Inst{23-22} = size;
3869   let Inst{21}    = 1;
3870   let Inst{20-16} = Rm;
3871   let Inst{15-11} = opcode;
3872   let Inst{10}    = 1;
3873   let Inst{9-5}   = Rn;
3874   let Inst{4-0}   = Rd;
3875 }
3876
3877 // All operand sizes distinguished in the encoding.
3878 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
3879                                SDPatternOperator OpNode> {
3880   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
3881                                       asm, ".8b",
3882          [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
3883   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
3884                                       asm, ".16b",
3885          [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
3886   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
3887                                       asm, ".4h",
3888          [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
3889   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
3890                                       asm, ".8h",
3891          [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
3892   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
3893                                       asm, ".2s",
3894          [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
3895   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
3896                                       asm, ".4s",
3897          [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
3898   def v2i64 : BaseSIMDThreeSameVector<1, U, 0b11, opc, V128,
3899                                       asm, ".2d",
3900          [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
3901 }
3902
3903 // As above, but D sized elements unsupported.
3904 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
3905                                   SDPatternOperator OpNode> {
3906   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
3907                                       asm, ".8b",
3908         [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
3909   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
3910                                       asm, ".16b",
3911         [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
3912   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
3913                                       asm, ".4h",
3914         [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
3915   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
3916                                       asm, ".8h",
3917         [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
3918   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
3919                                       asm, ".2s",
3920         [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
3921   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
3922                                       asm, ".4s",
3923         [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
3924 }
3925
3926 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
3927                                   SDPatternOperator OpNode> {
3928   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, 0b00, opc, V64,
3929                                       asm, ".8b",
3930       [(set (v8i8 V64:$dst),
3931             (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
3932   def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b00, opc, V128,
3933                                       asm, ".16b",
3934       [(set (v16i8 V128:$dst),
3935             (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
3936   def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b01, opc, V64,
3937                                       asm, ".4h",
3938       [(set (v4i16 V64:$dst),
3939             (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
3940   def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b01, opc, V128,
3941                                       asm, ".8h",
3942       [(set (v8i16 V128:$dst),
3943             (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
3944   def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b10, opc, V64,
3945                                       asm, ".2s",
3946       [(set (v2i32 V64:$dst),
3947             (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
3948   def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b10, opc, V128,
3949                                       asm, ".4s",
3950       [(set (v4i32 V128:$dst),
3951             (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
3952 }
3953
3954 // As above, but only B sized elements supported.
3955 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
3956                                 SDPatternOperator OpNode> {
3957   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
3958                                       asm, ".8b",
3959     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
3960   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
3961                                       asm, ".16b",
3962     [(set (v16i8 V128:$Rd),
3963           (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
3964 }
3965
3966 // As above, but only S and D sized floating point elements supported.
3967 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<5> opc,
3968                                  string asm, SDPatternOperator OpNode> {
3969   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
3970                                       asm, ".2s",
3971         [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
3972   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
3973                                       asm, ".4s",
3974         [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
3975   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
3976                                       asm, ".2d",
3977         [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
3978 }
3979
3980 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<5> opc,
3981                                     string asm,
3982                                     SDPatternOperator OpNode> {
3983   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
3984                                       asm, ".2s",
3985         [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
3986   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
3987                                       asm, ".4s",
3988         [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
3989   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
3990                                       asm, ".2d",
3991         [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
3992 }
3993
3994 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<5> opc,
3995                                  string asm, SDPatternOperator OpNode> {
3996   def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0}, opc, V64,
3997                                       asm, ".2s",
3998      [(set (v2f32 V64:$dst),
3999            (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4000   def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0}, opc, V128,
4001                                       asm, ".4s",
4002      [(set (v4f32 V128:$dst),
4003            (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4004   def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,1}, opc, V128,
4005                                       asm, ".2d",
4006      [(set (v2f64 V128:$dst),
4007            (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4008 }
4009
4010 // As above, but D and B sized elements unsupported.
4011 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
4012                                 SDPatternOperator OpNode> {
4013   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4014                                       asm, ".4h",
4015         [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4016   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4017                                       asm, ".8h",
4018         [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4019   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4020                                       asm, ".2s",
4021         [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4022   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4023                                       asm, ".4s",
4024         [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4025 }
4026
4027 // Logical three vector ops share opcode bits, and only use B sized elements.
4028 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
4029                                   SDPatternOperator OpNode = null_frag> {
4030   def v8i8  : BaseSIMDThreeSameVector<0, U, size, 0b00011, V64,
4031                                      asm, ".8b",
4032                          [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
4033   def v16i8  : BaseSIMDThreeSameVector<1, U, size, 0b00011, V128,
4034                                      asm, ".16b",
4035                          [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
4036
4037   def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
4038           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4039   def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
4040           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4041   def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
4042           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4043
4044   def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
4045       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4046   def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
4047       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4048   def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
4049       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4050 }
4051
4052 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
4053                                   string asm, SDPatternOperator OpNode> {
4054   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, size, 0b00011, V64,
4055                                      asm, ".8b",
4056              [(set (v8i8 V64:$dst),
4057                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4058   def v16i8  : BaseSIMDThreeSameVectorTied<1, U, size, 0b00011, V128,
4059                                      asm, ".16b",
4060              [(set (v16i8 V128:$dst),
4061                    (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
4062                            (v16i8 V128:$Rm)))]>;
4063
4064   def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
4065                            (v4i16 V64:$RHS))),
4066           (!cast<Instruction>(NAME#"v8i8")
4067             V64:$LHS, V64:$MHS, V64:$RHS)>;
4068   def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
4069                            (v2i32 V64:$RHS))),
4070           (!cast<Instruction>(NAME#"v8i8")
4071             V64:$LHS, V64:$MHS, V64:$RHS)>;
4072   def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
4073                            (v1i64 V64:$RHS))),
4074           (!cast<Instruction>(NAME#"v8i8")
4075             V64:$LHS, V64:$MHS, V64:$RHS)>;
4076
4077   def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
4078                            (v8i16 V128:$RHS))),
4079       (!cast<Instruction>(NAME#"v16i8")
4080         V128:$LHS, V128:$MHS, V128:$RHS)>;
4081   def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
4082                            (v4i32 V128:$RHS))),
4083       (!cast<Instruction>(NAME#"v16i8")
4084         V128:$LHS, V128:$MHS, V128:$RHS)>;
4085   def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
4086                            (v2i64 V128:$RHS))),
4087       (!cast<Instruction>(NAME#"v16i8")
4088         V128:$LHS, V128:$MHS, V128:$RHS)>;
4089 }
4090
4091
4092 //----------------------------------------------------------------------------
4093 // AdvSIMD two register vector instructions.
4094 //----------------------------------------------------------------------------
4095
4096 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4097 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4098                         RegisterOperand regtype, string asm, string dstkind,
4099                         string srckind, list<dag> pattern>
4100   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4101       "{\t$Rd" # dstkind # ", $Rn" # srckind #
4102       "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
4103     Sched<[WriteV]> {
4104   bits<5> Rd;
4105   bits<5> Rn;
4106   let Inst{31}    = 0;
4107   let Inst{30}    = Q;
4108   let Inst{29}    = U;
4109   let Inst{28-24} = 0b01110;
4110   let Inst{23-22} = size;
4111   let Inst{21-17} = 0b10000;
4112   let Inst{16-12} = opcode;
4113   let Inst{11-10} = 0b10;
4114   let Inst{9-5}   = Rn;
4115   let Inst{4-0}   = Rd;
4116 }
4117
4118 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4119 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4120                             RegisterOperand regtype, string asm, string dstkind,
4121                             string srckind, list<dag> pattern>
4122   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
4123       "{\t$Rd" # dstkind # ", $Rn" # srckind #
4124       "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4125     Sched<[WriteV]> {
4126   bits<5> Rd;
4127   bits<5> Rn;
4128   let Inst{31}    = 0;
4129   let Inst{30}    = Q;
4130   let Inst{29}    = U;
4131   let Inst{28-24} = 0b01110;
4132   let Inst{23-22} = size;
4133   let Inst{21-17} = 0b10000;
4134   let Inst{16-12} = opcode;
4135   let Inst{11-10} = 0b10;
4136   let Inst{9-5}   = Rn;
4137   let Inst{4-0}   = Rd;
4138 }
4139
4140 // Supports B, H, and S element sizes.
4141 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
4142                             SDPatternOperator OpNode> {
4143   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4144                                       asm, ".8b", ".8b",
4145                           [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4146   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4147                                       asm, ".16b", ".16b",
4148                           [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4149   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4150                                       asm, ".4h", ".4h",
4151                           [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4152   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4153                                       asm, ".8h", ".8h",
4154                           [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4155   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4156                                       asm, ".2s", ".2s",
4157                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4158   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4159                                       asm, ".4s", ".4s",
4160                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4161 }
4162
4163 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
4164                             RegisterOperand regtype, string asm, string dstkind,
4165                             string srckind, string amount>
4166   : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
4167       "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
4168       "|" # dstkind # "\t$Rd, $Rn, #" #  amount # "}", "", []>,
4169     Sched<[WriteV]> {
4170   bits<5> Rd;
4171   bits<5> Rn;
4172   let Inst{31}    = 0;
4173   let Inst{30}    = Q;
4174   let Inst{29-24} = 0b101110;
4175   let Inst{23-22} = size;
4176   let Inst{21-10} = 0b100001001110;
4177   let Inst{9-5}   = Rn;
4178   let Inst{4-0}   = Rd;
4179 }
4180
4181 multiclass SIMDVectorLShiftLongBySizeBHS {
4182   let neverHasSideEffects = 1 in {
4183   def v8i8  : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
4184                                              "shll", ".8h",  ".8b", "8">;
4185   def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
4186                                              "shll2", ".8h", ".16b", "8">;
4187   def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
4188                                              "shll", ".4s",  ".4h", "16">;
4189   def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
4190                                              "shll2", ".4s", ".8h", "16">;
4191   def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
4192                                              "shll", ".2d",  ".2s", "32">;
4193   def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
4194                                              "shll2", ".2d", ".4s", "32">;
4195   }
4196 }
4197
4198 // Supports all element sizes.
4199 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
4200                              SDPatternOperator OpNode> {
4201   def v8i8_v4i16  : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4202                                       asm, ".4h", ".8b",
4203                [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4204   def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4205                                       asm, ".8h", ".16b",
4206                [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4207   def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4208                                       asm, ".2s", ".4h",
4209                [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4210   def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4211                                       asm, ".4s", ".8h",
4212                [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4213   def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4214                                       asm, ".1d", ".2s",
4215                [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4216   def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4217                                       asm, ".2d", ".4s",
4218                [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4219 }
4220
4221 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
4222                                  SDPatternOperator OpNode> {
4223   def v8i8_v4i16  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4224                                           asm, ".4h", ".8b",
4225       [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
4226                                       (v8i8 V64:$Rn)))]>;
4227   def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4228                                           asm, ".8h", ".16b",
4229       [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
4230                                       (v16i8 V128:$Rn)))]>;
4231   def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4232                                           asm, ".2s", ".4h",
4233       [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
4234                                       (v4i16 V64:$Rn)))]>;
4235   def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4236                                           asm, ".4s", ".8h",
4237       [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
4238                                       (v8i16 V128:$Rn)))]>;
4239   def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4240                                           asm, ".1d", ".2s",
4241       [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
4242                                       (v2i32 V64:$Rn)))]>;
4243   def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4244                                           asm, ".2d", ".4s",
4245       [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
4246                                       (v4i32 V128:$Rn)))]>;
4247 }
4248
4249 // Supports all element sizes, except 1xD.
4250 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
4251                                   SDPatternOperator OpNode> {
4252   def v8i8  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4253                                     asm, ".8b", ".8b",
4254     [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
4255   def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4256                                     asm, ".16b", ".16b",
4257     [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
4258   def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4259                                     asm, ".4h", ".4h",
4260     [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
4261   def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4262                                     asm, ".8h", ".8h",
4263     [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
4264   def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4265                                     asm, ".2s", ".2s",
4266     [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
4267   def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4268                                     asm, ".4s", ".4s",
4269     [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
4270   def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, V128,
4271                                     asm, ".2d", ".2d",
4272     [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
4273 }
4274
4275 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
4276                              SDPatternOperator OpNode = null_frag> {
4277   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4278                                 asm, ".8b", ".8b",
4279     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4280   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4281                                 asm, ".16b", ".16b",
4282     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4283   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4284                                 asm, ".4h", ".4h",
4285     [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4286   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4287                                 asm, ".8h", ".8h",
4288     [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4289   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4290                                 asm, ".2s", ".2s",
4291     [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4292   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4293                                 asm, ".4s", ".4s",
4294     [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4295   def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, V128,
4296                                 asm, ".2d", ".2d",
4297     [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4298 }
4299
4300
4301 // Supports only B element sizes.
4302 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
4303                           SDPatternOperator OpNode> {
4304   def v8i8  : BaseSIMDTwoSameVector<0, U, size, opc, V64,
4305                                 asm, ".8b", ".8b",
4306                     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4307   def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, V128,
4308                                 asm, ".16b", ".16b",
4309                     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4310
4311 }
4312
4313 // Supports only B and H element sizes.
4314 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
4315                                 SDPatternOperator OpNode> {
4316   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4317                                 asm, ".8b", ".8b",
4318                     [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
4319   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4320                                 asm, ".16b", ".16b",
4321                     [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
4322   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4323                                 asm, ".4h", ".4h",
4324                     [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
4325   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4326                                 asm, ".8h", ".8h",
4327                     [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
4328 }
4329
4330 // Supports only S and D element sizes, uses high bit of the size field
4331 // as an extra opcode bit.
4332 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
4333                            SDPatternOperator OpNode> {
4334   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4335                                 asm, ".2s", ".2s",
4336                           [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4337   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4338                                 asm, ".4s", ".4s",
4339                           [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4340   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4341                                 asm, ".2d", ".2d",
4342                           [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4343 }
4344
4345 // Supports only S element size.
4346 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
4347                            SDPatternOperator OpNode> {
4348   def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4349                                 asm, ".2s", ".2s",
4350                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4351   def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4352                                 asm, ".4s", ".4s",
4353                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4354 }
4355
4356
4357 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
4358                            SDPatternOperator OpNode> {
4359   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4360                                 asm, ".2s", ".2s",
4361                           [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4362   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4363                                 asm, ".4s", ".4s",
4364                           [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4365   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4366                                 asm, ".2d", ".2d",
4367                           [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4368 }
4369
4370 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
4371                            SDPatternOperator OpNode> {
4372   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4373                                 asm, ".2s", ".2s",
4374                           [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4375   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4376                                 asm, ".4s", ".4s",
4377                           [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4378   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4379                                 asm, ".2d", ".2d",
4380                           [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4381 }
4382
4383
4384 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4385                            RegisterOperand inreg, RegisterOperand outreg,
4386                            string asm, string outkind, string inkind,
4387                            list<dag> pattern>
4388   : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
4389       "{\t$Rd" # outkind # ", $Rn" # inkind #
4390       "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
4391     Sched<[WriteV]> {
4392   bits<5> Rd;
4393   bits<5> Rn;
4394   let Inst{31}    = 0;
4395   let Inst{30}    = Q;
4396   let Inst{29}    = U;
4397   let Inst{28-24} = 0b01110;
4398   let Inst{23-22} = size;
4399   let Inst{21-17} = 0b10000;
4400   let Inst{16-12} = opcode;
4401   let Inst{11-10} = 0b10;
4402   let Inst{9-5}   = Rn;
4403   let Inst{4-0}   = Rd;
4404 }
4405
4406 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4407                            RegisterOperand inreg, RegisterOperand outreg,
4408                            string asm, string outkind, string inkind,
4409                            list<dag> pattern>
4410   : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
4411       "{\t$Rd" # outkind # ", $Rn" # inkind #
4412       "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4413     Sched<[WriteV]> {
4414   bits<5> Rd;
4415   bits<5> Rn;
4416   let Inst{31}    = 0;
4417   let Inst{30}    = Q;
4418   let Inst{29}    = U;
4419   let Inst{28-24} = 0b01110;
4420   let Inst{23-22} = size;
4421   let Inst{21-17} = 0b10000;
4422   let Inst{16-12} = opcode;
4423   let Inst{11-10} = 0b10;
4424   let Inst{9-5}   = Rn;
4425   let Inst{4-0}   = Rd;
4426 }
4427
4428 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
4429                               SDPatternOperator OpNode> {
4430   def v8i8  : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
4431                                       asm, ".8b", ".8h",
4432         [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4433   def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
4434                                       asm#"2", ".16b", ".8h", []>;
4435   def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
4436                                       asm, ".4h", ".4s",
4437         [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4438   def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
4439                                       asm#"2", ".8h", ".4s", []>;
4440   def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
4441                                       asm, ".2s", ".2d",
4442         [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4443   def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
4444                                       asm#"2", ".4s", ".2d", []>;
4445
4446   def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
4447             (!cast<Instruction>(NAME # "v16i8")
4448                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4449   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
4450             (!cast<Instruction>(NAME # "v8i16")
4451                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4452   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
4453             (!cast<Instruction>(NAME # "v4i32")
4454                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4455 }
4456
4457 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4458                            RegisterOperand regtype,
4459                            string asm, string kind, string zero,
4460                            ValueType dty, ValueType sty, SDNode OpNode>
4461   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4462       "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
4463       "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
4464       [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
4465     Sched<[WriteV]> {
4466   bits<5> Rd;
4467   bits<5> Rn;
4468   let Inst{31}    = 0;
4469   let Inst{30}    = Q;
4470   let Inst{29}    = U;
4471   let Inst{28-24} = 0b01110;
4472   let Inst{23-22} = size;
4473   let Inst{21-17} = 0b10000;
4474   let Inst{16-12} = opcode;
4475   let Inst{11-10} = 0b10;
4476   let Inst{9-5}   = Rn;
4477   let Inst{4-0}   = Rd;
4478 }
4479
4480 // Comparisons support all element sizes, except 1xD.
4481 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
4482                             SDNode OpNode> {
4483   def v8i8rz  : BaseSIMDCmpTwoVector<0, U, 0b00, opc, V64,
4484                                      asm, ".8b", "0",
4485                                      v8i8, v8i8, OpNode>;
4486   def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, opc, V128,
4487                                      asm, ".16b", "0",
4488                                      v16i8, v16i8, OpNode>;
4489   def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, opc, V64,
4490                                      asm, ".4h", "0",
4491                                      v4i16, v4i16, OpNode>;
4492   def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, opc, V128,
4493                                      asm, ".8h", "0",
4494                                      v8i16, v8i16, OpNode>;
4495   def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, opc, V64,
4496                                      asm, ".2s", "0",
4497                                      v2i32, v2i32, OpNode>;
4498   def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, opc, V128,
4499                                      asm, ".4s", "0",
4500                                      v4i32, v4i32, OpNode>;
4501   def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, opc, V128,
4502                                      asm, ".2d", "0",
4503                                      v2i64, v2i64, OpNode>;
4504 }
4505
4506 // FP Comparisons support only S and D element sizes.
4507 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
4508                               string asm, SDNode OpNode> {
4509
4510   def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, opc, V64,
4511                                      asm, ".2s", "0.0",
4512                                      v2i32, v2f32, OpNode>;
4513   def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, opc, V128,
4514                                      asm, ".4s", "0.0",
4515                                      v4i32, v4f32, OpNode>;
4516   def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, opc, V128,
4517                                      asm, ".2d", "0.0",
4518                                      v2i64, v2f64, OpNode>;
4519
4520   def : InstAlias<asm # " $Vd.2s, $Vn.2s, #0",
4521                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
4522   def : InstAlias<asm # " $Vd.4s, $Vn.4s, #0",
4523                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
4524   def : InstAlias<asm # " $Vd.2d, $Vn.2d, #0",
4525                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
4526   def : InstAlias<asm # ".2s $Vd, $Vn, #0",
4527                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
4528   def : InstAlias<asm # ".4s $Vd, $Vn, #0",
4529                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
4530   def : InstAlias<asm # ".2d $Vd, $Vn, #0",
4531                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
4532 }
4533
4534 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4535 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4536                              RegisterOperand outtype, RegisterOperand intype,
4537                              string asm, string VdTy, string VnTy,
4538                              list<dag> pattern>
4539   : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
4540       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
4541     Sched<[WriteV]> {
4542   bits<5> Rd;
4543   bits<5> Rn;
4544   let Inst{31}    = 0;
4545   let Inst{30}    = Q;
4546   let Inst{29}    = U;
4547   let Inst{28-24} = 0b01110;
4548   let Inst{23-22} = size;
4549   let Inst{21-17} = 0b10000;
4550   let Inst{16-12} = opcode;
4551   let Inst{11-10} = 0b10;
4552   let Inst{9-5}   = Rn;
4553   let Inst{4-0}   = Rd;
4554 }
4555
4556 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4557                              RegisterOperand outtype, RegisterOperand intype,
4558                              string asm, string VdTy, string VnTy,
4559                              list<dag> pattern>
4560   : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
4561       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
4562     Sched<[WriteV]> {
4563   bits<5> Rd;
4564   bits<5> Rn;
4565   let Inst{31}    = 0;
4566   let Inst{30}    = Q;
4567   let Inst{29}    = U;
4568   let Inst{28-24} = 0b01110;
4569   let Inst{23-22} = size;
4570   let Inst{21-17} = 0b10000;
4571   let Inst{16-12} = opcode;
4572   let Inst{11-10} = 0b10;
4573   let Inst{9-5}   = Rn;
4574   let Inst{4-0}   = Rd;
4575 }
4576
4577 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
4578   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
4579                                     asm, ".4s", ".4h", []>;
4580   def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
4581                                     asm#"2", ".4s", ".8h", []>;
4582   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
4583                                     asm, ".2d", ".2s", []>;
4584   def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
4585                                     asm#"2", ".2d", ".4s", []>;
4586 }
4587
4588 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
4589   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
4590                                     asm, ".4h", ".4s", []>;
4591   def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
4592                                     asm#"2", ".8h", ".4s", []>;
4593   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4594                                     asm, ".2s", ".2d", []>;
4595   def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4596                                     asm#"2", ".4s", ".2d", []>;
4597 }
4598
4599 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
4600                                      Intrinsic OpNode> {
4601   def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4602                                      asm, ".2s", ".2d",
4603                           [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4604   def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4605                                     asm#"2", ".4s", ".2d", []>;
4606
4607   def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
4608             (!cast<Instruction>(NAME # "v4f32")
4609                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4610 }
4611
4612 //----------------------------------------------------------------------------
4613 // AdvSIMD three register different-size vector instructions.
4614 //----------------------------------------------------------------------------
4615
4616 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4617 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
4618                       RegisterOperand outtype, RegisterOperand intype1,
4619                       RegisterOperand intype2, string asm,
4620                       string outkind, string inkind1, string inkind2,
4621                       list<dag> pattern>
4622   : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
4623       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4624       "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
4625     Sched<[WriteV]> {
4626   bits<5> Rd;
4627   bits<5> Rn;
4628   bits<5> Rm;
4629   let Inst{31}    = 0;
4630   let Inst{30}    = size{0};
4631   let Inst{29}    = U;
4632   let Inst{28-24} = 0b01110;
4633   let Inst{23-22} = size{2-1};
4634   let Inst{21}    = 1;
4635   let Inst{20-16} = Rm;
4636   let Inst{15-12} = opcode;
4637   let Inst{11-10} = 0b00;
4638   let Inst{9-5}   = Rn;
4639   let Inst{4-0}   = Rd;
4640 }
4641
4642 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4643 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
4644                       RegisterOperand outtype, RegisterOperand intype1,
4645                       RegisterOperand intype2, string asm,
4646                       string outkind, string inkind1, string inkind2,
4647                       list<dag> pattern>
4648   : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
4649       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4650       "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4651     Sched<[WriteV]> {
4652   bits<5> Rd;
4653   bits<5> Rn;
4654   bits<5> Rm;
4655   let Inst{31}    = 0;
4656   let Inst{30}    = size{0};
4657   let Inst{29}    = U;
4658   let Inst{28-24} = 0b01110;
4659   let Inst{23-22} = size{2-1};
4660   let Inst{21}    = 1;
4661   let Inst{20-16} = Rm;
4662   let Inst{15-12} = opcode;
4663   let Inst{11-10} = 0b00;
4664   let Inst{9-5}   = Rn;
4665   let Inst{4-0}   = Rd;
4666 }
4667
4668 // FIXME: TableGen doesn't know how to deal with expanded types that also
4669 //        change the element count (in this case, placing the results in
4670 //        the high elements of the result register rather than the low
4671 //        elements). Until that's fixed, we can't code-gen those.
4672 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
4673                                     Intrinsic IntOp> {
4674   def v8i16_v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4675                                                   V64, V128, V128,
4676                                                   asm, ".8b", ".8h", ".8h",
4677      [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4678   def v8i16_v16i8  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
4679                                                   V128, V128, V128,
4680                                                   asm#"2", ".16b", ".8h", ".8h",
4681      []>;
4682   def v4i32_v4i16  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4683                                                   V64, V128, V128,
4684                                                   asm, ".4h", ".4s", ".4s",
4685      [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4686   def v4i32_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4687                                                   V128, V128, V128,
4688                                                   asm#"2", ".8h", ".4s", ".4s",
4689      []>;
4690   def v2i64_v2i32  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4691                                                   V64, V128, V128,
4692                                                   asm, ".2s", ".2d", ".2d",
4693      [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4694   def v2i64_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4695                                                   V128, V128, V128,
4696                                                   asm#"2", ".4s", ".2d", ".2d",
4697      []>;
4698
4699
4700   // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
4701   // a version attached to an instruction.
4702   def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
4703                                                    (v8i16 V128:$Rm))),
4704             (!cast<Instruction>(NAME # "v8i16_v16i8")
4705                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4706                 V128:$Rn, V128:$Rm)>;
4707   def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
4708                                                     (v4i32 V128:$Rm))),
4709             (!cast<Instruction>(NAME # "v4i32_v8i16")
4710                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4711                 V128:$Rn, V128:$Rm)>;
4712   def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
4713                                                     (v2i64 V128:$Rm))),
4714             (!cast<Instruction>(NAME # "v2i64_v4i32")
4715                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4716                 V128:$Rn, V128:$Rm)>;
4717 }
4718
4719 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
4720                                       Intrinsic IntOp> {
4721   def v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4722                                             V128, V64, V64,
4723                                             asm, ".8h", ".8b", ".8b",
4724       [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4725   def v16i8  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
4726                                             V128, V128, V128,
4727                                             asm#"2", ".8h", ".16b", ".16b", []>;
4728   let Predicates = [HasCrypto] in {
4729     def v1i64  : BaseSIMDDifferentThreeVector<U, 0b110, opc,
4730                                               V128, V64, V64,
4731                                               asm, ".1q", ".1d", ".1d", []>;
4732     def v2i64  : BaseSIMDDifferentThreeVector<U, 0b111, opc,
4733                                               V128, V128, V128,
4734                                               asm#"2", ".1q", ".2d", ".2d", []>;
4735   }
4736
4737   def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
4738                           (v8i8 (extract_high_v16i8 V128:$Rm)))),
4739       (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
4740 }
4741
4742 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
4743                                  SDPatternOperator OpNode> {
4744   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4745                                                   V128, V64, V64,
4746                                                   asm, ".4s", ".4h", ".4h",
4747       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4748   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
4749                                                   V128, V128, V128,
4750                                                   asm#"2", ".4s", ".8h", ".8h",
4751       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
4752                                       (extract_high_v8i16 V128:$Rm)))]>;
4753   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4754                                                   V128, V64, V64,
4755                                                   asm, ".2d", ".2s", ".2s",
4756       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4757   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
4758                                                   V128, V128, V128,
4759                                                   asm#"2", ".2d", ".4s", ".4s",
4760       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
4761                                       (extract_high_v4i32 V128:$Rm)))]>;
4762 }
4763
4764 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
4765                                   SDPatternOperator OpNode = null_frag> {
4766   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4767                                                   V128, V64, V64,
4768                                                   asm, ".8h", ".8b", ".8b",
4769       [(set (v8i16 V128:$Rd),
4770             (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
4771   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
4772                                                  V128, V128, V128,
4773                                                  asm#"2", ".8h", ".16b", ".16b",
4774       [(set (v8i16 V128:$Rd),
4775             (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
4776                                 (extract_high_v16i8 V128:$Rm)))))]>;
4777   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4778                                                   V128, V64, V64,
4779                                                   asm, ".4s", ".4h", ".4h",
4780       [(set (v4i32 V128:$Rd),
4781             (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
4782   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
4783                                                   V128, V128, V128,
4784                                                   asm#"2", ".4s", ".8h", ".8h",
4785       [(set (v4i32 V128:$Rd),
4786             (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
4787                                   (extract_high_v8i16 V128:$Rm)))))]>;
4788   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4789                                                   V128, V64, V64,
4790                                                   asm, ".2d", ".2s", ".2s",
4791       [(set (v2i64 V128:$Rd),
4792             (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
4793   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
4794                                                   V128, V128, V128,
4795                                                   asm#"2", ".2d", ".4s", ".4s",
4796       [(set (v2i64 V128:$Rd),
4797             (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
4798                                  (extract_high_v4i32 V128:$Rm)))))]>;
4799 }
4800
4801 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
4802                                           string asm,
4803                                           SDPatternOperator OpNode> {
4804   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
4805                                                   V128, V64, V64,
4806                                                   asm, ".8h", ".8b", ".8b",
4807     [(set (v8i16 V128:$dst),
4808           (add (v8i16 V128:$Rd),
4809                (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
4810   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
4811                                                  V128, V128, V128,
4812                                                  asm#"2", ".8h", ".16b", ".16b",
4813     [(set (v8i16 V128:$dst),
4814           (add (v8i16 V128:$Rd),
4815                (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
4816                                    (extract_high_v16i8 V128:$Rm))))))]>;
4817   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
4818                                                   V128, V64, V64,
4819                                                   asm, ".4s", ".4h", ".4h",
4820     [(set (v4i32 V128:$dst),
4821           (add (v4i32 V128:$Rd),
4822                (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
4823   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4824                                                   V128, V128, V128,
4825                                                   asm#"2", ".4s", ".8h", ".8h",
4826     [(set (v4i32 V128:$dst),
4827           (add (v4i32 V128:$Rd),
4828                (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
4829                                     (extract_high_v8i16 V128:$Rm))))))]>;
4830   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
4831                                                   V128, V64, V64,
4832                                                   asm, ".2d", ".2s", ".2s",
4833     [(set (v2i64 V128:$dst),
4834           (add (v2i64 V128:$Rd),
4835                (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
4836   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4837                                                   V128, V128, V128,
4838                                                   asm#"2", ".2d", ".4s", ".4s",
4839     [(set (v2i64 V128:$dst),
4840           (add (v2i64 V128:$Rd),
4841                (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
4842                                     (extract_high_v4i32 V128:$Rm))))))]>;
4843 }
4844
4845 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
4846                                   SDPatternOperator OpNode = null_frag> {
4847   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4848                                                   V128, V64, V64,
4849                                                   asm, ".8h", ".8b", ".8b",
4850       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4851   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
4852                                                  V128, V128, V128,
4853                                                  asm#"2", ".8h", ".16b", ".16b",
4854       [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
4855                                       (extract_high_v16i8 V128:$Rm)))]>;
4856   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4857                                                   V128, V64, V64,
4858                                                   asm, ".4s", ".4h", ".4h",
4859       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4860   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
4861                                                   V128, V128, V128,
4862                                                   asm#"2", ".4s", ".8h", ".8h",
4863       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
4864                                       (extract_high_v8i16 V128:$Rm)))]>;
4865   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4866                                                   V128, V64, V64,
4867                                                   asm, ".2d", ".2s", ".2s",
4868       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4869   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
4870                                                   V128, V128, V128,
4871                                                   asm#"2", ".2d", ".4s", ".4s",
4872       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
4873                                       (extract_high_v4i32 V128:$Rm)))]>;
4874 }
4875
4876 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
4877                                       string asm,
4878                                       SDPatternOperator OpNode> {
4879   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
4880                                                   V128, V64, V64,
4881                                                   asm, ".8h", ".8b", ".8b",
4882     [(set (v8i16 V128:$dst),
4883           (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4884   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
4885                                                  V128, V128, V128,
4886                                                  asm#"2", ".8h", ".16b", ".16b",
4887     [(set (v8i16 V128:$dst),
4888           (OpNode (v8i16 V128:$Rd),
4889                   (extract_high_v16i8 V128:$Rn),
4890                   (extract_high_v16i8 V128:$Rm)))]>;
4891   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
4892                                                   V128, V64, V64,
4893                                                   asm, ".4s", ".4h", ".4h",
4894     [(set (v4i32 V128:$dst),
4895           (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4896   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4897                                                   V128, V128, V128,
4898                                                   asm#"2", ".4s", ".8h", ".8h",
4899     [(set (v4i32 V128:$dst),
4900           (OpNode (v4i32 V128:$Rd),
4901                   (extract_high_v8i16 V128:$Rn),
4902                   (extract_high_v8i16 V128:$Rm)))]>;
4903   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
4904                                                   V128, V64, V64,
4905                                                   asm, ".2d", ".2s", ".2s",
4906     [(set (v2i64 V128:$dst),
4907           (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4908   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4909                                                   V128, V128, V128,
4910                                                   asm#"2", ".2d", ".4s", ".4s",
4911     [(set (v2i64 V128:$dst),
4912           (OpNode (v2i64 V128:$Rd),
4913                   (extract_high_v4i32 V128:$Rn),
4914                   (extract_high_v4i32 V128:$Rm)))]>;
4915 }
4916
4917 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
4918                                            SDPatternOperator Accum> {
4919   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
4920                                                   V128, V64, V64,
4921                                                   asm, ".4s", ".4h", ".4h",
4922     [(set (v4i32 V128:$dst),
4923           (Accum (v4i32 V128:$Rd),
4924                  (v4i32 (int_arm64_neon_sqdmull (v4i16 V64:$Rn),
4925                                                 (v4i16 V64:$Rm)))))]>;
4926   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4927                                                   V128, V128, V128,
4928                                                   asm#"2", ".4s", ".8h", ".8h",
4929     [(set (v4i32 V128:$dst),
4930           (Accum (v4i32 V128:$Rd),
4931                  (v4i32 (int_arm64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
4932                                             (extract_high_v8i16 V128:$Rm)))))]>;
4933   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
4934                                                   V128, V64, V64,
4935                                                   asm, ".2d", ".2s", ".2s",
4936     [(set (v2i64 V128:$dst),
4937           (Accum (v2i64 V128:$Rd),
4938                  (v2i64 (int_arm64_neon_sqdmull (v2i32 V64:$Rn),
4939                                                 (v2i32 V64:$Rm)))))]>;
4940   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4941                                                   V128, V128, V128,
4942                                                   asm#"2", ".2d", ".4s", ".4s",
4943     [(set (v2i64 V128:$dst),
4944           (Accum (v2i64 V128:$Rd),
4945                  (v2i64 (int_arm64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
4946                                             (extract_high_v4i32 V128:$Rm)))))]>;
4947 }
4948
4949 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
4950                                   SDPatternOperator OpNode> {
4951   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4952                                                   V128, V128, V64,
4953                                                   asm, ".8h", ".8h", ".8b",
4954        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
4955   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
4956                                                   V128, V128, V128,
4957                                                   asm#"2", ".8h", ".8h", ".16b",
4958        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
4959                                        (extract_high_v16i8 V128:$Rm)))]>;
4960   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4961                                                   V128, V128, V64,
4962                                                   asm, ".4s", ".4s", ".4h",
4963        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
4964   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
4965                                                   V128, V128, V128,
4966                                                   asm#"2", ".4s", ".4s", ".8h",
4967        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
4968                                        (extract_high_v8i16 V128:$Rm)))]>;
4969   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4970                                                   V128, V128, V64,
4971                                                   asm, ".2d", ".2d", ".2s",
4972        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
4973   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
4974                                                   V128, V128, V128,
4975                                                   asm#"2", ".2d", ".2d", ".4s",
4976        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
4977                                        (extract_high_v4i32 V128:$Rm)))]>;
4978 }
4979
4980 //----------------------------------------------------------------------------
4981 // AdvSIMD bitwise extract from vector
4982 //----------------------------------------------------------------------------
4983
4984 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
4985                              string asm, string kind>
4986   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
4987       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
4988       "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
4989       [(set (vty regtype:$Rd),
4990             (ARM64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
4991     Sched<[WriteV]> {
4992   bits<5> Rd;
4993   bits<5> Rn;
4994   bits<5> Rm;
4995   bits<4> imm;
4996   let Inst{31}    = 0;
4997   let Inst{30}    = size;
4998   let Inst{29-21} = 0b101110000;
4999   let Inst{20-16} = Rm;
5000   let Inst{15}    = 0;
5001   let Inst{14-11} = imm;
5002   let Inst{10}    = 0;
5003   let Inst{9-5}   = Rn;
5004   let Inst{4-0}   = Rd;
5005 }
5006
5007
5008 multiclass SIMDBitwiseExtract<string asm> {
5009   def v8i8  : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
5010     let imm{3} = 0;
5011   }
5012   def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
5013 }
5014
5015 //----------------------------------------------------------------------------
5016 // AdvSIMD zip vector
5017 //----------------------------------------------------------------------------
5018
5019 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
5020                         string asm, string kind, SDNode OpNode, ValueType valty>
5021   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5022       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5023       "|" # kind # "\t$Rd, $Rn, $Rm}", "",
5024       [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
5025     Sched<[WriteV]> {
5026   bits<5> Rd;
5027   bits<5> Rn;
5028   bits<5> Rm;
5029   let Inst{31}    = 0;
5030   let Inst{30}    = size{0};
5031   let Inst{29-24} = 0b001110;
5032   let Inst{23-22} = size{2-1};
5033   let Inst{21}    = 0;
5034   let Inst{20-16} = Rm;
5035   let Inst{15}    = 0;
5036   let Inst{14-12} = opc;
5037   let Inst{11-10} = 0b10;
5038   let Inst{9-5}   = Rn;
5039   let Inst{4-0}   = Rd;
5040 }
5041
5042 multiclass SIMDZipVector<bits<3>opc, string asm,
5043                          SDNode OpNode> {
5044   def v8i8   : BaseSIMDZipVector<0b000, opc, V64,
5045       asm, ".8b", OpNode, v8i8>;
5046   def v16i8  : BaseSIMDZipVector<0b001, opc, V128,
5047       asm, ".16b", OpNode, v16i8>;
5048   def v4i16  : BaseSIMDZipVector<0b010, opc, V64,
5049       asm, ".4h", OpNode, v4i16>;
5050   def v8i16  : BaseSIMDZipVector<0b011, opc, V128,
5051       asm, ".8h", OpNode, v8i16>;
5052   def v2i32  : BaseSIMDZipVector<0b100, opc, V64,
5053       asm, ".2s", OpNode, v2i32>;
5054   def v4i32  : BaseSIMDZipVector<0b101, opc, V128,
5055       asm, ".4s", OpNode, v4i32>;
5056   def v2i64  : BaseSIMDZipVector<0b111, opc, V128,
5057       asm, ".2d", OpNode, v2i64>;
5058
5059   def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
5060         (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
5061   def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
5062         (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
5063   def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
5064         (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
5065 }
5066
5067 //----------------------------------------------------------------------------
5068 // AdvSIMD three register scalar instructions
5069 //----------------------------------------------------------------------------
5070
5071 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5072 class BaseSIMDThreeScalar<bit U, bits<2> size, bits<5> opcode,
5073                         RegisterClass regtype, string asm,
5074                         list<dag> pattern>
5075   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5076       "\t$Rd, $Rn, $Rm", "", pattern>,
5077     Sched<[WriteV]> {
5078   bits<5> Rd;
5079   bits<5> Rn;
5080   bits<5> Rm;
5081   let Inst{31-30} = 0b01;
5082   let Inst{29}    = U;
5083   let Inst{28-24} = 0b11110;
5084   let Inst{23-22} = size;
5085   let Inst{21}    = 1;
5086   let Inst{20-16} = Rm;
5087   let Inst{15-11} = opcode;
5088   let Inst{10}    = 1;
5089   let Inst{9-5}   = Rn;
5090   let Inst{4-0}   = Rd;
5091 }
5092
5093 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
5094                             SDPatternOperator OpNode> {
5095   def v1i64  : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
5096     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5097 }
5098
5099 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
5100                                SDPatternOperator OpNode> {
5101   def v1i64  : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
5102     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5103   def v1i32  : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm, []>;
5104   def v1i16  : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
5105   def v1i8   : BaseSIMDThreeScalar<U, 0b00, opc, FPR8 , asm, []>;
5106
5107   def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
5108             (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
5109   def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
5110             (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
5111 }
5112
5113 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
5114                              SDPatternOperator OpNode> {
5115   def v1i32  : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm,
5116                              [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5117   def v1i16  : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
5118 }
5119
5120 multiclass SIMDThreeScalarSD<bit U, bit S, bits<5> opc, string asm,
5121                              SDPatternOperator OpNode = null_frag> {
5122   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5123     def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
5124       [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5125     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
5126       [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5127   }
5128
5129   def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5130             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5131 }
5132
5133 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<5> opc, string asm,
5134                                 SDPatternOperator OpNode = null_frag> {
5135   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5136     def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
5137       [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5138     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
5139       [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
5140   }
5141
5142   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5143             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5144 }
5145
5146 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
5147               dag oops, dag iops, string asm, string cstr, list<dag> pat>
5148   : I<oops, iops, asm,
5149       "\t$Rd, $Rn, $Rm", cstr, pat>,
5150     Sched<[WriteV]> {
5151   bits<5> Rd;
5152   bits<5> Rn;
5153   bits<5> Rm;
5154   let Inst{31-30} = 0b01;
5155   let Inst{29}    = U;
5156   let Inst{28-24} = 0b11110;
5157   let Inst{23-22} = size;
5158   let Inst{21}    = 1;
5159   let Inst{20-16} = Rm;
5160   let Inst{15-11} = opcode;
5161   let Inst{10}    = 0;
5162   let Inst{9-5}   = Rn;
5163   let Inst{4-0}   = Rd;
5164 }
5165
5166 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5167 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
5168                                   SDPatternOperator OpNode = null_frag> {
5169   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5170                                       (outs FPR32:$Rd),
5171                                       (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
5172   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5173                                       (outs FPR64:$Rd),
5174                                       (ins FPR32:$Rn, FPR32:$Rm), asm, "",
5175             [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5176 }
5177
5178 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5179 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
5180                                   SDPatternOperator OpNode = null_frag> {
5181   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5182                                       (outs FPR32:$dst),
5183                                       (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
5184                                       asm, "$Rd = $dst", []>;
5185   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5186                                       (outs FPR64:$dst),
5187                                       (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
5188                                       asm, "$Rd = $dst",
5189             [(set (i64 FPR64:$dst),
5190                   (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5191 }
5192
5193 //----------------------------------------------------------------------------
5194 // AdvSIMD two register scalar instructions
5195 //----------------------------------------------------------------------------
5196
5197 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5198 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<5> opcode,
5199                         RegisterClass regtype, RegisterClass regtype2,
5200                         string asm, list<dag> pat>
5201   : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
5202       "\t$Rd, $Rn", "", pat>,
5203     Sched<[WriteV]> {
5204   bits<5> Rd;
5205   bits<5> Rn;
5206   let Inst{31-30} = 0b01;
5207   let Inst{29}    = U;
5208   let Inst{28-24} = 0b11110;
5209   let Inst{23-22} = size;
5210   let Inst{21-17} = 0b10000;
5211   let Inst{16-12} = opcode;
5212   let Inst{11-10} = 0b10;
5213   let Inst{9-5}   = Rn;
5214   let Inst{4-0}   = Rd;
5215 }
5216
5217 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5218 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
5219                         RegisterClass regtype, RegisterClass regtype2,
5220                         string asm, list<dag> pat>
5221   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
5222       "\t$Rd, $Rn", "$Rd = $dst", pat>,
5223     Sched<[WriteV]> {
5224   bits<5> Rd;
5225   bits<5> Rn;
5226   let Inst{31-30} = 0b01;
5227   let Inst{29}    = U;
5228   let Inst{28-24} = 0b11110;
5229   let Inst{23-22} = size;
5230   let Inst{21-17} = 0b10000;
5231   let Inst{16-12} = opcode;
5232   let Inst{11-10} = 0b10;
5233   let Inst{9-5}   = Rn;
5234   let Inst{4-0}   = Rd;
5235 }
5236
5237
5238 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5239 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<5> opcode,
5240                         RegisterClass regtype, string asm, string zero>
5241   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5242       "\t$Rd, $Rn, #" # zero, "", []>,
5243     Sched<[WriteV]> {
5244   bits<5> Rd;
5245   bits<5> Rn;
5246   let Inst{31-30} = 0b01;
5247   let Inst{29}    = U;
5248   let Inst{28-24} = 0b11110;
5249   let Inst{23-22} = size;
5250   let Inst{21-17} = 0b10000;
5251   let Inst{16-12} = opcode;
5252   let Inst{11-10} = 0b10;
5253   let Inst{9-5}   = Rn;
5254   let Inst{4-0}   = Rd;
5255 }
5256
5257 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
5258   : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
5259      [(set (f32 FPR32:$Rd), (int_arm64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
5260     Sched<[WriteV]> {
5261   bits<5> Rd;
5262   bits<5> Rn;
5263   let Inst{31-17} = 0b011111100110000;
5264   let Inst{16-12} = opcode;
5265   let Inst{11-10} = 0b10;
5266   let Inst{9-5}   = Rn;
5267   let Inst{4-0}   = Rd;
5268 }
5269
5270 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
5271                              SDPatternOperator OpNode> {
5272   def v1i64rz  : BaseSIMDCmpTwoScalar<U, 0b11, opc, FPR64, asm, "0">;
5273
5274   def : Pat<(v1i64 (OpNode FPR64:$Rn)),
5275             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5276 }
5277
5278 multiclass SIMDCmpTwoScalarSD<bit U, bit S, bits<5> opc, string asm,
5279                               SDPatternOperator OpNode> {
5280   def v1i64rz  : BaseSIMDCmpTwoScalar<U, {S,1}, opc, FPR64, asm, "0.0">;
5281   def v1i32rz  : BaseSIMDCmpTwoScalar<U, {S,0}, opc, FPR32, asm, "0.0">;
5282
5283   def : InstAlias<asm # " $Rd, $Rn, #0",
5284                   (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn)>;
5285   def : InstAlias<asm # " $Rd, $Rn, #0",
5286                   (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn)>;
5287
5288   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
5289             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5290 }
5291
5292 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
5293                           SDPatternOperator OpNode = null_frag> {
5294   def v1i64       : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5295     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
5296
5297   def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
5298             (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
5299 }
5300
5301 multiclass SIMDTwoScalarSD<bit U, bit S, bits<5> opc, string asm> {
5302   def v1i64       : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,[]>;
5303   def v1i32       : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,[]>;
5304 }
5305
5306 multiclass SIMDTwoScalarCVTSD<bit U, bit S, bits<5> opc, string asm,
5307                               SDPatternOperator OpNode> {
5308   def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,
5309                                 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
5310   def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,
5311                                 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
5312 }
5313
5314 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
5315                              SDPatternOperator OpNode = null_frag> {
5316   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5317     def v1i64  : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5318            [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5319     def v1i32  : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR32, asm,
5320            [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
5321     def v1i16  : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR16, asm, []>;
5322     def v1i8   : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5323   }
5324
5325   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
5326             (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
5327 }
5328
5329 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
5330                                  Intrinsic OpNode> {
5331   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5332     def v1i64  : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
5333         [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
5334     def v1i32  : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
5335         [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
5336     def v1i16  : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
5337     def v1i8   : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5338   }
5339
5340   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
5341             (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
5342 }
5343
5344
5345
5346 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5347 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
5348                                  SDPatternOperator OpNode = null_frag> {
5349   def v1i32  : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR64, asm,
5350         [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5351   def v1i16  : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR32, asm, []>;
5352   def v1i8   : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR16, asm, []>;
5353 }
5354
5355 //----------------------------------------------------------------------------
5356 // AdvSIMD scalar pairwise instructions
5357 //----------------------------------------------------------------------------
5358
5359 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5360 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
5361                         RegisterOperand regtype, RegisterOperand vectype,
5362                         string asm, string kind>
5363   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5364       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
5365     Sched<[WriteV]> {
5366   bits<5> Rd;
5367   bits<5> Rn;
5368   let Inst{31-30} = 0b01;
5369   let Inst{29}    = U;
5370   let Inst{28-24} = 0b11110;
5371   let Inst{23-22} = size;
5372   let Inst{21-17} = 0b11000;
5373   let Inst{16-12} = opcode;
5374   let Inst{11-10} = 0b10;
5375   let Inst{9-5}   = Rn;
5376   let Inst{4-0}   = Rd;
5377 }
5378
5379 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
5380   def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
5381                                       asm, ".2d">;
5382 }
5383
5384 multiclass SIMDPairwiseScalarSD<bit U, bit S, bits<5> opc, string asm> {
5385   def v2i32p : BaseSIMDPairwiseScalar<U, {S,0}, opc, FPR32Op, V64,
5386                                       asm, ".2s">;
5387   def v2i64p : BaseSIMDPairwiseScalar<U, {S,1}, opc, FPR64Op, V128,
5388                                       asm, ".2d">;
5389 }
5390
5391 //----------------------------------------------------------------------------
5392 // AdvSIMD across lanes instructions
5393 //----------------------------------------------------------------------------
5394
5395 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5396 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
5397                           RegisterClass regtype, RegisterOperand vectype,
5398                           string asm, string kind, list<dag> pattern>
5399   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5400       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
5401     Sched<[WriteV]> {
5402   bits<5> Rd;
5403   bits<5> Rn;
5404   let Inst{31}    = 0;
5405   let Inst{30}    = Q;
5406   let Inst{29}    = U;
5407   let Inst{28-24} = 0b01110;
5408   let Inst{23-22} = size;
5409   let Inst{21-17} = 0b11000;
5410   let Inst{16-12} = opcode;
5411   let Inst{11-10} = 0b10;
5412   let Inst{9-5}   = Rn;
5413   let Inst{4-0}   = Rd;
5414 }
5415
5416 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
5417                               string asm> {
5418   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8,  V64,
5419                                    asm, ".8b", []>;
5420   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8,  V128,
5421                                    asm, ".16b", []>;
5422   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
5423                                    asm, ".4h", []>;
5424   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
5425                                    asm, ".8h", []>;
5426   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
5427                                    asm, ".4s", []>;
5428 }
5429
5430 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
5431   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
5432                                    asm, ".8b", []>;
5433   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
5434                                    asm, ".16b", []>;
5435   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
5436                                    asm, ".4h", []>;
5437   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
5438                                    asm, ".8h", []>;
5439   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
5440                                    asm, ".4s", []>;
5441 }
5442
5443 multiclass SIMDAcrossLanesS<bits<5> opcode, bit sz1, string asm,
5444                             Intrinsic intOp> {
5445   def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
5446                                    asm, ".4s",
5447         [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
5448 }
5449
5450 //----------------------------------------------------------------------------
5451 // AdvSIMD INS/DUP instructions
5452 //----------------------------------------------------------------------------
5453
5454 // FIXME: There has got to be a better way to factor these. ugh.
5455
5456 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
5457                      string operands, string constraints, list<dag> pattern>
5458   : I<outs, ins, asm, operands, constraints, pattern>,
5459     Sched<[WriteV]> {
5460   bits<5> Rd;
5461   bits<5> Rn;
5462   let Inst{31} = 0;
5463   let Inst{30} = Q;
5464   let Inst{29} = op;
5465   let Inst{28-21} = 0b01110000;
5466   let Inst{15} = 0;
5467   let Inst{10} = 1;
5468   let Inst{9-5} = Rn;
5469   let Inst{4-0} = Rd;
5470 }
5471
5472 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
5473                       RegisterOperand vecreg, RegisterClass regtype>
5474   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
5475                    "{\t$Rd" # size # ", $Rn" #
5476                    "|" # size # "\t$Rd, $Rn}", "",
5477                    [(set (vectype vecreg:$Rd), (ARM64dup regtype:$Rn))]> {
5478   let Inst{20-16} = imm5;
5479   let Inst{14-11} = 0b0001;
5480 }
5481
5482 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
5483                          ValueType vectype, ValueType insreg,
5484                          RegisterOperand vecreg, Operand idxtype,
5485                          ValueType elttype, SDNode OpNode>
5486   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
5487                    "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
5488                    "|" # dstkind # "\t$Rd, $Rn$idx}", "",
5489                  [(set (vectype vecreg:$Rd),
5490                        (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
5491   let Inst{14-11} = 0b0000;
5492 }
5493
5494 class SIMDDup64FromElement
5495   : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
5496                        VectorIndexD, i64, ARM64duplane64> {
5497   bits<1> idx;
5498   let Inst{20} = idx;
5499   let Inst{19-16} = 0b1000;
5500 }
5501
5502 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
5503                            RegisterOperand vecreg>
5504   : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
5505                        VectorIndexS, i64, ARM64duplane32> {
5506   bits<2> idx;
5507   let Inst{20-19} = idx;
5508   let Inst{18-16} = 0b100;
5509 }
5510
5511 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
5512                            RegisterOperand vecreg>
5513   : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
5514                        VectorIndexH, i64, ARM64duplane16> {
5515   bits<3> idx;
5516   let Inst{20-18} = idx;
5517   let Inst{17-16} = 0b10;
5518 }
5519
5520 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
5521                           RegisterOperand vecreg>
5522   : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
5523                        VectorIndexB, i64, ARM64duplane8> {
5524   bits<4> idx;
5525   let Inst{20-17} = idx;
5526   let Inst{16} = 1;
5527 }
5528
5529 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
5530                   Operand idxtype, string asm, list<dag> pattern>
5531   : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
5532                    "{\t$Rd, $Rn" # size # "$idx" #
5533                    "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
5534   let Inst{14-11} = imm4;
5535 }
5536
5537 class SIMDSMov<bit Q, string size, RegisterClass regtype,
5538                Operand idxtype>
5539   : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
5540 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
5541                Operand idxtype>
5542   : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
5543       [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
5544
5545 class SIMDMovAlias<string asm, string size, Instruction inst,
5546                    RegisterClass regtype, Operand idxtype>
5547     : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
5548                     "|" # size # "\t$dst, $src$idx}",
5549                 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
5550
5551 multiclass SMov {
5552   def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
5553     bits<4> idx;
5554     let Inst{20-17} = idx;
5555     let Inst{16} = 1;
5556   }
5557   def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
5558     bits<4> idx;
5559     let Inst{20-17} = idx;
5560     let Inst{16} = 1;
5561   }
5562   def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
5563     bits<3> idx;
5564     let Inst{20-18} = idx;
5565     let Inst{17-16} = 0b10;
5566   }
5567   def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
5568     bits<3> idx;
5569     let Inst{20-18} = idx;
5570     let Inst{17-16} = 0b10;
5571   }
5572   def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
5573     bits<2> idx;
5574     let Inst{20-19} = idx;
5575     let Inst{18-16} = 0b100;
5576   }
5577 }
5578
5579 multiclass UMov {
5580   def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
5581     bits<4> idx;
5582     let Inst{20-17} = idx;
5583     let Inst{16} = 1;
5584   }
5585   def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
5586     bits<3> idx;
5587     let Inst{20-18} = idx;
5588     let Inst{17-16} = 0b10;
5589   }
5590   def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
5591     bits<2> idx;
5592     let Inst{20-19} = idx;
5593     let Inst{18-16} = 0b100;
5594   }
5595   def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
5596     bits<1> idx;
5597     let Inst{20} = idx;
5598     let Inst{19-16} = 0b1000;
5599   }
5600   def : SIMDMovAlias<"mov", ".s",
5601                      !cast<Instruction>(NAME#"vi32"),
5602                      GPR32, VectorIndexS>;
5603   def : SIMDMovAlias<"mov", ".d",
5604                      !cast<Instruction>(NAME#"vi64"),
5605                      GPR64, VectorIndexD>;
5606 }
5607
5608 class SIMDInsFromMain<string size, ValueType vectype,
5609                       RegisterClass regtype, Operand idxtype>
5610   : BaseSIMDInsDup<1, 0, (outs V128:$dst),
5611                    (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
5612                    "{\t$Rd" # size # "$idx, $Rn" #
5613                    "|" # size # "\t$Rd$idx, $Rn}",
5614                    "$Rd = $dst",
5615             [(set V128:$dst,
5616               (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
5617   let Inst{14-11} = 0b0011;
5618 }
5619
5620 class SIMDInsFromElement<string size, ValueType vectype,
5621                          ValueType elttype, Operand idxtype>
5622   : BaseSIMDInsDup<1, 1, (outs V128:$dst),
5623                    (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
5624                    "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
5625                    "|" # size # "\t$Rd$idx, $Rn$idx2}",
5626                    "$Rd = $dst",
5627          [(set V128:$dst,
5628                (vector_insert
5629                  (vectype V128:$Rd),
5630                  (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
5631                  idxtype:$idx))]>;
5632
5633 class SIMDInsMainMovAlias<string size, Instruction inst,
5634                           RegisterClass regtype, Operand idxtype>
5635     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
5636                         "|" # size #"\t$dst$idx, $src}",
5637                 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
5638 class SIMDInsElementMovAlias<string size, Instruction inst,
5639                              Operand idxtype>
5640     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
5641                       # "|" # size #" $dst$idx, $src$idx2}",
5642                 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
5643
5644
5645 multiclass SIMDIns {
5646   def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
5647     bits<4> idx;
5648     let Inst{20-17} = idx;
5649     let Inst{16} = 1;
5650   }
5651   def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
5652     bits<3> idx;
5653     let Inst{20-18} = idx;
5654     let Inst{17-16} = 0b10;
5655   }
5656   def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
5657     bits<2> idx;
5658     let Inst{20-19} = idx;
5659     let Inst{18-16} = 0b100;
5660   }
5661   def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
5662     bits<1> idx;
5663     let Inst{20} = idx;
5664     let Inst{19-16} = 0b1000;
5665   }
5666
5667   def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
5668     bits<4> idx;
5669     bits<4> idx2;
5670     let Inst{20-17} = idx;
5671     let Inst{16} = 1;
5672     let Inst{14-11} = idx2;
5673   }
5674   def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
5675     bits<3> idx;
5676     bits<3> idx2;
5677     let Inst{20-18} = idx;
5678     let Inst{17-16} = 0b10;
5679     let Inst{14-12} = idx2;
5680     let Inst{11} = 0;
5681   }
5682   def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
5683     bits<2> idx;
5684     bits<2> idx2;
5685     let Inst{20-19} = idx;
5686     let Inst{18-16} = 0b100;
5687     let Inst{14-13} = idx2;
5688     let Inst{12-11} = 0;
5689   }
5690   def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
5691     bits<1> idx;
5692     bits<1> idx2;
5693     let Inst{20} = idx;
5694     let Inst{19-16} = 0b1000;
5695     let Inst{14} = idx2;
5696     let Inst{13-11} = 0;
5697   }
5698
5699   // For all forms of the INS instruction, the "mov" mnemonic is the
5700   // preferred alias. Why they didn't just call the instruction "mov" in
5701   // the first place is a very good question indeed...
5702   def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
5703                          GPR32, VectorIndexB>;
5704   def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
5705                          GPR32, VectorIndexH>;
5706   def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
5707                          GPR32, VectorIndexS>;
5708   def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
5709                          GPR64, VectorIndexD>;
5710
5711   def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
5712                          VectorIndexB>;
5713   def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
5714                          VectorIndexH>;
5715   def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
5716                          VectorIndexS>;
5717   def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
5718                          VectorIndexD>;
5719 }
5720
5721 //----------------------------------------------------------------------------
5722 // AdvSIMD TBL/TBX
5723 //----------------------------------------------------------------------------
5724
5725 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5726 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
5727                           RegisterOperand listtype, string asm, string kind>
5728   : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
5729        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
5730     Sched<[WriteV]> {
5731   bits<5> Vd;
5732   bits<5> Vn;
5733   bits<5> Vm;
5734   let Inst{31}    = 0;
5735   let Inst{30}    = Q;
5736   let Inst{29-21} = 0b001110000;
5737   let Inst{20-16} = Vm;
5738   let Inst{15}    = 0;
5739   let Inst{14-13} = len;
5740   let Inst{12}    = op;
5741   let Inst{11-10} = 0b00;
5742   let Inst{9-5}   = Vn;
5743   let Inst{4-0}   = Vd;
5744 }
5745
5746 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5747 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
5748                           RegisterOperand listtype, string asm, string kind>
5749   : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
5750        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
5751     Sched<[WriteV]> {
5752   bits<5> Vd;
5753   bits<5> Vn;
5754   bits<5> Vm;
5755   let Inst{31}    = 0;
5756   let Inst{30}    = Q;
5757   let Inst{29-21} = 0b001110000;
5758   let Inst{20-16} = Vm;
5759   let Inst{15}    = 0;
5760   let Inst{14-13} = len;
5761   let Inst{12}    = op;
5762   let Inst{11-10} = 0b00;
5763   let Inst{9-5}   = Vn;
5764   let Inst{4-0}   = Vd;
5765 }
5766
5767 class SIMDTableLookupAlias<string asm, Instruction inst,
5768                           RegisterOperand vectype, RegisterOperand listtype>
5769     : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
5770                 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
5771
5772 multiclass SIMDTableLookup<bit op, string asm> {
5773   def v8i8One   : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
5774                                       asm, ".8b">;
5775   def v8i8Two   : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
5776                                       asm, ".8b">;
5777   def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
5778                                       asm, ".8b">;
5779   def v8i8Four  : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
5780                                       asm, ".8b">;
5781   def v16i8One  : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
5782                                       asm, ".16b">;
5783   def v16i8Two  : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
5784                                       asm, ".16b">;
5785   def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
5786                                       asm, ".16b">;
5787   def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
5788                                       asm, ".16b">;
5789
5790   def : SIMDTableLookupAlias<asm # ".8b",
5791                          !cast<Instruction>(NAME#"v8i8One"),
5792                          V64, VecListOne128>;
5793   def : SIMDTableLookupAlias<asm # ".8b",
5794                          !cast<Instruction>(NAME#"v8i8Two"),
5795                          V64, VecListTwo128>;
5796   def : SIMDTableLookupAlias<asm # ".8b",
5797                          !cast<Instruction>(NAME#"v8i8Three"),
5798                          V64, VecListThree128>;
5799   def : SIMDTableLookupAlias<asm # ".8b",
5800                          !cast<Instruction>(NAME#"v8i8Four"),
5801                          V64, VecListFour128>;
5802   def : SIMDTableLookupAlias<asm # ".16b",
5803                          !cast<Instruction>(NAME#"v16i8One"),
5804                          V128, VecListOne128>;
5805   def : SIMDTableLookupAlias<asm # ".16b",
5806                          !cast<Instruction>(NAME#"v16i8Two"),
5807                          V128, VecListTwo128>;
5808   def : SIMDTableLookupAlias<asm # ".16b",
5809                          !cast<Instruction>(NAME#"v16i8Three"),
5810                          V128, VecListThree128>;
5811   def : SIMDTableLookupAlias<asm # ".16b",
5812                          !cast<Instruction>(NAME#"v16i8Four"),
5813                          V128, VecListFour128>;
5814 }
5815
5816 multiclass SIMDTableLookupTied<bit op, string asm> {
5817   def v8i8One   : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
5818                                       asm, ".8b">;
5819   def v8i8Two   : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
5820                                       asm, ".8b">;
5821   def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
5822                                       asm, ".8b">;
5823   def v8i8Four  : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
5824                                       asm, ".8b">;
5825   def v16i8One  : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
5826                                       asm, ".16b">;
5827   def v16i8Two  : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
5828                                       asm, ".16b">;
5829   def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
5830                                       asm, ".16b">;
5831   def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
5832                                       asm, ".16b">;
5833
5834   def : SIMDTableLookupAlias<asm # ".8b",
5835                          !cast<Instruction>(NAME#"v8i8One"),
5836                          V64, VecListOne128>;
5837   def : SIMDTableLookupAlias<asm # ".8b",
5838                          !cast<Instruction>(NAME#"v8i8Two"),
5839                          V64, VecListTwo128>;
5840   def : SIMDTableLookupAlias<asm # ".8b",
5841                          !cast<Instruction>(NAME#"v8i8Three"),
5842                          V64, VecListThree128>;
5843   def : SIMDTableLookupAlias<asm # ".8b",
5844                          !cast<Instruction>(NAME#"v8i8Four"),
5845                          V64, VecListFour128>;
5846   def : SIMDTableLookupAlias<asm # ".16b",
5847                          !cast<Instruction>(NAME#"v16i8One"),
5848                          V128, VecListOne128>;
5849   def : SIMDTableLookupAlias<asm # ".16b",
5850                          !cast<Instruction>(NAME#"v16i8Two"),
5851                          V128, VecListTwo128>;
5852   def : SIMDTableLookupAlias<asm # ".16b",
5853                          !cast<Instruction>(NAME#"v16i8Three"),
5854                          V128, VecListThree128>;
5855   def : SIMDTableLookupAlias<asm # ".16b",
5856                          !cast<Instruction>(NAME#"v16i8Four"),
5857                          V128, VecListFour128>;
5858 }
5859
5860
5861 //----------------------------------------------------------------------------
5862 // AdvSIMD scalar CPY
5863 //----------------------------------------------------------------------------
5864 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5865 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
5866                         string kind, Operand idxtype>
5867   : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
5868        "{\t$dst, $src" # kind # "$idx" #
5869        "|\t$dst, $src$idx}", "", []>,
5870     Sched<[WriteV]> {
5871   bits<5> dst;
5872   bits<5> src;
5873   let Inst{31-21} = 0b01011110000;
5874   let Inst{15-10} = 0b000001;
5875   let Inst{9-5}   = src;
5876   let Inst{4-0}   = dst;
5877 }
5878
5879 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
5880       RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
5881     : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
5882                     # "|\t$dst, $src$index}",
5883                 (inst regtype:$dst, vectype:$src, idxtype:$index)>;
5884
5885
5886 multiclass SIMDScalarCPY<string asm> {
5887   def i8  : BaseSIMDScalarCPY<FPR8,  V128, ".b", VectorIndexB> {
5888     bits<4> idx;
5889     let Inst{20-17} = idx;
5890     let Inst{16} = 1;
5891   }
5892   def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
5893     bits<3> idx;
5894     let Inst{20-18} = idx;
5895     let Inst{17-16} = 0b10;
5896   }
5897   def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
5898     bits<2> idx;
5899     let Inst{20-19} = idx;
5900     let Inst{18-16} = 0b100;
5901   }
5902   def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
5903     bits<1> idx;
5904     let Inst{20} = idx;
5905     let Inst{19-16} = 0b1000;
5906   }
5907
5908   def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
5909                                                           VectorIndexD:$idx)))),
5910             (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
5911
5912   // 'DUP' mnemonic aliases.
5913   def : SIMDScalarCPYAlias<"dup", ".b",
5914                            !cast<Instruction>(NAME#"i8"),
5915                            FPR8, V128, VectorIndexB>;
5916   def : SIMDScalarCPYAlias<"dup", ".h",
5917                            !cast<Instruction>(NAME#"i16"),
5918                            FPR16, V128, VectorIndexH>;
5919   def : SIMDScalarCPYAlias<"dup", ".s",
5920                            !cast<Instruction>(NAME#"i32"),
5921                            FPR32, V128, VectorIndexS>;
5922   def : SIMDScalarCPYAlias<"dup", ".d",
5923                            !cast<Instruction>(NAME#"i64"),
5924                            FPR64, V128, VectorIndexD>;
5925 }
5926
5927 //----------------------------------------------------------------------------
5928 // AdvSIMD modified immediate instructions
5929 //----------------------------------------------------------------------------
5930
5931 class BaseSIMDModifiedImm<bit Q, bit op, dag oops, dag iops,
5932                           string asm, string op_string,
5933                           string cstr, list<dag> pattern>
5934   : I<oops, iops, asm, op_string, cstr, pattern>,
5935     Sched<[WriteV]> {
5936   bits<5> Rd;
5937   bits<8> imm8;
5938   let Inst{31}    = 0;
5939   let Inst{30}    = Q;
5940   let Inst{29}    = op;
5941   let Inst{28-19} = 0b0111100000;
5942   let Inst{18-16} = imm8{7-5};
5943   let Inst{11-10} = 0b01;
5944   let Inst{9-5}   = imm8{4-0};
5945   let Inst{4-0}   = Rd;
5946 }
5947
5948 class BaseSIMDModifiedImmVector<bit Q, bit op, RegisterOperand vectype,
5949                                 Operand immtype, dag opt_shift_iop,
5950                                 string opt_shift, string asm, string kind,
5951                                 list<dag> pattern>
5952   : BaseSIMDModifiedImm<Q, op, (outs vectype:$Rd),
5953                         !con((ins immtype:$imm8), opt_shift_iop), asm,
5954                         "{\t$Rd" # kind # ", $imm8" # opt_shift #
5955                         "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
5956                         "", pattern> {
5957   let DecoderMethod = "DecodeModImmInstruction";
5958 }
5959
5960 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
5961                                 Operand immtype, dag opt_shift_iop,
5962                                 string opt_shift, string asm, string kind,
5963                                 list<dag> pattern>
5964   : BaseSIMDModifiedImm<Q, op, (outs vectype:$dst),
5965                         !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
5966                         asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
5967                              "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
5968                         "$Rd = $dst", pattern> {
5969   let DecoderMethod = "DecodeModImmTiedInstruction";
5970 }
5971
5972 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
5973                                      RegisterOperand vectype, string asm,
5974                                      string kind, list<dag> pattern>
5975   : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
5976                               (ins logical_vec_shift:$shift),
5977                               "$shift", asm, kind, pattern> {
5978   bits<2> shift;
5979   let Inst{15}    = b15_b12{1};
5980   let Inst{14-13} = shift;
5981   let Inst{12}    = b15_b12{0};
5982 }
5983
5984 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
5985                                      RegisterOperand vectype, string asm,
5986                                      string kind, list<dag> pattern>
5987   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
5988                               (ins logical_vec_shift:$shift),
5989                               "$shift", asm, kind, pattern> {
5990   bits<2> shift;
5991   let Inst{15}    = b15_b12{1};
5992   let Inst{14-13} = shift;
5993   let Inst{12}    = b15_b12{0};
5994 }
5995
5996
5997 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
5998                                          RegisterOperand vectype, string asm,
5999                                          string kind, list<dag> pattern>
6000   : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6001                               (ins logical_vec_hw_shift:$shift),
6002                               "$shift", asm, kind, pattern> {
6003   bits<2> shift;
6004   let Inst{15} = b15_b12{1};
6005   let Inst{14} = 0;
6006   let Inst{13} = shift{0};
6007   let Inst{12} = b15_b12{0};
6008 }
6009
6010 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
6011                                          RegisterOperand vectype, string asm,
6012                                          string kind, list<dag> pattern>
6013   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6014                               (ins logical_vec_hw_shift:$shift),
6015                               "$shift", asm, kind, pattern> {
6016   bits<2> shift;
6017   let Inst{15} = b15_b12{1};
6018   let Inst{14} = 0;
6019   let Inst{13} = shift{0};
6020   let Inst{12} = b15_b12{0};
6021 }
6022
6023 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
6024                                       string asm> {
6025   def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
6026                                                  asm, ".4h", []>;
6027   def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
6028                                                  asm, ".8h", []>;
6029
6030   def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
6031                                              asm, ".2s", []>;
6032   def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
6033                                              asm, ".4s", []>;
6034 }
6035
6036 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
6037                                       bits<2> w_cmode, string asm,
6038                                       SDNode OpNode> {
6039   def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
6040                                                  asm, ".4h",
6041              [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
6042                                              imm0_255:$imm8,
6043                                              (i32 imm:$shift)))]>;
6044   def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
6045                                                  asm, ".8h",
6046              [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
6047                                               imm0_255:$imm8,
6048                                               (i32 imm:$shift)))]>;
6049
6050   def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
6051                                              asm, ".2s",
6052              [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
6053                                              imm0_255:$imm8,
6054                                              (i32 imm:$shift)))]>;
6055   def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
6056                                              asm, ".4s",
6057              [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
6058                                               imm0_255:$imm8,
6059                                               (i32 imm:$shift)))]>;
6060 }
6061
6062 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
6063                              RegisterOperand vectype, string asm,
6064                              string kind, list<dag> pattern>
6065   : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6066                               (ins move_vec_shift:$shift),
6067                               "$shift", asm, kind, pattern> {
6068   bits<1> shift;
6069   let Inst{15-13} = cmode{3-1};
6070   let Inst{12}    = shift;
6071 }
6072
6073 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bits<4> cmode,
6074                                    RegisterOperand vectype,
6075                                    Operand imm_type, string asm,
6076                                    string kind, list<dag> pattern>
6077   : BaseSIMDModifiedImmVector<Q, op, vectype, imm_type, (ins), "",
6078                               asm, kind, pattern> {
6079   let Inst{15-12} = cmode;
6080 }
6081
6082 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
6083                                    list<dag> pattern>
6084   : BaseSIMDModifiedImm<Q, op, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
6085                         "\t$Rd, $imm8", "", pattern> {
6086   let Inst{15-12} = cmode;
6087   let DecoderMethod = "DecodeModImmInstruction";
6088 }
6089
6090 //----------------------------------------------------------------------------
6091 // AdvSIMD indexed element
6092 //----------------------------------------------------------------------------
6093
6094 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6095 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6096                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
6097                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
6098                       string apple_kind, string dst_kind, string lhs_kind,
6099                       string rhs_kind, list<dag> pattern>
6100   : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
6101       asm,
6102       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6103       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
6104     Sched<[WriteV]> {
6105   bits<5> Rd;
6106   bits<5> Rn;
6107   bits<5> Rm;
6108
6109   let Inst{31}    = 0;
6110   let Inst{30}    = Q;
6111   let Inst{29}    = U;
6112   let Inst{28}    = Scalar;
6113   let Inst{27-24} = 0b1111;
6114   let Inst{23-22} = size;
6115   // Bit 21 must be set by the derived class.
6116   let Inst{20-16} = Rm;
6117   let Inst{15-12} = opc;
6118   // Bit 11 must be set by the derived class.
6119   let Inst{10}    = 0;
6120   let Inst{9-5}   = Rn;
6121   let Inst{4-0}   = Rd;
6122 }
6123
6124 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6125 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6126                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
6127                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
6128                       string apple_kind, string dst_kind, string lhs_kind,
6129                       string rhs_kind, list<dag> pattern>
6130   : I<(outs dst_reg:$dst),
6131       (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
6132       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6133       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
6134     Sched<[WriteV]> {
6135   bits<5> Rd;
6136   bits<5> Rn;
6137   bits<5> Rm;
6138
6139   let Inst{31}    = 0;
6140   let Inst{30}    = Q;
6141   let Inst{29}    = U;
6142   let Inst{28}    = Scalar;
6143   let Inst{27-24} = 0b1111;
6144   let Inst{23-22} = size;
6145   // Bit 21 must be set by the derived class.
6146   let Inst{20-16} = Rm;
6147   let Inst{15-12} = opc;
6148   // Bit 11 must be set by the derived class.
6149   let Inst{10}    = 0;
6150   let Inst{9-5}   = Rn;
6151   let Inst{4-0}   = Rd;
6152 }
6153
6154 multiclass SIMDFPIndexedSD<bit U, bits<4> opc, string asm,
6155                            SDPatternOperator OpNode> {
6156   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6157                                       V64, V64,
6158                                       V128, VectorIndexS,
6159                                       asm, ".2s", ".2s", ".2s", ".s",
6160     [(set (v2f32 V64:$Rd),
6161         (OpNode (v2f32 V64:$Rn),
6162          (v2f32 (ARM64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6163     bits<2> idx;
6164     let Inst{11} = idx{1};
6165     let Inst{21} = idx{0};
6166   }
6167
6168   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6169                                       V128, V128,
6170                                       V128, VectorIndexS,
6171                                       asm, ".4s", ".4s", ".4s", ".s",
6172     [(set (v4f32 V128:$Rd),
6173         (OpNode (v4f32 V128:$Rn),
6174          (v4f32 (ARM64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6175     bits<2> idx;
6176     let Inst{11} = idx{1};
6177     let Inst{21} = idx{0};
6178   }
6179
6180   def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
6181                                       V128, V128,
6182                                       V128, VectorIndexD,
6183                                       asm, ".2d", ".2d", ".2d", ".d",
6184     [(set (v2f64 V128:$Rd),
6185         (OpNode (v2f64 V128:$Rn),
6186          (v2f64 (ARM64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
6187     bits<1> idx;
6188     let Inst{11} = idx{0};
6189     let Inst{21} = 0;
6190   }
6191
6192   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6193                                       FPR32Op, FPR32Op, V128, VectorIndexS,
6194                                       asm, ".s", "", "", ".s",
6195     [(set (f32 FPR32Op:$Rd),
6196           (OpNode (f32 FPR32Op:$Rn),
6197                   (f32 (vector_extract (v4f32 V128:$Rm),
6198                                        VectorIndexS:$idx))))]> {
6199     bits<2> idx;
6200     let Inst{11} = idx{1};
6201     let Inst{21} = idx{0};
6202   }
6203
6204   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
6205                                       FPR64Op, FPR64Op, V128, VectorIndexD,
6206                                       asm, ".d", "", "", ".d",
6207     [(set (f64 FPR64Op:$Rd),
6208           (OpNode (f64 FPR64Op:$Rn),
6209                   (f64 (vector_extract (v2f64 V128:$Rm),
6210                                        VectorIndexD:$idx))))]> {
6211     bits<1> idx;
6212     let Inst{11} = idx{0};
6213     let Inst{21} = 0;
6214   }
6215 }
6216
6217 multiclass SIMDFPIndexedSDTiedPatterns<string INST, SDPatternOperator OpNode> {
6218   // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
6219   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6220                            (ARM64duplane32 (v4f32 V128:$Rm),
6221                                            VectorIndexS:$idx))),
6222             (!cast<Instruction>(INST # v2i32_indexed)
6223                 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6224   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6225                            (ARM64dup (f32 FPR32Op:$Rm)))),
6226             (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
6227                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6228
6229
6230   // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
6231   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6232                            (ARM64duplane32 (v4f32 V128:$Rm),
6233                                            VectorIndexS:$idx))),
6234             (!cast<Instruction>(INST # "v4i32_indexed")
6235                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6236   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6237                            (ARM64dup (f32 FPR32Op:$Rm)))),
6238             (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
6239                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6240
6241   // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
6242   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6243                            (ARM64duplane64 (v2f64 V128:$Rm),
6244                                            VectorIndexD:$idx))),
6245             (!cast<Instruction>(INST # "v2i64_indexed")
6246                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6247   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6248                            (ARM64dup (f64 FPR64Op:$Rm)))),
6249             (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
6250                 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
6251
6252   // 2 variants for 32-bit scalar version: extract from .2s or from .4s
6253   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6254                          (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
6255             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6256                 V128:$Rm, VectorIndexS:$idx)>;
6257   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6258                          (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
6259             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6260                 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
6261
6262   // 1 variant for 64-bit scalar version: extract from .1d or from .2d
6263   def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
6264                          (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
6265             (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
6266                 V128:$Rm, VectorIndexD:$idx)>;
6267 }
6268
6269 multiclass SIMDFPIndexedSDTied<bit U, bits<4> opc, string asm> {
6270   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
6271                                           V128, VectorIndexS,
6272                                           asm, ".2s", ".2s", ".2s", ".s", []> {
6273     bits<2> idx;
6274     let Inst{11} = idx{1};
6275     let Inst{21} = idx{0};
6276   }
6277
6278   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6279                                       V128, V128,
6280                                       V128, VectorIndexS,
6281                                       asm, ".4s", ".4s", ".4s", ".s", []> {
6282     bits<2> idx;
6283     let Inst{11} = idx{1};
6284     let Inst{21} = idx{0};
6285   }
6286
6287   def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
6288                                       V128, V128,
6289                                       V128, VectorIndexD,
6290                                       asm, ".2d", ".2d", ".2d", ".d", []> {
6291     bits<1> idx;
6292     let Inst{11} = idx{0};
6293     let Inst{21} = 0;
6294   }
6295
6296
6297   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6298                                       FPR32Op, FPR32Op, V128, VectorIndexS,
6299                                       asm, ".s", "", "", ".s", []> {
6300     bits<2> idx;
6301     let Inst{11} = idx{1};
6302     let Inst{21} = idx{0};
6303   }
6304
6305   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
6306                                       FPR64Op, FPR64Op, V128, VectorIndexD,
6307                                       asm, ".d", "", "", ".d", []> {
6308     bits<1> idx;
6309     let Inst{11} = idx{0};
6310     let Inst{21} = 0;
6311   }
6312 }
6313
6314 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
6315                          SDPatternOperator OpNode> {
6316   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
6317                                       V128_lo, VectorIndexH,
6318                                       asm, ".4h", ".4h", ".4h", ".h",
6319     [(set (v4i16 V64:$Rd),
6320         (OpNode (v4i16 V64:$Rn),
6321          (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6322     bits<3> idx;
6323     let Inst{11} = idx{2};
6324     let Inst{21} = idx{1};
6325     let Inst{20} = idx{0};
6326   }
6327
6328   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6329                                       V128, V128,
6330                                       V128_lo, VectorIndexH,
6331                                       asm, ".8h", ".8h", ".8h", ".h",
6332     [(set (v8i16 V128:$Rd),
6333        (OpNode (v8i16 V128:$Rn),
6334          (v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6335     bits<3> idx;
6336     let Inst{11} = idx{2};
6337     let Inst{21} = idx{1};
6338     let Inst{20} = idx{0};
6339   }
6340
6341   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6342                                       V64, V64,
6343                                       V128, VectorIndexS,
6344                                       asm, ".2s", ".2s", ".2s",  ".s",
6345     [(set (v2i32 V64:$Rd),
6346        (OpNode (v2i32 V64:$Rn),
6347           (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6348     bits<2> idx;
6349     let Inst{11} = idx{1};
6350     let Inst{21} = idx{0};
6351   }
6352
6353   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6354                                       V128, V128,
6355                                       V128, VectorIndexS,
6356                                       asm, ".4s", ".4s", ".4s", ".s",
6357     [(set (v4i32 V128:$Rd),
6358        (OpNode (v4i32 V128:$Rn),
6359           (v4i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6360     bits<2> idx;
6361     let Inst{11} = idx{1};
6362     let Inst{21} = idx{0};
6363   }
6364
6365   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6366                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
6367                                       asm, ".h", "", "", ".h", []> {
6368     bits<3> idx;
6369     let Inst{11} = idx{2};
6370     let Inst{21} = idx{1};
6371     let Inst{20} = idx{0};
6372   }
6373
6374   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6375                                       FPR32Op, FPR32Op, V128, VectorIndexS,
6376                                       asm, ".s", "", "", ".s",
6377       [(set (i32 FPR32Op:$Rd),
6378             (OpNode FPR32Op:$Rn,
6379                     (i32 (vector_extract (v4i32 V128:$Rm),
6380                                          VectorIndexS:$idx))))]> {
6381     bits<2> idx;
6382     let Inst{11} = idx{1};
6383     let Inst{21} = idx{0};
6384   }
6385 }
6386
6387 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
6388                                SDPatternOperator OpNode> {
6389   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6390                                       V64, V64,
6391                                       V128_lo, VectorIndexH,
6392                                       asm, ".4h", ".4h", ".4h", ".h",
6393     [(set (v4i16 V64:$Rd),
6394         (OpNode (v4i16 V64:$Rn),
6395          (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6396     bits<3> idx;
6397     let Inst{11} = idx{2};
6398     let Inst{21} = idx{1};
6399     let Inst{20} = idx{0};
6400   }
6401
6402   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6403                                       V128, V128,
6404                                       V128_lo, VectorIndexH,
6405                                       asm, ".8h", ".8h", ".8h", ".h",
6406     [(set (v8i16 V128:$Rd),
6407        (OpNode (v8i16 V128:$Rn),
6408          (v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6409     bits<3> idx;
6410     let Inst{11} = idx{2};
6411     let Inst{21} = idx{1};
6412     let Inst{20} = idx{0};
6413   }
6414
6415   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6416                                       V64, V64,
6417                                       V128, VectorIndexS,
6418                                       asm, ".2s", ".2s", ".2s", ".s",
6419     [(set (v2i32 V64:$Rd),
6420        (OpNode (v2i32 V64:$Rn),
6421           (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6422     bits<2> idx;
6423     let Inst{11} = idx{1};
6424     let Inst{21} = idx{0};
6425   }
6426
6427   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6428                                       V128, V128,
6429                                       V128, VectorIndexS,
6430                                       asm, ".4s", ".4s", ".4s", ".s",
6431     [(set (v4i32 V128:$Rd),
6432        (OpNode (v4i32 V128:$Rn),
6433           (v4i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6434     bits<2> idx;
6435     let Inst{11} = idx{1};
6436     let Inst{21} = idx{0};
6437   }
6438 }
6439
6440 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
6441                                    SDPatternOperator OpNode> {
6442   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
6443                                           V128_lo, VectorIndexH,
6444                                           asm, ".4h", ".4h", ".4h", ".h",
6445     [(set (v4i16 V64:$dst),
6446         (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
6447          (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6448     bits<3> idx;
6449     let Inst{11} = idx{2};
6450     let Inst{21} = idx{1};
6451     let Inst{20} = idx{0};
6452   }
6453
6454   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6455                                       V128, V128,
6456                                       V128_lo, VectorIndexH,
6457                                       asm, ".8h", ".8h", ".8h", ".h",
6458     [(set (v8i16 V128:$dst),
6459        (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
6460          (v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6461     bits<3> idx;
6462     let Inst{11} = idx{2};
6463     let Inst{21} = idx{1};
6464     let Inst{20} = idx{0};
6465   }
6466
6467   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6468                                       V64, V64,
6469                                       V128, VectorIndexS,
6470                                       asm, ".2s", ".2s", ".2s", ".s",
6471     [(set (v2i32 V64:$dst),
6472        (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
6473           (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6474     bits<2> idx;
6475     let Inst{11} = idx{1};
6476     let Inst{21} = idx{0};
6477   }
6478
6479   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6480                                       V128, V128,
6481                                       V128, VectorIndexS,
6482                                       asm, ".4s", ".4s", ".4s", ".s",
6483     [(set (v4i32 V128:$dst),
6484        (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
6485           (v4i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6486     bits<2> idx;
6487     let Inst{11} = idx{1};
6488     let Inst{21} = idx{0};
6489   }
6490 }
6491
6492 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
6493                              SDPatternOperator OpNode> {
6494   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6495                                       V128, V64,
6496                                       V128_lo, VectorIndexH,
6497                                       asm, ".4s", ".4s", ".4h", ".h",
6498     [(set (v4i32 V128:$Rd),
6499         (OpNode (v4i16 V64:$Rn),
6500          (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6501     bits<3> idx;
6502     let Inst{11} = idx{2};
6503     let Inst{21} = idx{1};
6504     let Inst{20} = idx{0};
6505   }
6506
6507   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6508                                       V128, V128,
6509                                       V128_lo, VectorIndexH,
6510                                       asm#"2", ".4s", ".4s", ".8h", ".h",
6511     [(set (v4i32 V128:$Rd),
6512           (OpNode (extract_high_v8i16 V128:$Rn),
6513                   (extract_high_v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6514                                                       VectorIndexH:$idx))))]> {
6515
6516     bits<3> idx;
6517     let Inst{11} = idx{2};
6518     let Inst{21} = idx{1};
6519     let Inst{20} = idx{0};
6520   }
6521
6522   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6523                                       V128, V64,
6524                                       V128, VectorIndexS,
6525                                       asm, ".2d", ".2d", ".2s", ".s",
6526     [(set (v2i64 V128:$Rd),
6527         (OpNode (v2i32 V64:$Rn),
6528          (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6529     bits<2> idx;
6530     let Inst{11} = idx{1};
6531     let Inst{21} = idx{0};
6532   }
6533
6534   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6535                                       V128, V128,
6536                                       V128, VectorIndexS,
6537                                       asm#"2", ".2d", ".2d", ".4s", ".s",
6538     [(set (v2i64 V128:$Rd),
6539           (OpNode (extract_high_v4i32 V128:$Rn),
6540                   (extract_high_v4i32 (ARM64duplane32 (v4i32 V128:$Rm),
6541                                                       VectorIndexS:$idx))))]> {
6542     bits<2> idx;
6543     let Inst{11} = idx{1};
6544     let Inst{21} = idx{0};
6545   }
6546
6547   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6548                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6549                                       asm, ".h", "", "", ".h", []> {
6550     bits<3> idx;
6551     let Inst{11} = idx{2};
6552     let Inst{21} = idx{1};
6553     let Inst{20} = idx{0};
6554   }
6555
6556   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6557                                       FPR64Op, FPR32Op, V128, VectorIndexS,
6558                                       asm, ".s", "", "", ".s", []> {
6559     bits<2> idx;
6560     let Inst{11} = idx{1};
6561     let Inst{21} = idx{0};
6562   }
6563 }
6564
6565 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
6566                                        SDPatternOperator Accum> {
6567   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
6568                                       V128, V64,
6569                                       V128_lo, VectorIndexH,
6570                                       asm, ".4s", ".4s", ".4h", ".h",
6571     [(set (v4i32 V128:$dst),
6572           (Accum (v4i32 V128:$Rd),
6573                  (v4i32 (int_arm64_neon_sqdmull
6574                              (v4i16 V64:$Rn),
6575                              (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6576                                                     VectorIndexH:$idx))))))]> {
6577     bits<3> idx;
6578     let Inst{11} = idx{2};
6579     let Inst{21} = idx{1};
6580     let Inst{20} = idx{0};
6581   }
6582
6583   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
6584   // intermediate EXTRACT_SUBREG would be untyped.
6585   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
6586                 (i32 (vector_extract (v4i32
6587                          (int_arm64_neon_sqdmull (v4i16 V64:$Rn),
6588                              (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6589                                                     VectorIndexH:$idx)))),
6590                          (i64 0))))),
6591             (EXTRACT_SUBREG
6592                 (!cast<Instruction>(NAME # v4i16_indexed)
6593                     (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
6594                     V128_lo:$Rm, VectorIndexH:$idx),
6595                 ssub)>;
6596
6597   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6598                                       V128, V128,
6599                                       V128_lo, VectorIndexH,
6600                                       asm#"2", ".4s", ".4s", ".8h", ".h",
6601     [(set (v4i32 V128:$dst),
6602           (Accum (v4i32 V128:$Rd),
6603                  (v4i32 (int_arm64_neon_sqdmull
6604                             (extract_high_v8i16 V128:$Rn),
6605                             (extract_high_v8i16
6606                                 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6607                                                 VectorIndexH:$idx))))))]> {
6608     bits<3> idx;
6609     let Inst{11} = idx{2};
6610     let Inst{21} = idx{1};
6611     let Inst{20} = idx{0};
6612   }
6613
6614   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6615                                       V128, V64,
6616                                       V128, VectorIndexS,
6617                                       asm, ".2d", ".2d", ".2s", ".s",
6618     [(set (v2i64 V128:$dst),
6619         (Accum (v2i64 V128:$Rd),
6620                (v2i64 (int_arm64_neon_sqdmull
6621                           (v2i32 V64:$Rn),
6622                           (v2i32 (ARM64duplane32 (v4i32 V128:$Rm),
6623                                                  VectorIndexS:$idx))))))]> {
6624     bits<2> idx;
6625     let Inst{11} = idx{1};
6626     let Inst{21} = idx{0};
6627   }
6628
6629   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6630                                       V128, V128,
6631                                       V128, VectorIndexS,
6632                                       asm#"2", ".2d", ".2d", ".4s", ".s",
6633     [(set (v2i64 V128:$dst),
6634           (Accum (v2i64 V128:$Rd),
6635                  (v2i64 (int_arm64_neon_sqdmull
6636                             (extract_high_v4i32 V128:$Rn),
6637                             (extract_high_v4i32
6638                                 (ARM64duplane32 (v4i32 V128:$Rm),
6639                                                 VectorIndexS:$idx))))))]> {
6640     bits<2> idx;
6641     let Inst{11} = idx{1};
6642     let Inst{21} = idx{0};
6643   }
6644
6645   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
6646                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6647                                       asm, ".h", "", "", ".h", []> {
6648     bits<3> idx;
6649     let Inst{11} = idx{2};
6650     let Inst{21} = idx{1};
6651     let Inst{20} = idx{0};
6652   }
6653
6654
6655   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6656                                       FPR64Op, FPR32Op, V128, VectorIndexS,
6657                                       asm, ".s", "", "", ".s",
6658     [(set (i64 FPR64Op:$dst),
6659           (Accum (i64 FPR64Op:$Rd),
6660                  (i64 (int_arm64_neon_sqdmulls_scalar
6661                             (i32 FPR32Op:$Rn),
6662                             (i32 (vector_extract (v4i32 V128:$Rm),
6663                                                  VectorIndexS:$idx))))))]> {
6664
6665     bits<2> idx;
6666     let Inst{11} = idx{1};
6667     let Inst{21} = idx{0};
6668   }
6669 }
6670
6671 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
6672                                    SDPatternOperator OpNode> {
6673   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6674   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6675                                       V128, V64,
6676                                       V128_lo, VectorIndexH,
6677                                       asm, ".4s", ".4s", ".4h", ".h",
6678     [(set (v4i32 V128:$Rd),
6679         (OpNode (v4i16 V64:$Rn),
6680          (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6681     bits<3> idx;
6682     let Inst{11} = idx{2};
6683     let Inst{21} = idx{1};
6684     let Inst{20} = idx{0};
6685   }
6686
6687   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6688                                       V128, V128,
6689                                       V128_lo, VectorIndexH,
6690                                       asm#"2", ".4s", ".4s", ".8h", ".h",
6691     [(set (v4i32 V128:$Rd),
6692           (OpNode (extract_high_v8i16 V128:$Rn),
6693                   (extract_high_v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6694                                                       VectorIndexH:$idx))))]> {
6695
6696     bits<3> idx;
6697     let Inst{11} = idx{2};
6698     let Inst{21} = idx{1};
6699     let Inst{20} = idx{0};
6700   }
6701
6702   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6703                                       V128, V64,
6704                                       V128, VectorIndexS,
6705                                       asm, ".2d", ".2d", ".2s", ".s",
6706     [(set (v2i64 V128:$Rd),
6707         (OpNode (v2i32 V64:$Rn),
6708          (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6709     bits<2> idx;
6710     let Inst{11} = idx{1};
6711     let Inst{21} = idx{0};
6712   }
6713
6714   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6715                                       V128, V128,
6716                                       V128, VectorIndexS,
6717                                       asm#"2", ".2d", ".2d", ".4s", ".s",
6718     [(set (v2i64 V128:$Rd),
6719           (OpNode (extract_high_v4i32 V128:$Rn),
6720                   (extract_high_v4i32 (ARM64duplane32 (v4i32 V128:$Rm),
6721                                                       VectorIndexS:$idx))))]> {
6722     bits<2> idx;
6723     let Inst{11} = idx{1};
6724     let Inst{21} = idx{0};
6725   }
6726   }
6727 }
6728
6729 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
6730                                        SDPatternOperator OpNode> {
6731   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6732   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
6733                                       V128, V64,
6734                                       V128_lo, VectorIndexH,
6735                                       asm, ".4s", ".4s", ".4h", ".h",
6736     [(set (v4i32 V128:$dst),
6737         (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
6738          (v4i16 (ARM64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6739     bits<3> idx;
6740     let Inst{11} = idx{2};
6741     let Inst{21} = idx{1};
6742     let Inst{20} = idx{0};
6743   }
6744
6745   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6746                                       V128, V128,
6747                                       V128_lo, VectorIndexH,
6748                                       asm#"2", ".4s", ".4s", ".8h", ".h",
6749     [(set (v4i32 V128:$dst),
6750           (OpNode (v4i32 V128:$Rd),
6751                   (extract_high_v8i16 V128:$Rn),
6752                   (extract_high_v8i16 (ARM64duplane16 (v8i16 V128_lo:$Rm),
6753                                                       VectorIndexH:$idx))))]> {
6754     bits<3> idx;
6755     let Inst{11} = idx{2};
6756     let Inst{21} = idx{1};
6757     let Inst{20} = idx{0};
6758   }
6759
6760   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6761                                       V128, V64,
6762                                       V128, VectorIndexS,
6763                                       asm, ".2d", ".2d", ".2s", ".s",
6764     [(set (v2i64 V128:$dst),
6765         (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
6766          (v2i32 (ARM64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6767     bits<2> idx;
6768     let Inst{11} = idx{1};
6769     let Inst{21} = idx{0};
6770   }
6771
6772   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6773                                       V128, V128,
6774                                       V128, VectorIndexS,
6775                                       asm#"2", ".2d", ".2d", ".4s", ".s",
6776     [(set (v2i64 V128:$dst),
6777           (OpNode (v2i64 V128:$Rd),
6778                   (extract_high_v4i32 V128:$Rn),
6779                   (extract_high_v4i32 (ARM64duplane32 (v4i32 V128:$Rm),
6780                                                       VectorIndexS:$idx))))]> {
6781     bits<2> idx;
6782     let Inst{11} = idx{1};
6783     let Inst{21} = idx{0};
6784   }
6785   }
6786 }
6787
6788 //----------------------------------------------------------------------------
6789 // AdvSIMD scalar shift by immediate
6790 //----------------------------------------------------------------------------
6791
6792 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6793 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
6794                      RegisterClass regtype1, RegisterClass regtype2,
6795                      Operand immtype, string asm, list<dag> pattern>
6796   : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
6797       asm, "\t$Rd, $Rn, $imm", "", pattern>,
6798     Sched<[WriteV]> {
6799   bits<5> Rd;
6800   bits<5> Rn;
6801   bits<7> imm;
6802   let Inst{31-30} = 0b01;
6803   let Inst{29}    = U;
6804   let Inst{28-23} = 0b111110;
6805   let Inst{22-16} = fixed_imm;
6806   let Inst{15-11} = opc;
6807   let Inst{10}    = 1;
6808   let Inst{9-5} = Rn;
6809   let Inst{4-0} = Rd;
6810 }
6811
6812 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6813 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
6814                      RegisterClass regtype1, RegisterClass regtype2,
6815                      Operand immtype, string asm, list<dag> pattern>
6816   : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
6817       asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
6818     Sched<[WriteV]> {
6819   bits<5> Rd;
6820   bits<5> Rn;
6821   bits<7> imm;
6822   let Inst{31-30} = 0b01;
6823   let Inst{29}    = U;
6824   let Inst{28-23} = 0b111110;
6825   let Inst{22-16} = fixed_imm;
6826   let Inst{15-11} = opc;
6827   let Inst{10}    = 1;
6828   let Inst{9-5} = Rn;
6829   let Inst{4-0} = Rd;
6830 }
6831
6832
6833 multiclass SIMDScalarRShiftSD<bit U, bits<5> opc, string asm> {
6834   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
6835                               FPR32, FPR32, vecshiftR32, asm, []> {
6836     let Inst{20-16} = imm{4-0};
6837   }
6838
6839   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6840                               FPR64, FPR64, vecshiftR64, asm, []> {
6841     let Inst{21-16} = imm{5-0};
6842   }
6843 }
6844
6845 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
6846                              SDPatternOperator OpNode> {
6847   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6848                               FPR64, FPR64, vecshiftR64, asm,
6849   [(set (i64 FPR64:$Rd),
6850      (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
6851     let Inst{21-16} = imm{5-0};
6852   }
6853
6854   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
6855             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
6856 }
6857
6858 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
6859                                  SDPatternOperator OpNode = null_frag> {
6860   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
6861                               FPR64, FPR64, vecshiftR64, asm,
6862   [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
6863                                                    (i32 vecshiftR64:$imm)))]> {
6864     let Inst{21-16} = imm{5-0};
6865   }
6866
6867   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
6868                            (i32 vecshiftR64:$imm))),
6869             (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
6870                                             vecshiftR64:$imm)>;
6871 }
6872
6873 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
6874                              SDPatternOperator OpNode> {
6875   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6876                               FPR64, FPR64, vecshiftL64, asm,
6877     [(set (v1i64 FPR64:$Rd),
6878        (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
6879     let Inst{21-16} = imm{5-0};
6880   }
6881 }
6882
6883 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6884 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
6885   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
6886                               FPR64, FPR64, vecshiftL64, asm, []> {
6887     let Inst{21-16} = imm{5-0};
6888   }
6889 }
6890
6891 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6892 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
6893                                SDPatternOperator OpNode = null_frag> {
6894   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
6895                               FPR8, FPR16, vecshiftR8, asm, []> {
6896     let Inst{18-16} = imm{2-0};
6897   }
6898
6899   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
6900                               FPR16, FPR32, vecshiftR16, asm, []> {
6901     let Inst{19-16} = imm{3-0};
6902   }
6903
6904   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
6905                               FPR32, FPR64, vecshiftR32, asm,
6906     [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
6907     let Inst{20-16} = imm{4-0};
6908   }
6909 }
6910
6911 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
6912                                 SDPatternOperator OpNode> {
6913   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
6914                               FPR8, FPR8, vecshiftL8, asm, []> {
6915     let Inst{18-16} = imm{2-0};
6916   }
6917
6918   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
6919                               FPR16, FPR16, vecshiftL16, asm, []> {
6920     let Inst{19-16} = imm{3-0};
6921   }
6922
6923   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
6924                               FPR32, FPR32, vecshiftL32, asm,
6925     [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
6926     let Inst{20-16} = imm{4-0};
6927   }
6928
6929   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6930                               FPR64, FPR64, vecshiftL64, asm,
6931     [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
6932     let Inst{21-16} = imm{5-0};
6933   }
6934
6935   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
6936             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
6937 }
6938
6939 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
6940   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
6941                               FPR8, FPR8, vecshiftR8, asm, []> {
6942     let Inst{18-16} = imm{2-0};
6943   }
6944
6945   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
6946                               FPR16, FPR16, vecshiftR16, asm, []> {
6947     let Inst{19-16} = imm{3-0};
6948   }
6949
6950   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
6951                               FPR32, FPR32, vecshiftR32, asm, []> {
6952     let Inst{20-16} = imm{4-0};
6953   }
6954
6955   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
6956                               FPR64, FPR64, vecshiftR64, asm, []> {
6957     let Inst{21-16} = imm{5-0};
6958   }
6959 }
6960
6961 //----------------------------------------------------------------------------
6962 // AdvSIMD vector x indexed element
6963 //----------------------------------------------------------------------------
6964
6965 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6966 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
6967                      RegisterOperand dst_reg, RegisterOperand src_reg,
6968                      Operand immtype,
6969                      string asm, string dst_kind, string src_kind,
6970                      list<dag> pattern>
6971   : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
6972       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
6973            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
6974     Sched<[WriteV]> {
6975   bits<5> Rd;
6976   bits<5> Rn;
6977   let Inst{31}    = 0;
6978   let Inst{30}    = Q;
6979   let Inst{29}    = U;
6980   let Inst{28-23} = 0b011110;
6981   let Inst{22-16} = fixed_imm;
6982   let Inst{15-11} = opc;
6983   let Inst{10}    = 1;
6984   let Inst{9-5}   = Rn;
6985   let Inst{4-0}   = Rd;
6986 }
6987
6988 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6989 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
6990                      RegisterOperand vectype1, RegisterOperand vectype2,
6991                      Operand immtype,
6992                      string asm, string dst_kind, string src_kind,
6993                      list<dag> pattern>
6994   : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
6995       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
6996            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
6997     Sched<[WriteV]> {
6998   bits<5> Rd;
6999   bits<5> Rn;
7000   let Inst{31}    = 0;
7001   let Inst{30}    = Q;
7002   let Inst{29}    = U;
7003   let Inst{28-23} = 0b011110;
7004   let Inst{22-16} = fixed_imm;
7005   let Inst{15-11} = opc;
7006   let Inst{10}    = 1;
7007   let Inst{9-5}   = Rn;
7008   let Inst{4-0}   = Rd;
7009 }
7010
7011 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
7012                               Intrinsic OpNode> {
7013   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7014                                   V64, V64, vecshiftR32,
7015                                   asm, ".2s", ".2s",
7016       [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
7017     bits<5> imm;
7018     let Inst{20-16} = imm;
7019   }
7020
7021   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7022                                   V128, V128, vecshiftR32,
7023                                   asm, ".4s", ".4s",
7024       [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
7025     bits<5> imm;
7026     let Inst{20-16} = imm;
7027   }
7028
7029   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7030                                   V128, V128, vecshiftR64,
7031                                   asm, ".2d", ".2d",
7032       [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
7033     bits<6> imm;
7034     let Inst{21-16} = imm;
7035   }
7036 }
7037
7038 multiclass SIMDVectorRShiftSDToFP<bit U, bits<5> opc, string asm,
7039                                   Intrinsic OpNode> {
7040   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7041                                   V64, V64, vecshiftR32,
7042                                   asm, ".2s", ".2s",
7043       [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
7044     bits<5> imm;
7045     let Inst{20-16} = imm;
7046   }
7047
7048   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7049                                   V128, V128, vecshiftR32,
7050                                   asm, ".4s", ".4s",
7051       [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
7052     bits<5> imm;
7053     let Inst{20-16} = imm;
7054   }
7055
7056   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7057                                   V128, V128, vecshiftR64,
7058                                   asm, ".2d", ".2d",
7059       [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
7060     bits<6> imm;
7061     let Inst{21-16} = imm;
7062   }
7063 }
7064
7065 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
7066                                      SDPatternOperator OpNode> {
7067   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7068                                   V64, V128, vecshiftR16Narrow,
7069                                   asm, ".8b", ".8h",
7070       [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
7071     bits<3> imm;
7072     let Inst{18-16} = imm;
7073   }
7074
7075   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7076                                   V128, V128, vecshiftR16Narrow,
7077                                   asm#"2", ".16b", ".8h", []> {
7078     bits<3> imm;
7079     let Inst{18-16} = imm;
7080     let hasSideEffects = 0;
7081   }
7082
7083   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7084                                   V64, V128, vecshiftR32Narrow,
7085                                   asm, ".4h", ".4s",
7086       [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
7087     bits<4> imm;
7088     let Inst{19-16} = imm;
7089   }
7090
7091   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7092                                   V128, V128, vecshiftR32Narrow,
7093                                   asm#"2", ".8h", ".4s", []> {
7094     bits<4> imm;
7095     let Inst{19-16} = imm;
7096     let hasSideEffects = 0;
7097   }
7098
7099   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7100                                   V64, V128, vecshiftR64Narrow,
7101                                   asm, ".2s", ".2d",
7102       [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
7103     bits<5> imm;
7104     let Inst{20-16} = imm;
7105   }
7106
7107   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7108                                   V128, V128, vecshiftR64Narrow,
7109                                   asm#"2", ".4s", ".2d", []> {
7110     bits<5> imm;
7111     let Inst{20-16} = imm;
7112     let hasSideEffects = 0;
7113   }
7114
7115   // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
7116   // themselves, so put them here instead.
7117
7118   // Patterns involving what's effectively an insert high and a normal
7119   // intrinsic, represented by CONCAT_VECTORS.
7120   def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
7121                                                    vecshiftR16Narrow:$imm)),
7122             (!cast<Instruction>(NAME # "v16i8_shift")
7123                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7124                 V128:$Rn, vecshiftR16Narrow:$imm)>;
7125   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
7126                                                      vecshiftR32Narrow:$imm)),
7127             (!cast<Instruction>(NAME # "v8i16_shift")
7128                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7129                 V128:$Rn, vecshiftR32Narrow:$imm)>;
7130   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
7131                                                      vecshiftR64Narrow:$imm)),
7132             (!cast<Instruction>(NAME # "v4i32_shift")
7133                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7134                 V128:$Rn, vecshiftR64Narrow:$imm)>;
7135 }
7136
7137 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
7138                                 SDPatternOperator OpNode> {
7139   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7140                                   V64, V64, vecshiftL8,
7141                                   asm, ".8b", ".8b",
7142                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7143                        (i32 vecshiftL8:$imm)))]> {
7144     bits<3> imm;
7145     let Inst{18-16} = imm;
7146   }
7147
7148   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7149                                   V128, V128, vecshiftL8,
7150                                   asm, ".16b", ".16b",
7151              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7152                    (i32 vecshiftL8:$imm)))]> {
7153     bits<3> imm;
7154     let Inst{18-16} = imm;
7155   }
7156
7157   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7158                                   V64, V64, vecshiftL16,
7159                                   asm, ".4h", ".4h",
7160               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7161                     (i32 vecshiftL16:$imm)))]> {
7162     bits<4> imm;
7163     let Inst{19-16} = imm;
7164   }
7165
7166   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7167                                   V128, V128, vecshiftL16,
7168                                   asm, ".8h", ".8h",
7169             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7170                   (i32 vecshiftL16:$imm)))]> {
7171     bits<4> imm;
7172     let Inst{19-16} = imm;
7173   }
7174
7175   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7176                                   V64, V64, vecshiftL32,
7177                                   asm, ".2s", ".2s",
7178               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7179                     (i32 vecshiftL32:$imm)))]> {
7180     bits<5> imm;
7181     let Inst{20-16} = imm;
7182   }
7183
7184   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7185                                   V128, V128, vecshiftL32,
7186                                   asm, ".4s", ".4s",
7187             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7188                   (i32 vecshiftL32:$imm)))]> {
7189     bits<5> imm;
7190     let Inst{20-16} = imm;
7191   }
7192
7193   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7194                                   V128, V128, vecshiftL64,
7195                                   asm, ".2d", ".2d",
7196             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7197                   (i32 vecshiftL64:$imm)))]> {
7198     bits<6> imm;
7199     let Inst{21-16} = imm;
7200   }
7201 }
7202
7203 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
7204                                 SDPatternOperator OpNode> {
7205   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7206                                   V64, V64, vecshiftR8,
7207                                   asm, ".8b", ".8b",
7208                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7209                        (i32 vecshiftR8:$imm)))]> {
7210     bits<3> imm;
7211     let Inst{18-16} = imm;
7212   }
7213
7214   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7215                                   V128, V128, vecshiftR8,
7216                                   asm, ".16b", ".16b",
7217              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7218                    (i32 vecshiftR8:$imm)))]> {
7219     bits<3> imm;
7220     let Inst{18-16} = imm;
7221   }
7222
7223   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7224                                   V64, V64, vecshiftR16,
7225                                   asm, ".4h", ".4h",
7226               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7227                     (i32 vecshiftR16:$imm)))]> {
7228     bits<4> imm;
7229     let Inst{19-16} = imm;
7230   }
7231
7232   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7233                                   V128, V128, vecshiftR16,
7234                                   asm, ".8h", ".8h",
7235             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7236                   (i32 vecshiftR16:$imm)))]> {
7237     bits<4> imm;
7238     let Inst{19-16} = imm;
7239   }
7240
7241   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7242                                   V64, V64, vecshiftR32,
7243                                   asm, ".2s", ".2s",
7244               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7245                     (i32 vecshiftR32:$imm)))]> {
7246     bits<5> imm;
7247     let Inst{20-16} = imm;
7248   }
7249
7250   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7251                                   V128, V128, vecshiftR32,
7252                                   asm, ".4s", ".4s",
7253             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7254                   (i32 vecshiftR32:$imm)))]> {
7255     bits<5> imm;
7256     let Inst{20-16} = imm;
7257   }
7258
7259   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7260                                   V128, V128, vecshiftR64,
7261                                   asm, ".2d", ".2d",
7262             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7263                   (i32 vecshiftR64:$imm)))]> {
7264     bits<6> imm;
7265     let Inst{21-16} = imm;
7266   }
7267 }
7268
7269 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7270 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
7271                                     SDPatternOperator OpNode = null_frag> {
7272   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7273                                   V64, V64, vecshiftR8, asm, ".8b", ".8b",
7274                  [(set (v8i8 V64:$dst),
7275                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7276                            (i32 vecshiftR8:$imm)))]> {
7277     bits<3> imm;
7278     let Inst{18-16} = imm;
7279   }
7280
7281   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7282                                   V128, V128, vecshiftR8, asm, ".16b", ".16b",
7283              [(set (v16i8 V128:$dst),
7284                (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7285                        (i32 vecshiftR8:$imm)))]> {
7286     bits<3> imm;
7287     let Inst{18-16} = imm;
7288   }
7289
7290   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7291                                   V64, V64, vecshiftR16, asm, ".4h", ".4h",
7292               [(set (v4i16 V64:$dst),
7293                 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7294                         (i32 vecshiftR16:$imm)))]> {
7295     bits<4> imm;
7296     let Inst{19-16} = imm;
7297   }
7298
7299   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7300                                   V128, V128, vecshiftR16, asm, ".8h", ".8h",
7301             [(set (v8i16 V128:$dst),
7302               (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7303                       (i32 vecshiftR16:$imm)))]> {
7304     bits<4> imm;
7305     let Inst{19-16} = imm;
7306   }
7307
7308   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7309                                   V64, V64, vecshiftR32, asm, ".2s", ".2s",
7310               [(set (v2i32 V64:$dst),
7311                 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7312                         (i32 vecshiftR32:$imm)))]> {
7313     bits<5> imm;
7314     let Inst{20-16} = imm;
7315   }
7316
7317   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7318                                   V128, V128, vecshiftR32, asm, ".4s", ".4s",
7319             [(set (v4i32 V128:$dst),
7320               (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7321                       (i32 vecshiftR32:$imm)))]> {
7322     bits<5> imm;
7323     let Inst{20-16} = imm;
7324   }
7325
7326   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7327                                   V128, V128, vecshiftR64,
7328                                   asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
7329               (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7330                       (i32 vecshiftR64:$imm)))]> {
7331     bits<6> imm;
7332     let Inst{21-16} = imm;
7333   }
7334 }
7335
7336 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
7337                                     SDPatternOperator OpNode = null_frag> {
7338   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7339                                   V64, V64, vecshiftL8,
7340                                   asm, ".8b", ".8b",
7341                     [(set (v8i8 V64:$dst),
7342                           (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7343                                   (i32 vecshiftL8:$imm)))]> {
7344     bits<3> imm;
7345     let Inst{18-16} = imm;
7346   }
7347
7348   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7349                                   V128, V128, vecshiftL8,
7350                                   asm, ".16b", ".16b",
7351                     [(set (v16i8 V128:$dst),
7352                           (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7353                                   (i32 vecshiftL8:$imm)))]> {
7354     bits<3> imm;
7355     let Inst{18-16} = imm;
7356   }
7357
7358   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7359                                   V64, V64, vecshiftL16,
7360                                   asm, ".4h", ".4h",
7361                     [(set (v4i16 V64:$dst),
7362                            (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7363                                    (i32 vecshiftL16:$imm)))]> {
7364     bits<4> imm;
7365     let Inst{19-16} = imm;
7366   }
7367
7368   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7369                                   V128, V128, vecshiftL16,
7370                                   asm, ".8h", ".8h",
7371                     [(set (v8i16 V128:$dst),
7372                           (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7373                                   (i32 vecshiftL16:$imm)))]> {
7374     bits<4> imm;
7375     let Inst{19-16} = imm;
7376   }
7377
7378   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7379                                   V64, V64, vecshiftL32,
7380                                   asm, ".2s", ".2s",
7381                     [(set (v2i32 V64:$dst),
7382                           (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7383                                   (i32 vecshiftL32:$imm)))]> {
7384     bits<5> imm;
7385     let Inst{20-16} = imm;
7386   }
7387
7388   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7389                                   V128, V128, vecshiftL32,
7390                                   asm, ".4s", ".4s",
7391                     [(set (v4i32 V128:$dst),
7392                           (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7393                                   (i32 vecshiftL32:$imm)))]> {
7394     bits<5> imm;
7395     let Inst{20-16} = imm;
7396   }
7397
7398   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7399                                   V128, V128, vecshiftL64,
7400                                   asm, ".2d", ".2d",
7401                     [(set (v2i64 V128:$dst),
7402                           (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7403                                   (i32 vecshiftL64:$imm)))]> {
7404     bits<6> imm;
7405     let Inst{21-16} = imm;
7406   }
7407 }
7408
7409 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
7410                                    SDPatternOperator OpNode> {
7411   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7412                                   V128, V64, vecshiftL8, asm, ".8h", ".8b",
7413       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
7414     bits<3> imm;
7415     let Inst{18-16} = imm;
7416   }
7417
7418   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7419                                   V128, V128, vecshiftL8,
7420                                   asm#"2", ".8h", ".16b",
7421       [(set (v8i16 V128:$Rd),
7422             (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
7423     bits<3> imm;
7424     let Inst{18-16} = imm;
7425   }
7426
7427   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7428                                   V128, V64, vecshiftL16, asm, ".4s", ".4h",
7429       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
7430     bits<4> imm;
7431     let Inst{19-16} = imm;
7432   }
7433
7434   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7435                                   V128, V128, vecshiftL16,
7436                                   asm#"2", ".4s", ".8h",
7437       [(set (v4i32 V128:$Rd),
7438             (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
7439
7440     bits<4> imm;
7441     let Inst{19-16} = imm;
7442   }
7443
7444   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7445                                   V128, V64, vecshiftL32, asm, ".2d", ".2s",
7446       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
7447     bits<5> imm;
7448     let Inst{20-16} = imm;
7449   }
7450
7451   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7452                                   V128, V128, vecshiftL32,
7453                                   asm#"2", ".2d", ".4s",
7454       [(set (v2i64 V128:$Rd),
7455             (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
7456     bits<5> imm;
7457     let Inst{20-16} = imm;
7458   }
7459 }
7460
7461
7462 //---
7463 // Vector load/store
7464 //---
7465 // SIMD ldX/stX no-index memory references don't allow the optional
7466 // ", #0" constant and handle post-indexing explicitly, so we use
7467 // a more specialized parse method for them. Otherwise, it's the same as
7468 // the general am_noindex handling.
7469
7470 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
7471                    string asm, dag oops, dag iops, list<dag> pattern>
7472   : I<oops, iops, asm, "\t$Vt, $vaddr", "", pattern> {
7473   bits<5> Vt;
7474   bits<5> vaddr;
7475   let Inst{31} = 0;
7476   let Inst{30} = Q;
7477   let Inst{29-23} = 0b0011000;
7478   let Inst{22} = L;
7479   let Inst{21-16} = 0b000000;
7480   let Inst{15-12} = opcode;
7481   let Inst{11-10} = size;
7482   let Inst{9-5} = vaddr;
7483   let Inst{4-0} = Vt;
7484 }
7485
7486 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
7487                        string asm, dag oops, dag iops>
7488   : I<oops, iops, asm, "\t$Vt, $vaddr, $Xm", "$vaddr = $wback", []> {
7489   bits<5> Vt;
7490   bits<5> vaddr;
7491   bits<5> Xm;
7492   let Inst{31} = 0;
7493   let Inst{30} = Q;
7494   let Inst{29-23} = 0b0011001;
7495   let Inst{22} = L;
7496   let Inst{21} = 0;
7497   let Inst{20-16} = Xm;
7498   let Inst{15-12} = opcode;
7499   let Inst{11-10} = size;
7500   let Inst{9-5} = vaddr;
7501   let Inst{4-0} = Vt;
7502 }
7503
7504 // The immediate form of AdvSIMD post-indexed addressing is encoded with
7505 // register post-index addressing from the zero register.
7506 multiclass SIMDLdStAliases<string asm, string layout, string Count,
7507                            int Offset, int Size> {
7508   // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
7509   //      "ld1\t$Vt, $vaddr, #16"
7510   // may get mapped to
7511   //      (LD1Twov8b_POST VecListTwo8b:$Vt, am_simdnoindex:$vaddr, XZR)
7512   def : InstAlias<asm # "\t$Vt, $vaddr, #" # Offset,
7513                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7514                       am_simdnoindex:$vaddr,
7515                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
7516                       XZR), 1>;
7517
7518   // E.g. "ld1.8b { v0, v1 }, [x1], #16"
7519   //      "ld1.8b\t$Vt, $vaddr, #16"
7520   // may get mapped to
7521   //      (LD1Twov8b_POST VecListTwo64:$Vt, am_simdnoindex:$vaddr, XZR)
7522   def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr, #" # Offset,
7523                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7524                       am_simdnoindex:$vaddr,
7525                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7526                       XZR), 0>;
7527
7528   // E.g. "ld1.8b { v0, v1 }, [x1]"
7529   //      "ld1\t$Vt, $vaddr"
7530   // may get mapped to
7531   //      (LD1Twov8b VecListTwo64:$Vt, am_simdnoindex:$vaddr)
7532   def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr",
7533                   (!cast<Instruction>(NAME # Count # "v" # layout)
7534                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7535                       am_simdnoindex:$vaddr), 0>;
7536
7537   // E.g. "ld1.8b { v0, v1 }, [x1], x2"
7538   //      "ld1\t$Vt, $vaddr, $Xm"
7539   // may get mapped to
7540   //      (LD1Twov8b_POST VecListTwo64:$Vt, am_simdnoindex:$vaddr, GPR64pi8:$Xm)
7541   def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr, $Xm",
7542                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7543                       am_simdnoindex:$vaddr,
7544                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7545                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
7546 }
7547
7548 multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
7549                        int Offset64, bits<4> opcode> {
7550   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
7551     def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
7552                            (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
7553                            (ins am_simdnoindex:$vaddr), []>;
7554     def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
7555                            (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
7556                            (ins am_simdnoindex:$vaddr), []>;
7557     def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
7558                            (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
7559                            (ins am_simdnoindex:$vaddr), []>;
7560     def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
7561                            (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
7562                            (ins am_simdnoindex:$vaddr), []>;
7563     def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
7564                            (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
7565                            (ins am_simdnoindex:$vaddr), []>;
7566     def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
7567                            (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
7568                            (ins am_simdnoindex:$vaddr), []>;
7569     def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
7570                            (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
7571                            (ins am_simdnoindex:$vaddr), []>;
7572
7573
7574     def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
7575                        (outs am_simdnoindex:$wback,
7576                              !cast<RegisterOperand>(veclist # "16b"):$Vt),
7577                        (ins am_simdnoindex:$vaddr,
7578                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7579     def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
7580                        (outs am_simdnoindex:$wback,
7581                              !cast<RegisterOperand>(veclist # "8h"):$Vt),
7582                        (ins am_simdnoindex:$vaddr,
7583                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7584     def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
7585                        (outs am_simdnoindex:$wback,
7586                              !cast<RegisterOperand>(veclist # "4s"):$Vt),
7587                        (ins am_simdnoindex:$vaddr,
7588                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7589     def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
7590                        (outs am_simdnoindex:$wback,
7591                              !cast<RegisterOperand>(veclist # "2d"):$Vt),
7592                        (ins am_simdnoindex:$vaddr,
7593                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7594     def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
7595                        (outs am_simdnoindex:$wback,
7596                              !cast<RegisterOperand>(veclist # "8b"):$Vt),
7597                        (ins am_simdnoindex:$vaddr,
7598                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7599     def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
7600                        (outs am_simdnoindex:$wback,
7601                              !cast<RegisterOperand>(veclist # "4h"):$Vt),
7602                        (ins am_simdnoindex:$vaddr,
7603                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7604     def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
7605                        (outs am_simdnoindex:$wback,
7606                              !cast<RegisterOperand>(veclist # "2s"):$Vt),
7607                        (ins am_simdnoindex:$vaddr,
7608                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7609   }
7610
7611   defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
7612   defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
7613   defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
7614   defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
7615   defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
7616   defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
7617   defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
7618 }
7619
7620 // Only ld1/st1 has a v1d version.
7621 multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
7622                        int Offset64, bits<4> opcode> {
7623   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
7624     def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
7625                             (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
7626                                  am_simdnoindex:$vaddr), []>;
7627     def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
7628                            (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
7629                                 am_simdnoindex:$vaddr), []>;
7630     def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
7631                            (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
7632                                 am_simdnoindex:$vaddr), []>;
7633     def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
7634                            (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
7635                                 am_simdnoindex:$vaddr), []>;
7636     def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
7637                            (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
7638                                 am_simdnoindex:$vaddr), []>;
7639     def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
7640                            (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
7641                                 am_simdnoindex:$vaddr), []>;
7642     def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
7643                            (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
7644                                 am_simdnoindex:$vaddr), []>;
7645
7646     def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
7647                        (outs am_simdnoindex:$wback),
7648                        (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
7649                             am_simdnoindex:$vaddr,
7650                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7651     def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
7652                        (outs am_simdnoindex:$wback),
7653                        (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
7654                             am_simdnoindex:$vaddr,
7655                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7656     def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
7657                        (outs am_simdnoindex:$wback),
7658                        (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
7659                             am_simdnoindex:$vaddr,
7660                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7661     def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
7662                        (outs am_simdnoindex:$wback),
7663                        (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
7664                             am_simdnoindex:$vaddr,
7665                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7666     def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
7667                        (outs am_simdnoindex:$wback),
7668                        (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
7669                             am_simdnoindex:$vaddr,
7670                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7671     def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
7672                        (outs am_simdnoindex:$wback),
7673                        (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
7674                             am_simdnoindex:$vaddr,
7675                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7676     def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
7677                        (outs am_simdnoindex:$wback),
7678                        (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
7679                             am_simdnoindex:$vaddr,
7680                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7681   }
7682
7683   defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
7684   defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
7685   defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
7686   defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
7687   defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
7688   defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
7689   defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
7690 }
7691
7692 multiclass BaseSIMDLd1<string Count, string asm, string veclist,
7693                        int Offset128, int Offset64, bits<4> opcode>
7694   : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
7695
7696   // LD1 instructions have extra "1d" variants.
7697   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
7698     def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
7699                            (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
7700                            (ins am_simdnoindex:$vaddr), []>;
7701
7702     def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
7703                        (outs am_simdnoindex:$wback,
7704                              !cast<RegisterOperand>(veclist # "1d"):$Vt),
7705                        (ins am_simdnoindex:$vaddr,
7706                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7707   }
7708
7709   defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
7710 }
7711
7712 multiclass BaseSIMDSt1<string Count, string asm, string veclist,
7713                        int Offset128, int Offset64, bits<4> opcode>
7714   : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
7715
7716   // ST1 instructions have extra "1d" variants.
7717   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
7718     def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
7719                            (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
7720                                 am_simdnoindex:$vaddr), []>;
7721
7722     def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
7723                        (outs am_simdnoindex:$wback),
7724                        (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
7725                             am_simdnoindex:$vaddr,
7726                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7727   }
7728
7729   defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
7730 }
7731
7732 multiclass SIMDLd1Multiple<string asm> {
7733   defm One   : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8,  0b0111>;
7734   defm Two   : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
7735   defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
7736   defm Four  : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
7737 }
7738
7739 multiclass SIMDSt1Multiple<string asm> {
7740   defm One   : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8,  0b0111>;
7741   defm Two   : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
7742   defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
7743   defm Four  : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
7744 }
7745
7746 multiclass SIMDLd2Multiple<string asm> {
7747   defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
7748 }
7749
7750 multiclass SIMDSt2Multiple<string asm> {
7751   defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
7752 }
7753
7754 multiclass SIMDLd3Multiple<string asm> {
7755   defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
7756 }
7757
7758 multiclass SIMDSt3Multiple<string asm> {
7759   defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
7760 }
7761
7762 multiclass SIMDLd4Multiple<string asm> {
7763   defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
7764 }
7765
7766 multiclass SIMDSt4Multiple<string asm> {
7767   defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
7768 }
7769
7770 //---
7771 // AdvSIMD Load/store single-element
7772 //---
7773
7774 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
7775                          string asm, string operands, string cst,
7776                          dag oops, dag iops, list<dag> pattern>
7777   : I<oops, iops, asm, operands, cst, pattern> {
7778   bits<5> Vt;
7779   bits<5> vaddr;
7780   let Inst{31} = 0;
7781   let Inst{29-24} = 0b001101;
7782   let Inst{22} = L;
7783   let Inst{21} = R;
7784   let Inst{15-13} = opcode;
7785   let Inst{9-5} = vaddr;
7786   let Inst{4-0} = Vt;
7787 }
7788
7789 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
7790                          string asm, string operands, string cst,
7791                          dag oops, dag iops, list<dag> pattern>
7792   : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
7793   bits<5> Vt;
7794   bits<5> vaddr;
7795   let Inst{31} = 0;
7796   let Inst{29-24} = 0b001101;
7797   let Inst{22} = L;
7798   let Inst{21} = R;
7799   let Inst{15-13} = opcode;
7800   let Inst{9-5} = vaddr;
7801   let Inst{4-0} = Vt;
7802 }
7803
7804
7805 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
7806 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
7807                   Operand listtype>
7808   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, $vaddr", "",
7809                        (outs listtype:$Vt), (ins am_simdnoindex:$vaddr),
7810                        []> {
7811   let Inst{30} = Q;
7812   let Inst{23} = 0;
7813   let Inst{20-16} = 0b00000;
7814   let Inst{12} = S;
7815   let Inst{11-10} = size;
7816 }
7817 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
7818 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
7819                       string asm, Operand listtype, Operand GPR64pi>
7820   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, $vaddr, $Xm",
7821                        "$vaddr = $wback",
7822                        (outs am_simdnoindex:$wback, listtype:$Vt),
7823                        (ins am_simdnoindex:$vaddr, GPR64pi:$Xm), []> {
7824   bits<5> Xm;
7825   let Inst{30} = Q;
7826   let Inst{23} = 1;
7827   let Inst{20-16} = Xm;
7828   let Inst{12} = S;
7829   let Inst{11-10} = size;
7830 }
7831
7832 multiclass SIMDLdrAliases<string asm, string layout, string Count,
7833                           int Offset, int Size> {
7834   // E.g. "ld1r { v0.8b }, [x1], #1"
7835   //      "ld1r.8b\t$Vt, $vaddr, #1"
7836   // may get mapped to
7837   //      (LD1Rv8b_POST VecListOne8b:$Vt, am_simdnoindex:$vaddr, XZR)
7838   def : InstAlias<asm # "\t$Vt, $vaddr, #" # Offset,
7839                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
7840                       am_simdnoindex:$vaddr,
7841                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
7842                       XZR), 1>;
7843
7844   // E.g. "ld1r.8b { v0 }, [x1], #1"
7845   //      "ld1r.8b\t$Vt, $vaddr, #1"
7846   // may get mapped to
7847   //      (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, XZR)
7848   def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr, #" # Offset,
7849                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
7850                       am_simdnoindex:$vaddr,
7851                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7852                       XZR), 0>;
7853
7854   // E.g. "ld1r.8b { v0 }, [x1]"
7855   //      "ld1r.8b\t$Vt, $vaddr"
7856   // may get mapped to
7857   //      (LD1Rv8b VecListOne64:$Vt, am_simdnoindex:$vaddr)
7858   def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr",
7859                   (!cast<Instruction>(NAME # "v" # layout)
7860                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7861                       am_simdnoindex:$vaddr), 0>;
7862
7863   // E.g. "ld1r.8b { v0 }, [x1], x2"
7864   //      "ld1r.8b\t$Vt, $vaddr, $Xm"
7865   // may get mapped to
7866   //      (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, GPR64pi1:$Xm)
7867   def : InstAlias<asm # "." # layout # "\t$Vt, $vaddr, $Xm",
7868                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
7869                       am_simdnoindex:$vaddr,
7870                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7871                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
7872 }
7873
7874 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
7875   int Offset1, int Offset2, int Offset4, int Offset8> {
7876   def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
7877                         !cast<Operand>("VecList" # Count # "8b")>;
7878   def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
7879                         !cast<Operand>("VecList" # Count #"16b")>;
7880   def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
7881                         !cast<Operand>("VecList" # Count #"4h")>;
7882   def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
7883                         !cast<Operand>("VecList" # Count #"8h")>;
7884   def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
7885                         !cast<Operand>("VecList" # Count #"2s")>;
7886   def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
7887                         !cast<Operand>("VecList" # Count #"4s")>;
7888   def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
7889                         !cast<Operand>("VecList" # Count #"1d")>;
7890   def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
7891                         !cast<Operand>("VecList" # Count #"2d")>;
7892
7893   def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
7894                                  !cast<Operand>("VecList" # Count # "8b"),
7895                                  !cast<Operand>("GPR64pi" # Offset1)>;
7896   def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
7897                                  !cast<Operand>("VecList" # Count # "16b"),
7898                                  !cast<Operand>("GPR64pi" # Offset1)>;
7899   def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
7900                                  !cast<Operand>("VecList" # Count # "4h"),
7901                                  !cast<Operand>("GPR64pi" # Offset2)>;
7902   def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
7903                                  !cast<Operand>("VecList" # Count # "8h"),
7904                                  !cast<Operand>("GPR64pi" # Offset2)>;
7905   def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
7906                                  !cast<Operand>("VecList" # Count # "2s"),
7907                                  !cast<Operand>("GPR64pi" # Offset4)>;
7908   def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
7909                                  !cast<Operand>("VecList" # Count # "4s"),
7910                                  !cast<Operand>("GPR64pi" # Offset4)>;
7911   def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
7912                                  !cast<Operand>("VecList" # Count # "1d"),
7913                                  !cast<Operand>("GPR64pi" # Offset8)>;
7914   def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
7915                                  !cast<Operand>("VecList" # Count # "2d"),
7916                                  !cast<Operand>("GPR64pi" # Offset8)>;
7917
7918   defm : SIMDLdrAliases<asm, "8b",  Count, Offset1,  64>;
7919   defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
7920   defm : SIMDLdrAliases<asm, "4h",  Count, Offset2,  64>;
7921   defm : SIMDLdrAliases<asm, "8h",  Count, Offset2, 128>;
7922   defm : SIMDLdrAliases<asm, "2s",  Count, Offset4,  64>;
7923   defm : SIMDLdrAliases<asm, "4s",  Count, Offset4, 128>;
7924   defm : SIMDLdrAliases<asm, "1d",  Count, Offset8,  64>;
7925   defm : SIMDLdrAliases<asm, "2d",  Count, Offset8, 128>;
7926 }
7927
7928 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
7929                       dag oops, dag iops, list<dag> pattern>
7930   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr", "", oops, iops,
7931                        pattern> {
7932   // idx encoded in Q:S:size fields.
7933   bits<4> idx;
7934   let Inst{30} = idx{3};
7935   let Inst{23} = 0;
7936   let Inst{20-16} = 0b00000;
7937   let Inst{12} = idx{2};
7938   let Inst{11-10} = idx{1-0};
7939 }
7940 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
7941                       dag oops, dag iops, list<dag> pattern>
7942   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr", "",
7943                            oops, iops, pattern> {
7944   // idx encoded in Q:S:size fields.
7945   bits<4> idx;
7946   let Inst{30} = idx{3};
7947   let Inst{23} = 0;
7948   let Inst{20-16} = 0b00000;
7949   let Inst{12} = idx{2};
7950   let Inst{11-10} = idx{1-0};
7951 }
7952 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
7953                           dag oops, dag iops>
7954   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7955                        "$vaddr = $wback", oops, iops, []> {
7956   // idx encoded in Q:S:size fields.
7957   bits<4> idx;
7958   bits<5> Xm;
7959   let Inst{30} = idx{3};
7960   let Inst{23} = 1;
7961   let Inst{20-16} = Xm;
7962   let Inst{12} = idx{2};
7963   let Inst{11-10} = idx{1-0};
7964 }
7965 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
7966                           dag oops, dag iops>
7967   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
7968                            "$vaddr = $wback", oops, iops, []> {
7969   // idx encoded in Q:S:size fields.
7970   bits<4> idx;
7971   bits<5> Xm;
7972   let Inst{30} = idx{3};
7973   let Inst{23} = 1;
7974   let Inst{20-16} = Xm;
7975   let Inst{12} = idx{2};
7976   let Inst{11-10} = idx{1-0};
7977 }
7978
7979 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
7980                       dag oops, dag iops, list<dag> pattern>
7981   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr", "", oops, iops,
7982                        pattern> {
7983   // idx encoded in Q:S:size<1> fields.
7984   bits<3> idx;
7985   let Inst{30} = idx{2};
7986   let Inst{23} = 0;
7987   let Inst{20-16} = 0b00000;
7988   let Inst{12} = idx{1};
7989   let Inst{11} = idx{0};
7990   let Inst{10} = size;
7991 }
7992 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
7993                       dag oops, dag iops, list<dag> pattern>
7994   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr", "",
7995                            oops, iops, pattern> {
7996   // idx encoded in Q:S:size<1> fields.
7997   bits<3> idx;
7998   let Inst{30} = idx{2};
7999   let Inst{23} = 0;
8000   let Inst{20-16} = 0b00000;
8001   let Inst{12} = idx{1};
8002   let Inst{11} = idx{0};
8003   let Inst{10} = size;
8004 }
8005
8006 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8007                           dag oops, dag iops>
8008   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
8009                        "$vaddr = $wback", oops, iops, []> {
8010   // idx encoded in Q:S:size<1> fields.
8011   bits<3> idx;
8012   bits<5> Xm;
8013   let Inst{30} = idx{2};
8014   let Inst{23} = 1;
8015   let Inst{20-16} = Xm;
8016   let Inst{12} = idx{1};
8017   let Inst{11} = idx{0};
8018   let Inst{10} = size;
8019 }
8020 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8021                           dag oops, dag iops>
8022   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
8023                            "$vaddr = $wback", oops, iops, []> {
8024   // idx encoded in Q:S:size<1> fields.
8025   bits<3> idx;
8026   bits<5> Xm;
8027   let Inst{30} = idx{2};
8028   let Inst{23} = 1;
8029   let Inst{20-16} = Xm;
8030   let Inst{12} = idx{1};
8031   let Inst{11} = idx{0};
8032   let Inst{10} = size;
8033 }
8034 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8035                       dag oops, dag iops, list<dag> pattern>
8036   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr", "", oops, iops,
8037                        pattern> {
8038   // idx encoded in Q:S fields.
8039   bits<2> idx;
8040   let Inst{30} = idx{1};
8041   let Inst{23} = 0;
8042   let Inst{20-16} = 0b00000;
8043   let Inst{12} = idx{0};
8044   let Inst{11-10} = size;
8045 }
8046 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8047                       dag oops, dag iops, list<dag> pattern>
8048   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr", "",
8049                            oops, iops, pattern> {
8050   // idx encoded in Q:S fields.
8051   bits<2> idx;
8052   let Inst{30} = idx{1};
8053   let Inst{23} = 0;
8054   let Inst{20-16} = 0b00000;
8055   let Inst{12} = idx{0};
8056   let Inst{11-10} = size;
8057 }
8058 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
8059                           string asm, dag oops, dag iops>
8060   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
8061                        "$vaddr = $wback", oops, iops, []> {
8062   // idx encoded in Q:S fields.
8063   bits<2> idx;
8064   bits<5> Xm;
8065   let Inst{30} = idx{1};
8066   let Inst{23} = 1;
8067   let Inst{20-16} = Xm;
8068   let Inst{12} = idx{0};
8069   let Inst{11-10} = size;
8070 }
8071 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8072                           string asm, dag oops, dag iops>
8073   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
8074                            "$vaddr = $wback", oops, iops, []> {
8075   // idx encoded in Q:S fields.
8076   bits<2> idx;
8077   bits<5> Xm;
8078   let Inst{30} = idx{1};
8079   let Inst{23} = 1;
8080   let Inst{20-16} = Xm;
8081   let Inst{12} = idx{0};
8082   let Inst{11-10} = size;
8083 }
8084 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8085                       dag oops, dag iops, list<dag> pattern>
8086   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr", "", oops, iops,
8087                        pattern> {
8088   // idx encoded in Q field.
8089   bits<1> idx;
8090   let Inst{30} = idx;
8091   let Inst{23} = 0;
8092   let Inst{20-16} = 0b00000;
8093   let Inst{12} = 0;
8094   let Inst{11-10} = size;
8095 }
8096 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8097                       dag oops, dag iops, list<dag> pattern>
8098   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr", "",
8099                            oops, iops, pattern> {
8100   // idx encoded in Q field.
8101   bits<1> idx;
8102   let Inst{30} = idx;
8103   let Inst{23} = 0;
8104   let Inst{20-16} = 0b00000;
8105   let Inst{12} = 0;
8106   let Inst{11-10} = size;
8107 }
8108 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
8109                           string asm, dag oops, dag iops>
8110   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
8111                        "$vaddr = $wback", oops, iops, []> {
8112   // idx encoded in Q field.
8113   bits<1> idx;
8114   bits<5> Xm;
8115   let Inst{30} = idx;
8116   let Inst{23} = 1;
8117   let Inst{20-16} = Xm;
8118   let Inst{12} = 0;
8119   let Inst{11-10} = size;
8120 }
8121 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8122                           string asm, dag oops, dag iops>
8123   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, $vaddr, $Xm",
8124                            "$vaddr = $wback", oops, iops, []> {
8125   // idx encoded in Q field.
8126   bits<1> idx;
8127   bits<5> Xm;
8128   let Inst{30} = idx;
8129   let Inst{23} = 1;
8130   let Inst{20-16} = Xm;
8131   let Inst{12} = 0;
8132   let Inst{11-10} = size;
8133 }
8134
8135 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8136 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
8137                          RegisterOperand listtype,
8138                          RegisterOperand GPR64pi> {
8139   def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
8140                            (outs listtype:$dst),
8141                            (ins listtype:$Vt, VectorIndexB:$idx,
8142                                 am_simdnoindex:$vaddr), []>;
8143
8144   def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
8145                             (outs am_simdnoindex:$wback, listtype:$dst),
8146                             (ins listtype:$Vt, VectorIndexB:$idx,
8147                                  am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8148 }
8149 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8150 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
8151                          RegisterOperand listtype,
8152                          RegisterOperand GPR64pi> {
8153   def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
8154                             (outs listtype:$dst),
8155                             (ins listtype:$Vt, VectorIndexH:$idx,
8156                                  am_simdnoindex:$vaddr), []>;
8157
8158   def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
8159                             (outs am_simdnoindex:$wback, listtype:$dst),
8160                             (ins listtype:$Vt, VectorIndexH:$idx,
8161                                  am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8162 }
8163 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8164 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
8165                          RegisterOperand listtype,
8166                          RegisterOperand GPR64pi> {
8167   def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
8168                             (outs listtype:$dst),
8169                             (ins listtype:$Vt, VectorIndexS:$idx,
8170                                  am_simdnoindex:$vaddr), []>;
8171
8172   def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
8173                             (outs am_simdnoindex:$wback, listtype:$dst),
8174                             (ins listtype:$Vt, VectorIndexS:$idx,
8175                                  am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8176 }
8177 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8178 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
8179                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8180   def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
8181                             (outs listtype:$dst),
8182                             (ins listtype:$Vt, VectorIndexD:$idx,
8183                                  am_simdnoindex:$vaddr), []>;
8184
8185   def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
8186                             (outs am_simdnoindex:$wback, listtype:$dst),
8187                             (ins listtype:$Vt, VectorIndexD:$idx,
8188                                  am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8189 }
8190 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8191 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
8192                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8193   def i8 : SIMDLdStSingleB<0, R, opcode, asm,
8194                            (outs), (ins listtype:$Vt, VectorIndexB:$idx,
8195                                         am_simdnoindex:$vaddr), []>;
8196
8197   def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
8198                                     (outs am_simdnoindex:$wback),
8199                                     (ins listtype:$Vt, VectorIndexB:$idx,
8200                                          am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8201 }
8202 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8203 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
8204                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8205   def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
8206                             (outs), (ins listtype:$Vt, VectorIndexH:$idx,
8207                                          am_simdnoindex:$vaddr), []>;
8208
8209   def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
8210                             (outs am_simdnoindex:$wback),
8211                             (ins listtype:$Vt, VectorIndexH:$idx,
8212                                  am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8213 }
8214 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8215 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
8216                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8217   def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
8218                             (outs), (ins listtype:$Vt, VectorIndexS:$idx,
8219                                          am_simdnoindex:$vaddr), []>;
8220
8221   def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
8222                             (outs am_simdnoindex:$wback),
8223                             (ins listtype:$Vt, VectorIndexS:$idx,
8224                                  am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8225 }
8226 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8227 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
8228                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8229   def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
8230                             (outs), (ins listtype:$Vt, VectorIndexD:$idx,
8231                                          am_simdnoindex:$vaddr), []>;
8232
8233   def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
8234                             (outs am_simdnoindex:$wback),
8235                             (ins listtype:$Vt, VectorIndexD:$idx,
8236                                  am_simdnoindex:$vaddr, GPR64pi:$Xm)>;
8237 }
8238
8239 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
8240                                  string Count, int Offset, Operand idxtype> {
8241   // E.g. "ld1 { v0.8b }[0], [x1], #1"
8242   //      "ld1\t$Vt, $vaddr, #1"
8243   // may get mapped to
8244   //      (LD1Rv8b_POST VecListOne8b:$Vt, am_simdnoindex:$vaddr, XZR)
8245   def : InstAlias<asm # "\t$Vt$idx, $vaddr, #" # Offset,
8246                   (!cast<Instruction>(NAME # Type  # "_POST")
8247                       am_simdnoindex:$vaddr,
8248                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8249                       idxtype:$idx, XZR), 1>;
8250
8251   // E.g. "ld1.8b { v0 }[0], [x1], #1"
8252   //      "ld1.8b\t$Vt, $vaddr, #1"
8253   // may get mapped to
8254   //      (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, XZR)
8255   def : InstAlias<asm # "." # layout # "\t$Vt$idx, $vaddr, #" # Offset,
8256                   (!cast<Instruction>(NAME # Type # "_POST")
8257                       am_simdnoindex:$vaddr,
8258                       !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8259                       idxtype:$idx, XZR), 0>;
8260
8261   // E.g. "ld1.8b { v0 }[0], [x1]"
8262   //      "ld1.8b\t$Vt, $vaddr"
8263   // may get mapped to
8264   //      (LD1Rv8b VecListOne64:$Vt, am_simdnoindex:$vaddr)
8265   def : InstAlias<asm # "." # layout # "\t$Vt$idx, $vaddr",
8266                       (!cast<Instruction>(NAME # Type)
8267                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8268                          idxtype:$idx, am_simdnoindex:$vaddr), 0>;
8269
8270   // E.g. "ld1.8b { v0 }[0], [x1], x2"
8271   //      "ld1.8b\t$Vt, $vaddr, $Xm"
8272   // may get mapped to
8273   //      (LD1Rv8b_POST VecListOne64:$Vt, am_simdnoindex:$vaddr, GPR64pi1:$Xm)
8274   def : InstAlias<asm # "." # layout # "\t$Vt$idx, $vaddr, $Xm",
8275                       (!cast<Instruction>(NAME # Type # "_POST")
8276                          am_simdnoindex:$vaddr,
8277                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8278                          idxtype:$idx,
8279                          !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8280 }
8281
8282 multiclass SIMDLdSt1SingleAliases<string asm> {
8283   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "One", 1, VectorIndexB>;
8284   defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
8285   defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
8286   defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
8287 }
8288
8289 multiclass SIMDLdSt2SingleAliases<string asm> {
8290   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Two", 2,  VectorIndexB>;
8291   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4,  VectorIndexH>;
8292   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8,  VectorIndexS>;
8293   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
8294 }
8295
8296 multiclass SIMDLdSt3SingleAliases<string asm> {
8297   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Three", 3,  VectorIndexB>;
8298   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6,  VectorIndexH>;
8299   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
8300   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
8301 }
8302
8303 multiclass SIMDLdSt4SingleAliases<string asm> {
8304   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Four", 4,  VectorIndexB>;
8305   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8,  VectorIndexH>;
8306   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
8307   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
8308 }
8309 } // end of 'let Predicates = [HasNEON]'
8310
8311 //----------------------------------------------------------------------------
8312 // Crypto extensions
8313 //----------------------------------------------------------------------------
8314
8315 let Predicates = [HasCrypto] in {
8316 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8317 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
8318               list<dag> pat>
8319   : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
8320     Sched<[WriteV]>{
8321   bits<5> Rd;
8322   bits<5> Rn;
8323   let Inst{31-16} = 0b0100111000101000;
8324   let Inst{15-12} = opc;
8325   let Inst{11-10} = 0b10;
8326   let Inst{9-5}   = Rn;
8327   let Inst{4-0}   = Rd;
8328 }
8329
8330 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
8331   : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
8332             [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
8333
8334 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
8335   : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
8336             "$Rd = $dst",
8337             [(set (v16i8 V128:$dst),
8338                   (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
8339
8340 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8341 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
8342                      dag oops, dag iops, list<dag> pat>
8343   : I<oops, iops, asm,
8344       "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
8345       "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
8346     Sched<[WriteV]>{
8347   bits<5> Rd;
8348   bits<5> Rn;
8349   bits<5> Rm;
8350   let Inst{31-21} = 0b01011110000;
8351   let Inst{20-16} = Rm;
8352   let Inst{15}    = 0;
8353   let Inst{14-12} = opc;
8354   let Inst{11-10} = 0b00;
8355   let Inst{9-5}   = Rn;
8356   let Inst{4-0}   = Rd;
8357 }
8358
8359 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
8360   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8361                    (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
8362                    [(set (v4i32 FPR128:$dst),
8363                          (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
8364                                  (v4i32 V128:$Rm)))]>;
8365
8366 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
8367   : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
8368                    (ins V128:$Rd, V128:$Rn, V128:$Rm),
8369                    [(set (v4i32 V128:$dst),
8370                          (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8371                                  (v4i32 V128:$Rm)))]>;
8372
8373 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
8374   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8375                    (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
8376                    [(set (v4i32 FPR128:$dst),
8377                          (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
8378                                  (v4i32 V128:$Rm)))]>;
8379
8380 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8381 class SHA2OpInst<bits<4> opc, string asm, string kind,
8382                  string cstr, dag oops, dag iops,
8383                  list<dag> pat>
8384   : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
8385                        "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
8386     Sched<[WriteV]>{
8387   bits<5> Rd;
8388   bits<5> Rn;
8389   let Inst{31-16} = 0b0101111000101000;
8390   let Inst{15-12} = opc;
8391   let Inst{11-10} = 0b10;
8392   let Inst{9-5}   = Rn;
8393   let Inst{4-0}   = Rd;
8394 }
8395
8396 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
8397   : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
8398                (ins V128:$Rd, V128:$Rn),
8399                [(set (v4i32 V128:$dst),
8400                      (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
8401
8402 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
8403   : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
8404                [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
8405 } // end of 'let Predicates = [HasCrypto]'
8406
8407 // Allow the size specifier tokens to be upper case, not just lower.
8408 def : TokenAlias<".8B", ".8b">;
8409 def : TokenAlias<".4H", ".4h">;
8410 def : TokenAlias<".2S", ".2s">;
8411 def : TokenAlias<".1D", ".1d">;
8412 def : TokenAlias<".16B", ".16b">;
8413 def : TokenAlias<".8H", ".8h">;
8414 def : TokenAlias<".4S", ".4s">;
8415 def : TokenAlias<".2D", ".2d">;
8416 def : TokenAlias<".1Q", ".1q">;
8417 def : TokenAlias<".B", ".b">;
8418 def : TokenAlias<".H", ".h">;
8419 def : TokenAlias<".S", ".s">;
8420 def : TokenAlias<".D", ".d">;
8421 def : TokenAlias<".Q", ".q">;