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