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