[AArch64] Add v8.1a "Limited Ordering Regions" extension
[oota-llvm.git] / lib / Target / AArch64 / AArch64InstrFormats.td
1 //===- AArch64InstrFormats.td - AArch64 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 AArch64 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 // AArch64 Instruction Format
25 class AArch64Inst<Format f, string cstr> : Instruction {
26   field bits<32> Inst; // Instruction encoding.
27   // Mask of bits that cause an encoding to be UNPREDICTABLE.
28   // If a bit is set, then if the corresponding bit in the
29   // target encoding differs from its value in the "Inst" field,
30   // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).
31   field bits<32> Unpredictable = 0;
32   // SoftFail is the generic name for this field, but we alias it so
33   // as to make it more obvious what it means in ARM-land.
34   field bits<32> SoftFail = Unpredictable;
35   let Namespace   = "AArch64";
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     : AArch64Inst<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> : AArch64Inst<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   let RenderMethod = "addShifterOperands";
94   let DiagnosticType = "InvalidMovImm32Shift";
95 }
96 def MovImm64ShifterOperand : AsmOperandClass {
97   let SuperClasses = [ShifterOperand];
98   let Name = "MovImm64Shifter";
99   let RenderMethod = "addShifterOperands";
100   let DiagnosticType = "InvalidMovImm64Shift";
101 }
102
103 // Shifter operand for arithmetic register shifted encodings.
104 class ArithmeticShifterOperand<int width> : AsmOperandClass {
105   let SuperClasses = [ShifterOperand];
106   let Name = "ArithmeticShifter" # width;
107   let PredicateMethod = "isArithmeticShifter<" # width # ">";
108   let RenderMethod = "addShifterOperands";
109   let DiagnosticType = "AddSubRegShift" # width;
110 }
111
112 def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;
113 def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;
114
115 // Shifter operand for logical register shifted encodings.
116 class LogicalShifterOperand<int width> : AsmOperandClass {
117   let SuperClasses = [ShifterOperand];
118   let Name = "LogicalShifter" # width;
119   let PredicateMethod = "isLogicalShifter<" # width # ">";
120   let RenderMethod = "addShifterOperands";
121   let DiagnosticType = "AddSubRegShift" # width;
122 }
123
124 def LogicalShifterOperand32 : LogicalShifterOperand<32>;
125 def LogicalShifterOperand64 : LogicalShifterOperand<64>;
126
127 // Shifter operand for logical vector 128/64-bit shifted encodings.
128 def LogicalVecShifterOperand : AsmOperandClass {
129   let SuperClasses = [ShifterOperand];
130   let Name = "LogicalVecShifter";
131   let RenderMethod = "addShifterOperands";
132 }
133 def LogicalVecHalfWordShifterOperand : AsmOperandClass {
134   let SuperClasses = [LogicalVecShifterOperand];
135   let Name = "LogicalVecHalfWordShifter";
136   let RenderMethod = "addShifterOperands";
137 }
138
139 // The "MSL" shifter on the vector MOVI instruction.
140 def MoveVecShifterOperand : AsmOperandClass {
141   let SuperClasses = [ShifterOperand];
142   let Name = "MoveVecShifter";
143   let RenderMethod = "addShifterOperands";
144 }
145
146 // Extend operand for arithmetic encodings.
147 def ExtendOperand : AsmOperandClass {
148   let Name = "Extend";
149   let DiagnosticType = "AddSubRegExtendLarge";
150 }
151 def ExtendOperand64 : AsmOperandClass {
152   let SuperClasses = [ExtendOperand];
153   let Name = "Extend64";
154   let DiagnosticType = "AddSubRegExtendSmall";
155 }
156 // 'extend' that's a lsl of a 64-bit register.
157 def ExtendOperandLSL64 : AsmOperandClass {
158   let SuperClasses = [ExtendOperand];
159   let Name = "ExtendLSL64";
160   let RenderMethod = "addExtend64Operands";
161   let DiagnosticType = "AddSubRegExtendLarge";
162 }
163
164 // 8-bit floating-point immediate encodings.
165 def FPImmOperand : AsmOperandClass {
166   let Name = "FPImm";
167   let ParserMethod = "tryParseFPImm";
168   let DiagnosticType = "InvalidFPImm";
169 }
170
171 def CondCode : AsmOperandClass {
172   let Name = "CondCode";
173   let DiagnosticType = "InvalidCondCode";
174 }
175
176 // A 32-bit register pasrsed as 64-bit
177 def GPR32as64Operand : AsmOperandClass {
178   let Name = "GPR32as64";
179 }
180 def GPR32as64 : RegisterOperand<GPR32> {
181   let ParserMatchClass = GPR32as64Operand;
182 }
183
184 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
185 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
186 // are encoded as the eight bit value 'abcdefgh'.
187 def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }
188
189
190 //===----------------------------------------------------------------------===//
191 // Operand Definitions.
192 //
193
194 // ADR[P] instruction labels.
195 def AdrpOperand : AsmOperandClass {
196   let Name = "AdrpLabel";
197   let ParserMethod = "tryParseAdrpLabel";
198   let DiagnosticType = "InvalidLabel";
199 }
200 def adrplabel : Operand<i64> {
201   let EncoderMethod = "getAdrLabelOpValue";
202   let PrintMethod = "printAdrpLabel";
203   let ParserMatchClass = AdrpOperand;
204 }
205
206 def AdrOperand : AsmOperandClass {
207   let Name = "AdrLabel";
208   let ParserMethod = "tryParseAdrLabel";
209   let DiagnosticType = "InvalidLabel";
210 }
211 def adrlabel : Operand<i64> {
212   let EncoderMethod = "getAdrLabelOpValue";
213   let ParserMatchClass = AdrOperand;
214 }
215
216 // simm9 predicate - True if the immediate is in the range [-256, 255].
217 def SImm9Operand : AsmOperandClass {
218   let Name = "SImm9";
219   let DiagnosticType = "InvalidMemoryIndexedSImm9";
220 }
221 def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {
222   let ParserMatchClass = SImm9Operand;
223 }
224
225 // simm7sN predicate - True if the immediate is a multiple of N in the range
226 // [-64 * N, 63 * N].
227 class SImm7Scaled<int Scale> : AsmOperandClass {
228   let Name = "SImm7s" # Scale;
229   let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm7";
230 }
231
232 def SImm7s4Operand : SImm7Scaled<4>;
233 def SImm7s8Operand : SImm7Scaled<8>;
234 def SImm7s16Operand : SImm7Scaled<16>;
235
236 def simm7s4 : Operand<i32> {
237   let ParserMatchClass = SImm7s4Operand;
238   let PrintMethod = "printImmScale<4>";
239 }
240
241 def simm7s8 : Operand<i32> {
242   let ParserMatchClass = SImm7s8Operand;
243   let PrintMethod = "printImmScale<8>";
244 }
245
246 def simm7s16 : Operand<i32> {
247   let ParserMatchClass = SImm7s16Operand;
248   let PrintMethod = "printImmScale<16>";
249 }
250
251 class AsmImmRange<int Low, int High> : AsmOperandClass {
252   let Name = "Imm" # Low # "_" # High;
253   let DiagnosticType = "InvalidImm" # Low # "_" # High;
254 }
255
256 def Imm1_8Operand : AsmImmRange<1, 8>;
257 def Imm1_16Operand : AsmImmRange<1, 16>;
258 def Imm1_32Operand : AsmImmRange<1, 32>;
259 def Imm1_64Operand : AsmImmRange<1, 64>;
260
261 def MovZSymbolG3AsmOperand : AsmOperandClass {
262   let Name = "MovZSymbolG3";
263   let RenderMethod = "addImmOperands";
264 }
265
266 def movz_symbol_g3 : Operand<i32> {
267   let ParserMatchClass = MovZSymbolG3AsmOperand;
268 }
269
270 def MovZSymbolG2AsmOperand : AsmOperandClass {
271   let Name = "MovZSymbolG2";
272   let RenderMethod = "addImmOperands";
273 }
274
275 def movz_symbol_g2 : Operand<i32> {
276   let ParserMatchClass = MovZSymbolG2AsmOperand;
277 }
278
279 def MovZSymbolG1AsmOperand : AsmOperandClass {
280   let Name = "MovZSymbolG1";
281   let RenderMethod = "addImmOperands";
282 }
283
284 def movz_symbol_g1 : Operand<i32> {
285   let ParserMatchClass = MovZSymbolG1AsmOperand;
286 }
287
288 def MovZSymbolG0AsmOperand : AsmOperandClass {
289   let Name = "MovZSymbolG0";
290   let RenderMethod = "addImmOperands";
291 }
292
293 def movz_symbol_g0 : Operand<i32> {
294   let ParserMatchClass = MovZSymbolG0AsmOperand;
295 }
296
297 def MovKSymbolG3AsmOperand : AsmOperandClass {
298   let Name = "MovKSymbolG3";
299   let RenderMethod = "addImmOperands";
300 }
301
302 def movk_symbol_g3 : Operand<i32> {
303   let ParserMatchClass = MovKSymbolG3AsmOperand;
304 }
305
306 def MovKSymbolG2AsmOperand : AsmOperandClass {
307   let Name = "MovKSymbolG2";
308   let RenderMethod = "addImmOperands";
309 }
310
311 def movk_symbol_g2 : Operand<i32> {
312   let ParserMatchClass = MovKSymbolG2AsmOperand;
313 }
314
315 def MovKSymbolG1AsmOperand : AsmOperandClass {
316   let Name = "MovKSymbolG1";
317   let RenderMethod = "addImmOperands";
318 }
319
320 def movk_symbol_g1 : Operand<i32> {
321   let ParserMatchClass = MovKSymbolG1AsmOperand;
322 }
323
324 def MovKSymbolG0AsmOperand : AsmOperandClass {
325   let Name = "MovKSymbolG0";
326   let RenderMethod = "addImmOperands";
327 }
328
329 def movk_symbol_g0 : Operand<i32> {
330   let ParserMatchClass = MovKSymbolG0AsmOperand;
331 }
332
333 class fixedpoint_i32<ValueType FloatVT>
334   : Operand<FloatVT>,
335     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
336   let EncoderMethod = "getFixedPointScaleOpValue";
337   let DecoderMethod = "DecodeFixedPointScaleImm32";
338   let ParserMatchClass = Imm1_32Operand;
339 }
340
341 class fixedpoint_i64<ValueType FloatVT>
342   : Operand<FloatVT>,
343     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
344   let EncoderMethod = "getFixedPointScaleOpValue";
345   let DecoderMethod = "DecodeFixedPointScaleImm64";
346   let ParserMatchClass = Imm1_64Operand;
347 }
348
349 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
350 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
351
352 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
353 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
354
355 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
356   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
357 }]> {
358   let EncoderMethod = "getVecShiftR8OpValue";
359   let DecoderMethod = "DecodeVecShiftR8Imm";
360   let ParserMatchClass = Imm1_8Operand;
361 }
362 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
363   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
364 }]> {
365   let EncoderMethod = "getVecShiftR16OpValue";
366   let DecoderMethod = "DecodeVecShiftR16Imm";
367   let ParserMatchClass = Imm1_16Operand;
368 }
369 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
370   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
371 }]> {
372   let EncoderMethod = "getVecShiftR16OpValue";
373   let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
374   let ParserMatchClass = Imm1_8Operand;
375 }
376 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
377   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
378 }]> {
379   let EncoderMethod = "getVecShiftR32OpValue";
380   let DecoderMethod = "DecodeVecShiftR32Imm";
381   let ParserMatchClass = Imm1_32Operand;
382 }
383 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
384   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
385 }]> {
386   let EncoderMethod = "getVecShiftR32OpValue";
387   let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
388   let ParserMatchClass = Imm1_16Operand;
389 }
390 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
391   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
392 }]> {
393   let EncoderMethod = "getVecShiftR64OpValue";
394   let DecoderMethod = "DecodeVecShiftR64Imm";
395   let ParserMatchClass = Imm1_64Operand;
396 }
397 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
398   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
399 }]> {
400   let EncoderMethod = "getVecShiftR64OpValue";
401   let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
402   let ParserMatchClass = Imm1_32Operand;
403 }
404
405 def Imm0_7Operand : AsmImmRange<0, 7>;
406 def Imm0_15Operand : AsmImmRange<0, 15>;
407 def Imm0_31Operand : AsmImmRange<0, 31>;
408 def Imm0_63Operand : AsmImmRange<0, 63>;
409
410 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
411   return (((uint32_t)Imm) < 8);
412 }]> {
413   let EncoderMethod = "getVecShiftL8OpValue";
414   let DecoderMethod = "DecodeVecShiftL8Imm";
415   let ParserMatchClass = Imm0_7Operand;
416 }
417 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
418   return (((uint32_t)Imm) < 16);
419 }]> {
420   let EncoderMethod = "getVecShiftL16OpValue";
421   let DecoderMethod = "DecodeVecShiftL16Imm";
422   let ParserMatchClass = Imm0_15Operand;
423 }
424 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
425   return (((uint32_t)Imm) < 32);
426 }]> {
427   let EncoderMethod = "getVecShiftL32OpValue";
428   let DecoderMethod = "DecodeVecShiftL32Imm";
429   let ParserMatchClass = Imm0_31Operand;
430 }
431 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
432   return (((uint32_t)Imm) < 64);
433 }]> {
434   let EncoderMethod = "getVecShiftL64OpValue";
435   let DecoderMethod = "DecodeVecShiftL64Imm";
436   let ParserMatchClass = Imm0_63Operand;
437 }
438
439
440 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
441 // instructions for splatting repeating bit patterns across the immediate.
442 def logical_imm32_XFORM : SDNodeXForm<imm, [{
443   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
444   return CurDAG->getTargetConstant(enc, MVT::i32);
445 }]>;
446 def logical_imm64_XFORM : SDNodeXForm<imm, [{
447   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
448   return CurDAG->getTargetConstant(enc, MVT::i32);
449 }]>;
450
451 let DiagnosticType = "LogicalSecondSource" in {
452   def LogicalImm32Operand : AsmOperandClass {
453     let Name = "LogicalImm32";
454   }
455   def LogicalImm64Operand : AsmOperandClass {
456     let Name = "LogicalImm64";
457   }
458   def LogicalImm32NotOperand : AsmOperandClass {
459     let Name = "LogicalImm32Not";
460   }
461   def LogicalImm64NotOperand : AsmOperandClass {
462     let Name = "LogicalImm64Not";
463   }
464 }
465 def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{
466   return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 32);
467 }], logical_imm32_XFORM> {
468   let PrintMethod = "printLogicalImm32";
469   let ParserMatchClass = LogicalImm32Operand;
470 }
471 def logical_imm64 : Operand<i64>, PatLeaf<(imm), [{
472   return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 64);
473 }], logical_imm64_XFORM> {
474   let PrintMethod = "printLogicalImm64";
475   let ParserMatchClass = LogicalImm64Operand;
476 }
477 def logical_imm32_not : Operand<i32> {
478   let ParserMatchClass = LogicalImm32NotOperand;
479 }
480 def logical_imm64_not : Operand<i64> {
481   let ParserMatchClass = LogicalImm64NotOperand;
482 }
483
484 // imm0_65535 predicate - True if the immediate is in the range [0,65535].
485 def Imm0_65535Operand : AsmImmRange<0, 65535>;
486 def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
487   return ((uint32_t)Imm) < 65536;
488 }]> {
489   let ParserMatchClass = Imm0_65535Operand;
490   let PrintMethod = "printHexImm";
491 }
492
493 // imm0_255 predicate - True if the immediate is in the range [0,255].
494 def Imm0_255Operand : AsmOperandClass { let Name = "Imm0_255"; }
495 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
496   return ((uint32_t)Imm) < 256;
497 }]> {
498   let ParserMatchClass = Imm0_255Operand;
499   let PrintMethod = "printHexImm";
500 }
501
502 // imm0_127 predicate - True if the immediate is in the range [0,127]
503 def Imm0_127Operand : AsmImmRange<0, 127>;
504 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
505   return ((uint32_t)Imm) < 128;
506 }]> {
507   let ParserMatchClass = Imm0_127Operand;
508   let PrintMethod = "printHexImm";
509 }
510
511 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
512 // for all shift-amounts.
513
514 // imm0_63 predicate - True if the immediate is in the range [0,63]
515 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
516   return ((uint64_t)Imm) < 64;
517 }]> {
518   let ParserMatchClass = Imm0_63Operand;
519 }
520
521 // imm0_31 predicate - True if the immediate is in the range [0,31]
522 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
523   return ((uint64_t)Imm) < 32;
524 }]> {
525   let ParserMatchClass = Imm0_31Operand;
526 }
527
528 // imm0_15 predicate - True if the immediate is in the range [0,15]
529 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
530   return ((uint64_t)Imm) < 16;
531 }]> {
532   let ParserMatchClass = Imm0_15Operand;
533 }
534
535 // imm0_7 predicate - True if the immediate is in the range [0,7]
536 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
537   return ((uint64_t)Imm) < 8;
538 }]> {
539   let ParserMatchClass = Imm0_7Operand;
540 }
541
542 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
543 def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
544   return ((uint32_t)Imm) < 16;
545 }]>;
546
547 // An arithmetic shifter operand:
548 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
549 //  {5-0} - imm6
550 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
551   let PrintMethod = "printShifter";
552   let ParserMatchClass = !cast<AsmOperandClass>(
553                          "ArithmeticShifterOperand" # width);
554 }
555
556 def arith_shift32 : arith_shift<i32, 32>;
557 def arith_shift64 : arith_shift<i64, 64>;
558
559 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
560     : Operand<Ty>,
561       ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
562   let PrintMethod = "printShiftedRegister";
563   let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
564 }
565
566 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
567 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
568
569 // An arithmetic shifter operand:
570 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
571 //  {5-0} - imm6
572 class logical_shift<int width> : Operand<i32> {
573   let PrintMethod = "printShifter";
574   let ParserMatchClass = !cast<AsmOperandClass>(
575                          "LogicalShifterOperand" # width);
576 }
577
578 def logical_shift32 : logical_shift<32>;
579 def logical_shift64 : logical_shift<64>;
580
581 class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
582     : Operand<Ty>,
583       ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
584   let PrintMethod = "printShiftedRegister";
585   let MIOperandInfo = (ops regclass, shiftop);
586 }
587
588 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
589 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
590
591 // A logical vector shifter operand:
592 //  {7-6} - shift type: 00 = lsl
593 //  {5-0} - imm6: #0, #8, #16, or #24
594 def logical_vec_shift : Operand<i32> {
595   let PrintMethod = "printShifter";
596   let EncoderMethod = "getVecShifterOpValue";
597   let ParserMatchClass = LogicalVecShifterOperand;
598 }
599
600 // A logical vector half-word shifter operand:
601 //  {7-6} - shift type: 00 = lsl
602 //  {5-0} - imm6: #0 or #8
603 def logical_vec_hw_shift : Operand<i32> {
604   let PrintMethod = "printShifter";
605   let EncoderMethod = "getVecShifterOpValue";
606   let ParserMatchClass = LogicalVecHalfWordShifterOperand;
607 }
608
609 // A vector move shifter operand:
610 //  {0} - imm1: #8 or #16
611 def move_vec_shift : Operand<i32> {
612   let PrintMethod = "printShifter";
613   let EncoderMethod = "getMoveVecShifterOpValue";
614   let ParserMatchClass = MoveVecShifterOperand;
615 }
616
617 def AddSubImmOperand : AsmOperandClass {
618   let Name = "AddSubImm";
619   let ParserMethod = "tryParseAddSubImm";
620   let DiagnosticType = "AddSubSecondSource";
621 }
622 // An ADD/SUB immediate shifter operand:
623 //  second operand:
624 //  {7-6} - shift type: 00 = lsl
625 //  {5-0} - imm6: #0 or #12
626 class addsub_shifted_imm<ValueType Ty>
627     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
628   let PrintMethod = "printAddSubImm";
629   let EncoderMethod = "getAddSubImmOpValue";
630   let ParserMatchClass = AddSubImmOperand;
631   let MIOperandInfo = (ops i32imm, i32imm);
632 }
633
634 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
635 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
636
637 class neg_addsub_shifted_imm<ValueType Ty>
638     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
639   let PrintMethod = "printAddSubImm";
640   let EncoderMethod = "getAddSubImmOpValue";
641   let ParserMatchClass = AddSubImmOperand;
642   let MIOperandInfo = (ops i32imm, i32imm);
643 }
644
645 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
646 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
647
648 // An extend operand:
649 //  {5-3} - extend type
650 //  {2-0} - imm3
651 def arith_extend : Operand<i32> {
652   let PrintMethod = "printArithExtend";
653   let ParserMatchClass = ExtendOperand;
654 }
655 def arith_extend64 : Operand<i32> {
656   let PrintMethod = "printArithExtend";
657   let ParserMatchClass = ExtendOperand64;
658 }
659
660 // 'extend' that's a lsl of a 64-bit register.
661 def arith_extendlsl64 : Operand<i32> {
662   let PrintMethod = "printArithExtend";
663   let ParserMatchClass = ExtendOperandLSL64;
664 }
665
666 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
667                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
668   let PrintMethod = "printExtendedRegister";
669   let MIOperandInfo = (ops GPR32, arith_extend);
670 }
671
672 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
673                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
674   let PrintMethod = "printExtendedRegister";
675   let MIOperandInfo = (ops GPR32, arith_extend64);
676 }
677
678 // Floating-point immediate.
679 def fpimm32 : Operand<f32>,
680               PatLeaf<(f32 fpimm), [{
681       return AArch64_AM::getFP32Imm(N->getValueAPF()) != -1;
682     }], SDNodeXForm<fpimm, [{
683       APFloat InVal = N->getValueAPF();
684       uint32_t enc = AArch64_AM::getFP32Imm(InVal);
685       return CurDAG->getTargetConstant(enc, MVT::i32);
686     }]>> {
687   let ParserMatchClass = FPImmOperand;
688   let PrintMethod = "printFPImmOperand";
689 }
690 def fpimm64 : Operand<f64>,
691               PatLeaf<(f64 fpimm), [{
692       return AArch64_AM::getFP64Imm(N->getValueAPF()) != -1;
693     }], SDNodeXForm<fpimm, [{
694       APFloat InVal = N->getValueAPF();
695       uint32_t enc = AArch64_AM::getFP64Imm(InVal);
696       return CurDAG->getTargetConstant(enc, MVT::i32);
697     }]>> {
698   let ParserMatchClass = FPImmOperand;
699   let PrintMethod = "printFPImmOperand";
700 }
701
702 def fpimm8 : Operand<i32> {
703   let ParserMatchClass = FPImmOperand;
704   let PrintMethod = "printFPImmOperand";
705 }
706
707 def fpimm0 : PatLeaf<(fpimm), [{
708   return N->isExactlyValue(+0.0);
709 }]>;
710
711 // Vector lane operands
712 class AsmVectorIndex<string Suffix> : AsmOperandClass {
713   let Name = "VectorIndex" # Suffix;
714   let DiagnosticType = "InvalidIndex" # Suffix;
715 }
716 def VectorIndex1Operand : AsmVectorIndex<"1">;
717 def VectorIndexBOperand : AsmVectorIndex<"B">;
718 def VectorIndexHOperand : AsmVectorIndex<"H">;
719 def VectorIndexSOperand : AsmVectorIndex<"S">;
720 def VectorIndexDOperand : AsmVectorIndex<"D">;
721
722 def VectorIndex1 : Operand<i64>, ImmLeaf<i64, [{
723   return ((uint64_t)Imm) == 1;
724 }]> {
725   let ParserMatchClass = VectorIndex1Operand;
726   let PrintMethod = "printVectorIndex";
727   let MIOperandInfo = (ops i64imm);
728 }
729 def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
730   return ((uint64_t)Imm) < 16;
731 }]> {
732   let ParserMatchClass = VectorIndexBOperand;
733   let PrintMethod = "printVectorIndex";
734   let MIOperandInfo = (ops i64imm);
735 }
736 def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
737   return ((uint64_t)Imm) < 8;
738 }]> {
739   let ParserMatchClass = VectorIndexHOperand;
740   let PrintMethod = "printVectorIndex";
741   let MIOperandInfo = (ops i64imm);
742 }
743 def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
744   return ((uint64_t)Imm) < 4;
745 }]> {
746   let ParserMatchClass = VectorIndexSOperand;
747   let PrintMethod = "printVectorIndex";
748   let MIOperandInfo = (ops i64imm);
749 }
750 def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
751   return ((uint64_t)Imm) < 2;
752 }]> {
753   let ParserMatchClass = VectorIndexDOperand;
754   let PrintMethod = "printVectorIndex";
755   let MIOperandInfo = (ops i64imm);
756 }
757
758 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
759 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
760 // are encoded as the eight bit value 'abcdefgh'.
761 def simdimmtype10 : Operand<i32>,
762                     PatLeaf<(f64 fpimm), [{
763       return AArch64_AM::isAdvSIMDModImmType10(N->getValueAPF()
764                                                .bitcastToAPInt()
765                                                .getZExtValue());
766     }], SDNodeXForm<fpimm, [{
767       APFloat InVal = N->getValueAPF();
768       uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
769                                                            .bitcastToAPInt()
770                                                            .getZExtValue());
771       return CurDAG->getTargetConstant(enc, MVT::i32);
772     }]>> {
773   let ParserMatchClass = SIMDImmType10Operand;
774   let PrintMethod = "printSIMDType10Operand";
775 }
776
777
778 //---
779 // System management
780 //---
781
782 // Base encoding for system instruction operands.
783 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
784 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
785                   list<dag> pattern = []>
786     : I<oops, iops, asm, operands, "", pattern> {
787   let Inst{31-22} = 0b1101010100;
788   let Inst{21}    = L;
789 }
790
791 // System instructions which do not have an Rt register.
792 class SimpleSystemI<bit L, dag iops, string asm, string operands,
793                     list<dag> pattern = []>
794     : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
795   let Inst{4-0} = 0b11111;
796 }
797
798 // System instructions which have an Rt register.
799 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
800     : BaseSystemI<L, oops, iops, asm, operands>,
801       Sched<[WriteSys]> {
802   bits<5> Rt;
803   let Inst{4-0} = Rt;
804 }
805
806 // Hint instructions that take both a CRm and a 3-bit immediate.
807 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
808 // model patterns with sufficiently fine granularity
809 let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
810   class HintI<string mnemonic>
811       : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#" $imm", "",
812                       [(int_aarch64_hint imm0_127:$imm)]>,
813         Sched<[WriteHint]> {
814     bits <7> imm;
815     let Inst{20-12} = 0b000110010;
816     let Inst{11-5} = imm;
817   }
818
819 // System instructions taking a single literal operand which encodes into
820 // CRm. op2 differentiates the opcodes.
821 def BarrierAsmOperand : AsmOperandClass {
822   let Name = "Barrier";
823   let ParserMethod = "tryParseBarrierOperand";
824 }
825 def barrier_op : Operand<i32> {
826   let PrintMethod = "printBarrierOption";
827   let ParserMatchClass = BarrierAsmOperand;
828 }
829 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
830                  list<dag> pattern = []>
831     : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
832       Sched<[WriteBarrier]> {
833   bits<4> CRm;
834   let Inst{20-12} = 0b000110011;
835   let Inst{11-8} = CRm;
836   let Inst{7-5} = opc;
837 }
838
839 // MRS/MSR system instructions. These have different operand classes because
840 // a different subset of registers can be accessed through each instruction.
841 def MRSSystemRegisterOperand : AsmOperandClass {
842   let Name = "MRSSystemRegister";
843   let ParserMethod = "tryParseSysReg";
844   let DiagnosticType = "MRS";
845 }
846 // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
847 def mrs_sysreg_op : Operand<i32> {
848   let ParserMatchClass = MRSSystemRegisterOperand;
849   let DecoderMethod = "DecodeMRSSystemRegister";
850   let PrintMethod = "printMRSSystemRegister";
851 }
852
853 def MSRSystemRegisterOperand : AsmOperandClass {
854   let Name = "MSRSystemRegister";
855   let ParserMethod = "tryParseSysReg";
856   let DiagnosticType = "MSR";
857 }
858 def msr_sysreg_op : Operand<i32> {
859   let ParserMatchClass = MSRSystemRegisterOperand;
860   let DecoderMethod = "DecodeMSRSystemRegister";
861   let PrintMethod = "printMSRSystemRegister";
862 }
863
864 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
865                        "mrs", "\t$Rt, $systemreg"> {
866   bits<16> systemreg;
867   let Inst{20-5} = systemreg;
868 }
869
870 // FIXME: Some of these def NZCV, others don't. Best way to model that?
871 // Explicitly modeling each of the system register as a register class
872 // would do it, but feels like overkill at this point.
873 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
874                        "msr", "\t$systemreg, $Rt"> {
875   bits<16> systemreg;
876   let Inst{20-5} = systemreg;
877 }
878
879 def SystemPStateFieldOperand : AsmOperandClass {
880   let Name = "SystemPStateField";
881   let ParserMethod = "tryParseSysReg";
882 }
883 def pstatefield_op : Operand<i32> {
884   let ParserMatchClass = SystemPStateFieldOperand;
885   let PrintMethod = "printSystemPStateField";
886 }
887
888 let Defs = [NZCV] in
889 class MSRpstateI
890   : SimpleSystemI<0, (ins pstatefield_op:$pstate_field, imm0_15:$imm),
891                   "msr", "\t$pstate_field, $imm">,
892     Sched<[WriteSys]> {
893   bits<6> pstatefield;
894   bits<4> imm;
895   let Inst{20-19} = 0b00;
896   let Inst{18-16} = pstatefield{5-3};
897   let Inst{15-12} = 0b0100;
898   let Inst{11-8} = imm;
899   let Inst{7-5} = pstatefield{2-0};
900
901   let DecoderMethod = "DecodeSystemPStateInstruction";
902 }
903
904 // SYS and SYSL generic system instructions.
905 def SysCRAsmOperand : AsmOperandClass {
906   let Name = "SysCR";
907   let ParserMethod = "tryParseSysCROperand";
908 }
909
910 def sys_cr_op : Operand<i32> {
911   let PrintMethod = "printSysCROperand";
912   let ParserMatchClass = SysCRAsmOperand;
913 }
914
915 class SystemXtI<bit L, string asm>
916   : RtSystemI<L, (outs),
917        (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
918        asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
919   bits<3> op1;
920   bits<4> Cn;
921   bits<4> Cm;
922   bits<3> op2;
923   let Inst{20-19} = 0b01;
924   let Inst{18-16} = op1;
925   let Inst{15-12} = Cn;
926   let Inst{11-8}  = Cm;
927   let Inst{7-5}   = op2;
928 }
929
930 class SystemLXtI<bit L, string asm>
931   : RtSystemI<L, (outs),
932        (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
933        asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
934   bits<3> op1;
935   bits<4> Cn;
936   bits<4> Cm;
937   bits<3> op2;
938   let Inst{20-19} = 0b01;
939   let Inst{18-16} = op1;
940   let Inst{15-12} = Cn;
941   let Inst{11-8}  = Cm;
942   let Inst{7-5}   = op2;
943 }
944
945
946 // Branch (register) instructions:
947 //
948 //  case opc of
949 //    0001 blr
950 //    0000 br
951 //    0101 dret
952 //    0100 eret
953 //    0010 ret
954 //    otherwise UNDEFINED
955 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
956                     string operands, list<dag> pattern>
957     : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
958   let Inst{31-25} = 0b1101011;
959   let Inst{24-21} = opc;
960   let Inst{20-16} = 0b11111;
961   let Inst{15-10} = 0b000000;
962   let Inst{4-0}   = 0b00000;
963 }
964
965 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
966     : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
967   bits<5> Rn;
968   let Inst{9-5} = Rn;
969 }
970
971 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
972 class SpecialReturn<bits<4> opc, string asm>
973     : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
974   let Inst{9-5} = 0b11111;
975 }
976
977 //---
978 // Conditional branch instruction.
979 //---
980
981 // Condition code.
982 // 4-bit immediate. Pretty-printed as <cc>
983 def ccode : Operand<i32> {
984   let PrintMethod = "printCondCode";
985   let ParserMatchClass = CondCode;
986 }
987 def inv_ccode : Operand<i32> {
988   // AL and NV are invalid in the aliases which use inv_ccode
989   let PrintMethod = "printInverseCondCode";
990   let ParserMatchClass = CondCode;
991   let MCOperandPredicate = [{
992     return MCOp.isImm() &&
993            MCOp.getImm() != AArch64CC::AL &&
994            MCOp.getImm() != AArch64CC::NV;
995   }];
996 }
997
998 // Conditional branch target. 19-bit immediate. The low two bits of the target
999 // offset are implied zero and so are not part of the immediate.
1000 def PCRelLabel19Operand : AsmOperandClass {
1001   let Name = "PCRelLabel19";
1002   let DiagnosticType = "InvalidLabel";
1003 }
1004 def am_brcond : Operand<OtherVT> {
1005   let EncoderMethod = "getCondBranchTargetOpValue";
1006   let DecoderMethod = "DecodePCRelLabel19";
1007   let PrintMethod = "printAlignedLabel";
1008   let ParserMatchClass = PCRelLabel19Operand;
1009 }
1010
1011 class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1012                      "b", ".$cond\t$target", "",
1013                      [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1014                    Sched<[WriteBr]> {
1015   let isBranch = 1;
1016   let isTerminator = 1;
1017   let Uses = [NZCV];
1018
1019   bits<4> cond;
1020   bits<19> target;
1021   let Inst{31-24} = 0b01010100;
1022   let Inst{23-5} = target;
1023   let Inst{4} = 0;
1024   let Inst{3-0} = cond;
1025 }
1026
1027 //---
1028 // Compare-and-branch instructions.
1029 //---
1030 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1031     : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1032          asm, "\t$Rt, $target", "",
1033          [(node regtype:$Rt, bb:$target)]>,
1034       Sched<[WriteBr]> {
1035   let isBranch = 1;
1036   let isTerminator = 1;
1037
1038   bits<5> Rt;
1039   bits<19> target;
1040   let Inst{30-25} = 0b011010;
1041   let Inst{24}    = op;
1042   let Inst{23-5}  = target;
1043   let Inst{4-0}   = Rt;
1044 }
1045
1046 multiclass CmpBranch<bit op, string asm, SDNode node> {
1047   def W : BaseCmpBranch<GPR32, op, asm, node> {
1048     let Inst{31} = 0;
1049   }
1050   def X : BaseCmpBranch<GPR64, op, asm, node> {
1051     let Inst{31} = 1;
1052   }
1053 }
1054
1055 //---
1056 // Test-bit-and-branch instructions.
1057 //---
1058 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1059 // the target offset are implied zero and so are not part of the immediate.
1060 def BranchTarget14Operand : AsmOperandClass {
1061   let Name = "BranchTarget14";
1062 }
1063 def am_tbrcond : Operand<OtherVT> {
1064   let EncoderMethod = "getTestBranchTargetOpValue";
1065   let PrintMethod = "printAlignedLabel";
1066   let ParserMatchClass = BranchTarget14Operand;
1067 }
1068
1069 // AsmOperand classes to emit (or not) special diagnostics
1070 def TBZImm0_31Operand : AsmOperandClass {
1071   let Name = "TBZImm0_31";
1072   let PredicateMethod = "isImm0_31";
1073   let RenderMethod = "addImm0_31Operands";
1074 }
1075 def TBZImm32_63Operand : AsmOperandClass {
1076   let Name = "Imm32_63";
1077   let DiagnosticType = "InvalidImm0_63";
1078 }
1079
1080 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1081   return (((uint32_t)Imm) < 32);
1082 }]> {
1083   let ParserMatchClass = matcher;
1084 }
1085
1086 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1087 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1088
1089 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1090   return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1091 }]> {
1092   let ParserMatchClass = TBZImm32_63Operand;
1093 }
1094
1095 class BaseTestBranch<RegisterClass regtype, Operand immtype,
1096                      bit op, string asm, SDNode node>
1097     : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1098        asm, "\t$Rt, $bit_off, $target", "",
1099        [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1100       Sched<[WriteBr]> {
1101   let isBranch = 1;
1102   let isTerminator = 1;
1103
1104   bits<5> Rt;
1105   bits<6> bit_off;
1106   bits<14> target;
1107
1108   let Inst{30-25} = 0b011011;
1109   let Inst{24}    = op;
1110   let Inst{23-19} = bit_off{4-0};
1111   let Inst{18-5}  = target;
1112   let Inst{4-0}   = Rt;
1113
1114   let DecoderMethod = "DecodeTestAndBranch";
1115 }
1116
1117 multiclass TestBranch<bit op, string asm, SDNode node> {
1118   def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1119     let Inst{31} = 0;
1120   }
1121
1122   def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1123     let Inst{31} = 1;
1124   }
1125
1126   // Alias X-reg with 0-31 imm to W-Reg.
1127   def : InstAlias<asm # "\t$Rd, $imm, $target",
1128                   (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1129                   tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1130   def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1131             (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1132             tbz_imm0_31_diag:$imm, bb:$target)>;
1133 }
1134
1135 //---
1136 // Unconditional branch (immediate) instructions.
1137 //---
1138 def BranchTarget26Operand : AsmOperandClass {
1139   let Name = "BranchTarget26";
1140   let DiagnosticType = "InvalidLabel";
1141 }
1142 def am_b_target : Operand<OtherVT> {
1143   let EncoderMethod = "getBranchTargetOpValue";
1144   let PrintMethod = "printAlignedLabel";
1145   let ParserMatchClass = BranchTarget26Operand;
1146 }
1147 def am_bl_target : Operand<i64> {
1148   let EncoderMethod = "getBranchTargetOpValue";
1149   let PrintMethod = "printAlignedLabel";
1150   let ParserMatchClass = BranchTarget26Operand;
1151 }
1152
1153 class BImm<bit op, dag iops, string asm, list<dag> pattern>
1154     : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1155   bits<26> addr;
1156   let Inst{31}    = op;
1157   let Inst{30-26} = 0b00101;
1158   let Inst{25-0}  = addr;
1159
1160   let DecoderMethod = "DecodeUnconditionalBranch";
1161 }
1162
1163 class BranchImm<bit op, string asm, list<dag> pattern>
1164     : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1165 class CallImm<bit op, string asm, list<dag> pattern>
1166     : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1167
1168 //---
1169 // Basic one-operand data processing instructions.
1170 //---
1171
1172 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1173 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1174                          SDPatternOperator node>
1175   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1176       [(set regtype:$Rd, (node regtype:$Rn))]>,
1177     Sched<[WriteI, ReadI]> {
1178   bits<5> Rd;
1179   bits<5> Rn;
1180
1181   let Inst{30-13} = 0b101101011000000000;
1182   let Inst{12-10} = opc;
1183   let Inst{9-5}   = Rn;
1184   let Inst{4-0}   = Rd;
1185 }
1186
1187 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1188 multiclass OneOperandData<bits<3> opc, string asm,
1189                           SDPatternOperator node = null_frag> {
1190   def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1191     let Inst{31} = 0;
1192   }
1193
1194   def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1195     let Inst{31} = 1;
1196   }
1197 }
1198
1199 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1200     : BaseOneOperandData<opc, GPR32, asm, node> {
1201   let Inst{31} = 0;
1202 }
1203
1204 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1205     : BaseOneOperandData<opc, GPR64, asm, node> {
1206   let Inst{31} = 1;
1207 }
1208
1209 //---
1210 // Basic two-operand data processing instructions.
1211 //---
1212 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1213                           list<dag> pattern>
1214     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1215         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1216       Sched<[WriteI, ReadI, ReadI]> {
1217   let Uses = [NZCV];
1218   bits<5> Rd;
1219   bits<5> Rn;
1220   bits<5> Rm;
1221   let Inst{30}    = isSub;
1222   let Inst{28-21} = 0b11010000;
1223   let Inst{20-16} = Rm;
1224   let Inst{15-10} = 0;
1225   let Inst{9-5}   = Rn;
1226   let Inst{4-0}   = Rd;
1227 }
1228
1229 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1230                       SDNode OpNode>
1231     : BaseBaseAddSubCarry<isSub, regtype, asm,
1232         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1233
1234 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1235                               SDNode OpNode>
1236     : BaseBaseAddSubCarry<isSub, regtype, asm,
1237         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1238          (implicit NZCV)]> {
1239   let Defs = [NZCV];
1240 }
1241
1242 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1243                        SDNode OpNode, SDNode OpNode_setflags> {
1244   def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1245     let Inst{31} = 0;
1246     let Inst{29} = 0;
1247   }
1248   def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1249     let Inst{31} = 1;
1250     let Inst{29} = 0;
1251   }
1252
1253   // Sets flags.
1254   def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1255                                     OpNode_setflags> {
1256     let Inst{31} = 0;
1257     let Inst{29} = 1;
1258   }
1259   def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1260                                     OpNode_setflags> {
1261     let Inst{31} = 1;
1262     let Inst{29} = 1;
1263   }
1264 }
1265
1266 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1267                      SDPatternOperator OpNode>
1268   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1269       asm, "\t$Rd, $Rn, $Rm", "",
1270       [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
1271   bits<5> Rd;
1272   bits<5> Rn;
1273   bits<5> Rm;
1274   let Inst{30-21} = 0b0011010110;
1275   let Inst{20-16} = Rm;
1276   let Inst{15-14} = 0b00;
1277   let Inst{13-10} = opc;
1278   let Inst{9-5}   = Rn;
1279   let Inst{4-0}   = Rd;
1280 }
1281
1282 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1283               SDPatternOperator OpNode>
1284     : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1285   let Inst{10}    = isSigned;
1286 }
1287
1288 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1289   def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1290            Sched<[WriteID32, ReadID, ReadID]> {
1291     let Inst{31} = 0;
1292   }
1293   def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1294            Sched<[WriteID64, ReadID, ReadID]> {
1295     let Inst{31} = 1;
1296   }
1297 }
1298
1299 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1300                 SDPatternOperator OpNode = null_frag>
1301   : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1302     Sched<[WriteIS, ReadI]> {
1303   let Inst{11-10} = shift_type;
1304 }
1305
1306 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
1307   def Wr : BaseShift<shift_type, GPR32, asm> {
1308     let Inst{31} = 0;
1309   }
1310
1311   def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1312     let Inst{31} = 1;
1313   }
1314
1315   def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1316             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1317                                              (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1318
1319   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1320             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1321
1322   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1323             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1324
1325   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1326             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1327 }
1328
1329 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
1330     : InstAlias<asm#" $dst, $src1, $src2",
1331                 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
1332
1333 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1334                        RegisterClass addtype, string asm,
1335                        list<dag> pattern>
1336   : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1337       asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1338   bits<5> Rd;
1339   bits<5> Rn;
1340   bits<5> Rm;
1341   bits<5> Ra;
1342   let Inst{30-24} = 0b0011011;
1343   let Inst{23-21} = opc;
1344   let Inst{20-16} = Rm;
1345   let Inst{15}    = isSub;
1346   let Inst{14-10} = Ra;
1347   let Inst{9-5}   = Rn;
1348   let Inst{4-0}   = Rd;
1349 }
1350
1351 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
1352   // MADD/MSUB generation is decided by MachineCombiner.cpp
1353   def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
1354       [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
1355       Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1356     let Inst{31} = 0;
1357   }
1358
1359   def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
1360       [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
1361       Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
1362     let Inst{31} = 1;
1363   }
1364 }
1365
1366 class WideMulAccum<bit isSub, bits<3> opc, string asm,
1367                    SDNode AccNode, SDNode ExtNode>
1368   : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
1369     [(set GPR64:$Rd, (AccNode GPR64:$Ra,
1370                             (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
1371     Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1372   let Inst{31} = 1;
1373 }
1374
1375 class MulHi<bits<3> opc, string asm, SDNode OpNode>
1376   : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
1377       asm, "\t$Rd, $Rn, $Rm", "",
1378       [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
1379     Sched<[WriteIM64, ReadIM, ReadIM]> {
1380   bits<5> Rd;
1381   bits<5> Rn;
1382   bits<5> Rm;
1383   let Inst{31-24} = 0b10011011;
1384   let Inst{23-21} = opc;
1385   let Inst{20-16} = Rm;
1386   let Inst{15}    = 0;
1387   let Inst{9-5}   = Rn;
1388   let Inst{4-0}   = Rd;
1389
1390   // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
1391   // (i.e. all bits 1) but is ignored by the processor.
1392   let PostEncoderMethod = "fixMulHigh";
1393 }
1394
1395 class MulAccumWAlias<string asm, Instruction inst>
1396     : InstAlias<asm#" $dst, $src1, $src2",
1397                 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
1398 class MulAccumXAlias<string asm, Instruction inst>
1399     : InstAlias<asm#" $dst, $src1, $src2",
1400                 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
1401 class WideMulAccumAlias<string asm, Instruction inst>
1402     : InstAlias<asm#" $dst, $src1, $src2",
1403                 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
1404
1405 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
1406               SDPatternOperator OpNode, string asm>
1407   : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
1408       asm, "\t$Rd, $Rn, $Rm", "",
1409       [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
1410     Sched<[WriteISReg, ReadI, ReadISReg]> {
1411   bits<5> Rd;
1412   bits<5> Rn;
1413   bits<5> Rm;
1414
1415   let Inst{31} = sf;
1416   let Inst{30-21} = 0b0011010110;
1417   let Inst{20-16} = Rm;
1418   let Inst{15-13} = 0b010;
1419   let Inst{12} = C;
1420   let Inst{11-10} = sz;
1421   let Inst{9-5} = Rn;
1422   let Inst{4-0} = Rd;
1423   let Predicates = [HasCRC];
1424 }
1425
1426 //---
1427 // Address generation.
1428 //---
1429
1430 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
1431     : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
1432         pattern>,
1433       Sched<[WriteI]> {
1434   bits<5>  Xd;
1435   bits<21> label;
1436   let Inst{31}    = page;
1437   let Inst{30-29} = label{1-0};
1438   let Inst{28-24} = 0b10000;
1439   let Inst{23-5}  = label{20-2};
1440   let Inst{4-0}   = Xd;
1441
1442   let DecoderMethod = "DecodeAdrInstruction";
1443 }
1444
1445 //---
1446 // Move immediate.
1447 //---
1448
1449 def movimm32_imm : Operand<i32> {
1450   let ParserMatchClass = Imm0_65535Operand;
1451   let EncoderMethod = "getMoveWideImmOpValue";
1452   let PrintMethod = "printHexImm";
1453 }
1454 def movimm32_shift : Operand<i32> {
1455   let PrintMethod = "printShifter";
1456   let ParserMatchClass = MovImm32ShifterOperand;
1457 }
1458 def movimm64_shift : Operand<i32> {
1459   let PrintMethod = "printShifter";
1460   let ParserMatchClass = MovImm64ShifterOperand;
1461 }
1462
1463 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1464 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1465                         string asm>
1466   : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
1467        asm, "\t$Rd, $imm$shift", "", []>,
1468     Sched<[WriteImm]> {
1469   bits<5> Rd;
1470   bits<16> imm;
1471   bits<6> shift;
1472   let Inst{30-29} = opc;
1473   let Inst{28-23} = 0b100101;
1474   let Inst{22-21} = shift{5-4};
1475   let Inst{20-5}  = imm;
1476   let Inst{4-0}   = Rd;
1477
1478   let DecoderMethod = "DecodeMoveImmInstruction";
1479 }
1480
1481 multiclass MoveImmediate<bits<2> opc, string asm> {
1482   def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
1483     let Inst{31} = 0;
1484   }
1485
1486   def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
1487     let Inst{31} = 1;
1488   }
1489 }
1490
1491 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1492 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1493                           string asm>
1494   : I<(outs regtype:$Rd),
1495       (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
1496        asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
1497     Sched<[WriteI, ReadI]> {
1498   bits<5> Rd;
1499   bits<16> imm;
1500   bits<6> shift;
1501   let Inst{30-29} = opc;
1502   let Inst{28-23} = 0b100101;
1503   let Inst{22-21} = shift{5-4};
1504   let Inst{20-5}  = imm;
1505   let Inst{4-0}   = Rd;
1506
1507   let DecoderMethod = "DecodeMoveImmInstruction";
1508 }
1509
1510 multiclass InsertImmediate<bits<2> opc, string asm> {
1511   def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
1512     let Inst{31} = 0;
1513   }
1514
1515   def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
1516     let Inst{31} = 1;
1517   }
1518 }
1519
1520 //---
1521 // Add/Subtract
1522 //---
1523
1524 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
1525                     RegisterClass srcRegtype, addsub_shifted_imm immtype,
1526                     string asm, SDPatternOperator OpNode>
1527     : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
1528         asm, "\t$Rd, $Rn, $imm", "",
1529         [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
1530       Sched<[WriteI, ReadI]>  {
1531   bits<5>  Rd;
1532   bits<5>  Rn;
1533   bits<14> imm;
1534   let Inst{30}    = isSub;
1535   let Inst{29}    = setFlags;
1536   let Inst{28-24} = 0b10001;
1537   let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
1538   let Inst{21-10} = imm{11-0};
1539   let Inst{9-5}   = Rn;
1540   let Inst{4-0}   = Rd;
1541   let DecoderMethod = "DecodeBaseAddSubImm";
1542 }
1543
1544 class BaseAddSubRegPseudo<RegisterClass regtype,
1545                           SDPatternOperator OpNode>
1546     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1547              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1548       Sched<[WriteI, ReadI, ReadI]>;
1549
1550 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
1551                      arith_shifted_reg shifted_regtype, string asm,
1552                      SDPatternOperator OpNode>
1553     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1554         asm, "\t$Rd, $Rn, $Rm", "",
1555         [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
1556       Sched<[WriteISReg, ReadI, ReadISReg]> {
1557   // The operands are in order to match the 'addr' MI operands, so we
1558   // don't need an encoder method and by-name matching. Just use the default
1559   // in-order handling. Since we're using by-order, make sure the names
1560   // do not match.
1561   bits<5> dst;
1562   bits<5> src1;
1563   bits<5> src2;
1564   bits<8> shift;
1565   let Inst{30}    = isSub;
1566   let Inst{29}    = setFlags;
1567   let Inst{28-24} = 0b01011;
1568   let Inst{23-22} = shift{7-6};
1569   let Inst{21}    = 0;
1570   let Inst{20-16} = src2;
1571   let Inst{15-10} = shift{5-0};
1572   let Inst{9-5}   = src1;
1573   let Inst{4-0}   = dst;
1574
1575   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1576 }
1577
1578 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
1579                      RegisterClass src1Regtype, Operand src2Regtype,
1580                      string asm, SDPatternOperator OpNode>
1581     : I<(outs dstRegtype:$R1),
1582         (ins src1Regtype:$R2, src2Regtype:$R3),
1583         asm, "\t$R1, $R2, $R3", "",
1584         [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
1585       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1586   bits<5> Rd;
1587   bits<5> Rn;
1588   bits<5> Rm;
1589   bits<6> ext;
1590   let Inst{30}    = isSub;
1591   let Inst{29}    = setFlags;
1592   let Inst{28-24} = 0b01011;
1593   let Inst{23-21} = 0b001;
1594   let Inst{20-16} = Rm;
1595   let Inst{15-13} = ext{5-3};
1596   let Inst{12-10} = ext{2-0};
1597   let Inst{9-5}   = Rn;
1598   let Inst{4-0}   = Rd;
1599
1600   let DecoderMethod = "DecodeAddSubERegInstruction";
1601 }
1602
1603 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1604 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
1605                        RegisterClass src1Regtype, RegisterClass src2Regtype,
1606                        Operand ext_op, string asm>
1607     : I<(outs dstRegtype:$Rd),
1608         (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
1609         asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
1610       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1611   bits<5> Rd;
1612   bits<5> Rn;
1613   bits<5> Rm;
1614   bits<6> ext;
1615   let Inst{30}    = isSub;
1616   let Inst{29}    = setFlags;
1617   let Inst{28-24} = 0b01011;
1618   let Inst{23-21} = 0b001;
1619   let Inst{20-16} = Rm;
1620   let Inst{15}    = ext{5};
1621   let Inst{12-10} = ext{2-0};
1622   let Inst{9-5}   = Rn;
1623   let Inst{4-0}   = Rd;
1624
1625   let DecoderMethod = "DecodeAddSubERegInstruction";
1626 }
1627
1628 // Aliases for register+register add/subtract.
1629 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
1630                      RegisterClass src1Regtype, RegisterClass src2Regtype,
1631                      int shiftExt>
1632     : InstAlias<asm#" $dst, $src1, $src2",
1633                 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
1634                       shiftExt)>;
1635
1636 multiclass AddSub<bit isSub, string mnemonic,
1637                   SDPatternOperator OpNode = null_frag> {
1638   let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1639   // Add/Subtract immediate
1640   // Increase the weight of the immediate variant to try to match it before
1641   // the extended register variant.
1642   // We used to match the register variant before the immediate when the
1643   // register argument could be implicitly zero-extended.
1644   let AddedComplexity = 6 in
1645   def Wri  : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
1646                            mnemonic, OpNode> {
1647     let Inst{31} = 0;
1648   }
1649   let AddedComplexity = 6 in
1650   def Xri  : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
1651                            mnemonic, OpNode> {
1652     let Inst{31} = 1;
1653   }
1654
1655   // Add/Subtract register - Only used for CodeGen
1656   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1657   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1658
1659   // Add/Subtract shifted register
1660   def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
1661                            OpNode> {
1662     let Inst{31} = 0;
1663   }
1664   def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
1665                            OpNode> {
1666     let Inst{31} = 1;
1667   }
1668   }
1669
1670   // Add/Subtract extended register
1671   let AddedComplexity = 1, hasSideEffects = 0 in {
1672   def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
1673                            arith_extended_reg32<i32>, mnemonic, OpNode> {
1674     let Inst{31} = 0;
1675   }
1676   def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
1677                            arith_extended_reg32to64<i64>, mnemonic, OpNode> {
1678     let Inst{31} = 1;
1679   }
1680   }
1681
1682   def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
1683                                arith_extendlsl64, mnemonic> {
1684     // UXTX and SXTX only.
1685     let Inst{14-13} = 0b11;
1686     let Inst{31} = 1;
1687   }
1688
1689   // Register/register aliases with no shift when SP is not used.
1690   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1691                        GPR32, GPR32, GPR32, 0>;
1692   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1693                        GPR64, GPR64, GPR64, 0>;
1694
1695   // Register/register aliases with no shift when either the destination or
1696   // first source register is SP.
1697   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1698                        GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
1699   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1700                        GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
1701   def : AddSubRegAlias<mnemonic,
1702                        !cast<Instruction>(NAME#"Xrx64"),
1703                        GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
1704   def : AddSubRegAlias<mnemonic,
1705                        !cast<Instruction>(NAME#"Xrx64"),
1706                        GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
1707 }
1708
1709 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp> {
1710   let isCompare = 1, Defs = [NZCV] in {
1711   // Add/Subtract immediate
1712   def Wri  : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
1713                            mnemonic, OpNode> {
1714     let Inst{31} = 0;
1715   }
1716   def Xri  : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
1717                            mnemonic, OpNode> {
1718     let Inst{31} = 1;
1719   }
1720
1721   // Add/Subtract register
1722   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1723   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1724
1725   // Add/Subtract shifted register
1726   def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
1727                            OpNode> {
1728     let Inst{31} = 0;
1729   }
1730   def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
1731                            OpNode> {
1732     let Inst{31} = 1;
1733   }
1734
1735   // Add/Subtract extended register
1736   let AddedComplexity = 1 in {
1737   def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
1738                            arith_extended_reg32<i32>, mnemonic, OpNode> {
1739     let Inst{31} = 0;
1740   }
1741   def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
1742                            arith_extended_reg32<i64>, mnemonic, OpNode> {
1743     let Inst{31} = 1;
1744   }
1745   }
1746
1747   def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
1748                                arith_extendlsl64, mnemonic> {
1749     // UXTX and SXTX only.
1750     let Inst{14-13} = 0b11;
1751     let Inst{31} = 1;
1752   }
1753   } // Defs = [NZCV]
1754
1755   // Compare aliases
1756   def : InstAlias<cmp#" $src, $imm", (!cast<Instruction>(NAME#"Wri")
1757                   WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
1758   def : InstAlias<cmp#" $src, $imm", (!cast<Instruction>(NAME#"Xri")
1759                   XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
1760   def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
1761                   WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
1762   def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
1763                   XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
1764   def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
1765                   XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
1766   def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
1767                   WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
1768   def : InstAlias<cmp#" $src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
1769                   XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
1770
1771   // Compare shorthands
1772   def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Wrs")
1773                   WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
1774   def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Xrs")
1775                   XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
1776   def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Wrx")
1777                   WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
1778   def : InstAlias<cmp#" $src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
1779                   XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
1780
1781   // Register/register aliases with no shift when SP is not used.
1782   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1783                        GPR32, GPR32, GPR32, 0>;
1784   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1785                        GPR64, GPR64, GPR64, 0>;
1786
1787   // Register/register aliases with no shift when the first source register
1788   // is SP.
1789   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1790                        GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
1791   def : AddSubRegAlias<mnemonic,
1792                        !cast<Instruction>(NAME#"Xrx64"),
1793                        GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
1794 }
1795
1796 //---
1797 // Extract
1798 //---
1799 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1800                                       SDTCisPtrTy<3>]>;
1801 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
1802
1803 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
1804                      list<dag> patterns>
1805     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
1806          asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
1807       Sched<[WriteExtr, ReadExtrHi]> {
1808   bits<5> Rd;
1809   bits<5> Rn;
1810   bits<5> Rm;
1811   bits<6> imm;
1812
1813   let Inst{30-23} = 0b00100111;
1814   let Inst{21}    = 0;
1815   let Inst{20-16} = Rm;
1816   let Inst{15-10} = imm;
1817   let Inst{9-5}   = Rn;
1818   let Inst{4-0}   = Rd;
1819 }
1820
1821 multiclass ExtractImm<string asm> {
1822   def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
1823                       [(set GPR32:$Rd,
1824                         (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
1825     let Inst{31} = 0;
1826     let Inst{22} = 0;
1827     // imm<5> must be zero.
1828     let imm{5}   = 0;
1829   }
1830   def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
1831                       [(set GPR64:$Rd,
1832                         (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
1833
1834     let Inst{31} = 1;
1835     let Inst{22} = 1;
1836   }
1837 }
1838
1839 //---
1840 // Bitfield
1841 //---
1842
1843 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1844 class BaseBitfieldImm<bits<2> opc,
1845                       RegisterClass regtype, Operand imm_type, string asm>
1846     : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
1847          asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
1848       Sched<[WriteIS, ReadI]> {
1849   bits<5> Rd;
1850   bits<5> Rn;
1851   bits<6> immr;
1852   bits<6> imms;
1853
1854   let Inst{30-29} = opc;
1855   let Inst{28-23} = 0b100110;
1856   let Inst{21-16} = immr;
1857   let Inst{15-10} = imms;
1858   let Inst{9-5}   = Rn;
1859   let Inst{4-0}   = Rd;
1860 }
1861
1862 multiclass BitfieldImm<bits<2> opc, string asm> {
1863   def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
1864     let Inst{31} = 0;
1865     let Inst{22} = 0;
1866     // imms<5> and immr<5> must be zero, else ReservedValue().
1867     let Inst{21} = 0;
1868     let Inst{15} = 0;
1869   }
1870   def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
1871     let Inst{31} = 1;
1872     let Inst{22} = 1;
1873   }
1874 }
1875
1876 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1877 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
1878                       RegisterClass regtype, Operand imm_type, string asm>
1879     : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
1880                              imm_type:$imms),
1881          asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
1882       Sched<[WriteIS, ReadI]> {
1883   bits<5> Rd;
1884   bits<5> Rn;
1885   bits<6> immr;
1886   bits<6> imms;
1887
1888   let Inst{30-29} = opc;
1889   let Inst{28-23} = 0b100110;
1890   let Inst{21-16} = immr;
1891   let Inst{15-10} = imms;
1892   let Inst{9-5}   = Rn;
1893   let Inst{4-0}   = Rd;
1894 }
1895
1896 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
1897   def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
1898     let Inst{31} = 0;
1899     let Inst{22} = 0;
1900     // imms<5> and immr<5> must be zero, else ReservedValue().
1901     let Inst{21} = 0;
1902     let Inst{15} = 0;
1903   }
1904   def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
1905     let Inst{31} = 1;
1906     let Inst{22} = 1;
1907   }
1908 }
1909
1910 //---
1911 // Logical
1912 //---
1913
1914 // Logical (immediate)
1915 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
1916                      RegisterClass sregtype, Operand imm_type, string asm,
1917                      list<dag> pattern>
1918     : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
1919          asm, "\t$Rd, $Rn, $imm", "", pattern>,
1920       Sched<[WriteI, ReadI]> {
1921   bits<5>  Rd;
1922   bits<5>  Rn;
1923   bits<13> imm;
1924   let Inst{30-29} = opc;
1925   let Inst{28-23} = 0b100100;
1926   let Inst{22}    = imm{12};
1927   let Inst{21-16} = imm{11-6};
1928   let Inst{15-10} = imm{5-0};
1929   let Inst{9-5}   = Rn;
1930   let Inst{4-0}   = Rd;
1931
1932   let DecoderMethod = "DecodeLogicalImmInstruction";
1933 }
1934
1935 // Logical (shifted register)
1936 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
1937                       logical_shifted_reg shifted_regtype, string asm,
1938                       list<dag> pattern>
1939     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1940         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1941       Sched<[WriteISReg, ReadI, ReadISReg]> {
1942   // The operands are in order to match the 'addr' MI operands, so we
1943   // don't need an encoder method and by-name matching. Just use the default
1944   // in-order handling. Since we're using by-order, make sure the names
1945   // do not match.
1946   bits<5> dst;
1947   bits<5> src1;
1948   bits<5> src2;
1949   bits<8> shift;
1950   let Inst{30-29} = opc;
1951   let Inst{28-24} = 0b01010;
1952   let Inst{23-22} = shift{7-6};
1953   let Inst{21}    = N;
1954   let Inst{20-16} = src2;
1955   let Inst{15-10} = shift{5-0};
1956   let Inst{9-5}   = src1;
1957   let Inst{4-0}   = dst;
1958
1959   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1960 }
1961
1962 // Aliases for register+register logical instructions.
1963 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
1964     : InstAlias<asm#" $dst, $src1, $src2",
1965                 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
1966
1967 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
1968                       string Alias> {
1969   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
1970   def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
1971                            [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
1972                                                logical_imm32:$imm))]> {
1973     let Inst{31} = 0;
1974     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
1975   }
1976   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
1977   def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
1978                            [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
1979                                                logical_imm64:$imm))]> {
1980     let Inst{31} = 1;
1981   }
1982
1983   def : InstAlias<Alias # " $Rd, $Rn, $imm",
1984                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
1985                       logical_imm32_not:$imm), 0>;
1986   def : InstAlias<Alias # " $Rd, $Rn, $imm",
1987                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
1988                        logical_imm64_not:$imm), 0>;
1989 }
1990
1991 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
1992                        string Alias> {
1993   let isCompare = 1, Defs = [NZCV] in {
1994   def Wri  : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
1995       [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
1996     let Inst{31} = 0;
1997     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
1998   }
1999   def Xri  : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2000       [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2001     let Inst{31} = 1;
2002   }
2003   } // end Defs = [NZCV]
2004
2005   def : InstAlias<Alias # " $Rd, $Rn, $imm",
2006                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2007                       logical_imm32_not:$imm), 0>;
2008   def : InstAlias<Alias # " $Rd, $Rn, $imm",
2009                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2010                        logical_imm64_not:$imm), 0>;
2011 }
2012
2013 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2014     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2015              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2016       Sched<[WriteI, ReadI, ReadI]>;
2017
2018 // Split from LogicalImm as not all instructions have both.
2019 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2020                       SDPatternOperator OpNode> {
2021   let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2022   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2023   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2024   }
2025
2026   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2027                             [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2028                                                  logical_shifted_reg32:$Rm))]> {
2029     let Inst{31} = 0;
2030   }
2031   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2032                             [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2033                                                  logical_shifted_reg64:$Rm))]> {
2034     let Inst{31} = 1;
2035   }
2036
2037   def : LogicalRegAlias<mnemonic,
2038                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
2039   def : LogicalRegAlias<mnemonic,
2040                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
2041 }
2042
2043 // Split from LogicalReg to allow setting NZCV Defs
2044 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2045                        SDPatternOperator OpNode = null_frag> {
2046   let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2047   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2048   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2049
2050   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2051             [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2052     let Inst{31} = 0;
2053   }
2054   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2055             [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2056     let Inst{31} = 1;
2057   }
2058   } // Defs = [NZCV]
2059
2060   def : LogicalRegAlias<mnemonic,
2061                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
2062   def : LogicalRegAlias<mnemonic,
2063                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
2064 }
2065
2066 //---
2067 // Conditionally set flags
2068 //---
2069
2070 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2071 class BaseCondSetFlagsImm<bit op, RegisterClass regtype, string asm>
2072     : I<(outs), (ins regtype:$Rn, imm0_31:$imm, imm0_15:$nzcv, ccode:$cond),
2073          asm, "\t$Rn, $imm, $nzcv, $cond", "", []>,
2074       Sched<[WriteI, ReadI]> {
2075   let Uses = [NZCV];
2076   let Defs = [NZCV];
2077
2078   bits<5> Rn;
2079   bits<5> imm;
2080   bits<4> nzcv;
2081   bits<4> cond;
2082
2083   let Inst{30}    = op;
2084   let Inst{29-21} = 0b111010010;
2085   let Inst{20-16} = imm;
2086   let Inst{15-12} = cond;
2087   let Inst{11-10} = 0b10;
2088   let Inst{9-5}   = Rn;
2089   let Inst{4}     = 0b0;
2090   let Inst{3-0}   = nzcv;
2091 }
2092
2093 multiclass CondSetFlagsImm<bit op, string asm> {
2094   def Wi : BaseCondSetFlagsImm<op, GPR32, asm> {
2095     let Inst{31} = 0;
2096   }
2097   def Xi : BaseCondSetFlagsImm<op, GPR64, asm> {
2098     let Inst{31} = 1;
2099   }
2100 }
2101
2102 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2103 class BaseCondSetFlagsReg<bit op, RegisterClass regtype, string asm>
2104     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm0_15:$nzcv, ccode:$cond),
2105          asm, "\t$Rn, $Rm, $nzcv, $cond", "", []>,
2106       Sched<[WriteI, ReadI, ReadI]> {
2107   let Uses = [NZCV];
2108   let Defs = [NZCV];
2109
2110   bits<5> Rn;
2111   bits<5> Rm;
2112   bits<4> nzcv;
2113   bits<4> cond;
2114
2115   let Inst{30}    = op;
2116   let Inst{29-21} = 0b111010010;
2117   let Inst{20-16} = Rm;
2118   let Inst{15-12} = cond;
2119   let Inst{11-10} = 0b00;
2120   let Inst{9-5}   = Rn;
2121   let Inst{4}     = 0b0;
2122   let Inst{3-0}   = nzcv;
2123 }
2124
2125 multiclass CondSetFlagsReg<bit op, string asm> {
2126   def Wr : BaseCondSetFlagsReg<op, GPR32, asm> {
2127     let Inst{31} = 0;
2128   }
2129   def Xr : BaseCondSetFlagsReg<op, GPR64, asm> {
2130     let Inst{31} = 1;
2131   }
2132 }
2133
2134 //---
2135 // Conditional select
2136 //---
2137
2138 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2139     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2140          asm, "\t$Rd, $Rn, $Rm, $cond", "",
2141          [(set regtype:$Rd,
2142                (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2143       Sched<[WriteI, ReadI, ReadI]> {
2144   let Uses = [NZCV];
2145
2146   bits<5> Rd;
2147   bits<5> Rn;
2148   bits<5> Rm;
2149   bits<4> cond;
2150
2151   let Inst{30}    = op;
2152   let Inst{29-21} = 0b011010100;
2153   let Inst{20-16} = Rm;
2154   let Inst{15-12} = cond;
2155   let Inst{11-10} = op2;
2156   let Inst{9-5}   = Rn;
2157   let Inst{4-0}   = Rd;
2158 }
2159
2160 multiclass CondSelect<bit op, bits<2> op2, string asm> {
2161   def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2162     let Inst{31} = 0;
2163   }
2164   def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2165     let Inst{31} = 1;
2166   }
2167 }
2168
2169 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2170                        PatFrag frag>
2171     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2172          asm, "\t$Rd, $Rn, $Rm, $cond", "",
2173          [(set regtype:$Rd,
2174                (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2175                (i32 imm:$cond), NZCV))]>,
2176       Sched<[WriteI, ReadI, ReadI]> {
2177   let Uses = [NZCV];
2178
2179   bits<5> Rd;
2180   bits<5> Rn;
2181   bits<5> Rm;
2182   bits<4> cond;
2183
2184   let Inst{30}    = op;
2185   let Inst{29-21} = 0b011010100;
2186   let Inst{20-16} = Rm;
2187   let Inst{15-12} = cond;
2188   let Inst{11-10} = op2;
2189   let Inst{9-5}   = Rn;
2190   let Inst{4-0}   = Rd;
2191 }
2192
2193 def inv_cond_XFORM : SDNodeXForm<imm, [{
2194   AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
2195   return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), MVT::i32);
2196 }]>;
2197
2198 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
2199   def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
2200     let Inst{31} = 0;
2201   }
2202   def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
2203     let Inst{31} = 1;
2204   }
2205
2206   def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
2207             (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
2208                                            (inv_cond_XFORM imm:$cond))>;
2209
2210   def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
2211             (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
2212                                            (inv_cond_XFORM imm:$cond))>;
2213 }
2214
2215 //---
2216 // Special Mask Value
2217 //---
2218 def maski8_or_more : Operand<i32>,
2219   ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
2220 }
2221 def maski16_or_more : Operand<i32>,
2222   ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
2223 }
2224
2225
2226 //---
2227 // Load/store
2228 //---
2229
2230 // (unsigned immediate)
2231 // Indexed for 8-bit registers. offset is in range [0,4095].
2232 def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
2233 def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
2234 def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
2235 def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
2236 def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
2237
2238 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
2239   let Name = "UImm12Offset" # Scale;
2240   let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
2241   let PredicateMethod = "isUImm12Offset<" # Scale # ">";
2242   let DiagnosticType = "InvalidMemoryIndexed" # Scale;
2243 }
2244
2245 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
2246 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
2247 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
2248 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
2249 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
2250
2251 class uimm12_scaled<int Scale> : Operand<i64> {
2252   let ParserMatchClass
2253    = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
2254   let EncoderMethod
2255    = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
2256   let PrintMethod = "printUImm12Offset<" # Scale # ">";
2257 }
2258
2259 def uimm12s1 : uimm12_scaled<1>;
2260 def uimm12s2 : uimm12_scaled<2>;
2261 def uimm12s4 : uimm12_scaled<4>;
2262 def uimm12s8 : uimm12_scaled<8>;
2263 def uimm12s16 : uimm12_scaled<16>;
2264
2265 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2266                       string asm, list<dag> pattern>
2267     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2268   bits<5> Rt;
2269
2270   bits<5> Rn;
2271   bits<12> offset;
2272
2273   let Inst{31-30} = sz;
2274   let Inst{29-27} = 0b111;
2275   let Inst{26}    = V;
2276   let Inst{25-24} = 0b01;
2277   let Inst{23-22} = opc;
2278   let Inst{21-10} = offset;
2279   let Inst{9-5}   = Rn;
2280   let Inst{4-0}   = Rt;
2281
2282   let DecoderMethod = "DecodeUnsignedLdStInstruction";
2283 }
2284
2285 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2286                   Operand indextype, string asm, list<dag> pattern> {
2287   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2288   def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
2289                            (ins GPR64sp:$Rn, indextype:$offset),
2290                            asm, pattern>,
2291            Sched<[WriteLD]>;
2292
2293   def : InstAlias<asm # " $Rt, [$Rn]",
2294                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2295 }
2296
2297 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2298              Operand indextype, string asm, list<dag> pattern> {
2299   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2300   def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2301                            (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2302                            asm, pattern>,
2303            Sched<[WriteST]>;
2304
2305   def : InstAlias<asm # " $Rt, [$Rn]",
2306                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2307 }
2308
2309 def PrefetchOperand : AsmOperandClass {
2310   let Name = "Prefetch";
2311   let ParserMethod = "tryParsePrefetch";
2312 }
2313 def prfop : Operand<i32> {
2314   let PrintMethod = "printPrefetchOp";
2315   let ParserMatchClass = PrefetchOperand;
2316 }
2317
2318 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2319 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2320     : BaseLoadStoreUI<sz, V, opc,
2321                       (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
2322                       asm, pat>,
2323       Sched<[WriteLD]>;
2324
2325 //---
2326 // Load literal
2327 //---
2328
2329 // Load literal address: 19-bit immediate. The low two bits of the target
2330 // offset are implied zero and so are not part of the immediate.
2331 def am_ldrlit : Operand<OtherVT> {
2332   let EncoderMethod = "getLoadLiteralOpValue";
2333   let DecoderMethod = "DecodePCRelLabel19";
2334   let PrintMethod = "printAlignedLabel";
2335   let ParserMatchClass = PCRelLabel19Operand;
2336 }
2337
2338 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2339 class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
2340     : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
2341         asm, "\t$Rt, $label", "", []>,
2342       Sched<[WriteLD]> {
2343   bits<5> Rt;
2344   bits<19> label;
2345   let Inst{31-30} = opc;
2346   let Inst{29-27} = 0b011;
2347   let Inst{26}    = V;
2348   let Inst{25-24} = 0b00;
2349   let Inst{23-5}  = label;
2350   let Inst{4-0}   = Rt;
2351 }
2352
2353 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2354 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
2355     : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
2356         asm, "\t$Rt, $label", "", pat>,
2357       Sched<[WriteLD]> {
2358   bits<5> Rt;
2359   bits<19> label;
2360   let Inst{31-30} = opc;
2361   let Inst{29-27} = 0b011;
2362   let Inst{26}    = V;
2363   let Inst{25-24} = 0b00;
2364   let Inst{23-5}  = label;
2365   let Inst{4-0}   = Rt;
2366 }
2367
2368 //---
2369 // Load/store register offset
2370 //---
2371
2372 def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
2373 def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
2374 def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
2375 def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
2376 def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
2377
2378 def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
2379 def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
2380 def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
2381 def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
2382 def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
2383
2384 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
2385   let Name = "Mem" # Reg # "Extend" # Width;
2386   let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
2387   let RenderMethod = "addMemExtendOperands";
2388   let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
2389 }
2390
2391 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
2392   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2393   // the trivial shift.
2394   let RenderMethod = "addMemExtend8Operands";
2395 }
2396 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
2397 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
2398 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
2399 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
2400
2401 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
2402   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2403   // the trivial shift.
2404   let RenderMethod = "addMemExtend8Operands";
2405 }
2406 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
2407 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
2408 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
2409 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
2410
2411 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
2412         : Operand<i32> {
2413   let ParserMatchClass = ParserClass;
2414   let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
2415   let DecoderMethod = "DecodeMemExtend";
2416   let EncoderMethod = "getMemExtendOpValue";
2417   let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
2418 }
2419
2420 def ro_Wextend8   : ro_extend<MemWExtend8Operand,   "w", 8>;
2421 def ro_Wextend16  : ro_extend<MemWExtend16Operand,  "w", 16>;
2422 def ro_Wextend32  : ro_extend<MemWExtend32Operand,  "w", 32>;
2423 def ro_Wextend64  : ro_extend<MemWExtend64Operand,  "w", 64>;
2424 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
2425
2426 def ro_Xextend8   : ro_extend<MemXExtend8Operand,   "x", 8>;
2427 def ro_Xextend16  : ro_extend<MemXExtend16Operand,  "x", 16>;
2428 def ro_Xextend32  : ro_extend<MemXExtend32Operand,  "x", 32>;
2429 def ro_Xextend64  : ro_extend<MemXExtend64Operand,  "x", 64>;
2430 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
2431
2432 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
2433                   Operand wextend, Operand xextend>  {
2434   // CodeGen-level pattern covering the entire addressing mode.
2435   ComplexPattern Wpat = windex;
2436   ComplexPattern Xpat = xindex;
2437
2438   // Asm-level Operand covering the valid "uxtw #3" style syntax.
2439   Operand Wext = wextend;
2440   Operand Xext = xextend;
2441 }
2442
2443 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
2444 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
2445 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
2446 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
2447 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
2448                        ro_Xextend128>;
2449
2450 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2451                       string asm, dag ins, dag outs, list<dag> pat>
2452     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2453   bits<5> Rt;
2454   bits<5> Rn;
2455   bits<5> Rm;
2456   bits<2> extend;
2457   let Inst{31-30} = sz;
2458   let Inst{29-27} = 0b111;
2459   let Inst{26}    = V;
2460   let Inst{25-24} = 0b00;
2461   let Inst{23-22} = opc;
2462   let Inst{21}    = 1;
2463   let Inst{20-16} = Rm;
2464   let Inst{15}    = extend{1}; // sign extend Rm?
2465   let Inst{14}    = 1;
2466   let Inst{12}    = extend{0}; // do shift?
2467   let Inst{11-10} = 0b10;
2468   let Inst{9-5}   = Rn;
2469   let Inst{4-0}   = Rt;
2470 }
2471
2472 class ROInstAlias<string asm, RegisterClass regtype, Instruction INST>
2473   : InstAlias<asm # " $Rt, [$Rn, $Rm]",
2474               (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2475
2476 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2477                    string asm, ValueType Ty, SDPatternOperator loadop> {
2478   let AddedComplexity = 10 in
2479   def roW : LoadStore8RO<sz, V, opc, regtype, asm,
2480                  (outs regtype:$Rt),
2481                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2482                  [(set (Ty regtype:$Rt),
2483                        (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2484                                              ro_Wextend8:$extend)))]>,
2485            Sched<[WriteLDIdx, ReadAdrBase]> {
2486     let Inst{13} = 0b0;
2487   }
2488
2489   let AddedComplexity = 10 in
2490   def roX : LoadStore8RO<sz, V, opc, regtype, asm,
2491                  (outs regtype:$Rt),
2492                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2493                  [(set (Ty regtype:$Rt),
2494                        (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2495                                              ro_Xextend8:$extend)))]>,
2496            Sched<[WriteLDIdx, ReadAdrBase]> {
2497     let Inst{13} = 0b1;
2498   }
2499
2500   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2501 }
2502
2503 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2504                     string asm, ValueType Ty, SDPatternOperator storeop> {
2505   let AddedComplexity = 10 in
2506   def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2507                  (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2508                  [(storeop (Ty regtype:$Rt),
2509                            (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2510                                          ro_Wextend8:$extend))]>,
2511             Sched<[WriteSTIdx, ReadAdrBase]> {
2512     let Inst{13} = 0b0;
2513   }
2514
2515   let AddedComplexity = 10 in
2516   def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2517                  (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2518                  [(storeop (Ty regtype:$Rt),
2519                            (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2520                                          ro_Xextend8:$extend))]>,
2521             Sched<[WriteSTIdx, ReadAdrBase]> {
2522     let Inst{13} = 0b1;
2523   }
2524
2525   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2526 }
2527
2528 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2529                       string asm, dag ins, dag outs, list<dag> pat>
2530     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2531   bits<5> Rt;
2532   bits<5> Rn;
2533   bits<5> Rm;
2534   bits<2> extend;
2535   let Inst{31-30} = sz;
2536   let Inst{29-27} = 0b111;
2537   let Inst{26}    = V;
2538   let Inst{25-24} = 0b00;
2539   let Inst{23-22} = opc;
2540   let Inst{21}    = 1;
2541   let Inst{20-16} = Rm;
2542   let Inst{15}    = extend{1}; // sign extend Rm?
2543   let Inst{14}    = 1;
2544   let Inst{12}    = extend{0}; // do shift?
2545   let Inst{11-10} = 0b10;
2546   let Inst{9-5}   = Rn;
2547   let Inst{4-0}   = Rt;
2548 }
2549
2550 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2551                     string asm, ValueType Ty, SDPatternOperator loadop> {
2552   let AddedComplexity = 10 in
2553   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2554                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2555                  [(set (Ty regtype:$Rt),
2556                        (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2557                                               ro_Wextend16:$extend)))]>,
2558             Sched<[WriteLDIdx, ReadAdrBase]> {
2559     let Inst{13} = 0b0;
2560   }
2561
2562   let AddedComplexity = 10 in
2563   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2564                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2565                  [(set (Ty regtype:$Rt),
2566                        (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2567                                              ro_Xextend16:$extend)))]>,
2568             Sched<[WriteLDIdx, ReadAdrBase]> {
2569     let Inst{13} = 0b1;
2570   }
2571
2572   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2573 }
2574
2575 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2576                      string asm, ValueType Ty, SDPatternOperator storeop> {
2577   let AddedComplexity = 10 in
2578   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2579                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2580                 [(storeop (Ty regtype:$Rt),
2581                           (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2582                                          ro_Wextend16:$extend))]>,
2583            Sched<[WriteSTIdx, ReadAdrBase]> {
2584     let Inst{13} = 0b0;
2585   }
2586
2587   let AddedComplexity = 10 in
2588   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2589                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2590                 [(storeop (Ty regtype:$Rt),
2591                           (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2592                                          ro_Xextend16:$extend))]>,
2593            Sched<[WriteSTIdx, ReadAdrBase]> {
2594     let Inst{13} = 0b1;
2595   }
2596
2597   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2598 }
2599
2600 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2601                       string asm, dag ins, dag outs, list<dag> pat>
2602     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2603   bits<5> Rt;
2604   bits<5> Rn;
2605   bits<5> Rm;
2606   bits<2> extend;
2607   let Inst{31-30} = sz;
2608   let Inst{29-27} = 0b111;
2609   let Inst{26}    = V;
2610   let Inst{25-24} = 0b00;
2611   let Inst{23-22} = opc;
2612   let Inst{21}    = 1;
2613   let Inst{20-16} = Rm;
2614   let Inst{15}    = extend{1}; // sign extend Rm?
2615   let Inst{14}    = 1;
2616   let Inst{12}    = extend{0}; // do shift?
2617   let Inst{11-10} = 0b10;
2618   let Inst{9-5}   = Rn;
2619   let Inst{4-0}   = Rt;
2620 }
2621
2622 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2623                     string asm, ValueType Ty, SDPatternOperator loadop> {
2624   let AddedComplexity = 10 in
2625   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2626                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2627                  [(set (Ty regtype:$Rt),
2628                        (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2629                                               ro_Wextend32:$extend)))]>,
2630            Sched<[WriteLDIdx, ReadAdrBase]> {
2631     let Inst{13} = 0b0;
2632   }
2633
2634   let AddedComplexity = 10 in
2635   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2636                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2637                  [(set (Ty regtype:$Rt),
2638                        (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2639                                               ro_Xextend32:$extend)))]>,
2640            Sched<[WriteLDIdx, ReadAdrBase]> {
2641     let Inst{13} = 0b1;
2642   }
2643
2644   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2645 }
2646
2647 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2648                      string asm, ValueType Ty, SDPatternOperator storeop> {
2649   let AddedComplexity = 10 in
2650   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2651                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2652                 [(storeop (Ty regtype:$Rt),
2653                           (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2654                                          ro_Wextend32:$extend))]>,
2655             Sched<[WriteSTIdx, ReadAdrBase]> {
2656     let Inst{13} = 0b0;
2657   }
2658
2659   let AddedComplexity = 10 in
2660   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2661                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2662                 [(storeop (Ty regtype:$Rt),
2663                           (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2664                                         ro_Xextend32:$extend))]>,
2665             Sched<[WriteSTIdx, ReadAdrBase]> {
2666     let Inst{13} = 0b1;
2667   }
2668
2669   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2670 }
2671
2672 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2673                       string asm, dag ins, dag outs, list<dag> pat>
2674     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2675   bits<5> Rt;
2676   bits<5> Rn;
2677   bits<5> Rm;
2678   bits<2> extend;
2679   let Inst{31-30} = sz;
2680   let Inst{29-27} = 0b111;
2681   let Inst{26}    = V;
2682   let Inst{25-24} = 0b00;
2683   let Inst{23-22} = opc;
2684   let Inst{21}    = 1;
2685   let Inst{20-16} = Rm;
2686   let Inst{15}    = extend{1}; // sign extend Rm?
2687   let Inst{14}    = 1;
2688   let Inst{12}    = extend{0}; // do shift?
2689   let Inst{11-10} = 0b10;
2690   let Inst{9-5}   = Rn;
2691   let Inst{4-0}   = Rt;
2692 }
2693
2694 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2695                     string asm, ValueType Ty, SDPatternOperator loadop> {
2696   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2697   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2698                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2699                 [(set (Ty regtype:$Rt),
2700                       (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2701                                              ro_Wextend64:$extend)))]>,
2702            Sched<[WriteLDIdx, ReadAdrBase]> {
2703     let Inst{13} = 0b0;
2704   }
2705
2706   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2707   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2708                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2709                  [(set (Ty regtype:$Rt),
2710                        (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2711                                               ro_Xextend64:$extend)))]>,
2712            Sched<[WriteLDIdx, ReadAdrBase]> {
2713     let Inst{13} = 0b1;
2714   }
2715
2716   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2717 }
2718
2719 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2720                      string asm, ValueType Ty, SDPatternOperator storeop> {
2721   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2722   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2723                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2724                 [(storeop (Ty regtype:$Rt),
2725                           (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2726                                          ro_Wextend64:$extend))]>,
2727             Sched<[WriteSTIdx, ReadAdrBase]> {
2728     let Inst{13} = 0b0;
2729   }
2730
2731   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2732   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2733                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2734                 [(storeop (Ty regtype:$Rt),
2735                           (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2736                                          ro_Xextend64:$extend))]>,
2737             Sched<[WriteSTIdx, ReadAdrBase]> {
2738     let Inst{13} = 0b1;
2739   }
2740
2741   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2742 }
2743
2744 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2745                       string asm, dag ins, dag outs, list<dag> pat>
2746     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2747   bits<5> Rt;
2748   bits<5> Rn;
2749   bits<5> Rm;
2750   bits<2> extend;
2751   let Inst{31-30} = sz;
2752   let Inst{29-27} = 0b111;
2753   let Inst{26}    = V;
2754   let Inst{25-24} = 0b00;
2755   let Inst{23-22} = opc;
2756   let Inst{21}    = 1;
2757   let Inst{20-16} = Rm;
2758   let Inst{15}    = extend{1}; // sign extend Rm?
2759   let Inst{14}    = 1;
2760   let Inst{12}    = extend{0}; // do shift?
2761   let Inst{11-10} = 0b10;
2762   let Inst{9-5}   = Rn;
2763   let Inst{4-0}   = Rt;
2764 }
2765
2766 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2767                      string asm, ValueType Ty, SDPatternOperator loadop> {
2768   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2769   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2770                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2771                  [(set (Ty regtype:$Rt),
2772                        (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2773                                                ro_Wextend128:$extend)))]>,
2774             Sched<[WriteLDIdx, ReadAdrBase]> {
2775     let Inst{13} = 0b0;
2776   }
2777
2778   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2779   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2780                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2781                  [(set (Ty regtype:$Rt),
2782                        (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2783                                                ro_Xextend128:$extend)))]>,
2784             Sched<[WriteLDIdx, ReadAdrBase]> {
2785     let Inst{13} = 0b1;
2786   }
2787
2788   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2789 }
2790
2791 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2792                       string asm, ValueType Ty, SDPatternOperator storeop> {
2793   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2794   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2795                (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2796                 [(storeop (Ty regtype:$Rt),
2797                           (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2798                                           ro_Wextend128:$extend))]>,
2799             Sched<[WriteSTIdx, ReadAdrBase]> {
2800     let Inst{13} = 0b0;
2801   }
2802
2803   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2804   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2805                (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2806                 [(storeop (Ty regtype:$Rt),
2807                           (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2808                                           ro_Xextend128:$extend))]>,
2809             Sched<[WriteSTIdx, ReadAdrBase]> {
2810     let Inst{13} = 0b1;
2811   }
2812
2813   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2814 }
2815
2816 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2817 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
2818                      string asm, list<dag> pat>
2819     : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
2820       Sched<[WriteLD]> {
2821   bits<5> Rt;
2822   bits<5> Rn;
2823   bits<5> Rm;
2824   bits<2> extend;
2825   let Inst{31-30} = sz;
2826   let Inst{29-27} = 0b111;
2827   let Inst{26}    = V;
2828   let Inst{25-24} = 0b00;
2829   let Inst{23-22} = opc;
2830   let Inst{21}    = 1;
2831   let Inst{20-16} = Rm;
2832   let Inst{15}    = extend{1}; // sign extend Rm?
2833   let Inst{14}    = 1;
2834   let Inst{12}    = extend{0}; // do shift?
2835   let Inst{11-10} = 0b10;
2836   let Inst{9-5}   = Rn;
2837   let Inst{4-0}   = Rt;
2838 }
2839
2840 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
2841   def roW : BasePrefetchRO<sz, V, opc, (outs),
2842                 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2843                 asm, [(AArch64Prefetch imm:$Rt,
2844                                      (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2845                                                     ro_Wextend64:$extend))]> {
2846     let Inst{13} = 0b0;
2847   }
2848
2849   def roX : BasePrefetchRO<sz, V, opc, (outs),
2850                 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2851                 asm,  [(AArch64Prefetch imm:$Rt,
2852                                       (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2853                                                      ro_Xextend64:$extend))]> {
2854     let Inst{13} = 0b1;
2855   }
2856
2857   def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
2858                (!cast<Instruction>(NAME # "roX") prfop:$Rt,
2859                                                  GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2860 }
2861
2862 //---
2863 // Load/store unscaled immediate
2864 //---
2865
2866 def am_unscaled8 :  ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
2867 def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
2868 def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
2869 def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
2870 def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
2871
2872 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2873                            string asm, list<dag> pattern>
2874     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2875   bits<5> Rt;
2876   bits<5> Rn;
2877   bits<9> offset;
2878   let Inst{31-30} = sz;
2879   let Inst{29-27} = 0b111;
2880   let Inst{26}    = V;
2881   let Inst{25-24} = 0b00;
2882   let Inst{23-22} = opc;
2883   let Inst{21}    = 0;
2884   let Inst{20-12} = offset;
2885   let Inst{11-10} = 0b00;
2886   let Inst{9-5}   = Rn;
2887   let Inst{4-0}   = Rt;
2888
2889   let DecoderMethod = "DecodeSignedLdStInstruction";
2890 }
2891
2892 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2893                    string asm, list<dag> pattern> {
2894   let AddedComplexity = 1 in // try this before LoadUI
2895   def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
2896                                (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
2897           Sched<[WriteLD]>;
2898
2899   def : InstAlias<asm # " $Rt, [$Rn]",
2900                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
2901 }
2902
2903 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2904                          string asm, list<dag> pattern> {
2905   let AddedComplexity = 1 in // try this before StoreUI
2906   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
2907                                (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
2908                                asm, pattern>,
2909           Sched<[WriteST]>;
2910
2911   def : InstAlias<asm # " $Rt, [$Rn]",
2912                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
2913 }
2914
2915 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
2916                             list<dag> pat> {
2917   let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2918   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
2919                                (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
2920                                asm, pat>,
2921           Sched<[WriteLD]>;
2922
2923   def : InstAlias<asm # " $Rt, [$Rn]",
2924                   (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
2925 }
2926
2927 //---
2928 // Load/store unscaled immediate, unprivileged
2929 //---
2930
2931 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
2932                                 dag oops, dag iops, string asm>
2933     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
2934   bits<5> Rt;
2935   bits<5> Rn;
2936   bits<9> offset;
2937   let Inst{31-30} = sz;
2938   let Inst{29-27} = 0b111;
2939   let Inst{26}    = V;
2940   let Inst{25-24} = 0b00;
2941   let Inst{23-22} = opc;
2942   let Inst{21}    = 0;
2943   let Inst{20-12} = offset;
2944   let Inst{11-10} = 0b10;
2945   let Inst{9-5}   = Rn;
2946   let Inst{4-0}   = Rt;
2947
2948   let DecoderMethod = "DecodeSignedLdStInstruction";
2949 }
2950
2951 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
2952                             RegisterClass regtype, string asm> {
2953   let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
2954   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
2955                                     (ins GPR64sp:$Rn, simm9:$offset), asm>,
2956           Sched<[WriteLD]>;
2957
2958   def : InstAlias<asm # " $Rt, [$Rn]",
2959                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
2960 }
2961
2962 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
2963                              RegisterClass regtype, string asm> {
2964   let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
2965   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
2966                                  (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
2967                                  asm>,
2968           Sched<[WriteST]>;
2969
2970   def : InstAlias<asm # " $Rt, [$Rn]",
2971                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
2972 }
2973
2974 //---
2975 // Load/store pre-indexed
2976 //---
2977
2978 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2979                           string asm, string cstr, list<dag> pat>
2980     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
2981   bits<5> Rt;
2982   bits<5> Rn;
2983   bits<9> offset;
2984   let Inst{31-30} = sz;
2985   let Inst{29-27} = 0b111;
2986   let Inst{26}    = V;
2987   let Inst{25-24} = 0;
2988   let Inst{23-22} = opc;
2989   let Inst{21}    = 0;
2990   let Inst{20-12} = offset;
2991   let Inst{11-10} = 0b11;
2992   let Inst{9-5}   = Rn;
2993   let Inst{4-0}   = Rt;
2994
2995   let DecoderMethod = "DecodeSignedLdStInstruction";
2996 }
2997
2998 let hasSideEffects = 0 in {
2999 let mayStore = 0, mayLoad = 1 in
3000 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3001              string asm>
3002     : BaseLoadStorePreIdx<sz, V, opc,
3003                      (outs GPR64sp:$wback, regtype:$Rt),
3004                      (ins GPR64sp:$Rn, simm9:$offset), asm,
3005                      "$Rn = $wback,@earlyclobber $wback", []>,
3006       Sched<[WriteLD, WriteAdr]>;
3007
3008 let mayStore = 1, mayLoad = 0 in
3009 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3010                   string asm, SDPatternOperator storeop, ValueType Ty>
3011     : BaseLoadStorePreIdx<sz, V, opc,
3012                       (outs GPR64sp:$wback),
3013                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3014                       asm, "$Rn = $wback,@earlyclobber $wback",
3015       [(set GPR64sp:$wback,
3016             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3017       Sched<[WriteAdr, WriteST]>;
3018 } // hasSideEffects = 0
3019
3020 //---
3021 // Load/store post-indexed
3022 //---
3023
3024 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3025                           string asm, string cstr, list<dag> pat>
3026     : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
3027   bits<5> Rt;
3028   bits<5> Rn;
3029   bits<9> offset;
3030   let Inst{31-30} = sz;
3031   let Inst{29-27} = 0b111;
3032   let Inst{26}    = V;
3033   let Inst{25-24} = 0b00;
3034   let Inst{23-22} = opc;
3035   let Inst{21}    = 0b0;
3036   let Inst{20-12} = offset;
3037   let Inst{11-10} = 0b01;
3038   let Inst{9-5}   = Rn;
3039   let Inst{4-0}   = Rt;
3040
3041   let DecoderMethod = "DecodeSignedLdStInstruction";
3042 }
3043
3044 let hasSideEffects = 0 in {
3045 let mayStore = 0, mayLoad = 1 in
3046 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3047              string asm>
3048     : BaseLoadStorePostIdx<sz, V, opc,
3049                       (outs GPR64sp:$wback, regtype:$Rt),
3050                       (ins GPR64sp:$Rn, simm9:$offset),
3051                       asm, "$Rn = $wback,@earlyclobber $wback", []>,
3052       Sched<[WriteLD, WriteI]>;
3053
3054 let mayStore = 1, mayLoad = 0 in
3055 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3056                    string asm, SDPatternOperator storeop, ValueType Ty>
3057     : BaseLoadStorePostIdx<sz, V, opc,
3058                       (outs GPR64sp:$wback),
3059                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3060                        asm, "$Rn = $wback,@earlyclobber $wback",
3061       [(set GPR64sp:$wback,
3062             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3063     Sched<[WriteAdr, WriteST, ReadAdrBase]>;
3064 } // hasSideEffects = 0
3065
3066
3067 //---
3068 // Load/store pair
3069 //---
3070
3071 // (indexed, offset)
3072
3073 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
3074                               string asm>
3075     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3076   bits<5> Rt;
3077   bits<5> Rt2;
3078   bits<5> Rn;
3079   bits<7> offset;
3080   let Inst{31-30} = opc;
3081   let Inst{29-27} = 0b101;
3082   let Inst{26}    = V;
3083   let Inst{25-23} = 0b010;
3084   let Inst{22}    = L;
3085   let Inst{21-15} = offset;
3086   let Inst{14-10} = Rt2;
3087   let Inst{9-5}   = Rn;
3088   let Inst{4-0}   = Rt;
3089
3090   let DecoderMethod = "DecodePairLdStInstruction";
3091 }
3092
3093 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
3094                           Operand indextype, string asm> {
3095   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3096   def i : BaseLoadStorePairOffset<opc, V, 1,
3097                                   (outs regtype:$Rt, regtype:$Rt2),
3098                                   (ins GPR64sp:$Rn, indextype:$offset), asm>,
3099           Sched<[WriteLD, WriteLDHi]>;
3100
3101   def : InstAlias<asm # " $Rt, $Rt2, [$Rn]",
3102                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3103                                                   GPR64sp:$Rn, 0)>;
3104 }
3105
3106
3107 multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
3108                            Operand indextype, string asm> {
3109   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
3110   def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
3111                                   (ins regtype:$Rt, regtype:$Rt2,
3112                                        GPR64sp:$Rn, indextype:$offset),
3113                                   asm>,
3114           Sched<[WriteSTP]>;
3115
3116   def : InstAlias<asm # " $Rt, $Rt2, [$Rn]",
3117                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3118                                                   GPR64sp:$Rn, 0)>;
3119 }
3120
3121 // (pre-indexed)
3122 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3123                               string asm>
3124     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
3125   bits<5> Rt;
3126   bits<5> Rt2;
3127   bits<5> Rn;
3128   bits<7> offset;
3129   let Inst{31-30} = opc;
3130   let Inst{29-27} = 0b101;
3131   let Inst{26}    = V;
3132   let Inst{25-23} = 0b011;
3133   let Inst{22}    = L;
3134   let Inst{21-15} = offset;
3135   let Inst{14-10} = Rt2;
3136   let Inst{9-5}   = Rn;
3137   let Inst{4-0}   = Rt;
3138
3139   let DecoderMethod = "DecodePairLdStInstruction";
3140 }
3141
3142 let hasSideEffects = 0 in {
3143 let mayStore = 0, mayLoad = 1 in
3144 class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3145                      Operand indextype, string asm>
3146     : BaseLoadStorePairPreIdx<opc, V, 1,
3147                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3148                               (ins GPR64sp:$Rn, indextype:$offset), asm>,
3149       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3150
3151 let mayStore = 1, mayLoad = 0 in
3152 class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3153                       Operand indextype, string asm>
3154     : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
3155                              (ins regtype:$Rt, regtype:$Rt2,
3156                                   GPR64sp:$Rn, indextype:$offset),
3157                              asm>,
3158       Sched<[WriteAdr, WriteSTP]>;
3159 } // hasSideEffects = 0
3160
3161 // (post-indexed)
3162
3163 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3164                               string asm>
3165     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
3166   bits<5> Rt;
3167   bits<5> Rt2;
3168   bits<5> Rn;
3169   bits<7> offset;
3170   let Inst{31-30} = opc;
3171   let Inst{29-27} = 0b101;
3172   let Inst{26}    = V;
3173   let Inst{25-23} = 0b001;
3174   let Inst{22}    = L;
3175   let Inst{21-15} = offset;
3176   let Inst{14-10} = Rt2;
3177   let Inst{9-5}   = Rn;
3178   let Inst{4-0}   = Rt;
3179
3180   let DecoderMethod = "DecodePairLdStInstruction";
3181 }
3182
3183 let hasSideEffects = 0 in {
3184 let mayStore = 0, mayLoad = 1 in
3185 class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3186                       Operand idxtype, string asm>
3187     : BaseLoadStorePairPostIdx<opc, V, 1,
3188                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3189                               (ins GPR64sp:$Rn, idxtype:$offset), asm>,
3190       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3191
3192 let mayStore = 1, mayLoad = 0 in
3193 class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3194                        Operand idxtype, string asm>
3195     : BaseLoadStorePairPostIdx<opc, V, 0, (outs),
3196                              (ins GPR64sp:$wback, regtype:$Rt, regtype:$Rt2,
3197                                   GPR64sp:$Rn, idxtype:$offset),
3198                              asm>,
3199       Sched<[WriteAdr, WriteSTP]>;
3200 } // hasSideEffects = 0
3201
3202 //  (no-allocate)
3203
3204 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
3205                               string asm>
3206     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3207   bits<5> Rt;
3208   bits<5> Rt2;
3209   bits<5> Rn;
3210   bits<7> offset;
3211   let Inst{31-30} = opc;
3212   let Inst{29-27} = 0b101;
3213   let Inst{26}    = V;
3214   let Inst{25-23} = 0b000;
3215   let Inst{22}    = L;
3216   let Inst{21-15} = offset;
3217   let Inst{14-10} = Rt2;
3218   let Inst{9-5}   = Rn;
3219   let Inst{4-0}   = Rt;
3220
3221   let DecoderMethod = "DecodePairLdStInstruction";
3222 }
3223
3224 multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3225                            Operand indextype, string asm> {
3226   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3227   def i : BaseLoadStorePairNoAlloc<opc, V, 1,
3228                                    (outs regtype:$Rt, regtype:$Rt2),
3229                                    (ins GPR64sp:$Rn, indextype:$offset), asm>,
3230           Sched<[WriteLD, WriteLDHi]>;
3231
3232
3233   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3234                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3235                                                   GPR64sp:$Rn, 0)>;
3236 }
3237
3238 multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3239                       Operand indextype, string asm> {
3240   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
3241   def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
3242                                    (ins regtype:$Rt, regtype:$Rt2,
3243                                         GPR64sp:$Rn, indextype:$offset),
3244                                    asm>,
3245           Sched<[WriteSTP]>;
3246
3247   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3248                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3249                                                   GPR64sp:$Rn, 0)>;
3250 }
3251
3252 //---
3253 // Load/store exclusive
3254 //---
3255
3256 // True exclusive operations write to and/or read from the system's exclusive
3257 // monitors, which as far as a compiler is concerned can be modelled as a
3258 // random shared memory address. Hence LoadExclusive mayStore.
3259 //
3260 // Since these instructions have the undefined register bits set to 1 in
3261 // their canonical form, we need a post encoder method to set those bits
3262 // to 1 when encoding these instructions. We do this using the
3263 // fixLoadStoreExclusive function. This function has template parameters:
3264 //
3265 // fixLoadStoreExclusive<int hasRs, int hasRt2>
3266 //
3267 // hasRs indicates that the instruction uses the Rs field, so we won't set
3268 // it to 1 (and the same for Rt2). We don't need template parameters for
3269 // the other register fields since Rt and Rn are always used.
3270 //
3271 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
3272 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3273                              dag oops, dag iops, string asm, string operands>
3274     : I<oops, iops, asm, operands, "", []> {
3275   let Inst{31-30} = sz;
3276   let Inst{29-24} = 0b001000;
3277   let Inst{23}    = o2;
3278   let Inst{22}    = L;
3279   let Inst{21}    = o1;
3280   let Inst{15}    = o0;
3281
3282   let DecoderMethod = "DecodeExclusiveLdStInstruction";
3283 }
3284
3285 // Neither Rs nor Rt2 operands.
3286 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3287                                dag oops, dag iops, string asm, string operands>
3288     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
3289   bits<5> Rt;
3290   bits<5> Rn;
3291   let Inst{20-16} = 0b11111;
3292   let Unpredictable{20-16} = 0b11111;
3293   let Inst{14-10} = 0b11111;
3294   let Unpredictable{14-10} = 0b11111;
3295   let Inst{9-5} = Rn;
3296   let Inst{4-0} = Rt;
3297
3298   let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
3299 }
3300
3301 // Simple load acquires don't set the exclusive monitor
3302 let mayLoad = 1, mayStore = 0 in
3303 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3304                   RegisterClass regtype, string asm>
3305     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3306                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3307       Sched<[WriteLD]>;
3308
3309 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3310                     RegisterClass regtype, string asm>
3311     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3312                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3313       Sched<[WriteLD]>;
3314
3315 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3316                        RegisterClass regtype, string asm>
3317     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3318                              (outs regtype:$Rt, regtype:$Rt2),
3319                              (ins GPR64sp0:$Rn), asm,
3320                              "\t$Rt, $Rt2, [$Rn]">,
3321       Sched<[WriteLD, WriteLDHi]> {
3322   bits<5> Rt;
3323   bits<5> Rt2;
3324   bits<5> Rn;
3325   let Inst{14-10} = Rt2;
3326   let Inst{9-5} = Rn;
3327   let Inst{4-0} = Rt;
3328
3329   let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
3330 }
3331
3332 // Simple store release operations do not check the exclusive monitor.
3333 let mayLoad = 0, mayStore = 1 in
3334 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3335                    RegisterClass regtype, string asm>
3336     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
3337                                (ins regtype:$Rt, GPR64sp0:$Rn),
3338                                asm, "\t$Rt, [$Rn]">,
3339       Sched<[WriteST]>;
3340
3341 let mayLoad = 1, mayStore = 1 in
3342 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3343                      RegisterClass regtype, string asm>
3344     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
3345                              (ins regtype:$Rt, GPR64sp0:$Rn),
3346                              asm, "\t$Ws, $Rt, [$Rn]">,
3347       Sched<[WriteSTX]> {
3348   bits<5> Ws;
3349   bits<5> Rt;
3350   bits<5> Rn;
3351   let Inst{20-16} = Ws;
3352   let Inst{9-5} = Rn;
3353   let Inst{4-0} = Rt;
3354
3355   let Constraints = "@earlyclobber $Ws";
3356   let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
3357 }
3358
3359 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3360                          RegisterClass regtype, string asm>
3361     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3362                              (outs GPR32:$Ws),
3363                              (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
3364                               asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
3365       Sched<[WriteSTX]> {
3366   bits<5> Ws;
3367   bits<5> Rt;
3368   bits<5> Rt2;
3369   bits<5> Rn;
3370   let Inst{20-16} = Ws;
3371   let Inst{14-10} = Rt2;
3372   let Inst{9-5} = Rn;
3373   let Inst{4-0} = Rt;
3374
3375   let Constraints = "@earlyclobber $Ws";
3376 }
3377
3378 //---
3379 // Exception generation
3380 //---
3381
3382 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3383 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
3384     : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
3385       Sched<[WriteSys]> {
3386   bits<16> imm;
3387   let Inst{31-24} = 0b11010100;
3388   let Inst{23-21} = op1;
3389   let Inst{20-5}  = imm;
3390   let Inst{4-2}   = 0b000;
3391   let Inst{1-0}   = ll;
3392 }
3393
3394 let Predicates = [HasFPARMv8] in {
3395
3396 //---
3397 // Floating point to integer conversion
3398 //---
3399
3400 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
3401                       RegisterClass srcType, RegisterClass dstType,
3402                       string asm, list<dag> pattern>
3403     : I<(outs dstType:$Rd), (ins srcType:$Rn),
3404          asm, "\t$Rd, $Rn", "", pattern>,
3405       Sched<[WriteFCvt]> {
3406   bits<5> Rd;
3407   bits<5> Rn;
3408   let Inst{30-29} = 0b00;
3409   let Inst{28-24} = 0b11110;
3410   let Inst{23-22} = type;
3411   let Inst{21}    = 1;
3412   let Inst{20-19} = rmode;
3413   let Inst{18-16} = opcode;
3414   let Inst{15-10} = 0;
3415   let Inst{9-5}   = Rn;
3416   let Inst{4-0}   = Rd;
3417 }
3418
3419 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3420 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
3421                       RegisterClass srcType, RegisterClass dstType,
3422                       Operand immType, string asm, list<dag> pattern>
3423     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3424          asm, "\t$Rd, $Rn, $scale", "", pattern>,
3425       Sched<[WriteFCvt]> {
3426   bits<5> Rd;
3427   bits<5> Rn;
3428   bits<6> scale;
3429   let Inst{30-29} = 0b00;
3430   let Inst{28-24} = 0b11110;
3431   let Inst{23-22} = type;
3432   let Inst{21}    = 0;
3433   let Inst{20-19} = rmode;
3434   let Inst{18-16} = opcode;
3435   let Inst{15-10} = scale;
3436   let Inst{9-5}   = Rn;
3437   let Inst{4-0}   = Rd;
3438 }
3439
3440 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
3441            SDPatternOperator OpN> {
3442   // Unscaled single-precision to 32-bit
3443   def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
3444                                      [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
3445     let Inst{31} = 0; // 32-bit GPR flag
3446   }
3447
3448   // Unscaled single-precision to 64-bit
3449   def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
3450                                      [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
3451     let Inst{31} = 1; // 64-bit GPR flag
3452   }
3453
3454   // Unscaled double-precision to 32-bit
3455   def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
3456                                      [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3457     let Inst{31} = 0; // 32-bit GPR flag
3458   }
3459
3460   // Unscaled double-precision to 64-bit
3461   def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
3462                                      [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3463     let Inst{31} = 1; // 64-bit GPR flag
3464   }
3465 }
3466
3467 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
3468                              SDPatternOperator OpN> {
3469   // Scaled single-precision to 32-bit
3470   def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
3471                               fixedpoint_f32_i32, asm,
3472               [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
3473                                           fixedpoint_f32_i32:$scale)))]> {
3474     let Inst{31} = 0; // 32-bit GPR flag
3475     let scale{5} = 1;
3476   }
3477
3478   // Scaled single-precision to 64-bit
3479   def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
3480                               fixedpoint_f32_i64, asm,
3481               [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
3482                                           fixedpoint_f32_i64:$scale)))]> {
3483     let Inst{31} = 1; // 64-bit GPR flag
3484   }
3485
3486   // Scaled double-precision to 32-bit
3487   def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
3488                               fixedpoint_f64_i32, asm,
3489               [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
3490                                           fixedpoint_f64_i32:$scale)))]> {
3491     let Inst{31} = 0; // 32-bit GPR flag
3492     let scale{5} = 1;
3493   }
3494
3495   // Scaled double-precision to 64-bit
3496   def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
3497                               fixedpoint_f64_i64, asm,
3498               [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
3499                                           fixedpoint_f64_i64:$scale)))]> {
3500     let Inst{31} = 1; // 64-bit GPR flag
3501   }
3502 }
3503
3504 //---
3505 // Integer to floating point conversion
3506 //---
3507
3508 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
3509 class BaseIntegerToFP<bit isUnsigned,
3510                       RegisterClass srcType, RegisterClass dstType,
3511                       Operand immType, string asm, list<dag> pattern>
3512     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3513          asm, "\t$Rd, $Rn, $scale", "", pattern>,
3514       Sched<[WriteFCvt]> {
3515   bits<5> Rd;
3516   bits<5> Rn;
3517   bits<6> scale;
3518   let Inst{30-23} = 0b00111100;
3519   let Inst{21-17} = 0b00001;
3520   let Inst{16}    = isUnsigned;
3521   let Inst{15-10} = scale;
3522   let Inst{9-5}   = Rn;
3523   let Inst{4-0}   = Rd;
3524 }
3525
3526 class BaseIntegerToFPUnscaled<bit isUnsigned,
3527                       RegisterClass srcType, RegisterClass dstType,
3528                       ValueType dvt, string asm, SDNode node>
3529     : I<(outs dstType:$Rd), (ins srcType:$Rn),
3530          asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
3531       Sched<[WriteFCvt]> {
3532   bits<5> Rd;
3533   bits<5> Rn;
3534   bits<6> scale;
3535   let Inst{30-23} = 0b00111100;
3536   let Inst{21-17} = 0b10001;
3537   let Inst{16}    = isUnsigned;
3538   let Inst{15-10} = 0b000000;
3539   let Inst{9-5}   = Rn;
3540   let Inst{4-0}   = Rd;
3541 }
3542
3543 multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
3544   // Unscaled
3545   def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
3546     let Inst{31} = 0; // 32-bit GPR flag
3547     let Inst{22} = 0; // 32-bit FPR flag
3548   }
3549
3550   def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
3551     let Inst{31} = 0; // 32-bit GPR flag
3552     let Inst{22} = 1; // 64-bit FPR flag
3553   }
3554
3555   def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
3556     let Inst{31} = 1; // 64-bit GPR flag
3557     let Inst{22} = 0; // 32-bit FPR flag
3558   }
3559
3560   def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
3561     let Inst{31} = 1; // 64-bit GPR flag
3562     let Inst{22} = 1; // 64-bit FPR flag
3563   }
3564
3565   // Scaled
3566   def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
3567                              [(set FPR32:$Rd,
3568                                    (fdiv (node GPR32:$Rn),
3569                                          fixedpoint_f32_i32:$scale))]> {
3570     let Inst{31} = 0; // 32-bit GPR flag
3571     let Inst{22} = 0; // 32-bit FPR flag
3572     let scale{5} = 1;
3573   }
3574
3575   def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
3576                              [(set FPR64:$Rd,
3577                                    (fdiv (node GPR32:$Rn),
3578                                          fixedpoint_f64_i32:$scale))]> {
3579     let Inst{31} = 0; // 32-bit GPR flag
3580     let Inst{22} = 1; // 64-bit FPR flag
3581     let scale{5} = 1;
3582   }
3583
3584   def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
3585                              [(set FPR32:$Rd,
3586                                    (fdiv (node GPR64:$Rn),
3587                                          fixedpoint_f32_i64:$scale))]> {
3588     let Inst{31} = 1; // 64-bit GPR flag
3589     let Inst{22} = 0; // 32-bit FPR flag
3590   }
3591
3592   def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
3593                              [(set FPR64:$Rd,
3594                                    (fdiv (node GPR64:$Rn),
3595                                          fixedpoint_f64_i64:$scale))]> {
3596     let Inst{31} = 1; // 64-bit GPR flag
3597     let Inst{22} = 1; // 64-bit FPR flag
3598   }
3599 }
3600
3601 //---
3602 // Unscaled integer <-> floating point conversion (i.e. FMOV)
3603 //---
3604
3605 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3606 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
3607                       RegisterClass srcType, RegisterClass dstType,
3608                       string asm>
3609     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
3610         // We use COPY_TO_REGCLASS for these bitconvert operations.
3611         // copyPhysReg() expands the resultant COPY instructions after
3612         // regalloc is done. This gives greater freedom for the allocator
3613         // and related passes (coalescing, copy propagation, et. al.) to
3614         // be more effective.
3615         [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
3616       Sched<[WriteFCopy]> {
3617   bits<5> Rd;
3618   bits<5> Rn;
3619   let Inst{30-23} = 0b00111100;
3620   let Inst{21}    = 1;
3621   let Inst{20-19} = rmode;
3622   let Inst{18-16} = opcode;
3623   let Inst{15-10} = 0b000000;
3624   let Inst{9-5}   = Rn;
3625   let Inst{4-0}   = Rd;
3626 }
3627
3628 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3629 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
3630                      RegisterClass srcType, RegisterOperand dstType, string asm,
3631                      string kind>
3632     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3633         "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
3634       Sched<[WriteFCopy]> {
3635   bits<5> Rd;
3636   bits<5> Rn;
3637   let Inst{30-23} = 0b00111101;
3638   let Inst{21}    = 1;
3639   let Inst{20-19} = rmode;
3640   let Inst{18-16} = opcode;
3641   let Inst{15-10} = 0b000000;
3642   let Inst{9-5}   = Rn;
3643   let Inst{4-0}   = Rd;
3644
3645   let DecoderMethod =  "DecodeFMOVLaneInstruction";
3646 }
3647
3648 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3649 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
3650                      RegisterOperand srcType, RegisterClass dstType, string asm,
3651                      string kind>
3652     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3653         "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
3654       Sched<[WriteFCopy]> {
3655   bits<5> Rd;
3656   bits<5> Rn;
3657   let Inst{30-23} = 0b00111101;
3658   let Inst{21}    = 1;
3659   let Inst{20-19} = rmode;
3660   let Inst{18-16} = opcode;
3661   let Inst{15-10} = 0b000000;
3662   let Inst{9-5}   = Rn;
3663   let Inst{4-0}   = Rd;
3664
3665   let DecoderMethod =  "DecodeFMOVLaneInstruction";
3666 }
3667
3668
3669
3670 multiclass UnscaledConversion<string asm> {
3671   def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
3672     let Inst{31} = 0; // 32-bit GPR flag
3673     let Inst{22} = 0; // 32-bit FPR flag
3674   }
3675
3676   def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
3677     let Inst{31} = 1; // 64-bit GPR flag
3678     let Inst{22} = 1; // 64-bit FPR flag
3679   }
3680
3681   def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
3682     let Inst{31} = 0; // 32-bit GPR flag
3683     let Inst{22} = 0; // 32-bit FPR flag
3684   }
3685
3686   def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
3687     let Inst{31} = 1; // 64-bit GPR flag
3688     let Inst{22} = 1; // 64-bit FPR flag
3689   }
3690
3691   def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
3692                                              asm, ".d"> {
3693     let Inst{31} = 1;
3694     let Inst{22} = 0;
3695   }
3696
3697   def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
3698                                                asm, ".d"> {
3699     let Inst{31} = 1;
3700     let Inst{22} = 0;
3701   }
3702 }
3703
3704 //---
3705 // Floating point conversion
3706 //---
3707
3708 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
3709                        RegisterClass srcType, string asm, list<dag> pattern>
3710     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
3711       Sched<[WriteFCvt]> {
3712   bits<5> Rd;
3713   bits<5> Rn;
3714   let Inst{31-24} = 0b00011110;
3715   let Inst{23-22} = type;
3716   let Inst{21-17} = 0b10001;
3717   let Inst{16-15} = opcode;
3718   let Inst{14-10} = 0b10000;
3719   let Inst{9-5}   = Rn;
3720   let Inst{4-0}   = Rd;
3721 }
3722
3723 multiclass FPConversion<string asm> {
3724   // Double-precision to Half-precision
3725   def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
3726                              [(set FPR16:$Rd, (fround FPR64:$Rn))]>;
3727
3728   // Double-precision to Single-precision
3729   def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
3730                              [(set FPR32:$Rd, (fround FPR64:$Rn))]>;
3731
3732   // Half-precision to Double-precision
3733   def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
3734                              [(set FPR64:$Rd, (fextend FPR16:$Rn))]>;
3735
3736   // Half-precision to Single-precision
3737   def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
3738                              [(set FPR32:$Rd, (fextend FPR16:$Rn))]>;
3739
3740   // Single-precision to Double-precision
3741   def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
3742                              [(set FPR64:$Rd, (fextend FPR32:$Rn))]>;
3743
3744   // Single-precision to Half-precision
3745   def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
3746                              [(set FPR16:$Rd, (fround FPR32:$Rn))]>;
3747 }
3748
3749 //---
3750 // Single operand floating point data processing
3751 //---
3752
3753 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3754 class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
3755                               ValueType vt, string asm, SDPatternOperator node>
3756     : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
3757          [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
3758       Sched<[WriteF]> {
3759   bits<5> Rd;
3760   bits<5> Rn;
3761   let Inst{31-23} = 0b000111100;
3762   let Inst{21-19} = 0b100;
3763   let Inst{18-15} = opcode;
3764   let Inst{14-10} = 0b10000;
3765   let Inst{9-5}   = Rn;
3766   let Inst{4-0}   = Rd;
3767 }
3768
3769 multiclass SingleOperandFPData<bits<4> opcode, string asm,
3770                                SDPatternOperator node = null_frag> {
3771   def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
3772     let Inst{22} = 0; // 32-bit size flag
3773   }
3774
3775   def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
3776     let Inst{22} = 1; // 64-bit size flag
3777   }
3778 }
3779
3780 //---
3781 // Two operand floating point data processing
3782 //---
3783
3784 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3785 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
3786                            string asm, list<dag> pat>
3787     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
3788          asm, "\t$Rd, $Rn, $Rm", "", pat>,
3789       Sched<[WriteF]> {
3790   bits<5> Rd;
3791   bits<5> Rn;
3792   bits<5> Rm;
3793   let Inst{31-23} = 0b000111100;
3794   let Inst{21}    = 1;
3795   let Inst{20-16} = Rm;
3796   let Inst{15-12} = opcode;
3797   let Inst{11-10} = 0b10;
3798   let Inst{9-5}   = Rn;
3799   let Inst{4-0}   = Rd;
3800 }
3801
3802 multiclass TwoOperandFPData<bits<4> opcode, string asm,
3803                             SDPatternOperator node = null_frag> {
3804   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3805                          [(set (f32 FPR32:$Rd),
3806                                (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
3807     let Inst{22} = 0; // 32-bit size flag
3808   }
3809
3810   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3811                          [(set (f64 FPR64:$Rd),
3812                                (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
3813     let Inst{22} = 1; // 64-bit size flag
3814   }
3815 }
3816
3817 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
3818   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3819                   [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
3820     let Inst{22} = 0; // 32-bit size flag
3821   }
3822
3823   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3824                   [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
3825     let Inst{22} = 1; // 64-bit size flag
3826   }
3827 }
3828
3829
3830 //---
3831 // Three operand floating point data processing
3832 //---
3833
3834 class BaseThreeOperandFPData<bit isNegated, bit isSub,
3835                              RegisterClass regtype, string asm, list<dag> pat>
3836     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
3837          asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
3838       Sched<[WriteFMul]> {
3839   bits<5> Rd;
3840   bits<5> Rn;
3841   bits<5> Rm;
3842   bits<5> Ra;
3843   let Inst{31-23} = 0b000111110;
3844   let Inst{21}    = isNegated;
3845   let Inst{20-16} = Rm;
3846   let Inst{15}    = isSub;
3847   let Inst{14-10} = Ra;
3848   let Inst{9-5}   = Rn;
3849   let Inst{4-0}   = Rd;
3850 }
3851
3852 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
3853                               SDPatternOperator node> {
3854   def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
3855             [(set FPR32:$Rd,
3856                   (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
3857     let Inst{22} = 0; // 32-bit size flag
3858   }
3859
3860   def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
3861             [(set FPR64:$Rd,
3862                   (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
3863     let Inst{22} = 1; // 64-bit size flag
3864   }
3865 }
3866
3867 //---
3868 // Floating point data comparisons
3869 //---
3870
3871 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3872 class BaseOneOperandFPComparison<bit signalAllNans,
3873                                  RegisterClass regtype, string asm,
3874                                  list<dag> pat>
3875     : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
3876       Sched<[WriteFCmp]> {
3877   bits<5> Rn;
3878   let Inst{31-23} = 0b000111100;
3879   let Inst{21}    = 1;
3880
3881   let Inst{15-10} = 0b001000;
3882   let Inst{9-5}   = Rn;
3883   let Inst{4}     = signalAllNans;
3884   let Inst{3-0}   = 0b1000;
3885
3886   // Rm should be 0b00000 canonically, but we need to accept any value.
3887   let PostEncoderMethod = "fixOneOperandFPComparison";
3888 }
3889
3890 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3891 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
3892                                 string asm, list<dag> pat>
3893     : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
3894       Sched<[WriteFCmp]> {
3895   bits<5> Rm;
3896   bits<5> Rn;
3897   let Inst{31-23} = 0b000111100;
3898   let Inst{21}    = 1;
3899   let Inst{20-16} = Rm;
3900   let Inst{15-10} = 0b001000;
3901   let Inst{9-5}   = Rn;
3902   let Inst{4}     = signalAllNans;
3903   let Inst{3-0}   = 0b0000;
3904 }
3905
3906 multiclass FPComparison<bit signalAllNans, string asm,
3907                         SDPatternOperator OpNode = null_frag> {
3908   let Defs = [NZCV] in {
3909   def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
3910       [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
3911     let Inst{22} = 0;
3912   }
3913
3914   def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
3915       [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
3916     let Inst{22} = 0;
3917   }
3918
3919   def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
3920       [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
3921     let Inst{22} = 1;
3922   }
3923
3924   def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
3925       [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
3926     let Inst{22} = 1;
3927   }
3928   } // Defs = [NZCV]
3929 }
3930
3931 //---
3932 // Floating point conditional comparisons
3933 //---
3934
3935 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3936 class BaseFPCondComparison<bit signalAllNans,
3937                               RegisterClass regtype, string asm>
3938     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm0_15:$nzcv, ccode:$cond),
3939          asm, "\t$Rn, $Rm, $nzcv, $cond", "", []>,
3940       Sched<[WriteFCmp]> {
3941   bits<5> Rn;
3942   bits<5> Rm;
3943   bits<4> nzcv;
3944   bits<4> cond;
3945
3946   let Inst{31-23} = 0b000111100;
3947   let Inst{21}    = 1;
3948   let Inst{20-16} = Rm;
3949   let Inst{15-12} = cond;
3950   let Inst{11-10} = 0b01;
3951   let Inst{9-5}   = Rn;
3952   let Inst{4}     = signalAllNans;
3953   let Inst{3-0}   = nzcv;
3954 }
3955
3956 multiclass FPCondComparison<bit signalAllNans, string asm> {
3957   let Defs = [NZCV], Uses = [NZCV] in {
3958   def Srr : BaseFPCondComparison<signalAllNans, FPR32, asm> {
3959     let Inst{22} = 0;
3960   }
3961
3962   def Drr : BaseFPCondComparison<signalAllNans, FPR64, asm> {
3963     let Inst{22} = 1;
3964   }
3965   } // Defs = [NZCV], Uses = [NZCV]
3966 }
3967
3968 //---
3969 // Floating point conditional select
3970 //---
3971
3972 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
3973     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
3974          asm, "\t$Rd, $Rn, $Rm, $cond", "",
3975          [(set regtype:$Rd,
3976                (AArch64csel (vt regtype:$Rn), regtype:$Rm,
3977                           (i32 imm:$cond), NZCV))]>,
3978       Sched<[WriteF]> {
3979   bits<5> Rd;
3980   bits<5> Rn;
3981   bits<5> Rm;
3982   bits<4> cond;
3983
3984   let Inst{31-23} = 0b000111100;
3985   let Inst{21}    = 1;
3986   let Inst{20-16} = Rm;
3987   let Inst{15-12} = cond;
3988   let Inst{11-10} = 0b11;
3989   let Inst{9-5}   = Rn;
3990   let Inst{4-0}   = Rd;
3991 }
3992
3993 multiclass FPCondSelect<string asm> {
3994   let Uses = [NZCV] in {
3995   def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
3996     let Inst{22} = 0;
3997   }
3998
3999   def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
4000     let Inst{22} = 1;
4001   }
4002   } // Uses = [NZCV]
4003 }
4004
4005 //---
4006 // Floating move immediate
4007 //---
4008
4009 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
4010   : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
4011       [(set regtype:$Rd, fpimmtype:$imm)]>,
4012     Sched<[WriteFImm]> {
4013   bits<5> Rd;
4014   bits<8> imm;
4015   let Inst{31-23} = 0b000111100;
4016   let Inst{21}    = 1;
4017   let Inst{20-13} = imm;
4018   let Inst{12-5}  = 0b10000000;
4019   let Inst{4-0}   = Rd;
4020 }
4021
4022 multiclass FPMoveImmediate<string asm> {
4023   def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
4024     let Inst{22} = 0;
4025   }
4026
4027   def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
4028     let Inst{22} = 1;
4029   }
4030 }
4031 } // end of 'let Predicates = [HasFPARMv8]'
4032
4033 //----------------------------------------------------------------------------
4034 // AdvSIMD
4035 //----------------------------------------------------------------------------
4036
4037 let Predicates = [HasNEON] in {
4038
4039 //----------------------------------------------------------------------------
4040 // AdvSIMD three register vector instructions
4041 //----------------------------------------------------------------------------
4042
4043 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4044 class BaseSIMDThreeSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4045                         RegisterOperand regtype, string asm, string kind,
4046                         list<dag> pattern>
4047   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4048       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4049       "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
4050     Sched<[WriteV]> {
4051   bits<5> Rd;
4052   bits<5> Rn;
4053   bits<5> Rm;
4054   let Inst{31}    = 0;
4055   let Inst{30}    = Q;
4056   let Inst{29}    = U;
4057   let Inst{28-24} = 0b01110;
4058   let Inst{23-22} = size;
4059   let Inst{21}    = 1;
4060   let Inst{20-16} = Rm;
4061   let Inst{15-11} = opcode;
4062   let Inst{10}    = 1;
4063   let Inst{9-5}   = Rn;
4064   let Inst{4-0}   = Rd;
4065 }
4066
4067 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4068 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4069                         RegisterOperand regtype, string asm, string kind,
4070                         list<dag> pattern>
4071   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
4072       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4073       "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4074     Sched<[WriteV]> {
4075   bits<5> Rd;
4076   bits<5> Rn;
4077   bits<5> Rm;
4078   let Inst{31}    = 0;
4079   let Inst{30}    = Q;
4080   let Inst{29}    = U;
4081   let Inst{28-24} = 0b01110;
4082   let Inst{23-22} = size;
4083   let Inst{21}    = 1;
4084   let Inst{20-16} = Rm;
4085   let Inst{15-11} = opcode;
4086   let Inst{10}    = 1;
4087   let Inst{9-5}   = Rn;
4088   let Inst{4-0}   = Rd;
4089 }
4090
4091 // All operand sizes distinguished in the encoding.
4092 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
4093                                SDPatternOperator OpNode> {
4094   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4095                                       asm, ".8b",
4096          [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4097   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4098                                       asm, ".16b",
4099          [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4100   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4101                                       asm, ".4h",
4102          [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4103   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4104                                       asm, ".8h",
4105          [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4106   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4107                                       asm, ".2s",
4108          [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4109   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4110                                       asm, ".4s",
4111          [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4112   def v2i64 : BaseSIMDThreeSameVector<1, U, 0b11, opc, V128,
4113                                       asm, ".2d",
4114          [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4115 }
4116
4117 // As above, but D sized elements unsupported.
4118 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
4119                                   SDPatternOperator OpNode> {
4120   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4121                                       asm, ".8b",
4122         [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
4123   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4124                                       asm, ".16b",
4125         [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
4126   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4127                                       asm, ".4h",
4128         [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
4129   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4130                                       asm, ".8h",
4131         [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
4132   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4133                                       asm, ".2s",
4134         [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
4135   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4136                                       asm, ".4s",
4137         [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
4138 }
4139
4140 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
4141                                   SDPatternOperator OpNode> {
4142   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, 0b00, opc, V64,
4143                                       asm, ".8b",
4144       [(set (v8i8 V64:$dst),
4145             (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4146   def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b00, opc, V128,
4147                                       asm, ".16b",
4148       [(set (v16i8 V128:$dst),
4149             (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4150   def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b01, opc, V64,
4151                                       asm, ".4h",
4152       [(set (v4i16 V64:$dst),
4153             (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4154   def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b01, opc, V128,
4155                                       asm, ".8h",
4156       [(set (v8i16 V128:$dst),
4157             (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4158   def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b10, opc, V64,
4159                                       asm, ".2s",
4160       [(set (v2i32 V64:$dst),
4161             (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4162   def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b10, opc, V128,
4163                                       asm, ".4s",
4164       [(set (v4i32 V128:$dst),
4165             (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4166 }
4167
4168 // As above, but only B sized elements supported.
4169 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
4170                                 SDPatternOperator OpNode> {
4171   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4172                                       asm, ".8b",
4173     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4174   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4175                                       asm, ".16b",
4176     [(set (v16i8 V128:$Rd),
4177           (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4178 }
4179
4180 // As above, but only S and D sized floating point elements supported.
4181 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<5> opc,
4182                                  string asm, SDPatternOperator OpNode> {
4183   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
4184                                       asm, ".2s",
4185         [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4186   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
4187                                       asm, ".4s",
4188         [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4189   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
4190                                       asm, ".2d",
4191         [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4192 }
4193
4194 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<5> opc,
4195                                     string asm,
4196                                     SDPatternOperator OpNode> {
4197   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
4198                                       asm, ".2s",
4199         [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4200   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
4201                                       asm, ".4s",
4202         [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4203   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
4204                                       asm, ".2d",
4205         [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4206 }
4207
4208 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<5> opc,
4209                                  string asm, SDPatternOperator OpNode> {
4210   def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0}, opc, V64,
4211                                       asm, ".2s",
4212      [(set (v2f32 V64:$dst),
4213            (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4214   def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0}, opc, V128,
4215                                       asm, ".4s",
4216      [(set (v4f32 V128:$dst),
4217            (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4218   def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,1}, opc, V128,
4219                                       asm, ".2d",
4220      [(set (v2f64 V128:$dst),
4221            (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4222 }
4223
4224 // As above, but D and B sized elements unsupported.
4225 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
4226                                 SDPatternOperator OpNode> {
4227   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4228                                       asm, ".4h",
4229         [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4230   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4231                                       asm, ".8h",
4232         [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4233   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4234                                       asm, ".2s",
4235         [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4236   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4237                                       asm, ".4s",
4238         [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4239 }
4240
4241 // Logical three vector ops share opcode bits, and only use B sized elements.
4242 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
4243                                   SDPatternOperator OpNode = null_frag> {
4244   def v8i8  : BaseSIMDThreeSameVector<0, U, size, 0b00011, V64,
4245                                      asm, ".8b",
4246                          [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
4247   def v16i8  : BaseSIMDThreeSameVector<1, U, size, 0b00011, V128,
4248                                      asm, ".16b",
4249                          [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
4250
4251   def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
4252           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4253   def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
4254           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4255   def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
4256           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4257
4258   def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
4259       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4260   def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
4261       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4262   def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
4263       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4264 }
4265
4266 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
4267                                   string asm, SDPatternOperator OpNode> {
4268   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, size, 0b00011, V64,
4269                                      asm, ".8b",
4270              [(set (v8i8 V64:$dst),
4271                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4272   def v16i8  : BaseSIMDThreeSameVectorTied<1, U, size, 0b00011, V128,
4273                                      asm, ".16b",
4274              [(set (v16i8 V128:$dst),
4275                    (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
4276                            (v16i8 V128:$Rm)))]>;
4277
4278   def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
4279                            (v4i16 V64:$RHS))),
4280           (!cast<Instruction>(NAME#"v8i8")
4281             V64:$LHS, V64:$MHS, V64:$RHS)>;
4282   def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
4283                            (v2i32 V64:$RHS))),
4284           (!cast<Instruction>(NAME#"v8i8")
4285             V64:$LHS, V64:$MHS, V64:$RHS)>;
4286   def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
4287                            (v1i64 V64:$RHS))),
4288           (!cast<Instruction>(NAME#"v8i8")
4289             V64:$LHS, V64:$MHS, V64:$RHS)>;
4290
4291   def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
4292                            (v8i16 V128:$RHS))),
4293       (!cast<Instruction>(NAME#"v16i8")
4294         V128:$LHS, V128:$MHS, V128:$RHS)>;
4295   def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
4296                            (v4i32 V128:$RHS))),
4297       (!cast<Instruction>(NAME#"v16i8")
4298         V128:$LHS, V128:$MHS, V128:$RHS)>;
4299   def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
4300                            (v2i64 V128:$RHS))),
4301       (!cast<Instruction>(NAME#"v16i8")
4302         V128:$LHS, V128:$MHS, V128:$RHS)>;
4303 }
4304
4305
4306 //----------------------------------------------------------------------------
4307 // AdvSIMD two register vector instructions.
4308 //----------------------------------------------------------------------------
4309
4310 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4311 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4312                         RegisterOperand regtype, string asm, string dstkind,
4313                         string srckind, list<dag> pattern>
4314   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4315       "{\t$Rd" # dstkind # ", $Rn" # srckind #
4316       "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
4317     Sched<[WriteV]> {
4318   bits<5> Rd;
4319   bits<5> Rn;
4320   let Inst{31}    = 0;
4321   let Inst{30}    = Q;
4322   let Inst{29}    = U;
4323   let Inst{28-24} = 0b01110;
4324   let Inst{23-22} = size;
4325   let Inst{21-17} = 0b10000;
4326   let Inst{16-12} = opcode;
4327   let Inst{11-10} = 0b10;
4328   let Inst{9-5}   = Rn;
4329   let Inst{4-0}   = Rd;
4330 }
4331
4332 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4333 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4334                             RegisterOperand regtype, string asm, string dstkind,
4335                             string srckind, list<dag> pattern>
4336   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
4337       "{\t$Rd" # dstkind # ", $Rn" # srckind #
4338       "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4339     Sched<[WriteV]> {
4340   bits<5> Rd;
4341   bits<5> Rn;
4342   let Inst{31}    = 0;
4343   let Inst{30}    = Q;
4344   let Inst{29}    = U;
4345   let Inst{28-24} = 0b01110;
4346   let Inst{23-22} = size;
4347   let Inst{21-17} = 0b10000;
4348   let Inst{16-12} = opcode;
4349   let Inst{11-10} = 0b10;
4350   let Inst{9-5}   = Rn;
4351   let Inst{4-0}   = Rd;
4352 }
4353
4354 // Supports B, H, and S element sizes.
4355 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
4356                             SDPatternOperator OpNode> {
4357   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4358                                       asm, ".8b", ".8b",
4359                           [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4360   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4361                                       asm, ".16b", ".16b",
4362                           [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4363   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4364                                       asm, ".4h", ".4h",
4365                           [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4366   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4367                                       asm, ".8h", ".8h",
4368                           [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4369   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4370                                       asm, ".2s", ".2s",
4371                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4372   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4373                                       asm, ".4s", ".4s",
4374                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4375 }
4376
4377 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
4378                             RegisterOperand regtype, string asm, string dstkind,
4379                             string srckind, string amount>
4380   : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
4381       "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
4382       "|" # dstkind # "\t$Rd, $Rn, #" #  amount # "}", "", []>,
4383     Sched<[WriteV]> {
4384   bits<5> Rd;
4385   bits<5> Rn;
4386   let Inst{31}    = 0;
4387   let Inst{30}    = Q;
4388   let Inst{29-24} = 0b101110;
4389   let Inst{23-22} = size;
4390   let Inst{21-10} = 0b100001001110;
4391   let Inst{9-5}   = Rn;
4392   let Inst{4-0}   = Rd;
4393 }
4394
4395 multiclass SIMDVectorLShiftLongBySizeBHS {
4396   let hasSideEffects = 0 in {
4397   def v8i8  : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
4398                                              "shll", ".8h",  ".8b", "8">;
4399   def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
4400                                              "shll2", ".8h", ".16b", "8">;
4401   def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
4402                                              "shll", ".4s",  ".4h", "16">;
4403   def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
4404                                              "shll2", ".4s", ".8h", "16">;
4405   def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
4406                                              "shll", ".2d",  ".2s", "32">;
4407   def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
4408                                              "shll2", ".2d", ".4s", "32">;
4409   }
4410 }
4411
4412 // Supports all element sizes.
4413 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
4414                              SDPatternOperator OpNode> {
4415   def v8i8_v4i16  : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4416                                       asm, ".4h", ".8b",
4417                [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4418   def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4419                                       asm, ".8h", ".16b",
4420                [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4421   def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4422                                       asm, ".2s", ".4h",
4423                [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4424   def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4425                                       asm, ".4s", ".8h",
4426                [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4427   def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4428                                       asm, ".1d", ".2s",
4429                [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4430   def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4431                                       asm, ".2d", ".4s",
4432                [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4433 }
4434
4435 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
4436                                  SDPatternOperator OpNode> {
4437   def v8i8_v4i16  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4438                                           asm, ".4h", ".8b",
4439       [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
4440                                       (v8i8 V64:$Rn)))]>;
4441   def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4442                                           asm, ".8h", ".16b",
4443       [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
4444                                       (v16i8 V128:$Rn)))]>;
4445   def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4446                                           asm, ".2s", ".4h",
4447       [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
4448                                       (v4i16 V64:$Rn)))]>;
4449   def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4450                                           asm, ".4s", ".8h",
4451       [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
4452                                       (v8i16 V128:$Rn)))]>;
4453   def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4454                                           asm, ".1d", ".2s",
4455       [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
4456                                       (v2i32 V64:$Rn)))]>;
4457   def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4458                                           asm, ".2d", ".4s",
4459       [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
4460                                       (v4i32 V128:$Rn)))]>;
4461 }
4462
4463 // Supports all element sizes, except 1xD.
4464 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
4465                                   SDPatternOperator OpNode> {
4466   def v8i8  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4467                                     asm, ".8b", ".8b",
4468     [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
4469   def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4470                                     asm, ".16b", ".16b",
4471     [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
4472   def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4473                                     asm, ".4h", ".4h",
4474     [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
4475   def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4476                                     asm, ".8h", ".8h",
4477     [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
4478   def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4479                                     asm, ".2s", ".2s",
4480     [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
4481   def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4482                                     asm, ".4s", ".4s",
4483     [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
4484   def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, V128,
4485                                     asm, ".2d", ".2d",
4486     [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
4487 }
4488
4489 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
4490                              SDPatternOperator OpNode = null_frag> {
4491   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4492                                 asm, ".8b", ".8b",
4493     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4494   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4495                                 asm, ".16b", ".16b",
4496     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4497   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4498                                 asm, ".4h", ".4h",
4499     [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4500   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4501                                 asm, ".8h", ".8h",
4502     [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4503   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4504                                 asm, ".2s", ".2s",
4505     [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4506   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4507                                 asm, ".4s", ".4s",
4508     [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4509   def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, V128,
4510                                 asm, ".2d", ".2d",
4511     [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4512 }
4513
4514
4515 // Supports only B element sizes.
4516 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
4517                           SDPatternOperator OpNode> {
4518   def v8i8  : BaseSIMDTwoSameVector<0, U, size, opc, V64,
4519                                 asm, ".8b", ".8b",
4520                     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4521   def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, V128,
4522                                 asm, ".16b", ".16b",
4523                     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4524
4525 }
4526
4527 // Supports only B and H element sizes.
4528 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
4529                                 SDPatternOperator OpNode> {
4530   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4531                                 asm, ".8b", ".8b",
4532                     [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
4533   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4534                                 asm, ".16b", ".16b",
4535                     [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
4536   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4537                                 asm, ".4h", ".4h",
4538                     [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
4539   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4540                                 asm, ".8h", ".8h",
4541                     [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
4542 }
4543
4544 // Supports only S and D element sizes, uses high bit of the size field
4545 // as an extra opcode bit.
4546 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
4547                            SDPatternOperator OpNode> {
4548   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4549                                 asm, ".2s", ".2s",
4550                           [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4551   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4552                                 asm, ".4s", ".4s",
4553                           [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4554   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4555                                 asm, ".2d", ".2d",
4556                           [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4557 }
4558
4559 // Supports only S element size.
4560 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
4561                            SDPatternOperator OpNode> {
4562   def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4563                                 asm, ".2s", ".2s",
4564                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4565   def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4566                                 asm, ".4s", ".4s",
4567                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4568 }
4569
4570
4571 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
4572                            SDPatternOperator OpNode> {
4573   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4574                                 asm, ".2s", ".2s",
4575                           [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4576   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4577                                 asm, ".4s", ".4s",
4578                           [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4579   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4580                                 asm, ".2d", ".2d",
4581                           [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4582 }
4583
4584 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
4585                            SDPatternOperator OpNode> {
4586   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4587                                 asm, ".2s", ".2s",
4588                           [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4589   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4590                                 asm, ".4s", ".4s",
4591                           [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4592   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4593                                 asm, ".2d", ".2d",
4594                           [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4595 }
4596
4597
4598 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4599                            RegisterOperand inreg, RegisterOperand outreg,
4600                            string asm, string outkind, string inkind,
4601                            list<dag> pattern>
4602   : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
4603       "{\t$Rd" # outkind # ", $Rn" # inkind #
4604       "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
4605     Sched<[WriteV]> {
4606   bits<5> Rd;
4607   bits<5> Rn;
4608   let Inst{31}    = 0;
4609   let Inst{30}    = Q;
4610   let Inst{29}    = U;
4611   let Inst{28-24} = 0b01110;
4612   let Inst{23-22} = size;
4613   let Inst{21-17} = 0b10000;
4614   let Inst{16-12} = opcode;
4615   let Inst{11-10} = 0b10;
4616   let Inst{9-5}   = Rn;
4617   let Inst{4-0}   = Rd;
4618 }
4619
4620 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4621                            RegisterOperand inreg, RegisterOperand outreg,
4622                            string asm, string outkind, string inkind,
4623                            list<dag> pattern>
4624   : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
4625       "{\t$Rd" # outkind # ", $Rn" # inkind #
4626       "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4627     Sched<[WriteV]> {
4628   bits<5> Rd;
4629   bits<5> Rn;
4630   let Inst{31}    = 0;
4631   let Inst{30}    = Q;
4632   let Inst{29}    = U;
4633   let Inst{28-24} = 0b01110;
4634   let Inst{23-22} = size;
4635   let Inst{21-17} = 0b10000;
4636   let Inst{16-12} = opcode;
4637   let Inst{11-10} = 0b10;
4638   let Inst{9-5}   = Rn;
4639   let Inst{4-0}   = Rd;
4640 }
4641
4642 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
4643                               SDPatternOperator OpNode> {
4644   def v8i8  : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
4645                                       asm, ".8b", ".8h",
4646         [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4647   def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
4648                                       asm#"2", ".16b", ".8h", []>;
4649   def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
4650                                       asm, ".4h", ".4s",
4651         [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4652   def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
4653                                       asm#"2", ".8h", ".4s", []>;
4654   def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
4655                                       asm, ".2s", ".2d",
4656         [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4657   def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
4658                                       asm#"2", ".4s", ".2d", []>;
4659
4660   def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
4661             (!cast<Instruction>(NAME # "v16i8")
4662                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4663   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
4664             (!cast<Instruction>(NAME # "v8i16")
4665                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4666   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
4667             (!cast<Instruction>(NAME # "v4i32")
4668                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4669 }
4670
4671 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4672                            RegisterOperand regtype,
4673                            string asm, string kind, string zero,
4674                            ValueType dty, ValueType sty, SDNode OpNode>
4675   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4676       "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
4677       "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
4678       [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
4679     Sched<[WriteV]> {
4680   bits<5> Rd;
4681   bits<5> Rn;
4682   let Inst{31}    = 0;
4683   let Inst{30}    = Q;
4684   let Inst{29}    = U;
4685   let Inst{28-24} = 0b01110;
4686   let Inst{23-22} = size;
4687   let Inst{21-17} = 0b10000;
4688   let Inst{16-12} = opcode;
4689   let Inst{11-10} = 0b10;
4690   let Inst{9-5}   = Rn;
4691   let Inst{4-0}   = Rd;
4692 }
4693
4694 // Comparisons support all element sizes, except 1xD.
4695 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
4696                             SDNode OpNode> {
4697   def v8i8rz  : BaseSIMDCmpTwoVector<0, U, 0b00, opc, V64,
4698                                      asm, ".8b", "0",
4699                                      v8i8, v8i8, OpNode>;
4700   def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, opc, V128,
4701                                      asm, ".16b", "0",
4702                                      v16i8, v16i8, OpNode>;
4703   def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, opc, V64,
4704                                      asm, ".4h", "0",
4705                                      v4i16, v4i16, OpNode>;
4706   def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, opc, V128,
4707                                      asm, ".8h", "0",
4708                                      v8i16, v8i16, OpNode>;
4709   def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, opc, V64,
4710                                      asm, ".2s", "0",
4711                                      v2i32, v2i32, OpNode>;
4712   def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, opc, V128,
4713                                      asm, ".4s", "0",
4714                                      v4i32, v4i32, OpNode>;
4715   def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, opc, V128,
4716                                      asm, ".2d", "0",
4717                                      v2i64, v2i64, OpNode>;
4718 }
4719
4720 // FP Comparisons support only S and D element sizes.
4721 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
4722                               string asm, SDNode OpNode> {
4723
4724   def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, opc, V64,
4725                                      asm, ".2s", "0.0",
4726                                      v2i32, v2f32, OpNode>;
4727   def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, opc, V128,
4728                                      asm, ".4s", "0.0",
4729                                      v4i32, v4f32, OpNode>;
4730   def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, opc, V128,
4731                                      asm, ".2d", "0.0",
4732                                      v2i64, v2f64, OpNode>;
4733
4734   def : InstAlias<asm # " $Vd.2s, $Vn.2s, #0",
4735                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
4736   def : InstAlias<asm # " $Vd.4s, $Vn.4s, #0",
4737                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
4738   def : InstAlias<asm # " $Vd.2d, $Vn.2d, #0",
4739                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
4740   def : InstAlias<asm # ".2s $Vd, $Vn, #0",
4741                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
4742   def : InstAlias<asm # ".4s $Vd, $Vn, #0",
4743                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
4744   def : InstAlias<asm # ".2d $Vd, $Vn, #0",
4745                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
4746 }
4747
4748 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4749 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4750                              RegisterOperand outtype, RegisterOperand intype,
4751                              string asm, string VdTy, string VnTy,
4752                              list<dag> pattern>
4753   : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
4754       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
4755     Sched<[WriteV]> {
4756   bits<5> Rd;
4757   bits<5> Rn;
4758   let Inst{31}    = 0;
4759   let Inst{30}    = Q;
4760   let Inst{29}    = U;
4761   let Inst{28-24} = 0b01110;
4762   let Inst{23-22} = size;
4763   let Inst{21-17} = 0b10000;
4764   let Inst{16-12} = opcode;
4765   let Inst{11-10} = 0b10;
4766   let Inst{9-5}   = Rn;
4767   let Inst{4-0}   = Rd;
4768 }
4769
4770 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4771                              RegisterOperand outtype, RegisterOperand intype,
4772                              string asm, string VdTy, string VnTy,
4773                              list<dag> pattern>
4774   : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
4775       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
4776     Sched<[WriteV]> {
4777   bits<5> Rd;
4778   bits<5> Rn;
4779   let Inst{31}    = 0;
4780   let Inst{30}    = Q;
4781   let Inst{29}    = U;
4782   let Inst{28-24} = 0b01110;
4783   let Inst{23-22} = size;
4784   let Inst{21-17} = 0b10000;
4785   let Inst{16-12} = opcode;
4786   let Inst{11-10} = 0b10;
4787   let Inst{9-5}   = Rn;
4788   let Inst{4-0}   = Rd;
4789 }
4790
4791 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
4792   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
4793                                     asm, ".4s", ".4h", []>;
4794   def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
4795                                     asm#"2", ".4s", ".8h", []>;
4796   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
4797                                     asm, ".2d", ".2s", []>;
4798   def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
4799                                     asm#"2", ".2d", ".4s", []>;
4800 }
4801
4802 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
4803   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
4804                                     asm, ".4h", ".4s", []>;
4805   def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
4806                                     asm#"2", ".8h", ".4s", []>;
4807   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4808                                     asm, ".2s", ".2d", []>;
4809   def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4810                                     asm#"2", ".4s", ".2d", []>;
4811 }
4812
4813 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
4814                                      Intrinsic OpNode> {
4815   def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4816                                      asm, ".2s", ".2d",
4817                           [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4818   def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4819                                     asm#"2", ".4s", ".2d", []>;
4820
4821   def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
4822             (!cast<Instruction>(NAME # "v4f32")
4823                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4824 }
4825
4826 //----------------------------------------------------------------------------
4827 // AdvSIMD three register different-size vector instructions.
4828 //----------------------------------------------------------------------------
4829
4830 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4831 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
4832                       RegisterOperand outtype, RegisterOperand intype1,
4833                       RegisterOperand intype2, string asm,
4834                       string outkind, string inkind1, string inkind2,
4835                       list<dag> pattern>
4836   : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
4837       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4838       "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
4839     Sched<[WriteV]> {
4840   bits<5> Rd;
4841   bits<5> Rn;
4842   bits<5> Rm;
4843   let Inst{31}    = 0;
4844   let Inst{30}    = size{0};
4845   let Inst{29}    = U;
4846   let Inst{28-24} = 0b01110;
4847   let Inst{23-22} = size{2-1};
4848   let Inst{21}    = 1;
4849   let Inst{20-16} = Rm;
4850   let Inst{15-12} = opcode;
4851   let Inst{11-10} = 0b00;
4852   let Inst{9-5}   = Rn;
4853   let Inst{4-0}   = Rd;
4854 }
4855
4856 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4857 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
4858                       RegisterOperand outtype, RegisterOperand intype1,
4859                       RegisterOperand intype2, string asm,
4860                       string outkind, string inkind1, string inkind2,
4861                       list<dag> pattern>
4862   : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
4863       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4864       "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4865     Sched<[WriteV]> {
4866   bits<5> Rd;
4867   bits<5> Rn;
4868   bits<5> Rm;
4869   let Inst{31}    = 0;
4870   let Inst{30}    = size{0};
4871   let Inst{29}    = U;
4872   let Inst{28-24} = 0b01110;
4873   let Inst{23-22} = size{2-1};
4874   let Inst{21}    = 1;
4875   let Inst{20-16} = Rm;
4876   let Inst{15-12} = opcode;
4877   let Inst{11-10} = 0b00;
4878   let Inst{9-5}   = Rn;
4879   let Inst{4-0}   = Rd;
4880 }
4881
4882 // FIXME: TableGen doesn't know how to deal with expanded types that also
4883 //        change the element count (in this case, placing the results in
4884 //        the high elements of the result register rather than the low
4885 //        elements). Until that's fixed, we can't code-gen those.
4886 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
4887                                     Intrinsic IntOp> {
4888   def v8i16_v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4889                                                   V64, V128, V128,
4890                                                   asm, ".8b", ".8h", ".8h",
4891      [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4892   def v8i16_v16i8  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
4893                                                   V128, V128, V128,
4894                                                   asm#"2", ".16b", ".8h", ".8h",
4895      []>;
4896   def v4i32_v4i16  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4897                                                   V64, V128, V128,
4898                                                   asm, ".4h", ".4s", ".4s",
4899      [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4900   def v4i32_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4901                                                   V128, V128, V128,
4902                                                   asm#"2", ".8h", ".4s", ".4s",
4903      []>;
4904   def v2i64_v2i32  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4905                                                   V64, V128, V128,
4906                                                   asm, ".2s", ".2d", ".2d",
4907      [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4908   def v2i64_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4909                                                   V128, V128, V128,
4910                                                   asm#"2", ".4s", ".2d", ".2d",
4911      []>;
4912
4913
4914   // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
4915   // a version attached to an instruction.
4916   def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
4917                                                    (v8i16 V128:$Rm))),
4918             (!cast<Instruction>(NAME # "v8i16_v16i8")
4919                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4920                 V128:$Rn, V128:$Rm)>;
4921   def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
4922                                                     (v4i32 V128:$Rm))),
4923             (!cast<Instruction>(NAME # "v4i32_v8i16")
4924                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4925                 V128:$Rn, V128:$Rm)>;
4926   def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
4927                                                     (v2i64 V128:$Rm))),
4928             (!cast<Instruction>(NAME # "v2i64_v4i32")
4929                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4930                 V128:$Rn, V128:$Rm)>;
4931 }
4932
4933 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
4934                                       Intrinsic IntOp> {
4935   def v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4936                                             V128, V64, V64,
4937                                             asm, ".8h", ".8b", ".8b",
4938       [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4939   def v16i8  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
4940                                             V128, V128, V128,
4941                                             asm#"2", ".8h", ".16b", ".16b", []>;
4942   let Predicates = [HasCrypto] in {
4943     def v1i64  : BaseSIMDDifferentThreeVector<U, 0b110, opc,
4944                                               V128, V64, V64,
4945                                               asm, ".1q", ".1d", ".1d", []>;
4946     def v2i64  : BaseSIMDDifferentThreeVector<U, 0b111, opc,
4947                                               V128, V128, V128,
4948                                               asm#"2", ".1q", ".2d", ".2d", []>;
4949   }
4950
4951   def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
4952                           (v8i8 (extract_high_v16i8 V128:$Rm)))),
4953       (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
4954 }
4955
4956 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
4957                                  SDPatternOperator OpNode> {
4958   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4959                                                   V128, V64, V64,
4960                                                   asm, ".4s", ".4h", ".4h",
4961       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4962   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
4963                                                   V128, V128, V128,
4964                                                   asm#"2", ".4s", ".8h", ".8h",
4965       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
4966                                       (extract_high_v8i16 V128:$Rm)))]>;
4967   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4968                                                   V128, V64, V64,
4969                                                   asm, ".2d", ".2s", ".2s",
4970       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4971   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
4972                                                   V128, V128, V128,
4973                                                   asm#"2", ".2d", ".4s", ".4s",
4974       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
4975                                       (extract_high_v4i32 V128:$Rm)))]>;
4976 }
4977
4978 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
4979                                   SDPatternOperator OpNode = null_frag> {
4980   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4981                                                   V128, V64, V64,
4982                                                   asm, ".8h", ".8b", ".8b",
4983       [(set (v8i16 V128:$Rd),
4984             (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
4985   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
4986                                                  V128, V128, V128,
4987                                                  asm#"2", ".8h", ".16b", ".16b",
4988       [(set (v8i16 V128:$Rd),
4989             (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
4990                                 (extract_high_v16i8 V128:$Rm)))))]>;
4991   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4992                                                   V128, V64, V64,
4993                                                   asm, ".4s", ".4h", ".4h",
4994       [(set (v4i32 V128:$Rd),
4995             (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
4996   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
4997                                                   V128, V128, V128,
4998                                                   asm#"2", ".4s", ".8h", ".8h",
4999       [(set (v4i32 V128:$Rd),
5000             (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5001                                   (extract_high_v8i16 V128:$Rm)))))]>;
5002   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5003                                                   V128, V64, V64,
5004                                                   asm, ".2d", ".2s", ".2s",
5005       [(set (v2i64 V128:$Rd),
5006             (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
5007   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5008                                                   V128, V128, V128,
5009                                                   asm#"2", ".2d", ".4s", ".4s",
5010       [(set (v2i64 V128:$Rd),
5011             (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5012                                  (extract_high_v4i32 V128:$Rm)))))]>;
5013 }
5014
5015 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
5016                                           string asm,
5017                                           SDPatternOperator OpNode> {
5018   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5019                                                   V128, V64, V64,
5020                                                   asm, ".8h", ".8b", ".8b",
5021     [(set (v8i16 V128:$dst),
5022           (add (v8i16 V128:$Rd),
5023                (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
5024   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5025                                                  V128, V128, V128,
5026                                                  asm#"2", ".8h", ".16b", ".16b",
5027     [(set (v8i16 V128:$dst),
5028           (add (v8i16 V128:$Rd),
5029                (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5030                                    (extract_high_v16i8 V128:$Rm))))))]>;
5031   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5032                                                   V128, V64, V64,
5033                                                   asm, ".4s", ".4h", ".4h",
5034     [(set (v4i32 V128:$dst),
5035           (add (v4i32 V128:$Rd),
5036                (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
5037   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5038                                                   V128, V128, V128,
5039                                                   asm#"2", ".4s", ".8h", ".8h",
5040     [(set (v4i32 V128:$dst),
5041           (add (v4i32 V128:$Rd),
5042                (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5043                                     (extract_high_v8i16 V128:$Rm))))))]>;
5044   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5045                                                   V128, V64, V64,
5046                                                   asm, ".2d", ".2s", ".2s",
5047     [(set (v2i64 V128:$dst),
5048           (add (v2i64 V128:$Rd),
5049                (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
5050   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5051                                                   V128, V128, V128,
5052                                                   asm#"2", ".2d", ".4s", ".4s",
5053     [(set (v2i64 V128:$dst),
5054           (add (v2i64 V128:$Rd),
5055                (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5056                                     (extract_high_v4i32 V128:$Rm))))))]>;
5057 }
5058
5059 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
5060                                   SDPatternOperator OpNode = null_frag> {
5061   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5062                                                   V128, V64, V64,
5063                                                   asm, ".8h", ".8b", ".8b",
5064       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5065   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5066                                                  V128, V128, V128,
5067                                                  asm#"2", ".8h", ".16b", ".16b",
5068       [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
5069                                       (extract_high_v16i8 V128:$Rm)))]>;
5070   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5071                                                   V128, V64, V64,
5072                                                   asm, ".4s", ".4h", ".4h",
5073       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5074   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5075                                                   V128, V128, V128,
5076                                                   asm#"2", ".4s", ".8h", ".8h",
5077       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5078                                       (extract_high_v8i16 V128:$Rm)))]>;
5079   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5080                                                   V128, V64, V64,
5081                                                   asm, ".2d", ".2s", ".2s",
5082       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5083   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5084                                                   V128, V128, V128,
5085                                                   asm#"2", ".2d", ".4s", ".4s",
5086       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5087                                       (extract_high_v4i32 V128:$Rm)))]>;
5088 }
5089
5090 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
5091                                       string asm,
5092                                       SDPatternOperator OpNode> {
5093   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5094                                                   V128, V64, V64,
5095                                                   asm, ".8h", ".8b", ".8b",
5096     [(set (v8i16 V128:$dst),
5097           (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5098   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5099                                                  V128, V128, V128,
5100                                                  asm#"2", ".8h", ".16b", ".16b",
5101     [(set (v8i16 V128:$dst),
5102           (OpNode (v8i16 V128:$Rd),
5103                   (extract_high_v16i8 V128:$Rn),
5104                   (extract_high_v16i8 V128:$Rm)))]>;
5105   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5106                                                   V128, V64, V64,
5107                                                   asm, ".4s", ".4h", ".4h",
5108     [(set (v4i32 V128:$dst),
5109           (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5110   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5111                                                   V128, V128, V128,
5112                                                   asm#"2", ".4s", ".8h", ".8h",
5113     [(set (v4i32 V128:$dst),
5114           (OpNode (v4i32 V128:$Rd),
5115                   (extract_high_v8i16 V128:$Rn),
5116                   (extract_high_v8i16 V128:$Rm)))]>;
5117   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5118                                                   V128, V64, V64,
5119                                                   asm, ".2d", ".2s", ".2s",
5120     [(set (v2i64 V128:$dst),
5121           (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5122   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5123                                                   V128, V128, V128,
5124                                                   asm#"2", ".2d", ".4s", ".4s",
5125     [(set (v2i64 V128:$dst),
5126           (OpNode (v2i64 V128:$Rd),
5127                   (extract_high_v4i32 V128:$Rn),
5128                   (extract_high_v4i32 V128:$Rm)))]>;
5129 }
5130
5131 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
5132                                            SDPatternOperator Accum> {
5133   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5134                                                   V128, V64, V64,
5135                                                   asm, ".4s", ".4h", ".4h",
5136     [(set (v4i32 V128:$dst),
5137           (Accum (v4i32 V128:$Rd),
5138                  (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
5139                                                 (v4i16 V64:$Rm)))))]>;
5140   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5141                                                   V128, V128, V128,
5142                                                   asm#"2", ".4s", ".8h", ".8h",
5143     [(set (v4i32 V128:$dst),
5144           (Accum (v4i32 V128:$Rd),
5145                  (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
5146                                             (extract_high_v8i16 V128:$Rm)))))]>;
5147   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5148                                                   V128, V64, V64,
5149                                                   asm, ".2d", ".2s", ".2s",
5150     [(set (v2i64 V128:$dst),
5151           (Accum (v2i64 V128:$Rd),
5152                  (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
5153                                                 (v2i32 V64:$Rm)))))]>;
5154   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5155                                                   V128, V128, V128,
5156                                                   asm#"2", ".2d", ".4s", ".4s",
5157     [(set (v2i64 V128:$dst),
5158           (Accum (v2i64 V128:$Rd),
5159                  (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
5160                                             (extract_high_v4i32 V128:$Rm)))))]>;
5161 }
5162
5163 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
5164                                   SDPatternOperator OpNode> {
5165   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5166                                                   V128, V128, V64,
5167                                                   asm, ".8h", ".8h", ".8b",
5168        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
5169   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5170                                                   V128, V128, V128,
5171                                                   asm#"2", ".8h", ".8h", ".16b",
5172        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
5173                                        (extract_high_v16i8 V128:$Rm)))]>;
5174   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5175                                                   V128, V128, V64,
5176                                                   asm, ".4s", ".4s", ".4h",
5177        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
5178   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5179                                                   V128, V128, V128,
5180                                                   asm#"2", ".4s", ".4s", ".8h",
5181        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
5182                                        (extract_high_v8i16 V128:$Rm)))]>;
5183   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5184                                                   V128, V128, V64,
5185                                                   asm, ".2d", ".2d", ".2s",
5186        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
5187   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5188                                                   V128, V128, V128,
5189                                                   asm#"2", ".2d", ".2d", ".4s",
5190        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
5191                                        (extract_high_v4i32 V128:$Rm)))]>;
5192 }
5193
5194 //----------------------------------------------------------------------------
5195 // AdvSIMD bitwise extract from vector
5196 //----------------------------------------------------------------------------
5197
5198 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
5199                              string asm, string kind>
5200   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
5201       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
5202       "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
5203       [(set (vty regtype:$Rd),
5204             (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
5205     Sched<[WriteV]> {
5206   bits<5> Rd;
5207   bits<5> Rn;
5208   bits<5> Rm;
5209   bits<4> imm;
5210   let Inst{31}    = 0;
5211   let Inst{30}    = size;
5212   let Inst{29-21} = 0b101110000;
5213   let Inst{20-16} = Rm;
5214   let Inst{15}    = 0;
5215   let Inst{14-11} = imm;
5216   let Inst{10}    = 0;
5217   let Inst{9-5}   = Rn;
5218   let Inst{4-0}   = Rd;
5219 }
5220
5221
5222 multiclass SIMDBitwiseExtract<string asm> {
5223   def v8i8  : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
5224     let imm{3} = 0;
5225   }
5226   def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
5227 }
5228
5229 //----------------------------------------------------------------------------
5230 // AdvSIMD zip vector
5231 //----------------------------------------------------------------------------
5232
5233 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
5234                         string asm, string kind, SDNode OpNode, ValueType valty>
5235   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5236       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5237       "|" # kind # "\t$Rd, $Rn, $Rm}", "",
5238       [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
5239     Sched<[WriteV]> {
5240   bits<5> Rd;
5241   bits<5> Rn;
5242   bits<5> Rm;
5243   let Inst{31}    = 0;
5244   let Inst{30}    = size{0};
5245   let Inst{29-24} = 0b001110;
5246   let Inst{23-22} = size{2-1};
5247   let Inst{21}    = 0;
5248   let Inst{20-16} = Rm;
5249   let Inst{15}    = 0;
5250   let Inst{14-12} = opc;
5251   let Inst{11-10} = 0b10;
5252   let Inst{9-5}   = Rn;
5253   let Inst{4-0}   = Rd;
5254 }
5255
5256 multiclass SIMDZipVector<bits<3>opc, string asm,
5257                          SDNode OpNode> {
5258   def v8i8   : BaseSIMDZipVector<0b000, opc, V64,
5259       asm, ".8b", OpNode, v8i8>;
5260   def v16i8  : BaseSIMDZipVector<0b001, opc, V128,
5261       asm, ".16b", OpNode, v16i8>;
5262   def v4i16  : BaseSIMDZipVector<0b010, opc, V64,
5263       asm, ".4h", OpNode, v4i16>;
5264   def v8i16  : BaseSIMDZipVector<0b011, opc, V128,
5265       asm, ".8h", OpNode, v8i16>;
5266   def v2i32  : BaseSIMDZipVector<0b100, opc, V64,
5267       asm, ".2s", OpNode, v2i32>;
5268   def v4i32  : BaseSIMDZipVector<0b101, opc, V128,
5269       asm, ".4s", OpNode, v4i32>;
5270   def v2i64  : BaseSIMDZipVector<0b111, opc, V128,
5271       asm, ".2d", OpNode, v2i64>;
5272
5273   def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
5274         (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
5275   def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
5276         (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
5277   def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
5278         (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
5279   def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
5280         (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
5281   def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
5282         (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
5283 }
5284
5285 //----------------------------------------------------------------------------
5286 // AdvSIMD three register scalar instructions
5287 //----------------------------------------------------------------------------
5288
5289 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5290 class BaseSIMDThreeScalar<bit U, bits<2> size, bits<5> opcode,
5291                         RegisterClass regtype, string asm,
5292                         list<dag> pattern>
5293   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5294       "\t$Rd, $Rn, $Rm", "", pattern>,
5295     Sched<[WriteV]> {
5296   bits<5> Rd;
5297   bits<5> Rn;
5298   bits<5> Rm;
5299   let Inst{31-30} = 0b01;
5300   let Inst{29}    = U;
5301   let Inst{28-24} = 0b11110;
5302   let Inst{23-22} = size;
5303   let Inst{21}    = 1;
5304   let Inst{20-16} = Rm;
5305   let Inst{15-11} = opcode;
5306   let Inst{10}    = 1;
5307   let Inst{9-5}   = Rn;
5308   let Inst{4-0}   = Rd;
5309 }
5310
5311 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5312 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
5313                         dag oops, dag iops, string asm,
5314             list<dag> pattern>
5315   : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
5316     Sched<[WriteV]> {
5317   bits<5> Rd;
5318   bits<5> Rn;
5319   bits<5> Rm;
5320   let Inst{31-30} = 0b01;
5321   let Inst{29}    = U;
5322   let Inst{28-24} = 0b11110;
5323   let Inst{23-22} = size;
5324   let Inst{21}    = R;
5325   let Inst{20-16} = Rm;
5326   let Inst{15-11} = opcode;
5327   let Inst{10}    = 1;
5328   let Inst{9-5}   = Rn;
5329   let Inst{4-0}   = Rd;
5330 }
5331
5332 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
5333                             SDPatternOperator OpNode> {
5334   def v1i64  : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
5335     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5336 }
5337
5338 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
5339                                SDPatternOperator OpNode> {
5340   def v1i64  : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
5341     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5342   def v1i32  : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm, []>;
5343   def v1i16  : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
5344   def v1i8   : BaseSIMDThreeScalar<U, 0b00, opc, FPR8 , asm, []>;
5345
5346   def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
5347             (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
5348   def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
5349             (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
5350 }
5351
5352 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
5353                              SDPatternOperator OpNode> {
5354   def v1i32  : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm,
5355                              [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5356   def v1i16  : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
5357 }
5358
5359 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
5360                                  SDPatternOperator OpNode = null_frag> {
5361   def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
5362                                      (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 
5363                                      asm, []>;
5364   def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
5365                                      (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 
5366                                      asm, []>;
5367 }
5368
5369 multiclass SIMDThreeScalarSD<bit U, bit S, bits<5> opc, string asm,
5370                              SDPatternOperator OpNode = null_frag> {
5371   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5372     def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
5373       [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5374     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
5375       [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5376   }
5377
5378   def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5379             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5380 }
5381
5382 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<5> opc, string asm,
5383                                 SDPatternOperator OpNode = null_frag> {
5384   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5385     def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
5386       [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5387     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
5388       [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
5389   }
5390
5391   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5392             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5393 }
5394
5395 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
5396               dag oops, dag iops, string asm, string cstr, list<dag> pat>
5397   : I<oops, iops, asm,
5398       "\t$Rd, $Rn, $Rm", cstr, pat>,
5399     Sched<[WriteV]> {
5400   bits<5> Rd;
5401   bits<5> Rn;
5402   bits<5> Rm;
5403   let Inst{31-30} = 0b01;
5404   let Inst{29}    = U;
5405   let Inst{28-24} = 0b11110;
5406   let Inst{23-22} = size;
5407   let Inst{21}    = 1;
5408   let Inst{20-16} = Rm;
5409   let Inst{15-11} = opcode;
5410   let Inst{10}    = 0;
5411   let Inst{9-5}   = Rn;
5412   let Inst{4-0}   = Rd;
5413 }
5414
5415 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5416 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
5417                                   SDPatternOperator OpNode = null_frag> {
5418   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5419                                       (outs FPR32:$Rd),
5420                                       (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
5421   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5422                                       (outs FPR64:$Rd),
5423                                       (ins FPR32:$Rn, FPR32:$Rm), asm, "",
5424             [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5425 }
5426
5427 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5428 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
5429                                   SDPatternOperator OpNode = null_frag> {
5430   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5431                                       (outs FPR32:$dst),
5432                                       (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
5433                                       asm, "$Rd = $dst", []>;
5434   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5435                                       (outs FPR64:$dst),
5436                                       (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
5437                                       asm, "$Rd = $dst",
5438             [(set (i64 FPR64:$dst),
5439                   (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5440 }
5441
5442 //----------------------------------------------------------------------------
5443 // AdvSIMD two register scalar instructions
5444 //----------------------------------------------------------------------------
5445
5446 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5447 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<5> opcode,
5448                         RegisterClass regtype, RegisterClass regtype2,
5449                         string asm, list<dag> pat>
5450   : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
5451       "\t$Rd, $Rn", "", pat>,
5452     Sched<[WriteV]> {
5453   bits<5> Rd;
5454   bits<5> Rn;
5455   let Inst{31-30} = 0b01;
5456   let Inst{29}    = U;
5457   let Inst{28-24} = 0b11110;
5458   let Inst{23-22} = size;
5459   let Inst{21-17} = 0b10000;
5460   let Inst{16-12} = opcode;
5461   let Inst{11-10} = 0b10;
5462   let Inst{9-5}   = Rn;
5463   let Inst{4-0}   = Rd;
5464 }
5465
5466 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5467 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
5468                         RegisterClass regtype, RegisterClass regtype2,
5469                         string asm, list<dag> pat>
5470   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
5471       "\t$Rd, $Rn", "$Rd = $dst", pat>,
5472     Sched<[WriteV]> {
5473   bits<5> Rd;
5474   bits<5> Rn;
5475   let Inst{31-30} = 0b01;
5476   let Inst{29}    = U;
5477   let Inst{28-24} = 0b11110;
5478   let Inst{23-22} = size;
5479   let Inst{21-17} = 0b10000;
5480   let Inst{16-12} = opcode;
5481   let Inst{11-10} = 0b10;
5482   let Inst{9-5}   = Rn;
5483   let Inst{4-0}   = Rd;
5484 }
5485
5486
5487 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5488 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<5> opcode,
5489                         RegisterClass regtype, string asm, string zero>
5490   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5491       "\t$Rd, $Rn, #" # zero, "", []>,
5492     Sched<[WriteV]> {
5493   bits<5> Rd;
5494   bits<5> Rn;
5495   let Inst{31-30} = 0b01;
5496   let Inst{29}    = U;
5497   let Inst{28-24} = 0b11110;
5498   let Inst{23-22} = size;
5499   let Inst{21-17} = 0b10000;
5500   let Inst{16-12} = opcode;
5501   let Inst{11-10} = 0b10;
5502   let Inst{9-5}   = Rn;
5503   let Inst{4-0}   = Rd;
5504 }
5505
5506 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
5507   : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
5508      [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
5509     Sched<[WriteV]> {
5510   bits<5> Rd;
5511   bits<5> Rn;
5512   let Inst{31-17} = 0b011111100110000;
5513   let Inst{16-12} = opcode;
5514   let Inst{11-10} = 0b10;
5515   let Inst{9-5}   = Rn;
5516   let Inst{4-0}   = Rd;
5517 }
5518
5519 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
5520                              SDPatternOperator OpNode> {
5521   def v1i64rz  : BaseSIMDCmpTwoScalar<U, 0b11, opc, FPR64, asm, "0">;
5522
5523   def : Pat<(v1i64 (OpNode FPR64:$Rn)),
5524             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5525 }
5526
5527 multiclass SIMDCmpTwoScalarSD<bit U, bit S, bits<5> opc, string asm,
5528                               SDPatternOperator OpNode> {
5529   def v1i64rz  : BaseSIMDCmpTwoScalar<U, {S,1}, opc, FPR64, asm, "0.0">;
5530   def v1i32rz  : BaseSIMDCmpTwoScalar<U, {S,0}, opc, FPR32, asm, "0.0">;
5531
5532   def : InstAlias<asm # " $Rd, $Rn, #0",
5533                   (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
5534   def : InstAlias<asm # " $Rd, $Rn, #0",
5535                   (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
5536
5537   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
5538             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5539 }
5540
5541 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
5542                           SDPatternOperator OpNode = null_frag> {
5543   def v1i64       : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5544     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
5545
5546   def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
5547             (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
5548 }
5549
5550 multiclass SIMDTwoScalarSD<bit U, bit S, bits<5> opc, string asm> {
5551   def v1i64       : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,[]>;
5552   def v1i32       : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,[]>;
5553 }
5554
5555 multiclass SIMDTwoScalarCVTSD<bit U, bit S, bits<5> opc, string asm,
5556                               SDPatternOperator OpNode> {
5557   def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,
5558                                 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
5559   def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,
5560                                 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
5561 }
5562
5563 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
5564                              SDPatternOperator OpNode = null_frag> {
5565   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5566     def v1i64  : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5567            [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5568     def v1i32  : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR32, asm,
5569            [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
5570     def v1i16  : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR16, asm, []>;
5571     def v1i8   : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5572   }
5573
5574   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
5575             (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
5576 }
5577
5578 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
5579                                  Intrinsic OpNode> {
5580   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5581     def v1i64  : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
5582         [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
5583     def v1i32  : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
5584         [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
5585     def v1i16  : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
5586     def v1i8   : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5587   }
5588
5589   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
5590             (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
5591 }
5592
5593
5594
5595 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5596 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
5597                                  SDPatternOperator OpNode = null_frag> {
5598   def v1i32  : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR64, asm,
5599         [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5600   def v1i16  : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR32, asm, []>;
5601   def v1i8   : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR16, asm, []>;
5602 }
5603
5604 //----------------------------------------------------------------------------
5605 // AdvSIMD scalar pairwise instructions
5606 //----------------------------------------------------------------------------
5607
5608 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5609 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
5610                         RegisterOperand regtype, RegisterOperand vectype,
5611                         string asm, string kind>
5612   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5613       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
5614     Sched<[WriteV]> {
5615   bits<5> Rd;
5616   bits<5> Rn;
5617   let Inst{31-30} = 0b01;
5618   let Inst{29}    = U;
5619   let Inst{28-24} = 0b11110;
5620   let Inst{23-22} = size;
5621   let Inst{21-17} = 0b11000;
5622   let Inst{16-12} = opcode;
5623   let Inst{11-10} = 0b10;
5624   let Inst{9-5}   = Rn;
5625   let Inst{4-0}   = Rd;
5626 }
5627
5628 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
5629   def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
5630                                       asm, ".2d">;
5631 }
5632
5633 multiclass SIMDPairwiseScalarSD<bit U, bit S, bits<5> opc, string asm> {
5634   def v2i32p : BaseSIMDPairwiseScalar<U, {S,0}, opc, FPR32Op, V64,
5635                                       asm, ".2s">;
5636   def v2i64p : BaseSIMDPairwiseScalar<U, {S,1}, opc, FPR64Op, V128,
5637                                       asm, ".2d">;
5638 }
5639
5640 //----------------------------------------------------------------------------
5641 // AdvSIMD across lanes instructions
5642 //----------------------------------------------------------------------------
5643
5644 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5645 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
5646                           RegisterClass regtype, RegisterOperand vectype,
5647                           string asm, string kind, list<dag> pattern>
5648   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5649       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
5650     Sched<[WriteV]> {
5651   bits<5> Rd;
5652   bits<5> Rn;
5653   let Inst{31}    = 0;
5654   let Inst{30}    = Q;
5655   let Inst{29}    = U;
5656   let Inst{28-24} = 0b01110;
5657   let Inst{23-22} = size;
5658   let Inst{21-17} = 0b11000;
5659   let Inst{16-12} = opcode;
5660   let Inst{11-10} = 0b10;
5661   let Inst{9-5}   = Rn;
5662   let Inst{4-0}   = Rd;
5663 }
5664
5665 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
5666                               string asm> {
5667   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8,  V64,
5668                                    asm, ".8b", []>;
5669   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8,  V128,
5670                                    asm, ".16b", []>;
5671   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
5672                                    asm, ".4h", []>;
5673   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
5674                                    asm, ".8h", []>;
5675   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
5676                                    asm, ".4s", []>;
5677 }
5678
5679 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
5680   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
5681                                    asm, ".8b", []>;
5682   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
5683                                    asm, ".16b", []>;
5684   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
5685                                    asm, ".4h", []>;
5686   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
5687                                    asm, ".8h", []>;
5688   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
5689                                    asm, ".4s", []>;
5690 }
5691
5692 multiclass SIMDAcrossLanesS<bits<5> opcode, bit sz1, string asm,
5693                             Intrinsic intOp> {
5694   def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
5695                                    asm, ".4s",
5696         [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
5697 }
5698
5699 //----------------------------------------------------------------------------
5700 // AdvSIMD INS/DUP instructions
5701 //----------------------------------------------------------------------------
5702
5703 // FIXME: There has got to be a better way to factor these. ugh.
5704
5705 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
5706                      string operands, string constraints, list<dag> pattern>
5707   : I<outs, ins, asm, operands, constraints, pattern>,
5708     Sched<[WriteV]> {
5709   bits<5> Rd;
5710   bits<5> Rn;
5711   let Inst{31} = 0;
5712   let Inst{30} = Q;
5713   let Inst{29} = op;
5714   let Inst{28-21} = 0b01110000;
5715   let Inst{15} = 0;
5716   let Inst{10} = 1;
5717   let Inst{9-5} = Rn;
5718   let Inst{4-0} = Rd;
5719 }
5720
5721 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
5722                       RegisterOperand vecreg, RegisterClass regtype>
5723   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
5724                    "{\t$Rd" # size # ", $Rn" #
5725                    "|" # size # "\t$Rd, $Rn}", "",
5726                    [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
5727   let Inst{20-16} = imm5;
5728   let Inst{14-11} = 0b0001;
5729 }
5730
5731 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
5732                          ValueType vectype, ValueType insreg,
5733                          RegisterOperand vecreg, Operand idxtype,
5734                          ValueType elttype, SDNode OpNode>
5735   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
5736                    "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
5737                    "|" # dstkind # "\t$Rd, $Rn$idx}", "",
5738                  [(set (vectype vecreg:$Rd),
5739                        (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
5740   let Inst{14-11} = 0b0000;
5741 }
5742
5743 class SIMDDup64FromElement
5744   : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
5745                        VectorIndexD, i64, AArch64duplane64> {
5746   bits<1> idx;
5747   let Inst{20} = idx;
5748   let Inst{19-16} = 0b1000;
5749 }
5750
5751 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
5752                            RegisterOperand vecreg>
5753   : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
5754                        VectorIndexS, i64, AArch64duplane32> {
5755   bits<2> idx;
5756   let Inst{20-19} = idx;
5757   let Inst{18-16} = 0b100;
5758 }
5759
5760 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
5761                            RegisterOperand vecreg>
5762   : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
5763                        VectorIndexH, i64, AArch64duplane16> {
5764   bits<3> idx;
5765   let Inst{20-18} = idx;
5766   let Inst{17-16} = 0b10;
5767 }
5768
5769 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
5770                           RegisterOperand vecreg>
5771   : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
5772                        VectorIndexB, i64, AArch64duplane8> {
5773   bits<4> idx;
5774   let Inst{20-17} = idx;
5775   let Inst{16} = 1;
5776 }
5777
5778 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
5779                   Operand idxtype, string asm, list<dag> pattern>
5780   : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
5781                    "{\t$Rd, $Rn" # size # "$idx" #
5782                    "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
5783   let Inst{14-11} = imm4;
5784 }
5785
5786 class SIMDSMov<bit Q, string size, RegisterClass regtype,
5787                Operand idxtype>
5788   : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
5789 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
5790                Operand idxtype>
5791   : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
5792       [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
5793
5794 class SIMDMovAlias<string asm, string size, Instruction inst,
5795                    RegisterClass regtype, Operand idxtype>
5796     : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
5797                     "|" # size # "\t$dst, $src$idx}",
5798                 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
5799
5800 multiclass SMov {
5801   def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
5802     bits<4> idx;
5803     let Inst{20-17} = idx;
5804     let Inst{16} = 1;
5805   }
5806   def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
5807     bits<4> idx;
5808     let Inst{20-17} = idx;
5809     let Inst{16} = 1;
5810   }
5811   def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
5812     bits<3> idx;
5813     let Inst{20-18} = idx;
5814     let Inst{17-16} = 0b10;
5815   }
5816   def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
5817     bits<3> idx;
5818     let Inst{20-18} = idx;
5819     let Inst{17-16} = 0b10;
5820   }
5821   def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
5822     bits<2> idx;
5823     let Inst{20-19} = idx;
5824     let Inst{18-16} = 0b100;
5825   }
5826 }
5827
5828 multiclass UMov {
5829   def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
5830     bits<4> idx;
5831     let Inst{20-17} = idx;
5832     let Inst{16} = 1;
5833   }
5834   def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
5835     bits<3> idx;
5836     let Inst{20-18} = idx;
5837     let Inst{17-16} = 0b10;
5838   }
5839   def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
5840     bits<2> idx;
5841     let Inst{20-19} = idx;
5842     let Inst{18-16} = 0b100;
5843   }
5844   def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
5845     bits<1> idx;
5846     let Inst{20} = idx;
5847     let Inst{19-16} = 0b1000;
5848   }
5849   def : SIMDMovAlias<"mov", ".s",
5850                      !cast<Instruction>(NAME#"vi32"),
5851                      GPR32, VectorIndexS>;
5852   def : SIMDMovAlias<"mov", ".d",
5853                      !cast<Instruction>(NAME#"vi64"),
5854                      GPR64, VectorIndexD>;
5855 }
5856
5857 class SIMDInsFromMain<string size, ValueType vectype,
5858                       RegisterClass regtype, Operand idxtype>
5859   : BaseSIMDInsDup<1, 0, (outs V128:$dst),
5860                    (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
5861                    "{\t$Rd" # size # "$idx, $Rn" #
5862                    "|" # size # "\t$Rd$idx, $Rn}",
5863                    "$Rd = $dst",
5864             [(set V128:$dst,
5865               (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
5866   let Inst{14-11} = 0b0011;
5867 }
5868
5869 class SIMDInsFromElement<string size, ValueType vectype,
5870                          ValueType elttype, Operand idxtype>
5871   : BaseSIMDInsDup<1, 1, (outs V128:$dst),
5872                    (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
5873                    "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
5874                    "|" # size # "\t$Rd$idx, $Rn$idx2}",
5875                    "$Rd = $dst",
5876          [(set V128:$dst,
5877                (vector_insert
5878                  (vectype V128:$Rd),
5879                  (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
5880                  idxtype:$idx))]>;
5881
5882 class SIMDInsMainMovAlias<string size, Instruction inst,
5883                           RegisterClass regtype, Operand idxtype>
5884     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
5885                         "|" # size #"\t$dst$idx, $src}",
5886                 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
5887 class SIMDInsElementMovAlias<string size, Instruction inst,
5888                              Operand idxtype>
5889     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
5890                       # "|" # size #" $dst$idx, $src$idx2}",
5891                 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
5892
5893
5894 multiclass SIMDIns {
5895   def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
5896     bits<4> idx;
5897     let Inst{20-17} = idx;
5898     let Inst{16} = 1;
5899   }
5900   def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
5901     bits<3> idx;
5902     let Inst{20-18} = idx;
5903     let Inst{17-16} = 0b10;
5904   }
5905   def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
5906     bits<2> idx;
5907     let Inst{20-19} = idx;
5908     let Inst{18-16} = 0b100;
5909   }
5910   def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
5911     bits<1> idx;
5912     let Inst{20} = idx;
5913     let Inst{19-16} = 0b1000;
5914   }
5915
5916   def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
5917     bits<4> idx;
5918     bits<4> idx2;
5919     let Inst{20-17} = idx;
5920     let Inst{16} = 1;
5921     let Inst{14-11} = idx2;
5922   }
5923   def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
5924     bits<3> idx;
5925     bits<3> idx2;
5926     let Inst{20-18} = idx;
5927     let Inst{17-16} = 0b10;
5928     let Inst{14-12} = idx2;
5929     let Inst{11} = {?};
5930   }
5931   def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
5932     bits<2> idx;
5933     bits<2> idx2;
5934     let Inst{20-19} = idx;
5935     let Inst{18-16} = 0b100;
5936     let Inst{14-13} = idx2;
5937     let Inst{12-11} = {?,?};
5938   }
5939   def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
5940     bits<1> idx;
5941     bits<1> idx2;
5942     let Inst{20} = idx;
5943     let Inst{19-16} = 0b1000;
5944     let Inst{14} = idx2;
5945     let Inst{13-11} = {?,?,?};
5946   }
5947
5948   // For all forms of the INS instruction, the "mov" mnemonic is the
5949   // preferred alias. Why they didn't just call the instruction "mov" in
5950   // the first place is a very good question indeed...
5951   def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
5952                          GPR32, VectorIndexB>;
5953   def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
5954                          GPR32, VectorIndexH>;
5955   def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
5956                          GPR32, VectorIndexS>;
5957   def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
5958                          GPR64, VectorIndexD>;
5959
5960   def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
5961                          VectorIndexB>;
5962   def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
5963                          VectorIndexH>;
5964   def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
5965                          VectorIndexS>;
5966   def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
5967                          VectorIndexD>;
5968 }
5969
5970 //----------------------------------------------------------------------------
5971 // AdvSIMD TBL/TBX
5972 //----------------------------------------------------------------------------
5973
5974 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5975 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
5976                           RegisterOperand listtype, string asm, string kind>
5977   : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
5978        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
5979     Sched<[WriteV]> {
5980   bits<5> Vd;
5981   bits<5> Vn;
5982   bits<5> Vm;
5983   let Inst{31}    = 0;
5984   let Inst{30}    = Q;
5985   let Inst{29-21} = 0b001110000;
5986   let Inst{20-16} = Vm;
5987   let Inst{15}    = 0;
5988   let Inst{14-13} = len;
5989   let Inst{12}    = op;
5990   let Inst{11-10} = 0b00;
5991   let Inst{9-5}   = Vn;
5992   let Inst{4-0}   = Vd;
5993 }
5994
5995 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5996 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
5997                           RegisterOperand listtype, string asm, string kind>
5998   : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
5999        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
6000     Sched<[WriteV]> {
6001   bits<5> Vd;
6002   bits<5> Vn;
6003   bits<5> Vm;
6004   let Inst{31}    = 0;
6005   let Inst{30}    = Q;
6006   let Inst{29-21} = 0b001110000;
6007   let Inst{20-16} = Vm;
6008   let Inst{15}    = 0;
6009   let Inst{14-13} = len;
6010   let Inst{12}    = op;
6011   let Inst{11-10} = 0b00;
6012   let Inst{9-5}   = Vn;
6013   let Inst{4-0}   = Vd;
6014 }
6015
6016 class SIMDTableLookupAlias<string asm, Instruction inst,
6017                           RegisterOperand vectype, RegisterOperand listtype>
6018     : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
6019                 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
6020
6021 multiclass SIMDTableLookup<bit op, string asm> {
6022   def v8i8One   : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
6023                                       asm, ".8b">;
6024   def v8i8Two   : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
6025                                       asm, ".8b">;
6026   def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
6027                                       asm, ".8b">;
6028   def v8i8Four  : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
6029                                       asm, ".8b">;
6030   def v16i8One  : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
6031                                       asm, ".16b">;
6032   def v16i8Two  : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
6033                                       asm, ".16b">;
6034   def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
6035                                       asm, ".16b">;
6036   def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
6037                                       asm, ".16b">;
6038
6039   def : SIMDTableLookupAlias<asm # ".8b",
6040                          !cast<Instruction>(NAME#"v8i8One"),
6041                          V64, VecListOne128>;
6042   def : SIMDTableLookupAlias<asm # ".8b",
6043                          !cast<Instruction>(NAME#"v8i8Two"),
6044                          V64, VecListTwo128>;
6045   def : SIMDTableLookupAlias<asm # ".8b",
6046                          !cast<Instruction>(NAME#"v8i8Three"),
6047                          V64, VecListThree128>;
6048   def : SIMDTableLookupAlias<asm # ".8b",
6049                          !cast<Instruction>(NAME#"v8i8Four"),
6050                          V64, VecListFour128>;
6051   def : SIMDTableLookupAlias<asm # ".16b",
6052                          !cast<Instruction>(NAME#"v16i8One"),
6053                          V128, VecListOne128>;
6054   def : SIMDTableLookupAlias<asm # ".16b",
6055                          !cast<Instruction>(NAME#"v16i8Two"),
6056                          V128, VecListTwo128>;
6057   def : SIMDTableLookupAlias<asm # ".16b",
6058                          !cast<Instruction>(NAME#"v16i8Three"),
6059                          V128, VecListThree128>;
6060   def : SIMDTableLookupAlias<asm # ".16b",
6061                          !cast<Instruction>(NAME#"v16i8Four"),
6062                          V128, VecListFour128>;
6063 }
6064
6065 multiclass SIMDTableLookupTied<bit op, string asm> {
6066   def v8i8One   : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
6067                                       asm, ".8b">;
6068   def v8i8Two   : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
6069                                       asm, ".8b">;
6070   def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
6071                                       asm, ".8b">;
6072   def v8i8Four  : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
6073                                       asm, ".8b">;
6074   def v16i8One  : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
6075                                       asm, ".16b">;
6076   def v16i8Two  : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
6077                                       asm, ".16b">;
6078   def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
6079                                       asm, ".16b">;
6080   def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
6081                                       asm, ".16b">;
6082
6083   def : SIMDTableLookupAlias<asm # ".8b",
6084                          !cast<Instruction>(NAME#"v8i8One"),
6085                          V64, VecListOne128>;
6086   def : SIMDTableLookupAlias<asm # ".8b",
6087                          !cast<Instruction>(NAME#"v8i8Two"),
6088                          V64, VecListTwo128>;
6089   def : SIMDTableLookupAlias<asm # ".8b",
6090                          !cast<Instruction>(NAME#"v8i8Three"),
6091                          V64, VecListThree128>;
6092   def : SIMDTableLookupAlias<asm # ".8b",
6093                          !cast<Instruction>(NAME#"v8i8Four"),
6094                          V64, VecListFour128>;
6095   def : SIMDTableLookupAlias<asm # ".16b",
6096                          !cast<Instruction>(NAME#"v16i8One"),
6097                          V128, VecListOne128>;
6098   def : SIMDTableLookupAlias<asm # ".16b",
6099                          !cast<Instruction>(NAME#"v16i8Two"),
6100                          V128, VecListTwo128>;
6101   def : SIMDTableLookupAlias<asm # ".16b",
6102                          !cast<Instruction>(NAME#"v16i8Three"),
6103                          V128, VecListThree128>;
6104   def : SIMDTableLookupAlias<asm # ".16b",
6105                          !cast<Instruction>(NAME#"v16i8Four"),
6106                          V128, VecListFour128>;
6107 }
6108
6109
6110 //----------------------------------------------------------------------------
6111 // AdvSIMD scalar CPY
6112 //----------------------------------------------------------------------------
6113 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6114 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
6115                         string kind, Operand idxtype>
6116   : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
6117        "{\t$dst, $src" # kind # "$idx" #
6118        "|\t$dst, $src$idx}", "", []>,
6119     Sched<[WriteV]> {
6120   bits<5> dst;
6121   bits<5> src;
6122   let Inst{31-21} = 0b01011110000;
6123   let Inst{15-10} = 0b000001;
6124   let Inst{9-5}   = src;
6125   let Inst{4-0}   = dst;
6126 }
6127
6128 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
6129       RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
6130     : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
6131                     # "|\t$dst, $src$index}",
6132                 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
6133
6134
6135 multiclass SIMDScalarCPY<string asm> {
6136   def i8  : BaseSIMDScalarCPY<FPR8,  V128, ".b", VectorIndexB> {
6137     bits<4> idx;
6138     let Inst{20-17} = idx;
6139     let Inst{16} = 1;
6140   }
6141   def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
6142     bits<3> idx;
6143     let Inst{20-18} = idx;
6144     let Inst{17-16} = 0b10;
6145   }
6146   def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
6147     bits<2> idx;
6148     let Inst{20-19} = idx;
6149     let Inst{18-16} = 0b100;
6150   }
6151   def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
6152     bits<1> idx;
6153     let Inst{20} = idx;
6154     let Inst{19-16} = 0b1000;
6155   }
6156
6157   def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
6158                                                           VectorIndexD:$idx)))),
6159             (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
6160
6161   // 'DUP' mnemonic aliases.
6162   def : SIMDScalarCPYAlias<"dup", ".b",
6163                            !cast<Instruction>(NAME#"i8"),
6164                            FPR8, V128, VectorIndexB>;
6165   def : SIMDScalarCPYAlias<"dup", ".h",
6166                            !cast<Instruction>(NAME#"i16"),
6167                            FPR16, V128, VectorIndexH>;
6168   def : SIMDScalarCPYAlias<"dup", ".s",
6169                            !cast<Instruction>(NAME#"i32"),
6170                            FPR32, V128, VectorIndexS>;
6171   def : SIMDScalarCPYAlias<"dup", ".d",
6172                            !cast<Instruction>(NAME#"i64"),
6173                            FPR64, V128, VectorIndexD>;
6174 }
6175
6176 //----------------------------------------------------------------------------
6177 // AdvSIMD modified immediate instructions
6178 //----------------------------------------------------------------------------
6179
6180 class BaseSIMDModifiedImm<bit Q, bit op, dag oops, dag iops,
6181                           string asm, string op_string,
6182                           string cstr, list<dag> pattern>
6183   : I<oops, iops, asm, op_string, cstr, pattern>,
6184     Sched<[WriteV]> {
6185   bits<5> Rd;
6186   bits<8> imm8;
6187   let Inst{31}    = 0;
6188   let Inst{30}    = Q;
6189   let Inst{29}    = op;
6190   let Inst{28-19} = 0b0111100000;
6191   let Inst{18-16} = imm8{7-5};
6192   let Inst{11-10} = 0b01;
6193   let Inst{9-5}   = imm8{4-0};
6194   let Inst{4-0}   = Rd;
6195 }
6196
6197 class BaseSIMDModifiedImmVector<bit Q, bit op, RegisterOperand vectype,
6198                                 Operand immtype, dag opt_shift_iop,
6199                                 string opt_shift, string asm, string kind,
6200                                 list<dag> pattern>
6201   : BaseSIMDModifiedImm<Q, op, (outs vectype:$Rd),
6202                         !con((ins immtype:$imm8), opt_shift_iop), asm,
6203                         "{\t$Rd" # kind # ", $imm8" # opt_shift #
6204                         "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6205                         "", pattern> {
6206   let DecoderMethod = "DecodeModImmInstruction";
6207 }
6208
6209 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
6210                                 Operand immtype, dag opt_shift_iop,
6211                                 string opt_shift, string asm, string kind,
6212                                 list<dag> pattern>
6213   : BaseSIMDModifiedImm<Q, op, (outs vectype:$dst),
6214                         !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
6215                         asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
6216                              "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6217                         "$Rd = $dst", pattern> {
6218   let DecoderMethod = "DecodeModImmTiedInstruction";
6219 }
6220
6221 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
6222                                      RegisterOperand vectype, string asm,
6223                                      string kind, list<dag> pattern>
6224   : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6225                               (ins logical_vec_shift:$shift),
6226                               "$shift", asm, kind, pattern> {
6227   bits<2> shift;
6228   let Inst{15}    = b15_b12{1};
6229   let Inst{14-13} = shift;
6230   let Inst{12}    = b15_b12{0};
6231 }
6232
6233 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
6234                                      RegisterOperand vectype, string asm,
6235                                      string kind, list<dag> pattern>
6236   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6237                               (ins logical_vec_shift:$shift),
6238                               "$shift", asm, kind, pattern> {
6239   bits<2> shift;
6240   let Inst{15}    = b15_b12{1};
6241   let Inst{14-13} = shift;
6242   let Inst{12}    = b15_b12{0};
6243 }
6244
6245
6246 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
6247                                          RegisterOperand vectype, string asm,
6248                                          string kind, list<dag> pattern>
6249   : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6250                               (ins logical_vec_hw_shift:$shift),
6251                               "$shift", asm, kind, pattern> {
6252   bits<2> shift;
6253   let Inst{15} = b15_b12{1};
6254   let Inst{14} = 0;
6255   let Inst{13} = shift{0};
6256   let Inst{12} = b15_b12{0};
6257 }
6258
6259 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
6260                                          RegisterOperand vectype, string asm,
6261                                          string kind, list<dag> pattern>
6262   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6263                               (ins logical_vec_hw_shift:$shift),
6264                               "$shift", asm, kind, pattern> {
6265   bits<2> shift;
6266   let Inst{15} = b15_b12{1};
6267   let Inst{14} = 0;
6268   let Inst{13} = shift{0};
6269   let Inst{12} = b15_b12{0};
6270 }
6271
6272 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
6273                                       string asm> {
6274   def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
6275                                                  asm, ".4h", []>;
6276   def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
6277                                                  asm, ".8h", []>;
6278
6279   def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
6280                                              asm, ".2s", []>;
6281   def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
6282                                              asm, ".4s", []>;
6283 }
6284
6285 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
6286                                       bits<2> w_cmode, string asm,
6287                                       SDNode OpNode> {
6288   def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
6289                                                  asm, ".4h",
6290              [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
6291                                              imm0_255:$imm8,
6292                                              (i32 imm:$shift)))]>;
6293   def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
6294                                                  asm, ".8h",
6295              [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
6296                                               imm0_255:$imm8,
6297                                               (i32 imm:$shift)))]>;
6298
6299   def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
6300                                              asm, ".2s",
6301              [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
6302                                              imm0_255:$imm8,
6303                                              (i32 imm:$shift)))]>;
6304   def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
6305                                              asm, ".4s",
6306              [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
6307                                               imm0_255:$imm8,
6308                                               (i32 imm:$shift)))]>;
6309 }
6310
6311 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
6312                              RegisterOperand vectype, string asm,
6313                              string kind, list<dag> pattern>
6314   : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6315                               (ins move_vec_shift:$shift),
6316                               "$shift", asm, kind, pattern> {
6317   bits<1> shift;
6318   let Inst{15-13} = cmode{3-1};
6319   let Inst{12}    = shift;
6320 }
6321
6322 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bits<4> cmode,
6323                                    RegisterOperand vectype,
6324                                    Operand imm_type, string asm,
6325                                    string kind, list<dag> pattern>
6326   : BaseSIMDModifiedImmVector<Q, op, vectype, imm_type, (ins), "",
6327                               asm, kind, pattern> {
6328   let Inst{15-12} = cmode;
6329 }
6330
6331 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
6332                                    list<dag> pattern>
6333   : BaseSIMDModifiedImm<Q, op, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
6334                         "\t$Rd, $imm8", "", pattern> {
6335   let Inst{15-12} = cmode;
6336   let DecoderMethod = "DecodeModImmInstruction";
6337 }
6338
6339 //----------------------------------------------------------------------------
6340 // AdvSIMD indexed element
6341 //----------------------------------------------------------------------------
6342
6343 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6344 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6345                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
6346                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
6347                       string apple_kind, string dst_kind, string lhs_kind,
6348                       string rhs_kind, list<dag> pattern>
6349   : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
6350       asm,
6351       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6352       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
6353     Sched<[WriteV]> {
6354   bits<5> Rd;
6355   bits<5> Rn;
6356   bits<5> Rm;
6357
6358   let Inst{31}    = 0;
6359   let Inst{30}    = Q;
6360   let Inst{29}    = U;
6361   let Inst{28}    = Scalar;
6362   let Inst{27-24} = 0b1111;
6363   let Inst{23-22} = size;
6364   // Bit 21 must be set by the derived class.
6365   let Inst{20-16} = Rm;
6366   let Inst{15-12} = opc;
6367   // Bit 11 must be set by the derived class.
6368   let Inst{10}    = 0;
6369   let Inst{9-5}   = Rn;
6370   let Inst{4-0}   = Rd;
6371 }
6372
6373 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6374 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6375                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
6376                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
6377                       string apple_kind, string dst_kind, string lhs_kind,
6378                       string rhs_kind, list<dag> pattern>
6379   : I<(outs dst_reg:$dst),
6380       (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
6381       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6382       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
6383     Sched<[WriteV]> {
6384   bits<5> Rd;
6385   bits<5> Rn;
6386   bits<5> Rm;
6387
6388   let Inst{31}    = 0;
6389   let Inst{30}    = Q;
6390   let Inst{29}    = U;
6391   let Inst{28}    = Scalar;
6392   let Inst{27-24} = 0b1111;
6393   let Inst{23-22} = size;
6394   // Bit 21 must be set by the derived class.
6395   let Inst{20-16} = Rm;
6396   let Inst{15-12} = opc;
6397   // Bit 11 must be set by the derived class.
6398   let Inst{10}    = 0;
6399   let Inst{9-5}   = Rn;
6400   let Inst{4-0}   = Rd;
6401 }
6402
6403 multiclass SIMDFPIndexedSD<bit U, bits<4> opc, string asm,
6404                            SDPatternOperator OpNode> {
6405   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6406                                       V64, V64,
6407                                       V128, VectorIndexS,
6408                                       asm, ".2s", ".2s", ".2s", ".s",
6409     [(set (v2f32 V64:$Rd),
6410         (OpNode (v2f32 V64:$Rn),
6411          (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6412     bits<2> idx;
6413     let Inst{11} = idx{1};
6414     let Inst{21} = idx{0};
6415   }
6416
6417   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6418                                       V128, V128,
6419                                       V128, VectorIndexS,
6420                                       asm, ".4s", ".4s", ".4s", ".s",
6421     [(set (v4f32 V128:$Rd),
6422         (OpNode (v4f32 V128:$Rn),
6423          (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6424     bits<2> idx;
6425     let Inst{11} = idx{1};
6426     let Inst{21} = idx{0};
6427   }
6428
6429   def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
6430                                       V128, V128,
6431                                       V128, VectorIndexD,
6432                                       asm, ".2d", ".2d", ".2d", ".d",
6433     [(set (v2f64 V128:$Rd),
6434         (OpNode (v2f64 V128:$Rn),
6435          (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
6436     bits<1> idx;
6437     let Inst{11} = idx{0};
6438     let Inst{21} = 0;
6439   }
6440
6441   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6442                                       FPR32Op, FPR32Op, V128, VectorIndexS,
6443                                       asm, ".s", "", "", ".s",
6444     [(set (f32 FPR32Op:$Rd),
6445           (OpNode (f32 FPR32Op:$Rn),
6446                   (f32 (vector_extract (v4f32 V128:$Rm),
6447                                        VectorIndexS:$idx))))]> {
6448     bits<2> idx;
6449     let Inst{11} = idx{1};
6450     let Inst{21} = idx{0};
6451   }
6452
6453   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
6454                                       FPR64Op, FPR64Op, V128, VectorIndexD,
6455                                       asm, ".d", "", "", ".d",
6456     [(set (f64 FPR64Op:$Rd),
6457           (OpNode (f64 FPR64Op:$Rn),
6458                   (f64 (vector_extract (v2f64 V128:$Rm),
6459                                        VectorIndexD:$idx))))]> {
6460     bits<1> idx;
6461     let Inst{11} = idx{0};
6462     let Inst{21} = 0;
6463   }
6464 }
6465
6466 multiclass SIMDFPIndexedSDTiedPatterns<string INST, SDPatternOperator OpNode> {
6467   // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
6468   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6469                            (AArch64duplane32 (v4f32 V128:$Rm),
6470                                            VectorIndexS:$idx))),
6471             (!cast<Instruction>(INST # v2i32_indexed)
6472                 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6473   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6474                            (AArch64dup (f32 FPR32Op:$Rm)))),
6475             (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
6476                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6477
6478
6479   // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
6480   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6481                            (AArch64duplane32 (v4f32 V128:$Rm),
6482                                            VectorIndexS:$idx))),
6483             (!cast<Instruction>(INST # "v4i32_indexed")
6484                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6485   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6486                            (AArch64dup (f32 FPR32Op:$Rm)))),
6487             (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
6488                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6489
6490   // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
6491   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6492                            (AArch64duplane64 (v2f64 V128:$Rm),
6493                                            VectorIndexD:$idx))),
6494             (!cast<Instruction>(INST # "v2i64_indexed")
6495                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6496   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6497                            (AArch64dup (f64 FPR64Op:$Rm)))),
6498             (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
6499                 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
6500
6501   // 2 variants for 32-bit scalar version: extract from .2s or from .4s
6502   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6503                          (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
6504             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6505                 V128:$Rm, VectorIndexS:$idx)>;
6506   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6507                          (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
6508             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6509                 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
6510
6511   // 1 variant for 64-bit scalar version: extract from .1d or from .2d
6512   def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
6513                          (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
6514             (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
6515                 V128:$Rm, VectorIndexD:$idx)>;
6516 }
6517
6518 multiclass SIMDFPIndexedSDTied<bit U, bits<4> opc, string asm> {
6519   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
6520                                           V128, VectorIndexS,
6521                                           asm, ".2s", ".2s", ".2s", ".s", []> {
6522     bits<2> idx;
6523     let Inst{11} = idx{1};
6524     let Inst{21} = idx{0};
6525   }
6526
6527   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6528                                       V128, V128,
6529                                       V128, VectorIndexS,
6530                                       asm, ".4s", ".4s", ".4s", ".s", []> {
6531     bits<2> idx;
6532     let Inst{11} = idx{1};
6533     let Inst{21} = idx{0};
6534   }
6535
6536   def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
6537                                       V128, V128,
6538                                       V128, VectorIndexD,
6539                                       asm, ".2d", ".2d", ".2d", ".d", []> {
6540     bits<1> idx;
6541     let Inst{11} = idx{0};
6542     let Inst{21} = 0;
6543   }
6544
6545
6546   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6547                                       FPR32Op, FPR32Op, V128, VectorIndexS,
6548                                       asm, ".s", "", "", ".s", []> {
6549     bits<2> idx;
6550     let Inst{11} = idx{1};
6551     let Inst{21} = idx{0};
6552   }
6553
6554   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
6555                                       FPR64Op, FPR64Op, V128, VectorIndexD,
6556                                       asm, ".d", "", "", ".d", []> {
6557     bits<1> idx;
6558     let Inst{11} = idx{0};
6559     let Inst{21} = 0;
6560   }
6561 }
6562
6563 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
6564                          SDPatternOperator OpNode> {
6565   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
6566                                       V128_lo, VectorIndexH,
6567                                       asm, ".4h", ".4h", ".4h", ".h",
6568     [(set (v4i16 V64:$Rd),
6569         (OpNode (v4i16 V64:$Rn),
6570          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6571     bits<3> idx;
6572     let Inst{11} = idx{2};
6573     let Inst{21} = idx{1};
6574     let Inst{20} = idx{0};
6575   }
6576
6577   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6578                                       V128, V128,
6579                                       V128_lo, VectorIndexH,
6580                                       asm, ".8h", ".8h", ".8h", ".h",
6581     [(set (v8i16 V128:$Rd),
6582        (OpNode (v8i16 V128:$Rn),
6583          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6584     bits<3> idx;
6585     let Inst{11} = idx{2};
6586     let Inst{21} = idx{1};
6587     let Inst{20} = idx{0};
6588   }
6589
6590   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6591                                       V64, V64,
6592                                       V128, VectorIndexS,
6593                                       asm, ".2s", ".2s", ".2s",  ".s",
6594     [(set (v2i32 V64:$Rd),
6595        (OpNode (v2i32 V64:$Rn),
6596           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6597     bits<2> idx;
6598     let Inst{11} = idx{1};
6599     let Inst{21} = idx{0};
6600   }
6601
6602   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6603                                       V128, V128,
6604                                       V128, VectorIndexS,
6605                                       asm, ".4s", ".4s", ".4s", ".s",
6606     [(set (v4i32 V128:$Rd),
6607        (OpNode (v4i32 V128:$Rn),
6608           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6609     bits<2> idx;
6610     let Inst{11} = idx{1};
6611     let Inst{21} = idx{0};
6612   }
6613
6614   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6615                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
6616                                       asm, ".h", "", "", ".h", []> {
6617     bits<3> idx;
6618     let Inst{11} = idx{2};
6619     let Inst{21} = idx{1};
6620     let Inst{20} = idx{0};
6621   }
6622
6623   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6624                                       FPR32Op, FPR32Op, V128, VectorIndexS,
6625                                       asm, ".s", "", "", ".s",
6626       [(set (i32 FPR32Op:$Rd),
6627             (OpNode FPR32Op:$Rn,
6628                     (i32 (vector_extract (v4i32 V128:$Rm),
6629                                          VectorIndexS:$idx))))]> {
6630     bits<2> idx;
6631     let Inst{11} = idx{1};
6632     let Inst{21} = idx{0};
6633   }
6634 }
6635
6636 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
6637                                SDPatternOperator OpNode> {
6638   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6639                                       V64, V64,
6640                                       V128_lo, VectorIndexH,
6641                                       asm, ".4h", ".4h", ".4h", ".h",
6642     [(set (v4i16 V64:$Rd),
6643         (OpNode (v4i16 V64:$Rn),
6644          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6645     bits<3> idx;
6646     let Inst{11} = idx{2};
6647     let Inst{21} = idx{1};
6648     let Inst{20} = idx{0};
6649   }
6650
6651   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6652                                       V128, V128,
6653                                       V128_lo, VectorIndexH,
6654                                       asm, ".8h", ".8h", ".8h", ".h",
6655     [(set (v8i16 V128:$Rd),
6656        (OpNode (v8i16 V128:$Rn),
6657          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6658     bits<3> idx;
6659     let Inst{11} = idx{2};
6660     let Inst{21} = idx{1};
6661     let Inst{20} = idx{0};
6662   }
6663
6664   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6665                                       V64, V64,
6666                                       V128, VectorIndexS,
6667                                       asm, ".2s", ".2s", ".2s", ".s",
6668     [(set (v2i32 V64:$Rd),
6669        (OpNode (v2i32 V64:$Rn),
6670           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6671     bits<2> idx;
6672     let Inst{11} = idx{1};
6673     let Inst{21} = idx{0};
6674   }
6675
6676   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6677                                       V128, V128,
6678                                       V128, VectorIndexS,
6679                                       asm, ".4s", ".4s", ".4s", ".s",
6680     [(set (v4i32 V128:$Rd),
6681        (OpNode (v4i32 V128:$Rn),
6682           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6683     bits<2> idx;
6684     let Inst{11} = idx{1};
6685     let Inst{21} = idx{0};
6686   }
6687 }
6688
6689 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
6690                                    SDPatternOperator OpNode> {
6691   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
6692                                           V128_lo, VectorIndexH,
6693                                           asm, ".4h", ".4h", ".4h", ".h",
6694     [(set (v4i16 V64:$dst),
6695         (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
6696          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6697     bits<3> idx;
6698     let Inst{11} = idx{2};
6699     let Inst{21} = idx{1};
6700     let Inst{20} = idx{0};
6701   }
6702
6703   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6704                                       V128, V128,
6705                                       V128_lo, VectorIndexH,
6706                                       asm, ".8h", ".8h", ".8h", ".h",
6707     [(set (v8i16 V128:$dst),
6708        (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
6709          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6710     bits<3> idx;
6711     let Inst{11} = idx{2};
6712     let Inst{21} = idx{1};
6713     let Inst{20} = idx{0};
6714   }
6715
6716   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6717                                       V64, V64,
6718                                       V128, VectorIndexS,
6719                                       asm, ".2s", ".2s", ".2s", ".s",
6720     [(set (v2i32 V64:$dst),
6721        (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
6722           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6723     bits<2> idx;
6724     let Inst{11} = idx{1};
6725     let Inst{21} = idx{0};
6726   }
6727
6728   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6729                                       V128, V128,
6730                                       V128, VectorIndexS,
6731                                       asm, ".4s", ".4s", ".4s", ".s",
6732     [(set (v4i32 V128:$dst),
6733        (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
6734           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6735     bits<2> idx;
6736     let Inst{11} = idx{1};
6737     let Inst{21} = idx{0};
6738   }
6739 }
6740
6741 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
6742                              SDPatternOperator OpNode> {
6743   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6744                                       V128, V64,
6745                                       V128_lo, VectorIndexH,
6746                                       asm, ".4s", ".4s", ".4h", ".h",
6747     [(set (v4i32 V128:$Rd),
6748         (OpNode (v4i16 V64:$Rn),
6749          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6750     bits<3> idx;
6751     let Inst{11} = idx{2};
6752     let Inst{21} = idx{1};
6753     let Inst{20} = idx{0};
6754   }
6755
6756   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6757                                       V128, V128,
6758                                       V128_lo, VectorIndexH,
6759                                       asm#"2", ".4s", ".4s", ".8h", ".h",
6760     [(set (v4i32 V128:$Rd),
6761           (OpNode (extract_high_v8i16 V128:$Rn),
6762                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6763                                                       VectorIndexH:$idx))))]> {
6764
6765     bits<3> idx;
6766     let Inst{11} = idx{2};
6767     let Inst{21} = idx{1};
6768     let Inst{20} = idx{0};
6769   }
6770
6771   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6772                                       V128, V64,
6773                                       V128, VectorIndexS,
6774                                       asm, ".2d", ".2d", ".2s", ".s",
6775     [(set (v2i64 V128:$Rd),
6776         (OpNode (v2i32 V64:$Rn),
6777          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6778     bits<2> idx;
6779     let Inst{11} = idx{1};
6780     let Inst{21} = idx{0};
6781   }
6782
6783   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6784                                       V128, V128,
6785                                       V128, VectorIndexS,
6786                                       asm#"2", ".2d", ".2d", ".4s", ".s",
6787     [(set (v2i64 V128:$Rd),
6788           (OpNode (extract_high_v4i32 V128:$Rn),
6789                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
6790                                                       VectorIndexS:$idx))))]> {
6791     bits<2> idx;
6792     let Inst{11} = idx{1};
6793     let Inst{21} = idx{0};
6794   }
6795
6796   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6797                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6798                                       asm, ".h", "", "", ".h", []> {
6799     bits<3> idx;
6800     let Inst{11} = idx{2};
6801     let Inst{21} = idx{1};
6802     let Inst{20} = idx{0};
6803   }
6804
6805   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6806                                       FPR64Op, FPR32Op, V128, VectorIndexS,
6807                                       asm, ".s", "", "", ".s", []> {
6808     bits<2> idx;
6809     let Inst{11} = idx{1};
6810     let Inst{21} = idx{0};
6811   }
6812 }
6813
6814 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
6815                                        SDPatternOperator Accum> {
6816   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
6817                                       V128, V64,
6818                                       V128_lo, VectorIndexH,
6819                                       asm, ".4s", ".4s", ".4h", ".h",
6820     [(set (v4i32 V128:$dst),
6821           (Accum (v4i32 V128:$Rd),
6822                  (v4i32 (int_aarch64_neon_sqdmull
6823                              (v4i16 V64:$Rn),
6824                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6825                                                     VectorIndexH:$idx))))))]> {
6826     bits<3> idx;
6827     let Inst{11} = idx{2};
6828     let Inst{21} = idx{1};
6829     let Inst{20} = idx{0};
6830   }
6831
6832   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
6833   // intermediate EXTRACT_SUBREG would be untyped.
6834   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
6835                 (i32 (vector_extract (v4i32
6836                          (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
6837                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6838                                                     VectorIndexH:$idx)))),
6839                          (i64 0))))),
6840             (EXTRACT_SUBREG
6841                 (!cast<Instruction>(NAME # v4i16_indexed)
6842                     (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
6843                     V128_lo:$Rm, VectorIndexH:$idx),
6844                 ssub)>;
6845
6846   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6847                                       V128, V128,
6848                                       V128_lo, VectorIndexH,
6849                                       asm#"2", ".4s", ".4s", ".8h", ".h",
6850     [(set (v4i32 V128:$dst),
6851           (Accum (v4i32 V128:$Rd),
6852                  (v4i32 (int_aarch64_neon_sqdmull
6853                             (extract_high_v8i16 V128:$Rn),
6854                             (extract_high_v8i16
6855                                 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6856                                                 VectorIndexH:$idx))))))]> {
6857     bits<3> idx;
6858     let Inst{11} = idx{2};
6859     let Inst{21} = idx{1};
6860     let Inst{20} = idx{0};
6861   }
6862
6863   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6864                                       V128, V64,
6865                                       V128, VectorIndexS,
6866                                       asm, ".2d", ".2d", ".2s", ".s",
6867     [(set (v2i64 V128:$dst),
6868         (Accum (v2i64 V128:$Rd),
6869                (v2i64 (int_aarch64_neon_sqdmull
6870                           (v2i32 V64:$Rn),
6871                           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
6872                                                  VectorIndexS:$idx))))))]> {
6873     bits<2> idx;
6874     let Inst{11} = idx{1};
6875     let Inst{21} = idx{0};
6876   }
6877
6878   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6879                                       V128, V128,
6880                                       V128, VectorIndexS,
6881                                       asm#"2", ".2d", ".2d", ".4s", ".s",
6882     [(set (v2i64 V128:$dst),
6883           (Accum (v2i64 V128:$Rd),
6884                  (v2i64 (int_aarch64_neon_sqdmull
6885                             (extract_high_v4i32 V128:$Rn),
6886                             (extract_high_v4i32
6887                                 (AArch64duplane32 (v4i32 V128:$Rm),
6888                                                 VectorIndexS:$idx))))))]> {
6889     bits<2> idx;
6890     let Inst{11} = idx{1};
6891     let Inst{21} = idx{0};
6892   }
6893
6894   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
6895                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6896                                       asm, ".h", "", "", ".h", []> {
6897     bits<3> idx;
6898     let Inst{11} = idx{2};
6899     let Inst{21} = idx{1};
6900     let Inst{20} = idx{0};
6901   }
6902
6903
6904   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6905                                       FPR64Op, FPR32Op, V128, VectorIndexS,
6906                                       asm, ".s", "", "", ".s",
6907     [(set (i64 FPR64Op:$dst),
6908           (Accum (i64 FPR64Op:$Rd),
6909                  (i64 (int_aarch64_neon_sqdmulls_scalar
6910                             (i32 FPR32Op:$Rn),
6911                             (i32 (vector_extract (v4i32 V128:$Rm),
6912                                                  VectorIndexS:$idx))))))]> {
6913
6914     bits<2> idx;
6915     let Inst{11} = idx{1};
6916     let Inst{21} = idx{0};
6917   }
6918 }
6919
6920 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
6921                                    SDPatternOperator OpNode> {
6922   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6923   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6924                                       V128, V64,
6925                                       V128_lo, VectorIndexH,
6926                                       asm, ".4s", ".4s", ".4h", ".h",
6927     [(set (v4i32 V128:$Rd),
6928         (OpNode (v4i16 V64:$Rn),
6929          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6930     bits<3> idx;
6931     let Inst{11} = idx{2};
6932     let Inst{21} = idx{1};
6933     let Inst{20} = idx{0};
6934   }
6935
6936   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6937                                       V128, V128,
6938                                       V128_lo, VectorIndexH,
6939                                       asm#"2", ".4s", ".4s", ".8h", ".h",
6940     [(set (v4i32 V128:$Rd),
6941           (OpNode (extract_high_v8i16 V128:$Rn),
6942                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6943                                                       VectorIndexH:$idx))))]> {
6944
6945     bits<3> idx;
6946     let Inst{11} = idx{2};
6947     let Inst{21} = idx{1};
6948     let Inst{20} = idx{0};
6949   }
6950
6951   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6952                                       V128, V64,
6953                                       V128, VectorIndexS,
6954                                       asm, ".2d", ".2d", ".2s", ".s",
6955     [(set (v2i64 V128:$Rd),
6956         (OpNode (v2i32 V64:$Rn),
6957          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6958     bits<2> idx;
6959     let Inst{11} = idx{1};
6960     let Inst{21} = idx{0};
6961   }
6962
6963   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6964                                       V128, V128,
6965                                       V128, VectorIndexS,
6966                                       asm#"2", ".2d", ".2d", ".4s", ".s",
6967     [(set (v2i64 V128:$Rd),
6968           (OpNode (extract_high_v4i32 V128:$Rn),
6969                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
6970                                                       VectorIndexS:$idx))))]> {
6971     bits<2> idx;
6972     let Inst{11} = idx{1};
6973     let Inst{21} = idx{0};
6974   }
6975   }
6976 }
6977
6978 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
6979                                        SDPatternOperator OpNode> {
6980   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6981   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
6982                                       V128, V64,
6983                                       V128_lo, VectorIndexH,
6984                                       asm, ".4s", ".4s", ".4h", ".h",
6985     [(set (v4i32 V128:$dst),
6986         (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
6987          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6988     bits<3> idx;
6989     let Inst{11} = idx{2};
6990     let Inst{21} = idx{1};
6991     let Inst{20} = idx{0};
6992   }
6993
6994   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6995                                       V128, V128,
6996                                       V128_lo, VectorIndexH,
6997                                       asm#"2", ".4s", ".4s", ".8h", ".h",
6998     [(set (v4i32 V128:$dst),
6999           (OpNode (v4i32 V128:$Rd),
7000                   (extract_high_v8i16 V128:$Rn),
7001                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7002                                                       VectorIndexH:$idx))))]> {
7003     bits<3> idx;
7004     let Inst{11} = idx{2};
7005     let Inst{21} = idx{1};
7006     let Inst{20} = idx{0};
7007   }
7008
7009   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7010                                       V128, V64,
7011                                       V128, VectorIndexS,
7012                                       asm, ".2d", ".2d", ".2s", ".s",
7013     [(set (v2i64 V128:$dst),
7014         (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
7015          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7016     bits<2> idx;
7017     let Inst{11} = idx{1};
7018     let Inst{21} = idx{0};
7019   }
7020
7021   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7022                                       V128, V128,
7023                                       V128, VectorIndexS,
7024                                       asm#"2", ".2d", ".2d", ".4s", ".s",
7025     [(set (v2i64 V128:$dst),
7026           (OpNode (v2i64 V128:$Rd),
7027                   (extract_high_v4i32 V128:$Rn),
7028                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7029                                                       VectorIndexS:$idx))))]> {
7030     bits<2> idx;
7031     let Inst{11} = idx{1};
7032     let Inst{21} = idx{0};
7033   }
7034   }
7035 }
7036
7037 //----------------------------------------------------------------------------
7038 // AdvSIMD scalar shift by immediate
7039 //----------------------------------------------------------------------------
7040
7041 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7042 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
7043                      RegisterClass regtype1, RegisterClass regtype2,
7044                      Operand immtype, string asm, list<dag> pattern>
7045   : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
7046       asm, "\t$Rd, $Rn, $imm", "", pattern>,
7047     Sched<[WriteV]> {
7048   bits<5> Rd;
7049   bits<5> Rn;
7050   bits<7> imm;
7051   let Inst{31-30} = 0b01;
7052   let Inst{29}    = U;
7053   let Inst{28-23} = 0b111110;
7054   let Inst{22-16} = fixed_imm;
7055   let Inst{15-11} = opc;
7056   let Inst{10}    = 1;
7057   let Inst{9-5} = Rn;
7058   let Inst{4-0} = Rd;
7059 }
7060
7061 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7062 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
7063                      RegisterClass regtype1, RegisterClass regtype2,
7064                      Operand immtype, string asm, list<dag> pattern>
7065   : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
7066       asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
7067     Sched<[WriteV]> {
7068   bits<5> Rd;
7069   bits<5> Rn;
7070   bits<7> imm;
7071   let Inst{31-30} = 0b01;
7072   let Inst{29}    = U;
7073   let Inst{28-23} = 0b111110;
7074   let Inst{22-16} = fixed_imm;
7075   let Inst{15-11} = opc;
7076   let Inst{10}    = 1;
7077   let Inst{9-5} = Rn;
7078   let Inst{4-0} = Rd;
7079 }
7080
7081
7082 multiclass SIMDScalarRShiftSD<bit U, bits<5> opc, string asm> {
7083   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7084                               FPR32, FPR32, vecshiftR32, asm, []> {
7085     let Inst{20-16} = imm{4-0};
7086   }
7087
7088   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7089                               FPR64, FPR64, vecshiftR64, asm, []> {
7090     let Inst{21-16} = imm{5-0};
7091   }
7092 }
7093
7094 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
7095                              SDPatternOperator OpNode> {
7096   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7097                               FPR64, FPR64, vecshiftR64, asm,
7098   [(set (i64 FPR64:$Rd),
7099      (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
7100     let Inst{21-16} = imm{5-0};
7101   }
7102
7103   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
7104             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
7105 }
7106
7107 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
7108                                  SDPatternOperator OpNode = null_frag> {
7109   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7110                               FPR64, FPR64, vecshiftR64, asm,
7111   [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
7112                                                    (i32 vecshiftR64:$imm)))]> {
7113     let Inst{21-16} = imm{5-0};
7114   }
7115
7116   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
7117                            (i32 vecshiftR64:$imm))),
7118             (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
7119                                             vecshiftR64:$imm)>;
7120 }
7121
7122 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
7123                              SDPatternOperator OpNode> {
7124   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7125                               FPR64, FPR64, vecshiftL64, asm,
7126     [(set (v1i64 FPR64:$Rd),
7127        (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7128     let Inst{21-16} = imm{5-0};
7129   }
7130 }
7131
7132 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7133 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
7134   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7135                               FPR64, FPR64, vecshiftL64, asm, []> {
7136     let Inst{21-16} = imm{5-0};
7137   }
7138 }
7139
7140 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7141 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
7142                                SDPatternOperator OpNode = null_frag> {
7143   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7144                               FPR8, FPR16, vecshiftR8, asm, []> {
7145     let Inst{18-16} = imm{2-0};
7146   }
7147
7148   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7149                               FPR16, FPR32, vecshiftR16, asm, []> {
7150     let Inst{19-16} = imm{3-0};
7151   }
7152
7153   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7154                               FPR32, FPR64, vecshiftR32, asm,
7155     [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
7156     let Inst{20-16} = imm{4-0};
7157   }
7158 }
7159
7160 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
7161                                 SDPatternOperator OpNode> {
7162   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7163                               FPR8, FPR8, vecshiftL8, asm, []> {
7164     let Inst{18-16} = imm{2-0};
7165   }
7166
7167   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7168                               FPR16, FPR16, vecshiftL16, asm, []> {
7169     let Inst{19-16} = imm{3-0};
7170   }
7171
7172   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7173                               FPR32, FPR32, vecshiftL32, asm,
7174     [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
7175     let Inst{20-16} = imm{4-0};
7176   }
7177
7178   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7179                               FPR64, FPR64, vecshiftL64, asm,
7180     [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7181     let Inst{21-16} = imm{5-0};
7182   }
7183
7184   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
7185             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
7186 }
7187
7188 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
7189   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7190                               FPR8, FPR8, vecshiftR8, asm, []> {
7191     let Inst{18-16} = imm{2-0};
7192   }
7193
7194   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7195                               FPR16, FPR16, vecshiftR16, asm, []> {
7196     let Inst{19-16} = imm{3-0};
7197   }
7198
7199   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7200                               FPR32, FPR32, vecshiftR32, asm, []> {
7201     let Inst{20-16} = imm{4-0};
7202   }
7203
7204   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7205                               FPR64, FPR64, vecshiftR64, asm, []> {
7206     let Inst{21-16} = imm{5-0};
7207   }
7208 }
7209
7210 //----------------------------------------------------------------------------
7211 // AdvSIMD vector x indexed element
7212 //----------------------------------------------------------------------------
7213
7214 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7215 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7216                      RegisterOperand dst_reg, RegisterOperand src_reg,
7217                      Operand immtype,
7218                      string asm, string dst_kind, string src_kind,
7219                      list<dag> pattern>
7220   : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
7221       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7222            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
7223     Sched<[WriteV]> {
7224   bits<5> Rd;
7225   bits<5> Rn;
7226   let Inst{31}    = 0;
7227   let Inst{30}    = Q;
7228   let Inst{29}    = U;
7229   let Inst{28-23} = 0b011110;
7230   let Inst{22-16} = fixed_imm;
7231   let Inst{15-11} = opc;
7232   let Inst{10}    = 1;
7233   let Inst{9-5}   = Rn;
7234   let Inst{4-0}   = Rd;
7235 }
7236
7237 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7238 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7239                      RegisterOperand vectype1, RegisterOperand vectype2,
7240                      Operand immtype,
7241                      string asm, string dst_kind, string src_kind,
7242                      list<dag> pattern>
7243   : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
7244       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7245            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
7246     Sched<[WriteV]> {
7247   bits<5> Rd;
7248   bits<5> Rn;
7249   let Inst{31}    = 0;
7250   let Inst{30}    = Q;
7251   let Inst{29}    = U;
7252   let Inst{28-23} = 0b011110;
7253   let Inst{22-16} = fixed_imm;
7254   let Inst{15-11} = opc;
7255   let Inst{10}    = 1;
7256   let Inst{9-5}   = Rn;
7257   let Inst{4-0}   = Rd;
7258 }
7259
7260 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
7261                               Intrinsic OpNode> {
7262   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7263                                   V64, V64, vecshiftR32,
7264                                   asm, ".2s", ".2s",
7265       [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
7266     bits<5> imm;
7267     let Inst{20-16} = imm;
7268   }
7269
7270   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7271                                   V128, V128, vecshiftR32,
7272                                   asm, ".4s", ".4s",
7273       [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
7274     bits<5> imm;
7275     let Inst{20-16} = imm;
7276   }
7277
7278   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7279                                   V128, V128, vecshiftR64,
7280                                   asm, ".2d", ".2d",
7281       [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
7282     bits<6> imm;
7283     let Inst{21-16} = imm;
7284   }
7285 }
7286
7287 multiclass SIMDVectorRShiftSDToFP<bit U, bits<5> opc, string asm,
7288                                   Intrinsic OpNode> {
7289   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7290                                   V64, V64, vecshiftR32,
7291                                   asm, ".2s", ".2s",
7292       [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
7293     bits<5> imm;
7294     let Inst{20-16} = imm;
7295   }
7296
7297   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7298                                   V128, V128, vecshiftR32,
7299                                   asm, ".4s", ".4s",
7300       [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
7301     bits<5> imm;
7302     let Inst{20-16} = imm;
7303   }
7304
7305   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7306                                   V128, V128, vecshiftR64,
7307                                   asm, ".2d", ".2d",
7308       [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
7309     bits<6> imm;
7310     let Inst{21-16} = imm;
7311   }
7312 }
7313
7314 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
7315                                      SDPatternOperator OpNode> {
7316   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7317                                   V64, V128, vecshiftR16Narrow,
7318                                   asm, ".8b", ".8h",
7319       [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
7320     bits<3> imm;
7321     let Inst{18-16} = imm;
7322   }
7323
7324   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7325                                   V128, V128, vecshiftR16Narrow,
7326                                   asm#"2", ".16b", ".8h", []> {
7327     bits<3> imm;
7328     let Inst{18-16} = imm;
7329     let hasSideEffects = 0;
7330   }
7331
7332   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7333                                   V64, V128, vecshiftR32Narrow,
7334                                   asm, ".4h", ".4s",
7335       [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
7336     bits<4> imm;
7337     let Inst{19-16} = imm;
7338   }
7339
7340   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7341                                   V128, V128, vecshiftR32Narrow,
7342                                   asm#"2", ".8h", ".4s", []> {
7343     bits<4> imm;
7344     let Inst{19-16} = imm;
7345     let hasSideEffects = 0;
7346   }
7347
7348   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7349                                   V64, V128, vecshiftR64Narrow,
7350                                   asm, ".2s", ".2d",
7351       [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
7352     bits<5> imm;
7353     let Inst{20-16} = imm;
7354   }
7355
7356   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7357                                   V128, V128, vecshiftR64Narrow,
7358                                   asm#"2", ".4s", ".2d", []> {
7359     bits<5> imm;
7360     let Inst{20-16} = imm;
7361     let hasSideEffects = 0;
7362   }
7363
7364   // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
7365   // themselves, so put them here instead.
7366
7367   // Patterns involving what's effectively an insert high and a normal
7368   // intrinsic, represented by CONCAT_VECTORS.
7369   def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
7370                                                    vecshiftR16Narrow:$imm)),
7371             (!cast<Instruction>(NAME # "v16i8_shift")
7372                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7373                 V128:$Rn, vecshiftR16Narrow:$imm)>;
7374   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
7375                                                      vecshiftR32Narrow:$imm)),
7376             (!cast<Instruction>(NAME # "v8i16_shift")
7377                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7378                 V128:$Rn, vecshiftR32Narrow:$imm)>;
7379   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
7380                                                      vecshiftR64Narrow:$imm)),
7381             (!cast<Instruction>(NAME # "v4i32_shift")
7382                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7383                 V128:$Rn, vecshiftR64Narrow:$imm)>;
7384 }
7385
7386 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
7387                                 SDPatternOperator OpNode> {
7388   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7389                                   V64, V64, vecshiftL8,
7390                                   asm, ".8b", ".8b",
7391                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7392                        (i32 vecshiftL8:$imm)))]> {
7393     bits<3> imm;
7394     let Inst{18-16} = imm;
7395   }
7396
7397   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7398                                   V128, V128, vecshiftL8,
7399                                   asm, ".16b", ".16b",
7400              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7401                    (i32 vecshiftL8:$imm)))]> {
7402     bits<3> imm;
7403     let Inst{18-16} = imm;
7404   }
7405
7406   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7407                                   V64, V64, vecshiftL16,
7408                                   asm, ".4h", ".4h",
7409               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7410                     (i32 vecshiftL16:$imm)))]> {
7411     bits<4> imm;
7412     let Inst{19-16} = imm;
7413   }
7414
7415   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7416                                   V128, V128, vecshiftL16,
7417                                   asm, ".8h", ".8h",
7418             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7419                   (i32 vecshiftL16:$imm)))]> {
7420     bits<4> imm;
7421     let Inst{19-16} = imm;
7422   }
7423
7424   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7425                                   V64, V64, vecshiftL32,
7426                                   asm, ".2s", ".2s",
7427               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7428                     (i32 vecshiftL32:$imm)))]> {
7429     bits<5> imm;
7430     let Inst{20-16} = imm;
7431   }
7432
7433   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7434                                   V128, V128, vecshiftL32,
7435                                   asm, ".4s", ".4s",
7436             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7437                   (i32 vecshiftL32:$imm)))]> {
7438     bits<5> imm;
7439     let Inst{20-16} = imm;
7440   }
7441
7442   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7443                                   V128, V128, vecshiftL64,
7444                                   asm, ".2d", ".2d",
7445             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7446                   (i32 vecshiftL64:$imm)))]> {
7447     bits<6> imm;
7448     let Inst{21-16} = imm;
7449   }
7450 }
7451
7452 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
7453                                 SDPatternOperator OpNode> {
7454   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7455                                   V64, V64, vecshiftR8,
7456                                   asm, ".8b", ".8b",
7457                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7458                        (i32 vecshiftR8:$imm)))]> {
7459     bits<3> imm;
7460     let Inst{18-16} = imm;
7461   }
7462
7463   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7464                                   V128, V128, vecshiftR8,
7465                                   asm, ".16b", ".16b",
7466              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7467                    (i32 vecshiftR8:$imm)))]> {
7468     bits<3> imm;
7469     let Inst{18-16} = imm;
7470   }
7471
7472   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7473                                   V64, V64, vecshiftR16,
7474                                   asm, ".4h", ".4h",
7475               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7476                     (i32 vecshiftR16:$imm)))]> {
7477     bits<4> imm;
7478     let Inst{19-16} = imm;
7479   }
7480
7481   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7482                                   V128, V128, vecshiftR16,
7483                                   asm, ".8h", ".8h",
7484             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7485                   (i32 vecshiftR16:$imm)))]> {
7486     bits<4> imm;
7487     let Inst{19-16} = imm;
7488   }
7489
7490   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7491                                   V64, V64, vecshiftR32,
7492                                   asm, ".2s", ".2s",
7493               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7494                     (i32 vecshiftR32:$imm)))]> {
7495     bits<5> imm;
7496     let Inst{20-16} = imm;
7497   }
7498
7499   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7500                                   V128, V128, vecshiftR32,
7501                                   asm, ".4s", ".4s",
7502             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7503                   (i32 vecshiftR32:$imm)))]> {
7504     bits<5> imm;
7505     let Inst{20-16} = imm;
7506   }
7507
7508   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7509                                   V128, V128, vecshiftR64,
7510                                   asm, ".2d", ".2d",
7511             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7512                   (i32 vecshiftR64:$imm)))]> {
7513     bits<6> imm;
7514     let Inst{21-16} = imm;
7515   }
7516 }
7517
7518 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7519 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
7520                                     SDPatternOperator OpNode = null_frag> {
7521   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7522                                   V64, V64, vecshiftR8, asm, ".8b", ".8b",
7523                  [(set (v8i8 V64:$dst),
7524                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7525                            (i32 vecshiftR8:$imm)))]> {
7526     bits<3> imm;
7527     let Inst{18-16} = imm;
7528   }
7529
7530   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7531                                   V128, V128, vecshiftR8, asm, ".16b", ".16b",
7532              [(set (v16i8 V128:$dst),
7533                (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7534                        (i32 vecshiftR8:$imm)))]> {
7535     bits<3> imm;
7536     let Inst{18-16} = imm;
7537   }
7538
7539   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7540                                   V64, V64, vecshiftR16, asm, ".4h", ".4h",
7541               [(set (v4i16 V64:$dst),
7542                 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7543                         (i32 vecshiftR16:$imm)))]> {
7544     bits<4> imm;
7545     let Inst{19-16} = imm;
7546   }
7547
7548   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7549                                   V128, V128, vecshiftR16, asm, ".8h", ".8h",
7550             [(set (v8i16 V128:$dst),
7551               (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7552                       (i32 vecshiftR16:$imm)))]> {
7553     bits<4> imm;
7554     let Inst{19-16} = imm;
7555   }
7556
7557   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7558                                   V64, V64, vecshiftR32, asm, ".2s", ".2s",
7559               [(set (v2i32 V64:$dst),
7560                 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7561                         (i32 vecshiftR32:$imm)))]> {
7562     bits<5> imm;
7563     let Inst{20-16} = imm;
7564   }
7565
7566   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7567                                   V128, V128, vecshiftR32, asm, ".4s", ".4s",
7568             [(set (v4i32 V128:$dst),
7569               (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7570                       (i32 vecshiftR32:$imm)))]> {
7571     bits<5> imm;
7572     let Inst{20-16} = imm;
7573   }
7574
7575   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7576                                   V128, V128, vecshiftR64,
7577                                   asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
7578               (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7579                       (i32 vecshiftR64:$imm)))]> {
7580     bits<6> imm;
7581     let Inst{21-16} = imm;
7582   }
7583 }
7584
7585 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
7586                                     SDPatternOperator OpNode = null_frag> {
7587   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7588                                   V64, V64, vecshiftL8,
7589                                   asm, ".8b", ".8b",
7590                     [(set (v8i8 V64:$dst),
7591                           (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7592                                   (i32 vecshiftL8:$imm)))]> {
7593     bits<3> imm;
7594     let Inst{18-16} = imm;
7595   }
7596
7597   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7598                                   V128, V128, vecshiftL8,
7599                                   asm, ".16b", ".16b",
7600                     [(set (v16i8 V128:$dst),
7601                           (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7602                                   (i32 vecshiftL8:$imm)))]> {
7603     bits<3> imm;
7604     let Inst{18-16} = imm;
7605   }
7606
7607   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7608                                   V64, V64, vecshiftL16,
7609                                   asm, ".4h", ".4h",
7610                     [(set (v4i16 V64:$dst),
7611                            (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7612                                    (i32 vecshiftL16:$imm)))]> {
7613     bits<4> imm;
7614     let Inst{19-16} = imm;
7615   }
7616
7617   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7618                                   V128, V128, vecshiftL16,
7619                                   asm, ".8h", ".8h",
7620                     [(set (v8i16 V128:$dst),
7621                           (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7622                                   (i32 vecshiftL16:$imm)))]> {
7623     bits<4> imm;
7624     let Inst{19-16} = imm;
7625   }
7626
7627   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7628                                   V64, V64, vecshiftL32,
7629                                   asm, ".2s", ".2s",
7630                     [(set (v2i32 V64:$dst),
7631                           (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7632                                   (i32 vecshiftL32:$imm)))]> {
7633     bits<5> imm;
7634     let Inst{20-16} = imm;
7635   }
7636
7637   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7638                                   V128, V128, vecshiftL32,
7639                                   asm, ".4s", ".4s",
7640                     [(set (v4i32 V128:$dst),
7641                           (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7642                                   (i32 vecshiftL32:$imm)))]> {
7643     bits<5> imm;
7644     let Inst{20-16} = imm;
7645   }
7646
7647   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7648                                   V128, V128, vecshiftL64,
7649                                   asm, ".2d", ".2d",
7650                     [(set (v2i64 V128:$dst),
7651                           (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7652                                   (i32 vecshiftL64:$imm)))]> {
7653     bits<6> imm;
7654     let Inst{21-16} = imm;
7655   }
7656 }
7657
7658 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
7659                                    SDPatternOperator OpNode> {
7660   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7661                                   V128, V64, vecshiftL8, asm, ".8h", ".8b",
7662       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
7663     bits<3> imm;
7664     let Inst{18-16} = imm;
7665   }
7666
7667   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7668                                   V128, V128, vecshiftL8,
7669                                   asm#"2", ".8h", ".16b",
7670       [(set (v8i16 V128:$Rd),
7671             (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
7672     bits<3> imm;
7673     let Inst{18-16} = imm;
7674   }
7675
7676   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7677                                   V128, V64, vecshiftL16, asm, ".4s", ".4h",
7678       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
7679     bits<4> imm;
7680     let Inst{19-16} = imm;
7681   }
7682
7683   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7684                                   V128, V128, vecshiftL16,
7685                                   asm#"2", ".4s", ".8h",
7686       [(set (v4i32 V128:$Rd),
7687             (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
7688
7689     bits<4> imm;
7690     let Inst{19-16} = imm;
7691   }
7692
7693   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7694                                   V128, V64, vecshiftL32, asm, ".2d", ".2s",
7695       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
7696     bits<5> imm;
7697     let Inst{20-16} = imm;
7698   }
7699
7700   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7701                                   V128, V128, vecshiftL32,
7702                                   asm#"2", ".2d", ".4s",
7703       [(set (v2i64 V128:$Rd),
7704             (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
7705     bits<5> imm;
7706     let Inst{20-16} = imm;
7707   }
7708 }
7709
7710
7711 //---
7712 // Vector load/store
7713 //---
7714 // SIMD ldX/stX no-index memory references don't allow the optional
7715 // ", #0" constant and handle post-indexing explicitly, so we use
7716 // a more specialized parse method for them. Otherwise, it's the same as
7717 // the general GPR64sp handling.
7718
7719 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
7720                    string asm, dag oops, dag iops, list<dag> pattern>
7721   : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
7722   bits<5> Vt;
7723   bits<5> Rn;
7724   let Inst{31} = 0;
7725   let Inst{30} = Q;
7726   let Inst{29-23} = 0b0011000;
7727   let Inst{22} = L;
7728   let Inst{21-16} = 0b000000;
7729   let Inst{15-12} = opcode;
7730   let Inst{11-10} = size;
7731   let Inst{9-5} = Rn;
7732   let Inst{4-0} = Vt;
7733 }
7734
7735 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
7736                        string asm, dag oops, dag iops>
7737   : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
7738   bits<5> Vt;
7739   bits<5> Rn;
7740   bits<5> Xm;
7741   let Inst{31} = 0;
7742   let Inst{30} = Q;
7743   let Inst{29-23} = 0b0011001;
7744   let Inst{22} = L;
7745   let Inst{21} = 0;
7746   let Inst{20-16} = Xm;
7747   let Inst{15-12} = opcode;
7748   let Inst{11-10} = size;
7749   let Inst{9-5} = Rn;
7750   let Inst{4-0} = Vt;
7751 }
7752
7753 // The immediate form of AdvSIMD post-indexed addressing is encoded with
7754 // register post-index addressing from the zero register.
7755 multiclass SIMDLdStAliases<string asm, string layout, string Count,
7756                            int Offset, int Size> {
7757   // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
7758   //      "ld1\t$Vt, [$Rn], #16"
7759   // may get mapped to
7760   //      (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
7761   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
7762                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7763                       GPR64sp:$Rn,
7764                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
7765                       XZR), 1>;
7766
7767   // E.g. "ld1.8b { v0, v1 }, [x1], #16"
7768   //      "ld1.8b\t$Vt, [$Rn], #16"
7769   // may get mapped to
7770   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
7771   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
7772                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7773                       GPR64sp:$Rn,
7774                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7775                       XZR), 0>;
7776
7777   // E.g. "ld1.8b { v0, v1 }, [x1]"
7778   //      "ld1\t$Vt, [$Rn]"
7779   // may get mapped to
7780   //      (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
7781   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
7782                   (!cast<Instruction>(NAME # Count # "v" # layout)
7783                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7784                       GPR64sp:$Rn), 0>;
7785
7786   // E.g. "ld1.8b { v0, v1 }, [x1], x2"
7787   //      "ld1\t$Vt, [$Rn], $Xm"
7788   // may get mapped to
7789   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
7790   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
7791                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7792                       GPR64sp:$Rn,
7793                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7794                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
7795 }
7796
7797 multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
7798                        int Offset64, bits<4> opcode> {
7799   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
7800     def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
7801                            (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
7802                            (ins GPR64sp:$Rn), []>;
7803     def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
7804                            (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
7805                            (ins GPR64sp:$Rn), []>;
7806     def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
7807                            (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
7808                            (ins GPR64sp:$Rn), []>;
7809     def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
7810                            (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
7811                            (ins GPR64sp:$Rn), []>;
7812     def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
7813                            (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
7814                            (ins GPR64sp:$Rn), []>;
7815     def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
7816                            (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
7817                            (ins GPR64sp:$Rn), []>;
7818     def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
7819                            (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
7820                            (ins GPR64sp:$Rn), []>;
7821
7822
7823     def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
7824                        (outs GPR64sp:$wback,
7825                              !cast<RegisterOperand>(veclist # "16b"):$Vt),
7826                        (ins GPR64sp:$Rn,
7827                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7828     def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
7829                        (outs GPR64sp:$wback,
7830                              !cast<RegisterOperand>(veclist # "8h"):$Vt),
7831                        (ins GPR64sp:$Rn,
7832                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7833     def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
7834                        (outs GPR64sp:$wback,
7835                              !cast<RegisterOperand>(veclist # "4s"):$Vt),
7836                        (ins GPR64sp:$Rn,
7837                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7838     def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
7839                        (outs GPR64sp:$wback,
7840                              !cast<RegisterOperand>(veclist # "2d"):$Vt),
7841                        (ins GPR64sp:$Rn,
7842                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7843     def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
7844                        (outs GPR64sp:$wback,
7845                              !cast<RegisterOperand>(veclist # "8b"):$Vt),
7846                        (ins GPR64sp:$Rn,
7847                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7848     def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
7849                        (outs GPR64sp:$wback,
7850                              !cast<RegisterOperand>(veclist # "4h"):$Vt),
7851                        (ins GPR64sp:$Rn,
7852                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7853     def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
7854                        (outs GPR64sp:$wback,
7855                              !cast<RegisterOperand>(veclist # "2s"):$Vt),
7856                        (ins GPR64sp:$Rn,
7857                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7858   }
7859
7860   defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
7861   defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
7862   defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
7863   defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
7864   defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
7865   defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
7866   defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
7867 }
7868
7869 // Only ld1/st1 has a v1d version.
7870 multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
7871                        int Offset64, bits<4> opcode> {
7872   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
7873     def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
7874                             (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
7875                                  GPR64sp:$Rn), []>;
7876     def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
7877                            (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
7878                                 GPR64sp:$Rn), []>;
7879     def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
7880                            (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
7881                                 GPR64sp:$Rn), []>;
7882     def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
7883                            (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
7884                                 GPR64sp:$Rn), []>;
7885     def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
7886                            (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
7887                                 GPR64sp:$Rn), []>;
7888     def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
7889                            (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
7890                                 GPR64sp:$Rn), []>;
7891     def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
7892                            (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
7893                                 GPR64sp:$Rn), []>;
7894
7895     def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
7896                        (outs GPR64sp:$wback),
7897                        (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
7898                             GPR64sp:$Rn,
7899                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7900     def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
7901                        (outs GPR64sp:$wback),
7902                        (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
7903                             GPR64sp:$Rn,
7904                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7905     def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
7906                        (outs GPR64sp:$wback),
7907                        (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
7908                             GPR64sp:$Rn,
7909                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7910     def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
7911                        (outs GPR64sp:$wback),
7912                        (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
7913                             GPR64sp:$Rn,
7914                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7915     def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
7916                        (outs GPR64sp:$wback),
7917                        (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
7918                             GPR64sp:$Rn,
7919                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7920     def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
7921                        (outs GPR64sp:$wback),
7922                        (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
7923                             GPR64sp:$Rn,
7924                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7925     def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
7926                        (outs GPR64sp:$wback),
7927                        (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
7928                             GPR64sp:$Rn,
7929                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7930   }
7931
7932   defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
7933   defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
7934   defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
7935   defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
7936   defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
7937   defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
7938   defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
7939 }
7940
7941 multiclass BaseSIMDLd1<string Count, string asm, string veclist,
7942                        int Offset128, int Offset64, bits<4> opcode>
7943   : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
7944
7945   // LD1 instructions have extra "1d" variants.
7946   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
7947     def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
7948                            (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
7949                            (ins GPR64sp:$Rn), []>;
7950
7951     def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
7952                        (outs GPR64sp:$wback,
7953                              !cast<RegisterOperand>(veclist # "1d"):$Vt),
7954                        (ins GPR64sp:$Rn,
7955                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7956   }
7957
7958   defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
7959 }
7960
7961 multiclass BaseSIMDSt1<string Count, string asm, string veclist,
7962                        int Offset128, int Offset64, bits<4> opcode>
7963   : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
7964
7965   // ST1 instructions have extra "1d" variants.
7966   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
7967     def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
7968                            (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
7969                                 GPR64sp:$Rn), []>;
7970
7971     def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
7972                        (outs GPR64sp:$wback),
7973                        (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
7974                             GPR64sp:$Rn,
7975                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7976   }
7977
7978   defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
7979 }
7980
7981 multiclass SIMDLd1Multiple<string asm> {
7982   defm One   : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8,  0b0111>;
7983   defm Two   : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
7984   defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
7985   defm Four  : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
7986 }
7987
7988 multiclass SIMDSt1Multiple<string asm> {
7989   defm One   : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8,  0b0111>;
7990   defm Two   : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
7991   defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
7992   defm Four  : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
7993 }
7994
7995 multiclass SIMDLd2Multiple<string asm> {
7996   defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
7997 }
7998
7999 multiclass SIMDSt2Multiple<string asm> {
8000   defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8001 }
8002
8003 multiclass SIMDLd3Multiple<string asm> {
8004   defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8005 }
8006
8007 multiclass SIMDSt3Multiple<string asm> {
8008   defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8009 }
8010
8011 multiclass SIMDLd4Multiple<string asm> {
8012   defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8013 }
8014
8015 multiclass SIMDSt4Multiple<string asm> {
8016   defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8017 }
8018
8019 //---
8020 // AdvSIMD Load/store single-element
8021 //---
8022
8023 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
8024                          string asm, string operands, string cst,
8025                          dag oops, dag iops, list<dag> pattern>
8026   : I<oops, iops, asm, operands, cst, pattern> {
8027   bits<5> Vt;
8028   bits<5> Rn;
8029   let Inst{31} = 0;
8030   let Inst{29-24} = 0b001101;
8031   let Inst{22} = L;
8032   let Inst{21} = R;
8033   let Inst{15-13} = opcode;
8034   let Inst{9-5} = Rn;
8035   let Inst{4-0} = Vt;
8036 }
8037
8038 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
8039                          string asm, string operands, string cst,
8040                          dag oops, dag iops, list<dag> pattern>
8041   : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
8042   bits<5> Vt;
8043   bits<5> Rn;
8044   let Inst{31} = 0;
8045   let Inst{29-24} = 0b001101;
8046   let Inst{22} = L;
8047   let Inst{21} = R;
8048   let Inst{15-13} = opcode;
8049   let Inst{9-5} = Rn;
8050   let Inst{4-0} = Vt;
8051 }
8052
8053
8054 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8055 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
8056                   Operand listtype>
8057   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
8058                        (outs listtype:$Vt), (ins GPR64sp:$Rn),
8059                        []> {
8060   let Inst{30} = Q;
8061   let Inst{23} = 0;
8062   let Inst{20-16} = 0b00000;
8063   let Inst{12} = S;
8064   let Inst{11-10} = size;
8065 }
8066 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8067 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
8068                       string asm, Operand listtype, Operand GPR64pi>
8069   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
8070                        "$Rn = $wback",
8071                        (outs GPR64sp:$wback, listtype:$Vt),
8072                        (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
8073   bits<5> Xm;
8074   let Inst{30} = Q;
8075   let Inst{23} = 1;
8076   let Inst{20-16} = Xm;
8077   let Inst{12} = S;
8078   let Inst{11-10} = size;
8079 }
8080
8081 multiclass SIMDLdrAliases<string asm, string layout, string Count,
8082                           int Offset, int Size> {
8083   // E.g. "ld1r { v0.8b }, [x1], #1"
8084   //      "ld1r.8b\t$Vt, [$Rn], #1"
8085   // may get mapped to
8086   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8087   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8088                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
8089                       GPR64sp:$Rn,
8090                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8091                       XZR), 1>;
8092
8093   // E.g. "ld1r.8b { v0 }, [x1], #1"
8094   //      "ld1r.8b\t$Vt, [$Rn], #1"
8095   // may get mapped to
8096   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8097   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8098                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
8099                       GPR64sp:$Rn,
8100                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8101                       XZR), 0>;
8102
8103   // E.g. "ld1r.8b { v0 }, [x1]"
8104   //      "ld1r.8b\t$Vt, [$Rn]"
8105   // may get mapped to
8106   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8107   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8108                   (!cast<Instruction>(NAME # "v" # layout)
8109                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8110                       GPR64sp:$Rn), 0>;
8111
8112   // E.g. "ld1r.8b { v0 }, [x1], x2"
8113   //      "ld1r.8b\t$Vt, [$Rn], $Xm"
8114   // may get mapped to
8115   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8116   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8117                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
8118                       GPR64sp:$Rn,
8119                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8120                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8121 }
8122
8123 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
8124   int Offset1, int Offset2, int Offset4, int Offset8> {
8125   def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
8126                         !cast<Operand>("VecList" # Count # "8b")>;
8127   def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
8128                         !cast<Operand>("VecList" # Count #"16b")>;
8129   def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
8130                         !cast<Operand>("VecList" # Count #"4h")>;
8131   def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
8132                         !cast<Operand>("VecList" # Count #"8h")>;
8133   def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
8134                         !cast<Operand>("VecList" # Count #"2s")>;
8135   def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
8136                         !cast<Operand>("VecList" # Count #"4s")>;
8137   def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
8138                         !cast<Operand>("VecList" # Count #"1d")>;
8139   def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
8140                         !cast<Operand>("VecList" # Count #"2d")>;
8141
8142   def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
8143                                  !cast<Operand>("VecList" # Count # "8b"),
8144                                  !cast<Operand>("GPR64pi" # Offset1)>;
8145   def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
8146                                  !cast<Operand>("VecList" # Count # "16b"),
8147                                  !cast<Operand>("GPR64pi" # Offset1)>;
8148   def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
8149                                  !cast<Operand>("VecList" # Count # "4h"),
8150                                  !cast<Operand>("GPR64pi" # Offset2)>;
8151   def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
8152                                  !cast<Operand>("VecList" # Count # "8h"),
8153                                  !cast<Operand>("GPR64pi" # Offset2)>;
8154   def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
8155                                  !cast<Operand>("VecList" # Count # "2s"),
8156                                  !cast<Operand>("GPR64pi" # Offset4)>;
8157   def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
8158                                  !cast<Operand>("VecList" # Count # "4s"),
8159                                  !cast<Operand>("GPR64pi" # Offset4)>;
8160   def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
8161                                  !cast<Operand>("VecList" # Count # "1d"),
8162                                  !cast<Operand>("GPR64pi" # Offset8)>;
8163   def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
8164                                  !cast<Operand>("VecList" # Count # "2d"),
8165                                  !cast<Operand>("GPR64pi" # Offset8)>;
8166
8167   defm : SIMDLdrAliases<asm, "8b",  Count, Offset1,  64>;
8168   defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
8169   defm : SIMDLdrAliases<asm, "4h",  Count, Offset2,  64>;
8170   defm : SIMDLdrAliases<asm, "8h",  Count, Offset2, 128>;
8171   defm : SIMDLdrAliases<asm, "2s",  Count, Offset4,  64>;
8172   defm : SIMDLdrAliases<asm, "4s",  Count, Offset4, 128>;
8173   defm : SIMDLdrAliases<asm, "1d",  Count, Offset8,  64>;
8174   defm : SIMDLdrAliases<asm, "2d",  Count, Offset8, 128>;
8175 }
8176
8177 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
8178                       dag oops, dag iops, list<dag> pattern>
8179   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8180                        pattern> {
8181   // idx encoded in Q:S:size fields.
8182   bits<4> idx;
8183   let Inst{30} = idx{3};
8184   let Inst{23} = 0;
8185   let Inst{20-16} = 0b00000;
8186   let Inst{12} = idx{2};
8187   let Inst{11-10} = idx{1-0};
8188 }
8189 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
8190                       dag oops, dag iops, list<dag> pattern>
8191   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8192                            oops, iops, pattern> {
8193   // idx encoded in Q:S:size fields.
8194   bits<4> idx;
8195   let Inst{30} = idx{3};
8196   let Inst{23} = 0;
8197   let Inst{20-16} = 0b00000;
8198   let Inst{12} = idx{2};
8199   let Inst{11-10} = idx{1-0};
8200 }
8201 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
8202                           dag oops, dag iops>
8203   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8204                        "$Rn = $wback", oops, iops, []> {
8205   // idx encoded in Q:S:size fields.
8206   bits<4> idx;
8207   bits<5> Xm;
8208   let Inst{30} = idx{3};
8209   let Inst{23} = 1;
8210   let Inst{20-16} = Xm;
8211   let Inst{12} = idx{2};
8212   let Inst{11-10} = idx{1-0};
8213 }
8214 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
8215                           dag oops, dag iops>
8216   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8217                            "$Rn = $wback", oops, iops, []> {
8218   // idx encoded in Q:S:size fields.
8219   bits<4> idx;
8220   bits<5> Xm;
8221   let Inst{30} = idx{3};
8222   let Inst{23} = 1;
8223   let Inst{20-16} = Xm;
8224   let Inst{12} = idx{2};
8225   let Inst{11-10} = idx{1-0};
8226 }
8227
8228 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
8229                       dag oops, dag iops, list<dag> pattern>
8230   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8231                        pattern> {
8232   // idx encoded in Q:S:size<1> fields.
8233   bits<3> idx;
8234   let Inst{30} = idx{2};
8235   let Inst{23} = 0;
8236   let Inst{20-16} = 0b00000;
8237   let Inst{12} = idx{1};
8238   let Inst{11} = idx{0};
8239   let Inst{10} = size;
8240 }
8241 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
8242                       dag oops, dag iops, list<dag> pattern>
8243   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8244                            oops, iops, pattern> {
8245   // idx encoded in Q:S:size<1> fields.
8246   bits<3> idx;
8247   let Inst{30} = idx{2};
8248   let Inst{23} = 0;
8249   let Inst{20-16} = 0b00000;
8250   let Inst{12} = idx{1};
8251   let Inst{11} = idx{0};
8252   let Inst{10} = size;
8253 }
8254
8255 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8256                           dag oops, dag iops>
8257   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8258                        "$Rn = $wback", oops, iops, []> {
8259   // idx encoded in Q:S:size<1> fields.
8260   bits<3> idx;
8261   bits<5> Xm;
8262   let Inst{30} = idx{2};
8263   let Inst{23} = 1;
8264   let Inst{20-16} = Xm;
8265   let Inst{12} = idx{1};
8266   let Inst{11} = idx{0};
8267   let Inst{10} = size;
8268 }
8269 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8270                           dag oops, dag iops>
8271   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8272                            "$Rn = $wback", oops, iops, []> {
8273   // idx encoded in Q:S:size<1> fields.
8274   bits<3> idx;
8275   bits<5> Xm;
8276   let Inst{30} = idx{2};
8277   let Inst{23} = 1;
8278   let Inst{20-16} = Xm;
8279   let Inst{12} = idx{1};
8280   let Inst{11} = idx{0};
8281   let Inst{10} = size;
8282 }
8283 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8284                       dag oops, dag iops, list<dag> pattern>
8285   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8286                        pattern> {
8287   // idx encoded in Q:S fields.
8288   bits<2> idx;
8289   let Inst{30} = idx{1};
8290   let Inst{23} = 0;
8291   let Inst{20-16} = 0b00000;
8292   let Inst{12} = idx{0};
8293   let Inst{11-10} = size;
8294 }
8295 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8296                       dag oops, dag iops, list<dag> pattern>
8297   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8298                            oops, iops, pattern> {
8299   // idx encoded in Q:S fields.
8300   bits<2> idx;
8301   let Inst{30} = idx{1};
8302   let Inst{23} = 0;
8303   let Inst{20-16} = 0b00000;
8304   let Inst{12} = idx{0};
8305   let Inst{11-10} = size;
8306 }
8307 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
8308                           string asm, dag oops, dag iops>
8309   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8310                        "$Rn = $wback", oops, iops, []> {
8311   // idx encoded in Q:S fields.
8312   bits<2> idx;
8313   bits<5> Xm;
8314   let Inst{30} = idx{1};
8315   let Inst{23} = 1;
8316   let Inst{20-16} = Xm;
8317   let Inst{12} = idx{0};
8318   let Inst{11-10} = size;
8319 }
8320 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8321                           string asm, dag oops, dag iops>
8322   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8323                            "$Rn = $wback", oops, iops, []> {
8324   // idx encoded in Q:S fields.
8325   bits<2> idx;
8326   bits<5> Xm;
8327   let Inst{30} = idx{1};
8328   let Inst{23} = 1;
8329   let Inst{20-16} = Xm;
8330   let Inst{12} = idx{0};
8331   let Inst{11-10} = size;
8332 }
8333 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8334                       dag oops, dag iops, list<dag> pattern>
8335   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8336                        pattern> {
8337   // idx encoded in Q field.
8338   bits<1> idx;
8339   let Inst{30} = idx;
8340   let Inst{23} = 0;
8341   let Inst{20-16} = 0b00000;
8342   let Inst{12} = 0;
8343   let Inst{11-10} = size;
8344 }
8345 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8346                       dag oops, dag iops, list<dag> pattern>
8347   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8348                            oops, iops, pattern> {
8349   // idx encoded in Q field.
8350   bits<1> idx;
8351   let Inst{30} = idx;
8352   let Inst{23} = 0;
8353   let Inst{20-16} = 0b00000;
8354   let Inst{12} = 0;
8355   let Inst{11-10} = size;
8356 }
8357 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
8358                           string asm, dag oops, dag iops>
8359   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8360                        "$Rn = $wback", oops, iops, []> {
8361   // idx encoded in Q field.
8362   bits<1> idx;
8363   bits<5> Xm;
8364   let Inst{30} = idx;
8365   let Inst{23} = 1;
8366   let Inst{20-16} = Xm;
8367   let Inst{12} = 0;
8368   let Inst{11-10} = size;
8369 }
8370 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8371                           string asm, dag oops, dag iops>
8372   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8373                            "$Rn = $wback", oops, iops, []> {
8374   // idx encoded in Q field.
8375   bits<1> idx;
8376   bits<5> Xm;
8377   let Inst{30} = idx;
8378   let Inst{23} = 1;
8379   let Inst{20-16} = Xm;
8380   let Inst{12} = 0;
8381   let Inst{11-10} = size;
8382 }
8383
8384 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8385 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
8386                          RegisterOperand listtype,
8387                          RegisterOperand GPR64pi> {
8388   def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
8389                            (outs listtype:$dst),
8390                            (ins listtype:$Vt, VectorIndexB:$idx,
8391                                 GPR64sp:$Rn), []>;
8392
8393   def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
8394                             (outs GPR64sp:$wback, listtype:$dst),
8395                             (ins listtype:$Vt, VectorIndexB:$idx,
8396                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8397 }
8398 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8399 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
8400                          RegisterOperand listtype,
8401                          RegisterOperand GPR64pi> {
8402   def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
8403                             (outs listtype:$dst),
8404                             (ins listtype:$Vt, VectorIndexH:$idx,
8405                                  GPR64sp:$Rn), []>;
8406
8407   def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
8408                             (outs GPR64sp:$wback, listtype:$dst),
8409                             (ins listtype:$Vt, VectorIndexH:$idx,
8410                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8411 }
8412 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8413 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
8414                          RegisterOperand listtype,
8415                          RegisterOperand GPR64pi> {
8416   def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
8417                             (outs listtype:$dst),
8418                             (ins listtype:$Vt, VectorIndexS:$idx,
8419                                  GPR64sp:$Rn), []>;
8420
8421   def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
8422                             (outs GPR64sp:$wback, listtype:$dst),
8423                             (ins listtype:$Vt, VectorIndexS:$idx,
8424                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8425 }
8426 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8427 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
8428                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8429   def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
8430                             (outs listtype:$dst),
8431                             (ins listtype:$Vt, VectorIndexD:$idx,
8432                                  GPR64sp:$Rn), []>;
8433
8434   def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
8435                             (outs GPR64sp:$wback, listtype:$dst),
8436                             (ins listtype:$Vt, VectorIndexD:$idx,
8437                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8438 }
8439 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8440 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
8441                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8442   def i8 : SIMDLdStSingleB<0, R, opcode, asm,
8443                            (outs), (ins listtype:$Vt, VectorIndexB:$idx,
8444                                         GPR64sp:$Rn), []>;
8445
8446   def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
8447                                     (outs GPR64sp:$wback),
8448                                     (ins listtype:$Vt, VectorIndexB:$idx,
8449                                          GPR64sp:$Rn, GPR64pi:$Xm)>;
8450 }
8451 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8452 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
8453                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8454   def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
8455                             (outs), (ins listtype:$Vt, VectorIndexH:$idx,
8456                                          GPR64sp:$Rn), []>;
8457
8458   def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
8459                             (outs GPR64sp:$wback),
8460                             (ins listtype:$Vt, VectorIndexH:$idx,
8461                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8462 }
8463 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8464 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
8465                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8466   def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
8467                             (outs), (ins listtype:$Vt, VectorIndexS:$idx,
8468                                          GPR64sp:$Rn), []>;
8469
8470   def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
8471                             (outs GPR64sp:$wback),
8472                             (ins listtype:$Vt, VectorIndexS:$idx,
8473                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8474 }
8475 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8476 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
8477                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8478   def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
8479                             (outs), (ins listtype:$Vt, VectorIndexD:$idx,
8480                                          GPR64sp:$Rn), []>;
8481
8482   def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
8483                             (outs GPR64sp:$wback),
8484                             (ins listtype:$Vt, VectorIndexD:$idx,
8485                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8486 }
8487
8488 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
8489                                  string Count, int Offset, Operand idxtype> {
8490   // E.g. "ld1 { v0.8b }[0], [x1], #1"
8491   //      "ld1\t$Vt, [$Rn], #1"
8492   // may get mapped to
8493   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8494   def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
8495                   (!cast<Instruction>(NAME # Type  # "_POST")
8496                       GPR64sp:$Rn,
8497                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8498                       idxtype:$idx, XZR), 1>;
8499
8500   // E.g. "ld1.8b { v0 }[0], [x1], #1"
8501   //      "ld1.8b\t$Vt, [$Rn], #1"
8502   // may get mapped to
8503   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8504   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
8505                   (!cast<Instruction>(NAME # Type # "_POST")
8506                       GPR64sp:$Rn,
8507                       !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8508                       idxtype:$idx, XZR), 0>;
8509
8510   // E.g. "ld1.8b { v0 }[0], [x1]"
8511   //      "ld1.8b\t$Vt, [$Rn]"
8512   // may get mapped to
8513   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8514   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
8515                       (!cast<Instruction>(NAME # Type)
8516                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8517                          idxtype:$idx, GPR64sp:$Rn), 0>;
8518
8519   // E.g. "ld1.8b { v0 }[0], [x1], x2"
8520   //      "ld1.8b\t$Vt, [$Rn], $Xm"
8521   // may get mapped to
8522   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8523   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
8524                       (!cast<Instruction>(NAME # Type # "_POST")
8525                          GPR64sp:$Rn,
8526                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8527                          idxtype:$idx,
8528                          !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8529 }
8530
8531 multiclass SIMDLdSt1SingleAliases<string asm> {
8532   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "One", 1, VectorIndexB>;
8533   defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
8534   defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
8535   defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
8536 }
8537
8538 multiclass SIMDLdSt2SingleAliases<string asm> {
8539   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Two", 2,  VectorIndexB>;
8540   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4,  VectorIndexH>;
8541   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8,  VectorIndexS>;
8542   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
8543 }
8544
8545 multiclass SIMDLdSt3SingleAliases<string asm> {
8546   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Three", 3,  VectorIndexB>;
8547   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6,  VectorIndexH>;
8548   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
8549   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
8550 }
8551
8552 multiclass SIMDLdSt4SingleAliases<string asm> {
8553   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Four", 4,  VectorIndexB>;
8554   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8,  VectorIndexH>;
8555   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
8556   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
8557 }
8558 } // end of 'let Predicates = [HasNEON]'
8559
8560 //----------------------------------------------------------------------------
8561 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
8562 //----------------------------------------------------------------------------
8563
8564 let Predicates = [HasNEON, HasV8_1a] in {
8565
8566 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
8567                                     RegisterOperand regtype, string asm, 
8568                                     string kind, list<dag> pattern>
8569   : BaseSIMDThreeSameVectorTied<Q, U, size, opcode, regtype, asm, kind, 
8570                                 pattern> {
8571   let Inst{21}=0;
8572 }
8573 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
8574                                              SDPatternOperator Accum> {
8575   def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
8576     [(set (v4i16 V64:$dst),
8577           (Accum (v4i16 V64:$Rd),
8578                  (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
8579                                                    (v4i16 V64:$Rm)))))]>;         
8580   def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
8581     [(set (v8i16 V128:$dst),
8582           (Accum (v8i16 V128:$Rd),
8583                  (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
8584                                                    (v8i16 V128:$Rm)))))]>;
8585   def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
8586     [(set (v2i32 V64:$dst),
8587           (Accum (v2i32 V64:$Rd),
8588                  (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
8589                                                    (v2i32 V64:$Rm)))))]>;
8590   def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
8591     [(set (v4i32 V128:$dst),
8592           (Accum (v4i32 V128:$Rd),
8593                  (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
8594                                                    (v4i32 V128:$Rm)))))]>;
8595 }
8596
8597 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
8598                                      SDPatternOperator Accum> {
8599   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
8600                                           V64, V64, V128_lo, VectorIndexH,
8601                                           asm, ".4h", ".4h", ".4h", ".h",
8602     [(set (v4i16 V64:$dst),
8603           (Accum (v4i16 V64:$Rd),
8604                  (v4i16 (int_aarch64_neon_sqrdmulh
8605                           (v4i16 V64:$Rn),
8606                           (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8607                                                     VectorIndexH:$idx))))))]> {
8608     bits<3> idx;
8609     let Inst{11} = idx{2};
8610     let Inst{21} = idx{1};
8611     let Inst{20} = idx{0};
8612   }
8613
8614   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8615                                           V128, V128, V128_lo, VectorIndexH,
8616                                           asm, ".8h", ".8h", ".8h", ".h",
8617     [(set (v8i16 V128:$dst),
8618           (Accum (v8i16 V128:$Rd),
8619                  (v8i16 (int_aarch64_neon_sqrdmulh
8620                           (v8i16 V128:$Rn),
8621                           (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8622                                                    VectorIndexH:$idx))))))]> {
8623     bits<3> idx;
8624     let Inst{11} = idx{2};
8625     let Inst{21} = idx{1};
8626     let Inst{20} = idx{0};
8627   }
8628
8629   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8630                                           V64, V64, V128, VectorIndexS,
8631                                           asm, ".2s", ".2s", ".2s", ".s",
8632     [(set (v2i32 V64:$dst),
8633         (Accum (v2i32 V64:$Rd),
8634                (v2i32 (int_aarch64_neon_sqrdmulh
8635                         (v2i32 V64:$Rn),
8636                         (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
8637                                                  VectorIndexS:$idx))))))]> {
8638     bits<2> idx;
8639     let Inst{11} = idx{1};
8640     let Inst{21} = idx{0};
8641   }
8642
8643   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 
8644   // an intermediate EXTRACT_SUBREG would be untyped.
8645   // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 
8646   // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
8647   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8648                        (i32 (vector_extract 
8649                                (v4i32 (insert_subvector
8650                                        (undef), 
8651                                         (v2i32 (int_aarch64_neon_sqrdmulh 
8652                                                  (v2i32 V64:$Rn),
8653                                                  (v2i32 (AArch64duplane32 
8654                                                           (v4i32 V128:$Rm),
8655                                                           VectorIndexS:$idx)))),
8656                                       (i32 0))),
8657                                (i64 0))))),
8658             (EXTRACT_SUBREG
8659                 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
8660                           (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 
8661                                                 FPR32Op:$Rd, 
8662                                                 ssub)), 
8663                           V64:$Rn,
8664                           V128:$Rm, 
8665                           VectorIndexS:$idx)),
8666                 ssub)>;
8667
8668   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8669                                           V128, V128, V128, VectorIndexS,
8670                                           asm, ".4s", ".4s", ".4s", ".s",
8671     [(set (v4i32 V128:$dst),
8672           (Accum (v4i32 V128:$Rd),
8673                  (v4i32 (int_aarch64_neon_sqrdmulh
8674                           (v4i32 V128:$Rn),
8675                           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8676                                                    VectorIndexS:$idx))))))]> {
8677     bits<2> idx;
8678     let Inst{11} = idx{1};
8679     let Inst{21} = idx{0};
8680   }
8681
8682   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
8683   // an intermediate EXTRACT_SUBREG would be untyped.
8684   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8685                         (i32 (vector_extract 
8686                                (v4i32 (int_aarch64_neon_sqrdmulh 
8687                                         (v4i32 V128:$Rn),
8688                                         (v4i32 (AArch64duplane32 
8689                                                  (v4i32 V128:$Rm),
8690                                                  VectorIndexS:$idx)))),
8691                                (i64 0))))),
8692             (EXTRACT_SUBREG
8693                 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
8694                          (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 
8695                                                FPR32Op:$Rd, 
8696                                                ssub)), 
8697                          V128:$Rn,
8698                          V128:$Rm, 
8699                          VectorIndexS:$idx)),
8700                 ssub)>;
8701
8702   def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
8703                                         FPR16Op, FPR16Op, V128_lo,
8704                                         VectorIndexH, asm, ".h", "", "", ".h", 
8705                                         []> {
8706     bits<3> idx;
8707     let Inst{11} = idx{2};
8708     let Inst{21} = idx{1};
8709     let Inst{20} = idx{0};
8710   }
8711
8712   def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
8713                                         FPR32Op, FPR32Op, V128, VectorIndexS,
8714                                         asm, ".s", "", "", ".s",
8715     [(set (i32 FPR32Op:$dst),
8716           (Accum (i32 FPR32Op:$Rd),
8717                  (i32 (int_aarch64_neon_sqrdmulh
8718                         (i32 FPR32Op:$Rn),
8719                         (i32 (vector_extract (v4i32 V128:$Rm),
8720                                              VectorIndexS:$idx))))))]> {
8721     bits<2> idx;
8722     let Inst{11} = idx{1};
8723     let Inst{21} = idx{0};
8724   }
8725 }
8726 } // let Predicates = [HasNeon, HasV8_1a]
8727
8728 //----------------------------------------------------------------------------
8729 // Crypto extensions
8730 //----------------------------------------------------------------------------
8731
8732 let Predicates = [HasCrypto] in {
8733 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8734 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
8735               list<dag> pat>
8736   : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
8737     Sched<[WriteV]>{
8738   bits<5> Rd;
8739   bits<5> Rn;
8740   let Inst{31-16} = 0b0100111000101000;
8741   let Inst{15-12} = opc;
8742   let Inst{11-10} = 0b10;
8743   let Inst{9-5}   = Rn;
8744   let Inst{4-0}   = Rd;
8745 }
8746
8747 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
8748   : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
8749             [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
8750
8751 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
8752   : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
8753             "$Rd = $dst",
8754             [(set (v16i8 V128:$dst),
8755                   (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
8756
8757 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8758 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
8759                      dag oops, dag iops, list<dag> pat>
8760   : I<oops, iops, asm,
8761       "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
8762       "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
8763     Sched<[WriteV]>{
8764   bits<5> Rd;
8765   bits<5> Rn;
8766   bits<5> Rm;
8767   let Inst{31-21} = 0b01011110000;
8768   let Inst{20-16} = Rm;
8769   let Inst{15}    = 0;
8770   let Inst{14-12} = opc;
8771   let Inst{11-10} = 0b00;
8772   let Inst{9-5}   = Rn;
8773   let Inst{4-0}   = Rd;
8774 }
8775
8776 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
8777   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8778                    (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
8779                    [(set (v4i32 FPR128:$dst),
8780                          (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
8781                                  (v4i32 V128:$Rm)))]>;
8782
8783 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
8784   : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
8785                    (ins V128:$Rd, V128:$Rn, V128:$Rm),
8786                    [(set (v4i32 V128:$dst),
8787                          (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8788                                  (v4i32 V128:$Rm)))]>;
8789
8790 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
8791   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8792                    (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
8793                    [(set (v4i32 FPR128:$dst),
8794                          (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
8795                                  (v4i32 V128:$Rm)))]>;
8796
8797 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8798 class SHA2OpInst<bits<4> opc, string asm, string kind,
8799                  string cstr, dag oops, dag iops,
8800                  list<dag> pat>
8801   : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
8802                        "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
8803     Sched<[WriteV]>{
8804   bits<5> Rd;
8805   bits<5> Rn;
8806   let Inst{31-16} = 0b0101111000101000;
8807   let Inst{15-12} = opc;
8808   let Inst{11-10} = 0b10;
8809   let Inst{9-5}   = Rn;
8810   let Inst{4-0}   = Rd;
8811 }
8812
8813 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
8814   : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
8815                (ins V128:$Rd, V128:$Rn),
8816                [(set (v4i32 V128:$dst),
8817                      (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
8818
8819 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
8820   : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
8821                [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
8822 } // end of 'let Predicates = [HasCrypto]'
8823
8824 // Allow the size specifier tokens to be upper case, not just lower.
8825 def : TokenAlias<".8B", ".8b">;
8826 def : TokenAlias<".4H", ".4h">;
8827 def : TokenAlias<".2S", ".2s">;
8828 def : TokenAlias<".1D", ".1d">;
8829 def : TokenAlias<".16B", ".16b">;
8830 def : TokenAlias<".8H", ".8h">;
8831 def : TokenAlias<".4S", ".4s">;
8832 def : TokenAlias<".2D", ".2d">;
8833 def : TokenAlias<".1Q", ".1q">;
8834 def : TokenAlias<".B", ".b">;
8835 def : TokenAlias<".H", ".h">;
8836 def : TokenAlias<".S", ".s">;
8837 def : TokenAlias<".D", ".d">;
8838 def : TokenAlias<".Q", ".q">;