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