[AArch64] The paired post-increment store instruction has an output register.
[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 def am_indexed7s8   : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S8", []>;
252 def am_indexed7s16  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S16", []>;
253 def am_indexed7s32  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S32", []>;
254 def am_indexed7s64  : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S64", []>;
255 def am_indexed7s128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed7S128", []>;
256
257 class AsmImmRange<int Low, int High> : AsmOperandClass {
258   let Name = "Imm" # Low # "_" # High;
259   let DiagnosticType = "InvalidImm" # Low # "_" # High;
260 }
261
262 def Imm1_8Operand : AsmImmRange<1, 8>;
263 def Imm1_16Operand : AsmImmRange<1, 16>;
264 def Imm1_32Operand : AsmImmRange<1, 32>;
265 def Imm1_64Operand : AsmImmRange<1, 64>;
266
267 def MovZSymbolG3AsmOperand : AsmOperandClass {
268   let Name = "MovZSymbolG3";
269   let RenderMethod = "addImmOperands";
270 }
271
272 def movz_symbol_g3 : Operand<i32> {
273   let ParserMatchClass = MovZSymbolG3AsmOperand;
274 }
275
276 def MovZSymbolG2AsmOperand : AsmOperandClass {
277   let Name = "MovZSymbolG2";
278   let RenderMethod = "addImmOperands";
279 }
280
281 def movz_symbol_g2 : Operand<i32> {
282   let ParserMatchClass = MovZSymbolG2AsmOperand;
283 }
284
285 def MovZSymbolG1AsmOperand : AsmOperandClass {
286   let Name = "MovZSymbolG1";
287   let RenderMethod = "addImmOperands";
288 }
289
290 def movz_symbol_g1 : Operand<i32> {
291   let ParserMatchClass = MovZSymbolG1AsmOperand;
292 }
293
294 def MovZSymbolG0AsmOperand : AsmOperandClass {
295   let Name = "MovZSymbolG0";
296   let RenderMethod = "addImmOperands";
297 }
298
299 def movz_symbol_g0 : Operand<i32> {
300   let ParserMatchClass = MovZSymbolG0AsmOperand;
301 }
302
303 def MovKSymbolG3AsmOperand : AsmOperandClass {
304   let Name = "MovKSymbolG3";
305   let RenderMethod = "addImmOperands";
306 }
307
308 def movk_symbol_g3 : Operand<i32> {
309   let ParserMatchClass = MovKSymbolG3AsmOperand;
310 }
311
312 def MovKSymbolG2AsmOperand : AsmOperandClass {
313   let Name = "MovKSymbolG2";
314   let RenderMethod = "addImmOperands";
315 }
316
317 def movk_symbol_g2 : Operand<i32> {
318   let ParserMatchClass = MovKSymbolG2AsmOperand;
319 }
320
321 def MovKSymbolG1AsmOperand : AsmOperandClass {
322   let Name = "MovKSymbolG1";
323   let RenderMethod = "addImmOperands";
324 }
325
326 def movk_symbol_g1 : Operand<i32> {
327   let ParserMatchClass = MovKSymbolG1AsmOperand;
328 }
329
330 def MovKSymbolG0AsmOperand : AsmOperandClass {
331   let Name = "MovKSymbolG0";
332   let RenderMethod = "addImmOperands";
333 }
334
335 def movk_symbol_g0 : Operand<i32> {
336   let ParserMatchClass = MovKSymbolG0AsmOperand;
337 }
338
339 class fixedpoint_i32<ValueType FloatVT>
340   : Operand<FloatVT>,
341     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {
342   let EncoderMethod = "getFixedPointScaleOpValue";
343   let DecoderMethod = "DecodeFixedPointScaleImm32";
344   let ParserMatchClass = Imm1_32Operand;
345 }
346
347 class fixedpoint_i64<ValueType FloatVT>
348   : Operand<FloatVT>,
349     ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {
350   let EncoderMethod = "getFixedPointScaleOpValue";
351   let DecoderMethod = "DecodeFixedPointScaleImm64";
352   let ParserMatchClass = Imm1_64Operand;
353 }
354
355 def fixedpoint_f32_i32 : fixedpoint_i32<f32>;
356 def fixedpoint_f64_i32 : fixedpoint_i32<f64>;
357
358 def fixedpoint_f32_i64 : fixedpoint_i64<f32>;
359 def fixedpoint_f64_i64 : fixedpoint_i64<f64>;
360
361 def vecshiftR8 : Operand<i32>, ImmLeaf<i32, [{
362   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
363 }]> {
364   let EncoderMethod = "getVecShiftR8OpValue";
365   let DecoderMethod = "DecodeVecShiftR8Imm";
366   let ParserMatchClass = Imm1_8Operand;
367 }
368 def vecshiftR16 : Operand<i32>, ImmLeaf<i32, [{
369   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
370 }]> {
371   let EncoderMethod = "getVecShiftR16OpValue";
372   let DecoderMethod = "DecodeVecShiftR16Imm";
373   let ParserMatchClass = Imm1_16Operand;
374 }
375 def vecshiftR16Narrow : Operand<i32>, ImmLeaf<i32, [{
376   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);
377 }]> {
378   let EncoderMethod = "getVecShiftR16OpValue";
379   let DecoderMethod = "DecodeVecShiftR16ImmNarrow";
380   let ParserMatchClass = Imm1_8Operand;
381 }
382 def vecshiftR32 : Operand<i32>, ImmLeaf<i32, [{
383   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
384 }]> {
385   let EncoderMethod = "getVecShiftR32OpValue";
386   let DecoderMethod = "DecodeVecShiftR32Imm";
387   let ParserMatchClass = Imm1_32Operand;
388 }
389 def vecshiftR32Narrow : Operand<i32>, ImmLeaf<i32, [{
390   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);
391 }]> {
392   let EncoderMethod = "getVecShiftR32OpValue";
393   let DecoderMethod = "DecodeVecShiftR32ImmNarrow";
394   let ParserMatchClass = Imm1_16Operand;
395 }
396 def vecshiftR64 : Operand<i32>, ImmLeaf<i32, [{
397   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);
398 }]> {
399   let EncoderMethod = "getVecShiftR64OpValue";
400   let DecoderMethod = "DecodeVecShiftR64Imm";
401   let ParserMatchClass = Imm1_64Operand;
402 }
403 def vecshiftR64Narrow : Operand<i32>, ImmLeaf<i32, [{
404   return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);
405 }]> {
406   let EncoderMethod = "getVecShiftR64OpValue";
407   let DecoderMethod = "DecodeVecShiftR64ImmNarrow";
408   let ParserMatchClass = Imm1_32Operand;
409 }
410
411 def Imm0_7Operand : AsmImmRange<0, 7>;
412 def Imm0_15Operand : AsmImmRange<0, 15>;
413 def Imm0_31Operand : AsmImmRange<0, 31>;
414 def Imm0_63Operand : AsmImmRange<0, 63>;
415
416 def vecshiftL8 : Operand<i32>, ImmLeaf<i32, [{
417   return (((uint32_t)Imm) < 8);
418 }]> {
419   let EncoderMethod = "getVecShiftL8OpValue";
420   let DecoderMethod = "DecodeVecShiftL8Imm";
421   let ParserMatchClass = Imm0_7Operand;
422 }
423 def vecshiftL16 : Operand<i32>, ImmLeaf<i32, [{
424   return (((uint32_t)Imm) < 16);
425 }]> {
426   let EncoderMethod = "getVecShiftL16OpValue";
427   let DecoderMethod = "DecodeVecShiftL16Imm";
428   let ParserMatchClass = Imm0_15Operand;
429 }
430 def vecshiftL32 : Operand<i32>, ImmLeaf<i32, [{
431   return (((uint32_t)Imm) < 32);
432 }]> {
433   let EncoderMethod = "getVecShiftL32OpValue";
434   let DecoderMethod = "DecodeVecShiftL32Imm";
435   let ParserMatchClass = Imm0_31Operand;
436 }
437 def vecshiftL64 : Operand<i32>, ImmLeaf<i32, [{
438   return (((uint32_t)Imm) < 64);
439 }]> {
440   let EncoderMethod = "getVecShiftL64OpValue";
441   let DecoderMethod = "DecodeVecShiftL64Imm";
442   let ParserMatchClass = Imm0_63Operand;
443 }
444
445
446 // Crazy immediate formats used by 32-bit and 64-bit logical immediate
447 // instructions for splatting repeating bit patterns across the immediate.
448 def logical_imm32_XFORM : SDNodeXForm<imm, [{
449   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);
450   return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
451 }]>;
452 def logical_imm64_XFORM : SDNodeXForm<imm, [{
453   uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);
454   return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
455 }]>;
456
457 let DiagnosticType = "LogicalSecondSource" in {
458   def LogicalImm32Operand : AsmOperandClass {
459     let Name = "LogicalImm32";
460   }
461   def LogicalImm64Operand : AsmOperandClass {
462     let Name = "LogicalImm64";
463   }
464   def LogicalImm32NotOperand : AsmOperandClass {
465     let Name = "LogicalImm32Not";
466   }
467   def LogicalImm64NotOperand : AsmOperandClass {
468     let Name = "LogicalImm64Not";
469   }
470 }
471 def logical_imm32 : Operand<i32>, PatLeaf<(imm), [{
472   return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 32);
473 }], logical_imm32_XFORM> {
474   let PrintMethod = "printLogicalImm32";
475   let ParserMatchClass = LogicalImm32Operand;
476 }
477 def logical_imm64 : Operand<i64>, PatLeaf<(imm), [{
478   return AArch64_AM::isLogicalImmediate(N->getZExtValue(), 64);
479 }], logical_imm64_XFORM> {
480   let PrintMethod = "printLogicalImm64";
481   let ParserMatchClass = LogicalImm64Operand;
482 }
483 def logical_imm32_not : Operand<i32> {
484   let ParserMatchClass = LogicalImm32NotOperand;
485 }
486 def logical_imm64_not : Operand<i64> {
487   let ParserMatchClass = LogicalImm64NotOperand;
488 }
489
490 // imm0_65535 predicate - True if the immediate is in the range [0,65535].
491 def Imm0_65535Operand : AsmImmRange<0, 65535>;
492 def imm0_65535 : Operand<i32>, ImmLeaf<i32, [{
493   return ((uint32_t)Imm) < 65536;
494 }]> {
495   let ParserMatchClass = Imm0_65535Operand;
496   let PrintMethod = "printHexImm";
497 }
498
499 // imm0_255 predicate - True if the immediate is in the range [0,255].
500 def Imm0_255Operand : AsmOperandClass { let Name = "Imm0_255"; }
501 def imm0_255 : Operand<i32>, ImmLeaf<i32, [{
502   return ((uint32_t)Imm) < 256;
503 }]> {
504   let ParserMatchClass = Imm0_255Operand;
505   let PrintMethod = "printHexImm";
506 }
507
508 // imm0_127 predicate - True if the immediate is in the range [0,127]
509 def Imm0_127Operand : AsmImmRange<0, 127>;
510 def imm0_127 : Operand<i32>, ImmLeaf<i32, [{
511   return ((uint32_t)Imm) < 128;
512 }]> {
513   let ParserMatchClass = Imm0_127Operand;
514   let PrintMethod = "printHexImm";
515 }
516
517 // NOTE: These imm0_N operands have to be of type i64 because i64 is the size
518 // for all shift-amounts.
519
520 // imm0_63 predicate - True if the immediate is in the range [0,63]
521 def imm0_63 : Operand<i64>, ImmLeaf<i64, [{
522   return ((uint64_t)Imm) < 64;
523 }]> {
524   let ParserMatchClass = Imm0_63Operand;
525 }
526
527 // imm0_31 predicate - True if the immediate is in the range [0,31]
528 def imm0_31 : Operand<i64>, ImmLeaf<i64, [{
529   return ((uint64_t)Imm) < 32;
530 }]> {
531   let ParserMatchClass = Imm0_31Operand;
532 }
533
534 // True if the 32-bit immediate is in the range [0,31]
535 def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{
536   return ((uint64_t)Imm) < 32;
537 }]> {
538   let ParserMatchClass = Imm0_31Operand;
539 }
540
541 // imm0_15 predicate - True if the immediate is in the range [0,15]
542 def imm0_15 : Operand<i64>, ImmLeaf<i64, [{
543   return ((uint64_t)Imm) < 16;
544 }]> {
545   let ParserMatchClass = Imm0_15Operand;
546 }
547
548 // imm0_7 predicate - True if the immediate is in the range [0,7]
549 def imm0_7 : Operand<i64>, ImmLeaf<i64, [{
550   return ((uint64_t)Imm) < 8;
551 }]> {
552   let ParserMatchClass = Imm0_7Operand;
553 }
554
555 // imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]
556 def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{
557   return ((uint32_t)Imm) < 16;
558 }]> {
559   let ParserMatchClass = Imm0_15Operand;
560 }
561
562 // An arithmetic shifter operand:
563 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr
564 //  {5-0} - imm6
565 class arith_shift<ValueType Ty, int width> : Operand<Ty> {
566   let PrintMethod = "printShifter";
567   let ParserMatchClass = !cast<AsmOperandClass>(
568                          "ArithmeticShifterOperand" # width);
569 }
570
571 def arith_shift32 : arith_shift<i32, 32>;
572 def arith_shift64 : arith_shift<i64, 64>;
573
574 class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>
575     : Operand<Ty>,
576       ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {
577   let PrintMethod = "printShiftedRegister";
578   let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));
579 }
580
581 def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;
582 def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;
583
584 // An arithmetic shifter operand:
585 //  {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror
586 //  {5-0} - imm6
587 class logical_shift<int width> : Operand<i32> {
588   let PrintMethod = "printShifter";
589   let ParserMatchClass = !cast<AsmOperandClass>(
590                          "LogicalShifterOperand" # width);
591 }
592
593 def logical_shift32 : logical_shift<32>;
594 def logical_shift64 : logical_shift<64>;
595
596 class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>
597     : Operand<Ty>,
598       ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {
599   let PrintMethod = "printShiftedRegister";
600   let MIOperandInfo = (ops regclass, shiftop);
601 }
602
603 def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;
604 def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;
605
606 // A logical vector shifter operand:
607 //  {7-6} - shift type: 00 = lsl
608 //  {5-0} - imm6: #0, #8, #16, or #24
609 def logical_vec_shift : Operand<i32> {
610   let PrintMethod = "printShifter";
611   let EncoderMethod = "getVecShifterOpValue";
612   let ParserMatchClass = LogicalVecShifterOperand;
613 }
614
615 // A logical vector half-word shifter operand:
616 //  {7-6} - shift type: 00 = lsl
617 //  {5-0} - imm6: #0 or #8
618 def logical_vec_hw_shift : Operand<i32> {
619   let PrintMethod = "printShifter";
620   let EncoderMethod = "getVecShifterOpValue";
621   let ParserMatchClass = LogicalVecHalfWordShifterOperand;
622 }
623
624 // A vector move shifter operand:
625 //  {0} - imm1: #8 or #16
626 def move_vec_shift : Operand<i32> {
627   let PrintMethod = "printShifter";
628   let EncoderMethod = "getMoveVecShifterOpValue";
629   let ParserMatchClass = MoveVecShifterOperand;
630 }
631
632 let DiagnosticType = "AddSubSecondSource" in {
633   def AddSubImmOperand : AsmOperandClass {
634     let Name = "AddSubImm";
635     let ParserMethod = "tryParseAddSubImm";
636   }
637   def AddSubImmNegOperand : AsmOperandClass {
638     let Name = "AddSubImmNeg";
639     let ParserMethod = "tryParseAddSubImm";
640   }
641 }
642 // An ADD/SUB immediate shifter operand:
643 //  second operand:
644 //  {7-6} - shift type: 00 = lsl
645 //  {5-0} - imm6: #0 or #12
646 class addsub_shifted_imm<ValueType Ty>
647     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {
648   let PrintMethod = "printAddSubImm";
649   let EncoderMethod = "getAddSubImmOpValue";
650   let ParserMatchClass = AddSubImmOperand;
651   let MIOperandInfo = (ops i32imm, i32imm);
652 }
653
654 class addsub_shifted_imm_neg<ValueType Ty>
655     : Operand<Ty> {
656   let EncoderMethod = "getAddSubImmOpValue";
657   let ParserMatchClass = AddSubImmNegOperand;
658   let MIOperandInfo = (ops i32imm, i32imm);
659 }
660
661 def addsub_shifted_imm32 : addsub_shifted_imm<i32>;
662 def addsub_shifted_imm64 : addsub_shifted_imm<i64>;
663 def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;
664 def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;
665
666 class neg_addsub_shifted_imm<ValueType Ty>
667     : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {
668   let PrintMethod = "printAddSubImm";
669   let EncoderMethod = "getAddSubImmOpValue";
670   let ParserMatchClass = AddSubImmOperand;
671   let MIOperandInfo = (ops i32imm, i32imm);
672 }
673
674 def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;
675 def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;
676
677 // An extend operand:
678 //  {5-3} - extend type
679 //  {2-0} - imm3
680 def arith_extend : Operand<i32> {
681   let PrintMethod = "printArithExtend";
682   let ParserMatchClass = ExtendOperand;
683 }
684 def arith_extend64 : Operand<i32> {
685   let PrintMethod = "printArithExtend";
686   let ParserMatchClass = ExtendOperand64;
687 }
688
689 // 'extend' that's a lsl of a 64-bit register.
690 def arith_extendlsl64 : Operand<i32> {
691   let PrintMethod = "printArithExtend";
692   let ParserMatchClass = ExtendOperandLSL64;
693 }
694
695 class arith_extended_reg32<ValueType Ty> : Operand<Ty>,
696                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
697   let PrintMethod = "printExtendedRegister";
698   let MIOperandInfo = (ops GPR32, arith_extend);
699 }
700
701 class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,
702                     ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {
703   let PrintMethod = "printExtendedRegister";
704   let MIOperandInfo = (ops GPR32, arith_extend64);
705 }
706
707 // Floating-point immediate.
708 def fpimm32 : Operand<f32>,
709               PatLeaf<(f32 fpimm), [{
710       return AArch64_AM::getFP32Imm(N->getValueAPF()) != -1;
711     }], SDNodeXForm<fpimm, [{
712       APFloat InVal = N->getValueAPF();
713       uint32_t enc = AArch64_AM::getFP32Imm(InVal);
714       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
715     }]>> {
716   let ParserMatchClass = FPImmOperand;
717   let PrintMethod = "printFPImmOperand";
718 }
719 def fpimm64 : Operand<f64>,
720               PatLeaf<(f64 fpimm), [{
721       return AArch64_AM::getFP64Imm(N->getValueAPF()) != -1;
722     }], SDNodeXForm<fpimm, [{
723       APFloat InVal = N->getValueAPF();
724       uint32_t enc = AArch64_AM::getFP64Imm(InVal);
725       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
726     }]>> {
727   let ParserMatchClass = FPImmOperand;
728   let PrintMethod = "printFPImmOperand";
729 }
730
731 def fpimm8 : Operand<i32> {
732   let ParserMatchClass = FPImmOperand;
733   let PrintMethod = "printFPImmOperand";
734 }
735
736 def fpimm0 : PatLeaf<(fpimm), [{
737   return N->isExactlyValue(+0.0);
738 }]>;
739
740 // Vector lane operands
741 class AsmVectorIndex<string Suffix> : AsmOperandClass {
742   let Name = "VectorIndex" # Suffix;
743   let DiagnosticType = "InvalidIndex" # Suffix;
744 }
745 def VectorIndex1Operand : AsmVectorIndex<"1">;
746 def VectorIndexBOperand : AsmVectorIndex<"B">;
747 def VectorIndexHOperand : AsmVectorIndex<"H">;
748 def VectorIndexSOperand : AsmVectorIndex<"S">;
749 def VectorIndexDOperand : AsmVectorIndex<"D">;
750
751 def VectorIndex1 : Operand<i64>, ImmLeaf<i64, [{
752   return ((uint64_t)Imm) == 1;
753 }]> {
754   let ParserMatchClass = VectorIndex1Operand;
755   let PrintMethod = "printVectorIndex";
756   let MIOperandInfo = (ops i64imm);
757 }
758 def VectorIndexB : Operand<i64>, ImmLeaf<i64, [{
759   return ((uint64_t)Imm) < 16;
760 }]> {
761   let ParserMatchClass = VectorIndexBOperand;
762   let PrintMethod = "printVectorIndex";
763   let MIOperandInfo = (ops i64imm);
764 }
765 def VectorIndexH : Operand<i64>, ImmLeaf<i64, [{
766   return ((uint64_t)Imm) < 8;
767 }]> {
768   let ParserMatchClass = VectorIndexHOperand;
769   let PrintMethod = "printVectorIndex";
770   let MIOperandInfo = (ops i64imm);
771 }
772 def VectorIndexS : Operand<i64>, ImmLeaf<i64, [{
773   return ((uint64_t)Imm) < 4;
774 }]> {
775   let ParserMatchClass = VectorIndexSOperand;
776   let PrintMethod = "printVectorIndex";
777   let MIOperandInfo = (ops i64imm);
778 }
779 def VectorIndexD : Operand<i64>, ImmLeaf<i64, [{
780   return ((uint64_t)Imm) < 2;
781 }]> {
782   let ParserMatchClass = VectorIndexDOperand;
783   let PrintMethod = "printVectorIndex";
784   let MIOperandInfo = (ops i64imm);
785 }
786
787 // 8-bit immediate for AdvSIMD where 64-bit values of the form:
788 // aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh
789 // are encoded as the eight bit value 'abcdefgh'.
790 def simdimmtype10 : Operand<i32>,
791                     PatLeaf<(f64 fpimm), [{
792       return AArch64_AM::isAdvSIMDModImmType10(N->getValueAPF()
793                                                .bitcastToAPInt()
794                                                .getZExtValue());
795     }], SDNodeXForm<fpimm, [{
796       APFloat InVal = N->getValueAPF();
797       uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()
798                                                            .bitcastToAPInt()
799                                                            .getZExtValue());
800       return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);
801     }]>> {
802   let ParserMatchClass = SIMDImmType10Operand;
803   let PrintMethod = "printSIMDType10Operand";
804 }
805
806
807 //---
808 // System management
809 //---
810
811 // Base encoding for system instruction operands.
812 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
813 class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,
814                   list<dag> pattern = []>
815     : I<oops, iops, asm, operands, "", pattern> {
816   let Inst{31-22} = 0b1101010100;
817   let Inst{21}    = L;
818 }
819
820 // System instructions which do not have an Rt register.
821 class SimpleSystemI<bit L, dag iops, string asm, string operands,
822                     list<dag> pattern = []>
823     : BaseSystemI<L, (outs), iops, asm, operands, pattern> {
824   let Inst{4-0} = 0b11111;
825 }
826
827 // System instructions which have an Rt register.
828 class RtSystemI<bit L, dag oops, dag iops, string asm, string operands>
829     : BaseSystemI<L, oops, iops, asm, operands>,
830       Sched<[WriteSys]> {
831   bits<5> Rt;
832   let Inst{4-0} = Rt;
833 }
834
835 // Hint instructions that take both a CRm and a 3-bit immediate.
836 // NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot
837 // model patterns with sufficiently fine granularity
838 let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in
839   class HintI<string mnemonic>
840       : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",
841                       [(int_aarch64_hint imm0_127:$imm)]>,
842         Sched<[WriteHint]> {
843     bits <7> imm;
844     let Inst{20-12} = 0b000110010;
845     let Inst{11-5} = imm;
846   }
847
848 // System instructions taking a single literal operand which encodes into
849 // CRm. op2 differentiates the opcodes.
850 def BarrierAsmOperand : AsmOperandClass {
851   let Name = "Barrier";
852   let ParserMethod = "tryParseBarrierOperand";
853 }
854 def barrier_op : Operand<i32> {
855   let PrintMethod = "printBarrierOption";
856   let ParserMatchClass = BarrierAsmOperand;
857 }
858 class CRmSystemI<Operand crmtype, bits<3> opc, string asm,
859                  list<dag> pattern = []>
860     : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,
861       Sched<[WriteBarrier]> {
862   bits<4> CRm;
863   let Inst{20-12} = 0b000110011;
864   let Inst{11-8} = CRm;
865   let Inst{7-5} = opc;
866 }
867
868 // MRS/MSR system instructions. These have different operand classes because
869 // a different subset of registers can be accessed through each instruction.
870 def MRSSystemRegisterOperand : AsmOperandClass {
871   let Name = "MRSSystemRegister";
872   let ParserMethod = "tryParseSysReg";
873   let DiagnosticType = "MRS";
874 }
875 // concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.
876 def mrs_sysreg_op : Operand<i32> {
877   let ParserMatchClass = MRSSystemRegisterOperand;
878   let DecoderMethod = "DecodeMRSSystemRegister";
879   let PrintMethod = "printMRSSystemRegister";
880 }
881
882 def MSRSystemRegisterOperand : AsmOperandClass {
883   let Name = "MSRSystemRegister";
884   let ParserMethod = "tryParseSysReg";
885   let DiagnosticType = "MSR";
886 }
887 def msr_sysreg_op : Operand<i32> {
888   let ParserMatchClass = MSRSystemRegisterOperand;
889   let DecoderMethod = "DecodeMSRSystemRegister";
890   let PrintMethod = "printMSRSystemRegister";
891 }
892
893 class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),
894                        "mrs", "\t$Rt, $systemreg"> {
895   bits<16> systemreg;
896   let Inst{20-5} = systemreg;
897 }
898
899 // FIXME: Some of these def NZCV, others don't. Best way to model that?
900 // Explicitly modeling each of the system register as a register class
901 // would do it, but feels like overkill at this point.
902 class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),
903                        "msr", "\t$systemreg, $Rt"> {
904   bits<16> systemreg;
905   let Inst{20-5} = systemreg;
906 }
907
908 def SystemPStateFieldOperand : AsmOperandClass {
909   let Name = "SystemPStateField";
910   let ParserMethod = "tryParseSysReg";
911 }
912 def pstatefield_op : Operand<i32> {
913   let ParserMatchClass = SystemPStateFieldOperand;
914   let PrintMethod = "printSystemPStateField";
915 }
916
917 let Defs = [NZCV] in
918 class MSRpstateI
919   : SimpleSystemI<0, (ins pstatefield_op:$pstate_field, imm0_15:$imm),
920                   "msr", "\t$pstate_field, $imm">,
921     Sched<[WriteSys]> {
922   bits<6> pstatefield;
923   bits<4> imm;
924   let Inst{20-19} = 0b00;
925   let Inst{18-16} = pstatefield{5-3};
926   let Inst{15-12} = 0b0100;
927   let Inst{11-8} = imm;
928   let Inst{7-5} = pstatefield{2-0};
929
930   let DecoderMethod = "DecodeSystemPStateInstruction";
931   // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns
932   // Fail the decoder should attempt to decode the instruction as MSRI.
933   let hasCompleteDecoder = 0;
934 }
935
936 // SYS and SYSL generic system instructions.
937 def SysCRAsmOperand : AsmOperandClass {
938   let Name = "SysCR";
939   let ParserMethod = "tryParseSysCROperand";
940 }
941
942 def sys_cr_op : Operand<i32> {
943   let PrintMethod = "printSysCROperand";
944   let ParserMatchClass = SysCRAsmOperand;
945 }
946
947 class SystemXtI<bit L, string asm>
948   : RtSystemI<L, (outs),
949        (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),
950        asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {
951   bits<3> op1;
952   bits<4> Cn;
953   bits<4> Cm;
954   bits<3> op2;
955   let Inst{20-19} = 0b01;
956   let Inst{18-16} = op1;
957   let Inst{15-12} = Cn;
958   let Inst{11-8}  = Cm;
959   let Inst{7-5}   = op2;
960 }
961
962 class SystemLXtI<bit L, string asm>
963   : RtSystemI<L, (outs),
964        (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),
965        asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {
966   bits<3> op1;
967   bits<4> Cn;
968   bits<4> Cm;
969   bits<3> op2;
970   let Inst{20-19} = 0b01;
971   let Inst{18-16} = op1;
972   let Inst{15-12} = Cn;
973   let Inst{11-8}  = Cm;
974   let Inst{7-5}   = op2;
975 }
976
977
978 // Branch (register) instructions:
979 //
980 //  case opc of
981 //    0001 blr
982 //    0000 br
983 //    0101 dret
984 //    0100 eret
985 //    0010 ret
986 //    otherwise UNDEFINED
987 class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,
988                     string operands, list<dag> pattern>
989     : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {
990   let Inst{31-25} = 0b1101011;
991   let Inst{24-21} = opc;
992   let Inst{20-16} = 0b11111;
993   let Inst{15-10} = 0b000000;
994   let Inst{4-0}   = 0b00000;
995 }
996
997 class BranchReg<bits<4> opc, string asm, list<dag> pattern>
998     : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {
999   bits<5> Rn;
1000   let Inst{9-5} = Rn;
1001 }
1002
1003 let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in
1004 class SpecialReturn<bits<4> opc, string asm>
1005     : BaseBranchReg<opc, (outs), (ins), asm, "", []> {
1006   let Inst{9-5} = 0b11111;
1007 }
1008
1009 //---
1010 // Conditional branch instruction.
1011 //---
1012
1013 // Condition code.
1014 // 4-bit immediate. Pretty-printed as <cc>
1015 def ccode : Operand<i32> {
1016   let PrintMethod = "printCondCode";
1017   let ParserMatchClass = CondCode;
1018 }
1019 def inv_ccode : Operand<i32> {
1020   // AL and NV are invalid in the aliases which use inv_ccode
1021   let PrintMethod = "printInverseCondCode";
1022   let ParserMatchClass = CondCode;
1023   let MCOperandPredicate = [{
1024     return MCOp.isImm() &&
1025            MCOp.getImm() != AArch64CC::AL &&
1026            MCOp.getImm() != AArch64CC::NV;
1027   }];
1028 }
1029
1030 // Conditional branch target. 19-bit immediate. The low two bits of the target
1031 // offset are implied zero and so are not part of the immediate.
1032 def PCRelLabel19Operand : AsmOperandClass {
1033   let Name = "PCRelLabel19";
1034   let DiagnosticType = "InvalidLabel";
1035 }
1036 def am_brcond : Operand<OtherVT> {
1037   let EncoderMethod = "getCondBranchTargetOpValue";
1038   let DecoderMethod = "DecodePCRelLabel19";
1039   let PrintMethod = "printAlignedLabel";
1040   let ParserMatchClass = PCRelLabel19Operand;
1041 }
1042
1043 class BranchCond : I<(outs), (ins ccode:$cond, am_brcond:$target),
1044                      "b", ".$cond\t$target", "",
1045                      [(AArch64brcond bb:$target, imm:$cond, NZCV)]>,
1046                    Sched<[WriteBr]> {
1047   let isBranch = 1;
1048   let isTerminator = 1;
1049   let Uses = [NZCV];
1050
1051   bits<4> cond;
1052   bits<19> target;
1053   let Inst{31-24} = 0b01010100;
1054   let Inst{23-5} = target;
1055   let Inst{4} = 0;
1056   let Inst{3-0} = cond;
1057 }
1058
1059 //---
1060 // Compare-and-branch instructions.
1061 //---
1062 class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>
1063     : I<(outs), (ins regtype:$Rt, am_brcond:$target),
1064          asm, "\t$Rt, $target", "",
1065          [(node regtype:$Rt, bb:$target)]>,
1066       Sched<[WriteBr]> {
1067   let isBranch = 1;
1068   let isTerminator = 1;
1069
1070   bits<5> Rt;
1071   bits<19> target;
1072   let Inst{30-25} = 0b011010;
1073   let Inst{24}    = op;
1074   let Inst{23-5}  = target;
1075   let Inst{4-0}   = Rt;
1076 }
1077
1078 multiclass CmpBranch<bit op, string asm, SDNode node> {
1079   def W : BaseCmpBranch<GPR32, op, asm, node> {
1080     let Inst{31} = 0;
1081   }
1082   def X : BaseCmpBranch<GPR64, op, asm, node> {
1083     let Inst{31} = 1;
1084   }
1085 }
1086
1087 //---
1088 // Test-bit-and-branch instructions.
1089 //---
1090 // Test-and-branch target. 14-bit sign-extended immediate. The low two bits of
1091 // the target offset are implied zero and so are not part of the immediate.
1092 def BranchTarget14Operand : AsmOperandClass {
1093   let Name = "BranchTarget14";
1094 }
1095 def am_tbrcond : Operand<OtherVT> {
1096   let EncoderMethod = "getTestBranchTargetOpValue";
1097   let PrintMethod = "printAlignedLabel";
1098   let ParserMatchClass = BranchTarget14Operand;
1099 }
1100
1101 // AsmOperand classes to emit (or not) special diagnostics
1102 def TBZImm0_31Operand : AsmOperandClass {
1103   let Name = "TBZImm0_31";
1104   let PredicateMethod = "isImm0_31";
1105   let RenderMethod = "addImm0_31Operands";
1106 }
1107 def TBZImm32_63Operand : AsmOperandClass {
1108   let Name = "Imm32_63";
1109   let DiagnosticType = "InvalidImm0_63";
1110 }
1111
1112 class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{
1113   return (((uint32_t)Imm) < 32);
1114 }]> {
1115   let ParserMatchClass = matcher;
1116 }
1117
1118 def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;
1119 def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;
1120
1121 def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{
1122   return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);
1123 }]> {
1124   let ParserMatchClass = TBZImm32_63Operand;
1125 }
1126
1127 class BaseTestBranch<RegisterClass regtype, Operand immtype,
1128                      bit op, string asm, SDNode node>
1129     : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),
1130        asm, "\t$Rt, $bit_off, $target", "",
1131        [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,
1132       Sched<[WriteBr]> {
1133   let isBranch = 1;
1134   let isTerminator = 1;
1135
1136   bits<5> Rt;
1137   bits<6> bit_off;
1138   bits<14> target;
1139
1140   let Inst{30-25} = 0b011011;
1141   let Inst{24}    = op;
1142   let Inst{23-19} = bit_off{4-0};
1143   let Inst{18-5}  = target;
1144   let Inst{4-0}   = Rt;
1145
1146   let DecoderMethod = "DecodeTestAndBranch";
1147 }
1148
1149 multiclass TestBranch<bit op, string asm, SDNode node> {
1150   def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {
1151     let Inst{31} = 0;
1152   }
1153
1154   def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {
1155     let Inst{31} = 1;
1156   }
1157
1158   // Alias X-reg with 0-31 imm to W-Reg.
1159   def : InstAlias<asm # "\t$Rd, $imm, $target",
1160                   (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,
1161                   tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;
1162   def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),
1163             (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),
1164             tbz_imm0_31_diag:$imm, bb:$target)>;
1165 }
1166
1167 //---
1168 // Unconditional branch (immediate) instructions.
1169 //---
1170 def BranchTarget26Operand : AsmOperandClass {
1171   let Name = "BranchTarget26";
1172   let DiagnosticType = "InvalidLabel";
1173 }
1174 def am_b_target : Operand<OtherVT> {
1175   let EncoderMethod = "getBranchTargetOpValue";
1176   let PrintMethod = "printAlignedLabel";
1177   let ParserMatchClass = BranchTarget26Operand;
1178 }
1179 def am_bl_target : Operand<i64> {
1180   let EncoderMethod = "getBranchTargetOpValue";
1181   let PrintMethod = "printAlignedLabel";
1182   let ParserMatchClass = BranchTarget26Operand;
1183 }
1184
1185 class BImm<bit op, dag iops, string asm, list<dag> pattern>
1186     : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {
1187   bits<26> addr;
1188   let Inst{31}    = op;
1189   let Inst{30-26} = 0b00101;
1190   let Inst{25-0}  = addr;
1191
1192   let DecoderMethod = "DecodeUnconditionalBranch";
1193 }
1194
1195 class BranchImm<bit op, string asm, list<dag> pattern>
1196     : BImm<op, (ins am_b_target:$addr), asm, pattern>;
1197 class CallImm<bit op, string asm, list<dag> pattern>
1198     : BImm<op, (ins am_bl_target:$addr), asm, pattern>;
1199
1200 //---
1201 // Basic one-operand data processing instructions.
1202 //---
1203
1204 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1205 class BaseOneOperandData<bits<3> opc, RegisterClass regtype, string asm,
1206                          SDPatternOperator node>
1207   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
1208       [(set regtype:$Rd, (node regtype:$Rn))]>,
1209     Sched<[WriteI, ReadI]> {
1210   bits<5> Rd;
1211   bits<5> Rn;
1212
1213   let Inst{30-13} = 0b101101011000000000;
1214   let Inst{12-10} = opc;
1215   let Inst{9-5}   = Rn;
1216   let Inst{4-0}   = Rd;
1217 }
1218
1219 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1220 multiclass OneOperandData<bits<3> opc, string asm,
1221                           SDPatternOperator node = null_frag> {
1222   def Wr : BaseOneOperandData<opc, GPR32, asm, node> {
1223     let Inst{31} = 0;
1224   }
1225
1226   def Xr : BaseOneOperandData<opc, GPR64, asm, node> {
1227     let Inst{31} = 1;
1228   }
1229 }
1230
1231 class OneWRegData<bits<3> opc, string asm, SDPatternOperator node>
1232     : BaseOneOperandData<opc, GPR32, asm, node> {
1233   let Inst{31} = 0;
1234 }
1235
1236 class OneXRegData<bits<3> opc, string asm, SDPatternOperator node>
1237     : BaseOneOperandData<opc, GPR64, asm, node> {
1238   let Inst{31} = 1;
1239 }
1240
1241 //---
1242 // Basic two-operand data processing instructions.
1243 //---
1244 class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1245                           list<dag> pattern>
1246     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1247         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1248       Sched<[WriteI, ReadI, ReadI]> {
1249   let Uses = [NZCV];
1250   bits<5> Rd;
1251   bits<5> Rn;
1252   bits<5> Rm;
1253   let Inst{30}    = isSub;
1254   let Inst{28-21} = 0b11010000;
1255   let Inst{20-16} = Rm;
1256   let Inst{15-10} = 0;
1257   let Inst{9-5}   = Rn;
1258   let Inst{4-0}   = Rd;
1259 }
1260
1261 class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,
1262                       SDNode OpNode>
1263     : BaseBaseAddSubCarry<isSub, regtype, asm,
1264         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;
1265
1266 class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,
1267                               SDNode OpNode>
1268     : BaseBaseAddSubCarry<isSub, regtype, asm,
1269         [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV)),
1270          (implicit NZCV)]> {
1271   let Defs = [NZCV];
1272 }
1273
1274 multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,
1275                        SDNode OpNode, SDNode OpNode_setflags> {
1276   def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {
1277     let Inst{31} = 0;
1278     let Inst{29} = 0;
1279   }
1280   def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {
1281     let Inst{31} = 1;
1282     let Inst{29} = 0;
1283   }
1284
1285   // Sets flags.
1286   def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,
1287                                     OpNode_setflags> {
1288     let Inst{31} = 0;
1289     let Inst{29} = 1;
1290   }
1291   def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,
1292                                     OpNode_setflags> {
1293     let Inst{31} = 1;
1294     let Inst{29} = 1;
1295   }
1296 }
1297
1298 class BaseTwoOperand<bits<4> opc, RegisterClass regtype, string asm,
1299                      SDPatternOperator OpNode>
1300   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1301       asm, "\t$Rd, $Rn, $Rm", "",
1302       [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]> {
1303   bits<5> Rd;
1304   bits<5> Rn;
1305   bits<5> Rm;
1306   let Inst{30-21} = 0b0011010110;
1307   let Inst{20-16} = Rm;
1308   let Inst{15-14} = 0b00;
1309   let Inst{13-10} = opc;
1310   let Inst{9-5}   = Rn;
1311   let Inst{4-0}   = Rd;
1312 }
1313
1314 class BaseDiv<bit isSigned, RegisterClass regtype, string asm,
1315               SDPatternOperator OpNode>
1316     : BaseTwoOperand<{0,0,1,?}, regtype, asm, OpNode> {
1317   let Inst{10}    = isSigned;
1318 }
1319
1320 multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {
1321   def Wr : BaseDiv<isSigned, GPR32, asm, OpNode>,
1322            Sched<[WriteID32, ReadID, ReadID]> {
1323     let Inst{31} = 0;
1324   }
1325   def Xr : BaseDiv<isSigned, GPR64, asm, OpNode>,
1326            Sched<[WriteID64, ReadID, ReadID]> {
1327     let Inst{31} = 1;
1328   }
1329 }
1330
1331 class BaseShift<bits<2> shift_type, RegisterClass regtype, string asm,
1332                 SDPatternOperator OpNode = null_frag>
1333   : BaseTwoOperand<{1,0,?,?}, regtype, asm, OpNode>,
1334     Sched<[WriteIS, ReadI]> {
1335   let Inst{11-10} = shift_type;
1336 }
1337
1338 multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {
1339   def Wr : BaseShift<shift_type, GPR32, asm> {
1340     let Inst{31} = 0;
1341   }
1342
1343   def Xr : BaseShift<shift_type, GPR64, asm, OpNode> {
1344     let Inst{31} = 1;
1345   }
1346
1347   def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),
1348             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,
1349                                              (EXTRACT_SUBREG i64:$Rm, sub_32))>;
1350
1351   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),
1352             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1353
1354   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),
1355             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1356
1357   def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),
1358             (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;
1359 }
1360
1361 class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>
1362     : InstAlias<asm#"\t$dst, $src1, $src2",
1363                 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;
1364
1365 class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,
1366                        RegisterClass addtype, string asm,
1367                        list<dag> pattern>
1368   : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),
1369       asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {
1370   bits<5> Rd;
1371   bits<5> Rn;
1372   bits<5> Rm;
1373   bits<5> Ra;
1374   let Inst{30-24} = 0b0011011;
1375   let Inst{23-21} = opc;
1376   let Inst{20-16} = Rm;
1377   let Inst{15}    = isSub;
1378   let Inst{14-10} = Ra;
1379   let Inst{9-5}   = Rn;
1380   let Inst{4-0}   = Rd;
1381 }
1382
1383 multiclass MulAccum<bit isSub, string asm, SDNode AccNode> {
1384   // MADD/MSUB generation is decided by MachineCombiner.cpp
1385   def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm,
1386       [/*(set GPR32:$Rd, (AccNode GPR32:$Ra, (mul GPR32:$Rn, GPR32:$Rm)))*/]>,
1387       Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1388     let Inst{31} = 0;
1389   }
1390
1391   def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm,
1392       [/*(set GPR64:$Rd, (AccNode GPR64:$Ra, (mul GPR64:$Rn, GPR64:$Rm)))*/]>,
1393       Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {
1394     let Inst{31} = 1;
1395   }
1396 }
1397
1398 class WideMulAccum<bit isSub, bits<3> opc, string asm,
1399                    SDNode AccNode, SDNode ExtNode>
1400   : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,
1401     [(set GPR64:$Rd, (AccNode GPR64:$Ra,
1402                             (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,
1403     Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {
1404   let Inst{31} = 1;
1405 }
1406
1407 class MulHi<bits<3> opc, string asm, SDNode OpNode>
1408   : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),
1409       asm, "\t$Rd, $Rn, $Rm", "",
1410       [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,
1411     Sched<[WriteIM64, ReadIM, ReadIM]> {
1412   bits<5> Rd;
1413   bits<5> Rn;
1414   bits<5> Rm;
1415   let Inst{31-24} = 0b10011011;
1416   let Inst{23-21} = opc;
1417   let Inst{20-16} = Rm;
1418   let Inst{15}    = 0;
1419   let Inst{9-5}   = Rn;
1420   let Inst{4-0}   = Rd;
1421
1422   // The Ra field of SMULH and UMULH is unused: it should be assembled as 31
1423   // (i.e. all bits 1) but is ignored by the processor.
1424   let PostEncoderMethod = "fixMulHigh";
1425 }
1426
1427 class MulAccumWAlias<string asm, Instruction inst>
1428     : InstAlias<asm#"\t$dst, $src1, $src2",
1429                 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;
1430 class MulAccumXAlias<string asm, Instruction inst>
1431     : InstAlias<asm#"\t$dst, $src1, $src2",
1432                 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;
1433 class WideMulAccumAlias<string asm, Instruction inst>
1434     : InstAlias<asm#"\t$dst, $src1, $src2",
1435                 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;
1436
1437 class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,
1438               SDPatternOperator OpNode, string asm>
1439   : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),
1440       asm, "\t$Rd, $Rn, $Rm", "",
1441       [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,
1442     Sched<[WriteISReg, ReadI, ReadISReg]> {
1443   bits<5> Rd;
1444   bits<5> Rn;
1445   bits<5> Rm;
1446
1447   let Inst{31} = sf;
1448   let Inst{30-21} = 0b0011010110;
1449   let Inst{20-16} = Rm;
1450   let Inst{15-13} = 0b010;
1451   let Inst{12} = C;
1452   let Inst{11-10} = sz;
1453   let Inst{9-5} = Rn;
1454   let Inst{4-0} = Rd;
1455   let Predicates = [HasCRC];
1456 }
1457
1458 //---
1459 // Address generation.
1460 //---
1461
1462 class ADRI<bit page, string asm, Operand adr, list<dag> pattern>
1463     : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",
1464         pattern>,
1465       Sched<[WriteI]> {
1466   bits<5>  Xd;
1467   bits<21> label;
1468   let Inst{31}    = page;
1469   let Inst{30-29} = label{1-0};
1470   let Inst{28-24} = 0b10000;
1471   let Inst{23-5}  = label{20-2};
1472   let Inst{4-0}   = Xd;
1473
1474   let DecoderMethod = "DecodeAdrInstruction";
1475 }
1476
1477 //---
1478 // Move immediate.
1479 //---
1480
1481 def movimm32_imm : Operand<i32> {
1482   let ParserMatchClass = Imm0_65535Operand;
1483   let EncoderMethod = "getMoveWideImmOpValue";
1484   let PrintMethod = "printHexImm";
1485 }
1486 def movimm32_shift : Operand<i32> {
1487   let PrintMethod = "printShifter";
1488   let ParserMatchClass = MovImm32ShifterOperand;
1489 }
1490 def movimm64_shift : Operand<i32> {
1491   let PrintMethod = "printShifter";
1492   let ParserMatchClass = MovImm64ShifterOperand;
1493 }
1494
1495 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1496 class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1497                         string asm>
1498   : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),
1499        asm, "\t$Rd, $imm$shift", "", []>,
1500     Sched<[WriteImm]> {
1501   bits<5> Rd;
1502   bits<16> imm;
1503   bits<6> shift;
1504   let Inst{30-29} = opc;
1505   let Inst{28-23} = 0b100101;
1506   let Inst{22-21} = shift{5-4};
1507   let Inst{20-5}  = imm;
1508   let Inst{4-0}   = Rd;
1509
1510   let DecoderMethod = "DecodeMoveImmInstruction";
1511 }
1512
1513 multiclass MoveImmediate<bits<2> opc, string asm> {
1514   def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {
1515     let Inst{31} = 0;
1516   }
1517
1518   def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {
1519     let Inst{31} = 1;
1520   }
1521 }
1522
1523 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1524 class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,
1525                           string asm>
1526   : I<(outs regtype:$Rd),
1527       (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),
1528        asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,
1529     Sched<[WriteI, ReadI]> {
1530   bits<5> Rd;
1531   bits<16> imm;
1532   bits<6> shift;
1533   let Inst{30-29} = opc;
1534   let Inst{28-23} = 0b100101;
1535   let Inst{22-21} = shift{5-4};
1536   let Inst{20-5}  = imm;
1537   let Inst{4-0}   = Rd;
1538
1539   let DecoderMethod = "DecodeMoveImmInstruction";
1540 }
1541
1542 multiclass InsertImmediate<bits<2> opc, string asm> {
1543   def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {
1544     let Inst{31} = 0;
1545   }
1546
1547   def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {
1548     let Inst{31} = 1;
1549   }
1550 }
1551
1552 //---
1553 // Add/Subtract
1554 //---
1555
1556 class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,
1557                     RegisterClass srcRegtype, addsub_shifted_imm immtype,
1558                     string asm, SDPatternOperator OpNode>
1559     : I<(outs dstRegtype:$Rd), (ins srcRegtype:$Rn, immtype:$imm),
1560         asm, "\t$Rd, $Rn, $imm", "",
1561         [(set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))]>,
1562       Sched<[WriteI, ReadI]>  {
1563   bits<5>  Rd;
1564   bits<5>  Rn;
1565   bits<14> imm;
1566   let Inst{30}    = isSub;
1567   let Inst{29}    = setFlags;
1568   let Inst{28-24} = 0b10001;
1569   let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #12
1570   let Inst{21-10} = imm{11-0};
1571   let Inst{9-5}   = Rn;
1572   let Inst{4-0}   = Rd;
1573   let DecoderMethod = "DecodeBaseAddSubImm";
1574 }
1575
1576 class BaseAddSubRegPseudo<RegisterClass regtype,
1577                           SDPatternOperator OpNode>
1578     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
1579              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
1580       Sched<[WriteI, ReadI, ReadI]>;
1581
1582 class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,
1583                      arith_shifted_reg shifted_regtype, string asm,
1584                      SDPatternOperator OpNode>
1585     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1586         asm, "\t$Rd, $Rn, $Rm", "",
1587         [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm))]>,
1588       Sched<[WriteISReg, ReadI, ReadISReg]> {
1589   // The operands are in order to match the 'addr' MI operands, so we
1590   // don't need an encoder method and by-name matching. Just use the default
1591   // in-order handling. Since we're using by-order, make sure the names
1592   // do not match.
1593   bits<5> dst;
1594   bits<5> src1;
1595   bits<5> src2;
1596   bits<8> shift;
1597   let Inst{30}    = isSub;
1598   let Inst{29}    = setFlags;
1599   let Inst{28-24} = 0b01011;
1600   let Inst{23-22} = shift{7-6};
1601   let Inst{21}    = 0;
1602   let Inst{20-16} = src2;
1603   let Inst{15-10} = shift{5-0};
1604   let Inst{9-5}   = src1;
1605   let Inst{4-0}   = dst;
1606
1607   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
1608 }
1609
1610 class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,
1611                      RegisterClass src1Regtype, Operand src2Regtype,
1612                      string asm, SDPatternOperator OpNode>
1613     : I<(outs dstRegtype:$R1),
1614         (ins src1Regtype:$R2, src2Regtype:$R3),
1615         asm, "\t$R1, $R2, $R3", "",
1616         [(set dstRegtype:$R1, (OpNode src1Regtype:$R2, src2Regtype:$R3))]>,
1617       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1618   bits<5> Rd;
1619   bits<5> Rn;
1620   bits<5> Rm;
1621   bits<6> ext;
1622   let Inst{30}    = isSub;
1623   let Inst{29}    = setFlags;
1624   let Inst{28-24} = 0b01011;
1625   let Inst{23-21} = 0b001;
1626   let Inst{20-16} = Rm;
1627   let Inst{15-13} = ext{5-3};
1628   let Inst{12-10} = ext{2-0};
1629   let Inst{9-5}   = Rn;
1630   let Inst{4-0}   = Rd;
1631
1632   let DecoderMethod = "DecodeAddSubERegInstruction";
1633 }
1634
1635 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1636 class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,
1637                        RegisterClass src1Regtype, RegisterClass src2Regtype,
1638                        Operand ext_op, string asm>
1639     : I<(outs dstRegtype:$Rd),
1640         (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),
1641         asm, "\t$Rd, $Rn, $Rm$ext", "", []>,
1642       Sched<[WriteIEReg, ReadI, ReadIEReg]> {
1643   bits<5> Rd;
1644   bits<5> Rn;
1645   bits<5> Rm;
1646   bits<6> ext;
1647   let Inst{30}    = isSub;
1648   let Inst{29}    = setFlags;
1649   let Inst{28-24} = 0b01011;
1650   let Inst{23-21} = 0b001;
1651   let Inst{20-16} = Rm;
1652   let Inst{15}    = ext{5};
1653   let Inst{12-10} = ext{2-0};
1654   let Inst{9-5}   = Rn;
1655   let Inst{4-0}   = Rd;
1656
1657   let DecoderMethod = "DecodeAddSubERegInstruction";
1658 }
1659
1660 // Aliases for register+register add/subtract.
1661 class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,
1662                      RegisterClass src1Regtype, RegisterClass src2Regtype,
1663                      int shiftExt>
1664     : InstAlias<asm#"\t$dst, $src1, $src2",
1665                 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,
1666                       shiftExt)>;
1667
1668 multiclass AddSub<bit isSub, string mnemonic, string alias,
1669                   SDPatternOperator OpNode = null_frag> {
1670   let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
1671   // Add/Subtract immediate
1672   // Increase the weight of the immediate variant to try to match it before
1673   // the extended register variant.
1674   // We used to match the register variant before the immediate when the
1675   // register argument could be implicitly zero-extended.
1676   let AddedComplexity = 6 in
1677   def Wri  : BaseAddSubImm<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,
1678                            mnemonic, OpNode> {
1679     let Inst{31} = 0;
1680   }
1681   let AddedComplexity = 6 in
1682   def Xri  : BaseAddSubImm<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,
1683                            mnemonic, OpNode> {
1684     let Inst{31} = 1;
1685   }
1686
1687   // Add/Subtract register - Only used for CodeGen
1688   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1689   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1690
1691   // Add/Subtract shifted register
1692   def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,
1693                            OpNode> {
1694     let Inst{31} = 0;
1695   }
1696   def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,
1697                            OpNode> {
1698     let Inst{31} = 1;
1699   }
1700   }
1701
1702   // Add/Subtract extended register
1703   let AddedComplexity = 1, hasSideEffects = 0 in {
1704   def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,
1705                            arith_extended_reg32<i32>, mnemonic, OpNode> {
1706     let Inst{31} = 0;
1707   }
1708   def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,
1709                            arith_extended_reg32to64<i64>, mnemonic, OpNode> {
1710     let Inst{31} = 1;
1711   }
1712   }
1713
1714   def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,
1715                                arith_extendlsl64, mnemonic> {
1716     // UXTX and SXTX only.
1717     let Inst{14-13} = 0b11;
1718     let Inst{31} = 1;
1719   }
1720
1721   // add Rd, Rb, -imm -> sub Rd, Rn, imm
1722   def : InstAlias<alias#"\t$Rd, $Rn, $imm",
1723                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,
1724                       addsub_shifted_imm32_neg:$imm), 0>;
1725   def : InstAlias<alias#"\t$Rd, $Rn, $imm",
1726                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,
1727                        addsub_shifted_imm64_neg:$imm), 0>;
1728
1729   // Register/register aliases with no shift when SP is not used.
1730   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1731                        GPR32, GPR32, GPR32, 0>;
1732   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1733                        GPR64, GPR64, GPR64, 0>;
1734
1735   // Register/register aliases with no shift when either the destination or
1736   // first source register is SP.
1737   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1738                        GPR32sponly, GPR32sp, GPR32, 16>; // UXTW #0
1739   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1740                        GPR32sp, GPR32sponly, GPR32, 16>; // UXTW #0
1741   def : AddSubRegAlias<mnemonic,
1742                        !cast<Instruction>(NAME#"Xrx64"),
1743                        GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #0
1744   def : AddSubRegAlias<mnemonic,
1745                        !cast<Instruction>(NAME#"Xrx64"),
1746                        GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #0
1747 }
1748
1749 multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,
1750                    string alias, string cmpAlias> {
1751   let isCompare = 1, Defs = [NZCV] in {
1752   // Add/Subtract immediate
1753   def Wri  : BaseAddSubImm<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,
1754                            mnemonic, OpNode> {
1755     let Inst{31} = 0;
1756   }
1757   def Xri  : BaseAddSubImm<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,
1758                            mnemonic, OpNode> {
1759     let Inst{31} = 1;
1760   }
1761
1762   // Add/Subtract register
1763   def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;
1764   def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;
1765
1766   // Add/Subtract shifted register
1767   def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,
1768                            OpNode> {
1769     let Inst{31} = 0;
1770   }
1771   def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,
1772                            OpNode> {
1773     let Inst{31} = 1;
1774   }
1775
1776   // Add/Subtract extended register
1777   let AddedComplexity = 1 in {
1778   def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,
1779                            arith_extended_reg32<i32>, mnemonic, OpNode> {
1780     let Inst{31} = 0;
1781   }
1782   def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,
1783                            arith_extended_reg32<i64>, mnemonic, OpNode> {
1784     let Inst{31} = 1;
1785   }
1786   }
1787
1788   def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,
1789                                arith_extendlsl64, mnemonic> {
1790     // UXTX and SXTX only.
1791     let Inst{14-13} = 0b11;
1792     let Inst{31} = 1;
1793   }
1794   } // Defs = [NZCV]
1795
1796   // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm
1797   def : InstAlias<alias#"\t$Rd, $Rn, $imm",
1798                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,
1799                       addsub_shifted_imm32_neg:$imm), 0>;
1800   def : InstAlias<alias#"\t$Rd, $Rn, $imm",
1801                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,
1802                        addsub_shifted_imm64_neg:$imm), 0>;
1803
1804   // Compare aliases
1805   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
1806                   WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;
1807   def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
1808                   XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;
1809   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")
1810                   WZR, GPR32sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
1811   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")
1812                   XZR, GPR64sp:$src1, GPR32:$src2, arith_extend:$sh), 4>;
1813   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")
1814                   XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;
1815   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")
1816                   WZR, GPR32:$src1, GPR32:$src2, arith_shift32:$sh), 4>;
1817   def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")
1818                   XZR, GPR64:$src1, GPR64:$src2, arith_shift64:$sh), 4>;
1819
1820   // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm
1821   def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")
1822                   WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;
1823   def : InstAlias<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")
1824                   XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;
1825
1826   // Compare shorthands
1827   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")
1828                   WZR, GPR32:$src1, GPR32:$src2, 0), 5>;
1829   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")
1830                   XZR, GPR64:$src1, GPR64:$src2, 0), 5>;
1831   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")
1832                   WZR, GPR32sponly:$src1, GPR32:$src2, 16), 5>;
1833   def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")
1834                   XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;
1835
1836   // Register/register aliases with no shift when SP is not used.
1837   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),
1838                        GPR32, GPR32, GPR32, 0>;
1839   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),
1840                        GPR64, GPR64, GPR64, 0>;
1841
1842   // Register/register aliases with no shift when the first source register
1843   // is SP.
1844   def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),
1845                        GPR32, GPR32sponly, GPR32, 16>; // UXTW #0
1846   def : AddSubRegAlias<mnemonic,
1847                        !cast<Instruction>(NAME#"Xrx64"),
1848                        GPR64, GPR64sponly, GPR64, 24>; // UXTX #0
1849 }
1850
1851 //---
1852 // Extract
1853 //---
1854 def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,
1855                                       SDTCisPtrTy<3>]>;
1856 def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;
1857
1858 class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,
1859                      list<dag> patterns>
1860     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),
1861          asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,
1862       Sched<[WriteExtr, ReadExtrHi]> {
1863   bits<5> Rd;
1864   bits<5> Rn;
1865   bits<5> Rm;
1866   bits<6> imm;
1867
1868   let Inst{30-23} = 0b00100111;
1869   let Inst{21}    = 0;
1870   let Inst{20-16} = Rm;
1871   let Inst{15-10} = imm;
1872   let Inst{9-5}   = Rn;
1873   let Inst{4-0}   = Rd;
1874 }
1875
1876 multiclass ExtractImm<string asm> {
1877   def Wrri : BaseExtractImm<GPR32, imm0_31, asm,
1878                       [(set GPR32:$Rd,
1879                         (AArch64Extr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {
1880     let Inst{31} = 0;
1881     let Inst{22} = 0;
1882     // imm<5> must be zero.
1883     let imm{5}   = 0;
1884   }
1885   def Xrri : BaseExtractImm<GPR64, imm0_63, asm,
1886                       [(set GPR64:$Rd,
1887                         (AArch64Extr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {
1888
1889     let Inst{31} = 1;
1890     let Inst{22} = 1;
1891   }
1892 }
1893
1894 //---
1895 // Bitfield
1896 //---
1897
1898 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1899 class BaseBitfieldImm<bits<2> opc,
1900                       RegisterClass regtype, Operand imm_type, string asm>
1901     : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),
1902          asm, "\t$Rd, $Rn, $immr, $imms", "", []>,
1903       Sched<[WriteIS, ReadI]> {
1904   bits<5> Rd;
1905   bits<5> Rn;
1906   bits<6> immr;
1907   bits<6> imms;
1908
1909   let Inst{30-29} = opc;
1910   let Inst{28-23} = 0b100110;
1911   let Inst{21-16} = immr;
1912   let Inst{15-10} = imms;
1913   let Inst{9-5}   = Rn;
1914   let Inst{4-0}   = Rd;
1915 }
1916
1917 multiclass BitfieldImm<bits<2> opc, string asm> {
1918   def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {
1919     let Inst{31} = 0;
1920     let Inst{22} = 0;
1921     // imms<5> and immr<5> must be zero, else ReservedValue().
1922     let Inst{21} = 0;
1923     let Inst{15} = 0;
1924   }
1925   def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {
1926     let Inst{31} = 1;
1927     let Inst{22} = 1;
1928   }
1929 }
1930
1931 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
1932 class BaseBitfieldImmWith2RegArgs<bits<2> opc,
1933                       RegisterClass regtype, Operand imm_type, string asm>
1934     : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,
1935                              imm_type:$imms),
1936          asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,
1937       Sched<[WriteIS, ReadI]> {
1938   bits<5> Rd;
1939   bits<5> Rn;
1940   bits<6> immr;
1941   bits<6> imms;
1942
1943   let Inst{30-29} = opc;
1944   let Inst{28-23} = 0b100110;
1945   let Inst{21-16} = immr;
1946   let Inst{15-10} = imms;
1947   let Inst{9-5}   = Rn;
1948   let Inst{4-0}   = Rd;
1949 }
1950
1951 multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {
1952   def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {
1953     let Inst{31} = 0;
1954     let Inst{22} = 0;
1955     // imms<5> and immr<5> must be zero, else ReservedValue().
1956     let Inst{21} = 0;
1957     let Inst{15} = 0;
1958   }
1959   def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {
1960     let Inst{31} = 1;
1961     let Inst{22} = 1;
1962   }
1963 }
1964
1965 //---
1966 // Logical
1967 //---
1968
1969 // Logical (immediate)
1970 class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,
1971                      RegisterClass sregtype, Operand imm_type, string asm,
1972                      list<dag> pattern>
1973     : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),
1974          asm, "\t$Rd, $Rn, $imm", "", pattern>,
1975       Sched<[WriteI, ReadI]> {
1976   bits<5>  Rd;
1977   bits<5>  Rn;
1978   bits<13> imm;
1979   let Inst{30-29} = opc;
1980   let Inst{28-23} = 0b100100;
1981   let Inst{22}    = imm{12};
1982   let Inst{21-16} = imm{11-6};
1983   let Inst{15-10} = imm{5-0};
1984   let Inst{9-5}   = Rn;
1985   let Inst{4-0}   = Rd;
1986
1987   let DecoderMethod = "DecodeLogicalImmInstruction";
1988 }
1989
1990 // Logical (shifted register)
1991 class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,
1992                       logical_shifted_reg shifted_regtype, string asm,
1993                       list<dag> pattern>
1994     : I<(outs regtype:$Rd), (ins regtype:$Rn, shifted_regtype:$Rm),
1995         asm, "\t$Rd, $Rn, $Rm", "", pattern>,
1996       Sched<[WriteISReg, ReadI, ReadISReg]> {
1997   // The operands are in order to match the 'addr' MI operands, so we
1998   // don't need an encoder method and by-name matching. Just use the default
1999   // in-order handling. Since we're using by-order, make sure the names
2000   // do not match.
2001   bits<5> dst;
2002   bits<5> src1;
2003   bits<5> src2;
2004   bits<8> shift;
2005   let Inst{30-29} = opc;
2006   let Inst{28-24} = 0b01010;
2007   let Inst{23-22} = shift{7-6};
2008   let Inst{21}    = N;
2009   let Inst{20-16} = src2;
2010   let Inst{15-10} = shift{5-0};
2011   let Inst{9-5}   = src1;
2012   let Inst{4-0}   = dst;
2013
2014   let DecoderMethod = "DecodeThreeAddrSRegInstruction";
2015 }
2016
2017 // Aliases for register+register logical instructions.
2018 class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype>
2019     : InstAlias<asm#"\t$dst, $src1, $src2",
2020                 (inst regtype:$dst, regtype:$src1, regtype:$src2, 0)>;
2021
2022 multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,
2023                       string Alias> {
2024   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2025   def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,
2026                            [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,
2027                                                logical_imm32:$imm))]> {
2028     let Inst{31} = 0;
2029     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2030   }
2031   let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in
2032   def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,
2033                            [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,
2034                                                logical_imm64:$imm))]> {
2035     let Inst{31} = 1;
2036   }
2037
2038   def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
2039                   (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,
2040                       logical_imm32_not:$imm), 0>;
2041   def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
2042                   (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,
2043                        logical_imm64_not:$imm), 0>;
2044 }
2045
2046 multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,
2047                        string Alias> {
2048   let isCompare = 1, Defs = [NZCV] in {
2049   def Wri  : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,
2050       [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {
2051     let Inst{31} = 0;
2052     let Inst{22} = 0; // 64-bit version has an additional bit of immediate.
2053   }
2054   def Xri  : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,
2055       [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {
2056     let Inst{31} = 1;
2057   }
2058   } // end Defs = [NZCV]
2059
2060   def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
2061                   (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,
2062                       logical_imm32_not:$imm), 0>;
2063   def : InstAlias<Alias # "\t$Rd, $Rn, $imm",
2064                   (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,
2065                        logical_imm64_not:$imm), 0>;
2066 }
2067
2068 class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>
2069     : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
2070              [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,
2071       Sched<[WriteI, ReadI, ReadI]>;
2072
2073 // Split from LogicalImm as not all instructions have both.
2074 multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,
2075                       SDPatternOperator OpNode> {
2076   let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
2077   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2078   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2079   }
2080
2081   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2082                             [(set GPR32:$Rd, (OpNode GPR32:$Rn,
2083                                                  logical_shifted_reg32:$Rm))]> {
2084     let Inst{31} = 0;
2085   }
2086   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2087                             [(set GPR64:$Rd, (OpNode GPR64:$Rn,
2088                                                  logical_shifted_reg64:$Rm))]> {
2089     let Inst{31} = 1;
2090   }
2091
2092   def : LogicalRegAlias<mnemonic,
2093                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
2094   def : LogicalRegAlias<mnemonic,
2095                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
2096 }
2097
2098 // Split from LogicalReg to allow setting NZCV Defs
2099 multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,
2100                        SDPatternOperator OpNode = null_frag> {
2101   let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
2102   def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;
2103   def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;
2104
2105   def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,
2106             [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm))]> {
2107     let Inst{31} = 0;
2108   }
2109   def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,
2110             [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm))]> {
2111     let Inst{31} = 1;
2112   }
2113   } // Defs = [NZCV]
2114
2115   def : LogicalRegAlias<mnemonic,
2116                         !cast<Instruction>(NAME#"Wrs"), GPR32>;
2117   def : LogicalRegAlias<mnemonic,
2118                         !cast<Instruction>(NAME#"Xrs"), GPR64>;
2119 }
2120
2121 //---
2122 // Conditionally set flags
2123 //---
2124
2125 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2126 class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,
2127                             string mnemonic, SDNode OpNode>
2128     : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),
2129          mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",
2130          [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),
2131                              (i32 imm:$cond), NZCV))]>,
2132       Sched<[WriteI, ReadI]> {
2133   let Uses = [NZCV];
2134   let Defs = [NZCV];
2135
2136   bits<5> Rn;
2137   bits<5> imm;
2138   bits<4> nzcv;
2139   bits<4> cond;
2140
2141   let Inst{30}    = op;
2142   let Inst{29-21} = 0b111010010;
2143   let Inst{20-16} = imm;
2144   let Inst{15-12} = cond;
2145   let Inst{11-10} = 0b10;
2146   let Inst{9-5}   = Rn;
2147   let Inst{4}     = 0b0;
2148   let Inst{3-0}   = nzcv;
2149 }
2150
2151 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
2152 class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,
2153                             SDNode OpNode>
2154     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
2155          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",
2156          [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),
2157                              (i32 imm:$cond), NZCV))]>,
2158       Sched<[WriteI, ReadI, ReadI]> {
2159   let Uses = [NZCV];
2160   let Defs = [NZCV];
2161
2162   bits<5> Rn;
2163   bits<5> Rm;
2164   bits<4> nzcv;
2165   bits<4> cond;
2166
2167   let Inst{30}    = op;
2168   let Inst{29-21} = 0b111010010;
2169   let Inst{20-16} = Rm;
2170   let Inst{15-12} = cond;
2171   let Inst{11-10} = 0b00;
2172   let Inst{9-5}   = Rn;
2173   let Inst{4}     = 0b0;
2174   let Inst{3-0}   = nzcv;
2175 }
2176
2177 multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {
2178   // immediate operand variants
2179   def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {
2180     let Inst{31} = 0;
2181   }
2182   def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {
2183     let Inst{31} = 1;
2184   }
2185   // register operand variants
2186   def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {
2187     let Inst{31} = 0;
2188   }
2189   def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {
2190     let Inst{31} = 1;
2191   }
2192 }
2193
2194 //---
2195 // Conditional select
2196 //---
2197
2198 class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>
2199     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2200          asm, "\t$Rd, $Rn, $Rm, $cond", "",
2201          [(set regtype:$Rd,
2202                (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,
2203       Sched<[WriteI, ReadI, ReadI]> {
2204   let Uses = [NZCV];
2205
2206   bits<5> Rd;
2207   bits<5> Rn;
2208   bits<5> Rm;
2209   bits<4> cond;
2210
2211   let Inst{30}    = op;
2212   let Inst{29-21} = 0b011010100;
2213   let Inst{20-16} = Rm;
2214   let Inst{15-12} = cond;
2215   let Inst{11-10} = op2;
2216   let Inst{9-5}   = Rn;
2217   let Inst{4-0}   = Rd;
2218 }
2219
2220 multiclass CondSelect<bit op, bits<2> op2, string asm> {
2221   def Wr : BaseCondSelect<op, op2, GPR32, asm> {
2222     let Inst{31} = 0;
2223   }
2224   def Xr : BaseCondSelect<op, op2, GPR64, asm> {
2225     let Inst{31} = 1;
2226   }
2227 }
2228
2229 class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,
2230                        PatFrag frag>
2231     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
2232          asm, "\t$Rd, $Rn, $Rm, $cond", "",
2233          [(set regtype:$Rd,
2234                (AArch64csel regtype:$Rn, (frag regtype:$Rm),
2235                (i32 imm:$cond), NZCV))]>,
2236       Sched<[WriteI, ReadI, ReadI]> {
2237   let Uses = [NZCV];
2238
2239   bits<5> Rd;
2240   bits<5> Rn;
2241   bits<5> Rm;
2242   bits<4> cond;
2243
2244   let Inst{30}    = op;
2245   let Inst{29-21} = 0b011010100;
2246   let Inst{20-16} = Rm;
2247   let Inst{15-12} = cond;
2248   let Inst{11-10} = op2;
2249   let Inst{9-5}   = Rn;
2250   let Inst{4-0}   = Rd;
2251 }
2252
2253 def inv_cond_XFORM : SDNodeXForm<imm, [{
2254   AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());
2255   return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),
2256                                    MVT::i32);
2257 }]>;
2258
2259 multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {
2260   def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {
2261     let Inst{31} = 0;
2262   }
2263   def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {
2264     let Inst{31} = 1;
2265   }
2266
2267   def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),
2268             (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,
2269                                            (inv_cond_XFORM imm:$cond))>;
2270
2271   def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),
2272             (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,
2273                                            (inv_cond_XFORM imm:$cond))>;
2274 }
2275
2276 //---
2277 // Special Mask Value
2278 //---
2279 def maski8_or_more : Operand<i32>,
2280   ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {
2281 }
2282 def maski16_or_more : Operand<i32>,
2283   ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {
2284 }
2285
2286
2287 //---
2288 // Load/store
2289 //---
2290
2291 // (unsigned immediate)
2292 // Indexed for 8-bit registers. offset is in range [0,4095].
2293 def am_indexed8 : ComplexPattern<i64, 2, "SelectAddrModeIndexed8", []>;
2294 def am_indexed16 : ComplexPattern<i64, 2, "SelectAddrModeIndexed16", []>;
2295 def am_indexed32 : ComplexPattern<i64, 2, "SelectAddrModeIndexed32", []>;
2296 def am_indexed64 : ComplexPattern<i64, 2, "SelectAddrModeIndexed64", []>;
2297 def am_indexed128 : ComplexPattern<i64, 2, "SelectAddrModeIndexed128", []>;
2298
2299 class UImm12OffsetOperand<int Scale> : AsmOperandClass {
2300   let Name = "UImm12Offset" # Scale;
2301   let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";
2302   let PredicateMethod = "isUImm12Offset<" # Scale # ">";
2303   let DiagnosticType = "InvalidMemoryIndexed" # Scale;
2304 }
2305
2306 def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;
2307 def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;
2308 def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;
2309 def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;
2310 def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;
2311
2312 class uimm12_scaled<int Scale> : Operand<i64> {
2313   let ParserMatchClass
2314    = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");
2315   let EncoderMethod
2316    = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";
2317   let PrintMethod = "printUImm12Offset<" # Scale # ">";
2318 }
2319
2320 def uimm12s1 : uimm12_scaled<1>;
2321 def uimm12s2 : uimm12_scaled<2>;
2322 def uimm12s4 : uimm12_scaled<4>;
2323 def uimm12s8 : uimm12_scaled<8>;
2324 def uimm12s16 : uimm12_scaled<16>;
2325
2326 class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2327                       string asm, list<dag> pattern>
2328     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2329   bits<5> Rt;
2330
2331   bits<5> Rn;
2332   bits<12> offset;
2333
2334   let Inst{31-30} = sz;
2335   let Inst{29-27} = 0b111;
2336   let Inst{26}    = V;
2337   let Inst{25-24} = 0b01;
2338   let Inst{23-22} = opc;
2339   let Inst{21-10} = offset;
2340   let Inst{9-5}   = Rn;
2341   let Inst{4-0}   = Rt;
2342
2343   let DecoderMethod = "DecodeUnsignedLdStInstruction";
2344 }
2345
2346 multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2347                   Operand indextype, string asm, list<dag> pattern> {
2348   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2349   def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),
2350                            (ins GPR64sp:$Rn, indextype:$offset),
2351                            asm, pattern>,
2352            Sched<[WriteLD]>;
2353
2354   def : InstAlias<asm # "\t$Rt, [$Rn]",
2355                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2356 }
2357
2358 multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2359              Operand indextype, string asm, list<dag> pattern> {
2360   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2361   def ui : BaseLoadStoreUI<sz, V, opc, (outs),
2362                            (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),
2363                            asm, pattern>,
2364            Sched<[WriteST]>;
2365
2366   def : InstAlias<asm # "\t$Rt, [$Rn]",
2367                   (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;
2368 }
2369
2370 def PrefetchOperand : AsmOperandClass {
2371   let Name = "Prefetch";
2372   let ParserMethod = "tryParsePrefetch";
2373 }
2374 def prfop : Operand<i32> {
2375   let PrintMethod = "printPrefetchOp";
2376   let ParserMatchClass = PrefetchOperand;
2377 }
2378
2379 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2380 class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>
2381     : BaseLoadStoreUI<sz, V, opc,
2382                       (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),
2383                       asm, pat>,
2384       Sched<[WriteLD]>;
2385
2386 //---
2387 // Load literal
2388 //---
2389
2390 // Load literal address: 19-bit immediate. The low two bits of the target
2391 // offset are implied zero and so are not part of the immediate.
2392 def am_ldrlit : Operand<OtherVT> {
2393   let EncoderMethod = "getLoadLiteralOpValue";
2394   let DecoderMethod = "DecodePCRelLabel19";
2395   let PrintMethod = "printAlignedLabel";
2396   let ParserMatchClass = PCRelLabel19Operand;
2397 }
2398
2399 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2400 class LoadLiteral<bits<2> opc, bit V, RegisterClass regtype, string asm>
2401     : I<(outs regtype:$Rt), (ins am_ldrlit:$label),
2402         asm, "\t$Rt, $label", "", []>,
2403       Sched<[WriteLD]> {
2404   bits<5> Rt;
2405   bits<19> label;
2406   let Inst{31-30} = opc;
2407   let Inst{29-27} = 0b011;
2408   let Inst{26}    = V;
2409   let Inst{25-24} = 0b00;
2410   let Inst{23-5}  = label;
2411   let Inst{4-0}   = Rt;
2412 }
2413
2414 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2415 class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>
2416     : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),
2417         asm, "\t$Rt, $label", "", pat>,
2418       Sched<[WriteLD]> {
2419   bits<5> Rt;
2420   bits<19> label;
2421   let Inst{31-30} = opc;
2422   let Inst{29-27} = 0b011;
2423   let Inst{26}    = V;
2424   let Inst{25-24} = 0b00;
2425   let Inst{23-5}  = label;
2426   let Inst{4-0}   = Rt;
2427 }
2428
2429 //---
2430 // Load/store register offset
2431 //---
2432
2433 def ro_Xindexed8 : ComplexPattern<i64, 4, "SelectAddrModeXRO<8>", []>;
2434 def ro_Xindexed16 : ComplexPattern<i64, 4, "SelectAddrModeXRO<16>", []>;
2435 def ro_Xindexed32 : ComplexPattern<i64, 4, "SelectAddrModeXRO<32>", []>;
2436 def ro_Xindexed64 : ComplexPattern<i64, 4, "SelectAddrModeXRO<64>", []>;
2437 def ro_Xindexed128 : ComplexPattern<i64, 4, "SelectAddrModeXRO<128>", []>;
2438
2439 def ro_Windexed8 : ComplexPattern<i64, 4, "SelectAddrModeWRO<8>", []>;
2440 def ro_Windexed16 : ComplexPattern<i64, 4, "SelectAddrModeWRO<16>", []>;
2441 def ro_Windexed32 : ComplexPattern<i64, 4, "SelectAddrModeWRO<32>", []>;
2442 def ro_Windexed64 : ComplexPattern<i64, 4, "SelectAddrModeWRO<64>", []>;
2443 def ro_Windexed128 : ComplexPattern<i64, 4, "SelectAddrModeWRO<128>", []>;
2444
2445 class MemExtendOperand<string Reg, int Width> : AsmOperandClass {
2446   let Name = "Mem" # Reg # "Extend" # Width;
2447   let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";
2448   let RenderMethod = "addMemExtendOperands";
2449   let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;
2450 }
2451
2452 def MemWExtend8Operand : MemExtendOperand<"W", 8> {
2453   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2454   // the trivial shift.
2455   let RenderMethod = "addMemExtend8Operands";
2456 }
2457 def MemWExtend16Operand : MemExtendOperand<"W", 16>;
2458 def MemWExtend32Operand : MemExtendOperand<"W", 32>;
2459 def MemWExtend64Operand : MemExtendOperand<"W", 64>;
2460 def MemWExtend128Operand : MemExtendOperand<"W", 128>;
2461
2462 def MemXExtend8Operand : MemExtendOperand<"X", 8> {
2463   // The address "[x0, x1, lsl #0]" actually maps to the variant which performs
2464   // the trivial shift.
2465   let RenderMethod = "addMemExtend8Operands";
2466 }
2467 def MemXExtend16Operand : MemExtendOperand<"X", 16>;
2468 def MemXExtend32Operand : MemExtendOperand<"X", 32>;
2469 def MemXExtend64Operand : MemExtendOperand<"X", 64>;
2470 def MemXExtend128Operand : MemExtendOperand<"X", 128>;
2471
2472 class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>
2473         : Operand<i32> {
2474   let ParserMatchClass = ParserClass;
2475   let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";
2476   let DecoderMethod = "DecodeMemExtend";
2477   let EncoderMethod = "getMemExtendOpValue";
2478   let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);
2479 }
2480
2481 def ro_Wextend8   : ro_extend<MemWExtend8Operand,   "w", 8>;
2482 def ro_Wextend16  : ro_extend<MemWExtend16Operand,  "w", 16>;
2483 def ro_Wextend32  : ro_extend<MemWExtend32Operand,  "w", 32>;
2484 def ro_Wextend64  : ro_extend<MemWExtend64Operand,  "w", 64>;
2485 def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;
2486
2487 def ro_Xextend8   : ro_extend<MemXExtend8Operand,   "x", 8>;
2488 def ro_Xextend16  : ro_extend<MemXExtend16Operand,  "x", 16>;
2489 def ro_Xextend32  : ro_extend<MemXExtend32Operand,  "x", 32>;
2490 def ro_Xextend64  : ro_extend<MemXExtend64Operand,  "x", 64>;
2491 def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;
2492
2493 class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,
2494                   Operand wextend, Operand xextend>  {
2495   // CodeGen-level pattern covering the entire addressing mode.
2496   ComplexPattern Wpat = windex;
2497   ComplexPattern Xpat = xindex;
2498
2499   // Asm-level Operand covering the valid "uxtw #3" style syntax.
2500   Operand Wext = wextend;
2501   Operand Xext = xextend;
2502 }
2503
2504 def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;
2505 def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;
2506 def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;
2507 def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;
2508 def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,
2509                        ro_Xextend128>;
2510
2511 class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2512                       string asm, dag ins, dag outs, list<dag> pat>
2513     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2514   bits<5> Rt;
2515   bits<5> Rn;
2516   bits<5> Rm;
2517   bits<2> extend;
2518   let Inst{31-30} = sz;
2519   let Inst{29-27} = 0b111;
2520   let Inst{26}    = V;
2521   let Inst{25-24} = 0b00;
2522   let Inst{23-22} = opc;
2523   let Inst{21}    = 1;
2524   let Inst{20-16} = Rm;
2525   let Inst{15}    = extend{1}; // sign extend Rm?
2526   let Inst{14}    = 1;
2527   let Inst{12}    = extend{0}; // do shift?
2528   let Inst{11-10} = 0b10;
2529   let Inst{9-5}   = Rn;
2530   let Inst{4-0}   = Rt;
2531 }
2532
2533 class ROInstAlias<string asm, RegisterClass regtype, Instruction INST>
2534   : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",
2535               (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2536
2537 multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2538                    string asm, ValueType Ty, SDPatternOperator loadop> {
2539   let AddedComplexity = 10 in
2540   def roW : LoadStore8RO<sz, V, opc, regtype, asm,
2541                  (outs regtype:$Rt),
2542                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2543                  [(set (Ty regtype:$Rt),
2544                        (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2545                                              ro_Wextend8:$extend)))]>,
2546            Sched<[WriteLDIdx, ReadAdrBase]> {
2547     let Inst{13} = 0b0;
2548   }
2549
2550   let AddedComplexity = 10 in
2551   def roX : LoadStore8RO<sz, V, opc, regtype, asm,
2552                  (outs regtype:$Rt),
2553                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2554                  [(set (Ty regtype:$Rt),
2555                        (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2556                                              ro_Xextend8:$extend)))]>,
2557            Sched<[WriteLDIdx, ReadAdrBase]> {
2558     let Inst{13} = 0b1;
2559   }
2560
2561   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2562 }
2563
2564 multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2565                     string asm, ValueType Ty, SDPatternOperator storeop> {
2566   let AddedComplexity = 10 in
2567   def roW : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2568                  (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),
2569                  [(storeop (Ty regtype:$Rt),
2570                            (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,
2571                                          ro_Wextend8:$extend))]>,
2572             Sched<[WriteSTIdx, ReadAdrBase]> {
2573     let Inst{13} = 0b0;
2574   }
2575
2576   let AddedComplexity = 10 in
2577   def roX : LoadStore8RO<sz, V, opc, regtype, asm, (outs),
2578                  (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),
2579                  [(storeop (Ty regtype:$Rt),
2580                            (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,
2581                                          ro_Xextend8:$extend))]>,
2582             Sched<[WriteSTIdx, ReadAdrBase]> {
2583     let Inst{13} = 0b1;
2584   }
2585
2586   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2587 }
2588
2589 class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2590                       string asm, dag ins, dag outs, list<dag> pat>
2591     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2592   bits<5> Rt;
2593   bits<5> Rn;
2594   bits<5> Rm;
2595   bits<2> extend;
2596   let Inst{31-30} = sz;
2597   let Inst{29-27} = 0b111;
2598   let Inst{26}    = V;
2599   let Inst{25-24} = 0b00;
2600   let Inst{23-22} = opc;
2601   let Inst{21}    = 1;
2602   let Inst{20-16} = Rm;
2603   let Inst{15}    = extend{1}; // sign extend Rm?
2604   let Inst{14}    = 1;
2605   let Inst{12}    = extend{0}; // do shift?
2606   let Inst{11-10} = 0b10;
2607   let Inst{9-5}   = Rn;
2608   let Inst{4-0}   = Rt;
2609 }
2610
2611 multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2612                     string asm, ValueType Ty, SDPatternOperator loadop> {
2613   let AddedComplexity = 10 in
2614   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2615                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2616                  [(set (Ty regtype:$Rt),
2617                        (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2618                                               ro_Wextend16:$extend)))]>,
2619             Sched<[WriteLDIdx, ReadAdrBase]> {
2620     let Inst{13} = 0b0;
2621   }
2622
2623   let AddedComplexity = 10 in
2624   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2625                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2626                  [(set (Ty regtype:$Rt),
2627                        (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2628                                              ro_Xextend16:$extend)))]>,
2629             Sched<[WriteLDIdx, ReadAdrBase]> {
2630     let Inst{13} = 0b1;
2631   }
2632
2633   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2634 }
2635
2636 multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2637                      string asm, ValueType Ty, SDPatternOperator storeop> {
2638   let AddedComplexity = 10 in
2639   def roW : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2640                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),
2641                 [(storeop (Ty regtype:$Rt),
2642                           (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,
2643                                          ro_Wextend16:$extend))]>,
2644            Sched<[WriteSTIdx, ReadAdrBase]> {
2645     let Inst{13} = 0b0;
2646   }
2647
2648   let AddedComplexity = 10 in
2649   def roX : LoadStore16RO<sz, V, opc, regtype, asm, (outs),
2650                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),
2651                 [(storeop (Ty regtype:$Rt),
2652                           (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,
2653                                          ro_Xextend16:$extend))]>,
2654            Sched<[WriteSTIdx, ReadAdrBase]> {
2655     let Inst{13} = 0b1;
2656   }
2657
2658   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2659 }
2660
2661 class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2662                       string asm, dag ins, dag outs, list<dag> pat>
2663     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2664   bits<5> Rt;
2665   bits<5> Rn;
2666   bits<5> Rm;
2667   bits<2> extend;
2668   let Inst{31-30} = sz;
2669   let Inst{29-27} = 0b111;
2670   let Inst{26}    = V;
2671   let Inst{25-24} = 0b00;
2672   let Inst{23-22} = opc;
2673   let Inst{21}    = 1;
2674   let Inst{20-16} = Rm;
2675   let Inst{15}    = extend{1}; // sign extend Rm?
2676   let Inst{14}    = 1;
2677   let Inst{12}    = extend{0}; // do shift?
2678   let Inst{11-10} = 0b10;
2679   let Inst{9-5}   = Rn;
2680   let Inst{4-0}   = Rt;
2681 }
2682
2683 multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2684                     string asm, ValueType Ty, SDPatternOperator loadop> {
2685   let AddedComplexity = 10 in
2686   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2687                  (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2688                  [(set (Ty regtype:$Rt),
2689                        (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2690                                               ro_Wextend32:$extend)))]>,
2691            Sched<[WriteLDIdx, ReadAdrBase]> {
2692     let Inst{13} = 0b0;
2693   }
2694
2695   let AddedComplexity = 10 in
2696   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2697                  (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2698                  [(set (Ty regtype:$Rt),
2699                        (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2700                                               ro_Xextend32:$extend)))]>,
2701            Sched<[WriteLDIdx, ReadAdrBase]> {
2702     let Inst{13} = 0b1;
2703   }
2704
2705   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2706 }
2707
2708 multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2709                      string asm, ValueType Ty, SDPatternOperator storeop> {
2710   let AddedComplexity = 10 in
2711   def roW : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2712                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),
2713                 [(storeop (Ty regtype:$Rt),
2714                           (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,
2715                                          ro_Wextend32:$extend))]>,
2716             Sched<[WriteSTIdx, ReadAdrBase]> {
2717     let Inst{13} = 0b0;
2718   }
2719
2720   let AddedComplexity = 10 in
2721   def roX : LoadStore32RO<sz, V, opc, regtype, asm, (outs),
2722                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),
2723                 [(storeop (Ty regtype:$Rt),
2724                           (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,
2725                                         ro_Xextend32:$extend))]>,
2726             Sched<[WriteSTIdx, ReadAdrBase]> {
2727     let Inst{13} = 0b1;
2728   }
2729
2730   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2731 }
2732
2733 class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2734                       string asm, dag ins, dag outs, list<dag> pat>
2735     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2736   bits<5> Rt;
2737   bits<5> Rn;
2738   bits<5> Rm;
2739   bits<2> extend;
2740   let Inst{31-30} = sz;
2741   let Inst{29-27} = 0b111;
2742   let Inst{26}    = V;
2743   let Inst{25-24} = 0b00;
2744   let Inst{23-22} = opc;
2745   let Inst{21}    = 1;
2746   let Inst{20-16} = Rm;
2747   let Inst{15}    = extend{1}; // sign extend Rm?
2748   let Inst{14}    = 1;
2749   let Inst{12}    = extend{0}; // do shift?
2750   let Inst{11-10} = 0b10;
2751   let Inst{9-5}   = Rn;
2752   let Inst{4-0}   = Rt;
2753 }
2754
2755 multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2756                     string asm, ValueType Ty, SDPatternOperator loadop> {
2757   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2758   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2759                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2760                 [(set (Ty regtype:$Rt),
2761                       (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2762                                              ro_Wextend64:$extend)))]>,
2763            Sched<[WriteLDIdx, ReadAdrBase]> {
2764     let Inst{13} = 0b0;
2765   }
2766
2767   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2768   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2769                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2770                  [(set (Ty regtype:$Rt),
2771                        (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2772                                               ro_Xextend64:$extend)))]>,
2773            Sched<[WriteLDIdx, ReadAdrBase]> {
2774     let Inst{13} = 0b1;
2775   }
2776
2777   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2778 }
2779
2780 multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2781                      string asm, ValueType Ty, SDPatternOperator storeop> {
2782   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2783   def roW : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2784                 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2785                 [(storeop (Ty regtype:$Rt),
2786                           (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2787                                          ro_Wextend64:$extend))]>,
2788             Sched<[WriteSTIdx, ReadAdrBase]> {
2789     let Inst{13} = 0b0;
2790   }
2791
2792   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2793   def roX : LoadStore64RO<sz, V, opc, regtype, asm, (outs),
2794                 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2795                 [(storeop (Ty regtype:$Rt),
2796                           (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2797                                          ro_Xextend64:$extend))]>,
2798             Sched<[WriteSTIdx, ReadAdrBase]> {
2799     let Inst{13} = 0b1;
2800   }
2801
2802   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2803 }
2804
2805 class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2806                       string asm, dag ins, dag outs, list<dag> pat>
2807     : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {
2808   bits<5> Rt;
2809   bits<5> Rn;
2810   bits<5> Rm;
2811   bits<2> extend;
2812   let Inst{31-30} = sz;
2813   let Inst{29-27} = 0b111;
2814   let Inst{26}    = V;
2815   let Inst{25-24} = 0b00;
2816   let Inst{23-22} = opc;
2817   let Inst{21}    = 1;
2818   let Inst{20-16} = Rm;
2819   let Inst{15}    = extend{1}; // sign extend Rm?
2820   let Inst{14}    = 1;
2821   let Inst{12}    = extend{0}; // do shift?
2822   let Inst{11-10} = 0b10;
2823   let Inst{9-5}   = Rn;
2824   let Inst{4-0}   = Rt;
2825 }
2826
2827 multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2828                      string asm, ValueType Ty, SDPatternOperator loadop> {
2829   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2830   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2831                 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2832                  [(set (Ty regtype:$Rt),
2833                        (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2834                                                ro_Wextend128:$extend)))]>,
2835             Sched<[WriteLDIdx, ReadAdrBase]> {
2836     let Inst{13} = 0b0;
2837   }
2838
2839   let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
2840   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs regtype:$Rt),
2841                 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2842                  [(set (Ty regtype:$Rt),
2843                        (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2844                                                ro_Xextend128:$extend)))]>,
2845             Sched<[WriteLDIdx, ReadAdrBase]> {
2846     let Inst{13} = 0b1;
2847   }
2848
2849   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2850 }
2851
2852 multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2853                       string asm, ValueType Ty, SDPatternOperator storeop> {
2854   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2855   def roW : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2856                (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),
2857                 [(storeop (Ty regtype:$Rt),
2858                           (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,
2859                                           ro_Wextend128:$extend))]>,
2860             Sched<[WriteSTIdx, ReadAdrBase]> {
2861     let Inst{13} = 0b0;
2862   }
2863
2864   let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
2865   def roX : LoadStore128RO<sz, V, opc, regtype, asm, (outs),
2866                (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),
2867                 [(storeop (Ty regtype:$Rt),
2868                           (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,
2869                                           ro_Xextend128:$extend))]>,
2870             Sched<[WriteSTIdx, ReadAdrBase]> {
2871     let Inst{13} = 0b1;
2872   }
2873
2874   def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX")>;
2875 }
2876
2877 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2878 class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,
2879                      string asm, list<dag> pat>
2880     : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,
2881       Sched<[WriteLD]> {
2882   bits<5> Rt;
2883   bits<5> Rn;
2884   bits<5> Rm;
2885   bits<2> extend;
2886   let Inst{31-30} = sz;
2887   let Inst{29-27} = 0b111;
2888   let Inst{26}    = V;
2889   let Inst{25-24} = 0b00;
2890   let Inst{23-22} = opc;
2891   let Inst{21}    = 1;
2892   let Inst{20-16} = Rm;
2893   let Inst{15}    = extend{1}; // sign extend Rm?
2894   let Inst{14}    = 1;
2895   let Inst{12}    = extend{0}; // do shift?
2896   let Inst{11-10} = 0b10;
2897   let Inst{9-5}   = Rn;
2898   let Inst{4-0}   = Rt;
2899 }
2900
2901 multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {
2902   def roW : BasePrefetchRO<sz, V, opc, (outs),
2903                 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),
2904                 asm, [(AArch64Prefetch imm:$Rt,
2905                                      (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,
2906                                                     ro_Wextend64:$extend))]> {
2907     let Inst{13} = 0b0;
2908   }
2909
2910   def roX : BasePrefetchRO<sz, V, opc, (outs),
2911                 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),
2912                 asm,  [(AArch64Prefetch imm:$Rt,
2913                                       (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,
2914                                                      ro_Xextend64:$extend))]> {
2915     let Inst{13} = 0b1;
2916   }
2917
2918   def : InstAlias<"prfm $Rt, [$Rn, $Rm]",
2919                (!cast<Instruction>(NAME # "roX") prfop:$Rt,
2920                                                  GPR64sp:$Rn, GPR64:$Rm, 0, 0)>;
2921 }
2922
2923 //---
2924 // Load/store unscaled immediate
2925 //---
2926
2927 def am_unscaled8 :  ComplexPattern<i64, 2, "SelectAddrModeUnscaled8", []>;
2928 def am_unscaled16 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled16", []>;
2929 def am_unscaled32 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled32", []>;
2930 def am_unscaled64 : ComplexPattern<i64, 2, "SelectAddrModeUnscaled64", []>;
2931 def am_unscaled128 :ComplexPattern<i64, 2, "SelectAddrModeUnscaled128", []>;
2932
2933 class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
2934                            string asm, list<dag> pattern>
2935     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {
2936   bits<5> Rt;
2937   bits<5> Rn;
2938   bits<9> offset;
2939   let Inst{31-30} = sz;
2940   let Inst{29-27} = 0b111;
2941   let Inst{26}    = V;
2942   let Inst{25-24} = 0b00;
2943   let Inst{23-22} = opc;
2944   let Inst{21}    = 0;
2945   let Inst{20-12} = offset;
2946   let Inst{11-10} = 0b00;
2947   let Inst{9-5}   = Rn;
2948   let Inst{4-0}   = Rt;
2949
2950   let DecoderMethod = "DecodeSignedLdStInstruction";
2951 }
2952
2953 multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2954                    string asm, list<dag> pattern> {
2955   let AddedComplexity = 1 in // try this before LoadUI
2956   def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),
2957                                (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,
2958           Sched<[WriteLD]>;
2959
2960   def : InstAlias<asm # "\t$Rt, [$Rn]",
2961                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
2962 }
2963
2964 multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
2965                          string asm, list<dag> pattern> {
2966   let AddedComplexity = 1 in // try this before StoreUI
2967   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
2968                                (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
2969                                asm, pattern>,
2970           Sched<[WriteST]>;
2971
2972   def : InstAlias<asm # "\t$Rt, [$Rn]",
2973                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
2974 }
2975
2976 multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,
2977                             list<dag> pat> {
2978   let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
2979   def i : BaseLoadStoreUnscale<sz, V, opc, (outs),
2980                                (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),
2981                                asm, pat>,
2982           Sched<[WriteLD]>;
2983
2984   def : InstAlias<asm # "\t$Rt, [$Rn]",
2985                   (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;
2986 }
2987
2988 //---
2989 // Load/store unscaled immediate, unprivileged
2990 //---
2991
2992 class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
2993                                 dag oops, dag iops, string asm>
2994     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {
2995   bits<5> Rt;
2996   bits<5> Rn;
2997   bits<9> offset;
2998   let Inst{31-30} = sz;
2999   let Inst{29-27} = 0b111;
3000   let Inst{26}    = V;
3001   let Inst{25-24} = 0b00;
3002   let Inst{23-22} = opc;
3003   let Inst{21}    = 0;
3004   let Inst{20-12} = offset;
3005   let Inst{11-10} = 0b10;
3006   let Inst{9-5}   = Rn;
3007   let Inst{4-0}   = Rt;
3008
3009   let DecoderMethod = "DecodeSignedLdStInstruction";
3010 }
3011
3012 multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,
3013                             RegisterClass regtype, string asm> {
3014   let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in
3015   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),
3016                                     (ins GPR64sp:$Rn, simm9:$offset), asm>,
3017           Sched<[WriteLD]>;
3018
3019   def : InstAlias<asm # "\t$Rt, [$Rn]",
3020                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3021 }
3022
3023 multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,
3024                              RegisterClass regtype, string asm> {
3025   let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in
3026   def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),
3027                                  (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3028                                  asm>,
3029           Sched<[WriteST]>;
3030
3031   def : InstAlias<asm # "\t$Rt, [$Rn]",
3032                   (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;
3033 }
3034
3035 //---
3036 // Load/store pre-indexed
3037 //---
3038
3039 class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3040                           string asm, string cstr, list<dag> pat>
3041     : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {
3042   bits<5> Rt;
3043   bits<5> Rn;
3044   bits<9> offset;
3045   let Inst{31-30} = sz;
3046   let Inst{29-27} = 0b111;
3047   let Inst{26}    = V;
3048   let Inst{25-24} = 0;
3049   let Inst{23-22} = opc;
3050   let Inst{21}    = 0;
3051   let Inst{20-12} = offset;
3052   let Inst{11-10} = 0b11;
3053   let Inst{9-5}   = Rn;
3054   let Inst{4-0}   = Rt;
3055
3056   let DecoderMethod = "DecodeSignedLdStInstruction";
3057 }
3058
3059 let hasSideEffects = 0 in {
3060 let mayStore = 0, mayLoad = 1 in
3061 class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3062              string asm>
3063     : BaseLoadStorePreIdx<sz, V, opc,
3064                      (outs GPR64sp:$wback, regtype:$Rt),
3065                      (ins GPR64sp:$Rn, simm9:$offset), asm,
3066                      "$Rn = $wback,@earlyclobber $wback", []>,
3067       Sched<[WriteLD, WriteAdr]>;
3068
3069 let mayStore = 1, mayLoad = 0 in
3070 class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3071                   string asm, SDPatternOperator storeop, ValueType Ty>
3072     : BaseLoadStorePreIdx<sz, V, opc,
3073                       (outs GPR64sp:$wback),
3074                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3075                       asm, "$Rn = $wback,@earlyclobber $wback",
3076       [(set GPR64sp:$wback,
3077             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3078       Sched<[WriteAdr, WriteST]>;
3079 } // hasSideEffects = 0
3080
3081 //---
3082 // Load/store post-indexed
3083 //---
3084
3085 class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,
3086                           string asm, string cstr, list<dag> pat>
3087     : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {
3088   bits<5> Rt;
3089   bits<5> Rn;
3090   bits<9> offset;
3091   let Inst{31-30} = sz;
3092   let Inst{29-27} = 0b111;
3093   let Inst{26}    = V;
3094   let Inst{25-24} = 0b00;
3095   let Inst{23-22} = opc;
3096   let Inst{21}    = 0b0;
3097   let Inst{20-12} = offset;
3098   let Inst{11-10} = 0b01;
3099   let Inst{9-5}   = Rn;
3100   let Inst{4-0}   = Rt;
3101
3102   let DecoderMethod = "DecodeSignedLdStInstruction";
3103 }
3104
3105 let hasSideEffects = 0 in {
3106 let mayStore = 0, mayLoad = 1 in
3107 class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3108              string asm>
3109     : BaseLoadStorePostIdx<sz, V, opc,
3110                       (outs GPR64sp:$wback, regtype:$Rt),
3111                       (ins GPR64sp:$Rn, simm9:$offset),
3112                       asm, "$Rn = $wback,@earlyclobber $wback", []>,
3113       Sched<[WriteLD, WriteI]>;
3114
3115 let mayStore = 1, mayLoad = 0 in
3116 class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterClass regtype,
3117                    string asm, SDPatternOperator storeop, ValueType Ty>
3118     : BaseLoadStorePostIdx<sz, V, opc,
3119                       (outs GPR64sp:$wback),
3120                       (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),
3121                        asm, "$Rn = $wback,@earlyclobber $wback",
3122       [(set GPR64sp:$wback,
3123             (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,
3124     Sched<[WriteAdr, WriteST, ReadAdrBase]>;
3125 } // hasSideEffects = 0
3126
3127
3128 //---
3129 // Load/store pair
3130 //---
3131
3132 // (indexed, offset)
3133
3134 class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,
3135                               string asm>
3136     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3137   bits<5> Rt;
3138   bits<5> Rt2;
3139   bits<5> Rn;
3140   bits<7> offset;
3141   let Inst{31-30} = opc;
3142   let Inst{29-27} = 0b101;
3143   let Inst{26}    = V;
3144   let Inst{25-23} = 0b010;
3145   let Inst{22}    = L;
3146   let Inst{21-15} = offset;
3147   let Inst{14-10} = Rt2;
3148   let Inst{9-5}   = Rn;
3149   let Inst{4-0}   = Rt;
3150
3151   let DecoderMethod = "DecodePairLdStInstruction";
3152 }
3153
3154 multiclass LoadPairOffset<bits<2> opc, bit V, RegisterClass regtype,
3155                           Operand indextype, string asm> {
3156   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3157   def i : BaseLoadStorePairOffset<opc, V, 1,
3158                                   (outs regtype:$Rt, regtype:$Rt2),
3159                                   (ins GPR64sp:$Rn, indextype:$offset), asm>,
3160           Sched<[WriteLD, WriteLDHi]>;
3161
3162   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3163                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3164                                                   GPR64sp:$Rn, 0)>;
3165 }
3166
3167
3168 multiclass StorePairOffset<bits<2> opc, bit V, RegisterClass regtype,
3169                            Operand indextype, string asm> {
3170   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in
3171   def i : BaseLoadStorePairOffset<opc, V, 0, (outs),
3172                                   (ins regtype:$Rt, regtype:$Rt2,
3173                                        GPR64sp:$Rn, indextype:$offset),
3174                                   asm>,
3175           Sched<[WriteSTP]>;
3176
3177   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3178                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3179                                                   GPR64sp:$Rn, 0)>;
3180 }
3181
3182 // (pre-indexed)
3183 class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3184                               string asm>
3185     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {
3186   bits<5> Rt;
3187   bits<5> Rt2;
3188   bits<5> Rn;
3189   bits<7> offset;
3190   let Inst{31-30} = opc;
3191   let Inst{29-27} = 0b101;
3192   let Inst{26}    = V;
3193   let Inst{25-23} = 0b011;
3194   let Inst{22}    = L;
3195   let Inst{21-15} = offset;
3196   let Inst{14-10} = Rt2;
3197   let Inst{9-5}   = Rn;
3198   let Inst{4-0}   = Rt;
3199
3200   let DecoderMethod = "DecodePairLdStInstruction";
3201 }
3202
3203 let hasSideEffects = 0 in {
3204 let mayStore = 0, mayLoad = 1 in
3205 class LoadPairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3206                      Operand indextype, string asm>
3207     : BaseLoadStorePairPreIdx<opc, V, 1,
3208                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3209                               (ins GPR64sp:$Rn, indextype:$offset), asm>,
3210       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3211
3212 let mayStore = 1, mayLoad = 0 in
3213 class StorePairPreIdx<bits<2> opc, bit V, RegisterClass regtype,
3214                       Operand indextype, string asm>
3215     : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),
3216                              (ins regtype:$Rt, regtype:$Rt2,
3217                                   GPR64sp:$Rn, indextype:$offset),
3218                              asm>,
3219       Sched<[WriteAdr, WriteSTP]>;
3220 } // hasSideEffects = 0
3221
3222 // (post-indexed)
3223
3224 class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,
3225                               string asm>
3226     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {
3227   bits<5> Rt;
3228   bits<5> Rt2;
3229   bits<5> Rn;
3230   bits<7> offset;
3231   let Inst{31-30} = opc;
3232   let Inst{29-27} = 0b101;
3233   let Inst{26}    = V;
3234   let Inst{25-23} = 0b001;
3235   let Inst{22}    = L;
3236   let Inst{21-15} = offset;
3237   let Inst{14-10} = Rt2;
3238   let Inst{9-5}   = Rn;
3239   let Inst{4-0}   = Rt;
3240
3241   let DecoderMethod = "DecodePairLdStInstruction";
3242 }
3243
3244 let hasSideEffects = 0 in {
3245 let mayStore = 0, mayLoad = 1 in
3246 class LoadPairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3247                       Operand idxtype, string asm>
3248     : BaseLoadStorePairPostIdx<opc, V, 1,
3249                               (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),
3250                               (ins GPR64sp:$Rn, idxtype:$offset), asm>,
3251       Sched<[WriteLD, WriteLDHi, WriteAdr]>;
3252
3253 let mayStore = 1, mayLoad = 0 in
3254 class StorePairPostIdx<bits<2> opc, bit V, RegisterClass regtype,
3255                        Operand idxtype, string asm>
3256     : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),
3257                              (ins regtype:$Rt, regtype:$Rt2,
3258                                   GPR64sp:$Rn, idxtype:$offset),
3259                              asm>,
3260       Sched<[WriteAdr, WriteSTP]>;
3261 } // hasSideEffects = 0
3262
3263 //  (no-allocate)
3264
3265 class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,
3266                               string asm>
3267     : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {
3268   bits<5> Rt;
3269   bits<5> Rt2;
3270   bits<5> Rn;
3271   bits<7> offset;
3272   let Inst{31-30} = opc;
3273   let Inst{29-27} = 0b101;
3274   let Inst{26}    = V;
3275   let Inst{25-23} = 0b000;
3276   let Inst{22}    = L;
3277   let Inst{21-15} = offset;
3278   let Inst{14-10} = Rt2;
3279   let Inst{9-5}   = Rn;
3280   let Inst{4-0}   = Rt;
3281
3282   let DecoderMethod = "DecodePairLdStInstruction";
3283 }
3284
3285 multiclass LoadPairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3286                            Operand indextype, string asm> {
3287   let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in
3288   def i : BaseLoadStorePairNoAlloc<opc, V, 1,
3289                                    (outs regtype:$Rt, regtype:$Rt2),
3290                                    (ins GPR64sp:$Rn, indextype:$offset), asm>,
3291           Sched<[WriteLD, WriteLDHi]>;
3292
3293
3294   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3295                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3296                                                   GPR64sp:$Rn, 0)>;
3297 }
3298
3299 multiclass StorePairNoAlloc<bits<2> opc, bit V, RegisterClass regtype,
3300                       Operand indextype, string asm> {
3301   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in
3302   def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),
3303                                    (ins regtype:$Rt, regtype:$Rt2,
3304                                         GPR64sp:$Rn, indextype:$offset),
3305                                    asm>,
3306           Sched<[WriteSTP]>;
3307
3308   def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",
3309                   (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,
3310                                                   GPR64sp:$Rn, 0)>;
3311 }
3312
3313 //---
3314 // Load/store exclusive
3315 //---
3316
3317 // True exclusive operations write to and/or read from the system's exclusive
3318 // monitors, which as far as a compiler is concerned can be modelled as a
3319 // random shared memory address. Hence LoadExclusive mayStore.
3320 //
3321 // Since these instructions have the undefined register bits set to 1 in
3322 // their canonical form, we need a post encoder method to set those bits
3323 // to 1 when encoding these instructions. We do this using the
3324 // fixLoadStoreExclusive function. This function has template parameters:
3325 //
3326 // fixLoadStoreExclusive<int hasRs, int hasRt2>
3327 //
3328 // hasRs indicates that the instruction uses the Rs field, so we won't set
3329 // it to 1 (and the same for Rt2). We don't need template parameters for
3330 // the other register fields since Rt and Rn are always used.
3331 //
3332 let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in
3333 class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3334                              dag oops, dag iops, string asm, string operands>
3335     : I<oops, iops, asm, operands, "", []> {
3336   let Inst{31-30} = sz;
3337   let Inst{29-24} = 0b001000;
3338   let Inst{23}    = o2;
3339   let Inst{22}    = L;
3340   let Inst{21}    = o1;
3341   let Inst{15}    = o0;
3342
3343   let DecoderMethod = "DecodeExclusiveLdStInstruction";
3344 }
3345
3346 // Neither Rs nor Rt2 operands.
3347 class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3348                                dag oops, dag iops, string asm, string operands>
3349     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {
3350   bits<5> Rt;
3351   bits<5> Rn;
3352   let Inst{20-16} = 0b11111;
3353   let Unpredictable{20-16} = 0b11111;
3354   let Inst{14-10} = 0b11111;
3355   let Unpredictable{14-10} = 0b11111;
3356   let Inst{9-5} = Rn;
3357   let Inst{4-0} = Rt;
3358
3359   let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";
3360 }
3361
3362 // Simple load acquires don't set the exclusive monitor
3363 let mayLoad = 1, mayStore = 0 in
3364 class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3365                   RegisterClass regtype, string asm>
3366     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3367                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3368       Sched<[WriteLD]>;
3369
3370 class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3371                     RegisterClass regtype, string asm>
3372     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),
3373                                (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,
3374       Sched<[WriteLD]>;
3375
3376 class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3377                        RegisterClass regtype, string asm>
3378     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3379                              (outs regtype:$Rt, regtype:$Rt2),
3380                              (ins GPR64sp0:$Rn), asm,
3381                              "\t$Rt, $Rt2, [$Rn]">,
3382       Sched<[WriteLD, WriteLDHi]> {
3383   bits<5> Rt;
3384   bits<5> Rt2;
3385   bits<5> Rn;
3386   let Inst{14-10} = Rt2;
3387   let Inst{9-5} = Rn;
3388   let Inst{4-0} = Rt;
3389
3390   let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";
3391 }
3392
3393 // Simple store release operations do not check the exclusive monitor.
3394 let mayLoad = 0, mayStore = 1 in
3395 class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3396                    RegisterClass regtype, string asm>
3397     : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),
3398                                (ins regtype:$Rt, GPR64sp0:$Rn),
3399                                asm, "\t$Rt, [$Rn]">,
3400       Sched<[WriteST]>;
3401
3402 let mayLoad = 1, mayStore = 1 in
3403 class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3404                      RegisterClass regtype, string asm>
3405     : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),
3406                              (ins regtype:$Rt, GPR64sp0:$Rn),
3407                              asm, "\t$Ws, $Rt, [$Rn]">,
3408       Sched<[WriteSTX]> {
3409   bits<5> Ws;
3410   bits<5> Rt;
3411   bits<5> Rn;
3412   let Inst{20-16} = Ws;
3413   let Inst{9-5} = Rn;
3414   let Inst{4-0} = Rt;
3415
3416   let Constraints = "@earlyclobber $Ws";
3417   let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";
3418 }
3419
3420 class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,
3421                          RegisterClass regtype, string asm>
3422     : BaseLoadStoreExclusive<sz, o2, L, o1, o0,
3423                              (outs GPR32:$Ws),
3424                              (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),
3425                               asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,
3426       Sched<[WriteSTX]> {
3427   bits<5> Ws;
3428   bits<5> Rt;
3429   bits<5> Rt2;
3430   bits<5> Rn;
3431   let Inst{20-16} = Ws;
3432   let Inst{14-10} = Rt2;
3433   let Inst{9-5} = Rn;
3434   let Inst{4-0} = Rt;
3435
3436   let Constraints = "@earlyclobber $Ws";
3437 }
3438
3439 //---
3440 // Exception generation
3441 //---
3442
3443 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in
3444 class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm>
3445     : I<(outs), (ins imm0_65535:$imm), asm, "\t$imm", "", []>,
3446       Sched<[WriteSys]> {
3447   bits<16> imm;
3448   let Inst{31-24} = 0b11010100;
3449   let Inst{23-21} = op1;
3450   let Inst{20-5}  = imm;
3451   let Inst{4-2}   = 0b000;
3452   let Inst{1-0}   = ll;
3453 }
3454
3455 let Predicates = [HasFPARMv8] in {
3456
3457 //---
3458 // Floating point to integer conversion
3459 //---
3460
3461 class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,
3462                       RegisterClass srcType, RegisterClass dstType,
3463                       string asm, list<dag> pattern>
3464     : I<(outs dstType:$Rd), (ins srcType:$Rn),
3465          asm, "\t$Rd, $Rn", "", pattern>,
3466       Sched<[WriteFCvt]> {
3467   bits<5> Rd;
3468   bits<5> Rn;
3469   let Inst{30-29} = 0b00;
3470   let Inst{28-24} = 0b11110;
3471   let Inst{23-22} = type;
3472   let Inst{21}    = 1;
3473   let Inst{20-19} = rmode;
3474   let Inst{18-16} = opcode;
3475   let Inst{15-10} = 0;
3476   let Inst{9-5}   = Rn;
3477   let Inst{4-0}   = Rd;
3478 }
3479
3480 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3481 class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,
3482                       RegisterClass srcType, RegisterClass dstType,
3483                       Operand immType, string asm, list<dag> pattern>
3484     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3485          asm, "\t$Rd, $Rn, $scale", "", pattern>,
3486       Sched<[WriteFCvt]> {
3487   bits<5> Rd;
3488   bits<5> Rn;
3489   bits<6> scale;
3490   let Inst{30-29} = 0b00;
3491   let Inst{28-24} = 0b11110;
3492   let Inst{23-22} = type;
3493   let Inst{21}    = 0;
3494   let Inst{20-19} = rmode;
3495   let Inst{18-16} = opcode;
3496   let Inst{15-10} = scale;
3497   let Inst{9-5}   = Rn;
3498   let Inst{4-0}   = Rd;
3499 }
3500
3501 multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,
3502            SDPatternOperator OpN> {
3503   // Unscaled single-precision to 32-bit
3504   def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,
3505                                      [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {
3506     let Inst{31} = 0; // 32-bit GPR flag
3507   }
3508
3509   // Unscaled single-precision to 64-bit
3510   def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,
3511                                      [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {
3512     let Inst{31} = 1; // 64-bit GPR flag
3513   }
3514
3515   // Unscaled double-precision to 32-bit
3516   def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,
3517                                      [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3518     let Inst{31} = 0; // 32-bit GPR flag
3519   }
3520
3521   // Unscaled double-precision to 64-bit
3522   def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,
3523                                      [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {
3524     let Inst{31} = 1; // 64-bit GPR flag
3525   }
3526 }
3527
3528 multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,
3529                              SDPatternOperator OpN> {
3530   // Scaled single-precision to 32-bit
3531   def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,
3532                               fixedpoint_f32_i32, asm,
3533               [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,
3534                                           fixedpoint_f32_i32:$scale)))]> {
3535     let Inst{31} = 0; // 32-bit GPR flag
3536     let scale{5} = 1;
3537   }
3538
3539   // Scaled single-precision to 64-bit
3540   def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,
3541                               fixedpoint_f32_i64, asm,
3542               [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,
3543                                           fixedpoint_f32_i64:$scale)))]> {
3544     let Inst{31} = 1; // 64-bit GPR flag
3545   }
3546
3547   // Scaled double-precision to 32-bit
3548   def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,
3549                               fixedpoint_f64_i32, asm,
3550               [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,
3551                                           fixedpoint_f64_i32:$scale)))]> {
3552     let Inst{31} = 0; // 32-bit GPR flag
3553     let scale{5} = 1;
3554   }
3555
3556   // Scaled double-precision to 64-bit
3557   def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,
3558                               fixedpoint_f64_i64, asm,
3559               [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,
3560                                           fixedpoint_f64_i64:$scale)))]> {
3561     let Inst{31} = 1; // 64-bit GPR flag
3562   }
3563 }
3564
3565 //---
3566 // Integer to floating point conversion
3567 //---
3568
3569 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
3570 class BaseIntegerToFP<bit isUnsigned,
3571                       RegisterClass srcType, RegisterClass dstType,
3572                       Operand immType, string asm, list<dag> pattern>
3573     : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),
3574          asm, "\t$Rd, $Rn, $scale", "", pattern>,
3575       Sched<[WriteFCvt]> {
3576   bits<5> Rd;
3577   bits<5> Rn;
3578   bits<6> scale;
3579   let Inst{30-23} = 0b00111100;
3580   let Inst{21-17} = 0b00001;
3581   let Inst{16}    = isUnsigned;
3582   let Inst{15-10} = scale;
3583   let Inst{9-5}   = Rn;
3584   let Inst{4-0}   = Rd;
3585 }
3586
3587 class BaseIntegerToFPUnscaled<bit isUnsigned,
3588                       RegisterClass srcType, RegisterClass dstType,
3589                       ValueType dvt, string asm, SDNode node>
3590     : I<(outs dstType:$Rd), (ins srcType:$Rn),
3591          asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,
3592       Sched<[WriteFCvt]> {
3593   bits<5> Rd;
3594   bits<5> Rn;
3595   bits<6> scale;
3596   let Inst{30-23} = 0b00111100;
3597   let Inst{21-17} = 0b10001;
3598   let Inst{16}    = isUnsigned;
3599   let Inst{15-10} = 0b000000;
3600   let Inst{9-5}   = Rn;
3601   let Inst{4-0}   = Rd;
3602 }
3603
3604 multiclass IntegerToFP<bit isUnsigned, string asm, SDNode node> {
3605   // Unscaled
3606   def UWSri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR32, f32, asm, node> {
3607     let Inst{31} = 0; // 32-bit GPR flag
3608     let Inst{22} = 0; // 32-bit FPR flag
3609   }
3610
3611   def UWDri: BaseIntegerToFPUnscaled<isUnsigned, GPR32, FPR64, f64, asm, node> {
3612     let Inst{31} = 0; // 32-bit GPR flag
3613     let Inst{22} = 1; // 64-bit FPR flag
3614   }
3615
3616   def UXSri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR32, f32, asm, node> {
3617     let Inst{31} = 1; // 64-bit GPR flag
3618     let Inst{22} = 0; // 32-bit FPR flag
3619   }
3620
3621   def UXDri: BaseIntegerToFPUnscaled<isUnsigned, GPR64, FPR64, f64, asm, node> {
3622     let Inst{31} = 1; // 64-bit GPR flag
3623     let Inst{22} = 1; // 64-bit FPR flag
3624   }
3625
3626   // Scaled
3627   def SWSri: BaseIntegerToFP<isUnsigned, GPR32, FPR32, fixedpoint_f32_i32, asm,
3628                              [(set FPR32:$Rd,
3629                                    (fdiv (node GPR32:$Rn),
3630                                          fixedpoint_f32_i32:$scale))]> {
3631     let Inst{31} = 0; // 32-bit GPR flag
3632     let Inst{22} = 0; // 32-bit FPR flag
3633     let scale{5} = 1;
3634   }
3635
3636   def SWDri: BaseIntegerToFP<isUnsigned, GPR32, FPR64, fixedpoint_f64_i32, asm,
3637                              [(set FPR64:$Rd,
3638                                    (fdiv (node GPR32:$Rn),
3639                                          fixedpoint_f64_i32:$scale))]> {
3640     let Inst{31} = 0; // 32-bit GPR flag
3641     let Inst{22} = 1; // 64-bit FPR flag
3642     let scale{5} = 1;
3643   }
3644
3645   def SXSri: BaseIntegerToFP<isUnsigned, GPR64, FPR32, fixedpoint_f32_i64, asm,
3646                              [(set FPR32:$Rd,
3647                                    (fdiv (node GPR64:$Rn),
3648                                          fixedpoint_f32_i64:$scale))]> {
3649     let Inst{31} = 1; // 64-bit GPR flag
3650     let Inst{22} = 0; // 32-bit FPR flag
3651   }
3652
3653   def SXDri: BaseIntegerToFP<isUnsigned, GPR64, FPR64, fixedpoint_f64_i64, asm,
3654                              [(set FPR64:$Rd,
3655                                    (fdiv (node GPR64:$Rn),
3656                                          fixedpoint_f64_i64:$scale))]> {
3657     let Inst{31} = 1; // 64-bit GPR flag
3658     let Inst{22} = 1; // 64-bit FPR flag
3659   }
3660 }
3661
3662 //---
3663 // Unscaled integer <-> floating point conversion (i.e. FMOV)
3664 //---
3665
3666 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3667 class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,
3668                       RegisterClass srcType, RegisterClass dstType,
3669                       string asm>
3670     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",
3671         // We use COPY_TO_REGCLASS for these bitconvert operations.
3672         // copyPhysReg() expands the resultant COPY instructions after
3673         // regalloc is done. This gives greater freedom for the allocator
3674         // and related passes (coalescing, copy propagation, et. al.) to
3675         // be more effective.
3676         [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,
3677       Sched<[WriteFCopy]> {
3678   bits<5> Rd;
3679   bits<5> Rn;
3680   let Inst{30-23} = 0b00111100;
3681   let Inst{21}    = 1;
3682   let Inst{20-19} = rmode;
3683   let Inst{18-16} = opcode;
3684   let Inst{15-10} = 0b000000;
3685   let Inst{9-5}   = Rn;
3686   let Inst{4-0}   = Rd;
3687 }
3688
3689 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3690 class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,
3691                      RegisterClass srcType, RegisterOperand dstType, string asm,
3692                      string kind>
3693     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3694         "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,
3695       Sched<[WriteFCopy]> {
3696   bits<5> Rd;
3697   bits<5> Rn;
3698   let Inst{30-23} = 0b00111101;
3699   let Inst{21}    = 1;
3700   let Inst{20-19} = rmode;
3701   let Inst{18-16} = opcode;
3702   let Inst{15-10} = 0b000000;
3703   let Inst{9-5}   = Rn;
3704   let Inst{4-0}   = Rd;
3705
3706   let DecoderMethod =  "DecodeFMOVLaneInstruction";
3707 }
3708
3709 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3710 class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,
3711                      RegisterOperand srcType, RegisterClass dstType, string asm,
3712                      string kind>
3713     : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,
3714         "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,
3715       Sched<[WriteFCopy]> {
3716   bits<5> Rd;
3717   bits<5> Rn;
3718   let Inst{30-23} = 0b00111101;
3719   let Inst{21}    = 1;
3720   let Inst{20-19} = rmode;
3721   let Inst{18-16} = opcode;
3722   let Inst{15-10} = 0b000000;
3723   let Inst{9-5}   = Rn;
3724   let Inst{4-0}   = Rd;
3725
3726   let DecoderMethod =  "DecodeFMOVLaneInstruction";
3727 }
3728
3729
3730
3731 multiclass UnscaledConversion<string asm> {
3732   def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {
3733     let Inst{31} = 0; // 32-bit GPR flag
3734     let Inst{22} = 0; // 32-bit FPR flag
3735   }
3736
3737   def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {
3738     let Inst{31} = 1; // 64-bit GPR flag
3739     let Inst{22} = 1; // 64-bit FPR flag
3740   }
3741
3742   def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {
3743     let Inst{31} = 0; // 32-bit GPR flag
3744     let Inst{22} = 0; // 32-bit FPR flag
3745   }
3746
3747   def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {
3748     let Inst{31} = 1; // 64-bit GPR flag
3749     let Inst{22} = 1; // 64-bit FPR flag
3750   }
3751
3752   def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,
3753                                              asm, ".d"> {
3754     let Inst{31} = 1;
3755     let Inst{22} = 0;
3756   }
3757
3758   def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,
3759                                                asm, ".d"> {
3760     let Inst{31} = 1;
3761     let Inst{22} = 0;
3762   }
3763 }
3764
3765 //---
3766 // Floating point conversion
3767 //---
3768
3769 class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,
3770                        RegisterClass srcType, string asm, list<dag> pattern>
3771     : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,
3772       Sched<[WriteFCvt]> {
3773   bits<5> Rd;
3774   bits<5> Rn;
3775   let Inst{31-24} = 0b00011110;
3776   let Inst{23-22} = type;
3777   let Inst{21-17} = 0b10001;
3778   let Inst{16-15} = opcode;
3779   let Inst{14-10} = 0b10000;
3780   let Inst{9-5}   = Rn;
3781   let Inst{4-0}   = Rd;
3782 }
3783
3784 multiclass FPConversion<string asm> {
3785   // Double-precision to Half-precision
3786   def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,
3787                              [(set FPR16:$Rd, (fround FPR64:$Rn))]>;
3788
3789   // Double-precision to Single-precision
3790   def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,
3791                              [(set FPR32:$Rd, (fround FPR64:$Rn))]>;
3792
3793   // Half-precision to Double-precision
3794   def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,
3795                              [(set FPR64:$Rd, (fextend FPR16:$Rn))]>;
3796
3797   // Half-precision to Single-precision
3798   def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,
3799                              [(set FPR32:$Rd, (fextend FPR16:$Rn))]>;
3800
3801   // Single-precision to Double-precision
3802   def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,
3803                              [(set FPR64:$Rd, (fextend FPR32:$Rn))]>;
3804
3805   // Single-precision to Half-precision
3806   def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,
3807                              [(set FPR16:$Rd, (fround FPR32:$Rn))]>;
3808 }
3809
3810 //---
3811 // Single operand floating point data processing
3812 //---
3813
3814 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3815 class BaseSingleOperandFPData<bits<4> opcode, RegisterClass regtype,
3816                               ValueType vt, string asm, SDPatternOperator node>
3817     : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",
3818          [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,
3819       Sched<[WriteF]> {
3820   bits<5> Rd;
3821   bits<5> Rn;
3822   let Inst{31-23} = 0b000111100;
3823   let Inst{21-19} = 0b100;
3824   let Inst{18-15} = opcode;
3825   let Inst{14-10} = 0b10000;
3826   let Inst{9-5}   = Rn;
3827   let Inst{4-0}   = Rd;
3828 }
3829
3830 multiclass SingleOperandFPData<bits<4> opcode, string asm,
3831                                SDPatternOperator node = null_frag> {
3832   def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {
3833     let Inst{22} = 0; // 32-bit size flag
3834   }
3835
3836   def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {
3837     let Inst{22} = 1; // 64-bit size flag
3838   }
3839 }
3840
3841 //---
3842 // Two operand floating point data processing
3843 //---
3844
3845 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3846 class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,
3847                            string asm, list<dag> pat>
3848     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),
3849          asm, "\t$Rd, $Rn, $Rm", "", pat>,
3850       Sched<[WriteF]> {
3851   bits<5> Rd;
3852   bits<5> Rn;
3853   bits<5> Rm;
3854   let Inst{31-23} = 0b000111100;
3855   let Inst{21}    = 1;
3856   let Inst{20-16} = Rm;
3857   let Inst{15-12} = opcode;
3858   let Inst{11-10} = 0b10;
3859   let Inst{9-5}   = Rn;
3860   let Inst{4-0}   = Rd;
3861 }
3862
3863 multiclass TwoOperandFPData<bits<4> opcode, string asm,
3864                             SDPatternOperator node = null_frag> {
3865   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3866                          [(set (f32 FPR32:$Rd),
3867                                (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {
3868     let Inst{22} = 0; // 32-bit size flag
3869   }
3870
3871   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3872                          [(set (f64 FPR64:$Rd),
3873                                (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {
3874     let Inst{22} = 1; // 64-bit size flag
3875   }
3876 }
3877
3878 multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm, SDNode node> {
3879   def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,
3880                   [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {
3881     let Inst{22} = 0; // 32-bit size flag
3882   }
3883
3884   def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,
3885                   [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {
3886     let Inst{22} = 1; // 64-bit size flag
3887   }
3888 }
3889
3890
3891 //---
3892 // Three operand floating point data processing
3893 //---
3894
3895 class BaseThreeOperandFPData<bit isNegated, bit isSub,
3896                              RegisterClass regtype, string asm, list<dag> pat>
3897     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),
3898          asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,
3899       Sched<[WriteFMul]> {
3900   bits<5> Rd;
3901   bits<5> Rn;
3902   bits<5> Rm;
3903   bits<5> Ra;
3904   let Inst{31-23} = 0b000111110;
3905   let Inst{21}    = isNegated;
3906   let Inst{20-16} = Rm;
3907   let Inst{15}    = isSub;
3908   let Inst{14-10} = Ra;
3909   let Inst{9-5}   = Rn;
3910   let Inst{4-0}   = Rd;
3911 }
3912
3913 multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,
3914                               SDPatternOperator node> {
3915   def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,
3916             [(set FPR32:$Rd,
3917                   (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {
3918     let Inst{22} = 0; // 32-bit size flag
3919   }
3920
3921   def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,
3922             [(set FPR64:$Rd,
3923                   (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {
3924     let Inst{22} = 1; // 64-bit size flag
3925   }
3926 }
3927
3928 //---
3929 // Floating point data comparisons
3930 //---
3931
3932 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3933 class BaseOneOperandFPComparison<bit signalAllNans,
3934                                  RegisterClass regtype, string asm,
3935                                  list<dag> pat>
3936     : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,
3937       Sched<[WriteFCmp]> {
3938   bits<5> Rn;
3939   let Inst{31-23} = 0b000111100;
3940   let Inst{21}    = 1;
3941
3942   let Inst{15-10} = 0b001000;
3943   let Inst{9-5}   = Rn;
3944   let Inst{4}     = signalAllNans;
3945   let Inst{3-0}   = 0b1000;
3946
3947   // Rm should be 0b00000 canonically, but we need to accept any value.
3948   let PostEncoderMethod = "fixOneOperandFPComparison";
3949 }
3950
3951 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3952 class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,
3953                                 string asm, list<dag> pat>
3954     : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,
3955       Sched<[WriteFCmp]> {
3956   bits<5> Rm;
3957   bits<5> Rn;
3958   let Inst{31-23} = 0b000111100;
3959   let Inst{21}    = 1;
3960   let Inst{20-16} = Rm;
3961   let Inst{15-10} = 0b001000;
3962   let Inst{9-5}   = Rn;
3963   let Inst{4}     = signalAllNans;
3964   let Inst{3-0}   = 0b0000;
3965 }
3966
3967 multiclass FPComparison<bit signalAllNans, string asm,
3968                         SDPatternOperator OpNode = null_frag> {
3969   let Defs = [NZCV] in {
3970   def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,
3971       [(OpNode FPR32:$Rn, (f32 FPR32:$Rm)), (implicit NZCV)]> {
3972     let Inst{22} = 0;
3973   }
3974
3975   def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,
3976       [(OpNode (f32 FPR32:$Rn), fpimm0), (implicit NZCV)]> {
3977     let Inst{22} = 0;
3978   }
3979
3980   def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,
3981       [(OpNode FPR64:$Rn, (f64 FPR64:$Rm)), (implicit NZCV)]> {
3982     let Inst{22} = 1;
3983   }
3984
3985   def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,
3986       [(OpNode (f64 FPR64:$Rn), fpimm0), (implicit NZCV)]> {
3987     let Inst{22} = 1;
3988   }
3989   } // Defs = [NZCV]
3990 }
3991
3992 //---
3993 // Floating point conditional comparisons
3994 //---
3995
3996 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
3997 class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,
3998                            string mnemonic, list<dag> pat>
3999     : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),
4000          mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,
4001       Sched<[WriteFCmp]> {
4002   let Uses = [NZCV];
4003   let Defs = [NZCV];
4004
4005   bits<5> Rn;
4006   bits<5> Rm;
4007   bits<4> nzcv;
4008   bits<4> cond;
4009
4010   let Inst{31-23} = 0b000111100;
4011   let Inst{21}    = 1;
4012   let Inst{20-16} = Rm;
4013   let Inst{15-12} = cond;
4014   let Inst{11-10} = 0b01;
4015   let Inst{9-5}   = Rn;
4016   let Inst{4}     = signalAllNans;
4017   let Inst{3-0}   = nzcv;
4018 }
4019
4020 multiclass FPCondComparison<bit signalAllNans, string mnemonic,
4021                             SDPatternOperator OpNode = null_frag> {
4022   def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,
4023       [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),
4024                           (i32 imm:$cond), NZCV))]> {
4025     let Inst{22} = 0;
4026   }
4027   def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,
4028       [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),
4029                           (i32 imm:$cond), NZCV))]> {
4030     let Inst{22} = 1;
4031   }
4032 }
4033
4034 //---
4035 // Floating point conditional select
4036 //---
4037
4038 class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>
4039     : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),
4040          asm, "\t$Rd, $Rn, $Rm, $cond", "",
4041          [(set regtype:$Rd,
4042                (AArch64csel (vt regtype:$Rn), regtype:$Rm,
4043                           (i32 imm:$cond), NZCV))]>,
4044       Sched<[WriteF]> {
4045   bits<5> Rd;
4046   bits<5> Rn;
4047   bits<5> Rm;
4048   bits<4> cond;
4049
4050   let Inst{31-23} = 0b000111100;
4051   let Inst{21}    = 1;
4052   let Inst{20-16} = Rm;
4053   let Inst{15-12} = cond;
4054   let Inst{11-10} = 0b11;
4055   let Inst{9-5}   = Rn;
4056   let Inst{4-0}   = Rd;
4057 }
4058
4059 multiclass FPCondSelect<string asm> {
4060   let Uses = [NZCV] in {
4061   def Srrr : BaseFPCondSelect<FPR32, f32, asm> {
4062     let Inst{22} = 0;
4063   }
4064
4065   def Drrr : BaseFPCondSelect<FPR64, f64, asm> {
4066     let Inst{22} = 1;
4067   }
4068   } // Uses = [NZCV]
4069 }
4070
4071 //---
4072 // Floating move immediate
4073 //---
4074
4075 class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>
4076   : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",
4077       [(set regtype:$Rd, fpimmtype:$imm)]>,
4078     Sched<[WriteFImm]> {
4079   bits<5> Rd;
4080   bits<8> imm;
4081   let Inst{31-23} = 0b000111100;
4082   let Inst{21}    = 1;
4083   let Inst{20-13} = imm;
4084   let Inst{12-5}  = 0b10000000;
4085   let Inst{4-0}   = Rd;
4086 }
4087
4088 multiclass FPMoveImmediate<string asm> {
4089   def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {
4090     let Inst{22} = 0;
4091   }
4092
4093   def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {
4094     let Inst{22} = 1;
4095   }
4096 }
4097 } // end of 'let Predicates = [HasFPARMv8]'
4098
4099 //----------------------------------------------------------------------------
4100 // AdvSIMD
4101 //----------------------------------------------------------------------------
4102
4103 let Predicates = [HasNEON] in {
4104
4105 //----------------------------------------------------------------------------
4106 // AdvSIMD three register vector instructions
4107 //----------------------------------------------------------------------------
4108
4109 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4110 class BaseSIMDThreeSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4111                         RegisterOperand regtype, string asm, string kind,
4112                         list<dag> pattern>
4113   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
4114       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4115       "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,
4116     Sched<[WriteV]> {
4117   bits<5> Rd;
4118   bits<5> Rn;
4119   bits<5> Rm;
4120   let Inst{31}    = 0;
4121   let Inst{30}    = Q;
4122   let Inst{29}    = U;
4123   let Inst{28-24} = 0b01110;
4124   let Inst{23-22} = size;
4125   let Inst{21}    = 1;
4126   let Inst{20-16} = Rm;
4127   let Inst{15-11} = opcode;
4128   let Inst{10}    = 1;
4129   let Inst{9-5}   = Rn;
4130   let Inst{4-0}   = Rd;
4131 }
4132
4133 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4134 class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4135                         RegisterOperand regtype, string asm, string kind,
4136                         list<dag> pattern>
4137   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,
4138       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
4139       "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4140     Sched<[WriteV]> {
4141   bits<5> Rd;
4142   bits<5> Rn;
4143   bits<5> Rm;
4144   let Inst{31}    = 0;
4145   let Inst{30}    = Q;
4146   let Inst{29}    = U;
4147   let Inst{28-24} = 0b01110;
4148   let Inst{23-22} = size;
4149   let Inst{21}    = 1;
4150   let Inst{20-16} = Rm;
4151   let Inst{15-11} = opcode;
4152   let Inst{10}    = 1;
4153   let Inst{9-5}   = Rn;
4154   let Inst{4-0}   = Rd;
4155 }
4156
4157 // All operand sizes distinguished in the encoding.
4158 multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,
4159                                SDPatternOperator OpNode> {
4160   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4161                                       asm, ".8b",
4162          [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4163   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4164                                       asm, ".16b",
4165          [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4166   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4167                                       asm, ".4h",
4168          [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4169   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4170                                       asm, ".8h",
4171          [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4172   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4173                                       asm, ".2s",
4174          [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4175   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4176                                       asm, ".4s",
4177          [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4178   def v2i64 : BaseSIMDThreeSameVector<1, U, 0b11, opc, V128,
4179                                       asm, ".2d",
4180          [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4181 }
4182
4183 // As above, but D sized elements unsupported.
4184 multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,
4185                                   SDPatternOperator OpNode> {
4186   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4187                                       asm, ".8b",
4188         [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;
4189   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4190                                       asm, ".16b",
4191         [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;
4192   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4193                                       asm, ".4h",
4194         [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;
4195   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4196                                       asm, ".8h",
4197         [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;
4198   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4199                                       asm, ".2s",
4200         [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;
4201   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4202                                       asm, ".4s",
4203         [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;
4204 }
4205
4206 multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,
4207                                   SDPatternOperator OpNode> {
4208   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, 0b00, opc, V64,
4209                                       asm, ".8b",
4210       [(set (v8i8 V64:$dst),
4211             (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4212   def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b00, opc, V128,
4213                                       asm, ".16b",
4214       [(set (v16i8 V128:$dst),
4215             (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4216   def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b01, opc, V64,
4217                                       asm, ".4h",
4218       [(set (v4i16 V64:$dst),
4219             (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4220   def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b01, opc, V128,
4221                                       asm, ".8h",
4222       [(set (v8i16 V128:$dst),
4223             (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4224   def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b10, opc, V64,
4225                                       asm, ".2s",
4226       [(set (v2i32 V64:$dst),
4227             (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4228   def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b10, opc, V128,
4229                                       asm, ".4s",
4230       [(set (v4i32 V128:$dst),
4231             (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4232 }
4233
4234 // As above, but only B sized elements supported.
4235 multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,
4236                                 SDPatternOperator OpNode> {
4237   def v8i8  : BaseSIMDThreeSameVector<0, U, 0b00, opc, V64,
4238                                       asm, ".8b",
4239     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4240   def v16i8 : BaseSIMDThreeSameVector<1, U, 0b00, opc, V128,
4241                                       asm, ".16b",
4242     [(set (v16i8 V128:$Rd),
4243           (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;
4244 }
4245
4246 // As above, but only S and D sized floating point elements supported.
4247 multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<5> opc,
4248                                  string asm, SDPatternOperator OpNode> {
4249   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
4250                                       asm, ".2s",
4251         [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4252   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
4253                                       asm, ".4s",
4254         [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4255   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
4256                                       asm, ".2d",
4257         [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4258 }
4259
4260 multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<5> opc,
4261                                     string asm,
4262                                     SDPatternOperator OpNode> {
4263   def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0}, opc, V64,
4264                                       asm, ".2s",
4265         [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4266   def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0}, opc, V128,
4267                                       asm, ".4s",
4268         [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4269   def v2f64 : BaseSIMDThreeSameVector<1, U, {S,1}, opc, V128,
4270                                       asm, ".2d",
4271         [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4272 }
4273
4274 multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<5> opc,
4275                                  string asm, SDPatternOperator OpNode> {
4276   def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0}, opc, V64,
4277                                       asm, ".2s",
4278      [(set (v2f32 V64:$dst),
4279            (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;
4280   def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0}, opc, V128,
4281                                       asm, ".4s",
4282      [(set (v4f32 V128:$dst),
4283            (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;
4284   def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,1}, opc, V128,
4285                                       asm, ".2d",
4286      [(set (v2f64 V128:$dst),
4287            (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;
4288 }
4289
4290 // As above, but D and B sized elements unsupported.
4291 multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,
4292                                 SDPatternOperator OpNode> {
4293   def v4i16 : BaseSIMDThreeSameVector<0, U, 0b01, opc, V64,
4294                                       asm, ".4h",
4295         [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
4296   def v8i16 : BaseSIMDThreeSameVector<1, U, 0b01, opc, V128,
4297                                       asm, ".8h",
4298         [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4299   def v2i32 : BaseSIMDThreeSameVector<0, U, 0b10, opc, V64,
4300                                       asm, ".2s",
4301         [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
4302   def v4i32 : BaseSIMDThreeSameVector<1, U, 0b10, opc, V128,
4303                                       asm, ".4s",
4304         [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4305 }
4306
4307 // Logical three vector ops share opcode bits, and only use B sized elements.
4308 multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,
4309                                   SDPatternOperator OpNode = null_frag> {
4310   def v8i8  : BaseSIMDThreeSameVector<0, U, size, 0b00011, V64,
4311                                      asm, ".8b",
4312                          [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;
4313   def v16i8  : BaseSIMDThreeSameVector<1, U, size, 0b00011, V128,
4314                                      asm, ".16b",
4315                          [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;
4316
4317   def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),
4318           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4319   def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),
4320           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4321   def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),
4322           (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;
4323
4324   def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),
4325       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4326   def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),
4327       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4328   def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),
4329       (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;
4330 }
4331
4332 multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,
4333                                   string asm, SDPatternOperator OpNode> {
4334   def v8i8  : BaseSIMDThreeSameVectorTied<0, U, size, 0b00011, V64,
4335                                      asm, ".8b",
4336              [(set (v8i8 V64:$dst),
4337                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
4338   def v16i8  : BaseSIMDThreeSameVectorTied<1, U, size, 0b00011, V128,
4339                                      asm, ".16b",
4340              [(set (v16i8 V128:$dst),
4341                    (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
4342                            (v16i8 V128:$Rm)))]>;
4343
4344   def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),
4345                            (v4i16 V64:$RHS))),
4346           (!cast<Instruction>(NAME#"v8i8")
4347             V64:$LHS, V64:$MHS, V64:$RHS)>;
4348   def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),
4349                            (v2i32 V64:$RHS))),
4350           (!cast<Instruction>(NAME#"v8i8")
4351             V64:$LHS, V64:$MHS, V64:$RHS)>;
4352   def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),
4353                            (v1i64 V64:$RHS))),
4354           (!cast<Instruction>(NAME#"v8i8")
4355             V64:$LHS, V64:$MHS, V64:$RHS)>;
4356
4357   def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),
4358                            (v8i16 V128:$RHS))),
4359       (!cast<Instruction>(NAME#"v16i8")
4360         V128:$LHS, V128:$MHS, V128:$RHS)>;
4361   def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),
4362                            (v4i32 V128:$RHS))),
4363       (!cast<Instruction>(NAME#"v16i8")
4364         V128:$LHS, V128:$MHS, V128:$RHS)>;
4365   def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),
4366                            (v2i64 V128:$RHS))),
4367       (!cast<Instruction>(NAME#"v16i8")
4368         V128:$LHS, V128:$MHS, V128:$RHS)>;
4369 }
4370
4371
4372 //----------------------------------------------------------------------------
4373 // AdvSIMD two register vector instructions.
4374 //----------------------------------------------------------------------------
4375
4376 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4377 class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4378                         RegisterOperand regtype, string asm, string dstkind,
4379                         string srckind, list<dag> pattern>
4380   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4381       "{\t$Rd" # dstkind # ", $Rn" # srckind #
4382       "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,
4383     Sched<[WriteV]> {
4384   bits<5> Rd;
4385   bits<5> Rn;
4386   let Inst{31}    = 0;
4387   let Inst{30}    = Q;
4388   let Inst{29}    = U;
4389   let Inst{28-24} = 0b01110;
4390   let Inst{23-22} = size;
4391   let Inst{21-17} = 0b10000;
4392   let Inst{16-12} = opcode;
4393   let Inst{11-10} = 0b10;
4394   let Inst{9-5}   = Rn;
4395   let Inst{4-0}   = Rd;
4396 }
4397
4398 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4399 class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4400                             RegisterOperand regtype, string asm, string dstkind,
4401                             string srckind, list<dag> pattern>
4402   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,
4403       "{\t$Rd" # dstkind # ", $Rn" # srckind #
4404       "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4405     Sched<[WriteV]> {
4406   bits<5> Rd;
4407   bits<5> Rn;
4408   let Inst{31}    = 0;
4409   let Inst{30}    = Q;
4410   let Inst{29}    = U;
4411   let Inst{28-24} = 0b01110;
4412   let Inst{23-22} = size;
4413   let Inst{21-17} = 0b10000;
4414   let Inst{16-12} = opcode;
4415   let Inst{11-10} = 0b10;
4416   let Inst{9-5}   = Rn;
4417   let Inst{4-0}   = Rd;
4418 }
4419
4420 // Supports B, H, and S element sizes.
4421 multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,
4422                             SDPatternOperator OpNode> {
4423   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4424                                       asm, ".8b", ".8b",
4425                           [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4426   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4427                                       asm, ".16b", ".16b",
4428                           [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4429   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4430                                       asm, ".4h", ".4h",
4431                           [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4432   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4433                                       asm, ".8h", ".8h",
4434                           [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4435   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4436                                       asm, ".2s", ".2s",
4437                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4438   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4439                                       asm, ".4s", ".4s",
4440                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4441 }
4442
4443 class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,
4444                             RegisterOperand regtype, string asm, string dstkind,
4445                             string srckind, string amount>
4446   : I<(outs V128:$Rd), (ins regtype:$Rn), asm,
4447       "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #
4448       "|" # dstkind # "\t$Rd, $Rn, #" #  amount # "}", "", []>,
4449     Sched<[WriteV]> {
4450   bits<5> Rd;
4451   bits<5> Rn;
4452   let Inst{31}    = 0;
4453   let Inst{30}    = Q;
4454   let Inst{29-24} = 0b101110;
4455   let Inst{23-22} = size;
4456   let Inst{21-10} = 0b100001001110;
4457   let Inst{9-5}   = Rn;
4458   let Inst{4-0}   = Rd;
4459 }
4460
4461 multiclass SIMDVectorLShiftLongBySizeBHS {
4462   let hasSideEffects = 0 in {
4463   def v8i8  : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,
4464                                              "shll", ".8h",  ".8b", "8">;
4465   def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,
4466                                              "shll2", ".8h", ".16b", "8">;
4467   def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,
4468                                              "shll", ".4s",  ".4h", "16">;
4469   def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,
4470                                              "shll2", ".4s", ".8h", "16">;
4471   def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,
4472                                              "shll", ".2d",  ".2s", "32">;
4473   def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,
4474                                              "shll2", ".2d", ".4s", "32">;
4475   }
4476 }
4477
4478 // Supports all element sizes.
4479 multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,
4480                              SDPatternOperator OpNode> {
4481   def v8i8_v4i16  : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4482                                       asm, ".4h", ".8b",
4483                [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4484   def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4485                                       asm, ".8h", ".16b",
4486                [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4487   def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4488                                       asm, ".2s", ".4h",
4489                [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4490   def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4491                                       asm, ".4s", ".8h",
4492                [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4493   def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4494                                       asm, ".1d", ".2s",
4495                [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4496   def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4497                                       asm, ".2d", ".4s",
4498                [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4499 }
4500
4501 multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,
4502                                  SDPatternOperator OpNode> {
4503   def v8i8_v4i16  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4504                                           asm, ".4h", ".8b",
4505       [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),
4506                                       (v8i8 V64:$Rn)))]>;
4507   def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4508                                           asm, ".8h", ".16b",
4509       [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),
4510                                       (v16i8 V128:$Rn)))]>;
4511   def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4512                                           asm, ".2s", ".4h",
4513       [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),
4514                                       (v4i16 V64:$Rn)))]>;
4515   def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4516                                           asm, ".4s", ".8h",
4517       [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),
4518                                       (v8i16 V128:$Rn)))]>;
4519   def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4520                                           asm, ".1d", ".2s",
4521       [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),
4522                                       (v2i32 V64:$Rn)))]>;
4523   def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4524                                           asm, ".2d", ".4s",
4525       [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),
4526                                       (v4i32 V128:$Rn)))]>;
4527 }
4528
4529 // Supports all element sizes, except 1xD.
4530 multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,
4531                                   SDPatternOperator OpNode> {
4532   def v8i8  : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, V64,
4533                                     asm, ".8b", ".8b",
4534     [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;
4535   def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, V128,
4536                                     asm, ".16b", ".16b",
4537     [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
4538   def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, V64,
4539                                     asm, ".4h", ".4h",
4540     [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;
4541   def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, V128,
4542                                     asm, ".8h", ".8h",
4543     [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;
4544   def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, V64,
4545                                     asm, ".2s", ".2s",
4546     [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;
4547   def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, V128,
4548                                     asm, ".4s", ".4s",
4549     [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
4550   def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, V128,
4551                                     asm, ".2d", ".2d",
4552     [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;
4553 }
4554
4555 multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,
4556                              SDPatternOperator OpNode = null_frag> {
4557   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4558                                 asm, ".8b", ".8b",
4559     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4560   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4561                                 asm, ".16b", ".16b",
4562     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4563   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4564                                 asm, ".4h", ".4h",
4565     [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;
4566   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4567                                 asm, ".8h", ".8h",
4568     [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4569   def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, V64,
4570                                 asm, ".2s", ".2s",
4571     [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4572   def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, V128,
4573                                 asm, ".4s", ".4s",
4574     [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4575   def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, V128,
4576                                 asm, ".2d", ".2d",
4577     [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4578 }
4579
4580
4581 // Supports only B element sizes.
4582 multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,
4583                           SDPatternOperator OpNode> {
4584   def v8i8  : BaseSIMDTwoSameVector<0, U, size, opc, V64,
4585                                 asm, ".8b", ".8b",
4586                     [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;
4587   def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, V128,
4588                                 asm, ".16b", ".16b",
4589                     [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
4590
4591 }
4592
4593 // Supports only B and H element sizes.
4594 multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,
4595                                 SDPatternOperator OpNode> {
4596   def v8i8  : BaseSIMDTwoSameVector<0, U, 0b00, opc, V64,
4597                                 asm, ".8b", ".8b",
4598                     [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;
4599   def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, V128,
4600                                 asm, ".16b", ".16b",
4601                     [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;
4602   def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, V64,
4603                                 asm, ".4h", ".4h",
4604                     [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;
4605   def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, V128,
4606                                 asm, ".8h", ".8h",
4607                     [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;
4608 }
4609
4610 // Supports only S and D element sizes, uses high bit of the size field
4611 // as an extra opcode bit.
4612 multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,
4613                            SDPatternOperator OpNode> {
4614   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4615                                 asm, ".2s", ".2s",
4616                           [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4617   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4618                                 asm, ".4s", ".4s",
4619                           [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4620   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4621                                 asm, ".2d", ".2d",
4622                           [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4623 }
4624
4625 // Supports only S element size.
4626 multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,
4627                            SDPatternOperator OpNode> {
4628   def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4629                                 asm, ".2s", ".2s",
4630                           [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4631   def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4632                                 asm, ".4s", ".4s",
4633                           [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4634 }
4635
4636
4637 multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,
4638                            SDPatternOperator OpNode> {
4639   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4640                                 asm, ".2s", ".2s",
4641                           [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;
4642   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4643                                 asm, ".4s", ".4s",
4644                           [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;
4645   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4646                                 asm, ".2d", ".2d",
4647                           [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4648 }
4649
4650 multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,
4651                            SDPatternOperator OpNode> {
4652   def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, V64,
4653                                 asm, ".2s", ".2s",
4654                           [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;
4655   def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, V128,
4656                                 asm, ".4s", ".4s",
4657                           [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4658   def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, V128,
4659                                 asm, ".2d", ".2d",
4660                           [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4661 }
4662
4663
4664 class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4665                            RegisterOperand inreg, RegisterOperand outreg,
4666                            string asm, string outkind, string inkind,
4667                            list<dag> pattern>
4668   : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,
4669       "{\t$Rd" # outkind # ", $Rn" # inkind #
4670       "|" # outkind # "\t$Rd, $Rn}", "", pattern>,
4671     Sched<[WriteV]> {
4672   bits<5> Rd;
4673   bits<5> Rn;
4674   let Inst{31}    = 0;
4675   let Inst{30}    = Q;
4676   let Inst{29}    = U;
4677   let Inst{28-24} = 0b01110;
4678   let Inst{23-22} = size;
4679   let Inst{21-17} = 0b10000;
4680   let Inst{16-12} = opcode;
4681   let Inst{11-10} = 0b10;
4682   let Inst{9-5}   = Rn;
4683   let Inst{4-0}   = Rd;
4684 }
4685
4686 class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4687                            RegisterOperand inreg, RegisterOperand outreg,
4688                            string asm, string outkind, string inkind,
4689                            list<dag> pattern>
4690   : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,
4691       "{\t$Rd" # outkind # ", $Rn" # inkind #
4692       "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,
4693     Sched<[WriteV]> {
4694   bits<5> Rd;
4695   bits<5> Rn;
4696   let Inst{31}    = 0;
4697   let Inst{30}    = Q;
4698   let Inst{29}    = U;
4699   let Inst{28-24} = 0b01110;
4700   let Inst{23-22} = size;
4701   let Inst{21-17} = 0b10000;
4702   let Inst{16-12} = opcode;
4703   let Inst{11-10} = 0b10;
4704   let Inst{9-5}   = Rn;
4705   let Inst{4-0}   = Rd;
4706 }
4707
4708 multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,
4709                               SDPatternOperator OpNode> {
4710   def v8i8  : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,
4711                                       asm, ".8b", ".8h",
4712         [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;
4713   def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,
4714                                       asm#"2", ".16b", ".8h", []>;
4715   def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,
4716                                       asm, ".4h", ".4s",
4717         [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;
4718   def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,
4719                                       asm#"2", ".8h", ".4s", []>;
4720   def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,
4721                                       asm, ".2s", ".2d",
4722         [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;
4723   def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,
4724                                       asm#"2", ".4s", ".2d", []>;
4725
4726   def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),
4727             (!cast<Instruction>(NAME # "v16i8")
4728                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4729   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),
4730             (!cast<Instruction>(NAME # "v8i16")
4731                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4732   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),
4733             (!cast<Instruction>(NAME # "v4i32")
4734                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4735 }
4736
4737 class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4738                            RegisterOperand regtype,
4739                            string asm, string kind, string zero,
4740                            ValueType dty, ValueType sty, SDNode OpNode>
4741   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
4742       "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #
4743       "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",
4744       [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,
4745     Sched<[WriteV]> {
4746   bits<5> Rd;
4747   bits<5> Rn;
4748   let Inst{31}    = 0;
4749   let Inst{30}    = Q;
4750   let Inst{29}    = U;
4751   let Inst{28-24} = 0b01110;
4752   let Inst{23-22} = size;
4753   let Inst{21-17} = 0b10000;
4754   let Inst{16-12} = opcode;
4755   let Inst{11-10} = 0b10;
4756   let Inst{9-5}   = Rn;
4757   let Inst{4-0}   = Rd;
4758 }
4759
4760 // Comparisons support all element sizes, except 1xD.
4761 multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,
4762                             SDNode OpNode> {
4763   def v8i8rz  : BaseSIMDCmpTwoVector<0, U, 0b00, opc, V64,
4764                                      asm, ".8b", "0",
4765                                      v8i8, v8i8, OpNode>;
4766   def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, opc, V128,
4767                                      asm, ".16b", "0",
4768                                      v16i8, v16i8, OpNode>;
4769   def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, opc, V64,
4770                                      asm, ".4h", "0",
4771                                      v4i16, v4i16, OpNode>;
4772   def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, opc, V128,
4773                                      asm, ".8h", "0",
4774                                      v8i16, v8i16, OpNode>;
4775   def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, opc, V64,
4776                                      asm, ".2s", "0",
4777                                      v2i32, v2i32, OpNode>;
4778   def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, opc, V128,
4779                                      asm, ".4s", "0",
4780                                      v4i32, v4i32, OpNode>;
4781   def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, opc, V128,
4782                                      asm, ".2d", "0",
4783                                      v2i64, v2i64, OpNode>;
4784 }
4785
4786 // FP Comparisons support only S and D element sizes.
4787 multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,
4788                               string asm, SDNode OpNode> {
4789
4790   def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, opc, V64,
4791                                      asm, ".2s", "0.0",
4792                                      v2i32, v2f32, OpNode>;
4793   def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, opc, V128,
4794                                      asm, ".4s", "0.0",
4795                                      v4i32, v4f32, OpNode>;
4796   def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, opc, V128,
4797                                      asm, ".2d", "0.0",
4798                                      v2i64, v2f64, OpNode>;
4799
4800   def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",
4801                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
4802   def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",
4803                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
4804   def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",
4805                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
4806   def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",
4807                   (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;
4808   def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",
4809                   (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;
4810   def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",
4811                   (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;
4812 }
4813
4814 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4815 class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,
4816                              RegisterOperand outtype, RegisterOperand intype,
4817                              string asm, string VdTy, string VnTy,
4818                              list<dag> pattern>
4819   : I<(outs outtype:$Rd), (ins intype:$Rn), asm,
4820       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,
4821     Sched<[WriteV]> {
4822   bits<5> Rd;
4823   bits<5> Rn;
4824   let Inst{31}    = 0;
4825   let Inst{30}    = Q;
4826   let Inst{29}    = U;
4827   let Inst{28-24} = 0b01110;
4828   let Inst{23-22} = size;
4829   let Inst{21-17} = 0b10000;
4830   let Inst{16-12} = opcode;
4831   let Inst{11-10} = 0b10;
4832   let Inst{9-5}   = Rn;
4833   let Inst{4-0}   = Rd;
4834 }
4835
4836 class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,
4837                              RegisterOperand outtype, RegisterOperand intype,
4838                              string asm, string VdTy, string VnTy,
4839                              list<dag> pattern>
4840   : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,
4841       !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,
4842     Sched<[WriteV]> {
4843   bits<5> Rd;
4844   bits<5> Rn;
4845   let Inst{31}    = 0;
4846   let Inst{30}    = Q;
4847   let Inst{29}    = U;
4848   let Inst{28-24} = 0b01110;
4849   let Inst{23-22} = size;
4850   let Inst{21-17} = 0b10000;
4851   let Inst{16-12} = opcode;
4852   let Inst{11-10} = 0b10;
4853   let Inst{9-5}   = Rn;
4854   let Inst{4-0}   = Rd;
4855 }
4856
4857 multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {
4858   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,
4859                                     asm, ".4s", ".4h", []>;
4860   def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,
4861                                     asm#"2", ".4s", ".8h", []>;
4862   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,
4863                                     asm, ".2d", ".2s", []>;
4864   def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,
4865                                     asm#"2", ".2d", ".4s", []>;
4866 }
4867
4868 multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {
4869   def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,
4870                                     asm, ".4h", ".4s", []>;
4871   def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,
4872                                     asm#"2", ".8h", ".4s", []>;
4873   def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4874                                     asm, ".2s", ".2d", []>;
4875   def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4876                                     asm#"2", ".4s", ".2d", []>;
4877 }
4878
4879 multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,
4880                                      Intrinsic OpNode> {
4881   def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,
4882                                      asm, ".2s", ".2d",
4883                           [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;
4884   def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,
4885                                     asm#"2", ".4s", ".2d", []>;
4886
4887   def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),
4888             (!cast<Instruction>(NAME # "v4f32")
4889                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;
4890 }
4891
4892 //----------------------------------------------------------------------------
4893 // AdvSIMD three register different-size vector instructions.
4894 //----------------------------------------------------------------------------
4895
4896 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4897 class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,
4898                       RegisterOperand outtype, RegisterOperand intype1,
4899                       RegisterOperand intype2, string asm,
4900                       string outkind, string inkind1, string inkind2,
4901                       list<dag> pattern>
4902   : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,
4903       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4904       "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,
4905     Sched<[WriteV]> {
4906   bits<5> Rd;
4907   bits<5> Rn;
4908   bits<5> Rm;
4909   let Inst{31}    = 0;
4910   let Inst{30}    = size{0};
4911   let Inst{29}    = U;
4912   let Inst{28-24} = 0b01110;
4913   let Inst{23-22} = size{2-1};
4914   let Inst{21}    = 1;
4915   let Inst{20-16} = Rm;
4916   let Inst{15-12} = opcode;
4917   let Inst{11-10} = 0b00;
4918   let Inst{9-5}   = Rn;
4919   let Inst{4-0}   = Rd;
4920 }
4921
4922 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
4923 class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,
4924                       RegisterOperand outtype, RegisterOperand intype1,
4925                       RegisterOperand intype2, string asm,
4926                       string outkind, string inkind1, string inkind2,
4927                       list<dag> pattern>
4928   : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,
4929       "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #
4930       "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,
4931     Sched<[WriteV]> {
4932   bits<5> Rd;
4933   bits<5> Rn;
4934   bits<5> Rm;
4935   let Inst{31}    = 0;
4936   let Inst{30}    = size{0};
4937   let Inst{29}    = U;
4938   let Inst{28-24} = 0b01110;
4939   let Inst{23-22} = size{2-1};
4940   let Inst{21}    = 1;
4941   let Inst{20-16} = Rm;
4942   let Inst{15-12} = opcode;
4943   let Inst{11-10} = 0b00;
4944   let Inst{9-5}   = Rn;
4945   let Inst{4-0}   = Rd;
4946 }
4947
4948 // FIXME: TableGen doesn't know how to deal with expanded types that also
4949 //        change the element count (in this case, placing the results in
4950 //        the high elements of the result register rather than the low
4951 //        elements). Until that's fixed, we can't code-gen those.
4952 multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,
4953                                     Intrinsic IntOp> {
4954   def v8i16_v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
4955                                                   V64, V128, V128,
4956                                                   asm, ".8b", ".8h", ".8h",
4957      [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;
4958   def v8i16_v16i8  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
4959                                                   V128, V128, V128,
4960                                                   asm#"2", ".16b", ".8h", ".8h",
4961      []>;
4962   def v4i32_v4i16  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
4963                                                   V64, V128, V128,
4964                                                   asm, ".4h", ".4s", ".4s",
4965      [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;
4966   def v4i32_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
4967                                                   V128, V128, V128,
4968                                                   asm#"2", ".8h", ".4s", ".4s",
4969      []>;
4970   def v2i64_v2i32  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
4971                                                   V64, V128, V128,
4972                                                   asm, ".2s", ".2d", ".2d",
4973      [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;
4974   def v2i64_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
4975                                                   V128, V128, V128,
4976                                                   asm#"2", ".4s", ".2d", ".2d",
4977      []>;
4978
4979
4980   // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in
4981   // a version attached to an instruction.
4982   def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),
4983                                                    (v8i16 V128:$Rm))),
4984             (!cast<Instruction>(NAME # "v8i16_v16i8")
4985                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4986                 V128:$Rn, V128:$Rm)>;
4987   def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),
4988                                                     (v4i32 V128:$Rm))),
4989             (!cast<Instruction>(NAME # "v4i32_v8i16")
4990                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4991                 V128:$Rn, V128:$Rm)>;
4992   def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),
4993                                                     (v2i64 V128:$Rm))),
4994             (!cast<Instruction>(NAME # "v2i64_v4i32")
4995                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
4996                 V128:$Rn, V128:$Rm)>;
4997 }
4998
4999 multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,
5000                                       Intrinsic IntOp> {
5001   def v8i8   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5002                                             V128, V64, V64,
5003                                             asm, ".8h", ".8b", ".8b",
5004       [(set (v8i16 V128:$Rd), (IntOp (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5005   def v16i8  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5006                                             V128, V128, V128,
5007                                             asm#"2", ".8h", ".16b", ".16b", []>;
5008   let Predicates = [HasCrypto] in {
5009     def v1i64  : BaseSIMDDifferentThreeVector<U, 0b110, opc,
5010                                               V128, V64, V64,
5011                                               asm, ".1q", ".1d", ".1d", []>;
5012     def v2i64  : BaseSIMDDifferentThreeVector<U, 0b111, opc,
5013                                               V128, V128, V128,
5014                                               asm#"2", ".1q", ".2d", ".2d", []>;
5015   }
5016
5017   def : Pat<(v8i16 (IntOp (v8i8 (extract_high_v16i8 V128:$Rn)),
5018                           (v8i8 (extract_high_v16i8 V128:$Rm)))),
5019       (!cast<Instruction>(NAME#"v16i8") V128:$Rn, V128:$Rm)>;
5020 }
5021
5022 multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,
5023                                  SDPatternOperator OpNode> {
5024   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5025                                                   V128, V64, V64,
5026                                                   asm, ".4s", ".4h", ".4h",
5027       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5028   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5029                                                   V128, V128, V128,
5030                                                   asm#"2", ".4s", ".8h", ".8h",
5031       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5032                                       (extract_high_v8i16 V128:$Rm)))]>;
5033   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5034                                                   V128, V64, V64,
5035                                                   asm, ".2d", ".2s", ".2s",
5036       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5037   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5038                                                   V128, V128, V128,
5039                                                   asm#"2", ".2d", ".4s", ".4s",
5040       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5041                                       (extract_high_v4i32 V128:$Rm)))]>;
5042 }
5043
5044 multiclass SIMDLongThreeVectorBHSabdl<bit U, bits<4> opc, string asm,
5045                                   SDPatternOperator OpNode = null_frag> {
5046   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5047                                                   V128, V64, V64,
5048                                                   asm, ".8h", ".8b", ".8b",
5049       [(set (v8i16 V128:$Rd),
5050             (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))))]>;
5051   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5052                                                  V128, V128, V128,
5053                                                  asm#"2", ".8h", ".16b", ".16b",
5054       [(set (v8i16 V128:$Rd),
5055             (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5056                                 (extract_high_v16i8 V128:$Rm)))))]>;
5057   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5058                                                   V128, V64, V64,
5059                                                   asm, ".4s", ".4h", ".4h",
5060       [(set (v4i32 V128:$Rd),
5061             (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))))]>;
5062   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5063                                                   V128, V128, V128,
5064                                                   asm#"2", ".4s", ".8h", ".8h",
5065       [(set (v4i32 V128:$Rd),
5066             (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5067                                   (extract_high_v8i16 V128:$Rm)))))]>;
5068   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5069                                                   V128, V64, V64,
5070                                                   asm, ".2d", ".2s", ".2s",
5071       [(set (v2i64 V128:$Rd),
5072             (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))))]>;
5073   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5074                                                   V128, V128, V128,
5075                                                   asm#"2", ".2d", ".4s", ".4s",
5076       [(set (v2i64 V128:$Rd),
5077             (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5078                                  (extract_high_v4i32 V128:$Rm)))))]>;
5079 }
5080
5081 multiclass SIMDLongThreeVectorTiedBHSabal<bit U, bits<4> opc,
5082                                           string asm,
5083                                           SDPatternOperator OpNode> {
5084   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5085                                                   V128, V64, V64,
5086                                                   asm, ".8h", ".8b", ".8b",
5087     [(set (v8i16 V128:$dst),
5088           (add (v8i16 V128:$Rd),
5089                (zext (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))))]>;
5090   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5091                                                  V128, V128, V128,
5092                                                  asm#"2", ".8h", ".16b", ".16b",
5093     [(set (v8i16 V128:$dst),
5094           (add (v8i16 V128:$Rd),
5095                (zext (v8i8 (OpNode (extract_high_v16i8 V128:$Rn),
5096                                    (extract_high_v16i8 V128:$Rm))))))]>;
5097   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5098                                                   V128, V64, V64,
5099                                                   asm, ".4s", ".4h", ".4h",
5100     [(set (v4i32 V128:$dst),
5101           (add (v4i32 V128:$Rd),
5102                (zext (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))))]>;
5103   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5104                                                   V128, V128, V128,
5105                                                   asm#"2", ".4s", ".8h", ".8h",
5106     [(set (v4i32 V128:$dst),
5107           (add (v4i32 V128:$Rd),
5108                (zext (v4i16 (OpNode (extract_high_v8i16 V128:$Rn),
5109                                     (extract_high_v8i16 V128:$Rm))))))]>;
5110   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5111                                                   V128, V64, V64,
5112                                                   asm, ".2d", ".2s", ".2s",
5113     [(set (v2i64 V128:$dst),
5114           (add (v2i64 V128:$Rd),
5115                (zext (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))))]>;
5116   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5117                                                   V128, V128, V128,
5118                                                   asm#"2", ".2d", ".4s", ".4s",
5119     [(set (v2i64 V128:$dst),
5120           (add (v2i64 V128:$Rd),
5121                (zext (v2i32 (OpNode (extract_high_v4i32 V128:$Rn),
5122                                     (extract_high_v4i32 V128:$Rm))))))]>;
5123 }
5124
5125 multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,
5126                                   SDPatternOperator OpNode = null_frag> {
5127   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5128                                                   V128, V64, V64,
5129                                                   asm, ".8h", ".8b", ".8b",
5130       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5131   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5132                                                  V128, V128, V128,
5133                                                  asm#"2", ".8h", ".16b", ".16b",
5134       [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 V128:$Rn),
5135                                       (extract_high_v16i8 V128:$Rm)))]>;
5136   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5137                                                   V128, V64, V64,
5138                                                   asm, ".4s", ".4h", ".4h",
5139       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5140   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5141                                                   V128, V128, V128,
5142                                                   asm#"2", ".4s", ".8h", ".8h",
5143       [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 V128:$Rn),
5144                                       (extract_high_v8i16 V128:$Rm)))]>;
5145   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5146                                                   V128, V64, V64,
5147                                                   asm, ".2d", ".2s", ".2s",
5148       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5149   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5150                                                   V128, V128, V128,
5151                                                   asm#"2", ".2d", ".4s", ".4s",
5152       [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 V128:$Rn),
5153                                       (extract_high_v4i32 V128:$Rm)))]>;
5154 }
5155
5156 multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,
5157                                       string asm,
5158                                       SDPatternOperator OpNode> {
5159   def v8i8_v8i16   : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,
5160                                                   V128, V64, V64,
5161                                                   asm, ".8h", ".8b", ".8b",
5162     [(set (v8i16 V128:$dst),
5163           (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;
5164   def v16i8_v8i16  : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,
5165                                                  V128, V128, V128,
5166                                                  asm#"2", ".8h", ".16b", ".16b",
5167     [(set (v8i16 V128:$dst),
5168           (OpNode (v8i16 V128:$Rd),
5169                   (extract_high_v16i8 V128:$Rn),
5170                   (extract_high_v16i8 V128:$Rm)))]>;
5171   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5172                                                   V128, V64, V64,
5173                                                   asm, ".4s", ".4h", ".4h",
5174     [(set (v4i32 V128:$dst),
5175           (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;
5176   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5177                                                   V128, V128, V128,
5178                                                   asm#"2", ".4s", ".8h", ".8h",
5179     [(set (v4i32 V128:$dst),
5180           (OpNode (v4i32 V128:$Rd),
5181                   (extract_high_v8i16 V128:$Rn),
5182                   (extract_high_v8i16 V128:$Rm)))]>;
5183   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5184                                                   V128, V64, V64,
5185                                                   asm, ".2d", ".2s", ".2s",
5186     [(set (v2i64 V128:$dst),
5187           (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;
5188   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5189                                                   V128, V128, V128,
5190                                                   asm#"2", ".2d", ".4s", ".4s",
5191     [(set (v2i64 V128:$dst),
5192           (OpNode (v2i64 V128:$Rd),
5193                   (extract_high_v4i32 V128:$Rn),
5194                   (extract_high_v4i32 V128:$Rm)))]>;
5195 }
5196
5197 multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,
5198                                            SDPatternOperator Accum> {
5199   def v4i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,
5200                                                   V128, V64, V64,
5201                                                   asm, ".4s", ".4h", ".4h",
5202     [(set (v4i32 V128:$dst),
5203           (Accum (v4i32 V128:$Rd),
5204                  (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
5205                                                 (v4i16 V64:$Rm)))))]>;
5206   def v8i16_v4i32  : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,
5207                                                   V128, V128, V128,
5208                                                   asm#"2", ".4s", ".8h", ".8h",
5209     [(set (v4i32 V128:$dst),
5210           (Accum (v4i32 V128:$Rd),
5211                  (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 V128:$Rn),
5212                                             (extract_high_v8i16 V128:$Rm)))))]>;
5213   def v2i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,
5214                                                   V128, V64, V64,
5215                                                   asm, ".2d", ".2s", ".2s",
5216     [(set (v2i64 V128:$dst),
5217           (Accum (v2i64 V128:$Rd),
5218                  (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),
5219                                                 (v2i32 V64:$Rm)))))]>;
5220   def v4i32_v2i64  : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,
5221                                                   V128, V128, V128,
5222                                                   asm#"2", ".2d", ".4s", ".4s",
5223     [(set (v2i64 V128:$dst),
5224           (Accum (v2i64 V128:$Rd),
5225                  (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 V128:$Rn),
5226                                             (extract_high_v4i32 V128:$Rm)))))]>;
5227 }
5228
5229 multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,
5230                                   SDPatternOperator OpNode> {
5231   def v8i8_v8i16   : BaseSIMDDifferentThreeVector<U, 0b000, opc,
5232                                                   V128, V128, V64,
5233                                                   asm, ".8h", ".8h", ".8b",
5234        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;
5235   def v16i8_v8i16  : BaseSIMDDifferentThreeVector<U, 0b001, opc,
5236                                                   V128, V128, V128,
5237                                                   asm#"2", ".8h", ".8h", ".16b",
5238        [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
5239                                        (extract_high_v16i8 V128:$Rm)))]>;
5240   def v4i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b010, opc,
5241                                                   V128, V128, V64,
5242                                                   asm, ".4s", ".4s", ".4h",
5243        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;
5244   def v8i16_v4i32  : BaseSIMDDifferentThreeVector<U, 0b011, opc,
5245                                                   V128, V128, V128,
5246                                                   asm#"2", ".4s", ".4s", ".8h",
5247        [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
5248                                        (extract_high_v8i16 V128:$Rm)))]>;
5249   def v2i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b100, opc,
5250                                                   V128, V128, V64,
5251                                                   asm, ".2d", ".2d", ".2s",
5252        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;
5253   def v4i32_v2i64  : BaseSIMDDifferentThreeVector<U, 0b101, opc,
5254                                                   V128, V128, V128,
5255                                                   asm#"2", ".2d", ".2d", ".4s",
5256        [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
5257                                        (extract_high_v4i32 V128:$Rm)))]>;
5258 }
5259
5260 //----------------------------------------------------------------------------
5261 // AdvSIMD bitwise extract from vector
5262 //----------------------------------------------------------------------------
5263
5264 class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,
5265                              string asm, string kind>
5266   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,
5267       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #
5268       "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",
5269       [(set (vty regtype:$Rd),
5270             (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,
5271     Sched<[WriteV]> {
5272   bits<5> Rd;
5273   bits<5> Rn;
5274   bits<5> Rm;
5275   bits<4> imm;
5276   let Inst{31}    = 0;
5277   let Inst{30}    = size;
5278   let Inst{29-21} = 0b101110000;
5279   let Inst{20-16} = Rm;
5280   let Inst{15}    = 0;
5281   let Inst{14-11} = imm;
5282   let Inst{10}    = 0;
5283   let Inst{9-5}   = Rn;
5284   let Inst{4-0}   = Rd;
5285 }
5286
5287
5288 multiclass SIMDBitwiseExtract<string asm> {
5289   def v8i8  : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {
5290     let imm{3} = 0;
5291   }
5292   def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;
5293 }
5294
5295 //----------------------------------------------------------------------------
5296 // AdvSIMD zip vector
5297 //----------------------------------------------------------------------------
5298
5299 class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,
5300                         string asm, string kind, SDNode OpNode, ValueType valty>
5301   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5302       "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #
5303       "|" # kind # "\t$Rd, $Rn, $Rm}", "",
5304       [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,
5305     Sched<[WriteV]> {
5306   bits<5> Rd;
5307   bits<5> Rn;
5308   bits<5> Rm;
5309   let Inst{31}    = 0;
5310   let Inst{30}    = size{0};
5311   let Inst{29-24} = 0b001110;
5312   let Inst{23-22} = size{2-1};
5313   let Inst{21}    = 0;
5314   let Inst{20-16} = Rm;
5315   let Inst{15}    = 0;
5316   let Inst{14-12} = opc;
5317   let Inst{11-10} = 0b10;
5318   let Inst{9-5}   = Rn;
5319   let Inst{4-0}   = Rd;
5320 }
5321
5322 multiclass SIMDZipVector<bits<3>opc, string asm,
5323                          SDNode OpNode> {
5324   def v8i8   : BaseSIMDZipVector<0b000, opc, V64,
5325       asm, ".8b", OpNode, v8i8>;
5326   def v16i8  : BaseSIMDZipVector<0b001, opc, V128,
5327       asm, ".16b", OpNode, v16i8>;
5328   def v4i16  : BaseSIMDZipVector<0b010, opc, V64,
5329       asm, ".4h", OpNode, v4i16>;
5330   def v8i16  : BaseSIMDZipVector<0b011, opc, V128,
5331       asm, ".8h", OpNode, v8i16>;
5332   def v2i32  : BaseSIMDZipVector<0b100, opc, V64,
5333       asm, ".2s", OpNode, v2i32>;
5334   def v4i32  : BaseSIMDZipVector<0b101, opc, V128,
5335       asm, ".4s", OpNode, v4i32>;
5336   def v2i64  : BaseSIMDZipVector<0b111, opc, V128,
5337       asm, ".2d", OpNode, v2i64>;
5338
5339   def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),
5340         (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;
5341   def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),
5342         (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;
5343   def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),
5344         (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;
5345   def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),
5346         (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;
5347   def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),
5348         (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;
5349 }
5350
5351 //----------------------------------------------------------------------------
5352 // AdvSIMD three register scalar instructions
5353 //----------------------------------------------------------------------------
5354
5355 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5356 class BaseSIMDThreeScalar<bit U, bits<2> size, bits<5> opcode,
5357                         RegisterClass regtype, string asm,
5358                         list<dag> pattern>
5359   : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,
5360       "\t$Rd, $Rn, $Rm", "", pattern>,
5361     Sched<[WriteV]> {
5362   bits<5> Rd;
5363   bits<5> Rn;
5364   bits<5> Rm;
5365   let Inst{31-30} = 0b01;
5366   let Inst{29}    = U;
5367   let Inst{28-24} = 0b11110;
5368   let Inst{23-22} = size;
5369   let Inst{21}    = 1;
5370   let Inst{20-16} = Rm;
5371   let Inst{15-11} = opcode;
5372   let Inst{10}    = 1;
5373   let Inst{9-5}   = Rn;
5374   let Inst{4-0}   = Rd;
5375 }
5376
5377 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
5378 class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,
5379                         dag oops, dag iops, string asm,
5380             list<dag> pattern>
5381   : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,
5382     Sched<[WriteV]> {
5383   bits<5> Rd;
5384   bits<5> Rn;
5385   bits<5> Rm;
5386   let Inst{31-30} = 0b01;
5387   let Inst{29}    = U;
5388   let Inst{28-24} = 0b11110;
5389   let Inst{23-22} = size;
5390   let Inst{21}    = R;
5391   let Inst{20-16} = Rm;
5392   let Inst{15-11} = opcode;
5393   let Inst{10}    = 1;
5394   let Inst{9-5}   = Rn;
5395   let Inst{4-0}   = Rd;
5396 }
5397
5398 multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,
5399                             SDPatternOperator OpNode> {
5400   def v1i64  : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
5401     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5402 }
5403
5404 multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,
5405                                SDPatternOperator OpNode> {
5406   def v1i64  : BaseSIMDThreeScalar<U, 0b11, opc, FPR64, asm,
5407     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;
5408   def v1i32  : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm, []>;
5409   def v1i16  : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
5410   def v1i8   : BaseSIMDThreeScalar<U, 0b00, opc, FPR8 , asm, []>;
5411
5412   def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),
5413             (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;
5414   def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),
5415             (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;
5416 }
5417
5418 multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,
5419                              SDPatternOperator OpNode> {
5420   def v1i32  : BaseSIMDThreeScalar<U, 0b10, opc, FPR32, asm,
5421                              [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5422   def v1i16  : BaseSIMDThreeScalar<U, 0b01, opc, FPR16, asm, []>;
5423 }
5424
5425 multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm,
5426                                  SDPatternOperator OpNode = null_frag> {
5427   def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),
5428                                      (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm), 
5429                                      asm, []>;
5430   def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),
5431                                      (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm), 
5432                                      asm, []>;
5433 }
5434
5435 multiclass SIMDThreeScalarSD<bit U, bit S, bits<5> opc, string asm,
5436                              SDPatternOperator OpNode = null_frag> {
5437   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5438     def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
5439       [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5440     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
5441       [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;
5442   }
5443
5444   def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5445             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5446 }
5447
5448 multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<5> opc, string asm,
5449                                 SDPatternOperator OpNode = null_frag> {
5450   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5451     def #NAME#64 : BaseSIMDThreeScalar<U, {S,1}, opc, FPR64, asm,
5452       [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;
5453     def #NAME#32 : BaseSIMDThreeScalar<U, {S,0}, opc, FPR32, asm,
5454       [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;
5455   }
5456
5457   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
5458             (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;
5459 }
5460
5461 class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,
5462               dag oops, dag iops, string asm, string cstr, list<dag> pat>
5463   : I<oops, iops, asm,
5464       "\t$Rd, $Rn, $Rm", cstr, pat>,
5465     Sched<[WriteV]> {
5466   bits<5> Rd;
5467   bits<5> Rn;
5468   bits<5> Rm;
5469   let Inst{31-30} = 0b01;
5470   let Inst{29}    = U;
5471   let Inst{28-24} = 0b11110;
5472   let Inst{23-22} = size;
5473   let Inst{21}    = 1;
5474   let Inst{20-16} = Rm;
5475   let Inst{15-11} = opcode;
5476   let Inst{10}    = 0;
5477   let Inst{9-5}   = Rn;
5478   let Inst{4-0}   = Rd;
5479 }
5480
5481 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5482 multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,
5483                                   SDPatternOperator OpNode = null_frag> {
5484   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5485                                       (outs FPR32:$Rd),
5486                                       (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;
5487   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5488                                       (outs FPR64:$Rd),
5489                                       (ins FPR32:$Rn, FPR32:$Rm), asm, "",
5490             [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5491 }
5492
5493 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5494 multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,
5495                                   SDPatternOperator OpNode = null_frag> {
5496   def i16  : BaseSIMDThreeScalarMixed<U, 0b01, opc,
5497                                       (outs FPR32:$dst),
5498                                       (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),
5499                                       asm, "$Rd = $dst", []>;
5500   def i32  : BaseSIMDThreeScalarMixed<U, 0b10, opc,
5501                                       (outs FPR64:$dst),
5502                                       (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),
5503                                       asm, "$Rd = $dst",
5504             [(set (i64 FPR64:$dst),
5505                   (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;
5506 }
5507
5508 //----------------------------------------------------------------------------
5509 // AdvSIMD two register scalar instructions
5510 //----------------------------------------------------------------------------
5511
5512 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5513 class BaseSIMDTwoScalar<bit U, bits<2> size, bits<5> opcode,
5514                         RegisterClass regtype, RegisterClass regtype2,
5515                         string asm, list<dag> pat>
5516   : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,
5517       "\t$Rd, $Rn", "", pat>,
5518     Sched<[WriteV]> {
5519   bits<5> Rd;
5520   bits<5> Rn;
5521   let Inst{31-30} = 0b01;
5522   let Inst{29}    = U;
5523   let Inst{28-24} = 0b11110;
5524   let Inst{23-22} = size;
5525   let Inst{21-17} = 0b10000;
5526   let Inst{16-12} = opcode;
5527   let Inst{11-10} = 0b10;
5528   let Inst{9-5}   = Rn;
5529   let Inst{4-0}   = Rd;
5530 }
5531
5532 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5533 class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,
5534                         RegisterClass regtype, RegisterClass regtype2,
5535                         string asm, list<dag> pat>
5536   : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,
5537       "\t$Rd, $Rn", "$Rd = $dst", pat>,
5538     Sched<[WriteV]> {
5539   bits<5> Rd;
5540   bits<5> Rn;
5541   let Inst{31-30} = 0b01;
5542   let Inst{29}    = U;
5543   let Inst{28-24} = 0b11110;
5544   let Inst{23-22} = size;
5545   let Inst{21-17} = 0b10000;
5546   let Inst{16-12} = opcode;
5547   let Inst{11-10} = 0b10;
5548   let Inst{9-5}   = Rn;
5549   let Inst{4-0}   = Rd;
5550 }
5551
5552
5553 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5554 class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<5> opcode,
5555                         RegisterClass regtype, string asm, string zero>
5556   : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,
5557       "\t$Rd, $Rn, #" # zero, "", []>,
5558     Sched<[WriteV]> {
5559   bits<5> Rd;
5560   bits<5> Rn;
5561   let Inst{31-30} = 0b01;
5562   let Inst{29}    = U;
5563   let Inst{28-24} = 0b11110;
5564   let Inst{23-22} = size;
5565   let Inst{21-17} = 0b10000;
5566   let Inst{16-12} = opcode;
5567   let Inst{11-10} = 0b10;
5568   let Inst{9-5}   = Rn;
5569   let Inst{4-0}   = Rd;
5570 }
5571
5572 class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>
5573   : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",
5574      [(set (f32 FPR32:$Rd), (int_aarch64_sisd_fcvtxn (f64 FPR64:$Rn)))]>,
5575     Sched<[WriteV]> {
5576   bits<5> Rd;
5577   bits<5> Rn;
5578   let Inst{31-17} = 0b011111100110000;
5579   let Inst{16-12} = opcode;
5580   let Inst{11-10} = 0b10;
5581   let Inst{9-5}   = Rn;
5582   let Inst{4-0}   = Rd;
5583 }
5584
5585 multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,
5586                              SDPatternOperator OpNode> {
5587   def v1i64rz  : BaseSIMDCmpTwoScalar<U, 0b11, opc, FPR64, asm, "0">;
5588
5589   def : Pat<(v1i64 (OpNode FPR64:$Rn)),
5590             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5591 }
5592
5593 multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,
5594                               SDPatternOperator OpNode> {
5595   def v1i64rz  : BaseSIMDCmpTwoScalar<U, {S,1}, opc, FPR64, asm, "0.0">;
5596   def v1i32rz  : BaseSIMDCmpTwoScalar<U, {S,0}, opc, FPR32, asm, "0.0">;
5597
5598   def : InstAlias<asm # "\t$Rd, $Rn, #0",
5599                   (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;
5600   def : InstAlias<asm # "\t$Rd, $Rn, #0",
5601                   (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;
5602
5603   def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),
5604             (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;
5605 }
5606
5607 multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,
5608                           SDPatternOperator OpNode = null_frag> {
5609   def v1i64       : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5610     [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;
5611
5612   def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),
5613             (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;
5614 }
5615
5616 multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm> {
5617   def v1i64       : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,[]>;
5618   def v1i32       : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,[]>;
5619 }
5620
5621 multiclass SIMDTwoScalarCVTSD<bit U, bit S, bits<5> opc, string asm,
5622                               SDPatternOperator OpNode> {
5623   def v1i64 : BaseSIMDTwoScalar<U, {S,1}, opc, FPR64, FPR64, asm,
5624                                 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;
5625   def v1i32 : BaseSIMDTwoScalar<U, {S,0}, opc, FPR32, FPR32, asm,
5626                                 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;
5627 }
5628
5629 multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,
5630                              SDPatternOperator OpNode = null_frag> {
5631   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5632     def v1i64  : BaseSIMDTwoScalar<U, 0b11, opc, FPR64, FPR64, asm,
5633            [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5634     def v1i32  : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR32, asm,
5635            [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
5636     def v1i16  : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR16, asm, []>;
5637     def v1i8   : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5638   }
5639
5640   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),
5641             (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;
5642 }
5643
5644 multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,
5645                                  Intrinsic OpNode> {
5646   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
5647     def v1i64  : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,
5648         [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;
5649     def v1i32  : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,
5650         [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;
5651     def v1i16  : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;
5652     def v1i8   : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;
5653   }
5654
5655   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),
5656             (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;
5657 }
5658
5659
5660
5661 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5662 multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,
5663                                  SDPatternOperator OpNode = null_frag> {
5664   def v1i32  : BaseSIMDTwoScalar<U, 0b10, opc, FPR32, FPR64, asm,
5665         [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn)))]>;
5666   def v1i16  : BaseSIMDTwoScalar<U, 0b01, opc, FPR16, FPR32, asm, []>;
5667   def v1i8   : BaseSIMDTwoScalar<U, 0b00, opc, FPR8 , FPR16, asm, []>;
5668 }
5669
5670 //----------------------------------------------------------------------------
5671 // AdvSIMD scalar pairwise instructions
5672 //----------------------------------------------------------------------------
5673
5674 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5675 class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,
5676                         RegisterOperand regtype, RegisterOperand vectype,
5677                         string asm, string kind>
5678   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5679       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,
5680     Sched<[WriteV]> {
5681   bits<5> Rd;
5682   bits<5> Rn;
5683   let Inst{31-30} = 0b01;
5684   let Inst{29}    = U;
5685   let Inst{28-24} = 0b11110;
5686   let Inst{23-22} = size;
5687   let Inst{21-17} = 0b11000;
5688   let Inst{16-12} = opcode;
5689   let Inst{11-10} = 0b10;
5690   let Inst{9-5}   = Rn;
5691   let Inst{4-0}   = Rd;
5692 }
5693
5694 multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {
5695   def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,
5696                                       asm, ".2d">;
5697 }
5698
5699 multiclass SIMDFPPairwiseScalar<bit U, bit S, bits<5> opc, string asm> {
5700   def v2i32p : BaseSIMDPairwiseScalar<U, {S,0}, opc, FPR32Op, V64,
5701                                       asm, ".2s">;
5702   def v2i64p : BaseSIMDPairwiseScalar<U, {S,1}, opc, FPR64Op, V128,
5703                                       asm, ".2d">;
5704 }
5705
5706 //----------------------------------------------------------------------------
5707 // AdvSIMD across lanes instructions
5708 //----------------------------------------------------------------------------
5709
5710 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
5711 class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,
5712                           RegisterClass regtype, RegisterOperand vectype,
5713                           string asm, string kind, list<dag> pattern>
5714   : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,
5715       "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,
5716     Sched<[WriteV]> {
5717   bits<5> Rd;
5718   bits<5> Rn;
5719   let Inst{31}    = 0;
5720   let Inst{30}    = Q;
5721   let Inst{29}    = U;
5722   let Inst{28-24} = 0b01110;
5723   let Inst{23-22} = size;
5724   let Inst{21-17} = 0b11000;
5725   let Inst{16-12} = opcode;
5726   let Inst{11-10} = 0b10;
5727   let Inst{9-5}   = Rn;
5728   let Inst{4-0}   = Rd;
5729 }
5730
5731 multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,
5732                               string asm> {
5733   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8,  V64,
5734                                    asm, ".8b", []>;
5735   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8,  V128,
5736                                    asm, ".16b", []>;
5737   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,
5738                                    asm, ".4h", []>;
5739   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,
5740                                    asm, ".8h", []>;
5741   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,
5742                                    asm, ".4s", []>;
5743 }
5744
5745 multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {
5746   def v8i8v  : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,
5747                                    asm, ".8b", []>;
5748   def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,
5749                                    asm, ".16b", []>;
5750   def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,
5751                                    asm, ".4h", []>;
5752   def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,
5753                                    asm, ".8h", []>;
5754   def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,
5755                                    asm, ".4s", []>;
5756 }
5757
5758 multiclass SIMDAcrossLanesS<bits<5> opcode, bit sz1, string asm,
5759                             Intrinsic intOp> {
5760   def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,
5761                                    asm, ".4s",
5762         [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;
5763 }
5764
5765 //----------------------------------------------------------------------------
5766 // AdvSIMD INS/DUP instructions
5767 //----------------------------------------------------------------------------
5768
5769 // FIXME: There has got to be a better way to factor these. ugh.
5770
5771 class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,
5772                      string operands, string constraints, list<dag> pattern>
5773   : I<outs, ins, asm, operands, constraints, pattern>,
5774     Sched<[WriteV]> {
5775   bits<5> Rd;
5776   bits<5> Rn;
5777   let Inst{31} = 0;
5778   let Inst{30} = Q;
5779   let Inst{29} = op;
5780   let Inst{28-21} = 0b01110000;
5781   let Inst{15} = 0;
5782   let Inst{10} = 1;
5783   let Inst{9-5} = Rn;
5784   let Inst{4-0} = Rd;
5785 }
5786
5787 class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,
5788                       RegisterOperand vecreg, RegisterClass regtype>
5789   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",
5790                    "{\t$Rd" # size # ", $Rn" #
5791                    "|" # size # "\t$Rd, $Rn}", "",
5792                    [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {
5793   let Inst{20-16} = imm5;
5794   let Inst{14-11} = 0b0001;
5795 }
5796
5797 class SIMDDupFromElement<bit Q, string dstkind, string srckind,
5798                          ValueType vectype, ValueType insreg,
5799                          RegisterOperand vecreg, Operand idxtype,
5800                          ValueType elttype, SDNode OpNode>
5801   : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",
5802                    "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #
5803                    "|" # dstkind # "\t$Rd, $Rn$idx}", "",
5804                  [(set (vectype vecreg:$Rd),
5805                        (OpNode (insreg V128:$Rn), idxtype:$idx))]> {
5806   let Inst{14-11} = 0b0000;
5807 }
5808
5809 class SIMDDup64FromElement
5810   : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,
5811                        VectorIndexD, i64, AArch64duplane64> {
5812   bits<1> idx;
5813   let Inst{20} = idx;
5814   let Inst{19-16} = 0b1000;
5815 }
5816
5817 class SIMDDup32FromElement<bit Q, string size, ValueType vectype,
5818                            RegisterOperand vecreg>
5819   : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,
5820                        VectorIndexS, i64, AArch64duplane32> {
5821   bits<2> idx;
5822   let Inst{20-19} = idx;
5823   let Inst{18-16} = 0b100;
5824 }
5825
5826 class SIMDDup16FromElement<bit Q, string size, ValueType vectype,
5827                            RegisterOperand vecreg>
5828   : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,
5829                        VectorIndexH, i64, AArch64duplane16> {
5830   bits<3> idx;
5831   let Inst{20-18} = idx;
5832   let Inst{17-16} = 0b10;
5833 }
5834
5835 class SIMDDup8FromElement<bit Q, string size, ValueType vectype,
5836                           RegisterOperand vecreg>
5837   : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,
5838                        VectorIndexB, i64, AArch64duplane8> {
5839   bits<4> idx;
5840   let Inst{20-17} = idx;
5841   let Inst{16} = 1;
5842 }
5843
5844 class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,
5845                   Operand idxtype, string asm, list<dag> pattern>
5846   : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,
5847                    "{\t$Rd, $Rn" # size # "$idx" #
5848                    "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {
5849   let Inst{14-11} = imm4;
5850 }
5851
5852 class SIMDSMov<bit Q, string size, RegisterClass regtype,
5853                Operand idxtype>
5854   : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;
5855 class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,
5856                Operand idxtype>
5857   : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",
5858       [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;
5859
5860 class SIMDMovAlias<string asm, string size, Instruction inst,
5861                    RegisterClass regtype, Operand idxtype>
5862     : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #
5863                     "|" # size # "\t$dst, $src$idx}",
5864                 (inst regtype:$dst, V128:$src, idxtype:$idx)>;
5865
5866 multiclass SMov {
5867   def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {
5868     bits<4> idx;
5869     let Inst{20-17} = idx;
5870     let Inst{16} = 1;
5871   }
5872   def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {
5873     bits<4> idx;
5874     let Inst{20-17} = idx;
5875     let Inst{16} = 1;
5876   }
5877   def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {
5878     bits<3> idx;
5879     let Inst{20-18} = idx;
5880     let Inst{17-16} = 0b10;
5881   }
5882   def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {
5883     bits<3> idx;
5884     let Inst{20-18} = idx;
5885     let Inst{17-16} = 0b10;
5886   }
5887   def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {
5888     bits<2> idx;
5889     let Inst{20-19} = idx;
5890     let Inst{18-16} = 0b100;
5891   }
5892 }
5893
5894 multiclass UMov {
5895   def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {
5896     bits<4> idx;
5897     let Inst{20-17} = idx;
5898     let Inst{16} = 1;
5899   }
5900   def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {
5901     bits<3> idx;
5902     let Inst{20-18} = idx;
5903     let Inst{17-16} = 0b10;
5904   }
5905   def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {
5906     bits<2> idx;
5907     let Inst{20-19} = idx;
5908     let Inst{18-16} = 0b100;
5909   }
5910   def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {
5911     bits<1> idx;
5912     let Inst{20} = idx;
5913     let Inst{19-16} = 0b1000;
5914   }
5915   def : SIMDMovAlias<"mov", ".s",
5916                      !cast<Instruction>(NAME#"vi32"),
5917                      GPR32, VectorIndexS>;
5918   def : SIMDMovAlias<"mov", ".d",
5919                      !cast<Instruction>(NAME#"vi64"),
5920                      GPR64, VectorIndexD>;
5921 }
5922
5923 class SIMDInsFromMain<string size, ValueType vectype,
5924                       RegisterClass regtype, Operand idxtype>
5925   : BaseSIMDInsDup<1, 0, (outs V128:$dst),
5926                    (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",
5927                    "{\t$Rd" # size # "$idx, $Rn" #
5928                    "|" # size # "\t$Rd$idx, $Rn}",
5929                    "$Rd = $dst",
5930             [(set V128:$dst,
5931               (vector_insert (vectype V128:$Rd), regtype:$Rn, idxtype:$idx))]> {
5932   let Inst{14-11} = 0b0011;
5933 }
5934
5935 class SIMDInsFromElement<string size, ValueType vectype,
5936                          ValueType elttype, Operand idxtype>
5937   : BaseSIMDInsDup<1, 1, (outs V128:$dst),
5938                    (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",
5939                    "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #
5940                    "|" # size # "\t$Rd$idx, $Rn$idx2}",
5941                    "$Rd = $dst",
5942          [(set V128:$dst,
5943                (vector_insert
5944                  (vectype V128:$Rd),
5945                  (elttype (vector_extract (vectype V128:$Rn), idxtype:$idx2)),
5946                  idxtype:$idx))]>;
5947
5948 class SIMDInsMainMovAlias<string size, Instruction inst,
5949                           RegisterClass regtype, Operand idxtype>
5950     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #
5951                         "|" # size #"\t$dst$idx, $src}",
5952                 (inst V128:$dst, idxtype:$idx, regtype:$src)>;
5953 class SIMDInsElementMovAlias<string size, Instruction inst,
5954                              Operand idxtype>
5955     : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2" #
5956                       # "|" # size #"\t$dst$idx, $src$idx2}",
5957                 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;
5958
5959
5960 multiclass SIMDIns {
5961   def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {
5962     bits<4> idx;
5963     let Inst{20-17} = idx;
5964     let Inst{16} = 1;
5965   }
5966   def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {
5967     bits<3> idx;
5968     let Inst{20-18} = idx;
5969     let Inst{17-16} = 0b10;
5970   }
5971   def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {
5972     bits<2> idx;
5973     let Inst{20-19} = idx;
5974     let Inst{18-16} = 0b100;
5975   }
5976   def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {
5977     bits<1> idx;
5978     let Inst{20} = idx;
5979     let Inst{19-16} = 0b1000;
5980   }
5981
5982   def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {
5983     bits<4> idx;
5984     bits<4> idx2;
5985     let Inst{20-17} = idx;
5986     let Inst{16} = 1;
5987     let Inst{14-11} = idx2;
5988   }
5989   def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {
5990     bits<3> idx;
5991     bits<3> idx2;
5992     let Inst{20-18} = idx;
5993     let Inst{17-16} = 0b10;
5994     let Inst{14-12} = idx2;
5995     let Inst{11} = {?};
5996   }
5997   def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {
5998     bits<2> idx;
5999     bits<2> idx2;
6000     let Inst{20-19} = idx;
6001     let Inst{18-16} = 0b100;
6002     let Inst{14-13} = idx2;
6003     let Inst{12-11} = {?,?};
6004   }
6005   def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {
6006     bits<1> idx;
6007     bits<1> idx2;
6008     let Inst{20} = idx;
6009     let Inst{19-16} = 0b1000;
6010     let Inst{14} = idx2;
6011     let Inst{13-11} = {?,?,?};
6012   }
6013
6014   // For all forms of the INS instruction, the "mov" mnemonic is the
6015   // preferred alias. Why they didn't just call the instruction "mov" in
6016   // the first place is a very good question indeed...
6017   def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),
6018                          GPR32, VectorIndexB>;
6019   def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),
6020                          GPR32, VectorIndexH>;
6021   def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),
6022                          GPR32, VectorIndexS>;
6023   def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),
6024                          GPR64, VectorIndexD>;
6025
6026   def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),
6027                          VectorIndexB>;
6028   def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),
6029                          VectorIndexH>;
6030   def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),
6031                          VectorIndexS>;
6032   def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),
6033                          VectorIndexD>;
6034 }
6035
6036 //----------------------------------------------------------------------------
6037 // AdvSIMD TBL/TBX
6038 //----------------------------------------------------------------------------
6039
6040 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6041 class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6042                           RegisterOperand listtype, string asm, string kind>
6043   : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,
6044        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,
6045     Sched<[WriteV]> {
6046   bits<5> Vd;
6047   bits<5> Vn;
6048   bits<5> Vm;
6049   let Inst{31}    = 0;
6050   let Inst{30}    = Q;
6051   let Inst{29-21} = 0b001110000;
6052   let Inst{20-16} = Vm;
6053   let Inst{15}    = 0;
6054   let Inst{14-13} = len;
6055   let Inst{12}    = op;
6056   let Inst{11-10} = 0b00;
6057   let Inst{9-5}   = Vn;
6058   let Inst{4-0}   = Vd;
6059 }
6060
6061 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
6062 class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,
6063                           RegisterOperand listtype, string asm, string kind>
6064   : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,
6065        "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,
6066     Sched<[WriteV]> {
6067   bits<5> Vd;
6068   bits<5> Vn;
6069   bits<5> Vm;
6070   let Inst{31}    = 0;
6071   let Inst{30}    = Q;
6072   let Inst{29-21} = 0b001110000;
6073   let Inst{20-16} = Vm;
6074   let Inst{15}    = 0;
6075   let Inst{14-13} = len;
6076   let Inst{12}    = op;
6077   let Inst{11-10} = 0b00;
6078   let Inst{9-5}   = Vn;
6079   let Inst{4-0}   = Vd;
6080 }
6081
6082 class SIMDTableLookupAlias<string asm, Instruction inst,
6083                           RegisterOperand vectype, RegisterOperand listtype>
6084     : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),
6085                 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;
6086
6087 multiclass SIMDTableLookup<bit op, string asm> {
6088   def v8i8One   : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,
6089                                       asm, ".8b">;
6090   def v8i8Two   : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,
6091                                       asm, ".8b">;
6092   def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,
6093                                       asm, ".8b">;
6094   def v8i8Four  : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,
6095                                       asm, ".8b">;
6096   def v16i8One  : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,
6097                                       asm, ".16b">;
6098   def v16i8Two  : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,
6099                                       asm, ".16b">;
6100   def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,
6101                                       asm, ".16b">;
6102   def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,
6103                                       asm, ".16b">;
6104
6105   def : SIMDTableLookupAlias<asm # ".8b",
6106                          !cast<Instruction>(NAME#"v8i8One"),
6107                          V64, VecListOne128>;
6108   def : SIMDTableLookupAlias<asm # ".8b",
6109                          !cast<Instruction>(NAME#"v8i8Two"),
6110                          V64, VecListTwo128>;
6111   def : SIMDTableLookupAlias<asm # ".8b",
6112                          !cast<Instruction>(NAME#"v8i8Three"),
6113                          V64, VecListThree128>;
6114   def : SIMDTableLookupAlias<asm # ".8b",
6115                          !cast<Instruction>(NAME#"v8i8Four"),
6116                          V64, VecListFour128>;
6117   def : SIMDTableLookupAlias<asm # ".16b",
6118                          !cast<Instruction>(NAME#"v16i8One"),
6119                          V128, VecListOne128>;
6120   def : SIMDTableLookupAlias<asm # ".16b",
6121                          !cast<Instruction>(NAME#"v16i8Two"),
6122                          V128, VecListTwo128>;
6123   def : SIMDTableLookupAlias<asm # ".16b",
6124                          !cast<Instruction>(NAME#"v16i8Three"),
6125                          V128, VecListThree128>;
6126   def : SIMDTableLookupAlias<asm # ".16b",
6127                          !cast<Instruction>(NAME#"v16i8Four"),
6128                          V128, VecListFour128>;
6129 }
6130
6131 multiclass SIMDTableLookupTied<bit op, string asm> {
6132   def v8i8One   : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,
6133                                       asm, ".8b">;
6134   def v8i8Two   : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,
6135                                       asm, ".8b">;
6136   def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,
6137                                       asm, ".8b">;
6138   def v8i8Four  : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,
6139                                       asm, ".8b">;
6140   def v16i8One  : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,
6141                                       asm, ".16b">;
6142   def v16i8Two  : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,
6143                                       asm, ".16b">;
6144   def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,
6145                                       asm, ".16b">;
6146   def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,
6147                                       asm, ".16b">;
6148
6149   def : SIMDTableLookupAlias<asm # ".8b",
6150                          !cast<Instruction>(NAME#"v8i8One"),
6151                          V64, VecListOne128>;
6152   def : SIMDTableLookupAlias<asm # ".8b",
6153                          !cast<Instruction>(NAME#"v8i8Two"),
6154                          V64, VecListTwo128>;
6155   def : SIMDTableLookupAlias<asm # ".8b",
6156                          !cast<Instruction>(NAME#"v8i8Three"),
6157                          V64, VecListThree128>;
6158   def : SIMDTableLookupAlias<asm # ".8b",
6159                          !cast<Instruction>(NAME#"v8i8Four"),
6160                          V64, VecListFour128>;
6161   def : SIMDTableLookupAlias<asm # ".16b",
6162                          !cast<Instruction>(NAME#"v16i8One"),
6163                          V128, VecListOne128>;
6164   def : SIMDTableLookupAlias<asm # ".16b",
6165                          !cast<Instruction>(NAME#"v16i8Two"),
6166                          V128, VecListTwo128>;
6167   def : SIMDTableLookupAlias<asm # ".16b",
6168                          !cast<Instruction>(NAME#"v16i8Three"),
6169                          V128, VecListThree128>;
6170   def : SIMDTableLookupAlias<asm # ".16b",
6171                          !cast<Instruction>(NAME#"v16i8Four"),
6172                          V128, VecListFour128>;
6173 }
6174
6175
6176 //----------------------------------------------------------------------------
6177 // AdvSIMD scalar CPY
6178 //----------------------------------------------------------------------------
6179 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6180 class BaseSIMDScalarCPY<RegisterClass regtype, RegisterOperand vectype,
6181                         string kind, Operand idxtype>
6182   : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), "mov",
6183        "{\t$dst, $src" # kind # "$idx" #
6184        "|\t$dst, $src$idx}", "", []>,
6185     Sched<[WriteV]> {
6186   bits<5> dst;
6187   bits<5> src;
6188   let Inst{31-21} = 0b01011110000;
6189   let Inst{15-10} = 0b000001;
6190   let Inst{9-5}   = src;
6191   let Inst{4-0}   = dst;
6192 }
6193
6194 class SIMDScalarCPYAlias<string asm, string size, Instruction inst,
6195       RegisterClass regtype, RegisterOperand vectype, Operand idxtype>
6196     : InstAlias<asm # "{\t$dst, $src" # size # "$index" #
6197                     # "|\t$dst, $src$index}",
6198                 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;
6199
6200
6201 multiclass SIMDScalarCPY<string asm> {
6202   def i8  : BaseSIMDScalarCPY<FPR8,  V128, ".b", VectorIndexB> {
6203     bits<4> idx;
6204     let Inst{20-17} = idx;
6205     let Inst{16} = 1;
6206   }
6207   def i16 : BaseSIMDScalarCPY<FPR16, V128, ".h", VectorIndexH> {
6208     bits<3> idx;
6209     let Inst{20-18} = idx;
6210     let Inst{17-16} = 0b10;
6211   }
6212   def i32 : BaseSIMDScalarCPY<FPR32, V128, ".s", VectorIndexS> {
6213     bits<2> idx;
6214     let Inst{20-19} = idx;
6215     let Inst{18-16} = 0b100;
6216   }
6217   def i64 : BaseSIMDScalarCPY<FPR64, V128, ".d", VectorIndexD> {
6218     bits<1> idx;
6219     let Inst{20} = idx;
6220     let Inst{19-16} = 0b1000;
6221   }
6222
6223   def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),
6224                                                           VectorIndexD:$idx)))),
6225             (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;
6226
6227   // 'DUP' mnemonic aliases.
6228   def : SIMDScalarCPYAlias<"dup", ".b",
6229                            !cast<Instruction>(NAME#"i8"),
6230                            FPR8, V128, VectorIndexB>;
6231   def : SIMDScalarCPYAlias<"dup", ".h",
6232                            !cast<Instruction>(NAME#"i16"),
6233                            FPR16, V128, VectorIndexH>;
6234   def : SIMDScalarCPYAlias<"dup", ".s",
6235                            !cast<Instruction>(NAME#"i32"),
6236                            FPR32, V128, VectorIndexS>;
6237   def : SIMDScalarCPYAlias<"dup", ".d",
6238                            !cast<Instruction>(NAME#"i64"),
6239                            FPR64, V128, VectorIndexD>;
6240 }
6241
6242 //----------------------------------------------------------------------------
6243 // AdvSIMD modified immediate instructions
6244 //----------------------------------------------------------------------------
6245
6246 class BaseSIMDModifiedImm<bit Q, bit op, dag oops, dag iops,
6247                           string asm, string op_string,
6248                           string cstr, list<dag> pattern>
6249   : I<oops, iops, asm, op_string, cstr, pattern>,
6250     Sched<[WriteV]> {
6251   bits<5> Rd;
6252   bits<8> imm8;
6253   let Inst{31}    = 0;
6254   let Inst{30}    = Q;
6255   let Inst{29}    = op;
6256   let Inst{28-19} = 0b0111100000;
6257   let Inst{18-16} = imm8{7-5};
6258   let Inst{11-10} = 0b01;
6259   let Inst{9-5}   = imm8{4-0};
6260   let Inst{4-0}   = Rd;
6261 }
6262
6263 class BaseSIMDModifiedImmVector<bit Q, bit op, RegisterOperand vectype,
6264                                 Operand immtype, dag opt_shift_iop,
6265                                 string opt_shift, string asm, string kind,
6266                                 list<dag> pattern>
6267   : BaseSIMDModifiedImm<Q, op, (outs vectype:$Rd),
6268                         !con((ins immtype:$imm8), opt_shift_iop), asm,
6269                         "{\t$Rd" # kind # ", $imm8" # opt_shift #
6270                         "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6271                         "", pattern> {
6272   let DecoderMethod = "DecodeModImmInstruction";
6273 }
6274
6275 class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,
6276                                 Operand immtype, dag opt_shift_iop,
6277                                 string opt_shift, string asm, string kind,
6278                                 list<dag> pattern>
6279   : BaseSIMDModifiedImm<Q, op, (outs vectype:$dst),
6280                         !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),
6281                         asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #
6282                              "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",
6283                         "$Rd = $dst", pattern> {
6284   let DecoderMethod = "DecodeModImmTiedInstruction";
6285 }
6286
6287 class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,
6288                                      RegisterOperand vectype, string asm,
6289                                      string kind, list<dag> pattern>
6290   : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6291                               (ins logical_vec_shift:$shift),
6292                               "$shift", asm, kind, pattern> {
6293   bits<2> shift;
6294   let Inst{15}    = b15_b12{1};
6295   let Inst{14-13} = shift;
6296   let Inst{12}    = b15_b12{0};
6297 }
6298
6299 class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,
6300                                      RegisterOperand vectype, string asm,
6301                                      string kind, list<dag> pattern>
6302   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6303                               (ins logical_vec_shift:$shift),
6304                               "$shift", asm, kind, pattern> {
6305   bits<2> shift;
6306   let Inst{15}    = b15_b12{1};
6307   let Inst{14-13} = shift;
6308   let Inst{12}    = b15_b12{0};
6309 }
6310
6311
6312 class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,
6313                                          RegisterOperand vectype, string asm,
6314                                          string kind, list<dag> pattern>
6315   : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6316                               (ins logical_vec_hw_shift:$shift),
6317                               "$shift", asm, kind, pattern> {
6318   bits<2> shift;
6319   let Inst{15} = b15_b12{1};
6320   let Inst{14} = 0;
6321   let Inst{13} = shift{0};
6322   let Inst{12} = b15_b12{0};
6323 }
6324
6325 class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,
6326                                          RegisterOperand vectype, string asm,
6327                                          string kind, list<dag> pattern>
6328   : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,
6329                               (ins logical_vec_hw_shift:$shift),
6330                               "$shift", asm, kind, pattern> {
6331   bits<2> shift;
6332   let Inst{15} = b15_b12{1};
6333   let Inst{14} = 0;
6334   let Inst{13} = shift{0};
6335   let Inst{12} = b15_b12{0};
6336 }
6337
6338 multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,
6339                                       string asm> {
6340   def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,
6341                                                  asm, ".4h", []>;
6342   def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,
6343                                                  asm, ".8h", []>;
6344
6345   def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,
6346                                              asm, ".2s", []>;
6347   def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,
6348                                              asm, ".4s", []>;
6349 }
6350
6351 multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,
6352                                       bits<2> w_cmode, string asm,
6353                                       SDNode OpNode> {
6354   def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,
6355                                                  asm, ".4h",
6356              [(set (v4i16 V64:$dst), (OpNode V64:$Rd,
6357                                              imm0_255:$imm8,
6358                                              (i32 imm:$shift)))]>;
6359   def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,
6360                                                  asm, ".8h",
6361              [(set (v8i16 V128:$dst), (OpNode V128:$Rd,
6362                                               imm0_255:$imm8,
6363                                               (i32 imm:$shift)))]>;
6364
6365   def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,
6366                                              asm, ".2s",
6367              [(set (v2i32 V64:$dst), (OpNode V64:$Rd,
6368                                              imm0_255:$imm8,
6369                                              (i32 imm:$shift)))]>;
6370   def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,
6371                                              asm, ".4s",
6372              [(set (v4i32 V128:$dst), (OpNode V128:$Rd,
6373                                               imm0_255:$imm8,
6374                                               (i32 imm:$shift)))]>;
6375 }
6376
6377 class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,
6378                              RegisterOperand vectype, string asm,
6379                              string kind, list<dag> pattern>
6380   : BaseSIMDModifiedImmVector<Q, op, vectype, imm0_255,
6381                               (ins move_vec_shift:$shift),
6382                               "$shift", asm, kind, pattern> {
6383   bits<1> shift;
6384   let Inst{15-13} = cmode{3-1};
6385   let Inst{12}    = shift;
6386 }
6387
6388 class SIMDModifiedImmVectorNoShift<bit Q, bit op, bits<4> cmode,
6389                                    RegisterOperand vectype,
6390                                    Operand imm_type, string asm,
6391                                    string kind, list<dag> pattern>
6392   : BaseSIMDModifiedImmVector<Q, op, vectype, imm_type, (ins), "",
6393                               asm, kind, pattern> {
6394   let Inst{15-12} = cmode;
6395 }
6396
6397 class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,
6398                                    list<dag> pattern>
6399   : BaseSIMDModifiedImm<Q, op, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,
6400                         "\t$Rd, $imm8", "", pattern> {
6401   let Inst{15-12} = cmode;
6402   let DecoderMethod = "DecodeModImmInstruction";
6403 }
6404
6405 //----------------------------------------------------------------------------
6406 // AdvSIMD indexed element
6407 //----------------------------------------------------------------------------
6408
6409 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6410 class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6411                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
6412                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
6413                       string apple_kind, string dst_kind, string lhs_kind,
6414                       string rhs_kind, list<dag> pattern>
6415   : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),
6416       asm,
6417       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6418       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,
6419     Sched<[WriteV]> {
6420   bits<5> Rd;
6421   bits<5> Rn;
6422   bits<5> Rm;
6423
6424   let Inst{31}    = 0;
6425   let Inst{30}    = Q;
6426   let Inst{29}    = U;
6427   let Inst{28}    = Scalar;
6428   let Inst{27-24} = 0b1111;
6429   let Inst{23-22} = size;
6430   // Bit 21 must be set by the derived class.
6431   let Inst{20-16} = Rm;
6432   let Inst{15-12} = opc;
6433   // Bit 11 must be set by the derived class.
6434   let Inst{10}    = 0;
6435   let Inst{9-5}   = Rn;
6436   let Inst{4-0}   = Rd;
6437 }
6438
6439 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
6440 class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,
6441                       RegisterOperand dst_reg, RegisterOperand lhs_reg,
6442                       RegisterOperand rhs_reg, Operand vec_idx, string asm,
6443                       string apple_kind, string dst_kind, string lhs_kind,
6444                       string rhs_kind, list<dag> pattern>
6445   : I<(outs dst_reg:$dst),
6446       (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,
6447       "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #
6448       "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,
6449     Sched<[WriteV]> {
6450   bits<5> Rd;
6451   bits<5> Rn;
6452   bits<5> Rm;
6453
6454   let Inst{31}    = 0;
6455   let Inst{30}    = Q;
6456   let Inst{29}    = U;
6457   let Inst{28}    = Scalar;
6458   let Inst{27-24} = 0b1111;
6459   let Inst{23-22} = size;
6460   // Bit 21 must be set by the derived class.
6461   let Inst{20-16} = Rm;
6462   let Inst{15-12} = opc;
6463   // Bit 11 must be set by the derived class.
6464   let Inst{10}    = 0;
6465   let Inst{9-5}   = Rn;
6466   let Inst{4-0}   = Rd;
6467 }
6468
6469 multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,
6470                          SDPatternOperator OpNode> {
6471   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6472                                       V64, V64,
6473                                       V128, VectorIndexS,
6474                                       asm, ".2s", ".2s", ".2s", ".s",
6475     [(set (v2f32 V64:$Rd),
6476         (OpNode (v2f32 V64:$Rn),
6477          (v2f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6478     bits<2> idx;
6479     let Inst{11} = idx{1};
6480     let Inst{21} = idx{0};
6481   }
6482
6483   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6484                                       V128, V128,
6485                                       V128, VectorIndexS,
6486                                       asm, ".4s", ".4s", ".4s", ".s",
6487     [(set (v4f32 V128:$Rd),
6488         (OpNode (v4f32 V128:$Rn),
6489          (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {
6490     bits<2> idx;
6491     let Inst{11} = idx{1};
6492     let Inst{21} = idx{0};
6493   }
6494
6495   def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,
6496                                       V128, V128,
6497                                       V128, VectorIndexD,
6498                                       asm, ".2d", ".2d", ".2d", ".d",
6499     [(set (v2f64 V128:$Rd),
6500         (OpNode (v2f64 V128:$Rn),
6501          (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {
6502     bits<1> idx;
6503     let Inst{11} = idx{0};
6504     let Inst{21} = 0;
6505   }
6506
6507   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6508                                       FPR32Op, FPR32Op, V128, VectorIndexS,
6509                                       asm, ".s", "", "", ".s",
6510     [(set (f32 FPR32Op:$Rd),
6511           (OpNode (f32 FPR32Op:$Rn),
6512                   (f32 (vector_extract (v4f32 V128:$Rm),
6513                                        VectorIndexS:$idx))))]> {
6514     bits<2> idx;
6515     let Inst{11} = idx{1};
6516     let Inst{21} = idx{0};
6517   }
6518
6519   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,
6520                                       FPR64Op, FPR64Op, V128, VectorIndexD,
6521                                       asm, ".d", "", "", ".d",
6522     [(set (f64 FPR64Op:$Rd),
6523           (OpNode (f64 FPR64Op:$Rn),
6524                   (f64 (vector_extract (v2f64 V128:$Rm),
6525                                        VectorIndexD:$idx))))]> {
6526     bits<1> idx;
6527     let Inst{11} = idx{0};
6528     let Inst{21} = 0;
6529   }
6530 }
6531
6532 multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {
6533   // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.
6534   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6535                            (AArch64duplane32 (v4f32 V128:$Rm),
6536                                            VectorIndexS:$idx))),
6537             (!cast<Instruction>(INST # v2i32_indexed)
6538                 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6539   def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),
6540                            (AArch64dup (f32 FPR32Op:$Rm)))),
6541             (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,
6542                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6543
6544
6545   // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.
6546   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6547                            (AArch64duplane32 (v4f32 V128:$Rm),
6548                                            VectorIndexS:$idx))),
6549             (!cast<Instruction>(INST # "v4i32_indexed")
6550                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6551   def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),
6552                            (AArch64dup (f32 FPR32Op:$Rm)))),
6553             (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,
6554                 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;
6555
6556   // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.
6557   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6558                            (AArch64duplane64 (v2f64 V128:$Rm),
6559                                            VectorIndexD:$idx))),
6560             (!cast<Instruction>(INST # "v2i64_indexed")
6561                 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;
6562   def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),
6563                            (AArch64dup (f64 FPR64Op:$Rm)))),
6564             (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,
6565                 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;
6566
6567   // 2 variants for 32-bit scalar version: extract from .2s or from .4s
6568   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6569                          (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),
6570             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6571                 V128:$Rm, VectorIndexS:$idx)>;
6572   def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),
6573                          (vector_extract (v2f32 V64:$Rm), VectorIndexS:$idx))),
6574             (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,
6575                 (SUBREG_TO_REG (i32 0), V64:$Rm, dsub), VectorIndexS:$idx)>;
6576
6577   // 1 variant for 64-bit scalar version: extract from .1d or from .2d
6578   def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),
6579                          (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),
6580             (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,
6581                 V128:$Rm, VectorIndexD:$idx)>;
6582 }
6583
6584 multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {
6585   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,
6586                                           V128, VectorIndexS,
6587                                           asm, ".2s", ".2s", ".2s", ".s", []> {
6588     bits<2> idx;
6589     let Inst{11} = idx{1};
6590     let Inst{21} = idx{0};
6591   }
6592
6593   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6594                                       V128, V128,
6595                                       V128, VectorIndexS,
6596                                       asm, ".4s", ".4s", ".4s", ".s", []> {
6597     bits<2> idx;
6598     let Inst{11} = idx{1};
6599     let Inst{21} = idx{0};
6600   }
6601
6602   def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,
6603                                       V128, V128,
6604                                       V128, VectorIndexD,
6605                                       asm, ".2d", ".2d", ".2d", ".d", []> {
6606     bits<1> idx;
6607     let Inst{11} = idx{0};
6608     let Inst{21} = 0;
6609   }
6610
6611
6612   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6613                                       FPR32Op, FPR32Op, V128, VectorIndexS,
6614                                       asm, ".s", "", "", ".s", []> {
6615     bits<2> idx;
6616     let Inst{11} = idx{1};
6617     let Inst{21} = idx{0};
6618   }
6619
6620   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,
6621                                       FPR64Op, FPR64Op, V128, VectorIndexD,
6622                                       asm, ".d", "", "", ".d", []> {
6623     bits<1> idx;
6624     let Inst{11} = idx{0};
6625     let Inst{21} = 0;
6626   }
6627 }
6628
6629 multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,
6630                          SDPatternOperator OpNode> {
6631   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,
6632                                       V128_lo, VectorIndexH,
6633                                       asm, ".4h", ".4h", ".4h", ".h",
6634     [(set (v4i16 V64:$Rd),
6635         (OpNode (v4i16 V64:$Rn),
6636          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6637     bits<3> idx;
6638     let Inst{11} = idx{2};
6639     let Inst{21} = idx{1};
6640     let Inst{20} = idx{0};
6641   }
6642
6643   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6644                                       V128, V128,
6645                                       V128_lo, VectorIndexH,
6646                                       asm, ".8h", ".8h", ".8h", ".h",
6647     [(set (v8i16 V128:$Rd),
6648        (OpNode (v8i16 V128:$Rn),
6649          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6650     bits<3> idx;
6651     let Inst{11} = idx{2};
6652     let Inst{21} = idx{1};
6653     let Inst{20} = idx{0};
6654   }
6655
6656   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6657                                       V64, V64,
6658                                       V128, VectorIndexS,
6659                                       asm, ".2s", ".2s", ".2s",  ".s",
6660     [(set (v2i32 V64:$Rd),
6661        (OpNode (v2i32 V64:$Rn),
6662           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6663     bits<2> idx;
6664     let Inst{11} = idx{1};
6665     let Inst{21} = idx{0};
6666   }
6667
6668   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6669                                       V128, V128,
6670                                       V128, VectorIndexS,
6671                                       asm, ".4s", ".4s", ".4s", ".s",
6672     [(set (v4i32 V128:$Rd),
6673        (OpNode (v4i32 V128:$Rn),
6674           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6675     bits<2> idx;
6676     let Inst{11} = idx{1};
6677     let Inst{21} = idx{0};
6678   }
6679
6680   def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6681                                       FPR16Op, FPR16Op, V128_lo, VectorIndexH,
6682                                       asm, ".h", "", "", ".h", []> {
6683     bits<3> idx;
6684     let Inst{11} = idx{2};
6685     let Inst{21} = idx{1};
6686     let Inst{20} = idx{0};
6687   }
6688
6689   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6690                                       FPR32Op, FPR32Op, V128, VectorIndexS,
6691                                       asm, ".s", "", "", ".s",
6692       [(set (i32 FPR32Op:$Rd),
6693             (OpNode FPR32Op:$Rn,
6694                     (i32 (vector_extract (v4i32 V128:$Rm),
6695                                          VectorIndexS:$idx))))]> {
6696     bits<2> idx;
6697     let Inst{11} = idx{1};
6698     let Inst{21} = idx{0};
6699   }
6700 }
6701
6702 multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,
6703                                SDPatternOperator OpNode> {
6704   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6705                                       V64, V64,
6706                                       V128_lo, VectorIndexH,
6707                                       asm, ".4h", ".4h", ".4h", ".h",
6708     [(set (v4i16 V64:$Rd),
6709         (OpNode (v4i16 V64:$Rn),
6710          (v4i16 (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 v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6718                                       V128, V128,
6719                                       V128_lo, VectorIndexH,
6720                                       asm, ".8h", ".8h", ".8h", ".h",
6721     [(set (v8i16 V128:$Rd),
6722        (OpNode (v8i16 V128:$Rn),
6723          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6724     bits<3> idx;
6725     let Inst{11} = idx{2};
6726     let Inst{21} = idx{1};
6727     let Inst{20} = idx{0};
6728   }
6729
6730   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6731                                       V64, V64,
6732                                       V128, VectorIndexS,
6733                                       asm, ".2s", ".2s", ".2s", ".s",
6734     [(set (v2i32 V64:$Rd),
6735        (OpNode (v2i32 V64:$Rn),
6736           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6737     bits<2> idx;
6738     let Inst{11} = idx{1};
6739     let Inst{21} = idx{0};
6740   }
6741
6742   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6743                                       V128, V128,
6744                                       V128, VectorIndexS,
6745                                       asm, ".4s", ".4s", ".4s", ".s",
6746     [(set (v4i32 V128:$Rd),
6747        (OpNode (v4i32 V128:$Rn),
6748           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6749     bits<2> idx;
6750     let Inst{11} = idx{1};
6751     let Inst{21} = idx{0};
6752   }
6753 }
6754
6755 multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,
6756                                    SDPatternOperator OpNode> {
6757   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,
6758                                           V128_lo, VectorIndexH,
6759                                           asm, ".4h", ".4h", ".4h", ".h",
6760     [(set (v4i16 V64:$dst),
6761         (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),
6762          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6763     bits<3> idx;
6764     let Inst{11} = idx{2};
6765     let Inst{21} = idx{1};
6766     let Inst{20} = idx{0};
6767   }
6768
6769   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6770                                       V128, V128,
6771                                       V128_lo, VectorIndexH,
6772                                       asm, ".8h", ".8h", ".8h", ".h",
6773     [(set (v8i16 V128:$dst),
6774        (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
6775          (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6776     bits<3> idx;
6777     let Inst{11} = idx{2};
6778     let Inst{21} = idx{1};
6779     let Inst{20} = idx{0};
6780   }
6781
6782   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6783                                       V64, V64,
6784                                       V128, VectorIndexS,
6785                                       asm, ".2s", ".2s", ".2s", ".s",
6786     [(set (v2i32 V64:$dst),
6787        (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
6788           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6789     bits<2> idx;
6790     let Inst{11} = idx{1};
6791     let Inst{21} = idx{0};
6792   }
6793
6794   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6795                                       V128, V128,
6796                                       V128, VectorIndexS,
6797                                       asm, ".4s", ".4s", ".4s", ".s",
6798     [(set (v4i32 V128:$dst),
6799        (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
6800           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6801     bits<2> idx;
6802     let Inst{11} = idx{1};
6803     let Inst{21} = idx{0};
6804   }
6805 }
6806
6807 multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,
6808                              SDPatternOperator OpNode> {
6809   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6810                                       V128, V64,
6811                                       V128_lo, VectorIndexH,
6812                                       asm, ".4s", ".4s", ".4h", ".h",
6813     [(set (v4i32 V128:$Rd),
6814         (OpNode (v4i16 V64:$Rn),
6815          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6816     bits<3> idx;
6817     let Inst{11} = idx{2};
6818     let Inst{21} = idx{1};
6819     let Inst{20} = idx{0};
6820   }
6821
6822   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
6823                                       V128, V128,
6824                                       V128_lo, VectorIndexH,
6825                                       asm#"2", ".4s", ".4s", ".8h", ".h",
6826     [(set (v4i32 V128:$Rd),
6827           (OpNode (extract_high_v8i16 V128:$Rn),
6828                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6829                                                       VectorIndexH:$idx))))]> {
6830
6831     bits<3> idx;
6832     let Inst{11} = idx{2};
6833     let Inst{21} = idx{1};
6834     let Inst{20} = idx{0};
6835   }
6836
6837   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
6838                                       V128, V64,
6839                                       V128, VectorIndexS,
6840                                       asm, ".2d", ".2d", ".2s", ".s",
6841     [(set (v2i64 V128:$Rd),
6842         (OpNode (v2i32 V64:$Rn),
6843          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
6844     bits<2> idx;
6845     let Inst{11} = idx{1};
6846     let Inst{21} = idx{0};
6847   }
6848
6849   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
6850                                       V128, V128,
6851                                       V128, VectorIndexS,
6852                                       asm#"2", ".2d", ".2d", ".4s", ".s",
6853     [(set (v2i64 V128:$Rd),
6854           (OpNode (extract_high_v4i32 V128:$Rn),
6855                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
6856                                                       VectorIndexS:$idx))))]> {
6857     bits<2> idx;
6858     let Inst{11} = idx{1};
6859     let Inst{21} = idx{0};
6860   }
6861
6862   def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,
6863                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6864                                       asm, ".h", "", "", ".h", []> {
6865     bits<3> idx;
6866     let Inst{11} = idx{2};
6867     let Inst{21} = idx{1};
6868     let Inst{20} = idx{0};
6869   }
6870
6871   def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,
6872                                       FPR64Op, FPR32Op, V128, VectorIndexS,
6873                                       asm, ".s", "", "", ".s", []> {
6874     bits<2> idx;
6875     let Inst{11} = idx{1};
6876     let Inst{21} = idx{0};
6877   }
6878 }
6879
6880 multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,
6881                                        SDPatternOperator Accum> {
6882   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
6883                                       V128, V64,
6884                                       V128_lo, VectorIndexH,
6885                                       asm, ".4s", ".4s", ".4h", ".h",
6886     [(set (v4i32 V128:$dst),
6887           (Accum (v4i32 V128:$Rd),
6888                  (v4i32 (int_aarch64_neon_sqdmull
6889                              (v4i16 V64:$Rn),
6890                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6891                                                     VectorIndexH:$idx))))))]> {
6892     bits<3> idx;
6893     let Inst{11} = idx{2};
6894     let Inst{21} = idx{1};
6895     let Inst{20} = idx{0};
6896   }
6897
6898   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but an
6899   // intermediate EXTRACT_SUBREG would be untyped.
6900   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
6901                 (i32 (vector_extract (v4i32
6902                          (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),
6903                              (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6904                                                     VectorIndexH:$idx)))),
6905                          (i64 0))))),
6906             (EXTRACT_SUBREG
6907                 (!cast<Instruction>(NAME # v4i16_indexed)
6908                     (SUBREG_TO_REG (i32 0), FPR32Op:$Rd, ssub), V64:$Rn,
6909                     V128_lo:$Rm, VectorIndexH:$idx),
6910                 ssub)>;
6911
6912   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
6913                                       V128, V128,
6914                                       V128_lo, VectorIndexH,
6915                                       asm#"2", ".4s", ".4s", ".8h", ".h",
6916     [(set (v4i32 V128:$dst),
6917           (Accum (v4i32 V128:$Rd),
6918                  (v4i32 (int_aarch64_neon_sqdmull
6919                             (extract_high_v8i16 V128:$Rn),
6920                             (extract_high_v8i16
6921                                 (AArch64duplane16 (v8i16 V128_lo:$Rm),
6922                                                 VectorIndexH:$idx))))))]> {
6923     bits<3> idx;
6924     let Inst{11} = idx{2};
6925     let Inst{21} = idx{1};
6926     let Inst{20} = idx{0};
6927   }
6928
6929   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
6930                                       V128, V64,
6931                                       V128, VectorIndexS,
6932                                       asm, ".2d", ".2d", ".2s", ".s",
6933     [(set (v2i64 V128:$dst),
6934         (Accum (v2i64 V128:$Rd),
6935                (v2i64 (int_aarch64_neon_sqdmull
6936                           (v2i32 V64:$Rn),
6937                           (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
6938                                                  VectorIndexS:$idx))))))]> {
6939     bits<2> idx;
6940     let Inst{11} = idx{1};
6941     let Inst{21} = idx{0};
6942   }
6943
6944   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
6945                                       V128, V128,
6946                                       V128, VectorIndexS,
6947                                       asm#"2", ".2d", ".2d", ".4s", ".s",
6948     [(set (v2i64 V128:$dst),
6949           (Accum (v2i64 V128:$Rd),
6950                  (v2i64 (int_aarch64_neon_sqdmull
6951                             (extract_high_v4i32 V128:$Rn),
6952                             (extract_high_v4i32
6953                                 (AArch64duplane32 (v4i32 V128:$Rm),
6954                                                 VectorIndexS:$idx))))))]> {
6955     bits<2> idx;
6956     let Inst{11} = idx{1};
6957     let Inst{21} = idx{0};
6958   }
6959
6960   def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
6961                                       FPR32Op, FPR16Op, V128_lo, VectorIndexH,
6962                                       asm, ".h", "", "", ".h", []> {
6963     bits<3> idx;
6964     let Inst{11} = idx{2};
6965     let Inst{21} = idx{1};
6966     let Inst{20} = idx{0};
6967   }
6968
6969
6970   def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
6971                                       FPR64Op, FPR32Op, V128, VectorIndexS,
6972                                       asm, ".s", "", "", ".s",
6973     [(set (i64 FPR64Op:$dst),
6974           (Accum (i64 FPR64Op:$Rd),
6975                  (i64 (int_aarch64_neon_sqdmulls_scalar
6976                             (i32 FPR32Op:$Rn),
6977                             (i32 (vector_extract (v4i32 V128:$Rm),
6978                                                  VectorIndexS:$idx))))))]> {
6979
6980     bits<2> idx;
6981     let Inst{11} = idx{1};
6982     let Inst{21} = idx{0};
6983   }
6984 }
6985
6986 multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,
6987                                    SDPatternOperator OpNode> {
6988   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
6989   def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,
6990                                       V128, V64,
6991                                       V128_lo, VectorIndexH,
6992                                       asm, ".4s", ".4s", ".4h", ".h",
6993     [(set (v4i32 V128:$Rd),
6994         (OpNode (v4i16 V64:$Rn),
6995          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
6996     bits<3> idx;
6997     let Inst{11} = idx{2};
6998     let Inst{21} = idx{1};
6999     let Inst{20} = idx{0};
7000   }
7001
7002   def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,
7003                                       V128, V128,
7004                                       V128_lo, VectorIndexH,
7005                                       asm#"2", ".4s", ".4s", ".8h", ".h",
7006     [(set (v4i32 V128:$Rd),
7007           (OpNode (extract_high_v8i16 V128:$Rn),
7008                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7009                                                       VectorIndexH:$idx))))]> {
7010
7011     bits<3> idx;
7012     let Inst{11} = idx{2};
7013     let Inst{21} = idx{1};
7014     let Inst{20} = idx{0};
7015   }
7016
7017   def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,
7018                                       V128, V64,
7019                                       V128, VectorIndexS,
7020                                       asm, ".2d", ".2d", ".2s", ".s",
7021     [(set (v2i64 V128:$Rd),
7022         (OpNode (v2i32 V64:$Rn),
7023          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7024     bits<2> idx;
7025     let Inst{11} = idx{1};
7026     let Inst{21} = idx{0};
7027   }
7028
7029   def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,
7030                                       V128, V128,
7031                                       V128, VectorIndexS,
7032                                       asm#"2", ".2d", ".2d", ".4s", ".s",
7033     [(set (v2i64 V128:$Rd),
7034           (OpNode (extract_high_v4i32 V128:$Rn),
7035                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7036                                                       VectorIndexS:$idx))))]> {
7037     bits<2> idx;
7038     let Inst{11} = idx{1};
7039     let Inst{21} = idx{0};
7040   }
7041   }
7042 }
7043
7044 multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,
7045                                        SDPatternOperator OpNode> {
7046   let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {
7047   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
7048                                       V128, V64,
7049                                       V128_lo, VectorIndexH,
7050                                       asm, ".4s", ".4s", ".4h", ".h",
7051     [(set (v4i32 V128:$dst),
7052         (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),
7053          (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {
7054     bits<3> idx;
7055     let Inst{11} = idx{2};
7056     let Inst{21} = idx{1};
7057     let Inst{20} = idx{0};
7058   }
7059
7060   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
7061                                       V128, V128,
7062                                       V128_lo, VectorIndexH,
7063                                       asm#"2", ".4s", ".4s", ".8h", ".h",
7064     [(set (v4i32 V128:$dst),
7065           (OpNode (v4i32 V128:$Rd),
7066                   (extract_high_v8i16 V128:$Rn),
7067                   (extract_high_v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
7068                                                       VectorIndexH:$idx))))]> {
7069     bits<3> idx;
7070     let Inst{11} = idx{2};
7071     let Inst{21} = idx{1};
7072     let Inst{20} = idx{0};
7073   }
7074
7075   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
7076                                       V128, V64,
7077                                       V128, VectorIndexS,
7078                                       asm, ".2d", ".2d", ".2s", ".s",
7079     [(set (v2i64 V128:$dst),
7080         (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),
7081          (v2i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {
7082     bits<2> idx;
7083     let Inst{11} = idx{1};
7084     let Inst{21} = idx{0};
7085   }
7086
7087   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
7088                                       V128, V128,
7089                                       V128, VectorIndexS,
7090                                       asm#"2", ".2d", ".2d", ".4s", ".s",
7091     [(set (v2i64 V128:$dst),
7092           (OpNode (v2i64 V128:$Rd),
7093                   (extract_high_v4i32 V128:$Rn),
7094                   (extract_high_v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
7095                                                       VectorIndexS:$idx))))]> {
7096     bits<2> idx;
7097     let Inst{11} = idx{1};
7098     let Inst{21} = idx{0};
7099   }
7100   }
7101 }
7102
7103 //----------------------------------------------------------------------------
7104 // AdvSIMD scalar shift by immediate
7105 //----------------------------------------------------------------------------
7106
7107 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7108 class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,
7109                      RegisterClass regtype1, RegisterClass regtype2,
7110                      Operand immtype, string asm, list<dag> pattern>
7111   : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),
7112       asm, "\t$Rd, $Rn, $imm", "", pattern>,
7113     Sched<[WriteV]> {
7114   bits<5> Rd;
7115   bits<5> Rn;
7116   bits<7> imm;
7117   let Inst{31-30} = 0b01;
7118   let Inst{29}    = U;
7119   let Inst{28-23} = 0b111110;
7120   let Inst{22-16} = fixed_imm;
7121   let Inst{15-11} = opc;
7122   let Inst{10}    = 1;
7123   let Inst{9-5} = Rn;
7124   let Inst{4-0} = Rd;
7125 }
7126
7127 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7128 class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,
7129                      RegisterClass regtype1, RegisterClass regtype2,
7130                      Operand immtype, string asm, list<dag> pattern>
7131   : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),
7132       asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,
7133     Sched<[WriteV]> {
7134   bits<5> Rd;
7135   bits<5> Rn;
7136   bits<7> imm;
7137   let Inst{31-30} = 0b01;
7138   let Inst{29}    = U;
7139   let Inst{28-23} = 0b111110;
7140   let Inst{22-16} = fixed_imm;
7141   let Inst{15-11} = opc;
7142   let Inst{10}    = 1;
7143   let Inst{9-5} = Rn;
7144   let Inst{4-0} = Rd;
7145 }
7146
7147
7148 multiclass SIMDScalarRShiftSD<bit U, bits<5> opc, string asm> {
7149   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7150                               FPR32, FPR32, vecshiftR32, asm, []> {
7151     let Inst{20-16} = imm{4-0};
7152   }
7153
7154   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7155                               FPR64, FPR64, vecshiftR64, asm, []> {
7156     let Inst{21-16} = imm{5-0};
7157   }
7158 }
7159
7160 multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,
7161                              SDPatternOperator OpNode> {
7162   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7163                               FPR64, FPR64, vecshiftR64, asm,
7164   [(set (i64 FPR64:$Rd),
7165      (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {
7166     let Inst{21-16} = imm{5-0};
7167   }
7168
7169   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),
7170             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;
7171 }
7172
7173 multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,
7174                                  SDPatternOperator OpNode = null_frag> {
7175   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7176                               FPR64, FPR64, vecshiftR64, asm,
7177   [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn),
7178                                                    (i32 vecshiftR64:$imm)))]> {
7179     let Inst{21-16} = imm{5-0};
7180   }
7181
7182   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),
7183                            (i32 vecshiftR64:$imm))),
7184             (!cast<Instruction>(NAME # "d") FPR64:$Rd, FPR64:$Rn,
7185                                             vecshiftR64:$imm)>;
7186 }
7187
7188 multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,
7189                              SDPatternOperator OpNode> {
7190   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7191                               FPR64, FPR64, vecshiftL64, asm,
7192     [(set (v1i64 FPR64:$Rd),
7193        (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7194     let Inst{21-16} = imm{5-0};
7195   }
7196 }
7197
7198 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7199 multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm> {
7200   def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},
7201                               FPR64, FPR64, vecshiftL64, asm, []> {
7202     let Inst{21-16} = imm{5-0};
7203   }
7204 }
7205
7206 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7207 multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,
7208                                SDPatternOperator OpNode = null_frag> {
7209   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7210                               FPR8, FPR16, vecshiftR8, asm, []> {
7211     let Inst{18-16} = imm{2-0};
7212   }
7213
7214   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7215                               FPR16, FPR32, vecshiftR16, asm, []> {
7216     let Inst{19-16} = imm{3-0};
7217   }
7218
7219   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7220                               FPR32, FPR64, vecshiftR32, asm,
7221     [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {
7222     let Inst{20-16} = imm{4-0};
7223   }
7224 }
7225
7226 multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,
7227                                 SDPatternOperator OpNode> {
7228   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7229                               FPR8, FPR8, vecshiftL8, asm, []> {
7230     let Inst{18-16} = imm{2-0};
7231   }
7232
7233   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7234                               FPR16, FPR16, vecshiftL16, asm, []> {
7235     let Inst{19-16} = imm{3-0};
7236   }
7237
7238   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7239                               FPR32, FPR32, vecshiftL32, asm,
7240     [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {
7241     let Inst{20-16} = imm{4-0};
7242   }
7243
7244   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7245                               FPR64, FPR64, vecshiftL64, asm,
7246     [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {
7247     let Inst{21-16} = imm{5-0};
7248   }
7249
7250   def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),
7251             (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;
7252 }
7253
7254 multiclass SIMDScalarRShiftBHSD<bit U, bits<5> opc, string asm> {
7255   def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},
7256                               FPR8, FPR8, vecshiftR8, asm, []> {
7257     let Inst{18-16} = imm{2-0};
7258   }
7259
7260   def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},
7261                               FPR16, FPR16, vecshiftR16, asm, []> {
7262     let Inst{19-16} = imm{3-0};
7263   }
7264
7265   def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},
7266                               FPR32, FPR32, vecshiftR32, asm, []> {
7267     let Inst{20-16} = imm{4-0};
7268   }
7269
7270   def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},
7271                               FPR64, FPR64, vecshiftR64, asm, []> {
7272     let Inst{21-16} = imm{5-0};
7273   }
7274 }
7275
7276 //----------------------------------------------------------------------------
7277 // AdvSIMD vector x indexed element
7278 //----------------------------------------------------------------------------
7279
7280 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7281 class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7282                      RegisterOperand dst_reg, RegisterOperand src_reg,
7283                      Operand immtype,
7284                      string asm, string dst_kind, string src_kind,
7285                      list<dag> pattern>
7286   : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),
7287       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7288            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,
7289     Sched<[WriteV]> {
7290   bits<5> Rd;
7291   bits<5> Rn;
7292   let Inst{31}    = 0;
7293   let Inst{30}    = Q;
7294   let Inst{29}    = U;
7295   let Inst{28-23} = 0b011110;
7296   let Inst{22-16} = fixed_imm;
7297   let Inst{15-11} = opc;
7298   let Inst{10}    = 1;
7299   let Inst{9-5}   = Rn;
7300   let Inst{4-0}   = Rd;
7301 }
7302
7303 let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in
7304 class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,
7305                      RegisterOperand vectype1, RegisterOperand vectype2,
7306                      Operand immtype,
7307                      string asm, string dst_kind, string src_kind,
7308                      list<dag> pattern>
7309   : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),
7310       asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #
7311            "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,
7312     Sched<[WriteV]> {
7313   bits<5> Rd;
7314   bits<5> Rn;
7315   let Inst{31}    = 0;
7316   let Inst{30}    = Q;
7317   let Inst{29}    = U;
7318   let Inst{28-23} = 0b011110;
7319   let Inst{22-16} = fixed_imm;
7320   let Inst{15-11} = opc;
7321   let Inst{10}    = 1;
7322   let Inst{9-5}   = Rn;
7323   let Inst{4-0}   = Rd;
7324 }
7325
7326 multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,
7327                               Intrinsic OpNode> {
7328   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7329                                   V64, V64, vecshiftR32,
7330                                   asm, ".2s", ".2s",
7331       [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 imm:$imm)))]> {
7332     bits<5> imm;
7333     let Inst{20-16} = imm;
7334   }
7335
7336   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7337                                   V128, V128, vecshiftR32,
7338                                   asm, ".4s", ".4s",
7339       [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 imm:$imm)))]> {
7340     bits<5> imm;
7341     let Inst{20-16} = imm;
7342   }
7343
7344   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7345                                   V128, V128, vecshiftR64,
7346                                   asm, ".2d", ".2d",
7347       [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 imm:$imm)))]> {
7348     bits<6> imm;
7349     let Inst{21-16} = imm;
7350   }
7351 }
7352
7353 multiclass SIMDVectorRShiftSDToFP<bit U, bits<5> opc, string asm,
7354                                   Intrinsic OpNode> {
7355   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7356                                   V64, V64, vecshiftR32,
7357                                   asm, ".2s", ".2s",
7358       [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 imm:$imm)))]> {
7359     bits<5> imm;
7360     let Inst{20-16} = imm;
7361   }
7362
7363   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7364                                   V128, V128, vecshiftR32,
7365                                   asm, ".4s", ".4s",
7366       [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 imm:$imm)))]> {
7367     bits<5> imm;
7368     let Inst{20-16} = imm;
7369   }
7370
7371   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7372                                   V128, V128, vecshiftR64,
7373                                   asm, ".2d", ".2d",
7374       [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 imm:$imm)))]> {
7375     bits<6> imm;
7376     let Inst{21-16} = imm;
7377   }
7378 }
7379
7380 multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,
7381                                      SDPatternOperator OpNode> {
7382   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7383                                   V64, V128, vecshiftR16Narrow,
7384                                   asm, ".8b", ".8h",
7385       [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {
7386     bits<3> imm;
7387     let Inst{18-16} = imm;
7388   }
7389
7390   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7391                                   V128, V128, vecshiftR16Narrow,
7392                                   asm#"2", ".16b", ".8h", []> {
7393     bits<3> imm;
7394     let Inst{18-16} = imm;
7395     let hasSideEffects = 0;
7396   }
7397
7398   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7399                                   V64, V128, vecshiftR32Narrow,
7400                                   asm, ".4h", ".4s",
7401       [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {
7402     bits<4> imm;
7403     let Inst{19-16} = imm;
7404   }
7405
7406   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7407                                   V128, V128, vecshiftR32Narrow,
7408                                   asm#"2", ".8h", ".4s", []> {
7409     bits<4> imm;
7410     let Inst{19-16} = imm;
7411     let hasSideEffects = 0;
7412   }
7413
7414   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7415                                   V64, V128, vecshiftR64Narrow,
7416                                   asm, ".2s", ".2d",
7417       [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {
7418     bits<5> imm;
7419     let Inst{20-16} = imm;
7420   }
7421
7422   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7423                                   V128, V128, vecshiftR64Narrow,
7424                                   asm#"2", ".4s", ".2d", []> {
7425     bits<5> imm;
7426     let Inst{20-16} = imm;
7427     let hasSideEffects = 0;
7428   }
7429
7430   // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions
7431   // themselves, so put them here instead.
7432
7433   // Patterns involving what's effectively an insert high and a normal
7434   // intrinsic, represented by CONCAT_VECTORS.
7435   def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),
7436                                                    vecshiftR16Narrow:$imm)),
7437             (!cast<Instruction>(NAME # "v16i8_shift")
7438                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7439                 V128:$Rn, vecshiftR16Narrow:$imm)>;
7440   def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),
7441                                                      vecshiftR32Narrow:$imm)),
7442             (!cast<Instruction>(NAME # "v8i16_shift")
7443                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7444                 V128:$Rn, vecshiftR32Narrow:$imm)>;
7445   def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),
7446                                                      vecshiftR64Narrow:$imm)),
7447             (!cast<Instruction>(NAME # "v4i32_shift")
7448                 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),
7449                 V128:$Rn, vecshiftR64Narrow:$imm)>;
7450 }
7451
7452 multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,
7453                                 SDPatternOperator OpNode> {
7454   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7455                                   V64, V64, vecshiftL8,
7456                                   asm, ".8b", ".8b",
7457                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7458                        (i32 vecshiftL8:$imm)))]> {
7459     bits<3> imm;
7460     let Inst{18-16} = imm;
7461   }
7462
7463   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7464                                   V128, V128, vecshiftL8,
7465                                   asm, ".16b", ".16b",
7466              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7467                    (i32 vecshiftL8:$imm)))]> {
7468     bits<3> imm;
7469     let Inst{18-16} = imm;
7470   }
7471
7472   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7473                                   V64, V64, vecshiftL16,
7474                                   asm, ".4h", ".4h",
7475               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7476                     (i32 vecshiftL16:$imm)))]> {
7477     bits<4> imm;
7478     let Inst{19-16} = imm;
7479   }
7480
7481   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7482                                   V128, V128, vecshiftL16,
7483                                   asm, ".8h", ".8h",
7484             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7485                   (i32 vecshiftL16:$imm)))]> {
7486     bits<4> imm;
7487     let Inst{19-16} = imm;
7488   }
7489
7490   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7491                                   V64, V64, vecshiftL32,
7492                                   asm, ".2s", ".2s",
7493               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7494                     (i32 vecshiftL32:$imm)))]> {
7495     bits<5> imm;
7496     let Inst{20-16} = imm;
7497   }
7498
7499   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7500                                   V128, V128, vecshiftL32,
7501                                   asm, ".4s", ".4s",
7502             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7503                   (i32 vecshiftL32:$imm)))]> {
7504     bits<5> imm;
7505     let Inst{20-16} = imm;
7506   }
7507
7508   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7509                                   V128, V128, vecshiftL64,
7510                                   asm, ".2d", ".2d",
7511             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7512                   (i32 vecshiftL64:$imm)))]> {
7513     bits<6> imm;
7514     let Inst{21-16} = imm;
7515   }
7516 }
7517
7518 multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,
7519                                 SDPatternOperator OpNode> {
7520   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7521                                   V64, V64, vecshiftR8,
7522                                   asm, ".8b", ".8b",
7523                  [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),
7524                        (i32 vecshiftR8:$imm)))]> {
7525     bits<3> imm;
7526     let Inst{18-16} = imm;
7527   }
7528
7529   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7530                                   V128, V128, vecshiftR8,
7531                                   asm, ".16b", ".16b",
7532              [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),
7533                    (i32 vecshiftR8:$imm)))]> {
7534     bits<3> imm;
7535     let Inst{18-16} = imm;
7536   }
7537
7538   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7539                                   V64, V64, vecshiftR16,
7540                                   asm, ".4h", ".4h",
7541               [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),
7542                     (i32 vecshiftR16:$imm)))]> {
7543     bits<4> imm;
7544     let Inst{19-16} = imm;
7545   }
7546
7547   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7548                                   V128, V128, vecshiftR16,
7549                                   asm, ".8h", ".8h",
7550             [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),
7551                   (i32 vecshiftR16:$imm)))]> {
7552     bits<4> imm;
7553     let Inst{19-16} = imm;
7554   }
7555
7556   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7557                                   V64, V64, vecshiftR32,
7558                                   asm, ".2s", ".2s",
7559               [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),
7560                     (i32 vecshiftR32:$imm)))]> {
7561     bits<5> imm;
7562     let Inst{20-16} = imm;
7563   }
7564
7565   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7566                                   V128, V128, vecshiftR32,
7567                                   asm, ".4s", ".4s",
7568             [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),
7569                   (i32 vecshiftR32:$imm)))]> {
7570     bits<5> imm;
7571     let Inst{20-16} = imm;
7572   }
7573
7574   def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},
7575                                   V128, V128, vecshiftR64,
7576                                   asm, ".2d", ".2d",
7577             [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),
7578                   (i32 vecshiftR64:$imm)))]> {
7579     bits<6> imm;
7580     let Inst{21-16} = imm;
7581   }
7582 }
7583
7584 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
7585 multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,
7586                                     SDPatternOperator OpNode = null_frag> {
7587   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7588                                   V64, V64, vecshiftR8, asm, ".8b", ".8b",
7589                  [(set (v8i8 V64:$dst),
7590                    (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7591                            (i32 vecshiftR8:$imm)))]> {
7592     bits<3> imm;
7593     let Inst{18-16} = imm;
7594   }
7595
7596   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7597                                   V128, V128, vecshiftR8, asm, ".16b", ".16b",
7598              [(set (v16i8 V128:$dst),
7599                (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7600                        (i32 vecshiftR8:$imm)))]> {
7601     bits<3> imm;
7602     let Inst{18-16} = imm;
7603   }
7604
7605   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7606                                   V64, V64, vecshiftR16, asm, ".4h", ".4h",
7607               [(set (v4i16 V64:$dst),
7608                 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7609                         (i32 vecshiftR16:$imm)))]> {
7610     bits<4> imm;
7611     let Inst{19-16} = imm;
7612   }
7613
7614   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7615                                   V128, V128, vecshiftR16, asm, ".8h", ".8h",
7616             [(set (v8i16 V128:$dst),
7617               (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7618                       (i32 vecshiftR16:$imm)))]> {
7619     bits<4> imm;
7620     let Inst{19-16} = imm;
7621   }
7622
7623   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7624                                   V64, V64, vecshiftR32, asm, ".2s", ".2s",
7625               [(set (v2i32 V64:$dst),
7626                 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7627                         (i32 vecshiftR32:$imm)))]> {
7628     bits<5> imm;
7629     let Inst{20-16} = imm;
7630   }
7631
7632   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7633                                   V128, V128, vecshiftR32, asm, ".4s", ".4s",
7634             [(set (v4i32 V128:$dst),
7635               (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7636                       (i32 vecshiftR32:$imm)))]> {
7637     bits<5> imm;
7638     let Inst{20-16} = imm;
7639   }
7640
7641   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7642                                   V128, V128, vecshiftR64,
7643                                   asm, ".2d", ".2d", [(set (v2i64 V128:$dst),
7644               (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7645                       (i32 vecshiftR64:$imm)))]> {
7646     bits<6> imm;
7647     let Inst{21-16} = imm;
7648   }
7649 }
7650
7651 multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,
7652                                     SDPatternOperator OpNode = null_frag> {
7653   def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},
7654                                   V64, V64, vecshiftL8,
7655                                   asm, ".8b", ".8b",
7656                     [(set (v8i8 V64:$dst),
7657                           (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),
7658                                   (i32 vecshiftL8:$imm)))]> {
7659     bits<3> imm;
7660     let Inst{18-16} = imm;
7661   }
7662
7663   def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},
7664                                   V128, V128, vecshiftL8,
7665                                   asm, ".16b", ".16b",
7666                     [(set (v16i8 V128:$dst),
7667                           (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),
7668                                   (i32 vecshiftL8:$imm)))]> {
7669     bits<3> imm;
7670     let Inst{18-16} = imm;
7671   }
7672
7673   def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},
7674                                   V64, V64, vecshiftL16,
7675                                   asm, ".4h", ".4h",
7676                     [(set (v4i16 V64:$dst),
7677                            (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),
7678                                    (i32 vecshiftL16:$imm)))]> {
7679     bits<4> imm;
7680     let Inst{19-16} = imm;
7681   }
7682
7683   def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},
7684                                   V128, V128, vecshiftL16,
7685                                   asm, ".8h", ".8h",
7686                     [(set (v8i16 V128:$dst),
7687                           (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),
7688                                   (i32 vecshiftL16:$imm)))]> {
7689     bits<4> imm;
7690     let Inst{19-16} = imm;
7691   }
7692
7693   def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},
7694                                   V64, V64, vecshiftL32,
7695                                   asm, ".2s", ".2s",
7696                     [(set (v2i32 V64:$dst),
7697                           (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),
7698                                   (i32 vecshiftL32:$imm)))]> {
7699     bits<5> imm;
7700     let Inst{20-16} = imm;
7701   }
7702
7703   def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},
7704                                   V128, V128, vecshiftL32,
7705                                   asm, ".4s", ".4s",
7706                     [(set (v4i32 V128:$dst),
7707                           (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
7708                                   (i32 vecshiftL32:$imm)))]> {
7709     bits<5> imm;
7710     let Inst{20-16} = imm;
7711   }
7712
7713   def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},
7714                                   V128, V128, vecshiftL64,
7715                                   asm, ".2d", ".2d",
7716                     [(set (v2i64 V128:$dst),
7717                           (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),
7718                                   (i32 vecshiftL64:$imm)))]> {
7719     bits<6> imm;
7720     let Inst{21-16} = imm;
7721   }
7722 }
7723
7724 multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,
7725                                    SDPatternOperator OpNode> {
7726   def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},
7727                                   V128, V64, vecshiftL8, asm, ".8h", ".8b",
7728       [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {
7729     bits<3> imm;
7730     let Inst{18-16} = imm;
7731   }
7732
7733   def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},
7734                                   V128, V128, vecshiftL8,
7735                                   asm#"2", ".8h", ".16b",
7736       [(set (v8i16 V128:$Rd),
7737             (OpNode (extract_high_v16i8 V128:$Rn), vecshiftL8:$imm))]> {
7738     bits<3> imm;
7739     let Inst{18-16} = imm;
7740   }
7741
7742   def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},
7743                                   V128, V64, vecshiftL16, asm, ".4s", ".4h",
7744       [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {
7745     bits<4> imm;
7746     let Inst{19-16} = imm;
7747   }
7748
7749   def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},
7750                                   V128, V128, vecshiftL16,
7751                                   asm#"2", ".4s", ".8h",
7752       [(set (v4i32 V128:$Rd),
7753             (OpNode (extract_high_v8i16 V128:$Rn), vecshiftL16:$imm))]> {
7754
7755     bits<4> imm;
7756     let Inst{19-16} = imm;
7757   }
7758
7759   def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},
7760                                   V128, V64, vecshiftL32, asm, ".2d", ".2s",
7761       [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {
7762     bits<5> imm;
7763     let Inst{20-16} = imm;
7764   }
7765
7766   def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},
7767                                   V128, V128, vecshiftL32,
7768                                   asm#"2", ".2d", ".4s",
7769       [(set (v2i64 V128:$Rd),
7770             (OpNode (extract_high_v4i32 V128:$Rn), vecshiftL32:$imm))]> {
7771     bits<5> imm;
7772     let Inst{20-16} = imm;
7773   }
7774 }
7775
7776
7777 //---
7778 // Vector load/store
7779 //---
7780 // SIMD ldX/stX no-index memory references don't allow the optional
7781 // ", #0" constant and handle post-indexing explicitly, so we use
7782 // a more specialized parse method for them. Otherwise, it's the same as
7783 // the general GPR64sp handling.
7784
7785 class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,
7786                    string asm, dag oops, dag iops, list<dag> pattern>
7787   : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {
7788   bits<5> Vt;
7789   bits<5> Rn;
7790   let Inst{31} = 0;
7791   let Inst{30} = Q;
7792   let Inst{29-23} = 0b0011000;
7793   let Inst{22} = L;
7794   let Inst{21-16} = 0b000000;
7795   let Inst{15-12} = opcode;
7796   let Inst{11-10} = size;
7797   let Inst{9-5} = Rn;
7798   let Inst{4-0} = Vt;
7799 }
7800
7801 class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,
7802                        string asm, dag oops, dag iops>
7803   : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {
7804   bits<5> Vt;
7805   bits<5> Rn;
7806   bits<5> Xm;
7807   let Inst{31} = 0;
7808   let Inst{30} = Q;
7809   let Inst{29-23} = 0b0011001;
7810   let Inst{22} = L;
7811   let Inst{21} = 0;
7812   let Inst{20-16} = Xm;
7813   let Inst{15-12} = opcode;
7814   let Inst{11-10} = size;
7815   let Inst{9-5} = Rn;
7816   let Inst{4-0} = Vt;
7817 }
7818
7819 // The immediate form of AdvSIMD post-indexed addressing is encoded with
7820 // register post-index addressing from the zero register.
7821 multiclass SIMDLdStAliases<string asm, string layout, string Count,
7822                            int Offset, int Size> {
7823   // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"
7824   //      "ld1\t$Vt, [$Rn], #16"
7825   // may get mapped to
7826   //      (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)
7827   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
7828                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7829                       GPR64sp:$Rn,
7830                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
7831                       XZR), 1>;
7832
7833   // E.g. "ld1.8b { v0, v1 }, [x1], #16"
7834   //      "ld1.8b\t$Vt, [$Rn], #16"
7835   // may get mapped to
7836   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)
7837   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
7838                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7839                       GPR64sp:$Rn,
7840                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7841                       XZR), 0>;
7842
7843   // E.g. "ld1.8b { v0, v1 }, [x1]"
7844   //      "ld1\t$Vt, [$Rn]"
7845   // may get mapped to
7846   //      (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)
7847   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
7848                   (!cast<Instruction>(NAME # Count # "v" # layout)
7849                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7850                       GPR64sp:$Rn), 0>;
7851
7852   // E.g. "ld1.8b { v0, v1 }, [x1], x2"
7853   //      "ld1\t$Vt, [$Rn], $Xm"
7854   // may get mapped to
7855   //      (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)
7856   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
7857                   (!cast<Instruction>(NAME # Count # "v" # layout # "_POST")
7858                       GPR64sp:$Rn,
7859                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
7860                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
7861 }
7862
7863 multiclass BaseSIMDLdN<string Count, string asm, string veclist, int Offset128,
7864                        int Offset64, bits<4> opcode> {
7865   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
7866     def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,
7867                            (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),
7868                            (ins GPR64sp:$Rn), []>;
7869     def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,
7870                            (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),
7871                            (ins GPR64sp:$Rn), []>;
7872     def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,
7873                            (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),
7874                            (ins GPR64sp:$Rn), []>;
7875     def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,
7876                            (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),
7877                            (ins GPR64sp:$Rn), []>;
7878     def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,
7879                            (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),
7880                            (ins GPR64sp:$Rn), []>;
7881     def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,
7882                            (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),
7883                            (ins GPR64sp:$Rn), []>;
7884     def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,
7885                            (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),
7886                            (ins GPR64sp:$Rn), []>;
7887
7888
7889     def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,
7890                        (outs GPR64sp:$wback,
7891                              !cast<RegisterOperand>(veclist # "16b"):$Vt),
7892                        (ins GPR64sp:$Rn,
7893                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7894     def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,
7895                        (outs GPR64sp:$wback,
7896                              !cast<RegisterOperand>(veclist # "8h"):$Vt),
7897                        (ins GPR64sp:$Rn,
7898                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7899     def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,
7900                        (outs GPR64sp:$wback,
7901                              !cast<RegisterOperand>(veclist # "4s"):$Vt),
7902                        (ins GPR64sp:$Rn,
7903                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7904     def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,
7905                        (outs GPR64sp:$wback,
7906                              !cast<RegisterOperand>(veclist # "2d"):$Vt),
7907                        (ins GPR64sp:$Rn,
7908                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7909     def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,
7910                        (outs GPR64sp:$wback,
7911                              !cast<RegisterOperand>(veclist # "8b"):$Vt),
7912                        (ins GPR64sp:$Rn,
7913                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7914     def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,
7915                        (outs GPR64sp:$wback,
7916                              !cast<RegisterOperand>(veclist # "4h"):$Vt),
7917                        (ins GPR64sp:$Rn,
7918                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7919     def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,
7920                        (outs GPR64sp:$wback,
7921                              !cast<RegisterOperand>(veclist # "2s"):$Vt),
7922                        (ins GPR64sp:$Rn,
7923                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7924   }
7925
7926   defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
7927   defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
7928   defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
7929   defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
7930   defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
7931   defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
7932   defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
7933 }
7934
7935 // Only ld1/st1 has a v1d version.
7936 multiclass BaseSIMDStN<string Count, string asm, string veclist, int Offset128,
7937                        int Offset64, bits<4> opcode> {
7938   let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {
7939     def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),
7940                             (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
7941                                  GPR64sp:$Rn), []>;
7942     def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),
7943                            (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
7944                                 GPR64sp:$Rn), []>;
7945     def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),
7946                            (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
7947                                 GPR64sp:$Rn), []>;
7948     def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),
7949                            (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
7950                                 GPR64sp:$Rn), []>;
7951     def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),
7952                            (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
7953                                 GPR64sp:$Rn), []>;
7954     def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),
7955                            (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
7956                                 GPR64sp:$Rn), []>;
7957     def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),
7958                            (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
7959                                 GPR64sp:$Rn), []>;
7960
7961     def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,
7962                        (outs GPR64sp:$wback),
7963                        (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,
7964                             GPR64sp:$Rn,
7965                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7966     def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,
7967                        (outs GPR64sp:$wback),
7968                        (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,
7969                             GPR64sp:$Rn,
7970                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7971     def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,
7972                        (outs GPR64sp:$wback),
7973                        (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,
7974                             GPR64sp:$Rn,
7975                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7976     def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,
7977                        (outs GPR64sp:$wback),
7978                        (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,
7979                             GPR64sp:$Rn,
7980                             !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;
7981     def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,
7982                        (outs GPR64sp:$wback),
7983                        (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,
7984                             GPR64sp:$Rn,
7985                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7986     def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,
7987                        (outs GPR64sp:$wback),
7988                        (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,
7989                             GPR64sp:$Rn,
7990                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7991     def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,
7992                        (outs GPR64sp:$wback),
7993                        (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,
7994                             GPR64sp:$Rn,
7995                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
7996   }
7997
7998   defm : SIMDLdStAliases<asm, "16b", Count, Offset128, 128>;
7999   defm : SIMDLdStAliases<asm, "8h", Count, Offset128, 128>;
8000   defm : SIMDLdStAliases<asm, "4s", Count, Offset128, 128>;
8001   defm : SIMDLdStAliases<asm, "2d", Count, Offset128, 128>;
8002   defm : SIMDLdStAliases<asm, "8b", Count, Offset64, 64>;
8003   defm : SIMDLdStAliases<asm, "4h", Count, Offset64, 64>;
8004   defm : SIMDLdStAliases<asm, "2s", Count, Offset64, 64>;
8005 }
8006
8007 multiclass BaseSIMDLd1<string Count, string asm, string veclist,
8008                        int Offset128, int Offset64, bits<4> opcode>
8009   : BaseSIMDLdN<Count, asm, veclist, Offset128, Offset64, opcode> {
8010
8011   // LD1 instructions have extra "1d" variants.
8012   let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
8013     def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,
8014                            (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),
8015                            (ins GPR64sp:$Rn), []>;
8016
8017     def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,
8018                        (outs GPR64sp:$wback,
8019                              !cast<RegisterOperand>(veclist # "1d"):$Vt),
8020                        (ins GPR64sp:$Rn,
8021                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8022   }
8023
8024   defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8025 }
8026
8027 multiclass BaseSIMDSt1<string Count, string asm, string veclist,
8028                        int Offset128, int Offset64, bits<4> opcode>
8029   : BaseSIMDStN<Count, asm, veclist, Offset128, Offset64, opcode> {
8030
8031   // ST1 instructions have extra "1d" variants.
8032   let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
8033     def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),
8034                            (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8035                                 GPR64sp:$Rn), []>;
8036
8037     def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,
8038                        (outs GPR64sp:$wback),
8039                        (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,
8040                             GPR64sp:$Rn,
8041                             !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;
8042   }
8043
8044   defm : SIMDLdStAliases<asm, "1d", Count, Offset64, 64>;
8045 }
8046
8047 multiclass SIMDLd1Multiple<string asm> {
8048   defm One   : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8,  0b0111>;
8049   defm Two   : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8050   defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8051   defm Four  : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8052 }
8053
8054 multiclass SIMDSt1Multiple<string asm> {
8055   defm One   : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8,  0b0111>;
8056   defm Two   : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>;
8057   defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>;
8058   defm Four  : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>;
8059 }
8060
8061 multiclass SIMDLd2Multiple<string asm> {
8062   defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8063 }
8064
8065 multiclass SIMDSt2Multiple<string asm> {
8066   defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>;
8067 }
8068
8069 multiclass SIMDLd3Multiple<string asm> {
8070   defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8071 }
8072
8073 multiclass SIMDSt3Multiple<string asm> {
8074   defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>;
8075 }
8076
8077 multiclass SIMDLd4Multiple<string asm> {
8078   defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8079 }
8080
8081 multiclass SIMDSt4Multiple<string asm> {
8082   defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>;
8083 }
8084
8085 //---
8086 // AdvSIMD Load/store single-element
8087 //---
8088
8089 class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,
8090                          string asm, string operands, string cst,
8091                          dag oops, dag iops, list<dag> pattern>
8092   : I<oops, iops, asm, operands, cst, pattern> {
8093   bits<5> Vt;
8094   bits<5> Rn;
8095   let Inst{31} = 0;
8096   let Inst{29-24} = 0b001101;
8097   let Inst{22} = L;
8098   let Inst{21} = R;
8099   let Inst{15-13} = opcode;
8100   let Inst{9-5} = Rn;
8101   let Inst{4-0} = Vt;
8102 }
8103
8104 class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,
8105                          string asm, string operands, string cst,
8106                          dag oops, dag iops, list<dag> pattern>
8107   : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {
8108   bits<5> Vt;
8109   bits<5> Rn;
8110   let Inst{31} = 0;
8111   let Inst{29-24} = 0b001101;
8112   let Inst{22} = L;
8113   let Inst{21} = R;
8114   let Inst{15-13} = opcode;
8115   let Inst{9-5} = Rn;
8116   let Inst{4-0} = Vt;
8117 }
8118
8119
8120 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8121 class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,
8122                   Operand listtype>
8123   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",
8124                        (outs listtype:$Vt), (ins GPR64sp:$Rn),
8125                        []> {
8126   let Inst{30} = Q;
8127   let Inst{23} = 0;
8128   let Inst{20-16} = 0b00000;
8129   let Inst{12} = S;
8130   let Inst{11-10} = size;
8131 }
8132 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8133 class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,
8134                       string asm, Operand listtype, Operand GPR64pi>
8135   : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",
8136                        "$Rn = $wback",
8137                        (outs GPR64sp:$wback, listtype:$Vt),
8138                        (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {
8139   bits<5> Xm;
8140   let Inst{30} = Q;
8141   let Inst{23} = 1;
8142   let Inst{20-16} = Xm;
8143   let Inst{12} = S;
8144   let Inst{11-10} = size;
8145 }
8146
8147 multiclass SIMDLdrAliases<string asm, string layout, string Count,
8148                           int Offset, int Size> {
8149   // E.g. "ld1r { v0.8b }, [x1], #1"
8150   //      "ld1r.8b\t$Vt, [$Rn], #1"
8151   // may get mapped to
8152   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8153   def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,
8154                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
8155                       GPR64sp:$Rn,
8156                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8157                       XZR), 1>;
8158
8159   // E.g. "ld1r.8b { v0 }, [x1], #1"
8160   //      "ld1r.8b\t$Vt, [$Rn], #1"
8161   // may get mapped to
8162   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8163   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,
8164                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
8165                       GPR64sp:$Rn,
8166                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8167                       XZR), 0>;
8168
8169   // E.g. "ld1r.8b { v0 }, [x1]"
8170   //      "ld1r.8b\t$Vt, [$Rn]"
8171   // may get mapped to
8172   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8173   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",
8174                   (!cast<Instruction>(NAME # "v" # layout)
8175                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8176                       GPR64sp:$Rn), 0>;
8177
8178   // E.g. "ld1r.8b { v0 }, [x1], x2"
8179   //      "ld1r.8b\t$Vt, [$Rn], $Xm"
8180   // may get mapped to
8181   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8182   def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",
8183                   (!cast<Instruction>(NAME # "v" # layout # "_POST")
8184                       GPR64sp:$Rn,
8185                       !cast<RegisterOperand>("VecList" # Count # Size):$Vt,
8186                       !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8187 }
8188
8189 multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,
8190   int Offset1, int Offset2, int Offset4, int Offset8> {
8191   def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,
8192                         !cast<Operand>("VecList" # Count # "8b")>;
8193   def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,
8194                         !cast<Operand>("VecList" # Count #"16b")>;
8195   def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,
8196                         !cast<Operand>("VecList" # Count #"4h")>;
8197   def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,
8198                         !cast<Operand>("VecList" # Count #"8h")>;
8199   def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,
8200                         !cast<Operand>("VecList" # Count #"2s")>;
8201   def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,
8202                         !cast<Operand>("VecList" # Count #"4s")>;
8203   def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,
8204                         !cast<Operand>("VecList" # Count #"1d")>;
8205   def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,
8206                         !cast<Operand>("VecList" # Count #"2d")>;
8207
8208   def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,
8209                                  !cast<Operand>("VecList" # Count # "8b"),
8210                                  !cast<Operand>("GPR64pi" # Offset1)>;
8211   def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,
8212                                  !cast<Operand>("VecList" # Count # "16b"),
8213                                  !cast<Operand>("GPR64pi" # Offset1)>;
8214   def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,
8215                                  !cast<Operand>("VecList" # Count # "4h"),
8216                                  !cast<Operand>("GPR64pi" # Offset2)>;
8217   def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,
8218                                  !cast<Operand>("VecList" # Count # "8h"),
8219                                  !cast<Operand>("GPR64pi" # Offset2)>;
8220   def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,
8221                                  !cast<Operand>("VecList" # Count # "2s"),
8222                                  !cast<Operand>("GPR64pi" # Offset4)>;
8223   def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,
8224                                  !cast<Operand>("VecList" # Count # "4s"),
8225                                  !cast<Operand>("GPR64pi" # Offset4)>;
8226   def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,
8227                                  !cast<Operand>("VecList" # Count # "1d"),
8228                                  !cast<Operand>("GPR64pi" # Offset8)>;
8229   def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,
8230                                  !cast<Operand>("VecList" # Count # "2d"),
8231                                  !cast<Operand>("GPR64pi" # Offset8)>;
8232
8233   defm : SIMDLdrAliases<asm, "8b",  Count, Offset1,  64>;
8234   defm : SIMDLdrAliases<asm, "16b", Count, Offset1, 128>;
8235   defm : SIMDLdrAliases<asm, "4h",  Count, Offset2,  64>;
8236   defm : SIMDLdrAliases<asm, "8h",  Count, Offset2, 128>;
8237   defm : SIMDLdrAliases<asm, "2s",  Count, Offset4,  64>;
8238   defm : SIMDLdrAliases<asm, "4s",  Count, Offset4, 128>;
8239   defm : SIMDLdrAliases<asm, "1d",  Count, Offset8,  64>;
8240   defm : SIMDLdrAliases<asm, "2d",  Count, Offset8, 128>;
8241 }
8242
8243 class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,
8244                       dag oops, dag iops, list<dag> pattern>
8245   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8246                        pattern> {
8247   // idx encoded in Q:S:size fields.
8248   bits<4> idx;
8249   let Inst{30} = idx{3};
8250   let Inst{23} = 0;
8251   let Inst{20-16} = 0b00000;
8252   let Inst{12} = idx{2};
8253   let Inst{11-10} = idx{1-0};
8254 }
8255 class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,
8256                       dag oops, dag iops, list<dag> pattern>
8257   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8258                            oops, iops, pattern> {
8259   // idx encoded in Q:S:size fields.
8260   bits<4> idx;
8261   let Inst{30} = idx{3};
8262   let Inst{23} = 0;
8263   let Inst{20-16} = 0b00000;
8264   let Inst{12} = idx{2};
8265   let Inst{11-10} = idx{1-0};
8266 }
8267 class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,
8268                           dag oops, dag iops>
8269   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8270                        "$Rn = $wback", oops, iops, []> {
8271   // idx encoded in Q:S:size fields.
8272   bits<4> idx;
8273   bits<5> Xm;
8274   let Inst{30} = idx{3};
8275   let Inst{23} = 1;
8276   let Inst{20-16} = Xm;
8277   let Inst{12} = idx{2};
8278   let Inst{11-10} = idx{1-0};
8279 }
8280 class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,
8281                           dag oops, dag iops>
8282   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8283                            "$Rn = $wback", oops, iops, []> {
8284   // idx encoded in Q:S:size fields.
8285   bits<4> idx;
8286   bits<5> Xm;
8287   let Inst{30} = idx{3};
8288   let Inst{23} = 1;
8289   let Inst{20-16} = Xm;
8290   let Inst{12} = idx{2};
8291   let Inst{11-10} = idx{1-0};
8292 }
8293
8294 class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,
8295                       dag oops, dag iops, list<dag> pattern>
8296   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8297                        pattern> {
8298   // idx encoded in Q:S:size<1> fields.
8299   bits<3> idx;
8300   let Inst{30} = idx{2};
8301   let Inst{23} = 0;
8302   let Inst{20-16} = 0b00000;
8303   let Inst{12} = idx{1};
8304   let Inst{11} = idx{0};
8305   let Inst{10} = size;
8306 }
8307 class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,
8308                       dag oops, dag iops, list<dag> pattern>
8309   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8310                            oops, iops, pattern> {
8311   // idx encoded in Q:S:size<1> fields.
8312   bits<3> idx;
8313   let Inst{30} = idx{2};
8314   let Inst{23} = 0;
8315   let Inst{20-16} = 0b00000;
8316   let Inst{12} = idx{1};
8317   let Inst{11} = idx{0};
8318   let Inst{10} = size;
8319 }
8320
8321 class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8322                           dag oops, dag iops>
8323   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8324                        "$Rn = $wback", oops, iops, []> {
8325   // idx encoded in Q:S:size<1> fields.
8326   bits<3> idx;
8327   bits<5> Xm;
8328   let Inst{30} = idx{2};
8329   let Inst{23} = 1;
8330   let Inst{20-16} = Xm;
8331   let Inst{12} = idx{1};
8332   let Inst{11} = idx{0};
8333   let Inst{10} = size;
8334 }
8335 class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,
8336                           dag oops, dag iops>
8337   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8338                            "$Rn = $wback", oops, iops, []> {
8339   // idx encoded in Q:S:size<1> fields.
8340   bits<3> idx;
8341   bits<5> Xm;
8342   let Inst{30} = idx{2};
8343   let Inst{23} = 1;
8344   let Inst{20-16} = Xm;
8345   let Inst{12} = idx{1};
8346   let Inst{11} = idx{0};
8347   let Inst{10} = size;
8348 }
8349 class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8350                       dag oops, dag iops, list<dag> pattern>
8351   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8352                        pattern> {
8353   // idx encoded in Q:S fields.
8354   bits<2> idx;
8355   let Inst{30} = idx{1};
8356   let Inst{23} = 0;
8357   let Inst{20-16} = 0b00000;
8358   let Inst{12} = idx{0};
8359   let Inst{11-10} = size;
8360 }
8361 class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8362                       dag oops, dag iops, list<dag> pattern>
8363   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8364                            oops, iops, pattern> {
8365   // idx encoded in Q:S fields.
8366   bits<2> idx;
8367   let Inst{30} = idx{1};
8368   let Inst{23} = 0;
8369   let Inst{20-16} = 0b00000;
8370   let Inst{12} = idx{0};
8371   let Inst{11-10} = size;
8372 }
8373 class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,
8374                           string asm, dag oops, dag iops>
8375   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8376                        "$Rn = $wback", oops, iops, []> {
8377   // idx encoded in Q:S fields.
8378   bits<2> idx;
8379   bits<5> Xm;
8380   let Inst{30} = idx{1};
8381   let Inst{23} = 1;
8382   let Inst{20-16} = Xm;
8383   let Inst{12} = idx{0};
8384   let Inst{11-10} = size;
8385 }
8386 class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8387                           string asm, dag oops, dag iops>
8388   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8389                            "$Rn = $wback", oops, iops, []> {
8390   // idx encoded in Q:S fields.
8391   bits<2> idx;
8392   bits<5> Xm;
8393   let Inst{30} = idx{1};
8394   let Inst{23} = 1;
8395   let Inst{20-16} = Xm;
8396   let Inst{12} = idx{0};
8397   let Inst{11-10} = size;
8398 }
8399 class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8400                       dag oops, dag iops, list<dag> pattern>
8401   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,
8402                        pattern> {
8403   // idx encoded in Q field.
8404   bits<1> idx;
8405   let Inst{30} = idx;
8406   let Inst{23} = 0;
8407   let Inst{20-16} = 0b00000;
8408   let Inst{12} = 0;
8409   let Inst{11-10} = size;
8410 }
8411 class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,
8412                       dag oops, dag iops, list<dag> pattern>
8413   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",
8414                            oops, iops, pattern> {
8415   // idx encoded in Q field.
8416   bits<1> idx;
8417   let Inst{30} = idx;
8418   let Inst{23} = 0;
8419   let Inst{20-16} = 0b00000;
8420   let Inst{12} = 0;
8421   let Inst{11-10} = size;
8422 }
8423 class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,
8424                           string asm, dag oops, dag iops>
8425   : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8426                        "$Rn = $wback", oops, iops, []> {
8427   // idx encoded in Q field.
8428   bits<1> idx;
8429   bits<5> Xm;
8430   let Inst{30} = idx;
8431   let Inst{23} = 1;
8432   let Inst{20-16} = Xm;
8433   let Inst{12} = 0;
8434   let Inst{11-10} = size;
8435 }
8436 class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,
8437                           string asm, dag oops, dag iops>
8438   : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",
8439                            "$Rn = $wback", oops, iops, []> {
8440   // idx encoded in Q field.
8441   bits<1> idx;
8442   bits<5> Xm;
8443   let Inst{30} = idx;
8444   let Inst{23} = 1;
8445   let Inst{20-16} = Xm;
8446   let Inst{12} = 0;
8447   let Inst{11-10} = size;
8448 }
8449
8450 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8451 multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,
8452                          RegisterOperand listtype,
8453                          RegisterOperand GPR64pi> {
8454   def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,
8455                            (outs listtype:$dst),
8456                            (ins listtype:$Vt, VectorIndexB:$idx,
8457                                 GPR64sp:$Rn), []>;
8458
8459   def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,
8460                             (outs GPR64sp:$wback, listtype:$dst),
8461                             (ins listtype:$Vt, VectorIndexB:$idx,
8462                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8463 }
8464 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8465 multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,
8466                          RegisterOperand listtype,
8467                          RegisterOperand GPR64pi> {
8468   def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,
8469                             (outs listtype:$dst),
8470                             (ins listtype:$Vt, VectorIndexH:$idx,
8471                                  GPR64sp:$Rn), []>;
8472
8473   def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,
8474                             (outs GPR64sp:$wback, listtype:$dst),
8475                             (ins listtype:$Vt, VectorIndexH:$idx,
8476                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8477 }
8478 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8479 multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,
8480                          RegisterOperand listtype,
8481                          RegisterOperand GPR64pi> {
8482   def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,
8483                             (outs listtype:$dst),
8484                             (ins listtype:$Vt, VectorIndexS:$idx,
8485                                  GPR64sp:$Rn), []>;
8486
8487   def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,
8488                             (outs GPR64sp:$wback, listtype:$dst),
8489                             (ins listtype:$Vt, VectorIndexS:$idx,
8490                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8491 }
8492 let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in
8493 multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,
8494                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8495   def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,
8496                             (outs listtype:$dst),
8497                             (ins listtype:$Vt, VectorIndexD:$idx,
8498                                  GPR64sp:$Rn), []>;
8499
8500   def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,
8501                             (outs GPR64sp:$wback, listtype:$dst),
8502                             (ins listtype:$Vt, VectorIndexD:$idx,
8503                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8504 }
8505 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8506 multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,
8507                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8508   def i8 : SIMDLdStSingleB<0, R, opcode, asm,
8509                            (outs), (ins listtype:$Vt, VectorIndexB:$idx,
8510                                         GPR64sp:$Rn), []>;
8511
8512   def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,
8513                                     (outs GPR64sp:$wback),
8514                                     (ins listtype:$Vt, VectorIndexB:$idx,
8515                                          GPR64sp:$Rn, GPR64pi:$Xm)>;
8516 }
8517 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8518 multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,
8519                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8520   def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,
8521                             (outs), (ins listtype:$Vt, VectorIndexH:$idx,
8522                                          GPR64sp:$Rn), []>;
8523
8524   def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,
8525                             (outs GPR64sp:$wback),
8526                             (ins listtype:$Vt, VectorIndexH:$idx,
8527                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8528 }
8529 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8530 multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,
8531                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8532   def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,
8533                             (outs), (ins listtype:$Vt, VectorIndexS:$idx,
8534                                          GPR64sp:$Rn), []>;
8535
8536   def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,
8537                             (outs GPR64sp:$wback),
8538                             (ins listtype:$Vt, VectorIndexS:$idx,
8539                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8540 }
8541 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in
8542 multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,
8543                          RegisterOperand listtype, RegisterOperand GPR64pi> {
8544   def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,
8545                             (outs), (ins listtype:$Vt, VectorIndexD:$idx,
8546                                          GPR64sp:$Rn), []>;
8547
8548   def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,
8549                             (outs GPR64sp:$wback),
8550                             (ins listtype:$Vt, VectorIndexD:$idx,
8551                                  GPR64sp:$Rn, GPR64pi:$Xm)>;
8552 }
8553
8554 multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,
8555                                  string Count, int Offset, Operand idxtype> {
8556   // E.g. "ld1 { v0.8b }[0], [x1], #1"
8557   //      "ld1\t$Vt, [$Rn], #1"
8558   // may get mapped to
8559   //      (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)
8560   def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,
8561                   (!cast<Instruction>(NAME # Type  # "_POST")
8562                       GPR64sp:$Rn,
8563                       !cast<RegisterOperand>("VecList" # Count # layout):$Vt,
8564                       idxtype:$idx, XZR), 1>;
8565
8566   // E.g. "ld1.8b { v0 }[0], [x1], #1"
8567   //      "ld1.8b\t$Vt, [$Rn], #1"
8568   // may get mapped to
8569   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)
8570   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,
8571                   (!cast<Instruction>(NAME # Type # "_POST")
8572                       GPR64sp:$Rn,
8573                       !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8574                       idxtype:$idx, XZR), 0>;
8575
8576   // E.g. "ld1.8b { v0 }[0], [x1]"
8577   //      "ld1.8b\t$Vt, [$Rn]"
8578   // may get mapped to
8579   //      (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)
8580   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",
8581                       (!cast<Instruction>(NAME # Type)
8582                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8583                          idxtype:$idx, GPR64sp:$Rn), 0>;
8584
8585   // E.g. "ld1.8b { v0 }[0], [x1], x2"
8586   //      "ld1.8b\t$Vt, [$Rn], $Xm"
8587   // may get mapped to
8588   //      (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)
8589   def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",
8590                       (!cast<Instruction>(NAME # Type # "_POST")
8591                          GPR64sp:$Rn,
8592                          !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,
8593                          idxtype:$idx,
8594                          !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;
8595 }
8596
8597 multiclass SIMDLdSt1SingleAliases<string asm> {
8598   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "One", 1, VectorIndexB>;
8599   defm : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;
8600   defm : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;
8601   defm : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;
8602 }
8603
8604 multiclass SIMDLdSt2SingleAliases<string asm> {
8605   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Two", 2,  VectorIndexB>;
8606   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4,  VectorIndexH>;
8607   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8,  VectorIndexS>;
8608   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;
8609 }
8610
8611 multiclass SIMDLdSt3SingleAliases<string asm> {
8612   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Three", 3,  VectorIndexB>;
8613   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6,  VectorIndexH>;
8614   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;
8615   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;
8616 }
8617
8618 multiclass SIMDLdSt4SingleAliases<string asm> {
8619   defm : SIMDLdStSingleAliases<asm, "b", "i8",  "Four", 4,  VectorIndexB>;
8620   defm : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8,  VectorIndexH>;
8621   defm : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;
8622   defm : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;
8623 }
8624 } // end of 'let Predicates = [HasNEON]'
8625
8626 //----------------------------------------------------------------------------
8627 // AdvSIMD v8.1 Rounding Double Multiply Add/Subtract
8628 //----------------------------------------------------------------------------
8629
8630 let Predicates = [HasNEON, HasV8_1a] in {
8631
8632 class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,
8633                                     RegisterOperand regtype, string asm, 
8634                                     string kind, list<dag> pattern>
8635   : BaseSIMDThreeSameVectorTied<Q, U, size, opcode, regtype, asm, kind, 
8636                                 pattern> {
8637   let Inst{21}=0;
8638 }
8639 multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,
8640                                              SDPatternOperator Accum> {
8641   def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",
8642     [(set (v4i16 V64:$dst),
8643           (Accum (v4i16 V64:$Rd),
8644                  (v4i16 (int_aarch64_neon_sqrdmulh (v4i16 V64:$Rn),
8645                                                    (v4i16 V64:$Rm)))))]>;         
8646   def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",
8647     [(set (v8i16 V128:$dst),
8648           (Accum (v8i16 V128:$Rd),
8649                  (v8i16 (int_aarch64_neon_sqrdmulh (v8i16 V128:$Rn),
8650                                                    (v8i16 V128:$Rm)))))]>;
8651   def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",
8652     [(set (v2i32 V64:$dst),
8653           (Accum (v2i32 V64:$Rd),
8654                  (v2i32 (int_aarch64_neon_sqrdmulh (v2i32 V64:$Rn),
8655                                                    (v2i32 V64:$Rm)))))]>;
8656   def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",
8657     [(set (v4i32 V128:$dst),
8658           (Accum (v4i32 V128:$Rd),
8659                  (v4i32 (int_aarch64_neon_sqrdmulh (v4i32 V128:$Rn),
8660                                                    (v4i32 V128:$Rm)))))]>;
8661 }
8662
8663 multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,
8664                                      SDPatternOperator Accum> {
8665   def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,
8666                                           V64, V64, V128_lo, VectorIndexH,
8667                                           asm, ".4h", ".4h", ".4h", ".h",
8668     [(set (v4i16 V64:$dst),
8669           (Accum (v4i16 V64:$Rd),
8670                  (v4i16 (int_aarch64_neon_sqrdmulh
8671                           (v4i16 V64:$Rn),
8672                           (v4i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8673                                                     VectorIndexH:$idx))))))]> {
8674     bits<3> idx;
8675     let Inst{11} = idx{2};
8676     let Inst{21} = idx{1};
8677     let Inst{20} = idx{0};
8678   }
8679
8680   def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,
8681                                           V128, V128, V128_lo, VectorIndexH,
8682                                           asm, ".8h", ".8h", ".8h", ".h",
8683     [(set (v8i16 V128:$dst),
8684           (Accum (v8i16 V128:$Rd),
8685                  (v8i16 (int_aarch64_neon_sqrdmulh
8686                           (v8i16 V128:$Rn),
8687                           (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),
8688                                                    VectorIndexH:$idx))))))]> {
8689     bits<3> idx;
8690     let Inst{11} = idx{2};
8691     let Inst{21} = idx{1};
8692     let Inst{20} = idx{0};
8693   }
8694
8695   def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,
8696                                           V64, V64, V128, VectorIndexS,
8697                                           asm, ".2s", ".2s", ".2s", ".s",
8698     [(set (v2i32 V64:$dst),
8699         (Accum (v2i32 V64:$Rd),
8700                (v2i32 (int_aarch64_neon_sqrdmulh
8701                         (v2i32 V64:$Rn),
8702                         (v2i32 (AArch64duplane32 (v4i32 V128:$Rm),
8703                                                  VectorIndexS:$idx))))))]> {
8704     bits<2> idx;
8705     let Inst{11} = idx{1};
8706     let Inst{21} = idx{0};
8707   }
8708
8709   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but 
8710   // an intermediate EXTRACT_SUBREG would be untyped.
8711   // FIXME: direct EXTRACT_SUBREG from v2i32 to i32 is illegal, that's why we 
8712   // got it lowered here as (i32 vector_extract (v4i32 insert_subvector(..)))
8713   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8714                        (i32 (vector_extract 
8715                                (v4i32 (insert_subvector
8716                                        (undef), 
8717                                         (v2i32 (int_aarch64_neon_sqrdmulh 
8718                                                  (v2i32 V64:$Rn),
8719                                                  (v2i32 (AArch64duplane32 
8720                                                           (v4i32 V128:$Rm),
8721                                                           VectorIndexS:$idx)))),
8722                                       (i32 0))),
8723                                (i64 0))))),
8724             (EXTRACT_SUBREG
8725                 (v2i32 (!cast<Instruction>(NAME # v2i32_indexed)
8726                           (v2i32 (INSERT_SUBREG (v2i32 (IMPLICIT_DEF)), 
8727                                                 FPR32Op:$Rd, 
8728                                                 ssub)), 
8729                           V64:$Rn,
8730                           V128:$Rm, 
8731                           VectorIndexS:$idx)),
8732                 ssub)>;
8733
8734   def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,
8735                                           V128, V128, V128, VectorIndexS,
8736                                           asm, ".4s", ".4s", ".4s", ".s",
8737     [(set (v4i32 V128:$dst),
8738           (Accum (v4i32 V128:$Rd),
8739                  (v4i32 (int_aarch64_neon_sqrdmulh
8740                           (v4i32 V128:$Rn),
8741                           (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),
8742                                                    VectorIndexS:$idx))))))]> {
8743     bits<2> idx;
8744     let Inst{11} = idx{1};
8745     let Inst{21} = idx{0};
8746   }
8747
8748   // FIXME: it would be nice to use the scalar (v1i32) instruction here, but
8749   // an intermediate EXTRACT_SUBREG would be untyped.
8750   def : Pat<(i32 (Accum (i32 FPR32Op:$Rd),
8751                         (i32 (vector_extract 
8752                                (v4i32 (int_aarch64_neon_sqrdmulh 
8753                                         (v4i32 V128:$Rn),
8754                                         (v4i32 (AArch64duplane32 
8755                                                  (v4i32 V128:$Rm),
8756                                                  VectorIndexS:$idx)))),
8757                                (i64 0))))),
8758             (EXTRACT_SUBREG
8759                 (v4i32 (!cast<Instruction>(NAME # v4i32_indexed)
8760                          (v4i32 (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), 
8761                                                FPR32Op:$Rd, 
8762                                                ssub)), 
8763                          V128:$Rn,
8764                          V128:$Rm, 
8765                          VectorIndexS:$idx)),
8766                 ssub)>;
8767
8768   def i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,
8769                                         FPR16Op, FPR16Op, V128_lo,
8770                                         VectorIndexH, asm, ".h", "", "", ".h", 
8771                                         []> {
8772     bits<3> idx;
8773     let Inst{11} = idx{2};
8774     let Inst{21} = idx{1};
8775     let Inst{20} = idx{0};
8776   }
8777
8778   def i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,
8779                                         FPR32Op, FPR32Op, V128, VectorIndexS,
8780                                         asm, ".s", "", "", ".s",
8781     [(set (i32 FPR32Op:$dst),
8782           (Accum (i32 FPR32Op:$Rd),
8783                  (i32 (int_aarch64_neon_sqrdmulh
8784                         (i32 FPR32Op:$Rn),
8785                         (i32 (vector_extract (v4i32 V128:$Rm),
8786                                              VectorIndexS:$idx))))))]> {
8787     bits<2> idx;
8788     let Inst{11} = idx{1};
8789     let Inst{21} = idx{0};
8790   }
8791 }
8792 } // let Predicates = [HasNeon, HasV8_1a]
8793
8794 //----------------------------------------------------------------------------
8795 // Crypto extensions
8796 //----------------------------------------------------------------------------
8797
8798 let Predicates = [HasCrypto] in {
8799 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8800 class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,
8801               list<dag> pat>
8802   : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,
8803     Sched<[WriteV]>{
8804   bits<5> Rd;
8805   bits<5> Rn;
8806   let Inst{31-16} = 0b0100111000101000;
8807   let Inst{15-12} = opc;
8808   let Inst{11-10} = 0b10;
8809   let Inst{9-5}   = Rn;
8810   let Inst{4-0}   = Rd;
8811 }
8812
8813 class AESInst<bits<4> opc, string asm, Intrinsic OpNode>
8814   : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",
8815             [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;
8816
8817 class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>
8818   : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),
8819             "$Rd = $dst",
8820             [(set (v16i8 V128:$dst),
8821                   (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;
8822
8823 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8824 class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,
8825                      dag oops, dag iops, list<dag> pat>
8826   : I<oops, iops, asm,
8827       "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #
8828       "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,
8829     Sched<[WriteV]>{
8830   bits<5> Rd;
8831   bits<5> Rn;
8832   bits<5> Rm;
8833   let Inst{31-21} = 0b01011110000;
8834   let Inst{20-16} = Rm;
8835   let Inst{15}    = 0;
8836   let Inst{14-12} = opc;
8837   let Inst{11-10} = 0b00;
8838   let Inst{9-5}   = Rn;
8839   let Inst{4-0}   = Rd;
8840 }
8841
8842 class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>
8843   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8844                    (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),
8845                    [(set (v4i32 FPR128:$dst),
8846                          (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),
8847                                  (v4i32 V128:$Rm)))]>;
8848
8849 class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>
8850   : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),
8851                    (ins V128:$Rd, V128:$Rn, V128:$Rm),
8852                    [(set (v4i32 V128:$dst),
8853                          (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),
8854                                  (v4i32 V128:$Rm)))]>;
8855
8856 class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>
8857   : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),
8858                    (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),
8859                    [(set (v4i32 FPR128:$dst),
8860                          (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),
8861                                  (v4i32 V128:$Rm)))]>;
8862
8863 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in
8864 class SHA2OpInst<bits<4> opc, string asm, string kind,
8865                  string cstr, dag oops, dag iops,
8866                  list<dag> pat>
8867   : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #
8868                        "|" # kind # "\t$Rd, $Rn}", cstr, pat>,
8869     Sched<[WriteV]>{
8870   bits<5> Rd;
8871   bits<5> Rn;
8872   let Inst{31-16} = 0b0101111000101000;
8873   let Inst{15-12} = opc;
8874   let Inst{11-10} = 0b10;
8875   let Inst{9-5}   = Rn;
8876   let Inst{4-0}   = Rd;
8877 }
8878
8879 class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>
8880   : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),
8881                (ins V128:$Rd, V128:$Rn),
8882                [(set (v4i32 V128:$dst),
8883                      (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;
8884
8885 class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>
8886   : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),
8887                [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;
8888 } // end of 'let Predicates = [HasCrypto]'
8889
8890 //----------------------------------------------------------------------------
8891 // v8.1 atomic instructions extension:
8892 // * CAS
8893 // * CASP
8894 // * SWP
8895 // * LDOPregister<OP>, and aliases STOPregister<OP>
8896
8897 // Instruction encodings:
8898 //
8899 //      31 30|29  24|23|22|21|20 16|15|14  10|9 5|4 0
8900 // CAS  SZ   |001000|1 |A |1 |Rs   |R |11111 |Rn |Rt
8901 // CASP  0|SZ|001000|0 |A |1 |Rs   |R |11111 |Rn |Rt
8902 // SWP  SZ   |111000|A |R |1 |Rs   |1 |OPC|00|Rn |Rt
8903 // LD   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |Rt
8904 // ST   SZ   |111000|A |R |1 |Rs   |0 |OPC|00|Rn |11111
8905
8906 // Instruction syntax:
8907 //
8908 // CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
8909 // CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]
8910 // CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]
8911 // CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]
8912 // SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
8913 // SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]
8914 // LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]
8915 // LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]
8916 // ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]
8917 // ST<OP>{<order>} <Xs>, [<Xn|SP>]
8918
8919 let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
8920 class BaseCASEncoding<dag oops, dag iops, string asm, string operands,
8921                       string cstr, list<dag> pattern>
8922       : I<oops, iops, asm, operands, cstr, pattern> {
8923   bits<2> Sz;
8924   bit NP;
8925   bit Acq;
8926   bit Rel;
8927   bits<5> Rs;
8928   bits<5> Rn;
8929   bits<5> Rt;
8930   let Inst{31-30} = Sz;
8931   let Inst{29-24} = 0b001000;
8932   let Inst{23} = NP;
8933   let Inst{22} = Acq;
8934   let Inst{21} = 0b1;
8935   let Inst{20-16} = Rs;
8936   let Inst{15} = Rel;
8937   let Inst{14-10} = 0b11111;
8938   let Inst{9-5} = Rn;
8939   let Inst{4-0} = Rt;
8940 }
8941
8942 class BaseCAS<string order, string size, RegisterClass RC>
8943       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
8944                         "cas" # order # size, "\t$Rs, $Rt, [$Rn]",
8945                         "$out = $Rs",[]> {
8946   let NP = 1;
8947 }
8948
8949 multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {
8950   let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseCAS<order, "b", GPR32>;
8951   let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseCAS<order, "h", GPR32>;
8952   let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseCAS<order, "", GPR32>;
8953   let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseCAS<order, "", GPR64>;
8954 }
8955
8956 class BaseCASP<string order, string size, RegisterOperand RC>
8957       : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),
8958                         "casp" # order # size, "\t$Rs, $Rt, [$Rn]",
8959                         "$out = $Rs",[]> {
8960   let NP = 0;
8961 }
8962
8963 multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {
8964   let Sz = 0b00, Acq = Acq, Rel = Rel in 
8965     def s : BaseCASP<order, "", WSeqPairClassOperand>;
8966   let Sz = 0b01, Acq = Acq, Rel = Rel in 
8967     def d : BaseCASP<order, "", XSeqPairClassOperand>;
8968 }
8969
8970 let Predicates = [HasV8_1a] in
8971 class BaseSWP<string order, string size, RegisterClass RC>
8972       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,
8973           "\t$Rs, $Rt, [$Rn]","",[]> {
8974   bits<2> Sz;
8975   bit Acq;
8976   bit Rel;
8977   bits<5> Rs;
8978   bits<3> opc = 0b000;
8979   bits<5> Rn;
8980   bits<5> Rt;
8981   let Inst{31-30} = Sz;
8982   let Inst{29-24} = 0b111000;
8983   let Inst{23} = Acq;
8984   let Inst{22} = Rel;
8985   let Inst{21} = 0b1;
8986   let Inst{20-16} = Rs;
8987   let Inst{15} = 0b1;
8988   let Inst{14-12} = opc;
8989   let Inst{11-10} = 0b00;
8990   let Inst{9-5} = Rn;
8991   let Inst{4-0} = Rt;
8992 }
8993
8994 multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {
8995   let Sz = 0b00, Acq = Acq, Rel = Rel in def b : BaseSWP<order, "b", GPR32>;
8996   let Sz = 0b01, Acq = Acq, Rel = Rel in def h : BaseSWP<order, "h", GPR32>;
8997   let Sz = 0b10, Acq = Acq, Rel = Rel in def s : BaseSWP<order, "", GPR32>;
8998   let Sz = 0b11, Acq = Acq, Rel = Rel in def d : BaseSWP<order, "", GPR64>;
8999 }
9000
9001 let Predicates = [HasV8_1a], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in
9002 class BaseLDOPregister<string op, string order, string size, RegisterClass RC>
9003       : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,
9004           "\t$Rs, $Rt, [$Rn]","",[]> {
9005   bits<2> Sz;
9006   bit Acq;
9007   bit Rel;
9008   bits<5> Rs;
9009   bits<3> opc;
9010   bits<5> Rn;
9011   bits<5> Rt;
9012   let Inst{31-30} = Sz;
9013   let Inst{29-24} = 0b111000;
9014   let Inst{23} = Acq;
9015   let Inst{22} = Rel;
9016   let Inst{21} = 0b1;
9017   let Inst{20-16} = Rs;
9018   let Inst{15} = 0b0;
9019   let Inst{14-12} = opc;
9020   let Inst{11-10} = 0b00;
9021   let Inst{9-5} = Rn;
9022   let Inst{4-0} = Rt;
9023 }
9024
9025 multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel, 
9026                         string order> {
9027   let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in 
9028     def b : BaseLDOPregister<op, order, "b", GPR32>;
9029   let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in 
9030     def h : BaseLDOPregister<op, order, "h", GPR32>;
9031   let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in 
9032     def s : BaseLDOPregister<op, order, "", GPR32>;
9033   let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in 
9034     def d : BaseLDOPregister<op, order, "", GPR64>;
9035 }
9036
9037 let Predicates = [HasV8_1a] in
9038 class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,
9039                         Instruction inst> :
9040       InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;
9041
9042 multiclass STOPregister<string asm, string instr> {
9043   def : BaseSTOPregister<asm # "lb", GPR32, WZR, 
9044                     !cast<Instruction>(instr # "Lb")>;
9045   def : BaseSTOPregister<asm # "lh", GPR32, WZR, 
9046                     !cast<Instruction>(instr # "Lh")>;
9047   def : BaseSTOPregister<asm # "l",  GPR32, WZR, 
9048                     !cast<Instruction>(instr # "Ls")>;
9049   def : BaseSTOPregister<asm # "l",  GPR64, XZR, 
9050                     !cast<Instruction>(instr # "Ld")>;
9051   def : BaseSTOPregister<asm # "b",  GPR32, WZR, 
9052                     !cast<Instruction>(instr # "b")>;
9053   def : BaseSTOPregister<asm # "h",  GPR32, WZR, 
9054                     !cast<Instruction>(instr # "h")>;
9055   def : BaseSTOPregister<asm,        GPR32, WZR, 
9056                     !cast<Instruction>(instr # "s")>;
9057   def : BaseSTOPregister<asm,        GPR64, XZR, 
9058                     !cast<Instruction>(instr # "d")>;
9059 }
9060
9061 //----------------------------------------------------------------------------
9062 // Allow the size specifier tokens to be upper case, not just lower.
9063 def : TokenAlias<".8B", ".8b">;
9064 def : TokenAlias<".4H", ".4h">;
9065 def : TokenAlias<".2S", ".2s">;
9066 def : TokenAlias<".1D", ".1d">;
9067 def : TokenAlias<".16B", ".16b">;
9068 def : TokenAlias<".8H", ".8h">;
9069 def : TokenAlias<".4S", ".4s">;
9070 def : TokenAlias<".2D", ".2d">;
9071 def : TokenAlias<".1Q", ".1q">;
9072 def : TokenAlias<".B", ".b">;
9073 def : TokenAlias<".H", ".h">;
9074 def : TokenAlias<".S", ".s">;
9075 def : TokenAlias<".D", ".d">;
9076 def : TokenAlias<".Q", ".q">;