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