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